From 230e0ffda71ef25d36352fe1e729cd7d110e0915 Mon Sep 17 00:00:00 2001 From: Mark Vainomaa Date: Wed, 22 Mar 2017 01:09:03 +0200 Subject: [PATCH] Rewrite to use Shuriken libraries --- BukkitUtils/pom.xml | 28 ++-- .../mikroskeem/utils/bukkit/PlayerUtils.java | 32 ++--- .../mikroskeem/utils/bukkit/ServerUtils.java | 122 ++++++++++-------- .../bukkit/fakeplugin/FakePluginFactory.java | 25 ++-- 4 files changed, 104 insertions(+), 103 deletions(-) diff --git a/BukkitUtils/pom.xml b/BukkitUtils/pom.xml index 5153018..e93947d 100644 --- a/BukkitUtils/pom.xml +++ b/BukkitUtils/pom.xml @@ -10,24 +10,25 @@ 4.0.0 bukkitutils - 1.7-SNAPSHOT + 1.8-SNAPSHOT destroystokyo-repo https://repo.destroystokyo.com/repository/maven-public// - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - eu.mikroskeem - reflect - 1.1-SNAPSHOT + shuriken.reflect + 0.0.1-SNAPSHOT + + + eu.mikroskeem + shuriken.instrumentation + 0.0.1-SNAPSHOT com.destroystokyo.paper @@ -35,22 +36,11 @@ 1.11.2-R0.1-SNAPSHOT provided - - org.bukkit - bukkit - 1.11.2-R0.1-SNAPSHOT - provided - org.projectlombok lombok - 1.16.10 + 1.16.12 provided - - org.jetbrains - annotations-java5 - RELEASE - diff --git a/BukkitUtils/src/main/java/eu/mikroskeem/utils/bukkit/PlayerUtils.java b/BukkitUtils/src/main/java/eu/mikroskeem/utils/bukkit/PlayerUtils.java index 950a666..adb16aa 100644 --- a/BukkitUtils/src/main/java/eu/mikroskeem/utils/bukkit/PlayerUtils.java +++ b/BukkitUtils/src/main/java/eu/mikroskeem/utils/bukkit/PlayerUtils.java @@ -1,11 +1,11 @@ package eu.mikroskeem.utils.bukkit; -import eu.mikroskeem.utils.reflect.Reflect; +import eu.mikroskeem.shuriken.reflect.Reflect; +import eu.mikroskeem.shuriken.reflect.wrappers.ClassWrapper; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; -import java.lang.reflect.Field; -import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; import static com.google.common.base.Preconditions.checkNotNull; import static eu.mikroskeem.utils.bukkit.ServerUtils.getNmsVersion; @@ -19,20 +19,22 @@ public class PlayerUtils { * @param player Player who ping to query * @return Player's ping (-1 if reflection failed) */ - public static int getNMSPing(@NotNull Player player){ + @SuppressWarnings("unchecked") + public static int getNMSPing(@NotNull Player player){ try { String nmsVer = getNmsVersion(); - Class craftPlayerClass = checkNotNull(Reflect.getClass( - String.format("org.bukkit.craftbukkit.%s.entity.CraftPlayer", nmsVer))); - Class craftEntityPlayerClass = checkNotNull(Reflect.getClass( - String.format("net.minecraft.server.%s.EntityPlayer", nmsVer))); - Method getHandle = checkNotNull(Reflect.getMethod(craftPlayerClass, "getHandle")); - Object handle = checkNotNull(Reflect.invokeMethod(getHandle, player)); - Field pingField = checkNotNull(Reflect.getField(craftEntityPlayerClass, "ping")); - return (Integer) checkNotNull(Reflect.readField(pingField, handle)); - } - catch (NullPointerException ignored){ - return -1; + ClassWrapper craftPlayerClass = (ClassWrapper) checkNotNull(Reflect.getClass( + String.format("org.bukkit.craftbukkit.%s.entity.CraftPlayer", nmsVer)).orElse(null)) + .setClassInstance(player); + ClassWrapper nmsEntityPlayerClass = (ClassWrapper) checkNotNull(Reflect.getClass( + String.format("net.minecraft.server.%s.EntityPlayer", nmsVer)).orElse(null)); + NMSPlayer nmsPlayer = craftPlayerClass + .invokeMethod("getHandle", nmsEntityPlayerClass.getWrappedClass()); + nmsEntityPlayerClass.setClassInstance(nmsPlayer); + return checkNotNull(nmsEntityPlayerClass.getField("ping", int.class).orElse(null)).read(); } + catch (NullPointerException|NoSuchFieldException|NoSuchMethodException| + IllegalAccessException|InvocationTargetException ignored){} + return -1; } } diff --git a/BukkitUtils/src/main/java/eu/mikroskeem/utils/bukkit/ServerUtils.java b/BukkitUtils/src/main/java/eu/mikroskeem/utils/bukkit/ServerUtils.java index 83de0d6..1b81884 100644 --- a/BukkitUtils/src/main/java/eu/mikroskeem/utils/bukkit/ServerUtils.java +++ b/BukkitUtils/src/main/java/eu/mikroskeem/utils/bukkit/ServerUtils.java @@ -1,13 +1,17 @@ package eu.mikroskeem.utils.bukkit; -import eu.mikroskeem.utils.reflect.Reflect; +import eu.mikroskeem.shuriken.instrumentation.validate.ClassDescriptor; +import eu.mikroskeem.shuriken.instrumentation.validate.FieldDescriptor; +import eu.mikroskeem.shuriken.instrumentation.validate.Validate; +import eu.mikroskeem.shuriken.reflect.Reflect; +import eu.mikroskeem.shuriken.reflect.wrappers.ClassWrapper; +import eu.mikroskeem.shuriken.reflect.wrappers.FieldWrapper; import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPluginLoader; import org.jetbrains.annotations.Nullable; -import java.lang.reflect.Field; -import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.Map; import java.util.Optional; @@ -21,18 +25,25 @@ public class ServerUtils { * Will use PaperSpigot's API if available, reflection otherwise * @return double array of TPS (not rounded!), values are -1 if reflection failed */ - public static double[] getTPS(){ - if(Reflect.getMethod(Bukkit.class, "getTps") != null) { - return Bukkit.getTPS(); - } else { + @SuppressWarnings("unchecked") + public static double[] getTPS(){ + Class _t = (Class)double[].class; + try { + return Reflect.wrapClass(Bukkit.class).invokeMethod("getTPS", double[].class); + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { try { - Class MinecraftServerClass = checkNotNull(Reflect.getClass( - String.format("net.minecraft.server.%s.MinecraftServer", getNmsVersion()))); - Method getServer = checkNotNull(Reflect.getMethod(MinecraftServerClass, "getServer")); - Field recentTPS = checkNotNull(Reflect.getField(MinecraftServerClass, "recentTps")); - Object server = checkNotNull(Reflect.invokeMethod(getServer, null)); - return (double[]) checkNotNull(Reflect.readField(recentTPS, server)); - } catch (NullPointerException ignored){} + Optional> minecraftServerClassOpt = Reflect.getClass(String.format( + "net.minecraft.server.%s.MinecraftServer", getNmsVersion() + )); + if (minecraftServerClassOpt.isPresent()) { + ClassWrapper minecraftServerClass = minecraftServerClassOpt.get(); + minecraftServerClass.invokeMethod("getServer", minecraftServerClass.getWrappedClass()); + Optional> recentTpsOpt = minecraftServerClass.getField("recentTps", _t); + if(recentTpsOpt.isPresent()) + return (double[]) recentTpsOpt.get().read(); + } + } + catch (NoSuchMethodException|NoSuchFieldException|InvocationTargetException|IllegalAccessException ignored){} } return new double[]{-1, -1, -1}; } @@ -54,34 +65,42 @@ public class ServerUtils { */ JavaPluginLoader pl = (JavaPluginLoader) plugin.getPluginLoader(); try { - Field loadersField = checkNotNull(Reflect.getField(pl.getClass(), "loaders")); - switch (getNmsVersion()){ - case "v1_8_R3": - case "v1_9_R1": - case "v1_9_R2": - try { - Map loaderMap = (Map) - checkNotNull(Reflect.readField(loadersField, pl)); + Optional> loadersFieldOpt = Reflect + .wrapClass(pl.getClass()) + .setClassInstance(pl) + .getField("loaders", Object.class); + if(loadersFieldOpt.isPresent()) { + FieldWrapper loadersField = loadersFieldOpt.get(); + switch (ServerUtils.getNmsVersion()){ + case "v1_8_R3": + case "v1_9_R1": + case "v1_9_R2": + Map loaderMap = (Map) loadersField.read(); return loaderMap.get(plugin.getName()); - } - catch (NullPointerException ignored){} - break; - case "v1_10_R1": - case "v1_11_R1": - Class pluginClassLoader = checkNotNull(Reflect.getClass( - "org.bukkit.plugin.java.PluginClassLoader")); - List loaders = (List) - checkNotNull(Reflect.readField(loadersField, pl)); - Optional loader = loaders.stream() - .filter(l->{ - Field f = checkNotNull(Reflect.getField(pluginClassLoader, "plugin")); - return checkNotNull(((JavaPlugin)Reflect.readField(f, l))) - .getName().equals(plugin.getName()); - }).findFirst(); - return loader.isPresent()?loader.get():null; + case "v1_10_R1": + case "v1_11_R1": + Optional> pluginClassLoaderOpt = Reflect + .getClass("org.bukkit.plugin.java.PluginClassLoader"); + if(pluginClassLoaderOpt.isPresent()){ + List loaders = (List) loadersField.read(); + return loaders.stream().filter(loader -> { + try { + String pluginName = Reflect.wrapInstance(loader) + .getField("plugin", JavaPlugin.class) + .get() + .read() + .getName(); + return pluginName.equals(plugin.getName()); + } + catch (NoSuchFieldException|IllegalAccessException|NullPointerException ignored){} + return false; + }).findFirst().orElse(null); + } + break; + } } } - catch (NullPointerException ignored){} + catch (NoSuchFieldException|IllegalAccessException ignored){} return null; } @@ -89,27 +108,22 @@ public class ServerUtils { * Get PluginClassLoader classes map * @param classLoader PluginClassLoader instance * @return Classes map - * @throws RuntimeException if ClassLoader doesn't extend PluginClassLoader */ @SuppressWarnings("unchecked") @Nullable public static Map> getClassesMap(ClassLoader classLoader){ Class clClass = classLoader.getClass(); try { - Class pluginClassLoader = checkNotNull(Reflect.getClass( - "org.bukkit.plugin.java.PluginClassLoader"), - "Couldn't find org.bukkit.plugin.java.PluginClassLoader class"); - if(pluginClassLoader.isAssignableFrom(clClass)){ - Field classesField = checkNotNull(Reflect.getField(clClass, "classes"), - "Failed to get classes field"); - return (Map>) checkNotNull(Reflect.readField(classesField, classLoader)); - } else { - throw new RuntimeException( - clClass.getName() - + " does not extend " - + pluginClassLoader.getName()); - } - } catch(NullPointerException e){ + ClassWrapper pluginClassLoader = checkNotNull(Reflect + .getClass("org.bukkit.plugin.java.PluginClassLoader").orElse(null), + "Couldn't find org.bukkit.plugin.java.PluginClassLoader class") + .setClassInstance(classLoader); + Validate.checkFields(pluginClassLoader, FieldDescriptor.of("classes", Map.class)); + Validate.checkClass(ClassDescriptor.ofWrapped(clClass, pluginClassLoader)); + return (Map>) checkNotNull(pluginClassLoader.getField("classes", Map.class) + .orElse(null), + "Failed to get classes field").read(); + } catch(NoSuchFieldException|IllegalAccessException|NullPointerException e){ e.printStackTrace(); } return null; diff --git a/BukkitUtils/src/main/java/eu/mikroskeem/utils/bukkit/fakeplugin/FakePluginFactory.java b/BukkitUtils/src/main/java/eu/mikroskeem/utils/bukkit/fakeplugin/FakePluginFactory.java index d8e0515..272662f 100644 --- a/BukkitUtils/src/main/java/eu/mikroskeem/utils/bukkit/fakeplugin/FakePluginFactory.java +++ b/BukkitUtils/src/main/java/eu/mikroskeem/utils/bukkit/fakeplugin/FakePluginFactory.java @@ -1,12 +1,13 @@ package eu.mikroskeem.utils.bukkit.fakeplugin; -import eu.mikroskeem.utils.reflect.Reflect; +import eu.mikroskeem.shuriken.reflect.Reflect; +import eu.mikroskeem.shuriken.reflect.simple.SimpleReflect; +import eu.mikroskeem.shuriken.reflect.wrappers.ClassWrapper; import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.SimplePluginManager; -import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -25,23 +26,17 @@ public class FakePluginFactory { @SuppressWarnings("unchecked") public FakePluginFactory(Plugin parentPlugin){ this.plugin = parentPlugin; - Field lookupNamesField, pluginsField; if(plugin.getServer().getPluginManager().getClass() != SimplePluginManager.class){ throw new RuntimeException("Server PluginManager is not SimplePluginManager"); } - isPaper = Reflect.getMethod(Bukkit.class, "getTPS") != null; + isPaper = SimpleReflect.getMethod(Bukkit.class, "getTPS", double[].class) != null; try { - pluginsField = checkNotNull(Reflect.getField( - SimplePluginManager.class, - "plugins")); - lookupNamesField = checkNotNull(Reflect.getField( - SimplePluginManager.class, - "lookupNames")); - plugins = (List) checkNotNull(Reflect.readField(pluginsField, - plugin.getServer().getPluginManager())); - lookupNames = (Map) checkNotNull(Reflect.readField(lookupNamesField, - plugin.getServer().getPluginManager())); - } catch (NullPointerException e){ + ClassWrapper spm = Reflect.wrapClass(SimplePluginManager.class) + .setClassInstance(plugin.getServer().getPluginManager()); + plugins = (List) checkNotNull(spm.getField("plugins", List.class).orElse(null)).read(); + lookupNames = (Map) checkNotNull(spm.getField("lookupNames", Map.class).orElse(null)).read(); + } catch (Exception e){ + e.printStackTrace(); throw new RuntimeException("Failed to get 'plugins' and 'lookupNames' field!"); } }