diff --git a/.gitignore b/.gitignore index e215ae4..3dcd1e4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ research/ .playwright-mcp/ cache/ -star-raid/data/ +star-raid/.env diff --git a/AGENTS.md b/AGENTS.md index 1a7a0bc..1336892 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -18,10 +18,11 @@ cd star-raid # 语法检查(每次改完 JS 必须跑;server/ 也要查) for f in js/*.js server/*.js; do node --check "$f" || echo "FAIL $f"; done -# 启动完整版(游戏+后端,Node≥22.5) +# 启动完整版(游戏+后端,Node≥22.5,自动读取 star-raid/.env) node server/server.js # 或 npm start;访问 http://localhost:8643 # 注意:8643 现由 node server 占用;旧 python http.server 试玩方式已废弃 -# 数据库:star-raid/data/starraid.db(git 忽略,删除重启自动重建空库) +# 数据库:默认 ~/.starraid/starraid.db(源码树之外,.env 的 DATA_DIR 可改) +# 警告:WAL 模式,备份/迁移库文件前必须停服或 wal_checkpoint,直接拷主库会丢数据 # Git(仓库根 = 工作区根目录,游戏在子目录) git add -A && git commit -m "提交信息" @@ -41,11 +42,12 @@ star-raid/ ├── css/style.css # 全部样式(像素风 UI 变量配色) ├── server/ # 后端(零依赖 node:http+node:sqlite) │ ├── server.js # 入口:静态白名单+/api路由+安全头 +│ ├── env.js # .env 加载(启动最先加载,环境变量优先) │ ├── db.js # SQLite schema(users/sessions/user_stats/codex_unlocks/runs) │ ├── auth.js # scrypt密码哈希+服务端session │ ├── api.js # API处理器;CODEX_KEYS 白名单(新增装备必须同步!) │ └── util.js # body解析/限流/输入校验 -├── data/ # SQLite 数据库(git 忽略) +├── .env # 本机配置(不进 git;模板 .env.example) ├── js/ │ ├── config.js # BAL 平衡参数、常量 │ ├── data.js # WEAPONS/SUBS/DRONES 装备数据表 diff --git a/star-raid/.env.example b/star-raid/.env.example new file mode 100644 index 0000000..4371c18 --- /dev/null +++ b/star-raid/.env.example @@ -0,0 +1,9 @@ +# Star Raid 服务端配置模板 —— 复制为 .env 后按机器修改 +# 监听端口 +PORT=8643 +# 监听地址 +HOST=0.0.0.0 +# 数据库目录(绝对路径,勿放源码目录内;支持 ~ 开头) +DATA_DIR=~/.starraid +# HTTPS 部署时置 1(Cookie 加 Secure) +COOKIE_SECURE=0 diff --git a/star-raid/DEPLOY.md b/star-raid/DEPLOY.md index 343e7c7..e6cf426 100644 --- a/star-raid/DEPLOY.md +++ b/star-raid/DEPLOY.md @@ -3,23 +3,24 @@ ## 运行要求 - **Node.js ≥ 22.5**(使用内置 `node:sqlite`,零 npm 依赖,无需 `npm install`) -- SQLite 数据库文件自动创建于 `star-raid/data/starraid.db`(已在 .gitignore) +- 配置:`star-raid/.env`(**不进 git**,模板见 `.env.example`,复制后按机器修改);启动时自动加载,真实环境变量优先于 .env +- 数据库文件默认在 **`~/.starraid/starraid.db`(源码目录之外)**,由 `DATA_DIR` 配置 ## 启动 ```bash cd star-raid -npm start # = node server/server.js -# 或指定环境变量 -PORT=8643 HOST=0.0.0.0 node server/server.js +npm start # = node server/server.js(自动读取 .env) +# 或环境变量临时覆盖(优先级高于 .env) +PORT=9000 node server/server.js ``` -| 环境变量 | 默认 | 说明 | +| 配置项(.env / 环境变量) | 默认 | 说明 | |---|---|---| | `PORT` | `8643` | 监听端口 | | `HOST` | `0.0.0.0` | 监听地址 | +| `DATA_DIR` | `~/.starraid` | **数据库目录(勿放源码树内)**,支持 `~` 开头 | | `COOKIE_SECURE` | 空 | **HTTPS 部署时必须设为 `1`**(Cookie 加 Secure) | -| `DATA_DIR` | `star-raid/data` | 数据库目录 | ## 公网部署(nginx + HTTPS 推荐) @@ -57,5 +58,6 @@ server { ## 数据维护 -- 备份:拷贝 `data/starraid.db`(WAL 模式,建议先 `PRAGMA wal_checkpoint` 或直接停服拷贝) -- 重置排行榜:停服后删除 `data/` 下文件,重启自动重建空库 +- 数据库位置:`DATA_DIR`(默认 `~/.starraid`)下的 `starraid.db` + `-wal`/`-shm` +- **WAL 模式警告:备份/迁移前必须先合并日志**——停服后拷贝,或执行 `PRAGMA wal_checkpoint(TRUNCATE);` 再拷。直接拷主库文件会丢数据(2026-08-06 已踩坑,测试数据全灭) +- 重置排行榜:停服后删除 `DATA_DIR` 下文件,重启自动重建空库 diff --git a/star-raid/server/db.js b/star-raid/server/db.js index db64505..89e24a0 100644 --- a/star-raid/server/db.js +++ b/star-raid/server/db.js @@ -3,8 +3,10 @@ const { DatabaseSync } = require("node:sqlite"); const path = require("node:path"); const fs = require("node:fs"); +const { expandHome } = require("./env"); -const DATA_DIR = process.env.DATA_DIR || path.join(__dirname, "..", "data"); +/* 数据目录不放源码树:默认 ~/.starraid,可用 DATA_DIR 环境变量 / .env 覆盖 */ +const DATA_DIR = expandHome(process.env.DATA_DIR || path.join(require("node:os").homedir(), ".starraid")); fs.mkdirSync(DATA_DIR, { recursive: true }); const db = new DatabaseSync(path.join(DATA_DIR, "starraid.db")); diff --git a/star-raid/server/env.js b/star-raid/server/env.js new file mode 100644 index 0000000..fda8cef --- /dev/null +++ b/star-raid/server/env.js @@ -0,0 +1,32 @@ +"use strict"; +/* ================= .env 配置加载(零依赖) ================= + 启动时最先加载:读取 star-raid/.env,注入 process.env。 + 约定:真实环境变量优先(已存在的不覆盖),.env 仅作默认。 */ +const fs = require("node:fs"); +const path = require("node:path"); + +const ENV_PATH = path.join(__dirname, "..", ".env"); +if (fs.existsSync(ENV_PATH)) { + for (const line of fs.readFileSync(ENV_PATH, "utf8").split(/\r?\n/)) { + const s = line.trim(); + if (!s || s.startsWith("#")) continue; + const i = s.indexOf("="); + if (i <= 0) continue; + const key = s.slice(0, i).trim(); + let val = s.slice(i + 1).trim(); + // 去掉成对引号 + if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) + val = val.slice(1, -1); + if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(key) && process.env[key] === undefined) + process.env[key] = val; + } +} + +/* 路径展开:支持 ~ 开头 */ +function expandHome(p) { + if (p === "~") return require("node:os").homedir(); + if (p && p.startsWith("~/")) return require("node:os").homedir() + p.slice(1); + return p; +} + +module.exports = { expandHome }; diff --git a/star-raid/server/server.js b/star-raid/server/server.js index c33f1a7..ad76231 100644 --- a/star-raid/server/server.js +++ b/star-raid/server/server.js @@ -2,6 +2,7 @@ /* ================= Star Raid 服务端入口 ================= 零依赖:node:http + node:sqlite。静态资源白名单 + /api 路由 + 安全头 */ const http = require("node:http"); +require("./env"); // 必须先于 db 加载:数据库目录等配置来自 .env const fs = require("node:fs"); const path = require("node:path"); const db = require("./db");