Moved commands handling to be Bukkit-compliant.

This commit is contained in:
sk89q 2011-01-19 23:27:35 -08:00
parent 627de1aebd
commit 7e481e6a9a
3 changed files with 805 additions and 686 deletions

View File

@ -1,3 +1,24 @@
name: WorldGuard name: WorldGuard
main: com.sk89q.worldguard.bukkit.WorldGuardPlugin main: com.sk89q.worldguard.bukkit.WorldGuardPlugin
version: WGVERSIONMACRO version: WGVERSIONMACRO
commands:
stopfire:
description: Halts all fire spread until it is disabled or the server is restarted
usage: /<command>
allowfire:
description: Re-enables fire spread if he has been disabled with /stopfire
usage: /<command>
god:
description: Toggles god mode
usage: /<command> [other player]
stack:
description: Stacks items in the player's inventory
usage: /<command>
aliases: ;
region:
description: Adjust protected regions
usage: /<command> <define|claim|flag|delete|info|addowner|removeowner|list|save|load> ...
aliases: rg, regions
reloadwg:
description: Reload WorldGuard's configuration
usage: /<command>

View File

@ -19,31 +19,16 @@
package com.sk89q.worldguard.bukkit; package com.sk89q.worldguard.bukkit;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.player.*; import org.bukkit.event.player.*;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.blocks.ItemType;
import com.sk89q.worldedit.bukkit.WorldEditAPI;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.*; import com.sk89q.worldguard.*;
import com.sk89q.worldguard.blacklist.events.ItemUseBlacklistEvent; import com.sk89q.worldguard.blacklist.events.ItemUseBlacklistEvent;
import com.sk89q.worldguard.domains.*;
import com.sk89q.worldguard.protection.*;
import static com.sk89q.worldguard.bukkit.BukkitUtil.*; import static com.sk89q.worldguard.bukkit.BukkitUtil.*;
/** /**
@ -54,12 +39,6 @@ public class WorldGuardPlayerListener extends PlayerListener {
* Plugin. * Plugin.
*/ */
private WorldGuardPlugin plugin; private WorldGuardPlugin plugin;
/**
* Group pattern used to specify groups for the region command.
*/
private static Pattern groupPattern = Pattern.compile("^[gG]:(.+)$");
private static int CMD_LIST_SIZE = 9;
/** /**
* Construct the object; * Construct the object;
@ -162,665 +141,4 @@ public void onPlayerLogin(PlayerLoginEvent event) {
} }
} }
} }
/**
* Called when a player attempts to use a command
*
* @param event Relevant event details
*/
@Override
public void onPlayerCommand(PlayerChatEvent event) {
if (handleCommand(event)) {
event.setCancelled(true);
}
}
/**
* Called when a player attempts to use a command
*
* @param event Relevant event details
*/
public boolean handleCommand(PlayerChatEvent event) {
Player player = event.getPlayer();
String[] split = event.getMessage().split(" ");
if (split[0].equalsIgnoreCase("/stopfire") &&
plugin.hasPermission(player, "/stopfire")) {
if (!plugin.fireSpreadDisableToggle) {
plugin.getServer().broadcastMessage(ChatColor.YELLOW
+ "Fire spread has been globally disabled by " + player.getName() + ".");
} else {
player.sendMessage(ChatColor.YELLOW + "Fire spread was already globally disabled.");
}
plugin.fireSpreadDisableToggle = true;
} else if (split[0].equalsIgnoreCase("/allowfire")
&& plugin.hasPermission(player, "/stopfire")) {
if (plugin.fireSpreadDisableToggle) {
plugin.getServer().broadcastMessage(ChatColor.YELLOW
+ "Fire spread has been globally re-enabled by " + player.getName() + ".");
} else {
player.sendMessage(ChatColor.YELLOW + "Fire spread was already globally enabled.");
}
plugin.fireSpreadDisableToggle = false;
} else if (split[0].equalsIgnoreCase("/god")
&& plugin.hasPermission(player, "/god")) {
// Allow setting other people invincible
if (split.length > 1) {
if (!plugin.hasPermission(player, "/godother")) {
player.sendMessage(ChatColor.RED + "You don't have permission to make others invincible.");
return true;
}
Player other = matchSinglePlayer(plugin.getServer(), split[1]);
if (other == null) {
player.sendMessage(ChatColor.RED + "Player not found.");
} else {
if (!plugin.invinciblePlayers.contains(other.getName())) {
plugin.invinciblePlayers.add(other.getName());
player.sendMessage(ChatColor.YELLOW + other.getName() + " is now invincible!");
other.sendMessage(ChatColor.YELLOW + player.getName() + " has made you invincible!");
} else {
plugin.invinciblePlayers.remove(other.getName());
player.sendMessage(ChatColor.YELLOW + other.getName() + " is no longer invincible.");
other.sendMessage(ChatColor.YELLOW + player.getName() + " has taken away your invincibility.");
}
}
// Invincibility for one's self
} else {
if (!plugin.invinciblePlayers.contains(player.getName())) {
plugin.invinciblePlayers.add(player.getName());
player.sendMessage(ChatColor.YELLOW + "You are now invincible!");
} else {
plugin.invinciblePlayers.remove(player.getName());
player.sendMessage(ChatColor.YELLOW + "You are no longer invincible.");
}
}
} else if ((split[0].equalsIgnoreCase("/stack")
|| split[0].equalsIgnoreCase("/;"))
&& plugin.hasPermission(player, "/stack")) {
ItemStack[] items = player.getInventory().getContents();
int len = items.length;
int affected = 0;
for (int i = 0; i < len; i++) {
ItemStack item = items[i];
// Avoid infinite stacks and stacks with durability
if (item == null || item.getAmount() <= 0
|| ItemType.shouldNotStack(item.getTypeId())) {
continue;
}
// Ignore buckets
if (item.getTypeId() >= 325 && item.getTypeId() <= 327) {
continue;
}
if (item.getAmount() < 64) {
int needed = 64 - item.getAmount(); // Number of needed items until 64
// Find another stack of the same type
for (int j = i + 1; j < len; j++) {
ItemStack item2 = items[j];
// Avoid infinite stacks and stacks with durability
if (item2 == null || item2.getAmount() <= 0
|| ItemType.shouldNotStack(item.getTypeId())) {
continue;
}
// Same type?
// Blocks store their color in the damage value
if (item2.getTypeId() == item.getTypeId() &&
(!ItemType.usesDamageValue(item.getTypeId())
|| item.getDamage() == item2.getDamage())) {
// This stack won't fit in the parent stack
if (item2.getAmount() > needed) {
item.setAmount(64);
item2.setAmount(item2.getAmount() - needed);
break;
// This stack will
} else {
items[j] = null;
item.setAmount(item.getAmount() + item2.getAmount());
needed = 64 - item.getAmount();
}
affected++;
}
}
}
}
if (affected > 0) {
player.getInventory().setContents(items);
}
player.sendMessage(ChatColor.YELLOW + "Items compacted into stacks!");
} else if (split[0].equalsIgnoreCase("/rg")
|| split[0].equalsIgnoreCase("/region")) {
if (split.length < 2) {
player.sendMessage(ChatColor.RED + "/region <define|claim|flag|delete|info|add|remove|list|save|load> ...");
return true;
}
String action = split[1];
String[] args = new String[split.length - 1];
System.arraycopy(split, 1, args, 0, split.length - 1);
handleRegionCommand(player, action, args);
} else if (split[0].equalsIgnoreCase("/reload")
&& plugin.hasPermission(player, "/reload")
&& split.length > 1) {
if (split[1].equalsIgnoreCase("WorldGuard")) {
LoggerToChatHandler handler = new LoggerToChatHandler(player);
handler.setLevel(Level.ALL);
Logger minecraftLogger = Logger.getLogger("Minecraft");
minecraftLogger.addHandler(handler);
try {
plugin.loadConfiguration();
plugin.postReload();
player.sendMessage("WorldGuard configuration reloaded.");
} catch (Throwable t) {
player.sendMessage("Error while reloading: "
+ t.getMessage());
} finally {
minecraftLogger.removeHandler(handler);
}
return true;
}
} else {
return false;
}
return true;
}
/**
* Handles a region command.
*
* @param player
* @param action
* @param args
*/
private void handleRegionCommand(Player player, String action, String[] args) {
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 + "/region define <id> [owner1 [owner2 [owners...]]]");
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;
}
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 (args.length >= 3) {
region.setOwners(parseDomainString(args, 2));
}
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("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 <id>");
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;
}
region.getOwners().addPlayer(player.getName());
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 + "/region flag <id> <flag> <none|allow|deny>");
return;
}
try {
String id = args[1].toLowerCase();
String flagStr = args[2];
String stateStr = args[3];
ProtectedRegion region = plugin.regionManager.getRegion(id);
if (region == null) {
player.sendMessage(ChatColor.RED + "Could not find a region by that ID.");
return;
}
AreaFlags.State state = null;
if (stateStr.equalsIgnoreCase("allow")) {
state = AreaFlags.State.ALLOW;
} else if (stateStr.equalsIgnoreCase("deny")) {
state = AreaFlags.State.DENY;
} else if (stateStr.equalsIgnoreCase("none")) {
state = AreaFlags.State.NONE;
} else {
player.sendMessage(ChatColor.RED + "Acceptable states: allow, deny, none");
return;
}
AreaFlags flags = region.getFlags();
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")) {
flags.allowLighter = state;
} else {
player.sendMessage(ChatColor.RED + "Acceptable flags: build, pvp, tnt, lighter");
return;
}
plugin.regionLoader.save(plugin.regionManager);
player.sendMessage(ChatColor.YELLOW + "Region '" + id + "' updated.");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
/*} else if (action.equalsIgnoreCase("priority")) {
if (!canUseRegionCommand(player, "/regiondefine")) {
player.sendMessage(ChatColor.RED + "You don't have the /regiondefine permission.");
return;
}
if (args.length < 3) {
player.sendMessage(ChatColor.RED + "/region priority <id> <priority>");
return;
}
try {
String id = args[1].toLowerCase();
int priority = 0;
try {
priority = Integer.parseInt(args[2]);
} catch (NumberFormatException e) {
player.sendMessage(ChatColor.RED + "The priority must be a number.");
return;
}
ProtectedRegion region = plugin.regionManager.getRegion(id);
if (region == null) {
player.sendMessage(ChatColor.RED + "Could not find a region by that ID.");
return;
}
region.setPriority(priority);
plugin.regionLoader.save(plugin.regionManager);
player.sendMessage(ChatColor.YELLOW + "Region '" + id + "' updated.");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}*/
} 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 + "/region info <id>");
return;
}
String id = args[1].toLowerCase();
if (!plugin.regionManager.hasRegion(id)) {
player.sendMessage(ChatColor.RED + "A region with ID '"
+ id + "' doesn't exist.");
return;
}
ProtectedRegion region = plugin.regionManager.getRegion(id);
AreaFlags flags = region.getFlags();
DefaultDomain domain = region.getOwners();
player.sendMessage(ChatColor.YELLOW + "Region ID: " + id);
player.sendMessage(ChatColor.GRAY + "Type: " + region.getClass().getCanonicalName());
player.sendMessage(ChatColor.GRAY + "Priority: " + region.getPriority());
player.sendMessage(ChatColor.BLUE + "Build: " + flags.allowBuild.name());
player.sendMessage(ChatColor.BLUE + "PvP: " + flags.allowPvP.name());
player.sendMessage(ChatColor.BLUE + "TNT: " + flags.allowTNT.name());
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("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 + "/region addowner <id>");
return;
}
try {
String id = args[1].toLowerCase();
if (!plugin.regionManager.hasRegion(id)) {
player.sendMessage(ChatColor.RED + "A region with ID '"
+ id + "' doesn't exist.");
return;
}
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!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
} 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 + "/region removeowner <id>");
return;
}
try {
String id = args[1].toLowerCase();
if (!plugin.regionManager.hasRegion(id)) {
player.sendMessage(ChatColor.RED + "A region with ID '"
+ id + "' doesn't exist.");
return;
}
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!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
} 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) {
try {
page = Math.max(0, Integer.parseInt(args[1]) - 1);
} catch (NumberFormatException e) {
page = 0;
}
}
Map<String,ProtectedRegion> regions = plugin.regionManager.getRegions();
int size = regions.size();
int pages = (int)Math.ceil(size / (float)CMD_LIST_SIZE);
String[] regionIDList = new String[size];
int index = 0;
for (String id : regions.keySet()) {
regionIDList[index] = id;
index++;
}
Arrays.sort(regionIDList);
player.sendMessage(ChatColor.RED + "Regions (page "
+ (page + 1) + " of " + pages + "):");
if (page < pages) {
for (int i = page * CMD_LIST_SIZE; i < page * CMD_LIST_SIZE + CMD_LIST_SIZE; i++) {
if (i >= size) break;
player.sendMessage(ChatColor.YELLOW.toString() + (i + 1) + ". " + regionIDList[i]);
}
}
} 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 + "/region delete <id>");
return;
}
try {
String id = args[1].toLowerCase();
if (!plugin.regionManager.hasRegion(id)) {
player.sendMessage(ChatColor.RED + "A region with ID '"
+ 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!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
} 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!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
} else if (action.equalsIgnoreCase("load")) {
if (!canUseRegionCommand(player, "/regionload")) {
player.sendMessage(ChatColor.RED + "You don't have the /regionload permission.");
return;
}
try {
plugin.regionLoader.load(plugin.regionManager);
player.sendMessage(ChatColor.YELLOW + "Region database loaded from file!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to load: "
+ e.getMessage());
}
} else {
player.sendMessage(ChatColor.RED + "/region <define|claim|flag|delete|info|addowner|removeowner|list|save|load> ...");
}
}
/**
* Checks for the command or /region.
*
* @param player
* @param cmd
* @return
*/
private boolean canUseRegionCommand(Player player, String cmd) {
return plugin.hasPermission(player, "/region")
|| plugin.hasPermission(player, cmd);
}
/**
* Parse a group/player DefaultDomain specification for areas.
*
* @param domain
* @param split
* @param startIndex
*/
private static void addToDomain(DefaultDomain domain,
String[] split, int startIndex) {
for (int i = startIndex; i < split.length; i++) {
String s = split[i];
Matcher m = groupPattern.matcher(s);
if (m.matches()) {
domain.addGroup(m.group(1));
} else {
domain.addPlayer(s);
}
}
}
/**
* Parse a group/player DefaultDomain specification for areas.
*
* @param domain
* @param split
* @param startIndex
*/
private static void removeFromDomain(DefaultDomain domain,
String[] split, int startIndex) {
for (int i = startIndex; i < split.length; i++) {
String s = split[i];
Matcher m = groupPattern.matcher(s);
if (m.matches()) {
domain.removeGroup(m.group(1));
} else {
domain.removePlayer(s);
}
}
}
/**
* Parse a group/player DefaultDomain specification for areas.
*
* @param split
* @param startIndex
* @return
*/
private static DefaultDomain parseDomainString(String[] split, int startIndex) {
DefaultDomain domain = new DefaultDomain();
for (int i = startIndex; i < split.length; i++) {
String s = split[i];
Matcher m = groupPattern.matcher(s);
if (m.matches()) {
domain.addGroup(m.group(1));
} else {
domain.addPlayer(s);
}
}
return domain;
}
} }

View File

@ -19,29 +19,46 @@
package com.sk89q.worldguard.bukkit; package com.sk89q.worldguard.bukkit;
import static com.sk89q.worldguard.bukkit.BukkitUtil.matchSinglePlayer;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.command.Command;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.ChatColor;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.event.Event.Priority; import org.bukkit.event.Event.Priority;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginLoader; import org.bukkit.plugin.PluginLoader;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.config.Configuration; import org.bukkit.util.config.Configuration;
import com.sk89q.bukkit.migration.PermissionsResolverManager; import com.sk89q.bukkit.migration.PermissionsResolverManager;
import com.sk89q.bukkit.migration.PermissionsResolverServerListener; import com.sk89q.bukkit.migration.PermissionsResolverServerListener;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.blocks.ItemType;
import com.sk89q.worldedit.bukkit.WorldEditAPI;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldguard.blacklist.Blacklist; import com.sk89q.worldguard.blacklist.Blacklist;
import com.sk89q.worldguard.blacklist.BlacklistLogger; import com.sk89q.worldguard.blacklist.BlacklistLogger;
import com.sk89q.worldguard.blacklist.loggers.*; import com.sk89q.worldguard.blacklist.loggers.*;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.*; import com.sk89q.worldguard.protection.*;
/** /**
@ -52,6 +69,9 @@
public class WorldGuardPlugin extends JavaPlugin { public class WorldGuardPlugin extends JavaPlugin {
private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard"); private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
private static Pattern groupPattern = Pattern.compile("^[gG]:(.+)$");
private static int CMD_LIST_SIZE = 9;
private final WorldGuardPlayerListener playerListener = private final WorldGuardPlayerListener playerListener =
new WorldGuardPlayerListener(this); new WorldGuardPlayerListener(this);
private final WorldGuardBlockListener blockListener = private final WorldGuardBlockListener blockListener =
@ -112,6 +132,16 @@ public class WorldGuardPlugin extends JavaPlugin {
boolean useRegions; boolean useRegions;
int regionWand = 287; int regionWand = 287;
/**
* Construct the plugin.
*
* @param pluginLoader
* @param instance
* @param desc
* @param folder
* @param plugin
* @param cLoader
*/
public WorldGuardPlugin(PluginLoader pluginLoader, Server instance, public WorldGuardPlugin(PluginLoader pluginLoader, Server instance,
PluginDescriptionFile desc, File folder, File plugin, ClassLoader cLoader) { PluginDescriptionFile desc, File folder, File plugin, ClassLoader cLoader) {
super(pluginLoader, instance, desc, folder, plugin, cLoader); super(pluginLoader, instance, desc, folder, plugin, cLoader);
@ -132,12 +162,21 @@ public WorldGuardPlugin(PluginLoader pluginLoader, Server instance,
registerEvents(); registerEvents();
} }
/**
* Called on plugin enable.
*/
public void onEnable() { public void onEnable() {
} }
/**
* Called on plugin disable.
*/
public void onDisable() { public void onDisable() {
} }
/**
* Register used events.
*/
private void registerEvents() { private void registerEvents() {
registerEvent(Event.Type.BLOCK_DAMAGED, blockListener, Priority.Normal); registerEvent(Event.Type.BLOCK_DAMAGED, blockListener, Priority.Normal);
registerEvent(Event.Type.BLOCK_FLOW, blockListener, Priority.Normal); registerEvent(Event.Type.BLOCK_FLOW, blockListener, Priority.Normal);
@ -151,7 +190,6 @@ private void registerEvents() {
registerEvent(Event.Type.ENTITY_DAMAGEDBY_ENTITY, entityListener, Priority.Normal); registerEvent(Event.Type.ENTITY_DAMAGEDBY_ENTITY, entityListener, Priority.Normal);
registerEvent(Event.Type.ENTITY_EXPLODE, entityListener, Priority.Normal); registerEvent(Event.Type.ENTITY_EXPLODE, entityListener, Priority.Normal);
registerEvent(Event.Type.PLAYER_COMMAND, playerListener, Priority.Normal);
registerEvent(Event.Type.PLAYER_ITEM, playerListener, Priority.Normal); registerEvent(Event.Type.PLAYER_ITEM, playerListener, Priority.Normal);
registerEvent(Event.Type.PLAYER_JOIN, playerListener, Priority.Normal); registerEvent(Event.Type.PLAYER_JOIN, playerListener, Priority.Normal);
registerEvent(Event.Type.PLAYER_LOGIN, playerListener, Priority.Normal); registerEvent(Event.Type.PLAYER_LOGIN, playerListener, Priority.Normal);
@ -160,10 +198,22 @@ private void registerEvents() {
permsListener.register(this); permsListener.register(this);
} }
/**
* Register an event.
*
* @param type
* @param listener
* @param priority
*/
private void registerEvent(Event.Type type, Listener listener, Priority priority) { private void registerEvent(Event.Type type, Listener listener, Priority priority) {
getServer().getPluginManager().registerEvent(type, listener, priority, this); getServer().getPluginManager().registerEvent(type, listener, priority, this);
} }
/**
* Create a default configuration file from the .jar.
*
* @param name
*/
private void createDefaultConfiguration(String name) { private void createDefaultConfiguration(String name) {
File actual = new File(getDataFolder(), name); File actual = new File(getDataFolder(), name);
if (!actual.exists()) { if (!actual.exists()) {
@ -201,7 +251,7 @@ private void createDefaultConfiguration(String name) {
} }
/** /**
* Load the configuration * Load the configuration.
*/ */
public void loadConfiguration() { public void loadConfiguration() {
Configuration config = getConfiguration(); Configuration config = getConfiguration();
@ -358,13 +408,712 @@ public void postReload() {
} catch (NullPointerException e) { // Thrown if loaded too early } catch (NullPointerException e) { // Thrown if loaded too early
} }
} }
/**
* Handles a command.
*/
public boolean onCommand(Player player, Command cmd, String commandLabel, String[] args) {
try {
return handleCommand(player, cmd.getName(), args);
} catch (InsufficientArgumentsException e) {
if (e.getHelp() != null) {
player.sendMessage(ChatColor.RED + e.getHelp());
return true;
} else {
return false;
}
} catch (InsufficientPermissionsException e) {
player.sendMessage(ChatColor.RED + "You don't have sufficient permission.");
return true;
}
}
/**
* Internal method to handle a command.
*
* @param player
* @param cmd
* @param args
* @return
* @throws InsufficientArgumentsException
* @throws InsufficientPermissionsException
*/
private boolean handleCommand(Player player, String cmd, String[] args)
throws InsufficientArgumentsException, InsufficientPermissionsException {
if (cmd.equalsIgnoreCase("stopfire")) {
checkPermission(player, "/stopfire");
checkArgs(args, 0, 0);
if (!fireSpreadDisableToggle) {
getServer().broadcastMessage(ChatColor.YELLOW
+ "Fire spread has been globally disabled by " + player.getName() + ".");
} else {
player.sendMessage(ChatColor.YELLOW + "Fire spread was already globally disabled.");
}
fireSpreadDisableToggle = true;
return true;
}
if (cmd.equalsIgnoreCase("allowfire")) {
checkPermission(player, "/stopfire");
checkArgs(args, 0, 0);
if (fireSpreadDisableToggle) {
getServer().broadcastMessage(ChatColor.YELLOW
+ "Fire spread has been globally re-enabled by " + player.getName() + ".");
} else {
player.sendMessage(ChatColor.YELLOW + "Fire spread was already globally enabled.");
}
fireSpreadDisableToggle = false;
return true;
}
if (cmd.equalsIgnoreCase("god")) {
checkPermission(player, "/god");
checkArgs(args, 0, 1);
// Allow setting other people invincible
if (args.length > 1) {
if (!hasPermission(player, "/godother")) {
player.sendMessage(ChatColor.RED + "You don't have permission to make others invincible.");
return true;
}
Player other = matchSinglePlayer(getServer(), args[1]);
if (other == null) {
player.sendMessage(ChatColor.RED + "Player not found.");
} else {
if (!invinciblePlayers.contains(other.getName())) {
invinciblePlayers.add(other.getName());
player.sendMessage(ChatColor.YELLOW + other.getName() + " is now invincible!");
other.sendMessage(ChatColor.YELLOW + player.getName() + " has made you invincible!");
} else {
invinciblePlayers.remove(other.getName());
player.sendMessage(ChatColor.YELLOW + other.getName() + " is no longer invincible.");
other.sendMessage(ChatColor.YELLOW + player.getName() + " has taken away your invincibility.");
}
}
// Invincibility for one's self
} else {
if (!invinciblePlayers.contains(player.getName())) {
invinciblePlayers.add(player.getName());
player.sendMessage(ChatColor.YELLOW + "You are now invincible!");
} else {
invinciblePlayers.remove(player.getName());
player.sendMessage(ChatColor.YELLOW + "You are no longer invincible.");
}
}
return true;
}
if (cmd.equalsIgnoreCase("stack")) {
checkPermission(player, "stack");
checkArgs(args, 0, 0);
ItemStack[] items = player.getInventory().getContents();
int len = items.length;
int affected = 0;
for (int i = 0; i < len; i++) {
ItemStack item = items[i];
// Avoid infinite stacks and stacks with durability
if (item == null || item.getAmount() <= 0
|| ItemType.shouldNotStack(item.getTypeId())) {
continue;
}
// Ignore buckets
if (item.getTypeId() >= 325 && item.getTypeId() <= 327) {
continue;
}
if (item.getAmount() < 64) {
int needed = 64 - item.getAmount(); // Number of needed items until 64
// Find another stack of the same type
for (int j = i + 1; j < len; j++) {
ItemStack item2 = items[j];
// Avoid infinite stacks and stacks with durability
if (item2 == null || item2.getAmount() <= 0
|| ItemType.shouldNotStack(item.getTypeId())) {
continue;
}
// Same type?
// Blocks store their color in the damage value
if (item2.getTypeId() == item.getTypeId() &&
(!ItemType.usesDamageValue(item.getTypeId())
|| item.getDamage() == item2.getDamage())) {
// This stack won't fit in the parent stack
if (item2.getAmount() > needed) {
item.setAmount(64);
item2.setAmount(item2.getAmount() - needed);
break;
// This stack will
} else {
items[j] = null;
item.setAmount(item.getAmount() + item2.getAmount());
needed = 64 - item.getAmount();
}
affected++;
}
}
}
}
if (affected > 0) {
player.getInventory().setContents(items);
}
player.sendMessage(ChatColor.YELLOW + "Items compacted into stacks!");
return true;
}
if (cmd.equalsIgnoreCase("region")) {
checkArgs(args, 1, -1);
String action = args[1];
String[] subArgs = new String[args.length - 1];
System.arraycopy(args, 1, subArgs, 0, args.length - 1);
return handleRegionCommand(player, action, subArgs);
}
if (cmd.equalsIgnoreCase("reloadwg")) {
checkPermission(player, "reloadwg");
checkArgs(args, 0, 0);
LoggerToChatHandler handler = new LoggerToChatHandler(player);
handler.setLevel(Level.ALL);
Logger minecraftLogger = Logger.getLogger("Minecraft");
minecraftLogger.addHandler(handler);
try {
loadConfiguration();
postReload();
player.sendMessage("WorldGuard configuration reloaded.");
} catch (Throwable t) {
player.sendMessage("Error while reloading: "
+ t.getMessage());
} finally {
minecraftLogger.removeHandler(handler);
}
return true;
}
return false;
}
/**
* Handles a region command.
*
* @param player
* @param action
* @param args
* @throws InsufficientPermissionsException
* @throws InsufficientArgumentsException
*/
private boolean handleRegionCommand(Player player, String action, String[] args)
throws InsufficientPermissionsException, InsufficientArgumentsException {
if (!useRegions) {
player.sendMessage(ChatColor.RED + "Regions are disabled.");
return true;
}
Plugin wePlugin = getServer().getPluginManager().getPlugin("WorldEdit");
if (wePlugin == null) {
player.sendMessage(ChatColor.RED + "WorldEdit must be installed and enabled!");
return true;
}
if (action.equalsIgnoreCase("define")) {
checkRegionPermission(player, "/regiondefine");
checkArgs(args, 1, -1, "/region define <id> [owner1 [owner2 [owners...]]]");
try {
String id = args[1].toLowerCase();
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 (args.length >= 2) {
region.setOwners(parseDomainString(args, 2));
}
regionManager.addRegion(id, region);
regionLoader.save(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());
}
return true;
}
if (action.equalsIgnoreCase("claim")) {
checkRegionPermission(player, "/regionclaim");
checkArgs(args, 1, 1, "/region claim <id>");
try {
String id = args[1].toLowerCase();
ProtectedRegion existing = regionManager.getRegion(id);
if (existing != null) {
if (!existing.getOwners().contains(wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "You don't own this region.");
return true;
}
}
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 (regionManager.overlapsUnownedRegion(region, wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "This region overlaps with someone else's region.");
return true;
}
region.getOwners().addPlayer(player.getName());
regionManager.addRegion(id, region);
regionLoader.save(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());
}
return true;
}
if (action.equalsIgnoreCase("flag")) {
checkRegionPermission(player, "/regiondefine");
checkArgs(args, 3, 3, "/region flag <id> <flag> <none|allow|deny>");
try {
String id = args[1].toLowerCase();
String flagStr = args[2];
String stateStr = args[3];
ProtectedRegion region = regionManager.getRegion(id);
if (region == null) {
player.sendMessage(ChatColor.RED + "Could not find a region by that ID.");
return true;
}
AreaFlags.State state = null;
if (stateStr.equalsIgnoreCase("allow")) {
state = AreaFlags.State.ALLOW;
} else if (stateStr.equalsIgnoreCase("deny")) {
state = AreaFlags.State.DENY;
} else if (stateStr.equalsIgnoreCase("none")) {
state = AreaFlags.State.NONE;
} else {
player.sendMessage(ChatColor.RED + "Acceptable states: allow, deny, none");
return true;
}
AreaFlags flags = region.getFlags();
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")) {
flags.allowLighter = state;
} else {
player.sendMessage(ChatColor.RED + "Acceptable flags: build, pvp, tnt, lighter");
return true;
}
regionLoader.save(regionManager);
player.sendMessage(ChatColor.YELLOW + "Region '" + id + "' updated.");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
return true;
}
if (action.equalsIgnoreCase("info")) {
checkRegionPermission(player, "/regioninfo");
checkArgs(args, 1, 1, "/region info <id>");
String id = args[1].toLowerCase();
if (!regionManager.hasRegion(id)) {
player.sendMessage(ChatColor.RED + "A region with ID '"
+ id + "' doesn't exist.");
return true;
}
ProtectedRegion region = regionManager.getRegion(id);
AreaFlags flags = region.getFlags();
DefaultDomain domain = region.getOwners();
player.sendMessage(ChatColor.YELLOW + "Region ID: " + id);
player.sendMessage(ChatColor.GRAY + "Type: " + region.getClass().getCanonicalName());
player.sendMessage(ChatColor.GRAY + "Priority: " + region.getPriority());
player.sendMessage(ChatColor.BLUE + "Build: " + flags.allowBuild.name());
player.sendMessage(ChatColor.BLUE + "PvP: " + flags.allowPvP.name());
player.sendMessage(ChatColor.BLUE + "TNT: " + flags.allowTNT.name());
player.sendMessage(ChatColor.BLUE + "Lighter: " + flags.allowLighter.name());
player.sendMessage(ChatColor.LIGHT_PURPLE + "Players: " + domain.toPlayersString());
player.sendMessage(ChatColor.LIGHT_PURPLE + "Groups: " + domain.toGroupsString());
return true;
}
if (action.equalsIgnoreCase("addowner")) {
if (!hasPermission(player, "/regionclaim")) {
checkRegionPermission(player, "/regiondefine");
}
checkArgs(args, 2, -1, "/region addowner <id> [owner1 [owner2 [owners...]]]");
try {
String id = args[1].toLowerCase();
if (!regionManager.hasRegion(id)) {
player.sendMessage(ChatColor.RED + "A region with ID '"
+ id + "' doesn't exist.");
return true;
}
ProtectedRegion existing = regionManager.getRegion(id);
if (!canUseRegionCommand(player, "/regiondefine")
&& !existing.getOwners().contains(wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "You don't own this region.");
return true;
}
addToDomain(existing.getOwners(), args, 2);
regionLoader.save(regionManager);
player.sendMessage(ChatColor.YELLOW + "Region updated!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
return true;
}
if (action.equalsIgnoreCase("removeowner")) {
if (!hasPermission(player, "/regionclaim")) {
checkRegionPermission(player, "/regiondefine");
}
checkArgs(args, 2, -1, "/region removeowner <id> [owner1 [owner2 [owners...]]]");
try {
String id = args[1].toLowerCase();
if (!regionManager.hasRegion(id)) {
player.sendMessage(ChatColor.RED + "A region with ID '"
+ id + "' doesn't exist.");
return true;
}
ProtectedRegion existing = regionManager.getRegion(id);
if (!canUseRegionCommand(player, "/regiondefine")
&& !existing.getOwners().contains(wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "You don't own this region.");
return true;
}
removeFromDomain(existing.getOwners(), args, 2);
regionLoader.save(regionManager);
player.sendMessage(ChatColor.YELLOW + "Region updated!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
return true;
}
if (action.equalsIgnoreCase("list")) {
checkRegionPermission(player, "/regionlist");
checkArgs(args, 0, 1, "/region list [page]");
int page = 0;
if (args.length >= 2) {
try {
page = Math.max(0, Integer.parseInt(args[1]) - 1);
} catch (NumberFormatException e) {
page = 0;
}
}
Map<String,ProtectedRegion> regions = regionManager.getRegions();
int size = regions.size();
int pages = (int)Math.ceil(size / (float)CMD_LIST_SIZE);
String[] regionIDList = new String[size];
int index = 0;
for (String id : regions.keySet()) {
regionIDList[index] = id;
index++;
}
Arrays.sort(regionIDList);
player.sendMessage(ChatColor.RED + "Regions (page "
+ (page + 1) + " of " + pages + "):");
if (page < pages) {
for (int i = page * CMD_LIST_SIZE; i < page * CMD_LIST_SIZE + CMD_LIST_SIZE; i++) {
if (i >= size) break;
player.sendMessage(ChatColor.YELLOW.toString() + (i + 1) + ". " + regionIDList[i]);
}
}
return true;
}
if (action.equalsIgnoreCase("delete")) {
if (!hasPermission(player, "/regionclaim")) {
checkRegionPermission(player, "/regiondelete");
}
checkArgs(args, 0, 1, "/region delete <id>");
try {
String id = args[1].toLowerCase();
if (!regionManager.hasRegion(id)) {
player.sendMessage(ChatColor.RED + "A region with ID '"
+ id + "' doesn't exist.");
return true;
}
ProtectedRegion existing = regionManager.getRegion(id);
if (!canUseRegionCommand(player, "/regiondelete")
&& !existing.getOwners().contains(wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "You don't own this region.");
return true;
}
regionManager.removeRegion(id);
regionLoader.save(regionManager);
player.sendMessage(ChatColor.YELLOW + "Region removed!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
return true;
}
if (action.equalsIgnoreCase("save")) {
checkRegionPermission(player, "/regionsave");
checkArgs(args, 0, 0, "/region save");
try {
regionLoader.save(regionManager);
player.sendMessage(ChatColor.YELLOW + "Region database saved to file!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
return true;
}
if (action.equalsIgnoreCase("load")) {
checkRegionPermission(player, "/regionload");
checkArgs(args, 0, 0, "/region load");
try {
regionLoader.load(regionManager);
player.sendMessage(ChatColor.YELLOW + "Region database loaded from file!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to load: "
+ e.getMessage());
}
return true;
}
return false;
}
/**
* Parse a group/player DefaultDomain specification for areas.
*
* @param domain
* @param split
* @param startIndex
*/
private static void addToDomain(DefaultDomain domain,
String[] split, int startIndex) {
for (int i = startIndex; i < split.length; i++) {
String s = split[i];
Matcher m = groupPattern.matcher(s);
if (m.matches()) {
domain.addGroup(m.group(1));
} else {
domain.addPlayer(s);
}
}
}
/**
* Parse a group/player DefaultDomain specification for areas.
*
* @param domain
* @param split
* @param startIndex
*/
private static void removeFromDomain(DefaultDomain domain,
String[] split, int startIndex) {
for (int i = startIndex; i < split.length; i++) {
String s = split[i];
Matcher m = groupPattern.matcher(s);
if (m.matches()) {
domain.removeGroup(m.group(1));
} else {
domain.removePlayer(s);
}
}
}
/**
* Parse a group/player DefaultDomain specification for areas.
*
* @param split
* @param startIndex
* @return
*/
private static DefaultDomain parseDomainString(String[] split, int startIndex) {
DefaultDomain domain = new DefaultDomain();
for (int i = startIndex; i < split.length; i++) {
String s = split[i];
Matcher m = groupPattern.matcher(s);
if (m.matches()) {
domain.addGroup(m.group(1));
} else {
domain.addPlayer(s);
}
}
return domain;
}
/**
* Checks for the command or /region.
*
* @param player
* @param cmd
* @return
*/
private boolean canUseRegionCommand(Player player, String cmd) {
return hasPermission(player, "/region")
|| hasPermission(player, cmd);
}
/**
* Checks to see if there are sufficient permissions, otherwise an exception
* is raised in that case.
*
* @param player
* @param permission
* @throws InsufficientPermissionsException
*/
private void checkRegionPermission(Player player, String permission)
throws InsufficientPermissionsException {
if (!hasPermission(player, "/region") && !hasPermission(player, permission)) {
throw new InsufficientPermissionsException();
}
}
/**
* Checks to see if there are sufficient permissions, otherwise an exception
* is raised in that case.
*
* @param player
* @param permission
* @throws InsufficientPermissionsException
*/
private void checkPermission(Player player, String permission)
throws InsufficientPermissionsException {
if (!hasPermission(player, permission)) {
throw new InsufficientPermissionsException();
}
}
/**
* Checks to make sure that there are enough but not too many arguments.
*
* @param args
* @param min
* @param max -1 for no maximum
* @throws InsufficientArgumentsException
*/
private void checkArgs(String[] args, int min, int max)
throws InsufficientArgumentsException {
if (args.length <= min || (max != -1 && args.length - 1 > max)) {
throw new InsufficientArgumentsException();
}
}
/**
* Checks to make sure that there are enough but not too many arguments.
*
* @param args
* @param min
* @param max -1 for no maximum
* @param help
* @throws InsufficientArgumentsException
*/
private void checkArgs(String[] args, int min, int max, String help)
throws InsufficientArgumentsException {
if (args.length <= min || (max != -1 && args.length - 1 > max)) {
throw new InsufficientArgumentsException(help);
}
}
boolean inGroup(Player player, String group) { boolean inGroup(Player player, String group) {
return perms.inGroup(player.getName(), group); return perms.inGroup(player.getName(), group);
} }
boolean hasPermission(Player player, String perm) { boolean hasPermission(Player player, String perm) {
return perms.hasPermission(player.getName(), perm); return player.isOp() || perms.hasPermission(player.getName(), perm);
} }
String[] getGroups(Player player) { String[] getGroups(Player player) {
@ -374,4 +1123,35 @@ String[] getGroups(Player player) {
BukkitPlayer wrapPlayer(Player player) { BukkitPlayer wrapPlayer(Player player) {
return new BukkitPlayer(this, player); return new BukkitPlayer(this, player);
} }
/**
* Thrown when a player has insufficient permissions.
*
* @author sk89q
*/
private static class InsufficientPermissionsException extends Exception {
private static final long serialVersionUID = 9087662707619954750L;
}
/**
* Thrown when a command wasn't given sufficient arguments.
*
* @author sk89q
*/
private static class InsufficientArgumentsException extends Exception {
private static final long serialVersionUID = 4153597953889773788L;
private final String help;
public InsufficientArgumentsException() {
help = null;
}
public InsufficientArgumentsException(String msg) {
this.help = msg;
}
public String getHelp() {
return help;
}
}
} }