Update reflection in NMS/OBC
This commit is contained in:
parent
7f56645ba5
commit
cef4af80f0
@ -2,12 +2,8 @@ package fr.pandacube.lib.paper.players;
|
||||
|
||||
import fr.pandacube.lib.paper.reflect.util.PrimaryWorlds;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.CraftServer;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.dataconverter.MCDataConverter;
|
||||
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;
|
||||
@ -154,29 +150,17 @@ public interface PaperOffPlayer extends AbstractOffPlayer {
|
||||
/**
|
||||
* Gets the NBT data from the player-data file.
|
||||
* It will not work if the player is online, because the data on the file are not synchronized with real-time values.
|
||||
* @param convertTag true to convert the data to the current MC version, false to keep the saved version
|
||||
* @return the NBT data from the player-data file, or null if the file does not exists.
|
||||
* @return the NBT data from the player-data file, or null if the file does not exist.
|
||||
* @throws IllegalStateException if the player is online.
|
||||
* @throws IOException if an error occurs reading the data.
|
||||
*/
|
||||
default CompoundTag getPlayerData(boolean convertTag) throws IOException {
|
||||
default CompoundTag getPlayerData() {
|
||||
if (isOnline())
|
||||
throw new IllegalStateException("Cannot access data file of " + getName() + " because they’re online.");
|
||||
CompoundTag data = ReflectWrapper.wrapTyped(Bukkit.getServer(), CraftServer.class)
|
||||
return ReflectWrapper.wrapTyped(Bukkit.getServer(), CraftServer.class)
|
||||
.getServer()
|
||||
.getPlayerList()
|
||||
.playerIo()
|
||||
.getPlayerData(getUniqueId().toString());
|
||||
if (data != null && convertTag) {
|
||||
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 IOException("Unable to upgrade data format of player " + getName() + " (" + getUniqueId() + ") from version " + destVersion + " to " + destVersion);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
.load(getName(), getUniqueId().toString()).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -184,10 +168,9 @@ public interface PaperOffPlayer extends AbstractOffPlayer {
|
||||
* It will not work if the player is online, because the data on the file are not synchronized with real-time values.
|
||||
* @return the NBT data from the player-data file.
|
||||
* @throws IllegalStateException if the player is online.
|
||||
* @throws IOException if an error occurs reading the data.
|
||||
*/
|
||||
default PlayerDataWrapper getPlayerDataWrapper() throws IOException {
|
||||
return new PlayerDataWrapper(getPlayerData(true));
|
||||
default PlayerDataWrapper getPlayerDataWrapper() {
|
||||
return new PlayerDataWrapper(getPlayerData());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -213,25 +196,23 @@ public interface PaperOffPlayer extends AbstractOffPlayer {
|
||||
* @return the file where the player-data is stored.
|
||||
*/
|
||||
default File getPlayerDataFile(boolean old) {
|
||||
File playerDataDir = new File(WorldUtil.worldDir(PrimaryWorlds.PRIMARY_WORLDS.get(0)), "playerdata");
|
||||
File playerDataDir = new File(WorldUtil.worldDir(PrimaryWorlds.PRIMARY_WORLDS.getFirst()), "playerdata");
|
||||
return new File(playerDataDir, getUniqueId() + (old ? ".dat_old" : ".dat"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player’s inventory.
|
||||
* @return the player’s inventory.
|
||||
* @throws IOException if an error occurs reading the data.
|
||||
*/
|
||||
default PlayerInventory getInventory() throws IOException {
|
||||
default PlayerInventory getInventory() {
|
||||
return getPlayerDataWrapper().getInventory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player’s enderchest.
|
||||
* @return the player’s enderchest.
|
||||
* @throws IOException if an error occurs reading the data.
|
||||
*/
|
||||
default Inventory getEnderChest() throws IOException {
|
||||
default Inventory getEnderChest() {
|
||||
return getPlayerDataWrapper().getEnderChest();
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,8 @@ import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.GameProfileArgu
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.ResourceLocationArgument;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.Vec3Argument;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.core.BlockPos;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.core.HolderLookupProvider;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.core.RegistryAccess;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.core.Vec3i;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.CollectionTag;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.CompoundTag;
|
||||
@ -130,6 +132,8 @@ public class PandalibPaperReflect {
|
||||
thAcc.catchThrowable(() -> initWrapper(Vec3Argument.class, Vec3Argument.REFLECT.get()));
|
||||
// minecraft.core
|
||||
thAcc.catchThrowable(() -> initWrapper(BlockPos.class, BlockPos.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(HolderLookupProvider.class, HolderLookupProvider.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(RegistryAccess.class, RegistryAccess.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(Vec3i.class, Vec3i.REFLECT.get()));
|
||||
// minecraft.nbt
|
||||
thAcc.catchThrowable(() -> initWrapper(CollectionTag.class, CollectionTag.REFLECT.get()));
|
||||
|
@ -1,7 +1,6 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.craftbukkit;
|
||||
|
||||
import fr.pandacube.lib.paper.reflect.OBCReflect;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.CompoundTag;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped;
|
||||
@ -20,11 +19,6 @@ public class CraftItemStack extends ReflectWrapperTyped<ItemStack> {
|
||||
}
|
||||
|
||||
|
||||
public static ItemStack asCraftMirror(CompoundTag nbt) {
|
||||
return asCraftMirror(fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.ItemStack.of(nbt));
|
||||
}
|
||||
|
||||
|
||||
public static fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.ItemStack asNMSCopy(ItemStack original) {
|
||||
return wrap(wrapReflectEx(() -> asNMSCopy.invokeStatic(original)), fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.ItemStack.class);
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.core;
|
||||
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperI;
|
||||
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
|
||||
public interface HolderLookupProvider extends ReflectWrapperI {
|
||||
ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.core.HolderLookup.Provider"));
|
||||
|
||||
class __concrete extends ReflectWrapper implements HolderLookupProvider {
|
||||
protected __concrete(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.core;
|
||||
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.network.protocol.custom.CustomPacketPayload;
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
|
||||
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
|
||||
public interface RegistryAccess extends HolderLookupProvider {
|
||||
ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.core.RegistryAccess"));
|
||||
|
||||
class __concrete extends ReflectWrapper implements RegistryAccess {
|
||||
protected __concrete(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
}
|
||||
}
|
@ -51,7 +51,7 @@ public class CompoundTag extends ReflectWrapper implements Tag {
|
||||
|
||||
private static final ReflectMethod<?> get = wrapEx(() -> REFLECT.method("get", String.class));
|
||||
private static final ReflectMethod<?> getAllKeys = wrapEx(() -> REFLECT.method("getAllKeys"));
|
||||
private static final ReflectMethod<?> entries = wrapEx(() -> REFLECT.method("entries"));
|
||||
private static final ReflectMethod<?> entrySet = wrapEx(() -> REFLECT.method("entrySet"));
|
||||
private static final ReflectMethod<?> size = wrapEx(() -> REFLECT.method("size"));
|
||||
private static final ReflectMethod<?> contains = wrapEx(() -> REFLECT.method("contains", String.class));
|
||||
private static final ReflectMethod<?> containsStringInt = wrapEx(() -> REFLECT.method("contains", String.class, int.class));
|
||||
@ -166,9 +166,9 @@ public class CompoundTag extends ReflectWrapper implements Tag {
|
||||
* The values in the returned Map are not wrapped.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<String, ?> entries() {
|
||||
public Set<Map.Entry<String, ?>> entrySet() {
|
||||
// we cannot easily wrap every value of the map without being able to synchronize the returned map with the wrapped map
|
||||
return (Map<String, ?>) wrapReflectEx(() -> entries.invoke(__getRuntimeInstance()));
|
||||
return (Set<Map.Entry<String, ?>>) wrapReflectEx(() -> entrySet.invoke(__getRuntimeInstance()));
|
||||
}
|
||||
public int size() {
|
||||
return (int) wrapReflectEx(() -> size.invoke(__getRuntimeInstance()));
|
||||
|
@ -1,5 +1,6 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.server;
|
||||
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.core.RegistryAccess;
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
@ -11,11 +12,16 @@ import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
public class MinecraftServer extends ReflectWrapper {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.server.MinecraftServer"));
|
||||
private static final ReflectMethod<?> getPlayerList = wrapEx(() -> REFLECT.method("getPlayerList"));
|
||||
public static final ReflectMethod<?> registryAccess = wrapEx(() -> REFLECT.method("registryAccess"));
|
||||
|
||||
public PlayerList getPlayerList() {
|
||||
return wrap(wrapReflectEx(() -> getPlayerList.invoke(__getRuntimeInstance())), PlayerList.class);
|
||||
}
|
||||
|
||||
public RegistryAccess registryAccess() {
|
||||
return wrap(wrapReflectEx(() -> registryAccess.invoke(__getRuntimeInstance())), RegistryAccess.class);
|
||||
}
|
||||
|
||||
protected MinecraftServer(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
@ -1,21 +1,35 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
|
||||
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.CompoundTag;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.CraftServer;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.core.HolderLookupProvider;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.core.RegistryAccess;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.Tag;
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
public class ItemStack extends ReflectWrapper {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.world.item.ItemStack"));
|
||||
private static final ReflectMethod<?> of = wrapEx(() -> REFLECT.method("of", CompoundTag.REFLECT.get()));
|
||||
private static final ReflectMethod<?> save = wrapEx(() -> REFLECT.method("save", CompoundTag.REFLECT.get()));
|
||||
private static final ReflectMethod<?> parse = wrapEx(() -> REFLECT.method("parse", HolderLookupProvider.REFLECT.get(), Tag.REFLECT.get()));
|
||||
private static final ReflectMethod<?> saveWithPrefix = wrapEx(() -> REFLECT.method("save", HolderLookupProvider.REFLECT.get(), Tag.REFLECT.get()));
|
||||
private static final ReflectMethod<?> save = wrapEx(() -> REFLECT.method("save", HolderLookupProvider.REFLECT.get()));
|
||||
|
||||
public static ItemStack of(CompoundTag nbt) {
|
||||
return wrap(wrapReflectEx(() -> of.invokeStatic(unwrap(nbt))), ItemStack.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Optional<ItemStack> parse(HolderLookupProvider registries, Tag nbt) {
|
||||
return ((Optional<Object>) wrapReflectEx(() -> parse.invokeStatic(unwrap(registries), unwrap(nbt))))
|
||||
.map(o -> wrap(o, ItemStack.class));
|
||||
}
|
||||
|
||||
|
||||
public static Optional<ItemStack> parse(Tag nbt) {
|
||||
return parse(getRegistries(), nbt);
|
||||
}
|
||||
|
||||
|
||||
@ -24,7 +38,26 @@ public class ItemStack extends ReflectWrapper {
|
||||
}
|
||||
|
||||
|
||||
public CompoundTag save(CompoundTag nbt) {
|
||||
return wrap(wrapReflectEx(() -> save.invoke(__getRuntimeInstance(), unwrap(nbt))), CompoundTag.class);
|
||||
public Tag save(HolderLookupProvider registries, Tag prefix) {
|
||||
return wrap(wrapReflectEx(() -> saveWithPrefix.invoke(__getRuntimeInstance(), unwrap(registries), unwrap(prefix))), Tag.class);
|
||||
}
|
||||
|
||||
|
||||
public Tag save(HolderLookupProvider registries) {
|
||||
return wrap(wrapReflectEx(() -> save.invoke(__getRuntimeInstance(), unwrap(registries))), Tag.class);
|
||||
}
|
||||
|
||||
|
||||
public Tag save(Tag prefix) {
|
||||
return save(getRegistries(), prefix);
|
||||
}
|
||||
|
||||
|
||||
public Tag save() {
|
||||
return save(getRegistries());
|
||||
}
|
||||
|
||||
private static RegistryAccess getRegistries() {
|
||||
return wrap(Bukkit.getServer(), CraftServer.class).getServer().registryAccess();
|
||||
}
|
||||
}
|
||||
|
@ -6,18 +6,23 @@ import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
public class PlayerDataStorage extends ReflectWrapper {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.world.level.storage.PlayerDataStorage"));
|
||||
public static final ReflectMethod<?> getPlayerData = wrapEx(() -> REFLECT.method("getPlayerData", String.class)); // Craftbukkit method
|
||||
public static final ReflectMethod<?> load = wrapEx(() -> REFLECT.method("load", String.class, String.class));
|
||||
|
||||
/**
|
||||
* @param playerName the name of the player: used for loading error message and of offline UUID generation.
|
||||
* @param playerId UUID of a player as it is used to name the player data file (UUID.toString())
|
||||
*/
|
||||
public CompoundTag getPlayerData(String playerId) {
|
||||
return wrap(wrapReflectEx(() -> getPlayerData.invoke(__getRuntimeInstance(), playerId)), CompoundTag.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
public Optional<CompoundTag> load(String playerName, String playerId) {
|
||||
return ((Optional<Object>) wrapReflectEx(() -> load.invoke(__getRuntimeInstance(), playerId)))
|
||||
.map(o -> wrap(o, CompoundTag.class));
|
||||
}
|
||||
|
||||
|
||||
|
@ -116,10 +116,9 @@ public record PlayerDataWrapper(CompoundTag data) {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
CompoundTag itemTag = list.getCompound(i);
|
||||
int nbtSlot = itemTag.getByte("Slot") & 255;
|
||||
ItemStack is = filterStack(CraftItemStack.asCraftMirror(itemTag));
|
||||
if (is != null) {
|
||||
stacks.put(nbtSlot, CraftItemStack.asCraftMirror(itemTag));
|
||||
}
|
||||
fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.ItemStack.parse(itemTag)
|
||||
.map(nms -> filterStack(CraftItemStack.asCraftMirror(nms)))
|
||||
.ifPresent(is -> stacks.put(nbtSlot, is));
|
||||
}
|
||||
return stacks;
|
||||
}
|
||||
@ -148,9 +147,8 @@ public record PlayerDataWrapper(CompoundTag data) {
|
||||
if (stack == null)
|
||||
continue;
|
||||
CompoundTag itemTag = new CompoundTag();
|
||||
CraftItemStack.asNMSCopy(is.getValue()).save(itemTag);
|
||||
itemTag.putByte("Slot", is.getKey().byteValue());
|
||||
list.add(list.size(), itemTag);
|
||||
list.add(list.size(), CraftItemStack.asNMSCopy(is.getValue()).save(itemTag));
|
||||
}
|
||||
data.put(key, list);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user