diff --git a/src/main/java/com/sk89q/worldguard/bukkit/FlagStateManager.java b/src/main/java/com/sk89q/worldguard/bukkit/FlagStateManager.java index db4028b4..ae91ecd9 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/FlagStateManager.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/FlagStateManager.java @@ -36,24 +36,24 @@ /** * 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(); } @@ -66,16 +66,16 @@ public void run() { 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); @@ -87,7 +87,7 @@ public void run() { .get(player.getWorld()); ApplicableRegionSet applicable = regionManager .getApplicableRegions(playerLocation); - + if (!RegionQueryUtil.isInvincible(plugin, player, applicable) && !plugin.getGlobalStateManager().hasGodMode(player) && !(player.getGameMode() == GameMode.CREATIVE)) { @@ -96,7 +96,7 @@ public void run() { } } } - + /** * Process healing for a player. * @@ -106,18 +106,18 @@ public void run() { */ 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); Integer minHealth = applicable.getFlag(DefaultFlag.MIN_HEAL); Integer maxHealth = applicable.getFlag(DefaultFlag.MAX_HEAL); - + if (healAmount == null || healDelay == null || healAmount == 0 || healDelay < 0) { return; } @@ -127,7 +127,7 @@ private void processHeal(ApplicableRegionSet applicable, Player player, 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; @@ -137,10 +137,10 @@ private void processHeal(ApplicableRegionSet applicable, Player player, 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 @@ -154,7 +154,7 @@ private void processFeed(ApplicableRegionSet applicable, Player player, 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; } @@ -177,7 +177,7 @@ private void processFeed(ApplicableRegionSet applicable, Player player, /** * Forget a player. - * + * * @param player The player to forget */ public synchronized void forget(Player player) { @@ -194,21 +194,21 @@ public synchronized void forgetAll() { /** * 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. */ @@ -220,6 +220,7 @@ public static class PlayerFlagState { public Boolean lastExitAllowed = null; public Boolean notifiedForLeave = false; public Boolean notifiedForEnter = false; + public GameMode lastGameMode; public World lastWorld; public int lastBlockX; public int lastBlockY; diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java index 224af626..cafccf9b 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java @@ -25,6 +25,7 @@ import com.sk89q.worldedit.blocks.BlockID; import com.sk89q.worldedit.blocks.ItemID; import org.bukkit.ChatColor; +import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.block.Block; @@ -42,6 +43,7 @@ import org.bukkit.event.player.PlayerChatEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerGameModeChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerItemHeldEvent; import org.bukkit.event.player.PlayerJoinEvent; @@ -159,6 +161,7 @@ public void onPlayerMove(PlayerMoveEvent event) { String farewell = set.getFlag(DefaultFlag.FAREWELL_MESSAGE);//, localPlayer); Boolean notifyEnter = set.getFlag(DefaultFlag.NOTIFY_ENTER);//, localPlayer); Boolean notifyLeave = set.getFlag(DefaultFlag.NOTIFY_LEAVE);//, localPlayer); + GameMode gameMode = set.getFlag(DefaultFlag.GAME_MODE); if (state.lastFarewell != null && (farewell == null || !state.lastFarewell.equals(farewell))) { @@ -199,6 +202,15 @@ public void onPlayerMove(PlayerMoveEvent event) { + regionList); } + if (gameMode != null && player.getGameMode() != gameMode) { + player.setGameMode(gameMode); + } else { + if (state.lastGameMode != null) { + player.setGameMode(state.lastGameMode); + state.lastGameMode = null; + } + } + state.lastGreeting = greeting; state.lastFarewell = farewell; state.notifiedForEnter = notifyEnter; @@ -213,6 +225,21 @@ public void onPlayerMove(PlayerMoveEvent event) { } } + @EventHandler + public void onPlayerGameModeChange(PlayerGameModeChangeEvent event) { + Player player = event.getPlayer(); + WorldConfiguration wcfg = plugin.getGlobalStateManager().get(player.getWorld()); + if (wcfg.useRegions) { + GameMode gameMode = plugin.getGlobalRegionManager().get(player.getWorld()) + .getApplicableRegions(player.getLocation()).getFlag(DefaultFlag.GAME_MODE); + if (gameMode != null && event.getNewGameMode() != gameMode) { + event.setCancelled(true); + player.sendMessage(ChatColor.RED + "Your game mode is locked to " + + gameMode + "in this region!"); + } + } + } + @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { Player player = event.getPlayer(); diff --git a/src/main/java/com/sk89q/worldguard/protection/flags/DefaultFlag.java b/src/main/java/com/sk89q/worldguard/protection/flags/DefaultFlag.java index 639d64bc..fb2a1e1a 100644 --- a/src/main/java/com/sk89q/worldguard/protection/flags/DefaultFlag.java +++ b/src/main/java/com/sk89q/worldguard/protection/flags/DefaultFlag.java @@ -19,6 +19,7 @@ package com.sk89q.worldguard.protection.flags; +import org.bukkit.GameMode; import org.bukkit.entity.EntityType; /** @@ -70,6 +71,7 @@ public final class DefaultFlag { public static final BooleanFlag NOTIFY_ENTER = new BooleanFlag("notify-enter", RegionGroup.ALL); public static final BooleanFlag NOTIFY_LEAVE = new BooleanFlag("notify-leave", RegionGroup.ALL); public static final SetFlag DENY_SPAWN = new SetFlag("deny-spawn", RegionGroup.ALL, new EntityTypeFlag(null)); + public static final EnumFlag GAME_MODE = new EnumFlag("game-mode", GameMode.class, RegionGroup.ALL); public static final IntegerFlag HEAL_DELAY = new IntegerFlag("heal-delay", RegionGroup.ALL); public static final IntegerFlag HEAL_AMOUNT = new IntegerFlag("heal-amount", RegionGroup.ALL); public static final IntegerFlag MIN_HEAL = new IntegerFlag("heal-min-health", RegionGroup.ALL); @@ -94,7 +96,7 @@ public final class DefaultFlag { EXIT, ENTRY, LIGHTNING, ENTITY_PAINTING_DESTROY, HEAL_AMOUNT, HEAL_DELAY, MIN_HEAL, MAX_HEAL, FEED_DELAY, FEED_AMOUNT, MIN_FOOD, MAX_FOOD, - SNOW_FALL, SNOW_MELT, ICE_FORM, ICE_MELT, + SNOW_FALL, SNOW_MELT, ICE_FORM, ICE_MELT, GAME_MODE, MUSHROOMS, LEAF_DECAY, GRASS_SPREAD, SEND_CHAT, RECEIVE_CHAT, FIRE_SPREAD, LAVA_FIRE, LAVA_FLOW, WATER_FLOW, TELE_LOC, SPAWN_LOC, POTION_SPLASH,