mirror of
https://github.com/EngineHub/WorldGuard.git
synced 2024-11-10 21:10:16 +01:00
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:
parent
643345b459
commit
aae521b727
@ -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() {
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
Session session = plugin.getSessionManager().get(player);
|
||||
|
||||
// Tell the user
|
||||
if (player.equals(sender)) {
|
||||
player.sendMessage(ChatColor.YELLOW + "God mode enabled! Use /ungod to disable.");
|
||||
if (GodMode.set(player, session, true)) {
|
||||
player.setFireTicks(0);
|
||||
|
||||
// Keep track of this
|
||||
included = true;
|
||||
} else {
|
||||
player.sendMessage(ChatColor.YELLOW + "God enabled by "
|
||||
+ plugin.toName(sender) + ".");
|
||||
// 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);
|
||||
Session session = plugin.getSessionManager().get(player);
|
||||
|
||||
// Tell the user
|
||||
if (player.equals(sender)) {
|
||||
player.sendMessage(ChatColor.YELLOW + "God mode disabled!");
|
||||
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) + ".");
|
||||
// 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.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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() + "\".");
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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')");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
48
src/main/java/com/sk89q/worldguard/session/MoveType.java
Normal file
48
src/main/java/com/sk89q/worldguard/session/MoveType.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
222
src/main/java/com/sk89q/worldguard/session/Session.java
Normal file
222
src/main/java/com/sk89q/worldguard/session/Session.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
219
src/main/java/com/sk89q/worldguard/session/SessionManager.java
Normal file
219
src/main/java/com/sk89q/worldguard/session/SessionManager.java
Normal 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
148
src/main/java/com/sk89q/worldguard/session/handler/Handler.java
Normal file
148
src/main/java/com/sk89q/worldguard/session/handler/Handler.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user