Merge branch 'v3.4.2' into iris4

# Conflicts:
#	core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java
#	core/src/main/java/com/volmit/iris/core/safeguard/ModesSFG.java
#	core/src/main/java/com/volmit/iris/core/service/WandSVC.java
#	core/src/main/java/com/volmit/iris/engine/framework/Engine.java
#	core/src/main/java/com/volmit/iris/engine/object/TileBanner.java
#	core/src/main/java/com/volmit/iris/engine/object/TileData.java
#	core/src/main/java/com/volmit/iris/engine/object/TileSign.java
#	core/src/main/java/com/volmit/iris/engine/object/TileSpawner.java
#	core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java
#	core/src/main/java/com/volmit/iris/util/matter/TileWrapper.java
#	nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java
#	nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java
#	nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java
#	nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java
#	nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java
#	nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java
#	nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java
#	nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java
This commit is contained in:
Julian Krings
2024-08-14 21:53:13 +02:00
32 changed files with 912 additions and 809 deletions
@@ -35,9 +35,14 @@ import java.util.stream.Collectors;
import com.google.gson.JsonNull;
import com.volmit.iris.core.nms.container.BiomeColor;
import com.volmit.iris.util.scheduling.J;
import net.minecraft.nbt.*;
import net.minecraft.nbt.Tag;
import net.minecraft.server.commands.data.BlockDataAccessor;
import com.volmit.iris.core.nms.container.IPackRepository;
import com.volmit.iris.util.io.IO;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.EntityBlock;
import com.google.common.base.Preconditions;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
@@ -70,6 +75,8 @@ import org.bukkit.craftbukkit.v1_19_R1.CraftChunk;
import org.bukkit.craftbukkit.v1_19_R1.CraftServer;
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R1.block.CraftBlock;
import org.bukkit.craftbukkit.v1_19_R1.block.CraftBlockState;
import org.bukkit.craftbukkit.v1_19_R1.block.CraftBlockStates;
import org.bukkit.craftbukkit.v1_19_R1.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftDolphin;
import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack;
@@ -79,6 +86,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.generator.BiomeProvider;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
@@ -103,8 +111,6 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.TagParser;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.EntityType;
@@ -178,50 +184,57 @@ public class NMSBinding implements INMSBinding {
return type.getDeclaredClasses()[ordinal];
}
@Override
public boolean hasTile(Material material) {
return !CraftBlockState.class.equals(CraftBlockStates.getBlockStateType(material));
}
@Override
public boolean hasTile(Location l) {
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
}
@Override
public CompoundTag serializeTile(Location location) {
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true);
@SuppressWarnings("unchecked")
public KMap<String, Object> serializeTile(Location location) {
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), false);
if (e == null) {
return null;
}
net.minecraft.nbt.CompoundTag tag = e.saveWithFullMetadata();
return convert(tag);
net.minecraft.nbt.CompoundTag tag = e.saveWithoutMetadata();
return (KMap<String, Object>) convertFromTag(tag, 0, 64);
}
private CompoundTag convert(net.minecraft.nbt.CompoundTag tag) {
try {
ByteArrayOutputStream boas = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(boas);
tag.write(dos);
dos.close();
return (CompoundTag) NBTUtil.read(new ByteArrayInputStream(boas.toByteArray()), false).getTag();
} catch (Throwable ex) {
ex.printStackTrace();
@Contract(value = "null, _, _ -> null", pure = true)
private Object convertFromTag(net.minecraft.nbt.Tag tag, int depth, int maxDepth) {
if (tag == null || depth > maxDepth) return null;
if (tag instanceof CollectionTag<?> collection) {
KList<Object> list = new KList<>();
for (Object i : collection) {
if (i instanceof net.minecraft.nbt.Tag t)
list.add(convertFromTag(t, depth + 1, maxDepth));
else list.add(i);
}
return list;
}
if (tag instanceof net.minecraft.nbt.CompoundTag compound) {
KMap<String, Object> map = new KMap<>();
return null;
}
private net.minecraft.nbt.CompoundTag convert(CompoundTag tag) {
try {
ByteArrayOutputStream boas = new ByteArrayOutputStream();
NBTUtil.write(tag, boas, false);
DataInputStream din = new DataInputStream(new ByteArrayInputStream(boas.toByteArray()));
net.minecraft.nbt.CompoundTag c = NbtIo.read(din);
din.close();
return c;
} catch (Throwable e) {
e.printStackTrace();
for (String key : compound.getAllKeys()) {
var child = compound.get(key);
if (child == null) continue;
var value = convertFromTag(child, depth + 1, maxDepth);
if (value == null) continue;
map.put(key, value);
}
return map;
}
return null;
if (tag instanceof NumericTag numeric)
return numeric.getAsNumber();
return tag.getAsString();
}
private RegistryAccess getRegistryAccess(World world) {
@@ -236,8 +249,52 @@ public class NMSBinding implements INMSBinding {
}
@Override
public void deserializeTile(CompoundTag c, Location pos) {
((CraftWorld) pos.getWorld()).getHandle().getChunkAt(new BlockPos(pos.getBlockX(), 0, pos.getBlockZ())).setBlockEntityNbt(convert(c));
public void deserializeTile(KMap<String, Object> map, Location pos) {
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64);
var level = ((CraftWorld) pos.getWorld()).getHandle();
var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
J.s(() -> merge(level, blockPos, tag));
}
private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) {
var blockEntity = level.getBlockEntity(blockPos);
if (blockEntity == null) {
Iris.warn("[NMS] BlockEntity not found at " + blockPos);
var state = level.getBlockState(blockPos);
if (!state.hasBlockEntity())
return;
blockEntity = ((EntityBlock) state.getBlock())
.newBlockEntity(blockPos, state);
}
var accessor = new BlockDataAccessor(blockEntity, blockPos);
accessor.setData(tag.merge(accessor.getData()));
}
private Tag convertToTag(Object object, int depth, int maxDepth) {
if (object == null || depth > maxDepth) return EndTag.INSTANCE;
if (object instanceof Map<?,?> map) {
var tag = new net.minecraft.nbt.CompoundTag();
for (var i : map.entrySet()) {
tag.put(i.getKey().toString(), convertToTag(i.getValue(), depth + 1, maxDepth));
}
return tag;
}
if (object instanceof List<?> list) {
var tag = new net.minecraft.nbt.ListTag();
for (var i : list) {
tag.add(convertToTag(i, depth + 1, maxDepth));
}
return tag;
}
if (object instanceof Byte number) return ByteTag.valueOf(number);
if (object instanceof Short number) return ShortTag.valueOf(number);
if (object instanceof Integer number) return IntTag.valueOf(number);
if (object instanceof Long number) return LongTag.valueOf(number);
if (object instanceof Float number) return FloatTag.valueOf(number);
if (object instanceof Double number) return DoubleTag.valueOf(number);
if (object instanceof String string) return StringTag.valueOf(string);
return EndTag.INSTANCE;
}
@Override
@@ -27,6 +27,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
@@ -37,7 +38,12 @@ import com.google.gson.JsonNull;
import com.volmit.iris.core.nms.container.BiomeColor;
import com.volmit.iris.core.nms.container.IPackRepository;
import com.volmit.iris.util.io.IO;
import com.volmit.iris.util.scheduling.J;
import net.minecraft.nbt.*;
import net.minecraft.nbt.Tag;
import net.minecraft.server.commands.data.BlockDataAccessor;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.EntityBlock;
import com.google.common.base.Preconditions;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
@@ -70,6 +76,8 @@ import org.bukkit.craftbukkit.v1_19_R2.CraftChunk;
import org.bukkit.craftbukkit.v1_19_R2.CraftServer;
import org.bukkit.craftbukkit.v1_19_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R2.block.CraftBlock;
import org.bukkit.craftbukkit.v1_19_R2.block.CraftBlockState;
import org.bukkit.craftbukkit.v1_19_R2.block.CraftBlockStates;
import org.bukkit.craftbukkit.v1_19_R2.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftDolphin;
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack;
@@ -79,6 +87,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.generator.BiomeProvider;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
@@ -104,8 +113,6 @@ import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.TagParser;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.EntityType;
@@ -179,50 +186,57 @@ public class NMSBinding implements INMSBinding {
return type.getDeclaredClasses()[ordinal];
}
@Override
public boolean hasTile(Material material) {
return !CraftBlockState.class.equals(CraftBlockStates.getBlockStateType(material));
}
@Override
public boolean hasTile(Location l) {
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
}
@Override
public CompoundTag serializeTile(Location location) {
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true);
@SuppressWarnings("unchecked")
public KMap<String, Object> serializeTile(Location location) {
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), false);
if (e == null) {
return null;
}
net.minecraft.nbt.CompoundTag tag = e.saveWithFullMetadata();
return convert(tag);
net.minecraft.nbt.CompoundTag tag = e.saveWithoutMetadata();
return (KMap<String, Object>) convertFromTag(tag, 0, 64);
}
private CompoundTag convert(net.minecraft.nbt.CompoundTag tag) {
try {
ByteArrayOutputStream boas = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(boas);
tag.write(dos);
dos.close();
return (CompoundTag) NBTUtil.read(new ByteArrayInputStream(boas.toByteArray()), false).getTag();
} catch (Throwable ex) {
ex.printStackTrace();
@Contract(value = "null, _, _ -> null", pure = true)
private Object convertFromTag(net.minecraft.nbt.Tag tag, int depth, int maxDepth) {
if (tag == null || depth > maxDepth) return null;
if (tag instanceof CollectionTag<?> collection) {
KList<Object> list = new KList<>();
for (Object i : collection) {
if (i instanceof net.minecraft.nbt.Tag t)
list.add(convertFromTag(t, depth + 1, maxDepth));
else list.add(i);
}
return list;
}
if (tag instanceof net.minecraft.nbt.CompoundTag compound) {
KMap<String, Object> map = new KMap<>();
return null;
}
private net.minecraft.nbt.CompoundTag convert(CompoundTag tag) {
try {
ByteArrayOutputStream boas = new ByteArrayOutputStream();
NBTUtil.write(tag, boas, false);
DataInputStream din = new DataInputStream(new ByteArrayInputStream(boas.toByteArray()));
net.minecraft.nbt.CompoundTag c = NbtIo.read(din);
din.close();
return c;
} catch (Throwable e) {
e.printStackTrace();
for (String key : compound.getAllKeys()) {
var child = compound.get(key);
if (child == null) continue;
var value = convertFromTag(child, depth + 1, maxDepth);
if (value == null) continue;
map.put(key, value);
}
return map;
}
return null;
if (tag instanceof NumericTag numeric)
return numeric.getAsNumber();
return tag.getAsString();
}
private RegistryAccess getRegistryAccess(World world) {
@@ -237,8 +251,52 @@ public class NMSBinding implements INMSBinding {
}
@Override
public void deserializeTile(CompoundTag c, Location pos) {
((CraftWorld) pos.getWorld()).getHandle().getChunkAt(new BlockPos(pos.getBlockX(), 0, pos.getBlockZ())).setBlockEntityNbt(convert(c));
public void deserializeTile(KMap<String, Object> map, Location pos) {
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64);
var level = ((CraftWorld) pos.getWorld()).getHandle();
var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
J.s(() -> merge(level, blockPos, tag));
}
private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) {
var blockEntity = level.getBlockEntity(blockPos);
if (blockEntity == null) {
Iris.warn("[NMS] BlockEntity not found at " + blockPos);
var state = level.getBlockState(blockPos);
if (!state.hasBlockEntity())
return;
blockEntity = ((EntityBlock) state.getBlock())
.newBlockEntity(blockPos, state);
}
var accessor = new BlockDataAccessor(blockEntity, blockPos);
accessor.setData(tag.merge(accessor.getData()));
}
private Tag convertToTag(Object object, int depth, int maxDepth) {
if (object == null || depth > maxDepth) return EndTag.INSTANCE;
if (object instanceof Map<?,?> map) {
var tag = new net.minecraft.nbt.CompoundTag();
for (var i : map.entrySet()) {
tag.put(i.getKey().toString(), convertToTag(i.getValue(), depth + 1, maxDepth));
}
return tag;
}
if (object instanceof List<?> list) {
var tag = new net.minecraft.nbt.ListTag();
for (var i : list) {
tag.add(convertToTag(i, depth + 1, maxDepth));
}
return tag;
}
if (object instanceof Byte number) return ByteTag.valueOf(number);
if (object instanceof Short number) return ShortTag.valueOf(number);
if (object instanceof Integer number) return IntTag.valueOf(number);
if (object instanceof Long number) return LongTag.valueOf(number);
if (object instanceof Float number) return FloatTag.valueOf(number);
if (object instanceof Double number) return DoubleTag.valueOf(number);
if (object instanceof String string) return StringTag.valueOf(string);
return EndTag.INSTANCE;
}
@Override
@@ -35,9 +35,14 @@ import java.util.stream.Collectors;
import com.google.gson.JsonNull;
import com.volmit.iris.core.nms.container.BiomeColor;
import com.volmit.iris.util.scheduling.J;
import net.minecraft.nbt.*;
import net.minecraft.nbt.Tag;
import net.minecraft.server.commands.data.BlockDataAccessor;
import com.volmit.iris.core.nms.container.IPackRepository;
import com.volmit.iris.util.io.IO;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.EntityBlock;
import com.google.common.base.Preconditions;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
@@ -70,6 +75,8 @@ import org.bukkit.craftbukkit.v1_19_R3.CraftChunk;
import org.bukkit.craftbukkit.v1_19_R3.CraftServer;
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R3.block.CraftBlock;
import org.bukkit.craftbukkit.v1_19_R3.block.CraftBlockState;
import org.bukkit.craftbukkit.v1_19_R3.block.CraftBlockStates;
import org.bukkit.craftbukkit.v1_19_R3.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftDolphin;
import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack;
@@ -79,6 +86,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.generator.BiomeProvider;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
@@ -104,8 +112,6 @@ import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.TagParser;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.EntityType;
@@ -180,50 +186,57 @@ public class NMSBinding implements INMSBinding {
return type.getDeclaredClasses()[ordinal];
}
@Override
public boolean hasTile(Material material) {
return !CraftBlockState.class.equals(CraftBlockStates.getBlockStateType(material));
}
@Override
public boolean hasTile(Location l) {
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
}
@Override
public CompoundTag serializeTile(Location location) {
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true);
@SuppressWarnings("unchecked")
public KMap<String, Object> serializeTile(Location location) {
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), false);
if (e == null) {
return null;
}
net.minecraft.nbt.CompoundTag tag = e.saveWithFullMetadata();
return convert(tag);
net.minecraft.nbt.CompoundTag tag = e.saveWithoutMetadata();
return (KMap<String, Object>) convertFromTag(tag, 0, 64);
}
private CompoundTag convert(net.minecraft.nbt.CompoundTag tag) {
try {
ByteArrayOutputStream boas = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(boas);
tag.write(dos);
dos.close();
return (CompoundTag) NBTUtil.read(new ByteArrayInputStream(boas.toByteArray()), false).getTag();
} catch (Throwable ex) {
ex.printStackTrace();
@Contract(value = "null, _, _ -> null", pure = true)
private Object convertFromTag(net.minecraft.nbt.Tag tag, int depth, int maxDepth) {
if (tag == null || depth > maxDepth) return null;
if (tag instanceof CollectionTag<?> collection) {
KList<Object> list = new KList<>();
for (Object i : collection) {
if (i instanceof net.minecraft.nbt.Tag t)
list.add(convertFromTag(t, depth + 1, maxDepth));
else list.add(i);
}
return list;
}
if (tag instanceof net.minecraft.nbt.CompoundTag compound) {
KMap<String, Object> map = new KMap<>();
return null;
}
private net.minecraft.nbt.CompoundTag convert(CompoundTag tag) {
try {
ByteArrayOutputStream boas = new ByteArrayOutputStream();
NBTUtil.write(tag, boas, false);
DataInputStream din = new DataInputStream(new ByteArrayInputStream(boas.toByteArray()));
net.minecraft.nbt.CompoundTag c = NbtIo.read(din);
din.close();
return c;
} catch (Throwable e) {
e.printStackTrace();
for (String key : compound.getAllKeys()) {
var child = compound.get(key);
if (child == null) continue;
var value = convertFromTag(child, depth + 1, maxDepth);
if (value == null) continue;
map.put(key, value);
}
return map;
}
return null;
if (tag instanceof NumericTag numeric)
return numeric.getAsNumber();
return tag.getAsString();
}
private RegistryAccess getRegistryAccess(World world) {
@@ -238,8 +251,52 @@ public class NMSBinding implements INMSBinding {
}
@Override
public void deserializeTile(CompoundTag c, Location pos) {
((CraftWorld) pos.getWorld()).getHandle().getChunkAt(new BlockPos(pos.getBlockX(), 0, pos.getBlockZ())).setBlockEntityNbt(convert(c));
public void deserializeTile(KMap<String, Object> map, Location pos) {
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64);
var level = ((CraftWorld) pos.getWorld()).getHandle();
var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
J.s(() -> merge(level, blockPos, tag));
}
private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) {
var blockEntity = level.getBlockEntity(blockPos);
if (blockEntity == null) {
Iris.warn("[NMS] BlockEntity not found at " + blockPos);
var state = level.getBlockState(blockPos);
if (!state.hasBlockEntity())
return;
blockEntity = ((EntityBlock) state.getBlock())
.newBlockEntity(blockPos, state);
}
var accessor = new BlockDataAccessor(blockEntity, blockPos);
accessor.setData(tag.merge(accessor.getData()));
}
private Tag convertToTag(Object object, int depth, int maxDepth) {
if (object == null || depth > maxDepth) return EndTag.INSTANCE;
if (object instanceof Map<?,?> map) {
var tag = new net.minecraft.nbt.CompoundTag();
for (var i : map.entrySet()) {
tag.put(i.getKey().toString(), convertToTag(i.getValue(), depth + 1, maxDepth));
}
return tag;
}
if (object instanceof List<?> list) {
var tag = new net.minecraft.nbt.ListTag();
for (var i : list) {
tag.add(convertToTag(i, depth + 1, maxDepth));
}
return tag;
}
if (object instanceof Byte number) return ByteTag.valueOf(number);
if (object instanceof Short number) return ShortTag.valueOf(number);
if (object instanceof Integer number) return IntTag.valueOf(number);
if (object instanceof Long number) return LongTag.valueOf(number);
if (object instanceof Float number) return FloatTag.valueOf(number);
if (object instanceof Double number) return DoubleTag.valueOf(number);
if (object instanceof String string) return StringTag.valueOf(string);
return EndTag.INSTANCE;
}
@Override
@@ -48,6 +48,7 @@ import com.volmit.iris.util.nbt.io.NBTUtil;
import com.volmit.iris.util.nbt.mca.NBTWorld;
import com.volmit.iris.util.nbt.mca.palette.*;
import com.volmit.iris.util.nbt.tag.CompoundTag;
import com.volmit.iris.util.scheduling.J;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
import net.bytebuddy.ByteBuddy;
@@ -60,11 +61,12 @@ import net.minecraft.core.MappedRegistry;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.TagParser;
import net.minecraft.nbt.*;
import net.minecraft.nbt.Tag;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.commands.data.BlockDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.level.LevelReader;
@@ -74,6 +76,7 @@ import net.minecraft.world.RandomSequences;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkAccess;
@@ -91,6 +94,8 @@ import org.bukkit.craftbukkit.v1_20_R1.CraftChunk;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_20_R1.block.CraftBlock;
import org.bukkit.craftbukkit.v1_20_R1.block.CraftBlockState;
import org.bukkit.craftbukkit.v1_20_R1.block.CraftBlockStates;
import org.bukkit.craftbukkit.v1_20_R1.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftDolphin;
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
@@ -100,6 +105,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.generator.BiomeProvider;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import sun.misc.Unsafe;
@@ -182,50 +188,57 @@ public class NMSBinding implements INMSBinding {
return type.getDeclaredClasses()[ordinal];
}
@Override
public boolean hasTile(Material material) {
return !CraftBlockState.class.equals(CraftBlockStates.getBlockStateType(material));
}
@Override
public boolean hasTile(Location l) {
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
}
@Override
public CompoundTag serializeTile(Location location) {
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true);
@SuppressWarnings("unchecked")
public KMap<String, Object> serializeTile(Location location) {
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), false);
if (e == null) {
return null;
}
net.minecraft.nbt.CompoundTag tag = e.saveWithFullMetadata();
return convert(tag);
net.minecraft.nbt.CompoundTag tag = e.saveWithoutMetadata();
return (KMap<String, Object>) convertFromTag(tag, 0, 64);
}
private CompoundTag convert(net.minecraft.nbt.CompoundTag tag) {
try {
ByteArrayOutputStream boas = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(boas);
tag.write(dos);
dos.close();
return (CompoundTag) NBTUtil.read(new ByteArrayInputStream(boas.toByteArray()), false).getTag();
} catch (Throwable ex) {
ex.printStackTrace();
@Contract(value = "null, _, _ -> null", pure = true)
private Object convertFromTag(net.minecraft.nbt.Tag tag, int depth, int maxDepth) {
if (tag == null || depth > maxDepth) return null;
if (tag instanceof CollectionTag<?> collection) {
KList<Object> list = new KList<>();
for (Object i : collection) {
if (i instanceof net.minecraft.nbt.Tag t)
list.add(convertFromTag(t, depth + 1, maxDepth));
else list.add(i);
}
return list;
}
if (tag instanceof net.minecraft.nbt.CompoundTag compound) {
KMap<String, Object> map = new KMap<>();
return null;
}
private net.minecraft.nbt.CompoundTag convert(CompoundTag tag) {
try {
ByteArrayOutputStream boas = new ByteArrayOutputStream();
NBTUtil.write(tag, boas, false);
DataInputStream din = new DataInputStream(new ByteArrayInputStream(boas.toByteArray()));
net.minecraft.nbt.CompoundTag c = NbtIo.read(din);
din.close();
return c;
} catch (Throwable e) {
e.printStackTrace();
for (String key : compound.getAllKeys()) {
var child = compound.get(key);
if (child == null) continue;
var value = convertFromTag(child, depth + 1, maxDepth);
if (value == null) continue;
map.put(key, value);
}
return map;
}
return null;
if (tag instanceof NumericTag numeric)
return numeric.getAsNumber();
return tag.getAsString();
}
private RegistryAccess getRegistryAccess(World world) {
@@ -240,8 +253,52 @@ public class NMSBinding implements INMSBinding {
}
@Override
public void deserializeTile(CompoundTag c, Location pos) {
((CraftWorld) pos.getWorld()).getHandle().getChunkAt(new BlockPos(pos.getBlockX(), 0, pos.getBlockZ())).setBlockEntityNbt(convert(c));
public void deserializeTile(KMap<String, Object> map, Location pos) {
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64);
var level = ((CraftWorld) pos.getWorld()).getHandle();
var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
J.s(() -> merge(level, blockPos, tag));
}
private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) {
var blockEntity = level.getBlockEntity(blockPos);
if (blockEntity == null) {
Iris.warn("[NMS] BlockEntity not found at " + blockPos);
var state = level.getBlockState(blockPos);
if (!state.hasBlockEntity())
return;
blockEntity = ((EntityBlock) state.getBlock())
.newBlockEntity(blockPos, state);
}
var accessor = new BlockDataAccessor(blockEntity, blockPos);
accessor.setData(tag.merge(accessor.getData()));
}
private Tag convertToTag(Object object, int depth, int maxDepth) {
if (object == null || depth > maxDepth) return EndTag.INSTANCE;
if (object instanceof Map<?,?> map) {
var tag = new net.minecraft.nbt.CompoundTag();
for (var i : map.entrySet()) {
tag.put(i.getKey().toString(), convertToTag(i.getValue(), depth + 1, maxDepth));
}
return tag;
}
if (object instanceof List<?> list) {
var tag = new net.minecraft.nbt.ListTag();
for (var i : list) {
tag.add(convertToTag(i, depth + 1, maxDepth));
}
return tag;
}
if (object instanceof Byte number) return ByteTag.valueOf(number);
if (object instanceof Short number) return ShortTag.valueOf(number);
if (object instanceof Integer number) return IntTag.valueOf(number);
if (object instanceof Long number) return LongTag.valueOf(number);
if (object instanceof Float number) return FloatTag.valueOf(number);
if (object instanceof Double number) return DoubleTag.valueOf(number);
if (object instanceof String string) return StringTag.valueOf(string);
return EndTag.INSTANCE;
}
@Override
@@ -35,6 +35,10 @@ import java.util.stream.Collectors;
import com.google.gson.JsonNull;
import com.volmit.iris.core.nms.container.BiomeColor;
import com.volmit.iris.util.scheduling.J;
import net.minecraft.nbt.*;
import net.minecraft.nbt.Tag;
import net.minecraft.server.commands.data.BlockDataAccessor;
import com.volmit.iris.core.nms.container.IPackRepository;
import com.volmit.iris.util.io.IO;
import net.minecraft.server.commands.DataPackCommand;
@@ -64,12 +68,15 @@ import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.world.level.dimension.LevelStem;
import net.minecraft.world.level.storage.LevelStorageSource;
import net.minecraft.world.level.storage.PrimaryLevelData;
import net.minecraft.world.level.block.EntityBlock;
import org.bukkit.*;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.v1_20_R2.CraftChunk;
import org.bukkit.craftbukkit.v1_20_R2.CraftServer;
import org.bukkit.craftbukkit.v1_20_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_20_R2.block.CraftBlockState;
import org.bukkit.craftbukkit.v1_20_R2.block.CraftBlockStates;
import org.bukkit.craftbukkit.v1_20_R2.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_20_R2.entity.CraftDolphin;
import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack;
@@ -81,6 +88,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.generator.BiomeProvider;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
@@ -106,8 +114,6 @@ import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.TagParser;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
@@ -183,50 +189,57 @@ public class NMSBinding implements INMSBinding {
return type.getDeclaredClasses()[ordinal];
}
@Override
public boolean hasTile(Material material) {
return !CraftBlockState.class.equals(CraftBlockStates.getBlockStateType(material));
}
@Override
public boolean hasTile(Location l) {
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
}
@Override
public CompoundTag serializeTile(Location location) {
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true);
@SuppressWarnings("unchecked")
public KMap<String, Object> serializeTile(Location location) {
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), false);
if (e == null) {
return null;
}
net.minecraft.nbt.CompoundTag tag = e.saveWithFullMetadata();
return convert(tag);
net.minecraft.nbt.CompoundTag tag = e.saveWithoutMetadata();
return (KMap<String, Object>) convertFromTag(tag, 0, 64);
}
private CompoundTag convert(net.minecraft.nbt.CompoundTag tag) {
try {
ByteArrayOutputStream boas = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(boas);
tag.write(dos);
dos.close();
return (CompoundTag) NBTUtil.read(new ByteArrayInputStream(boas.toByteArray()), false).getTag();
} catch (Throwable ex) {
ex.printStackTrace();
@Contract(value = "null, _, _ -> null", pure = true)
private Object convertFromTag(net.minecraft.nbt.Tag tag, int depth, int maxDepth) {
if (tag == null || depth > maxDepth) return null;
if (tag instanceof CollectionTag<?> collection) {
KList<Object> list = new KList<>();
for (Object i : collection) {
if (i instanceof net.minecraft.nbt.Tag t)
list.add(convertFromTag(t, depth + 1, maxDepth));
else list.add(i);
}
return list;
}
if (tag instanceof net.minecraft.nbt.CompoundTag compound) {
KMap<String, Object> map = new KMap<>();
return null;
}
private net.minecraft.nbt.CompoundTag convert(CompoundTag tag) {
try {
ByteArrayOutputStream boas = new ByteArrayOutputStream();
NBTUtil.write(tag, boas, false);
DataInputStream din = new DataInputStream(new ByteArrayInputStream(boas.toByteArray()));
net.minecraft.nbt.CompoundTag c = NbtIo.read(din);
din.close();
return c;
} catch (Throwable e) {
e.printStackTrace();
for (String key : compound.getAllKeys()) {
var child = compound.get(key);
if (child == null) continue;
var value = convertFromTag(child, depth + 1, maxDepth);
if (value == null) continue;
map.put(key, value);
}
return map;
}
return null;
if (tag instanceof NumericTag numeric)
return numeric.getAsNumber();
return tag.getAsString();
}
private RegistryAccess getRegistryAccess(World world) {
@@ -241,8 +254,52 @@ public class NMSBinding implements INMSBinding {
}
@Override
public void deserializeTile(CompoundTag c, Location pos) {
((CraftWorld) pos.getWorld()).getHandle().getChunkAt(new BlockPos(pos.getBlockX(), 0, pos.getBlockZ())).setBlockEntityNbt(convert(c));
public void deserializeTile(KMap<String, Object> map, Location pos) {
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64);
var level = ((CraftWorld) pos.getWorld()).getHandle();
var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
J.s(() -> merge(level, blockPos, tag));
}
private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) {
var blockEntity = level.getBlockEntity(blockPos);
if (blockEntity == null) {
Iris.warn("[NMS] BlockEntity not found at " + blockPos);
var state = level.getBlockState(blockPos);
if (!state.hasBlockEntity())
return;
blockEntity = ((EntityBlock) state.getBlock())
.newBlockEntity(blockPos, state);
}
var accessor = new BlockDataAccessor(blockEntity, blockPos);
accessor.setData(tag.merge(accessor.getData()));
}
private Tag convertToTag(Object object, int depth, int maxDepth) {
if (object == null || depth > maxDepth) return EndTag.INSTANCE;
if (object instanceof Map<?,?> map) {
var tag = new net.minecraft.nbt.CompoundTag();
for (var i : map.entrySet()) {
tag.put(i.getKey().toString(), convertToTag(i.getValue(), depth + 1, maxDepth));
}
return tag;
}
if (object instanceof List<?> list) {
var tag = new net.minecraft.nbt.ListTag();
for (var i : list) {
tag.add(convertToTag(i, depth + 1, maxDepth));
}
return tag;
}
if (object instanceof Byte number) return ByteTag.valueOf(number);
if (object instanceof Short number) return ShortTag.valueOf(number);
if (object instanceof Integer number) return IntTag.valueOf(number);
if (object instanceof Long number) return LongTag.valueOf(number);
if (object instanceof Float number) return FloatTag.valueOf(number);
if (object instanceof Double number) return DoubleTag.valueOf(number);
if (object instanceof String string) return StringTag.valueOf(string);
return EndTag.INSTANCE;
}
@Override
@@ -24,6 +24,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;
@@ -70,13 +71,20 @@ import net.minecraft.world.level.dimension.LevelStem;
import net.minecraft.world.level.storage.LevelStorageSource;
import net.minecraft.world.level.storage.PrimaryLevelData;
import com.volmit.iris.core.nms.container.BiomeColor;
import com.volmit.iris.util.scheduling.J;
import net.minecraft.nbt.*;
import net.minecraft.nbt.Tag;
import net.minecraft.server.commands.data.BlockDataAccessor;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.EntityBlock;
import org.bukkit.*;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.v1_20_R3.CraftChunk;
import org.bukkit.craftbukkit.v1_20_R3.CraftServer;
import org.bukkit.craftbukkit.v1_20_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_20_R3.block.CraftBlockState;
import org.bukkit.craftbukkit.v1_20_R3.block.CraftBlockStates;
import org.bukkit.craftbukkit.v1_20_R3.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftDolphin;
import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack;
@@ -87,6 +95,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.generator.BiomeProvider;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
@@ -112,8 +121,6 @@ import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.TagParser;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
@@ -191,50 +198,57 @@ public class NMSBinding implements INMSBinding {
return type.getDeclaredClasses()[ordinal];
}
@Override
public boolean hasTile(Material material) {
return !CraftBlockState.class.equals(CraftBlockStates.getBlockStateType(material));
}
@Override
public boolean hasTile(Location l) {
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
}
@Override
public CompoundTag serializeTile(Location location) {
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true);
@SuppressWarnings("unchecked")
public KMap<String, Object> serializeTile(Location location) {
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), false);
if (e == null) {
return null;
}
net.minecraft.nbt.CompoundTag tag = e.saveWithFullMetadata();
return convert(tag);
net.minecraft.nbt.CompoundTag tag = e.saveWithoutMetadata();
return (KMap<String, Object>) convertFromTag(tag, 0, 64);
}
private CompoundTag convert(net.minecraft.nbt.CompoundTag tag) {
try {
ByteArrayOutputStream boas = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(boas);
tag.write(dos);
dos.close();
return (CompoundTag) NBTUtil.read(new ByteArrayInputStream(boas.toByteArray()), false).getTag();
} catch (Throwable ex) {
ex.printStackTrace();
@Contract(value = "null, _, _ -> null", pure = true)
private Object convertFromTag(net.minecraft.nbt.Tag tag, int depth, int maxDepth) {
if (tag == null || depth > maxDepth) return null;
if (tag instanceof CollectionTag<?> collection) {
KList<Object> list = new KList<>();
for (Object i : collection) {
if (i instanceof net.minecraft.nbt.Tag t)
list.add(convertFromTag(t, depth + 1, maxDepth));
else list.add(i);
}
return list;
}
if (tag instanceof net.minecraft.nbt.CompoundTag compound) {
KMap<String, Object> map = new KMap<>();
return null;
}
private net.minecraft.nbt.CompoundTag convert(CompoundTag tag) {
try {
ByteArrayOutputStream boas = new ByteArrayOutputStream();
NBTUtil.write(tag, boas, false);
DataInputStream din = new DataInputStream(new ByteArrayInputStream(boas.toByteArray()));
net.minecraft.nbt.CompoundTag c = NbtIo.read(din);
din.close();
return c;
} catch (Throwable e) {
e.printStackTrace();
for (String key : compound.getAllKeys()) {
var child = compound.get(key);
if (child == null) continue;
var value = convertFromTag(child, depth + 1, maxDepth);
if (value == null) continue;
map.put(key, value);
}
return map;
}
return null;
if (tag instanceof NumericTag numeric)
return numeric.getAsNumber();
return tag.getAsString();
}
private RegistryAccess getRegistryAccess(World world) {
@@ -249,8 +263,52 @@ public class NMSBinding implements INMSBinding {
}
@Override
public void deserializeTile(CompoundTag c, Location pos) {
((CraftWorld) pos.getWorld()).getHandle().getChunkAt(new BlockPos(pos.getBlockX(), 0, pos.getBlockZ())).setBlockEntityNbt(convert(c));
public void deserializeTile(KMap<String, Object> map, Location pos) {
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64);
var level = ((CraftWorld) pos.getWorld()).getHandle();
var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
J.s(() -> merge(level, blockPos, tag));
}
private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) {
var blockEntity = level.getBlockEntity(blockPos);
if (blockEntity == null) {
Iris.warn("[NMS] BlockEntity not found at " + blockPos);
var state = level.getBlockState(blockPos);
if (!state.hasBlockEntity())
return;
blockEntity = ((EntityBlock) state.getBlock())
.newBlockEntity(blockPos, state);
}
var accessor = new BlockDataAccessor(blockEntity, blockPos);
accessor.setData(tag.merge(accessor.getData()));
}
private Tag convertToTag(Object object, int depth, int maxDepth) {
if (object == null || depth > maxDepth) return EndTag.INSTANCE;
if (object instanceof Map<?,?> map) {
var tag = new net.minecraft.nbt.CompoundTag();
for (var i : map.entrySet()) {
tag.put(i.getKey().toString(), convertToTag(i.getValue(), depth + 1, maxDepth));
}
return tag;
}
if (object instanceof List<?> list) {
var tag = new net.minecraft.nbt.ListTag();
for (var i : list) {
tag.add(convertToTag(i, depth + 1, maxDepth));
}
return tag;
}
if (object instanceof Byte number) return ByteTag.valueOf(number);
if (object instanceof Short number) return ShortTag.valueOf(number);
if (object instanceof Integer number) return IntTag.valueOf(number);
if (object instanceof Long number) return LongTag.valueOf(number);
if (object instanceof Float number) return FloatTag.valueOf(number);
if (object instanceof Double number) return DoubleTag.valueOf(number);
if (object instanceof String string) return StringTag.valueOf(string);
return EndTag.INSTANCE;
}
@Override
@@ -54,14 +54,32 @@ import net.bytebuddy.dynamic.loading.ClassReloadingStrategy;
import net.bytebuddy.matcher.ElementMatchers;
import net.minecraft.core.MappedRegistry;
import net.minecraft.core.RegistrationInfo;
import com.volmit.iris.util.nbt.tag.CompoundTag;
import com.volmit.iris.util.scheduling.J;
import net.minecraft.core.*;
import net.minecraft.core.Registry;
import net.minecraft.core.component.DataComponents;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.progress.ChunkProgressListener;
import net.minecraft.util.GsonHelper;
import net.minecraft.world.RandomSequences;
import net.minecraft.nbt.*;
import net.minecraft.nbt.ByteTag;
import net.minecraft.nbt.DoubleTag;
import net.minecraft.nbt.EndTag;
import net.minecraft.nbt.FloatTag;
import net.minecraft.nbt.IntTag;
import net.minecraft.nbt.LongTag;
import net.minecraft.nbt.ShortTag;
import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag;
import net.minecraft.server.commands.data.BlockDataAccessor;
import net.minecraft.server.commands.data.DataCommands;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.chunk.status.ChunkStatus;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.world.level.dimension.LevelStem;
@@ -73,6 +91,9 @@ import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.v1_20_R4.CraftChunk;
import org.bukkit.craftbukkit.v1_20_R4.CraftServer;
import org.bukkit.craftbukkit.v1_20_R4.CraftWorld;
import org.bukkit.craftbukkit.v1_20_R4.block.CraftBlockState;
import org.bukkit.craftbukkit.v1_20_R4.block.CraftBlockStates;
import org.bukkit.craftbukkit.v1_20_R4.block.CraftBlockType;
import org.bukkit.craftbukkit.v1_20_R4.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_20_R4.entity.CraftDolphin;
import org.bukkit.craftbukkit.v1_20_R4.inventory.CraftItemStack;
@@ -83,6 +104,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.generator.BiomeProvider;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
@@ -97,19 +119,11 @@ import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.mantle.Mantle;
import com.volmit.iris.util.math.Vector3d;
import com.volmit.iris.util.matter.MatterBiomeInject;
import com.volmit.iris.util.nbt.io.NBTUtil;
import com.volmit.iris.util.nbt.mca.NBTWorld;
import com.volmit.iris.util.nbt.mca.palette.*;
import com.volmit.iris.util.nbt.tag.CompoundTag;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.TagParser;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
@@ -184,55 +198,109 @@ public class NMSBinding implements INMSBinding {
return type.getDeclaredClasses()[ordinal];
}
@Override
public boolean hasTile(Material material) {
return !CraftBlockState.class.equals(CraftBlockStates.getBlockStateType(material));
}
@Override
public boolean hasTile(Location l) {
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
}
@Override
public CompoundTag serializeTile(Location location) {
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true);
@SuppressWarnings("unchecked")
public KMap<String, Object> serializeTile(Location location) {
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), false);
if (e == null) {
return null;
}
net.minecraft.nbt.CompoundTag tag = e.saveWithFullMetadata(registry());
return convert(tag);
net.minecraft.nbt.CompoundTag tag = e.saveWithoutMetadata(registry());
return (KMap<String, Object>) convertFromTag(tag, 0, 64);
}
private CompoundTag convert(net.minecraft.nbt.CompoundTag tag) {
try {
ByteArrayOutputStream boas = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(boas);
tag.write(dos);
dos.close();
return (CompoundTag) NBTUtil.read(new ByteArrayInputStream(boas.toByteArray()), false).getTag();
} catch (Throwable ex) {
ex.printStackTrace();
}
@Contract(value = "null, _, _ -> null", pure = true)
private Object convertFromTag(net.minecraft.nbt.Tag tag, int depth, int maxDepth) {
if (tag == null || depth > maxDepth) return null;
return switch (tag) {
case CollectionTag<?> collection -> {
KList<Object> list = new KList<>();
return null;
}
for (Object i : collection) {
if (i instanceof net.minecraft.nbt.Tag t)
list.add(convertFromTag(t, depth + 1, maxDepth));
else list.add(i);
}
yield list;
}
case net.minecraft.nbt.CompoundTag compound -> {
KMap<String, Object> map = new KMap<>();
private net.minecraft.nbt.CompoundTag convert(CompoundTag tag) {
try {
ByteArrayOutputStream boas = new ByteArrayOutputStream();
NBTUtil.write(tag, boas, false);
DataInputStream din = new DataInputStream(new ByteArrayInputStream(boas.toByteArray()));
net.minecraft.nbt.CompoundTag c = NbtIo.read(din);
din.close();
return c;
} catch (Throwable e) {
e.printStackTrace();
}
return null;
for (String key : compound.getAllKeys()) {
var child = compound.get(key);
if (child == null) continue;
var value = convertFromTag(child, depth + 1, maxDepth);
if (value == null) continue;
map.put(key, value);
}
yield map;
}
case NumericTag numeric -> numeric.getAsNumber();
default -> tag.getAsString();
};
}
@Override
public void deserializeTile(CompoundTag c, Location pos) {
((CraftWorld) pos.getWorld()).getHandle().getChunkAt(new BlockPos(pos.getBlockX(), 0, pos.getBlockZ())).setBlockEntityNbt(convert(c));
public void deserializeTile(KMap<String, Object> map, Location pos) {
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64);
var level = ((CraftWorld) pos.getWorld()).getHandle();
var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
J.s(() -> merge(level, blockPos, tag));
}
private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) {
var blockEntity = level.getBlockEntity(blockPos);
if (blockEntity == null) {
Iris.warn("[NMS] BlockEntity not found at " + blockPos);
var state = level.getBlockState(blockPos);
if (!state.hasBlockEntity())
return;
blockEntity = ((EntityBlock) state.getBlock())
.newBlockEntity(blockPos, state);
}
var accessor = new BlockDataAccessor(blockEntity, blockPos);
accessor.setData(tag.merge(accessor.getData()));
}
private Tag convertToTag(Object object, int depth, int maxDepth) {
if (object == null || depth > maxDepth) return EndTag.INSTANCE;
return switch (object) {
case Map<?, ?> map -> {
var tag = new net.minecraft.nbt.CompoundTag();
for (var i : map.entrySet()) {
tag.put(i.getKey().toString(), convertToTag(i.getValue(), depth + 1, maxDepth));
}
yield tag;
}
case List<?> list -> {
var tag = new net.minecraft.nbt.ListTag();
for (var i : list) {
tag.add(convertToTag(i, depth + 1, maxDepth));
}
yield tag;
}
case Byte number -> ByteTag.valueOf(number);
case Short number -> ShortTag.valueOf(number);
case Integer number -> IntTag.valueOf(number);
case Long number -> LongTag.valueOf(number);
case Float number -> FloatTag.valueOf(number);
case Double number -> DoubleTag.valueOf(number);
case String string -> StringTag.valueOf(string);
default -> EndTag.INSTANCE;
};
}
@Override
@@ -472,13 +540,13 @@ public class NMSBinding implements INMSBinding {
@Override
public MCAPaletteAccess createPalette() {
MCAIdMapper<BlockState> registry = registryCache.aquireNasty(() -> {
Field cf = net.minecraft.core.IdMapper.class.getDeclaredField("tToId");
Field df = net.minecraft.core.IdMapper.class.getDeclaredField("idToT");
Field bf = net.minecraft.core.IdMapper.class.getDeclaredField("nextId");
Field cf = IdMapper.class.getDeclaredField("tToId");
Field df = IdMapper.class.getDeclaredField("idToT");
Field bf = IdMapper.class.getDeclaredField("nextId");
cf.setAccessible(true);
df.setAccessible(true);
bf.setAccessible(true);
net.minecraft.core.IdMapper<BlockState> blockData = Block.BLOCK_STATE_REGISTRY;
IdMapper<BlockState> blockData = Block.BLOCK_STATE_REGISTRY;
int b = bf.getInt(blockData);
Object2IntMap<BlockState> c = (Object2IntMap<BlockState>) cf.get(blockData);
List<BlockState> d = (List<BlockState>) df.get(blockData);
@@ -50,7 +50,11 @@ import net.bytebuddy.dynamic.loading.ClassReloadingStrategy;
import net.bytebuddy.matcher.ElementMatchers;
import net.minecraft.core.*;
import net.minecraft.core.Registry;
import com.volmit.iris.util.scheduling.J;
import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.*;
import net.minecraft.nbt.Tag;
import net.minecraft.server.commands.data.BlockDataAccessor;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.progress.ChunkProgressListener;
@@ -59,6 +63,7 @@ import net.minecraft.world.RandomSequences;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.chunk.status.ChunkStatus;
import net.minecraft.world.level.chunk.status.WorldGenContext;
import net.minecraft.world.level.dimension.DimensionType;
@@ -71,6 +76,8 @@ import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.v1_21_R1.CraftChunk;
import org.bukkit.craftbukkit.v1_21_R1.CraftServer;
import org.bukkit.craftbukkit.v1_21_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_21_R1.block.CraftBlockState;
import org.bukkit.craftbukkit.v1_21_R1.block.CraftBlockStates;
import org.bukkit.craftbukkit.v1_21_R1.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_21_R1.entity.CraftDolphin;
import org.bukkit.craftbukkit.v1_21_R1.inventory.CraftItemStack;
@@ -81,6 +88,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.generator.BiomeProvider;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
@@ -102,8 +110,6 @@ import com.volmit.iris.util.nbt.tag.CompoundTag;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.TagParser;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
@@ -178,55 +184,109 @@ public class NMSBinding implements INMSBinding {
return type.getDeclaredClasses()[ordinal];
}
@Override
public boolean hasTile(Material material) {
return !CraftBlockState.class.equals(CraftBlockStates.getBlockStateType(material));
}
@Override
public boolean hasTile(Location l) {
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
}
@Override
public CompoundTag serializeTile(Location location) {
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true);
@SuppressWarnings("unchecked")
public KMap<String, Object> serializeTile(Location location) {
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), false);
if (e == null) {
return null;
}
net.minecraft.nbt.CompoundTag tag = e.saveWithFullMetadata(registry());
return convert(tag);
net.minecraft.nbt.CompoundTag tag = e.saveWithoutMetadata(registry());
return (KMap<String, Object>) convertFromTag(tag, 0, 64);
}
private CompoundTag convert(net.minecraft.nbt.CompoundTag tag) {
try {
ByteArrayOutputStream boas = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(boas);
tag.write(dos);
dos.close();
return (CompoundTag) NBTUtil.read(new ByteArrayInputStream(boas.toByteArray()), false).getTag();
} catch (Throwable ex) {
ex.printStackTrace();
}
@Contract(value = "null, _, _ -> null", pure = true)
private Object convertFromTag(net.minecraft.nbt.Tag tag, int depth, int maxDepth) {
if (tag == null || depth > maxDepth) return null;
return switch (tag) {
case CollectionTag<?> collection -> {
KList<Object> list = new KList<>();
return null;
}
for (Object i : collection) {
if (i instanceof net.minecraft.nbt.Tag t)
list.add(convertFromTag(t, depth + 1, maxDepth));
else list.add(i);
}
yield list;
}
case net.minecraft.nbt.CompoundTag compound -> {
KMap<String, Object> map = new KMap<>();
private net.minecraft.nbt.CompoundTag convert(CompoundTag tag) {
try {
ByteArrayOutputStream boas = new ByteArrayOutputStream();
NBTUtil.write(tag, boas, false);
DataInputStream din = new DataInputStream(new ByteArrayInputStream(boas.toByteArray()));
net.minecraft.nbt.CompoundTag c = NbtIo.read(din);
din.close();
return c;
} catch (Throwable e) {
e.printStackTrace();
}
return null;
for (String key : compound.getAllKeys()) {
var child = compound.get(key);
if (child == null) continue;
var value = convertFromTag(child, depth + 1, maxDepth);
if (value == null) continue;
map.put(key, value);
}
yield map;
}
case NumericTag numeric -> numeric.getAsNumber();
default -> tag.getAsString();
};
}
@Override
public void deserializeTile(CompoundTag c, Location pos) {
((CraftWorld) pos.getWorld()).getHandle().getChunkAt(new BlockPos(pos.getBlockX(), 0, pos.getBlockZ())).setBlockEntityNbt(convert(c));
public void deserializeTile(KMap<String, Object> map, Location pos) {
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64);
var level = ((CraftWorld) pos.getWorld()).getHandle();
var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
J.s(() -> merge(level, blockPos, tag));
}
private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) {
var blockEntity = level.getBlockEntity(blockPos);
if (blockEntity == null) {
Iris.warn("[NMS] BlockEntity not found at " + blockPos);
var state = level.getBlockState(blockPos);
if (!state.hasBlockEntity())
return;
blockEntity = ((EntityBlock) state.getBlock())
.newBlockEntity(blockPos, state);
}
var accessor = new BlockDataAccessor(blockEntity, blockPos);
accessor.setData(tag.merge(accessor.getData()));
}
private Tag convertToTag(Object object, int depth, int maxDepth) {
if (object == null || depth > maxDepth) return EndTag.INSTANCE;
return switch (object) {
case Map<?, ?> map -> {
var tag = new net.minecraft.nbt.CompoundTag();
for (var i : map.entrySet()) {
tag.put(i.getKey().toString(), convertToTag(i.getValue(), depth + 1, maxDepth));
}
yield tag;
}
case List<?> list -> {
var tag = new net.minecraft.nbt.ListTag();
for (var i : list) {
tag.add(convertToTag(i, depth + 1, maxDepth));
}
yield tag;
}
case Byte number -> ByteTag.valueOf(number);
case Short number -> ShortTag.valueOf(number);
case Integer number -> IntTag.valueOf(number);
case Long number -> LongTag.valueOf(number);
case Float number -> FloatTag.valueOf(number);
case Double number -> DoubleTag.valueOf(number);
case String string -> StringTag.valueOf(string);
default -> EndTag.INSTANCE;
};
}
@Override