From b09dfbde60d9068f9f11c5791c1ff55c3b116494 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9D=8F=E9=BB=91?= Date: Sat, 25 May 2019 00:08:37 +0800 Subject: [PATCH] + nbt util --- build.gradle | 2 +- src/main/resources/simplei18n/high/zh_CN.yml | 3 - .../skymc/taboolib/common/nms/NMSHandler.java | 11 +- .../taboolib/common/nms/NMSHandlerImpl.java | 110 +++++++++- .../taboolib/common/nms/nbt/NBTBase.java | 147 +++++++++++++ .../taboolib/common/nms/nbt/NBTCompound.java | 162 +++++++++++++++ .../taboolib/common/nms/nbt/NBTList.java | 195 ++++++++++++++++++ .../taboolib/common/nms/nbt/NBTType.java | 42 ++++ 8 files changed, 662 insertions(+), 10 deletions(-) create mode 100644 src/main/scala/me/skymc/taboolib/common/nms/nbt/NBTBase.java create mode 100644 src/main/scala/me/skymc/taboolib/common/nms/nbt/NBTCompound.java create mode 100644 src/main/scala/me/skymc/taboolib/common/nms/nbt/NBTList.java create mode 100644 src/main/scala/me/skymc/taboolib/common/nms/nbt/NBTType.java diff --git a/build.gradle b/build.gradle index 8129fa4..109b036 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { id 'com.github.johnrengelman.shadow' version '4.0.4' } group = 'me.skymc' -version = '4.81' +version = '4.82' sourceCompatibility = 1.8 targetCompatibility = 1.8 diff --git a/src/main/resources/simplei18n/high/zh_CN.yml b/src/main/resources/simplei18n/high/zh_CN.yml index 675d8d3..7f02fe7 100644 --- a/src/main/resources/simplei18n/high/zh_CN.yml +++ b/src/main/resources/simplei18n/high/zh_CN.yml @@ -172,9 +172,6 @@ 'item.minecraft.dandelion_yellow': '蒲公英黄' 'item.minecraft.dark_oak_boat': '深色橡木船' 'item.minecraft.debug_stick': '调试棒' -'item.minecraft.debug_stick.empty': '%s不具备属性' -'item.minecraft.debug_stick.select': '已选择“%s”(%s)' -'item.minecraft.debug_stick.update': '将\'%s\'设为%s' 'item.minecraft.diamond': '钻石' 'item.minecraft.diamond_axe': '钻石斧' 'item.minecraft.diamond_boots': '钻石靴子' diff --git a/src/main/scala/me/skymc/taboolib/common/nms/NMSHandler.java b/src/main/scala/me/skymc/taboolib/common/nms/NMSHandler.java index 362e515..76d263b 100644 --- a/src/main/scala/me/skymc/taboolib/common/nms/NMSHandler.java +++ b/src/main/scala/me/skymc/taboolib/common/nms/NMSHandler.java @@ -1,6 +1,7 @@ package me.skymc.taboolib.common.nms; import me.skymc.taboolib.common.function.TFunction; +import me.skymc.taboolib.common.nms.nbt.NBTCompound; import me.skymc.taboolib.common.versioncontrol.SimpleVersionControl; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; @@ -23,6 +24,8 @@ public abstract class NMSHandler { } } + abstract public double[] getTPS(); + abstract public String getName(ItemStack itemStack); abstract public String getName(Entity entity); @@ -31,7 +34,13 @@ public abstract class NMSHandler { abstract public void sendActionBar(Player player, String text); - abstract public double[] getTPS(); + abstract public ItemStack saveNBT(ItemStack itemStack, NBTCompound compound); + + abstract public Object _NBT(ItemStack itemStack); + + public NBTCompound loadNBT(ItemStack itemStack) { + return (NBTCompound) _NBT(itemStack); + } public static NMSHandler getHandler() { return handler; diff --git a/src/main/scala/me/skymc/taboolib/common/nms/NMSHandlerImpl.java b/src/main/scala/me/skymc/taboolib/common/nms/NMSHandlerImpl.java index e25c165..0f95445 100644 --- a/src/main/scala/me/skymc/taboolib/common/nms/NMSHandlerImpl.java +++ b/src/main/scala/me/skymc/taboolib/common/nms/NMSHandlerImpl.java @@ -1,16 +1,16 @@ package me.skymc.taboolib.common.nms; import me.skymc.taboolib.TabooLib; +import me.skymc.taboolib.common.nms.nbt.NBTCompound; import me.skymc.taboolib.common.packet.TPacketHandler; +import me.skymc.taboolib.common.util.SimpleReflection; import me.skymc.taboolib.nms.NMSUtils; import net.minecraft.server.v1_12_R1.ChatMessageType; import net.minecraft.server.v1_12_R1.EntityVillager; import net.minecraft.server.v1_12_R1.MinecraftServer; import net.minecraft.server.v1_12_R1.NBTTagCompound; import net.minecraft.server.v1_13_R2.IRegistry; -import net.minecraft.server.v1_8_R3.ChatComponentText; -import net.minecraft.server.v1_8_R3.PacketPlayOutChat; -import net.minecraft.server.v1_8_R3.PacketPlayOutTitle; +import net.minecraft.server.v1_8_R3.*; import org.bukkit.craftbukkit.v1_13_R2.entity.CraftVillager; import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack; import org.bukkit.entity.Entity; @@ -20,6 +20,9 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; import java.lang.reflect.Field; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; /** * @Author 坏黑 @@ -27,8 +30,22 @@ import java.lang.reflect.Field; */ public class NMSHandlerImpl extends NMSHandler { + private final int VERSION = TabooLib.getVersionNumber(); private Field entityTypesField; + static { + SimpleReflection.saveField(NBTTagString.class); + SimpleReflection.saveField(NBTTagDouble.class); + SimpleReflection.saveField(NBTTagInt.class); + SimpleReflection.saveField(NBTTagFloat.class); + SimpleReflection.saveField(NBTTagShort.class); + SimpleReflection.saveField(NBTTagLong.class); + SimpleReflection.saveField(NBTTagByte.class); + SimpleReflection.saveField(NBTTagIntArray.class); + SimpleReflection.saveField(NBTTagByteArray.class); + SimpleReflection.saveField(NBTTagList.class); + } + public NMSHandlerImpl() { if (TabooLib.getVersionNumber() >= 11300) { for (Field declaredField : NMSUtils.getNMSClass("Entity").getDeclaredFields()) { @@ -41,6 +58,11 @@ public class NMSHandlerImpl extends NMSHandler { } } + @Override + public double[] getTPS() { + return MinecraftServer.getServer().recentTps; + } + @Override public String getName(ItemStack itemStack) { Object nmsItem = CraftItemStack.asNMSCopy(itemStack); @@ -153,7 +175,85 @@ public class NMSHandlerImpl extends NMSHandler { } @Override - public double[] getTPS() { - return MinecraftServer.getServer().recentTps; + public ItemStack saveNBT(ItemStack itemStack, NBTCompound compound) { + Object nmsItem = CraftItemStack.asNMSCopy(itemStack); + try { + ((net.minecraft.server.v1_8_R3.ItemStack) nmsItem).setTag((net.minecraft.server.v1_8_R3.NBTTagCompound) toNBTBase(compound)); + } catch (Throwable t) { + t.printStackTrace(); + } + return CraftItemStack.asBukkitCopy((net.minecraft.server.v1_8_R3.ItemStack) nmsItem); + } + + @Override + public Object _NBT(ItemStack itemStack) { + Object nmsItem = CraftItemStack.asNMSCopy(itemStack); + try { + return ((net.minecraft.server.v1_8_R3.ItemStack) nmsItem).hasTag() ? fromNBTBase(((net.minecraft.server.v1_8_R3.ItemStack) nmsItem).getTag()) : new NBTCompound(); + } catch (Throwable t) { + t.printStackTrace(); + } + return new NBTCompound(); + } + + private Object toNBTBase(me.skymc.taboolib.common.nms.nbt.NBTBase base) { + switch (base.getType()) { + case INT: + return new NBTTagInt(base.asInt()); + case BYTE: + return new NBTTagByte(base.asByte()); + case LONG: + return new NBTTagLong(base.asLong()); + case FLOAT: + return new NBTTagFloat(base.asFloat()); + case SHORT: + return new NBTTagShort(base.asShort()); + case DOUBLE: + return new NBTTagDouble(base.asDouble()); + case STRING: + return new NBTTagString(base.asString()); + case INT_ARRAY: + return new NBTTagIntArray(base.asIntArray()); + case BYTE_ARRAY: + return new NBTTagByteArray(base.asByteArray()); + case LIST: + Object nmsList = new NBTTagList(); + base.asList().forEach(value -> ((NBTTagList) nmsList).add((net.minecraft.server.v1_8_R3.NBTBase) toNBTBase(value))); + return nmsList; + case COMPOUND: + Object nmsTag = new net.minecraft.server.v1_8_R3.NBTTagCompound(); + base.asCompound().forEach((k, v) -> ((net.minecraft.server.v1_8_R3.NBTTagCompound) nmsTag).set(k, (net.minecraft.server.v1_8_R3.NBTBase) toNBTBase(v))); + return nmsTag; + } + return null; + } + + private Object fromNBTBase(Object base) { + if (base instanceof NBTTagString) { + return new me.skymc.taboolib.common.nms.nbt.NBTBase(SimpleReflection.getFieldValue(NBTTagString.class, base, "data", "")); + } else if (base instanceof NBTTagDouble) { + return new me.skymc.taboolib.common.nms.nbt.NBTBase(SimpleReflection.getFieldValue(NBTTagDouble.class, base, "data", 0D)); + } else if (base instanceof NBTTagInt) { + return new me.skymc.taboolib.common.nms.nbt.NBTBase(SimpleReflection.getFieldValue(NBTTagInt.class, base, "data", 0)); + } else if (base instanceof NBTTagFloat) { + return new me.skymc.taboolib.common.nms.nbt.NBTBase(SimpleReflection.getFieldValue(NBTTagFloat.class, base, "data", (float) 0)); + } else if (base instanceof NBTTagShort) { + return new me.skymc.taboolib.common.nms.nbt.NBTBase(SimpleReflection.getFieldValue(NBTTagShort.class, base, "data", (short) 0)); + } else if (base instanceof NBTTagLong) { + return new me.skymc.taboolib.common.nms.nbt.NBTBase(SimpleReflection.getFieldValue(NBTTagLong.class, base, "data", 0L)); + } else if (base instanceof NBTTagByte) { + return new me.skymc.taboolib.common.nms.nbt.NBTBase(SimpleReflection.getFieldValue(NBTTagByte.class, base, "data", (byte) 0D)); + } else if (base instanceof NBTTagIntArray) { + return new me.skymc.taboolib.common.nms.nbt.NBTBase(SimpleReflection.getFieldValue(NBTTagIntArray.class, base, "data", new int[0])); + } else if (base instanceof NBTTagByteArray) { + return new me.skymc.taboolib.common.nms.nbt.NBTBase(SimpleReflection.getFieldValue(NBTTagByteArray.class, base, "data", new byte[0])); + } else if (base instanceof net.minecraft.server.v1_8_R3.NBTTagCompound) { + Set keys = VERSION >= 11300 ? ((net.minecraft.server.v1_13_R2.NBTTagCompound) base).getKeys() : ((net.minecraft.server.v1_8_R3.NBTTagCompound) base).c(); + return keys.stream().collect(Collectors.toMap(key -> key, key -> (me.skymc.taboolib.common.nms.nbt.NBTBase) fromNBTBase(((net.minecraft.server.v1_13_R2.NBTTagCompound) base).get(key)), (a, b) -> b, me.skymc.taboolib.common.nms.nbt.NBTCompound::new)); + } else if (base instanceof NBTTagList) { + List list = (List) SimpleReflection.getFieldValue(NBTTagList.class, base, "list"); + return list.stream().map(this::fromNBTBase).collect(Collectors.toCollection(me.skymc.taboolib.common.nms.nbt.NBTList::new)); + } + return null; } } diff --git a/src/main/scala/me/skymc/taboolib/common/nms/nbt/NBTBase.java b/src/main/scala/me/skymc/taboolib/common/nms/nbt/NBTBase.java new file mode 100644 index 0000000..ad5ebce --- /dev/null +++ b/src/main/scala/me/skymc/taboolib/common/nms/nbt/NBTBase.java @@ -0,0 +1,147 @@ +package me.skymc.taboolib.common.nms.nbt; + +import java.util.Arrays; +import java.util.Objects; + +/** + * @Author 坏黑 + * @Since 2019-05-24 17:45 + */ +public class NBTBase { + + protected NBTType type; + protected Object data; + + public NBTBase(String data) { + this.type = NBTType.STRING; + this.data = data; + } + + public NBTBase(byte data) { + this.type = NBTType.BYTE; + this.data = data; + } + + public NBTBase(byte[] data) { + this.type = NBTType.BYTE_ARRAY; + this.data = data; + } + + public NBTBase(int data) { + this.type = NBTType.INT; + this.data = data; + } + + public NBTBase(int[] data) { + this.type = NBTType.INT_ARRAY; + this.data = data; + } + + public NBTBase(double data) { + this.type = NBTType.DOUBLE; + this.data = data; + } + + public NBTBase(float data) { + this.type = NBTType.FLOAT; + this.data = data; + } + + public NBTBase(short data) { + this.type = NBTType.SHORT; + this.data = data; + } + + public NBTBase(long data) { + this.type = NBTType.LONG; + this.data = data; + } + + public NBTBase(NBTCompound data) { + this.type = NBTType.COMPOUND; + this.data = data; + } + + public NBTBase(NBTList data) { + this.type = NBTType.LIST; + this.data = data; + } + + public String asString() { + return (String) data; + } + + public byte asByte() { + return (byte) data; + } + + public byte[] asByteArray() { + return (byte[]) data; + } + + public int asInt() { + return (int) data; + } + + public int[] asIntArray() { + return (int[]) data; + } + + public double asDouble() { + return (double) data; + } + + public float asFloat() { + return (float) data; + } + + public short asShort() { + return (short) data; + } + + public long asLong() { + return (long) data; + } + + public NBTCompound asCompound() { + return (NBTCompound) data; + } + + public NBTList asList() { + return (NBTList) data; + } + + public NBTType getType() { + return type; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof NBTBase)) { + return false; + } + NBTBase nbtBase = (NBTBase) o; + return getType() == nbtBase.getType() && + Objects.equals(data, nbtBase.data); + } + + @Override + public int hashCode() { + return Objects.hash(getType(), data); + } + + @Override + public String toString() { + switch (type) { + case INT_ARRAY: + return Arrays.toString(asIntArray()); + case BYTE_ARRAY: + return Arrays.toString(asByteArray()); + default: + return String.valueOf(data); + } + } +} diff --git a/src/main/scala/me/skymc/taboolib/common/nms/nbt/NBTCompound.java b/src/main/scala/me/skymc/taboolib/common/nms/nbt/NBTCompound.java new file mode 100644 index 0000000..f61b502 --- /dev/null +++ b/src/main/scala/me/skymc/taboolib/common/nms/nbt/NBTCompound.java @@ -0,0 +1,162 @@ +package me.skymc.taboolib.common.nms.nbt; + +import com.google.common.collect.Maps; + +import java.util.Collection; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * @Author 坏黑 + * @Since 2019-05-24 17:44 + */ +public class NBTCompound extends NBTBase implements Map { + + private Map value = Maps.newConcurrentMap(); + + public NBTCompound() { + super(0); + this.type = NBTType.COMPOUND; + } + + @Override + public int size() { + return value.size(); + } + + @Override + public boolean isEmpty() { + return value.isEmpty(); + } + + @Override + public boolean containsKey(Object key) { + return value.containsKey(key); + } + + @Override + public boolean containsValue(Object value) { + return this.value.containsValue(value); + } + + @Override + public NBTBase get(Object key) { + return value.get(key); + } + + @Override + public NBTBase put(String key, NBTBase value) { + return this.value.put(key, value); + } + + @Override + public NBTBase remove(Object key) { + return value.remove(key); + } + + @Override + public void putAll(Map m) { + this.value.putAll(m); + } + + @Override + public void clear() { + this.value.clear(); + } + + @Override + public Set keySet() { + return this.value.keySet(); + } + + @Override + public Collection values() { + return this.value.values(); + } + + @Override + public Set> entrySet() { + return this.value.entrySet(); + } + + @Override + public NBTBase getOrDefault(Object key, NBTBase defaultValue) { + return this.value.getOrDefault(key, defaultValue); + } + + @Override + public void forEach(BiConsumer action) { + this.value.forEach(action); + } + + @Override + public void replaceAll(BiFunction function) { + this.value.replaceAll(function); + } + + @Override + public NBTBase putIfAbsent(String key, NBTBase value) { + return this.value.putIfAbsent(key, value); + } + + @Override + public boolean remove(Object key, Object value) { + return this.value.remove(key, value); + } + + @Override + public boolean replace(String key, NBTBase oldValue, NBTBase newValue) { + return this.value.replace(key, oldValue, newValue); + } + + @Override + public NBTBase replace(String key, NBTBase value) { + return this.value.replace(key, value); + } + + @Override + public NBTBase computeIfAbsent(String key, Function mappingFunction) { + return this.value.computeIfAbsent(key, mappingFunction); + } + + @Override + public NBTBase computeIfPresent(String key, BiFunction remappingFunction) { + return this.value.computeIfPresent(key, remappingFunction); + } + + @Override + public NBTBase compute(String key, BiFunction remappingFunction) { + return this.value.compute(key, remappingFunction); + } + + @Override + public NBTBase merge(String key, NBTBase value, BiFunction remappingFunction) { + return this.value.merge(key, value, remappingFunction); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof NBTCompound)) { + return false; + } + NBTCompound that = (NBTCompound) o; + return Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), value); + } + + @Override + public String toString() { + return String.valueOf(value); + } +} diff --git a/src/main/scala/me/skymc/taboolib/common/nms/nbt/NBTList.java b/src/main/scala/me/skymc/taboolib/common/nms/nbt/NBTList.java new file mode 100644 index 0000000..1879ccc --- /dev/null +++ b/src/main/scala/me/skymc/taboolib/common/nms/nbt/NBTList.java @@ -0,0 +1,195 @@ +package me.skymc.taboolib.common.nms.nbt; + +import com.google.common.collect.Lists; + +import java.util.*; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.function.UnaryOperator; +import java.util.stream.Stream; + +/** + * @Author 坏黑 + * @Since 2019-05-24 18:37 + */ +public class NBTList extends NBTBase implements List { + + private List value = Lists.newCopyOnWriteArrayList(); + + public NBTList() { + super(0); + this.type = NBTType.LIST; + } + + @Override + public int size() { + return value.size(); + } + + @Override + public boolean isEmpty() { + return value.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return value.contains(0); + } + + @Override + public Iterator iterator() { + return value.iterator(); + } + + @Override + public Object[] toArray() { + return value.toArray(); + } + + @Override + public T[] toArray(T[] a) { + return value.toArray(a); + } + + @Override + public boolean add(NBTBase base) { + return value.add(base); + } + + @Override + public boolean remove(Object o) { + return value.remove(o); + } + + @Override + public boolean containsAll(Collection c) { + return value.containsAll(c); + } + + @Override + public boolean addAll(Collection c) { + return value.addAll(c); + } + + @Override + public boolean addAll(int index, Collection c) { + return value.addAll(index, c); + } + + @Override + public boolean removeAll(Collection c) { + return value.removeAll(c); + } + + @Override + public boolean removeIf(Predicate filter) { + return value.removeIf(filter); + } + + @Override + public boolean retainAll(Collection c) { + return value.retainAll(c); + } + + @Override + public void replaceAll(UnaryOperator operator) { + value.replaceAll(operator); + } + + @Override + public void sort(Comparator c) { + value.sort(c); + } + + @Override + public void clear() { + value.clear(); + } + + @Override + public NBTBase get(int index) { + return value.get(index); + } + + @Override + public NBTBase set(int index, NBTBase element) { + return value.set(index, element); + } + + @Override + public void add(int index, NBTBase element) { + value.add(index, element); + } + + @Override + public NBTBase remove(int index) { + return value.remove(index); + } + + @Override + public int indexOf(Object o) { + return value.indexOf(o); + } + + @Override + public int lastIndexOf(Object o) { + return value.lastIndexOf(o); + } + + @Override + public ListIterator listIterator() { + return value.listIterator(); + } + + @Override + public ListIterator listIterator(int index) { + return value.listIterator(index); + } + + @Override + public List subList(int fromIndex, int toIndex) { + return value.subList(fromIndex, toIndex); + } + + @Override + public Spliterator spliterator() { + return value.spliterator(); + } + + @Override + public Stream stream() { + return value.stream(); + } + + @Override + public Stream parallelStream() { + return value.parallelStream(); + } + + @Override + public void forEach(Consumer action) { + value.forEach(action); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof NBTList)) { + return false; + } + NBTList nbtBases = (NBTList) o; + return Objects.equals(value, nbtBases.value); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), value); + } + + @Override + public String toString() { + return String.valueOf(value); + } +} diff --git a/src/main/scala/me/skymc/taboolib/common/nms/nbt/NBTType.java b/src/main/scala/me/skymc/taboolib/common/nms/nbt/NBTType.java new file mode 100644 index 0000000..b1769cd --- /dev/null +++ b/src/main/scala/me/skymc/taboolib/common/nms/nbt/NBTType.java @@ -0,0 +1,42 @@ +package me.skymc.taboolib.common.nms.nbt; + +/** + * @Author 坏黑 + * @Since 2019-05-24 17:46 + */ +public enum NBTType { + + END(0), + + BYTE(1), + + SHORT(2), + + INT(3), + + LONG(4), + + FLOAT(5), + + DOUBLE(6), + + BYTE_ARRAY(7), + + INT_ARRAY(11), + + STRING(8), + + LIST(9), + + COMPOUND(10); + + private int id; + + NBTType(int i) { + this.id = i; + } + + public int getId() { + return this.id; + } +}