Utils/BukkitUtils/src/main/java/eu/mikroskeem/utils/bukkit/ServerUtils.java

99 lines
4.1 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 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")
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 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 "";
}
}
}