Files
zhamao-framework/src/ZM/Module/QQBot.php

174 lines
7.8 KiB
PHP
Raw Normal View History

2020-09-29 15:07:43 +08:00
<?php
namespace ZM\Module;
use Exception;
2020-11-03 21:02:24 +08:00
use ZM\Annotation\CQ\CQAPIResponse;
use ZM\Annotation\CQ\CQBefore;
use ZM\Annotation\CQ\CQCommand;
use ZM\Annotation\CQ\CQMessage;
use ZM\Annotation\CQ\CQMetaEvent;
use ZM\Annotation\CQ\CQNotice;
use ZM\Annotation\CQ\CQRequest;
use ZM\Event\EventDispatcher;
use ZM\Exception\InterruptException;
use ZM\Exception\WaitTimeoutException;
use ZM\Utils\CoMessage;
use ZM\Utils\MessageUtil;
use ZM\Utils\SingletonTrait;
2020-11-03 21:02:24 +08:00
2020-09-29 15:07:43 +08:00
/**
* Class QQBot
2020-10-03 23:00:18 +08:00
* @package ZM\Module
2020-09-29 15:07:43 +08:00
*/
class QQBot
{
use SingletonTrait;
public function handleByEvent() {
$data = json_decode(context()->getFrame()->data, true);
$this->handle($data);
}
2020-11-03 21:02:24 +08:00
/**
* @param $data
* @param int $level
2020-11-03 21:02:24 +08:00
* @throws InterruptException
*/
public function handle($data, $level = 0) {
2020-11-03 21:02:24 +08:00
try {
if ($level > 10) return;
set_coroutine_params(["data" => $data]);
2020-11-03 21:02:24 +08:00
if (isset($data["post_type"])) {
//echo TermColor::ITALIC.json_encode($data, 128|256).TermColor::RESET.PHP_EOL;
ctx()->setCache("level", $level);
2020-11-03 21:02:24 +08:00
//Console::debug("Calling CQ Event from fd=" . ctx()->getConnection()->getFd());
if ($data["post_type"] != "meta_event") {
$r = $this->dispatchBeforeEvents($data, "pre"); // before在这里执行元事件不执行before为减少不必要的调试日志
if ($r->store === "block") EventDispatcher::interrupt();
}
2020-11-03 21:02:24 +08:00
//Console::warning("最上数据包:".json_encode($data));
}
if (isset($data["echo"]) || isset($data["post_type"])) {
if (CoMessage::resumeByWS()) EventDispatcher::interrupt();
}
if (($data["post_type"] ?? "meta_event") != "meta_event") {
$r = $this->dispatchBeforeEvents($data, "post"); // before在这里执行元事件不执行before为减少不必要的调试日志
if ($r->store === "block") EventDispatcher::interrupt();
}
if (isset($data["post_type"])) $this->dispatchEvents($data);
else $this->dispatchAPIResponse($data);
2020-11-03 21:02:24 +08:00
} /** @noinspection PhpRedundantCatchClauseInspection */ catch (WaitTimeoutException $e) {
$e->module->finalReply($e->getMessage());
}
}
/**
* @param $data
* @param $time
* @return EventDispatcher
* @throws Exception
*/
public function dispatchBeforeEvents($data, $time): EventDispatcher {
2020-11-03 21:02:24 +08:00
$before = new EventDispatcher(CQBefore::class);
if ($time === "pre") {
$before->setRuleFunction(function($v) use ($data){
return $v->level >= 200 && $v->cq_event == $data["post_type"];
});
} else {
$before->setRuleFunction(function($v) use ($data){
return $v->level < 200 && $v->cq_event == $data["post_type"];
});
}
2020-11-03 21:02:24 +08:00
$before->setReturnFunction(function ($result) {
if (!$result) EventDispatcher::interrupt("block");
2020-11-03 21:02:24 +08:00
});
$before->dispatchEvents($data);
return $before;
2020-11-03 21:02:24 +08:00
}
/**
* @param $data
* @throws InterruptException
* @throws Exception
*/
2020-11-03 21:02:24 +08:00
private function dispatchEvents($data) {
//Console::warning("最xia数据包".json_encode($data));
switch ($data["post_type"]) {
case "message":
//分发CQCommand事件
$dispatcher = new EventDispatcher(CQCommand::class);
$dispatcher->setReturnFunction(function ($result) {
if (is_string($result)) ctx()->reply($result);
if (ctx()->getCache("has_reply") === true) EventDispatcher::interrupt();
2020-11-03 21:02:24 +08:00
});
$s = MessageUtil::matchCommand(ctx()->getMessage(), 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();
}
2020-11-03 21:02:24 +08:00
//分发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"]));
});
$msg_dispatcher->setReturnFunction(function ($result) {
if (is_string($result)) ctx()->reply($result);
});
$msg_dispatcher->dispatchEvents(ctx()->getMessage());
return;
case "meta_event":
//Console::success("当前数据包:".json_encode(ctx()->getData()));
$dispatcher = new EventDispatcher(CQMetaEvent::class);
$dispatcher->setRuleFunction(function (CQMetaEvent $v) {
2020-12-31 16:26:51 +08:00
return ($v->meta_event_type == '' || ($v->meta_event_type != '' && $v->meta_event_type == ctx()->getData()["meta_event_type"]));
2020-11-03 21:02:24 +08:00
});
//eval(BP);
$dispatcher->dispatchEvents(ctx()->getData());
return;
case "notice":
$dispatcher = new EventDispatcher(CQNotice::class);
$dispatcher->setRuleFunction(function (CQNotice $v) {
return
($v->notice_type == '' || ($v->notice_type != '' && $v->notice_type == ctx()->getData()["notice_type"])) &&
($v->sub_type == '' || ($v->sub_type != '' && $v->sub_type == ctx()->getData()["sub_type"])) &&
($v->group_id == '' || ($v->group_id != '' && $v->group_id == ctx()->getData()["group_id"])) &&
($v->operator_id == '' || ($v->operator_id != '' && $v->operator_id == ctx()->getData()["operator_id"]));
});
$dispatcher->dispatchEvents(ctx()->getData());
return;
case "request":
$dispatcher = new EventDispatcher(CQRequest::class);
$dispatcher->setRuleFunction(function (CQRequest $v) {
return ($v->request_type == '' || ($v->request_type != '' && $v->request_type == ctx()->getData()['request_type'])) &&
($v->sub_type == '' || ($v->sub_type != '' && $v->sub_type == ctx()->getData()['sub_type'])) &&
($v->user_id == 0 || ($v->user_id != 0 && $v->user_id == ctx()->getData()["user_id"])) &&
($v->comment == '' || ($v->comment != '' && $v->comment == ctx()->getData()['comment']));
});
$dispatcher->dispatchEvents(ctx()->getData());
return;
}
}
/**
* @param $req
* @throws Exception
*/
2020-11-03 21:02:24 +08:00
private function dispatchAPIResponse($req) {
set_coroutine_params(["cq_response" => $req]);
$dispatcher = new EventDispatcher(CQAPIResponse::class);
$dispatcher->setRuleFunction(function (CQAPIResponse $response) {
return $response->retcode == ctx()->getCQResponse()["retcode"];
});
$dispatcher->dispatchEvents($req);
2020-09-29 15:07:43 +08:00
}
}