Minecraft 1.21.1游戏服务器运维笔记1:Ubuntu 18.04.6折腾Fabric配置及TinyRemapper、session.lock错误的解决方法

摘要

本文叙述了如何在 Linux 服务器上通过完全命令行交互的方式配置基于 Minecraft 1.21.1 版本的 Fabric 服务器,交代了环境配置流程,以及服务端文件、模组文件的下载方法,给出了命令行操作方式以及完整的游戏启动脚本。

背景

上星期,我们的 Minecraft 服务器里大型的潜影贝农场刚刚完工,夜里朋友上线跟我发消息,问我是不是做了存档回滚还回滚到了错误的版本,因为刚刚建造好的刷沙机不见了。

我当天下午清除了一次缓存,备份目录下面出现了一个没有办法打开的文件,叫做zit2d9Dt。我一开始以为是某个过程产生的奇怪文本文件,所以直接用 cat 命令查看了……在二进制数据炸屏之后我的 ssh 当场被卡掉下来了……

我们服务器的备份机制就是通过 crontab 定期执行一个脚本,直接用 zip 命令把整个 world 文件夹都压缩起来,然后放在一个 backups 目录下面。因为世界出了问题,我跟同学就想到回滚到几天前的版本,但是我们才发现前段时间所有的备份其实都有问题,只是我们没有发现。这些备份出现了很奇怪的现象——像是箱子里的物品是最新的状态,但是世界的建造情况却是半个月前的样子。

所以现在我们服务器末地的刷石机没了、刷沙机、潜影贝农场、还有我们在末地的基地、前哨和社区都没了。

在发生了这些事情之后,我对我原本搭建的服务器和备份系统感到极度的不信任。在和一位多年运维 Minecraft 服务器的朋友交流寻求帮助的时候,对方在听闻我使用的是 Minecraft 原版的官方服务端的时候觉得这是一件很不可思议的事情。在他看来,这个服务端非常难以操作,体验很糟糕。他表示他从来没有使用过原版的服务端,因此无法提供帮助。

我说好吧,Mojang 造出来的东西这么不堪吗?既然这样的话,我还是着手重新配置基于 Fabric 的游戏服务器服务端好了。

笔者作为 Minecraft 的萌新小白,完全没有任何配置和运营 Minecraft 服务器的经验,只是会使用 Linux 而已,所以本文中所述的一切操作都是完完全全误打误撞摸索出来的野路子。 不过也正因如此,文中的叙述几乎可以说是事无巨细,将读者可能会有困惑的方方面面都顾及到了,希望能给读者提供一些帮助。

需求

前瞻知识及材料准备

阅读本文你需要的前瞻知识包括:

  • 关于 Minecraft 游戏版本、Fabric 等服务端、模组的基本常识;
  • 能够正常使用 Linxu 操作系统,基本掌握命令行的操作方法。

同时,你需要的材料是一台配置足以运行 Minecraft 1.21.1 游戏服务的远程服务器(可以从任意的云服务商那里购买,或者自己做云网穿),并且已经完成了 Minecraft 游戏服务所需的 25565 端口的放行(也可以放行其他端口,游戏使用的端口号可以在 server.properties 里面修改,下文会讲到)。

这部分内容我在这里就不赘述了,一方面网上的资料比较多,另一方面我这边已经配置好了,想要再演示这些基本内容会很不方便,文章就太长了,写不完了。

准备工作

在开始配置 Minecraft 游戏服务器之前,最好先对服务器大致的定位有一个认识,从而确定服务器究竟需要安装哪些模组。

对于我们的游戏服务器,主要经营的是生存模式游戏,包含一些轻度的生电内容。一方面想要把原先自己写的基于 Bash Shell 脚本和 crontab 定时执行的备份系统替换为现有成熟的备份解决方案,另一方面也想为生电游戏加上一些辅助插件。总的来说,重新配置服务器的需求可以分为三大类,分别是:

  1. Fabric 服务端游戏本体;
  2. 各路生电辅助插件;
  3. 正规的服务器备份方案,如各类备份模组等。

这些内容需要服主与服务器的玩家交流协商。最终决定要配置的游戏和模组包括:

  • Fabric 服务端生存模式游戏及其 API,游戏版本为 1.21.1;
  • servux 用于支持 minihud 查看结构边界;
  • minihud 服务器端(查看世界生成的结构等);
  • QuickBackupMulti(用于备份世界)。

环境配置

操作系统

我们的服务器所使用的操作系统是 Ubuntu 18.04.6,这是在买服务器的时候就决定了的。

JDK 配置

目前服务器上已经安装了 JDK 21 环境,由于我们要运行比较新的 1.21.1 版本,JDK 17 已经不再可用。另,可以考虑根据 B站 UP 主的建议 更换到 Alibaba DragonWell JDK 以便取得更好的性能,但是我这里为了方便没有采用这个配置。

openjdk version "21.0.3.0.3" 2024-04-16
OpenJDK Runtime Environment (Alibaba Dragonwell Standard Edition)-21.0.3.0.3+9-GA (build 21.0.3.0.3)
OpenJDK 64-Bit Server VM (Alibaba Dragonwell Standard Edition)-21.0.3.0.3+9-GA (build 21.0.3.0.3, mixed mode, sharing)

因为我需要在本地 WSL 上配置一个模拟环境,测试一下配置服务器的方法能否在本地的 WSL 环境里面正常运行起来,正好可以讲一下如何配置 Java 环境。关于换源之类的细节我就不再赘述了,首先在开始安装 Java 之前最好先执行 sudo apt update更新软件源。(不要小看这个细节,如果不执行这一步很可能会失败)然后:

sudo apt install openjdk-21-jdk

等待安装完成之后执行 java -version 查看。

安装 screen

screen 为多重视窗管理程序。此处所谓的视窗,是指一个全屏幕的文字模式画面。通常只有在使用 telnet/ssh 登入远程主机或是使用老式的终端机时,才有可能用到 screen 程序。

Minecraft 游戏服务器启动之后会进入游戏进程,这个进程就是游戏的后台。你可以在这个窗口里面输入 Minecraft 指令对世界生效,但是一旦你将这个窗口关闭,游戏进程就会被杀死,游戏就会停止。因此,我们需要将游戏挂载在一个 screen 视窗下面运行,启动游戏之后可以用 Ctrl A + D 切换到原来的系统 shell,这样即使你关闭、断开了与 Linux 服务器操作系统 shell 的 ssh 链接,游戏也会继续在独立的 screen session 中运行,且再次登入服务器也随时可以通过 screen -r 命令返回查看。

由于 Ubuntu 上的包管理器是 apt,因此使用 apt 命令安装:

apt-get install screen

查看是否已经正确安装了 screen:

screen -version

如果出现类似如下的输出就说明安装基本正确:

Screen version 4.09.01 (GNU) 20-Aug-23

游戏用户与文件目录系统设计

好的文件目录设计是好的开始。为了运行 Minecraft 游戏服务,我在服务器上创建了一个专门的用户 minecraft,在其主目录 /home/minecraft 下创建了 mcserver 文件夹,后面将会被搭建称为 Minecraft 服务器的运行时目录,这样的设计可以确保服务器的文件不会和用户主目录下的各种配置文件相冲突。

mcserver 下面会产生下面几个比较重要的文件和文件夹:

  • mods 文件夹——储存所有服务器端的 Mods 文件的文件夹
  • world 文件夹——游戏世界的存档文件夹

这两个文件夹不用急着创建,后面会讲到的。

操作步骤

备份旧的游戏文件

由于我们的服务器上面以前运行过 Minecraft 的游戏,所以需要首先备份以前的游戏记录。首先备份原来的游戏文件目录到 ./backups 目录下,zip 命令操作参考zip 和 unzip 命令用法。

下载安装 Fabric 服务端

下载 Server Jar

首先,Fabric 需要有 Minecraft 的服务端文件 server.jar 才能运行,文件需要自备而不会自动替你下载。因此,你需要在 Mojang 的官网的上下载正确版本的文件,然后把 server.jar 和我们接下来下载的 fabric-installer.jar 放在同一级目录下(放置的目录就是游戏的运行时目录。我的方案是在服务器的 minecraft 用户的主目录 ~ 下面创建了 ~/mcserver 文件夹)。

Note. 这一点非常重要,实践发现如果你不这样操作,Fabric Installer 就不能正确安装 Fabric,那样的话你就必须把产生的其余文件删掉然后重新 Fabric Install 操作。

我这边偷了个懒,找了个 收集不同版本的 Minecraft 的网站。要下载 1.21.1 你可以点击进入网站的下载页面,也可以使用命令:

curl -OJ https://piston-data.mojang.com/v1/objects/59353fb40c36d304f2035d51e7d6e6baa98dc05c/server.jar

下载 Fabric Installer

官网文档 具体讲解了如何通过 CLI 安装 Fabric,以及详细的操作。可以具体查看。

首先需要从 Installer 下载页面 下载文件 fabric-installer.jar。文件没有按照版本区分,所以我猜测这东西应该就是针对所有版本的。

当然也可以在命令行下载:

curl -OJ https://maven.fabricmc.net/net/fabricmc/fabric-installer/1.0.1/fabric-installer-1.0.1.jar

这里下载的 Fabric 版本目前为 0.16.7。

按照官网上的提示:

The Fabric Installer has full support from installing the client and the server from the command line. This could be used to automate the installation. The installer has a number of commands that can be used for a headless install.

可以直接在命令行操作选择安装服务器的版本。

java -jar fabric-installer-1.0.1.jar server -mcversion "1.21.1"

Note. 执行时需要加上 -mcversion "1.21" 参数,否则的话就算已经给出了正确的 server.jar。报错发生的时候还没有安装任何模组。

脚本启动与参数配置

Aikar's flags

了解一下什么是 Aikar's flags:根据 PaperMC Docs 网站给出的信息资料 显示:

Aikar's flags are a set of flags that can be used when running the game. These flags are designed to change certain settings on the JVM that can improve the performance of the game. Some of the flags include reducing the amount of RAM and processor usage, as well as optimizing the game for better performance.

这些是 Aikar 提供的 Java 启动参数(Flags),专门为 Minecraft 服务器的性能优化而设计,特别是在大型服务器或长时间运行的服务器上使用。它们主要是围绕 Java 的垃圾回收器(Garbage Collector, GC)进行调整,以减少内存管理对服务器性能的影响。

以下是网站给出的 Aikar's flags:

java -Xms10G -Xmx10G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -jar paper.jar --nogui

以下是由 ChatGPT 给出的对于这些参数的解释:

内存分配

  • -Xms10G: 设定 Java 虚拟机(JVM)的初始堆内存大小为 10 GB。这个值会在服务器启动时分配,不会动态变化。
  • -Xmx10G: 设定 JVM 的最大堆内存大小为 10 GB,服务器运行时内存使用的上限。

当然在这里我们羸弱的土豆服务器不可能给 JVM 分配整整 10GB 的初始堆内存大小,所以这个数值需要根据实际情况进行修改。

垃圾回收器设置(GC)

  • -XX:+UseG1GC: 启用 G1垃圾回收器,适用于大内存应用程序,特别是 Minecraft 服务器。
  • -XX:+ParallelRefProcEnabled: 并行引用处理,加快垃圾回收中的引用处理速度。
  • -XX:MaxGCPauseMillis=200: 设定 最大GC暂停时间 为 200 毫秒,控制每次垃圾回收暂停的时长,减少对游戏的卡顿。
  • -XX:+UnlockExperimentalVMOptions: 启用一些 实验性的 JVM 选项,为进一步优化开放可能的实验功能。
  • -XX:+DisableExplicitGC: 禁用显式GC,阻止程序调用 System.gc(),避免可能的性能损失。
  • -XX:+AlwaysPreTouch: 预热内存,在启动时预先分配堆内存,避免在服务器运行过程中分配内存的性能开销。

G1GC 相关优化

  • -XX:G1NewSizePercent=30: 设置 G1GC 的 新生代内存大小 占堆内存的最小百分比为 30%。
  • -XX:G1MaxNewSizePercent=40: 设置 G1GC 的 新生代内存大小 占堆内存的最大百分比为 40%。
  • -XX:G1HeapRegionSize=8M: 将 G1堆内存分区大小 设置为 8 MB,每个分区的大小影响内存分配和垃圾回收效率。
  • -XX:G1ReservePercent=20: 保留 20% 的堆内存不被使用,作为 内存回收的预留空间,以应对突发的内存需求。
  • -XX:G1HeapWastePercent=5: 允许 G1GC 垃圾回收过程中 最多浪费 5% 的堆内存,以提高回收效率。
  • -XX:G1MixedGCCountTarget=4: 混合垃圾回收目标次数 为 4,控制垃圾回收的频率和时间。
  • -XX:InitiatingHeapOccupancyPercent=15: 当堆内存使用 超过 15% 时,触发 G1GC 执行垃圾回收。
  • -XX:G1MixedGCLiveThresholdPercent=90: G1GC 只会在混合垃圾回收中处理存活对象 少于 90% 的分区。
  • -XX:G1RSetUpdatingPauseTimePercent=5: 更新 RSet 的暂停时间 不超过总暂停时间的 5%。

堆内存管理

  • -XX:SurvivorRatio=32: 新生代的存活区比例,设置为 32 意味着伊甸园区与幸存者区的比例是 32:1。
  • -XX:+PerfDisableSharedMem: 禁用 性能共享内存,减少对性能监控的开销。
  • -XX:MaxTenuringThreshold=1: 最大晋升阈值 为 1,对象只在新生代停留一次后就被提升到老年代,减少新生代的垃圾回收次数。

其他参数

  • -Dusing.aikars.flags=https://mcflags.emc.gs: 指定使用 Aikar 的优化标记,并引用它们的来源网站。
  • -Daikars.new.flags=true: 告诉服务器启用 Aikar 的新标记。

启动服务参数

  • -jar paper.jar --nogui: 启动 paper.jar,这是 Minecraft 服务器的 jar 文件,同时 --nogui 表示不使用图形界面。

启动脚本

有一说一,上面这一大堆内容我也看不懂,我看着一愣一愣的。

不管了,反正照着来呗。将上文中出现的 Aikar's flags 整合起来,就可以编写启动脚本了。脚本可以取名 start_mc_server.sh,内容比较长,我放在了附录 A 里面。

模组配置

下载模组文件资源

平台

本文中所有的模组资源都可以在 CurseForge 平台找到,但是经过实践之后发现,CurseForge 这个平台它就很离谱。它的搜索框在搜索模组的时候经常是输错一个字母(比如把 Servux 写作 servux)就搜不到东西。所以我的建议是直接在 Google 里面搜索相关资源。

同时由于网站的限制,模组资源文件不能通过 curl 命令从远程服务器下载,只能先一个一个下载,好然后使用 scp 命令一次性上传到远程服务器。

Fabric API

Fabric API 是通过模组形式安装的,网址在 https://www.curseforge.com/minecraft/mc-mods/fabric-api

Servux

用于支持 MiniHUD 显示结构边界的 Mod。网址在 https://www.curseforge.com/minecraft/mc-mods/servux

这个模组不需要在客户端上安装。官网上将这行文字标记为红色,似乎很重要。

MiniHUD

网址在 https://www.curseforge.com/minecraft/mc-mods/minihud。按照原本的计划是需要在服务器安装 minihud 模组的服务端。但在实际查询 CurseForge 资料的时候发现了这样一段资料文字:

minihud A client-side mod that allows displaying various "info lines" on the screen ("mini-F3"). The alignment (screen corner), background and text color and font size are configurable.

Note: This is a client-side-only mod! You can't put it on a server.

(翻译:注意:这是一个仅限客户端的模组!你不能把它放在服务器上。)

Note: MiniHUD also requires the MaLiLib library mod.

Be sure to download the correct version of both mods from the Files page!

https://www.curseforge.com/minecraft/mc-mods/malilib

这里提及的 MaLiLib 是一个为 Masa 的模组提供客户端侧支持的公共代码库模组。 它基本上包含了所有可配置选项,按键绑定系统,做大多数 GUI 代码支持以及其他的实用组件供其他模组使用。也就是说所谓的 MiniHUD 服务端其实就是需要下载 MaLiLib。但其实 MaLiLib 需要同时在本地和服务器上安装,而 MiniHUD 只需要安装在本地客户端

QuickBackupMulti

网址在 https://www.curseforge.com/minecraft/mc-mods/quickbackupmulti

一个 Minecraft mod,用于在游戏中创建、保存备份和管理。它可以在单人游戏和服务器中使用。

您可以在游戏中进行带有描述的保存备份,并且您可以随时恢复它。 此外,您可以设置 make save-backup 的计划。它将根据您设置的计划创建保存备份

2.x 版本的 Mod 现在支持创建备份! 它使用 NOSQL 数据库来保存备份信息,

这个 Mod 不会对世界生成产生任何影响。

服务器模组的安装

理论上只需要将模组放置在运行时目录下的 mods 文件夹下面就可以了。

  • 需要在服务器端安装的模组有:Servux、MaLiLib、QuickbackupMulti、Fabric API;
  • 需要在本地安装的模组有:MaLiLib、MiniHUD、QuickbackupMulti,Fabric API 可以直接通过 PCL 或者 HMCL 之类的启动器进行安装。

在安装模组之前,你需要首先执行一次 java -jar ./fabric-server-launch.jar,这将会创建名为 mods 的模组文件夹。不必担心游戏会立即启动或者创建不必要的世界存档,由于没有启用 EULA 协议,游戏会在启动之后立即暴死。

Note. 不要一上来就执行脚本 start_mc_server.sh,不知道为什么这样做会产生 Cannot create Java Virtual Machine 的错误。

游戏配置

编辑 Server Properties

server.properties 文件保存了游戏的世界配置,包括游戏难度、游戏模式(生存、创造、极限)、世界种子等等。里面只有几个地方需要修改:

  1. 游戏难度 diffculity=hard
  2. levelseed=<世界种子>,需要和载入的游戏存档世界保持一致。我这里就设置 levelseed=31011421 了,因为我们的游戏存档用的就是这个种子。

或者直接将以前编辑过的 server.properties 上传到远程服务器。可以使用任何熟悉的文本编辑器,比如 nano,或者 vim 更方便。

vim ./server.properties

然后直接编辑里面的内容就可以了。

启用 EULA 协议

编辑 eula.txt,将 eula 选项改为 true,表示同意终端用户协议。

载入世界存档

需要载入的世界存档必须是名为 world 的文件夹,文件夹内有包含 level.dat 在内的若干区块数据 .dat 文件及文件夹。将其安置在游戏的运行时目录下就可以了。

启动游戏

执行编写好的脚本 ./start_mc_server.sh 即可,使用 screen -r 切入游戏后台会话检查游戏是否正确启动了。如果是就没有问题了!

本地客户端配置

如果你已经完成了上面的一系列操作,那么你不大可能会在配置自己的本地客户端的时候遇到困难。这个操作很简单,首先就是在你的启动器里面勾选下载 Minecraft 1.21.1 Fabric + Fabric API,然后打开本地配置中的 mods 文件夹将上文提及到的 MaLiLib、MiniHUD、QuickbackupMulti 模组一股脑塞进去。

关键问题在于服主需要向服务器的玩家说明如何配置本地客户端,这就要考验服主的能力了。当然如果你的服务器玩家学习能力比较强,就不需要在这方面费心,只需要向他们提供一份服务器已安装模组的清单文件就好了。

记录报错与解决方法

TinyRemapper 报错

第一次遇到这个报错的时候我在 Reddit 论坛上面发了帖子求助:Error while setting up my first Minecraft 1.21 Fabric server.,最后的结果就是需要在运行 fabric-installer.jar 的时候指定 -mcversion "1.21.1" 参数,否则就算已经在游戏的运行时目录下安置了 1.21.1 版本的 server.jar,游戏还是倾向于下载最新版本,也就是 1.21.3 的 Fabric 启动程序。

报错日志:

Uncaught exception in thread "main"
java.lang.RuntimeException: An exception occurred when launching the server!
        at net.fabricmc.loader.impl.launch.server.FabricServerLauncher.main(FabricServerLauncher.java:71)
Caused by: java.lang.RuntimeException: Unfixable conflicts
        at net.fabricmc.loader.impl.lib.tinyremapper.TinyRemapper.handleConflicts(TinyRemapper.java:898)
        at net.fabricmc.loader.impl.lib.tinyremapper.TinyRemapper.propagate(TinyRemapper.java:798)
        at net.fabricmc.loader.impl.lib.tinyremapper.TinyRemapper.mrjRefresh(TinyRemapper.java:1077)
        at net.fabricmc.loader.impl.lib.tinyremapper.TinyRemapper.apply(TinyRemapper.java:929)
        at net.fabricmc.loader.impl.game.GameProviderHelper.deobfuscate0(GameProviderHelper.java:314)
        at net.fabricmc.loader.impl.game.GameProviderHelper.deobfuscate(GameProviderHelper.java:246)
        at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.initialize(MinecraftGameProvider.java:331)
        at net.fabricmc.loader.impl.launch.knot.Knot.init(Knot.java:140)
        at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:68)
        at net.fabricmc.loader.impl.launch.knot.KnotServer.main(KnotServer.java:23)
        at net.fabricmc.loader.impl.launch.server.FabricServerLauncher.main(FabricServerLauncher.java:69)

进程占用文件的冲突

Minecraft 服务器无法启动,因为 session.lock 文件已经被锁定。这个通常是由于以下原因之一:

  1. 服务器已经在运行:可能有另一个 Minecraft 服务器实例已经启动,并正在使用这个 world 文件夹。如果你尝试在同一个文件夹中启动多个服务器实例,会导致该文件被锁定。

  2. 服务器崩溃后未正确关闭:如果服务器在崩溃或非正常关闭时没有释放 session.lock 文件,它会保持锁定状态,阻止其他实例启动。

检查后发现,这个问题产生的原因是因为我在执行 start_mc_server.sh 脚本的时候不小心使用了 sudo

sudo ./start_mc_server

这就导致了启动的游戏服务的 screen session 实际上是在 root 用户下,但是我却没有意识到。直接执行了 screen -r 之后发现找不到游戏后台的 session,于是我就再次执行了 start_mc_server.sh,就遭遇了报错。

可以尝试以下方法来解决这个问题:

  1. 检查是否有其他实例在运行:通过以下命令查看当前是否有 Minecraft 服务器正在运行:

    ps aux | grep java
    

    如果有正在运行的 Minecraft 进程,你可以终止它们:

    kill <PID>
    

    替换 <PID> 为进程 ID。

  2. 删除 session.lock 文件:如果没有其他服务器实例在运行,可以手动删除 session.lock 文件。进入你的 world 目录,找到并删除 session.lock 文件:

    rm ./world/session.lock
    

    然后尝试重新启动服务器。当然如果进程已经被正确杀死,应该就不需要手动删除 session.lock 了。这是最好的。

报错日志:

$ java -jar ./fabric-server-launch.jar --nogui
Starting net.fabricmc.loader.impl.game.minecraft.BundlerClassPathCapture
[00:01:19] [main/INFO]: Loading Minecraft 1.21 with Fabric Loader 0.16.7
[00:01:20] [main/INFO]: Loading 4 mods:
        - fabricloader 0.16.7
           \-- mixinextras 0.4.1
        - java 22
        - minecraft 1.21
[00:01:20] [main/INFO]: SpongePowered MIXIN Subsystem Version=0.8.7 Source=file:/mnt/e/dev/mcserver-localtest/mcserver/libraries/net/fabricmc/sponge-mixin/0.15.3+mixin.0.8.7/sponge-mixin-0.15.3+mixin.0.8.7.jar Service=Knot/Fabric Env=SERVER
[00:01:27] [main/INFO]: Environment: Environment[sessionHost=https://sessionserver.mojang.com, servicesHost=https://api.minecraftservices.com, name=PROD]
[00:01:28] [main/ERROR]: Failed to start the minecraft server
net.minecraft.class_5125$class_5126: /mnt/e/dev/mcserver-localtest/mcserver/./world/session.lock: already locked (possibly by other Minecraft instance?)
        at knot/net.minecraft.class_5125$class_5126.method_26805(class_5125.java:95) ~[server-intermediary.jar:?]
        at knot/net.minecraft.class_5125.method_26803(class_5125.java:41) ~[server-intermediary.jar:?]
        at knot/net.minecraft.class_32$class_5143.<init>(class_32.java:374) ~[server-intermediary.jar:?]
        at knot/net.minecraft.class_32.method_52236(class_32.java:353) ~[server-intermediary.jar:?]
        at knot/net.minecraft.server.Main.main(Main.java:137) [server-intermediary.jar:?]
        at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:480) [fabric-loader-0.16.7.jar:?]
        at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74) [fabric-loader-0.16.7.jar:?]
        at net.fabricmc.loader.impl.launch.knot.KnotServer.main(KnotServer.java:23) [fabric-loader-0.16.7.jar:?]
        at net.fabricmc.loader.impl.launch.server.FabricServerLauncher.main(FabricServerLauncher.java:69) [fabric-loader-0.16.7.jar:?]

screen 权限报错

这个错误很奇怪,我想不通是怎么产生的。在本地 WSL 上测试的时候报错说无法访问 /run/screen 因为没有权限。既然如此那么直接加权吧:

chmod +777 -R /run/screen

附录

附录 A:在独立窗口中启动 Minecraft 游戏服务的脚本

#!/bin/bash
# 
# name    : start_mc_server.sh
# author  : BOXonline_1396529
# usage   : start_mc_server.sh [OPTIONS]
# date    : 2024-10-25
# version : 1.0.0.1
#
# start_mc_server.sh - Script to start Minecraft server

# Function to display help message
function show_help {
    echo "Usage: start_mc_server [OPTIONS]"
    echo
    echo "To launch Minecraft service in an independent screen session. Notice"
    echo "that the screen should be installed to the server first.            "
    echo
    echo "Options:"
    echo "  -h, --help   Show this help message and exit"
}

# Parse the first argument
case "$1" in
    -h|--help)
        show_help
        exit 0
        ;;
    *)
        FILE="$1"
        ;;
esac

echo "Starting server..."

name="Minecraft"

# Memory Settings
mem_args="-Xmx2048M -Xms1024M"

# GC Settings
gc_args=\
" -XX:+UseG1GC"\
" -XX:+ParallelRefProcEnabled"\
" -XX:MaxGCPauseMillis=200"\
" -XX:G1NewSizePercent=30"\
" -XX:G1MaxNewSizePercent=40"\
" -XX:G1HeapRegionSize=8M"\
" -XX:G1ReservePercent=20"\
" -XX:G1HeapWastePercent=5"\
" -XX:G1MixedGCCountTarget=4"\
" -XX:InitiatingHeapOccupancyPercent=15"\
" -XX:G1MixedGCLiveThresholdPercent=90"\
" -XX:G1RSetUpdatingPauseTimePercent=5"\
" -XX:SurvivorRatio=32"

# JVM Optimizations
jvm_optim_args=\
" -XX:+UnlockExperimentalVMOptions"\
" -XX:+DisableExplicitGC"\
" -XX:+AlwaysPreTouch"\
" -XX:+PerfDisableSharedMem"\
" -XX:MaxTenuringThreshold=1"

# Aikar's flags
aikar_args=\
" -Dusing.aikars.flags=https://mcflags.emc.gs"\
" -Daikars.new.flags=true"

# To start the server
server_jar="./fabric-server-launch.jar"
server_args="--nogui"

# Combine all the flags together
cmd=\
"java ${mem_args} ${jvm_optim_args} ${gc_args} ${aikar_args} "\
"-jar ${server_jar} ${server_args}"

# Start the screen session and run the server
screen -dmS ${name}
screen -x -S ${name} -p 0 -X stuff "${cmd}\n"

echo "
___  ___                             __ _   
|  \\/  (                            / _| |  
| .  . |_ _ __   ___  ___ _ __ __ _| |_| |_ 
| |\\/| | | '_ \\ / _ \\/ __| '__/ _\` |  _| __|
| |  | | | | | |  __/ (__| | | (_| | | | |_ 
\\_|  |_/_|_| |_|\\___|\\___|_|  \\__,_|_|  \\__|"

echo "
The server should be running under the screen session named \`Minecraft\` now
if there's no error. You can use \`screen -r\` switching to the backstage of 
the game.
"