diff --git a/README.md b/README.md index 2964801..c1bba64 100644 --- a/README.md +++ b/README.md @@ -43,12 +43,14 @@ - `/seen` `(/info)` - `/tpsbar` - `/essc admin` 管理模式切换 +- `/maintenance` `(/maint)` 维护模式管理 ### 其它功能 - Shift + 右键快捷打开潜影盒 - 潜影盒交互保护,尽量避免刷物品、吞物品和嵌套放入问题 - 管理模式独立背包、装备栏与状态切换 +- 维护模式:替换 MOTD,并阻止无绕过权限的玩家进入 - Enderman 掉落方块控制 - JEI 配方同步修复 @@ -64,6 +66,7 @@ | `tpsbar` | 开启 | 插件版 TPSBar,仍受 `config.yml` 中 `tpsbar.mode` 控制 | | `jei-sync` | 开启 | Fabric / NeoForge JEI 配方同步修复 | | `mob-drops` | 关闭 | 末影人掉落控制,默认关闭以保留过去标准版行为 | +| `maintenance` | 开启 | 维护模式命令、MOTD 替换和登录拦截 | 修改模块开关后建议重启服务器,使命令注册表和监听器状态完全刷新。`/essc reload` 可以刷新配置和已注册命令的执行检查,但无法从 Bukkit 命令表中真正热移除或新增直连命令。 @@ -88,6 +91,12 @@ - 便捷菜单布局 - `modules.yml` - 功能模块开关 +- `maintenance.yml` + - 维护模式状态 + - 维护 MOTD + - 维护踢出提示 + - 维护 BossBar + - 绕过权限 - `lang/zh_CN.yml`、`lang/en_US.yml` - 命令反馈 - 帮助信息 @@ -143,8 +152,21 @@ Windows 可使用: ```bash ./gradlew shadowJar ./gradlew build +./gradlew deployToPaper12111 +./gradlew deployToPaper2612 ``` +## 本地测试服 + +项目包含两个本地测试服目录: + +| 测试服 | 端口 | 部署任务 | 启动脚本 | +| --- | --- | --- | --- | +| Paper 1.21.11 | `25566` | `deployToPaper12111` | `test-server/paper-1.21.11/start.bat` | +| Paper 26.1.2 | `25565` | `deployToPaper2612` | `test-server/paper-26.1.2/start.bat` | + +IDEA 运行配置会在启动测试服前自动执行对应部署任务。部署任务会替换 `EssentialsC*.jar`,并删除 `plugins/EssentialsC` 数据目录,以便测试新增默认配置和语言文本。 + ## 开发说明 - 使用 `paperweight-userdev` 进行 Paper 开发 diff --git a/build.gradle b/build.gradle index 4adf0a8..9849ee9 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ plugins { } group = 'cn.infstar' -version = '1.3.1' +version = '1.4.0' repositories { mavenCentral() @@ -55,3 +55,25 @@ tasks.named('shadowJar', ShadowJar).configure { tasks.named('assemble').configure { dependsOn(tasks.named('shadowJar')) } + +def registerTestServerDeployTask = { String taskName, String serverPath, String serverName -> + tasks.register(taskName, Copy) { + group = 'deployment' + description = "构建并部署插件到本地 ${serverName} 测试服务器。" + def artifact = tasks.named('shadowJar').flatMap { it.archiveFile } + def pluginsDir = layout.projectDirectory.dir("${serverPath}/plugins") + dependsOn(tasks.named('shadowJar')) + from(artifact) + into(pluginsDir) + + doFirst { + delete(fileTree(pluginsDir) { + include 'EssentialsC*.jar' + }) + delete(pluginsDir.file('EssentialsC').asFile) + } + } +} + +registerTestServerDeployTask('deployToPaper12111', 'test-server/paper-1.21.11', 'Paper 1.21.11') +registerTestServerDeployTask('deployToPaper2612', 'test-server/paper-26.1.2', 'Paper 26.1.2') diff --git a/src/main/java/cn/infstar/essentialsC/EssentialsC.java b/src/main/java/cn/infstar/essentialsC/EssentialsC.java index 436f103..2f5ec77 100644 --- a/src/main/java/cn/infstar/essentialsC/EssentialsC.java +++ b/src/main/java/cn/infstar/essentialsC/EssentialsC.java @@ -4,6 +4,8 @@ import cn.infstar.essentialsC.admin.AdminModeManager; import cn.infstar.essentialsC.commands.BaseCommand; import cn.infstar.essentialsC.commands.CommandRegistry; import cn.infstar.essentialsC.commands.HelpCommand; +import cn.infstar.essentialsC.maintenance.MaintenanceListener; +import cn.infstar.essentialsC.maintenance.MaintenanceManager; import cn.infstar.essentialsC.tpsbar.TpsBarService; import org.bukkit.Bukkit; import org.bukkit.command.Command; @@ -18,6 +20,7 @@ public final class EssentialsC extends JavaPlugin { private static LangManager langManager; private ModuleManager moduleManager; private AdminModeManager adminModeManager; + private MaintenanceManager maintenanceManager; private TpsBarService tpsBarManager; @Override @@ -30,6 +33,11 @@ public final class EssentialsC extends JavaPlugin { getServer().getPluginManager().registerEvents(adminModeManager, this); } + if (moduleManager.isEnabled(ModuleManager.MAINTENANCE)) { + maintenanceManager = new MaintenanceManager(this); + getServer().getPluginManager().registerEvents(new MaintenanceListener(this), this); + } + if (moduleManager.isEnabled(ModuleManager.TPSBAR)) { tpsBarManager = createOptionalService("cn.infstar.essentialsC.tpsbar.TpsBarManager", TpsBarService.class); } @@ -51,6 +59,9 @@ public final class EssentialsC extends JavaPlugin { if (adminModeManager != null) { adminModeManager.shutdown(); } + if (maintenanceManager != null) { + maintenanceManager.shutdown(); + } getLogger().info("EssentialsC 已禁用。"); } @@ -66,6 +77,10 @@ public final class EssentialsC extends JavaPlugin { return moduleManager; } + public MaintenanceManager getMaintenanceManager() { + return maintenanceManager; + } + public TpsBarService getTpsBarManager() { return tpsBarManager; } @@ -151,6 +166,7 @@ public final class EssentialsC extends JavaPlugin { } private void registerCommandWithAliases(org.bukkit.command.CommandMap commandMap, String name, BaseCommand executor, String... aliases) { + String fallbackPrefix = getName().toLowerCase(java.util.Locale.ROOT); Command command = new Command(name) { @Override public boolean execute(CommandSender sender, String commandLabel, String[] args) { @@ -171,7 +187,7 @@ public final class EssentialsC extends JavaPlugin { }; command.setPermission(executor.getPermission()); - commandMap.register("", command); + commandMap.register(fallbackPrefix, command); for (String alias : aliases) { Command aliasCmd = new Command(alias) { @@ -193,7 +209,7 @@ public final class EssentialsC extends JavaPlugin { } }; aliasCmd.setPermission(executor.getPermission()); - commandMap.register("", aliasCmd); + commandMap.register(fallbackPrefix, aliasCmd); } } } diff --git a/src/main/java/cn/infstar/essentialsC/ModuleManager.java b/src/main/java/cn/infstar/essentialsC/ModuleManager.java index 708b6d9..2a75911 100644 --- a/src/main/java/cn/infstar/essentialsC/ModuleManager.java +++ b/src/main/java/cn/infstar/essentialsC/ModuleManager.java @@ -19,6 +19,7 @@ public final class ModuleManager { public static final String TPSBAR = "tpsbar"; public static final String JEI_SYNC = "jei-sync"; public static final String MOB_DROPS = "mob-drops"; + public static final String MAINTENANCE = "maintenance"; private static final Map DEFAULT_MODULES = new LinkedHashMap<>(); @@ -29,6 +30,7 @@ public final class ModuleManager { DEFAULT_MODULES.put(TPSBAR, true); DEFAULT_MODULES.put(JEI_SYNC, true); DEFAULT_MODULES.put(MOB_DROPS, false); + DEFAULT_MODULES.put(MAINTENANCE, true); } private final JavaPlugin plugin; diff --git a/src/main/java/cn/infstar/essentialsC/commands/CommandRegistry.java b/src/main/java/cn/infstar/essentialsC/commands/CommandRegistry.java index c74b423..64d9e2c 100644 --- a/src/main/java/cn/infstar/essentialsC/commands/CommandRegistry.java +++ b/src/main/java/cn/infstar/essentialsC/commands/CommandRegistry.java @@ -42,6 +42,7 @@ public final class CommandRegistry { register("repair", "essentialsc.command.repair", ModuleManager.PLAYER, "cn.infstar.essentialsC.commands.RepairCommand", "rep"); register("tpsbar", "essentialsc.command.tpsbar", ModuleManager.TPSBAR, "cn.infstar.essentialsC.commands.TpsBarCommand"); register("mobdrops", "essentialsc.mobdrops.enderman", ModuleManager.MOB_DROPS, "cn.infstar.essentialsC.commands.MobDropCommand"); + register("maintenance", "essentialsc.command.maintenance", ModuleManager.MAINTENANCE, "cn.infstar.essentialsC.commands.MaintenanceCommand", "maint"); registerSubCommand("admin", "essentialsc.command.admin", ModuleManager.ADMIN_MODE, "cn.infstar.essentialsC.commands.AdminCommand"); } diff --git a/src/main/java/cn/infstar/essentialsC/commands/HelpCommand.java b/src/main/java/cn/infstar/essentialsC/commands/HelpCommand.java index f64fd49..507d8a6 100644 --- a/src/main/java/cn/infstar/essentialsC/commands/HelpCommand.java +++ b/src/main/java/cn/infstar/essentialsC/commands/HelpCommand.java @@ -37,6 +37,9 @@ public class HelpCommand extends BaseCommand implements TabCompleter { EssentialsC.getLangManager().reload(); plugin.getModuleManager().reload(); CommandRegistry.clearCache(); + if (plugin.getMaintenanceManager() != null && plugin.getModuleManager().isEnabled(ModuleManager.MAINTENANCE)) { + plugin.getMaintenanceManager().reload(); + } TpsBarService tpsBarService = plugin.getTpsBarManager(); if (tpsBarService != null) { if (plugin.getModuleManager().isEnabled(ModuleManager.TPSBAR)) { @@ -65,6 +68,9 @@ public class HelpCommand extends BaseCommand implements TabCompleter { EssentialsC.getLangManager().reload(); plugin.getModuleManager().reload(); CommandRegistry.clearCache(); + if (plugin.getMaintenanceManager() != null && plugin.getModuleManager().isEnabled(ModuleManager.MAINTENANCE)) { + plugin.getMaintenanceManager().reload(); + } TpsBarService tpsBarService = plugin.getTpsBarManager(); if (tpsBarService != null) { if (plugin.getModuleManager().isEnabled(ModuleManager.TPSBAR)) { @@ -201,6 +207,10 @@ public class HelpCommand extends BaseCommand implements TabCompleter { otherCommands.append(lang.getString("help.commands.tpsbar")).append("\n"); hasOtherCommands = true; } + if (CommandRegistry.isAvailable("maintenance") && player.hasPermission("essentialsc.command.maintenance")) { + otherCommands.append(lang.getString("help.commands.maintenance")).append("\n"); + hasOtherCommands = true; + } if (hasOtherCommands) { sendPrefixed(player, lang.getString("help.section-other")); @@ -272,6 +282,8 @@ public class HelpCommand extends BaseCommand implements TabCompleter { {"repair", "essentialsc.command.repair"}, {"rep", "essentialsc.command.repair"}, {"tpsbar", "essentialsc.command.tpsbar"}, + {"maintenance", "essentialsc.command.maintenance"}, + {"maint", "essentialsc.command.maintenance"}, {"mobdrops", "essentialsc.mobdrops.enderman"}, {"admin", "essentialsc.command.admin"}, {"version", null}, @@ -324,6 +336,11 @@ public class HelpCommand extends BaseCommand implements TabCompleter { } return players; } + + if ((subCmd.equals("maintenance") || subCmd.equals("maint")) + && sender.hasPermission("essentialsc.command.maintenance")) { + return completeMaintenanceArgs(args[1]); + } } return new ArrayList<>(); @@ -339,4 +356,15 @@ public class HelpCommand extends BaseCommand implements TabCompleter { } return completions; } + + private List completeMaintenanceArgs(String partialInput) { + List completions = new ArrayList<>(); + String partial = partialInput.toLowerCase(); + for (String option : List.of("on", "off", "status", "reload")) { + if (option.startsWith(partial)) { + completions.add(option); + } + } + return completions; + } } diff --git a/src/main/java/cn/infstar/essentialsC/commands/MaintenanceCommand.java b/src/main/java/cn/infstar/essentialsC/commands/MaintenanceCommand.java new file mode 100644 index 0000000..0bf633f --- /dev/null +++ b/src/main/java/cn/infstar/essentialsC/commands/MaintenanceCommand.java @@ -0,0 +1,86 @@ +package cn.infstar.essentialsC.commands; + +import cn.infstar.essentialsC.maintenance.MaintenanceManager; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + +public class MaintenanceCommand extends BaseCommand implements TabCompleter { + + public MaintenanceCommand() { + super("essentialsc.command.maintenance"); + } + + @Override + protected boolean execute(Player player, String[] args) { + return executeCommand(player, args); + } + + @Override + protected boolean executeConsole(CommandSender sender, String[] args) { + return executeCommand(sender, args); + } + + private boolean executeCommand(CommandSender sender, String[] args) { + MaintenanceManager maintenanceManager = plugin.getMaintenanceManager(); + if (maintenanceManager == null) { + sender.sendMessage(getLang().getPrefixedString("messages.module-disabled")); + return true; + } + + if (args.length == 0 || args[0].equalsIgnoreCase("status")) { + sendStatus(sender, maintenanceManager); + return true; + } + + switch (args[0].toLowerCase()) { + case "on", "enable", "enabled" -> { + maintenanceManager.setEnabled(true); + sender.sendMessage(getLang().getPrefixedString("maintenance.messages.enabled")); + return true; + } + case "off", "disable", "disabled" -> { + maintenanceManager.setEnabled(false); + sender.sendMessage(getLang().getPrefixedString("maintenance.messages.disabled")); + return true; + } + case "reload" -> { + maintenanceManager.reload(); + sender.sendMessage(getLang().getPrefixedString("maintenance.messages.reloaded")); + return true; + } + default -> { + sender.sendMessage(getLang().getPrefixedString("maintenance.messages.usage")); + return true; + } + } + } + + private void sendStatus(CommandSender sender, MaintenanceManager maintenanceManager) { + String status = getLang().getString(maintenanceManager.isEnabled() + ? "maintenance.status.enabled" + : "maintenance.status.disabled"); + sender.sendMessage(getLang().getPrefixedString("maintenance.messages.status", + java.util.Map.of("status", status))); + } + + @Override + public List onTabComplete(CommandSender sender, Command command, String label, String[] args) { + if (args.length != 1 || !sender.hasPermission(getPermission())) { + return List.of(); + } + + String partial = args[0].toLowerCase(); + List completions = new ArrayList<>(); + for (String option : List.of("on", "off", "status", "reload")) { + if (option.startsWith(partial)) { + completions.add(option); + } + } + return completions; + } +} diff --git a/src/main/java/cn/infstar/essentialsC/maintenance/MaintenanceListener.java b/src/main/java/cn/infstar/essentialsC/maintenance/MaintenanceListener.java new file mode 100644 index 0000000..ef6b716 --- /dev/null +++ b/src/main/java/cn/infstar/essentialsC/maintenance/MaintenanceListener.java @@ -0,0 +1,66 @@ +package cn.infstar.essentialsC.maintenance; + +import cn.infstar.essentialsC.EssentialsC; +import cn.infstar.essentialsC.ModuleManager; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.server.ServerListPingEvent; + +public final class MaintenanceListener implements Listener { + + private final EssentialsC plugin; + + public MaintenanceListener(EssentialsC plugin) { + this.plugin = plugin; + } + + @EventHandler + public void onServerListPing(ServerListPingEvent event) { + MaintenanceManager maintenanceManager = plugin.getMaintenanceManager(); + if (!plugin.getModuleManager().isEnabled(ModuleManager.MAINTENANCE) + || maintenanceManager == null + || !maintenanceManager.isEnabled() + || !maintenanceManager.isMotdEnabled()) { + return; + } + + event.setMotd(maintenanceManager.getMotd()); + } + + @EventHandler + public void onPlayerLogin(PlayerLoginEvent event) { + MaintenanceManager maintenanceManager = plugin.getMaintenanceManager(); + if (!plugin.getModuleManager().isEnabled(ModuleManager.MAINTENANCE) + || maintenanceManager == null + || !maintenanceManager.isEnabled()) { + return; + } + + if (event.getPlayer().hasPermission(maintenanceManager.getBypassPermission())) { + return; + } + + event.disallow(PlayerLoginEvent.Result.KICK_OTHER, maintenanceManager.getKickMessage()); + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + MaintenanceManager maintenanceManager = plugin.getMaintenanceManager(); + if (!plugin.getModuleManager().isEnabled(ModuleManager.MAINTENANCE) || maintenanceManager == null) { + return; + } + + maintenanceManager.addBossBarPlayer(event.getPlayer()); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + MaintenanceManager maintenanceManager = plugin.getMaintenanceManager(); + if (maintenanceManager != null) { + maintenanceManager.removeBossBarPlayer(event.getPlayer()); + } + } +} diff --git a/src/main/java/cn/infstar/essentialsC/maintenance/MaintenanceManager.java b/src/main/java/cn/infstar/essentialsC/maintenance/MaintenanceManager.java new file mode 100644 index 0000000..4967591 --- /dev/null +++ b/src/main/java/cn/infstar/essentialsC/maintenance/MaintenanceManager.java @@ -0,0 +1,178 @@ +package cn.infstar.essentialsC.maintenance; + +import cn.infstar.essentialsC.EssentialsC; +import org.bukkit.ChatColor; +import org.bukkit.boss.BarColor; +import org.bukkit.boss.BarStyle; +import org.bukkit.boss.BossBar; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Locale; + +public final class MaintenanceManager { + + private static final int CURRENT_CONFIG_VERSION = 1; + + private final EssentialsC plugin; + private final File configFile; + private FileConfiguration config; + private BossBar bossBar; + + public MaintenanceManager(EssentialsC plugin) { + this.plugin = plugin; + this.configFile = new File(plugin.getDataFolder(), "maintenance.yml"); + reload(); + } + + public void reload() { + if (!configFile.exists()) { + plugin.saveResource("maintenance.yml", false); + } + + config = YamlConfiguration.loadConfiguration(configFile); + config.addDefault("config-version", CURRENT_CONFIG_VERSION); + config.addDefault("enabled", false); + config.addDefault("bypass-permission", "essentialsc.maintenance.bypass"); + config.addDefault("motd.enabled", true); + config.addDefault("motd.lines", List.of("&c服务器维护中", "&7请稍后再试")); + config.addDefault("kick-message", List.of("&c服务器正在维护", "&7请稍后再进入")); + config.addDefault("bossbar.enabled", true); + config.addDefault("bossbar.title", "&c服务器正在维护"); + config.addDefault("bossbar.color", "RED"); + config.addDefault("bossbar.style", "SOLID"); + config.addDefault("bossbar.progress", 1.0D); + config.options().copyDefaults(true); + save(); + refreshBossBar(); + } + + public boolean isEnabled() { + return config.getBoolean("enabled", false); + } + + public void setEnabled(boolean enabled) { + config.set("enabled", enabled); + save(); + refreshBossBar(); + } + + public String getBypassPermission() { + return config.getString("bypass-permission", "essentialsc.maintenance.bypass"); + } + + public boolean isMotdEnabled() { + return config.getBoolean("motd.enabled", true); + } + + public String getMotd() { + return colorizeLines(config.getStringList("motd.lines")); + } + + public String getKickMessage() { + return colorizeLines(config.getStringList("kick-message")); + } + + public void refreshBossBar() { + clearBossBar(); + if (!isEnabled() || !isBossBarEnabled()) { + return; + } + + bossBar = plugin.getServer().createBossBar( + colorize(config.getString("bossbar.title", "&c服务器正在维护")), + readBossBarColor(), + readBossBarStyle() + ); + bossBar.setProgress(readBossBarProgress()); + bossBar.setVisible(true); + + for (Player player : plugin.getServer().getOnlinePlayers()) { + addBossBarPlayer(player); + } + } + + public void addBossBarPlayer(Player player) { + if (bossBar == null || player == null || !player.isOnline()) { + return; + } + if (player.hasPermission(getBypassPermission())) { + bossBar.removePlayer(player); + return; + } + bossBar.addPlayer(player); + } + + public void removeBossBarPlayer(Player player) { + if (bossBar != null && player != null) { + bossBar.removePlayer(player); + } + } + + public void shutdown() { + clearBossBar(); + } + + private void clearBossBar() { + if (bossBar == null) { + return; + } + + bossBar.removeAll(); + bossBar = null; + } + + private boolean isBossBarEnabled() { + return config.getBoolean("bossbar.enabled", true); + } + + private BarColor readBossBarColor() { + try { + return BarColor.valueOf(config.getString("bossbar.color", "RED").toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException ignored) { + return BarColor.RED; + } + } + + private BarStyle readBossBarStyle() { + try { + return BarStyle.valueOf(config.getString("bossbar.style", "SOLID").toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException ignored) { + return BarStyle.SOLID; + } + } + + private double readBossBarProgress() { + double progress = config.getDouble("bossbar.progress", 1.0D); + if (!Double.isFinite(progress)) { + return 1.0D; + } + return Math.max(0.0D, Math.min(1.0D, progress)); + } + + private String colorizeLines(List lines) { + if (lines == null || lines.isEmpty()) { + return ""; + } + + return String.join("\n", lines.stream() + .map(this::colorize) + .toList()); + } + + private String colorize(String text) { + return ChatColor.translateAlternateColorCodes('&', text == null ? "" : text); + } + + private void save() { + try { + config.save(configFile); + } catch (IOException e) { + plugin.getLogger().warning("保存 maintenance.yml 失败: " + e.getMessage()); + } + } +} diff --git a/src/main/resources/lang/en_US.yml b/src/main/resources/lang/en_US.yml index 2048541..84f1b82 100644 --- a/src/main/resources/lang/en_US.yml +++ b/src/main/resources/lang/en_US.yml @@ -84,6 +84,7 @@ help: repair: " &f/repair &7- Repair held or all items" admin: " &f/essc admin &7- Toggle admin mode" tpsbar: " &f/tpsbar [player] &7- Toggle TPS boss bar" + maintenance: " &f/maintenance &7- Manage maintenance mode" blocks-menu: title: "&6&lEssentialsC &8- &e&lShortcut Menu" @@ -170,3 +171,14 @@ mobdrops-menu: name: "&dEnderman Drops" status: "&7Current status: {status}" toggle: "&eClick to toggle" + +maintenance: + status: + enabled: "&cEnabled" + disabled: "&aDisabled" + messages: + enabled: "&aMaintenance mode enabled." + disabled: "&cMaintenance mode disabled." + reloaded: "&aMaintenance configuration reloaded." + status: "&7Maintenance mode status: {status}" + usage: "&cUsage: /maintenance " diff --git a/src/main/resources/lang/zh_CN.yml b/src/main/resources/lang/zh_CN.yml index ec42e07..bc6c2b5 100644 --- a/src/main/resources/lang/zh_CN.yml +++ b/src/main/resources/lang/zh_CN.yml @@ -84,6 +84,7 @@ help: repair: " &f/repair &7- 修复手中或全部物品" admin: " &f/essc admin &7- 切换管理模式" tpsbar: " &f/tpsbar [玩家] &7- 切换 TPS 状态栏" + maintenance: " &f/maintenance &7- 管理维护模式" blocks-menu: title: "&6&lEssentialsC &8- &e&l便捷菜单" @@ -170,3 +171,14 @@ mobdrops-menu: name: "&d末影人掉落" status: "&7当前状态:{status}" toggle: "&e点击切换" + +maintenance: + status: + enabled: "&c开启" + disabled: "&a关闭" + messages: + enabled: "&a维护模式已开启。" + disabled: "&c维护模式已关闭。" + reloaded: "&a维护模式配置已重载。" + status: "&7维护模式当前状态:{status}" + usage: "&c用法:/maintenance " diff --git a/src/main/resources/maintenance.yml b/src/main/resources/maintenance.yml new file mode 100644 index 0000000..cb0be1d --- /dev/null +++ b/src/main/resources/maintenance.yml @@ -0,0 +1,31 @@ +# EssentialsC 维护模式配置 + +config-version: 1 + +# 是否开启维护模式。 +enabled: false + +# 拥有该权限的玩家可以在维护模式下进入服务器。 +bypass-permission: "essentialsc.maintenance.bypass" + +motd: + # 维护模式开启时是否替换服务器列表 MOTD。 + enabled: true + lines: + - "&c服务器维护中" + - "&7请稍后再试" + +kick-message: + - "&c服务器正在维护" + - "&7请稍后再进入" + +bossbar: + # 维护模式开启时是否向无绕过权限的在线玩家显示 BossBar。 + enabled: true + title: "&c服务器正在维护" + # 可选值:PINK / BLUE / RED / GREEN / YELLOW / PURPLE / WHITE + color: RED + # 可选值:SOLID / SEGMENTED_6 / SEGMENTED_10 / SEGMENTED_12 / SEGMENTED_20 + style: SOLID + # 进度范围:0.0 - 1.0 + progress: 1.0 diff --git a/src/main/resources/modules.yml b/src/main/resources/modules.yml index 1ca22c6..065bbd0 100644 --- a/src/main/resources/modules.yml +++ b/src/main/resources/modules.yml @@ -26,3 +26,6 @@ modules: mob-drops: # 末影人掉落控制菜单和监听器。默认关闭,用于保留过去标准版的行为。 enabled: false + maintenance: + # 维护模式。开启维护后可替换 MOTD,并阻止无绕过权限的玩家进入。 + enabled: true diff --git a/src/main/resources/paper-plugin.yml b/src/main/resources/paper-plugin.yml index f7e2184..0cd381c 100644 --- a/src/main/resources/paper-plugin.yml +++ b/src/main/resources/paper-plugin.yml @@ -92,6 +92,12 @@ permissions: essentialsc.command.tpsbar.others: description: 允许为其他玩家切换 /tpsbar default: op + essentialsc.command.maintenance: + description: 允许管理维护模式 + default: op + essentialsc.maintenance.bypass: + description: 允许在维护模式下进入服务器 + default: op essentialsc.shulkerbox.open: description: 允许通过 Shift+右键快捷打开潜影盒 default: op @@ -129,5 +135,7 @@ permissions: essentialsc.command.reload: true essentialsc.command.tpsbar: true essentialsc.command.tpsbar.others: true + essentialsc.command.maintenance: true + essentialsc.maintenance.bypass: true essentialsc.shulkerbox.open: true essentialsc.mobdrops.enderman: true