Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
113 commits
Select commit Hold shift + click to select a range
99a769d
Fix: Replace password auth with token auth for factorio.com API
Jun 19, 2026
437cd94
文档: 添加 FSM 前端国际化设计规范
BAYUNZIYUE Jun 21, 2026
d9c93b2
文档: 添加 FSM 前端国际化实现计划
BAYUNZIYUE Jun 21, 2026
6e452f0
功能: 添加 i18n 核心基础设施 + 英文翻译文件(9 命名空间)
BAYUNZIYUE Jun 21, 2026
af63fe9
功能: 安装 i18n 依赖 + 添加中文翻译文件(9 命名空间)
BAYUNZIYUE Jun 21, 2026
a2b7376
功能: ConfirmDialog + Layout 国际化(含语言切换器)
BAYUNZIYUE Jun 21, 2026
b0ee691
功能: 添加 FSM 前端国际化支持(zh-CN 中文翻译)
BAYUNZIYUE Jun 21, 2026
30f7890
文档: 添加新语言适配指南
BAYUNZIYUE Jun 21, 2026
fcf5bc7
文档: 添加服务器版本管理器设计规范
BAYUNZIYUE Jun 21, 2026
e881478
文档: 添加服务器版本管理器实现计划
BAYUNZIYUE Jun 21, 2026
abcad12
功能: 添加服务器版本管理器(下载/更新 Factorio 服务端)
BAYUNZIYUE Jun 21, 2026
2ef2054
修复: 服务器版本管理器 API 路由注册 + Factorio API 格式适配
BAYUNZIYUE Jun 21, 2026
4400b99
调整: 版本列表区分稳定版(绿色)与测试版(橙色)标识
BAYUNZIYUE Jun 21, 2026
b77795c
修复: 版本安装解压路径修正为 FactorioDir 根目录
BAYUNZIYUE Jun 21, 2026
a5a01e4
功能: 集成 updater.factorio.com 完整版本列表支持降级
BAYUNZIYUE Jun 21, 2026
d862202
调整: 完整版本列表按稳定版/测试版分栏,从新到旧排列
BAYUNZIYUE Jun 21, 2026
81c4464
修复: 版本排序——按数字从新到旧排列
BAYUNZIYUE Jun 21, 2026
f84df0a
修复: 前端订阅 server_version WebSocket 房间以接收下载进度
BAYUNZIYUE Jun 21, 2026
01376eb
修复: axios 拦截器处理超时无响应 + 安装请求超时设为 10 分钟
BAYUNZIYUE Jun 21, 2026
6f3fda8
重构: 安装改为异步——API 秒回,下载在后台,进度靠 WebSocket
BAYUNZIYUE Jun 21, 2026
74e3d64
功能: 安装完成后自动刷新 FSM 内存中版本缓存
BAYUNZIYUE Jun 21, 2026
8657f79
修复: 2.0 存档解析——Python 辅助脚本 + Go fallback 共存双方案
BAYUNZIYUE Jun 21, 2026
163c7e8
重构: 纯 Go 实现 2.0 存档解析——分离 readFromV1/readFromV2,零外部依赖
BAYUNZIYUE Jun 21, 2026
e516474
修复: 版本号显示去掉尾部零——2.0 不再显示为 2.0.0.0
BAYUNZIYUE Jun 21, 2026
e88fdd7
修复: 损坏的 mod zip 不再导致 FSM 崩溃——log.Fatal 改为 log.Printf + 优雅跳过
BAYUNZIYUE Jun 21, 2026
752b4b1
修复: Factorio 版本列显示依赖版本而非 metadata 标签——direct-rockets 从 2.0.0.0 修正为 2.…
BAYUNZIYUE Jun 21, 2026
c6ec6c4
修复: dep_op 字段传递到前端——显示 >= 符号标识依赖版本要求
BAYUNZIYUE Jun 21, 2026
1298a6a
修复: 未注册 mod 点击启用时自动注册到 mod-list.json
BAYUNZIYUE Jun 21, 2026
da412b9
修复: 删除 mod 返回明确 JSON 状态而非原始字符串
BAYUNZIYUE Jun 21, 2026
db6922b
修复: 从存档加载模组改用 try/finally 保证状态清理——不再无限转圈
BAYUNZIYUE Jun 21, 2026
42a39e5
功能: 从存档加载模组增加 WebSocket 实时进度条
BAYUNZIYUE Jun 21, 2026
e43d47c
修复: 修正 WebSocket 进度消息字符串格式
BAYUNZIYUE Jun 21, 2026
a9f4105
修复: 确认加载模组后立即关闭弹窗——进度条不被遮挡
BAYUNZIYUE Jun 21, 2026
38bf0a4
修复: ConfirmDialog 点击确认后立即关闭——进度条不被遮挡
BAYUNZIYUE Jun 21, 2026
1b61924
修复: ConfirmDialog 增加 closeImmediately 属性——仅关闭弹窗不等待 Promise
BAYUNZIYUE Jun 21, 2026
24749f0
功能: 加载模组进度条旁添加取消按钮
BAYUNZIYUE Jun 21, 2026
b26dfaf
功能: 存档加载模组增加 Checklist 勾选要安装的模组
BAYUNZIYUE Jun 21, 2026
c497c95
调整: 弹窗宽度适配手机——移动端 11/12 宽度
BAYUNZIYUE Jun 21, 2026
d1eb10a
修复: 文件锁增加 30 秒超时——防止死锁导致页面卡死
BAYUNZIYUE Jun 21, 2026
c21d203
功能: 控制面板 IP/端口记住上次输入值
BAYUNZIYUE Jun 21, 2026
443710d
功能: 上传模组支持多选文件 + 进度条
BAYUNZIYUE Jun 21, 2026
93a92ea
feat: mod sync from save via level.dat0, i18n, DLC grouping, mod list…
Jun 21, 2026
d205fb8
功能: 模组下载改为 5 线程并发 + 进度持久化
BAYUNZIYUE Jun 21, 2026
6670608
功能: 多线程进度条 + 断连恢复——重启/刷新后自动清除已完成进度
BAYUNZIYUE Jun 21, 2026
b898828
功能: 模组页新增常驻删除所有模组按钮
BAYUNZIYUE Jun 21, 2026
ed05ea0
修复: 三个 Mod 管理按钮限制为服务器停止时可用 + 统一红色按钮风格
BAYUNZIYUE Jun 21, 2026
271d372
docs: add ROADMAP.md
Jun 21, 2026
5200922
修复: 401 时自动跳转登录页——不再显示 Could not read username
BAYUNZIYUE Jun 21, 2026
a3e8788
docs: add ROADMAP.md
Jun 21, 2026
924163f
修复: 401 跳转改用 replace + 挂起 Promise——防止后续 reject 干扰跳转
BAYUNZIYUE Jun 21, 2026
24fa7ef
调整: 所有 Mod 的 Factorio 版本统一显示 >= 前缀
BAYUNZIYUE Jun 21, 2026
485e69d
功能: 删除所有模组增加二次确认弹窗
BAYUNZIYUE Jun 21, 2026
056d71b
修复: Worker 进度条改为列表——显示实际下载状态
BAYUNZIYUE Jun 21, 2026
93813b7
功能: Worker 下载列表显示文件大小(来自 Content-Length)
BAYUNZIYUE Jun 21, 2026
0b1ab6a
修复: 页面加载时清除残留进度状态——不再显示旧安装提示
BAYUNZIYUE Jun 22, 2026
454b4d3
修复: 60 秒超时自动清除进度 + 移除 localStorage 持久化
BAYUNZIYUE Jun 22, 2026
da77fc3
修复: Worker 增加 downloading 状态——完成时显示文件大小
BAYUNZIYUE Jun 22, 2026
c5e3f9a
修复: HEAD 请求预取文件大小——Worker 下载中即显示大小
BAYUNZIYUE Jun 22, 2026
a692dcb
调整: 前端下载中也显示文件大小
BAYUNZIYUE Jun 22, 2026
292edde
功能: Mod 列表显示文件大小 + 修复 HEAD 请求无认证
BAYUNZIYUE Jun 22, 2026
4edaa86
功能: Mod 列表每 5 秒自动刷新——文件变动即时反映
BAYUNZIYUE Jun 22, 2026
4d6dc49
调整: 2s 轮询 + 后台标签页跳过刷新
BAYUNZIYUE Jun 22, 2026
4c650ab
优化: Mod 门户列表懒加载——仅在点安装模组标签时才请求 6000+ 列表
BAYUNZIYUE Jun 22, 2026
bd54b8f
优化: 首次点安装模组标签加载门户列表 + TabControl 支持 onActivate
BAYUNZIYUE Jun 22, 2026
58a1c85
功能: 侧边栏新增检查模组更新按钮
BAYUNZIYUE Jun 22, 2026
e25f5c7
优化: 门户列表缓存 1 小时——避免每次都请求 6000+ 模组
BAYUNZIYUE Jun 22, 2026
c137b6b
优化: 后端缓存门户列表 1 小时——避免每次 12MB 传输
BAYUNZIYUE Jun 22, 2026
ae9a757
回退: 恢复门户列表预加载——后端缓存已够快
BAYUNZIYUE Jun 22, 2026
4242595
优化: 加载模组列表时显示脉冲进度条——避免体感卡死
BAYUNZIYUE Jun 22, 2026
cc71269
优化: 加载进度条分段显示——1/3 宽度脉冲避免全宽动画感
BAYUNZIYUE Jun 22, 2026
0c10a40
优化: 移除虚假进度条——加载模组列表仅显示真实文本状态
BAYUNZIYUE Jun 22, 2026
9cf5a39
修复: Factorio 登录状态复用 localStorage——避免每次重查 API 导致登录表单闪现
BAYUNZIYUE Jun 22, 2026
4fd25f4
功能: Worker 增加下载进度条 + 百分比
BAYUNZIYUE Jun 22, 2026
94a8b66
修复: 进度条始终占位——不再因大小信息延迟而跳动
BAYUNZIYUE Jun 22, 2026
9a09bf1
回退: 移除 localStorage 缓存——恢复原始 AddMod 登录检测
BAYUNZIYUE Jun 22, 2026
2f4f6de
修复: 共享 Factorio 登录状态到父组件——AddMod 和 LoadMods 不再各自独立查询
BAYUNZIYUE Jun 22, 2026
ef6f7e7
修复: 认证结果返回前不渲染标签——消除登录表单闪现
BAYUNZIYUE Jun 23, 2026
2df36d0
修复: 加载模组列表文本统一——去掉 downloadComplete 避免卡住错觉
BAYUNZIYUE Jun 23, 2026
f35dedd
重构: 加载模组列表独立横幅——加载中三标签灰色禁用,完成后恢复
BAYUNZIYUE Jun 23, 2026
51ef2c1
修复: Updater API 兼容 stable 标签——2.1.7 版本已识别
BAYUNZIYUE Jun 23, 2026
315b99f
功能: 服务器设置添加中文说明切换——静态翻译 27 个 Factorio 设置项
BAYUNZIYUE Jun 23, 2026
068720e
文档: 基于 Factorio Wiki 重写服务器设置说明
BAYUNZIYUE Jun 23, 2026
d56e36d
修复: Factorio 2.1 兼容性判断 & 模组版本显示 & 崩溃修复
BAYUNZIYUE Jun 23, 2026
fc3f979
修复: Portal 兼容性改用 GEC & DepOp 不再硬编码
BAYUNZIYUE Jun 23, 2026
3a4203b
修复: 门户搜不到 mod 时返回 404 而非 500 报错
BAYUNZIYUE Jun 23, 2026
482a874
合并: Joey develop 分支 — mod_sync + i18n + DLC 分组
BAYUNZIYUE Jun 23, 2026
4a031d3
修复: i18next 中文翻译 — common 命名空间 + 语言切换按钮
BAYUNZIYUE Jun 23, 2026
c257bf5
修复: 侧边栏恢复服务器版本链接
BAYUNZIYUE Jun 23, 2026
f701ec7
修复: 注册全部 10 个 i18n 命名空间 + 创建独立翻译文件
BAYUNZIYUE Jun 24, 2026
88bfc0b
修复: 恢复检查模组更新按钮 + 清理 LoadMods 死代码
BAYUNZIYUE Jun 24, 2026
b222041
翻译: 补全 9 个命名空间全部翻译键 (0 missing)
BAYUNZIYUE Jun 24, 2026
7a9985d
修复: 模组页黑屏 — 取消每 2 秒 153 次 portal API 请求
BAYUNZIYUE Jun 24, 2026
848d983
修复: React #31 崩溃 — axios 拦截器 Object 渲染 + 404 静默
BAYUNZIYUE Jun 24, 2026
6a3725d
文档: 遵循上游规范 — 更新 CHANGELOG.md + ROADMAP.md
BAYUNZIYUE Jun 24, 2026
357d8e9
修复: LoadMods 使用父组件共享的 Factorio 认证状态
BAYUNZIYUE Jun 24, 2026
c9225b5
文档: CHANGELOG 标注共享认证态退化修复及原因
BAYUNZIYUE Jun 24, 2026
be455d5
翻译: ModList 表头 + LoadMods 全部硬编码字符串中文化
BAYUNZIYUE Jun 24, 2026
7ca86d7
重构: 回退 ModList/LoadMods 到我们的版本 + 逐条合并 Joey 功能
BAYUNZIYUE Jun 24, 2026
10c85b8
备忘: 游戏设置页合并到控制面板
BAYUNZIYUE Jun 24, 2026
9f05b56
重构: 控制台+日志合并 — 终端页面替换两个独立页面
BAYUNZIYUE Jun 24, 2026
4a9376d
功能: 终端页关服显示历史日志 + 开服实时流 + 指令输入
BAYUNZIYUE Jun 24, 2026
a185c91
功能: 终端字体大小 + 换行模式 — localStorage 记忆
BAYUNZIYUE Jun 24, 2026
037fb21
功能: 终端宽度调节 + 移动端优化 + 全页面放宽
BAYUNZIYUE Jun 24, 2026
5c0f871
修复: 终端宽度改用 inline style — Tailwind class 不生效
BAYUNZIYUE Jun 24, 2026
e0b7ae6
修复: 解耦版本显示与兼容性判断 + 依赖显示
BAYUNZIYUE Jun 24, 2026
d94aae4
调整: 模组列表列顺序 — 兼容性+启用移到名称左边
BAYUNZIYUE Jun 24, 2026
3bacf71
功能: 模组列表排序 + 列显隐 + 设置记忆
BAYUNZIYUE Jun 24, 2026
6af7779
样式: 模组列表列分割线 + 行分割线
BAYUNZIYUE Jun 24, 2026
127dcdb
功能: 列宽拖拽调整 + 分割线加深 (resizable columns)
BAYUNZIYUE Jun 24, 2026
93d6a22
修复: 排序导致重复 — 稳定排序 + 唯一 React key
BAYUNZIYUE Jun 24, 2026
a027217
修复: LoadMods 回退 — 恢复 mod_sync 选择性同步 + 共享认证
BAYUNZIYUE Jun 24, 2026
73326a9
功能: 模组操作互斥锁 — 防止冲突操作
BAYUNZIYUE Jun 24, 2026
c465db5
功能: mod 同步取消 + ModList 表格重写 + EventLog + 游戏设置合并
BAYUNZIYUE Jul 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,56 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [0.12.0] - TBD

### Added
- Server version manager: download, update, and downgrade Factorio server from UI - Thanks to @BAYUNZIYUE
- Full version list from updater.factorio.com (stable/experimental)
- Async install with WebSocket real-time progress
- Mod sync from save: read mod list from level.dat0 with exact versions - Thanks to @joey00797-cell
- Selective sync with checkboxes
- WebSocket download progress for each mod
- DLC mods (elevated-rails, quality, space-age) detected from mod-list.json
- Grouped in UI with single toggle - Thanks to @joey00797-cell
- i18n internationalization via i18next framework with zh-CN translations - Thanks to @joey00797-cell, @BAYUNZIYUE
- Language switcher dialog (EN / RU / 中文)
- 5-thread concurrent mod downloading with per-worker progress bars
- Upload mod multi-file support with progress
- Mod list auto-refresh every 2s with background-tab skip
- TabControl onActivate support for lazy portal list loading
- Server settings Chinese descriptions toggle (27 items based on Factorio Wiki)
- File size display in mod list
- IP/port memory in Controls page (localStorage)
- Cache mod portal list for 1 hour (~60x speedup)
- Token-based Factorio authentication support

### Changed
- Factorio version display uniformly prefixed with `>=`
- Mod portal releases compatibility now uses Factorio-aware GEC (same major.minor required)
- DepOp no longer hardcoded to `>=` — reflects actual dependency operator
- Portal "Mod not found" returns 404 JSON instead of 500 error
- File lock timeout increased to 30s to prevent deadlocks
- Docker build cache for go mod download and npm install

### Fixed
- Factorio 2.1 compatibility: mods with different minor version correctly marked incompatible
- save.go: Factorio 2.0 save header parsing (readFromV2, 192-line complete rewrite)
- mod_modInfo.go: base dependency version override (old `base >= 0.18` no longer overwrites info.json factorio_version: 2.0)
- mod_modInfo.go: dependency parsing bounds check (prevents crash on malformed deps)
- Corrupted mod zip files gracefully skipped instead of crashing FSM
- 401 auto-redirect to login page (replace instead of push state)
- React #31 crash: axios interceptor no longer passes Object to Flash component
- Mod page black screen: portal API calls limited to initial mount (was 153 calls every 2s)
- Auth gate prevents login form flash (authChecked before tab render)
- Shared Factorio auth state restored across all mod tabs (AddMod + LoadMods) —
parent component checks portal login once, children receive via props;
merged Joey's LoadMods rewrite regressed this with local state — fixed via prop drilling
- Updater API stable tag compatibility for 2.1.7 detection
- save.go: fmt.Errorf escaped percent signs fixed (20+ instances)

### Removed
- removeAll on Docker volume replaced with proper mod directory clear - Thanks to @joey00797-cell

## [0.11.0] - TBD
### Changed
- Configuration environment variables are now uppercase and prefixed with FSM
Expand Down
80 changes: 80 additions & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# FSM Roadmap

## ✅ Done

- [x] Fix mod folder cleanup on Docker volume
- [x] Fix save file parsing for Factorio 2.0
- [x] Read all mods with exact versions directly from save file
- [x] New endpoint to read mods from save without downloading
- [x] Selective mod sync with checkboxes (select/deselect all)
- [x] Real-time download progress via WebSocket
- [x] DLC mods auto-detected and grouped in UI with single toggle
- [x] DLC mods visible in installed mods list with enable/disable
- [x] Server start blocked while mod sync is in progress
- [x] i18n support (EN/RU/zh-CN)
- [x] Token-based authentication on factorio.com
- [x] Server version manager (download/update/downgrade Factorio from UI)
- [x] 5-thread concurrent mod downloading with progress bars
- [x] Upload mod multi-file support
- [x] Mod portal list caching (1 hour)
- [x] Factorio 2.1 compatibility (GEC version checking)
- [x] Factorio 2.0 save header parser (readFromV2)
- [x] Server settings Chinese descriptions (Factorio Wiki based)
- [x] Auth gate preventing login form flash
- [x] 401 auto-redirect to login page

## 📂 Worktree 隔离开发

```
主目录: /workspace/projects/factorio-server-manager-joey (当前功能)
参考目录: /workspace/projects/factorio-server-manager-develop (joey/develop)

新功能:
git worktree add ../factorio-server-manager-<slug> -b feat/<slug>
cd ../factorio-server-manager-<slug>
# 开发、构建、测试...
# 完成后: git push && git worktree remove ../factorio-server-manager-<slug>
```

## 🧪 测试流程(每次改动必做)

修改代码后,必须闭环验证以下步骤:

1. **构建**: `npm run build && go build`
2. **部署**: `cp -r app/* /home/game/fsm/app/ && cp factorio-server-manager /home/game/fsm/`
3. **重启**: `kill $(pgrep factorio-server); cd /home/game/fsm && setsid ./factorio-server-manager ...`
4. **登录**: Playwright 打开 `/login` → 输入凭据 → 确认跳转到主页
5. **功能页**: 导航到改动的页面,等待 15 秒
6. **检查**: 控制台 0 个 JS Error,页面正常渲染
7. **交互**: 点击/拖拽核心功能,确认不崩溃

> 每次提交前跑一遍,不允许「改完就提交」。

## 🚧 Planned

### Mods
- [ ] Auto-resolve mod dependencies when creating a new save
- [ ] Portal link icon next to each mod in the list
- [ ] Row highlight on hover in mod list
- [ ] Batch update all compatible mods for current server version

### Authentication
- [ ] Show logged-in username on mod portal tab
- [ ] Refresh button for saved credentials
- [ ] Proper FSM login (registration form on first launch)

### Server
- [ ] Controls page info panel — merge Game Settings into Controls dashboard:
- Remove standalone `/game-settings` page (mostly empty config.ini view)
- Add read-only info section below start/stop controls:
- Factorio version + base mod version
- Data paths (read-data / write-data)
- Installed / compatible / incompatible mod counts
- Save file count + last modified
- (future) uptime, player count
- [ ] Server Status tab refactor:
- Autostart checkbox
- Factorio version dropdown with auto-download
- Server name field
- [ ] Multi-server support
- [ ] Dual logs — Factorio server logs + FSM manager logs
Empty file added decompiled_script.lua
Empty file.
22 changes: 14 additions & 8 deletions docker/Dockerfile-build
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
FROM alpine:latest as build

RUN apk add --no-cache git make musl-dev go nodejs npm zip mingw-w64-gcc

ENV GOROOT /usr/lib/go
ENV GOPATH /go
ENV PATH /go/bin:$PATH
ENV FACTORIO_ROOT /go/src/factorio-server-manager

COPY docker/build-release.sh /usr/local/bin/build-release.sh
COPY ./ $FACTORIO_ROOT

RUN mkdir -p ${GOPATH}/bin
RUN chmod u+x /usr/local/bin/build-release.sh

WORKDIR $FACTORIO_ROOT

# Кешируем Go зависимости отдельно
COPY src/go.mod src/go.sum ./src/
RUN cd src && go mod download

# Кешируем npm зависимости отдельно
COPY package.json package-lock.json ./
RUN npm install

# Копируем остальное
COPY ./ ./

COPY docker/build-release.sh /usr/local/bin/build-release.sh
RUN chmod u+x /usr/local/bin/build-release.sh

VOLUME /build
VOLUME $FACTORIO_ROOT

RUN ["/usr/local/bin/build-release.sh"]

FROM scratch as output
Expand Down
Empty file modified docker/build-release.sh
100755 → 100644
Empty file.
Empty file modified docker/build.sh
100755 → 100644
Empty file.
Empty file modified docker/entrypoint.sh
100755 → 100644
Empty file.
143 changes: 143 additions & 0 deletions docs/add-language-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# 添加新语言指南

FSM 前端基于 `react-i18next`,添加新语言只需创建翻译文件并注册即可。

## 快速上手(以日语 ja 为例)

### 第 1 步:创建翻译文件

```bash
mkdir -p ui/locales/ja
```

复制英文文件作为模板:

```bash
cp ui/locales/en/*.json ui/locales/ja/
```

### 第 2 步:翻译

逐个编辑 `ui/locales/ja/` 下的 9 个 JSON 文件,**只改 value,不改 key**。

| 文件 | 示例 key | 英文 | 日文翻译 |
|---|---|---|---|
| `common.json` | `save` | Save | 保存 |
| `common.json` | `cancel` | Cancel | キャンセル |
| `common.json` | `confirm` | Confirm | 確認 |
| `controls.json` | `startServer` | Start Server | サーバー起動 |
| `controls.json` | `RUNNING` | Running | 実行中 |
| `layout.json` | `appTitle` | Factorio Server Manager | Factorio サーバーマネージャー |

### 第 3 步:注册语言

编辑 `ui/i18n.js`,在两个地方添加 ja:

**位置 1 — import 翻译文件:**

```js
// 在 zh-CN imports 后面添加
import jaCommon from './locales/ja/common.json';
import jaLayout from './locales/ja/layout.json';
import jaControls from './locales/ja/controls.json';
import jaMods from './locales/ja/mods.json';
import jaSaves from './locales/ja/saves.json';
import jaServerSettings from './locales/ja/serverSettings.json';
import jaLogs from './locales/ja/logs.json';
import jaConsole from './locales/ja/console.json';
import jaUserManagement from './locales/ja/userManagement.json';
```

**位置 2 — 添加到 resources 对象:**

```js
const resources = {
en: { /* 已有 */ },
'zh-CN': { /* 已有 */ },
ja: {
common: jaCommon,
layout: jaLayout,
controls: jaControls,
mods: jaMods,
saves: jaSaves,
serverSettings: jaServerSettings,
logs: jaLogs,
console: jaConsole,
userManagement: jaUserManagement,
},
};
```

### 第 4 步:添加到语言切换器

编辑 `ui/App/components/Layout.jsx`,在 `<select>` 中添加:

```jsx
<option value="ja">日本語</option>
```

### 第 5 步:验证

```bash
npm run build
```

构建通过即完成。浏览器语言设为日语时自动显示日文,也可通过侧边栏切换器手动选择。

---

## 翻译文件结构

```
ui/locales/
├── en/ ← 英文(fallback,必须保持完整)
│ ├── common.json ← 通用词汇(保存/取消/确认/删除...)
│ ├── layout.json ← 导航栏/侧边栏/页面标题
│ ├── controls.json ← 服务器启停控制面板
│ ├── mods.json ← Mod 管理全部子页面
│ ├── saves.json ← 存档管理全部子页面
│ ├── serverSettings.json ← 服务器+游戏设置
│ ├── logs.json ← 日志页面
│ ├── console.json ← RCON 控制台
│ └── userManagement.json ← 用户管理/登录
├── zh-CN/ ← 简体中文(已完成)
└── ja/ ← 日语(按本指南添加)
```

## 翻译规则

1. **只改 value,不改 key。** key 是代码引用的标识,改了会导致显示空白。
2. **保持扁平结构。** 所有 key 在 JSON 顶层,不要嵌套。
3. **不要修改 HTML。** 翻译值里不要放 `<div>`、`<span>` 等标签。
4. **大写 key 是状态值**(如 `RUNNING`、`STOPPED`、`UNKNOWN`),翻译时用对应的状态词。
5. **en/ 是权威源。** 如果某个 key 在目标语言中缺失,i18next 会自动回退到英文,不会报错。

## 自动语言检测

`i18next-browser-languagedetector` 按以下优先级检测:

1. `localStorage` 中 `fsm_lang` 的值(用户手动切换后记住)
2. 浏览器 `navigator.language`

例如浏览器语言是 `ja` → 自动加载日语;无匹配 → 回退英文。

## 常见 BCP 47 语言标签

| 语言 | 标签 | 写入 `i18n.js` |
|---|---|---|
| 日语 | `ja` | `ja` |
| 韩语 | `ko` | `ko` |
| 繁体中文 | `zh-TW` | `zh-TW` |
| 德语 | `de` | `de` |
| 法语 | `fr` | `fr` |
| 俄语 | `ru` | `ru` |
| 西班牙语 | `es` | `es` |
| 葡萄牙语 | `pt` | `pt` |
| 波兰语 | `pl` | `pl` |

## 注意事项

- **不要删除或修改 `en/` 下的文件。** 英文是 fallback 语言,必须保持完整。
- **新语言的 JSON 文件名必须与 `en/` 完全一致。**
- 如果不想翻译所有 key,可以先复制英文再逐条翻译,未翻译的 key 会自动回退英文。
- Factorio 社区有大量活跃的非英语玩家,欢迎贡献翻译 PR。
Loading