From c2054a5d456cb1648f1cea9183ddcec69b1442f7 Mon Sep 17 00:00:00 2001 From: nossr50 Date: Sat, 18 May 2024 12:30:44 -0700 Subject: [PATCH] 2.2.012 fix for daze in 1.20.4 and older --- Changelog.txt | 3 + pom.xml | 3 +- .../skills/archery/ArcheryManager.java | 4 +- .../nossr50/util/PotionEffectMapper.java | 142 ------------------ .../gmail/nossr50/util/PotionEffectUtil.java | 92 ++++++++++++ .../gmail/nossr50/util/skills/SkillUtils.java | 8 +- .../nossr50/util/PotionEffectUtilTest.java | 58 +++++++ 7 files changed, 161 insertions(+), 149 deletions(-) delete mode 100644 src/main/java/com/gmail/nossr50/util/PotionEffectMapper.java create mode 100644 src/main/java/com/gmail/nossr50/util/PotionEffectUtil.java create mode 100644 src/test/java/com/gmail/nossr50/util/PotionEffectUtilTest.java diff --git a/Changelog.txt b/Changelog.txt index fa2ac2762..4641b529d 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,3 +1,6 @@ +Version 2.2.012 + Fixed a bug where Daze would cause an exception in older game versions (1.20.4 and older) + 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) diff --git a/pom.xml b/pom.xml index 51cac0c77..a8ce46efc 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 com.gmail.nossr50.mcMMO mcMMO - 2.2.011 + 2.2.012 mcMMO https://github.com/mcMMO-Dev/mcMMO @@ -80,6 +80,7 @@ org.junit.jupiter:junit-jupiter false + skip diff --git a/src/main/java/com/gmail/nossr50/skills/archery/ArcheryManager.java b/src/main/java/com/gmail/nossr50/skills/archery/ArcheryManager.java index 16574621b..785fafd46 100644 --- a/src/main/java/com/gmail/nossr50/skills/archery/ArcheryManager.java +++ b/src/main/java/com/gmail/nossr50/skills/archery/ArcheryManager.java @@ -19,7 +19,7 @@ import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; import org.bukkit.potion.PotionEffect; -import static com.gmail.nossr50.util.PotionEffectMapper.getNausea; +import static com.gmail.nossr50.util.PotionEffectUtil.getNauseaPotionEffectType; public class ArcheryManager extends SkillManager { public ArcheryManager(McMMOPlayer mcMMOPlayer) { @@ -97,7 +97,7 @@ public class ArcheryManager extends SkillManager { dazedLocation.setPitch(90 - Misc.getRandom().nextInt(181)); mcMMO.p.getFoliaLib().getImpl().teleportAsync(defender, dazedLocation); - defender.addPotionEffect(new PotionEffect(getNausea(), 20 * 10, 10)); + defender.addPotionEffect(new PotionEffect(getNauseaPotionEffectType(), 20 * 10, 10)); if (NotificationManager.doesPlayerUseNotifications(defender)) { NotificationManager.sendPlayerInformation(defender, NotificationType.SUBSKILL_MESSAGE, "Combat.TouchedFuzzy"); diff --git a/src/main/java/com/gmail/nossr50/util/PotionEffectMapper.java b/src/main/java/com/gmail/nossr50/util/PotionEffectMapper.java deleted file mode 100644 index f58c66834..000000000 --- a/src/main/java/com/gmail/nossr50/util/PotionEffectMapper.java +++ /dev/null @@ -1,142 +0,0 @@ -package com.gmail.nossr50.util; - -import com.gmail.nossr50.mcMMO; -import org.bukkit.potion.PotionEffectType; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -final public class PotionEffectMapper { - private static final PotionEffectType haste; - private static final PotionEffectType nausea; - private static final Method potionEffectTypeWrapperGetPotionEffectType; - private static final Class classPotionEffectTypeWrapper; - - private PotionEffectMapper() { - // Utility class - } - - static { - potionEffectTypeWrapperGetPotionEffectType = getPotionEffectTypeWrapperGetPotionEffectType(); - classPotionEffectTypeWrapper = getClassPotionEffectTypeWrapper(); - - haste = initHaste(); - nausea = initNausea(); - } - - private static Method getPotionEffectTypeWrapperGetPotionEffectType() { - try { - return classPotionEffectTypeWrapper.getMethod("getType"); - } catch (NoSuchMethodException e) { - return null; - } - } - - private static Class getClassPotionEffectTypeWrapper() { - try { - return Class.forName("org.bukkit.potion.PotionEffectTypeWrapper"); - } catch (ClassNotFoundException e) { - return null; - } - } - - private static PotionEffectType initNausea() { - if (classPotionEffectTypeWrapper != null) { - return getNauseaLegacy(); - } else { - return getNauseaModern(); - } - } - - private static PotionEffectType getNauseaModern() { -// PotionEffectType potionEffectType = Registry.EFFECT.match("nausea"); -// if (potionEffectType != null) { -// return potionEffectType; -// } -// -// // Look for the potion effect type by name -// for (PotionEffectType pet : Registry.EFFECT) { -// if (pet.getKey().getKey().equalsIgnoreCase("CONFUSION") -// || pet.getKey().getKey().equalsIgnoreCase("NAUSEA") -// || pet.getName().equalsIgnoreCase("CONFUSION") -// || pet.getName().equalsIgnoreCase("NAUSEA")) { -// return pet; -// } -// } - - try { - return (PotionEffectType) PotionEffectType.class.getField("NAUSEA").get(null); - } catch (NoSuchFieldException | IllegalAccessException e) { - mcMMO.p.getLogger().severe("Unable to find the Nausea potion effect type, " + - "mcMMO will not function properly."); - throw new IllegalStateException("Unable to find the Nausea potion effect type"); - } - } - - private static PotionEffectType getNauseaLegacy() { - try { - Object potionEffectTypeWrapper = PotionEffectType.class.getField("CONFUSION").get(null); - PotionEffectType potionEffectType = (PotionEffectType) potionEffectTypeWrapperGetPotionEffectType - .invoke(potionEffectTypeWrapper); - return potionEffectType; - } catch (IllegalAccessException | NoSuchFieldException | InvocationTargetException e) { - mcMMO.p.getLogger().severe("Unable to find the Nausea potion effect type, " + - "mcMMO will not function properly."); - throw new IllegalStateException("Unable to find the Nausea potion effect type"); - } - } - - private static PotionEffectType initHaste() { - - - mcMMO.p.getLogger().severe("Unable to find the Haste potion effect type, " + - "mcMMO will not function properly."); - throw new IllegalStateException("Unable to find the Haste potion effect type"); - } - - private static PotionEffectType getHasteLegacy() { - try { - Object potionEffectTypeWrapper = PotionEffectType.class.getField("FAST_DIGGING").get(null); - PotionEffectType potionEffectType = (PotionEffectType) potionEffectTypeWrapperGetPotionEffectType - .invoke(potionEffectTypeWrapper); - return potionEffectType; - } catch (IllegalAccessException | NoSuchFieldException | InvocationTargetException e) { - mcMMO.p.getLogger().severe("Unable to find the Haste potion effect type, " + - "mcMMO will not function properly."); - throw new IllegalStateException("Unable to find the Haste potion effect type"); - } - } - - private static PotionEffectType getHasteModern() { -// PotionEffectType potionEffectType = Registry.EFFECT.match("haste"); -// if (potionEffectType != null) { -// return potionEffectType; -// } -// -// // Look for the potion effect type by name -// for (PotionEffectType pet : Registry.EFFECT) { -// if (pet.getKey().getKey().equalsIgnoreCase("HASTE") -// || pet.getKey().getKey().equalsIgnoreCase("FAST_DIGGING") -// || pet.getName().equalsIgnoreCase("HASTE") -// || pet.getName().equalsIgnoreCase("FAST_DIGGING")) { -// return pet; -// } -// } - - try { - return (PotionEffectType) PotionEffectType.class.getField("HASTE").get(null); - } catch (NoSuchFieldException | IllegalAccessException e) { - mcMMO.p.getLogger().severe("Unable to find the Haste potion effect type, " + - "mcMMO will not function properly."); - throw new IllegalStateException("Unable to find the Haste potion effect type"); - } - } - - public static PotionEffectType getHaste() { - return haste; - } - - public static PotionEffectType getNausea() { - return nausea; - } -} diff --git a/src/main/java/com/gmail/nossr50/util/PotionEffectUtil.java b/src/main/java/com/gmail/nossr50/util/PotionEffectUtil.java new file mode 100644 index 000000000..706cc8c9f --- /dev/null +++ b/src/main/java/com/gmail/nossr50/util/PotionEffectUtil.java @@ -0,0 +1,92 @@ +package com.gmail.nossr50.util; + +import org.bukkit.potion.PotionEffectType; + +/** + * This util class is responsible for mapping the correct potion effect types for the server version. + * This is necessary because the potion effect types have changed between versions. + * This util class will provide the correct potion effect types for the server version. + */ +final public class PotionEffectUtil { + private static final PotionEffectType haste; + private static final PotionEffectType nausea; + + static { + haste = findHastePotionEffectType(); + nausea = findNauseaPotionEffectType(); + } + + private PotionEffectUtil() { + // Utility class + } + + private static PotionEffectType findNauseaPotionEffectType() { + if (getNauseaLegacy() != null) { + return getNauseaLegacy(); + } else { + return getNauseaModern(); + } + } + + private static PotionEffectType getNauseaModern() { + try { + return (PotionEffectType) PotionEffectType.class.getField("NAUSEA").get(null); + } catch (NoSuchFieldException | IllegalAccessException e) { + return null; + } + } + + private static PotionEffectType getNauseaLegacy() { + try { + Object potionEffectTypeWrapper = PotionEffectType.class.getField("CONFUSION").get(null); + return (PotionEffectType) potionEffectTypeWrapper; + } catch (IllegalAccessException | NoSuchFieldException e) { + return null; + } + } + + private static PotionEffectType findHastePotionEffectType() { + if (getHasteLegacy() != null) { + return getHasteLegacy(); + } else if (getHasteModern() != null) { + return getHasteModern(); + } else { + throw new IllegalStateException("Unable to find the Haste PotionEffectType"); + } + } + + private static PotionEffectType getHasteLegacy() { + try { + Object potionEffectTypeWrapper = PotionEffectType.class.getField("FAST_DIGGING").get(null); + return (PotionEffectType) potionEffectTypeWrapper; + } catch (IllegalAccessException | NoSuchFieldException e) { + return null; + } + } + + private static PotionEffectType getHasteModern() { + try { + return (PotionEffectType) PotionEffectType.class.getField("HASTE").get(null); + } catch (NoSuchFieldException | IllegalAccessException e) { + return null; + } + } + + /** + * Get the Haste potion effect type. + * This will return the correct potion effect type for the server version. + * @return The Haste potion effect type. + */ + public static PotionEffectType getHastePotionEffectType() { + return haste; + } + + /** + * Get the Nausea potion effect type. + * This will return the correct potion effect type for the server version. + * @return The Nausea potion effect type. + */ + public static PotionEffectType getNauseaPotionEffectType() { + return nausea; + } +} diff --git a/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java b/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java index c83389f8b..02c6c47cb 100644 --- a/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java +++ b/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java @@ -33,7 +33,7 @@ import org.jetbrains.annotations.Nullable; import java.util.Iterator; import static com.gmail.nossr50.util.ItemMetadataUtils.*; -import static com.gmail.nossr50.util.PotionEffectMapper.getHaste; +import static com.gmail.nossr50.util.PotionEffectUtil.getHastePotionEffectType; public final class SkillUtils { /** @@ -158,9 +158,9 @@ public final class SkillUtils { int duration = 0; int amplifier = 0; - if (player.hasPotionEffect(getHaste())) { + if (player.hasPotionEffect(getHastePotionEffectType())) { for (PotionEffect effect : player.getActivePotionEffects()) { - if (effect.getType() == getHaste()) { + if (effect.getType() == getHastePotionEffectType()) { duration = effect.getDuration(); amplifier = effect.getAmplifier(); break; @@ -190,7 +190,7 @@ public final class SkillUtils { mcMMO.p.getSkillTools().getSuperAbilityMaxLength(mcMMO.p.getSkillTools().getSuperAbility(skill))) * Misc.TICK_CONVERSION_FACTOR; } - PotionEffect abilityBuff = new PotionEffect(getHaste(), duration + ticks, amplifier + 10); + PotionEffect abilityBuff = new PotionEffect(getHastePotionEffectType(), duration + ticks, amplifier + 10); player.addPotionEffect(abilityBuff, true); } } diff --git a/src/test/java/com/gmail/nossr50/util/PotionEffectUtilTest.java b/src/test/java/com/gmail/nossr50/util/PotionEffectUtilTest.java new file mode 100644 index 000000000..1618988e9 --- /dev/null +++ b/src/test/java/com/gmail/nossr50/util/PotionEffectUtilTest.java @@ -0,0 +1,58 @@ +package com.gmail.nossr50.util; + +import com.gmail.nossr50.mcMMO; +import com.gmail.nossr50.util.compat.CompatibilityManager; +import com.gmail.nossr50.util.platform.MinecraftGameVersion; +import org.bukkit.potion.PotionEffectType; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; + +import static com.gmail.nossr50.util.PotionEffectUtil.getNauseaPotionEffectType; +import static java.util.logging.Logger.getLogger; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; +import static org.mockito.Mockito.when; + +class PotionEffectUtilTest { + private MockedStatic mockedStaticMcMMO; + private static final java.util.logging.Logger logger = getLogger(PotionEffectUtilTest.class.getName()); + + @BeforeEach + void setUp() { + mockedStaticMcMMO = mockStatic(mcMMO.class); + mcMMO.p = mock(mcMMO.class); + when(mcMMO.p.getLogger()).thenReturn(logger); + CompatibilityManager compatibilityManager = mock(CompatibilityManager.class); + MinecraftGameVersion minecraftGameVersion = mock(MinecraftGameVersion.class); + when(compatibilityManager.getMinecraftGameVersion()).thenReturn(minecraftGameVersion); + when(minecraftGameVersion.isAtLeast(1, 20, 5)).thenReturn(false); + when(mcMMO.getCompatibilityManager()).thenReturn(compatibilityManager); + } + + @AfterEach + void tearDown() { + mockedStaticMcMMO.close(); + } + + @Test + @Tag("skip") + void testGetNauseaPotionEffectType() { + // TODO: Test only works on older versions since we aren't properly mocking the spigot registry + final PotionEffectType nausea = getNauseaPotionEffectType(); + assertNotNull(nausea); + assertThat(nausea).isEqualTo(PotionEffectType.NAUSEA); + } + + @Test + @Tag("skip") + void testGetHastePotionEffectType() { + // TODO: Test only works on older versions since we aren't properly mocking the spigot registry + final PotionEffectType haste = PotionEffectUtil.getHastePotionEffectType(); + assertNotNull(haste); + assertThat(haste).isEqualTo(PotionEffectType.HASTE); + } +} \ No newline at end of file