打包计划
任务:把《原神》文字战斗模拟系统打成一个解压即用的 zip 包,内置免安装 MySQL,对方装了 JDK 就能跑。 源项目根目录:
E:\C\cDownKeShe\(默认包原版);重构版:E:\AI\zcode\object\ke-she\refactored\。 打包工作目录:E:\AI\zcode\object\ke-she\dist\(新建)。
0. 用户决策(已确认)
Section titled “0. 用户决策(已确认)”- 数据库方案:随包带免安装 MySQL(不用 H2/SQLite,SQL 全不动)。
- 打包形态:完整项目 zip(源码 + 依赖 jar + run.bat + README),对方装 JDK 解压即跑。
1. 核心问题:硬编码的 MySQL 路径
Section titled “1. 核心问题:硬编码的 MySQL 路径”当前 DBConnector.java 硬编码:
File mysqlExe = new File("E:\\SQL\\mysql\\bin\\mysqld.exe");File myIni = new File("E:\\SQL\\mysql\\my.ini");pb.directory(new File("E:\\SQL"));别人电脑没有 E:\SQL,程序连不上库就 System.exit(1) 退出。必须改成相对路径,让 MySQL 跟着项目走。
2. MySQL 瘦身清单(关键,决定包体积)
Section titled “2. MySQL 瘦身清单(关键,决定包体积)”实测 E:\SQL\mysql 共 1.1 GB,绝大部分可删。运行时只保留:
✅ 必须保留
Section titled “✅ 必须保留”| 路径 | 体积 | 用途 |
|---|---|---|
bin/mysqld.exe | 49M | 数据库服务主程序(唯一必需的可执行) |
bin/*.dll(与 mysqld 同目录的运行时 DLL) | ~5M | VC++ 运行时,通常已在系统,但保险保留 |
share/ | 9.5M | 字符集、错误信息、时区表(mysqld 启动必需) |
lib/libmysql.dll | 6.9M | 客户端库(连接器用,保留保险) |
lib/plugin/ | — | 存储引擎插件(InnoDB 等,mysqld 启动会加载) |
my.ini | 145B | 配置文件(路径要改成相对/自适应) |
LICENSE README | <1M | GPL 协议,必须带(GPL 合规) |
❌ 可以删除(瘦身)
Section titled “❌ 可以删除(瘦身)”| 路径 | 体积 | 原因 |
|---|---|---|
bin/mysqld.pdb | 333M | 调试符号,运行完全不需要 |
bin/libprotobuf-debug.pdb 等 *.pdb | ~30M | 全部 pdb 调试符号 |
bin/mysql.exe mysqladmin.exe mysqldump.exe mysqlcheck.exe mysqlimport.exe mysqlshow.exe mysqlslap.exe mysqlpump.exe mysqlbinlog.exe mysql_migrate_keyring.exe mysql_upgrade.exe mysql_secure_installation.exe perror.exe myisam*.exe | 各 6-7M | 客户端/维护工具,游戏运行不需要,保留 mysqld.exe 一个即可 |
lib/*.lib(libmysql.lib/mysqlclient.lib/mysqlservices.lib) | 53M | 开发链接库,运行不需要 |
lib/private/ | — | 私有头,不需要 |
lib/mecab/ | — | 日语分词(可选删,体积小可留) |
include/ | 412K | C 开发头文件,不需要 |
docs/ | 10K | 文档,不需要 |
data/binlog.* | <1M | 二进制日志,初始化时会重生 |
data/*.err *.pid auto.cnf | 小 | 运行时生成 |
data 目录单独处理(见第 3 节)。
瘦身后预估:mysqld.exe(49) + share(9.5) + lib(~7) + bin/dll(~5) ≈ 70M,zip 压缩后约 30M。
3. data 目录策略(最容易出错,重点)
Section titled “3. data 目录策略(最容易出错,重点)”mysqld 需要 datadir 指向一个已初始化的数据目录(含 mysql 系统库、表结构)。两个方案:
方案 A(推荐):打包干净的 data 目录
Section titled “方案 A(推荐):打包干净的 data 目录”- 把现有
E:\SQL\mysql\data整个复制过来,但清理运行时产物:删binlog.*、*.err、*.pid、auto.cnf、ib_logfile*、ibdata1、undo_*、#innodb_temp、mysql.sock。 - 保留:
mysql/(系统库)、genshin_rpg/(游戏数据,900K)、sys/、performance_schema/、各种.pem(SSL 证书,初始化生成但保留可避免重新生成失败)、ib_buffer_pool。 - 风险:InnoDB 数据文件(ibdata1)被删后,启动时可能报”系统表空间不存在”。更稳的做法是用
mysqld --initialize重新生成 data(见方案 B)。
方案 B(最稳):data 目录不打包,首次启动自动初始化
Section titled “方案 B(最稳):data 目录不打包,首次启动自动初始化”- zip 里不带 data 目录(或带一个空的
data/占位)。 start_mysql.bat启动前检测:若data\mysql不存在,执行:(mysqld --defaults-file=my.ini --initialize-insecure --console--initialize-insecure= root 空密码,与代码里密码候选["","root","123456"]匹配)。- 初始化后再启动 mysqld,再跑
db\genshin_rpg.sql建库建表。
本计划采用方案 B 的混合:打包里带一份预先
--initialize过、并已导入 genshin_rpg.sql 的干净 data(让对方解压即有数据、零等待),同时在start_mysql.bat里加”检测 data 是否存在,否则自动初始化”的兜底。两全。
my.ini 路径处理
Section titled “my.ini 路径处理”原 my.ini:
[mysqld]port=3306basedir=E:\SQL\mysqldatadir=E:\SQL\mysql\datacharacter-set-server=utf8mb4default-storage-engine=INNODBsecure-file-priv=""问题:basedir/datadir 用了绝对路径,换机器就失效。MySQL 的 basedir/datadir 不支持相对路径写法(会相对 CURRENTDIR,行为不可靠)。
解决:不把 basedir/datadir 写死在 my.ini,改由启动脚本动态生成 my.ini(脚本知道自己所在目录)。详见第 5 节 start_mysql.bat。
4. 代码改造(仅 DBConnector.java,最小改动)
Section titled “4. 代码改造(仅 DBConnector.java,最小改动)”4.1 路径改成相对工作目录
Section titled “4.1 路径改成相对工作目录”原代码用 E:\\SQL\\mysql\\bin\\mysqld.exe。改成:从 当前工作目录 或 jar/类路径所在目录 推导 MySQL 路径。
采用约定:MySQL 子目录与启动脚本同级。即包内布局:
GenshinRPG/├─ run.bat ← 双击启动入口├─ start_mysql.bat ← 启动/初始化 MySQL(被 run.bat 调用)├─ stop_mysql.bat ← 关闭 MySQL├─ mysql/ ← 瘦身后的免安装 MySQL│ ├─ bin/mysqld.exe│ ├─ share/│ ├─ lib/libmysql.dll, plugin/│ ├─ data/ ← 干净 data(含 genshin_rpg)│ └─ my.ini ← 由 start_mysql.bat 动态生成├─ lib/│ └─ mysql-connector-j-8.0.33.jar├─ bin/ ← 编译产物(可预编译好,对方免编译)├─ src/ ← 源码(分包重构版)├─ db/│ └─ genshin_rpg.sql ← 建库脚本(首次初始化兜底用)├─ README.txt ← 使用说明└─ .gitignore4.2 DBConnector.java 改动点(精确到行)
Section titled “4.2 DBConnector.java 改动点(精确到行)”定位(重构版 refactored/src/com/genshin/rpg/dao/DBConnector.java,约 50-65 行):
原代码:
File mysqlExe = new File("E:\\SQL\\mysql\\bin\\mysqld.exe");File myIni = new File("E:\\SQL\\mysql\\my.ini");if (mysqlExe.exists() && myIni.exists()) { ProcessBuilder pb = new ProcessBuilder( mysqlExe.getAbsolutePath(), "--defaults-file=" + myIni.getAbsolutePath() ); pb.directory(new File("E:\\SQL")); pb.start(); Thread.sleep(4000); connected = tryConnect();}改为(用相对路径,基准 = 程序工作目录 = 包根目录):
// 内置 MySQL 子目录路径:相对当前工作目录File mysqlDir = new File("mysql");File mysqlExe = new File(mysqlDir, "bin/mysqld.exe");File myIni = new File(mysqlDir, "my.ini");if (mysqlExe.exists() && myIni.exists()) { ProcessBuilder pb = new ProcessBuilder( mysqlExe.getAbsolutePath(), "--defaults-file=" + myIni.getAbsolutePath() ); pb.directory(mysqlDir.getAbsoluteFile()); // 工作目录设为 mysql/,便于相对 data 路径 pb.redirectErrorStream(true); pb.start(); Thread.sleep(4000); connected = tryConnect();}⚠️ 红线:除路径外,其余逻辑一字不改——密码候选
["","root","123456"]、连接串jdbc:mysql://localhost:3306/...、库名genshin_rpg、Thread.sleep(4000)、连不上则JOptionPane + System.exit(1)全部保留。
4.3 可选增强(推荐加,提升体验,不破坏功能)
Section titled “4.3 可选增强(推荐加,提升体验,不破坏功能)”连不上时给更友好的提示,引导用户检查:
javax.swing.JOptionPane.showMessageDialog(null, "无法连接 MySQL。\n请确认:\n1) 本机 3306 端口未被占用\n2) mysql\\data 目录存在且未损坏\n3) 已按 README 指示从 run.bat 启动", "数据库连接错误", javax.swing.JOptionPane.ERROR_MESSAGE);(原提示是”无法连接至 localhost:3306”,可保留原文不改,仅补几行说明。)
5. 启动脚本设计
Section titled “5. 启动脚本设计”5.1 start_mysql.bat(核心,处理路径自适应 + 首次初始化)
Section titled “5.1 start_mysql.bat(核心,处理路径自适应 + 首次初始化)”@echo offchcp 65001 >nulcd /d "%~dp0"
echo [MySQL] 检查数据库服务...REM 若 3306 已通,说明 MySQL 已在跑(本机或其他),直接跳过启动mysql\bin\mysql.exe -uroot -e "SELECT 1" >nul 2>&1REM 注意:上面这行需要 mysql.exe,我们瘦身时删了。改用端口探测:
REM 用 powershell 探测端口(避免依赖 mysql.exe)powershell -Command "try { $c=New-Object Net.Sockets.TcpClient; $c.Connect('localhost',3306); $c.Close(); exit 0 } catch { exit 1 }"if %errorlevel%==0 ( echo [MySQL] 检测到 3306 端口已开放,跳过启动。 goto :eof)
REM 端口未开,启动内置 MySQLecho [MySQL] 正在启动内置免安装 MySQL...
REM 动态生成 my.ini(路径自适应本机)set "BASE=%cd%\mysql"set "DATA=%BASE%\data"( echo [mysqld] echo port=3306 echo basedir=%BASE% echo datadir=%DATA% echo character-set-server=utf8mb4 echo default-storage-engine=INNODB echo secure-file-priv="" echo skip-grant-tables) > mysql\my.ini
REM 若 data 未初始化,先初始化(首次运行)if not exist "mysql\data\mysql" ( echo [MySQL] 首次运行,正在初始化数据目录(约 10 秒)... mysql\bin\mysqld.exe --defaults-file=mysql\my.ini --initialize-insecure --console)
REM 后台启动 mysqldstart "" /B mysql\bin\mysqld.exe --defaults-file=mysql\my.ini
REM 等待启动(最多 30 秒,每秒探测一次端口)set /a wait=0:waitlooppowershell -Command "try { $c=New-Object Net.Sockets.TcpClient; $c.Connect('localhost',3306); $c.Close(); exit 0 } catch { exit 1 }"if %errorlevel%==0 goto :readyset /a wait+=1if %wait% geq 30 goto :timeouttimeout /t 1 /nobreak >nulgoto :waitloop
:readyecho [MySQL] 启动成功。goto :eof
:timeoutecho [MySQL] 启动超时!请检查 mysql\data 目录或 3306 端口占用。exit /b 1关键点:
- 用
skip-grant-tables让 root 免密(与代码密码候选""匹配)。--initialize-insecure首次初始化(root 空密码)。- 端口探测替代依赖 mysql.exe(瘦身已删)。
- 用 PowerShell 探测端口兼容性好(Win7+/PS 自带)。
5.2 run.bat(用户双击入口)
Section titled “5.2 run.bat(用户双击入口)”@echo offchcp 65001 >nulcd /d "%~dp0"
echo ========================================echo 原神文字战斗模拟系统 - 启动中echo ========================================
REM 1. 启动内置 MySQLcall start_mysql.batif %errorlevel% neq 0 ( echo [错误] MySQL 启动失败,程序无法继续。 pause exit /b 1)
REM 2. 启动 Java 程序echo [应用] 正在启动...set "CP=bin;lib\mysql-connector-j-8.0.33.jar"java -cp "%CP%" com.genshin.rpg.Main
REM 3. 退出时关闭 MySQL(可选,避免残留进程)echo.echo [清理] 正在关闭数据库服务...call stop_mysql.batpause5.3 stop_mysql.bat
Section titled “5.3 stop_mysql.bat”@echo offcd /d "%~dp0"REM 用 mysqladmin 关闭需要 mysqladmin.exe(已删)。改用任务管理方式:REM 方案:存储 mysqld 的 PID 启动时记录,关闭时按 PID 杀进程。REM 简化版:直接按进程名结束本目录启动的 mysqld(不影响系统服务)REM 安全做法:记录 PIDif exist mysql\mysqld.pid ( for /f %%P in (mysql\mysqld.pid) do taskkill /PID %%P /F >nul 2>&1 del mysql\mysqld.pid) else ( REM 兜底:提示用户手动关 echo [提示] 未找到 PID 记录。如需关闭,可在任务管理器结束 mysqld.exe。)(启动脚本里 start "" /B mysqld 改为先拿 PID:start "" /B cmd /c "mysqld ... & echo !PID! > mysql\mysqld.pid" 较复杂,执行 AI 可简化为”程序退出后留 MySQL 运行,下次启动更快”,在 README 里说明。)
6. README.txt(写给最终用户)
Section titled “6. README.txt(写给最终用户)”《原神》文字战斗模拟系统 - 使用说明====================================
【环境要求】- Windows 10/11(64 位)- 已安装 JDK 17 或以上(运行 java -version 能看到版本号即可)
【运行步骤】1. 解压本 zip 到任意目录(路径尽量不要含中文或空格)。2. 双击 run.bat。3. 首次启动会自动初始化数据库(约 10 秒),请耐心等待。4. 出现登录窗口即成功。 - 玩家:点"玩家注册"新建账号 → 切"玩家登录"登录。 - 管理员:点"管理员后台",密码 klee is comming
【常见问题】Q: 提示"3306 端口被占用"?A: 你电脑已装了 MySQL。双击 run.bat 会自动检测并复用,无需处理。
Q: 启动后白屏/闪退?A: 确认 JDK 已装。命令行运行 java -version 验证。
Q: 想看源码?A: 用 IntelliJ IDEA 打开本目录,src/ 下是全部源码。
【目录说明】- run.bat 启动入口- mysql/ 内置免安装 MySQL(请勿删除)- lib/ JDBC 驱动- bin/ 已编译的 class(可直接运行)- src/ 源码- db/genshin_rpg.sql 建库脚本(参考)
【卸载】直接删除整个文件夹即可。数据库数据存在 mysql\data 下,会一起删除。7. 工作步骤(执行 AI 按序执行)
Section titled “7. 工作步骤(执行 AI 按序执行)”- 创建打包工作目录
E:\AI\zcode\object\ke-she\dist\genshinrpg\。 - 瘦身 MySQL:把
E:\SQL\mysql复制到GenshinRPG\mysql\,然后删除第 2 节列出的所有可删项(*.pdb、lib\*.lib、非 mysqld 的bin\*.exe、include、docs、lib\private、data\binlog.*、data\*.err、data\*.pid、data\auto.cnf、data\ib_logfile*、data\ibdata1、data\undo_*、data\#innodb_temp)。- 保留:
bin\mysqld.exe、bin\*.dll、share\、lib\libmysql.dll、lib\plugin\、lib\mecab\(可选)、LICENSE、README、data\mysql、data\sys、data\performance_schema、data\genshin_rpg、data\*.pem。
- 保留:
- 复制源码与依赖:把
refactored\src\复制到GenshinRPG\src\;mysql-connector-j-8.0.33.jar复制到GenshinRPG\lib\;db\genshin_rpg.sql复制到GenshinRPG\db\。 - 改 DBConnector.java:按第 4.2 节把绝对路径
E:\\SQL\\...改为相对mysql\...。只改路径,其余不动。 - 预编译 bin:在
GenshinRPG\下编译javac -encoding UTF-8 -d bin @sources.txt,让对方免编译(README 也写”可双击 run.bat 直接跑”)。 - 写脚本:写
start_mysql.bat、run.bat、stop_mysql.bat、README.txt、.gitignore。 - 本地验证(必须在 dist 上跑通):
- 关掉本机已有的 MySQL 服务(
net stop mysql或任务管理器结束 mysqld),模拟”对方无 MySQL”环境。 - 删
GenshinRPG\mysql\data重新初始化(验证首次初始化流程)。 - 双击 run.bat,确认:① 端口探测 → ② 初始化 → ③ 程序启动 → ④ 能登录能玩。
- 再次双击(复用已启动的 MySQL),确认不重复初始化。
- 关掉本机已有的 MySQL 服务(
- 打 zip:把整个
GenshinRPG\压成GenshinRPG.zip,放E:\AI\zcode\object\ke-she\dist\。 - 体积核对:zip 应在 50MB 以内(目标 30MB 左右)。
8. 完成判据(必须全部验证)
Section titled “8. 完成判据(必须全部验证)”-
GenshinRPG.zip解压后,在不带E:\SQL的干净环境下双击 run.bat 能启动到登录窗。 - 首次启动自动初始化 MySQL 并建好 genshin_rpg 库(程序能登录/注册/存档)。
- DBConnector.java 除路径行外无其他改动(diff 自查)。
- 所有功能与原版一致(登录/战斗/养成/管理员后台)。
- zip 体积 < 50MB。
- README 写清楚运行步骤。
- 写一份
dist\PACK_NOTE.md:记录瘦身明细(删了什么、留了什么、最终体积)、首次初始化验证记录、复用启动验证记录。
9. 风险与对策
Section titled “9. 风险与对策”| 风险 | 对策 |
|---|---|
mysqld.exe 缺少 lib/plugin 无法启动 | 保留 lib\plugin\(InnoDB 等引擎插件) |
--initialize-insecure 在某些 MySQL 版本行为差异 | 打包已初始化的 data 兜底(方案 B 混合) |
| 对方机器已有 MySQL 占 3306 | start_mysql.bat 端口探测,已开则复用 |
| 路径含中文/空格导致 mysqld 报错 | README 提示解压到无中文空格路径 |
| GPL 协议(MySQL 是 GPL) | 保留 LICENSE/README,分发说明注明”内含 MySQL Community Server (GPL)“ |
| binlog 删除后启动失败 | 用 --initialize 重生而非手动删 |
(计划书完。配合同目录《打包执行提示词.md》使用。)