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