最近在和室友联机《饥荒》,在本地开房还是不方便,所以在阿里云上部署了服务器。中间踩了很多的坑。由于这个游戏也是处于过气阶段,新的资料比较少,所以在这里记录一下。
旧mod兼容问题
饥荒作为我们的童年回忆已经是一个过气的老游戏了,当前很多mod作者都弃坑不再维护,像Smarter Crock Pot这种经典mod上次更新还在2015年(居然已经11年过去了),现在实际上根本用不了却还处于“最多订阅”第一页,社区热度下降可见一斑。总之游玩的时候需要先看看是否兼容。
我目前试出来的不兼容mod:
- Smarter Crock Pot 使用后所有人都做不了饭。
- Fish Farm 到第二天要生成鱼或蜂蜜的时候导致闪退
- Extra Equip Slot 不能使用
- Restart 好像不能使用
- Food Values - Item Tooltips (Server and Client) 只能服务器端开启,客户端无法使用
- 实际上疑似所有客户端 Food Values - Item Tooltips 类mod都不能用,比如 Advanced Tooltips
- 高效的砍树&采矿 - multiple drops 采到冰的时候会闪退
我整理的当前可用的mod:
服务器端mod合集(最后那几个人物mod自用,其他mod建议全都开启):https://steamcommunity.com/sharedfiles/filedetails/?id=3638235981
客户端mod合集:https://steamcommunity.com/sharedfiles/filedetails/?id=3638251164
在云服务器开服
主要是根据:https://zhuanlan.zhihu.com/p/625645476 这个教程进行的,感谢作者。
注意千万不要选择不生成洞穴!后面要想加入非常麻烦!具体参见后文
教程写得很好,有一点小笔误都是可以自己看出来的,比如cd /dontstarvetogether_dedicated_server/mods这里其实是cd ~/dontstarvetogether_dedicated_server/mods
不过教程中说需要开放以下端口来保证正常通信# steam端口,TCP+UDP协议
~/.klei/DoNotStarveTogether/Cluster_1/Caves/server.ini 中的 master_server_port、authentication_port
这个文件中初始并没有这两个变量,参考另一个教程发现这个.ini文件中需要再加上STEAM字段,完整内容如下:
|
Master/modoverrides.lua及Caves/modoverrides.lua是放mod配置的地方,建议第一步生成世界的时候就设置好,有GUI毕竟方便一些。后面要加mod或改配置就在这里。记得加mod还要在 dontstarvetogether_dedicated_server/mods/dedicated_server_mods_setup.lua 中加入,并且需要确保mod正常安装
内地服务器被墙 & 服务器可用区切换
一开始本来想按照最便宜的来,在阿里云上选了华北地区创建实例。结果笑死,根本连不上steam和klei服务器。(其实第一次尝试能成功下载并创建房间加入,但第二天就完全创建不了,Log中显示 Timed Out. 用到的指令:ping login.kleientertainment.com
curl -v https://login.kleientertainment.com/HealthCheck
nslookup login.kleientertainment.com
telnet login.kleientertainment.com 443
mtr -r -n -P 443 login.kleientertainment.com
而且要切换可用区不能直接用这个数据盘,所以得把布置好的数据盘转换成快照又转成自定义镜像,把镜像复制到香港地区,再从镜像创建实例。最后其实也就贵了一两毛钱/h……
SteamCMD workshop timeout
因为SteamCMD自己的bug,除了第一次尝试的时候下载了一些mod外,其他mod怎么都下载失败,log报错:Master: [00:00:03]: Running main.lua
Master:
Master: [00:00:03]: loaded modindex
Master: [00:00:03]: ModIndex: Beginning normal load sequence for dedicated server.
Master:
Master: [00:00:04]: [Workshop] Item query page 0, size: 26, total size: 26
Master: [00:00:04]: [Workshop] Item query queued IDs: 1079538195 1185229307 1892210190 2968760008 2978292229 2981762440 3003031644 3005687457 3007113503 3014637953 3034630375 3287608658 3358138839 3364034917 3490732007 3574405615 362175979 374550642 375859599 378160973 458940297 462372013 462434129src/clientdll/contentupdatecontext.cpp (2036) : Staging library folder not found
src/clientdll/contentupdatecontext.cpp (2037) : Install library folder not found
src/clientdll/contentupdatecontext.cpp (2036) : Staging library folder not found
src/clientdll/contentupdatecontext.cpp (2037) : Install library folder not found
src/clientdll/contentupdatecontext.cpp (2036) : Staging library folder not found
……
569043634 581762517 806509244
Master: [00:00:04]: [Workshop] Item query sent
Master: [00:00:05]: [Workshop] ItemQuery got this many results: 26, matching: 26
Master: [00:00:05]: [Workshop] ModQuery got 26 results
Master: [00:00:05]: [Workshop] ModQuery queued to download IDs: 1079538195 362175979 458940297 462372013 462434129 581762517 806509244
Master: [00:00:05]: [Workshop] ModQuery already have IDs: {98,1185229307} {1.4.8,1892210190} {2.5,2968760008} {1.9,2978292229} {1.3.6.6,2981762440} {25.4.13,3003031644} {1.4.6,3005687457} {2.0.9,3007113503} {1.0.3,3014637953} {1.0,3034630375} {0.0.7,3287608658} {1.4.1.3,3358138839} {1.2.2,3364034917} {1.1.23,3490732007} {1.1.3,3574405615} {1.9,374550642} {2.2.04,375859599} {1.7.5,378160973} {1.6.10,569043634}
Master: [00:00:05]: [Workshop] ItemQuery finished all queries, moving to download phase
Master: [00:00:05]: [Workshop] ItemQuery downloading 7 pending mods marked to download
Master: [00:00:05]: [Workshop] DownloadPublishedFile [10] 1079538195
Master: [00:00:05]: [Workshop] DownloadPublishedFile [10] 362175979
Master: [00:00:05]: [Workshop] DownloadPublishedFile [10] 458940297
Master: [00:00:05]: [Workshop] DownloadPublishedFile [10] 462372013
Master: [00:00:05]: [Workshop] DownloadPublishedFile [10] 462434129
Master: [00:00:05]: [Workshop] DownloadPublishedFile [10] 581762517
Master: [00:00:05]: [Workshop] DownloadPublishedFile [10] 806509244
Master: src/clientdll/contentupdatecontext.cpp (2036) : Staging library folder not found
Master: src/clientdll/contentupdatecontext.cpp (2037) : Install library folder not found
Master: [00:00:05]: [Workshop] OnDownloadPublishedFile [16] 1079538195
Master: [00:00:05]: [Workshop] ODPF failed entirely: 16
Master: src/clientdll/contentupdatecontext.cpp (2036) : Staging library folder not found
Master: src/clientdll/contentupdatecontext.cpp (2037) : Install library folder not found
Master: [00:00:06]: [Workshop] OnDownloadPublishedFile [16] 362175979
Master: [00:00:06]: [Workshop] ODPF failed entirely: 16
……
Master: [00:00:35]: DownloadServerMods timed out with no response from Workshop...
从https://github.com/ValveSoftware/Source-1-Games/issues/7508 来看这应该是steamcmd本身的bug,我尝试了多种方法,比如把mod手动放入成功安装的mod的所在地 dontstarvetogether_dedicated_server/ugc_mods 中、在steamcmd中使用 workshop_download_item 指令手动下载到游戏目录(这个指令甚至不在steamcmd开发文档中),但都不能正确识别,它还是会认为缺少mod,然后尝试下载并失败。
最后我在这篇指南中找到了唯一的解决办法:
在dedicated_server_mods_setup.lua中设置好mod id(按照教程的话这一步已经做过了),然!后! 将带有workshop-前缀的mod文件夹放到 dontstarvetogether_dedicated_server/mods里。这样steam客户端才会正常加载mod进去。
配置systemctl实现开机自启服务器
首先创建/etc/systemd/system/dst_server.service,然后在其中设置如下 Systemd 服务:[Unit]
Description=Don't Starve Together Cluster
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/root
ExecStart=/root/boot_cave.sh
# 关键:由于脚本会启动子进程(Caves),我们需要确保关闭服务时所有相关进程都被杀死
KillMode=control-group
# 如果任意一个分片崩溃,自动重启整个脚本
Restart=always
RestartSec=15
[Install]
WantedBy=multi-user.target
然后创建一下日志文件:sudo touch /var/log/dst_server.log && sudo chmod 666 /var/log/dst_server.log (除了这里,游戏本身在~/.klei/DoNotStarveTogether/Cluster_1/Master/server_log.txt以及~/.klei/DoNotStarveTogether/Cluster_1/Caves/server_log.txt中也会输出日志)
相关指令:# 重新加载配置
systemctl daemon-reload
# 设置开机自启
systemctl enable dst_server
# 立即启动(测试一下)
systemctl start dst_server
# 查看状态
systemctl status dst_server
# 查看服务器的实时输出日志
sudo journalctl -u dst_server.service -f
初始没有生成洞穴世界的情况下中途加入洞穴
血的教训,初始一定不要闲的没事取消洞穴,中途加入太麻烦了。
具体教程:https://steamcommunity.com/sharedfiles/filedetails/?id=2043035362
由于饥荒游戏机制,主世界和洞穴是两个独立的世界。中途加洞穴的核心思想就是重新创建一个包含这两个世界的存档,然后用之前没有洞穴的存档中的人物和地图信息覆盖新存档的主世界信息,也就是Cluster_x/Master/save/session中的内容。
但是非常不幸的是,这样操作后得到的存档可以在本地启动,上传到服务器上却无论如何都不能成功开房加入了。显示“授权失败”(Authentication failed),尝试各种方法都未解决,后面我们就勉强在本地玩了。
多世界启动的参考资料(没有派上用场):https://forums.kleientertainment.com/forums/topic/59174-understanding-shards-and-migration-portals/