From 809c4514612487262268cfbe93a141ad95fea3cd Mon Sep 17 00:00:00 2001 From: jayoevans Date: Sat, 26 Oct 2019 15:56:30 +1000 Subject: [PATCH] Setup ability registry --- .../projectkorra/ability/Ability.java | 363 ++++++------------ .../projectkorra/ability/AbilityData.java | 15 +- .../ability/AbilityException.java | 16 + .../projectkorra/ability/AbilityManager.java | 126 ++++-- ...ilityLoader.java => AbilityRegistery.java} | 32 +- ...Loader.java => AddonAbilityRegistery.java} | 25 +- .../projectkorra/event/AbilityLoadEvent.java | 6 +- 7 files changed, 261 insertions(+), 322 deletions(-) create mode 100644 src/com/projectkorra/projectkorra/ability/AbilityException.java rename src/com/projectkorra/projectkorra/ability/util/{AbilityLoader.java => AbilityRegistery.java} (79%) rename src/com/projectkorra/projectkorra/ability/util/{AddonAbilityLoader.java => AddonAbilityRegistery.java} (83%) diff --git a/src/com/projectkorra/projectkorra/ability/Ability.java b/src/com/projectkorra/projectkorra/ability/Ability.java index df92b88e..ed31d3d8 100644 --- a/src/com/projectkorra/projectkorra/ability/Ability.java +++ b/src/com/projectkorra/projectkorra/ability/Ability.java @@ -57,7 +57,6 @@ import java.util.jar.JarFile; public abstract class Ability { private static final double DEFAULT_COLLISION_RADIUS = 0.3; - private static final List ADDON_PLUGINS = new ArrayList<>(); private static final Map, Map> ATTRIBUTE_FIELDS = new HashMap<>(); private static int idCounter; @@ -94,7 +93,7 @@ public abstract class Ability { * @see #ABILITIES_BY_NAME * @see #getAbility(String) */ - public Ability() { + private Ability() { for (final Field field : this.getClass().getDeclaredFields()) { if (field.isAnnotationPresent(Attribute.class)) { final Attribute attribute = field.getAnnotation(Attribute.class); @@ -113,7 +112,9 @@ public abstract class Ability { * @see #start() */ public Ability(final Config config, final Player player) { - if (player == null || !this.isEnabled()) { + this(); + + if (player == null) { return; } @@ -143,7 +144,7 @@ public abstract class Ability { * @see #isRemoved() */ public final void start() { - if (this.player == null || !this.isEnabled()) { + if (this.player == null) { return; } final AbilityStartEvent event = new AbilityStartEvent(this); @@ -188,152 +189,6 @@ public abstract class Ability { } } - /** - * Ability keeps track of plugins that have registered abilities to use - * for bending reload purposes
- * This isn't a simple list, external use isn't recommended - * - * @return a list of entrys with the plugin name and path abilities can be - * found at - */ - public static List getAddonPlugins() { - return ADDON_PLUGINS; - } - - /** - * Scans a JavaPlugin and registers Ability class files. - * - * @param plugin a JavaPlugin containing Ability class files - * @param packageBase a prefix of the package name, used to increase - * performance - * @see #getAbilities() - * @see #getAbility(String) - */ - public static void registerPluginAbilities(final JavaPlugin plugin, final String packageBase) { - final com.projectkorra.projectkorra.ability.loader.AbilityLoader abilityLoader = new com.projectkorra.projectkorra.ability.loader.AbilityLoader(plugin, packageBase); - final List loadedAbilities = abilityLoader.load(Ability.class, Ability.class); - final String entry = plugin.getName() + "::" + packageBase; - if (!ADDON_PLUGINS.contains(entry)) { - ADDON_PLUGINS.add(entry); - } - - for (final Ability coreAbil : loadedAbilities) { - if (!coreAbil.isEnabled()) { - plugin.getLogger().info(coreAbil.getName() + " is disabled"); - continue; - } - - final String name = coreAbil.getName(); - - if (name == null) { - plugin.getLogger().warning("Ability " + coreAbil.getClass().getName() + " has no name?"); - continue; - } - - try { - ABILITIES_BY_NAME.put(name.toLowerCase(), coreAbil); - ABILITIES_BY_CLASS.put(coreAbil.getClass(), coreAbil); - - if (coreAbil instanceof ComboAbility) { - final ComboAbility combo = (ComboAbility) coreAbil; - if (combo.getCombination() != null) { - ComboManager.getComboAbilities().put(name, new ComboManager.ComboAbilityInfo(name, combo.getCombination(), combo)); - ComboManager.getDescriptions().put(name, coreAbil.getDescription()); - ComboManager.getInstructions().put(name, coreAbil.getInstructions()); - } - } - - if (coreAbil instanceof MultiAbility) { - final MultiAbility multiAbil = (MultiAbility) coreAbil; - MultiAbilityManager.multiAbilityList.add(new MultiAbilityInfo(name, multiAbil.getMultiAbilities())); - } - - if (coreAbil instanceof PassiveAbility) { - PassiveAbility passive = (PassiveAbility) coreAbil; - coreAbil.setHiddenAbility(true); - PassiveManager.getPassives().put(name, coreAbil); - if (!PassiveManager.getPassiveClasses().containsKey(passive)) { - PassiveManager.getPassiveClasses().put(passive, coreAbil.getClass()); - } - } - } catch (Exception | Error e) { - plugin.getLogger().warning("The ability " + coreAbil.getName() + " was not able to load, if this message shows again please remove it!"); - e.printStackTrace(); - ABILITIES_BY_NAME.remove(name.toLowerCase()); - ABILITIES_BY_CLASS.remove(coreAbil.getClass()); - } - } - } - - /** - * Scans all of the Jar files inside of /ProjectKorra/folder and registers - * all of the Ability class files that were found. - * - * @param folder the name of the folder to scan - * @see #getAbilities() - * @see #getAbility(String) - */ - public static void registerAddonAbilities(final String folder) { - final ProjectKorra plugin = ProjectKorra.plugin; - final File path = new File(plugin.getDataFolder().toString() + folder); - if (!path.exists()) { - path.mkdir(); - return; - } - - final com.projectkorra.projectkorra.ability.loader.AddonAbilityLoader abilityLoader = new AddonAbilityLoader(plugin, path); - final List loadedAbilities = abilityLoader.load(Ability.class, Ability.class); - - for (final Ability coreAbil : loadedAbilities) { - if (!(coreAbil instanceof AddonAbility)) { - plugin.getLogger().warning(coreAbil.getName() + " is an addon ability and must implement the AddonAbility interface"); - continue; - } else if (!coreAbil.isEnabled()) { - plugin.getLogger().info(coreAbil.getName() + " is disabled"); - continue; - } - - final AddonAbility addon = (AddonAbility) coreAbil; - final String name = coreAbil.getName(); - - try { - addon.load(); - ABILITIES_BY_NAME.put(name.toLowerCase(), coreAbil); - ABILITIES_BY_CLASS.put(coreAbil.getClass(), coreAbil); - - if (coreAbil instanceof ComboAbility) { - final ComboAbility combo = (ComboAbility) coreAbil; - if (combo.getCombination() != null) { - ComboManager.getComboAbilities().put(name, new ComboManager.ComboAbilityInfo(name, combo.getCombination(), combo)); - ComboManager.getDescriptions().put(name, coreAbil.getDescription()); - ComboManager.getInstructions().put(name, coreAbil.getInstructions()); - ComboManager.getAuthors().put(name, addon.getAuthor()); - } - } - - if (coreAbil instanceof MultiAbility) { - final MultiAbility multiAbil = (MultiAbility) coreAbil; - MultiAbilityManager.multiAbilityList.add(new MultiAbilityInfo(name, multiAbil.getMultiAbilities())); - } - - if (coreAbil instanceof PassiveAbility) { - PassiveAbility passive = (PassiveAbility) coreAbil; - coreAbil.setHiddenAbility(true); - PassiveManager.getPassives().put(name, coreAbil); - if (!PassiveManager.getPassiveClasses().containsKey(passive)) { - PassiveManager.getPassiveClasses().put(passive, coreAbil.getClass()); - } - } - } catch (Exception | Error e) { - plugin.getLogger().warning("The ability " + coreAbil.getName() + " was not able to load, if this message shows again please remove it!"); - e.printStackTrace(); - addon.stop(); - ABILITIES_BY_NAME.remove(name.toLowerCase()); - ABILITIES_BY_CLASS.remove(coreAbil.getClass()); - } - } - } - public long getStartTime() { return this.startTime; } @@ -380,21 +235,21 @@ public abstract class Ability { return config.Description; } - public String getMovePreview(final Player player) { - final BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); - String displayedMessage = ""; - if (bPlayer.isOnCooldown(this)) { - final long cooldown = bPlayer.getCooldown(this.getName()) - System.currentTimeMillis(); - displayedMessage = this.getElement().getColor() + "" + ChatColor.STRIKETHROUGH + this.getName() + "" + this.getElement().getColor() + " - " + TimeUtil.formatTime(cooldown); - } else { - if (bPlayer.getStance() != null && bPlayer.getStance().getName().equals(this.getName())) { - displayedMessage = this.getElement().getColor() + "" + ChatColor.UNDERLINE + this.getName(); - } else { - displayedMessage = this.getElement().getColor() + this.getName(); - } - } - return displayedMessage; - } +// public String getMovePreview(final Player player) { +// final BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); +// String displayedMessage = ""; +// if (bPlayer.isOnCooldown(this)) { +// final long cooldown = bPlayer.getCooldown(this.getName()) - System.currentTimeMillis(); +// displayedMessage = this.getElement().getColor() + "" + ChatColor.STRIKETHROUGH + this.getName() + "" + this.getElement().getColor() + " - " + TimeUtil.formatTime(cooldown); +// } else { +// if (bPlayer.getStance() != null && bPlayer.getStance().getName().equals(this.getName())) { +// displayedMessage = this.getElement().getColor() + "" + ChatColor.UNDERLINE + this.getName(); +// } else { +// displayedMessage = this.getElement().getColor() + this.getName(); +// } +// } +// return displayedMessage; +// } public Player getPlayer() { return this.player; @@ -406,57 +261,57 @@ public abstract class Ability { * * @param target The player who now controls the ability */ - public void setPlayer(final Player target) { - if (target == this.player) { - return; - } - - final Class clazz = this.getClass(); - - // The mapping from player UUID to a map of the player's instances. - Map> classMap = INSTANCES_BY_PLAYER.get(clazz); - - if (classMap != null) { - // The map of AbilityId to Ability for the current player. - final Map playerMap = classMap.get(this.player.getUniqueId()); - - if (playerMap != null) { - // Remove the ability from the current player's map. - playerMap.remove(this.id); - - if (playerMap.isEmpty()) { - // Remove the player's empty ability map from global instances map. - classMap.remove(this.player.getUniqueId()); - } - } - - if (classMap.isEmpty()) { - INSTANCES_BY_PLAYER.remove(this.getClass()); - } - } - - // Add a new map for the current ability if it doesn't exist in the global map. - if (!INSTANCES_BY_PLAYER.containsKey(clazz)) { - INSTANCES_BY_PLAYER.put(clazz, new ConcurrentHashMap<>()); - } - - classMap = INSTANCES_BY_PLAYER.get(clazz); - - // Create an AbilityId to Ability map for the target player if it doesn't exist. - if (!classMap.containsKey(target.getUniqueId())) { - classMap.put(target.getUniqueId(), new ConcurrentHashMap<>()); - } - - // Add the current instance to the target player's ability map. - classMap.get(target.getUniqueId()).put(this.getId(), this); - - this.player = target; - - final BendingPlayer newBendingPlayer = BendingPlayer.getBendingPlayer(target); - if (newBendingPlayer != null) { - this.bPlayer = newBendingPlayer; - } - } +// public void setPlayer(final Player target) { +// if (target == this.player) { +// return; +// } +// +// final Class clazz = this.getClass(); +// +// // The mapping from player UUID to a map of the player's instances. +// Map> classMap = INSTANCES_BY_PLAYER.get(clazz); +// +// if (classMap != null) { +// // The map of AbilityId to Ability for the current player. +// final Map playerMap = classMap.get(this.player.getUniqueId()); +// +// if (playerMap != null) { +// // Remove the ability from the current player's map. +// playerMap.remove(this.id); +// +// if (playerMap.isEmpty()) { +// // Remove the player's empty ability map from global instances map. +// classMap.remove(this.player.getUniqueId()); +// } +// } +// +// if (classMap.isEmpty()) { +// INSTANCES_BY_PLAYER.remove(this.getClass()); +// } +// } +// +// // Add a new map for the current ability if it doesn't exist in the global map. +// if (!INSTANCES_BY_PLAYER.containsKey(clazz)) { +// INSTANCES_BY_PLAYER.put(clazz, new ConcurrentHashMap<>()); +// } +// +// classMap = INSTANCES_BY_PLAYER.get(clazz); +// +// // Create an AbilityId to Ability map for the target player if it doesn't exist. +// if (!classMap.containsKey(target.getUniqueId())) { +// classMap.put(target.getUniqueId(), new ConcurrentHashMap<>()); +// } +// +// // Add the current instance to the target player's ability map. +// classMap.get(target.getUniqueId()).put(this.getId(), this); +// +// this.player = target; +// +// final BendingPlayer newBendingPlayer = BendingPlayer.getBendingPlayer(target); +// if (newBendingPlayer != null) { +// this.bPlayer = newBendingPlayer; +// } +// } /** * Used by the CollisionManager to check if two instances can collide with @@ -589,44 +444,44 @@ public abstract class Ability { * Returns a String used to debug potential Ability memory that can be * caused by a developer forgetting to call {@link #remove()} */ - public static String getDebugString() { - final StringBuilder sb = new StringBuilder(); - int playerCounter = 0; - final HashMap classCounter = new HashMap<>(); - - for (final Map> map1 : INSTANCES_BY_PLAYER.values()) { - playerCounter++; - for (final Map map2 : map1.values()) { - for (final Ability coreAbil : map2.values()) { - final String simpleName = coreAbil.getClass().getSimpleName(); - - if (classCounter.containsKey(simpleName)) { - classCounter.put(simpleName, classCounter.get(simpleName) + 1); - } else { - classCounter.put(simpleName, 1); - } - } - } - } - - for (final Set set : INSTANCES_BY_CLASS.values()) { - for (final Ability coreAbil : set) { - final String simpleName = coreAbil.getClass().getSimpleName(); - if (classCounter.containsKey(simpleName)) { - classCounter.put(simpleName, classCounter.get(simpleName) + 1); - } else { - classCounter.put(simpleName, 1); - } - } - } - - sb.append("Class->UUID's in memory: " + playerCounter + "\n"); - sb.append("Abilities in memory:\n"); - for (final String className : classCounter.keySet()) { - sb.append(className + ": " + classCounter.get(className) + "\n"); - } - return sb.toString(); - } +// public static String getDebugString() { +// final StringBuilder sb = new StringBuilder(); +// int playerCounter = 0; +// final HashMap classCounter = new HashMap<>(); +// +// for (final Map> map1 : INSTANCES_BY_PLAYER.values()) { +// playerCounter++; +// for (final Map map2 : map1.values()) { +// for (final Ability coreAbil : map2.values()) { +// final String simpleName = coreAbil.getClass().getSimpleName(); +// +// if (classCounter.containsKey(simpleName)) { +// classCounter.put(simpleName, classCounter.get(simpleName) + 1); +// } else { +// classCounter.put(simpleName, 1); +// } +// } +// } +// } +// +// for (final Set set : INSTANCES_BY_CLASS.values()) { +// for (final Ability coreAbil : set) { +// final String simpleName = coreAbil.getClass().getSimpleName(); +// if (classCounter.containsKey(simpleName)) { +// classCounter.put(simpleName, classCounter.get(simpleName) + 1); +// } else { +// classCounter.put(simpleName, 1); +// } +// } +// } +// +// sb.append("Class->UUID's in memory: " + playerCounter + "\n"); +// sb.append("Abilities in memory:\n"); +// for (final String className : classCounter.keySet()) { +// sb.append(className + ": " + classCounter.get(className) + "\n"); +// } +// return sb.toString(); +// } public abstract void progress(); diff --git a/src/com/projectkorra/projectkorra/ability/AbilityData.java b/src/com/projectkorra/projectkorra/ability/AbilityData.java index 09ea4b1f..ca9a52cd 100644 --- a/src/com/projectkorra/projectkorra/ability/AbilityData.java +++ b/src/com/projectkorra/projectkorra/ability/AbilityData.java @@ -26,6 +26,16 @@ public @interface AbilityData { */ String name(); + /** + * @return The class used to register this ability. + */ + Class abilityLoader(); + + /** + * @return true if this is a hidden ability. + */ + boolean hidden() default false; + /** * @return the name of the author of this AddonAbility */ @@ -35,9 +45,4 @@ public @interface AbilityData { * @return The version of the ability as a String. */ String version() default "1.0"; - - /** - * @return The class used to register this ability. - */ - Class abilityLoader(); } diff --git a/src/com/projectkorra/projectkorra/ability/AbilityException.java b/src/com/projectkorra/projectkorra/ability/AbilityException.java new file mode 100644 index 00000000..1a381a42 --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/AbilityException.java @@ -0,0 +1,16 @@ +package com.projectkorra.projectkorra.ability; + +public class AbilityException extends RuntimeException { + + public AbilityException(String message) { + super(message); + } + + public AbilityException(String message, Throwable cause) { + super(message, cause); + } + + public AbilityException(Throwable cause) { + super(cause); + } +} diff --git a/src/com/projectkorra/projectkorra/ability/AbilityManager.java b/src/com/projectkorra/projectkorra/ability/AbilityManager.java index 027b28b6..4ab7ae14 100644 --- a/src/com/projectkorra/projectkorra/ability/AbilityManager.java +++ b/src/com/projectkorra/projectkorra/ability/AbilityManager.java @@ -4,18 +4,20 @@ import co.aikar.timings.lib.MCTiming; import com.projectkorra.projectkorra.ProjectKorra; import com.projectkorra.projectkorra.ability.api.PassiveAbility; import com.projectkorra.projectkorra.ability.loader.*; +import com.projectkorra.projectkorra.ability.util.AbilityRegistery; +import com.projectkorra.projectkorra.ability.util.AddonAbilityRegistery; import com.projectkorra.projectkorra.configuration.ConfigManager; import com.projectkorra.projectkorra.configuration.configs.abilities.AbilityConfig; import com.projectkorra.projectkorra.element.Element; import com.projectkorra.projectkorra.element.SubElement; import com.projectkorra.projectkorra.event.AbilityProgressEvent; -import com.projectkorra.projectkorra.firebending.FireBlast; import com.projectkorra.projectkorra.module.Module; import com.projectkorra.projectkorra.module.ModuleManager; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; +import java.io.File; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.ParameterizedType; @@ -31,6 +33,8 @@ public class AbilityManager extends Module { private final Set abilitySet = new HashSet<>(); private final Map, LinkedList>> abilityMap = new HashMap<>(); + private final Set addonPlugins = new HashSet<>(); + public AbilityManager() { super("Ability"); @@ -99,30 +103,76 @@ public class AbilityManager extends Module { this.abilitySet.clear(); this.abilityMap.clear(); - Ability.registerPluginAbilities(getPlugin(), "com.projectkorra"); - Ability.registerAddonAbilities("/Abilities/"); + registerPluginAbilities("com.projectkorra"); + registerAddonAbilities("Abilities"); - registerAbility(FireBlast.class); +// registerAbility(FireBlast.class); } - private void registerAbility(Class abilityClass) throws IllegalAccessException, InstantiationException { - AbilityData abilityData = abilityClass.getDeclaredAnnotation(AbilityData.class); + /** + * Scans a JavaPlugin and registers Ability class files. + * + * @param plugin a JavaPlugin containing Ability class files + * @param packageBase a prefix of the package name, used to increase + * performance + * @see #getAbilities() + * @see #getAbility(String) + */ + public void registerPluginAbilities(String packageBase) { + AbilityRegistery abilityRegistery = new AbilityRegistery<>(getPlugin(), packageBase); + List> loadedAbilities = abilityRegistery.load(Ability.class, Ability.class); - if (abilityData == null) { - getPlugin().getLogger().warning("Ability " + abilityClass.getName() + " has no AbilityData annotation"); + String entry = getPlugin().getName() + "::" + packageBase; + this.addonPlugins.add(entry); + + for (Class abilityClass : loadedAbilities) { + AbilityData abilityData = getAbilityData(abilityClass); + AbilityLoader abilityLoader = getAbilityLoader(abilityData); + + registerAbility(abilityClass, abilityData, abilityLoader); + } + } + + /** + * Scans all of the Jar files inside of /ProjectKorra/folder and registers + * all of the Ability class files that were found. + * + * @param folder the name of the folder to scan + * @see #getAbilities() + * @see #getAbility(String) + */ + public void registerAddonAbilities(String folder) { + File file = new File(getPlugin().getDataFolder(), folder); + + if (!file.exists()) { + file.mkdir(); return; } + AddonAbilityRegistery abilityRegistery = new AddonAbilityRegistery<>(getPlugin(), file); + List> loadedAbilities = abilityRegistery.load(Ability.class, Ability.class); + + for (Class abilityClass : loadedAbilities) { + AbilityData abilityData = getAbilityData(abilityClass); + AbilityLoader abilityLoader = getAbilityLoader(abilityData); + + if (!(abilityLoader instanceof AddonAbilityLoader)) { + throw new AbilityException(abilityClass.getName() + " must have an AddonAbilityLoader"); + } + + registerAbility(abilityClass, abilityData, abilityLoader); + } + } + + private void registerAbility(Class abilityClass, AbilityData abilityData, AbilityLoader abilityLoader) throws AbilityException { + AbilityConfig abilityConfig = getAbilityConfig(abilityClass); + String abilityName = abilityData.name(); if (abilityName == null) { - getPlugin().getLogger().warning("Ability " + abilityClass.getName() + " has no name?"); - return; + throw new AbilityException("Ability " + abilityClass.getName() + " has no name"); } - AbilityLoader abilityLoader = abilityData.abilityLoader().newInstance(); - AbilityConfig abilityConfig = ConfigManager.getConfig(((Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0])); - if (!abilityConfig.Enabled) { getPlugin().getLogger().info(abilityName + " is disabled"); return; @@ -141,18 +191,12 @@ public class AbilityManager extends Module { } this.comboAbilityManager.registerAbility(abilityClass, abilityData, comboAbilityLoader); - -// ComboManager.getComboAbilities().put(abilityName, new ComboManager.ComboAbilityInfo(abilityName, comboAbilityLoader.getCombination(), )); -// ComboManager.getDescriptions().put(abilityName, abilityConfig.Description); -// ComboManager.getInstructions().put(abilityName, abilityConfig.Instructions); } if (abilityLoader instanceof MultiAbilityLoader) { MultiAbilityLoader multiAbilityLoader = (MultiAbilityLoader) abilityLoader; this.multiAbilityManager.registerAbility(abilityClass, abilityData, multiAbilityLoader); - -// MultiAbilityManager.multiAbilityList.add(new MultiAbilityManager.MultiAbilityInfo(abilityName, multiAbilityLoader.getMultiAbilities())); } if (abilityLoader instanceof PassiveAbilityLoader) { @@ -164,16 +208,40 @@ public class AbilityManager extends Module { } } - public T createAbility(Player player, Class abilityClass) { + private AbilityData getAbilityData(Class abilityClass) throws AbilityException { + AbilityData abilityData = abilityClass.getDeclaredAnnotation(AbilityData.class); + + if (abilityData == null) { + throw new AbilityException("Ability " + abilityClass.getName() + " has missing AbilityData annotation"); + } + + return abilityData; + } + + private AbilityLoader getAbilityLoader(AbilityData abilityData) throws AbilityException { + try { + return abilityData.abilityLoader().newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new AbilityException(e); + } + } + + private AbilityConfig getAbilityConfig(Class abilityClass) throws AbilityException { + try { + return ConfigManager.getConfig(((Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0])); + } catch (Exception e) { + throw new AbilityException(e); + } + } + + public T createAbility(Player player, Class abilityClass) throws AbilityException { try { Constructor constructor = abilityClass.getDeclaredConstructor(Player.class); return constructor.newInstance(player); } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { - e.printStackTrace(); + throw new AbilityException(e); } - - return null; } public void startAbility(Ability ability) { @@ -270,4 +338,16 @@ public class AbilityManager extends Module { }) .collect(Collectors.toList()); } + + /** + * {@link AbilityManager} keeps track of plugins that have registered abilities to use + * for bending reload purposes
+ * This isn't a simple list, external use isn't recommended + * + * @return a list of entrys with the plugin name and path abilities can be + * found at + */ + public Set getAddonPlugins() { + return this.addonPlugins; + } } diff --git a/src/com/projectkorra/projectkorra/ability/util/AbilityLoader.java b/src/com/projectkorra/projectkorra/ability/util/AbilityRegistery.java similarity index 79% rename from src/com/projectkorra/projectkorra/ability/util/AbilityLoader.java rename to src/com/projectkorra/projectkorra/ability/util/AbilityRegistery.java index c3752719..8cc1974e 100644 --- a/src/com/projectkorra/projectkorra/ability/util/AbilityLoader.java +++ b/src/com/projectkorra/projectkorra/ability/util/AbilityRegistery.java @@ -1,8 +1,12 @@ package com.projectkorra.projectkorra.ability.util; +import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.event.AbilityLoadEvent; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; + import java.io.File; import java.io.IOException; -import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; import java.net.URL; import java.net.URLDecoder; @@ -12,22 +16,14 @@ import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarFile; -import sun.reflect.ReflectionFactory; - -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.java.JavaPlugin; - -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.event.AbilityLoadEvent; - -public class AbilityLoader { +public class AbilityRegistery { private final Plugin plugin; private ClassLoader loader; private JarFile jar; private String path; - public AbilityLoader(final JavaPlugin plugin, final String packageBase) { + public AbilityRegistery(final JavaPlugin plugin, final String packageBase) { this.plugin = plugin; this.loader = plugin.getClass().getClassLoader(); this.path = packageBase.replace('.', '/'); @@ -60,8 +56,8 @@ public class AbilityLoader { * {@code Object.class} for classes without a type. * @return */ - public List load(final Class classType, final Class parentClass) { - final ArrayList loadables = new ArrayList<>(); + public List> load(final Class classType, final Class parentClass) { + final ArrayList> loadables = new ArrayList<>(); if (this.loader == null || this.jar == null) { return loadables; @@ -89,16 +85,10 @@ public class AbilityLoader { continue; } - final ReflectionFactory rf = ReflectionFactory.getReflectionFactory(); - final Constructor objDef = parentClass.getDeclaredConstructor(); - final Constructor intConstr = rf.newConstructorForSerialization(clazz, objDef); - final T loadable = (T) clazz.cast(intConstr.newInstance()); - - if (loadable == null) { - continue; - } + Class loadable = (Class) clazz; loadables.add(loadable); + final AbilityLoadEvent event = new AbilityLoadEvent(this.plugin, loadable, this.jar); this.plugin.getServer().getPluginManager().callEvent(event); } catch (Exception | Error e) { diff --git a/src/com/projectkorra/projectkorra/ability/util/AddonAbilityLoader.java b/src/com/projectkorra/projectkorra/ability/util/AddonAbilityRegistery.java similarity index 83% rename from src/com/projectkorra/projectkorra/ability/util/AddonAbilityLoader.java rename to src/com/projectkorra/projectkorra/ability/util/AddonAbilityRegistery.java index 795b1b66..6bcb0151 100644 --- a/src/com/projectkorra/projectkorra/ability/util/AddonAbilityLoader.java +++ b/src/com/projectkorra/projectkorra/ability/util/AddonAbilityRegistery.java @@ -1,8 +1,11 @@ package com.projectkorra.projectkorra.ability.util; +import com.projectkorra.projectkorra.event.AbilityLoadEvent; +import com.projectkorra.projectkorra.util.FileExtensionFilter; +import org.bukkit.plugin.Plugin; + import java.io.File; import java.io.IOException; -import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; import java.net.MalformedURLException; import java.net.URL; @@ -14,21 +17,14 @@ import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.logging.Level; -import sun.reflect.ReflectionFactory; - -import org.bukkit.plugin.Plugin; - -import com.projectkorra.projectkorra.event.AbilityLoadEvent; -import com.projectkorra.projectkorra.util.FileExtensionFilter; - -public class AddonAbilityLoader { +public class AddonAbilityRegistery { private final Plugin plugin; private final File directory; private final ArrayList files; private ClassLoader loader; - public AddonAbilityLoader(final Plugin plugin, final File directory) { + public AddonAbilityRegistery(final Plugin plugin, final File directory) { this.plugin = plugin; this.directory = directory; this.files = new ArrayList(); @@ -59,8 +55,8 @@ public class AddonAbilityLoader { * @return A list of all of the T objects that were loaded from the jar * files within @param directory */ - public List load(final Class classType, final Class parentClass) { - final ArrayList loadables = new ArrayList<>(); + public List> load(final Class classType, final Class parentClass) { + final ArrayList> loadables = new ArrayList<>(); for (final File file : this.files) { JarFile jarFile = null; @@ -86,10 +82,7 @@ public class AddonAbilityLoader { continue; } - final ReflectionFactory rf = ReflectionFactory.getReflectionFactory(); - final Constructor objDef = parentClass.getDeclaredConstructor(); - final Constructor intConstr = rf.newConstructorForSerialization(clazz, objDef); - final T loadable = (T) clazz.cast(intConstr.newInstance()); + Class loadable = (Class) clazz; loadables.add(loadable); final AbilityLoadEvent event = new AbilityLoadEvent(this.plugin, loadable, jarFile); diff --git a/src/com/projectkorra/projectkorra/event/AbilityLoadEvent.java b/src/com/projectkorra/projectkorra/event/AbilityLoadEvent.java index 1a100b12..04186e24 100644 --- a/src/com/projectkorra/projectkorra/event/AbilityLoadEvent.java +++ b/src/com/projectkorra/projectkorra/event/AbilityLoadEvent.java @@ -14,7 +14,7 @@ public class AbilityLoadEvent extends Event { private static final HandlerList handlers = new HandlerList(); private final Plugin plugin; - private final T loadable; + private final Class loadable; private final JarFile jarFile; /** @@ -24,7 +24,7 @@ public class AbilityLoadEvent extends Event { * @param loadable The class that was loaded * @param jarFile The JarFile the class was loaded from */ - public AbilityLoadEvent(final Plugin plugin, final T loadable, final JarFile jarFile) { + public AbilityLoadEvent(final Plugin plugin, final Class loadable, final JarFile jarFile) { this.plugin = plugin; this.loadable = loadable; this.jarFile = jarFile; @@ -53,7 +53,7 @@ public class AbilityLoadEvent extends Event { * * @return The loaded class */ - public T getLoadable() { + public Class getLoadable() { return this.loadable; }