Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f147402d30 | ||
|
|
8e35db0f35 | ||
|
|
9b2eff0a71 | ||
|
|
104cdc023d | ||
|
|
deb283c44b | ||
|
|
324e90c68a | ||
|
|
c60502ffd8 | ||
|
|
26e59955ed | ||
|
|
4746e95249 | ||
|
|
9cafb07e4d | ||
|
|
b2b0fe65c6 | ||
|
|
06e6ce589b | ||
|
|
12fc1438c2 | ||
|
|
e5e1f71a2a | ||
|
|
2aaa14261b | ||
|
|
f006a9584c | ||
|
|
03cf9a668b | ||
|
|
db70e6f346 | ||
|
|
e0df194ff2 | ||
|
|
ab55137f59 | ||
|
|
bbb79526b2 | ||
|
|
cde9a403f7 | ||
|
|
43a9228304 | ||
|
|
c1b8d12d05 | ||
|
|
a25674e9a5 | ||
|
|
778ec404ff | ||
|
|
4ab38e5b89 |
No files matched your search
@@ -1,7 +1,7 @@
|
||||
apply plugin: 'eclipse'
|
||||
apply plugin: 'idea'
|
||||
|
||||
project.version = '6.1.2'
|
||||
project.version = '6.2.1-SNAPSHOT'
|
||||
ext.internalVersion = project.version + ";" + gitCommitHash
|
||||
|
||||
sourceCompatibility = 1.7
|
||||
@@ -11,7 +11,7 @@ checkstyle.configFile = new File(projectDir, "config/checkstyle/checkstyle.xml")
|
||||
|
||||
dependencies {
|
||||
compile 'org.khelekore:prtree:1.5.0'
|
||||
compile 'org.bukkit:bukkit:1.9.4-R0.1-SNAPSHOT'
|
||||
compile 'org.bukkit:bukkit:1.11-R0.1-SNAPSHOT'
|
||||
compile 'com.sk89q.worldedit:worldedit-bukkit:6.1.3-SNAPSHOT'
|
||||
compile 'com.sk89q:squirrelid:0.1.0'
|
||||
compile 'com.sk89q:guavabackport:1.1'
|
||||
|
||||
@@ -85,7 +85,7 @@ public class RegionContainer {
|
||||
*/
|
||||
void initialize() {
|
||||
ConfigurationManager config = plugin.getGlobalStateManager();
|
||||
container = new RegionContainerImpl(config.selectedRegionStoreDriver);
|
||||
container = new RegionContainerImpl(config.selectedRegionStoreDriver, plugin.getFlagRegistry());
|
||||
|
||||
// Migrate to UUIDs
|
||||
autoMigrate();
|
||||
@@ -293,7 +293,7 @@ public class RegionContainer {
|
||||
|
||||
if (config.migrateRegionsToUuid) {
|
||||
RegionDriver driver = getDriver();
|
||||
UUIDMigration migrator = new UUIDMigration(driver, plugin.getProfileService());
|
||||
UUIDMigration migrator = new UUIDMigration(driver, plugin.getProfileService(), plugin.getFlagRegistry());
|
||||
migrator.setKeepUnresolvedNames(config.keepUnresolvedNames);
|
||||
try {
|
||||
migrate(migrator);
|
||||
|
||||
@@ -145,6 +145,7 @@ public class WorldConfiguration {
|
||||
public int maxClaimVolume;
|
||||
public boolean claimOnlyInsideExistingRegions;
|
||||
public int maxRegionCountPerPlayer;
|
||||
public boolean boundedLocationFlags;
|
||||
public boolean antiWolfDumbness;
|
||||
public boolean signChestProtection;
|
||||
public boolean disableSignChestProtectionCheck;
|
||||
@@ -462,6 +463,7 @@ public class WorldConfiguration {
|
||||
regionWand = getInt("regions.wand", 334);
|
||||
maxClaimVolume = getInt("regions.max-claim-volume", 30000);
|
||||
claimOnlyInsideExistingRegions = getBoolean("regions.claim-only-inside-existing-regions", false);
|
||||
boundedLocationFlags = getBoolean("regions.location-flags-only-inside-regions", false);
|
||||
|
||||
maxRegionCountPerPlayer = getInt("regions.max-region-count-per-player.default", 7);
|
||||
maxRegionCounts = new HashMap<String, Integer>();
|
||||
|
||||
@@ -37,10 +37,33 @@ import com.sk89q.worldguard.bukkit.commands.GeneralCommands;
|
||||
import com.sk89q.worldguard.bukkit.commands.ProtectionCommands;
|
||||
import com.sk89q.worldguard.bukkit.commands.ToggleCommands;
|
||||
import com.sk89q.worldguard.bukkit.event.player.ProcessPlayerEvent;
|
||||
import com.sk89q.worldguard.bukkit.listener.*;
|
||||
import com.sk89q.worldguard.bukkit.listener.BlacklistListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.BlockedPotionsListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.BuildPermissionListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.ChestProtectionListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.DebuggingListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.EventAbstractionListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.InvincibilityListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.PlayerModesListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.PlayerMoveListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.RegionFlagsListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.RegionProtectionListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.WorldGuardBlockListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.WorldGuardCommandBookListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.WorldGuardEntityListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.WorldGuardHangingListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.WorldGuardPlayerListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.WorldGuardServerListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.WorldGuardVehicleListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.WorldGuardWeatherListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.WorldGuardWorldListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.WorldRulesListener;
|
||||
import com.sk89q.worldguard.bukkit.util.Events;
|
||||
import com.sk89q.worldguard.protection.GlobalRegionManager;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.managers.storage.StorageException;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
@@ -68,8 +91,17 @@ import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
@@ -91,6 +123,7 @@ public class WorldGuardPlugin extends JavaPlugin {
|
||||
private final ConfigurationManager configuration = new ConfigurationManager(this);
|
||||
private final RegionContainer regionContainer = new RegionContainer(this);
|
||||
private final GlobalRegionManager globalRegionManager = new GlobalRegionManager(this, regionContainer);
|
||||
private final SimpleFlagRegistry flagRegistry = new SimpleFlagRegistry();
|
||||
private SessionManager sessionManager;
|
||||
private final Supervisor supervisor = new SimpleSupervisor();
|
||||
private ListeningExecutorService executorService;
|
||||
@@ -110,6 +143,7 @@ public class WorldGuardPlugin extends JavaPlugin {
|
||||
return plugin.hasPermission(player, perm);
|
||||
}
|
||||
};
|
||||
flagRegistry.registerAll(DefaultFlag.getDefaultFlags());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,6 +161,7 @@ public class WorldGuardPlugin extends JavaPlugin {
|
||||
@SuppressWarnings("deprecation")
|
||||
public void onEnable() {
|
||||
configureLogger();
|
||||
flagRegistry.setInitialized(true);
|
||||
|
||||
getDataFolder().mkdirs(); // Need to create the plugins/WorldGuard folder
|
||||
|
||||
@@ -388,6 +423,15 @@ public class WorldGuardPlugin extends JavaPlugin {
|
||||
return profileCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the flag registry.
|
||||
*
|
||||
* @return the flag registry
|
||||
*/
|
||||
public FlagRegistry getFlagRegistry() {
|
||||
return flagRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a player is in a group.
|
||||
* This calls the corresponding method in PermissionsResolverManager
|
||||
|
||||
+8
-5
@@ -46,9 +46,11 @@ import com.sk89q.worldguard.bukkit.util.logging.LoggerToChatHandler;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
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.flags.RegionGroup;
|
||||
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.managers.RemovalStrategy;
|
||||
import com.sk89q.worldguard.protection.managers.migration.DriverMigration;
|
||||
@@ -466,6 +468,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
String flagName = args.getString(1);
|
||||
String value = args.argsLength() >= 3 ? args.getJoinedStrings(2) : null;
|
||||
RegionGroup groupValue = null;
|
||||
FlagRegistry flagRegistry = plugin.getFlagRegistry();
|
||||
RegionPermissionModel permModel = getPermissionModel(sender);
|
||||
|
||||
if (args.hasFlag('e')) {
|
||||
@@ -490,7 +493,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
throw new CommandPermissionsException();
|
||||
}
|
||||
|
||||
Flag<?> foundFlag = DefaultFlag.fuzzyMatchFlag(flagName);
|
||||
Flag<?> foundFlag = DefaultFlag.fuzzyMatchFlag(flagRegistry, flagName);
|
||||
|
||||
// We didn't find the flag, so let's print a list of flags that the user
|
||||
// can use, and do nothing afterwards
|
||||
@@ -498,7 +501,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
StringBuilder list = new StringBuilder();
|
||||
|
||||
// Need to build a list
|
||||
for (Flag<?> flag : DefaultFlag.getFlags()) {
|
||||
for (Flag<?> flag : flagRegistry) {
|
||||
// Can the user set this flag?
|
||||
if (!permModel.maySetFlag(existing, flag)) {
|
||||
continue;
|
||||
@@ -537,7 +540,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
// Parse the [-g group] separately so entire command can abort if parsing
|
||||
// the [value] part throws an error.
|
||||
try {
|
||||
groupValue = groupFlag.parseInput(plugin, sender, group);
|
||||
groupValue = groupFlag.parseInput(FlagContext.create().setSender(sender).setInput(group).setObject("region", existing).build());
|
||||
} catch (InvalidFlagFormat e) {
|
||||
throw new CommandException(e.getMessage());
|
||||
}
|
||||
@@ -913,7 +916,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
throw new CommandException("The driver specified as 'to' does not seem to be supported in your version of WorldGuard.");
|
||||
}
|
||||
|
||||
DriverMigration migration = new DriverMigration(fromDriver, toDriver);
|
||||
DriverMigration migration = new DriverMigration(fromDriver, toDriver, plugin.getFlagRegistry());
|
||||
|
||||
LoggerToChatHandler handler = null;
|
||||
Logger minecraftLogger = null;
|
||||
@@ -972,7 +975,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
ConfigurationManager config = plugin.getGlobalStateManager();
|
||||
RegionContainer container = plugin.getRegionContainer();
|
||||
RegionDriver driver = container.getDriver();
|
||||
UUIDMigration migration = new UUIDMigration(driver, plugin.getProfileService());
|
||||
UUIDMigration migration = new UUIDMigration(driver, plugin.getProfileService(), plugin.getFlagRegistry());
|
||||
migration.setKeepUnresolvedNames(config.keepUnresolvedNames);
|
||||
sender.sendMessage(ChatColor.YELLOW + "Now performing migration... this may take a while.");
|
||||
container.migrate(migration);
|
||||
|
||||
+2
-1
@@ -35,6 +35,7 @@ import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.bukkit.permission.RegionPermissionModel;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
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;
|
||||
@@ -391,7 +392,7 @@ class RegionCommandsBase {
|
||||
* @throws InvalidFlagFormat thrown if the value is invalid
|
||||
*/
|
||||
protected static <V> void setFlag(ProtectedRegion region, Flag<V> flag, CommandSender sender, String value) throws InvalidFlagFormat {
|
||||
region.setFlag(flag, flag.parseInput(WorldGuardPlugin.inst(), sender, value));
|
||||
region.setFlag(flag, flag.parseInput(FlagContext.create().setSender(sender).setInput(value).setObject("region", region).build()));
|
||||
}
|
||||
|
||||
}
|
||||
+3
-1
@@ -21,10 +21,12 @@ package com.sk89q.worldguard.bukkit.commands.region;
|
||||
|
||||
import com.sk89q.squirrelid.cache.ProfileCache;
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -105,7 +107,7 @@ public class RegionPrintoutBuilder implements Callable<String> {
|
||||
public void appendFlagsList(boolean useColors) {
|
||||
boolean hasFlags = false;
|
||||
|
||||
for (Flag<?> flag : DefaultFlag.getFlags()) {
|
||||
for (Flag<?> flag : WorldGuardPlugin.inst().getFlagRegistry()) {
|
||||
Object val = region.getFlag(flag), group = null;
|
||||
|
||||
// No value
|
||||
|
||||
+46
-10
@@ -70,8 +70,10 @@ import org.bukkit.event.vehicle.VehicleDestroyEvent;
|
||||
import org.bukkit.event.world.StructureGrowEvent;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.*;
|
||||
import org.bukkit.material.Dispenser;
|
||||
import org.bukkit.material.MaterialData;
|
||||
import org.bukkit.material.PistonExtensionMaterial;
|
||||
import org.bukkit.material.SpawnEgg;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
@@ -107,6 +109,10 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
getPlugin().getServer().getPluginManager().registerEvents(new SpigotCompatListener(), getPlugin());
|
||||
} catch (LinkageError ignored) {
|
||||
}
|
||||
try {
|
||||
getPlugin().getServer().getPluginManager().registerEvents(new LingeringPotionListener(), getPlugin());
|
||||
} catch (NoClassDefFoundError ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -633,7 +639,7 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
Events.fireToCancel(event, new DestroyEntityEvent(event, create(event.getPlayer(), event.getHook()), caught));
|
||||
} else if (Entities.isConsideredBuildingIfUsed(caught)) {
|
||||
Events.fireToCancel(event, new UseEntityEvent(event, create(event.getPlayer(), event.getHook()), caught));
|
||||
} else if (Entities.isNonHostile(caught)) {
|
||||
} else if (Entities.isNonHostile(caught) || caught instanceof Player) {
|
||||
Events.fireToCancel(event, new DamageEntityEvent(event, create(event.getPlayer(), event.getHook()), caught));
|
||||
}
|
||||
}
|
||||
@@ -711,8 +717,9 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onEntityCombust(EntityCombustEvent event) {
|
||||
if (event instanceof EntityCombustByBlockEvent) {
|
||||
Events.fireToCancel(event, new DamageEntityEvent(event, create(((EntityCombustByBlockEvent) event).getCombuster()), event.getEntity()));
|
||||
|
||||
// at the time of writing, spigot is throwing null for the event's combuster. this causes lots of issues downstream.
|
||||
// whenever (i mean if ever) it is fixed, use getCombuster again instead of the current block
|
||||
Events.fireToCancel(event, new DamageEntityEvent(event, create(event.getEntity().getLocation().getBlock()), event.getEntity()));
|
||||
} else if (event instanceof EntityCombustByEntityEvent) {
|
||||
Events.fireToCancel(event, new DamageEntityEvent(event, create(((EntityCombustByEntityEvent) event).getCombuster()), event.getEntity()));
|
||||
}
|
||||
@@ -832,6 +839,7 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
// Fire entity interaction event
|
||||
if (!event.isCancelled()) {
|
||||
int blocked = 0;
|
||||
int affectedSize = event.getAffectedEntities().size();
|
||||
boolean hasDamageEffect = Materials.hasDamageEffect(potion.getEffects());
|
||||
|
||||
for (LivingEntity affected : event.getAffectedEntities()) {
|
||||
@@ -848,7 +856,7 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
}
|
||||
}
|
||||
|
||||
if (blocked == event.getAffectedEntities().size()) {
|
||||
if (blocked == affectedSize) { // server does weird things with this if the event is modified, so use cached number
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -889,23 +897,36 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
// next to redstone, without plugins getting the clicked place event
|
||||
// (not sure if this actually still happens)
|
||||
Events.fireToCancel(event, new UseBlockEvent(event, cause, clicked.getLocation(), Material.TNT));
|
||||
|
||||
// Workaround for http://leaky.bukkit.org/issues/1034
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, cause, placed.getLocation(), Material.TNT));
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle created Minecarts
|
||||
if (item != null && Materials.isMinecart(item.getType())) {
|
||||
// TODO: Give a more specific Minecart type
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, cause, placed.getLocation().add(0.5, 0, 0.5), EntityType.MINECART));
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle created boats
|
||||
if (item != null && Materials.isBoat(item.getType())) {
|
||||
// TODO as above
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, cause, placed.getLocation().add(0.5, 0, 0.5), EntityType.BOAT));
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle created armor stands
|
||||
if (item != null && item.getType() == Materials.ARMOR_STAND) {
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, cause, placed.getLocation().add(0.5, 0, 0.5), EntityType.ARMOR_STAND));
|
||||
return;
|
||||
}
|
||||
|
||||
if (item != null && item.getType() == Materials.END_CRYSTAL) { /*&& placed.getType() == Material.BEDROCK) {*/ // in vanilla you can only place them on bedrock but who knows what plugins will add
|
||||
// may be overprotective as a result, but better than being underprotective
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, cause, placed.getLocation().add(0.5, 0, 0.5), EntityType.ENDER_CRYSTAL));
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle created spawn eggs
|
||||
@@ -918,6 +939,7 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
}
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, cause, placed.getLocation().add(0.5, 0, 0.5), type));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle cocoa beans
|
||||
@@ -926,11 +948,7 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
if (!(faceClicked == BlockFace.DOWN || faceClicked == BlockFace.UP)) {
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, cause, placed.getLocation(), Material.COCOA));
|
||||
}
|
||||
}
|
||||
|
||||
// Workaround for http://leaky.bukkit.org/issues/1034
|
||||
if (item != null && item.getType() == Material.TNT) {
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, cause, placed.getLocation(), Material.TNT));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -990,4 +1008,22 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
}
|
||||
}
|
||||
|
||||
public class LingeringPotionListener implements Listener {
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onLingeringSplash(LingeringPotionSplashEvent event) {
|
||||
AreaEffectCloud aec = event.getAreaEffectCloud();
|
||||
LingeringPotion potion = event.getEntity();
|
||||
World world = potion.getWorld();
|
||||
Cause cause = create(event.getEntity());
|
||||
|
||||
// Fire item interaction event
|
||||
Events.fireToCancel(event, new UseItemEvent(event, cause, world, potion.getItem()));
|
||||
|
||||
// Fire entity spawn event
|
||||
if (!event.isCancelled()) {
|
||||
// radius unfortunately doesn't go through with this, so only a single location is tested
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, cause, aec.getLocation().add(0.5, 0, 0.5), EntityType.AREA_EFFECT_CLOUD));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-16
@@ -25,6 +25,7 @@ import com.sk89q.worldguard.bukkit.WorldConfiguration;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.bukkit.event.block.BreakBlockEvent;
|
||||
import com.sk89q.worldguard.bukkit.event.block.PlaceBlockEvent;
|
||||
import com.sk89q.worldguard.bukkit.util.Entities;
|
||||
import com.sk89q.worldguard.bukkit.util.Materials;
|
||||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
@@ -61,10 +62,6 @@ public class RegionFlagsListener extends AbstractListener {
|
||||
|
||||
Block block;
|
||||
if ((block = event.getCause().getFirstBlock()) != null) {
|
||||
// ================================================================
|
||||
// PISTONS flag
|
||||
// ================================================================
|
||||
|
||||
if (Materials.isPistonBlock(block.getType())) {
|
||||
event.filter(testState(query, DefaultFlag.PISTONS), false);
|
||||
}
|
||||
@@ -80,31 +77,22 @@ public class RegionFlagsListener extends AbstractListener {
|
||||
|
||||
Block block;
|
||||
if ((block = event.getCause().getFirstBlock()) != null) {
|
||||
// ================================================================
|
||||
// PISTONS flag
|
||||
// ================================================================
|
||||
|
||||
if (Materials.isPistonBlock(block.getType())) {
|
||||
event.filter(testState(query, DefaultFlag.PISTONS), false);
|
||||
}
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// CREEPER_EXPLOSION flag
|
||||
// ================================================================
|
||||
|
||||
if (event.getCause().find(EntityType.CREEPER) != null) { // Creeper
|
||||
event.filter(testState(query, DefaultFlag.CREEPER_EXPLOSION), config.explosionFlagCancellation);
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// ENDERDRAGON_BLOCK_DAMAGE flag
|
||||
// ================================================================
|
||||
|
||||
if (event.getCause().find(EntityType.ENDER_DRAGON) != null) { // Enderdragon
|
||||
event.filter(testState(query, DefaultFlag.ENDERDRAGON_BLOCK_DAMAGE), config.explosionFlagCancellation);
|
||||
}
|
||||
|
||||
if (event.getCause().find(Entities.enderCrystalType) != null) { // should be nullsafe even if enderCrystalType field is null
|
||||
event.filter(testState(query, DefaultFlag.OTHER_EXPLOSION), config.explosionFlagCancellation);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
|
||||
+5
-1
@@ -340,10 +340,14 @@ public class RegionProtectionListener extends AbstractListener {
|
||||
what = "drop items";
|
||||
|
||||
/* XP drops */
|
||||
} else if (event.getEffectiveType() == EntityType.EXPERIENCE_ORB) {
|
||||
} else if (type == EntityType.EXPERIENCE_ORB) {
|
||||
canSpawn = query.testBuild(target, associable, combine(event, DefaultFlag.EXP_DROPS));
|
||||
what = "drop XP";
|
||||
|
||||
} else if (Entities.isAoECloud(type)) {
|
||||
canSpawn = query.testBuild(target, associable, combine(event, DefaultFlag.POTION_SPLASH));
|
||||
what = "use lingering potions";
|
||||
|
||||
/* Everything else */
|
||||
} else {
|
||||
canSpawn = query.testBuild(target, associable, combine(event));
|
||||
|
||||
+13
@@ -167,6 +167,19 @@ public class WorldGuardEntityListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
if (attacker.getType() == Entities.enderCrystalType) {
|
||||
// this isn't handled elsewhere because ender crystal explosions don't carry a player cause
|
||||
// in the same way that creepers or tnt can
|
||||
WorldConfiguration wcfg = plugin.getGlobalStateManager().get(defender.getWorld());
|
||||
if (wcfg.useRegions && wcfg.explosionFlagCancellation) {
|
||||
if (!plugin.getRegionContainer().createQuery().getApplicableRegions(defender.getLocation())
|
||||
.testState(null, DefaultFlag.OTHER_EXPLOSION)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (defender instanceof Player) {
|
||||
Player player = (Player) defender;
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
|
||||
+4
@@ -99,6 +99,10 @@ public class RegionPermissionModel extends AbstractPermissionModel {
|
||||
public boolean mayTeleportTo(ProtectedRegion region) {
|
||||
return hasPatternPermission("teleport", region);
|
||||
}
|
||||
|
||||
public boolean mayOverrideLocationFlagBounds(ProtectedRegion region) {
|
||||
return hasPatternPermission("locationoverride", region);
|
||||
}
|
||||
|
||||
public boolean mayList() {
|
||||
return hasPluginPermission("region.list");
|
||||
|
||||
@@ -182,6 +182,8 @@ public final class Entities {
|
||||
|
||||
private static final EntityType armorStandType =
|
||||
Enums.findByValue(EntityType.class, "ARMOR_STAND");
|
||||
public static final EntityType enderCrystalType =
|
||||
Enums.findByValue(EntityType.class, "ENDER_CRYSTAL");
|
||||
|
||||
/**
|
||||
* Test whether using the given entity should be considered "building"
|
||||
@@ -192,7 +194,8 @@ public final class Entities {
|
||||
*/
|
||||
public static boolean isConsideredBuildingIfUsed(Entity entity) {
|
||||
return entity instanceof Hanging
|
||||
|| entity.getType() == armorStandType;
|
||||
|| entity.getType() == armorStandType
|
||||
|| entity.getType() == enderCrystalType;
|
||||
}
|
||||
|
||||
private static final EntityType tippedArrow = Enums.findByValue(EntityType.class, "TIPPED_ARROW");
|
||||
@@ -201,4 +204,9 @@ public final class Entities {
|
||||
return (entity != null &&
|
||||
(entity.getType() == tippedArrow || entity.getType() == spectralArrow));
|
||||
}
|
||||
|
||||
private static final EntityType aoeCloud = Enums.findByValue(EntityType.class, "AREA_EFFECT_CLOUD");
|
||||
public static boolean isAoECloud(EntityType type) {
|
||||
return type == aoeCloud;
|
||||
}
|
||||
}
|
||||
@@ -47,12 +47,35 @@ public final class Materials {
|
||||
private static final Set<PotionEffectType> DAMAGE_EFFECTS = new HashSet<PotionEffectType>();
|
||||
|
||||
public static Material ARMOR_STAND;
|
||||
public static Material END_CRYSTAL;
|
||||
|
||||
private static Set<Material> shulkerBoxes = new HashSet<>();
|
||||
|
||||
static {
|
||||
try {
|
||||
// for backwards compatible access to material enum
|
||||
ARMOR_STAND = Material.ARMOR_STAND;
|
||||
END_CRYSTAL = Material.END_CRYSTAL;
|
||||
} catch (NoSuchFieldError ignored) {}
|
||||
|
||||
try {
|
||||
shulkerBoxes.add(Material.WHITE_SHULKER_BOX);
|
||||
shulkerBoxes.add(Material.ORANGE_SHULKER_BOX);
|
||||
shulkerBoxes.add(Material.MAGENTA_SHULKER_BOX);
|
||||
shulkerBoxes.add(Material.LIGHT_BLUE_SHULKER_BOX);
|
||||
shulkerBoxes.add(Material.YELLOW_SHULKER_BOX);
|
||||
shulkerBoxes.add(Material.LIME_SHULKER_BOX);
|
||||
shulkerBoxes.add(Material.PINK_SHULKER_BOX);
|
||||
shulkerBoxes.add(Material.GRAY_SHULKER_BOX);
|
||||
shulkerBoxes.add(Material.SILVER_SHULKER_BOX); // who called this silver?
|
||||
shulkerBoxes.add(Material.CYAN_SHULKER_BOX);
|
||||
shulkerBoxes.add(Material.PURPLE_SHULKER_BOX);
|
||||
shulkerBoxes.add(Material.BLUE_SHULKER_BOX);
|
||||
shulkerBoxes.add(Material.BROWN_SHULKER_BOX);
|
||||
shulkerBoxes.add(Material.GREEN_SHULKER_BOX);
|
||||
shulkerBoxes.add(Material.RED_SHULKER_BOX);
|
||||
shulkerBoxes.add(Material.BLACK_SHULKER_BOX);
|
||||
} catch (NoSuchFieldError ignored) {
|
||||
ARMOR_STAND = null;
|
||||
}
|
||||
|
||||
ENTITY_ITEMS.put(EntityType.PAINTING, Material.PAINTING);
|
||||
@@ -276,7 +299,9 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.JUNGLE_DOOR, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.ACACIA_DOOR, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.DARK_OAK_DOOR, MODIFIED_ON_RIGHT);
|
||||
|
||||
} catch (NoSuchFieldError ignored) {
|
||||
}
|
||||
try {
|
||||
MATERIAL_FLAGS.put(Material.GRASS_PATH, 0);
|
||||
MATERIAL_FLAGS.put(Material.CHORUS_PLANT, 0);
|
||||
MATERIAL_FLAGS.put(Material.CHORUS_FLOWER, 0);
|
||||
@@ -293,9 +318,19 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.STRUCTURE_BLOCK, MODIFIED_ON_LEFT | MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.COMMAND_REPEATING, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.COMMAND_CHAIN , MODIFIED_ON_RIGHT);
|
||||
|
||||
} catch (NoSuchFieldError ignored) {
|
||||
}
|
||||
try { // 1.10
|
||||
MATERIAL_FLAGS.put(Material.MAGMA, 0);
|
||||
MATERIAL_FLAGS.put(Material.NETHER_WART_BLOCK, 0);
|
||||
MATERIAL_FLAGS.put(Material.RED_NETHER_BRICK, 0);
|
||||
MATERIAL_FLAGS.put(Material.BONE_BLOCK, 0);
|
||||
MATERIAL_FLAGS.put(Material.STRUCTURE_VOID, 0);
|
||||
} catch (NoSuchFieldError ignored) {
|
||||
}
|
||||
for (Material m : shulkerBoxes) {
|
||||
MATERIAL_FLAGS.put(m, MODIFIED_ON_RIGHT);
|
||||
}
|
||||
|
||||
MATERIAL_FLAGS.put(Material.IRON_SPADE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.IRON_PICKAXE, 0);
|
||||
@@ -456,7 +491,7 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.LEASH, 0);
|
||||
MATERIAL_FLAGS.put(Material.NAME_TAG, 0);
|
||||
MATERIAL_FLAGS.put(Material.COMMAND_MINECART, 0);
|
||||
try {
|
||||
try { // 1.8
|
||||
MATERIAL_FLAGS.put(Material.PRISMARINE_SHARD, 0);
|
||||
MATERIAL_FLAGS.put(Material.PRISMARINE_CRYSTALS, 0);
|
||||
MATERIAL_FLAGS.put(Material.RABBIT, 0);
|
||||
@@ -476,7 +511,9 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.JUNGLE_DOOR_ITEM, 0);
|
||||
MATERIAL_FLAGS.put(Material.ACACIA_DOOR_ITEM, 0);
|
||||
MATERIAL_FLAGS.put(Material.DARK_OAK_DOOR_ITEM, 0);
|
||||
|
||||
} catch (NoSuchFieldError ignored) {
|
||||
}
|
||||
try { // 1.9 + 1.10 (oops)
|
||||
MATERIAL_FLAGS.put(Material.BOAT_SPRUCE, 0);
|
||||
MATERIAL_FLAGS.put(Material.BOAT_BIRCH, 0);
|
||||
MATERIAL_FLAGS.put(Material.BOAT_ACACIA, 0);
|
||||
@@ -493,7 +530,11 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.LINGERING_POTION, 0);
|
||||
MATERIAL_FLAGS.put(Material.ELYTRA, 0);
|
||||
MATERIAL_FLAGS.put(Material.END_CRYSTAL, 0);
|
||||
|
||||
} catch (NoSuchFieldError ignored) {
|
||||
}
|
||||
try { // 1.11
|
||||
MATERIAL_FLAGS.put(Material.TOTEM, 0);
|
||||
MATERIAL_FLAGS.put(Material.SHULKER_SHELL, 0);
|
||||
} catch (NoSuchFieldError ignored) {
|
||||
}
|
||||
MATERIAL_FLAGS.put(Material.GOLD_RECORD, 0);
|
||||
@@ -701,7 +742,8 @@ public final class Materials {
|
||||
|| material == Material.BOAT_ACACIA
|
||||
|| material == Material.BOAT_SPRUCE
|
||||
|| material == Material.BOAT_DARK_OAK
|
||||
|| material == Material.BOAT_JUNGLE;
|
||||
|| material == Material.BOAT_JUNGLE
|
||||
|| material == Material.BOAT_BIRCH;
|
||||
} catch (NoSuchFieldError ignored) {
|
||||
return material == Material.BOAT;
|
||||
}
|
||||
@@ -722,7 +764,8 @@ public final class Materials {
|
||||
|| material == Material.BREWING_STAND
|
||||
|| material == Material.TRAPPED_CHEST
|
||||
|| material == Material.HOPPER
|
||||
|| material == Material.DROPPER;
|
||||
|| material == Material.DROPPER
|
||||
|| shulkerBoxes.contains(material);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
-10
@@ -23,8 +23,6 @@ import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.RegionGroup;
|
||||
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag.State;
|
||||
|
||||
@@ -42,14 +40,6 @@ public abstract class AbstractRegionSet implements ApplicableRegionSet {
|
||||
return test(queryState(player, DefaultFlag.BUILD));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean canConstruct(LocalPlayer player) {
|
||||
checkNotNull(player);
|
||||
final RegionGroup flag = getFlag(DefaultFlag.CONSTRUCT, player);
|
||||
return RegionGroupFlag.isMember(this, flag, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean testState(@Nullable RegionAssociable subject, StateFlag... flags) {
|
||||
return test(queryState(subject, flags));
|
||||
|
||||
-11
@@ -149,17 +149,6 @@ public interface ApplicableRegionSet extends Iterable<ProtectedRegion> {
|
||||
*/
|
||||
<V> Collection<V> queryAllValues(@Nullable RegionAssociable subject, Flag<V> flag);
|
||||
|
||||
/**
|
||||
* Test whether the construct flag evaluates true for the given player.
|
||||
*
|
||||
* @param player the player
|
||||
* @return true if true
|
||||
* @deprecated The {@code CONSTRUCT} flag is being removed and is no longer
|
||||
* needed because flags now support groups assigned to them.
|
||||
*/
|
||||
@Deprecated
|
||||
boolean canConstruct(LocalPlayer player);
|
||||
|
||||
/**
|
||||
* Gets the state of a state flag. This cannot be used for the build flag.
|
||||
*
|
||||
|
||||
+2
-2
@@ -37,8 +37,8 @@ public class BooleanFlag extends Flag<Boolean> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean parseInput(WorldGuardPlugin plugin, CommandSender sender, String input) throws InvalidFlagFormat {
|
||||
input = input.trim();
|
||||
public Boolean parseInput(FlagContext context) throws InvalidFlagFormat {
|
||||
String input = context.getUserInput();
|
||||
|
||||
if (input.equalsIgnoreCase("true") || input.equalsIgnoreCase("yes")
|
||||
|| input.equalsIgnoreCase("on")
|
||||
|
||||
+2
-1
@@ -37,7 +37,8 @@ public class CommandStringFlag extends Flag<String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parseInput(WorldGuardPlugin plugin, CommandSender sender, String input) throws InvalidFlagFormat {
|
||||
public String parseInput(FlagContext context) throws InvalidFlagFormat {
|
||||
String input = context.getUserInput();
|
||||
input = input.trim();
|
||||
if (!input.startsWith("/")) {
|
||||
input = "/" + input;
|
||||
|
||||
+33
-13
@@ -19,11 +19,15 @@
|
||||
|
||||
package com.sk89q.worldguard.protection.flags;
|
||||
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.WeatherType;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The flags that are used in WorldGuard.
|
||||
*/
|
||||
@@ -32,13 +36,6 @@ public final class DefaultFlag {
|
||||
// Overrides membership check
|
||||
public static final StateFlag PASSTHROUGH = new StateFlag("passthrough", false);
|
||||
|
||||
/**
|
||||
* @deprecated This flag is being removed because group flags can now be
|
||||
* set on all flags.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final RegionGroupFlag CONSTRUCT = new RegionGroupFlag("construct", RegionGroup.MEMBERS);
|
||||
|
||||
// This flag is unlike the others. It forces the checking of region membership
|
||||
public static final StateFlag BUILD = new BuildFlag("build", true);
|
||||
|
||||
@@ -134,14 +131,19 @@ public final class DefaultFlag {
|
||||
// public static final StringFlag MAX_PLAYERS_MESSAGE = new StringFlag("max-players-reject-message");
|
||||
public static final LocationFlag TELE_LOC = new LocationFlag("teleport", RegionGroup.MEMBERS);
|
||||
public static final LocationFlag SPAWN_LOC = new LocationFlag("spawn", RegionGroup.MEMBERS);
|
||||
public static final StateFlag ENABLE_SHOP = new StateFlag("allow-shop", false);
|
||||
public static final BooleanFlag BUYABLE = new BooleanFlag("buyable");
|
||||
public static final DoubleFlag PRICE = new DoubleFlag("price");
|
||||
public static final SetFlag<String> BLOCKED_CMDS = new SetFlag<String>("blocked-cmds", new CommandStringFlag(null));
|
||||
public static final SetFlag<String> ALLOWED_CMDS = new SetFlag<String>("allowed-cmds", new CommandStringFlag(null));
|
||||
|
||||
// these 3 are not used by worldguard and should be re-implemented in plugins that may use them using custom flag api
|
||||
@Deprecated
|
||||
public static final StateFlag ENABLE_SHOP = new StateFlag("allow-shop", false);
|
||||
@Deprecated
|
||||
public static final BooleanFlag BUYABLE = new BooleanFlag("buyable");
|
||||
@Deprecated
|
||||
public static final DoubleFlag PRICE = new DoubleFlag("price");
|
||||
|
||||
public static final Flag<?>[] flagsList = new Flag<?>[] {
|
||||
PASSTHROUGH, BUILD, CONSTRUCT, BLOCK_BREAK, BLOCK_PLACE, PVP, CHEST_ACCESS, PISTONS,
|
||||
PASSTHROUGH, BUILD, BLOCK_BREAK, BLOCK_PLACE, PVP, CHEST_ACCESS, PISTONS,
|
||||
TNT, LIGHTER, RIDE, USE, INTERACT, PLACE_VEHICLE, DESTROY_VEHICLE, DAMAGE_ANIMALS, SLEEP,
|
||||
MOB_DAMAGE, MOB_SPAWNING, DENY_SPAWN, INVINCIBILITY, EXP_DROPS,
|
||||
CREEPER_EXPLOSION, OTHER_EXPLOSION, ENDERDRAGON_BLOCK_DAMAGE, GHAST_FIREBALL, ENDER_BUILD,
|
||||
@@ -161,18 +163,35 @@ public final class DefaultFlag {
|
||||
private DefaultFlag() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of default flags.
|
||||
*
|
||||
* @deprecated Use {@link FlagRegistry}
|
||||
* @return An array of flags
|
||||
*/
|
||||
@Deprecated
|
||||
public static Flag<?>[] getFlags() {
|
||||
return flagsList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of default flags.
|
||||
*
|
||||
* @return An array of flags
|
||||
*/
|
||||
public static List<Flag<?>> getDefaultFlags() {
|
||||
return Arrays.asList(flagsList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to match the flag with the given ID using a fuzzy name match.
|
||||
*
|
||||
* @param flagRegistry the flag registry
|
||||
* @param id the flag ID
|
||||
* @return a flag, or null
|
||||
*/
|
||||
public static Flag<?> fuzzyMatchFlag(String id) {
|
||||
for (Flag<?> flag : DefaultFlag.getFlags()) {
|
||||
public static Flag<?> fuzzyMatchFlag(FlagRegistry flagRegistry, String id) {
|
||||
for (Flag<?> flag : flagRegistry) {
|
||||
if (flag.getName().replace("-", "").equalsIgnoreCase(id.replace("-", ""))) {
|
||||
return flag;
|
||||
}
|
||||
@@ -180,4 +199,5 @@ public final class DefaultFlag {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+2
-12
@@ -19,10 +19,6 @@
|
||||
|
||||
package com.sk89q.worldguard.protection.flags;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
|
||||
/**
|
||||
* Stores doubles.
|
||||
*/
|
||||
@@ -37,14 +33,8 @@ public class DoubleFlag extends Flag<Double> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double parseInput(WorldGuardPlugin plugin, CommandSender sender, String input) throws InvalidFlagFormat {
|
||||
input = input.trim();
|
||||
|
||||
try {
|
||||
return Double.parseDouble(input);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new InvalidFlagFormat("Not a number: " + input);
|
||||
}
|
||||
public Double parseInput(FlagContext context) throws InvalidFlagFormat {
|
||||
return context.getUserInputAsDouble();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,10 +19,6 @@
|
||||
|
||||
package com.sk89q.worldguard.protection.flags;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
|
||||
/**
|
||||
* Stores an enum value.
|
||||
*/
|
||||
@@ -78,7 +74,8 @@ public class EnumFlag<T extends Enum<T>> extends Flag<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public T parseInput(WorldGuardPlugin plugin, CommandSender sender, String input) throws InvalidFlagFormat {
|
||||
public T parseInput(FlagContext context) throws InvalidFlagFormat {
|
||||
String input = context.getUserInput();
|
||||
try {
|
||||
return findValue(input);
|
||||
} catch (IllegalArgumentException e) {
|
||||
|
||||
@@ -19,28 +19,44 @@
|
||||
|
||||
package com.sk89q.worldguard.protection.flags;
|
||||
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.sk89q.worldguard.protection.FlagValueCalculator;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* A flag carries extra data on a region.
|
||||
*
|
||||
* <p>Each flag implementation is a singleton and must be registered with a
|
||||
* {@link FlagRegistry} to be useful. Flag values are stored as their
|
||||
* proper data type, but they are first "loaded" by calling
|
||||
* {@link #unmarshal(Object)}. On save, the objects are fed
|
||||
* through {@link #marshal(Object)} and then saved.</p>
|
||||
*/
|
||||
public abstract class Flag<T> {
|
||||
|
||||
private static final Pattern VALID_NAME = Pattern.compile("^[:A-Za-z0-9\\-]{1,40}$");
|
||||
private final String name;
|
||||
private final RegionGroupFlag regionGroup;
|
||||
|
||||
/**
|
||||
* Create a new flag.
|
||||
*
|
||||
* <p>Flag names should match the regex {@code ^[:A-Za-z0-9\-]{1,40}$}.</p>
|
||||
*
|
||||
* @param name The name of the flag
|
||||
* @param defaultGroup The default group
|
||||
* @throws IllegalArgumentException Thrown if the name is invalid
|
||||
*/
|
||||
public Flag(String name, @Nullable RegionGroup defaultGroup) {
|
||||
protected Flag(String name, @Nullable RegionGroup defaultGroup) {
|
||||
if (name != null && !isValidName(name)) {
|
||||
throw new IllegalArgumentException("Invalid flag name used");
|
||||
}
|
||||
this.name = name;
|
||||
this.regionGroup = defaultGroup != null ? new RegionGroupFlag(name + "-group", defaultGroup) : null;
|
||||
}
|
||||
@@ -48,9 +64,12 @@ public abstract class Flag<T> {
|
||||
/**
|
||||
* Create a new flag with {@link RegionGroup#ALL} as the default group.
|
||||
*
|
||||
* <p>Flag names should match the regex {@code ^[:A-Za-z0-9\-]{1,40}$}.</p>
|
||||
*
|
||||
* @param name The name of the flag
|
||||
* @throws IllegalArgumentException Thrown if the name is invalid
|
||||
*/
|
||||
public Flag(String name) {
|
||||
protected Flag(String name) {
|
||||
this(name, RegionGroup.ALL);
|
||||
}
|
||||
|
||||
@@ -59,7 +78,7 @@ public abstract class Flag<T> {
|
||||
*
|
||||
* @return The name of the flag
|
||||
*/
|
||||
public String getName() {
|
||||
public final String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -73,13 +92,20 @@ public abstract class Flag<T> {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a list of values, choose the best one.
|
||||
*
|
||||
* <p>If there is no "best value" defined, then the first value should
|
||||
* be returned. The default implementation returns the first value. If
|
||||
* an implementation does have a strategy defined, then
|
||||
* {@link #hasConflictStrategy()} should be overridden too.</p>
|
||||
*
|
||||
* @param values A collection of values
|
||||
* @return The chosen value
|
||||
*/
|
||||
@Nullable
|
||||
public T chooseValue(Collection<T> values) {
|
||||
if (!values.isEmpty()) {
|
||||
return values.iterator().next();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return Iterators.getNext(values.iterator(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,20 +171,18 @@ public abstract class Flag<T> {
|
||||
*
|
||||
* @return The region group flag
|
||||
*/
|
||||
public RegionGroupFlag getRegionGroupFlag() {
|
||||
public final RegionGroupFlag getRegionGroupFlag() {
|
||||
return regionGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a given input to coerce it to a type compatible with the flag.
|
||||
*
|
||||
* @param plugin The plugin
|
||||
* @param sender The sender
|
||||
* @param input THe input
|
||||
* @param context the {@link FlagContext}
|
||||
* @return The coerced type
|
||||
* @throws InvalidFlagFormat Raised if the input is invalid
|
||||
*/
|
||||
public abstract T parseInput(WorldGuardPlugin plugin, CommandSender sender, String input) throws InvalidFlagFormat;
|
||||
public abstract T parseInput(FlagContext context) throws InvalidFlagFormat;
|
||||
|
||||
/**
|
||||
* Convert a raw type that was loaded (from a YAML file, for example)
|
||||
@@ -184,4 +208,16 @@ public abstract class Flag<T> {
|
||||
"name='" + name + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether a flag name is valid.
|
||||
*
|
||||
* @param name The flag name
|
||||
* @return Whether the name is valid
|
||||
*/
|
||||
public static boolean isValidName(String name) {
|
||||
checkNotNull(name, "name");
|
||||
return VALID_NAME.matcher(name).matches();
|
||||
}
|
||||
|
||||
}
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* 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.flags;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Map;
|
||||
|
||||
public final class FlagContext {
|
||||
|
||||
private final CommandSender sender;
|
||||
private final String input;
|
||||
|
||||
private Map<String, Object> context;
|
||||
|
||||
private FlagContext(CommandSender sender, String input, Map<String, Object> values) {
|
||||
this.sender = sender;
|
||||
this.input = input;
|
||||
this.context = values;
|
||||
}
|
||||
|
||||
public static FlagContextBuilder create() {
|
||||
return new FlagContextBuilder();
|
||||
}
|
||||
|
||||
public void put(String name, Object value) {
|
||||
context.put(name, value);
|
||||
}
|
||||
|
||||
public CommandSender getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
public String getUserInput() {
|
||||
return input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the CommandSender as a player.
|
||||
*
|
||||
* @return Player
|
||||
* @throws InvalidFlagFormat if the sender is not a player
|
||||
*/
|
||||
public Player getPlayerSender() throws InvalidFlagFormat {
|
||||
try {
|
||||
return WorldGuardPlugin.inst().checkPlayer(sender);
|
||||
} catch (CommandException e) {
|
||||
throw new InvalidFlagFormat(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getUserInputAsInt() throws InvalidFlagFormat {
|
||||
try {
|
||||
return Integer.parseInt(input);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new InvalidFlagFormat("Not a number: " + input);
|
||||
}
|
||||
}
|
||||
|
||||
public Double getUserInputAsDouble() throws InvalidFlagFormat {
|
||||
try {
|
||||
return Double.parseDouble(input);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new InvalidFlagFormat("Not a number: " + input);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object from the context by key name.
|
||||
* May return null if the object does not exist in the context.
|
||||
*
|
||||
* @param name key name of the object
|
||||
* @return the object matching the key, or null
|
||||
*/
|
||||
@Nullable
|
||||
public Object get(String name) {
|
||||
return get(name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object from the context by key name.
|
||||
* Will only return null if
|
||||
* a) you provide null as the default
|
||||
* b) the key has explicity been set to null
|
||||
*
|
||||
* @param name key name of the object
|
||||
* @return the object matching the key
|
||||
*/
|
||||
@Nullable
|
||||
public Object get(String name, Object defaultValue) {
|
||||
Object obj;
|
||||
return (((obj = context.get(name)) != null) || context.containsKey(name)
|
||||
? obj : defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a copy of this FlagContext, with optional substitutions for values
|
||||
*
|
||||
* If any supplied variable is null, it will be ignored.
|
||||
* If a map is supplied, it will override this FlagContext's values of the same key,
|
||||
* but unprovided keys will not be overriden and will be returned as shallow copies.
|
||||
*
|
||||
* @param commandSender CommandSender for the new FlagContext to run under
|
||||
* @param s String of the user input for the new FlagContext
|
||||
* @param values map of values to override from the current FlagContext
|
||||
* @return a copy of this FlagContext
|
||||
*/
|
||||
public FlagContext copyWith(@Nullable CommandSender commandSender, @Nullable String s, @Nullable Map<String, Object> values) {
|
||||
Map<String, Object> map = Maps.newHashMap();
|
||||
map.putAll(context);
|
||||
if (values != null) {
|
||||
map.putAll(values);
|
||||
}
|
||||
return new FlagContext(commandSender == null ? this.sender : commandSender, s == null ? this.input : s, map);
|
||||
}
|
||||
|
||||
public static class FlagContextBuilder {
|
||||
private CommandSender sender;
|
||||
private String input;
|
||||
private Map<String, Object> map = Maps.newHashMap();
|
||||
|
||||
public FlagContextBuilder setSender(CommandSender sender) {
|
||||
this.sender = sender;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FlagContextBuilder setInput(String input) {
|
||||
this.input = input;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FlagContextBuilder setObject(String key, Object value) {
|
||||
this.map.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected boolean tryAddToMap(String key, Object value) {
|
||||
if (map.containsKey(key)) return false;
|
||||
this.map.put(key, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
public FlagContext build() {
|
||||
Bukkit.getServer().getPluginManager().callEvent(new FlagContextCreateEvent(this));
|
||||
|
||||
return new FlagContext(sender, input, map);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.flags;
|
||||
|
||||
import com.sk89q.worldguard.protection.flags.FlagContext.FlagContextBuilder;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
public class FlagContextCreateEvent extends Event {
|
||||
|
||||
private FlagContextBuilder builder;
|
||||
|
||||
public FlagContextCreateEvent(FlagContextBuilder builder) {
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an object to the flag context with the given key. Keys must be unique.
|
||||
*
|
||||
* @param key a unique string to identify the object
|
||||
* @param value the object to store in the context
|
||||
* @return true if added successfully, false if the key was already used
|
||||
*/
|
||||
public boolean addObject(String key, Object value) {
|
||||
return builder.tryAddToMap(key, value);
|
||||
}
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.flags;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public final class Flags {
|
||||
|
||||
private static final Logger log = Logger.getLogger(Flags.class.getCanonicalName());
|
||||
|
||||
private Flags() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Marshal a value of flag values into a map of raw values.
|
||||
*
|
||||
* @param values The unmarshalled flag values map
|
||||
* @return The raw values map
|
||||
*/
|
||||
public static Map<String, Object> marshal(Map<Flag<?>, Object> values) {
|
||||
checkNotNull(values, "values");
|
||||
|
||||
Map<String, Object> rawValues = Maps.newHashMap();
|
||||
for (Entry<Flag<?>, Object> entry : values.entrySet()) {
|
||||
try {
|
||||
rawValues.put(entry.getKey().getName(), marshal(entry.getKey(), entry.getValue()));
|
||||
} catch (Exception e) {
|
||||
log.log(Level.WARNING, "Failed to marshal flag value for " + entry.getKey() + "; value is " + entry.getValue(), e);
|
||||
}
|
||||
}
|
||||
|
||||
return rawValues;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> Object marshal(Flag<T> flag, Object value) {
|
||||
return flag.marshal((T) value);
|
||||
}
|
||||
|
||||
}
|
||||
+2
-12
@@ -19,10 +19,6 @@
|
||||
|
||||
package com.sk89q.worldguard.protection.flags;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
|
||||
/**
|
||||
* Stores an integer.
|
||||
*/
|
||||
@@ -37,14 +33,8 @@ public class IntegerFlag extends Flag<Integer> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer parseInput(WorldGuardPlugin plugin, CommandSender sender,String input) throws InvalidFlagFormat {
|
||||
input = input.trim();
|
||||
|
||||
try {
|
||||
return Integer.parseInt(input);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new InvalidFlagFormat("Not a number: " + input);
|
||||
}
|
||||
public Integer parseInput(FlagContext context) throws InvalidFlagFormat {
|
||||
return context.getUserInputAsInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+30
-15
@@ -19,13 +19,14 @@
|
||||
|
||||
package com.sk89q.worldguard.protection.flags;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.worldedit.Location;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.bukkit.BukkitUtil;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.bukkit.permission.RegionPermissionModel;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -42,18 +43,13 @@ public class LocationFlag extends Flag<Location> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location parseInput(WorldGuardPlugin plugin, CommandSender sender, String input) throws InvalidFlagFormat {
|
||||
input = input.trim();
|
||||
|
||||
final Player player;
|
||||
try {
|
||||
player = plugin.checkPlayer(sender);
|
||||
} catch (CommandException e) {
|
||||
throw new InvalidFlagFormat(e.getMessage());
|
||||
}
|
||||
public Location parseInput(FlagContext context) throws InvalidFlagFormat {
|
||||
String input = context.getUserInput();
|
||||
Player player = context.getPlayerSender();
|
||||
|
||||
Location loc = null;
|
||||
if ("here".equalsIgnoreCase(input)) {
|
||||
return toLazyLocation(player.getLocation());
|
||||
loc = toLazyLocation(player.getLocation());
|
||||
} else if ("none".equalsIgnoreCase(input)) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -67,13 +63,32 @@ public class LocationFlag extends Flag<Location> {
|
||||
final float yaw = split.length < 4 ? 0 : Float.parseFloat(split[3]);
|
||||
final float pitch = split.length < 5 ? 0 : Float.parseFloat(split[4]);
|
||||
|
||||
return new LazyLocation(world.getName(), new Vector(x, y, z), yaw, pitch);
|
||||
loc = new LazyLocation(world.getName(), new Vector(x, y, z), yaw, pitch);
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidFlagFormat("Expected 'here' or x,y,z.");
|
||||
}
|
||||
if (loc != null) {
|
||||
Object obj = context.get("region");
|
||||
if (obj instanceof ProtectedRegion) {
|
||||
ProtectedRegion rg = (ProtectedRegion) obj;
|
||||
if (WorldGuardPlugin.inst().getGlobalStateManager().get(player.getWorld()).boundedLocationFlags) {
|
||||
if (!rg.contains(loc.getPosition())) {
|
||||
if (new RegionPermissionModel(WorldGuardPlugin.inst(), player).mayOverrideLocationFlagBounds(rg)) {
|
||||
player.sendMessage(ChatColor.GRAY + "WARNING: Flag location is outside of region.");
|
||||
} else {
|
||||
// no permission
|
||||
throw new InvalidFlagFormat("You can't set that flag outside of the region boundaries.");
|
||||
}
|
||||
}
|
||||
// clamp height to world limits
|
||||
loc.setPosition(loc.getPosition().clampY(0, player.getWorld().getMaxHeight()));
|
||||
return loc;
|
||||
}
|
||||
}
|
||||
return loc;
|
||||
}
|
||||
throw new InvalidFlagFormat("Expected 'here' or x,y,z.");
|
||||
}
|
||||
|
||||
private Location toLazyLocation(org.bukkit.Location location) {
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
package com.sk89q.worldguard.protection.flags;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -56,14 +54,16 @@ public class SetFlag<T> extends Flag<Set<T>> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<T> parseInput(WorldGuardPlugin plugin, CommandSender sender, String input) throws InvalidFlagFormat {
|
||||
public Set<T> parseInput(FlagContext context) throws InvalidFlagFormat {
|
||||
String input = context.getUserInput();
|
||||
if (input.isEmpty()) {
|
||||
return Sets.newHashSet();
|
||||
} else {
|
||||
Set<T> items = Sets.newHashSet();
|
||||
|
||||
for (String str : input.split(",")) {
|
||||
items.add(subFlag.parseInput(plugin, sender, str.trim()));
|
||||
FlagContext copy = context.copyWith(null, str, null);
|
||||
items.add(subFlag.parseInput(copy));
|
||||
}
|
||||
|
||||
return items;
|
||||
|
||||
+2
-2
@@ -81,8 +81,8 @@ public class StateFlag extends Flag<StateFlag.State> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public State parseInput(WorldGuardPlugin plugin, CommandSender sender, String input) throws InvalidFlagFormat {
|
||||
input = input.trim();
|
||||
public State parseInput(FlagContext context) throws InvalidFlagFormat {
|
||||
String input = context.getUserInput();
|
||||
|
||||
if (input.equalsIgnoreCase("allow")) {
|
||||
return State.ALLOW;
|
||||
|
||||
+2
-2
@@ -59,8 +59,8 @@ public class StringFlag extends Flag<String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parseInput(WorldGuardPlugin plugin, CommandSender sender, String input) throws InvalidFlagFormat {
|
||||
return input.replaceAll("(?!\\\\)\\\\n", "\n").replaceAll("\\\\\\\\n", "\\n");
|
||||
public String parseInput(FlagContext context) throws InvalidFlagFormat {
|
||||
return context.getUserInput().replaceAll("(?!\\\\)\\\\n", "\n").replaceAll("\\\\\\\\n", "\\n");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-10
@@ -19,11 +19,8 @@
|
||||
|
||||
package com.sk89q.worldguard.protection.flags;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.bukkit.BukkitUtil;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -42,15 +39,11 @@ public class VectorFlag extends Flag<Vector> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector parseInput(WorldGuardPlugin plugin, CommandSender sender, String input) throws InvalidFlagFormat {
|
||||
input = input.trim();
|
||||
public Vector parseInput(FlagContext context) throws InvalidFlagFormat {
|
||||
String input = context.getUserInput();
|
||||
|
||||
if ("here".equalsIgnoreCase(input)) {
|
||||
try {
|
||||
return BukkitUtil.toVector(plugin.checkPlayer(sender).getLocation());
|
||||
} catch (CommandException e) {
|
||||
throw new InvalidFlagFormat(e.getMessage());
|
||||
}
|
||||
return BukkitUtil.toVector(context.getPlayerSender().getLocation());
|
||||
} else {
|
||||
String[] split = input.split(",");
|
||||
if (split.length == 3) {
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.flags.registry;
|
||||
|
||||
public class FlagConflictException extends RuntimeException {
|
||||
|
||||
public FlagConflictException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* WorldGuard, a suite of tools for Minecraft
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldGuard team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.protection.flags.registry;
|
||||
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Keeps track of registered flags.
|
||||
*/
|
||||
public interface FlagRegistry extends Iterable<Flag<?>> {
|
||||
|
||||
/**
|
||||
* Register a new flag.
|
||||
*
|
||||
* <p>There may be an appropriate time to register flags. If flags are
|
||||
* registered outside this time, then an exception may be thrown.</p>
|
||||
*
|
||||
* @param flag The flag
|
||||
* @throws FlagConflictException Thrown when an existing flag exists with the same name
|
||||
* @throws IllegalStateException If it is not the right time to register new flags
|
||||
*/
|
||||
void register(Flag<?> flag) throws FlagConflictException;
|
||||
|
||||
/**
|
||||
* Register a collection of flags.
|
||||
*
|
||||
* <p>There may be an appropriate time to register flags. If flags are
|
||||
* registered outside this time, then an exception may be thrown.</p>
|
||||
*
|
||||
* <p>If there is a flag conflict, then an error will be logged but
|
||||
* no exception will be thrown.</p>
|
||||
*
|
||||
* @param flags a collection of flags
|
||||
* @throws IllegalStateException If it is not the right time to register new flags
|
||||
*/
|
||||
void registerAll(Collection<Flag<?>> flags);
|
||||
|
||||
/**
|
||||
* Get af flag by its name.
|
||||
*
|
||||
* @param name The name
|
||||
* @return The flag, if it has been registered
|
||||
*/
|
||||
@Nullable
|
||||
Flag<?> get(String name);
|
||||
|
||||
/**
|
||||
* Unmarshal a raw map of values into a map of flags with their
|
||||
* unmarshalled values.
|
||||
*
|
||||
* @param rawValues The raw values map
|
||||
* @param createUnknown Whether "just in time" flags should be created for unknown flags
|
||||
* @return The unmarshalled flag values map
|
||||
*/
|
||||
Map<Flag<?>, Object> unmarshal(Map<String, Object> rawValues, boolean createUnknown);
|
||||
|
||||
/**
|
||||
* Get the number of registered flags.
|
||||
*
|
||||
* @return The number of registered flags
|
||||
*/
|
||||
int size();
|
||||
|
||||
}
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* 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.flags.registry;
|
||||
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class SimpleFlagRegistry implements FlagRegistry {
|
||||
|
||||
private static final Logger log = Logger.getLogger(SimpleFlagRegistry.class.getCanonicalName());
|
||||
|
||||
private final Object lock = new Object();
|
||||
private final ConcurrentMap<String, Flag<?>> flags = Maps.newConcurrentMap();
|
||||
private boolean initialized;
|
||||
|
||||
public boolean isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
public void setInitialized(boolean initialized) {
|
||||
this.initialized = initialized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Flag<?> flag) throws FlagConflictException {
|
||||
synchronized (lock) {
|
||||
if (initialized) {
|
||||
throw new IllegalStateException("New flags cannot be registered at this time");
|
||||
}
|
||||
|
||||
forceRegister(flag);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerAll(Collection<Flag<?>> flags) {
|
||||
synchronized (lock) {
|
||||
for (Flag<?> flag : flags) {
|
||||
try {
|
||||
register(flag);
|
||||
} catch (FlagConflictException e) {
|
||||
log.log(Level.WARNING, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Flag<?> forceRegister(Flag<?> flag) throws FlagConflictException {
|
||||
checkNotNull(flag, "flag");
|
||||
checkNotNull(flag.getName(), "flag.getName()");
|
||||
|
||||
synchronized (lock) {
|
||||
String name = flag.getName().toLowerCase();
|
||||
if (flags.containsKey(name)) {
|
||||
throw new FlagConflictException("A flag already exists by the name " + name);
|
||||
}
|
||||
|
||||
flags.put(name, flag);
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Flag<?> get(String name) {
|
||||
checkNotNull(name, "name");
|
||||
return flags.get(name.toLowerCase());
|
||||
}
|
||||
|
||||
private Flag<?> getOrCreate(String name) {
|
||||
Flag<?> flag = get(name);
|
||||
|
||||
if (flag != null) {
|
||||
return flag;
|
||||
}
|
||||
|
||||
synchronized (lock) {
|
||||
flag = get(name); // Load again because the previous load was not synchronized
|
||||
return flag != null ? flag : forceRegister(new UnknownFlag(name));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Flag<?>, Object> unmarshal(Map<String, Object> rawValues, boolean createUnknown) {
|
||||
checkNotNull(rawValues, "rawValues");
|
||||
|
||||
ConcurrentMap<Flag<?>, Object> values = Maps.newConcurrentMap();
|
||||
ConcurrentMap<String, Object> regionFlags = Maps.newConcurrentMap();
|
||||
|
||||
for (Entry<String, Object> entry : rawValues.entrySet()) {
|
||||
if (entry.getKey().endsWith("-group")) {
|
||||
regionFlags.put(entry.getKey(), entry.getValue());
|
||||
continue;
|
||||
}
|
||||
Flag<?> flag = createUnknown ? getOrCreate(entry.getKey()) : get(entry.getKey());
|
||||
|
||||
if (flag != null) {
|
||||
try {
|
||||
Object unmarshalled = flag.unmarshal(entry.getValue());
|
||||
|
||||
if (unmarshalled != null) {
|
||||
values.put(flag, unmarshalled);
|
||||
} else {
|
||||
log.warning("Failed to parse flag '" + flag.getName() + "' with value '" + entry.getValue() + "'");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.log(Level.WARNING, "Failed to unmarshal flag value for " + flag, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Entry<String, Object> entry : regionFlags.entrySet()) {
|
||||
String parentName = entry.getKey().replaceAll("-group", "");
|
||||
Flag<?> parent = get(parentName);
|
||||
if (parent == null || parent instanceof UnknownFlag) {
|
||||
if (createUnknown) forceRegister(new UnknownFlag(entry.getKey()));
|
||||
} else {
|
||||
values.put(parent.getRegionGroupFlag(), parent.getRegionGroupFlag().unmarshal(entry.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return flags.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Flag<?>> iterator() {
|
||||
return Iterators.unmodifiableIterator(flags.values().iterator());
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.flags.registry;
|
||||
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.FlagContext;
|
||||
import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class UnknownFlag extends Flag<Object> {
|
||||
|
||||
public UnknownFlag(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parseInput(FlagContext context) throws InvalidFlagFormat {
|
||||
throw new InvalidFlagFormat("The plugin that registered this flag is not currently installed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object unmarshal(@Nullable Object o) {
|
||||
return o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object marshal(Object o) {
|
||||
return o;
|
||||
}
|
||||
|
||||
}
|
||||
+8
-12
@@ -20,6 +20,7 @@
|
||||
package com.sk89q.worldguard.protection.managers;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.managers.index.ChunkHashTable;
|
||||
import com.sk89q.worldguard.protection.managers.index.ConcurrentRegionIndex;
|
||||
import com.sk89q.worldguard.protection.managers.index.PriorityRTreeIndex;
|
||||
@@ -29,16 +30,7 @@ import com.sk89q.worldguard.protection.managers.storage.StorageException;
|
||||
import com.sk89q.worldguard.util.Normal;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.logging.Level;
|
||||
@@ -62,6 +54,7 @@ public class RegionContainerImpl {
|
||||
private final RegionDriver driver;
|
||||
private final Supplier<? extends ConcurrentRegionIndex> indexFactory = new ChunkHashTable.Factory(new PriorityRTreeIndex.Factory());
|
||||
private final Timer timer = new Timer();
|
||||
private final FlagRegistry flagRegistry;
|
||||
|
||||
private final Set<Normal> failingLoads = new HashSet<Normal>();
|
||||
private final Set<RegionManager> failingSaves = Collections.synchronizedSet(
|
||||
@@ -71,12 +64,15 @@ public class RegionContainerImpl {
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param driver the region store driver
|
||||
* @param flagRegistry the flag registry
|
||||
*/
|
||||
public RegionContainerImpl(RegionDriver driver) {
|
||||
public RegionContainerImpl(RegionDriver driver, FlagRegistry flagRegistry) {
|
||||
checkNotNull(driver);
|
||||
checkNotNull(flagRegistry, "flagRegistry");
|
||||
this.driver = driver;
|
||||
timer.schedule(new BackgroundLoader(), LOAD_ATTEMPT_INTERVAL, LOAD_ATTEMPT_INTERVAL);
|
||||
timer.schedule(new BackgroundSaver(), SAVE_INTERVAL, SAVE_INTERVAL);
|
||||
this.flagRegistry = flagRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -129,7 +125,7 @@ public class RegionContainerImpl {
|
||||
*/
|
||||
private RegionManager createAndLoad(String name) throws StorageException {
|
||||
RegionDatabase store = driver.get(name);
|
||||
RegionManager manager = new RegionManager(store, indexFactory);
|
||||
RegionManager manager = new RegionManager(store, indexFactory, flagRegistry);
|
||||
manager.load(); // Try loading, although it may fail
|
||||
return manager;
|
||||
}
|
||||
|
||||
+18
-14
@@ -27,6 +27,7 @@ import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.RegionResultSet;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.managers.index.ConcurrentRegionIndex;
|
||||
import com.sk89q.worldguard.protection.managers.index.RegionIndex;
|
||||
import com.sk89q.worldguard.protection.managers.storage.DifferenceSaveException;
|
||||
@@ -37,14 +38,7 @@ import com.sk89q.worldguard.protection.util.RegionCollectionConsumer;
|
||||
import com.sk89q.worldguard.util.Normal;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@@ -57,6 +51,7 @@ public final class RegionManager {
|
||||
|
||||
private final RegionDatabase store;
|
||||
private final Supplier<? extends ConcurrentRegionIndex> indexFactory;
|
||||
private final FlagRegistry flagRegistry;
|
||||
private ConcurrentRegionIndex index;
|
||||
|
||||
/**
|
||||
@@ -64,14 +59,17 @@ public final class RegionManager {
|
||||
*
|
||||
* @param store the region store
|
||||
* @param indexFactory the factory for creating new instances of the index
|
||||
* @param flagRegistry the flag registry
|
||||
*/
|
||||
public RegionManager(RegionDatabase store, Supplier<? extends ConcurrentRegionIndex> indexFactory) {
|
||||
public RegionManager(RegionDatabase store, Supplier<? extends ConcurrentRegionIndex> indexFactory, FlagRegistry flagRegistry) {
|
||||
checkNotNull(store);
|
||||
checkNotNull(indexFactory);
|
||||
checkNotNull(flagRegistry, "flagRegistry");
|
||||
|
||||
this.store = store;
|
||||
this.indexFactory = indexFactory;
|
||||
this.index = indexFactory.get();
|
||||
this.flagRegistry = flagRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,7 +91,7 @@ public final class RegionManager {
|
||||
* @throws StorageException thrown when loading fails
|
||||
*/
|
||||
public void load() throws StorageException {
|
||||
Set<ProtectedRegion> regions = store.loadAll();
|
||||
Set<ProtectedRegion> regions = store.loadAll(flagRegistry);
|
||||
for (ProtectedRegion region : regions) {
|
||||
region.setDirty(false);
|
||||
}
|
||||
@@ -107,7 +105,7 @@ public final class RegionManager {
|
||||
*/
|
||||
public void save() throws StorageException {
|
||||
index.setDirty(false);
|
||||
store.saveAll(new HashSet<ProtectedRegion>(getValuesCopy()));
|
||||
store.saveAll(new HashSet<ProtectedRegion>(getFilteredValuesCopy()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -424,12 +422,18 @@ public final class RegionManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an {@link ArrayList} copy of regions in the index.
|
||||
* Get an {@link ArrayList} copy of regions in the index with transient regions filtered.
|
||||
*
|
||||
* @return a list
|
||||
*/
|
||||
private List<ProtectedRegion> getValuesCopy() {
|
||||
return new ArrayList<ProtectedRegion>(index.values());
|
||||
private List<ProtectedRegion> getFilteredValuesCopy() {
|
||||
List<ProtectedRegion> filteredValues = new ArrayList<ProtectedRegion>();
|
||||
for (ProtectedRegion region : index.values()) {
|
||||
if (!region.isTransient()) {
|
||||
filteredValues.add(region);
|
||||
}
|
||||
}
|
||||
return filteredValues;
|
||||
}
|
||||
|
||||
// =============== HELPER METHODS ===============
|
||||
|
||||
+8
-2
@@ -19,6 +19,8 @@
|
||||
|
||||
package com.sk89q.worldguard.protection.managers.migration;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.managers.storage.RegionDatabase;
|
||||
import com.sk89q.worldguard.protection.managers.storage.RegionDriver;
|
||||
import com.sk89q.worldguard.protection.managers.storage.StorageException;
|
||||
@@ -36,17 +38,21 @@ public class DriverMigration extends AbstractMigration {
|
||||
|
||||
private static final Logger log = Logger.getLogger(DriverMigration.class.getCanonicalName());
|
||||
private final RegionDriver target;
|
||||
private final FlagRegistry flagRegistry;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param driver the source storage driver
|
||||
* @param target the target storage driver
|
||||
* @param flagRegistry the flag registry
|
||||
*/
|
||||
public DriverMigration(RegionDriver driver, RegionDriver target) {
|
||||
public DriverMigration(RegionDriver driver, RegionDriver target, FlagRegistry flagRegistry) {
|
||||
super(driver);
|
||||
checkNotNull(target);
|
||||
Preconditions.checkNotNull(flagRegistry, "flagRegistry");
|
||||
this.target = target;
|
||||
this.flagRegistry = flagRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -56,7 +62,7 @@ public class DriverMigration extends AbstractMigration {
|
||||
log.info("Loading the regions for '" + store.getName() + "' with the old driver...");
|
||||
|
||||
try {
|
||||
regions = store.loadAll();
|
||||
regions = store.loadAll(flagRegistry);
|
||||
} catch (StorageException e) {
|
||||
throw new MigrationException("Failed to load region data for the world '" + store.getName() + "'", e);
|
||||
}
|
||||
|
||||
+8
-8
@@ -24,18 +24,14 @@ import com.sk89q.squirrelid.Profile;
|
||||
import com.sk89q.squirrelid.resolver.ProfileService;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.domains.PlayerDomain;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.managers.storage.RegionDatabase;
|
||||
import com.sk89q.worldguard.protection.managers.storage.RegionDriver;
|
||||
import com.sk89q.worldguard.protection.managers.storage.StorageException;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.logging.Level;
|
||||
@@ -53,6 +49,7 @@ public class UUIDMigration extends AbstractMigration {
|
||||
|
||||
private final Timer timer = new Timer();
|
||||
private final ProfileService profileService;
|
||||
private final FlagRegistry flagRegistry;
|
||||
private final ConcurrentMap<String, UUID> resolvedNames = new ConcurrentHashMap<String, UUID>();
|
||||
private final Set<String> unresolvedNames = new HashSet<String>();
|
||||
private boolean keepUnresolvedNames = true;
|
||||
@@ -62,11 +59,14 @@ public class UUIDMigration extends AbstractMigration {
|
||||
*
|
||||
* @param driver the storage driver
|
||||
* @param profileService the profile service
|
||||
* @param flagRegistry the flag registry
|
||||
*/
|
||||
public UUIDMigration(RegionDriver driver, ProfileService profileService) {
|
||||
public UUIDMigration(RegionDriver driver, ProfileService profileService, FlagRegistry flagRegistry) {
|
||||
super(driver);
|
||||
checkNotNull(profileService);
|
||||
checkNotNull(flagRegistry, "flagRegistry");
|
||||
this.profileService = profileService;
|
||||
this.flagRegistry = flagRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -76,7 +76,7 @@ public class UUIDMigration extends AbstractMigration {
|
||||
Set<ProtectedRegion> regions;
|
||||
|
||||
try {
|
||||
regions = store.loadAll();
|
||||
regions = store.loadAll(flagRegistry);
|
||||
} catch (StorageException e) {
|
||||
throw new MigrationException("Failed to load region data for the world '" + store.getName() + "'", e);
|
||||
}
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldguard.protection.managers.storage;
|
||||
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.managers.RegionDifference;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
@@ -42,7 +43,7 @@ public class MemoryRegionDatabase implements RegionDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ProtectedRegion> loadAll() {
|
||||
public Set<ProtectedRegion> loadAll(FlagRegistry flagRegistry) {
|
||||
return regions;
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldguard.protection.managers.storage;
|
||||
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.managers.RegionDifference;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
@@ -53,10 +54,11 @@ public interface RegionDatabase {
|
||||
* {@code get()} and {@code put()} calls in order to maximize performance.
|
||||
* </p>
|
||||
*
|
||||
* @param flags a flag registry
|
||||
* @return a set of loaded regions
|
||||
* @throws StorageException thrown on read error
|
||||
*/
|
||||
Set<ProtectedRegion> loadAll() throws StorageException;
|
||||
Set<ProtectedRegion> loadAll(FlagRegistry flags) throws StorageException;
|
||||
|
||||
/**
|
||||
* Replace all the data in the store with the given collection of regions.
|
||||
|
||||
-59
@@ -19,12 +19,9 @@
|
||||
|
||||
package com.sk89q.worldguard.protection.managers.storage;
|
||||
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -43,62 +40,6 @@ public final class RegionDatabaseUtils {
|
||||
private RegionDatabaseUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Try setting the given map of flags onto the region.
|
||||
*
|
||||
* @param region the region
|
||||
* @param flagData the map of flag data
|
||||
*/
|
||||
public static void trySetFlagMap(ProtectedRegion region, Map<String, Object> flagData) {
|
||||
checkNotNull(region);
|
||||
checkNotNull(flagData);
|
||||
|
||||
for (Flag<?> flag : DefaultFlag.getFlags()) {
|
||||
if (flag == null) {
|
||||
// Some plugins that add custom flags to WorldGuard are doing
|
||||
// something very wrong -- see WORLDGUARD-3094
|
||||
continue;
|
||||
}
|
||||
|
||||
Object o = flagData.get(flag.getName());
|
||||
if (o != null) {
|
||||
RegionDatabaseUtils.trySetFlag(region, flag, o);
|
||||
}
|
||||
|
||||
// Set group
|
||||
if (flag.getRegionGroupFlag() != null) {
|
||||
Object o2 = flagData.get(flag.getRegionGroupFlag().getName());
|
||||
if (o2 != null) {
|
||||
RegionDatabaseUtils.trySetFlag(region, flag.getRegionGroupFlag(), o2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to set a flag on the region.
|
||||
*
|
||||
* @param region the region
|
||||
* @param flag the flag
|
||||
* @param value the value of the flag, which may be {@code null}
|
||||
* @param <T> the flag's type
|
||||
* @return true if the set succeeded
|
||||
*/
|
||||
public static <T> boolean trySetFlag(ProtectedRegion region, Flag<T> flag, @Nullable Object value) {
|
||||
checkNotNull(region);
|
||||
checkNotNull(flag);
|
||||
|
||||
T val = flag.unmarshal(value);
|
||||
|
||||
if (val != null) {
|
||||
region.setFlag(flag, val);
|
||||
return true;
|
||||
} else {
|
||||
log.warning("Failed to parse flag '" + flag.getName() + "' with value '" + value + "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-link parent regions on each provided region using the two
|
||||
* provided maps.
|
||||
|
||||
+10
-33
@@ -26,7 +26,8 @@ import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.BlockVector2D;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
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;
|
||||
@@ -45,15 +46,7 @@ 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.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -97,8 +90,8 @@ public class YamlRegionFile implements RegionDatabase {
|
||||
* @param file the file
|
||||
*/
|
||||
public YamlRegionFile(String name, File file) {
|
||||
checkNotNull(name);
|
||||
checkNotNull(file);
|
||||
checkNotNull(name, "name");
|
||||
checkNotNull(file, "file");
|
||||
this.name = name;
|
||||
this.file = file;
|
||||
}
|
||||
@@ -109,7 +102,7 @@ public class YamlRegionFile implements RegionDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ProtectedRegion> loadAll() throws StorageException {
|
||||
public Set<ProtectedRegion> loadAll(FlagRegistry flagRegistry) throws StorageException {
|
||||
Map<String, ProtectedRegion> loaded = new HashMap<String, ProtectedRegion>();
|
||||
|
||||
YAMLProcessor config = createYamlProcessor(file);
|
||||
@@ -162,7 +155,7 @@ public class YamlRegionFile implements RegionDatabase {
|
||||
|
||||
Integer priority = checkNotNull(node.getInt("priority"));
|
||||
region.setPriority(priority);
|
||||
setFlags(region, node.getNode("flags"));
|
||||
setFlags(flagRegistry, region, node.getNode("flags"));
|
||||
region.setOwners(parseDomain(node.getNode("owners")));
|
||||
region.setMembers(parseDomain(node.getNode("members")));
|
||||
|
||||
@@ -287,31 +280,15 @@ public class YamlRegionFile implements RegionDatabase {
|
||||
}
|
||||
|
||||
private Map<String, Object> getFlagData(ProtectedRegion region) {
|
||||
Map<String, Object> flagData = new HashMap<String, Object>();
|
||||
|
||||
for (Map.Entry<Flag<?>, Object> entry : region.getFlags().entrySet()) {
|
||||
Flag<?> flag = entry.getKey();
|
||||
addMarshalledFlag(flagData, flag, entry.getValue());
|
||||
}
|
||||
|
||||
return flagData;
|
||||
return Flags.marshal(region.getFlags());
|
||||
}
|
||||
|
||||
private void setFlags(ProtectedRegion region, YAMLNode flagsData) {
|
||||
private void setFlags(FlagRegistry flagRegistry, ProtectedRegion region, YAMLNode flagsData) {
|
||||
if (flagsData != null) {
|
||||
RegionDatabaseUtils.trySetFlagMap(region, flagsData.getMap());
|
||||
region.setFlags(flagRegistry.unmarshal(flagsData.getMap(), true));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <V> void addMarshalledFlag(Map<String, Object> flagData, Flag<V> flag, Object val) {
|
||||
if (val == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
flagData.put(flag.getName(), flag.marshal((V) val));
|
||||
}
|
||||
|
||||
private Map<String, Object> getDomainData(DefaultDomain domain) {
|
||||
Map<String, Object> domainData = new HashMap<String, Object>();
|
||||
|
||||
|
||||
+7
-7
@@ -27,6 +27,7 @@ import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.BlockVector2D;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
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;
|
||||
@@ -45,6 +46,7 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
@@ -59,17 +61,19 @@ class DataLoader {
|
||||
final Connection conn;
|
||||
final DataSourceConfig config;
|
||||
final int worldId;
|
||||
final FlagRegistry flagRegistry;
|
||||
|
||||
private final Map<String, ProtectedRegion> loaded = new HashMap<String, ProtectedRegion>();
|
||||
private final Map<ProtectedRegion, String> parentSets = new HashMap<ProtectedRegion, String>();
|
||||
private final Yaml yaml = SQLRegionDatabase.createYaml();
|
||||
|
||||
DataLoader(SQLRegionDatabase regionStore, Connection conn) throws SQLException {
|
||||
DataLoader(SQLRegionDatabase regionStore, Connection conn, FlagRegistry flagRegistry) throws SQLException {
|
||||
checkNotNull(regionStore);
|
||||
|
||||
this.conn = conn;
|
||||
this.config = regionStore.getDataSourceConfig();
|
||||
this.worldId = regionStore.getWorldId();
|
||||
this.flagRegistry = flagRegistry;
|
||||
}
|
||||
|
||||
public Set<ProtectedRegion> load() throws SQLException {
|
||||
@@ -239,13 +243,9 @@ class DataLoader {
|
||||
unmarshalFlagValue(rs.getString("value")));
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Map<String, Object>> entry : data.rowMap().entrySet()) {
|
||||
for (Entry<String, Map<String, Object>> entry : data.rowMap().entrySet()) {
|
||||
ProtectedRegion region = loaded.get(entry.getKey());
|
||||
if (region != null) {
|
||||
RegionDatabaseUtils.trySetFlagMap(region, entry.getValue());
|
||||
} else {
|
||||
throw new RuntimeException("An unexpected error occurred (loaded.get() returned null)");
|
||||
}
|
||||
region.setFlags(flagRegistry.unmarshal(entry.getValue(), true));
|
||||
}
|
||||
} finally {
|
||||
closer.closeQuietly();
|
||||
|
||||
+3
-2
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldguard.protection.managers.storage.sql;
|
||||
|
||||
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;
|
||||
@@ -198,7 +199,7 @@ class SQLRegionDatabase implements RegionDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ProtectedRegion> loadAll() throws StorageException {
|
||||
public Set<ProtectedRegion> loadAll(FlagRegistry flagRegistry) throws StorageException {
|
||||
initialize();
|
||||
|
||||
Closer closer = Closer.create();
|
||||
@@ -206,7 +207,7 @@ class SQLRegionDatabase implements RegionDatabase {
|
||||
|
||||
try {
|
||||
try {
|
||||
loader = new DataLoader(this, closer.register(getConnection()));
|
||||
loader = new DataLoader(this, closer.register(getConnection()), flagRegistry);
|
||||
} catch (SQLException e) {
|
||||
throw new StorageException("Failed to get a connection to the database", e);
|
||||
}
|
||||
|
||||
+14
-2
@@ -39,12 +39,24 @@ import java.util.List;
|
||||
public class GlobalProtectedRegion extends ProtectedRegion {
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
* 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 ID
|
||||
*/
|
||||
public GlobalProtectedRegion(String id) {
|
||||
super(id);
|
||||
this(id, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param id the ID
|
||||
* @param transientRegion whether this region should only be kept in memory and not be saved
|
||||
*/
|
||||
public GlobalProtectedRegion(String id, boolean transientRegion) {
|
||||
super(id, transientRegion);
|
||||
min = new BlockVector(0, 0, 0);
|
||||
max = new BlockVector(0, 0, 0);
|
||||
}
|
||||
|
||||
+17
-2
@@ -39,14 +39,29 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
public class ProtectedCuboidRegion extends ProtectedRegion {
|
||||
|
||||
/**
|
||||
* Construct a new instance of this cuboid region.
|
||||
* Construct a new instance of this cuboid region.<br>
|
||||
* Equivalent to {@link #ProtectedCuboidRegion(String, boolean, BlockVector, BlockVector)
|
||||
* ProtectedCuboidRegion(id, false, pt1, pt2)}<br>
|
||||
* <code>transientRegion</code> will be set to false, and this region can be saved.
|
||||
*
|
||||
* @param id the region id
|
||||
* @param pt1 the first point of this region
|
||||
* @param pt2 the second point of this region
|
||||
*/
|
||||
public ProtectedCuboidRegion(String id, BlockVector pt1, BlockVector pt2) {
|
||||
super(id);
|
||||
this(id, false, pt1, pt2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance of this cuboid region.
|
||||
*
|
||||
* @param id the region id
|
||||
* @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(String id, boolean transientRegion, BlockVector pt1, BlockVector pt2) {
|
||||
super(id, transientRegion);
|
||||
setMinMaxPoints(pt1, pt2);
|
||||
}
|
||||
|
||||
|
||||
+25
-1
@@ -36,8 +36,32 @@ public class ProtectedPolygonalRegion extends ProtectedRegion {
|
||||
private final int minY;
|
||||
private final int maxY;
|
||||
|
||||
/**
|
||||
* Construct a new instance of this polygonal region.<br>
|
||||
* Equivalent to {@link #ProtectedPolygonalRegion(String, 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 id
|
||||
* @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(String id, List<BlockVector2D> points, int minY, int maxY) {
|
||||
super(id);
|
||||
this(id, false, points, minY, maxY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance of this polygonal region.
|
||||
*
|
||||
* @param id the region id
|
||||
* @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(String id, boolean transientRegion, List<BlockVector2D> points, int minY, int maxY) {
|
||||
super(id, transientRegion);
|
||||
ImmutableList<BlockVector2D> immutablePoints = ImmutableList.copyOf(points);
|
||||
setMinMaxPoints(immutablePoints, minY, maxY);
|
||||
this.points = immutablePoints;
|
||||
|
||||
+17
-1
@@ -56,6 +56,7 @@ public abstract class ProtectedRegion implements ChangeTracked, Comparable<Prote
|
||||
protected BlockVector max;
|
||||
|
||||
private final String id;
|
||||
private final boolean transientRegion;
|
||||
private int priority = 0;
|
||||
private ProtectedRegion parent;
|
||||
private DefaultDomain owners = new DefaultDomain();
|
||||
@@ -67,9 +68,10 @@ public abstract class ProtectedRegion implements ChangeTracked, Comparable<Prote
|
||||
* Construct a new instance of this region.
|
||||
*
|
||||
* @param id the name of 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) { // Package private because we can't have people creating their own region types
|
||||
ProtectedRegion(String id, boolean transientRegion) { // Package private because we can't have people creating their own region types
|
||||
checkNotNull(id);
|
||||
|
||||
if (!isValidId(id)) {
|
||||
@@ -77,6 +79,7 @@ public abstract class ProtectedRegion implements ChangeTracked, Comparable<Prote
|
||||
}
|
||||
|
||||
this.id = Normal.normalize(id);
|
||||
this.transientRegion = transientRegion;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -680,8 +683,21 @@ public abstract class ProtectedRegion implements ChangeTracked, Comparable<Prote
|
||||
*/
|
||||
abstract Area toArea();
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if this region should only be kept in memory and not be saved
|
||||
*/
|
||||
public boolean isTransient() {
|
||||
return transientRegion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if this region is not transient and changes have been made.
|
||||
*/
|
||||
@Override
|
||||
public boolean isDirty() {
|
||||
if (isTransient()) {
|
||||
return false;
|
||||
}
|
||||
return dirty || owners.isDirty() || members.isDirty();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.sk89q.guavabackport.cache.LoadingCache;
|
||||
import com.sk89q.worldguard.bukkit.BukkitUtil;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.session.handler.*;
|
||||
import com.sk89q.worldguard.session.handler.Handler.Factory;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@@ -33,9 +34,14 @@ import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
@@ -77,6 +83,7 @@ public class SessionManager implements Runnable, Listener {
|
||||
public SessionManager(WorldGuardPlugin plugin) {
|
||||
checkNotNull(plugin, "plugin");
|
||||
this.plugin = plugin;
|
||||
handlers.addAll(defaultHandlers);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -129,6 +136,82 @@ public class SessionManager implements Runnable, Listener {
|
||||
}
|
||||
}
|
||||
|
||||
private LinkedList<Factory<? extends Handler>> handlers = new LinkedList<Factory<? extends Handler>>();
|
||||
|
||||
private static final Set<Factory<? extends Handler>> defaultHandlers = new HashSet<Factory<? extends Handler>>();
|
||||
static {
|
||||
Factory<?>[] factories = {
|
||||
FeedFlag.FACTORY,
|
||||
FeedFlag.FACTORY,
|
||||
NotifyEntryFlag.FACTORY,
|
||||
NotifyExitFlag.FACTORY,
|
||||
EntryFlag.FACTORY,
|
||||
ExitFlag.FACTORY,
|
||||
FarewellFlag.FACTORY,
|
||||
GreetingFlag.FACTORY,
|
||||
GameModeFlag.FACTORY,
|
||||
InvincibilityFlag.FACTORY,
|
||||
TimeLockFlag.FACTORY,
|
||||
WeatherLockFlag.FACTORY,
|
||||
GodMode.FACTORY,
|
||||
WaterBreathing.FACTORY
|
||||
};
|
||||
defaultHandlers.addAll(Arrays.asList(factories));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a handler with the SessionManager.
|
||||
*
|
||||
* You may specify another handler class to ensure your handler is always registered after that class.
|
||||
* If that class is not already registered, this method will return false.
|
||||
*
|
||||
* For example, flags that always act on a player in a region (like {@link HealFlag} and {@link FeedFlag})
|
||||
* should be registered earlier, whereas flags that only take effect when a player leaves the region (like
|
||||
* {@link FarewellFlag} and {@link GreetingFlag}) should be registered after the {@link ExitFlag.Factory}.class handler factory.
|
||||
*
|
||||
* @param factory a factory which takes a session and returns an instance of your handler
|
||||
* @param after the handler factory to insert the first handler after, to ensure a specific order when creating new sessions
|
||||
*
|
||||
* @return {@code true} (as specified by {@link Collection#add})
|
||||
* {@code false} if {@param after} is not registered, or {@param factory} is null
|
||||
*/
|
||||
public boolean registerHandler(Factory<? extends Handler> factory, @Nullable Factory<? extends Handler> after) {
|
||||
if (factory == null) return false;
|
||||
WorldGuardPlugin.inst().getLogger().log(Level.INFO, "Registering session handler "
|
||||
+ factory.getClass().getEnclosingClass().getName());
|
||||
if (after == null) {
|
||||
handlers.add(factory);
|
||||
} else {
|
||||
int index = handlers.indexOf(after);
|
||||
if (index == -1) return false;
|
||||
|
||||
handlers.add(index, factory); // shifts "after" right one, and everything after "after" right one
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a handler.
|
||||
*
|
||||
* This will prevent it from being added to newly created sessions only. Existing
|
||||
* sessions with the handler will continue to use it.
|
||||
*
|
||||
* Will return false if the handler was not registered to begin with.
|
||||
*
|
||||
* @param factory the handler factory to unregister
|
||||
* @return true if the handler was registered and is now unregistered, false otherwise
|
||||
*/
|
||||
public boolean unregisterHandler(Factory<? extends Handler> factory) {
|
||||
if (defaultHandlers.contains(factory)) {
|
||||
WorldGuardPlugin.inst().getLogger().log(Level.WARNING, "Someone is unregistering a default WorldGuard handler: "
|
||||
+ factory.getClass().getEnclosingClass().getName() + ". This may cause parts of WorldGuard to stop functioning");
|
||||
} else {
|
||||
WorldGuardPlugin.inst().getLogger().log(Level.INFO, "Unregistering session handler "
|
||||
+ factory.getClass().getEnclosingClass().getName());
|
||||
}
|
||||
return handlers.remove(factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a session for a player.
|
||||
*
|
||||
@@ -137,20 +220,9 @@ public class SessionManager implements Runnable, Listener {
|
||||
*/
|
||||
private Session createSession(Player player) {
|
||||
Session session = new Session(this);
|
||||
session.register(new HealFlag(session));
|
||||
session.register(new FeedFlag(session));
|
||||
session.register(new NotifyEntryFlag(session));
|
||||
session.register(new NotifyExitFlag(session));
|
||||
session.register(new EntryFlag(session));
|
||||
session.register(new ExitFlag(session));
|
||||
session.register(new FarewellFlag(session));
|
||||
session.register(new GreetingFlag(session));
|
||||
session.register(new GameModeFlag(session));
|
||||
session.register(new InvincibilityFlag(session));
|
||||
session.register(new TimeLockFlag(session));
|
||||
session.register(new WeatherLockFlag(session));
|
||||
session.register(new GodMode(session));
|
||||
session.register(new WaterBreathing(session));
|
||||
for (Factory<? extends Handler> factory : handlers) {
|
||||
session.register(factory.create(session));
|
||||
}
|
||||
session.initialize(player);
|
||||
return session;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,14 @@ import java.util.Set;
|
||||
|
||||
public class EntryFlag extends Handler {
|
||||
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static class Factory extends Handler.Factory<EntryFlag> {
|
||||
@Override
|
||||
public EntryFlag create(Session session) {
|
||||
return new EntryFlag(session);
|
||||
}
|
||||
}
|
||||
|
||||
private static final long MESSAGE_THRESHOLD = 1000 * 2;
|
||||
private long lastMessage;
|
||||
|
||||
|
||||
@@ -32,6 +32,14 @@ import org.bukkit.entity.Player;
|
||||
|
||||
public class ExitFlag extends FlagValueChangeHandler<State> {
|
||||
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static class Factory extends Handler.Factory<ExitFlag> {
|
||||
@Override
|
||||
public ExitFlag create(Session session) {
|
||||
return new ExitFlag(session);
|
||||
}
|
||||
}
|
||||
|
||||
private static final long MESSAGE_THRESHOLD = 1000 * 2;
|
||||
private String storedMessage;
|
||||
private boolean exitViaTeleport = false;
|
||||
|
||||
@@ -34,6 +34,14 @@ import java.util.Set;
|
||||
|
||||
public class FarewellFlag extends Handler {
|
||||
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static class Factory extends Handler.Factory<FarewellFlag> {
|
||||
@Override
|
||||
public FarewellFlag create(Session session) {
|
||||
return new FarewellFlag(session);
|
||||
}
|
||||
}
|
||||
|
||||
private Set<String> lastMessageStack = Collections.emptySet();
|
||||
|
||||
public FarewellFlag(Session session) {
|
||||
|
||||
@@ -28,6 +28,14 @@ import org.bukkit.entity.Player;
|
||||
|
||||
public class FeedFlag extends Handler {
|
||||
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static class Factory extends Handler.Factory<FeedFlag> {
|
||||
@Override
|
||||
public FeedFlag create(Session session) {
|
||||
return new FeedFlag(session);
|
||||
}
|
||||
}
|
||||
|
||||
private long lastFeed = 0;
|
||||
|
||||
public FeedFlag(Session session) {
|
||||
|
||||
@@ -32,6 +32,14 @@ import javax.annotation.Nullable;
|
||||
|
||||
public class GameModeFlag extends FlagValueChangeHandler<GameMode> {
|
||||
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static class Factory extends Handler.Factory<GameModeFlag> {
|
||||
@Override
|
||||
public GameModeFlag create(Session session) {
|
||||
return new GameModeFlag(session);
|
||||
}
|
||||
}
|
||||
|
||||
private GameMode originalGameMode;
|
||||
private GameMode setGameMode;
|
||||
|
||||
|
||||
@@ -29,6 +29,14 @@ import javax.annotation.Nullable;
|
||||
|
||||
public class GodMode extends Handler {
|
||||
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static class Factory extends Handler.Factory<GodMode> {
|
||||
@Override
|
||||
public GodMode create(Session session) {
|
||||
return new GodMode(session);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean godMode;
|
||||
|
||||
public GodMode(Session session) {
|
||||
|
||||
@@ -35,6 +35,14 @@ import java.util.Set;
|
||||
|
||||
public class GreetingFlag extends Handler {
|
||||
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static class Factory extends Handler.Factory<GreetingFlag> {
|
||||
@Override
|
||||
public GreetingFlag create(Session session) {
|
||||
return new GreetingFlag(session);
|
||||
}
|
||||
}
|
||||
|
||||
private Set<String> lastMessageStack = Collections.emptySet();
|
||||
|
||||
public GreetingFlag(Session session) {
|
||||
|
||||
@@ -39,6 +39,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
*/
|
||||
public abstract class Handler {
|
||||
|
||||
public static abstract class Factory<T extends Handler> {
|
||||
public abstract T create(Session session);
|
||||
}
|
||||
|
||||
private final Session session;
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,14 @@ import org.bukkit.entity.Player;
|
||||
|
||||
public class HealFlag extends Handler {
|
||||
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static class Factory extends Handler.Factory<HealFlag> {
|
||||
@Override
|
||||
public HealFlag create(Session session) {
|
||||
return new HealFlag(session);
|
||||
}
|
||||
}
|
||||
|
||||
private long lastHeal = 0;
|
||||
|
||||
public HealFlag(Session session) {
|
||||
|
||||
+8
@@ -31,6 +31,14 @@ import javax.annotation.Nullable;
|
||||
|
||||
public class InvincibilityFlag extends FlagValueChangeHandler<State> {
|
||||
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static class Factory extends Handler.Factory<InvincibilityFlag> {
|
||||
@Override
|
||||
public InvincibilityFlag create(Session session) {
|
||||
return new InvincibilityFlag(session);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private State invincibility;
|
||||
|
||||
|
||||
+8
@@ -30,6 +30,14 @@ import org.bukkit.entity.Player;
|
||||
|
||||
public class NotifyEntryFlag extends FlagValueChangeHandler<Boolean> {
|
||||
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static class Factory extends Handler.Factory<NotifyEntryFlag> {
|
||||
@Override
|
||||
public NotifyEntryFlag create(Session session) {
|
||||
return new NotifyEntryFlag(session);
|
||||
}
|
||||
}
|
||||
|
||||
public NotifyEntryFlag(Session session) {
|
||||
super(session, DefaultFlag.NOTIFY_ENTER);
|
||||
}
|
||||
|
||||
+8
@@ -29,6 +29,14 @@ import org.bukkit.entity.Player;
|
||||
|
||||
public class NotifyExitFlag extends FlagValueChangeHandler<Boolean> {
|
||||
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static class Factory extends Handler.Factory<NotifyExitFlag> {
|
||||
@Override
|
||||
public NotifyExitFlag create(Session session) {
|
||||
return new NotifyExitFlag(session);
|
||||
}
|
||||
}
|
||||
|
||||
private Boolean notifiedForLeave = false;
|
||||
|
||||
public NotifyExitFlag(Session session) {
|
||||
|
||||
@@ -31,6 +31,14 @@ import java.util.regex.Pattern;
|
||||
|
||||
public class TimeLockFlag extends FlagValueChangeHandler<String> {
|
||||
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static class Factory extends Handler.Factory<TimeLockFlag> {
|
||||
@Override
|
||||
public TimeLockFlag create(Session session) {
|
||||
return new TimeLockFlag(session);
|
||||
}
|
||||
}
|
||||
|
||||
private Long initialTime;
|
||||
private boolean initialRelative;
|
||||
|
||||
|
||||
+8
@@ -24,6 +24,14 @@ import org.bukkit.entity.Player;
|
||||
|
||||
public class WaterBreathing extends Handler {
|
||||
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static class Factory extends Handler.Factory<WaterBreathing> {
|
||||
@Override
|
||||
public WaterBreathing create(Session session) {
|
||||
return new WaterBreathing(session);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean waterBreathing;
|
||||
|
||||
public WaterBreathing(Session session) {
|
||||
|
||||
+8
@@ -31,6 +31,14 @@ import javax.annotation.Nullable;
|
||||
|
||||
public class WeatherLockFlag extends FlagValueChangeHandler<WeatherType> {
|
||||
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static class Factory extends Handler.Factory<WeatherLockFlag> {
|
||||
@Override
|
||||
public WeatherLockFlag create(Session session) {
|
||||
return new WeatherLockFlag(session);
|
||||
}
|
||||
}
|
||||
|
||||
private WeatherType initialWeather;
|
||||
|
||||
public WeatherLockFlag(Session session) {
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ public class HashMapIndexPriorityTest extends RegionPriorityTest {
|
||||
|
||||
@Override
|
||||
protected RegionManager createRegionManager() throws Exception {
|
||||
return new RegionManager(new MemoryRegionDatabase(), new HashMapIndex.Factory());
|
||||
return new RegionManager(new MemoryRegionDatabase(), new HashMapIndex.Factory(), getFlagRegistry());
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -27,7 +27,7 @@ public class HashMapIndexRegionOverlapTest extends RegionOverlapTest {
|
||||
|
||||
@Override
|
||||
protected RegionManager createRegionManager() throws Exception {
|
||||
return new RegionManager(new MemoryRegionDatabase(), new HashMapIndex.Factory());
|
||||
return new RegionManager(new MemoryRegionDatabase(), new HashMapIndex.Factory(), getFlagRegistry());
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -19,15 +19,15 @@
|
||||
|
||||
package com.sk89q.worldguard.protection;
|
||||
|
||||
import com.sk89q.worldguard.protection.managers.index.HashMapIndex;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.managers.index.HashMapIndex;
|
||||
import com.sk89q.worldguard.protection.managers.storage.MemoryRegionDatabase;
|
||||
|
||||
public class HashMapIndexTest extends RegionOverlapTest {
|
||||
|
||||
@Override
|
||||
protected RegionManager createRegionManager() throws Exception {
|
||||
return new RegionManager(new MemoryRegionDatabase(), new HashMapIndex.Factory());
|
||||
return new RegionManager(new MemoryRegionDatabase(), new HashMapIndex.Factory(), getFlagRegistry());
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -27,7 +27,7 @@ public class PriorityRTreeIndexTest extends RegionOverlapTest {
|
||||
|
||||
@Override
|
||||
protected RegionManager createRegionManager() throws Exception {
|
||||
return new RegionManager(new MemoryRegionDatabase(), new PriorityRTreeIndex.Factory());
|
||||
return new RegionManager(new MemoryRegionDatabase(), new PriorityRTreeIndex.Factory(), getFlagRegistry());
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -27,7 +27,7 @@ public class PriorityRTreeRegionEntryExitTest extends RegionEntryExitTest {
|
||||
|
||||
@Override
|
||||
protected RegionManager createRegionManager() throws Exception {
|
||||
return new RegionManager(new MemoryRegionDatabase(), new PriorityRTreeIndex.Factory());
|
||||
return new RegionManager(new MemoryRegionDatabase(), new PriorityRTreeIndex.Factory(), getFlagRegistry());
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -27,7 +27,7 @@ public class PriorityRTreeRegionOverlapTest extends RegionOverlapTest {
|
||||
|
||||
@Override
|
||||
protected RegionManager createRegionManager() throws Exception {
|
||||
return new RegionManager(new MemoryRegionDatabase(), new PriorityRTreeIndex.Factory());
|
||||
return new RegionManager(new MemoryRegionDatabase(), new PriorityRTreeIndex.Factory(), getFlagRegistry());
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -27,7 +27,7 @@ public class PriorityRTreeRegionPriorityTest extends RegionPriorityTest {
|
||||
|
||||
@Override
|
||||
protected RegionManager createRegionManager() throws Exception {
|
||||
return new RegionManager(new MemoryRegionDatabase(), new PriorityRTreeIndex.Factory());
|
||||
return new RegionManager(new MemoryRegionDatabase(), new PriorityRTreeIndex.Factory(), getFlagRegistry());
|
||||
}
|
||||
|
||||
}
|
||||
+8
@@ -26,6 +26,8 @@ import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.flags.RegionGroup;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
@@ -53,6 +55,12 @@ public abstract class RegionEntryExitTest {
|
||||
TestPlayer vipPlayer;
|
||||
TestPlayer builderPlayer;
|
||||
|
||||
protected FlagRegistry getFlagRegistry() {
|
||||
FlagRegistry registry = new SimpleFlagRegistry();
|
||||
registry.registerAll(DefaultFlag.getDefaultFlags());
|
||||
return registry;
|
||||
}
|
||||
|
||||
protected abstract RegionManager createRegionManager() throws Exception;
|
||||
|
||||
@Before
|
||||
|
||||
+16
-9
@@ -19,15 +19,6 @@
|
||||
|
||||
package com.sk89q.worldguard.protection;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.BlockVector2D;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
@@ -35,11 +26,21 @@ import com.sk89q.worldguard.TestPlayer;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry;
|
||||
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 org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public abstract class RegionOverlapTest {
|
||||
static String COURTYARD_ID = "courtyard";
|
||||
@@ -58,6 +59,12 @@ public abstract class RegionOverlapTest {
|
||||
ProtectedRegion fountain;
|
||||
TestPlayer player1;
|
||||
TestPlayer player2;
|
||||
|
||||
protected FlagRegistry getFlagRegistry() {
|
||||
FlagRegistry registry = new SimpleFlagRegistry();
|
||||
registry.registerAll(DefaultFlag.getDefaultFlags());
|
||||
return registry;
|
||||
}
|
||||
|
||||
protected abstract RegionManager createRegionManager() throws Exception;
|
||||
|
||||
|
||||
+8
@@ -26,6 +26,8 @@ import com.sk89q.worldguard.TestPlayer;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
@@ -55,6 +57,12 @@ public abstract class RegionPriorityTest {
|
||||
ProtectedRegion fountain;
|
||||
TestPlayer player1;
|
||||
TestPlayer player2;
|
||||
|
||||
protected FlagRegistry getFlagRegistry() {
|
||||
FlagRegistry registry = new SimpleFlagRegistry();
|
||||
registry.registerAll(DefaultFlag.getDefaultFlags());
|
||||
return registry;
|
||||
}
|
||||
|
||||
protected abstract RegionManager createRegionManager() throws Exception;
|
||||
|
||||
|
||||
Reference in new issue
Block a user