diff --git a/src/com/massivecraft/massivecore/MassiveCore.java b/src/com/massivecraft/massivecore/MassiveCore.java index 412be6f7..df25004c 100644 --- a/src/com/massivecraft/massivecore/MassiveCore.java +++ b/src/com/massivecraft/massivecore/MassiveCore.java @@ -64,10 +64,7 @@ import com.massivecraft.massivecore.engine.EngineMassiveCoreVariable; import com.massivecraft.massivecore.engine.EngineMassiveCoreWorldNameSet; import com.massivecraft.massivecore.integration.vault.IntegrationVault; import com.massivecraft.massivecore.item.DataBannerPattern; -import com.massivecraft.massivecore.item.WriterBannerPattern; -import com.massivecraft.massivecore.item.WriterFireworkEffect; import com.massivecraft.massivecore.item.WriterItemStack; -import com.massivecraft.massivecore.item.WriterPotionEffect; import com.massivecraft.massivecore.mixin.MixinActionbar; import com.massivecraft.massivecore.mixin.MixinActual; import com.massivecraft.massivecore.mixin.MixinCommand; @@ -86,6 +83,7 @@ import com.massivecraft.massivecore.mixin.MixinVisibility; import com.massivecraft.massivecore.mixin.MixinWorld; import com.massivecraft.massivecore.mson.Mson; import com.massivecraft.massivecore.mson.MsonEvent; +import com.massivecraft.massivecore.nms.NmsItemStack; import com.massivecraft.massivecore.ps.PS; import com.massivecraft.massivecore.ps.PSAdapter; import com.massivecraft.massivecore.store.ModificationPollerLocal; @@ -168,8 +166,12 @@ public class MassiveCore extends MassivePlugin ret.registerTypeAdapter(Mson.class, AdapterMson.get()); ret.registerTypeAdapter(MsonEvent.class, AdapterMsonEvent.get()); - // Items and Inventories + // ItemStack ret.registerTypeAdapter(ItemStack.class, AdapterItemStack.get()); + Class classCraftItemStack = NmsItemStack.get().classCraftItemStack; + if (classCraftItemStack != null) ret.registerTypeAdapter(classCraftItemStack, AdapterItemStack.get()); + + // Inventory ret.registerTypeAdapter(Inventory.class, AdapterInventory.get()); ret.registerTypeAdapter(PlayerInventory.class, AdapterPlayerInventory.get()); @@ -240,9 +242,6 @@ public class MassiveCore extends MassivePlugin // Writer, WriterItemStack.class, - WriterPotionEffect.class, - WriterFireworkEffect.class, - WriterBannerPattern.class, // Engine EngineMassiveCoreChestGui.class, diff --git a/src/com/massivecraft/massivecore/engine/EngineMassiveCoreSponsor.java b/src/com/massivecraft/massivecore/engine/EngineMassiveCoreSponsor.java index da8b12ed..d95577af 100644 --- a/src/com/massivecraft/massivecore/engine/EngineMassiveCoreSponsor.java +++ b/src/com/massivecraft/massivecore/engine/EngineMassiveCoreSponsor.java @@ -71,43 +71,55 @@ public class EngineMassiveCoreSponsor extends Engine } // -------------------------------------------- // - // INFORM + // ENABLED // -------------------------------------------- // - public void inform(final CommandSender sender) + public boolean isEnabled(final CommandSender sender) { - // Fail Safe - if (sender == null) return; + // If there is a sender ... + if (sender == null) return false; - // If enabled by mconf ... - if ( ! MassiveCoreMConf.get().sponsorEnabled) return; + // ... and enabled by mconf ... + if ( ! MassiveCoreMConf.get().sponsorEnabled) return false; // ... and enabled by info base ... - if ( ! MassiveCoreMSponsorInfo.get().enabled) return; + if ( ! MassiveCoreMSponsorInfo.get().enabled) return false; // ... and enabled by info time ... long now = System.currentTimeMillis(); long to = MassiveCoreMSponsorInfo.get().enabledToMillis; long left = to - now; - if (left <= 0) return; + if (left <= 0) return false; // ... and enabled by sender type ... - boolean isConsole = IdUtil.isConsole(sender); - boolean enabledByType = (isConsole ? MassiveCoreMSponsorInfo.get().consoleEnabled : MassiveCoreMSponsorInfo.get().ingameEnabled); - if ( ! enabledByType) return; + boolean enabledByType = (IdUtil.isConsole(sender) ? MassiveCoreMSponsorInfo.get().consoleEnabled : MassiveCoreMSponsorInfo.get().ingameEnabled); + if ( ! enabledByType) return false; // ... and enabled by sender operator ... - if ( ! sender.isOp()) return; + if ( ! sender.isOp()) return false; // ... and enabled by in indicator files ... for (String indicatorFileName : MassiveCoreMSponsorInfo.get().indicatorFileNames) { File indicatorFile = new File(indicatorFileName); - if (indicatorFile.exists()) return; + if (indicatorFile.exists()) return false; } - // ... then schedule inner inform. - int delayTicks = (isConsole ? MassiveCoreMSponsorInfo.get().consoleDelayTicks : MassiveCoreMSponsorInfo.get().ingameDelayTicks); + // ... then it's actually enabled. + return true; + } + + // -------------------------------------------- // + // INFORM + // -------------------------------------------- // + + public void inform(final CommandSender sender) + { + // Enabled + if ( ! this.isEnabled(sender)) return; + + // Schedule + int delayTicks = (IdUtil.isConsole(sender) ? MassiveCoreMSponsorInfo.get().consoleDelayTicks : MassiveCoreMSponsorInfo.get().ingameDelayTicks); Bukkit.getScheduler().runTaskLater(this.getPlugin(), new Runnable() { @Override @@ -120,11 +132,11 @@ public class EngineMassiveCoreSponsor extends Engine public void informInner(CommandSender sender) { - // Console? - boolean isConsole = IdUtil.isConsole(sender); + // Enabled + if ( ! this.isEnabled(sender)) return; // Messages - List msgs = (isConsole ? MassiveCoreMSponsorInfo.get().consoleMsgs : MassiveCoreMSponsorInfo.get().ingameMsgs); + List msgs = (IdUtil.isConsole(sender) ? MassiveCoreMSponsorInfo.get().consoleMsgs : MassiveCoreMSponsorInfo.get().ingameMsgs); String senderVisual = MixinDisplayName.get().getDisplayName(sender, sender); for (String msg : msgs) { diff --git a/src/com/massivecraft/massivecore/item/WriterAbstract.java b/src/com/massivecraft/massivecore/item/WriterAbstract.java index dbb5ecdc..bbdaca68 100644 --- a/src/com/massivecraft/massivecore/item/WriterAbstract.java +++ b/src/com/massivecraft/massivecore/item/WriterAbstract.java @@ -1,11 +1,13 @@ package com.massivecraft.massivecore.item; +import java.util.Arrays; import java.util.List; import com.massivecraft.massivecore.Engine; import com.massivecraft.massivecore.MassiveCoreMConf; import com.massivecraft.massivecore.collections.MassiveList; import com.massivecraft.massivecore.command.type.primitive.TypeBoolean; +import com.massivecraft.massivecore.util.MUtil; import com.massivecraft.massivecore.util.ReflectionUtil; import com.massivecraft.massivecore.util.Txt; @@ -14,53 +16,132 @@ public abstract class WriterAbstract extends Engine // -------------------------------------------- // // WRITERS // -------------------------------------------- // - // A writer may contain subwriters. + // Writer have dependencies and child writers. + + // A dependency is another writer that must be successfully activated for this writer to function. + // For that reason the dependencies are activated just after the provoke logic. + // Examples would be WriterPotionEffect and WriterFireworkEffect. + // They are implicitly required for some ItemStack field writers. + + private List> dependencyClasses = new MassiveList<>(); + public List> getDependencyClasses() { return this.dependencyClasses; } + public void addDependencyClasses(Class... dependencyClasses) { this.getDependencyClasses().addAll(Arrays.asList(dependencyClasses)); } + // This is the writer classes scheduled to be used at setup. + // We do not yet know if they are compatible with this Minecraft version. + // All, some or none of them may fail. + private List> writerClasses = new MassiveList<>(); + public List> getWriterClasses() { return this.writerClasses; } + public void addWriterClasses(Class... writerClasses) { this.getWriterClasses().addAll(Arrays.asList(writerClasses)); } + + // These are the actually functional child writers. + // This list should only contain writers that passed the provoke routine. private List> writers = new MassiveList<>(); + public List> getWriters() { return this.writers; } - public List> getWriters() + // Here is the logic to perform the dependency and child writer setup. + public void setupDependencies() { - return this.writers; + for (Class dependencyClass : this.getDependencyClasses()) + { + this.setupWriter(dependencyClass, false); + } } - - public void clearWriters() + + public void setupWriters() { - this.writers.clear(); + for (Class writerClass : this.getWriterClasses()) + { + this.setupWriter(writerClass, true); + } } - + @SuppressWarnings("unchecked") - public void addWriter(Class clazz) + public void setupWriter(Class writerClass, boolean add) { - boolean success = false; try { - Class> clazzInner = (Class>) clazz; - WriterAbstract writer = ReflectionUtil.getSingletonInstance(clazzInner); - writer.setActive(this.getActivePlugin()); - this.getWriters().add(writer); - success = true; + Class> writerClassInner = (Class>) writerClass; + WriterAbstract writer = ReflectionUtil.getSingletonInstance(writerClassInner); + + if ( ! writer.isActive()) writer.setActive(this.getActivePlugin()); + + if (add) this.getWriters().add((WriterAbstract)writer); } catch (Throwable t) { - if (MassiveCoreMConf.get().debugWriters) - { - t.printStackTrace(); - } - } - - if (MassiveCoreMConf.get().debugWriters) - { - String message = Txt.parse("%s %s", clazz.getSimpleName(), TypeBoolean.getOn().getVisual(success)); - this.getActivePlugin().log(message); + this.reportSuccess(false, writerClass.getSimpleName(), t); } } - - public void addWriters(Class... clazzs) + + public void reportSuccess(boolean success) { - for (Class clazz : clazzs) + this.reportSuccess(success, this.getClass().getSimpleName()); + } + + public void reportSuccess(boolean success, String name) + { + this.reportSuccess(success, name, null); + } + + public void reportSuccess(boolean success, String name, Throwable t) + { + if ( ! MassiveCoreMConf.get().debugWriters) return; + + // Create + List messages = new MassiveList<>(); + + // Fill + String message; + + // Main + message = Txt.parse("%s %s", name, TypeBoolean.getOn().getVisual(success)); + messages.add(message); + + // Throwable + if (t != null) { - this.addWriter(clazz); + message = Txt.parse("### %s %s", t.getClass().getSimpleName(), t.getMessage()); + messages.add(message); + for (String s : MUtil.getStackTraceStrings(Arrays.asList(t.getStackTrace()), true)) + { + message = Txt.parse("--> %s", s); + messages.add(message); + } } + + // Send + for (String s : messages) + { + this.getActivePlugin().log(s); + } + } + + // -------------------------------------------- // + // ACTIVE + // -------------------------------------------- // + // The setActive method starts out with the provoke. + // This means it can fail immediately with a runtime exception. + // If this happens it will not have been activated in any way. + + @Override + public void setActive(boolean active) + { + if (active) + { + // Provoke + this.provoke(); + + // Setup Dependencies + this.setupDependencies(); + + // Report This Success + this.reportSuccess(true); + + // Setup Writers + this.setupWriters(); + } + super.setActive(active); } // -------------------------------------------- // @@ -121,17 +202,6 @@ public abstract class WriterAbstract extends Engine return cb; } - // -------------------------------------------- // - // ACTIVE - // -------------------------------------------- // - - @Override - public void setActive(boolean active) - { - this.provoke(); - super.setActive(active); - } - // -------------------------------------------- // // PROVOKE // -------------------------------------------- // @@ -167,7 +237,7 @@ public abstract class WriterAbstract extends Engine public void write(OA oa, OB ob, boolean a2b) { - if (!this.isActive()) throw new IllegalStateException("not active " + this.getClass().getName()); + if ( ! this.isActive()) throw new IllegalStateException("not active " + this.getClass().getName()); if (oa == null) throw new NullPointerException("oa"); if (ob == null) throw new NullPointerException("ob"); diff --git a/src/com/massivecraft/massivecore/item/WriterAbstractItemStackMetaState.java b/src/com/massivecraft/massivecore/item/WriterAbstractItemStackMetaState.java index 1ee57afa..bf61b624 100644 --- a/src/com/massivecraft/massivecore/item/WriterAbstractItemStackMetaState.java +++ b/src/com/massivecraft/massivecore/item/WriterAbstractItemStackMetaState.java @@ -1,9 +1,20 @@ package com.massivecraft.massivecore.item; +import org.bukkit.Material; import org.bukkit.inventory.meta.BlockStateMeta; public abstract class WriterAbstractItemStackMetaState extends WriterAbstractItemStackMeta { + // -------------------------------------------- // + // CONSTRUCT + // -------------------------------------------- // + + public WriterAbstractItemStackMetaState() + { + // For the initial provoke to pass we must set a Material with a BlockStateMeta. + this.setMaterial(Material.SHIELD); + } + // -------------------------------------------- // // CREATE // -------------------------------------------- // diff --git a/src/com/massivecraft/massivecore/item/WriterBannerPattern.java b/src/com/massivecraft/massivecore/item/WriterBannerPattern.java index d263110c..00cd039b 100644 --- a/src/com/massivecraft/massivecore/item/WriterBannerPattern.java +++ b/src/com/massivecraft/massivecore/item/WriterBannerPattern.java @@ -8,22 +8,12 @@ public class WriterBannerPattern extends WriterAbstractBannerPattern T invokeMethod(Method method, Object target, Object argument) + { + return invokeMethod(method, target, new Object[]{argument}); + } + @SuppressWarnings("unchecked") public static T invokeMethod(Method method, Object target) { @@ -160,6 +165,11 @@ public class ReflectionUtil } } + public static T invokeConstructor(Constructor constructor, Object argument) + { + return invokeConstructor(constructor, new Object[]{argument}); + } + @SuppressWarnings("unchecked") public static T invokeConstructor(Constructor constructor) {