geforkt von Mirrors/FastAsyncWorldEdit
Implement region blacklisting
Dieser Commit ist enthalten in:
Ursprung
f0880a27a0
Commit
7d894228d0
@ -1,42 +0,0 @@
|
|||||||
package com.fastasyncworldedit.bukkit.filter;
|
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.regions.filter.CuboidRegionFilter;
|
|
||||||
import com.fastasyncworldedit.core.util.TaskManager;
|
|
||||||
import com.flowpowered.math.vector.Vector3i;
|
|
||||||
import com.griefdefender.api.GriefDefender;
|
|
||||||
import com.griefdefender.api.claim.Claim;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
|
||||||
import org.bukkit.World;
|
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
public class GriefDefenderFilter extends CuboidRegionFilter {
|
|
||||||
|
|
||||||
private final Collection<Claim> claims;
|
|
||||||
private final World world;
|
|
||||||
|
|
||||||
public GriefDefenderFilter(World world) {
|
|
||||||
checkNotNull(world);
|
|
||||||
this.claims = TaskManager.IMP.sync(
|
|
||||||
(Supplier<Collection<Claim>>) () -> new ArrayDeque<>(GriefDefender.getCore().getAllClaims()));
|
|
||||||
this.world = world;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void calculateRegions() {
|
|
||||||
for (Claim claim : claims) {
|
|
||||||
Vector3i bot = claim.getGreaterBoundaryCorner();
|
|
||||||
if (world.getUID().equals(claim.getWorldUniqueId())) {
|
|
||||||
Vector3i top = claim.getGreaterBoundaryCorner();
|
|
||||||
BlockVector2 pos1 = BlockVector2.at(bot.getX(), bot.getZ());
|
|
||||||
BlockVector2 pos2 = BlockVector2.at(top.getX(), top.getZ());
|
|
||||||
add(pos1, pos2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
package com.fastasyncworldedit.bukkit.filter;
|
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.regions.filter.CuboidRegionFilter;
|
|
||||||
import com.fastasyncworldedit.core.util.TaskManager;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
|
||||||
import me.ryanhamshire.GriefPrevention.Claim;
|
|
||||||
import me.ryanhamshire.GriefPrevention.GriefPrevention;
|
|
||||||
import org.bukkit.World;
|
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
public class GriefPreventionFilter extends CuboidRegionFilter {
|
|
||||||
|
|
||||||
private final Collection<Claim> claims;
|
|
||||||
private final World world;
|
|
||||||
|
|
||||||
public GriefPreventionFilter(World world) {
|
|
||||||
checkNotNull(world);
|
|
||||||
this.claims = TaskManager.IMP.sync(
|
|
||||||
(Supplier<Collection<Claim>>) () -> new ArrayDeque<>(GriefPrevention.instance.dataStore.getClaims()));
|
|
||||||
this.world = world;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void calculateRegions() {
|
|
||||||
for (Claim claim : claims) {
|
|
||||||
org.bukkit.Location bot = claim.getGreaterBoundaryCorner();
|
|
||||||
if (world.equals(bot.getWorld())) {
|
|
||||||
org.bukkit.Location top = claim.getGreaterBoundaryCorner();
|
|
||||||
BlockVector2 pos1 = BlockVector2.at(bot.getBlockX(), bot.getBlockZ());
|
|
||||||
BlockVector2 pos2 = BlockVector2.at(top.getBlockX(), top.getBlockZ());
|
|
||||||
add(pos1, pos2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
package com.fastasyncworldedit.bukkit.filter;
|
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.Fawe;
|
|
||||||
import com.fastasyncworldedit.core.regions.filter.CuboidRegionFilter;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
|
||||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
|
||||||
import com.sk89q.worldguard.WorldGuard;
|
|
||||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
|
||||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
|
||||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
|
||||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.bukkit.World;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
public class WorldGuardFilter extends CuboidRegionFilter {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
|
||||||
|
|
||||||
private final World world;
|
|
||||||
private boolean large;
|
|
||||||
private RegionManager manager;
|
|
||||||
|
|
||||||
public WorldGuardFilter(World world) {
|
|
||||||
checkNotNull(world);
|
|
||||||
this.world = world;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void calculateRegions() {
|
|
||||||
Fawe.get().getQueueHandler().sync(() -> {
|
|
||||||
WorldGuardFilter.this.manager = WorldGuard.getInstance().getPlatform().getRegionContainer().get(
|
|
||||||
BukkitAdapter.adapt(world));
|
|
||||||
for (ProtectedRegion region : manager.getRegions().values()) {
|
|
||||||
BlockVector3 min = region.getMinimumPoint();
|
|
||||||
BlockVector3 max = region.getMaximumPoint();
|
|
||||||
if (max.getBlockX() - min.getBlockX() > 1024 || max.getBlockZ() - min.getBlockZ() > 1024) {
|
|
||||||
LOGGER.info("Large or complex region shapes cannot be optimized. Filtering will be slower");
|
|
||||||
large = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
add(min.toBlockVector2(), max.toBlockVector2());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean containsChunk(int chunkX, int chunkZ) {
|
|
||||||
if (!large) {
|
|
||||||
return super.containsChunk(chunkX, chunkZ);
|
|
||||||
}
|
|
||||||
BlockVector3 pos1 = BlockVector3.at(chunkX << 4, 0, chunkZ << 4);
|
|
||||||
BlockVector3 pos2 = BlockVector3.at(pos1.getBlockX() + 15, 255, pos1.getBlockZ() + 15);
|
|
||||||
ProtectedCuboidRegion chunkRegion = new ProtectedCuboidRegion("unimportant", pos1, pos2);
|
|
||||||
ApplicableRegionSet set = manager.getApplicableRegions(chunkRegion);
|
|
||||||
return set.size() > 0 && !set.getRegions().iterator().next().getId().equals("__global__");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean containsRegion(int mcaX, int mcaZ) {
|
|
||||||
if (!large) {
|
|
||||||
return super.containsRegion(mcaX, mcaZ);
|
|
||||||
}
|
|
||||||
BlockVector3 pos1 = BlockVector3.at(mcaX << 9, 0, mcaZ << 9);
|
|
||||||
BlockVector3 pos2 = BlockVector3.at(pos1.getBlockX() + 511, 255, pos1.getBlockZ() + 511);
|
|
||||||
ProtectedCuboidRegion regionRegion = new ProtectedCuboidRegion("unimportant", pos1, pos2);
|
|
||||||
ApplicableRegionSet set = manager.getApplicableRegions(regionRegion);
|
|
||||||
return set.size() > 0 && !set.getRegions().iterator().next().getId().equals("__global__");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,8 +1,6 @@
|
|||||||
package com.fastasyncworldedit.bukkit.regions;
|
package com.fastasyncworldedit.bukkit.regions;
|
||||||
|
|
||||||
import com.fastasyncworldedit.bukkit.filter.GriefDefenderFilter;
|
|
||||||
import com.fastasyncworldedit.core.regions.FaweMask;
|
import com.fastasyncworldedit.core.regions.FaweMask;
|
||||||
import com.fastasyncworldedit.core.regions.filter.RegionFilter;
|
|
||||||
import com.flowpowered.math.vector.Vector3i;
|
import com.flowpowered.math.vector.Vector3i;
|
||||||
import com.griefdefender.api.GriefDefender;
|
import com.griefdefender.api.GriefDefender;
|
||||||
import com.griefdefender.api.claim.Claim;
|
import com.griefdefender.api.claim.Claim;
|
||||||
@ -12,7 +10,6 @@ import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
|||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
@ -65,9 +62,4 @@ public class GriefDefenderFeature extends BukkitMaskManager implements Listener
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public RegionFilter getFilter(String world) {
|
|
||||||
return new GriefDefenderFilter(Bukkit.getWorld(world));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package com.fastasyncworldedit.bukkit.regions;
|
package com.fastasyncworldedit.bukkit.regions;
|
||||||
|
|
||||||
import com.fastasyncworldedit.bukkit.filter.GriefPreventionFilter;
|
|
||||||
import com.fastasyncworldedit.core.regions.FaweMask;
|
import com.fastasyncworldedit.core.regions.FaweMask;
|
||||||
import com.fastasyncworldedit.core.regions.filter.RegionFilter;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
@ -10,7 +8,6 @@ import com.sk89q.worldedit.regions.CuboidRegion;
|
|||||||
import me.ryanhamshire.GriefPrevention.Claim;
|
import me.ryanhamshire.GriefPrevention.Claim;
|
||||||
import me.ryanhamshire.GriefPrevention.GriefPrevention;
|
import me.ryanhamshire.GriefPrevention.GriefPrevention;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
@ -61,9 +58,4 @@ public class GriefPreventionFeature extends BukkitMaskManager implements Listene
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public RegionFilter getFilter(String world) {
|
|
||||||
return new GriefPreventionFilter(Bukkit.getWorld(world));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
package com.fastasyncworldedit.bukkit.regions;
|
package com.fastasyncworldedit.bukkit.regions;
|
||||||
|
|
||||||
import com.fastasyncworldedit.bukkit.filter.WorldGuardFilter;
|
|
||||||
import com.fastasyncworldedit.core.regions.FaweMask;
|
import com.fastasyncworldedit.core.regions.FaweMask;
|
||||||
import com.fastasyncworldedit.core.regions.RegionWrapper;
|
import com.fastasyncworldedit.core.regions.RegionWrapper;
|
||||||
import com.fastasyncworldedit.core.regions.filter.RegionFilter;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
@ -11,6 +10,7 @@ import com.sk89q.worldedit.regions.AbstractRegion;
|
|||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.regions.Polygonal2DRegion;
|
import com.sk89q.worldedit.regions.Polygonal2DRegion;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import com.sk89q.worldedit.regions.RegionIntersection;
|
||||||
import com.sk89q.worldguard.LocalPlayer;
|
import com.sk89q.worldguard.LocalPlayer;
|
||||||
import com.sk89q.worldguard.WorldGuard;
|
import com.sk89q.worldguard.WorldGuard;
|
||||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||||
@ -29,12 +29,38 @@ import org.bukkit.entity.Player;
|
|||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class WorldGuardFeature extends BukkitMaskManager implements Listener {
|
public class WorldGuardFeature extends BukkitMaskManager implements Listener {
|
||||||
|
|
||||||
private final WorldGuardPlugin worldguard;
|
|
||||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||||
|
private final WorldGuardPlugin worldguard;
|
||||||
|
|
||||||
|
public WorldGuardFeature(Plugin plugin) {
|
||||||
|
super(plugin.getName());
|
||||||
|
this.worldguard = this.getWorldGuard();
|
||||||
|
LOGGER.info("Plugin 'WorldGuard' found. Using it now.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Region adapt(ProtectedRegion region) {
|
||||||
|
if (region instanceof ProtectedCuboidRegion) {
|
||||||
|
return new CuboidRegion(region.getMinimumPoint(), region.getMaximumPoint());
|
||||||
|
}
|
||||||
|
if (region instanceof GlobalProtectedRegion) {
|
||||||
|
return RegionWrapper.GLOBAL();
|
||||||
|
}
|
||||||
|
if (region instanceof ProtectedPolygonalRegion) {
|
||||||
|
ProtectedPolygonalRegion casted = (ProtectedPolygonalRegion) region;
|
||||||
|
BlockVector3 max = region.getMaximumPoint();
|
||||||
|
BlockVector3 min = region.getMinimumPoint();
|
||||||
|
return new Polygonal2DRegion(null, casted.getPoints(), min.getBlockY(), max.getBlockY());
|
||||||
|
}
|
||||||
|
return new AdaptedRegion(region);
|
||||||
|
}
|
||||||
|
|
||||||
private WorldGuardPlugin getWorldGuard() {
|
private WorldGuardPlugin getWorldGuard() {
|
||||||
final Plugin plugin = Bukkit.getPluginManager().getPlugin("WorldGuard");
|
final Plugin plugin = Bukkit.getPluginManager().getPlugin("WorldGuard");
|
||||||
@ -47,27 +73,21 @@ public class WorldGuardFeature extends BukkitMaskManager implements Listener {
|
|||||||
return (WorldGuardPlugin) plugin;
|
return (WorldGuardPlugin) plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WorldGuardFeature(Plugin plugin) {
|
public Set<ProtectedRegion> getRegions(LocalPlayer player, Location location, boolean isWhitelist) {
|
||||||
super(plugin.getName());
|
|
||||||
this.worldguard = this.getWorldGuard();
|
|
||||||
LOGGER.info("Plugin 'WorldGuard' found. Using it now.");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProtectedRegion getRegion(LocalPlayer player, Location location) {
|
|
||||||
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
|
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
|
||||||
if (container == null) {
|
if (container == null) {
|
||||||
LOGGER.info("Region capability is not enabled for WorldGuard.");
|
LOGGER.info("Region capability is not enabled for WorldGuard.");
|
||||||
return null;
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
RegionManager manager = container.get(BukkitAdapter.adapt(location.getWorld()));
|
RegionManager manager = container.get(BukkitAdapter.adapt(location.getWorld()));
|
||||||
if (manager == null) {
|
if (manager == null) {
|
||||||
LOGGER.info("Region capability is not enabled for that world.");
|
LOGGER.info("Region capability is not enabled for that world.");
|
||||||
return null;
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
final ProtectedRegion global = manager.getRegion("__global__");
|
final ProtectedRegion global = manager.getRegion("__global__");
|
||||||
if (global != null && isAllowed(player, global)) {
|
// If they're allowed and it's a whitelist return, else if they're not allowed and it's a blacklist, return
|
||||||
return global;
|
if (global != null && isAllowed(player, global) == isWhitelist) {
|
||||||
|
return Collections.singleton(global);
|
||||||
}
|
}
|
||||||
final ApplicableRegionSet regions = manager.getApplicableRegions(BlockVector3.at(
|
final ApplicableRegionSet regions = manager.getApplicableRegions(BlockVector3.at(
|
||||||
location.getX(),
|
location.getX(),
|
||||||
@ -75,20 +95,39 @@ public class WorldGuardFeature extends BukkitMaskManager implements Listener {
|
|||||||
location.getZ()
|
location.getZ()
|
||||||
));
|
));
|
||||||
//Merge WorldGuardFlag
|
//Merge WorldGuardFlag
|
||||||
|
if (isWhitelist) {
|
||||||
if (player.hasPermission("fawe.worldguardflag") && !regions.testState(
|
if (player.hasPermission("fawe.worldguardflag") && !regions.testState(
|
||||||
player,
|
player,
|
||||||
Flags.BUILD,
|
Flags.BUILD,
|
||||||
Flags.BLOCK_PLACE,
|
Flags.BLOCK_PLACE,
|
||||||
Flags.BLOCK_BREAK
|
Flags.BLOCK_BREAK
|
||||||
)) {
|
)) {
|
||||||
return null;
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
Set<ProtectedRegion> protectedRegions = new HashSet<>();
|
||||||
for (ProtectedRegion region : regions) {
|
for (ProtectedRegion region : regions) {
|
||||||
if (isAllowed(player, region)) {
|
if (isAllowed(player, region)) {
|
||||||
return region;
|
protectedRegions.add(region);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return Collections.unmodifiableSet(protectedRegions);
|
||||||
|
} else {
|
||||||
|
if (player.hasPermission("fawe.worldguardflag") && !regions.testState(
|
||||||
|
player,
|
||||||
|
Flags.BUILD,
|
||||||
|
Flags.BLOCK_PLACE,
|
||||||
|
Flags.BLOCK_BREAK
|
||||||
|
)) {
|
||||||
|
return ImmutableSet.copyOf(regions.getRegions());
|
||||||
|
}
|
||||||
|
Set<ProtectedRegion> protectedRegions = new HashSet<>();
|
||||||
|
for (ProtectedRegion region : regions) {
|
||||||
|
if (!isAllowed(player, region)) {
|
||||||
|
protectedRegions.add(region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Collections.unmodifiableSet(protectedRegions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAllowed(LocalPlayer localplayer, ProtectedRegion region) {
|
public boolean isAllowed(LocalPlayer localplayer, ProtectedRegion region) {
|
||||||
@ -115,45 +154,45 @@ public class WorldGuardFeature extends BukkitMaskManager implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FaweMask getMask(com.sk89q.worldedit.entity.Player wePlayer, MaskType type) {
|
public FaweMask getMask(com.sk89q.worldedit.entity.Player wePlayer, MaskType type, boolean isWhitelist) {
|
||||||
final Player player = BukkitAdapter.adapt(wePlayer);
|
final Player player = BukkitAdapter.adapt(wePlayer);
|
||||||
final LocalPlayer localplayer = this.worldguard.wrapPlayer(player);
|
final LocalPlayer localplayer = this.worldguard.wrapPlayer(player);
|
||||||
final Location location = player.getLocation();
|
final Location location = player.getLocation();
|
||||||
final ProtectedRegion myregion = this.getRegion(localplayer, location);
|
final Set<ProtectedRegion> regions = this.getRegions(localplayer, location, isWhitelist);
|
||||||
if (myregion != null) {
|
if (!regions.isEmpty()) {
|
||||||
final BlockVector3 pos1;
|
Set<Region> result = new HashSet<>();
|
||||||
final BlockVector3 pos2;
|
for (ProtectedRegion myregion : regions) {
|
||||||
if (myregion.getId().equals("__global__")) {
|
if (myregion.getId().equals("__global__")) {
|
||||||
pos1 = BlockVector3.at(Integer.MIN_VALUE, wePlayer.getWorld().getMinY(), Integer.MIN_VALUE);
|
return new FaweMask(RegionWrapper.GLOBAL()) {
|
||||||
pos2 = BlockVector3.at(Integer.MAX_VALUE, wePlayer.getWorld().getMaxY(), Integer.MAX_VALUE);
|
|
||||||
} else {
|
|
||||||
if (myregion instanceof ProtectedCuboidRegion) {
|
|
||||||
pos1 = myregion.getMinimumPoint();
|
|
||||||
pos2 = myregion.getMaximumPoint();
|
|
||||||
} else {
|
|
||||||
return new FaweMask(adapt(myregion)) {
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid(com.sk89q.worldedit.entity.Player player, MaskType type) {
|
public boolean isValid(com.sk89q.worldedit.entity.Player player, MaskType type) {
|
||||||
return isAllowed(worldguard.wrapPlayer(BukkitAdapter.adapt(player)), myregion);
|
return isAllowed(worldguard.wrapPlayer(BukkitAdapter.adapt(player)), myregion);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
} else {
|
||||||
|
if (myregion instanceof ProtectedCuboidRegion) {
|
||||||
|
result.add(new CuboidRegion(myregion.getMaximumPoint(), myregion.getMaximumPoint()));
|
||||||
|
} else {
|
||||||
|
result.add(adapt(myregion));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new FaweMask(new CuboidRegion(pos1, pos2)) {
|
}
|
||||||
|
return new FaweMask(new RegionIntersection(wePlayer.getWorld(), result)) {
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid(com.sk89q.worldedit.entity.Player player, MaskType type) {
|
public boolean isValid(com.sk89q.worldedit.entity.Player player, MaskType type) {
|
||||||
return isAllowed(worldguard.wrapPlayer(BukkitAdapter.adapt(player)), myregion);
|
final LocalPlayer localplayer = worldguard.wrapPlayer(BukkitAdapter.adapt(player));
|
||||||
|
for (ProtectedRegion myregion : regions) {
|
||||||
|
if (!isAllowed(localplayer, myregion)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public RegionFilter getFilter(String world) {
|
|
||||||
return new WorldGuardFilter(Bukkit.getWorld(world));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class AdaptedRegion extends AbstractRegion {
|
private static class AdaptedRegion extends AbstractRegion {
|
||||||
|
|
||||||
private final ProtectedRegion region;
|
private final ProtectedRegion region;
|
||||||
@ -190,20 +229,4 @@ public class WorldGuardFeature extends BukkitMaskManager implements Listener {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Region adapt(ProtectedRegion region) {
|
|
||||||
if (region instanceof ProtectedCuboidRegion) {
|
|
||||||
return new CuboidRegion(region.getMinimumPoint(), region.getMaximumPoint());
|
|
||||||
}
|
|
||||||
if (region instanceof GlobalProtectedRegion) {
|
|
||||||
return RegionWrapper.GLOBAL();
|
|
||||||
}
|
|
||||||
if (region instanceof ProtectedPolygonalRegion) {
|
|
||||||
ProtectedPolygonalRegion casted = (ProtectedPolygonalRegion) region;
|
|
||||||
BlockVector3 max = region.getMaximumPoint();
|
|
||||||
BlockVector3 min = region.getMinimumPoint();
|
|
||||||
return new Polygonal2DRegion(null, casted.getPoints(), min.getBlockY(), max.getBlockY());
|
|
||||||
}
|
|
||||||
return new AdaptedRegion(region);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
package com.fastasyncworldedit.bukkit.regions.plotsquared;
|
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.regions.filter.CuboidRegionFilter;
|
|
||||||
import com.plotsquared.core.location.Location;
|
|
||||||
import com.plotsquared.core.plot.Plot;
|
|
||||||
import com.plotsquared.core.plot.PlotArea;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
public class PlotRegionFilter extends CuboidRegionFilter {
|
|
||||||
|
|
||||||
private final PlotArea area;
|
|
||||||
|
|
||||||
public PlotRegionFilter(PlotArea area) {
|
|
||||||
checkNotNull(area);
|
|
||||||
this.area = area;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void calculateRegions() {
|
|
||||||
ArrayList<Plot> plots = new ArrayList<>(area.getPlots());
|
|
||||||
for (Plot plot : plots) {
|
|
||||||
Location bottom = plot.getCorners()[0];
|
|
||||||
Location top = plot.getCorners()[1];
|
|
||||||
add(BlockVector2.at(bottom.getX(), bottom.getZ()), BlockVector2.at(top.getX(), top.getZ()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -184,13 +184,4 @@ public class PlotSquaredFeature extends FaweMaskManager {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public RegionFilter getFilter(String world) {
|
|
||||||
PlotArea area = PlotSquared.get().getPlotAreaManager().getPlotArea(world, null);
|
|
||||||
if (area != null) {
|
|
||||||
return new PlotRegionFilter(area);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
package com.fastasyncworldedit.bukkit.regions.plotsquaredv4;
|
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.regions.filter.CuboidRegionFilter;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.object.Location;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
public class PlotRegionFilter extends CuboidRegionFilter {
|
|
||||||
|
|
||||||
private final PlotArea area;
|
|
||||||
|
|
||||||
public PlotRegionFilter(PlotArea area) {
|
|
||||||
checkNotNull(area);
|
|
||||||
this.area = area;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void calculateRegions() {
|
|
||||||
ArrayList<Plot> plots = new ArrayList<>(area.getPlots());
|
|
||||||
for (Plot plot : plots) {
|
|
||||||
Location bottom = plot.getCorners()[0];
|
|
||||||
Location top = plot.getCorners()[1];
|
|
||||||
add(BlockVector2.at(bottom.getX(), bottom.getZ()), BlockVector2.at(top.getX(), top.getZ()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -224,13 +224,4 @@ public class PlotSquaredFeature extends FaweMaskManager {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public RegionFilter getFilter(String world) {
|
|
||||||
PlotArea area = PlotSquared.get().getPlotArea(world, null);
|
|
||||||
if (area != null) {
|
|
||||||
return new PlotRegionFilter(area);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -152,12 +152,24 @@ public class FaweAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a player's allowed WorldEdit region.
|
* Get a player's allowed WorldEdit region(s).
|
||||||
*/
|
*/
|
||||||
public static Region[] getRegions(Player player) {
|
public static Region[] getRegions(Player player) {
|
||||||
return WEManager.IMP.getMask(player);
|
return WEManager.IMP.getMask(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a player's allowed WorldEdit region(s).
|
||||||
|
*
|
||||||
|
* @param player Player to get mask of
|
||||||
|
* @param type Mask type; whether to check if the player is an owner of a member of the regions
|
||||||
|
* @param isWhiteList If searching for whitelist or blacklist regions. True if whitelist
|
||||||
|
* @return array of allowed regions if whitelist, else of disallowed regions.
|
||||||
|
*/
|
||||||
|
public static Region[] getRegions(Player player, FaweMaskManager.MaskType type, boolean isWhiteList) {
|
||||||
|
return WEManager.IMP.getMask(player, type, isWhiteList);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel the edit with the following extent.
|
* Cancel the edit with the following extent.
|
||||||
*
|
*
|
||||||
|
@ -125,6 +125,12 @@ public class Settings extends Config {
|
|||||||
" - OWNER = Players who own the region"
|
" - OWNER = Players who own the region"
|
||||||
})
|
})
|
||||||
public String MODE = "MEMBER";
|
public String MODE = "MEMBER";
|
||||||
|
@Comment({
|
||||||
|
"Allow region blacklists.",
|
||||||
|
" - Currently only implemented for WorldGuard ",
|
||||||
|
" - see region-restrictions-options.worldguard-region-blacklist"
|
||||||
|
})
|
||||||
|
public boolean ALLOW_BLACKLISTS = false;
|
||||||
@Comment({
|
@Comment({
|
||||||
"List of plugin mask managers that should be exclusive. Exclusive managers are not ",
|
"List of plugin mask managers that should be exclusive. Exclusive managers are not ",
|
||||||
"checked for edit restrictions if another manager already allowed an edit, and further ",
|
"checked for edit restrictions if another manager already allowed an edit, and further ",
|
||||||
@ -133,6 +139,16 @@ public class Settings extends Config {
|
|||||||
" - Some custom-implementations in other plugins may override this setting"
|
" - Some custom-implementations in other plugins may override this setting"
|
||||||
})
|
})
|
||||||
public List<String> EXCLUSIVE_MANAGERS = new ArrayList<>(Collections.singleton(("ExamplePlugin")));
|
public List<String> EXCLUSIVE_MANAGERS = new ArrayList<>(Collections.singleton(("ExamplePlugin")));
|
||||||
|
@Comment({
|
||||||
|
"If a worldguard-protected world should be considered as a region blacklist.",
|
||||||
|
" - This will create a blacklist of regions where an edit cannot operate.",
|
||||||
|
" - Useful for a \"freebuild\" worlds with few protected areas.",
|
||||||
|
" - May cause performance loss with large numbers of protected areas.",
|
||||||
|
" - Requires region-restrictions-options.allow-blacklists be true.",
|
||||||
|
" - Will still search for current allowed regions to limit the edit to.",
|
||||||
|
" - Any blacklist regions are likely to override any internal allowed regions."
|
||||||
|
})
|
||||||
|
public boolean WORLDGUARD_REGION_BLACKLIST = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ public class ProvideBindings extends Bindings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Region[] regions(Player player, FaweMaskManager.MaskType type) {
|
public Region[] regions(Player player, FaweMaskManager.MaskType type) {
|
||||||
Region[] regions = player.getCurrentRegions(type);
|
Region[] regions = player.getAllowedRegions(type);
|
||||||
if (regions == null) {
|
if (regions == null) {
|
||||||
throw new IllegalArgumentException(Caption.toString(Caption.of("fawe.error.no.region")));
|
throw new IllegalArgumentException(Caption.toString(Caption.of("fawe.error.no.region")));
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ public class HeightBoundExtent extends FaweRegionExtent {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
if (trimY(set, min, max) | trimNBT(set, this::contains)) {
|
if (trimY(set, min, max, true) | trimNBT(set, this::contains)) {
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -4,88 +4,177 @@ import com.fastasyncworldedit.core.limit.FaweLimit;
|
|||||||
import com.fastasyncworldedit.core.queue.IChunk;
|
import com.fastasyncworldedit.core.queue.IChunk;
|
||||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||||
import com.fastasyncworldedit.core.queue.IChunkSet;
|
import com.fastasyncworldedit.core.queue.IChunkSet;
|
||||||
|
import com.fastasyncworldedit.core.regions.RegionWrapper;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.regions.RegionIntersection;
|
import com.sk89q.worldedit.regions.RegionIntersection;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
public class MultiRegionExtent extends FaweRegionExtent {
|
public class MultiRegionExtent extends FaweRegionExtent {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private final RegionIntersection intersection;
|
private final RegionIntersection intersection;
|
||||||
private final Region[] regions;
|
@Nullable
|
||||||
|
private final RegionIntersection disallowedIntersection;
|
||||||
|
@Nullable
|
||||||
|
private final Region[] allowed;
|
||||||
|
@Nullable
|
||||||
|
private final Region[] disallowed;
|
||||||
|
@Nullable
|
||||||
private Region region;
|
private Region region;
|
||||||
private int index;
|
private int index;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance.
|
* Create a new instance. Has both allowed and disallowed regions. Assumes that disallowed regions are encompassed by
|
||||||
|
* allowed regions.
|
||||||
*
|
*
|
||||||
* @param extent the extent
|
* @param extent the extent
|
||||||
|
* @param limit the limit to be used
|
||||||
|
* @param allowed the allowed regions or null for global editing
|
||||||
|
* @param disallowed the disallowed regions or null for no disallowed regions
|
||||||
*/
|
*/
|
||||||
public MultiRegionExtent(Extent extent, FaweLimit limit, Region[] regions) {
|
public MultiRegionExtent(Extent extent, FaweLimit limit, @Nullable Region[] allowed, @Nullable Region[] disallowed) {
|
||||||
super(extent, limit);
|
super(extent, limit);
|
||||||
this.index = 0;
|
this.index = 0;
|
||||||
this.region = regions[0];
|
if (allowed != null && !allowed[0].isGlobal()) {
|
||||||
this.regions = regions;
|
this.region = allowed[0];
|
||||||
this.intersection = new RegionIntersection(Arrays.asList(regions));
|
this.allowed = allowed;
|
||||||
|
this.intersection = new RegionIntersection(Arrays.asList(allowed));
|
||||||
|
} else {
|
||||||
|
this.region = null;
|
||||||
|
this.allowed = null;
|
||||||
|
this.intersection = null;
|
||||||
|
}
|
||||||
|
if (disallowed != null && disallowed.length > 0) {
|
||||||
|
this.disallowed = disallowed;
|
||||||
|
this.disallowedIntersection = new RegionIntersection(Arrays.asList(disallowed));
|
||||||
|
} else {
|
||||||
|
this.disallowed = null;
|
||||||
|
this.disallowedIntersection = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean contains(int x, int y, int z) {
|
public boolean contains(int x, int y, int z) {
|
||||||
if (region.contains(x, y, z)) {
|
if (region != null && region.contains(x, y, z)) {
|
||||||
|
if (disallowed != null) {
|
||||||
|
for (final Region disallow : disallowed) {
|
||||||
|
if (disallow.contains(x, y, z)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < regions.length; i++) {
|
boolean result = allowed == null;
|
||||||
|
if (!result) {
|
||||||
|
for (int i = 0; i < allowed.length; i++) {
|
||||||
if (i != index) {
|
if (i != index) {
|
||||||
Region current = regions[i];
|
Region current = allowed[i];
|
||||||
if (current.contains(x, y, z)) {
|
if (current.contains(x, y, z)) {
|
||||||
region = current;
|
region = current;
|
||||||
index = i;
|
index = i;
|
||||||
return true;
|
result = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (!result || disallowed == null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
for (final Region disallow : disallowed) {
|
||||||
|
if (disallow.contains(x, y, z)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public boolean processGet(int chunkX, int chunkZ) {
|
|
||||||
for (Region region : regions) {
|
|
||||||
if (region.containsChunk(chunkX, chunkZ)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean contains(int x, int z) {
|
public boolean contains(int x, int z) {
|
||||||
if (region.contains(x, z)) {
|
if (region != null && region.contains(x, z)) {
|
||||||
|
if (disallowed != null) {
|
||||||
|
for (final Region disallow : disallowed) {
|
||||||
|
if (disallow.contains(x, z)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < regions.length; i++) {
|
boolean result = allowed == null;
|
||||||
|
if (!result) {
|
||||||
|
for (int i = 0; i < allowed.length; i++) {
|
||||||
if (i != index) {
|
if (i != index) {
|
||||||
Region current = regions[i];
|
Region current = allowed[i];
|
||||||
if (current.contains(x, z)) {
|
if (current.contains(x, z)) {
|
||||||
region = current;
|
region = current;
|
||||||
index = i;
|
index = i;
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!result || disallowed == null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
for (final Region disallow : disallowed) {
|
||||||
|
if (disallow.contains(x, z)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all allowed regions
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Collection<Region> getRegions() {
|
||||||
|
if (allowed == null) {
|
||||||
|
return List.of(RegionWrapper.GLOBAL());
|
||||||
}
|
}
|
||||||
}
|
return Arrays.asList(allowed);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Region> getRegions() {
|
public boolean processGet(int chunkX, int chunkZ) {
|
||||||
return Arrays.asList(regions);
|
boolean result = allowed == null;
|
||||||
|
if (!result) {
|
||||||
|
for (Region region : allowed) {
|
||||||
|
if (region.containsChunk(chunkX, chunkZ)) {
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!result || disallowed == null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
for (Region region : disallowed) {
|
||||||
|
if (region.containsChunk(chunkX, chunkZ)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
return intersection.processSet(chunk, get, set);
|
if (intersection != null) {
|
||||||
|
set = intersection.processSet(chunk, get, set);
|
||||||
|
}
|
||||||
|
if (disallowedIntersection != null) {
|
||||||
|
intersection.processSet(chunk, get, set);
|
||||||
|
}
|
||||||
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -34,12 +34,15 @@ public interface IBatchProcessor {
|
|||||||
Extent construct(Extent child);
|
Extent construct(Extent child);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method to trim a chunk based on min and max Y.
|
* Utility method to trim a chunk based on min and max Y (inclusive).
|
||||||
*
|
*
|
||||||
|
* @param keepInsideRange if all blocks inside the range (inclusive) should be kept (default)
|
||||||
* @return false if chunk is empty of blocks
|
* @return false if chunk is empty of blocks
|
||||||
*/
|
*/
|
||||||
default boolean trimY(IChunkSet set, int minY, int maxY) {
|
default boolean trimY(IChunkSet set, int minY, int maxY, final boolean keepInsideRange) {
|
||||||
int minLayer = (minY - 1) >> 4;
|
int minLayer = (minY - 1) >> 4;
|
||||||
|
int maxLayer = (maxY + 1) >> 4;
|
||||||
|
if (keepInsideRange) {
|
||||||
for (int layer = set.getMinSectionPosition(); layer <= minLayer; layer++) {
|
for (int layer = set.getMinSectionPosition(); layer <= minLayer; layer++) {
|
||||||
if (set.hasSection(layer)) {
|
if (set.hasSection(layer)) {
|
||||||
if (layer == minLayer) {
|
if (layer == minLayer) {
|
||||||
@ -58,7 +61,6 @@ public interface IBatchProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int maxLayer = (maxY + 1) >> 4;
|
|
||||||
for (int layer = maxLayer; layer < set.getMaxSectionPosition(); layer++) {
|
for (int layer = maxLayer; layer < set.getMaxSectionPosition(); layer++) {
|
||||||
if (set.hasSection(layer)) {
|
if (set.hasSection(layer)) {
|
||||||
if (layer == minLayer) {
|
if (layer == minLayer) {
|
||||||
@ -86,10 +88,46 @@ public interface IBatchProcessor {
|
|||||||
layer++;
|
layer++;
|
||||||
}
|
}
|
||||||
} catch (ArrayIndexOutOfBoundsException exception) {
|
} catch (ArrayIndexOutOfBoundsException exception) {
|
||||||
WorldEdit.logger.error("minY = {} , layer = {}", minY, ((minY - 15) >> 4), exception);
|
WorldEdit.logger.error("IBatchProcessor: minY = {} , layer = {}", minY, ((minY - 15) >> 4), exception);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
int chunkMaxY = (set.getMaxSectionPosition() << 4) + 15;
|
||||||
|
int chunkMinY = set.getMinSectionPosition() << 4;
|
||||||
|
if (maxY >= chunkMaxY && minY <= chunkMinY) {
|
||||||
|
set.reset();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
boolean hasBlocks = false;
|
||||||
|
for (int layer = set.getMinSectionPosition(); layer <= set.getMaxSectionPosition(); layer++) {
|
||||||
|
if (layer < minLayer || layer > maxLayer) {
|
||||||
|
hasBlocks |= set.hasSection(layer);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (layer == minLayer) {
|
||||||
|
char[] arr = set.loadIfPresent(layer);
|
||||||
|
if (arr != null) {
|
||||||
|
int index = (minY & 15) << 8;
|
||||||
|
for (int i = index; i < 4096; i++) {
|
||||||
|
arr[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set.setBlocks(layer, arr);
|
||||||
|
} else if (layer == maxLayer) {
|
||||||
|
char[] arr = set.loadIfPresent(layer);
|
||||||
|
if (arr != null) {
|
||||||
|
int index = ((maxY + 1) & 15) << 8;
|
||||||
|
for (int i = 0; i < index; i++) {
|
||||||
|
arr[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set.setBlocks(layer, arr);
|
||||||
|
} else {
|
||||||
|
set.setBlocks(layer, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hasBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method to trim entity and blocks with a provided contains function.
|
* Utility method to trim entity and blocks with a provided contains function.
|
||||||
|
@ -23,22 +23,39 @@ public abstract class FaweMaskManager {
|
|||||||
return this.key;
|
return this.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a {@link FaweMask} for the given player and {@link MaskType}
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link #getMask(Player, MaskType, boolean)}
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
public FaweMask getMask(final Player player, MaskType type) {
|
public FaweMask getMask(final Player player, MaskType type) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a {@link FaweMask} for the given player and {@link MaskType}. If isWhitelist is false, will return a "blacklist" mask.
|
||||||
|
*/
|
||||||
|
public FaweMask getMask(final Player player, MaskType type, boolean isWhitelist) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Not used internally
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
public boolean isValid(FaweMask mask) {
|
public boolean isValid(FaweMask mask) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Not used internally
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
public RegionFilter getFilter(String world) {
|
public RegionFilter getFilter(String world) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasMemberPermission(Player player) {
|
|
||||||
return player.hasPermission("fawe." + getKey() + ".member");
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isExclusive() {
|
public boolean isExclusive() {
|
||||||
return Settings.IMP.REGION_RESTRICTIONS_OPTIONS.EXCLUSIVE_MANAGERS.contains(this.key);
|
return Settings.IMP.REGION_RESTRICTIONS_OPTIONS.EXCLUSIVE_MANAGERS.contains(this.key);
|
||||||
}
|
}
|
||||||
|
@ -391,7 +391,7 @@ public class EditSessionBuilder {
|
|||||||
}
|
}
|
||||||
if (allowedRegions == null) {
|
if (allowedRegions == null) {
|
||||||
if (player != null && !player.hasPermission("fawe.bypass") && !player.hasPermission("fawe.bypass.regions")) {
|
if (player != null && !player.hasPermission("fawe.bypass") && !player.hasPermission("fawe.bypass.regions")) {
|
||||||
allowedRegions = player.getCurrentRegions();
|
allowedRegions = player.getAllowedRegions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FaweRegionExtent regionExtent = null;
|
FaweRegionExtent regionExtent = null;
|
||||||
@ -402,7 +402,7 @@ public class EditSessionBuilder {
|
|||||||
if (allowedRegions.length == 1) {
|
if (allowedRegions.length == 1) {
|
||||||
regionExtent = new SingleRegionExtent(this.extent, this.limit, allowedRegions[0]);
|
regionExtent = new SingleRegionExtent(this.extent, this.limit, allowedRegions[0]);
|
||||||
} else {
|
} else {
|
||||||
regionExtent = new MultiRegionExtent(this.extent, this.limit, allowedRegions);
|
regionExtent = new MultiRegionExtent(this.extent, this.limit, allowedRegions, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -61,19 +61,26 @@ public class WEManager {
|
|||||||
cancelEditSafe(parent, reason);
|
cancelEditSafe(parent, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public Region[] getMask(Player player) {
|
|
||||||
return getMask(player, FaweMaskManager.MaskType.getDefaultMaskType());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isIn(int x, int y, int z, Region region) {
|
public boolean isIn(int x, int y, int z, Region region) {
|
||||||
return region.contains(x, y, z);
|
return region.contains(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a player's mask.
|
* Get a player's allowed WorldEdit region(s).
|
||||||
*/
|
*/
|
||||||
public Region[] getMask(Player player, FaweMaskManager.MaskType type) {
|
public Region[] getMask(Player player) {
|
||||||
|
return getMask(player, FaweMaskManager.MaskType.getDefaultMaskType(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a player's mask.
|
||||||
|
*
|
||||||
|
* @param player Player to get mask of
|
||||||
|
* @param type Mask type; whether to check if the player is an owner of a member of the regions
|
||||||
|
* @param isWhitelist If searching for whitelist or blacklist regions. True if whitelist
|
||||||
|
* @return array of allowed regions if whitelist, else of disallowed regions.
|
||||||
|
*/
|
||||||
|
public Region[] getMask(Player player, FaweMaskManager.MaskType type, final boolean isWhitelist) {
|
||||||
if (!Settings.IMP.REGION_RESTRICTIONS || player.hasPermission("fawe.bypass") || player.hasPermission("fawe.bypass.regions")) {
|
if (!Settings.IMP.REGION_RESTRICTIONS || player.hasPermission("fawe.bypass") || player.hasPermission("fawe.bypass.regions")) {
|
||||||
return new Region[]{RegionWrapper.GLOBAL()};
|
return new Region[]{RegionWrapper.GLOBAL()};
|
||||||
}
|
}
|
||||||
@ -89,7 +96,7 @@ public class WEManager {
|
|||||||
Set<Region> regions = new HashSet<>();
|
Set<Region> regions = new HashSet<>();
|
||||||
|
|
||||||
|
|
||||||
if (masks == null) {
|
if (masks == null || !isWhitelist) {
|
||||||
masks = new HashSet<>();
|
masks = new HashSet<>();
|
||||||
} else {
|
} else {
|
||||||
synchronized (masks) {
|
synchronized (masks) {
|
||||||
@ -125,7 +132,7 @@ public class WEManager {
|
|||||||
if (manager.isExclusive() && !masks.isEmpty()) {
|
if (manager.isExclusive() && !masks.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final FaweMask mask = manager.getMask(player, FaweMaskManager.MaskType.getDefaultMaskType());
|
final FaweMask mask = manager.getMask(player, FaweMaskManager.MaskType.getDefaultMaskType(), isWhitelist);
|
||||||
if (mask != null) {
|
if (mask != null) {
|
||||||
regions.add(mask.getRegion());
|
regions.add(mask.getRegion());
|
||||||
masks.add(mask);
|
masks.add(mask);
|
||||||
@ -140,9 +147,10 @@ public class WEManager {
|
|||||||
player.printError(TextComponent.of("Missing permission " + "fawe." + manager.getKey()));
|
player.printError(TextComponent.of("Missing permission " + "fawe." + manager.getKey()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!masks.isEmpty()) {
|
regions.addAll(backupRegions);
|
||||||
|
if (!masks.isEmpty() && isWhitelist) {
|
||||||
player.setMeta("lastMask", masks);
|
player.setMeta("lastMask", masks);
|
||||||
} else {
|
} else if (isWhitelist) {
|
||||||
player.deleteMeta("lastMask");
|
player.deleteMeta("lastMask");
|
||||||
}
|
}
|
||||||
return regions.toArray(new Region[0]);
|
return regions.toArray(new Region[0]);
|
||||||
|
@ -86,6 +86,7 @@ public final class EditSessionBuilder {
|
|||||||
private FaweLimit limit;
|
private FaweLimit limit;
|
||||||
private AbstractChangeSet changeSet;
|
private AbstractChangeSet changeSet;
|
||||||
private Region[] allowedRegions;
|
private Region[] allowedRegions;
|
||||||
|
private Region[] disallowedRegions;
|
||||||
private Boolean fastMode;
|
private Boolean fastMode;
|
||||||
private Boolean checkMemory;
|
private Boolean checkMemory;
|
||||||
private Boolean combineStages;
|
private Boolean combineStages;
|
||||||
@ -341,6 +342,34 @@ public final class EditSessionBuilder {
|
|||||||
return setDirty();
|
return setDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the regions the edit is allowed to operate in. Set to null for the regions to be calculated based on the actor if
|
||||||
|
* present
|
||||||
|
*/
|
||||||
|
public EditSessionBuilder disallowedRegions(@Nullable Region[] disallowedRegions) {
|
||||||
|
this.disallowedRegions = disallowedRegions;
|
||||||
|
return setDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the regions the edit is allowed to operate in. Set to null for the regions to be calculated based on the actor if
|
||||||
|
* present
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public EditSessionBuilder disallowedRegions(@Nullable RegionWrapper[] disallowedRegions) {
|
||||||
|
this.disallowedRegions = disallowedRegions;
|
||||||
|
return setDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the region the edit is allowed to operate in. Set to null for the regions to be calculated based on the actor if
|
||||||
|
* present
|
||||||
|
*/
|
||||||
|
public EditSessionBuilder disallowedRegions(@Nullable RegionWrapper disallowedRegion) {
|
||||||
|
this.disallowedRegions = disallowedRegion == null ? null : disallowedRegion.toArray();
|
||||||
|
return setDirty();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the edit to be allowed to edit everywhere
|
* Set the edit to be allowed to edit everywhere
|
||||||
*/
|
*/
|
||||||
@ -511,23 +540,33 @@ public final class EditSessionBuilder {
|
|||||||
if (actor != null && !actor.hasPermission("fawe.bypass") && !actor.hasPermission("fawe.bypass.regions")) {
|
if (actor != null && !actor.hasPermission("fawe.bypass") && !actor.hasPermission("fawe.bypass.regions")) {
|
||||||
if (actor instanceof Player) {
|
if (actor instanceof Player) {
|
||||||
Player player = (Player) actor;
|
Player player = (Player) actor;
|
||||||
allowedRegions = player.getCurrentRegions();
|
allowedRegions = player.getAllowedRegions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (disallowedRegions == null && Settings.IMP.REGION_RESTRICTIONS && Settings.IMP.REGION_RESTRICTIONS_OPTIONS.ALLOW_BLACKLISTS) {
|
||||||
|
if (actor != null && !actor.hasPermission("fawe.bypass") && !actor.hasPermission("fawe.bypass.regions")) {
|
||||||
|
if (actor instanceof Player) {
|
||||||
|
Player player = (Player) actor;
|
||||||
|
disallowedRegions = player.getDisallowedRegions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FaweRegionExtent regionExtent = null;
|
FaweRegionExtent regionExtent = null;
|
||||||
if (allowedRegions != null) {
|
if (disallowedRegions != null) { // Always use MultiRegionExtent if we have blacklist regions
|
||||||
|
regionExtent = new MultiRegionExtent(this.extent, this.limit, allowedRegions, disallowedRegions);
|
||||||
|
} else if (allowedRegions == null) {
|
||||||
|
allowedRegions = new Region[]{RegionWrapper.GLOBAL()};
|
||||||
|
} else {
|
||||||
if (allowedRegions.length == 0) {
|
if (allowedRegions.length == 0) {
|
||||||
regionExtent = new NullExtent(this.extent, FaweCache.NO_REGION);
|
regionExtent = new NullExtent(this.extent, FaweCache.NO_REGION);
|
||||||
} else {
|
} else {
|
||||||
if (allowedRegions.length == 1) {
|
if (allowedRegions.length == 1) {
|
||||||
regionExtent = new SingleRegionExtent(this.extent, this.limit, allowedRegions[0]);
|
regionExtent = new SingleRegionExtent(this.extent, this.limit, allowedRegions[0]);
|
||||||
} else {
|
} else {
|
||||||
regionExtent = new MultiRegionExtent(this.extent, this.limit, allowedRegions);
|
regionExtent = new MultiRegionExtent(this.extent, this.limit, allowedRegions, disallowedRegions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
allowedRegions = new Region[]{RegionWrapper.GLOBAL()};
|
|
||||||
}
|
}
|
||||||
// There's no need to do lighting (and it'll also just be a pain to implement) if we're not placing chunks
|
// There's no need to do lighting (and it'll also just be a pain to implement) if we're not placing chunks
|
||||||
if (placeChunks) {
|
if (placeChunks) {
|
||||||
|
@ -348,12 +348,46 @@ public interface Player extends Entity, Actor {
|
|||||||
<B extends BlockStateHolder<B>> void sendFakeBlock(BlockVector3 pos, @Nullable B block);
|
<B extends BlockStateHolder<B>> void sendFakeBlock(BlockVector3 pos, @Nullable B block);
|
||||||
|
|
||||||
//FAWE start
|
//FAWE start
|
||||||
Region[] getCurrentRegions();
|
/**
|
||||||
|
* Get the player's current allowed WorldEdit regions.
|
||||||
|
*
|
||||||
|
* @return an array of allowed regions
|
||||||
|
*/
|
||||||
|
Region[] getAllowedRegions();
|
||||||
|
|
||||||
Region[] getCurrentRegions(FaweMaskManager.MaskType type);
|
/**
|
||||||
|
* Get the player's current allowed WorldEdit regions.
|
||||||
|
*
|
||||||
|
* @param type Mask type; whether to check if the player is an owner of a member of the regions
|
||||||
|
* @return an array of allowed regions
|
||||||
|
*/
|
||||||
|
Region[] getAllowedRegions(FaweMaskManager.MaskType type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the player's current disallowed WorldEdit regions. Effectively a blacklist.
|
||||||
|
*
|
||||||
|
* @return an array of disallowed regions
|
||||||
|
*/
|
||||||
|
Region[] getDisallowedRegions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the player's current disallowed WorldEdit regions. Effectively a blacklist.
|
||||||
|
*
|
||||||
|
* @param type Mask type; whether to check if the player is an owner of a member of the regions
|
||||||
|
* @return an array of disallowed regions
|
||||||
|
*/
|
||||||
|
Region[] getDisallowedRegions(FaweMaskManager.MaskType type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the largest region in the player's allowed WorldEdit region.
|
||||||
|
*/
|
||||||
Region getLargestRegion();
|
Region getLargestRegion();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a players selection and selector type to the given region
|
||||||
|
*/
|
||||||
|
void setSelection(Region region);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the player's selection region. If the selection is defined in
|
* Get the player's selection region. If the selection is defined in
|
||||||
* a different world, the {@code IncompleteRegionException}
|
* a different world, the {@code IncompleteRegionException}
|
||||||
@ -366,8 +400,6 @@ public interface Player extends Entity, Actor {
|
|||||||
return getSession().getSelection(getWorld());
|
return getSession().getSelection(getWorld());
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSelection(Region region);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the player's WorldEdit selection.
|
* Set the player's WorldEdit selection.
|
||||||
*
|
*
|
||||||
|
@ -483,27 +483,31 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//FAWE start
|
//FAWE start
|
||||||
|
@Override
|
||||||
/**
|
public Region[] getAllowedRegions() {
|
||||||
* Get the player's current allowed WorldEdit regions.
|
return getAllowedRegions(FaweMaskManager.MaskType.getDefaultMaskType());
|
||||||
*
|
|
||||||
* @return an array of allowed regions
|
|
||||||
*/
|
|
||||||
public Region[] getCurrentRegions() {
|
|
||||||
return getCurrentRegions(FaweMaskManager.MaskType.MEMBER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Region[] getCurrentRegions(FaweMaskManager.MaskType type) {
|
@Override
|
||||||
return WEManager.IMP.getMask(this, type);
|
public Region[] getAllowedRegions(FaweMaskManager.MaskType type) {
|
||||||
|
return WEManager.IMP.getMask(this, type, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Get the largest region in the player's allowed WorldEdit region.
|
public Region[] getDisallowedRegions() {
|
||||||
*/
|
return getDisallowedRegions(FaweMaskManager.MaskType.getDefaultMaskType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Region[] getDisallowedRegions(FaweMaskManager.MaskType type) {
|
||||||
|
return WEManager.IMP.getMask(this, type, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Region getLargestRegion() {
|
public Region getLargestRegion() {
|
||||||
long area = 0;
|
long area = 0;
|
||||||
Region max = null;
|
Region max = null;
|
||||||
for (Region region : this.getCurrentRegions()) {
|
for (Region region : this.getAllowedRegions()) {
|
||||||
final long tmp = region.getVolume();
|
final long tmp = region.getVolume();
|
||||||
if (tmp > area) {
|
if (tmp > area) {
|
||||||
area = tmp;
|
area = tmp;
|
||||||
@ -513,6 +517,7 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
|
|||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setSelection(Region region) {
|
public void setSelection(Region region) {
|
||||||
RegionSelector selector;
|
RegionSelector selector;
|
||||||
if (region instanceof ConvexPolyhedralRegion) {
|
if (region instanceof ConvexPolyhedralRegion) {
|
||||||
|
@ -748,13 +748,13 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
|||||||
if (minY <= set.getMinSectionPosition() << 4 && maxY >= (set.getMaxSectionPosition() << 4) + 15) {
|
if (minY <= set.getMinSectionPosition() << 4 && maxY >= (set.getMaxSectionPosition() << 4) + 15) {
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
trimY(set, minY, maxY);
|
trimY(set, minY, maxY, true);
|
||||||
trimNBT(set, this::contains);
|
trimNBT(set, this::contains);
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
if (tx >= minX && bx <= maxX && tz >= minZ && bz <= maxZ) {
|
if (tx >= minX && bx <= maxX && tz >= minZ && bz <= maxZ) {
|
||||||
if (minY > set.getMinSectionPosition() << 4 || maxY < (set.getMaxSectionPosition() << 4) + 15) {
|
if (minY > set.getMinSectionPosition() << 4 || maxY < (set.getMaxSectionPosition() << 4) + 15) {
|
||||||
trimY(set, minY, maxY);
|
trimY(set, minY, maxY, true);
|
||||||
}
|
}
|
||||||
final int lowerX = Math.max(0, minX - bx);
|
final int lowerX = Math.max(0, minX - bx);
|
||||||
final int upperX = Math.min(15, 15 + maxX - tx);
|
final int upperX = Math.min(15, 15 + maxX - tx);
|
||||||
@ -769,9 +769,13 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
|||||||
boolean trimZ = lowerZ != 0 || upperZ != 15;
|
boolean trimZ = lowerZ != 0 || upperZ != 15;
|
||||||
|
|
||||||
for (int layer = get.getMinSectionPosition(); layer < get.getMaxSectionPosition(); layer++) {
|
for (int layer = get.getMinSectionPosition(); layer < get.getMaxSectionPosition(); layer++) {
|
||||||
if (set.hasSection(layer)) {
|
if (!set.hasSection(layer)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
char[] arr = Objects.requireNonNull(set.loadIfPresent(layer)); // This shouldn't be null if above is true
|
char[] arr = Objects.requireNonNull(set.loadIfPresent(layer)); // This shouldn't be null if above is true
|
||||||
if (trimX || trimZ) {
|
if (!(trimX || trimZ)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
int indexY = 0;
|
int indexY = 0;
|
||||||
for (int y = 0; y < 16; y++, indexY += 256) { // For each y layer within a chunk section
|
for (int y = 0; y < 16; y++, indexY += 256) { // For each y layer within a chunk section
|
||||||
int index;
|
int index;
|
||||||
@ -792,7 +796,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (trimX) {
|
if (trimX) {
|
||||||
index = indexY + lowerZi;
|
index = indexY + lowerZi; // Skip blocks already removed by trimZ
|
||||||
for (int z = lowerZ; z <= upperZ; z++, index += 16) {
|
for (int z = lowerZ; z <= upperZ; z++, index += 16) {
|
||||||
for (int x = 0; x < lowerX; x++) {
|
for (int x = 0; x < lowerX; x++) {
|
||||||
// null the x values
|
// null the x values
|
||||||
@ -807,13 +811,86 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
|||||||
}
|
}
|
||||||
set.setBlocks(layer, arr);
|
set.setBlocks(layer, arr);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
trimNBT(set, this::contains);
|
trimNBT(set, this::contains);
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set, boolean asBlacklist) {
|
||||||
|
if (!asBlacklist) {
|
||||||
|
return processSet(chunk, get, set);
|
||||||
|
}
|
||||||
|
int bx = chunk.getX() << 4;
|
||||||
|
int bz = chunk.getZ() << 4;
|
||||||
|
int tx = bx + 15;
|
||||||
|
int tz = bz + 15;
|
||||||
|
|
||||||
|
if (bx >= minX && tx <= maxX && bz >= minZ && tz <= maxZ) {
|
||||||
|
// contains all X/Z
|
||||||
|
int sMaxY = (set.getMaxSectionPosition() << 4) + 15;
|
||||||
|
int sMinY = set.getMinSectionPosition() << 4;
|
||||||
|
if (minY <= sMinY && maxY >= sMaxY) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
trimY(set, minY, maxY, false);
|
||||||
|
trimNBT(set, this::contains);
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
if (tx >= minX && bx <= maxX && tz >= minZ && bz <= maxZ) {
|
||||||
|
if (minY > set.getMinSectionPosition() << 4 || maxY < (set.getMaxSectionPosition() << 4) + 15) {
|
||||||
|
trimY(set, minY, maxY, false);
|
||||||
|
}
|
||||||
|
final int lowerX = Math.max(0, minX - bx);
|
||||||
|
final int upperX = Math.min(15, 15 + maxX - tx);
|
||||||
|
|
||||||
|
final int lowerZ = Math.max(0, minZ - bz);
|
||||||
|
final int upperZ = Math.min(15, 15 + maxZ - tz);
|
||||||
|
|
||||||
|
final int lowerZi = (lowerZ << 4);
|
||||||
|
|
||||||
|
boolean trimX = lowerX != 0 || upperX != 15;
|
||||||
|
boolean trimZ = lowerZ != 0 || upperZ != 15;
|
||||||
|
|
||||||
|
for (int layer = get.getMinSectionPosition(); layer < get.getMaxSectionPosition(); layer++) {
|
||||||
|
if (!set.hasSection(layer)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
char[] arr = Objects.requireNonNull(set.loadIfPresent(layer)); // This shouldn't be null if above is true
|
||||||
|
if (!(trimX || trimZ)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int indexY = 0;
|
||||||
|
for (int y = 0; y < 16; y++, indexY += 256) { // For each y layer within a chunk section
|
||||||
|
int index;
|
||||||
|
if (trimZ) {
|
||||||
|
index = indexY;
|
||||||
|
for (int z = lowerZ; z <= upperZ; z++) {
|
||||||
|
// null the z values
|
||||||
|
for (int x = 0; x < 16; x++, index++) {
|
||||||
|
arr[index] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (trimX) {
|
||||||
|
index = indexY + lowerZi; // Skip blocks already removed by trimZ
|
||||||
|
for (int z = lowerZ; z <= upperZ; z++, index += 16) {
|
||||||
|
for (int x = lowerX; x <= upperX; x++) {
|
||||||
|
// null the x values
|
||||||
|
arr[index + x] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set.setBlocks(layer, arr);
|
||||||
|
}
|
||||||
|
trimNBT(set, bv3 -> !this.contains(bv3));
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
return set;
|
||||||
|
}
|
||||||
//FAWE end
|
//FAWE end
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.regions;
|
package com.sk89q.worldedit.regions;
|
||||||
|
|
||||||
|
import com.fastasyncworldedit.core.FaweCache;
|
||||||
import com.fastasyncworldedit.core.extent.SingleRegionExtent;
|
import com.fastasyncworldedit.core.extent.SingleRegionExtent;
|
||||||
import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock;
|
import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock;
|
||||||
import com.fastasyncworldedit.core.extent.processor.ProcessorScope;
|
import com.fastasyncworldedit.core.extent.processor.ProcessorScope;
|
||||||
@ -366,6 +367,7 @@ public interface Region extends Iterable<BlockVector3>, Cloneable, IBatchProcess
|
|||||||
return tx >= min.getX() && bx <= max.getX() && tz >= min.getZ() && bz <= max.getZ();
|
return tx >= min.getX() && bx <= max.getX() && tz >= min.getZ() && bz <= max.getZ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
default IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
default IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
int bx = chunk.getX() << 4;
|
int bx = chunk.getX() << 4;
|
||||||
int bz = chunk.getZ() << 4;
|
int bz = chunk.getZ() << 4;
|
||||||
@ -377,12 +379,10 @@ public interface Region extends Iterable<BlockVector3>, Cloneable, IBatchProcess
|
|||||||
if (tx >= min.getX() && bx <= max.getX() && tz >= min.getZ() && bz <= max.getZ()) {
|
if (tx >= min.getX() && bx <= max.getX() && tz >= min.getZ() && bz <= max.getZ()) {
|
||||||
// contains some
|
// contains some
|
||||||
boolean processExtra = false;
|
boolean processExtra = false;
|
||||||
for (int layer = 0; layer < 16; layer++) {
|
for (int layer = getMinimumY() >> 4; layer <= getMaximumY() >> 4; layer++) {
|
||||||
int by = layer << 4;
|
int by = layer << 4;
|
||||||
int ty = by + 15;
|
int ty = by + 15;
|
||||||
if (containsEntireCuboid(bx, tx, by, ty, bz, tz)) {
|
if (!containsEntireCuboid(bx, tx, by, ty, bz, tz)) {
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
processExtra = true;
|
processExtra = true;
|
||||||
char[] arr = set.load(layer);
|
char[] arr = set.load(layer);
|
||||||
for (int y = 0, index = 0; y < 16; y++) {
|
for (int y = 0, index = 0; y < 16; y++) {
|
||||||
@ -406,6 +406,58 @@ public interface Region extends Iterable<BlockVector3>, Cloneable, IBatchProcess
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the chunk, with the option to process as if the region is a blacklisted region, and thus any contained blocks
|
||||||
|
* should be removed, rather than uncontained blocks being removed.
|
||||||
|
*
|
||||||
|
* @param asBlacklist If any blocks contained by the region should be removed
|
||||||
|
*/
|
||||||
|
default IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set, boolean asBlacklist) {
|
||||||
|
if (!asBlacklist) {
|
||||||
|
return processSet(chunk, get, set);
|
||||||
|
}
|
||||||
|
int bx = chunk.getX() << 4;
|
||||||
|
int bz = chunk.getZ() << 4;
|
||||||
|
int tx = bx + 15;
|
||||||
|
int tz = bz + 15;
|
||||||
|
|
||||||
|
BlockVector3 min = getMinimumPoint();
|
||||||
|
BlockVector3 max = getMaximumPoint();
|
||||||
|
if (tx >= min.getX() && bx <= max.getX() && tz >= min.getZ() && bz <= max.getZ()) {
|
||||||
|
// contains some
|
||||||
|
boolean processExtra = false;
|
||||||
|
for (int layer = getMinimumY() >> 4; layer <= getMaximumY() >> 4; layer++) {
|
||||||
|
int by = layer << 4;
|
||||||
|
int ty = by + 15;
|
||||||
|
if (containsEntireCuboid(bx, tx, by, ty, bz, tz)) {
|
||||||
|
set.setBlocks(layer, FaweCache.IMP.EMPTY_CHAR_4096);
|
||||||
|
processExtra = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
char[] arr = set.load(layer);
|
||||||
|
for (int y = 0, index = 0; y < 16; y++) {
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
for (int x = 0; x < 16; x++, index++) {
|
||||||
|
if (arr[index] != 0 && contains(x, y, z)) {
|
||||||
|
arr[index] = 0;
|
||||||
|
processExtra = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (processExtra) {
|
||||||
|
set.setBlocks(layer, arr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (processExtra) {
|
||||||
|
trimNBT(set, bv3 -> !this.contains(bv3));
|
||||||
|
}
|
||||||
|
return set;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default Future<IChunkSet> postProcessSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
default Future<IChunkSet> postProcessSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
// Doesn't need to do anything
|
// Doesn't need to do anything
|
||||||
|
@ -30,12 +30,11 @@ import com.sk89q.worldedit.math.BlockVector3;
|
|||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
@ -58,7 +57,7 @@ public class RegionIntersection extends AbstractRegion {
|
|||||||
*
|
*
|
||||||
* @param regions a list of regions, which is copied
|
* @param regions a list of regions, which is copied
|
||||||
*/
|
*/
|
||||||
public RegionIntersection(List<Region> regions) {
|
public RegionIntersection(Collection<Region> regions) {
|
||||||
this(null, regions);
|
this(null, regions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +76,7 @@ public class RegionIntersection extends AbstractRegion {
|
|||||||
* @param world the world
|
* @param world the world
|
||||||
* @param regions a list of regions, which is copied
|
* @param regions a list of regions, which is copied
|
||||||
*/
|
*/
|
||||||
public RegionIntersection(World world, List<Region> regions) {
|
public RegionIntersection(World world, Collection<Region> regions) {
|
||||||
super(world);
|
super(world);
|
||||||
checkNotNull(regions);
|
checkNotNull(regions);
|
||||||
checkArgument(!regions.isEmpty(), "empty region list is not supported");
|
checkArgument(!regions.isEmpty(), "empty region list is not supported");
|
||||||
@ -174,9 +173,22 @@ public class RegionIntersection extends AbstractRegion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future<IChunkSet> postProcessSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set, boolean asBlacklist) {
|
||||||
// Doesn't need to do anything
|
if (!asBlacklist) {
|
||||||
return CompletableFuture.completedFuture(set);
|
return processSet(chunk, get, set);
|
||||||
|
}
|
||||||
|
int bx = chunk.getX() << 4;
|
||||||
|
int bz = chunk.getZ() << 4;
|
||||||
|
int tx = bx + 15;
|
||||||
|
int tz = bz + 15;
|
||||||
|
for (Region region : regions) {
|
||||||
|
BlockVector3 regMin = region.getMinimumPoint();
|
||||||
|
BlockVector3 regMax = region.getMaximumPoint();
|
||||||
|
if (tx >= regMin.getX() && bx <= regMax.getX() && tz >= regMin.getZ() && bz <= regMax.getZ()) {
|
||||||
|
return region.processSet(chunk, get, set, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return set; // default return set as no "blacklist" regions contained the chunk
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Region> getRegions() {
|
public List<Region> getRegions() {
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren