星露谷联机 bug “这个角色属于另一位玩家” 解决方案
0. 发现问题
前几天联机的时候发现了一个 bug : 联机后的第二天再次联机时,无法选择之前创建的角色,会弹出 “这个角色属于另一位玩家” 的提示(当时是拍屏,就不放图了)
1. 解决方案
打开目录 C:\Users\你的用户名\AppData\Roaming\StardewValley\Saves
,打开你的存档所在的文件夹,找到那个和文件夹名字一样的文件(不是 SaveGameInfo
,也不以 _old
结尾),编辑它(可以使用 VS Code ,也可以用记事本)。
按 Ctrl+F
,输入 userID
,找到类似这样的内容:
将这一段整体替换成 <userID />
。
然后寻找下一处,把所有这种带数字的都替换掉。替换完全部后,保存,重开游戏,解决。
这种解决方案并不稳定,似乎有概率复现,更强大的解决方案见下一小节:
2. 终极方案
写了个程序自动解决这个问题:
源码解析
获取当前用户的工作路径:
auto home_path = std::string{std::getenv("USERPROFILE")};
扫描存档文件夹的所有存档:
auto reg_find = std::regex{R"(^(?!SaveGameInfo)(?!.*(_old|\.vdf|\.bak)$).+$)"};
auto path = std::format(R"({}\AppData\Roaming\StardewValley\Saves)", home_path);
auto saves = std::vector<fs::path>{};
for (auto& dir_entry : fs::recursive_directory_iterator(path)) {
if (!dir_entry.is_regular_file()) {
continue;
}
if (!regex_match(dir_entry.path().filename().string(), reg_find)) {
continue;
}
saves.emplace_back(dir_entry.path());
}
修复存档:
for (auto&& path : saves) {
auto reg_fix = std::regex{R"(<userID>\d*</userID>)"};
auto bak_path = format("{}.bak", path.string());
fs::copy_file(path, bak_path, fs::copy_options::overwrite_existing);
using is_it = std::istreambuf_iterator<char>;
using os_it = std::ostreambuf_iterator<char>;
auto fin = std::ifstream{bak_path};
auto beg = is_it{fin};
auto end = is_it{};
auto ctx = std::string{beg, end};
auto fout = std::ofstream{path};
auto it = os_it{fout};
std::regex_replace(it, ctx.begin(), ctx.end(), reg_fix, "<userID />");
}
在这里找到全部的源代码: Github Repo