package tv.mineinthebox.essentials.managers;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.PluginCommand;
import org.bukkit.command.SimpleCommandMap;
import org.bukkit.plugin.Plugin;
import tv.mineinthebox.essentials.xEssentials;
import tv.mineinthebox.essentials.commands.SimpleCommand;
public class CommandManager {
private final xEssentials pl;
public CommandManager(xEssentials pl) {
this.pl = pl;
}
/**
* @author zeeveener
* @param object
* @param field
* @return Object
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
private Object getPrivateField(Object object, String field)throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
Class<?> clazz = object.getClass();
Field objectField = clazz.getDeclaredField(field);
objectField.setAccessible(true);
Object result = objectField.get(object);
objectField.setAccessible(false);
return result;
}
/**
* unregister a command, credits to zeeveener for his awesome code to unregister commands!
*
* @author zeeveener, xize
* @param cmd - the command to be unregistered
*/
public void unRegisterBukkitCommand(PluginCommand cmd) {
try {
Object result = getPrivateField(Bukkit.getServer().getPluginManager(), "commandMap");
SimpleCommandMap commandMap = (SimpleCommandMap) result;
Object map = getPrivateField(commandMap, "knownCommands");
@SuppressWarnings("unchecked")
HashMap<String, Command> knownCommands = (HashMap<String, Command>) map;
knownCommands.remove("xessentials"+":"+cmd.getName());
if(knownCommands.containsKey(cmd.getName()) && knownCommands.get(cmd.getName().toLowerCase()).toString().contains(pl.getName())) {
knownCommands.remove(cmd.getName());
}
for (String alias : cmd.getAliases()){
if(knownCommands.containsKey("xessentials:"+alias) && knownCommands.get("xessentials:"+alias).toString().contains(pl.getName())){
knownCommands.remove("xessentials:"+alias);
}
if(knownCommands.containsKey(alias) && knownCommands.get(alias).toString().contains(pl.getName())){
knownCommands.remove(alias);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* returns true if the command is registered inside xEssentials otherwise false
*
* @author xize
* @param cmd - the command
* @return boolean
*/
public boolean isRegistered(String cmd) {
try {
Object result = getPrivateField(Bukkit.getServer().getPluginManager(), "commandMap");
SimpleCommandMap commandMap = (SimpleCommandMap) result;
Object map = getPrivateField(commandMap, "knownCommands");
@SuppressWarnings("unchecked")
HashMap<String, Command> knownCommands = (HashMap<String, Command>) map;
if(knownCommands.containsKey("xessentials"+":"+cmd) || (knownCommands.containsKey(cmd) && knownCommands.get(cmd).toString().contains(pl.getName()))) {
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* re-registers the command in the plugin
*
* @author zeeveener, xize
* @param cmd - the command
*/
@SuppressWarnings("unchecked")
public void registerBukkitCommand(PluginCommand cmd) {
try {
Object result = getPrivateField(Bukkit.getServer().getPluginManager(), "commandMap");
SimpleCommandMap commandMap = (SimpleCommandMap) result;
Object map = getPrivateField(commandMap, "knownCommands");
HashMap<String, Command> knownCommands = (HashMap<String, Command>) map;
knownCommands.put("xessentials:"+cmd.getName(), cmd);
knownCommands.put(cmd.getName(), cmd);
List<String> aliases = (List<String>)pl.getDescription().getCommands().get(cmd.getName()).get("aliases");
for(String alias : aliases){
if(!knownCommands.containsKey("xessentials:"+alias)){
knownCommands.put("xessentials:"+alias, cmd);
}
if(!knownCommands.containsKey(alias)){
knownCommands.put(alias, cmd);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* forces to create a PluginCommand
*
* @author xize
* @param cmd - the command to be created as instance
* @return PluginCommand
*/
@SuppressWarnings("unchecked")
public PluginCommand createPluginCommand(String cmd) {
try {
//forcibly make a new PluginCommand object
Class<?> clazz = Class.forName("org.bukkit.command.PluginCommand");
Constructor<?> constructor = clazz.getDeclaredConstructor(String.class, Plugin.class);
constructor.setAccessible(true);
Field mf = Constructor.class.getDeclaredField("modifiers");
mf.setAccessible(true);
mf.setInt(constructor, constructor.getModifiers() &~Modifier.PROTECTED);
PluginCommand command = (PluginCommand) constructor.newInstance(cmd, pl);
command.setExecutor(new SimpleCommand(pl));
List<String> aliases = (List<String>) pl.getDescription().getCommands().get(command.getName()).get("aliases");
command.setAliases(aliases);
constructor.setAccessible(false);
mf.setAccessible(false);
return command;
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
}