129 lines
5.2 KiB
Java
129 lines
5.2 KiB
Java
package eu.mikroskeem.utils.bukkit;
|
|
|
|
import eu.mikroskeem.utils.reflect.Reflect;
|
|
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.util.List;
|
|
import java.util.Map;
|
|
import java.util.Optional;
|
|
|
|
import static com.google.common.base.Preconditions.checkNotNull;
|
|
|
|
public class ServerUtils {
|
|
/**
|
|
* Get server's TPS
|
|
*
|
|
* 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 {
|
|
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 new double[]{-1, -1, -1};
|
|
}
|
|
|
|
/**
|
|
* Get plugin class loader. Useful when you want to add new classes on runtime
|
|
*
|
|
* @param plugin Plugin which will be used to get plugin ClassLoader
|
|
* @return Plugin ClassLoader
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
@Nullable
|
|
public static ClassLoader getPluginClassLoader(JavaPlugin plugin){
|
|
/*
|
|
* Note: CB/Spigot has PluginClassLoader package-private, PaperSpigot has public
|
|
* So *DO NOT* try to cast this ClassLoader to PluginClassLoader, if you aim to be
|
|
* compatible with other Bukkit-based servers
|
|
* I repeat, *DO NOT USE* PluginClassLoader!
|
|
*/
|
|
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<String, ClassLoader> loaderMap = (Map<String, ClassLoader>)
|
|
checkNotNull(Reflect.readField(loadersField, pl));
|
|
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;
|
|
}
|
|
}
|
|
catch (NullPointerException ignored){}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* 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"));
|
|
if(pluginClassLoader.isAssignableFrom(clClass)){
|
|
Field classesField = checkNotNull(Reflect.getField(clClass, "classes"));
|
|
return (Map<String, Class<?>>) checkNotNull(Reflect.readField(classesField, classLoader));
|
|
} else {
|
|
throw new RuntimeException(
|
|
clClass.getName()
|
|
+ " does not extend "
|
|
+ pluginClassLoader.getName());
|
|
}
|
|
} catch(NullPointerException e){
|
|
e.printStackTrace();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Get NMS version of current running server
|
|
* @return NMS version or 0 length string
|
|
*/
|
|
public static String getNmsVersion(){
|
|
try {
|
|
String bukkitPackageName = Bukkit.getServer().getClass().getPackage().getName();
|
|
return bukkitPackageName.substring(bukkitPackageName.lastIndexOf(".") + 1);
|
|
} catch (NullPointerException e){
|
|
return "";
|
|
}
|
|
}
|
|
}
|