mirror of
https://github.com/zhamao-robot/zhamao-framework.git
synced 2026-07-20 15:15:35 +08:00
initial commit
This commit is contained in:
220
src/ZM/API/CQ.php
Normal file
220
src/ZM/API/CQ.php
Normal 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("&", "&", $str);
|
||||
$str = str_replace("[", "[", $str);
|
||||
$str = str_replace("]", "]", $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("&", "&", $msg);
|
||||
$msg = str_replace("[", "[", $msg);
|
||||
$msg = str_replace("]", "]", $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
249
src/ZM/API/CQAPI.php
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user