mirror of
https://github.com/EngineHub/WorldGuard.git
synced 2026-11-04 09:02:07 -05:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca7967085b |
No files matched your search
@@ -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. -->
|
||||
@@ -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.
|
||||
@@ -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. -->
|
||||
@@ -15,5 +15,3 @@ dependency-reduced-pom.xml
|
||||
.gradle/
|
||||
**/build/
|
||||
out/
|
||||
|
||||
scripts/
|
||||
@@ -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
@@ -1,2 +1,2 @@
|
||||
group=com.sk89q.worldguard
|
||||
version=7.0.3
|
||||
version=7.0.2-SNAPSHOT
|
||||
@@ -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"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ 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;
|
||||
@@ -56,6 +55,16 @@ public class BukkitPlayer extends com.sk89q.worldedit.bukkit.BukkitPlayer implem
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultNamespace() {
|
||||
// TODO: Add a per player override
|
||||
boolean useNamespaces = WorldGuard.getInstance().getPlatform().getGlobalStateManager().useNamespaces;
|
||||
if (useNamespaces) {
|
||||
return getUniqueId().toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasGroup(String group) {
|
||||
return plugin.inGroup(getPlayer(), group);
|
||||
@@ -174,11 +183,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 +196,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);
|
||||
}
|
||||
|
||||
+1
-11
@@ -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());
|
||||
}
|
||||
}
|
||||
+32
-114
@@ -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.
|
||||
*
|
||||
|
||||
+3
-24
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -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 */
|
||||
|
||||
+8
-12
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-46
@@ -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;
|
||||
|
||||
+1
-5
@@ -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: " +
|
||||
|
||||
+3
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,29 @@ import java.util.List;
|
||||
|
||||
public interface LocalPlayer extends Player, RegionAssociable {
|
||||
|
||||
/**
|
||||
* Returns the default namespace for this player.
|
||||
*
|
||||
* @return the default namespace.
|
||||
*/
|
||||
String getDefaultNamespace();
|
||||
|
||||
default boolean isDefaultNamespace(String otherNamespace) {
|
||||
String namespace = getDefaultNamespace();
|
||||
// If both are null, they're the same (the global)
|
||||
if (namespace == null && otherNamespace == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If only one is null, they're a mismatch
|
||||
if (namespace == null || otherNamespace == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compare string equality
|
||||
return namespace.equalsIgnoreCase(otherNamespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this player is inside a group.
|
||||
*
|
||||
|
||||
+2
-2
@@ -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.")
|
||||
|
||||
+25
-21
@@ -32,6 +32,7 @@ import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.RegionIdentifier;
|
||||
import com.sk89q.worldguard.protection.util.DomainInputResolver;
|
||||
import com.sk89q.worldguard.protection.util.DomainInputResolver.UserLocatorPolicy;
|
||||
|
||||
@@ -50,13 +51,13 @@ public class MemberCommands extends RegionCommandsBase {
|
||||
flags = "nw:",
|
||||
desc = "Add a member to a region",
|
||||
min = 2)
|
||||
public void addMember(CommandContext args, Actor sender) throws CommandException {
|
||||
public void addMember(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
|
||||
warnAboutSaveFailures(sender);
|
||||
|
||||
World world = checkWorld(args, sender, 'w'); // Get the world
|
||||
String id = args.getString(0);
|
||||
RegionManager manager = checkRegionManager(world);
|
||||
ProtectedRegion region = checkExistingRegion(manager, id, true);
|
||||
RegionIdentifier id = processRegionId(sender, args.getString(0), true);
|
||||
ProtectedRegion region = checkExistingRegion(sender, manager, id);
|
||||
|
||||
// Check permissions
|
||||
if (!getPermissionModel(sender).mayAddMembers(region)) {
|
||||
@@ -69,10 +70,11 @@ public class MemberCommands extends RegionCommandsBase {
|
||||
resolver.setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_ONLY);
|
||||
|
||||
|
||||
final String description = String.format("Adding members to the region '%s' on '%s'", region.getId(), world.getName());
|
||||
String friendlyName = id.getDisplayName(sender);
|
||||
final String description = String.format("Adding members to the region '%s' on '%s'", friendlyName, world.getName());
|
||||
AsyncCommandBuilder.wrap(resolver, sender)
|
||||
.registerWithSupervisor(worldGuard.getSupervisor(), description)
|
||||
.onSuccess(String.format("Region '%s' updated with new members.", region.getId()), region.getMembers()::addAll)
|
||||
.onSuccess(String.format("Region '%s' updated with new members.", friendlyName), region.getMembers()::addAll)
|
||||
.onFailure("Failed to add new members", worldGuard.getExceptionConverter())
|
||||
.buildAndExec(worldGuard.getExecutorService());
|
||||
}
|
||||
@@ -82,15 +84,14 @@ public class MemberCommands extends RegionCommandsBase {
|
||||
flags = "nw:",
|
||||
desc = "Add an owner to a region",
|
||||
min = 2)
|
||||
public void addOwner(CommandContext args, Actor sender) throws CommandException {
|
||||
public void addOwner(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
|
||||
warnAboutSaveFailures(sender);
|
||||
|
||||
World world = checkWorld(args, sender, 'w'); // Get the world
|
||||
|
||||
String id = args.getString(0);
|
||||
|
||||
RegionManager manager = checkRegionManager(world);
|
||||
ProtectedRegion region = checkExistingRegion(manager, id, true);
|
||||
RegionIdentifier id = processRegionId(sender, args.getString(0), true);
|
||||
ProtectedRegion region = checkExistingRegion(sender, manager, id);
|
||||
|
||||
// Check permissions
|
||||
if (!getPermissionModel(sender).mayAddOwners(region)) {
|
||||
@@ -103,10 +104,11 @@ public class MemberCommands extends RegionCommandsBase {
|
||||
resolver.setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_ONLY);
|
||||
|
||||
|
||||
final String description = String.format("Adding owners to the region '%s' on '%s'", region.getId(), world.getName());
|
||||
String friendlyName = id.getDisplayName(sender);
|
||||
final String description = String.format("Adding owners to the region '%s' on '%s'", friendlyName, world.getName());
|
||||
AsyncCommandBuilder.wrap(checkedAddOwners(sender, manager, region, world, resolver), sender)
|
||||
.registerWithSupervisor(worldGuard.getSupervisor(), description)
|
||||
.onSuccess(String.format("Region '%s' updated with new owners.", region.getId()), region.getOwners()::addAll)
|
||||
.onSuccess(String.format("Region '%s' updated with new owners.", friendlyName), region.getOwners()::addAll)
|
||||
.onFailure("Failed to add new owners", worldGuard.getExceptionConverter())
|
||||
.buildAndExec(worldGuard.getExecutorService());
|
||||
}
|
||||
@@ -149,13 +151,13 @@ public class MemberCommands extends RegionCommandsBase {
|
||||
flags = "naw:",
|
||||
desc = "Remove an owner to a region",
|
||||
min = 1)
|
||||
public void removeMember(CommandContext args, Actor sender) throws CommandException {
|
||||
public void removeMember(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
|
||||
warnAboutSaveFailures(sender);
|
||||
|
||||
World world = checkWorld(args, sender, 'w'); // Get the world
|
||||
String id = args.getString(0);
|
||||
RegionManager manager = checkRegionManager(world);
|
||||
ProtectedRegion region = checkExistingRegion(manager, id, true);
|
||||
RegionIdentifier id = processRegionId(sender, args.getString(0), true);
|
||||
ProtectedRegion region = checkExistingRegion(sender, manager, id);
|
||||
|
||||
// Check permissions
|
||||
if (!getPermissionModel(sender).mayRemoveMembers(region)) {
|
||||
@@ -178,11 +180,12 @@ public class MemberCommands extends RegionCommandsBase {
|
||||
callable = resolver;
|
||||
}
|
||||
|
||||
final String description = String.format("Removing members from the region '%s' on '%s'", region.getId(), world.getName());
|
||||
String friendlyName = id.getDisplayName(sender);
|
||||
final String description = String.format("Removing members from the region '%s' on '%s'", friendlyName, world.getName());
|
||||
AsyncCommandBuilder.wrap(callable, sender)
|
||||
.registerWithSupervisor(worldGuard.getSupervisor(), description)
|
||||
.sendMessageAfterDelay("(Please wait... querying player names...)")
|
||||
.onSuccess(String.format("Region '%s' updated with members removed.", region.getId()), region.getMembers()::removeAll)
|
||||
.onSuccess(String.format("Region '%s' updated with members removed.", friendlyName), region.getMembers()::removeAll)
|
||||
.onFailure("Failed to remove members", worldGuard.getExceptionConverter())
|
||||
.buildAndExec(worldGuard.getExecutorService());
|
||||
}
|
||||
@@ -192,13 +195,13 @@ public class MemberCommands extends RegionCommandsBase {
|
||||
flags = "naw:",
|
||||
desc = "Remove an owner to a region",
|
||||
min = 1)
|
||||
public void removeOwner(CommandContext args, Actor sender) throws CommandException {
|
||||
public void removeOwner(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
|
||||
warnAboutSaveFailures(sender);
|
||||
|
||||
World world = checkWorld(args, sender, 'w'); // Get the world
|
||||
String id = args.getString(0);
|
||||
RegionManager manager = checkRegionManager(world);
|
||||
ProtectedRegion region = checkExistingRegion(manager, id, true);
|
||||
RegionIdentifier id = processRegionId(sender, args.getString(0), true);
|
||||
ProtectedRegion region = checkExistingRegion(sender, manager, id);
|
||||
|
||||
// Check permissions
|
||||
if (!getPermissionModel(sender).mayRemoveOwners(region)) {
|
||||
@@ -221,11 +224,12 @@ public class MemberCommands extends RegionCommandsBase {
|
||||
callable = resolver;
|
||||
}
|
||||
|
||||
final String description = String.format("Removing owners from the region '%s' on '%s'", region.getId(), world.getName());
|
||||
String friendlyName = id.getDisplayName(sender);
|
||||
final String description = String.format("Removing owners from the region '%s' on '%s'", friendlyName, world.getName());
|
||||
AsyncCommandBuilder.wrap(callable, sender)
|
||||
.registerWithSupervisor(worldGuard.getSupervisor(), description)
|
||||
.sendMessageAfterDelay("(Please wait... querying player names...)")
|
||||
.onSuccess(String.format("Region '%s' updated with owners removed.", region.getId()), region.getOwners()::removeAll)
|
||||
.onSuccess(String.format("Region '%s' updated with owners removed.", friendlyName), region.getOwners()::removeAll)
|
||||
.onFailure("Failed to remove owners", worldGuard.getExceptionConverter())
|
||||
.buildAndExec(worldGuard.getExecutorService());
|
||||
}
|
||||
|
||||
+105
-111
@@ -32,6 +32,7 @@ import com.sk89q.worldedit.command.util.AsyncCommandBuilder;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.auth.AuthorizationException;
|
||||
import com.sk89q.worldedit.util.formatting.component.ErrorFormat;
|
||||
import com.sk89q.worldedit.util.formatting.component.LabelFormat;
|
||||
import com.sk89q.worldedit.util.formatting.component.SubtleFormat;
|
||||
@@ -44,7 +45,6 @@ import com.sk89q.worldedit.util.formatting.text.format.TextDecoration;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.commands.CommandUtils;
|
||||
import com.sk89q.worldguard.commands.task.RegionAdder;
|
||||
import com.sk89q.worldguard.commands.task.RegionLister;
|
||||
import com.sk89q.worldguard.commands.task.RegionManagerLoader;
|
||||
@@ -68,11 +68,8 @@ import com.sk89q.worldguard.protection.managers.migration.MigrationException;
|
||||
import com.sk89q.worldguard.protection.managers.migration.UUIDMigration;
|
||||
import com.sk89q.worldguard.protection.managers.storage.DriverType;
|
||||
import com.sk89q.worldguard.protection.managers.storage.RegionDriver;
|
||||
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.*;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException;
|
||||
import com.sk89q.worldguard.protection.regions.RegionContainer;
|
||||
import com.sk89q.worldguard.protection.util.DomainInputResolver.UserLocatorPolicy;
|
||||
import com.sk89q.worldguard.session.Session;
|
||||
import com.sk89q.worldguard.util.Enums;
|
||||
@@ -129,47 +126,49 @@ 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 {
|
||||
public void define(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
|
||||
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);
|
||||
RegionIdentifier id = processRegionId(sender, args.getString(0), false);
|
||||
|
||||
World world = checkWorld(args, sender, 'w');
|
||||
World world = player.getWorld();
|
||||
RegionManager manager = checkRegionManager(world);
|
||||
|
||||
checkRegionDoesNotExist(manager, id, true);
|
||||
checkRegionDoesNotExist(sender, manager, id, true);
|
||||
|
||||
ProtectedRegion region;
|
||||
|
||||
if (args.hasFlag('g')) {
|
||||
region = new GlobalProtectedRegion(id);
|
||||
} else {
|
||||
region = checkRegionFromSelection(sender, id);
|
||||
region = checkRegionFromSelection(player, id);
|
||||
}
|
||||
|
||||
RegionAdder task = new RegionAdder(manager, region);
|
||||
task.addOwnersFromCommand(args, 2);
|
||||
|
||||
final String description = String.format("Adding region '%s'", region.getId());
|
||||
String friendlyName = id.getDisplayName(sender);
|
||||
final String description = String.format("Adding region '%s'", friendlyName);
|
||||
AsyncCommandBuilder.wrap(task, sender)
|
||||
.registerWithSupervisor(worldGuard.getSupervisor(), description)
|
||||
.onSuccess((Component) null,
|
||||
t -> {
|
||||
sender.print(String.format("A new region has been made named '%s'.", region.getId()));
|
||||
sender.print(String.format("A new region has been made named '%s'.", friendlyName));
|
||||
warnAboutDimensions(sender, region);
|
||||
informNewUser(sender, manager, region);
|
||||
checkSpawnOverlap(sender, world, region);
|
||||
})
|
||||
.onFailure(String.format("Failed to add the region '%s'", region.getId()), worldGuard.getExceptionConverter())
|
||||
.onFailure(String.format("Failed to add the region '%s'", friendlyName), worldGuard.getExceptionConverter())
|
||||
.buildAndExec(worldGuard.getExecutorService());
|
||||
}
|
||||
|
||||
@@ -181,22 +180,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 {
|
||||
public void redefine(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
|
||||
warnAboutSaveFailures(sender);
|
||||
|
||||
String id = checkRegionId(args.getString(0), false);
|
||||
LocalPlayer player = worldGuard.checkPlayer(sender);
|
||||
|
||||
World world = checkWorld(args, sender, 'w');
|
||||
RegionIdentifier id = processRegionId(sender, args.getString(0), false);
|
||||
|
||||
World world = player.getWorld();
|
||||
RegionManager manager = checkRegionManager(world);
|
||||
|
||||
ProtectedRegion existing = checkExistingRegion(manager, id, false);
|
||||
ProtectedRegion existing = checkExistingRegion(sender, manager, id);
|
||||
|
||||
// Check permissions
|
||||
if (!getPermissionModel(sender).mayRedefine(existing)) {
|
||||
if (!getPermissionModel(player).mayRedefine(existing)) {
|
||||
throw new CommandPermissionsException();
|
||||
}
|
||||
|
||||
@@ -205,25 +206,26 @@ 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);
|
||||
|
||||
RegionAdder task = new RegionAdder(manager, region);
|
||||
|
||||
final String description = String.format("Updating region '%s'", region.getId());
|
||||
String friendlyName = id.getDisplayName(sender);
|
||||
final String description = String.format("Updating region '%s'", friendlyName);
|
||||
AsyncCommandBuilder.wrap(task, sender)
|
||||
.registerWithSupervisor(worldGuard.getSupervisor(), description)
|
||||
.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.", friendlyName));
|
||||
warnAboutDimensions(player, region);
|
||||
informNewUser(player, manager, region);
|
||||
checkSpawnOverlap(sender, world, region);
|
||||
})
|
||||
.onFailure(String.format("Failed to update the region '%s'", region.getId()), worldGuard.getExceptionConverter())
|
||||
.onFailure(String.format("Failed to update the region '%s'", friendlyName), worldGuard.getExceptionConverter())
|
||||
.buildAndExec(worldGuard.getExecutorService());
|
||||
}
|
||||
|
||||
@@ -241,7 +243,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
usage = "<id>",
|
||||
desc = "Claim a region",
|
||||
min = 1, max = 1)
|
||||
public void claim(CommandContext args, Actor sender) throws CommandException {
|
||||
public void claim(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
|
||||
warnAboutSaveFailures(sender);
|
||||
|
||||
LocalPlayer player = worldGuard.checkPlayer(sender);
|
||||
@@ -252,11 +254,11 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
throw new CommandPermissionsException();
|
||||
}
|
||||
|
||||
String id = checkRegionId(args.getString(0), false);
|
||||
RegionIdentifier id = processRegionId(sender, args.getString(0), false);
|
||||
|
||||
RegionManager manager = checkRegionManager(player.getWorld());
|
||||
|
||||
checkRegionDoesNotExist(manager, id, false);
|
||||
checkRegionDoesNotExist(sender, manager, id, false);
|
||||
ProtectedRegion region = checkRegionFromSelection(player, id);
|
||||
|
||||
WorldConfiguration wcfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(player.getWorld());
|
||||
@@ -318,11 +320,12 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
task.setLocatorPolicy(UserLocatorPolicy.UUID_ONLY);
|
||||
task.setOwnersInput(new String[]{player.getName()});
|
||||
|
||||
final String description = String.format("Claiming region '%s'", id);
|
||||
String friendlyName = id.getDisplayName(sender);
|
||||
final String description = String.format("Claiming region '%s'", friendlyName);
|
||||
AsyncCommandBuilder.wrap(task, sender)
|
||||
.registerWithSupervisor(WorldGuard.getInstance().getSupervisor(), description)
|
||||
.sendMessageAfterDelay("(Please wait... " + description + ")")
|
||||
.onSuccess(TextComponent.of(String.format("A new region has been claimed named '%s'.", id)), null)
|
||||
.onSuccess(TextComponent.of(String.format("A new region has been claimed named '%s'.", friendlyName)), null)
|
||||
.onFailure("Failed to claim region", WorldGuard.getInstance().getExceptionConverter())
|
||||
.buildAndExec(WorldGuard.getInstance().getExecutorService());
|
||||
}
|
||||
@@ -335,34 +338,29 @@ 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:")
|
||||
public void select(CommandContext args, Actor sender) throws CommandException {
|
||||
World world = checkWorld(args, sender, 'w');
|
||||
RegionManager manager = checkRegionManager(world);
|
||||
min = 0, max = 1)
|
||||
public void select(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
|
||||
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);
|
||||
RegionIdentifier id = processRegionId(sender, args.getString(0), false);
|
||||
existing = checkExistingRegion(sender, manager, id);
|
||||
}
|
||||
|
||||
// Check permissions
|
||||
if (!getPermissionModel(sender).maySelect(existing)) {
|
||||
if (!getPermissionModel(player).maySelect(existing)) {
|
||||
throw new CommandPermissionsException();
|
||||
}
|
||||
|
||||
// Select
|
||||
setPlayerSelection(sender, existing, world);
|
||||
setPlayerSelection(player, existing);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -377,7 +375,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
flags = "usw:",
|
||||
desc = "Get information about a region",
|
||||
min = 0, max = 1)
|
||||
public void info(CommandContext args, Actor sender) throws CommandException {
|
||||
public void info(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
|
||||
warnAboutSaveFailures(sender);
|
||||
|
||||
World world = checkWorld(args, sender, 'w'); // Get the world
|
||||
@@ -395,7 +393,8 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
existing = checkRegionStandingIn(manager, (LocalPlayer) sender, true,
|
||||
"/rg info -w \"" + world.getName() + "\" %id%" + (args.hasFlag('u') ? " -u" : "") + (args.hasFlag('s') ? " -s" : ""));
|
||||
} else { // Get region from the ID
|
||||
existing = checkExistingRegion(manager, args.getString(0), true);
|
||||
RegionIdentifier id = processRegionId(sender, args.getString(0), true);
|
||||
existing = checkExistingRegion(sender, manager, id);
|
||||
}
|
||||
|
||||
// Check permissions
|
||||
@@ -410,7 +409,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 +419,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());
|
||||
}
|
||||
@@ -494,7 +490,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
flags = "g:w:eh:",
|
||||
desc = "Set flags",
|
||||
min = 2)
|
||||
public void flag(CommandContext args, Actor sender) throws CommandException {
|
||||
public void flag(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
|
||||
warnAboutSaveFailures(sender);
|
||||
|
||||
World world = checkWorld(args, sender, 'w'); // Get the world
|
||||
@@ -514,13 +510,13 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
|
||||
// Lookup the existing region
|
||||
RegionManager manager = checkRegionManager(world);
|
||||
ProtectedRegion existing = checkExistingRegion(manager, args.getString(0), true);
|
||||
RegionIdentifier id = processRegionId(sender, args.getString(0), true);
|
||||
ProtectedRegion existing = checkExistingRegion(sender, manager, id);
|
||||
|
||||
// Check permissions
|
||||
if (!permModel.maySetFlag(existing)) {
|
||||
throw new CommandPermissionsException();
|
||||
}
|
||||
String regionId = existing.getId();
|
||||
|
||||
Flag<?> foundFlag = Flags.fuzzyMatchFlag(flagRegistry, flagName);
|
||||
|
||||
@@ -528,7 +524,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
// can use, and do nothing afterwards
|
||||
if (foundFlag == null) {
|
||||
AsyncCommandBuilder.wrap(new FlagListBuilder(flagRegistry, permModel, existing, world,
|
||||
regionId, sender, flagName), sender)
|
||||
id, sender, flagName), sender)
|
||||
.registerWithSupervisor(WorldGuard.getInstance().getSupervisor(), "Flag list for invalid flag command.")
|
||||
.onSuccess((Component) null, sender::print)
|
||||
.onFailure((Component) null, WorldGuard.getInstance().getExceptionConverter())
|
||||
@@ -585,7 +581,8 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
}
|
||||
|
||||
if (!args.hasFlag('h')) {
|
||||
sender.print("Region flag " + foundFlag.getName() + " set on '" + regionId + "' to '" + value + "'.");
|
||||
String friendlyName = id.getDisplayName(sender);
|
||||
sender.print("Region flag " + foundFlag.getName() + " set on '" + friendlyName + "' to '" + value + "'.");
|
||||
}
|
||||
|
||||
// No value? Clear the flag, if -g isn't specified
|
||||
@@ -600,7 +597,8 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
}
|
||||
|
||||
if (!args.hasFlag('h')) {
|
||||
sender.print("Region flag " + foundFlag.getName() + " removed from '" + regionId + "'. (Any -g(roups) were also removed.)");
|
||||
String friendlyName = id.getDisplayName(sender);
|
||||
sender.print("Region flag " + foundFlag.getName() + " removed from '" + friendlyName + "'. (Any -g(roups) were also removed.)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -628,7 +626,6 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
printout.appendFlagsList(false);
|
||||
printout.append(SubtleFormat.wrap(")"));
|
||||
printout.send(sender);
|
||||
checkSpawnOverlap(sender, world, existing);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -637,7 +634,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
flags = "p:w:",
|
||||
desc = "View region flags",
|
||||
min = 0, max = 2)
|
||||
public void flagHelper(CommandContext args, Actor sender) throws CommandException {
|
||||
public void flagHelper(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
|
||||
World world = checkWorld(args, sender, 'w'); // Get the world
|
||||
|
||||
// Lookup the existing region
|
||||
@@ -651,7 +648,8 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
region = checkRegionStandingIn(manager, (LocalPlayer) sender, true,
|
||||
"/rg flags -w \"" + world.getName() + "\" %id%");
|
||||
} else { // Get region from the ID
|
||||
region = checkExistingRegion(manager, args.getString(0), true);
|
||||
RegionIdentifier id = processRegionId(sender, args.getString(0), true);
|
||||
region = checkExistingRegion(sender, manager, id);
|
||||
}
|
||||
|
||||
final RegionPermissionModel perms = getPermissionModel(sender);
|
||||
@@ -669,12 +667,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());
|
||||
@@ -692,7 +685,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
flags = "w:",
|
||||
desc = "Set the priority of a region",
|
||||
min = 2, max = 2)
|
||||
public void setPriority(CommandContext args, Actor sender) throws CommandException {
|
||||
public void setPriority(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
|
||||
warnAboutSaveFailures(sender);
|
||||
|
||||
World world = checkWorld(args, sender, 'w'); // Get the world
|
||||
@@ -700,7 +693,8 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
|
||||
// Lookup the existing region
|
||||
RegionManager manager = checkRegionManager(world);
|
||||
ProtectedRegion existing = checkExistingRegion(manager, args.getString(0), false);
|
||||
RegionIdentifier id = processRegionId(sender, args.getString(0), false);
|
||||
ProtectedRegion existing = checkExistingRegion(sender, manager, id);
|
||||
|
||||
// Check permissions
|
||||
if (!getPermissionModel(sender).maySetPriority(existing)) {
|
||||
@@ -709,8 +703,8 @@ 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);
|
||||
String friendlyName = id.getDisplayName(sender);
|
||||
sender.print("Priority of '" + friendlyName + "' set to " + priority + " (higher numbers override).");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -725,7 +719,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
flags = "w:",
|
||||
desc = "Set the parent of a region",
|
||||
min = 1, max = 2)
|
||||
public void setParent(CommandContext args, Actor sender) throws CommandException {
|
||||
public void setParent(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
|
||||
warnAboutSaveFailures(sender);
|
||||
|
||||
World world = checkWorld(args, sender, 'w'); // Get the world
|
||||
@@ -736,9 +730,11 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
RegionManager manager = checkRegionManager(world);
|
||||
|
||||
// Get parent and child
|
||||
child = checkExistingRegion(manager, args.getString(0), false);
|
||||
RegionIdentifier childId = processRegionId(sender, args.getString(0), false);
|
||||
child = checkExistingRegion(sender, manager, childId);
|
||||
if (args.argsLength() == 2) {
|
||||
parent = checkExistingRegion(manager, args.getString(1), false);
|
||||
RegionIdentifier parentId = processRegionId(sender, args.getString(1), false);
|
||||
parent = checkExistingRegion(sender, manager, parentId);
|
||||
} else {
|
||||
parent = null;
|
||||
}
|
||||
@@ -752,11 +748,15 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
child.setParent(parent);
|
||||
} catch (CircularInheritanceException e) {
|
||||
// Tell the user what's wrong
|
||||
RegionPrintoutBuilder printout = new RegionPrintoutBuilder(world.getName(), parent, null, sender);
|
||||
assert parent != null;
|
||||
printout.append(ErrorFormat.wrap("Uh oh! Setting '", parent.getId(), "' to be the parent of '", child.getId(),
|
||||
|
||||
String parentFriendlyName = parent.getIdentifier().getDisplayName(sender);
|
||||
String childFriendlyName = childId.getDisplayName(sender);
|
||||
|
||||
RegionPrintoutBuilder printout = new RegionPrintoutBuilder(world.getName(), parent, null, sender);
|
||||
printout.append(ErrorFormat.wrap("Uh oh! Setting '", parentFriendlyName, "' to be the parent of '", childFriendlyName,
|
||||
"' would cause circular inheritance.")).newline();
|
||||
printout.append(SubtleFormat.wrap("(Current inheritance on '", parent.getId(), "':")).newline();
|
||||
printout.append(SubtleFormat.wrap("(Current inheritance on '", parentFriendlyName, "':")).newline();
|
||||
printout.appendParentTree(true);
|
||||
printout.append(SubtleFormat.wrap(")"));
|
||||
printout.send(sender);
|
||||
@@ -764,8 +764,9 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
}
|
||||
|
||||
// Tell the user the current inheritance
|
||||
String childFriendlyName = childId.getDisplayName(sender);
|
||||
RegionPrintoutBuilder printout = new RegionPrintoutBuilder(world.getName(), child, null, sender);
|
||||
printout.append(TextComponent.of("Inheritance set for region '" + child.getId() + "'.", TextColor.LIGHT_PURPLE));
|
||||
printout.append(TextComponent.of("Inheritance set for region '" + childFriendlyName + "'.", TextColor.LIGHT_PURPLE));
|
||||
if (parent != null) {
|
||||
printout.newline();
|
||||
printout.append(SubtleFormat.wrap("(Current inheritance:")).newline();
|
||||
@@ -789,7 +790,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
flags = "fuw:",
|
||||
desc = "Remove a region",
|
||||
min = 1, max = 1)
|
||||
public void remove(CommandContext args, Actor sender) throws CommandException {
|
||||
public void remove(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
|
||||
warnAboutSaveFailures(sender);
|
||||
|
||||
World world = checkWorld(args, sender, 'w'); // Get the world
|
||||
@@ -798,7 +799,8 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
|
||||
// Lookup the existing region
|
||||
RegionManager manager = checkRegionManager(world);
|
||||
ProtectedRegion existing = checkExistingRegion(manager, args.getString(0), true);
|
||||
RegionIdentifier id = processRegionId(sender, args.getString(0), true);
|
||||
ProtectedRegion existing = checkExistingRegion(sender, manager, id);
|
||||
|
||||
// Check permissions
|
||||
if (!getPermissionModel(sender).mayDelete(existing)) {
|
||||
@@ -815,12 +817,15 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
task.setRemovalStrategy(RemovalStrategy.UNSET_PARENT_IN_CHILDREN);
|
||||
}
|
||||
|
||||
final String description = String.format("Removing region '%s' in '%s'", existing.getId(), world.getName());
|
||||
String friendlyName = id.getDisplayName(sender);
|
||||
final String description = String.format("Removing region '%s' in '%s'", friendlyName, world.getName());
|
||||
AsyncCommandBuilder.wrap(task, sender)
|
||||
.registerWithSupervisor(WorldGuard.getInstance().getSupervisor(), description)
|
||||
.sendMessageAfterDelay("Please wait... removing region.")
|
||||
.onSuccess((Component) null, removed -> sender.print(TextComponent.of(
|
||||
"Successfully removed " + removed.stream().map(ProtectedRegion::getId).collect(Collectors.joining(", ")) + ".",
|
||||
"Successfully removed " + removed.stream()
|
||||
.map((r) -> r.getIdentifier().getDisplayName(sender))
|
||||
.collect(Collectors.joining(", ")) + ".",
|
||||
TextColor.LIGHT_PURPLE)))
|
||||
.onFailure("Failed to remove region", WorldGuard.getInstance().getExceptionConverter())
|
||||
.buildAndExec(WorldGuard.getInstance().getExecutorService());
|
||||
@@ -855,10 +860,6 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
if (world != null) {
|
||||
RegionManager manager = checkRegionManager(world);
|
||||
|
||||
if (manager == null) {
|
||||
throw new CommandException("No region manager exists for world '" + world.getName() + "'.");
|
||||
}
|
||||
|
||||
final String description = String.format("Loading region data for '%s'.", world.getName());
|
||||
AsyncCommandBuilder.wrap(new RegionManagerLoader(manager), sender)
|
||||
.registerWithSupervisor(worldGuard.getSupervisor(), description)
|
||||
@@ -915,10 +916,6 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
if (world != null) {
|
||||
RegionManager manager = checkRegionManager(world);
|
||||
|
||||
if (manager == null) {
|
||||
throw new CommandException("No region manager exists for world '" + world.getName() + "'.");
|
||||
}
|
||||
|
||||
final String description = String.format("Saving region data for '%s'.", world.getName());
|
||||
AsyncCommandBuilder.wrap(new RegionManagerSaver(manager), sender)
|
||||
.registerWithSupervisor(worldGuard.getSupervisor(), description)
|
||||
@@ -1081,14 +1078,15 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
flags = "sw:",
|
||||
desc = "Teleports you to the location associated with the region.",
|
||||
min = 1, max = 1)
|
||||
public void teleport(CommandContext args, Actor sender) throws CommandException {
|
||||
public void teleport(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
|
||||
LocalPlayer player = worldGuard.checkPlayer(sender);
|
||||
Location teleportLocation;
|
||||
|
||||
// Lookup the existing region
|
||||
World world = checkWorld(args, player, 'w');
|
||||
RegionManager regionManager = checkRegionManager(world);
|
||||
ProtectedRegion existing = checkExistingRegion(regionManager, args.getString(0), true);
|
||||
RegionIdentifier id = processRegionId(sender, args.getString(0), true);
|
||||
ProtectedRegion existing = checkExistingRegion(sender, regionManager, id);
|
||||
|
||||
// Check permissions
|
||||
if (!getPermissionModel(player).mayTeleportTo(existing)) {
|
||||
@@ -1111,17 +1109,10 @@ 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();
|
||||
}
|
||||
|
||||
String friendlyName = id.getDisplayName(sender);
|
||||
player.teleport(teleportLocation,
|
||||
message.replace("%id%", existing.getId()),
|
||||
"Unable to teleport to region '" + existing.getId() + "'.");
|
||||
"Teleported you to the region '" + friendlyName + "'.",
|
||||
"Unable to teleport to region '" + friendlyName + "'.");
|
||||
}
|
||||
|
||||
@Command(aliases = {"toggle-bypass", "bypass"},
|
||||
@@ -1144,12 +1135,12 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
private final RegionPermissionModel permModel;
|
||||
private final ProtectedRegion existing;
|
||||
private final World world;
|
||||
private final String regionId;
|
||||
private final RegionIdentifier regionId;
|
||||
private final Actor sender;
|
||||
private final String flagName;
|
||||
|
||||
FlagListBuilder(FlagRegistry flagRegistry, RegionPermissionModel permModel, ProtectedRegion existing,
|
||||
World world, String regionId, Actor sender, String flagName) {
|
||||
World world, RegionIdentifier regionId, Actor sender, String flagName) {
|
||||
this.flagRegistry = flagRegistry;
|
||||
this.permModel = permModel;
|
||||
this.existing = existing;
|
||||
@@ -1181,9 +1172,10 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
for (int i = 0; i < flagList.size(); i++) {
|
||||
String flag = flagList.get(i);
|
||||
|
||||
String qualifiedName = regionId.getQualifiedName();
|
||||
builder.append(TextComponent.of(flag, i % 2 == 0 ? TextColor.GRAY : TextColor.WHITE)
|
||||
.hoverEvent(clickToSet).clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND,
|
||||
"/rg flag -w \"" + world.getName() + "\" " + regionId + " " + flag + " ")));
|
||||
"/rg flag -w \"" + world.getName() + "\" " + qualifiedName + " " + flag + " ")));
|
||||
if (i < flagList.size() + 1) {
|
||||
builder.append(TextComponent.of(", "));
|
||||
}
|
||||
@@ -1193,10 +1185,12 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
.append(TextComponent.newline())
|
||||
.append(builder.build());
|
||||
if (sender.isPlayer()) {
|
||||
String friendlyName = regionId.getDisplayName(sender);
|
||||
String qualifiedName = regionId.getQualifiedName();
|
||||
return ret.append(TextComponent.of("Or use the command ", TextColor.LIGHT_PURPLE)
|
||||
.append(TextComponent.of("/rg flags " + regionId, TextColor.AQUA)
|
||||
.append(TextComponent.of("/rg flags " + friendlyName, TextColor.AQUA)
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
|
||||
"/rg flags -w \"" + world.getName() + "\" " + regionId))));
|
||||
"/rg flags -w \"" + world.getName() + "\" " + qualifiedName))));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
+265
-66
@@ -33,13 +33,13 @@ import com.sk89q.worldedit.regions.Polygonal2DRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.Polygonal2DRegionSelector;
|
||||
import com.sk89q.worldedit.util.auth.AuthorizationException;
|
||||
import com.sk89q.worldedit.util.formatting.component.ErrorFormat;
|
||||
import com.sk89q.worldedit.util.formatting.component.SubtleFormat;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextDecoration;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
@@ -49,13 +49,13 @@ import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.FlagContext;
|
||||
import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.RegionContainer;
|
||||
import com.sk89q.worldguard.protection.regions.*;
|
||||
import com.sk89q.worldguard.util.profile.Profile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
class RegionCommandsBase {
|
||||
@@ -77,32 +77,16 @@ class RegionCommandsBase {
|
||||
* Gets the world from the given flag, or falling back to the the current player
|
||||
* if the sender is a player, otherwise reporting an error.
|
||||
*
|
||||
* @param args the arguments
|
||||
* @param args the arguments
|
||||
* @param sender the sender
|
||||
* @param flag the flag (such as 'w')
|
||||
* @param flag the flag (such as 'w')
|
||||
* @return a world
|
||||
* @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 {
|
||||
@@ -111,28 +95,190 @@ class RegionCommandsBase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a region name.
|
||||
*
|
||||
* @param name the name
|
||||
* @param allowGlobal whether __global__ is allowed
|
||||
* @throws CommandException thrown on an error
|
||||
*/
|
||||
protected static void checkName(String name, boolean allowGlobal) throws CommandException {
|
||||
if (!RegionIdentifier.isValidName(name)) {
|
||||
throw new CommandException(
|
||||
"The region name of '" + name + "' contains characters that are not allowed.");
|
||||
}
|
||||
|
||||
if (!allowGlobal && name.equalsIgnoreCase("__global__")) { // Sorry, no global
|
||||
throw new CommandException(
|
||||
"Sorry, you can't use __global__ here.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a region ID.
|
||||
*
|
||||
* @param id the id
|
||||
* @param id the id
|
||||
* @param allowGlobal whether __global__ is allowed
|
||||
* @return the id given
|
||||
* @throws CommandException thrown on an error
|
||||
*/
|
||||
@Deprecated
|
||||
protected static String checkRegionId(String id, boolean allowGlobal) throws CommandException {
|
||||
if (!ProtectedRegion.isValidId(id)) {
|
||||
throw new CommandException(
|
||||
"The region name of '" + id + "' contains characters that are not allowed.");
|
||||
}
|
||||
|
||||
if (!allowGlobal && id.equalsIgnoreCase("__global__")) { // Sorry, no global
|
||||
throw new CommandException(
|
||||
"Sorry, you can't use __global__ here.");
|
||||
}
|
||||
|
||||
checkName(id, allowGlobal);
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a region namespace.
|
||||
*
|
||||
* @param namespace the namespace name
|
||||
* @throws CommandException thrown on an error
|
||||
*/
|
||||
protected static void checkNamespace(String namespace) throws CommandException {
|
||||
if (!RegionIdentifier.isValidNamespace(namespace)) {
|
||||
throw new CommandException(
|
||||
"The region namespace of '" + namespace + "' contains characters that are not allowed.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unqualified name from a possibly qualified region identifier.
|
||||
*
|
||||
* @param id the unprocessed region identifier
|
||||
* @return the unqualified name, or an empty string if not present
|
||||
*/
|
||||
protected static String getUnqualifiedName(String id) {
|
||||
int namespaceSeparatorIndex = id.lastIndexOf(':');
|
||||
if (namespaceSeparatorIndex == -1) {
|
||||
return id;
|
||||
}
|
||||
|
||||
int unqualifiedNameStartIndex = namespaceSeparatorIndex + 1;
|
||||
if (unqualifiedNameStartIndex == id.length()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return id.substring(unqualifiedNameStartIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the namespace name from a possibly qualified region identifier.
|
||||
*
|
||||
* @param id the unprocessed region identifier
|
||||
* @return an optional containing the namespace name, or an empty string if qualified,
|
||||
* if not qualified, an empty optional is returned
|
||||
*/
|
||||
protected static Optional<String> getNamespace(String id) {
|
||||
int namespaceSeparatorIndex = id.lastIndexOf(':');
|
||||
if (namespaceSeparatorIndex == -1) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(id.substring(0, namespaceSeparatorIndex));
|
||||
}
|
||||
|
||||
private static class InvalidMacroException extends RuntimeException {
|
||||
public InvalidMacroException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* Expand macros in the namespace name.
|
||||
*
|
||||
* @param namespace the unexpanded namespace name
|
||||
* @return the expanded namespace name
|
||||
*/
|
||||
protected static String expandNamespace(String namespace) {
|
||||
if (namespace.startsWith("#")) {
|
||||
String playerName = namespace.substring(1);
|
||||
|
||||
try {
|
||||
Profile profile = WorldGuard.getInstance().getProfileService().findByName(playerName);
|
||||
if (profile != null) {
|
||||
return profile.getUniqueId().toString();
|
||||
}
|
||||
} catch (InterruptedException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
throw new InvalidMacroException("Macro unresolvable: " + namespace);
|
||||
}
|
||||
|
||||
return namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the macro expanded namespace name from a possibly qualified region identifier.
|
||||
*
|
||||
* @param id the unprocessed region identifier
|
||||
* @return an optional containing the expanded namespace name, or an empty string if qualified,
|
||||
* if not qualified, an empty optional is returned
|
||||
*/
|
||||
protected static Optional<String> getExpandedNamespace(String id) throws CommandException {
|
||||
try {
|
||||
return getNamespace(id).map(RegionCommandsBase::expandNamespace);
|
||||
} catch (InvalidMacroException ex) {
|
||||
throw new CommandException(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default namespace for a given actor.
|
||||
*
|
||||
* @param sender the sender who's default namespace we intend to retrieve.
|
||||
* @return the default namespace
|
||||
*/
|
||||
protected static String getDefaultNamespace(Actor sender) {
|
||||
if (sender instanceof LocalPlayer) {
|
||||
return ((LocalPlayer) sender).getDefaultNamespace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a possibly qualified region identifier into a RegionIdentifier.
|
||||
*
|
||||
* This method takes a possibly qualified region identifier, and processes it, expanding any namespace macros,
|
||||
* running permissions checks, and validating the names for invalid character.
|
||||
*
|
||||
* @param sender the contextual sender to use for checks and macro expansions
|
||||
* @param id the possibly unqualified id
|
||||
* @param allowGlobal whether or not this method should allow use of the name __global__ name
|
||||
* @return the processed region id
|
||||
* @throws AuthorizationException if a permission check fails
|
||||
* @throws CommandException if a name validation check fails
|
||||
*/
|
||||
protected static RegionIdentifier processRegionId(Actor sender, String id, boolean allowGlobal) throws AuthorizationException, CommandException {
|
||||
String unqualifiedName = getUnqualifiedName(id);
|
||||
checkName(unqualifiedName, allowGlobal);
|
||||
|
||||
Optional<String> optProvidedNamespace = getExpandedNamespace(id);
|
||||
String namespace = optProvidedNamespace.orElse(getDefaultNamespace(sender));
|
||||
|
||||
// TODO use more informative permission checks
|
||||
|
||||
// This needs checked as a special case, before namespace name validation.
|
||||
if (namespace.equals("")) {
|
||||
sender.checkPermission("worldguard.region.namespace.global");
|
||||
return new RegionIdentifier(null, unqualifiedName);
|
||||
}
|
||||
|
||||
checkNamespace(namespace);
|
||||
|
||||
try {
|
||||
UUID namespacePlayerId = UUID.fromString(namespace);
|
||||
if (!namespacePlayerId.equals(sender.getUniqueId())) {
|
||||
sender.checkPermission("worldguard.region.namespace.player");
|
||||
}
|
||||
} catch (IllegalArgumentException ex) {
|
||||
sender.checkPermission("worldguard.region.namespace.custom." + namespace);
|
||||
}
|
||||
|
||||
return new RegionIdentifier(namespace, unqualifiedName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a protected region by a given name, otherwise throw a
|
||||
* {@link CommandException}.
|
||||
@@ -144,6 +290,7 @@ class RegionCommandsBase {
|
||||
* @param allowGlobal true to allow selecting __global__
|
||||
* @throws CommandException thrown if no region is found by the given name
|
||||
*/
|
||||
@Deprecated
|
||||
protected static ProtectedRegion checkExistingRegion(RegionManager regionManager, String id, boolean allowGlobal) throws CommandException {
|
||||
// Validate the id
|
||||
checkRegionId(id, allowGlobal);
|
||||
@@ -166,6 +313,36 @@ class RegionCommandsBase {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a protected region by a given name, otherwise throw a
|
||||
* {@link CommandException}.
|
||||
*
|
||||
* <p>This also validates the region ID.</p>
|
||||
*
|
||||
* @param actor the associated player
|
||||
* @param regionManager the region manager
|
||||
* @param id the name to search
|
||||
* @throws CommandException thrown if no region is found by the given name
|
||||
*/
|
||||
protected static ProtectedRegion checkExistingRegion(Actor actor, RegionManager regionManager, RegionIdentifier id) throws CommandException {
|
||||
ProtectedRegion region = regionManager.getRegion(id);
|
||||
|
||||
// No region found!
|
||||
if (region == null) {
|
||||
// But we want a __global__, so let's create one
|
||||
if (id.getQualifiedName().equals(":__global__")) {
|
||||
region = new GlobalProtectedRegion(id);
|
||||
regionManager.addRegion(region);
|
||||
return region;
|
||||
}
|
||||
|
||||
throw new CommandException(
|
||||
"No region could be found with the name of '" + id.getDisplayName(actor) + "'.");
|
||||
}
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the region at the player's location, if possible.
|
||||
@@ -220,10 +397,12 @@ class RegionCommandsBase {
|
||||
builder.append(TextComponent.of(", "));
|
||||
}
|
||||
first = false;
|
||||
TextComponent regionComp = TextComponent.of(region.getId(), TextColor.AQUA);
|
||||
|
||||
RegionIdentifier id = region.getIdentifier();
|
||||
TextComponent regionComp = TextComponent.of(id.getDisplayName(player), TextColor.AQUA);
|
||||
if (rgCmd != null && rgCmd.contains("%id%")) {
|
||||
regionComp = regionComp.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to pick this region")))
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, rgCmd.replace("%id%", region.getId())));
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, rgCmd.replace("%id%", id.getQualifiedName())));
|
||||
}
|
||||
builder.append(regionComp);
|
||||
}
|
||||
@@ -235,17 +414,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. " +
|
||||
@@ -261,10 +439,23 @@ class RegionCommandsBase {
|
||||
* @param id the ID
|
||||
* @throws CommandException thrown if the ID already exists
|
||||
*/
|
||||
@Deprecated
|
||||
protected static void checkRegionDoesNotExist(RegionManager manager, String id, boolean mayRedefine) throws CommandException {
|
||||
checkRegionDoesNotExist(null, manager, new RegionIdentifier(id), mayRedefine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a region with the given ID does not already exist.
|
||||
*
|
||||
* @param actor the associated player
|
||||
* @param manager the manager
|
||||
* @param id the identifier
|
||||
* @throws CommandException thrown if the ID already exists
|
||||
*/
|
||||
protected static void checkRegionDoesNotExist(Actor actor, RegionManager manager, RegionIdentifier id, boolean mayRedefine) throws CommandException {
|
||||
if (manager.hasRegion(id)) {
|
||||
throw new CommandException("A region with that name already exists. Please choose another name." +
|
||||
(mayRedefine ? " To change the shape, use /region redefine " + id + "." : ""));
|
||||
(mayRedefine ? " To change the shape, use /region redefine " + id.getDisplayName(actor) + "." : ""));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,15 +481,28 @@ 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);
|
||||
@Deprecated
|
||||
protected static ProtectedRegion checkRegionFromSelection(LocalPlayer player, String id) throws CommandException {
|
||||
return checkRegionFromSelection(player, new RegionIdentifier(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link ProtectedRegion} from the player's selection.
|
||||
*
|
||||
* @param player the player
|
||||
* @param id the identifier of the new region
|
||||
* @return a new region
|
||||
* @throws CommandException thrown on an error
|
||||
*/
|
||||
protected static ProtectedRegion checkRegionFromSelection(LocalPlayer player, RegionIdentifier id) throws CommandException {
|
||||
Region selection = checkSelection(player);
|
||||
|
||||
// Detect the type of region from WorldEdit
|
||||
if (selection instanceof Polygonal2DRegion) {
|
||||
@@ -340,9 +544,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 +572,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 +599,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(
|
||||
|
||||
+10
-20
@@ -19,7 +19,7 @@
|
||||
|
||||
package com.sk89q.worldguard.commands.region;
|
||||
|
||||
import com.sk89q.worldguard.protection.flags.registry.UnknownFlag;
|
||||
import com.sk89q.worldguard.protection.regions.RegionIdentifier;
|
||||
import com.sk89q.worldguard.util.profile.cache.ProfileCache;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
@@ -59,6 +59,7 @@ public class RegionPrintoutBuilder implements Callable<TextComponent> {
|
||||
@Nullable
|
||||
private final ProfileCache cache;
|
||||
private final TextComponentProducer builder = new TextComponentProducer();
|
||||
private final Actor actor;
|
||||
private final RegionPermissionModel perms;
|
||||
|
||||
/**
|
||||
@@ -71,6 +72,7 @@ public class RegionPrintoutBuilder implements Callable<TextComponent> {
|
||||
this.world = world;
|
||||
this.region = region;
|
||||
this.cache = cache;
|
||||
this.actor = actor;
|
||||
this.perms = actor != null && actor.isPlayer() ? new RegionPermissionModel(actor) : null;
|
||||
}
|
||||
|
||||
@@ -86,8 +88,10 @@ public class RegionPrintoutBuilder implements Callable<TextComponent> {
|
||||
*/
|
||||
public void appendBasics() {
|
||||
builder.append(TextComponent.of("Region: ", TextColor.BLUE));
|
||||
builder.append(TextComponent.of(region.getId(), TextColor.YELLOW)
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "/rg info -w \"" + world + "\" " + region.getId())));
|
||||
|
||||
RegionIdentifier id = region.getIdentifier();
|
||||
builder.append(TextComponent.of(id.getDisplayName(actor), TextColor.YELLOW)
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "/rg info -w \"" + world + "\" " + id.getQualifiedName())));
|
||||
|
||||
builder.append(TextComponent.of(" (type=", TextColor.GRAY));
|
||||
builder.append(TextComponent.of(region.getType().getName()));
|
||||
@@ -144,22 +148,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 +310,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,
|
||||
|
||||
@@ -76,6 +76,7 @@ public abstract class ConfigurationManager {
|
||||
public boolean migrateRegionsToUuid;
|
||||
public boolean keepUnresolvedNames;
|
||||
public boolean particleEffects;
|
||||
public boolean useNamespaces;
|
||||
|
||||
@Unreported public Map<String, String> hostKeys = new HashMap<>();
|
||||
public boolean hostKeysAllowFMLClients;
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
+1
@@ -63,6 +63,7 @@ public abstract class YamlConfigurationManager extends ConfigurationManager {
|
||||
usePlayerMove = config.getBoolean("use-player-move-event", true);
|
||||
usePlayerTeleports = config.getBoolean("use-player-teleports", true);
|
||||
particleEffects = config.getBoolean("use-particle-effects", true);
|
||||
useNamespaces = config.getBoolean("use-namespaces", true);
|
||||
|
||||
deopOnJoin = config.getBoolean("security.deop-everyone-on-join", false);
|
||||
blockInGameOp = config.getBoolean("security.block-in-game-op-command", false);
|
||||
|
||||
@@ -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(", "));
|
||||
}
|
||||
|
||||
+1
@@ -26,6 +26,7 @@ import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.RegionIdentifier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
||||
+1
-2
@@ -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;
|
||||
}
|
||||
|
||||
+26
@@ -34,6 +34,7 @@ import com.sk89q.worldguard.protection.managers.storage.DifferenceSaveException;
|
||||
import com.sk89q.worldguard.protection.managers.storage.RegionDatabase;
|
||||
import com.sk89q.worldguard.protection.managers.storage.StorageException;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.RegionIdentifier;
|
||||
import com.sk89q.worldguard.protection.util.RegionCollectionConsumer;
|
||||
import com.sk89q.worldguard.util.Normal;
|
||||
|
||||
@@ -242,10 +243,22 @@ public final class RegionManager {
|
||||
* @param id the name of the region
|
||||
* @return true if this index contains the region
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean hasRegion(String id) {
|
||||
return index.contains(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the index contains a region with the given identifier,
|
||||
* with quality determined by {@link Normal}.
|
||||
*
|
||||
* @param id the region identifier
|
||||
* @return true if this index contains the region
|
||||
*/
|
||||
public boolean hasRegion(RegionIdentifier id) {
|
||||
return index.contains(id.getLegacyQualifiedName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region named by the given name (equality determined using
|
||||
* {@link Normal}).
|
||||
@@ -254,11 +267,24 @@ public final class RegionManager {
|
||||
* @return a region or {@code null}
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated
|
||||
public ProtectedRegion getRegion(String id) {
|
||||
checkNotNull(id);
|
||||
return index.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region named y the given id.
|
||||
*
|
||||
* @param id the region identifier
|
||||
* @return a region or {@code null}
|
||||
*/
|
||||
@Nullable
|
||||
public ProtectedRegion getRegion(RegionIdentifier id) {
|
||||
checkNotNull(id);
|
||||
return index.get(id.getLegacyQualifiedName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use exact ids with {@link #getRegion}
|
||||
*/
|
||||
|
||||
+3
-2
@@ -70,12 +70,13 @@ public class HashMapIndex extends AbstractRegionIndex implements ConcurrentRegio
|
||||
region.setDirty(true);
|
||||
|
||||
synchronized (lock) {
|
||||
String normalId = normalize(region.getId());
|
||||
String newFullId = region.getIdentifier().getLegacyQualifiedName();
|
||||
String normalId = normalize(newFullId);
|
||||
|
||||
ProtectedRegion existing = regions.get(normalId);
|
||||
|
||||
// Casing / form of ID has changed
|
||||
if (existing != null && !existing.getId().equals(region.getId())) {
|
||||
if (existing != null && !existing.getIdentifier().getLegacyQualifiedName().equals(newFullId)) {
|
||||
removed.add(existing);
|
||||
}
|
||||
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* WorldGuard, a suite of tools for Minecraft
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldGuard team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.protection.managers.storage.file;
|
||||
|
||||
import com.sk89q.util.yaml.YAMLNode;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
class DomainParser {
|
||||
public static class One {
|
||||
public static DefaultDomain parseDomain(YAMLNode node) {
|
||||
if (node == null) {
|
||||
return new DefaultDomain();
|
||||
}
|
||||
|
||||
DefaultDomain domain = new DefaultDomain();
|
||||
|
||||
for (String name : node.getStringList("players", null)) {
|
||||
if (!name.isEmpty()) {
|
||||
domain.addPlayer(name);
|
||||
}
|
||||
}
|
||||
|
||||
for (String stringId : node.getStringList("unique-ids", null)) {
|
||||
try {
|
||||
domain.addPlayer(UUID.fromString(stringId));
|
||||
} catch (IllegalArgumentException e) {
|
||||
YamlCommon.log.log(Level.WARNING, "Failed to parse UUID '" + stringId + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
for (String name : node.getStringList("groups", null)) {
|
||||
if (!name.isEmpty()) {
|
||||
domain.addGroup(name);
|
||||
}
|
||||
}
|
||||
|
||||
return domain;
|
||||
}
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.protection.managers.storage.file;
|
||||
|
||||
import com.sk89q.util.yaml.YAMLNode;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
class FlagParser {
|
||||
public static class One {
|
||||
public static void setFlags(FlagRegistry flagRegistry, ProtectedRegion region, YAMLNode flagsData) {
|
||||
if (flagsData != null) {
|
||||
region.setFlags(flagRegistry.unmarshal(flagsData.getMap(), true));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.protection.managers.storage.file;
|
||||
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
class YamlCommon {
|
||||
public static final Logger log = Logger.getLogger(YamlRegionFile.class.getCanonicalName());
|
||||
public static final Yaml ERROR_DUMP_YAML;
|
||||
|
||||
static {
|
||||
DumperOptions options = new DumperOptions();
|
||||
options.setIndent(4);
|
||||
options.setDefaultFlowStyle(DumperOptions.FlowStyle.AUTO);
|
||||
|
||||
ERROR_DUMP_YAML = new Yaml(new SafeConstructor(), new Representer(), options);
|
||||
}
|
||||
|
||||
public static final String YAML_GLOBAL_NAMESPACE_NAME = "__global_ns__";
|
||||
|
||||
private YamlCommon() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump the given object as YAML for debugging purposes.
|
||||
*
|
||||
* @param object the object
|
||||
* @return the YAML string or an error string if dumping fals
|
||||
*/
|
||||
public static String toYamlOutput(Object object) {
|
||||
try {
|
||||
return ERROR_DUMP_YAML.dump(object).replaceAll("(?m)^", "\t");
|
||||
} catch (Throwable t) {
|
||||
return "<error while dumping object>";
|
||||
}
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.protection.managers.storage.file;
|
||||
|
||||
import com.sk89q.util.yaml.YAMLProcessor;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
interface YamlReader {
|
||||
public int getVersion();
|
||||
default public boolean canLoad(YAMLProcessor config) {
|
||||
return config.getInt("version", 1) == getVersion();
|
||||
}
|
||||
public Set<ProtectedRegion> load(FlagRegistry flagRegistry, YAMLProcessor config);
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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.protection.managers.storage.file;
|
||||
|
||||
import com.sk89q.util.yaml.YAMLNode;
|
||||
import com.sk89q.util.yaml.YAMLProcessor;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.managers.storage.RegionDatabaseUtils;
|
||||
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.sk89q.worldguard.protection.managers.storage.file.YamlCommon.log;
|
||||
import static com.sk89q.worldguard.protection.managers.storage.file.YamlCommon.toYamlOutput;
|
||||
|
||||
class YamlReaderVersionOne implements YamlReader {
|
||||
@Override
|
||||
public int getVersion() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ProtectedRegion> load(FlagRegistry flagRegistry, YAMLProcessor config) {
|
||||
Map<String, ProtectedRegion> loaded = new HashMap<>();
|
||||
Map<String, YAMLNode> regionData = config.getNodes("regions");
|
||||
|
||||
if (regionData == null) {
|
||||
return Collections.emptySet(); // No regions are even configured
|
||||
}
|
||||
|
||||
Map<ProtectedRegion, String> parentSets = new LinkedHashMap<>();
|
||||
|
||||
for (Map.Entry<String, YAMLNode> entry : regionData.entrySet()) {
|
||||
String id = entry.getKey();
|
||||
YAMLNode node = entry.getValue();
|
||||
|
||||
String type = node.getString("type");
|
||||
ProtectedRegion region;
|
||||
|
||||
try {
|
||||
if (type == null) {
|
||||
log.warning("Undefined region type for region '" + id + "'!\n" +
|
||||
"Here is what the region data looks like:\n\n" + toYamlOutput(entry.getValue().getMap()) + "\n");
|
||||
continue;
|
||||
} else if (type.equals("cuboid")) {
|
||||
Vector3 pt1 = checkNotNull(node.getVector("min"));
|
||||
Vector3 pt2 = checkNotNull(node.getVector("max"));
|
||||
BlockVector3 min = pt1.getMinimum(pt2).toBlockPoint();
|
||||
BlockVector3 max = pt1.getMaximum(pt2).toBlockPoint();
|
||||
region = new ProtectedCuboidRegion(id, min, max);
|
||||
} else if (type.equals("poly2d")) {
|
||||
Integer minY = checkNotNull(node.getInt("min-y"));
|
||||
Integer maxY = checkNotNull(node.getInt("max-y"));
|
||||
List<BlockVector2> points = node.getBlockVector2List("points", null);
|
||||
region = new ProtectedPolygonalRegion(id, points, minY, maxY);
|
||||
} else if (type.equals("global")) {
|
||||
region = new GlobalProtectedRegion(id);
|
||||
} else {
|
||||
log.warning("Unknown region type for region '" + id + "'!\n" +
|
||||
"Here is what the region data looks like:\n\n" + toYamlOutput(entry.getValue().getMap()) + "\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
Integer priority = checkNotNull(node.getInt("priority"));
|
||||
region.setPriority(priority);
|
||||
FlagParser.One.setFlags(flagRegistry, region, node.getNode("flags"));
|
||||
region.setOwners(DomainParser.One.parseDomain(node.getNode("owners")));
|
||||
region.setMembers(DomainParser.One.parseDomain(node.getNode("members")));
|
||||
|
||||
loaded.put(id, region);
|
||||
|
||||
String parentId = node.getString("parent");
|
||||
if (parentId != null) {
|
||||
parentSets.put(region, parentId);
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
log.log(Level.WARNING,
|
||||
"Unexpected NullPointerException encountered during parsing for the region '" + id + "'!\n" +
|
||||
"Here is what the region data looks like:\n\n" + toYamlOutput(entry.getValue().getMap()) +
|
||||
"\n\nNote: This region will disappear as a result!", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Relink parents
|
||||
RegionDatabaseUtils.relinkParents(loaded, parentSets);
|
||||
|
||||
return new HashSet<>(loaded.values());
|
||||
}
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.protection.managers.storage.file;
|
||||
|
||||
import com.sk89q.util.yaml.YAMLNode;
|
||||
import com.sk89q.util.yaml.YAMLProcessor;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.managers.storage.RegionDatabaseUtils;
|
||||
import com.sk89q.worldguard.protection.regions.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.sk89q.worldguard.protection.managers.storage.file.YamlCommon.*;
|
||||
|
||||
class YamlReaderVersionTwo implements YamlReader {
|
||||
@Override
|
||||
public int getVersion() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ProtectedRegion> load(FlagRegistry flagRegistry, YAMLProcessor config) {
|
||||
Map<String, ProtectedRegion> loaded = new HashMap<>();
|
||||
Map<String, YAMLNode> regionData = config.getNodes("regions");
|
||||
|
||||
if (regionData == null) {
|
||||
return Collections.emptySet(); // No regions are even configured
|
||||
}
|
||||
|
||||
Map<ProtectedRegion, String> parentSets = new LinkedHashMap<>();
|
||||
|
||||
for (Map.Entry<String, YAMLNode> namespaceEntry : regionData.entrySet()) {
|
||||
String namespaceKey = namespaceEntry.getKey();
|
||||
|
||||
String namespace = namespaceKey;
|
||||
if (namespace.equals(YAML_GLOBAL_NAMESPACE_NAME)) {
|
||||
namespace = null;
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Object> entry : namespaceEntry.getValue().getMap().entrySet()) {
|
||||
String name = entry.getKey();
|
||||
YAMLNode node = config.getNode("regions." + namespaceKey + "." + name);
|
||||
|
||||
String type = node.getString("type");
|
||||
ProtectedRegion region;
|
||||
|
||||
RegionIdentifier id = new RegionIdentifier(namespace, name);
|
||||
try {
|
||||
if (type == null) {
|
||||
log.warning("Undefined region type for region '" + id + "'!\n" +
|
||||
"Here is what the region data looks like:\n\n" + toYamlOutput(node.getMap()) + "\n");
|
||||
continue;
|
||||
} else if (type.equals("cuboid")) {
|
||||
Vector3 pt1 = checkNotNull(node.getVector("min"));
|
||||
Vector3 pt2 = checkNotNull(node.getVector("max"));
|
||||
BlockVector3 min = pt1.getMinimum(pt2).toBlockPoint();
|
||||
BlockVector3 max = pt1.getMaximum(pt2).toBlockPoint();
|
||||
region = new ProtectedCuboidRegion(id, min, max);
|
||||
} else if (type.equals("poly2d")) {
|
||||
Integer minY = checkNotNull(node.getInt("min-y"));
|
||||
Integer maxY = checkNotNull(node.getInt("max-y"));
|
||||
List<BlockVector2> points = node.getBlockVector2List("points", null);
|
||||
region = new ProtectedPolygonalRegion(id, points, minY, maxY);
|
||||
} else if (type.equals("global")) {
|
||||
region = new GlobalProtectedRegion(id);
|
||||
} else {
|
||||
log.warning("Unknown region type for region '" + id + "'!\n" +
|
||||
"Here is what the region data looks like:\n\n" + toYamlOutput(node.getMap()) + "\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
Integer priority = checkNotNull(node.getInt("priority"));
|
||||
region.setPriority(priority);
|
||||
FlagParser.One.setFlags(flagRegistry, region, node.getNode("flags"));
|
||||
region.setOwners(DomainParser.One.parseDomain(node.getNode("owners")));
|
||||
region.setMembers(DomainParser.One.parseDomain(node.getNode("members")));
|
||||
|
||||
loaded.put(id.getLegacyQualifiedName(), region);
|
||||
|
||||
String parentQualifiedName = node.getString("parent");
|
||||
if (parentQualifiedName != null) {
|
||||
parentSets.put(region, parentQualifiedName);
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
log.log(Level.WARNING,
|
||||
"Unexpected NullPointerException encountered during parsing for the region '" + id + "'!\n" +
|
||||
"Here is what the region data looks like:\n\n" + toYamlOutput(node.getMap()) +
|
||||
"\n\nNote: This region will disappear as a result!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Relink parents
|
||||
RegionDatabaseUtils.relinkParents(loaded, parentSets);
|
||||
|
||||
return new HashSet<>(loaded.values());
|
||||
}
|
||||
}
|
||||
+36
-155
@@ -19,56 +19,32 @@
|
||||
|
||||
package com.sk89q.worldguard.protection.managers.storage.file;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.sk89q.util.yaml.YAMLFormat;
|
||||
import com.sk89q.util.yaml.YAMLNode;
|
||||
import com.sk89q.util.yaml.YAMLProcessor;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.protection.flags.FlagUtil;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.managers.RegionDifference;
|
||||
import com.sk89q.worldguard.protection.managers.storage.DifferenceSaveException;
|
||||
import com.sk89q.worldguard.protection.managers.storage.RegionDatabase;
|
||||
import com.sk89q.worldguard.protection.managers.storage.RegionDatabaseUtils;
|
||||
import com.sk89q.worldguard.protection.managers.storage.StorageException;
|
||||
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.DumperOptions.FlowStyle;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||
import com.sk89q.worldguard.protection.regions.*;
|
||||
import org.yaml.snakeyaml.parser.ParserException;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.*;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.sk89q.worldguard.protection.managers.storage.file.YamlCommon.YAML_GLOBAL_NAMESPACE_NAME;
|
||||
|
||||
/**
|
||||
* A store that persists regions in a YAML-encoded file.
|
||||
*/
|
||||
public class YamlRegionFile implements RegionDatabase {
|
||||
|
||||
private static final Logger log = Logger.getLogger(YamlRegionFile.class.getCanonicalName());
|
||||
private static final Yaml ERROR_DUMP_YAML;
|
||||
|
||||
private static final String FILE_HEADER = "#\r\n" +
|
||||
"# WorldGuard regions file\r\n" +
|
||||
"#\r\n" +
|
||||
@@ -81,17 +57,19 @@ public class YamlRegionFile implements RegionDatabase {
|
||||
"# REMEMBER TO KEEP PERIODICAL BACKUPS.\r\n" +
|
||||
"#";
|
||||
|
||||
private final String name;
|
||||
private final File file;
|
||||
private static final List<YamlReader> YAML_READERS = new ArrayList<>();
|
||||
|
||||
static {
|
||||
DumperOptions options = new DumperOptions();
|
||||
options.setIndent(4);
|
||||
options.setDefaultFlowStyle(FlowStyle.AUTO);
|
||||
|
||||
ERROR_DUMP_YAML = new Yaml(new SafeConstructor(), new Representer(), options);
|
||||
// IMPORTANT: For best performance, add these in reverse order.
|
||||
// We always want the latest version to be attempted first, so that once migrated, we are checking
|
||||
// one version, not n.
|
||||
YAML_READERS.add(new YamlReaderVersionTwo());
|
||||
YAML_READERS.add(new YamlReaderVersionOne());
|
||||
}
|
||||
|
||||
private final String name;
|
||||
private final File file;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
@@ -112,80 +90,22 @@ public class YamlRegionFile implements RegionDatabase {
|
||||
|
||||
@Override
|
||||
public Set<ProtectedRegion> loadAll(FlagRegistry flagRegistry) throws StorageException {
|
||||
Map<String, ProtectedRegion> loaded = new HashMap<>();
|
||||
|
||||
YAMLProcessor config = createYamlProcessor(file);
|
||||
try {
|
||||
config.load();
|
||||
} catch (FileNotFoundException e) {
|
||||
return new HashSet<>(loaded.values());
|
||||
return new HashSet<>();
|
||||
} catch (IOException | ParserException e) {
|
||||
throw new StorageException("Failed to load region data from '" + file + "'", e);
|
||||
}
|
||||
|
||||
Map<String, YAMLNode> regionData = config.getNodes("regions");
|
||||
|
||||
if (regionData == null) {
|
||||
return Collections.emptySet(); // No regions are even configured
|
||||
}
|
||||
|
||||
Map<ProtectedRegion, String> parentSets = new LinkedHashMap<>();
|
||||
|
||||
for (Map.Entry<String, YAMLNode> entry : regionData.entrySet()) {
|
||||
String id = entry.getKey();
|
||||
YAMLNode node = entry.getValue();
|
||||
|
||||
String type = node.getString("type");
|
||||
ProtectedRegion region;
|
||||
|
||||
try {
|
||||
if (type == null) {
|
||||
log.warning("Undefined region type for region '" + id + "'!\n" +
|
||||
"Here is what the region data looks like:\n\n" + toYamlOutput(entry.getValue().getMap()) + "\n");
|
||||
continue;
|
||||
} else if (type.equals("cuboid")) {
|
||||
Vector3 pt1 = checkNotNull(node.getVector("min"));
|
||||
Vector3 pt2 = checkNotNull(node.getVector("max"));
|
||||
BlockVector3 min = pt1.getMinimum(pt2).toBlockPoint();
|
||||
BlockVector3 max = pt1.getMaximum(pt2).toBlockPoint();
|
||||
region = new ProtectedCuboidRegion(id, min, max);
|
||||
} else if (type.equals("poly2d")) {
|
||||
Integer minY = checkNotNull(node.getInt("min-y"));
|
||||
Integer maxY = checkNotNull(node.getInt("max-y"));
|
||||
List<BlockVector2> points = node.getBlockVector2List("points", null);
|
||||
region = new ProtectedPolygonalRegion(id, points, minY, maxY);
|
||||
} else if (type.equals("global")) {
|
||||
region = new GlobalProtectedRegion(id);
|
||||
} else {
|
||||
log.warning("Unknown region type for region '" + id + "'!\n" +
|
||||
"Here is what the region data looks like:\n\n" + toYamlOutput(entry.getValue().getMap()) + "\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
Integer priority = checkNotNull(node.getInt("priority"));
|
||||
region.setPriority(priority);
|
||||
setFlags(flagRegistry, region, node.getNode("flags"));
|
||||
region.setOwners(parseDomain(node.getNode("owners")));
|
||||
region.setMembers(parseDomain(node.getNode("members")));
|
||||
|
||||
loaded.put(id, region);
|
||||
|
||||
String parentId = node.getString("parent");
|
||||
if (parentId != null) {
|
||||
parentSets.put(region, parentId);
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
log.log(Level.WARNING,
|
||||
"Unexpected NullPointerException encountered during parsing for the region '" + id + "'!\n" +
|
||||
"Here is what the region data looks like:\n\n" + toYamlOutput(entry.getValue().getMap()) +
|
||||
"\n\nNote: This region will disappear as a result!", e);
|
||||
for (YamlReader reader : YAML_READERS) {
|
||||
if (reader.canLoad(config)) {
|
||||
return reader.load(flagRegistry, config);
|
||||
}
|
||||
}
|
||||
|
||||
// Relink parents
|
||||
RegionDatabaseUtils.relinkParents(loaded, parentSets);
|
||||
|
||||
return new HashSet<>(loaded.values());
|
||||
throw new IllegalStateException("No YAML reader was registered that understands the saved region information");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -197,13 +117,25 @@ public class YamlRegionFile implements RegionDatabase {
|
||||
|
||||
config.clear();
|
||||
|
||||
config.setProperty("version", YAML_READERS.get(0).getVersion());
|
||||
YAMLNode regionsNode = config.addNode("regions");
|
||||
Map<String, Object> map = regionsNode.getMap();
|
||||
|
||||
// Creates a mapping of existing namespace node names, to their underlying YAMLNode.
|
||||
Map<String, YAMLNode> namespaceMap = new HashMap<>();
|
||||
|
||||
for (ProtectedRegion region : regions) {
|
||||
Map<String, Object> nodeMap = new HashMap<>();
|
||||
map.put(region.getId(), nodeMap);
|
||||
YAMLNode node = new YAMLNode(nodeMap, false);
|
||||
RegionIdentifier identifier = region.getIdentifier();
|
||||
|
||||
String internalNamespace = identifier.getNamespace().orElse(YAML_GLOBAL_NAMESPACE_NAME);
|
||||
YAMLNode namespaceNode = namespaceMap.compute(internalNamespace, (ignored, existingNamespaceNode) -> {
|
||||
if (existingNamespaceNode == null) {
|
||||
existingNamespaceNode = regionsNode.addNode(internalNamespace);
|
||||
}
|
||||
|
||||
return existingNamespaceNode;
|
||||
});
|
||||
|
||||
YAMLNode node = namespaceNode.addNode(identifier.getName());
|
||||
|
||||
if (region instanceof ProtectedCuboidRegion) {
|
||||
ProtectedCuboidRegion cuboid = (ProtectedCuboidRegion) region;
|
||||
@@ -238,7 +170,7 @@ public class YamlRegionFile implements RegionDatabase {
|
||||
|
||||
ProtectedRegion parent = region.getParent();
|
||||
if (parent != null) {
|
||||
node.setProperty("parent", parent.getId());
|
||||
node.setProperty("parent", parent.getIdentifier().getLegacyQualifiedName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,46 +189,10 @@ public class YamlRegionFile implements RegionDatabase {
|
||||
throw new DifferenceSaveException("Not supported");
|
||||
}
|
||||
|
||||
private DefaultDomain parseDomain(YAMLNode node) {
|
||||
if (node == null) {
|
||||
return new DefaultDomain();
|
||||
}
|
||||
|
||||
DefaultDomain domain = new DefaultDomain();
|
||||
|
||||
for (String name : node.getStringList("players", null)) {
|
||||
if (!name.isEmpty()) {
|
||||
domain.addPlayer(name);
|
||||
}
|
||||
}
|
||||
|
||||
for (String stringId : node.getStringList("unique-ids", null)) {
|
||||
try {
|
||||
domain.addPlayer(UUID.fromString(stringId));
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.log(Level.WARNING, "Failed to parse UUID '" + stringId + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
for (String name : node.getStringList("groups", null)) {
|
||||
if (!name.isEmpty()) {
|
||||
domain.addGroup(name);
|
||||
}
|
||||
}
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
private Map<String, Object> getFlagData(ProtectedRegion region) {
|
||||
return FlagUtil.marshal(region.getFlags());
|
||||
}
|
||||
|
||||
private void setFlags(FlagRegistry flagRegistry, ProtectedRegion region, YAMLNode flagsData) {
|
||||
if (flagsData != null) {
|
||||
region.setFlags(flagRegistry.unmarshal(flagsData.getMap(), true));
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> getDomainData(DefaultDomain domain) {
|
||||
Map<String, Object> domainData = new HashMap<>();
|
||||
|
||||
@@ -331,19 +227,4 @@ public class YamlRegionFile implements RegionDatabase {
|
||||
checkNotNull(file);
|
||||
return new YAMLProcessor(file, false, YAMLFormat.COMPACT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump the given object as YAML for debugging purposes.
|
||||
*
|
||||
* @param object the object
|
||||
* @return the YAML string or an error string if dumping fals
|
||||
*/
|
||||
private static String toYamlOutput(Object object) {
|
||||
try {
|
||||
return ERROR_DUMP_YAML.dump(object).replaceAll("(?m)^", "\t");
|
||||
} catch (Throwable t) {
|
||||
return "<error while dumping object>";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+23
@@ -44,6 +44,7 @@ public class GlobalProtectedRegion extends ProtectedRegion {
|
||||
*
|
||||
* @param id the ID
|
||||
*/
|
||||
@Deprecated
|
||||
public GlobalProtectedRegion(String id) {
|
||||
this(id, false);
|
||||
}
|
||||
@@ -54,7 +55,29 @@ public class GlobalProtectedRegion extends ProtectedRegion {
|
||||
* @param id the ID
|
||||
* @param transientRegion whether this region should only be kept in memory and not be saved
|
||||
*/
|
||||
@Deprecated
|
||||
public GlobalProtectedRegion(String id, boolean transientRegion) {
|
||||
this(new RegionIdentifier(id), transientRegion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance.<br>
|
||||
* Equivalent to {@link #GlobalProtectedRegion(String, boolean) GlobalProtectedRegion(id, false)}<br>
|
||||
* <code>transientRegion</code> will be set to false, and this region can be saved.
|
||||
*
|
||||
* @param id the region identifier
|
||||
*/
|
||||
public GlobalProtectedRegion(RegionIdentifier id) {
|
||||
this(id, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param id the region identifier
|
||||
* @param transientRegion whether this region should only be kept in memory and not be saved
|
||||
*/
|
||||
public GlobalProtectedRegion(RegionIdentifier id, boolean transientRegion) {
|
||||
super(id, transientRegion);
|
||||
min = BlockVector3.ZERO;
|
||||
max = BlockVector3.ZERO;
|
||||
|
||||
+28
@@ -47,6 +47,7 @@ public class ProtectedCuboidRegion extends ProtectedRegion {
|
||||
* @param pt1 the first point of this region
|
||||
* @param pt2 the second point of this region
|
||||
*/
|
||||
@Deprecated
|
||||
public ProtectedCuboidRegion(String id, BlockVector3 pt1, BlockVector3 pt2) {
|
||||
this(id, false, pt1, pt2);
|
||||
}
|
||||
@@ -59,7 +60,34 @@ public class ProtectedCuboidRegion extends ProtectedRegion {
|
||||
* @param pt1 the first point of this region
|
||||
* @param pt2 the second point of this region
|
||||
*/
|
||||
@Deprecated
|
||||
public ProtectedCuboidRegion(String id, boolean transientRegion, BlockVector3 pt1, BlockVector3 pt2) {
|
||||
this(new RegionIdentifier(id), transientRegion, pt1, pt2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance of this cuboid region.<br>
|
||||
* Equivalent to {@link #ProtectedCuboidRegion(RegionIdentifier, boolean, BlockVector3, BlockVector3)
|
||||
* ProtectedCuboidRegion(id, false, pt1, pt2)}<br>
|
||||
* <code>transientRegion</code> will be set to false, and this region can be saved.
|
||||
*
|
||||
* @param id the region identifier
|
||||
* @param pt1 the first point of this region
|
||||
* @param pt2 the second point of this region
|
||||
*/
|
||||
public ProtectedCuboidRegion(RegionIdentifier id, BlockVector3 pt1, BlockVector3 pt2) {
|
||||
this(id, false, pt1, pt2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance of this cuboid region.
|
||||
*
|
||||
* @param id the region identifier
|
||||
* @param transientRegion whether this region should only be kept in memory and not be saved
|
||||
* @param pt1 the first point of this region
|
||||
* @param pt2 the second point of this region
|
||||
*/
|
||||
public ProtectedCuboidRegion(RegionIdentifier id, boolean transientRegion, BlockVector3 pt1, BlockVector3 pt2) {
|
||||
super(id, transientRegion);
|
||||
setMinMaxPoints(pt1, pt2);
|
||||
}
|
||||
|
||||
+31
@@ -47,6 +47,7 @@ public class ProtectedPolygonalRegion extends ProtectedRegion {
|
||||
* @param minY the minimum y coordinate
|
||||
* @param maxY the maximum y coordinate
|
||||
*/
|
||||
@Deprecated
|
||||
public ProtectedPolygonalRegion(String id, List<BlockVector2> points, int minY, int maxY) {
|
||||
this(id, false, points, minY, maxY);
|
||||
}
|
||||
@@ -60,7 +61,37 @@ public class ProtectedPolygonalRegion extends ProtectedRegion {
|
||||
* @param minY the minimum y coordinate
|
||||
* @param maxY the maximum y coordinate
|
||||
*/
|
||||
@Deprecated
|
||||
public ProtectedPolygonalRegion(String id, boolean transientRegion, List<BlockVector2> points, int minY, int maxY) {
|
||||
this(new RegionIdentifier(id), transientRegion, points, minY, maxY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance of this polygonal region.<br>
|
||||
* Equivalent to {@link #ProtectedPolygonalRegion(RegionIdentifier, boolean, List, int, int)
|
||||
* ProtectedPolygonalRegion(id, false, points, minY, maxY)}<br>
|
||||
* <code>transientRegion</code> will be set to false, and this region can be saved.
|
||||
*
|
||||
* @param id the region identifier
|
||||
* @param points a {@link List} of points that this region should contain
|
||||
* @param minY the minimum y coordinate
|
||||
* @param maxY the maximum y coordinate
|
||||
*/
|
||||
public ProtectedPolygonalRegion(RegionIdentifier id, List<BlockVector2> points, int minY, int maxY) {
|
||||
this(id, false, points, minY, maxY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance of this polygonal region.
|
||||
*
|
||||
* @param id the region identifier
|
||||
* @param transientRegion whether this region should only be kept in memory and not be saved
|
||||
* @param points a {@link List} of points that this region should contain
|
||||
* @param minY the minimum y coordinate
|
||||
* @param maxY the maximum y coordinate
|
||||
*/
|
||||
public ProtectedPolygonalRegion(RegionIdentifier id, boolean transientRegion, List<BlockVector2> points,
|
||||
int minY, int maxY) {
|
||||
super(id, transientRegion);
|
||||
ImmutableList<BlockVector2> immutablePoints = ImmutableList.copyOf(points);
|
||||
setMinMaxPoints(immutablePoints, minY, maxY);
|
||||
|
||||
+16
-14
@@ -28,7 +28,6 @@ import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.util.ChangeTracked;
|
||||
import com.sk89q.worldguard.util.Normal;
|
||||
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Line2D;
|
||||
@@ -37,7 +36,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@@ -50,12 +48,11 @@ import javax.annotation.Nullable;
|
||||
public abstract class ProtectedRegion implements ChangeTracked, Comparable<ProtectedRegion> {
|
||||
|
||||
public static final String GLOBAL_REGION = "__global__";
|
||||
private static final Pattern VALID_ID_PATTERN = Pattern.compile("^[A-Za-z0-9_,'\\-\\+/]{1,}$");
|
||||
|
||||
protected BlockVector3 min;
|
||||
protected BlockVector3 max;
|
||||
|
||||
private final String id;
|
||||
private final RegionIdentifier id;
|
||||
private final boolean transientRegion;
|
||||
private int priority = 0;
|
||||
private ProtectedRegion parent;
|
||||
@@ -67,18 +64,13 @@ public abstract class ProtectedRegion implements ChangeTracked, Comparable<Prote
|
||||
/**
|
||||
* Construct a new instance of this region.
|
||||
*
|
||||
* @param id the name of this region
|
||||
* @param id the name information for this region
|
||||
* @param transientRegion whether this region should only be kept in memory and not be saved
|
||||
* @throws IllegalArgumentException thrown if the ID is invalid (see {@link #isValidId(String)}
|
||||
*/
|
||||
ProtectedRegion(String id, boolean transientRegion) { // Package private because we can't have people creating their own region types
|
||||
ProtectedRegion(RegionIdentifier id, boolean transientRegion) { // Package private because we can't have people creating their own region types
|
||||
checkNotNull(id);
|
||||
|
||||
if (!isValidId(id)) {
|
||||
throw new IllegalArgumentException("Invalid region ID: " + id);
|
||||
}
|
||||
|
||||
this.id = Normal.normalize(id);
|
||||
this.id = id;
|
||||
this.transientRegion = transientRegion;
|
||||
}
|
||||
|
||||
@@ -119,7 +111,17 @@ public abstract class ProtectedRegion implements ChangeTracked, Comparable<Prote
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
@Deprecated
|
||||
public String getId() {
|
||||
return id.getLegacyQualifiedName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the identifier info for this region.
|
||||
*
|
||||
* @return the identifier info
|
||||
*/
|
||||
public RegionIdentifier getIdentifier() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -734,9 +736,9 @@ public abstract class ProtectedRegion implements ChangeTracked, Comparable<Prote
|
||||
* @param id the id to check
|
||||
* @return whether the region id given is valid
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isValidId(String id) {
|
||||
checkNotNull(id);
|
||||
return VALID_ID_PATTERN.matcher(id).matches();
|
||||
return RegionIdentifier.isValidName(id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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.protection.regions;
|
||||
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.util.Normal;
|
||||
import com.sk89q.worldguard.util.profile.Profile;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public final class RegionIdentifier {
|
||||
private static final Pattern VALID_NAME_PATTERN = Pattern.compile("^[A-Za-z0-9_,'\\-\\+/]{1,}$");
|
||||
|
||||
private String namespace;
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Construct a new RegionIdentifier for describing region name information, using the global namespace.<br>
|
||||
* Equivalent to {@link #RegionIdentifier(String, String) RegionIdentifier(null, name)}<br>
|
||||
* <code>namespace</code> will be set to null.
|
||||
*
|
||||
* @param name the name for this region
|
||||
* @throws IllegalArgumentException thrown if the name is invalid (see {@link #isValidName(String)}
|
||||
*/
|
||||
public RegionIdentifier(String name) {
|
||||
this(null, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new RegionIdentifier for describing region name information.
|
||||
*
|
||||
* @param namespace the namespace name for this region, or null if there isn't one
|
||||
* @param name the name for this region
|
||||
* @throws IllegalArgumentException thrown if the namespace is invalid (see {@link #isValidNamespace(String)}
|
||||
* @throws IllegalArgumentException thrown if the name is invalid (see {@link #isValidName(String)}
|
||||
*/
|
||||
public RegionIdentifier(@Nullable String namespace, String name) {
|
||||
if (!isValidNamespace(name)) {
|
||||
throw new IllegalArgumentException("Invalid region namespace: " + namespace);
|
||||
}
|
||||
|
||||
if (!isValidName(name)) {
|
||||
throw new IllegalArgumentException("Invalid region name: " + name);
|
||||
}
|
||||
|
||||
this.namespace = namespace == null ? null : Normal.normalize(namespace);
|
||||
this.name = Normal.normalize(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the qualified name. This is incompatible with the legacy naming scheme, and
|
||||
* should be used when interacting with the command system. This will ensure that the correct
|
||||
* region is referenced regardless of the user's default namespace.
|
||||
*
|
||||
* @return the qualified name
|
||||
*/
|
||||
public String getQualifiedName() {
|
||||
return getNamespace().orElse("") + ":" + name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the legacy qualified name. This is compatible with the legacy naming scheme, and
|
||||
* should be used when interacting with the region manager via names.
|
||||
*
|
||||
* If you're using this outside of WorldGuard internals, you're doing something wrong.
|
||||
*
|
||||
* @return the legacy qualified name
|
||||
*/
|
||||
@Deprecated
|
||||
public String getLegacyQualifiedName() {
|
||||
return getNamespace().map((ns) -> ns + ':' + getName()).orElse(getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Compresses the name into a more user friendly macro based name.
|
||||
*
|
||||
* @param actor a player context
|
||||
* @return the user friendly display name
|
||||
*/
|
||||
public String getDisplayName(Actor actor) {
|
||||
if (actor instanceof LocalPlayer) {
|
||||
LocalPlayer player = (LocalPlayer) actor;
|
||||
if (player.isDefaultNamespace(namespace)) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
if (namespace != null) {
|
||||
try {
|
||||
UUID playerID = UUID.fromString(namespace);
|
||||
Profile profile = WorldGuard.getInstance().getProfileCache().getIfPresent(playerID);
|
||||
if (profile != null) {
|
||||
return "#" + profile.getName() + ":" + name;
|
||||
}
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to the fully qualified name.
|
||||
return getQualifiedName();
|
||||
}
|
||||
|
||||
public Optional<String> getNamespace() {
|
||||
return Optional.ofNullable(namespace);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public static boolean isValidNamespace(String namespace) {
|
||||
if (namespace == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return VALID_NAME_PATTERN.matcher(namespace).matches();
|
||||
}
|
||||
|
||||
public static boolean isValidName(String name) {
|
||||
checkNotNull(name);
|
||||
return VALID_NAME_PATTERN.matcher(name).matches();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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())));
|
||||
|
||||
|
||||
@@ -64,6 +64,11 @@ public class TestPlayer extends AbstractPlayerActor implements LocalPlayer {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultNamespace() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasGroup(String group) {
|
||||
return groups.contains(group.toLowerCase());
|
||||
|
||||
+4
-58
@@ -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));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user