/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package gcb.plugin;
import gcb.GCBConfig;
import gcb.GarenaInterface;
import gcb.Main;
import gcb.MemberInfo;
import gcb.WC3Interface;
import gcb.bot.ChatThread;
import gcb.bot.SQLThread;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.ConversionException;
import org.apache.commons.configuration.PropertiesConfiguration;
/**
*
* @author wizardus
*/
public class PluginManager {
String pluginPath;
ArrayList<Plugin> pluginList;
Hashtable<String, ArrayList<Plugin>> register; //function to plugin list
Hashtable<String, Plugin> plugins; //class name to plugin
Map<Integer, GarenaInterface> garenaConnections;
WC3Interface wc3i;
SQLThread sqlthread;
ChatThread chatthread;
public PluginManager() {
pluginList = new ArrayList<Plugin>();
register = new Hashtable<String, ArrayList<Plugin>>();
plugins = new Hashtable<String, Plugin>();
pluginPath = GCBConfig.configuration.getString("gcb_plugin_path", "plugin/");
}
public void setGarena(Map<Integer, GarenaInterface> garenaConnections, WC3Interface wc3i, SQLThread sqlthread, ChatThread chatthread) {
this.garenaConnections = garenaConnections;
this.wc3i = wc3i;
this.sqlthread = sqlthread;
this.chatthread = chatthread;
}
//copied from http://faheemsohail.com/2011/01/writing-a-small-plugin-framework-for-your-apps/
public void initPlugins() {
File filePath = new File(pluginPath);
File files[] = filePath.listFiles();
if(files == null) return;
Main.println(0, "[PluginManager] Searching through " + files.length + " files for plugins...");
// Convert File to a URL
ClassLoader loader = null;
try {
URL url = filePath.toURI().toURL();
URL[] urls = new URL[]{url};
loader = new URLClassLoader(urls);
} catch(MalformedURLException e) {
if(Main.DEBUG) {
e.printStackTrace();
}
Main.println(1, "[PluginManager] Malformed URL: " + e.getLocalizedMessage());
return;
}
//Iterate over files in the plugin directory
for (File file : files) {
if (file.isFile() && (file.getName().endsWith(".gcbp.cfg") || file.getName().endsWith(".plugin.cfg"))) {
PropertiesConfiguration pluginConfig = null;
try {
pluginConfig = new PropertiesConfiguration(file);
} catch(ConfigurationException e) {
if(Main.DEBUG) {
e.printStackTrace();
}
Main.println(1, "[PluginManager] Warning: unable to parse plugin configuration file " + file.getAbsolutePath());
}
String fullyQualifiedName = pluginConfig.getString("classname");
File pluginFile = new File(pluginConfig.getString("pluginfile"));
try {
//add loaded plugin to plugin list
Plugin plugin = (Plugin) loader.loadClass(fullyQualifiedName).newInstance();
pluginList.add(plugin);
plugins.put(fullyQualifiedName, plugin);
} catch(Exception e) {
if(Main.DEBUG) {
e.printStackTrace();
}
Main.println(1, "[PluginManager] Error while initiating " + fullyQualifiedName + " in " + pluginFile + ":" + e.getLocalizedMessage());
}
} else {
//skip folders
continue;
}
}
Main.println(4, "[PluginManager] " + pluginList.size() + " plugins found!");
//call init on all plugins
for(Plugin plugin : pluginList) {
//keep exceptions contained
try {
plugin.init(this);
} catch(Exception e) {
e.printStackTrace();
}
}
}
public void say(int id, String s) {
if(chatthread != null) {
chatthread.queueChat(id, s, ChatThread.MAIN_CHAT);
} else {
synchronized(garenaConnections) {
if(garenaConnections.containsKey(id)) {
garenaConnections.get(id).sendGCRPChat(s);
}
}
}
}
public void register(Plugin p, String s) {
ArrayList<Plugin> registerList = register.get(s);
if(registerList == null) {
registerList = new ArrayList<Plugin>();
register.put(s, registerList);
}
if(!registerList.contains(p)) {
registerList.add(p);
}
}
public void deregister(Plugin p, String s) {
ArrayList<Plugin> registerList = register.get(s);
if(registerList != null) {
registerList.remove(p);
}
}
public void registerDelayed(Plugin p, String argument, long millis) {
DelayThread thread = new DelayThread(p, argument, millis);
thread.start();
}
public void registerListener(Plugin p) {
synchronized(garenaConnections) {
Iterator<GarenaInterface> it = garenaConnections.values().iterator();
while(it.hasNext()) {
it.next().registerListener(p);
}
}
}
public void deregisterListener(Plugin p) {
synchronized(garenaConnections) {
Iterator<GarenaInterface> it = garenaConnections.values().iterator();
while(it.hasNext()) {
it.next().deregisterListener(p);
}
}
}
public void loadPlugins() {
try {
String[] pluginNames = GCBConfig.configuration.getStringArray("gcb_plugins");
Main.println(0, "[PluginManager] Loading " + pluginNames.length + " plugins...");
for(String pluginName : pluginNames) {
if(pluginName.equals("")) {
continue;
}
loadPlugin(pluginName);
}
} catch(ConversionException e) {
//do nothing
}
}
public void loadPlugin(String name) {
Main.println(4, "[PluginManager] Loading " + name + "...");
Plugin plugin = plugins.get(name);
if(plugin != null) {
//don't make exceptions go up and cause a big problem
try {
plugin.load();
} catch(Exception e) {
e.printStackTrace();
}
} else {
Main.println(1, "[PluginManager] Load failed: plugin not found!");
}
}
public void unloadPlugin(String name) {
Plugin plugin = plugins.get(name);
if(plugin != null) {
//don't make exception go up and cause a big problem
try {
plugin.unload();
} catch(Exception e) {
e.printStackTrace();
}
}
}
public String onCommand(MemberInfo player, String command, String payload, int rank) {
ArrayList<Plugin> registerList = register.get("onCommand");
if(registerList != null) {
for(Plugin p : registerList) {
String response = p.onCommand(player, command, payload, rank);
if(response != null) {
return response;
}
}
}
return null;
}
public void onDisconnect(int type) {
ArrayList<Plugin> registerList = register.get("onDisconnect");
if(registerList != null) {
for(Plugin p : registerList) {
p.onDisconnect(type);
}
}
}
public void onPacket(int type, int identifier, byte[] bytes, int offset, int length) {
ArrayList<Plugin> registerList = register.get("onPacket");
if(registerList != null) {
for(Plugin p : registerList) {
p.onPacket(type, identifier, bytes, offset, length);
}
}
}
public void log(String message) {
Main.println(0, message);
}
public ChatThread getChatThread() {
return chatthread;
}
public Map<Integer, GarenaInterface> getGarena() {
return garenaConnections;
}
public SQLThread getSQLThread() {
return sqlthread;
}
public WC3Interface getWC3i() {
return wc3i;
}
}
class DelayThread extends Thread {
long millis; //milliseconds to sleep
Plugin plugin; //plugin to call
String argument;
public DelayThread(Plugin plugin, String argument, long millis) {
this.plugin = plugin;
this.argument = argument;
this.millis = millis;
}
public void run() {
try {
Thread.sleep(millis);
} catch(InterruptedException ie) {
}
plugin.onDelay(argument);
}
}