From 46c9ea5a25647befa56c502aa9989e2099118584 Mon Sep 17 00:00:00 2001 From: nossr50 Date: Fri, 17 May 2024 17:22:58 -0700 Subject: [PATCH] 2.2.011 --- Changelog.txt | 1 + pom.xml | 2 +- .../config/skills/alchemy/PotionConfig.java | 50 ++++++------ .../skills/alchemy/AlchemyPotion.java | 6 ++ .../nossr50/util/PotionCompatibilityType.java | 2 +- .../com/gmail/nossr50/util/PotionUtil.java | 81 +++++++++++++++---- 6 files changed, 98 insertions(+), 44 deletions(-) diff --git a/Changelog.txt b/Changelog.txt index 0b4b870d6..fa2ac2762 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,4 +1,5 @@ Version 2.2.011 + Fixed bug where some potions on older versions (1.20.4 and older) were not brewable (night vision extended, etc) Improved logging for Alchemy potion look up (see notes) NOTES: diff --git a/pom.xml b/pom.xml index 7feea2206..51cac0c77 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 com.gmail.nossr50.mcMMO mcMMO - 2.2.011-SNAPSHOT + 2.2.011 mcMMO https://github.com/mcMMO-Dev/mcMMO diff --git a/src/main/java/com/gmail/nossr50/config/skills/alchemy/PotionConfig.java b/src/main/java/com/gmail/nossr50/config/skills/alchemy/PotionConfig.java index 626719921..ecc16e66e 100644 --- a/src/main/java/com/gmail/nossr50/config/skills/alchemy/PotionConfig.java +++ b/src/main/java/com/gmail/nossr50/config/skills/alchemy/PotionConfig.java @@ -24,7 +24,7 @@ import java.util.Map; import java.util.stream.Collectors; import static com.gmail.nossr50.util.ItemUtils.setItemName; -import static com.gmail.nossr50.util.PotionUtil.matchPotionType; +import static com.gmail.nossr50.util.PotionUtil.*; public class PotionConfig extends LegacyConfigLoader { @@ -177,32 +177,14 @@ public class PotionConfig extends LegacyConfigLoader { return null; } - PotionType potionType = matchPotionType(potionTypeStr, upgraded, extended); - if (potionType == null) { - // try matching to key - mcMMO.p.getLogger().warning("Failed to match potion type, trying to match with config key..."); - matchPotionType(key, upgraded, extended); - } - - if (potionType == null) { - mcMMO.p.getLogger().severe("PotionConfig: Failed to parse potion type for: " + potionTypeStr - + ", upgraded: " + upgraded + ", extended: " + extended + " for potion " + key - + ", from configuration section: " + potion_section); + // This works via side effects + // TODO: Redesign later, side effects are stupid + if(!setPotionType(potionMeta, potionTypeStr, upgraded, extended)) { + mcMMO.p.getLogger().severe("PotionConfig: Failed to set parameters of potion for " + key + ": " + potionTypeStr); return null; } - // Set base potion type - // NOTE: extended/ignored are effectively ignored here on 1.20.5 and later - PotionUtil.setBasePotionType(potionMeta, potionType, extended, upgraded); - -// // Use the name of the potion to indicate upgrade status if not set in PotionData -// if (convertPotionConfigName(key).toUpperCase().contains("STRONG")) -// upgraded = true; -// -// if (convertPotionConfigName(key).toUpperCase().contains("LONG")) -// extended = true; - - List lore = new ArrayList<>(); + final List lore = new ArrayList<>(); if (potion_section.contains("Lore")) { for (String line : potion_section.getStringList("Lore")) { lore.add(ChatColor.translateAlternateColorCodes('&', line)); @@ -245,7 +227,6 @@ public class PotionConfig extends LegacyConfigLoader { } } } - // Set the name of the potion setPotionDisplayName(potion_section, potionMeta); @@ -254,10 +235,27 @@ public class PotionConfig extends LegacyConfigLoader { return new AlchemyPotion(potion_section.getName(), itemStack, children); } catch (Exception e) { mcMMO.p.getLogger().warning("PotionConfig: Failed to load Alchemy potion: " + potion_section.getName()); + e.printStackTrace(); return null; } } + private boolean setPotionType(PotionMeta potionMeta, String potionTypeStr, boolean upgraded, boolean extended) { + final PotionType potionType = matchPotionType(potionTypeStr, upgraded, extended); + + if (potionType == null) { + mcMMO.p.getLogger().severe("PotionConfig: Failed to parse potion type for: " + potionTypeStr); + return false; + } + + // set base + setBasePotionType(potionMeta, potionType, extended, upgraded); + + // Legacy only + setUpgradedAndExtendedProperties(potionType, potionMeta, upgraded, extended); + return true; + } + private void setPotionDisplayName(ConfigurationSection section, PotionMeta potionMeta) { // If a potion doesn't have any custom effects, there is no reason to override the vanilla name if (potionMeta.getCustomEffects().isEmpty()) { @@ -342,7 +340,7 @@ public class PotionConfig extends LegacyConfigLoader { .filter(potion -> potion.isSimilarPotion(item)) .toList(); if(potionList.size() > 1) { - mcMMO.p.getLogger().severe("Multiple potions defined in config have match this potion, for mcMMO to behave" + + mcMMO.p.getLogger().severe("Multiple potions defined in config have matched this potion, for mcMMO to behave" + " properly there should only be one match found."); mcMMO.p.getLogger().severe("Potion ItemStack:" + item.toString()); mcMMO.p.getLogger().severe("Alchemy Potions from config matching this item: " diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/alchemy/AlchemyPotion.java b/src/main/java/com/gmail/nossr50/datatypes/skills/alchemy/AlchemyPotion.java index 146894008..0b0654dda 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/skills/alchemy/AlchemyPotion.java +++ b/src/main/java/com/gmail/nossr50/datatypes/skills/alchemy/AlchemyPotion.java @@ -1,6 +1,7 @@ package com.gmail.nossr50.datatypes.skills.alchemy; import com.gmail.nossr50.mcMMO; +import com.gmail.nossr50.util.PotionUtil; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; @@ -74,6 +75,11 @@ public class AlchemyPotion { return false; } + // Legacy only comparison, compare PotionData + if (!PotionUtil.isPotionDataEqual(getAlchemyPotionMeta(), otherPotionMeta)) { + return false; + } + /* * If one potion has lore and the other does not, then they are not the same potion. * If both have lore, compare the lore. diff --git a/src/main/java/com/gmail/nossr50/util/PotionCompatibilityType.java b/src/main/java/com/gmail/nossr50/util/PotionCompatibilityType.java index 0b19748a5..6981644b3 100644 --- a/src/main/java/com/gmail/nossr50/util/PotionCompatibilityType.java +++ b/src/main/java/com/gmail/nossr50/util/PotionCompatibilityType.java @@ -2,5 +2,5 @@ package com.gmail.nossr50.util; public enum PotionCompatibilityType { PRE_1_20_5, - POST_1_20_6 + MODERN } diff --git a/src/main/java/com/gmail/nossr50/util/PotionUtil.java b/src/main/java/com/gmail/nossr50/util/PotionUtil.java index 0debc5ab8..b369250fe 100644 --- a/src/main/java/com/gmail/nossr50/util/PotionUtil.java +++ b/src/main/java/com/gmail/nossr50/util/PotionUtil.java @@ -25,9 +25,9 @@ public class PotionUtil { private static final Method methodPotionDataIsExtended; private static final Method methodPotionDataGetType; private static final Method methodPotionMetaGetBasePotionData; + private static final Method methodPotionMetaSetBasePotionData; private static final Method methodPotionMetaGetBasePotionType; private static final Method methodPotionMetaSetBasePotionType; - private static final Method methodSetBasePotionData; private static final Class potionDataClass; public static final String STRONG = "STRONG"; @@ -49,20 +49,20 @@ public class PotionUtil { legacyPotionTypes.put("REGEN", "REGENERATION"); methodPotionTypeGetKey = getKeyMethod(); methodPotionDataIsUpgraded = getPotionDataIsUpgraded(); - methodPotionDataIsExtended = getIsExtended(); - methodPotionMetaGetBasePotionData = getBasePotionData(); - methodPotionMetaGetBasePotionType = getBasePotionType(); + methodPotionDataIsExtended = getPotionDataIsExtended(); + methodPotionMetaGetBasePotionData = getGetBasePotionDataMethod(); + methodPotionMetaGetBasePotionType = getGetBasePotionTypeMethod(); methodPotionMetaSetBasePotionType = getMethodPotionMetaSetBasePotionType(); - methodPotionDataGetType = getPotionDataGetType(); - methodPotionTypeGetEffectType = getPotionTypeEffectType(); - methodPotionTypeGetPotionEffects = getPotionTypeGetPotionEffects(); - methodSetBasePotionData = getSetBasePotionData(); + methodPotionDataGetType = getPotionDataGetTypeMethod(); + methodPotionTypeGetEffectType = getPotionTypeEffectTypeMethod(); + methodPotionTypeGetPotionEffects = getPotionTypeGetPotionEffectsMethod(); + methodPotionMetaSetBasePotionData = setBasePotionData(); if (potionDataClass != null && !mcMMO.getCompatibilityManager().getMinecraftGameVersion().isAtLeast(1, 20, 5)) { COMPATIBILITY_MODE = PotionCompatibilityType.PRE_1_20_5; } else { - COMPATIBILITY_MODE = PotionCompatibilityType.POST_1_20_6; + COMPATIBILITY_MODE = PotionCompatibilityType.MODERN; } } @@ -145,6 +145,14 @@ public class PotionUtil { } } + private static @Nullable Method setBasePotionData() { + try { + return PotionMeta.class.getMethod("setBasePotionData", potionDataClass); + } catch (NoSuchMethodException e) { + return null; + } + } + private static Method getMethodPotionMetaSetBasePotionType() { try { return PotionMeta.class.getMethod("setBasePotionType", PotionType.class); @@ -171,7 +179,7 @@ public class PotionUtil { } } - private static @Nullable Method getIsExtended() { + private static @Nullable Method getPotionDataIsExtended() { try { // TODO: Needed? final Class clazz = Class.forName("org.bukkit.potion.PotionData"); @@ -186,7 +194,7 @@ public class PotionUtil { * * @return the getBasePotionData method, or null if it does not exist */ - private static @Nullable Method getBasePotionData() { + private static @Nullable Method getGetBasePotionDataMethod() { try { return PotionMeta.class.getMethod("getBasePotionData"); } catch (NoSuchMethodException e) { @@ -194,7 +202,7 @@ public class PotionUtil { } } - private static Method getBasePotionType() { + private static Method getGetBasePotionTypeMethod() { try { return PotionMeta.class.getMethod("getBasePotionType"); } catch (NoSuchMethodException e) { @@ -202,7 +210,7 @@ public class PotionUtil { } } - private static Method getPotionDataGetType() { + private static Method getPotionDataGetTypeMethod() { try { final Class clazz = Class.forName("org.bukkit.potion.PotionData"); return clazz.getMethod("getType"); @@ -211,7 +219,7 @@ public class PotionUtil { } } - private static Method getPotionTypeEffectType() { + private static Method getPotionTypeEffectTypeMethod() { try { return PotionType.class.getMethod("getEffectType"); } catch (NoSuchMethodException e) { @@ -219,7 +227,7 @@ public class PotionUtil { } } - private static Method getPotionTypeGetPotionEffects() { + private static Method getPotionTypeGetPotionEffectsMethod() { try { return PotionType.class.getMethod("getPotionEffects"); } catch (NoSuchMethodException e) { @@ -474,12 +482,28 @@ public class PotionUtil { } } + public static void setUpgradedAndExtendedProperties(PotionType potionType, PotionMeta potionMeta, + boolean isUpgraded, boolean isExtended) { + if (potionDataClass == null || mcMMO.getCompatibilityManager().getMinecraftGameVersion().isAtLeast(1, 20, 5)) { + return; + } + + try { + final Object potionData = potionDataClass.getConstructor(PotionType.class, boolean.class, boolean.class) + .newInstance(potionType, isExtended, isUpgraded); + methodPotionMetaSetBasePotionData.invoke(potionMeta, potionData); + } catch (IllegalAccessException | InvocationTargetException | InstantiationException + | NoSuchMethodException ex) { + throw new RuntimeException(ex); + } + } + private static void setBasePotionTypeLegacy(PotionMeta potionMeta, PotionType potionType, boolean extended, boolean upgraded) { try { Object potionData = potionDataClass.getConstructor(PotionType.class, boolean.class, boolean.class) .newInstance(potionType, extended, upgraded); - methodSetBasePotionData.invoke(potionMeta, potionData); + methodPotionMetaSetBasePotionData.invoke(potionMeta, potionData); } catch (IllegalAccessException | InvocationTargetException | InstantiationException | NoSuchMethodException ex) { throw new RuntimeException(ex); } @@ -492,4 +516,29 @@ public class PotionUtil { throw new RuntimeException(ex); } } + + public static boolean isPotionDataEqual(PotionMeta potionMeta, PotionMeta otherPotionMeta) { + if (COMPATIBILITY_MODE == PotionCompatibilityType.MODERN) { + return true; // we don't compare data on newer versions + } else { + try { + final Object potionData = methodPotionMetaGetBasePotionData.invoke(potionMeta); + final Object otherPotionData = methodPotionMetaGetBasePotionData.invoke(otherPotionMeta); + final PotionType potionType = (PotionType) methodPotionDataGetType.invoke(potionData); + final PotionType otherPotionType = (PotionType) methodPotionDataGetType.invoke(otherPotionData); + if (potionType != otherPotionType) { + return false; + } + if (methodPotionDataIsExtended.invoke(potionData) != methodPotionDataIsExtended.invoke(otherPotionData)) { + return false; + } + if (methodPotionDataIsUpgraded.invoke(potionData) != methodPotionDataIsUpgraded.invoke(otherPotionData)) { + return false; + } + return true; + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + } }