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:
@@ -67,7 +67,7 @@ public class HMCLeavesDataProvider extends ExternalDataProvider {
|
||||
BlockData blockData = Bukkit.createBlockData(material);
|
||||
if (IrisSettings.get().getGenerator().preventLeafDecay && blockData instanceof Leaves leaves)
|
||||
leaves.setPersistent(true);
|
||||
return new IrisCustomData(blockData, ExternalDataSVC.buildState(blockId, state));
|
||||
return IrisCustomData.of(blockData, ExternalDataSVC.buildState(blockId, state));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -72,7 +72,7 @@ public class MythicCrucibleDataProvider extends ExternalDataProvider {
|
||||
CustomBlockItemContext blockItemContext = crucibleItem.getBlockData();
|
||||
FurnitureItemContext furnitureItemContext = crucibleItem.getFurnitureData();
|
||||
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) {
|
||||
return blockItemContext.getBlockData();
|
||||
}
|
||||
|
||||
@@ -49,9 +49,9 @@ public class NexoDataProvider extends ExternalDataProvider {
|
||||
BlockData data = NexoBlocks.blockData(blockId.key());
|
||||
if (data == null)
|
||||
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())) {
|
||||
return new IrisCustomData(B.getAir(), blockState);
|
||||
return IrisCustomData.of(B.getAir(), blockState);
|
||||
}
|
||||
|
||||
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||
|
||||
@@ -1,127 +1,78 @@
|
||||
package com.volmit.iris.util.data;
|
||||
|
||||
import com.volmit.iris.core.link.Identifier;
|
||||
import lombok.Data;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
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.structure.Mirror;
|
||||
import org.bukkit.block.structure.StructureRotation;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@Data
|
||||
public class IrisCustomData implements BlockData {
|
||||
private final @NonNull BlockData base;
|
||||
private final @NotNull Identifier custom;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.*;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Material getMaterial() {
|
||||
return base.getMaterial();
|
||||
public interface IrisCustomData extends BlockData {
|
||||
@NonNull BlockData getBase();
|
||||
@NonNull Identifier getCustom();
|
||||
|
||||
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
|
||||
@Override
|
||||
public String getAsString() {
|
||||
return base.getAsString();
|
||||
@ApiStatus.Internal
|
||||
abstract class Internal {
|
||||
private static final KMap<Class<?>, Class<?>[]> cache = new KMap<>();
|
||||
|
||||
private static Class<?>[] getInterfaces(ClassLoader loader, Class<?> base) {
|
||||
return cache.computeIfAbsent(base, k -> {
|
||||
Queue<Class<?>> queue = new LinkedList<>();
|
||||
Set<Class<?>> set = new HashSet<>();
|
||||
|
||||
queue.add(k);
|
||||
while (!queue.isEmpty()) {
|
||||
Class<?> i = queue.poll();
|
||||
|
||||
if (!BlockData.class.isAssignableFrom(i))
|
||||
continue;
|
||||
|
||||
for (Class<?> j : i.getInterfaces()) {
|
||||
if (j.isSealed() || j.isHidden())
|
||||
continue;
|
||||
|
||||
try {
|
||||
Class.forName(j.getName(), false, loader);
|
||||
set.add(j);
|
||||
} catch (ClassNotFoundException ignored) {}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getAsString(boolean b) {
|
||||
return base.getAsString(b);
|
||||
var parent = i.getSuperclass();
|
||||
if (parent != null)
|
||||
queue.add(parent);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public BlockData merge(@NotNull BlockData blockData) {
|
||||
return new IrisCustomData(base.merge(blockData), custom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(@Nullable BlockData blockData) {
|
||||
if (blockData instanceof IrisCustomData b)
|
||||
return custom.equals(b.custom) && base.matches(b.base);
|
||||
return base.matches(blockData);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public BlockData clone() {
|
||||
return new IrisCustomData(base.clone(), custom);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SoundGroup getSoundGroup() {
|
||||
return base.getSoundGroup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLightEmission() {
|
||||
return base.getLightEmission();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOccluding() {
|
||||
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();
|
||||
set.add(IrisCustomData.class);
|
||||
return set.toArray(Class<?>[]::new);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user