小游戏服务端配置教程:修订间差异
ChengZhiFy(留言 | 贡献) 创建页面,内容为“<nowiki>'''test'''</nowiki>” |
ChengZhiFy(留言 | 贡献) 无编辑摘要 |
||
| (未显示同一用户的1个中间版本) | |||
| 第1行: | 第1行: | ||
< | TJUUS 目前运营过的大部分小游戏均为地图 + 数据包形式,这篇教程提供这种类型的服务端配置教程,以让后续的小游戏服务端更加方便。 | ||
=== 服务端重要构成部分 | Crucial Components === | |||
* '''logs''' 文件夹 | 存放服务器运行产生的日志文件 | |||
* '''plugins''' 文件夹 | 存放服务器插件 | |||
* 三个 '''world''' 文件夹 | 服务器三个世界维度的地图存档 | |||
* '''server.properties''' | 服务端配置信息 | |||
* '''eula.txt''' | 开服需要遵守的'''最终用户许可协议''' | |||
* 服务端核心 | |||
=== 在哪下载服务端核心 | Where to download server jar? === | |||
参考 [[常用服务端资源指南]] | |||
=== 配置教程 | Tutorial === | |||
请确保你的电脑拥有'''兼容你所需要运行的服务端'''的 Java 环境, (Windows) 为了方便请加入到'''系统环境变量'''中. | |||
(我推荐本地部署完毕后再上传至面板) | |||
获取与小游戏地图游戏版本'''相同'''的 Minecraft 服务端核心,移动至一个新文件夹里。新建一个'''文本文档''', 写入以下内容:<syntaxhighlight lang="bat" line="1"> | |||
java -jar server-core.jar nogui | |||
pause | |||
</syntaxhighlight>server-core.jar 为你的服务端核心, nogui 是为了禁用掉 Minecraft 在较新版本服务端核心中自带的图形化控制台. | |||
将文件类型改为 .bat 并运行。 | |||
此时文件夹内会生成一个 '''eula.txt''' 文件,你需要将里面的 eula 布尔值改为 '''true'''。 | |||
再次运行 bat 文件, 不出意外这次服务端将会正常启动. | |||
我们找到 server.properties 文件, 将部分配置改成下列所示:<syntaxhighlight lang="properties" line="1"> | |||
enable-command-block=true | |||
online-mode=false | |||
</syntaxhighlight>接着, 将文件夹内 world 文件夹删除, 并将你需要导入的小游戏地图文件夹名称改为 world 后导入。 | |||
=== 语音组件和全局语音组件(可选) === | |||
我推荐前往 [https://modrinth.com/plugin/simple-voice-chat/ Modrinth] 下载 '''Simple Voice Chat''' 的全类型全版本资源, 并将其加入到'''服务端'''文件夹的 '''mods / plugins''' 文件夹。 | |||
并将 '''voicechat-server.properties''' 中的 '''port''' 与 '''MCSM 面板'''中对应。 | |||
Fabric 端可使用 [https://modrinth.com/mod/enhanced-groups Simple Voice Chat Enhanced Groups] 实现全局语音 (仅 Fabric 可用) | |||
Forge 端请尝试 [https://modrinth.com/mod/connector Sinytra Connector] 来兼容上文的 Fabric 模组 | |||
对于支持 Bukkit 插件的服务端,可以参考以下代码自行构建一个插件并放入服务端的 plugins 文件夹中。<syntaxhighlight lang="java" line="1"> | |||
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; | |||
} | |||
} | |||
</syntaxhighlight><syntaxhighlight lang="java" line="1"> | |||
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秒执行,确保玩家已连接到语音服务器 | |||
} | |||
} | |||
</syntaxhighlight><syntaxhighlight lang="java" line="1"> | |||
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(); | |||
} | |||
} | |||
</syntaxhighlight>Simple Voice Chat 提供了它的 [https://modrepo.de/minecraft/voicechat/api/overview API 文档], 这方便我们基于它开发一些更有意思的拓展组件。 | |||
=== 皮肤恢复组件(可选) === | |||
[https://modrinth.com/plugin/skinsrestorer 皮肤恢复插件 (SkinRestorer)]: (较新的 MC 版本也支持模组服,服务端侧) | |||
[https://modrinth.com/mod/skinrestorer 皮肤恢复模组 (SkinRestorer)]: (服务端侧,个人客户端无需安装) | |||
<references /> | |||
2025年11月30日 (日) 13:40的最新版本
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): (服务端侧,个人客户端无需安装)