Compare commits

...

10 Commits
2.6.0 ... 2.6.2

Author SHA1 Message Date
Jerry Ma
176b690417 Update v2.md 2021-12-07 13:28:21 +08:00
Jerry Ma
e22b1b90ec Update build-update.md 2021-12-07 13:27:33 +08:00
Jerry Ma
a3c560790c Merge pull request #55 from zhamao-robot/fix/cqafter
update to build 429
2021-12-07 13:25:55 +08:00
570e2108dd - 新增配置项 onebot.message_command_policy
- 新增 CQCommand 阻断策略的自定义配置功能
- 修复 CQAfter 无法正常使用的 bug #53
2021-12-07 13:21:29 +08:00
Jerry Ma
59c0d95e5d Create 2_Feature_request.yaml 2021-12-07 12:34:18 +08:00
Jerry Ma
9ceaecdc02 Update README.md 2021-12-07 12:17:47 +08:00
Jerry Ma
19d50898ef Create 1_Bug_report.yaml 2021-12-07 12:15:49 +08:00
Jerry Ma
5b62ca62ae Update README.md 2021-11-17 00:28:54 +08:00
fb528d30ce update docs 2021-11-16 16:51:05 +08:00
5f2d5ed334 update to build 428 2021-11-16 16:49:32 +08:00
12 changed files with 223 additions and 20 deletions

View File

@@ -0,0 +1,38 @@
name: 🐛 漏洞BUG报告
description: ⚠️ 请不要直接在此提交安全漏洞
labels: bug
body:
- type: input
id: affected-versions
attributes:
label: 受影响版本
placeholder: x.y.z
validations:
required: true
- type: textarea
id: description
attributes:
label: 描述
description: 请详细地描述您的问题
validations:
required: true
- type: textarea
id: reproduce-steps
attributes:
label: 复现步骤
description: |
请尽可能地提供可以复现此步骤的漏洞。
如果步骤过长或难以描述,您可以自行建立一个用于复现漏洞的仓库。
validations:
required: true
- type: textarea
id: possible-solution
attributes:
label: 解决方案
description: 如果您对这个漏洞的成因或修复有任何意见的话,请在此提出
- type: textarea
id: additional-context
attributes:
label: 附加信息
description: 其他可能有帮助的信息,如日志、截图等

View File

@@ -0,0 +1,19 @@
name: 🚀 功能建议
description: 新功能、改进的意见、草案
labels: enhancement
body:
- type: textarea
id: description
attributes:
label: 描述
description: 请提供简洁清楚的描述
validations:
required: true
- type: textarea
id: example
attributes:
label: 例子
description: |
一个简单的例子,展示该功能将如何被使用(包括代码、配置文件等)
如果这是针对已有功能的改进,请展示改进前后使用方式(或效能)的对比

View File

@@ -110,4 +110,10 @@ vendor/bin/start server
在贡献代码时,请保管好自己的全局配置文件中的敏感信息,请勿将带有个人信息的配置文件上传 GitHub 等网站。
![star](https://starchart.cc/zhamao-robot/zhamao-framework.svg)
感谢 JetBrains 为此开源项目提供 PhpStorm 开发工具支持:
<img src="https://resources.jetbrains.com/storage/products/company/brand/logos/PhpStorm.svg" width="300">
感谢 [php-libonebot](https://github.com/botuniverse/php-libonebot) 开发者 @sunxyw 中为项目开发规范化提出的一些建议。
<!-- ![star](https://starchart.cc/zhamao-robot/zhamao-framework.svg) -->

View File

@@ -123,7 +123,8 @@ $config['onebot'] = [
'status' => true,
'single_bot_mode' => false,
'message_level' => 99,
'message_convert_string' => true
'message_convert_string' => true,
'message_command_policy' => 'interrupt',
];
/** 一个远程简易终端使用nc直接连接即可但是不建议开放host为0.0.0.0(远程连接) */

View File

@@ -128,3 +128,52 @@ public function onStart() {
( 其实还是很聪明的!
</chat-box>
### strToArray()
`string` 类型的消息文本转换为 `array` 格式。
定义:`strToArray($msg, bool $ignore_space = true, bool $trim_text = false)`
参数 `$msg` 为带 OB/CQ 码的字符串消息,如 `你好啊,[CQ:at,qq=123]`
参数 `$ignore_space``false` 时,转换的数组内会包含空 `text` 段。
参数 `$trim_text``true` 时,会自动去除 `text` 段消息头尾的换行符和空格。
这个命令转换的数组格式符合 OneBot 11/12 标准,但细节上可能会与不同 OneBot 实现有所差异。
```php
$str = "你好啊,[CQ:at,qq=123]";
$arr = \ZM\Utils\MessageUtil::strToArray($str);
```
转换结果参考如下:
```json
[
{
"type": "text",
"data": {
"text": "你好啊,"
}
},
{
"type": "at",
"data": {
"qq": "123"
}
}
]
```
### arrayToStr()
`array` 格式的消息内容转换为字符串 + CQ 码的形式。
定义:`arrayToStr(array $array)`
```php
// 我们使用上边的 $arr 作为传入值。
$new_str = \ZM\Utils\MessageUtil::arrayToStr($arr);
// 结果:"你好啊,[CQ:at,qq=123]"
```

View File

@@ -56,6 +56,8 @@
| `swoole_coroutine_hook_flags` | Swoole 启动时一键协程化 Hook 的 Flag 值,详见 [一键协程化](http://wiki.swoole.com/#/runtime?id=%e5%87%bd%e6%95%b0%e5%8e%9f%e5%9e%8b) | `SWOOLE_HOOK_ALL & (~SWOOLE_HOOK_CURL)` |
| `swoole_server_mode` | Swoole Server 启动的进程模式,有 `SWOOLE_PROCESS``SWOOLE_BASE` 两种,见 [启动方式](http://wiki.swoole.com/#/learn?id=swoole_process) | `SWOOLE_PROCESS` |
| `middleware_error_policy` | 中间件错误处理策略,见 [中间件 - 错误处理策略](../../event/middleware/#_6) | 1 |
| `reload_delay_time` | 框架 reload 重载命令接收后延迟的时间毫秒0 为不等待) | 800 |
| `global_middleware_binding` | 给注解事件绑定全局中间件,见 [中间件 - 全局中间件](../../event/middleware/#_6) | `[]` |
### 子表 **light_cache**
@@ -106,11 +108,13 @@
### 子表 onebot
| 配置名称 | 说明 | 默认值 |
| ----------------- | ------------------------------------------------------------ | ------ |
| `status` | 是否开启 OneBot 标准机器人解析功能 | true |
| `single_bot_mode` | 是否开启单机器人模式 | false |
| `message_level` | 机器人的 WebSocket 事件在 Swoole 原生事件 `@OnMessageEvent` 中的等级(越高说明越被优先处理) | 99999 |
| 配置名称 | 说明 | 默认值 |
| ------------------------ | ------------------------------------------------------------ | ------ |
| `status` | 是否开启 OneBot 标准机器人解析功能 | true |
| `single_bot_mode` | 是否开启单机器人模式 | false |
| `message_level` | 机器人的 WebSocket 事件在 Swoole 原生事件 `@OnMessageEvent` 中的等级(越高说明越被优先处理) | 99 |
| `message_convert_string` | 是否将数组格式的消息转换为字符串以保证与旧版本的兼容性 | true |
| `message_command_policy` | CQCommand命令匹配后执行流程`interrupt` 为不执行后续 CQMessage`continue` 为继续 | `interrupt` |
### 子表 remote_terminal

View File

@@ -4,6 +4,18 @@
同时此处将只使用 build 版本号进行区分。
## build 429 (2021-12-7)
- 新增配置项 `onebot`.`message_command_policy`
- 新增 CQCommand 阻断策略的自定义配置功能
- 修复 CQAfter 无法正常使用的 bug #53
## build 428 (2021-11-16)
- 修复 `ctx()->waitMessage()` 在 array 消息模式下无法正确返回消息字符串的问题
- 新增 `ctx()->getArrayMessage()``ctx()->getStringMessage()` 两个方法
- 修复注解事件 `CQCommand``CQMessage` 在 array 消息模式下无法正确解析的 Bug
## build 427 (2021-11-16)
- 新增全局中间件,可在全局配置文件中设置

View File

@@ -1,5 +1,21 @@
# 更新日志v2 版本)
## v2.6.2 (build 429)
> 更新时间2021.12.7
- 新增配置项 `onebot`.`message_command_policy`
- 新增 CQCommand 阻断策略的自定义配置功能
- 修复 CQAfter 无法正常使用的 bug #53
## v2.6.1 (build 428)
> 更新时间2021.11.16
- 修复 ctx()->waitMessage() 在 array 消息模式下无法正确返回消息字符串的问题
- 新增 ctx()->getArrayMessage() 和 ctx()->getStringMessage() 两个方法
- 修复注解事件 CQCommand 和 CQMessage 在 array 消息模式下无法正确解析的 Bug
## v2.6.0 (build 427)
> 更新时间2021.11.16

View File

@@ -30,8 +30,8 @@ class ConsoleApplication extends Application
{
private static $obj = null;
const VERSION_ID = 427;
const VERSION = "2.6.0";
const VERSION_ID = 429;
const VERSION = "2.6.2";
/**
* @throws InitException
@@ -75,7 +75,7 @@ class ConsoleApplication extends Application
$composer["autoload"]["psr-4"]["Custom\\"] = "src/Custom";
$r = file_put_contents(WORKING_DIR . "/composer.json", json_encode($composer, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
if ($r !== false) {
echo "成功添加!请运行 composer dump-autoload \n";
echo "成功添加!请运行 'composer dump-autoload'\n";
exit(0);
} else {
echo zm_internal_errcode("E00006") . "添加失败!请按任意键继续!";

View File

@@ -181,7 +181,11 @@ class Context implements ContextInterface
if ($r === false) {
throw new WaitTimeoutException($this, $timeout_prompt);
}
return $r["message"];
if (is_array($r["message"]) && (ZMConfig::get("global", "onebot")["message_convert_string"] ?? true) === true) {
return MessageUtil::arrayToStr($r["message"]);
} else {
return $r["message"];
}
}
/**
@@ -254,4 +258,16 @@ class Context implements ContextInterface
public function getOption() { return self::getCache("match"); }
public function getOriginMessage() { return self::$context[$this->cid]["data"]["message"] ?? null; }
public function getArrayMessage(): array {
$msg = $this->getOriginMessage();
if (is_array($msg)) return $msg;
else return MessageUtil::strToArray($msg);
}
public function getStringMessage(): string {
$msg = $this->getOriginMessage();
if (is_string($msg)) return $msg;
else return MessageUtil::arrayToStr($msg);
}
}

View File

@@ -4,6 +4,7 @@
namespace ZM\Module;
use Exception;
use ZM\Annotation\CQ\CQAfter;
use ZM\Annotation\CQ\CQAPIResponse;
use ZM\Annotation\CQ\CQBefore;
use ZM\Annotation\CQ\CQCommand;
@@ -11,6 +12,7 @@ use ZM\Annotation\CQ\CQMessage;
use ZM\Annotation\CQ\CQMetaEvent;
use ZM\Annotation\CQ\CQNotice;
use ZM\Annotation\CQ\CQRequest;
use ZM\Config\ZMConfig;
use ZM\Event\EventDispatcher;
use ZM\Exception\InterruptException;
use ZM\Exception\WaitTimeoutException;
@@ -59,9 +61,25 @@ class QQBot
}
if (isset($data["post_type"])) $this->dispatchEvents($data);
else $this->dispatchAPIResponse($data);
if (($data["post_type"] ?? "meta_event") != "meta_event") {
$r = $this->dispatchAfterEvents($data); // before在这里执行元事件不执行before为减少不必要的调试日志
if ($r->store === "block") EventDispatcher::interrupt();
}
} /** @noinspection PhpRedundantCatchClauseInspection */ catch (WaitTimeoutException $e) {
if (($data["post_type"] ?? "meta_event") != "meta_event") {
$r = $this->dispatchAfterEvents($data); // before在这里执行元事件不执行before为减少不必要的调试日志
if ($r->store === "block") EventDispatcher::interrupt();
}
$e->module->finalReply($e->getMessage());
} catch (InterruptException $e) {
if (($data["post_type"] ?? "meta_event") != "meta_event") {
$r = $this->dispatchAfterEvents($data); // before在这里执行元事件不执行before为减少不必要的调试日志
if ($r->store === "block") EventDispatcher::interrupt();
}
throw $e;
}
// 这里修复CQAfter不能使用的问题我竟然一直没写绝了
}
/**
@@ -73,11 +91,11 @@ class QQBot
public function dispatchBeforeEvents($data, $time): EventDispatcher {
$before = new EventDispatcher(CQBefore::class);
if ($time === "pre") {
$before->setRuleFunction(function($v) use ($data){
$before->setRuleFunction(function ($v) use ($data) {
return $v->level >= 200 && $v->cq_event == $data["post_type"];
});
} else {
$before->setRuleFunction(function($v) use ($data){
$before->setRuleFunction(function ($v) use ($data) {
return $v->level < 200 && $v->cq_event == $data["post_type"];
});
}
@@ -103,22 +121,33 @@ class QQBot
if (is_string($result)) ctx()->reply($result);
if (ctx()->getCache("has_reply") === true) EventDispatcher::interrupt();
});
$s = MessageUtil::matchCommand(ctx()->getMessage(), ctx()->getData());
$s = MessageUtil::matchCommand(ctx()->getStringMessage(), ctx()->getData());
if ($s->status !== false) {
if (!empty($s->match)) ctx()->setCache("match", $s->match);
$dispatcher->dispatchEvent($s->object, null);
if (is_string($dispatcher->store)) ctx()->reply($dispatcher->store);
if (ctx()->getCache("has_reply") === true) EventDispatcher::interrupt();
if (ctx()->getCache("has_reply") === true) {
$policy = ZMConfig::get("global", "onebot")['message_command_policy'] ?? 'interrupt';
switch ($policy) {
case 'interrupt':
EventDispatcher::interrupt();
break;
case 'continue':
break;
default:
throw new Exception("未知的消息命令策略:" . $policy);
}
}
}
//分发CQMessage事件
$msg_dispatcher = new EventDispatcher(CQMessage::class);
$msg_dispatcher->setRuleFunction(function ($v) {
return ($v->message == '' || ($v->message != '' && $v->message == context()->getData()["message"])) &&
($v->user_id == 0 || ($v->user_id != 0 && $v->user_id == context()->getData()["user_id"])) &&
($v->group_id == 0 || ($v->group_id != 0 && $v->group_id == (context()->getData()["group_id"] ?? 0))) &&
($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"]));
return ($v->message == '' || ($v->message == ctx()->getStringMessage())) &&
($v->user_id == 0 || ($v->user_id == ctx()->getUserId())) &&
($v->group_id == 0 || ($v->group_id == (ctx()->getGroupId() ?? 0))) &&
($v->message_type == '' || ($v->message_type == ctx()->getMessageType())) &&
($v->raw_message == '' || ($v->raw_message == context()->getData()["raw_message"]));
});
$msg_dispatcher->setReturnFunction(function ($result) {
if (is_string($result)) ctx()->reply($result);
@@ -158,6 +187,16 @@ class QQBot
}
}
private function dispatchAfterEvents($data): EventDispatcher {
$after = new EventDispatcher(CQAfter::class);
$after->setRuleFunction(function ($v) use ($data) {
return $v->cq_event == $data["post_type"];
});
zm_dump("开始触发!", $data);
$after->dispatchEvents($data);
return $after;
}
/**
* @param $req
* @throws Exception

View File

@@ -111,6 +111,9 @@ class MessageUtil
*/
public static function matchCommand($msg, $obj): MatchResult {
$ls = EventManager::$events[CQCommand::class] ?? [];
if (is_array($msg)) {
$msg = self::arrayToStr($msg);
}
$word = self::splitCommand($msg);
$matched = new MatchResult();
foreach ($ls as $v) {