This commit is contained in:
nossr50 2024-05-17 17:22:58 -07:00
parent e6ff219a5c
commit 46c9ea5a25
6 changed files with 98 additions and 44 deletions

View File

@ -1,4 +1,5 @@
Version 2.2.011 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) Improved logging for Alchemy potion look up (see notes)
NOTES: NOTES:

View File

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

View File

@ -24,7 +24,7 @@ import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static com.gmail.nossr50.util.ItemUtils.setItemName; 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 { public class PotionConfig extends LegacyConfigLoader {
@ -177,32 +177,14 @@ public class PotionConfig extends LegacyConfigLoader {
return null; return null;
} }
PotionType potionType = matchPotionType(potionTypeStr, upgraded, extended); // This works via side effects
if (potionType == null) { // TODO: Redesign later, side effects are stupid
// try matching to key if(!setPotionType(potionMeta, potionTypeStr, upgraded, extended)) {
mcMMO.p.getLogger().warning("Failed to match potion type, trying to match with config key..."); mcMMO.p.getLogger().severe("PotionConfig: Failed to set parameters of potion for " + key + ": " + potionTypeStr);
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);
return null; return null;
} }
// Set base potion type final List<String> lore = new ArrayList<>();
// 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<>();
if (potion_section.contains("Lore")) { if (potion_section.contains("Lore")) {
for (String line : potion_section.getStringList("Lore")) { for (String line : potion_section.getStringList("Lore")) {
lore.add(ChatColor.translateAlternateColorCodes('&', line)); lore.add(ChatColor.translateAlternateColorCodes('&', line));
@ -245,7 +227,6 @@ public class PotionConfig extends LegacyConfigLoader {
} }
} }
} }
// Set the name of the potion // Set the name of the potion
setPotionDisplayName(potion_section, potionMeta); setPotionDisplayName(potion_section, potionMeta);
@ -254,10 +235,27 @@ public class PotionConfig extends LegacyConfigLoader {
return new AlchemyPotion(potion_section.getName(), itemStack, children); return new AlchemyPotion(potion_section.getName(), itemStack, children);
} catch (Exception e) { } catch (Exception e) {
mcMMO.p.getLogger().warning("PotionConfig: Failed to load Alchemy potion: " + potion_section.getName()); mcMMO.p.getLogger().warning("PotionConfig: Failed to load Alchemy potion: " + potion_section.getName());
e.printStackTrace();
return null; 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) { 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 a potion doesn't have any custom effects, there is no reason to override the vanilla name
if (potionMeta.getCustomEffects().isEmpty()) { if (potionMeta.getCustomEffects().isEmpty()) {
@ -342,7 +340,7 @@ public class PotionConfig extends LegacyConfigLoader {
.filter(potion -> potion.isSimilarPotion(item)) .filter(potion -> potion.isSimilarPotion(item))
.toList(); .toList();
if(potionList.size() > 1) { 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."); " properly there should only be one match found.");
mcMMO.p.getLogger().severe("Potion ItemStack:" + item.toString()); mcMMO.p.getLogger().severe("Potion ItemStack:" + item.toString());
mcMMO.p.getLogger().severe("Alchemy Potions from config matching this item: " mcMMO.p.getLogger().severe("Alchemy Potions from config matching this item: "

View File

@ -1,6 +1,7 @@
package com.gmail.nossr50.datatypes.skills.alchemy; package com.gmail.nossr50.datatypes.skills.alchemy;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.PotionUtil;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.inventory.meta.PotionMeta;
@ -74,6 +75,11 @@ public class AlchemyPotion {
return false; 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 one potion has lore and the other does not, then they are not the same potion.
* If both have lore, compare the lore. * If both have lore, compare the lore.

View File

@ -2,5 +2,5 @@ package com.gmail.nossr50.util;
public enum PotionCompatibilityType { public enum PotionCompatibilityType {
PRE_1_20_5, PRE_1_20_5,
POST_1_20_6 MODERN
} }

View File

@ -25,9 +25,9 @@ public class PotionUtil {
private static final Method methodPotionDataIsExtended; private static final Method methodPotionDataIsExtended;
private static final Method methodPotionDataGetType; private static final Method methodPotionDataGetType;
private static final Method methodPotionMetaGetBasePotionData; private static final Method methodPotionMetaGetBasePotionData;
private static final Method methodPotionMetaSetBasePotionData;
private static final Method methodPotionMetaGetBasePotionType; private static final Method methodPotionMetaGetBasePotionType;
private static final Method methodPotionMetaSetBasePotionType; private static final Method methodPotionMetaSetBasePotionType;
private static final Method methodSetBasePotionData;
private static final Class<?> potionDataClass; private static final Class<?> potionDataClass;
public static final String STRONG = "STRONG"; public static final String STRONG = "STRONG";
@ -49,20 +49,20 @@ public class PotionUtil {
legacyPotionTypes.put("REGEN", "REGENERATION"); legacyPotionTypes.put("REGEN", "REGENERATION");
methodPotionTypeGetKey = getKeyMethod(); methodPotionTypeGetKey = getKeyMethod();
methodPotionDataIsUpgraded = getPotionDataIsUpgraded(); methodPotionDataIsUpgraded = getPotionDataIsUpgraded();
methodPotionDataIsExtended = getIsExtended(); methodPotionDataIsExtended = getPotionDataIsExtended();
methodPotionMetaGetBasePotionData = getBasePotionData(); methodPotionMetaGetBasePotionData = getGetBasePotionDataMethod();
methodPotionMetaGetBasePotionType = getBasePotionType(); methodPotionMetaGetBasePotionType = getGetBasePotionTypeMethod();
methodPotionMetaSetBasePotionType = getMethodPotionMetaSetBasePotionType(); methodPotionMetaSetBasePotionType = getMethodPotionMetaSetBasePotionType();
methodPotionDataGetType = getPotionDataGetType(); methodPotionDataGetType = getPotionDataGetTypeMethod();
methodPotionTypeGetEffectType = getPotionTypeEffectType(); methodPotionTypeGetEffectType = getPotionTypeEffectTypeMethod();
methodPotionTypeGetPotionEffects = getPotionTypeGetPotionEffects(); methodPotionTypeGetPotionEffects = getPotionTypeGetPotionEffectsMethod();
methodSetBasePotionData = getSetBasePotionData(); methodPotionMetaSetBasePotionData = setBasePotionData();
if (potionDataClass != null if (potionDataClass != null
&& !mcMMO.getCompatibilityManager().getMinecraftGameVersion().isAtLeast(1, 20, 5)) { && !mcMMO.getCompatibilityManager().getMinecraftGameVersion().isAtLeast(1, 20, 5)) {
COMPATIBILITY_MODE = PotionCompatibilityType.PRE_1_20_5; COMPATIBILITY_MODE = PotionCompatibilityType.PRE_1_20_5;
} else { } 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() { private static Method getMethodPotionMetaSetBasePotionType() {
try { try {
return PotionMeta.class.getMethod("setBasePotionType", PotionType.class); 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 { try {
// TODO: <?> Needed? // TODO: <?> Needed?
final Class<?> clazz = Class.forName("org.bukkit.potion.PotionData"); 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 * @return the getBasePotionData method, or null if it does not exist
*/ */
private static @Nullable Method getBasePotionData() { private static @Nullable Method getGetBasePotionDataMethod() {
try { try {
return PotionMeta.class.getMethod("getBasePotionData"); return PotionMeta.class.getMethod("getBasePotionData");
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
@ -194,7 +202,7 @@ public class PotionUtil {
} }
} }
private static Method getBasePotionType() { private static Method getGetBasePotionTypeMethod() {
try { try {
return PotionMeta.class.getMethod("getBasePotionType"); return PotionMeta.class.getMethod("getBasePotionType");
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
@ -202,7 +210,7 @@ public class PotionUtil {
} }
} }
private static Method getPotionDataGetType() { private static Method getPotionDataGetTypeMethod() {
try { try {
final Class<?> clazz = Class.forName("org.bukkit.potion.PotionData"); final Class<?> clazz = Class.forName("org.bukkit.potion.PotionData");
return clazz.getMethod("getType"); return clazz.getMethod("getType");
@ -211,7 +219,7 @@ public class PotionUtil {
} }
} }
private static Method getPotionTypeEffectType() { private static Method getPotionTypeEffectTypeMethod() {
try { try {
return PotionType.class.getMethod("getEffectType"); return PotionType.class.getMethod("getEffectType");
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
@ -219,7 +227,7 @@ public class PotionUtil {
} }
} }
private static Method getPotionTypeGetPotionEffects() { private static Method getPotionTypeGetPotionEffectsMethod() {
try { try {
return PotionType.class.getMethod("getPotionEffects"); return PotionType.class.getMethod("getPotionEffects");
} catch (NoSuchMethodException e) { } 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, private static void setBasePotionTypeLegacy(PotionMeta potionMeta, PotionType potionType, boolean extended,
boolean upgraded) { boolean upgraded) {
try { try {
Object potionData = potionDataClass.getConstructor(PotionType.class, boolean.class, boolean.class) Object potionData = potionDataClass.getConstructor(PotionType.class, boolean.class, boolean.class)
.newInstance(potionType, extended, upgraded); .newInstance(potionType, extended, upgraded);
methodSetBasePotionData.invoke(potionMeta, potionData); methodPotionMetaSetBasePotionData.invoke(potionMeta, potionData);
} catch (IllegalAccessException | InvocationTargetException | InstantiationException | NoSuchMethodException ex) { } catch (IllegalAccessException | InvocationTargetException | InstantiationException | NoSuchMethodException ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }
@ -492,4 +516,29 @@ public class PotionUtil {
throw new RuntimeException(ex); 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);
}
}
}
} }