diff --git a/Maintenance-API.jar b/Maintenance-API.jar index aa766f22..b92bfd05 100644 Binary files a/Maintenance-API.jar and b/Maintenance-API.jar differ diff --git a/Maintenance-API/pom.xml b/Maintenance-API/pom.xml index 34728b3a..03c9c714 100644 --- a/Maintenance-API/pom.xml +++ b/Maintenance-API/pom.xml @@ -6,7 +6,7 @@ maintenance-base eu.kennytv - 2.4 + 2.5 maintenance-api @@ -22,7 +22,7 @@ org.spigotmc spigot-api - 1.12.2-R0.1-SNAPSHOT + 1.13.2-R0.1-SNAPSHOT provided diff --git a/Maintenance-API/src/main/java/eu/kennytv/maintenance/api/bungee/IMaintenanceBungee.java b/Maintenance-API/src/main/java/eu/kennytv/maintenance/api/bungee/IMaintenanceBungee.java new file mode 100644 index 00000000..6d5f80c7 --- /dev/null +++ b/Maintenance-API/src/main/java/eu/kennytv/maintenance/api/bungee/IMaintenanceBungee.java @@ -0,0 +1,30 @@ +package eu.kennytv.maintenance.api.bungee; + +import eu.kennytv.maintenance.api.IMaintenance; +import net.md_5.bungee.api.config.ServerInfo; + +/** + * @author KennyTV + * @since 2.5 + */ +public interface IMaintenanceBungee extends IMaintenance { + + /** + * Enables/disables maintenance mode on a proxied server. + * If enabled, all non-permitted players will be kicked. + * If MySQL is enabled, it will also be written into the database. + * + * @param maintenance true to enable, false to disable maintenance mode + */ + boolean setMaintenanceToServer(ServerInfo server, boolean maintenance); + + /** + * @return true if maintenance is currently enabled on the proxied server + */ + boolean isMaintenance(ServerInfo server); + + /** + * @return true if a start- or endtimer task is currently running regarding the proxied server + */ + boolean isServerTaskRunning(ServerInfo server); +} diff --git a/Maintenance-API/src/main/java/eu/kennytv/maintenance/api/MaintenanceBungeeAPI.java b/Maintenance-API/src/main/java/eu/kennytv/maintenance/api/bungee/MaintenanceBungeeAPI.java similarity index 59% rename from Maintenance-API/src/main/java/eu/kennytv/maintenance/api/MaintenanceBungeeAPI.java rename to Maintenance-API/src/main/java/eu/kennytv/maintenance/api/bungee/MaintenanceBungeeAPI.java index a98948ff..0c692b7e 100644 --- a/Maintenance-API/src/main/java/eu/kennytv/maintenance/api/MaintenanceBungeeAPI.java +++ b/Maintenance-API/src/main/java/eu/kennytv/maintenance/api/bungee/MaintenanceBungeeAPI.java @@ -1,29 +1,29 @@ -package eu.kennytv.maintenance.api; +package eu.kennytv.maintenance.api.bungee; +import eu.kennytv.maintenance.api.IMaintenanceBase; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.plugin.Plugin; /** - * Utility class to get the {@link IMaintenance} instance for the BungeeCord version of the plugin. + * Utility class to get the {@link IMaintenanceBungee} instance for the BungeeCord version of the plugin. *

* Only access this class if you're running the plugin on a BungeeCord server! *

* * @author KennyTV - * @since 2.1 + * @since 2.5 */ public final class MaintenanceBungeeAPI { /** * Returns API instance of IMaintenance. * - * @return {@link IMaintenance} instance + * @return {@link IMaintenanceBungee} instance */ - public static IMaintenance getAPI() { + public static IMaintenanceBungee getAPI() { final Plugin maintenance = ProxyServer.getInstance().getPluginManager().getPlugin("MaintenanceBungee"); if (maintenance == null) ProxyServer.getInstance().getLogger().warning("Could not get instance of MaintenanceBungee!"); - - return ((IMaintenanceBase) maintenance).getApi(); + return (IMaintenanceBungee) ((IMaintenanceBase) maintenance).getApi(); } } diff --git a/Maintenance-API/src/main/java/eu/kennytv/maintenance/api/MaintenanceSpigotAPI.java b/Maintenance-API/src/main/java/eu/kennytv/maintenance/api/spigot/MaintenanceSpigotAPI.java similarity index 82% rename from Maintenance-API/src/main/java/eu/kennytv/maintenance/api/MaintenanceSpigotAPI.java rename to Maintenance-API/src/main/java/eu/kennytv/maintenance/api/spigot/MaintenanceSpigotAPI.java index 6586861b..83800719 100644 --- a/Maintenance-API/src/main/java/eu/kennytv/maintenance/api/MaintenanceSpigotAPI.java +++ b/Maintenance-API/src/main/java/eu/kennytv/maintenance/api/spigot/MaintenanceSpigotAPI.java @@ -1,5 +1,7 @@ -package eu.kennytv.maintenance.api; +package eu.kennytv.maintenance.api.spigot; +import eu.kennytv.maintenance.api.IMaintenance; +import eu.kennytv.maintenance.api.IMaintenanceBase; import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; @@ -10,7 +12,7 @@ *

* * @author KennyTV - * @since 2.1 + * @since 2.5 */ public final class MaintenanceSpigotAPI { @@ -23,7 +25,6 @@ public static IMaintenance getAPI() { final Plugin maintenance = Bukkit.getPluginManager().getPlugin("MaintenanceSpigot"); if (maintenance == null) Bukkit.getLogger().warning("Could not get instance of MaintenanceSpigot!"); - return ((IMaintenanceBase) maintenance).getApi(); } } diff --git a/Maintenance-Bungee/pom.xml b/Maintenance-Bungee/pom.xml index 90c2e9a3..2608821d 100644 --- a/Maintenance-Bungee/pom.xml +++ b/Maintenance-Bungee/pom.xml @@ -6,7 +6,7 @@ maintenance-base eu.kennytv - 2.4 + 2.5 maintenance-bungee diff --git a/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/MaintenanceBungeePlugin.java b/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/MaintenanceBungeePlugin.java index fbd6f328..33d20c39 100644 --- a/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/MaintenanceBungeePlugin.java +++ b/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/MaintenanceBungeePlugin.java @@ -2,39 +2,52 @@ import eu.kennytv.maintenance.api.IMaintenance; import eu.kennytv.maintenance.api.ISettings; -import eu.kennytv.maintenance.api.MaintenanceBungeeAPI; +import eu.kennytv.maintenance.api.bungee.IMaintenanceBungee; +import eu.kennytv.maintenance.api.bungee.MaintenanceBungeeAPI; import eu.kennytv.maintenance.bungee.command.MaintenanceBungeeCommand; import eu.kennytv.maintenance.bungee.command.MaintenanceBungeeCommandBase; import eu.kennytv.maintenance.bungee.listener.PostLoginListener; +import eu.kennytv.maintenance.bungee.listener.ServerConnectListener; import eu.kennytv.maintenance.bungee.metrics.MetricsLite; +import eu.kennytv.maintenance.bungee.runnable.SingleMaintenanceRunnable; import eu.kennytv.maintenance.core.MaintenanceModePlugin; +import eu.kennytv.maintenance.core.Settings; import eu.kennytv.maintenance.core.hook.ServerListPlusHook; +import eu.kennytv.maintenance.core.runnable.MaintenanceRunnableBase; +import eu.kennytv.maintenance.core.util.ServerType; import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.plugin.Plugin; import net.md_5.bungee.api.plugin.PluginManager; import net.minecrell.serverlistplus.core.plugin.ServerListPlusPlugin; import java.io.File; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; /** * @author KennyTV * @since 1.0 */ -public final class MaintenanceBungeePlugin extends MaintenanceModePlugin { +public final class MaintenanceBungeePlugin extends MaintenanceModePlugin implements IMaintenanceBungee { private final MaintenanceBungeeBase plugin; private final SettingsBungee settings; + private final Map serverTaskIds = new HashMap<>(); MaintenanceBungeePlugin(final MaintenanceBungeeBase plugin) { - super("§8[§eMaintenanceBungee§8] ", plugin.getDescription().getVersion()); + super("§8[§eMaintenanceBungee§8] ", plugin.getDescription().getVersion(), ServerType.BUNGEE); this.plugin = plugin; plugin.getLogger().info("Plugin by KennyTV"); + plugin.getLogger().info(getUpdateMessage()); settings = new SettingsBungee(this, plugin); final PluginManager pm = getProxy().getPluginManager(); pm.registerListener(plugin, new PostLoginListener(this, settings)); + pm.registerListener(plugin, new ServerConnectListener(this, settings)); final MaintenanceBungeeCommand maintenanceCommand = new MaintenanceBungeeCommand(this, settings); pm.registerCommand(plugin, new MaintenanceBungeeCommandBase(maintenanceCommand)); @@ -61,7 +74,6 @@ public void setMaintenance(final boolean maintenance) { } serverActions(maintenance); - if (isTaskRunning()) cancelTask(); } @@ -80,10 +92,63 @@ void serverActions(final boolean maintenance) { } @Override - public int startMaintenanceRunnable(final Runnable runnable) { + public boolean isMaintenance(final ServerInfo server) { + return settings.getMaintenanceServers().contains(server.getName()); + } + + @Override + public boolean setMaintenanceToServer(final ServerInfo server, final boolean maintenance) { + if (maintenance) { + if (!settings.getMaintenanceServers().add(server.getName())) return false; + + final ServerInfo fallback = getProxy().getServerInfo(settings.getFallbackServer()); + if (fallback == null) + plugin.getLogger().warning("The fallback server set in the SpigotServers.yml could not be found! Instead kicking players from that server off the network!"); + else if (fallback.equals(server)) + plugin.getLogger().warning("Maintenance has been enabled on the fallback server! If a player joins on a proxied server, they will be kicked completely instead of being sent to the fallback server!"); + server.getPlayers().forEach(p -> { + if (!p.hasPermission("maintenance.bypass") && !settings.getWhitelistedPlayers().containsKey(p.getUniqueId())) { + if (fallback != null && fallback.canAccess(p)) { + p.sendMessage(settings.getMessage("singleMaintenanceActivated").replace("%SERVER%", server.getName())); + p.connect(fallback); + } else + p.disconnect(settings.getMessage("singleMaintenanceKickComplete").replace("%NEWLINE%", "\n").replace("%SERVER%", server.getName())); + } else { + p.sendMessage(settings.getMessage("singleMaintenanceActivated").replace("%SERVER%", server.getName())); + } + }); + } else { + if (!settings.getMaintenanceServers().remove(server.getName())) return false; + server.getPlayers().forEach(p -> p.sendMessage(settings.getMessage("singleMaintenanceDeactivated").replace("%SERVER%", server.getName()))); + } + + /*if (mySQL != null) { + mySQL.executeUpdate(serversQuery, "spigotServers-with-maintenance", maintenanceServers, maintenanceServers); + } else { + spigotServers.set("maintenance-on", maintenanceServers); + saveSpigotServers(); + }*/ + cancelSingleTask(server); + settings.saveServersToConfig(); + return true; + } + + @Override + public boolean isServerTaskRunning(final ServerInfo server) { + return serverTaskIds.containsKey(server.getName()); + } + + @Override + protected int startMaintenanceRunnable(final Runnable runnable) { return getProxy().getScheduler().schedule(plugin, runnable, 0, 1, TimeUnit.SECONDS).getId(); } + public MaintenanceRunnableBase startSingleMaintenanceRunnable(final ServerInfo server, final int minutes, final boolean enable) { + final MaintenanceRunnableBase runnable = new SingleMaintenanceRunnable(this, (Settings) getSettings(), minutes, enable, server); + serverTaskIds.put(server.getName(), getProxy().getScheduler().schedule(plugin, runnable, 0, 1, TimeUnit.SECONDS).getId()); + return runnable; + } + @Override public void async(final Runnable runnable) { getProxy().getScheduler().runAsync(plugin, runnable); @@ -96,6 +161,12 @@ public void cancelTask() { taskId = 0; } + public void cancelSingleTask(final ServerInfo server) { + final Integer task = serverTaskIds.remove(server.getName()); + if (task != null) + getProxy().getScheduler().cancel(task); + } + @Override public ISettings getSettings() { return settings; @@ -119,4 +190,8 @@ public static IMaintenance getAPI() { public ProxyServer getProxy() { return plugin.getProxy(); } + + public Logger getLogger() { + return plugin.getLogger(); + } } \ No newline at end of file diff --git a/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/SettingsBungee.java b/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/SettingsBungee.java index 7f14169e..55edd438 100644 --- a/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/SettingsBungee.java +++ b/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/SettingsBungee.java @@ -13,20 +13,23 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.sql.SQLException; -import java.util.List; -import java.util.UUID; +import java.util.*; public final class SettingsBungee extends Settings { private final String updateQuery; private final String maintenanceQuery; + //private final String serversQuery; private final MySQL mySQL; private final MaintenanceBungeePlugin maintenancePlugin; private final MaintenanceBungeeBase plugin; private final IPingListener pingListener; + private Set maintenanceServers; private Configuration config; private Configuration language; private Configuration whitelist; + private Configuration spigotServers; + private String fallbackServer; private long millisecondsToCheck; private long lastMySQLCheck; @@ -44,9 +47,8 @@ public final class SettingsBungee extends Settings { if (!plugin.getDataFolder().exists()) plugin.getDataFolder().mkdirs(); createFile("bungee-config.yml"); - createFile("language.yml"); createFile("WhitelistedPlayers.yml"); - + createFile("SpigotServers.yml"); reloadConfigs(); final Configuration mySQLSection = config.getSection("mysql"); @@ -63,11 +65,13 @@ public final class SettingsBungee extends Settings { mySQL.executeUpdate("CREATE TABLE IF NOT EXISTS " + mySQLTable + " (setting VARCHAR(16) PRIMARY KEY, value VARCHAR(255))"); updateQuery = "INSERT INTO " + mySQLTable + " (setting, value) VALUES (?, ?) ON DUPLICATE KEY UPDATE value = ?"; maintenanceQuery = "SELECT * FROM " + mySQLTable + " WHERE setting = ?"; + //serversQuery = "INSERT INTO " + serversTable + " (setting, value) VALUES (?, ?) ON DUPLICATE KEY UPDATE value = ?"; plugin.getLogger().info("Done!"); } else { mySQL = null; updateQuery = null; maintenanceQuery = null; + //serversQuery = null; } } @@ -97,14 +101,37 @@ public void reloadConfigs() { try { config = YamlConfiguration.getProvider(YamlConfiguration.class) .load(new InputStreamReader(new FileInputStream(new File(plugin.getDataFolder(), "bungee-config.yml")), StandardCharsets.UTF_8)); - language = YamlConfiguration.getProvider(YamlConfiguration.class) - .load(new InputStreamReader(new FileInputStream(new File(plugin.getDataFolder(), "language.yml")), StandardCharsets.UTF_8)); whitelist = YamlConfiguration.getProvider(YamlConfiguration.class).load(new File(plugin.getDataFolder(), "WhitelistedPlayers.yml")); + spigotServers = YamlConfiguration.getProvider(YamlConfiguration.class).load(new File(plugin.getDataFolder(), "spigotServers.yml")); } catch (final IOException e) { throw new RuntimeException("Unable to load Maintenance files!", e); } loadSettings(); + createAndLoadLanguageFile(); + } + + private void createAndLoadLanguageFile() { + final File file = new File(plugin.getDataFolder(), "language-" + getLanguage() + ".yml"); + if (!file.exists()) { + try (final InputStream in = plugin.getResourceAsStream("language-" + getLanguage() + ".yml")) { + Files.copy(in, file.toPath()); + } catch (final IOException | NullPointerException e) { + plugin.getLogger().warning("Unable to provide language " + getLanguage()); + if (!languageName.equals("en")) { + plugin.getLogger().warning("Falling back to default language: en"); + languageName = "en"; + createAndLoadLanguageFile(); + return; + } + } + } + try { + language = YamlConfiguration.getProvider(YamlConfiguration.class) + .load(new InputStreamReader(new FileInputStream(new File(plugin.getDataFolder(), "language-" + getLanguage() + ".yml")), StandardCharsets.UTF_8)); + } catch (final IOException e) { + throw new RuntimeException("Unable to load Maintenance language file!", e); + } } @Override @@ -119,11 +146,19 @@ public void saveConfig() { @Override public void saveWhitelistedPlayers() { - final File file = new File(plugin.getDataFolder(), "WhitelistedPlayers.yml"); + saveFile(whitelist, "WhitelistedPlayers.yml"); + } + + public void saveSpigotServers() { + saveFile(spigotServers, "SpigotServers.yml"); + } + + private void saveFile(final Configuration config, final String name) { + final File file = new File(plugin.getDataFolder(), name); try { - YamlConfiguration.getProvider(YamlConfiguration.class).save(whitelist, file); + YamlConfiguration.getProvider(YamlConfiguration.class).save(config, file); } catch (final IOException e) { - throw new RuntimeException("Unable to save WhitelistedPlayers.yml!", e); + throw new RuntimeException("Unable to save " + name + "!", e); } } @@ -131,11 +166,18 @@ public void saveWhitelistedPlayers() { public void loadExtraSettings() { whitelistedPlayers.clear(); whitelist.getKeys().forEach(key -> whitelistedPlayers.put(UUID.fromString(key), whitelist.getString(key))); + fallbackServer = spigotServers.getString("fallback", "hub"); if (mySQL != null) { final long configValue = config.getInt("mysql.update-interval"); millisecondsToCheck = configValue > 0 ? configValue * 1000 : -1; lastMySQLCheck = 0; - } + }/* else { + final List list = spigotServers.getStringList("maintenance-on"); + maintenanceServers = list == null ? new HashSet<>() : new HashSet<>(list); + }*/ + + final List list = spigotServers.getStringList("maintenance-on"); + maintenanceServers = list == null ? new HashSet<>() : new HashSet<>(list); } @Override @@ -213,7 +255,6 @@ public boolean isMaintenance() { if (millisecondsToCheck != -1) lastMySQLCheck = System.currentTimeMillis(); } - return maintenance; } @@ -235,4 +276,17 @@ public void setMaintenanceToSQL(final boolean maintenance) { public MySQL getMySQL() { return mySQL; } + + public Set getMaintenanceServers() { + return maintenanceServers; + } + + public void saveServersToConfig() { + spigotServers.set("maintenance-on", new ArrayList<>(maintenanceServers)); + saveSpigotServers(); + } + + public String getFallbackServer() { + return fallbackServer; + } } diff --git a/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/command/MaintenanceBungeeCommand.java b/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/command/MaintenanceBungeeCommand.java index 14fbdd3e..7c2b8908 100644 --- a/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/command/MaintenanceBungeeCommand.java +++ b/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/command/MaintenanceBungeeCommand.java @@ -4,22 +4,27 @@ import eu.kennytv.maintenance.bungee.SettingsBungee; import eu.kennytv.maintenance.bungee.util.ProxiedSenderInfo; import eu.kennytv.maintenance.core.command.MaintenanceCommand; +import eu.kennytv.maintenance.core.runnable.MaintenanceRunnableBase; import eu.kennytv.maintenance.core.util.SenderInfo; -import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.HoverEvent; import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.connection.ProxiedPlayer; public final class MaintenanceBungeeCommand extends MaintenanceCommand { + private final MaintenanceBungeePlugin plugin; + private final SettingsBungee settingsBungee; public MaintenanceBungeeCommand(final MaintenanceBungeePlugin plugin, final SettingsBungee settings) { super(plugin, settings, "MaintenanceBungee"); + this.plugin = plugin; + settingsBungee = settings; } @Override protected void addPlayerToWhitelist(final SenderInfo sender, final String name) { - final ProxiedPlayer selected = ProxyServer.getInstance().getPlayer(name); + final ProxiedPlayer selected = plugin.getProxy().getPlayer(name); if (selected == null) { sender.sendMessage(settings.getMessage("playerNotOnline")); return; @@ -33,7 +38,7 @@ protected void addPlayerToWhitelist(final SenderInfo sender, final String name) @Override protected void removePlayerFromWhitelist(final SenderInfo sender, final String name) { - final ProxiedPlayer selected = ProxyServer.getInstance().getPlayer(name); + final ProxiedPlayer selected = plugin.getProxy().getPlayer(name); if (selected == null) { if (settings.removeWhitelistedPlayer(name)) sender.sendMessage(settings.getMessage("whitelistRemoved").replace("%PLAYER%", name)); @@ -63,4 +68,94 @@ protected void checkForUpdate(final SenderInfo sender) { } else sender.sendMessage(plugin.getPrefix() + "§aYou already have the latest version of the plugin!"); } + + @Override + protected void handleToggleServerCommand(final SenderInfo sender, final String args[]) { + final ServerInfo server = plugin.getProxy().getServerInfo(args[1]); + if (server == null) { + sender.sendMessage(settings.getMessage("serverNotFound")); + return; + } + + final boolean maintenance = args[0].equalsIgnoreCase("on"); + if (maintenance == settingsBungee.getMaintenanceServers().contains(server.getName())) { + sender.sendMessage(settings.getMessage(maintenance ? "alreadyEnabled" : "alreadyDisabled")); + return; + } + + if (!plugin.setMaintenanceToServer(server, maintenance)) + sender.sendMessage(settings.getMessage(maintenance ? "singleServerAlreadyEnabled" : "singleServerAlreadyDisabled")); + else if (!plugin.getProxy().getPlayer(sender.getUuid()).getServer().getInfo().equals(server)) + sender.sendMessage(settings.getMessage(maintenance ? "singleMaintenanceActivated" : "singleMaintenanceDeactivated").replace("%SERVER%", server.getName())); + } + + @Override + protected void handleTimerServerCommands(final SenderInfo sender, final String args[]) { + if (args[0].equalsIgnoreCase("endtimer")) { + if (checkPermission(sender, "servertimer")) return; + if (checkTimerArgs(sender, args[2], "singleEndtimerUsage")) return; + + final ServerInfo server = checkSingleTimerArgs(sender, args); + if (server == null) return; + if (!plugin.isMaintenance(server)) { + sender.sendMessage(settings.getMessage("singleServerAlreadyDisabled").replace("%SERVER%", server.getName())); + return; + } + final MaintenanceRunnableBase runnable = plugin.startSingleMaintenanceRunnable(server, Integer.parseInt(args[2]), false); + sender.sendMessage(settings.getMessage("endtimerStarted").replace("%TIME%", runnable.getTime())); + } else if (args[0].equalsIgnoreCase("starttimer")) { + if (checkPermission(sender, "servertimer")) return; + if (checkTimerArgs(sender, args[2], "singleStarttimerUsage")) return; + + final ServerInfo server = checkSingleTimerArgs(sender, args); + if (server == null) return; + if (plugin.isMaintenance(server)) { + sender.sendMessage(settings.getMessage("singleServerAlreadyEnabled").replace("%SERVER%", server.getName())); + return; + } + + final MaintenanceRunnableBase runnable = plugin.startSingleMaintenanceRunnable(server, Integer.parseInt(args[2]), true); + sender.sendMessage(settings.getMessage("starttimerStarted").replace("%TIME%", runnable.getTime())); + } else if (args[0].equalsIgnoreCase("timer")) { + if (args[1].equalsIgnoreCase("abort") || args[1].equalsIgnoreCase("stop") || args[1].equalsIgnoreCase("cancel")) { + if (checkPermission(sender, "servertimer")) return; + final ServerInfo server = plugin.getProxy().getServerInfo(args[2]); + if (server == null) { + sender.sendMessage(settings.getMessage("serverNotFound")); + return; + } + if (!plugin.isServerTaskRunning(server)) { + sender.sendMessage(settings.getMessage("timerNotRunning")); + return; + } + + plugin.cancelSingleTask(server); + sender.sendMessage(settings.getMessage("timerCancelled")); + } else + sendUsage(sender); + } + } + + @Override + protected void showMaintenanceStatus(final SenderInfo sender) { + if (settingsBungee.getMaintenanceServers().isEmpty()) { + sender.sendMessage(settings.getMessage("singleServerMaintenanceListEmpty")); + } else { + sender.sendMessage(settings.getMessage("singleServerMaintenanceList")); + settingsBungee.getMaintenanceServers().forEach(server -> sender.sendMessage("§8- §b" + server)); + } + } + + private ServerInfo checkSingleTimerArgs(final SenderInfo sender, final String[] args) { + final ServerInfo server = plugin.getProxy().getServerInfo(args[1]); + if (server == null) { + sender.sendMessage(settings.getMessage("serverNotFound")); + return null; + } + if (plugin.isServerTaskRunning(server)) { + sender.sendMessage(settings.getMessage("timerAlreadyRunning")); + return null; + } + return server; + } } diff --git a/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/listener/PostLoginListener.java b/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/listener/PostLoginListener.java index 2afe3c39..85ce44be 100644 --- a/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/listener/PostLoginListener.java +++ b/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/listener/PostLoginListener.java @@ -1,6 +1,5 @@ package eu.kennytv.maintenance.bungee.listener; -import com.google.common.collect.Sets; import eu.kennytv.maintenance.bungee.MaintenanceBungeePlugin; import eu.kennytv.maintenance.bungee.SettingsBungee; import net.md_5.bungee.api.chat.ClickEvent; @@ -13,13 +12,14 @@ import net.md_5.bungee.event.EventHandler; import net.md_5.bungee.event.EventPriority; +import java.util.HashSet; import java.util.Set; import java.util.UUID; public final class PostLoginListener implements Listener { private final MaintenanceBungeePlugin plugin; private final SettingsBungee settings; - private final Set notifiedPlayers = Sets.newHashSet(); + private final Set notifiedPlayers = new HashSet<>(); public PostLoginListener(final MaintenanceBungeePlugin plugin, final SettingsBungee settings) { this.plugin = plugin; diff --git a/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/listener/ServerConnectListener.java b/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/listener/ServerConnectListener.java new file mode 100644 index 00000000..e88d46cc --- /dev/null +++ b/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/listener/ServerConnectListener.java @@ -0,0 +1,53 @@ +package eu.kennytv.maintenance.bungee.listener; + +import eu.kennytv.maintenance.bungee.MaintenanceBungeePlugin; +import eu.kennytv.maintenance.bungee.SettingsBungee; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.event.ServerConnectEvent; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.event.EventHandler; +import net.md_5.bungee.event.EventPriority; + +public final class ServerConnectListener implements Listener { + private final MaintenanceBungeePlugin plugin; + private final SettingsBungee settings; + private boolean warned; + + public ServerConnectListener(final MaintenanceBungeePlugin plugin, final SettingsBungee settings) { + this.plugin = plugin; + this.settings = settings; + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void serverConnect(final ServerConnectEvent event) { + final ProxiedPlayer p = event.getPlayer(); + final ServerInfo target = event.getTarget(); + if (!settings.getMaintenanceServers().contains(target.getName())) return; + if (p.hasPermission("maintenance.bypass") || settings.getWhitelistedPlayers().containsKey(p.getUniqueId())) + return; + + event.setCancelled(true); + if (settings.isJoinNotifications()) { + target.getPlayers().stream().filter(player -> player.hasPermission("maintenance.joinnotification")) + .forEach(player -> player.sendMessage(settings.getMessage("joinNotification").replace("%PLAYER%", p.getName()))); + } + // Normal serverconnect + if (event.getReason() != ServerConnectEvent.Reason.JOIN_PROXY && event.getReason() != ServerConnectEvent.Reason.KICK_REDIRECT + && event.getReason() != ServerConnectEvent.Reason.LOBBY_FALLBACK && event.getReason() != ServerConnectEvent.Reason.SERVER_DOWN_REDIRECT) { + p.sendMessage(settings.getMessage("singleMaintenanceKick").replace("%SERVER%", target.getName())); + return; + } + + // If it's the initial proxy join or a kick from another server, go back to fallback server + final ServerInfo fallback = plugin.getProxy().getServerInfo(settings.getFallbackServer()); + if (fallback == null || !fallback.canAccess(p) || plugin.isMaintenance(fallback)) { + p.disconnect(settings.getMessage("singleMaintenanceKickComplete").replace("%NEWLINE%", "\n").replace("%SERVER%", target.getName())); + if (!warned) { + plugin.getLogger().warning("Could not send player to the fallback server set in the SpigotServers.yml! Instead kicking player off the network!"); + warned = true; + } + } else + p.connect(fallback); + } +} diff --git a/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/runnable/SingleMaintenanceRunnable.java b/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/runnable/SingleMaintenanceRunnable.java new file mode 100644 index 00000000..1a57c7f6 --- /dev/null +++ b/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/runnable/SingleMaintenanceRunnable.java @@ -0,0 +1,33 @@ +package eu.kennytv.maintenance.bungee.runnable; + +import eu.kennytv.maintenance.bungee.MaintenanceBungeePlugin; +import eu.kennytv.maintenance.core.MaintenanceModePlugin; +import eu.kennytv.maintenance.core.Settings; +import eu.kennytv.maintenance.core.runnable.MaintenanceRunnableBase; +import net.md_5.bungee.api.config.ServerInfo; + +public final class SingleMaintenanceRunnable extends MaintenanceRunnableBase { + private final ServerInfo server; + + public SingleMaintenanceRunnable(final MaintenanceModePlugin plugin, final Settings settings, final int minutes, + final boolean enable, final ServerInfo server) { + super(plugin, settings, minutes, enable); + this.server = server; + } + + @Override + protected void finish() { + final MaintenanceBungeePlugin plugin = (MaintenanceBungeePlugin) this.plugin; + plugin.setMaintenanceToServer(server, enable); + } + + @Override + protected String startMessageKey() { + return settings.getMessage("singleStarttimerBroadcast").replace("%TIME%", getTime()).replace("%SERVER%", server.getName()); + } + + @Override + protected String endMessageKey() { + return settings.getMessage("singleEndtimerBroadcast").replace("%TIME%", getTime()).replace("%SERVER%", server.getName()); + } +} diff --git a/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/util/ProxiedSenderInfo.java b/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/util/ProxiedSenderInfo.java index d7c68ce0..06f8922d 100644 --- a/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/util/ProxiedSenderInfo.java +++ b/Maintenance-Bungee/src/main/java/eu/kennytv/maintenance/bungee/util/ProxiedSenderInfo.java @@ -7,7 +7,7 @@ import java.util.UUID; -public final class ProxiedSenderInfo extends SenderInfo { +public final class ProxiedSenderInfo implements SenderInfo { private final CommandSender sender; public ProxiedSenderInfo(final CommandSender sender) { diff --git a/Maintenance-Bungee/src/main/resources/SpigotServers.yml b/Maintenance-Bungee/src/main/resources/SpigotServers.yml new file mode 100644 index 00000000..48ca7187 --- /dev/null +++ b/Maintenance-Bungee/src/main/resources/SpigotServers.yml @@ -0,0 +1,6 @@ +# Enables maintenance on certain Spigot servers managed by your Bungee instance(s) +# If it's enabled on a server with players on it, they will be forwarded to the fallback server (or kicked completely if not set correctly) +maintenance-on: + #- SpigotServer1 + #- AnotherServer +fallback: hub \ No newline at end of file diff --git a/Maintenance-Bungee/src/main/resources/bungee-config.yml b/Maintenance-Bungee/src/main/resources/bungee-config.yml index a3c14d62..8f427409 100644 --- a/Maintenance-Bungee/src/main/resources/bungee-config.yml +++ b/Maintenance-Bungee/src/main/resources/bungee-config.yml @@ -1,5 +1,4 @@ # MaintenanceBungee Plugin by KennyTV -# Version ${project.version} # Enables maintenance-mode. enable-maintenance-mode: false @@ -34,6 +33,10 @@ send-join-notification: false # If set to true, the server icon will be changed to maintenance-icon.png in the Bungee main/base-folder. custom-maintenance-icon: false +# Changes the language of command feedback/messages. +# Currently available are: en (English), de (German) +language: en + # Only enable MySQL if you really know what you are doing. mysql: use-mysql: false diff --git a/Maintenance-Core/pom.xml b/Maintenance-Core/pom.xml index aa0286c7..2c16a278 100644 --- a/Maintenance-Core/pom.xml +++ b/Maintenance-Core/pom.xml @@ -6,7 +6,7 @@ maintenance-base eu.kennytv - 2.4 + 2.5 maintenance-core diff --git a/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/MaintenanceModePlugin.java b/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/MaintenanceModePlugin.java index 77c1e1cd..2cf74fca 100644 --- a/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/MaintenanceModePlugin.java +++ b/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/MaintenanceModePlugin.java @@ -3,6 +3,8 @@ import eu.kennytv.maintenance.api.IMaintenance; import eu.kennytv.maintenance.core.hook.ServerListPlusHook; import eu.kennytv.maintenance.core.runnable.MaintenanceRunnable; +import eu.kennytv.maintenance.core.util.ServerType; +import eu.kennytv.maintenance.core.util.Version; import java.io.*; import java.net.HttpURLConnection; @@ -11,16 +13,19 @@ import java.net.URLConnection; public abstract class MaintenanceModePlugin implements IMaintenance { - protected final String version; + protected final Version version; protected ServerListPlusHook serverListPlusHook; protected MaintenanceRunnable runnable; protected int taskId; private final String prefix; - private String newestVersion; + private final ServerType serverType; + private Version newestVersion; - protected MaintenanceModePlugin(final String prefix, final String version) { + protected MaintenanceModePlugin(final String prefix, final String version, final ServerType serverType) { this.prefix = prefix; - this.version = version; + this.version = new Version(version); + this.serverType = serverType; + checkNewestVersion(); } @Override @@ -30,7 +35,7 @@ public boolean isMaintenance() { @Override public String getVersion() { - return version; + return version.toString(); } @Override @@ -43,11 +48,11 @@ public void startMaintenanceRunnable(final int minutes, final boolean enable) { taskId = startMaintenanceRunnable(runnable); } - public String getNewestVersion() { + public Version getNewestVersion() { return newestVersion; } - public abstract int startMaintenanceRunnable(Runnable runnable); + protected abstract int startMaintenanceRunnable(Runnable runnable); public abstract void async(Runnable runnable); @@ -65,6 +70,10 @@ public String getPrefix() { return prefix; } + public ServerType getServerType() { + return serverType; + } + public String formatedTimer() { if (!isTaskRunning()) return "-"; final int preHours = runnable.getSecondsLeft() / 60; @@ -73,21 +82,37 @@ public String formatedTimer() { return String.format("%02d:%02d:%02d", preHours / 60, minutes, seconds); } - public boolean updateAvailable() { + public void checkNewestVersion() { try { final HttpURLConnection c = (HttpURLConnection) new URL("https://api.spigotmc.org/legacy/update.php?resource=40699").openConnection(); - final String newVersion = new BufferedReader(new InputStreamReader(c.getInputStream())).readLine().replaceAll("[a-zA-Z -]", ""); + final String newVersionString = new BufferedReader(new InputStreamReader(c.getInputStream())).readLine(); + final Version newVersion = new Version(newVersionString); final boolean available = !newVersion.equals(version); if (available) newestVersion = newVersion; - - return available; } catch (final Exception ignored) { - return false; } } + public boolean updateAvailable() { + checkNewestVersion(); + return version.compareTo(newestVersion) == -1; + } + + public String getUpdateMessage() { + if (version.compareTo(newestVersion) == -1) { + return "§cNewest version available: §aVersion " + newestVersion + "§c, you're on §a" + version; + } else if (version.compareTo(newestVersion) != 0) { + if (version.getTag().equalsIgnoreCase("snapshot")) { + return "§cYou're running a development version, please report bugs on the Discord server (https://kennytv.eu/discord) or the GitHub tracker (https://kennytv.eu/maintenance/issues)"; + } else { + return "§cYou're running a version, that doesn't exist! §cN§ai§dc§ee§5!"; + } + } + return "You have the latest version of the plugin installed."; + } + public boolean installUpdate() { try { URL url = null; diff --git a/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/Settings.java b/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/Settings.java index 16ad38f6..b925022c 100644 --- a/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/Settings.java +++ b/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/Settings.java @@ -14,6 +14,7 @@ public abstract class Settings implements ISettings { private String playerCountMessage; private String playerCountHoverMessage; private String kickMessage; + protected String languageName; private boolean customPlayerCountMessage; private boolean customMaintenanceIcon; private boolean joinNotifications; @@ -34,6 +35,7 @@ protected void loadSettings() { playerCountMessage = getColoredString(getConfigString("playercountmessage")); playerCountHoverMessage = getColoredString(getConfigString("playercounthovermessage")); kickMessage = getColoredString(getConfigString("kickmessage")); + languageName = getConfigString("language").toLowerCase(); if (customMaintenanceIcon) reloadMaintenanceIcon(); @@ -62,6 +64,10 @@ private void updateConfig() { setToConfig("timer-broadcasts-for-minutes", null); fileChanged = true; } + // 2.5 language + if (!configContains("language")) { + setToConfig("language", "en"); + } if (updateExtraConfig() || fileChanged) { saveConfig(); @@ -119,6 +125,10 @@ public String getKickMessage() { return kickMessage; } + public String getLanguage() { + return languageName; + } + public void setMaintenance(final boolean maintenance) { this.maintenance = maintenance; } diff --git a/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/command/CommandInfo.java b/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/command/CommandInfo.java new file mode 100644 index 00000000..25d42364 --- /dev/null +++ b/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/command/CommandInfo.java @@ -0,0 +1,21 @@ +package eu.kennytv.maintenance.core.command; + +import eu.kennytv.maintenance.core.util.SenderInfo; + +final class CommandInfo { + private final String[] messages; + private final String permission; + + CommandInfo(final String permission, final String... messages) { + this.messages = messages; + this.permission = permission; + } + + public boolean hasPermission(final SenderInfo sender) { + return sender.hasPermission("maintenance." + permission); + } + + public String[] getMessages() { + return messages; + } +} diff --git a/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/command/MaintenanceCommand.java b/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/command/MaintenanceCommand.java index 16b947d0..f9a17e37 100644 --- a/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/command/MaintenanceCommand.java +++ b/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/command/MaintenanceCommand.java @@ -3,20 +3,45 @@ import eu.kennytv.maintenance.core.MaintenanceModePlugin; import eu.kennytv.maintenance.core.Settings; import eu.kennytv.maintenance.core.util.SenderInfo; +import eu.kennytv.maintenance.core.util.ServerType; -import java.util.Arrays; -import java.util.Map; -import java.util.UUID; +import java.util.*; public abstract class MaintenanceCommand { protected final MaintenanceModePlugin plugin; protected final Settings settings; + private final List commandInfos; private final String name; protected MaintenanceCommand(final MaintenanceModePlugin plugin, final Settings settings, final String name) { this.plugin = plugin; this.settings = settings; this.name = name; + this.commandInfos = new ArrayList<>(); + addCommandInfo("reload", "§6/maintenance reload §7(Reloads the config file, whitelist file and the server-icon)"); + addCommandInfo("toggle", "§6/maintenance on §7(Enables maintenance mode)", "§6/maintenance off §7(Disables maintenance mode)"); + if (plugin.getServerType() == ServerType.BUNGEE) { + addCommandInfo("toggleserver", "§6/maintenance on §7(Enables maintenance mode on a specific proxied server)", + "§6/maintenance off §7(Disables maintenance mode on a specific proxied server)"); + } + addCommandInfo("timer", "§6/maintenance starttimer §7(After the given time in minutes, maintenance mode will be enabled)", + "§6/maintenance endtimer §7(After the given time in minutes, maintenance mode will be disabled)", + "§6/maintenance timer abort §7(If running, the current timer will be aborted)"); + if (plugin.getServerType() == ServerType.BUNGEE) { + addCommandInfo("servertimer", "§6/maintenance starttimer §7(After the given time in minutes, maintenance mode will be enabled on the given server)", + "§6/maintenance endtimer §7(After the given time in minutes, maintenance mode will be disabled on the given server)", + "§6/maintenance timer abort §7(If running, the timer running for that server will be aborted)"); + } + addCommandInfo("whitelist.list", "§6/maintenance whitelist §7(Shows all whitelisted players for the maintenance mode)"); + addCommandInfo("whitelist.add", "§6/maintenance add §7(Adds the player to the maintenance whitelist, so they can join the server even though maintenance is enabled)"); + addCommandInfo("whitelist.remove", "§6/maintenance remove §7(Removes the player from the maintenance whitelist)"); + addCommandInfo("setmotd", "§6/maintenance setmotd <1/2> §7(Sets a motd for maintenance mode)", "§6/maintenance removemotd §7(Removes a maintenance motd)"); + addCommandInfo("motd", "§6/maintenance motd §7(Lists the currently set maintenance motds)"); + addCommandInfo("update", "§6/maintenance update §7(Remotely downloads the newest version of the plugin onto your server)"); + } + + private void addCommandInfo(final String permission, final String... messages) { + commandInfos.add(new CommandInfo(permission, messages)); } public void execute(final SenderInfo sender, final String[] args) { @@ -42,7 +67,6 @@ public void execute(final SenderInfo sender, final String[] args) { } else if (args[0].equals("forceupdate")) { if (checkPermission(sender, "update")) return; sender.sendMessage(settings.getMessage("updateDownloading")); - if (plugin.installUpdate()) sender.sendMessage(settings.getMessage("updateFinished")); else @@ -70,61 +94,40 @@ public void execute(final SenderInfo sender, final String[] args) { } } sender.sendMessage("§8§m----------"); + } else if (args[0].equalsIgnoreCase("status") && plugin.getServerType() == ServerType.BUNGEE) { + if (checkPermission(sender, "status")) return; + showMaintenanceStatus(sender); } else sendUsage(sender); } else if (args.length == 2) { - if (args[0].equalsIgnoreCase("endtimer")) { - if (checkPermission(sender, "timer")) return; + if (args[0].equalsIgnoreCase("help")) { if (!isNumeric(args[1])) { - sender.sendMessage(settings.getMessage("endtimerUsage")); + sender.sendMessage(settings.getMessage("helpUsage")); return; } - if (plugin.isTaskRunning()) { - sender.sendMessage(settings.getMessage("timerAlreadyRunning")); - return; - } - - final int minutes = Integer.parseInt(args[1]); - if (minutes > 40320) { - sender.sendMessage(settings.getMessage("timerTooLong")); - return; - } - if (minutes < 1) { - sender.sendMessage("§8§o[KennyTV whispers to you] §c§oThink about running a timer for a negative amount of minutes. Doesn't work §lthat §c§owell."); + sendUsage(sender, Integer.parseInt(args[1])); + } else if ((args[0].equalsIgnoreCase("on") || args[0].equalsIgnoreCase("off")) && plugin.getServerType() == ServerType.BUNGEE) { + if (checkPermission(sender, "toggleserver")) return; + handleToggleServerCommand(sender, args); + } else if (args[0].equalsIgnoreCase("endtimer")) { + if (checkPermission(sender, "timer")) return; + if (checkTimerArgs(sender, args[1], "endtimerUsage")) return; + if (!plugin.isMaintenance()) { + sender.sendMessage(settings.getMessage("alreadyDisabled")); return; } - - if (!plugin.isMaintenance()) - plugin.setMaintenance(true); - plugin.startMaintenanceRunnable(minutes, false); + plugin.startMaintenanceRunnable(Integer.parseInt(args[1]), false); sender.sendMessage(settings.getMessage("endtimerStarted").replace("%TIME%", plugin.getRunnable().getTime())); } else if (args[0].equalsIgnoreCase("starttimer")) { if (checkPermission(sender, "timer")) return; - if (!isNumeric(args[1])) { - sender.sendMessage(settings.getMessage("starttimerUsage")); - return; - } + if (checkTimerArgs(sender, args[1], "starttimerUsage")) return; if (plugin.isMaintenance()) { sender.sendMessage(settings.getMessage("alreadyEnabled")); return; } - if (plugin.isTaskRunning()) { - sender.sendMessage(settings.getMessage("timerAlreadyRunning")); - return; - } - - final int minutes = Integer.parseInt(args[1]); - if (minutes > 40320) { - sender.sendMessage(settings.getMessage("timerTooLong")); - return; - } - if (minutes < 1) { - sender.sendMessage("§8§o[KennyTV whispers to you] §c§oThink about running a timer for a negative amount of minutes. Doesn't work §lthat §c§owell."); - return; - } + plugin.startMaintenanceRunnable(Integer.parseInt(args[1]), true); sender.sendMessage(settings.getMessage("starttimerStarted").replace("%TIME%", plugin.getRunnable().getTime())); - plugin.startMaintenanceRunnable(minutes, true); } else if (args[0].equalsIgnoreCase("timer")) { if (args[1].equalsIgnoreCase("abort") || args[1].equalsIgnoreCase("stop") || args[1].equalsIgnoreCase("cancel")) { if (checkPermission(sender, "timer")) return; @@ -168,6 +171,8 @@ public void execute(final SenderInfo sender, final String[] args) { sender.sendMessage(settings.getMessage("removedMotd").replace("%INDEX%", args[1])); } else sendUsage(sender); + } else if (args.length == 3 && plugin.getServerType() == ServerType.BUNGEE) { + handleTimerServerCommands(sender, args); } else if (args.length > 3 && args[0].equalsIgnoreCase("setmotd")) { if (checkPermission(sender, "setmotd")) return; if (!isNumeric(args[1])) { @@ -216,40 +221,69 @@ public void execute(final SenderInfo sender, final String[] args) { sendUsage(sender); } - private void sendUsage(final SenderInfo sender) { + protected void sendUsage(final SenderInfo sender) { + sendUsage(sender, 1); + } + + private static final int COMMANDS_PER_PAGE = 8; + + protected void sendUsage(final SenderInfo sender, final int page) { + final List commands = new ArrayList<>(); + commandInfos.stream().filter(cmd -> cmd.hasPermission(sender)).forEach(cmd -> { + for (String message : cmd.getMessages()) { + commands.add(message); + } + }); + if ((page - 1) * COMMANDS_PER_PAGE > commands.size()) { + sender.sendMessage(plugin.getPrefix() + "§cThere is no page with that number!"); + return; + } + + final List filteredCommands; + if (page * COMMANDS_PER_PAGE >= commands.size()) + filteredCommands = commands.subList((page - 1) * COMMANDS_PER_PAGE, commands.size()); + else + filteredCommands = commands.subList((page - 1) * COMMANDS_PER_PAGE, page * COMMANDS_PER_PAGE); + + sender.sendMessage(""); + sender.sendMessage("§8========[ §e" + name + " §8| §eVersion: §e" + plugin.getVersion() + " §8]========"); + filteredCommands.forEach(sender::sendMessage); + if (page * 10 < commands.size()) + sender.sendMessage("§7Use §b/maintenance help " + (page + 1) + " §7to get to the next help window."); + else + sender.sendMessage("§8× §7Created by §bKennyTV"); + sender.sendMessage("§8========[ §e" + name + " §8| §e" + page + "/" + ((commands.size() + getDivide(commands.size())) / COMMANDS_PER_PAGE) + " §8]========"); sender.sendMessage(""); - sender.sendMessage("§8===========[ §e" + name + " §8| §eVersion: §e" + plugin.getVersion() + " §8]==========="); - if (sender.hasPermission("maintenance.reload")) - sender.sendMessage("§6/maintenance reload §7(Reloads the config file, whitelist file and the server-icon)"); - if (sender.hasPermission("maintenance.toggle")) { - sender.sendMessage("§6/maintenance on §7(Enables maintenance mode"); - sender.sendMessage("§6/maintenance off §7(Disables maintenance mode)"); + } + + private int getDivide(final int size) { + final int commandSize = size % COMMANDS_PER_PAGE; + return commandSize > 0 ? COMMANDS_PER_PAGE - commandSize : 0; + } + + protected boolean checkTimerArgs(final SenderInfo sender, final String time, final String usageKey) { + if (!isNumeric(time)) { + sender.sendMessage(settings.getMessage(usageKey)); + return true; + } + if (plugin.isTaskRunning()) { + sender.sendMessage(settings.getMessage("timerAlreadyRunning")); + return true; } - if (sender.hasPermission("maintenance.timer")) { - sender.sendMessage("§6/maintenance starttimer §7(After the given time in minutes, maintenance mode will be enabled)"); - sender.sendMessage("§6/maintenance endtimer §7(Enables maintenance mode. After the given time in minutes, maintenance mode will be disabled)"); - sender.sendMessage("§6/maintenance timer abort §7(If running, the current timer will be aborted)"); + + final int minutes = Integer.parseInt(time); + if (minutes > 40320) { + sender.sendMessage(settings.getMessage("timerTooLong")); + return true; } - if (sender.hasPermission("maintenance.whitelist.list")) - sender.sendMessage("§6/maintenance whitelist §7(Shows all whitelisted players for the maintenance mode)"); - if (sender.hasPermission("maintenance.whitelist.add")) - sender.sendMessage("§6/maintenance add §7(Adds the player to the maintenance whitelist, so they can join the server even though maintenance is enabled)"); - if (sender.hasPermission("maintenance.whitelist.remove")) - sender.sendMessage("§6/maintenance remove §7(Removes the player from the maintenance whitelist)"); - if (sender.hasPermission("maintenance.setmotd")) { - sender.sendMessage("§6/maintenance setmotd <1/2> §7(Sets a motd for maintenance mode)"); - sender.sendMessage("§6/maintenance removemotd §7(Removes a maintenance motd)"); + if (minutes < 1) { + sender.sendMessage("§8§o[KennyTV whispers to you] §c§oThink about running a timer for a negative amount of minutes. Doesn't work §lthat §c§owell."); + return true; } - if (sender.hasPermission("maintenance.motd")) - sender.sendMessage("§6/maintenance motd §7(Lists the currently set maintenance motds)"); - if (sender.hasPermission("maintenance.update")) - sender.sendMessage("§6/maintenance update §7(Remotely downloads the newest version of the plugin onto your server)"); - sender.sendMessage("§8× §7Created by §bKennyTV"); - sender.sendMessage("§8===========[ §e" + name + " §8| §eVersion: §e" + plugin.getVersion() + " §8]==========="); - sender.sendMessage(""); + return false; } - private boolean checkPermission(final SenderInfo sender, final String permission) { + protected boolean checkPermission(final SenderInfo sender, final String permission) { if (!sender.hasPermission("maintenance." + permission)) { sender.sendMessage(settings.getMessage("noPermission")); return true; @@ -257,7 +291,7 @@ private boolean checkPermission(final SenderInfo sender, final String permission return false; } - private boolean isNumeric(final String string) { + protected boolean isNumeric(final String string) { try { Integer.parseInt(string); } catch (final NumberFormatException nfe) { @@ -271,4 +305,13 @@ private boolean isNumeric(final String string) { protected abstract void removePlayerFromWhitelist(SenderInfo sender, String name); protected abstract void checkForUpdate(SenderInfo sender); + + protected void showMaintenanceStatus(SenderInfo sender) { + } + + protected void handleToggleServerCommand(SenderInfo sender, String args[]) { + } + + protected void handleTimerServerCommands(SenderInfo sender, String args[]) { + } } diff --git a/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/runnable/MaintenanceRunnable.java b/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/runnable/MaintenanceRunnable.java index cf312558..7be43e20 100644 --- a/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/runnable/MaintenanceRunnable.java +++ b/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/runnable/MaintenanceRunnable.java @@ -3,55 +3,24 @@ import eu.kennytv.maintenance.core.MaintenanceModePlugin; import eu.kennytv.maintenance.core.Settings; -public final class MaintenanceRunnable implements Runnable { - private final MaintenanceModePlugin plugin; - private final Settings settings; - private final boolean enable; - private int seconds; +public final class MaintenanceRunnable extends MaintenanceRunnableBase { public MaintenanceRunnable(final MaintenanceModePlugin plugin, final Settings settings, final int minutes, final boolean enable) { - this.plugin = plugin; - this.settings = settings; - this.seconds = minutes * 60; - this.enable = enable; + super(plugin, settings, minutes, enable); } @Override - public void run() { - if (seconds == 0) { - plugin.setMaintenance(enable); - if (plugin.isTaskRunning()) - plugin.cancelTask(); - } else if (settings.getBroadcastIntervalls().contains(seconds)) { - if (enable) - plugin.broadcast(settings.getMessage("starttimerBroadcast").replaceAll("%TIME%", getTime())); - else - plugin.broadcast(settings.getMessage("endtimerBroadcast").replaceAll("%TIME%", getTime())); - } - - seconds--; - } - - public String getTime() { - final int preHours = this.seconds / 60; - final int minutes = preHours % 60; - final int seconds = this.seconds % 60; - - final StringBuilder buider = new StringBuilder(); - append(buider, "hour", preHours / 60); - append(buider, "minute", minutes); - append(buider, "second", seconds); - return buider.toString(); + protected void finish() { + plugin.setMaintenance(enable); } - private void append(final StringBuilder builder, final String timeUnit, final int time) { - if (time == 0) return; - if (builder.length() != 0) - builder.append(" "); - builder.append(time).append(" ").append(settings.getMessage(time == 1 ? timeUnit : timeUnit + "s")); + @Override + protected String startMessageKey() { + return settings.getMessage("starttimerBroadcast").replace("%TIME%", getTime()); } - public int getSecondsLeft() { - return seconds; + @Override + protected String endMessageKey() { + return settings.getMessage("endtimerBroadcast").replace("%TIME%", getTime()); } } diff --git a/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/runnable/MaintenanceRunnableBase.java b/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/runnable/MaintenanceRunnableBase.java new file mode 100644 index 00000000..1ebe2c5c --- /dev/null +++ b/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/runnable/MaintenanceRunnableBase.java @@ -0,0 +1,61 @@ +package eu.kennytv.maintenance.core.runnable; + +import eu.kennytv.maintenance.core.MaintenanceModePlugin; +import eu.kennytv.maintenance.core.Settings; + +public abstract class MaintenanceRunnableBase implements Runnable { + protected final MaintenanceModePlugin plugin; + protected final Settings settings; + protected final boolean enable; + protected int seconds; + + protected MaintenanceRunnableBase(final MaintenanceModePlugin plugin, final Settings settings, final int minutes, final boolean enable) { + this.plugin = plugin; + this.settings = settings; + this.seconds = minutes * 60; + this.enable = enable; + } + + @Override + public void run() { + if (seconds == 0) { + finish(); + } else if (settings.getBroadcastIntervalls().contains(seconds)) { + if (enable) + plugin.broadcast(startMessageKey()); + else + plugin.broadcast(endMessageKey()); + } + + seconds--; + } + + protected abstract void finish(); + + protected abstract String startMessageKey(); + + protected abstract String endMessageKey(); + + public String getTime() { + final int preHours = this.seconds / 60; + final int minutes = preHours % 60; + final int seconds = this.seconds % 60; + + final StringBuilder buider = new StringBuilder(); + append(buider, "hour", preHours / 60); + append(buider, "minute", minutes); + append(buider, "second", seconds); + return buider.toString(); + } + + private void append(final StringBuilder builder, final String timeUnit, final int time) { + if (time == 0) return; + if (builder.length() != 0) + builder.append(" "); + builder.append(time).append(" ").append(settings.getMessage(time == 1 ? timeUnit : timeUnit + "s")); + } + + public int getSecondsLeft() { + return seconds; + } +} diff --git a/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/util/SenderInfo.java b/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/util/SenderInfo.java index 75c68d61..0c7cf67e 100644 --- a/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/util/SenderInfo.java +++ b/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/util/SenderInfo.java @@ -2,13 +2,13 @@ import java.util.UUID; -public abstract class SenderInfo { +public interface SenderInfo { - public abstract UUID getUuid(); + UUID getUuid(); - public abstract String getName(); + String getName(); - public abstract boolean hasPermission(String permission); + boolean hasPermission(String permission); - public abstract void sendMessage(String message); + void sendMessage(String message); } \ No newline at end of file diff --git a/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/util/ServerType.java b/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/util/ServerType.java new file mode 100644 index 00000000..4b9adecc --- /dev/null +++ b/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/util/ServerType.java @@ -0,0 +1,7 @@ +package eu.kennytv.maintenance.core.util; + +public enum ServerType { + + BUNGEE, + SPIGOT +} diff --git a/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/util/Version.java b/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/util/Version.java new file mode 100644 index 00000000..3adc3605 --- /dev/null +++ b/Maintenance-Core/src/main/java/eu/kennytv/maintenance/core/util/Version.java @@ -0,0 +1,76 @@ +package eu.kennytv.maintenance.core.util; + +public final class Version implements Comparable { + private final int[] parts = new int[3]; + private final String version; + private final String tag; + + public Version(final String version) { + if (version == null || version.isEmpty()) { + this.version = ""; + tag = ""; + System.out.println("Unknown Maintenance version detected!"); + return; + } + final String[] split = version.split("-", 2)[0].split("\\."); + for (int i = 0; i < split.length; i++) { + if (!isNumeric(split[i])) { + this.version = ""; + tag = ""; + System.out.println("Unknown Maintenance version detected!"); + return; + } + parts[i] = Integer.parseInt(split[i]); + } + + this.version = version; + tag = version.contains("-") ? version.split("-", 2)[1] : ""; + } + + /** + * Compare two versions + * + * @param version version to compare to + * @return 0 if they are the same, 1 if this version (not the one to compare to) is newer, -1 if older + */ + @Override + public int compareTo(final Version version) { + if (version == null || version.toString() == null) return 0; + final int max = Math.max(this.parts.length, version.parts.length); + for (int i = 0; i < max; i += 1) { + final int partA = i < this.parts.length ? this.parts[i] : 0; + final int partB = i < version.parts.length ? version.parts[i] : 0; + if (partA < partB) return -1; + if (partA > partB) return 1; + } + + if (this.tag.isEmpty() && !version.tag.isEmpty()) + return 1; + if (!this.tag.isEmpty() && version.tag.isEmpty()) + return -1; + return 0; + } + + public String getTag() { + return tag; + } + + @Override + public String toString() { + return version; + } + + @Override + public boolean equals(final Object o) { + return o instanceof Version && o == this || version.equals(o.toString()); + } + + private boolean isNumeric(final String string) { + try { + Integer.parseInt(string); + } catch (final NumberFormatException nfe) { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/Maintenance-Core/src/main/resources/language-de.yml b/Maintenance-Core/src/main/resources/language-de.yml new file mode 100644 index 00000000..2552fbee --- /dev/null +++ b/Maintenance-Core/src/main/resources/language-de.yml @@ -0,0 +1,64 @@ +# Maintenance Plugin by KennyTV +# Wörter zwischen dem '%'-Zeichen nur entfernen, wenn Du wirklich weißt, warum Du sie entfernen willst + +noPermission: "&cDu hast nicht die erforderliche Berechtigung für diesen Befehl." +maintenanceActivated: "&8[&eMaintenance&8] &6Der Wartungsmodus ist nun aktiviert." +maintenanceDeactivated: "&8[&eMaintenance&8] &6Der Wartungsmodus ist nun deaktiviert." +alreadyEnabled: "&8[&eMaintenance&8] &cDer Wartungsmodus ist bereits aktiviert!" +alreadyDisabled: "&8[&eMaintenance&8] &cDer Wartungsmodus ist bereits deaktiviert!" +helpUsage: "&8[&eMaintenance&8] &c/maintenance help " +endtimerBroadcast: "&8[&eMaintenance&8] &7Der Wartungsmodus wird deaktiviert in: &6%TIME%&7." +endtimerStarted: "&8[&eMaintenance&8] &aGestarteter Timer: &7Der Wartungsmodus wird deaktiviert in: &6%TIME%&7." +endtimerUsage: "&8[&eMaintenance&8] &c/maintenance endtimer " +starttimerBroadcast: "&8[&eMaintenance&8] &7Der Wartungsmodus wird aktiviert in: &6%TIME%&7." +starttimerStarted: "&8[&eMaintenance&8] &aGestarteter Timer: &7Der Wartungsmodus wird aktiviert in: &6%TIME%&7" +starttimerUsage: "&8[&eMaintenance&8] &c/maintenance starttimer " +timerAlreadyRunning: "&8[&eMaintenance&8] &cMomentan läuft bereits ein Timer!" +timerNotRunning: "&8[&eMaintenance&8] &cMomentan läuft kein Timer." +timerCancelled: "&8[&eMaintenance&8] &cDer laufende Timer wurde beendet." +timerTooLong: "&8[&eMaintenance&8] &cDie angegebene Nummer muss kleiner als 40320 sein (= 28 Tage)!" +joinNotification: "&8[&eMaintenance&8] &e%PLAYER% &chat versucht den Server beizutreten." +motdList: "&8[&eMaintenance&8] &7Liste der Maintenance MOTDs:" +reload: "&8[&eMaintenance&8] &aConfig, WhitelistedPlayers, Language Datei und Maintenance Icon wurden neugeladen." +removedMotd: "&8[&eMaintenance&8] &aDie %INDEX%. Maintenance MOTD wurde entfernt." +removeMotdError: "&8[&eMaintenance&8] &cDu hast nur eine Maintenance MOTD, daher kannst du auch keine entfernen!" +removeMotdUsage: "&8[&eMaintenance&8] &c/maintenance removemotd " +serverNotFound: "&8[&eMaintenance&8] &cEs wurde kein Server mit diesem Namen gefunden!" +setMotd: "&8[&eMaintenance&8] &aDie %LINE%. Zeile der %INDEX%. Maintenance MOTD wurde geändert zu: %MOTD%" +setMotdUsage: "&8[&eMaintenance&8] &c/maintenance setmotd <1/2> " +setMotdIndexError: "&8[&eMaintenance&8] §cMomentan gibt es %MOTDS% MOTDs, du musst also eine Zahl zwischen 1 and %NEWAMOUNT% wählen." +setMotdLineError: "&8[&eMaintenance&8] &cDas zweite Argument muss die Zeilennummer sein (1 oder 2)!" +updateDownloading: "&8[&eMaintenance&8] &c&lUpdate wird heruntergeladen..." +updateFailed: "&8[&eMaintenance&8] &4&lUpdate fehlgeschlagen!" +updateFinished: "&8[&eMaintenance&8] &a&lDas Update war erfolgreich! Um Probleme mit Timern zu vermeiden und das Update zu vervollständigen, musst du den Server neustarten!" +whitelistedPlayers: "&8[&eMaintenance&8] &6Spieler in der Maintenance Whitelist:" +whitelistedPlayersFormat: "&8- &e%NAME% &8(&7%UUID%&8)" +whitelistAdded: "&8[&eMaintenance&8] &b%PLAYER% &awurde zur Maintenance Whitelist hinzugefügt!" +whitelistAlreadyAdded: "&8[&eMaintenance&8] &b%PLAYER% &cist bereits in der Maintenance Whitelist!" +whitelistRemoved: "&8[&eMaintenance&8] &b%PLAYER% &awurde von der Maintenance Whitelist entfernt!" +whitelistNotFound: "&8[&eMaintenance&8] &cDieser Spieler ist nicht in der Maintenance Whitelist!" +whitelistEmtpy: "&8[&eMaintenance&8] &cDie Maintenance Whitelist ist leer! Nutze '/maintenance add ', um jemanden hinzuzufügen!" +whitelistEmptyDefault: "&8[&eMaintenance&8] &cNutze '/maintenance add ', um jemanden hinzuzufügen. Ansonsten kannst auch die UUID des Spielers in die WhitelistedPlayers.yml einsetzen, wie es im dortigen Beispiel schon drinsteht!" +playerNotFound: "&8[&eMaintenance&8] &cBisher hat kein Spieler mit diesem Namen jemals auf diesem Server gespielt." +playerNotOnline: "&8[&eMaintenance&8] &cEs ist momentan kein Spieler mit diesem Namen online." + +second: "Sekunde" +seconds: "Sekunden" +minute: "Minute" +minutes: "Minuten" +hour: "Stunde" +hours: "Stunden" + +# Nachrichten für den Bungee Teil des Plugins, einfach ignorieren, falls das Plugin auf Spigot verwendet wird +singleEndtimerBroadcast: "&8[&eMaintenance&8] &7Der Wartungsmodus auf Server %SERVER% wird deaktiviert in: &6%TIME%&7." +singleEndtimerUsage: "&8[&eMaintenance&8] &c/maintenance endtimer " +singleStarttimerBroadcast: "&8[&eMaintenance&8] &7Der Wartungsmodus auf Server %SERVER% wird aktiviert in: &6%TIME%&7." +singleStarttimerUsage: "&8[&eMaintenance&8] &c/maintenance starttimer " +singleMaintenanceKick: "&8[&eMaintenance&8] &cDer Server %SERVER% befindet sich momentan im Wartungsmodus! Probier es später nochmal!" +singleMaintenanceKickComplete: "&cDer Server %SERVER% befindet sich in Wartung!%NEWLINE%&cDu kannst versuchen zu rejoinen, um andere Server zu betreten!" +singleMaintenanceActivated: "&8[&eMaintenance&8] &6Der Wartungsmodus wurde auf &e%SERVER% &6aktiviert." +singleMaintenanceDeactivated: "&8[&eMaintenance&8] &6Der Wartungsmodus wurde auf &e%SERVER% &6deaktiviert." +singleServerAlreadyEnabled: "&8[&eMaintenance&8] &cDer Wartungsmodus ist bereits an auf &e%SERVER%&c!" +singleServerAlreadyDisabled: "&8[&eMaintenance&8] &cDer Wartungsmodus ist bereits aus auf &e%SERVER%&c!" +singleServerMaintenanceList: "&8[&eMaintenance&8] &7Unterserverserver, die im Wartungsmodus sind:" +singleServerMaintenanceListEmpty: "&8[&eMaintenance&8] &7Es befindet sich momentan kein Unterserver im Wartungsmodus." \ No newline at end of file diff --git a/Maintenance-Core/src/main/resources/language.yml b/Maintenance-Core/src/main/resources/language-en.yml similarity index 65% rename from Maintenance-Core/src/main/resources/language.yml rename to Maintenance-Core/src/main/resources/language-en.yml index a1f9500e..5465d58e 100644 --- a/Maintenance-Core/src/main/resources/language.yml +++ b/Maintenance-Core/src/main/resources/language-en.yml @@ -2,47 +2,63 @@ # Don't remove words inbetween the '%' if you don't exactly know why you're doing it noPermission: "&cYou do not have the permission to execute that command." -reload: "&8[&eMaintenance&8] &aReloaded config, whitelistedplayers, language file and the maintenance icon." -alreadyEnabled: "&8[&eMaintenance&8] &cMaintenance already is enabled!" -alreadyDisabled: "&8[&eMaintenance&8] &cMaintenance already is disabled!" maintenanceActivated: "&8[&eMaintenance&8] &6Maintenance mode is now activated." maintenanceDeactivated: "&8[&eMaintenance&8] &6Maintenance mode is now deactivated." -starttimerUsage: "&8[&eMaintenance&8] &c/maintenance starttimer " -starttimerStarted: "&8[&eMaintenance&8] &aStarted timer: &7Maintenance mode will be activated in &6%TIME%&7." -starttimerBroadcast: "&8[&eMaintenance&8] &7Maintenance mode will be enabled in &6%TIME%&7." -endtimerUsage: "&8[&eMaintenance&8] &c/maintenance endtimer " -endtimerStarted: "&8[&eMaintenance&8] &aStarted timer: &7Maintenance mode will be deactivated in &6%TIME%&7." +alreadyEnabled: "&8[&eMaintenance&8] &cMaintenance is already enabled!" +alreadyDisabled: "&8[&eMaintenance&8] &cMaintenance is already disabled!" +helpUsage: "&8[&eMaintenance&8] &c/maintenance help " endtimerBroadcast: "&8[&eMaintenance&8] &7Maintenance mode will be disabled in &6%TIME%&7." -timerTooLong: "&8[&eMaintenance&8] &cThe number has to be less than 40320 (28 days)!" -timerAlreadyRunning: "&8[&eMaintenance&8] &cThere's already a starttimer scheduled!" +endtimerStarted: "&8[&eMaintenance&8] &aStarted timer: &7Maintenance mode will be deactivated in &6%TIME%&7." +endtimerUsage: "&8[&eMaintenance&8] &c/maintenance endtimer " +starttimerBroadcast: "&8[&eMaintenance&8] &7Maintenance mode will be enabled in &6%TIME%&7." +starttimerStarted: "&8[&eMaintenance&8] &aStarted timer: &7Maintenance mode will be activated in &6%TIME%&7." +starttimerUsage: "&8[&eMaintenance&8] &c/maintenance starttimer " +timerAlreadyRunning: "&8[&eMaintenance&8] &cThere's already a timer scheduled!" timerNotRunning: "&8[&eMaintenance&8] &cThere's currently no running timer." timerCancelled: "&8[&eMaintenance&8] &cThe current timer has been disabled." +timerTooLong: "&8[&eMaintenance&8] &cThe number has to be less than 40320 (28 days)!" joinNotification: "&8[&eMaintenance&8] &e%PLAYER% &ctried to join the server." -updateDownloading: "&8[&eMaintenance&8] &c&lDownloading update..." -updateFinished: "&8[&eMaintenance&8] &a&lThe update was successful! To prevent issues with tasks and to complete the update, you have to restart the server!" -updateFailed: "&8[&eMaintenance&8] &4&lUpdate failed!" +motdList: "&8[&eMaintenance&8] &7List of your maintenance motds:" +reload: "&8[&eMaintenance&8] &aReloaded config, whitelistedplayers, language file and the maintenance icon." +removedMotd: "&8[&eMaintenance&8] &aRemoved motd number %INDEX%." +removeMotdError: "&8[&eMaintenance&8] &cYou only have one motd, so you can't remove any!" +removeMotdUsage: "&8[&eMaintenance&8] &c/maintenance removemotd " +serverNotFound: "&8[&eMaintenance&8] &cNo server with this name is registered on the proxy!" +setMotd: "&8[&eMaintenance&8] &aSet line %LINE% of the %INDEX%. maintenance motd to %MOTD%" setMotdUsage: "&8[&eMaintenance&8] &c/maintenance setmotd <1/2> " -setMotdLineError: "&8[&eMaintenance&8] &cThe second argument has to be the line number (1 or 2)!" setMotdIndexError: "&8[&eMaintenance&8] §cYou currently have %MOTDS% motds, so you have to pick a number between 1 and %NEWAMOUNT%." -setMotd: "&8[&eMaintenance&8] &aSet line %LINE% of the %INDEX%. maintenance motd to %MOTD%" -removeMotdUsage: "&8[&eMaintenance&8] &c/maintenance removemotd " -removeMotdError: "&8[&eMaintenance&8] &cYou only have one motd, so you can't remove any!" -removedMotd: "&8[&eMaintenance&8] &aRemoved motd number %INDEX%." -motdList: "&8[&eMaintenance&8] &7List of your maintenance motds:" -whitelistEmtpy: "&8[&eMaintenance&8] &cThe maintenance whitelist is empty! Use '/maintenance add ' to add someone!" -whitelistEmptyDefault: "&8[&eMaintenance&8] &cUse '/maintenance add ' to add someone. Alternatively, you can add the uuid of a player to the WhitelistedPlayers.yml as seen in the example in the file!" +setMotdLineError: "&8[&eMaintenance&8] &cThe second argument has to be the line number (1 or 2)!" +updateDownloading: "&8[&eMaintenance&8] &c&lDownloading update..." +updateFailed: "&8[&eMaintenance&8] &4&lUpdate failed!" +updateFinished: "&8[&eMaintenance&8] &a&lThe update was successful! To prevent issues with tasks and to complete the update, you have to restart the server!" whitelistedPlayers: "&8[&eMaintenance&8] &6Whitelisted players for maintenance:" whitelistedPlayersFormat: "&8- &e%NAME% &8(&7%UUID%&8)" -whitelistNotFound: "&8[&eMaintenance&8] &cThis player is not in the maintenance whitelist!" -whitelistAlreadyAdded: "&8[&eMaintenance&8] &b%PLAYER% &calready is in the maintenance whitelist!" whitelistAdded: "&8[&eMaintenance&8] &aAdded &b%PLAYER% &ato the maintenance whitelist!" +whitelistAlreadyAdded: "&8[&eMaintenance&8] &b%PLAYER% &calready is in the maintenance whitelist!" whitelistRemoved: "&8[&eMaintenance&8] &aRemoved &b%PLAYER% &afrom the maintenance whitelist!" -playerNotOnline: "&8[&eMaintenance&8] &cThere's no player online with that name." +whitelistNotFound: "&8[&eMaintenance&8] &cThis player is not in the maintenance whitelist!" +whitelistEmtpy: "&8[&eMaintenance&8] &cThe maintenance whitelist is empty! Use '/maintenance add ' to add someone!" +whitelistEmptyDefault: "&8[&eMaintenance&8] &cUse '/maintenance add ' to add someone. Alternatively, you can add the uuid of a player to the WhitelistedPlayers.yml as seen in the example in the file!" playerNotFound: "&8[&eMaintenance&8] &cNo player with this name has played on this server before." +playerNotOnline: "&8[&eMaintenance&8] &cThere's no player online with that name." second: "second" seconds: "seconds" minute: "minute" minutes: "minutes" hour: "hour" -hours: "hours" \ No newline at end of file +hours: "hours" + +# Some messages for the Bungee part, just ignore them if you use the plugin on Spigot +singleEndtimerBroadcast: "&8[&eMaintenance&8] &7Maintenance mode on server %SERVER% will be disabled in &6%TIME%&7." +singleEndtimerUsage: "&8[&eMaintenance&8] &c/maintenance endtimer " +singleStarttimerBroadcast: "&8[&eMaintenance&8] &7Maintenance mode on server %SERVER% will be enabled in &6%TIME%&7." +singleStarttimerUsage: "&8[&eMaintenance&8] &c/maintenance starttimer " +singleMaintenanceKick: "&8[&eMaintenance&8] &cThe server %SERVER% is currently under maintenance! Try again later!" +singleMaintenanceKickComplete: "&cThe server %SERVER% is under maintenance!%NEWLINE%&cYou may try to rejoin to go onto another server!" +singleMaintenanceActivated: "&8[&eMaintenance&8] &6Maintenance mode is now activated on server &e%SERVER%&6." +singleMaintenanceDeactivated: "&8[&eMaintenance&8] &6Maintenance mode is now deactivated on server &e%SERVER%&6." +singleServerAlreadyEnabled: "&8[&eMaintenance&8] &cMaintenance is already enabled on server &e%SERVER%&c!" +singleServerAlreadyDisabled: "&8[&eMaintenance&8] &cMaintenance is already disabled on server &e%SERVER%&c!" +singleServerMaintenanceList: "&8[&eMaintenance&8] &7Proxied servers, that have maintenance enabled:" +singleServerMaintenanceListEmpty: "&8[&eMaintenance&8] &7There are no proxied servers that are under maintenance." \ No newline at end of file diff --git a/Maintenance-Parent/pom.xml b/Maintenance-Parent/pom.xml index 5c8110f1..90c20405 100644 --- a/Maintenance-Parent/pom.xml +++ b/Maintenance-Parent/pom.xml @@ -6,7 +6,7 @@ maintenance-base eu.kennytv - 2.4 + 2.5 maintenance-parent diff --git a/Maintenance-Spigot/pom.xml b/Maintenance-Spigot/pom.xml index cdd2c3ce..26b92e01 100644 --- a/Maintenance-Spigot/pom.xml +++ b/Maintenance-Spigot/pom.xml @@ -6,7 +6,7 @@ maintenance-base eu.kennytv - 2.4 + 2.5 maintenance-spigot @@ -45,7 +45,7 @@ com.comphenix.protocol ProtocolLib-API - 4.4.0-SNAPSHOT + 4.4.0 provided diff --git a/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/MaintenanceSpigotPlugin.java b/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/MaintenanceSpigotPlugin.java index 186c141e..ce2863de 100644 --- a/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/MaintenanceSpigotPlugin.java +++ b/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/MaintenanceSpigotPlugin.java @@ -2,9 +2,10 @@ import eu.kennytv.maintenance.api.IMaintenance; import eu.kennytv.maintenance.api.ISettings; -import eu.kennytv.maintenance.api.MaintenanceSpigotAPI; +import eu.kennytv.maintenance.api.spigot.MaintenanceSpigotAPI; import eu.kennytv.maintenance.core.MaintenanceModePlugin; import eu.kennytv.maintenance.core.hook.ServerListPlusHook; +import eu.kennytv.maintenance.core.util.ServerType; import eu.kennytv.maintenance.spigot.command.MaintenanceSpigotCommand; import eu.kennytv.maintenance.spigot.listener.PlayerLoginListener; import eu.kennytv.maintenance.spigot.metrics.MetricsLite; @@ -24,12 +25,13 @@ public final class MaintenanceSpigotPlugin extends MaintenanceModePlugin { private final SettingsSpigot settings; MaintenanceSpigotPlugin(final MaintenanceSpigotBase plugin) { - super("§8[§eMaintenanceSpigot§8] ", plugin.getDescription().getVersion()); + super("§8[§eMaintenanceSpigot§8] ", plugin.getDescription().getVersion(), ServerType.SPIGOT); this.plugin = plugin; settings = new SettingsSpigot(this, plugin); plugin.getLogger().info("Plugin by KennyTV"); + plugin.getLogger().info(getUpdateMessage()); plugin.getCommand("maintenancespigot").setExecutor(new MaintenanceSpigotCommand(this, settings)); final PluginManager pm = getServer().getPluginManager(); diff --git a/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/SettingsSpigot.java b/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/SettingsSpigot.java index 151f4cd7..70a85c0c 100644 --- a/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/SettingsSpigot.java +++ b/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/SettingsSpigot.java @@ -38,9 +38,7 @@ public final class SettingsSpigot extends Settings { if (!plugin.getDataFolder().exists()) plugin.getDataFolder().mkdirs(); createFile("spigot-config.yml"); - createFile("language.yml"); createFile("WhitelistedPlayers.yml"); - reloadConfigs(); } @@ -55,6 +53,38 @@ private void createFile(final String name) { } } + private void createAndLoadLanguageFile() { + final File file = new File(plugin.getDataFolder(), "language-" + getLanguage() + ".yml"); + if (!file.exists()) { + try (final InputStream in = plugin.getResource("language-" + getLanguage() + ".yml")) { + Files.copy(in, file.toPath()); + } catch (final IOException e) { + plugin.getLogger().warning("Unable to provide language " + getLanguage()); + if (!languageName.equals("en")) { + plugin.getLogger().warning("Falling back to default language: en"); + languageName = "en"; + createAndLoadLanguageFile(); + return; + } + } + } + try { + language = YamlConfiguration.loadConfiguration(new InputStreamReader(new FileInputStream(new File(plugin.getDataFolder(), "language-" + getLanguage() + ".yml")), StandardCharsets.UTF_8)); + } catch (final IOException e) { + throw new RuntimeException("Unable to load Maintenance language file!", e); + } + } + + @Override + public boolean updateExtraConfig() { + // Remove MySQL part from default config + /*if (configContains("mysql")) { + setToConfig("mysql", null); + return true; + }*/ + return false; + } + @Override public void saveConfig() { try { @@ -76,16 +106,14 @@ public void saveWhitelistedPlayers() { @Override public void reloadConfigs() { try { - final File file = new File(plugin.getDataFolder(), "spigot-config.yml"); - config = YamlConfiguration.loadConfiguration(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); - final File languageFile = new File(plugin.getDataFolder(), "language.yml"); - language = YamlConfiguration.loadConfiguration(new InputStreamReader(new FileInputStream(languageFile), StandardCharsets.UTF_8)); + config = YamlConfiguration.loadConfiguration(new InputStreamReader(new FileInputStream(new File(plugin.getDataFolder(), "spigot-config.yml")), StandardCharsets.UTF_8)); whitelist = YamlConfiguration.loadConfiguration(new File(plugin.getDataFolder(), "WhitelistedPlayers.yml")); } catch (final IOException e) { throw new RuntimeException("Unable to load Maintenance files!", e); } loadSettings(); + createAndLoadLanguageFile(); } @Override diff --git a/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/listener/PacketListener.java b/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/listener/PacketListener.java index fc9d0e1e..45349a89 100644 --- a/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/listener/PacketListener.java +++ b/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/listener/PacketListener.java @@ -7,13 +7,13 @@ import com.comphenix.protocol.events.PacketEvent; import com.comphenix.protocol.wrappers.WrappedGameProfile; import com.comphenix.protocol.wrappers.WrappedServerPing; -import com.google.common.collect.Lists; import eu.kennytv.maintenance.core.listener.IPingListener; import eu.kennytv.maintenance.spigot.MaintenanceSpigotBase; import eu.kennytv.maintenance.spigot.SettingsSpigot; import javax.imageio.ImageIO; import java.io.File; +import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -39,7 +39,7 @@ public void onPacketSending(final PacketEvent event) { .replace("%MAX%", Integer.toString(pl.getServer().getMaxPlayers()))); } - final List players = Lists.newArrayList(); + final List players = new ArrayList<>(); for (final String string : settings.getPlayerCountHoverMessage().split("%NEWLINE%")) players.add(new WrappedGameProfile(UUID.randomUUID(), string)); ping.setPlayers(players); diff --git a/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/listener/PlayerLoginListener.java b/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/listener/PlayerLoginListener.java index e5d42988..674f8c92 100644 --- a/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/listener/PlayerLoginListener.java +++ b/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/listener/PlayerLoginListener.java @@ -1,6 +1,5 @@ package eu.kennytv.maintenance.spigot.listener; -import com.google.common.collect.Sets; import eu.kennytv.maintenance.spigot.MaintenanceSpigotPlugin; import eu.kennytv.maintenance.spigot.SettingsSpigot; import net.md_5.bungee.api.chat.ClickEvent; @@ -14,13 +13,14 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerLoginEvent; +import java.util.HashSet; import java.util.Set; import java.util.UUID; public final class PlayerLoginListener implements Listener { private final MaintenanceSpigotPlugin plugin; private final SettingsSpigot settings; - private final Set notifiedPlayers = Sets.newHashSet(); + private final Set notifiedPlayers = new HashSet<>(); public PlayerLoginListener(final MaintenanceSpigotPlugin plugin, final SettingsSpigot settings) { this.plugin = plugin; diff --git a/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/util/BukkitSenderInfo.java b/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/util/BukkitSenderInfo.java index f7deef43..ce3a204c 100644 --- a/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/util/BukkitSenderInfo.java +++ b/Maintenance-Spigot/src/main/java/eu/kennytv/maintenance/spigot/util/BukkitSenderInfo.java @@ -6,7 +6,7 @@ import java.util.UUID; -public final class BukkitSenderInfo extends SenderInfo { +public final class BukkitSenderInfo implements SenderInfo { private final CommandSender sender; public BukkitSenderInfo(final CommandSender sender) { diff --git a/Maintenance-Spigot/src/main/resources/spigot-config.yml b/Maintenance-Spigot/src/main/resources/spigot-config.yml index 7531f7b8..5f2ad628 100644 --- a/Maintenance-Spigot/src/main/resources/spigot-config.yml +++ b/Maintenance-Spigot/src/main/resources/spigot-config.yml @@ -1,5 +1,4 @@ # MaintenanceSpigot Plugin by KennyTV -# Version ${project.version} # Important note: To use this plugin to its full extend, it requires the plugin 'ProtocolLib' # Enables maintenance-mode. @@ -33,4 +32,8 @@ timer-broadcast-for-seconds: [1200, 900, 600, 300, 120, 60, 30, 20, 10, 5, 4, 3, send-join-notification: false # If set to true, the server icon will be changed to maintenance-icon.png in the Bungee main/base-folder. -custom-maintenance-icon: false \ No newline at end of file +custom-maintenance-icon: false + +# Changes the language of command feedback/messages. +# Currently available are: en (English), de (German) +language: en \ No newline at end of file diff --git a/pom.xml b/pom.xml index a719132b..c43c4b68 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ eu.kennytv maintenance-base - 2.4 + 2.5 Maintenance pom @@ -31,7 +31,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.1.1 + 3.2.0 package @@ -44,6 +44,10 @@ com.zaxxer.hikari eu.kennytv.lib.hikari +