Compare commits

..
Author SHA1 Message Date
Wyatt Childers c95f52a303 Allow set flags to be manipulate via keywords
This adds support for updating an existing region, so that
if you have a long list of items in a set flag, such as
`deny-spawn` you can add or remove items, rather than overwrite.

Example:
```
/rg flag test deny-spawn add creeper
/rg flag test deny-spawn remove zombie
```
2020-01-14 22:56:04 -05:00
32 changed files with 224 additions and 732 deletions

No files matched your search

-31
View File
@@ -1,31 +0,0 @@
---
name: Bug report
about: Report a way in which WorldGuard is not working as intended
title: ''
labels: type:bug, status:pending
assignees: ''
---
**Versions**
<!-- Please include the full version of WorldEdit, WorldGuard and the platform (Bukkit/Spigot/Paper) you are running, e.g. output from `/we version`, `/wg version` `/version` commands. Please ensure you are running up to date software before making a bug report. Old versions will recieve little to no support. -->
WorldEdit version:
WorldGuard version:
Platform version:
**Describe the bug**
<!-- A clear and concise description of what the bug is. -->
**To Reproduce**
<!-- Steps to reproduce the behavior: -->
1. ...
2. ...
**Expected behavior**
<!-- A clear and concise description of what you expected to happen. -->
**Screenshots**
<!-- If applicable, add screenshots to help explain your problem. -->
**Additional context**
<!-- Add any other context about the problem here. -->
-5
View File
@@ -1,5 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: EngineHub Discord
url: https://discord.gg/EngineHub
about: Please ask and answer questions here.
-20
View File
@@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for WorlGuard
title: ''
labels: type:feature-request, status:pending
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
**Describe the solution you'd like**
<!-- A clear and concise description of what you want to happen. -->
**Describe alternatives you've considered**
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
**Additional context**
<!-- Add any other context or screenshots about the feature request here. -->
-2
View File
@@ -15,5 +15,3 @@ dependency-reduced-pom.xml
.gradle/
**/build/
out/
scripts/
-39
View File
@@ -1,44 +1,5 @@
# Changelog
## 7.0.3
* This is the last release supporting MC 1.14 and 1.15.
* Decouple chest-access flag from interact flag. IMPORTANT: If you relied on allowing players to access chests via setting
the interact flag to allow, you will now need to set the chest-access flag to allow instead (or as well). This does not
affect any setups where users were *not* supposed to be able to access chests and other inventories.
* Add natural-health-regen and natural-hunger-drain flags. Unlike the heal/feed flags, these can not restore or deplete health/hunger.
* Fix the interact flag allowing breaking of turtle eggs (now tied directly to block-trampling flag).
* Fix a memory leak that could occur with many many explosives.
* Add regions.titles-always-use-default-times config option. Set this to true if you use greeting/farewell titles and another plugin
makes the titles disappear too quickly.
* Add protection for cauldrons water level changing.
* Improve diagnostic hints and information, such as spawn protection warnings, flag colors in region info, etc.
* Fix waterlogged blocks bypassing water-flow flag.
* Workaround for a CraftBukkit change that made no-physics-sand/gravel non-functional.
* Workaround for CraftBukkit throttling move events.
* Track projectiles shot by dispensers.
* Allowed setting passthrough allow on global to unprotect it if members/owners are added.
* Add support for newer forge clients (FML2) in host keys.
* Allow using WorldEdit's `//world <worldname>` command to select a world for region commands. This removes the need to
use `-w <worldname>` in every command when running commands from console.
* Add a teleport-message flag, shown when using `/rg tp`.
* Add coral-fade flag, which prevents corals from drying when out of water.
* Fix spammy deny-message when walking over redstone ore with certain flag setups.
* Improve handling of interacting with various tools in hand that didn't modify blocks. (eg opening a chest with an axe in hand)
* Fix allow-all-interact option not being read from per-world configs.
* Fix misattribution of pets (eg wolves) in PvP.
* Improve performance of hopper checks when on recent builds of Paper.
* Add event-handling.break-hoppers-on-denied-move config option to prevent hoppers from being broken (but items still won't be moved).
* Note to developers using the WorldGuard API: If you specifically relied on flags such as greeting/farewell, deny-message, etc being
StringFlags, be warned that this will change in a future version to support JSON text components. Please plan accordingly.
## 7.0.2
* Update to MC 1.15. Still compatible with 1.14, and incompatible with 1.13, as before.
* Add an informational message when defining a region that overlaps vanilla spawn protection.
* Protect against pushing a piston with another piston on a region border.
* Protect against buckets in dispensers on region borders.
## 7.0.1
* Add `/rg toggle-bypass` command which temporarily turns off region bypassing until used again.
* More improvements to `/rg flag` and `/rg flags` commands.
+1 -1
View File
@@ -1,2 +1,2 @@
group=com.sk89q.worldguard
version=7.0.3
version=7.0.2-SNAPSHOT
+5 -5
View File
@@ -24,11 +24,11 @@ repositories {
dependencies {
"compile"(project(":worldguard-core"))
//"compile"(project(":worldguard-libs:bukkit"))
"api"("com.destroystokyo.paper:paper-api:1.15.2-R0.1-SNAPSHOT")
"implementation"("io.papermc:paperlib:1.0.4")
"api"("com.destroystokyo.paper:paper-api:1.15-R0.1-SNAPSHOT")
"implementation"("io.papermc:paperlib:1.0.2")
"api"("com.sk89q.worldedit:worldedit-bukkit:${Versions.WORLDEDIT}") { isTransitive = false }
"implementation"("com.sk89q:commandbook:2.3") { isTransitive = false }
"implementation"("org.bstats:bstats-bukkit:1.7")
"implementation"("org.bstats:bstats-bukkit:1.5")
}
tasks.named<Upload>("install") {
@@ -61,10 +61,10 @@ tasks.named<Jar>("jar") {
tasks.named<ShadowJar>("shadowJar") {
dependencies {
relocate("org.bstats", "com.sk89q.worldguard.bukkit.bstats") {
include(dependency("org.bstats:bstats-bukkit:1.7"))
include(dependency("org.bstats:bstats-bukkit:1.5"))
}
relocate ("io.papermc.lib", "com.sk89q.worldguard.bukkit.paperlib") {
include(dependency("io.papermc:paperlib:1.0.4"))
include(dependency("io.papermc:paperlib:1.0.2"))
}
}
}
@@ -24,8 +24,6 @@ import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.weather.WeatherType;
import com.sk89q.worldedit.world.weather.WeatherTypes;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.util.MessagingUtil;
import io.papermc.lib.PaperLib;
import org.bukkit.BanList.Type;
import org.bukkit.Bukkit;
@@ -174,11 +172,7 @@ public class BukkitPlayer extends com.sk89q.worldedit.bukkit.BukkitPlayer implem
@Override
public void sendTitle(String title, String subtitle) {
if (WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(getWorld()).forceDefaultTitleTimes) {
getPlayer().sendTitle(title, subtitle, 10, 70, 20);
} else {
getPlayer().sendTitle(title, subtitle, -1, -1, -1);
}
getPlayer().sendTitle(title, subtitle, -1, -1, -1);
}
@Override
@@ -191,10 +185,7 @@ public class BukkitPlayer extends com.sk89q.worldedit.bukkit.BukkitPlayer implem
PaperLib.teleportAsync(getPlayer(), BukkitAdapter.adapt(location))
.thenApply(success -> {
if (success) {
// The success message can be cleared via flag
if (!successMessage.isEmpty()) {
MessagingUtil.sendStringToChat(this, successMessage);
}
print(successMessage);
} else {
printError(failMessage);
}
@@ -105,13 +105,6 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
if (inputs == null || inputs.isEmpty()) {
parentConfig.setProperty(node, new ArrayList<String>());
}
if (config.getProperty(node) != null) {
inputs = config.getStringList(node, null);
}
if (inputs == null || inputs.isEmpty()) {
return set;
}
@@ -151,7 +144,6 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
allowAllInteract = getTargetMatchers("event-handling.interaction-whitelist");
blockUseAtFeet = getTargetMatchers("event-handling.emit-block-use-at-feet");
ignoreHopperMoveEvents = getBoolean("event-handling.ignore-hopper-item-move-events", false);
breakDeniedHoppers = getBoolean("event-handling.break-hoppers-on-denied-move", true);
usePaperEntityOrigin = getBoolean("regions.use-paper-entity-origin", false);
@@ -259,14 +251,12 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
disableVineGrowth = getBoolean("dynamics.disable-vine-growth", false);
disableCropGrowth = getBoolean("dynamics.disable-crop-growth", false);
disableSoilDehydration = getBoolean("dynamics.disable-soil-dehydration", false);
disableCoralBlockFade = getBoolean("dynamics.disable-coral-block-fade", false);
allowedSnowFallOver = new HashSet<>(convertLegacyBlocks(getStringList("dynamics.snow-fall-blocks", null)));
useRegions = getBoolean("regions.enable", true);
regionInvinciblityRemovesMobs = getBoolean("regions.invincibility-removes-mobs", false);
regionCancelEmptyChatEvents = getBoolean("regions.cancel-chat-without-recipients", true);
regionNetherPortalProtection = getBoolean("regions.nether-portal-protection", true);
forceDefaultTitleTimes = config.getBoolean("regions.titles-always-use-default-times", true); // note: technically not region-specific, but we only use it for the title flags
regionNetherPortalProtection = getBoolean("regions.nether-portal-protection", false);
fakePlayerBuildOverride = getBoolean("regions.fake-player-build-override", true);
explosionFlagCancellation = getBoolean("regions.explosion-flags-block-entity-damage", true);
highFreqFlags = getBoolean("regions.high-frequency-flags", false);
@@ -20,6 +20,7 @@
package com.sk89q.worldguard.bukkit;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Streams;
import com.sk89q.bukkit.util.CommandsManagerRegistration;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
@@ -92,8 +93,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.jar.JarFile;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
/**
* The main class for WorldGuard as a Bukkit plugin.
@@ -212,7 +214,7 @@ public class WorldGuardPlugin extends JavaPlugin {
((SimpleFlagRegistry) WorldGuard.getInstance().getFlagRegistry()).setInitialized(true);
// Enable metrics
final Metrics metrics = new Metrics(this, 3283); // bStats plugin id
final Metrics metrics = new Metrics(this);
if (metrics.isEnabled() && platform.getGlobalStateManager().extraStats) {
setupCustomCharts(metrics);
}
@@ -486,25 +488,44 @@ public class WorldGuardPlugin extends JavaPlugin {
return;
}
try (InputStream stream = getResource("defaults/" + defaultName)){
if (stream == null) throw new FileNotFoundException();
copyDefaultConfig(stream, actual, defaultName);
InputStream input = null;
try {
JarFile file = new JarFile(getFile());
ZipEntry copy = file.getEntry("defaults/" + defaultName);
if (copy == null) throw new FileNotFoundException();
input = file.getInputStream(copy);
} catch (IOException e) {
getLogger().severe("Unable to read default configuration: " + defaultName);
WorldGuard.logger.severe("Unable to read default configuration: " + defaultName);
}
}
if (input != null) {
FileOutputStream output = null;
private void copyDefaultConfig(InputStream input, File actual, String name) {
try (FileOutputStream output = new FileOutputStream(actual)) {
byte[] buf = new byte[8192];
int length;
while ((length = input.read(buf)) > 0) {
output.write(buf, 0, length);
try {
output = new FileOutputStream(actual);
byte[] buf = new byte[8192];
int length = 0;
while ((length = input.read(buf)) > 0) {
output.write(buf, 0, length);
}
WorldGuard.logger.info("Default configuration file written: "
+ actual.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
input.close();
} catch (IOException ignore) {
}
try {
if (output != null) {
output.close();
}
} catch (IOException ignore) {
}
}
getLogger().info("Default configuration file written: " + name);
} catch (IOException e) {
getLogger().log(Level.WARNING, "Failed to write default config file", e);
}
}
@@ -36,7 +36,6 @@ import org.bukkit.entity.TNTPrimed;
import org.bukkit.entity.Tameable;
import org.bukkit.entity.Vehicle;
import org.bukkit.metadata.Metadatable;
import org.bukkit.projectiles.BlockProjectileSource;
import javax.annotation.Nullable;
import java.util.ArrayList;
@@ -237,15 +236,6 @@ public final class Cause {
WGMetadata.put(target, CAUSE_KEY, parent);
}
/**
* Remove a parent cause from a {@code Metadatable} object.
*
* @param target the target
*/
public static void untrackParentCause(Metadatable target) {
WGMetadata.remove(target, CAUSE_KEY);
}
/**
* Builds causes.
*/
@@ -284,14 +274,12 @@ public final class Cause {
} else if (o instanceof AreaEffectCloud) {
indirect = true;
addAll(((AreaEffectCloud) o).getSource());
} else if (o instanceof Tameable) {
indirect = true;
addAll(((Tameable) o).getOwner());
} else if (o instanceof Creature && ((Creature) o).getTarget() != null) {
indirect = true;
addAll(((Creature) o).getTarget());
} else if (o instanceof BlockProjectileSource) {
addAll(((BlockProjectileSource) o).getBlock());
} else if (o instanceof Tameable) {
indirect = true;
addAll(((Tameable) o).getOwner());
}
// Add manually tracked parent causes
@@ -75,13 +75,4 @@ public final class WGMetadata {
return null;
}
/**
* Removes metadata from the target.
*
* @param target the target
* @param key the key
*/
public static void remove(Metadatable target, String key) {
target.removeMetadata(key, WorldGuardPlugin.inst());
}
}
@@ -61,7 +61,6 @@ import org.bukkit.block.Chest;
import org.bukkit.block.DoubleChest;
import org.bukkit.block.Hopper;
import org.bukkit.block.PistonMoveReaction;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Waterlogged;
import org.bukkit.block.data.type.Dispenser;
import org.bukkit.entity.AreaEffectCloud;
@@ -73,10 +72,8 @@ import org.bukkit.entity.Firework;
import org.bukkit.entity.Item;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Mob;
import org.bukkit.entity.Painting;
import org.bukkit.entity.Player;
import org.bukkit.entity.Tameable;
import org.bukkit.entity.ThrownPotion;
import org.bukkit.entity.minecart.HopperMinecart;
import org.bukkit.event.Cancellable;
@@ -97,7 +94,6 @@ import org.bukkit.event.block.BlockMultiPlaceEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.block.CauldronLevelChangeEvent;
import org.bukkit.event.block.EntityBlockFormEvent;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.entity.AreaEffectCloudApplyEvent;
@@ -139,7 +135,6 @@ import org.bukkit.event.vehicle.VehicleDamageEvent;
import org.bukkit.event.vehicle.VehicleDestroyEvent;
import org.bukkit.event.world.StructureGrowEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.projectiles.ProjectileSource;
@@ -159,17 +154,6 @@ public class EventAbstractionListener extends AbstractListener {
private final EventDebounce<BlockPistonRetractKey> pistonRetractDebounce = EventDebounce.create(5000);
private final EventDebounce<BlockPistonExtendKey> pistonExtendDebounce = EventDebounce.create(5000);
private static final boolean HAS_SNAPSHOT_INVHOLDER;
static {
boolean temp;
try {
Inventory.class.getMethod("getHolder", boolean.class);
temp = true;
} catch (NoSuchMethodException e) {
temp = false;
}
HAS_SNAPSHOT_INVHOLDER = temp;
}
/**
* Construct the listener.
*
@@ -286,24 +270,14 @@ public class EventAbstractionListener extends AbstractListener {
boolean trample = fromType == Material.FARMLAND && toType == Material.DIRT;
BreakBlockEvent breakDelagate = new BreakBlockEvent(event, cause, block);
if (trample) {
breakDelagate.setSilent(true);
breakDelagate.getRelevantFlags().add(Flags.TRAMPLE_BLOCKS);
} else if (fromType == Material.REDSTONE_ORE) {
breakDelagate.setSilent(true);
}
boolean denied;
if (!(denied = Events.fireToCancel(event, breakDelagate))) {
if (!Events.fireToCancel(event, breakDelagate)) {
PlaceBlockEvent placeDelegate = new PlaceBlockEvent(event, cause, block.getLocation(), toType);
if (trample) {
placeDelegate.setSilent(true);
placeDelegate.getRelevantFlags().add(Flags.TRAMPLE_BLOCKS);
} else if (fromType == Material.REDSTONE_ORE) {
placeDelegate.setSilent(true);
}
denied = Events.fireToCancel(event, placeDelegate);
}
if (denied && entity instanceof Player) {
playDenyEffect((Player) entity, block.getLocation());
Events.fireToCancel(event, placeDelegate);
}
} else {
if (toType == Material.AIR) {
@@ -322,19 +296,16 @@ public class EventAbstractionListener extends AbstractListener {
Events.fireToCancel(event, new PlaceBlockEvent(event, cause, block.getLocation(), toType));
if (entity instanceof FallingBlock) {
if (event.isCancelled() && !wasCancelled) {
FallingBlock fallingBlock = (FallingBlock) entity;
final Material material = fallingBlock.getBlockData().getMaterial();
if (!material.isItem()) return;
ItemStack itemStack = new ItemStack(material, 1);
Item item = block.getWorld().dropItem(fallingBlock.getLocation(), itemStack);
item.setVelocity(new Vector());
if (Events.fireAndTestCancel(new SpawnEntityEvent(event, create(block, entity), item))) {
item.remove();
}
if (event.isCancelled() && !wasCancelled && entity instanceof FallingBlock) {
FallingBlock fallingBlock = (FallingBlock) entity;
final Material material = fallingBlock.getBlockData().getMaterial();
if (!material.isItem()) return;
ItemStack itemStack = new ItemStack(material, 1);
Item item = block.getWorld().dropItem(fallingBlock.getLocation(), itemStack);
item.setVelocity(new Vector());
if (Events.fireAndTestCancel(new SpawnEntityEvent(event, create(block, entity), item))) {
item.remove();
}
Cause.untrackParentCause(entity);
}
}
}
@@ -344,9 +315,6 @@ public class EventAbstractionListener extends AbstractListener {
public void onEntityExplode(EntityExplodeEvent event) {
Entity entity = event.getEntity();
Events.fireBulkEventToCancel(event, new BreakBlockEvent(event, create(entity), event.getLocation().getWorld(), event.blockList(), Material.AIR));
if (entity instanceof Creeper) {
Cause.untrackParentCause(entity);
}
}
@EventHandler(ignoreCancelled = true)
@@ -364,7 +332,6 @@ public class EventAbstractionListener extends AbstractListener {
Events.fireBulkEventToCancel(event, new BreakBlockEvent(event, cause, event.getBlock().getWorld(), blocks, Material.AIR));
if (originalSize != blocks.size()) {
event.setCancelled(true);
return;
}
for (Block b : blocks) {
Location loc = b.getRelative(direction).getLocation();
@@ -384,14 +351,8 @@ public class EventAbstractionListener extends AbstractListener {
public void onBlockPistonExtend(BlockPistonExtendEvent event) {
EventDebounce.Entry entry = pistonExtendDebounce.getIfNotPresent(new BlockPistonExtendKey(event), event);
if (entry != null) {
Cause cause = create(event.getBlock());
List<Block> blocks = new ArrayList<>(event.getBlocks());
int originalLength = blocks.size();
Events.fireBulkEventToCancel(event, new BreakBlockEvent(event, cause, event.getBlock().getWorld(), blocks, Material.AIR));
if (originalLength != blocks.size()) {
event.setCancelled(true);
return;
}
BlockFace dir = event.getDirection();
for (int i = 0; i < blocks.size(); i++) {
Block existing = blocks.get(i);
@@ -401,7 +362,7 @@ public class EventAbstractionListener extends AbstractListener {
blocks.set(i, existing.getRelative(dir));
}
}
Events.fireBulkEventToCancel(event, new PlaceBlockEvent(event, cause, event.getBlock().getWorld(), blocks, Material.STONE));
Events.fireBulkEventToCancel(event, new PlaceBlockEvent(event, create(event.getBlock()), event.getBlock().getWorld(), blocks, Material.STONE));
if (blocks.size() != originalLength) {
event.setCancelled(true);
}
@@ -434,37 +395,23 @@ public class EventAbstractionListener extends AbstractListener {
@Nullable ItemStack item = event.getItem();
Block clicked = event.getClickedBlock();
Block placed;
boolean silent = false;
boolean modifiesWorld;
Cause cause = create(player);
switch (event.getAction()) {
case PHYSICAL:
if (event.useInteractedBlock() != Result.DENY) {
if (clicked.getType() == Material.FARMLAND || clicked.getType() == Material.TURTLE_EGG) {
BreakBlockEvent breakDelagate = new BreakBlockEvent(event, cause, clicked);
breakDelagate.setSilent(true);
breakDelagate.getRelevantFlags().add(Flags.TRAMPLE_BLOCKS);
boolean denied;
if (!(denied = Events.fireToCancel(event, breakDelagate))) {
PlaceBlockEvent placeDelegate = new PlaceBlockEvent(event, cause, clicked.getLocation(),
clicked.getType() == Material.FARMLAND ? Material.DIRT : clicked.getType());
placeDelegate.setSilent(true);
placeDelegate.getRelevantFlags().add(Flags.TRAMPLE_BLOCKS);
denied = Events.fireToCancel(event, placeDelegate);
}
if (denied) {
playDenyEffect(player, clicked.getLocation());
}
return;
}
DelegateEvent firedEvent = new UseBlockEvent(event, cause, clicked).setAllowed(hasInteractBypass(clicked));
if (clicked.getType() == Material.REDSTONE_ORE) {
firedEvent.setSilent(true);
silent = true;
}
if (clicked.getType() == Material.FARMLAND || clicked.getType() == Material.TURTLE_EGG) {
silent = true;
firedEvent.getRelevantFlags().add(Flags.TRAMPLE_BLOCKS);
}
firedEvent.setSilent(silent);
interactDebounce.debounce(clicked, event.getPlayer(), event, firedEvent);
if (event.useInteractedBlock() == Result.DENY) {
playDenyEffect(player, clicked.getLocation().add(0, 1, 0));
}
}
break;
@@ -846,11 +793,7 @@ public class EventAbstractionListener extends AbstractListener {
} else if (damager instanceof Creeper) {
eventToFire.getRelevantFlags().add(Flags.CREEPER_EXPLOSION);
}
if (Events.fireToCancel(event, eventToFire)) {
if (damager instanceof Tameable && damager instanceof Mob) {
((Mob) damager).setTarget(null);
}
}
Events.fireToCancel(event, eventToFire);
// Item use event with the item in hand
// Older blacklist handler code used this, although it suffers from
@@ -931,35 +874,21 @@ public class EventAbstractionListener extends AbstractListener {
@EventHandler(ignoreCancelled = true)
public void onInventoryMoveItem(InventoryMoveItemEvent event) {
InventoryHolder causeHolder;
if (HAS_SNAPSHOT_INVHOLDER) {
causeHolder = event.getInitiator().getHolder(false);
} else {
causeHolder = event.getInitiator().getHolder();
}
final InventoryHolder causeHolder = event.getInitiator().getHolder();
WorldConfiguration wcfg = null;
if (causeHolder instanceof Hopper
&& (wcfg = getWorldConfig(BukkitAdapter.adapt((((Hopper) causeHolder).getWorld())))).ignoreHopperMoveEvents) {
&& getWorldConfig(BukkitAdapter.adapt((((Hopper) causeHolder).getWorld()))).ignoreHopperMoveEvents) {
return;
} else if (causeHolder instanceof HopperMinecart
&& (wcfg = getWorldConfig(BukkitAdapter.adapt((((HopperMinecart) causeHolder).getWorld())))).ignoreHopperMoveEvents) {
&& getWorldConfig(BukkitAdapter.adapt((((HopperMinecart) causeHolder).getWorld()))).ignoreHopperMoveEvents) {
return;
}
Entry entry;
if ((entry = moveItemDebounce.tryDebounce(event)) != null) {
InventoryHolder sourceHolder;
InventoryHolder targetHolder;
if (HAS_SNAPSHOT_INVHOLDER) {
sourceHolder = event.getSource().getHolder(false);
targetHolder = event.getDestination().getHolder(false);
} else {
sourceHolder = event.getSource().getHolder();
targetHolder = event.getDestination().getHolder();
}
InventoryHolder sourceHolder = event.getSource().getHolder();
InventoryHolder targetHolder = event.getDestination().getHolder();
Cause cause;
if (causeHolder instanceof Entity) {
@@ -976,7 +905,7 @@ public class EventAbstractionListener extends AbstractListener {
handleInventoryHolderUse(event, cause, targetHolder);
if (event.isCancelled() && causeHolder instanceof Hopper && wcfg.breakDeniedHoppers) {
if (event.isCancelled() && causeHolder instanceof Hopper) {
Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(),
() -> ((Hopper) causeHolder).getBlock().breakNaturally());
} else {
@@ -1023,18 +952,15 @@ public class EventAbstractionListener extends AbstractListener {
@EventHandler(ignoreCancelled = true)
public void onBlockDispense(BlockDispenseEvent event) {
Cause cause = create(event.getBlock());
Block dispenserBlock = event.getBlock();
ItemStack item = event.getItem();
Events.fireToCancel(event, new UseItemEvent(event, cause, dispenserBlock.getWorld(), item));
// Simulate right click event as players have it
if (dispenserBlock.getType() == Material.DISPENSER) {
Cause cause = create(event.getBlock());
ItemStack item = event.getItem();
if (Events.fireToCancel(event, new UseItemEvent(event, cause, dispenserBlock.getWorld(), item))) {
return;
}
BlockData blockData = dispenserBlock.getBlockData();
Dispenser dispenser = (Dispenser) blockData; // if this ClassCastExceptions it's a bukkit bug
if (dispenserBlock.getBlockData() instanceof Dispenser) {
Dispenser dispenser = (Dispenser) dispenserBlock.getBlockData();
Block placed = dispenserBlock.getRelative(dispenser.getFacing());
Block clicked = placed.getRelative(dispenser.getFacing());
handleBlockRightClick(event, cause, item, clicked, placed);
@@ -1088,14 +1014,6 @@ public class EventAbstractionListener extends AbstractListener {
Events.fireToCancel(event, useEvent);
}
@EventHandler(ignoreCancelled = true)
public void onCauldronLevelChange(CauldronLevelChangeEvent event) {
if (event.getEntity() == null) return;
interactDebounce.debounce(event.getBlock(), event.getEntity(), event,
new UseBlockEvent(event, create(event.getEntity()),
event.getBlock()).setAllowed(hasInteractBypass(event.getBlock())));
}
/**
* Handle the right click of a block while an item is held.
*
@@ -35,7 +35,6 @@ 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.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.vehicle.VehicleEnterEvent;
import org.bukkit.plugin.PluginManager;
@@ -78,14 +77,6 @@ public class PlayerMoveListener implements Listener {
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerMove(PlayerMoveEvent event) {
Location from = event.getFrom();
Location to = event.getTo();
if (from.getBlockX() == to.getBlockX()
&& from.getBlockY() == to.getBlockY()
&& from.getBlockZ() == to.getBlockZ()) {
return;
}
final Player player = event.getPlayer();
LocalPlayer localPlayer = plugin.wrapPlayer(player);
@@ -98,15 +89,15 @@ public class PlayerMoveListener implements Listener {
} else if (event.getPlayer().getVehicle() != null && event.getPlayer().getVehicle() instanceof Horse) {
moveType = MoveType.RIDE;
}
com.sk89q.worldedit.util.Location weLocation = session.testMoveTo(localPlayer, BukkitAdapter.adapt(to), moveType);
com.sk89q.worldedit.util.Location weLocation = session.testMoveTo(localPlayer, BukkitAdapter.adapt(event.getTo()), moveType);
if (weLocation != null) {
final Location override = BukkitAdapter.adapt(weLocation);
override.setX(override.getBlockX() + 0.5);
override.setY(override.getBlockY());
override.setZ(override.getBlockZ() + 0.5);
override.setPitch(to.getPitch());
override.setYaw(to.getYaw());
override.setPitch(event.getTo().getPitch());
override.setYaw(event.getTo().getYaw());
event.setTo(override.clone());
@@ -133,16 +124,4 @@ public class PlayerMoveListener implements Listener {
}
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
final Player player = event.getPlayer();
LocalPlayer localPlayer = plugin.wrapPlayer(player);
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().get(localPlayer);
com.sk89q.worldedit.util.Location loc = session.testMoveTo(localPlayer,
BukkitAdapter.adapt(event.getPlayer().getLocation()), MoveType.OTHER_CANCELLABLE); // white lie
if (loc != null) {
player.teleport(BukkitAdapter.adapt(loc));
}
}
}
@@ -41,6 +41,7 @@ import com.sk89q.worldguard.bukkit.util.InteropUtils;
import com.sk89q.worldguard.bukkit.util.Materials;
import com.sk89q.worldguard.commands.CommandUtils;
import com.sk89q.worldguard.config.WorldConfiguration;
import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
import com.sk89q.worldguard.protection.association.RegionAssociable;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.StateFlag;
@@ -258,7 +259,7 @@ public class RegionProtectionListener extends AbstractListener {
/* Inventory */
} else if (Materials.isInventoryBlock(type)) {
canUse = query.testBuild(BukkitAdapter.adapt(target), associable, combine(event, Flags.CHEST_ACCESS));
canUse = query.testBuild(BukkitAdapter.adapt(target), associable, combine(event, Flags.INTERACT, Flags.CHEST_ACCESS));
what = "open that";
/* Beds */
@@ -34,7 +34,6 @@ import com.sk89q.worldguard.util.SpongeUtil;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.data.Waterlogged;
import org.bukkit.entity.Player;
import org.bukkit.entity.Snowman;
import org.bukkit.event.EventHandler;
@@ -195,7 +194,7 @@ public class WorldGuardBlockListener implements Listener {
}
}
if (wcfg.highFreqFlags && (isWater || blockFrom.getBlockData() instanceof Waterlogged)
if (wcfg.highFreqFlags && isWater
&& WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().queryState(BukkitAdapter.adapt(blockFrom.getLocation()), (RegionAssociable) null, Flags.WATER_FLOW) == StateFlag.State.DENY) {
event.setCancelled(true);
return;
@@ -206,6 +205,13 @@ public class WorldGuardBlockListener implements Listener {
event.setCancelled(true);
return;
}
if (wcfg.disableObsidianGenerators && (isAir || isLava)
&& (blockTo.getType() == Material.REDSTONE_WIRE
|| blockTo.getType() == Material.TRIPWIRE)) {
blockTo.setType(Material.AIR);
return;
}
}
/*
@@ -676,16 +682,6 @@ public class WorldGuardBlockListener implements Listener {
event.setCancelled(true);
return;
}
} else if (Materials.isCoral(event.getBlock().getType())) {
if (wcfg.disableCoralBlockFade) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.CORAL_FADE))) {
event.setCancelled(true);
return;
}
}
}
@@ -47,9 +47,7 @@ import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.Enderman;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Fireball;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
@@ -76,10 +74,8 @@ 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.EntityRegainHealthEvent.RegainReason;
import org.bukkit.event.entity.EntityTransformEvent;
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.world.PortalCreateEvent;
@@ -752,10 +748,6 @@ public class WorldGuardEntityListener implements Listener {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onEntityRegainHealth(EntityRegainHealthEvent event) {
RegainReason regainReason = event.getRegainReason();
if (regainReason != RegainReason.REGEN && regainReason != RegainReason.SATIATED) {
return;
}
Entity ent = event.getEntity();
World world = ent.getWorld();
@@ -767,31 +759,6 @@ public class WorldGuardEntityListener implements Listener {
event.setCancelled(true);
return;
}
if (wcfg.useRegions && ent instanceof Player
&& !WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().testState(
BukkitAdapter.adapt(ent.getLocation()),
WorldGuardPlugin.inst().wrapPlayer((Player) ent),
Flags.HEALTH_REGEN)) {
event.setCancelled(true);
}
}
@EventHandler(ignoreCancelled = true)
public void onFoodChange(FoodLevelChangeEvent event) {
if (event.getItem() != null) return;
HumanEntity ent = event.getEntity();
if (!(ent instanceof Player)) return;
LocalPlayer player = WorldGuardPlugin.inst().wrapPlayer((Player) ent);
if (event.getFoodLevel() > player.getFoodLevel()) return;
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(player.getWorld());
if (wcfg.useRegions
&& !WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().testState(
player.getLocation(), player, Flags.HUNGER_DRAIN)) {
event.setCancelled(true);
}
}
/**
@@ -807,19 +774,7 @@ public class WorldGuardEntityListener implements Listener {
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(ent.getWorld()));
if (ent instanceof FallingBlock) {
Material id = event.getBlock().getType();
if (id == Material.GRAVEL && wcfg.noPhysicsGravel) {
event.setCancelled(true);
return;
}
if (id == Material.SAND && wcfg.noPhysicsSand) {
event.setCancelled(true);
return;
}
} else if (ent instanceof Enderman) {
if (ent instanceof Enderman) {
if (wcfg.disableEndermanGriefing) {
event.setCancelled(true);
return;
@@ -38,7 +38,6 @@ import com.sk89q.worldguard.session.Session;
import com.sk89q.worldguard.session.handler.GameModeFlag;
import com.sk89q.worldguard.util.Entities;
import com.sk89q.worldguard.util.command.CommandFilter;
import com.sk89q.worldguard.util.profile.Profile;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.World;
@@ -148,8 +147,6 @@ public class WorldGuardPlayerListener implements Listener {
}
Events.fire(new ProcessPlayerEvent(player));
WorldGuard.getInstance().getExecutorService().submit(() ->
WorldGuard.getInstance().getProfileCache().put(new Profile(player.getUniqueId(), player.getName())));
}
@EventHandler(ignoreCancelled = true)
@@ -202,8 +199,7 @@ public class WorldGuardPlayerListener implements Listener {
}
if (!hostname.equals(hostKey)
&& !(cfg.hostKeysAllowFMLClients &&
(hostname.equals(hostKey + "\u0000FML\u0000") || hostname.equals(hostKey + "\u0000FML2\u0000")))) {
&& !(cfg.hostKeysAllowFMLClients && hostname.equals(hostKey + "\u0000FML\u0000"))) {
event.disallow(PlayerLoginEvent.Result.KICK_OTHER,
"You did not join with the valid host key!");
log.warning("WorldGuard host key check: " +
@@ -27,6 +27,7 @@ import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.event.player.ProcessPlayerEvent;
import com.sk89q.worldguard.session.AbstractSessionManager;
import com.sk89q.worldguard.session.Session;
import com.sk89q.worldguard.util.profile.Profile;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -61,6 +62,8 @@ public class BukkitSessionManager extends AbstractSessionManager implements Runn
// Pre-load a session
LocalPlayer player = WorldGuardPlugin.inst().wrapPlayer(event.getPlayer());
get(player).initialize(player);
WorldGuard.getInstance().getExecutorService().submit(() ->
WorldGuard.getInstance().getProfileCache().put(new Profile(player.getUniqueId(), player.getName())));
}
@Override
@@ -454,9 +454,9 @@ public final class Materials {
MATERIAL_FLAGS.put(Material.STONECUTTER, 0);
MATERIAL_FLAGS.put(Material.SWEET_BERRY_BUSH, MODIFIED_ON_RIGHT);
MATERIAL_FLAGS.put(Material.IRON_SHOVEL, 0);
MATERIAL_FLAGS.put(Material.IRON_SHOVEL, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.IRON_PICKAXE, 0);
MATERIAL_FLAGS.put(Material.IRON_AXE, 0);
MATERIAL_FLAGS.put(Material.IRON_AXE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.FLINT_AND_STEEL, 0);
MATERIAL_FLAGS.put(Material.APPLE, 0);
MATERIAL_FLAGS.put(Material.BOW, 0);
@@ -467,32 +467,32 @@ public final class Materials {
MATERIAL_FLAGS.put(Material.GOLD_INGOT, 0);
MATERIAL_FLAGS.put(Material.IRON_SWORD, 0);
MATERIAL_FLAGS.put(Material.WOODEN_SWORD, 0);
MATERIAL_FLAGS.put(Material.WOODEN_SHOVEL, 0);
MATERIAL_FLAGS.put(Material.WOODEN_SHOVEL, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.WOODEN_PICKAXE, 0);
MATERIAL_FLAGS.put(Material.WOODEN_AXE, 0);
MATERIAL_FLAGS.put(Material.WOODEN_AXE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.STONE_SWORD, 0);
MATERIAL_FLAGS.put(Material.STONE_SHOVEL, 0);
MATERIAL_FLAGS.put(Material.STONE_SHOVEL, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.STONE_PICKAXE, 0);
MATERIAL_FLAGS.put(Material.STONE_AXE, 0);
MATERIAL_FLAGS.put(Material.STONE_AXE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.DIAMOND_SWORD, 0);
MATERIAL_FLAGS.put(Material.DIAMOND_SHOVEL, 0);
MATERIAL_FLAGS.put(Material.DIAMOND_SHOVEL, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.DIAMOND_PICKAXE, 0);
MATERIAL_FLAGS.put(Material.DIAMOND_AXE, 0);
MATERIAL_FLAGS.put(Material.DIAMOND_AXE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.STICK, 0);
MATERIAL_FLAGS.put(Material.BOWL, 0);
MATERIAL_FLAGS.put(Material.MUSHROOM_STEW, 0);
MATERIAL_FLAGS.put(Material.GOLDEN_SWORD, 0);
MATERIAL_FLAGS.put(Material.GOLDEN_SHOVEL, 0);
MATERIAL_FLAGS.put(Material.GOLDEN_SHOVEL, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.GOLDEN_PICKAXE, 0);
MATERIAL_FLAGS.put(Material.GOLDEN_AXE, 0);
MATERIAL_FLAGS.put(Material.GOLDEN_AXE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.STRING, 0);
MATERIAL_FLAGS.put(Material.FEATHER, 0);
MATERIAL_FLAGS.put(Material.GUNPOWDER, 0);
MATERIAL_FLAGS.put(Material.WOODEN_HOE, 0);
MATERIAL_FLAGS.put(Material.STONE_HOE, 0);
MATERIAL_FLAGS.put(Material.IRON_HOE, 0);
MATERIAL_FLAGS.put(Material.DIAMOND_HOE, 0);
MATERIAL_FLAGS.put(Material.GOLDEN_HOE, 0);
MATERIAL_FLAGS.put(Material.WOODEN_HOE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.STONE_HOE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.IRON_HOE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.DIAMOND_HOE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.GOLDEN_HOE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.WHEAT_SEEDS, 0);
MATERIAL_FLAGS.put(Material.BREAD, 0);
MATERIAL_FLAGS.put(Material.LEATHER_HELMET, 0);
@@ -547,29 +547,29 @@ public final class Materials {
MATERIAL_FLAGS.put(Material.COD, 0);
MATERIAL_FLAGS.put(Material.COOKED_COD, 0);
MATERIAL_FLAGS.put(Material.INK_SAC, 0);
MATERIAL_FLAGS.put(Material.BLACK_DYE, 0);
MATERIAL_FLAGS.put(Material.BLUE_DYE, 0);
MATERIAL_FLAGS.put(Material.BROWN_DYE, 0);
MATERIAL_FLAGS.put(Material.CYAN_DYE, 0);
MATERIAL_FLAGS.put(Material.GRAY_DYE, 0);
MATERIAL_FLAGS.put(Material.GREEN_DYE, 0);
MATERIAL_FLAGS.put(Material.LIGHT_BLUE_DYE, 0);
MATERIAL_FLAGS.put(Material.LIGHT_GRAY_DYE, 0);
MATERIAL_FLAGS.put(Material.LIME_DYE, 0);
MATERIAL_FLAGS.put(Material.MAGENTA_DYE, 0);
MATERIAL_FLAGS.put(Material.ORANGE_DYE, 0);
MATERIAL_FLAGS.put(Material.PINK_DYE, 0);
MATERIAL_FLAGS.put(Material.PURPLE_DYE, 0);
MATERIAL_FLAGS.put(Material.RED_DYE, 0);
MATERIAL_FLAGS.put(Material.WHITE_DYE, 0);
MATERIAL_FLAGS.put(Material.YELLOW_DYE, 0);
MATERIAL_FLAGS.put(Material.BLACK_DYE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.BLUE_DYE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.BROWN_DYE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.CYAN_DYE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.GRAY_DYE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.GREEN_DYE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.LIGHT_BLUE_DYE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.LIGHT_GRAY_DYE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.LIME_DYE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.MAGENTA_DYE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.ORANGE_DYE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.PINK_DYE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.PURPLE_DYE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.RED_DYE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.WHITE_DYE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.YELLOW_DYE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.COCOA_BEANS, 0);
MATERIAL_FLAGS.put(Material.BONE_MEAL, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.BONE, 0);
MATERIAL_FLAGS.put(Material.SUGAR, 0);
MATERIAL_FLAGS.put(Material.COOKIE, 0);
MATERIAL_FLAGS.put(Material.MAP, 0);
MATERIAL_FLAGS.put(Material.SHEARS, 0);
MATERIAL_FLAGS.put(Material.SHEARS, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.MELON_SLICE, 0);
MATERIAL_FLAGS.put(Material.PUMPKIN_SEEDS, 0);
MATERIAL_FLAGS.put(Material.MELON_SEEDS, 0);
@@ -1199,13 +1199,6 @@ public final class Materials {
return Tag.BEDS.isTagged(material);
}
public static boolean isCoral(Material material) {
return Tag.CORAL_BLOCKS.isTagged(material) ||
Tag.CORAL_PLANTS.isTagged(material) ||
Tag.CORALS.isTagged(material) ||
Tag.WALL_CORALS.isTagged(material);
}
/**
* Test whether the material is a crop.
* @param type the material
@@ -1299,7 +1292,7 @@ public final class Materials {
*/
public static boolean isItemAppliedToBlock(Material item, Material block) {
Integer flags = MATERIAL_FLAGS.get(item);
return flags == null || (flags & MODIFIES_BLOCKS) == MODIFIES_BLOCKS || isToolApplicable(item, block);
return flags == null || (flags & MODIFIES_BLOCKS) == MODIFIES_BLOCKS;
}
/**
@@ -1371,90 +1364,4 @@ public final class Materials {
}
}
/**
* Check if the material is usable via right-click on the target
* material. Returns false if the target material cannot be modified
* by the provided tool, or of the provided tool material isn't
* a tool material.
*
* @param toolMaterial the tool material being used
* @param targetMaterial the target material to check
* @return true if tool has an interact function with this material
*/
public static boolean isToolApplicable(Material toolMaterial, Material targetMaterial) {
switch (toolMaterial) {
case WOODEN_HOE:
case STONE_HOE:
case IRON_HOE:
case GOLDEN_HOE:
case DIAMOND_HOE:
switch (targetMaterial) {
case GRASS_BLOCK:
case DIRT:
case GRASS_PATH:
// case COARSE_DIRT: // already handled by the server...
return true;
}
return false;
case WOODEN_AXE:
case STONE_AXE:
case IRON_AXE:
case GOLDEN_AXE:
case DIAMOND_AXE:
switch (targetMaterial) {
case OAK_LOG:
case DARK_OAK_LOG:
case ACACIA_LOG:
case BIRCH_LOG:
case SPRUCE_LOG:
case JUNGLE_LOG:
case OAK_WOOD:
case DARK_OAK_WOOD:
case ACACIA_WOOD:
case BIRCH_WOOD:
case SPRUCE_WOOD:
case JUNGLE_WOOD:
return true;
}
return false;
case WOODEN_SHOVEL:
case STONE_SHOVEL:
case IRON_SHOVEL:
case GOLDEN_SHOVEL:
case DIAMOND_SHOVEL:
switch (targetMaterial) {
case GRASS_BLOCK:
case CAMPFIRE:
return true;
}
return false;
case SHEARS:
switch (targetMaterial) {
case PUMPKIN:
case BEE_NEST:
case BEEHIVE:
return true;
}
return false;
case BLACK_DYE:
case BLUE_DYE:
case BROWN_DYE:
case CYAN_DYE:
case GRAY_DYE:
case GREEN_DYE:
case LIGHT_BLUE_DYE:
case LIGHT_GRAY_DYE:
case LIME_DYE:
case MAGENTA_DYE:
case ORANGE_DYE:
case PINK_DYE:
case PURPLE_DYE:
case RED_DYE:
case WHITE_DYE:
case YELLOW_DYE:
return Tag.SIGNS.isTagged(targetMaterial);
default:
return false;
}
}
}
@@ -75,7 +75,7 @@ class FlagHelperBox extends PaginationBox {
.collect(Collectors.toList());
private static final int SIZE = FLAGS.size() == Flags.INBUILT_FLAGS.size() ? FLAGS.size() : FLAGS.size() + 1;
private static final int PAD_PX_SIZE = 180;
static final Set<Flag<?>> DANGER_ZONE = ImmutableSet.of(Flags.BUILD, Flags.PASSTHROUGH, Flags.BLOCK_PLACE, Flags.BLOCK_BREAK);
private static final Set<Flag<?>> DANGER_ZONE = ImmutableSet.of(Flags.BUILD, Flags.PASSTHROUGH, Flags.BLOCK_PLACE, Flags.BLOCK_BREAK);
private final World world;
private final ProtectedRegion region;
@@ -199,7 +199,7 @@ class FlagHelperBox extends PaginationBox {
if (maySet) {
if (isExplicitSet) {
hoverTexts.add(TextComponent.of("Click to unset", TextColor.GOLD));
} else if (DANGER_ZONE.contains(flag) && !(ProtectedRegion.GLOBAL_REGION.equals(region.getId()) && flag == Flags.PASSTHROUGH)) {
} else if (DANGER_ZONE.contains(flag)) {
hoverTexts.add(TextComponent.of("Setting this flag may have unintended consequences.", TextColor.RED)
.append(TextComponent.newline())
.append(TextComponent.of("Please read the documentation and set this flag manually if you really intend to.")
@@ -129,21 +129,22 @@ public final class RegionCommands extends RegionCommandsBase {
* @throws CommandException any error
*/
@Command(aliases = {"define", "def", "d", "create"},
usage = "[-w <world>] <id> [<owner1> [<owner2> [<owners...>]]]",
flags = "ngw:",
usage = "<id> [<owner1> [<owner2> [<owners...>]]]",
flags = "ng",
desc = "Defines a region",
min = 1)
public void define(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
LocalPlayer player = worldGuard.checkPlayer(sender);
// Check permissions
if (!getPermissionModel(sender).mayDefine()) {
if (!getPermissionModel(player).mayDefine()) {
throw new CommandPermissionsException();
}
String id = checkRegionId(args.getString(0), false);
World world = checkWorld(args, sender, 'w');
World world = player.getWorld();
RegionManager manager = checkRegionManager(world);
checkRegionDoesNotExist(manager, id, true);
@@ -153,7 +154,7 @@ public final class RegionCommands extends RegionCommandsBase {
if (args.hasFlag('g')) {
region = new GlobalProtectedRegion(id);
} else {
region = checkRegionFromSelection(sender, id);
region = checkRegionFromSelection(player, id);
}
RegionAdder task = new RegionAdder(manager, region);
@@ -181,22 +182,24 @@ public final class RegionCommands extends RegionCommandsBase {
* @throws CommandException any error
*/
@Command(aliases = {"redefine", "update", "move"},
usage = "[-w <world>] <id>",
usage = "<id>",
desc = "Re-defines the shape of a region",
flags = "gw:",
flags = "g",
min = 1, max = 1)
public void redefine(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
LocalPlayer player = worldGuard.checkPlayer(sender);
String id = checkRegionId(args.getString(0), false);
World world = checkWorld(args, sender, 'w');
World world = player.getWorld();
RegionManager manager = checkRegionManager(world);
ProtectedRegion existing = checkExistingRegion(manager, id, false);
// Check permissions
if (!getPermissionModel(sender).mayRedefine(existing)) {
if (!getPermissionModel(player).mayRedefine(existing)) {
throw new CommandPermissionsException();
}
@@ -205,7 +208,7 @@ public final class RegionCommands extends RegionCommandsBase {
if (args.hasFlag('g')) {
region = new GlobalProtectedRegion(id);
} else {
region = checkRegionFromSelection(sender, id);
region = checkRegionFromSelection(player, id);
}
region.copyFrom(existing);
@@ -218,9 +221,9 @@ public final class RegionCommands extends RegionCommandsBase {
.sendMessageAfterDelay("(Please wait... " + description + ")")
.onSuccess((Component) null,
t -> {
sender.print(String.format("Region '%s' has been updated with a new area.", region.getId()));
warnAboutDimensions(sender, region);
informNewUser(sender, manager, region);
player.print(String.format("Region '%s' has been updated with a new area.", region.getId()));
warnAboutDimensions(player, region);
informNewUser(player, manager, region);
checkSpawnOverlap(sender, world, region);
})
.onFailure(String.format("Failed to update the region '%s'", region.getId()), worldGuard.getExceptionConverter())
@@ -335,34 +338,28 @@ public final class RegionCommands extends RegionCommandsBase {
* @throws CommandException any error
*/
@Command(aliases = {"select", "sel", "s"},
usage = "[-w <world>] [id]",
usage = "[id]",
desc = "Load a region as a WorldEdit selection",
min = 0, max = 1,
flags = "w:")
min = 0, max = 1)
public void select(CommandContext args, Actor sender) throws CommandException {
World world = checkWorld(args, sender, 'w');
RegionManager manager = checkRegionManager(world);
LocalPlayer player = worldGuard.checkPlayer(sender);
RegionManager manager = checkRegionManager(player.getWorld());
ProtectedRegion existing;
// If no arguments were given, get the region that the player is inside
if (args.argsLength() == 0) {
LocalPlayer player = worldGuard.checkPlayer(sender);
if (!player.getWorld().equals(world)) { // confusing to get current location regions in another world
throw new CommandException("Please specify a region name."); // just don't allow that
}
world = player.getWorld();
existing = checkRegionStandingIn(manager, player, "/rg select -w \"" + world.getName() + "\" %id%");
existing = checkRegionStandingIn(manager, player, "/rg select %id%");
} else {
existing = checkExistingRegion(manager, args.getString(0), false);
}
// Check permissions
if (!getPermissionModel(sender).maySelect(existing)) {
if (!getPermissionModel(player).maySelect(existing)) {
throw new CommandPermissionsException();
}
// Select
setPlayerSelection(sender, existing, world);
setPlayerSelection(player, existing);
}
/**
@@ -410,7 +407,7 @@ public final class RegionCommands extends RegionCommandsBase {
throw new CommandPermissionsException();
}
setPlayerSelection(worldGuard.checkPlayer(sender), existing, world);
setPlayerSelection(worldGuard.checkPlayer(sender), existing);
}
// Print region information
@@ -420,10 +417,7 @@ public final class RegionCommands extends RegionCommandsBase {
AsyncCommandBuilder.wrap(printout, sender)
.registerWithSupervisor(WorldGuard.getInstance().getSupervisor(), "Fetching region info")
.sendMessageAfterDelay("(Please wait... fetching region information...)")
.onSuccess((Component) null, component -> {
sender.print(component);
checkSpawnOverlap(sender, world, existing);
})
.onSuccess((Component) null, sender::print)
.onFailure("Failed to fetch region information", WorldGuard.getInstance().getExceptionConverter())
.buildAndExec(WorldGuard.getInstance().getExecutorService());
}
@@ -628,7 +622,6 @@ public final class RegionCommands extends RegionCommandsBase {
printout.appendFlagsList(false);
printout.append(SubtleFormat.wrap(")"));
printout.send(sender);
checkSpawnOverlap(sender, world, existing);
}
}
@@ -669,12 +662,7 @@ public final class RegionCommands extends RegionCommandsBase {
if (!sender.isPlayer()) {
flagHelperBox.tryMonoSpacing();
}
AsyncCommandBuilder.wrap(() -> {
if (checkSpawnOverlap(sender, world, region)) {
flagHelperBox.setComponentsPerPage(15);
}
return flagHelperBox.create(page);
}, sender)
AsyncCommandBuilder.wrap(() -> flagHelperBox.create(page), sender)
.onSuccess((Component) null, sender::print)
.onFailure("Failed to get region flags", WorldGuard.getInstance().getExceptionConverter())
.buildAndExec(WorldGuard.getInstance().getExecutorService());
@@ -710,7 +698,6 @@ public final class RegionCommands extends RegionCommandsBase {
existing.setPriority(priority);
sender.print("Priority of '" + existing.getId() + "' set to " + priority + " (higher numbers override).");
checkSpawnOverlap(sender, world, existing);
}
/**
@@ -1111,16 +1098,8 @@ public final class RegionCommands extends RegionCommandsBase {
}
}
String message = existing.getFlag(Flags.TELE_MESSAGE);
// If the flag isn't set, use the default message
// If message.isEmpty(), no message is sent by LocalPlayer#teleport(...)
if (message == null) {
message = Flags.TELE_MESSAGE.getDefault();
}
player.teleport(teleportLocation,
message.replace("%id%", existing.getId()),
"Teleported you to the region '" + existing.getId() + "'.",
"Unable to teleport to region '" + existing.getId() + "'.");
}
@@ -84,25 +84,9 @@ class RegionCommandsBase {
* @throws CommandException on error
*/
protected static World checkWorld(CommandContext args, Actor sender, char flag) throws CommandException {
return checkWorld(args, sender, flag, true);
}
protected static World checkWorld(CommandContext args, Actor sender, char flag, boolean allowWorldEditOverride) throws CommandException {
if (args.hasFlag(flag)) {
return WorldGuard.getInstance().getPlatform().getMatcher().matchWorld(sender, args.getFlag(flag));
} else {
if (allowWorldEditOverride) {
try {
World override = WorldEdit.getInstance().getSessionManager().get(sender).getWorldOverride();
if (override != null) {
if (sender instanceof LocalPlayer && !override.equals(((LocalPlayer) sender).getWorld())) {
sender.printDebug(TextComponent.of("Using //world override for region command: " + override.getName()));
}
return override;
}
} catch (NoSuchMethodError ignored) {
}
}
if (sender instanceof LocalPlayer) {
return ((LocalPlayer) sender).getWorld();
} else {
@@ -235,17 +219,16 @@ class RegionCommandsBase {
}
/**
* Get a WorldEdit selection for an actor, or emit an exception if there is none
* Get a WorldEdit selection for a player, or emit an exception if there is none
* available.
*
* @param actor the actor
* @param player the player
* @return the selection
* @throws CommandException thrown on an error
*/
protected static Region checkSelection(Actor actor) throws CommandException {
protected static Region checkSelection(LocalPlayer player) throws CommandException {
try {
LocalSession localSession = WorldEdit.getInstance().getSessionManager().get(actor);
return localSession.getRegionSelector(localSession.getSelectionWorld()).getRegion();
return WorldEdit.getInstance().getSessionManager().get(player).getRegionSelector(player.getWorld()).getRegion();
} catch (IncompleteRegionException e) {
throw new CommandException(
"Please select an area first. " +
@@ -290,15 +273,15 @@ class RegionCommandsBase {
}
/**
* Create a {@link ProtectedRegion} from the actor's selection.
* Create a {@link ProtectedRegion} from the player's selection.
*
* @param actor the actor
* @param player the player
* @param id the ID of the new region
* @return a new region
* @throws CommandException thrown on an error
*/
protected static ProtectedRegion checkRegionFromSelection(Actor actor, String id) throws CommandException {
Region selection = checkSelection(actor);
protected static ProtectedRegion checkRegionFromSelection(LocalPlayer player, String id) throws CommandException {
Region selection = checkSelection(player);
// Detect the type of region from WorldEdit
if (selection instanceof Polygonal2DRegion) {
@@ -340,9 +323,6 @@ class RegionCommandsBase {
* @param region the region
*/
protected static void warnAboutDimensions(Actor sender, ProtectedRegion region) {
if (region instanceof GlobalProtectedRegion) {
return;
}
int height = region.getMaximumPoint().getBlockY() - region.getMinimumPoint().getBlockY();
if (height <= 2) {
sender.printDebug("(Warning: The height of the region was " + (height + 1) + " block(s).)");
@@ -371,28 +351,26 @@ class RegionCommandsBase {
* @param world the world the region is in
* @param region the region
*/
protected static boolean checkSpawnOverlap(Actor sender, World world, ProtectedRegion region) {
protected static void checkSpawnOverlap(Actor sender, World world, ProtectedRegion region) {
ProtectedRegion spawn = WorldGuard.getInstance().getPlatform().getSpawnProtection(world);
if (spawn != null) {
if (!spawn.getIntersectingRegions(ImmutableList.of(region)).isEmpty()) {
sender.print(ErrorFormat.wrap("Warning!")
.append(TextComponent.of(" This region overlaps vanilla's spawn protection. WorldGuard cannot " +
"override this, and only server operators will be able to interact with this area.", TextColor.WHITE)));
return true;
"override this, and only server operators will be able to interact with this area.")));
}
}
return false;
}
/**
* Set an actor's selection to a given region.
* Set a player's selection to a given region.
*
* @param actor the actor
* @param player the player
* @param region the region
* @throws CommandException thrown on a command error
*/
protected static void setPlayerSelection(Actor actor, ProtectedRegion region, World world) throws CommandException {
LocalSession session = WorldEdit.getInstance().getSessionManager().get(actor);
protected static void setPlayerSelection(LocalPlayer player, ProtectedRegion region) throws CommandException {
LocalSession session = WorldEdit.getInstance().getSessionManager().get(player);
// Set selection
if (region instanceof ProtectedCuboidRegion) {
@@ -400,20 +378,20 @@ class RegionCommandsBase {
BlockVector3 pt1 = cuboid.getMinimumPoint();
BlockVector3 pt2 = cuboid.getMaximumPoint();
CuboidRegionSelector selector = new CuboidRegionSelector(world, pt1, pt2);
session.setRegionSelector(world, selector);
selector.explainRegionAdjust(actor, session);
actor.print("Region selected as a cuboid.");
CuboidRegionSelector selector = new CuboidRegionSelector(player.getWorld(), pt1, pt2);
session.setRegionSelector(player.getWorld(), selector);
selector.explainRegionAdjust(player, session);
player.print("Region selected as a cuboid.");
} else if (region instanceof ProtectedPolygonalRegion) {
ProtectedPolygonalRegion poly2d = (ProtectedPolygonalRegion) region;
Polygonal2DRegionSelector selector = new Polygonal2DRegionSelector(
world, poly2d.getPoints(),
player.getWorld(), poly2d.getPoints(),
poly2d.getMinimumPoint().getBlockY(),
poly2d.getMaximumPoint().getBlockY());
session.setRegionSelector(world, selector);
selector.explainRegionAdjust(actor, session);
actor.print("Region selected as a polygon.");
session.setRegionSelector(player.getWorld(), selector);
selector.explainRegionAdjust(player, session);
player.print("Region selected as a polygon.");
} else if (region instanceof GlobalProtectedRegion) {
throw new CommandException(
@@ -19,7 +19,6 @@
package com.sk89q.worldguard.commands.region;
import com.sk89q.worldguard.protection.flags.registry.UnknownFlag;
import com.sk89q.worldguard.util.profile.cache.ProfileCache;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.math.BlockVector3;
@@ -144,22 +143,8 @@ public class RegionPrintoutBuilder implements Callable<TextComponent> {
flagString = flag.getName() + " -g " + group + ": ";
}
TextColor flagColor = TextColor.WHITE;
if (useColors) {
// passthrough is ok on global
if (FlagHelperBox.DANGER_ZONE.contains(flag)
&& !(region.getId().equals(ProtectedRegion.GLOBAL_REGION) && flag == Flags.PASSTHROUGH)) {
flagColor = TextColor.DARK_RED;
} else if (Flags.INBUILT_FLAGS.contains(flag.getName())) {
flagColor = TextColor.GOLD;
} else if (flag instanceof UnknownFlag) {
flagColor = TextColor.GRAY;
} else {
flagColor = TextColor.LIGHT_PURPLE;
}
}
TextComponent flagText = TextComponent.of(flagString, flagColor)
.append(TextComponent.of(String.valueOf(val), useColors ? TextColor.YELLOW : TextColor.WHITE));
TextComponent flagText = TextComponent.of(flagString, useColors ? TextColor.GOLD : TextColor.WHITE)
.append(TextComponent.of(String.valueOf(val), useColors? TextColor.YELLOW : TextColor.WHITE));
if (perms != null && perms.maySetFlag(region, flag)) {
flagText = flagText.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to set flag")))
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND,
@@ -320,7 +305,7 @@ public class RegionPrintoutBuilder implements Callable<TextComponent> {
builder.append(TextComponent.space().append(TextComponent.of("[Teleport]", TextColor.GRAY)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT,
TextComponent.of("Click to teleport").append(TextComponent.newline()).append(
TextComponent.of(teleFlag.getBlockX() + ", "
TextComponent.of(teleFlag.getBlockY() + ", "
+ teleFlag.getBlockY() + ", "
+ teleFlag.getBlockZ()))))
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
@@ -158,19 +158,16 @@ public abstract class WorldConfiguration {
public boolean disableEndermanGriefing;
public boolean disableSnowmanTrails;
public boolean disableSoilDehydration;
public boolean disableCoralBlockFade;
public Set<String> allowedSnowFallOver;
public boolean regionInvinciblityRemovesMobs;
public boolean regionCancelEmptyChatEvents;
public boolean regionNetherPortalProtection;
public boolean forceDefaultTitleTimes;
public boolean fakePlayerBuildOverride;
public boolean explosionFlagCancellation;
public boolean disableDeathMessages;
public boolean disableObsidianGenerators;
public boolean strictEntitySpawn;
public boolean ignoreHopperMoveEvents;
public boolean breakDeniedHoppers;
protected Map<String, Integer> maxRegionCounts;
/**
@@ -311,7 +311,7 @@ public class DefaultDomain implements Domain, ChangeTracked {
public String toGroupsString() {
StringBuilder str = new StringBuilder();
for (Iterator<String> it = groupDomain.getGroups().iterator(); it.hasNext(); ) {
str.append("g:");
str.append("*");
str.append(it.next());
if (it.hasNext()) {
str.append(", ");
@@ -373,8 +373,7 @@ public class DefaultDomain implements Domain, ChangeTracked {
private Component toGroupsComponent() {
final TextComponent.Builder builder = TextComponent.builder("");
for (Iterator<String> it = groupDomain.getGroups().iterator(); it.hasNext(); ) {
builder.append(TextComponent.of("g:", TextColor.GRAY))
.append(TextComponent.of(it.next(), TextColor.GOLD));
builder.append(TextComponent.of(it.next(), TextColor.GOLD));
if (it.hasNext()) {
builder.append(TextComponent.of(", "));
}
@@ -361,8 +361,7 @@ public class FlagValueCalculator {
if (flag == Flags.PASSTHROUGH) {
// Has members/owners -> the global region acts like
// a regular region without PASSTHROUGH
State passthrough = region.getFlag(Flags.PASSTHROUGH);
if (passthrough == State.DENY || passthrough != State.ALLOW && region.hasMembersOrOwners()) {
if (region.hasMembersOrOwners() || region.getFlag(Flags.PASSTHROUGH) == State.DENY) {
return null;
} else {
return (V) State.ALLOW;
@@ -118,7 +118,6 @@ public final class Flags {
public static final StateFlag VINE_GROWTH = register(new StateFlag("vine-growth", true));
public static final StateFlag CROP_GROWTH = register(new StateFlag("crop-growth", true));
public static final StateFlag SOIL_DRY = register(new StateFlag("soil-dry", true));
public static final StateFlag CORAL_FADE = register(new StateFlag("coral-fade", true));
public static final StateFlag WATER_FLOW = register(new StateFlag("water-flow", true));
public static final StateFlag LAVA_FLOW = register(new StateFlag("lava-flow", true));
@@ -135,20 +134,9 @@ public final class Flags {
public static final LocationFlag TELE_LOC = register(new LocationFlag("teleport", RegionGroup.MEMBERS));
public static final LocationFlag SPAWN_LOC = register(new LocationFlag("spawn", RegionGroup.MEMBERS));
/**
* @deprecated The type of this flag will change from a StringFlag to a ComponentFlag to support JSON text
* in a future release. If you depend on the type of this flag, take proper precaution for future breakage.
*/
@Deprecated
public static final StringFlag TELE_MESSAGE = register(new StringFlag("teleport-message",
LegacyComponentSerializer.INSTANCE.serialize(TextComponent.of("").append(TextComponent.of(
"Teleported you to the region '%id%'.", TextColor.LIGHT_PURPLE)))));
// idk?
public static final StateFlag INVINCIBILITY = register(new StateFlag("invincible", false));
public static final StateFlag FALL_DAMAGE = register(new StateFlag("fall-damage", true));
public static final StateFlag HEALTH_REGEN = register(new StateFlag("natural-health-regen", true));
public static final StateFlag HUNGER_DRAIN = register(new StateFlag("natural-hunger-drain", true));
// session and movement based flags
public static final StateFlag ENTRY = register(new StateFlag("entry", true, RegionGroup.NON_MEMBERS));
@@ -159,29 +147,9 @@ public final class Flags {
public static final StateFlag ENDERPEARL = register(new StateFlag("enderpearl", true));
public static final StateFlag CHORUS_TELEPORT = register(new StateFlag("chorus-fruit-teleport", true));
/**
* @deprecated The type of this flag will change from a StringFlag to a ComponentFlag to support JSON text
* in a future release. If you depend on the type of this flag, take proper precaution for future breakage.
*/
@Deprecated
public static final StringFlag GREET_MESSAGE = register(new StringFlag("greeting"));
/**
* @deprecated The type of this flag will change from a StringFlag to a ComponentFlag to support JSON text
* in a future release. If you depend on the type of this flag, take proper precaution for future breakage.
*/
@Deprecated
public static final StringFlag FAREWELL_MESSAGE = register(new StringFlag("farewell"));
/**
* @deprecated The type of this flag will change from a StringFlag to a ComponentFlag to support JSON text
* in a future release. If you depend on the type of this flag, take proper precaution for future breakage.
*/
@Deprecated
public static final StringFlag GREET_TITLE = register(new StringFlag("greeting-title"));
/**
* @deprecated The type of this flag will change from a StringFlag to a ComponentFlag to support JSON text
* in a future release. If you depend on the type of this flag, take proper precaution for future breakage.
*/
@Deprecated
public static final StringFlag FAREWELL_TITLE = register(new StringFlag("farewell-title"));
public static final BooleanFlag NOTIFY_ENTER = register(new BooleanFlag("notify-enter"));
@@ -205,29 +173,14 @@ public final class Flags {
public static final IntegerFlag MAX_FOOD = register(new IntegerFlag("feed-max-hunger"), f -> f.setSuggestedValues(VITALS_MAXS));
// deny messages
/**
* @deprecated The type of this flag will change from a StringFlag to a ComponentFlag to support JSON text
* in a future release. If you depend on the type of this flag, take proper precaution for future breakage.
*/
@Deprecated
public static final StringFlag DENY_MESSAGE = register(new StringFlag("deny-message",
LegacyComponentSerializer.INSTANCE.serialize(TextComponent.of("").append(TextComponent.of("Hey!",
TextColor.RED, Sets.newHashSet(TextDecoration.BOLD)))
.append(TextComponent.of(" Sorry, but you can't %what% here.", TextColor.GRAY)))));
/**
* @deprecated The type of this flag will change from a StringFlag to a ComponentFlag to support JSON text
* in a future release. If you depend on the type of this flag, take proper precaution for future breakage.
*/
@Deprecated
public static final StringFlag ENTRY_DENY_MESSAGE = register(new StringFlag("entry-deny-message",
LegacyComponentSerializer.INSTANCE.serialize(TextComponent.of("").append(TextComponent.of("Hey!",
TextColor.RED, Sets.newHashSet(TextDecoration.BOLD)))
.append(TextComponent.of(" You are not permitted to enter this area.", TextColor.GRAY)))));
/**
* @deprecated The type of this flag will change from a StringFlag to a ComponentFlag to support JSON text
* in a future release. If you depend on the type of this flag, take proper precaution for future breakage.
*/
@Deprecated
public static final StringFlag EXIT_DENY_MESSAGE = register(new StringFlag("exit-deny-message",
LegacyComponentSerializer.INSTANCE.serialize(TextComponent.of("").append(TextComponent.of("Hey!",
TextColor.RED, Sets.newHashSet(TextDecoration.BOLD)))
@@ -21,8 +21,6 @@ package com.sk89q.worldguard.protection.flags;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.Beta;
/**
* Stores an Number.
*/
@@ -39,20 +37,10 @@ public abstract class NumberFlag<T extends Number> extends Flag<T> {
super(name);
}
/**
* Not recommended for public use. Will likely be moved when migrating to piston for commands.
* @param values suggested values
*/
@Beta
public void setSuggestedValues(Number[] values) {
this.suggestions = checkNotNull(values);
}
/**
* Not recommended for public use. Will likely be moved when migrating to piston for commands.
* @return suggested values
*/
@Beta
public Number[] getSuggestedValues() {
return suggestions;
}
@@ -20,18 +20,25 @@
package com.sk89q.worldguard.protection.flags;
import com.google.common.collect.Sets;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Stores a set of types.
*/
public class SetFlag<T> extends Flag<Set<T>> {
private static final Pattern ANY_MODIFIER = Pattern.compile("^(add|sub|subtract|rem|remove) (.*)$");
private static final Pattern REMOVE_MODIFIERS = Pattern.compile("^(sub|subtract|rem|remove) (.*)$");
private Flag<T> subFlag;
public SetFlag(String name, RegionGroup defaultGroup, Flag<T> subFlag) {
@@ -60,10 +67,32 @@ public class SetFlag<T> extends Flag<Set<T>> {
return Sets.newHashSet();
} else {
Set<T> items = Sets.newHashSet();
boolean subtractive = false;
// If the input starts with particular keywords, attempt to load the existing values,
// and make this a modification, instead of an overwrite.
Matcher keywordMatcher = ANY_MODIFIER.matcher(input);
if (keywordMatcher.matches()) {
ProtectedRegion region = Objects.requireNonNull((ProtectedRegion) context.get("region"));
Set<T> existingValue = region.getFlag(this);
if (existingValue != null) {
items.addAll(existingValue);
}
subtractive = REMOVE_MODIFIERS.matcher(input).matches();
input = keywordMatcher.group(2);
}
for (String str : input.split(",")) {
FlagContext copy = context.copyWith(null, str, null);
items.add(subFlag.parseInput(copy));
T subFlagValue = subFlag.parseInput(copy);
if (subtractive) {
items.remove(subFlagValue);
} else {
items.add(subFlagValue);
}
}
return items;
@@ -59,7 +59,7 @@ public abstract class AbstractSessionManager implements SessionManager {
private final LoadingCache<WorldPlayerTuple, Boolean> bypassCache = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(2, TimeUnit.SECONDS)
.expireAfterAccess(2, TimeUnit.SECONDS)
.build(CacheLoader.from(tuple ->
tuple.getPlayer().hasPermission("worldguard.region.bypass." + tuple.getWorld().getName())));
@@ -27,7 +27,6 @@ import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldguard.TestPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.association.RegionOverlapAssociation;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
@@ -169,6 +168,10 @@ public abstract class RegionOverlapTest {
public void testPlayer2BuildAccess() {
ApplicableRegionSet appl;
HashSet<ProtectedRegion> test = new HashSet<>();
test.add(courtyard);
test.add(fountain);
// Outside
appl = manager.getApplicableRegions(outside);
assertTrue(appl.testState(player2, Flags.BUILD));
@@ -179,61 +182,4 @@ public abstract class RegionOverlapTest {
appl = manager.getApplicableRegions(inFountain);
assertTrue(appl.testState(player2, Flags.BUILD));
}
@Test
public void testNonPlayerBuildAccessInOneRegion() {
ApplicableRegionSet appl;
HashSet<ProtectedRegion> source = new HashSet<>();
source.add(courtyard);
RegionOverlapAssociation assoc = new RegionOverlapAssociation(source);
// Outside
appl = manager.getApplicableRegions(outside);
assertTrue(appl.testState(assoc, Flags.BUILD));
// Inside courtyard
appl = manager.getApplicableRegions(inCourtyard);
assertTrue(appl.testState(assoc, Flags.BUILD));
// Inside fountain
appl = manager.getApplicableRegions(inFountain);
assertFalse(appl.testState(assoc, Flags.BUILD));
}
@Test
public void testNonPlayerBuildAccessInBothRegions() {
ApplicableRegionSet appl;
HashSet<ProtectedRegion> source = new HashSet<>();
source.add(fountain);
source.add(courtyard);
RegionOverlapAssociation assoc = new RegionOverlapAssociation(source);
// Outside
appl = manager.getApplicableRegions(outside);
assertTrue(appl.testState(assoc, Flags.BUILD));
// Inside courtyard
appl = manager.getApplicableRegions(inCourtyard);
assertTrue(appl.testState(assoc, Flags.BUILD));
// Inside fountain
appl = manager.getApplicableRegions(inFountain);
assertTrue(appl.testState(assoc, Flags.BUILD));
}
@Test
public void testNonPlayerBuildAccessInNoRegions() {
ApplicableRegionSet appl;
HashSet<ProtectedRegion> source = new HashSet<>();
RegionOverlapAssociation assoc = new RegionOverlapAssociation(source);
// Outside
appl = manager.getApplicableRegions(outside);
assertTrue(appl.testState(assoc, Flags.BUILD));
// Inside courtyard
appl = manager.getApplicableRegions(inCourtyard);
assertFalse(appl.testState(assoc, Flags.BUILD));
// Inside fountain
appl = manager.getApplicableRegions(inFountain);
assertFalse(appl.testState(assoc, Flags.BUILD));
}
}