Compare commits

...
110 Commits
Author SHA1 Message Date
KennyTV 3b4a66b04e 2.5 Release 2018-11-17 11:46:04 +01:00
KennyTV 7384b2e55c 2.5 API 2018-11-17 11:44:28 +01:00
KennyTV f8eaed445a Version increase to 2.5 2018-11-17 11:43:43 +01:00
KennyTV dfef9190ca Some final fixes and changes 2018-11-17 11:41:51 +01:00
KennyTV 7ce61834c2 Check for other kick reasons 2018-11-16 22:23:58 +01:00
KennyTV 240a7ab242 Message changes 2018-11-16 22:08:35 +01:00
KennyTV b3de59bfba API change 2018-11-10 22:08:29 +01:00
KennyTV 5d5de39845 Make the help message a little fancier 2018-11-10 17:38:41 +01:00
KennyTV 59af774d09 Some more fixes 2018-11-10 16:50:10 +01:00
KennyTV 18828207c0 Maintenance status command + some more minor changes 2018-11-10 15:08:32 +01:00
KennyTV 5c67922996 Some fixes and changes 2018-11-09 23:20:34 +01:00
KennyTV af50a45e65 Command 2018-11-09 21:14:32 +01:00
KennyTV 7ccd265a30 pom changes 2018-11-07 21:36:29 +01:00
KennyTV e76f22f071 Timer commands for single server maintenance 2018-11-07 21:32:08 +01:00
KennyTV 3c03b719d2 API changes 2018-11-07 21:31:49 +01:00
KennyTV cd71531766 Timers for single server maintenance
Todo: Implementation in command
2018-11-07 20:02:59 +01:00
KennyTV 282c116d02 Some improvements to messages and message handling 2018-11-06 11:01:04 +01:00
KennyTV 820171916b Improve version check handling 2018-11-05 23:02:46 +01:00
KennyTV 136fbb0ba8 Improve version check handling 2018-11-05 22:58:12 +01:00
KennyTV 4f0c05c357 Further single server maintenance stuff 2018-11-05 21:24:56 +01:00
KennyTV 0377838a26 Dont save and get Spigot maintenance servers from sql for now 2018-11-04 14:43:47 +01:00
KennyTV b72ff1b772 Some message changes 2018-10-19 14:21:21 +02:00
KennyTV 287488f1b6 Some single server maintenance stuff I did during a course at university ¯\_(ツ)_/¯ 2018-10-19 12:08:37 +02:00
KennyTV 9ffb67db1f WIP: Add possibility to set single servers to maintenance 2018-10-12 23:17:46 +02:00
KennyTV a563c0a8a8 Restructured language files 2018-10-02 12:15:08 +02:00
KennyTV 234086444f WIP: Add possibility to set single servers to maintenance 2018-10-02 11:56:30 +02:00
KennyTV a93b0834a2 Remove more or less deprecated Guava usages 2018-09-30 11:29:48 +02:00
KennyTV b5550dfe82 Add multiple language support 2018-09-28 13:22:55 +02:00
KennyTV d99300ecac Version increase to 2.5-SNAPSHOT
Increase from 2.4.1-SNAPSHOT as bigger feature updates are planned
2018-09-28 12:42:06 +02:00
KennyTV 1c0688a172 Add language-de 2018-09-28 12:00:40 +02:00
KennyTV ff3b117189 Make SenderInfo an interface instead of an abstract class 2018-09-27 10:14:29 +02:00
KennyTV aaed1b32cd Fix starttimer command not working
Remove slf4j shade for now
2018-09-27 09:57:56 +02:00
KennyTV 38c8e1d2c3 Shade slf4j to fix compatibility with plugins using older Hikari dependencies 2018-09-26 11:11:56 +02:00
KennyTV 1e1792d132 Version increase to 2.4.1-SNAPSHOT
Update ProtocolLib dependency to newest release
2018-09-22 19:20:55 +02:00
KennyTV b29462a5cb 2.4 Release 2018-09-17 10:21:17 +02:00
KennyTV c9161ebe24 2.4 Release API 2018-09-17 10:17:44 +02:00
KennyTV 8441c6a8bf Prepare for 2.4 Release 2018-09-17 10:16:23 +02:00
KennyTV 72c2ba77ee Some final fixes and changes
Move kickmessage back to config
2018-09-16 22:36:12 +02:00
KennyTV a097790b76 Update dependencies 2018-09-13 10:43:09 +02:00
KennyTV b7129e8aa8 Fix raw color saving in config when upgrading from a version lower than 2.3 2018-09-08 12:29:10 +02:00
KennyTV ab9c2b8be1 Spigot Runnable fix 2018-09-08 12:13:47 +02:00
KennyTV a9a37b8fc8 Fix Bungee config not updating 2018-09-08 12:00:21 +02:00
KennyTV d50cb67a26 Add timer variable for the pingmessage
Have broadcasts for timers be set for seconds instead of just minutes + better formatting
Some language fixes
2018-09-07 22:52:20 +02:00
KennyTV 5e42500308 WIP: Add timer variable for the pingmessage
WIP: Have broadcasts for timers be set for seconds instead of just minutes + better formatting
2018-08-29 00:42:00 +02:00
KennyTV 50997a847f Language fixes and changes 2018-08-26 17:56:31 +02:00
KennyTV 2305d85c01 Switch messages to language file + small fixes 2018-08-26 12:34:28 +02:00
KennyTV 33bbc35d88 Change javadoc message to read the new config field 2018-08-26 11:50:08 +02:00
KennyTV 28b3e100fb Switch some more messages to language file 2018-08-26 11:49:13 +02:00
KennyTV edae2d699b Switch some messages to language file 2018-08-25 12:37:23 +02:00
KennyTV 0cc477a769 Prepare new language file 2018-08-25 12:19:01 +02:00
KennyTV 53b84a999f Change helpmessage 2018-08-25 11:41:33 +02:00
KennyTV 49487c11ff Don't enable/disable maintenance mode if it's already in the goal's state 2018-08-25 11:39:49 +02:00
KennyTV 0c4070b7a7 Add possibility to show the default playercount 2018-08-22 20:11:24 +02:00
KennyTV 67909a4862 Relocate HikariCP dependency 2018-08-22 19:08:20 +02:00
KennyTV 28ee563083 Don't spam update notifications on every single join
Also, minor cleanup #3
2018-08-21 21:05:48 +02:00
KennyTV 28b2b528c1 Minor cleanup #2 2018-08-21 21:01:12 +02:00
KennyTV a53d9d0850 Minor cleanup 2018-08-21 20:58:59 +02:00
KennyTV 873a8812aa Add variables to show normal playercount 2018-08-21 20:53:15 +02:00
KennyTV 19ebc90963 Whoops 2018-08-17 12:37:49 +02:00
KennyTV dfbd1381de Version increase to 2.4-SNAPSHOT 2018-08-17 12:36:08 +02:00
KennyTV c9fe48a067 2.3.1 Release
Hotfix before the release
2018-08-17 12:30:01 +02:00
KennyTV 49b022b665 Quick hotfix for the 2.3.1 Release
When enabling maintenance on one proxy with MySQL enabled, the other ones will now also kick all non permitted players and switch their ServerListPlus state
2018-08-17 11:29:28 +02:00
KennyTV 86be23ae5f Minor changes 2018-08-16 19:05:44 +02:00
KennyTV 420412978e 2.3.1 Release 2018-08-16 17:56:28 +02:00
KennyTV 25e2f4dae2 2.3.1 Release 2018-08-16 17:54:57 +02:00
KennyTV d767be96b5 Fix 2018-08-15 11:54:35 +02:00
KennyTV 6d73acca9b Only check the mysql delay if it's at least a second 2018-08-15 11:11:25 +02:00
KennyTV 1f116374ad Fix permission checks for help page 2018-08-11 11:10:25 +02:00
KennyTV d0b7d96208 Fix updated config being overwritten again 2018-08-08 11:56:32 +02:00
KennyTV 16285d7064 Change some javadocs 2018-08-07 23:31:02 +02:00
KennyTV 1f27084fe1 Return empty string for pingmessages if config list is empty 2018-08-07 23:04:09 +02:00
KennyTV 261aace0db Remove unnecessary (second) result closing 2018-08-07 22:58:06 +02:00
KennyTV 344b910214 Remove unused method 2018-08-07 22:49:22 +02:00
KennyTV fbaa4896e1 Replace deprecated ProtocolLib packet 2018-08-07 14:55:19 +02:00
KennyTV 2f93064f60 Some pom changes 2018-08-07 13:51:59 +02:00
KennyTV 65b47c5e07 Only show the commands you have the permission to execute in the helppage 2018-08-06 21:12:36 +02:00
KennyTV d70d01f2d3 Fix config updating unnecessary value in Spigot version 2018-07-27 12:34:09 +02:00
KennyTV 769d7d3bcd Minor improvement 2018-07-27 12:28:07 +02:00
KennyTV a5f47688e0 Minor improvement 2018-07-27 11:50:19 +02:00
KennyTV 7d2e6a25a4 Move license and whitelistedplayers file to core module 2018-07-25 00:29:06 +02:00
KennyTV 69999b3b7a Fix MySQL millisecondsToCheck variable 2018-07-24 22:29:03 +02:00
KennyTV 94d1bd4eb9 Only make a request to the database at least x seconds after the last one 2018-07-23 11:52:30 +02:00
KennyTV c18e8b7ab7 Add warning and backup string if config value is null 2018-07-23 11:10:16 +02:00
KennyTV 9f45187300 Add warning and backup string if config value is null 2018-07-23 11:09:08 +02:00
KennyTV 0c6ba8a9b7 Updated BungeeCord dependency to 1.13-SNAPSHOT 2018-07-21 11:02:55 +02:00
KennyTV 1af69f2e8b Version increase to 2.3.1-SNAPSHOT 2018-07-18 15:50:35 +02:00
KennyTV a3b836b1c5 2.3 Release 2018-07-17 11:45:43 +02:00
KennyTV 1eca6c81ad Version increase for the 2.3 Release 2018-07-17 11:41:03 +02:00
KennyTV b9b4a78b5c Minor cleanup 2018-07-16 21:52:27 +02:00
KennyTV fda23c5539 The whitelist command now also shows the UUID of the player 2018-07-16 20:25:05 +02:00
KennyTV 8297321971 Changed help message order 2018-07-16 18:04:14 +02:00
KennyTV cfeaf00f26 Fixed wrong command descriptions 2018-07-16 13:22:46 +02:00
KennyTV 5ee1b32249 Uncommented new help messages 2018-07-16 13:07:59 +02:00
KennyTV b69f0dc90e Added missing motd command permission 2018-07-14 22:27:20 +02:00
KennyTV fe6cae4e47 Added motdlist command 2018-07-09 16:33:51 +02:00
KennyTV b494b5c23c Reworked setmotd command 2018-07-09 15:49:54 +02:00
KennyTV 3bd3395128 Removed setmotd command 2018-07-08 11:29:20 +02:00
KennyTV 3e3f63220d Config fix 2018-07-08 11:25:47 +02:00
KennyTV ccba0f042f Version increase to 2.3-SNAPSHOT 2018-07-08 11:20:18 +02:00
KennyTV abdd89259d Added multiple pingmessages + minor improvements 2018-07-08 10:54:51 +02:00
KennyTV 256f203c48 Minor code change 2018-06-18 11:17:47 +02:00
KennyTV 205412b02c Minor improvement 2018-06-18 11:17:06 +02:00
KennyTV 990289feb2 Fixed a problem with the setmotd command 2018-06-17 20:57:50 +02:00
KennyTV 44b1ff1a1f Fixed a typo 2018-06-17 20:27:01 +02:00
KennyTV f9e11bb9e5 Removed unused method 2018-06-17 19:58:21 +02:00
KennyTV eef1584b1c Small logic change 2018-06-17 18:51:35 +02:00
KennyTV 937dd84d1c Added permission per subcommand 2018-06-17 18:40:47 +02:00
KennyTV 80b9fe280b Message change 2018-06-17 18:29:58 +02:00
KennyTV 3892892792 Version increase to 2.2.3-SNAPSHOT 2018-06-17 18:06:59 +02:00
KennyTV 519551e76c Removed Spigot dependency from Core module 2018-06-17 14:36:18 +02:00
47 changed files with 1413 additions and 488 deletions

No files matched your search

Binary file not shown.
+3 -3
View File
@@ -6,7 +6,7 @@
<parent>
<artifactId>maintenance-base</artifactId>
<groupId>eu.kennytv</groupId>
<version>2.2.2</version>
<version>2.5</version>
</parent>
<artifactId>maintenance-api</artifactId>
@@ -16,13 +16,13 @@
<dependency>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
<version>1.12-SNAPSHOT</version>
<version>1.13-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
<version>1.13.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
@@ -24,7 +24,7 @@ public interface IMaintenance {
boolean isMaintenance();
/**
* @return true if a timer task is currently running
* @return true if a start- or endtimer task is currently running
*/
boolean isTaskRunning();
@@ -10,12 +10,14 @@ import java.util.UUID;
public interface ISettings {
/**
* Note that the value might need a few seconds to update, if you're on BungeeCord with MySQL enabled
*
* @return true if maintenance is currently enabled
*/
boolean isMaintenance();
/**
* @return true if "join-notification" is set to true in the config
* @return true if "send-join-notification" is set to true in the config
*/
boolean isJoinNotifications();
@@ -40,10 +42,10 @@ public interface ISettings {
/**
* Removes a player from the maintenance whitelist.
*
* @param name name of the player to remove in lowercase letters
* @param name name of the player to remove with original lower-/uppercase letters
* @return true if removing the player was successful
* @deprecated if a player changes their name, the list will still contain the old one
* @see #removeWhitelistedPlayer(UUID)
* @deprecated if a player changes their name, the list will still contain the old one and thus this might not work
*/
@Deprecated
boolean removeWhitelistedPlayer(String name);
@@ -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);
}
@@ -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.
* <p>
* This class is NOT available for the Spigot version!
* Only access this class if you're running the plugin on a BungeeCord server!
* </p>
*
* @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();
}
}
@@ -1,16 +1,18 @@
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;
/**
* Utility class to get the {@link IMaintenance} instance for the Spigot/Bukkit version of the plugin.
* Utility class to get the {@link IMaintenance} instance for the Spigot version of the plugin.
* <p>
* This class is NOT available for the BungeeCord version!
* Only access this class if you're running the plugin on a Spigot server!
* </p>
*
* @author KennyTV
* @since 2.1
* @since 2.5
*/
public final class MaintenanceSpigotAPI {
@@ -23,7 +25,6 @@ public final class MaintenanceSpigotAPI {
final Plugin maintenance = Bukkit.getPluginManager().getPlugin("MaintenanceSpigot");
if (maintenance == null)
Bukkit.getLogger().warning("Could not get instance of MaintenanceSpigot!");
return ((IMaintenanceBase) maintenance).getApi();
}
}
+3 -3
View File
@@ -6,7 +6,7 @@
<parent>
<artifactId>maintenance-base</artifactId>
<groupId>eu.kennytv</groupId>
<version>2.2.2</version>
<version>2.5</version>
</parent>
<artifactId>maintenance-bungee</artifactId>
@@ -29,7 +29,7 @@
<dependency>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
<version>1.12-SNAPSHOT</version>
<version>1.13-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -41,7 +41,7 @@
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.1.0</version>
<version>3.2.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
@@ -2,39 +2,52 @@ package eu.kennytv.maintenance.bungee;
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<String, Integer> 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(plugin);
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));
@@ -60,24 +73,80 @@ public final class MaintenanceBungeePlugin extends MaintenanceModePlugin {
settings.reloadConfigs();
}
if (serverListPlusHook != null)
serverListPlusHook.setEnabled(!maintenance);
serverActions(maintenance);
if (isTaskRunning())
cancelTask();
}
void serverActions(final boolean maintenance) {
if (serverListPlusHook != null)
serverListPlusHook.setEnabled(!maintenance);
if (maintenance) {
getProxy().getPlayers().stream()
.filter(p -> !p.hasPermission("maintenance.bypass") && !settings.getWhitelistedPlayers().containsKey(p.getUniqueId()))
.forEach(p -> p.disconnect(settings.getKickMessage().replace("%NEWLINE%", "\n")));
getProxy().broadcast(settings.getMaintenanceActivated());
getProxy().broadcast(settings.getMessage("maintenanceActivated"));
} else
getProxy().broadcast(settings.getMaintenanceDeactivated());
getProxy().broadcast(settings.getMessage("maintenanceDeactivated"));
}
@Override
public int schedule(final Runnable runnable) {
return getProxy().getScheduler().schedule(plugin, runnable, 0, 1, TimeUnit.MINUTES).getId();
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
@@ -88,7 +157,14 @@ public final class MaintenanceBungeePlugin extends MaintenanceModePlugin {
@Override
public void cancelTask() {
getProxy().getScheduler().cancel(taskId);
setTaskId(0);
runnable = null;
taskId = 0;
}
public void cancelSingleTask(final ServerInfo server) {
final Integer task = serverTaskIds.remove(server.getName());
if (task != null)
getProxy().getScheduler().cancel(task);
}
@Override
@@ -114,4 +190,8 @@ public final class MaintenanceBungeePlugin extends MaintenanceModePlugin {
public ProxyServer getProxy() {
return plugin.getProxy();
}
public Logger getLogger() {
return plugin.getLogger();
}
}
@@ -10,22 +10,33 @@ import net.md_5.bungee.config.Configuration;
import net.md_5.bungee.config.YamlConfiguration;
import java.io.*;
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<String> maintenanceServers;
private Configuration config;
private Configuration language;
private Configuration whitelist;
private Configuration spigotServers;
private String fallbackServer;
SettingsBungee(final MaintenanceBungeeBase plugin) {
private long millisecondsToCheck;
private long lastMySQLCheck;
SettingsBungee(final MaintenanceBungeePlugin maintenancePlugin, final MaintenanceBungeeBase plugin) {
super(maintenancePlugin);
this.maintenancePlugin = maintenancePlugin;
this.plugin = plugin;
final PluginManager pm = plugin.getProxy().getPluginManager();
@@ -33,7 +44,12 @@ public final class SettingsBungee extends Settings {
pm.registerListener(plugin, listener);
pingListener = listener;
reloadConfigs(createFiles());
if (!plugin.getDataFolder().exists())
plugin.getDataFolder().mkdirs();
createFile("bungee-config.yml");
createFile("WhitelistedPlayers.yml");
createFile("SpigotServers.yml");
reloadConfigs();
final Configuration mySQLSection = config.getSection("mysql");
if (mySQLSection.getBoolean("use-mysql", false)) {
@@ -49,24 +65,80 @@ 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;
}
}
private void createFile(final String name) {
final File file = new File(plugin.getDataFolder(), name);
if (!file.exists()) {
try (final InputStream in = plugin.getResourceAsStream(name)) {
Files.copy(in, file.toPath());
} catch (final IOException e) {
throw new RuntimeException("Unable to create " + name + " file for MaintenanceBungee", e);
}
}
}
@Override
public boolean updateExtraConfig() {
// 2.3.1 mysql.update-interval
if (!configContains("mysql.update-interval")) {
setToConfig("mysql.update-interval", 15);
return true;
}
return false;
}
@Override
public void reloadConfigs() {
reloadConfigs(false);
try {
config = YamlConfiguration.getProvider(YamlConfiguration.class)
.load(new InputStreamReader(new FileInputStream(new File(plugin.getDataFolder(), "bungee-config.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
public void saveConfig() {
final File file = new File(plugin.getDataFolder(), "bungee-config.yml");
try {
YamlConfiguration.getProvider(YamlConfiguration.class).save(config, new OutputStreamWriter(new FileOutputStream(file), "UTF8"));
YamlConfiguration.getProvider(YamlConfiguration.class).save(config, new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8));
} catch (final IOException e) {
throw new RuntimeException("Unable to save bungee-config.yml!", e);
}
@@ -74,35 +146,38 @@ public final class SettingsBungee extends Settings {
@Override
public void saveWhitelistedPlayers() {
final File file = new File(plugin.getDataFolder(), "WhitelistedPlayers.yml");
try {
YamlConfiguration.getProvider(YamlConfiguration.class).save(whitelist, file);
} catch (final IOException e) {
throw new RuntimeException("Unable to save WhitelistedPlayers.yml!", e);
}
saveFile(whitelist, "WhitelistedPlayers.yml");
}
private void reloadConfigs(final boolean createdNewWhitelist) {
final File file = new File(plugin.getDataFolder(), "bungee-config.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 {
config = YamlConfiguration.getProvider(YamlConfiguration.class).load(new InputStreamReader(new FileInputStream(file), "UTF8"));
whitelist = YamlConfiguration.getProvider(YamlConfiguration.class).load(new File(plugin.getDataFolder(), "WhitelistedPlayers.yml"));
YamlConfiguration.getProvider(YamlConfiguration.class).save(config, file);
} catch (final IOException e) {
throw new RuntimeException("Unable to load bungee-config.yml!", e);
throw new RuntimeException("Unable to save " + name + "!", e);
}
if (createdNewWhitelist) {
whitelist.set("a8179ff3-c201-4a75-bdaa-9d14aca6f83f", "KennyTV");
saveWhitelistedPlayers();
}
loadSettings();
}
@Override
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<String> list = spigotServers.getStringList("maintenance-on");
maintenanceServers = list == null ? new HashSet<>() : new HashSet<>(list);
}*/
final List<String> list = spigotServers.getStringList("maintenance-on");
maintenanceServers = list == null ? new HashSet<>() : new HashSet<>(list);
}
@Override
@@ -111,36 +186,23 @@ public final class SettingsBungee extends Settings {
}
@Override
public boolean createFiles() {
if (!plugin.getDataFolder().exists())
plugin.getDataFolder().mkdirs();
final File file = new File(plugin.getDataFolder(), "bungee-config.yml");
if (!file.exists()) {
try (final InputStream in = plugin.getResourceAsStream("bungee-config.yml")) {
Files.copy(in, file.toPath());
} catch (final IOException e) {
throw new RuntimeException("Unable to create bungee-config.yml file for MaintenanceBungee", e);
}
public String getConfigString(final String path) {
final String s = config.getString(path);
if (s == null) {
plugin.getLogger().warning("The config is missing the following string: " + path);
return "null";
}
boolean createdNewWhitelist = false;
final File whitelistFile = new File(plugin.getDataFolder(), "WhitelistedPlayers.yml");
if (!whitelistFile.exists()) {
createdNewWhitelist = true;
try {
whitelistFile.createNewFile();
} catch (final IOException e) {
throw new RuntimeException("Unable to create WhitelistedPlayers.yml file for MaintenanceBungee", e);
}
}
return createdNewWhitelist;
return s;
}
@Override
public String getConfigString(final String path) {
return ChatColor.translateAlternateColorCodes('&', config.getString(path));
public String getMessage(final String path) {
final String s = language.getString(path);
if (s == null) {
plugin.getLogger().warning("The language file is missing the following string: " + path);
return "null";
}
return ChatColor.translateAlternateColorCodes('&', s);
}
@Override
@@ -149,8 +211,13 @@ public final class SettingsBungee extends Settings {
}
@Override
public List<Integer> getBroadcastIntervallList() {
return config.getIntList("timer-broadcasts-for-minutes");
public List<Integer> getConfigIntList(final String path) {
return config.getIntList(path);
}
@Override
public List<String> getConfigList(final String path) {
return config.getStringList(path);
}
@Override
@@ -158,20 +225,36 @@ public final class SettingsBungee extends Settings {
config.set(path, var);
}
@Override
public boolean configContains(final String path) {
return config.contains(path);
}
@Override
public String getColoredString(final String message) {
return ChatColor.translateAlternateColorCodes('&', message);
}
@Override
public boolean isMaintenance() {
if (mySQL != null) {
if (mySQL != null && (millisecondsToCheck == -1 || System.currentTimeMillis() - lastMySQLCheck > millisecondsToCheck)) {
mySQL.executeQuery(maintenanceQuery, rs -> {
try {
if (rs.next())
maintenance = Boolean.parseBoolean(rs.getString("value"));
rs.close();
if (rs.next()) {
final boolean databaseValue = Boolean.parseBoolean(rs.getString("value"));
if (databaseValue != maintenance)
maintenancePlugin.serverActions(maintenance);
maintenance = databaseValue;
}
} catch (final SQLException e) {
e.printStackTrace();
}
}, "maintenance");
if (millisecondsToCheck != -1)
lastMySQLCheck = System.currentTimeMillis();
}
return maintenance;
}
@@ -184,6 +267,8 @@ public final class SettingsBungee extends Settings {
plugin.getProxy().getScheduler().runAsync(plugin, () -> {
final String s = String.valueOf(maintenance);
mySQL.executeUpdate(updateQuery, "maintenance", s, s);
if (millisecondsToCheck != -1)
lastMySQLCheck = System.currentTimeMillis();
});
this.maintenance = maintenance;
}
@@ -191,4 +276,17 @@ public final class SettingsBungee extends Settings {
public MySQL getMySQL() {
return mySQL;
}
public Set<String> getMaintenanceServers() {
return maintenanceServers;
}
public void saveServersToConfig() {
spigotServers.set("maintenance-on", new ArrayList<>(maintenanceServers));
saveSpigotServers();
}
public String getFallbackServer() {
return fallbackServer;
}
}
@@ -4,61 +4,65 @@ import eu.kennytv.maintenance.bungee.MaintenanceBungeePlugin;
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.ChatColor;
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(plugin.getPrefix() + "§cThere's no player online with that name.");
sender.sendMessage(settings.getMessage("playerNotOnline"));
return;
}
if (settings.addWhitelistedPlayer(selected.getUniqueId(), selected.getName()))
sender.sendMessage(plugin.getPrefix() + "§aAdded §b" + selected.getName() + " §ato the maintenance whitelist!");
sender.sendMessage(settings.getMessage("whitelistAdded").replace("%PLAYER%", selected.getName()));
else
sender.sendMessage(plugin.getPrefix() + "§b" + selected.getName() + " §calready is in the maintenance whitelist!");
sender.sendMessage(settings.getMessage("whitelistAlreadyAdded").replace("%PLAYER%", selected.getName()));
}
@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.toLowerCase()))
sender.sendMessage(plugin.getPrefix() + "§aRemoved §b" + name.toLowerCase() + " §afrom the maintenance whitelist!");
if (settings.removeWhitelistedPlayer(name))
sender.sendMessage(settings.getMessage("whitelistRemoved").replace("%PLAYER%", name));
else
sender.sendMessage(plugin.getPrefix() + "§cThere is no player with that name in the maintenance whitelist!");
sender.sendMessage(settings.getMessage("whitelistNotFound"));
return;
}
if (settings.removeWhitelistedPlayer(selected.getUniqueId()))
sender.sendMessage(plugin.getPrefix() + "§aRemoved §b" + selected.getName() + " §afrom the maintenance whitelist!");
sender.sendMessage(settings.getMessage("whitelistRemoved").replace("%PLAYER%", selected.getName()));
else
sender.sendMessage(plugin.getPrefix() + "§cThis player is not in the maintenance whitelist!");
sender.sendMessage(settings.getMessage("whitelistNotFound"));
}
@Override
protected void checkForUpdate(final SenderInfo sender) {
if (plugin.updateAvailable()) {
sender.sendMessage(plugin.getPrefix() + "§cNewest version available: §aVersion " + plugin.getNewestVersion() + "§c, you're still on §a" + plugin.getVersion());
sender.sendMessage(plugin.getPrefix() + "§cNewest version available: §aVersion " + plugin.getNewestVersion() + "§c, you're on §a" + plugin.getVersion());
sender.sendMessage(plugin.getPrefix() + "§c§lWARNING: §cYou will have to restart the proxy to prevent further issues and to complete the update!" +
" If you can't do that, don't update!");
final TextComponent tc = new TextComponent("§6× §8[§aUpdate§8]");
tc.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/maintenance forceupdate"));
tc.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText("§aClick here to update the plugin")));
tc.addExtra(" §8< §7Or use the command §c/maintenace forceupdate");
tc.addExtra(" §8< §7Or use the command §c/maintenance forceupdate");
((ProxiedSenderInfo) sender).sendMessage(tc);
} else
@@ -66,7 +70,92 @@ public final class MaintenanceBungeeCommand extends MaintenanceCommand {
}
@Override
protected String getColoredString(final String message) {
return ChatColor.translateAlternateColorCodes('&', message);
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;
}
}
@@ -12,9 +12,14 @@ import net.md_5.bungee.api.plugin.Listener;
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<UUID> notifiedPlayers = new HashSet<>();
public PostLoginListener(final MaintenanceBungeePlugin plugin, final SettingsBungee settings) {
this.plugin = plugin;
@@ -32,16 +37,17 @@ public final class PostLoginListener implements Listener {
if (settings.isJoinNotifications())
plugin.getProxy().getPlayers().stream().filter(player -> player.hasPermission("maintenance.joinnotification"))
.forEach(player -> player.sendMessage(settings.getJoinNotification().replace("%PLAYER%", p.getName())));
.forEach(player -> player.sendMessage(settings.getMessage("joinNotification").replace("%PLAYER%", p.getName())));
return;
}
}
if (!p.hasPermission("maintenance.admin")) return;
if (!p.hasPermission("maintenance.admin") || notifiedPlayers.contains(p.getUniqueId())) return;
plugin.async(() -> {
if (plugin.updateAvailable()) {
p.sendMessage(plugin.getPrefix() + "§cThere is a newer version available: §aVersion " + plugin.getNewestVersion() + "§c, you're still on §a" + plugin.getVersion());
p.sendMessage(plugin.getPrefix() + "§cThere is a newer version available: §aVersion " + plugin.getNewestVersion() + "§c, you're on §a" + plugin.getVersion());
notifiedPlayers.add(p.getUniqueId());
final TextComponent tc1 = new TextComponent(TextComponent.fromLegacyText(plugin.getPrefix() + " "));
final TextComponent tc2 = new TextComponent(TextComponent.fromLegacyText("§cDownload it at: §6https://www.spigotmc.org/resources/maintenancemode.40699/"));
@@ -29,11 +29,19 @@ public final class ProxyPingListener implements Listener, IPingListener {
if (!settings.isMaintenance()) return;
final ServerPing ping = event.getResponse();
ping.setVersion(new ServerPing.Protocol(settings.getPlayerCountMessage(), 1));
ping.setDescription(settings.getPingMessage().replace("%NEWLINE%", "\n"));
ping.setPlayers(new ServerPing.Players(0, 0, new ServerPing.PlayerInfo[]{
if (settings.hasCustomPlayerCountMessage()) {
ping.getVersion().setProtocol(1);
ping.getVersion().setName(settings.getPlayerCountMessage()
.replace("%ONLINE%", Integer.toString(ping.getPlayers().getOnline()))
.replace("%MAX%", Integer.toString(ping.getPlayers().getMax())));
}
ping.setDescription(settings.getRandomPingMessage());
ping.getPlayers().setOnline(0);
ping.getPlayers().setMax(0);
ping.getPlayers().setSample(new ServerPing.PlayerInfo[]{
new ServerPing.PlayerInfo(settings.getPlayerCountHoverMessage().replace("%NEWLINE%", "\n"), "")
}));
});
if (settings.hasCustomIcon() && favicon != null)
ping.setFavicon(favicon);
@@ -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);
}
}
@@ -12,6 +12,7 @@ import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.TimeUnit;
@@ -266,7 +267,7 @@ public final class MetricsLite {
}
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
final GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
gzip.write(str.getBytes("UTF-8"));
gzip.write(str.getBytes(StandardCharsets.UTF_8));
gzip.close();
return outputStream.toByteArray();
}
@@ -65,9 +65,4 @@ public final class MySQL {
executeUpdate(query, res -> {
}, objects);
}
public void close() {
if (hikariDataSource != null && !hikariDataSource.isClosed())
hikariDataSource.close();
}
}
@@ -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());
}
}
@@ -7,7 +7,7 @@ import net.md_5.bungee.api.connection.ProxiedPlayer;
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) {
@@ -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
@@ -1,42 +1,42 @@
# MaintenanceBungee Plugin by KennyTV
# Version ${project.version}
# MaintenanceBungee Plugin by KennyTV
# Enables maintenance-mode.
enable-maintenance-mode: false
# The message shown in the multiplayer server list motd.
pingmessage: "&cMaintenance mode!%NEWLINE%&6We will be back soon!"
# If you put in multiple entries, one of them will be chosen randomly on every ping.
pingmessages:
- "&cMaintenance mode!%NEWLINE%&6We will be back soon!"
#- "Another entry"
# Is shown at the top right corner of the server in the serverlist,
# If set to true, the message below will be shown at the top right corner of the server in the serverlist,
# where the playercount would normally be displayed.
# If set to false, the normal playercount will be shown.
# Alternatively you can use '%ONLINE%' and '%MAX% if you want to include the playercount in a custom message (e.g. '&cMaintenance &7%ONLINE%&8/&7%MAX%').
enable-playercountmessage: true
playercountmessage: "&4Maintenance"
# Is shown when you move your mouse above the text at the top right corner of the server in the serverlist,
# where the playercount would normally be displayed.
playercounthovermessage: "&cCurrently under%NEWLINE%&cmaintenance"
# Will be shown, when a player tries to join on the server without the permission.
# Is shown when a player tries to join while maintenance is enabled and they don't have the permission to bypass it.
kickmessage: "&cThe server is currently under maintenance!%NEWLINE%Try again later!"
# Some self explanatory messages
no-permission: "&cYou do not have the permission to execute that command."
maintenance-activated: "&6Maintenance mode is now activated."
maintenance-deactivated: "&6Maintenance mode is now deactivated."
starttimer-broadcast-mesage: '&8[&eMaintenance&8] &7Maintenance mode will be enabled in &6%MINUTES% minutes&7.'
endtimer-broadcast-mesage: '&8[&eMaintenance&8] &7Maintenance mode will be disabled in &6%MINUTES% minutes&7.'
# If using the timer command: In what intervalls before enabling/disabling maintenance there will be a broadcast.
timer-broadcasts-for-minutes: [60, 30, 15, 10, 5, 4, 3, 2, 1]
timer-broadcast-for-seconds: [1200, 900, 600, 300, 120, 60, 30, 20, 10, 5, 4, 3, 2, 1]
# If set to true, players with the maintenance.joinnotification permission will receive a message,
# that a player tried to join the server while maintenance is enabled.
send-join-notification: false
join-notification: "&e%PLAYER% &ctried to join the server."
# 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
@@ -47,3 +47,7 @@ mysql:
password: password
# A new table with this name will be created on first startup when 'use-mysql' is set to true.
table: maintenance_settings
# Requests to the database will only be made at least x seconds after the last request,
# so there won't be a request on every single ping on a server with many players.
# Set this to 0 to make a database request on every single ping.
update-interval: 15
+1 -7
View File
@@ -6,19 +6,13 @@
<parent>
<artifactId>maintenance-base</artifactId>
<groupId>eu.kennytv</groupId>
<version>2.2.2</version>
<version>2.5</version>
</parent>
<artifactId>maintenance-core</artifactId>
<name>Maintenance-Core</name>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.minecrell</groupId>
<artifactId>ServerListPlus</artifactId>
@@ -2,6 +2,9 @@ package eu.kennytv.maintenance.core;
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;
@@ -10,20 +13,19 @@ import java.net.URL;
import java.net.URLConnection;
public abstract class MaintenanceModePlugin implements IMaintenance {
protected final String version;
protected int taskId;
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;
// Changed the loading of the maintenance icon to be more predictable
// It will load directly on startup and can now reloaded by using the "/maintenance reload" command as well
// Changed the reload message to read the proper changes
// API fix
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
@@ -33,23 +35,24 @@ public abstract class MaintenanceModePlugin implements IMaintenance {
@Override
public String getVersion() {
return version;
return version.toString();
}
@Override
public boolean isTaskRunning() {
return taskId != 0;
return taskId != 0 && runnable != null;
}
public void setTaskId(final int taskId) {
this.taskId = taskId;
public void startMaintenanceRunnable(final int minutes, final boolean enable) {
runnable = new MaintenanceRunnable(this, (Settings) getSettings(), minutes, enable);
taskId = startMaintenanceRunnable(runnable);
}
public String getNewestVersion() {
public Version getNewestVersion() {
return newestVersion;
}
public abstract int schedule(Runnable runnable);
protected abstract int startMaintenanceRunnable(Runnable runnable);
public abstract void async(Runnable runnable);
@@ -59,25 +62,57 @@ public abstract class MaintenanceModePlugin implements IMaintenance {
public abstract void broadcast(String message);
public MaintenanceRunnable getRunnable() {
return runnable;
}
public String getPrefix() {
return prefix;
}
public boolean updateAvailable() {
public ServerType getServerType() {
return serverType;
}
public String formatedTimer() {
if (!isTaskRunning()) return "-";
final int preHours = runnable.getSecondsLeft() / 60;
final int minutes = preHours % 60;
final int seconds = runnable.getSecondsLeft() % 60;
return String.format("%02d:%02d:%02d", preHours / 60, minutes, seconds);
}
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;
@@ -1,61 +1,95 @@
package eu.kennytv.maintenance.core;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import eu.kennytv.maintenance.api.ISettings;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.*;
public abstract class Settings implements ISettings {
protected final Map<UUID, String> whitelistedPlayers = Maps.newHashMap();
private static final Random RANDOM = new Random();
protected final Map<UUID, String> whitelistedPlayers = new HashMap<>();
private final MaintenanceModePlugin plugin;
protected boolean maintenance;
private Set<Integer> broadcastIntervalls;
private String timerBroadcastMessage;
private String endtimerBroadcastMessage;
private String pingMessage;
private String kickMessage;
private String joinNotification;
private String noPermMessage;
private String maintenanceActivated;
private String maintenanceDeactivated;
private List<String> pingMessages;
private String playerCountMessage;
private String playerCountHoverMessage;
private boolean joinNotifications;
private String kickMessage;
protected String languageName;
private boolean customPlayerCountMessage;
private boolean customMaintenanceIcon;
private boolean joinNotifications;
protected Settings(final MaintenanceModePlugin plugin) {
this.plugin = plugin;
}
protected void loadSettings() {
timerBroadcastMessage = getConfigString("starttimer-broadcast-mesage");
endtimerBroadcastMessage = getConfigString("endtimer-broadcast-mesage");
pingMessage = getConfigString("pingmessage");
kickMessage = getConfigString("kickmessage");
joinNotification = getConfigString("join-notification");
noPermMessage = getConfigString("no-permission");
maintenanceActivated = getConfigString("maintenance-activated");
maintenanceDeactivated = getConfigString("maintenance-deactivated");
updateConfig();
pingMessages = getConfigList("pingmessages");
maintenance = getConfigBoolean("enable-maintenance-mode");
joinNotifications = getConfigBoolean("send-join-notification");
customPlayerCountMessage = getConfigBoolean("enable-playercountmessage");
customMaintenanceIcon = getConfigBoolean("custom-maintenance-icon");
broadcastIntervalls = Sets.newHashSet(getBroadcastIntervallList());
playerCountMessage = getConfigString("playercountmessage");
playerCountHoverMessage = getConfigString("playercounthovermessage");
if (hasCustomIcon())
joinNotifications = getConfigBoolean("send-join-notification");
broadcastIntervalls = new HashSet<>(getConfigIntList("timer-broadcast-for-seconds"));
playerCountMessage = getColoredString(getConfigString("playercountmessage"));
playerCountHoverMessage = getColoredString(getConfigString("playercounthovermessage"));
kickMessage = getColoredString(getConfigString("kickmessage"));
languageName = getConfigString("language").toLowerCase();
if (customMaintenanceIcon)
reloadMaintenanceIcon();
loadExtraSettings();
}
public abstract void saveWhitelistedPlayers();
private void updateConfig() {
boolean fileChanged = false;
public abstract boolean createFiles();
// 2.3 pingmessage -> pingmessages
if (configContains("pingmessage")) {
final List<String> list = new ArrayList<>();
list.add(getConfigString("pingmessage"));
setToConfig("pingmessages", list);
setToConfig("pingmessage", null);
fileChanged = true;
}
// 2.4 enable-playercountmessage
if (!configContains("enable-playercountmessage")) {
setToConfig("enable-playercountmessage", true);
fileChanged = true;
}
// 2.4. timer-broadcasts-for-minutes -> timer-broadcast-for-seconds
if (configContains("timer-broadcasts-for-minutes") || !configContains("timer-broadcast-for-seconds")) {
setToConfig("timer-broadcast-for-seconds", Arrays.asList(1200, 900, 600, 300, 120, 60, 30, 20, 10, 5, 4, 3, 2, 1));
setToConfig("timer-broadcasts-for-minutes", null);
fileChanged = true;
}
// 2.5 language
if (!configContains("language")) {
setToConfig("language", "en");
}
if (updateExtraConfig() || fileChanged) {
saveConfig();
reloadConfigs();
}
}
public boolean updateExtraConfig() {
return false;
}
public abstract void saveWhitelistedPlayers();
public abstract String getConfigString(String path);
public abstract String getMessage(String path);
public abstract boolean getConfigBoolean(String path);
public abstract List<Integer> getBroadcastIntervallList();
public abstract List<Integer> getConfigIntList(String path);
public abstract List<String> getConfigList(String path);
public abstract void loadExtraSettings();
@@ -67,36 +101,16 @@ public abstract class Settings implements ISettings {
public abstract void setToConfig(String path, Object var);
public String getTimerBroadcastMessage() {
return timerBroadcastMessage;
public abstract boolean configContains(String path);
public abstract String getColoredString(String s);
public List<String> getPingMessages() {
return pingMessages;
}
public String getEndtimerBroadcastMessage() {
return endtimerBroadcastMessage;
}
public String getPingMessage() {
return pingMessage;
}
public String getKickMessage() {
return kickMessage;
}
public String getJoinNotification() {
return joinNotification;
}
public String getNoPermMessage() {
return noPermMessage;
}
public String getMaintenanceActivated() {
return maintenanceActivated;
}
public String getMaintenanceDeactivated() {
return maintenanceDeactivated;
public Set<Integer> getBroadcastIntervalls() {
return broadcastIntervalls;
}
public String getPlayerCountMessage() {
@@ -107,10 +121,28 @@ public abstract class Settings implements ISettings {
return playerCountHoverMessage;
}
public String getKickMessage() {
return kickMessage;
}
public String getLanguage() {
return languageName;
}
public void setMaintenance(final boolean maintenance) {
this.maintenance = maintenance;
}
public String getRandomPingMessage() {
if (pingMessages.isEmpty()) return "";
final String s = pingMessages.size() > 1 ? pingMessages.get(RANDOM.nextInt(pingMessages.size())) : pingMessages.get(0);
return getColoredString(s.replace("%NEWLINE%", "\n").replace("%TIMER%", plugin.formatedTimer()));
}
public boolean hasCustomPlayerCountMessage() {
return customPlayerCountMessage;
}
@Override
public boolean isMaintenance() {
return maintenance;
@@ -126,10 +158,6 @@ public abstract class Settings implements ISettings {
return customMaintenanceIcon;
}
public Set<Integer> getBroadcastIntervalls() {
return broadcastIntervalls;
}
@Override
public Map<UUID, String> getWhitelistedPlayers() {
return whitelistedPlayers;
@@ -147,8 +175,10 @@ public abstract class Settings implements ISettings {
@Deprecated
@Override
public boolean removeWhitelistedPlayer(final String name) {
if (!whitelistedPlayers.containsValue(name)) return false;
final UUID uuid = whitelistedPlayers.entrySet().stream().filter(entry -> entry.getValue().equals(name)).findFirst().get().getKey();
final Map.Entry<UUID, String> entry = whitelistedPlayers.entrySet().stream().filter(e -> e.getValue().equalsIgnoreCase(name)).findAny().orElse(null);
if (entry == null) return false;
final UUID uuid = entry.getKey();
whitelistedPlayers.remove(uuid);
setWhitelist(uuid.toString(), null);
saveWhitelistedPlayers();
@@ -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;
}
}
@@ -2,196 +2,316 @@ package eu.kennytv.maintenance.core.command;
import eu.kennytv.maintenance.core.MaintenanceModePlugin;
import eu.kennytv.maintenance.core.Settings;
import eu.kennytv.maintenance.core.runnable.MaintenanceRunnable;
import eu.kennytv.maintenance.core.util.MessageUtil;
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<CommandInfo> 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 <server> §7(Enables maintenance mode on a specific proxied server)",
"§6/maintenance off <server> §7(Disables maintenance mode on a specific proxied server)");
}
addCommandInfo("timer", "§6/maintenance starttimer <minutes> §7(After the given time in minutes, maintenance mode will be enabled)",
"§6/maintenance endtimer <minutes> §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 <server> <minutes> §7(After the given time in minutes, maintenance mode will be enabled on the given server)",
"§6/maintenance endtimer <server> <minutes> §7(After the given time in minutes, maintenance mode will be disabled on the given server)",
"§6/maintenance timer abort <server> §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 <player> §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 <player> §7(Removes the player from the maintenance whitelist)");
addCommandInfo("setmotd", "§6/maintenance setmotd <index> <1/2> <message> §7(Sets a motd for maintenance mode)", "§6/maintenance removemotd <index> §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) {
if (!sender.hasPermission("maintenance.admin")) {
sender.sendMessage(settings.getNoPermMessage());
return;
}
if (checkPermission(sender, "command")) return;
if (args.length == 1) {
if (args[0].equalsIgnoreCase("on")) {
plugin.setMaintenance(true);
} else if (args[0].equalsIgnoreCase("off")) {
plugin.setMaintenance(false);
if (args[0].equalsIgnoreCase("on") || args[0].equalsIgnoreCase("off")) {
if (checkPermission(sender, "toggle")) return;
final boolean maintenance = args[0].equalsIgnoreCase("on");
if (maintenance == plugin.isMaintenance()) {
sender.sendMessage(settings.getMessage(maintenance ? "alreadyEnabled" : "alreadyDisabled"));
return;
}
plugin.setMaintenance(maintenance);
} else if (args[0].equalsIgnoreCase("reload")) {
if (!sender.hasPermission("maintenance.reload")) {
sender.sendMessage(settings.getNoPermMessage());
return;
}
if (checkPermission(sender, "reload")) return;
settings.reloadConfigs();
sender.sendMessage(plugin.getPrefix() + "§aReloaded config, whitelistedplayers and the maintenance icon");
sender.sendMessage(settings.getMessage("reload"));
} else if (args[0].equalsIgnoreCase("update")) {
if (!sender.hasPermission("maintenance.admin")) {
sender.sendMessage(settings.getNoPermMessage());
return;
}
if (checkPermission(sender, "update")) return;
checkForUpdate(sender);
} else if (args[0].equals("forceupdate")) {
if (!sender.hasPermission("maintenance.admin")) {
sender.sendMessage(settings.getNoPermMessage());
return;
}
sender.sendMessage(plugin.getPrefix() + "§c§lDownloading update...");
if (checkPermission(sender, "update")) return;
sender.sendMessage(settings.getMessage("updateDownloading"));
if (plugin.installUpdate())
sender.sendMessage(plugin.getPrefix() + "§a§lThe update was successful! To prevent issues with tasks and to complete the update, you have to restart the proxy!");
sender.sendMessage(settings.getMessage("updateFinished"));
else
sender.sendMessage(plugin.getPrefix() + "§4Failed!");
sender.sendMessage(settings.getMessage("updateFailed"));
} else if (args[0].equalsIgnoreCase("whitelist")) {
if (checkPermission(sender, "whitelist.list")) return;
final Map<UUID, String> players = settings.getWhitelistedPlayers();
if (players.isEmpty()) {
sender.sendMessage(plugin.getPrefix() + "§cThe maintenance whitelist is empty! Use \"/maintenance add <player>\" to add someone!");
sender.sendMessage(settings.getMessage("whitelistEmtpy"));
} else if (players.size() == 1 && players.containsKey(UUID.fromString("a8179ff3-c201-4a75-bdaa-9d14aca6f83f"))) {
sender.sendMessage(plugin.getPrefix() + "§cUse \"/maintenance add <player>\" to add someone. Alternatively, you can add the uuid of a player to the WhitelistedPlayers.yml as seen in the example in the file!");
sender.sendMessage(settings.getMessage("whitelistEmptyDefault"));
} else {
sender.sendMessage("§6Whitelisted players for maintenance:");
players.forEach((key, value) -> sender.sendMessage("§8- §e" + value));
sender.sendMessage(settings.getMessage("whitelistedPlayers"));
final String format = settings.getMessage("whitelistedPlayersFormat");
players.forEach((key, value) -> sender.sendMessage(format.replace("%NAME%", value).replace("%UUID%", key.toString())));
sender.sendMessage("");
}
} else if (args[0].equalsIgnoreCase("motd")) {
if (checkPermission(sender, "motd")) return;
sender.sendMessage(settings.getMessage("motdList"));
for (int i = 0; i < settings.getPingMessages().size(); i++) {
sender.sendMessage("§b" + (i + 1) + "§8§m---------");
for (final String motd : settings.getColoredString(settings.getPingMessages().get(i)).split("%NEWLINE%")) {
sender.sendMessage(motd);
}
}
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 (!MessageUtil.isNumeric(args[1])) {
sender.sendMessage(plugin.getPrefix() + "§6/maintenance timer endtimer <minutes>");
if (args[0].equalsIgnoreCase("help")) {
if (!isNumeric(args[1])) {
sender.sendMessage(settings.getMessage("helpUsage"));
return;
}
if (plugin.isTaskRunning()) {
sender.sendMessage(plugin.getPrefix() + "§cThere's already a starttimer scheduled!");
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;
}
final int minutes = Integer.parseInt(args[1]);
if (minutes > 40320) {
sender.sendMessage(plugin.getPrefix() + "§cThe number has to be less than 40320 (28 days)!");
return;
}
if (minutes < 1) {
sender.sendMessage(plugin.getPrefix() + "§cThink about running a timer for a negative amount of minutes. Doesn't work §othat §r§cwell.");
return;
}
plugin.setMaintenance(true);
sender.sendMessage(plugin.getPrefix() + "§aStarted timer: §7Maintenance mode will be deactivated in §6" + minutes + " minutes§7.");
plugin.setTaskId(plugin.schedule(new MaintenanceRunnable(plugin, settings, 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 (!MessageUtil.isNumeric(args[1])) {
sender.sendMessage(plugin.getPrefix() + "§6/maintenance timer starttimer <minutes>");
return;
}
if (plugin.isTaskRunning()) {
sender.sendMessage(plugin.getPrefix() + "§cThere's already running a timer!");
if (checkPermission(sender, "timer")) return;
if (checkTimerArgs(sender, args[1], "starttimerUsage")) return;
if (plugin.isMaintenance()) {
sender.sendMessage(settings.getMessage("alreadyEnabled"));
return;
}
final int minutes = Integer.parseInt(args[1]);
if (minutes > 40320) {
sender.sendMessage(plugin.getPrefix() + "§cThe number has to be less than 40320 (28 days)!");
return;
}
if (minutes < 1) {
sender.sendMessage(plugin.getPrefix() + "§cThink about running a timer for a negative amount of minutes. Doesn't work §othat §cwell.");
return;
}
sender.sendMessage(plugin.getPrefix() + "§aStarted timer: §7Maintenance mode will be activated in §6" + minutes + " minutes§7.");
plugin.setTaskId(plugin.schedule(new MaintenanceRunnable(plugin, settings, minutes, true)));
plugin.startMaintenanceRunnable(Integer.parseInt(args[1]), true);
sender.sendMessage(settings.getMessage("starttimerStarted").replace("%TIME%", plugin.getRunnable().getTime()));
} else if (args[0].equalsIgnoreCase("timer")) {
if (args[1].equalsIgnoreCase("abort") || args[1].equalsIgnoreCase("stop") || args[1].equalsIgnoreCase("cancel")) {
if (checkPermission(sender, "timer")) return;
if (!plugin.isTaskRunning()) {
sender.sendMessage(plugin.getPrefix() + "§cThere's currently no running timer.");
sender.sendMessage(settings.getMessage("timerNotRunning"));
return;
}
plugin.cancelTask();
sender.sendMessage(plugin.getPrefix() + "§cThe timer has been disabled.");
sender.sendMessage(settings.getMessage("timerCancelled"));
} else
sendUsage(sender);
} else if (args[0].equalsIgnoreCase("add")) {
if (checkPermission(sender, "whitelist.add")) return;
addPlayerToWhitelist(sender, args[1]);
} else if (args[0].equalsIgnoreCase("remove")) {
if (checkPermission(sender, "whitelist.remove")) return;
removePlayerFromWhitelist(sender, args[1]);
} else
sendUsage(sender);
} else if (args.length == 3) {
if (args[0].equalsIgnoreCase("setmotd")) {
if (!MessageUtil.isNumeric(args[1])) {
sender.sendMessage(plugin.getPrefix() + "§cThe first argument has to be numeric!");
} else if (args[0].equalsIgnoreCase("removemotd")) {
if (checkPermission(sender, "setmotd")) return;
if (!isNumeric(args[1])) {
sender.sendMessage(settings.getMessage("removeMotdUsage"));
return;
}
if (settings.getPingMessages().size() < 2) {
sender.sendMessage(settings.getMessage("removeMotdError"));
return;
}
final int line = Integer.parseInt(args[1]);
if (line < 1 || line > 2) {
sender.sendMessage(plugin.getPrefix() + "§cThe first argument has to be a 1 or a 2!");
final int index = Integer.parseInt(args[1]);
if (index > settings.getPingMessages().size()) {
sender.sendMessage(settings.getMessage("setMotdIndexError").replace("%MOTDS%", Integer.toString(settings.getPingMessages().size()))
.replace("%NEWAMOUNT%", Integer.toString(settings.getPingMessages().size())));
return;
}
final String message = getColoredString(String.join(" ", Arrays.copyOfRange(args, 2, args.length)));
final String oldMessage = settings.getConfigString("pingmessage");
final String newMessage;
if (line == 1)
newMessage = oldMessage.contains("%NEWLINE%") ?
message + "%NEWLINE%" + oldMessage.split("%NEWLINE%", 2)[1] : message;
else
newMessage = oldMessage.contains("%NEWLINE%") ?
oldMessage.split("%NEWLINE%", 2)[0] + "%NEWLINE%" + message : oldMessage + "%NEWLINE%" + message;
settings.setToConfig("pingmessage", newMessage);
settings.getPingMessages().remove(index - 1);
settings.setToConfig("pingmessages", settings.getPingMessages());
settings.saveConfig();
settings.reloadConfigs();
sender.sendMessage(plugin.getPrefix() + "§aSet line " + line + " of the maintenance motd to §f" + message);
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])) {
sender.sendMessage(settings.getMessage("setMotdUsage"));
return;
}
final int index = Integer.parseInt(args[1]);
if (index < 1 || index > settings.getPingMessages().size() + 1) {
sender.sendMessage(settings.getMessage("setMotdIndexError").replace("%MOTDS%", Integer.toString(settings.getPingMessages().size()))
.replace("%NEWAMOUNT%", Integer.toString(settings.getPingMessages().size() + 1)));
return;
}
if (!isNumeric(args[2])) {
sender.sendMessage(settings.getMessage("setMotdLineError"));
return;
}
final int line = Integer.parseInt(args[2]);
if (line != 1 && line != 2) {
sender.sendMessage(settings.getMessage("setMotdLineError"));
return;
}
final String message = String.join(" ", Arrays.copyOfRange(args, 3, args.length));
final String oldMessage = index > settings.getPingMessages().size() ? "" : settings.getPingMessages().get(index - 1);
final String newMessage;
if (line == 1)
newMessage = oldMessage.contains("%NEWLINE%") ?
message + "%NEWLINE%" + oldMessage.split("%NEWLINE%", 2)[1] : message;
else
newMessage = oldMessage.contains("%NEWLINE%") ?
oldMessage.split("%NEWLINE%", 2)[0] + "%NEWLINE%" + message : oldMessage + "%NEWLINE%" + message;
if (index > settings.getPingMessages().size())
settings.getPingMessages().add(newMessage);
else
settings.getPingMessages().set(index - 1, newMessage);
settings.setToConfig("pingmessages", settings.getPingMessages());
settings.saveConfig();
settings.reloadConfigs();
sender.sendMessage(settings.getMessage("setMotd").replace("%LINE%", args[2]).replace("%INDEX%", args[1])
.replace("%MOTD%", "§f" + settings.getColoredString(message)));
} else
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<String> 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<String> 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]===========");
sender.sendMessage("§6/maintenance reload §7(Reloads the config file)");
sender.sendMessage("§6/maintenance on §7(Enables maintenance mode");
sender.sendMessage("§6/maintenance off §7(Disables maintenance mode)");
sender.sendMessage("§6/maintenance setmotd <1/2> <message> §7(Sets the motd for maintenance mode)");
sender.sendMessage("§6/maintenance starttimer <minutes> §7(After the given time in minutes, maintenance mode will be enabled. Broadcast settings for the timer can be found in the config)");
sender.sendMessage("§6/maintenance endtimer <minutes> §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)");
sender.sendMessage("§6/maintenance add <player> §7(Adds the player to the maintenance whitelist, so they can join the server even though maintenance is enabled)");
sender.sendMessage("§6/maintenance remove <player> §7(Removes the player from the maintenance whitelist)");
sender.sendMessage("§6/maintenance whitelist §7(Shows all whitelisted players for the maintenance mode)");
sender.sendMessage("§6/maintenance update §7(Remotely downloads the newest version of the plugin onto your server)");
sender.sendMessage("§9Created by: KennyTV");
sender.sendMessage("§8===========[ §e" + name + " §8| §eVersion: §e" + plugin.getVersion() + " §8]===========");
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("");
}
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;
}
final int minutes = Integer.parseInt(time);
if (minutes > 40320) {
sender.sendMessage(settings.getMessage("timerTooLong"));
return true;
}
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;
}
return false;
}
protected boolean checkPermission(final SenderInfo sender, final String permission) {
if (!sender.hasPermission("maintenance." + permission)) {
sender.sendMessage(settings.getMessage("noPermission"));
return true;
}
return false;
}
protected boolean isNumeric(final String string) {
try {
Integer.parseInt(string);
} catch (final NumberFormatException nfe) {
return false;
}
return true;
}
protected abstract void addPlayerToWhitelist(SenderInfo sender, String name);
protected abstract void removePlayerFromWhitelist(SenderInfo sender, String name);
protected abstract void checkForUpdate(SenderInfo sender);
protected abstract String getColoredString(String message);
protected void showMaintenanceStatus(SenderInfo sender) {
}
protected void handleToggleServerCommand(SenderInfo sender, String args[]) {
}
protected void handleTimerServerCommands(SenderInfo sender, String args[]) {
}
}
@@ -3,32 +3,24 @@ package eu.kennytv.maintenance.core.runnable;
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 minutes;
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.minutes = minutes;
this.enable = enable;
super(plugin, settings, minutes, enable);
}
@Override
public void run() {
if (minutes <= 0) {
plugin.setMaintenance(enable);
if (plugin.isTaskRunning())
plugin.cancelTask();
} else if (settings.getBroadcastIntervalls().contains(minutes)) {
if (enable)
plugin.broadcast(settings.getTimerBroadcastMessage().replaceAll("%MINUTES%", String.valueOf(minutes)));
else
plugin.broadcast(settings.getEndtimerBroadcastMessage().replaceAll("%MINUTES%", String.valueOf(minutes)));
}
protected void finish() {
plugin.setMaintenance(enable);
}
minutes--;
@Override
protected String startMessageKey() {
return settings.getMessage("starttimerBroadcast").replace("%TIME%", getTime());
}
@Override
protected String endMessageKey() {
return settings.getMessage("endtimerBroadcast").replace("%TIME%", getTime());
}
}
@@ -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;
}
}
@@ -1,13 +0,0 @@
package eu.kennytv.maintenance.core.util;
public final class MessageUtil {
public static boolean isNumeric(final String string) {
try {
Integer.parseInt(string);
} catch (final NumberFormatException nfe) {
return false;
}
return true;
}
}
@@ -2,13 +2,13 @@ package eu.kennytv.maintenance.core.util;
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);
}
@@ -0,0 +1,7 @@
package eu.kennytv.maintenance.core.util;
public enum ServerType {
BUNGEE,
SPIGOT
}
@@ -0,0 +1,76 @@
package eu.kennytv.maintenance.core.util;
public final class Version implements Comparable<Version> {
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;
}
}
@@ -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 <Seite>"
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 <Minuten>"
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 <Minuten>"
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 <Index>"
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 <Index> <1/2> <Text>"
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 <Spieler>', um jemanden hinzuzufügen!"
whitelistEmptyDefault: "&8[&eMaintenance&8] &cNutze '/maintenance add <player>', 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 <Server> <Minuten>"
singleStarttimerBroadcast: "&8[&eMaintenance&8] &7Der Wartungsmodus auf Server %SERVER% wird aktiviert in: &6%TIME%&7."
singleStarttimerUsage: "&8[&eMaintenance&8] &c/maintenance starttimer <Server> <Minuten>"
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."
@@ -0,0 +1,64 @@
# Maintenance Plugin by KennyTV
# 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."
maintenanceActivated: "&8[&eMaintenance&8] &6Maintenance mode is now activated."
maintenanceDeactivated: "&8[&eMaintenance&8] &6Maintenance mode is now deactivated."
alreadyEnabled: "&8[&eMaintenance&8] &cMaintenance is already enabled!"
alreadyDisabled: "&8[&eMaintenance&8] &cMaintenance is already disabled!"
helpUsage: "&8[&eMaintenance&8] &c/maintenance help <page>"
endtimerBroadcast: "&8[&eMaintenance&8] &7Maintenance mode will be disabled in &6%TIME%&7."
endtimerStarted: "&8[&eMaintenance&8] &aStarted timer: &7Maintenance mode will be deactivated in &6%TIME%&7."
endtimerUsage: "&8[&eMaintenance&8] &c/maintenance endtimer <minutes>"
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 <minutes>"
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."
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 <index>"
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 <index> <1/2> <message>"
setMotdIndexError: "&8[&eMaintenance&8] §cYou currently have %MOTDS% motds, so you have to pick a number between 1 and %NEWAMOUNT%."
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)"
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!"
whitelistNotFound: "&8[&eMaintenance&8] &cThis player is not in the maintenance whitelist!"
whitelistEmtpy: "&8[&eMaintenance&8] &cThe maintenance whitelist is empty! Use '/maintenance add <player>' to add someone!"
whitelistEmptyDefault: "&8[&eMaintenance&8] &cUse '/maintenance add <player>' 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"
# 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 <server> <minutes>"
singleStarttimerBroadcast: "&8[&eMaintenance&8] &7Maintenance mode on server %SERVER% will be enabled in &6%TIME%&7."
singleStarttimerUsage: "&8[&eMaintenance&8] &c/maintenance starttimer <server> <minutes>"
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."
+1 -1
View File
@@ -6,7 +6,7 @@
<parent>
<artifactId>maintenance-base</artifactId>
<groupId>eu.kennytv</groupId>
<version>2.2.2</version>
<version>2.5</version>
</parent>
<artifactId>maintenance-parent</artifactId>
+3 -3
View File
@@ -6,7 +6,7 @@
<parent>
<artifactId>maintenance-base</artifactId>
<groupId>eu.kennytv</groupId>
<version>2.2.2</version>
<version>2.5</version>
</parent>
<artifactId>maintenance-spigot</artifactId>
@@ -33,7 +33,7 @@
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
<version>1.13.1-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -45,7 +45,7 @@
<dependency>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib-API</artifactId>
<version>4.3.0</version>
<version>4.4.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
@@ -2,9 +2,10 @@ package eu.kennytv.maintenance.spigot;
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(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();
@@ -63,14 +65,14 @@ public final class MaintenanceSpigotPlugin extends MaintenanceModePlugin {
getServer().getOnlinePlayers().stream()
.filter(p -> !p.hasPermission("maintenance.bypass") && !settings.getWhitelistedPlayers().containsKey(p.getUniqueId()))
.forEach(p -> p.kickPlayer(settings.getKickMessage().replace("%NEWLINE%", "\n")));
getServer().broadcastMessage(settings.getMaintenanceActivated());
getServer().broadcastMessage(settings.getMessage("maintenanceActivated"));
} else
getServer().broadcastMessage(settings.getMaintenanceDeactivated());
getServer().broadcastMessage(settings.getMessage("maintenanceDeactivated"));
}
@Override
public int schedule(final Runnable runnable) {
return getServer().getScheduler().scheduleSyncRepeatingTask(plugin, runnable, 0, 1200);
public int startMaintenanceRunnable(final Runnable runnable) {
return getServer().getScheduler().scheduleSyncRepeatingTask(plugin, runnable, 0, 20);
}
@Override
@@ -81,7 +83,8 @@ public final class MaintenanceSpigotPlugin extends MaintenanceModePlugin {
@Override
public void cancelTask() {
getServer().getScheduler().cancelTask(taskId);
setTaskId(0);
runnable = null;
taskId = 0;
}
@Override
@@ -104,10 +107,6 @@ public final class MaintenanceSpigotPlugin extends MaintenanceModePlugin {
return MaintenanceSpigotAPI.getAPI();
}
public MaintenanceSpigotBase getBase() {
return plugin;
}
public Server getServer() {
return plugin.getServer();
}
@@ -10,6 +10,7 @@ import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.PluginManager;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.List;
import java.util.UUID;
@@ -18,9 +19,11 @@ public final class SettingsSpigot extends Settings {
private final MaintenanceSpigotBase plugin;
private final IPingListener pingListener;
private FileConfiguration config;
private FileConfiguration language;
private FileConfiguration whitelist;
SettingsSpigot(final MaintenanceSpigotBase plugin) {
SettingsSpigot(final MaintenanceSpigotPlugin pl, final MaintenanceSpigotBase plugin) {
super(pl);
this.plugin = plugin;
final PluginManager pm = plugin.getServer().getPluginManager();
@@ -32,10 +35,56 @@ public final class SettingsSpigot extends Settings {
pingListener = listener;
}
createFiles();
if (!plugin.getDataFolder().exists())
plugin.getDataFolder().mkdirs();
createFile("spigot-config.yml");
createFile("WhitelistedPlayers.yml");
reloadConfigs();
}
private void createFile(final String name) {
final File file = new File(plugin.getDataFolder(), name);
if (!file.exists()) {
try (final InputStream in = plugin.getResource(name)) {
Files.copy(in, file.toPath());
} catch (final IOException e) {
throw new RuntimeException("Unable to create " + name + " file for Maintenance!", e);
}
}
}
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 {
@@ -56,15 +105,15 @@ public final class SettingsSpigot extends Settings {
@Override
public void reloadConfigs() {
final File file = new File(plugin.getDataFolder(), "spigot-config.yml");
try {
config = YamlConfiguration.loadConfiguration(new InputStreamReader(new FileInputStream(file), "UTF8"));
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 spigot-config.yml!", e);
throw new RuntimeException("Unable to load Maintenance files!", e);
}
loadSettings();
createAndLoadLanguageFile();
}
@Override
@@ -79,33 +128,23 @@ public final class SettingsSpigot extends Settings {
}
@Override
public boolean createFiles() {
if (!plugin.getDataFolder().exists())
plugin.getDataFolder().mkdirs();
final File file = new File(plugin.getDataFolder(), "spigot-config.yml");
if (!file.exists()) {
try (final InputStream in = plugin.getResource("spigot-config.yml")) {
Files.copy(in, file.toPath());
} catch (final IOException e) {
throw new RuntimeException("Unable to create spigot-config.yml file for Maintenance!", e);
}
public String getConfigString(final String path) {
final String s = config.getString(path);
if (s == null) {
plugin.getLogger().warning("The config is missing the following string: " + path);
return "null";
}
final File whitelistFile = new File(plugin.getDataFolder(), "WhitelistedPlayers.yml");
if (!whitelistFile.exists()) {
try (final InputStream in = plugin.getResource("WhitelistedPlayers.yml")) {
Files.copy(in, whitelistFile.toPath());
} catch (final IOException e) {
throw new RuntimeException("Unable to create WhitelistedPlayers.yml file for Maintenance!", e);
}
}
return true;
return s;
}
@Override
public String getConfigString(final String path) {
return ChatColor.translateAlternateColorCodes('&', config.getString(path));
public String getMessage(final String path) {
final String s = language.getString(path);
if (s == null) {
plugin.getLogger().warning("The language file is missing the following string: " + path);
return "null";
}
return ChatColor.translateAlternateColorCodes('&', s);
}
@Override
@@ -114,8 +153,13 @@ public final class SettingsSpigot extends Settings {
}
@Override
public List<Integer> getBroadcastIntervallList() {
return config.getIntegerList("timer-broadcasts-for-minutes");
public List<Integer> getConfigIntList(final String path) {
return config.getIntegerList(path);
}
@Override
public List<String> getConfigList(final String path) {
return config.getStringList(path);
}
@Override
@@ -123,6 +167,16 @@ public final class SettingsSpigot extends Settings {
config.set(path, var);
}
@Override
public boolean configContains(final String path) {
return config.contains(path);
}
@Override
public String getColoredString(final String message) {
return ChatColor.translateAlternateColorCodes('&', message);
}
@Override
public boolean reloadMaintenanceIcon() {
return pingListener.loadIcon();
@@ -6,7 +6,6 @@ import eu.kennytv.maintenance.spigot.MaintenanceSpigotPlugin;
import eu.kennytv.maintenance.spigot.SettingsSpigot;
import eu.kennytv.maintenance.spigot.util.BukkitSenderInfo;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@@ -29,57 +28,56 @@ public final class MaintenanceSpigotCommand extends MaintenanceCommand implement
protected void addPlayerToWhitelist(final SenderInfo sender, final String name) {
final Player selected = Bukkit.getPlayer(name);
if (selected != null) {
settings.addWhitelistedPlayer(selected.getUniqueId(), selected.getName());
sender.sendMessage(plugin.getPrefix() + "§aAdded §b" + selected.getName() + " §ato the maintenance whitelist!");
if (settings.addWhitelistedPlayer(selected.getUniqueId(), selected.getName()))
sender.sendMessage(settings.getMessage("whitelistAdded").replace("%PLAYER%", selected.getName()));
else
sender.sendMessage(settings.getMessage("whitelistAlreadyAdded").replace("%PLAYER%", selected.getName()));
return;
}
final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(name);
if (!offlinePlayer.hasPlayedBefore()) {
sender.sendMessage(plugin.getPrefix() + "§cNo player with this name has played on this server before.");
sender.sendMessage(settings.getMessage("playerNotFound"));
return;
}
if (settings.addWhitelistedPlayer(offlinePlayer.getUniqueId(), offlinePlayer.getName()))
sender.sendMessage(plugin.getPrefix() + "§aAdded §b" + offlinePlayer.getName() + " §ato the maintenance whitelist!");
sender.sendMessage(settings.getMessage("whitelistAdded").replace("%PLAYER%", offlinePlayer.getName()));
else
sender.sendMessage(plugin.getPrefix() + "§b" + offlinePlayer.getName() + " §calready is in the maintenance whitelist!");
sender.sendMessage(settings.getMessage("whitelistAlreadyAdded").replace("%PLAYER%", offlinePlayer.getName()));
}
@Override
protected void removePlayerFromWhitelist(final SenderInfo sender, final String name) {
final Player selected = Bukkit.getPlayer(name);
if (selected != null) {
settings.removeWhitelistedPlayer(selected.getUniqueId());
sender.sendMessage(plugin.getPrefix() + "§aRemoved §b" + selected.getName() + " §afrom the maintenance whitelist!");
if (settings.removeWhitelistedPlayer(selected.getUniqueId()))
sender.sendMessage(settings.getMessage("whitelistRemoved").replace("%PLAYER%", selected.getName()));
else
sender.sendMessage(settings.getMessage("whitelistNotFound"));
return;
}
final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(name);
if (!offlinePlayer.hasPlayedBefore()) {
sender.sendMessage(plugin.getPrefix() + "§cNo player with this name has played on this server before.");
sender.sendMessage(settings.getMessage("playerNotFound"));
return;
}
if (settings.removeWhitelistedPlayer(offlinePlayer.getUniqueId()))
sender.sendMessage(plugin.getPrefix() + "§aRemoved §b" + offlinePlayer.getName() + " §afrom the maintenance whitelist!");
sender.sendMessage(settings.getMessage("whitelistRemoved").replace("%PLAYER%", offlinePlayer.getName()));
else
sender.sendMessage(plugin.getPrefix() + "§cThis player is not in the maintenance whitelist!");
sender.sendMessage(settings.getMessage("whitelistNotFound"));
}
@Override
protected void checkForUpdate(final SenderInfo sender) {
if (plugin.updateAvailable()) {
sender.sendMessage(plugin.getPrefix() + "§cNewest version available: §aVersion " + plugin.getNewestVersion() + "§c, you're still on §a" + plugin.getVersion());
sender.sendMessage(plugin.getPrefix() + "§cNewest version available: §aVersion " + plugin.getNewestVersion() + "§c, you're on §a" + plugin.getVersion());
sender.sendMessage(plugin.getPrefix() + "§c§lWARNING: §cYou will have to restart the server to prevent further issues and to complete the update!" +
" If you can't do that, don't update!");
sender.sendMessage(plugin.getPrefix() + "§eUse §c§l/maintenance forceupdate §eto update!");
} else
sender.sendMessage(plugin.getPrefix() + "§aYou already have the latest version of the plugin!");
}
@Override
protected String getColoredString(final String message) {
return ChatColor.translateAlternateColorCodes('&', message);
}
}
@@ -7,13 +7,13 @@ import com.comphenix.protocol.events.PacketAdapter;
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;
@@ -24,17 +24,22 @@ public final class PacketListener implements IPingListener {
public PacketListener(final MaintenanceSpigotBase base, final SettingsSpigot settings) {
this.pl = base;
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(base, ListenerPriority.HIGHEST,
PacketType.Status.Server.OUT_SERVER_INFO) {
PacketType.Status.Server.SERVER_INFO) {
@Override
public void onPacketSending(final PacketEvent event) {
if (!settings.isMaintenance()) return;
final WrappedServerPing ping = event.getPacket().getServerPings().read(0);
ping.setVersionProtocol(0);
ping.setMotD(settings.getPingMessage().replace("%NEWLINE%", "\n"));
ping.setVersionName(settings.getPlayerCountMessage());
ping.setMotD(settings.getRandomPingMessage());
final List<WrappedGameProfile> players = Lists.newArrayList();
if (settings.hasCustomPlayerCountMessage()) {
ping.setVersionProtocol(0);
ping.setVersionName(settings.getPlayerCountMessage()
.replace("%ONLINE%", Integer.toString(pl.getServer().getOnlinePlayers().size()))
.replace("%MAX%", Integer.toString(pl.getServer().getMaxPlayers())));
}
final List<WrappedGameProfile> players = new ArrayList<>();
for (final String string : settings.getPlayerCountHoverMessage().split("%NEWLINE%"))
players.add(new WrappedGameProfile(UUID.randomUUID(), string));
ping.setPlayers(players);
@@ -13,14 +13,14 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerLoginEvent;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
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<UUID> notifiedPlayers = new HashSet<>();
public PlayerLoginListener(final MaintenanceSpigotPlugin plugin, final SettingsSpigot settings) {
this.plugin = plugin;
@@ -39,21 +39,19 @@ public final class PlayerLoginListener implements Listener {
if (settings.isJoinNotifications())
Bukkit.getOnlinePlayers().stream().filter(player -> player.hasPermission("maintenance.joinnotification"))
.forEach(player -> player.sendMessage(settings.getJoinNotification().replace("%PLAYER%", p.getName())));
.forEach(player -> player.sendMessage(settings.getMessage("joinNotification").replace("%PLAYER%", p.getName())));
return;
}
}
if (!p.hasPermission("maintenance.admin")) return;
if (!p.hasPermission("maintenance.admin") || notifiedPlayers.contains(p.getUniqueId())) return;
plugin.async(() -> {
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();
if (!newVersion.equals(plugin.getVersion())) {
p.sendMessage(plugin.getPrefix() + "§cThere is a newer version available: §aVersion " + newVersion + "§c, you're still on §a" + plugin.getVersion());
if (plugin.updateAvailable()) {
p.sendMessage(plugin.getPrefix() + "§cThere is a newer version available: §aVersion " + plugin.getNewestVersion() + "§c, you're on §a" + plugin.getVersion());
notifiedPlayers.add(p.getUniqueId());
try {
final TextComponent tc1 = new TextComponent(TextComponent.fromLegacyText(plugin.getPrefix()));
final TextComponent tc2 = new TextComponent(TextComponent.fromLegacyText("§cDownload it at: §6https://www.spigotmc.org/resources/maintenancemode.40699/"));
final TextComponent click = new TextComponent(TextComponent.fromLegacyText(" §7§l§o(CLICK ME)"));
@@ -63,8 +61,9 @@ public final class PlayerLoginListener implements Listener {
tc1.addExtra(click);
p.spigot().sendMessage(tc1);
} catch (final Exception e) {
p.sendMessage(plugin.getPrefix() + "§cDownload it at: §6https://www.spigotmc.org/resources/maintenancemode.40699/");
}
} catch (final Exception ignored) {
}
});
}
@@ -3,7 +3,6 @@ package eu.kennytv.maintenance.spigot.listener;
import eu.kennytv.maintenance.core.listener.IPingListener;
import eu.kennytv.maintenance.spigot.MaintenanceSpigotBase;
import eu.kennytv.maintenance.spigot.SettingsSpigot;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
@@ -28,7 +27,7 @@ public final class ServerListPingListener implements Listener, IPingListener {
if (!settings.isMaintenance()) return;
event.setMaxPlayers(0);
event.setMotd(settings.getPingMessage().replace("%NEWLINE%", "\n"));
event.setMotd(settings.getRandomPingMessage());
if (settings.hasCustomIcon() && serverIcon != null)
event.setServerIcon(serverIcon);
@@ -37,7 +36,7 @@ public final class ServerListPingListener implements Listener, IPingListener {
@Override
public boolean loadIcon() {
try {
serverIcon = Bukkit.loadServerIcon(ImageIO.read(new File("maintenance-icon.png")));
serverIcon = plugin.getServer().loadServerIcon(ImageIO.read(new File("maintenance-icon.png")));
} catch (final Exception e) {
plugin.getLogger().warning("§4Could not load 'maintenance-icon.png' - did you create one in your Spigot folder (not the plugins folder)?");
return false;
@@ -17,6 +17,7 @@ import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Timer;
import java.util.TimerTask;
@@ -227,7 +228,7 @@ public final class MetricsLite {
}
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
final GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
gzip.write(str.getBytes("UTF-8"));
gzip.write(str.getBytes(StandardCharsets.UTF_8));
gzip.close();
return outputStream.toByteArray();
}
@@ -6,7 +6,7 @@ import org.bukkit.entity.Player;
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) {
@@ -1,38 +1,39 @@
# 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.
enable-maintenance-mode: false
# The message shown in the multiplayer server list motd.
pingmessage: "&cMaintenance mode!%NEWLINE%&6We will be back soon!"
# If you put in multiple entries, one of them will be chosen randomly on every ping.
pingmessages:
- "&cMaintenance mode!%NEWLINE%&6We will be back soon!"
#- "Another entry"
# Is shown at the top right corner of the server in the serverlist,
# If set to true, the message below will be shown at the top right corner of the server in the serverlist,
# where the playercount would normally be displayed.
# If set to false, the normal playercount will be shown.
# Alternatively you can use '%ONLINE%' and '%MAX% if you want to include the playercount in a custom message (e.g. '&cMaintenance &7%ONLINE%&8/&7%MAX%').
enable-playercountmessage: true
playercountmessage: "&4Maintenance"
# Is shown when you move your mouse above the text at the top right corner of the server in the serverlist,
# where the playercount would normally be displayed.
playercounthovermessage: "&cCurrently under%NEWLINE%&cmaintenance"
# Will be shown, when a player tries to join on the server without the permission.
# Is shown when a player tries to join while maintenance is enabled and they don't have the permission to bypass it.
kickmessage: "&cThe server is currently under maintenance!%NEWLINE%Try again later!"
# Some self explanatory messages
no-permission: "&cYou do not have the permission to execute that command."
maintenance-activated: "&6Maintenance mode is now activated."
maintenance-deactivated: "&6Maintenance mode is now deactivated."
starttimer-broadcast-mesage: '&8[&eMaintenance&8] &7Maintenance mode will be enabled in &6%MINUTES% minutes&7.'
endtimer-broadcast-mesage: '&8[&eMaintenance&8] &7Maintenance mode will be disabled in &6%MINUTES% minutes&7.'
# If using the timer command: In what intervalls before enabling/disabling maintenance there will be a broadcast.
timer-broadcasts-for-minutes: [60, 30, 15, 10, 5, 4, 3, 2, 1]
timer-broadcast-for-seconds: [1200, 900, 600, 300, 120, 60, 30, 20, 10, 5, 4, 3, 2, 1]
# If set to true, players with the maintenance.joinnotification permission will receive a message,
# that a player tried to join the server while maintenance is enabled.
send-join-notification: false
join-notification: "&e%PLAYER% &ctried to join the server."
# If set to true, the server icon will be changed to maintenance-icon.png in the Bungee main/base-folder.
custom-maintenance-icon: false
custom-maintenance-icon: false
# Changes the language of command feedback/messages.
# Currently available are: en (English), de (German)
language: en
+14 -2
View File
@@ -6,7 +6,7 @@
<groupId>eu.kennytv</groupId>
<artifactId>maintenance-base</artifactId>
<version>2.2.2</version>
<version>2.5</version>
<name>Maintenance</name>
<packaging>pom</packaging>
@@ -31,13 +31,25 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<version>3.2.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>com.zaxxer.hikari</pattern>
<shadedPattern>eu.kennytv.lib.hikari</shadedPattern>
</relocation>
<!--<relocation>
<pattern>org.slf4j</pattern>
<shadedPattern>eu.kennytv.lib.slf4j</shadedPattern>
</relocation>-->
</relocations>
</configuration>
</execution>
</executions>
</plugin>