Skip to content

Commit

Permalink
FullBlockData: forcibly prefill Spigot's internal enum cache
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Jun 17, 2022
1 parent 51880d3 commit fd40644
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 1 deletion.
2 changes: 2 additions & 0 deletions plugin/src/main/java/com/denizenscript/denizen/Denizen.java
Expand Up @@ -18,6 +18,7 @@
import com.denizenscript.denizen.tags.core.NPCTagBase;
import com.denizenscript.denizen.tags.core.ServerTagBase;
import com.denizenscript.denizen.utilities.*;
import com.denizenscript.denizen.utilities.blocks.FullBlockData;
import com.denizenscript.denizen.utilities.command.*;
import com.denizenscript.denizen.utilities.command.manager.CommandManager;
import com.denizenscript.denizen.utilities.command.manager.Injector;
Expand Down Expand Up @@ -371,6 +372,7 @@ else if (javaVersion.startsWith("17")) {
exCommand.enableFor(getCommand("ex"));
ExSustainedCommandHandler exsCommand = new ExSustainedCommandHandler();
exsCommand.enableFor(getCommand("exs"));
FullBlockData.init();
// Load script files without processing.
DenizenCore.preloadScripts();
// Load the saves.yml into memory
Expand Down
Expand Up @@ -53,7 +53,7 @@ public class InventoryScriptContainer extends ScriptContainer {
// inventory: inventory type
//
// # The title can be anything you wish. Use color tags to make colored titles.
// # Note that titles only work for some inventory types, including CHEST, DISPENSER, FURNACE, ENCHANTING, and HOPPER.
// # Note that titles only work for some inventory types, including ANVIL, CHEST, DISPENSER, FURNACE, ENCHANTING, HOPPER, WORKBENCH
// # | MOST inventory scripts should have this key!
// title: custom title
//
Expand Down
Expand Up @@ -3,22 +3,68 @@
import com.denizenscript.denizen.nms.NMSHandler;
import com.denizenscript.denizen.nms.util.jnbt.CompoundTag;
import com.denizenscript.denizen.objects.LocationTag;
import com.denizenscript.denizen.utilities.debugging.Debug;
import com.denizenscript.denizencore.flags.MapTagBasedFlagTracker;
import com.denizenscript.denizencore.objects.ObjectTag;
import com.denizenscript.denizencore.objects.core.MapTag;
import com.denizenscript.denizencore.utilities.CoreUtilities;
import com.denizenscript.denizencore.utilities.text.StringHolder;
import org.bukkit.Axis;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.*;
import org.bukkit.block.data.type.RedstoneWire;
import org.bukkit.block.data.type.Wall;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

public class FullBlockData {

public static void init() {
HashSet<Class<? extends BlockData>> classesHandled = new HashSet<>();
for (Material material : Material.values()) {
if (!material.isBlock() || material.isLegacy()) {
continue;
}
BlockData data = material.createBlockData();
if (classesHandled.add(data.getClass())) {
initBlockDataClass(data);
}
}
}

/** Trigger a bunch of pointless block data changes, to cause the enum class cache CraftBlockData.ENUM_VALUES to be filled in, thus making it probably safe for async usage. */
private static void initBlockDataClass(BlockData data) {
try {
Class<? extends BlockData> dataClass = data.getClass();
HashMap<String, Method> setMethods = new HashMap<>();
for (Method m : dataClass.getMethods()) {
if (m.getName().startsWith("set") && m.getParameterCount() == 1 && m.getReturnType() == void.class) {
setMethods.put(m.getName(), m);
}
}
for (Method m : dataClass.getMethods()) {
if (m.getName().startsWith("get") && m.getParameterCount() == 0 && m.getReturnType().isEnum()) {
Method setter = setMethods.get("set" + m.getName().substring("get".length()));
if (setter != null && setter.getParameterTypes()[0] == m.getReturnType()) {
setter.setAccessible(true);
m.setAccessible(true);
Object curVal = m.invoke(data);
setter.invoke(data, curVal);
}
}
}
}
catch (Throwable ex) {
Debug.echoError("Errored while trying to pre-load BlockData class '" + data.getClass().getName() + "'");
Debug.echoError(ex);
}
}

public FullBlockData(Block block, boolean copyFlags) {
this(block);
if (copyFlags) {
Expand Down

0 comments on commit fd40644

Please sign in to comment.