diff --git a/src/WorldEdit.java b/src/WorldEdit.java index c21d533bc..ddcbf98ab 100644 --- a/src/WorldEdit.java +++ b/src/WorldEdit.java @@ -18,37 +18,55 @@ */ import java.util.HashMap; +import java.util.HashSet; +import java.util.Arrays; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.Map; import java.io.*; import com.sk89q.worldedit.*; /** - * Plugin entry point for Hey0's mod. + * Plugin base. * * @author sk89q */ -public class WorldEdit extends Plugin { - private final static String DEFAULT_ALLOWED_BLOCKS = - "0,1,2,3,4,5,7,8,9,10,11,12,13,14,15,16,17,18,19,20,35,41,42,43," + - "44,45,47,48,49,52,53,54,56,57,58,60,61,62,67,73,78,79,80,81,82,85"; +public class WorldEdit { + /** + * List of default allowed blocks. + */ + private final static Integer[] DEFAULT_ALLOWED_BLOCKS = { + 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 35, 41, 42, 43, 44, 45, 47, 48, 49, 52, 53, 54, 56, 57, 58, 60, + 61, 62, 67, 73, 78, 79, 80, 81, 82, 85 + }; + /** + * Logger. + */ private static final Logger logger = Logger.getLogger("Minecraft"); + /** + * Stores the WorldEdit sessions of players. + */ private HashMap sessions = new HashMap(); + /** + * Stores the commands. + */ private HashMap commands = new HashMap(); - private PropertiesFile properties; - private String[] allowedBlocks; - private int defaultMaxBlocksChanged; + /** + * List of the blocks that can be used. If null, all blocks can be used. + */ + private HashSet allowedBlocks; + /** + * Default block change limit. -1 for no limit. + */ + private int defaultChangeLimit = -1; /** * Construct an instance of the plugin. */ public WorldEdit() { - super(); - commands.put("/editpos1", "Set editing position #1"); commands.put("/editpos2", "Set editing position #2"); commands.put("/editwand", "Gives you the \"edit wand\""); @@ -82,12 +100,12 @@ public class WorldEdit extends Plugin { * @param player * @return */ - private WorldEditSession getSession(WorldEditPlayer player) { + public WorldEditSession getSession(WorldEditPlayer player) { if (sessions.containsKey(player)) { return sessions.get(player); } else { WorldEditSession session = new WorldEditSession(); - session.setBlockChangeLimit(defaultMaxBlocksChanged); + session.setBlockChangeLimit(getDefaultChangeLimit()); sessions.put(player, session); return session; } @@ -101,7 +119,7 @@ public class WorldEdit extends Plugin { * @throws UnknownItemException * @throws DisallowedItemException */ - private int getItem(String id, boolean allAllowed) + public int getItem(String id, boolean allAllowed) throws UnknownItemException, DisallowedItemException { int foundID; @@ -115,17 +133,11 @@ public class WorldEdit extends Plugin { } } - // All items allowed - if (allAllowed || allowedBlocks[0].equals("")) { + // Check if the item is allowed + if (allAllowed || allowedBlocks.isEmpty() || allowedBlocks.contains(foundID)) { return foundID; } - for (String s : allowedBlocks) { - if (s.equals(String.valueOf(foundID))) { - return foundID; - } - } - throw new DisallowedItemException(); } @@ -137,20 +149,11 @@ public class WorldEdit extends Plugin { * @throws UnknownItemException * @throws DisallowedItemException */ - private int getItem(String id) throws UnknownItemException, + public int getItem(String id) throws UnknownItemException, DisallowedItemException { return getItem(id, false); } - /** - * - * @param player - */ - @Override - public void onDisconnect(Player player) { - sessions.remove(player.getName()); - } - /** * Checks to make sure that there are enough but not too many arguments. * @@ -172,140 +175,6 @@ public class WorldEdit extends Plugin { } } - /** - * Enables the plugin. - */ - public void enable() { - if (properties == null) { - properties = new PropertiesFile("worldedit.properties"); - } else { - properties.load(); - } - - allowedBlocks = properties.getString("allowed-blocks", DEFAULT_ALLOWED_BLOCKS).split(","); - defaultMaxBlocksChanged = - Math.max(-1, properties.getInt("max-blocks-changed", -1)); - - etc controller = etc.getInstance(); - - for (Map.Entry entry : commands.entrySet()) { - controller.addCommand(entry.getKey(), entry.getValue()); - } - } - - /** - * Disables the plugin. - */ - public void disable() { - etc controller = etc.getInstance(); - - for (String key : commands.keySet()) { - controller.removeCommand(key); - } - - sessions.clear(); - } - - /** - * Called on right click. - * - * @param modPlayer - * @param blockPlaced - * @param blockClicked - * @param itemInHand - * @return false if you want the action to go through - */ - @Override - public boolean onBlockCreate(Player modPlayer, Block blockPlaced, - Block blockClicked, int itemInHand) { - if (itemInHand == 271) { // Wooden axe - if (!modPlayer.canUseCommand("/editpos1") - || !modPlayer.canUseCommand("/editpos2")) { - return false; - } - - WorldEditPlayer player = new WorldEditPlayer(modPlayer); - WorldEditSession session = getSession(player); - - if (session.isToolControlEnabled()) { - Point cur = Point.toBlockPoint(blockClicked.getX(), - blockClicked.getY(), - blockClicked.getZ()); - - try { - if (session.hasToolBeenDoubleClicked() - && cur.equals(session.getPos1())) { // Pos 2 - session.setPos2(cur); - session.setPos1(session.getLastToolPos1()); - player.print("Second edit position set; first one restored."); - } else { - // Have to remember the original position because on - // double click, we are going to restore it - try { - session.setLastToolPos1(session.getPos1()); - } catch (IncompleteRegionException e) {} - - session.setPos1(cur); - player.print("First edit position set."); - } - } catch (IncompleteRegionException e) {} - - session.triggerToolClick(); - - return true; - } - } - - return false; - } - - /** - * - * @param modPlayer - * @param split - * @return whether the command was processed - */ - @Override - public boolean onCommand(Player modPlayer, String[] split) { - try { - if (commands.containsKey(split[0])) { - if (modPlayer.canUseCommand(split[0])) { - WorldEditPlayer player = new WorldEditPlayer(modPlayer); - WorldEditSession session = getSession(player); - EditSession editSession = - new EditSession(session.getBlockChangeLimit()); - editSession.enableQueue(); - - try { - return performCommand(player, session, editSession, split); - } finally { - session.remember(editSession); - editSession.flushQueue(); - } - } - } - - return false; - } catch (NumberFormatException e) { - modPlayer.sendMessage(Colors.Rose + "Number expected; string given."); - } catch (IncompleteRegionException e2) { - modPlayer.sendMessage(Colors.Rose + "The edit region has not been fully defined."); - } catch (UnknownItemException e3) { - modPlayer.sendMessage(Colors.Rose + "Unknown item."); - } catch (DisallowedItemException e4) { - modPlayer.sendMessage(Colors.Rose + "Disallowed item."); - } catch (MaxChangedBlocksException e5) { - modPlayer.sendMessage(Colors.Rose + "The maximum number of blocks changed (" - + e5.getBlockLimit() + ") in an instance was reached."); - } catch (InsufficientArgumentsException e6) { - modPlayer.sendMessage(Colors.Rose + e6.getMessage()); - } catch (WorldEditException e7) { - modPlayer.sendMessage(Colors.Rose + e7.getMessage()); - } - - return true; - } - /** * The main meat of command processing. * @@ -320,7 +189,7 @@ public class WorldEdit extends Plugin { * @throws InsufficientArgumentsException * @throws DisallowedItemException */ - private boolean performCommand(WorldEditPlayer player, + public boolean performCommand(WorldEditPlayer player, WorldEditSession session, EditSession editSession, String[] split) throws WorldEditException { @@ -639,15 +508,67 @@ public class WorldEdit extends Plugin { } /** - * Gets the block type at a position x, y, z. Use an instance of - * EditSession if possible. - * - * @param x - * @param y - * @param z - * @return Block type + * Remove a session. + * + * @param player */ - public int getBlock(int x, int y, int z) { - return etc.getMCServer().e.a(x, y, z); + public void removeSession(WorldEditPlayer player) { + sessions.remove(player); + } + + /** + * Remove all sessions. + */ + public void clearSessions() { + sessions.clear(); + } + + /** + * Get the list of commands. + * + * @return List + */ + public HashMap getCommands() { + return commands; + } + + /** + * Set the list of allowed blocks. Provided null to use the default list. + * + * @param allowedBlocks + */ + public void setAllowedBlocks(HashSet allowedBlocks) { + this.allowedBlocks = allowedBlocks != null ? allowedBlocks + : new HashSet(Arrays.asList(DEFAULT_ALLOWED_BLOCKS)); + } + + /** + * Get a comma-delimited list of the default allowed blocks. + * + * @return comma-delimited list + */ + public static String getDefaultAllowedBlocks() { + StringBuilder b = new StringBuilder(); + for (Integer id : DEFAULT_ALLOWED_BLOCKS) { + b.append(id).append(","); + } + return b.substring(0, b.length() - 1); + } + + /** + * @return the defaultChangeLimit + */ + public int getDefaultChangeLimit() { + return defaultChangeLimit; + } + + /** + * Set the default limit on the number of blocks that can be changed + * in one operation. + * + * @param defaultChangeLimit the defaultChangeLimit to set + */ + public void setDefaultChangeLimit(int defaultChangeLimit) { + this.defaultChangeLimit = defaultChangeLimit; } } diff --git a/src/WorldEditPlayer.java b/src/WorldEditPlayer.java index c83e416eb..e9c271b03 100644 --- a/src/WorldEditPlayer.java +++ b/src/WorldEditPlayer.java @@ -89,6 +89,15 @@ public class WorldEditPlayer { return player.getRotation(); } + /** + * Get the ID of the item that the player is holding. + * + * @return + */ + public int getItemInHand() { + return player.getItemInHand(); + } + /** * Print a WorldEdit message. * diff --git a/src/WorldEditSM.java b/src/WorldEditSM.java new file mode 100644 index 000000000..011c003a8 --- /dev/null +++ b/src/WorldEditSM.java @@ -0,0 +1,94 @@ +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q + * + * 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 . +*/ + +import java.util.Map; +import java.util.HashSet; + +/** + * Entry point for the plugin for hey0's mod. + * + * @author sk89q + */ +public class WorldEditSM extends Plugin { + private PropertiesFile properties; + private static final WorldEdit worldEdit = new WorldEdit(); + private static final WorldEditSMListener listener = + new WorldEditSMListener(worldEdit); + + /** + * Initializes the plugin. + */ + @Override + public void initialize() { + PluginLoader loader = etc.getLoader(); + + loader.addListener(PluginLoader.Hook.BLOCK_CREATED, listener, this, + PluginListener.Priority.MEDIUM); + loader.addListener(PluginLoader.Hook.BLOCK_DESTROYED, listener, this, + PluginListener.Priority.MEDIUM); + loader.addListener(PluginLoader.Hook.COMMAND, listener, this, + PluginListener.Priority.MEDIUM); + loader.addListener(PluginLoader.Hook.DISCONNECT, listener, this, + PluginListener.Priority.MEDIUM); + loader.addListener(PluginLoader.Hook.LOGIN, listener, this, + PluginListener.Priority.MEDIUM); + } + + /** + * Enables the plugin. + */ + @Override + public void enable() { + if (properties == null) { + properties = new PropertiesFile("worldedit.properties"); + } else { + properties.load(); + } + + // Get allowed blocks + HashSet allowedBlocks = new HashSet(); + for (String b : properties.getString("allowed-blocks", + WorldEdit.getDefaultAllowedBlocks()).split(",")) { + try { + allowedBlocks.add(Integer.parseInt(b)); + } catch (NumberFormatException e) { + } + } + worldEdit.setAllowedBlocks(allowedBlocks); + + worldEdit.setDefaultChangeLimit( + Math.max(-1, properties.getInt("max-blocks-changed", -1))); + + for (Map.Entry entry : worldEdit.getCommands().entrySet()) { + etc.getInstance().addCommand(entry.getKey(), entry.getValue()); + } + } + + /** + * Disables the plugin. + */ + @Override + public void disable() { + for (String key : worldEdit.getCommands().keySet()) { + etc.getInstance().removeCommand(key); + } + + worldEdit.clearSessions(); + } +} diff --git a/src/WorldEditSMListener.java b/src/WorldEditSMListener.java new file mode 100644 index 000000000..031c23072 --- /dev/null +++ b/src/WorldEditSMListener.java @@ -0,0 +1,168 @@ +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q + * + * 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 . +*/ + +import com.sk89q.worldedit.*; + +/** + * Event listener for Hey0's server mod plugin. + * + * @author sk89q + */ +public class WorldEditSMListener extends PluginListener { + /** + * Stores a reference to the WorldEdit object. + */ + private WorldEdit worldEdit; + + /** + * Construct the listener with a reference to the WorldEdit object. + * + * @param worldEdit + */ + public WorldEditSMListener(WorldEdit worldEdit) { + this.worldEdit = worldEdit; + } + + /** + * + * @param player + */ + @Override + public void onDisconnect(Player player) { + worldEdit.removeSession(new WorldEditPlayer(player)); + } + + /** + * Called on right click. + * + * @param modPlayer + * @param blockPlaced + * @param blockClicked + * @param itemInHand + * @return false if you want the action to go through + */ + @Override + public boolean onBlockCreate(Player modPlayer, Block blockPlaced, + Block blockClicked, int itemInHand) { + WorldEditPlayer player = new WorldEditPlayer(modPlayer); + + if (itemInHand != 271) { return false; } + if (!modPlayer.canUseCommand("/editpos2")) { return false; } + + WorldEditSession session = worldEdit.getSession(player); + + if (session.isToolControlEnabled()) { + Point cur = Point.toBlockPoint(blockClicked.getX(), + blockClicked.getY(), + blockClicked.getZ()); + + session.setPos2(cur); + player.print("Second edit position set."); + + return true; + } + + return false; + } + + /** + * Called on left click. + * + * @param modPlayer + * @param blockClicked + * @param itemInHand + * @return false if you want the action to go through + */ + @Override + public boolean onBlockDestroy(Player modPlayer, Block blockClicked) { + WorldEditPlayer player = new WorldEditPlayer(modPlayer); + + if (player.getItemInHand() != 271) { return false; } + if (!modPlayer.canUseCommand("/editpos1")) { return false; } + + WorldEditSession session = worldEdit.getSession(player); + + if (session.isToolControlEnabled()) { + Point cur = Point.toBlockPoint(blockClicked.getX(), + blockClicked.getY(), + blockClicked.getZ()); + + try { + if (session.getPos1().equals(cur)) { + return false; + } + } catch (IncompleteRegionException e) { + } + + session.setPos1(cur); + player.print("First edit position set."); + + return true; + } + + return false; + } + + /** + * + * @param modPlayer + * @param split + * @return whether the command was processed + */ + @Override + public boolean onCommand(Player modPlayer, String[] split) { + try { + if (worldEdit.getCommands().containsKey(split[0])) { + if (modPlayer.canUseCommand(split[0])) { + WorldEditPlayer player = new WorldEditPlayer(modPlayer); + WorldEditSession session = worldEdit.getSession(player); + EditSession editSession = + new EditSession(session.getBlockChangeLimit()); + editSession.enableQueue(); + + try { + return worldEdit.performCommand(player, session, editSession, split); + } finally { + session.remember(editSession); + editSession.flushQueue(); + } + } + } + + return false; + } catch (NumberFormatException e) { + modPlayer.sendMessage(Colors.Rose + "Number expected; string given."); + } catch (IncompleteRegionException e2) { + modPlayer.sendMessage(Colors.Rose + "The edit region has not been fully defined."); + } catch (UnknownItemException e3) { + modPlayer.sendMessage(Colors.Rose + "Unknown item."); + } catch (DisallowedItemException e4) { + modPlayer.sendMessage(Colors.Rose + "Disallowed item."); + } catch (MaxChangedBlocksException e5) { + modPlayer.sendMessage(Colors.Rose + "The maximum number of blocks changed (" + + e5.getBlockLimit() + ") in an instance was reached."); + } catch (InsufficientArgumentsException e6) { + modPlayer.sendMessage(Colors.Rose + e6.getMessage()); + } catch (WorldEditException e7) { + modPlayer.sendMessage(Colors.Rose + e7.getMessage()); + } + + return true; + } +} \ No newline at end of file