mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-01 23:47:21 +00:00
implement dynamic tile entities
This commit is contained in:
parent
b6457e47e6
commit
f58078e8a0
@ -117,10 +117,8 @@ public class CommandObject implements DecreeExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTile(int xx, int yy, int zz, TileData<? extends TileState> tile) {
|
public void setTile(int xx, int yy, int zz, TileData tile) {
|
||||||
BlockState state = world.getBlockAt(xx, yy, zz).getState();
|
tile.toBukkitTry(world.getBlockAt(xx, yy, zz));
|
||||||
tile.toBukkitTry(state);
|
|
||||||
state.update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -28,10 +28,7 @@ import com.volmit.iris.util.math.Vector3d;
|
|||||||
import com.volmit.iris.util.nbt.mca.palette.MCABiomeContainer;
|
import com.volmit.iris.util.nbt.mca.palette.MCABiomeContainer;
|
||||||
import com.volmit.iris.util.nbt.mca.palette.MCAPaletteAccess;
|
import com.volmit.iris.util.nbt.mca.palette.MCAPaletteAccess;
|
||||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.*;
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.WorldCreator;
|
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.entity.Dolphin;
|
import org.bukkit.entity.Dolphin;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
@ -41,13 +38,16 @@ import org.bukkit.generator.ChunkGenerator;
|
|||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.Color;
|
||||||
|
|
||||||
public interface INMSBinding {
|
public interface INMSBinding {
|
||||||
|
boolean hasTile(Material material);
|
||||||
|
|
||||||
boolean hasTile(Location l);
|
boolean hasTile(Location l);
|
||||||
|
|
||||||
CompoundTag serializeTile(Location location);
|
KMap<String, Object> serializeTile(Location location);
|
||||||
|
|
||||||
void deserializeTile(CompoundTag s, Location newPosition);
|
void deserializeTile(KMap<String, Object> s, Location newPosition);
|
||||||
|
|
||||||
CompoundTag serializeEntity(Entity location);
|
CompoundTag serializeEntity(Entity location);
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ import com.volmit.iris.util.nbt.mca.palette.MCAPaletteAccess;
|
|||||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.entity.Dolphin;
|
import org.bukkit.entity.Dolphin;
|
||||||
@ -61,16 +62,27 @@ public class NMSBinding1X implements INMSBinding {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasTile(Material material) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasTile(Location l) {
|
public boolean hasTile(Location l) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag serializeTile(Location location) {
|
public KMap<String, Object> serializeTile(Location location) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deserializeTile(KMap<String, Object> s, Location newPosition) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectBiomesFromMantle(Chunk e, Mantle mantle) {
|
public void injectBiomesFromMantle(Chunk e, Mantle mantle) {
|
||||||
|
|
||||||
@ -105,11 +117,6 @@ public class NMSBinding1X implements INMSBinding {
|
|||||||
return Color.GREEN;
|
return Color.GREEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deserializeTile(CompoundTag s, Location newPosition) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag serializeEntity(Entity location) {
|
public CompoundTag serializeEntity(Entity location) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -183,7 +183,7 @@ public class TreeSVC implements IrisService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTile(int xx, int yy, int zz, TileData<? extends TileState> tile) {
|
public void setTile(int xx, int yy, int zz, TileData tile) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ import java.util.concurrent.CountDownLatch;
|
|||||||
public class WandSVC implements IrisService {
|
public class WandSVC implements IrisService {
|
||||||
private static final Particle CRIT_MAGIC = E.getOrDefault(Particle.class, "CRIT_MAGIC", "CRIT");
|
private static final Particle CRIT_MAGIC = E.getOrDefault(Particle.class, "CRIT_MAGIC", "CRIT");
|
||||||
private static final Particle REDSTONE = E.getOrDefault(Particle.class, "REDSTONE", "DUST");
|
private static final Particle REDSTONE = E.getOrDefault(Particle.class, "REDSTONE", "DUST");
|
||||||
private static final int BLOCKS_PER_TICK = Integer.parseInt(System.getProperty("iris.blocks_per_tick", "100"));
|
private static final int BLOCKS_PER_TICK = Integer.parseInt(System.getProperty("iris.blocks_per_tick", "1000"));
|
||||||
|
|
||||||
private static ItemStack dust;
|
private static ItemStack dust;
|
||||||
private static ItemStack wand;
|
private static ItemStack wand;
|
||||||
@ -84,19 +84,6 @@ public class WandSVC implements IrisService {
|
|||||||
Cuboid c = new Cuboid(f[0], f[1]);
|
Cuboid c = new Cuboid(f[0], f[1]);
|
||||||
IrisObject s = new IrisObject(c.getSizeX(), c.getSizeY(), c.getSizeZ());
|
IrisObject s = new IrisObject(c.getSizeX(), c.getSizeY(), c.getSizeZ());
|
||||||
|
|
||||||
if (Bukkit.isPrimaryThread()) {
|
|
||||||
for (Block b : c) {
|
|
||||||
if (b.getType().equals(Material.AIR)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockVector bv = b.getLocation().subtract(c.getLowerNE().toVector()).toVector().toBlockVector();
|
|
||||||
s.setUnsigned(bv.getBlockX(), bv.getBlockY(), bv.getBlockZ(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
var it = c.iterator();
|
var it = c.iterator();
|
||||||
var latch = new CountDownLatch(1);
|
var latch = new CountDownLatch(1);
|
||||||
new SR() {
|
new SR() {
|
||||||
|
@ -53,7 +53,6 @@ import com.volmit.iris.util.math.Position2;
|
|||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
import com.volmit.iris.util.matter.MatterCavern;
|
import com.volmit.iris.util.matter.MatterCavern;
|
||||||
import com.volmit.iris.util.matter.MatterUpdate;
|
import com.volmit.iris.util.matter.MatterUpdate;
|
||||||
import com.volmit.iris.util.matter.TileWrapper;
|
|
||||||
import com.volmit.iris.util.matter.slices.container.JigsawPieceContainer;
|
import com.volmit.iris.util.matter.slices.container.JigsawPieceContainer;
|
||||||
import com.volmit.iris.util.parallel.BurstExecutor;
|
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
@ -283,10 +282,10 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
|||||||
}
|
}
|
||||||
|
|
||||||
getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.TILE, () -> J.s(() -> {
|
getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.TILE, () -> J.s(() -> {
|
||||||
getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), TileWrapper.class, (x, y, z, tile) -> {
|
getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), TileData.class, (x, y, z, tile) -> {
|
||||||
int betterY = y + getWorld().minHeight();
|
int betterY = y + getWorld().minHeight();
|
||||||
if (!TileData.setTileState(c.getBlock(x, betterY, z), tile.getData()))
|
if (!TileData.setTileState(c.getBlock(x, betterY, z), tile))
|
||||||
Iris.warn("Failed to set tile entity data at [%d %d %d | %s] for tile %s!", x, betterY, z, c.getBlock(x, betterY, z).getBlockData().getMaterial().getKey(), tile.getData().getTileId());
|
Iris.warn("Failed to set tile entity data at [%d %d %d | %s] for tile %s!", x, betterY, z, c.getBlock(x, betterY, z).getBlockData().getMaterial().getKey(), tile.getMaterial().name());
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.CUSTOM, () -> J.s(() -> {
|
getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.CUSTOM, () -> J.s(() -> {
|
||||||
|
@ -79,7 +79,7 @@ public class HeightmapObjectPlacer implements IObjectPlacer {
|
|||||||
return oplacer.isDebugSmartBore();
|
return oplacer.isDebugSmartBore();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTile(int param1Int1, int param1Int2, int param1Int3, TileData<? extends TileState> param1TileData) {
|
public void setTile(int param1Int1, int param1Int2, int param1Int3, TileData param1TileData) {
|
||||||
oplacer.setTile(param1Int1, param1Int2, param1Int3, param1TileData);
|
oplacer.setTile(param1Int1, param1Int2, param1Int3, param1TileData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,9 +119,7 @@ public class WorldObjectPlacer implements IObjectPlacer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTile(int xx, int yy, int zz, TileData<? extends TileState> tile) {
|
public void setTile(int xx, int yy, int zz, TileData tile) {
|
||||||
BlockState state = world.getBlockAt(xx, yy + world.getMinHeight(), zz).getState();
|
tile.toBukkitTry(world.getBlockAt(xx, yy + world.getMinHeight(), zz));
|
||||||
tile.toBukkitTry(state);
|
|
||||||
state.update();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,8 +107,8 @@ public interface EngineMantle extends IObjectPlacer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default void setTile(int x, int y, int z, TileData<? extends TileState> d) {
|
default void setTile(int x, int y, int z, TileData d) {
|
||||||
getMantle().set(x, y, z, new TileWrapper(d));
|
getMantle().set(x, y, z, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -206,7 +206,7 @@ public class MantleWriter implements IObjectPlacer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTile(int xx, int yy, int zz, TileData<? extends TileState> tile) {
|
public void setTile(int xx, int yy, int zz, TileData tile) {
|
||||||
getEngineMantle().setTile(xx, yy, zz, tile);
|
getEngineMantle().setTile(xx, yy, zz, tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ public interface IObjectPlacer {
|
|||||||
|
|
||||||
boolean isDebugSmartBore();
|
boolean isDebugSmartBore();
|
||||||
|
|
||||||
void setTile(int xx, int yy, int zz, TileData<? extends TileState> tile);
|
void setTile(int xx, int yy, int zz, TileData tile);
|
||||||
|
|
||||||
Engine getEngine();
|
Engine getEngine();
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ package com.volmit.iris.engine.object;
|
|||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.loader.IrisData;
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
import com.volmit.iris.core.loader.IrisRegistrant;
|
import com.volmit.iris.core.loader.IrisRegistrant;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
import com.volmit.iris.engine.object.annotations.*;
|
import com.volmit.iris.engine.object.annotations.*;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
@ -196,17 +197,12 @@ public class IrisBlockData extends IrisRegistrant {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public TileData<?> tryGetTile() {
|
public TileData tryGetTile(IrisData data) {
|
||||||
//TODO Do like a registry thing with the tile data registry. Also update the parsing of data to include **block** entities.
|
//TODO Do like a registry thing with the tile data registry. Also update the parsing of data to include **block** entities.
|
||||||
if (data.containsKey("entitySpawn")) {
|
var type = getBlockData(data).getMaterial();
|
||||||
TileSpawner spawner = new TileSpawner();
|
if (!INMS.get().hasTile(type))
|
||||||
String name = (String) data.get("entitySpawn");
|
return null;
|
||||||
if (name.contains(":"))
|
return new TileData().setMaterial(type).setProperties(this.data);
|
||||||
name = name.split(":")[1];
|
|
||||||
spawner.setEntityType(EntityType.fromName(name));
|
|
||||||
return spawner;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String keyify(String dat) {
|
private String keyify(String dat) {
|
||||||
|
@ -64,11 +64,11 @@ public class IrisMaterialPalette {
|
|||||||
return getLayerGenerator(rng, rdata).fit(getBlockData(rdata), x / zoom, y / zoom, z / zoom);
|
return getLayerGenerator(rng, rdata).fit(getBlockData(rdata), x / zoom, y / zoom, z / zoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<TileData<?>> getTile(RNG rng, double x, double y, double z, IrisData rdata) {
|
public Optional<TileData> getTile(RNG rng, double x, double y, double z, IrisData rdata) {
|
||||||
if (getBlockData(rdata).isEmpty())
|
if (getBlockData(rdata).isEmpty())
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
|
|
||||||
TileData<?> tile = getBlockData(rdata).size() == 1 ? palette.get(0).tryGetTile() : palette.getRandom(rng).tryGetTile();
|
TileData tile = getBlockData(rdata).size() == 1 ? palette.get(0).tryGetTile(rdata) : palette.getRandom(rng).tryGetTile(rdata);
|
||||||
return tile != null ? Optional.of(tile) : Optional.empty();
|
return tile != null ? Optional.of(tile) : Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
@Setter
|
@Setter
|
||||||
protected transient AtomicCache<AxisAlignedBB> aabb = new AtomicCache<>();
|
protected transient AtomicCache<AxisAlignedBB> aabb = new AtomicCache<>();
|
||||||
private KMap<BlockVector, BlockData> blocks;
|
private KMap<BlockVector, BlockData> blocks;
|
||||||
private KMap<BlockVector, TileData<? extends TileState>> states;
|
private KMap<BlockVector, TileData> states;
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
private int w;
|
private int w;
|
||||||
@ -434,7 +434,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
d.put(new BlockVector(i.getBlockX(), i.getBlockY(), i.getBlockZ()), Objects.requireNonNull(getBlocks().get(i)));
|
d.put(new BlockVector(i.getBlockX(), i.getBlockY(), i.getBlockZ()), Objects.requireNonNull(getBlocks().get(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
KMap<BlockVector, TileData<? extends TileState>> dx = new KMap<>();
|
KMap<BlockVector, TileData> dx = new KMap<>();
|
||||||
|
|
||||||
for (BlockVector i : getBlocks().keySet()) {
|
for (BlockVector i : getBlocks().keySet()) {
|
||||||
d.put(new BlockVector(i.getBlockX(), i.getBlockY(), i.getBlockZ()), Objects.requireNonNull(getBlocks().get(i)));
|
d.put(new BlockVector(i.getBlockX(), i.getBlockY(), i.getBlockZ()), Objects.requireNonNull(getBlocks().get(i)));
|
||||||
@ -476,7 +476,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
} else {
|
} else {
|
||||||
BlockData data = block.getBlockData();
|
BlockData data = block.getBlockData();
|
||||||
getBlocks().put(v, data);
|
getBlocks().put(v, data);
|
||||||
TileData<? extends TileState> state = TileData.getTileState(block);
|
TileData state = TileData.getTileState(block);
|
||||||
if (state != null) {
|
if (state != null) {
|
||||||
Iris.info("Saved State " + v);
|
Iris.info("Saved State " + v);
|
||||||
getStates().put(v, state);
|
getStates().put(v, state);
|
||||||
@ -802,7 +802,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
|
|
||||||
for (BlockVector g : getBlocks().keySet()) {
|
for (BlockVector g : getBlocks().keySet()) {
|
||||||
BlockData d;
|
BlockData d;
|
||||||
TileData<? extends TileState> tile = null;
|
TileData tile = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
d = getBlocks().get(g);
|
d = getBlocks().get(g);
|
||||||
@ -842,11 +842,9 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
else
|
else
|
||||||
data = newData;
|
data = newData;
|
||||||
|
|
||||||
if (newData.getMaterial() == Material.SPAWNER) {
|
Optional<TileData> t = j.getReplace().getTile(rng, x, y, z, rdata);
|
||||||
Optional<TileData<?>> t = j.getReplace().getTile(rng, x, y, z, rdata);
|
if (t.isPresent()) {
|
||||||
if (t.isPresent()) {
|
tile = t.get();
|
||||||
tile = t.get();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1044,7 +1042,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
spinx, spiny, spinz));
|
spinx, spiny, spinz));
|
||||||
}
|
}
|
||||||
|
|
||||||
KMap<BlockVector, TileData<? extends TileState>> dx = new KMap<>();
|
KMap<BlockVector, TileData> dx = new KMap<>();
|
||||||
|
|
||||||
for (BlockVector i : getStates().keySet()) {
|
for (BlockVector i : getStates().keySet()) {
|
||||||
dx.put(r.rotate(i.clone(), spinx, spiny, spinz), getStates().get(i));
|
dx.put(r.rotate(i.clone(), spinx, spiny, spinz), getStates().get(i));
|
||||||
@ -1062,9 +1060,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
|
|
||||||
if (getStates().containsKey(i)) {
|
if (getStates().containsKey(i)) {
|
||||||
Iris.info(Objects.requireNonNull(states.get(i)).toString());
|
Iris.info(Objects.requireNonNull(states.get(i)).toString());
|
||||||
BlockState st = b.getState();
|
Objects.requireNonNull(getStates().get(i)).toBukkitTry(b);
|
||||||
Objects.requireNonNull(getStates().get(i)).toBukkitTry(st);
|
|
||||||
st.update();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1075,7 +1071,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
b.setBlockData(Objects.requireNonNull(getBlocks().get(i)), false);
|
b.setBlockData(Objects.requireNonNull(getBlocks().get(i)), false);
|
||||||
|
|
||||||
if (getStates().containsKey(i)) {
|
if (getStates().containsKey(i)) {
|
||||||
Objects.requireNonNull(getStates().get(i)).toBukkitTry(b.getState());
|
Objects.requireNonNull(getStates().get(i)).toBukkitTry(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1084,7 +1080,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
return blocks;
|
return blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized KMap<BlockVector, TileData<? extends TileState>> getStates() {
|
public synchronized KMap<BlockVector, TileData> getStates() {
|
||||||
return states;
|
return states;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,120 +0,0 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.volmit.iris.engine.object;
|
|
||||||
|
|
||||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
|
||||||
import com.volmit.iris.util.nbt.tag.ListTag;
|
|
||||||
import lombok.Data;
|
|
||||||
import org.bukkit.DyeColor;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.block.Banner;
|
|
||||||
import org.bukkit.block.banner.Pattern;
|
|
||||||
import org.bukkit.block.banner.PatternType;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class TileBanner implements TileData<Banner> {
|
|
||||||
public static final int id = 2;
|
|
||||||
|
|
||||||
private List<Pattern> patterns = new ArrayList<>();
|
|
||||||
private DyeColor baseColor;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTileId() {
|
|
||||||
return "minecraft:banner";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isApplicable(BlockData data) {
|
|
||||||
return isBanner(data.getMaterial());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBukkit(Banner banner) {
|
|
||||||
banner.setPatterns(patterns);
|
|
||||||
banner.setBaseColor(baseColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fromBukkit(Banner banner) {
|
|
||||||
this.patterns = banner.getPatterns();
|
|
||||||
this.baseColor = banner.getBaseColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("MethodDoesntCallSuperMethod")
|
|
||||||
@Override
|
|
||||||
public TileBanner clone() {
|
|
||||||
TileBanner ts = new TileBanner();
|
|
||||||
ts.setBaseColor(getBaseColor());
|
|
||||||
ts.setPatterns(getPatterns());
|
|
||||||
return ts;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBinary(DataOutputStream out) throws IOException {
|
|
||||||
out.writeShort(id);
|
|
||||||
out.writeByte(baseColor.ordinal());
|
|
||||||
out.writeByte(patterns.size());
|
|
||||||
for (Pattern p : patterns) {
|
|
||||||
out.writeByte(p.getColor().ordinal());
|
|
||||||
out.writeByte(p.getPattern().ordinal());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fromBinary(DataInputStream in) throws IOException {
|
|
||||||
baseColor = DyeColor.values()[in.readByte()];
|
|
||||||
int listSize = in.readByte();
|
|
||||||
patterns = new ArrayList<>();
|
|
||||||
|
|
||||||
for (int i = 0; i < listSize; i++) {
|
|
||||||
DyeColor color = DyeColor.values()[in.readByte()];
|
|
||||||
PatternType type = PatternType.values()[in.readByte()];
|
|
||||||
patterns.add(new Pattern(color, type));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@Override
|
|
||||||
public CompoundTag toNBT(CompoundTag tag) {
|
|
||||||
@SuppressWarnings("unchecked") ListTag<CompoundTag> listTag = (ListTag<CompoundTag>) ListTag.createUnchecked(CompoundTag.class);
|
|
||||||
for (Pattern p : patterns) {
|
|
||||||
CompoundTag pattern = new CompoundTag();
|
|
||||||
pattern.putString("Pattern", p.getPattern().getIdentifier());
|
|
||||||
pattern.putByte("Color", p.getColor().getDyeData());
|
|
||||||
listTag.add(pattern);
|
|
||||||
}
|
|
||||||
tag.put("Patterns", listTag);
|
|
||||||
return tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isBanner(Material material) {
|
|
||||||
return switch (material) {
|
|
||||||
case RED_BANNER, RED_WALL_BANNER, ORANGE_BANNER, ORANGE_WALL_BANNER, YELLOW_BANNER, YELLOW_WALL_BANNER, LIME_BANNER, LIME_WALL_BANNER, GREEN_BANNER, GREEN_WALL_BANNER, CYAN_BANNER, CYAN_WALL_BANNER, LIGHT_BLUE_BANNER, LIGHT_BLUE_WALL_BANNER, BLUE_BANNER, BLUE_WALL_BANNER, PURPLE_BANNER, PURPLE_WALL_BANNER, MAGENTA_BANNER, MAGENTA_WALL_BANNER, PINK_BANNER, PINK_WALL_BANNER, WHITE_BANNER, WHITE_WALL_BANNER, LIGHT_GRAY_BANNER, LIGHT_GRAY_WALL_BANNER, GRAY_BANNER, GRAY_WALL_BANNER, BLACK_BANNER, BLACK_WALL_BANNER, BROWN_BANNER, BROWN_WALL_BANNER ->
|
|
||||||
true;
|
|
||||||
default -> false;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -18,9 +18,14 @@
|
|||||||
|
|
||||||
package com.volmit.iris.engine.object;
|
package com.volmit.iris.engine.object;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.block.TileState;
|
import org.bukkit.block.TileState;
|
||||||
@ -29,73 +34,70 @@ import org.bukkit.block.data.BlockData;
|
|||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
|
|
||||||
|
@Data
|
||||||
@SuppressWarnings("ALL")
|
@SuppressWarnings("ALL")
|
||||||
public interface TileData<T extends TileState> extends Cloneable {
|
@Accessors(chain = true)
|
||||||
|
public class TileData implements Cloneable {
|
||||||
|
private static final Gson gson = new GsonBuilder().disableHtmlEscaping().setLenient().create();
|
||||||
|
|
||||||
static final KList<TileData<? extends TileState>> registry = setup();
|
private Material material = null;
|
||||||
|
private KMap<String, Object> properties = new KMap<>();
|
||||||
|
|
||||||
static KList<TileData<? extends TileState>> setup() {
|
public static boolean setTileState(Block block, TileData data) {
|
||||||
KList<TileData<? extends TileState>> registry = new KList<>();
|
|
||||||
|
|
||||||
registry.add(new TileSign());
|
|
||||||
registry.add(new TileSpawner());
|
|
||||||
registry.add(new TileBanner());
|
|
||||||
|
|
||||||
return registry;
|
|
||||||
}
|
|
||||||
|
|
||||||
static TileData<? extends TileState> read(DataInputStream s) throws IOException {
|
|
||||||
try {
|
|
||||||
int id = s.readShort();
|
|
||||||
@SuppressWarnings("unchecked") TileData<? extends TileState> d = registry.get(id).getClass().getConstructor().newInstance();
|
|
||||||
d.fromBinary(s);
|
|
||||||
return d;
|
|
||||||
} catch (InvocationTargetException | InstantiationException | IllegalAccessException |
|
|
||||||
NoSuchMethodException e) {
|
|
||||||
throw new IOException("Failed to create TileData instance due to missing type registrar!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean setTileState(Block block, TileData<? extends TileState> data) {
|
|
||||||
if (block.getState() instanceof TileState && data.isApplicable(block.getBlockData()))
|
if (block.getState() instanceof TileState && data.isApplicable(block.getBlockData()))
|
||||||
return data.toBukkitTry(block.getState());
|
return data.toBukkitTry(block);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TileData<? extends TileState> getTileState(Block block) {
|
public static TileData getTileState(Block block) {
|
||||||
for (TileData<? extends TileState> i : registry) {
|
if (!INMS.get().hasTile(block.getType()))
|
||||||
BlockData data = block.getBlockData();
|
return null;
|
||||||
|
return new TileData().fromBukkit(block);
|
||||||
if (i.isApplicable(data)) {
|
|
||||||
try {
|
|
||||||
@SuppressWarnings("unchecked") TileData<? extends TileState> s = i.getClass().getConstructor().newInstance();
|
|
||||||
s.fromBukkitTry(block.getState());
|
|
||||||
return s;
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String getTileId();
|
public static TileData read(DataInputStream in) throws IOException {
|
||||||
|
TileData d = new TileData();
|
||||||
|
d.material = Material.matchMaterial(in.readUTF());
|
||||||
|
d.properties = gson.fromJson(in.readUTF(), KMap.class);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
boolean isApplicable(BlockData data);
|
public boolean isApplicable(BlockData data) {
|
||||||
|
return material != null && data.getMaterial() == material;
|
||||||
|
}
|
||||||
|
|
||||||
void toBukkit(T t);
|
public void toBukkit(Block block) {
|
||||||
|
if (material == null) throw new IllegalStateException("Material not set");
|
||||||
|
if (block.getType() != material)
|
||||||
|
throw new IllegalStateException("Material mismatch: " + block.getType() + " vs " + material);
|
||||||
|
INMS.get().deserializeTile(properties, block.getLocation());
|
||||||
|
}
|
||||||
|
|
||||||
void fromBukkit(T t);
|
public TileData fromBukkit(Block block) {
|
||||||
|
if (material != null && block.getType() != material)
|
||||||
|
throw new IllegalStateException("Material mismatch: " + block.getType() + " vs " + material);
|
||||||
|
if (material == null) material = block.getType();
|
||||||
|
properties = INMS.get().serializeTile(block.getLocation());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
default boolean toBukkitTry(BlockState t) {
|
public boolean toBukkitTry(Block block) {
|
||||||
try {
|
try {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
toBukkit((T) t);
|
toBukkit(block);
|
||||||
t.update();
|
return true;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean fromBukkitTry(Block block) {
|
||||||
|
try {
|
||||||
|
//noinspection unchecked
|
||||||
|
fromBukkit(block);
|
||||||
return true;
|
return true;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
@ -105,24 +107,16 @@ public interface TileData<T extends TileState> extends Cloneable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
default boolean fromBukkitTry(BlockState t) {
|
public void toBinary(DataOutputStream out) throws IOException {
|
||||||
try {
|
out.writeUTF(material == null ? "" : material.getKey().toString());
|
||||||
//noinspection unchecked
|
out.writeUTF(gson.toJson(properties));
|
||||||
fromBukkit((T) t);
|
|
||||||
return true;
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CompoundTag toNBT(CompoundTag parent);
|
@Override
|
||||||
|
public TileData clone() {
|
||||||
void toBinary(DataOutputStream out) throws IOException;
|
var clone = new TileData();
|
||||||
|
clone.material = material;
|
||||||
void fromBinary(DataInputStream in) throws IOException;
|
clone.properties = properties.copy(); //TODO make a deep copy
|
||||||
|
return clone;
|
||||||
TileData<T> clone();
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,109 +0,0 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.volmit.iris.engine.object;
|
|
||||||
|
|
||||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
|
||||||
import lombok.Data;
|
|
||||||
import org.bukkit.DyeColor;
|
|
||||||
import org.bukkit.block.Sign;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
import org.bukkit.block.data.type.WallSign;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class TileSign implements TileData<Sign> {
|
|
||||||
public static final int id = 0;
|
|
||||||
private String line1;
|
|
||||||
private String line2;
|
|
||||||
private String line3;
|
|
||||||
private String line4;
|
|
||||||
private DyeColor dyeColor;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTileId() {
|
|
||||||
return "minecraft:sign";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isApplicable(BlockData data) {
|
|
||||||
return data instanceof org.bukkit.block.data.type.Sign || data instanceof WallSign;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBukkit(Sign t) {
|
|
||||||
t.setLine(0, line1);
|
|
||||||
t.setLine(1, line2);
|
|
||||||
t.setLine(2, line3);
|
|
||||||
t.setLine(3, line4);
|
|
||||||
t.setColor(dyeColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fromBukkit(Sign sign) {
|
|
||||||
line1 = sign.getLine(0);
|
|
||||||
line2 = sign.getLine(1);
|
|
||||||
line3 = sign.getLine(2);
|
|
||||||
line4 = sign.getLine(3);
|
|
||||||
dyeColor = sign.getColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("MethodDoesntCallSuperMethod")
|
|
||||||
@Override
|
|
||||||
public TileSign clone() {
|
|
||||||
TileSign ts = new TileSign();
|
|
||||||
ts.setDyeColor(getDyeColor());
|
|
||||||
ts.setLine1(getLine1());
|
|
||||||
ts.setLine2(getLine2());
|
|
||||||
ts.setLine3(getLine3());
|
|
||||||
ts.setLine4(getLine4());
|
|
||||||
return ts;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBinary(DataOutputStream out) throws IOException {
|
|
||||||
out.writeShort(id);
|
|
||||||
out.writeUTF(line1);
|
|
||||||
out.writeUTF(line2);
|
|
||||||
out.writeUTF(line3);
|
|
||||||
out.writeUTF(line4);
|
|
||||||
out.writeByte(dyeColor.ordinal());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fromBinary(DataInputStream in) throws IOException {
|
|
||||||
line1 = in.readUTF();
|
|
||||||
line2 = in.readUTF();
|
|
||||||
line3 = in.readUTF();
|
|
||||||
line4 = in.readUTF();
|
|
||||||
dyeColor = DyeColor.values()[in.readByte()];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompoundTag toNBT(CompoundTag tag) {
|
|
||||||
tag.putString("Text1", line1);
|
|
||||||
tag.putString("Text2", line2);
|
|
||||||
tag.putString("Text3", line3);
|
|
||||||
tag.putString("Text4", line4);
|
|
||||||
tag.putString("Color", dyeColor.name().toLowerCase());
|
|
||||||
return tag;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,91 +0,0 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.volmit.iris.engine.object;
|
|
||||||
|
|
||||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
|
||||||
import com.volmit.iris.util.nbt.tag.ListTag;
|
|
||||||
import lombok.Data;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.block.CreatureSpawner;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class TileSpawner implements TileData<CreatureSpawner> {
|
|
||||||
|
|
||||||
public static final int id = 1;
|
|
||||||
|
|
||||||
private EntityType entityType;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTileId() {
|
|
||||||
return "minecraft:mob_spawner";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isApplicable(BlockData data) {
|
|
||||||
return data.getMaterial() == Material.SPAWNER;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBukkit(CreatureSpawner t) {
|
|
||||||
t.setSpawnedType(entityType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fromBukkit(CreatureSpawner sign) {
|
|
||||||
entityType = sign.getSpawnedType();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("MethodDoesntCallSuperMethod")
|
|
||||||
@Override
|
|
||||||
public TileSpawner clone() {
|
|
||||||
TileSpawner ts = new TileSpawner();
|
|
||||||
ts.setEntityType(getEntityType());
|
|
||||||
return ts;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBinary(DataOutputStream out) throws IOException {
|
|
||||||
out.writeShort(id);
|
|
||||||
out.writeShort(entityType.ordinal());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fromBinary(DataInputStream in) throws IOException {
|
|
||||||
entityType = EntityType.values()[in.readShort()];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompoundTag toNBT(CompoundTag parent) {
|
|
||||||
@SuppressWarnings("unchecked") ListTag<CompoundTag> potentials = (ListTag<CompoundTag>) ListTag.createUnchecked(CompoundTag.class);
|
|
||||||
CompoundTag t = new CompoundTag();
|
|
||||||
CompoundTag ent = new CompoundTag();
|
|
||||||
ent.putString("id", entityType.getKey().toString());
|
|
||||||
t.put("Entity", ent);
|
|
||||||
t.putInt("Weight", 1);
|
|
||||||
potentials.add(t);
|
|
||||||
parent.put("SpawnPotentials", potentials);
|
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.volmit.iris.util.matter;
|
|
||||||
|
|
||||||
import com.volmit.iris.engine.object.TileData;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class TileWrapper {
|
|
||||||
private final TileData<?> data;
|
|
||||||
}
|
|
@ -19,6 +19,7 @@
|
|||||||
package com.volmit.iris.util.matter;
|
package com.volmit.iris.util.matter;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.engine.object.TileData;
|
||||||
import com.volmit.iris.util.data.Cuboid;
|
import com.volmit.iris.util.data.Cuboid;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
@ -33,8 +34,8 @@ public class WorldMatter {
|
|||||||
matter.slice(MatterEntityGroup.class).writeInto(at);
|
matter.slice(MatterEntityGroup.class).writeInto(at);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matter.hasSlice(TileWrapper.class)) {
|
if (matter.hasSlice(TileData.class)) {
|
||||||
matter.slice(TileWrapper.class).writeInto(at);
|
matter.slice(TileData.class).writeInto(at);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ public class WorldMatter {
|
|||||||
s.getHeader().setAuthor(author);
|
s.getHeader().setAuthor(author);
|
||||||
s.slice(BlockData.class).readFrom(c.getLowerNE());
|
s.slice(BlockData.class).readFrom(c.getLowerNE());
|
||||||
s.slice(MatterEntityGroup.class).readFrom(c.getLowerNE());
|
s.slice(MatterEntityGroup.class).readFrom(c.getLowerNE());
|
||||||
s.slice(TileWrapper.class).readFrom(c.getLowerNE());
|
s.slice(TileData.class).readFrom(c.getLowerNE());
|
||||||
s.trimSlices();
|
s.trimSlices();
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
@ -18,13 +18,9 @@
|
|||||||
|
|
||||||
package com.volmit.iris.util.matter.slices;
|
package com.volmit.iris.util.matter.slices;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
|
||||||
import com.volmit.iris.core.nms.INMS;
|
|
||||||
import com.volmit.iris.engine.object.TileData;
|
import com.volmit.iris.engine.object.TileData;
|
||||||
import com.volmit.iris.util.data.palette.Palette;
|
import com.volmit.iris.util.data.palette.Palette;
|
||||||
import com.volmit.iris.util.matter.Sliced;
|
import com.volmit.iris.util.matter.Sliced;
|
||||||
import com.volmit.iris.util.matter.TileWrapper;
|
|
||||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
|
||||||
@ -34,47 +30,28 @@ import java.io.IOException;
|
|||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
@Sliced
|
@Sliced
|
||||||
public class TileMatter extends RawMatter<TileWrapper> {
|
public class TileMatter extends RawMatter<TileData> {
|
||||||
|
|
||||||
public TileMatter() {
|
public TileMatter() {
|
||||||
this(1, 1, 1);
|
this(1, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TileMatter(int width, int height, int depth) {
|
public TileMatter(int width, int height, int depth) {
|
||||||
super(width, height, depth, TileWrapper.class);
|
super(width, height, depth, TileData.class);
|
||||||
registerWriter(World.class, (w, d, x, y, z) -> {
|
registerWriter(World.class, (w, d, x, y, z) -> TileData.setTileState(w.getBlockAt(new Location(w, x, y, z)), d));
|
||||||
CompoundTag tag = commonNbt(x, y, z, d.getData().getTileId());
|
registerReader(World.class, (w, x, y, z) -> TileData.getTileState(w.getBlockAt(new Location(w, x, y, z))));
|
||||||
INMS.get().deserializeTile(d.getData().toNBT(d.getData().toNBT(tag)), new Location(w, x, y, z));
|
|
||||||
Iris.warn("S: " + tag);
|
|
||||||
});
|
|
||||||
registerReader(World.class, (w, x, y, z) -> {
|
|
||||||
TileData d = TileData.getTileState(w.getBlockAt(new Location(w, x, y, z)));
|
|
||||||
if (d == null)
|
|
||||||
return null;
|
|
||||||
return new TileWrapper(d);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Palette<TileWrapper> getGlobalPalette() {
|
public Palette<TileData> getGlobalPalette() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeNode(TileWrapper b, DataOutputStream dos) throws IOException {
|
public void writeNode(TileData b, DataOutputStream dos) throws IOException {
|
||||||
b.getData().toBinary(dos);
|
b.toBinary(dos);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TileWrapper readNode(DataInputStream din) throws IOException {
|
public TileData readNode(DataInputStream din) throws IOException {
|
||||||
return new TileWrapper(TileData.read(din));
|
return TileData.read(din);
|
||||||
}
|
|
||||||
|
|
||||||
private CompoundTag commonNbt(int x, int y, int z, String mobId) {
|
|
||||||
CompoundTag tag = new CompoundTag();
|
|
||||||
tag.putInt("x", x);
|
|
||||||
tag.putInt("y", y);
|
|
||||||
tag.putInt("z", z);
|
|
||||||
tag.putBoolean("keepPacked", false);
|
|
||||||
tag.putString("id", mobId);
|
|
||||||
return tag;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,17 @@ import java.lang.reflect.Method;
|
|||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import com.volmit.iris.core.nms.container.BiomeColor;
|
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.LevelReader;
|
||||||
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
@ -22,6 +28,8 @@ import org.bukkit.craftbukkit.v1_19_R1.CraftChunk;
|
|||||||
import org.bukkit.craftbukkit.v1_19_R1.CraftServer;
|
import org.bukkit.craftbukkit.v1_19_R1.CraftServer;
|
||||||
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
|
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.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.block.data.CraftBlockData;
|
||||||
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftDolphin;
|
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftDolphin;
|
||||||
import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack;
|
||||||
@ -30,6 +38,7 @@ import org.bukkit.entity.Entity;
|
|||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
@ -54,8 +63,6 @@ import net.minecraft.core.BlockPos;
|
|||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.nbt.NbtIo;
|
|
||||||
import net.minecraft.nbt.TagParser;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.entity.EntityType;
|
import net.minecraft.world.entity.EntityType;
|
||||||
@ -127,55 +134,106 @@ public class NMSBinding implements INMSBinding {
|
|||||||
return type.getDeclaredClasses()[ordinal];
|
return type.getDeclaredClasses()[ordinal];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasTile(Material material) {
|
||||||
|
return !CraftBlockState.class.equals(CraftBlockStates.getBlockStateType(material));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasTile(Location l) {
|
public boolean hasTile(Location l) {
|
||||||
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
|
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag serializeTile(Location location) {
|
@SuppressWarnings("unchecked")
|
||||||
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true);
|
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) {
|
if (e == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
net.minecraft.nbt.CompoundTag tag = e.saveWithFullMetadata();
|
net.minecraft.nbt.CompoundTag tag = e.saveWithoutMetadata();
|
||||||
return convert(tag);
|
return (KMap<String, Object>) convertFromTag(tag, 0, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompoundTag convert(net.minecraft.nbt.CompoundTag tag) {
|
@Contract(value = "null, _, _ -> null", pure = true)
|
||||||
try {
|
private Object convertFromTag(net.minecraft.nbt.Tag tag, int depth, int maxDepth) {
|
||||||
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
if (tag == null || depth > maxDepth) return null;
|
||||||
DataOutputStream dos = new DataOutputStream(boas);
|
if (tag instanceof CollectionTag<?> collection) {
|
||||||
tag.write(dos);
|
KList<Object> list = new KList<>();
|
||||||
dos.close();
|
|
||||||
return (CompoundTag) NBTUtil.read(new ByteArrayInputStream(boas.toByteArray()), false).getTag();
|
for (Object i : collection) {
|
||||||
} catch (Throwable ex) {
|
if (i instanceof net.minecraft.nbt.Tag t)
|
||||||
ex.printStackTrace();
|
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;
|
for (String key : compound.getAllKeys()) {
|
||||||
}
|
var child = compound.get(key);
|
||||||
|
if (child == null) continue;
|
||||||
private net.minecraft.nbt.CompoundTag convert(CompoundTag tag) {
|
var value = convertFromTag(child, depth + 1, maxDepth);
|
||||||
try {
|
if (value == null) continue;
|
||||||
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
map.put(key, value);
|
||||||
NBTUtil.write(tag, boas, false);
|
}
|
||||||
DataInputStream din = new DataInputStream(new ByteArrayInputStream(boas.toByteArray()));
|
return map;
|
||||||
net.minecraft.nbt.CompoundTag c = NbtIo.read(din);
|
|
||||||
din.close();
|
|
||||||
return c;
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
if (tag instanceof NumericTag numeric)
|
||||||
return null;
|
return numeric.getAsNumber();
|
||||||
|
return tag.getAsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deserializeTile(CompoundTag c, Location pos) {
|
public void deserializeTile(KMap<String, Object> map, Location pos) {
|
||||||
((CraftWorld) pos.getWorld()).getHandle().getChunkAt(new BlockPos(pos.getBlockX(), 0, pos.getBlockZ())).setBlockEntityNbt(convert(c));
|
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
|
@Override
|
||||||
|
@ -10,11 +10,17 @@ import java.lang.reflect.Method;
|
|||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import com.volmit.iris.core.nms.container.BiomeColor;
|
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.LevelReader;
|
||||||
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
@ -22,6 +28,8 @@ import org.bukkit.craftbukkit.v1_19_R2.CraftChunk;
|
|||||||
import org.bukkit.craftbukkit.v1_19_R2.CraftServer;
|
import org.bukkit.craftbukkit.v1_19_R2.CraftServer;
|
||||||
import org.bukkit.craftbukkit.v1_19_R2.CraftWorld;
|
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.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.block.data.CraftBlockData;
|
||||||
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftDolphin;
|
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftDolphin;
|
||||||
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack;
|
||||||
@ -30,6 +38,7 @@ import org.bukkit.entity.Entity;
|
|||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
@ -55,8 +64,6 @@ import net.minecraft.core.Holder;
|
|||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.nbt.NbtIo;
|
|
||||||
import net.minecraft.nbt.TagParser;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.entity.EntityType;
|
import net.minecraft.world.entity.EntityType;
|
||||||
@ -128,55 +135,106 @@ public class NMSBinding implements INMSBinding {
|
|||||||
return type.getDeclaredClasses()[ordinal];
|
return type.getDeclaredClasses()[ordinal];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasTile(Material material) {
|
||||||
|
return !CraftBlockState.class.equals(CraftBlockStates.getBlockStateType(material));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasTile(Location l) {
|
public boolean hasTile(Location l) {
|
||||||
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
|
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag serializeTile(Location location) {
|
@SuppressWarnings("unchecked")
|
||||||
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true);
|
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) {
|
if (e == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
net.minecraft.nbt.CompoundTag tag = e.saveWithFullMetadata();
|
net.minecraft.nbt.CompoundTag tag = e.saveWithoutMetadata();
|
||||||
return convert(tag);
|
return (KMap<String, Object>) convertFromTag(tag, 0, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompoundTag convert(net.minecraft.nbt.CompoundTag tag) {
|
@Contract(value = "null, _, _ -> null", pure = true)
|
||||||
try {
|
private Object convertFromTag(net.minecraft.nbt.Tag tag, int depth, int maxDepth) {
|
||||||
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
if (tag == null || depth > maxDepth) return null;
|
||||||
DataOutputStream dos = new DataOutputStream(boas);
|
if (tag instanceof CollectionTag<?> collection) {
|
||||||
tag.write(dos);
|
KList<Object> list = new KList<>();
|
||||||
dos.close();
|
|
||||||
return (CompoundTag) NBTUtil.read(new ByteArrayInputStream(boas.toByteArray()), false).getTag();
|
for (Object i : collection) {
|
||||||
} catch (Throwable ex) {
|
if (i instanceof net.minecraft.nbt.Tag t)
|
||||||
ex.printStackTrace();
|
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;
|
for (String key : compound.getAllKeys()) {
|
||||||
}
|
var child = compound.get(key);
|
||||||
|
if (child == null) continue;
|
||||||
private net.minecraft.nbt.CompoundTag convert(CompoundTag tag) {
|
var value = convertFromTag(child, depth + 1, maxDepth);
|
||||||
try {
|
if (value == null) continue;
|
||||||
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
map.put(key, value);
|
||||||
NBTUtil.write(tag, boas, false);
|
}
|
||||||
DataInputStream din = new DataInputStream(new ByteArrayInputStream(boas.toByteArray()));
|
return map;
|
||||||
net.minecraft.nbt.CompoundTag c = NbtIo.read(din);
|
|
||||||
din.close();
|
|
||||||
return c;
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
if (tag instanceof NumericTag numeric)
|
||||||
return null;
|
return numeric.getAsNumber();
|
||||||
|
return tag.getAsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deserializeTile(CompoundTag c, Location pos) {
|
public void deserializeTile(KMap<String, Object> map, Location pos) {
|
||||||
((CraftWorld) pos.getWorld()).getHandle().getChunkAt(new BlockPos(pos.getBlockX(), 0, pos.getBlockZ())).setBlockEntityNbt(convert(c));
|
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
|
@Override
|
||||||
|
@ -10,11 +10,17 @@ import java.lang.reflect.Method;
|
|||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import com.volmit.iris.core.nms.container.BiomeColor;
|
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.LevelReader;
|
||||||
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
@ -22,6 +28,8 @@ import org.bukkit.craftbukkit.v1_19_R3.CraftChunk;
|
|||||||
import org.bukkit.craftbukkit.v1_19_R3.CraftServer;
|
import org.bukkit.craftbukkit.v1_19_R3.CraftServer;
|
||||||
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
|
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.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.block.data.CraftBlockData;
|
||||||
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftDolphin;
|
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftDolphin;
|
||||||
import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack;
|
||||||
@ -30,6 +38,7 @@ import org.bukkit.entity.Entity;
|
|||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
@ -55,8 +64,6 @@ import net.minecraft.core.Holder;
|
|||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.nbt.NbtIo;
|
|
||||||
import net.minecraft.nbt.TagParser;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.entity.EntityType;
|
import net.minecraft.world.entity.EntityType;
|
||||||
@ -129,55 +136,106 @@ public class NMSBinding implements INMSBinding {
|
|||||||
return type.getDeclaredClasses()[ordinal];
|
return type.getDeclaredClasses()[ordinal];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasTile(Material material) {
|
||||||
|
return !CraftBlockState.class.equals(CraftBlockStates.getBlockStateType(material));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasTile(Location l) {
|
public boolean hasTile(Location l) {
|
||||||
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
|
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag serializeTile(Location location) {
|
@SuppressWarnings("unchecked")
|
||||||
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true);
|
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) {
|
if (e == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
net.minecraft.nbt.CompoundTag tag = e.saveWithFullMetadata();
|
net.minecraft.nbt.CompoundTag tag = e.saveWithoutMetadata();
|
||||||
return convert(tag);
|
return (KMap<String, Object>) convertFromTag(tag, 0, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompoundTag convert(net.minecraft.nbt.CompoundTag tag) {
|
@Contract(value = "null, _, _ -> null", pure = true)
|
||||||
try {
|
private Object convertFromTag(net.minecraft.nbt.Tag tag, int depth, int maxDepth) {
|
||||||
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
if (tag == null || depth > maxDepth) return null;
|
||||||
DataOutputStream dos = new DataOutputStream(boas);
|
if (tag instanceof CollectionTag<?> collection) {
|
||||||
tag.write(dos);
|
KList<Object> list = new KList<>();
|
||||||
dos.close();
|
|
||||||
return (CompoundTag) NBTUtil.read(new ByteArrayInputStream(boas.toByteArray()), false).getTag();
|
for (Object i : collection) {
|
||||||
} catch (Throwable ex) {
|
if (i instanceof net.minecraft.nbt.Tag t)
|
||||||
ex.printStackTrace();
|
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;
|
for (String key : compound.getAllKeys()) {
|
||||||
}
|
var child = compound.get(key);
|
||||||
|
if (child == null) continue;
|
||||||
private net.minecraft.nbt.CompoundTag convert(CompoundTag tag) {
|
var value = convertFromTag(child, depth + 1, maxDepth);
|
||||||
try {
|
if (value == null) continue;
|
||||||
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
map.put(key, value);
|
||||||
NBTUtil.write(tag, boas, false);
|
}
|
||||||
DataInputStream din = new DataInputStream(new ByteArrayInputStream(boas.toByteArray()));
|
return map;
|
||||||
net.minecraft.nbt.CompoundTag c = NbtIo.read(din);
|
|
||||||
din.close();
|
|
||||||
return c;
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
if (tag instanceof NumericTag numeric)
|
||||||
return null;
|
return numeric.getAsNumber();
|
||||||
|
return tag.getAsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deserializeTile(CompoundTag c, Location pos) {
|
public void deserializeTile(KMap<String, Object> map, Location pos) {
|
||||||
((CraftWorld) pos.getWorld()).getHandle().getChunkAt(new BlockPos(pos.getBlockX(), 0, pos.getBlockZ())).setBlockEntityNbt(convert(c));
|
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
|
@Override
|
||||||
|
@ -17,20 +17,23 @@ import com.volmit.iris.util.nbt.io.NBTUtil;
|
|||||||
import com.volmit.iris.util.nbt.mca.NBTWorld;
|
import com.volmit.iris.util.nbt.mca.NBTWorld;
|
||||||
import com.volmit.iris.util.nbt.mca.palette.*;
|
import com.volmit.iris.util.nbt.mca.palette.*;
|
||||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
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.Object2IntMap;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.nbt.NbtIo;
|
import net.minecraft.nbt.*;
|
||||||
import net.minecraft.nbt.TagParser;
|
import net.minecraft.nbt.Tag;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.server.commands.data.BlockDataAccessor;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.entity.EntityDimensions;
|
import net.minecraft.world.entity.EntityDimensions;
|
||||||
import net.minecraft.world.level.LevelReader;
|
import net.minecraft.world.level.LevelReader;
|
||||||
import net.minecraft.world.level.biome.BiomeSource;
|
import net.minecraft.world.level.biome.BiomeSource;
|
||||||
import net.minecraft.world.level.block.Block;
|
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.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
@ -44,6 +47,8 @@ import org.bukkit.craftbukkit.v1_20_R1.CraftChunk;
|
|||||||
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
|
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
|
||||||
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld;
|
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.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.block.data.CraftBlockData;
|
||||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftDolphin;
|
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftDolphin;
|
||||||
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
|
||||||
@ -54,6 +59,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent;
|
|||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import sun.misc.Unsafe;
|
import sun.misc.Unsafe;
|
||||||
|
|
||||||
@ -67,6 +73,7 @@ import java.lang.reflect.Method;
|
|||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
@ -132,55 +139,106 @@ public class NMSBinding implements INMSBinding {
|
|||||||
return type.getDeclaredClasses()[ordinal];
|
return type.getDeclaredClasses()[ordinal];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasTile(Material material) {
|
||||||
|
return !CraftBlockState.class.equals(CraftBlockStates.getBlockStateType(material));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasTile(Location l) {
|
public boolean hasTile(Location l) {
|
||||||
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
|
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag serializeTile(Location location) {
|
@SuppressWarnings("unchecked")
|
||||||
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true);
|
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) {
|
if (e == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
net.minecraft.nbt.CompoundTag tag = e.saveWithFullMetadata();
|
net.minecraft.nbt.CompoundTag tag = e.saveWithoutMetadata();
|
||||||
return convert(tag);
|
return (KMap<String, Object>) convertFromTag(tag, 0, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompoundTag convert(net.minecraft.nbt.CompoundTag tag) {
|
@Contract(value = "null, _, _ -> null", pure = true)
|
||||||
try {
|
private Object convertFromTag(net.minecraft.nbt.Tag tag, int depth, int maxDepth) {
|
||||||
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
if (tag == null || depth > maxDepth) return null;
|
||||||
DataOutputStream dos = new DataOutputStream(boas);
|
if (tag instanceof CollectionTag<?> collection) {
|
||||||
tag.write(dos);
|
KList<Object> list = new KList<>();
|
||||||
dos.close();
|
|
||||||
return (CompoundTag) NBTUtil.read(new ByteArrayInputStream(boas.toByteArray()), false).getTag();
|
for (Object i : collection) {
|
||||||
} catch (Throwable ex) {
|
if (i instanceof net.minecraft.nbt.Tag t)
|
||||||
ex.printStackTrace();
|
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;
|
for (String key : compound.getAllKeys()) {
|
||||||
}
|
var child = compound.get(key);
|
||||||
|
if (child == null) continue;
|
||||||
private net.minecraft.nbt.CompoundTag convert(CompoundTag tag) {
|
var value = convertFromTag(child, depth + 1, maxDepth);
|
||||||
try {
|
if (value == null) continue;
|
||||||
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
map.put(key, value);
|
||||||
NBTUtil.write(tag, boas, false);
|
}
|
||||||
DataInputStream din = new DataInputStream(new ByteArrayInputStream(boas.toByteArray()));
|
return map;
|
||||||
net.minecraft.nbt.CompoundTag c = NbtIo.read(din);
|
|
||||||
din.close();
|
|
||||||
return c;
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
if (tag instanceof NumericTag numeric)
|
||||||
return null;
|
return numeric.getAsNumber();
|
||||||
|
return tag.getAsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deserializeTile(CompoundTag c, Location pos) {
|
public void deserializeTile(KMap<String, Object> map, Location pos) {
|
||||||
((CraftWorld) pos.getWorld()).getHandle().getChunkAt(new BlockPos(pos.getBlockX(), 0, pos.getBlockZ())).setBlockEntityNbt(convert(c));
|
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
|
@Override
|
||||||
|
@ -10,17 +10,25 @@ import java.lang.reflect.Method;
|
|||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import com.volmit.iris.core.nms.container.BiomeColor;
|
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.LevelReader;
|
||||||
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.craftbukkit.v1_20_R2.CraftChunk;
|
import org.bukkit.craftbukkit.v1_20_R2.CraftChunk;
|
||||||
import org.bukkit.craftbukkit.v1_20_R2.CraftServer;
|
import org.bukkit.craftbukkit.v1_20_R2.CraftServer;
|
||||||
import org.bukkit.craftbukkit.v1_20_R2.CraftWorld;
|
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.block.data.CraftBlockData;
|
||||||
import org.bukkit.craftbukkit.v1_20_R2.entity.CraftDolphin;
|
import org.bukkit.craftbukkit.v1_20_R2.entity.CraftDolphin;
|
||||||
import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack;
|
||||||
@ -30,6 +38,7 @@ import org.bukkit.entity.Entity;
|
|||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
@ -55,8 +64,6 @@ import net.minecraft.core.Holder;
|
|||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.core.registries.Registries;
|
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.ResourceKey;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
@ -130,55 +137,106 @@ public class NMSBinding implements INMSBinding {
|
|||||||
return type.getDeclaredClasses()[ordinal];
|
return type.getDeclaredClasses()[ordinal];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasTile(Material material) {
|
||||||
|
return !CraftBlockState.class.equals(CraftBlockStates.getBlockStateType(material));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasTile(Location l) {
|
public boolean hasTile(Location l) {
|
||||||
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
|
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag serializeTile(Location location) {
|
@SuppressWarnings("unchecked")
|
||||||
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true);
|
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) {
|
if (e == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
net.minecraft.nbt.CompoundTag tag = e.saveWithFullMetadata();
|
net.minecraft.nbt.CompoundTag tag = e.saveWithoutMetadata();
|
||||||
return convert(tag);
|
return (KMap<String, Object>) convertFromTag(tag, 0, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompoundTag convert(net.minecraft.nbt.CompoundTag tag) {
|
@Contract(value = "null, _, _ -> null", pure = true)
|
||||||
try {
|
private Object convertFromTag(net.minecraft.nbt.Tag tag, int depth, int maxDepth) {
|
||||||
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
if (tag == null || depth > maxDepth) return null;
|
||||||
DataOutputStream dos = new DataOutputStream(boas);
|
if (tag instanceof CollectionTag<?> collection) {
|
||||||
tag.write(dos);
|
KList<Object> list = new KList<>();
|
||||||
dos.close();
|
|
||||||
return (CompoundTag) NBTUtil.read(new ByteArrayInputStream(boas.toByteArray()), false).getTag();
|
for (Object i : collection) {
|
||||||
} catch (Throwable ex) {
|
if (i instanceof net.minecraft.nbt.Tag t)
|
||||||
ex.printStackTrace();
|
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;
|
for (String key : compound.getAllKeys()) {
|
||||||
}
|
var child = compound.get(key);
|
||||||
|
if (child == null) continue;
|
||||||
private net.minecraft.nbt.CompoundTag convert(CompoundTag tag) {
|
var value = convertFromTag(child, depth + 1, maxDepth);
|
||||||
try {
|
if (value == null) continue;
|
||||||
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
map.put(key, value);
|
||||||
NBTUtil.write(tag, boas, false);
|
}
|
||||||
DataInputStream din = new DataInputStream(new ByteArrayInputStream(boas.toByteArray()));
|
return map;
|
||||||
net.minecraft.nbt.CompoundTag c = NbtIo.read(din);
|
|
||||||
din.close();
|
|
||||||
return c;
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
if (tag instanceof NumericTag numeric)
|
||||||
return null;
|
return numeric.getAsNumber();
|
||||||
|
return tag.getAsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deserializeTile(CompoundTag c, Location pos) {
|
public void deserializeTile(KMap<String, Object> map, Location pos) {
|
||||||
((CraftWorld) pos.getWorld()).getHandle().getChunkAt(new BlockPos(pos.getBlockX(), 0, pos.getBlockZ())).setBlockEntityNbt(convert(c));
|
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
|
@Override
|
||||||
|
@ -10,17 +10,25 @@ import java.lang.reflect.Method;
|
|||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import com.volmit.iris.core.nms.container.BiomeColor;
|
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.LevelReader;
|
||||||
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.craftbukkit.v1_20_R3.CraftChunk;
|
import org.bukkit.craftbukkit.v1_20_R3.CraftChunk;
|
||||||
import org.bukkit.craftbukkit.v1_20_R3.CraftServer;
|
import org.bukkit.craftbukkit.v1_20_R3.CraftServer;
|
||||||
import org.bukkit.craftbukkit.v1_20_R3.CraftWorld;
|
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.block.data.CraftBlockData;
|
||||||
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftDolphin;
|
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftDolphin;
|
||||||
import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack;
|
||||||
@ -30,6 +38,7 @@ import org.bukkit.entity.Entity;
|
|||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
@ -55,8 +64,6 @@ import net.minecraft.core.Holder;
|
|||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.core.registries.Registries;
|
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.ResourceKey;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
@ -130,55 +137,106 @@ public class NMSBinding implements INMSBinding {
|
|||||||
return type.getDeclaredClasses()[ordinal];
|
return type.getDeclaredClasses()[ordinal];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasTile(Material material) {
|
||||||
|
return !CraftBlockState.class.equals(CraftBlockStates.getBlockStateType(material));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasTile(Location l) {
|
public boolean hasTile(Location l) {
|
||||||
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
|
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag serializeTile(Location location) {
|
@SuppressWarnings("unchecked")
|
||||||
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true);
|
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) {
|
if (e == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
net.minecraft.nbt.CompoundTag tag = e.saveWithFullMetadata();
|
net.minecraft.nbt.CompoundTag tag = e.saveWithoutMetadata();
|
||||||
return convert(tag);
|
return (KMap<String, Object>) convertFromTag(tag, 0, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompoundTag convert(net.minecraft.nbt.CompoundTag tag) {
|
@Contract(value = "null, _, _ -> null", pure = true)
|
||||||
try {
|
private Object convertFromTag(net.minecraft.nbt.Tag tag, int depth, int maxDepth) {
|
||||||
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
if (tag == null || depth > maxDepth) return null;
|
||||||
DataOutputStream dos = new DataOutputStream(boas);
|
if (tag instanceof CollectionTag<?> collection) {
|
||||||
tag.write(dos);
|
KList<Object> list = new KList<>();
|
||||||
dos.close();
|
|
||||||
return (CompoundTag) NBTUtil.read(new ByteArrayInputStream(boas.toByteArray()), false).getTag();
|
for (Object i : collection) {
|
||||||
} catch (Throwable ex) {
|
if (i instanceof net.minecraft.nbt.Tag t)
|
||||||
ex.printStackTrace();
|
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;
|
for (String key : compound.getAllKeys()) {
|
||||||
}
|
var child = compound.get(key);
|
||||||
|
if (child == null) continue;
|
||||||
private net.minecraft.nbt.CompoundTag convert(CompoundTag tag) {
|
var value = convertFromTag(child, depth + 1, maxDepth);
|
||||||
try {
|
if (value == null) continue;
|
||||||
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
map.put(key, value);
|
||||||
NBTUtil.write(tag, boas, false);
|
}
|
||||||
DataInputStream din = new DataInputStream(new ByteArrayInputStream(boas.toByteArray()));
|
return map;
|
||||||
net.minecraft.nbt.CompoundTag c = NbtIo.read(din);
|
|
||||||
din.close();
|
|
||||||
return c;
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
if (tag instanceof NumericTag numeric)
|
||||||
return null;
|
return numeric.getAsNumber();
|
||||||
|
return tag.getAsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deserializeTile(CompoundTag c, Location pos) {
|
public void deserializeTile(KMap<String, Object> map, Location pos) {
|
||||||
((CraftWorld) pos.getWorld()).getHandle().getChunkAt(new BlockPos(pos.getBlockX(), 0, pos.getBlockZ())).setBlockEntityNbt(convert(c));
|
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
|
@Override
|
||||||
|
@ -1,24 +1,35 @@
|
|||||||
package com.volmit.iris.core.nms.v1_20_R4;
|
package com.volmit.iris.core.nms.v1_20_R4;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.Iterator;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Vector;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import com.volmit.iris.core.nms.container.BiomeColor;
|
import com.volmit.iris.core.nms.container.BiomeColor;
|
||||||
import com.volmit.iris.core.nms.datapack.DataVersion;
|
import com.volmit.iris.core.nms.datapack.DataVersion;
|
||||||
|
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.core.component.DataComponents;
|
||||||
|
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.item.component.CustomData;
|
||||||
import net.minecraft.world.level.LevelReader;
|
import net.minecraft.world.level.LevelReader;
|
||||||
|
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.chunk.status.ChunkStatus;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
@ -26,6 +37,9 @@ import org.bukkit.block.data.BlockData;
|
|||||||
import org.bukkit.craftbukkit.v1_20_R4.CraftChunk;
|
import org.bukkit.craftbukkit.v1_20_R4.CraftChunk;
|
||||||
import org.bukkit.craftbukkit.v1_20_R4.CraftServer;
|
import org.bukkit.craftbukkit.v1_20_R4.CraftServer;
|
||||||
import org.bukkit.craftbukkit.v1_20_R4.CraftWorld;
|
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.block.data.CraftBlockData;
|
||||||
import org.bukkit.craftbukkit.v1_20_R4.entity.CraftDolphin;
|
import org.bukkit.craftbukkit.v1_20_R4.entity.CraftDolphin;
|
||||||
import org.bukkit.craftbukkit.v1_20_R4.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.v1_20_R4.inventory.CraftItemStack;
|
||||||
@ -35,6 +49,7 @@ import org.bukkit.entity.Entity;
|
|||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
@ -49,19 +64,11 @@ import com.volmit.iris.util.json.JSONObject;
|
|||||||
import com.volmit.iris.util.mantle.Mantle;
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
import com.volmit.iris.util.math.Vector3d;
|
import com.volmit.iris.util.math.Vector3d;
|
||||||
import com.volmit.iris.util.matter.MatterBiomeInject;
|
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.NBTWorld;
|
||||||
import com.volmit.iris.util.nbt.mca.palette.*;
|
import com.volmit.iris.util.nbt.mca.palette.*;
|
||||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
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.core.registries.Registries;
|
||||||
import net.minecraft.nbt.NbtIo;
|
|
||||||
import net.minecraft.nbt.TagParser;
|
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
@ -134,55 +141,109 @@ public class NMSBinding implements INMSBinding {
|
|||||||
return type.getDeclaredClasses()[ordinal];
|
return type.getDeclaredClasses()[ordinal];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasTile(Material material) {
|
||||||
|
return !CraftBlockState.class.equals(CraftBlockStates.getBlockStateType(material));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasTile(Location l) {
|
public boolean hasTile(Location l) {
|
||||||
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
|
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag serializeTile(Location location) {
|
@SuppressWarnings("unchecked")
|
||||||
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true);
|
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) {
|
if (e == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
net.minecraft.nbt.CompoundTag tag = e.saveWithFullMetadata(registry());
|
net.minecraft.nbt.CompoundTag tag = e.saveWithoutMetadata(registry());
|
||||||
return convert(tag);
|
return (KMap<String, Object>) convertFromTag(tag, 0, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompoundTag convert(net.minecraft.nbt.CompoundTag tag) {
|
@Contract(value = "null, _, _ -> null", pure = true)
|
||||||
try {
|
private Object convertFromTag(net.minecraft.nbt.Tag tag, int depth, int maxDepth) {
|
||||||
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
if (tag == null || depth > maxDepth) return null;
|
||||||
DataOutputStream dos = new DataOutputStream(boas);
|
return switch (tag) {
|
||||||
tag.write(dos);
|
case CollectionTag<?> collection -> {
|
||||||
dos.close();
|
KList<Object> list = new KList<>();
|
||||||
return (CompoundTag) NBTUtil.read(new ByteArrayInputStream(boas.toByteArray()), false).getTag();
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
for (String key : compound.getAllKeys()) {
|
||||||
try {
|
var child = compound.get(key);
|
||||||
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
if (child == null) continue;
|
||||||
NBTUtil.write(tag, boas, false);
|
var value = convertFromTag(child, depth + 1, maxDepth);
|
||||||
DataInputStream din = new DataInputStream(new ByteArrayInputStream(boas.toByteArray()));
|
if (value == null) continue;
|
||||||
net.minecraft.nbt.CompoundTag c = NbtIo.read(din);
|
map.put(key, value);
|
||||||
din.close();
|
}
|
||||||
return c;
|
yield map;
|
||||||
} catch (Throwable e) {
|
}
|
||||||
e.printStackTrace();
|
case NumericTag numeric -> numeric.getAsNumber();
|
||||||
}
|
default -> tag.getAsString();
|
||||||
|
};
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deserializeTile(CompoundTag c, Location pos) {
|
public void deserializeTile(KMap<String, Object> map, Location pos) {
|
||||||
((CraftWorld) pos.getWorld()).getHandle().getChunkAt(new BlockPos(pos.getBlockX(), 0, pos.getBlockZ())).setBlockEntityNbt(convert(c));
|
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
|
@Override
|
||||||
@ -422,13 +483,13 @@ public class NMSBinding implements INMSBinding {
|
|||||||
@Override
|
@Override
|
||||||
public MCAPaletteAccess createPalette() {
|
public MCAPaletteAccess createPalette() {
|
||||||
MCAIdMapper<BlockState> registry = registryCache.aquireNasty(() -> {
|
MCAIdMapper<BlockState> registry = registryCache.aquireNasty(() -> {
|
||||||
Field cf = net.minecraft.core.IdMapper.class.getDeclaredField("tToId");
|
Field cf = IdMapper.class.getDeclaredField("tToId");
|
||||||
Field df = net.minecraft.core.IdMapper.class.getDeclaredField("idToT");
|
Field df = IdMapper.class.getDeclaredField("idToT");
|
||||||
Field bf = net.minecraft.core.IdMapper.class.getDeclaredField("nextId");
|
Field bf = IdMapper.class.getDeclaredField("nextId");
|
||||||
cf.setAccessible(true);
|
cf.setAccessible(true);
|
||||||
df.setAccessible(true);
|
df.setAccessible(true);
|
||||||
bf.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);
|
int b = bf.getInt(blockData);
|
||||||
Object2IntMap<BlockState> c = (Object2IntMap<BlockState>) cf.get(blockData);
|
Object2IntMap<BlockState> c = (Object2IntMap<BlockState>) cf.get(blockData);
|
||||||
List<BlockState> d = (List<BlockState>) df.get(blockData);
|
List<BlockState> d = (List<BlockState>) df.get(blockData);
|
||||||
|
@ -8,18 +8,20 @@ import java.io.DataOutputStream;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.Iterator;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Vector;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import com.volmit.iris.core.nms.container.BiomeColor;
|
import com.volmit.iris.core.nms.container.BiomeColor;
|
||||||
import com.volmit.iris.core.nms.datapack.DataVersion;
|
import com.volmit.iris.core.nms.datapack.DataVersion;
|
||||||
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import net.minecraft.core.component.DataComponents;
|
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.level.ChunkMap;
|
import net.minecraft.server.level.ChunkMap;
|
||||||
import net.minecraft.world.item.component.CustomData;
|
import net.minecraft.world.item.component.CustomData;
|
||||||
import net.minecraft.world.level.LevelReader;
|
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.ChunkStatus;
|
||||||
import net.minecraft.world.level.chunk.status.WorldGenContext;
|
import net.minecraft.world.level.chunk.status.WorldGenContext;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
@ -28,6 +30,8 @@ import org.bukkit.block.data.BlockData;
|
|||||||
import org.bukkit.craftbukkit.v1_21_R1.CraftChunk;
|
import org.bukkit.craftbukkit.v1_21_R1.CraftChunk;
|
||||||
import org.bukkit.craftbukkit.v1_21_R1.CraftServer;
|
import org.bukkit.craftbukkit.v1_21_R1.CraftServer;
|
||||||
import org.bukkit.craftbukkit.v1_21_R1.CraftWorld;
|
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.block.data.CraftBlockData;
|
||||||
import org.bukkit.craftbukkit.v1_21_R1.entity.CraftDolphin;
|
import org.bukkit.craftbukkit.v1_21_R1.entity.CraftDolphin;
|
||||||
import org.bukkit.craftbukkit.v1_21_R1.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.v1_21_R1.inventory.CraftItemStack;
|
||||||
@ -37,6 +41,7 @@ import org.bukkit.entity.Entity;
|
|||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
@ -62,8 +67,6 @@ import net.minecraft.core.Holder;
|
|||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.core.registries.Registries;
|
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.ResourceKey;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
@ -136,55 +139,109 @@ public class NMSBinding implements INMSBinding {
|
|||||||
return type.getDeclaredClasses()[ordinal];
|
return type.getDeclaredClasses()[ordinal];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasTile(Material material) {
|
||||||
|
return !CraftBlockState.class.equals(CraftBlockStates.getBlockStateType(material));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasTile(Location l) {
|
public boolean hasTile(Location l) {
|
||||||
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
|
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag serializeTile(Location location) {
|
@SuppressWarnings("unchecked")
|
||||||
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true);
|
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) {
|
if (e == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
net.minecraft.nbt.CompoundTag tag = e.saveWithFullMetadata(registry());
|
net.minecraft.nbt.CompoundTag tag = e.saveWithoutMetadata(registry());
|
||||||
return convert(tag);
|
return (KMap<String, Object>) convertFromTag(tag, 0, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompoundTag convert(net.minecraft.nbt.CompoundTag tag) {
|
@Contract(value = "null, _, _ -> null", pure = true)
|
||||||
try {
|
private Object convertFromTag(net.minecraft.nbt.Tag tag, int depth, int maxDepth) {
|
||||||
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
if (tag == null || depth > maxDepth) return null;
|
||||||
DataOutputStream dos = new DataOutputStream(boas);
|
return switch (tag) {
|
||||||
tag.write(dos);
|
case CollectionTag<?> collection -> {
|
||||||
dos.close();
|
KList<Object> list = new KList<>();
|
||||||
return (CompoundTag) NBTUtil.read(new ByteArrayInputStream(boas.toByteArray()), false).getTag();
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
for (String key : compound.getAllKeys()) {
|
||||||
try {
|
var child = compound.get(key);
|
||||||
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
if (child == null) continue;
|
||||||
NBTUtil.write(tag, boas, false);
|
var value = convertFromTag(child, depth + 1, maxDepth);
|
||||||
DataInputStream din = new DataInputStream(new ByteArrayInputStream(boas.toByteArray()));
|
if (value == null) continue;
|
||||||
net.minecraft.nbt.CompoundTag c = NbtIo.read(din);
|
map.put(key, value);
|
||||||
din.close();
|
}
|
||||||
return c;
|
yield map;
|
||||||
} catch (Throwable e) {
|
}
|
||||||
e.printStackTrace();
|
case NumericTag numeric -> numeric.getAsNumber();
|
||||||
}
|
default -> tag.getAsString();
|
||||||
|
};
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deserializeTile(CompoundTag c, Location pos) {
|
public void deserializeTile(KMap<String, Object> map, Location pos) {
|
||||||
((CraftWorld) pos.getWorld()).getHandle().getChunkAt(new BlockPos(pos.getBlockX(), 0, pos.getBlockZ())).setBlockEntityNbt(convert(c));
|
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
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user