diff --git a/src/main/java/org/mineacademy/fo/craft/CraftingHandler.java b/src/main/java/org/mineacademy/fo/craft/CraftingHandler.java index 6a693ce8b..c1c29615f 100644 --- a/src/main/java/org/mineacademy/fo/craft/CraftingHandler.java +++ b/src/main/java/org/mineacademy/fo/craft/CraftingHandler.java @@ -19,6 +19,11 @@ import static org.mineacademy.fo.MinecraftVersion.atLeast; +/** + * The manager of custom crafting recipes. + * + * @author Rubix327 + */ public final class CraftingHandler { /** diff --git a/src/main/java/org/mineacademy/fo/model/SimpleEnchantment.java b/src/main/java/org/mineacademy/fo/model/SimpleEnchantment.java index 48587cf4e..053210852 100644 --- a/src/main/java/org/mineacademy/fo/model/SimpleEnchantment.java +++ b/src/main/java/org/mineacademy/fo/model/SimpleEnchantment.java @@ -1,15 +1,8 @@ package org.mineacademy.fo.model; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.regex.Pattern; - +import lombok.NonNull; import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.enchantments.Enchantment; @@ -22,17 +15,13 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -import org.mineacademy.fo.ChatUtil; -import org.mineacademy.fo.Common; -import org.mineacademy.fo.MathUtil; -import org.mineacademy.fo.MinecraftVersion; +import org.mineacademy.fo.*; import org.mineacademy.fo.MinecraftVersion.V; -import org.mineacademy.fo.Valid; -import org.mineacademy.fo.plugin.SimplePlugin; import org.mineacademy.fo.remain.Remain; -import lombok.NonNull; -import net.md_5.bungee.api.ChatColor; +import java.util.*; +import java.util.Map.Entry; +import java.util.regex.Pattern; /** * Represents a simple way of getting your own enchantments into Minecraft @@ -81,12 +70,11 @@ private static NamespacedKey toKey(@NonNull String name) { if (!MinecraftVersion.atLeast(V.v1_13)) throw new RuntimeException("SimpleEnchantment requires Minecraft 1.13.2 or greater. Cannot make " + name); - name = new String(name); name = name.toLowerCase().replace(" ", "_"); name = ChatUtil.replaceDiacritic(name); Valid.checkBoolean(name != null && VALID_NAMESPACE.matcher(name).matches(), "Enchant name must only contain English alphabet names: " + name); - return new NamespacedKey(SimplePlugin.getInstance(), name); + return NamespacedKey.minecraft(name); } // ------------------------------------------------------------------------------------------ @@ -178,7 +166,7 @@ public ItemStack applyTo(ItemStack item, int level) { * @return */ public String getLore(int level) { - return this.name + " " + MathUtil.toRoman(level); + return "&r&7" + this.name + " " + MathUtil.toRoman(level); } /** @@ -360,7 +348,7 @@ public static ItemStack addEnchantmentLores(ItemStack item) { final String lore = ((SimpleEnchantment) e.getKey()).getLore(e.getValue()); if (lore != null && !lore.isEmpty()) - customEnchants.add(Common.colorize("&r&7" + lore)); + customEnchants.add(Common.colorize(lore)); } } catch (final NullPointerException ex) { diff --git a/src/main/java/org/mineacademy/fo/plugin/AutoRegisterScanner.java b/src/main/java/org/mineacademy/fo/plugin/AutoRegisterScanner.java index 247cf4fea..263844742 100644 --- a/src/main/java/org/mineacademy/fo/plugin/AutoRegisterScanner.java +++ b/src/main/java/org/mineacademy/fo/plugin/AutoRegisterScanner.java @@ -24,7 +24,10 @@ import org.mineacademy.fo.settings.YamlStaticConfig; import java.io.IOException; -import java.lang.reflect.*; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.*; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -89,13 +92,21 @@ public static void scanAndRegister() { // Auto register classes final AutoRegister autoRegister = clazz.getAnnotation(AutoRegister.class); + // Classes that should be auto registered without the annotation + boolean noAnnotationRequired = false; + List> registeredWithNoAnnotation = Arrays.asList( + Tool.class, SimpleEnchantment.class, + BungeeListener.class, SimpleExpansion.class, + PacketListener.class, DiscordListener.class + ); + for (Class cl : registeredWithNoAnnotation){ + if (cl.isAssignableFrom(clazz)){ + noAnnotationRequired = true; + } + } + // Require our annotation to be used, or support legacy classes from Foundation 5 - if (autoRegister != null || Tool.class.isAssignableFrom(clazz) - || SimpleEnchantment.class.isAssignableFrom(clazz) - || BungeeListener.class.isAssignableFrom(clazz) - || SimpleExpansion.class.isAssignableFrom(clazz) - || PacketListener.class.isAssignableFrom(clazz) - || DiscordListener.class.isAssignableFrom(clazz)) { + if (autoRegister != null || noAnnotationRequired) { if (!Modifier.isFinal(clazz.getModifiers())){ Logger.error(new FoException("Non final class is attempted to be auto-registered!"), @@ -278,22 +289,22 @@ private static void autoRegister(Class clazz, boolean printWarnings) { } final SimplePlugin plugin = SimplePlugin.getInstance(); - final Tuple tuple = findInstance(clazz); + final Tuple tuple = findInstance(clazz); - final FindInstance mode = tuple.getKey(); + final InstanceType mode = tuple.getKey(); final Object instance = tuple.getValue(); boolean eventsRegistered = false; if (SimpleListener.class.isAssignableFrom(clazz)) { - enforceModeFor(clazz, mode, FindInstance.SINGLETON); + enforceModeFor(clazz, mode, InstanceType.SINGLETON); plugin.registerEvents((SimpleListener) instance); eventsRegistered = true; } else if (BungeeListener.class.isAssignableFrom(clazz)) { - enforceModeFor(clazz, mode, FindInstance.SINGLETON); + enforceModeFor(clazz, mode, InstanceType.SINGLETON); if (!bungeeListenerRegistered) { bungeeListenerRegistered = true; @@ -317,7 +328,7 @@ else if (SimpleCommandGroup.class.isAssignableFrom(clazz)) { } else if (SimpleExpansion.class.isAssignableFrom(clazz)) { - enforceModeFor(clazz, mode, FindInstance.SINGLETON); + enforceModeFor(clazz, mode, InstanceType.SINGLETON); Variables.addExpansion((SimpleExpansion) instance); } @@ -325,7 +336,7 @@ else if (SimpleExpansion.class.isAssignableFrom(clazz)) { else if (YamlConfig.class.isAssignableFrom(clazz)) { // Automatically called onLoadFinish when getting instance - enforceModeFor(clazz, mode, FindInstance.SINGLETON); + enforceModeFor(clazz, mode, InstanceType.SINGLETON); if (SimplePlugin.isReloading()) { ((YamlConfig) instance).save(); @@ -336,19 +347,19 @@ else if (YamlConfig.class.isAssignableFrom(clazz)) { else if (PacketListener.class.isAssignableFrom(clazz)) { // Automatically registered by means of adding packet adapters - enforceModeFor(clazz, mode, FindInstance.SINGLETON); + enforceModeFor(clazz, mode, InstanceType.SINGLETON); ((PacketListener) instance).onRegister(); } else if (DiscordListener.class.isAssignableFrom(clazz)) // Automatically registered in its constructor - enforceModeFor(clazz, mode, FindInstance.SINGLETON); + enforceModeFor(clazz, mode, InstanceType.SINGLETON); else if (SimpleEnchantment.class.isAssignableFrom(clazz)) { // Automatically registered in its constructor - enforceModeFor(clazz, mode, FindInstance.SINGLETON); + enforceModeFor(clazz, mode, InstanceType.SINGLETON); if (!enchantListenersRegistered) { enchantListenersRegistered = true; @@ -360,41 +371,31 @@ else if (SimpleEnchantment.class.isAssignableFrom(clazz)) { } else if (SimpleCraft.class.isAssignableFrom(clazz)){ - enforceModeFor(clazz, mode, FindInstance.SINGLETON); - try { - Field field = clazz.getDeclaredField("instance"); - field.setAccessible(true); - CraftingHandler.register(((SimpleCraft) field.get(null))); - } catch (IllegalAccessException | NoSuchFieldException e) { - throw new FoException("SimpleCraft class " + clazz.getName() + " must have 'private static final " + - clazz.getName() + " instance' field to be registered."); - } + enforceModeFor(clazz, mode, InstanceType.SINGLETON); + CraftingHandler.register((SimpleCraft) instance); } else if (SimpleBossSkill.class.isAssignableFrom(clazz)){ - enforceModeFor(clazz, mode, FindInstance.NEW_FROM_CONSTRUCTOR); - try{ - SimpleBossSkill skill = (SimpleBossSkill) clazz.getConstructor().newInstance(); - clazz.getMethod("register").invoke(skill); - } catch (InvocationTargetException | InstantiationException | IllegalAccessException | - NoSuchMethodException e) { - throw new RuntimeException(e); - } + enforceModeFor(clazz, mode, InstanceType.NEW_FROM_CONSTRUCTOR); + ((SimpleBossSkill) instance).register(); } else if (Tool.class.isAssignableFrom(clazz)) // Automatically registered in its constructor - enforceModeFor(clazz, mode, FindInstance.SINGLETON); + enforceModeFor(clazz, mode, InstanceType.SINGLETON); + else if (instance instanceof Listener) { // Pass-through to register events later } - else + else { throw new FoException("@AutoRegister cannot be used on " + clazz); + } // Register events if needed - if (!eventsRegistered && instance instanceof Listener) + if (!eventsRegistered && instance instanceof Listener) { plugin.registerEvents((Listener) instance); + } } /* @@ -453,14 +454,14 @@ private static List> findValidClasses() { } /* - * Tries to return instance of the given class, either by returning its singleon - * or creating a new instance from constructor if valid + * Tries to return instance of the given class, either by returning its singleton + * or creating a new instance from a constructor */ - private static Tuple findInstance(Class clazz) { + private static Tuple findInstance(Class clazz) { final Constructor constructor; Object instance = null; - FindInstance mode = null; + InstanceType mode = null; try{ constructor = clazz.getDeclaredConstructor(); @@ -469,7 +470,7 @@ private static Tuple findInstance(Class clazz) { // Case 1: Public constructor if (Modifier.isPublic(modifiers)) { instance = ReflectionUtil.instantiate(constructor); - mode = FindInstance.NEW_FROM_CONSTRUCTOR; + mode = InstanceType.NEW_FROM_CONSTRUCTOR; } // Case 2: Singleton @@ -495,7 +496,7 @@ else if (Modifier.isPrivate(modifiers)) { instanceField = field; } } - if (instanceField == null){ + if (instanceField == null && suitable.size() != 0){ Logger.printErrors( "PROBLEM:", "Your " + clazz + " (using @AutoRegister) contains several", @@ -510,7 +511,7 @@ else if (Modifier.isPrivate(modifiers)) { if (instanceField != null) { instance = ReflectionUtil.getFieldContent(instanceField, (Object) null); - mode = FindInstance.SINGLETON; + mode = InstanceType.SINGLETON; } } @@ -528,15 +529,15 @@ else if (Modifier.isPrivate(modifiers)) { /* * Checks if the way the given class can be made a new instance of, correspond with the required way */ - private static void enforceModeFor(Class clazz, FindInstance actual, FindInstance required) { - Valid.checkBoolean(required == actual, clazz + " using @AutoRegister must have " + (required == FindInstance.NEW_FROM_CONSTRUCTOR ? "a single public no args constructor" + private static void enforceModeFor(Class clazz, InstanceType actual, InstanceType required) { + Valid.checkBoolean(required == actual, clazz + " using @AutoRegister must have " + (required == InstanceType.NEW_FROM_CONSTRUCTOR ? "a single public no args constructor" : "one private no args constructor and a 'private static final " + clazz.getSimpleName() + " instance' field to be a singleton")); } /* * How a new instance can be made to autoregister */ - enum FindInstance { + enum InstanceType { NEW_FROM_CONSTRUCTOR, SINGLETON }