Fix and improve PluginClassLoader getter

This commit is contained in:
Mark Vainomaa 2016-12-22 16:17:16 +02:00
parent 5e988df250
commit 0cd587cbff

View File

@ -4,13 +4,12 @@ import eu.mikroskeem.utils.reflect.Reflect;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPluginLoader;
import org.bukkit.plugin.java.PluginClassLoader;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkNotNull;
@ -45,31 +44,42 @@ public class ServerUtils {
*/
@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();
Field loadersField = Reflect.getField(pl.getClass(), "loaders");
if(loadersField != null) {
List<PluginClassLoader> loaders = null;
try {
Field loadersField = checkNotNull(Reflect.getField(pl.getClass(), "loaders"));
switch (getNmsVersion()){
case "v1_8_R3":
case "v1_9_R1": // TODO: Check?
case "v1_9_R1":
case "v1_9_R2":
loaders = new ArrayList<>(((Map<String, PluginClassLoader>)
Reflect.readField(loadersField, pl)).values());
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":
loaders = (List<PluginClassLoader>) Reflect.readField(loadersField, pl);
break;
}
if(loaders != null) {
for(PluginClassLoader loader : loaders) {
if(loader.getPlugin().getName().equals(plugin.getName())){
return loader;
}
}
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;
}