From 99660920d7c7dc1c698818243f577a5b9ba0eec0 Mon Sep 17 00:00:00 2001 From: sk89q Date: Thu, 14 Aug 2014 01:24:38 -0700 Subject: [PATCH] Refactor region API with new RegionContainer object. --- .../worldguard/bukkit/BukkitBlacklist.java | 4 +- .../ManagerContainer.java | 63 +- .../worldguard/bukkit/RegionContainer.java | 242 ++++++ .../sk89q/worldguard/bukkit/RegionQuery.java | 196 +++++ .../worldguard/bukkit/WorldGuardPlugin.java | 31 +- .../bukkit/commands/RegionCommands.java | 2 +- .../bukkit/commands/WorldGuardCommands.java | 7 +- ...tEvent.java => AbstractDelegateEvent.java} | 11 +- .../event/block/AbstractBlockEvent.java | 8 +- .../bukkit/event/block/BreakBlockEvent.java | 6 +- .../bukkit/event/block/PlaceBlockEvent.java | 6 +- .../bukkit/event/block/UseBlockEvent.java | 6 +- .../event/entity/AbstractEntityEvent.java | 8 +- .../event/entity/DestroyEntityEvent.java | 3 +- .../bukkit/event/entity/SpawnEntityEvent.java | 6 +- .../bukkit/event/entity/UseEntityEvent.java | 3 +- .../bukkit/event/inventory/UseItemEvent.java | 8 +- .../{ => listener}/FlagStateManager.java | 508 ++++++------- .../listener/RegionProtectionListener.java | 75 +- .../bukkit/{ => listener}/SpongeUtil.java | 261 +++---- .../listener/WorldGuardBlockListener.java | 1 - .../listener/WorldGuardEntityListener.java | 2 +- .../listener/WorldGuardPlayerListener.java | 4 +- .../{ => util}/LoggerToChatHandler.java | 8 +- .../bukkit/util/ProtectedRegionQuery.java | 101 --- .../bukkit/{ => util}/RegionQueryUtil.java | 174 ++--- .../bukkit/{ => util}/ReportWriter.java | 689 +++++++++--------- .../protection/GlobalRegionManager.java | 114 +-- 28 files changed, 1431 insertions(+), 1116 deletions(-) rename src/main/java/com/sk89q/worldguard/{protection => bukkit}/ManagerContainer.java (79%) create mode 100644 src/main/java/com/sk89q/worldguard/bukkit/RegionContainer.java create mode 100644 src/main/java/com/sk89q/worldguard/bukkit/RegionQuery.java rename src/main/java/com/sk89q/worldguard/bukkit/event/{AbstractInteractEvent.java => AbstractDelegateEvent.java} (86%) rename src/main/java/com/sk89q/worldguard/bukkit/{ => listener}/FlagStateManager.java (96%) rename src/main/java/com/sk89q/worldguard/bukkit/{ => listener}/SpongeUtil.java (96%) rename src/main/java/com/sk89q/worldguard/bukkit/{ => util}/LoggerToChatHandler.java (97%) delete mode 100644 src/main/java/com/sk89q/worldguard/bukkit/util/ProtectedRegionQuery.java rename src/main/java/com/sk89q/worldguard/bukkit/{ => util}/RegionQueryUtil.java (95%) rename src/main/java/com/sk89q/worldguard/bukkit/{ => util}/ReportWriter.java (97%) diff --git a/src/main/java/com/sk89q/worldguard/bukkit/BukkitBlacklist.java b/src/main/java/com/sk89q/worldguard/bukkit/BukkitBlacklist.java index e98a7314..d333a650 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/BukkitBlacklist.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/BukkitBlacklist.java @@ -21,7 +21,8 @@ import com.sk89q.worldguard.blacklist.Blacklist; -public class BukkitBlacklist extends Blacklist { +class BukkitBlacklist extends Blacklist { + private WorldGuardPlugin plugin; public BukkitBlacklist(Boolean useAsWhitelist, WorldGuardPlugin plugin) { @@ -33,4 +34,5 @@ public BukkitBlacklist(Boolean useAsWhitelist, WorldGuardPlugin plugin) { public void broadcastNotification(String msg) { plugin.broadcastNotification(msg); } + } diff --git a/src/main/java/com/sk89q/worldguard/protection/ManagerContainer.java b/src/main/java/com/sk89q/worldguard/bukkit/ManagerContainer.java similarity index 79% rename from src/main/java/com/sk89q/worldguard/protection/ManagerContainer.java rename to src/main/java/com/sk89q/worldguard/bukkit/ManagerContainer.java index 2ce82afb..f79f09b7 100644 --- a/src/main/java/com/sk89q/worldguard/protection/ManagerContainer.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/ManagerContainer.java @@ -17,10 +17,9 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.protection; +package com.sk89q.worldguard.bukkit; import com.google.common.base.Supplier; -import com.sk89q.worldguard.bukkit.ConfigurationManager; import com.sk89q.worldguard.protection.managers.RegionManager; import com.sk89q.worldguard.protection.managers.index.ChunkHashTable; import com.sk89q.worldguard.protection.managers.index.ConcurrentRegionIndex; @@ -54,16 +53,29 @@ class ManagerContainer { private static final Logger log = Logger.getLogger(ManagerContainer.class.getCanonicalName()); private static final int SAVE_INTERVAL = 1000 * 30; + private final ConfigurationManager config; private final ConcurrentMap mapping = new ConcurrentHashMap(); private final Object lock = new Object(); private final EnumMap drivers = new EnumMap(DriverType.class); - private final RegionStoreDriver defaultDriver; + private RegionStoreDriver defaultDriver; private final Supplier indexFactory = new ChunkHashTable.Factory(new PriorityRTreeIndex.Factory()); private final Timer timer = new Timer(); + /** + * Create a new instance. + * + * @param config the configuration + */ ManagerContainer(ConfigurationManager config) { checkNotNull(config); + this.config = config; + timer.schedule(new BackgroundSaver(), SAVE_INTERVAL, SAVE_INTERVAL); + } + /** + * Create drivers from the configuration. + */ + public void initialize() { for (DriverType type : DriverType.values()) { drivers.put(type, type.create(config)); } @@ -73,10 +85,15 @@ class ManagerContainer { } else { defaultDriver = drivers.get(DriverType.YAML); } - - timer.schedule(new BackgroundSaver(), SAVE_INTERVAL, SAVE_INTERVAL); } + /** + * Load the {@code RegionManager} for the world with the given name, + * creating a new instance for the world if one does not exist yet. + * + * @param name the name of the world + * @return a region manager, or {@code null} if loading failed + */ @Nullable public RegionManager load(String name) { checkNotNull(name); @@ -100,6 +117,13 @@ public RegionManager load(String name) { } } + /** + * Create a new region manager and load the data. + * + * @param name the name of the world + * @return a region manager + * @throws IOException thrown if loading fals + */ private RegionManager createAndLoad(String name) throws IOException { RegionStore store = defaultDriver.get(name); RegionManager manager = new RegionManager(store, indexFactory); @@ -107,6 +131,14 @@ private RegionManager createAndLoad(String name) throws IOException { return manager; } + /** + * Unload the region manager associated with the given world name. + * + *

If no region manager has been loaded for the given name, then + * nothing will happen.

+ * + * @param name the name of the world + */ public void unload(String name) { checkNotNull(name); @@ -120,11 +152,16 @@ public void unload(String name) { } catch (IOException e) { log.log(Level.WARNING, "Failed to save the region data for '" + name + "'", e); } + + mapping.remove(normal); } - mapping.remove(normal); } } + /** + * Unload all region managers and save their contents before returning. + * This message may block for an extended period of time. + */ public void unloadAll() { synchronized (lock) { for (Map.Entry entry : mapping.entrySet()) { @@ -141,16 +178,30 @@ public void unloadAll() { } } + /** + * Get the region manager for the given world name. + * + * @param name the name of the world + * @return a region manager, or {@code null} if one was never loaded + */ @Nullable public RegionManager get(String name) { checkNotNull(name); return mapping.get(Normal.normal(name)); } + /** + * Get an immutable list of loaded region managers. + * + * @return an immutable list + */ public List getLoaded() { return Collections.unmodifiableList(new ArrayList(mapping.values())); } + /** + * A task to save managers in the background. + */ private class BackgroundSaver extends TimerTask { @Override public void run() { diff --git a/src/main/java/com/sk89q/worldguard/bukkit/RegionContainer.java b/src/main/java/com/sk89q/worldguard/bukkit/RegionContainer.java new file mode 100644 index 00000000..bd8f1348 --- /dev/null +++ b/src/main/java/com/sk89q/worldguard/bukkit/RegionContainer.java @@ -0,0 +1,242 @@ +/* + * WorldGuard, a suite of tools for Minecraft + * Copyright (C) sk89q + * Copyright (C) WorldGuard team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldguard.bukkit; + +import com.sk89q.worldedit.Vector2D; +import com.sk89q.worldguard.LocalPlayer; +import com.sk89q.worldguard.protection.managers.RegionManager; +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.world.ChunkLoadEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.event.world.WorldLoadEvent; +import org.bukkit.event.world.WorldUnloadEvent; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A region container creates {@link RegionManager}s for loaded worlds, which + * allows access to the region data of a world. Generally, only data is + * loaded for worlds that are loaded in the server. + * + *

This class is thread safe and its contents can be accessed from + * multiple concurrent threads.

+ * + *

An instance of this class can be retrieved using + * {@link WorldGuardPlugin#getRegionContainer()}.

+ */ +public class RegionContainer { + + private final Object lock = new Object(); + private final WorldGuardPlugin plugin; + private final ManagerContainer container; + + /** + * Create a new instance. + * + * @param plugin the plugin + */ + RegionContainer(WorldGuardPlugin plugin) { + this.plugin = plugin; + + ConfigurationManager config = plugin.getGlobalStateManager(); + container = new ManagerContainer(config); + } + + /** + * Initialize the region container. + */ + void initialize() { + container.initialize(); + + loadWorlds(); + + Bukkit.getPluginManager().registerEvents(new Listener() { + @EventHandler + public void onWorldLoad(WorldLoadEvent event) { + load(event.getWorld()); + } + + @EventHandler + public void onWorldUnload(WorldUnloadEvent event) { + unload(event.getWorld()); + } + + @EventHandler + public void onChunkLoad(ChunkLoadEvent event) { + RegionManager manager = get(event.getWorld()); + if (manager != null) { + Chunk chunk = event.getChunk(); + manager.loadChunk(new Vector2D(chunk.getX(), chunk.getZ())); + } + } + + @EventHandler + public void onChunkUnload(ChunkUnloadEvent event) { + RegionManager manager = get(event.getWorld()); + if (manager != null) { + Chunk chunk = event.getChunk(); + manager.unloadChunk(new Vector2D(chunk.getX(), chunk.getZ())); + } + } + }, plugin); + } + + /** + * Save data and unload. + */ + void unload() { + synchronized (lock) { + container.unloadAll(); + } + } + + /** + * Try loading the region managers for all currently loaded worlds. + */ + private void loadWorlds() { + synchronized (lock) { + for (World world : Bukkit.getServer().getWorlds()) { + load(world); + } + } + } + + /** + * Reload the region container. + * + *

This method may block until the data for all loaded worlds has been + * unloaded and new data has been loaded.

+ */ + public void reload() { + synchronized (lock) { + unload(); + loadWorlds(); + } + } + + /** + * Load the region data for a world if it has not been loaded already. + * + * @param world the world + * @return a region manager, either returned from the cache or newly loaded + */ + @Nullable + private RegionManager load(World world) { + checkNotNull(world); + + RegionManager manager; + + synchronized (lock) { + manager = container.load(world.getName()); + + if (manager != null) { + // Bias the region data for loaded chunks + List positions = new ArrayList(); + for (Chunk chunk : world.getLoadedChunks()) { + positions.add(new Vector2D(chunk.getX(), chunk.getZ())); + } + manager.loadChunks(positions); + } + } + + return manager; + } + + /** + * Unload the region data for a world. + * + * @param world a world + */ + void unload(World world) { + checkNotNull(world); + + synchronized (lock) { + container.unload(world.getName()); + } + } + + /** + * Get the region manager for a world if one exists. + * + *

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. If you merely want to query flags or a list of + * regions in a position, using {@link #createQuery(Player)} is much + * simpler and it will handle the case of a {@code null} + * {@code RegionManager}. That said, if you wish to make changes to + * regions, then you will have to get a region manager.

+ * + * @param world the world + * @return a region manager, or {@code null} if one is not available + */ + @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 getLoaded() { + return Collections.unmodifiableList(container.getLoaded()); + } + + /** + * Create a new region query with no player. + * + * @return a new query + */ + public RegionQuery createAnonymousQuery() { + return new RegionQuery(plugin, (Player) null); + } + + /** + * Create a new region query. + * + * @param player a player, or {@code null} + * @return a new query + */ + public RegionQuery createQuery(@Nullable Player player) { + return new RegionQuery(plugin, player); + } + + /** + * Create a new region query. + * + * @param player a player, or {@code null} + * @return a new query + */ + public RegionQuery createQuery(@Nullable LocalPlayer player) { + return new RegionQuery(plugin, player); + } + +} diff --git a/src/main/java/com/sk89q/worldguard/bukkit/RegionQuery.java b/src/main/java/com/sk89q/worldguard/bukkit/RegionQuery.java new file mode 100644 index 00000000..56f18664 --- /dev/null +++ b/src/main/java/com/sk89q/worldguard/bukkit/RegionQuery.java @@ -0,0 +1,196 @@ +/* + * WorldGuard, a suite of tools for Minecraft + * Copyright (C) sk89q + * Copyright (C) WorldGuard team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldguard.bukkit; + +import com.sk89q.worldguard.LocalPlayer; +import com.sk89q.worldguard.protection.ApplicableRegionSet; +import com.sk89q.worldguard.protection.GlobalRegionManager; +import com.sk89q.worldguard.protection.flags.DefaultFlag; +import com.sk89q.worldguard.protection.flags.StateFlag; +import com.sk89q.worldguard.protection.managers.RegionManager; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; + +import javax.annotation.Nullable; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * This object allows easy spatial queries involving region data. + * + *

Results may be cached for brief amounts of time.

+ */ +public class RegionQuery { + + private final ConfigurationManager config; + private final GlobalRegionManager globalManager; + @Nullable + private final LocalPlayer localPlayer; + + /** + * Create a new instance. + * + * @param plugin the plugin + * @param player an optional player + */ + RegionQuery(WorldGuardPlugin plugin, @Nullable Player player) { + this(plugin, player != null ? plugin.wrapPlayer(player) : null); + } + + /** + * Create a new instance. + * + * @param plugin the plugin + * @param player an optional player + */ + RegionQuery(WorldGuardPlugin plugin, @Nullable LocalPlayer player) { + checkNotNull(plugin); + + this.config = plugin.getGlobalStateManager(); + //noinspection deprecation + this.globalManager = plugin.getGlobalRegionManager(); + this.localPlayer = player; + } + + /** + * Test whether the player (which must not be {@code null} can build at + * the given location, using only the membership information and the state + * of the {@link DefaultFlag#BUILD} flag to determine status. + * + *

This method is used to check blocks and entities for which there + * are no other related flags for (i.e. beds have the + * {@link DefaultFlag#SLEEP} flag).

+ * + *

If region data is not available (it failed to load or region support + * is disabled), then either {@code true} or {@code false} may be returned + * depending on the configuration.

+ * + * @param location the location + * @return true if building is permitted + * @throws NullPointerException if there is no player for this query + */ + public boolean testPermission(Location location) { + checkNotNull(location); + checkNotNull(localPlayer, "testPermission() requires a player for the query"); + + World world = location.getWorld(); + WorldConfiguration worldConfig = config.get(world); + + if (!worldConfig.useRegions) { + return true; + } + + if (globalManager.hasBypass(localPlayer, world)) { + return true; + } else { + RegionManager manager = globalManager.get(location.getWorld()); + return manager == null || manager.getApplicableRegions(BukkitUtil.toVector(location)).canBuild(localPlayer); + } + } + + /** + * Test whether the player (which must not be {@code null} can build at + * the given location, using the membership information, state + * of the {@link DefaultFlag#BUILD} flag, and the state of any passed + * flags. + * + *

This method is used to check blocks and entities for which there + * are other related flags for (i.e. beds have the + * {@link DefaultFlag#SLEEP} flag). The criteria under which this method + * returns true is subject to change (i.e. all flags must be true or + * one cannot be DENY, etc.).

+ * + *

If region data is not available (it failed to load or region support + * is disabled), then either {@code true} or {@code false} may be returned + * depending on the configuration.

+ * + * @param location the location to test + * @param flags an array of flags + * @return true if the flag tests true + */ + public boolean testPermission(Location location, StateFlag... flags) { + checkNotNull(location); + checkNotNull(flags); + checkNotNull(localPlayer, "testPermission() requires a player for the query"); + + World world = location.getWorld(); + WorldConfiguration worldConfig = config.get(world); + + if (!worldConfig.useRegions) { + return true; + } + + RegionManager manager = globalManager.get(location.getWorld()); + + if (manager != null) { + ApplicableRegionSet result = manager.getApplicableRegions(BukkitUtil.toVector(location)); + + if (result.canBuild(localPlayer)) { + return true; + } + + for (StateFlag flag : flags) { + if (result.allows(flag, localPlayer)) { + return true; + } + } + + return false; + } else{ + return true; // null manager -> return true for now + } + } + + /** + * Test whether a {@link StateFlag} is evaluates to {@code ALLOW}. + * + *

This method is to check whether certain functionality + * is enabled (i.e. water flow). The player, if provided, may be used + * in evaluation of the flag.

+ * + *

If region data is not available (it failed to load or region support + * is disabled), then either {@code true} or {@code false} may be returned + * depending on the configuration.

+ * + * @param location the location + * @param flag the flag + * @return true if the flag evaluates to {@code ALLOW} + */ + public boolean testEnabled(Location location, StateFlag flag) { + checkNotNull(location); + checkNotNull(flag); + + World world = location.getWorld(); + WorldConfiguration worldConfig = config.get(world); + + if (!worldConfig.useRegions) { + return true; + } + + if (globalManager.hasBypass(localPlayer, world)) { + return true; + } else { + RegionManager manager = globalManager.get(location.getWorld()); + return manager == null || manager.getApplicableRegions(BukkitUtil.toVector(location)).allows(flag, localPlayer); + } + } + +} diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java index b1605983..82d4c088 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java @@ -53,6 +53,7 @@ import com.sk89q.worldguard.bukkit.listener.ChestProtectionListener; import com.sk89q.worldguard.bukkit.listener.DebuggingListener; import com.sk89q.worldguard.bukkit.listener.EventAbstractionListener; +import com.sk89q.worldguard.bukkit.listener.FlagStateManager; import com.sk89q.worldguard.bukkit.listener.RegionProtectionListener; import com.sk89q.worldguard.bukkit.listener.WorldGuardBlockListener; import com.sk89q.worldguard.bukkit.listener.WorldGuardCommandBookListener; @@ -69,7 +70,6 @@ import com.sk89q.worldguard.protection.util.migrator.MigrationException; import com.sk89q.worldguard.protection.util.migrator.UUIDMigrator; import com.sk89q.worldguard.util.FatalConfigurationLoadingException; -import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.World; @@ -109,8 +109,9 @@ public class WorldGuardPlugin extends JavaPlugin { private static WorldGuardPlugin inst; private final CommandsManager commands; - private GlobalRegionManager globalRegionManager; - private ConfigurationManager configuration; + private final ConfigurationManager configuration = new ConfigurationManager(this); + private final RegionContainer regionContainer = new RegionContainer(this); + private final GlobalRegionManager globalRegionManager = new GlobalRegionManager(this, regionContainer); private FlagStateManager flagStateManager; private final Supervisor supervisor = new SimpleSupervisor(); private ListeningExecutorService executorService; @@ -145,7 +146,8 @@ public static WorldGuardPlugin inst() { @Override @SuppressWarnings("deprecation") public void onEnable() { - configuration = new ConfigurationManager(this); + getDataFolder().mkdirs(); // Need to create the plugins/WorldGuard folder + executorService = MoreExecutors.listeningDecorator(EvenMoreExecutors.newBoundedCachedThreadPool(0, 1, 20)); // Set the proper command injector @@ -165,9 +167,6 @@ public void run() { } }, 0L); - // Need to create the plugins/WorldGuard folder - getDataFolder().mkdirs(); - File cacheDir = new File(getDataFolder(), "cache"); cacheDir.mkdirs(); try { @@ -190,8 +189,7 @@ public void run() { configuration.load(); getLogger().info("Loading region data..."); - globalRegionManager = new GlobalRegionManager(this); - globalRegionManager.loadAll(Bukkit.getServer().getWorlds()); + regionContainer.initialize(); migrateRegionUniqueIds(); // Migrate to UUIDs } catch (FatalConfigurationLoadingException e) { @@ -282,7 +280,7 @@ public void onDisable() { getLogger().log(Level.WARNING, "Some tasks failed while waiting for remaining tasks to finish", e); } - globalRegionManager.unloadAll(); + regionContainer.unload(); configuration.unload(); this.getServer().getScheduler().cancelTasks(this); } @@ -362,12 +360,23 @@ public String convertThrowable(@Nullable Throwable throwable) { /** * Get the GlobalRegionManager. * - * @return The plugin's global region manager + * @return the plugin's global region manager + * @deprecated use {@link #getRegionContainer()} */ + @Deprecated public GlobalRegionManager getGlobalRegionManager() { return globalRegionManager; } + /** + * Get the object that manages region data. + * + * @return the region container + */ + public RegionContainer getRegionContainer() { + return regionContainer; + } + /** * Get the WorldGuard Configuration. * diff --git a/src/main/java/com/sk89q/worldguard/bukkit/commands/RegionCommands.java b/src/main/java/com/sk89q/worldguard/bukkit/commands/RegionCommands.java index e4928023..e30423ea 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/commands/RegionCommands.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/commands/RegionCommands.java @@ -34,7 +34,7 @@ import com.sk89q.worldedit.bukkit.selections.Polygonal2DSelection; import com.sk89q.worldedit.bukkit.selections.Selection; import com.sk89q.worldguard.LocalPlayer; -import com.sk89q.worldguard.bukkit.LoggerToChatHandler; +import com.sk89q.worldguard.bukkit.util.LoggerToChatHandler; import com.sk89q.worldguard.bukkit.permission.RegionPermissionModel; import com.sk89q.worldguard.bukkit.WorldConfiguration; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; diff --git a/src/main/java/com/sk89q/worldguard/bukkit/commands/WorldGuardCommands.java b/src/main/java/com/sk89q/worldguard/bukkit/commands/WorldGuardCommands.java index 17e7dd7c..9812e0eb 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/commands/WorldGuardCommands.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/commands/WorldGuardCommands.java @@ -25,8 +25,8 @@ import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.odeum.task.Task; import com.sk89q.odeum.task.TaskStateComparator; -import com.sk89q.worldguard.bukkit.LoggerToChatHandler; -import com.sk89q.worldguard.bukkit.ReportWriter; +import com.sk89q.worldguard.bukkit.util.LoggerToChatHandler; +import com.sk89q.worldguard.bukkit.util.ReportWriter; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.util.PastebinPoster; import com.sk89q.worldguard.util.PastebinPoster.PasteCallback; @@ -78,9 +78,8 @@ public void reload(CommandContext args, CommandSender sender) throws CommandExce try { plugin.getGlobalStateManager().unload(); - plugin.getGlobalRegionManager().unloadAll(); + plugin.getRegionContainer().reload(); plugin.getGlobalStateManager().load(); - plugin.getGlobalRegionManager().loadAll(Bukkit.getServer().getWorlds()); // WGBukkit.cleanCache(); sender.sendMessage("WorldGuard configuration reloaded."); } catch (Throwable t) { diff --git a/src/main/java/com/sk89q/worldguard/bukkit/event/AbstractInteractEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/AbstractDelegateEvent.java similarity index 86% rename from src/main/java/com/sk89q/worldguard/bukkit/event/AbstractInteractEvent.java rename to src/main/java/com/sk89q/worldguard/bukkit/event/AbstractDelegateEvent.java index 0c4aa410..ce9ce635 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/event/AbstractInteractEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/AbstractDelegateEvent.java @@ -23,10 +23,13 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.Event; +import javax.annotation.Nullable; + import static com.google.common.base.Preconditions.checkNotNull; -public abstract class AbstractInteractEvent extends Event implements Cancellable { +public abstract class AbstractDelegateEvent extends Event implements Cancellable { + @Nullable private final Event originalEvent; private final Cause cause; private boolean cancelled; @@ -37,8 +40,7 @@ public abstract class AbstractInteractEvent extends Event implements Cancellable * @param originalEvent the original event * @param cause the cause */ - protected AbstractInteractEvent(Event originalEvent, Cause cause) { - checkNotNull(originalEvent); + protected AbstractDelegateEvent(@Nullable Event originalEvent, Cause cause) { checkNotNull(cause); this.originalEvent = originalEvent; this.cause = cause; @@ -47,8 +49,9 @@ protected AbstractInteractEvent(Event originalEvent, Cause cause) { /** * Get the original event. * - * @return the original event + * @return the original event, which may be {@code null} if unavailable */ + @Nullable public Event getOriginalEvent() { return originalEvent; } diff --git a/src/main/java/com/sk89q/worldguard/bukkit/event/block/AbstractBlockEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/block/AbstractBlockEvent.java index 1d01971d..6ebd57bf 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/event/block/AbstractBlockEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/block/AbstractBlockEvent.java @@ -20,7 +20,7 @@ package com.sk89q.worldguard.bukkit.event.block; import com.sk89q.worldguard.bukkit.cause.Cause; -import com.sk89q.worldguard.bukkit.event.AbstractInteractEvent; +import com.sk89q.worldguard.bukkit.event.AbstractDelegateEvent; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; @@ -30,14 +30,14 @@ import static com.google.common.base.Preconditions.checkNotNull; -abstract class AbstractBlockEvent extends AbstractInteractEvent { +abstract class AbstractBlockEvent extends AbstractDelegateEvent { private final Location target; @Nullable private final Block block; private final Material effectiveMaterial; - protected AbstractBlockEvent(Event originalEvent, Cause cause, Block block) { + protected AbstractBlockEvent(@Nullable Event originalEvent, Cause cause, Block block) { super(originalEvent, cause); checkNotNull(block); this.target = block.getLocation(); @@ -45,7 +45,7 @@ protected AbstractBlockEvent(Event originalEvent, Cause cause, Block block) { this.effectiveMaterial = block.getType(); } - protected AbstractBlockEvent(Event originalEvent, Cause cause, Location target, Material effectiveMaterial) { + protected AbstractBlockEvent(@Nullable Event originalEvent, Cause cause, Location target, Material effectiveMaterial) { super(originalEvent, cause); this.target = target; this.block = null; diff --git a/src/main/java/com/sk89q/worldguard/bukkit/event/block/BreakBlockEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/block/BreakBlockEvent.java index e3647c62..097eeaef 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/event/block/BreakBlockEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/block/BreakBlockEvent.java @@ -26,15 +26,17 @@ import org.bukkit.event.Event; import org.bukkit.event.HandlerList; +import javax.annotation.Nullable; + public class BreakBlockEvent extends AbstractBlockEvent { private static final HandlerList handlers = new HandlerList(); - public BreakBlockEvent(Event originalEvent, Cause cause, Block block) { + public BreakBlockEvent(@Nullable Event originalEvent, Cause cause, Block block) { super(originalEvent, cause, block); } - public BreakBlockEvent(Event originalEvent, Cause cause, Location target, Material effectiveMaterial) { + public BreakBlockEvent(@Nullable Event originalEvent, Cause cause, Location target, Material effectiveMaterial) { super(originalEvent, cause, target, effectiveMaterial); } diff --git a/src/main/java/com/sk89q/worldguard/bukkit/event/block/PlaceBlockEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/block/PlaceBlockEvent.java index 7a02a876..c6dd711d 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/event/block/PlaceBlockEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/block/PlaceBlockEvent.java @@ -26,15 +26,17 @@ import org.bukkit.event.Event; import org.bukkit.event.HandlerList; +import javax.annotation.Nullable; + public class PlaceBlockEvent extends AbstractBlockEvent { private static final HandlerList handlers = new HandlerList(); - public PlaceBlockEvent(Event originalEvent, Cause cause, Block block) { + public PlaceBlockEvent(@Nullable Event originalEvent, Cause cause, Block block) { super(originalEvent, cause, block); } - public PlaceBlockEvent(Event originalEvent, Cause cause, Location target, Material effectiveMaterial) { + public PlaceBlockEvent(@Nullable Event originalEvent, Cause cause, Location target, Material effectiveMaterial) { super(originalEvent, cause, target, effectiveMaterial); } diff --git a/src/main/java/com/sk89q/worldguard/bukkit/event/block/UseBlockEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/block/UseBlockEvent.java index bd22dbf0..5c581196 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/event/block/UseBlockEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/block/UseBlockEvent.java @@ -26,6 +26,8 @@ import org.bukkit.event.Event; import org.bukkit.event.HandlerList; +import javax.annotation.Nullable; + /** * Fired when a block is interacted with. */ @@ -33,11 +35,11 @@ public class UseBlockEvent extends AbstractBlockEvent { private static final HandlerList handlers = new HandlerList(); - public UseBlockEvent(Event originalEvent, Cause cause, Block block) { + public UseBlockEvent(@Nullable Event originalEvent, Cause cause, Block block) { super(originalEvent, cause, block); } - public UseBlockEvent(Event originalEvent, Cause cause, Location target, Material effectiveMaterial) { + public UseBlockEvent(@Nullable Event originalEvent, Cause cause, Location target, Material effectiveMaterial) { super(originalEvent, cause, target, effectiveMaterial); } diff --git a/src/main/java/com/sk89q/worldguard/bukkit/event/entity/AbstractEntityEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/entity/AbstractEntityEvent.java index 093325e8..83743552 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/event/entity/AbstractEntityEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/entity/AbstractEntityEvent.java @@ -20,7 +20,7 @@ package com.sk89q.worldguard.bukkit.event.entity; import com.sk89q.worldguard.bukkit.cause.Cause; -import com.sk89q.worldguard.bukkit.event.AbstractInteractEvent; +import com.sk89q.worldguard.bukkit.event.AbstractDelegateEvent; import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.event.Event; @@ -29,20 +29,20 @@ import static com.google.common.base.Preconditions.checkNotNull; -abstract class AbstractEntityEvent extends AbstractInteractEvent { +abstract class AbstractEntityEvent extends AbstractDelegateEvent { private final Location target; @Nullable private final Entity entity; - protected AbstractEntityEvent(Event originalEvent, Cause cause, Entity entity) { + protected AbstractEntityEvent(@Nullable Event originalEvent, Cause cause, Entity entity) { super(originalEvent, cause); checkNotNull(entity); this.target = entity.getLocation(); this.entity = entity; } - protected AbstractEntityEvent(Event originalEvent, Cause cause, Location target) { + protected AbstractEntityEvent(@Nullable Event originalEvent, Cause cause, Location target) { super(originalEvent, cause); checkNotNull(target); this.target = target; diff --git a/src/main/java/com/sk89q/worldguard/bukkit/event/entity/DestroyEntityEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/entity/DestroyEntityEvent.java index db53d8eb..fd2d4056 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/event/entity/DestroyEntityEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/entity/DestroyEntityEvent.java @@ -25,6 +25,7 @@ import org.bukkit.event.HandlerList; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import static com.google.common.base.Preconditions.checkNotNull; @@ -32,7 +33,7 @@ public class DestroyEntityEvent extends AbstractEntityEvent { private static final HandlerList handlers = new HandlerList(); - public DestroyEntityEvent(Event originalEvent, Cause cause, Entity target) { + public DestroyEntityEvent(@Nullable Event originalEvent, Cause cause, Entity target) { super(originalEvent, cause, checkNotNull(target)); } diff --git a/src/main/java/com/sk89q/worldguard/bukkit/event/entity/SpawnEntityEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/entity/SpawnEntityEvent.java index 05fee2f7..00817798 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/event/entity/SpawnEntityEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/entity/SpawnEntityEvent.java @@ -26,6 +26,8 @@ import org.bukkit.event.Event; import org.bukkit.event.HandlerList; +import javax.annotation.Nullable; + import static com.google.common.base.Preconditions.checkNotNull; public class SpawnEntityEvent extends AbstractEntityEvent { @@ -33,12 +35,12 @@ public class SpawnEntityEvent extends AbstractEntityEvent { private static final HandlerList handlers = new HandlerList(); private final EntityType effectiveType; - public SpawnEntityEvent(Event originalEvent, Cause cause, Entity target) { + public SpawnEntityEvent(@Nullable Event originalEvent, Cause cause, Entity target) { super(originalEvent, cause, checkNotNull(target)); this.effectiveType = target.getType(); } - public SpawnEntityEvent(Event originalEvent, Cause cause, Location location, EntityType type) { + public SpawnEntityEvent(@Nullable Event originalEvent, Cause cause, Location location, EntityType type) { super(originalEvent, cause, location); checkNotNull(type); this.effectiveType = type; diff --git a/src/main/java/com/sk89q/worldguard/bukkit/event/entity/UseEntityEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/entity/UseEntityEvent.java index 66b34282..9df27960 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/event/entity/UseEntityEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/entity/UseEntityEvent.java @@ -25,6 +25,7 @@ import org.bukkit.event.HandlerList; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import static com.google.common.base.Preconditions.checkNotNull; @@ -35,7 +36,7 @@ public class UseEntityEvent extends AbstractEntityEvent { private static final HandlerList handlers = new HandlerList(); - public UseEntityEvent(Event originalEvent, Cause cause, Entity target) { + public UseEntityEvent(@Nullable Event originalEvent, Cause cause, Entity target) { super(originalEvent, cause, checkNotNull(target)); } diff --git a/src/main/java/com/sk89q/worldguard/bukkit/event/inventory/UseItemEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/inventory/UseItemEvent.java index acd0185e..6dbb91ce 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/event/inventory/UseItemEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/inventory/UseItemEvent.java @@ -20,24 +20,26 @@ package com.sk89q.worldguard.bukkit.event.inventory; import com.sk89q.worldguard.bukkit.cause.Cause; -import com.sk89q.worldguard.bukkit.event.AbstractInteractEvent; +import com.sk89q.worldguard.bukkit.event.AbstractDelegateEvent; import org.bukkit.World; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.bukkit.inventory.ItemStack; +import javax.annotation.Nullable; + import static com.google.common.base.Preconditions.checkNotNull; /** * Fired when an item is interacted with. */ -public class UseItemEvent extends AbstractInteractEvent { +public class UseItemEvent extends AbstractDelegateEvent { private static final HandlerList handlers = new HandlerList(); private final World world; private final ItemStack itemStack; - public UseItemEvent(Event originalEvent, Cause cause, World world, ItemStack itemStack) { + public UseItemEvent(@Nullable Event originalEvent, Cause cause, World world, ItemStack itemStack) { super(originalEvent, cause); checkNotNull(world); checkNotNull(itemStack); diff --git a/src/main/java/com/sk89q/worldguard/bukkit/FlagStateManager.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/FlagStateManager.java similarity index 96% rename from src/main/java/com/sk89q/worldguard/bukkit/FlagStateManager.java rename to src/main/java/com/sk89q/worldguard/bukkit/listener/FlagStateManager.java index 9988a155..af6365c6 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/FlagStateManager.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/FlagStateManager.java @@ -1,252 +1,256 @@ -/* - * WorldGuard, a suite of tools for Minecraft - * Copyright (C) sk89q - * Copyright (C) WorldGuard team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser 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 Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldguard.bukkit; - -import com.sk89q.worldedit.Vector; -import com.sk89q.worldguard.protection.ApplicableRegionSet; -import com.sk89q.worldguard.protection.flags.DefaultFlag; -import com.sk89q.worldguard.protection.managers.RegionManager; -import org.bukkit.GameMode; -import org.bukkit.World; -import org.bukkit.entity.Player; - -import java.util.HashMap; -import java.util.Map; - -import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector; - -/** - * This processes per-player state information and is also meant to be used - * as a scheduled task. - * - * @author sk89q - */ -public class FlagStateManager implements Runnable { - - public static final int RUN_DELAY = 20; - - private WorldGuardPlugin plugin; - private Map states; - - /** - * Construct the object. - * - * @param plugin The plugin instance - */ - public FlagStateManager(WorldGuardPlugin plugin) { - this.plugin = plugin; - - states = new HashMap(); - } - - /** - * Run the task. - */ - @Override - public void run() { - Player[] players = plugin.getServer().getOnlinePlayers(); - ConfigurationManager config = plugin.getGlobalStateManager(); - - for (Player player : players) { - WorldConfiguration worldConfig = config.get(player.getWorld()); - - if (!worldConfig.useRegions) { - continue; - } - - PlayerFlagState state; - - synchronized (this) { - state = states.get(player.getName()); - - if (state == null) { - state = new PlayerFlagState(); - states.put(player.getName(), state); - } - } - - Vector playerLocation = toVector(player.getLocation()); - RegionManager regionManager = plugin.getGlobalRegionManager().get(player.getWorld()); - ApplicableRegionSet applicable = regionManager.getApplicableRegions(playerLocation); - - if (!RegionQueryUtil.isInvincible(plugin, player, applicable) - && !plugin.getGlobalStateManager().hasGodMode(player) - && !(player.getGameMode() == GameMode.CREATIVE)) { - processHeal(applicable, player, state); - processFeed(applicable, player, state); - } - } - } - - /** - * Process healing for a player. - * - * @param applicable The set of applicable regions - * @param player The player to process healing flags on - * @param state The player's state - */ - private void processHeal(ApplicableRegionSet applicable, Player player, - PlayerFlagState state) { - - if (player.getHealth() <= 0) { - return; - } - - long now = System.currentTimeMillis(); - - Integer healAmount = applicable.getFlag(DefaultFlag.HEAL_AMOUNT); - Integer healDelay = applicable.getFlag(DefaultFlag.HEAL_DELAY); - Double minHealth = applicable.getFlag(DefaultFlag.MIN_HEAL); - Double maxHealth = applicable.getFlag(DefaultFlag.MAX_HEAL); - - if (healAmount == null || healDelay == null || healAmount == 0 || healDelay < 0) { - return; - } - if (minHealth == null) { - minHealth = 0.0; - } - if (maxHealth == null) { - maxHealth = player.getMaxHealth(); - } - - // Apply a cap to prevent possible exceptions - minHealth = Math.min(player.getMaxHealth(), minHealth); - maxHealth = Math.min(player.getMaxHealth(), maxHealth); - - if (player.getHealth() >= maxHealth && healAmount > 0) { - return; - } - - if (healDelay <= 0) { - player.setHealth(healAmount > 0 ? maxHealth : minHealth); // this will insta-kill if the flag is unset - state.lastHeal = now; - } else if (now - state.lastHeal > healDelay * 1000) { - // clamp health between minimum and maximum - player.setHealth(Math.min(maxHealth, Math.max(minHealth, player.getHealth() + healAmount))); - state.lastHeal = now; - } - } - - /** - * Process restoring hunger for a player. - * - * @param applicable The set of applicable regions - * @param player The player to process hunger flags on - * @param state The player's state - */ - private void processFeed(ApplicableRegionSet applicable, Player player, - PlayerFlagState state) { - - long now = System.currentTimeMillis(); - - Integer feedAmount = applicable.getFlag(DefaultFlag.FEED_AMOUNT); - Integer feedDelay = applicable.getFlag(DefaultFlag.FEED_DELAY); - Integer minHunger = applicable.getFlag(DefaultFlag.MIN_FOOD); - Integer maxHunger = applicable.getFlag(DefaultFlag.MAX_FOOD); - - if (feedAmount == null || feedDelay == null || feedAmount == 0 || feedDelay < 0) { - return; - } - if (minHunger == null) { - minHunger = 0; - } - if (maxHunger == null) { - maxHunger = 20; - } - - // Apply a cap to prevent possible exceptions - minHunger = Math.min(20, minHunger); - maxHunger = Math.min(20, maxHunger); - - if (player.getFoodLevel() >= maxHunger && feedAmount > 0) { - return; - } - - if (feedDelay <= 0) { - player.setFoodLevel(feedAmount > 0 ? maxHunger : minHunger); - player.setSaturation(player.getFoodLevel()); - state.lastFeed = now; - } else if (now - state.lastFeed > feedDelay * 1000) { - // clamp health between minimum and maximum - player.setFoodLevel(Math.min(maxHunger, Math.max(minHunger, player.getFoodLevel() + feedAmount))); - player.setSaturation(player.getFoodLevel()); - state.lastFeed = now; - } - } - - /** - * Forget a player. - * - * @param player The player to forget - */ - public synchronized void forget(Player player) { - states.remove(player.getName()); - } - - /** - * Forget all managed players. Use with caution. - */ - public synchronized void forgetAll() { - states.clear(); - } - - /** - * Get a player's flag state. A new state will be created if there is no existing - * state for the player. - * - * @param player The player to get a state for - * @return The {@code player}'s state - */ - public synchronized PlayerFlagState getState(Player player) { - PlayerFlagState state = states.get(player.getName()); - - if (state == null) { - state = new PlayerFlagState(); - states.put(player.getName(), state); - } - - return state; - } - - /** - * Keeps state per player. - */ - public static class PlayerFlagState { - public long lastHeal; - public long lastFeed; - public String lastGreeting; - public String lastFarewell; - public Boolean lastExitAllowed = null; - public Boolean notifiedForLeave = false; - public Boolean notifiedForEnter = false; - public GameMode lastGameMode; - public World lastWorld; - public int lastBlockX; - public int lastBlockY; - public int lastBlockZ; - - /* Used to cache invincibility status */ - public World lastInvincibleWorld; - public int lastInvincibleX; - public int lastInvincibleY; - public int lastInvincibleZ; - public boolean wasInvincible; - } -} +/* + * WorldGuard, a suite of tools for Minecraft + * Copyright (C) sk89q + * Copyright (C) WorldGuard team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldguard.bukkit.listener; + +import com.sk89q.worldedit.Vector; +import com.sk89q.worldguard.bukkit.ConfigurationManager; +import com.sk89q.worldguard.bukkit.util.RegionQueryUtil; +import com.sk89q.worldguard.bukkit.WorldConfiguration; +import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import com.sk89q.worldguard.protection.ApplicableRegionSet; +import com.sk89q.worldguard.protection.flags.DefaultFlag; +import com.sk89q.worldguard.protection.managers.RegionManager; +import org.bukkit.GameMode; +import org.bukkit.World; +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.Map; + +import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector; + +/** + * This processes per-player state information and is also meant to be used + * as a scheduled task. + * + * @author sk89q + */ +public class FlagStateManager implements Runnable { + + public static final int RUN_DELAY = 20; + + private WorldGuardPlugin plugin; + private Map states; + + /** + * Construct the object. + * + * @param plugin The plugin instance + */ + public FlagStateManager(WorldGuardPlugin plugin) { + this.plugin = plugin; + + states = new HashMap(); + } + + /** + * Run the task. + */ + @Override + public void run() { + Player[] players = plugin.getServer().getOnlinePlayers(); + ConfigurationManager config = plugin.getGlobalStateManager(); + + for (Player player : players) { + WorldConfiguration worldConfig = config.get(player.getWorld()); + + if (!worldConfig.useRegions) { + continue; + } + + PlayerFlagState state; + + synchronized (this) { + state = states.get(player.getName()); + + if (state == null) { + state = new PlayerFlagState(); + states.put(player.getName(), state); + } + } + + Vector playerLocation = toVector(player.getLocation()); + RegionManager regionManager = plugin.getGlobalRegionManager().get(player.getWorld()); + ApplicableRegionSet applicable = regionManager.getApplicableRegions(playerLocation); + + if (!RegionQueryUtil.isInvincible(plugin, player, applicable) + && !plugin.getGlobalStateManager().hasGodMode(player) + && !(player.getGameMode() == GameMode.CREATIVE)) { + processHeal(applicable, player, state); + processFeed(applicable, player, state); + } + } + } + + /** + * Process healing for a player. + * + * @param applicable The set of applicable regions + * @param player The player to process healing flags on + * @param state The player's state + */ + private void processHeal(ApplicableRegionSet applicable, Player player, + PlayerFlagState state) { + + if (player.getHealth() <= 0) { + return; + } + + long now = System.currentTimeMillis(); + + Integer healAmount = applicable.getFlag(DefaultFlag.HEAL_AMOUNT); + Integer healDelay = applicable.getFlag(DefaultFlag.HEAL_DELAY); + Double minHealth = applicable.getFlag(DefaultFlag.MIN_HEAL); + Double maxHealth = applicable.getFlag(DefaultFlag.MAX_HEAL); + + if (healAmount == null || healDelay == null || healAmount == 0 || healDelay < 0) { + return; + } + if (minHealth == null) { + minHealth = 0.0; + } + if (maxHealth == null) { + maxHealth = player.getMaxHealth(); + } + + // Apply a cap to prevent possible exceptions + minHealth = Math.min(player.getMaxHealth(), minHealth); + maxHealth = Math.min(player.getMaxHealth(), maxHealth); + + if (player.getHealth() >= maxHealth && healAmount > 0) { + return; + } + + if (healDelay <= 0) { + player.setHealth(healAmount > 0 ? maxHealth : minHealth); // this will insta-kill if the flag is unset + state.lastHeal = now; + } else if (now - state.lastHeal > healDelay * 1000) { + // clamp health between minimum and maximum + player.setHealth(Math.min(maxHealth, Math.max(minHealth, player.getHealth() + healAmount))); + state.lastHeal = now; + } + } + + /** + * Process restoring hunger for a player. + * + * @param applicable The set of applicable regions + * @param player The player to process hunger flags on + * @param state The player's state + */ + private void processFeed(ApplicableRegionSet applicable, Player player, + PlayerFlagState state) { + + long now = System.currentTimeMillis(); + + Integer feedAmount = applicable.getFlag(DefaultFlag.FEED_AMOUNT); + Integer feedDelay = applicable.getFlag(DefaultFlag.FEED_DELAY); + Integer minHunger = applicable.getFlag(DefaultFlag.MIN_FOOD); + Integer maxHunger = applicable.getFlag(DefaultFlag.MAX_FOOD); + + if (feedAmount == null || feedDelay == null || feedAmount == 0 || feedDelay < 0) { + return; + } + if (minHunger == null) { + minHunger = 0; + } + if (maxHunger == null) { + maxHunger = 20; + } + + // Apply a cap to prevent possible exceptions + minHunger = Math.min(20, minHunger); + maxHunger = Math.min(20, maxHunger); + + if (player.getFoodLevel() >= maxHunger && feedAmount > 0) { + return; + } + + if (feedDelay <= 0) { + player.setFoodLevel(feedAmount > 0 ? maxHunger : minHunger); + player.setSaturation(player.getFoodLevel()); + state.lastFeed = now; + } else if (now - state.lastFeed > feedDelay * 1000) { + // clamp health between minimum and maximum + player.setFoodLevel(Math.min(maxHunger, Math.max(minHunger, player.getFoodLevel() + feedAmount))); + player.setSaturation(player.getFoodLevel()); + state.lastFeed = now; + } + } + + /** + * Forget a player. + * + * @param player The player to forget + */ + public synchronized void forget(Player player) { + states.remove(player.getName()); + } + + /** + * Forget all managed players. Use with caution. + */ + public synchronized void forgetAll() { + states.clear(); + } + + /** + * Get a player's flag state. A new state will be created if there is no existing + * state for the player. + * + * @param player The player to get a state for + * @return The {@code player}'s state + */ + public synchronized PlayerFlagState getState(Player player) { + PlayerFlagState state = states.get(player.getName()); + + if (state == null) { + state = new PlayerFlagState(); + states.put(player.getName(), state); + } + + return state; + } + + /** + * Keeps state per player. + */ + public static class PlayerFlagState { + public long lastHeal; + public long lastFeed; + public String lastGreeting; + public String lastFarewell; + public Boolean lastExitAllowed = null; + public Boolean notifiedForLeave = false; + public Boolean notifiedForEnter = false; + public GameMode lastGameMode; + public World lastWorld; + public int lastBlockX; + public int lastBlockY; + public int lastBlockZ; + + /* Used to cache invincibility status */ + public World lastInvincibleWorld; + public int lastInvincibleX; + public int lastInvincibleY; + public int lastInvincibleZ; + public boolean wasInvincible; + } +} diff --git a/src/main/java/com/sk89q/worldguard/bukkit/listener/RegionProtectionListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/RegionProtectionListener.java index 66300fe3..2eec00ed 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/listener/RegionProtectionListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/RegionProtectionListener.java @@ -19,7 +19,7 @@ package com.sk89q.worldguard.bukkit.listener; -import com.sk89q.worldedit.Vector2D; +import com.sk89q.worldguard.bukkit.RegionQuery; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.bukkit.event.block.BreakBlockEvent; import com.sk89q.worldguard.bukkit.event.block.PlaceBlockEvent; @@ -29,21 +29,14 @@ 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.ProtectedRegionQuery; import com.sk89q.worldguard.protection.flags.DefaultFlag; -import com.sk89q.worldguard.protection.managers.RegionManager; import org.bukkit.ChatColor; -import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.command.CommandSender; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; -import org.bukkit.event.world.ChunkLoadEvent; -import org.bukkit.event.world.ChunkUnloadEvent; -import org.bukkit.event.world.WorldLoadEvent; -import org.bukkit.event.world.WorldUnloadEvent; /** * Handle events that need to be processed by region protection. @@ -63,34 +56,6 @@ private void tellErrorMessage(CommandSender sender, Object subject) { sender.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area."); } - @EventHandler - public void onWorldLoad(WorldLoadEvent event) { - getPlugin().getGlobalRegionManager().load(event.getWorld()); - } - - @EventHandler - public void onWorldUnload(WorldUnloadEvent event) { - getPlugin().getGlobalRegionManager().unload(event.getWorld()); - } - - @EventHandler - public void onChunkLoad(ChunkLoadEvent event) { - RegionManager manager = getPlugin().getGlobalRegionManager().get(event.getWorld()); - if (manager != null) { - Chunk chunk = event.getChunk(); - manager.loadChunk(new Vector2D(chunk.getX(), chunk.getZ())); - } - } - - @EventHandler - public void onChunkUnload(ChunkUnloadEvent event) { - RegionManager manager = getPlugin().getGlobalRegionManager().get(event.getWorld()); - if (manager != null) { - Chunk chunk = event.getChunk(); - manager.unloadChunk(new Vector2D(chunk.getX(), chunk.getZ())); - } - } - @EventHandler(ignoreCancelled = true) public void onPlaceBlock(PlaceBlockEvent event) { Player player = event.getCause().getPlayerRootCause(); @@ -98,15 +63,15 @@ public void onPlaceBlock(PlaceBlockEvent event) { Material type = event.getEffectiveMaterial(); if (player != null) { - ProtectedRegionQuery query = new ProtectedRegionQuery(getPlugin(), player); + RegionQuery query = getPlugin().getRegionContainer().createQuery(player); boolean canPlace; // Flint and steel, fire charge if (type == Material.FIRE) { - canPlace = query.allows(DefaultFlag.LIGHTER, target) || (query.canBuild(target) && query.canConstruct(target)); + canPlace = query.testPermission(target, DefaultFlag.LIGHTER); } else { - canPlace = query.canBuild(target) && query.canConstruct(target); + canPlace = query.testPermission(target); } if (!canPlace) { @@ -139,30 +104,24 @@ public void onUseBlock(UseBlockEvent event) { Material type = event.getEffectiveMaterial(); if (player != null) { - ProtectedRegionQuery query = new ProtectedRegionQuery(getPlugin(), player); + RegionQuery query = getPlugin().getRegionContainer().createQuery(player); boolean canUse; // Inventory blocks (CHEST_ACCESS) if (Materials.isInventoryBlock(type)) { - canUse = query.canBuild( target) - || query.allows(DefaultFlag.CHEST_ACCESS, target) - || query.allows(DefaultFlag.USE, target); + canUse = query.testPermission(target, DefaultFlag.USE, DefaultFlag.CHEST_ACCESS); // Beds (SLEEP) } else if (type == Material.BED) { - canUse = query.canBuild(target) - || query.allows(DefaultFlag.SLEEP, target) - || query.allows(DefaultFlag.USE, target); + canUse = query.testPermission(target, DefaultFlag.USE, DefaultFlag.SLEEP); // TNT (TNT) } else if (type == Material.TNT) { - canUse = query.canBuild(target) - || query.allows(DefaultFlag.TNT, target); + canUse = query.testPermission(target, DefaultFlag.TNT); // Everything else } else { - canUse = query.canBuild(target) - || query.allows(DefaultFlag.USE, target); + canUse = query.testPermission(target, DefaultFlag.USE); } if (!canUse) { @@ -179,13 +138,13 @@ public void onSpawnEntity(SpawnEntityEvent event) { EntityType type = event.getEffectiveType(); if (player != null) { - ProtectedRegionQuery query = new ProtectedRegionQuery(getPlugin(), player); + RegionQuery query = getPlugin().getRegionContainer().createQuery(player); boolean canSpawn; if (Entities.isVehicle(type)) { - canSpawn = query.canBuild(target) || query.allows(DefaultFlag.PLACE_VEHICLE, target); + canSpawn = query.testPermission(target, DefaultFlag.PLACE_VEHICLE); } else { - canSpawn = query.canBuild(target); + canSpawn = query.testPermission(target); } if (!canSpawn) { @@ -202,13 +161,13 @@ public void onDestroyEntity(DestroyEntityEvent event) { EntityType type = event.getEntity().getType(); if (player != null) { - ProtectedRegionQuery query = new ProtectedRegionQuery(getPlugin(), player); + RegionQuery query = getPlugin().getRegionContainer().createQuery(player); boolean canDestroy; if (Entities.isVehicle(type)) { - canDestroy = query.canBuild(target) || query.allows(DefaultFlag.DESTROY_VEHICLE, target); + canDestroy = query.testPermission(target, DefaultFlag.DESTROY_VEHICLE); } else { - canDestroy = query.canBuild(target); + canDestroy = query.testPermission(target); } if (!canDestroy) { @@ -224,8 +183,8 @@ public void onUseEntity(UseEntityEvent event) { Location target = event.getTarget(); if (player != null) { - ProtectedRegionQuery query = new ProtectedRegionQuery(getPlugin(), player); - boolean canUse = query.canBuild(target) || query.allows(DefaultFlag.USE, target); + RegionQuery query = getPlugin().getRegionContainer().createQuery(player); + boolean canUse = query.testPermission(target, DefaultFlag.USE); if (!canUse) { tellErrorMessage(player, target); diff --git a/src/main/java/com/sk89q/worldguard/bukkit/SpongeUtil.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/SpongeUtil.java similarity index 96% rename from src/main/java/com/sk89q/worldguard/bukkit/SpongeUtil.java rename to src/main/java/com/sk89q/worldguard/bukkit/listener/SpongeUtil.java index c596630c..c5b52a67 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/SpongeUtil.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/SpongeUtil.java @@ -1,129 +1,132 @@ -/* - * WorldGuard, a suite of tools for Minecraft - * Copyright (C) sk89q - * Copyright (C) WorldGuard team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser 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 Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldguard.bukkit; - -import org.bukkit.World; - -import static com.sk89q.worldguard.bukkit.BukkitUtil.isBlockWater; -import static com.sk89q.worldguard.bukkit.BukkitUtil.setBlockToWater; - -public final class SpongeUtil { - - private SpongeUtil() { - } - - /** - * Remove water around a sponge. - * - * @param plugin The plugin instace - * @param world The world the sponge isin - * @param ox The x coordinate of the 'sponge' block - * @param oy The y coordinate of the 'sponge' block - * @param oz The z coordinate of the 'sponge' block - */ - public static void clearSpongeWater(WorldGuardPlugin plugin, World world, int ox, int oy, int oz) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(world); - - for (int cx = -wcfg.spongeRadius; cx <= wcfg.spongeRadius; cx++) { - for (int cy = -wcfg.spongeRadius; cy <= wcfg.spongeRadius; cy++) { - for (int cz = -wcfg.spongeRadius; cz <= wcfg.spongeRadius; cz++) { - if (isBlockWater(world, ox + cx, oy + cy, oz + cz)) { - world.getBlockAt(ox + cx, oy + cy, oz + cz).setTypeId(0); - } - } - } - } - } - - /** - * Add water around a sponge. - * - * @param plugin The plugin instance - * @param world The world the sponge is located in - * @param ox The x coordinate of the 'sponge' block - * @param oy The y coordinate of the 'sponge' block - * @param oz The z coordinate of the 'sponge' block - */ - public static void addSpongeWater(WorldGuardPlugin plugin, World world, int ox, int oy, int oz) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(world); - - // The negative x edge - int cx = ox - wcfg.spongeRadius - 1; - for (int cy = oy - wcfg.spongeRadius - 1; cy <= oy + wcfg.spongeRadius + 1; cy++) { - for (int cz = oz - wcfg.spongeRadius - 1; cz <= oz + wcfg.spongeRadius + 1; cz++) { - if (isBlockWater(world, cx, cy, cz)) { - setBlockToWater(world, cx + 1, cy, cz); - } - } - } - - // The positive x edge - cx = ox + wcfg.spongeRadius + 1; - for (int cy = oy - wcfg.spongeRadius - 1; cy <= oy + wcfg.spongeRadius + 1; cy++) { - for (int cz = oz - wcfg.spongeRadius - 1; cz <= oz + wcfg.spongeRadius + 1; cz++) { - if (isBlockWater(world, cx, cy, cz)) { - setBlockToWater(world, cx - 1, cy, cz); - } - } - } - - // The negative y edge - int cy = oy - wcfg.spongeRadius - 1; - for (cx = ox - wcfg.spongeRadius - 1; cx <= ox + wcfg.spongeRadius + 1; cx++) { - for (int cz = oz - wcfg.spongeRadius - 1; cz <= oz + wcfg.spongeRadius + 1; cz++) { - if (isBlockWater(world, cx, cy, cz)) { - setBlockToWater(world, cx, cy + 1, cz); - } - } - } - - // The positive y edge - cy = oy + wcfg.spongeRadius + 1; - for (cx = ox - wcfg.spongeRadius - 1; cx <= ox + wcfg.spongeRadius + 1; cx++) { - for (int cz = oz - wcfg.spongeRadius - 1; cz <= oz + wcfg.spongeRadius + 1; cz++) { - if (isBlockWater(world, cx, cy, cz)) { - setBlockToWater(world, cx, cy - 1, cz); - } - } - } - - // The negative z edge - int cz = oz - wcfg.spongeRadius - 1; - for (cx = ox - wcfg.spongeRadius - 1; cx <= ox + wcfg.spongeRadius + 1; cx++) { - for (cy = oy - wcfg.spongeRadius - 1; cy <= oy + wcfg.spongeRadius + 1; cy++) { - if (isBlockWater(world, cx, cy, cz)) { - setBlockToWater(world, cx, cy, cz + 1); - } - } - } - - // The positive z edge - cz = oz + wcfg.spongeRadius + 1; - for (cx = ox - wcfg.spongeRadius - 1; cx <= ox + wcfg.spongeRadius + 1; cx++) { - for (cy = oy - wcfg.spongeRadius - 1; cy <= oy + wcfg.spongeRadius + 1; cy++) { - if (isBlockWater(world, cx, cy, cz)) { - setBlockToWater(world, cx, cy, cz - 1); - } - } - } - } -} +/* + * WorldGuard, a suite of tools for Minecraft + * Copyright (C) sk89q + * Copyright (C) WorldGuard team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldguard.bukkit.listener; + +import com.sk89q.worldguard.bukkit.ConfigurationManager; +import com.sk89q.worldguard.bukkit.WorldConfiguration; +import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import org.bukkit.World; + +import static com.sk89q.worldguard.bukkit.BukkitUtil.isBlockWater; +import static com.sk89q.worldguard.bukkit.BukkitUtil.setBlockToWater; + +public final class SpongeUtil { + + private SpongeUtil() { + } + + /** + * Remove water around a sponge. + * + * @param plugin The plugin instace + * @param world The world the sponge isin + * @param ox The x coordinate of the 'sponge' block + * @param oy The y coordinate of the 'sponge' block + * @param oz The z coordinate of the 'sponge' block + */ + public static void clearSpongeWater(WorldGuardPlugin plugin, World world, int ox, int oy, int oz) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(world); + + for (int cx = -wcfg.spongeRadius; cx <= wcfg.spongeRadius; cx++) { + for (int cy = -wcfg.spongeRadius; cy <= wcfg.spongeRadius; cy++) { + for (int cz = -wcfg.spongeRadius; cz <= wcfg.spongeRadius; cz++) { + if (isBlockWater(world, ox + cx, oy + cy, oz + cz)) { + world.getBlockAt(ox + cx, oy + cy, oz + cz).setTypeId(0); + } + } + } + } + } + + /** + * Add water around a sponge. + * + * @param plugin The plugin instance + * @param world The world the sponge is located in + * @param ox The x coordinate of the 'sponge' block + * @param oy The y coordinate of the 'sponge' block + * @param oz The z coordinate of the 'sponge' block + */ + public static void addSpongeWater(WorldGuardPlugin plugin, World world, int ox, int oy, int oz) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(world); + + // The negative x edge + int cx = ox - wcfg.spongeRadius - 1; + for (int cy = oy - wcfg.spongeRadius - 1; cy <= oy + wcfg.spongeRadius + 1; cy++) { + for (int cz = oz - wcfg.spongeRadius - 1; cz <= oz + wcfg.spongeRadius + 1; cz++) { + if (isBlockWater(world, cx, cy, cz)) { + setBlockToWater(world, cx + 1, cy, cz); + } + } + } + + // The positive x edge + cx = ox + wcfg.spongeRadius + 1; + for (int cy = oy - wcfg.spongeRadius - 1; cy <= oy + wcfg.spongeRadius + 1; cy++) { + for (int cz = oz - wcfg.spongeRadius - 1; cz <= oz + wcfg.spongeRadius + 1; cz++) { + if (isBlockWater(world, cx, cy, cz)) { + setBlockToWater(world, cx - 1, cy, cz); + } + } + } + + // The negative y edge + int cy = oy - wcfg.spongeRadius - 1; + for (cx = ox - wcfg.spongeRadius - 1; cx <= ox + wcfg.spongeRadius + 1; cx++) { + for (int cz = oz - wcfg.spongeRadius - 1; cz <= oz + wcfg.spongeRadius + 1; cz++) { + if (isBlockWater(world, cx, cy, cz)) { + setBlockToWater(world, cx, cy + 1, cz); + } + } + } + + // The positive y edge + cy = oy + wcfg.spongeRadius + 1; + for (cx = ox - wcfg.spongeRadius - 1; cx <= ox + wcfg.spongeRadius + 1; cx++) { + for (int cz = oz - wcfg.spongeRadius - 1; cz <= oz + wcfg.spongeRadius + 1; cz++) { + if (isBlockWater(world, cx, cy, cz)) { + setBlockToWater(world, cx, cy - 1, cz); + } + } + } + + // The negative z edge + int cz = oz - wcfg.spongeRadius - 1; + for (cx = ox - wcfg.spongeRadius - 1; cx <= ox + wcfg.spongeRadius + 1; cx++) { + for (cy = oy - wcfg.spongeRadius - 1; cy <= oy + wcfg.spongeRadius + 1; cy++) { + if (isBlockWater(world, cx, cy, cz)) { + setBlockToWater(world, cx, cy, cz + 1); + } + } + } + + // The positive z edge + cz = oz + wcfg.spongeRadius + 1; + for (cx = ox - wcfg.spongeRadius - 1; cx <= ox + wcfg.spongeRadius + 1; cx++) { + for (cy = oy - wcfg.spongeRadius - 1; cy <= oy + wcfg.spongeRadius + 1; cy++) { + if (isBlockWater(world, cx, cy, cz)) { + setBlockToWater(world, cx, cy, cz - 1); + } + } + } + } +} diff --git a/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardBlockListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardBlockListener.java index ef0c69cf..d29e8594 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardBlockListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardBlockListener.java @@ -24,7 +24,6 @@ import com.sk89q.worldedit.blocks.BlockType; import com.sk89q.worldedit.blocks.ItemType; import com.sk89q.worldguard.bukkit.ConfigurationManager; -import com.sk89q.worldguard.bukkit.SpongeUtil; import com.sk89q.worldguard.bukkit.WorldConfiguration; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.protection.ApplicableRegionSet; diff --git a/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardEntityListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardEntityListener.java index b052f72f..aa30e18a 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardEntityListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardEntityListener.java @@ -24,7 +24,7 @@ import com.sk89q.worldguard.LocalPlayer; import com.sk89q.worldguard.bukkit.BukkitUtil; import com.sk89q.worldguard.bukkit.ConfigurationManager; -import com.sk89q.worldguard.bukkit.RegionQueryUtil; +import com.sk89q.worldguard.bukkit.util.RegionQueryUtil; import com.sk89q.worldguard.bukkit.WorldConfiguration; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.protection.ApplicableRegionSet; diff --git a/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardPlayerListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardPlayerListener.java index 6b4ce0eb..bdd08b3b 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardPlayerListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardPlayerListener.java @@ -22,10 +22,9 @@ import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.BlockID; import com.sk89q.worldguard.LocalPlayer; -import com.sk89q.worldguard.blacklist.event.ItemUseBlacklistEvent; import com.sk89q.worldguard.bukkit.BukkitUtil; import com.sk89q.worldguard.bukkit.ConfigurationManager; -import com.sk89q.worldguard.bukkit.FlagStateManager.PlayerFlagState; +import com.sk89q.worldguard.bukkit.listener.FlagStateManager.PlayerFlagState; import com.sk89q.worldguard.bukkit.WorldConfiguration; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.protection.ApplicableRegionSet; @@ -50,7 +49,6 @@ import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerFishEvent; import org.bukkit.event.player.PlayerGameModeChangeEvent; -import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerItemHeldEvent; import org.bukkit.event.player.PlayerJoinEvent; diff --git a/src/main/java/com/sk89q/worldguard/bukkit/LoggerToChatHandler.java b/src/main/java/com/sk89q/worldguard/bukkit/util/LoggerToChatHandler.java similarity index 97% rename from src/main/java/com/sk89q/worldguard/bukkit/LoggerToChatHandler.java rename to src/main/java/com/sk89q/worldguard/bukkit/util/LoggerToChatHandler.java index 5bf5c60a..c735fc85 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/LoggerToChatHandler.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/util/LoggerToChatHandler.java @@ -17,14 +17,14 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.bukkit; - -import java.util.logging.Handler; -import java.util.logging.LogRecord; +package com.sk89q.worldguard.bukkit.util; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; +import java.util.logging.Handler; +import java.util.logging.LogRecord; + /** * Sends all logger messages to a player. * diff --git a/src/main/java/com/sk89q/worldguard/bukkit/util/ProtectedRegionQuery.java b/src/main/java/com/sk89q/worldguard/bukkit/util/ProtectedRegionQuery.java deleted file mode 100644 index 9d26992a..00000000 --- a/src/main/java/com/sk89q/worldguard/bukkit/util/ProtectedRegionQuery.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * WorldGuard, a suite of tools for Minecraft - * Copyright (C) sk89q - * Copyright (C) WorldGuard team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser 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 Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldguard.bukkit.util; - -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.protection.ApplicableRegionSet; -import com.sk89q.worldguard.protection.GlobalRegionManager; -import com.sk89q.worldguard.protection.flags.StateFlag; -import com.sk89q.worldguard.protection.managers.RegionManager; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.entity.Player; - -import javax.annotation.Nullable; - -import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector; - -public class ProtectedRegionQuery { - - private final ConfigurationManager config; - private final GlobalRegionManager globalManager; - @Nullable - private final LocalPlayer localPlayer; - - 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; - } - - public boolean canBuild(Location location) { - World world = location.getWorld(); - WorldConfiguration worldConfig = config.get(world); - - if (!worldConfig.useRegions) { - return true; - } - - if (localPlayer != null && globalManager.hasBypass(localPlayer, world)) { - return true; - } else { - RegionManager manager = globalManager.get(location.getWorld()); - return manager.getApplicableRegions(BukkitUtil.toVector(location)).canBuild(localPlayer); - } - } - - public boolean canConstruct(Location location) { - World world = location.getWorld(); - WorldConfiguration worldConfig = config.get(world); - - if (!worldConfig.useRegions) { - return true; - } - - if (localPlayer != null && globalManager.hasBypass(localPlayer, world)) { - return true; - } else { - RegionManager manager = globalManager.get(location.getWorld()); - ApplicableRegionSet result = manager.getApplicableRegions(BukkitUtil.toVector(location)); - return result.canBuild(localPlayer) && result.canConstruct(localPlayer); - } - } - - public boolean allows(StateFlag flag, Location location) { - World world = location.getWorld(); - WorldConfiguration worldConfig = config.get(world); - - if (!worldConfig.useRegions) { - return true; - } - - RegionManager manager = globalManager.get(location.getWorld()); - return manager.getApplicableRegions(toVector(location)).allows(flag, localPlayer); - } - -} diff --git a/src/main/java/com/sk89q/worldguard/bukkit/RegionQueryUtil.java b/src/main/java/com/sk89q/worldguard/bukkit/util/RegionQueryUtil.java similarity index 95% rename from src/main/java/com/sk89q/worldguard/bukkit/RegionQueryUtil.java rename to src/main/java/com/sk89q/worldguard/bukkit/util/RegionQueryUtil.java index 5ddb3f3b..c60ea076 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/RegionQueryUtil.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/util/RegionQueryUtil.java @@ -1,86 +1,88 @@ -/* - * WorldGuard, a suite of tools for Minecraft - * Copyright (C) sk89q - * Copyright (C) WorldGuard team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser 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 Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldguard.bukkit; - -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.entity.Player; - -import com.sk89q.worldedit.Vector; -import com.sk89q.worldguard.protection.ApplicableRegionSet; -import com.sk89q.worldguard.protection.flags.DefaultFlag; -import com.sk89q.worldguard.protection.flags.StateFlag; -import com.sk89q.worldguard.protection.managers.RegionManager; - -public final class RegionQueryUtil { - - private RegionQueryUtil() { - } - - public static boolean isInvincible(WorldGuardPlugin plugin, Player player) { - return isInvincible(plugin, player, null); - } - - public static boolean isInvincible(WorldGuardPlugin plugin, Player player, - ApplicableRegionSet set) { - Location loc = player.getLocation(); - World world = player.getWorld(); - - FlagStateManager.PlayerFlagState state = plugin.getFlagStateManager().getState(player); - - if (state.lastInvincibleWorld == null || - !state.lastInvincibleWorld.equals(world) || - state.lastInvincibleX != loc.getBlockX() || - state.lastInvincibleY != loc.getBlockY() || - state.lastInvincibleZ != loc.getBlockZ()) { - state.lastInvincibleX = loc.getBlockX(); - state.lastInvincibleY = loc.getBlockY(); - state.lastInvincibleZ = loc.getBlockZ(); - state.lastInvincibleWorld = world; - - if (set == null) { - Vector vec = new Vector(state.lastInvincibleX, - state.lastInvincibleY, state.lastInvincibleZ); - RegionManager mgr = plugin.getGlobalRegionManager().get(world); - set = mgr.getApplicableRegions(vec); - } - - state.wasInvincible = set.allows(DefaultFlag.INVINCIBILITY, plugin.wrapPlayer(player)); - } - - return state.wasInvincible; - } - - public static Boolean isAllowedInvinciblity(WorldGuardPlugin plugin, Player player) { - World world = player.getWorld(); - FlagStateManager.PlayerFlagState state = plugin.getFlagStateManager().getState(player); - Vector vec = new Vector(state.lastInvincibleX, state.lastInvincibleY, state.lastInvincibleZ); - - StateFlag.State regionState = plugin.getGlobalRegionManager().get(world). - getApplicableRegions(vec).getFlag(DefaultFlag.INVINCIBILITY, plugin.wrapPlayer(player)); - if (regionState == StateFlag.State.ALLOW) { - return Boolean.TRUE; - } else if (regionState == StateFlag.State.DENY) { - return Boolean.FALSE; - } else { - return null; - } - } -} +/* + * WorldGuard, a suite of tools for Minecraft + * Copyright (C) sk89q + * Copyright (C) WorldGuard team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldguard.bukkit.util; + +import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import com.sk89q.worldguard.bukkit.listener.FlagStateManager; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; + +import com.sk89q.worldedit.Vector; +import com.sk89q.worldguard.protection.ApplicableRegionSet; +import com.sk89q.worldguard.protection.flags.DefaultFlag; +import com.sk89q.worldguard.protection.flags.StateFlag; +import com.sk89q.worldguard.protection.managers.RegionManager; + +public final class RegionQueryUtil { + + private RegionQueryUtil() { + } + + public static boolean isInvincible(WorldGuardPlugin plugin, Player player) { + return isInvincible(plugin, player, null); + } + + public static boolean isInvincible(WorldGuardPlugin plugin, Player player, + ApplicableRegionSet set) { + Location loc = player.getLocation(); + World world = player.getWorld(); + + FlagStateManager.PlayerFlagState state = plugin.getFlagStateManager().getState(player); + + if (state.lastInvincibleWorld == null || + !state.lastInvincibleWorld.equals(world) || + state.lastInvincibleX != loc.getBlockX() || + state.lastInvincibleY != loc.getBlockY() || + state.lastInvincibleZ != loc.getBlockZ()) { + state.lastInvincibleX = loc.getBlockX(); + state.lastInvincibleY = loc.getBlockY(); + state.lastInvincibleZ = loc.getBlockZ(); + state.lastInvincibleWorld = world; + + if (set == null) { + Vector vec = new Vector(state.lastInvincibleX, + state.lastInvincibleY, state.lastInvincibleZ); + RegionManager mgr = plugin.getGlobalRegionManager().get(world); + set = mgr.getApplicableRegions(vec); + } + + state.wasInvincible = set.allows(DefaultFlag.INVINCIBILITY, plugin.wrapPlayer(player)); + } + + return state.wasInvincible; + } + + public static Boolean isAllowedInvinciblity(WorldGuardPlugin plugin, Player player) { + World world = player.getWorld(); + FlagStateManager.PlayerFlagState state = plugin.getFlagStateManager().getState(player); + Vector vec = new Vector(state.lastInvincibleX, state.lastInvincibleY, state.lastInvincibleZ); + + StateFlag.State regionState = plugin.getGlobalRegionManager().get(world). + getApplicableRegions(vec).getFlag(DefaultFlag.INVINCIBILITY, plugin.wrapPlayer(player)); + if (regionState == StateFlag.State.ALLOW) { + return Boolean.TRUE; + } else if (regionState == StateFlag.State.DENY) { + return Boolean.FALSE; + } else { + return null; + } + } +} diff --git a/src/main/java/com/sk89q/worldguard/bukkit/ReportWriter.java b/src/main/java/com/sk89q/worldguard/bukkit/util/ReportWriter.java similarity index 97% rename from src/main/java/com/sk89q/worldguard/bukkit/ReportWriter.java rename to src/main/java/com/sk89q/worldguard/bukkit/util/ReportWriter.java index 82fa737b..54efe314 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/ReportWriter.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/util/ReportWriter.java @@ -1,343 +1,346 @@ -/* - * WorldGuard, a suite of tools for Minecraft - * Copyright (C) sk89q - * Copyright (C) WorldGuard team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser 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 Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldguard.bukkit; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.lang.reflect.Field; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.bukkit.Server; -import org.bukkit.World; -import org.bukkit.entity.Entity; -import org.bukkit.plugin.Plugin; - -import com.sk89q.worldguard.protection.GlobalRegionManager; -import com.sk89q.worldguard.protection.flags.DefaultFlag; -import com.sk89q.worldguard.protection.flags.Flag; -import com.sk89q.worldguard.protection.flags.StateFlag; -import com.sk89q.worldguard.protection.managers.RegionManager; -import com.sk89q.worldguard.protection.regions.ProtectedRegion; -import com.sk89q.worldguard.util.LogListBlock; - -public class ReportWriter { - - private static final SimpleDateFormat dateFmt = - new SimpleDateFormat("yyyy-MM-dd kk:mm Z"); - - private Date date = new Date(); - private StringBuilder output = new StringBuilder(); - - public ReportWriter(WorldGuardPlugin plugin) { - appendReportHeader(plugin); - appendServerInformation(plugin.getServer()); - appendPluginInformation(plugin.getServer().getPluginManager().getPlugins()); - appendWorldInformation(plugin.getServer().getWorlds()); - appendGlobalConfiguration(plugin.getGlobalStateManager()); - appendWorldConfigurations(plugin, plugin.getServer().getWorlds(), - plugin.getGlobalRegionManager(), plugin.getGlobalStateManager()); - appendln("-------------"); - appendln("END OF REPORT"); - appendln(); - } - - protected static String repeat(String str, int n) { - if(str == null) { - return null; - } - - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < n; i++) { - sb.append(str); - } - - return sb.toString(); - } - - protected void appendln(String text) { - output.append(text); - output.append("\r\n"); - } - - protected void appendln(String text, Object ... args) { - output.append(String.format(text, args)); - output.append("\r\n"); - } - - protected void append(LogListBlock log) { - output.append(log.toString()); - } - - protected void appendln() { - output.append("\r\n"); - } - - protected void appendHeader(String text) { - String rule = repeat("-", text.length()); - output.append(rule); - output.append("\r\n"); - appendln(text); - output.append(rule); - output.append("\r\n"); - appendln(); - } - - private void appendReportHeader(WorldGuardPlugin plugin) { - appendln("WorldGuard Configuration Report"); - appendln("Generated " + dateFmt.format(date)); - appendln(); - appendln("Version: " + plugin.getDescription().getVersion()); - appendln(); - } - - private void appendGlobalConfiguration(ConfigurationManager config) { - appendHeader("Global Configuration"); - - LogListBlock log = new LogListBlock(); - LogListBlock configLog = log.putChild("Configuration"); - - Class cls = config.getClass(); - for (Field field : cls.getFields()) { - try { - String name = field.getName(); - // store these elsewhere maybe? - if (name.equals("CONFIG_HEADER") - || name.equals("hostKeys") - || name.equals("sqlPassword")) { - continue; - } - Object val = field.get(config); - configLog.put(name, val); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } catch (IllegalAccessException ignore) { - } - } - - append(log); - appendln(); - } - - private void appendServerInformation(Server server) { - appendHeader("Server Information"); - - LogListBlock log = new LogListBlock(); - - Runtime runtime = Runtime.getRuntime(); - - log.put("Java", "%s %s (%s)", - System.getProperty("java.vendor"), - System.getProperty("java.version"), - System.getProperty("java.vendor.url")); - log.put("Operating system", "%s %s (%s)", - System.getProperty("os.name"), - System.getProperty("os.version"), - System.getProperty("os.arch")); - log.put("Available processors", runtime.availableProcessors()); - log.put("Free memory", runtime.freeMemory() / 1024 / 1024 + " MB"); - log.put("Max memory", runtime.maxMemory() / 1024 / 1024 + " MB"); - log.put("Total memory", runtime.totalMemory() / 1024 / 1024 + " MB"); - log.put("Server ID", server.getServerId()); - log.put("Server name", server.getServerName()); - log.put("Implementation", server.getVersion()); - //log.put("Address", server.getIp(), server.getPort()); - log.put("Player count", "%d/%d", - server.getOnlinePlayers().length, server.getMaxPlayers()); - - append(log); - appendln(); - } - - private void appendPluginInformation(Plugin[] plugins) { - appendHeader("Plugins (" + plugins.length + ")"); - - LogListBlock log = new LogListBlock(); - - for (Plugin plugin : plugins) { - log.put(plugin.getDescription().getName(), plugin.getDescription().getVersion()); - } - - append(log); - appendln(); - - /*appendHeader("Plugin Information"); - - log = new LogListBlock(); - - for (Plugin plugin : plugins) { - log.putChild(plugin.getDescription().getName()) - .put("Data folder", plugin.getDataFolder()) - .put("Website", plugin.getDescription().getWebsite()) - .put("Entry point", plugin.getDescription().getMain()); - } - - append(log); - appendln();*/ - } - - private void appendWorldInformation(List worlds) { - appendHeader("Worlds"); - - LogListBlock log = new LogListBlock(); - - int i = 0; - for (World world : worlds) { - int loadedChunkCount = world.getLoadedChunks().length; - - LogListBlock worldLog = log.putChild(world.getName() + " (" + i + ")"); - LogListBlock infoLog = worldLog.putChild("Information"); - LogListBlock entitiesLog = worldLog.putChild("Entities"); - - infoLog.put("Seed", world.getSeed()); - infoLog.put("Environment", world.getEnvironment().toString()); - infoLog.put("Player count", world.getPlayers().size()); - infoLog.put("Entity count", world.getEntities().size()); - infoLog.put("Loaded chunk count", loadedChunkCount); - infoLog.put("Spawn location", world.getSpawnLocation()); - infoLog.put("Raw time", world.getFullTime()); - - Map, Integer> entityCounts = - new HashMap, Integer>(); - - // Collect entities - for (Entity entity : world.getEntities()) { - Class cls = entity.getClass(); - - if (entityCounts.containsKey(cls)) { - entityCounts.put(cls, entityCounts.get(cls) + 1); - } else { - entityCounts.put(cls, 1); - } - } - - // Print entities - for (Map.Entry, Integer> entry - : entityCounts.entrySet()) { - entitiesLog.put(entry.getKey().getSimpleName(), - "%d [%f/chunk]", - entry.getValue(), - (float) (entry.getValue() / (double) loadedChunkCount)); - } - - i++; - } - - append(log); - appendln(); - } - - private void appendWorldConfigurations(WorldGuardPlugin plugin, List worlds, - GlobalRegionManager regionMgr, ConfigurationManager mgr) { - appendHeader("World Configurations"); - - LogListBlock log = new LogListBlock(); - - int i = 0; - for (World world : worlds) { - LogListBlock worldLog = log.putChild(world.getName() + " (" + i + ")"); - LogListBlock infoLog = worldLog.putChild("Information"); - LogListBlock configLog = worldLog.putChild("Configuration"); - LogListBlock blacklistLog = worldLog.putChild("Blacklist"); - LogListBlock regionsLog = worldLog.putChild("Region manager"); - - infoLog.put("Configuration file", (new File(plugin.getDataFolder(), "worlds/" - + world.getName() + "/config.yml")).getAbsoluteFile()); - - infoLog.put("Blacklist file", (new File(plugin.getDataFolder(), "worlds/" - + world.getName() + "/blacklist.txt")).getAbsoluteFile()); - infoLog.put("Regions file", (new File(plugin.getDataFolder(), "worlds/" - + world.getName() + "/regions.yml")).getAbsoluteFile()); - - WorldConfiguration config = mgr.get(world); - - Class cls = config.getClass(); - for (Field field : cls.getFields()) { - try { - Object val = field.get(config); - configLog.put(field.getName(), String.valueOf(val)); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } catch (IllegalAccessException ignore) { - } - } - - if (config.getBlacklist() == null) { - blacklistLog.put("State", "DISABLED"); - } else { - blacklistLog.put("State", "Enabled"); - blacklistLog.put("Number of items", - config.getBlacklist().getItemCount()); - blacklistLog.put("Is whitelist", - config.getBlacklist().isWhitelist()); - } - - RegionManager worldRegions = regionMgr.get(world); - - regionsLog.put("Type", worldRegions.getClass().getCanonicalName()); - regionsLog.put("Number of regions", worldRegions.getRegions().size()); - LogListBlock globalRegionLog = regionsLog.putChild("Global region"); - - ProtectedRegion globalRegion = worldRegions.matchRegion("__global__"); - if (globalRegion == null) { - globalRegionLog.put("Status", "UNDEFINED"); - } else { - for (Flag flag : DefaultFlag.getFlags()) { - if (flag instanceof StateFlag) { - globalRegionLog.put(flag.getName(), - globalRegion.getFlag(flag)); - } - } - } - } - - append(log); - appendln(); - } - - public void write(File file) throws IOException { - FileWriter writer = null; - BufferedWriter out; - - try { - writer = new FileWriter(file); - out = new BufferedWriter(writer); - out.write(output.toString()); - out.close(); - } finally { - if (writer != null) { - try { - writer.close(); - } catch (IOException ignore) { - } - } - } - } - - @Override - public String toString() { - return output.toString(); - } -} +/* + * WorldGuard, a suite of tools for Minecraft + * Copyright (C) sk89q + * Copyright (C) WorldGuard team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldguard.bukkit.util; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.reflect.Field; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.sk89q.worldguard.bukkit.ConfigurationManager; +import com.sk89q.worldguard.bukkit.WorldConfiguration; +import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import org.bukkit.Server; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.plugin.Plugin; + +import com.sk89q.worldguard.protection.GlobalRegionManager; +import com.sk89q.worldguard.protection.flags.DefaultFlag; +import com.sk89q.worldguard.protection.flags.Flag; +import com.sk89q.worldguard.protection.flags.StateFlag; +import com.sk89q.worldguard.protection.managers.RegionManager; +import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import com.sk89q.worldguard.util.LogListBlock; + +public class ReportWriter { + + private static final SimpleDateFormat dateFmt = + new SimpleDateFormat("yyyy-MM-dd kk:mm Z"); + + private Date date = new Date(); + private StringBuilder output = new StringBuilder(); + + public ReportWriter(WorldGuardPlugin plugin) { + appendReportHeader(plugin); + appendServerInformation(plugin.getServer()); + appendPluginInformation(plugin.getServer().getPluginManager().getPlugins()); + appendWorldInformation(plugin.getServer().getWorlds()); + appendGlobalConfiguration(plugin.getGlobalStateManager()); + appendWorldConfigurations(plugin, plugin.getServer().getWorlds(), + plugin.getGlobalRegionManager(), plugin.getGlobalStateManager()); + appendln("-------------"); + appendln("END OF REPORT"); + appendln(); + } + + protected static String repeat(String str, int n) { + if(str == null) { + return null; + } + + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < n; i++) { + sb.append(str); + } + + return sb.toString(); + } + + protected void appendln(String text) { + output.append(text); + output.append("\r\n"); + } + + protected void appendln(String text, Object ... args) { + output.append(String.format(text, args)); + output.append("\r\n"); + } + + protected void append(LogListBlock log) { + output.append(log.toString()); + } + + protected void appendln() { + output.append("\r\n"); + } + + protected void appendHeader(String text) { + String rule = repeat("-", text.length()); + output.append(rule); + output.append("\r\n"); + appendln(text); + output.append(rule); + output.append("\r\n"); + appendln(); + } + + private void appendReportHeader(WorldGuardPlugin plugin) { + appendln("WorldGuard Configuration Report"); + appendln("Generated " + dateFmt.format(date)); + appendln(); + appendln("Version: " + plugin.getDescription().getVersion()); + appendln(); + } + + private void appendGlobalConfiguration(ConfigurationManager config) { + appendHeader("Global Configuration"); + + LogListBlock log = new LogListBlock(); + LogListBlock configLog = log.putChild("Configuration"); + + Class cls = config.getClass(); + for (Field field : cls.getFields()) { + try { + String name = field.getName(); + // store these elsewhere maybe? + if (name.equals("CONFIG_HEADER") + || name.equals("hostKeys") + || name.equals("sqlPassword")) { + continue; + } + Object val = field.get(config); + configLog.put(name, val); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException ignore) { + } + } + + append(log); + appendln(); + } + + private void appendServerInformation(Server server) { + appendHeader("Server Information"); + + LogListBlock log = new LogListBlock(); + + Runtime runtime = Runtime.getRuntime(); + + log.put("Java", "%s %s (%s)", + System.getProperty("java.vendor"), + System.getProperty("java.version"), + System.getProperty("java.vendor.url")); + log.put("Operating system", "%s %s (%s)", + System.getProperty("os.name"), + System.getProperty("os.version"), + System.getProperty("os.arch")); + log.put("Available processors", runtime.availableProcessors()); + log.put("Free memory", runtime.freeMemory() / 1024 / 1024 + " MB"); + log.put("Max memory", runtime.maxMemory() / 1024 / 1024 + " MB"); + log.put("Total memory", runtime.totalMemory() / 1024 / 1024 + " MB"); + log.put("Server ID", server.getServerId()); + log.put("Server name", server.getServerName()); + log.put("Implementation", server.getVersion()); + //log.put("Address", server.getIp(), server.getPort()); + log.put("Player count", "%d/%d", + server.getOnlinePlayers().length, server.getMaxPlayers()); + + append(log); + appendln(); + } + + private void appendPluginInformation(Plugin[] plugins) { + appendHeader("Plugins (" + plugins.length + ")"); + + LogListBlock log = new LogListBlock(); + + for (Plugin plugin : plugins) { + log.put(plugin.getDescription().getName(), plugin.getDescription().getVersion()); + } + + append(log); + appendln(); + + /*appendHeader("Plugin Information"); + + log = new LogListBlock(); + + for (Plugin plugin : plugins) { + log.putChild(plugin.getDescription().getName()) + .put("Data folder", plugin.getDataFolder()) + .put("Website", plugin.getDescription().getWebsite()) + .put("Entry point", plugin.getDescription().getMain()); + } + + append(log); + appendln();*/ + } + + private void appendWorldInformation(List worlds) { + appendHeader("Worlds"); + + LogListBlock log = new LogListBlock(); + + int i = 0; + for (World world : worlds) { + int loadedChunkCount = world.getLoadedChunks().length; + + LogListBlock worldLog = log.putChild(world.getName() + " (" + i + ")"); + LogListBlock infoLog = worldLog.putChild("Information"); + LogListBlock entitiesLog = worldLog.putChild("Entities"); + + infoLog.put("Seed", world.getSeed()); + infoLog.put("Environment", world.getEnvironment().toString()); + infoLog.put("Player count", world.getPlayers().size()); + infoLog.put("Entity count", world.getEntities().size()); + infoLog.put("Loaded chunk count", loadedChunkCount); + infoLog.put("Spawn location", world.getSpawnLocation()); + infoLog.put("Raw time", world.getFullTime()); + + Map, Integer> entityCounts = + new HashMap, Integer>(); + + // Collect entities + for (Entity entity : world.getEntities()) { + Class cls = entity.getClass(); + + if (entityCounts.containsKey(cls)) { + entityCounts.put(cls, entityCounts.get(cls) + 1); + } else { + entityCounts.put(cls, 1); + } + } + + // Print entities + for (Map.Entry, Integer> entry + : entityCounts.entrySet()) { + entitiesLog.put(entry.getKey().getSimpleName(), + "%d [%f/chunk]", + entry.getValue(), + (float) (entry.getValue() / (double) loadedChunkCount)); + } + + i++; + } + + append(log); + appendln(); + } + + private void appendWorldConfigurations(WorldGuardPlugin plugin, List worlds, + GlobalRegionManager regionMgr, ConfigurationManager mgr) { + appendHeader("World Configurations"); + + LogListBlock log = new LogListBlock(); + + int i = 0; + for (World world : worlds) { + LogListBlock worldLog = log.putChild(world.getName() + " (" + i + ")"); + LogListBlock infoLog = worldLog.putChild("Information"); + LogListBlock configLog = worldLog.putChild("Configuration"); + LogListBlock blacklistLog = worldLog.putChild("Blacklist"); + LogListBlock regionsLog = worldLog.putChild("Region manager"); + + infoLog.put("Configuration file", (new File(plugin.getDataFolder(), "worlds/" + + world.getName() + "/config.yml")).getAbsoluteFile()); + + infoLog.put("Blacklist file", (new File(plugin.getDataFolder(), "worlds/" + + world.getName() + "/blacklist.txt")).getAbsoluteFile()); + infoLog.put("Regions file", (new File(plugin.getDataFolder(), "worlds/" + + world.getName() + "/regions.yml")).getAbsoluteFile()); + + WorldConfiguration config = mgr.get(world); + + Class cls = config.getClass(); + for (Field field : cls.getFields()) { + try { + Object val = field.get(config); + configLog.put(field.getName(), String.valueOf(val)); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException ignore) { + } + } + + if (config.getBlacklist() == null) { + blacklistLog.put("State", "DISABLED"); + } else { + blacklistLog.put("State", "Enabled"); + blacklistLog.put("Number of items", + config.getBlacklist().getItemCount()); + blacklistLog.put("Is whitelist", + config.getBlacklist().isWhitelist()); + } + + RegionManager worldRegions = regionMgr.get(world); + + regionsLog.put("Type", worldRegions.getClass().getCanonicalName()); + regionsLog.put("Number of regions", worldRegions.getRegions().size()); + LogListBlock globalRegionLog = regionsLog.putChild("Global region"); + + ProtectedRegion globalRegion = worldRegions.matchRegion("__global__"); + if (globalRegion == null) { + globalRegionLog.put("Status", "UNDEFINED"); + } else { + for (Flag flag : DefaultFlag.getFlags()) { + if (flag instanceof StateFlag) { + globalRegionLog.put(flag.getName(), + globalRegion.getFlag(flag)); + } + } + } + } + + append(log); + appendln(); + } + + public void write(File file) throws IOException { + FileWriter writer = null; + BufferedWriter out; + + try { + writer = new FileWriter(file); + out = new BufferedWriter(writer); + out.write(output.toString()); + out.close(); + } finally { + if (writer != null) { + try { + writer.close(); + } catch (IOException ignore) { + } + } + } + } + + @Override + public String toString() { + return output.toString(); + } +} diff --git a/src/main/java/com/sk89q/worldguard/protection/GlobalRegionManager.java b/src/main/java/com/sk89q/worldguard/protection/GlobalRegionManager.java index 651d6f9e..62c206a3 100644 --- a/src/main/java/com/sk89q/worldguard/protection/GlobalRegionManager.java +++ b/src/main/java/com/sk89q/worldguard/protection/GlobalRegionManager.java @@ -19,111 +19,45 @@ package com.sk89q.worldguard.protection; -import com.sk89q.worldedit.Vector2D; import com.sk89q.worldguard.LocalPlayer; -import com.sk89q.worldguard.bukkit.ConfigurationManager; +import com.sk89q.worldguard.bukkit.RegionContainer; +import com.sk89q.worldguard.bukkit.RegionQuery; 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; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.entity.Player; 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; /** - * A global region manager loads, saves and caches region data for zero or - * more worlds at a time. + * This is the legacy class for accessing region data. * - *

This class is thread safe and its contents can be accessed from - * multiple concurrent threads.

+ * @deprecated use {@link WorldGuardPlugin#getRegionContainer()} */ +@Deprecated public class GlobalRegionManager { private final WorldGuardPlugin plugin; - private final ManagerContainer container; + private final RegionContainer container; /** * Create a new instance. * * @param plugin the plugin + * @param container the container */ - public GlobalRegionManager(WorldGuardPlugin plugin) { + public GlobalRegionManager(WorldGuardPlugin plugin, RegionContainer container) { + checkNotNull(plugin); + checkNotNull(container); this.plugin = plugin; - - ConfigurationManager config = plugin.getGlobalStateManager(); - container = new ManagerContainer(config); - } - - /** - * Load the region data for a world if it has not been loaded already. - * - *

This method is called by WorldGuard and should not be called - * by other plugins.

- * - * @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 positions = new ArrayList(); - for (Chunk chunk : world.getLoadedChunks()) { - positions.add(new Vector2D(chunk.getX(), chunk.getZ())); - } - manager.loadChunks(positions); - } - - return manager; - } - - /** - * Load the region data for a list of worlds. - * - *

This method is called by WorldGuard and should not be called - * by other plugins.

- * - * @param worlds a list of worlds - */ - public void loadAll(Collection 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) { - 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(); + this.container = container; } /** @@ -138,7 +72,7 @@ public void unloadAll() { */ @Nullable public RegionManager get(World world) { - return container.get(world.getName()); + return container.get(world); } /** @@ -155,8 +89,8 @@ public List getLoaded() { * * @return a new query */ - public ProtectedRegionQuery createAnonymousQuery() { - return new ProtectedRegionQuery(plugin, (Player) null); + private RegionQuery createAnonymousQuery() { + return container.createAnonymousQuery(); } /** @@ -165,8 +99,8 @@ public ProtectedRegionQuery createAnonymousQuery() { * @param player a player, or {@code null} * @return a new query */ - public ProtectedRegionQuery createQuery(@Nullable Player player) { - return new ProtectedRegionQuery(plugin, player); + private RegionQuery createQuery(@Nullable Player player) { + return container.createQuery(player); } /** @@ -175,8 +109,8 @@ public ProtectedRegionQuery createQuery(@Nullable Player player) { * @param player a player, or {@code null} * @return a new query */ - private ProtectedRegionQuery createQuery(@Nullable LocalPlayer player) { - return new ProtectedRegionQuery(plugin, player); + private RegionQuery createQuery(@Nullable LocalPlayer player) { + return container.createQuery(player); } /** @@ -243,7 +177,7 @@ public boolean canBuild(Player player, Block block) { */ @Deprecated public boolean canBuild(Player player, Location location) { - return createQuery(player).canBuild(location); + return createQuery(player).testPermission(location); } /** @@ -252,12 +186,12 @@ public boolean canBuild(Player player, Location location) { * @param player the player * @param block the block * @return true if permitted - * @deprecated use {@link #createQuery(Player)} + * @deprecated the construct flag is being removed */ @Deprecated @SuppressWarnings("deprecation") public boolean canConstruct(Player player, Block block) { - return canConstruct(player, block.getLocation()); + return canBuild(player, block.getLocation()); } /** @@ -266,11 +200,11 @@ public boolean canConstruct(Player player, Block block) { * @param player the player * @param location the location * @return true if permitted - * @deprecated use {@link #createQuery(Player)} + * @deprecated the construct flag is being removed */ @Deprecated public boolean canConstruct(Player player, Location location) { - return createQuery(player).canConstruct(location); + return canBuild(player, location); } /** @@ -299,7 +233,7 @@ public boolean allows(StateFlag flag, Location location) { */ @Deprecated public boolean allows(StateFlag flag, Location location, @Nullable LocalPlayer player) { - return createQuery(player).allows(flag, location); + return createQuery(player).testEnabled(location, flag); } }