Fix region bypass permission and support fake players.

This commit is contained in:
sk89q 2014-08-22 19:32:03 -07:00
parent 858b0b2c1c
commit 74e64d0641
5 changed files with 62 additions and 26 deletions

View File

@ -113,6 +113,9 @@ public ApplicableRegionSet getApplicableRegions(Location location) {
* {@link #testState(Location, Player, StateFlag...)} with
* {@code flags} plus the {@code BUILD} flag.</p>
*
* <p>This method does not check the region bypass permission. That must
* be done by the calling code.</p>
*
* @param location the location
* @param player the player
* @param flags zero or more flags
@ -123,12 +126,6 @@ public boolean testBuild(Location location, Player player, StateFlag... flags) {
checkNotNull(location);
checkNotNull(player);
World world = location.getWorld();
if (player.hasPermission("worldguard.region.bypass." + world.getName())) {
return true;
}
LocalPlayer localPlayer = plugin.wrapPlayer(player);
return testBuild(location, localPlayer, flags);
}
@ -141,6 +138,9 @@ public boolean testBuild(Location location, Player player, StateFlag... flags) {
* {@link #testState(Location, Player, StateFlag...)} with
* {@code flags} plus the {@code BUILD} flag.</p>
*
* <p>This method does not check the region bypass permission. That must
* be done by the calling code.</p>
*
* @param location the location
* @param subject the subject
* @param flags zero or more flags
@ -169,6 +169,9 @@ public boolean testBuild(Location location, RegionAssociable subject, StateFlag.
* to certain users.) The player argument is required if the
* {@link DefaultFlag#BUILD} flag is in the list of flags.</p>
*
* <p>This method does not check the region bypass permission. That must
* be done by the calling code.</p>
*
* @param location the location
* @param player an optional player, which would be used to determine the region group to apply
* @param flag the flag

View File

@ -169,6 +169,7 @@ public class WorldConfiguration {
public boolean disableSoilDehydration;
public Set<Integer> allowedSnowFallOver;
public boolean regionInvinciblityRemovesMobs;
public boolean fakePlayerBuildOverride;
public boolean explosionFlagCancellation;
public boolean disableDeathMessages;
public boolean disableObsidianGenerators;
@ -414,6 +415,7 @@ private void loadConfiguration() {
useRegions = getBoolean("regions.enable", true);
regionInvinciblityRemovesMobs = getBoolean("regions.invincibility-removes-mobs", false);
fakePlayerBuildOverride = getBoolean("regions.fake-player-build-override", true);
explosionFlagCancellation = getBoolean("regions.explosion-flags-block-entity-damage", true);
highFreqFlags = getBoolean("regions.high-frequency-flags", false);
checkLiquidFlow = getBoolean("regions.protect-against-liquid-flow", false);

View File

@ -21,6 +21,7 @@
import com.google.common.base.Predicate;
import com.sk89q.worldguard.bukkit.RegionQuery;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.cause.Cause;
import com.sk89q.worldguard.bukkit.event.block.BreakBlockEvent;
@ -30,6 +31,7 @@
import com.sk89q.worldguard.bukkit.event.entity.DestroyEntityEvent;
import com.sk89q.worldguard.bukkit.event.entity.SpawnEntityEvent;
import com.sk89q.worldguard.bukkit.event.entity.UseEntityEvent;
import com.sk89q.worldguard.bukkit.permission.RegionPermissionModel;
import com.sk89q.worldguard.bukkit.util.DelayedRegionOverlapAssociation;
import com.sk89q.worldguard.bukkit.util.Entities;
import com.sk89q.worldguard.bukkit.util.Events;
@ -45,6 +47,7 @@
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
@ -104,8 +107,21 @@ private void tellErrorMessage(Cause cause, Location location, String what) {
* @param cause the cause
* @return true if whitelisted
*/
private boolean isWhitelisted(Cause cause) {
return false;
private boolean isWhitelisted(Cause cause, World world) {
Object rootCause = cause.getRootCause();
if (rootCause instanceof Player) {
Player player = (Player) rootCause;
WorldConfiguration config = getWorldConfig(world);
if (config.fakePlayerBuildOverride && Entities.isFakePlayer(player)) {
return true;
}
return new RegionPermissionModel(getPlugin(), player).mayIgnoreRegionProtection(world);
} else {
return false;
}
}
private RegionAssociable createRegionAssociable(Cause cause) {
@ -129,7 +145,7 @@ private RegionAssociable createRegionAssociable(Cause cause) {
@EventHandler(ignoreCancelled = true)
public void onPlaceBlock(final PlaceBlockEvent event) {
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
if (isWhitelisted(event.getCause())) return; // Whitelisted cause
if (isWhitelisted(event.getCause(), event.getWorld())) return; // Whitelisted cause
final Material type = event.getEffectiveMaterial();
final RegionQuery query = getPlugin().getRegionContainer().createQuery();
@ -170,7 +186,7 @@ public boolean apply(Location target) {
@EventHandler(ignoreCancelled = true)
public void onBreakBlock(final BreakBlockEvent event) {
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
if (isWhitelisted(event.getCause())) return; // Whitelisted cause
if (isWhitelisted(event.getCause(), event.getWorld())) return; // Whitelisted cause
final RegionQuery query = getPlugin().getRegionContainer().createQuery();
@ -208,7 +224,7 @@ public boolean apply(Location target) {
@EventHandler(ignoreCancelled = true)
public void onUseBlock(final UseBlockEvent event) {
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
if (isWhitelisted(event.getCause())) return; // Whitelisted cause
if (isWhitelisted(event.getCause(), event.getWorld())) return; // Whitelisted cause
final Material type = event.getEffectiveMaterial();
final RegionQuery query = getPlugin().getRegionContainer().createQuery();
@ -254,7 +270,7 @@ public boolean apply(Location target) {
@EventHandler(ignoreCancelled = true)
public void onSpawnEntity(SpawnEntityEvent event) {
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
if (isWhitelisted(event.getCause())) return; // Whitelisted cause
if (isWhitelisted(event.getCause(), event.getWorld())) return; // Whitelisted cause
Location target = event.getTarget();
EntityType type = event.getEffectiveType();
@ -295,7 +311,7 @@ public void onSpawnEntity(SpawnEntityEvent event) {
@EventHandler(ignoreCancelled = true)
public void onDestroyEntity(DestroyEntityEvent event) {
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
if (isWhitelisted(event.getCause())) return; // Whitelisted cause
if (isWhitelisted(event.getCause(), event.getWorld())) return; // Whitelisted cause
Location target = event.getTarget();
EntityType type = event.getEntity().getType();
@ -330,7 +346,7 @@ public void onDestroyEntity(DestroyEntityEvent event) {
@EventHandler(ignoreCancelled = true)
public void onUseEntity(UseEntityEvent event) {
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
if (isWhitelisted(event.getCause())) return; // Whitelisted cause
if (isWhitelisted(event.getCause(), event.getWorld())) return; // Whitelisted cause
Location target = event.getTarget();
RegionAssociable associable = createRegionAssociable(event.getCause());
@ -348,7 +364,7 @@ public void onUseEntity(UseEntityEvent event) {
@EventHandler(ignoreCancelled = true)
public void onDamageEntity(DamageEntityEvent event) {
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
if (isWhitelisted(event.getCause())) return; // Whitelisted cause
if (isWhitelisted(event.getCause(), event.getWorld())) return; // Whitelisted cause
Location target = event.getTarget();
RegionAssociable associable = createRegionAssociable(event.getCause());
@ -391,17 +407,19 @@ public void onVehicleExit(VehicleExitEvent event) {
if (vehicle instanceof Tameable && exited instanceof Player) {
Player player = (Player) exited;
RegionQuery query = getPlugin().getRegionContainer().createQuery();
Location location = vehicle.getLocation();
if (!query.testBuild(location, player, DefaultFlag.USE)) {
long now = System.currentTimeMillis();
Long lastTime = WGMetadata.getIfPresent(player, DISEMBARK_MESSAGE_KEY, Long.class);
if (lastTime == null || now - lastTime >= LAST_MESSAGE_DELAY) {
player.sendMessage("" + ChatColor.GOLD + "Don't disembark here!" + ChatColor.GRAY + " You can't get back on.");
WGMetadata.put(player, DISEMBARK_MESSAGE_KEY, now);
}
if (!isWhitelisted(Cause.create(player), vehicle.getWorld())) {
RegionQuery query = getPlugin().getRegionContainer().createQuery();
Location location = vehicle.getLocation();
if (!query.testBuild(location, player, DefaultFlag.USE)) {
long now = System.currentTimeMillis();
Long lastTime = WGMetadata.getIfPresent(player, DISEMBARK_MESSAGE_KEY, Long.class);
if (lastTime == null || now - lastTime >= LAST_MESSAGE_DELAY) {
player.sendMessage("" + ChatColor.GOLD + "Don't disembark here!" + ChatColor.GRAY + " You can't get back on.");
WGMetadata.put(player, DISEMBARK_MESSAGE_KEY, now);
}
event.setCancelled(true);
event.setCancelled(true);
}
}
}
}

View File

@ -21,6 +21,7 @@
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.entity.Tameable;
@ -113,4 +114,15 @@ public static Entity getShooter(Entity entity) {
return entity;
}
/**
* Return whether the given player is a fake player using the typical
* fake player convention of [Mod].
*
* @param player the player
* @return true if a fake player
*/
public static boolean isFakePlayer(Player player) {
String name = player.getName();
return name.length() >= 3 && name.charAt(0) == '[' && name.charAt(name.length() - 1) == ']';
}
}

View File

@ -158,7 +158,8 @@ public boolean canBuild(Player player, Block block) {
*/
@Deprecated
public boolean canBuild(Player player, Location location) {
return createQuery().testBuild(location, player);
return hasBypass(player, location.getWorld()) || createQuery().testBuild(location, player);
}
/**