diff --git a/common/src/main/java/com/dfsek/terra/addons/injection/Inject.java b/common/src/main/java/com/dfsek/terra/addons/injection/Inject.java new file mode 100644 index 000000000..38b35cd42 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/addons/injection/Inject.java @@ -0,0 +1,11 @@ +package com.dfsek.terra.addons.injection; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Inject { +} diff --git a/common/src/main/java/com/dfsek/terra/addons/injection/InjectionException.java b/common/src/main/java/com/dfsek/terra/addons/injection/InjectionException.java new file mode 100644 index 000000000..26d3e5be4 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/addons/injection/InjectionException.java @@ -0,0 +1,13 @@ +package com.dfsek.terra.addons.injection; + +public class InjectionException extends Exception { + private static final long serialVersionUID = -6929631447064215387L; + + public InjectionException(String message) { + super(message); + } + + public InjectionException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/common/src/main/java/com/dfsek/terra/addons/injection/Injector.java b/common/src/main/java/com/dfsek/terra/addons/injection/Injector.java new file mode 100644 index 000000000..0ba685a4f --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/addons/injection/Injector.java @@ -0,0 +1,47 @@ +package com.dfsek.terra.addons.injection; + +import com.dfsek.terra.api.util.ReflectionUtil; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.HashSet; +import java.util.Set; + +public class Injector { + private final T value; + private final Set> targets = new HashSet<>(); + + public Injector(T value) { + this.value = value; + } + + public void addExplicitTarget(Class target) { + targets.add(target); + } + + public void inject(Object object) throws InjectionException { + for(Field field : ReflectionUtil.getFields(object.getClass())) { + Inject inject = field.getAnnotation(Inject.class); + if(inject == null) continue; + + System.out.println(field); + System.out.println("attempting to inject " + value.getClass() + " to " + field.getClass()); + if(value.getClass().equals(field.getType()) || targets.contains(field.getType())) { + System.out.println("injecting..."); + int mod = field.getModifiers(); + if(Modifier.isFinal(mod)) { + throw new InjectionException("Attempted to inject final field: " + field); + } + if(Modifier.isStatic(mod)) { + throw new InjectionException("Attempted to inject static field: " + field); + } + field.setAccessible(true); + try { + field.set(object, value); + } catch(IllegalAccessException e) { + throw new InjectionException("Failed to inject field: " + field, e); + } + } + } + } +} diff --git a/common/src/main/java/com/dfsek/terra/addons/loading/pre/PreLoadAddon.java b/common/src/main/java/com/dfsek/terra/addons/loading/pre/PreLoadAddon.java index 08e006e21..5b14b43ad 100644 --- a/common/src/main/java/com/dfsek/terra/addons/loading/pre/PreLoadAddon.java +++ b/common/src/main/java/com/dfsek/terra/addons/loading/pre/PreLoadAddon.java @@ -4,6 +4,8 @@ import com.dfsek.terra.addons.addon.TerraAddon; import com.dfsek.terra.addons.annotations.Addon; import com.dfsek.terra.addons.annotations.Depends; import com.dfsek.terra.addons.loading.AddonLoadException; +import com.dfsek.terra.addons.loading.pre.exception.CircularDependencyException; +import com.dfsek.terra.addons.loading.pre.exception.DependencyMissingException; import java.util.ArrayList; import java.util.Arrays; @@ -32,7 +34,8 @@ public class PreLoadAddon { for(String dependency : dependencies) { PreLoadAddon preLoadAddon = pool.get(dependency); - if(preLoadAddon == null) throw new DependencyMissingException("Dependency " + dependency + " was not found."); + if(preLoadAddon == null) + throw new DependencyMissingException("Dependency " + dependency + " was not found. Please install " + dependency + " to use " + id + "."); depends.add(preLoadAddon); preLoadAddon.rebuildDependencies(pool, origin, false); } diff --git a/common/src/main/java/com/dfsek/terra/addons/loading/pre/CircularDependencyException.java b/common/src/main/java/com/dfsek/terra/addons/loading/pre/exception/CircularDependencyException.java similarity index 88% rename from common/src/main/java/com/dfsek/terra/addons/loading/pre/CircularDependencyException.java rename to common/src/main/java/com/dfsek/terra/addons/loading/pre/exception/CircularDependencyException.java index f262f7285..221e66520 100644 --- a/common/src/main/java/com/dfsek/terra/addons/loading/pre/CircularDependencyException.java +++ b/common/src/main/java/com/dfsek/terra/addons/loading/pre/exception/CircularDependencyException.java @@ -1,4 +1,4 @@ -package com.dfsek.terra.addons.loading.pre; +package com.dfsek.terra.addons.loading.pre.exception; import com.dfsek.terra.addons.loading.AddonLoadException; diff --git a/common/src/main/java/com/dfsek/terra/addons/loading/pre/DependencyMissingException.java b/common/src/main/java/com/dfsek/terra/addons/loading/pre/exception/DependencyMissingException.java similarity index 88% rename from common/src/main/java/com/dfsek/terra/addons/loading/pre/DependencyMissingException.java rename to common/src/main/java/com/dfsek/terra/addons/loading/pre/exception/DependencyMissingException.java index 936c6f480..b6a81d837 100644 --- a/common/src/main/java/com/dfsek/terra/addons/loading/pre/DependencyMissingException.java +++ b/common/src/main/java/com/dfsek/terra/addons/loading/pre/exception/DependencyMissingException.java @@ -1,4 +1,4 @@ -package com.dfsek.terra.addons.loading.pre; +package com.dfsek.terra.addons.loading.pre.exception; import com.dfsek.terra.addons.loading.AddonLoadException; diff --git a/common/src/main/java/com/dfsek/terra/api/core/event/TerraEventManager.java b/common/src/main/java/com/dfsek/terra/api/core/event/TerraEventManager.java index aafa3f118..1bc3e6aa7 100644 --- a/common/src/main/java/com/dfsek/terra/api/core/event/TerraEventManager.java +++ b/common/src/main/java/com/dfsek/terra/api/core/event/TerraEventManager.java @@ -34,7 +34,11 @@ public class TerraEventManager implements EventManager { try { if(event instanceof PackEvent && !listenerHolder.global) { PackEvent packEvent = (PackEvent) event; - if(packEvent.getPack().getTemplate().getAddons().contains(listenerHolder.addon)) { + if(packEvent + .getPack() + .getTemplate() + .getAddons() + .contains(listenerHolder.addon)) { listenerHolder.method.invoke(listenerHolder.listener, event); } } else { diff --git a/common/src/main/java/com/dfsek/terra/config/pack/ConfigPackTemplate.java b/common/src/main/java/com/dfsek/terra/config/pack/ConfigPackTemplate.java index 13df2f11a..d57615148 100644 --- a/common/src/main/java/com/dfsek/terra/config/pack/ConfigPackTemplate.java +++ b/common/src/main/java/com/dfsek/terra/config/pack/ConfigPackTemplate.java @@ -8,6 +8,7 @@ import com.dfsek.terra.api.util.seeded.NoiseSeeded; import com.dfsek.terra.config.loaders.config.function.FunctionTemplate; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; @@ -22,7 +23,7 @@ public class ConfigPackTemplate implements ConfigTemplate { @Value("addons") @Default - private Set addons; + private Set addons = new HashSet<>(); @Value("variables") @Default diff --git a/common/src/main/java/com/dfsek/terra/registry/AddonRegistry.java b/common/src/main/java/com/dfsek/terra/registry/AddonRegistry.java index 892e48d87..d73799b67 100644 --- a/common/src/main/java/com/dfsek/terra/registry/AddonRegistry.java +++ b/common/src/main/java/com/dfsek/terra/registry/AddonRegistry.java @@ -1,6 +1,8 @@ package com.dfsek.terra.registry; import com.dfsek.terra.addons.addon.TerraAddon; +import com.dfsek.terra.addons.injection.InjectionException; +import com.dfsek.terra.addons.injection.Injector; import com.dfsek.terra.addons.loading.AddonClassLoader; import com.dfsek.terra.addons.loading.AddonLoadException; import com.dfsek.terra.addons.loading.pre.AddonPool; @@ -11,6 +13,8 @@ import java.io.File; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.util.logging.LogManager; +import java.util.logging.Logger; public class AddonRegistry extends TerraRegistry { private final TerraPlugin main; @@ -39,6 +43,9 @@ public class AddonRegistry extends TerraRegistry { } public boolean loadAll() { + Injector pluginInjector = new Injector<>(main); + pluginInjector.addExplicitTarget(TerraPlugin.class); + boolean valid = true; File addonsFolder = new File(main.getDataFolder(), "addons"); addonsFolder.mkdirs(); @@ -59,6 +66,16 @@ public class AddonRegistry extends TerraRegistry { Class addonClass = addon.getAddonClass(); Constructor constructor; + String logPrefix = "Terra:" + addon.getId(); + Logger addonLogger = Logger.getLogger(logPrefix); + + if(!LogManager.getLogManager().addLogger(addonLogger)) { + addonLogger = LogManager.getLogManager().getLogger(logPrefix); + } + + Injector loggerInjector = new Injector<>(addonLogger); + loggerInjector.addExplicitTarget(Logger.class); + try { constructor = addonClass.getConstructor(); } catch(NoSuchMethodException e) { @@ -67,7 +84,9 @@ public class AddonRegistry extends TerraRegistry { TerraAddon loadedAddon; try { loadedAddon = constructor.newInstance(); - } catch(InstantiationException | IllegalAccessException | InvocationTargetException e) { + pluginInjector.inject(loadedAddon); + loggerInjector.inject(loadedAddon); + } catch(InstantiationException | IllegalAccessException | InvocationTargetException | InjectionException e) { throw new AddonLoadException("Failed to load addon \" + " + addon.getId() + "\": ", e); } try {