diff --git a/build.xml b/build.xml new file mode 100644 index 000000000..0ca80f539 --- /dev/null +++ b/build.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + Builds, tests, and runs the project Plan. + + + diff --git a/manifest.mf b/manifest.mf new file mode 100644 index 000000000..8e407f0a5 --- /dev/null +++ b/manifest.mf @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml new file mode 100644 index 000000000..25e9bb8ff --- /dev/null +++ b/nbproject/build-impl.xml @@ -0,0 +1,1419 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + Must select one file in the IDE or set profile.class + This target only works when run from inside the NetBeans IDE. + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + Must select some files in the IDE or set test.includes + + + + + Must select one file in the IDE or set run.class + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties new file mode 100644 index 000000000..65f9e2e02 --- /dev/null +++ b/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=4835e233 +build.xml.script.CRC32=f09b6a05 +build.xml.stylesheet.CRC32=8064a381@1.79.1.48 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=4835e233 +nbproject/build-impl.xml.script.CRC32=8797a4da +nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48 diff --git a/nbproject/private/config.properties b/nbproject/private/config.properties new file mode 100644 index 000000000..e69de29bb diff --git a/nbproject/private/private.properties b/nbproject/private/private.properties new file mode 100644 index 000000000..a11705098 --- /dev/null +++ b/nbproject/private/private.properties @@ -0,0 +1,10 @@ +compile.on.save=true +do.depend=false +do.jar=true +file.reference.craftbukkit-1.10.2.jar=D:\\Minecraft Servers\\Buildtools\\craftbukkit-1.10.2.jar +file.reference.EssentialsX-2.0.1.jar=D:\\Downloads\\EssentialsX-2.0.1.jar +file.reference.OnTime.jar=D:\\Downloads\\OnTime.jar +file.reference.Vault.jar=D:\\Minecraft Servers\\TestServer\\plugins\\Uusi kansio\\Vault.jar +javac.debug=true +javadoc.preview=true +user.properties.file=C:\\Users\\Risto\\AppData\\Roaming\\.tmcbeans\\8.1.0\\build.properties diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml new file mode 100644 index 000000000..800132876 --- /dev/null +++ b/nbproject/private/private.xml @@ -0,0 +1,22 @@ + + + + + + file:/C:/Users/Risto/Documents/NetBeansProjects/PlayerAnalyticsPlugin-0.0.1/src/com/djrapitops/plan/Plan.java + file:/C:/Users/Risto/Documents/NetBeansProjects/PlayerAnalyticsPlugin-0.0.1/src/plugin.yml + file:/C:/Users/Risto/Documents/NetBeansProjects/PlayerAnalyticsPlugin-0.0.1/src/com/djrapitops/plan/command/hooks/Hook.java + file:/C:/Users/Risto/Documents/NetBeansProjects/PlayerAnalyticsPlugin-0.0.1/src/com/djrapitops/plan/command/hooks/VaultHook.java + file:/C:/Users/Risto/Documents/NetBeansProjects/PlayerAnalyticsPlugin-0.0.1/src/com/djrapitops/plan/command/utils/DataFormatUtils.java + file:/C:/Users/Risto/Documents/NetBeansProjects/PlayerAnalyticsPlugin-0.0.1/src/com/djrapitops/plan/command/hooks/FactionsHook.java + file:/C:/Users/Risto/Documents/NetBeansProjects/PlayerAnalyticsPlugin-0.0.1/src/com/djrapitops/plan/command/commands/InspectCommand.java + file:/C:/Users/Risto/Documents/NetBeansProjects/PlayerAnalyticsPlugin-0.0.1/src/config.yml + file:/C:/Users/Risto/Documents/NetBeansProjects/PlayerAnalyticsPlugin-0.0.1/src/com/djrapitops/plan/API.java + file:/C:/Users/Risto/Documents/NetBeansProjects/PlayerAnalyticsPlugin-0.0.1/src/com/djrapitops/plan/PlanCommand.java + file:/C:/Users/Risto/Documents/NetBeansProjects/PlayerAnalyticsPlugin-0.0.1/src/com/djrapitops/plan/command/hooks/PlaceholderAPIHook.java + file:/C:/Users/Risto/Documents/NetBeansProjects/PlayerAnalyticsPlugin-0.0.1/src/com/djrapitops/plan/command/utils/DataUtils.java + file:/C:/Users/Risto/Documents/NetBeansProjects/PlayerAnalyticsPlugin-0.0.1/src/com/djrapitops/plan/command/commands/AnalyzeCommand.java + file:/C:/Users/Risto/Documents/NetBeansProjects/PlayerAnalyticsPlugin-0.0.1/src/com/djrapitops/plan/command/hooks/AdvancedAchievementsHook.java + + + diff --git a/nbproject/project.properties b/nbproject/project.properties new file mode 100644 index 000000000..d46472440 --- /dev/null +++ b/nbproject/project.properties @@ -0,0 +1,95 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=Plan +application.vendor=Risto +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# Files in build.classes.dir which should be excluded from distribution jar +dist.archive.excludes= +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/Plan.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.AdvancedAchievements.jar=D:\\Minecraft Servers\\TestServer\\plugins\\Uusi kansio\\AdvancedAchievements.jar +file.reference.Factions.jar=D:\\Minecraft Servers\\TestServer\\plugins\\Uusi kansio\\Factions.jar +file.reference.MassiveCore.jar=D:\\Minecraft Servers\\TestServer\\plugins\\Uusi kansio\\MassiveCore.jar +file.reference.mcMMO.jar=D:\\Minecraft Servers\\TestServer\\plugins\\Uusi kansio\\mcMMO.jar +file.reference.PlaceholderAPI.jar=D:\\Minecraft Servers\\TestServer\\plugins\\Uusi kansio\\PlaceholderAPI.jar +file.reference.SuperbVote-0.3.2.jar=D:\\Minecraft Servers\\TestServer\\plugins\\Uusi kansio\\SuperbVote-0.3.2.jar +file.reference.Towny.jar=D:\\Downloads\\Towny.jar +file.reference.Vault.jar=D:\\Minecraft Servers\\TestServer\\plugins\\Vault.jar +includes=** +jar.compress=true +javac.classpath=\ + ${file.reference.craftbukkit-1.10.2.jar}:\ + ${file.reference.OnTime.jar}:\ + ${file.reference.EssentialsX-2.0.1.jar}:\ + ${file.reference.Towny.jar}:\ + ${file.reference.Vault.jar}:\ + ${file.reference.Factions.jar}:\ + ${file.reference.MassiveCore.jar}:\ + ${file.reference.mcMMO.jar}:\ + ${file.reference.SuperbVote-0.3.2.jar}:\ + ${file.reference.PlaceholderAPI.jar}:\ + ${file.reference.AdvancedAchievements.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.external.vm=true +javac.processorpath=\ + ${javac.classpath} +javac.source=1.8 +javac.target=1.8 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class=player.analytics.main.Main +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 000000000..6451c434d --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,15 @@ + + + org.netbeans.modules.java.j2seproject + + + Plan + + + + + + + + + diff --git a/src/com/djrapitops/plan/API.java b/src/com/djrapitops/plan/API.java new file mode 100644 index 000000000..c296c67af --- /dev/null +++ b/src/com/djrapitops/plan/API.java @@ -0,0 +1,63 @@ +package com.djrapitops.plan; + +import com.djrapitops.plan.command.hooks.Hook; +import com.djrapitops.plan.command.utils.DataFormatUtils; +import com.djrapitops.plan.command.utils.DataUtils; +import java.util.HashMap; + +public class API { + + private Plan plugin; + + public API(Plan plugin) { + this.plugin = plugin; + } + + public boolean getDebug() { + return plugin.getConfig().getBoolean("debug"); + } + + public boolean getVisibleEssentials() { + return plugin.getConfig().getBoolean("visible.essentials"); + } + + public boolean getVisibleOnTime() { + return plugin.getConfig().getBoolean("visible.ontime"); + } + + public boolean getVisibleFactions() { + return plugin.getConfig().getBoolean("visible.factions"); + } + + public boolean getVisibleSuperbVote() { + return plugin.getConfig().getBoolean("visible.superbvote"); + } + + public boolean getVisibleTowny() { + return plugin.getConfig().getBoolean("visible.towny"); + } + + public boolean getVisibleVault() { + return plugin.getConfig().getBoolean("visible.vault"); + } + + public boolean getVisibleAdvancedAchievements() { + return plugin.getConfig().getBoolean("visible.advancedachievements"); + } + + public boolean getVisiblePlaceholderAPI() { + return plugin.getConfig().getBoolean("visible.placeholderapi"); + } + + public HashMap getData(String playerName) { + return DataFormatUtils.removeExtraDataPoints(DataUtils.getData(false, playerName)); + } + + public HashMap getAllData(String playerName) { + return DataFormatUtils.removeExtraDataPoints(DataUtils.getData(true, playerName)); + } + + public void addExtraHook(String name, Hook hook) { + plugin.addExtraHook(name, hook); + } +} diff --git a/src/com/djrapitops/plan/Plan.java b/src/com/djrapitops/plan/Plan.java new file mode 100644 index 000000000..a74d1194e --- /dev/null +++ b/src/com/djrapitops/plan/Plan.java @@ -0,0 +1,183 @@ +package com.djrapitops.plan; + +import com.djrapitops.plan.command.hooks.EssentialsHook; +import com.djrapitops.plan.command.hooks.FactionsHook; +import com.djrapitops.plan.command.hooks.OnTimeHook; +import com.djrapitops.plan.command.hooks.Hook; +import com.djrapitops.plan.command.hooks.PlaceholderAPIHook; +import com.djrapitops.plan.command.hooks.SuperbVoteHook; +//import com.djrapitops.plan.command.hooks.McMMOHook; +import com.djrapitops.plan.command.hooks.TownyHook; +import com.djrapitops.plan.command.hooks.VaultHook; +import com.djrapitops.plan.command.hooks.AdvancedAchievementsHook; +import com.djrapitops.plan.command.utils.DataUtils; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; + +public class Plan extends JavaPlugin { + + private final Map hooks; + private Hook placeholderAPIHook; + private API api; + private final Map extraHooks; + + public Plan() { + this.hooks = new HashMap<>(); + this.extraHooks = new HashMap<>(); + } + + public Map getHooks() { + return this.hooks; + } + + @Override + public void onEnable() { + getDataFolder().mkdirs(); + + getConfig().options().copyDefaults(true); + + getConfig().options().header("Plan Config\n" + + "debug - Errors are saved in errorlog.txt when they occur\n" + + "visible - Plugin's data is accessable with /plan inspect command" + ); + + saveConfig(); + + try { + if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) { + String[] placeholders = DataUtils.getPlaceholdersFileData(); + if (placeholders != null) { + this.placeholderAPIHook = new PlaceholderAPIHook(this, placeholders); + PlaceholderAPIHook phAHook = (PlaceholderAPIHook) placeholderAPIHook; + phAHook.hook(); + } else { + logToFile("Failed to read placeholders.yml\n"); + } + } + } catch (Exception e) { + logError("Failed to create placeholders.yml"); + logToFile("Failed to create placeholders.yml\n" + e); + } + + List hookFail = hookInit(); + if (this.hooks.isEmpty()) { + logError("Found no plugins to get data (or config set to false). Disabling plugin.."); + logToFile("MAIN\nNo Hooks found. Plugin Disabled."); + getServer().getPluginManager().disablePlugin(this); + return; + } + + this.api = new API(this); + + String loadedMsg = "Hooked into: "; + for (String key : this.hooks.keySet()) { + loadedMsg += ChatColor.GREEN + key + " "; + } + String failedMsg = "Not Hooked: "; + for (String string : hookFail) { + failedMsg += ChatColor.RED + string + " "; + } + Bukkit.getServer().getConsoleSender().sendMessage("[Plan] " + loadedMsg); + if (!hookFail.isEmpty()) { + Bukkit.getServer().getConsoleSender().sendMessage("[Plan] " + failedMsg); + } + + getCommand("plan").setExecutor(new PlanCommand(this)); + + log("Player Analytics Enabled."); + } + + public List hookInit() { + this.hooks.clear(); + List hookFail = new ArrayList<>(); + String[] plugins = {"OnTime", "Essentials", "Towny", "Vault", "Factions", "SuperbVote", "AdvancedAchievements"}; + for (String pluginName : plugins) { + + if (getConfig().getBoolean("visible." + pluginName.toLowerCase())) { + try { + String className = "com.djrapitops.plan.command.hooks." + pluginName + "Hook"; + Class clazz = (Class) Hook.class.forName(className); + this.hooks.put(pluginName, clazz.getConstructor(Plan.class).newInstance(this)); + } catch (Exception | NoClassDefFoundError e) { + hookFail.add(pluginName); + String toLog = "MAIN-HOOKINIT\nFailed to hook " + pluginName + "\n" + e; + toLog += "\n" + e.getCause(); + logToFile(toLog); + + } + } else { + hookFail.add(ChatColor.YELLOW + pluginName); + } + } + for (String extraHook : this.extraHooks.keySet()) { + this.hooks.put(extraHook, this.extraHooks.get(extraHook)); + } + if (getConfig().getBoolean("visible.placeholderapi")) { + if (this.placeholderAPIHook != null) { + this.hooks.put("PlaceholderAPI", this.placeholderAPIHook); + } else { + hookFail.add("PlaceholderAPI"); + } + } else { + hookFail.add(ChatColor.YELLOW + "PlaceholderAPI"); + } + return hookFail; + } + + @Override + public void onDisable() { + log("Player Analytics Disabled."); + } + + public void log(String message) { + getLogger().info(message); + } + + public void logError(String message) { + getLogger().severe(message); + } + + public void logToFile(String message) { + if (getConfig().getBoolean("debug")) { + File folder = getDataFolder(); + if (!folder.exists()) { + folder.mkdir(); + } + File log = new File(getDataFolder(), "errorlog.txt"); + try { + if (!log.exists()) { + log.createNewFile(); + } + FileWriter fw = new FileWriter(log, true); + try (PrintWriter pw = new PrintWriter(fw)) { + pw.println(message + "\n"); + pw.flush(); + } + } catch (IOException e) { + logError("Failed to create log.txt file"); + } + } + } + + public Hook getPlaceholderAPIHook() { + return this.placeholderAPIHook; + } + + public API getAPI() { + return api; + } + + public void addExtraHook(String name, Hook hook) { + this.extraHooks.put(name, hook); + } +} diff --git a/src/com/djrapitops/plan/PlanCommand.java b/src/com/djrapitops/plan/PlanCommand.java new file mode 100644 index 000000000..cd5342425 --- /dev/null +++ b/src/com/djrapitops/plan/PlanCommand.java @@ -0,0 +1,109 @@ +package com.djrapitops.plan; + +import com.djrapitops.plan.command.CommandType; +import com.djrapitops.plan.command.SubCommand; +import com.djrapitops.plan.command.commands.AnalyzeCommand; +import com.djrapitops.plan.command.commands.HelpCommand; +import com.djrapitops.plan.command.commands.InspectCommand; +import com.djrapitops.plan.command.commands.ReloadCommand; +import com.djrapitops.plan.javaTools.Editor; +import org.bukkit.ChatColor; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +import java.util.List; +import java.util.ArrayList; +import org.bukkit.entity.Player; + +public class PlanCommand implements CommandExecutor { + + private final List commands; + + public PlanCommand(Plan plugin) { + commands = new ArrayList<>(); + + commands.add(new HelpCommand(plugin, this)); + commands.add(new InspectCommand(plugin)); + if (plugin.getConfig().getBoolean("analysis")) { + commands.add(new AnalyzeCommand(plugin)); + } + commands.add(new ReloadCommand(plugin)); + } + + public List getCommands() { + return this.commands; + } + + public SubCommand getCommand(String name) { + for (SubCommand command : commands) { + String[] aliases = command.getName().split(","); + + for (String alias : aliases) { + if (alias.equalsIgnoreCase(name)) { + return command; + } + } + } + return null; + } + + private void sendDefaultCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) { + String command = "inspect"; + if (args.length < 1) { + command = "help"; + } + Editor edit = new Editor(); + onCommand(sender, cmd, commandLabel, edit.mergeArrays(new String[]{command}, args)); + } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) { + if (args.length < 1) { + sendDefaultCommand(sender, cmd, commandLabel, args); + return true; + } + + SubCommand command = getCommand(args[0]); + + if (command == null) { + sendDefaultCommand(sender, cmd, commandLabel, args); + return true; + } + + if (!sender.hasPermission(command.getPermission())) { +// Phrase.NO_PERMISSION_FOR_COMMAND.sendWithPrefix( sender ); + sender.sendMessage(ChatColor.RED + "[PLAN] You do not have the required permmission."); + return true; + } + + boolean console = !(sender instanceof Player); + + if (console && args.length < 2 && command.getCommandType() == CommandType.CONSOLE_WITH_ARGUMENTS) { +// Phrase.COMMAND_NEEDS_ARGUMENTS.sendWithPrefix( sender ); + sender.sendMessage(ChatColor.RED + "[PLAN] Command requires arguments."); + + return true; + } + + if (console && command.getCommandType() == CommandType.PLAYER) { +// Phrase.COMMAND_NOT_CONSOLE.sendWithPrefix( sender, commandLabel ); + sender.sendMessage(ChatColor.RED + "[PLAN] This command can be only used as a player."); + + return true; + } + + String[] realArgs = new String[args.length - 1]; + + for (int i = 1; i < args.length; i++) { + realArgs[i - 1] = args[i]; + } + + if (!command.onCommand(sender, cmd, commandLabel, realArgs)) { +// Phrase.TRY_COMMAND.sendWithPrefix( sender, parse( commandLabel, command ) ); + } + return true; + } + +} diff --git a/src/com/djrapitops/plan/UUIDFetcher.java b/src/com/djrapitops/plan/UUIDFetcher.java new file mode 100644 index 000000000..cf26ecba7 --- /dev/null +++ b/src/com/djrapitops/plan/UUIDFetcher.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2015 Nate Mortensen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.djrapitops.plan; + +import com.google.common.collect.ImmutableList; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; + +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.ByteBuffer; +import java.util.*; +import java.util.concurrent.Callable; + +public class UUIDFetcher implements Callable> +{ + private static final double PROFILES_PER_REQUEST = 100; + private static final String PROFILE_URL = "https://api.mojang.com/profiles/minecraft"; + private final JSONParser jsonParser = new JSONParser(); + private final List names; + private final boolean rateLimiting; + + public UUIDFetcher( List names, boolean rateLimiting ) + { + this.names = ImmutableList.copyOf( names ); + this.rateLimiting = rateLimiting; + } + + public UUIDFetcher( List names ) + { + this( names, true ); + } + + public Map call() throws Exception + { + Map uuidMap = new HashMap(); + + int requests = ( int ) Math.ceil( names.size() / PROFILES_PER_REQUEST ); + + for( int i = 0; i < requests; i++ ) + { + HttpURLConnection connection = createConnection(); + String body = JSONArray.toJSONString( names.subList( i * 100, Math.min( ( i + 1 ) * 100, names.size() ) ) ); + writeBody( connection, body ); + JSONArray array = ( JSONArray ) jsonParser.parse( new InputStreamReader( connection.getInputStream() ) ); + for( Object profile : array ) + { + JSONObject jsonProfile = ( JSONObject ) profile; + String id = ( String ) jsonProfile.get( "id" ); + String name = ( String ) jsonProfile.get( "name" ); + UUID uuid = UUIDFetcher.getUUID( id ); + uuidMap.put( name, uuid ); + } + if( rateLimiting && i != requests - 1 ) + { + Thread.sleep( 100L ); + } + } + return uuidMap; + } + + private static void writeBody( HttpURLConnection connection, String body ) throws Exception + { + OutputStream stream = connection.getOutputStream(); + stream.write( body.getBytes() ); + stream.flush(); + stream.close(); + } + + private static HttpURLConnection createConnection() throws Exception + { + URL url = new URL( PROFILE_URL ); + HttpURLConnection connection = ( HttpURLConnection ) url.openConnection(); + connection.setRequestMethod( "POST" ); + connection.setRequestProperty( "Content-Type", "application/json" ); + connection.setUseCaches( false ); + connection.setDoInput( true ); + connection.setDoOutput( true ); + return connection; + } + + private static UUID getUUID( String id ) + { + return UUID.fromString( id.substring( 0, 8 ) + "-" + id.substring( 8, 12 ) + "-" + id.substring( 12, 16 ) + "-" + id.substring( 16, 20 ) + "-" + id.substring( 20, 32 ) ); + } + + public static byte[] toBytes( UUID uuid ) + { + ByteBuffer byteBuffer = ByteBuffer.wrap( new byte[16] ); + byteBuffer.putLong( uuid.getMostSignificantBits() ); + byteBuffer.putLong( uuid.getLeastSignificantBits() ); + return byteBuffer.array(); + } + + public static UUID fromBytes( byte[] array ) + { + if( array.length != 16 ) + { + throw new IllegalArgumentException( "Illegal byte array length: " + array.length ); + } + ByteBuffer byteBuffer = ByteBuffer.wrap( array ); + long mostSignificant = byteBuffer.getLong(); + long leastSignificant = byteBuffer.getLong(); + return new UUID( mostSignificant, leastSignificant ); + } + + public static UUID getUUIDOf( String name ) throws Exception + { + return new UUIDFetcher( Arrays.asList( name ) ).call().get( name ); + } +} \ No newline at end of file diff --git a/src/com/djrapitops/plan/command/CommandType.java b/src/com/djrapitops/plan/command/CommandType.java new file mode 100644 index 000000000..a0c49b1b1 --- /dev/null +++ b/src/com/djrapitops/plan/command/CommandType.java @@ -0,0 +1,8 @@ +package com.djrapitops.plan.command; + +public enum CommandType +{ + CONSOLE, + PLAYER, + CONSOLE_WITH_ARGUMENTS +} diff --git a/src/com/djrapitops/plan/command/SubCommand.java b/src/com/djrapitops/plan/command/SubCommand.java new file mode 100644 index 000000000..cc2f003c5 --- /dev/null +++ b/src/com/djrapitops/plan/command/SubCommand.java @@ -0,0 +1,63 @@ +package com.djrapitops.plan.command; + +//import com.djrapitops.plan.Phrase; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +public abstract class SubCommand +{ + private final String name; + + private final String permission; + + private final String usage; + +// private final Phrase description; + + private final CommandType commandType; + + public SubCommand( String name, String permission, String usage, CommandType commandType ) + { + this.name = name; + + this.permission = permission; + + this.usage = usage; + +// this.description = description; + + this.commandType = commandType; + } + + public String getFirstName() + { + return name.split( "," )[0]; + } + + public String getName() + { + return name; + } + + public String getPermission() + { + return permission; + } + + public String getUsage() + { + return usage; + } + +// public Phrase getDescription() +// { +// return description; +// } + + public CommandType getCommandType() + { + return commandType; + } + + public abstract boolean onCommand( CommandSender sender, Command cmd, String commandLabel, String[] args ); +} diff --git a/src/com/djrapitops/plan/command/commands/AnalyzeCommand.java b/src/com/djrapitops/plan/command/commands/AnalyzeCommand.java new file mode 100644 index 000000000..ae52a7659 --- /dev/null +++ b/src/com/djrapitops/plan/command/commands/AnalyzeCommand.java @@ -0,0 +1,169 @@ +package com.djrapitops.plan.command.commands; + +import com.djrapitops.plan.Plan; +import com.djrapitops.plan.command.CommandType; +import com.djrapitops.plan.command.SubCommand; +import com.djrapitops.plan.command.utils.DataFormatUtils; +import com.djrapitops.plan.command.utils.DataUtils; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.UUID; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +public class AnalyzeCommand extends SubCommand { + + private Plan plugin; + private HashMap> playerData; + private HashMap analyzedPlayerdata; + private Date refreshDate; + + public AnalyzeCommand(Plan plugin) { + super("analyze", "plan.analyze", "Analyze data of all players /plan analyze [-refresh]", CommandType.CONSOLE); + this.plugin = plugin; +// this.plugin.log("Refreshing playerDataMap, this might take a while.."); +// this.playerData = DataUtils.getTotalData(); +// this.analyzedPlayerdata = analyze(this.playerData); +// this.refreshDate = new Date(); +// this.plugin.log("PlayerDataMap refresh complete."); + } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) { + ChatColor operatorColor = ChatColor.DARK_GREEN; + ChatColor textColor = ChatColor.GRAY; + for (String arg : args) { + if (arg.toLowerCase().equals("-refresh")) { + if (sender.hasPermission("plan.analyze.refresh")) { + sender.sendMessage(textColor + "[" + operatorColor + "Plan" + textColor + "] " + + "Refreshing playerData, this might take a while.."); + this.playerData = DataUtils.getTotalData(); + this.refreshDate = new Date(); + this.analyzedPlayerdata = analyze(this.playerData); + + } + } + } + if (this.playerData == null || this.refreshDate == null || this.analyzedPlayerdata == null) { + sender.sendMessage(textColor + "[" + operatorColor + "Plan" + textColor + "] " + + "Refreshing playerData, this might take a while.."); + this.playerData = DataUtils.getTotalData(); + this.refreshDate = new Date(); + this.analyzedPlayerdata = analyze(this.playerData); + } + List dataList = new ArrayList<>(); + sender.sendMessage(textColor + "-- [" + operatorColor + "PLAN - Analysis results, refreshed " + DataFormatUtils.formatTimeAmount(refreshDate, new Date()) + " ago:" + textColor + "] --"); + for (String key : this.analyzedPlayerdata.keySet()) { + dataList.add(new String[]{key, this.analyzedPlayerdata.get(key)}); + } + Collections.sort(dataList, new Comparator() { + public int compare(String[] strings, String[] otherStrings) { + return strings[0].compareTo(otherStrings[0]); + } + }); + sender.sendMessage("" + textColor + "Averages for "+this.playerData.size()+" player(s)"); + for (String[] dataString : dataList) { + sender.sendMessage("" + operatorColor + dataString[0].charAt(4) + dataString[0].toLowerCase().substring(5) + ": " + textColor + dataString[1]); + } + sender.sendMessage(textColor + "-- o --"); + return true; + } + + private HashMap analyze(HashMap> playerData) { + HashMap> playerDataLists = new HashMap<>(); + String[] ignore = {"ESS-BAN REASON", "ESS-OPPED", "ESS-MUTE TIME", "ESS-LOCATION", "ESS-HUNGER", "ESS-LOCATION WORLD", + "ESS-NICKNAME", "ESS-UUID", "FAC-FACTION", "ONT-LAST LOGIN", "TOW-TOWN", "TOW-REGISTERED", + "TOW-LAST LOGIN", "TOW-OWNER OF", "TOW-PLOT PERMS", "TOW-PLOT OPTIONS", "TOW-FRIENDS", "ESS-ONLINE SINCE", + "ESS-OFFLINE SINCE"}; + List ignoreKeys = new ArrayList<>(); + ignoreKeys.addAll(Arrays.asList(ignore)); + for (UUID key : playerData.keySet()) { + for (String dataKey : playerData.get(key).keySet()) { + if (!ignoreKeys.contains(dataKey)) { + if (playerDataLists.get(dataKey) == null) { + playerDataLists.put(dataKey, new ArrayList<>()); + } + playerDataLists.get(dataKey).add(playerData.get(key).get(dataKey)); + } + } + } + + String[] numbers = {"ESS-HEALTH", "ESS-XP LEVEL", "FAC-POWER", "FAC-POWER PER HOUR", + "FAC-POWER PER DEATH", "SVO-VOTES", "ONT-TOTAL VOTES", "ONT-TOTAL REFERRED", "ECO-BALANCE"}; + List numberKeys = new ArrayList<>(); + numberKeys.addAll(Arrays.asList(numbers)); + String[] booleanValues = {"ESS-BANNED", "ESS-JAILED", "ESS-MUTED", "ESS-FLYING", "TOW-ONLINE"}; + List boolKeys = new ArrayList<>(); + boolKeys.addAll(Arrays.asList(booleanValues)); + String[] timeValues = {"ONT-TOTAL PLAY"}; + List timeKeys = new ArrayList<>(); + timeKeys.addAll(Arrays.asList(timeValues)); + + HashMap analyzedData = new HashMap<>(); + int errors = 0; + HashSet errorTypes = new HashSet<>(); + + for (String dataKey : playerDataLists.keySet()) { + if (numberKeys.contains(dataKey)) { + double sum = 0; + + for (String dataPoint : playerDataLists.get(dataKey)) { + try { + if (dataKey.equals("FAC-POWER")) { + sum += Double.parseDouble(dataPoint.split(" ")[0]); + } else if (dataKey.equals("ECO-BALANCE")) { + sum += Double.parseDouble(DataFormatUtils.removeLetters(dataPoint)); + } else { + sum += Double.parseDouble(dataPoint); + } + } catch (Exception e) { + errors++; + errorTypes.add("" + e); + } + } + analyzedData.put(dataKey, "" + (sum / this.playerData.size())); + + } else if (boolKeys.contains(dataKey)) { + int amount = 0; + for (String dataPoint : playerDataLists.get(dataKey)) { + try { + if (Boolean.parseBoolean(dataPoint)) { + amount++; + } + } catch (Exception e) { + errors++; + errorTypes.add("" + e); + } + } + analyzedData.put(dataKey, "" + ((amount / this.playerData.size())*100) + "%"); + } else if (timeKeys.contains(dataKey)) { + Long time = Long.parseLong("0"); + for (String dataPoint : playerDataLists.get(dataKey)) { + try { + time += Long.parseLong(dataPoint); + } catch (Exception e) { + errors++; + errorTypes.add("" + e); + } + } + analyzedData.put(dataKey, "" + (time / this.playerData.size())); + } + } + if (errors > 0) { + String log = "ANALYZE\n" + errors + " error(s) occurred while analyzing total data.\nFollowing types:"; + for (String errorType : errorTypes) { + log += "\n " + errorType; + } + plugin.logToFile(log); + } + return DataFormatUtils.formatAnalyzed(analyzedData); + } + +} diff --git a/src/com/djrapitops/plan/command/commands/HelpCommand.java b/src/com/djrapitops/plan/command/commands/HelpCommand.java new file mode 100644 index 000000000..226bf3c30 --- /dev/null +++ b/src/com/djrapitops/plan/command/commands/HelpCommand.java @@ -0,0 +1,53 @@ +package com.djrapitops.plan.command.commands; + +//import com.djrapitops.plan.Phrase; +import com.djrapitops.plan.Plan; +import com.djrapitops.plan.PlanCommand; +import com.djrapitops.plan.command.CommandType; +import com.djrapitops.plan.command.SubCommand; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class HelpCommand extends SubCommand { + + private final Plan plugin; + private final PlanCommand command; + + public HelpCommand(Plan plugin, PlanCommand command) { + super("help,?", "plan.?", "Show command list.", CommandType.CONSOLE); + + this.plugin = plugin; + this.command = command; + } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) { + + ChatColor operatorColor = ChatColor.DARK_GREEN; + + ChatColor textColor = ChatColor.GRAY; + + sender.sendMessage(textColor + "-- [" + operatorColor + "PLAN - Player Analytics" + textColor + "] --"); + + for (SubCommand command : this.command.getCommands()) { + if (command.getName().equalsIgnoreCase(getName())) { + continue; + } + + if (!sender.hasPermission(command.getPermission())) { + continue; + } + + if (!(sender instanceof Player) && command.getCommandType() == CommandType.PLAYER) { + continue; + } + + sender.sendMessage(operatorColor + "/plan " + command.getFirstName() + textColor + " - " + command.getUsage()); + } + + return true; + } + +} diff --git a/src/com/djrapitops/plan/command/commands/InspectCommand.java b/src/com/djrapitops/plan/command/commands/InspectCommand.java new file mode 100644 index 000000000..69f59ba2a --- /dev/null +++ b/src/com/djrapitops/plan/command/commands/InspectCommand.java @@ -0,0 +1,121 @@ +package com.djrapitops.plan.command.commands; + +import com.djrapitops.plan.Plan; +import com.djrapitops.plan.command.CommandType; +import com.djrapitops.plan.command.SubCommand; +import com.djrapitops.plan.command.utils.DataFormatUtils; +import com.djrapitops.plan.command.utils.DataUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import me.edge209.OnTime.UUIDFetcher; + +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class InspectCommand extends SubCommand { + + private Plan plugin; + + public InspectCommand(Plan plugin) { + super("inspect", "plan.inspect", "Inspect data /plan [-a, -r].", CommandType.CONSOLE_WITH_ARGUMENTS); + + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) { + String playerName = getPlayerDisplayname(args, sender); +// if (args.length < 1 && !(sender instanceof Player)) { +// sender.sendMessage(ChatColor.RED+"Console use of inspect requires arguments."); +// return false; +// } + if (this.plugin.getHooks().isEmpty()) { + this.plugin.logError("noHookedPluginsError on InspectCommand"); + + this.plugin.logToFile("INSPECT\nnoHookedPluginsError on InspectCommand"); + + return false; + } + + boolean allData = false; + boolean format = true; + for (String arg : args) { + if (arg.toLowerCase().equals("-a")) { + allData = true; + } + if (arg.toLowerCase().equals("-r")) { + format = false; + } + } + + HashMap data = getData(allData, playerName); + if (format && !data.isEmpty()) { + data = format(data); + } + if (data.isEmpty()) { + data.put("ERR-NO RESULTS", "No results were found."); + + plugin.logToFile("INSPECT-Results\nNo results were found for: " + playerName); + + } + + List dataList = new ArrayList<>(); + for (String key : data.keySet()) { + dataList.add(new String[]{key, data.get(key)}); + } + Collections.sort(dataList, new Comparator() { + public int compare(String[] strings, String[] otherStrings) { + return strings[0].compareTo(otherStrings[0]); + } + }); + + ChatColor operatorColor = ChatColor.DARK_GREEN; + ChatColor textColor = ChatColor.GRAY; + + sender.sendMessage(textColor + "-- [" + operatorColor + "PLAN - Inspect results: " + playerName + textColor + "] --"); + + for (String[] dataString : dataList) { + sender.sendMessage("" + operatorColor + dataString[0].charAt(4) + dataString[0].toLowerCase().substring(5) + ": " + textColor + dataString[1]); + } + sender.sendMessage(textColor + "-- o --"); + return true; + } + + public HashMap getData(boolean allData, String playerName) { + return DataUtils.getData(allData, playerName); + } + + public HashMap format(HashMap data) throws NumberFormatException { + return DataFormatUtils.removeExtraDataPoints(data); + } + + private String getPlayerDisplayname(String[] args, CommandSender sender) { + String playerName = ""; + if (args.length > 0) { + if ((args[0].equals("-a")) || (args[0].equals("-r"))) { + playerName = "ArgumentGivenError"; + plugin.log("No username given, returned empty username."); + + plugin.logToFile("INSPECT-GETNAME\nNo username given, returned empty username.\n" + args[0]); + + } else if (sender.hasPermission("plan.inspect.other")) { + playerName = args[0]; + } + } else { + try { + Player player = plugin.getServer().getPlayer(UUIDFetcher.getUUIDOf(sender.getName())); + playerName = player.getName(); + } catch (Exception e) { + playerName = "ConsoleNotPlayerErr"; + } + } + return playerName; + } +} diff --git a/src/com/djrapitops/plan/command/commands/ReloadCommand.java b/src/com/djrapitops/plan/command/commands/ReloadCommand.java new file mode 100644 index 000000000..06297169b --- /dev/null +++ b/src/com/djrapitops/plan/command/commands/ReloadCommand.java @@ -0,0 +1,54 @@ +package com.djrapitops.plan.command.commands; + +import com.djrapitops.plan.Plan; +import com.djrapitops.plan.command.CommandType; +import com.djrapitops.plan.command.SubCommand; +import com.djrapitops.plan.command.hooks.PlaceholderAPIHook; +import com.djrapitops.plan.command.utils.DataUtils; +import java.util.List; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +public class ReloadCommand extends SubCommand { + + private Plan plugin; + + public ReloadCommand(Plan plugin) { + super("reload", "plan.reload", "Reload plugin config & Hooks", CommandType.CONSOLE); + + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) { + plugin.reloadConfig(); + List hookFail = plugin.hookInit(); + ChatColor operatorColor = ChatColor.DARK_GREEN; + ChatColor textColor = ChatColor.GRAY; + try { + if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) { + PlaceholderAPIHook papih = (PlaceholderAPIHook) plugin.getPlaceholderAPIHook(); + papih.setPlaceholders(DataUtils.getPlaceholdersFileData()); + } + } catch (Exception e) { + plugin.logToFile("RELOAD-PlaceholderAPI reload failed\n" + e); + } + sender.sendMessage(textColor + "[" + operatorColor + "PLAN" + textColor + "] Config & Hooks reloaded."); + String loadedMsg = " Hooked into: "; + for (String key : plugin.getHooks().keySet()) { + loadedMsg += ChatColor.GREEN + key + " "; + } + String failedMsg = " Not Hooked: "; + for (String string : hookFail) { + failedMsg += ChatColor.RED + string + " "; + } + sender.sendMessage(textColor + loadedMsg); + if (!hookFail.isEmpty()) { + sender.sendMessage(textColor + failedMsg); + } + return true; + } + +} diff --git a/src/com/djrapitops/plan/command/hooks/AdvancedAchievementsHook.java b/src/com/djrapitops/plan/command/hooks/AdvancedAchievementsHook.java new file mode 100644 index 000000000..c399b4f2f --- /dev/null +++ b/src/com/djrapitops/plan/command/hooks/AdvancedAchievementsHook.java @@ -0,0 +1,71 @@ +package com.djrapitops.plan.command.hooks; + +import com.djrapitops.plan.Plan; +import com.djrapitops.plan.UUIDFetcher; +import com.hm.achievement.AdvancedAchievements; +import com.hm.achievement.category.MultipleAchievements; +import com.hm.achievement.category.NormalAchievements; +import java.util.HashMap; +import java.util.UUID; +import static org.bukkit.Bukkit.getPlayer; +import org.bukkit.entity.Player; +import static org.bukkit.plugin.java.JavaPlugin.getPlugin; + +public class AdvancedAchievementsHook implements Hook { + + private Plan plugin; + private AdvancedAchievements aAPlugin; + private int totalAchievements; + + public AdvancedAchievementsHook(Plan plugin) throws Exception, NoClassDefFoundError { + this.plugin = plugin; + this.aAPlugin = getPlugin(AdvancedAchievements.class); + for (NormalAchievements category : NormalAchievements.values()) { + String categoryName = category.toString(); + if (aAPlugin.getDisabledCategorySet().contains(categoryName)) { + continue; + } + totalAchievements += aAPlugin.getPluginConfig().getConfigurationSection(categoryName).getKeys(false).size(); + } + for (MultipleAchievements category : MultipleAchievements.values()) { + String categoryName = category.toString(); + if (aAPlugin.getDisabledCategorySet().contains(categoryName)) { + continue; + } + for (String item : aAPlugin.getPluginConfig().getConfigurationSection(categoryName).getKeys(false)) { + totalAchievements += aAPlugin.getPluginConfig().getConfigurationSection(categoryName + '.' + item) + .getKeys(false).size(); + } + } + + if (!aAPlugin.getDisabledCategorySet().contains("Commands")) { + totalAchievements += aAPlugin.getPluginConfig().getConfigurationSection("Commands").getKeys(false).size(); + } + } + + @Override + public HashMap getData(String player) throws Exception { + HashMap data = new HashMap<>(); + UUID uuid = UUIDFetcher.getUUIDOf(player); + Player p = getPlayer(player); + if (uuid != null) { + p = getPlayer(uuid); + } + if (p != null) { + try { + if (totalAchievements > 0) { + data.put("AAC-ACHIEVEMENTS", aAPlugin.getDb().getPlayerAchievementsAmount(p) + " / " + totalAchievements); + } + } catch (Exception e) { + plugin.logToFile("AAHOOK-GetData\nFailed to get data\n" + e + "\nfor: " + player); + } + } + return data; + } + + @Override + public HashMap getAllData(String player) throws Exception { + return getData(player); + } + +} diff --git a/src/com/djrapitops/plan/command/hooks/EssentialsHook.java b/src/com/djrapitops/plan/command/hooks/EssentialsHook.java new file mode 100644 index 000000000..4e4135267 --- /dev/null +++ b/src/com/djrapitops/plan/command/hooks/EssentialsHook.java @@ -0,0 +1,84 @@ +package com.djrapitops.plan.command.hooks; + +import com.djrapitops.plan.Plan; +import java.util.HashMap; + +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import net.ess3.api.IEssentials; +import com.earth2me.essentials.craftbukkit.BanLookup; +import com.gmail.nossr50.util.uuid.UUIDFetcher; +import static org.bukkit.plugin.java.JavaPlugin.getPlugin; +import org.bukkit.BanList; +import org.bukkit.Location; + +public class EssentialsHook implements Hook { + + private IEssentials ess; + private final Plan plugin; + + public EssentialsHook(Plan p) throws Exception { + this.ess = getPlugin(Essentials.class); + this.plugin = p; + } + + @Override + public HashMap getData(String player) throws Exception { + HashMap data = new HashMap<>(); + User user = this.ess.getOfflineUser(player); + if (user != null) { + if (this.ess.getServer().getBanList(BanList.Type.IP).isBanned(player) + || BanLookup.isBanned(this.ess, player)) { + data.put("ESS-BANNED", "" + true); + data.put("ESS-BAN REASON", "" + BanLookup.getBanEntry(this.ess, player).getReason()); + } + if (user.isJailed()) { + data.put("ESS-JAILED", "" + true); + data.put("ESS-JAIL TIME", "" + user.getJailTimeout()); + } + if (user.isMuted()) { + data.put("ESS-MUTED", "" + true); + data.put("ESS-MUTE TIME", "" + user.getMuteTimeout()); + } + try { + if (user.isReachable()) { + Location loc = user.getLocation(); + data.put("ESS-LOCATION WORLD", loc.getWorld().getName()); + data.put("ESS-LOCATION", " X:" + loc.getBlockX() + " Y:" + loc.getBlockY() + " Z:" + loc.getBlockZ()); + } else { + Location loc = user.getLogoutLocation(); + data.put("ESS-LOCATION WORLD", loc.getWorld().getName()); + data.put("ESS-LOCATION", "X:" + loc.getBlockX() + " Y:" + loc.getBlockY() + " Z:" + loc.getBlockZ()); + } + } catch (Exception e) { + this.plugin.logToFile("ESSENTIALSHOOK\n" + e + "\n" + e.getMessage()); + + } + data.put("ESS-NICKNAME", "" + user.getDisplayName()); + if (user.isReachable()) { + data.put("ESS-ONLINE SINCE", "" + user.getLastOnlineActivity()); + } else { + data.put("ESS-OFFLINE SINCE", "" + user.getLastOnlineActivity()); + } + } + return data; + } + + @Override + public HashMap getAllData(String player) throws Exception { + HashMap data = new HashMap<>(); + data.putAll(getData(player)); + User user = this.ess.getOfflineUser(player); + if (user != null) { + data.put("ESS-UUID", "" + user.getBase().getUniqueId().toString()); + data.put("ESS-HEALTH", "" + user.getBase().getHealth()); + data.put("ESS-HUNGER", "" + user.getBase().getFoodLevel()); + data.put("ESS-XP LEVEL", "" + user.getBase().getLevel()); + data.put("ESS-OPPED", "" + user.getBase().isOp()); +// data.put("ESS-GOD MODE", "" + user.isGodModeEnabled()); + data.put("ESS-FLYING", "" + user.getBase().isFlying()); + } + return data; + } + +} diff --git a/src/com/djrapitops/plan/command/hooks/FactionsHook.java b/src/com/djrapitops/plan/command/hooks/FactionsHook.java new file mode 100644 index 000000000..128888e0d --- /dev/null +++ b/src/com/djrapitops/plan/command/hooks/FactionsHook.java @@ -0,0 +1,54 @@ +package com.djrapitops.plan.command.hooks; + +import com.djrapitops.plan.Plan; +import com.djrapitops.plan.UUIDFetcher; +import com.massivecraft.factions.Factions; +import java.util.HashMap; + +import com.massivecraft.factions.entity.MPlayer; +import java.util.UUID; +import static org.bukkit.Bukkit.getOfflinePlayer; +import static org.bukkit.Bukkit.getPlayer; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import static org.bukkit.plugin.java.JavaPlugin.getPlugin; + +public class FactionsHook implements Hook { + + private Plan plugin; + private Factions factions; + + public FactionsHook(Plan plugin) throws Exception { + this.plugin = plugin; + this.factions = getPlugin(Factions.class); + } + + @Override + public HashMap getData(String player) throws Exception { + HashMap data = new HashMap<>(); + MPlayer mplayer; + UUID uuid = UUIDFetcher.getUUIDOf(player); + OfflinePlayer p = getOfflinePlayer(player); + if (uuid != null) { + p = getOfflinePlayer(uuid); + } + mplayer = MPlayer.get(p.getUniqueId()); + if (p.hasPlayedBefore()) { + if (mplayer.hasFaction()) { + data.put("FAC-FACTION", mplayer.getFactionName()); + if (mplayer.hasTitle()) { + data.put("FAC-TITLE", mplayer.getTitle()); + } + } + data.put("FAC-POWER", mplayer.getPowerRounded() + " / " + mplayer.getPowerMax()); + data.put("FAC-POWER PER HOUR", "" + mplayer.getPowerPerHour()); + data.put("FAC-POWER PER DEATH", "" + mplayer.getPowerPerDeath()); + } + return data; + } + + @Override + public HashMap getAllData(String player) throws Exception { + return getData(player); + } +} diff --git a/src/com/djrapitops/plan/command/hooks/Hook.java b/src/com/djrapitops/plan/command/hooks/Hook.java new file mode 100644 index 000000000..dc81f158c --- /dev/null +++ b/src/com/djrapitops/plan/command/hooks/Hook.java @@ -0,0 +1,16 @@ + +package com.djrapitops.plan.command.hooks; + +import com.djrapitops.plan.Plan; +import java.util.HashMap; + +public interface Hook { + + public HashMap getData(String player) throws Exception; + public HashMap getAllData(String player) throws Exception; + + public default void setPlan(Plan plan) throws Exception { + + } + +} diff --git a/src/com/djrapitops/plan/command/hooks/OnTimeHook.java b/src/com/djrapitops/plan/command/hooks/OnTimeHook.java new file mode 100644 index 000000000..860cf8085 --- /dev/null +++ b/src/com/djrapitops/plan/command/hooks/OnTimeHook.java @@ -0,0 +1,40 @@ +package com.djrapitops.plan.command.hooks; + +import com.djrapitops.plan.Plan; +import java.util.HashMap; +import me.edge209.OnTime.OnTimeAPI; + +public class OnTimeHook implements Hook { + + private Plan plugin; + + public OnTimeHook(Plan plugin) throws Exception { + this.plugin = plugin; + if (OnTimeAPI.data.LASTLOGIN == null) { + throw new Exception("Ontime not installed."); + } + } + + @Override + public HashMap getData(String player) throws Exception { + HashMap data = new HashMap<>(); + try { + data.put("ONT-LAST LOGIN", "" + OnTimeAPI.getPlayerTimeData(player, OnTimeAPI.data.LASTLOGIN)); + data.put("ONT-TOTAL PLAY", "" + OnTimeAPI.getPlayerTimeData(player, OnTimeAPI.data.TOTALPLAY)); + data.put("ONT-TOTAL VOTES", "" + OnTimeAPI.getPlayerTimeData(player, OnTimeAPI.data.TOTALVOTE)); + data.put("ONT-TOTAL REFERRED", "" + OnTimeAPI.getPlayerTimeData(player, OnTimeAPI.data.TOTALREFER)); + } catch (NoClassDefFoundError e) { + plugin.logToFile("ONTIME HOOK ERROR" + + "\nOntimeHook enabled but failing, could not get data." + + "\n" + e + + "\n" + e.getMessage()); + + } + return data; + } + + @Override + public HashMap getAllData(String player) throws Exception { + return getData(player); + } +} diff --git a/src/com/djrapitops/plan/command/hooks/PlaceholderAPIHook.java b/src/com/djrapitops/plan/command/hooks/PlaceholderAPIHook.java new file mode 100644 index 000000000..21598bf44 --- /dev/null +++ b/src/com/djrapitops/plan/command/hooks/PlaceholderAPIHook.java @@ -0,0 +1,69 @@ +package com.djrapitops.plan.command.hooks; + +import com.djrapitops.plan.Plan; +import com.djrapitops.plan.UUIDFetcher; +import com.djrapitops.plan.command.commands.InspectCommand; +import com.djrapitops.plan.command.utils.DataFormatUtils; +import com.djrapitops.plan.command.utils.DataUtils; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import me.clip.placeholderapi.PlaceholderAPI; +import me.clip.placeholderapi.external.EZPlaceholderHook; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +public class PlaceholderAPIHook extends EZPlaceholderHook implements Hook { + + private final List placeholders; + private final Plan plan; + + public PlaceholderAPIHook(Plan plan, String[] placeholders) { + super(plan, "plan"); + this.plan = plan; + this.placeholders = new ArrayList<>(); + this.placeholders.addAll(Arrays.asList(placeholders)); + } + + @Override + public String onPlaceholderRequest(Player player, String identifier) { + HashMap data = DataFormatUtils.removeExtraDataPoints(DataUtils.getData(true, player.getDisplayName())); + String key = identifier.toUpperCase(); + if (data.get(key) != null) { + return data.get(key); + } else { + plan.logToFile("PlaceholderAPIHOOK\nFailed to get data\n" + player.getDisplayName() + "\n" + key); + } + return null; + } + + @Override + public HashMap getData(String playerName) throws Exception { + HashMap data = new HashMap<>(); + Player player = Bukkit.getPlayer(UUIDFetcher.getUUIDOf(playerName)); + for (String placeholder : placeholders) { + if (placeholder.length() > 0) { + String key = ("" + placeholder.subSequence(1, placeholder.length() - 1)).toUpperCase(); + data.put("PHA-" + key.toUpperCase(), PlaceholderAPI.setPlaceholders(player, placeholder)); + } + } + return data; + } + + @Override + public HashMap getAllData(String player) throws Exception { + return getData(player); + } + + public void setPlaceholders(String[] placeholders) { + this.placeholders.clear(); + this.placeholders.addAll(Arrays.asList(placeholders)); + } + + @Override + public boolean hook() { + return super.hook(); + } + +} diff --git a/src/com/djrapitops/plan/command/hooks/SuperbVoteHook.java b/src/com/djrapitops/plan/command/hooks/SuperbVoteHook.java new file mode 100644 index 000000000..c8a5b9455 --- /dev/null +++ b/src/com/djrapitops/plan/command/hooks/SuperbVoteHook.java @@ -0,0 +1,30 @@ +package com.djrapitops.plan.command.hooks; + +import com.djrapitops.plan.Plan; +import com.djrapitops.plan.UUIDFetcher; +import io.minimum.minecraft.superbvote.SuperbVote; +import java.util.HashMap; + +public class SuperbVoteHook implements Hook { + + private Plan plugin; + private SuperbVote hookP; + + public SuperbVoteHook(Plan plugin) throws Exception { + this.plugin = plugin; + this.hookP = SuperbVote.getPlugin(); + } + + @Override + public HashMap getData(String player) throws Exception { + HashMap data = new HashMap<>(); + data.put("SVO-VOTES", "" + hookP.getVoteStorage().getVotes(UUIDFetcher.getUUIDOf(player))); + return data; + } + + @Override + public HashMap getAllData(String player) throws Exception { + return getData(player); + } + +} diff --git a/src/com/djrapitops/plan/command/hooks/TownyHook.java b/src/com/djrapitops/plan/command/hooks/TownyHook.java new file mode 100644 index 000000000..7ae1b50fc --- /dev/null +++ b/src/com/djrapitops/plan/command/hooks/TownyHook.java @@ -0,0 +1,80 @@ +package com.djrapitops.plan.command.hooks; + +import com.djrapitops.plan.Plan; +import com.palmergames.bukkit.towny.Towny; +import static com.palmergames.bukkit.towny.TownyFormatter.getFormattedName; +import static com.palmergames.bukkit.towny.TownyFormatter.getFormattedResidents; +import static com.palmergames.bukkit.towny.TownyFormatter.lastOnlineFormat; +import static com.palmergames.bukkit.towny.TownyFormatter.registeredFormat; +import com.palmergames.bukkit.towny.exceptions.TownyException; +import com.palmergames.bukkit.towny.object.Resident; +import com.palmergames.bukkit.towny.object.TownyUniverse; +import com.palmergames.bukkit.util.BukkitTools; +import com.palmergames.bukkit.util.Colors; +import com.palmergames.util.StringMgmt; +import java.util.HashMap; +import java.util.List; +import static org.bukkit.plugin.java.JavaPlugin.getPlugin; +import static com.palmergames.bukkit.towny.TownyFormatter.getFormattedResidents; + +public class TownyHook implements Hook { + + private Towny towny; + private final Plan plugin; + + public TownyHook(Plan p) throws Exception { + this.towny = getPlugin(Towny.class); + this.plugin = p; + } + + @Override + public HashMap getData(String player) throws Exception { + HashMap data = new HashMap<>(); + try { + Resident resident = TownyUniverse.getDataSource().getResident(player); + if (resident != null) { + data.put("TOW-ONLINE", "" + BukkitTools.isOnline(player)); + data.put("TOW-REGISTERED", registeredFormat.format(resident.getRegistered())); + data.put("TOW-LAST LOGIN", lastOnlineFormat.format(resident.getLastOnline())); + data.put("TOW-OWNER OF", resident.getTownBlocks().size() + " plots"); + try { + if (resident.hasTown()) { + data.put("TOW-TOWN", getFormattedName(resident.getTown())); + } + if (resident.hasNation()) { + if (!resident.getNationRanks().isEmpty()) { + data.put("TOW-NATION", resident.getTown().getNation().getName()); + } + } + } catch (TownyException e) { + plugin.logToFile("TOWNYHOOK\n" + e + "\n" + e.getMessage()); + + } + + } + } catch (TownyException e) { + plugin.logToFile("TOWNYHOOK\n" + e + "\nError resident: " + player); + + } + return data; + } + + @Override + public HashMap getAllData(String player) throws Exception { + HashMap data = new HashMap<>(); + data.putAll(getData(player)); + try { + Resident resident = TownyUniverse.getDataSource().getResident(player); + + data.put("TOW-PLOT PERMS", resident.getPermissions().getColourString()); + data.put("TOW-PLOT OPTIONS", "PVP: " + ((resident.getPermissions().pvp) ? "ON" : "OFF") + " Explosions: " + ((resident.getPermissions().explosion) ? "ON" : "OFF") + " Firespread: " + ((resident.getPermissions().fire) ? "ON" : "OFF") + " Mob Spawns: " + ((resident.getPermissions().mobs) ? "ON" : "OFF")); + List friends = resident.getFriends(); + data.put("TOW-FRIENDS", getFormattedResidents("Friends", friends).toString()); + } catch (TownyException e) { + plugin.logToFile("TOWNYHOOK-All\n" + e + "\nError resident: " + player); + + } + return data; + } + +} diff --git a/src/com/djrapitops/plan/command/hooks/VaultHook.java b/src/com/djrapitops/plan/command/hooks/VaultHook.java new file mode 100644 index 000000000..190cf8b6f --- /dev/null +++ b/src/com/djrapitops/plan/command/hooks/VaultHook.java @@ -0,0 +1,46 @@ +package com.djrapitops.plan.command.hooks; + +import com.djrapitops.plan.Plan; +import com.djrapitops.plan.UUIDFetcher; +import java.util.HashMap; +import java.util.UUID; +import org.bukkit.OfflinePlayer; +import net.milkbowl.vault.economy.Economy; +import static org.bukkit.Bukkit.getOfflinePlayer; +import static org.bukkit.Bukkit.getServer; + +public class VaultHook implements Hook { + + private Plan plugin; + private Economy econ; + + public VaultHook(Plan plugin) throws Exception { + this.plugin = plugin; + this.econ = getServer().getServicesManager().getRegistration(Economy.class).getProvider(); + } + + @Override + public HashMap getData(String player) throws Exception { + HashMap data = new HashMap<>(); + try { + UUID uuid = UUIDFetcher.getUUIDOf(player); + OfflinePlayer p = getOfflinePlayer(player); + if (uuid != null) { + p = getOfflinePlayer(uuid); + } + if (p.hasPlayedBefore()) { + data.put("ECO-BALANCE", this.econ.format(this.econ.getBalance(p))); + } + } catch (Exception e) { + plugin.logToFile("VAULTHOOK\n" + e + "\nError player: " + player); + + } + return data; + } + + @Override + public HashMap getAllData(String player) throws Exception { + return getData(player); + } + +} diff --git a/src/com/djrapitops/plan/command/utils/DataFormatUtils.java b/src/com/djrapitops/plan/command/utils/DataFormatUtils.java new file mode 100644 index 000000000..37ab24e1e --- /dev/null +++ b/src/com/djrapitops/plan/command/utils/DataFormatUtils.java @@ -0,0 +1,211 @@ + +package com.djrapitops.plan.command.utils; + +import com.djrapitops.plan.Plan; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import static org.bukkit.plugin.java.JavaPlugin.getPlugin; + +public class DataFormatUtils { + + public static HashMap removeExtraDataPoints(HashMap data) throws NumberFormatException { + List remove = new ArrayList<>(); + Plan plugin = getPlugin(Plan.class); + for (String key : data.keySet()) { + try { + if (key.subSequence(0, 3).equals("ONT")) { + if ((data.get(key)).equals("-1") || (data.get(key)).equals("-1.0")) { + remove.add(key); + } + } + if (key.subSequence(0, 3).equals("PHA")) { + if ((data.get(key)).contains("%")) { + remove.add(key); + } + } + } catch (Exception e) { + plugin.logToFile("FORMAT-Remove\n" + e + "\n" + key); + } + } + for (String removedKey : remove) { + data.remove(removedKey); + } + remove.clear(); + if (data.get("TOW-REGISTERED") != null) { + if (data.get("TOW-REGISTERED").contains("1970")) { + remove.add("TOW-REGISTERED"); + remove.add("TOW-ONLINE"); + remove.add("TOW-LAST LOGIN"); + remove.add("TOW-OWNER OF"); + if (data.get("TOW-FRIENDS") != null) { + remove.add("TOW-FRIENDS"); + remove.add("TOW-PLOT PERMS"); + remove.add("TOW-PLOT OPTIONS"); + } + } + + if (data.get("ONT-LAST LOGIN") != null) { + remove.add("TOW-LAST LOGIN"); + } + } + for (String removedKey : remove) { + data.remove(removedKey); + } + String[] keysTimestamp = {"ONT-LAST LOGIN"}; + for (String key : keysTimestamp) { + if (data.get(key) != null) { + try { + String formatted = formatTimeStamp(data.get(key)); + data.replace(key, formatted); + } catch (NumberFormatException e) { + + plugin.logToFile("FORMAT-TimeStamp\nError Parsing Last Login.\n" + e + "\n" + data.get(key)); + + data.remove(key); + } + } + } + String[] keysRemoveIfZero = {"ESS-ONLINE SINCE", "ESS-OFFLINE SINCE"}; + for (String key : keysRemoveIfZero) { + if (data.get(key) != null) { + if (data.get(key).equals("0")) { + data.remove(key); + } + } + } + + String[] keysTimeAmount = {"ONT-TOTAL PLAY", "ESS-ONLINE SINCE", "ESS-OFFLINE SINCE"}; + for (String key : keysTimeAmount) { + if (data.get(key) != null) { + try { + String formatted; + if (key.equals("ONT-TOTAL PLAY")) { + formatted = formatTimeAmount(data.get(key)); + } else { + formatted = formatTimeAmount(data.get(key), new Date()); + } + if (formatted != null) { + data.replace(key, formatted); + } + } catch (NumberFormatException e) { + + plugin.logToFile("FORMAT-Since\nError Parsing number.\n" + e + "\n" + data.get(key)); + + data.remove(key); + } + } + } + if (data.get("SVO-VOTES") != null) { + if (data.get("ONT-TOTAL VOTES") != null) { + data.remove("ONT-TOTAL VOTES"); + } + } + return data; + } + + public static String formatTimeStamp(String string) throws NumberFormatException { + long ms = Long.parseLong(string); + Date sfd = new Date(ms); + return ("" + sfd).substring(4, 19); + } + + public static String formatTimeAmount(String string) throws NumberFormatException { + String returnValue = ""; + long ms = Long.parseLong(string); + long x = ms / 1000; + long seconds = x % 60; + x /= 60; + long minutes = x % 60; + x /= 60; + long hours = x % 24; + x /= 24; + long days = x; + if (days != 0) { + returnValue += days + "d "; + } + if (hours != 0) { + returnValue += hours + "h "; + } + if (minutes != 0) { + returnValue += minutes + "m "; + } + if (seconds != 0) { + returnValue += seconds + "s"; + } + return returnValue; + } + + public static String formatTimeAmount(String string, Date date) throws NumberFormatException { + String returnValue = ""; + long ms = (date.toInstant().getEpochSecond() * 1000) - Long.parseLong(string); + long x = ms / 1000; + long seconds = x % 60; + x /= 60; + long minutes = x % 60; + x /= 60; + long hours = x % 24; + x /= 24; + long days = x; + if (days != 0) { + returnValue += days + "d "; + } + if (hours != 0) { + returnValue += hours + "h "; + } + if (minutes != 0) { + returnValue += minutes + "m "; + } + if (seconds != 0) { + returnValue += seconds + "s"; + } + return returnValue; + } + public static String formatTimeAmount(Date before, Date now) throws NumberFormatException { + String returnValue = ""; + long ms = (now.toInstant().getEpochSecond() * 1000) - (before.toInstant().getEpochSecond() * 1000); + long x = ms / 1000; + long seconds = x % 60; + x /= 60; + long minutes = x % 60; + x /= 60; + long hours = x % 24; + x /= 24; + long days = x; + if (days != 0) { + returnValue += days + "d "; + } + if (hours != 0) { + returnValue += hours + "h "; + } + if (minutes != 0) { + returnValue += minutes + "m "; + } + if (seconds != 0) { + returnValue += seconds + "s"; + } + return returnValue; + } + + public static HashMap formatAnalyzed(HashMap analyzedData) { + return removeExtraDataPoints(analyzedData); + } + + public static String removeLetters(String dataPoint) { + String numbers = "0123456789."; + List numList = new ArrayList<>(); + char[] numberArray = numbers.toCharArray(); + for (char c : numberArray) { + numList.add(c); + } + String returnString = ""; + for (int i = 0; i < dataPoint.length(); i++) { + if (numList.contains(dataPoint.charAt(i))) { + returnString += dataPoint.charAt(i); + } + } + return returnString; + } +} diff --git a/src/com/djrapitops/plan/command/utils/DataUtils.java b/src/com/djrapitops/plan/command/utils/DataUtils.java new file mode 100644 index 000000000..5bd1d3cf5 --- /dev/null +++ b/src/com/djrapitops/plan/command/utils/DataUtils.java @@ -0,0 +1,69 @@ +package com.djrapitops.plan.command.utils; + +import com.djrapitops.plan.Plan; +import java.io.File; +import java.util.HashMap; +import java.util.Scanner; +import java.util.UUID; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import static org.bukkit.plugin.java.JavaPlugin.getPlugin; + +public class DataUtils { + + public static HashMap getData(boolean allData, String playerName) { + HashMap data = new HashMap<>(); + Plan plugin = getPlugin(Plan.class); + for (String hook : plugin.getHooks().keySet()) { + try { + if (allData) { + data.putAll(plugin.getHooks().get(hook).getAllData(playerName)); + } else { + data.putAll(plugin.getHooks().get(hook).getData(playerName)); + } + } catch (Exception e) { + + String toLog = "UTILS-GetData" + + "\nFailed to getData from " + hook + + "\n" + e + + "\ncausing argument: " + playerName; + for (StackTraceElement element : e.getStackTrace()) { + toLog += "\n " + element; + } + plugin.logToFile(toLog); + + } + } + return data; + } + + public static HashMap> getTotalData() { + HashMap> playerData = new HashMap<>(); + for (OfflinePlayer player : Bukkit.getOfflinePlayers()) { + if (playerData.get(player.getUniqueId()) == null) { + playerData.put(player.getUniqueId(), getData(true, player.getName())); + } + } + return playerData; + } + + public static String[] getPlaceholdersFileData() { + Plan plugin = getPlugin(Plan.class); + File placeholdersFile = new File(plugin.getDataFolder(), "placeholders.yml"); + try { + if (!placeholdersFile.exists()) { + placeholdersFile.createNewFile(); + } + Scanner filescanner = new Scanner(placeholdersFile); + String placeholdersString = ""; + if (filescanner.hasNextLine()) { + placeholdersString = filescanner.nextLine(); + } + String[] returnArray = placeholdersString.split(" "); + return returnArray; + } catch (Exception e) { + plugin.logToFile("Failed to create placeholders.yml\n" + e); + } + return null; + } +} diff --git a/src/com/djrapitops/plan/javaTools/Editor.java b/src/com/djrapitops/plan/javaTools/Editor.java new file mode 100644 index 000000000..3cba0d71b --- /dev/null +++ b/src/com/djrapitops/plan/javaTools/Editor.java @@ -0,0 +1,29 @@ + +package com.djrapitops.plan.javaTools; + +public class Editor { + + public String[] mergeArrays( String[]... arrays ) + { + int arraySize = 0; + + for( String[] array : arrays ) + { + arraySize += array.length; + } + + String[] result = new String[arraySize]; + + int j = 0; + + for( String[] array : arrays ) + { + for( String string : array ) + { + result[j++] = string; + } + } + + return result; + } +} diff --git a/src/config.yml b/src/config.yml new file mode 100644 index 000000000..6c09d1022 --- /dev/null +++ b/src/config.yml @@ -0,0 +1,12 @@ +debug: true +analysis: true + +visible: + ontime: true + essentials: true + factions: true + towny: true + vault: true + superbvote: true + placeholderapi: true + advancedachievements: true \ No newline at end of file diff --git a/src/plugin.yml b/src/plugin.yml new file mode 100644 index 000000000..88ebaa148 --- /dev/null +++ b/src/plugin.yml @@ -0,0 +1,47 @@ +name: Plan +main: com.djrapitops.plan.Plan +version: 1.4.0 + +commands: + plan: + usage: / + description: base command + inspect: + usage: /plan inspect + description: inspect player data + analyze: + usage: /plan analyze + description: analyze all players' data, add -r to refresh analysis. + reload: + usage: /plan reload + description: reload plugin config + +softdepend: +- OnTime +- EssentialsX +- Towny +- Vault +- Factions +- SuperbVote +- PlaceholderAPI +- AdvancedAchievements + +permissions: + plan.?: + description: Help command + default: true + plan.inspect: + description: Allows you to check your player data. + default: true + plan.inspect.other: + description: Allows you to check other players' player data. + default: true + plan.analyze: + description: Allows you to check analysed data about all players. + default: true + plan.analyze.refresh: + description: Allows you to refresh the analyse result with -r argument + default: false + plan.reload: + description: Allows to reload plugin config + default: true \ No newline at end of file