diff --git a/Core/src/main/java/com/craftaro/core/hooks/BaseHookRegistry.java b/Core/src/main/java/com/craftaro/core/hooks/BaseHookRegistry.java index 7d65aa92..95e45db8 100644 --- a/Core/src/main/java/com/craftaro/core/hooks/BaseHookRegistry.java +++ b/Core/src/main/java/com/craftaro/core/hooks/BaseHookRegistry.java @@ -15,6 +15,9 @@ import java.util.stream.Collectors; /** * This hook registry makes use of priorities to automatically activate the highest priority hook that is available if no hook has been activated programmatically. */ +// TODO: Allow multiple hooks to be active at the same time (useful for using multiple specific Eco/Protection/... hooks/plugins) +// TODO: Allow specifying a hook-name-string as "prefered" to be auto-active (maybe String[] or comma-separated String?) +// (null means use priority, otherwise try to activate the hook with the given name first) public abstract class BaseHookRegistry extends HookRegistry { private final Plugin plugin; diff --git a/Core/src/main/java/com/craftaro/core/hooks/hologram/HologramHookRegistry.java b/Core/src/main/java/com/craftaro/core/hooks/hologram/HologramHookRegistry.java index e1234f24..0b4de76f 100644 --- a/Core/src/main/java/com/craftaro/core/hooks/hologram/HologramHookRegistry.java +++ b/Core/src/main/java/com/craftaro/core/hooks/hologram/HologramHookRegistry.java @@ -2,7 +2,9 @@ package com.craftaro.core.hooks.hologram; import com.craftaro.core.hooks.BaseHookRegistry; import com.craftaro.core.hooks.HookPriority; +import com.craftaro.core.hooks.hologram.adapter.CmiHologramHook; import com.craftaro.core.hooks.hologram.adapter.DecentHologramsHook; +import com.craftaro.core.hooks.hologram.adapter.SainttxHologramsHook; import org.bukkit.plugin.Plugin; public class HologramHookRegistry extends BaseHookRegistry { @@ -13,5 +15,7 @@ public class HologramHookRegistry extends BaseHookRegistry { @Override public void registerDefaultHooks() { register(new DecentHologramsHook(), HookPriority.HIGH); + register(new SainttxHologramsHook(), HookPriority.NORMAL); + register(new CmiHologramHook(), HookPriority.LOW); } } diff --git a/Core/src/main/java/com/craftaro/core/hooks/hologram/adapter/CmiHologramHook.java b/Core/src/main/java/com/craftaro/core/hooks/hologram/adapter/CmiHologramHook.java new file mode 100644 index 00000000..91894a14 --- /dev/null +++ b/Core/src/main/java/com/craftaro/core/hooks/hologram/adapter/CmiHologramHook.java @@ -0,0 +1,113 @@ +package com.craftaro.core.hooks.hologram.adapter; + +import com.Zrips.CMI.CMI; +import com.Zrips.CMI.Modules.Holograms.CMIHologram; +import com.Zrips.CMI.Modules.Holograms.HologramManager; +import com.craftaro.core.hooks.hologram.HologramHook; +import org.bukkit.Location; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class CmiHologramHook extends HologramHook { + private static final String CMI_PLUGIN_NAME = "CMI"; + + private final ArrayList ourHologramIds = new ArrayList<>(0); + private String hologramNamePrefix; + + private HologramManager cmiHologramManager; + + @Override + public String getName() { + return CMI_PLUGIN_NAME; + } + + @Override + public @NotNull String[] getPluginDependencies() { + return new String[] {CMI_PLUGIN_NAME}; + } + + @Override + public void activate(Plugin plugin) { + this.hologramNamePrefix = plugin.getClass().getName() + "-"; + this.cmiHologramManager = JavaPlugin.getPlugin(CMI.class).getHologramManager(); + } + + @Override + public void deactivate() { + removeAll(); + this.hologramNamePrefix = null; + this.cmiHologramManager = null; + } + + @Override + public boolean exists(@NotNull String id) { + return this.cmiHologramManager.getByName(getHologramName(id)) != null; + } + + @Override + public void create(@NotNull String id, @NotNull Location location, @NotNull List lines) { + if (exists(id)) { + throw new IllegalStateException("Cannot create hologram that already exists: " + getHologramName(id)); + } + + CMIHologram hologram = new CMIHologram(getHologramName(id), getNormalizedLocation(location)); + hologram.setLines(lines); + this.cmiHologramManager.addHologram(hologram); + hologram.update(); + + this.ourHologramIds.add(id); + } + + @Override + public void update(@NotNull String id, @NotNull List lines) { + CMIHologram hologram = this.cmiHologramManager.getByName(getHologramName(id)); + if (hologram == null) { + throw new IllegalStateException("Cannot update hologram that does not exist: " + getHologramName(id)); + } + + hologram.setLines(lines); + hologram.update(); + } + + @Override + public void updateBulk(@NotNull Map> hologramData) { + for (Map.Entry> entry : hologramData.entrySet()) { + update(entry.getKey(), entry.getValue()); + } + } + + @Override + public void remove(@Nullable String id) { + CMIHologram hologram = this.cmiHologramManager.getByName(getHologramName(id)); + if (hologram != null) { + this.cmiHologramManager.removeHolo(hologram); + } + + this.ourHologramIds.remove(id); + } + + @Override + public void removeAll() { + for (String id : this.ourHologramIds) { + CMIHologram hologram = this.cmiHologramManager.getByName(getHologramName(id)); + if (hologram != null) { + this.cmiHologramManager.removeHolo(hologram); + } + } + this.ourHologramIds.clear(); + this.ourHologramIds.trimToSize(); + } + + private String getHologramName(String id) { + if (this.hologramNamePrefix == null) { + throw new IllegalStateException("Hook has not been activated yet"); + } + return this.hologramNamePrefix + id; + } +} diff --git a/Core/src/main/java/com/craftaro/core/hooks/hologram/adapter/SainttxHologramsHook.java b/Core/src/main/java/com/craftaro/core/hooks/hologram/adapter/SainttxHologramsHook.java new file mode 100644 index 00000000..0c0d25bd --- /dev/null +++ b/Core/src/main/java/com/craftaro/core/hooks/hologram/adapter/SainttxHologramsHook.java @@ -0,0 +1,135 @@ +package com.craftaro.core.hooks.hologram.adapter; + +import com.craftaro.core.hooks.hologram.HologramHook; +import com.sainttx.holograms.api.Hologram; +import com.sainttx.holograms.api.HologramManager; +import com.sainttx.holograms.api.HologramPlugin; +import com.sainttx.holograms.api.line.HologramLine; +import com.sainttx.holograms.api.line.TextLine; +import org.bukkit.Location; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class SainttxHologramsHook extends HologramHook { + private final ArrayList ourHologramIds = new ArrayList<>(0); + private String hologramNamePrefix; + private HologramManager sainttxHologramManager; + + @Override + public String getName() { + return "SainttxHolograms"; + } + + @Override + public @NotNull String[] getPluginDependencies() { + return new String[] {"Holograms"}; + } + + @Override + public void activate(Plugin plugin) { + this.hologramNamePrefix = plugin.getClass().getName() + "-"; + this.sainttxHologramManager = JavaPlugin.getPlugin(HologramPlugin.class).getHologramManager(); + } + + @Override + public void deactivate() { + removeAll(); + this.hologramNamePrefix = null; + this.sainttxHologramManager = null; + } + + @Override + public boolean exists(@NotNull String id) { + return this.sainttxHologramManager.getHologram(getHologramName(id)) != null; + } + + @Override + public void create(@NotNull String id, @NotNull Location location, @NotNull List lines) { + if (exists(id)) { + throw new IllegalStateException("Cannot create hologram that already exists: " + getHologramName(id)); + } + + Hologram hologram = new Hologram(getHologramName(id), getNormalizedLocation(location), false); + for (String line : lines) { + hologram.addLine(createByReflection(hologram, line)); + } + this.sainttxHologramManager.addActiveHologram(hologram); + + this.ourHologramIds.add(id); + } + + @Override + public void update(@NotNull String id, @NotNull List lines) { + Hologram hologram = this.sainttxHologramManager.getHologram(getHologramName(id)); + if (hologram == null) { + throw new IllegalStateException("Cannot update hologram that does not exist: " + getHologramName(id)); + } + + for (HologramLine hologramLine : hologram.getLines().toArray(new HologramLine[0])) { + hologram.removeLine(hologramLine); + } + for (String line : lines) { + hologram.addLine(new TextLine(hologram, line)); + } + } + + @Override + public void updateBulk(@NotNull Map> hologramData) { + for (Map.Entry> entry : hologramData.entrySet()) { + update(entry.getKey(), entry.getValue()); + } + } + + @Override + public void remove(@Nullable String id) { + removeSainttxHologramIfExists(getHologramName(id)); + this.ourHologramIds.remove(id); + } + + @Override + public void removeAll() { + for (String id : this.ourHologramIds) { + removeSainttxHologramIfExists(getHologramName(id)); + } + this.ourHologramIds.clear(); + this.ourHologramIds.trimToSize(); + } + + @Override + protected double getYOffset() { + return 0.5; + } + + private String getHologramName(String id) { + if (this.hologramNamePrefix == null) { + throw new IllegalStateException("Hook has not been activated yet"); + } + return this.hologramNamePrefix + id; + } + + private void removeSainttxHologramIfExists(String name) { + Hologram hologram = this.sainttxHologramManager.getHologram(name); + if (hologram != null) { + this.sainttxHologramManager.deleteHologram(hologram); + } + } + + // FIXME: This is a workaround for the compile/JVM which causes calls to the constructor to + // loading the HologramLine when loading this class, which causes a NoClassDefFoundError + // when the HologramLine class is not available at runtime. + // Des ist basically ein Design-Problem des Hook-Interface, welches Hook-Infos/-Meta und Hook-Implementierung + // in einer Klasse vereint. Best-Case wäre dass die Hook-Implementierung nie geladen wird, bis sie tatsäclich gebraucht wird. + private static HologramLine createByReflection(Hologram hologram, String line) { + try { + return TextLine.class.getConstructor(Hologram.class, String.class).newInstance(hologram, line); + } catch (ReflectiveOperationException ex) { + throw new RuntimeException(ex); + } + } +}