mirror of
https://github.com/zhamao-robot/zhamao-framework.git
synced 2026-03-17 20:54:52 +08:00
update to 2.0.0-b5 version
set modules config to array add subdir index.html update Example of Hello.php add Exception tester for TimerMiddleware.php add keyword for @CQCommand rename OnWorkerStart.php to OnStart.php remove SwooleEventAfter.php rename HandleEvent.php to SwooleHandler.php set ZMRobot callback mode default to true add getNextArg() and getFullArg() add EventDispatcher.php logger set Exception all based from ZMException fix recursive bug for Response.php add single_bot_mode add SingletonTrait.php add bot() function
This commit is contained in:
parent
1ffb30a471
commit
ba5b793db7
@ -3,7 +3,7 @@
|
|||||||
"description": "High performance QQ robot and web server development framework",
|
"description": "High performance QQ robot and web server development framework",
|
||||||
"minimum-stability": "stable",
|
"minimum-stability": "stable",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"version": "2.0.0-b4",
|
"version": "2.0.0-b5",
|
||||||
"extra": {},
|
"extra": {},
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
@ -35,6 +35,10 @@
|
|||||||
"symfony/routing": "^5.1",
|
"symfony/routing": "^5.1",
|
||||||
"symfony/polyfill-php80": "^1.20"
|
"symfony/polyfill-php80": "^1.20"
|
||||||
},
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-ctype": "*",
|
||||||
|
"ext-mbstring": "*"
|
||||||
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"ZM\\": "src/ZM",
|
"ZM\\": "src/ZM",
|
||||||
|
|||||||
@ -50,8 +50,6 @@ $config['sql_config'] = [
|
|||||||
'sql_username' => 'name',
|
'sql_username' => 'name',
|
||||||
'sql_database' => 'db_name',
|
'sql_database' => 'db_name',
|
||||||
'sql_password' => '',
|
'sql_password' => '',
|
||||||
'sql_enable_cache' => true,
|
|
||||||
'sql_reset_cache' => '0300',
|
|
||||||
'sql_options' => [
|
'sql_options' => [
|
||||||
PDO::ATTR_STRINGIFY_FETCHES => false,
|
PDO::ATTR_STRINGIFY_FETCHES => false,
|
||||||
PDO::ATTR_EMULATE_PREPARES => false
|
PDO::ATTR_EMULATE_PREPARES => false
|
||||||
@ -115,7 +113,10 @@ $config['command_register_class'] = [
|
|||||||
|
|
||||||
/** 服务器启用的外部第三方和内部插件 */
|
/** 服务器启用的外部第三方和内部插件 */
|
||||||
$config['modules'] = [
|
$config['modules'] = [
|
||||||
'onebot' => true, // QQ机器人事件解析器,如果取消此项则默认为 true 开启状态,否则你手动填写 false 才会关闭
|
'onebot' => [
|
||||||
|
'status' => true,
|
||||||
|
'single_bot_mode' => false
|
||||||
|
], // QQ机器人事件解析器,如果取消此项则默认为 true 开启状态,否则你手动填写 false 才会关闭
|
||||||
];
|
];
|
||||||
|
|
||||||
return $config;
|
return $config;
|
||||||
|
|||||||
10
resources/html/subdir/index.html
Normal file
10
resources/html/subdir/index.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Example page</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div style="background: red; width: 100px; height: 100px"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -8,7 +8,9 @@ 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\Event\EventDispatcher;
|
||||||
use ZM\Store\Redis\ZMRedis;
|
use ZM\Store\Redis\ZMRedis;
|
||||||
|
use ZM\Utils\ZMUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Hello
|
* Class Hello
|
||||||
@ -40,11 +42,20 @@ class Hello
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用命令 .reload 发给机器人远程重载,注意将 user_id 换成你自己的 QQ
|
||||||
|
* @CQCommand(".reload",user_id=627577391)
|
||||||
|
*/
|
||||||
|
public function reload() {
|
||||||
|
ctx()->reply("重启中...");
|
||||||
|
ZMUtil::reload();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @CQCommand("我是谁")
|
* @CQCommand("我是谁")
|
||||||
*/
|
*/
|
||||||
public function whoami() {
|
public function whoami() {
|
||||||
$user = ctx()->getRobot()->setCallback(true)->getLoginInfo();
|
$user = ctx()->getRobot()->getLoginInfo();
|
||||||
return "你是" . $user["data"]["nickname"] . ",QQ号是" . $user["data"]["user_id"];
|
return "你是" . $user["data"]["nickname"] . ",QQ号是" . $user["data"]["user_id"];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,6 +132,14 @@ class Hello
|
|||||||
Console::info("机器人 " . $conn->getOption("connect_id") . " 已断开连接!");
|
Console::info("机器人 " . $conn->getOption("connect_id") . " 已断开连接!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止 Chrome 自动请求 /favicon.ico 导致的多条请求并发和干扰
|
||||||
|
* @OnSwooleEvent("request",rule="ctx()->getRequest()->server['request_uri'] == '/favicon.ico'",level=200)
|
||||||
|
*/
|
||||||
|
public function onRequest() {
|
||||||
|
EventDispatcher::interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 框架会默认关闭未知的WebSocket链接,因为这个绑定的事件,你可以根据你自己的需求进行修改
|
* 框架会默认关闭未知的WebSocket链接,因为这个绑定的事件,你可以根据你自己的需求进行修改
|
||||||
* @OnSwooleEvent(type="open",rule="connectIsDefault()")
|
* @OnSwooleEvent(type="open",rule="connectIsDefault()")
|
||||||
|
|||||||
@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
namespace Module\Middleware;
|
namespace Module\Middleware;
|
||||||
|
|
||||||
use ZM\Annotation\Http\After;
|
use ZM\Annotation\Http\HandleAfter;
|
||||||
use ZM\Annotation\Http\Before;
|
use ZM\Annotation\Http\HandleBefore;
|
||||||
|
use ZM\Annotation\Http\HandleException;
|
||||||
use ZM\Annotation\Http\MiddlewareClass;
|
use ZM\Annotation\Http\MiddlewareClass;
|
||||||
use ZM\Console\Console;
|
use ZM\Console\Console;
|
||||||
use ZM\Http\MiddlewareInterface;
|
use ZM\Http\MiddlewareInterface;
|
||||||
@ -19,7 +20,7 @@ class TimerMiddleware implements MiddlewareInterface
|
|||||||
private $starttime;
|
private $starttime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Before()
|
* @HandleBefore()
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function onBefore() {
|
public function onBefore() {
|
||||||
@ -28,9 +29,16 @@ class TimerMiddleware implements MiddlewareInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @After()
|
* @HandleAfter()
|
||||||
*/
|
*/
|
||||||
public function onAfter() {
|
public function onAfter() {
|
||||||
Console::info("Using " . round((microtime(true) - $this->starttime) * 1000, 2) . " ms.");
|
Console::info("Using " . round((microtime(true) - $this->starttime) * 1000, 2) . " ms.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @HandleException(\Exception::class)
|
||||||
|
*/
|
||||||
|
public function onException() {
|
||||||
|
Console::error("Using " . round((microtime(true) - $this->starttime) * 1000, 2) . " ms but an Exception occurred.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,7 +24,7 @@ class ZMRobot
|
|||||||
/** @var ConnectionObject|null */
|
/** @var ConnectionObject|null */
|
||||||
private $connection;
|
private $connection;
|
||||||
|
|
||||||
private $callback = null;
|
private $callback = true;
|
||||||
private $prefix = 0;
|
private $prefix = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,6 +50,9 @@ class ZMRobot
|
|||||||
return new ZMRobot($r[array_rand($r)]);
|
return new ZMRobot($r[array_rand($r)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getFirst() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return ZMRobot[]
|
* @return ZMRobot[]
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use ZM\Console\Console;
|
|||||||
use ReflectionClass;
|
use ReflectionClass;
|
||||||
use ReflectionException;
|
use ReflectionException;
|
||||||
use ReflectionMethod;
|
use ReflectionMethod;
|
||||||
use ZM\Annotation\Http\{After, Before, Controller, HandleException, Middleware, MiddlewareClass, RequestMapping};
|
use ZM\Annotation\Http\{HandleAfter, HandleBefore, Controller, HandleException, Middleware, MiddlewareClass, RequestMapping};
|
||||||
use ZM\Annotation\Interfaces\Level;
|
use ZM\Annotation\Interfaces\Level;
|
||||||
use ZM\Annotation\Module\Closed;
|
use ZM\Annotation\Module\Closed;
|
||||||
use ZM\Utils\DataProvider;
|
use ZM\Utils\DataProvider;
|
||||||
@ -287,8 +287,8 @@ class AnnotationParser
|
|||||||
foreach ($reflection_class->getMethods() as $vss) {
|
foreach ($reflection_class->getMethods() as $vss) {
|
||||||
$method_annotations = $this->reader->getMethodAnnotations($vss);
|
$method_annotations = $this->reader->getMethodAnnotations($vss);
|
||||||
foreach ($method_annotations as $vsss) {
|
foreach ($method_annotations as $vsss) {
|
||||||
if ($vsss instanceof Before) $result["before"] = $vss->getName();
|
if ($vsss instanceof HandleBefore) $result["before"] = $vss->getName();
|
||||||
if ($vsss instanceof After) $result["after"] = $vss->getName();
|
if ($vsss instanceof HandleAfter) $result["after"] = $vss->getName();
|
||||||
if ($vsss instanceof HandleException) {
|
if ($vsss instanceof HandleException) {
|
||||||
$result["exceptions"][$vsss->class_name] = $vss->getName();
|
$result["exceptions"][$vsss->class_name] = $vss->getName();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,8 @@ class CQCommand extends AnnotationBase implements Level
|
|||||||
public $start_with = "";
|
public $start_with = "";
|
||||||
/** @var string */
|
/** @var string */
|
||||||
public $end_with = "";
|
public $end_with = "";
|
||||||
|
/** @var string */
|
||||||
|
public $keyword = "";
|
||||||
/** @var string[] */
|
/** @var string[] */
|
||||||
public $alias = [];
|
public $alias = [];
|
||||||
/** @var string */
|
/** @var string */
|
||||||
|
|||||||
@ -9,11 +9,11 @@ use Doctrine\Common\Annotations\Annotation\Target;
|
|||||||
use ZM\Annotation\AnnotationBase;
|
use ZM\Annotation\AnnotationBase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class After
|
* Class HandleAfter
|
||||||
* @package ZM\Annotation\Http
|
* @package ZM\Annotation\Http
|
||||||
* @Annotation
|
* @Annotation
|
||||||
* @Target("METHOD")
|
* @Target("METHOD")
|
||||||
*/
|
*/
|
||||||
class After extends AnnotationBase
|
class HandleAfter extends AnnotationBase
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -4,16 +4,15 @@
|
|||||||
namespace ZM\Annotation\Http;
|
namespace ZM\Annotation\Http;
|
||||||
|
|
||||||
|
|
||||||
use Doctrine\Common\Annotations\Annotation\Required;
|
|
||||||
use Doctrine\Common\Annotations\Annotation\Target;
|
use Doctrine\Common\Annotations\Annotation\Target;
|
||||||
use ZM\Annotation\AnnotationBase;
|
use ZM\Annotation\AnnotationBase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Before
|
* Class HandleBefore
|
||||||
* @package ZM\Annotation\Http
|
* @package ZM\Annotation\Http
|
||||||
* @Annotation
|
* @Annotation
|
||||||
* @Target("METHOD")
|
* @Target("METHOD")
|
||||||
*/
|
*/
|
||||||
class Before extends AnnotationBase
|
class HandleBefore extends AnnotationBase
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -13,6 +13,6 @@ use ZM\Annotation\AnnotationBase;
|
|||||||
* @Annotation
|
* @Annotation
|
||||||
* @Target("METHOD")
|
* @Target("METHOD")
|
||||||
*/
|
*/
|
||||||
class ZMSetup extends AnnotationBase
|
class OnSetup extends AnnotationBase
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -12,7 +12,7 @@ use ZM\Annotation\AnnotationBase;
|
|||||||
* @Annotation
|
* @Annotation
|
||||||
* @Target("ALL")
|
* @Target("ALL")
|
||||||
*/
|
*/
|
||||||
class OnWorkerStart extends AnnotationBase
|
class OnStart extends AnnotationBase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var int
|
* @var int
|
||||||
@ -1,76 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
|
|
||||||
namespace ZM\Annotation\Swoole;
|
|
||||||
|
|
||||||
|
|
||||||
use Doctrine\Common\Annotations\Annotation\Required;
|
|
||||||
use Doctrine\Common\Annotations\Annotation\Target;
|
|
||||||
use ZM\Annotation\AnnotationBase;
|
|
||||||
use ZM\Annotation\Interfaces\Level;
|
|
||||||
use ZM\Annotation\Interfaces\Rule;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class SwooleEventAfter
|
|
||||||
* @Annotation
|
|
||||||
* @Target("ALL")
|
|
||||||
* @package ZM\Annotation\Swoole
|
|
||||||
*/
|
|
||||||
class SwooleEventAfter extends AnnotationBase implements Rule, Level
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
* @Required
|
|
||||||
*/
|
|
||||||
public $type;
|
|
||||||
|
|
||||||
/** @var string */
|
|
||||||
public $rule = "";
|
|
||||||
|
|
||||||
/** @var int */
|
|
||||||
public $level = 20;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getType(): string {
|
|
||||||
return $this->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $type
|
|
||||||
*/
|
|
||||||
public function setType(string $type) {
|
|
||||||
$this->type = $type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getRule(): string {
|
|
||||||
return $this->rule;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $rule
|
|
||||||
*/
|
|
||||||
public function setRule(string $rule) {
|
|
||||||
$this->rule = $rule;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getLevel(): int {
|
|
||||||
return $this->level;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $level
|
|
||||||
*/
|
|
||||||
public function setLevel(int $level) {
|
|
||||||
$this->level = $level;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -9,12 +9,12 @@ use Doctrine\Common\Annotations\Annotation\Target;
|
|||||||
use ZM\Annotation\AnnotationBase;
|
use ZM\Annotation\AnnotationBase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class HandleEvent
|
* Class SwooleHandler
|
||||||
* @package ZM\Annotation\Swoole
|
* @package ZM\Annotation\Swoole
|
||||||
* @Annotation
|
* @Annotation
|
||||||
* @Target("METHOD")
|
* @Target("METHOD")
|
||||||
*/
|
*/
|
||||||
class HandleEvent extends AnnotationBase
|
class SwooleHandler extends AnnotationBase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
@ -68,9 +68,6 @@ class ConsoleApplication extends Application
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_dir(DataProvider::getWorkingDir() . '/src/')) {
|
|
||||||
die("Unable to find source directory.\nMaybe you need to run \"init\"?");
|
|
||||||
}
|
|
||||||
ZMConfig::setDirectory(DataProvider::getWorkingDir() . '/config');
|
ZMConfig::setDirectory(DataProvider::getWorkingDir() . '/config');
|
||||||
ZMConfig::env($args["env"] ?? "");
|
ZMConfig::env($args["env"] ?? "");
|
||||||
if (ZMConfig::get("global") === false) {
|
if (ZMConfig::get("global") === false) {
|
||||||
|
|||||||
@ -203,7 +203,6 @@ class Context implements ContextInterface
|
|||||||
switch ($mode) {
|
switch ($mode) {
|
||||||
case ZM_MATCH_ALL:
|
case ZM_MATCH_ALL:
|
||||||
$p = $arg;
|
$p = $arg;
|
||||||
array_shift($p);
|
|
||||||
return trim(implode(" ", $p)) == "" ? $this->waitMessage($prompt_msg) : trim(implode(" ", $p));
|
return trim(implode(" ", $p)) == "" ? $this->waitMessage($prompt_msg) : trim(implode(" ", $p));
|
||||||
case ZM_MATCH_NUMBER:
|
case ZM_MATCH_NUMBER:
|
||||||
foreach ($arg as $k => $v) {
|
foreach ($arg as $k => $v) {
|
||||||
@ -215,9 +214,9 @@ class Context implements ContextInterface
|
|||||||
}
|
}
|
||||||
return $this->waitMessage($prompt_msg);
|
return $this->waitMessage($prompt_msg);
|
||||||
case ZM_MATCH_FIRST:
|
case ZM_MATCH_FIRST:
|
||||||
if (isset($arg[1])) {
|
if (isset($arg[0])) {
|
||||||
$a = $arg[1];
|
$a = $arg[0];
|
||||||
array_splice($arg, 1, 1);
|
array_splice($arg, 0, 1);
|
||||||
ctx()->setCache("match", $arg);
|
ctx()->setCache("match", $arg);
|
||||||
return $a;
|
return $a;
|
||||||
} else {
|
} else {
|
||||||
@ -227,6 +226,22 @@ class Context implements ContextInterface
|
|||||||
throw new InvalidArgumentException();
|
throw new InvalidArgumentException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $prompt_msg
|
||||||
|
* @return int|mixed|string
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* @throws WaitTimeoutException
|
||||||
|
*/
|
||||||
|
public function getNextArg($prompt_msg = "") { return $this->getArgs(ZM_MATCH_FIRST, $prompt_msg); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $prompt_msg
|
||||||
|
* @return int|mixed|string
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* @throws WaitTimeoutException
|
||||||
|
*/
|
||||||
|
public function getFullArg($prompt_msg = "") { return $this->getArgs(ZM_MATCH_ALL, $prompt_msg); }
|
||||||
|
|
||||||
public function cloneFromParent() {
|
public function cloneFromParent() {
|
||||||
set_coroutine_params(self::$context[Co::getPcid()] ?? self::$context[$this->cid]);
|
set_coroutine_params(self::$context[Co::getPcid()] ?? self::$context[$this->cid]);
|
||||||
return context();
|
return context();
|
||||||
|
|||||||
@ -103,6 +103,10 @@ interface ContextInterface
|
|||||||
*/
|
*/
|
||||||
public function getArgs($mode, $prompt_msg);
|
public function getArgs($mode, $prompt_msg);
|
||||||
|
|
||||||
|
public function getNextArg($prompt_msg = "");
|
||||||
|
|
||||||
|
public function getFullArg($prompt_msg = "");
|
||||||
|
|
||||||
public function setCache($key, $value);
|
public function setCache($key, $value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -7,8 +7,12 @@ namespace ZM\Event;
|
|||||||
use Doctrine\Common\Annotations\AnnotationException;
|
use Doctrine\Common\Annotations\AnnotationException;
|
||||||
use Exception;
|
use Exception;
|
||||||
use ZM\Annotation\AnnotationBase;
|
use ZM\Annotation\AnnotationBase;
|
||||||
use ZM\Annotation\CQ\CQMetaEvent;
|
use ZM\Console\Console;
|
||||||
use ZM\Exception\InterruptException;
|
use ZM\Exception\InterruptException;
|
||||||
|
use ZM\Exception\ZMException;
|
||||||
|
use ZM\Store\LightCacheInside;
|
||||||
|
use ZM\Store\Lock\SpinLock;
|
||||||
|
use ZM\Store\ZMAtomic;
|
||||||
use ZM\Utils\ZMUtil;
|
use ZM\Utils\ZMUtil;
|
||||||
|
|
||||||
class EventDispatcher
|
class EventDispatcher
|
||||||
@ -19,6 +23,10 @@ class EventDispatcher
|
|||||||
private $rule = null;
|
private $rule = null;
|
||||||
/** @var null|callable */
|
/** @var null|callable */
|
||||||
private $return_func = null;
|
private $return_func = null;
|
||||||
|
/** @var bool */
|
||||||
|
private $log = false;
|
||||||
|
/** @var int */
|
||||||
|
private $eid = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws InterruptException
|
* @throws InterruptException
|
||||||
@ -27,8 +35,32 @@ class EventDispatcher
|
|||||||
throw new InterruptException('interrupt');
|
throw new InterruptException('interrupt');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function enableEventTrace($event_class) {
|
||||||
|
SpinLock::lock("_event_trace");
|
||||||
|
$list = LightCacheInside::get("wait_api", "event_trace");
|
||||||
|
$list[$event_class] = true;
|
||||||
|
LightCacheInside::set("wait_api", "event_trace", $list);
|
||||||
|
SpinLock::unlock("_event_trace");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function disableEventTrace($event_class) {
|
||||||
|
SpinLock::lock("_event_trace");
|
||||||
|
$list = LightCacheInside::get("wait_api", "event_trace");
|
||||||
|
unset($list[$event_class]);
|
||||||
|
LightCacheInside::set("wait_api", "event_trace", $list);
|
||||||
|
SpinLock::unlock("_event_trace");
|
||||||
|
}
|
||||||
|
|
||||||
public function __construct(string $class = '') {
|
public function __construct(string $class = '') {
|
||||||
$this->class = $class;
|
$this->class = $class;
|
||||||
|
try {
|
||||||
|
$this->eid = ZMAtomic::get("_event_id")->add(1);
|
||||||
|
$list = LightCacheInside::get("wait_api", "event_trace");
|
||||||
|
} catch (ZMException $e) {
|
||||||
|
$list = [];
|
||||||
|
}
|
||||||
|
if (isset($list[$class])) $this->log = true;
|
||||||
|
if ($this->log) Console::verbose("[事件分发{$this->eid}] 开始分发事件: " . $class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setRuleFunction(callable $rule = null) {
|
public function setRuleFunction(callable $rule = null) {
|
||||||
@ -43,10 +75,13 @@ class EventDispatcher
|
|||||||
|
|
||||||
public function dispatchEvents(...$params) {
|
public function dispatchEvents(...$params) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
foreach ((EventManager::$events[$this->class] ?? []) as $v) {
|
foreach ((EventManager::$events[$this->class] ?? []) as $v) {
|
||||||
$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 ($this->log) Console::verbose("[事件分发{$this->eid}] 单一对象 " . $v->class . "::" . $v->method . " 分发结束。");
|
||||||
|
if ($result !== false && is_callable($this->return_func)) {
|
||||||
|
if ($this->log) Console::verbose("[事件分发{$this->eid}] 单一对象 " . $v->class . "::" . $v->method . " 正在执行返回值处理函数 ...");
|
||||||
|
($this->return_func)($result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} catch (InterruptException $e) {
|
} catch (InterruptException $e) {
|
||||||
@ -67,9 +102,15 @@ class EventDispatcher
|
|||||||
public function dispatchEvent(?AnnotationBase $v, $rule_func = null, ...$params) {
|
public function dispatchEvent(?AnnotationBase $v, $rule_func = null, ...$params) {
|
||||||
$q_c = $v->class;
|
$q_c = $v->class;
|
||||||
$q_f = $v->method;
|
$q_f = $v->method;
|
||||||
if ($rule_func !== null && !$rule_func($v)) return false;
|
if ($this->log) Console::verbose("[事件分发{$this->eid}] 正在判断 " . $q_c . "::" . $q_f . " 方法下的 rule ...");
|
||||||
|
if ($rule_func !== null && !$rule_func($v)) {
|
||||||
|
if ($this->log) Console::verbose("[事件分发{$this->eid}] " . $q_c . "::" . $q_f . " 方法下的 rule 判断为 false, 拒绝执行此方法。");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ($this->log) Console::verbose("[事件分发{$this->eid}] " . $q_c . "::" . $q_f . " 方法下的 rule 为真,继续执行方法本身 ...");
|
||||||
if (isset(EventManager::$middleware_map[$q_c][$q_f])) {
|
if (isset(EventManager::$middleware_map[$q_c][$q_f])) {
|
||||||
$middlewares = EventManager::$middleware_map[$q_c][$q_f];
|
$middlewares = EventManager::$middleware_map[$q_c][$q_f];
|
||||||
|
if ($this->log) Console::verbose("[事件分发{$this->eid}] " . $q_c . "::" . $q_f . " 方法还绑定了 Middleware:" . implode(", ", $middlewares));
|
||||||
$before_result = true;
|
$before_result = true;
|
||||||
$r = [];
|
$r = [];
|
||||||
foreach ($middlewares as $k => $middleware) {
|
foreach ($middlewares as $k => $middleware) {
|
||||||
@ -81,22 +122,34 @@ class EventDispatcher
|
|||||||
$r[$k]->class = $q_c;
|
$r[$k]->class = $q_c;
|
||||||
$r[$k]->method = $q_f;
|
$r[$k]->method = $q_f;
|
||||||
if (isset($middleware_obj["before"])) {
|
if (isset($middleware_obj["before"])) {
|
||||||
|
if ($this->log) Console::verbose("[事件分发{$this->eid}] Middleware 存在前置事件,执行中 ...");
|
||||||
$rs = $middleware_obj["before"];
|
$rs = $middleware_obj["before"];
|
||||||
$before_result = $r[$k]->$rs(...$params);
|
$before_result = $r[$k]->$rs(...$params);
|
||||||
if ($before_result === false) break;
|
if ($before_result === false) {
|
||||||
|
if ($this->log) Console::verbose("[事件分发{$this->eid}] Middleware 前置事件为 false,停止执行原事件,开始执行下一事件。");
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if ($this->log) Console::verbose("[事件分发{$this->eid}] Middleware 前置事件为 true,继续执行原事件。");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($before_result) {
|
if ($before_result) {
|
||||||
try {
|
try {
|
||||||
$q_o = ZMUtil::getModInstance($q_c);
|
$q_o = ZMUtil::getModInstance($q_c);
|
||||||
|
if ($this->log) Console::verbose("[事件分发{$this->eid}] 正在执行方法 " . $q_c . "::" . $q_f . " ...");
|
||||||
$result = $q_o->$q_f(...$params);
|
$result = $q_o->$q_f(...$params);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
if ($e instanceof InterruptException) throw $e;
|
if ($e instanceof InterruptException) {
|
||||||
|
if ($this->log) Console::verbose("[事件分发{$this->eid}] 检测到事件阻断调用,正在跳出事件分发器 ...");
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
if ($this->log) Console::verbose("[事件分发{$this->eid}] 方法 " . $q_c . "::" . $q_f . " 执行过程中抛出了异常,正在倒序查找 Middleware 中的捕获方法 ...");
|
||||||
for ($i = count($middlewares) - 1; $i >= 0; --$i) {
|
for ($i = count($middlewares) - 1; $i >= 0; --$i) {
|
||||||
$middleware_obj = EventManager::$middlewares[$middlewares[$i]];
|
$middleware_obj = EventManager::$middlewares[$middlewares[$i]];
|
||||||
if (!isset($middleware_obj["exceptions"])) continue;
|
if (!isset($middleware_obj["exceptions"])) continue;
|
||||||
foreach ($middleware_obj["exceptions"] as $name => $method) {
|
foreach ($middleware_obj["exceptions"] as $name => $method) {
|
||||||
if ($e instanceof $name) {
|
if ($e instanceof $name) {
|
||||||
|
if ($this->log) Console::verbose("[事件分发{$this->eid}] 方法 " . $q_c . "::" . $q_f . " 的异常 " . get_class($e) . " 被 Middleware:" . $middlewares[$i] . " 下的 " . get_class($r[$i]) . "::" . $method . " 捕获。");
|
||||||
$r[$i]->$method($e);
|
$r[$i]->$method($e);
|
||||||
self::interrupt();
|
self::interrupt();
|
||||||
}
|
}
|
||||||
@ -107,7 +160,9 @@ class EventDispatcher
|
|||||||
for ($i = count($middlewares) - 1; $i >= 0; --$i) {
|
for ($i = count($middlewares) - 1; $i >= 0; --$i) {
|
||||||
$middleware_obj = EventManager::$middlewares[$middlewares[$i]];
|
$middleware_obj = EventManager::$middlewares[$middlewares[$i]];
|
||||||
if (isset($middleware_obj["after"], $r[$i])) {
|
if (isset($middleware_obj["after"], $r[$i])) {
|
||||||
|
if ($this->log) Console::verbose("[事件分发{$this->eid}] Middleware 存在后置事件,执行中 ...");
|
||||||
$r[$i]->{$middleware_obj["after"]}(...$params);
|
$r[$i]->{$middleware_obj["after"]}(...$params);
|
||||||
|
if ($this->log) Console::verbose("[事件分发{$this->eid}] Middleware 后置事件执行完毕!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $result;
|
return $result;
|
||||||
@ -115,6 +170,7 @@ class EventDispatcher
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
$q_o = ZMUtil::getModInstance($q_c);
|
$q_o = ZMUtil::getModInstance($q_c);
|
||||||
|
if ($this->log) Console::verbose("[事件分发{$this->eid}] 正在执行方法 " . $q_c . "::" . $q_f . " ...");
|
||||||
return $q_o->$q_f(...$params);
|
return $q_o->$q_f(...$params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,7 @@ use Swoole\Process;
|
|||||||
use Swoole\Timer;
|
use Swoole\Timer;
|
||||||
use ZM\Annotation\AnnotationParser;
|
use ZM\Annotation\AnnotationParser;
|
||||||
use ZM\Annotation\Http\RequestMapping;
|
use ZM\Annotation\Http\RequestMapping;
|
||||||
use ZM\Annotation\Swoole\OnWorkerStart;
|
use ZM\Annotation\Swoole\OnStart;
|
||||||
use ZM\Annotation\Swoole\OnSwooleEvent;
|
use ZM\Annotation\Swoole\OnSwooleEvent;
|
||||||
use ZM\Config\ZMConfig;
|
use ZM\Config\ZMConfig;
|
||||||
use ZM\ConnectionManager\ManagerGM;
|
use ZM\ConnectionManager\ManagerGM;
|
||||||
@ -24,7 +24,7 @@ use ZM\Console\Console;
|
|||||||
use Swoole\Http\Request;
|
use Swoole\Http\Request;
|
||||||
use Swoole\Server;
|
use Swoole\Server;
|
||||||
use Swoole\WebSocket\Frame;
|
use Swoole\WebSocket\Frame;
|
||||||
use ZM\Annotation\Swoole\HandleEvent;
|
use ZM\Annotation\Swoole\SwooleHandler;
|
||||||
use ZM\Console\TermColor;
|
use ZM\Console\TermColor;
|
||||||
use ZM\Context\Context;
|
use ZM\Context\Context;
|
||||||
use ZM\Context\ContextInterface;
|
use ZM\Context\ContextInterface;
|
||||||
@ -33,6 +33,7 @@ use ZM\Exception\DbException;
|
|||||||
use ZM\Framework;
|
use ZM\Framework;
|
||||||
use ZM\Http\Response;
|
use ZM\Http\Response;
|
||||||
use ZM\Module\QQBot;
|
use ZM\Module\QQBot;
|
||||||
|
use ZM\Store\LightCacheInside;
|
||||||
use ZM\Store\MySQL\SqlPoolStorage;
|
use ZM\Store\MySQL\SqlPoolStorage;
|
||||||
use ZM\Store\Redis\ZMRedisPool;
|
use ZM\Store\Redis\ZMRedisPool;
|
||||||
use ZM\Store\ZMBuf;
|
use ZM\Store\ZMBuf;
|
||||||
@ -44,7 +45,7 @@ use ZM\Utils\ZMUtil;
|
|||||||
class ServerEventHandler
|
class ServerEventHandler
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @HandleEvent("start")
|
* @SwooleHandler("start")
|
||||||
*/
|
*/
|
||||||
public function onStart() {
|
public function onStart() {
|
||||||
global $terminal_id;
|
global $terminal_id;
|
||||||
@ -87,14 +88,14 @@ class ServerEventHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @HandleEvent("shutdown")
|
* @SwooleHandler("shutdown")
|
||||||
*/
|
*/
|
||||||
public function onShutdown() {
|
public function onShutdown() {
|
||||||
Console::debug("正在关闭 Master 进程,pid=" . posix_getpid());
|
Console::debug("正在关闭 Master 进程,pid=" . posix_getpid());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @HandleEvent("WorkerStop")
|
* @SwooleHandler("WorkerStop")
|
||||||
* @param $server
|
* @param $server
|
||||||
* @param $worker_id
|
* @param $worker_id
|
||||||
*/
|
*/
|
||||||
@ -103,7 +104,7 @@ class ServerEventHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @HandleEvent("WorkerStart")
|
* @SwooleHandler("WorkerStart")
|
||||||
* @param Server $server
|
* @param Server $server
|
||||||
* @param $worker_id
|
* @param $worker_id
|
||||||
*/
|
*/
|
||||||
@ -205,12 +206,12 @@ class ServerEventHandler
|
|||||||
EventManager::registerTimerTick(); //启动计时器
|
EventManager::registerTimerTick(); //启动计时器
|
||||||
//ZMBuf::unsetCache("wait_start");
|
//ZMBuf::unsetCache("wait_start");
|
||||||
set_coroutine_params(["server" => $server, "worker_id" => $worker_id]);
|
set_coroutine_params(["server" => $server, "worker_id" => $worker_id]);
|
||||||
$dispatcher = new EventDispatcher(OnWorkerStart::class);
|
$dispatcher = new EventDispatcher(OnStart::class);
|
||||||
$dispatcher->setRuleFunction(function ($v) {
|
$dispatcher->setRuleFunction(function ($v) {
|
||||||
return server()->worker_id === $v->worker_id || $v->worker_id === -1;
|
return server()->worker_id === $v->worker_id || $v->worker_id === -1;
|
||||||
});
|
});
|
||||||
$dispatcher->dispatchEvents($server, $worker_id);
|
$dispatcher->dispatchEvents($server, $worker_id);
|
||||||
Console::debug("@OnWorkerStart 执行完毕");
|
Console::debug("@OnStart 执行完毕");
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
Console::error("Worker加载出错!停止服务!");
|
Console::error("Worker加载出错!停止服务!");
|
||||||
Console::error($e->getMessage() . "\n" . $e->getTraceAsString());
|
Console::error($e->getMessage() . "\n" . $e->getTraceAsString());
|
||||||
@ -243,7 +244,7 @@ class ServerEventHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @HandleEvent("message")
|
* @SwooleHandler("message")
|
||||||
* @param $server
|
* @param $server
|
||||||
* @param Frame $frame
|
* @param Frame $frame
|
||||||
*/
|
*/
|
||||||
@ -266,9 +267,9 @@ class ServerEventHandler
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
$starttime = microtime(true);
|
//$starttime = microtime(true);
|
||||||
$dispatcher->dispatchEvents($conn);
|
$dispatcher->dispatchEvents($conn);
|
||||||
Console::success("Used ".round((microtime(true) - $starttime) * 1000, 3)." ms!");
|
//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);
|
||||||
@ -282,7 +283,7 @@ class ServerEventHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @HandleEvent("request")
|
* @SwooleHandler("request")
|
||||||
* @param $request
|
* @param $request
|
||||||
* @param $response
|
* @param $response
|
||||||
*/
|
*/
|
||||||
@ -356,7 +357,7 @@ class ServerEventHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @HandleEvent("open")
|
* @SwooleHandler("open")
|
||||||
* @param $server
|
* @param $server
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
*/
|
*/
|
||||||
@ -369,6 +370,7 @@ class ServerEventHandler
|
|||||||
$conn = ManagerGM::get($request->fd);
|
$conn = ManagerGM::get($request->fd);
|
||||||
set_coroutine_params(["server" => $server, "request" => $request, "connection" => $conn, "fd" => $request->fd]);
|
set_coroutine_params(["server" => $server, "request" => $request, "connection" => $conn, "fd" => $request->fd]);
|
||||||
$conn->setOption("connect_id", strval($request->header["x-self-id"]) ?? "");
|
$conn->setOption("connect_id", strval($request->header["x-self-id"]) ?? "");
|
||||||
|
|
||||||
$dispatcher = new EventDispatcher(OnSwooleEvent::class);
|
$dispatcher = new EventDispatcher(OnSwooleEvent::class);
|
||||||
$dispatcher->setRuleFunction(function ($v) {
|
$dispatcher->setRuleFunction(function ($v) {
|
||||||
if ($v->getRule() == '') {
|
if ($v->getRule() == '') {
|
||||||
@ -380,6 +382,11 @@ class ServerEventHandler
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
|
if ($conn->getName() === 'qq' && ZMConfig::get("global", "modules")["onebot"]["status"] === true) {
|
||||||
|
if (ZMConfig::get("global", "modules")["onebot"]["single_bot_mode"]) {
|
||||||
|
LightCacheInside::set("connect", "conn_fd", $request->fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
$dispatcher->dispatchEvents($conn);
|
$dispatcher->dispatchEvents($conn);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")";
|
$error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")";
|
||||||
@ -394,7 +401,7 @@ class ServerEventHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @HandleEvent("close")
|
* @SwooleHandler("close")
|
||||||
* @param $server
|
* @param $server
|
||||||
* @param $fd
|
* @param $fd
|
||||||
*/
|
*/
|
||||||
@ -404,6 +411,8 @@ class ServerEventHandler
|
|||||||
if ($conn === null) return;
|
if ($conn === null) return;
|
||||||
Console::debug("Calling Swoole \"close\" event from fd=" . $fd);
|
Console::debug("Calling Swoole \"close\" event from fd=" . $fd);
|
||||||
set_coroutine_params(["server" => $server, "connection" => $conn, "fd" => $fd]);
|
set_coroutine_params(["server" => $server, "connection" => $conn, "fd" => $fd]);
|
||||||
|
|
||||||
|
|
||||||
$dispatcher = new EventDispatcher(OnSwooleEvent::class);
|
$dispatcher = new EventDispatcher(OnSwooleEvent::class);
|
||||||
$dispatcher->setRuleFunction(function ($v) {
|
$dispatcher->setRuleFunction(function ($v) {
|
||||||
if ($v->getRule() == '') {
|
if ($v->getRule() == '') {
|
||||||
@ -415,6 +424,11 @@ class ServerEventHandler
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
|
if ($conn->getName() === 'qq' && ZMConfig::get("global", "modules")["onebot"]["status"] === true) {
|
||||||
|
if (ZMConfig::get("global", "modules")["onebot"]["single_bot_mode"]) {
|
||||||
|
LightCacheInside::set("connect", "conn_fd", -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
$dispatcher->dispatchEvents($conn);
|
$dispatcher->dispatchEvents($conn);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")";
|
$error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")";
|
||||||
@ -429,7 +443,7 @@ class ServerEventHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @HandleEvent("pipeMessage")
|
* @SwooleHandler("pipeMessage")
|
||||||
* @param $server
|
* @param $server
|
||||||
* @param $src_worker_id
|
* @param $src_worker_id
|
||||||
* @param $data
|
* @param $data
|
||||||
@ -462,7 +476,7 @@ class ServerEventHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @HandleEvent("task")
|
* @SwooleHandler("task")
|
||||||
*/
|
*/
|
||||||
public function onTask() {
|
public function onTask() {
|
||||||
}
|
}
|
||||||
@ -504,7 +518,7 @@ class ServerEventHandler
|
|||||||
|
|
||||||
//加载插件
|
//加载插件
|
||||||
$plugins = ZMConfig::get("global", "modules") ?? [];
|
$plugins = ZMConfig::get("global", "modules") ?? [];
|
||||||
if (!isset($plugins["onebot"])) $plugins["onebot"] = true;
|
if (!isset($plugins["onebot"])) $plugins["onebot"] = ["status" => true, "single_bot_mode" => false];
|
||||||
|
|
||||||
if ($plugins["onebot"]) {
|
if ($plugins["onebot"]) {
|
||||||
$obj = new OnSwooleEvent();
|
$obj = new OnSwooleEvent();
|
||||||
@ -514,6 +528,11 @@ class ServerEventHandler
|
|||||||
$obj->level = 99999;
|
$obj->level = 99999;
|
||||||
$obj->rule = 'connectIsQQ()';
|
$obj->rule = 'connectIsQQ()';
|
||||||
EventManager::addEvent(OnSwooleEvent::class, $obj);
|
EventManager::addEvent(OnSwooleEvent::class, $obj);
|
||||||
|
if ($plugins["onebot"]["single_bot_mode"]) {
|
||||||
|
LightCacheInside::set("connect", "conn_fd", -1);
|
||||||
|
} else {
|
||||||
|
LightCacheInside::set("connect", "conn_fd", -2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: 编写加载外部插件的方式
|
//TODO: 编写加载外部插件的方式
|
||||||
|
|||||||
@ -4,8 +4,6 @@
|
|||||||
namespace ZM\Exception;
|
namespace ZM\Exception;
|
||||||
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class DbException extends ZMException
|
class DbException extends ZMException
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@ -4,8 +4,6 @@
|
|||||||
namespace ZM\Exception;
|
namespace ZM\Exception;
|
||||||
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class InterruptException extends ZMException
|
class InterruptException extends ZMException
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@ -4,8 +4,6 @@
|
|||||||
namespace ZM\Exception;
|
namespace ZM\Exception;
|
||||||
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class InvalidArgumentException extends ZMException
|
class InvalidArgumentException extends ZMException
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@ -4,8 +4,6 @@
|
|||||||
namespace ZM\Exception;
|
namespace ZM\Exception;
|
||||||
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class NotInitializedException extends ZMException
|
class NotInitializedException extends ZMException
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,6 @@
|
|||||||
namespace ZM\Exception;
|
namespace ZM\Exception;
|
||||||
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -4,7 +4,6 @@
|
|||||||
namespace ZM\Exception;
|
namespace ZM\Exception;
|
||||||
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
class WaitTimeoutException extends ZMException
|
class WaitTimeoutException extends ZMException
|
||||||
|
|||||||
@ -6,7 +6,7 @@ namespace ZM;
|
|||||||
|
|
||||||
use Doctrine\Common\Annotations\AnnotationReader;
|
use Doctrine\Common\Annotations\AnnotationReader;
|
||||||
use Exception;
|
use Exception;
|
||||||
use ZM\Annotation\Swoole\ZMSetup;
|
use ZM\Annotation\Swoole\OnSetup;
|
||||||
use ZM\Config\ZMConfig;
|
use ZM\Config\ZMConfig;
|
||||||
use ZM\ConnectionManager\ManagerGM;
|
use ZM\ConnectionManager\ManagerGM;
|
||||||
use ZM\Event\ServerEventHandler;
|
use ZM\Event\ServerEventHandler;
|
||||||
@ -20,7 +20,7 @@ use ReflectionException;
|
|||||||
use ReflectionMethod;
|
use ReflectionMethod;
|
||||||
use Swoole\Runtime;
|
use Swoole\Runtime;
|
||||||
use Swoole\WebSocket\Server;
|
use Swoole\WebSocket\Server;
|
||||||
use ZM\Annotation\Swoole\HandleEvent;
|
use ZM\Annotation\Swoole\SwooleHandler;
|
||||||
use ZM\Console\Console;
|
use ZM\Console\Console;
|
||||||
use ZM\Utils\ZMUtil;
|
use ZM\Utils\ZMUtil;
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ class Framework
|
|||||||
self::$server = new Server(ZMConfig::get("global", "host"), ZMConfig::get("global", "port"));
|
self::$server = new Server(ZMConfig::get("global", "host"), ZMConfig::get("global", "port"));
|
||||||
$this->server_set = ZMConfig::get("global", "swoole");
|
$this->server_set = ZMConfig::get("global", "swoole");
|
||||||
Console::init(
|
Console::init(
|
||||||
ZMConfig::get("global", "info_level"),
|
ZMConfig::get("global", "info_level") ?? 2,
|
||||||
self::$server,
|
self::$server,
|
||||||
$args["log-theme"] ?? "default",
|
$args["log-theme"] ?? "default",
|
||||||
($o = ZMConfig::get("console_color")) === false ? [] : $o
|
($o = ZMConfig::get("console_color")) === false ? [] : $o
|
||||||
@ -150,11 +150,11 @@ class Framework
|
|||||||
$method_annotations = $reader->getMethodAnnotations($vs);
|
$method_annotations = $reader->getMethodAnnotations($vs);
|
||||||
if ($method_annotations != []) {
|
if ($method_annotations != []) {
|
||||||
$annotation = $method_annotations[0];
|
$annotation = $method_annotations[0];
|
||||||
if ($annotation instanceof HandleEvent) {
|
if ($annotation instanceof SwooleHandler) {
|
||||||
$annotation->class = $v;
|
$annotation->class = $v;
|
||||||
$annotation->method = $vs->getName();
|
$annotation->method = $vs->getName();
|
||||||
$event_list[strtolower($annotation->event)] = $annotation;
|
$event_list[strtolower($annotation->event)] = $annotation;
|
||||||
} elseif ($annotation instanceof ZMSetup) {
|
} elseif ($annotation instanceof OnSetup) {
|
||||||
$annotation->class = $v;
|
$annotation->class = $v;
|
||||||
$annotation->method = $vs->getName();
|
$annotation->method = $vs->getName();
|
||||||
$c = new $v();
|
$c = new $v();
|
||||||
|
|||||||
@ -4,6 +4,8 @@
|
|||||||
namespace ZM\Http;
|
namespace ZM\Http;
|
||||||
|
|
||||||
|
|
||||||
|
use ZM\Console\Console;
|
||||||
|
|
||||||
class Response
|
class Response
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -92,6 +94,7 @@ class Response
|
|||||||
*/
|
*/
|
||||||
public function status($http_code, $reason = null) {
|
public function status($http_code, $reason = null) {
|
||||||
$this->status_code = $http_code;
|
$this->status_code = $http_code;
|
||||||
|
Console::trace();
|
||||||
return $this->response->status($http_code, $reason);
|
return $this->response->status($http_code, $reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +187,8 @@ class Response
|
|||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function redirect($location, $http_code = null) {
|
public function redirect($location, $http_code = null) {
|
||||||
return $this->redirect($location, $http_code);
|
$this->is_end = true;
|
||||||
|
return $this->response->redirect($location, $http_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -21,7 +21,6 @@ use ZM\Utils\CoMessage;
|
|||||||
/**
|
/**
|
||||||
* Class QQBot
|
* Class QQBot
|
||||||
* @package ZM\Module
|
* @package ZM\Module
|
||||||
* @ExternalModule("onebot")
|
|
||||||
*/
|
*/
|
||||||
class QQBot
|
class QQBot
|
||||||
{
|
{
|
||||||
@ -80,12 +79,13 @@ class QQBot
|
|||||||
//分发CQCommand事件
|
//分发CQCommand事件
|
||||||
$dispatcher = new EventDispatcher(CQCommand::class);
|
$dispatcher = new EventDispatcher(CQCommand::class);
|
||||||
$dispatcher->setRuleFunction(function (CQCommand $v) use ($word) {
|
$dispatcher->setRuleFunction(function (CQCommand $v) use ($word) {
|
||||||
if ($v->match == "" && $v->pattern == "" && $v->regex == "") return false;
|
if(array_diff([$v->match, $v->pattern, $v->regex, $v->keyword, $v->end_with, $v->start_with], [""]) == []) 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]) || in_array($word[0], $v->alias)) {
|
if(($word[0] != "" && $v->match == $word[0]) || in_array($word[0], $v->alias)) {
|
||||||
|
array_shift($word);
|
||||||
ctx()->setCache("match", $word);
|
ctx()->setCache("match", $word);
|
||||||
return true;
|
return true;
|
||||||
} elseif ($v->start_with != "" && mb_strpos(ctx()->getMessage(), $v->start_with) === 0) {
|
} elseif ($v->start_with != "" && mb_strpos(ctx()->getMessage(), $v->start_with) === 0) {
|
||||||
@ -94,6 +94,9 @@ class QQBot
|
|||||||
} elseif ($v->end_with != "" && strlen(ctx()->getMessage()) == (strripos(ctx()->getMessage(), $v->end_with) + strlen($v->end_with))) {
|
} elseif ($v->end_with != "" && strlen(ctx()->getMessage()) == (strripos(ctx()->getMessage(), $v->end_with) + strlen($v->end_with))) {
|
||||||
ctx()->setCache("match", [substr(ctx()->getMessage(), 0, strripos(ctx()->getMessage(), $v->end_with))]);
|
ctx()->setCache("match", [substr(ctx()->getMessage(), 0, strripos(ctx()->getMessage(), $v->end_with))]);
|
||||||
return true;
|
return true;
|
||||||
|
} elseif ($v->keyword != "" && mb_strpos(ctx()->getMessage(), $v->keyword) !== false) {
|
||||||
|
ctx()->setCache("match", explode($v->keyword, ctx()->getMessage()));
|
||||||
|
return true;
|
||||||
}elseif ($v->pattern != "") {
|
}elseif ($v->pattern != "") {
|
||||||
$match = matchArgs($v->pattern, ctx()->getMessage());
|
$match = matchArgs($v->pattern, ctx()->getMessage());
|
||||||
if($match !== false) {
|
if($match !== false) {
|
||||||
|
|||||||
@ -179,9 +179,11 @@ class LightCache
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(self::$config["persistence_path"] == "") return;
|
if(self::$config["persistence_path"] == "") return;
|
||||||
|
if (file_exists(self::$config["persistence_path"])) {
|
||||||
$r = file_put_contents(self::$config["persistence_path"], json_encode($r, 128 | 256));
|
$r = file_put_contents(self::$config["persistence_path"], json_encode($r, 128 | 256));
|
||||||
if ($r === false) Console::error("Not saved, please check your \"persistence_path\"!");
|
if ($r === false) Console::error("Not saved, please check your \"persistence_path\"!");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static function checkExpire($key) {
|
private static function checkExpire($key) {
|
||||||
if (($expire = self::$kv_table->get($key, "expire")) >= 0) {
|
if (($expire = self::$kv_table->get($key, "expire")) >= 0) {
|
||||||
|
|||||||
@ -6,6 +6,7 @@ namespace ZM\Store;
|
|||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Swoole\Table;
|
use Swoole\Table;
|
||||||
|
use ZM\Exception\ZMException;
|
||||||
|
|
||||||
class LightCacheInside
|
class LightCacheInside
|
||||||
{
|
{
|
||||||
@ -15,9 +16,11 @@ class LightCacheInside
|
|||||||
public static $last_error = '';
|
public static $last_error = '';
|
||||||
|
|
||||||
public static function init() {
|
public static function init() {
|
||||||
self::$kv_table["wait_api"] = new Table(2, 0);
|
self::$kv_table["wait_api"] = new Table(3, 0);
|
||||||
self::$kv_table["wait_api"]->column("value", Table::TYPE_STRING, 65536);
|
self::$kv_table["wait_api"]->column("value", Table::TYPE_STRING, 65536);
|
||||||
$result = self::$kv_table["wait_api"]->create();
|
self::$kv_table["connect"] = new Table(8, 0);
|
||||||
|
self::$kv_table["connect"]->column("value", Table::TYPE_STRING, 256);
|
||||||
|
$result = self::$kv_table["wait_api"]->create() && self::$kv_table["connect"]->create();
|
||||||
if ($result === false) {
|
if ($result === false) {
|
||||||
self::$last_error = '系统内存不足,申请失败';
|
self::$last_error = '系统内存不足,申请失败';
|
||||||
return $result;
|
return $result;
|
||||||
@ -25,8 +28,14 @@ class LightCacheInside
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $table
|
||||||
|
* @param string $key
|
||||||
|
* @return mixed|null
|
||||||
|
* @throws ZMException
|
||||||
|
*/
|
||||||
public static function get(string $table, string $key) {
|
public static function get(string $table, string $key) {
|
||||||
if (!isset(self::$kv_table[$table])) throw new Exception("not initialized LightCache");
|
if (!isset(self::$kv_table[$table])) throw new ZMException("not initialized LightCache");
|
||||||
$r = self::$kv_table[$table]->get($key);
|
$r = self::$kv_table[$table]->get($key);
|
||||||
return $r === false ? null : json_decode($r["value"], true);
|
return $r === false ? null : json_decode($r["value"], true);
|
||||||
}
|
}
|
||||||
@ -36,10 +45,10 @@ class LightCacheInside
|
|||||||
* @param string $key
|
* @param string $key
|
||||||
* @param string|array|int $value
|
* @param string|array|int $value
|
||||||
* @return mixed
|
* @return mixed
|
||||||
* @throws Exception
|
* @throws ZMException
|
||||||
*/
|
*/
|
||||||
public static function set(string $table, string $key, $value) {
|
public static function set(string $table, string $key, $value) {
|
||||||
if (self::$kv_table === null) throw new Exception("not initialized LightCache");
|
if (self::$kv_table === null) throw new ZMException("not initialized LightCache");
|
||||||
try {
|
try {
|
||||||
return self::$kv_table[$table]->set($key, [
|
return self::$kv_table[$table]->set($key, [
|
||||||
"value" => json_encode($value, 256)
|
"value" => json_encode($value, 256)
|
||||||
|
|||||||
@ -29,6 +29,7 @@ class ZMAtomic
|
|||||||
}
|
}
|
||||||
self::$atomics["stop_signal"] = new Atomic(0);
|
self::$atomics["stop_signal"] = new Atomic(0);
|
||||||
self::$atomics["wait_msg_id"] = new Atomic(0);
|
self::$atomics["wait_msg_id"] = new Atomic(0);
|
||||||
|
self::$atomics["_event_id"] = new Atomic(0);
|
||||||
for ($i = 0; $i < 10; ++$i) {
|
for ($i = 0; $i < 10; ++$i) {
|
||||||
self::$atomics["_tmp_" . $i] = new Atomic(0);
|
self::$atomics["_tmp_" . $i] = new Atomic(0);
|
||||||
}
|
}
|
||||||
|
|||||||
24
src/ZM/Utils/SingletonTrait.php
Normal file
24
src/ZM/Utils/SingletonTrait.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace ZM\Utils;
|
||||||
|
|
||||||
|
|
||||||
|
trait SingletonTrait
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var self
|
||||||
|
*/
|
||||||
|
private static $instance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public static function getInstance() {
|
||||||
|
if (null === self::$instance) {
|
||||||
|
self::$instance = new self();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -37,9 +37,6 @@ class ZMUtil
|
|||||||
if (($v["result"] ?? false) === 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");
|
LightCacheInside::unset("wait_api", "wait_api");
|
||||||
foreach (server()->connections as $v) {
|
|
||||||
server()->close($v);
|
|
||||||
}
|
|
||||||
LightCache::savePersistence();
|
LightCache::savePersistence();
|
||||||
//DataProvider::saveBuffer();
|
//DataProvider::saveBuffer();
|
||||||
Timer::clearAll();
|
Timer::clearAll();
|
||||||
|
|||||||
@ -1,16 +1,20 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Swoole\Coroutine;
|
use Swoole\Coroutine;
|
||||||
|
use ZM\API\ZMRobot;
|
||||||
use ZM\Config\ZMConfig;
|
use ZM\Config\ZMConfig;
|
||||||
|
use ZM\ConnectionManager\ManagerGM;
|
||||||
use ZM\Console\Console;
|
use ZM\Console\Console;
|
||||||
use ZM\Context\Context;
|
use ZM\Context\Context;
|
||||||
use ZM\Event\EventManager;
|
use ZM\Event\EventManager;
|
||||||
|
use ZM\Exception\RobotNotFoundException;
|
||||||
|
use ZM\Exception\ZMException;
|
||||||
use ZM\Framework;
|
use ZM\Framework;
|
||||||
|
use ZM\Store\LightCacheInside;
|
||||||
use ZM\Store\ZMBuf;
|
use ZM\Store\ZMBuf;
|
||||||
use ZM\Utils\DataProvider;
|
use ZM\Utils\DataProvider;
|
||||||
use Swoole\Coroutine\System;
|
use Swoole\Coroutine\System;
|
||||||
use ZM\Context\ContextInterface;
|
use ZM\Context\ContextInterface;
|
||||||
use ZM\Utils\ZMUtil;
|
|
||||||
|
|
||||||
|
|
||||||
function phar_classloader($p) {
|
function phar_classloader($p) {
|
||||||
@ -227,7 +231,7 @@ function ctx() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function debug($msg) { Console::debug($msg); }
|
function zm_debug($msg) { Console::debug($msg); }
|
||||||
|
|
||||||
function onebot_target_id_name($message_type) {
|
function onebot_target_id_name($message_type) {
|
||||||
return ($message_type == "group" ? "group_id" : "user_id");
|
return ($message_type == "group" ? "group_id" : "user_id");
|
||||||
@ -268,6 +272,22 @@ function server() {
|
|||||||
return Framework::$server;
|
return Framework::$server;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ZMRobot
|
||||||
|
* @throws RobotNotFoundException
|
||||||
|
* @throws ZMException
|
||||||
|
*/
|
||||||
|
function bot() {
|
||||||
|
if (($conn = LightCacheInside::get("connect", "conn_fd")) == -2) {
|
||||||
|
return ZMRobot::getRandom();
|
||||||
|
} elseif ($conn != -1) {
|
||||||
|
if (($obj = ManagerGM::get($conn)) !== null) return new ZMRobot($obj);
|
||||||
|
else throw new RobotNotFoundException("单机器人连接模式可能连接了多个机器人!");
|
||||||
|
} else {
|
||||||
|
throw new RobotNotFoundException("没有任何机器人连接到框架!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use Module\Example\Hello;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use ReflectionException;
|
use ReflectionException;
|
||||||
use ZM\Annotation\AnnotationParser;
|
use ZM\Annotation\AnnotationParser;
|
||||||
use ZM\Annotation\Swoole\OnWorkerStart;
|
use ZM\Annotation\Swoole\OnStart;
|
||||||
use ZM\Console\Console;
|
use ZM\Console\Console;
|
||||||
|
|
||||||
class AnnotationParserRegisterTest extends TestCase
|
class AnnotationParserRegisterTest extends TestCase
|
||||||
@ -34,8 +34,8 @@ class AnnotationParserRegisterTest extends TestCase
|
|||||||
public function testAnnotation() {
|
public function testAnnotation() {
|
||||||
ob_start();
|
ob_start();
|
||||||
$gen = $this->parser->generateAnnotationEvents();
|
$gen = $this->parser->generateAnnotationEvents();
|
||||||
$m = $gen[OnWorkerStart::class][0]->method;
|
$m = $gen[OnStart::class][0]->method;
|
||||||
$class = $gen[OnWorkerStart::class][0]->class;
|
$class = $gen[OnStart::class][0]->class;
|
||||||
$c = new $class();
|
$c = new $class();
|
||||||
try {
|
try {
|
||||||
$c->$m();
|
$c->$m();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user