From dc964fcb4b423b02410d10c6d3384b504879362a Mon Sep 17 00:00:00 2001 From: Nils Gereke Date: Wed, 26 Jun 2024 18:38:08 +0200 Subject: [PATCH] Fix paper support (#28) * fix: paper support * fix: create new backpack when no storage found --- .../imprex/zip/common/MinecraftVersion.java | 176 ++++++++++++++++-- .../net/imprex/zip/common/ReflectionUtil.java | 2 +- .../main/java/net/imprex/zip/Backpack.java | 22 ++- .../java/net/imprex/zip/BackpackHandler.java | 29 ++- .../java/net/imprex/zip/BackpackType.java | 2 +- .../main/java/net/imprex/zip/NmsInstance.java | 2 +- .../net/imprex/zip/config/BackpackConfig.java | 2 +- 7 files changed, 199 insertions(+), 36 deletions(-) diff --git a/zip-common/src/main/java/net/imprex/zip/common/MinecraftVersion.java b/zip-common/src/main/java/net/imprex/zip/common/MinecraftVersion.java index 30b1f46..2cef771 100644 --- a/zip-common/src/main/java/net/imprex/zip/common/MinecraftVersion.java +++ b/zip-common/src/main/java/net/imprex/zip/common/MinecraftVersion.java @@ -1,5 +1,8 @@ package net.imprex.zip.common; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -9,38 +12,175 @@ * @author Imprex-Development * @see https://github.com/Imprex-Development/orebfuscator/blob/master/orebfuscator-common/src/main/java/net/imprex/orebfuscator/util/MinecraftVersion.java */ -public final class MinecraftVersion { +public final class MinecraftVersion implements Comparable { - private static final Pattern VERSION_PATTERN = Pattern.compile("org\\.bukkit\\.craftbukkit\\.(v(\\d+)_(\\d+)_R(\\d+))"); + private static final class NmsMapping { - private final String nmsVersion; - private final int majorVersion; - private final int minorVersion; + private static final List MAPPINGS = new ArrayList<>(); - private MinecraftVersion() { + static { + MAPPINGS.add(new NmsMapping("1.21", "v1_21_R1")); + MAPPINGS.add(new NmsMapping("1.20.5", "v1_20_R4")); + } + + public static String get(MinecraftVersion version) { + for (NmsMapping mapping : MAPPINGS) { + if (version.isAtOrAbove(mapping.version)) { + if (mapping.version.minor() != version.minor()) { + System.out.println(String.format("Using nms mapping with mismatched minor versions: %s - %s", + mapping.version, version)); + } + + return mapping.nmsVersion; + } + } + + throw new RuntimeException("Can't get nms package version for minecraft version: " + version); + } + + private final MinecraftVersion version; + private final String nmsVersion; + + public NmsMapping(String version, String nmsVersion) { + this.version = new MinecraftVersion(version); + this.nmsVersion = nmsVersion; + } + } + + private static final Pattern VERSION_PATTERN = Pattern.compile("(?\\d+)(?:\\.(?\\d+))(?:\\.(?\\d+))?"); + private static final Pattern PACKAGE_PATTERN = Pattern.compile("org\\.bukkit\\.craftbukkit\\.(v\\d+_\\d+_R\\d+)"); + + private static final MinecraftVersion CURRENT_VERSION = new MinecraftVersion(Bukkit.getBukkitVersion()); + + private static String NMS_VERSION; + + static { String craftBukkitPackage = Bukkit.getServer().getClass().getPackage().getName(); - Matcher matcher = VERSION_PATTERN.matcher(craftBukkitPackage); + Matcher matcher = PACKAGE_PATTERN.matcher(craftBukkitPackage); + + if (matcher.find()) { + NMS_VERSION = matcher.group(1); + } else { + NMS_VERSION = NmsMapping.get(CURRENT_VERSION); + } + } + + public static String nmsVersion() { + return NMS_VERSION; + } + + public static int majorVersion() { + return CURRENT_VERSION.major; + } + + public static int minorVersion() { + return CURRENT_VERSION.minor; + } + + public static int patchVersion() { + return CURRENT_VERSION.patch; + } + + public static boolean isAbove(String version) { + return CURRENT_VERSION.isAbove(new MinecraftVersion(version)); + } + + public static boolean isAtOrAbove(String version) { + return CURRENT_VERSION.isAtOrAbove(new MinecraftVersion(version)); + } + + public static boolean isAtOrBelow(String version) { + return CURRENT_VERSION.isAtOrBelow(new MinecraftVersion(version)); + } + + public static boolean isBelow(String version) { + return CURRENT_VERSION.isBelow(new MinecraftVersion(version)); + } + + private final int major; + private final int minor; + private final int patch; + + public MinecraftVersion(String version) { + Matcher matcher = VERSION_PATTERN.matcher(version); if (!matcher.find()) { - throw new RuntimeException("Can't parse craftbukkit package version " + craftBukkitPackage); + throw new IllegalArgumentException("can't parse minecraft version: " + version); + } + + this.major = Integer.parseInt(matcher.group("major")); + this.minor = Integer.parseInt(matcher.group("minor")); + + String patch = matcher.group("patch"); + if (patch != null) { + this.patch = Integer.parseInt(patch); + } else { + this.patch = 0; } + } + + public int major() { + return this.major; + } + + public int minor() { + return this.minor; + } + + public int patch() { + return this.patch; + } + + public boolean isAbove(MinecraftVersion version) { + return this.compareTo(version) > 0; + } + + public boolean isAtOrAbove(MinecraftVersion version) { + return this.compareTo(version) >= 0; + } + + public boolean isAtOrBelow(MinecraftVersion version) { + return this.compareTo(version) <= 0; + } - this.nmsVersion = matcher.group(1); - this.majorVersion = Integer.parseInt(matcher.group(2)); - this.minorVersion = Integer.parseInt(matcher.group(3)); + public boolean isBelow(MinecraftVersion version) { + return this.compareTo(version) < 0; } - private static final MinecraftVersion VERSION = new MinecraftVersion(); + @Override + public int compareTo(MinecraftVersion other) { + int major = Integer.compare(this.major, other.major); + if (major != 0) { + return major; + } + + int minor = Integer.compare(this.minor, other.minor); + if (minor != 0) { + return minor; + } - public static String getNmsVersion() { - return VERSION.nmsVersion; + return Integer.compare(this.patch, other.patch); } - public static int getMajorVersion() { - return VERSION.majorVersion; + @Override + public int hashCode() { + return Objects.hash(major, minor, patch); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof MinecraftVersion)) { + return false; + } + MinecraftVersion other = (MinecraftVersion) obj; + return major == other.major && minor == other.minor && patch == other.patch; } - public static int getMinorVersion() { - return VERSION.minorVersion; + @Override + public String toString() { + return String.format("%s.%s.%s", this.major, this.minor, this.patch); } } \ No newline at end of file diff --git a/zip-common/src/main/java/net/imprex/zip/common/ReflectionUtil.java b/zip-common/src/main/java/net/imprex/zip/common/ReflectionUtil.java index a60429d..d82461f 100644 --- a/zip-common/src/main/java/net/imprex/zip/common/ReflectionUtil.java +++ b/zip-common/src/main/java/net/imprex/zip/common/ReflectionUtil.java @@ -14,7 +14,7 @@ public static String getMinecraftServer(String className) { } public static String getCraftBukkit(String className) { - return String.format("%s.%s.%s",CRAFTBUKKIT_PATH, MinecraftVersion.getNmsVersion(), className); + return String.format("%s.%s.%s", CRAFTBUKKIT_PATH, MinecraftVersion.nmsVersion(), className); } public static Class getMinecraftServerClass(String className) { diff --git a/zip-plugin/src/main/java/net/imprex/zip/Backpack.java b/zip-plugin/src/main/java/net/imprex/zip/Backpack.java index ebb187d..41d466c 100644 --- a/zip-plugin/src/main/java/net/imprex/zip/Backpack.java +++ b/zip-plugin/src/main/java/net/imprex/zip/Backpack.java @@ -22,9 +22,11 @@ public class Backpack implements ZIPBackpack { private final BackpackHandler backpackHandler; - private final NamespacedKey storageKey; private final MessageConfig messageConfig; + private final NamespacedKey identifierKey; + private final NamespacedKey storageKey; + private final UniqueId id; private final String typeRaw; @@ -33,14 +35,15 @@ public class Backpack implements ZIPBackpack { private ItemStack[] content; private Inventory inventory; - public Backpack(BackpackPlugin plugin, BackpackType type) { + public Backpack(BackpackPlugin plugin, BackpackType type, UniqueId id) { this.backpackHandler = plugin.getBackpackHandler(); - this.storageKey = plugin.getBackpackStorageKey(); this.messageConfig = plugin.getBackpackConfig().message(); - this.type = type; + this.identifierKey = plugin.getBackpackIdentifierKey(); + this.storageKey = plugin.getBackpackStorageKey(); + this.type = type; this.typeRaw = type.getUniqueName(); - this.id = UniqueId.get(); + this.id = id != null ? id : UniqueId.get(); int rows = this.type.getInventoryRows(); String displayName = this.type.getDisplayName(); @@ -48,12 +51,15 @@ public Backpack(BackpackPlugin plugin, BackpackType type) { this.content = this.inventory.getContents(); this.backpackHandler.registerBackpack(this); + + this.save(); } public Backpack(BackpackPlugin plugin, UniqueId id, Ingrim4Buffer buffer) { this.backpackHandler = plugin.getBackpackHandler(); - this.storageKey = plugin.getBackpackStorageKey(); this.messageConfig = plugin.getBackpackConfig().message(); + this.identifierKey = plugin.getBackpackIdentifierKey(); + this.storageKey = plugin.getBackpackStorageKey(); /* * Load backpack id from buffer but don't use it! @@ -123,6 +129,7 @@ public void open(Player player) { } } else { player.sendMessage(this.messageConfig.get(MessageKey.ThisBackpackNoLongerExist)); + if (this.hasUnuseableContent()) { this.messageConfig.send(player, MessageKey.YouHaveUnusableItemsUsePickup); } @@ -133,7 +140,8 @@ public void open(Player player) { public boolean applyOnItem(ItemStack item) { if (item != null && item.hasItemMeta()) { ItemMeta meta = item.getItemMeta(); - meta.getPersistentDataContainer().set(this.storageKey, PersistentDataType.BYTE_ARRAY, id.toByteArray()); + meta.getPersistentDataContainer().set(this.storageKey, PersistentDataType.BYTE_ARRAY, this.id.toByteArray()); + meta.getPersistentDataContainer().set(this.identifierKey, PersistentDataType.STRING, this.typeRaw); item.setItemMeta(meta); return true; } diff --git a/zip-plugin/src/main/java/net/imprex/zip/BackpackHandler.java b/zip-plugin/src/main/java/net/imprex/zip/BackpackHandler.java index 9e086f8..5dd7c2d 100644 --- a/zip-plugin/src/main/java/net/imprex/zip/BackpackHandler.java +++ b/zip-plugin/src/main/java/net/imprex/zip/BackpackHandler.java @@ -66,6 +66,7 @@ public void disable() { private Backpack loadBackpack(UniqueId id) { Path file = this.folderPath.resolve(id.toString()); + if (!Files.isRegularFile(file)) { return null; } @@ -109,8 +110,13 @@ public Backpack getBackpack(UniqueId id) { if (this.loadingIssue.contains(id)) { return null; } + + Backpack backpack = this.backpackById.get(id); + if (backpack != null) { + return backpack; + } - Backpack backpack = this.loadBackpack(id); + backpack = this.loadBackpack(id); if (backpack == null) { this.loadingIssue.add(id); } @@ -137,20 +143,29 @@ public Backpack getBackpack(ItemStack item) { ItemMeta meta = item.getItemMeta(); PersistentDataContainer dataContainer = meta.getPersistentDataContainer(); + UniqueId uniqueId = null; if (dataContainer.has(this.backpackStorageKey, PersistentDataType.BYTE_ARRAY)) { byte[] storageKey = dataContainer.get(this.backpackStorageKey, PersistentDataType.BYTE_ARRAY); - UniqueId uniqueId = UniqueId.fromByteArray(storageKey); - return this.getBackpack(uniqueId); - } else if (dataContainer.has(this.backpackIdentifierKey, PersistentDataType.STRING)) { + uniqueId = UniqueId.fromByteArray(storageKey); + + Backpack backpack = this.getBackpack(uniqueId); + if (backpack != null) { + return backpack; + } + } + + if (dataContainer.has(this.backpackIdentifierKey, PersistentDataType.STRING)) { String backpackIdentifier = dataContainer.get(this.backpackIdentifierKey, PersistentDataType.STRING); BackpackType backpackType = this.registry.getTypeByName(backpackIdentifier); if (backpackType == null) { return null; } - Backpack newBackpack = backpackType.create(); - newBackpack.applyOnItem(item); - return newBackpack; + Backpack backpack = uniqueId != null + ? new Backpack(plugin, backpackType, uniqueId) + : backpackType.create(); + backpack.applyOnItem(item); + return backpack; } } diff --git a/zip-plugin/src/main/java/net/imprex/zip/BackpackType.java b/zip-plugin/src/main/java/net/imprex/zip/BackpackType.java index 16500c7..511f078 100644 --- a/zip-plugin/src/main/java/net/imprex/zip/BackpackType.java +++ b/zip-plugin/src/main/java/net/imprex/zip/BackpackType.java @@ -40,7 +40,7 @@ public ItemStack createItem() { @Override public Backpack create() { - return new Backpack(this.plugin, this); + return new Backpack(this.plugin, this, null); } @Override diff --git a/zip-plugin/src/main/java/net/imprex/zip/NmsInstance.java b/zip-plugin/src/main/java/net/imprex/zip/NmsInstance.java index f3ee527..95227f6 100644 --- a/zip-plugin/src/main/java/net/imprex/zip/NmsInstance.java +++ b/zip-plugin/src/main/java/net/imprex/zip/NmsInstance.java @@ -21,7 +21,7 @@ public static void initialize() { throw new IllegalStateException("NMS adapter is already initialized!"); } - String nmsVersion = MinecraftVersion.getNmsVersion(); + String nmsVersion = MinecraftVersion.nmsVersion(); ZIPLogger.debug("Searching NMS adapter for server version \"" + nmsVersion + "\"!"); try { diff --git a/zip-plugin/src/main/java/net/imprex/zip/config/BackpackConfig.java b/zip-plugin/src/main/java/net/imprex/zip/config/BackpackConfig.java index 4d0bdb0..31f1a71 100644 --- a/zip-plugin/src/main/java/net/imprex/zip/config/BackpackConfig.java +++ b/zip-plugin/src/main/java/net/imprex/zip/config/BackpackConfig.java @@ -28,7 +28,7 @@ public void deserialize() { Path configPath = dataFolder.resolve("config.yml"); if (Files.notExists(configPath)) { - String configVersion = MinecraftVersion.getMajorVersion() + "." + MinecraftVersion.getMinorVersion(); + String configVersion = MinecraftVersion.majorVersion() + "." + MinecraftVersion.minorVersion(); if (Files.notExists(dataFolder)) { Files.createDirectories(dataFolder);