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