diff --git a/src/main/java/su/nightexpress/nightcore/core/CoreLogger.java b/src/main/java/su/nightexpress/nightcore/core/CoreLogger.java new file mode 100644 index 0000000..aa803ba --- /dev/null +++ b/src/main/java/su/nightexpress/nightcore/core/CoreLogger.java @@ -0,0 +1,19 @@ +package su.nightexpress.nightcore.core; + +import org.jetbrains.annotations.NotNull; +import su.nightexpress.nightcore.util.Plugins; + +public class CoreLogger { + + public static void info(@NotNull String text) { + Plugins.getCore().info(text); + } + + public static void warn(@NotNull String text) { + Plugins.getCore().warn(text); + } + + public static void error(@NotNull String text) { + Plugins.getCore().error(text); + } +} diff --git a/src/main/java/su/nightexpress/nightcore/db/AbstractUser.java b/src/main/java/su/nightexpress/nightcore/db/AbstractUser.java index f430730..b47c4f6 100644 --- a/src/main/java/su/nightexpress/nightcore/db/AbstractUser.java +++ b/src/main/java/su/nightexpress/nightcore/db/AbstractUser.java @@ -30,9 +30,15 @@ public AbstractUser(@NotNull UUID uuid, @NotNull String name, long dateCreated, this.disableAutoSave(); } - public abstract void onLoad(); + @Deprecated + public void onLoad() { - public abstract void onUnload(); + } + + @Deprecated + public void onUnload() { + + } public boolean isCacheExpired() { diff --git a/src/main/java/su/nightexpress/nightcore/db/AbstractUserManager.java b/src/main/java/su/nightexpress/nightcore/db/AbstractUserManager.java index cf4c1da..72322de 100644 --- a/src/main/java/su/nightexpress/nightcore/db/AbstractUserManager.java +++ b/src/main/java/su/nightexpress/nightcore/db/AbstractUserManager.java @@ -48,6 +48,14 @@ protected void onShutdown() { this.loadedByNameMap.clear(); } + protected void onLoad(@NotNull U user) { + + } + + protected void onUnload(@NotNull U user) { + + } + public void loadOnline() { //plugin.debug("Load data for online players"); Players.getOnline().forEach(player -> { @@ -115,10 +123,12 @@ public void save(@NotNull U user) { private void load(@NotNull U user) { user.onLoad(); this.cacheTemporary(user); + this.onLoad(user); } private void unload(@NotNull U user) { user.onUnload(); + this.onUnload(user); this.loadedByIdMap.remove(user.getId()); this.loadedByNameMap.remove(user.getName().toLowerCase()); diff --git a/src/main/java/su/nightexpress/nightcore/util/ItemNbt.java b/src/main/java/su/nightexpress/nightcore/util/ItemNbt.java index db7c276..1109e59 100644 --- a/src/main/java/su/nightexpress/nightcore/util/ItemNbt.java +++ b/src/main/java/su/nightexpress/nightcore/util/ItemNbt.java @@ -24,11 +24,11 @@ public class ItemNbt { - private static final Class ITEM_STACK_CLASS = Reflex.getClass("net.minecraft.world.item", "ItemStack"); - private static final Class COMPOUND_TAG_CLASS = Reflex.getClass("net.minecraft.nbt", "NBTTagCompound"); - private static final Class NBT_IO_CLASS = Reflex.getClass("net.minecraft.nbt", "NBTCompressedStreamTools"); + private static final Class ITEM_STACK_CLASS = Reflex.getNMSClass("net.minecraft.world.item", "ItemStack"); + private static final Class COMPOUND_TAG_CLASS = Reflex.getNMSClass("net.minecraft.nbt", "CompoundTag", "NBTTagCompound"); + private static final Class NBT_IO_CLASS = Reflex.getNMSClass("net.minecraft.nbt", "NbtIo", "NBTCompressedStreamTools"); - private static final Class CRAFT_ITEM_STACK_CLASS = Reflex.getClass(Version.CRAFTBUKKIT_PACKAGE + ".inventory", "CraftItemStack"); + private static final Class CRAFT_ITEM_STACK_CLASS = Reflex.getNMSClass(Version.CRAFTBUKKIT_PACKAGE + ".inventory", "CraftItemStack"); private static final Method CRAFT_ITEM_STACK_AS_NMS_COPY = Reflex.getMethod(CRAFT_ITEM_STACK_CLASS, "asNMSCopy", ItemStack.class); private static final Method CRAFT_ITEM_STACK_AS_BUKKIT_COPY = Reflex.getMethod(CRAFT_ITEM_STACK_CLASS, "asBukkitCopy", ITEM_STACK_CLASS); @@ -36,10 +36,13 @@ public class ItemNbt { private static final Method NBT_IO_WRITE = Reflex.getMethod(NBT_IO_CLASS, "a", COMPOUND_TAG_CLASS, DataOutput.class); private static final Method NBT_IO_READ = Reflex.getMethod(NBT_IO_CLASS, "a", DataInput.class); - private static final Class DATA_FIXERS_CLASS = Reflex.getClass("net.minecraft.util.datafix", "DataConverterRegistry"); // DataFixers - private static final Method GET_DATA_FIXER = Reflex.getMethod(DATA_FIXERS_CLASS, "a"); - private static final Class NBT_OPS_CLASS = Reflex.getClass("net.minecraft.nbt", "DynamicOpsNBT"); // NbtOps - private static final Class REFERENCES_CLASS = Reflex.getClass("net.minecraft.util.datafix.fixes", "DataConverterTypes"); // References + private static final Class TAG_PARSER_CLASS = Reflex.getNMSClass("net.minecraft.nbt", "TagParser", "MojangsonParser"); + private static final Method PARSE_TAG = TAG_PARSER_CLASS == null ? null : Reflex.getMethod(TAG_PARSER_CLASS, "a", String.class); + + private static final Class DATA_FIXERS_CLASS = Reflex.getNMSClass("net.minecraft.util.datafix", "DataFixers", "DataConverterRegistry"); // DataFixers + private static final Method GET_DATA_FIXER = Reflex.getMethod(DATA_FIXERS_CLASS, "a"); + private static final Class NBT_OPS_CLASS = Reflex.getNMSClass("net.minecraft.nbt", "NbtOps", "DynamicOpsNBT"); // NbtOps + private static final Class REFERENCES_CLASS = Reflex.getNMSClass("net.minecraft.util.datafix.fixes", "References", "DataConverterTypes"); // References private static final int DATA_FIXER_SOURCE_VERSION = 3700; // 1.20.4 private static final int DATA_FXIER_TARGET_VERSION = 3953; // 1.21 @@ -70,8 +73,8 @@ public class ItemNbt { } if (Version.isAtLeast(Version.MC_1_20_6)) { - Class minecraftServerClass = Reflex.getClass("net.minecraft.server", "MinecraftServer"); - Class holderLookupProviderClass = Reflex.getInnerClass("net.minecraft.core.HolderLookup", "a"); // Provider + Class minecraftServerClass = Reflex.getNMSClass("net.minecraft.server", "MinecraftServer"); + Class holderLookupProviderClass = Reflex.getNMSClass("net.minecraft.core", "HolderLookup$a"); // Provider String registryAccessName = "bc"; if (Version.isAtLeast(Version.MC_1_21_3)) registryAccessName = "ba"; @@ -95,7 +98,7 @@ public static boolean load(@NotNull NightCore core) { useRegistry = true; - Class craftServerClass = Reflex.getClass(Version.CRAFTBUKKIT_PACKAGE, "CraftServer"); + Class craftServerClass = Reflex.getNMSClass(Version.CRAFTBUKKIT_PACKAGE, "CraftServer"); if (craftServerClass == null) { core.error("Could not find 'CraftServer' class in craftbukkit package: '" + Version.CRAFTBUKKIT_PACKAGE + "'."); return false; @@ -204,6 +207,65 @@ public static ItemStack decompress(@NotNull String compressed) { } } + @Nullable + public static String getTagString(@NotNull ItemStack item) { + if (CRAFT_ITEM_STACK_AS_NMS_COPY == null) { + throw new UnsupportedOperationException("Unsupported server version!"); + } + + try { + Object compoundTag; + Object itemStack = CRAFT_ITEM_STACK_AS_NMS_COPY.invoke(null, item); + + if (useRegistry) { + if (ITEM_STACK_SAVE_OPTIONAL == null) return null; + + compoundTag = ITEM_STACK_SAVE_OPTIONAL.invoke(itemStack, registryAccess); + } + else { + if (NBT_TAG_COMPOUND_NEW == null || NMS_SAVE == null) return null; + + compoundTag = NBT_TAG_COMPOUND_NEW.newInstance(); + NMS_SAVE.invoke(itemStack, compoundTag); + } + + return compoundTag.toString(); + } + catch (ReflectiveOperationException exception) { + exception.printStackTrace(); + return null; + } + } + + @Nullable + public static ItemStack fromTagString(@NotNull String tagString) { + if (TAG_PARSER_CLASS == null || PARSE_TAG == null || CRAFT_ITEM_STACK_AS_BUKKIT_COPY == null) { + throw new UnsupportedOperationException("Unsupported server version!"); + } + + try { + Object compoundTag = Reflex.invokeMethod(PARSE_TAG, null, tagString); + Object itemStack; + + if (useRegistry) { + if (ITEM_STACK_PARSE_OPTIONAL == null) return null; + + itemStack = ITEM_STACK_PARSE_OPTIONAL.invoke(null, registryAccess, compoundTag); + } + else { + if (NMS_ITEM_OF == null) return null; + + itemStack = NMS_ITEM_OF.invoke(null, compoundTag); + } + + return (ItemStack) CRAFT_ITEM_STACK_AS_BUKKIT_COPY.invoke(null, itemStack); + } + catch (ReflectiveOperationException exception) { + exception.printStackTrace(); + return null; + } + } + @NotNull public static List compress(@NotNull ItemStack[] items) { return compress(Arrays.asList(items)); diff --git a/src/main/java/su/nightexpress/nightcore/util/Reflex.java b/src/main/java/su/nightexpress/nightcore/util/Reflex.java index ad15946..ff76293 100644 --- a/src/main/java/su/nightexpress/nightcore/util/Reflex.java +++ b/src/main/java/su/nightexpress/nightcore/util/Reflex.java @@ -2,6 +2,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import su.nightexpress.nightcore.core.CoreLogger; import java.lang.reflect.*; import java.util.ArrayList; @@ -19,12 +20,39 @@ public static Class getInnerClass(@NotNull String path, @NotNull String name) return getClass(path + "$" + name); } + public static Class getNMSClass(@NotNull String path, @NotNull String realName) { + return getNMSClass(path, realName, null); + } + + public static Class getNMSClass(@NotNull String path, @NotNull String realName, @Nullable String obfName) { + Class byRealName = getClass(path + "." + realName, false); + if (byRealName != null) { + //CoreLogger.info("Class found by real name: " + path + "." + realName); + return byRealName; + } + + if (obfName != null) { + Class byObfName = getClass(path + "." + obfName, false); + if (byObfName != null) { + //CoreLogger.info("Class found by obfuscated name: " + path + "." + obfName); + return byObfName; + } + } + + CoreLogger.warn("NMS class not found: " + path + "[" + realName + " / " + obfName + "]"); + return null; + } + private static Class getClass(@NotNull String path) { + return getClass(path, true); + } + + private static Class getClass(@NotNull String path, boolean printError) { try { return Class.forName(path); } catch (ClassNotFoundException exception) { - exception.printStackTrace(); + if (printError) exception.printStackTrace(); return null; } } diff --git a/src/main/java/su/nightexpress/nightcore/util/number/CompactNumber.java b/src/main/java/su/nightexpress/nightcore/util/number/CompactNumber.java index db3b465..3fc80f2 100644 --- a/src/main/java/su/nightexpress/nightcore/util/number/CompactNumber.java +++ b/src/main/java/su/nightexpress/nightcore/util/number/CompactNumber.java @@ -16,7 +16,7 @@ public CompactNumber(double value, @Nullable NumberShortcut shortcut) { @NotNull public String format() { - String num = String.valueOf(NumberUtil.round(this.value, 1)); + String num = NumberUtil.format(NumberUtil.round(this.value, 1)); if (this.shortcut != null) num += this.shortcut.getSymbol(); return num; diff --git a/src/main/java/su/nightexpress/nightcore/util/text/tag/decorator/ShowItemDecorator.java b/src/main/java/su/nightexpress/nightcore/util/text/tag/decorator/ShowItemDecorator.java index 7250692..d90feeb 100644 --- a/src/main/java/su/nightexpress/nightcore/util/text/tag/decorator/ShowItemDecorator.java +++ b/src/main/java/su/nightexpress/nightcore/util/text/tag/decorator/ShowItemDecorator.java @@ -44,7 +44,9 @@ public HoverEvent createEvent() { String key = BukkitThing.toString(itemStack.getType()); ItemMeta meta = itemStack.getItemMeta(); - Item item = new Item(key, itemStack.getAmount(), ItemTag.ofNbt(meta == null ? null : meta.getAsString())); + String nbt = meta == null ? "{}" : meta.getAsString(); + + Item item = new Item(key, itemStack.getAmount(), ItemTag.ofNbt(nbt)); return new HoverEvent(HoverEvent.Action.SHOW_ITEM, item); }