diff --git a/CHANGELOG.md b/CHANGELOG.md index d0275429..27d6d88e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ In addition, be aware of these breaking changes: * Once the region data has been converted (automatically) to use UUIDs, it is no longer possible to downgrade. * Plugins that utility WorldGuard's API may not work anymore. * Protection is now a lot more exhaustive so it is no longer, for example, possible to fling sand into a region. +* In the rare situation that you are user of the "auto-invincibility" and "auto-no-drowning" groups (`wg-invincible` and `wg-amphibious`), you now have to enable these features in the config (`auto-invincible-group: true` and `auto-no-drowning-group: true`). This is because some permission plugins have been causing severe hang ups whenever it is queried for a player's groups, which, in this case, happens to include when the player joins. ### UUID support @@ -108,6 +109,7 @@ A long requested feature was the availability of block place and break flags. Th * Changed sponges to now be disabled by default. However, if you had previously installed WorldGuard, sponges will still be enabled. Sponges are being added in Minecraft and they work differently than in Minecraft Classic (which WorldGuard emulates). In addition, enabling sponge support in WorldGuard incurs extra CPU cost even if no sponges exist in the world. * Changed how region data is loaded and saved so failures are now more graceful. If the region data fails to load for a world, then the entire world will be protected by default. In addition, periodic attempts will be made to load the region data in the background. * Changed the `FEED` flag to maximize the player's saturation level if the hunger level is raised. +* Changed the `wg-invincible` and `wg-amphibious` groups feature so that it now must be enabled in the configuration. * Removed the ability for WorldGuard to upgrade from a version for Minecraft Alpha. ### API changes diff --git a/UPGRADE.md b/UPGRADE.md index 9ce5c9d3..26e57562 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -22,6 +22,7 @@ Be aware of these breaking changes: * MySQL support now features the ability to migrate tables. If you are using tables without a prefix, then the new migration code should be able to handle your table. However, if you are using a table prefix, you may encounter trouble with migration. * Plugins that utility WorldGuard's API may not work anymore. * Protection is now a lot more exhaustive so it is no longer, for example, possible to fling sand into a region. +* In the rare situation that you are user of the "auto-invincibility" and "auto-no-drowning" groups (`wg-invincible` and `wg-amphibious`), you now have to enable these features in the config (`auto-invincible-group: true` and `auto-no-drowning-group: true`). This is because some permission plugins have been causing severe hang ups whenever it is queried for a player's groups, which, in this case, happens to include when the player joins. ## Major features diff --git a/src/main/java/com/sk89q/worldguard/bukkit/ConfigurationManager.java b/src/main/java/com/sk89q/worldguard/bukkit/ConfigurationManager.java index 8b307b2a..61e3074f 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/ConfigurationManager.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/ConfigurationManager.java @@ -87,7 +87,9 @@ public class ConfigurationManager { public boolean useRegionsScheduler; public boolean useRegionsCreatureSpawnEvent; public boolean activityHaltToggle = false; - public boolean autoGodMode; + public boolean useGodPermission; + public boolean useGodGroup; + public boolean useAmphibiousGroup; public boolean usePlayerMove; public boolean usePlayerTeleports; public boolean deopOnJoin; @@ -153,7 +155,9 @@ public void load() { migrateRegionsToUuid = config.getBoolean("regions.uuid-migration.perform-on-next-start", true); keepUnresolvedNames = config.getBoolean("regions.uuid-migration.keep-names-that-lack-uuids", true); useRegionsCreatureSpawnEvent = config.getBoolean("regions.use-creature-spawn-event", true); - autoGodMode = config.getBoolean("auto-invincible", config.getBoolean("auto-invincible-permission", false)); + useGodPermission = config.getBoolean("auto-invincible", config.getBoolean("auto-invincible-permission", false)); + useGodGroup = config.getBoolean("auto-invincible-group", false); + useAmphibiousGroup = config.getBoolean("auto-no-drowning-group", false); config.removeProperty("auto-invincible-permission"); usePlayerMove = config.getBoolean("use-player-move-event", true); usePlayerTeleports = config.getBoolean("use-player-teleports", true); diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java index 29b0115f..680f82d9 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java @@ -44,12 +44,14 @@ import com.sk89q.worldguard.bukkit.commands.GeneralCommands; import com.sk89q.worldguard.bukkit.commands.ProtectionCommands; import com.sk89q.worldguard.bukkit.commands.ToggleCommands; +import com.sk89q.worldguard.bukkit.event.player.ProcessPlayerEvent; import com.sk89q.worldguard.bukkit.listener.BlacklistListener; import com.sk89q.worldguard.bukkit.listener.BlockedPotionsListener; 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.PlayerModesListener; import com.sk89q.worldguard.bukkit.listener.RegionFlagsListener; import com.sk89q.worldguard.bukkit.listener.RegionProtectionListener; import com.sk89q.worldguard.bukkit.listener.WorldGuardBlockListener; @@ -61,6 +63,7 @@ import com.sk89q.worldguard.bukkit.listener.WorldGuardVehicleListener; import com.sk89q.worldguard.bukkit.listener.WorldGuardWeatherListener; import com.sk89q.worldguard.bukkit.listener.WorldGuardWorldListener; +import com.sk89q.worldguard.bukkit.util.Events; import com.sk89q.worldguard.protection.GlobalRegionManager; import com.sk89q.worldguard.protection.managers.RegionManager; import com.sk89q.worldguard.protection.managers.storage.StorageException; @@ -235,6 +238,7 @@ public void run() { (new RegionFlagsListener(this)).registerEvents(); (new BlockedPotionsListener(this)).registerEvents(); (new EventAbstractionListener(this)).registerEvents(); + (new PlayerModesListener(this)).registerEvents(); if ("true".equalsIgnoreCase(System.getProperty("worldguard.debug.listener"))) { (new DebuggingListener(this, log)).registerEvents(); } @@ -252,14 +256,9 @@ public void run() { } worldListener.registerEvents(); - if (!configuration.hasCommandBookGodMode()) { - // Check god mode for existing players, if any - for (Player player : getServer().getOnlinePlayers()) { - if (inGroup(player, "wg-invincible") || - (configuration.autoGodMode && hasPermission(player, "worldguard.auto-invincible"))) { - configuration.enableGodMode(player); - } - } + for (Player player : getServer().getOnlinePlayers()) { + ProcessPlayerEvent event = new ProcessPlayerEvent(player); + Events.fire(event); } } diff --git a/src/main/java/com/sk89q/worldguard/bukkit/event/player/ProcessPlayerEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/player/ProcessPlayerEvent.java new file mode 100644 index 00000000..7a540838 --- /dev/null +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/player/ProcessPlayerEvent.java @@ -0,0 +1,52 @@ +/* + * 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.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import static com.google.common.base.Preconditions.checkNotNull; + +public class ProcessPlayerEvent extends Event { + + private static final HandlerList handlers = new HandlerList(); + + private final Player player; + + public ProcessPlayerEvent(Player player) { + checkNotNull(player); + this.player = player; + } + + public Player getPlayer() { + return player; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + +} diff --git a/src/main/java/com/sk89q/worldguard/bukkit/listener/PlayerModesListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/PlayerModesListener.java new file mode 100644 index 00000000..3380662a --- /dev/null +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/PlayerModesListener.java @@ -0,0 +1,78 @@ +/* + * 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.WorldGuardPlugin; +import com.sk89q.worldguard.bukkit.event.player.ProcessPlayerEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import java.util.logging.Level; +import java.util.logging.Logger; + +public class PlayerModesListener extends AbstractListener { + + private static final Logger log = Logger.getLogger(PlayerModesListener.class.getCanonicalName()); + + private static final String INVINCIBLE_PERMISSION = "worldguard.auto-invincible"; + private static final String INVINCIBLE_GROUP = "wg-invincible"; + private static final String AMPHIBIOUS_GROUP = "wg-amphibious"; + + /** + * Construct the listener. + * + * @param plugin an instance of WorldGuardPlugin + */ + public PlayerModesListener(WorldGuardPlugin plugin) { + super(plugin); + } + + private boolean hasGodModeGroup(Player player) { + return getConfig().useGodGroup && getPlugin().inGroup(player, INVINCIBLE_GROUP); + } + + private boolean hasGodModePermission(Player player) { + return getConfig().useGodPermission && getPlugin().hasPermission(player, INVINCIBLE_PERMISSION); + } + + private boolean hasAmphibiousGroup(Player player) { + return getConfig().useAmphibiousGroup && getPlugin().inGroup(player, AMPHIBIOUS_GROUP); + } + + @EventHandler + public void onProcessPlayer(ProcessPlayerEvent event) { + ConfigurationManager config = getConfig(); + Player player = event.getPlayer(); + + if (!config.hasCommandBookGodMode()) { + if (hasGodModeGroup(player) || hasGodModePermission(player)) { + log.log(Level.INFO, "Enabled auto-god mode for " + player.getName()); + config.enableGodMode(player); + } + } + + if (hasAmphibiousGroup(player)) { + log.log(Level.INFO, "Enabled no-drowning mode for " + player.getName() + " (player is in group 'wg-amphibious')"); + config.enableAmphibiousMode(player); + } + } + +} 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 fed86f48..c92c1864 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardPlayerListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardPlayerListener.java @@ -26,7 +26,9 @@ import com.sk89q.worldguard.bukkit.ConfigurationManager; import com.sk89q.worldguard.bukkit.WorldConfiguration; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import com.sk89q.worldguard.bukkit.event.player.ProcessPlayerEvent; import com.sk89q.worldguard.bukkit.listener.FlagStateManager.PlayerFlagState; +import com.sk89q.worldguard.bukkit.util.Events; import com.sk89q.worldguard.protection.ApplicableRegionSet; import com.sk89q.worldguard.protection.flags.DefaultFlag; import com.sk89q.worldguard.protection.managers.RegionManager; @@ -60,7 +62,6 @@ import java.util.Iterator; import java.util.Set; -import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -348,16 +349,7 @@ public void onPlayerJoin(PlayerJoinEvent event) { + "Fire spread is currently globally disabled for this world."); } - if (!cfg.hasCommandBookGodMode() && cfg.autoGodMode && (plugin.inGroup(player, "wg-invincible") - || plugin.hasPermission(player, "worldguard.auto-invincible"))) { - log.log(Level.INFO, "Enabled auto-god mode for " + player.getName()); - cfg.enableGodMode(player); - } - - if (plugin.inGroup(player, "wg-amphibious")) { - log.log(Level.INFO, "Enabled no-drowning mode for " + player.getName() + " (player is in group 'wg-amphibious')"); - cfg.enableAmphibiousMode(player); - } + Events.fire(new ProcessPlayerEvent(player)); if (wcfg.useRegions) { PlayerFlagState state = plugin.getFlagStateManager().getState(player); diff --git a/src/main/java/com/sk89q/worldguard/bukkit/util/Events.java b/src/main/java/com/sk89q/worldguard/bukkit/util/Events.java index 637fe1fe..760e4f8b 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/util/Events.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/util/Events.java @@ -26,6 +26,8 @@ import org.bukkit.event.Event.Result; import org.bukkit.event.player.PlayerInteractEvent; +import static com.google.common.base.Preconditions.checkNotNull; + /** * Utility methods to deal with events. */ @@ -34,6 +36,16 @@ public final class Events { private Events() { } + /** + * Fire an event. + * + * @param event the event + */ + public static void fire(Event event) { + checkNotNull(event); + Bukkit.getServer().getPluginManager().callEvent(event); + } + /** * Fire the {@code eventToFire} and return whether the event was cancelled. * @@ -41,7 +53,7 @@ private Events() { * @param an event that can be fired and is cancellable * @return true if the event was cancelled */ - public static boolean fireAndTestCancel( T eventToFire) { + public static boolean fireAndTestCancel(T eventToFire) { Bukkit.getServer().getPluginManager().callEvent(eventToFire); return eventToFire.isCancelled(); }