From 9ec675f1628c9289a3ac4045960ba31341c253f4 Mon Sep 17 00:00:00 2001 From: Almighty-Satan <43804777+Almighty-Satan@users.noreply.github.com> Date: Sat, 5 Oct 2024 13:52:40 +0200 Subject: [PATCH] Revert "feat: new xp cooldown field resolving method" --- .../cfw/version/CrucibleVersionAdapter.java | 6 +- .../version/MagmaOneTwelveVersionAdapter.java | 59 +++++++++++++ .../cfw/version/OneSevenVersionAdapter.java | 87 +++++++------------ .../version/OneSeventeenVersionAdapter.java | 6 +- .../cfw/version/OneTwentyVersionAdapter.java | 4 +- .../cfw/version/ServerSoftware.java | 2 +- 6 files changed, 100 insertions(+), 64 deletions(-) create mode 100644 src/main/java/de/varoplugin/cfw/version/MagmaOneTwelveVersionAdapter.java diff --git a/src/main/java/de/varoplugin/cfw/version/CrucibleVersionAdapter.java b/src/main/java/de/varoplugin/cfw/version/CrucibleVersionAdapter.java index 1142746d..c2b46977 100644 --- a/src/main/java/de/varoplugin/cfw/version/CrucibleVersionAdapter.java +++ b/src/main/java/de/varoplugin/cfw/version/CrucibleVersionAdapter.java @@ -64,10 +64,10 @@ protected void initLocale() throws NoSuchFieldException, SecurityException, Ille } @Override - protected void initXp(Player player) { + protected void initXp() { try { - Class entityHumanClass = Class.forName("net.minecraft.entity.player.EntityPlayer"); - this.xpCooldownField = entityHumanClass.getDeclaredField("field_71090_bL"); + Class entityHuman = Class.forName("net.minecraft.entity.player.EntityPlayer"); + this.xpCooldownField = entityHuman.getDeclaredField("field_71090_bL"); } catch (Throwable t) { t.printStackTrace(); } diff --git a/src/main/java/de/varoplugin/cfw/version/MagmaOneTwelveVersionAdapter.java b/src/main/java/de/varoplugin/cfw/version/MagmaOneTwelveVersionAdapter.java new file mode 100644 index 00000000..f64738a4 --- /dev/null +++ b/src/main/java/de/varoplugin/cfw/version/MagmaOneTwelveVersionAdapter.java @@ -0,0 +1,59 @@ +/* + * MIT License + * + * Copyright (c) 2020-2022 CuukyOfficial + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package de.varoplugin.cfw.version; + +import java.lang.reflect.Field; + +class MagmaOneTwelveVersionAdapter extends OneTwelveVersionAdapter { + + @Override + protected void initXp(String entityHumanName, String foodMetaName) { + // this is EXTREMELY unsafe + try { + Class foodMetaClass = Class.forName(foodMetaName); + int fieldNum = 0; + for (Field field : Class.forName(entityHumanName).getDeclaredFields()) + if (fieldNum == 0 && field.getType() == foodMetaClass) + fieldNum = 1; + else if (fieldNum == 1 && field.getType() == foodMetaClass) + fieldNum = 2; + else if (fieldNum == 2 && field.getType() == int.class) + fieldNum = 3; + else if (fieldNum == 3 && field.getType() == float.class) + fieldNum = 4; + else if (fieldNum == 4 && field.getType() == float.class) + fieldNum = 5; + else if (fieldNum == 5 && field.getType() == int.class) { + this.xpCooldownField = field; + return; + } else + fieldNum = 0; + + throw new Error("Unable to find xp cooldown field"); + } catch (SecurityException | ClassNotFoundException e) { + throw new Error(e); + } + } +} diff --git a/src/main/java/de/varoplugin/cfw/version/OneSevenVersionAdapter.java b/src/main/java/de/varoplugin/cfw/version/OneSevenVersionAdapter.java index 6cf7737a..494e2c05 100644 --- a/src/main/java/de/varoplugin/cfw/version/OneSevenVersionAdapter.java +++ b/src/main/java/de/varoplugin/cfw/version/OneSevenVersionAdapter.java @@ -29,8 +29,6 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Collection; -import java.util.HashMap; -import java.util.Map; import java.util.Properties; import org.bukkit.Bukkit; @@ -40,8 +38,6 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.ExperienceOrb; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -81,52 +77,7 @@ protected void init() throws IllegalArgumentException, NoSuchMethodException, Se this.initRespawn(); this.initNetworkManager(); this.initLocale(); - } - - protected void initXp(Player player) { - this.searchXpField(player, VersionUtils.getNmsClass() + ".EntityHuman", VersionUtils.getNmsClass() + ".EntityExperienceOrb"); - } - - protected void searchXpField(Player player, String humanClassName, String experienceOrbClassName) { - try { - Class entityHumanClass = Class.forName(humanClassName); - Map values = new HashMap<>(); - Object craftPlayer = this.getHandle(player); - - // Get values of all int fields of player - for (Field field : entityHumanClass.getDeclaredFields()) { - if (field.getType() == int.class) { - field.setAccessible(true); - values.put(field, field.getInt(craftPlayer)); - } - } - - // Invoke method which sets the value of xp cooldown to 2 - Location randomLoc = new Location(player.getWorld(), 0, 0, 0); - ExperienceOrb orb = (ExperienceOrb) player.getWorld().spawnEntity(randomLoc, EntityType.EXPERIENCE_ORB); - orb.setExperience(0); - Class entityExperienceOrbClass = Class.forName(experienceOrbClassName); - for (Method method : entityExperienceOrbClass.getDeclaredMethods()) { - if (method.getParameterTypes().length == 1 && method.getParameterTypes()[0] == entityHumanClass) { - method.setAccessible(true); - method.invoke(this.getHandle(orb), craftPlayer); - } - } - - orb.remove(); - - // Compare values and use the field with changed value - for (Field field : values.keySet()) { - if (field.getInt(craftPlayer) != values.get(field)) { - this.xpCooldownField = field; - return; - } - } - - throw new Error("Unable to find xp cooldown field"); - } catch (SecurityException | IllegalAccessException | InvocationTargetException | ClassNotFoundException e) { - throw new Error(e); - } + this.initXp(); } protected void initServerProperties() throws ClassNotFoundException, NoSuchMethodException, SecurityException, NoSuchFieldException { @@ -167,6 +118,38 @@ protected void initLocale() throws NoSuchFieldException, SecurityException, Ille this.localeField.setAccessible(true); } + protected void initXp() { + this.initXp(VersionUtils.getNmsClass() + ".EntityHuman", VersionUtils.getNmsClass() + ".FoodMetaData"); + } + + protected void initXp(String entityHumanName, String foodMetaName) { + // this is EXTREMELY unsafe + try { + int fieldNum = 0; + for (Field field : Class.forName(entityHumanName).getDeclaredFields()) + if (fieldNum == 0 && field.getType() == Class.forName(foodMetaName)) + fieldNum = 1; + // This is for 1.19+, but I don't want to create a new version adapter class for one single line of code (Yes, I am lazy) + else if (fieldNum == 1 && field.getType().getName().equals("net.minecraft.world.entity.monster.warden.WardenSpawnTracker")) + ; + else if (fieldNum == 1 && field.getType() == int.class) + fieldNum = 2; + else if (fieldNum == 2 && field.getType() == float.class) + fieldNum = 3; + else if (fieldNum == 3 && field.getType() == float.class) + fieldNum = 4; + else if (fieldNum == 4 && field.getType() == int.class) { + this.xpCooldownField = field; + return; + } else + fieldNum = 0; + + throw new Error("Unable to find xp cooldown field"); + } catch (SecurityException | ClassNotFoundException e) { + throw new Error(e); + } + } + protected Object getHandle(Entity entity) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { return this.entityHandleMethod.invoke(entity); } @@ -280,10 +263,6 @@ public void removeAi(LivingEntity entity) { @Override public void setXpCooldown(Player player, int cooldown) { - if (this.xpCooldownField == null) { - this.initXp(player); - } - try { this.xpCooldownField.set(this.getHandle(player), cooldown); } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) { diff --git a/src/main/java/de/varoplugin/cfw/version/OneSeventeenVersionAdapter.java b/src/main/java/de/varoplugin/cfw/version/OneSeventeenVersionAdapter.java index 5fde590b..2c3c3eee 100644 --- a/src/main/java/de/varoplugin/cfw/version/OneSeventeenVersionAdapter.java +++ b/src/main/java/de/varoplugin/cfw/version/OneSeventeenVersionAdapter.java @@ -50,10 +50,8 @@ protected void initRespawn() { } @Override - protected void initXp(Player player) { - String entityHumanClass = "net.minecraft.world.entity.player.EntityHuman"; - String entityExperienceOrbClass = "net.minecraft.world.entity.EntityExperienceOrb"; - this.searchXpField(player, entityHumanClass, entityExperienceOrbClass); + protected void initXp() { + this.initXp("net.minecraft.world.entity.player.EntityHuman", "net.minecraft.world.food.FoodMetaData"); } @Override diff --git a/src/main/java/de/varoplugin/cfw/version/OneTwentyVersionAdapter.java b/src/main/java/de/varoplugin/cfw/version/OneTwentyVersionAdapter.java index d43c8f82..32d028e2 100644 --- a/src/main/java/de/varoplugin/cfw/version/OneTwentyVersionAdapter.java +++ b/src/main/java/de/varoplugin/cfw/version/OneTwentyVersionAdapter.java @@ -29,8 +29,8 @@ public class OneTwentyVersionAdapter extends OneNineteenVersionAdapter { @Override - protected void initXp(Player player) { - // Not needed, since Player#setExpCooldown is available + protected void initXp() { + // nop } @Override diff --git a/src/main/java/de/varoplugin/cfw/version/ServerSoftware.java b/src/main/java/de/varoplugin/cfw/version/ServerSoftware.java index 9bb89b23..99c53837 100644 --- a/src/main/java/de/varoplugin/cfw/version/ServerSoftware.java +++ b/src/main/java/de/varoplugin/cfw/version/ServerSoftware.java @@ -30,7 +30,7 @@ public enum ServerSoftware { MAGMA_1_18("Magma 1.18.2", SpigotVersionAdapter::new, "org.magmafoundation.magma.helpers.EnumJ17Helper", "Magma"), - MAGMA_1_12("Magma", SpigotVersionAdapter::new, "org.magmafoundation.magma.Magma", "Magma"), + MAGMA_1_12("Magma", versionSupplier -> new MagmaOneTwelveVersionAdapter(), "org.magmafoundation.magma.Magma", "Magma"), CRUCIBLE("Crucible", versionSupplier -> new CrucibleVersionAdapter(), "io.github.crucible.CrucibleCommand", "Crucible"), URANIUM("Uranium", null, null, "Uranium"), THERMOS("Thermos", null, "thermos.Thermos", "Thermos"),