diff --git a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/players/PaperOffPlayer.java b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/players/PaperOffPlayer.java index 7ce8ff6..8d8bfff 100644 --- a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/players/PaperOffPlayer.java +++ b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/players/PaperOffPlayer.java @@ -7,6 +7,7 @@ import fr.pandacube.lib.paper.reflect.wrapper.dataconverter.MCTypeRegistry; import fr.pandacube.lib.paper.reflect.wrapper.minecraft.SharedConstants; import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.CompoundTag; import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.NbtIo; +import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.Tag; import fr.pandacube.lib.paper.util.PlayerDataWrapper; import fr.pandacube.lib.paper.world.WorldUtil; import fr.pandacube.lib.players.standalone.AbstractOffPlayer; @@ -166,8 +167,13 @@ public interface PaperOffPlayer extends AbstractOffPlayer { .playerIo() .getPlayerData(getUniqueId().toString()); if (convertTag) { - int i = data.contains("DataVersion", 3) ? data.getInt("DataVersion") : -1; - data = MCDataConverter.convertTag(MCTypeRegistry.PLAYER(), data, i, SharedConstants.getCurrentVersion().getDataVersion().getVersion()); + int srcVersion = data.contains("DataVersion", Tag.TAG_ANY_NUMERIC()) ? data.getInt("DataVersion") : -1; + int destVersion = SharedConstants.getCurrentVersion().getDataVersion().getVersion(); + try { + data = MCDataConverter.convertTag(MCTypeRegistry.PLAYER(), data, srcVersion, destVersion); + } catch (Exception e) { + throw new RuntimeException("Unable to upgrade data format of player " + getName() + " (" + getUniqueId() + ") from version " + destVersion + " to " + destVersion); + } } return data; } @@ -196,7 +202,7 @@ public interface PaperOffPlayer extends AbstractOffPlayer { File old = getPlayerDataFile(true); old.delete(); Files.move(file.toPath(), old.toPath()); - NbtIo.writeCompressed(data.data, file.toPath()); + NbtIo.writeCompressed(data.data(), file.toPath()); } /** diff --git a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/minecraft/nbt/Tag.java b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/minecraft/nbt/Tag.java index 26d6697..7ad5966 100644 --- a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/minecraft/nbt/Tag.java +++ b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/minecraft/nbt/Tag.java @@ -3,6 +3,7 @@ package fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt; import static fr.pandacube.lib.util.ThrowableUtil.wrapEx; import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx; +import fr.pandacube.lib.reflect.ReflectField; import fr.pandacube.lib.reflect.ReflectMethod; import fr.pandacube.lib.paper.reflect.NMSReflect; import fr.pandacube.lib.paper.reflect.NMSReflect.ClassMapping; @@ -14,12 +15,26 @@ import fr.pandacube.lib.reflect.wrapper.ReflectWrapperI; public interface Tag extends ReflectWrapperI { ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.nbt.Tag")); ReflectMethod getAsString = wrapEx(() -> MAPPING.mojMethod("getAsString")); + ReflectField TAG_LIST = wrapEx(() -> MAPPING.mojField("TAG_LIST")); + ReflectField TAG_COMPOUND = wrapEx(() -> MAPPING.mojField("TAG_COMPOUND")); + ReflectField TAG_ANY_NUMERIC = wrapEx(() -> MAPPING.mojField("TAG_ANY_NUMERIC")); default String getAsString() { return wrapReflectEx(() -> (String) getAsString.invoke(__getRuntimeInstance())); } - + + static byte TAG_LIST() { + return wrapReflectEx(() -> (byte) TAG_LIST.getStaticValue()); + } + + static byte TAG_COMPOUND() { + return wrapReflectEx(() -> (byte) TAG_COMPOUND.getStaticValue()); + } + + static byte TAG_ANY_NUMERIC() { + return wrapReflectEx(() -> (byte) TAG_ANY_NUMERIC.getStaticValue()); + } class __concrete extends ReflectWrapper implements Tag { diff --git a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/util/PlayerDataWrapper.java b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/util/PlayerDataWrapper.java index ada5c75..bc35784 100644 --- a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/util/PlayerDataWrapper.java +++ b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/util/PlayerDataWrapper.java @@ -4,6 +4,7 @@ import com.google.common.base.Preconditions; import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.CraftItemStack; import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.CompoundTag; import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.ListTag; +import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.Tag; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.HumanEntity; @@ -23,13 +24,10 @@ import java.util.function.IntUnaryOperator; /** * A wrapper to easily manipulate vanilla player data. + * + * @param data The data as they are stored in the player file. */ -public class PlayerDataWrapper { - - /** - * The data as they are stored in the player file. - */ - public final CompoundTag data; +public record PlayerDataWrapper(CompoundTag data) { /** * Creates a new wrapper for the provided player data. @@ -86,8 +84,6 @@ public class PlayerDataWrapper { } - - public Inventory getEnderChest() { return getBukkitInventory("EnderItems", InventoryType.ENDER_CHEST, IntUnaryOperator.identity()); } @@ -97,7 +93,6 @@ public class PlayerDataWrapper { } - private Inventory getBukkitInventory(String nbtKey, InventoryType bukkitType, IntUnaryOperator nbtToBukkitSlotConverter) { Map stacks = getRawInventoryContent(nbtKey); Inventory inv = Bukkit.createInventory(null, bukkitType); @@ -110,9 +105,9 @@ public class PlayerDataWrapper { } private Map getRawInventoryContent(String key) { - if (!data.contains(key, 9)) // type 9 is list + if (!data.contains(key, Tag.TAG_LIST())) return Map.of(); - ListTag list = data.getList(key, 10); // type of list element 10 is CompoundTag + ListTag list = data.getList(key, Tag.TAG_COMPOUND()); if (list == null) return Map.of(); @@ -129,9 +124,6 @@ public class PlayerDataWrapper { } - - - private void setBukkitInventory(String nbtKey, Inventory inv, IntUnaryOperator bukkitToNBTSlotConverter) { Map stacks = new TreeMap<>(); if (inv == null) { @@ -168,12 +160,6 @@ public class PlayerDataWrapper { } - - - - - - private int getHeldItemSlot() { if (!data.contains("SelectedItemSlot")) return 0; @@ -185,9 +171,6 @@ public class PlayerDataWrapper { } - - - public int getScore() { if (!data.contains("Score")) return 0; @@ -200,7 +183,6 @@ public class PlayerDataWrapper { } - public int getTotalExperience() { if (!data.contains("XpTotal")) return 0; @@ -217,12 +199,6 @@ public class PlayerDataWrapper { } - - - - - - private static class DummyPlayerInventory extends InventoryWrapper implements PlayerInventory { private int heldItemSlot;