initial 2.0.0-a5 commit

fix waitMessage function
fix CQCommand regexMatch and fullMatch
it just works
This commit is contained in:
jerry 2020-11-04 18:43:50 +08:00
parent 29fa9d8662
commit deab5fd921
10 changed files with 43 additions and 36 deletions

View File

@ -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

View File

@ -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));
// 回复用户结果

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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();
}
}
/**

View File

@ -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事件

View File

@ -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;

View File

@ -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);
}