Project Map · Structure
九万八千行代码,但你日常真正会碰的只有其中三块。先认路,再干活。
gameboxclient 工作区快照。
行数是当时统计的,用来判断「这块有多重」,不必精确对上。
仓库根目录下真正重要的只有四个地方:
electron/ ——
桌面外壳。开窗口、管更新、跟操作系统打交道。15 个文件,很小。
src/ —— 界面和业务。你 90% 的时间在这里。约 9.8 万行。
extend/ —— 外挂的第三方工具:SVN 客户端、Python
打包脚本、7-Zip、 地图编辑器、便携版 nginx 和
node。不是代码,是二进制,随安装包一起分发。
tools/ —— 给开发自己用的小脚本和 Excel 样表,跟运行时无关。
而 src/ 里面,真正的主战场是三个目录:
src/views/GameEditor/(各类配置编辑页,4.2 万行)、
src/store/config/(每张配置表的字段定义)、
src/components/PropEditor/(把字段定义渲染成表单的通用引擎)。
这三个是一套东西的三个面,理解了它们就理解了这个工具的一大半。
点标题展开。带标记的地方要特别留意: 主战场 日常改动集中区 · 别碰 有坑或已废弃 · 孤立 不在路由里、疑似停用 · 外部 二进制或外部工具。
electron/主进程:桌面外壳
15 文件
main/index.ts入口,只有两行:import ready 然后调用
main/handler/ready.ts真正的启动流程:灌环境变量 → whenReady → 建窗口
main/handler/channel.ts全部 21 个 IPC 通道都在这一个文件里。加 IPC 就改这主战场
main/helpers/window.ts建主窗口和 Excel 小窗;Remote.enable()
在这里
main/config/options.ts窗口的 webPreferences:三个安全开关全关在这里
main/manager/window.ts窗口实例的单例注册表
main/tools/updater.tselectron-updater 自动更新与日志初始化
preload/index.ts写了但从未被构建、从未被加载。看它等于看废纸别碰
src/渲染进程:界面与业务
约 9.8 万行
views/页面组件,按业务分目录
195 文件
GameEditor/游戏编辑器,18 个配置模块 +
专家模式各页。这是本体主战场42432 行
GameEditor/Dashboard/首页面板。1759 行的巨型聚合页,GM
和地图转换是它的弹窗2664 行
Database/index.vue 已不在路由里,但
const.ts 与
Components/ 仍被目录外
10 个在用文件引用 —— 删之前先
grep孤立10079 行
GM/GM
工具(发邮件、改年龄、公告等)。不是路由,
由 Dashboard 以弹窗方式引入3765 行
Option/发布栈。挂在 /expert/release,不是
/option1079 行
ReLogin/当前在用的登录页(路由
/login 指向它)
Login/index.vue 已被路由注释掉,只有
Password.vue 还在用孤立
MapTransform/地图转换,同样是 Dashboard 的弹窗
Script/, BasePage/
Script 无人引用;BasePage
有路由 /base 但不在任何菜单里孤立
GateWay/网关配置,挂在 /expert/gateWay
store/Pinia。两类,性质完全不同
36 文件
modules/真正的运行态:登录环境、任务队列、路由、弹窗、进度……19
个
modules/GameEvn.ts整个工具的钥匙链。SVN/Jenkins/GM 凭据都住在这里主战场
modules/table.ts用 import.meta.glob 把 config/ 下的 schema
全部装载成 Map
config/名字叫 store 其实不是状态,是 16
张配置表的字段定义 (Item.ts 5647 行、Npc.ts 1881
行)主战场
components/通用组件
72 文件
PropEditor/schema
驱动的表单引擎。把字段定义变成实际控件,是本项目最核心的抽象主战场
PropEditor/Components/可用的控件全集:Select / Switch / Time / MapPoint /
RelateDialog…
confirmServer/, VersionOption/
选服与版本切换,影响后续所有请求打到哪台服
Icon/, Dialog/,
Form/, Menu/,
TagsView/
脚手架自带的通用件,多数只用了一小部分
api/接口封装,按业务域分目录
80 文件
game/编辑器主力接口,全部打到
/1000y/engine/cmd
gm/GM 操作与表数据读写,含 excel_modify(1052
行)
login/登录、用户信息、以及构建轮询
checkstartBuild
workspace/本地工作副本路径与 SVN 状态(861 行)。页面没了,API
还在用
task/发布卡片的定义:哪些是 SVN 型、哪些是 Jenkins 型
utils/extend/和外部世界打交道的胶水层
主战场
envOption.tsinitEnv() 在这。改接口地址、改凭据来源,改的是这个文件,不是
.env
electron.ts渲染层通往
@electron/remote 的唯一出口,只有 5
行
svn.ts拼 svn 命令行并 exec。Mac/Win 走不同的二进制路径
python.ts调 extend/Python/** 下的
exe。解释器路径当前是断的,见下方「已知坑」别碰
jenkins/拆成 client / build / monitor / config
四块,是这一层写得最整齐的可照做
jenkins_old.ts上一版实现,还没删别碰
cos.ts, oss.ts
腾讯云 COS 与阿里云 OSS 两套对象存储封装
zip.ts, fsextend.ts,
dialog.ts
压缩、文件系统、系统对话框
config/axios/HTTP 层
service.ts在用的那个。拦截器、pcode 计算、1000y
特判都在这主战场
serviceold.ts旧版副本,内容有八成像。改错文件是本项目最经典的坑别碰
encryptor.ts密码 sha256 + base64、excelToken 加密
router/index.ts全部路由定义,700 行硬编码。hash 路由,加页面就在这里加主战场
permission.ts路由守卫:多窗口分流、离开确认、token 检查。不做权限过滤
locales/zh-CN.ts界面文案。想知道某个菜单项对应哪个路由名,查这里最快
hooks/web/18 个组合式函数:useStorage / useI18n / useTitle /
useNProgress…
layout/外壳:Header、TagsView、ToolHeader
directives/permission/v-hasPermi
指令注册了但全项目零使用,脚手架残留孤立
plugins/第三方装配:elementPlus / windi / svgIcon / vueI18n /
echarts
process/渲染侧的下载解压任务封装,与 worker 子进程对接
extend/外挂二进制与资源,随包分发
外部
6032 文件
worker/主进程 fork 的子进程脚本:download / decompress / unzip /
spwan*。 这几个是 JS,看得懂也改得动
Svn/便携版 SVN 客户端。Mac/Arm64/1.14.2/bin/svn
当前没有可执行位有坑
Python/16 个 .exe:地图转换、动画转换、lua 读写、nginx
初始化。 全是 Windows 可执行文件有坑
map/, TiledMap/
地图编辑与资源生成工具(exe)
QNnginx/, QNnode/
便携版 nginx 和 node,登录后被拉起来给本地预览用
7zip-bin/只有 win 目录
config/, localTableHeader/,
delData/
随包分发的 JSON 配置,运行时会被读取
tools/开发自用脚本,跟运行时无关
script/copyfile.jsnpm run cpsvn 调它,装依赖后自动跑
excel/q1/各类配置表的 xlsx 样本
根目录配置文件构建与规范
vite.config.ts构建全部配置。preload 构建块在 58-72 行被整段注释
.env / .env.base / .env.dev / .env.pro只有 11 个键。不要指望在这找到 SVN 或 Jenkins 配置
electron-builder.json5打包配置:哪些 extend 目录要 unpack
README.md脚手架模板原文,不反映本项目业务,不要当依据别信
这张表是本页最该收藏的部分。左边是需求的原话,右边是实际要动的文件。
| 需求听起来像 | 真正要改的地方 | 注意 |
|---|---|---|
| 物品表加一个字段 | src/store/config/Item.ts 加字段定义 |
页面组件不用动,PropEditor 会自己渲染 |
| 某个字段的下拉选项要加一项 |
对应 src/store/config/*.ts 里该字段的
options
|
选项若来自另一张表,去 views/GameEditor/*/module.ts
|
| 字段要换个控件(比如改成开关) | 同上,改字段的 editor / type |
可选控件全在 components/PropEditor/Components/ |
| 某个字段要显示在另一个标签页 |
src/views/GameEditor/<模块>/view.ts 的 Groups
|
只有部分模块有 view.ts,其余直接写在页面里 |
| 新增一个编辑页 / 菜单项 |
src/router/index.ts 加路由 +
src/locales/zh-CN.ts 加
router.future.* 标题
|
菜单靠 meta.showMenu 控制,图标用 iconify 名 |
| 接口地址要改 / 换服务器 |
src/utils/extend/envOption.ts
|
不是 .env。多数地址由 /user/info 下发,前端只是接收
|
| 请求要加一个统一的头 / 参数 | src/config/axios/service.ts 的请求拦截器 |
别改成 serviceold.ts |
| 要读写本地文件 / 调系统命令 | src/utils/extend/ 加一个模块 |
渲染层能直接 require('fs'),但新代码建议走 IPC |
| 要加一个主进程能力(开窗口、读注册表…) |
electron/main/handler/channel.ts 加
ipcMain.handle
|
渲染侧用 ipcRenderer.invoke 调 |
| 发布流程要加一种任务 |
src/api/task/index.ts 的卡片列表 +
utils/extend/jenkins/config.ts 的 JOB_TYPES
|
先想清楚是 SVN 型还是 Jenkins 型,两条路径完全不同 |
| 登录后要多做一件事 |
src/api/login/index.ts 的 loginSuccess()
|
注意它同时被 ReLogin 页调用,改动影响启动链 |
| 改按钮文案 / 菜单名 | src/locales/zh-CN.ts |
有不少页面把中文直接写死在模板里,先全局搜一下原文案 |
| 改样式 |
页面内的 <style lang="less" scoped>,或
WindiCSS 的原子类
|
两套并存:Element Plus 主题、WindiCSS 原子类、以及
src/styles/
|
| 要加一张新的配置表 |
src/store/config/ 新增 schema +
store/modules/table.ts 的
tableConfigMap 与几个表名数组
|
表名和文件名不一致时必须在 tableConfigMap 里登记映射
|
找不到入口时的通用办法
从界面文案倒推。在应用里看到「刷新时间」这个标签,
就全局搜这四个字。搜到的多半是某个
src/store/config/*.ts 里的
summary 字段,从那里往上就能定位到表和模块。
搜不到就搜路由名:地址栏 hash 里是 #/game/npc_edit, 去
src/router/index.ts 搜 npc_edit, 直接看到它的
component 指向哪个文件。
❌ 别学
Python 工具链的解释器路径当前是断的。
src/utils/extend/python.ts:34-41 按平台去找
extend/Python/Win/3.11/python.exe 或
extend/Python/Mac/3.8/bin/python3, 但当前
extend/Python/ 下根本没有 Win/ 和 Mac/ 这两个目录
—— 只有
move/ luaTrans/ Script/ mapMask/ transPlist/,里面是 16 个
.exe。
影响:地图转换、动画转换、lua 读写、nginx 初始化这几条链路, 在任何平台上都会因为找不到解释器而失败。
这是本仓库目前最该问清楚的一件事:这些 exe
是不是已经打包成独立 可执行文件、不再需要 python 解释器了?如果是,python.ts
里那段 command 拼接就是死代码。问到答案前不要自己乱改。
❌ 别学
smallWindow 一个变量当两样东西用。
electron/main/helpers/window.ts 里,smallWindow
本来存的是 Excel 小窗的 BrowserWindow 实例(71 行), 但
setSharedData(data)(103 行)会把它整个覆写成任意数据,
getSharedData()(106 行)再读回来。
后果:一旦调过 setSharedData,
getSmallWindow() 拿到的就不再是窗口对象了。
跨窗口传数据和窗口引用管理必须拆成两个变量。
❌ 别学
小窗的 setWindowOpenHandler 解构了不存在的字段。
helpers/window.ts:91 写的是
({ docUrl }) => shell.openExternal(docUrl),
但这个回调的入参对象里字段名是 url,不是
docUrl
—— 同一个文件 48 行的主窗口就写对了。
后果:在 Excel 小窗里点任何外链,传给
shell.openExternal 的都是 undefined。
规范做法见
Electron · setWindowOpenHandler,参数是 { url, frameName, features, ... }。