Skip to content

Instantly share code, notes, and snippets.

@imba-tjd
Last active January 26, 2023 13:53
Show Gist options
  • Save imba-tjd/dfd099b1047e2e9524bf0c563bad031b to your computer and use it in GitHub Desktop.
Save imba-tjd/dfd099b1047e2e9524bf0c563bad031b to your computer and use it in GitHub Desktop.
// KP Backuper:帮助解决卡琳典狱长在非最低难度下强制覆盖自动保存的特性。
// 放到与nw.exe同一目录下。运行后每隔一分钟会检测存档有没有发生变化,如果变了,就备份到www/save_bak目录下。
// 并发安全性:读取时会加读锁,因此不会读到一半游戏自动保存导致读取内容错误,副作用是此次游戏的自动保存会不生效(静默失败);但本游戏保存很频繁,因此无影响。对于游戏保存到一半时本程序触发读,本程序会过一秒钟重试。
// 编译:C:\tools\bflat-7.0.1-windows-x64\bflat.exe build KPBackuper.cs -Os --no-globalization --no-reflection --no-stacktrace-data && upx --lzma KPBackuper.exe
using System;
using System.IO;
using System.Threading;
using System.Runtime.InteropServices;
[DllImport("user32")]
static extern void MessageBox(nint hWnd, string text, string caption, uint type);
try
{
Console.Title = "KP Backuper";
Environment.CurrentDirectory += "/www";
if (!Directory.Exists("save_bak"))
Directory.CreateDirectory("save_bak");
Console.Write("输入存档编号,必须已存在:");
int num = int.Parse(Console.ReadLine());
string filename = "save/file" + num + ".rpgsave";
byte[] data = File.ReadAllBytes(filename);
int retry_count = 0;
while (true)
{
byte[] new_data;
try
{
new_data = File.ReadAllBytes(filename);
retry_count = 0;
}
catch (IOException e)
{
if (e.HResult == -2147024864 && retry_count < 3)
{
Thread.Sleep(1000);
retry_count++;
continue;
}
else
throw;
}
// 如果长度不同,则需要备份。如果长度相同但内容不同,则需要备份。无论是否备份都要睡眠。
if (data.Length == new_data.Length)
{
for (int i = 0; i < data.Length; i++)
if (data[i] != new_data[i])
goto backup;
goto sleep;
}
backup:
DateTime dt = DateTime.Now;
Console.WriteLine(dt.ToString("t") + " 检测到变化");
string bak_filename = "save_bak/file" + num + dt.ToString("-yyyy-MM-dd-HH-mm") + ".rpgsave";
File.WriteAllBytes(bak_filename, new_data);
data = new_data;
sleep:
Thread.Sleep(1000 * 61);
}
}
catch (Exception e)
{
Console.WriteLine(DateTime.Now + " 发生了错误,程序即将退出");
MessageBox(0, e.ToString(), "KP Backuper Error", 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment