Add config setting to allow clamping of location flags.

Prevents players from setting locations (teleport, spawn) to point outside of the region.
The permission to override this is "worldguard.region.locationoverride.(own/member/.)regionid".
Also prevents location flags from being set to under the map or over the max world height.
Fixes WORLDGUARD-2775, WORLDGUARD-3370.
This commit is contained in:
wizjany 2015-08-02 03:42:13 -04:00
parent c1b8d12d05
commit 43a9228304
4 changed files with 32 additions and 5 deletions

View File

@ -145,6 +145,7 @@ public class WorldConfiguration {
public int maxClaimVolume; public int maxClaimVolume;
public boolean claimOnlyInsideExistingRegions; public boolean claimOnlyInsideExistingRegions;
public int maxRegionCountPerPlayer; public int maxRegionCountPerPlayer;
public boolean boundedLocationFlags;
public boolean antiWolfDumbness; public boolean antiWolfDumbness;
public boolean signChestProtection; public boolean signChestProtection;
public boolean disableSignChestProtectionCheck; public boolean disableSignChestProtectionCheck;
@ -462,6 +463,7 @@ private void loadConfiguration() {
regionWand = getInt("regions.wand", 334); regionWand = getInt("regions.wand", 334);
maxClaimVolume = getInt("regions.max-claim-volume", 30000); maxClaimVolume = getInt("regions.max-claim-volume", 30000);
claimOnlyInsideExistingRegions = getBoolean("regions.claim-only-inside-existing-regions", false); claimOnlyInsideExistingRegions = getBoolean("regions.claim-only-inside-existing-regions", false);
boundedLocationFlags = getBoolean("regions.location-flags-only-inside-regions", false);
maxRegionCountPerPlayer = getInt("regions.max-region-count-per-player.default", 7); maxRegionCountPerPlayer = getInt("regions.max-region-count-per-player.default", 7);
maxRegionCounts = new HashMap<String, Integer>(); maxRegionCounts = new HashMap<String, Integer>();

View File

@ -540,7 +540,7 @@ public void flag(CommandContext args, CommandSender sender) throws CommandExcept
// Parse the [-g group] separately so entire command can abort if parsing // Parse the [-g group] separately so entire command can abort if parsing
// the [value] part throws an error. // the [value] part throws an error.
try { try {
groupValue = groupFlag.parseInput(FlagContext.create().setSender(sender).setInput(group).build()); groupValue = groupFlag.parseInput(FlagContext.create().setSender(sender).setInput(group).setObject("region", existing).build());
} catch (InvalidFlagFormat e) { } catch (InvalidFlagFormat e) {
throw new CommandException(e.getMessage()); throw new CommandException(e.getMessage());
} }

View File

@ -99,6 +99,10 @@ public boolean mayLookup(ProtectedRegion region) {
public boolean mayTeleportTo(ProtectedRegion region) { public boolean mayTeleportTo(ProtectedRegion region) {
return hasPatternPermission("teleport", region); return hasPatternPermission("teleport", region);
} }
public boolean mayOverrideLocationFlagBounds(ProtectedRegion region) {
return hasPatternPermission("locationoverride", region);
}
public boolean mayList() { public boolean mayList() {
return hasPluginPermission("region.list"); return hasPluginPermission("region.list");

View File

@ -22,6 +22,10 @@
import com.sk89q.worldedit.Location; import com.sk89q.worldedit.Location;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.bukkit.BukkitUtil; import com.sk89q.worldedit.bukkit.BukkitUtil;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.permission.RegionPermissionModel;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import org.bukkit.ChatColor;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -43,8 +47,9 @@ public Location parseInput(FlagContext context) throws InvalidFlagFormat {
String input = context.getUserInput(); String input = context.getUserInput();
Player player = context.getPlayerSender(); Player player = context.getPlayerSender();
Location loc = null;
if ("here".equalsIgnoreCase(input)) { if ("here".equalsIgnoreCase(input)) {
return toLazyLocation(player.getLocation()); loc = toLazyLocation(player.getLocation());
} else if ("none".equalsIgnoreCase(input)) { } else if ("none".equalsIgnoreCase(input)) {
return null; return null;
} else { } else {
@ -58,13 +63,29 @@ public Location parseInput(FlagContext context) throws InvalidFlagFormat {
final float yaw = split.length < 4 ? 0 : Float.parseFloat(split[3]); final float yaw = split.length < 4 ? 0 : Float.parseFloat(split[3]);
final float pitch = split.length < 5 ? 0 : Float.parseFloat(split[4]); final float pitch = split.length < 5 ? 0 : Float.parseFloat(split[4]);
return new LazyLocation(world.getName(), new Vector(x, y, z), yaw, pitch); loc = new LazyLocation(world.getName(), new Vector(x, y, z), yaw, pitch);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
} }
} }
throw new InvalidFlagFormat("Expected 'here' or x,y,z.");
} }
if (loc != null) {
Object obj = context.get("region");
if (obj instanceof ProtectedRegion) {
ProtectedRegion rg = (ProtectedRegion) obj;
if (WorldGuardPlugin.inst().getGlobalStateManager().get(player.getWorld()).boundedLocationFlags) {
if (!rg.contains(loc.getPosition()) && new RegionPermissionModel(WorldGuardPlugin.inst(), player).mayOverrideLocationFlagBounds(rg)) {
player.sendMessage(ChatColor.GRAY + "WARNING: Flag location is outside of region.");
} else {
// no permission
throw new InvalidFlagFormat("You can't set that flag outside of the region boundaries.");
}
// clamp height to world limits
loc.setPosition(loc.getPosition().clampY(0, player.getWorld().getMaxHeight()));
return loc;
}
}
}
throw new InvalidFlagFormat("Expected 'here' or x,y,z.");
} }
private Location toLazyLocation(org.bukkit.Location location) { private Location toLazyLocation(org.bukkit.Location location) {