小游戏服务端配置教程
TJUUS 目前运营过的大部分小游戏均为地图 + 数据包形式,这篇教程提供这种类型的服务端配置教程,以让后续的小游戏服务端更加方便。
服务端重要构成部分 | Crucial Components
- logs 文件夹 | 存放服务器运行产生的日志文件
- plugins 文件夹 | 存放服务器插件
- 三个 world 文件夹 | 服务器三个世界维度的地图存档
- server.properties | 服务端配置信息
- eula.txt | 开服需要遵守的最终用户许可协议
- 服务端核心
在哪下载服务端核心 | Where to download server jar?
参考 常用服务端资源指南
配置教程 | Tutorial
请确保你的电脑拥有兼容你所需要运行的服务端的 Java 环境, (Windows) 为了方便请加入到系统环境变量中.
(我推荐本地部署完毕后再上传至面板)
获取与小游戏地图游戏版本相同的 Minecraft 服务端核心,移动至一个新文件夹里。新建一个文本文档, 写入以下内容:
java -jar server-core.jar nogui
pauseserver-core.jar 为你的服务端核心, nogui 是为了禁用掉 Minecraft 在较新版本服务端核心中自带的图形化控制台.
将文件类型改为 .bat 并运行。
此时文件夹内会生成一个 eula.txt 文件,你需要将里面的 eula 布尔值改为 true。
再次运行 bat 文件, 不出意外这次服务端将会正常启动.
我们找到 server.properties 文件, 将部分配置改成下列所示:
enable-command-block=true
online-mode=false接着, 将文件夹内 world 文件夹删除, 并将你需要导入的小游戏地图文件夹名称改为 world 后导入。
语音组件和全局语音组件(可选)
我推荐前往 Modrinth 下载 Simple Voice Chat 的全类型全版本资源, 并将其加入到服务端文件夹的 mods / plugins 文件夹。
并将 voicechat-server.properties 中的 port 与 MCSM 面板中对应。
Fabric 端可使用 Simple Voice Chat Enhanced Groups 实现全局语音 (仅 Fabric 可用)
Forge 端请尝试 Sinytra Connector 来兼容上文的 Fabric 模组
对于支持 Bukkit 插件的服务端,可以参考以下代码自行构建一个插件并放入服务端的 plugins 文件夹中。
package me.chengzhify.autoJoinVoiceGroup;
import de.maxhenkel.voicechat.api.BukkitVoicechatService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import javax.annotation.Nullable;
import java.util.UUID;
public final class AutoJoinVoiceGroup extends JavaPlugin {
public static UUID uuid = UUID.randomUUID();
private static AutoJoinVoiceGroup instance;
public static final Logger LOGGER = LogManager.getLogger("AutoJoinVoiceGroup");
@Nullable
private VoicechatImpl voicechatPlugin;
@Override
public void onEnable() {
instance = this;
// Plugin startup logic
if (!getServer().getPluginManager().isPluginEnabled("voicechat")) {
getLogger().severe("voicechat not found! Disabling...");
getServer().getPluginManager().disablePlugin(this);
} else {
BukkitVoicechatService service = getServer().getServicesManager().load(BukkitVoicechatService.class);
if (service != null) {
voicechatPlugin = new VoicechatImpl();
service.registerPlugin(voicechatPlugin);
LOGGER.info("Successfully registered voicegroup plugin");
} else {
LOGGER.info("Failed to register voicegroup plugin");
}
}
Bukkit.getPluginManager().registerEvents(new PlayerJoinListener(), this);
Bukkit.getScheduler().runTaskLater(this, () -> {
uuid = VoicechatImpl.createGroup("全局", "语音频道");
}, 60L);
}
@Override
public void onDisable() {
// Plugin shutdown logic
if (voicechatPlugin != null) {
getServer().getServicesManager().unregister(voicechatPlugin);
}
instance = null;
}
public static AutoJoinVoiceGroup getInstance() {
return instance;
}
}package me.chengzhify.autoJoinVoiceGroup;
import de.maxhenkel.voicechat.api.VoicechatConnection;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
public class PlayerJoinListener implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
event.getPlayer().sendMessage("§a正在尝试将你连接至全局语音频道...");
Bukkit.getScheduler().runTaskLaterAsynchronously(AutoJoinVoiceGroup.getInstance(), () -> {
VoicechatConnection connection = VoicechatImpl.voiceServerApi.getConnectionOf(event.getPlayer().getUniqueId());
if (connection == null) {
event.getPlayer().sendMessage("§c连接失败! 请检查你的 SimpleVoiceChat 模组是否正确启用!");
return;
}
connection.setGroup(VoicechatImpl.voiceServerApi.getGroup(AutoJoinVoiceGroup.uuid));
event.getPlayer().sendMessage("§a你已成功连接至全局语音频道!");
}, 20L * 3L); // 延迟3秒执行,确保玩家已连接到语音服务器
}
}package me.chengzhify.autoJoinVoiceGroup;
import de.maxhenkel.voicechat.api.Group;
import de.maxhenkel.voicechat.api.VoicechatApi;
import de.maxhenkel.voicechat.api.VoicechatPlugin;
import de.maxhenkel.voicechat.api.VoicechatServerApi;
import de.maxhenkel.voicechat.api.events.EventRegistration;
import de.maxhenkel.voicechat.api.events.JoinGroupEvent;
import de.maxhenkel.voicechat.api.events.LeaveGroupEvent;
import de.maxhenkel.voicechat.api.events.VoicechatServerStartedEvent;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import java.util.UUID;
import static org.apache.logging.log4j.LogManager.getLogger;
public class VoicechatImpl implements VoicechatPlugin {
public static VoicechatServerApi voiceServerApi;
private static final AutoJoinVoiceGroup instance = AutoJoinVoiceGroup.getInstance();
private static final boolean voiceLog = instance.getConfig().getBoolean("voice-group-console-log");
@Override
public String getPluginId() {
return "AutoJoinVoiceGroup";
}
@Override
public void initialize(VoicechatApi api) {
}
@Override
public void registerEvents(EventRegistration registration) {
registration.registerEvent(VoicechatServerStartedEvent.class, this::onVoiceServerStart);
}
private void onVoiceServerStart(VoicechatServerStartedEvent event) {
voiceServerApi = event.getVoicechat();
System.out.println(voiceServerApi);
getLogger().info("[VoiceChat] API 已获取,可以创建语音频道了!");
}
public static UUID createGroup(String name, String team) {
Group g = voiceServerApi.groupBuilder()
.setPersistent(true)
.setName(name + team) // The name of the group
.setType(Group.Type.OPEN)
.build();
if (voiceLog) {
getLogger().info("[VoiceGroup] " + name + team + " 语音组已创建");
}
return g.getId();
}
}Simple Voice Chat 提供了它的 API 文档, 这方便我们基于它开发一些更有意思的拓展组件。
皮肤恢复组件(可选)
皮肤恢复插件 (SkinRestorer): (较新的 MC 版本也支持模组服,服务端侧)
皮肤恢复模组 (SkinRestorer): (服务端侧,个人客户端无需安装)