换位置
This commit is contained in:
@@ -10,11 +10,11 @@
|
||||
- Linux/Windows 都提供命令行入口,支持 `list`、`create`、`start`、`stop`、`connect`、`compile`、`regen`、`interactive` 等命令。
|
||||
- 工具面向一个 Erlang/rebar3 游戏服务器工程,约定服务器工程根目录包含 `run/`、`config/`、`rebar3` 等内容。
|
||||
- 每个服务器实例位于 `<服务器项目根>/run/<prefix>_<type>_s<id>/`,实例差异配置写入 `config/kv.config`,启动前根据模板生成 `config/sys.config`。
|
||||
- 项目级工具配置位于 `<服务器项目根>/.server_manager/config/`,首次打开项目时从软件自带模板目录同步 `default.kv` 和 `sys_*.config.example`。
|
||||
- 项目级工具配置位于 `<服务器项目根>/.server_manager/config/`,首次打开项目时从软件自带模板目录同步 `default.config` 和 `sys_*.config.example`。
|
||||
- 应用级配置位于 `%LOCALAPPDATA%/ServerManager` 或 `~/.config/ServerManager`,用于保存最近项目列表和应用日志。
|
||||
- 打包使用 PyInstaller 目录模式生成 `src/dist/main/main.exe`,Inno Setup 生成 `output/ServerManager_Setup.exe`。
|
||||
- 打包使用 PyInstaller 目录模式生成 `src/dist/ServerManager/ServerManager.exe`,Inno Setup 生成 `output/ServerManager_Setup.exe`。
|
||||
- 实际 GUI/CLI 主入口是 `src/server_manager_gui.py`;根目录 `main.py` 是一个 Tkinter 自动更新集成示例/遗留入口。
|
||||
- 更新机制支持 `version.json` 清单、全量安装包更新,以及基于 `bsdiff4` 的 `main.exe` 增量补丁;替换 exe 时由独立 `mini_updater.exe` 等待主进程退出后完成替换并重启。
|
||||
- 更新机制支持 `version.json` 清单、全量安装包更新,以及基于 `bsdiff4` 的 `ServerManager.exe` 增量补丁;替换 exe 时由独立 `mini_updater.exe` 等待主进程退出后完成替换并重启。
|
||||
- 日志查看支持单文件加载、玩家协议日志、日期归档日志、ripgrep 全局搜索、正文高亮、匹配行过滤和 less 风格快捷键。
|
||||
|
||||
## 核心文件树
|
||||
@@ -37,7 +37,7 @@ server_manager/
|
||||
├── rg.exe # 可选,ripgrep Windows 可执行文件
|
||||
├── output/
|
||||
│ ├── config/
|
||||
│ │ ├── default.kv
|
||||
│ │ ├── default.config
|
||||
│ │ ├── sys_game.config.example
|
||||
│ │ ├── sys_login.config.example
|
||||
│ │ ├── sys_center.config.example
|
||||
@@ -83,8 +83,8 @@ server_manager/
|
||||
2. Windows 下提供 PyQt6 GUI;Windows/Linux 下提供 CLI。
|
||||
3. GUI 无参数启动;命令行带任意参数时进入 CLI,行为与 src/server_manager_cli.py 一致。
|
||||
4. 工具管理一个外部 Erlang 游戏服务器项目,项目根目录通常含 run、config、rebar3、apps 等。
|
||||
5. 首次打开服务器项目时,将软件自带模板 output/config 下的 default.kv 与 sys_*.config.example 同步到 <项目根>/.server_manager/config/。
|
||||
6. 所有项目级配置保存在 <项目根>/.server_manager/config/tool.config;应用级配置和日志保存在 %LOCALAPPDATA%/ServerManager 或 ~/.config/ServerManager。
|
||||
5. 首次打开服务器项目时,将软件自带模板 output/config 下的 default.config 与 sys_*.config.example 同步到 <项目根>/.server_manager/config/。
|
||||
6. 所有项目级配置保存在 <项目根>/.server_manager/config/user.config;应用级配置和日志保存在 %LOCALAPPDATA%/ServerManager 或 ~/.config/ServerManager。
|
||||
7. 支持服务器创建、启动、快速启动、停止、remsh 连接、编译、配置编辑、sys.config 重新生成、本地/远程服务器列表、节点状态批量检查、日志查看、日志搜索、自动更新、打包发版。
|
||||
|
||||
二、技术栈与依赖
|
||||
@@ -109,12 +109,12 @@ server_manager/
|
||||
- version.json:版本清单,当前版本为 1.0.46,字段包含 version、update_url、release_notes、full_installer_url、delta_updates。
|
||||
- main.py:Tkinter 示例/遗留入口,LOCAL_VERSION = "1.0.46",演示 updater 自动更新集成;真实桌面工具入口仍以 src/server_manager_gui.py 为准。
|
||||
- updater.py:保留一个 Tkinter/独立入口可用的无感更新模块,兼容 delta 与 delta_updates。
|
||||
- mini_updater.py:独立进程外更新器,等待主进程 PID 退出后替换 main.exe 并重启。
|
||||
- mini_updater.py:独立进程外更新器,等待主进程 PID 退出后替换 ServerManager.exe 并重启。
|
||||
- release.py:发版脚本,负责更新 build_installer.iss、main.py、version.json,生成 delta_updates,打包后可生成 bsdiff4 patch 并填 new_exe_sha256。
|
||||
- release.bat:一键正式发版脚本,顺序为 PyInstaller -> release.py 版本预处理 -> Inno Setup -> release.py --post-build。
|
||||
- pack_all.bat:正式打包但不改版本号,生成 output/ServerManager_Setup.exe,并复制 version.json 到 output/。
|
||||
- pack_local_test.py 与 pack_local_test.bat:生成 output_local/ServerManager_Setup_LOCAL.exe,不改版本号、不覆盖 output/。
|
||||
- build_installer.iss:Inno Setup 脚本,正式版 AppName=ServerManager,测试版 AppName=ServerManager (本地测试),安装 src/dist/main/*、src/dist/mini_updater.exe、version.json、output/config/*。
|
||||
- build_installer.iss:Inno Setup 脚本,正式版 AppName=ServerManager,测试版 AppName=ServerManager (本地测试),安装 src/dist/ServerManager/*、src/dist/mini_updater.exe、version.json、output/config/*。
|
||||
- .gitignore:忽略 output_local/,可注明 release_backup/ 可选忽略。
|
||||
- rg.exe:可选,不需要生成二进制;文档说明放置在根目录即可被打包复制。
|
||||
|
||||
@@ -135,7 +135,7 @@ src 目录:
|
||||
- icon/convert_icon.py、icon/icon.png、icon/icon.ico:图标资源和转换脚本。
|
||||
|
||||
output/config 目录:
|
||||
- default.kv:默认配置和配置项定义。
|
||||
- default.config:默认配置和配置项定义。
|
||||
- sys_game.config.example、sys_login.config.example、sys_center.config.example、sys_cross.config.example、sys_client.config.example:Erlang sys.config 模板,使用 ${key} 占位符。
|
||||
|
||||
四、version.json 内容
|
||||
@@ -159,23 +159,23 @@ output/config 目录:
|
||||
|
||||
1. 项目级配置目录固定为 <项目根>/.server_manager/config。
|
||||
2. 软件自带模板目录:
|
||||
- 打包后:main.exe 同级的 config/。
|
||||
- 打包后:ServerManager.exe 同级的 config/。
|
||||
- 源码运行:仓库根目录 output/config/。
|
||||
3. 受管模板文件:
|
||||
- default.kv
|
||||
- default.config
|
||||
- sys_center.config.example
|
||||
- sys_client.config.example
|
||||
- sys_cross.config.example
|
||||
- sys_game.config.example
|
||||
- sys_login.config.example
|
||||
4. 打开项目时必须确保 .server_manager/config 存在并同步上述模板;保留用户自己的 tool.config。
|
||||
4. 打开项目时必须确保 .server_manager/config 存在并同步上述模板;保留用户自己的 user.config。
|
||||
5. 配置合并优先级从低到高:
|
||||
- .server_manager/config/default.kv
|
||||
- .server_manager/config/tool.config
|
||||
- run_dir/config/tool.config 或 run_dir/tool.config
|
||||
- .server_manager/config/default.config
|
||||
- .server_manager/config/user.config
|
||||
- run_dir/config/user.config 或 run_dir/user.config
|
||||
- run_dir/<server_dir>/config/kv.config
|
||||
6. 合并配置后强制用当前机器 IP 覆盖 ip 和 game_host。
|
||||
7. tool.config 是 key=value 文件,至少写入:
|
||||
7. user.config 是 key=value 文件,至少写入:
|
||||
- server_root、run_dir
|
||||
- r25_path
|
||||
- db_host、db_port、db_user、db_pass
|
||||
@@ -184,12 +184,12 @@ output/config 目录:
|
||||
8. 应用级配置:
|
||||
- Windows: %LOCALAPPDATA%/ServerManager/app_config.json
|
||||
- Linux/macOS: ~/.config/ServerManager/app_config.json
|
||||
- 保存最近 10 个有效项目,判断有效项目时需存在 .server_manager/config/default.kv 或旧式 config/default.kv。
|
||||
- 保存最近 10 个有效项目,判断有效项目时需存在 .server_manager/config/default.config 或 config/project.config。
|
||||
- 应用日志写到同目录 logs/,日志文件名 server_manager_YYYYMMDD.log 或 server_manager_cli_YYYYMMDD.log,保留最近 7 天。
|
||||
|
||||
六、default.kv 要求
|
||||
六、default.config 要求
|
||||
|
||||
default.kv 必须含以下默认值和配置定义:
|
||||
default.config 必须含以下默认值和配置定义:
|
||||
|
||||
- prefix=ddxq2
|
||||
- server_id=1
|
||||
@@ -259,7 +259,7 @@ default.kv 必须含以下默认值和配置定义:
|
||||
- client_server -> sys_client.config.example
|
||||
- center_server -> sys_center.config.example
|
||||
- cross_server -> sys_cross.config.example
|
||||
4. 生成 sys.config 前需要将 log_dir 和 role_log 归一化为 run/<server_dir>/<tail>。如果 default.kv 中是 run/server/log,则实际应变为 run/<server_dir>/log。
|
||||
4. 生成 sys.config 前需要将 log_dir 和 role_log 归一化为 run/<server_dir>/<tail>。如果 default.config 中是 run/server/log,则实际应变为 run/<server_dir>/log。
|
||||
5. 若模板中仍有未替换占位符,要输出警告但不要崩溃。
|
||||
|
||||
八、服务器创建逻辑
|
||||
@@ -350,7 +350,7 @@ default.kv 必须含以下默认值和配置定义:
|
||||
|
||||
CLI 初始化时自动检测 server_root:
|
||||
1. 命令行 --root 优先。
|
||||
2. 读取 tool.config 的 server_root/run_dir 次之。
|
||||
2. 读取 user.config 的 server_root/run_dir 次之。
|
||||
3. 当前工作目录、脚本目录、上级目录中查找 apps 与 config。
|
||||
4. 加载配置后执行 run_startup_migrations。
|
||||
|
||||
@@ -412,7 +412,7 @@ GUI 图标:
|
||||
- center:auto_reload、open_time、login_node
|
||||
- cross:auto_reload、open_time、center_node
|
||||
- client:连接服务器ID、连接服务器端口、登录服地址、登录服HTTP端口、auto_reload、login_node
|
||||
4. ID 范围从 default.kv 的 <type>_id_min/max/default 读取,越界时自动修正并提示。
|
||||
4. ID 范围从 default.config 的 <type>_id_min/max/default 读取,越界时自动修正并提示。
|
||||
5. 服务器 ID 改变时自动更新服务器名与默认端口。
|
||||
6. 数据库和节点支持“使用默认配置”复选框,默认勾选并禁用手工输入。
|
||||
7. 点击创建前展示确认信息,再调用 server_creator.create_server。
|
||||
@@ -426,7 +426,7 @@ GUI 图标:
|
||||
4. 远程操作:从登录服加载、刷新状态、搜索过滤、双击或按钮 remsh 连接。
|
||||
5. 远程列表通过登录服节点 rpc:call 获取 server_temp_info/server_info_lib 数据;输出需解析 server_id、server_name、server_node。
|
||||
6. 状态刷新使用批量 check_nodes_status,并写入 NodeStatusCache。
|
||||
7. 编辑配置打开 KvConfigEditDialog,读取 kv.config,允许添加/删除 default.kv 中声明的可编辑配置项;保存后重新生成 sys.config。
|
||||
7. 编辑配置打开 KvConfigEditDialog,读取 kv.config,允许添加/删除 default.config 中声明的可编辑配置项;保存后重新生成 sys.config。
|
||||
|
||||
日志查看页:
|
||||
1. 顶级“日志查看”内有两个子页签:
|
||||
@@ -468,12 +468,12 @@ GUI 图标:
|
||||
- Erlang 与节点配置:Erlang 路径、Erlang 版本、登录服节点、中心服节点、Cookie。
|
||||
2. 提供“检查版本”按钮,比对系统 erl 和配置路径 erl 的 OTP 版本。
|
||||
3. 登录服节点、中心服节点提供“测试连接”,使用 net_adm:ping。
|
||||
4. “填充默认值”从 default.kv 填入表单。
|
||||
5. “保存配置”写入 tool.config;若 Erlang 路径变化,询问是否删除 server_root/_build 并执行 rebar3 as game_server_dev compile。
|
||||
4. “填充默认值”从 default.config 填入表单。
|
||||
5. “保存配置”写入 user.config;若 Erlang 路径变化,询问是否删除 server_root/_build 并执行 rebar3 as game_server_dev compile。
|
||||
|
||||
欢迎页:
|
||||
1. 无项目时显示欢迎页,提供打开项目、最近项目、定位项目、帮助入口。
|
||||
2. 最近项目来自应用级 app_config.json,只显示仍存在且含 default.kv 的项目。
|
||||
2. 最近项目来自应用级 app_config.json,只显示仍存在且含 default.config 的项目。
|
||||
|
||||
更新机制:
|
||||
1. src/updater.py 提供:
|
||||
@@ -486,11 +486,11 @@ GUI 图标:
|
||||
- clean_up_old_version
|
||||
- apply_delta_patch
|
||||
- run_installer_and_exit
|
||||
2. 打包后 version.json 优先从 main.exe 同目录读取,其次从 _MEIPASS。
|
||||
2. 打包后 version.json 优先从 ServerManager.exe 同目录读取,其次从 _MEIPASS。
|
||||
3. GUI 启动 1.5 秒后后台检查 update_url;远端 version 与本地不同则询问是否更新。
|
||||
4. 当前版本有 delta_updates 且 patch_url、new_exe_sha256 完整时优先增量,否则下载 full_installer_url 或 download_url。
|
||||
5. 下载时显示 QProgressDialog;可取消。
|
||||
6. 增量使用 bsdiff4.patch(当前 main.exe, patch) 生成临时新 exe,校验 sha256,通过 mini_updater.exe 替换并重启。
|
||||
6. 增量使用 bsdiff4.patch(当前 ServerManager.exe, patch) 生成临时新 exe,校验 sha256,通过 mini_updater.exe 替换并重启。
|
||||
7. 全量更新下载安装包后用 /VERYSILENT /SUPPRESSMSGBOXES /FORCECLOSEAPPLICATIONS 静默安装并退出。
|
||||
8. mini_updater.py 只依赖标准库,参数:
|
||||
- --pid
|
||||
@@ -508,30 +508,30 @@ GUI 图标:
|
||||
- add-data: ../version.json、config.json、server_commands.py、server_creator.py、icon。
|
||||
- hidden-import: PyQt6.QtWidgets/Core/Gui、pymysql、server_commands、server_creator、server_manager_cli、updater、app_config、bsdiff4、requests。
|
||||
- collect-all PyQt6 与 bsdiff4。
|
||||
- 若根目录有 rg.exe,复制到 dist/main/rg.exe。
|
||||
- 复制 ../output/config 到 dist/main/config。
|
||||
- 若根目录有 rg.exe,复制到 dist/ServerManager/rg.exe。
|
||||
- 复制 ../output/config 到 dist/ServerManager/config。
|
||||
- 再用 PyInstaller onefile windowed 打包 ../mini_updater.py 到 dist/mini_updater.exe。
|
||||
2. src/build_linux.sh 与 build.bat 等价,但使用 python3、Linux add-data 冒号分隔,输出 dist/main/main。
|
||||
2. src/build_linux.sh 与 build.bat 等价,但使用 python3、Linux add-data 冒号分隔,输出 dist/ServerManager/ServerManager。
|
||||
3. src/build_portable.bat 提供单文件便携版尝试,失败回退 onedir。
|
||||
4. build_installer.iss:
|
||||
- 正式输出 output/ServerManager_Setup.exe。
|
||||
- 本地测试 /DLOCAL_TEST=1 输出 output_local/ServerManager_Setup_LOCAL.exe,独立 AppId。
|
||||
- 安装 src/dist/main/* 到 {app},安装 mini_updater.exe、version.json、output/config/*。
|
||||
- 安装 src/dist/ServerManager/* 到 {app},安装 mini_updater.exe、version.json、output/config/*。
|
||||
- 创建开始菜单/可选桌面快捷方式。
|
||||
- 安装完成后运行 main.exe。
|
||||
- 安装完成后运行 ServerManager.exe。
|
||||
5. release.py:
|
||||
- get_current_version 以 output/version.json 为准读取旧版本。
|
||||
- set_version_pre(new_version, notes):更新 build_installer.iss 的 MyAppVersion、main.py 的 LOCAL_VERSION、version.json 的 version/release_notes/delta_updates,并同步到 src/dist/main/version.json 和 _internal/version.json。
|
||||
- set_version_post(old_exe):复制 version.json 到 output;若提供旧版 main.exe 且安装 bsdiff4,生成 output/patches/v<old>_to_v<new>.patch 并填 new_exe_sha256。
|
||||
- set_version_pre(new_version, notes):更新 build_installer.iss 的 MyAppVersion、main.py 的 LOCAL_VERSION、version.json 的 version/release_notes/delta_updates,并同步到 src/dist/ServerManager/version.json 和 _internal/version.json。
|
||||
- set_version_post(old_exe):复制 version.json 到 output;若提供旧版 ServerManager.exe 且安装 bsdiff4,生成 output/patches/v<old>_to_v<new>.patch 并填 new_exe_sha256。
|
||||
|
||||
入口脚本:
|
||||
1. src/run.bat:
|
||||
- 自动计算 SERVER_ROOT 为脚本目录向上两级。
|
||||
- 优先使用 SERVER_MANAGER_MAIN、同目录 main.exe、dist/main/main.exe。
|
||||
- 优先使用 SERVER_MANAGER_MAIN、同目录 ServerManager.exe、dist/ServerManager/ServerManager.exe。
|
||||
- 无参数进入 interactive。
|
||||
- gui 启动 GUI。
|
||||
- 其他参数转发 CLI,并附加 --root SERVER_ROOT。
|
||||
2. src/run.sh 同理,优先 SERVER_MANAGER_MAIN、同目录 main、dist/main/main。
|
||||
2. src/run.sh 同理,优先 SERVER_MANAGER_MAIN、同目录 ServerManager、dist/ServerManager/ServerManager。
|
||||
|
||||
十二、核心代码复刻细则
|
||||
|
||||
@@ -588,7 +588,7 @@ GUI 图标:
|
||||
- IS_WINDOWS = platform.system() == "Windows"
|
||||
- IS_LINUX = platform.system() == "Linux"
|
||||
- REBAR3_CMD = "rebar3.cmd" if IS_WINDOWS else "./rebar3"
|
||||
- MANAGED_CONFIG_TEMPLATE_FILES = ("default.kv", "sys_center.config.example", "sys_client.config.example", "sys_cross.config.example", "sys_game.config.example", "sys_login.config.example")
|
||||
- MANAGED_CONFIG_TEMPLATE_FILES = ("default.config", "sys_center.config.example", "sys_client.config.example", "sys_cross.config.example", "sys_game.config.example", "sys_login.config.example")
|
||||
|
||||
必须提供这些函数:
|
||||
|
||||
@@ -606,25 +606,26 @@ GUI 图标:
|
||||
|
||||
- get_server_manager_config_dir 返回 Path(server_root).resolve() / ".server_manager" / "config"。
|
||||
- get_bundled_tool_config_template_dir 打包后返回 Path(sys.executable).parent / "config",源码运行返回 Path(__file__).parent.parent / "output" / "config"。
|
||||
- sync_server_manager_config_templates 必须检查模板目录存在、default.kv 存在、每个 MANAGED_CONFIG_TEMPLATE_FILES 都存在;逐个 copy2 到项目 .server_manager/config。
|
||||
- sync_server_manager_config_templates 必须检查模板目录存在、default.config 存在、每个 MANAGED_CONFIG_TEMPLATE_FILES 都存在;逐个 copy2 到项目 .server_manager/config。
|
||||
- read_config_file 读取 key=value,忽略空行、# 注释、% 注释;去除空白和首尾双引号。
|
||||
- read_merged_config 合并顺序为 default.kv -> tool.config -> run_dir tool.config -> kv.config,最后强制 merged["ip"] 和 merged["game_host"] 为 get_local_ip()。
|
||||
- read_merged_config 合并顺序为 default.config -> config/project.config -> user.config -> run_dir user.config -> kv.config,最后强制 merged["ip"] 和 merged["game_host"] 为 get_local_ip()。
|
||||
|
||||
read_merged_config 伪代码:
|
||||
|
||||
def read_merged_config(server_root, server_dir=None, run_dir=None):
|
||||
cfg_dir = get_server_manager_config_dir(server_root)
|
||||
merged = {}
|
||||
if (cfg_dir / "default.kv").exists():
|
||||
merged.update(read_config_file(str(cfg_dir / "default.kv")))
|
||||
elif (cfg_dir / "default.config").exists():
|
||||
if (cfg_dir / "default.config").exists():
|
||||
merged.update(read_config_file(str(cfg_dir / "default.config")))
|
||||
project_cfg = Path(server_root) / "config" / "project.config"
|
||||
if project_cfg.exists():
|
||||
merged.update(read_config_file(str(project_cfg)))
|
||||
|
||||
if (cfg_dir / "tool.config").exists():
|
||||
merged.update(read_config_file(str(cfg_dir / "tool.config")))
|
||||
if (cfg_dir / "user.config").exists():
|
||||
merged.update(read_config_file(str(cfg_dir / "user.config")))
|
||||
|
||||
if run_dir:
|
||||
for p in (Path(run_dir) / "config" / "tool.config", Path(run_dir) / "tool.config"):
|
||||
for p in (Path(run_dir) / "config" / "user.config", Path(run_dir) / "user.config"):
|
||||
if p.exists():
|
||||
merged.update(read_config_file(str(p)))
|
||||
break
|
||||
@@ -926,7 +927,7 @@ GUI 图标:
|
||||
- detected_root = _detect_server_root()
|
||||
- configured_root = _read_configured_server_root(detected_root)
|
||||
- server_root 优先级:参数 server_root > configured_root > detected_root
|
||||
- run_dir 优先级:tool.config 的 run_dir > server_root/run
|
||||
- run_dir 优先级:user.config 的 run_dir > server_root/run
|
||||
- config_path = get_server_manager_config_dir(server_root)
|
||||
- 加载配置后设置 prefix、db_host、db_port、db_user、db_pass、cookie。
|
||||
- 执行 run_startup_migrations(server_root)。
|
||||
@@ -969,10 +970,10 @@ GUI 图标:
|
||||
- __init__(project_root=None):无项目时 config_error="未打开项目"。
|
||||
- open_project(project_root):调用 ensure_and_get_server_manager_config_dir;成功后设置 tool_dir、tool_config_path、data。
|
||||
- _load_tool_config:读 key=value。
|
||||
- _save_tool_config:按固定分组写 tool.config。
|
||||
- _load_default_kv(server_root):读 .server_manager/config/default.kv。
|
||||
- _load_config:tool.config 为空时从 default.kv 补齐;首次运行自动创建 run_dir;需要保存补齐后的 tool.config。
|
||||
- save:写 tool.config 前刷新 ip/game_host 为 get_local_ip()。
|
||||
- _save_tool_config:按固定分组写 user.config。
|
||||
- _load_default_kv(server_root):读 .server_manager/config/default.config。
|
||||
- _load_config:user.config 为空时从 default.config 补齐;首次运行自动创建 run_dir;需要保存补齐后的 user.config。
|
||||
- save:写 user.config 前刷新 ip/game_host 为 get_local_ip()。
|
||||
- get/set 支持嵌套 key。
|
||||
- has_project/is_config_complete/is_configured/get_missing_config。
|
||||
|
||||
@@ -997,7 +998,7 @@ GUI 图标:
|
||||
- CreateServerTab:创建服务器。
|
||||
- ServerManageTab:本地/远程服务器管理。
|
||||
- ConfigTab:工具设置。
|
||||
- DefaultKvTab:default.kv 编辑。
|
||||
- DefaultKvTab:default.config 编辑。
|
||||
- UpdateCheckWorker/UpdateDownloadWorker:自动更新后台工作线程。
|
||||
- WelcomePage:无项目欢迎页。
|
||||
- MainWindow:主窗口、菜单、欢迎页/项目页切换、更新检查、项目迁移、状态缓存。
|
||||
@@ -1034,7 +1035,7 @@ GUI 图标:
|
||||
find_rg_executable 查找顺序:
|
||||
|
||||
- RG_PATH 环境变量。
|
||||
- 打包后 main.exe 同目录的 rg.exe/rg。
|
||||
- 打包后 ServerManager.exe 同目录的 rg.exe/rg。
|
||||
- 源码仓库根目录的 rg.exe/rg。
|
||||
- PATH 中的 rg。
|
||||
|
||||
@@ -1090,7 +1091,7 @@ GUI 图标:
|
||||
|
||||
src/updater.py 必须实现:
|
||||
|
||||
- _version_json_path:打包后优先 main.exe 同目录 version.json,再 sys._MEIPASS/version.json;源码运行用项目根 version.json。
|
||||
- _version_json_path:打包后优先 ServerManager.exe 同目录 version.json,再 sys._MEIPASS/version.json;源码运行用项目根 version.json。
|
||||
- get_current_version:读取 version 字段,失败返回 0.0.0。
|
||||
- get_version_info:读取完整 JSON,失败返回 {"version": "0.0.0", "release_notes": ""}。
|
||||
- _parse_version/version_less:将版本字符串转 int tuple 比较。
|
||||
@@ -1131,11 +1132,11 @@ GUI 图标:
|
||||
- version.json 设置 version、release_notes。
|
||||
- full_installer_url 固定指向 ServerManager_Setup.exe。
|
||||
- delta_updates 只保留 old_version -> new_version 一项,patch_url 格式为 output/patches/v<old>_to_v<new>.patch。
|
||||
- 如果 src/dist/main/_internal/version.json 或 src/dist/main/version.json 存在,则同步复制。
|
||||
- 如果 src/dist/ServerManager/_internal/version.json 或 src/dist/ServerManager/version.json 存在,则同步复制。
|
||||
|
||||
set_version_post 必须:
|
||||
|
||||
- 找新 exe:src/dist/main/main.exe,找不到再找 src/dist/main.exe。
|
||||
- 找新 exe:src/dist/ServerManager/ServerManager.exe,找不到再找 src/dist/ServerManager.exe。
|
||||
- 没有 old_exe_path 时只复制 version.json 到 output。
|
||||
- 有 old_exe_path 且 bsdiff4 可用时生成 output/patches/v<old>_to_v<new>.patch。
|
||||
- 计算新 exe sha256,填回 version.json 的 delta_updates[old_version].new_exe_sha256。
|
||||
@@ -1548,12 +1549,12 @@ GUI 图标:
|
||||
- 项目简介:Windows GUI + Linux CLI。
|
||||
- 功能特性:控制台、创建服务器、服务器管理、日志查看、工具设置、自动更新。
|
||||
- 打包与发版维护者流程:先 pack_local_test,再 release/pack_all。
|
||||
- rg.exe 放置说明:根目录与 src 同级;build.bat 会复制到 dist/main。
|
||||
- rg.exe 放置说明:根目录与 src 同级;build.bat 会复制到 dist/ServerManager。
|
||||
- 安装说明:Windows 安装包、源码运行 Windows/Linux。
|
||||
- 快速上手:打开项目时选择服务器项目根目录,不要选 run/config/.server_manager/config。
|
||||
- 首次打开项目会复制模板到 .server_manager/config。
|
||||
- 重点路径:服务器根目录、运行目录、Erlang 路径。
|
||||
- CLI 用法表:main.exe/main 无参数 GUI,带参数 CLI。
|
||||
- CLI 用法表:ServerManager.exe/ServerManager 无参数 GUI,带参数 CLI。
|
||||
- 命令行参数完整说明。
|
||||
- version.json 字段说明、download/update URL 规则。
|
||||
- 配置说明:项目级配置、单服配置、模板来源。
|
||||
@@ -1567,7 +1568,7 @@ GUI 图标:
|
||||
- 推荐流程:本地测试包 -> 本地安装验证 -> 正式发版。
|
||||
- pack_local_test 不改版本、不覆盖 output。
|
||||
- release.bat 顺序:PyInstaller -> 改版本 -> Inno -> post-build。
|
||||
- 本地不保存 main_*.exe;若要增量,需手动提供上一版 main.exe。
|
||||
- 本地不保存 ServerManager_*.exe;若要增量,需手动提供上一版 ServerManager.exe。
|
||||
- 手动发版命令:
|
||||
- cd src
|
||||
- build.bat
|
||||
@@ -1869,7 +1870,7 @@ GUI 图标:
|
||||
2. 选择是则 shutil.rmtree(_build)。
|
||||
3. 执行 `<rebar3> as game_server_dev compile`,输出到控制台。
|
||||
- emit config_saved。
|
||||
- 提示“项目配置已保存到当前项目的 .server_manager/config/tool.config”。
|
||||
- 提示“项目配置已保存到当前项目的 .server_manager/config/user.config”。
|
||||
|
||||
31. CLI argparse 精确结构细则
|
||||
|
||||
@@ -1942,7 +1943,7 @@ GUI 图标:
|
||||
|
||||
Windows `src/build.bat` PyInstaller 主命令必须等价于:
|
||||
|
||||
- `pyinstaller --noconfirm --onedir --console --name main`
|
||||
- `pyinstaller --noconfirm --onedir --console --name ServerManager`
|
||||
- `--icon icon\icon.ico`,没有 icon.ico 时用 `--icon NONE`
|
||||
- `--add-data "..\version.json;."`
|
||||
- `--add-data "config.json;."`
|
||||
@@ -1967,11 +1968,11 @@ GUI 图标:
|
||||
|
||||
Windows build 后处理:
|
||||
|
||||
- 如果 `..\rg.exe` 存在,复制到 `dist\main\rg.exe`。
|
||||
- 如果 `..\output\config` 存在,复制到 `dist\main\config\`。
|
||||
- 如果 `..\rg.exe` 存在,复制到 `dist\ServerManager\rg.exe`。
|
||||
- 如果 `..\output\config` 存在,复制到 `dist\ServerManager\config\`。
|
||||
- 生成 mini_updater:
|
||||
`pyinstaller --noconfirm --onefile --windowed --name mini_updater --distpath dist --workpath build_mini --specpath build_mini ..\mini_updater.py`
|
||||
- 如果 `config\tool.config` 存在,复制到 `dist\main\config\tool.config`。
|
||||
- 如果 `config\user.config` 存在,复制到 `dist\ServerManager\config\user.config`。
|
||||
- 清理 build、build_mini、spec。
|
||||
|
||||
Linux `build_linux.sh`:
|
||||
@@ -1983,8 +1984,8 @@ GUI 图标:
|
||||
- `server_commands.py:.`
|
||||
- `server_creator.py:.`
|
||||
- `icon:icon`
|
||||
- 输出 `dist/main/main`。
|
||||
- 复制 `../output/config/.` 到 `dist/main/config/`。
|
||||
- 输出 `dist/ServerManager/ServerManager`。
|
||||
- 复制 `../output/config/.` 到 `dist/ServerManager/config/`。
|
||||
|
||||
Inno Setup `build_installer.iss`:
|
||||
|
||||
@@ -1998,9 +1999,9 @@ GUI 图标:
|
||||
- OutputDir output
|
||||
- OutputBaseFilename ServerManager_Setup
|
||||
- MyAppVersion "1.0.46"。
|
||||
- MyAppExeName "main.exe"。
|
||||
- MyAppExeName "ServerManager.exe"。
|
||||
- Files:
|
||||
- Source "src\dist\main\*" DestDir "{app}" recursesubdirs createallsubdirs
|
||||
- Source "src\dist\ServerManager\*" DestDir "{app}" recursesubdirs createallsubdirs
|
||||
- Source "src\dist\mini_updater.exe" DestDir "{app}"
|
||||
- Source "version.json" DestDir "{app}"
|
||||
- Source "output\config\*" DestDir "{app}\config" recursesubdirs createallsubdirs
|
||||
@@ -2013,12 +2014,12 @@ GUI 图标:
|
||||
- 可选桌面快捷方式
|
||||
- 可选快速启动栏
|
||||
- Run:
|
||||
- 安装完成后 nowait postinstall 启动 `{app}\main.exe`
|
||||
- 安装完成后 nowait postinstall 启动 `{app}\ServerManager.exe`
|
||||
- UninstallDelete:
|
||||
- 删除 `{app}`
|
||||
- 删除 `{localappdata}\{#MyAppName}`
|
||||
|
||||
33. default.kv 与 sys 模板生成细则
|
||||
33. default.config 与 sys 模板生成细则
|
||||
|
||||
如果无法还原真实 Erlang sys_*.config.example 的完整内容,也必须生成结构化模板,满足以下要求:
|
||||
|
||||
@@ -2111,7 +2112,7 @@ GUI 图标:
|
||||
|
||||
- `python -m py_compile src/server_manager_gui.py src/server_manager_cli.py src/server_commands.py src/server_creator.py src/log_viewer_tab.py src/log_viewer_pane.py src/rg_search.py src/app_config.py src/updater.py`
|
||||
- `python src/server_manager_cli.py --help`
|
||||
- `python -c "from server_commands import read_config_file; print(read_config_file('output/config/default.kv').get('prefix'))"`
|
||||
- `python -c "from server_commands import read_config_file; print(read_config_file('output/config/default.config').get('prefix'))"`
|
||||
- `python -c "from server_creator import generate_server_dir_name; print(generate_server_dir_name('ddxq2','game',100))"`
|
||||
- `python -c "from rg_search import find_rg_executable; print(find_rg_executable())"`
|
||||
|
||||
@@ -2119,7 +2120,7 @@ GUI 图标:
|
||||
|
||||
- 无项目启动欢迎页。
|
||||
- 打开一个临时服务器项目目录后生成 `.server_manager/config`。
|
||||
- 工具设置保存后存在 `.server_manager/config/tool.config`。
|
||||
- 工具设置保存后存在 `.server_manager/config/user.config`。
|
||||
- 创建服务器后存在 `run/<server>/config/kv.config` 与 `sys.config`。
|
||||
- 日志页在无日志文件时给出“文件不存在”而不是崩溃。
|
||||
|
||||
@@ -2245,11 +2246,11 @@ GUI 图标:
|
||||
|
||||
36. DefaultKvTab 细则
|
||||
|
||||
DefaultKvTab 用于编辑当前项目 `.server_manager/config/default.kv`。
|
||||
DefaultKvTab 用于编辑当前项目 `.server_manager/config/default.config`。
|
||||
|
||||
UI:
|
||||
|
||||
- 标题:`默认配置管理 (.server_manager/config/default.kv)`,颜色 #25c889,16px,加粗。
|
||||
- 标题:`默认配置管理 (.server_manager/config/default.config)`,颜色 #25c889,16px,加粗。
|
||||
- 描述:`此文件定义创建服务器时的默认值,支持 ${key} 占位符替换`。
|
||||
- 横向 QSplitter:
|
||||
- 左侧:分类列表,最大宽 200;底部 `+ 新增配置项`。
|
||||
@@ -2261,7 +2262,7 @@ GUI 图标:
|
||||
load_default_kv:
|
||||
|
||||
- server_root 为空时控制台输出 `[警告] 请先配置服务器根目录`。
|
||||
- default_kv_path = get_server_manager_config_dir(server_root) / "default.kv"。
|
||||
- default_kv_path = get_server_manager_config_dir(server_root) / "default.config"。
|
||||
- 文件不存在时输出警告。
|
||||
- 读取文件时:
|
||||
- current_category 初始为“其他”。
|
||||
@@ -2308,7 +2309,7 @@ GUI 图标:
|
||||
- 成功输出 `[成功] 配置已保存: <path>` 并弹窗。
|
||||
- 失败输出错误并 QMessageBox.critical。
|
||||
|
||||
注意:此页保存会重写 default.kv,因此注释和空行不会完全保留;复刻时应保持这个行为。
|
||||
注意:此页保存会重写 default.config,因此注释和空行不会完全保留;复刻时应保持这个行为。
|
||||
|
||||
37. CreateServerTab 动态字段与校验细则
|
||||
|
||||
@@ -2333,7 +2334,7 @@ GUI 图标:
|
||||
- 数据库配置框内提供 db_game_name、db_log_name 输入框;game/login/center/cross 显示,client 隐藏。
|
||||
- db_game_name 默认 `{prefix}_{type}_s{id}`,db_log_name 默认 `{prefix}_{type}_log_s{id}`,ID 或类型变化时同步默认值,但创建前可手动修改。
|
||||
- auto_reload 默认 default_kv.auto_reload == "true"。
|
||||
- 登录/中心节点优先 tool.config,其次 default.kv,去掉首尾单引号。
|
||||
- 登录/中心节点优先 user.config,其次 default.config,去掉首尾单引号。
|
||||
|
||||
`_on_server_id_changed(value)`:
|
||||
|
||||
@@ -2399,8 +2400,8 @@ GUI 图标:
|
||||
- 切回 SCRIPT_DIR。
|
||||
- 查找打包主程序优先级:
|
||||
1. 环境变量 SERVER_MANAGER_MAIN 且文件存在。
|
||||
2. `%SCRIPT_DIR%\main.exe`
|
||||
3. `%SCRIPT_DIR%\dist\main\main.exe`
|
||||
2. `%SCRIPT_DIR%\ServerManager.exe`
|
||||
3. `%SCRIPT_DIR%\dist\ServerManager\ServerManager.exe`
|
||||
- 无参数:
|
||||
- 打包程序存在:`"%SM_MAIN%" --root "%SERVER_ROOT%" interactive`
|
||||
- 否则:`python server_manager_cli.py --root "%SERVER_ROOT%" interactive`
|
||||
@@ -2421,7 +2422,7 @@ GUI 图标:
|
||||
- SM_MAIN 优先:
|
||||
1. SERVER_MANAGER_MAIN
|
||||
2. SCRIPT_DIR/main 且可执行
|
||||
3. SCRIPT_DIR/dist/main/main 且可执行
|
||||
3. SCRIPT_DIR/dist/ServerManager/ServerManager 且可执行
|
||||
- check_python 支持 python3 或 python,要求 Python 3.6+。
|
||||
- gui 模式检查 PyQt6,缺失时 pip3 install PyQt6 或 pip install PyQt6。
|
||||
- 无参数进入 interactive。
|
||||
@@ -2579,7 +2580,7 @@ GUI 图标:
|
||||
|
||||
配置项发现函数必须按以下优先级实现:
|
||||
|
||||
- `_read_default_kv(server_root)` 读取 `read_merged_config(server_root)`,即合并后的项目配置,不直接只读 default.kv。
|
||||
- `_read_default_kv(server_root)` 读取 `read_merged_config(server_root)`,即合并后的项目配置,不直接只读 default.config。
|
||||
- `get_required_keys_from_kv(server_root, server_type)` 从 `required_keys_base` 和 `required_keys_<type>` 读取逗号分隔列表;若 base 不存在则返回 None。
|
||||
- `get_config_keys_from_kv(server_root, server_type)` 读取所有 `config_keys_base_<key>` 与 `config_keys_<type>_<key>`,返回 `{key: 中文说明}`;一个都没有则返回 None。
|
||||
- `get_editable_config_from_default_kv(server_root)` 读取所有 `editable_config_<key>`,用于编辑对话框的可添加配置项。
|
||||
@@ -2620,7 +2621,7 @@ GUI 图标:
|
||||
- 调用 `generate_start_config(server_root, server_dir)` 生成完整 sys.config。
|
||||
- 成功返回 `(True, '服务器 xxx 创建成功', merged_config)`;异常返回 `(False, '创建服务器失败: xxx', None)`。
|
||||
|
||||
43. Config 类 tool.config 读写与首次打开项目细则
|
||||
43. Config 类 user.config 读写与首次打开项目细则
|
||||
|
||||
`server_manager_gui.py` 中 `Config` 类负责“当前项目配置”,不能把项目配置混入应用级 app_config。
|
||||
|
||||
@@ -2645,11 +2646,11 @@ GUI 图标:
|
||||
- `project_root = Path(project_root).resolve()`。
|
||||
- 调用 `ensure_and_get_server_manager_config_dir(project_root)`,该函数负责创建/同步 `.server_manager/config` 和受管模板。
|
||||
- 失败时保存 `config_error` 并返回 False。
|
||||
- 成功时设置 `tool_dir=project_root`,`tool_config_path=cfg_dir / "tool.config"`,清空 `config_error`,调用 `_load_config()` 后返回 True。
|
||||
- 成功时设置 `tool_dir=project_root`,`tool_config_path=cfg_dir / "user.config"`,清空 `config_error`,调用 `_load_config()` 后返回 True。
|
||||
|
||||
`_load_tool_config()`:
|
||||
|
||||
- tool.config 不存在返回空 dict。
|
||||
- user.config 不存在返回空 dict。
|
||||
- 逐行读取 UTF-8,strip 空白,跳过空行和 `#` 注释。
|
||||
- 只解析第一处 `=`,左右 strip 后存入 dict。
|
||||
- 出错返回空 dict。
|
||||
@@ -2667,14 +2668,14 @@ GUI 图标:
|
||||
`_load_config()` 的合并规则:
|
||||
|
||||
- `tool_cfg = _load_tool_config()`;`is_first_run = not tool_config_path.exists()`。
|
||||
- `server_root` 默认当前项目目录,tool.config 中 server_root 非空则覆盖。
|
||||
- `server_root` 默认当前项目目录,user.config 中 server_root 非空则覆盖。
|
||||
- `run_dir` 为空时默认 `server_root/run`。
|
||||
- 首次运行且 run_dir 不存在时尝试创建运行目录,失败只忽略,不阻止 GUI 打开。
|
||||
- 读取 `get_server_manager_config_dir(server_root) / 'default.kv'` 作为默认值来源。
|
||||
- 辅助 `get_value(tool_key, default_key, fallback)`:优先 tool.config;为空时读 default.kv;如果 default.kv 值是首尾单引号包裹,要去掉单引号;最后仍为空则 fallback。
|
||||
- 读取 `get_server_manager_config_dir(server_root) / 'default.config'` 作为默认值来源。
|
||||
- 辅助 `get_value(tool_key, default_key, fallback)`:优先 user.config;为空时读 default.config;如果 default.config 值是首尾单引号包裹,要去掉单引号;最后仍为空则 fallback。
|
||||
- database.port、login_db.server_id、login_db.port 要转 int,空值分别回退 3306、900、0。
|
||||
- 每次加载都用 `get_local_ip()` 写入 server.ip 和 server.game_host。
|
||||
- 首次运行或发现 db_host、db_user、db_pass、prefix、login_node、center_node、cookie 从 default.kv 补齐时,调用 `save()` 回写 tool.config。
|
||||
- 首次运行或发现 db_host、db_user、db_pass、prefix、login_node、center_node、cookie 从 default.config 补齐时,调用 `save()` 回写 user.config。
|
||||
|
||||
`save()`:
|
||||
|
||||
@@ -2795,7 +2796,7 @@ GUI 图标:
|
||||
|
||||
- `len(sys.argv) > 1` 时调用 `_run_cli_from_argv()`,由 `server_manager_cli.main()` 处理 list/create/start/stop 等命令。
|
||||
- 无参数时调用 GUI `main()`。
|
||||
- 这样打包后的 `main.exe list` 与 `python server_manager_cli.py list` 行为一致。
|
||||
- 这样打包后的 `ServerManager.exe list` 与 `python server_manager_cli.py list` 行为一致。
|
||||
|
||||
GUI `main()` 规则:
|
||||
|
||||
@@ -2891,13 +2892,13 @@ GUI 图标:
|
||||
在基础验收之外,复刻项目还必须满足以下实现级检查:
|
||||
|
||||
- 无项目启动 GUI 时,不访问空的 `tool_config_path`,欢迎页可正常显示最近项目。
|
||||
- 第一次打开项目时,如果 `.server_manager/config/tool.config` 不存在,会创建 run 目录并把 default.kv 中的数据库、prefix、cookie 等默认值写入 tool.config。
|
||||
- 再次打开同一项目时,不覆盖已有 tool.config 中用户手动设置的值。
|
||||
- 第一次打开项目时,如果 `.server_manager/config/user.config` 不存在,会创建 run 目录并把 default.config 中的数据库、prefix、cookie 等默认值写入 user.config。
|
||||
- 再次打开同一项目时,不覆盖已有 user.config 中用户手动设置的值。
|
||||
- 最近项目写入的是应用级 JSON,不写到项目目录;删除或无效项目不会出现在欢迎页最近列表。
|
||||
- CLI `start --background` 会打开新窗口,CLI `start` 默认在当前窗口前台运行。
|
||||
- GUI 和 CLI 生成的 `run/<server>/config/kv.config` 字段一致,且随后都能生成 sys.config。
|
||||
- 停止服务器命令使用参数列表执行,不能依赖 shell 拼接引号。
|
||||
- `main.exe list`、`main.exe --help`、`python src/server_manager_gui.py list` 均进入 CLI,不弹 GUI。
|
||||
- `ServerManager.exe list`、`ServerManager.exe --help`、`python src/server_manager_gui.py list` 均进入 CLI,不弹 GUI。
|
||||
- `python src/server_manager_gui.py` 无参数进入 GUI,并自动打开最近的有效项目;没有最近项目则停留欢迎页。
|
||||
- 切换项目时,旧 tab、旧 console、旧 worker 引用不会继续显示在新项目界面。
|
||||
- frozen 模式下退出不会弹 PyInstaller 临时目录删除失败的系统错误框。
|
||||
@@ -2919,15 +2920,15 @@ GUI 图标:
|
||||
十四、验收标准
|
||||
|
||||
1. `python src/server_manager_gui.py` 无参数能打开 GUI 欢迎页。
|
||||
2. `python src/server_manager_gui.py list` 或打包后的 `main.exe list` 能进入 CLI。
|
||||
2. `python src/server_manager_gui.py list` 或打包后的 `ServerManager.exe list` 能进入 CLI。
|
||||
3. `python src/server_manager_cli.py --help` 显示完整命令。
|
||||
4. 打开一个服务器项目后能生成/同步 `<项目根>/.server_manager/config`。
|
||||
5. 工具设置保存后能写入 tool.config。
|
||||
5. 工具设置保存后能写入 user.config。
|
||||
6. 创建服务器能生成 run/<server>/config/kv.config 与 sys.config。
|
||||
7. rebar3 启动命令、快速 erl 启动命令、stop/remsh 命令格式正确。
|
||||
8. 服务器管理能扫描本地 run 目录并显示分类列表。
|
||||
9. 日志页能加载普通日志和归档日志;rg 存在时能全局搜索。
|
||||
10. `src/build.bat` 能生成 `src/dist/main/main.exe` 与 `src/dist/mini_updater.exe`。
|
||||
10. `src/build.bat` 能生成 `src/dist/ServerManager/ServerManager.exe` 与 `src/dist/mini_updater.exe`。
|
||||
11. Inno Setup 能生成 output/ServerManager_Setup.exe。
|
||||
12. version.json、release.py、mini_updater.py 支持全量/增量更新流程。
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user