Setup ability registry

This commit is contained in:
jayoevans 2019-10-26 15:56:30 +10:00
parent ad148a7881
commit 809c451461
7 changed files with 261 additions and 322 deletions

View file

@ -57,7 +57,6 @@ import java.util.jar.JarFile;
public abstract class Ability<Config extends AbilityConfig> {
private static final double DEFAULT_COLLISION_RADIUS = 0.3;
private static final List<String> ADDON_PLUGINS = new ArrayList<>();
private static final Map<Class<? extends Ability>, Map<String, Field>> ATTRIBUTE_FIELDS = new HashMap<>();
private static int idCounter;
@ -94,7 +93,7 @@ public abstract class Ability<Config extends AbilityConfig> {
* @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<Config extends AbilityConfig> {
* @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<Config extends AbilityConfig> {
* @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<Config extends AbilityConfig> {
}
}
/**
* Ability keeps track of plugins that have registered abilities to use
* for bending reload purposes <br>
* <b>This isn't a simple list, external use isn't recommended</b>
*
* @return a list of entrys with the plugin name and path abilities can be
* found at
*/
public static List<String> 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<Ability> abilityLoader = new com.projectkorra.projectkorra.ability.loader.AbilityLoader<Ability>(plugin, packageBase);
final List<Ability> 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<Ability> abilityLoader = new AddonAbilityLoader<Ability>(plugin, path);
final List<Ability> 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<Config extends AbilityConfig> {
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<Config extends AbilityConfig> {
*
* @param target The player who now controls the ability
*/
public void setPlayer(final Player target) {
if (target == this.player) {
return;
}
final Class<? extends Ability> clazz = this.getClass();
// The mapping from player UUID to a map of the player's instances.
Map<UUID, Map<Integer, Ability>> classMap = INSTANCES_BY_PLAYER.get(clazz);
if (classMap != null) {
// The map of AbilityId to Ability for the current player.
final Map<Integer, Ability> 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<? extends Ability> clazz = this.getClass();
//
// // The mapping from player UUID to a map of the player's instances.
// Map<UUID, Map<Integer, Ability>> classMap = INSTANCES_BY_PLAYER.get(clazz);
//
// if (classMap != null) {
// // The map of AbilityId to Ability for the current player.
// final Map<Integer, Ability> 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<Config extends AbilityConfig> {
* 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<String, Integer> classCounter = new HashMap<>();
for (final Map<UUID, Map<Integer, Ability>> map1 : INSTANCES_BY_PLAYER.values()) {
playerCounter++;
for (final Map<Integer, Ability> 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<Ability> 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<String, Integer> classCounter = new HashMap<>();
//
// for (final Map<UUID, Map<Integer, Ability>> map1 : INSTANCES_BY_PLAYER.values()) {
// playerCounter++;
// for (final Map<Integer, Ability> 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<Ability> 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();

View file

@ -26,6 +26,16 @@ public @interface AbilityData {
*/
String name();
/**
* @return The class used to register this ability.
*/
Class<? extends AbilityLoader> 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<? extends AbilityLoader> abilityLoader();
}

View file

@ -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);
}
}

View file

@ -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<Ability> abilitySet = new HashSet<>();
private final Map<UUID, Map<Class<? extends Ability>, LinkedList<Ability>>> abilityMap = new HashMap<>();
private final Set<String> 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 <T extends Ability> void registerAbility(Class<T> 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<Ability> abilityRegistery = new AbilityRegistery<>(getPlugin(), packageBase);
List<Class<Ability>> 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<Ability> 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<Ability> abilityRegistery = new AddonAbilityRegistery<>(getPlugin(), file);
List<Class<Ability>> loadedAbilities = abilityRegistery.load(Ability.class, Ability.class);
for (Class<Ability> 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 <T extends Ability> void registerAbility(Class<T> 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<? extends AbilityConfig>) ((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 extends Ability> T createAbility(Player player, Class<T> abilityClass) {
private AbilityData getAbilityData(Class<? extends Ability> 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<? extends Ability> abilityClass) throws AbilityException {
try {
return ConfigManager.getConfig(((Class<? extends AbilityConfig>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]));
} catch (Exception e) {
throw new AbilityException(e);
}
}
public <T extends Ability> T createAbility(Player player, Class<T> abilityClass) throws AbilityException {
try {
Constructor<T> 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 <br>
* <b>This isn't a simple list, external use isn't recommended</b>
*
* @return a list of entrys with the plugin name and path abilities can be
* found at
*/
public Set<String> getAddonPlugins() {
return this.addonPlugins;
}
}

View file

@ -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<T> {
public class AbilityRegistery<T> {
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<T> {
* {@code Object.class} for classes without a type.
* @return
*/
public List<T> load(final Class<?> classType, final Class<?> parentClass) {
final ArrayList<T> loadables = new ArrayList<>();
public List<Class<T>> load(final Class<?> classType, final Class<?> parentClass) {
final ArrayList<Class<T>> loadables = new ArrayList<>();
if (this.loader == null || this.jar == null) {
return loadables;
@ -89,16 +85,10 @@ public class AbilityLoader<T> {
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<T> loadable = (Class<T>) clazz;
loadables.add(loadable);
final AbilityLoadEvent<T> event = new AbilityLoadEvent<T>(this.plugin, loadable, this.jar);
this.plugin.getServer().getPluginManager().callEvent(event);
} catch (Exception | Error e) {

View file

@ -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<T> {
public class AddonAbilityRegistery<T> {
private final Plugin plugin;
private final File directory;
private final ArrayList<File> 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<File>();
@ -59,8 +55,8 @@ public class AddonAbilityLoader<T> {
* @return A list of all of the T objects that were loaded from the jar
* files within @param directory
*/
public List<T> load(final Class<?> classType, final Class<?> parentClass) {
final ArrayList<T> loadables = new ArrayList<>();
public List<Class<T>> load(final Class<?> classType, final Class<?> parentClass) {
final ArrayList<Class<T>> loadables = new ArrayList<>();
for (final File file : this.files) {
JarFile jarFile = null;
@ -86,10 +82,7 @@ public class AddonAbilityLoader<T> {
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<T> loadable = (Class<T>) clazz;
loadables.add(loadable);
final AbilityLoadEvent<T> event = new AbilityLoadEvent<T>(this.plugin, loadable, jarFile);

View file

@ -14,7 +14,7 @@ public class AbilityLoadEvent<T> extends Event {
private static final HandlerList handlers = new HandlerList();
private final Plugin plugin;
private final T loadable;
private final Class<T> loadable;
private final JarFile jarFile;
/**
@ -24,7 +24,7 @@ public class AbilityLoadEvent<T> 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<T> loadable, final JarFile jarFile) {
this.plugin = plugin;
this.loadable = loadable;
this.jarFile = jarFile;
@ -53,7 +53,7 @@ public class AbilityLoadEvent<T> extends Event {
*
* @return The loaded class
*/
public T getLoadable() {
public Class<T> getLoadable() {
return this.loadable;
}