update to build 424 (2.6.0-alpha1)

This commit is contained in:
crazywhalecc
2021-11-02 16:01:24 +08:00
parent 85ef09d43c
commit d3c420ec84
13 changed files with 215 additions and 51 deletions

View File

@@ -39,7 +39,10 @@ $config['swoole'] = [
$config['runtime'] = [
'swoole_coroutine_hook_flags' => SWOOLE_HOOK_ALL & (~SWOOLE_HOOK_CURL),
'swoole_server_mode' => SWOOLE_PROCESS,
'middleware_error_policy' => 1
'middleware_error_policy' => 1,
'reload_kill_connect' => false,
'global_middleware_binding' => [
]
];
/** 轻量字符串缓存,默认开启 */
@@ -120,7 +123,8 @@ $config['static_file_server'] = [
$config['onebot'] = [
'status' => true,
'single_bot_mode' => false,
'message_level' => 99999
'message_level' => 99,
'message_format' => 'string'
];
/** 一个远程简易终端使用nc直接连接即可但是不建议开放host为0.0.0.0(远程连接) */

25
instant-test.php Normal file
View File

@@ -0,0 +1,25 @@
<?php
require_once "vendor/autoload.php";
use ZM\Annotation\CQ\CQCommand;
use ZM\Annotation\Swoole\OnOpenEvent;
use ZM\ConnectionManager\ConnectionObject;
use ZM\Console\Console;
use ZM\Module\InstantModule;
use ZM\ZMServer;
$weather = new InstantModule("weather");
$weather->onEvent(OnOpenEvent::class, ['connect_type' => 'qq'], function(ConnectionObject $conn) {
Console::info("机器人 " . $conn->getOption("connect_id") . " 已连接!");
});
$weather->onEvent(CQCommand::class, ['match' => '你好'], function() {
ctx()->reply("hello呀");
});
$app = new ZMServer("app-name");
$app->addModule($weather);
$app->run();

View File

@@ -50,4 +50,10 @@ class RunServerCommand extends Command
(new Framework($input->getOptions()))->start();
return 0;
}
public static function exportDefinition() {
$cmd = new self();
$cmd->configure();
return $cmd->getDefinition();
}
}

View File

@@ -21,15 +21,14 @@ use ZM\Command\RunServerCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use ZM\Console\Console;
use ZM\Exception\InitException;
class ConsoleApplication extends Application
{
private static $obj = null;
const VERSION_ID = 423;
const VERSION = "2.5.6";
const VERSION_ID = 424;
const VERSION = "2.6.0";
/**
* @throws InitException
@@ -49,7 +48,8 @@ class ConsoleApplication extends Application
*/
public function initEnv($with_default_cmd = ""): ConsoleApplication {
if (defined("WORKDING_DIR")) throw new InitException();
$this->selfCheck();
_zm_env_check();
define("WORKING_DIR", getcwd());
if (Phar::running() !== "") {
@@ -121,17 +121,4 @@ class ConsoleApplication extends Application
die(zm_internal_errcode("E00005") . "{$e->getMessage()} at {$e->getFile()}({$e->getLine()})");
}
}
/**
* 启动炸毛前要做的环境检查项目
*/
private function selfCheck(): void {
if (!extension_loaded("swoole")) die(zm_internal_errcode("E00001") . "Can not find swoole extension.\n");
if (version_compare(SWOOLE_VERSION, "4.5.0") == -1) die(zm_internal_errcode("E00002") . "You must install swoole version >= 4.5.0 !");
if (version_compare(PHP_VERSION, "7.2") == -1) die(zm_internal_errcode("E00003") . "PHP >= 7.2 required.");
if (version_compare(SWOOLE_VERSION, "4.6.7") < 0 && !extension_loaded("pcntl")) {
Console::error(zm_internal_errcode("E00004") . "Swoole 版本必须不低于 4.6.7 或 PHP 安装加载了 pcntl 扩展!");
die();
}
}
}

View File

@@ -91,7 +91,7 @@ class EventDispatcher
try {
foreach ((EventManager::$events[$this->class] ?? []) as $v) {
$this->dispatchEvent($v, $this->rule, ...$params);
if ($this->log) Console::verbose("[事件分发{$this->eid}] 单一对象 " . $v->class . "::" . $v->method . " 分发结束。");
if ($this->log) Console::verbose("[事件分发{$this->eid}] 单一对象 " . $v->class . "::" . (is_string($v->method) ? $v->method : "{closure}") . " 分发结束。");
if ($this->status == self::STATUS_BEFORE_FAILED || $this->status == self::STATUS_RULE_FAILED) continue;
if (is_callable($this->return_func) && $this->status === self::STATUS_NORMAL) {
if ($this->log) Console::verbose("[事件分发{$this->eid}] 单一对象 " . $v->class . "::" . $v->method . " 正在执行返回值处理函数 ...");
@@ -121,7 +121,7 @@ class EventDispatcher
public function dispatchEvent($v, $rule_func = null, ...$params) {
$q_c = $v->class;
$q_f = $v->method;
if ($q_c === "" && ($q_f instanceof Closure)) {
if (($q_c ?? "") === "" && ($q_f instanceof Closure)) {
if ($this->log) Console::verbose("[事件分发{$this->eid}] 闭包函数的事件触发过程!");
if ($rule_func !== null && !$rule_func($v)) {
if ($this->log) Console::verbose("[事件分发{$this->eid}] 闭包函数下的 ruleFunc 判断为 false, 拒绝执行此方法。");
@@ -158,6 +158,7 @@ class EventDispatcher
$r[$k]->class = $q_c;
$r[$k]->method = $q_f;
$r[$k]->middleware = $middleware;
$r[$k]->current_event = $v;
if (isset($middleware_obj["before"])) {
if ($this->log) Console::verbose("[事件分发{$this->eid}] Middleware 存在前置事件,执行中 ...");
$rs = $middleware_obj["before"];

View File

@@ -23,7 +23,11 @@ class EventManager
public static $req_mapping = [];
public static function addEvent($event_name, ?AnnotationBase $event_obj) {
Console::debug("Adding event $event_name at ".$event_obj->class.":".$event_obj->method);
if ($event_obj->method instanceof \Closure) {
Console::debug("Adding event $event_name at @Anonymous");
} else {
Console::debug("Adding event $event_name at " . ($event_obj->class) . ":" . ($event_obj->method));
}
self::$events[$event_name][] = $event_obj;
(new AnnotationParser())->sortByLevel(self::$events, $event_name);
}

View File

@@ -70,7 +70,7 @@ class OnOpen implements SwooleEvent
try {
$obb_onebot = ZMConfig::get("global", "onebot") ??
ZMConfig::get("global", "modules")["onebot"] ??
["status" => true, "single_bot_mode" => false, "message_level" => 99999];
["status" => true, "single_bot_mode" => false, "message_level" => 99];
$onebot_status = $obb_onebot["status"];
if ($conn->getName() === 'qq' && $onebot_status === true) {
if ($obb_onebot["single_bot_mode"]) {

View File

@@ -132,7 +132,7 @@ class OnWorkerStart implements SwooleEvent
* @throws Exception
*/
private function loadAnnotations() {
if (Framework::$instant_mode) goto skip;
//加载各个模块的注解类,以及反射
Console::debug("Mapping annotations");
$parser = new AnnotationParser();
@@ -146,20 +146,6 @@ class OnWorkerStart implements SwooleEvent
}
}
//加载自定义的全局函数
Console::debug("Loading context class...");
$context_class = ZMConfig::get("global", "context_class");
if (!is_a($context_class, ContextInterface::class, true)) {
throw new ZMKnownException("E00032", "Context class must implemented from ContextInterface!");
}
//加载插件
$obb_onebot = ZMConfig::get("global", "onebot") ??
ZMConfig::get("global", "modules")["onebot"] ??
["status" => true, "single_bot_mode" => false, "message_level" => 99999];
// 检查是否允许热加载phar模块允许的话将遍历phar内的文件
$plugin_enable_hotload = ZMConfig::get("global", "module_loader")["enable_hotload"] ?? false;
if ($plugin_enable_hotload) {
@@ -176,12 +162,23 @@ class OnWorkerStart implements SwooleEvent
$parser->registerMods();
EventManager::loadEventByParser($parser); //加载事件
skip:
//加载自定义的全局函数
Console::debug("Loading context class...");
$context_class = ZMConfig::get("global", "context_class");
if (!is_a($context_class, ContextInterface::class, true)) {
throw new ZMKnownException("E00032", "Context class must implemented from ContextInterface!");
}
//加载插件
$obb_onebot = ZMConfig::get("global", "onebot") ??
ZMConfig::get("global", "modules")["onebot"] ??
["status" => true, "single_bot_mode" => false, "message_level" => 99999];
if ($obb_onebot["status"]) {
Console::debug("OneBot support enabled, listening OneBot event(3).");
$obj = new OnMessageEvent();
$obj->class = QQBot::class;
$obj->method = 'handleByEvent';
$obj->level = $obb_onebot["message_level"] ?? 99999;
$obj->level = $obb_onebot["message_level"] ?? 99;
$obj->rule = 'connectIsQQ()';
EventManager::addEvent(OnMessageEvent::class, $obj);
if ($obb_onebot["single_bot_mode"]) {

View File

@@ -9,6 +9,7 @@ use Exception;
use Phar;
use Swoole\Server\Port;
use Throwable;
use ZM\Annotation\CQ\CQCommand;
use ZM\Config\ZMConfig;
use ZM\ConnectionManager\ManagerGM;
use ZM\Console\TermColor;
@@ -76,9 +77,11 @@ class Framework
*/
private $setup_events = [];
public function __construct($args = []) {
$tty_width = $this->getTtyWidth();
public static $instant_mode = false;
public function __construct($args = [], $instant_mode = false) {
$tty_width = $this->getTtyWidth();
self::$instant_mode = $instant_mode;
self::$argv = $args;
ZMConfig::setDirectory(DataProvider::getSourceRootDir() . '/config');
ZMConfig::setEnv($args["env"] ?? "");
@@ -124,7 +127,9 @@ class Framework
$this->server_set["log_level"] = SWOOLE_LOG_DEBUG;
$add_port = ZMConfig::get("global", "remote_terminal")["status"] ?? false;
$this->loadServerEvents();
if ($instant_mode) {
$this->loadServerEvents();
}
$this->parseCliArgs(self::$argv, $add_port);
@@ -148,7 +153,7 @@ class Framework
} else {
$out["worker"] = $this->server_set["worker_num"];
}
$out["environment"] = $args["env"] === null ? "default" : $args["env"];
$out["environment"] = ($args["env"] ?? null) === null ? "default" : $args["env"];
$out["log_level"] = Console::getLevel();
$out["version"] = ZM_VERSION . (LOAD_MODE == 0 ? (" (build " . ZM_VERSION_ID . ")") : "");
$out["master_pid"] = posix_getpid();
@@ -182,7 +187,7 @@ class Framework
}
self::printProps($out, $tty_width, $args["log-theme"] === null);
if ($args["preview"]) {
if ($args["preview"] ?? false) {
exit();
}

View File

@@ -0,0 +1,18 @@
<?php
namespace ZM\Module;
/**
* @since 2.6
*/
class InstantModule extends ModuleBase
{
public function onEvent($event_class, $params, callable $callable) {
$class = new $event_class();
foreach ($params as $k => $v) {
if (is_string($k)) $class->$k = $v;
}
$class->method = $callable;
$this->events[] = $class;
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace ZM\Module;
/**
* @since 2.6
*/
abstract class ModuleBase
{
protected $module_name;
protected $events = [];
public function __construct($module_name) {
$this->module_name = $module_name;
}
/**
* @return mixed
*/
public function getModuleName() {
return $this->module_name;
}
/**
* @return array
*/
public function getEvents(): array {
return $this->events;
}
}

59
src/ZM/ZMServer.php Normal file
View File

@@ -0,0 +1,59 @@
<?php
namespace ZM;
use ZM\Command\RunServerCommand;
use ZM\Console\Console;
use ZM\Event\EventManager;
use ZM\Exception\InitException;
use ZM\Module\ModuleBase;
/**
* @since 2.6
*/
class ZMServer
{
protected $app_name;
/** @var ModuleBase[] */
protected $modules = [];
public function __construct($app_name) {
$this->app_name = $app_name;
}
public function addModule($module_class) {
$this->modules[] = $module_class;
}
public function run() {
Console::setLevel(4);
foreach ($this->modules as $module_class) {
foreach ($module_class->getEvents() as $event) {
EventManager::addEvent(get_class($event), $event);
}
}
echo "Running...\n";
if (defined("WORKDING_DIR")) throw new InitException();
_zm_env_check();
define("WORKING_DIR", getcwd());
define("SOURCE_ROOT_DIR", WORKING_DIR);
define("LOAD_MODE", is_dir(SOURCE_ROOT_DIR . "/src/ZM") ? 0 : 1);
define("FRAMEWORK_ROOT_DIR", realpath(__DIR__ . "/../../"));
define("ZM_VERSION_ID", ConsoleApplication::VERSION_ID);
define("ZM_VERSION", ConsoleApplication::VERSION);
$options = array_map(function ($x) {
return $x->getDefault();
}, RunServerCommand::exportDefinition()->getOptions());
(new Framework($options, true))->start();
}
/**
* @return mixed
*/
public function getAppName() {
return $this->app_name;
}
}

View File

@@ -29,6 +29,19 @@ function getClassPath($class_name) {
if (file_exists($dir2)) return $dir2;
else return null;
}
/**
* 检查炸毛框架运行的环境
* @internal
*/
function _zm_env_check() {
if (!extension_loaded("swoole")) die(zm_internal_errcode("E00001") . "Can not find swoole extension.\n");
if (version_compare(SWOOLE_VERSION, "4.5.0") == -1) die(zm_internal_errcode("E00002") . "You must install swoole version >= 4.5.0 !");
if (version_compare(PHP_VERSION, "7.2") == -1) die(zm_internal_errcode("E00003") . "PHP >= 7.2 required.");
if (version_compare(SWOOLE_VERSION, "4.6.7") < 0 && !extension_loaded("pcntl")) {
Console::error(zm_internal_errcode("E00004") . "Swoole 版本必须不低于 4.6.7 或 PHP 安装加载了 pcntl 扩展!");
die();
}
}
/**
* 使用自己定义的万san能分割函数
@@ -331,19 +344,33 @@ function zm_dump($var, ...$moreVars) {
return $var;
}
function zm_info($obj) { Console::info($obj); }
function zm_info($obj) {
Console::info($obj);
}
function zm_warning($obj) { Console::warning($obj); }
function zm_warning($obj) {
Console::warning($obj);
}
function zm_success($obj) { Console::success($obj); }
function zm_success($obj) {
Console::success($obj);
}
function zm_debug($obj) { Console::debug($obj); }
function zm_debug($obj) {
Console::debug($obj);
}
function zm_verbose($obj) { Console::verbose($obj); }
function zm_verbose($obj) {
Console::verbose($obj);
}
function zm_error($obj) { Console::error($obj); }
function zm_error($obj) {
Console::error($obj);
}
function zm_config($name, $key = null) { return ZMConfig::get($name, $key); }
function zm_config($name, $key = null) {
return ZMConfig::get($name, $key);
}
function quick_reply_closure($reply) {
return function () use ($reply) {