# 更新日志（v2 版本）

## v2.8.0（build 473）

> 更新时间：2022.5.7

- 新增 AllBotsProxy、AllGroupsProxy 代理类，支持批量发送机器人动作
- 新增全局函数 `implode_when_necessary()`，用于将可能为数组的参数转换为字符串
- 新增依赖注入、容器支持，目前对 Swoole 事件、机器人事件均支持使用依赖注入
- 新增全局容器方法 `container()`、`resolve()`、`app()`，用于获取容器参数等
- 新增相关容器测试
- 新增链式调用全局方法 `chain()`
- 新增函数执行时间工具全局函数 `stopwatch()`
- 新增 `@CommandArgument` 注解，可直接通过注解添加聊天机器人命令参数
- （内部）新增 `EventManager::$event_map`，用于补充对事件对象遍历的方式
- 新增 `EventMapIterator` 类，用于遍历注解事件对象
- 新增 `MessageUtil::checkArguments()` 方法，用于检查 `@CommandArgument` 注解
- 新增启动命令参数 `--audit-mode`，用于单次审计模式
- 新增部分不可执行脚本的防呆退出功能
- 重构全局方法 `match_pattern()`，优化性能以及解决部分字符串不能匹配的 Bug
- 优化容器支持无名顺序参数的调用
- 优化静态路由，支持 64 以上长度的路由
- 优化 `@RequestMapping` 注解事件的方法返回值处理，支持数组和字符串（数组自动转为 JSON 格式）
- 优化单元测试流程
- 优化上下文对象，在非协程环境下不再会抛出异常或返回 null
- 修改默认 Hello 模块下随机数功能为采用 `@CommandArgument` 注解模式
- 重构帮助生成器，将帮助生成器重构为 `CommandInfoUtil` 类
- 修复 `CQ::encode()` 无法传入 `int` 的强类型解析问题（#113）
- （内部）重构 CQ 类
- 修复 `EventMapIterator` 对 PHP 8.1 的兼容性问题
- 修复 #95 中提到的无输入流时报错的问题
- 修复 `ZMServer` 中的 typo
- 修复 Container 环境继承全局变量的问题
- 修复 `server:stop` 命令下部分情况报错的问题

## v2.7.6（build 460）

> 更新时间：2022.4.3

- 重构 phpunit-swoole，使其可以正常使用
- 新增 `--private-mode` 参数，用于隐藏启动前的 MOTD 及敏感信息
- 修复 Composer extra 配置项 `zm.exclude-annotation-path` 不能正常工作的 Bug
- 优化注解事件加载器，防止 Master 进程中添加的事件在 Worker 中被覆盖的问题
- 修复 `DataProvider::isRelativePath()` 方法判断有误的 Bug
- 新增退出框架时支持以非 0 exit code 退出的功能
- 优化 `ZMUtil::getClassesPsr4()` 方法，排除不含类的文件
- 优化 `module:xxx` 类命令的有关实现代码
- 优化代码到 phpstan-level-4

## v2.7.5（build 455）

> 更新时间：2022.3.27

- 修复前几个小版本无法收发消息的 Bug
- 新增 API Document 自动生成脚本

## v2.7.4（build 454）

> 更新时间：2022.3.27

- 修复部分命令下无法杀掉进程的 Bug
- 新增 `@Cron` 注解
- 修复全局函数 `match_pattern` 无法正常工作的 Bug

## v2.7.3（build 453）

> 更新时间：2022.3.25

- 新增命令帮助生成器
- 重构全局函数，统一函数命名，并补全注释
- 修复 OnSetup 注解无法使用 Attribute 解析的 Bug
- 修复 HelpGenerator 的 Alias 不工作的 Bug
- 新增 property 注解用于 IDE 识别

## v2.7.2（build 449）

> 更新时间：2022.3.21

- 新增 Composer 模块加载和分发模式

## v2.7.1（build 448）

> 更新时间：2022.3.20

- 加快 build 命令的执行速度，取消进度条和提升性能

## v2.7.0（build 447）

> 更新时间：2022.3.20

- 优化分离 WorkerManager 与 ProcessManager 的职责
- 新增 Ctrl+C 一次无法停止框架时多次 Ctrl+C 后可强行杀掉所有进程的功能
- `./zhamao server:stop` 新增参数 `--force`，使用 `SIGKILL` 强行杀掉所有进程
- 新增 AnnotationParser 对 `autoload-dev` 项中的 `psr-4` 默认检索条件
- 新增框架启动状态检测功能，如果已经启动了同样目录的框架，则会报错
- 新增“强制启用轮询模式启动热更新”功能（参数 `--polling-watch`）
- 修复与 PHP 8.1 的兼容性
- 对 DaemonCommand 进行优化，与 ServerCommand 效果相同
- 修复 `autoload`.`psr-4` 不存在时报错的 Bug
- 新增框架停止时 Worker 退出回显状态码
- 新增 inotify 判断模式，如果使用 `--watch` 检测到没有安装 inotify，则自动使用轮询模式
- 新增 PHPStan 和 PHP CS Fixer 并优化全局代码
- 修复 `ctx()` 可能会返回 null 的 Bug
- 修复 Response 类在 PHP 8.1 环境下的报错
- 新增 PHP 8 Attribute 与注解同时支持的特性
- 新增方法宏（Macroable）
- 修复打包模块时命名空间与实际不一致的 Bug
- 修复打包模块后 `files` 的 autoload 项不能被解压和引入的 Bug
- 修复注释空格的样式
- 更改 `extra`.`exclude_annotate` 为 `zm`.`exclude-annotation-path` 项
- 新增配置项 `runtime`.`annotation_reader_ignore`：支持注解解析器忽略注解的自定义
- 新增 `./zhamao server` 下的 `--no-state-check` 参数，关闭“启动框架前的运行状态检查”功能

## v2.6.6（build 434）

> 更新时间：2022.1.8

- 修复框架在 PHP 8.1 下运行时的一些问题
- 新增 Console 日志输出到文件的功能

## v2.6.5（build 433）

> 更新时间：2021.12.28

- 修复 OneBotV11 因 IDE 自动优化导致 API 接口发生变化的问题

## v2.6.4（build 432）

> 更新时间：2021.12.25

- 新增 GoCqhttpAPI 包，用于支持额外的 OneBot Action（API）
- 修复 MySQL 查询器中 `fetchOne()` 方法无法正确返回值的 Bug
- 修复 Swoole Hook 因配置不当无法正确使用的 Bug
- 修复 Issue #50
- 新增 PhpStorm IDE 直接运行框架的脚本

## v2.6.3 (build 430)

> 更新时间：2021.12.8

- 删除调试信息
- 修复 #56 中关于数据库组件的 Bug

## 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

- 新增全局中间件，可在全局配置文件中设置
- 修复部分 Typo
- 新增指令 `server:status`、`server:reload`、`server:stop` 可用在新开终端中查看框架运行状态、重启和退出
- 新增支持 `array` 格式的消息
- 上下文 Context 对象新增 `getOriginMessage()` 用于获取原消息，`getMessage()` 如果在设置了转换后，将默认转换消息为字符串格式保持与旧模块兼容
- OneBot API 新增全局过滤器，可用作 Action 过滤重写等操作
- 配置文件新增 `runtime.reload_delay_time`，用于可配置重载 Worker 等待的时间（毫秒）
- 配置文件新增 `runtime.global_middleware_binding`，用于配置全局中间件
- 配置文件新增 `onebot.message_convert_string`，用于配置是否转换数组格式为字符串，保证与前版本的兼容性（默认为 true）
- MessageUtil 消息工具类新增方法：`strToArray($msg, bool $ignore_space = true, bool $trim_text = false)`
- MessageUtil 消息工具类新增方法：`arrayToStr(array $array)`
- 新增框架启动多次监测功能，无法使用同一个框架项目同时启动两个框架

## v2.5.8 (build 426)

> 更新时间：2021.11.10

- 修复 CQ 码的解析函数 Bug（#52）

## v2.5.7 (build 425)

> 更新时间：2021.11.3

- 调低 OneBot 相关事件在 Swoole 的优先级
- 修复部分情况下闭包事件函数分发时引发的崩溃 bug
- 修复 reload 时会断开 WebSocket 连接且导致进程崩溃的 bug

## v2.5.6 (build 423)

> 更新时间：2021.10.17

- 修复 PHP 7.2 ~ 7.3 下无法使用新版 MySQL 组件的 bug

## v2.5.5 (build 422)

> 更新时间：2021.10.6

- 修复 `script_` 前缀无法被排除加载模块的 bug
- 修复 MySQL 组件的依赖问题

## v2.5.4 (buidl 421)

> 更新时间：2021.9.11

- 删除多余的调试信息

## v2.5.3 (build 420)

> 更新时间：2021.9.11

- 修复 DB 模块在未连接数据库的时候抛出未知异常
- 修复部分情况下打包模块出现的错误
- 修复 OneBot 事件无法响应的 bug
- 新增部分 EventDispatcher 触发的事件 debug 日志

## v2.5.2 (build 418)

> 更新时间：2021.9.10

- 新增 AnnotationException，统一框架内部的抛出异常的类型
- 新增 AnnotationParser 下的 `verifyMiddlewares()` 方法
- 私有化 CQAPI 类下的内部方法
- 将 WebSocket API 响应超时时间从 60 秒缩短为 30 秒
- 修复 DB 类不能使用旧查询器的 bug
- 统一 DB 类下抛出 Exception 的类型为 ZMException 的子类
- EventDispatcher 新增对 `middleware_error_policy` 的处理段
- 配置文件下 `runtime` 新增 `middleware_error_policy` 字段
- 将 LightCache 组件抛出的异常改为 LightCacheException
- ModuleManager 修复改配置的 `load_path` 不生效的 bug
- 修复打包时生成的 Phar Autoload 列表出错的 bug
- 将配置的 override 改为 overwrite
- 新增解包时忽略依赖的选项（`--ignore-depends`）
- 删除众多调试日志，修改部分调试日志为 debug 级别的输出
- 修改 `ZM\MySQL\MySQLManager` 下的 `getConnection()` 为 `getWrapper()`
- MySQLPool 对象新增 `getCount()` 方法
- 新增 MySQLQueryBuilder 类（`doctrine/dbal` 的 wrapper 类）
- 修复 MySQLStatement 封装原 dbal 组件时与连接池不兼容的 bug
- 新增 MySQLStatementWrapper 类
- 完善 MySQLWrapper 类，用作主要的查询对象控制类
- 编写外部插件加载方式（Phar 热加载功能）
- 修复 `ZMUtil::getClassesPsr4()` 方法在遇到空扩展名文件时的报错

## v2.5.1 (build 416)

> 更新时间：2021.7.9

- 修复：脚手架无法正常使用 `init` 命令的 bug。

## v2.5.0（build 415）

> 更新时间：2021.7.9

以下是版本**新增内容**：

- 新增全新的模块系统，可打包模块（src 目录下的子目录用户逻辑代码）为 phar 格式进行分发和版本备份。
- 全局配置文件新增 `module_loader` 项，用于配置外部模块加载的一些设置。
- 全局配置文件新增 `runtime` 配置项，可自定义配置 Swoole 的一些运行时参数，目前可配置一键协程化的 Hook 参数和 Swoole Server 的启动模式。
- 新增 `module:list` 命令，用于查看未打包和已打包的模块列表。
- 新增 `module:pack` 命令，用于打包现有 src 目录下的模块。
- 新增 `module:unpack` 命令，用于解包现有的 phar 模块包。
- 新增打包框架功能，支持将用户的整个项目连同炸毛框架打包为一个 phar 便携运行，使用命令 `build`。
- 新增快捷脚本 `./zhamao`，效果同 `vendor/bin/start` 或 `bin/start`。
- 新增启动参数 `--interact`：又重新支持交互终端了，但还是有点问题，不推荐使用。
- 新增启动参数 `--disable-safe-exit`：如果你的项目在 Ctrl+C 时总是卡住且项目内没有什么使用 LightCache 等缓存在内存的数据可开启防止关不掉框架。
- 新增启动参数 `--preview`：只显示参数，不启动炸毛框架的服务器。
- 新增启动参数 `--force-load-module`：强制打包状态下加载的模块（使用英文逗号分隔多个模块名称）。
- `CoroutinePool` 协程池新增 `getRunningCoroutineCount` 方法，用于查看协程池中的协程数量。
- `DataProvider` 新增 `getFrameworkRootDir()`、`getSourceRootDir()`，分别代表获取框架的根目录和用户源码根目录。（详见下方对目录的定义解释）
- `DataProvider` 中 `getDataFolder` 新增参数 `$second = ''`，如果给定，则自动创建子目录 `$second` 并返回。
- `DataProvider` 新增 `scanDirFiles()` 方法，用于扫描目录，可选择是否递归、是否返回相对路径，也支持扫描 Phar 文件内的路径，非常好用。
- `DataProvider` 新增 `isRelativePath()` 方法，检查路径是否为相对路径（根据第一个字符是否是 '/' 来判断）。
- `ZMUtil` 新增 `getClassesPsr4()` 方法，用于根据 Psr-4 标准来获取目录下的所有类文件。
- 新增全局错误码，可以根据错误码在文档内快速定位和解决问题。
- 中间件和注解事件支持回溯，可以快速查看调用栈（比如中间件可以知道自己是在哪个注解事件中被调用）。
- 使用 `./zhamao build` 来构建框架的 phar 包时增加显示进度条。
- EventDispatcher 新增方法 `getEid()` 和 `getClass()`，分别用于获取事件分发 ID 和注解事件的注解类名称。
- 新增 EventTracer，用于追踪事件的调用栈。
- 中间件支持传参。
- MySQL 数据库查询器改为使用 `doctrine/dbal` 组件，更灵活和稳定。
- 新增对 `SWOOLE_BASE` 模式的支持（支持只启动一个进程的 Server）。

以下是版本**修改内容**：

- 启动文件 `vendor/bin/start` 修改为 shell 脚本，可自动寻找 PHP 环境。
- 全局强制依赖 `league/climate` 组件。
- 修复框架启动时的信息显示换行问题。
- 修复框架使用 Phar 方式启动时导致的报错。
- 修复使用 Ctrl+C 结束时一部分用户卡住的 bug。
- 远程和本地终端去掉 stop 命令，建议直接使用发 SIGTERM 方式结束框架。
- 全局配置文件的 `zm_data` 根目录默认修改为 `WORKING_DIR`。
- 命令 `systemd:generate` 修改为 `generate:systemd`。
- 全局配置文件删除 `server_event_handler_class` 项，此项废弃。
- 修复部分 CQ 码解析过程中没有转义的问题。
- 将 `ZMRobot` 类转移为 `OneBotV11` 类，但提供兼容。
- 修复在守护进程模式下使用 `daemon:reload` 和 `daemon:stop` 命令可能失效的问题。
- 修复 systemd 生成时脚本目录错误的 bug。
- 修复 PipeMessage 等事件未捕获错误导致崩溃的问题。
- `ZM\Http\RouteManager` 移动到 `ZM\Utils\Manager\RouteManager`，但原地址兼容。
- 修复 `Terminal` 类使用的一些问题。
- 对 `pcntl` 扩展改为可选依赖，当 Swoole 版本大于等于 4.6.7 时不需要安装 `pcntl` 扩展。
- 修正启动时框架对缺省配置项的一些默认参数。
- 注解 `@OnSetup` 和 `@SwooleHandler` 可直接使用，无需设置 `server_event_handler_class` 即可。
- 修复框架在一些非正常终端中运行时导致错误的问题。
- 使用 `--debug-mode` 参数时，自动开启热更新。
- 修复脚手架在使用 composer 更新后检查全局配置功能的 bug。
- 修复重启和关闭框架时造成的非正常连接断开。
- 改用独立进程监听文件变化和终端输入。
- 修复有协程中断的任务时停止服务器会报 Swoole 警告的 bug。
- 修复连接被反复断开的问题。

**对目录的定义解释**：

在 2.4.4 版本之前，使用炸毛框架中，只含有两种目录，`getWorkingDir` 和 `getDataFolder`，分别代表获取工作目录和数据目录。在 2.5 版本中，又新增了 `getFrameworkRootDir` 代表获取框架的根目录，`getSourceRootDir` 代表获取源码的根目录。

以 Composer 运行模式举例，如果你使用 `composer create-project zhamao/framework-starter` 命令新建的框架，那么假设我们从 `/app` 目录下运行此命令，然后使用 `cd framework-starter/` 进入项目目录，此时我们使用 `vendor/bin/start server` 命令运行服务器，对应的目录为：

- `WorkingDir`：`/app/framework-starter/`
- `SourceRootDir`：`/app/framework-starter/`
- `FrameworkRootDir`：`/app/framework-starter/vendor/zhamao/framework/`

如果以源码模式（直接克隆 `zhamao-framework.git` 仓库），启动框架，那么使用命令 `bin/start server` 启动框架后，以上三个返回的目录则完全相同。

如果以 2.5 版本新的项目归档模式（build）启动框架，假设我们的项目代码打包为 `server.phar`，在 `/app/` 目录，我们使用命令 `php server.phar server` 启动炸毛框架，那么它对应的目录为：

- `WorkingDir`：`/app/`
- `SourceRootDir`：`phar:///app/server.phar/`
- `FrameworkRootDir`：`phar:///app/server.phar/vendor/zhamao/framework/`

如果最后一种归档方式启动的框架是从源码模式打包而来，那么 `FrameworkRootDir` 就与 `SourceRootDir` 相同。

**版本部分兼容问题变化**：

理论上如果不使用框架内部未开放的接口方法的话，从 2.4 升级到 2.5 是非常自然的，但是也有一部分可能会造成不兼容的问题。

- 生成 systemd 配置文件的命令 `systemd:generate` 变成 `generate:systemd`。
- 全局配置文件中的 `zm_data` 的父目录由 `__DIR__ . "/../"` 改为 `WORKING_DIR`。
- 2.5 版本将 ZMRobot 类中的所有函数方法都移动到了 `OneBotV11` 类中，但原先的 ZMRobot 还可以使用。

## v2.4.4 (build 405)

> 更新时间：2021.3.29

以下是可能不兼容的变更：

- 新增依赖：框架需要 PHP 安装 pcntl 扩展以及开启 `pcntl_signal` 函数（一般情况下编译安装的都会有，宝塔面板请手动解除函数禁用）

## v2.4.3 (build 403)

> 更新时间：2021.3.29

- 新增：swoole 设置配置新增 `max_wait_time` 项，设置等待进程关闭流程最大时间（秒）
- 新增：常量 `MAIN_WORKER`，值等同于 `worker_cache` 项中的 `worker` 参数（WorkerCache 所在的进程）
- 新增：`LightCache` 新增 `getExpireTS()` 方法，用于返回项目过期的时间戳
- 修复：`savePersistence()` 的部分丢失数据的 bug
- 新增：全局方法 `zm_go()`
- 修复：2.4.2 版本下的刷屏报错
- 优化：Ctrl+C 响应机制，启用异步 重启/关闭 措施，防止残留僵尸进程和丢失数据

## v2.4.2 (build 402)

> 更新时间：2021.3.27

- 更改：`WORKING_DIR` 常量的含义
- 修复：未指定 `--remote-terminal` 参数时还依旧开启远程终端的 bug
- 删除：`phar_classloader()` 全局方法
- 更改：持久化存储 LightCache 的逻辑，修复一个愚蠢的容易造成误用的方式
- 新增：LightCache 方法 `addPersistence()` 和 `removePersistence()`
- 新增：框架启动短指令 `./zhamao` 或 `php zhamao`

## v2.4.1 (build 401)

> 更新时间：2021.3.25

- 修复：开启框架时导致的报错

## v2.4.0（build 400）

> 更新时间：2021.3.25

- 新增：检查全局配置文件的命令
- 新增：全局配置文件更新记录
- 依赖变更：**Swoole 最低版本需要 4.5.0**
- 优化：reload 和 stop 命令重载和停止框架的逻辑
- 新增：`$_running_annotation` 变量，可在注解事件中的类使用
- 新增：远程终端（Remote Terminal），弥补原来删掉的本地终端，通过 nc 命令连接即可
- 新增：启动参数 `--worker-num`，`--task-worker-num`，`--remote-terminal`
- 更新：全局配置文件结构
- 新增：Swoole 计时器报错处理
- 新增：全局方法（`zm_dump()`，`zm_error()`，`zm_warning()`，`zm_info()`，`zm_success()`，`zm_verbose()`，`zm_debug()`，`zm_config()`）
- 新增：示例模块的图灵机器人和 at 机器人的处理函数
- 新增：MessageUtil 工具类新增 `isAtMe(), splitCommand(), matchCommand()` 方法
- 新增：ProcessManager 进程管理类新增 `workerAction(), sendActionToWorker(), resumeAllWorkerCoroutines()` 方法
- 优化：CQCommand 的匹配逻辑
- 新增：支持添加自定义远程终端指令的 `@TerminalCommand` 注解
- 新增：图灵机器人 API 封装函数
- 新增：ZMUtil 工具杂项类 `getReloadableFiles()` 函数
- 新增：`vendor/bin/start systemd:generate` 生成 systemd 配置文件的功能
- 新增：`vendor/bin/start check:config` 检查配置文件更新的命令
- 新增：`vendor/bin/start init` 新增 `--force` 参数，覆盖现有文件重新生成
- 新增：MessageUtil 新增方法：`addShortCommand()`，用于快速添加静态文本问答回复的

以下是需要**手动更新**或**更换新写法**的部分：

- 配置文件 `global.php` 中的 `modules` 字段展开，内置模块的配置一律平铺到外面。详见 [更新日志 - 配置文件变更](/update/config)。

以下是默认机器人直接连接产生的变更：

- 2.4.0 新增了默认回复其他人 at 的消息，如果不需要，请将 `Hello.php` 中的 `changeAt()` 和 `turingAPI()` 方法删除。

## v2.3.5 (build 398)

> 更新时间：2021.3.23

- 修复：MySQL 数据库查询导致的一系列问题
- 修复：内存泄露问题

> 2.3.2-2.3.4 版本由于操作失误导致代码不完整，请直接使用 2.3.5 即可。

## v2.3.1

> 更新时间：2021.3.18

- 规范代码，修复一个小报错的 bug

## v2.3.0

> 更新时间：2021.3.16

- 新增：MessageUtil 消息处理工具类
- 新增：TaskManager，封装了 TaskWorker 进程的应用
- 新增：CQObject，使用 `CQ::getCQ()` 可获取对象形式的 CQ 码解析结果
- 新增：`@OnTask` 注解，绑定任务函数
- 新增：RouteManager 路由管理类，可快速添加路由
- 修复：`ZM_DATA` 和 `DataProvider::getDataFolder()` 返回 false 的问题
- 优化：关闭显示停止框架后多余的输出信息

注：本次升级建议升级后合并全局配置文件，有一些新加的内容。

## v2.2.11

> 更新时间：2021.3.13

- 新增：内部 ID 版本号（ZM_VERSION_ID）
- 优化：启动时 log 的等级
- 移除：终端输入命令
- 修复：纯 HTTP 服务器的启动 bug
- 新增：`zm_timer` 的报错处理，防止服务器直接崩掉

## v2.2.10

> 更新时间：2021.3.8

- 新增：用户态 php 编译脚本 `build-runtime.sh`
- 移除：无用的调试信息
- 新增：`--show-php-ver` 启动参数

## v2.2.9

> 更新时间：2021.3.6

- 更新：`reply()` 方法传入数组则变为快速相应的 API 操作
- 修复：在 Worker 进程下调用 `ZMUtil::reload()` 会导致一些奇怪的 bug
- 修复：`reply()` 时会 at 私聊成员的 bug（由 go-cqhttp 导致）

## v2.2.8

> 更新时间：2021.3.2

- 更新：MOTD 显示的方式，更加直观和炫酷

## v2.2.7

> 更新时间：2021.2.27

- 修复：2.2.6 版本下 `reply()` 方法在群里调用会 at 成员的 bug
- 修复：空 `access_token` 的情况下会无法连入的 bug
- 修复：使用 Closure 闭包函数自行编写逻辑的判断返回 false 无法阻断连接的 bug

## v2.2.6

> 更新时间：2021.2.26

- 新增：`uuidgen()` 全局函数，快速生成 uuid
- 修复：MySQL `rawQuery()` 在参数为非数组时会报 Warning 的 bug
- 新增：示例模块的 API 示例：一言查询
- 优化：删减部分无用代码
- 更改：`ctx()->reply()` 方法改为调用隐藏方法：`.handle_quick_operation`
- 修复：`ctx()->finalReply()` 一直以来的 bug（未阻断事件）
- 新增：`access_token` 配置项支持闭包函数自行设计判断方式和逻辑
- 新增：全局函数 `working_dir()`

## v2.2.5

> 更新时间：2021.2.20

- 新增：`saveToJson()` 和 `loadFromJson()` 方法（DataProvider 类）
- 修复：`@OnSave` 注解事件无法工作的 bug
- 调整：自定义计时器创建时的性能调优
- 新增：WorkerCache 方法：`hasKey()`
- 新增：SpinLock 方法：`transaction()`（直接在事务中上锁）
- 新增：CQ 方法：`getAllCQ()`，`_custom()`（获取消息中的所有 CQ 码）
- 修复：CQ 类中的部分 bug

## v2.2.4

> 更新时间：2021.2.7

- 修复：终端交互导致的 ssh 断掉后 CPU 占用过高的问题
- 修复：WorkerCache 在缺少配置文件下工作异常的问题
- 新增：全局函数：`zm_atomic()`

## v2.2.3

> 更新时间：2021.1.30

- 修复：waitMessage() 在 v2.2.2 版本中不可用的 bug
- 修复：access_token 无效的问题

## v2.2.2

> 更新时间：2021.1.29

- 修复：模块文件错误时避免循环报错
- 优化：代码结构
- 修复：在不同进程时调用机器人 API 无法返回且报错的 bug
- **修复：机器人无法连接的问题（2.1.6 ~ 2.2.1 受影响）**

## v2.2.1

> 更新时间：2021.1.29

- 修复：配置文件兼容性问题

## v2.2.0

> 更新时间：2021.1.29

- 新增：`@OnPipeMessageEvent` 注解
- 新增：进程管理器
- 新增：`--daemon` 守护进程化后查看状态以及一系列操作的命令行
- 新增：WorkerCache
- 修复：路由问题
- 修复：`http_header` 配置项不生效的 bug
- 优化：框架内部所有异常全部基于 `ZMException`
- 优化：SingletonTrait 支持扩展

## v2.1.6

> 更新时间：2021.1.18

- 优化：代码结构
- 增加：更多提示语
- 修复：处理空格消息时的报错
- 修复：上下文的bug

## v2.1.5

> 更新时间：2021.1.13

- 优化：终端对 PHP Warning 和 PHP Notice 的报错信息显示，统一格式
- 新增：`ctx()->getNumArg()` 上下文中快速获取数字类型的参数的方法
- 优化：删除不必要的调试信息
- 优化：路由组件全面替换为 `symfony/routing`，兼容性和稳定性 up！

## v2.1.4

> 更新时间：2021.1.3

- 修复：启动时会提示丢失类的 bug
- 优化：HTTP 响应类如果被使用了则一律返回 false
- 优化：PHP Warning 等报错统一样式

## v2.1.3

> 更新时间：2021.1.2

- 修复：注解解析器在某种特殊情况下导致的 bug

## v2.1.2

> 更新时间：2021.1.2

- 修复：引入包模式启动时会导致的满屏报错

## v2.1.1

> 更新时间：2021.1.2

- 修复：自定义加载注解选定 composer.json 文件错误的 bug

## v2.1.0

> 更新时间：2021.1.2

- 新增：`@OnOpenEvent`，`@OnCloseEvent`，`@OnMessageEvent`，`@OnRequestEvent`
- 优化事件分发器，修复一些事件分发过程中的 bug
- 修复 `@CQBefore` 事件的 bug

## v2.0.3

> 更新时间：2020.12.31

- 修复：CQBefore 注解事件在 level 低于 200 时无法调用的 bug
- 修复：CQMetaEvent 注解事件调用时报错的 bug

## v2.0.2

> 更新时间：2020.12.31

- 更新：将 CQ 码调用类更新到与最新 OneBot 标准相兼容的状态

## v2.0.1

> 更新时间：2020.12.23

- 修复：开屏报错文件夹不存在

## v2.0

> 更新时间：2020.12.23

已发布正式版。
