/*
Copyright 2014 Lisovik Denis (Лисовик Денис) ckyberlis@gmail.com
This file is part of PPLoader.
PPLoader is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PPLoader is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with PPLoader. If not, see <http://www.gnu.org/licenses/>
*/
package org.cyberlis.pyloader;
import java.io.File;
import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.command.SimpleCommandMap;
import org.bukkit.entity.Player;
import org.bukkit.plugin.InvalidDescriptionException;
import org.bukkit.plugin.InvalidPluginException;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginLoader;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.SimplePluginManager;
import org.bukkit.plugin.UnknownDependencyException;
import org.bukkit.plugin.java.JavaPlugin;
/**
* Java plugin to initialize python plugin loader and provide it with a little moral boost.
*
*/
public class PythonLoader extends JavaPlugin {
protected PluginManager pm;
public void onDisable() {}
public void onEnable() {}
/**
* Initialize and load up the plugin loader.
*/
@Override
public void onLoad() {
//check if jython.jar exists if not try to download
if(!new File("lib/jython.jar").exists()) {
getServer().getLogger().log(Level.SEVERE, "Could not find lib/jython.jar!");
return;
}
pm = Bukkit.getServer().getPluginManager();
boolean needsload = true;
String errorstr = "cannot ensure that the python loader class is not loaded twice!";
Map<Pattern, PluginLoader> fileAssociations = ReflectionHelper.getFileAssociations(pm, errorstr);
if (fileAssociations != null) {
PluginLoader loader = fileAssociations.get(PythonPluginLoader.fileFilters[0]);
if (loader != null) // already loaded
needsload = false;
}
if (needsload) {
pm.registerInterface(PythonPluginLoader.class);
for (File file : this.getFile().getParentFile().listFiles()) {
for (Pattern filter : PythonPluginLoader.fileFilters) {
Matcher match = filter.matcher(file.getName());
if (match.find()) {
try {
pm.loadPlugin(file);
} catch (InvalidPluginException e) {
e.printStackTrace();
} catch (InvalidDescriptionException e) {
e.printStackTrace();
} catch (UnknownDependencyException e) {
e.printStackTrace();
}
}
}
}
}
}
public final boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args)
{
if (cmd.getName().equalsIgnoreCase("pploader")) {
if (args.length < 1) {
return false;
}
String action = args[0];
if ((!action.equalsIgnoreCase("load")) && (!action.equalsIgnoreCase("unload")) && (!action.equalsIgnoreCase("reload"))) {
getServer().getLogger().severe("Invalid action specified.");
return false;
}
if(!(sender instanceof ConsoleCommandSender) && !(sender instanceof Player && sender.isOp())){
getServer().getLogger().severe("You do not have the permission to do this.");
return true;
}
if (args.length == 1) {
getServer().getLogger().severe("You must specify plugin name or filename");
return true;
}
try
{
if (action.equalsIgnoreCase("unload")){
String plName = args[1];
unloadPlugin(plName);
}
else if (action.equalsIgnoreCase("load")){
String fileName = args[1];
loadPlugin(fileName);
}
else if (action.equalsIgnoreCase("reload") && args.length == 3){
String plName = args[1];
String fileName = args[2];
reloadPlugin(plName, fileName);
} else {
getServer().getLogger().severe("You must specify plugin name or filename");
}
}
catch (Exception e) {
e.printStackTrace();
getServer().getLogger().severe("Exception while perfoming action "+action+" "+e.getMessage());
}
return true;
}
return false;
}
private boolean unloadPlugin(String pluginName)
throws Exception
{
PluginManager manager = getServer().getPluginManager();
SimplePluginManager spmanager = (SimplePluginManager)manager;
if (spmanager != null) {
Field pluginsField = spmanager.getClass().getDeclaredField("plugins");
pluginsField.setAccessible(true);
List plugins = (List)pluginsField.get(spmanager);
Field lookupNamesField = spmanager.getClass().getDeclaredField("lookupNames");
lookupNamesField.setAccessible(true);
Map lookupNames = (Map)lookupNamesField.get(spmanager);
Field commandMapField = spmanager.getClass().getDeclaredField("commandMap");
commandMapField.setAccessible(true);
SimpleCommandMap commandMap = (SimpleCommandMap)commandMapField.get(spmanager);
Field knownCommandsField = null;
Map knownCommands = null;
if (commandMap != null) {
knownCommandsField = commandMap.getClass().getDeclaredField("knownCommands");
knownCommandsField.setAccessible(true);
knownCommands = (Map)knownCommandsField.get(commandMap);
}
Iterator it;
for (Plugin plugin: manager.getPlugins())
if (plugin.getDescription().getName().equalsIgnoreCase(pluginName)) {
manager.disablePlugin(plugin);
if ((plugins != null) && (plugins.contains(plugin))) {
plugins.remove(plugin);
}
if ((lookupNames != null) && (lookupNames.containsKey(pluginName))) {
lookupNames.remove(pluginName);
}
if (commandMap != null)
for (it = knownCommands.entrySet().iterator(); it.hasNext(); ) {
Map.Entry entry = (Map.Entry)it.next();
if ((entry.getValue() instanceof PluginCommand)) {
PluginCommand command = (PluginCommand)entry.getValue();
if (command.getPlugin() == plugin) {
command.unregister(commandMap);
it.remove();
}
}
}
}
}
else
{
getServer().getLogger().warning(pluginName + " is already unloaded.");
return true;
}
getServer().getLogger().info("Unloaded " + pluginName + " successfully!");
return true;
}
private boolean loadPlugin(String pluginName)
{
try
{
File file = new File("plugins", pluginName);
for (Pattern filter : PythonPluginLoader.fileFilters) {
Matcher match = filter.matcher(file.getName());
if (match.find()) {
try {
Plugin plugin = pm.loadPlugin(file);
pm.enablePlugin(plugin);
} catch (InvalidPluginException e) {
e.printStackTrace();
} catch (InvalidDescriptionException e) {
e.printStackTrace();
} catch (UnknownDependencyException e) {
e.printStackTrace();
}
}
}
} catch (Exception e) {
e.printStackTrace();
getServer().getLogger().severe("Error loading " + pluginName + ", this plugin must be reloaded by restarting the server.");
return false;
}
getServer().getLogger().info("Loaded " + pluginName + " successfully!");
return true;
}
private boolean reloadPlugin(String pluginName, String fileName)
throws Exception
{
boolean unload = unloadPlugin(pluginName);
boolean load = loadPlugin(fileName);
if ((unload) && (load)) {
getServer().getLogger().info("Reloaded " + pluginName + " successfully!");
}
else {
getServer().getLogger().severe("Error reloading " + pluginName + ".");
return false;
}
return true;
}
}