9
0
mirror of https://github.com/VolmitSoftware/Iris.git synced 2025-12-19 15:09:18 +00:00

replace IrisCustomData class with a proxy to keep full access to the base BlockData

This commit is contained in:
Julian Krings
2025-11-26 21:32:13 +01:00
parent f7a459f3bc
commit 528c97f367
4 changed files with 63 additions and 112 deletions

View File

@@ -67,7 +67,7 @@ public class HMCLeavesDataProvider extends ExternalDataProvider {
BlockData blockData = Bukkit.createBlockData(material); BlockData blockData = Bukkit.createBlockData(material);
if (IrisSettings.get().getGenerator().preventLeafDecay && blockData instanceof Leaves leaves) if (IrisSettings.get().getGenerator().preventLeafDecay && blockData instanceof Leaves leaves)
leaves.setPersistent(true); leaves.setPersistent(true);
return new IrisCustomData(blockData, ExternalDataSVC.buildState(blockId, state)); return IrisCustomData.of(blockData, ExternalDataSVC.buildState(blockId, state));
} }
@NotNull @NotNull

View File

@@ -72,7 +72,7 @@ public class MythicCrucibleDataProvider extends ExternalDataProvider {
CustomBlockItemContext blockItemContext = crucibleItem.getBlockData(); CustomBlockItemContext blockItemContext = crucibleItem.getBlockData();
FurnitureItemContext furnitureItemContext = crucibleItem.getFurnitureData(); FurnitureItemContext furnitureItemContext = crucibleItem.getFurnitureData();
if (furnitureItemContext != null) { if (furnitureItemContext != null) {
return new IrisCustomData(B.getAir(), ExternalDataSVC.buildState(blockId, state)); return IrisCustomData.of(B.getAir(), ExternalDataSVC.buildState(blockId, state));
} else if (blockItemContext != null) { } else if (blockItemContext != null) {
return blockItemContext.getBlockData(); return blockItemContext.getBlockData();
} }

View File

@@ -49,9 +49,9 @@ public class NexoDataProvider extends ExternalDataProvider {
BlockData data = NexoBlocks.blockData(blockId.key()); BlockData data = NexoBlocks.blockData(blockId.key());
if (data == null) if (data == null)
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key()); throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
return new IrisCustomData(data, blockState); return IrisCustomData.of(data, blockState);
} else if (NexoFurniture.isFurniture(blockId.key())) { } else if (NexoFurniture.isFurniture(blockId.key())) {
return new IrisCustomData(B.getAir(), blockState); return IrisCustomData.of(B.getAir(), blockState);
} }
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key()); throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());

View File

@@ -1,127 +1,78 @@
package com.volmit.iris.util.data; package com.volmit.iris.util.data;
import com.volmit.iris.core.link.Identifier; import com.volmit.iris.core.link.Identifier;
import lombok.Data; import com.volmit.iris.util.collection.KMap;
import lombok.NonNull; import lombok.NonNull;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.SoundGroup;
import org.bukkit.block.*;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.block.structure.Mirror; import org.jetbrains.annotations.ApiStatus;
import org.bukkit.block.structure.StructureRotation;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@Data import java.lang.reflect.Proxy;
public class IrisCustomData implements BlockData { import java.util.*;
private final @NonNull BlockData base;
private final @NotNull Identifier custom;
@NotNull public interface IrisCustomData extends BlockData {
@Override @NonNull BlockData getBase();
public Material getMaterial() { @NonNull Identifier getCustom();
return base.getMaterial();
static IrisCustomData of(@NotNull BlockData base, @NotNull Identifier custom) {
var clazz = base.getClass();
var loader = clazz.getClassLoader();
return (IrisCustomData) Proxy.newProxyInstance(loader, Internal.getInterfaces(loader, clazz), (proxy, method, args) ->
switch (method.getName()) {
case "getBase" -> base;
case "getCustom" -> custom;
case "merge" -> of(base.merge((BlockData) args[0]), custom);
case "clone" -> of(base.clone(), custom);
case "hashCode" -> Objects.hash(base, custom);
case "copyTo" -> throw new UnsupportedOperationException("Cannot copy from custom block data");
case "matches" -> {
if (!(args[0] instanceof IrisCustomData store))
yield false;
yield base.matches(store.getBase()) && custom.equals(store.getCustom());
}
case "equals" -> {
if (!(args[0] instanceof IrisCustomData store))
yield false;
yield store.getBase().equals(base) && store.getCustom().equals(custom);
}
default -> method.invoke(base, args);
});
} }
@NotNull @ApiStatus.Internal
@Override abstract class Internal {
public String getAsString() { private static final KMap<Class<?>, Class<?>[]> cache = new KMap<>();
return base.getAsString();
}
@NotNull private static Class<?>[] getInterfaces(ClassLoader loader, Class<?> base) {
@Override return cache.computeIfAbsent(base, k -> {
public String getAsString(boolean b) { Queue<Class<?>> queue = new LinkedList<>();
return base.getAsString(b); Set<Class<?>> set = new HashSet<>();
}
@NotNull queue.add(k);
@Override while (!queue.isEmpty()) {
public BlockData merge(@NotNull BlockData blockData) { Class<?> i = queue.poll();
return new IrisCustomData(base.merge(blockData), custom);
}
@Override if (!BlockData.class.isAssignableFrom(i))
public boolean matches(@Nullable BlockData blockData) { continue;
if (blockData instanceof IrisCustomData b)
return custom.equals(b.custom) && base.matches(b.base);
return base.matches(blockData);
}
@NotNull for (Class<?> j : i.getInterfaces()) {
@Override if (j.isSealed() || j.isHidden())
public BlockData clone() { continue;
return new IrisCustomData(base.clone(), custom);
}
@NotNull try {
@Override Class.forName(j.getName(), false, loader);
public SoundGroup getSoundGroup() { set.add(j);
return base.getSoundGroup(); } catch (ClassNotFoundException ignored) {}
} }
@Override var parent = i.getSuperclass();
public int getLightEmission() { if (parent != null)
return base.getLightEmission(); queue.add(parent);
} }
@Override set.add(IrisCustomData.class);
public boolean isOccluding() { return set.toArray(Class<?>[]::new);
return base.isOccluding(); });
} }
@Override
public boolean requiresCorrectToolForDrops() {
return base.requiresCorrectToolForDrops();
}
@Override
public boolean isPreferredTool(@NotNull ItemStack itemStack) {
return base.isPreferredTool(itemStack);
}
@NotNull
@Override
public PistonMoveReaction getPistonMoveReaction() {
return base.getPistonMoveReaction();
}
@Override
public boolean isSupported(@NotNull Block block) {
return base.isSupported(block);
}
@Override
public boolean isSupported(@NotNull Location location) {
return base.isSupported(location);
}
@Override
public boolean isFaceSturdy(@NotNull BlockFace blockFace, @NotNull BlockSupport blockSupport) {
return base.isFaceSturdy(blockFace, blockSupport);
}
@NotNull
@Override
public Material getPlacementMaterial() {
return base.getPlacementMaterial();
}
@Override
public void rotate(@NotNull StructureRotation structureRotation) {
base.rotate(structureRotation);
}
@Override
public void mirror(@NotNull Mirror mirror) {
base.mirror(mirror);
}
@NotNull
@Override
public BlockState createBlockState() {
return base.createBlockState();
} }
} }