铝箔梦中饥荒没暂停导致烧家存档覆盖气急败坏而写
  • TypeScript 57.7%
  • HTML 34.9%
  • Shell 7.4%
Find a file
2025-07-10 15:02:31 +08:00
.local/share/nautilus/scripts init 2025-06-29 18:45:15 +08:00
.gitignore init 2025-06-29 18:45:15 +08:00
clamp.ts init 2025-06-29 18:45:15 +08:00
commit_example.sh init 2025-06-29 18:45:15 +08:00
config_example.json init 2025-06-29 18:45:15 +08:00
deno.json init 2025-06-29 18:45:15 +08:00
gameSaveWatcher.service init 2025-06-29 18:45:15 +08:00
hashList.ts init 2025-06-29 18:45:15 +08:00
index.html 沟槽的怎么有 rmvxace 把存档文件和 game.exe 混一起啊 2025-07-10 15:01:11 +08:00
main.ts 沟槽的怎么有 rmvxace 把存档文件和 game.exe 混一起啊 2025-07-10 15:01:11 +08:00
README.md typo 2025-07-10 15:02:31 +08:00

存档监视器

  • 铝箔梦中饥荒没暂停导致烧家存档覆盖气急败坏而写

存档监视器是一个基于 Deno 的无脑自动 commit 的小工具。

结构

main.ts

根据配置文件,盯着存档文件夹,一旦有更改则调用 commit.sh

commit.sh

在当前目录的上级目录创建两个 git 裸仓库(bare repository),一个仅存储每日第一个存档,一个以今日日期命名且仅保留最新的两个。

这样,无论是恶意玩家在很久之前埋的雷爆发还是进来个黑山大叔扔珍珠,你都不用担心造成过大损失。

为什么不使用一个 git 仓库,每天开一个分支然后删掉旧分支?

使用一个 git 仓库的两个分支确实可以节约存储。

但是其缺点是,删除旧分支的时候,必须额外执行 git gc,而这个操作必须遍历所有对象而非被删除分支的对象。这使得超大存档的每天第一次提交(顺便删除前天的分支)时都会带来较大的性能开销。

  • 如果可以删除分支时自动删除对应 object 就好了,但可惜我不会。

食用方法

(记得先安装 Deno

配置监视规则

config_example.json 复制一份,重命名为 config.json

编辑 config.json

  • commitScript: commit.sh 的实际位置。
  • watchList: 一个json数组其内容可以是
    • 字符串,表示存档文件夹的位置
    • 一个 json 对象,其中:
      • path 表示存档文件夹的位置;
      • delay 表示当游戏完成存档后开始提交的延迟
        • 如果延迟过长,当你在延迟内触发两次游戏存档,那么这两次会被合并,实际上会在第二次存档完成后延迟秒后开始 commit。
        • 如果延迟过短,那么可能游戏存档到一半就开始提交导致得到损坏的存档。
      • excludeRegexps 表示忽略的文件正则表达式,是一个字符串数组。
        • 当文件被修改时,如果文件名命中任一表达式则会被忽略
      • includeRegexps 表示需要追踪的文件正则表达式。
        • 当文件被修改时,如果 includeRegexps 非空,且文件名没有命中任一表达式,则会被忽略

配置提交规则

commit_example.sh 复制一份,重命名为 commit.sh(或其他你在前文 json commitScript 项中填写的内容)

commit_example.sh 是一个示例脚本使用git无脑保存但好歹能凑合用。如果你有更多需求如保存更多天/全都保存/每小时不存超过多少条/自动push到远程仓库/使用孤独摇滚文件系统自动打快照,请自行写一个(如果能顺便给我开个 pr 就更好了)。

  • 提示:
    • 这个脚本被调用时,其“当前目录”(cwd)会是存档文件夹,而第一个参数也是存档文件夹的绝对路径。
    • 为防止递归,存档文件夹下 .git 开头的文件被修改不会触发,但尽管如此,我依旧建议把 git 仓库扔到上层以降低误删可能性(万一你在玩米塔.jpg
    • 如果你准备将存档文件夹传到远程仓库github 等),强烈建议对上传的文件夹目录做验证,并仅存到私有仓库(一方面很多游戏的存档内都会有一些私有信息,另一方面沙盒/虚拟机内的恶意软件也可能借此尝试将你的密码文件上传)。

额外的安装

systemd

如果你想开机自启以防开游戏时忘记:

# 在当前文件夹下:
systemctl --user link ./gameSaveWatcher.service
systemctl --user enable --now gameSaveWatcher.service 
  • 不必担心性能——watch 用的是 inotify 不是轮询。
  • 一旦启动,修改配置文件将不再有效(除非修改后 systemd restart service且修改的内容会因为其他 api 调用而被重新覆盖掉。

GNOME

如果你想右键存档文件夹-脚本-标记为存档文件夹(自动调用 http api 监视这个文件夹而无需手动在网页里添加该文件):

ln -s "$(realpath .local/share/nautilus/scripts/mark\ as\ save\ dir.ts)" ~/.local/share/nautilus/scripts/

动态管理存档文件夹

当存档监视器运行时,修改配置文件不会被读取。

于此对应的,你可以使用一个 http api 来管理存档文件夹(同时自动修改配置文件)。

  • 为防止沙盒/虚拟机提权,不能改 commitScript。

接口

  • GET /listListeners
    • 返回 watchList
  • POST /addListener
    • post body 需要一个 JSON是符合 watchList 的 JSON 对象。
  • POST removeListener
    • post body 同上,但只需要 path。