/**
* bFundamentals 1.2-SNAPSHOT
* Copyright (C) 2013 CodingBadgers <plugins@mcbadgercraft.com>
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package uk.codingbadgers.bFundamentals.commands;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandMap;
import org.bukkit.command.SimpleCommandMap;
import org.bukkit.plugin.PluginManager;
import com.google.common.collect.ImmutableList;
import uk.codingbadgers.bFundamentals.bFundamentals;
import uk.codingbadgers.bFundamentals.module.Module;
/**
* The Module Command handler, handles internal command registering.
* <p>
* SHOULD NOT BE USED OUTSIDE bFundamentals
*/
public class ModuleCommandHandler {
// TODO check each update to make sure they don't change the field name
private static final String commandMapFieldName = "commandMap";
private static final String commandsFieldName = "knownCommands";
private static Map<Module, List<ModuleCommand>> commands = new HashMap<Module, List<ModuleCommand>>();
private static CommandMap commandMap;
private static Field knownCommandsField;
static {
setupCommandMap();
}
private static void setupCommandMap() {
// reflection to make sure we don't have to use OBC code
try {
Class<? extends PluginManager> clazz = Bukkit.getServer().getPluginManager().getClass();
Field field = clazz.getDeclaredField(commandMapFieldName);
field.setAccessible(true);
commandMap = (CommandMap) field.get(Bukkit.getServer().getPluginManager());
} catch (Exception e) {
bFundamentals.log(Level.INFO, "Error setting up command handler", e);
commandMap = null;
}
if (commandMap instanceof SimpleCommandMap) {
try {
knownCommandsField = SimpleCommandMap.class.getDeclaredField(commandsFieldName);
knownCommandsField.setAccessible(true);
} catch (Exception e) {
bFundamentals.log(Level.INFO, "Error setting up command handler", e);
}
} else {
bFundamentals.log(Level.SEVERE, "Unknown command map type, cannot deregister commands.");
}
}
/**
* Register command.
*
* @param module the module
* @param command the command
*/
public static void registerCommand(Module module, ModuleCommand command) {
command.register(module);
commandMap.register(module.getName(), command);
if (commands.containsKey(module)) {
commands.get(module).add(command);
} else {
commands.put(module, new ArrayList<ModuleCommand>(Arrays.asList(command)));
}
}
/**
* Deregister all commands from a module.
*
* @param module the module
*/
@SuppressWarnings("unchecked")
public static void deregisterCommand(Module module) {
if (!commands.containsKey(module) || getCommands(module) == null) {
return;
}
List<ModuleCommand> commands = new ArrayList<ModuleCommand>(getCommands(module));
for (ModuleCommand command : commands) {
ModuleCommandHandler.commands.get(module).remove(command);
try {
Map<String, Command> knownCommands = (Map<String, Command>) knownCommandsField.get(commandMap);
Command theCommand = commandMap.getCommand(command.getLabel());
if (theCommand == null) {
throw new Exception("Cannot find command " + command.getLabel() + " in bukkit command map");
}
theCommand.unregister(commandMap);
knownCommands.remove(theCommand.getLabel().toLowerCase());
if (bFundamentals.getConfigurationManager().isDebugEnabled()) {
bFundamentals.log(Level.INFO, theCommand.getLabel().toLowerCase() + " for module " + module.getName() + " has been deregistered successfully");
}
} catch (Throwable e) {
bFundamentals.log(Level.INFO, "Error deregistrying " + command.getName() + " for module " + module.getName(), e);
}
}
}
/**
* Gets the commands for a module.
*
* @param module the module
* @return the commands for that module
*/
public static List<ModuleCommand> getCommands(Module module) {
if (!commands.containsKey(module)) {
return new ImmutableList.Builder<ModuleCommand>().build();
}
return new ImmutableList.Builder<ModuleCommand>().addAll(commands.get(module)).build();
}
}