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