package com.sijobe.spc.command; import com.sijobe.spc.core.Constants; import com.sijobe.spc.util.FontColour; import com.sijobe.spc.util.KeyListener; import com.sijobe.spc.util.KeyboardHandler; import com.sijobe.spc.util.Settings; import com.sijobe.spc.validation.Parameter; import com.sijobe.spc.validation.ParameterInteger; import com.sijobe.spc.validation.ParameterString; import com.sijobe.spc.validation.Parameters; import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandManager; import com.sijobe.spc.wrapper.CommandSender; import com.sijobe.spc.wrapper.Minecraft; import com.sijobe.spc.wrapper.MinecraftServer; import com.sijobe.spc.wrapper.Player; import java.io.File; import java.util.List; import org.lwjgl.input.Keyboard; /** * Handles the bindings that the player has assigned to keys * * @author simo_415 * @version 1.1 */ public class Bind extends MultipleCommands implements KeyListener { /** * The bindings that the player uses */ private static Settings BINDINGS = new Settings(new File(Constants.MOD_DIR, "bindings.properties")); /** * The instance that all key bindings are associated against */ private static Bind INSTANCE = new Bind(""); // Adds all the binding listeners static { INSTANCE.addKeyListeners(); } /** * The parameters for the bind command */ private static final Parameters BIND_PARAMS = new Parameters ( new Parameter[] { new ParameterString("<KEYCODE>", false), new ParameterString("<COMMAND>", false), new ParameterString("{PARAMETERS}", true, true) } ); /** * The parameters for the bindid command */ private static final Parameters BINDID_PARAMS = new Parameters ( new Parameter[] { new ParameterInteger("<KEYID>", false), new ParameterString("<COMMAND>", false), new ParameterString("{PARAMETERS}", true, true) } ); /** * The parameters for the unbind command */ private static final Parameters UNBIND_PARAMS = new Parameters ( new Parameter[] { new ParameterString("<KEYCODE|all>", false), } ); /** * Initialises the instance using the specified command name * * @param name - The name of the command */ public Bind(String name) { super(name); } /** * Adds all the binding listeners to the key listener */ private void addKeyListeners() { for (Object key : BINDINGS.keySet()) { try { bind(Integer.parseInt((String)key)); } catch (Exception e) { System.err.println("Invalid key specified in bindings: " + key); BINDINGS.remove(key); } } } /** * The bind commands are only enabled in single player mode since keyboard * handling can only currently be done locally as key presses don't get sent * to the server. * * @see com.sijobe.spc.wrapper.CommandBase#isEnabled() */ @Override public boolean isEnabled() { return Minecraft.isSinglePlayer(); } /** * @see com.sijobe.spc.command.MultipleCommands#getCommands() */ @Override public String[] getCommands() { return new String[] {"bind", "unbind", "bindid", "unbindid"}; } /** * @see com.sijobe.spc.wrapper.CommandBase#execute(com.sijobe.spc.wrapper.CommandSender, java.util.List) */ @Override public void execute(CommandSender sender, List<?> params) throws CommandException { if (getName().equalsIgnoreCase("bind") || getName().equalsIgnoreCase("bindid")) { int keycode = Keyboard.KEY_NONE; if (getName().equalsIgnoreCase("bind")) { String key = (String)params.get(0); keycode = Keyboard.getKeyIndex(key.toUpperCase()); } else { keycode = (Integer)params.get(0); } if (keycode == Keyboard.KEY_NONE) { throw new CommandException("Unknown keycode " + params.get(0)); } String command = (String)params.get(1); String param = ""; if (params.size() > 2) { param = (String)params.get(2); } if (BINDINGS.get(keycode + "") == null) { bind(keycode); } BINDINGS.set(keycode + "", command + " " + param); BINDINGS.save(); sender.sendMessageToPlayer("Key " + FontColour.AQUA + params.get(0) + FontColour.WHITE + " was successfully bound."); } else if (getName().equalsIgnoreCase("unbind") || getName().equalsIgnoreCase("unbindid")) { int keycode = Keyboard.KEY_NONE; if (getName().equalsIgnoreCase("unbind")) { String key = (String)params.get(0); if (key.equalsIgnoreCase("all")) { BINDINGS.clear(); BINDINGS.save(); sender.sendMessageToPlayer("All bindings removed."); return; } keycode = Keyboard.getKeyIndex(key.toUpperCase()); } else { keycode = (Integer)params.get(0); } if (keycode == Keyboard.KEY_NONE) { throw new CommandException("Unknown keycode " + params.get(0)); } unbind(keycode); if (BINDINGS.remove(keycode + "") == null) { throw new CommandException("No binding was found for key " + FontColour.AQUA + (String)params.get(0)); } else { BINDINGS.save(); sender.sendMessageToPlayer("Binding " + FontColour.AQUA + params.get(0) + FontColour.WHITE + " was successfully removed."); } } else { assert false : "Invalid command " + getName(); } } /** * Binds a key to a listener * * @param key - The key to bind */ private void bind(int key) { if (!KeyboardHandler.getInstance().addKeyPressedListener(key, INSTANCE)) { System.err.println("Invalid key specified in bindings: " + key); BINDINGS.remove(key); } } /** * Unbinds the key from the listener * * @param key - The key to unbind */ private void unbind(int key) { KeyboardHandler.getInstance().removeKeyPressedListener(key, INSTANCE); } @Override public Parameters getParameters() { if (getName().equalsIgnoreCase("bind")) { return BIND_PARAMS; } else if (getName().equalsIgnoreCase("unbind")) { return UNBIND_PARAMS; } else if (getName().equalsIgnoreCase("bindid")) { return BINDID_PARAMS; } else { assert false : "Invalid command name initialsied " + getName(); return Parameters.DEFAULT; } } /** * Handles binding events * * @see com.sijobe.spc.util.KeyListener#keyPressed(int) */ @Override public void keyPressed(int key) { if (Minecraft.isGuiScreenOpen()) { return; } Player player = Minecraft.getPlayer(); if (player != null) { CommandSender sender = new CommandSender(MinecraftServer.getPlayerByUsername(player.getPlayerName())); CommandManager.runCommand(sender, BINDINGS.getString(key + "", "")); } } /** * @see com.sijobe.spc.util.KeyListener#keyReleased(int) */ @Override public void keyReleased(int key) { // Not required } }