nossr50 1 vuosi sitten
vanhempi
sitoutus
46c9ea5a25

+ 1 - 0
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:

+ 1 - 1
pom.xml

@@ -2,7 +2,7 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.gmail.nossr50.mcMMO</groupId>
     <artifactId>mcMMO</artifactId>
-    <version>2.2.011-SNAPSHOT</version>
+    <version>2.2.011</version>
     <name>mcMMO</name>
     <url>https://github.com/mcMMO-Dev/mcMMO</url>
     <scm>

+ 24 - 26
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<String> lore = new ArrayList<>();
+            final List<String> 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: "

+ 6 - 0
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.

+ 1 - 1
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
 }

+ 65 - 16
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);
+            }
+        }
+    }
 }