initial commit

This commit is contained in:
whale
2020-03-02 16:14:20 +08:00
parent 517082d159
commit 769b87af6a
132 changed files with 5424 additions and 2866 deletions

220
src/ZM/API/CQ.php Normal file
View File

@@ -0,0 +1,220 @@
<?php
namespace ZM\API;
use Framework\Console;
use ZM\Utils\ZMUtil;
class CQ
{
/**
* at一下QQ用户仅在QQ群支持at全体
* @param $qq
* @return string
*/
public static function at($qq) {
if (is_numeric($qq) || $qq === "all") {
return "[CQ:at,qq=" . $qq . "]";
}
Console::error("传入的QQ号码($qq)错误!");
return " ";
}
/**
* 发送QQ原生表情
* @param $id
* @return string
*/
public static function face($id) {
if (is_numeric($id)) {
return "[CQ:face,id=" . $id . "]";
}
Console::error("传入的face id($id)错误!");
return " ";
}
/**
* 发送emoji表情
* @param $id
* @return string
*/
public static function emoji($id) {
if (is_numeric($id)) {
return "[CQ:emoji,id=" . $id . "]";
}
Console::error("传入的emoji id($id)错误!");
return " ";
}
/**
* 发送原创表情存放在酷Q目录的data/bface/下
* @param $id
* @return string
*/
public static function bface($id) {
return "[CQ:bface,id=" . $id . "]";
}
/**
* 发送小表情
* @param $id
* @return string
*/
public static function sface($id) {
if (is_numeric($id)) {
return "[CQ:sface,id=" . $id . "]";
}
Console::error("传入的sface id($id)错误!");
return " ";
}
/**
* 发送图片
* cache为<FALSE>时禁用CQ-HTTP-API插件的缓存
* @param $file
* @param bool $cache
* @return string
*/
public static function image($file, $cache = true) {
if ($cache === false)
return "[CQ:image,file=" . $file . ",cache=0]";
else
return "[CQ:image,file=" . $file . "]";
}
/**
* 发送语音
* cache为<FALSE>时禁用CQ-HTTP-API插件的缓存
* magic为<TRUE>时标记为变声
* @param $file
* @param bool $magic
* @param bool $cache
* @return string
*/
public static function record($file, $magic = false, $cache = true) {
if ($cache === false) $c = ",cache=0";
else $c = "";
if ($magic === true) $m = ",magic=true";
else $m = "";
return "[CQ:record,file=" . $file . $c . $m . "]";
}
/**
* 发送投掷骰子(只能在单条回复中单独使用)
* @return string
*/
public static function rps() {
return "[CQ:rps]";
}
/**
* 发送掷骰子表情(只能在单条回复中单独使用)
* @return string
*/
public static function dice() {
return "[CQ:dice]";
}
/**
* 戳一戳(原窗口抖动,仅支持好友消息使用)
* @return string
*/
public static function shake() {
return "[CQ:shake]";
}
/**
* 发送音乐分享(只能在单条回复中单独使用)
* qq、163、xiami为内置分享需要先通过搜索功能获取id后使用
* custom为自定义分享
* 当为自定义分享时:
* $id_or_url 为音乐卡片点进去打开的链接(一般是音乐介绍界面啦什么的)
* $audio 为音乐如mp3文件的HTTP链接地址不可为空
* $title 为音乐卡片的标题建议12字以内不可为空
* $content 为音乐卡片的简介(可忽略)
* $image 为音乐卡片的图片链接地址(可忽略)
* @param $type
* @param $id_or_url
* @param string $audio
* @param string $title
* @param string $content
* @param string $image
* @return string
*/
public static function music($type, $id_or_url, $audio = null, $title = null, $content = null, $image = null) {
switch ($type) {
case "qq":
case "163":
case "xiami":
return "[CQ:music,type=$type,id=$id_or_url]";
case "custom":
if ($title === null || $audio === null) {
Console::error("传入CQ码实例的标题和音频链接不能为空");
return " ";
}
if ($content === null) $c = "";
else $c = ",content=" . $content;
if ($image === null) $i = "";
else $i = ",image=" . $image;
return "[CQ:music,type=custom,url=" . $id_or_url . ",audio=" . $audio . ",title=" . $title . $c . $i . "]";
default:
Console::error("传入的music type($type)错误!");
return " ";
}
}
/**
* 发送链接分享(只能在单条回复中单独使用)
* @param $url
* @param $title
* @param null $content
* @param null $image
* @return string
*/
public static function share($url, $title, $content = null, $image = null) {
if ($content === null) $c = "";
else $c = ",content=" . $content;
if ($image === null) $i = "";
else $i = ",image=" . $image;
return "[CQ:share,url=" . $url . ",title=" . $title . $c . $i . "]";
}
/**
* 反转义字符串中的CQ码敏感符号
* @param $str
* @return mixed
*/
public static function decode($str) {
$str = str_replace("&amp;", "&", $str);
$str = str_replace("&#91;", "[", $str);
$str = str_replace("&#93;", "]", $str);
return $str;
}
public static function replace($str) {
$str = str_replace("{{", "[", $str);
$str = str_replace("}}", "]", $str);
return $str;
}
/**
* 转义CQ码
* @param $msg
* @return mixed
*/
public static function escape($msg) {
$msg = str_replace("&", "&amp;", $msg);
$msg = str_replace("[", "&#91;", $msg);
$msg = str_replace("]", "&#93;", $msg);
return $msg;
}
public static function removeCQ($msg) {
while (($cq = ZMUtil::getCQ($msg)) !== null) {
$msg = str_replace(mb_substr($msg, $cq["start"], $cq["end"] - $cq["start"] + 1), "", $msg);
}
return $msg;
}
}

249
src/ZM/API/CQAPI.php Normal file
View File

@@ -0,0 +1,249 @@
<?php
namespace ZM\API;
use Co;
use Framework\Console;
use Framework\ZMBuf;
use ZM\Connection\ConnectionManager;
use ZM\Connection\CQConnection;
use ZM\Connection\WSConnection;
/**
* @method static send_private_msg($self_id, $params, $function = null)
* @method static send_group_msg($self_id, $params, $function = null)
* @method static send_discuss_msg($self_id, $params, $function = null)
* @method static send_msg($self_id, $params, $function = null)
* @method static delete_msg($self_id, $params, $function = null)
* @method static send_like($self_id, $params, $function = null)
* @method static set_group_kick($self_id, $params, $function = null)
* @method static set_group_ban($self_id, $params, $function = null)
* @method static set_group_anonymous_ban($self_id, $params, $function = null)
* @method static set_group_whole_ban($self_id, $params, $function = null)
* @method static set_group_admin($self_id, $params, $function = null)
* @method static set_group_anonymous($self_id, $params, $function = null)
* @method static set_group_card($self_id, $params, $function = null)
* @method static set_group_leave($self_id, $params, $function = null)
* @method static set_group_special_title($self_id, $params, $function = null)
* @method static set_discuss_leave($self_id, $params, $function = null)
* @method static set_friend_add_request($self_id, $params, $function = null)
* @method static set_group_add_request($self_id, $params, $function = null)
* @method static get_login_info($self_id, $params, $function = null)
* @method static get_stranger_info($self_id, $params, $function = null)
* @method static get_group_list($self_id, $params, $function = null)
* @method static get_group_member_info($self_id, $params, $function = null)
* @method static get_group_member_list($self_id, $params, $function = null)
* @method static get_cookies($self_id, $params, $function = null)
* @method static get_csrf_token($self_id, $params, $function = null)
* @method static get_credentials($self_id, $params, $function = null)
* @method static get_record($self_id, $params, $function = null)
* @method static get_status($self_id, $params, $function = null)
* @method static get_version_info($self_id, $params, $function = null)
* @method static set_restart($self_id, $params, $function = null)
* @method static set_restart_plugin($self_id, $params, $function = null)
* @method static clean_data_dir($self_id, $params, $function = null)
* @method static clean_plugin_log($self_id, $params, $function = null)
* @method static _get_friend_list($self_id, $params, $function = null)
* @method static _get_group_info($self_id, $params, $function = null)
* @method static _get_vip_info($self_id, $params, $function = null)
* @method static send_private_msg_async($self_id, $params, $function = null)
* @method static send_group_msg_async($self_id, $params, $function = null)
* @method static send_discuss_msg_async($self_id, $params, $function = null)
* @method static send_msg_async($self_id, $params, $function = null)
* @method static delete_msg_async($self_id, $params, $function = null)
* @method static set_group_kick_async($self_id, $params, $function = null)
* @method static set_group_ban_async($self_id, $params, $function = null)
* @method static set_group_anonymous_ban_async($self_id, $params, $function = null)
* @method static set_group_whole_ban_async($self_id, $params, $function = null)
* @method static set_group_admin_async($self_id, $params, $function = null)
* @method static set_group_anonymous_async($self_id, $params, $function = null)
* @method static set_group_card_async($self_id, $params, $function = null)
* @method static set_group_leave_async($self_id, $params, $function = null)
* @method static set_group_special_title_async($self_id, $params, $function = null)
* @method static set_discuss_leave_async($self_id, $params, $function = null)
* @method static set_friend_add_request_async($self_id, $params, $function = null)
* @method static set_group_add_request_async($self_id, $params, $function = null)
*/
class CQAPI
{
public static function quick_reply(WSConnection $conn, $data, $msg, $yield = null) {
switch ($data["message_type"]) {
case "group":
return self::send_group_msg($conn, ["group_id" => $data["group_id"], "message" => $msg], $yield);
case "private":
return self::send_private_msg($conn, ["user_id" => $data["user_id"], "message" => $msg], $yield);
case "discuss":
return self::send_discuss_msg($conn, ["discuss_id" => $data["discuss_id"], "message" => $msg], $yield);
}
return null;
}
public static function __callStatic($name, $arg) {
$all = self::getSupportedAPIs();
$find = null;
if (in_array($name, $all)) $find = $name;
else {
foreach ($all as $v) {
if (strtolower($name) == strtolower(str_replace("_", "", $v))) {
$find = $v;
break;
}
}
}
if ($find === null) {
Console::error("Unknown API " . $name);
return false;
}
$reply = ["action" => $find];
if (!is_array($arg[1])) {
Console::error("Error when parsing params. Please make sure your params is an array.");
return false;
}
if ($arg[1] != []) {
$reply["params"] = $arg[1];
}
if (!($arg[0] instanceof CQConnection)) {
$robot = ConnectionManager::getByType("qq", ["self_id" => $arg[0]]);
if ($robot == []) {
Console::error("发送错误,机器人连接不存在!");
return false;
}
$arg[0] = $robot[0];
}
return self::processAPI($arg[0], $reply, $arg[2] ?? null);
}
/********************** non-API Part **********************/
private static function getSupportedAPIs() {
return [
"send_private_msg",
"send_group_msg",
"send_discuss_msg",
"send_msg",
"delete_msg",
"send_like",
"set_group_kick",
"set_group_ban",
"set_group_anonymous_ban",
"set_group_whole_ban",
"set_group_admin",
"set_group_anonymous",
"set_group_card",
"set_group_leave",
"set_group_special_title",
"set_discuss_leave",
"set_friend_add_request",
"set_group_add_request",
"get_login_info",
"get_stranger_info",
"get_group_list",
"get_group_member_info",
"get_group_member_list",
"get_cookies",
"get_csrf_token",
"get_credentials",
"get_record",
"get_status",
"get_version_info",
"set_restart",
"set_restart_plugin",
"clean_data_dir",
"clean_plugin_log",
"_get_friend_list",
"_get_group_info",
"_get_vip_info",
//异步API
"send_private_msg_async",
"send_group_msg_async",
"send_discuss_msg_async",
"send_msg_async",
"delete_msg_async",
"set_group_kick_async",
"set_group_ban_async",
"set_group_anonymous_ban_async",
"set_group_whole_ban_async",
"set_group_admin_async",
"set_group_anonymous_async",
"set_group_card_async",
"set_group_leave_async",
"set_group_special_title_async",
"set_discuss_leave_async",
"set_friend_add_request_async",
"set_group_add_request_async"
];
}
public static function getLoggedAPIs() {
return [
"send_private_msg",
"send_group_msg",
"send_discuss_msg",
"send_msg",
"send_private_msg_async",
"send_group_msg_async",
"send_discuss_msg_async",
"send_msg_async"
];
}
/**
* @param WSConnection $connection
* @param $reply
* @param |null $function
* @return bool
*/
private static function processAPI($connection, $reply, $function = null) {
$api_id = ZMBuf::$atomics["wait_msg_id"]->get();
$reply["echo"] = $api_id;
ZMBuf::$atomics["wait_msg_id"]->add(1);
if (is_callable($function)) {
ZMBuf::appendKey("sent_api", $api_id, [
"data" => $reply,
"time" => microtime(true),
"func" => $function,
"self_id" => $connection->getQQ()
]);
} elseif ($function === true) {
ZMBuf::appendKey("sent_api", $api_id, [
"data" => $reply,
"time" => microtime(true),
"coroutine" => Co::getuid(),
"self_id" => $connection->getQQ()
]);
} else {
ZMBuf::appendKey("sent_api", $api_id, [
"data" => $reply,
"time" => microtime(true),
"self_id" => $connection->getQQ()
]);
}
if ($connection->push(json_encode($reply))) {
Console::msg($reply, $connection->getQQ());
ZMBuf::$atomics["out_count"]->add(1);
if ($function === true) {
Co::suspend();
$data = ZMBuf::get("sent_api")[$api_id];
ZMBuf::unsetByValue("sent_api", $reply["echo"]);
return isset($data['result']) ? $data['result'] : null;
}
return true;
} else {
$response = [
"status" => "failed",
"retcode" => 999,
"data" => null,
"self_id" => $connection->getQQ()
];
$s = ZMBuf::get("sent_api")[$reply["echo"]];
if (($s["func"] ?? null) !== null)
call_user_func($s["func"], $response, $reply);
ZMBuf::unsetByValue("sent_api", $reply["echo"]);
if ($function === true) return null;
return false;
}
}
}