Skip to content

Latest commit

 

History

History
132 lines (90 loc) · 4.98 KB

File metadata and controls

132 lines (90 loc) · 4.98 KB

Velocity Forget Me 开发文档

中文 | English

本文档记录插件的实现结构和处理流程,面向需要维护或扩展插件的开发者。

目录结构

velocity_forget_me/
├── __init__.py              # MCDR 入口、配置加载、on_info 监听
├── processor.py             # 事件顺序、session 和记录删除
└── utils/
    ├── config.py            # Serializable 配置类和字段校验
    ├── connection.py        # Velocity 连接日志解析
    ├── paths.py             # MCDR working_directory 路径解析
    └── uuid.py              # PlayerDB UUID 查询

事件入口

插件使用 MCDR 的 on_info 处理 mcdr.general_info

  1. 只接受 info.is_from_server 为真的信息。
  2. info.content 交给 ConnectionEventParser
  3. 正则必须提供 playerserveraction 三个命名捕获组。
  4. 解析成功后为事件分配顺序号,并交给 ConnectionProcessor.process()

process() 使用 MCDR 的 @new_thread() 装饰器运行在 daemon thread 中。网络查询和文件操作不会阻塞 MCDR 的信息处理线程。

Session 模型

JoinSession 表示一个玩家在一个后端服务器上的连接 session。session key 为:

(player_name.casefold(), server_name)

因此:

(Player, lobby)
(Player, survival)

是两个独立 session。一个服务器的连接或断开不会覆盖、结束或修改另一个服务器的 session。

同一个玩家再次连接同一个服务器时,会递增该 (player, server) 对应的 generation,并替换当前 session。generation 用于确认异步处理仍然针对当前 session。

Session 主要保存:

  • 玩家名;
  • 服务器名;
  • generation;
  • 连接时间;
  • UUID;
  • 断开时间;
  • 是否已经执行过删除。

事件顺序

on_info() 在提交后台任务前调用 reserve() 分配递增的顺序号。每个处理线程会等待自己的顺序号成为当前序号,保证日志事件按照 MCDR 接收到的顺序处理。

连接事件只创建或替换对应 session,不立即查询 UUID,也不删除记录。

断开事件按 (player, disconnect_server) 查找 session。如果不存在对应 session,事件直接忽略。

删除条件

删除流程必须同时满足:

  1. 存在同一玩家、同一服务器的 session;
  2. 断开时间不早于连接时间;
  3. 连接到断开的时间不超过 disconnect_window_seconds
  4. session 仍然是该 (player, server) 对的当前 generation;
  5. UUID 已从 session、缓存或 PlayerDB 获得;
  6. RememberMe 文件内容同时等于连接服务器和断开服务器。

文件路径为:

<record_directory>/<uuid>.txt

只有完成全部检查后才调用 Path.unlink()

删除失败不会伪造成功日志。文件不存在使用 DEBUG 日志,读取或删除失败使用 ERROR 日志,服务器名不匹配使用 WARNING 日志。

Session 生命周期

当前没有独立的后台定时器清理未收到断开事件的 session:

  • 收到对应断开事件且超过时间窗口时,session 被删除,但 RememberMe 文件保留;
  • 收到对应断开事件且符合条件时,完成检查后删除 session;
  • UUID 查询失败时,当前 session 被删除,记录保留;
  • 插件卸载或重载时,close() 清理全部内存 session;
  • 如果始终没有收到断开事件,session 会一直保留到上述清理时机。

配置架构

PluginConfig 继承 MCDR 的 Serializable。入口通过以下方式加载:

server.load_config_simple(
    target_class=PluginConfig,
    failure_policy='raise',
)

字段默认值由 Serializable 类属性提供。validate_attribute() 在反序列化字段时校验路径、数值、正则表达式和 UUID API URL。记录目录在配置加载后,根据 MCDR 的 working_directory 解析为绝对路径;解析后的路径单独传给 processor,不修改配置对象中的原始字符串。

扩展注意事项

  • 修改连接日志格式时,应优先修改配置中的 connection_regex,并保留三个命名捕获组。
  • 修改 session 相关逻辑时,必须同时检查 _sessions_generations_is_current_session()
  • 不要把 PlayerDB 查询移回 on_info();它必须继续在 @new_thread() 处理器中执行。
  • 删除记录前必须保留服务器名检查,避免一个服务器的断开事件删除另一个服务器的 RememberMe 记录。
  • 插件只处理文件形式的 RememberMe,不应假设 VelocityRememberServer 或 LuckPerms 的存储结构。

本地检查

编译所有源文件:

python -m py_compile velocity_forget_me/__init__.py velocity_forget_me/processor.py velocity_forget_me/utils/__init__.py velocity_forget_me/utils/config.py velocity_forget_me/utils/connection.py velocity_forget_me/utils/paths.py velocity_forget_me/utils/uuid.py

使用 MCDR 原生命令打包:

python -m mcdreforged pack