Compare commits

...
42 Commits
Author SHA1 Message Date
sk89q 9cf85caf3c Set version to 6.1. 2015-06-08 15:04:59 -07:00
sk89q 2f1343f408 Updated changelog for v6.1. 2015-06-08 15:04:52 -07:00
wizjany 3cb6c4e46f Check both attacker and defender locations for PvP.
Fixes WORLDGUARD-3494.
2015-06-08 14:37:32 -07:00
sk89q 7f9b850288 Always generate Javadocs and sources .jar. 2015-06-08 14:37:32 -07:00
sk89q e8d4f2fd84 Turn off doclint. 2015-06-08 14:37:32 -07:00
sk89q f3891aaaf9 Add a workaround for incorrect piston retract information. 2015-06-03 23:46:24 -07:00
wizjany ea75549a29 Clean up Heal and Feed flags.
Allow the flags to increase values for players who are invincible (or in creative mode),
but not decrease them.
Fixes WORLDGUARD-3492.
2015-06-04 02:02:53 -04:00
wizjany fbd8206038 Check for connected chests.
Fixes WORLDGUARD-3021.
2015-05-29 03:56:14 -04:00
wizjany 522ac459db Fix weather lock flag.
Probably. Maybe.
Fixes WORLDGUARD-3452.
2015-05-29 02:26:32 -04:00
wizjany 255dd2d41a Add support for Spigot's BlockExplodeEvent.
Also update Bukkit dependency and guava version quirks.
Fixes WORLDGUARD-3484.
2015-05-29 01:49:20 -04:00
wizjany cf1716ff37 Separate vehicles and animals from INTERACT flag.
Destroying vehicles now checks only the vehicle-destroy flag.
Damaging animals checks the new damage-animals flag.
These are both allowed for members by default, like other build-dependent flags.

Fixes WORLDGUARD-3427 and WORLDGUARD-3358.
2015-05-28 17:21:58 -04:00
sk89q a277e69e9c Get the session during the gamemode event lazily. 2015-05-28 11:28:02 -07:00
sk89q ec5bb32510 Add -s to show stack traces with the event debugging command. 2015-05-27 22:18:30 -07:00
Wizjany 8ddb7d4b99 Don't add a period for custom blacklist messages.
Fixes WORLDGUARD-3472
2015-05-02 22:38:42 -04:00
Wizjany 3258bff2d1 Fix CommandFilter matching emoticons etc.
Fixes WORLDGUARD-3461.
2015-04-18 12:01:21 -04:00
Wizjany 8d7d32a2d2 Check event cancellation before playing deny effect for bucket events. 2015-04-05 15:44:43 -04:00
Wizjany a907eb2348 Move repeaters/comparators from use to build.
This should mirror the protection given in WG 5.9.
2015-03-13 23:34:22 -04:00
wizjany 32132b5b0a Protect against spawn egg usage.
Fixes WORLDGUARD-3347.
2015-03-11 01:46:55 -04:00
wizjany c0c7c3215e Mark Player/Group Domains as dirty in a few missing places.
Fixes WORLDGUARD-3404.
2015-03-11 00:44:41 -04:00
Wizjany ddf0f41061 Actually register WorldRulesListener for events.
Fixes WORLDGUARD-3406.
2015-03-03 13:09:50 -05:00
Wizjany d3ecbcb18a Protect switching inverted daylight detectors too. 2015-02-28 18:39:54 -05:00
wizjany b7f4262978 Add comparators to USE too for consistency. 2015-02-19 21:21:17 -05:00
wizjany 60e6f92c64 Have repeaters be covered by the USE flag. 2015-02-19 21:17:45 -05:00
wizjany 98af7966cd Added weather-lock flag.
Valid values are clear or downfall. Unset to restore to normal world weather.
2015-02-18 02:24:31 -05:00
wizjany 99d042d260 Added time-lock flag.
Valid values are 0 to 24000 for absolute time, or +- any number for relative time.
Closes WORLDGUARD-3379.
2015-02-18 01:59:30 -05:00
wizjany c9d6166fcb Check for null task fields.
Fixes WORLDGUARD-3372.
2015-02-17 16:51:02 -05:00
sk89q 752ccec150 Don't call initialize() on non-cancellable movements.
Fixes WORLDGUARD-3362.
2015-02-11 17:12:10 -08:00
sk89q 91ccb95672 Add classloader override to the build POM. 2015-02-11 17:09:10 -08:00
wizjany 4caff457d3 Add Citizens NPCs to NPC detection for region whitelisting.
Fixes WORLDGUARD-3356.
2015-02-04 17:03:01 -05:00
wizjany a1a6ee7107 Fixed blocks (e.g. sugar canes) adjacent to physics blocks (e.g. sand) not updating.
Fixes WORLDGUARD-3367. This change MAY have breaking unintended consequences,
but the physics configs seem to still be working.
2015-02-04 03:33:37 -05:00
sk89q af157b88bd Handle empty sets in SetFlag. 2015-01-30 00:03:25 -08:00
sk89q ea4f4c088b Have enderchests be covered by the USE flag.
Fixes WORLDGUARD-3336.
2015-01-28 01:36:07 -08:00
sk89q 6559ed5c1a Have tripwire be covered by the USE flag.
Fixes WORLDGUARD-3351.
2015-01-28 01:35:17 -08:00
sk89q deddcf8dd2 Handle null block attacker.
Fixes WORLDGUARD-3350.
2015-01-28 01:26:50 -08:00
sk89q dfe536a2d2 Fix issues with MC 1.7 compatibility. 2015-01-28 01:11:36 -08:00
sk89q 5bfb348354 Add a fall-damage flag.
Closes WORLDGUARD-2279.
2015-01-28 01:01:43 -08:00
sk89q afcf93b7b1 Reset handler caches when a move type is non-cancellable. 2015-01-27 15:21:56 -08:00
sk89q e1843624bb Add exit-via-teleport flag (default allow). 2015-01-27 15:01:01 -08:00
wizjany 0f4e7b5061 Creeper explosions with a player target cause should no longer be ignored.
Also fixed primed tnt being checked twice for tnt flags. TNT Minecarts are not included, as was prior behavior.
Fixes WORLDGUARD-3344
2015-01-24 23:00:19 -05:00
wizjany 869ead63bc Fix armor stands to behave more like item frames.
Placing and modifying them respects permissions, and  they are no longer blocked by mob-spawning deny.
2015-01-24 17:02:55 -05:00
sk89q 6a6de7802b Fix missing material data for 1.8 items.
Fixes WORLDGUARD-3306.
2015-01-22 21:42:53 -08:00
sk89q b50302d9d0 Set version back to 6.0.0-SNAPSHOT. 2015-01-20 19:28:22 -08:00
29 changed files with 579 additions and 186 deletions

No files matched your search

+35
View File
@@ -1,5 +1,40 @@
# Changelog
## 6.1
* Added `exit-via-teleport` flag (default allow) to control exiting an exit=deny region via teleportation.
* Added a `fall-damage` flag to control player damage caused by falling.
* Added a `time-lock` flag to lock players' time of day. Valid values are from 0 to 24000 for absolute time, or +- any number for relative time.
* Added a `weather-lock` flag to lock players' weather. Valid values are "clear" or "downfall". Unset to restore to normal world weather.
* Added `-s` to the event debugging commands to show a stack trace rather than attempt to detect the causing plugin.
* Added support for using the `-e` argument (sets an empty value for the flag) in the flag set command when the type of flag is of the 'set' type.
* Added NPCs from the Citizens plugin to a whitelist so they are not protected.
* Added support for Spigot's BlockExplodeEvent.
* Changed tripwire to fall under the `use` flag.
* Changed enderchests to fall under the `use` flag.
* Changed vehicles and animals so they are not included in the `interact` flag.
* Changed the display of custom blacklist messages to no longer include a period at the end.
* Changed protection logic to consider connected chests.
* Changed the heal and feed flags to increase values for players who are invincible (or in creative mode) but not decrease them.
* Changed PvP protection to consider both attacker and defender locations.
* Fixed missing protection data for some 1.8-added blocks.
* Fixed compatibility issues with MC 1.7.
* Fixed inverted daylight detectors not being protected.
* Fixed spawn eggs not being included in protection.
* Fixed piston blocking not working due to a bug in Spigot.
* Fixed the blocking of certain invalid entity damage events.
* Fixed creeper explosions not being blocked in certain situations with explosion related flags set.
* Fixed "stickiness" with some position-related flags, sometimes resulting in rubber banding in the exit flags.
* Fixed armor stands so that they are treated more like item frames than mobs.
* Fixed blocks (e.g. sugar canes) adjacent to physics blocks (e.g. sand) not updating.
* Fixed a NullPointerException that occurred sometimes when generating the scheduler section of the report function (`/wg report`).
* Fixed the "no XP drops" configuration not functioning following a previous release.
* Fixed changes to region ownership sometimes not triggering a region database save.
* Fixed bucket protection displaying the "deny effect" even if bucket use was not prevented.
* Fixed CommandFilter matching emoticons and other unwanted characters.
* Fixed an exception occurring sometimes during game mode changes.
* Fixed primed TNT being checked twice for TNT flags.
## 6.0 beta 5
MC 1.7.9, 1.7.10 and 1.8 (Spigot only) are supported.
+42 -51
View File
@@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.sk89q</groupId>
<artifactId>worldguard</artifactId>
<version>6.0.0-beta-05</version>
<version>6.1</version>
<packaging>jar</packaging>
<!-- Project information -->
@@ -66,8 +66,8 @@
<url>http://maven.sk89q.com/repo/</url>
</repository>
<repository>
<id>bukkit-repo</id>
<url>http://repo.bukkit.org/content/groups/public</url>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
</repository>
</repositories>
@@ -92,8 +92,15 @@
<dependency>
<groupId>com.sk89q.spigot</groupId>
<artifactId>bukkit</artifactId>
<artifactId>bukkit-classloader-check</artifactId>
<version>1.8-R0.1-SNAPSHOT</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.8.6-R0.1-SNAPSHOT</version>
<scope>compile</scope>
<type>jar</type>
</dependency>
@@ -129,14 +136,6 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>10.0.1</version> <!-- Bukkit only bundles 10.0.1 -->
<scope>compile</scope> <!-- required runtime dependency -->
<type>jar</type>
</dependency>
<dependency>
<!-- Contains parts of Guava that are not compatible
between Bukkit 10.0.1 and 17+ -->
@@ -461,6 +460,37 @@
<tagNameFormat>@{project.version}</tagNameFormat>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.8.1</version>
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -492,43 +522,4 @@
</plugin>
</plugins>
</build>
<profiles>
<!-- Attach javadocs and source .jars -->
<profile>
<id>attach-docs</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.8.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
@@ -44,7 +44,7 @@ public class TellAction extends RepeatGuardedAction {
if (event.getPlayer() != null) {
if (message != null) {
event.getPlayer().printRaw(ChatColor.YELLOW + String.format(message, event.getTarget().getFriendlyName()) + ".");
event.getPlayer().printRaw(ChatColor.YELLOW + String.format(message, event.getTarget().getFriendlyName()));
} else {
event.getPlayer().printRaw(ChatColor.YELLOW + "You're not allowed to " + event.getDescription() + " " +
event.getTarget().getFriendlyName() + ".");
@@ -195,6 +195,7 @@ public class WorldGuardPlugin extends JavaPlugin {
(new ChestProtectionListener(this)).registerEvents();
(new RegionProtectionListener(this)).registerEvents();
(new RegionFlagsListener(this)).registerEvents();
(new WorldRulesListener(this)).registerEvents();
(new BlockedPotionsListener(this)).registerEvents();
(new EventAbstractionListener(this)).registerEvents();
(new PlayerModesListener(this)).registerEvents();
@@ -129,6 +129,17 @@ public final class Cause {
return null;
}
@Nullable
public Entity getFirstNonPlayerEntity() {
for (Object object : causes) {
if (object instanceof Entity && !(object instanceof Player)) {
return (Entity) object;
}
}
return null;
}
@Nullable
public Block getFirstBlock() {
for (Object object : causes) {
@@ -19,10 +19,7 @@
package com.sk89q.worldguard.bukkit.commands;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.minecraft.util.commands.*;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.event.debug.*;
import com.sk89q.worldguard.util.report.CancelReport;
@@ -58,45 +55,45 @@ public class DebuggingCommands {
this.plugin = plugin;
}
@Command(aliases = {"testbreak"}, usage = "[player]", desc = "Simulate a block break", min = 1, max = 1, flags = "t")
@Command(aliases = {"testbreak"}, usage = "[player]", desc = "Simulate a block break", min = 1, max = 1, flags = "ts")
@CommandPermissions("worldguard.debug.event")
public void fireBreakEvent(CommandContext args, final CommandSender sender) throws CommandException {
Player target = plugin.matchSinglePlayer(sender, args.getString(0));
Block block = traceBlock(sender, target, args.hasFlag('t'));
sender.sendMessage(ChatColor.AQUA + "Testing BLOCK BREAK at " + ChatColor.DARK_AQUA + block);
LoggingBlockBreakEvent event = new LoggingBlockBreakEvent(block, target);
testEvent(sender, target, event);
testEvent(sender, target, event, args.hasFlag('s'));
}
@Command(aliases = {"testplace"}, usage = "[player]", desc = "Simulate a block place", min = 1, max = 1, flags = "t")
@Command(aliases = {"testplace"}, usage = "[player]", desc = "Simulate a block place", min = 1, max = 1, flags = "ts")
@CommandPermissions("worldguard.debug.event")
public void firePlaceEvent(CommandContext args, final CommandSender sender) throws CommandException {
Player target = plugin.matchSinglePlayer(sender, args.getString(0));
Block block = traceBlock(sender, target, args.hasFlag('t'));
sender.sendMessage(ChatColor.AQUA + "Testing BLOCK PLACE at " + ChatColor.DARK_AQUA + block);
LoggingBlockPlaceEvent event = new LoggingBlockPlaceEvent(block, block.getState(), block.getRelative(BlockFace.DOWN), target.getItemInHand(), target, true);
testEvent(sender, target, event);
testEvent(sender, target, event, args.hasFlag('s'));
}
@Command(aliases = {"testinteract"}, usage = "[player]", desc = "Simulate a block interact", min = 1, max = 1, flags = "t")
@Command(aliases = {"testinteract"}, usage = "[player]", desc = "Simulate a block interact", min = 1, max = 1, flags = "ts")
@CommandPermissions("worldguard.debug.event")
public void fireInteractEvent(CommandContext args, final CommandSender sender) throws CommandException {
Player target = plugin.matchSinglePlayer(sender, args.getString(0));
Block block = traceBlock(sender, target, args.hasFlag('t'));
sender.sendMessage(ChatColor.AQUA + "Testing BLOCK INTERACT at " + ChatColor.DARK_AQUA + block);
LoggingPlayerInteractEvent event = new LoggingPlayerInteractEvent(target, Action.RIGHT_CLICK_BLOCK, target.getItemInHand(), block, BlockFace.SOUTH);
testEvent(sender, target, event);
testEvent(sender, target, event, args.hasFlag('s'));
}
@Command(aliases = {"testdamage"}, usage = "[player]", desc = "Simulate an entity damage", min = 1, max = 1, flags = "t")
@Command(aliases = {"testdamage"}, usage = "[player]", desc = "Simulate an entity damage", min = 1, max = 1, flags = "ts")
@CommandPermissions("worldguard.debug.event")
public void fireDamageEvent(CommandContext args, final CommandSender sender) throws CommandException {
Player target = plugin.matchSinglePlayer(sender, args.getString(0));
Entity entity = traceEntity(sender, target, args.hasFlag('t'));
sender.sendMessage(ChatColor.AQUA + "Testing ENTITY DAMAGE on " + ChatColor.DARK_AQUA + entity);
LoggingEntityDamageByEntityEvent event = new LoggingEntityDamageByEntityEvent(target, entity, DamageCause.ENTITY_ATTACK, 1);
testEvent(sender, target, event);
testEvent(sender, target, event, args.hasFlag('s'));
}
/**
@@ -104,10 +101,11 @@ public class DebuggingCommands {
*
* @param receiver The receiver of the messages
* @param target The target
* @param event THe event
* @param event The event
* @param stacktraceMode Whether stack traces should be generated and posted
* @param <T> The type of event
*/
private <T extends Event & CancelLogging> void testEvent(CommandSender receiver, Player target, T event) {
private <T extends Event & CancelLogging> void testEvent(CommandSender receiver, Player target, T event, boolean stacktraceMode) throws CommandPermissionsException {
boolean isConsole = receiver instanceof ConsoleCommandSender;
if (!receiver.equals(target)) {
@@ -122,12 +120,22 @@ public class DebuggingCommands {
Bukkit.getPluginManager().callEvent(event);
int start = new Exception().getStackTrace().length;
CancelReport report = new CancelReport(event, event.getCancels(), start);
report.setDetectingPlugin(!stacktraceMode);
String result = report.toString();
receiver.sendMessage(result.replaceAll("(?m)^", ChatColor.AQUA.toString()));
if (result.length() >= 500 && !isConsole) {
receiver.sendMessage(ChatColor.GRAY + "The report was also printed to console.");
if (stacktraceMode) {
receiver.sendMessage(ChatColor.GRAY + "The report was printed to console.");
log.info("Event report for " + receiver.getName() + ":\n\n" + result);
plugin.checkPermission(receiver, "worldguard.debug.pastebin");
CommandUtils.pastebin(plugin, receiver, result, "Event debugging report: %s.txt");
} else {
receiver.sendMessage(result.replaceAll("(?m)^", ChatColor.AQUA.toString()));
if (result.length() >= 500 && !isConsole) {
receiver.sendMessage(ChatColor.GRAY + "The report was also printed to console.");
log.info("Event report for " + receiver.getName() + ":\n\n" + result);
}
}
}
@@ -64,9 +64,8 @@ import org.bukkit.event.vehicle.VehicleDestroyEvent;
import org.bukkit.event.world.StructureGrowEvent;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.*;
import org.bukkit.material.Dispenser;
import org.bukkit.material.MaterialData;
import org.bukkit.material.SpawnEgg;
import org.bukkit.projectiles.ProjectileSource;
import org.bukkit.util.Vector;
@@ -243,18 +242,28 @@ public class EventAbstractionListener extends AbstractListener {
Events.fireBulkEventToCancel(event, new BreakBlockEvent(event, create(entity), event.getLocation().getWorld(), event.blockList(), Material.AIR));
}
@SuppressWarnings("deprecation")
@EventHandler(ignoreCancelled = true)
public void onBlockPistonRetract(BlockPistonRetractEvent event) {
if (event.isSticky()) {
EventDebounce.Entry entry = pistonRetractDebounce.getIfNotPresent(new BlockPistonRetractKey(event), event);
if (entry != null) {
Cause cause = create(event.getBlock());
Events.fireToCancel(event, new BreakBlockEvent(event, cause, event.getRetractLocation(), Material.AIR));
Events.fireToCancel(event, new PlaceBlockEvent(event, cause, event.getBlock().getRelative(event.getDirection())));
Block piston = event.getBlock();
Cause cause = create(piston);
// Workaround for incorrect piston events
BlockFace direction = event.getDirection();
if (piston.getType() == Material.PISTON_MOVING_PIECE) {
direction = new PistonExtensionMaterial(Material.PISTON_STICKY_BASE.getId(), piston.getData()).getFacing();
}
Location retractLocation = piston.getRelative(direction, 2).getLocation();
Events.fireToCancel(event, new BreakBlockEvent(event, cause, retractLocation, Material.AIR));
Events.fireToCancel(event, new PlaceBlockEvent(event, cause, piston.getRelative(direction)));
entry.setCancelled(event.isCancelled());
if (event.isCancelled()) {
playDenyEffect(event.getBlock().getLocation().add(0.5, 1, 0.5));
playDenyEffect(piston.getLocation().add(0.5, 1, 0.5));
}
}
}
@@ -430,7 +439,9 @@ public class EventAbstractionListener extends AbstractListener {
Events.fireToCancel(event, new PlaceBlockEvent(event, create(player), blockAffected.getLocation(), blockMaterial).setAllowed(allowed));
Events.fireToCancel(event, new UseItemEvent(event, create(player), player.getWorld(), item).setAllowed(allowed));
playDenyEffect(event.getPlayer(), blockAffected.getLocation().add(0.5, 0.5, 0.5));
if (event.isCancelled()) {
playDenyEffect(event.getPlayer(), blockAffected.getLocation().add(0.5, 0.5, 0.5));
}
}
@EventHandler(ignoreCancelled = true)
@@ -448,7 +459,9 @@ public class EventAbstractionListener extends AbstractListener {
Events.fireToCancel(event, new BreakBlockEvent(event, create(player), blockAffected).setAllowed(allowed));
Events.fireToCancel(event, new UseItemEvent(event, create(player), player.getWorld(), item).setAllowed(allowed));
playDenyEffect(event.getPlayer(), blockAffected.getLocation().add(0.5, 1, 0.5));
if (event.isCancelled()) {
playDenyEffect(event.getPlayer(), blockAffected.getLocation().add(0.5, 0.5, 0.5));
}
}
// TODO: Handle EntityPortalEnterEvent
@@ -619,7 +632,13 @@ public class EventAbstractionListener extends AbstractListener {
@EventHandler(ignoreCancelled = true)
public void onEntityDamage(EntityDamageEvent event) {
if (event instanceof EntityDamageByBlockEvent) {
Events.fireToCancel(event, new DamageEntityEvent(event, create(((EntityDamageByBlockEvent) event).getDamager()), event.getEntity()));
@Nullable Block attacker = ((EntityDamageByBlockEvent) event).getDamager();
// The attacker should NOT be null, but sometimes it is
// See WORLDGUARD-3350
if (attacker != null) {
Events.fireToCancel(event, new DamageEntityEvent(event, create(attacker), event.getEntity()));
}
} else if (event instanceof EntityDamageByEntityEvent) {
EntityDamageByEntityEvent entityEvent = (EntityDamageByEntityEvent) event;
@@ -683,7 +702,7 @@ public class EventAbstractionListener extends AbstractListener {
@EventHandler(ignoreCancelled = true)
public void onVehicleDamage(VehicleDamageEvent event) {
Entity attacker = event.getAttacker();
Events.fireToCancel(event, new DestroyEntityEvent(event, create(attacker), event.getVehicle()));
Events.fireToCancel(event, new DamageEntityEvent(event, create(attacker), event.getVehicle()));
}
@EventHandler(ignoreCancelled = true)
@@ -833,6 +852,11 @@ public class EventAbstractionListener extends AbstractListener {
Events.fireToCancel(event, new SpawnEntityEvent(event, cause, placed.getLocation().add(0.5, 0, 0.5), EntityType.BOAT));
}
// Handle created armor stands
if (item != null && item.getType() == Materials.ARMOR_STAND) {
Events.fireToCancel(event, new SpawnEntityEvent(event, cause, placed.getLocation().add(0.5, 0, 0.5), EntityType.ARMOR_STAND));
}
// Handle created spawn eggs
if (item != null && item.getType() == Material.MONSTER_EGG) {
MaterialData data = item.getData();
@@ -907,6 +931,12 @@ public class EventAbstractionListener extends AbstractListener {
public void onPlayerInteractAtEntity(PlayerInteractAtEntityEvent event){
onPlayerInteractEntity(event);
}
@EventHandler(ignoreCancelled = true)
public void onBlockExplode(BlockExplodeEvent event) {
Events.fireBulkEventToCancel(event, new BreakBlockEvent(event, create(event.getBlock()),
event.getBlock().getLocation().getWorld(), event.blockList(), Material.AIR));
}
}
}
@@ -30,12 +30,16 @@ import com.sk89q.worldguard.protection.association.RegionAssociable;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.flags.StateFlag;
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.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import javax.annotation.Nullable;
@@ -87,7 +91,7 @@ public class RegionFlagsListener extends AbstractListener {
}
Entity entity;
if ((entity = event.getCause().getFirstEntity()) != null) {
if ((entity = event.getCause().getFirstNonPlayerEntity()) != null) {
// ================================================================
// CREEPER_EXPLOSION flag
// ================================================================
@@ -107,6 +111,21 @@ public class RegionFlagsListener extends AbstractListener {
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onEntityDamage(EntityDamageEvent event) {
Entity entity = event.getEntity();
World world = entity.getWorld();
if (!isRegionSupportEnabled(world)) return; // Region support disabled
RegionQuery query = getPlugin().getRegionContainer().createQuery();
if (entity instanceof Player && event.getCause() == DamageCause.FALL) {
if (!query.testState(entity.getLocation(), (Player) entity, DefaultFlag.FALL_DAMAGE)) {
event.setCancelled(true);
}
}
}
/**
* Create a new predicate to test a state flag for each location.
*
@@ -215,9 +215,9 @@ public class RegionProtectionListener extends AbstractListener {
String what;
/* TNT */
if (event.getCause().find(EntityType.PRIMED_TNT, EntityType.PRIMED_TNT) != null) {
if (event.getCause().find(EntityType.PRIMED_TNT, EntityType.MINECART_TNT) != null) {
canBreak = query.testBuild(target, associable, combine(event, DefaultFlag.BLOCK_BREAK, DefaultFlag.TNT));
what = "dynamite blocks";
what = "use dynamite";
/* Everything else */
} else {
@@ -390,7 +390,8 @@ public class RegionProtectionListener extends AbstractListener {
String what;
/* Hostile / ambient mob override */
if (Entities.isHostile(event.getEntity()) || Entities.isAmbient(event.getEntity()) || Entities.isNPC(event.getEntity())) {
if (Entities.isHostile(event.getEntity()) || Entities.isAmbient(event.getEntity())
|| Entities.isNPC(event.getEntity()) || Entities.isVehicle(event.getEntity().getType())) {
canUse = event.getRelevantFlags().isEmpty() || query.queryState(target, associable, combine(event)) != State.DENY;
what = "use that";
@@ -439,7 +440,8 @@ public class RegionProtectionListener extends AbstractListener {
}
/* Hostile / ambient mob override */
if (Entities.isHostile(event.getEntity()) || Entities.isAmbient(event.getEntity())) {
if (Entities.isHostile(event.getEntity()) || Entities.isAmbient(event.getEntity())
|| Entities.isVehicle(event.getEntity().getType())) {
canDamage = event.getRelevantFlags().isEmpty() || query.queryState(target, associable, combine(event)) != State.DENY;
what = "hit that";
@@ -453,7 +455,8 @@ public class RegionProtectionListener extends AbstractListener {
Player defender = (Player) event.getEntity();
canDamage = query.testBuild(target, associable, combine(event, DefaultFlag.PVP))
&& query.queryState(playerAttacker.getLocation(), playerAttacker, combine(event, DefaultFlag.PVP)) != State.DENY;
&& query.queryState(playerAttacker.getLocation(), playerAttacker, combine(event, DefaultFlag.PVP)) != State.DENY
&& query.queryState(target, playerAttacker, combine(event, DefaultFlag.PVP)) != State.DENY;
// Fire the disallow PVP event
if (!canDamage && Events.fireAndTestCancel(new DisallowedPVPEvent(playerAttacker, defender, event.getOriginalEvent()))) {
@@ -467,6 +470,11 @@ public class RegionProtectionListener extends AbstractListener {
canDamage = event.getRelevantFlags().isEmpty() || query.queryState(target, associable, combine(event)) != State.DENY;
what = "damage that";
/* damage to non-hostile mobs (e.g. animals) */
} else if (Entities.isNonHostile(event.getEntity())) {
canDamage = query.testBuild(target, associable, combine(event, DefaultFlag.DAMAGE_ANIMALS));
what = "harm that";
/* Everything else */
} else {
canDamage = query.testBuild(target, associable, combine(event, DefaultFlag.INTERACT));
@@ -380,7 +380,7 @@ public class WorldGuardBlockListener implements Listener {
return;
}
int id = event.getChangedTypeId();
int id = event.getBlock().getTypeId();
if (id == 13 && wcfg.noPhysicsGravel) {
event.setCancelled(true);
@@ -22,6 +22,7 @@ package com.sk89q.worldguard.bukkit.listener;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.bukkit.*;
import com.sk89q.worldguard.bukkit.util.Entities;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
@@ -552,6 +553,11 @@ public class WorldGuardEntityListener implements Listener {
return;
}
// armor stands are living entities, but we check them as blocks/non-living entities, so ignore them here
if (Entities.isConsideredBuildingIfUsed(event.getEntity())) {
return;
}
if (wcfg.allowTamedSpawns
&& event.getEntity() instanceof Tameable // nullsafe check
&& ((Tameable) event.getEntity()).isTamed()) {
@@ -31,6 +31,7 @@ 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 com.sk89q.worldguard.session.handler.GameModeFlag;
import com.sk89q.worldguard.util.command.CommandFilter;
import org.bukkit.ChatColor;
@@ -84,12 +85,15 @@ public class WorldGuardPlayerListener implements Listener {
public void onPlayerGameModeChange(PlayerGameModeChangeEvent event) {
Player player = event.getPlayer();
WorldConfiguration wcfg = plugin.getGlobalStateManager().get(player.getWorld());
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 (handler.getOriginalGameMode() != null && expected != null && expected != event.getNewGameMode()) {
log.info("Game mode change on " + player.getName() + " has been blocked due to the region GAMEMODE flag");
event.setCancelled(true);
Session session = plugin.getSessionManager().getIfPresent(player);
if (session != null) {
GameModeFlag handler = session.getHandler(GameModeFlag.class);
if (handler != null && wcfg.useRegions && !plugin.getGlobalRegionManager().hasBypass(player, player.getWorld())) {
GameMode expected = handler.getSetGameMode();
if (handler.getOriginalGameMode() != null && expected != null && expected != event.getNewGameMode()) {
log.info("Game mode change on " + player.getName() + " has been blocked due to the region GAMEMODE flag");
event.setCancelled(true);
}
}
}
}
@@ -20,9 +20,13 @@
package com.sk89q.worldguard.bukkit.util;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.material.Bed;
import org.bukkit.material.Chest;
import org.bukkit.material.MaterialData;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -43,7 +47,8 @@ public final class Blocks {
* @return a list of connected blocks, not including the given block
*/
public static List<Block> getConnected(Block block) {
MaterialData data = block.getState().getData();
BlockState state = block.getState();
MaterialData data = state.getData();
if (data instanceof Bed) {
Bed bed = (Bed) data;
@@ -52,6 +57,28 @@ public final class Blocks {
} else {
return Arrays.asList(block.getRelative(bed.getFacing()));
}
} else if (data instanceof Chest) {
BlockFace facing = ((Chest) data).getFacing();
ArrayList<Block> chests = new ArrayList<Block>();
if (facing == BlockFace.NORTH || facing == BlockFace.SOUTH) {
if (block.getRelative(BlockFace.EAST).getState().getData() instanceof Chest) {
chests.add(block.getRelative(BlockFace.EAST));
}
if (block.getRelative(BlockFace.WEST).getState().getData() instanceof Chest) {
chests.add(block.getRelative(BlockFace.WEST));
}
} else if (facing == BlockFace.EAST || facing == BlockFace.WEST) {
if (block.getRelative(BlockFace.NORTH).getState().getData() instanceof Chest) {
chests.add(block.getRelative(BlockFace.NORTH));
}
if (block.getRelative(BlockFace.SOUTH).getState().getData() instanceof Chest) {
chests.add(block.getRelative(BlockFace.SOUTH));
}
} else {
// don't know how to handle diagonal chests
return Collections.emptyList();
}
return chests;
} else {
return Collections.emptyList();
}
@@ -19,6 +19,7 @@
package com.sk89q.worldguard.bukkit.util;
import com.sk89q.worldguard.util.Enums;
import org.bukkit.entity.*;
import org.bukkit.entity.minecart.ExplosiveMinecart;
import org.bukkit.projectiles.ProjectileSource;
@@ -132,6 +133,17 @@ public final class Entities {
|| entity instanceof EnderDragon;
}
/**
* Test whether an entity is a non-hostile creature.
*
* @param entity
* @return true if non-hostile
*/
public static boolean isNonHostile(Entity entity) {
return !isHostile(entity)
&& (entity instanceof Creature || entity instanceof WaterMob);
}
/**
* Test whether an entity is ambient.
*
@@ -149,7 +161,7 @@ public final class Entities {
* @return true if an NPC
*/
public static boolean isNPC(Entity entity) {
return entity instanceof NPC;
return entity instanceof NPC || entity.hasMetadata("NPC");
}
/**
@@ -163,6 +175,9 @@ public final class Entities {
return entity instanceof LivingEntity && !(entity instanceof Player);
}
private static final org.bukkit.entity.EntityType armorStandType =
Enums.findByValue(org.bukkit.entity.EntityType.class, "ARMOR_STAND");
/**
* Test whether using the given entity should be considered "building"
* rather than merely using an entity.
@@ -171,7 +186,8 @@ public final class Entities {
* @return true if considered building
*/
public static boolean isConsideredBuildingIfUsed(Entity entity) {
return entity instanceof Hanging;
return entity instanceof Hanging
|| entity.getType() == armorStandType;
}
}
@@ -46,7 +46,15 @@ public final class Materials {
private static final Map<Material, Integer> MATERIAL_FLAGS = new HashMap<Material, Integer>();
private static final Set<PotionEffectType> DAMAGE_EFFECTS = new HashSet<PotionEffectType>();
public static Material ARMOR_STAND;
static {
try {
ARMOR_STAND = Material.ARMOR_STAND;
} catch (NoSuchFieldError ignored) {
ARMOR_STAND = null;
}
ENTITY_ITEMS.put(EntityType.PAINTING, Material.PAINTING);
ENTITY_ITEMS.put(EntityType.ARROW, Material.ARROW);
ENTITY_ITEMS.put(EntityType.SNOWBALL, Material.SNOW_BALL);
@@ -66,6 +74,9 @@ public final class Materials {
ENTITY_ITEMS.put(EntityType.MINECART_HOPPER, Material.HOPPER_MINECART);
ENTITY_ITEMS.put(EntityType.SPLASH_POTION, Material.POTION);
ENTITY_ITEMS.put(EntityType.EGG, Material.EGG);
try {
ENTITY_ITEMS.put(EntityType.ARMOR_STAND, Material.ARMOR_STAND);
} catch (NoSuchFieldError ignored) {}
MATERIAL_FLAGS.put(Material.AIR, 0);
MATERIAL_FLAGS.put(Material.STONE, 0);
@@ -241,7 +252,7 @@ public final class Materials {
try {
MATERIAL_FLAGS.put(Material.STANDING_BANNER, 0);
MATERIAL_FLAGS.put(Material.WALL_BANNER, 0);
MATERIAL_FLAGS.put(Material.DAYLIGHT_DETECTOR_INVERTED, 0);
MATERIAL_FLAGS.put(Material.DAYLIGHT_DETECTOR_INVERTED, MODIFIED_ON_RIGHT);
MATERIAL_FLAGS.put(Material.RED_SANDSTONE, 0);
MATERIAL_FLAGS.put(Material.RED_SANDSTONE_STAIRS, 0);
MATERIAL_FLAGS.put(Material.DOUBLE_STONE_SLAB2, 0);
@@ -391,7 +402,7 @@ public final class Materials {
MATERIAL_FLAGS.put(Material.CAULDRON_ITEM, 0);
MATERIAL_FLAGS.put(Material.EYE_OF_ENDER, 0);
MATERIAL_FLAGS.put(Material.SPECKLED_MELON, 0);
MATERIAL_FLAGS.put(Material.MONSTER_EGG, 0);
MATERIAL_FLAGS.put(Material.MONSTER_EGG, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.EXP_BOTTLE, 0);
MATERIAL_FLAGS.put(Material.FIREBALL, 0);
MATERIAL_FLAGS.put(Material.BOOK_AND_QUILL, 0);
@@ -423,6 +434,28 @@ public final class Materials {
MATERIAL_FLAGS.put(Material.LEASH, 0);
MATERIAL_FLAGS.put(Material.NAME_TAG, 0);
MATERIAL_FLAGS.put(Material.COMMAND_MINECART, 0);
try {
MATERIAL_FLAGS.put(Material.PRISMARINE_SHARD, 0);
MATERIAL_FLAGS.put(Material.PRISMARINE_CRYSTALS, 0);
MATERIAL_FLAGS.put(Material.RABBIT, 0);
MATERIAL_FLAGS.put(Material.COOKED_RABBIT, 0);
MATERIAL_FLAGS.put(Material.RABBIT_STEW, 0);
MATERIAL_FLAGS.put(Material.RABBIT_FOOT, 0);
MATERIAL_FLAGS.put(Material.RABBIT_HIDE, 0);
MATERIAL_FLAGS.put(Material.ARMOR_STAND, 0);
MATERIAL_FLAGS.put(Material.IRON_BARDING, 0);
MATERIAL_FLAGS.put(Material.GOLD_BARDING, 0);
MATERIAL_FLAGS.put(Material.DIAMOND_BARDING, 0);;
MATERIAL_FLAGS.put(Material.MUTTON, 0);
MATERIAL_FLAGS.put(Material.COOKED_MUTTON, 0);
MATERIAL_FLAGS.put(Material.BANNER, 0);
MATERIAL_FLAGS.put(Material.SPRUCE_DOOR_ITEM, 0);
MATERIAL_FLAGS.put(Material.BIRCH_DOOR_ITEM, 0);
MATERIAL_FLAGS.put(Material.JUNGLE_DOOR_ITEM, 0);
MATERIAL_FLAGS.put(Material.ACACIA_DOOR_ITEM, 0);
MATERIAL_FLAGS.put(Material.DARK_OAK_DOOR_ITEM, 0);
} catch (NoSuchFieldError ignored) {
}
MATERIAL_FLAGS.put(Material.GOLD_RECORD, 0);
MATERIAL_FLAGS.put(Material.GREEN_RECORD, 0);
MATERIAL_FLAGS.put(Material.RECORD_3, 0);
@@ -644,11 +677,13 @@ public final class Materials {
case LEVER: return true;
case STONE_BUTTON: return true;
case WOOD_BUTTON: return true;
case TRIPWIRE: return true;
case WOODEN_DOOR: return true;
case TRAP_DOOR: return true;
case FENCE_GATE: return true;
case WORKBENCH: return true;
case ENCHANTMENT_TABLE: return true;
case ENDER_CHEST: return true;
case BEACON: return true;
case ANVIL: return true;
case WOOD_PLATE: return true;
@@ -720,7 +755,11 @@ public final class Materials {
* @return true to be considered as used
*/
public static boolean isConsideredBuildingIfUsed(Material type) {
return type == Material.SAPLING;
return type == Material.SAPLING
|| type == Material.DIODE_BLOCK_OFF
|| type == Material.DIODE_BLOCK_ON
|| type == Material.REDSTONE_COMPARATOR_OFF
|| type == Material.REDSTONE_COMPARATOR_ON;
}
/**
@@ -77,7 +77,8 @@ public class SchedulerReport extends DataReport {
for (Class<?> type : classes) {
Optional<Field> field = taskFieldCache.getUnchecked(type);
if (field.isPresent()) {
return field.get().get(task).getClass();
Object res = field.get().get(task);
return res == null ? null : res.getClass();
}
}
} catch (IllegalAccessException ignored) {
@@ -51,7 +51,6 @@ public class GroupDomain implements Domain, ChangeTracked {
public GroupDomain(GroupDomain domain) {
checkNotNull(domain, "domain");
groups.addAll(domain.getGroups());
dirty = true;
}
/**
@@ -128,6 +127,7 @@ public class GroupDomain implements Domain, ChangeTracked {
@Override
public void clear() {
setDirty(true);
groups.clear();
}
@@ -125,6 +125,7 @@ public class PlayerDomain implements Domain, ChangeTracked {
*/
public void removePlayer(UUID uuid) {
checkNotNull(uuid);
setDirty(true);
uniqueIds.remove(uuid);
}
@@ -136,6 +137,7 @@ public class PlayerDomain implements Domain, ChangeTracked {
*/
public void removePlayer(LocalPlayer player) {
checkNotNull(player);
setDirty(true);
removePlayer(player.getName());
removePlayer(player.getUniqueId());
}
@@ -183,6 +185,7 @@ public class PlayerDomain implements Domain, ChangeTracked {
@Override
public void clear() {
setDirty(true);
uniqueIds.clear();
names.clear();
}
@@ -21,6 +21,7 @@ package com.sk89q.worldguard.protection.flags;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.WeatherType;
import org.bukkit.entity.EntityType;
/**
@@ -48,6 +49,7 @@ public final class DefaultFlag {
public static final StateFlag BLOCK_PLACE = new StateFlag("block-place", false);
public static final StateFlag USE = new StateFlag("use", false);
public static final StateFlag INTERACT = new StateFlag("interact", false);
public static final StateFlag DAMAGE_ANIMALS = new StateFlag("damage-animals", false);
public static final StateFlag PVP = new StateFlag("pvp", false);
public static final StateFlag SLEEP = new StateFlag("sleep", false);
public static final StateFlag TNT = new StateFlag("tnt", false);
@@ -100,6 +102,7 @@ public final class DefaultFlag {
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);
public static final StateFlag FALL_DAMAGE = new StateFlag("fall-damage", true);
// Flags that adjust behaviors that aren't state flags
public static final StringFlag DENY_MESSAGE = new StringFlag("deny-message",
@@ -109,12 +112,15 @@ public final class DefaultFlag {
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 BooleanFlag EXIT_OVERRIDE = new BooleanFlag("exit-override");
public static final StateFlag EXIT_VIA_TELEPORT = new StateFlag("exit-via-teleport", true);
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");
public static final BooleanFlag NOTIFY_LEAVE = new BooleanFlag("notify-leave");
public static final SetFlag<EntityType> DENY_SPAWN = new SetFlag<EntityType>("deny-spawn", new EntityTypeFlag(null));
public static final EnumFlag<GameMode> GAME_MODE = new EnumFlag<GameMode>("game-mode", GameMode.class);
public static final StringFlag TIME_LOCK = new StringFlag("time-lock");
public static final EnumFlag<WeatherType> WEATHER_LOCK = new EnumFlag<WeatherType>("weather-lock", WeatherType.class);
public static final IntegerFlag HEAL_DELAY = new IntegerFlag("heal-delay");
public static final IntegerFlag HEAL_AMOUNT = new IntegerFlag("heal-amount");
public static final DoubleFlag MIN_HEAL = new DoubleFlag("heal-min-health");
@@ -135,19 +141,19 @@ public final class DefaultFlag {
public static final Flag<?>[] flagsList = new Flag<?>[] {
PASSTHROUGH, BUILD, CONSTRUCT, BLOCK_BREAK, BLOCK_PLACE, PVP, CHEST_ACCESS, PISTONS,
TNT, LIGHTER, RIDE, USE, INTERACT, PLACE_VEHICLE, DESTROY_VEHICLE, SLEEP,
TNT, LIGHTER, RIDE, USE, INTERACT, PLACE_VEHICLE, DESTROY_VEHICLE, DAMAGE_ANIMALS, SLEEP,
MOB_DAMAGE, MOB_SPAWNING, DENY_SPAWN, INVINCIBILITY, EXP_DROPS,
CREEPER_EXPLOSION, OTHER_EXPLOSION, ENDERDRAGON_BLOCK_DAMAGE, GHAST_FIREBALL, ENDER_BUILD,
DENY_MESSAGE, ENTRY_DENY_MESSAGE, EXIT_DENY_MESSAGE, EXIT_OVERRIDE,
DENY_MESSAGE, ENTRY_DENY_MESSAGE, EXIT_DENY_MESSAGE, EXIT_OVERRIDE, EXIT_VIA_TELEPORT,
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,*/
ENTITY_ITEM_FRAME_DESTROY, FALL_DAMAGE, ITEM_PICKUP, ITEM_DROP, /*MAX_PLAYERS, MAX_PLAYERS_MESSAGE,*/
HEAL_AMOUNT, HEAL_DELAY, MIN_HEAL, MAX_HEAL,
FEED_DELAY, FEED_AMOUNT, MIN_FOOD, MAX_FOOD,
SNOW_FALL, SNOW_MELT, ICE_FORM, ICE_MELT, SOIL_DRY, GAME_MODE,
MUSHROOMS, LEAF_DECAY, GRASS_SPREAD, MYCELIUM_SPREAD, VINE_GROWTH,
SEND_CHAT, RECEIVE_CHAT, FIRE_SPREAD, LAVA_FIRE, LAVA_FLOW, WATER_FLOW,
TELE_LOC, SPAWN_LOC, POTION_SPLASH,
TELE_LOC, SPAWN_LOC, POTION_SPLASH, TIME_LOCK, WEATHER_LOCK,
BLOCKED_CMDS, ALLOWED_CMDS, PRICE, BUYABLE, ENABLE_SHOP
};
@@ -19,6 +19,7 @@
package com.sk89q.worldguard.protection.flags;
import com.google.common.collect.Sets;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import org.bukkit.command.CommandSender;
@@ -56,13 +57,17 @@ public class SetFlag<T> extends Flag<Set<T>> {
@Override
public Set<T> parseInput(WorldGuardPlugin plugin, CommandSender sender, String input) throws InvalidFlagFormat {
Set<T> items = new HashSet<T>();
if (input.isEmpty()) {
return Sets.newHashSet();
} else {
Set<T> items = Sets.newHashSet();
for (String str : input.split(",")) {
items.add(subFlag.parseInput(plugin, sender, str.trim()));
for (String str : input.split(",")) {
items.add(subFlag.parseInput(plugin, sender, str.trim()));
}
return items;
}
return new HashSet<T>(items);
}
@Override
@@ -28,22 +28,27 @@ import org.bukkit.Location;
*/
public enum MoveType {
RESPAWN(false),
EMBARK(true),
MOVE(true),
TELEPORT(true),
RIDE(true),
OTHER_NON_CANCELLABLE(false),
OTHER_CANCELLABLE(true);
RESPAWN(false, true),
EMBARK(true, false),
MOVE(true, false),
TELEPORT(true, true),
RIDE(true, false),
OTHER_NON_CANCELLABLE(false, false),
OTHER_CANCELLABLE(true, false);
private final boolean cancellable;
private final boolean teleport;
MoveType(boolean cancellable) {
MoveType(boolean cancellable, boolean teleport) {
this.cancellable = cancellable;
this.teleport = teleport;
}
public boolean isCancellable() {
return cancellable;
}
public boolean isTeleport() {
return teleport;
}
}
@@ -147,6 +147,8 @@ public class SessionManager implements Runnable, Listener {
session.register(new FarewellFlag(session));
session.register(new GameModeFlag(session));
session.register(new InvincibilityFlag(session));
session.register(new TimeLockFlag(session));
session.register(new WeatherLockFlag(session));
session.register(new GodMode(session));
session.register(new WaterBreathing(session));
session.initialize(player);
@@ -34,6 +34,7 @@ public class ExitFlag extends FlagValueChangeHandler<State> {
private static final long MESSAGE_THRESHOLD = 1000 * 2;
private String storedMessage;
private boolean exitViaTeleport = false;
private long lastMessage;
public ExitFlag(Session session) {
@@ -43,6 +44,7 @@ public class ExitFlag extends FlagValueChangeHandler<State> {
private void update(LocalPlayer localPlayer, ApplicableRegionSet set, boolean allowed) {
if (!allowed) {
storedMessage = set.queryValue(localPlayer, DefaultFlag.EXIT_DENY_MESSAGE);
exitViaTeleport = set.testState(localPlayer, DefaultFlag.EXIT_VIA_TELEPORT);
}
}
@@ -71,7 +73,7 @@ public class ExitFlag extends FlagValueChangeHandler<State> {
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
if (allowed && !lastAllowed) {
if (allowed && !lastAllowed && !(moveType.isTeleport() && exitViaTeleport) && moveType.isCancellable()) {
Boolean override = toSet.queryValue(localPlayer, DefaultFlag.EXIT_OVERRIDE);
if (override == null || !override) {
sendMessage(player);
@@ -91,7 +93,7 @@ public class ExitFlag extends FlagValueChangeHandler<State> {
boolean lastAllowed = StateFlag.test(lastValue);
if (!lastAllowed) {
if (!lastAllowed && moveType.isCancellable()) {
Boolean override = toSet.queryValue(getPlugin().wrapPlayer(player), DefaultFlag.EXIT_OVERRIDE);
if (override == null || !override) {
sendMessage(player);
@@ -19,6 +19,7 @@
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;
@@ -35,42 +36,47 @@ public class FeedFlag extends Handler {
@Override
public void tick(Player player, ApplicableRegionSet set) {
if (!getSession().isInvincible(player) && player.getGameMode() != GameMode.CREATIVE) {
long now = System.currentTimeMillis();
long now = System.currentTimeMillis();
LocalPlayer localPlayer = getSession().getPlugin().wrapPlayer(player);
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);
Integer feedAmount = set.queryValue(localPlayer, DefaultFlag.FEED_AMOUNT);
Integer feedDelay = set.queryValue(localPlayer, DefaultFlag.FEED_DELAY);
Integer minHunger = set.queryValue(localPlayer, DefaultFlag.MIN_FOOD);
Integer maxHunger = set.queryValue(localPlayer, DefaultFlag.MAX_FOOD);
if (feedAmount == null || feedDelay == null || feedAmount == 0 || feedDelay < 0) {
return;
}
if (minHunger == null) {
minHunger = 0;
}
if (maxHunger == null) {
maxHunger = 20;
}
if (feedAmount == null || feedDelay == null || feedAmount == 0 || feedDelay < 0) {
return;
}
if (feedAmount < 0
&& (getSession().isInvincible(player)
|| (player.getGameMode() != GameMode.SURVIVAL && player.getGameMode() != GameMode.ADVENTURE))) {
// don't starve invincible players
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);
// 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 (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;
}
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;
}
}
@@ -38,46 +38,48 @@ public class HealFlag extends Handler {
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;
}
if (player.getHealth() <= 0) {
return;
}
long now = System.currentTimeMillis();
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);
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 (healAmount == null || healDelay == null || healAmount == 0 || healDelay < 0) {
return;
}
if (healAmount < 0
&& (getSession().isInvincible(player)
|| (player.getGameMode() != GameMode.SURVIVAL && player.getGameMode() != GameMode.ADVENTURE))) {
// don't damage invincible players
return;
}
if (minHealth == null) {
minHealth = 0.0;
}
if (maxHealth == null) {
maxHealth = player.getMaxHealth();
}
if (minHealth == null) {
minHealth = 0.0;
}
// Apply a cap to prevent possible exceptions
minHealth = Math.min(player.getMaxHealth(), minHealth);
maxHealth = Math.min(player.getMaxHealth(), maxHealth);
if (maxHealth == null) {
maxHealth = player.getMaxHealth();
}
if (player.getHealth() >= maxHealth && healAmount > 0) {
return;
}
// 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;
}
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,86 @@
/*
* 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.Location;
import org.bukkit.entity.Player;
import javax.annotation.Nullable;
import java.util.regex.Pattern;
public class TimeLockFlag extends FlagValueChangeHandler<String> {
private Long time;
private boolean relative;
private Long initialTime;
private boolean initialRelative;
Pattern timePattern = Pattern.compile("(\\+|-)?\\d+");
public TimeLockFlag(Session session) {
super(session, DefaultFlag.TIME_LOCK);
}
private void updatePlayerTime(Player player, @Nullable String value) {
// store settings, regardless of if we change anything
initialRelative = player.isPlayerTimeRelative();
initialTime = player.getPlayerTime();
if (value == null || !timePattern.matcher(value).matches()) {
// invalid input
return;
}
if (value.startsWith("+") || value.startsWith("-")) {
relative = true;
} else {
relative = false;
}
time = Long.valueOf(value);
if (!relative && (time < 0L || time > 24000L)) { // invalid time, reset to 0
time = 0L;
}
player.setPlayerTime(time, relative);
}
@Override
protected void onInitialValue(Player player, ApplicableRegionSet set, String value) {
initialTime = player.getPlayerTime();
initialRelative = player.isPlayerTimeRelative();
updatePlayerTime(player, value);
}
@Override
protected boolean onSetValue(Player player, Location from, Location to, ApplicableRegionSet toSet, String currentValue, String lastValue, MoveType moveType) {
updatePlayerTime(player, currentValue);
return true;
}
@Override
protected boolean onAbsentValue(Player player, Location from, Location to, ApplicableRegionSet toSet, String lastValue, MoveType moveType) {
player.setPlayerTime(initialTime, initialRelative);
initialRelative = true;
initialTime = 0L;
return true;
}
}
@@ -0,0 +1,71 @@
/*
* 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.Location;
import org.bukkit.WeatherType;
import org.bukkit.entity.Player;
import javax.annotation.Nullable;
public class WeatherLockFlag extends FlagValueChangeHandler<WeatherType> {
private WeatherType initialWeather;
public WeatherLockFlag(Session session) {
super(session, DefaultFlag.WEATHER_LOCK);
}
private void updatePlayerWeather(Player player, @Nullable WeatherType value) {
initialWeather = player.getPlayerWeather();
player.setPlayerWeather(value);
}
@Override
protected void onInitialValue(Player player, ApplicableRegionSet set, WeatherType value) {
if (value == null) {
initialWeather = null;
return;
}
updatePlayerWeather(player, value);
}
@Override
protected boolean onSetValue(Player player, Location from, Location to, ApplicableRegionSet toSet, WeatherType currentValue, WeatherType lastValue, MoveType moveType) {
updatePlayerWeather(player, currentValue);
return true;
}
@Override
protected boolean onAbsentValue(Player player, Location from, Location to, ApplicableRegionSet toSet, WeatherType lastValue, MoveType moveType) {
if (initialWeather != null) {
player.setPlayerWeather(initialWeather);
} else {
player.resetPlayerWeather();
}
initialWeather = null;
return true;
}
}
@@ -64,7 +64,7 @@ public class CommandFilter implements Predicate<String> {
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean apply(String command) {
command = command.toLowerCase().replaceAll("^/([^:]*:)?", "/");
command = command.toLowerCase().replaceAll("^/([^ :]*:)?", "/");
/*
* denied used allow?
@@ -40,6 +40,7 @@ public class CancelReport implements Report {
private final List<CancelAttempt> cancels;
private final HandlerTracer tracer;
private final int stackTruncateLength;
private boolean detectingPlugin = true;
public <T extends Event & Cancellable> CancelReport(T event, List<CancelAttempt> cancels, int stackTruncateLength) {
checkNotNull(event, "event");
@@ -51,6 +52,14 @@ public class CancelReport implements Report {
this.stackTruncateLength = stackTruncateLength;
}
public boolean isDetectingPlugin() {
return detectingPlugin;
}
public void setDetectingPlugin(boolean detectingPlugin) {
this.detectingPlugin = detectingPlugin;
}
private StackTraceElement[] truncateStackTrace(StackTraceElement[] elements) {
int newLength = elements.length - stackTruncateLength;
if (newLength <= 0) {
@@ -87,7 +96,7 @@ public class CancelReport implements Report {
builder.append(getCancelText(cancel.getAfter()));
builder.append(" by ");
if (cause != null) {
if (detectingPlugin && cause != null) {
builder.append(cause.getName());
} else {
builder.append(" (NOT KNOWN - use the stack trace below)");