Utils/BukkitUtils/src/main/java/eu/mikroskeem/utils/bukkit/fakeplugin/FakePluginFactory.java

80 lines
3.2 KiB
Java

package eu.mikroskeem.utils.bukkit.fakeplugin;
import eu.mikroskeem.utils.reflect.Reflect;
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;
import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
public class FakePluginFactory {
private final List<AbstractFakePlugin> fakePlugins = new ArrayList<>();
private final Plugin plugin;
private final List<Plugin> plugins;
@Getter private final Map<String, Plugin> lookupNames;
private final boolean isPaper;
@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;
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){
throw new RuntimeException("Failed to get 'plugins' and 'lookupNames' field!");
}
}
@SuppressWarnings("unchecked")
public synchronized <T extends AbstractFakePlugin> T newPlugin(String name, String version, String mainClass){
T fakePlugin = (T) new AbstractFakePlugin(plugin, name, version, mainClass, null, null){};
fakePlugins.add(fakePlugin);
return fakePlugin;
}
public synchronized <T extends AbstractFakePlugin> void addPlugin(T plugin){
/* Note: took me 5 hours to realize lookupNames map keys are lower case (on PaperSpigot)
* Note 2: Took me another 5 hours to realize lower case lookupNames keys are *only* on PaperSpigot
*/
String lookupName = isPaper?plugin.getName().toLowerCase(Locale.ENGLISH):plugin.getName();
lookupNames.put(lookupName, plugin);
plugins.add(plugin);
fakePlugins.add(plugin);
}
public synchronized <T extends AbstractFakePlugin> void removePlugin(T plugin){
if (plugins.contains(plugin)) plugins.remove(plugin);
if (lookupNames.containsKey(plugin.getName())) {
String lookupName = isPaper?plugin.getName().toLowerCase(Locale.ENGLISH):plugin.getName();
lookupNames.remove(lookupName);
}
if (fakePlugins.contains(plugin)) fakePlugins.remove(plugin);
}
/* Note: Not needed, SimplePluginManager handles plugin removal already
synchronized void removeAllPlugins() {
fakePlugins.forEach(this::removePlugin);
}
*/
}