mirror of
https://github.com/zhamao-robot/zhamao-framework.git
synced 2026-07-21 23:55:35 +08:00
update to version 1.4
This commit is contained in:
@@ -38,18 +38,19 @@ class MessageEvent
|
||||
* @throws AnnotationException
|
||||
*/
|
||||
public function onBefore() {
|
||||
foreach (ZMBuf::$events[CQBefore::class]["message"] ?? [] as $v) {
|
||||
$c = $v->class;
|
||||
$obj_list = ZMBuf::$events[CQBefore::class]["message"];
|
||||
foreach ($obj_list as $v) {
|
||||
if($v->level < 200) break;
|
||||
EventHandler::callWithMiddleware(
|
||||
$c,
|
||||
$v->class,
|
||||
$v->method,
|
||||
["data" => context()->getData(), "connection" => $this->connection],
|
||||
[],
|
||||
function ($r) {
|
||||
if(!$r) context()->setCache("block_continue", true);
|
||||
if (!$r) context()->setCache("block_continue", true);
|
||||
}
|
||||
);
|
||||
if(context()->getCache("block_continue") === true) return false;
|
||||
if (context()->getCache("block_continue") === true) return false;
|
||||
}
|
||||
foreach (ZMBuf::get("wait_api", []) as $k => $v) {
|
||||
if (context()->getData()["user_id"] == $v["user_id"] &&
|
||||
@@ -63,6 +64,21 @@ class MessageEvent
|
||||
return false;
|
||||
}
|
||||
}
|
||||
foreach (ZMBuf::$events[CQBefore::class]["message"] ?? [] as $v) {
|
||||
if($v->level >= 200) continue;
|
||||
$c = $v->class;
|
||||
if (ctx()->getCache("level") != 0) continue;
|
||||
EventHandler::callWithMiddleware(
|
||||
$c,
|
||||
$v->method,
|
||||
["data" => context()->getData(), "connection" => $this->connection],
|
||||
[],
|
||||
function ($r) {
|
||||
if (!$r) context()->setCache("block_continue", true);
|
||||
}
|
||||
);
|
||||
if (context()->getCache("block_continue") === true) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -91,7 +107,7 @@ class MessageEvent
|
||||
"data" => context()->getData(),
|
||||
"connection" => context()->getConnection()
|
||||
];
|
||||
if(!isset($obj[$c])) {
|
||||
if (!isset($obj[$c])) {
|
||||
$obj[$c] = new $c($class_construct);
|
||||
}
|
||||
if ($word[0] != "" && $v->match == $word[0]) {
|
||||
@@ -102,7 +118,8 @@ class MessageEvent
|
||||
});
|
||||
return;
|
||||
} elseif ($v->regexMatch != "" && ($args = matchArgs($v->regexMatch, context()->getMessage())) !== false) {
|
||||
$this->function_call = EventHandler::callWithMiddleware($obj[$c], $v->method, $class_construct, [$args], function ($r){
|
||||
Console::debug("Calling $c -> {$v->method}");
|
||||
$this->function_call = EventHandler::callWithMiddleware($obj[$c], $v->method, $class_construct, [$args], function ($r) {
|
||||
if (is_string($r)) context()->reply($r);
|
||||
return true;
|
||||
});
|
||||
@@ -120,13 +137,14 @@ class MessageEvent
|
||||
($v->message_type == '' || ($v->message_type != '' && $v->message_type == context()->getData()["message_type"])) &&
|
||||
($v->raw_message == '' || ($v->raw_message != '' && $v->raw_message == context()->getData()["raw_message"]))) {
|
||||
$c = $v->class;
|
||||
Console::debug("Calling CQMessage: $c -> {$v->method}");
|
||||
if (!isset($obj[$c]))
|
||||
$obj[$c] = new $c([
|
||||
"data" => context()->getData(),
|
||||
"connection" => $this->connection
|
||||
], ModHandleType::CQ_MESSAGE);
|
||||
EventHandler::callWithMiddleware($obj[$c], $v->method, [], [context()->getData()["message"]], function($r) {
|
||||
if(is_string($r)) context()->reply($r);
|
||||
EventHandler::callWithMiddleware($obj[$c], $v->method, [], [context()->getData()["message"]], function ($r) {
|
||||
if (is_string($r)) context()->reply($r);
|
||||
});
|
||||
if (context()->getCache("block_continue") === true) return;
|
||||
}
|
||||
@@ -150,10 +168,10 @@ class MessageEvent
|
||||
["data" => context()->getData(), "connection" => $this->connection],
|
||||
[],
|
||||
function ($r) {
|
||||
if(!$r) context()->setCache("block_continue", true);
|
||||
if (!$r) context()->setCache("block_continue", true);
|
||||
}
|
||||
);
|
||||
if(context()->getCache("block_continue") === true) return false;
|
||||
if (context()->getCache("block_continue") === true) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ use Exception;
|
||||
use Framework\Console;
|
||||
use Framework\ZMBuf;
|
||||
use ZM\Event\Swoole\{MessageEvent, RequestEvent, WorkerStartEvent, WSCloseEvent, WSOpenEvent};
|
||||
use Swoole\Http\Request;
|
||||
use Swoole\Server;
|
||||
use Swoole\WebSocket\Frame;
|
||||
use ZM\Annotation\CQ\CQAPIResponse;
|
||||
@@ -46,8 +47,9 @@ class EventHandler
|
||||
DataProvider::saveBuffer();
|
||||
ZMBuf::$server->shutdown();
|
||||
});
|
||||
(new WorkerStartEvent($param0, $param1))->onActivate()->onAfter();
|
||||
$r = (new WorkerStartEvent($param0, $param1))->onActivate();
|
||||
Console::log("\n=== Worker #" . $param0->worker_id . " 已启动 ===\n", "gold");
|
||||
$r->onAfter();
|
||||
self::startTick();
|
||||
} catch (Exception $e) {
|
||||
Console::error("Worker加载出错!停止服务!");
|
||||
@@ -69,6 +71,7 @@ class EventHandler
|
||||
} catch (Error $e) {
|
||||
$error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")";
|
||||
Console::error("Fatal error when calling $event_name: " . $error_msg);
|
||||
Console::stackTrace();
|
||||
}
|
||||
break;
|
||||
case "request":
|
||||
@@ -99,12 +102,14 @@ class EventHandler
|
||||
}
|
||||
break;
|
||||
case "open":
|
||||
set_coroutine_params(["server" => $param0, "request" => $param1]);
|
||||
/** @var Request $param1 */
|
||||
set_coroutine_params(["server" => $param0, "request" => $param1, "fd" => $param1->fd]);
|
||||
try {
|
||||
(new WSOpenEvent($param0, $param1))->onActivate()->onAfter();
|
||||
} catch (Error $e) {
|
||||
$error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")";
|
||||
Console::error("Fatal error when calling $event_name: " . $error_msg);
|
||||
Console::stackTrace();
|
||||
}
|
||||
break;
|
||||
case "close":
|
||||
@@ -114,6 +119,7 @@ class EventHandler
|
||||
} catch (Error $e) {
|
||||
$error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")";
|
||||
Console::error("Fatal error when calling $event_name: " . $error_msg);
|
||||
Console::stackTrace();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -128,6 +134,7 @@ class EventHandler
|
||||
* @throws AnnotationException
|
||||
*/
|
||||
public static function callCQEvent($event_data, $conn_or_response, int $level = 0) {
|
||||
ctx()->setCache("level",$level);
|
||||
if ($level >= 5) {
|
||||
Console::warning("Recursive call reached " . $level . " times");
|
||||
Console::stackTrace();
|
||||
@@ -160,8 +167,12 @@ class EventHandler
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $req
|
||||
* @throws AnnotationException
|
||||
*/
|
||||
public static function callCQResponse($req) {
|
||||
//Console::info("收到来自API连接的回复:".json_encode($req, 128|256));
|
||||
Console::debug("收到来自API连接的回复:".json_encode($req, 128|256));
|
||||
$status = $req["status"];
|
||||
$retcode = $req["retcode"];
|
||||
$data = $req["data"];
|
||||
@@ -172,13 +183,26 @@ class EventHandler
|
||||
"status" => $status,
|
||||
"retcode" => $retcode,
|
||||
"data" => $data,
|
||||
"self_id" => $self_id
|
||||
"self_id" => $self_id,
|
||||
"echo" => $req["echo"]
|
||||
];
|
||||
set_coroutine_params(["cq_response" => $response]);
|
||||
if (isset(ZMBuf::$events[CQAPIResponse::class][$req["retcode"]])) {
|
||||
list($c, $method) = ZMBuf::$events[CQAPIResponse::class][$req["retcode"]];
|
||||
$class = new $c(["data" => $origin["data"]]);
|
||||
call_user_func_array([$class, $method], [$origin["data"], $req]);
|
||||
}
|
||||
$origin_ctx = ctx()->copy();
|
||||
ctx()->setCache("action", $origin["data"]["action"] ?? "unknown");
|
||||
ctx()->setData($origin["data"]);
|
||||
foreach (ZMBuf::$events[CQAPISend::class] ?? [] as $k => $v) {
|
||||
if (($v->action == "" || $v->action == ctx()->getCache("action")) && $v->with_result) {
|
||||
$c = $v->class;
|
||||
self::callWithMiddleware($c, $v->method, context()->copy(), [ctx()->getCache("action"), $origin["data"]["params"] ?? [], ctx()->getRobotId()]);
|
||||
if (context()->getCache("block_continue") === true) break;
|
||||
}
|
||||
}
|
||||
set_coroutine_params($origin_ctx);
|
||||
if (($origin["func"] ?? null) !== null) {
|
||||
call_user_func($origin["func"], $response, $origin["data"]);
|
||||
} elseif (($origin["coroutine"] ?? false) !== false) {
|
||||
@@ -204,7 +228,7 @@ class EventHandler
|
||||
context()->setCache("action", $action);
|
||||
context()->setCache("reply", $reply);
|
||||
foreach (ZMBuf::$events[CQAPISend::class] ?? [] as $k => $v) {
|
||||
if ($v->action == "" || $v->action == $action) {
|
||||
if (($v->action == "" || $v->action == $action) && !$v->with_result) {
|
||||
$c = $v->class;
|
||||
self::callWithMiddleware($c, $v->method, context()->copy(), [$reply["action"], $reply["params"] ?? [], $connection->getQQ()]);
|
||||
if (context()->getCache("block_continue") === true) break;
|
||||
@@ -286,5 +310,6 @@ class EventHandler
|
||||
foreach (ZMBuf::get("paused_tick", []) as $cid) {
|
||||
Co::resume($cid);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,8 +48,10 @@ class MessageEvent implements SwooleEvent
|
||||
ctx()->setCache("level", 0);
|
||||
Console::debug("Calling CQ Event from fd=" . $conn->fd);
|
||||
EventHandler::callCQEvent($data, ConnectionManager::get(context()->getFrame()->fd), 0);
|
||||
} else
|
||||
} else{
|
||||
set_coroutine_params(["connection" => $conn]);
|
||||
EventHandler::callCQResponse($data);
|
||||
}
|
||||
}
|
||||
foreach (ZMBuf::$events[SwooleEventAt::class] ?? [] as $v) {
|
||||
if (strtolower($v->type) == "message" && $this->parseSwooleRule($v)) {
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace ZM\Event\Swoole;
|
||||
|
||||
use Closure;
|
||||
use Doctrine\Common\Annotations\AnnotationException;
|
||||
use Framework\Console;
|
||||
use Framework\ZMBuf;
|
||||
use Swoole\Http\Request;
|
||||
use Swoole\WebSocket\Server;
|
||||
@@ -51,9 +52,16 @@ class WSOpenEvent implements SwooleEvent
|
||||
if ($type_conn == CQConnection::class) {
|
||||
$qq = $this->request->get["qq"] ?? $this->request->header["x-self-id"] ?? "";
|
||||
$self_token = ZMBuf::globals("access_token") ?? "";
|
||||
$remote_token = $this->request->get["token"] ?? (isset($header["authorization"]) ? explode(" ", $this->request->header["authorization"])[1] : "");
|
||||
if(isset($this->request->header["authorization"])) {
|
||||
Console::debug($this->request->header["authorization"]);
|
||||
}
|
||||
$remote_token = $this->request->get["token"] ?? (isset($this->request->header["authorization"]) ? explode(" ", $this->request->header["authorization"])[1] : "");
|
||||
if ($qq != "" && ($self_token == $remote_token)) $this->conn = new CQConnection($this->server, $this->request->fd, $qq);
|
||||
else $this->conn = new UnknownConnection($this->server, $this->request->fd);
|
||||
else {
|
||||
$this->conn = new UnknownConnection($this->server, $this->request->fd);
|
||||
Console::warning("connection of CQ has invalid QQ or token!");
|
||||
Console::debug("Remote token: ".$remote_token);
|
||||
}
|
||||
} else {
|
||||
$this->conn = new $type_conn($this->server, $this->request->fd);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ use Doctrine\Common\Annotations\AnnotationException;
|
||||
use Exception;
|
||||
use ReflectionException;
|
||||
use Swoole\Coroutine;
|
||||
use Swoole\Database\PDOConfig;
|
||||
use Swoole\Database\PDOPool;
|
||||
use Swoole\Process;
|
||||
use Swoole\Timer;
|
||||
use ZM\Annotation\AnnotationBase;
|
||||
@@ -25,7 +27,6 @@ use Swoole\Server;
|
||||
use ZM\Event\EventHandler;
|
||||
use ZM\Exception\DbException;
|
||||
use Framework\DataProvider;
|
||||
use ZM\Utils\SQLPool;
|
||||
use ZM\Utils\ZMUtil;
|
||||
|
||||
class WorkerStartEvent implements SwooleEvent
|
||||
@@ -49,6 +50,9 @@ class WorkerStartEvent implements SwooleEvent
|
||||
*/
|
||||
public function onActivate(): WorkerStartEvent {
|
||||
Console::info("Worker启动中");
|
||||
ZMBuf::$server = $this->server;
|
||||
Console::listenConsole(); //这个方法只能在这里调用,且如果worker_num不为1的话,此功能不可用
|
||||
|
||||
Process::signal(SIGINT, function () {
|
||||
Console::warning("Server interrupted by keyboard.");
|
||||
ZMUtil::stop(true);
|
||||
@@ -76,14 +80,35 @@ class WorkerStartEvent implements SwooleEvent
|
||||
}
|
||||
if (ZMBuf::globals("sql_config")["sql_host"] != "") {
|
||||
Console::info("新建SQL连接池中");
|
||||
ZMBuf::$sql_pool = new SQLPool();
|
||||
ob_start();
|
||||
phpinfo();
|
||||
$str = ob_get_clean();
|
||||
$str = explode("\n", $str);
|
||||
foreach($str as $k => $v) {
|
||||
$v = trim($v);
|
||||
if($v == "") continue;
|
||||
if(mb_strpos($v, "API Extensions") === false) continue;
|
||||
if(mb_strpos($v, "pdo_mysql") === false) {
|
||||
throw new DbException("未安装 mysqlnd php-mysql扩展。");
|
||||
}
|
||||
}
|
||||
$sql = ZMBuf::globals("sql_config");
|
||||
ZMBuf::$sql_pool = new PDOPool((new PDOConfig())
|
||||
->withHost($sql["sql_host"])
|
||||
->withPort($sql["sql_port"])
|
||||
// ->withUnixSocket('/tmp/mysql.sock')
|
||||
->withDbName($sql["sql_database"])
|
||||
->withCharset('utf8mb4')
|
||||
->withUsername($sql["sql_username"])
|
||||
->withPassword($sql["sql_password"])
|
||||
);
|
||||
DB::initTableList();
|
||||
}
|
||||
ZMBuf::$server = $this->server;
|
||||
|
||||
ZMBuf::$atomics['reload_time']->add(1);
|
||||
|
||||
Console::info("监听console输入");
|
||||
Console::listenConsole(); //这个方法只能在这里调用,且如果worker_num不为1的话,此功能不可用
|
||||
|
||||
$this->setAutosaveTimer(ZMBuf::globals("auto_save_interval"));
|
||||
$this->loadAllClass(); //加载composer资源、phar外置包、注解解析注册等
|
||||
return $this;
|
||||
@@ -99,18 +124,22 @@ class WorkerStartEvent implements SwooleEvent
|
||||
}
|
||||
ZMBuf::unsetCache("wait_start");
|
||||
set_coroutine_params(["server" => $this->server, "worker_id" => $this->worker_id]);
|
||||
|
||||
foreach (ZMBuf::$events[OnStart::class] ?? [] as $v) {
|
||||
$class_name = $v->class;
|
||||
Console::debug("正在调用启动时函数: " . $class_name . " -> " . $v->method);
|
||||
EventHandler::callWithMiddleware($class_name, $v->method, ["server" => $this->server, "worker_id" => $this->worker_id], []);
|
||||
}
|
||||
foreach (ZMBuf::$events[SwooleEventAfter::class] ?? [] as $v) {
|
||||
/** @var AnnotationBase $v */
|
||||
if (strtolower($v->type) == "workerstart") {
|
||||
$class_name = $v->class;
|
||||
Console::debug("正在调用启动时函数after: " . $class_name . " -> " . $v->method);
|
||||
EventHandler::callWithMiddleware($class_name, $v->method, ["server" => $this->server, "worker_id" => $this->worker_id], []);
|
||||
if (context()->getCache("block_continue") === true) break;
|
||||
}
|
||||
}
|
||||
Console::debug("调用完毕!");
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -118,8 +147,8 @@ class WorkerStartEvent implements SwooleEvent
|
||||
foreach ($this->server->connections as $v) {
|
||||
$this->server->close($v);
|
||||
}
|
||||
if (ZMBuf::$sql_pool instanceof SqlPool) {
|
||||
ZMBuf::$sql_pool->destruct();
|
||||
if (ZMBuf::$sql_pool !== null) {
|
||||
ZMBuf::$sql_pool->close();
|
||||
ZMBuf::$sql_pool = null;
|
||||
}
|
||||
}
|
||||
@@ -147,12 +176,11 @@ class WorkerStartEvent implements SwooleEvent
|
||||
}
|
||||
|
||||
//加载composer类
|
||||
Console::info("加载composer资源中");
|
||||
if (file_exists(DataProvider::getWorkingDir() . "/vendor/autoload.php")) {
|
||||
Console::info("加载composer资源中");
|
||||
require_once DataProvider::getWorkingDir() . "/vendor/autoload.php";
|
||||
} else {
|
||||
if (isPharMode()) require_once WORKING_DIR . "/vendor/autoload.php";
|
||||
}
|
||||
if (isPharMode()) require_once WORKING_DIR . "/vendor/autoload.php";
|
||||
|
||||
//加载各个模块的注解类,以及反射
|
||||
Console::info("检索Module中");
|
||||
@@ -162,6 +190,7 @@ class WorkerStartEvent implements SwooleEvent
|
||||
ConnectionManager::registerCustomClass();
|
||||
|
||||
//加载自定义的全局函数
|
||||
Console::debug("加载自定义的全局函数中");
|
||||
if (file_exists(DataProvider::getWorkingDir() . "/src/Custom/global_function.php"))
|
||||
require_once DataProvider::getWorkingDir() . "/src/Custom/global_function.php";
|
||||
$this->afterCheck();
|
||||
@@ -169,7 +198,7 @@ class WorkerStartEvent implements SwooleEvent
|
||||
|
||||
private function setAutosaveTimer($globals) {
|
||||
DataProvider::$buffer_list = [];
|
||||
Timer::tick($globals * 1000, function () {
|
||||
zm_timer_tick($globals * 1000, function () {
|
||||
DataProvider::saveBuffer();
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user