Rewrite to use Shuriken libraries
This commit is contained in:
parent
a5131f534b
commit
230e0ffda7
@ -10,24 +10,25 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>bukkitutils</artifactId>
|
||||
<version>1.7-SNAPSHOT</version>
|
||||
<version>1.8-SNAPSHOT</version>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>destroystokyo-repo</id>
|
||||
<url>https://repo.destroystokyo.com/repository/maven-public//</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>eu.mikroskeem</groupId>
|
||||
<artifactId>reflect</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<artifactId>shuriken.reflect</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>eu.mikroskeem</groupId>
|
||||
<artifactId>shuriken.instrumentation</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.destroystokyo.paper</groupId>
|
||||
@ -35,22 +36,11 @@
|
||||
<version>1.11.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>1.11.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.16.10</version>
|
||||
<version>1.16.12</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations-java5</artifactId>
|
||||
<version>RELEASE</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@ -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 <CraftPlayer, NMSPlayer> 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));
|
||||
ClassWrapper<CraftPlayer> craftPlayerClass = (ClassWrapper<CraftPlayer>) checkNotNull(Reflect.getClass(
|
||||
String.format("org.bukkit.craftbukkit.%s.entity.CraftPlayer", nmsVer)).orElse(null))
|
||||
.setClassInstance(player);
|
||||
ClassWrapper<NMSPlayer> nmsEntityPlayerClass = (ClassWrapper<NMSPlayer>) 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 ignored){
|
||||
catch (NullPointerException|NoSuchFieldException|NoSuchMethodException|
|
||||
IllegalAccessException|InvocationTargetException ignored){}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 <C> double[] getTPS(){
|
||||
Class<C> _t = (Class<C>)double[].class;
|
||||
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){}
|
||||
return Reflect.wrapClass(Bukkit.class).invokeMethod("getTPS", double[].class);
|
||||
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
|
||||
try {
|
||||
Optional<ClassWrapper<?>> minecraftServerClassOpt = Reflect.getClass(String.format(
|
||||
"net.minecraft.server.%s.MinecraftServer", getNmsVersion()
|
||||
));
|
||||
if (minecraftServerClassOpt.isPresent()) {
|
||||
ClassWrapper<?> minecraftServerClass = minecraftServerClassOpt.get();
|
||||
minecraftServerClass.invokeMethod("getServer", minecraftServerClass.getWrappedClass());
|
||||
Optional<FieldWrapper<C>> 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()){
|
||||
Optional<FieldWrapper<Object>> loadersFieldOpt = Reflect
|
||||
.wrapClass(pl.getClass())
|
||||
.setClassInstance(pl)
|
||||
.getField("loaders", Object.class);
|
||||
if(loadersFieldOpt.isPresent()) {
|
||||
FieldWrapper<Object> loadersField = loadersFieldOpt.get();
|
||||
switch (ServerUtils.getNmsVersion()){
|
||||
case "v1_8_R3":
|
||||
case "v1_9_R1":
|
||||
case "v1_9_R2":
|
||||
try {
|
||||
Map<String, ClassLoader> loaderMap = (Map<String, ClassLoader>)
|
||||
checkNotNull(Reflect.readField(loadersField, pl));
|
||||
Map<String, ClassLoader> loaderMap = (Map<String, ClassLoader>) 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<ClassLoader> loaders = (List<ClassLoader>)
|
||||
checkNotNull(Reflect.readField(loadersField, pl));
|
||||
Optional<ClassLoader> 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;
|
||||
Optional<ClassWrapper<?>> pluginClassLoaderOpt = Reflect
|
||||
.getClass("org.bukkit.plugin.java.PluginClassLoader");
|
||||
if(pluginClassLoaderOpt.isPresent()){
|
||||
List<ClassLoader> loaders = (List<ClassLoader>) 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<String, Class<?>> 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<String, Class<?>>) 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<String, Class<?>>) checkNotNull(pluginClassLoader.getField("classes", Map.class)
|
||||
.orElse(null),
|
||||
"Failed to get classes field").read();
|
||||
} catch(NoSuchFieldException|IllegalAccessException|NullPointerException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
|
@ -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<Plugin>) checkNotNull(Reflect.readField(pluginsField,
|
||||
plugin.getServer().getPluginManager()));
|
||||
lookupNames = (Map<String, Plugin>) checkNotNull(Reflect.readField(lookupNamesField,
|
||||
plugin.getServer().getPluginManager()));
|
||||
} catch (NullPointerException e){
|
||||
ClassWrapper<SimplePluginManager> spm = Reflect.wrapClass(SimplePluginManager.class)
|
||||
.setClassInstance(plugin.getServer().getPluginManager());
|
||||
plugins = (List<Plugin>) checkNotNull(spm.getField("plugins", List.class).orElse(null)).read();
|
||||
lookupNames = (Map<String, Plugin>) checkNotNull(spm.getField("lookupNames", Map.class).orElse(null)).read();
|
||||
} catch (Exception e){
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Failed to get 'plugins' and 'lookupNames' field!");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user