diff --git a/.idea/libraries/Maven__com_github_TBMCPlugins_ButtonCore_Towny_master_248b0d8d0a_1.xml b/.idea/libraries/Maven__com_github_TBMCPlugins_ButtonCore_Towny_master_248b0d8d0a_1.xml deleted file mode 100644 index 0d3e00e..0000000 --- a/.idea/libraries/Maven__com_github_TBMCPlugins_ButtonCore_Towny_master_248b0d8d0a_1.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__com_github_milkbowl_VaultAPI_master_431c5273c2_1.xml b/.idea/libraries/Maven__com_github_milkbowl_VaultAPI_master_431c5273c2_1.xml deleted file mode 100644 index 19b24a3..0000000 --- a/.idea/libraries/Maven__com_github_milkbowl_VaultAPI_master_431c5273c2_1.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/BuildConfigUpdater/BuildConfigUpdater.iml b/BuildConfigUpdater/BuildConfigUpdater.iml index 73696cd..f14440c 100644 --- a/BuildConfigUpdater/BuildConfigUpdater.iml +++ b/BuildConfigUpdater/BuildConfigUpdater.iml @@ -12,6 +12,7 @@ + @@ -19,6 +20,7 @@ + diff --git a/BuildConfigUpdater/src/main/java/BCUMain.java b/BuildConfigUpdater/src/main/java/BCUMain.java index 07666d3..a5e2007 100644 --- a/BuildConfigUpdater/src/main/java/BCUMain.java +++ b/BuildConfigUpdater/src/main/java/BCUMain.java @@ -1,4 +1,4 @@ -import buttondevteam.component.updater.PluginUpdater; +import buttondevteam.core.component.updater.PluginUpdater; import java.util.List; import java.util.stream.Collectors; diff --git a/ButtonCore/pom.xml b/ButtonCore/pom.xml index 2bbce2d..e044b9a 100755 --- a/ButtonCore/pom.xml +++ b/ButtonCore/pom.xml @@ -1,200 +1,200 @@ - - 4.0.0 - - com.github.TBMCPlugins - ButtonCore - master-SNAPSHOT - - com.github.TBMCPlugins.ButtonCore - ButtonCore - ButtonCore - ButtonCore - - src/main/java - - - src/main/resources - - *.properties - *.yml - *.csv - *.txt - - true - - - ButtonCore - - - maven-compiler-plugin - - 1.8 - 1.8 - - - - org.apache.maven.plugins - maven-shade-plugin - 2.4.2 - - - package - - shade - - - - - - - - - - org.apache.maven.plugins - maven-resources-plugin - 3.0.1 - - - copy - compile - - copy-resources - - - target - - - src/main/resources - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - false - - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - - jar - - - - - - - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - - - jitpack.io - https://jitpack.io/ - - - vault-repo - http://nexus.hc.to/content/repositories/pub_releases - - - ess-repo - http://repo.ess3.net/content/repositories/essrel/ - - - - - org.reflections - reflections - 0.9.10 - compile - - - org.spigotmc - spigot-api - 1.12.2-R0.1-SNAPSHOT - provided - - - - commons-io - commons-io - 1.3.2 - provided - - - - com.github.TBMCPlugins.ButtonCore - Towny - master-SNAPSHOT - provided - - - com.github.milkbowl - VaultAPI - master-SNAPSHOT - provided - - - - org.javassist - javassist - 3.20.0-GA - - - org.mockito - mockito-core - 2.7.20 - - - - org.projectlombok - lombok - 1.16.16 - provided - - - com.github.TBMCPlugins.ButtonCore - ButtonProcessor - master-SNAPSHOT - provided - - - net.ess3 - Essentials - 2.13.1 - provided - - - - TBMCPlugins - https://github.com/TBMCPlugins - - - - internal.repo - Temporary Staging Repository - file://${project.build.directory}/mvn-repo/${project.name} - - - - - github - UTF-8 - - - https://github.com/TBMCPlugins/mvn-repo - scm:git:https://github.com/TBMCPlugins/mvn-repo.git - scm:git:https://github.com/TBMCPlugins/mvn-repo.git - + + 4.0.0 + + com.github.TBMCPlugins + ButtonCore + master-SNAPSHOT + + com.github.TBMCPlugins.ButtonCore + ButtonCore + ButtonCore + ButtonCore + + src/main/java + + + src/main/resources + + *.properties + *.yml + *.csv + *.txt + + true + + + ButtonCore + + + maven-compiler-plugin + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-shade-plugin + 2.4.2 + + + package + + shade + + + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.0.1 + + + copy + compile + + copy-resources + + + target + + + src/main/resources + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + false + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + jitpack.io + https://jitpack.io/ + + + vault-repo + http://nexus.hc.to/content/repositories/pub_releases + + + ess-repo + http://repo.ess3.net/content/repositories/essrel/ + + + + + org.reflections + reflections + 0.9.10 + compile + + + org.spigotmc + spigot-api + 1.12.2-R0.1-SNAPSHOT + provided + + + + commons-io + commons-io + 1.3.2 + provided + + + + com.github.TBMCPlugins.ButtonCore + Towny + master-SNAPSHOT + provided + + + com.github.milkbowl + VaultAPI + master-SNAPSHOT + provided + + + + org.javassist + javassist + 3.20.0-GA + + + org.mockito + mockito-core + 2.7.20 + + + + org.projectlombok + lombok + 1.16.16 + provided + + + com.github.TBMCPlugins.ButtonCore + ButtonProcessor + master-SNAPSHOT + compile + + + net.ess3 + Essentials + 2.13.1 + provided + + + + TBMCPlugins + https://github.com/TBMCPlugins + + + + internal.repo + Temporary Staging Repository + file://${project.build.directory}/mvn-repo/${project.name} + + + + + github + UTF-8 + + + https://github.com/TBMCPlugins/mvn-repo + scm:git:https://github.com/TBMCPlugins/mvn-repo.git + scm:git:https://github.com/TBMCPlugins/mvn-repo.git + \ No newline at end of file diff --git a/ButtonCore/src/main/java/buttondevteam/core/ComponentCommand.java b/ButtonCore/src/main/java/buttondevteam/core/ComponentCommand.java index a90337a..4aaceac 100644 --- a/ButtonCore/src/main/java/buttondevteam/core/ComponentCommand.java +++ b/ButtonCore/src/main/java/buttondevteam/core/ComponentCommand.java @@ -2,62 +2,65 @@ package buttondevteam.core; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.architecture.Component; +import buttondevteam.lib.chat.Command2MC; import buttondevteam.lib.chat.CommandClass; -import buttondevteam.lib.chat.TBMCCommandBase; import lombok.val; +import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; +import org.bukkit.plugin.Plugin; import java.util.Optional; -@CommandClass(modOnly = true) -public class ComponentCommand extends TBMCCommandBase { - @Override - public boolean OnCommand(CommandSender sender, String alias, String[] args) { - if (args.length < 1) - return false; - boolean enable = true; +@CommandClass(modOnly = true, helpText = { + "§6---- Component command ----", + "Can be used to enable/disable/list components" +}) +public class ComponentCommand extends Command2MC { + public ComponentCommand() { + addParamConverter(Plugin.class, arg -> Bukkit.getPluginManager().getPlugin(arg)); + + } + + @Subcommand + public boolean enable(CommandSender sender, Plugin plugin, String component) { + if (plugin == null) return respond(sender, "§cPlugin not found!"); + plugin.reloadConfig(); //Reload config so the new config values are read - All changes are saved to disk on disable + return enable_disable(sender, plugin, component, true); + } + + @Subcommand + public boolean disable(CommandSender sender, Plugin plugin, String component) { + if (plugin == null) return respond(sender, "§cPlugin not found!"); + return enable_disable(sender, plugin, component, false); + } + + @Subcommand + public boolean list(CommandSender sender, String plugin) { + sender.sendMessage("§6List of components:"); + Component.getComponents().values().stream().filter(c -> plugin == null || c.getPlugin().getName().equalsIgnoreCase(plugin)) //If plugin is null, don't check + .map(c -> c.getPlugin().getName() + " - " + c.getClass().getSimpleName() + " - " + (c.isEnabled() ? "en" : "dis") + "abled").forEach(sender::sendMessage); + return true; + } + + private boolean enable_disable(CommandSender sender, Plugin plugin, String component, boolean enable) { try { - switch (args[0]) { - case "enable": - enable = true; - break; - case "disable": - enable = false; - break; - case "list": - sender.sendMessage("§6List of components:"); - Component.getComponents().values().stream().map(c -> c.getPlugin().getName() + " - " + c.getClass().getSimpleName() + " - " + (c.isEnabled() ? "en" : "dis") + "abled").forEach(sender::sendMessage); - return true; - default: - return false; - } - if (args.length < 2) - return false; - val oc = getComponentOrError(args[1], sender); + val oc = getComponentOrError(plugin, component, sender); if (!oc.isPresent()) return true; - if (enable) //Reload config so the new config values are read - getPlugin().reloadConfig(); //All changes are saved to disk on disable Component.setComponentEnabled(oc.get(), enable); sender.sendMessage(oc.get().getClass().getSimpleName() + " " + (enable ? "en" : "dis") + "abled."); } catch (Exception e) { - TBMCCoreAPI.SendException("Couldn't " + (enable ? "en" : "dis") + "able component " + args[0] + "!", e); + TBMCCoreAPI.SendException("Couldn't " + (enable ? "en" : "dis") + "able component " + component + "!", e); } return true; } - private Optional getComponentOrError(String arg, CommandSender sender) { - val oc = Component.getComponents().values().stream().filter(c -> c.getClass().getSimpleName().equalsIgnoreCase(arg)).findAny(); + private Optional getComponentOrError(Plugin plugin, String arg, CommandSender sender) { + val oc = Component.getComponents().values().stream() + .filter(c -> plugin.getName().equals(c.getPlugin().getName())) + .filter(c -> c.getClass().getSimpleName().equalsIgnoreCase(arg)).findAny(); if (!oc.isPresent()) - sender.sendMessage("§cComponent not found!"); + sender.sendMessage("§cComponent not found!"); //^ Much simpler to solve in the new command system return oc; - } - - @Override - public String[] GetHelpText(String alias) { - return new String[]{ - "§6---- Component command ----", - "Enable or disable or list components" - }; - } + } //TODO: Tabcompletion for the new command system } diff --git a/ButtonCore/src/main/java/buttondevteam/core/ComponentManager.java b/ButtonCore/src/main/java/buttondevteam/core/ComponentManager.java index 0c3c51b..9a84ddd 100644 --- a/ButtonCore/src/main/java/buttondevteam/core/ComponentManager.java +++ b/ButtonCore/src/main/java/buttondevteam/core/ComponentManager.java @@ -1,6 +1,7 @@ package buttondevteam.core; import buttondevteam.lib.TBMCCoreAPI; +import buttondevteam.lib.architecture.ButtonPlugin; import buttondevteam.lib.architecture.Component; import lombok.val; @@ -31,16 +32,11 @@ public final class ComponentManager { } /** - * Disables all components that are enabled + * Unregister all components of a plugin that are enabled - called on {@link ButtonPlugin} disable */ - public static void disableComponents() { - Component.getComponents().values().stream().filter(Component::isEnabled).forEach(c -> { - try { - Component.setComponentEnabled(c, false); - } catch (Exception e) { - TBMCCoreAPI.SendException("Failed to disable one of the components: " + c.getClass().getSimpleName(), e); - } - }); + public static void unregComponents(ButtonPlugin plugin) { + while (!plugin.getComponentStack().empty()) //Unregister in reverse order + Component.unregisterComponent(plugin, plugin.getComponentStack().pop()); //Components are pushed on register componentsEnabled = false; } @@ -54,4 +50,16 @@ public final class ComponentManager { val c = Component.getComponents().get(cl); return c != null && c.isEnabled(); } + + /** + * Will also return null if the component is not registered. + * + * @param cl The component class + * @return The component if it's registered and enabled + */ + @SuppressWarnings("unchecked") + public static T getIfEnabled(Class cl) { + val c = Component.getComponents().get(cl); + return c != null && c.isEnabled() ? (T) c : null; + } } diff --git a/ButtonCore/src/main/java/buttondevteam/core/MainPlugin.java b/ButtonCore/src/main/java/buttondevteam/core/MainPlugin.java index f18cedd..b2200a4 100755 --- a/ButtonCore/src/main/java/buttondevteam/core/MainPlugin.java +++ b/ButtonCore/src/main/java/buttondevteam/core/MainPlugin.java @@ -1,19 +1,20 @@ package buttondevteam.core; -import buttondevteam.component.channel.Channel; -import buttondevteam.component.channel.ChannelComponent; -import buttondevteam.component.channel.ChatRoom; -import buttondevteam.component.members.MemberComponent; -import buttondevteam.component.randomtp.RandomTPComponent; -import buttondevteam.component.restart.RestartComponent; -import buttondevteam.component.towny.TownyComponent; -import buttondevteam.component.updater.PluginUpdater; -import buttondevteam.component.updater.PluginUpdaterComponent; +import buttondevteam.core.component.channel.Channel; +import buttondevteam.core.component.channel.ChannelComponent; +import buttondevteam.core.component.channel.ChatRoom; +import buttondevteam.core.component.members.MemberComponent; +import buttondevteam.core.component.randomtp.RandomTPComponent; +import buttondevteam.core.component.restart.RestartComponent; +import buttondevteam.core.component.towny.TownyComponent; +import buttondevteam.core.component.updater.PluginUpdater; +import buttondevteam.core.component.updater.PluginUpdaterComponent; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.architecture.ButtonPlugin; import buttondevteam.lib.architecture.Component; import buttondevteam.lib.architecture.ConfigData; import buttondevteam.lib.chat.Color; +import buttondevteam.lib.chat.Command2MC; import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.player.ChromaGamerBase; import buttondevteam.lib.player.TBMCPlayer; @@ -68,7 +69,7 @@ public class MainPlugin extends ButtonPlugin { Component.registerComponent(this, new MemberComponent()); Component.registerComponent(this, new TownyComponent()); ComponentManager.enableComponents(); - TBMCChatAPI.AddCommand(this, ComponentCommand.class); + Command2MC.registerCommand(new ComponentCommand()); TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this); ChromaGamerBase.addConverter(commandSender -> Optional.ofNullable(commandSender instanceof ConsoleCommandSender || commandSender instanceof BlockCommandSender ? TBMCPlayer.getPlayer(new UUID(0, 0), TBMCPlayer.class) : null)); //Console & cmdblocks @@ -100,7 +101,6 @@ public class MainPlugin extends ButtonPlugin { @Override public void pluginDisable() { - ComponentManager.disableComponents(); logger.info("Saving player data..."); TBMCPlayerBase.savePlayers(); logger.info("Player data saved."); @@ -132,6 +132,7 @@ public class MainPlugin extends ButtonPlugin { @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (command.getName().equals("dontrunthiscmd")) return true; //Used in chat preprocess for console sender.sendMessage("§cThis command isn't available."); //In theory, unregistered commands use this method return true; } diff --git a/ButtonCore/src/main/java/buttondevteam/core/PlayerListener.java b/ButtonCore/src/main/java/buttondevteam/core/PlayerListener.java index 3c3907f..c5146cd 100755 --- a/ButtonCore/src/main/java/buttondevteam/core/PlayerListener.java +++ b/ButtonCore/src/main/java/buttondevteam/core/PlayerListener.java @@ -1,13 +1,21 @@ package buttondevteam.core; +import buttondevteam.lib.TBMCCommandPreprocessEvent; +import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCSystemChatEvent; +import buttondevteam.lib.chat.Command2MC; import buttondevteam.lib.player.TBMCPlayerBase; +import lombok.val; import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.event.Cancellable; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.server.ServerCommandEvent; import java.util.Arrays; @@ -32,4 +40,33 @@ public class PlayerListener implements Listener { Bukkit.getOnlinePlayers().stream().filter(event::shouldSendTo) .forEach(p -> p.sendMessage(event.getChannel().DisplayName().get().substring(0, 2) + event.getMessage())); } + + @EventHandler + public void onPlayerChatPreprocess(PlayerCommandPreprocessEvent event) { + handlePreprocess(event.getPlayer(), event.getMessage(), event); + } + + @EventHandler + public void onSystemChatPreprocess(ServerCommandEvent event) { + handlePreprocess(event.getSender(), "/" + event.getCommand(), event); + if (event.isCancelled()) event.setCommand("dontrunthiscmd"); //Bugfix + } + + private void handlePreprocess(CommandSender sender, String message, Cancellable event) { + if (event.isCancelled()) return; + val ev = new TBMCCommandPreprocessEvent(sender, message); + Bukkit.getPluginManager().callEvent(ev); + if (ev.isCancelled()) + event.setCancelled(true); //Cancel the original event + } + + @EventHandler + public void onTBMCPreprocess(TBMCCommandPreprocessEvent event) { + if (event.isCancelled()) return; + try { + event.setCancelled(Command2MC.handleCommand(event.getSender(), event.getMessage())); + } catch (Exception e) { + TBMCCoreAPI.SendException("Command processing failed for sender '" + event.getSender() + "' and message '" + event.getMessage() + "'", e); + } + } } \ No newline at end of file diff --git a/ButtonCore/src/main/java/buttondevteam/core/TestPrepare.java b/ButtonCore/src/main/java/buttondevteam/core/TestPrepare.java index 179e9cf..67b0a33 100755 --- a/ButtonCore/src/main/java/buttondevteam/core/TestPrepare.java +++ b/ButtonCore/src/main/java/buttondevteam/core/TestPrepare.java @@ -1,13 +1,14 @@ package buttondevteam.core; -import buttondevteam.component.channel.Channel; -import buttondevteam.component.channel.ChannelComponent; +import buttondevteam.core.component.channel.Channel; +import buttondevteam.core.component.channel.ChannelComponent; import buttondevteam.lib.architecture.Component; import buttondevteam.lib.chat.Color; import buttondevteam.lib.chat.TBMCChatAPI; import org.bukkit.Bukkit; import org.bukkit.Server; import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitScheduler; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; @@ -40,7 +41,7 @@ public class TestPrepare { return cl.isAssignableFrom(invocation.getMethod().getReturnType()); } })); - Component.registerComponent(Mockito.mock(MainPlugin.class), new ChannelComponent()); + Component.registerComponent(Mockito.mock(JavaPlugin.class), new ChannelComponent()); TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fg§f", Color.White, "g", null)); } } diff --git a/ButtonCore/src/main/java/buttondevteam/component/channel/Channel.java b/ButtonCore/src/main/java/buttondevteam/core/component/channel/Channel.java similarity index 99% rename from ButtonCore/src/main/java/buttondevteam/component/channel/Channel.java rename to ButtonCore/src/main/java/buttondevteam/core/component/channel/Channel.java index 38b53c0..c643880 100755 --- a/ButtonCore/src/main/java/buttondevteam/component/channel/Channel.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/channel/Channel.java @@ -1,4 +1,4 @@ -package buttondevteam.component.channel; +package buttondevteam.core.component.channel; import buttondevteam.core.ComponentManager; import buttondevteam.core.MainPlugin; diff --git a/ButtonCore/src/main/java/buttondevteam/component/channel/ChannelComponent.java b/ButtonCore/src/main/java/buttondevteam/core/component/channel/ChannelComponent.java similarity index 89% rename from ButtonCore/src/main/java/buttondevteam/component/channel/ChannelComponent.java rename to ButtonCore/src/main/java/buttondevteam/core/component/channel/ChannelComponent.java index a49ea1e..083633d 100644 --- a/ButtonCore/src/main/java/buttondevteam/component/channel/ChannelComponent.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/channel/ChannelComponent.java @@ -1,4 +1,4 @@ -package buttondevteam.component.channel; +package buttondevteam.core.component.channel; import buttondevteam.lib.architecture.Component; import org.bukkit.plugin.java.JavaPlugin; diff --git a/ButtonCore/src/main/java/buttondevteam/component/channel/ChatChannelRegisterEvent.java b/ButtonCore/src/main/java/buttondevteam/core/component/channel/ChatChannelRegisterEvent.java similarity index 91% rename from ButtonCore/src/main/java/buttondevteam/component/channel/ChatChannelRegisterEvent.java rename to ButtonCore/src/main/java/buttondevteam/core/component/channel/ChatChannelRegisterEvent.java index 896a64d..4797b3e 100755 --- a/ButtonCore/src/main/java/buttondevteam/component/channel/ChatChannelRegisterEvent.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/channel/ChatChannelRegisterEvent.java @@ -1,4 +1,4 @@ -package buttondevteam.component.channel; +package buttondevteam.core.component.channel; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; diff --git a/ButtonCore/src/main/java/buttondevteam/component/channel/ChatRoom.java b/ButtonCore/src/main/java/buttondevteam/core/component/channel/ChatRoom.java similarity index 95% rename from ButtonCore/src/main/java/buttondevteam/component/channel/ChatRoom.java rename to ButtonCore/src/main/java/buttondevteam/core/component/channel/ChatRoom.java index ea01ed6..a086a42 100755 --- a/ButtonCore/src/main/java/buttondevteam/component/channel/ChatRoom.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/channel/ChatRoom.java @@ -1,4 +1,4 @@ -package buttondevteam.component.channel; +package buttondevteam.core.component.channel; import buttondevteam.lib.chat.Color; import buttondevteam.lib.chat.TBMCChatAPI; diff --git a/ButtonCore/src/main/java/buttondevteam/component/members/MemberCommand.java b/ButtonCore/src/main/java/buttondevteam/core/component/members/MemberCommand.java similarity index 97% rename from ButtonCore/src/main/java/buttondevteam/component/members/MemberCommand.java rename to ButtonCore/src/main/java/buttondevteam/core/component/members/MemberCommand.java index d5334a1..d395d99 100644 --- a/ButtonCore/src/main/java/buttondevteam/component/members/MemberCommand.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/members/MemberCommand.java @@ -1,4 +1,4 @@ -package buttondevteam.component.members; +package buttondevteam.core.component.members; import buttondevteam.core.MainPlugin; import buttondevteam.lib.chat.CommandClass; diff --git a/ButtonCore/src/main/java/buttondevteam/component/members/MemberComponent.java b/ButtonCore/src/main/java/buttondevteam/core/component/members/MemberComponent.java similarity index 96% rename from ButtonCore/src/main/java/buttondevteam/component/members/MemberComponent.java rename to ButtonCore/src/main/java/buttondevteam/core/component/members/MemberComponent.java index 453f535..0caeca7 100644 --- a/ButtonCore/src/main/java/buttondevteam/component/members/MemberComponent.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/members/MemberComponent.java @@ -1,4 +1,4 @@ -package buttondevteam.component.members; +package buttondevteam.core.component.members; import buttondevteam.core.MainPlugin; import buttondevteam.lib.architecture.Component; diff --git a/ButtonCore/src/main/java/buttondevteam/component/randomtp/RandomTP.java b/ButtonCore/src/main/java/buttondevteam/core/component/randomtp/RandomTP.java similarity index 99% rename from ButtonCore/src/main/java/buttondevteam/component/randomtp/RandomTP.java rename to ButtonCore/src/main/java/buttondevteam/core/component/randomtp/RandomTP.java index 1f0f396..a0612db 100644 --- a/ButtonCore/src/main/java/buttondevteam/component/randomtp/RandomTP.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/randomtp/RandomTP.java @@ -1,4 +1,4 @@ -package buttondevteam.component.randomtp; +package buttondevteam.core.component.randomtp; import buttondevteam.lib.architecture.Component; import buttondevteam.lib.chat.CommandClass; diff --git a/ButtonCore/src/main/java/buttondevteam/component/randomtp/RandomTPComponent.java b/ButtonCore/src/main/java/buttondevteam/core/component/randomtp/RandomTPComponent.java similarity index 84% rename from ButtonCore/src/main/java/buttondevteam/component/randomtp/RandomTPComponent.java rename to ButtonCore/src/main/java/buttondevteam/core/component/randomtp/RandomTPComponent.java index 0261c59..e324b3a 100644 --- a/ButtonCore/src/main/java/buttondevteam/component/randomtp/RandomTPComponent.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/randomtp/RandomTPComponent.java @@ -1,4 +1,4 @@ -package buttondevteam.component.randomtp; +package buttondevteam.core.component.randomtp; import buttondevteam.lib.architecture.Component; diff --git a/ButtonCore/src/main/java/buttondevteam/component/restart/PrimeRestartCommand.java b/ButtonCore/src/main/java/buttondevteam/core/component/restart/PrimeRestartCommand.java similarity index 96% rename from ButtonCore/src/main/java/buttondevteam/component/restart/PrimeRestartCommand.java rename to ButtonCore/src/main/java/buttondevteam/core/component/restart/PrimeRestartCommand.java index 51ee9b2..32773ab 100644 --- a/ButtonCore/src/main/java/buttondevteam/component/restart/PrimeRestartCommand.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/restart/PrimeRestartCommand.java @@ -1,4 +1,4 @@ -package buttondevteam.component.restart; +package buttondevteam.core.component.restart; import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.chat.TBMCCommandBase; diff --git a/ButtonCore/src/main/java/buttondevteam/component/restart/RestartComponent.java b/ButtonCore/src/main/java/buttondevteam/core/component/restart/RestartComponent.java similarity index 96% rename from ButtonCore/src/main/java/buttondevteam/component/restart/RestartComponent.java rename to ButtonCore/src/main/java/buttondevteam/core/component/restart/RestartComponent.java index e2f98b2..e49e3b2 100644 --- a/ButtonCore/src/main/java/buttondevteam/component/restart/RestartComponent.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/restart/RestartComponent.java @@ -1,4 +1,4 @@ -package buttondevteam.component.restart; +package buttondevteam.core.component.restart; import buttondevteam.lib.architecture.Component; import buttondevteam.lib.chat.IFakePlayer; diff --git a/ButtonCore/src/main/java/buttondevteam/component/restart/ScheduledRestartCommand.java b/ButtonCore/src/main/java/buttondevteam/core/component/restart/ScheduledRestartCommand.java similarity index 66% rename from ButtonCore/src/main/java/buttondevteam/component/restart/ScheduledRestartCommand.java rename to ButtonCore/src/main/java/buttondevteam/core/component/restart/ScheduledRestartCommand.java index ecc44ad..fea469e 100755 --- a/ButtonCore/src/main/java/buttondevteam/component/restart/ScheduledRestartCommand.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/restart/ScheduledRestartCommand.java @@ -1,9 +1,11 @@ -package buttondevteam.component.restart; +package buttondevteam.core.component.restart; import buttondevteam.core.MainPlugin; import buttondevteam.lib.ScheduledServerRestartEvent; import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.chat.TBMCCommandBase; +import lombok.Getter; +import lombok.Setter; import org.bukkit.Bukkit; import org.bukkit.boss.BarColor; import org.bukkit.boss.BarFlag; @@ -14,43 +16,45 @@ import org.bukkit.scheduler.BukkitTask; @CommandClass(modOnly = true, path = "schrestart") public class ScheduledRestartCommand extends TBMCCommandBase { - private static volatile int restartcounter; - private static volatile BukkitTask restarttask; - private static volatile BossBar restartbar; + @Getter + @Setter + private int restartCounter; + private BukkitTask restarttask; + private volatile BossBar restartbar; @Override public boolean OnCommand(CommandSender sender, String alias, String[] args) { - int ticks = 20 * 60; + int secs = 60; try { if (args.length > 0) - ticks = Integer.parseInt(args[0]); + secs = Integer.parseInt(args[0]); } catch (NumberFormatException e) { - sender.sendMessage("§cError: Ticks must be a number."); + sender.sendMessage("§cError: Seconds must be a number."); return false; } - if (ticks < 20) { - sender.sendMessage("§cError: Ticks must be more than 20."); + if (secs < 10) { + sender.sendMessage("§cError: Seconds must be at least 10."); return false; } - final int restarttime = restartcounter = ticks; - restartbar = Bukkit.createBossBar("Server restart in " + ticks / 20f + "s", BarColor.RED, BarStyle.SOLID, + final int restarttime = restartCounter = secs * 20; + restartbar = Bukkit.createBossBar("Server restart in " + secs + "s", BarColor.RED, BarStyle.SOLID, BarFlag.DARKEN_SKY); restartbar.setProgress(1); Bukkit.getOnlinePlayers().forEach(p -> restartbar.addPlayer(p)); - sender.sendMessage("Scheduled restart in " + ticks / 20f); - ScheduledServerRestartEvent e = new ScheduledServerRestartEvent(ticks); + sender.sendMessage("Scheduled restart in " + secs); + ScheduledServerRestartEvent e = new ScheduledServerRestartEvent(restarttime, this); Bukkit.getPluginManager().callEvent(e); restarttask = Bukkit.getScheduler().runTaskTimer(MainPlugin.Instance, () -> { - if (restartcounter < 0) { + if (restartCounter < 0) { restarttask.cancel(); restartbar.getPlayers().forEach(p -> restartbar.removePlayer(p)); Bukkit.spigot().restart(); } - if (restartcounter % 200 == 0) - Bukkit.broadcastMessage("§c-- The server is restarting in " + restartcounter / 20 + " seconds!"); - restartbar.setProgress(restartcounter / (double) restarttime); - restartbar.setTitle(String.format("Server restart in %.2f", restartcounter / 20f)); - restartcounter--; + if (restartCounter % 200 == 0) + Bukkit.broadcastMessage("§c-- The server is restarting in " + restartCounter / 20 + " seconds! (/press)"); + restartbar.setProgress(restartCounter / (double) restarttime); + restartbar.setTitle(String.format("Server restart in %.2f", restartCounter / 20f)); + restartCounter--; }, 1, 1); return true; } diff --git a/ButtonCore/src/main/java/buttondevteam/component/towny/TownyComponent.java b/ButtonCore/src/main/java/buttondevteam/core/component/towny/TownyComponent.java similarity index 97% rename from ButtonCore/src/main/java/buttondevteam/component/towny/TownyComponent.java rename to ButtonCore/src/main/java/buttondevteam/core/component/towny/TownyComponent.java index 61a9c5a..1b2bf9d 100644 --- a/ButtonCore/src/main/java/buttondevteam/component/towny/TownyComponent.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/towny/TownyComponent.java @@ -1,4 +1,4 @@ -package buttondevteam.component.towny; +package buttondevteam.core.component.towny; import buttondevteam.core.ComponentManager; import buttondevteam.lib.TBMCCoreAPI; diff --git a/ButtonCore/src/main/java/buttondevteam/component/updater/PluginUpdater.java b/ButtonCore/src/main/java/buttondevteam/core/component/updater/PluginUpdater.java similarity index 99% rename from ButtonCore/src/main/java/buttondevteam/component/updater/PluginUpdater.java rename to ButtonCore/src/main/java/buttondevteam/core/component/updater/PluginUpdater.java index ce2e993..64401fd 100755 --- a/ButtonCore/src/main/java/buttondevteam/component/updater/PluginUpdater.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/updater/PluginUpdater.java @@ -1,4 +1,4 @@ -package buttondevteam.component.updater; +package buttondevteam.core.component.updater; import buttondevteam.lib.TBMCCoreAPI; import com.google.gson.JsonArray; diff --git a/ButtonCore/src/main/java/buttondevteam/component/updater/PluginUpdaterComponent.java b/ButtonCore/src/main/java/buttondevteam/core/component/updater/PluginUpdaterComponent.java similarity index 87% rename from ButtonCore/src/main/java/buttondevteam/component/updater/PluginUpdaterComponent.java rename to ButtonCore/src/main/java/buttondevteam/core/component/updater/PluginUpdaterComponent.java index bd64c05..2ead741 100644 --- a/ButtonCore/src/main/java/buttondevteam/component/updater/PluginUpdaterComponent.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/updater/PluginUpdaterComponent.java @@ -1,4 +1,4 @@ -package buttondevteam.component.updater; +package buttondevteam.core.component.updater; import buttondevteam.lib.architecture.Component; import buttondevteam.lib.chat.TBMCChatAPI; diff --git a/ButtonCore/src/main/java/buttondevteam/component/updater/UpdatePluginCommand.java b/ButtonCore/src/main/java/buttondevteam/core/component/updater/UpdatePluginCommand.java similarity index 96% rename from ButtonCore/src/main/java/buttondevteam/component/updater/UpdatePluginCommand.java rename to ButtonCore/src/main/java/buttondevteam/core/component/updater/UpdatePluginCommand.java index ee006c4..0569e89 100755 --- a/ButtonCore/src/main/java/buttondevteam/component/updater/UpdatePluginCommand.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/updater/UpdatePluginCommand.java @@ -1,4 +1,4 @@ -package buttondevteam.component.updater; +package buttondevteam.core.component.updater; import buttondevteam.core.MainPlugin; import buttondevteam.lib.TBMCCoreAPI; diff --git a/ButtonCore/src/main/java/buttondevteam/lib/ScheduledServerRestartEvent.java b/ButtonCore/src/main/java/buttondevteam/lib/ScheduledServerRestartEvent.java index 749578f..4531ad9 100755 --- a/ButtonCore/src/main/java/buttondevteam/lib/ScheduledServerRestartEvent.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/ScheduledServerRestartEvent.java @@ -1,20 +1,18 @@ package buttondevteam.lib; +import buttondevteam.core.component.restart.ScheduledRestartCommand; +import lombok.Getter; +import lombok.RequiredArgsConstructor; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; +@Getter +@RequiredArgsConstructor public class ScheduledServerRestartEvent extends Event { private static final HandlerList handlers = new HandlerList(); - private final int restartticks; - - public ScheduledServerRestartEvent(int restartticks) { - this.restartticks = restartticks; - } - - public int getRestartTicks() { - return restartticks; - } + private final int restartTicks; + private final ScheduledRestartCommand command; @Override public HandlerList getHandlers() { diff --git a/ButtonCore/src/main/java/buttondevteam/lib/TBMCChatEvent.java b/ButtonCore/src/main/java/buttondevteam/lib/TBMCChatEvent.java index cae2c39..ee37c30 100755 --- a/ButtonCore/src/main/java/buttondevteam/lib/TBMCChatEvent.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/TBMCChatEvent.java @@ -1,6 +1,6 @@ package buttondevteam.lib; -import buttondevteam.component.channel.Channel; +import buttondevteam.core.component.channel.Channel; import buttondevteam.lib.chat.ChatMessage; import lombok.Getter; import lombok.experimental.Delegate; diff --git a/ButtonCore/src/main/java/buttondevteam/lib/TBMCChatEventBase.java b/ButtonCore/src/main/java/buttondevteam/lib/TBMCChatEventBase.java index bed34a6..d30e12e 100755 --- a/ButtonCore/src/main/java/buttondevteam/lib/TBMCChatEventBase.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/TBMCChatEventBase.java @@ -1,6 +1,6 @@ package buttondevteam.lib; -import buttondevteam.component.channel.Channel; +import buttondevteam.core.component.channel.Channel; import lombok.Getter; import lombok.NonNull; import lombok.RequiredArgsConstructor; diff --git a/ButtonCore/src/main/java/buttondevteam/lib/TBMCChatPreprocessEvent.java b/ButtonCore/src/main/java/buttondevteam/lib/TBMCChatPreprocessEvent.java index 28bd27e..6ff3bda 100755 --- a/ButtonCore/src/main/java/buttondevteam/lib/TBMCChatPreprocessEvent.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/TBMCChatPreprocessEvent.java @@ -1,6 +1,6 @@ package buttondevteam.lib; -import buttondevteam.component.channel.Channel; +import buttondevteam.core.component.channel.Channel; import lombok.Getter; import lombok.Setter; import org.bukkit.command.CommandSender; diff --git a/ButtonCore/src/main/java/buttondevteam/lib/TBMCCommandPreprocessEvent.java b/ButtonCore/src/main/java/buttondevteam/lib/TBMCCommandPreprocessEvent.java new file mode 100755 index 0000000..a72c0b7 --- /dev/null +++ b/ButtonCore/src/main/java/buttondevteam/lib/TBMCCommandPreprocessEvent.java @@ -0,0 +1,39 @@ +package buttondevteam.lib; + +import lombok.Getter; +import lombok.Setter; +import org.bukkit.command.CommandSender; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Can be used to change or handle commands before they're sent. + * Called on using player, console and Discord commands. + * + * @author NorbiPeti + */ +@Getter +public class TBMCCommandPreprocessEvent extends Event implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + + private final CommandSender sender; + @Setter + private String message; + @Setter + private boolean cancelled; + + public TBMCCommandPreprocessEvent(CommandSender sender, String message) { + this.sender = sender; + this.message = message; //TODO: Actually call from Discord as well + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/ButtonCore/src/main/java/buttondevteam/lib/TBMCCoreAPI.java b/ButtonCore/src/main/java/buttondevteam/lib/TBMCCoreAPI.java index e114196..d4d06cf 100755 --- a/ButtonCore/src/main/java/buttondevteam/lib/TBMCCoreAPI.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/TBMCCoreAPI.java @@ -1,188 +1,188 @@ -package buttondevteam.lib; - -import buttondevteam.component.updater.PluginUpdater; -import buttondevteam.core.MainPlugin; -import buttondevteam.lib.player.ChromaGamerBase; -import buttondevteam.lib.potato.DebugPotato; -import org.apache.commons.io.IOUtils; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.event.Listener; -import org.bukkit.plugin.Plugin; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.net.URLConnection; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map.Entry; - -public class TBMCCoreAPI { - static final List coders = new ArrayList() { - private static final long serialVersionUID = -4462159250738367334L; - { - add("Alisolarflare"); - add("NorbiPeti"); - add("iie"); - add("thewindmillman"); - add("mayskam1995"); - } - }; - - /** - * Updates or installs the specified plugin. The plugin must use Maven. - * - * @param name - * The plugin's repository name. - * @param sender - * The command sender (if not console, messages will be printed to console as well). - */ - public static void UpdatePlugin(String name, CommandSender sender) { - UpdatePlugin(name, sender, "master"); - } - - /** - * Updates or installs the specified plugin from the specified branch. The plugin must use Maven. - * - * @param name - * The plugin's repository name. - * @param sender - * The command sender (if not console, messages will be printed to console as well). - * @param branch - * The branch to download the plugin from. - * @return Success or not - */ - public static boolean UpdatePlugin(String name, CommandSender sender, String branch) { - return PluginUpdater.UpdatePlugin(name, sender, branch); - } - - public static String DownloadString(String urlstr) throws IOException { - URL url = new URL(urlstr); - URLConnection con = url.openConnection(); - con.setRequestProperty("User-Agent", "TBMCPlugins"); - InputStream in = con.getInputStream(); - String encoding = con.getContentEncoding(); - encoding = encoding == null ? "UTF-8" : encoding; - String body = IOUtils.toString(in, encoding); - in.close(); - return body; - } - - private static final HashMap exceptionsToSend = new HashMap<>(); - private static final List debugMessagesToSend = new ArrayList<>(); - - /** - * Send exception to the {@link TBMCExceptionEvent}. - * - * @param sourcemsg - * A message that is shown at the top of the exception (before the exception's message) - * @param e - * The exception to send - */ - public static void SendException(String sourcemsg, Throwable e) { - SendException(sourcemsg, e, false); - } - - public static void SendException(String sourcemsg, Throwable e, boolean debugPotato) { - SendUnsentExceptions(); - TBMCExceptionEvent event = new TBMCExceptionEvent(sourcemsg, e); - Bukkit.getPluginManager().callEvent(event); - synchronized (exceptionsToSend) { - if (!event.isHandled()) - exceptionsToSend.put(sourcemsg, e); - } - Bukkit.getLogger().warning(sourcemsg); - e.printStackTrace(); - if (debugPotato) { - List devsOnline = new ArrayList(); - for (Player player : Bukkit.getOnlinePlayers()) { - if (coders.contains(player.getName())) { - devsOnline.add(player); - } - } - if (!devsOnline.isEmpty()) { - DebugPotato potato = new DebugPotato() - .setMessage(new String[] { // - "§b§o" + e.getClass().getSimpleName(), // - "§c§o" + sourcemsg, // - "§a§oFind a dev to fix this issue" }) - .setType(e instanceof IOException ? "Throwable Potato" - : e instanceof ClassCastException ? "Squished Potato" - : e instanceof NullPointerException ? "Plain Potato" - : e instanceof StackOverflowError ? "Chips" : "Error Potato"); - for (Player dev : devsOnline) { - potato.Send(dev); - } - } - } - } - - public static void sendDebugMessage(String debugMessage) { - SendUnsentDebugMessages(); - TBMCDebugMessageEvent event = new TBMCDebugMessageEvent(debugMessage); - Bukkit.getPluginManager().callEvent(event); - synchronized (debugMessagesToSend) { - if (!event.isSent()) - debugMessagesToSend.add(debugMessage); - } - } - - /** - * Registers Bukkit events, handling the exceptions occurring in those events - * - * @param listener - * The class that handles the events - * @param plugin - * The plugin which the listener belongs to - */ - public static void RegisterEventsForExceptions(Listener listener, Plugin plugin) { - EventExceptionHandler.registerEvents(listener, plugin, new EventExceptionCoreHandler()); - } - - public static void RegisterUserClass(Class userclass) { - ChromaGamerBase.RegisterPluginUserClass(userclass); - } - - /** - * Send exceptions that haven't been sent (their events didn't get handled). This method is used by the DiscordPlugin's ready event - */ - public static void SendUnsentExceptions() { - synchronized (exceptionsToSend) { - if (exceptionsToSend.size() > 20) { - exceptionsToSend.clear(); // Don't call more and more events if all the handler plugins are unloaded - Bukkit.getLogger().warning("Unhandled exception list is over 20! Clearing!"); - } - for (Iterator> iterator = exceptionsToSend.entrySet().iterator(); iterator.hasNext(); ) { - Entry entry = iterator.next(); - TBMCExceptionEvent event = new TBMCExceptionEvent(entry.getKey(), entry.getValue()); - Bukkit.getPluginManager().callEvent(event); - if (event.isHandled()) - iterator.remove(); - } - } - } - - public static void SendUnsentDebugMessages() { - synchronized (debugMessagesToSend) { - if (debugMessagesToSend.size() > 20) { - debugMessagesToSend.clear(); // Don't call more and more DebugMessages if all the handler plugins are unloaded - Bukkit.getLogger().warning("Unhandled Debug Message list is over 20! Clearing!"); - } - for (Iterator iterator = debugMessagesToSend.iterator(); iterator.hasNext(); ) { - String message = iterator.next(); - TBMCDebugMessageEvent event = new TBMCDebugMessageEvent(message); - Bukkit.getPluginManager().callEvent(event); - if (event.isSent()) - iterator.remove(); - } - } - } - - public static boolean IsTestServer() { - return MainPlugin.Test; - } +package buttondevteam.lib; + +import buttondevteam.core.MainPlugin; +import buttondevteam.core.component.updater.PluginUpdater; +import buttondevteam.lib.player.ChromaGamerBase; +import buttondevteam.lib.potato.DebugPotato; +import org.apache.commons.io.IOUtils; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; +import org.bukkit.plugin.Plugin; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; + +public class TBMCCoreAPI { + static final List coders = new ArrayList() { + private static final long serialVersionUID = -4462159250738367334L; + { + add("Alisolarflare"); + add("NorbiPeti"); + add("iie"); + add("thewindmillman"); + add("mayskam1995"); + } + }; + + /** + * Updates or installs the specified plugin. The plugin must use Maven. + * + * @param name + * The plugin's repository name. + * @param sender + * The command sender (if not console, messages will be printed to console as well). + */ + public static void UpdatePlugin(String name, CommandSender sender) { + UpdatePlugin(name, sender, "master"); + } + + /** + * Updates or installs the specified plugin from the specified branch. The plugin must use Maven. + * + * @param name + * The plugin's repository name. + * @param sender + * The command sender (if not console, messages will be printed to console as well). + * @param branch + * The branch to download the plugin from. + * @return Success or not + */ + public static boolean UpdatePlugin(String name, CommandSender sender, String branch) { + return PluginUpdater.UpdatePlugin(name, sender, branch); + } + + public static String DownloadString(String urlstr) throws IOException { + URL url = new URL(urlstr); + URLConnection con = url.openConnection(); + con.setRequestProperty("User-Agent", "TBMCPlugins"); + InputStream in = con.getInputStream(); + String encoding = con.getContentEncoding(); + encoding = encoding == null ? "UTF-8" : encoding; + String body = IOUtils.toString(in, encoding); + in.close(); + return body; + } + + private static final HashMap exceptionsToSend = new HashMap<>(); + private static final List debugMessagesToSend = new ArrayList<>(); + + /** + * Send exception to the {@link TBMCExceptionEvent}. + * + * @param sourcemsg + * A message that is shown at the top of the exception (before the exception's message) + * @param e + * The exception to send + */ + public static void SendException(String sourcemsg, Throwable e) { + SendException(sourcemsg, e, false); + } + + public static void SendException(String sourcemsg, Throwable e, boolean debugPotato) { + SendUnsentExceptions(); + TBMCExceptionEvent event = new TBMCExceptionEvent(sourcemsg, e); + Bukkit.getPluginManager().callEvent(event); + synchronized (exceptionsToSend) { + if (!event.isHandled()) + exceptionsToSend.put(sourcemsg, e); + } + Bukkit.getLogger().warning(sourcemsg); + e.printStackTrace(); + if (debugPotato) { + List devsOnline = new ArrayList(); + for (Player player : Bukkit.getOnlinePlayers()) { + if (coders.contains(player.getName())) { + devsOnline.add(player); + } + } + if (!devsOnline.isEmpty()) { + DebugPotato potato = new DebugPotato() + .setMessage(new String[] { // + "§b§o" + e.getClass().getSimpleName(), // + "§c§o" + sourcemsg, // + "§a§oFind a dev to fix this issue" }) + .setType(e instanceof IOException ? "Throwable Potato" + : e instanceof ClassCastException ? "Squished Potato" + : e instanceof NullPointerException ? "Plain Potato" + : e instanceof StackOverflowError ? "Chips" : "Error Potato"); + for (Player dev : devsOnline) { + potato.Send(dev); + } + } + } + } + + public static void sendDebugMessage(String debugMessage) { + SendUnsentDebugMessages(); + TBMCDebugMessageEvent event = new TBMCDebugMessageEvent(debugMessage); + Bukkit.getPluginManager().callEvent(event); + synchronized (debugMessagesToSend) { + if (!event.isSent()) + debugMessagesToSend.add(debugMessage); + } + } + + /** + * Registers Bukkit events, handling the exceptions occurring in those events + * + * @param listener + * The class that handles the events + * @param plugin + * The plugin which the listener belongs to + */ + public static void RegisterEventsForExceptions(Listener listener, Plugin plugin) { + EventExceptionHandler.registerEvents(listener, plugin, new EventExceptionCoreHandler()); + } + + public static void RegisterUserClass(Class userclass) { + ChromaGamerBase.RegisterPluginUserClass(userclass); + } + + /** + * Send exceptions that haven't been sent (their events didn't get handled). This method is used by the DiscordPlugin's ready event + */ + public static void SendUnsentExceptions() { + synchronized (exceptionsToSend) { + if (exceptionsToSend.size() > 20) { + exceptionsToSend.clear(); // Don't call more and more events if all the handler plugins are unloaded + Bukkit.getLogger().warning("Unhandled exception list is over 20! Clearing!"); + } + for (Iterator> iterator = exceptionsToSend.entrySet().iterator(); iterator.hasNext(); ) { + Entry entry = iterator.next(); + TBMCExceptionEvent event = new TBMCExceptionEvent(entry.getKey(), entry.getValue()); + Bukkit.getPluginManager().callEvent(event); + if (event.isHandled()) + iterator.remove(); + } + } + } + + public static void SendUnsentDebugMessages() { + synchronized (debugMessagesToSend) { + if (debugMessagesToSend.size() > 20) { + debugMessagesToSend.clear(); // Don't call more and more DebugMessages if all the handler plugins are unloaded + Bukkit.getLogger().warning("Unhandled Debug Message list is over 20! Clearing!"); + } + for (Iterator iterator = debugMessagesToSend.iterator(); iterator.hasNext(); ) { + String message = iterator.next(); + TBMCDebugMessageEvent event = new TBMCDebugMessageEvent(message); + Bukkit.getPluginManager().callEvent(event); + if (event.isSent()) + iterator.remove(); + } + } + } + + public static boolean IsTestServer() { + return MainPlugin.Test; + } } \ No newline at end of file diff --git a/ButtonCore/src/main/java/buttondevteam/lib/TBMCSystemChatEvent.java b/ButtonCore/src/main/java/buttondevteam/lib/TBMCSystemChatEvent.java index f4ded2a..80cd634 100755 --- a/ButtonCore/src/main/java/buttondevteam/lib/TBMCSystemChatEvent.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/TBMCSystemChatEvent.java @@ -1,6 +1,6 @@ package buttondevteam.lib; -import buttondevteam.component.channel.Channel; +import buttondevteam.core.component.channel.Channel; import lombok.Getter; import org.bukkit.command.CommandSender; import org.bukkit.event.HandlerList; diff --git a/ButtonCore/src/main/java/buttondevteam/lib/ThorpeUtils.java b/ButtonCore/src/main/java/buttondevteam/lib/ThorpeUtils.java new file mode 100644 index 0000000..4f8560c --- /dev/null +++ b/ButtonCore/src/main/java/buttondevteam/lib/ThorpeUtils.java @@ -0,0 +1,38 @@ +package buttondevteam.lib; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public final class ThorpeUtils { + private ThorpeUtils() {} + + public static String getDisplayName(CommandSender sender) { + if (sender instanceof IHaveFancyName) + return ((IHaveFancyName) sender).getFancyName(); + if (sender instanceof Player) + return ((Player) sender).getDisplayName(); + return sender.getName(); + } + + public static String getFullDisplayName(CommandSender sender) { + if (sender instanceof IHaveFancyName) + return ((IHaveFancyName) sender).getFancyFullName(); + return getDisplayName(sender); + } + + public interface IHaveFancyName { + /** + * May not be null. + * + * @return The name to be displayed in most places. + */ + String getFancyName(); + + /** + * May return null. + * + * @return The full name that can be used to uniquely indentify the user. + */ + String getFancyFullName(); + } +} diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java index 2eee783..5b26d9d 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java @@ -1,5 +1,6 @@ package buttondevteam.lib.architecture; +import buttondevteam.core.ComponentManager; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.chat.TBMCChatAPI; import lombok.AccessLevel; @@ -7,14 +8,30 @@ import lombok.Getter; import lombok.experimental.var; import org.bukkit.plugin.java.JavaPlugin; +import java.util.Stack; + public abstract class ButtonPlugin extends JavaPlugin { @Getter(AccessLevel.PROTECTED) private IHaveConfig iConfig; + /** + * Used to unregister components in the right order + */ + @Getter + private Stack componentStack = new Stack<>(); protected abstract void pluginEnable(); + /** + * Called after the components are unregistered + */ protected abstract void pluginDisable(); + /** + * Called before the components are unregistered + */ + protected void pluginPreDisable() { + } + @Override public final void onEnable() { var section = super.getConfig().getConfigurationSection("global"); @@ -30,6 +47,8 @@ public abstract class ButtonPlugin extends JavaPlugin { @Override public final void onDisable() { try { + pluginPreDisable(); + ComponentManager.unregComponents(this); pluginDisable(); saveConfig(); iConfig = null; //Clearing the hashmap is not enough, we need to update the section as well diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java index 02b58e7..e052555 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java @@ -3,6 +3,7 @@ package buttondevteam.lib.architecture; import buttondevteam.core.ComponentManager; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.architecture.exceptions.UnregisteredComponentException; +import buttondevteam.lib.chat.Command2MC; import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.chat.TBMCCommandBase; import lombok.Getter; @@ -38,7 +39,8 @@ public abstract class Component { /** * Registers a component checking it's dependencies and calling {@link #register(JavaPlugin)}.
* Make sure to register the dependencies first.
- * The component will be enabled automatically, regardless of when it was registered. + * The component will be enabled automatically, regardless of when it was registered.
+ * If not using {@link ButtonPlugin}, call {@link ComponentManager#unregComponents(ButtonPlugin)} on plugin disable. * * @param component The component to register * @return Whether the component is registered successfully (it may have failed to enable) @@ -49,15 +51,13 @@ public abstract class Component { /** * Unregisters a component by calling {@link #unregister(JavaPlugin)}.
- * Make sure to unregister the dependencies last. + * Make sure to unregister the dependencies last.
+ * Components will be unregistered in opposite order of registering by default by {@link ButtonPlugin} or {@link ComponentManager#unregComponents(ButtonPlugin)}. * - * @param componentClass The component class to unregister + * @param component The component to unregister * @return Whether the component is unregistered successfully (it also got disabled) */ - public static boolean unregisterComponent(JavaPlugin plugin, Class componentClass) { - val component = components.get(componentClass); - if (component == null) - return false; //Failed to load + public static boolean unregisterComponent(JavaPlugin plugin, Component component) { return registerUnregisterComponent(plugin, component, false); } @@ -74,10 +74,16 @@ public abstract class Component { } } if (register) { + if (components.containsKey(component.getClass())) { + TBMCCoreAPI.SendException("Failed to register component " + component.getClassName(), new IllegalArgumentException("The component is already registered!")); + return false; + } component.plugin = plugin; updateConfig(plugin, component); component.register(plugin); components.put(component.getClass(), component); + if (plugin instanceof ButtonPlugin) + ((ButtonPlugin) plugin).getComponentStack().push(component); if (ComponentManager.areComponentsEnabled() && component.shouldBeEnabled().get()) { try { //Enable components registered after the previous ones getting enabled setComponentEnabled(component, true); @@ -89,6 +95,8 @@ public abstract class Component { } return true; //Component shouldn't be enabled } else { + if (!components.containsKey(component.getClass())) + return true; //Already unregistered if (component.enabled) { try { setComponentEnabled(component, false); @@ -183,6 +191,16 @@ public abstract class Component { */ protected abstract void disable(); + /** + * Registers a TBMCCommand to the component. Make sure to use {@link buttondevteam.lib.chat.CommandClass} and {@link buttondevteam.lib.chat.Command2.Subcommand}. + * You don't need to register the command in plugin.yml. + * + * @param commandBase Custom coded command class + */ + protected final void registerCommand(Command2MC commandBase) { + Command2MC.registerCommand(commandBase); + } + /** * Registers a TBMCCommand to the component. Make sure to add it to plugin.yml and use {@link buttondevteam.lib.chat.CommandClass}. * diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java index 6ca2bbe..1a3a11f 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java @@ -62,6 +62,18 @@ public class ConfigData { //TODO: Save after a while if (hmm == null) hmm = def; //Set if the getter returned null return hmm; } + if (val instanceof Number) { + if (def instanceof Long) + val = ((Number) val).longValue(); + else if (def instanceof Short) + val = ((Number) val).shortValue(); + else if (def instanceof Byte) + val = ((Number) val).byteValue(); + else if (def instanceof Float) + val = ((Number) val).floatValue(); + else if (def instanceof Double) + val = ((Number) val).doubleValue(); + } return (T) val; } diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java index e2ddee2..98fa241 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java @@ -1,13 +1,15 @@ package buttondevteam.lib.architecture; import lombok.Getter; +import lombok.val; import org.bukkit.configuration.ConfigurationSection; import java.util.HashMap; import java.util.function.Function; +import java.util.function.Supplier; /** - * Members of this interface should be protected (access level) + * A config system */ public final class IHaveConfig { private final HashMap> datamap = new HashMap<>(); @@ -15,7 +17,7 @@ public final class IHaveConfig { private ConfigurationSection config; /** - * May be used in testing + * May be used in testing. * * @param section May be null for testing */ @@ -73,4 +75,42 @@ public final class IHaveConfig { datamap.put(path, data = new ConfigData<>(config, path, getter.apply(primitiveDef), primitiveDef, getter, setter)); return (ConfigData) data; } + + /** + * This method overload should only be used with primitves or String. + * + * @param path The path in config to use + * @param def The value to use by default + * @param The type of this variable (only use primitives or String) + * @return The data object that can be used to get or set the value + */ + @SuppressWarnings("unchecked") + public ConfigData getData(String path, Supplier def) { + ConfigData data = datamap.get(path); + if (data == null) { + val defval = def.get(); + datamap.put(path, data = new ConfigData<>(config, path, defval, defval)); + } + return (ConfigData) data; + } + + /** + * This method overload may be used with any class. + * + * @param path The path in config to use + * @param def The value to use by default + * @param getter A function that converts a primitive representation to the correct value + * @param setter A function that converts a value to a primitive representation + * @param The type of this variable (can be any class) + * @return The data object that can be used to get or set the value + */ + @SuppressWarnings("unchecked") + public ConfigData getData(String path, Supplier def, Function getter, Function setter) { + ConfigData data = datamap.get(path); + if (data == null) { + val defval = def.get(); + datamap.put(path, data = new ConfigData<>(config, path, defval, setter.apply(defval), getter, setter)); + } + return (ConfigData) data; + } } diff --git a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java index af9052c..c16d318 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java @@ -1,25 +1,53 @@ package buttondevteam.lib.chat; +import buttondevteam.lib.TBMCCoreAPI; +import buttondevteam.lib.player.ChromaGamerBase; +import lombok.RequiredArgsConstructor; +import lombok.experimental.var; +import lombok.val; import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.YamlConfiguration; +import java.io.InputStreamReader; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.function.Function; +import java.util.stream.Collectors; +/** + * The method name is the subcommand, use underlines (_) to add further subcommands. + * The args may be null if the conversion failed. + */ public abstract class Command2 { /** * Default handler for commands, can be used to copy the args too. * * @param sender The sender which ran the command - * @param command The (sub)command ran by the user * @param args All of the arguments passed as is - * @return + * @return The success of the command */ - public boolean def(CommandSender sender, String command, @TextArg String args) { + public boolean def(CommandSender sender, @TextArg String args) { return false; } + /** + * Convenience method. Return with this. + * + * @param sender The sender of the command + * @param message The message to send to the sender + * @return Always true so that the usage isn't shown + */ + protected boolean respond(CommandSender sender, String message) { + sender.sendMessage(message); + return true; + } + /** * TODO: @CommandClass(helpText=...) * Parameters annotated with this receive all of the remaining arguments @@ -28,4 +56,172 @@ public abstract class Command2 { @Retention(RetentionPolicy.RUNTIME) public @interface TextArg { } -} + + /** + * Methods annotated with this will be recognised as subcommands + */ + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + public @interface Subcommand { + /** + * Help text to show players. A usage message will be also shown below it. + */ + String[] helpText() default {}; + } + + @RequiredArgsConstructor + protected static class SubcommandData { + public final Method method; + public final T command; + public final String[] helpText; + } + + public Command2() { + path = getcmdpath(); + } + + /** + * Adds a param converter that obtains a specific object from a string parameter. + * The converter may return null. + * + * @param cl The class of the result object + * @param converter The converter to use + * @param The type of the result + */ + protected static void addParamConverter(Class cl, Function converter, HashMap, Function> map) { + map.put(cl, converter); + } + + protected static boolean handleCommand(CommandSender sender, String commandline, + HashMap> subcommands, HashMap, Function> paramConverters) throws Exception { + for (int i = commandline.length(); i != -1; i = commandline.lastIndexOf(' ', i - 1)) { + String subcommand = commandline.substring(0, i).toLowerCase(); + SubcommandData sd = subcommands.get(subcommand); //O(1) + if (sd == null) continue; //TODO: This will run each time someone runs any command + val params = new ArrayList(sd.method.getParameterCount()); + int j = subcommand.length(), pj; + Class[] parameterTypes = sd.method.getParameterTypes(); + if (parameterTypes.length == 0) + throw new Exception("No sender parameter for method '" + sd.method + "'"); + val sendertype = parameterTypes[0]; + final ChromaGamerBase cg; + if (sendertype.isAssignableFrom(sender.getClass())) + params.add(sender); //The command either expects a CommandSender or it is a Player, or some other expected type + else if (ChromaGamerBase.class.isAssignableFrom(sendertype) + && (cg = ChromaGamerBase.getFromSender(sender)) != null + && cg.getClass() == sendertype) //The command expects a user of our system + params.add(cg); + else { + sender.sendMessage("§cYou need to be a " + sendertype.getSimpleName() + " to use this command."); + return true; + } + for (int i1 = 1; i1 < parameterTypes.length; i1++) { + Class cl = parameterTypes[i1]; + pj = j + 1; //Start index + if (pj == commandline.length() + 1) { //No param given + params.add(null); + continue; //Fill the remaining params with nulls + } + j = commandline.indexOf(' ', j + 1); //End index + if (j == -1) //Last parameter + j = commandline.length(); + String param = commandline.substring(pj, j); + if (cl == String.class) { + params.add(param); + continue; + } + val conv = paramConverters.get(cl); + if (conv == null) + throw new Exception("No suitable converter found for parameter type '" + cl.getCanonicalName() + "' for command '" + sd.method.toString() + "'"); + params.add(conv.apply(param)); + } + //System.out.println("Our params: "+params); + val ret = sd.method.invoke(sd.command, params.toArray()); //I FORGOT TO TURN IT INTO AN ARRAY (for a long time) + if (ret instanceof Boolean) { + if (!(boolean) ret) //Show usage + sender.sendMessage(sd.helpText); + } else if (ret != null) + throw new Exception("Wrong return type! Must return a boolean or void. Return value: "+ret); + return true; //We found a method + } + return false; //Didn't handle + } //TODO: Add to the help + + protected static void registerCommand(T command, HashMap> subcommands, char commandChar) { + val path = command.getCommandPath(); + try { //Register the default handler first so it can be reliably overwritten + val method = command.getClass().getMethod("def", CommandSender.class, String.class); + val cc = command.getClass().getAnnotation(CommandClass.class); + var ht = cc == null ? new String[0] : cc.helpText(); + String[] both = Arrays.copyOf(ht, ht.length + 1); + both[ht.length] = "Usage: " + commandChar + path; //TODO: Print subcommands + ht = both; + subcommands.put(commandChar + path, new SubcommandData<>(method, command, ht)); //TODO: Disable components when the plugin is disabled + } catch (Exception e) { + TBMCCoreAPI.SendException("Could not register default handler for command /" + path, e); + } //Continue on + for (val method : command.getClass().getMethods()) { + val ann = method.getAnnotation(Subcommand.class); + if (ann != null) { + val cc = command.getClass().getAnnotation(CommandClass.class); + var ht = ann.helpText().length != 0 || cc == null ? ann.helpText() : cc.helpText(); //If cc is null then it's empty array + val subcommand = commandChar + path + //Add command path (class name by default) + (method.getName().equals("def") ? "" : " " + method.getName().replace('_', ' ').toLowerCase()); //Add method name, unless it's 'def' + ht = getHelpText(method, ht, subcommand); + subcommands.put(subcommand, new SubcommandData<>(method, command, ht)); //Result of the above (def) is that it will show the help text + } + } + } + + private static String[] getHelpText(Method method, String[] ht, String subcommand) { //TODO: helpText[0]="§6---- "+helpText[0]+" ----"; + val str = method.getDeclaringClass().getResourceAsStream("/commands.yml"); + if (str == null) + TBMCCoreAPI.SendException("Error while getting command data!", new Exception("Resource not found!")); + else { + YamlConfiguration yc = YamlConfiguration.loadConfiguration(new InputStreamReader(str)); //Generated by ButtonProcessor + val ccs = yc.getConfigurationSection(method.getDeclaringClass().getCanonicalName()); + if (ccs != null) { + val cs = ccs.getConfigurationSection(method.getName()); + if (cs != null) { + val mname = cs.getString("method"); + val params = cs.getString("params"); + val goodname = method.getName() + "(" + Arrays.stream(method.getParameterTypes()).map(cl -> cl.getCanonicalName()).collect(Collectors.joining(",")) + ")"; + if (goodname.equals(mname) && params != null) { + String[] both = Arrays.copyOf(ht, ht.length + 1); + both[ht.length] = "Usage: " + subcommand + " " + params; + ht = both; + } else + TBMCCoreAPI.SendException("Error while getting command data for " + method + "!", new Exception("Method '" + method.toString() + "' != " + mname + " or params is " + params)); + } else + TBMCCoreAPI.SendException("Error while getting command data for " + method + "!", new Exception("cs is " + cs)); + } else + TBMCCoreAPI.SendException("Error while getting command data for " + method + "!", new Exception("ccs is " + ccs + " - class: " + method.getDeclaringClass().getCanonicalName())); + } + return ht; + } + + private final String path; + + /** + * The command's path, or name if top-level command.
+ * For example:
+ * "u admin updateplugin" or "u" for the top level one
+ * The path must be lowercase!
+ * + * @return The command path, which is the command class name by default (removing any "command" from it) - Change via the {@link CommandClass} annotation + */ + public final String getCommandPath() { + return path; + } + + private String getcmdpath() { + if (!getClass().isAnnotationPresent(CommandClass.class)) + throw new RuntimeException( + "No @CommandClass annotation on command class " + getClass().getSimpleName() + "!"); + Function, String> getFromClass = cl -> cl.getSimpleName().toLowerCase().replace("commandbase", "") // <-- ... + .replace("command", ""); + String path = getClass().getAnnotation(CommandClass.class).path(); + path = path.length() == 0 ? getFromClass.apply(getClass()) : path; + return path; + } +} //TODO: Test support of Player instead of CommandSender diff --git a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java new file mode 100644 index 0000000..715d078 --- /dev/null +++ b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java @@ -0,0 +1,24 @@ +package buttondevteam.lib.chat; + +import org.bukkit.command.CommandSender; + +import java.util.HashMap; +import java.util.function.Function; + +public class Command2MC extends Command2 { + + private static HashMap> subcommands = new HashMap<>(); + private static HashMap, Function> paramConverters = new HashMap<>(); + + public static boolean handleCommand(CommandSender sender, String commandLine) throws Exception { + return handleCommand(sender, commandLine, subcommands, paramConverters); + } + + public static void registerCommand(Command2MC command) { + registerCommand(command, subcommands, '/'); + } + + public static void addParamConverter(Class cl, Function converter) { + addParamConverter(cl, converter, paramConverters); + } +} diff --git a/ButtonCore/src/main/java/buttondevteam/lib/chat/CommandClass.java b/ButtonCore/src/main/java/buttondevteam/lib/chat/CommandClass.java index 55fcfec..ddfff22 100755 --- a/ButtonCore/src/main/java/buttondevteam/lib/chat/CommandClass.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/chat/CommandClass.java @@ -38,7 +38,7 @@ public @interface CommandClass { boolean excludeFromPath() default false; /** - * The help text to show for the players. + * The help text to show for the players. A usage message will be also shown below it. * * @return The help text */ diff --git a/ButtonCore/src/main/java/buttondevteam/lib/chat/TBMCChatAPI.java b/ButtonCore/src/main/java/buttondevteam/lib/chat/TBMCChatAPI.java index a2da67e..d143d8b 100755 --- a/ButtonCore/src/main/java/buttondevteam/lib/chat/TBMCChatAPI.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/chat/TBMCChatAPI.java @@ -1,9 +1,9 @@ package buttondevteam.lib.chat; -import buttondevteam.component.channel.Channel; -import buttondevteam.component.channel.Channel.RecipientTestResult; import buttondevteam.core.CommandCaller; import buttondevteam.core.MainPlugin; +import buttondevteam.core.component.channel.Channel; +import buttondevteam.core.component.channel.Channel.RecipientTestResult; import buttondevteam.lib.TBMCChatEvent; import buttondevteam.lib.TBMCChatPreprocessEvent; import buttondevteam.lib.TBMCCoreAPI; @@ -160,7 +160,7 @@ public class TBMCChatAPI { } catch (Exception e) { TBMCCoreAPI.SendException("An error occured while registering command " + thecmdclass.getSimpleName(), e); } - } //TODO: onCommand(CommandSender sender, String alias, int arg1, String arg2) (planned for a while) + } /** *

diff --git a/ButtonCore/src/main/java/buttondevteam/lib/player/ChannelPlayerData.java b/ButtonCore/src/main/java/buttondevteam/lib/player/ChannelPlayerData.java index 6cebce8..5f12ca9 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/player/ChannelPlayerData.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/player/ChannelPlayerData.java @@ -1,6 +1,6 @@ package buttondevteam.lib.player; -import buttondevteam.component.channel.Channel; +import buttondevteam.core.component.channel.Channel; import org.bukkit.configuration.file.YamlConfiguration; public class ChannelPlayerData { //I just want this to work diff --git a/ButtonCore/src/main/java/buttondevteam/lib/player/ChromaGamerBase.java b/ButtonCore/src/main/java/buttondevteam/lib/player/ChromaGamerBase.java index 902a00a..6c6ea0b 100755 --- a/ButtonCore/src/main/java/buttondevteam/lib/player/ChromaGamerBase.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/player/ChromaGamerBase.java @@ -1,6 +1,6 @@ package buttondevteam.lib.player; -import buttondevteam.component.channel.Channel; +import buttondevteam.core.component.channel.Channel; import buttondevteam.lib.TBMCCoreAPI; import com.google.common.collect.HashBiMap; import lombok.val; diff --git a/ButtonCore/src/main/java/buttondevteam/lib/player/TBMCPlayerBase.java b/ButtonCore/src/main/java/buttondevteam/lib/player/TBMCPlayerBase.java index ba15bb4..0093c4e 100755 --- a/ButtonCore/src/main/java/buttondevteam/lib/player/TBMCPlayerBase.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/player/TBMCPlayerBase.java @@ -1,6 +1,6 @@ package buttondevteam.lib.player; -import buttondevteam.component.towny.TownyComponent; +import buttondevteam.core.component.towny.TownyComponent; import buttondevteam.lib.TBMCCoreAPI; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; diff --git a/ButtonCore/src/main/resources/plugin.yml b/ButtonCore/src/main/resources/plugin.yml index fb36458..43c609f 100755 --- a/ButtonCore/src/main/resources/plugin.yml +++ b/ButtonCore/src/main/resources/plugin.yml @@ -1,4 +1,4 @@ -name: ButtonCore +name: ThorpeCore main: buttondevteam.core.MainPlugin version: 1.0 author: TBMCPlugins @@ -15,3 +15,4 @@ commands: description: Add or remove a member component: description: Enable or disable or list components + dontrunthiscmd: \ No newline at end of file diff --git a/ButtonProcessor/ButtonProcessor.iml b/ButtonProcessor/ButtonProcessor.iml index cc79963..35bfd14 100755 --- a/ButtonProcessor/ButtonProcessor.iml +++ b/ButtonProcessor/ButtonProcessor.iml @@ -12,6 +12,13 @@ + + + + + + + \ No newline at end of file diff --git a/ButtonProcessor/pom.xml b/ButtonProcessor/pom.xml index 54981ad..975ead3 100755 --- a/ButtonProcessor/pom.xml +++ b/ButtonProcessor/pom.xml @@ -1,40 +1,60 @@ - - 4.0.0 - - com.github.TBMCPlugins - ButtonCore - master-SNAPSHOT - - com.github.TBMCPlugins.ButtonCore - ButtonProcessor - jar - - ButtonProcessor - http://maven.apache.org - - - - - maven-compiler-plugin - - 1.8 - 1.8 - -proc:none - - - - org.apache.maven.plugins - maven-surefire-plugin - - false - - - - - - - - UTF-8 - - + + 4.0.0 + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + + + org.yaml + snakeyaml + 1.21 + compile + + + org.spigotmc + spigot-api + 1.12.2-R0.1-SNAPSHOT + compile + + + + com.github.TBMCPlugins + ButtonCore + master-SNAPSHOT + + com.github.TBMCPlugins.ButtonCore + ButtonProcessor + jar + + ButtonProcessor + http://maven.apache.org + + + + + maven-compiler-plugin + + 1.8 + 1.8 + -proc:none + + + + org.apache.maven.plugins + maven-surefire-plugin + + false + + + + + + + + UTF-8 + + diff --git a/ButtonProcessor/src/main/java/buttondevteam/buttonproc/ButtonProcessor.java b/ButtonProcessor/src/main/java/buttondevteam/buttonproc/ButtonProcessor.java index e9e36ba..f7bb7fe 100755 --- a/ButtonProcessor/src/main/java/buttondevteam/buttonproc/ButtonProcessor.java +++ b/ButtonProcessor/src/main/java/buttondevteam/buttonproc/ButtonProcessor.java @@ -1,17 +1,25 @@ package buttondevteam.buttonproc; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; + import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.lang.model.SourceVersion; -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.Element; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; +import javax.lang.model.element.*; +import javax.tools.Diagnostic; import javax.tools.Diagnostic.Kind; +import javax.tools.FileObject; +import javax.tools.JavaFileObject; +import javax.tools.StandardLocation; +import java.io.File; +import java.io.IOException; +import java.io.Writer; import java.util.List; import java.util.Set; import java.util.function.Function; +import java.util.stream.Collectors; @SupportedAnnotationTypes("buttondevteam.*") public class ButtonProcessor extends AbstractProcessor { @@ -23,7 +31,7 @@ public class ButtonProcessor extends AbstractProcessor { System.out.println("Processing " + targetcl); List annotationMirrors = processingEnv.getElementUtils() .getAllAnnotationMirrors(targetcl); - System.out.println("Annotations: " + annotationMirrors); + //System.out.println("Annotations: " + annotationMirrors); Function hasAnnotation = ann -> annotationMirrors.stream() .anyMatch(am -> am.getAnnotationType().toString().contains(ann)); if (hasAnnotation.apply("ChromaGamerEnforcer") && !hasAnnotation.apply("UserClass") @@ -36,15 +44,67 @@ public class ButtonProcessor extends AbstractProcessor { "No PlayerClass annotation found for " + targetcl.getSimpleName(), targetcl); for (AnnotationMirror annotation : annotationMirrors) { String type = annotation.getAnnotationType().toString(); - System.out.println("Type: " + type); + //System.out.println("Type: " + type); } + processSubcommands(targetcl, annotationMirrors); } } + try { + if (found) { + FileObject fo = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", "commands.yml"); + yc.save(new File(fo.toUri())); + found = false; + } + } catch (IOException e) { + e.printStackTrace(); + } return true; // claim the annotations } - @Override + private YamlConfiguration yc = new YamlConfiguration(); + private boolean found = false; + + private void processSubcommands(Element targetcl, List annotationMirrors) { + if (!(targetcl instanceof ExecutableElement)) + return; + //System.out.println("Annotations: "+annotationMirrors); + if (annotationMirrors.stream().noneMatch(an -> an.getAnnotationType().toString().endsWith("Subcommand"))) + return; + //System.out.print("Processing method: " + targetcl.getEnclosingElement()+" "+targetcl); + ConfigurationSection cs = yc.createSection(targetcl.getEnclosingElement().toString() + + "." + targetcl.getSimpleName().toString()); //Need to do the 2 config sections at once so it doesn't overwrite the class section + System.out.println(targetcl); + cs.set("method", targetcl.toString()); + cs.set("params", ((ExecutableElement) targetcl).getParameters().stream().skip(1).map(p -> { + //String tn=p.asType().toString(); + //return tn.substring(tn.lastIndexOf('.')+1)+" "+p.getSimpleName(); + boolean optional = p.getAnnotationMirrors().stream().anyMatch(am -> am.getAnnotationType().toString().endsWith("Optional")); + if (optional) + return "[" + p.getSimpleName() + "]"; + return "<" + p.getSimpleName() + ">"; + }).collect(Collectors.joining(" "))); + //System.out.println(); + found = true; + } + + @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.latestSupported(); } + + private String fetchSourcePath() { + try { + JavaFileObject generationForPath = processingEnv.getFiler().createSourceFile("PathFor" + getClass().getSimpleName()); + Writer writer = generationForPath.openWriter(); + String sourcePath = generationForPath.toUri().getPath(); + writer.close(); + generationForPath.delete(); + + return sourcePath; + } catch (IOException e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, "Unable to determine source file path!"); + } + + return ""; + } }