diff --git a/src/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java b/src/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java index 889a4add..04860b56 100644 --- a/src/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java +++ b/src/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java @@ -297,7 +297,7 @@ public boolean handleCommand(PlayerChatEvent event) { } else if (split[0].equalsIgnoreCase("/rg") || split[0].equalsIgnoreCase("/region")) { if (split.length < 2) { - player.sendMessage(ChatColor.RED + "/rg ..."); + player.sendMessage(ChatColor.RED + "/region ..."); return true; } @@ -321,10 +321,19 @@ public boolean handleCommand(PlayerChatEvent event) { * @param args */ private void handleRegionCommand(Player player, String action, String[] args) { - if (action.equalsIgnoreCase("define") - && canUseRegionCommand(player, "/regiondefine")) { + if (!plugin.useRegions) { + player.sendMessage(ChatColor.RED + "Regions are disabled."); + return; + } + + if (action.equalsIgnoreCase("define")) { + if (!canUseRegionCommand(player, "/regiondefine")) { + player.sendMessage(ChatColor.RED + "You don't have the /regiondefine permission."); + return; + } + if (args.length < 2) { - player.sendMessage(ChatColor.RED + "/rg define [owner1 [owner2 [owners...]]]"); + player.sendMessage(ChatColor.RED + "/region define [owner1 [owner2 [owners...]]]"); return; } @@ -358,10 +367,68 @@ && canUseRegionCommand(player, "/regiondefine")) { player.sendMessage(ChatColor.RED + "Region database failed to save: " + e.getMessage()); } - } else if (action.equalsIgnoreCase("flag") - && canUseRegionCommand(player, "/regiondefine")) { + } else if (action.equalsIgnoreCase("claim")) { + if (!canUseRegionCommand(player, "/regionclaim")) { + player.sendMessage(ChatColor.RED + "You don't have the /regionclaim permission."); + return; + } + + if (args.length < 1) { + player.sendMessage(ChatColor.RED + "/region claim "); + return; + } + + try { + String id = args[1].toLowerCase(); + Plugin wePlugin = plugin.getServer().getPluginManager().getPlugin("WorldEdit"); + if (plugin == null) { + player.sendMessage(ChatColor.RED + "WorldEdit must be installed and enabled as a plugin."); + return; + } + + ProtectedRegion existing = plugin.regionManager.getRegion(id); + + if (existing != null) { + if (!existing.getOwners().contains(plugin.wrapPlayer(player))) { + player.sendMessage(ChatColor.RED + "You don't own this region."); + return; + } + } + + WorldEditPlugin worldEdit = (WorldEditPlugin)wePlugin; + WorldEditAPI api = worldEdit.getAPI(); + + LocalSession session = api.getSession(player); + Region weRegion = session.getRegion(); + + BlockVector min = weRegion.getMinimumPoint().toBlockVector(); + BlockVector max = weRegion.getMaximumPoint().toBlockVector(); + + ProtectedRegion region = new ProtectedCuboidRegion(min, max); + + if (!plugin.regionManager.overlapsUnownedRegion(region, plugin.wrapPlayer(player))) { + player.sendMessage(ChatColor.RED + "This region overlaps with someone else's region."); + return; + } + + plugin.regionManager.addRegion(id, region); + plugin.regionLoader.save(plugin.regionManager); + player.sendMessage(ChatColor.YELLOW + "Region saved as " + id + "."); + } catch (IncompleteRegionException e) { + player.sendMessage(ChatColor.RED + "You must first define an area in WorldEdit."); + } catch (IOException e) { + player.sendMessage(ChatColor.RED + "Region database failed to save: " + + e.getMessage()); + } + } else if (action.equalsIgnoreCase("flag")) { + if (!canUseRegionCommand(player, "/regiondefine")) { + player.sendMessage(ChatColor.RED + "You don't have the /regiondefine permission."); + return; + } + if (args.length < 4) { - player.sendMessage(ChatColor.RED + "/rg flag "); + player.sendMessage(ChatColor.RED + "/region flag "); + player.sendMessage(ChatColor.RED + "Other flags not supported in Bukkit at the moment."); return; } @@ -391,13 +458,13 @@ && canUseRegionCommand(player, "/regiondefine")) { AreaFlags flags = region.getFlags(); - if (flagStr.equalsIgnoreCase("build")) { + /*if (flagStr.equalsIgnoreCase("build")) { flags.allowBuild = state; } else if (flagStr.equalsIgnoreCase("pvp")) { flags.allowPvP = state; } else if (flagStr.equalsIgnoreCase("tnt")) { flags.allowTNT = state; - } else if (flagStr.equalsIgnoreCase("lighter")) { + } else*/ if (flagStr.equalsIgnoreCase("lighter")) { flags.allowLighter = state; } else { player.sendMessage(ChatColor.RED + "Acceptable flags: build, pvp, tnt, lighter"); @@ -410,10 +477,14 @@ && canUseRegionCommand(player, "/regiondefine")) { player.sendMessage(ChatColor.RED + "Region database failed to save: " + e.getMessage()); } - } else if (action.equalsIgnoreCase("info") - && canUseRegionCommand(player, "/regioninfo")) { + } else if (action.equalsIgnoreCase("info")) { + if (!canUseRegionCommand(player, "/regioninfo")) { + player.sendMessage(ChatColor.RED + "You don't have the /regioninfo permission."); + return; + } + if (args.length < 2) { - player.sendMessage(ChatColor.RED + "/rg info "); + player.sendMessage(ChatColor.RED + "/region info "); return; } @@ -436,10 +507,15 @@ && canUseRegionCommand(player, "/regioninfo")) { player.sendMessage(ChatColor.BLUE + "Lighter: " + flags.allowLighter.name()); player.sendMessage(ChatColor.LIGHT_PURPLE + "Players: " + domain.toPlayersString()); player.sendMessage(ChatColor.LIGHT_PURPLE + "Groups: " + domain.toGroupsString()); - } else if (action.equalsIgnoreCase("add") - && canUseRegionCommand(player, "/regiondefine")) { + } else if (action.equalsIgnoreCase("addowner")) { + if (!canUseRegionCommand(player, "/regiondefine") + && !canUseRegionCommand(player, "/regionclaim")) { + player.sendMessage(ChatColor.RED + "You don't have the /regiondefine permission."); + return; + } + if (args.length < 2) { - player.sendMessage(ChatColor.RED + "/rg add "); + player.sendMessage(ChatColor.RED + "/region addowner "); return; } @@ -451,7 +527,15 @@ && canUseRegionCommand(player, "/regiondefine")) { return; } - addToDomain(plugin.regionManager.getRegion(id).getOwners(), args, 1); + ProtectedRegion existing = plugin.regionManager.getRegion(id); + + if (!canUseRegionCommand(player, "/regiondefine") + && !existing.getOwners().contains(plugin.wrapPlayer(player))) { + player.sendMessage(ChatColor.RED + "You don't own this region."); + return; + } + + addToDomain(existing.getOwners(), args, 2); plugin.regionLoader.save(plugin.regionManager); player.sendMessage(ChatColor.YELLOW + "Region updated!"); @@ -459,10 +543,15 @@ && canUseRegionCommand(player, "/regiondefine")) { player.sendMessage(ChatColor.RED + "Region database failed to save: " + e.getMessage()); } - } else if (action.equalsIgnoreCase("remove") - && canUseRegionCommand(player, "/regiondefine")) { + } else if (action.equalsIgnoreCase("removeowner")) { + if (!canUseRegionCommand(player, "/regiondefine") + && !canUseRegionCommand(player, "/regionclaim")) { + player.sendMessage(ChatColor.RED + "You don't have the /regiondefine permission."); + return; + } + if (args.length < 2) { - player.sendMessage(ChatColor.RED + "/rg remove "); + player.sendMessage(ChatColor.RED + "/region removeowner "); return; } @@ -474,7 +563,15 @@ && canUseRegionCommand(player, "/regiondefine")) { return; } - removeFromDomain(plugin.regionManager.getRegion(id).getOwners(), args, 1); + ProtectedRegion existing = plugin.regionManager.getRegion(id); + + if (!canUseRegionCommand(player, "/regiondefine") + && !existing.getOwners().contains(plugin.wrapPlayer(player))) { + player.sendMessage(ChatColor.RED + "You don't own this region."); + return; + } + + removeFromDomain(existing.getOwners(), args, 2); plugin.regionLoader.save(plugin.regionManager); player.sendMessage(ChatColor.YELLOW + "Region updated!"); @@ -482,8 +579,12 @@ && canUseRegionCommand(player, "/regiondefine")) { player.sendMessage(ChatColor.RED + "Region database failed to save: " + e.getMessage()); } - } else if (action.equalsIgnoreCase("list") - && canUseRegionCommand(player, "/regionlist")) { + } else if (action.equalsIgnoreCase("list")) { + if (!canUseRegionCommand(player, "/regiondefine")) { + player.sendMessage(ChatColor.RED + "You don't have the /regiondefine permission."); + return; + } + int page = 0; if (args.length >= 2) { @@ -516,10 +617,15 @@ && canUseRegionCommand(player, "/regionlist")) { player.sendMessage(ChatColor.YELLOW.toString() + (i + 1) + ". " + regionIDList[i]); } } - } else if (action.equalsIgnoreCase("delete") - && canUseRegionCommand(player, "/regiondelete")) { + } else if (action.equalsIgnoreCase("delete")) { + if (!canUseRegionCommand(player, "/regiondelete") + && !canUseRegionCommand(player, "/regionclaim")) { + player.sendMessage(ChatColor.RED + "You don't have the /regiondelete permission."); + return; + } + if (args.length < 2) { - player.sendMessage(ChatColor.RED + "/rg delete "); + player.sendMessage(ChatColor.RED + "/region delete "); return; } @@ -530,6 +636,15 @@ && canUseRegionCommand(player, "/regiondelete")) { + id + "' doesn't exist."); return; } + + ProtectedRegion existing = plugin.regionManager.getRegion(id); + + if (!canUseRegionCommand(player, "/regiondelete") + && !existing.getOwners().contains(plugin.wrapPlayer(player))) { + player.sendMessage(ChatColor.RED + "You don't own this region."); + return; + } + plugin.regionManager.removeRegion(id); plugin.regionLoader.save(plugin.regionManager); player.sendMessage(ChatColor.YELLOW + "Region removed!"); @@ -537,8 +652,12 @@ && canUseRegionCommand(player, "/regiondelete")) { player.sendMessage(ChatColor.RED + "Region database failed to save: " + e.getMessage()); } - } else if (action.equalsIgnoreCase("save") - && canUseRegionCommand(player, "/regionsave")) { + } else if (action.equalsIgnoreCase("save")) { + if (!canUseRegionCommand(player, "/regionsave")) { + player.sendMessage(ChatColor.RED + "You don't have the /regionsave permission."); + return; + } + try { plugin.regionLoader.save(plugin.regionManager); player.sendMessage(ChatColor.YELLOW + "Region database saved to file!"); @@ -546,8 +665,12 @@ && canUseRegionCommand(player, "/regionsave")) { player.sendMessage(ChatColor.RED + "Region database failed to save: " + e.getMessage()); } - } else if (action.equalsIgnoreCase("load") - && canUseRegionCommand(player, "/regionload")) { + } else if (action.equalsIgnoreCase("load")) { + if (!canUseRegionCommand(player, "/regiondelete")) { + player.sendMessage(ChatColor.RED + "You don't have the /regiondelete permission."); + return; + } + try { plugin.regionLoader.load(plugin.regionManager); player.sendMessage(ChatColor.YELLOW + "Region database loaded from file!"); @@ -556,7 +679,7 @@ && canUseRegionCommand(player, "/regionload")) { + e.getMessage()); } } else { - player.sendMessage(ChatColor.RED + "/rg ..."); + player.sendMessage(ChatColor.RED + "/region ..."); } } diff --git a/src/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java b/src/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java index 62df5df1..120da0ac 100644 --- a/src/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java +++ b/src/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java @@ -285,7 +285,7 @@ boolean inGroup(Player player, String group) { } boolean hasPermission(Player player, String perm) { - return !perm.equals("/regionbypass"); + return perm.equals("/regionclaim"); } List getGroups(Player player) { diff --git a/src/com/sk89q/worldguard/protection/FlatRegionManager.java b/src/com/sk89q/worldguard/protection/FlatRegionManager.java index c202d2db..44bb050b 100644 --- a/src/com/sk89q/worldguard/protection/FlatRegionManager.java +++ b/src/com/sk89q/worldguard/protection/FlatRegionManager.java @@ -24,6 +24,7 @@ import java.util.Map; import java.util.LinkedHashMap; import com.sk89q.worldedit.Vector; +import com.sk89q.worldguard.LocalPlayer; /** * A very simple implementation of the region manager that uses a flat list @@ -129,6 +130,32 @@ public List getApplicableRegionsIDs(Vector pt) { return applicable; } + /** + * Returns true if the provided region overlaps with any other region that + * is not owned by the player. + * + * @param region + * @param player + * @return + */ + public boolean overlapsUnownedRegion(ProtectedRegion region, LocalPlayer player) { + for (ProtectedRegion other : regions.values()) { + if (other.getOwners().contains(player)) { + continue; + } + + try { + if (ProtectedRegion.intersects(region, other)) { + return true; + } + } catch (UnsupportedIntersectionException e) { + // TODO: Maybe do something here + } + } + + return false; + } + /** * Get the number of regions. * diff --git a/src/com/sk89q/worldguard/protection/ProtectedRegion.java b/src/com/sk89q/worldguard/protection/ProtectedRegion.java index 5dea89d9..c63a91e6 100644 --- a/src/com/sk89q/worldguard/protection/ProtectedRegion.java +++ b/src/com/sk89q/worldguard/protection/ProtectedRegion.java @@ -19,6 +19,7 @@ package com.sk89q.worldguard.protection; +import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.Vector; import com.sk89q.worldguard.domains.DefaultDomain; @@ -125,4 +126,34 @@ public AreaFlags getFlags() { * @return */ public abstract boolean contains(Vector pt); + + /** + * Checks if two region intersects. + * + * @param region1 + * @param region2 + * @throws UnsupportedIntersectionException + * @return + */ + public static boolean intersects(ProtectedRegion region1, ProtectedRegion region2) + throws UnsupportedIntersectionException { + if (region1 instanceof ProtectedCuboidRegion + && region2 instanceof ProtectedCuboidRegion) { + ProtectedCuboidRegion r1 = (ProtectedCuboidRegion)region1; + ProtectedCuboidRegion r2 = (ProtectedCuboidRegion)region2; + BlockVector min1 = r1.getMinimumPoint(); + BlockVector max1 = r1.getMinimumPoint(); + BlockVector min2 = r2.getMinimumPoint(); + BlockVector max2 = r2.getMinimumPoint(); + + return !(min1.getBlockX() > max2.getBlockX() + || min1.getBlockY() > max2.getBlockY() + || min1.getBlockZ() > max2.getBlockZ() + || max1.getBlockX() < min2.getBlockX() + || max1.getBlockY() < min2.getBlockY() + || max1.getBlockZ() < min2.getBlockZ()); + } else { + throw new UnsupportedIntersectionException(); + } + } } diff --git a/src/com/sk89q/worldguard/protection/RegionManager.java b/src/com/sk89q/worldguard/protection/RegionManager.java index 74aa8127..95bd82c9 100644 --- a/src/com/sk89q/worldguard/protection/RegionManager.java +++ b/src/com/sk89q/worldguard/protection/RegionManager.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.Map; import com.sk89q.worldedit.Vector; +import com.sk89q.worldguard.LocalPlayer; /** * An interface for getting, setting, and looking up regions. The most @@ -92,6 +93,16 @@ public interface RegionManager { */ public List getApplicableRegionsIDs(Vector pt); + /** + * Returns true if the provided region overlaps with any other region that + * is not owned by the player. + * + * @param region + * @param player + * @return + */ + public boolean overlapsUnownedRegion(ProtectedRegion region, LocalPlayer player); + /** * Get the number of regions. * diff --git a/src/com/sk89q/worldguard/protection/UnsupportedIntersectionException.java b/src/com/sk89q/worldguard/protection/UnsupportedIntersectionException.java new file mode 100644 index 00000000..033c9752 --- /dev/null +++ b/src/com/sk89q/worldguard/protection/UnsupportedIntersectionException.java @@ -0,0 +1,24 @@ +// $Id$ +/* + * WorldGuard + * 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 . +*/ + +package com.sk89q.worldguard.protection; + +public class UnsupportedIntersectionException extends Exception { + private static final long serialVersionUID = 6423189392345575148L; +}