Compare commits

...
76 Commits
Author SHA1 Message Date
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
35 changed files with 648 additions and 402 deletions

No files matched your search

Binary file not shown.
+2 -2
View File
@@ -6,7 +6,7 @@
<parent>
<artifactId>maintenance-base</artifactId>
<groupId>eu.kennytv</groupId>
<version>2.2.2</version>
<version>2.4</version>
</parent>
<artifactId>maintenance-api</artifactId>
@@ -16,7 +16,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>
@@ -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);
@@ -6,7 +6,7 @@ import net.md_5.bungee.api.plugin.Plugin;
/**
* Utility class to get the {@link IMaintenance} 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
@@ -4,9 +4,9 @@ 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
+3 -3
View File
@@ -6,7 +6,7 @@
<parent>
<artifactId>maintenance-base</artifactId>
<groupId>eu.kennytv</groupId>
<version>2.2.2</version>
<version>2.4</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>
@@ -31,7 +31,7 @@ public final class MaintenanceBungeePlugin extends MaintenanceModePlugin {
this.plugin = plugin;
plugin.getLogger().info("Plugin by KennyTV");
settings = new SettingsBungee(plugin);
settings = new SettingsBungee(this, plugin);
final PluginManager pm = getProxy().getPluginManager();
pm.registerListener(plugin, new PostLoginListener(this, settings));
@@ -60,24 +60,28 @@ 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 int startMaintenanceRunnable(final Runnable runnable) {
return getProxy().getScheduler().schedule(plugin, runnable, 0, 1, TimeUnit.SECONDS).getId();
}
@Override
@@ -88,7 +92,8 @@ public final class MaintenanceBungeePlugin extends MaintenanceModePlugin {
@Override
public void cancelTask() {
getProxy().getScheduler().cancel(taskId);
setTaskId(0);
runnable = null;
taskId = 0;
}
@Override
@@ -10,6 +10,7 @@ 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;
@@ -20,12 +21,19 @@ public final class SettingsBungee extends Settings {
private final String maintenanceQuery;
private final MySQL mySQL;
private final MaintenanceBungeePlugin maintenancePlugin;
private final MaintenanceBungeeBase plugin;
private final IPingListener pingListener;
private Configuration config;
private Configuration language;
private Configuration whitelist;
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 +41,13 @@ 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("language.yml");
createFile("WhitelistedPlayers.yml");
reloadConfigs();
final Configuration mySQLSection = config.getSection("mysql");
if (mySQLSection.getBoolean("use-mysql", false)) {
@@ -57,16 +71,47 @@ public final class SettingsBungee extends Settings {
}
}
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));
language = YamlConfiguration.getProvider(YamlConfiguration.class)
.load(new InputStreamReader(new FileInputStream(new File(plugin.getDataFolder(), "language.yml")), StandardCharsets.UTF_8));
whitelist = YamlConfiguration.getProvider(YamlConfiguration.class).load(new File(plugin.getDataFolder(), "WhitelistedPlayers.yml"));
} catch (final IOException e) {
throw new RuntimeException("Unable to load Maintenance files!", e);
}
loadSettings();
}
@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);
}
@@ -82,27 +127,15 @@ public final class SettingsBungee extends Settings {
}
}
private void reloadConfigs(final boolean createdNewWhitelist) {
final File file = new File(plugin.getDataFolder(), "bungee-config.yml");
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"));
} catch (final IOException e) {
throw new RuntimeException("Unable to load bungee-config.yml!", 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)));
if (mySQL != null) {
final long configValue = config.getInt("mysql.update-interval");
millisecondsToCheck = configValue > 0 ? configValue * 1000 : -1;
lastMySQLCheck = 0;
}
}
@Override
@@ -111,36 +144,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 +169,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,18 +183,35 @@ 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 +226,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;
}
@@ -5,7 +5,6 @@ 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.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;
@@ -22,51 +21,46 @@ public final class MaintenanceBungeeCommand extends MaintenanceCommand {
protected void addPlayerToWhitelist(final SenderInfo sender, final String name) {
final ProxiedPlayer selected = ProxyServer.getInstance().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);
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
sender.sendMessage(plugin.getPrefix() + "§aYou already have the latest version of the plugin!");
}
@Override
protected String getColoredString(final String message) {
return ChatColor.translateAlternateColorCodes('&', message);
}
}
@@ -1,5 +1,6 @@
package eu.kennytv.maintenance.bungee.listener;
import com.google.common.collect.Sets;
import eu.kennytv.maintenance.bungee.MaintenanceBungeePlugin;
import eu.kennytv.maintenance.bungee.SettingsBungee;
import net.md_5.bungee.api.chat.ClickEvent;
@@ -12,9 +13,13 @@ 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.Set;
import java.util.UUID;
public final class PostLoginListener implements Listener {
private final MaintenanceBungeePlugin plugin;
private final SettingsBungee settings;
private final Set<UUID> notifiedPlayers = Sets.newHashSet();
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);
@@ -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();
}
}
@@ -1,38 +1,35 @@
# MaintenanceBungee Plugin by KennyTV
# MaintenanceBungee Plugin by KennyTV
# Version ${project.version}
# 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
@@ -47,3 +44,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.4</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,7 @@ 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 java.io.*;
import java.net.HttpURLConnection;
@@ -11,16 +12,12 @@ import java.net.URLConnection;
public abstract class MaintenanceModePlugin implements IMaintenance {
protected final String version;
protected int taskId;
protected ServerListPlusHook serverListPlusHook;
protected MaintenanceRunnable runnable;
protected int taskId;
private final String prefix;
private String 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) {
this.prefix = prefix;
this.version = version;
@@ -38,18 +35,19 @@ public abstract class MaintenanceModePlugin implements IMaintenance {
@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() {
return newestVersion;
}
public abstract int schedule(Runnable runnable);
public abstract int startMaintenanceRunnable(Runnable runnable);
public abstract void async(Runnable runnable);
@@ -59,10 +57,22 @@ public abstract class MaintenanceModePlugin implements IMaintenance {
public abstract void broadcast(String message);
public MaintenanceRunnable getRunnable() {
return runnable;
}
public String getPrefix() {
return prefix;
}
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 boolean updateAvailable() {
try {
final HttpURLConnection c = (HttpURLConnection) new URL("https://api.spigotmc.org/legacy/update.php?resource=40699").openConnection();
@@ -1,61 +1,89 @@
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;
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"));
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;
}
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 +95,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 +115,24 @@ public abstract class Settings implements ISettings {
return playerCountHoverMessage;
}
public String getKickMessage() {
return kickMessage;
}
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 +148,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 +165,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();
@@ -2,8 +2,6 @@ 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 java.util.Arrays;
@@ -22,148 +20,198 @@ public abstract class MaintenanceCommand {
}
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
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 (checkPermission(sender, "timer")) return;
if (!isNumeric(args[1])) {
sender.sendMessage(settings.getMessage("endtimerUsage"));
return;
}
if (plugin.isTaskRunning()) {
sender.sendMessage(plugin.getPrefix() + "§cThere's already a starttimer scheduled!");
sender.sendMessage(settings.getMessage("timerAlreadyRunning"));
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)!");
sender.sendMessage(settings.getMessage("timerTooLong"));
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.");
sender.sendMessage("§8§o[KennyTV whispers to you] §c§oThink about running a timer for a negative amount of minutes. Doesn't work §lthat §c§owell.");
return;
}
plugin.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)));
if (!plugin.isMaintenance())
plugin.setMaintenance(true);
plugin.startMaintenanceRunnable(minutes, 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>");
if (checkPermission(sender, "timer")) return;
if (!isNumeric(args[1])) {
sender.sendMessage(settings.getMessage("starttimerUsage"));
return;
}
if (plugin.isMaintenance()) {
sender.sendMessage(settings.getMessage("alreadyEnabled"));
return;
}
if (plugin.isTaskRunning()) {
sender.sendMessage(plugin.getPrefix() + "§cThere's already running a timer!");
sender.sendMessage(settings.getMessage("timerAlreadyRunning"));
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)!");
sender.sendMessage(settings.getMessage("timerTooLong"));
return;
}
if (minutes < 1) {
sender.sendMessage(plugin.getPrefix() + "§cThink about running a timer for a negative amount of minutes. Doesn't work §othat §cwell.");
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;
}
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)));
sender.sendMessage(settings.getMessage("starttimerStarted").replace("%TIME%", plugin.getRunnable().getTime()));
plugin.startMaintenanceRunnable(minutes, true);
} else if (args[0].equalsIgnoreCase("timer")) {
if (args[1].equalsIgnoreCase("abort") || args[1].equalsIgnoreCase("stop") || args[1].equalsIgnoreCase("cancel")) {
if (checkPermission(sender, "timer")) return;
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 && 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);
}
@@ -171,27 +219,56 @@ public abstract class MaintenanceCommand {
private void sendUsage(final SenderInfo sender) {
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");
if (sender.hasPermission("maintenance.reload"))
sender.sendMessage("§6/maintenance reload §7(Reloads the config file, whitelist file and the server-icon)");
if (sender.hasPermission("maintenance.toggle")) {
sender.sendMessage("§6/maintenance on §7(Enables maintenance mode");
sender.sendMessage("§6/maintenance off §7(Disables maintenance mode)");
}
if (sender.hasPermission("maintenance.timer")) {
sender.sendMessage("§6/maintenance starttimer <minutes> §7(After the given time in minutes, maintenance mode will be enabled)");
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)");
}
if (sender.hasPermission("maintenance.whitelist.list"))
sender.sendMessage("§6/maintenance whitelist §7(Shows all whitelisted players for the maintenance mode)");
if (sender.hasPermission("maintenance.whitelist.add"))
sender.sendMessage("§6/maintenance add <player> §7(Adds the player to the maintenance whitelist, so they can join the server even though maintenance is enabled)");
if (sender.hasPermission("maintenance.whitelist.remove"))
sender.sendMessage("§6/maintenance remove <player> §7(Removes the player from the maintenance whitelist)");
if (sender.hasPermission("maintenance.setmotd")) {
sender.sendMessage("§6/maintenance setmotd <index> <1/2> <message> §7(Sets a motd for maintenance mode)");
sender.sendMessage("§6/maintenance removemotd <index> §7(Removes a maintenance motd)");
}
if (sender.hasPermission("maintenance.motd"))
sender.sendMessage("§6/maintenance motd §7(Lists the currently set maintenance motds)");
if (sender.hasPermission("maintenance.update"))
sender.sendMessage("§6/maintenance update §7(Remotely downloads the newest version of the plugin onto your server)");
sender.sendMessage("§8× §7Created by §bKennyTV");
sender.sendMessage("§8===========[ §e" + name + " §8| §eVersion: §e" + plugin.getVersion() + " §8]===========");
sender.sendMessage("");
}
private boolean checkPermission(final SenderInfo sender, final String permission) {
if (!sender.hasPermission("maintenance." + permission)) {
sender.sendMessage(settings.getMessage("noPermission"));
return true;
}
return false;
}
private 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);
}
@@ -7,28 +7,51 @@ public final class MaintenanceRunnable implements Runnable {
private final MaintenanceModePlugin plugin;
private final Settings settings;
private final boolean enable;
private int minutes;
private int seconds;
public MaintenanceRunnable(final MaintenanceModePlugin plugin, final Settings settings, final int minutes, final boolean enable) {
this.plugin = plugin;
this.settings = settings;
this.minutes = minutes;
this.seconds = minutes * 60;
this.enable = enable;
}
@Override
public void run() {
if (minutes <= 0) {
if (seconds == 0) {
plugin.setMaintenance(enable);
if (plugin.isTaskRunning())
plugin.cancelTask();
} else if (settings.getBroadcastIntervalls().contains(minutes)) {
} else if (settings.getBroadcastIntervalls().contains(seconds)) {
if (enable)
plugin.broadcast(settings.getTimerBroadcastMessage().replaceAll("%MINUTES%", String.valueOf(minutes)));
plugin.broadcast(settings.getMessage("starttimerBroadcast").replaceAll("%TIME%", getTime()));
else
plugin.broadcast(settings.getEndtimerBroadcastMessage().replaceAll("%MINUTES%", String.valueOf(minutes)));
plugin.broadcast(settings.getMessage("endtimerBroadcast").replaceAll("%TIME%", getTime()));
}
minutes--;
seconds--;
}
public String getTime() {
final int preHours = this.seconds / 60;
final int minutes = preHours % 60;
final int seconds = this.seconds % 60;
final StringBuilder buider = new StringBuilder();
append(buider, "hour", preHours / 60);
append(buider, "minute", minutes);
append(buider, "second", seconds);
return buider.toString();
}
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;
}
}
@@ -0,0 +1,48 @@
# 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."
reload: "&8[&eMaintenance&8] &aReloaded config, whitelistedplayers, language file and the maintenance icon."
alreadyEnabled: "&8[&eMaintenance&8] &cMaintenance already is enabled!"
alreadyDisabled: "&8[&eMaintenance&8] &cMaintenance already is disabled!"
maintenanceActivated: "&8[&eMaintenance&8] &6Maintenance mode is now activated."
maintenanceDeactivated: "&8[&eMaintenance&8] &6Maintenance mode is now deactivated."
starttimerUsage: "&8[&eMaintenance&8] &c/maintenance starttimer <minutes>"
starttimerStarted: "&8[&eMaintenance&8] &aStarted timer: &7Maintenance mode will be activated in &6%TIME%&7."
starttimerBroadcast: "&8[&eMaintenance&8] &7Maintenance mode will be enabled in &6%TIME%&7."
endtimerUsage: "&8[&eMaintenance&8] &c/maintenance endtimer <minutes>"
endtimerStarted: "&8[&eMaintenance&8] &aStarted timer: &7Maintenance mode will be deactivated in &6%TIME%&7."
endtimerBroadcast: "&8[&eMaintenance&8] &7Maintenance mode will be disabled in &6%TIME%&7."
timerTooLong: "&8[&eMaintenance&8] &cThe number has to be less than 40320 (28 days)!"
timerAlreadyRunning: "&8[&eMaintenance&8] &cThere's already a starttimer scheduled!"
timerNotRunning: "&8[&eMaintenance&8] &cThere's currently no running timer."
timerCancelled: "&8[&eMaintenance&8] &cThe current timer has been disabled."
joinNotification: "&8[&eMaintenance&8] &e%PLAYER% &ctried to join the server."
updateDownloading: "&8[&eMaintenance&8] &c&lDownloading update..."
updateFinished: "&8[&eMaintenance&8] &a&lThe update was successful! To prevent issues with tasks and to complete the update, you have to restart the server!"
updateFailed: "&8[&eMaintenance&8] &4&lUpdate failed!"
setMotdUsage: "&8[&eMaintenance&8] &c/maintenance setmotd <index> <1/2> <message>"
setMotdLineError: "&8[&eMaintenance&8] &cThe second argument has to be the line number (1 or 2)!"
setMotdIndexError: "&8[&eMaintenance&8] §cYou currently have %MOTDS% motds, so you have to pick a number between 1 and %NEWAMOUNT%."
setMotd: "&8[&eMaintenance&8] &aSet line %LINE% of the %INDEX%. maintenance motd to %MOTD%"
removeMotdUsage: "&8[&eMaintenance&8] &c/maintenance removemotd <index>"
removeMotdError: "&8[&eMaintenance&8] &cYou only have one motd, so you can't remove any!"
removedMotd: "&8[&eMaintenance&8] &aRemoved motd number %INDEX%."
motdList: "&8[&eMaintenance&8] &7List of your maintenance motds:"
whitelistEmtpy: "&8[&eMaintenance&8] &cThe maintenance whitelist is empty! Use '/maintenance add <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!"
whitelistedPlayers: "&8[&eMaintenance&8] &6Whitelisted players for maintenance:"
whitelistedPlayersFormat: "&8- &e%NAME% &8(&7%UUID%&8)"
whitelistNotFound: "&8[&eMaintenance&8] &cThis player is not in the maintenance whitelist!"
whitelistAlreadyAdded: "&8[&eMaintenance&8] &b%PLAYER% &calready is in the maintenance whitelist!"
whitelistAdded: "&8[&eMaintenance&8] &aAdded &b%PLAYER% &ato the maintenance whitelist!"
whitelistRemoved: "&8[&eMaintenance&8] &aRemoved &b%PLAYER% &afrom the maintenance whitelist!"
playerNotOnline: "&8[&eMaintenance&8] &cThere's no player online with that name."
playerNotFound: "&8[&eMaintenance&8] &cNo player with this name has played on this server before."
second: "second"
seconds: "seconds"
minute: "minute"
minutes: "minutes"
hour: "hour"
hours: "hours"
+1 -1
View File
@@ -6,7 +6,7 @@
<parent>
<artifactId>maintenance-base</artifactId>
<groupId>eu.kennytv</groupId>
<version>2.2.2</version>
<version>2.4</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.4</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-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
@@ -27,7 +27,7 @@ public final class MaintenanceSpigotPlugin extends MaintenanceModePlugin {
super("§8[§eMaintenanceSpigot§8] ", plugin.getDescription().getVersion());
this.plugin = plugin;
settings = new SettingsSpigot(plugin);
settings = new SettingsSpigot(this, plugin);
plugin.getLogger().info("Plugin by KennyTV");
plugin.getCommand("maintenancespigot").setExecutor(new MaintenanceSpigotCommand(this, settings));
@@ -63,14 +63,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 +81,8 @@ public final class MaintenanceSpigotPlugin extends MaintenanceModePlugin {
@Override
public void cancelTask() {
getServer().getScheduler().cancelTask(taskId);
setTaskId(0);
runnable = null;
taskId = 0;
}
@Override
@@ -104,10 +105,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,26 @@ public final class SettingsSpigot extends Settings {
pingListener = listener;
}
createFiles();
if (!plugin.getDataFolder().exists())
plugin.getDataFolder().mkdirs();
createFile("spigot-config.yml");
createFile("language.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);
}
}
}
@Override
public void saveConfig() {
try {
@@ -56,12 +75,14 @@ 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"));
final File file = new File(plugin.getDataFolder(), "spigot-config.yml");
config = YamlConfiguration.loadConfiguration(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
final File languageFile = new File(plugin.getDataFolder(), "language.yml");
language = YamlConfiguration.loadConfiguration(new InputStreamReader(new FileInputStream(languageFile), StandardCharsets.UTF_8));
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();
@@ -79,33 +100,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 +125,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 +139,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);
}
}
@@ -24,15 +24,20 @@ 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());
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 = Lists.newArrayList();
for (final String string : settings.getPlayerCountHoverMessage().split("%NEWLINE%"))
@@ -1,5 +1,6 @@
package eu.kennytv.maintenance.spigot.listener;
import com.google.common.collect.Sets;
import eu.kennytv.maintenance.spigot.MaintenanceSpigotPlugin;
import eu.kennytv.maintenance.spigot.SettingsSpigot;
import net.md_5.bungee.api.chat.ClickEvent;
@@ -13,14 +14,13 @@ 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.Set;
import java.util.UUID;
public final class PlayerLoginListener implements Listener {
private final MaintenanceSpigotPlugin plugin;
private final SettingsSpigot settings;
private final Set<UUID> notifiedPlayers = Sets.newHashSet();
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();
}
@@ -1,38 +1,36 @@
# 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
+10 -2
View File
@@ -6,7 +6,7 @@
<groupId>eu.kennytv</groupId>
<artifactId>maintenance-base</artifactId>
<version>2.2.2</version>
<version>2.4</version>
<name>Maintenance</name>
<packaging>pom</packaging>
@@ -31,13 +31,21 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<version>3.1.1</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>
</relocations>
</configuration>
</execution>
</executions>
</plugin>