Rewrite session and movement flag code.

Also adds entry-deny-message and exit-deny-message.

Fixes WORLDGUARD-3086, WORLDGUARD-2542, WORLDGUARD-2731.
This commit is contained in:
sk89q 2015-01-17 18:54:10 -08:00
parent 643345b459
commit aae521b727
30 changed files with 1767 additions and 799 deletions

View File

@ -20,15 +20,13 @@
package com.sk89q.worldguard.bukkit;
import com.google.common.collect.ImmutableMap;
import com.sk89q.commandbook.CommandBook;
import com.sk89q.commandbook.GodComponent;
import com.sk89q.util.yaml.YAMLFormat;
import com.sk89q.util.yaml.YAMLProcessor;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.protection.managers.storage.file.DirectoryYamlDriver;
import com.sk89q.worldguard.protection.managers.storage.DriverType;
import com.sk89q.worldguard.protection.managers.storage.RegionDriver;
import com.sk89q.worldguard.protection.managers.storage.file.DirectoryYamlDriver;
import com.sk89q.worldguard.protection.managers.storage.sql.SQLDriver;
import com.sk89q.worldguard.session.handler.WaterBreathing;
import com.sk89q.worldguard.util.report.Unreported;
import com.sk89q.worldguard.util.sql.DataSourceConfig;
import org.bukkit.World;
@ -37,9 +35,7 @@
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Logger;
@ -79,12 +75,9 @@ public class ConfigurationManager {
@Unreported private WorldGuardPlugin plugin;
@Unreported private ConcurrentMap<String, WorldConfiguration> worlds;
@Unreported private YAMLProcessor config;
@Deprecated @Unreported private Set<String> hasGodMode = new HashSet<String>();
@Unreported private Set<String> hasAmphibious = new HashSet<String>();
private boolean hasCommandBookGodMode = false;
public boolean useRegionsScheduler;
public boolean useRegionsCreatureSpawnEvent;
public boolean activityHaltToggle = false;
public boolean useGodPermission;
@ -152,7 +145,6 @@ public void load() {
}
config.removeProperty("suppress-tick-sync-warnings");
useRegionsScheduler = config.getBoolean("regions.use-scheduler", true);
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);
@ -242,37 +234,6 @@ public WorldConfiguration get(World world) {
return config;
}
/**
* Forget a player.
*
* @param player The player to forget about
*/
public void forgetPlayer(LocalPlayer player) {
hasGodMode.remove(player.getName());
hasAmphibious.remove(player.getName());
}
/**
* Enable god mode for a player.
*
* @param player The player to enable god mode for.
*/
@Deprecated
public void enableGodMode(Player player) {
hasGodMode.add(player.getName());
}
/**
* Disable god mode for a player.
*
* @param player The player to disable godmode for
*/
@Deprecated
public void disableGodMode(Player player) {
hasGodMode.remove(player.getName());
}
/**
* Check to see if god mode is enabled for a player.
*
@ -280,13 +241,7 @@ public void disableGodMode(Player player) {
* @return Whether the player has godmode through WorldGuard or CommandBook
*/
public boolean hasGodMode(Player player) {
if (hasCommandBookGodMode) {
GodComponent god = CommandBook.inst().getComponentManager().getComponent(GodComponent.class);
if (god != null) {
return god.hasGodMode(player);
}
}
return hasGodMode.contains(player.getName());
return plugin.getSessionManager().get(player).isInvincible(player);
}
/**
@ -295,7 +250,10 @@ public boolean hasGodMode(Player player) {
* @param player The player to enable amphibious mode for
*/
public void enableAmphibiousMode(Player player) {
hasAmphibious.add(player.getName());
WaterBreathing handler = plugin.getSessionManager().get(player).getHandler(WaterBreathing.class);
if (handler != null) {
handler.setWaterBreathing(true);
}
}
/**
@ -304,7 +262,10 @@ public void enableAmphibiousMode(Player player) {
* @param player The player to disable amphibious mode for
*/
public void disableAmphibiousMode(Player player) {
hasAmphibious.remove(player.getName());
WaterBreathing handler = plugin.getSessionManager().get(player).getHandler(WaterBreathing.class);
if (handler != null) {
handler.setWaterBreathing(false);
}
}
/**
@ -314,7 +275,8 @@ public void disableAmphibiousMode(Player player) {
* @return Whether {@code player} has amphibious mode
*/
public boolean hasAmphibiousMode(Player player) {
return hasAmphibious.contains(player.getName());
WaterBreathing handler = plugin.getSessionManager().get(player).getHandler(WaterBreathing.class);
return handler != null && handler.hasWaterBreathing();
}
public void updateCommandBookGodMode() {

View File

@ -37,6 +37,7 @@
import com.sk89q.worldguard.bukkit.commands.ToggleCommands;
import com.sk89q.worldguard.bukkit.event.player.ProcessPlayerEvent;
import com.sk89q.worldguard.bukkit.listener.*;
import com.sk89q.worldguard.session.SessionManager;
import com.sk89q.worldguard.bukkit.util.Events;
import com.sk89q.worldguard.protection.GlobalRegionManager;
import com.sk89q.worldguard.protection.managers.RegionManager;
@ -85,7 +86,7 @@ public class WorldGuardPlugin extends JavaPlugin {
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 SessionManager sessionManager;
private final Supervisor supervisor = new SimpleSupervisor();
private ListeningExecutorService executorService;
private ProfileService profileService;
@ -126,6 +127,8 @@ public void onEnable() {
executorService = MoreExecutors.listeningDecorator(EvenMoreExecutors.newBoundedCachedThreadPool(0, 1, 20));
sessionManager = new SessionManager(this);
// Set the proper command injector
commands.setInjector(new SimpleInjector(this));
@ -164,14 +167,10 @@ public void run() {
log.info("Loading region data...");
regionContainer.initialize();
flagStateManager = new FlagStateManager(this);
if (configuration.useRegionsScheduler) {
getServer().getScheduler().scheduleSyncRepeatingTask(this, flagStateManager,
FlagStateManager.RUN_DELAY, FlagStateManager.RUN_DELAY);
}
getServer().getScheduler().scheduleSyncRepeatingTask(this, sessionManager, SessionManager.RUN_DELAY, SessionManager.RUN_DELAY);
// Register events
getServer().getPluginManager().registerEvents(sessionManager, this);
(new WorldGuardPlayerListener(this)).registerEvents();
(new WorldGuardBlockListener(this)).registerEvents();
(new WorldGuardEntityListener(this)).registerEvents();
@ -327,8 +326,8 @@ public ConfigurationManager getGlobalConfiguration() {
*
* @return The flag state manager
*/
public FlagStateManager getFlagStateManager() {
return flagStateManager;
public SessionManager getSessionManager() {
return sessionManager;
}
/**
@ -925,15 +924,6 @@ public void broadcastNotification(String msg) {
log.info(msg);
}
/**
* Forgets a player.
*
* @param player The player to remove state information for
*/
public void forgetPlayer(Player player) {
flagStateManager.forget(player);
}
/**
* Checks to see if a player can build at a location. This will return
* true if region protection is disabled.

View File

@ -19,11 +19,6 @@
package com.sk89q.worldguard.bukkit.commands;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandException;
@ -31,6 +26,12 @@
import com.sk89q.worldedit.blocks.ItemType;
import com.sk89q.worldguard.bukkit.ConfigurationManager;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.session.Session;
import com.sk89q.worldguard.session.handler.GodMode;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public class GeneralCommands {
private final WorldGuardPlugin plugin;
@ -54,7 +55,7 @@ public void god(CommandContext args, CommandSender sender) throws CommandExcepti
// Check permissions!
plugin.checkPermission(sender, "worldguard.god");
} else if (args.argsLength() == 1) {
} else {
targets = plugin.matchPlayers(sender, args.getString(0));
// Check permissions!
@ -62,26 +63,29 @@ public void god(CommandContext args, CommandSender sender) throws CommandExcepti
}
for (Player player : targets) {
config.enableGodMode(player);
player.setFireTicks(0);
// Tell the user
if (player.equals(sender)) {
player.sendMessage(ChatColor.YELLOW + "God mode enabled! Use /ungod to disable.");
// Keep track of this
included = true;
} else {
player.sendMessage(ChatColor.YELLOW + "God enabled by "
+ plugin.toName(sender) + ".");
Session session = plugin.getSessionManager().get(player);
if (GodMode.set(player, session, true)) {
player.setFireTicks(0);
// Tell the user
if (player.equals(sender)) {
player.sendMessage(ChatColor.YELLOW + "God mode enabled! Use /ungod to disable.");
// Keep track of this
included = true;
} else {
player.sendMessage(ChatColor.YELLOW + "God enabled by "
+ plugin.toName(sender) + ".");
}
}
}
// The player didn't receive any items, then we need to send the
// user a message so s/he know that something is indeed working
if (!included && args.hasFlag('s')) {
sender.sendMessage(ChatColor.YELLOW.toString() + "Players now have god mode.");
sender.sendMessage(ChatColor.YELLOW + "Players now have god mode.");
}
}
@ -100,7 +104,7 @@ public void ungod(CommandContext args, CommandSender sender) throws CommandExcep
// Check permissions!
plugin.checkPermission(sender, "worldguard.god");
} else if (args.argsLength() == 1) {
} else {
targets = plugin.matchPlayers(sender, args.getString(0));
// Check permissions!
@ -108,25 +112,27 @@ public void ungod(CommandContext args, CommandSender sender) throws CommandExcep
}
for (Player player : targets) {
config.disableGodMode(player);
// Tell the user
if (player.equals(sender)) {
player.sendMessage(ChatColor.YELLOW + "God mode disabled!");
// Keep track of this
included = true;
} else {
player.sendMessage(ChatColor.YELLOW + "God disabled by "
+ plugin.toName(sender) + ".");
Session session = plugin.getSessionManager().get(player);
if (GodMode.set(player, session, false)) {
// Tell the user
if (player.equals(sender)) {
player.sendMessage(ChatColor.YELLOW + "God mode disabled!");
// Keep track of this
included = true;
} else {
player.sendMessage(ChatColor.YELLOW + "God disabled by "
+ plugin.toName(sender) + ".");
}
}
}
// The player didn't receive any items, then we need to send the
// user a message so s/he know that something is indeed working
if (!included && args.hasFlag('s')) {
sender.sendMessage(ChatColor.YELLOW.toString() + "Players no longer have god mode.");
sender.sendMessage(ChatColor.YELLOW + "Players no longer have god mode.");
}
}

View File

@ -250,12 +250,12 @@ public void stopProfile(CommandContext args, final CommandSender sender) throws
@CommandPermissions("worldguard.flushstates")
public void flushStates(CommandContext args, CommandSender sender) throws CommandException {
if (args.argsLength() == 0) {
plugin.getFlagStateManager().forgetAll();
plugin.getSessionManager().resetAllStates();
sender.sendMessage("Cleared all states.");
} else {
Player player = plugin.getServer().getPlayer(args.getString(0));
if (player != null) {
plugin.getFlagStateManager().forget(player);
plugin.getSessionManager().resetState(player);
sender.sendMessage("Cleared states for player \"" + player.getName() + "\".");
}
}

View File

@ -1,88 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.internal;
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;
}
}
}

View File

@ -1,252 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.listener;
import com.sk89q.worldguard.bukkit.BukkitUtil;
import com.sk89q.worldguard.bukkit.ConfigurationManager;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.internal.RegionQueryUtil;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import org.bukkit.GameMode;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* 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<String, PlayerFlagState> states;
/**
* Construct the object.
*
* @param plugin The plugin instance
*/
public FlagStateManager(WorldGuardPlugin plugin) {
this.plugin = plugin;
states = new HashMap<String, PlayerFlagState>();
}
/**
* Run the task.
*/
@Override
public void run() {
Collection<? extends Player> players = BukkitUtil.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);
}
}
ApplicableRegionSet applicable = plugin.getRegionContainer().createQuery().getApplicableRegions(player.getLocation());
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;
}
}

View File

@ -22,6 +22,9 @@
import com.sk89q.worldguard.bukkit.ConfigurationManager;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.event.player.ProcessPlayerEvent;
import com.sk89q.worldguard.session.Session;
import com.sk89q.worldguard.session.handler.GodMode;
import com.sk89q.worldguard.session.handler.WaterBreathing;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@ -61,17 +64,18 @@ private boolean hasAmphibiousGroup(Player player) {
public void onProcessPlayer(ProcessPlayerEvent event) {
ConfigurationManager config = getConfig();
Player player = event.getPlayer();
Session session = getPlugin().getSessionManager().get(player);
if (!config.hasCommandBookGodMode()) {
if (hasGodModeGroup(player) || hasGodModePermission(player)) {
if (hasGodModeGroup(player) || hasGodModePermission(player)) {
if (GodMode.set(player, session, true)) {
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);
if (WaterBreathing.set(player, session, true)) {
log.log(Level.INFO, "Enabled water breathing mode for " + player.getName() + " (player is in group 'wg-amphibious')");
}
}
}

View File

@ -19,46 +19,25 @@
package com.sk89q.worldguard.bukkit.listener;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.bukkit.BukkitUtil;
import com.sk89q.worldguard.bukkit.ConfigurationManager;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.listener.FlagStateManager.PlayerFlagState;
import com.sk89q.guavabackport.cache.CacheBuilder;
import com.sk89q.guavabackport.cache.CacheLoader;
import com.sk89q.guavabackport.cache.LoadingCache;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import com.sk89q.worldguard.session.MoveType;
import com.sk89q.worldguard.session.Session;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.plugin.PluginManager;
import java.util.concurrent.TimeUnit;
import org.bukkit.util.Vector;
public class PlayerMoveListener implements Listener {
private final WorldGuardPlugin plugin;
private LoadingCache<WorldPlayerTuple, Boolean> bypassCache = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterAccess(5, TimeUnit.SECONDS)
.build(new CacheLoader<WorldPlayerTuple, Boolean>() {
@Override
public Boolean load(WorldPlayerTuple tuple) throws Exception {
return plugin.getGlobalRegionManager().hasBypass(tuple.player, tuple.world);
}
});
public PlayerMoveListener(WorldGuardPlugin plugin) {
this.plugin = plugin;
@ -71,196 +50,56 @@ public void registerEvents() {
}
}
private boolean hasBypass(Player player, World world) {
return bypassCache.getUnchecked(new WorldPlayerTuple(world, player));
}
@EventHandler
public void onPlayerRespawn(PlayerRespawnEvent event) {
Player player = event.getPlayer();
/**
* Handles movement related events, including changing gamemode, sending
* greeting/farewell messages, etc.
*
* @param from The before location
* @param to The to location
* @return True if the movement should not be allowed
*/
public boolean shouldDenyMove(Player player, Location from, Location to) {
PlayerFlagState state = plugin.getFlagStateManager().getState(player);
// Flush states in multi-world scenario
if (state.lastWorld != null && !state.lastWorld.equals(to.getWorld())) {
plugin.getFlagStateManager().forget(player);
state = plugin.getFlagStateManager().getState(player);
}
// TODO: Clean up this disaster
World world = from.getWorld();
World toWorld = to.getWorld();
LocalPlayer localPlayer = plugin.wrapPlayer(player);
boolean hasBypass = hasBypass(player, world);
boolean hasRemoteBypass;
if (world.equals(toWorld)) {
hasRemoteBypass = hasBypass;
} else {
hasRemoteBypass = hasBypass(player, toWorld);
}
RegionManager regions = plugin.getGlobalRegionManager().get(toWorld);
if (regions == null) {
return false;
}
Vector pt = new Vector(to.getBlockX(), to.getBlockY(), to.getBlockZ());
ApplicableRegionSet set = regions.getApplicableRegions(pt);
boolean entryAllowed = set.allows(DefaultFlag.ENTRY, localPlayer);
if (!hasRemoteBypass && !entryAllowed) {
player.sendMessage(ChatColor.DARK_RED + "You are not permitted to enter this area.");
return true;
}
// Have to set this state
if (state.lastExitAllowed == null) {
state.lastExitAllowed = plugin.getRegionContainer().createQuery().getApplicableRegions(from).allows(DefaultFlag.EXIT, localPlayer);
}
boolean exitAllowed = set.allows(DefaultFlag.EXIT, localPlayer);
if (!hasBypass && exitAllowed && !state.lastExitAllowed) {
player.sendMessage(ChatColor.DARK_RED + "You are not permitted to leave this area.");
return true;
}
String greeting = set.getFlag(DefaultFlag.GREET_MESSAGE);
String farewell = set.getFlag(DefaultFlag.FAREWELL_MESSAGE);
Boolean notifyEnter = set.getFlag(DefaultFlag.NOTIFY_ENTER);
Boolean notifyLeave = set.getFlag(DefaultFlag.NOTIFY_LEAVE);
GameMode gameMode = set.getFlag(DefaultFlag.GAME_MODE);
if (state.lastFarewell != null && (farewell == null || !state.lastFarewell.equals(farewell))) {
String replacedFarewell = plugin.replaceMacros(player, BukkitUtil.replaceColorMacros(state.lastFarewell));
player.sendMessage(replacedFarewell.replaceAll("\\\\n", "\n").split("\\n"));
}
if (greeting != null && (state.lastGreeting == null || !state.lastGreeting.equals(greeting))) {
String replacedGreeting = plugin.replaceMacros(player, BukkitUtil.replaceColorMacros(greeting));
player.sendMessage(replacedGreeting.replaceAll("\\\\n", "\n").split("\\n"));
}
if ((notifyLeave == null || !notifyLeave) && state.notifiedForLeave != null && state.notifiedForLeave) {
plugin.broadcastNotification(ChatColor.GRAY + "WG: "
+ ChatColor.LIGHT_PURPLE + player.getName()
+ ChatColor.GOLD + " left NOTIFY region");
}
if (notifyEnter != null && notifyEnter && (state.notifiedForEnter == null || !state.notifiedForEnter)) {
StringBuilder regionList = new StringBuilder();
for (ProtectedRegion region : set) {
if (regionList.length() != 0) {
regionList.append(", ");
}
regionList.append(region.getId());
}
plugin.broadcastNotification(ChatColor.GRAY + "WG: "
+ ChatColor.LIGHT_PURPLE + player.getName()
+ ChatColor.GOLD + " entered NOTIFY region: "
+ ChatColor.WHITE
+ regionList);
}
if (!hasBypass && gameMode != null) {
if (player.getGameMode() != gameMode) {
state.lastGameMode = player.getGameMode();
player.setGameMode(gameMode);
} else if (state.lastGameMode == null) {
state.lastGameMode = player.getServer().getDefaultGameMode();
}
} else {
if (state.lastGameMode != null) {
GameMode mode = state.lastGameMode;
state.lastGameMode = null;
player.setGameMode(mode);
}
}
state.lastGreeting = greeting;
state.lastFarewell = farewell;
state.notifiedForEnter = notifyEnter;
state.notifiedForLeave = notifyLeave;
state.lastExitAllowed = exitAllowed;
state.lastWorld = to.getWorld();
state.lastBlockX = to.getBlockX();
state.lastBlockY = to.getBlockY();
state.lastBlockZ = to.getBlockZ();
return false;
Session session = plugin.getSessionManager().get(player);
session.testMoveTo(player, event.getRespawnLocation(), MoveType.RESPAWN, true);
}
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerMove(PlayerMoveEvent event) {
final Player player = event.getPlayer();
World world = player.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
Session session = plugin.getSessionManager().get(player);
final Location override = session.testMoveTo(player, event.getTo(), MoveType.MOVE);
if (wcfg.useRegions) {
if (hasMoved(event.getFrom(), event.getTo())) {
if (shouldDenyMove(player, event.getFrom(), event.getTo())) {
Location newLoc = event.getFrom();
newLoc.setX(newLoc.getBlockX() + 0.5);
newLoc.setY(newLoc.getBlockY());
newLoc.setZ(newLoc.getBlockZ() + 0.5);
event.setTo(newLoc);
if (override != null) {
override.setX(override.getBlockX() + 0.5);
override.setY(override.getBlockY());
override.setZ(override.getBlockZ() + 0.5);
override.setPitch(event.getTo().getPitch());
override.setYaw(event.getTo().getYaw());
Entity vehicle = player.getVehicle();
if (vehicle != null) {
vehicle.eject();
vehicle.teleport(newLoc);
player.teleport(newLoc);
vehicle.setPassenger(player);
event.setTo(override.clone());
Entity vehicle = player.getVehicle();
if (vehicle != null) {
vehicle.eject();
Entity current = vehicle;
while (current != null) {
current.eject();
vehicle.setVelocity(new Vector());
if (vehicle instanceof LivingEntity) {
vehicle.teleport(override.clone());
} else {
vehicle.teleport(override.clone().add(0, 1, 0));
}
current = current.getVehicle();
}
player.teleport(override.clone().add(0, 1, 0));
Bukkit.getScheduler().runTaskLater(plugin, new Runnable() {
@Override
public void run() {
player.teleport(override.clone().add(0, 1, 0));
}
}, 1);
}
}
}
private static boolean hasMoved(Location loc1, Location loc2) {
return loc1.getBlockX() != loc2.getBlockX()
|| loc1.getBlockY() != loc2.getBlockY()
|| loc1.getBlockZ() != loc2.getBlockZ();
}
private static class WorldPlayerTuple {
private final World world;
private final Player player;
private WorldPlayerTuple(World world, Player player) {
this.world = world;
this.player = player;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
WorldPlayerTuple that = (WorldPlayerTuple) o;
if (!player.equals(that.player)) return false;
if (!world.equals(that.world)) return false;
return true;
}
@Override
public int hashCode() {
int result = world.hashCode();
result = 31 * result + player.hashCode();
return result;
}
}
}

View File

@ -21,59 +21,21 @@
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.bukkit.BukkitUtil;
import com.sk89q.worldguard.bukkit.ConfigurationManager;
import com.sk89q.worldguard.bukkit.RegionQuery;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.internal.RegionQueryUtil;
import com.sk89q.worldguard.bukkit.*;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.GlobalRegionManager;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.Enderman;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Fireball;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.entity.Tameable;
import org.bukkit.entity.ThrownPotion;
import org.bukkit.entity.Wither;
import org.bukkit.entity.WitherSkull;
import org.bukkit.entity.Wolf;
import org.bukkit.entity.*;
import org.bukkit.entity.minecart.ExplosiveMinecart;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.*;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.event.entity.CreeperPowerEvent;
import org.bukkit.event.entity.EntityBreakDoorEvent;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.EntityCombustEvent;
import org.bukkit.event.entity.EntityCreatePortalEvent;
import org.bukkit.event.entity.EntityDamageByBlockEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.EntityInteractEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.event.entity.ExplosionPrimeEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.event.entity.PigZapEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.entity.PotionSplashEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.projectiles.ProjectileSource;
@ -144,7 +106,7 @@ private void onEntityDamageByBlock(EntityDamageByBlockEvent event) {
} else if (defender instanceof Player) {
Player player = (Player) defender;
if (isInvincible(player)) {
if (plugin.getSessionManager().get(player).isInvincible(player)) {
event.setCancelled(true);
return;
}
@ -216,7 +178,7 @@ private void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(player.getWorld());
if (isInvincible(player)) {
if (plugin.getSessionManager().get(player).isInvincible(player)) {
if (wcfg.regionInvinciblityRemovesMobs
&& attacker instanceof LivingEntity && !(attacker instanceof Player)
&& !(attacker instanceof Tameable && ((Tameable) attacker).isTamed())) {
@ -323,7 +285,7 @@ private void onEntityDamageByProjectile(EntityDamageByEntityEvent event) {
WorldConfiguration wcfg = cfg.get(player.getWorld());
// Check Invincible
if (isInvincible(player)) {
if (plugin.getSessionManager().get(player).isInvincible(player)) {
event.setCancelled(true);
return;
}
@ -375,7 +337,7 @@ public void onEntityDamage(EntityDamageEvent event) {
} else if (defender instanceof Player) {
Player player = (Player) defender;
if (isInvincible(player)) {
if (plugin.getSessionManager().get(player).isInvincible(player)) {
event.setCancelled(true);
player.setFireTicks(0);
return;
@ -455,9 +417,8 @@ public void onEntityCombust(EntityCombustEvent event) {
if (entity instanceof Player) {
Player player = (Player) entity;
if (cfg.hasGodMode(player) || (wcfg.useRegions && RegionQueryUtil.isInvincible(plugin, player))) {
if (plugin.getSessionManager().get(player).isInvincible(player)) {
event.setCancelled(true);
return;
}
}
}
@ -762,41 +723,12 @@ public void onEntityChangeBlock(EntityChangeBlockEvent event) {
public void onFoodLevelChange(FoodLevelChangeEvent event) {
if (event.getEntity() instanceof Player) {
Player player = (Player) event.getEntity();
if (event.getFoodLevel() < player.getFoodLevel() && isInvincible(player)) {
if (event.getFoodLevel() < player.getFoodLevel() && plugin.getSessionManager().get(player).isInvincible(player)) {
event.setCancelled(true);
}
}
}
/**
* Check if a player is invincible, via either god mode or region flag. If
* the region denies invincibility, the player must have an extra permission
* to override it. (worldguard.god.override-regions)
*
* @param player The player to check
* @return Whether {@code player} is invincible
*/
private boolean isInvincible(Player player) {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(player.getWorld());
boolean god = cfg.hasGodMode(player);
if (wcfg.useRegions) {
Boolean flag = RegionQueryUtil.isAllowedInvinciblity(plugin, player);
boolean allowed = flag == null || flag;
boolean invincible = RegionQueryUtil.isInvincible(plugin, player);
if (allowed) {
return god || invincible;
} else {
return (god && plugin.hasPermission(player, "worldguard.god.override-regions"))
|| invincible;
}
} else {
return god;
}
}
/**
* Checks regions and config settings to protect items from being knocked
* out of item frames.

View File

@ -26,11 +26,12 @@
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.regions.ProtectedRegion;
import com.sk89q.worldguard.session.MoveType;
import com.sk89q.worldguard.session.handler.GameModeFlag;
import com.sk89q.worldguard.util.command.CommandFilter;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
@ -83,10 +84,10 @@ public void registerEvents() {
public void onPlayerGameModeChange(PlayerGameModeChangeEvent event) {
Player player = event.getPlayer();
WorldConfiguration wcfg = plugin.getGlobalStateManager().get(player.getWorld());
if (wcfg.useRegions && !plugin.getGlobalRegionManager().hasBypass(player, player.getWorld())) {
GameMode gameMode = plugin.getRegionContainer().createQuery().getApplicableRegions(player.getLocation()).getFlag(DefaultFlag.GAME_MODE);
if (plugin.getFlagStateManager().getState(player).lastGameMode != null
&& gameMode != null && event.getNewGameMode() != gameMode) {
GameModeFlag handler = plugin.getSessionManager().get(player).getHandler(GameModeFlag.class);
if (handler != null && wcfg.useRegions && !plugin.getGlobalRegionManager().hasBypass(player, player.getWorld())) {
GameMode expected = handler.getSetGameMode();
if (expected != event.getNewGameMode()) {
event.setCancelled(true);
}
}
@ -126,14 +127,7 @@ public void onPlayerJoin(PlayerJoinEvent event) {
Events.fire(new ProcessPlayerEvent(player));
if (wcfg.useRegions) {
PlayerFlagState state = plugin.getFlagStateManager().getState(player);
Location loc = player.getLocation();
state.lastWorld = loc.getWorld();
state.lastBlockX = loc.getBlockX();
state.lastBlockY = loc.getBlockY();
state.lastBlockZ = loc.getBlockZ();
}
plugin.getSessionManager().get(player); // Initializes a session
}
@EventHandler(ignoreCancelled = true)
@ -186,46 +180,6 @@ public void onPlayerLogin(PlayerLoginEvent event) {
}
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
World world = player.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
// This is to make the enter/exit flags accurate -- move events are not
// sent constantly, so it is possible to move just a little enough to
// not trigger the event and then rejoin so that you are then considered
// outside the border. This should work around that.
if (wcfg.useRegions) {
boolean hasBypass = plugin.getGlobalRegionManager().hasBypass(player, world);
PlayerFlagState state = plugin.getFlagStateManager().getState(player);
if (state.lastWorld != null && !hasBypass) {
LocalPlayer localPlayer = plugin.wrapPlayer(player);
Location loc = player.getLocation();
ApplicableRegionSet set = plugin.getRegionContainer().createQuery().getApplicableRegions(loc);
if (state.lastExitAllowed == null) {
state.lastExitAllowed = set.allows(DefaultFlag.EXIT, localPlayer);
}
if (!state.lastExitAllowed || !set.allows(DefaultFlag.ENTRY, localPlayer)) {
// Only if we have the last location cached
if (state.lastWorld.equals(world)) {
Location newLoc = new Location(world, state.lastBlockX + 0.5,
state.lastBlockY, state.lastBlockZ + 0.5);
player.teleport(newLoc);
}
}
}
}
cfg.forgetPlayer(plugin.wrapPlayer(player));
plugin.forgetPlayer(player);
}
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
@ -378,20 +332,20 @@ public void onItemHeldChange(PlayerItemHeldEvent event) {
}
}
@EventHandler(priority= EventPriority.LOW, ignoreCancelled = true)
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerTeleport(PlayerTeleportEvent event) {
World world = event.getFrom().getWorld();
Player player = event.getPlayer();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
if (wcfg.useRegions) {
ApplicableRegionSet set = plugin.getRegionContainer().createQuery().getApplicableRegions(event.getTo());
ApplicableRegionSet setFrom = plugin.getRegionContainer().createQuery().getApplicableRegions(event.getFrom());
LocalPlayer localPlayer = plugin.wrapPlayer(event.getPlayer());
LocalPlayer localPlayer = plugin.wrapPlayer(player);
if (cfg.usePlayerTeleports) {
boolean result = plugin.getPlayerMoveListener().shouldDenyMove(event.getPlayer(), event.getFrom(), event.getTo());
if (result) {
if (null != plugin.getSessionManager().get(player).testMoveTo(player, event.getTo(), MoveType.TELEPORT)) {
event.setCancelled(true);
return;
}
@ -401,7 +355,7 @@ public void onPlayerTeleport(PlayerTeleportEvent event) {
if (!plugin.getGlobalRegionManager().hasBypass(localPlayer, world)
&& !(set.allows(DefaultFlag.ENDERPEARL, localPlayer)
&& setFrom.allows(DefaultFlag.ENDERPEARL, localPlayer))) {
event.getPlayer().sendMessage(ChatColor.DARK_RED + "You're not allowed to go there.");
player.sendMessage(ChatColor.DARK_RED + "You're not allowed to go there.");
event.setCancelled(true);
return;
}

View File

@ -22,12 +22,15 @@
import com.sk89q.worldguard.bukkit.ConfigurationManager;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.util.Locations;
import com.sk89q.worldguard.session.MoveType;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.entity.Vehicle;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.vehicle.VehicleMoveEvent;
import org.bukkit.util.Vector;
public class WorldGuardVehicleListener implements Listener {
@ -52,8 +55,7 @@ public void registerEvents() {
@EventHandler
public void onVehicleMove(VehicleMoveEvent event) {
Vehicle vehicle = event.getVehicle();
if (vehicle.getPassenger() == null
|| !(vehicle.getPassenger() instanceof Player)) return;
if (vehicle.getPassenger() == null || !(vehicle.getPassenger() instanceof Player)) return;
Player player = (Player) vehicle.getPassenger();
World world = vehicle.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
@ -61,12 +63,9 @@ public void onVehicleMove(VehicleMoveEvent event) {
if (wcfg.useRegions) {
// Did we move a block?
if (event.getFrom().getBlockX() != event.getTo().getBlockX()
|| event.getFrom().getBlockY() != event.getTo().getBlockY()
|| event.getFrom().getBlockZ() != event.getTo().getBlockZ()) {
boolean result = plugin.getPlayerMoveListener().shouldDenyMove(player, event.getFrom(), event.getTo());
if (result) {
vehicle.setVelocity(new org.bukkit.util.Vector(0,0,0));
if (Locations.isDifferentBlock(event.getFrom(), event.getTo())) {
if (null != plugin.getSessionManager().get(player).testMoveTo(player, event.getTo(), MoveType.RIDE)) {
vehicle.setVelocity(new Vector(0,0,0));
vehicle.teleport(event.getFrom());
}
}

View File

@ -96,7 +96,7 @@ public final class DefaultFlag {
public static final StateFlag SEND_CHAT = new StateFlag("send-chat", true);
public static final StateFlag RECEIVE_CHAT = new StateFlag("receive-chat", true);
public static final StateFlag ENTRY = new StateFlag("entry", true, RegionGroup.NON_MEMBERS);
public static final StateFlag EXIT = new StateFlag("exit", true, RegionGroup.NON_MEMBERS);
public static final StateFlag EXIT = new StateFlag("exit", false, RegionGroup.NON_MEMBERS);
public static final StateFlag ENDERPEARL = new StateFlag("enderpearl", true);
public static final StateFlag ENTITY_PAINTING_DESTROY = new StateFlag("entity-painting-destroy", true);
public static final StateFlag ENTITY_ITEM_FRAME_DESTROY = new StateFlag("entity-item-frame-destroy", true);
@ -104,6 +104,10 @@ public final class DefaultFlag {
// Flags that adjust behaviors that aren't state flags
public static final StringFlag DENY_MESSAGE = new StringFlag("deny-message",
"" + ChatColor.RED + ChatColor.BOLD + "Hey!" + ChatColor.GRAY + " Sorry, but you can't %what% here.");
public static final StringFlag ENTRY_DENY_MESSAGE = new StringFlag("entry-deny-message",
"" + ChatColor.RED + ChatColor.BOLD + "Hey!" + ChatColor.GRAY + " You are not permitted to enter this area.");
public static final StringFlag EXIT_DENY_MESSAGE = new StringFlag("exit-deny-message",
"" + ChatColor.RED + ChatColor.BOLD + "Hey!" + ChatColor.GRAY + " You are not permitted to leave this area.");
public static final StringFlag GREET_MESSAGE = new StringFlag("greeting");
public static final StringFlag FAREWELL_MESSAGE = new StringFlag("farewell");
public static final BooleanFlag NOTIFY_ENTER = new BooleanFlag("notify-enter");
@ -133,7 +137,8 @@ public final class DefaultFlag {
TNT, LIGHTER, RIDE, USE, INTERACT, PLACE_VEHICLE, DESTROY_VEHICLE, SLEEP,
MOB_DAMAGE, MOB_SPAWNING, DENY_SPAWN, INVINCIBILITY, EXP_DROPS,
CREEPER_EXPLOSION, OTHER_EXPLOSION, ENDERDRAGON_BLOCK_DAMAGE, GHAST_FIREBALL, ENDER_BUILD,
DENY_MESSAGE, GREET_MESSAGE, FAREWELL_MESSAGE, NOTIFY_ENTER, NOTIFY_LEAVE,
DENY_MESSAGE, ENTRY_DENY_MESSAGE, EXIT_DENY_MESSAGE,
GREET_MESSAGE, FAREWELL_MESSAGE, NOTIFY_ENTER, NOTIFY_LEAVE,
EXIT, ENTRY, LIGHTNING, ENTITY_PAINTING_DESTROY, ENDERPEARL,
ENTITY_ITEM_FRAME_DESTROY, ITEM_PICKUP, ITEM_DROP, /*MAX_PLAYERS, MAX_PLAYERS_MESSAGE,*/
HEAL_AMOUNT, HEAL_DELAY, MIN_HEAL, MAX_HEAL,

View File

@ -0,0 +1,48 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.session;
import org.bukkit.Location;
/**
* Types of movements.
*
* <p>Used with {@link Session#testMoveTo(Location, MoveType)}.</p>
*/
public enum MoveType {
RESPAWN(false),
MOVE(true),
TELEPORT(true),
RIDE(true),
OTHER_NON_CANCELLABLE(false),
OTHER_CANCELLABLE(true);
private final boolean cancellable;
MoveType(boolean cancellable) {
this.cancellable = cancellable;
}
public boolean isCancellable() {
return cancellable;
}
}

View File

@ -0,0 +1,222 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.session;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.sk89q.worldguard.bukkit.RegionQuery;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.util.Locations;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.StateFlag.State;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.session.handler.Handler;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Keeps session information on a player.
*/
public class Session {
private final SessionManager manager;
private final HashMap<Class<?>, Handler> handlers = Maps.newLinkedHashMap();
private Location lastValid;
private Set<ProtectedRegion> lastRegionSet;
/**
* Create a new session.
*
* @param manager The session manager
*/
public Session(SessionManager manager) {
checkNotNull(manager, "manager");
this.manager = manager;
}
/**
* Register a new handler.
*
* @param handler A new handler
*/
void register(Handler handler) {
handlers.put(handler.getClass(), handler);
}
/**
* Get the plugin.
*
* @return The plugin
*/
public WorldGuardPlugin getPlugin() {
return getManager().getPlugin();
}
/**
* Get the session manager.
*
* @return The session manager
*/
public SessionManager getManager() {
return manager;
}
/**
* Get a handler by class, if has been registered.
*
* @param type The type of handler
* @param <T> The type of handler
* @return A handler instance, otherwise null
*/
@Nullable
@SuppressWarnings("unchecked")
public <T extends Handler> T getHandler(Class<T> type) {
return (T) handlers.get(type);
}
/**
* Initialize the session.
*
* @param player The player
*/
void initialize(Player player) {
RegionQuery query = getManager().getPlugin().getRegionContainer().createQuery();
Location location = player.getLocation();
ApplicableRegionSet set = query.getApplicableRegions(location);
lastValid = location;
lastRegionSet = set.getRegions();
for (Handler handler : handlers.values()) {
handler.initialize(player, location, set);
}
}
/**
* Tick the session.
*
* @param player The player
*/
void tick(Player player) {
RegionQuery query = getManager().getPlugin().getRegionContainer().createQuery();
Location location = player.getLocation();
ApplicableRegionSet set = query.getApplicableRegions(location);
for (Handler handler : handlers.values()) {
handler.tick(player, set);
}
}
/**
* Re-initialize the session.
*
* @param player The player
*/
void resetState(Player player) {
initialize(player);
}
/**
* Test whether the session has invincibility enabled.
*
* @return Whether invincibility is enabled
*/
public boolean isInvincible(Player player) {
boolean invincible = false;
for (Handler handler : handlers.values()) {
State state = handler.getInvincibility(player);
if (state != null) {
switch (state) {
case DENY: return false;
case ALLOW: invincible = true;
}
}
}
return invincible;
}
/**
* Test movement to the given location.
*
* @param player The player
* @param to The new location
* @param moveType The type of move
* @return The overridden location, if the location is being overridden
* @see #testMoveTo(Player, Location, MoveType, boolean) For an explanation
*/
@Nullable
public Location testMoveTo(Player player, Location to, MoveType moveType) {
return testMoveTo(player, to, moveType, false);
}
/**
* Test movement to the given location.
*
* <p>If a non-null {@link Location} is returned, the player should be
* at that location instead of where the player has tried to move to.</p>
*
* <p>If the {@code moveType} is cancellable
* ({@link MoveType#isCancellable()}, then the last valid location will
* be set to the given one.</p>
*
* @param player The player
* @param to The new location
* @param moveType The type of move
* @param forced Whether to force a check
* @return The overridden location, if the location is being overridden
*/
@Nullable
public Location testMoveTo(Player player, Location to, MoveType moveType, boolean forced) {
RegionQuery query = getManager().getPlugin().getRegionContainer().createQuery();
if (forced || Locations.isDifferentBlock(lastValid, to)) {
ApplicableRegionSet toSet = query.getApplicableRegions(to);
for (Handler handler : handlers.values()) {
if (!handler.testMoveTo(player, lastValid, to, toSet, moveType) && moveType.isCancellable()) {
return lastValid;
}
}
Set<ProtectedRegion> entered = Sets.difference(toSet.getRegions(), lastRegionSet);
Set<ProtectedRegion> exited = Sets.difference(lastRegionSet, toSet.getRegions());
for (Handler handler : handlers.values()) {
if (!handler.onCrossBoundary(player, lastValid, to, toSet, entered, exited, moveType) && moveType.isCancellable()) {
return lastValid;
}
}
lastValid = to;
lastRegionSet = toSet.getRegions();
}
return null;
}
}

View File

@ -0,0 +1,219 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.session;
import com.sk89q.guavabackport.cache.CacheBuilder;
import com.sk89q.guavabackport.cache.CacheLoader;
import com.sk89q.guavabackport.cache.LoadingCache;
import com.sk89q.worldguard.bukkit.BukkitUtil;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.session.handler.*;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Keeps tracks of sessions and also does session-related handling
* (flags, etc.).
*/
public class SessionManager implements Runnable, Listener {
public static final int RUN_DELAY = 20;
public static final long SESSION_LIFETIME = 10;
private final WorldGuardPlugin plugin;
private final LoadingCache<WorldPlayerTuple, Boolean> bypassCache = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterAccess(2, TimeUnit.SECONDS)
.build(new CacheLoader<WorldPlayerTuple, Boolean>() {
@Override
public Boolean load(WorldPlayerTuple tuple) throws Exception {
return plugin.getGlobalRegionManager().hasBypass(tuple.player, tuple.world);
}
});
private final LoadingCache<CacheKey, Session> sessions = CacheBuilder.newBuilder()
.expireAfterAccess(SESSION_LIFETIME, TimeUnit.MINUTES)
.build(new CacheLoader<CacheKey, Session>() {
@Override
public Session load(CacheKey key) throws Exception {
return createSession(key.playerRef.get());
}
});
/**
* Create a new instance.
*
* @param plugin The plugin
*/
public SessionManager(WorldGuardPlugin plugin) {
checkNotNull(plugin, "plugin");
this.plugin = plugin;
}
/**
* Get the plugin.
*
* @return The plugin
*/
public WorldGuardPlugin getPlugin() {
return plugin;
}
/**
* Check whether a player has the region bypass permission.
*
* <p>The return value may be cached for a few seconds.</p>
*
* @param player The player
* @param world The world
* @return A value
*/
public boolean hasBypass(Player player, World world) {
return bypassCache.getUnchecked(new WorldPlayerTuple(world, player));
}
/**
* Re-initialize handlers and clear "last position," "last state," etc.
* information for all players.
*/
public void resetAllStates() {
Collection<? extends Player> players = BukkitUtil.getOnlinePlayers();
for (Player player : players) {
Session session = sessions.getIfPresent(player);
if (session != null) {
session.resetState(player);
}
}
}
/**
* Re-initialize handlers and clear "last position," "last state," etc.
* information.
*
* @param player The player
*/
public void resetState(Player player) {
checkNotNull(player, "player");
@Nullable Session session = sessions.getIfPresent(player);
if (session != null) {
session.resetState(player);
}
}
/**
* Create a session for a player.
*
* @param player The player
* @return The new session
*/
private Session createSession(Player player) {
Session session = new Session(this);
session.register(new HealFlag(session));
session.register(new FeedFlag(session));
session.register(new NotifyEntryFlag(session));
session.register(new NotifyExitFlag(session));
session.register(new EntryFlag(session));
session.register(new ExitFlag(session));
session.register(new GreetingFlag(session));
session.register(new FarewellFlag(session));
session.register(new GameModeFlag(session));
session.register(new InvincibilityFlag(session));
session.register(new GodMode(session));
session.register(new WaterBreathing(session));
session.initialize(player);
return session;
}
/**
* Get a player's session, if one exists.
*
* @param player The player
* @return The session
*/
@Nullable
public Session getIfPresent(Player player) {
return sessions.getIfPresent(player);
}
/**
* Get a player's session. A session will be created if there is no
* existing session for the player.
*
* <p>This method can only be called from the main thread. While the
* session manager itself is thread-safe, some of the handlers may
* require initialization that requires the server main thread.</p>
*
* @param player The player to get a session for
* @return The {@code player}'s session
*/
public Session get(Player player) {
return sessions.getUnchecked(new CacheKey(player));
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
// Pre-load a session
get(event.getPlayer());
}
@Override
public void run() {
for (Player player : BukkitUtil.getOnlinePlayers()) {
get(player).tick(player);
}
}
private static final class CacheKey {
private final WeakReference<Player> playerRef;
private final UUID uuid;
private CacheKey(Player player) {
playerRef = new WeakReference<Player>(player);
uuid = player.getUniqueId();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CacheKey cacheKey = (CacheKey) o;
return uuid.equals(cacheKey.uuid);
}
@Override
public int hashCode() {
return uuid.hashCode();
}
}
}

View File

@ -0,0 +1,55 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.session;
import org.bukkit.World;
import org.bukkit.entity.Player;
class WorldPlayerTuple {
final World world;
final Player player;
WorldPlayerTuple(World world, Player player) {
this.world = world;
this.player = player;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
WorldPlayerTuple that = (WorldPlayerTuple) o;
if (!player.equals(that.player)) return false;
if (!world.equals(that.world)) return false;
return true;
}
@Override
public int hashCode() {
int result = world.hashCode();
result = 31 * result + player.hashCode();
return result;
}
}

View File

@ -0,0 +1,60 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.session.handler;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.session.MoveType;
import com.sk89q.worldguard.session.Session;
import org.bukkit.Location;
import org.bukkit.entity.Player;
public class EntryFlag extends Handler {
private static final long MESSAGE_THRESHOLD = 1000 * 2;
private long lastMessage;
public EntryFlag(Session session) {
super(session);
}
@Override
public boolean testMoveTo(Player player, Location from, Location to, ApplicableRegionSet toSet, MoveType moveType) {
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
boolean allowed = toSet.testState(localPlayer, DefaultFlag.ENTRY);
if (!getSession().getManager().hasBypass(player, to.getWorld()) && !allowed && moveType.isCancellable()) {
String message = toSet.queryValue(localPlayer, DefaultFlag.ENTRY_DENY_MESSAGE);
long now = System.currentTimeMillis();
if ((now - lastMessage) > MESSAGE_THRESHOLD && message != null && !message.isEmpty()) {
player.sendMessage(message);
lastMessage = now;
}
return false;
} else {
return true;
}
}
}

View File

@ -0,0 +1,85 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.session.handler;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.flags.StateFlag.State;
import com.sk89q.worldguard.session.MoveType;
import com.sk89q.worldguard.session.Session;
import org.bukkit.Location;
import org.bukkit.entity.Player;
public class ExitFlag extends FlagValueChangeHandler<State> {
private static final long MESSAGE_THRESHOLD = 1000 * 2;
private String storedMessage;
private long lastMessage;
public ExitFlag(Session session) {
super(session, DefaultFlag.EXIT);
}
private void update(LocalPlayer localPlayer, ApplicableRegionSet set, State newState) {
if (newState == State.DENY) {
storedMessage = set.queryValue(localPlayer, DefaultFlag.EXIT_DENY_MESSAGE);
}
}
private void sendMessage(Player player) {
long now = System.currentTimeMillis();
if ((now - lastMessage) > MESSAGE_THRESHOLD && storedMessage != null && !storedMessage.isEmpty()) {
player.sendMessage(storedMessage);
lastMessage = now;
}
}
@Override
protected void onInitialValue(Player player, ApplicableRegionSet set, State value) {
update(getPlugin().wrapPlayer(player), set, value);
}
@Override
protected boolean onSetValue(Player player, Location from, Location to, ApplicableRegionSet toSet, State currentValue, State lastValue, MoveType moveType) {
if (getSession().getManager().hasBypass(player, from.getWorld())) {
return true;
}
update(getPlugin().wrapPlayer(player), toSet, currentValue);
return true;
}
@Override
protected boolean onAbsentValue(Player player, Location from, Location to, ApplicableRegionSet toSet, State lastValue, MoveType moveType) {
if (getSession().getManager().hasBypass(player, from.getWorld())) {
return true;
}
if (lastValue == State.DENY) {
sendMessage(player);
return false;
}
return true;
}
}

View File

@ -0,0 +1,78 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.session.handler;
import com.google.common.collect.Sets;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.session.MoveType;
import com.sk89q.worldguard.session.Session;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.util.Collections;
import java.util.Set;
public class FarewellFlag extends Handler {
private Set<String> lastMessageStack = Collections.emptySet();
public FarewellFlag(Session session) {
super(session);
}
private Set<String> getMessages(Player player, ApplicableRegionSet set) {
return Sets.newLinkedHashSet(set.queryAllValues(getPlugin().wrapPlayer(player), DefaultFlag.FAREWELL_MESSAGE));
}
@Override
public void initialize(Player player, Location current, ApplicableRegionSet set) {
lastMessageStack = getMessages(player, set);
}
@Override
public boolean onCrossBoundary(Player player, Location from, Location to, ApplicableRegionSet toSet, Set<ProtectedRegion> entered, Set<ProtectedRegion> exited, MoveType moveType) {
Set<String> messages = getMessages(player, toSet);
if (!messages.isEmpty()) {
// Due to flag priorities, we have to collect the lower
// priority flag values separately
for (ProtectedRegion region : toSet) {
String message = region.getFlag(DefaultFlag.FAREWELL_MESSAGE);
if (message != null) {
messages.add(message);
}
}
}
for (String message : lastMessageStack) {
if (!messages.contains(message)) {
player.sendMessage(getPlugin().replaceMacros(player, message).replaceAll("\\\\n", "\n").split("\\n"));
break;
}
}
lastMessageStack = messages;
return true;
}
}

View File

@ -0,0 +1,77 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.session.handler;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.session.Session;
import org.bukkit.GameMode;
import org.bukkit.entity.Player;
public class FeedFlag extends Handler {
private long lastFeed = 0;
public FeedFlag(Session session) {
super(session);
}
@Override
public void tick(Player player, ApplicableRegionSet set) {
if (!getSession().isInvincible(player) && player.getGameMode() != GameMode.CREATIVE) {
long now = System.currentTimeMillis();
Integer feedAmount = set.getFlag(DefaultFlag.FEED_AMOUNT);
Integer feedDelay = set.getFlag(DefaultFlag.FEED_DELAY);
Integer minHunger = set.getFlag(DefaultFlag.MIN_FOOD);
Integer maxHunger = set.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());
lastFeed = now;
} else if (now - lastFeed > feedDelay * 1000) {
// clamp health between minimum and maximum
player.setFoodLevel(Math.min(maxHunger, Math.max(minHunger, player.getFoodLevel() + feedAmount)));
player.setSaturation(player.getFoodLevel());
lastFeed = now;
}
}
}
}

View File

@ -0,0 +1,74 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.session.handler;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.session.MoveType;
import com.sk89q.worldguard.session.Session;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.util.Set;
public abstract class FlagValueChangeHandler<T> extends Handler {
private final Flag<T> flag;
private T lastValue;
protected FlagValueChangeHandler(Session session, Flag<T> flag) {
super(session);
this.flag = flag;
}
@Override
public final void initialize(Player player, Location current, ApplicableRegionSet set) {
lastValue = set.queryValue(getPlugin().wrapPlayer(player), flag);
if (lastValue != null) {
onInitialValue(player, set, lastValue);
}
}
@Override
public boolean onCrossBoundary(Player player, Location from, Location to, ApplicableRegionSet toSet, Set<ProtectedRegion> entered, Set<ProtectedRegion> exited, MoveType moveType) {
T currentValue = toSet.queryValue(getPlugin().wrapPlayer(player), flag);
boolean allowed = true;
if (currentValue == null && lastValue != null) {
allowed = onAbsentValue(player, from, to, toSet, lastValue, moveType);
} else if (currentValue != null && currentValue != lastValue) {
allowed = onSetValue(player, from, to, toSet, currentValue, lastValue, moveType);
}
if (allowed) {
lastValue = currentValue;
}
return allowed;
}
protected abstract void onInitialValue(Player player, ApplicableRegionSet set, T value);
protected abstract boolean onSetValue(Player player, Location from, Location to, ApplicableRegionSet toSet, T currentValue, T lastValue, MoveType moveType);
protected abstract boolean onAbsentValue(Player player, Location from, Location to, ApplicableRegionSet toSet, T lastValue, MoveType moveType);
}

View File

@ -0,0 +1,80 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.session.handler;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.session.MoveType;
import com.sk89q.worldguard.session.Session;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
public class GameModeFlag extends FlagValueChangeHandler<GameMode> {
private GameMode originalGameMode;
private GameMode setGameMode;
public GameModeFlag(Session session) {
super(session, DefaultFlag.GAME_MODE);
}
public GameMode getSetGameMode() {
return setGameMode;
}
private void updateGameMode(Player player, GameMode newValue, World world) {
if (player.getGameMode() != newValue) {
if (originalGameMode == null) {
originalGameMode = player.getGameMode();
}
if (!getSession().getManager().hasBypass(player, world)) {
player.setGameMode(newValue);
setGameMode = newValue;
}
}
}
@Override
protected void onInitialValue(Player player, ApplicableRegionSet set, GameMode value) {
updateGameMode(player, value, player.getWorld());
}
@Override
protected boolean onSetValue(Player player, Location from, Location to, ApplicableRegionSet toSet, GameMode currentValue, GameMode lastValue, MoveType moveType) {
updateGameMode(player, currentValue, to.getWorld());
return true;
}
@Override
protected boolean onAbsentValue(Player player, Location from, Location to, ApplicableRegionSet toSet, GameMode lastValue, MoveType moveType) {
if (originalGameMode != null) {
if (player.getGameMode() == setGameMode) {
player.setGameMode(originalGameMode);
}
originalGameMode = null;
}
return true;
}
}

View File

@ -0,0 +1,76 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.session.handler;
import com.sk89q.commandbook.CommandBook;
import com.sk89q.commandbook.GodComponent;
import com.sk89q.worldguard.protection.flags.StateFlag.State;
import com.sk89q.worldguard.session.Session;
import org.bukkit.entity.Player;
import javax.annotation.Nullable;
public class GodMode extends Handler {
private boolean godMode;
public GodMode(Session session) {
super(session);
}
public boolean hasGodMode(Player player) {
if (getPlugin().getGlobalStateManager().hasCommandBookGodMode()) {
GodComponent god = CommandBook.inst().getComponentManager().getComponent(GodComponent.class);
if (god != null) {
return god.hasGodMode(player);
}
}
return godMode;
}
public void setGodMode(Player player, boolean godMode) {
if (getPlugin().getGlobalStateManager().hasCommandBookGodMode()) {
GodComponent god = CommandBook.inst().getComponentManager().getComponent(GodComponent.class);
if (god != null) {
god.enableGodMode(player);
}
}
this.godMode = godMode;
}
@Nullable
@Override
public State getInvincibility(Player player) {
return hasGodMode(player) ? State.ALLOW : null;
}
public static boolean set(Player player, Session session, boolean value) {
GodMode godMode = session.getHandler(GodMode.class);
if (godMode != null) {
godMode.setGodMode(player, value);
return true;
} else{
return false;
}
}
}

View File

@ -0,0 +1,69 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.session.handler;
import com.google.common.collect.Sets;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.session.MoveType;
import com.sk89q.worldguard.session.Session;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
public class GreetingFlag extends Handler {
private Set<String> lastMessageStack = Collections.emptySet();
public GreetingFlag(Session session) {
super(session);
}
@Override
public boolean onCrossBoundary(Player player, Location from, Location to, ApplicableRegionSet toSet, Set<ProtectedRegion> entered, Set<ProtectedRegion> exited, MoveType moveType) {
Collection<String> messages = toSet.queryAllValues(getPlugin().wrapPlayer(player), DefaultFlag.GREET_MESSAGE);
for (String message : messages) {
if (!lastMessageStack.contains(message)) {
player.sendMessage(getPlugin().replaceMacros(player, message).replaceAll("\\\\n", "\n").split("\\n"));
break;
}
}
lastMessageStack = Sets.newHashSet(messages);
if (!lastMessageStack.isEmpty()) {
// Due to flag priorities, we have to collect the lower
// priority flag values separately
for (ProtectedRegion region : toSet) {
String message = region.getFlag(DefaultFlag.GREET_MESSAGE);
if (message != null) {
lastMessageStack.add(message);
}
}
}
return true;
}
}

View File

@ -0,0 +1,148 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.session.handler;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.StateFlag.State;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.session.MoveType;
import com.sk89q.worldguard.session.Session;
import com.sk89q.worldguard.session.SessionManager;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import javax.annotation.Nullable;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Stores session data and possibly acts on it.
*/
public abstract class Handler {
private final Session session;
/**
* Create a new handler.
*
* @param session The session
*/
protected Handler(Session session) {
checkNotNull(session, "session");
this.session = session;
}
/**
* Get the plugin.
*
* @return The plugin
*/
public WorldGuardPlugin getPlugin() {
return getSession().getManager().getPlugin();
}
/**
* Get the session.
*
* @return The session
*/
public Session getSession() {
return session;
}
/**
* Called when the session is first being created or
* {@code /wg flushstates} is used.
*
* @param player The player
* @param current The player's current location
* @param set The regions for the current location
*/
public void initialize(Player player, Location current, ApplicableRegionSet set) {
}
/**
* Called when {@link Session#testMoveTo(Player, Location, MoveType)} is called.
*
* <p>If this method returns {@code false}, then no other handlers
* will be run (for this move attempt).</p>
*
* @param player The player
* @param from The previous, valid, location
* @param to The new location to test
* @param toSet The regions for the new location
* @param moveType The type of movement
* @return Whether the movement should be allowed
*/
public boolean testMoveTo(Player player, Location from, Location to, ApplicableRegionSet toSet, MoveType moveType) {
return true;
}
/**
* Called when a player has moved into a new location where either
* there are fewer regions or more regions.
*
* <p>This is called only if the move test
* ({@link Session#testMoveTo(Player, Location, MoveType)}) was successful.</p>
*
* <p>If this method returns {@code false}, then no other handlers
* will be run (for this move attempt).</p>
*
* @param player The player
* @param from The previous, valid, location
* @param to The new location to test
* @param toSet The regions for the new location
* @param entered The list of regions that have been entered
* @param exited The list of regions that have been left
* @param moveType The type of move
* @return Whether the movement should be allowed
*/
public boolean onCrossBoundary(Player player, Location from, Location to, ApplicableRegionSet toSet,
Set<ProtectedRegion> entered, Set<ProtectedRegion> exited, MoveType moveType) {
return true;
}
/**
* Called periodically (at least once every second) by
* {@link SessionManager} in the server's main thread.
*
* @param player The player
* @param set The regions for the player's current location
*/
public void tick(Player player, ApplicableRegionSet set) {
}
/**
* Return whether the player should be invincible.
*
* <p>{@link State#DENY} can be returned to prevent invincibility
* even if another handler permits it.</p>
*
* @param player The player
* @return Invincibility state
*/
@Nullable
public State getInvincibility(Player player) {
return null;
}
}

View File

@ -0,0 +1,84 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.session.handler;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.session.Session;
import org.bukkit.GameMode;
import org.bukkit.entity.Player;
public class HealFlag extends Handler {
private long lastHeal = 0;
public HealFlag(Session session) {
super(session);
}
@Override
public void tick(Player player, ApplicableRegionSet set) {
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
if (!getSession().isInvincible(player) && player.getGameMode() != GameMode.CREATIVE) {
if (player.getHealth() <= 0) {
return;
}
long now = System.currentTimeMillis();
Integer healAmount = set.queryValue(localPlayer, DefaultFlag.HEAL_AMOUNT);
Integer healDelay = set.queryValue(localPlayer, DefaultFlag.HEAL_DELAY);
Double minHealth = set.queryValue(localPlayer, DefaultFlag.MIN_HEAL);
Double maxHealth = set.queryValue(localPlayer, 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
lastHeal = now;
} else if (now - lastHeal > healDelay * 1000) {
// clamp health between minimum and maximum
player.setHealth(Math.min(maxHealth, Math.max(minHealth, player.getHealth() + healAmount)));
lastHeal = now;
}
}
}
}

View File

@ -0,0 +1,68 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.session.handler;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.flags.StateFlag.State;
import com.sk89q.worldguard.session.MoveType;
import com.sk89q.worldguard.session.Session;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import javax.annotation.Nullable;
public class InvincibilityFlag extends FlagValueChangeHandler<State> {
@Nullable
private State invincibility;
public InvincibilityFlag(Session session) {
super(session, DefaultFlag.INVINCIBILITY);
}
@Override
protected void onInitialValue(Player player, ApplicableRegionSet set, State value) {
invincibility = value;
}
@Override
protected boolean onSetValue(Player player, Location from, Location to, ApplicableRegionSet toSet, State currentValue, State lastValue, MoveType moveType) {
invincibility = currentValue;
return true;
}
@Override
protected boolean onAbsentValue(Player player, Location from, Location to, ApplicableRegionSet toSet, State lastValue, MoveType moveType) {
invincibility = null;
return true;
}
@Override
@Nullable
public State getInvincibility(Player player) {
if (invincibility == State.DENY && getPlugin().hasPermission(player, "worldguard.god.override-regions")) {
return null;
}
return invincibility;
}
}

View File

@ -0,0 +1,68 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.session.handler;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.session.MoveType;
import com.sk89q.worldguard.session.Session;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Player;
public class NotifyEntryFlag extends FlagValueChangeHandler<Boolean> {
public NotifyEntryFlag(Session session) {
super(session, DefaultFlag.NOTIFY_ENTER);
}
@Override
protected void onInitialValue(Player player, ApplicableRegionSet set, Boolean value) {
}
@Override
protected boolean onSetValue(Player player, Location from, Location to, ApplicableRegionSet toSet, Boolean currentValue, Boolean lastValue, MoveType moveType) {
StringBuilder regionList = new StringBuilder();
for (ProtectedRegion region : toSet) {
if (regionList.length() != 0) {
regionList.append(", ");
}
regionList.append(region.getId());
}
getPlugin().broadcastNotification(ChatColor.GRAY + "WG: "
+ ChatColor.LIGHT_PURPLE + player.getName()
+ ChatColor.GOLD + " entered NOTIFY region: "
+ ChatColor.WHITE
+ regionList);
return true;
}
@Override
protected boolean onAbsentValue(Player player, Location from, Location to, ApplicableRegionSet toSet, Boolean lastValue, MoveType moveType) {
return true;
}
}

View File

@ -0,0 +1,55 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.session.handler;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.session.MoveType;
import com.sk89q.worldguard.session.Session;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Player;
public class NotifyExitFlag extends FlagValueChangeHandler<Boolean> {
private Boolean notifiedForLeave = false;
public NotifyExitFlag(Session session) {
super(session, DefaultFlag.NOTIFY_LEAVE);
}
@Override
protected void onInitialValue(Player player, ApplicableRegionSet set, Boolean value) {
}
@Override
protected boolean onSetValue(Player player, Location from, Location to, ApplicableRegionSet toSet, Boolean currentValue, Boolean lastValue, MoveType moveType) {
return true;
}
@Override
protected boolean onAbsentValue(Player player, Location from, Location to, ApplicableRegionSet toSet, Boolean lastValue, MoveType moveType) {
getPlugin().broadcastNotification(ChatColor.GRAY + "WG: "
+ ChatColor.LIGHT_PURPLE + player.getName()
+ ChatColor.GOLD + " left NOTIFY region");
return true;
}
}

View File

@ -0,0 +1,51 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.session.handler;
import com.sk89q.worldguard.session.Session;
import org.bukkit.entity.Player;
public class WaterBreathing extends Handler {
public boolean waterBreathing;
public WaterBreathing(Session session) {
super(session);
}
public boolean hasWaterBreathing() {
return waterBreathing;
}
public void setWaterBreathing(boolean waterBreathing) {
this.waterBreathing = waterBreathing;
}
public static boolean set(Player player, Session session, boolean value) {
WaterBreathing waterBreathing = session.getHandler(WaterBreathing.class);
if (waterBreathing != null) {
waterBreathing.setWaterBreathing(value);
return true;
} else{
return false;
}
}
}