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.Bukkit;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPluginLoader; import org.bukkit.plugin.java.JavaPluginLoader;
import org.bukkit.plugin.java.PluginClassLoader;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@ -45,31 +44,42 @@ public class ServerUtils {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static ClassLoader getPluginClassLoader(JavaPlugin plugin){ public static ClassLoader getPluginClassLoader(JavaPlugin plugin){
JavaPluginLoader pl = (JavaPluginLoader)plugin.getPluginLoader(); /*
Field loadersField = Reflect.getField(pl.getClass(), "loaders"); * Note: CB/Spigot has PluginClassLoader package-private, PaperSpigot has public
if(loadersField != null) { * So *DO NOT* try to cast this ClassLoader to PluginClassLoader, if you aim to be
List<PluginClassLoader> loaders = null; * 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()){ switch (getNmsVersion()){
case "v1_8_R3": case "v1_8_R3":
case "v1_9_R1": // TODO: Check? case "v1_9_R1":
case "v1_9_R2": case "v1_9_R2":
loaders = new ArrayList<>(((Map<String, PluginClassLoader>) try {
Reflect.readField(loadersField, pl)).values()); Map<String, ClassLoader> loaderMap = (Map<String, ClassLoader>)
checkNotNull(Reflect.readField(loadersField, pl));
return loaderMap.get(plugin.getName());
}
catch (NullPointerException ignored){}
break; break;
case "v1_10_R1": case "v1_10_R1":
case "v1_11_R1": case "v1_11_R1":
loaders = (List<PluginClassLoader>) Reflect.readField(loadersField, pl); Class<?> pluginClassLoader = checkNotNull(Reflect.getClass(
break; "org.bukkit.plugin.java.PluginClassLoader"));
} List<ClassLoader> loaders = (List<ClassLoader>)
checkNotNull(Reflect.readField(loadersField, pl));
if(loaders != null) { Optional<ClassLoader> loader = loaders.stream()
for(PluginClassLoader loader : loaders) { .filter(l->{
if(loader.getPlugin().getName().equals(plugin.getName())){ Field f = checkNotNull(Reflect.getField(pluginClassLoader, "plugin"));
return loader; return checkNotNull(((JavaPlugin)Reflect.readField(f, l)))
} .getName().equals(plugin.getName());
} }).findFirst();
return loader.isPresent()?loader.get():null;
} }
} }
catch (NullPointerException ignored){}
return null; return null;
} }