Reorganize Bukkit portion of the region API.

This commit is contained in:
sk89q 2014-08-13 14:06:37 -07:00
parent 5b685e71d3
commit ad1c10a3e9
8 changed files with 234 additions and 95 deletions

View File

@ -64,11 +64,12 @@
import com.sk89q.worldguard.bukkit.listener.WorldGuardWeatherListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardWorldListener;
import com.sk89q.worldguard.protection.GlobalRegionManager;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.util.UnresolvedNamesException;
import com.sk89q.worldguard.protection.util.migrator.MigrationException;
import com.sk89q.worldguard.protection.util.migrator.UUIDMigrator;
import com.sk89q.worldguard.protection.util.UnresolvedNamesException;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.util.FatalConfigurationLoadingException;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.World;
@ -190,7 +191,7 @@ public void run() {
getLogger().info("Loading region data...");
globalRegionManager = new GlobalRegionManager(this);
globalRegionManager.preload();
globalRegionManager.loadAll(Bukkit.getServer().getWorlds());
migrateRegionUniqueIds(); // Migrate to UUIDs
} catch (FatalConfigurationLoadingException e) {
@ -281,7 +282,7 @@ public void onDisable() {
getLogger().log(Level.WARNING, "Some tasks failed while waiting for remaining tasks to finish", e);
}
globalRegionManager.unload();
globalRegionManager.unloadAll();
configuration.unload();
this.getServer().getScheduler().cancelTasks(this);
}

View File

@ -35,7 +35,7 @@
import com.sk89q.worldedit.bukkit.selections.Selection;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.bukkit.LoggerToChatHandler;
import com.sk89q.worldguard.bukkit.RegionPermissionModel;
import com.sk89q.worldguard.bukkit.permission.RegionPermissionModel;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.ApplicableRegionSet;

View File

@ -30,6 +30,7 @@
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.util.PastebinPoster;
import com.sk89q.worldguard.util.PastebinPoster.PasteCallback;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -77,9 +78,9 @@ public void reload(CommandContext args, CommandSender sender) throws CommandExce
try {
plugin.getGlobalStateManager().unload();
plugin.getGlobalRegionManager().unload();
plugin.getGlobalRegionManager().unloadAll();
plugin.getGlobalStateManager().load();
plugin.getGlobalRegionManager().preload();
plugin.getGlobalRegionManager().loadAll(Bukkit.getServer().getWorlds());
// WGBukkit.cleanCache();
sender.sendMessage("WorldGuard configuration reloaded.");
} catch (Throwable t) {

View File

@ -29,7 +29,7 @@
import com.sk89q.worldguard.bukkit.event.entity.UseEntityEvent;
import com.sk89q.worldguard.bukkit.util.Entities;
import com.sk89q.worldguard.bukkit.util.Materials;
import com.sk89q.worldguard.bukkit.util.RegionQuery;
import com.sk89q.worldguard.bukkit.util.ProtectedRegionQuery;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
import org.bukkit.ChatColor;
@ -98,7 +98,7 @@ public void onPlaceBlock(PlaceBlockEvent event) {
Material type = event.getEffectiveMaterial();
if (player != null) {
RegionQuery query = new RegionQuery(getPlugin(), player);
ProtectedRegionQuery query = new ProtectedRegionQuery(getPlugin(), player);
boolean canPlace;
// Flint and steel, fire charge
@ -139,7 +139,7 @@ public void onUseBlock(UseBlockEvent event) {
Material type = event.getEffectiveMaterial();
if (player != null) {
RegionQuery query = new RegionQuery(getPlugin(), player);
ProtectedRegionQuery query = new ProtectedRegionQuery(getPlugin(), player);
boolean canUse;
// Inventory blocks (CHEST_ACCESS)
@ -179,7 +179,7 @@ public void onSpawnEntity(SpawnEntityEvent event) {
EntityType type = event.getEffectiveType();
if (player != null) {
RegionQuery query = new RegionQuery(getPlugin(), player);
ProtectedRegionQuery query = new ProtectedRegionQuery(getPlugin(), player);
boolean canSpawn;
if (Entities.isVehicle(type)) {
@ -202,7 +202,7 @@ public void onDestroyEntity(DestroyEntityEvent event) {
EntityType type = event.getEntity().getType();
if (player != null) {
RegionQuery query = new RegionQuery(getPlugin(), player);
ProtectedRegionQuery query = new ProtectedRegionQuery(getPlugin(), player);
boolean canDestroy;
if (Entities.isVehicle(type)) {
@ -224,7 +224,7 @@ public void onUseEntity(UseEntityEvent event) {
Location target = event.getTarget();
if (player != null) {
RegionQuery query = new RegionQuery(getPlugin(), player);
ProtectedRegionQuery query = new ProtectedRegionQuery(getPlugin(), player);
boolean canUse = query.canBuild(target) || query.allows(DefaultFlag.USE, target);
if (!canUse) {

View File

@ -17,8 +17,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
package com.sk89q.worldguard.bukkit.permission;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import org.bukkit.command.CommandSender;
import com.sk89q.worldguard.internal.PermissionModel;

View File

@ -17,14 +17,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
package com.sk89q.worldguard.bukkit.permission;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
/**
* Used for querying region-related permissions.
@ -35,6 +36,10 @@ public RegionPermissionModel(WorldGuardPlugin plugin, CommandSender sender) {
super(plugin, sender);
}
public boolean mayIgnoreRegionProtection(World world) {
return hasPluginPermission("region.bypass." + world.getName());
}
public boolean mayForceLoadRegions() {
return hasPluginPermission("region.load");
}

View File

@ -24,6 +24,7 @@
import com.sk89q.worldguard.bukkit.ConfigurationManager;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.GlobalRegionManager;
import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
@ -35,17 +36,21 @@
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
public class RegionQuery {
public class ProtectedRegionQuery {
private final ConfigurationManager config;
private final GlobalRegionManager globalManager;
@Nullable
private final LocalPlayer localPlayer;
public RegionQuery(WorldGuardPlugin plugin, @Nullable Player player) {
public ProtectedRegionQuery(WorldGuardPlugin plugin, @Nullable Player player) {
this(plugin, player != null ? plugin.wrapPlayer(player) : null);
}
public ProtectedRegionQuery(WorldGuardPlugin plugin, @Nullable LocalPlayer player) {
this.config = plugin.getGlobalStateManager();
this.globalManager = plugin.getGlobalRegionManager();
this.localPlayer = player != null ? plugin.wrapPlayer(player) : null;
this.localPlayer = player;
}
public boolean canBuild(Location location) {
@ -76,7 +81,8 @@ public boolean canConstruct(Location location) {
return true;
} else {
RegionManager manager = globalManager.get(location.getWorld());
return manager.getApplicableRegions(BukkitUtil.toVector(location)).canConstruct(localPlayer);
ApplicableRegionSet result = manager.getApplicableRegions(BukkitUtil.toVector(location));
return result.canBuild(localPlayer) && result.canConstruct(localPlayer);
}
}

View File

@ -21,10 +21,9 @@
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.bukkit.BukkitUtil;
import com.sk89q.worldguard.bukkit.ConfigurationManager;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.util.ProtectedRegionQuery;
import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
import org.bukkit.Chunk;
@ -35,146 +34,272 @@
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
/**
* A global region manager loads, saves and caches region data for zero or
* more worlds at a time.
*
* <p>This class is thread safe and its contents can be accessed from
* multiple concurrent threads.</p>
*/
public class GlobalRegionManager {
private final WorldGuardPlugin plugin;
private final ConfigurationManager config;
private final ManagerContainer container;
/**
* Create a new instance.
*
* @param plugin the plugin
*/
public GlobalRegionManager(WorldGuardPlugin plugin) {
this.plugin = plugin;
config = plugin.getGlobalStateManager();
ConfigurationManager config = plugin.getGlobalStateManager();
container = new ManagerContainer(config);
}
/**
* Load the region data for a world if it has not been loaded already.
*
* <p>This method is called by WorldGuard and should not be called
* by other plugins.</p>
*
* @param world the world
* @return a region manager, either returned from the cache or newly loaded
*/
@Nullable
public RegionManager load(World world) {
checkNotNull(world);
RegionManager manager = container.load(world.getName());
if (manager != null) {
// Bias the region data for loaded chunks
List<Vector2D> positions = new ArrayList<Vector2D>();
for (Chunk chunk : world.getLoadedChunks()) {
positions.add(new Vector2D(chunk.getX(), chunk.getZ()));
}
manager.loadChunks(positions);
}
return manager;
}
public void preload() {
for (World world : plugin.getServer().getWorlds()) {
/**
* Load the region data for a list of worlds.
*
* <p>This method is called by WorldGuard and should not be called
* by other plugins.</p>
*
* @param worlds a list of worlds
*/
public void loadAll(Collection<? extends World> worlds) {
checkNotNull(worlds);
for (World world : worlds) {
load(world);
}
}
/**
* Unload the region data for a world.
*
* @param world a world
*/
public void unload(World world) {
unload(world.getName());
}
public void unload(String name) {
container.unload(name);
}
public void unload() {
container.unloadAll();
checkNotNull(world);
container.unload(world.getName());
}
/**
* Unload all region data for all worlds that region data has
* been loaded for.
*/
public void unloadAll() {
container.unloadAll();
}
/**
* Get the region manager for a world if one exists.
*
* <p>This method may return {@code null} if region data for the given
* world has not been loaded, has failed to load, or support for regions
* has been disabled.</p>
*
* @param world the world
* @return a region manager, or {@code null} if one is not availale
*/
@Nullable
public RegionManager get(World world) {
return container.get(world.getName());
}
/**
* Get an immutable list of loaded {@link RegionManager}s.
*
* @return a list of managers
*/
public List<RegionManager> getLoaded() {
return container.getLoaded();
return Collections.unmodifiableList(container.getLoaded());
}
/**
* Create a new region query with no player.
*
* @return a new query
*/
public ProtectedRegionQuery createAnonymousQuery() {
return new ProtectedRegionQuery(plugin, (Player) null);
}
/**
* Create a new region query.
*
* @param player a player, or {@code null}
* @return a new query
*/
public ProtectedRegionQuery createQuery(@Nullable Player player) {
return new ProtectedRegionQuery(plugin, player);
}
/**
* Create a new region query.
*
* @param player a player, or {@code null}
* @return a new query
*/
private ProtectedRegionQuery createQuery(@Nullable LocalPlayer player) {
return new ProtectedRegionQuery(plugin, player);
}
/**
* Test whether the given player has region protection bypass permission.
*
* @param player the player
* @param world the world
* @return true if a bypass is permitted
* @deprecated use {@link #createQuery(Player)}
*/
@Deprecated
public boolean hasBypass(LocalPlayer player, World world) {
return player.hasPermission("worldguard.region.bypass." + world.getName());
}
/**
* Test whether the given player has region protection bypass permission.
*
* @param player the player
* @param world the world
* @return true if a bypass is permitted
* @deprecated use {@link #createQuery(Player)}
*/
@Deprecated
public boolean hasBypass(Player player, World world) {
return plugin.hasPermission(player, "worldguard.region.bypass." + world.getName());
}
/**
* Test whether the player can build (place, use, destroy blocks and
* entities) at the given position, considering only the build flag
* and the region's members.
*
* <p>This method is not an absolute test as to whether WorldGuard
* would allow or block an event because this method doesn't
* consider flags (i.e. chest-access flags when concerning a chest) or
* other modules in WorldGuard (i.e chest protection).</p>
*
* @param player the player
* @param block the block
* @return true if a bypass is permitted
* @deprecated use {@link #createQuery(Player)}
*/
@SuppressWarnings("deprecation")
@Deprecated
public boolean canBuild(Player player, Block block) {
return canBuild(player, block.getLocation());
}
public boolean canBuild(Player player, Location loc) {
World world = loc.getWorld();
WorldConfiguration worldConfig = config.get(world);
if (!worldConfig.useRegions) {
return true;
}
LocalPlayer localPlayer = plugin.wrapPlayer(player);
if (!hasBypass(player, world)) {
RegionManager mgr = get(world);
if (mgr != null && !mgr.getApplicableRegions(BukkitUtil.toVector(loc)).canBuild(localPlayer)) {
return false;
}
}
return true;
/**
* Test whether the player can build (place, use, destroy blocks and
* entities) at the given position, considering only the build flag
* and the region's members.
*
* <p>This method is not an absolute test as to whether WorldGuard
* would allow or block an event because this method doesn't
* consider flags (i.e. chest-access flags when concerning a chest) or
* other modules in WorldGuard (i.e chest protection).</p>
*
* @param player the player
* @param location the location
* @return true if a bypass is permitted
* @deprecated use {@link #createQuery(Player)}
*/
@Deprecated
public boolean canBuild(Player player, Location location) {
return createQuery(player).canBuild(location);
}
/**
* Test whether the player can place blocks at the given position.
*
* @param player the player
* @param block the block
* @return true if permitted
* @deprecated use {@link #createQuery(Player)}
*/
@Deprecated
@SuppressWarnings("deprecation")
public boolean canConstruct(Player player, Block block) {
return canConstruct(player, block.getLocation());
}
public boolean canConstruct(Player player, Location loc) {
World world = loc.getWorld();
WorldConfiguration worldConfig = config.get(world);
if (!worldConfig.useRegions) {
return true;
/**
* Test whether the player can place blocks at the given position.
*
* @param player the player
* @param location the location
* @return true if permitted
* @deprecated use {@link #createQuery(Player)}
*/
@Deprecated
public boolean canConstruct(Player player, Location location) {
return createQuery(player).canConstruct(location);
}
LocalPlayer localPlayer = plugin.wrapPlayer(player);
if (!hasBypass(player, world)) {
RegionManager mgr = get(world);
if (mgr != null) {
final ApplicableRegionSet applicableRegions = mgr.getApplicableRegions(BukkitUtil.toVector(loc));
if (!applicableRegions.canBuild(localPlayer)) {
return false;
}
if (!applicableRegions.canConstruct(localPlayer)) {
return false;
}
}
/**
* Test the value of a state flag at a location.
*
* @param flag the flag
* @param location the location
* @return true if set to true
* @deprecated use {@link #createQuery(Player)}
*/
@Deprecated
@SuppressWarnings("deprecation")
public boolean allows(StateFlag flag, Location location) {
return allows(flag, location, null);
}
return true;
}
public boolean allows(StateFlag flag, Location loc) {
return allows(flag, loc, null);
}
public boolean allows(StateFlag flag, Location loc, @Nullable LocalPlayer player) {
World world = loc.getWorld();
WorldConfiguration worldConfig = config.get(world);
if (!worldConfig.useRegions) {
return true;
}
RegionManager mgr = get(world);
return mgr == null || mgr.getApplicableRegions(toVector(loc)).allows(flag, player);
/**
* Test the value of a state flag at a location, using the player as the
* relevant actor.
*
* @param flag the flag
* @param location the location
* @param player the actor
* @return true if set to true
* @deprecated use {@link #createQuery(Player)}
*/
@Deprecated
public boolean allows(StateFlag flag, Location location, @Nullable LocalPlayer player) {
return createQuery(player).allows(flag, location);
}
}