From 9f8c6edabe971304027f7fd2b84984fc69dd033b Mon Sep 17 00:00:00 2001 From: Fionera Date: Tue, 8 Sep 2020 20:40:43 +0200 Subject: [PATCH] Add Java 14 support by replacing the final field access --- pom.xml | 6 ++-- .../tamablefoxes/versions/FieldHelper.java | 34 +++++++++++++++++++ .../version_1_14_R1/NMSInterface_1_14_R1.java | 16 ++------- .../version_1_15_R1/NMSInterface_1_15_R1.java | 17 ++-------- .../version_1_16_R1/NMSInterface_1_16_R1.java | 19 ++--------- .../version_1_16_R2/NMSInterface_1_16_R2.java | 19 ++--------- 6 files changed, 47 insertions(+), 64 deletions(-) create mode 100644 src/main/java/net/seanomik/tamablefoxes/versions/FieldHelper.java diff --git a/pom.xml b/pom.xml index 61d07ac..4ae37a0 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ Tamablefoxes - 1.8 + 1.14 UTF-8 @@ -24,8 +24,8 @@ maven-compiler-plugin 3.7.0 - ${java.version} - ${java.version} + 9 + 9 diff --git a/src/main/java/net/seanomik/tamablefoxes/versions/FieldHelper.java b/src/main/java/net/seanomik/tamablefoxes/versions/FieldHelper.java new file mode 100644 index 0000000..5f907cc --- /dev/null +++ b/src/main/java/net/seanomik/tamablefoxes/versions/FieldHelper.java @@ -0,0 +1,34 @@ +package net.seanomik.tamablefoxes.versions; + +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +public final class FieldHelper { + + private static final VarHandle MODIFIERS; + + static { + try { + MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(Field.class, MethodHandles.lookup()); + MODIFIERS = lookup.findVarHandle(Field.class, "modifiers", int.class); + } catch (IllegalAccessException | NoSuchFieldException ex) { + throw new RuntimeException(ex); + } + } + + public static void makeNonFinal(Field field) { + int mods = field.getModifiers(); + if (Modifier.isFinal(mods)) { + MODIFIERS.set(field, mods & ~Modifier.FINAL); + } + } + + public static void setField(Field field, Object obj, Object value) throws IllegalAccessException { + makeNonFinal(field); + field.setAccessible(true); + field.set(obj, value); + field.setAccessible(false); + } +} \ No newline at end of file diff --git a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_14_R1/NMSInterface_1_14_R1.java b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_14_R1/NMSInterface_1_14_R1.java index b9f5ca8..9282305 100644 --- a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_14_R1/NMSInterface_1_14_R1.java +++ b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_14_R1/NMSInterface_1_14_R1.java @@ -4,6 +4,7 @@ import net.minecraft.server.v1_14_R1.EntityFox; import net.minecraft.server.v1_14_R1.EntityTypes; import net.seanomik.tamablefoxes.Utils; import net.seanomik.tamablefoxes.io.LanguageConfig; +import net.seanomik.tamablefoxes.versions.FieldHelper; import net.seanomik.tamablefoxes.versions.NMSInterface; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -19,20 +20,7 @@ public class NMSInterface_1_14_R1 implements NMSInterface { public void registerCustomFoxEntity() { try { // Replace the fox entity Field field = EntityTypes.FOX.getClass().getDeclaredField("aZ"); - field.setAccessible(true); - - // If the field is final, then make it non final - if ((field.getModifiers() & Modifier.FINAL) == Modifier.FINAL) { - Field fieldMutable = field.getClass().getDeclaredField("modifiers"); - fieldMutable.setAccessible(true); - fieldMutable.set(field, fieldMutable.getInt(field) & ~Modifier.FINAL); - fieldMutable.setAccessible(false); - } - - field.set(EntityTypes.FOX, (EntityTypes.b) (type, world) -> new EntityTamableFox(type, world)); - - field.setAccessible(false); - + FieldHelper.setField(field, EntityTypes.FOX, (EntityTypes.b) EntityTamableFox::new); Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.GREEN + LanguageConfig.getSuccessReplaced()); } catch (Exception e) { Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace()); diff --git a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_15_R1/NMSInterface_1_15_R1.java b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_15_R1/NMSInterface_1_15_R1.java index e700421..fe0d2ca 100644 --- a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_15_R1/NMSInterface_1_15_R1.java +++ b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_15_R1/NMSInterface_1_15_R1.java @@ -2,9 +2,9 @@ package net.seanomik.tamablefoxes.versions.version_1_15_R1; import net.minecraft.server.v1_15_R1.EntityFox; import net.minecraft.server.v1_15_R1.EntityTypes; -import net.seanomik.tamablefoxes.TamableFoxes; import net.seanomik.tamablefoxes.Utils; import net.seanomik.tamablefoxes.io.LanguageConfig; +import net.seanomik.tamablefoxes.versions.FieldHelper; import net.seanomik.tamablefoxes.versions.NMSInterface; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -20,20 +20,7 @@ public class NMSInterface_1_15_R1 implements NMSInterface { public void registerCustomFoxEntity() { try { // Replace the fox entity Field field = EntityTypes.FOX.getClass().getDeclaredField("ba"); - field.setAccessible(true); - - // If the field is final, then make it non final - if ((field.getModifiers() & Modifier.FINAL) == Modifier.FINAL) { - Field fieldMutable = field.getClass().getDeclaredField("modifiers"); - fieldMutable.setAccessible(true); - fieldMutable.set(field, fieldMutable.getInt(field) & ~Modifier.FINAL); - fieldMutable.setAccessible(false); - } - - field.set(EntityTypes.FOX, (EntityTypes.b) (type, world) -> new EntityTamableFox(type, world)); - - field.setAccessible(false); - + FieldHelper.setField(field, EntityTypes.FOX, (EntityTypes.b) EntityTamableFox::new); Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.GREEN + LanguageConfig.getSuccessReplaced()); } catch (Exception e) { Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace()); diff --git a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R1/NMSInterface_1_16_R1.java b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R1/NMSInterface_1_16_R1.java index f085eb2..320b210 100644 --- a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R1/NMSInterface_1_16_R1.java +++ b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R1/NMSInterface_1_16_R1.java @@ -2,9 +2,9 @@ package net.seanomik.tamablefoxes.versions.version_1_16_R1; import net.minecraft.server.v1_16_R1.EntityTypes; import net.minecraft.server.v1_16_R1.EntityFox; -import net.seanomik.tamablefoxes.TamableFoxes; import net.seanomik.tamablefoxes.Utils; import net.seanomik.tamablefoxes.io.LanguageConfig; +import net.seanomik.tamablefoxes.versions.FieldHelper; import net.seanomik.tamablefoxes.versions.NMSInterface; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -21,20 +21,7 @@ public class NMSInterface_1_16_R1 implements NMSInterface { public void registerCustomFoxEntity() { try { // Replace the fox entity Field field = EntityTypes.FOX.getClass().getDeclaredField("be"); - field.setAccessible(true); - - // If the field is final, then make it non final - if ((field.getModifiers() & Modifier.FINAL) == Modifier.FINAL) { - Field fieldMutable = field.getClass().getDeclaredField("modifiers"); - fieldMutable.setAccessible(true); - fieldMutable.set(field, fieldMutable.getInt(field) & ~Modifier.FINAL); - fieldMutable.setAccessible(false); - } - - field.set(EntityTypes.FOX, (EntityTypes.b) (type, world) -> new EntityTamableFox(type, world)); - - field.setAccessible(false); - + FieldHelper.setField(field, EntityTypes.FOX, (EntityTypes.b) EntityTamableFox::new); Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.GREEN + LanguageConfig.getSuccessReplaced()); } catch (Exception e) { Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace()); @@ -44,6 +31,6 @@ public class NMSInterface_1_16_R1 implements NMSInterface { @Override public void spawnTamableFox(Location loc, FoxType type) { EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) loc.getWorld().spawnEntity(loc, EntityType.FOX)).getHandle(); - tamableFox.setFoxType( (type == FoxType.RED) ? EntityFox.Type.RED : EntityFox.Type.SNOW ); + tamableFox.setFoxType((type == FoxType.RED) ? EntityFox.Type.RED : EntityFox.Type.SNOW); } } diff --git a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R2/NMSInterface_1_16_R2.java b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R2/NMSInterface_1_16_R2.java index f8962f3..ed6a178 100644 --- a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R2/NMSInterface_1_16_R2.java +++ b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R2/NMSInterface_1_16_R2.java @@ -4,6 +4,7 @@ import net.minecraft.server.v1_16_R2.EntityFox; import net.minecraft.server.v1_16_R2.EntityTypes; import net.seanomik.tamablefoxes.Utils; import net.seanomik.tamablefoxes.io.LanguageConfig; +import net.seanomik.tamablefoxes.versions.FieldHelper; import net.seanomik.tamablefoxes.versions.NMSInterface; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -12,7 +13,6 @@ import org.bukkit.craftbukkit.v1_16_R2.entity.CraftEntity; import org.bukkit.entity.EntityType; import java.lang.reflect.Field; -import java.lang.reflect.Modifier; public class NMSInterface_1_16_R2 implements NMSInterface { @@ -20,20 +20,7 @@ public class NMSInterface_1_16_R2 implements NMSInterface { public void registerCustomFoxEntity() { try { // Replace the fox entity Field field = EntityTypes.FOX.getClass().getDeclaredField("bf"); - field.setAccessible(true); - - // If the field is final, then make it non final - if ((field.getModifiers() & Modifier.FINAL) == Modifier.FINAL) { - Field fieldMutable = field.getClass().getDeclaredField("modifiers"); - fieldMutable.setAccessible(true); - fieldMutable.set(field, fieldMutable.getInt(field) & ~Modifier.FINAL); - fieldMutable.setAccessible(false); - } - - field.set(EntityTypes.FOX, (EntityTypes.b) (type, world) -> new EntityTamableFox(type, world)); - - field.setAccessible(false); - + FieldHelper.setField(field, EntityTypes.FOX, (EntityTypes.b) EntityTamableFox::new); Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.GREEN + LanguageConfig.getSuccessReplaced()); } catch (Exception e) { Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace()); @@ -43,6 +30,6 @@ public class NMSInterface_1_16_R2 implements NMSInterface { @Override public void spawnTamableFox(Location loc, FoxType type) { EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) loc.getWorld().spawnEntity(loc, EntityType.FOX)).getHandle(); - tamableFox.setFoxType( (type == FoxType.RED) ? EntityFox.Type.RED : EntityFox.Type.SNOW ); + tamableFox.setFoxType((type == FoxType.RED) ? EntityFox.Type.RED : EntityFox.Type.SNOW); } }