add legacy tile data reader

This commit is contained in:
Julian Krings 2024-11-25 20:05:21 +01:00
parent 623fd45ef4
commit cacef8c8fc
6 changed files with 68 additions and 13 deletions

View File

@ -376,9 +376,11 @@ public class CommandObject implements DecreeExecutor {
@Param(description = "The file to store it in, can use / for subfolders")
String name,
@Param(description = "Overwrite existing object files", defaultValue = "false", aliases = "force")
boolean overwrite
boolean overwrite,
@Param(description = "Use legacy TileState serialization if possible", defaultValue = "true")
boolean legacy
) {
IrisObject o = WandSVC.createSchematic(player());
IrisObject o = WandSVC.createSchematic(player(), legacy);
if (o == null) {
sender().sendMessage(C.YELLOW + "You need to hold your wand!");

View File

@ -76,7 +76,7 @@ public class WandSVC implements IrisService {
* @param p The wand player
* @return The new object
*/
public static IrisObject createSchematic(Player p) {
public static IrisObject createSchematic(Player p, boolean legacy) {
if (!isHoldingWand(p)) {
return null;
}
@ -132,7 +132,7 @@ public class WandSVC implements IrisService {
continue;
BlockVector bv = b.getLocation().subtract(c.getLowerNE().toVector()).toVector().toBlockVector();
s.setUnsigned(bv.getBlockX(), bv.getBlockY(), bv.getBlockZ(), b);
s.setUnsigned(bv.getBlockX(), bv.getBlockY(), bv.getBlockZ(), b, legacy);
} finally {
i++;
}

View File

@ -562,7 +562,7 @@ public class IrisObject extends IrisRegistrant {
}
}
public void setUnsigned(int x, int y, int z, Block block) {
public void setUnsigned(int x, int y, int z, Block block, boolean legacy) {
BlockVector v = getSigned(x, y, z);
if (block == null) {
@ -571,7 +571,7 @@ public class IrisObject extends IrisRegistrant {
} else {
BlockData data = block.getBlockData();
getBlocks().put(v, data);
TileData state = TileData.getTileState(block);
TileData state = TileData.getTileState(block, legacy);
if (state != null) {
Iris.debug("Saved State " + v);
getStates().put(v, state);

View File

@ -1,8 +1,10 @@
package com.volmit.iris.engine.object;
import com.volmit.iris.core.nms.container.Pair;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.scheduling.J;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.ToString;
@ -15,6 +17,7 @@ import org.bukkit.block.banner.Pattern;
import org.bukkit.block.banner.PatternType;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.EntityType;
import org.jetbrains.annotations.Nullable;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@ -24,10 +27,10 @@ import java.util.Map;
@ToString
@EqualsAndHashCode(callSuper = false)
public class LegacyTileData extends TileData {
private static final Map<Integer, IOFunction<DataInputStream, Handler>> legacy = Map.of(
0, SignHandler::new,
1, SpawnerHandler::new,
2, BannerHandler::new);
private static final Map<Integer, Pair<Builder, IOFunction<DataInputStream, Handler>>> legacy = Map.of(
0, new Pair<>(SignHandler::fromBukkit, SignHandler::new),
1, new Pair<>(SpawnerHandler::fromBukkit, SpawnerHandler::new),
2, new Pair<>(BannerHandler::fromBukkit, BannerHandler::new));
private final int id;
private final Handler handler;
@ -36,7 +39,24 @@ public class LegacyTileData extends TileData {
var factory = legacy.get(id);
if (factory == null)
throw new IOException("Unknown tile type: " + id);
handler = factory.apply(in);
handler = factory.getB().apply(in);
}
private LegacyTileData(int id, Handler handler) {
this.id = id;
this.handler = handler;
}
@Nullable
public static LegacyTileData fromBukkit(@NonNull BlockState tileState) {
var type = tileState.getType();
for (var id : legacy.keySet()) {
var factory = legacy.get(id);
var handler = factory.getA().apply(tileState, type);
if (handler != null)
return new LegacyTileData(id, handler);
}
return null;
}
@Override
@ -77,8 +97,14 @@ public class LegacyTileData extends TileData {
void toBukkit(Block block);
}
@FunctionalInterface
private interface Builder {
@Nullable Handler apply(@NonNull BlockState blockState, @NonNull Material type);
}
@ToString
@EqualsAndHashCode
@AllArgsConstructor
private static class SignHandler implements Handler {
private final String line1;
private final String line2;
@ -94,6 +120,13 @@ public class LegacyTileData extends TileData {
dyeColor = DyeColor.values()[in.readByte()];
}
@SuppressWarnings("deprecation")
private static SignHandler fromBukkit(BlockState blockState, Material type) {
if (!Tag.ALL_SIGNS.isTagged(type) || !(blockState instanceof Sign sign))
return null;
return new SignHandler(sign.getLine(0), sign.getLine(1), sign.getLine(2), sign.getLine(3), sign.getColor());
}
@Override
public Material getMaterial() {
return Material.OAK_SIGN;
@ -126,6 +159,7 @@ public class LegacyTileData extends TileData {
}
@ToString
@EqualsAndHashCode
@AllArgsConstructor
private static class SpawnerHandler implements Handler {
private final EntityType type;
@ -133,6 +167,12 @@ public class LegacyTileData extends TileData {
type = EntityType.values()[in.readShort()];
}
private static SpawnerHandler fromBukkit(BlockState blockState, Material material) {
if (material != Material.SPAWNER || !(blockState instanceof CreatureSpawner spawner))
return null;
return new SpawnerHandler(spawner.getSpawnedType());
}
@Override
public Material getMaterial() {
return Material.SPAWNER;
@ -157,6 +197,7 @@ public class LegacyTileData extends TileData {
}
@ToString
@EqualsAndHashCode
@AllArgsConstructor
private static class BannerHandler implements Handler {
private final KList<Pattern> patterns;
private final DyeColor baseColor;
@ -172,6 +213,12 @@ public class LegacyTileData extends TileData {
}
}
private static BannerHandler fromBukkit(BlockState blockState, Material type) {
if (!Tag.BANNERS.isTagged(type) || !(blockState instanceof Banner banner))
return null;
return new BannerHandler(new KList<>(banner.getPatterns()), banner.getBaseColor());
}
@Override
public Material getMaterial() {
return Material.WHITE_BANNER;

View File

@ -53,9 +53,15 @@ public class TileData implements Cloneable {
return false;
}
public static TileData getTileState(Block block) {
public static TileData getTileState(Block block, boolean useLegacy) {
if (!INMS.get().hasTile(block.getType()))
return null;
if (useLegacy) {
var legacy = LegacyTileData.fromBukkit(block.getState());
if (legacy != null)
return legacy;
}
return new TileData().fromBukkit(block);
}

View File

@ -40,7 +40,7 @@ public class TileMatter extends RawMatter<TileWrapper> {
public TileMatter(int width, int height, int depth) {
super(width, height, depth, TileWrapper.class);
registerWriter(World.class, (w, d, x, y, z) -> TileData.setTileState(w.getBlockAt(new Location(w, x, y, z)), d.getData()));
registerReader(World.class, (w, x, y, z) -> new TileWrapper(TileData.getTileState(w.getBlockAt(new Location(w, x, y, z)))));
registerReader(World.class, (w, x, y, z) -> new TileWrapper(TileData.getTileState(w.getBlockAt(new Location(w, x, y, z)), false)));
}
@Override