From 58592f07776746f6ca2d73915e550d2af4d659c9 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Mon, 9 Apr 2018 00:26:03 +0300 Subject: [PATCH 01/33] Added Plan placeholders to PlaceholderAPI --- PlanPluginBridge/pom.xml | 10 + .../djrapitops/pluginbridge/plan/Bridge.java | 4 +- .../placeholderapi/PlaceholderAPIHook.java | 32 +++ .../plan/placeholderapi/PlanPlaceholders.java | 190 ++++++++++++++++++ 4 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/placeholderapi/PlaceholderAPIHook.java create mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/placeholderapi/PlanPlaceholders.java diff --git a/PlanPluginBridge/pom.xml b/PlanPluginBridge/pom.xml index db9c9f651..ca703ea83 100644 --- a/PlanPluginBridge/pom.xml +++ b/PlanPluginBridge/pom.xml @@ -65,6 +65,10 @@ viaversion-repo https://repo.viaversion.com + + placeholderapi + http://repo.extendedclip.com/content/repositories/placeholderapi/ + @@ -210,6 +214,12 @@ 3.3.5 provided + + me.clip + placeholderapi + LATEST + provided + ${project.artifactId} diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Bridge.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Bridge.java index 13a44d935..3c8dd62a4 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Bridge.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Bridge.java @@ -17,6 +17,7 @@ import com.djrapitops.pluginbridge.plan.jobs.JobsHook; import com.djrapitops.pluginbridge.plan.kingdoms.KingdomsHook; import com.djrapitops.pluginbridge.plan.litebans.LiteBansHook; import com.djrapitops.pluginbridge.plan.mcmmo.McmmoHook; +import com.djrapitops.pluginbridge.plan.placeholderapi.PlaceholderAPIHook; import com.djrapitops.pluginbridge.plan.protocolsupport.ProtocolSupportHook; import com.djrapitops.pluginbridge.plan.redprotect.RedProtectHook; import com.djrapitops.pluginbridge.plan.superbvote.SuperbVoteHook; @@ -87,7 +88,8 @@ public class Bridge { new RedProtectHook(h), new TownyHook(h), new VaultHook(h), - new ViaVersionHook(h) + new ViaVersionHook(h), + new PlaceholderAPIHook(h) }; } } diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/placeholderapi/PlaceholderAPIHook.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/placeholderapi/PlaceholderAPIHook.java new file mode 100644 index 000000000..2ee7ed317 --- /dev/null +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/placeholderapi/PlaceholderAPIHook.java @@ -0,0 +1,32 @@ +package com.djrapitops.pluginbridge.plan.placeholderapi; + +import com.djrapitops.plan.data.plugin.HookHandler; +import com.djrapitops.pluginbridge.plan.Hook; +import me.clip.placeholderapi.PlaceholderAPI; + +/** + * A Class responsible for hooking to MCMMO and registering data sources. + * + * @author Rsl1122 + * @since 3.2.1 + */ +public class PlaceholderAPIHook extends Hook { + + /** + * Hooks the plugin and registers it's PluginData objects. + *

+ * API#addPluginDataSource uses the same method from HookHandler. + * + * @param hookH HookHandler instance for registering the data sources. + */ + public PlaceholderAPIHook(HookHandler hookH) { + super("me.clip.placeholderapi.PlaceholderAPI", hookH); + } + + public void hook() throws NoClassDefFoundError { + if (enabled) { + PlaceholderAPI.unregisterPlaceholderHook("plan"); + PlaceholderAPI.registerPlaceholderHook("plan", new PlanPlaceholders()); + } + } +} diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/placeholderapi/PlanPlaceholders.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/placeholderapi/PlanPlaceholders.java new file mode 100644 index 000000000..3f0f576fd --- /dev/null +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/placeholderapi/PlanPlaceholders.java @@ -0,0 +1,190 @@ +package com.djrapitops.pluginbridge.plan.placeholderapi; + +import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plan.data.PlayerProfile; +import com.djrapitops.plan.data.ServerProfile; +import com.djrapitops.plan.data.calculation.ActivityIndex; +import com.djrapitops.plan.data.container.TPS; +import com.djrapitops.plan.system.PlanSystem; +import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.utilities.FormatUtils; +import com.djrapitops.plan.utilities.MiscUtils; +import com.djrapitops.plan.utilities.analysis.Analysis; +import com.djrapitops.plan.utilities.analysis.MathUtils; +import com.djrapitops.plugin.api.TimeAmount; +import com.djrapitops.plugin.api.utility.log.Log; +import me.clip.placeholderapi.expansion.PlaceholderExpansion; +import org.bukkit.entity.Player; + +import java.io.Serializable; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.stream.Collectors; + +/** + * Placeholders of Plan. + * + * @author Rsl1122 + */ +public class PlanPlaceholders extends PlaceholderExpansion { + + private final PlanPlugin plugin; + + public PlanPlaceholders() { + plugin = PlanPlugin.getInstance(); + } + + @Override + public String getIdentifier() { + return "plan"; + } + + @Override + public String getPlugin() { + return "Plan"; + } + + @Override + public String getAuthor() { + return "Rsl1122"; + } + + @Override + public String getVersion() { + return plugin.getVersion(); + } + + @Override + public String onPlaceholderRequest(Player player, String identifier) { + Serializable planValue = getPlanValue(identifier); + if (planValue != null) { + return planValue.toString(); + } + Serializable serverValue = getServerValue(identifier); + if (serverValue != null) { + return serverValue.toString(); + } + + if (player != null) { + Serializable playerValue = getPlayerValue(player, identifier); + if (playerValue != null) { + return playerValue.toString(); + } + } + + return null; + } + + private Serializable getPlanValue(String identifier) { + switch (identifier.toLowerCase()) { + case "address": + return PlanSystem.getInstance().getWebServerSystem().getWebServer().getAccessAddress(); + case "analysis_refresh": + Optional refreshDate = Analysis.getRefreshDate(); + if (refreshDate.isPresent()) { + return FormatUtils.formatTimeStampClock(refreshDate.get()); + } + return "Not yet run"; + default: + return null; + } + } + + private Serializable getServerValue(String identifier) { + Callable serverProfile = Analysis::getServerProfile; + + long now = MiscUtils.getTime(); + long dayAgo = now - TimeAmount.DAY.ms(); + long weekAgo = now - TimeAmount.WEEK.ms(); + long monthAgo = now - TimeAmount.MONTH.ms(); + + try { + switch (identifier.toLowerCase()) { + case "players_total": + return serverProfile.call().getPlayerCount(); + case "players_new_day": + return serverProfile.call().getPlayersWhoRegistered(0, dayAgo).count(); + case "players_new_week": + return serverProfile.call().getPlayersWhoRegistered(0, weekAgo).count(); + case "players_new_month": + return serverProfile.call().getPlayersWhoRegistered(0, monthAgo).count(); + case "players_unique_day": + return serverProfile.call().getPlayersWhoPlayedBetween(0, dayAgo).count(); + case "players_unique_week": + return serverProfile.call().getPlayersWhoPlayedBetween(0, weekAgo).count(); + case "players_unique_month": + return serverProfile.call().getPlayersWhoPlayedBetween(0, monthAgo).count(); + case "playtime_total": + return FormatUtils.formatTimeAmount(serverProfile.call().getTotalPlaytime()); + case "session_avg": + return FormatUtils.formatTimeAmount( + PlayerProfile.getSessionAverage(serverProfile.call().getAllSessions().stream()) + ); + case "session_count": + return serverProfile.call().getAllSessions().size(); + case "kills_players": + return PlayerProfile.getPlayerKills(serverProfile.call().getAllSessions().stream()).count(); + case "kills_mobs": + return PlayerProfile.getMobKillCount(serverProfile.call().getAllSessions().stream()); + case "deaths_total": + return PlayerProfile.getDeathCount(serverProfile.call().getAllSessions().stream()); + case "tps_day": + return FormatUtils.cutDecimals( + MathUtils.averageDouble(serverProfile.call().getTPSData(0, dayAgo).map(TPS::getTicksPerSecond)) + ); + case "tps_drops_week": + return ServerProfile.getLowSpikeCount(serverProfile.call().getTPSData(0, weekAgo).collect(Collectors.toList())); + default: + break; + } + } catch (Exception e) { + Log.toLog(this.getClass().getName(), e); + } + return null; + } + + private Serializable getPlayerValue(Player player, String identifier) { + UUID uuid = player.getUniqueId(); + Callable profile = () -> Database.getActive().fetch().getPlayerProfile(uuid); + + long now = MiscUtils.getTime(); + long dayAgo = now - TimeAmount.DAY.ms(); + long weekAgo = now - TimeAmount.WEEK.ms(); + long monthAgo = now - TimeAmount.MONTH.ms(); + + try { + switch (identifier.toLowerCase()) { + case "playtime": + return FormatUtils.formatTimeAmount(profile.call().getPlaytime(0, now)); + case "playtime_day": + return FormatUtils.formatTimeAmount(profile.call().getPlaytime(dayAgo, now)); + case "playtime_week": + return FormatUtils.formatTimeAmount(profile.call().getPlaytime(weekAgo, now)); + case "playtime_month": + return FormatUtils.formatTimeAmount(profile.call().getPlaytime(monthAgo, now)); + case "geolocation": + return profile.call().getMostRecentGeoInfo().getGeolocation(); + case "activity_index": + ActivityIndex activityIndex = profile.call().getActivityIndex(now); + return activityIndex.getValue() + " (" + activityIndex.getGroup() + ")"; + case "registered": + return FormatUtils.formatTimeAmount(profile.call().getRegistered()); + case "last_seen": + return FormatUtils.formatTimeAmount(profile.call().getLastSeen()); + case "player_kills": + return profile.call().getPlayerKills().count(); + case "mob_kills": + return profile.call().getMobKillCount(); + case "deaths": + return profile.call().getDeathCount(); + default: + break; + } + } catch (Exception e) { + Log.toLog(this.getClass().getName(), e); + } + return null; + } + +} \ No newline at end of file From a27175e136c8cae7bcdb7e300afde963d3f78b27 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Mon, 9 Apr 2018 23:50:29 +0300 Subject: [PATCH 02/33] Updated commands to new APF 3.2.0 commands, better help formatting --- Plan/pom.xml | 2 +- .../java/com/djrapitops/plan/PlanSponge.java | 25 +------- .../plan/command/PlanBungeeCommand.java | 47 +++++++-------- .../djrapitops/plan/command/PlanCommand.java | 59 +++++++++---------- .../plan/command/commands/AnalyzeCommand.java | 21 +++---- .../commands/BungeeSetupToggleCommand.java | 12 ++-- .../plan/command/commands/DevCommand.java | 9 ++- .../plan/command/commands/InfoCommand.java | 14 ++--- .../plan/command/commands/InspectCommand.java | 21 +++---- .../plan/command/commands/ListCommand.java | 17 ++---- .../command/commands/ListServersCommand.java | 10 ++-- .../plan/command/commands/ManageCommand.java | 45 +++++++------- .../plan/command/commands/NetworkCommand.java | 14 ++--- .../command/commands/QInspectCommand.java | 22 +++---- .../command/commands/RegisterCommand.java | 19 +++--- .../plan/command/commands/ReloadCommand.java | 15 ++--- .../plan/command/commands/SearchCommand.java | 18 ++---- .../plan/command/commands/WebUserCommand.java | 49 +++++---------- .../commands/manage/ManageBackupCommand.java | 13 ++-- .../commands/manage/ManageClearCommand.java | 19 +++--- .../manage/ManageConDebugCommand.java | 18 ++---- .../commands/manage/ManageDisableCommand.java | 11 ++-- .../commands/manage/ManageHotswapCommand.java | 26 ++++---- .../commands/manage/ManageImportCommand.java | 23 ++++---- .../commands/manage/ManageMoveCommand.java | 17 +++--- .../commands/manage/ManageRestoreCommand.java | 13 ++-- .../commands/manage/ManageSetupCommand.java | 24 +++----- .../commands/webuser/WebCheckCommand.java | 17 +++--- .../commands/webuser/WebDeleteCommand.java | 17 +++--- .../commands/webuser/WebLevelCommand.java | 13 ++-- .../commands/webuser/WebListUsersCommand.java | 10 ++-- .../plan/system/settings/locale/Locale.java | 39 +++++------- 32 files changed, 265 insertions(+), 414 deletions(-) diff --git a/Plan/pom.xml b/Plan/pom.xml index 978f562bc..1bf81cf38 100644 --- a/Plan/pom.xml +++ b/Plan/pom.xml @@ -29,7 +29,7 @@ com.djrapitops AbstractPluginFramework - 3.1.1 + 3.2.0-SNAPSHOT diff --git a/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java b/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java index 364a669cc..1b73173b1 100644 --- a/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java +++ b/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java @@ -102,29 +102,8 @@ public class PlanSponge extends SpongePlugin implements PlanPlugin { } @Override - public void log(String level, String msg) { - switch (level.toUpperCase()) { - case "INFO_COLOR": - case "INFO": - case "I": - logger.info(msg); - break; - case "W": - case "WARN": - case "WARNING": - logger.warn(msg); - break; - case "E": - case "ERR": - case "ERROR": - case "SEVERE": - logger.error(msg); - break; - default: - logger.info(msg); - break; - } - + public Logger getLogger() { + return logger; } @Override diff --git a/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java index bfbf39472..5769ab9a0 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java @@ -6,9 +6,10 @@ import com.djrapitops.plan.command.commands.manage.ManageConDebugCommand; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.TreeCommand; -import com.djrapitops.plugin.command.defaultcmds.StatusCommand; +import com.djrapitops.plugin.command.TreeCmdNode; +import com.djrapitops.plugin.command.defaultcmds.StatusCommandNode; /** * TreeCommand for the /plan command, and all subcommands. @@ -18,7 +19,7 @@ import com.djrapitops.plugin.command.defaultcmds.StatusCommand; * @author Rsl1122 * @since 1.0.0 */ -public class PlanBungeeCommand extends TreeCommand { +public class PlanBungeeCommand extends TreeCmdNode { /** * CommandExecutor class Constructor. @@ -28,31 +29,27 @@ public class PlanBungeeCommand extends TreeCommand { * @param plugin Current instance of Plan */ public PlanBungeeCommand(PlanBungee plugin) { - super(plugin, "planbungee", CommandType.CONSOLE, Permissions.MANAGE.getPermission(), "", "planbungee"); - super.setDefaultCommand("help"); + super("planbungee", Permissions.MANAGE.getPermission(), CommandType.CONSOLE, null); super.setColorScheme(plugin.getColorScheme()); - } + setInDepthHelp(Locale.get(Msg.CMD_HELP_PLAN).toArray()); - @Override - public String[] addHelp() { - return Locale.get(Msg.CMD_HELP_PLAN).toArray(); - } - - @Override - public void addCommands() { - add( - new ReloadCommand(plugin), - new StatusCommand<>(plugin, Permissions.MANAGE.getPermission(), plugin.getColorScheme()), - new ListCommand(), - new BungeeSetupToggleCommand() - ); RegisterCommand registerCommand = new RegisterCommand(); - add( - registerCommand, - new WebUserCommand(plugin, registerCommand), - new NetworkCommand(), - new ListServersCommand(plugin), - new ManageConDebugCommand() + setNodeGroups( + new CommandNode[]{ + new NetworkCommand(), + new ListServersCommand(plugin), + new ListCommand(), + }, + new CommandNode[]{ + registerCommand, + new WebUserCommand(plugin, registerCommand, this), + }, + new CommandNode[]{ + new ManageConDebugCommand(), + new BungeeSetupToggleCommand(), + new ReloadCommand(plugin), + new StatusCommandNode<>(plugin, Permissions.MANAGE.getPermission(), plugin.getColorScheme()), + } ); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java index e76518554..b7616020f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java @@ -6,9 +6,10 @@ import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.TreeCommand; -import com.djrapitops.plugin.command.defaultcmds.StatusCommand; +import com.djrapitops.plugin.command.TreeCmdNode; +import com.djrapitops.plugin.command.defaultcmds.StatusCommandNode; /** * TreeCommand for the /plan command, and all SubCommands. @@ -18,41 +19,35 @@ import com.djrapitops.plugin.command.defaultcmds.StatusCommand; * @author Rsl1122 * @since 1.0.0 */ -public class PlanCommand extends TreeCommand { +public class PlanCommand extends TreeCmdNode { public PlanCommand(Plan plugin) { - super(plugin, "plan", CommandType.CONSOLE, "", "", "plan"); + super("plan", "", CommandType.CONSOLE, null); super.setDefaultCommand("inspect"); super.setColorScheme(plugin.getColorScheme()); - } + setInDepthHelp(Locale.get(Msg.CMD_HELP_PLAN).toArray()); - @Override - public String[] addHelp() { - return Locale.get(Msg.CMD_HELP_PLAN).toArray(); - } - - @Override - public void addCommands() { - add( - new InspectCommand(), - new QInspectCommand(plugin), - new AnalyzeCommand(), - new SearchCommand(), - new InfoCommand(plugin), - new ReloadCommand(plugin), - new ManageCommand(plugin), - new StatusCommand<>(plugin, Permissions.MANAGE.getPermission(), plugin.getColorScheme()), - new ListCommand() - ); RegisterCommand registerCommand = new RegisterCommand(); - add( - registerCommand, - new WebUserCommand(plugin, registerCommand), - new NetworkCommand(), - new ListServersCommand(plugin)); - - if (Settings.DEV_MODE.isTrue()) { - add(new DevCommand()); - } + setNodeGroups( + new CommandNode[]{ + new InspectCommand(), + new QInspectCommand(plugin), + new SearchCommand(), + new ListCommand(), + new AnalyzeCommand(), + new NetworkCommand(), + }, + new CommandNode[]{ + new WebUserCommand(plugin, registerCommand, this), + registerCommand + }, + new CommandNode[]{ + new InfoCommand(plugin), + new ReloadCommand(plugin), + new ManageCommand(plugin, this), + new StatusCommandNode<>(plugin, Permissions.MANAGE.getPermission(), plugin.getColorScheme()), + (Settings.DEV_MODE.isTrue() ? new DevCommand() : null) + } + ); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/AnalyzeCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/AnalyzeCommand.java index 3e7502ae9..6a0f82074 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/AnalyzeCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/AnalyzeCommand.java @@ -14,10 +14,10 @@ import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plan.system.webserver.WebServerSystem; import com.djrapitops.plan.utilities.analysis.Analysis; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.CommandUtils; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; import org.bukkit.ChatColor; import java.util.Map; @@ -30,23 +30,17 @@ import java.util.UUID; * @author Rsl1122 * @since 2.0.0 */ -public class AnalyzeCommand extends SubCommand { +public class AnalyzeCommand extends CommandNode { public AnalyzeCommand() { - super("analyze, analyse, analysis, a", - CommandType.CONSOLE, - Permissions.ANALYZE.getPermission(), - Locale.get(Msg.CMD_USG_ANALYZE).parse(), - "[ServerName or ID]"); + super("analyze|analyse|analysis|a", Permissions.ANALYZE.getPermission(), CommandType.CONSOLE); + setShortHelp(Locale.get(Msg.CMD_USG_ANALYZE).parse()); + setInDepthHelp(Locale.get(Msg.CMD_HELP_ANALYZE).toArray()); + setArguments("[server/id]"); } @Override - public String[] addHelp() { - return Locale.get(Msg.CMD_HELP_ANALYZE).toArray(); - } - - @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { sender.sendMessage(Locale.get(Msg.CMD_INFO_FETCH_DATA).toString()); Processing.submitNonCritical(() -> { @@ -63,7 +57,6 @@ public class AnalyzeCommand extends SubCommand { Log.toLog(this.getClass(), e); } }); - return true; } private void sendLink(Server server, ISender sender) { diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/BungeeSetupToggleCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/BungeeSetupToggleCommand.java index f4e3b7482..63a7b3c60 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/BungeeSetupToggleCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/BungeeSetupToggleCommand.java @@ -6,25 +6,26 @@ package com.djrapitops.plan.command.commands; import com.djrapitops.plan.system.info.connection.ConnectionSystem; import com.djrapitops.plan.system.settings.Permissions; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; /** * Command for Toggling whether or not BungeeCord accepts set up requests. - * + *

* This was added as a security measure against unwanted MySQL snooping. * * @author Rsl1122 */ -public class BungeeSetupToggleCommand extends SubCommand { +public class BungeeSetupToggleCommand extends CommandNode { public BungeeSetupToggleCommand() { - super("setup", CommandType.ALL, Permissions.MANAGE.getPermission(), "Toggle Setup mode for Bungee"); + super("setup", Permissions.MANAGE.getPermission(), CommandType.ALL); + setShortHelp("Toggle Setup mode for Bungee"); } @Override - public boolean onCommand(ISender sender, String s, String[] strings) { + public void onCommand(ISender sender, String s, String[] strings) { boolean setupAllowed = ConnectionSystem.isSetupAllowed(); ConnectionSystem connectionSystem = ConnectionSystem.getInstance(); @@ -35,6 +36,5 @@ public class BungeeSetupToggleCommand extends SubCommand { } String msg = !setupAllowed ? "§aSet-up is now Allowed" : "§cSet-up is now Forbidden"; sender.sendMessage(msg); - return true; } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/DevCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/DevCommand.java index 7021b997e..e2355622b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/DevCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/DevCommand.java @@ -8,25 +8,25 @@ import com.djrapitops.plan.system.info.connection.ConnectionSystem; import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plan.utilities.Condition; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; /** * Command used for testing functions that are too difficult to unit test. * * @author Rsl1122 */ -public class DevCommand extends SubCommand { +public class DevCommand extends CommandNode { public DevCommand() { super("dev", CommandType.PLAYER_OR_ARGS, "plan.*", "Test Plugin functions not testable with unit tests.", ""); } @Override - public boolean onCommand(ISender sender, String cmd, String[] args) { + public void onCommand(ISender sender, String cmd, String[] args) { if (!Condition.isTrue(args.length >= 1, Locale.get(Msg.CMD_FAIL_REQ_ONE_ARG).toString(), sender)) { - return true; + return; } String feature = args[0]; switch (feature) { @@ -45,6 +45,5 @@ public class DevCommand extends SubCommand { default: break; } - return true; } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/InfoCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/InfoCommand.java index 801ef88d4..5f0ef1685 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/InfoCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/InfoCommand.java @@ -6,9 +6,9 @@ import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plan.system.update.VersionCheckSystem; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; import com.djrapitops.plugin.settings.ColorScheme; /** @@ -17,21 +17,18 @@ import com.djrapitops.plugin.settings.ColorScheme; * @author Rsl1122 * @since 2.0.0 */ -public class InfoCommand extends SubCommand { +public class InfoCommand extends CommandNode { private final Plan plugin; public InfoCommand(Plan plugin) { - super("info", - CommandType.CONSOLE, - Permissions.INFO.getPermission(), - Locale.get(Msg.CMD_USG_INFO).toString()); - + super("info", Permissions.INFO.getPermission(), CommandType.CONSOLE); + setShortHelp(Locale.get(Msg.CMD_USG_INFO).toString()); this.plugin = plugin; } @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { ColorScheme cs = plugin.getColorScheme(); String mColor = cs.getMainColor(); String sColor = cs.getSecondaryColor(); @@ -47,7 +44,6 @@ public class InfoCommand extends SubCommand { Locale.get(Msg.CMD_CONSTANT_FOOTER).toString() }; sender.sendMessage(messages); - return true; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java index 1e6951417..52e688588 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java @@ -13,10 +13,10 @@ import com.djrapitops.plan.utilities.Condition; import com.djrapitops.plan.utilities.MiscUtils; import com.djrapitops.plan.utilities.uuid.UUIDUtility; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.CommandUtils; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.RunnableFactory; import com.djrapitops.plugin.utilities.Verify; @@ -30,27 +30,20 @@ import java.util.UUID; * @author Rsl1122 * @since 1.0.0 */ -public class InspectCommand extends SubCommand { +public class InspectCommand extends CommandNode { public InspectCommand() { - super("inspect", - CommandType.PLAYER_OR_ARGS, - Permissions.INSPECT.getPermission(), - Locale.get(Msg.CMD_USG_INSPECT).toString(), - ""); + super("inspect", Permissions.INSPECT.getPermission(), CommandType.PLAYER_OR_ARGS); + setArguments(""); + setShortHelp(Locale.get(Msg.CMD_USG_INSPECT).toString()); + setInDepthHelp(Locale.get(Msg.CMD_HELP_INSPECT).toArray()); } @Override - public String[] addHelp() { - return Locale.get(Msg.CMD_HELP_INSPECT).toArray(); - } - - @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { String playerName = MiscUtils.getPlayerName(args, sender); runInspectTask(playerName, sender); - return true; } private void runInspectTask(String playerName, ISender sender) { diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/ListCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/ListCommand.java index db06e1f0d..d8b12f741 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/ListCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/ListCommand.java @@ -4,10 +4,10 @@ import com.djrapitops.plan.system.info.connection.ConnectionSystem; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.CommandUtils; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; /** * Command used to display url to the player list page. @@ -15,22 +15,17 @@ import com.djrapitops.plugin.command.SubCommand; * @author Rsl1122 * @since 3.5.2 */ -public class ListCommand extends SubCommand { +public class ListCommand extends CommandNode { public ListCommand() { - super("list, pl, playerlist, players", CommandType.CONSOLE, Permissions.INSPECT_OTHER.getPermission(), Locale.get(Msg.CMD_USG_LIST).toString(), ""); + super("players|pl|playerlist|list", Permissions.INSPECT_OTHER.getPermission(), CommandType.CONSOLE); + setShortHelp(Locale.get(Msg.CMD_USG_LIST).toString()); + setInDepthHelp(Locale.get(Msg.CMD_HELP_LIST).toArray()); } @Override - public String[] addHelp() { - return Locale.get(Msg.CMD_HELP_LIST).toArray(); - } - - @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { - + public void onCommand(ISender sender, String commandLabel, String[] args) { sendListMsg(sender); - return true; } private void sendListMsg(ISender sender) { diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/ListServersCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/ListServersCommand.java index 2837d8b3f..647def4bb 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/ListServersCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/ListServersCommand.java @@ -8,9 +8,9 @@ import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; import com.djrapitops.plugin.settings.ColorScheme; import java.util.List; @@ -20,7 +20,7 @@ import java.util.List; * * @author Rsl1122 */ -public class ListServersCommand extends SubCommand { +public class ListServersCommand extends CommandNode { private final PlanPlugin plugin; @@ -28,13 +28,14 @@ public class ListServersCommand extends SubCommand { super("servers, serverlist, listservers, sl", CommandType.CONSOLE, Permissions.MANAGE.getPermission(), - "List servers in the network"); + "List servers in the network", + ""); this.plugin = plugin; } @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { ColorScheme colorScheme = plugin.getColorScheme(); String mCol = colorScheme.getMainColor(); String sCol = colorScheme.getSecondaryColor(); @@ -50,7 +51,6 @@ public class ListServersCommand extends SubCommand { sender.sendMessage("§cDatabase Exception occurred."); Log.toLog(this.getClass(), e); } - return true; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java index 521a09220..2ba8103e5 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java @@ -5,8 +5,9 @@ import com.djrapitops.plan.command.commands.manage.*; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.TreeCommand; +import com.djrapitops.plugin.command.TreeCmdNode; /** * This SubCommand is used to manage the the plugin's database and components. @@ -14,31 +15,27 @@ import com.djrapitops.plugin.command.TreeCommand; * @author Rsl1122 * @since 2.3.0 */ -public class ManageCommand extends TreeCommand { +public class ManageCommand extends TreeCmdNode { - public ManageCommand(Plan plugin) { - super(plugin, "manage,m", CommandType.CONSOLE, Permissions.MANAGE.getPermission(), Locale.get(Msg.CMD_USG_MANAGE).toString(), "plan m"); + public ManageCommand(Plan plugin, CommandNode parent) { + super("manage|m", Permissions.MANAGE.getPermission(), CommandType.CONSOLE, parent); + setShortHelp(Locale.get(Msg.CMD_USG_MANAGE).toString()); + setInDepthHelp(Locale.get(Msg.CMD_HELP_MANAGE).toArray()); super.setColorScheme(plugin.getColorScheme()); - } - - @Override - public String[] addHelp() { - return Locale.get(Msg.CMD_HELP_MANAGE).toArray(); - } - - @Override - public void addCommands() { - add( - new ManageMoveCommand(), - new ManageHotswapCommand(plugin), - new ManageBackupCommand(), - new ManageRestoreCommand(plugin), - new ManageImportCommand(), - new ManageRemoveCommand(), - new ManageClearCommand(plugin), - new ManageSetupCommand(), - new ManageDisableCommand(), - new ManageConDebugCommand() + setNodeGroups( + new CommandNode[]{ + new ManageMoveCommand(), + new ManageBackupCommand(), + new ManageRestoreCommand(plugin), + new ManageHotswapCommand(plugin), + new ManageClearCommand(plugin), + }, + new CommandNode[]{ + new ManageSetupCommand(), + new ManageConDebugCommand(), + new ManageImportCommand(), + new ManageDisableCommand() + } ); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/NetworkCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/NetworkCommand.java index d9bd4fc87..1181a92c9 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/NetworkCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/NetworkCommand.java @@ -4,29 +4,27 @@ import com.djrapitops.plan.system.info.connection.ConnectionSystem; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.CommandUtils; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; /** * Command used to display url to the network page. * * @author Rsl1122 */ -public class NetworkCommand extends SubCommand { +public class NetworkCommand extends CommandNode { public NetworkCommand() { - super("network, n, netw", - CommandType.CONSOLE, - Permissions.ANALYZE.getPermission(), - "Get the link to the network page"); + super("network|n|netw", + Permissions.ANALYZE.getPermission(), CommandType.CONSOLE); + setShortHelp("View the network page"); } @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { sendNetworkMsg(sender); - return true; } private void sendNetworkMsg(ISender sender) { diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/QInspectCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/QInspectCommand.java index f209a1455..781b03071 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/QInspectCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/QInspectCommand.java @@ -13,9 +13,9 @@ import com.djrapitops.plan.utilities.FormatUtils; import com.djrapitops.plan.utilities.MiscUtils; import com.djrapitops.plan.utilities.uuid.UUIDUtility; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; import com.djrapitops.plugin.settings.ColorScheme; import com.djrapitops.plugin.settings.DefaultMessages; import com.djrapitops.plugin.task.AbsRunnable; @@ -30,7 +30,7 @@ import java.util.UUID; * @author Rsl1122 * @since 1.0.0 */ -public class QInspectCommand extends SubCommand { +public class QInspectCommand extends CommandNode { private final PlanPlugin plugin; @@ -40,27 +40,19 @@ public class QInspectCommand extends SubCommand { * @param plugin Current instance of Plan */ public QInspectCommand(PlanPlugin plugin) { - super("qinspect", - CommandType.PLAYER_OR_ARGS, - Permissions.QUICK_INSPECT.getPermission(), - Locale.get(Msg.CMD_USG_QINSPECT).toString(), - ""); - + super("qinspect", Permissions.QUICK_INSPECT.getPermission(), CommandType.PLAYER_OR_ARGS); + setArguments(""); + setShortHelp(Locale.get(Msg.CMD_USG_QINSPECT).toString()); + setInDepthHelp(Locale.get(Msg.CMD_HELP_QINSPECT).toArray()); this.plugin = plugin; } @Override - public String[] addHelp() { - return Locale.get(Msg.CMD_HELP_QINSPECT).toArray(); - } - - @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { String playerName = MiscUtils.getPlayerName(args, sender, Permissions.QUICK_INSPECT_OTHER); runInspectTask(playerName, sender); - return true; } private void runInspectTask(String playerName, ISender sender) { diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java index 12280ec51..72ba990ae 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java @@ -9,13 +9,15 @@ import com.djrapitops.plan.utilities.Condition; import com.djrapitops.plan.utilities.PassEncryptUtil; import com.djrapitops.plugin.api.Check; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.CommandUtils; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.RunnableFactory; +import java.util.Arrays; + /** * Command for registering web users. *

@@ -27,27 +29,23 @@ import com.djrapitops.plugin.task.RunnableFactory; * @author Rsl1122 * @since 3.5.2 */ -public class RegisterCommand extends SubCommand { +public class RegisterCommand extends CommandNode { public RegisterCommand() { super("register", CommandType.PLAYER_OR_ARGS, "", // No Permission Requirement Locale.get(Msg.CMD_USG_WEB_REGISTER).toString(), - " [name] [access lvl]"); + " [name] [lvl]"); + setInDepthHelp(Locale.get(Msg.CMD_HELP_WEB_REGISTER).toArray()); if (Check.isBukkitAvailable()) { setupFilter(); } } @Override - public String[] addHelp() { - return Locale.get(Msg.CMD_HELP_WEB_REGISTER).toArray(); - } - - @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { - String notEnoughArgsMsg = Locale.get(Msg.CMD_FAIL_REQ_ARGS).parse("(3) " + super.getArguments()); + public void onCommand(ISender sender, String commandLabel, String[] args) { + String notEnoughArgsMsg = Locale.get(Msg.CMD_FAIL_REQ_ARGS).parse("(3) " + Arrays.toString(getArguments())); String hashErrorMsg = "§cPassword hash error."; String permLvlErrorMsg = "§cIncorrect perm level, not a number: "; try { @@ -65,7 +63,6 @@ public class RegisterCommand extends SubCommand { } catch (Exception e) { Log.toLog(this.getClass().getSimpleName(), e); } - return true; } private void consoleRegister(String[] args, ISender sender, String notEnoughArgsMsg) throws PassEncryptUtil.CannotPerformOperationException { diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/ReloadCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/ReloadCommand.java index 839a3cd4c..17bacbdd4 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/ReloadCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/ReloadCommand.java @@ -5,9 +5,9 @@ import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; /** * This SubCommand is used to reload the plugin. @@ -15,21 +15,18 @@ import com.djrapitops.plugin.command.SubCommand; * @author Rsl1122 * @since 2.0.0 */ -public class ReloadCommand extends SubCommand { +public class ReloadCommand extends CommandNode { private final PlanPlugin plugin; public ReloadCommand(PlanPlugin plugin) { - super("reload", - CommandType.CONSOLE, - Permissions.MANAGE.getPermission(), - Locale.get(Msg.CMD_USG_RELOAD).toString()); - + super("reload", Permissions.MANAGE.getPermission(), CommandType.CONSOLE); + setShortHelp(Locale.get(Msg.CMD_USG_RELOAD).toString()); this.plugin = plugin; } @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { try { plugin.reloadPlugin(true); } catch (Exception e) { @@ -37,7 +34,5 @@ public class ReloadCommand extends SubCommand { sender.sendMessage("§cSomething went wrong during reload of the plugin, a restart is recommended."); } sender.sendMessage(Locale.get(Msg.CMD_INFO_RELOAD_COMPLETE).toString()); - return true; } - } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/SearchCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/SearchCommand.java index 72441ad8d..6c3fad0d2 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/SearchCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/SearchCommand.java @@ -5,9 +5,9 @@ import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plan.utilities.Condition; import com.djrapitops.plan.utilities.MiscUtils; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.RunnableFactory; import com.djrapitops.plugin.utilities.FormatUtils; @@ -22,31 +22,25 @@ import java.util.List; * @author Rsl1122 * @since 2.0.0 */ -public class SearchCommand extends SubCommand { +public class SearchCommand extends CommandNode { public SearchCommand() { super("search", CommandType.PLAYER_OR_ARGS, Permissions.SEARCH.getPermission(), Locale.get(Msg.CMD_USG_SEARCH).toString(), - ""); - + ""); + setInDepthHelp(Locale.get(Msg.CMD_HELP_SEARCH).toArray()); } @Override - public String[] addHelp() { - return Locale.get(Msg.CMD_HELP_SEARCH).toArray(); - } - - @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { if (!Condition.isTrue(args.length >= 1, Locale.get(Msg.CMD_FAIL_REQ_ONE_ARG).toString(), sender)) { - return true; + return; } sender.sendMessage(Locale.get(Msg.CMD_INFO_SEARCHING).toString()); runSearchTask(args, sender); - return true; } private void runSearchTask(String[] args, ISender sender) { diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/WebUserCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/WebUserCommand.java index 5119c40d1..7a18cfcdc 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/WebUserCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/WebUserCommand.java @@ -1,7 +1,5 @@ package com.djrapitops.plan.command.commands; -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.PlanBungee; import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.command.commands.webuser.WebCheckCommand; import com.djrapitops.plan.command.commands.webuser.WebDeleteCommand; @@ -10,8 +8,9 @@ import com.djrapitops.plan.command.commands.webuser.WebListUsersCommand; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.TreeCommand; +import com.djrapitops.plugin.command.TreeCmdNode; /** * Web subcommand used to manage Web users. @@ -19,39 +18,21 @@ import com.djrapitops.plugin.command.TreeCommand; * @author Rsl1122 * @since 3.5.2 */ -public class WebUserCommand extends TreeCommand { +public class WebUserCommand extends TreeCmdNode { - public WebUserCommand(Plan plugin, RegisterCommand register) { - super(plugin, "webuser, web", - CommandType.CONSOLE, - Permissions.MANAGE_WEB.getPerm(), - Locale.get(Msg.CMD_USG_WEB).toString(), - "plan web"); + public WebUserCommand(PlanPlugin plugin, RegisterCommand register, CommandNode parent) { + super("webuser|web", Permissions.MANAGE_WEB.getPerm(), CommandType.CONSOLE, parent); + setShortHelp(Locale.get(Msg.CMD_USG_WEB).toString()); super.setColorScheme(plugin.getColorScheme()); - add(register); - } - - public WebUserCommand(PlanBungee plugin, RegisterCommand register) { - super(plugin, "webuser, web", - CommandType.CONSOLE, - Permissions.MANAGE_WEB.getPerm(), - Locale.get(Msg.CMD_USG_WEB).toString(), - "planbungee web"); - add(register); - } - - @Override - public String[] addHelp() { - return Locale.get(Msg.CMD_HELP_WEB).toArray(); - } - - @Override - public void addCommands() { - add( - new WebLevelCommand(plugin), - new WebListUsersCommand(plugin), - new WebCheckCommand(), - new WebDeleteCommand() + setInDepthHelp(Locale.get(Msg.CMD_HELP_WEB).toArray()); + setNodeGroups( + new CommandNode[]{ + register, + new WebLevelCommand(plugin), + new WebListUsersCommand(plugin), + new WebCheckCommand(), + new WebDeleteCommand() + } ); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageBackupCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageBackupCommand.java index 7362b103d..53af59bf6 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageBackupCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageBackupCommand.java @@ -9,9 +9,9 @@ import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plan.utilities.Condition; import com.djrapitops.plan.utilities.ManageUtils; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.RunnableFactory; import com.djrapitops.plugin.utilities.Verify; @@ -22,7 +22,7 @@ import com.djrapitops.plugin.utilities.Verify; * @author Rsl1122 * @since 2.3.0 */ -public class ManageBackupCommand extends SubCommand { +public class ManageBackupCommand extends CommandNode { public ManageBackupCommand() { super("backup", @@ -34,16 +34,16 @@ public class ManageBackupCommand extends SubCommand { } @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { try { if (!Condition.isTrue(args.length >= 1, Locale.get(Msg.CMD_FAIL_REQ_ARGS).parse(this.getArguments()), sender)) { - return true; + return; } String dbName = args[0].toLowerCase(); boolean isCorrectDB = "sqlite".equals(dbName) || "mysql".equals(dbName); if (!Condition.isTrue(isCorrectDB, Locale.get(Msg.MANAGE_FAIL_INCORRECT_DB) + dbName, sender)) { - return true; + return; } final Database database = DBSystem.getActiveDatabaseByName(dbName); @@ -51,7 +51,7 @@ public class ManageBackupCommand extends SubCommand { // If DB is null return if (!Condition.isTrue(Verify.notNull(database), Locale.get(Msg.MANAGE_FAIL_FAULTY_DB).toString(), sender)) { Log.error(dbName + " was null!"); - return true; + return; } Log.debug("Backup", "Start"); runBackupTask(sender, args, database); @@ -60,7 +60,6 @@ public class ManageBackupCommand extends SubCommand { } finally { Log.logDebug("Backup"); } - return true; } private void runBackupTask(ISender sender, String[] args, final Database database) { diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java index 4ada4101f..4f5b2b44f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java @@ -14,9 +14,9 @@ import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plan.utilities.Condition; import com.djrapitops.plan.utilities.MiscUtils; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.RunnableFactory; import com.djrapitops.plugin.utilities.Verify; @@ -27,7 +27,7 @@ import com.djrapitops.plugin.utilities.Verify; * @author Rsl1122 * @since 2.3.0 */ -public class ManageClearCommand extends SubCommand { +public class ManageClearCommand extends CommandNode { private final Plan plugin; @@ -38,30 +38,26 @@ public class ManageClearCommand extends SubCommand { Locale.get(Msg.CMD_USG_MANAGE_CLEAR).toString(), " [-a]"); + setInDepthHelp(Locale.get(Msg.CMD_HELP_MANAGE_CLEAR).toArray()); this.plugin = plugin; } @Override - public String[] addHelp() { - return Locale.get(Msg.CMD_HELP_MANAGE_CLEAR).toArray(); - } - - @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { if (!Condition.isTrue(args.length >= 1, Locale.get(Msg.CMD_FAIL_REQ_ONE_ARG).toString(), sender)) { - return true; + return; } String dbName = args[0].toLowerCase(); boolean isCorrectDB = "sqlite".equals(dbName) || "mysql".equals(dbName); if (!Condition.isTrue(isCorrectDB, Locale.get(Msg.MANAGE_FAIL_INCORRECT_DB) + dbName, sender)) { - return true; + return; } if (!Condition.isTrue(Verify.contains("-a", args), Locale.get(Msg.MANAGE_FAIL_CONFIRM).parse(Locale.get(Msg.MANAGE_NOTIFY_REMOVE).parse(args[0])), sender)) { - return true; + return; } try { @@ -70,7 +66,6 @@ public class ManageClearCommand extends SubCommand { } catch (DBInitException e) { sender.sendMessage(Locale.get(Msg.MANAGE_FAIL_FAULTY_DB).toString()); } - return true; } private void runClearTask(ISender sender, Database database) { diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java index fe403ad9d..b44dd92ef 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java @@ -10,13 +10,11 @@ import com.djrapitops.plan.system.info.server.Server; import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.system.settings.locale.Locale; -import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plan.system.webserver.WebServerSystem; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; import com.djrapitops.plugin.settings.ColorScheme; import java.util.List; @@ -28,7 +26,7 @@ import java.util.UUID; * @author Rsl1122 * @since 2.3.0 */ -public class ManageConDebugCommand extends SubCommand { +public class ManageConDebugCommand extends CommandNode { private final ColorScheme cs; @@ -38,25 +36,17 @@ public class ManageConDebugCommand extends SubCommand { Permissions.MANAGE.getPermission(), "Debug Bukkit-Bungee Connections", ""); - cs = PlanPlugin.getInstance().getColorScheme(); } @Override - public String[] addHelp() { - return Locale.get(Msg.CMD_HELP_MANAGE_HOTSWAP).toArray(); - } - - @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { if (!WebServerSystem.isWebServerEnabled()) { sender.sendMessage("§cWebServer is not enabled on this server."); - return true; + return; } Processing.submitNonCritical(() -> testServers(sender)); - - return true; } private void testServers(ISender sender) { diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageDisableCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageDisableCommand.java index cf00f566f..3cdc235a0 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageDisableCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageDisableCommand.java @@ -5,9 +5,9 @@ import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plan.utilities.Condition; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; /** * This manage SubCommand is used to disable some features of the plugin temporarily. @@ -15,7 +15,7 @@ import com.djrapitops.plugin.command.SubCommand; * @author Rsl1122 * @since 4.0.4 */ -public class ManageDisableCommand extends SubCommand { +public class ManageDisableCommand extends CommandNode { /** * Class Constructor. */ @@ -23,14 +23,14 @@ public class ManageDisableCommand extends SubCommand { super("disable", CommandType.PLAYER_OR_ARGS, Permissions.MANAGE.getPermission(), - "Used to disable some features of the Plugin temporarily", + "Disable a feature temporarily", ""); } @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { if (!Condition.isTrue(args.length >= 1, Locale.get(Msg.CMD_FAIL_REQ_ARGS).parse(this.getArguments()), sender)) { - return true; + return; } switch (args[0].toLowerCase()) { case "kickcount": @@ -40,6 +40,5 @@ public class ManageDisableCommand extends SubCommand { default: sender.sendMessage("§eDefine a feature to disable! (currently supports only kickCount)"); } - return true; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotswapCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotswapCommand.java index a77a9b8b9..228ba09f9 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotswapCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotswapCommand.java @@ -9,9 +9,9 @@ import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plan.utilities.Condition; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; import com.djrapitops.plugin.utilities.Verify; /** @@ -21,7 +21,7 @@ import com.djrapitops.plugin.utilities.Verify; * @author Rsl1122 * @since 2.3.0 */ -public class ManageHotswapCommand extends SubCommand { +public class ManageHotswapCommand extends CommandNode { private final Plan plugin; @@ -31,30 +31,25 @@ public class ManageHotswapCommand extends SubCommand { Permissions.MANAGE.getPermission(), Locale.get(Msg.CMD_USG_MANAGE_HOTSWAP).toString(), ""); - + setInDepthHelp(Locale.get(Msg.CMD_HELP_MANAGE_HOTSWAP).toArray()); this.plugin = plugin; } @Override - public String[] addHelp() { - return Locale.get(Msg.CMD_HELP_MANAGE_HOTSWAP).toArray(); - } - - @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { if (!Condition.isTrue(args.length >= 1, Locale.get(Msg.CMD_FAIL_REQ_ONE_ARG).toString(), sender)) { - return true; + return; } String dbName = args[0].toLowerCase(); boolean isCorrectDB = "sqlite".equals(dbName) || "mysql".equals(dbName); if (!Condition.isTrue(isCorrectDB, Locale.get(Msg.MANAGE_FAIL_INCORRECT_DB) + dbName, sender)) { - return true; + return; } if (Condition.isTrue(dbName.equals(Database.getActive().getConfigName()), Locale.get(Msg.MANAGE_FAIL_SAME_DB).toString(), sender)) { - return true; + return; } try { @@ -63,22 +58,21 @@ public class ManageHotswapCommand extends SubCommand { // If DB is null return if (!Condition.isTrue(Verify.notNull(database), Locale.get(Msg.MANAGE_FAIL_FAULTY_DB).toString(), sender)) { Log.error(dbName + " was null!"); - return true; + return; } if (!database.isOpen()) { - return true; + return; } } catch (Exception e) { Log.toLog(this.getClass(), e); sender.sendMessage(Locale.get(Msg.MANAGE_FAIL_FAULTY_DB).toString()); - return true; + return; } Settings.DB_TYPE.set(dbName); Settings.save(); plugin.reloadPlugin(true); - return true; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java index 575abb1bf..d7d879416 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java @@ -6,19 +6,21 @@ import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plan.utilities.Condition; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.RunnableFactory; +import java.util.Arrays; + /** * This manage SubCommand is used to import data from 3rd party plugins. * * @author Rsl1122 * @since 2.3.0 */ -public class ManageImportCommand extends SubCommand { +public class ManageImportCommand extends CommandNode { public ManageImportCommand() { super("import", @@ -26,17 +28,13 @@ public class ManageImportCommand extends SubCommand { Permissions.MANAGE.getPermission(), Locale.get(Msg.CMD_USG_MANAGE_IMPORT).toString(), "/list [import args]"); + setInDepthHelp(Locale.get(Msg.CMD_HELP_MANAGE_IMPORT).toArray()); } @Override - public String[] addHelp() { - return Locale.get(Msg.CMD_HELP_MANAGE_IMPORT).toArray(); - } - - @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { - if (!Condition.isTrue(args.length >= 1, Locale.get(Msg.CMD_FAIL_REQ_ONE_ARG) + " " + this.getArguments(), sender)) { - return true; + public void onCommand(ISender sender, String commandLabel, String[] args) { + if (!Condition.isTrue(args.length >= 1, Locale.get(Msg.CMD_FAIL_REQ_ONE_ARG) + " " + Arrays.toString(this.getArguments()), sender)) { + return; } String importArg = args[0]; @@ -47,13 +45,13 @@ public class ManageImportCommand extends SubCommand { .map(Importer::getNames) .map(list -> list.get(0)) .forEach(name -> sender.sendMessage("- " + name)); - return true; + return; } Importer importer = ImporterManager.getImporter(importArg); if (importer == null) { sender.sendMessage("§eImporter '" + importArg + "' doesn't exist"); - return true; + return; } RunnableFactory.createNew("Import:" + importArg, new AbsRunnable() { @@ -66,6 +64,5 @@ public class ManageImportCommand extends SubCommand { } } }).runTaskAsynchronously(); - return true; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageMoveCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageMoveCommand.java index f6ff42b13..01818d1e7 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageMoveCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageMoveCommand.java @@ -8,9 +8,9 @@ import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plan.utilities.Condition; import com.djrapitops.plan.utilities.ManageUtils; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.RunnableFactory; import com.djrapitops.plugin.utilities.Verify; @@ -23,7 +23,7 @@ import com.djrapitops.plugin.utilities.Verify; * @author Rsl1122 * @since 2.3.0 */ -public class ManageMoveCommand extends SubCommand { +public class ManageMoveCommand extends CommandNode { public ManageMoveCommand() { super("move", @@ -34,31 +34,31 @@ public class ManageMoveCommand extends SubCommand { } @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { if (!Condition.isTrue(args.length >= 2, Locale.get(Msg.CMD_FAIL_REQ_ARGS).parse(this.getArguments()), sender)) { - return true; + return; } String fromDB = args[0].toLowerCase(); boolean isCorrectDB = "sqlite".equals(fromDB) || "mysql".equals(fromDB); if (!Condition.isTrue(isCorrectDB, Locale.get(Msg.MANAGE_FAIL_INCORRECT_DB) + fromDB, sender)) { - return true; + return; } String toDB = args[1].toLowerCase(); isCorrectDB = "sqlite".equals(toDB) || "mysql".equals(toDB); if (!Condition.isTrue(isCorrectDB, Locale.get(Msg.MANAGE_FAIL_INCORRECT_DB) + toDB, sender)) { - return true; + return; } if (!Condition.isTrue(!Verify.equalsIgnoreCase(fromDB, toDB), Locale.get(Msg.MANAGE_FAIL_SAME_DB).toString(), sender)) { - return true; + return; } if (!Condition.isTrue(Verify.contains("-a", args), Locale.get(Msg.MANAGE_FAIL_CONFIRM).parse(Locale.get(Msg.MANAGE_NOTIFY_REMOVE).parse(args[1])), sender)) { - return true; + return; } try { @@ -69,7 +69,6 @@ public class ManageMoveCommand extends SubCommand { } catch (Exception e) { sender.sendMessage(Locale.get(Msg.MANAGE_FAIL_FAULTY_DB).toString()); } - return true; } private void runMoveTask(final Database fromDatabase, final Database toDatabase, ISender sender) { diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java index 06e2e1485..65a2ebd3b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java @@ -10,9 +10,9 @@ import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plan.utilities.Condition; import com.djrapitops.plan.utilities.ManageUtils; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.RunnableFactory; import com.djrapitops.plugin.utilities.Verify; @@ -25,7 +25,7 @@ import java.io.File; * * @author Rsl1122 */ -public class ManageRestoreCommand extends SubCommand { +public class ManageRestoreCommand extends CommandNode { private final Plan plugin; @@ -40,20 +40,20 @@ public class ManageRestoreCommand extends SubCommand { } @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { if (!Condition.isTrue(args.length >= 2, Locale.get(Msg.CMD_FAIL_REQ_ARGS).parse(this.getArguments()), sender)) { - return true; + return; } String db = args[1].toLowerCase(); boolean isCorrectDB = "sqlite".equals(db) || "mysql".equals(db); if (!Condition.isTrue(isCorrectDB, Locale.get(Msg.MANAGE_FAIL_INCORRECT_DB) + db, sender)) { - return true; + return; } if (!Condition.isTrue(Verify.contains("-a", args), Locale.get(Msg.MANAGE_FAIL_CONFIRM).parse(Locale.get(Msg.MANAGE_NOTIFY_REWRITE).parse(args[1])), sender)) { - return true; + return; } try { @@ -63,7 +63,6 @@ public class ManageRestoreCommand extends SubCommand { } catch (Exception e) { sender.sendMessage(Locale.get(Msg.MANAGE_FAIL_FAULTY_DB).toString()); } - return true; } private void runRestoreTask(String[] args, ISender sender, final Database database) { diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageSetupCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageSetupCommand.java index 137d7bb07..cbd0f4e79 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageSetupCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageSetupCommand.java @@ -10,9 +10,9 @@ import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plan.system.webserver.WebServerSystem; import com.djrapitops.plan.utilities.Condition; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; /** * This manage SubCommand is used to request settings from Bungee so that connection can be established. @@ -20,42 +20,36 @@ import com.djrapitops.plugin.command.SubCommand; * @author Rsl1122 * @since 2.3.0 */ -public class ManageSetupCommand extends SubCommand { +public class ManageSetupCommand extends CommandNode { public ManageSetupCommand() { super("setup", CommandType.PLAYER_OR_ARGS, Permissions.MANAGE.getPermission(), - "Set-Up Bungee WebServer connection", - ""); + "Set-Up Bungee connection", + ""); + setInDepthHelp(Locale.get(Msg.CMD_HELP_MANAGE_HOTSWAP).toArray()); } @Override - public String[] addHelp() { - return Locale.get(Msg.CMD_HELP_MANAGE_HOTSWAP).toArray(); - } - - @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { if (!Condition.isTrue(args.length >= 1, Locale.get(Msg.CMD_FAIL_REQ_ONE_ARG).toString(), sender)) { - return true; + return; } if (!WebServerSystem.isWebServerEnabled()) { sender.sendMessage("§cWebServer is not enabled on this server! Make sure it enables on boot!"); - return true; + return; } String address = args[0].toLowerCase(); if (!address.startsWith("http") || address.endsWith("://")) { sender.sendMessage("§cMake sure you're using the full address (Starts with http:// or https://) - Check Bungee enable log for the full address."); - return true; + return; } if (address.endsWith("/")) { address = address.substring(0, address.length() - 1); } requestSetup(sender, address); - - return true; } private void requestSetup(ISender sender, String address) { diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebCheckCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebCheckCommand.java index 4723e8a4f..ec963f0ae 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebCheckCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebCheckCommand.java @@ -7,9 +7,9 @@ import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plan.utilities.Condition; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.RunnableFactory; import org.bukkit.ChatColor; @@ -20,20 +20,18 @@ import org.bukkit.ChatColor; * @author Rsl1122 * @since 3.5.2 */ -public class WebCheckCommand extends SubCommand { +public class WebCheckCommand extends CommandNode { public WebCheckCommand() { - super("check", - CommandType.PLAYER_OR_ARGS, - Permissions.MANAGE_WEB.getPerm(), - Locale.get(Msg.CMD_USG_WEB_CHECK).toString(), - ""); + super("check", Permissions.MANAGE_WEB.getPerm(), CommandType.PLAYER_OR_ARGS); + setShortHelp(Locale.get(Msg.CMD_USG_WEB_CHECK).toString()); + setArguments(""); } @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { if (!Condition.isTrue(args.length >= 1, Locale.get(Msg.CMD_FAIL_REQ_ONE_ARG).parse() + " ", sender)) { - return true; + return; } Database database = Database.getActive(); String user = args[0]; @@ -55,7 +53,6 @@ public class WebCheckCommand extends SubCommand { } } }).runTaskAsynchronously(); - return true; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebDeleteCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebDeleteCommand.java index cd383a4be..2c8acb35a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebDeleteCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebDeleteCommand.java @@ -6,9 +6,9 @@ import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plan.utilities.Condition; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.RunnableFactory; import net.md_5.bungee.api.ChatColor; @@ -19,20 +19,18 @@ import net.md_5.bungee.api.ChatColor; * @author Rsl1122 * @since 3.5.2 */ -public class WebDeleteCommand extends SubCommand { +public class WebDeleteCommand extends CommandNode { public WebDeleteCommand() { - super("delete, remove", - CommandType.PLAYER_OR_ARGS, - Permissions.MANAGE_WEB.getPerm(), - Locale.get(Msg.CMD_USG_WEB_DELETE).toString(), - ""); + super("delete|remove", Permissions.MANAGE_WEB.getPerm(), CommandType.PLAYER_OR_ARGS); + setShortHelp(Locale.get(Msg.CMD_USG_WEB_DELETE).toString()); + setArguments(""); } @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { if (!Condition.isTrue(args.length >= 1, Locale.get(Msg.CMD_FAIL_REQ_ONE_ARG).parse() + " ", sender)) { - return true; + return; } Database database = Database.getActive(); String user = args[0]; @@ -54,7 +52,6 @@ public class WebDeleteCommand extends SubCommand { } } }).runTaskAsynchronously(); - return true; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebLevelCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebLevelCommand.java index 033f436ac..1a054105f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebLevelCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebLevelCommand.java @@ -4,9 +4,9 @@ import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; import com.djrapitops.plugin.settings.ColorScheme; /** @@ -15,20 +15,18 @@ import com.djrapitops.plugin.settings.ColorScheme; * @author Rsl1122 * @since 3.5.2 */ -public class WebLevelCommand extends SubCommand { +public class WebLevelCommand extends CommandNode { private final PlanPlugin plugin; public WebLevelCommand(PlanPlugin plugin) { - super("level", - CommandType.CONSOLE, - Permissions.MANAGE_WEB.getPerm(), - Locale.get(Msg.CMD_USG_WEB_LEVEL).toString()); + super("level", Permissions.MANAGE_WEB.getPerm(), CommandType.CONSOLE); + setShortHelp(Locale.get(Msg.CMD_USG_WEB_LEVEL).toString()); this.plugin = plugin; } @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { ColorScheme cs = plugin.getColorScheme(); String sCol = cs.getSecondaryColor(); String cmdBall = Locale.get(Msg.CMD_CONSTANT_LIST_BALL).parse(); @@ -44,7 +42,6 @@ public class WebLevelCommand extends SubCommand { }; sender.sendMessage(messages); - return true; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebListUsersCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebListUsersCommand.java index ba3ecd59a..55f775ae3 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebListUsersCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebListUsersCommand.java @@ -8,9 +8,9 @@ import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plan.utilities.comparators.WebUserComparator; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; import com.djrapitops.plugin.settings.ColorScheme; import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.RunnableFactory; @@ -23,17 +23,18 @@ import java.util.List; * @author Rsl1122 * @since 3.5.2 */ -public class WebListUsersCommand extends SubCommand { +public class WebListUsersCommand extends CommandNode { private final PlanPlugin plugin; public WebListUsersCommand(PlanPlugin plugin) { - super("list", CommandType.CONSOLE, Permissions.MANAGE_WEB.getPerm(), "List registered web users & permission levels."); + super("list", Permissions.MANAGE_WEB.getPerm(), CommandType.CONSOLE); + setShortHelp("List registered web users & permission levels."); this.plugin = plugin; } @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { RunnableFactory.createNew(new AbsRunnable("Webuser List Task") { @Override public void run() { @@ -55,7 +56,6 @@ public class WebListUsersCommand extends SubCommand { } } }).runTaskAsynchronously(); - return true; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/locale/Locale.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/locale/Locale.java index 1080ab38d..8399c78b5 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/locale/Locale.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/locale/Locale.java @@ -203,35 +203,33 @@ public class Locale { add(Msg.CMD_USG_QANALYZE, "View the Server Analysis as Text"); add(Msg.CMD_USG_HELP, "Show command list."); add(Msg.CMD_USG_INFO, "Check the version of Plan"); - add(Msg.CMD_USG_INSPECT, "Inspect Player's Data"); - add(Msg.CMD_USG_QINSPECT, "Inspect Player's Data as Text"); + add(Msg.CMD_USG_INSPECT, "Inspect player's data"); + add(Msg.CMD_USG_QINSPECT, "Inspect player's data in game"); add(Msg.CMD_USG_LIST, "List to all cached players"); add(Msg.CMD_USG_MANAGE, "Database management command"); add(Msg.CMD_USG_MANAGE_BACKUP, "Backup a database to .db file"); add(Msg.CMD_USG_MANAGE_CLEAN, "Clear old data from the database"); add(Msg.CMD_USG_MANAGE_CLEAR, "Clear ALL data from the database"); add(Msg.CMD_USG_MANAGE_DUMP, "Create a Hastebin log for Dev for easier Issue reporting."); - add(Msg.CMD_USG_MANAGE_HOTSWAP, "Hotswap to another database & restart the plugin"); - add(Msg.CMD_USG_MANAGE_IMPORT, "Import Data from supported plugins to Active Database."); - add(Msg.CMD_USG_MANAGE_MOVE, "Copy data from one database to another & overwrite values"); + add(Msg.CMD_USG_MANAGE_HOTSWAP, "Hotswap database & restart the plugin"); + add(Msg.CMD_USG_MANAGE_IMPORT, "Import Data from plugins"); + add(Msg.CMD_USG_MANAGE_MOVE, "Move data between databases"); add(Msg.CMD_USG_MANAGE_REMOVE, "Remove players's data from the Active Database."); - add(Msg.CMD_USG_MANAGE_RESTORE, "Restore a database from a backup file"); + add(Msg.CMD_USG_MANAGE_RESTORE, "Restore a database"); add(Msg.CMD_USG_RELOAD, "Restart the Plugin (Reloads config)"); add(Msg.CMD_USG_SEARCH, "Search for player"); - add(Msg.CMD_USG_WEB, "Manage Webusers"); - add(Msg.CMD_USG_WEB_CHECK, "Check a webuser and their permission level."); - add(Msg.CMD_USG_WEB_DELETE, "Delete a webuser"); + add(Msg.CMD_USG_WEB, "Manage Web users"); + add(Msg.CMD_USG_WEB_CHECK, "Check a web user's permission level."); + add(Msg.CMD_USG_WEB_DELETE, "Delete a web user"); add(Msg.CMD_USG_WEB_LEVEL, "Info about permission levels."); - add(Msg.CMD_USG_WEB_REGISTER, "Register a user for the webserver"); + add(Msg.CMD_USG_WEB_REGISTER, "Register a web user"); add(Msg.CMD_HELP_ANALYZE, mCol + "Analysis Command" + "\\" + tCol + " Used to Refresh analysis cache & Access the result page" - + "\\" + sCol + " /plan status can be used to check status of analysis while it is running." - + "\\" + sCol + " Aliases: analyze, analyse, analysis, a"); + + "\\" + sCol + " /plan status can be used to check status of analysis while it is running."); add(Msg.CMD_HELP_QANALYZE, mCol + "Quick Analysis command" + "\\" + tCol + " Used to get in game info about analysis." - + "\\" + sCol + " Has less info than full Analysis web page." - + "\\" + sCol + " Aliases: qanalyze, ganalyse, qanalysis, qa"); + + "\\" + sCol + " Has less info than full Analysis web page."); add(Msg.CMD_HELP_PLAN, mCol + "/plan - Main Command" + "\\" + tCol + " Used to access all SubCommands & help" + "\\" + sCol + " /plan - List subcommands" @@ -242,21 +240,17 @@ public class Locale { + "\\" + sCol + " Alias: /plan "); add(Msg.CMD_HELP_QINSPECT, mCol + "Quick Inspect command" + "\\" + tCol + " Used to get some inspect info in game." - + "\\" + sCol + " Has less info than full Inspect web page." - + "\\" + sCol + " Alias: /plan qi"); + + "\\" + sCol + " Has less info than full Inspect web page."); add(Msg.CMD_HELP_LIST, mCol + "List command" + "\\" + tCol + " Used to get a link to players page." - + "\\" + sCol + " Players page contains links to all cached inspect pages." - + "\\" + sCol + " Alias: /plan pl"); + + "\\" + sCol + " Players page contains links to all cached inspect pages."); add(Msg.CMD_HELP_MANAGE, mCol + "Manage command\\" + tCol + " Used to Manage Database of the plugin." - + "\\" + sCol + " Alias: /plan m" + "\\" + sCol + " /plan m - List subcommands" + "\\" + sCol + " /plan m ? - in depth help"); add(Msg.CMD_HELP_MANAGE_CLEAR, mCol + "Manage Clear command" + "\\" + tCol + " Used to delete ALL data in the active database." - + "\\" + sCol + " Plugin should be reloaded after successful clear." - + "\\" + sCol + " Alias: /plan pl"); + + "\\" + sCol + " Plugin should be reloaded after successful clear."); add(Msg.CMD_HELP_MANAGE_DUMP, mCol + "Manage Dump command" + "\\" + tCol + " Used to dump important data for bug reporting to hastebin."); add(Msg.CMD_HELP_MANAGE_HOTSWAP, mCol + "Manage Hotswap command" @@ -275,8 +269,7 @@ public class Locale { + "\\" + sCol + " Users have a permission level:" + "\\" + tCol + " 0 - Access to all pages" + "\\" + tCol + " 1 - Access to /players & all inspect pages" - + "\\" + tCol + " 2 - Access to own inspect page" - + "\\" + sCol + " Alias: /plan web"); + + "\\" + tCol + " 2 - Access to own inspect page"); add(Msg.CMD_HELP_WEB_REGISTER, mCol + "Web Register command" + "\\" + tCol + " Used to register a new user for the webserver." + "\\" + sCol + " Registering a user for another player requires " + Permissions.MANAGE_WEB.getPerm() + " permission." From 4b4594d9b8a9497a3a062d0c66e4c1c9b7b92794 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Wed, 11 Apr 2018 11:26:59 +0300 Subject: [PATCH 03/33] Removed deprecated APF code usage --- .../java/com/djrapitops/plan/PlanSponge.java | 3 +- .../plan/command/PlanBungeeCommand.java | 4 +-- .../djrapitops/plan/command/PlanCommand.java | 4 +-- .../plan/command/commands/DevCommand.java | 4 ++- .../command/commands/ListServersCommand.java | 7 ++-- .../plan/command/commands/ManageCommand.java | 3 +- .../plan/command/commands/NetworkCommand.java | 3 +- .../command/commands/RegisterCommand.java | 9 +++-- .../plan/command/commands/SearchCommand.java | 8 ++--- .../commands/manage/ManageBackupCommand.java | 8 ++--- .../commands/manage/ManageClearCommand.java | 9 ++--- .../manage/ManageConDebugCommand.java | 7 ++-- .../commands/manage/ManageDisableCommand.java | 8 ++--- ...Command.java => ManageHotSwapCommand.java} | 12 +++---- .../commands/manage/ManageImportCommand.java | 8 ++--- .../commands/manage/ManageMoveCommand.java | 8 ++--- .../commands/manage/ManageRemoveCommand.java | 33 +++++-------------- .../commands/manage/ManageRestoreCommand.java | 11 +++---- .../commands/manage/ManageSetupCommand.java | 8 ++--- 19 files changed, 58 insertions(+), 99 deletions(-) rename Plan/src/main/java/com/djrapitops/plan/command/commands/manage/{ManageHotswapCommand.java => ManageHotSwapCommand.java} (88%) diff --git a/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java b/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java index 1b73173b1..e72f886e2 100644 --- a/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java +++ b/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java @@ -22,7 +22,7 @@ import org.spongepowered.api.plugin.Plugin; import java.io.File; import java.io.InputStream; -@Plugin(id = "plan", name = "Plan", version = "4.2.0") +@Plugin(id = "plan", name = "Plan", version = "4.2.0", description = "Player Analytics Plugin by Rsl1122", authors = {"Rsl1122"}) public class PlanSponge extends SpongePlugin implements PlanPlugin { @Inject @@ -90,7 +90,6 @@ public class PlanSponge extends SpongePlugin implements PlanPlugin { return PlanColorScheme.create(); } - @Override public void onReload() { diff --git a/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java index 5769ab9a0..2636189cf 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java @@ -9,7 +9,7 @@ import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.TreeCmdNode; -import com.djrapitops.plugin.command.defaultcmds.StatusCommandNode; +import com.djrapitops.plugin.command.defaultcmds.StatusCommand; /** * TreeCommand for the /plan command, and all subcommands. @@ -48,7 +48,7 @@ public class PlanBungeeCommand extends TreeCmdNode { new ManageConDebugCommand(), new BungeeSetupToggleCommand(), new ReloadCommand(plugin), - new StatusCommandNode<>(plugin, Permissions.MANAGE.getPermission(), plugin.getColorScheme()), + new StatusCommand<>(plugin, Permissions.MANAGE.getPermission(), plugin.getColorScheme()), } ); } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java index b7616020f..9e428f65e 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java @@ -9,7 +9,7 @@ import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.TreeCmdNode; -import com.djrapitops.plugin.command.defaultcmds.StatusCommandNode; +import com.djrapitops.plugin.command.defaultcmds.StatusCommand; /** * TreeCommand for the /plan command, and all SubCommands. @@ -45,7 +45,7 @@ public class PlanCommand extends TreeCmdNode { new InfoCommand(plugin), new ReloadCommand(plugin), new ManageCommand(plugin, this), - new StatusCommandNode<>(plugin, Permissions.MANAGE.getPermission(), plugin.getColorScheme()), + new StatusCommand<>(plugin, Permissions.MANAGE.getPermission(), plugin.getColorScheme()), (Settings.DEV_MODE.isTrue() ? new DevCommand() : null) } ); diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/DevCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/DevCommand.java index e2355622b..16b15247f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/DevCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/DevCommand.java @@ -20,7 +20,9 @@ import com.djrapitops.plugin.command.ISender; public class DevCommand extends CommandNode { public DevCommand() { - super("dev", CommandType.PLAYER_OR_ARGS, "plan.*", "Test Plugin functions not testable with unit tests.", ""); + super("dev", "plan.*", CommandType.PLAYER_OR_ARGS); + setShortHelp("Test Plugin functions not testable with unit tests."); + setArguments(""); } @Override diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/ListServersCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/ListServersCommand.java index 647def4bb..cd147a0eb 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/ListServersCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/ListServersCommand.java @@ -25,11 +25,8 @@ public class ListServersCommand extends CommandNode { private final PlanPlugin plugin; public ListServersCommand(PlanPlugin plugin) { - super("servers, serverlist, listservers, sl", - CommandType.CONSOLE, - Permissions.MANAGE.getPermission(), - "List servers in the network", - ""); + super("servers|serverlist|listservers|sl|ls", Permissions.MANAGE.getPermission(), CommandType.CONSOLE); + setShortHelp("List servers in the network"); this.plugin = plugin; } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java index 2ba8103e5..2fc4dcf8f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java @@ -27,7 +27,8 @@ public class ManageCommand extends TreeCmdNode { new ManageMoveCommand(), new ManageBackupCommand(), new ManageRestoreCommand(plugin), - new ManageHotswapCommand(plugin), + new ManageRemoveCommand(), + new ManageHotSwapCommand(plugin), new ManageClearCommand(plugin), }, new CommandNode[]{ diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/NetworkCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/NetworkCommand.java index 1181a92c9..3b4b89725 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/NetworkCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/NetworkCommand.java @@ -17,8 +17,7 @@ import com.djrapitops.plugin.command.ISender; public class NetworkCommand extends CommandNode { public NetworkCommand() { - super("network|n|netw", - Permissions.ANALYZE.getPermission(), CommandType.CONSOLE); + super("network|n|netw", Permissions.ANALYZE.getPermission(), CommandType.CONSOLE); setShortHelp("View the network page"); } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java index 72ba990ae..f88981af6 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java @@ -32,11 +32,10 @@ import java.util.Arrays; public class RegisterCommand extends CommandNode { public RegisterCommand() { - super("register", - CommandType.PLAYER_OR_ARGS, - "", // No Permission Requirement - Locale.get(Msg.CMD_USG_WEB_REGISTER).toString(), - " [name] [lvl]"); + // No Permission Requirement + super("register", "", CommandType.PLAYER_OR_ARGS); + setShortHelp(Locale.get(Msg.CMD_USG_WEB_REGISTER).toString()); + setArguments("", "[name]", "[lvl]"); setInDepthHelp(Locale.get(Msg.CMD_HELP_WEB_REGISTER).toArray()); if (Check.isBukkitAvailable()) { setupFilter(); diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/SearchCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/SearchCommand.java index 6c3fad0d2..8a2211fd0 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/SearchCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/SearchCommand.java @@ -25,11 +25,9 @@ import java.util.List; public class SearchCommand extends CommandNode { public SearchCommand() { - super("search", - CommandType.PLAYER_OR_ARGS, - Permissions.SEARCH.getPermission(), - Locale.get(Msg.CMD_USG_SEARCH).toString(), - ""); + super("search", Permissions.SEARCH.getPermission(), CommandType.PLAYER_OR_ARGS); + setShortHelp(Locale.get(Msg.CMD_USG_SEARCH).toString()); + setArguments(""); setInDepthHelp(Locale.get(Msg.CMD_HELP_SEARCH).toArray()); } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageBackupCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageBackupCommand.java index 53af59bf6..ec69b3257 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageBackupCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageBackupCommand.java @@ -25,11 +25,9 @@ import com.djrapitops.plugin.utilities.Verify; public class ManageBackupCommand extends CommandNode { public ManageBackupCommand() { - super("backup", - CommandType.CONSOLE, - Permissions.MANAGE.getPermission(), - Locale.get(Msg.CMD_USG_MANAGE_BACKUP).toString(), - ""); + super("backup", Permissions.MANAGE.getPermission(), CommandType.CONSOLE); + setShortHelp(Locale.get(Msg.CMD_USG_MANAGE_BACKUP).toString()); + setArguments(""); } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java index 4f5b2b44f..d24714d18 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java @@ -32,12 +32,9 @@ public class ManageClearCommand extends CommandNode { private final Plan plugin; public ManageClearCommand(Plan plugin) { - super("clear", - CommandType.PLAYER_OR_ARGS, - Permissions.MANAGE.getPermission(), - Locale.get(Msg.CMD_USG_MANAGE_CLEAR).toString(), - " [-a]"); - + super("clear", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); + setShortHelp(Locale.get(Msg.CMD_USG_MANAGE_CLEAR).toString()); + setArguments("", "[-a]"); setInDepthHelp(Locale.get(Msg.CMD_HELP_MANAGE_CLEAR).toArray()); this.plugin = plugin; diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java index b44dd92ef..07036d91a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java @@ -31,11 +31,8 @@ public class ManageConDebugCommand extends CommandNode { private final ColorScheme cs; public ManageConDebugCommand() { - super("con", - CommandType.ALL, - Permissions.MANAGE.getPermission(), - "Debug Bukkit-Bungee Connections", - ""); + super("con", Permissions.MANAGE.getPermission(), CommandType.ALL); + setShortHelp("Debug Bukkit-Bungee Connections"); cs = PlanPlugin.getInstance().getColorScheme(); } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageDisableCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageDisableCommand.java index 3cdc235a0..bbca26d0f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageDisableCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageDisableCommand.java @@ -20,11 +20,9 @@ public class ManageDisableCommand extends CommandNode { * Class Constructor. */ public ManageDisableCommand() { - super("disable", - CommandType.PLAYER_OR_ARGS, - Permissions.MANAGE.getPermission(), - "Disable a feature temporarily", - ""); + super("disable", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); + setShortHelp("Disable a feature temporarily"); + setArguments(""); } @Override diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotswapCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotSwapCommand.java similarity index 88% rename from Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotswapCommand.java rename to Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotSwapCommand.java index 228ba09f9..9977aaf81 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotswapCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotSwapCommand.java @@ -21,16 +21,14 @@ import com.djrapitops.plugin.utilities.Verify; * @author Rsl1122 * @since 2.3.0 */ -public class ManageHotswapCommand extends CommandNode { +public class ManageHotSwapCommand extends CommandNode { private final Plan plugin; - public ManageHotswapCommand(Plan plugin) { - super("hotswap", - CommandType.PLAYER_OR_ARGS, - Permissions.MANAGE.getPermission(), - Locale.get(Msg.CMD_USG_MANAGE_HOTSWAP).toString(), - ""); + public ManageHotSwapCommand(Plan plugin) { + super("hotswap", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); + setShortHelp(Locale.get(Msg.CMD_USG_MANAGE_HOTSWAP).toString()); + setArguments(""); setInDepthHelp(Locale.get(Msg.CMD_HELP_MANAGE_HOTSWAP).toArray()); this.plugin = plugin; diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java index d7d879416..3585fd2ea 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java @@ -23,11 +23,9 @@ import java.util.Arrays; public class ManageImportCommand extends CommandNode { public ManageImportCommand() { - super("import", - CommandType.CONSOLE, - Permissions.MANAGE.getPermission(), - Locale.get(Msg.CMD_USG_MANAGE_IMPORT).toString(), - "/list [import args]"); + super("import", Permissions.MANAGE.getPermission(), CommandType.CONSOLE); + setShortHelp(Locale.get(Msg.CMD_USG_MANAGE_IMPORT).toString()); + setArguments("/list", "[import args]"); setInDepthHelp(Locale.get(Msg.CMD_HELP_MANAGE_IMPORT).toArray()); } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageMoveCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageMoveCommand.java index 01818d1e7..1e6965a98 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageMoveCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageMoveCommand.java @@ -26,11 +26,9 @@ import com.djrapitops.plugin.utilities.Verify; public class ManageMoveCommand extends CommandNode { public ManageMoveCommand() { - super("move", - CommandType.PLAYER_OR_ARGS, - Permissions.MANAGE.getPermission(), - Locale.get(Msg.CMD_USG_MANAGE_MOVE).toString(), - " [-a]"); + super("move", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); + setShortHelp(Locale.get(Msg.CMD_USG_MANAGE_MOVE).toString()); + setArguments("", "", "[-a]"); } @Override diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRemoveCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRemoveCommand.java index 2dc0d9ef0..5131c1a8d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRemoveCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRemoveCommand.java @@ -1,8 +1,6 @@ package com.djrapitops.plan.command.commands.manage; import com.djrapitops.plan.api.exceptions.database.DBException; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.system.cache.SessionCache; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.locale.Locale; @@ -11,49 +9,39 @@ import com.djrapitops.plan.utilities.Condition; import com.djrapitops.plan.utilities.MiscUtils; import com.djrapitops.plan.utilities.uuid.UUIDUtility; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.SubCommand; import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.RunnableFactory; import com.djrapitops.plugin.utilities.Verify; -import org.bukkit.entity.Player; import java.util.UUID; -import static org.bukkit.Bukkit.getPlayer; - /** * This manage subcommand is used to remove a single player's data from the * database. * * @author Rsl1122 */ -public class ManageRemoveCommand extends SubCommand { +public class ManageRemoveCommand extends CommandNode { public ManageRemoveCommand() { - super("remove", - CommandType.PLAYER_OR_ARGS, - Permissions.MANAGE.getPermission(), - Locale.get(Msg.CMD_USG_MANAGE_REMOVE).toString(), - " [-a]"); + super("remove|delete", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); + setShortHelp(Locale.get(Msg.CMD_USG_MANAGE_REMOVE).toString()); + setArguments("", "[-a]"); + setInDepthHelp(Locale.get(Msg.CMD_HELP_MANAGE_REMOVE).toArray()); } @Override - public String[] addHelp() { - return Locale.get(Msg.CMD_HELP_MANAGE_REMOVE).toArray(); - } - - @Override - public boolean onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(ISender sender, String commandLabel, String[] args) { if (!Condition.isTrue(args.length >= 1, Locale.get(Msg.CMD_FAIL_REQ_ONE_ARG).toString(), sender)) { - return true; + return; } String playerName = MiscUtils.getPlayerName(args, sender, Permissions.MANAGE); runRemoveTask(playerName, sender, args); - return true; } private void runRemoveTask(String playerName, ISender sender, String[] args) { @@ -83,11 +71,6 @@ public class ManageRemoveCommand extends SubCommand { database.remove().player(uuid); - Player player = getPlayer(uuid); - if (player != null) { - SessionCache.getActiveSessions().remove(uuid); - SessionCache.getInstance().cacheSession(uuid, new Session(MiscUtils.getTime(), player.getWorld().getName(), player.getGameMode().name())); - } sender.sendMessage(Locale.get(Msg.MANAGE_INFO_REMOVE_SUCCESS).parse(playerName, Database.getActive().getConfigName())); } catch (DBException e) { Log.toLog(this.getClass(), e); diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java index 65a2ebd3b..c3728b80b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java @@ -18,6 +18,7 @@ import com.djrapitops.plugin.task.RunnableFactory; import com.djrapitops.plugin.utilities.Verify; import java.io.File; +import java.util.Arrays; /** * This manage SubCommand is used to restore a backup.db file in the @@ -30,18 +31,16 @@ public class ManageRestoreCommand extends CommandNode { private final Plan plugin; public ManageRestoreCommand(Plan plugin) { - super("restore", - CommandType.CONSOLE, - Permissions.MANAGE.getPermission(), - Locale.get(Msg.CMD_USG_MANAGE_RESTORE).toString(), - " [-a]"); + super("restore", Permissions.MANAGE.getPermission(), CommandType.CONSOLE); + setShortHelp(Locale.get(Msg.CMD_USG_MANAGE_RESTORE).toString()); + setArguments("", "", "[-a]"); this.plugin = plugin; } @Override public void onCommand(ISender sender, String commandLabel, String[] args) { - if (!Condition.isTrue(args.length >= 2, Locale.get(Msg.CMD_FAIL_REQ_ARGS).parse(this.getArguments()), sender)) { + if (!Condition.isTrue(args.length >= 2, Locale.get(Msg.CMD_FAIL_REQ_ARGS).parse(Arrays.toString(this.getArguments())), sender)) { return; } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageSetupCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageSetupCommand.java index cbd0f4e79..6f0cf2a7b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageSetupCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageSetupCommand.java @@ -23,11 +23,9 @@ import com.djrapitops.plugin.command.ISender; public class ManageSetupCommand extends CommandNode { public ManageSetupCommand() { - super("setup", - CommandType.PLAYER_OR_ARGS, - Permissions.MANAGE.getPermission(), - "Set-Up Bungee connection", - ""); + super("setup", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); + setShortHelp("Set-Up Bungee connection"); + setArguments(""); setInDepthHelp(Locale.get(Msg.CMD_HELP_MANAGE_HOTSWAP).toArray()); } From 9d8abc11e83c22fe228ecbceb420b2c3462d08eb Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Wed, 11 Apr 2018 11:36:24 +0300 Subject: [PATCH 04/33] Clear and remove command no longer clear session cache --- .../com/djrapitops/plan/command/PlanCommand.java | 4 ++-- .../plan/command/commands/InfoCommand.java | 8 ++++---- .../plan/command/commands/ManageCommand.java | 4 ++-- .../command/commands/manage/ManageClearCommand.java | 13 +++---------- .../commands/manage/ManageHotSwapCommand.java | 6 +++--- .../commands/manage/ManageRestoreCommand.java | 6 +++--- 6 files changed, 17 insertions(+), 24 deletions(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java index 9e428f65e..68ce5d31e 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java @@ -1,6 +1,6 @@ package com.djrapitops.plan.command; -import com.djrapitops.plan.Plan; +import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.command.commands.*; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.Settings; @@ -21,7 +21,7 @@ import com.djrapitops.plugin.command.defaultcmds.StatusCommand; */ public class PlanCommand extends TreeCmdNode { - public PlanCommand(Plan plugin) { + public PlanCommand(PlanPlugin plugin) { super("plan", "", CommandType.CONSOLE, null); super.setDefaultCommand("inspect"); super.setColorScheme(plugin.getColorScheme()); diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/InfoCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/InfoCommand.java index 5f0ef1685..2f3eccbfa 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/InfoCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/InfoCommand.java @@ -1,6 +1,6 @@ package com.djrapitops.plan.command.commands; -import com.djrapitops.plan.Plan; +import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.locale.Locale; @@ -19,9 +19,9 @@ import com.djrapitops.plugin.settings.ColorScheme; */ public class InfoCommand extends CommandNode { - private final Plan plugin; + private final PlanPlugin plugin; - public InfoCommand(Plan plugin) { + public InfoCommand(PlanPlugin plugin) { super("info", Permissions.INFO.getPermission(), CommandType.CONSOLE); setShortHelp(Locale.get(Msg.CMD_USG_INFO).toString()); this.plugin = plugin; @@ -38,7 +38,7 @@ public class InfoCommand extends CommandNode { String upToDate = VersionCheckSystem.isNewVersionAvailable() ? "Update Available" : "Up to date"; String[] messages = { Locale.get(Msg.CMD_HEADER_INFO).toString(), - ball + mColor + " Version: " + sColor + plugin.getDescription().getVersion(), + ball + mColor + " Version: " + sColor + plugin.getVersion(), ball + mColor + " Up to date: " + sColor + upToDate, ball + mColor + " Active Database: " + tColor + Database.getActive().getConfigName(), Locale.get(Msg.CMD_CONSTANT_FOOTER).toString() diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java index 2fc4dcf8f..1f5b674ad 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java @@ -1,6 +1,6 @@ package com.djrapitops.plan.command.commands; -import com.djrapitops.plan.Plan; +import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.command.commands.manage.*; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.locale.Locale; @@ -17,7 +17,7 @@ import com.djrapitops.plugin.command.TreeCmdNode; */ public class ManageCommand extends TreeCmdNode { - public ManageCommand(Plan plugin, CommandNode parent) { + public ManageCommand(PlanPlugin plugin, CommandNode parent) { super("manage|m", Permissions.MANAGE.getPermission(), CommandType.CONSOLE, parent); setShortHelp(Locale.get(Msg.CMD_USG_MANAGE).toString()); setInDepthHelp(Locale.get(Msg.CMD_HELP_MANAGE).toArray()); diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java index d24714d18..f47891e88 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java @@ -1,11 +1,9 @@ package com.djrapitops.plan.command.commands.manage; -import com.djrapitops.plan.Plan; +import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.database.DBException; import com.djrapitops.plan.api.exceptions.database.DBInitException; import com.djrapitops.plan.api.exceptions.database.FatalDBException; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.system.cache.SessionCache; import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.settings.Permissions; @@ -29,9 +27,9 @@ import com.djrapitops.plugin.utilities.Verify; */ public class ManageClearCommand extends CommandNode { - private final Plan plugin; + private final PlanPlugin plugin; - public ManageClearCommand(Plan plugin) { + public ManageClearCommand(PlanPlugin plugin) { super("clear", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); setShortHelp(Locale.get(Msg.CMD_USG_MANAGE_CLEAR).toString()); setArguments("", "[-a]"); @@ -75,11 +73,6 @@ public class ManageClearCommand extends CommandNode { database.remove().everything(); long now = MiscUtils.getTime(); - SessionCache.clear(); - plugin.getServer().getOnlinePlayers().forEach( - player -> SessionCache.getInstance().cacheSession(player.getUniqueId(), - new Session(now, player.getWorld().getName(), player.getGameMode().name())) - ); sender.sendMessage(Locale.get(Msg.MANAGE_INFO_CLEAR_SUCCESS).toString()); } catch (FatalDBException e) { sender.sendMessage(Locale.get(Msg.MANAGE_INFO_FAIL).toString() diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotSwapCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotSwapCommand.java index 9977aaf81..32e26aaca 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotSwapCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotSwapCommand.java @@ -1,6 +1,6 @@ package com.djrapitops.plan.command.commands.manage; -import com.djrapitops.plan.Plan; +import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.settings.Permissions; @@ -23,9 +23,9 @@ import com.djrapitops.plugin.utilities.Verify; */ public class ManageHotSwapCommand extends CommandNode { - private final Plan plugin; + private final PlanPlugin plugin; - public ManageHotSwapCommand(Plan plugin) { + public ManageHotSwapCommand(PlanPlugin plugin) { super("hotswap", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); setShortHelp(Locale.get(Msg.CMD_USG_MANAGE_HOTSWAP).toString()); setArguments(""); diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java index c3728b80b..fa9007768 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java @@ -1,6 +1,6 @@ package com.djrapitops.plan.command.commands.manage; -import com.djrapitops.plan.Plan; +import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.database.databases.sql.SQLiteDB; @@ -28,9 +28,9 @@ import java.util.Arrays; */ public class ManageRestoreCommand extends CommandNode { - private final Plan plugin; + private final PlanPlugin plugin; - public ManageRestoreCommand(Plan plugin) { + public ManageRestoreCommand(PlanPlugin plugin) { super("restore", Permissions.MANAGE.getPermission(), CommandType.CONSOLE); setShortHelp(Locale.get(Msg.CMD_USG_MANAGE_RESTORE).toString()); setArguments("", "", "[-a]"); From e4d16685a49aa0b0e59576c7657645ce58c12f6a Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Wed, 11 Apr 2018 11:37:04 +0300 Subject: [PATCH 05/33] Sponge /plan command registration --- Plan/src/main/java/com/djrapitops/plan/PlanSponge.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java b/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java index e72f886e2..855f7c39d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java +++ b/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java @@ -1,6 +1,7 @@ package com.djrapitops.plan; import com.djrapitops.plan.api.exceptions.EnableException; +import com.djrapitops.plan.command.PlanCommand; import com.djrapitops.plan.system.SpongeSystem; import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; @@ -67,6 +68,7 @@ public class PlanSponge extends SpongePlugin implements PlanPlugin { Log.error("This error should be reported at https://github.com/Rsl1122/Plan-PlayerAnalytics/issues"); onDisable(); } + registerCommand("plan", new PlanCommand(this)); } @Override From ef05304efdd9c5383bac8e394c58d936e4ac82e4 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Wed, 11 Apr 2018 17:00:57 +0300 Subject: [PATCH 06/33] Initial versions of Sponge Listeners (untested) #559 --- .../djrapitops/plan/system/SpongeSystem.java | 2 +- .../listeners/SpongeListenerSystem.java | 22 ++- .../system/listeners/bukkit/ChatListener.java | 26 ++-- .../bukkit/CommandPreprocessListener.java | 36 +++-- .../bukkit/PlayerOnlineListener.java | 98 ++++++------ .../listeners/sponge/SpongeAFKListener.java | 68 +++++++++ .../listeners/sponge/SpongeChatListener.java | 48 ++++++ .../sponge/SpongeCommandListener.java | 57 +++++++ .../listeners/sponge/SpongeDeathListener.java | 119 +++++++++++++++ .../sponge/SpongeGMChangeListener.java | 50 ++++++ .../sponge/SpongePlayerListener.java | 143 ++++++++++++++++++ .../sponge/SpongeWorldChangeListener.java | 58 +++++++ .../player/SpongeKillProcessor.java | 59 ++++++++ 13 files changed, 711 insertions(+), 75 deletions(-) create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeAFKListener.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeChatListener.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeCommandListener.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeGMChangeListener.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongePlayerListener.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeWorldChangeListener.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/SpongeKillProcessor.java diff --git a/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java index 90169df5c..46d620f0d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java @@ -38,7 +38,7 @@ public class SpongeSystem extends PlanSystem implements ServerSystem { fileSystem = new FileSystem(plugin); configSystem = new BukkitConfigSystem(); databaseSystem = new BukkitDBSystem(); - listenerSystem = new SpongeListenerSystem(); + listenerSystem = new SpongeListenerSystem(plugin); taskSystem = new SpongeTaskSystem(); infoSystem = new BukkitInfoSystem(); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/SpongeListenerSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/SpongeListenerSystem.java index 793df78a4..27ccc1def 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/SpongeListenerSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/SpongeListenerSystem.java @@ -1,14 +1,32 @@ package com.djrapitops.plan.system.listeners; +import com.djrapitops.plan.PlanSponge; +import com.djrapitops.plan.system.listeners.sponge.*; +import org.spongepowered.api.Sponge; + public class SpongeListenerSystem extends ListenerSystem { + private final PlanSponge plugin; + + public SpongeListenerSystem(PlanSponge plugin) { + this.plugin = plugin; + } + @Override protected void registerListeners() { - + plugin.registerListener( + new SpongeAFKListener(), + new SpongeChatListener(), + new SpongeCommandListener(), + new SpongeDeathListener(), + new SpongeGMChangeListener(), + new SpongePlayerListener(), + new SpongeWorldChangeListener() + ); } @Override protected void unregisterListeners() { - + Sponge.getEventManager().unregisterPluginListeners(plugin); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/ChatListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/ChatListener.java index 2f767ba06..2a87cd7eb 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/ChatListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/ChatListener.java @@ -31,19 +31,23 @@ public class ChatListener implements Listener { } try { - Player p = event.getPlayer(); - UUID uuid = p.getUniqueId(); - String name = p.getName(); - String displayName = p.getDisplayName(); - - SessionCache sessionCache = SessionCache.getInstance(); - if (sessionCache.isFirstSession(uuid)) { - sessionCache.firstSessionMessageSent(uuid); - } - - Processing.submit(new NameProcessor(uuid, name, displayName)); + actOnChatEvent(event); } catch (Exception e) { Log.toLog(this.getClass(), e); } } + + private void actOnChatEvent(AsyncPlayerChatEvent event) { + Player p = event.getPlayer(); + UUID uuid = p.getUniqueId(); + String name = p.getName(); + String displayName = p.getDisplayName(); + + SessionCache sessionCache = SessionCache.getInstance(); + if (sessionCache.isFirstSession(uuid)) { + sessionCache.firstSessionMessageSent(uuid); + } + + Processing.submit(new NameProcessor(uuid, name, displayName)); + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/CommandPreprocessListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/CommandPreprocessListener.java index 0d7aabde9..9af4a5f0d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/CommandPreprocessListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/CommandPreprocessListener.java @@ -43,27 +43,31 @@ public class CommandPreprocessListener implements Listener { } try { - String commandName = event.getMessage().substring(1).split(" ")[0].toLowerCase(); - - boolean logUnknownCommands = Settings.LOG_UNKNOWN_COMMANDS.isTrue(); - boolean combineCommandAliases = Settings.COMBINE_COMMAND_ALIASES.isTrue(); - - if (!logUnknownCommands || combineCommandAliases) { - Command command = getBukkitCommand(commandName); - if (command == null) { - if (!logUnknownCommands) { - return; - } - } else if (combineCommandAliases) { - commandName = command.getName(); - } - } - Processing.submit(new CommandProcessor(commandName)); + actOnCommandEvent(event); } catch (Exception e) { Log.toLog(this.getClass(), e); } } + private void actOnCommandEvent(PlayerCommandPreprocessEvent event) { + String commandName = event.getMessage().substring(1).split(" ")[0].toLowerCase(); + + boolean logUnknownCommands = Settings.LOG_UNKNOWN_COMMANDS.isTrue(); + boolean combineCommandAliases = Settings.COMBINE_COMMAND_ALIASES.isTrue(); + + if (!logUnknownCommands || combineCommandAliases) { + Command command = getBukkitCommand(commandName); + if (command == null) { + if (!logUnknownCommands) { + return; + } + } else if (combineCommandAliases) { + commandName = command.getName(); + } + } + Processing.submit(new CommandProcessor(commandName)); + } + private Command getBukkitCommand(String commandName) { Command command = plugin.getServer().getPluginCommand(commandName); if (command == null) { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java index 31fd2ba4b..eda55f727 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java @@ -72,61 +72,69 @@ public class PlayerOnlineListener implements Listener { @EventHandler(priority = EventPriority.MONITOR) public void onPlayerJoin(PlayerJoinEvent event) { try { - Player player = event.getPlayer(); - NotificationCenter.checkNotifications(player); - - UUID uuid = player.getUniqueId(); - long time = MiscUtils.getTime(); - - AFKListener.AFK_TRACKER.performedAction(uuid, time); - - String world = player.getWorld().getName(); - String gm = player.getGameMode().name(); - - String ip = player.getAddress().getAddress().getHostAddress(); - - String playerName = player.getName(); - String displayName = player.getDisplayName(); - - int playersOnline = TaskSystem.getInstance().getTpsCountTimer().getLatestPlayersOnline(); - - SessionCache.getInstance().cacheSession(uuid, new Session(time, world, gm)); - - Processing.submit( - new RegisterProcessor(uuid, player.getFirstPlayed(), time, playerName, playersOnline, - new IPUpdateProcessor(uuid, ip, time), - new NameProcessor(uuid, playerName, displayName), - new PlayerPageUpdateProcessor(uuid) - ) - ); - Processing.submit(new NetworkPageUpdateProcessor()); + actOnJoinEvent(event); } catch (Exception e) { Log.toLog(this.getClass(), e); } } + private void actOnJoinEvent(PlayerJoinEvent event) { + Player player = event.getPlayer(); + NotificationCenter.checkNotifications(player); + + UUID uuid = player.getUniqueId(); + long time = MiscUtils.getTime(); + + AFKListener.AFK_TRACKER.performedAction(uuid, time); + + String world = player.getWorld().getName(); + String gm = player.getGameMode().name(); + + String ip = player.getAddress().getAddress().getHostAddress(); + + String playerName = player.getName(); + String displayName = player.getDisplayName(); + + int playersOnline = TaskSystem.getInstance().getTpsCountTimer().getLatestPlayersOnline(); + + SessionCache.getInstance().cacheSession(uuid, new Session(time, world, gm)); + + Processing.submit( + new RegisterProcessor(uuid, player.getFirstPlayed(), time, playerName, playersOnline, + new IPUpdateProcessor(uuid, ip, time), + new NameProcessor(uuid, playerName, displayName), + new PlayerPageUpdateProcessor(uuid) + ) + ); + Processing.submit(new NetworkPageUpdateProcessor()); + } + @EventHandler(priority = EventPriority.MONITOR) public void onPlayerQuit(PlayerQuitEvent event) { try { - long time = MiscUtils.getTime(); - Player player = event.getPlayer(); - UUID uuid = player.getUniqueId(); - - AFKListener.AFK_TRACKER.loggedOut(uuid, time); - - Processing.submit(new BanAndOpProcessor(uuid, player.isBanned(), player.isOp())); - Processing.submit(new EndSessionProcessor(uuid, time)); - Processing.submit(new NetworkPageUpdateProcessor()); - - SessionCache sessionCache = SessionCache.getInstance(); - if (sessionCache.isFirstSession(uuid)) { - int messagesSent = sessionCache.getFirstSessionMsgCount(uuid); - Processing.submit(new FirstLeaveProcessor(uuid, time, messagesSent)); - } - - Processing.submit(new PlayerPageUpdateProcessor(uuid)); + actOnQuitEvent(event); } catch (Exception e) { Log.toLog(this.getClass(), e); } } + + private void actOnQuitEvent(PlayerQuitEvent event) { + long time = MiscUtils.getTime(); + Player player = event.getPlayer(); + UUID uuid = player.getUniqueId(); + + AFKListener.AFK_TRACKER.loggedOut(uuid, time); + + Processing.submit(new BanAndOpProcessor(uuid, player.isBanned(), player.isOp())); + Processing.submit(new EndSessionProcessor(uuid, time)); + Processing.submit(new NetworkPageUpdateProcessor()); + + SessionCache sessionCache = SessionCache.getInstance(); + if (sessionCache.isFirstSession(uuid)) { + int messagesSent = sessionCache.getFirstSessionMsgCount(uuid); + Processing.submit(new FirstLeaveProcessor(uuid, time, messagesSent)); + } + + Processing.submit(new PlayerPageUpdateProcessor(uuid)); + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeAFKListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeAFKListener.java new file mode 100644 index 000000000..62a2897fd --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeAFKListener.java @@ -0,0 +1,68 @@ +package com.djrapitops.plan.system.listeners.sponge; + +import com.djrapitops.plan.system.afk.AFKTracker; +import com.djrapitops.plan.utilities.MiscUtils; +import com.djrapitops.plugin.api.utility.log.Log; +import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.Order; +import org.spongepowered.api.event.command.SendCommandEvent; +import org.spongepowered.api.event.entity.MoveEntityEvent; +import org.spongepowered.api.event.entity.living.humanoid.player.PlayerChangeClientSettingsEvent; +import org.spongepowered.api.event.entity.living.humanoid.player.TargetPlayerEvent; +import org.spongepowered.api.event.filter.cause.First; +import org.spongepowered.api.event.message.MessageChannelEvent; + +import java.util.UUID; + +/** + * Listener that keeps track of actions that are not considered being AFK. + *

+ * Additional Listener calls in SpongePlayerListener to avoid having HIGHEST priority listeners. + * + * @author Rsl1122 + * @see SpongePlayerListener + */ +public class SpongeAFKListener { + + // Static so that /reload does not cause afk tracking to fail. + public static final AFKTracker AFK_TRACKER = new AFKTracker(); + + private void event(TargetPlayerEvent event) { + try { + UUID uuid = event.getTargetEntity().getUniqueId(); + long time = MiscUtils.getTime(); + + AFK_TRACKER.performedAction(uuid, time); + } catch (Exception e) { + Log.toLog(this.getClass(), e); + } + } + + @Listener(order = Order.POST) + public void onMove(MoveEntityEvent event, @First Player player) { + UUID uuid = player.getUniqueId(); + long time = MiscUtils.getTime(); + AFK_TRACKER.performedAction(uuid, time); + } + + @Listener(order = Order.POST) + public void onPlayerChat(MessageChannelEvent.Chat event, @First Player player) { + UUID uuid = player.getUniqueId(); + long time = MiscUtils.getTime(); + AFK_TRACKER.performedAction(uuid, time); + } + + @Listener(order = Order.POST) + public void onPlayerCommand(SendCommandEvent event, @First Player player) { + UUID uuid = player.getUniqueId(); + long time = MiscUtils.getTime(); + AFK_TRACKER.performedAction(uuid, time); + } + + @Listener(order = Order.POST) + public void onSettingsChange(PlayerChangeClientSettingsEvent event) { + event(event); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeChatListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeChatListener.java new file mode 100644 index 000000000..c3f7f56af --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeChatListener.java @@ -0,0 +1,48 @@ +package com.djrapitops.plan.system.listeners.sponge; + +import com.djrapitops.plan.system.cache.SessionCache; +import com.djrapitops.plan.system.processing.Processing; +import com.djrapitops.plan.system.processing.processors.player.NameProcessor; +import com.djrapitops.plugin.api.utility.log.Log; +import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.Order; +import org.spongepowered.api.event.filter.cause.First; +import org.spongepowered.api.event.message.MessageChannelEvent; + +import java.util.UUID; + +/** + * Listener that keeps track of player display name. + * + * @author Rsl1122 + */ +public class SpongeChatListener { + + @Listener(order = Order.POST) + public void onPlayerChat(MessageChannelEvent.Chat event, @First Player player) { + if (event.isCancelled()) { + return; + } + + try { + actOnChatEvent(player); + } catch (Exception e) { + Log.toLog(this.getClass(), e); + } + } + + private void actOnChatEvent(@First Player player) { + UUID uuid = player.getUniqueId(); + String name = player.getName(); + String displayName = player.getDisplayNameData().displayName().get().toPlain(); + + SessionCache sessionCache = SessionCache.getInstance(); + if (sessionCache.isFirstSession(uuid)) { + sessionCache.firstSessionMessageSent(uuid); + } + + Processing.submit(new NameProcessor(uuid, name, displayName)); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeCommandListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeCommandListener.java new file mode 100644 index 000000000..1eccd3774 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeCommandListener.java @@ -0,0 +1,57 @@ +package com.djrapitops.plan.system.listeners.sponge; + +import com.djrapitops.plan.system.processing.Processing; +import com.djrapitops.plan.system.processing.processors.CommandProcessor; +import com.djrapitops.plan.system.settings.Permissions; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plugin.api.utility.log.Log; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.command.CommandMapping; +import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.Order; +import org.spongepowered.api.event.command.SendCommandEvent; +import org.spongepowered.api.event.filter.cause.First; + +import java.util.Optional; + +/** + * Listener that keeps track of used commands. + * + * @author Rsl1122 + */ +public class SpongeCommandListener { + + @Listener(order = Order.POST) + public void onPlayerCommand(SendCommandEvent event, @First Player player) { + boolean hasIgnorePermission = player.hasPermission(Permissions.IGNORE_COMMANDUSE.getPermission()); + if (event.isCancelled() || hasIgnorePermission) { + return; + } + try { + actOnCommandEvent(event); + } catch (Exception e) { + Log.toLog(this.getClass(), e); + } + } + + private void actOnCommandEvent(SendCommandEvent event) { + String commandName = event.getCommand(); + + boolean logUnknownCommands = Settings.LOG_UNKNOWN_COMMANDS.isTrue(); + boolean combineCommandAliases = Settings.COMBINE_COMMAND_ALIASES.isTrue(); + + if (!logUnknownCommands || combineCommandAliases) { + Optional existingCommand = Sponge.getCommandManager().get(commandName); + if (!existingCommand.isPresent()) { + if (!logUnknownCommands) { + return; + } + } else if (combineCommandAliases) { + commandName = existingCommand.get().getPrimaryAlias(); + } + } + Processing.submit(new CommandProcessor(commandName)); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java new file mode 100644 index 000000000..93b5cc42a --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java @@ -0,0 +1,119 @@ +package com.djrapitops.plan.system.listeners.sponge; + +import com.djrapitops.plan.data.container.Session; +import com.djrapitops.plan.system.cache.SessionCache; +import com.djrapitops.plan.system.processing.Processing; +import com.djrapitops.plan.system.processing.processors.player.SpongeKillProcessor; +import com.djrapitops.plan.utilities.MiscUtils; +import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.utilities.Format; +import org.spongepowered.api.data.type.HandTypes; +import org.spongepowered.api.entity.Entity; +import org.spongepowered.api.entity.living.Living; +import org.spongepowered.api.entity.living.animal.Wolf; +import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.entity.projectile.arrow.Arrow; +import org.spongepowered.api.entity.projectile.source.ProjectileSource; +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.cause.entity.damage.source.EntityDamageSource; +import org.spongepowered.api.event.entity.DestructEntityEvent; +import org.spongepowered.api.item.ItemType; +import org.spongepowered.api.item.ItemTypes; +import org.spongepowered.api.item.inventory.ItemStack; + +import java.util.Optional; +import java.util.UUID; + +/** + * Listener for Deaths and Kills on Sponge. + * + * @author Rsl1122 + */ +public class SpongeDeathListener { + + @Listener + public void onEntityDeath(DestructEntityEvent.Death event) { + long time = MiscUtils.getTime(); + Living dead = event.getTargetEntity(); + + if (dead instanceof Player) { + // Process Death + Processing.submitCritical(() -> SessionCache.getCachedSession(dead.getUniqueId()).ifPresent(Session::died)); + } + + try { + Optional optDamageSource = event.getCause().first(EntityDamageSource.class); + if (optDamageSource.isPresent()) { + EntityDamageSource damageSource = optDamageSource.get(); + Entity killerEntity = damageSource.getSource(); + handleKill(time, dead, killerEntity); + } + } catch (Exception e) { + Log.toLog(this.getClass(), e); + } + } + + private void handleKill(long time, Living dead, Entity killerEntity) { + SpongeKillProcessor processor = null; + if (killerEntity instanceof Player) { + processor = handlePlayerKill(time, dead, (Player) killerEntity); + } else if (killerEntity instanceof Wolf) { + processor = handleWolfKill(time, dead, (Wolf) killerEntity); + } else if (killerEntity instanceof Arrow) { + processor = handleArrowKill(time, dead, (Arrow) killerEntity); + } + if (processor != null) { + Processing.submit(processor); + } + } + + private SpongeKillProcessor handlePlayerKill(long time, Living dead, Player killer) { + + Optional inMainHand = killer.getItemInHand(HandTypes.MAIN_HAND); + ItemStack inHand = inMainHand.orElse(killer.getItemInHand(HandTypes.OFF_HAND).orElse(ItemStack.empty())); + ItemType type = inHand.isEmpty() ? ItemTypes.AIR : inHand.getType(); + + return new SpongeKillProcessor(killer.getUniqueId(), time, dead, normalizeItemName(type)); + } + + private SpongeKillProcessor handleWolfKill(long time, Living dead, Wolf wolf) { + Optional creator = wolf.getCreator(); + + return creator.map( + uuid -> new SpongeKillProcessor(uuid, time, dead, "Wolf") + ).orElse(null); + } + + private SpongeKillProcessor handleArrowKill(long time, Living dead, Arrow arrow) { + ProjectileSource source = arrow.getShooter(); + if (!(source instanceof Player)) { + return null; + } + + Player player = (Player) source; + + return new SpongeKillProcessor(player.getUniqueId(), time, dead, "Bow"); + } + + /** + * Normalizes an item name + * + * @param type The type of the item + * @return The normalized item name + */ + private String normalizeItemName(ItemType type) { + String[] parts = type.getName().split("_"); + StringBuilder builder = new StringBuilder(); + + for (int i = 0; i < parts.length; i++) { + String part = new Format(parts[i]).capitalize().toString(); + builder.append(part); + if (i < parts.length - 1) { + builder.append(" "); + } + } + + return builder.toString(); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeGMChangeListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeGMChangeListener.java new file mode 100644 index 000000000..c1bfa3850 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeGMChangeListener.java @@ -0,0 +1,50 @@ +package com.djrapitops.plan.system.listeners.sponge; + +import com.djrapitops.plan.data.container.Session; +import com.djrapitops.plan.system.cache.SessionCache; +import com.djrapitops.plan.system.settings.WorldAliasSettings; +import com.djrapitops.plan.utilities.MiscUtils; +import com.djrapitops.plugin.api.utility.log.Log; +import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.Order; +import org.spongepowered.api.event.entity.living.humanoid.ChangeGameModeEvent; + +import java.util.Optional; +import java.util.UUID; + +/** + * Listener for GameMode change on Sponge. + * + * @author Rsl1122 + */ +public class SpongeGMChangeListener { + + @Listener(order = Order.POST) + public void onGMChange(ChangeGameModeEvent.TargetPlayer event) { + if (event.isCancelled()) { + return; + } + + try { + actOnGMChangeEvent(event); + } catch (Exception e) { + Log.toLog(this.getClass(), e); + } + } + + private void actOnGMChangeEvent(ChangeGameModeEvent.TargetPlayer event) { + Player player = event.getTargetEntity(); + UUID uuid = player.getUniqueId(); + long time = MiscUtils.getTime(); + + String gameMode = event.getGameMode().getName().toUpperCase(); + String worldName = player.getWorld().getName(); + + WorldAliasSettings.addWorld(worldName); + + Optional cachedSession = SessionCache.getCachedSession(uuid); + cachedSession.ifPresent(session -> session.changeState(worldName, gameMode, time)); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongePlayerListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongePlayerListener.java new file mode 100644 index 000000000..38135e5be --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongePlayerListener.java @@ -0,0 +1,143 @@ +package com.djrapitops.plan.system.listeners.sponge; + +import com.djrapitops.plan.data.container.Session; +import com.djrapitops.plan.system.cache.SessionCache; +import com.djrapitops.plan.system.processing.Processing; +import com.djrapitops.plan.system.processing.processors.info.NetworkPageUpdateProcessor; +import com.djrapitops.plan.system.processing.processors.info.PlayerPageUpdateProcessor; +import com.djrapitops.plan.system.processing.processors.player.*; +import com.djrapitops.plan.system.tasks.TaskSystem; +import com.djrapitops.plan.utilities.MiscUtils; +import com.djrapitops.plugin.api.systems.NotificationCenter; +import com.djrapitops.plugin.api.utility.log.Log; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.data.key.Keys; +import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.entity.living.player.gamemode.GameMode; +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.Order; +import org.spongepowered.api.event.entity.living.humanoid.player.KickPlayerEvent; +import org.spongepowered.api.event.network.ClientConnectionEvent; +import org.spongepowered.api.profile.GameProfile; +import org.spongepowered.api.service.ProviderRegistration; +import org.spongepowered.api.service.ban.BanService; + +import java.util.Optional; +import java.util.UUID; + +/** + * Listener for Player Join/Leave on Sponge. + * + * @author Rsl1122 + */ +public class SpongePlayerListener { + + @Listener(order = Order.POST) + public void onLogin(ClientConnectionEvent.Login event) { + try { + actOnLoginEvent(event); + } catch (Exception e) { + Log.toLog(this.getClass(), e); + } + } + + private void actOnLoginEvent(ClientConnectionEvent.Login event) { + GameProfile profile = event.getProfile(); + UUID uuid = profile.getUniqueId(); + boolean banned = isBanned(profile); + Processing.submit(new BanAndOpProcessor(uuid, banned, false)); + } + + @Listener(order = Order.POST) + public void onKick(KickPlayerEvent event) { + try { + UUID uuid = event.getTargetEntity().getUniqueId(); + Processing.submit(new KickProcessor(uuid)); + } catch (Exception e) { + Log.toLog(this.getClass(), e); + } + } + + private boolean isBanned(GameProfile profile) { + Optional> banService = Sponge.getServiceManager().getRegistration(BanService.class); + boolean banned = false; + if (banService.isPresent()) { + banned = banService.get().getProvider().isBanned(profile); + } + return banned; + } + + @Listener(order = Order.POST) + public void onJoin(ClientConnectionEvent.Join event) { + try { + actOnJoinEvent(event); + } catch (Exception e) { + Log.toLog(this.getClass(), e); + } + } + + private void actOnJoinEvent(ClientConnectionEvent.Join event) { + Player player = event.getTargetEntity(); + + NotificationCenter.checkNotifications(player); + + UUID uuid = player.getUniqueId(); + long time = MiscUtils.getTime(); + + SpongeAFKListener.AFK_TRACKER.performedAction(uuid, time); + + String world = player.getWorld().getName(); + Optional gameMode = player.getGameModeData().get(Keys.GAME_MODE); + String gm = "ADVENTURE"; + if (gameMode.isPresent()) { + gm = gameMode.get().getName().toUpperCase(); + } + + String ip = player.getConnection().getAddress().getAddress().getHostAddress(); + + String playerName = player.getName(); + String displayName = player.getDisplayNameData().displayName().get().toPlain(); + + int playersOnline = TaskSystem.getInstance().getTpsCountTimer().getLatestPlayersOnline(); + + SessionCache.getInstance().cacheSession(uuid, new Session(time, world, gm)); + + Processing.submit( + new RegisterProcessor(uuid, time, time, playerName, playersOnline, + new IPUpdateProcessor(uuid, ip, time), + new NameProcessor(uuid, playerName, displayName), + new PlayerPageUpdateProcessor(uuid) + ) + ); + Processing.submit(new NetworkPageUpdateProcessor()); + } + + @Listener(order = Order.POST) + public void onQuit(ClientConnectionEvent.Disconnect event) { + try { + actOnQuitEvent(event); + } catch (Exception e) { + Log.toLog(this.getClass(), e); + } + } + + private void actOnQuitEvent(ClientConnectionEvent.Disconnect event) { + long time = MiscUtils.getTime(); + Player player = event.getTargetEntity(); + UUID uuid = player.getUniqueId(); + + SpongeAFKListener.AFK_TRACKER.loggedOut(uuid, time); + + Processing.submit(new BanAndOpProcessor(uuid, isBanned(player.getProfile()), false)); + Processing.submit(new EndSessionProcessor(uuid, time)); + Processing.submit(new NetworkPageUpdateProcessor()); + + SessionCache sessionCache = SessionCache.getInstance(); + if (sessionCache.isFirstSession(uuid)) { + int messagesSent = sessionCache.getFirstSessionMsgCount(uuid); + Processing.submit(new FirstLeaveProcessor(uuid, time, messagesSent)); + } + + Processing.submit(new PlayerPageUpdateProcessor(uuid)); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeWorldChangeListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeWorldChangeListener.java new file mode 100644 index 000000000..230983ea8 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeWorldChangeListener.java @@ -0,0 +1,58 @@ +package com.djrapitops.plan.system.listeners.sponge; + +import com.djrapitops.plan.data.container.Session; +import com.djrapitops.plan.system.cache.SessionCache; +import com.djrapitops.plan.system.settings.WorldAliasSettings; +import com.djrapitops.plan.utilities.MiscUtils; +import com.djrapitops.plugin.api.utility.log.Log; +import org.spongepowered.api.data.key.Keys; +import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.entity.living.player.gamemode.GameMode; +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.Order; +import org.spongepowered.api.event.entity.MoveEntityEvent; +import org.spongepowered.api.event.filter.cause.First; + +import java.util.Optional; +import java.util.UUID; + +/** + * Listener for World change on Sponge. + * + * @author Rsl1122 + */ +public class SpongeWorldChangeListener { + + @Listener(order = Order.POST) + public void onWorldChange(MoveEntityEvent.Teleport event, @First Player player) { + if (event.isCancelled()) { + return; + } + + try { + actOnEvent(event, player); + } catch (Exception e) { + Log.toLog(this.getClass(), e); + } + } + + private void actOnEvent(MoveEntityEvent.Teleport event, Player player) { + long time = MiscUtils.getTime(); + + UUID uuid = player.getUniqueId(); + + String worldName = event.getToTransform().getExtent().getName(); + String gameMode = getGameMode(player); + + WorldAliasSettings.addWorld(worldName); + + Optional cachedSession = SessionCache.getCachedSession(uuid); + cachedSession.ifPresent(session -> session.changeState(worldName, gameMode, time)); + } + + private String getGameMode(Player player) { + Optional gameMode = player.getGameModeData().get(Keys.GAME_MODE); + return gameMode.map(gm -> gm.getName().toUpperCase()).orElse("ADVENTURE"); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/SpongeKillProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/SpongeKillProcessor.java new file mode 100644 index 000000000..d352c3b4f --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/SpongeKillProcessor.java @@ -0,0 +1,59 @@ +package com.djrapitops.plan.system.processing.processors.player; + +import com.djrapitops.plan.data.container.PlayerKill; +import com.djrapitops.plan.data.container.Session; +import com.djrapitops.plan.system.cache.SessionCache; +import com.djrapitops.plan.system.processing.CriticalRunnable; +import org.bukkit.entity.Player; +import org.spongepowered.api.entity.living.Living; + +import java.util.Optional; +import java.util.UUID; + +/** + * Processor Class for KillEvent information when the killer is a + * player. + *

+ * Adds PlayerKill or a Mob kill to the active Session. + * + * @author Rsl1122 + * @since 4.3.0 + */ +public class SpongeKillProcessor implements CriticalRunnable { + + private final UUID uuid; + private final Living dead; + private final String weaponName; + private final long time; + + /** + * Constructor. + * + * @param uuid UUID of the killer. + * @param time Epoch ms the event occurred. + * @param dead Dead entity (Mob or Player) + * @param weaponName Weapon used. + */ + public SpongeKillProcessor(UUID uuid, long time, Living dead, String weaponName) { + this.uuid = uuid; + this.time = time; + this.dead = dead; + this.weaponName = weaponName; + } + + @Override + public void run() { + Optional cachedSession = SessionCache.getCachedSession(uuid); + if (!cachedSession.isPresent()) { + return; + } + Session session = cachedSession.get(); + + if (dead instanceof Player) { + Player deadPlayer = (Player) dead; + session.playerKilled(new PlayerKill(deadPlayer.getUniqueId(), weaponName, time)); + } else { + session.mobKilled(); + } + } +} From e6eac6fa5de2b21bf0c704c4bd39ea3b2c467632 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Wed, 11 Apr 2018 17:36:16 +0300 Subject: [PATCH 07/33] Sponge TaskSystem, fix to DeathListener --- .../listeners/sponge/SpongeDeathListener.java | 9 +- .../plan/system/tasks/BukkitTaskSystem.java | 62 +---------- .../plan/system/tasks/BungeeTaskSystem.java | 2 +- .../plan/system/tasks/ServerTaskSystem.java | 69 ++++++++++++ .../plan/system/tasks/SpongeTaskSystem.java | 19 +++- .../{bukkit => server}/BootAnalysisTask.java | 2 +- .../BukkitTPSCountTimer.java | 2 +- .../NetworkPageRefreshTask.java | 2 +- .../PaperTPSCountTimer.java | 2 +- .../PeriodicAnalysisTask.java | 2 +- .../tasks/server/SpongeTPSCountTimer.java | 103 ++++++++++++++++++ .../djrapitops/plan/utilities/MiscUtils.java | 10 +- 12 files changed, 208 insertions(+), 76 deletions(-) create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/tasks/ServerTaskSystem.java rename Plan/src/main/java/com/djrapitops/plan/system/tasks/{bukkit => server}/BootAnalysisTask.java (96%) rename Plan/src/main/java/com/djrapitops/plan/system/tasks/{bukkit => server}/BukkitTPSCountTimer.java (98%) rename Plan/src/main/java/com/djrapitops/plan/system/tasks/{bukkit => server}/NetworkPageRefreshTask.java (90%) rename Plan/src/main/java/com/djrapitops/plan/system/tasks/{bukkit => server}/PaperTPSCountTimer.java (96%) rename Plan/src/main/java/com/djrapitops/plan/system/tasks/{bukkit => server}/PeriodicAnalysisTask.java (96%) create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/tasks/server/SpongeTPSCountTimer.java diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java index 93b5cc42a..88d0118df 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java @@ -7,6 +7,7 @@ import com.djrapitops.plan.system.processing.processors.player.SpongeKillProcess import com.djrapitops.plan.utilities.MiscUtils; import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.utilities.Format; +import org.spongepowered.api.data.key.Keys; import org.spongepowered.api.data.type.HandTypes; import org.spongepowered.api.entity.Entity; import org.spongepowered.api.entity.living.Living; @@ -77,9 +78,13 @@ public class SpongeDeathListener { } private SpongeKillProcessor handleWolfKill(long time, Living dead, Wolf wolf) { - Optional creator = wolf.getCreator(); + Optional> owner = wolf.get(Keys.TAMED_OWNER); - return creator.map( + if (!owner.isPresent()) { + return null; + } + + return owner.get().map( uuid -> new SpongeKillProcessor(uuid, time, dead, "Wolf") ).orElse(null); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/BukkitTaskSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/BukkitTaskSystem.java index 087ad6744..b9f18a62e 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/BukkitTaskSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/BukkitTaskSystem.java @@ -5,17 +5,9 @@ package com.djrapitops.plan.system.tasks; import com.djrapitops.plan.Plan; -import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.system.settings.locale.Locale; -import com.djrapitops.plan.system.settings.locale.Msg; -import com.djrapitops.plan.system.tasks.bukkit.*; -import com.djrapitops.plan.utilities.file.export.HtmlExport; -import com.djrapitops.plugin.api.Benchmark; +import com.djrapitops.plan.system.tasks.server.BukkitTPSCountTimer; +import com.djrapitops.plan.system.tasks.server.PaperTPSCountTimer; import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.task.ITask; -import com.djrapitops.plugin.task.RunnableFactory; import org.bukkit.Bukkit; /** @@ -23,62 +15,18 @@ import org.bukkit.Bukkit; * * @author Rsl1122 */ -public class BukkitTaskSystem extends TaskSystem { - - private ITask bootAnalysisTask; - - private final Plan plugin; +public class BukkitTaskSystem extends ServerTaskSystem { public BukkitTaskSystem(Plan plugin) { + super(plugin); tpsCountTimer = Check.isPaperAvailable() ? new PaperTPSCountTimer(plugin) : new BukkitTPSCountTimer(plugin); - - this.plugin = plugin; - } - - @Override - public void enable() { - registerTasks(); } @Override public void disable() { super.disable(); - Bukkit.getScheduler().cancelTasks(plugin); - } - - private void registerTasks() { - Benchmark.start("Task Registration"); - - // Analysis refresh settings - int analysisRefreshMinutes = Settings.ANALYSIS_AUTO_REFRESH.getNumber(); - boolean analysisRefreshTaskIsEnabled = analysisRefreshMinutes > 0; - long analysisPeriod = analysisRefreshMinutes * TimeAmount.MINUTE.ticks(); - - Log.info(Locale.get(Msg.ENABLE_BOOT_ANALYSIS_INFO).toString()); - - registerTask(tpsCountTimer).runTaskTimer(1000, TimeAmount.SECOND.ticks()); - registerTask(new NetworkPageRefreshTask()).runTaskTimerAsynchronously(20L, 5L * TimeAmount.MINUTE.ticks()); - bootAnalysisTask = registerTask(new BootAnalysisTask()).runTaskLaterAsynchronously(30L * TimeAmount.SECOND.ticks()); - - if (analysisRefreshTaskIsEnabled) { - registerTask(new PeriodicAnalysisTask()).runTaskTimerAsynchronously(analysisPeriod, analysisPeriod); - } - if (Settings.ANALYSIS_EXPORT.isTrue()) { - RunnableFactory.createNew(new HtmlExport(plugin)).runTaskAsynchronously(); - } - Benchmark.stop("Enable", "Task Registration"); - } - - public void cancelBootAnalysis() { - try { - if (bootAnalysisTask != null) { - bootAnalysisTask.cancel(); - bootAnalysisTask = null; - } - } catch (Exception ignored) { - /* Ignored */ - } + Bukkit.getScheduler().cancelTasks((Plan) plugin); } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/BungeeTaskSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/BungeeTaskSystem.java index bd71063fd..49719b024 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/BungeeTaskSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/BungeeTaskSystem.java @@ -6,9 +6,9 @@ package com.djrapitops.plan.system.tasks; import com.djrapitops.plan.PlanBungee; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.system.tasks.bukkit.NetworkPageRefreshTask; import com.djrapitops.plan.system.tasks.bungee.BungeeTPSCountTimer; import com.djrapitops.plan.system.tasks.bungee.EnableConnectionTask; +import com.djrapitops.plan.system.tasks.server.NetworkPageRefreshTask; import com.djrapitops.plan.utilities.file.export.HtmlExport; import com.djrapitops.plugin.api.TimeAmount; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/ServerTaskSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/ServerTaskSystem.java new file mode 100644 index 000000000..643205841 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/ServerTaskSystem.java @@ -0,0 +1,69 @@ +package com.djrapitops.plan.system.tasks; + +import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.locale.Locale; +import com.djrapitops.plan.system.settings.locale.Msg; +import com.djrapitops.plan.system.tasks.server.BootAnalysisTask; +import com.djrapitops.plan.system.tasks.server.NetworkPageRefreshTask; +import com.djrapitops.plan.system.tasks.server.PeriodicAnalysisTask; +import com.djrapitops.plan.utilities.file.export.HtmlExport; +import com.djrapitops.plugin.api.Benchmark; +import com.djrapitops.plugin.api.TimeAmount; +import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.task.ITask; +import com.djrapitops.plugin.task.RunnableFactory; + +/** + * Abstracted TaskSystem implementation for both Bukkit and Sponge. + * + * @author Rsl1122 + */ +public class ServerTaskSystem extends TaskSystem { + + protected final PlanPlugin plugin; + protected ITask bootAnalysisTask; + + public ServerTaskSystem(PlanPlugin plugin) { + this.plugin = plugin; + } + + @Override + public void enable() { + registerTasks(); + } + + private void registerTasks() { + Benchmark.start("Task Registration"); + + // Analysis refresh settings + int analysisRefreshMinutes = Settings.ANALYSIS_AUTO_REFRESH.getNumber(); + boolean analysisRefreshTaskIsEnabled = analysisRefreshMinutes > 0; + long analysisPeriod = analysisRefreshMinutes * TimeAmount.MINUTE.ticks(); + + Log.info(Locale.get(Msg.ENABLE_BOOT_ANALYSIS_INFO).toString()); + + registerTask(tpsCountTimer).runTaskTimer(1000, TimeAmount.SECOND.ticks()); + registerTask(new NetworkPageRefreshTask()).runTaskTimerAsynchronously(20L, 5L * TimeAmount.MINUTE.ticks()); + bootAnalysisTask = registerTask(new BootAnalysisTask()).runTaskLaterAsynchronously(30L * TimeAmount.SECOND.ticks()); + + if (analysisRefreshTaskIsEnabled) { + registerTask(new PeriodicAnalysisTask()).runTaskTimerAsynchronously(analysisPeriod, analysisPeriod); + } + if (Settings.ANALYSIS_EXPORT.isTrue()) { + RunnableFactory.createNew(new HtmlExport(plugin)).runTaskAsynchronously(); + } + Benchmark.stop("Enable", "Task Registration"); + } + + public void cancelBootAnalysis() { + try { + if (bootAnalysisTask != null) { + bootAnalysisTask.cancel(); + bootAnalysisTask = null; + } + } catch (Exception ignored) { + /* Ignored */ + } + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/SpongeTaskSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/SpongeTaskSystem.java index f6f9832f1..e9e8f4c6f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/SpongeTaskSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/SpongeTaskSystem.java @@ -1,9 +1,22 @@ package com.djrapitops.plan.system.tasks; -public class SpongeTaskSystem extends TaskSystem { +import com.djrapitops.plan.PlanSponge; +import com.djrapitops.plan.system.tasks.server.SpongeTPSCountTimer; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.scheduler.Task; + +public class SpongeTaskSystem extends ServerTaskSystem { + + public SpongeTaskSystem(PlanSponge plugin) { + super(plugin); + tpsCountTimer = new SpongeTPSCountTimer(plugin); + } @Override - public void enable() { - + public void disable() { + super.disable(); + for (Task task : Sponge.getScheduler().getScheduledTasks(plugin)) { + task.cancel(); + } } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/bukkit/BootAnalysisTask.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/BootAnalysisTask.java similarity index 96% rename from Plan/src/main/java/com/djrapitops/plan/system/tasks/bukkit/BootAnalysisTask.java rename to Plan/src/main/java/com/djrapitops/plan/system/tasks/server/BootAnalysisTask.java index 90cd49488..baa8c53ff 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/bukkit/BootAnalysisTask.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/BootAnalysisTask.java @@ -1,4 +1,4 @@ -package com.djrapitops.plan.system.tasks.bukkit; +package com.djrapitops.plan.system.tasks.server; import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.info.InfoSystem; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/bukkit/BukkitTPSCountTimer.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/BukkitTPSCountTimer.java similarity index 98% rename from Plan/src/main/java/com/djrapitops/plan/system/tasks/bukkit/BukkitTPSCountTimer.java rename to Plan/src/main/java/com/djrapitops/plan/system/tasks/server/BukkitTPSCountTimer.java index 027294e98..0bc8a0b74 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/bukkit/BukkitTPSCountTimer.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/BukkitTPSCountTimer.java @@ -1,4 +1,4 @@ -package com.djrapitops.plan.system.tasks.bukkit; +package com.djrapitops.plan.system.tasks.server; import com.djrapitops.plan.Plan; import com.djrapitops.plan.data.container.TPS; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/bukkit/NetworkPageRefreshTask.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/NetworkPageRefreshTask.java similarity index 90% rename from Plan/src/main/java/com/djrapitops/plan/system/tasks/bukkit/NetworkPageRefreshTask.java rename to Plan/src/main/java/com/djrapitops/plan/system/tasks/server/NetworkPageRefreshTask.java index 6589bf4c1..0b598e1dd 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/bukkit/NetworkPageRefreshTask.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/NetworkPageRefreshTask.java @@ -1,4 +1,4 @@ -package com.djrapitops.plan.system.tasks.bukkit; +package com.djrapitops.plan.system.tasks.server; import com.djrapitops.plan.system.info.InfoSystem; import com.djrapitops.plan.system.info.connection.WebExceptionLogger; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/bukkit/PaperTPSCountTimer.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PaperTPSCountTimer.java similarity index 96% rename from Plan/src/main/java/com/djrapitops/plan/system/tasks/bukkit/PaperTPSCountTimer.java rename to Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PaperTPSCountTimer.java index 845a22a9d..00b5fd9ce 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/bukkit/PaperTPSCountTimer.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PaperTPSCountTimer.java @@ -1,4 +1,4 @@ -package com.djrapitops.plan.system.tasks.bukkit; +package com.djrapitops.plan.system.tasks.server; import com.djrapitops.plan.Plan; import com.djrapitops.plan.data.container.TPS; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/bukkit/PeriodicAnalysisTask.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PeriodicAnalysisTask.java similarity index 96% rename from Plan/src/main/java/com/djrapitops/plan/system/tasks/bukkit/PeriodicAnalysisTask.java rename to Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PeriodicAnalysisTask.java index e3a11f3d1..32436b109 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/bukkit/PeriodicAnalysisTask.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PeriodicAnalysisTask.java @@ -1,4 +1,4 @@ -package com.djrapitops.plan.system.tasks.bukkit; +package com.djrapitops.plan.system.tasks.server; import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.info.InfoSystem; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/SpongeTPSCountTimer.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/SpongeTPSCountTimer.java new file mode 100644 index 000000000..b813d1639 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/SpongeTPSCountTimer.java @@ -0,0 +1,103 @@ +package com.djrapitops.plan.system.tasks.server; + +import com.djrapitops.plan.PlanSponge; +import com.djrapitops.plan.data.container.TPS; +import com.djrapitops.plan.data.container.builders.TPSBuilder; +import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.tasks.TPSCountTimer; +import com.djrapitops.plan.utilities.analysis.MathUtils; +import com.djrapitops.plugin.api.utility.log.Log; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.world.Chunk; +import org.spongepowered.api.world.World; + +import java.lang.management.ManagementFactory; +import java.lang.management.OperatingSystemMXBean; +import java.util.Iterator; + +public class SpongeTPSCountTimer extends TPSCountTimer { + + private long lastCheckNano; + + public SpongeTPSCountTimer(PlanSponge plugin) { + super(plugin); + lastCheckNano = -1; + } + + @Override + public void addNewTPSEntry(long nanoTime, long now) { + long diff = nanoTime - lastCheckNano; + + lastCheckNano = nanoTime; + + if (diff > nanoTime) { // First run's diff = nanoTime + 1, no calc possible. + Log.debug("First run of TPSCountTimer Task."); + return; + } + + history.add(calculateTPS(diff, now)); + } + + /** + * Calculates the TPS + * + * @param diff The time difference between the last run and the new run + * @param now The time right now + * @return the TPS + */ + private TPS calculateTPS(long diff, long now) { + OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean(); + int availableProcessors = operatingSystemMXBean.getAvailableProcessors(); + double averageCPUUsage = MathUtils.round(operatingSystemMXBean.getSystemLoadAverage() / availableProcessors * 100.0); + + if (averageCPUUsage < 0) { // If unavailable, getSystemLoadAverage() returns -1 + averageCPUUsage = -1; + } + + Runtime runtime = Runtime.getRuntime(); + + long totalMemory = runtime.totalMemory(); + long usedMemory = (totalMemory - runtime.freeMemory()) / 1000000; + + double tps = Sponge.getGame().getServer().getTicksPerSecond(); + int playersOnline = ServerInfo.getServerProperties().getOnlinePlayers(); + latestPlayersOnline = playersOnline; + int loadedChunks = getLoadedChunks(); + int entityCount = getEntityCount(); + + return TPSBuilder.get() + .date(now) + .tps(tps) + .playersOnline(playersOnline) + .usedCPU(averageCPUUsage) + .usedMemory(usedMemory) + .entities(entityCount) + .chunksLoaded(loadedChunks) + .toTPS(); + } + + /** + * Gets the amount of loaded chunks + * + * @return amount of loaded chunks + */ + private int getLoadedChunks() { + int loaded = 0; + for (World world : Sponge.getGame().getServer().getWorlds()) { + Iterator iterator = world.getLoadedChunks().iterator(); + while (iterator.hasNext()) { + loaded++; + } + } + return loaded; + } + + /** + * Gets the amount of entities on the server + * + * @return amount of entities + */ + protected int getEntityCount() { + return Sponge.getGame().getServer().getWorlds().stream().mapToInt(world -> world.getEntities().size()).sum(); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java b/Plan/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java index 722d24b52..18a740eeb 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java @@ -1,14 +1,12 @@ package com.djrapitops.plan.utilities; -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.PlanBungee; +import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.database.DBException; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; -import com.djrapitops.plugin.api.Check; import com.djrapitops.plugin.api.TimeAmount; import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.command.CommandUtils; @@ -142,10 +140,6 @@ public class MiscUtils { } public static String getPlanVersion() { - if (Check.isBukkitAvailable()) { - return Plan.getInstance().getDescription().getVersion(); - } else { - return PlanBungee.getInstance().getDescription().getVersion(); - } + return PlanPlugin.getInstance().getVersion(); } } From f4c3f804cde58a6a4713712d61c39d5a1578a52c Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Wed, 11 Apr 2018 19:14:02 +0300 Subject: [PATCH 08/33] Fixed Death Processing and other sponge bugs --- .../djrapitops/plan/system/SpongeSystem.java | 2 +- .../listeners/sponge/SpongeDeathListener.java | 13 +++++++--- .../player/SpongeKillProcessor.java | 24 ++++++++++++------- .../tasks/server/SpongeTPSCountTimer.java | 4 +++- .../plan/utilities/analysis/Analysis.java | 4 ++-- 5 files changed, 31 insertions(+), 16 deletions(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java index 46d620f0d..ac3003e0d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java @@ -39,7 +39,7 @@ public class SpongeSystem extends PlanSystem implements ServerSystem { configSystem = new BukkitConfigSystem(); databaseSystem = new BukkitDBSystem(); listenerSystem = new SpongeListenerSystem(plugin); - taskSystem = new SpongeTaskSystem(); + taskSystem = new SpongeTaskSystem(plugin); infoSystem = new BukkitInfoSystem(); serverInfo = new SpongeServerInfo(); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java index 88d0118df..43aa426ed 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java @@ -74,7 +74,14 @@ public class SpongeDeathListener { ItemStack inHand = inMainHand.orElse(killer.getItemInHand(HandTypes.OFF_HAND).orElse(ItemStack.empty())); ItemType type = inHand.isEmpty() ? ItemTypes.AIR : inHand.getType(); - return new SpongeKillProcessor(killer.getUniqueId(), time, dead, normalizeItemName(type)); + return new SpongeKillProcessor(killer.getUniqueId(), time, getUUID(dead), normalizeItemName(type)); + } + + private UUID getUUID(Living dead) { + if (dead instanceof Player) { + return dead.getUniqueId(); + } + return null; } private SpongeKillProcessor handleWolfKill(long time, Living dead, Wolf wolf) { @@ -85,7 +92,7 @@ public class SpongeDeathListener { } return owner.get().map( - uuid -> new SpongeKillProcessor(uuid, time, dead, "Wolf") + uuid -> new SpongeKillProcessor(uuid, time, getUUID(dead), "Wolf") ).orElse(null); } @@ -97,7 +104,7 @@ public class SpongeDeathListener { Player player = (Player) source; - return new SpongeKillProcessor(player.getUniqueId(), time, dead, "Bow"); + return new SpongeKillProcessor(player.getUniqueId(), time, getUUID(dead), "Bow"); } /** diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/SpongeKillProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/SpongeKillProcessor.java index d352c3b4f..dbc95a61a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/SpongeKillProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/SpongeKillProcessor.java @@ -4,8 +4,6 @@ import com.djrapitops.plan.data.container.PlayerKill; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.system.cache.SessionCache; import com.djrapitops.plan.system.processing.CriticalRunnable; -import org.bukkit.entity.Player; -import org.spongepowered.api.entity.living.Living; import java.util.Optional; import java.util.UUID; @@ -22,7 +20,7 @@ import java.util.UUID; public class SpongeKillProcessor implements CriticalRunnable { private final UUID uuid; - private final Living dead; + private final UUID deadUUID; private final String weaponName; private final long time; @@ -31,29 +29,37 @@ public class SpongeKillProcessor implements CriticalRunnable { * * @param uuid UUID of the killer. * @param time Epoch ms the event occurred. - * @param dead Dead entity (Mob or Player) + * @param deadUUID Dead entity (Mob or Player) * @param weaponName Weapon used. */ - public SpongeKillProcessor(UUID uuid, long time, Living dead, String weaponName) { + public SpongeKillProcessor(UUID uuid, long time, UUID deadUUID, String weaponName) { this.uuid = uuid; this.time = time; - this.dead = dead; + this.deadUUID = deadUUID; this.weaponName = weaponName; } @Override public void run() { Optional cachedSession = SessionCache.getCachedSession(uuid); + System.out.println("*"); if (!cachedSession.isPresent()) { + System.out.println("No session"); return; } + System.out.println("**"); Session session = cachedSession.get(); + System.out.println("***"); - if (dead instanceof Player) { - Player deadPlayer = (Player) dead; - session.playerKilled(new PlayerKill(deadPlayer.getUniqueId(), weaponName, time)); + if (deadUUID != null) { + System.out.println("Dead player"); + + session.playerKilled(new PlayerKill(deadUUID, weaponName, time)); } else { + System.out.println("Dead mob"); + session.mobKilled(); } + System.out.println("****"); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/SpongeTPSCountTimer.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/SpongeTPSCountTimer.java index b813d1639..f19301d6a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/SpongeTPSCountTimer.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/SpongeTPSCountTimer.java @@ -62,7 +62,7 @@ public class SpongeTPSCountTimer extends TPSCountTimer { double tps = Sponge.getGame().getServer().getTicksPerSecond(); int playersOnline = ServerInfo.getServerProperties().getOnlinePlayers(); latestPlayersOnline = playersOnline; - int loadedChunks = getLoadedChunks(); + int loadedChunks = -1; int entityCount = getEntityCount(); return TPSBuilder.get() @@ -82,6 +82,8 @@ public class SpongeTPSCountTimer extends TPSCountTimer { * @return amount of loaded chunks */ private int getLoadedChunks() { + // DISABLED + int loaded = 0; for (World world : Sponge.getGame().getServer().getWorlds()) { Iterator iterator = world.getLoadedChunks().iterator(); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/Analysis.java b/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/Analysis.java index 873ca9395..5cd90d252 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/Analysis.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/Analysis.java @@ -16,7 +16,7 @@ import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; -import com.djrapitops.plan.system.tasks.BukkitTaskSystem; +import com.djrapitops.plan.system.tasks.ServerTaskSystem; import com.djrapitops.plan.system.tasks.TaskSystem; import com.djrapitops.plan.utilities.MiscUtils; import com.djrapitops.plugin.StaticHolder; @@ -79,7 +79,7 @@ public class Analysis implements Callable { } private AnalysisData runAnalysis() throws Exception { - ((BukkitTaskSystem) TaskSystem.getInstance()).cancelBootAnalysis(); + ((ServerTaskSystem) TaskSystem.getInstance()).cancelBootAnalysis(); Benchmark.start("Analysis: Total"); log(Locale.get(Msg.ANALYSIS_START).toString()); From cb9c99108dcaf76a74b8683f8d38ba815e0a2fe6 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Wed, 11 Apr 2018 19:33:19 +0300 Subject: [PATCH 09/33] Sponge config values and renamed some Systems to more generic names. --- .../djrapitops/plan/system/BukkitSystem.java | 12 +++---- .../djrapitops/plan/system/SpongeSystem.java | 14 ++++---- ...ukkitDBSystem.java => ServerDBSystem.java} | 2 +- ...tInfoSystem.java => ServerInfoSystem.java} | 8 ++--- ...ystem.java => ServerConnectionSystem.java} | 4 +-- .../plan/system/settings/Settings.java | 1 + ...figSystem.java => ServerConfigSystem.java} | 2 +- .../settings/config/SpongeConfigSystem.java | 35 +++++++++++++++++++ .../system/BungeeBukkitConnectionTest.java | 4 +-- .../plan/system/BungeeSystemTest.java | 6 ++-- 10 files changed, 63 insertions(+), 25 deletions(-) rename Plan/src/main/java/com/djrapitops/plan/system/database/{BukkitDBSystem.java => ServerDBSystem.java} (94%) rename Plan/src/main/java/com/djrapitops/plan/system/info/{BukkitInfoSystem.java => ServerInfoSystem.java} (87%) rename Plan/src/main/java/com/djrapitops/plan/system/info/connection/{BukkitConnectionSystem.java => ServerConnectionSystem.java} (98%) rename Plan/src/main/java/com/djrapitops/plan/system/settings/config/{BukkitConfigSystem.java => ServerConfigSystem.java} (91%) create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/settings/config/SpongeConfigSystem.java diff --git a/Plan/src/main/java/com/djrapitops/plan/system/BukkitSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/BukkitSystem.java index 63019c76c..dc22a04e3 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/BukkitSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/BukkitSystem.java @@ -9,13 +9,13 @@ import com.djrapitops.plan.ShutdownHook; import com.djrapitops.plan.api.ServerAPI; import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.data.plugin.HookHandler; -import com.djrapitops.plan.system.database.BukkitDBSystem; +import com.djrapitops.plan.system.database.ServerDBSystem; import com.djrapitops.plan.system.file.FileSystem; -import com.djrapitops.plan.system.info.BukkitInfoSystem; +import com.djrapitops.plan.system.info.ServerInfoSystem; import com.djrapitops.plan.system.info.server.BukkitServerInfo; import com.djrapitops.plan.system.listeners.BukkitListenerSystem; import com.djrapitops.plan.system.settings.PlanErrorManager; -import com.djrapitops.plan.system.settings.config.BukkitConfigSystem; +import com.djrapitops.plan.system.settings.config.ServerConfigSystem; import com.djrapitops.plan.system.settings.network.NetworkSettings; import com.djrapitops.plan.system.tasks.BukkitTaskSystem; import com.djrapitops.plan.system.update.VersionCheckSystem; @@ -37,12 +37,12 @@ public class BukkitSystem extends PlanSystem implements ServerSystem { versionCheckSystem = new VersionCheckSystem(plugin.getVersion()); fileSystem = new FileSystem(plugin); - configSystem = new BukkitConfigSystem(); - databaseSystem = new BukkitDBSystem(); + configSystem = new ServerConfigSystem(); + databaseSystem = new ServerDBSystem(); listenerSystem = new BukkitListenerSystem(plugin); taskSystem = new BukkitTaskSystem(plugin); - infoSystem = new BukkitInfoSystem(); + infoSystem = new ServerInfoSystem(); serverInfo = new BukkitServerInfo(plugin); hookHandler = new HookHandler(); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java index ac3003e0d..7bfb57173 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java @@ -9,13 +9,13 @@ import com.djrapitops.plan.ShutdownHook; import com.djrapitops.plan.api.ServerAPI; import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.data.plugin.HookHandler; -import com.djrapitops.plan.system.database.BukkitDBSystem; +import com.djrapitops.plan.system.database.ServerDBSystem; import com.djrapitops.plan.system.file.FileSystem; -import com.djrapitops.plan.system.info.BukkitInfoSystem; +import com.djrapitops.plan.system.info.ServerInfoSystem; import com.djrapitops.plan.system.info.server.SpongeServerInfo; import com.djrapitops.plan.system.listeners.SpongeListenerSystem; import com.djrapitops.plan.system.settings.PlanErrorManager; -import com.djrapitops.plan.system.settings.config.BukkitConfigSystem; +import com.djrapitops.plan.system.settings.config.SpongeConfigSystem; import com.djrapitops.plan.system.settings.network.NetworkSettings; import com.djrapitops.plan.system.tasks.SpongeTaskSystem; import com.djrapitops.plan.system.update.VersionCheckSystem; @@ -29,6 +29,8 @@ import com.djrapitops.plugin.api.utility.log.Log; */ public class SpongeSystem extends PlanSystem implements ServerSystem { + private boolean firstInstall = false; + public SpongeSystem(PlanSponge plugin) { testSystem = this; @@ -36,12 +38,12 @@ public class SpongeSystem extends PlanSystem implements ServerSystem { versionCheckSystem = new VersionCheckSystem(plugin.getVersion()); fileSystem = new FileSystem(plugin); - configSystem = new BukkitConfigSystem(); - databaseSystem = new BukkitDBSystem(); + configSystem = new SpongeConfigSystem(); + databaseSystem = new ServerDBSystem(); listenerSystem = new SpongeListenerSystem(plugin); taskSystem = new SpongeTaskSystem(plugin); - infoSystem = new BukkitInfoSystem(); + infoSystem = new ServerInfoSystem(); serverInfo = new SpongeServerInfo(); hookHandler = new HookHandler(); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/BukkitDBSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/database/ServerDBSystem.java similarity index 94% rename from Plan/src/main/java/com/djrapitops/plan/system/database/BukkitDBSystem.java rename to Plan/src/main/java/com/djrapitops/plan/system/database/ServerDBSystem.java index 50837dc6e..9b323eb2c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/BukkitDBSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/ServerDBSystem.java @@ -14,7 +14,7 @@ import com.djrapitops.plan.system.settings.Settings; * * @author Rsl1122 */ -public class BukkitDBSystem extends DBSystem { +public class ServerDBSystem extends DBSystem { @Override protected void initDatabase() throws DBInitException { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/BukkitInfoSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/info/ServerInfoSystem.java similarity index 87% rename from Plan/src/main/java/com/djrapitops/plan/system/info/BukkitInfoSystem.java rename to Plan/src/main/java/com/djrapitops/plan/system/info/ServerInfoSystem.java index 3bb0b4b85..8501140ff 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/BukkitInfoSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/ServerInfoSystem.java @@ -6,7 +6,7 @@ package com.djrapitops.plan.system.info; import com.djrapitops.plan.api.exceptions.connection.NoServersException; import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.info.connection.BukkitConnectionSystem; +import com.djrapitops.plan.system.info.connection.ServerConnectionSystem; import com.djrapitops.plan.system.info.request.CacheNetworkPageContentRequest; import com.djrapitops.plan.system.info.request.InfoRequest; import com.djrapitops.plan.system.info.request.SetupRequest; @@ -19,10 +19,10 @@ import com.djrapitops.plugin.api.utility.log.Log; * * @author Rsl1122 */ -public class BukkitInfoSystem extends InfoSystem { +public class ServerInfoSystem extends InfoSystem { - public BukkitInfoSystem() { - super(new BukkitConnectionSystem()); + public ServerInfoSystem() { + super(new ServerConnectionSystem()); } @Override diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/BukkitConnectionSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ServerConnectionSystem.java similarity index 98% rename from Plan/src/main/java/com/djrapitops/plan/system/info/connection/BukkitConnectionSystem.java rename to Plan/src/main/java/com/djrapitops/plan/system/info/connection/ServerConnectionSystem.java index 582572595..c0f5c71bd 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/BukkitConnectionSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ServerConnectionSystem.java @@ -28,13 +28,13 @@ import java.util.UUID; * * @author Rsl1122 */ -public class BukkitConnectionSystem extends ConnectionSystem { +public class ServerConnectionSystem extends ConnectionSystem { private long latestServerMapRefresh; private Server mainServer; - public BukkitConnectionSystem() { + public ServerConnectionSystem() { latestServerMapRefresh = 0; } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java index bee0bf5bc..63a8f01d7 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java @@ -36,6 +36,7 @@ public enum Settings { FORMAT_DATE_RECENT_DAYS("Customization.Formatting.Dates.RecentDays"), DISPLAY_PLAYER_IPS("Customization.Display.PlayerIPs"), DISPLAY_GAPS_IN_GRAPH_DATA("Customization.Display.GapsInGraphData"), + DATA_GEOLOCATIONS("Data.Geolocations"), // Integer WEBSERVER_PORT("WebServer.Port"), diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/config/BukkitConfigSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/ServerConfigSystem.java similarity index 91% rename from Plan/src/main/java/com/djrapitops/plan/system/settings/config/BukkitConfigSystem.java rename to Plan/src/main/java/com/djrapitops/plan/system/settings/config/ServerConfigSystem.java index c9d9f6849..7d3e56339 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/config/BukkitConfigSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/ServerConfigSystem.java @@ -15,7 +15,7 @@ import java.io.IOException; * * @author Rsl1122 */ -public class BukkitConfigSystem extends ConfigSystem { +public class ServerConfigSystem extends ConfigSystem { @Override protected void copyDefaults() throws IOException { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/config/SpongeConfigSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/SpongeConfigSystem.java new file mode 100644 index 000000000..5d88d7fe0 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/SpongeConfigSystem.java @@ -0,0 +1,35 @@ +package com.djrapitops.plan.system.settings.config; + +import com.djrapitops.plan.api.exceptions.EnableException; +import com.djrapitops.plan.system.file.FileSystem; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plugin.api.utility.log.Log; + +import java.io.IOException; + +/** + * Sponge ConfigSystem that disables WebServer and Geolocations on first enable. + * + * @author Rsl1122 + */ +public class SpongeConfigSystem extends ServerConfigSystem { + + private boolean firstInstall; + + @Override + public void enable() throws EnableException { + firstInstall = !FileSystem.getConfigFile().exists(); + super.enable(); + } + + @Override + protected void copyDefaults() throws IOException { + super.copyDefaults(); + if (firstInstall) { + Log.info("WebServer and Geolocations disabled by default. Please enable them in the config."); + Settings.WEBSERVER_DISABLED.set(true); + Settings.DATA_GEOLOCATIONS.set(false); + Settings.save(); + } + } +} \ No newline at end of file diff --git a/Plan/src/test/java/com/djrapitops/plan/system/BungeeBukkitConnectionTest.java b/Plan/src/test/java/com/djrapitops/plan/system/BungeeBukkitConnectionTest.java index a7ed9e625..72de62411 100644 --- a/Plan/src/test/java/com/djrapitops/plan/system/BungeeBukkitConnectionTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/system/BungeeBukkitConnectionTest.java @@ -8,7 +8,7 @@ import com.djrapitops.plan.Plan; import com.djrapitops.plan.PlanBungee; import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.database.BukkitDBSystem; +import com.djrapitops.plan.system.database.ServerDBSystem; import com.djrapitops.plan.system.info.request.GenerateInspectPageRequest; import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.settings.Settings; @@ -97,7 +97,7 @@ public class BungeeBukkitConnectionTest { Settings.WEBSERVER_PORT.setTemporaryValue(9250); Settings.BUNGEE_IP.setTemporaryValue("localhost"); Settings.DB_TYPE.setTemporaryValue("sqlite"); - bungeeSystem.setDatabaseSystem(new BukkitDBSystem()); + bungeeSystem.setDatabaseSystem(new ServerDBSystem()); bungeeSystem.enable(); diff --git a/Plan/src/test/java/com/djrapitops/plan/system/BungeeSystemTest.java b/Plan/src/test/java/com/djrapitops/plan/system/BungeeSystemTest.java index fad9d8338..8a2e169c0 100644 --- a/Plan/src/test/java/com/djrapitops/plan/system/BungeeSystemTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/system/BungeeSystemTest.java @@ -6,7 +6,7 @@ package com.djrapitops.plan.system; import com.djrapitops.plan.PlanBungee; import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.database.BukkitDBSystem; +import com.djrapitops.plan.system.database.ServerDBSystem; import com.djrapitops.plan.system.settings.Settings; import org.junit.*; import org.junit.rules.ExpectedException; @@ -63,7 +63,7 @@ public class BungeeSystemTest { Settings.WEBSERVER_PORT.setTemporaryValue(9005); Settings.BUNGEE_IP.setTemporaryValue("8.8.8.8"); Settings.DB_TYPE.setTemporaryValue("sqlite"); - bungeeSystem.setDatabaseSystem(new BukkitDBSystem()); + bungeeSystem.setDatabaseSystem(new ServerDBSystem()); bungeeSystem.enable(); } @@ -77,7 +77,7 @@ public class BungeeSystemTest { Settings.WEBSERVER_PORT.setTemporaryValue(9005); Settings.DB_TYPE.setTemporaryValue("sqlite"); - bungeeSystem.setDatabaseSystem(new BukkitDBSystem()); + bungeeSystem.setDatabaseSystem(new ServerDBSystem()); bungeeSystem.enable(); } From 2b6564bb32ee59cffd82a62cfed20437b2b829e3 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Wed, 11 Apr 2018 19:36:50 +0300 Subject: [PATCH 10/33] Disabled geolocations by default on Sponge --- .../plan/system/cache/GeolocationCache.java | 16 ++++++++++------ .../processors/player/IPUpdateProcessor.java | 14 +++++++++----- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/system/cache/GeolocationCache.java b/Plan/src/main/java/com/djrapitops/plan/system/cache/GeolocationCache.java index 353083fac..d0825e32d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/cache/GeolocationCache.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/cache/GeolocationCache.java @@ -3,6 +3,8 @@ package com.djrapitops.plan.system.cache; import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.system.SubSystem; import com.djrapitops.plan.system.file.FileSystem; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plugin.api.Check; import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.utilities.Verify; import com.google.common.cache.Cache; @@ -45,12 +47,14 @@ public class GeolocationCache implements SubSystem { @Override public void enable() throws EnableException { geolocationDB = new File(FileSystem.getDataFolder(), "GeoIP.dat"); - try { - GeolocationCache.checkDB(); - } catch (UnknownHostException e) { - Log.error("Plan Requires internet access on first run to download GeoLite2 Geolocation database."); - } catch (IOException e) { - throw new EnableException("Something went wrong saving the downloaded GeoLite2 Geolocation database", e); + if (!Check.isSpongeAvailable() || Settings.DATA_GEOLOCATIONS.isTrue()) { + try { + GeolocationCache.checkDB(); + } catch (UnknownHostException e) { + Log.error("Plan Requires internet access on first run to download GeoLite2 Geolocation database."); + } catch (IOException e) { + throw new EnableException("Something went wrong saving the downloaded GeoLite2 Geolocation database", e); + } } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/IPUpdateProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/IPUpdateProcessor.java index 759695e73..420c03243 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/IPUpdateProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/IPUpdateProcessor.java @@ -9,6 +9,8 @@ import com.djrapitops.plan.data.container.GeoInfo; import com.djrapitops.plan.system.cache.GeolocationCache; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.processing.CriticalRunnable; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plugin.api.Check; import com.djrapitops.plugin.api.utility.log.Log; import java.util.UUID; @@ -32,11 +34,13 @@ public class IPUpdateProcessor implements CriticalRunnable { @Override public void run() { - String country = GeolocationCache.getCountry(ip); - try { - Database.getActive().save().geoInfo(uuid, new GeoInfo(ip, country, time)); - } catch (DBException e) { - Log.toLog(this.getClass(), e); + if (!Check.isSpongeAvailable() || Settings.DATA_GEOLOCATIONS.isTrue()) { + String country = GeolocationCache.getCountry(ip); + try { + Database.getActive().save().geoInfo(uuid, new GeoInfo(ip, country, time)); + } catch (DBException e) { + Log.toLog(this.getClass(), e); + } } } } \ No newline at end of file From 41cce35f9a2f94bf25fc25f9b5369034dd16d683 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Fri, 13 Apr 2018 08:43:03 +0300 Subject: [PATCH 11/33] Removed debug messages from sponge kill processor --- .../processors/player/SpongeKillProcessor.java | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/SpongeKillProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/SpongeKillProcessor.java index dbc95a61a..c737e6aa6 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/SpongeKillProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/SpongeKillProcessor.java @@ -29,7 +29,7 @@ public class SpongeKillProcessor implements CriticalRunnable { * * @param uuid UUID of the killer. * @param time Epoch ms the event occurred. - * @param deadUUID Dead entity (Mob or Player) + * @param deadUUID Dead entity (Mob or Player) * @param weaponName Weapon used. */ public SpongeKillProcessor(UUID uuid, long time, UUID deadUUID, String weaponName) { @@ -42,24 +42,15 @@ public class SpongeKillProcessor implements CriticalRunnable { @Override public void run() { Optional cachedSession = SessionCache.getCachedSession(uuid); - System.out.println("*"); if (!cachedSession.isPresent()) { - System.out.println("No session"); return; } - System.out.println("**"); Session session = cachedSession.get(); - System.out.println("***"); if (deadUUID != null) { - System.out.println("Dead player"); - session.playerKilled(new PlayerKill(deadUUID, weaponName, time)); } else { - System.out.println("Dead mob"); - session.mobKilled(); } - System.out.println("****"); } } From f1024f67c04fb35d8af017b2b1007481b024e02b Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Fri, 13 Apr 2018 08:43:33 +0300 Subject: [PATCH 12/33] Relocated apache packages, Replaced deprecated StrSubstitutor --- Plan/pom.xml | 11 ++++++++--- .../main/java/com/djrapitops/plan/data/Actions.java | 2 +- .../system/info/request/CacheInspectPageRequest.java | 4 ++-- .../system/settings/config/SpongeConfigSystem.java | 4 +++- .../plan/system/settings/locale/Message.java | 4 ++-- .../system/webserver/response/JavaScriptResponse.java | 4 ++-- .../webserver/response/errors/ErrorResponse.java | 4 ++-- .../webserver/response/pages/InspectPageResponse.java | 4 ++-- .../webserver/response/pages/PlayersPageResponse.java | 4 ++-- .../java/com/djrapitops/plan/utilities/html/Html.java | 4 ++-- .../com/djrapitops/plan/utilities/html/HtmlUtils.java | 4 ++-- 11 files changed, 28 insertions(+), 21 deletions(-) diff --git a/Plan/pom.xml b/Plan/pom.xml index 1bf81cf38..1fcc381f8 100644 --- a/Plan/pom.xml +++ b/Plan/pom.xml @@ -74,11 +74,10 @@ jar provided - org.apache.commons - commons-lang3 - 3.6 + commons-text + 1.3 @@ -192,6 +191,12 @@ junit:* + + + org.apache + plan.org.apache + + diff --git a/Plan/src/main/java/com/djrapitops/plan/data/Actions.java b/Plan/src/main/java/com/djrapitops/plan/data/Actions.java index f7784fe22..d9f7a5a9e 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/Actions.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/Actions.java @@ -4,7 +4,7 @@ */ package com.djrapitops.plan.data; -import org.apache.commons.lang3.text.WordUtils; +import org.apache.commons.text.WordUtils; /** * IDs of various actions diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPageRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPageRequest.java index e1855733f..c1aaba26f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPageRequest.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPageRequest.java @@ -17,7 +17,7 @@ import com.djrapitops.plan.system.webserver.response.pages.InspectPageResponse; import com.djrapitops.plan.utilities.Base64Util; import com.djrapitops.plan.utilities.file.export.HtmlExport; import com.djrapitops.plugin.utilities.Verify; -import org.apache.commons.lang3.text.StrSubstitutor; +import org.apache.commons.text.StringSubstitutor; import java.util.Collections; import java.util.Map; @@ -63,7 +63,7 @@ public class CacheInspectPageRequest extends InfoRequestWithVariables implements Map replace = Collections.singletonMap("networkName", ServerInfo.getServerName()); boolean export = Settings.ANALYSIS_EXPORT.isTrue(); - cache(export, uuid, StrSubstitutor.replace(Base64Util.decode(html), replace)); + cache(export, uuid, StringSubstitutor.replace(Base64Util.decode(html), replace)); return DefaultResponses.SUCCESS.get(); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/config/SpongeConfigSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/SpongeConfigSystem.java index 5d88d7fe0..477a57ab7 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/config/SpongeConfigSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/SpongeConfigSystem.java @@ -26,7 +26,9 @@ public class SpongeConfigSystem extends ServerConfigSystem { protected void copyDefaults() throws IOException { super.copyDefaults(); if (firstInstall) { - Log.info("WebServer and Geolocations disabled by default. Please enable them in the config."); + Log.info("§eWebServer and Geolocations disabled by default on Sponge servers. You can enable them in the config:"); + Log.info("§e " + Settings.WEBSERVER_DISABLED.getPath()); + Log.info("§e " + Settings.DATA_GEOLOCATIONS.getPath()); Settings.WEBSERVER_DISABLED.set(true); Settings.DATA_GEOLOCATIONS.set(false); Settings.save(); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/locale/Message.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/locale/Message.java index 563ebfe6e..957b19aca 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/locale/Message.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/locale/Message.java @@ -1,7 +1,7 @@ package com.djrapitops.plan.system.settings.locale; import com.djrapitops.plugin.utilities.Verify; -import org.apache.commons.lang3.text.StrSubstitutor; +import org.apache.commons.text.StringSubstitutor; import java.io.Serializable; import java.util.HashMap; @@ -30,7 +30,7 @@ public class Message { replaceMap.put(String.valueOf(i), p[i].toString()); } - StrSubstitutor sub = new StrSubstitutor(replaceMap); + StringSubstitutor sub = new StringSubstitutor(replaceMap); return sub.replace(content); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/JavaScriptResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/JavaScriptResponse.java index 884df375a..bcfba7697 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/JavaScriptResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/JavaScriptResponse.java @@ -2,7 +2,7 @@ package com.djrapitops.plan.system.webserver.response; import com.djrapitops.plan.system.settings.theme.Theme; import com.djrapitops.plan.system.settings.theme.ThemeVal; -import org.apache.commons.lang3.text.StrSubstitutor; +import org.apache.commons.text.StringSubstitutor; import java.util.HashMap; import java.util.Map; @@ -18,6 +18,6 @@ public class JavaScriptResponse extends FileResponse { super.setType(ResponseType.JAVASCRIPT); Map replace = new HashMap<>(); replace.put("defaultTheme", Theme.getValue(ThemeVal.THEME_DEFAULT)); - setContent(StrSubstitutor.replace(Theme.replaceColors(getContent()), replace)); + setContent(StringSubstitutor.replace(Theme.replaceColors(getContent()), replace)); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ErrorResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ErrorResponse.java index 26a50d66f..db2e8cad7 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ErrorResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ErrorResponse.java @@ -9,7 +9,7 @@ import com.djrapitops.plan.system.webserver.response.Response; import com.djrapitops.plan.utilities.MiscUtils; import com.djrapitops.plan.utilities.file.FileUtil; import com.djrapitops.plugin.api.utility.log.Log; -import org.apache.commons.lang3.text.StrSubstitutor; +import org.apache.commons.text.StringSubstitutor; import java.io.IOException; import java.util.HashMap; @@ -41,7 +41,7 @@ public class ErrorResponse extends Response { placeHolders.put("paragraph", paragraph); placeHolders.put("version", MiscUtils.getPlanVersion()); - setContent(StrSubstitutor.replace(getContent(), placeHolders)); + setContent(StringSubstitutor.replace(getContent(), placeHolders)); } public void setTitle(String title) { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/InspectPageResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/InspectPageResponse.java index a072ee71c..3735fe690 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/InspectPageResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/InspectPageResponse.java @@ -6,7 +6,7 @@ import com.djrapitops.plan.system.webserver.response.cache.PageId; import com.djrapitops.plan.system.webserver.response.cache.ResponseCache; import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse; import com.djrapitops.plan.system.webserver.response.pages.parts.InspectPagePluginsContent; -import org.apache.commons.lang3.text.StrSubstitutor; +import org.apache.commons.text.StringSubstitutor; import java.util.HashMap; import java.util.Map; @@ -35,7 +35,7 @@ public class InspectPageResponse extends Response { replaceMap.put("navPluginsTabs", inspectPagePluginsTab[0]); replaceMap.put("pluginsTabs", inspectPagePluginsTab[1]); - return StrSubstitutor.replace(super.getContent(), replaceMap); + return StringSubstitutor.replace(super.getContent(), replaceMap); } private String[] getCalculating() { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/PlayersPageResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/PlayersPageResponse.java index ace6d0bfc..5afde7d68 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/PlayersPageResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/PlayersPageResponse.java @@ -20,7 +20,7 @@ import com.djrapitops.plan.utilities.file.FileUtil; import com.djrapitops.plan.utilities.html.Html; import com.djrapitops.plugin.api.Check; import com.djrapitops.plugin.api.utility.log.Log; -import org.apache.commons.lang3.text.StrSubstitutor; +import org.apache.commons.text.StringSubstitutor; import java.io.IOException; import java.util.*; @@ -47,7 +47,7 @@ public class PlayersPageResponse extends Response { } replace.put("playersTable", buildPlayersTable(db)); replace.put("version", plugin.getVersion()); - super.setContent(Theme.replaceColors(StrSubstitutor.replace(FileUtil.getStringFromResource("web/players.html"), replace))); + super.setContent(Theme.replaceColors(StringSubstitutor.replace(FileUtil.getStringFromResource("web/players.html"), replace))); } catch (DBException | IOException e) { Log.toLog(this.getClass(), e); setContent(new InternalErrorResponse("/players", e).getContent()); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/Html.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/Html.java index 885a80d85..8873663fa 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/Html.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/Html.java @@ -1,6 +1,6 @@ package com.djrapitops.plan.utilities.html; -import org.apache.commons.lang3.text.StrSubstitutor; +import org.apache.commons.text.StringSubstitutor; import java.io.Serializable; import java.util.HashMap; @@ -131,7 +131,7 @@ public enum Html { replaceMap.put(String.valueOf(i), p[i]); } - StrSubstitutor sub = new StrSubstitutor(replaceMap); + StringSubstitutor sub = new StringSubstitutor(replaceMap); sub.setEnableSubstitutionInVariables(false); return sub.replace(html); } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlUtils.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlUtils.java index 9112bef4a..53358ed0d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlUtils.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlUtils.java @@ -2,7 +2,7 @@ package com.djrapitops.plan.utilities.html; import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.settings.Settings; -import org.apache.commons.lang3.text.StrSubstitutor; +import org.apache.commons.text.StringSubstitutor; import java.io.Serializable; import java.util.Map; @@ -27,7 +27,7 @@ public class HtmlUtils { * @return Html with placeholders replaced */ public static String replacePlaceholders(String html, Map replaceMap) { - StrSubstitutor sub = new StrSubstitutor(replaceMap); + StringSubstitutor sub = new StringSubstitutor(replaceMap); sub.setEnableSubstitutionInVariables(true); return sub.replace(html); } From 3c81926ef8be27feee6578265f82b1efef52d525 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Fri, 13 Apr 2018 10:30:57 +0300 Subject: [PATCH 13/33] Fixed some sponge issues --- Plan/dependency-reduced-pom.xml | 11 ++++++++++- Plan/pom.xml | 5 ++++- .../commands/manage/ManageConDebugCommand.java | 4 ++++ .../com/djrapitops/plan/system/database/DBSystem.java | 3 ++- .../system/info/request/SaveDBSettingsRequest.java | 4 ++-- 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/Plan/dependency-reduced-pom.xml b/Plan/dependency-reduced-pom.xml index 2a9978de3..b52e8a198 100644 --- a/Plan/dependency-reduced-pom.xml +++ b/Plan/dependency-reduced-pom.xml @@ -62,6 +62,15 @@ junit:* + + + org.apache + plan.org.apache + + org.apache.logging.* + + + @@ -260,7 +269,7 @@ org.spongepowered spongeapi - 7.0.0 + LATEST provided diff --git a/Plan/pom.xml b/Plan/pom.xml index 1fcc381f8..ca2b23d6a 100644 --- a/Plan/pom.xml +++ b/Plan/pom.xml @@ -70,7 +70,7 @@ org.spongepowered spongeapi - 7.0.0 + LATEST jar provided @@ -195,6 +195,9 @@ org.apache plan.org.apache + + org.apache.logging.* + diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java index 07036d91a..9a8f8055e 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java @@ -50,6 +50,10 @@ public class ManageConDebugCommand extends CommandNode { try { List servers = Database.getActive().fetch().getServers(); + if (servers.isEmpty()) { + sender.sendMessage("§cNo Servers found in the database."); + } + String accessAddress = WebServerSystem.getInstance().getWebServer().getAccessAddress(); UUID thisServer = ServerInfo.getServerUUID(); for (Server server : servers) { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/DBSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/database/DBSystem.java index 54cbd3472..73393e5ec 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/DBSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/DBSystem.java @@ -50,7 +50,8 @@ public abstract class DBSystem implements SubSystem { Benchmark.stop("Enable", "Init Database"); } catch (DBInitException e) { Throwable cause = e.getCause(); - throw new EnableException(db.getName() + " init failure: " + cause.getMessage(), cause); + String message = cause == null ? e.getMessage() : cause.getMessage(); + throw new EnableException((db != null ? db.getName() : "Database") + " init failure: " + message, cause); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/SaveDBSettingsRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/SaveDBSettingsRequest.java index 63a64136c..a5522ab18 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/request/SaveDBSettingsRequest.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/SaveDBSettingsRequest.java @@ -4,7 +4,7 @@ */ package com.djrapitops.plan.system.info.request; -import com.djrapitops.plan.Plan; +import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.connection.BadRequestException; import com.djrapitops.plan.api.exceptions.connection.WebException; import com.djrapitops.plan.system.settings.Settings; @@ -64,7 +64,7 @@ public class SaveDBSettingsRequest extends InfoRequestWithVariables implements S Log.info("----------------------------------"); return DefaultResponses.SUCCESS.get(); } finally { - Plan.getInstance().reloadPlugin(true); + PlanPlugin.getInstance().reloadPlugin(true); } } From c67d57e5e9e518501b2da54efbc5e8c2de82abdf Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Fri, 13 Apr 2018 22:47:25 +0300 Subject: [PATCH 14/33] Implemented MySQL for Sponge #564 --- .../plan/system/database/ServerDBSystem.java | 4 +- .../database/databases/sql/MySQLDB.java | 13 +++-- .../database/databases/sql/SpongeMySQLDB.java | 47 +++++++++++++++++++ 3 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SpongeMySQLDB.java diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/ServerDBSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/database/ServerDBSystem.java index 9b323eb2c..c17ec6e63 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/ServerDBSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/ServerDBSystem.java @@ -7,7 +7,9 @@ package com.djrapitops.plan.system.database; import com.djrapitops.plan.api.exceptions.database.DBInitException; import com.djrapitops.plan.system.database.databases.sql.MySQLDB; import com.djrapitops.plan.system.database.databases.sql.SQLiteDB; +import com.djrapitops.plan.system.database.databases.sql.SpongeMySQLDB; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plugin.api.Check; /** * Bukkit Database system that initializes SQLite and MySQL database objects. @@ -18,7 +20,7 @@ public class ServerDBSystem extends DBSystem { @Override protected void initDatabase() throws DBInitException { - databases.add(new MySQLDB()); + databases.add(Check.isSpongeAvailable() ? new SpongeMySQLDB() : new MySQLDB()); databases.add(new SQLiteDB()); String dbType = Settings.DB_TYPE.toString().toLowerCase().trim(); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/MySQLDB.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/MySQLDB.java index 34cf4fed0..01f8321d2 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/MySQLDB.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/MySQLDB.java @@ -1,9 +1,11 @@ package com.djrapitops.plan.system.database.databases.sql; +import com.djrapitops.plan.api.exceptions.database.DBInitException; import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plugin.api.utility.log.Log; import org.apache.commons.dbcp2.BasicDataSource; +import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException; @@ -12,7 +14,7 @@ import java.sql.SQLException; */ public class MySQLDB extends SQLDB { - private BasicDataSource dataSource; + protected DataSource dataSource; public MySQLDB() { } @@ -21,8 +23,9 @@ public class MySQLDB extends SQLDB { * Setups the {@link BasicDataSource} */ @Override - public void setupDataSource() { - dataSource = new BasicDataSource(); + public void setupDataSource() throws DBInitException { + BasicDataSource dataSource = new BasicDataSource(); + this.dataSource = dataSource; dataSource.setDriverClassName("com.mysql.jdbc.Driver"); String host = Settings.DB_HOST.toString(); @@ -62,7 +65,9 @@ public class MySQLDB extends SQLDB { @Override public void close() { try { - dataSource.close(); + if (dataSource != null && dataSource instanceof BasicDataSource) { + ((BasicDataSource) dataSource).close(); + } } catch (SQLException e) { Log.toLog(this.getClass(), e); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SpongeMySQLDB.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SpongeMySQLDB.java new file mode 100644 index 000000000..a066005ca --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SpongeMySQLDB.java @@ -0,0 +1,47 @@ +package com.djrapitops.plan.system.database.databases.sql; + +import com.djrapitops.plan.api.exceptions.database.DBInitException; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plugin.api.utility.log.Log; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.service.sql.SqlService; + +import java.sql.SQLException; +import java.util.Optional; + +/** + * MySQLDB implementation for Sponge since default driver is not available. + * + * @author Rsl1122 + */ +public class SpongeMySQLDB extends MySQLDB { + + @Override + public void setupDataSource() throws DBInitException { + Optional sqlServiceProvider = Sponge.getServiceManager().provide(SqlService.class); + if (!sqlServiceProvider.isPresent()) { + return; + } + + String host = Settings.DB_HOST.toString(); + String port = Integer.toString(Settings.DB_PORT.getNumber()); + String database = Settings.DB_DATABASE.toString(); + String launchOptions = Settings.DB_LAUNCH_OPTIONS.toString(); + if (launchOptions.isEmpty() || !launchOptions.startsWith("?") || launchOptions.endsWith("&")) { + Log.error("Launch Options were faulty, using default (?rewriteBatchedStatements=true&useSSL=false)"); + launchOptions = "?rewriteBatchedStatements=true&useSSL=false"; + } + + String url = host + ":" + port + "/" + database + launchOptions; + String username = Settings.DB_USER.toString(); + String password = Settings.DB_PASS.toString(); + try { + this.dataSource = sqlServiceProvider.get().getDataSource( + "jdbc:mysql://" + username + ":" + password + "@" + url + ); + } catch (SQLException e) { + throw new DBInitException(e); + } + } + +} \ No newline at end of file From 01431cf4aa6279d4fe95c16364724ae9159e79d0 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Fri, 13 Apr 2018 22:49:23 +0300 Subject: [PATCH 15/33] Fixed locales not being in the jar #561 --- Plan/dependency-reduced-pom.xml | 1 + Plan/pom.xml | 1 + .../java/com/djrapitops/plan/system/settings/locale/Locale.java | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Plan/dependency-reduced-pom.xml b/Plan/dependency-reduced-pom.xml index b52e8a198..445b1158f 100644 --- a/Plan/dependency-reduced-pom.xml +++ b/Plan/dependency-reduced-pom.xml @@ -19,6 +19,7 @@ **/*.html **/*.js **/*.css + locale/*.txt licence.yml diff --git a/Plan/pom.xml b/Plan/pom.xml index ca2b23d6a..39ee621d4 100644 --- a/Plan/pom.xml +++ b/Plan/pom.xml @@ -148,6 +148,7 @@ **/*.html **/*.js **/*.css + locale/*.txt licence.yml diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/locale/Locale.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/locale/Locale.java index 8399c78b5..408b48710 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/locale/Locale.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/locale/Locale.java @@ -71,7 +71,7 @@ public class Locale { } else if (locale.equals("DEFAULT")) { Log.info("Using Locale: Default (EN)"); } else { - loadFromResource("locale_" + locale + ".txt"); + loadFromResource("locale/locale_" + locale + ".txt"); } } catch (IOException e) { Log.toLog(this.getClass(), e); From 23a3fc441b2ee6b35ad155ea7efb2aef53f95170 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Fri, 13 Apr 2018 23:02:11 +0300 Subject: [PATCH 16/33] Sponge version bump to 4.2.1 --- Plan/dependency-reduced-pom.xml | 22 +++++++++---------- .../java/com/djrapitops/plan/PlanSponge.java | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Plan/dependency-reduced-pom.xml b/Plan/dependency-reduced-pom.xml index 445b1158f..30e597272 100644 --- a/Plan/dependency-reduced-pom.xml +++ b/Plan/dependency-reduced-pom.xml @@ -19,7 +19,7 @@ **/*.html **/*.js **/*.css - locale/*.txt + locale/*.txt licence.yml @@ -63,15 +63,15 @@ junit:* - - - org.apache - plan.org.apache - - org.apache.logging.* - - - + + + org.apache + plan.org.apache + + org.apache.logging.* + + + @@ -270,7 +270,7 @@ org.spongepowered spongeapi - LATEST + LATEST provided diff --git a/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java b/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java index 855f7c39d..d9ff71cda 100644 --- a/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java +++ b/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java @@ -23,7 +23,7 @@ import org.spongepowered.api.plugin.Plugin; import java.io.File; import java.io.InputStream; -@Plugin(id = "plan", name = "Plan", version = "4.2.0", description = "Player Analytics Plugin by Rsl1122", authors = {"Rsl1122"}) +@Plugin(id = "plan", name = "Plan", version = "4.2.1", description = "Player Analytics Plugin by Rsl1122", authors = {"Rsl1122"}) public class PlanSponge extends SpongePlugin implements PlanPlugin { @Inject @@ -114,7 +114,7 @@ public class PlanSponge extends SpongePlugin implements PlanPlugin { @Override public String getVersion() { - return "4.2.0"; + return "4.2.1"; } public SpongeSystem getSystem() { From 4e0f1b38f1ef45fa637657ece4d40f1a9fc59159 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Sat, 14 Apr 2018 11:18:30 +0300 Subject: [PATCH 17/33] Update command #539 --- .../plan/command/PlanBungeeCommand.java | 2 + .../djrapitops/plan/command/PlanCommand.java | 3 +- .../plan/command/commands/UpdateCommand.java | 210 ++++++++++++++++++ .../manage/ManageConDebugCommand.java | 14 +- .../info/connection/ConnectionSystem.java | 3 + .../info/request/UpdateCancelRequest.java | 37 +++ .../system/info/request/UpdateRequest.java | 43 ++++ .../plan/system/settings/Settings.java | 2 + .../system/update/ShutdownUpdateHook.java | 104 +++++++++ .../system/update/VersionCheckSystem.java | 36 ++- .../plan/system/update/VersionInfo.java | 63 ++++++ .../plan/system/update/VersionInfoLoader.java | 57 +++++ Plan/src/main/resources/bungee.yml | 2 +- Plan/src/main/resources/bungeeconfig.yml | 2 + Plan/src/main/resources/config.yml | 2 + Plan/src/main/resources/plugin.yml | 2 +- .../system/update/VersionInfoLoaderTest.java | 24 ++ 17 files changed, 592 insertions(+), 14 deletions(-) create mode 100644 Plan/src/main/java/com/djrapitops/plan/command/commands/UpdateCommand.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/info/request/UpdateCancelRequest.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/info/request/UpdateRequest.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/update/ShutdownUpdateHook.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/update/VersionInfo.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/update/VersionInfoLoader.java create mode 100644 Plan/src/test/java/com/djrapitops/plan/system/update/VersionInfoLoaderTest.java diff --git a/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java index 2636189cf..8472f44da 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java @@ -4,6 +4,7 @@ import com.djrapitops.plan.PlanBungee; import com.djrapitops.plan.command.commands.*; import com.djrapitops.plan.command.commands.manage.ManageConDebugCommand; import com.djrapitops.plan.system.settings.Permissions; +import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plugin.command.CommandNode; @@ -49,6 +50,7 @@ public class PlanBungeeCommand extends TreeCmdNode { new BungeeSetupToggleCommand(), new ReloadCommand(plugin), new StatusCommand<>(plugin, Permissions.MANAGE.getPermission(), plugin.getColorScheme()), + (Settings.ALLOW_UPDATE.isTrue() ? new UpdateCommand() : null) } ); } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java index 68ce5d31e..6b2ca3f1c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java @@ -46,7 +46,8 @@ public class PlanCommand extends TreeCmdNode { new ReloadCommand(plugin), new ManageCommand(plugin, this), new StatusCommand<>(plugin, Permissions.MANAGE.getPermission(), plugin.getColorScheme()), - (Settings.DEV_MODE.isTrue() ? new DevCommand() : null) + (Settings.DEV_MODE.isTrue() ? new DevCommand() : null), + (Settings.ALLOW_UPDATE.isTrue() ? new UpdateCommand() : null) } ); } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/UpdateCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/UpdateCommand.java new file mode 100644 index 000000000..ad5f473ad --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/UpdateCommand.java @@ -0,0 +1,210 @@ +package com.djrapitops.plan.command.commands; + +import com.djrapitops.plan.api.exceptions.connection.*; +import com.djrapitops.plan.api.exceptions.database.DBException; +import com.djrapitops.plan.command.commands.manage.ManageConDebugCommand; +import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.database.databases.operation.FetchOperations; +import com.djrapitops.plan.system.info.InfoSystem; +import com.djrapitops.plan.system.info.request.CheckConnectionRequest; +import com.djrapitops.plan.system.info.request.UpdateCancelRequest; +import com.djrapitops.plan.system.info.server.Server; +import com.djrapitops.plan.system.settings.Permissions; +import com.djrapitops.plan.system.update.VersionCheckSystem; +import com.djrapitops.plan.system.update.VersionInfo; +import com.djrapitops.plan.system.webserver.WebServerSystem; +import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.command.CommandNode; +import com.djrapitops.plugin.command.CommandType; +import com.djrapitops.plugin.command.ISender; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +/** + * Command that updates all servers in the network + * + * @author Rsl1122 + */ +public class UpdateCommand extends CommandNode { + + public UpdateCommand() { + super("update", Permissions.MANAGE.getPermission(), CommandType.ALL); + setArguments("[-update]/[cancel]"); + setShortHelp("Get change log link or update plugin."); + setInDepthHelp( + "/plan update", + " Used to update the plugin on the next shutdown\n", + " /plan update - get change log link", + " /plan update -update - Schedule update to happen on all network servers that are online next time they reboot.", + " /plan update cancel - Cancel scheduled update on servers that haven't rebooted yet." + ); + } + + @Override + public void onCommand(ISender sender, String commandLabel, String[] args) { + if (!VersionCheckSystem.isNewVersionAvailable()) { + sender.sendMessage("§aYou're running the latest version of Plan."); + return; + } + + VersionInfo available = VersionCheckSystem.getInstance().getNewVersionAvailable(); + String downloadUrl = available.getDownloadUrl(); + + if (!available.isTrusted()) { + sender.sendMessage("§cVersion download url did not start with " + + "https://github.com/Rsl1122/Plan-PlayerAnalytics/releases/ " + + "and might not be trusted. You can download this version manually here (Direct download):"); + sender.sendLink(downloadUrl, downloadUrl); + return; + } + + if (args.length == 0) { + sender.sendLink("Change Log v" + available.getVersion().toString() + ": ", "Click me", available.getChangeLogUrl()); + return; + } + + String firstArgument = args[0]; + if ("-update".equals(firstArgument)) { + handleUpdate(sender, args); + } else if ("cancel".equals(firstArgument)) { + cancel(sender); + } else { + throw new IllegalArgumentException("Unknown argument, use '-update' or 'cancel'"); + } + } + + private void cancel(ISender sender) { + try { + cancel(sender, Database.getActive().fetch().getServers()); + sender.sendMessage("§aUpdate has been cancelled."); + } catch (DBException e) { + sender.sendMessage("§cDatabase error occurred, cancel could not be performed."); + Log.toLog(this.getClass().getName(), e); + } + } + + private void handleUpdate(ISender sender, String[] args) { + sender.sendMessage("§aYou can cancel the update on servers that haven't rebooted yet with /plan update cancel."); + sender.sendMessage("Checking that all servers are online.."); + if (!checkNetworkStatus(sender)) { + sender.sendMessage("§cNot all servers were online or accessible, you can still update available servers using -force as a 2nd argument."); + if (args.length <= 1 || !"-force".equals(args[1])) { + return; + } + } + try { + List servers = Database.getActive().fetch().getServers(); + update(sender, servers); + } catch (DBException e) { + Log.toLog(this.getClass().getName(), e); + } + } + + private void update(ISender sender, List servers) { + for (Server server : servers) { + if (update(sender, server)) { + sender.sendMessage("§a" + server.getName() + " scheduled for update."); + } else { + sender.sendMessage("§cUpdate failed on a server, cancelling update on all servers.."); + cancel(sender, servers); + sender.sendMessage("§cUpdate cancelled."); + break; + } + } + } + + private void cancel(ISender sender, List servers) { + for (Server server : servers) { + cancel(sender, server); + } + + } + + private void cancel(ISender sender, Server server) { + try { + InfoSystem.getInstance().getConnectionSystem().sendInfoRequest(new UpdateCancelRequest(), server); + } catch (ForbiddenException | GatewayException | InternalErrorException e) { + sender.sendMessage("§cCancel failed on " + server.getName() + ": Odd Exception: " + e.getClass().getSimpleName()); + } catch (UnauthorizedServerException e) { + sender.sendMessage("§cCancel failed on " + server.getName() + ": Unauthorized. " + server.getName() + " might be using different database."); + } catch (ConnectionFailException e) { + sender.sendMessage("§cCancel failed on " + server.getName() + ": " + e.getCause().getClass().getSimpleName() + " " + e.getCause().getMessage()); + String address = server.getWebAddress(); + boolean local = address.contains("localhost") + || address.startsWith("https://:") // IP empty = Localhost + || address.startsWith("http://:") // IP empty = Localhost + || address.contains("127.0.0.1"); + if (!local) { + sender.sendMessage("§cNon-local address, check that port is open"); + } + } catch (NotFoundException e) { + /* Ignored, older version */ + } catch (WebException e) { + sender.sendMessage("§cCancel failed on " + server.getName() + ": Odd Exception:" + e.getClass().getSimpleName()); + } + } + + private boolean update(ISender sender, Server server) { + try { + InfoSystem.getInstance().getConnectionSystem().sendInfoRequest(new CheckConnectionRequest(), server); + return true; + } catch (BadRequestException e) { + sender.sendMessage("§c" + server.getName() + " has Allow-Update set to false, aborting update."); + return false; + } catch (ForbiddenException | GatewayException | InternalErrorException e) { + sender.sendMessage("§c" + server.getName() + ": Odd Exception: " + e.getClass().getSimpleName()); + return false; + } catch (UnauthorizedServerException e) { + sender.sendMessage("§cFail reason: Unauthorized. " + server.getName() + " might be using different database."); + return false; + } catch (ConnectionFailException e) { + sender.sendMessage("§cFail reason: " + e.getCause().getClass().getSimpleName() + " " + e.getCause().getMessage()); + String address = server.getWebAddress(); + boolean local = address.contains("localhost") + || address.startsWith("https://:") // IP empty = Localhost + || address.startsWith("http://:") // IP empty = Localhost + || address.contains("127.0.0.1"); + if (!local) { + sender.sendMessage("§cNon-local address, check that port is open"); + } + return false; + } catch (NotFoundException e) { + sender.sendMessage("§e" + server.getName() + " is using older version and can not be scheduled for update. " + + "You can update it manually, update will proceed."); + return true; + } catch (WebException e) { + sender.sendMessage("§eOdd Exception: " + e.getClass().getSimpleName()); + return false; + } + } + + private boolean checkNetworkStatus(ISender sender) { + try { + FetchOperations fetch = Database.getActive().fetch(); + Optional bungeeInformation = fetch.getBungeeInformation(); + if (!bungeeInformation.isPresent()) { + return true; + } + Map bukkitServers = fetch.getBukkitServers(); + String accessAddress = WebServerSystem.getInstance().getWebServer().getAccessAddress(); + boolean success = true; + for (Server server : bukkitServers.values()) { + if (!ManageConDebugCommand.testServer(sender, accessAddress, server)) { + success = false; + } + } + Server bungee = bungeeInformation.get(); + if (!ManageConDebugCommand.testServer(sender, accessAddress, bungee)) { + success = false; + } + return success; + } catch (DBException e) { + sender.sendMessage("§cDatabase error occurred, update has been cancelled."); + Log.toLog(this.getClass().getName(), e); + return false; + } + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java index 9a8f8055e..7414538e8 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java @@ -28,12 +28,9 @@ import java.util.UUID; */ public class ManageConDebugCommand extends CommandNode { - private final ColorScheme cs; - public ManageConDebugCommand() { super("con", Permissions.MANAGE.getPermission(), CommandType.ALL); setShortHelp("Debug Bukkit-Bungee Connections"); - cs = PlanPlugin.getInstance().getColorScheme(); } @Override @@ -68,18 +65,19 @@ public class ManageConDebugCommand extends CommandNode { } } - private void testServer(ISender sender, String accessAddress, Server server) { + public static boolean testServer(ISender sender, String accessAddress, Server server) { String address = server.getWebAddress().toLowerCase(); boolean usingHttps = address.startsWith("https"); boolean local = address.contains("localhost") - || address.startsWith("https://:") - || address.startsWith("http://:") + || address.startsWith("https://:") // IP empty = Localhost + || address.startsWith("http://:") // IP empty = Localhost || address.contains("127.0.0.1"); try { InfoSystem.getInstance().getConnectionSystem().sendInfoRequest(new CheckConnectionRequest(accessAddress), server); sender.sendMessage(getMsgFor(address, usingHttps, local, true, true)); + return true; } catch (ForbiddenException | BadRequestException | InternalErrorException e) { sender.sendMessage(getMsgFor(address, usingHttps, local, false, false)); @@ -102,9 +100,11 @@ public class ManageConDebugCommand extends CommandNode { sender.sendMessage(getMsgFor(address, usingHttps, local, false, false)); sender.sendMessage("§eOdd Exception: " + e.getClass().getSimpleName()); } + return false; } - private String getMsgFor(String address, boolean usingHttps, boolean local, boolean successTo, boolean successFrom) { + private static String getMsgFor(String address, boolean usingHttps, boolean local, boolean successTo, boolean successFrom) { + ColorScheme cs = PlanPlugin.getInstance().getColorScheme(); String tCol = cs.getTertiaryColor(); String sCol = cs.getSecondaryColor(); return tCol + address + sCol + ": " diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java index 546c8a884..b53777ecc 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java @@ -125,6 +125,9 @@ public abstract class ConnectionSystem implements SubSystem { putRequest(requests, SaveDBSettingsRequest.createHandler()); putRequest(requests, SendDBSettingsRequest.createHandler()); putRequest(requests, CheckConnectionRequest.createHandler()); + + putRequest(requests, UpdateRequest.createHandler()); + putRequest(requests, UpdateCancelRequest.createHandler()); return requests; } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/UpdateCancelRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/UpdateCancelRequest.java new file mode 100644 index 000000000..e7aeebc55 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/UpdateCancelRequest.java @@ -0,0 +1,37 @@ +/* + * Licence is provided in the jar as license.yml also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml + */ +package com.djrapitops.plan.system.info.request; + +import com.djrapitops.plan.system.update.ShutdownUpdateHook; +import com.djrapitops.plan.system.webserver.response.DefaultResponses; +import com.djrapitops.plan.system.webserver.response.Response; + +import java.util.Map; + +/** + * InfoRequest used for Updating the plugin on a network. + * + * @author Rsl1122 + */ +public class UpdateCancelRequest implements InfoRequest { + + public UpdateCancelRequest() { + } + + public static UpdateCancelRequest createHandler() { + return new UpdateCancelRequest(); + } + + @Override + public void runLocally() { + ShutdownUpdateHook.deActivate(); + } + + @Override + public Response handleRequest(Map variables) { + ShutdownUpdateHook.deActivate(); + return DefaultResponses.SUCCESS.get(); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/UpdateRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/UpdateRequest.java new file mode 100644 index 000000000..c724d1abb --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/UpdateRequest.java @@ -0,0 +1,43 @@ +/* + * Licence is provided in the jar as license.yml also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml + */ +package com.djrapitops.plan.system.info.request; + +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.update.ShutdownUpdateHook; +import com.djrapitops.plan.system.webserver.response.DefaultResponses; +import com.djrapitops.plan.system.webserver.response.Response; +import com.djrapitops.plan.system.webserver.response.api.BadRequestResponse; + +import java.util.Map; + +/** + * InfoRequest used for Updating the plugin on a network. + * + * @author Rsl1122 + */ +public class UpdateRequest implements InfoRequest { + + public UpdateRequest() { + } + + public static UpdateRequest createHandler() { + return new UpdateRequest(); + } + + @Override + public void runLocally() { + new ShutdownUpdateHook().register(); + } + + @Override + public Response handleRequest(Map variables) { + if (Settings.ALLOW_UPDATE.isTrue()) { + new ShutdownUpdateHook().register(); + return DefaultResponses.SUCCESS.get(); + } else { + return new BadRequestResponse("Update not allowed on this server"); + } + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java index 63a8f01d7..a4fc77b0b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java @@ -37,6 +37,8 @@ public enum Settings { DISPLAY_PLAYER_IPS("Customization.Display.PlayerIPs"), DISPLAY_GAPS_IN_GRAPH_DATA("Customization.Display.GapsInGraphData"), DATA_GEOLOCATIONS("Data.Geolocations"), + ALLOW_UPDATE("Plugin.Allow-Update-Command"), + NOTIFY_ABOUT_DEV_RELEASES("Plugin.Notify-About-DEV-Releases"), // Integer WEBSERVER_PORT("WebServer.Port"), diff --git a/Plan/src/main/java/com/djrapitops/plan/system/update/ShutdownUpdateHook.java b/Plan/src/main/java/com/djrapitops/plan/system/update/ShutdownUpdateHook.java new file mode 100644 index 000000000..99f5b1ee6 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/update/ShutdownUpdateHook.java @@ -0,0 +1,104 @@ +package com.djrapitops.plan.system.update; + +import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plugin.api.Check; +import com.djrapitops.plugin.api.utility.Version; +import com.djrapitops.plugin.api.utility.log.Log; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URL; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; + +/** + * Shutdown hook that updates the plugin on server shutdown. + *

+ * Does not perform update on force close. + * + * @author Rsl1122 + */ +public class ShutdownUpdateHook extends Thread { + + private static boolean activated = false; + + private static boolean isActivated() { + return activated; + } + + private static void activate(ShutdownUpdateHook hook) { + activated = true; + Runtime.getRuntime().addShutdownHook(hook); + } + + public static void deActivate() { + activated = false; + Log.infoColor("§aUpdate has been cancelled."); + } + + public void register() { + if (isActivated()) { + return; + } + Log.infoColor("§aUpdate has been scheduled, The new jar will be downloaded on server shutdown."); + activate(this); + } + + @Override + public void run() { + if (!activated) { + return; + } + activated = false; + VersionInfo available = VersionCheckSystem.getInstance().getNewVersionAvailable(); + + if (!Version.isNewVersionAvailable(new Version(VersionCheckSystem.getCurrentVersion()), available.getVersion())) { + return; + } + + File dataFolder = PlanPlugin.getInstance().getDataFolder(); + File pluginsFolder = Check.isSpongeAvailable() + ? dataFolder.getParentFile() + : new File(dataFolder.getParentFile().getParentFile(), "mods"); + if (pluginsFolder == null || !pluginsFolder.isDirectory()) { + System.out.println("Could not get plugin folder for Plan."); + return; + } + File newFileLocation = new File(pluginsFolder, "Plan-" + available.getVersion() + ".jar"); + + try { + downloadNewJar(available, newFileLocation); + deleteOldJar(pluginsFolder, newFileLocation); + } catch (IOException e) { + Log.toLog(this.getClass().getName(), e); + } + } + + private void deleteOldJar(File pluginsFolder, File newFileLocation) { + File[] files = pluginsFolder.listFiles(); + if (files == null) { + System.out.println("Could not delete old jar."); + return; + } + for (File file : files) { + String fileName = file.getName(); + boolean isPlanJar = (fileName.startsWith("Plan-") + && fileName.endsWith(".jar")) + || fileName.equals("Plan.jar"); + boolean isNewJar = fileName.equals(newFileLocation.getName()); + if (isPlanJar && !isNewJar) { + file.deleteOnExit(); + } + } + } + + private void downloadNewJar(VersionInfo available, File newFileLocation) throws IOException { + URL downloadFrom = new URL(available.getDownloadUrl()); + + ReadableByteChannel rbc = Channels.newChannel(downloadFrom.openStream()); + FileOutputStream fos = new FileOutputStream(newFileLocation); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java index 5051d2441..fe1cd2e8d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java @@ -6,6 +6,7 @@ package com.djrapitops.plan.system.update; import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.SubSystem; +import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plugin.api.Priority; import com.djrapitops.plugin.api.systems.NotificationCenter; import com.djrapitops.plugin.api.utility.Version; @@ -13,6 +14,8 @@ import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.utilities.Verify; import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; /** * System for checking if new Version is available when the System initializes. @@ -22,7 +25,7 @@ import java.io.IOException; public class VersionCheckSystem implements SubSystem { private final String currentVersion; - private boolean newVersionAvailable = false; + private VersionInfo newVersionAvailable; public VersionCheckSystem(String currentVersion) { this.currentVersion = currentVersion; @@ -35,7 +38,7 @@ public class VersionCheckSystem implements SubSystem { } public static boolean isNewVersionAvailable() { - return getInstance().newVersionAvailable; + return getInstance().newVersionAvailable != null; } public static String getCurrentVersion() { @@ -44,14 +47,35 @@ public class VersionCheckSystem implements SubSystem { @Override public void enable() { - checkForNewVersion(); + if (Settings.ALLOW_UPDATE.isTrue()) { + try { + List versions = VersionInfoLoader.load(); + if (Settings.NOTIFY_ABOUT_DEV_RELEASES.isFalse()) { + versions = versions.stream().filter(VersionInfo::isRelease).collect(Collectors.toList()); + } + VersionInfo newestVersion = versions.get(0); + if (Version.isNewVersionAvailable(new Version(currentVersion), newestVersion.getVersion())) { + String notification = + "New Release (" + newestVersion.getVersion().toString() + ") is available and can be updated " + + "to using update subcommand." + (newestVersion.isRelease() ? "" : " This is a DEV release."); + Log.info(notification); + NotificationCenter.addNotification(newestVersion.isRelease() ? Priority.HIGH : Priority.MEDIUM, notification); + } else { + Log.info("You're using the latest version."); + } + } catch (IOException e) { + Log.error("Version information could not be loaded from Github/versions.txt"); + } + } else { + checkForNewVersion(); + } } private void checkForNewVersion() { String githubVersionUrl = "https://raw.githubusercontent.com/Rsl1122/Plan-PlayerAnalytics/master/Plan/src/main/resources/plugin.yml"; String spigotUrl = "https://www.spigotmc.org/resources/plan-player-analytics.32536/"; try { - newVersionAvailable = Version.checkVersion(currentVersion, githubVersionUrl); + boolean newVersionAvailable = Version.checkVersion(currentVersion, githubVersionUrl); if (!newVersionAvailable) { try { newVersionAvailable = Version.checkVersion(currentVersion, spigotUrl); @@ -77,4 +101,8 @@ public class VersionCheckSystem implements SubSystem { public void disable() { /* Does not need to be closed */ } + + public VersionInfo getNewVersionAvailable() { + return newVersionAvailable; + } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/update/VersionInfo.java b/Plan/src/main/java/com/djrapitops/plan/system/update/VersionInfo.java new file mode 100644 index 000000000..c294a5803 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/update/VersionInfo.java @@ -0,0 +1,63 @@ +package com.djrapitops.plan.system.update; + +import com.djrapitops.plugin.api.utility.Version; +import com.google.common.base.Objects; + +/** + * Data class for reading version.txt in https://github.com/Rsl1122/Plan-PlayerAnalytics. + * + * @author Rsl1122 + */ +public class VersionInfo implements Comparable { + + private final boolean release; + private final Version version; + private final String downloadUrl; + private final String changeLogUrl; + + public VersionInfo(boolean release, Version version, String downloadUrl, String changeLogUrl) { + this.release = release; + this.version = version; + this.downloadUrl = downloadUrl; + this.changeLogUrl = changeLogUrl; + } + + public boolean isRelease() { + return release; + } + + public Version getVersion() { + return version; + } + + public String getDownloadUrl() { + return downloadUrl; + } + + public String getChangeLogUrl() { + return changeLogUrl; + } + + public boolean isTrusted() { + return downloadUrl.startsWith("https://github.com/Rsl1122/Plan-PlayerAnalytics/releases/download/"); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + VersionInfo that = (VersionInfo) o; + return release == that.release && + Objects.equal(version, that.version); + } + + @Override + public int hashCode() { + return Objects.hashCode(release, version); + } + + @Override + public int compareTo(VersionInfo o) { + return -this.version.compareTo(o.version); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/update/VersionInfoLoader.java b/Plan/src/main/java/com/djrapitops/plan/system/update/VersionInfoLoader.java new file mode 100644 index 000000000..4ff8281bf --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/update/VersionInfoLoader.java @@ -0,0 +1,57 @@ +package com.djrapitops.plan.system.update; + +import com.djrapitops.plugin.api.utility.Version; + +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Scanner; + +/** + * Utility for loading version information from github. + * + * @author Rsl1122 + */ +public class VersionInfoLoader { + + private static final String VERSION_TXT_URL = + "https://raw.githubusercontent.com/Rsl1122/Plan-PlayerAnalytics/master/versions.txt"; + + /** + * Loads version information from github. + * + * @return List of VersionInfo, newest version first. + * @throws IOException If site can not be accessed. + * @throws java.net.MalformedURLException If VERSION_TXT_URL is not valid. + */ + public static List load() throws IOException { + URL url = new URL(VERSION_TXT_URL); + + List versionInfo = new ArrayList<>(); + + try (Scanner websiteScanner = new Scanner(url.openStream())) { + while (websiteScanner.hasNextLine()) { + String line = websiteScanner.nextLine(); + if (!line.startsWith("REL") && !line.startsWith("DEV")) { + continue; + } + String[] parts = line.split("\\|"); + if (parts.length < 4) { + continue; + } + boolean release = parts[0].equals("REL"); + Version version = new Version(parts[1]); + String downloadUrl = parts[2]; + String changeLogUrl = parts[3]; + + versionInfo.add(new VersionInfo(release, version, downloadUrl, changeLogUrl)); + } + } + + Collections.sort(versionInfo); + return versionInfo; + } + +} \ No newline at end of file diff --git a/Plan/src/main/resources/bungee.yml b/Plan/src/main/resources/bungee.yml index ff3950d61..50e65696b 100644 --- a/Plan/src/main/resources/bungee.yml +++ b/Plan/src/main/resources/bungee.yml @@ -1,4 +1,4 @@ name: Plan author: Rsl1122 main: com.djrapitops.plan.PlanBungee -version: 4.2.0 \ No newline at end of file +version: 4.2.0-b1 \ No newline at end of file diff --git a/Plan/src/main/resources/bungeeconfig.yml b/Plan/src/main/resources/bungeeconfig.yml index 439e5f76b..459f24239 100644 --- a/Plan/src/main/resources/bungeeconfig.yml +++ b/Plan/src/main/resources/bungeeconfig.yml @@ -12,6 +12,8 @@ Network: Plugin: Debug: 'false' Locale: default + Allow-Update-Command: true + Notify-About-DEV-Releases: false # ----------------------------------------------------- # More information about SSL Certificate Settings: diff --git a/Plan/src/main/resources/config.yml b/Plan/src/main/resources/config.yml index 65cbe2836..4e102d8f5 100644 --- a/Plan/src/main/resources/config.yml +++ b/Plan/src/main/resources/config.yml @@ -17,6 +17,8 @@ Plugin: Bungee-Override: StandaloneMode: false CopyBungeeConfig: true + Allow-Update-Command: true + Notify-About-DEV-Releases: false # ----------------------------------------------------- # More information about SSL Certificate Settings: diff --git a/Plan/src/main/resources/plugin.yml b/Plan/src/main/resources/plugin.yml index ae52c2950..d7d70ff21 100644 --- a/Plan/src/main/resources/plugin.yml +++ b/Plan/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: Plan author: Rsl1122 main: com.djrapitops.plan.Plan -version: 4.2.0 +version: 4.2.0-b1 softdepend: - EssentialsX - Towny diff --git a/Plan/src/test/java/com/djrapitops/plan/system/update/VersionInfoLoaderTest.java b/Plan/src/test/java/com/djrapitops/plan/system/update/VersionInfoLoaderTest.java new file mode 100644 index 000000000..60734e2a0 --- /dev/null +++ b/Plan/src/test/java/com/djrapitops/plan/system/update/VersionInfoLoaderTest.java @@ -0,0 +1,24 @@ +package com.djrapitops.plan.system.update; + +import com.djrapitops.plugin.api.utility.Version; +import org.junit.Test; + +import java.io.IOException; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class VersionInfoLoaderTest { + + @Test + public void versionLoaderTest() throws IOException { + List versions = VersionInfoLoader.load(); + + VersionInfo oldest = versions.get(versions.size() - 1); + assertEquals(new Version("4.1.7"), oldest.getVersion()); + assertTrue(oldest.isRelease()); + assertTrue(oldest.isTrusted()); + } + +} \ No newline at end of file From 0ff4e22a0214074627df54bbe085b7635b9ebb7a Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Sat, 14 Apr 2018 12:56:38 +0300 Subject: [PATCH 18/33] Fixed Update downloading, old jar deletion still broken --- .../djrapitops/plan/command/PlanCommand.java | 1 + .../plan/command/commands/UpdateCommand.java | 62 ++++++--- .../djrapitops/plan/system/PlanSystem.java | 2 +- .../system/update/ShutdownUpdateHook.java | 127 +++++++++++------- .../system/update/VersionCheckSystem.java | 5 +- .../system/update/ShutdownUpdateHookTest.java | 41 ++++++ 6 files changed, 168 insertions(+), 70 deletions(-) create mode 100644 Plan/src/test/java/com/djrapitops/plan/system/update/ShutdownUpdateHookTest.java diff --git a/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java index 6b2ca3f1c..50195b0ff 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java @@ -36,6 +36,7 @@ public class PlanCommand extends TreeCmdNode { new ListCommand(), new AnalyzeCommand(), new NetworkCommand(), + new ListServersCommand(plugin) }, new CommandNode[]{ new WebUserCommand(plugin, registerCommand, this), diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/UpdateCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/UpdateCommand.java index ad5f473ad..080946e7d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/UpdateCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/UpdateCommand.java @@ -6,17 +6,22 @@ import com.djrapitops.plan.command.commands.manage.ManageConDebugCommand; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.database.databases.operation.FetchOperations; import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.request.CheckConnectionRequest; import com.djrapitops.plan.system.info.request.UpdateCancelRequest; +import com.djrapitops.plan.system.info.request.UpdateRequest; import com.djrapitops.plan.system.info.server.Server; import com.djrapitops.plan.system.settings.Permissions; +import com.djrapitops.plan.system.settings.locale.Locale; +import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plan.system.update.VersionCheckSystem; import com.djrapitops.plan.system.update.VersionInfo; import com.djrapitops.plan.system.webserver.WebServerSystem; import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; +import com.djrapitops.plugin.command.CommandUtils; import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plugin.task.AbsRunnable; +import com.djrapitops.plugin.task.RunnableFactory; import java.util.List; import java.util.Map; @@ -32,13 +37,13 @@ public class UpdateCommand extends CommandNode { public UpdateCommand() { super("update", Permissions.MANAGE.getPermission(), CommandType.ALL); - setArguments("[-update]/[cancel]"); + setArguments("[-u]/[cancel]"); setShortHelp("Get change log link or update plugin."); setInDepthHelp( "/plan update", " Used to update the plugin on the next shutdown\n", " /plan update - get change log link", - " /plan update -update - Schedule update to happen on all network servers that are online next time they reboot.", + " /plan update -u - Schedule update to happen on all network servers that are online next time they reboot.", " /plan update cancel - Cancel scheduled update on servers that haven't rebooted yet." ); } @@ -62,24 +67,40 @@ public class UpdateCommand extends CommandNode { } if (args.length == 0) { - sender.sendLink("Change Log v" + available.getVersion().toString() + ": ", "Click me", available.getChangeLogUrl()); + String message = "Change Log v" + available.getVersion().toString() + ": "; + String url = available.getChangeLogUrl(); + if (CommandUtils.isConsole(sender)) { + sender.sendMessage(message + url); + } else { + sender.sendMessage(message); + sender.sendLink(" ", Locale.get(Msg.CMD_INFO_CLICK_ME).toString(), url); + } return; } String firstArgument = args[0]; - if ("-update".equals(firstArgument)) { - handleUpdate(sender, args); - } else if ("cancel".equals(firstArgument)) { - cancel(sender); - } else { - throw new IllegalArgumentException("Unknown argument, use '-update' or 'cancel'"); - } + RunnableFactory.createNew("Update Command Task", new AbsRunnable() { + @Override + public void run() { + try { + if ("-u".equals(firstArgument)) { + handleUpdate(sender, args); + } else if ("cancel".equals(firstArgument)) { + handleCancel(sender); + } else { + throw new IllegalArgumentException("Unknown argument, use '-u' or 'cancel'"); + } + } finally { + cancel(); + } + } + }).runTaskAsynchronously(); } - private void cancel(ISender sender) { + private void handleCancel(ISender sender) { try { cancel(sender, Database.getActive().fetch().getServers()); - sender.sendMessage("§aUpdate has been cancelled."); + sender.sendMessage("§aCancel operation performed."); } catch (DBException e) { sender.sendMessage("§cDatabase error occurred, cancel could not be performed."); Log.toLog(this.getClass().getName(), e); @@ -90,24 +111,28 @@ public class UpdateCommand extends CommandNode { sender.sendMessage("§aYou can cancel the update on servers that haven't rebooted yet with /plan update cancel."); sender.sendMessage("Checking that all servers are online.."); if (!checkNetworkStatus(sender)) { - sender.sendMessage("§cNot all servers were online or accessible, you can still update available servers using -force as a 2nd argument."); - if (args.length <= 1 || !"-force".equals(args[1])) { + sender.sendMessage("§cNot all servers were online or accessible, you can still update available servers using /plan -update -force"); + if (args.length > 1 && "-force".equals(args[1])) { return; } } try { List servers = Database.getActive().fetch().getServers(); - update(sender, servers); + update(sender, servers, args); } catch (DBException e) { Log.toLog(this.getClass().getName(), e); } } - private void update(ISender sender, List servers) { + private void update(ISender sender, List servers, String[] args) { for (Server server : servers) { if (update(sender, server)) { sender.sendMessage("§a" + server.getName() + " scheduled for update."); } else { + if (args.length > 1 && "-force".equals(args[1])) { + sender.sendMessage("§e" + server.getName() + " failed to update, -force specified, continuing update."); + continue; + } sender.sendMessage("§cUpdate failed on a server, cancelling update on all servers.."); cancel(sender, servers); sender.sendMessage("§cUpdate cancelled."); @@ -149,7 +174,7 @@ public class UpdateCommand extends CommandNode { private boolean update(ISender sender, Server server) { try { - InfoSystem.getInstance().getConnectionSystem().sendInfoRequest(new CheckConnectionRequest(), server); + InfoSystem.getInstance().getConnectionSystem().sendInfoRequest(new UpdateRequest(), server); return true; } catch (BadRequestException e) { sender.sendMessage("§c" + server.getName() + " has Allow-Update set to false, aborting update."); @@ -186,6 +211,7 @@ public class UpdateCommand extends CommandNode { FetchOperations fetch = Database.getActive().fetch(); Optional bungeeInformation = fetch.getBungeeInformation(); if (!bungeeInformation.isPresent()) { + sender.sendMessage("Bungee address not found in the database, assuming this is not a network."); return true; } Map bukkitServers = fetch.getBukkitServers(); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/PlanSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/PlanSystem.java index d2a42788e..516dd7b02 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/PlanSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/PlanSystem.java @@ -81,9 +81,9 @@ public abstract class PlanSystem implements SubSystem { checkSubSystemInitialization(); SubSystem[] systems = new SubSystem[]{ - versionCheckSystem, fileSystem, configSystem, + versionCheckSystem, databaseSystem, webServerSystem, processing, diff --git a/Plan/src/main/java/com/djrapitops/plan/system/update/ShutdownUpdateHook.java b/Plan/src/main/java/com/djrapitops/plan/system/update/ShutdownUpdateHook.java index 99f5b1ee6..0e64ab73d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/update/ShutdownUpdateHook.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/update/ShutdownUpdateHook.java @@ -5,12 +5,10 @@ import com.djrapitops.plugin.api.Check; import com.djrapitops.plugin.api.utility.Version; import com.djrapitops.plugin.api.utility.log.Log; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; +import java.io.*; import java.net.URL; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; +import java.util.HashSet; +import java.util.Set; /** * Shutdown hook that updates the plugin on server shutdown. @@ -22,64 +20,59 @@ import java.nio.channels.ReadableByteChannel; public class ShutdownUpdateHook extends Thread { private static boolean activated = false; + private static File newJar; + + private static Set toDelete = new HashSet<>(); private static boolean isActivated() { return activated; } - private static void activate(ShutdownUpdateHook hook) { + public static void activate() { activated = true; - Runtime.getRuntime().addShutdownHook(hook); - } - - public static void deActivate() { - activated = false; - Log.infoColor("§aUpdate has been cancelled."); - } - - public void register() { - if (isActivated()) { - return; - } - Log.infoColor("§aUpdate has been scheduled, The new jar will be downloaded on server shutdown."); - activate(this); - } - - @Override - public void run() { - if (!activated) { - return; - } - activated = false; VersionInfo available = VersionCheckSystem.getInstance().getNewVersionAvailable(); if (!Version.isNewVersionAvailable(new Version(VersionCheckSystem.getCurrentVersion()), available.getVersion())) { return; } - - File dataFolder = PlanPlugin.getInstance().getDataFolder(); - File pluginsFolder = Check.isSpongeAvailable() - ? dataFolder.getParentFile() - : new File(dataFolder.getParentFile().getParentFile(), "mods"); - if (pluginsFolder == null || !pluginsFolder.isDirectory()) { - System.out.println("Could not get plugin folder for Plan."); - return; - } - File newFileLocation = new File(pluginsFolder, "Plan-" + available.getVersion() + ".jar"); - try { - downloadNewJar(available, newFileLocation); - deleteOldJar(pluginsFolder, newFileLocation); + File pluginsFolder = getPluginsFolder(); + newJar = new File(pluginsFolder, "Plan-" + available.getVersion() + ".jar"); + + downloadNewJar(available, newJar); + registerOldJarForDeletion(pluginsFolder, newJar); } catch (IOException e) { - Log.toLog(this.getClass().getName(), e); + e.printStackTrace(); } } - private void deleteOldJar(File pluginsFolder, File newFileLocation) { + private static File getPluginsFolder() throws FileNotFoundException { + File dataFolder = PlanPlugin.getInstance().getDataFolder(); + File pluginsFolder = Check.isSpongeAvailable() + ? new File(dataFolder.getParentFile().getParentFile().getPath(), "mods") + : new File(dataFolder.getParentFile().getPath()); + if (!pluginsFolder.isDirectory()) { + throw new FileNotFoundException("Could not get plugin folder for Plan."); + } + return pluginsFolder; + } + + public static void deActivate() { + activated = false; + Log.infoColor("§aUpdate has been cancelled."); + + if (newJar != null && newJar.exists()) { + if (!newJar.delete()) { + newJar.deleteOnExit(); + } + } + toDelete.clear(); + } + + public static void registerOldJarForDeletion(File pluginsFolder, File newFileLocation) throws FileNotFoundException { File[] files = pluginsFolder.listFiles(); if (files == null) { - System.out.println("Could not delete old jar."); - return; + throw new FileNotFoundException("Could not delete old jar."); } for (File file : files) { String fileName = file.getName(); @@ -88,17 +81,51 @@ public class ShutdownUpdateHook extends Thread { || fileName.equals("Plan.jar"); boolean isNewJar = fileName.equals(newFileLocation.getName()); if (isPlanJar && !isNewJar) { - file.deleteOnExit(); + toDelete.add(file); } } } - private void downloadNewJar(VersionInfo available, File newFileLocation) throws IOException { + public static void downloadNewJar(VersionInfo available, File newFileLocation) throws IOException { URL downloadFrom = new URL(available.getDownloadUrl()); + BufferedInputStream in = null; + FileOutputStream fout = null; + try { + in = new BufferedInputStream(downloadFrom.openStream()); + fout = new FileOutputStream(newFileLocation); - ReadableByteChannel rbc = Channels.newChannel(downloadFrom.openStream()); - FileOutputStream fos = new FileOutputStream(newFileLocation); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + final byte data[] = new byte[1024]; + int count; + while ((count = in.read(data, 0, 1024)) != -1) { + fout.write(data, 0, count); + } + } finally { + if (in != null) { + in.close(); + } + if (fout != null) { + fout.close(); + } + } + } + + public void register() { + if (isActivated()) { + return; + } + Log.infoColor("§aUpdate has been scheduled, Downloading new jar.. Restart server to take effect."); + activate(); + Runtime.getRuntime().addShutdownHook(this); + } + + @Override + public void run() { + for (File f : toDelete + ) { + if (!f.delete()) { + f.deleteOnExit(); + } + } } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java index fe1cd2e8d..b52f9f21c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java @@ -55,10 +55,13 @@ public class VersionCheckSystem implements SubSystem { } VersionInfo newestVersion = versions.get(0); if (Version.isNewVersionAvailable(new Version(currentVersion), newestVersion.getVersion())) { + newVersionAvailable = newestVersion; String notification = "New Release (" + newestVersion.getVersion().toString() + ") is available and can be updated " + "to using update subcommand." + (newestVersion.isRelease() ? "" : " This is a DEV release."); - Log.info(notification); + Log.infoColor("§a----------------------------------------"); + Log.infoColor("§a" + notification); + Log.infoColor("§a----------------------------------------"); NotificationCenter.addNotification(newestVersion.isRelease() ? Priority.HIGH : Priority.MEDIUM, notification); } else { Log.info("You're using the latest version."); diff --git a/Plan/src/test/java/com/djrapitops/plan/system/update/ShutdownUpdateHookTest.java b/Plan/src/test/java/com/djrapitops/plan/system/update/ShutdownUpdateHookTest.java new file mode 100644 index 000000000..f162ecd6c --- /dev/null +++ b/Plan/src/test/java/com/djrapitops/plan/system/update/ShutdownUpdateHookTest.java @@ -0,0 +1,41 @@ +package com.djrapitops.plan.system.update; + +import com.djrapitops.plugin.api.utility.Version; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.io.File; +import java.io.IOException; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * //TODO Class Javadoc Comment + * + * @author Rsl1122 + */ +public class ShutdownUpdateHookTest { + + @ClassRule + public static TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Test + public void downloadNewJar() throws IOException { + File newJar = new File(temporaryFolder.getRoot(), "Plan-4.2.0.jar"); + ShutdownUpdateHook.downloadNewJar(new VersionInfo( + true, + new Version("4.2.0"), + "https://github.com/Rsl1122/Plan-PlayerAnalytics/releases/download/4.2.0/Plan-4.2.0.jar", + "" + ), newJar + ); + + assertTrue(newJar.exists()); + + ShutdownUpdateHook.registerOldJarForDeletion(temporaryFolder.getRoot(), new File(temporaryFolder.getRoot(), "Plan-4.2.0-b1.jar")); + + assertFalse(newJar.exists()); + } +} \ No newline at end of file From a8c1374722747a9c083444078e274e52d64732b9 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Wed, 18 Apr 2018 10:59:15 +0300 Subject: [PATCH 19/33] APF-3.2.0 --- Plan/pom.xml | 2 +- .../com/djrapitops/plan/system/settings/PlanErrorManager.java | 2 +- Plan/src/test/java/utilities/TestErrorManager.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Plan/pom.xml b/Plan/pom.xml index 39ee621d4..75e098a40 100644 --- a/Plan/pom.xml +++ b/Plan/pom.xml @@ -29,7 +29,7 @@ com.djrapitops AbstractPluginFramework - 3.2.0-SNAPSHOT + 3.2.0 diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/PlanErrorManager.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/PlanErrorManager.java index 8d16f3495..5b5dc0470 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/PlanErrorManager.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/PlanErrorManager.java @@ -20,7 +20,7 @@ import java.util.logging.Logger; * * @author Rsl1122 */ -public class PlanErrorManager extends ErrorManager { +public class PlanErrorManager implements ErrorManager { @Override public void toLog(String source, Throwable e, Class callingPlugin) { diff --git a/Plan/src/test/java/utilities/TestErrorManager.java b/Plan/src/test/java/utilities/TestErrorManager.java index 292a40224..425029cd7 100644 --- a/Plan/src/test/java/utilities/TestErrorManager.java +++ b/Plan/src/test/java/utilities/TestErrorManager.java @@ -11,7 +11,7 @@ import com.djrapitops.plugin.api.utility.log.errormanager.ErrorManager; * * @author Rsl1122 */ -public class TestErrorManager extends ErrorManager { +public class TestErrorManager implements ErrorManager { @Override public void toLog(String s, Throwable throwable, Class aClass) { From 428fc40eef43023173079877db38f02c34c40a63 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Wed, 18 Apr 2018 11:03:32 +0300 Subject: [PATCH 20/33] Fixed UpdateHookTest --- .../plan/system/update/ShutdownUpdateHookTest.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Plan/src/test/java/com/djrapitops/plan/system/update/ShutdownUpdateHookTest.java b/Plan/src/test/java/com/djrapitops/plan/system/update/ShutdownUpdateHookTest.java index f162ecd6c..ef9ee6f6c 100644 --- a/Plan/src/test/java/com/djrapitops/plan/system/update/ShutdownUpdateHookTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/system/update/ShutdownUpdateHookTest.java @@ -7,8 +7,8 @@ import org.junit.rules.TemporaryFolder; import java.io.File; import java.io.IOException; +import java.util.Arrays; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** @@ -34,8 +34,11 @@ public class ShutdownUpdateHookTest { assertTrue(newJar.exists()); - ShutdownUpdateHook.registerOldJarForDeletion(temporaryFolder.getRoot(), new File(temporaryFolder.getRoot(), "Plan-4.2.0-b1.jar")); + System.out.println(Arrays.toString(temporaryFolder.getRoot().listFiles())); + ShutdownUpdateHook.registerOldJarForDeletion(temporaryFolder.getRoot(), new File(temporaryFolder.getRoot(), "Plan-4.2.0.jar")); - assertFalse(newJar.exists()); + new ShutdownUpdateHook().run(); + + assertTrue(newJar.exists()); } } \ No newline at end of file From 887cf3c29edc1a26b5f6d5b9da5ccad9e1f277a7 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Fri, 4 May 2018 10:12:15 +0300 Subject: [PATCH 21/33] Fixed shutdown update hook not deleting the old jar (on Bukkit) --- .../system/update/ShutdownUpdateHook.java | 40 +++++++++++-------- .../system/update/ShutdownUpdateHookTest.java | 15 ++++++- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/system/update/ShutdownUpdateHook.java b/Plan/src/main/java/com/djrapitops/plan/system/update/ShutdownUpdateHook.java index 0e64ab73d..f71d5d8de 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/update/ShutdownUpdateHook.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/update/ShutdownUpdateHook.java @@ -7,6 +7,7 @@ import com.djrapitops.plugin.api.utility.log.Log; import java.io.*; import java.net.URL; +import java.net.URLClassLoader; import java.util.HashSet; import java.util.Set; @@ -76,8 +77,7 @@ public class ShutdownUpdateHook extends Thread { } for (File file : files) { String fileName = file.getName(); - boolean isPlanJar = (fileName.startsWith("Plan-") - && fileName.endsWith(".jar")) + boolean isPlanJar = (fileName.startsWith("Plan-") && fileName.endsWith(".jar")) || fileName.equals("Plan.jar"); boolean isNewJar = fileName.equals(newFileLocation.getName()); if (isPlanJar && !isNewJar) { @@ -88,24 +88,15 @@ public class ShutdownUpdateHook extends Thread { public static void downloadNewJar(VersionInfo available, File newFileLocation) throws IOException { URL downloadFrom = new URL(available.getDownloadUrl()); - BufferedInputStream in = null; - FileOutputStream fout = null; - try { - in = new BufferedInputStream(downloadFrom.openStream()); - fout = new FileOutputStream(newFileLocation); - + try ( + BufferedInputStream in = new BufferedInputStream(downloadFrom.openStream()); + FileOutputStream fout = new FileOutputStream(newFileLocation) + ) { final byte data[] = new byte[1024]; int count; while ((count = in.read(data, 0, 1024)) != -1) { fout.write(data, 0, count); } - } finally { - if (in != null) { - in.close(); - } - if (fout != null) { - fout.close(); - } } } @@ -120,12 +111,27 @@ public class ShutdownUpdateHook extends Thread { @Override public void run() { - for (File f : toDelete - ) { + unloadJar(); + + for (File f : toDelete) { if (!f.delete()) { f.deleteOnExit(); } } } + private void unloadJar() { + ClassLoader classLoader = PlanPlugin.class.getClassLoader(); + + if (classLoader instanceof URLClassLoader) { + try { + ((URLClassLoader) classLoader).close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + System.gc(); + } + } \ No newline at end of file diff --git a/Plan/src/test/java/com/djrapitops/plan/system/update/ShutdownUpdateHookTest.java b/Plan/src/test/java/com/djrapitops/plan/system/update/ShutdownUpdateHookTest.java index ef9ee6f6c..825ae3a47 100644 --- a/Plan/src/test/java/com/djrapitops/plan/system/update/ShutdownUpdateHookTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/system/update/ShutdownUpdateHookTest.java @@ -9,12 +9,14 @@ import java.io.File; import java.io.IOException; import java.util.Arrays; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** - * //TODO Class Javadoc Comment + * Test for ShutdownUpdateHook functionality. * * @author Rsl1122 + * @see ShutdownUpdateHook */ public class ShutdownUpdateHookTest { @@ -33,12 +35,23 @@ public class ShutdownUpdateHookTest { ); assertTrue(newJar.exists()); + } + + @Test + public void deleteOldJarAndKeepNewJar() throws IOException { + File newJar = new File(temporaryFolder.getRoot(), "Plan-4.2.0.jar"); + File oldJar = new File(temporaryFolder.getRoot(), "Plan.jar"); + + assertTrue(newJar.createNewFile()); + assertTrue(oldJar.createNewFile()); System.out.println(Arrays.toString(temporaryFolder.getRoot().listFiles())); ShutdownUpdateHook.registerOldJarForDeletion(temporaryFolder.getRoot(), new File(temporaryFolder.getRoot(), "Plan-4.2.0.jar")); new ShutdownUpdateHook().run(); + System.out.println(Arrays.toString(temporaryFolder.getRoot().listFiles())); assertTrue(newJar.exists()); + assertFalse(oldJar.exists()); } } \ No newline at end of file From 09a273705368c2082106b9d9495f21a8a957cb97 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Sun, 13 May 2018 12:25:02 +0300 Subject: [PATCH 22/33] Fixed tests breaking due to class unloading --- .../com/djrapitops/plan/system/update/ShutdownUpdateHook.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/system/update/ShutdownUpdateHook.java b/Plan/src/main/java/com/djrapitops/plan/system/update/ShutdownUpdateHook.java index f71d5d8de..889aa3cdf 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/update/ShutdownUpdateHook.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/update/ShutdownUpdateHook.java @@ -111,7 +111,9 @@ public class ShutdownUpdateHook extends Thread { @Override public void run() { - unloadJar(); + if (!(Check.isBukkitAvailable() && Check.isSpongeAvailable() && Check.isBungeeAvailable())) { + unloadJar(); + } for (File f : toDelete) { if (!f.delete()) { From 2c7b514719ba132a1bebf6642fc7b8adb52cf889 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Mon, 21 May 2018 10:34:13 +0300 Subject: [PATCH 23/33] Disabled update system because it doesn't work on Bungee yet. --- .../java/com/djrapitops/plan/command/PlanBungeeCommand.java | 3 +-- .../main/java/com/djrapitops/plan/command/PlanCommand.java | 2 +- .../com/djrapitops/plan/command/commands/UpdateCommand.java | 2 +- .../plan/system/info/connection/ConnectionSystem.java | 4 ++-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java index 8472f44da..8c9707a91 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java @@ -4,7 +4,6 @@ import com.djrapitops.plan.PlanBungee; import com.djrapitops.plan.command.commands.*; import com.djrapitops.plan.command.commands.manage.ManageConDebugCommand; import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; import com.djrapitops.plugin.command.CommandNode; @@ -50,7 +49,7 @@ public class PlanBungeeCommand extends TreeCmdNode { new BungeeSetupToggleCommand(), new ReloadCommand(plugin), new StatusCommand<>(plugin, Permissions.MANAGE.getPermission(), plugin.getColorScheme()), - (Settings.ALLOW_UPDATE.isTrue() ? new UpdateCommand() : null) +// (Settings.ALLOW_UPDATE.isTrue() ? new UpdateCommand() : null) } ); } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java index 50195b0ff..ed0787e36 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java @@ -48,7 +48,7 @@ public class PlanCommand extends TreeCmdNode { new ManageCommand(plugin, this), new StatusCommand<>(plugin, Permissions.MANAGE.getPermission(), plugin.getColorScheme()), (Settings.DEV_MODE.isTrue() ? new DevCommand() : null), - (Settings.ALLOW_UPDATE.isTrue() ? new UpdateCommand() : null) +// (Settings.ALLOW_UPDATE.isTrue() ? new UpdateCommand() : null) } ); } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/UpdateCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/UpdateCommand.java index 080946e7d..10d2371be 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/UpdateCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/UpdateCommand.java @@ -179,7 +179,7 @@ public class UpdateCommand extends CommandNode { } catch (BadRequestException e) { sender.sendMessage("§c" + server.getName() + " has Allow-Update set to false, aborting update."); return false; - } catch (ForbiddenException | GatewayException | InternalErrorException e) { + } catch (ForbiddenException | GatewayException | InternalErrorException | NoServersException e) { sender.sendMessage("§c" + server.getName() + ": Odd Exception: " + e.getClass().getSimpleName()); return false; } catch (UnauthorizedServerException e) { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java index b53777ecc..50d9c9716 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java @@ -126,8 +126,8 @@ public abstract class ConnectionSystem implements SubSystem { putRequest(requests, SendDBSettingsRequest.createHandler()); putRequest(requests, CheckConnectionRequest.createHandler()); - putRequest(requests, UpdateRequest.createHandler()); - putRequest(requests, UpdateCancelRequest.createHandler()); +// putRequest(requests, UpdateRequest.createHandler()); +// putRequest(requests, UpdateCancelRequest.createHandler()); return requests; } From 71098e59f4417b8f3d8e123b4f049b72b19662ac Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Mon, 21 May 2018 11:31:18 +0300 Subject: [PATCH 24/33] IP storage updated for GDPR compliance --- .../djrapitops/plan/data/PlayerProfile.java | 2 +- .../plan/data/container/GeoInfo.java | 18 ++- .../system/database/databases/sql/SQLDB.java | 6 +- .../databases/sql/tables/GeoInfoTable.java | 128 +++++++++++++----- .../importing/importers/Importer.java | 8 +- .../processors/player/IPUpdateProcessor.java | 4 +- .../plan/utilities/FormatUtils.java | 7 +- .../djrapitops/plan/utilities/SHA256Hash.java | 21 +++ .../system/database/databases/SQLiteTest.java | 26 ++-- .../plan/utilities/FormatUtilsTest.java | 2 +- .../plan/utilities/SHA256HashTest.java | 19 +++ 11 files changed, 187 insertions(+), 54 deletions(-) create mode 100644 Plan/src/main/java/com/djrapitops/plan/utilities/SHA256Hash.java create mode 100644 Plan/src/test/java/com/djrapitops/plan/utilities/SHA256HashTest.java diff --git a/Plan/src/main/java/com/djrapitops/plan/data/PlayerProfile.java b/Plan/src/main/java/com/djrapitops/plan/data/PlayerProfile.java index 999404cf5..e31d2e820 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/PlayerProfile.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/PlayerProfile.java @@ -241,7 +241,7 @@ public class PlayerProfile { public GeoInfo getMostRecentGeoInfo() { if (geoInformation.isEmpty()) { - return new GeoInfo("-", "Not Known", MiscUtils.getTime()); + return new GeoInfo("-", "Not Known", MiscUtils.getTime(), ""); } geoInformation.sort(new GeoInfoComparator()); return geoInformation.get(0); diff --git a/Plan/src/main/java/com/djrapitops/plan/data/container/GeoInfo.java b/Plan/src/main/java/com/djrapitops/plan/data/container/GeoInfo.java index f34bf5f21..89f6429b7 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/container/GeoInfo.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/container/GeoInfo.java @@ -4,8 +4,13 @@ */ package com.djrapitops.plan.data.container; +import com.djrapitops.plan.utilities.FormatUtils; +import com.djrapitops.plan.utilities.SHA256Hash; import com.google.common.base.Objects; +import java.io.UnsupportedEncodingException; +import java.security.NoSuchAlgorithmException; + /** * Data class that contains information about IP and Geolocation. * @@ -15,12 +20,19 @@ public class GeoInfo { private final String ip; private final String geolocation; + private final String ipHash; private final long lastUsed; - public GeoInfo(String ip, String geolocation, long lastUsed) { + public GeoInfo(String ip, String geolocation, long lastUsed) + throws UnsupportedEncodingException, NoSuchAlgorithmException { + this(FormatUtils.formatIP(ip), geolocation, lastUsed, new SHA256Hash(ip).create()); + } + + public GeoInfo(String ip, String geolocation, long lastUsed, String ipHash) { this.ip = ip; this.geolocation = geolocation; this.lastUsed = lastUsed; + this.ipHash = ipHash; } public String getIp() { @@ -35,6 +47,10 @@ public class GeoInfo { return lastUsed; } + public String getIpHash() { + return ipHash; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java index 9935158f9..328514f29 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java @@ -133,7 +133,7 @@ public abstract class SQLDB extends Database { if (newDatabase) { Log.info("New Database created."); - versionTable.setVersion(16); + versionTable.setVersion(17); } int version = versionTable.getVersion(); @@ -177,6 +177,10 @@ public abstract class SQLDB extends Database { worldTimesTable.alterTableV16(); versionTable.setVersion(16); } + if (version < 17) { + geoInfoTable.alterTableV17(); + versionTable.setVersion(17); + } } catch (SQLException e) { throw new DBInitException("Failed to set-up Database", e); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/GeoInfoTable.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/GeoInfoTable.java index b401cda14..24a6ed238 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/GeoInfoTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/GeoInfoTable.java @@ -10,8 +10,14 @@ import com.djrapitops.plan.system.database.databases.sql.statements.Column; import com.djrapitops.plan.system.database.databases.sql.statements.Select; import com.djrapitops.plan.system.database.databases.sql.statements.Sql; import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.task.AbsRunnable; +import com.djrapitops.plugin.task.RunnableFactory; import com.djrapitops.plugin.utilities.Verify; +import java.io.UnsupportedEncodingException; +import java.security.NoSuchAlgorithmException; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -33,11 +39,12 @@ public class GeoInfoTable extends UserIDTable { insertStatement = "INSERT INTO " + tableName + " (" + Col.USER_ID + ", " + Col.IP + ", " + + Col.IP_HASH + ", " + Col.GEOLOCATION + ", " + Col.LAST_USED + ") VALUES (" + usersTable.statementSelectID + ", " - + "?, ?, ?)"; + + "?, ?, ?, ?)"; } private String insertStatement; @@ -48,6 +55,7 @@ public class GeoInfoTable extends UserIDTable { .column(Col.USER_ID, Sql.INT).notNull() .column(Col.IP, Sql.varchar(39)).notNull() .column(Col.GEOLOCATION, Sql.varchar(50)).notNull() + .column(Col.IP_HASH, Sql.varchar(200)) .column(Col.LAST_USED, Sql.LONG).notNull().defaultValue("0") .foreignKey(Col.USER_ID, usersTable.getTableName(), UsersTable.Col.ID) .toString() @@ -64,6 +72,49 @@ public class GeoInfoTable extends UserIDTable { addColumns(Col.LAST_USED + " bigint NOT NULL DEFAULT 0"); } + public void alterTableV17() { + addColumns(Col.IP_HASH.get() + " varchar(200) DEFAULT ''"); + + RunnableFactory.createNew("DB Version 16->17", new AbsRunnable() { + @Override + public void run() { + try { + Map> allGeoInfo = getAllGeoInfo(); + + String sql = "UPDATE " + tableName + " SET " + + Col.IP + "=?, " + + Col.IP_HASH + "=? " + + "WHERE " + Col.IP + "=?"; + executeBatch(new ExecStatement(sql) { + @Override + public void prepare(PreparedStatement statement) throws SQLException { + for (List geoInfos : allGeoInfo.values()) { + for (GeoInfo geoInfo : geoInfos) { + try { + GeoInfo updatedInfo = new GeoInfo( + geoInfo.getIp(), + geoInfo.getGeolocation(), + geoInfo.getLastUsed() + ); + statement.setString(1, updatedInfo.getIp()); + statement.setString(2, updatedInfo.getIpHash()); + statement.setString(3, geoInfo.getIp()); + } catch (UnsupportedEncodingException | NoSuchAlgorithmException e) { + if (Settings.DEV_MODE.isTrue()) { + Log.toLog(this.getClass(), e); + } + } + } + } + } + }); + } catch (SQLException e) { + e.printStackTrace(); + } + } + }); + } + public List getGeoInfo(UUID uuid) throws SQLException { String sql = "SELECT DISTINCT * FROM " + tableName + " WHERE " + Col.USER_ID + "=" + usersTable.statementSelectID; @@ -80,8 +131,9 @@ public class GeoInfoTable extends UserIDTable { while (set.next()) { String ip = set.getString(Col.IP.get()); String geolocation = set.getString(Col.GEOLOCATION.get()); + String ipHash = set.getString(Col.IP_HASH.get()); long lastUsed = set.getLong(Col.LAST_USED.get()); - geoInfo.add(new GeoInfo(ip, geolocation, lastUsed)); + geoInfo.add(new GeoInfo(ip, geolocation, lastUsed, ipHash)); } return geoInfo; } @@ -92,7 +144,7 @@ public class GeoInfoTable extends UserIDTable { String sql = "UPDATE " + tableName + " SET " + Col.LAST_USED + "=?" + " WHERE " + Col.USER_ID + "=" + usersTable.statementSelectID + - " AND " + Col.IP + "=?" + + " AND " + Col.IP_HASH + "=?" + " AND " + Col.GEOLOCATION + "=?"; execute(new ExecStatement(sql) { @@ -100,7 +152,7 @@ public class GeoInfoTable extends UserIDTable { public void prepare(PreparedStatement statement) throws SQLException { statement.setLong(1, info.getLastUsed()); statement.setString(2, uuid.toString()); - statement.setString(3, info.getIp()); + statement.setString(3, info.getIpHash()); statement.setString(4, info.getGeolocation()); } }); @@ -120,8 +172,9 @@ public class GeoInfoTable extends UserIDTable { public void prepare(PreparedStatement statement) throws SQLException { statement.setString(1, uuid.toString()); statement.setString(2, info.getIp()); - statement.setString(3, info.getGeolocation()); - statement.setLong(4, info.getLastUsed()); + statement.setString(3, info.getIpHash()); + statement.setString(4, info.getGeolocation()); + statement.setLong(5, info.getLastUsed()); } }); } @@ -154,6 +207,7 @@ public class GeoInfoTable extends UserIDTable { Col.IP + ", " + Col.GEOLOCATION + ", " + Col.LAST_USED + ", " + + Col.IP_HASH + ", " + usersUUIDColumn + " FROM " + tableName + " INNER JOIN " + usersTable + " on " + usersIDColumn + "=" + Col.USER_ID; @@ -169,8 +223,9 @@ public class GeoInfoTable extends UserIDTable { String ip = set.getString(Col.IP.get()); String geolocation = set.getString(Col.GEOLOCATION.get()); + String ipHash = set.getString(Col.IP_HASH.get()); long lastUsed = set.getLong(Col.LAST_USED.get()); - userGeoInfo.add(new GeoInfo(ip, geolocation, lastUsed)); + userGeoInfo.add(new GeoInfo(ip, geolocation, lastUsed, ipHash)); geoLocations.put(uuid, userGeoInfo); } @@ -203,9 +258,40 @@ public class GeoInfoTable extends UserIDTable { }); } + public void insertAllGeoInfo(Map> allIPsAndGeolocations) throws SQLException { + if (Verify.isEmpty(allIPsAndGeolocations)) { + return; + } + + executeBatch(new ExecStatement(insertStatement) { + @Override + public void prepare(PreparedStatement statement) throws SQLException { + // Every User + for (UUID uuid : allIPsAndGeolocations.keySet()) { + // Every GeoInfo + for (GeoInfo info : allIPsAndGeolocations.get(uuid)) { + String ip = info.getIp(); + String ipHash = info.getIpHash(); + String geoLocation = info.getGeolocation(); + long lastUsed = info.getLastUsed(); + + statement.setString(1, uuid.toString()); + statement.setString(2, ip); + statement.setString(3, ipHash); + statement.setString(4, geoLocation); + statement.setLong(5, lastUsed); + + statement.addBatch(); + } + } + } + }); + } + public enum Col implements Column { USER_ID(UserIDTable.Col.USER_ID.get()), IP("ip"), + IP_HASH("ip_hash"), GEOLOCATION("geolocation"), LAST_USED("last_used"); @@ -225,32 +311,4 @@ public class GeoInfoTable extends UserIDTable { return column; } } - - public void insertAllGeoInfo(Map> allIPsAndGeolocations) throws SQLException { - if (Verify.isEmpty(allIPsAndGeolocations)) { - return; - } - - executeBatch(new ExecStatement(insertStatement) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - // Every User - for (UUID uuid : allIPsAndGeolocations.keySet()) { - // Every GeoInfo - for (GeoInfo info : allIPsAndGeolocations.get(uuid)) { - String ip = info.getIp(); - String geoLocation = info.getGeolocation(); - long lastUsed = info.getLastUsed(); - - statement.setString(1, uuid.toString()); - statement.setString(2, ip); - statement.setString(3, geoLocation); - statement.setLong(4, lastUsed); - - statement.addBatch(); - } - } - } - }); - } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/importing/importers/Importer.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/importing/importers/Importer.java index 51bb8d27a..fadfac3e4 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/importing/importers/Importer.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/importing/importers/Importer.java @@ -23,6 +23,8 @@ import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.utilities.Verify; import com.google.common.collect.ImmutableMap; +import java.io.UnsupportedEncodingException; +import java.security.NoSuchAlgorithmException; import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -228,7 +230,11 @@ public abstract class Importer { return userImportData.getIps().parallelStream() .map(ip -> { String geoLoc = GeolocationCache.getCountry(ip); - return new GeoInfo(ip, geoLoc, date); + try { + return new GeoInfo(ip, geoLoc, date); + } catch (UnsupportedEncodingException | NoSuchAlgorithmException e) { + throw new IllegalArgumentException(e); + } }).collect(Collectors.toList()); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/IPUpdateProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/IPUpdateProcessor.java index 420c03243..caaae6b43 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/IPUpdateProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/IPUpdateProcessor.java @@ -13,6 +13,8 @@ import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plugin.api.Check; import com.djrapitops.plugin.api.utility.log.Log; +import java.io.UnsupportedEncodingException; +import java.security.NoSuchAlgorithmException; import java.util.UUID; /** @@ -38,7 +40,7 @@ public class IPUpdateProcessor implements CriticalRunnable { String country = GeolocationCache.getCountry(ip); try { Database.getActive().save().geoInfo(uuid, new GeoInfo(ip, country, time)); - } catch (DBException e) { + } catch (DBException | UnsupportedEncodingException | NoSuchAlgorithmException e) { Log.toLog(this.getClass(), e); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/FormatUtils.java b/Plan/src/main/java/com/djrapitops/plan/utilities/FormatUtils.java index df7aefc2d..70e77a9be 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/FormatUtils.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/FormatUtils.java @@ -276,10 +276,13 @@ public class FormatUtils { } public static String formatIP(String ip) { + if ("localhost".equals(ip)) { + return ip; + } StringBuilder b = new StringBuilder(); int i = 0; for (String part : ip.split("\\.")) { - if (i >= 3) { + if (i >= 2) { break; } @@ -288,7 +291,7 @@ public class FormatUtils { i++; } - return b.append("xx").toString(); + return b.append("xx.xx").toString(); } /** diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/SHA256Hash.java b/Plan/src/main/java/com/djrapitops/plan/utilities/SHA256Hash.java new file mode 100644 index 000000000..0335912f6 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/SHA256Hash.java @@ -0,0 +1,21 @@ +package com.djrapitops.plan.utilities; + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Base64; + +public class SHA256Hash { + + private final String original; + + public SHA256Hash(String original) { + this.original = original; + } + + public String create() throws NoSuchAlgorithmException, UnsupportedEncodingException { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + digest.update(original.getBytes("UTF-8")); + return Base64.getEncoder().encodeToString(digest.digest()); + } +} diff --git a/Plan/src/test/java/com/djrapitops/plan/system/database/databases/SQLiteTest.java b/Plan/src/test/java/com/djrapitops/plan/system/database/databases/SQLiteTest.java index 939a38bb6..6364ce644 100644 --- a/Plan/src/test/java/com/djrapitops/plan/system/database/databases/SQLiteTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/system/database/databases/SQLiteTest.java @@ -22,6 +22,7 @@ import com.djrapitops.plan.system.processing.processors.player.RegisterProcessor import com.djrapitops.plan.utilities.Base64Util; import com.djrapitops.plan.utilities.ManageUtils; import com.djrapitops.plan.utilities.MiscUtils; +import com.djrapitops.plan.utilities.SHA256Hash; import com.djrapitops.plan.utilities.analysis.MathUtils; import com.djrapitops.plugin.StaticHolder; import com.djrapitops.plugin.api.utility.log.Log; @@ -36,8 +37,10 @@ import utilities.TestConstants; import utilities.TestErrorManager; import utilities.mocks.SystemMockUtil; +import java.io.UnsupportedEncodingException; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; +import java.security.NoSuchAlgorithmException; import java.sql.SQLException; import java.util.*; @@ -258,7 +261,7 @@ public class SQLiteTest { String expectedGeoLoc = "TestLocation"; long time = MiscUtils.getTime(); - GeoInfo expected = new GeoInfo(expectedIP, expectedGeoLoc, time); + GeoInfo expected = new GeoInfo(expectedIP, expectedGeoLoc, time, "3"); geoInfoTable.saveGeoInfo(playerUUID, expected); geoInfoTable.saveGeoInfo(playerUUID, expected); commitTest(); @@ -563,7 +566,7 @@ public class SQLiteTest { sessionsTable.saveSession(playerUUID, session); nicknamesTable.saveUserName(playerUUID, "TestNick"); - geoInfoTable.saveGeoInfo(playerUUID, new GeoInfo("1.2.3.4", "TestLoc", 223456789L)); + geoInfoTable.saveGeoInfo(playerUUID, new GeoInfo("1.2.3.4", "TestLoc", 223456789L, "3")); actionsTable.insertAction(playerUUID, new Action(1324L, Actions.FIRST_SESSION, "Add")); assertTrue(usersTable.isRegistered(playerUUID)); @@ -579,7 +582,7 @@ public class SQLiteTest { } @Test - public void testRemovalEverything() throws SQLException, DBException { + public void testRemovalEverything() throws SQLException, DBException, UnsupportedEncodingException, NoSuchAlgorithmException { UserInfoTable userInfoTable = db.getUserInfoTable(); UsersTable usersTable = db.getUsersTable(); SessionsTable sessionsTable = db.getSessionsTable(); @@ -608,7 +611,7 @@ public class SQLiteTest { assertTrue(securityTable.getUsers().isEmpty()); } - private void saveAllData(SQLDB database) throws SQLException { + private void saveAllData(SQLDB database) throws SQLException, UnsupportedEncodingException, NoSuchAlgorithmException { System.out.println("Saving all possible data to the Database.."); UserInfoTable userInfoTable = database.getUserInfoTable(); UsersTable usersTable = database.getUsersTable(); @@ -632,7 +635,8 @@ public class SQLiteTest { sessionsTable.saveSession(playerUUID, session); nicknamesTable.saveUserName(playerUUID, "TestNick"); - geoInfoTable.saveGeoInfo(playerUUID, new GeoInfo("1.2.3.4", "TestLoc", 223456789L)); + geoInfoTable.saveGeoInfo(playerUUID, new GeoInfo("1.2.3.4", "TestLoc", 223456789L, + new SHA256Hash("1.2.3.4").create())); actionsTable.insertAction(playerUUID, new Action(1324L, Actions.FIRST_SESSION, "Add")); assertTrue(usersTable.isRegistered(playerUUID)); @@ -756,7 +760,7 @@ public class SQLiteTest { } @Test - public void testBackupAndRestore() throws SQLException, DBInitException { + public void testBackupAndRestore() throws SQLException, DBInitException, UnsupportedEncodingException, NoSuchAlgorithmException { System.out.println("- Creating Backup Database -"); SQLiteDB backup = new SQLiteDB("debug-backup" + MiscUtils.getTime()); backup.init(); @@ -894,7 +898,7 @@ public class SQLiteTest { } @Test - public void testWorldTableGetWorldNamesNoException() throws SQLException { + public void testWorldTableGetWorldNamesNoException() throws SQLException, UnsupportedEncodingException, NoSuchAlgorithmException { saveAllData(db); Set worldNames = db.getWorldTable().getWorldNames(TestConstants.SERVER_UUID); assertEquals(new HashSet<>(worlds), worldNames); @@ -924,11 +928,11 @@ public class SQLiteTest { usersTable.registerUser(secondUuid, 0, ""); usersTable.registerUser(thirdUuid, 0, ""); - geoInfoTable.saveGeoInfo(firstUuid, new GeoInfo("-", "Test1", 0)); - GeoInfo secondInfo = new GeoInfo("-", "Test2", 5); + geoInfoTable.saveGeoInfo(firstUuid, new GeoInfo("-", "Test1", 0, "3")); + GeoInfo secondInfo = new GeoInfo("-", "Test2", 5, "3"); geoInfoTable.saveGeoInfo(firstUuid, secondInfo); - geoInfoTable.saveGeoInfo(secondUuid, new GeoInfo("-", "Test3", 0)); - geoInfoTable.saveGeoInfo(thirdUuid, new GeoInfo("-", "Test4", 0)); + geoInfoTable.saveGeoInfo(secondUuid, new GeoInfo("-", "Test3", 0, "3")); + geoInfoTable.saveGeoInfo(thirdUuid, new GeoInfo("-", "Test4", 0, "3")); List geolocations = geoInfoTable.getNetworkGeolocations(); System.out.println(geolocations); diff --git a/Plan/src/test/java/com/djrapitops/plan/utilities/FormatUtilsTest.java b/Plan/src/test/java/com/djrapitops/plan/utilities/FormatUtilsTest.java index ac4e2e1fb..87c853d10 100644 --- a/Plan/src/test/java/com/djrapitops/plan/utilities/FormatUtilsTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/utilities/FormatUtilsTest.java @@ -161,7 +161,7 @@ public class FormatUtilsTest { String ip = "1.2.3.4"; String ip2 = "1.2.3.26"; String ip3 = "1.2.3.235"; - String expected = "1.2.3.xx"; + String expected = "1.2.xx.xx"; assertEquals(expected, FormatUtils.formatIP(ip)); assertEquals(expected, FormatUtils.formatIP(ip2)); diff --git a/Plan/src/test/java/com/djrapitops/plan/utilities/SHA256HashTest.java b/Plan/src/test/java/com/djrapitops/plan/utilities/SHA256HashTest.java new file mode 100644 index 000000000..4af7d88e8 --- /dev/null +++ b/Plan/src/test/java/com/djrapitops/plan/utilities/SHA256HashTest.java @@ -0,0 +1,19 @@ +package com.djrapitops.plan.utilities; + +import org.junit.Test; + +import java.io.UnsupportedEncodingException; +import java.security.NoSuchAlgorithmException; + +import static org.junit.Assert.assertEquals; + +public class SHA256HashTest { + + @Test + public void sameStringReturnsSameHash() throws UnsupportedEncodingException, NoSuchAlgorithmException { + String expected = new SHA256Hash("1.3.4.5").create(); + String result = new SHA256Hash("1.3.4.5").create(); + assertEquals(expected, result); + } + +} \ No newline at end of file From b5cf501010afb271cc3642e3e860da2fc3445770 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Thu, 24 May 2018 14:57:12 +0300 Subject: [PATCH 25/33] Enabled Geolocation setting on Bungee and Bukkit, Version bump to 4.3.0 --- Plan/src/main/java/com/djrapitops/plan/PlanSponge.java | 2 +- .../com/djrapitops/plan/system/cache/GeolocationCache.java | 3 +-- .../system/processing/processors/player/IPUpdateProcessor.java | 3 +-- .../plan/system/settings/network/NetworkSettings.java | 3 ++- Plan/src/main/resources/bungee.yml | 2 +- Plan/src/main/resources/bungeeconfig.yml | 1 + Plan/src/main/resources/config.yml | 1 + Plan/src/main/resources/plugin.yml | 2 +- 8 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java b/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java index d9ff71cda..5f9fa4ee0 100644 --- a/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java +++ b/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java @@ -23,7 +23,7 @@ import org.spongepowered.api.plugin.Plugin; import java.io.File; import java.io.InputStream; -@Plugin(id = "plan", name = "Plan", version = "4.2.1", description = "Player Analytics Plugin by Rsl1122", authors = {"Rsl1122"}) +@Plugin(id = "plan", name = "Plan", version = "4.3.0", description = "Player Analytics Plugin by Rsl1122", authors = {"Rsl1122"}) public class PlanSponge extends SpongePlugin implements PlanPlugin { @Inject diff --git a/Plan/src/main/java/com/djrapitops/plan/system/cache/GeolocationCache.java b/Plan/src/main/java/com/djrapitops/plan/system/cache/GeolocationCache.java index d0825e32d..29b1dd6cb 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/cache/GeolocationCache.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/cache/GeolocationCache.java @@ -4,7 +4,6 @@ import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.system.SubSystem; import com.djrapitops.plan.system.file.FileSystem; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.Check; import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.utilities.Verify; import com.google.common.cache.Cache; @@ -47,7 +46,7 @@ public class GeolocationCache implements SubSystem { @Override public void enable() throws EnableException { geolocationDB = new File(FileSystem.getDataFolder(), "GeoIP.dat"); - if (!Check.isSpongeAvailable() || Settings.DATA_GEOLOCATIONS.isTrue()) { + if (Settings.DATA_GEOLOCATIONS.isTrue()) { try { GeolocationCache.checkDB(); } catch (UnknownHostException e) { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/IPUpdateProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/IPUpdateProcessor.java index caaae6b43..7bebbaea4 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/IPUpdateProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/IPUpdateProcessor.java @@ -10,7 +10,6 @@ import com.djrapitops.plan.system.cache.GeolocationCache; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.processing.CriticalRunnable; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.Check; import com.djrapitops.plugin.api.utility.log.Log; import java.io.UnsupportedEncodingException; @@ -36,7 +35,7 @@ public class IPUpdateProcessor implements CriticalRunnable { @Override public void run() { - if (!Check.isSpongeAvailable() || Settings.DATA_GEOLOCATIONS.isTrue()) { + if (Settings.DATA_GEOLOCATIONS.isTrue()) { String country = GeolocationCache.getCountry(ip); try { Database.getActive().save().geoInfo(uuid, new GeoInfo(ip, country, time)); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettings.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettings.java index d42a7efa3..3338e8568 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettings.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettings.java @@ -147,7 +147,8 @@ public class NetworkSettings { Settings.MAX_PLAYERS_PLAYERS_PAGE, Settings.PLAYERTABLE_FOOTER, Settings.FORMAT_DATE_RECENT_DAYS, Settings.FORMAT_DATE_RECENT_DAYS_PATTERN, Settings.FORMAT_DATE_CLOCK, Settings.FORMAT_DATE_NO_SECONDS, Settings.FORMAT_DATE_FULL, Settings.DISPLAY_PLAYER_IPS, Settings.ACTIVE_LOGIN_THRESHOLD, - Settings.ACTIVE_PLAY_THRESHOLD, Settings.DISPLAY_GAPS_IN_GRAPH_DATA, Settings.AFK_THRESHOLD_MINUTES + Settings.ACTIVE_PLAY_THRESHOLD, Settings.DISPLAY_GAPS_IN_GRAPH_DATA, Settings.AFK_THRESHOLD_MINUTES, + Settings.DATA_GEOLOCATIONS }; Log.debug("NetworkSettings: Adding Config Values.."); for (Settings setting : sameStrings) { diff --git a/Plan/src/main/resources/bungee.yml b/Plan/src/main/resources/bungee.yml index 50e65696b..4c7a06885 100644 --- a/Plan/src/main/resources/bungee.yml +++ b/Plan/src/main/resources/bungee.yml @@ -1,4 +1,4 @@ name: Plan author: Rsl1122 main: com.djrapitops.plan.PlanBungee -version: 4.2.0-b1 \ No newline at end of file +version: 4.3.0 \ No newline at end of file diff --git a/Plan/src/main/resources/bungeeconfig.yml b/Plan/src/main/resources/bungeeconfig.yml index 459f24239..3c1f1954d 100644 --- a/Plan/src/main/resources/bungeeconfig.yml +++ b/Plan/src/main/resources/bungeeconfig.yml @@ -65,6 +65,7 @@ Data: Commands: LogUnknownCommands: false CombineCommandAliases: true + Geolocations: true # ----------------------------------------------------- Customization: UseServerTime: true diff --git a/Plan/src/main/resources/config.yml b/Plan/src/main/resources/config.yml index 4e102d8f5..06055feb5 100644 --- a/Plan/src/main/resources/config.yml +++ b/Plan/src/main/resources/config.yml @@ -79,6 +79,7 @@ Data: Commands: LogUnknownCommands: false CombineCommandAliases: true + Geolocations: true # ----------------------------------------------------- Customization: UseServerTime: true diff --git a/Plan/src/main/resources/plugin.yml b/Plan/src/main/resources/plugin.yml index d7d70ff21..dc914b096 100644 --- a/Plan/src/main/resources/plugin.yml +++ b/Plan/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: Plan author: Rsl1122 main: com.djrapitops.plan.Plan -version: 4.2.0-b1 +version: 4.3.0 softdepend: - EssentialsX - Towny From efb3c6ef866862770175a4d4b6c2ba1bd12bfe36 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Thu, 24 May 2018 14:57:29 +0300 Subject: [PATCH 26/33] Disabled rest of the update system --- Plan/dependency-reduced-pom.xml | 14 +++++++++----- .../plan/command/commands/UpdateCommand.java | 3 ++- .../plan/system/update/VersionCheckSystem.java | 6 ++++-- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Plan/dependency-reduced-pom.xml b/Plan/dependency-reduced-pom.xml index 30e597272..8090dff0b 100644 --- a/Plan/dependency-reduced-pom.xml +++ b/Plan/dependency-reduced-pom.xml @@ -174,7 +174,11 @@ org.slf4j - asm-all + asm + org.ow2.asm + + + asm-commons org.ow2.asm @@ -313,10 +317,6 @@ flow-noise com.flowpowered - - asm - org.ow2.asm - slf4j-api org.slf4j @@ -325,6 +325,10 @@ jsr305 com.google.code.findbugs + + asm + org.ow2.asm + gson com.google.code.gson diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/UpdateCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/UpdateCommand.java index 10d2371be..a12ffd7ea 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/UpdateCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/UpdateCommand.java @@ -112,7 +112,8 @@ public class UpdateCommand extends CommandNode { sender.sendMessage("Checking that all servers are online.."); if (!checkNetworkStatus(sender)) { sender.sendMessage("§cNot all servers were online or accessible, you can still update available servers using /plan -update -force"); - if (args.length > 1 && "-force".equals(args[1])) { + // If -force, continue, otherwise return. + if (args.length < 2 || !"-force".equals(args[1])) { return; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java index b52f9f21c..bf6465161 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java @@ -57,8 +57,10 @@ public class VersionCheckSystem implements SubSystem { if (Version.isNewVersionAvailable(new Version(currentVersion), newestVersion.getVersion())) { newVersionAvailable = newestVersion; String notification = - "New Release (" + newestVersion.getVersion().toString() + ") is available and can be updated " + - "to using update subcommand." + (newestVersion.isRelease() ? "" : " This is a DEV release."); + "New Release (" + newestVersion.getVersion().toString() + ") is available " + +// "and can be updated to using update subcommand." + + newestVersion.getChangeLogUrl() + + (newestVersion.isRelease() ? "" : " This is a DEV release."); Log.infoColor("§a----------------------------------------"); Log.infoColor("§a" + notification); Log.infoColor("§a----------------------------------------"); From ecd56a1bf79409c9a96f873a08017906930adeca Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Thu, 24 May 2018 15:22:28 +0300 Subject: [PATCH 27/33] Fixed #572 GP Data erasure (Removed calls & Added delays) Addresses https://github.com/TechFortress/GriefPrevention/issues/279 --- Plan/dependency-reduced-pom.xml | 18 +++++++++--------- Plan/pom.xml | 4 ++-- .../info/PlayerPageUpdateProcessor.java | 18 +++++++++++++++--- PlanPluginBridge/pom.xml | 4 ++-- .../griefprevention/GriefPreventionData.java | 4 ---- .../plus/GriefPreventionPlusData.java | 4 ---- 6 files changed, 28 insertions(+), 24 deletions(-) diff --git a/Plan/dependency-reduced-pom.xml b/Plan/dependency-reduced-pom.xml index 8090dff0b..9951979db 100644 --- a/Plan/dependency-reduced-pom.xml +++ b/Plan/dependency-reduced-pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.djrapitops Plan - 4.2.0-SNAPSHOT + 4.3.0-SNAPSHOT ${basedir}/src/main/java ${basedir}/src/test/java @@ -174,11 +174,11 @@ org.slf4j - asm - org.ow2.asm + asm + org.ow2.asm - - asm-commons + + asm-commons org.ow2.asm @@ -325,10 +325,10 @@ jsr305 com.google.code.findbugs - - asm - org.ow2.asm - + + asm + org.ow2.asm + gson com.google.code.gson diff --git a/Plan/pom.xml b/Plan/pom.xml index 75e098a40..545fc06c2 100644 --- a/Plan/pom.xml +++ b/Plan/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.djrapitops Plan - 4.2.0-SNAPSHOT + 4.3.0-SNAPSHOT jar @@ -35,7 +35,7 @@ com.djrapitops PlanPluginBridge - 4.2.0-SNAPSHOT + 4.3.0-SNAPSHOT diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/info/PlayerPageUpdateProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/info/PlayerPageUpdateProcessor.java index df386e77d..19fb85ed3 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/info/PlayerPageUpdateProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/info/PlayerPageUpdateProcessor.java @@ -2,6 +2,9 @@ package com.djrapitops.plan.system.processing.processors.info; import com.djrapitops.plan.system.info.InfoSystem; import com.djrapitops.plan.system.info.connection.WebExceptionLogger; +import com.djrapitops.plugin.api.TimeAmount; +import com.djrapitops.plugin.task.AbsRunnable; +import com.djrapitops.plugin.task.RunnableFactory; import java.util.UUID; @@ -15,8 +18,17 @@ public class PlayerPageUpdateProcessor implements Runnable { @Override public void run() { - WebExceptionLogger.logIfOccurs(this.getClass(), - () -> InfoSystem.getInstance().generateAndCachePlayerPage(uuid) - ); + RunnableFactory.createNew("Generate Inspect page: " + uuid, new AbsRunnable() { + @Override + public void run() { + try { + WebExceptionLogger.logIfOccurs(PlayerPageUpdateProcessor.class, + () -> InfoSystem.getInstance().generateAndCachePlayerPage(uuid) + ); + } finally { + cancel(); + } + } + }).runTaskLaterAsynchronously(TimeAmount.SECOND.ticks() * 20); } } diff --git a/PlanPluginBridge/pom.xml b/PlanPluginBridge/pom.xml index ca703ea83..fde602e3a 100644 --- a/PlanPluginBridge/pom.xml +++ b/PlanPluginBridge/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.djrapitops PlanPluginBridge - 4.2.0-SNAPSHOT + 4.3.0-SNAPSHOT jar ${project.groupId}:${project.artifactId} @@ -75,7 +75,7 @@ com.djrapitops Plan - 4.2.0-SNAPSHOT + 4.3.0-SNAPSHOT provided diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/griefprevention/GriefPreventionData.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/griefprevention/GriefPreventionData.java index 971672bdf..002453587 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/griefprevention/GriefPreventionData.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/griefprevention/GriefPreventionData.java @@ -13,7 +13,6 @@ import com.djrapitops.plan.utilities.analysis.MathUtils; import com.djrapitops.plugin.utilities.FormatUtils; import me.ryanhamshire.GriefPrevention.Claim; import me.ryanhamshire.GriefPrevention.DataStore; -import me.ryanhamshire.GriefPrevention.PlayerData; import java.util.*; import java.util.stream.Collectors; @@ -43,15 +42,12 @@ public class GriefPreventionData extends PluginData { claim -> FormatUtils.formatLocation(claim.getGreaterBoundaryCorner()), Claim::getArea) ); - PlayerData data = dataStore.getPlayerData(uuid); - int blocks = data.getAccruedClaimBlocks() + data.getBonusClaimBlocks() + dataStore.getGroupBonusBlocks(uuid); String softMuted = dataStore.isSoftMuted(uuid) ? "Yes" : "No"; long totalArea = MathUtils.sumLong(claims.values().stream().map(i -> (long) i)); inspectContainer.addValue(getWithIcon("SoftMuted", "bell-slash-o", "deep-orange"), softMuted); inspectContainer.addValue(getWithIcon("Claims", "map-marker", "blue-grey"), claims.size()); inspectContainer.addValue(getWithIcon("Claimed Area", "map-o", "light-green"), totalArea); - inspectContainer.addValue(getWithIcon("Claim Blocks Available", "map-o", "light-green"), blocks); TableContainer claimsTable = new TableContainer(getWithIcon("Claim", "map-marker"), getWithIcon("Area", "map-o")); claimsTable.setColor("blue-grey"); diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/griefprevention/plus/GriefPreventionPlusData.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/griefprevention/plus/GriefPreventionPlusData.java index 37a14527e..3045d7ce9 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/griefprevention/plus/GriefPreventionPlusData.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/griefprevention/plus/GriefPreventionPlusData.java @@ -13,7 +13,6 @@ import com.djrapitops.plan.utilities.analysis.MathUtils; import com.djrapitops.plugin.utilities.FormatUtils; import net.kaikk.mc.gpp.Claim; import net.kaikk.mc.gpp.DataStore; -import net.kaikk.mc.gpp.PlayerData; import java.util.*; import java.util.stream.Collectors; @@ -43,13 +42,10 @@ public class GriefPreventionPlusData extends PluginData { claim -> FormatUtils.formatLocation(claim.getGreaterBoundaryCorner()), Claim::getArea) ); - PlayerData data = dataStore.getPlayerData(uuid); - int blocks = data.getAccruedClaimBlocks() + data.getBonusClaimBlocks(); long totalArea = MathUtils.sumLong(claims.values().stream().map(i -> (long) i)); inspectContainer.addValue(getWithIcon("Claims", "map-marker", "blue-grey"), claims.size()); inspectContainer.addValue(getWithIcon("Claimed Area", "map-o", "light-green"), totalArea); - inspectContainer.addValue(getWithIcon("Claim Blocks Available", "map-o", "light-green"), blocks); TableContainer claimsTable = new TableContainer(getWithIcon("Claim", "map-marker"), getWithIcon("Area", "map-o")); claimsTable.setColor("blue-grey"); From 70e70ee958dae807a58400ba8863c4a4b644ed88 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Thu, 24 May 2018 15:48:51 +0300 Subject: [PATCH 28/33] Log file cleaning #510 --- .../plan/system/file/FileSystem.java | 7 +- .../plan/system/settings/Settings.java | 1 + .../settings/network/NetworkSettings.java | 69 +++++++++++++------ .../system/tasks/LogsFolderCleanTask.java | 54 +++++++++++++++ Plan/src/main/resources/bungeeconfig.yml | 1 + Plan/src/main/resources/config.yml | 1 + 6 files changed, 110 insertions(+), 23 deletions(-) create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/tasks/LogsFolderCleanTask.java diff --git a/Plan/src/main/java/com/djrapitops/plan/system/file/FileSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/file/FileSystem.java index 953c2277f..affecc907 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/file/FileSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/file/FileSystem.java @@ -8,7 +8,11 @@ import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.SubSystem; +import com.djrapitops.plan.system.tasks.LogsFolderCleanTask; import com.djrapitops.plan.utilities.file.FileUtil; +import com.djrapitops.plugin.api.TimeAmount; +import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.task.RunnableFactory; import com.djrapitops.plugin.utilities.Verify; import java.io.File; @@ -63,10 +67,11 @@ public class FileSystem implements SubSystem { if (configFile.exists()) { configFile.createNewFile(); } + RunnableFactory.createNew(new LogsFolderCleanTask(Log.getLogsFolder())) + .runTaskLaterAsynchronously(TimeAmount.SECOND.ticks() * 30L); } catch (IOException e) { throw new EnableException("Failed to create config.yml", e); } - } @Override diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java index a4fc77b0b..3dee98387 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java @@ -50,6 +50,7 @@ public enum Settings { MAX_PLAYERS("Customization.Display.MaxPlayers"), MAX_PLAYERS_PLAYERS_PAGE("Customization.Display.MaxPlayersPlayersPage"), AFK_THRESHOLD_MINUTES("Data.AFKThresholdMinutes"), + KEEP_LOGS_DAYS("Plugin.KeepLogsForXDays"), // String DEBUG("Plugin.Debug"), diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettings.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettings.java index 3338e8568..2424cd46c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettings.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettings.java @@ -21,6 +21,8 @@ import java.util.Map; import java.util.Optional; import java.util.UUID; +import static com.djrapitops.plan.system.settings.Settings.*; + /** * Class for managing Config setting transfer from Bungee to Bukkit servers. * @@ -36,7 +38,7 @@ public class NetworkSettings { return; } - if (Settings.BUNGEE_OVERRIDE_STANDALONE_MODE.isTrue() || Settings.BUNGEE_COPY_CONFIG.isFalse()) { + if (BUNGEE_OVERRIDE_STANDALONE_MODE.isTrue() || BUNGEE_COPY_CONFIG.isFalse()) { return; } @@ -134,27 +136,50 @@ public class NetworkSettings { private Map getConfigValues() throws DBException { Log.debug("NetworkSettings: Loading Config Values.."); Map configValues = new HashMap<>(); - addConfigValue(configValues, Settings.DB_TYPE, "mysql"); + addConfigValue(configValues, DB_TYPE, "mysql"); Settings[] sameStrings = new Settings[]{ - Settings.DB_HOST, Settings.DB_USER, Settings.DB_PASS, - Settings.DB_DATABASE, Settings.DB_LAUNCH_OPTIONS, - Settings.FORMAT_DECIMALS, Settings.FORMAT_SECONDS, - Settings.FORMAT_DAY, Settings.FORMAT_DAYS, Settings.FORMAT_HOURS, - Settings.FORMAT_MINUTES, Settings.FORMAT_MONTHS, Settings.FORMAT_MONTH, - Settings.FORMAT_YEAR, Settings.FORMAT_YEARS, Settings.FORMAT_ZERO_SECONDS, - Settings.USE_SERVER_TIME, Settings.DISPLAY_SESSIONS_AS_TABLE, Settings.APPEND_WORLD_PERC, - Settings.ORDER_WORLD_PIE_BY_PERC, Settings.MAX_SESSIONS, Settings.MAX_PLAYERS, - Settings.MAX_PLAYERS_PLAYERS_PAGE, Settings.PLAYERTABLE_FOOTER, Settings.FORMAT_DATE_RECENT_DAYS, - Settings.FORMAT_DATE_RECENT_DAYS_PATTERN, Settings.FORMAT_DATE_CLOCK, Settings.FORMAT_DATE_NO_SECONDS, - Settings.FORMAT_DATE_FULL, Settings.DISPLAY_PLAYER_IPS, Settings.ACTIVE_LOGIN_THRESHOLD, - Settings.ACTIVE_PLAY_THRESHOLD, Settings.DISPLAY_GAPS_IN_GRAPH_DATA, Settings.AFK_THRESHOLD_MINUTES, - Settings.DATA_GEOLOCATIONS + DB_HOST, + DB_USER, + DB_PASS, + DB_DATABASE, + DB_LAUNCH_OPTIONS, + FORMAT_DECIMALS, + FORMAT_SECONDS, + FORMAT_DAY, + FORMAT_DAYS, + FORMAT_HOURS, + FORMAT_MINUTES, + FORMAT_MONTHS, + FORMAT_MONTH, + FORMAT_YEAR, + FORMAT_YEARS, + FORMAT_ZERO_SECONDS, + USE_SERVER_TIME, + DISPLAY_SESSIONS_AS_TABLE, + APPEND_WORLD_PERC, + ORDER_WORLD_PIE_BY_PERC, + MAX_SESSIONS, + MAX_PLAYERS, + MAX_PLAYERS_PLAYERS_PAGE, + PLAYERTABLE_FOOTER, + FORMAT_DATE_RECENT_DAYS, + FORMAT_DATE_RECENT_DAYS_PATTERN, + FORMAT_DATE_CLOCK, + FORMAT_DATE_NO_SECONDS, + FORMAT_DATE_FULL, + DISPLAY_PLAYER_IPS, + ACTIVE_LOGIN_THRESHOLD, + ACTIVE_PLAY_THRESHOLD, + DISPLAY_GAPS_IN_GRAPH_DATA, + AFK_THRESHOLD_MINUTES, + DATA_GEOLOCATIONS, + KEEP_LOGS_DAYS }; Log.debug("NetworkSettings: Adding Config Values.."); for (Settings setting : sameStrings) { addConfigValue(configValues, setting, setting.toString()); } - addConfigValue(configValues, Settings.DB_PORT, Settings.DB_PORT.getNumber()); + addConfigValue(configValues, DB_PORT, DB_PORT.getNumber()); addServerSpecificValues(configValues); return configValues; } @@ -176,18 +201,18 @@ public class NetworkSettings { ServerSpecificSettings settings = Settings.serverSpecific(); for (UUID serverUUID : Database.getActive().fetch().getServerUUIDs()) { - String theme = settings.getString(serverUUID, Settings.THEME_BASE); - Integer port = settings.getInt(serverUUID, Settings.WEBSERVER_PORT); - String name = settings.getString(serverUUID, Settings.SERVER_NAME); + String theme = settings.getString(serverUUID, THEME_BASE); + Integer port = settings.getInt(serverUUID, WEBSERVER_PORT); + String name = settings.getString(serverUUID, SERVER_NAME); if (!Verify.isEmpty(theme)) { - addConfigValue(configValues, serverUUID, Settings.THEME_BASE, theme); + addConfigValue(configValues, serverUUID, THEME_BASE, theme); } if (port != null && port != 0) { - addConfigValue(configValues, serverUUID, Settings.WEBSERVER_PORT, port); + addConfigValue(configValues, serverUUID, WEBSERVER_PORT, port); } if (!Verify.isEmpty(name)) { - addConfigValue(configValues, serverUUID, Settings.SERVER_NAME, name); + addConfigValue(configValues, serverUUID, SERVER_NAME, name); } } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/LogsFolderCleanTask.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/LogsFolderCleanTask.java new file mode 100644 index 000000000..1bdd02b12 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/LogsFolderCleanTask.java @@ -0,0 +1,54 @@ +package com.djrapitops.plan.system.tasks; + +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plugin.api.TimeAmount; +import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.task.AbsRunnable; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Objects; + +/** + * Task in charge of removing old log files + * + * @author Rsl1122 + */ +public class LogsFolderCleanTask extends AbsRunnable { + + private final File folder; + + public LogsFolderCleanTask(File folder) { + super(LogsFolderCleanTask.class.getSimpleName()); + this.folder = folder; + } + + @Override + public void run() { + try { + if (!folder.exists() || folder.isFile()) { + return; + } + cleanFolder(); + } catch (NullPointerException ignore) { + /* Ignored - not supposed to occur. */ + } finally { + cancel(); + } + } + + private void cleanFolder() { + long now = System.currentTimeMillis(); + for (File file : Objects.requireNonNull(folder.listFiles())) { + long forDaysMs = Settings.KEEP_LOGS_DAYS.getNumber() * TimeAmount.DAY.ms(); + if (now - file.lastModified() > (forDaysMs > 0 ? forDaysMs : TimeAmount.DAY.ms())) { + try { + Files.delete(file.toPath()); + } catch (IOException e) { + Log.warn("Could not delete log file at: " + file.getAbsolutePath() + ", " + e.getMessage()); + } + } + } + } +} \ No newline at end of file diff --git a/Plan/src/main/resources/bungeeconfig.yml b/Plan/src/main/resources/bungeeconfig.yml index 3c1f1954d..367263b59 100644 --- a/Plan/src/main/resources/bungeeconfig.yml +++ b/Plan/src/main/resources/bungeeconfig.yml @@ -14,6 +14,7 @@ Plugin: Locale: default Allow-Update-Command: true Notify-About-DEV-Releases: false + KeepLogsForXDays: 7 # ----------------------------------------------------- # More information about SSL Certificate Settings: diff --git a/Plan/src/main/resources/config.yml b/Plan/src/main/resources/config.yml index 06055feb5..7fe8992c1 100644 --- a/Plan/src/main/resources/config.yml +++ b/Plan/src/main/resources/config.yml @@ -19,6 +19,7 @@ Plugin: CopyBungeeConfig: true Allow-Update-Command: true Notify-About-DEV-Releases: false + KeepLogsForXDays: 7 # ----------------------------------------------------- # More information about SSL Certificate Settings: From 5b23bddc04e1f133ebcb1939e3b265920fb59e6b Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Thu, 24 May 2018 15:49:22 +0300 Subject: [PATCH 29/33] Postponed PlaceholderAPI support due to unexpected NoClassDefFoundError --- .../main/java/com/djrapitops/pluginbridge/plan/Bridge.java | 4 ++-- .../pluginbridge/plan/placeholderapi/PlaceholderAPIHook.java | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Bridge.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Bridge.java index 3c8dd62a4..076bdbdb3 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Bridge.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Bridge.java @@ -88,8 +88,8 @@ public class Bridge { new RedProtectHook(h), new TownyHook(h), new VaultHook(h), - new ViaVersionHook(h), - new PlaceholderAPIHook(h) + new ViaVersionHook(h)//, +// new PlaceholderAPIHook(h) }; } } diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/placeholderapi/PlaceholderAPIHook.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/placeholderapi/PlaceholderAPIHook.java index 2ee7ed317..e4572a8a6 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/placeholderapi/PlaceholderAPIHook.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/placeholderapi/PlaceholderAPIHook.java @@ -5,10 +5,9 @@ import com.djrapitops.pluginbridge.plan.Hook; import me.clip.placeholderapi.PlaceholderAPI; /** - * A Class responsible for hooking to MCMMO and registering data sources. + * A Class responsible for hooking to PlaceholderAPI. * * @author Rsl1122 - * @since 3.2.1 */ public class PlaceholderAPIHook extends Hook { From 2274f9204e18e5b232422dae126bb4a0a993af30 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Thu, 24 May 2018 15:50:19 +0300 Subject: [PATCH 30/33] Updated PluginBridge jar --- ...e-4.2.0.jar => PlanPluginBridge-4.3.0.jar} | Bin 125201 -> 130733 bytes 1 file changed, 0 insertions(+), 0 deletions(-) rename PlanPluginBridge/{PlanPluginBridge-4.2.0.jar => PlanPluginBridge-4.3.0.jar} (77%) diff --git a/PlanPluginBridge/PlanPluginBridge-4.2.0.jar b/PlanPluginBridge/PlanPluginBridge-4.3.0.jar similarity index 77% rename from PlanPluginBridge/PlanPluginBridge-4.2.0.jar rename to PlanPluginBridge/PlanPluginBridge-4.3.0.jar index 785b36dc96ff28a00bac37d7c7f263522a7ea58b..214f1f3a9d3a0bced16819e4c274a9b4bfb2e3fe 100644 GIT binary patch delta 21722 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 s6=7UIkkJV!!y(kS?3xNZfn65? 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 exa1u`gdo%QFC` Date: Thu, 24 May 2018 15:59:51 +0300 Subject: [PATCH 31/33] Cleaning option for inactive players #507 --- .../system/database/databases/sql/SQLDB.java | 22 +++++++++++++++++++ .../plan/system/settings/Settings.java | 1 + .../settings/network/NetworkSettings.java | 3 ++- Plan/src/main/resources/bungeeconfig.yml | 1 + Plan/src/main/resources/config.yml | 1 + 5 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java index 328514f29..dd28c3101 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java @@ -1,11 +1,13 @@ package com.djrapitops.plan.system.database.databases.sql; +import com.djrapitops.plan.api.exceptions.database.DBException; import com.djrapitops.plan.api.exceptions.database.DBInitException; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.database.databases.operation.*; import com.djrapitops.plan.system.database.databases.sql.operation.*; import com.djrapitops.plan.system.database.databases.sql.tables.*; import com.djrapitops.plan.system.database.databases.sql.tables.move.Version8TransferTable; +import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plugin.api.TimeAmount; import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.task.AbsRunnable; @@ -15,6 +17,10 @@ import org.apache.commons.dbcp2.BasicDataSource; import java.sql.Connection; import java.sql.SQLException; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; /** * Class containing main logic for different data related save and load functionality. @@ -250,6 +256,22 @@ public abstract class SQLDB extends Database { private void clean() throws SQLException { tpsTable.clean(); transferTable.clean(); + + long now = System.currentTimeMillis(); + long keepActiveAfter = now - TimeAmount.DAY.ms() * Settings.KEEP_INACTIVE_PLAYERS_DAYS.getNumber(); + + List inactivePlayers = sessionsTable.getLastSeenForAllPlayers().entrySet().stream() + .filter(entry -> entry.getValue() > keepActiveAfter) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); + for (UUID uuid : inactivePlayers) { + try { + removeOps.player(uuid); + } catch (DBException e) { + Log.toLog(this.getClass().getName(), e); + } + } + Log.info("Removed data of " + inactivePlayers.size() + " players."); } public abstract Connection getConnection() throws SQLException; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java index 3dee98387..6ea6583bd 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java @@ -51,6 +51,7 @@ public enum Settings { MAX_PLAYERS_PLAYERS_PAGE("Customization.Display.MaxPlayersPlayersPage"), AFK_THRESHOLD_MINUTES("Data.AFKThresholdMinutes"), KEEP_LOGS_DAYS("Plugin.KeepLogsForXDays"), + KEEP_INACTIVE_PLAYERS_DAYS("Data.KeepInactivePlayerDataForDays"), // String DEBUG("Plugin.Debug"), diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettings.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettings.java index 2424cd46c..780613bf7 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettings.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettings.java @@ -173,7 +173,8 @@ public class NetworkSettings { DISPLAY_GAPS_IN_GRAPH_DATA, AFK_THRESHOLD_MINUTES, DATA_GEOLOCATIONS, - KEEP_LOGS_DAYS + KEEP_LOGS_DAYS, + KEEP_INACTIVE_PLAYERS_DAYS }; Log.debug("NetworkSettings: Adding Config Values.."); for (Settings setting : sameStrings) { diff --git a/Plan/src/main/resources/bungeeconfig.yml b/Plan/src/main/resources/bungeeconfig.yml index 367263b59..0e4be559d 100644 --- a/Plan/src/main/resources/bungeeconfig.yml +++ b/Plan/src/main/resources/bungeeconfig.yml @@ -67,6 +67,7 @@ Data: LogUnknownCommands: false CombineCommandAliases: true Geolocations: true + KeepInactivePlayerDataForDays: 180 # ----------------------------------------------------- Customization: UseServerTime: true diff --git a/Plan/src/main/resources/config.yml b/Plan/src/main/resources/config.yml index 7fe8992c1..be15fa519 100644 --- a/Plan/src/main/resources/config.yml +++ b/Plan/src/main/resources/config.yml @@ -81,6 +81,7 @@ Data: LogUnknownCommands: false CombineCommandAliases: true Geolocations: true + KeepInactivePlayerDataForDays: 180 # ----------------------------------------------------- Customization: UseServerTime: true From 11519ffc999501e0e3a3eace06a04aaf283a5b57 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Thu, 24 May 2018 16:30:18 +0300 Subject: [PATCH 32/33] Fix travis pluginbridge install --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index fc8755495..a10f3a28b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ before_install: - pwd - cd PlanPluginBridge - ls - - mvn install:install-file -Dfile=/home/travis/build/Rsl1122/Plan-PlayerAnalytics/PlanPluginBridge/PlanPluginBridge-4.2.0.jar -DpomFile=/home/travis/build/Rsl1122/Plan-PlayerAnalytics/PlanPluginBridge/pom.xml + - mvn install:install-file -Dfile=/home/travis/build/Rsl1122/Plan-PlayerAnalytics/PlanPluginBridge/PlanPluginBridge-4.3.0.jar -DpomFile=/home/travis/build/Rsl1122/Plan-PlayerAnalytics/PlanPluginBridge/pom.xml - cd ../Plan - ls install: From 8b67c73368cae9bfe19e4b82aed5073e63d716f6 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Thu, 24 May 2018 16:33:02 +0300 Subject: [PATCH 33/33] Attempt to fix iOS http auth --- .../com/djrapitops/plan/system/webserver/RequestHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java index f699040b7..2d1f9bf03 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java @@ -45,7 +45,7 @@ public class RequestHandler implements HttpHandler { Response response = responseHandler.getResponse(request); responseCode = response.getCode(); if (response instanceof PromptAuthorizationResponse) { - responseHeaders.set("WWW-Authenticate", "Basic realm=\"/\";"); + responseHeaders.set("WWW-Authenticate", "Basic realm=\"/\""); } response.setResponseHeaders(responseHeaders);