From deab5fd921fcfffe61415b84794496388aa02b48 Mon Sep 17 00:00:00 2001 From: jerry Date: Wed, 4 Nov 2020 18:43:50 +0800 Subject: [PATCH] initial 2.0.0-a5 commit fix waitMessage function fix CQCommand regexMatch and fullMatch it just works --- config/global.php | 4 ++-- src/Module/Example/Hello.php | 13 ++++--------- src/ZM/Annotation/CQ/CQCommand.php | 4 ++-- src/ZM/Context/Context.php | 14 +++++++++----- src/ZM/Context/ContextInterface.php | 3 +-- src/ZM/Event/EventDispatcher.php | 3 --- src/ZM/Event/ServerEventHandler.php | 4 ++++ src/ZM/Module/QQBot.php | 30 +++++++++++++++++------------ src/ZM/Utils/CoMessage.php | 1 + src/ZM/Utils/ZMUtil.php | 3 ++- 10 files changed, 43 insertions(+), 36 deletions(-) diff --git a/config/global.php b/config/global.php index 83379206..07c3d9e9 100644 --- a/config/global.php +++ b/config/global.php @@ -28,7 +28,7 @@ $config['crash_dir'] = $config['zm_data'] . 'crash/'; $config['swoole'] = [ 'log_file' => $config['crash_dir'] . 'swoole_error.log', 'worker_num' => swoole_cpu_num(), - 'dispatch_mode' => 2, + 'dispatch_mode' => 2, //包分配原则,见 https://wiki.swoole.com/#/server/setting?id=dispatch_mode 'max_coroutine' => 300000, //'task_worker_num' => 4, //'task_enable_coroutine' => true @@ -37,7 +37,7 @@ $config['swoole'] = [ /** 轻量字符串缓存,默认开启 */ $config['light_cache'] = [ "size" => 1024, //最多允许储存的条数(需要2的倍数) - "max_strlen" => 8192, //单行字符串最大长度(需要2的倍数) + "max_strlen" => 16384, //单行字符串最大长度(需要2的倍数) "hash_conflict_proportion" => 0.6, //Hash冲突率(越大越好,但是需要的内存更多) "persistence_path" => $config['zm_data']."_cache.json", 'auto_save_interval' => 900 diff --git a/src/Module/Example/Hello.php b/src/Module/Example/Hello.php index ad387249..99c49bab 100644 --- a/src/Module/Example/Hello.php +++ b/src/Module/Example/Hello.php @@ -2,15 +2,11 @@ namespace Module\Example; -use ZM\Annotation\CQ\CQMetaEvent; use ZM\Annotation\Swoole\OnSwooleEvent; -use ZM\Annotation\Swoole\OnWorkerStart; use ZM\ConnectionManager\ConnectionObject; use ZM\Console\Console; use ZM\Annotation\CQ\CQCommand; use ZM\Annotation\Http\RequestMapping; -use ZM\Store\LightCache; -use ZM\Store\Lock\SpinLock; use ZM\Utils\ZMUtil; /** @@ -56,15 +52,14 @@ class Hello /** * @CQCommand("随机数") - * @CQCommand(regexMatch="*从*到*的随机数") - * @param $arg + * @CQCommand(pattern="*从*到*的随机数") * @return string */ - public function randNum($arg) { + public function randNum() { // 获取第一个数字类型的参数 - $num1 = ctx()->getArgs($arg, ZM_MATCH_NUMBER, "请输入第一个数字"); + $num1 = ctx()->getArgs(ZM_MATCH_NUMBER, "请输入第一个数字"); // 获取第二个数字类型的参数 - $num2 = ctx()->getArgs($arg, ZM_MATCH_NUMBER, "请输入第二个数字"); + $num2 = ctx()->getArgs(ZM_MATCH_NUMBER, "请输入第二个数字"); $a = min(intval($num1), intval($num2)); $b = max(intval($num1), intval($num2)); // 回复用户结果 diff --git a/src/ZM/Annotation/CQ/CQCommand.php b/src/ZM/Annotation/CQ/CQCommand.php index 6d468b6b..4f1d09c2 100644 --- a/src/ZM/Annotation/CQ/CQCommand.php +++ b/src/ZM/Annotation/CQ/CQCommand.php @@ -18,9 +18,9 @@ class CQCommand extends AnnotationBase implements Level /** @var string */ public $match = ""; /** @var string */ - public $regexMatch = ""; + public $pattern = ""; /** @var string */ - public $fullMatch = ""; + public $regex = ""; /** @var string[] */ public $alias = []; /** @var string */ diff --git a/src/ZM/Context/Context.php b/src/ZM/Context/Context.php index f721fdd2..c158330f 100644 --- a/src/ZM/Context/Context.php +++ b/src/ZM/Context/Context.php @@ -10,6 +10,7 @@ use Swoole\WebSocket\Frame; use swoole_server; use ZM\ConnectionManager\ConnectionObject; use ZM\ConnectionManager\ManagerGM; +use ZM\Console\Console; use ZM\Exception\InvalidArgumentException; use ZM\Exception\WaitTimeoutException; use ZM\Http\Response; @@ -142,14 +143,15 @@ class Context implements ContextInterface if (!isset($this->getData()["user_id"], $this->getData()["message"], $this->getData()["self_id"])) throw new InvalidArgumentException("协程等待参数缺失"); - + Console::debug("==== 开始等待输入 ===="); if ($prompt != "") $this->reply($prompt); $r = CoMessage::yieldByWS($this->getData(), ["user_id", "self_id", "message_type", onebot_target_id_name($this->getMessageType())]); if($r === false) { throw new WaitTimeoutException($this, $timeout_prompt); } - + return $r["message"]; + /* $cid = Co::getuid(); $api_id = ZMAtomic::get("wait_msg_id")->add(1); $hang = [ @@ -184,18 +186,18 @@ class Context implements ContextInterface $result = $sess["result"]; if (isset($id)) swoole_timer_clear($id); if ($result === null) throw new WaitTimeoutException($this, $timeout_prompt); - return $result; + return $result;*/ } /** - * @param $arg * @param $mode * @param $prompt_msg * @return mixed|string * @throws InvalidArgumentException * @throws WaitTimeoutException */ - public function getArgs(&$arg, $mode, $prompt_msg) { + public function getArgs($mode, $prompt_msg) { + $arg = ctx()->getCache("match"); switch ($mode) { case ZM_MATCH_ALL: $p = $arg; @@ -205,6 +207,7 @@ class Context implements ContextInterface foreach ($arg as $k => $v) { if (is_numeric($v)) { array_splice($arg, $k, 1); + ctx()->setCache("match", $arg); return $v; } } @@ -213,6 +216,7 @@ class Context implements ContextInterface if (isset($arg[1])) { $a = $arg[1]; array_splice($arg, 1, 1); + ctx()->setCache("match", $arg); return $a; } else { return $this->waitMessage($prompt_msg); diff --git a/src/ZM/Context/ContextInterface.php b/src/ZM/Context/ContextInterface.php index 93d81542..0f76be9d 100644 --- a/src/ZM/Context/ContextInterface.php +++ b/src/ZM/Context/ContextInterface.php @@ -97,12 +97,11 @@ interface ContextInterface public function waitMessage($prompt = "", $timeout = 600, $timeout_prompt = ""); /** - * @param $arg * @param $mode * @param $prompt_msg * @return mixed */ - public function getArgs(&$arg, $mode, $prompt_msg); + public function getArgs($mode, $prompt_msg); public function setCache($key, $value); diff --git a/src/ZM/Event/EventDispatcher.php b/src/ZM/Event/EventDispatcher.php index 561cacad..5f5339bf 100644 --- a/src/ZM/Event/EventDispatcher.php +++ b/src/ZM/Event/EventDispatcher.php @@ -45,9 +45,6 @@ class EventDispatcher try { foreach ((EventManager::$events[$this->class] ?? []) as $v) { - if($this->class == CQMetaEvent::class) { - //eval(BP); - } $result = $this->dispatchEvent($v, $this->rule, ...$params); if ($result !== false && is_callable($this->return_func)) ($this->return_func)($result); } diff --git a/src/ZM/Event/ServerEventHandler.php b/src/ZM/Event/ServerEventHandler.php index a7ebcebd..42637178 100644 --- a/src/ZM/Event/ServerEventHandler.php +++ b/src/ZM/Event/ServerEventHandler.php @@ -247,6 +247,7 @@ class ServerEventHandler * @param Frame $frame */ public function onMessage($server, Frame $frame) { + Console::debug("Calling Swoole \"message\" from fd=" . $frame->fd.": ".TermColor::ITALIC.$frame->data.TermColor::RESET); unset(Context::$context[Co::getCid()]); $conn = ManagerGM::get($frame->fd); @@ -264,7 +265,9 @@ class ServerEventHandler } }); try { + $starttime = microtime(true); $dispatcher->dispatchEvents($conn); + Console::success("Used ".round((microtime(true) - $starttime) * 1000, 3)." ms!"); } catch (Exception $e) { $error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")"; Console::error("Uncaught exception " . get_class($e) . " when calling \"message\": " . $error_msg); @@ -274,6 +277,7 @@ class ServerEventHandler Console::error("Uncaught Error " . get_class($e) . " when calling \"message\": " . $error_msg); Console::trace(); } + } /** diff --git a/src/ZM/Module/QQBot.php b/src/ZM/Module/QQBot.php index f1cd1de2..e77d2ff1 100644 --- a/src/ZM/Module/QQBot.php +++ b/src/ZM/Module/QQBot.php @@ -11,8 +11,6 @@ use ZM\Annotation\CQ\CQMessage; use ZM\Annotation\CQ\CQMetaEvent; use ZM\Annotation\CQ\CQNotice; use ZM\Annotation\CQ\CQRequest; -use ZM\Console\Console; -use ZM\Console\TermColor; use ZM\Event\EventDispatcher; use ZM\Exception\InterruptException; use ZM\Exception\WaitTimeoutException; @@ -39,8 +37,7 @@ class QQBot ctx()->setCache("level", 0); //Console::debug("Calling CQ Event from fd=" . ctx()->getConnection()->getFd()); $this->dispatchBeforeEvents($data); // >= 200 的level before在这里执行 - if (false) { - Console::error("哦豁,停下了"); + if (CoMessage::resumeByWS()) { EventDispatcher::interrupt(); } //Console::warning("最上数据包:".json_encode($data)); @@ -70,7 +67,7 @@ class QQBot //Console::warning("最xia数据包:".json_encode($data)); switch ($data["post_type"]) { case "message": - $word = split_explode(" ", str_replace("\r", "", context()->getMessage())); + $word = explodeMsg(str_replace("\r", "", context()->getMessage())); if (count(explode("\n", $word[0])) >= 2) { $enter = explode("\n", context()->getMessage()); $first = split_explode(" ", array_shift($enter)); @@ -82,17 +79,26 @@ class QQBot //分发CQCommand事件 $dispatcher = new EventDispatcher(CQCommand::class); - $dispatcher->setRuleFunction(function ($v) use ($word) { - if ($v->match == "" && $v->regexMatch == "" && $v->fullMatch == "") return false; + $dispatcher->setRuleFunction(function (CQCommand $v) use ($word) { + if ($v->match == "" && $v->pattern == "" && $v->regex == "") return false; elseif (($v->user_id == 0 || ($v->user_id != 0 && $v->user_id == ctx()->getUserId())) && ($v->group_id == 0 || ($v->group_id != 0 && $v->group_id == (ctx()->getGroupId() ?? 0))) && ($v->message_type == '' || ($v->message_type != '' && $v->message_type == ctx()->getMessageType())) ) { - if (($word[0] != "" && $v->match == $word[0]) || - in_array($word[0], $v->alias) || - ($v->regexMatch != "" && ($args = matchArgs($v->regexMatch, ctx()->getMessage())) !== false) || - ($v->fullMatch != "" && (preg_match("/" . $v->fullMatch . "/u", ctx()->getMessage(), $args)) != 0)) { + if(($word[0] != "" && $v->match == $word[0]) || in_array($word[0], $v->alias)) { + ctx()->setCache("match", $word); return true; + } elseif ($v->pattern != "") { + $match = matchArgs($v->pattern, ctx()->getMessage()); + if($match !== false) { + ctx()->setCache("match", $match); + return true; + } + } elseif ($v->regex != "") { + if(preg_match("/" . $v->regex . "/u", ctx()->getMessage(), $word2) != 0) { + ctx()->setCache("match", $word2); + return true; + } } } return false; @@ -101,7 +107,7 @@ class QQBot if (is_string($result)) ctx()->reply($result); EventDispatcher::interrupt(); }); - $r = $dispatcher->dispatchEvents($word); + $r = $dispatcher->dispatchEvents(); if ($r === null) EventDispatcher::interrupt(); //分发CQMessage事件 diff --git a/src/ZM/Utils/CoMessage.php b/src/ZM/Utils/CoMessage.php index 485229e0..637f56f7 100644 --- a/src/ZM/Utils/CoMessage.php +++ b/src/ZM/Utils/CoMessage.php @@ -55,6 +55,7 @@ class CoMessage SpinLock::lock("wait_api"); $all = LightCacheInside::get("wait_api", "wait_api") ?? []; foreach ($all as $k => $v) { + if(!isset($v["compare"])) continue; foreach ($v["compare"] as $vs) { if ($v[$vs] != ($dat[$vs] ?? null)) { continue 2; diff --git a/src/ZM/Utils/ZMUtil.php b/src/ZM/Utils/ZMUtil.php index 928369fe..6cf136f4 100644 --- a/src/ZM/Utils/ZMUtil.php +++ b/src/ZM/Utils/ZMUtil.php @@ -34,8 +34,9 @@ class ZMUtil Console::info(Console::setColor("Reloading server...", "gold")); usleep($delay * 1000); foreach ((LightCacheInside::get("wait_api", "wait_api") ?? []) as $k => $v) { - if ($v["result"] === null && isset($v["coroutine"])) Co::resume($v["coroutine"]); + if (($v["result"] ?? false) === null && isset($v["coroutine"])) Co::resume($v["coroutine"]); } + LightCacheInside::unset("wait_api", "wait_api"); foreach (server()->connections as $v) { server()->close($v); }