From c8067257f95d0b4681dd8f9fbad39d0b27bcedc5 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 8 Apr 2019 12:46:47 +0200 Subject: [PATCH 01/12] Implemented config & doc pregen #59 The doc gen works --- ...1) (com.github.TBMCPlugins.ButtonCore).iml | 2 +- .../core/component/channel/Channel.java | 2 +- .../lib/architecture/ButtonPlugin.java | 1 + .../lib/architecture/Component.java | 1 + .../lib/architecture/ConfigData.java | 2 ++ .../lib/architecture/IHaveConfig.java | 30 +++++++++++++++++-- .../buttonproc/ConfigProcessor.java | 26 ++++++++++++++-- 7 files changed, 58 insertions(+), 6 deletions(-) diff --git a/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml b/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml index 7c2fa83..3c34336 100644 --- a/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml +++ b/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml @@ -21,7 +21,7 @@ - + diff --git a/ButtonCore/src/main/java/buttondevteam/core/component/channel/Channel.java b/ButtonCore/src/main/java/buttondevteam/core/component/channel/Channel.java index c643880..120615c 100755 --- a/ButtonCore/src/main/java/buttondevteam/core/component/channel/Channel.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/channel/Channel.java @@ -53,7 +53,7 @@ public class Channel { */ public final ConfigData DisplayName() { throwGame(); - return component.getConfig().getData(ID + ".displayName", defDisplayName); + return component.getConfig().getData(ID + ".displayName", defDisplayName); //TODO: Use config map } public final ConfigData Color() { diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java index 25df8af..10e5c49 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java @@ -42,6 +42,7 @@ public abstract class ButtonPlugin extends JavaPlugin { @Override public final void onEnable() { loadConfig(); + IHaveConfig.pregenConfig(this, iConfig); try { pluginEnable(); } catch (Exception e) { diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java index 4d2c9cf..435c71d 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java @@ -85,6 +85,7 @@ public abstract class Component { } component.plugin = plugin; updateConfig(plugin, component); + IHaveConfig.pregenConfig(component, component.config); component.register(plugin); components.put(component.getClass(), component); if (plugin instanceof ButtonPlugin) diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java index 6374db0..c3d8baa 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java @@ -4,6 +4,7 @@ import buttondevteam.core.MainPlugin; import buttondevteam.lib.ThorpeUtils; import lombok.AccessLevel; import lombok.AllArgsConstructor; +import lombok.Getter; import lombok.RequiredArgsConstructor; import org.bukkit.Bukkit; import org.bukkit.configuration.Configuration; @@ -29,6 +30,7 @@ public class ConfigData { * May be null for testing */ private final ConfigurationSection config; + @Getter private final String path; private final T def; private final Object primitiveDef; diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java index 241e4f5..15a5d24 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java @@ -1,10 +1,10 @@ package buttondevteam.lib.architecture; +import buttondevteam.core.MainPlugin; +import buttondevteam.lib.TBMCCoreAPI; import lombok.Getter; import lombok.val; import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.scheduler.BukkitTask; import java.util.HashMap; import java.util.function.Function; @@ -117,4 +117,30 @@ public final class IHaveConfig { } return (ConfigData) data; } + + /** + * Generates the config YAML. + * + * @param obj The object which has config methods + * @param config The config that holds the values + */ + public static void pregenConfig(Object obj, IHaveConfig config) { + val ms = obj.getClass().getDeclaredMethods(); + for (val m : ms) { + if (!m.getReturnType().getName().equals(ConfigData.class.getName())) continue; + try { + if (m.getParameterCount() == 0) { + m.setAccessible(true); + ConfigData c = (ConfigData) m.invoke(obj); + if (!c.getPath().equals(m.getName())) + MainPlugin.Instance.getLogger().warning("Config name does not match: " + c.getPath() + " instead of " + m.getName()); //TODO: Set it here + c.get(); //Saves the default value if needed - also checks validity + } else if (m.getParameterCount() == 1) { + //TODO: Config map + } + } catch (Exception e) { + TBMCCoreAPI.SendException("Failed to pregenerate " + m.getName() + " for " + obj + "!", e); + } + } + } } diff --git a/ButtonProcessor/src/main/java/buttondevteam/buttonproc/ConfigProcessor.java b/ButtonProcessor/src/main/java/buttondevteam/buttonproc/ConfigProcessor.java index f244553..8895fa9 100644 --- a/ButtonProcessor/src/main/java/buttondevteam/buttonproc/ConfigProcessor.java +++ b/ButtonProcessor/src/main/java/buttondevteam/buttonproc/ConfigProcessor.java @@ -4,7 +4,11 @@ import org.bukkit.configuration.file.YamlConfiguration; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; import javax.tools.FileObject; import javax.tools.StandardLocation; import java.io.File; @@ -29,11 +33,29 @@ public class ConfigProcessor { public void process(Element targetcl) { if (targetcl.getModifiers().contains(Modifier.ABSTRACT)) return; + final String path = "components." + targetcl.getSimpleName(); + for (Element e : targetcl.getEnclosedElements()) { + /*System.out.println("Element: "+e); + System.out.println("Type: "+e.getClass()+" - "+e.getKind()); + if(e instanceof ExecutableElement) + System.out.println("METHOD!");*/ + if (!(e instanceof ExecutableElement)) continue; + TypeMirror tm = ((ExecutableElement) e).getReturnType(); + if (tm.getKind() != TypeKind.DECLARED) continue; + DeclaredType dt = (DeclaredType) tm; + if (!dt.asElement().getSimpleName().contentEquals("ConfigData")) return; + System.out.println("Config: " + e.getSimpleName()); + System.out.println("Value: " + ((ExecutableElement) e).getDefaultValue()); + String doc = procEnv.getElementUtils().getDocComment(e); + if (doc == null) continue; + System.out.println("DOC: " + doc); + yaml.set(path + "." + e.getSimpleName() + "_doc", doc); //methodName_doc + } String javadoc = procEnv.getElementUtils().getDocComment(targetcl); if (javadoc == null) return; - System.out.println("JAVADOC"); //TODO: Config methods + System.out.println("JAVADOC"); System.out.println(javadoc); - yaml.set("components." + targetcl.getSimpleName() + "._doc", javadoc); + yaml.set(path + "._doc", javadoc); try { yaml.save(file); } catch (IOException e) { From 87189eb1adce5784d5e16a1f29d0cbbb072dcdf7 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Wed, 10 Apr 2019 13:48:47 +0200 Subject: [PATCH 02/12] Config doc gen fix & markdown instead of yaml --- BuildConfigUpdater/BuildConfigUpdater.iml | 1 + .../buttonproc/ConfigProcessor.java | 45 ++++++++++++------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/BuildConfigUpdater/BuildConfigUpdater.iml b/BuildConfigUpdater/BuildConfigUpdater.iml index 274b3de..f14440c 100644 --- a/BuildConfigUpdater/BuildConfigUpdater.iml +++ b/BuildConfigUpdater/BuildConfigUpdater.iml @@ -12,6 +12,7 @@ + diff --git a/ButtonProcessor/src/main/java/buttondevteam/buttonproc/ConfigProcessor.java b/ButtonProcessor/src/main/java/buttondevteam/buttonproc/ConfigProcessor.java index 8895fa9..c06169a 100644 --- a/ButtonProcessor/src/main/java/buttondevteam/buttonproc/ConfigProcessor.java +++ b/ButtonProcessor/src/main/java/buttondevteam/buttonproc/ConfigProcessor.java @@ -1,7 +1,5 @@ package buttondevteam.buttonproc; -import org.bukkit.configuration.file.YamlConfiguration; - import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; @@ -12,23 +10,24 @@ import javax.lang.model.type.TypeMirror; import javax.tools.FileObject; import javax.tools.StandardLocation; import java.io.File; +import java.io.FileWriter; import java.io.IOException; public class ConfigProcessor { private final ProcessingEnvironment procEnv; - private final YamlConfiguration yaml; - private final File file; + private final FileWriter sw; public ConfigProcessor(ProcessingEnvironment procEnv) { this.procEnv = procEnv; - FileObject file = null; + FileWriter sw = null; try { - file = procEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", "config.yml"); + FileObject file = procEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", "configHelp.md"); + sw = new FileWriter(new File(file.toUri())); + System.out.println(file.toUri()); } catch (IOException e) { e.printStackTrace(); } - yaml = new YamlConfiguration(); - this.file = new File(file.toUri()); + this.sw = sw; } public void process(Element targetcl) { @@ -43,23 +42,37 @@ public class ConfigProcessor { TypeMirror tm = ((ExecutableElement) e).getReturnType(); if (tm.getKind() != TypeKind.DECLARED) continue; DeclaredType dt = (DeclaredType) tm; - if (!dt.asElement().getSimpleName().contentEquals("ConfigData")) return; + if (!dt.asElement().getSimpleName().contentEquals("ConfigData")) + continue; //Ahhha! There was a return here! (MinecraftChatModule getListener()) System.out.println("Config: " + e.getSimpleName()); - System.out.println("Value: " + ((ExecutableElement) e).getDefaultValue()); + String doc = procEnv.getElementUtils().getDocComment(e); if (doc == null) continue; System.out.println("DOC: " + doc); - yaml.set(path + "." + e.getSimpleName() + "_doc", doc); //methodName_doc + try { + sw.append(path).append(".").append(String.valueOf(e.getSimpleName())).append(System.lineSeparator()).append(System.lineSeparator()); + sw.append(doc.trim()).append(System.lineSeparator()).append(System.lineSeparator()); + } catch (IOException e1) { + e1.printStackTrace(); + } } String javadoc = procEnv.getElementUtils().getDocComment(targetcl); - if (javadoc == null) return; - System.out.println("JAVADOC"); - System.out.println(javadoc); - yaml.set(path + "._doc", javadoc); try { - yaml.save(file); + if (javadoc != null) { + System.out.println("JAVADOC"); + System.out.println(javadoc.trim()); + sw.append(path).append(System.lineSeparator()).append(System.lineSeparator()); + sw.append(javadoc).append(System.lineSeparator()).append(System.lineSeparator()); + } + sw.flush(); } catch (IOException e) { e.printStackTrace(); } } + + @Override + protected void finalize() throws Throwable { + sw.close(); + super.finalize(); + } } From aec9682b2a82a46ab69ae4ab28a2b5e50a158329 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 15 Apr 2019 15:37:40 +0200 Subject: [PATCH 03/12] Subcommand perm group --- BuildConfigUpdater/BuildConfigUpdater.iml | 1 - .../ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml | 2 +- .../src/main/java/buttondevteam/lib/chat/Command2.java | 7 +++++++ .../src/main/java/buttondevteam/lib/chat/ICommand2MC.java | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/BuildConfigUpdater/BuildConfigUpdater.iml b/BuildConfigUpdater/BuildConfigUpdater.iml index f14440c..274b3de 100644 --- a/BuildConfigUpdater/BuildConfigUpdater.iml +++ b/BuildConfigUpdater/BuildConfigUpdater.iml @@ -12,7 +12,6 @@ - diff --git a/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml b/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml index 3c34336..77fac1e 100644 --- a/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml +++ b/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml @@ -1,5 +1,5 @@ - + diff --git a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java index bc10fc7..79c8556 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java @@ -46,10 +46,17 @@ public abstract class Command2 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Subcommand { + String MOD_GROUP = "mod"; /** * Help text to show players. A usage message will be also shown below it. */ String[] helpText() default {}; + + /** + * The main permission which allows using this command (individual access can be still granted with "thorpe.command.X"). + * Used to be "tbmc.admin" + */ + String permGroup() default ""; //TODO } @Target(ElementType.PARAMETER) diff --git a/ButtonCore/src/main/java/buttondevteam/lib/chat/ICommand2MC.java b/ButtonCore/src/main/java/buttondevteam/lib/chat/ICommand2MC.java index 4ad997b..566285d 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/chat/ICommand2MC.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/chat/ICommand2MC.java @@ -2,7 +2,7 @@ package buttondevteam.lib.chat; import buttondevteam.lib.architecture.ButtonPlugin; -public class ICommand2MC extends ICommand2 { +public abstract class ICommand2MC extends ICommand2 { public ICommand2MC() { super(ButtonPlugin.getCommand2MC()); } From 4132a330375377ca6fd9661d688a31ee269a503b Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Wed, 17 Apr 2019 13:52:55 +0200 Subject: [PATCH 04/12] Perm changes --- .../src/main/java/buttondevteam/lib/chat/Command2.java | 2 +- .../src/main/java/buttondevteam/lib/chat/Command2MC.java | 6 ++++++ .../src/main/java/buttondevteam/lib/chat/CommandClass.java | 6 ++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java index 79c8556..f080d23 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java @@ -54,7 +54,7 @@ public abstract class Command2 /** * The main permission which allows using this command (individual access can be still granted with "thorpe.command.X"). - * Used to be "tbmc.admin" + * Used to be "tbmc.admin". The {@link #MOD_GROUP} is provided to use with this. */ String permGroup() default ""; //TODO } diff --git a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java index 9761ea5..82933cd 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java @@ -2,6 +2,9 @@ package buttondevteam.lib.chat; import buttondevteam.core.MainPlugin; import lombok.val; +import org.bukkit.Bukkit; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionDefault; import java.util.function.Function; @@ -9,12 +12,15 @@ public class Command2MC extends Command2 { @Override public void registerCommand(ICommand2MC command) { super.registerCommand(command, '/'); + Bukkit.getPluginManager().addPermission(new Permission("thorpe.command." + command.getCommandPath().replace(' ', '.'), + modOnly(command) ? PermissionDefault.OP : PermissionDefault.TRUE)); //Allow commands by default, unless it's mod only - TODO: Test } @Override public boolean hasPermission(Command2MCSender sender, ICommand2MC command) { return modOnly(command) ? MainPlugin.permission.has(sender.getSender(), "tbmc.admin") //TODO: Change when groups are implemented + //: MainPlugin.permission.has(sender.getSender(), permGroup()) - TODO: Check for subcommands (permGroup) : MainPlugin.permission.has(sender.getSender(), "thorpe.command." + command.getCommandPath().replace(' ', '.')); } diff --git a/ButtonCore/src/main/java/buttondevteam/lib/chat/CommandClass.java b/ButtonCore/src/main/java/buttondevteam/lib/chat/CommandClass.java index aa497fd..bc17204 100755 --- a/ButtonCore/src/main/java/buttondevteam/lib/chat/CommandClass.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/chat/CommandClass.java @@ -44,4 +44,10 @@ public @interface CommandClass { * @return The help text */ String[] helpText() default {}; + + /** + * The main permission which allows using this command (individual access can be still granted with "thorpe.command.X"). + * Used to be "tbmc.admin" + */ + String permGroup() default ""; //TODO: A single annotation instead of these two } From 4dade43f82028b50a35554dd65a6082438392395 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 29 Apr 2019 12:53:26 +0200 Subject: [PATCH 05/12] Added support for config map gen #59 Hopefully Also added support for setting the path automatically --- .../lib/architecture/ButtonPlugin.java | 2 +- .../lib/architecture/Component.java | 2 +- .../lib/architecture/ConfigData.java | 23 +++++--- .../lib/architecture/IHaveConfig.java | 52 +++++++++++++------ 4 files changed, 54 insertions(+), 25 deletions(-) diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java index 10e5c49..8d30120 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java @@ -42,7 +42,7 @@ public abstract class ButtonPlugin extends JavaPlugin { @Override public final void onEnable() { loadConfig(); - IHaveConfig.pregenConfig(this, iConfig); + IHaveConfig.pregenConfig(this, null); try { pluginEnable(); } catch (Exception e) { diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java index 435c71d..2385195 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java @@ -85,7 +85,7 @@ public abstract class Component { } component.plugin = plugin; updateConfig(plugin, component); - IHaveConfig.pregenConfig(component, component.config); + IHaveConfig.pregenConfig(component, null); component.register(plugin); components.put(component.getClass(), component); if (plugin instanceof ButtonPlugin) diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java index f4d2285..bc758ef 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java @@ -5,7 +5,7 @@ import buttondevteam.lib.ThorpeUtils; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.RequiredArgsConstructor; +import lombok.Setter; import org.bukkit.Bukkit; import org.bukkit.configuration.Configuration; import org.bukkit.configuration.ConfigurationSection; @@ -20,9 +20,8 @@ import java.util.function.Function; /** * Use the getter/setter constructor if {@link T} isn't a primitive type or String.
- * Use {@link Component#getConfig()} or {@link ButtonPlugin#getIConfig()} then {@link IHaveConfig#getData(String, Object)} to get an instance. + * Use {@link Component#getConfig()} or {@link ButtonPlugin#getIConfig()} then {@link IHaveConfig#getData(String, Object)} to get an instance. */ -@RequiredArgsConstructor(access = AccessLevel.PACKAGE) //@AllArgsConstructor(access = AccessLevel.PACKAGE) public class ConfigData { private static final HashMap saveTasks = new HashMap<>(); @@ -31,7 +30,8 @@ public class ConfigData { */ private final ConfigurationSection config; @Getter - private final String path; + @Setter(AccessLevel.PACKAGE) + private String path; private final T def; private final Object primitiveDef; private final Runnable saveAction; @@ -54,14 +54,23 @@ public class ConfigData { private boolean saved = false; //This constructor is needed because it sets the getter and setter - public ConfigData(ConfigurationSection config, String path, T def, Object primitiveDef, Function getter, Function setter, Runnable saveAction) { + ConfigData(ConfigurationSection config, String path, T def, Object primitiveDef, Function getter, Function setter, Runnable saveAction) { this.config = config; this.path = path; this.def = def; this.primitiveDef = primitiveDef; this.getter = getter; this.setter = setter; - this.saveAction=saveAction; + this.saveAction = saveAction; + } + + @java.beans.ConstructorProperties({"config", "path", "def", "primitiveDef", "saveAction"}) + ConfigData(ConfigurationSection config, String path, T def, Object primitiveDef, Runnable saveAction) { + this.config = config; + this.path = path; + this.def = def; + this.primitiveDef = primitiveDef; + this.saveAction = saveAction; } @Override @@ -106,7 +115,7 @@ public class ConfigData { else val = value; if (config != null) { config.set(path, val); - if(!saveTasks.containsKey(config.getRoot())) { + if (!saveTasks.containsKey(config.getRoot())) { synchronized (saveTasks) { saveTasks.put(config.getRoot(), new SaveTask(Bukkit.getScheduler().runTaskLaterAsynchronously(MainPlugin.Instance, () -> { synchronized (saveTasks) { diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java index 15a5d24..2b7ce8f 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java @@ -6,9 +6,12 @@ import lombok.Getter; import lombok.val; import org.bukkit.configuration.ConfigurationSection; -import java.util.HashMap; +import javax.annotation.Nullable; +import java.lang.reflect.InvocationTargetException; +import java.util.*; import java.util.function.Function; import java.util.function.Supplier; +import java.util.stream.Collectors; /** * A config system @@ -26,7 +29,7 @@ public final class IHaveConfig { */ IHaveConfig(ConfigurationSection section, Runnable saveAction) { config = section; - this.saveAction=saveAction; + this.saveAction = saveAction; } /** @@ -65,11 +68,11 @@ public final class IHaveConfig { /** * This method overload may be used with any class. The given default value will be run through the getter. * - * @param path The path in config to use - * @param primitiveDef The primitive 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) + * @param path The path in config to use + * @param primitiveDef The primitive 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") @@ -121,22 +124,39 @@ public final class IHaveConfig { /** * Generates the config YAML. * - * @param obj The object which has config methods - * @param config The config that holds the values + * @param obj The object which has config methods + * @param configMap The result from {@link Component#getConfigMap(String, Map)}. May be null. */ - public static void pregenConfig(Object obj, IHaveConfig config) { + public static void pregenConfig(Object obj, @Nullable Map configMap) { val ms = obj.getClass().getDeclaredMethods(); for (val m : ms) { if (!m.getReturnType().getName().equals(ConfigData.class.getName())) continue; try { + m.setAccessible(true); + List> configList; if (m.getParameterCount() == 0) { - m.setAccessible(true); - ConfigData c = (ConfigData) m.invoke(obj); - if (!c.getPath().equals(m.getName())) - MainPlugin.Instance.getLogger().warning("Config name does not match: " + c.getPath() + " instead of " + m.getName()); //TODO: Set it here + configList = Collections.singletonList((ConfigData) m.invoke(obj)); + } else if (m.getParameterCount() == 1 && m.getParameterTypes()[0] == IHaveConfig.class) { + if (configMap == null) continue; //Hope it will get called with the param later + configList = configMap.entrySet().stream().map(kv -> + { + try { + return (ConfigData) m.invoke(obj, kv.getValue()); + } catch (IllegalAccessException | InvocationTargetException e) { + TBMCCoreAPI.SendException("Failed to pregenerate " + m.getName() + " for " + obj + " using config " + kv.getKey() + "!", e); + return null; + } + }).filter(Objects::nonNull).collect(Collectors.toList()); + } else { + MainPlugin.Instance.getLogger().warning("Method " + m.getName() + " returns a config but its parameters are unknown: " + Arrays.toString(m.getParameterTypes())); + continue; + } + for (val c : configList) { + if (c.getPath().length() == 0) + c.setPath(m.getName()); + else if (!c.getPath().equals(m.getName())) + MainPlugin.Instance.getLogger().warning("Config name does not match: " + c.getPath() + " instead of " + m.getName()); c.get(); //Saves the default value if needed - also checks validity - } else if (m.getParameterCount() == 1) { - //TODO: Config map } } catch (Exception e) { TBMCCoreAPI.SendException("Failed to pregenerate " + m.getName() + " for " + obj + "!", e); From 0d4f3b09dd1b7a1978df00512aa5fda6ece16560 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Wed, 1 May 2019 00:41:31 +0200 Subject: [PATCH 06/12] Pregen config & cmd perm fixes Added perm group check Needs testing --- .../lib/architecture/ButtonPlugin.java | 19 ++++++- .../lib/architecture/Component.java | 18 ++++--- .../java/buttondevteam/lib/chat/Command2.java | 4 +- .../buttondevteam/lib/chat/Command2MC.java | 52 +++++++++++++++---- 4 files changed, 73 insertions(+), 20 deletions(-) diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java index 8d30120..c4e7ce1 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java @@ -9,6 +9,11 @@ import lombok.Getter; import lombok.experimental.var; import org.bukkit.plugin.java.JavaPlugin; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.Optional; import java.util.Stack; @HasConfig @@ -42,12 +47,13 @@ public abstract class ButtonPlugin extends JavaPlugin { @Override public final void onEnable() { loadConfig(); - IHaveConfig.pregenConfig(this, null); try { pluginEnable(); } catch (Exception e) { TBMCCoreAPI.SendException("Error while enabling plugin " + getName() + "!", e); } + if (configGenAllowed(this)) //If it's not disabled (by default it's not) + IHaveConfig.pregenConfig(this, null); } private void loadConfig() { @@ -91,4 +97,15 @@ public abstract class ButtonPlugin extends JavaPlugin { loaded = true; //Needed because for the first time it uses reloadConfig() to load it return true; } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE) + public @interface ConfigOpts { + boolean disableConfigGen() default false; + } + + public static boolean configGenAllowed(Object obj) { + return !Optional.ofNullable(obj.getClass().getAnnotation(ConfigOpts.class)) + .map(ConfigOpts::disableConfigGen).orElse(false); + } } diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java index 2385195..b98466b 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java @@ -45,7 +45,7 @@ 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. + * 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) @@ -57,7 +57,7 @@ public abstract class Component { /** * Unregisters a component by calling {@link #unregister(JavaPlugin)}.
* 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)}. + * Components will be unregistered in opposite order of registering by default by {@link ButtonPlugin} or {@link ComponentManager#unregComponents(ButtonPlugin)}. * * @param component The component to unregister * @return Whether the component is unregistered successfully (it also got disabled) @@ -85,7 +85,6 @@ public abstract class Component { } component.plugin = plugin; updateConfig(plugin, component); - IHaveConfig.pregenConfig(component, null); component.register(plugin); components.put(component.getClass(), component); if (plugin instanceof ButtonPlugin) @@ -134,6 +133,8 @@ public abstract class Component { if (component.enabled = enabled) { updateConfig(component.getPlugin(), component); component.enable(); + if (ButtonPlugin.configGenAllowed(component)) + IHaveConfig.pregenConfig(component, null); } else { component.disable(); component.plugin.saveConfig(); @@ -193,7 +194,7 @@ public abstract class Component { /** * Disables the module, when called by the JavaPlugin class. Do * any cleanups needed within this method. - * To access the plugin, use {@link #getPlugin()}. + * To access the plugin, use {@link #getPlugin()}. */ protected abstract void disable(); @@ -229,14 +230,15 @@ public abstract class Component { /** * Returns a map of configs that are under the given key. - * @param key The key to use + * + * @param key The key to use * @param defaultProvider A mapping between config paths and config generators * @return A map containing configs */ protected Map getConfigMap(String key, Map> defaultProvider) { - val c=getConfig().getConfig(); - var cs=c.getConfigurationSection(key); - if(cs==null) cs=c.createSection(key); + val c = getConfig().getConfig(); + var cs = c.getConfigurationSection(key); + if (cs == null) cs = c.createSection(key); val res = cs.getValues(false).entrySet().stream().filter(e -> e.getValue() instanceof ConfigurationSection) .collect(Collectors.toMap(Map.Entry::getKey, kv -> new IHaveConfig((ConfigurationSection) kv.getValue(), getPlugin()::saveConfig))); if (res.size() == 0) { diff --git a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java index 9d2212c..8f41b3c 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java @@ -105,7 +105,7 @@ public abstract class Command2 sender.sendMessage(sd.helpText); return true; } - if (!hasPermission(sender, sd.command)) { + if (!hasPermission(sender, sd.command, sd.method)) { sender.sendMessage("§cYou don't have permission to use this command"); return true; } @@ -283,7 +283,7 @@ public abstract class Command2 return ht; } - public abstract boolean hasPermission(TP sender, TC command); + public abstract boolean hasPermission(TP sender, TC command, Method subcommand); public String[] getCommandsText() { return commandHelp.toArray(new String[0]); diff --git a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java index 82933cd..9dfb3b7 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java @@ -6,21 +6,27 @@ import org.bukkit.Bukkit; import org.bukkit.permissions.Permission; import org.bukkit.permissions.PermissionDefault; +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; import java.util.function.Function; public class Command2MC extends Command2 { @Override public void registerCommand(ICommand2MC command) { super.registerCommand(command, '/'); - Bukkit.getPluginManager().addPermission(new Permission("thorpe.command." + command.getCommandPath().replace(' ', '.'), - modOnly(command) ? PermissionDefault.OP : PermissionDefault.TRUE)); //Allow commands by default, unless it's mod only - TODO: Test + val perm = "thorpe.command." + command.getCommandPath().replace(' ', '.'); + if (Bukkit.getPluginManager().getPermission(perm) == null) //Check needed for plugin reset + Bukkit.getPluginManager().addPermission(new Permission(perm, + modOnly(command) ? PermissionDefault.OP : PermissionDefault.TRUE)); //Allow commands by default, unless it's mod only - TODO: Test } @Override - public boolean hasPermission(Command2MCSender sender, ICommand2MC command) { + public boolean hasPermission(Command2MCSender sender, ICommand2MC command, Method method) { + String pg; return modOnly(command) - ? MainPlugin.permission.has(sender.getSender(), "tbmc.admin") //TODO: Change when groups are implemented - //: MainPlugin.permission.has(sender.getSender(), permGroup()) - TODO: Check for subcommands (permGroup) + ? MainPlugin.permission.has(sender.getSender(), "tbmc.admin") + : (pg = permGroup(command, method)) != null + ? MainPlugin.permission.has(sender.getSender(), pg) : MainPlugin.permission.has(sender.getSender(), "thorpe.command." + command.getCommandPath().replace(' ', '.')); } @@ -31,11 +37,39 @@ public class Command2MC extends Command2 { * @return Whether the command is mod only */ private boolean modOnly(ICommand2MC command) { - for (Class cl = command.getClass(); cl != null; cl = cl.getSuperclass()) { - val cc = command.getClass().getAnnotation(CommandClass.class); - if (cc != null && cc.modOnly()) return true; + return getAnnForValue(command.getClass(), CommandClass.class, CommandClass::modOnly, false); + } + + /** + * Returns true if this class or any of the superclasses are mod only. + * + * @param method The subcommand to check + * @return The permission group for the subcommand or null + */ + private String permGroup(ICommand2MC command, Method method) { + val sc = method.getAnnotation(Subcommand.class); + if (sc != null && sc.permGroup().length() > 0) return sc.permGroup(); + return getAnnForValue(command.getClass(), CommandClass.class, CommandClass::permGroup, null); + } + + /** + * Loops until it finds a value that is not the same as def + * + * @param sourceCl The class which has the annotation + * @param annCl The annotation to get + * @param annMethod The annotation method to check + * @param def The value to ignore when looking for the result + * @param The annotation type + * @param The type of the value + * @return The value returned by the first superclass or def + */ + private V getAnnForValue(Class sourceCl, Class annCl, Function annMethod, V def) { + for (Class cl = sourceCl; cl != null; cl = cl.getSuperclass()) { + val cc = cl.getAnnotation(annCl); + V r; + if (cc != null && (r = annMethod.apply(cc)) != def) return r; } - return false; + return def; } /** From 497c761cc0efefc8232a358459b818ce257c14be Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 4 May 2019 03:06:22 +0200 Subject: [PATCH 07/12] Imprv. perm. handling, read only conf data Improved permission handling (can't say fixed because it doesn't work, unless I forgot to test the last version) Added ReadOnlyConfigData --- .../lib/architecture/ConfigData.java | 2 + .../lib/architecture/IHaveConfig.java | 18 +++++++++ .../lib/architecture/ReadOnlyConfigData.java | 15 +++++++ .../java/buttondevteam/lib/chat/Command2.java | 3 ++ .../buttondevteam/lib/chat/Command2MC.java | 39 +++++++++++++++---- 5 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 ButtonCore/src/main/java/buttondevteam/lib/architecture/ReadOnlyConfigData.java diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java index bc758ef..b14f7c6 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java @@ -109,6 +109,8 @@ public class ConfigData { } public void set(T value) { + if (this instanceof ReadOnlyConfigData) + return; //Safety for Discord channel/role data Object val; if (setter != null && value != null) val = setter.apply(value); diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java index 2b7ce8f..b3d6fbd 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java @@ -83,6 +83,24 @@ public final class IHaveConfig { return (ConfigData) data; } + /** + * This method overload may be used with any class. The given default value will be run through the getter. + * + * @param path The path in config to use + * @param primitiveDef The primitive 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 ReadOnlyConfigData getReadOnlyDataPrimDef(String path, Object primitiveDef, Function getter, Function setter) { + ConfigData data = datamap.get(path); + if (data == null) + datamap.put(path, data = new ReadOnlyConfigData<>(config, path, getter.apply(primitiveDef), primitiveDef, getter, setter, saveAction)); + return (ReadOnlyConfigData) data; + } + /** * This method overload should only be used with primitves or String. * diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ReadOnlyConfigData.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ReadOnlyConfigData.java new file mode 100644 index 0000000..5594c21 --- /dev/null +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ReadOnlyConfigData.java @@ -0,0 +1,15 @@ +package buttondevteam.lib.architecture; + +import org.bukkit.configuration.ConfigurationSection; + +import java.util.function.Function; + +public class ReadOnlyConfigData extends ConfigData { + ReadOnlyConfigData(ConfigurationSection config, String path, T def, Object primitiveDef, Function getter, Function setter, Runnable saveAction) { + super(config, path, def, primitiveDef, getter, setter, saveAction); + } + + ReadOnlyConfigData(ConfigurationSection config, String path, T def, Object primitiveDef, Runnable saveAction) { + super(config, path, def, primitiveDef, saveAction); + } +} diff --git a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java index 8f41b3c..d383e28 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2.java @@ -48,6 +48,9 @@ public abstract class Command2 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Subcommand { + /** + * Allowed for OPs only by default + */ String MOD_GROUP = "mod"; /** * Help text to show players. A usage message will be also shown below it. diff --git a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java index 9dfb3b7..5976b3d 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java @@ -1,6 +1,7 @@ package buttondevteam.lib.chat; import buttondevteam.core.MainPlugin; +import lombok.experimental.var; import lombok.val; import org.bukkit.Bukkit; import org.bukkit.permissions.Permission; @@ -14,20 +15,39 @@ public class Command2MC extends Command2 { @Override public void registerCommand(ICommand2MC command) { super.registerCommand(command, '/'); - val perm = "thorpe.command." + command.getCommandPath().replace(' ', '.'); + var perm = "thorpe.command." + command.getCommandPath().replace(' ', '.'); + if (Bukkit.getPluginManager().getPermission(perm) == null) //Check needed for plugin reset + System.out.println("Adding perm " + perm + " with default: " + + (modOnly(command) ? PermissionDefault.OP : PermissionDefault.TRUE)); //Allow commands by default, unless it's mod only - TODO: Test if (Bukkit.getPluginManager().getPermission(perm) == null) //Check needed for plugin reset Bukkit.getPluginManager().addPermission(new Permission(perm, modOnly(command) ? PermissionDefault.OP : PermissionDefault.TRUE)); //Allow commands by default, unless it's mod only - TODO: Test + for (val method : command.getClass().getMethods()) { + if (!method.isAnnotationPresent(Subcommand.class)) continue; + String pg = permGroup(command, method); + if (pg == null) continue; + perm = "thorpe." + pg; + if (Bukkit.getPluginManager().getPermission(perm) == null) //It may occur multiple times + System.out.println("Adding perm " + perm + " with default: " + + PermissionDefault.OP); //Do not allow any commands that belong to a group + if (Bukkit.getPluginManager().getPermission(perm) == null) //It may occur multiple times + Bukkit.getPluginManager().addPermission(new Permission(perm, + //pg.equals(Subcommand.MOD_GROUP) ? PermissionDefault.OP : PermissionDefault.TRUE)); //Allow commands by default, unless it's mod only + PermissionDefault.OP)); //Do not allow any commands that belong to a group + } } @Override public boolean hasPermission(Command2MCSender sender, ICommand2MC command, Method method) { String pg; - return modOnly(command) - ? MainPlugin.permission.has(sender.getSender(), "tbmc.admin") - : (pg = permGroup(command, method)) != null - ? MainPlugin.permission.has(sender.getSender(), pg) - : MainPlugin.permission.has(sender.getSender(), "thorpe.command." + command.getCommandPath().replace(' ', '.')); + String perm = modOnly(command) + ? "tbmc.admin" + : (pg = permGroup(command, method)) != null //TODO: This way we can't grant specific perms if it has a perm group + ? "thorpe." + pg + : "thorpe.command." + command.getCommandPath().replace(' ', '.'); + //noinspection deprecation + System.out.println("Has permission " + perm + ": " + MainPlugin.permission.playerHas((String) null, sender.getSender().getName(), perm)); + return MainPlugin.permission.playerHas((String) null, sender.getSender().getName(), perm); } /** @@ -47,8 +67,13 @@ public class Command2MC extends Command2 { * @return The permission group for the subcommand or null */ private String permGroup(ICommand2MC command, Method method) { + //System.out.println("Perm group for command " + command.getClass().getSimpleName() + " and method " + method.getName()); val sc = method.getAnnotation(Subcommand.class); - if (sc != null && sc.permGroup().length() > 0) return sc.permGroup(); + if (sc != null && sc.permGroup().length() > 0) { + //System.out.println("Returning sc.permGroup(): " + sc.permGroup()); + return sc.permGroup(); + } + //System.out.println("Returning getAnnForValue(" + command.getClass().getSimpleName() + ", ...): " + getAnnForValue(command.getClass(), CommandClass.class, CommandClass::permGroup, null)); return getAnnForValue(command.getClass(), CommandClass.class, CommandClass::permGroup, null); } From a75397f2b0c95f05208c2296a0806f2aadf0ac37 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 20 May 2019 23:36:59 +0200 Subject: [PATCH 08/12] Unconnected perm group & fixes --- ...1) (com.github.TBMCPlugins.ButtonCore).iml | 38 ------------------- .../java/buttondevteam/core/MainPlugin.java | 7 ++++ .../lib/architecture/Component.java | 2 + .../buttondevteam/lib/chat/Command2MC.java | 36 ++++++++++++------ 4 files changed, 34 insertions(+), 49 deletions(-) delete mode 100644 ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml diff --git a/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml b/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml deleted file mode 100644 index c89b771..0000000 --- a/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/ButtonCore/src/main/java/buttondevteam/core/MainPlugin.java b/ButtonCore/src/main/java/buttondevteam/core/MainPlugin.java index e810c67..9f67ecb 100755 --- a/ButtonCore/src/main/java/buttondevteam/core/MainPlugin.java +++ b/ButtonCore/src/main/java/buttondevteam/core/MainPlugin.java @@ -69,6 +69,13 @@ public class MainPlugin extends ButtonPlugin { "{channel}] <{name}> {message}"); } + /** + * The permission group for users that aren't online on the server. Currently this can happen for people using commands from Discord. + */ + public ConfigData unconnPermGroup() { + return getIConfig().getData("unconnPermGroup", "unconnected"); + } + @Override public void pluginEnable() { // Logs "Plugin Enabled", registers commands diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java index b98466b..8632c1c 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java @@ -132,10 +132,12 @@ public abstract class Component { if (component.enabled == enabled) return; //Don't do anything if (component.enabled = enabled) { updateConfig(component.getPlugin(), component); + System.out.println("Enabling component " + component.getClassName()); component.enable(); if (ButtonPlugin.configGenAllowed(component)) IHaveConfig.pregenConfig(component, null); } else { + System.out.println("Disabling component " + component.getClassName()); component.disable(); component.plugin.saveConfig(); TBMCChatAPI.RemoveCommands(component); diff --git a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java index 5976b3d..e62f9e5 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java @@ -4,6 +4,9 @@ import buttondevteam.core.MainPlugin; import lombok.experimental.var; import lombok.val; import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; import org.bukkit.permissions.Permission; import org.bukkit.permissions.PermissionDefault; @@ -25,7 +28,7 @@ public class Command2MC extends Command2 { for (val method : command.getClass().getMethods()) { if (!method.isAnnotationPresent(Subcommand.class)) continue; String pg = permGroup(command, method); - if (pg == null) continue; + if (pg.length() == 0) continue; perm = "thorpe." + pg; if (Bukkit.getPluginManager().getPermission(perm) == null) //It may occur multiple times System.out.println("Adding perm " + perm + " with default: " @@ -39,15 +42,26 @@ public class Command2MC extends Command2 { @Override public boolean hasPermission(Command2MCSender sender, ICommand2MC command, Method method) { + if (sender.getSender() instanceof ConsoleCommandSender) return true; //Always allow the console String pg; - String perm = modOnly(command) - ? "tbmc.admin" - : (pg = permGroup(command, method)) != null //TODO: This way we can't grant specific perms if it has a perm group - ? "thorpe." + pg - : "thorpe.command." + command.getCommandPath().replace(' ', '.'); - //noinspection deprecation - System.out.println("Has permission " + perm + ": " + MainPlugin.permission.playerHas((String) null, sender.getSender().getName(), perm)); - return MainPlugin.permission.playerHas((String) null, sender.getSender().getName(), perm); + boolean p = true; + String[] perms = { + "thorpe.command." + command.getCommandPath().replace(' ', '.'), + (pg = permGroup(command, method)).length() > 0 ? "thorpe." + pg : null, + modOnly(command) ? "tbmc.admin" : null + }; + for (String perm : perms) { + if (perm != null) { + if (p) { //Use OfflinePlayer to avoid fetching player data + if (sender.getSender() instanceof Player) + p = MainPlugin.permission.playerHas(null, (OfflinePlayer) sender.getSender(), perm); + else + p = MainPlugin.permission.groupHas((String) null, MainPlugin.Instance.unconnPermGroup().get(), perm); + System.out.println("Has permission " + perm + ": " + p); + } else break; //If any of the permissions aren't granted then don't allow + } + } + return p; } /** @@ -64,7 +78,7 @@ public class Command2MC extends Command2 { * Returns true if this class or any of the superclasses are mod only. * * @param method The subcommand to check - * @return The permission group for the subcommand or null + * @return The permission group for the subcommand or empty string */ private String permGroup(ICommand2MC command, Method method) { //System.out.println("Perm group for command " + command.getClass().getSimpleName() + " and method " + method.getName()); @@ -74,7 +88,7 @@ public class Command2MC extends Command2 { return sc.permGroup(); } //System.out.println("Returning getAnnForValue(" + command.getClass().getSimpleName() + ", ...): " + getAnnForValue(command.getClass(), CommandClass.class, CommandClass::permGroup, null)); - return getAnnForValue(command.getClass(), CommandClass.class, CommandClass::permGroup, null); + return getAnnForValue(command.getClass(), CommandClass.class, CommandClass::permGroup, ""); } /** From 5872117d28db7e5c7e4b1104f22d73ce03db37f5 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Fri, 31 May 2019 01:52:41 +0200 Subject: [PATCH 09/12] Y E E H A W Added error message if needed for member assigning Fixed #65, #63 /yeehaw --- BuildConfigUpdater/BuildConfigUpdater.iml | 3 +++ .../core/component/members/MemberComponent.java | 9 ++++++--- .../src/main/java/buttondevteam/lib/chat/Command2MC.java | 5 +++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/BuildConfigUpdater/BuildConfigUpdater.iml b/BuildConfigUpdater/BuildConfigUpdater.iml index f14440c..1d62bbd 100644 --- a/BuildConfigUpdater/BuildConfigUpdater.iml +++ b/BuildConfigUpdater/BuildConfigUpdater.iml @@ -13,6 +13,9 @@ + + + diff --git a/ButtonCore/src/main/java/buttondevteam/core/component/members/MemberComponent.java b/ButtonCore/src/main/java/buttondevteam/core/component/members/MemberComponent.java index b5bab6e..66ce1ed 100644 --- a/ButtonCore/src/main/java/buttondevteam/core/component/members/MemberComponent.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/members/MemberComponent.java @@ -54,9 +54,12 @@ public class MemberComponent extends Component implements Listener { if (permission != null && !permission.playerInGroup(event.getPlayer(), memberGroup().get()) && (new Date(event.getPlayer().getFirstPlayed()).toInstant().plus(registeredForDays().get(), ChronoUnit.DAYS).isBefore(Instant.now()) || event.getPlayer().getStatistic(Statistic.PLAY_ONE_TICK) > 20 * 3600 * playedHours().get())) { - 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."); + 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."); + } } } } diff --git a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java index e62f9e5..baff097 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/chat/Command2MC.java @@ -12,6 +12,7 @@ import org.bukkit.permissions.PermissionDefault; import java.lang.annotation.Annotation; import java.lang.reflect.Method; +import java.util.UUID; import java.util.function.Function; public class Command2MC extends Command2 { @@ -56,8 +57,8 @@ public class Command2MC extends Command2 { if (sender.getSender() instanceof Player) p = MainPlugin.permission.playerHas(null, (OfflinePlayer) sender.getSender(), perm); else - p = MainPlugin.permission.groupHas((String) null, MainPlugin.Instance.unconnPermGroup().get(), perm); - System.out.println("Has permission " + perm + ": " + p); + //p = MainPlugin.permission.groupHas((String) null, MainPlugin.Instance.unconnPermGroup().get(), perm); + p = MainPlugin.permission.playerHas(null, Bukkit.getOfflinePlayer(new UUID(0, 0)), perm); } else break; //If any of the permissions aren't granted then don't allow } } From cc3ed7cf52a03a3f151d4bedaceec267230b19ce Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 1 Jun 2019 02:25:33 +0200 Subject: [PATCH 10/12] Test config option upd. And indentation fixes apparently --- .idea/misc.xml | 5 ++ BuildConfigUpdater/BuildConfigUpdater.iml | 1 + .../java/buttondevteam/core/MainPlugin.java | 73 +++++++++---------- .../java/buttondevteam/lib/TBMCCoreAPI.java | 65 ++++++++--------- 4 files changed, 69 insertions(+), 75 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index dd45459..6db2058 100755 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,10 @@ + + + + +