From d2ab3511c29696aaf34526de549da1b01becba12 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Fri, 14 Feb 2020 17:36:00 +0100 Subject: [PATCH 1/4] Add subcommand perms, failed attempt at separating command handlers Removed project files Added permission for each subcommand (#89) Made separate instances of the command handler for each plugin Spent a lot of time crafting type arguments then realized it won't work (per-plugin managers) --- .gitignore | 2 +- .idea/ButtonCore.iml | 13 -- .idea/codeStyles/codeStyleConfig.xml | 5 - .idea/compiler.xml | 87 ------------ .idea/encodings.xml | 10 -- .idea/inspectionProfiles/Project_Default.xml | 11 -- ...aven__org_projectlombok_lombok_1_16_16.xml | 14 -- .idea/markdown-exported-files.xml | 8 -- .idea/markdown-navigator.xml | 82 ------------ .../markdown-navigator/profiles_settings.xml | 3 - .idea/misc.xml | 23 ---- .idea/modules.xml | 12 -- .idea/uiDesigner.xml | 124 ------------------ .idea/vcs.xml | 6 - BuildConfigUpdater/BuildConfigUpdater.iml | 55 -------- ButtonProcessor/ButtonProcessor.iml | 40 ------ Chroma-Core/Chroma-Core.iml | 88 ------------- .../buttondevteam/core/ComponentCommand.java | 8 +- .../java/buttondevteam/core/MainPlugin.java | 2 +- .../java/buttondevteam/core/TestPrepare.java | 4 +- .../component/members/MemberComponent.java | 6 +- .../lib/architecture/ButtonPlugin.java | 6 +- .../lib/architecture/Component.java | 22 ++-- .../java/buttondevteam/lib/chat/Command2.java | 19 ++- .../buttondevteam/lib/chat/Command2MC.java | 20 ++- .../buttondevteam/lib/chat/ICommand2.java | 7 +- .../buttondevteam/lib/chat/ICommand2MC.java | 12 +- CorePOM/CorePOM.iml | 22 ---- 28 files changed, 72 insertions(+), 639 deletions(-) delete mode 100755 .idea/ButtonCore.iml delete mode 100644 .idea/codeStyles/codeStyleConfig.xml delete mode 100755 .idea/compiler.xml delete mode 100755 .idea/encodings.xml delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100755 .idea/libraries/Maven__org_projectlombok_lombok_1_16_16.xml delete mode 100644 .idea/markdown-exported-files.xml delete mode 100644 .idea/markdown-navigator.xml delete mode 100644 .idea/markdown-navigator/profiles_settings.xml delete mode 100755 .idea/misc.xml delete mode 100755 .idea/modules.xml delete mode 100644 .idea/uiDesigner.xml delete mode 100755 .idea/vcs.xml delete mode 100644 BuildConfigUpdater/BuildConfigUpdater.iml delete mode 100755 ButtonProcessor/ButtonProcessor.iml delete mode 100644 Chroma-Core/Chroma-Core.iml delete mode 100644 CorePOM/CorePOM.iml diff --git a/.gitignore b/.gitignore index 7219eb8..5bf6210 100755 --- a/.gitignore +++ b/.gitignore @@ -218,7 +218,7 @@ pip-log.txt .mr.developer.cfg .metadata/* TheButtonAutoFlair/out/artifacts/Autoflair/Autoflair.jar -#*.iml +*.iml *.name .idea dependency-reduced-pom.xml diff --git a/.idea/ButtonCore.iml b/.idea/ButtonCore.iml deleted file mode 100755 index c32b2ad..0000000 --- a/.idea/ButtonCore.iml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index a55e7a1..0000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100755 index b5342db..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100755 index adcb5b6..0000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 14d4bba..0000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_projectlombok_lombok_1_16_16.xml b/.idea/libraries/Maven__org_projectlombok_lombok_1_16_16.xml deleted file mode 100755 index d846a35..0000000 --- a/.idea/libraries/Maven__org_projectlombok_lombok_1_16_16.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/markdown-exported-files.xml b/.idea/markdown-exported-files.xml deleted file mode 100644 index 5d1f129..0000000 --- a/.idea/markdown-exported-files.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/markdown-navigator.xml b/.idea/markdown-navigator.xml deleted file mode 100644 index a280ac6..0000000 --- a/.idea/markdown-navigator.xml +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/markdown-navigator/profiles_settings.xml b/.idea/markdown-navigator/profiles_settings.xml deleted file mode 100644 index 57927c5..0000000 --- a/.idea/markdown-navigator/profiles_settings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100755 index 1014481..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100755 index 8c958b0..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml deleted file mode 100644 index e96534f..0000000 --- a/.idea/uiDesigner.xml +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100755 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/BuildConfigUpdater/BuildConfigUpdater.iml b/BuildConfigUpdater/BuildConfigUpdater.iml deleted file mode 100644 index 781a0fd..0000000 --- a/BuildConfigUpdater/BuildConfigUpdater.iml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/ButtonProcessor/ButtonProcessor.iml b/ButtonProcessor/ButtonProcessor.iml deleted file mode 100755 index 6a0a7be..0000000 --- a/ButtonProcessor/ButtonProcessor.iml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Chroma-Core/Chroma-Core.iml b/Chroma-Core/Chroma-Core.iml deleted file mode 100644 index 112e8d8..0000000 --- a/Chroma-Core/Chroma-Core.iml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Chroma-Core/src/main/java/buttondevteam/core/ComponentCommand.java b/Chroma-Core/src/main/java/buttondevteam/core/ComponentCommand.java index 55fbf6f..f7b437e 100644 --- a/Chroma-Core/src/main/java/buttondevteam/core/ComponentCommand.java +++ b/Chroma-Core/src/main/java/buttondevteam/core/ComponentCommand.java @@ -5,6 +5,7 @@ import buttondevteam.lib.architecture.ButtonPlugin; import buttondevteam.lib.architecture.Component; import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.Command2.Subcommand; +import buttondevteam.lib.chat.Command2MC; import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.chat.ICommand2MC; import lombok.val; @@ -18,8 +19,9 @@ import java.util.Optional; "Component command", "Can be used to enable/disable/list components" }) -public class ComponentCommand extends ICommand2MC { - public ComponentCommand() { +public class ComponentCommand extends ICommand2MC { + @Override + public void onRegister(Command2MC manager) { getManager().addParamConverter(Plugin.class, arg -> Bukkit.getPluginManager().getPlugin(arg), "Plugin not found!"); } @@ -29,7 +31,7 @@ public class ComponentCommand extends ICommand2MC { }) public boolean enable(CommandSender sender, Plugin plugin, String component) { if (plugin instanceof ButtonPlugin) { - if (!((ButtonPlugin) plugin).justReload()) { + if (!((ButtonPlugin) plugin).justReload()) { sender.sendMessage("§cCouldn't reload config, check console."); return true; } diff --git a/Chroma-Core/src/main/java/buttondevteam/core/MainPlugin.java b/Chroma-Core/src/main/java/buttondevteam/core/MainPlugin.java index 7557932..6010576 100755 --- a/Chroma-Core/src/main/java/buttondevteam/core/MainPlugin.java +++ b/Chroma-Core/src/main/java/buttondevteam/core/MainPlugin.java @@ -44,7 +44,7 @@ import java.util.Optional; import java.util.UUID; import java.util.logging.Logger; -public class MainPlugin extends ButtonPlugin { +public class MainPlugin extends ButtonPlugin { public static MainPlugin Instance; public static Permission permission; @Nullable diff --git a/Chroma-Core/src/main/java/buttondevteam/core/TestPrepare.java b/Chroma-Core/src/main/java/buttondevteam/core/TestPrepare.java index 13513b4..34521e7 100755 --- a/Chroma-Core/src/main/java/buttondevteam/core/TestPrepare.java +++ b/Chroma-Core/src/main/java/buttondevteam/core/TestPrepare.java @@ -2,13 +2,13 @@ package buttondevteam.core; import buttondevteam.core.component.channel.Channel; import buttondevteam.core.component.channel.ChannelComponent; +import buttondevteam.lib.architecture.ButtonPlugin; 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; @@ -42,7 +42,7 @@ public class TestPrepare { } })); //noinspection unchecked - Component.registerComponent(Mockito.mock(JavaPlugin.class), new ChannelComponent()); + Component.registerComponent(Mockito.mock(ButtonPlugin.class), new ChannelComponent()); TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fg§f", Color.White, "g", null)); } } diff --git a/Chroma-Core/src/main/java/buttondevteam/core/component/members/MemberComponent.java b/Chroma-Core/src/main/java/buttondevteam/core/component/members/MemberComponent.java index d003526..28d0d06 100644 --- a/Chroma-Core/src/main/java/buttondevteam/core/component/members/MemberComponent.java +++ b/Chroma-Core/src/main/java/buttondevteam/core/component/members/MemberComponent.java @@ -62,7 +62,7 @@ public class MemberComponent extends Component implements Listener { @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { - if (checkMember(event.getPlayer()) && (checkRegTime(event.getPlayer()) || checkPlayTime(event.getPlayer()))) { + if (checkMember(event.getPlayer()) && (checkRegTime(event.getPlayer()) || checkPlayTime(event.getPlayer()))) { try { if (permission.playerAddGroup(null, event.getPlayer(), memberGroup().get())) { event.getPlayer().sendMessage("§bYou are a member now. YEEHAW"); @@ -90,8 +90,8 @@ public class MemberComponent extends Component implements Listener { public long getRegTime(Player player) { Instant date = new Date(player.getFirstPlayed()).toInstant().plus(registeredForDays().get(), ChronoUnit.DAYS); - if(date.isBefore(Instant.now())) - return date.toEpochMilli()-Instant.now().toEpochMilli(); + if (date.isBefore(Instant.now())) + return date.toEpochMilli() - Instant.now().toEpochMilli(); return -1; } diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java b/Chroma-Core/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java index b16b447..e202f45 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java +++ b/Chroma-Core/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java @@ -22,9 +22,9 @@ import java.util.Optional; import java.util.Stack; @HasConfig(global = true) -public abstract class ButtonPlugin extends JavaPlugin { - @Getter - private static Command2MC command2MC = new Command2MC(); +public abstract class ButtonPlugin> extends JavaPlugin { + @Getter //Needs to be static as we don't know the plugin when a command is handled + private Command2MC command2MC = new Command2MC<>(); @Getter(AccessLevel.PROTECTED) private IHaveConfig iConfig; private CommentedConfiguration yaml; diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/architecture/Component.java b/Chroma-Core/src/main/java/buttondevteam/lib/architecture/Component.java index c0b7b63..66f01ec 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/architecture/Component.java +++ b/Chroma-Core/src/main/java/buttondevteam/lib/architecture/Component.java @@ -23,7 +23,7 @@ import java.util.stream.Collectors; * Configuration is based on class name */ @HasConfig(global = false) //Used for obtaining javadoc -public abstract class Component { +public abstract class Component { private static HashMap, Component> components = new HashMap<>(); @Getter @@ -44,12 +44,11 @@ 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.
- * 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) */ - public static boolean registerComponent(T plugin, Component component) { + public static boolean registerComponent(T plugin, Component component) { return registerUnregisterComponent(plugin, component, true); } @@ -61,11 +60,11 @@ public abstract class Component { * @param component The component to unregister * @return Whether the component is unregistered successfully (it also got disabled) */ - public static boolean unregisterComponent(T plugin, Component component) { + public static boolean unregisterComponent(T plugin, Component component) { return registerUnregisterComponent(plugin, component, false); } - public static boolean registerUnregisterComponent(T plugin, Component component, boolean register) { + public static boolean registerUnregisterComponent(T plugin, Component component, boolean register) { try { val metaAnn = component.getClass().getAnnotation(ComponentMetadata.class); if (metaAnn != null) { @@ -86,8 +85,7 @@ public abstract class Component { updateConfig(plugin, component); component.register(plugin); components.put(component.getClass(), component); - if (plugin instanceof ButtonPlugin) - ((ButtonPlugin) plugin).getComponentStack().push(component); + plugin.getComponentStack().push(component); if (ComponentManager.areComponentsEnabled() && component.shouldBeEnabled().get()) { try { //Enable components registered after the previous ones getting enabled setComponentEnabled(component, true); @@ -97,7 +95,6 @@ public abstract class Component { return true; } } - return true; //Component shouldn't be enabled } else { if (!components.containsKey(component.getClass())) return true; //Already unregistered @@ -111,8 +108,8 @@ public abstract class Component { } component.unregister(plugin); components.remove(component.getClass()); - return true; } + return true; } catch (Exception e) { TBMCCoreAPI.SendException("Failed to " + (register ? "" : "un") + "register component " + component.getClassName() + "!", e); return false; @@ -125,7 +122,7 @@ public abstract class Component { * * @param component The component to register */ - public static void setComponentEnabled(Component component, boolean enabled) throws UnregisteredComponentException { + public static void setComponentEnabled(Component component, boolean enabled) throws UnregisteredComponentException { if (!components.containsKey(component.getClass())) throw new UnregisteredComponentException(component); if (component.enabled == enabled) return; //Don't do anything @@ -142,6 +139,7 @@ public abstract class Component { } else { component.disable(); //TBMCChatAPI.RemoveCommands(component); - TODO + component.getPlugin().getCommand2MC().unregisterCommand(); } } @@ -207,8 +205,8 @@ public abstract class Component { * * @param commandBase Custom coded command class */ - protected final void registerCommand(ICommand2MC commandBase) { - ButtonPlugin.getCommand2MC().registerCommand(commandBase); + protected final > void registerCommand(ICommand2MC commandBase) { + getPlugin().getCommand2MC().registerCommand(commandBase); } /** diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.java b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.java index 3983f61..36c3324 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.java +++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.java @@ -12,6 +12,7 @@ import lombok.val; import org.bukkit.Bukkit; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.scheduler.BukkitTask; +import org.jetbrains.annotations.NotNull; import java.io.InputStreamReader; import java.lang.annotation.ElementType; @@ -287,7 +288,7 @@ public abstract class Command2 var ht = command.getHelpText(method, ann); if (ht != null) { 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' + getCommandPath(method.getName(), ' '); //Add method name, unless it's 'def' ht = getParameterHelp(method, ht, subcommand); subcommands.put(subcommand, new SubcommandData<>(method, command, ht)); //Result of the above (def) is that it will show the help text scmdHelpList.add(subcommand); @@ -355,4 +356,20 @@ public abstract class Command2 /*public Set getAllSubcommands() { return Collections.unmodifiableSet(subcommands.keySet()); }*/ + + public void unregisterCommand() { + + } + + /** + * It will start with the given replace char. + * + * @param methodName The method's name, method.getName() + * @param replaceChar The character to use between subcommands + * @return The command path starting with the replace char. + */ + @NotNull + public String getCommandPath(String methodName, char replaceChar) { + return methodName.equals("def") ? "" : replaceChar + methodName.replace('_', replaceChar).toLowerCase(); + } } diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.java b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.java index 2f52c69..ba4331e 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.java +++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.java @@ -1,6 +1,7 @@ package buttondevteam.lib.chat; import buttondevteam.core.MainPlugin; +import buttondevteam.lib.architecture.ButtonPlugin; import lombok.val; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; @@ -19,9 +20,9 @@ import java.util.Arrays; import java.util.HashMap; import java.util.function.Function; -public class Command2MC extends Command2 implements Listener { +public class Command2MC> extends Command2, Command2MCSender> implements Listener { @Override - public void registerCommand(ICommand2MC command) { + public void registerCommand(ICommand2MC command) { super.registerCommand(command, '/'); var perm = "chroma.command." + command.getCommandPath().replace(' ', '.'); if (Bukkit.getPluginManager().getPermission(perm) == null) //Check needed for plugin reset @@ -29,6 +30,13 @@ public class Command2MC extends Command2 implemen PermissionDefault.TRUE)); //Allow commands by default, it will check mod-only for (val method : command.getClass().getMethods()) { if (!method.isAnnotationPresent(Subcommand.class)) continue; + var path = getCommandPath(method.getName(), '.'); + if (path.length() > 0) { + var subperm = perm + path; + if (Bukkit.getPluginManager().getPermission(subperm) == null) //Check needed for plugin reset + Bukkit.getPluginManager().addPermission(new Permission(subperm, + PermissionDefault.TRUE)); //Allow commands by default, it will check mod-only + } String pg = permGroup(command, method); if (pg.length() == 0) continue; perm = "chroma." + pg; @@ -39,11 +47,11 @@ public class Command2MC extends Command2 implemen } @Override - public boolean hasPermission(Command2MCSender sender, ICommand2MC command, Method method) { + public boolean hasPermission(Command2MCSender sender, ICommand2MC command, Method method) { return hasPermission(sender.getSender(), command, method); } - public boolean hasPermission(CommandSender sender, ICommand2MC command, Method method) { + public boolean hasPermission(CommandSender sender, ICommand2MC command, Method method) { if (sender instanceof ConsoleCommandSender) return true; //Always allow the console String pg; boolean p = true; @@ -73,7 +81,7 @@ public class Command2MC extends Command2 implemen * @param method The subcommand to check * @return The permission group for the subcommand or empty string */ - private String permGroup(ICommand2MC command, Method method) { + private String permGroup(ICommand2MC command, Method method) { val sc = method.getAnnotation(Subcommand.class); if (sc != null && sc.permGroup().length() > 0) { return sc.permGroup(); @@ -121,7 +129,7 @@ public class Command2MC extends Command2 implemen String subcommand = commandline.substring(0, i).toLowerCase(); if (subcommand.length() == 0 || subcommand.charAt(0) != '/') subcommand = '/' + subcommand; //Console //System.out.println("Subcommand: " + subcommand); - SubcommandData sd = subcommands.get(subcommand); //O(1) + SubcommandData> sd = subcommands.get(subcommand); //O(1) if (sd == null) continue; //System.out.println("ht: " + Arrays.toString(sd.helpText)); Arrays.stream(sd.helpText).skip(1).map(ht -> new HashMap.SimpleEntry<>(ht, subcommands.get(ht))).filter(e -> e.getValue() != null) diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2.java b/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2.java index d0a202a..a6cd34c 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2.java +++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2.java @@ -45,10 +45,13 @@ public abstract class ICommand2 { private final String path; @Getter - private final Command2 manager; //TIL that if I use a raw type on a variable then none of the type args will work (including what's defined on a method, not on the type) + private Command2 manager; //TIL that if I use a raw type on a variable then none of the type args will work (including what's defined on a method, not on the type) - public ICommand2(Command2 manager) { + public > ICommand2() { path = getcmdpath(); + } + + public > void onRegister(Command2 manager) { this.manager = manager; } diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2MC.java b/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2MC.java index 566285d..75121a1 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2MC.java +++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2MC.java @@ -2,8 +2,16 @@ package buttondevteam.lib.chat; import buttondevteam.lib.architecture.ButtonPlugin; -public abstract class ICommand2MC extends ICommand2 { +public abstract class ICommand2MC> extends ICommand2 { public ICommand2MC() { - super(ButtonPlugin.getCommand2MC()); + } + + public void onRegister(Command2MC manager) { + } + + @Override + public > void onRegister(Command2 manager) { + super.onRegister(manager); + onRegister((Command2MC) manager); } } diff --git a/CorePOM/CorePOM.iml b/CorePOM/CorePOM.iml deleted file mode 100644 index de84cf2..0000000 --- a/CorePOM/CorePOM.iml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 23f3c0f13347e6039c9192655d657e6b8615ab3c Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Fri, 14 Feb 2020 19:20:20 +0100 Subject: [PATCH 2/4] Add plugin & component to commands, unregister on disable #88 --- .../buttondevteam/core/ComponentCommand.java | 8 ++-- .../java/buttondevteam/core/MainPlugin.java | 6 +-- .../java/buttondevteam/core/TestPrepare.java | 4 +- .../lib/architecture/ButtonPlugin.java | 17 ++++++-- .../lib/architecture/Component.java | 29 ++++++++------ .../java/buttondevteam/lib/chat/Command2.java | 18 ++++++++- .../buttondevteam/lib/chat/Command2MC.java | 34 +++++++++++++--- .../buttondevteam/lib/chat/ICommand2.java | 7 +--- .../buttondevteam/lib/chat/ICommand2MC.java | 39 ++++++++++++++++--- 9 files changed, 119 insertions(+), 43 deletions(-) diff --git a/Chroma-Core/src/main/java/buttondevteam/core/ComponentCommand.java b/Chroma-Core/src/main/java/buttondevteam/core/ComponentCommand.java index f7b437e..55fbf6f 100644 --- a/Chroma-Core/src/main/java/buttondevteam/core/ComponentCommand.java +++ b/Chroma-Core/src/main/java/buttondevteam/core/ComponentCommand.java @@ -5,7 +5,6 @@ import buttondevteam.lib.architecture.ButtonPlugin; import buttondevteam.lib.architecture.Component; import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.Command2.Subcommand; -import buttondevteam.lib.chat.Command2MC; import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.chat.ICommand2MC; import lombok.val; @@ -19,9 +18,8 @@ import java.util.Optional; "Component command", "Can be used to enable/disable/list components" }) -public class ComponentCommand extends ICommand2MC { - @Override - public void onRegister(Command2MC manager) { +public class ComponentCommand extends ICommand2MC { + public ComponentCommand() { getManager().addParamConverter(Plugin.class, arg -> Bukkit.getPluginManager().getPlugin(arg), "Plugin not found!"); } @@ -31,7 +29,7 @@ public class ComponentCommand extends ICommand2MC { }) public boolean enable(CommandSender sender, Plugin plugin, String component) { if (plugin instanceof ButtonPlugin) { - if (!((ButtonPlugin) plugin).justReload()) { + if (!((ButtonPlugin) plugin).justReload()) { sender.sendMessage("§cCouldn't reload config, check console."); return true; } diff --git a/Chroma-Core/src/main/java/buttondevteam/core/MainPlugin.java b/Chroma-Core/src/main/java/buttondevteam/core/MainPlugin.java index 6010576..b450bf4 100755 --- a/Chroma-Core/src/main/java/buttondevteam/core/MainPlugin.java +++ b/Chroma-Core/src/main/java/buttondevteam/core/MainPlugin.java @@ -44,7 +44,7 @@ import java.util.Optional; import java.util.UUID; import java.util.logging.Logger; -public class MainPlugin extends ButtonPlugin { +public class MainPlugin extends ButtonPlugin { public static MainPlugin Instance; public static Permission permission; @Nullable @@ -117,8 +117,8 @@ public class MainPlugin extends ButtonPlugin { if (Bukkit.getPluginManager().isPluginEnabled("Votifier") && economy != null) Component.registerComponent(this, new VotifierComponent(economy)); ComponentManager.enableComponents(); - getCommand2MC().registerCommand(new ComponentCommand()); - getCommand2MC().registerCommand(new ChromaCommand()); + registerCommand(new ComponentCommand()); + registerCommand(new ChromaCommand()); TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this); TBMCCoreAPI.RegisterEventsForExceptions(getCommand2MC(), this); ChromaGamerBase.addConverter(commandSender -> Optional.ofNullable(commandSender instanceof ConsoleCommandSender || commandSender instanceof BlockCommandSender diff --git a/Chroma-Core/src/main/java/buttondevteam/core/TestPrepare.java b/Chroma-Core/src/main/java/buttondevteam/core/TestPrepare.java index 34521e7..13513b4 100755 --- a/Chroma-Core/src/main/java/buttondevteam/core/TestPrepare.java +++ b/Chroma-Core/src/main/java/buttondevteam/core/TestPrepare.java @@ -2,13 +2,13 @@ package buttondevteam.core; import buttondevteam.core.component.channel.Channel; import buttondevteam.core.component.channel.ChannelComponent; -import buttondevteam.lib.architecture.ButtonPlugin; 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; @@ -42,7 +42,7 @@ public class TestPrepare { } })); //noinspection unchecked - Component.registerComponent(Mockito.mock(ButtonPlugin.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/Chroma-Core/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java b/Chroma-Core/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java index e202f45..cf7db91 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java +++ b/Chroma-Core/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java @@ -4,6 +4,7 @@ import buttondevteam.buttonproc.HasConfig; import buttondevteam.core.ComponentManager; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.chat.Command2MC; +import buttondevteam.lib.chat.ICommand2MC; import lombok.AccessLevel; import lombok.Getter; import org.bukkit.configuration.InvalidConfigurationException; @@ -22,9 +23,9 @@ import java.util.Optional; import java.util.Stack; @HasConfig(global = true) -public abstract class ButtonPlugin> extends JavaPlugin { +public abstract class ButtonPlugin extends JavaPlugin { @Getter //Needs to be static as we don't know the plugin when a command is handled - private Command2MC command2MC = new Command2MC<>(); + private static Command2MC command2MC = new Command2MC(); @Getter(AccessLevel.PROTECTED) private IHaveConfig iConfig; private CommentedConfiguration yaml; @@ -84,7 +85,7 @@ public abstract class ButtonPlugin> extends JavaPlug if (ConfigData.saveNow(getConfig())) getLogger().info("Saved configuration changes."); iConfig = null; //Clearing the hashmap is not enough, we need to update the section as well - //TBMCChatAPI.RemoveCommands(this); - TODO + getCommand2MC().unregisterCommands(this); } catch (Exception e) { TBMCCoreAPI.SendException("Error while disabling plugin " + getName() + "!", e); } @@ -147,6 +148,16 @@ public abstract class ButtonPlugin> extends JavaPlug } } + /** + * Registers command and sets its plugin. + * + * @param command The command to register + */ + protected void registerCommand(ICommand2MC command) { + command.registerToPlugin(this); + getCommand2MC().registerCommand(command); + } + @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface ConfigOpts { diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/architecture/Component.java b/Chroma-Core/src/main/java/buttondevteam/lib/architecture/Component.java index 66f01ec..ba9925f 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/architecture/Component.java +++ b/Chroma-Core/src/main/java/buttondevteam/lib/architecture/Component.java @@ -23,8 +23,8 @@ import java.util.stream.Collectors; * Configuration is based on class name */ @HasConfig(global = false) //Used for obtaining javadoc -public abstract class Component { - private static HashMap, Component> components = new HashMap<>(); +public abstract class Component { + @SuppressWarnings("rawtypes") private static HashMap, Component> components = new HashMap<>(); @Getter private boolean enabled = false; @@ -44,11 +44,12 @@ 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.
+ * 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) */ - public static boolean registerComponent(T plugin, Component component) { + public static boolean registerComponent(T plugin, Component component) { return registerUnregisterComponent(plugin, component, true); } @@ -64,11 +65,11 @@ public abstract class Component { return registerUnregisterComponent(plugin, component, false); } - public static boolean registerUnregisterComponent(T plugin, Component component, boolean register) { + public static boolean registerUnregisterComponent(T plugin, Component component, boolean register) { try { val metaAnn = component.getClass().getAnnotation(ComponentMetadata.class); if (metaAnn != null) { - Class[] dependencies = metaAnn.depends(); + @SuppressWarnings("rawtypes") Class[] dependencies = metaAnn.depends(); for (val dep : dependencies) { //TODO: Support dependencies at enable/disable as well if (!components.containsKey(dep)) { plugin.getLogger().warning("Failed to " + (register ? "" : "un") + "register component " + component.getClassName() + " as a required dependency is missing/disabled: " + dep.getSimpleName()); @@ -85,7 +86,8 @@ public abstract class Component { updateConfig(plugin, component); component.register(plugin); components.put(component.getClass(), component); - plugin.getComponentStack().push(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); @@ -138,8 +140,7 @@ public abstract class Component { //System.out.println("Done enabling "+component.getClassName()); } else { component.disable(); - //TBMCChatAPI.RemoveCommands(component); - TODO - component.getPlugin().getCommand2MC().unregisterCommand(); + ButtonPlugin.getCommand2MC().unregisterCommands(component); } } @@ -160,6 +161,7 @@ public abstract class Component { * * @return The currently registered components */ + @SuppressWarnings("rawtypes") public static Map, Component> getComponents() { return Collections.unmodifiableMap(components); } @@ -200,13 +202,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}. + * Registers a command 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 + * @param command Custom coded command class */ - protected final > void registerCommand(ICommand2MC commandBase) { - getPlugin().getCommand2MC().registerCommand(commandBase); + protected final void registerCommand(ICommand2MC command) { + if (plugin instanceof ButtonPlugin) + command.registerToPlugin((ButtonPlugin) plugin); + command.registerToComponent(this); + ButtonPlugin.getCommand2MC().registerCommand(command); } /** diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.java b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.java index 36c3324..a9aead8 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.java +++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.java @@ -114,6 +114,8 @@ public abstract class Command2 private ArrayList commandHelp = new ArrayList<>(); //Mainly needed by Discord + private char commandChar; + /** * Adds a param converter that obtains a specific object from a string parameter. * The converter may return null. @@ -260,6 +262,7 @@ public abstract class Command2 public abstract void registerCommand(TC command); protected void registerCommand(TC command, @SuppressWarnings("SameParameterValue") char commandChar) { + this.commandChar = commandChar; val path = command.getCommandPath(); int x = path.indexOf(' '); val mainPath = commandChar + path.substring(0, x == -1 ? path.length() : x); @@ -357,8 +360,19 @@ public abstract class Command2 return Collections.unmodifiableSet(subcommands.keySet()); }*/ - public void unregisterCommand() { - + /** + * Unregisters all of the subcommands in the given command. + * + * @param command The command object + */ + public void unregisterCommand(ICommand2 command) { + var path = command.getCommandPath(); + for (val method : command.getClass().getMethods()) { + val ann = method.getAnnotation(Subcommand.class); + if (ann == null) continue; + val subcommand = commandChar + path + getCommandPath(method.getName(), ' '); + subcommands.remove(subcommand); + } } /** diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.java b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.java index ba4331e..ca7b917 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.java +++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.java @@ -2,6 +2,7 @@ package buttondevteam.lib.chat; import buttondevteam.core.MainPlugin; import buttondevteam.lib.architecture.ButtonPlugin; +import buttondevteam.lib.architecture.Component; import lombok.val; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; @@ -18,11 +19,17 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Arrays; import java.util.HashMap; +import java.util.Optional; import java.util.function.Function; -public class Command2MC> extends Command2, Command2MCSender> implements Listener { +public class Command2MC extends Command2 implements Listener { + /** + * Don't use directly, use the method in Component and ButtonPlugin to automatically unregister the command when needed. + * + * @param command The command to register + */ @Override - public void registerCommand(ICommand2MC command) { + public void registerCommand(ICommand2MC command) { super.registerCommand(command, '/'); var perm = "chroma.command." + command.getCommandPath().replace(' ', '.'); if (Bukkit.getPluginManager().getPermission(perm) == null) //Check needed for plugin reset @@ -47,11 +54,11 @@ public class Command2MC> extends Command2 command, Method method) { + public boolean hasPermission(Command2MCSender sender, ICommand2MC command, Method method) { return hasPermission(sender.getSender(), command, method); } - public boolean hasPermission(CommandSender sender, ICommand2MC command, Method method) { + public boolean hasPermission(CommandSender sender, ICommand2MC command, Method method) { if (sender instanceof ConsoleCommandSender) return true; //Always allow the console String pg; boolean p = true; @@ -81,7 +88,7 @@ public class Command2MC> extends Command2 command, Method method) { + private String permGroup(ICommand2MC command, Method method) { val sc = method.getAnnotation(Subcommand.class); if (sc != null && sc.permGroup().length() > 0) { return sc.permGroup(); @@ -120,6 +127,21 @@ public class Command2MC> extends Command2 sd.command).filter(cmd -> plugin.equals(cmd.getPlugin())).toArray(ICommand2MC[]::new); + for (var cmd : cmds) + unregisterCommand(cmd);*/ + subcommands.values().removeIf(sd -> plugin.equals(sd.command.getPlugin())); + } + + public void unregisterCommands(Component component) { + /*var cmds = subcommands.values().stream().map(sd -> sd.command).filter(cmd -> component.equals(cmd.getComponent())).toArray(ICommand2MC[]::new); + for (var cmd : cmds) + unregisterCommand(cmd);*/ + subcommands.values().removeIf(sd -> Optional.ofNullable(sd.command.getComponent()) + .map(comp -> component.getClass().getSimpleName().equals(comp.getClass().getSimpleName())).orElse(false)); + } + @EventHandler private void handleTabComplete(TabCompleteEvent event) { String commandline = event.getBuffer(); @@ -129,7 +151,7 @@ public class Command2MC> extends Command2> sd = subcommands.get(subcommand); //O(1) + SubcommandData sd = subcommands.get(subcommand); //O(1) if (sd == null) continue; //System.out.println("ht: " + Arrays.toString(sd.helpText)); Arrays.stream(sd.helpText).skip(1).map(ht -> new HashMap.SimpleEntry<>(ht, subcommands.get(ht))).filter(e -> e.getValue() != null) diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2.java b/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2.java index a6cd34c..fc49c75 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2.java +++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2.java @@ -45,13 +45,10 @@ public abstract class ICommand2 { private final String path; @Getter - private Command2 manager; //TIL that if I use a raw type on a variable then none of the type args will work (including what's defined on a method, not on the type) + private final Command2 manager; //TIL that if I use a raw type on a variable then none of the type args will work (including what's defined on a method, not on the type) - public > ICommand2() { + public > ICommand2(Command2 manager) { path = getcmdpath(); - } - - public > void onRegister(Command2 manager) { this.manager = manager; } diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2MC.java b/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2MC.java index 75121a1..af12d61 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2MC.java +++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2MC.java @@ -1,17 +1,46 @@ package buttondevteam.lib.chat; import buttondevteam.lib.architecture.ButtonPlugin; +import buttondevteam.lib.architecture.Component; +import lombok.Getter; + +import javax.annotation.Nullable; + +@SuppressWarnings("JavadocReference") +public abstract class ICommand2MC extends ICommand2 { + @Getter + private ButtonPlugin plugin; + @Getter + @Nullable + private Component component; -public abstract class ICommand2MC> extends ICommand2 { public ICommand2MC() { + super(ButtonPlugin.getCommand2MC()); } - public void onRegister(Command2MC manager) { + /** + * Called from {@link buttondevteam.lib.architecture.Component#registerCommand(ICommand2MC)} and {@link ButtonPlugin#registerCommand(ICommand2MC)} + */ + public void registerToPlugin(ButtonPlugin plugin) { + if (this.plugin == null) + this.plugin = plugin; + else + throw new IllegalStateException("The command is already assigned to a plugin!"); } - @Override + /** + * Called from {@link buttondevteam.lib.architecture.Component#registerCommand(ICommand2MC)} + */ + public void registerToComponent(Component component) { + if (this.component == null) + this.component = component; + else + throw new IllegalStateException("The command is already assigned to a component!"); + } + + /*@Override public > void onRegister(Command2 manager) { super.onRegister(manager); - onRegister((Command2MC) manager); - } + onRegister((Command2MC) manager); //If ICommand2 is inherited with the same type arg, this would fail but I don't want to add another type param to ICommand2 + } //For example: class IOffender extends ICommand2*/ } From c947c887a139cd6a59b753a8f652fe08a557af24 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 15 Feb 2020 00:22:34 +0100 Subject: [PATCH 3/4] Fix found issues, finish /member command #69 --- .../core/component/members/MemberCommand.java | 38 +++++++------ .../component/members/MemberComponent.java | 53 +++++++++++++------ .../restart/ScheduledRestartCommand.java | 3 ++ .../buttondevteam/lib/chat/Command2MC.java | 13 +++-- 4 files changed, 70 insertions(+), 37 deletions(-) diff --git a/Chroma-Core/src/main/java/buttondevteam/core/component/members/MemberCommand.java b/Chroma-Core/src/main/java/buttondevteam/core/component/members/MemberCommand.java index 395b71c..207e182 100644 --- a/Chroma-Core/src/main/java/buttondevteam/core/component/members/MemberCommand.java +++ b/Chroma-Core/src/main/java/buttondevteam/core/component/members/MemberCommand.java @@ -9,13 +9,9 @@ import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.util.Date; +import java.util.concurrent.TimeUnit; -import static buttondevteam.core.MainPlugin.permission; - -@CommandClass(modOnly = true, path = "member", helpText = { // +@CommandClass(path = "member", helpText = { // "Member command", // "Add or remove server members.", // }) @@ -27,12 +23,12 @@ public class MemberCommand extends ICommand2MC { this.component = component; } - @Command2.Subcommand + @Command2.Subcommand(permGroup = Command2.Subcommand.MOD_GROUP) public boolean add(CommandSender sender, OfflinePlayer player) { return addRemove(sender, player, true); } - @Command2.Subcommand + @Command2.Subcommand(permGroup = Command2.Subcommand.MOD_GROUP) public boolean remove(CommandSender sender, OfflinePlayer player) { return addRemove(sender, player, false); } @@ -53,17 +49,25 @@ public class MemberCommand extends ICommand2MC { } @Command2.Subcommand - public void def(CommandSender sender) { - if(!(sender instanceof Player)) { - sender.sendMessage("§cYou need to be a player to use this command."); - return; - } - Player player= (Player) sender; + public void def(Player player) { String msg; - if (component.checkMember(player)) - msg="You are a member."; + if (!component.checkNotMember(player)) + msg = "You are a member."; else { - component.getRegTime(player); + double pt = component.getPlayTime(player); + long rt = component.getRegTime(player); + if (pt == -1 || rt == -1) { + Boolean result = component.addPlayerAsMember(player); + if (result == null) + msg = "Can't assign member group because groups are not supported by the permissions plugin."; + else if (result) + msg = "You meet all the requirements."; + else + msg = "You should be a member but failed to add you to the group."; + } else + msg = String.format("You need to play for %.2f hours total or play for %d more days to become a member.", + pt, TimeUnit.MILLISECONDS.toDays(rt)); } + player.sendMessage(msg); } } diff --git a/Chroma-Core/src/main/java/buttondevteam/core/component/members/MemberComponent.java b/Chroma-Core/src/main/java/buttondevteam/core/component/members/MemberComponent.java index 28d0d06..8151d2e 100644 --- a/Chroma-Core/src/main/java/buttondevteam/core/component/members/MemberComponent.java +++ b/Chroma-Core/src/main/java/buttondevteam/core/component/members/MemberComponent.java @@ -62,37 +62,60 @@ public class MemberComponent extends Component implements Listener { @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { - if (checkMember(event.getPlayer()) && (checkRegTime(event.getPlayer()) || checkPlayTime(event.getPlayer()))) { - try { - if (permission.playerAddGroup(null, event.getPlayer(), memberGroup().get())) { - event.getPlayer().sendMessage("§bYou are a member now. YEEHAW"); - MainPlugin.Instance.getLogger().info("Added " + event.getPlayer().getName() + " as a member."); - } else { - MainPlugin.Instance.getLogger().warning("Failed to assign the member role! Please make sure the member group exists or disable the component if it's unused."); - } - } catch (UnsupportedOperationException e) { - MainPlugin.Instance.getLogger().warning("Failed to assign the member role! Groups are not supported by the permissions implementation."); - } + if (checkNotMember(event.getPlayer()) && (checkRegTime(event.getPlayer()) || checkPlayTime(event.getPlayer()))) { + addPlayerAsMember(event.getPlayer()); } } - public boolean checkMember(Player player) { + public Boolean addPlayerAsMember(Player player) { + try { + if (permission.playerAddGroup(null, player, memberGroup().get())) { + player.sendMessage("§bYou are a member now!"); + MainPlugin.Instance.getLogger().info("Added " + player.getName() + " as a member."); + return true; + } else { + MainPlugin.Instance.getLogger().warning("Failed to assign the member role! Please make sure the member group exists or disable the component if it's unused."); + return false; + } + } catch (UnsupportedOperationException e) { + MainPlugin.Instance.getLogger().warning("Failed to assign the member role! Groups are not supported by the permissions implementation."); + return null; + } + } + + public boolean checkNotMember(Player player) { return permission != null && !permission.playerInGroup(player, memberGroup().get()); } public boolean checkRegTime(Player player) { - return new Date(player.getFirstPlayed()).toInstant().plus(registeredForDays().get(), ChronoUnit.DAYS).isBefore(Instant.now()); + return getRegTime(player) == -1; } public boolean checkPlayTime(Player player) { - return player.getStatistic(playtime.getKey()) > playtime.getValue() * playedHours().get(); + return getPlayTime(player) > playtime.getValue() * playedHours().get(); } + /** + * Returns milliseconds + */ public long getRegTime(Player player) { Instant date = new Date(player.getFirstPlayed()).toInstant().plus(registeredForDays().get(), ChronoUnit.DAYS); - if (date.isBefore(Instant.now())) + if (date.isAfter(Instant.now())) return date.toEpochMilli() - Instant.now().toEpochMilli(); return -1; } + public int getPlayTimeTotal(Player player) { + return player.getStatistic(playtime.getKey()); + } + + /** + * Returns hours + */ + public double getPlayTime(Player player) { + double pt = playedHours().get() - (double) getPlayTimeTotal(player) / playtime.getValue(); + if (pt < 0) return -1; + return pt; + } + } diff --git a/Chroma-Core/src/main/java/buttondevteam/core/component/restart/ScheduledRestartCommand.java b/Chroma-Core/src/main/java/buttondevteam/core/component/restart/ScheduledRestartCommand.java index e9fd7c0..1182629 100755 --- a/Chroma-Core/src/main/java/buttondevteam/core/component/restart/ScheduledRestartCommand.java +++ b/Chroma-Core/src/main/java/buttondevteam/core/component/restart/ScheduledRestartCommand.java @@ -18,6 +18,8 @@ import org.bukkit.boss.BossBar; import org.bukkit.command.CommandSender; import org.bukkit.scheduler.BukkitTask; +import javax.annotation.Nonnull; + @CommandClass(modOnly = true, path = "schrestart", helpText = { "Scheduled restart", // "This command restarts the server 1 minute after it's executed, warning players every 10 seconds.", // @@ -31,6 +33,7 @@ public class ScheduledRestartCommand extends ICommand2MC { private BukkitTask restarttask; private volatile BossBar restartbar; @Getter + @Nonnull private final RestartComponent component; @Command2.Subcommand diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.java b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.java index ca7b917..3093f9a 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.java +++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.java @@ -60,6 +60,7 @@ public class Command2MC extends Command2 implemen public boolean hasPermission(CommandSender sender, ICommand2MC command, Method method) { if (sender instanceof ConsoleCommandSender) return true; //Always allow the console + if (command == null) return true; //Allow viewing the command - it doesn't do anything anyway String pg; boolean p = true; String[] perms = { @@ -89,9 +90,11 @@ public class Command2MC extends Command2 implemen * @return The permission group for the subcommand or empty string */ private String permGroup(ICommand2MC command, Method method) { - val sc = method.getAnnotation(Subcommand.class); - if (sc != null && sc.permGroup().length() > 0) { - return sc.permGroup(); + if (method != null) { + val sc = method.getAnnotation(Subcommand.class); + if (sc != null && sc.permGroup().length() > 0) { + return sc.permGroup(); + } } if (getAnnForValue(command.getClass(), CommandClass.class, CommandClass::modOnly, false)) return Subcommand.MOD_GROUP; @@ -131,14 +134,14 @@ public class Command2MC extends Command2 implemen /*var cmds = subcommands.values().stream().map(sd -> sd.command).filter(cmd -> plugin.equals(cmd.getPlugin())).toArray(ICommand2MC[]::new); for (var cmd : cmds) unregisterCommand(cmd);*/ - subcommands.values().removeIf(sd -> plugin.equals(sd.command.getPlugin())); + subcommands.values().removeIf(sd -> Optional.ofNullable(sd.command).map(ICommand2MC::getPlugin).map(plugin::equals).orElse(false)); } public void unregisterCommands(Component component) { /*var cmds = subcommands.values().stream().map(sd -> sd.command).filter(cmd -> component.equals(cmd.getComponent())).toArray(ICommand2MC[]::new); for (var cmd : cmds) unregisterCommand(cmd);*/ - subcommands.values().removeIf(sd -> Optional.ofNullable(sd.command.getComponent()) + subcommands.values().removeIf(sd -> Optional.ofNullable(sd.command).map(ICommand2MC::getComponent) .map(comp -> component.getClass().getSimpleName().equals(comp.getClass().getSimpleName())).orElse(false)); } From dd1f42d4200edc878b9e9fec5deb913e2525bbd1 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sun, 16 Feb 2020 18:21:10 +0100 Subject: [PATCH 4/4] Check subcommand perms, show help text on wrong sender type #89 --- .../src/main/java/buttondevteam/lib/chat/Command2.java | 1 + .../src/main/java/buttondevteam/lib/chat/Command2MC.java | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.java b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.java index a9aead8..1d20d08 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.java +++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.java @@ -186,6 +186,7 @@ public abstract class Command2 params.add(cg); else { sender.sendMessage("§cYou need to be a " + sendertype.getSimpleName() + " to use this command."); + sender.sendMessage(sd.helpText); //Send what the command is about, could be useful for commands like /member where some subcommands aren't player-only return; } val paramArr = sd.method.getParameters(); diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.java b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.java index 3093f9a..ff4b7f4 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.java +++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.java @@ -63,8 +63,11 @@ public class Command2MC extends Command2 implemen if (command == null) return true; //Allow viewing the command - it doesn't do anything anyway String pg; boolean p = true; + var cmdperm = "chroma.command." + command.getCommandPath().replace(' ', '.'); + var path = getCommandPath(method.getName(), '.'); String[] perms = { - "chroma.command." + command.getCommandPath().replace(' ', '.'), + path.length() > 0 ? cmdperm + path : null, + cmdperm, (pg = permGroup(command, method)).length() > 0 ? "chroma." + pg : null }; for (String perm : perms) {