Merge branch 'IntellectualSites:main' into main

This commit is contained in:
Telesphoreo 2023-06-14 15:46:43 -05:00 committed by GitHub
commit c609aa97ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 233 additions and 154 deletions

View File

@ -8,7 +8,7 @@ body:
value: |
Thanks for taking the time to fill out this bug report for FastAsyncWorldEdit! Fill out the following form to your best ability to help us fix the problem.
Only use this if you're absolutely sure that you found a bug and can reproduce it. For anything else, use: [our Discord server](https://discord.gg/intellectualsites) or [the wiki](https://intellectualsites.github.io/fastasyncworldedit-documentation/).
Do NOT use the public issue tracker to report security vulnerabilities! They are disclosed using [this](https://forms.gle/btgdRn9yhGtzEiGW8) form!
Do NOT use the public issue tracker to report security vulnerabilities! They are disclosed using [this](https://github.com/IntellectualSites/FastAsyncWorldEdit/security/policy) GitHub form!
- type: dropdown
attributes:

View File

@ -34,7 +34,7 @@ logger.lifecycle("""
*******************************************
""")
var rootVersion by extra("2.6.3")
var rootVersion by extra("2.6.4")
var snapshot by extra("SNAPSHOT")
var revision: String by extra("")
var buildNumber by extra("")

View File

@ -202,8 +202,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
}
try {
// Non-Paper
SERVER_LEVEL_ENTITY_MANAGER = ServerLevel.class.getDeclaredField("entityManager");
LEVEL_CHUNK_ENTITIES.setAccessible(true);
SERVER_LEVEL_ENTITY_MANAGER = ServerLevel.class.getDeclaredField(Refraction.pickName("entityManager", "P"));
SERVER_LEVEL_ENTITY_MANAGER.setAccessible(true);
} catch (NoSuchFieldException ignored) {
}
POST_CHUNK_REWRITE = chunkRewrite;

View File

@ -199,8 +199,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
}
try {
// Non-Paper
SERVER_LEVEL_ENTITY_MANAGER = ServerLevel.class.getDeclaredField("entityManager");
LEVEL_CHUNK_ENTITIES.setAccessible(true);
SERVER_LEVEL_ENTITY_MANAGER = ServerLevel.class.getDeclaredField(Refraction.pickName("entityManager", "P"));
SERVER_LEVEL_ENTITY_MANAGER.setAccessible(true);
} catch (NoSuchFieldException ignored) {
}
POST_CHUNK_REWRITE = chunkRewrite;

View File

@ -204,8 +204,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
}
try {
// Non-Paper
SERVER_LEVEL_ENTITY_MANAGER = ServerLevel.class.getDeclaredField("entityManager");
LEVEL_CHUNK_ENTITIES.setAccessible(true);
SERVER_LEVEL_ENTITY_MANAGER = ServerLevel.class.getDeclaredField(Refraction.pickName("entityManager", "L"));
SERVER_LEVEL_ENTITY_MANAGER.setAccessible(true);
} catch (NoSuchFieldException ignored) {
}
POST_CHUNK_REWRITE = chunkRewrite;

View File

@ -182,8 +182,8 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
CraftServer.class.cast(Bukkit.getServer());
int dataVersion = CraftMagicNumbers.INSTANCE.getDataVersion();
if (dataVersion != 3463) {
throw new UnsupportedClassVersionError("Not 1.20!");
if (dataVersion != 3463 && dataVersion != 3465) {
throw new UnsupportedClassVersionError("Not 1.20(.1)!");
}
serverWorldsField = CraftServer.class.getDeclaredField("worlds");

View File

@ -211,7 +211,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
try {
// Non-Paper
SERVER_LEVEL_ENTITY_MANAGER = ServerLevel.class.getDeclaredField(Refraction.pickName("entityManager", "M"));
LEVEL_CHUNK_ENTITIES.setAccessible(true);
SERVER_LEVEL_ENTITY_MANAGER.setAccessible(true);
} catch (NoSuchFieldException ignored) {
}
POST_CHUNK_REWRITE = chunkRewrite;

View File

@ -2,9 +2,7 @@ package com.fastasyncworldedit.bukkit.regions;
import com.fastasyncworldedit.core.regions.FaweMask;
import com.palmergames.bukkit.towny.Towny;
import com.palmergames.bukkit.towny.TownyUniverse;
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
import com.palmergames.bukkit.towny.object.PlayerCache;
import com.palmergames.bukkit.towny.TownyAPI;
import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.Town;
import com.palmergames.bukkit.towny.object.TownBlock;
@ -36,31 +34,27 @@ public class TownyFeature extends BukkitMaskManager implements Listener {
if (block == null) {
return false;
}
Resident resident;
try {
resident = TownyUniverse.getInstance().getResident(player.getName());
try {
if (block.getResident().equals(resident)) {
return true;
}
} catch (NotRegisteredException ignored) {
}
Town town = block.getTown();
if (town.isMayor(resident)) {
Resident resident = TownyAPI.getInstance().getResident(player);
if (resident == null) {
return false;
}
if (block.hasResident(resident) || block.hasTrustedResident(resident)) {
return true;
}
Town town = block.getTownOrNull(); // Will not be null, because block is not null.
if (town.isMayor(resident) || town.hasTrustedResident(resident)) {
return true;
}
if (!town.hasResident(resident)) {
return false;
}
if (player.hasPermission("fawe.towny.*")) {
return true;
}
for (String rank : resident.getTownRanks()) {
if (player.hasPermission("fawe.towny." + rank)) {
return true;
}
if (!town.hasResident(resident)) {
return false;
}
if (player.hasPermission("fawe.towny.*")) {
return true;
}
for (String rank : resident.getTownRanks()) {
if (player.hasPermission("fawe.towny." + rank)) {
return true;
}
}
} catch (NotRegisteredException ignored) {
}
return false;
}
@ -69,32 +63,23 @@ public class TownyFeature extends BukkitMaskManager implements Listener {
public FaweMask getMask(final com.sk89q.worldedit.entity.Player wePlayer, MaskType type, boolean isWhitelist) {
final Player player = BukkitAdapter.adapt(wePlayer);
final Location location = player.getLocation();
try {
final PlayerCache cache = ((Towny) this.towny).getCache(player);
final WorldCoord mycoord = cache.getLastTownBlock();
if (mycoord == null) {
return null;
}
final TownBlock myplot = mycoord.getTownBlock();
if (myplot == null) {
return null;
}
boolean isMember = isAllowed(player, myplot);
if (isMember) {
final Chunk chunk = location.getChunk();
final BlockVector3 pos1 = BlockVector3
.at(chunk.getX() * 16, 0, chunk.getZ() * 16);
final BlockVector3 pos2 = BlockVector3.at(
chunk.getX() * 16 + 15, 156, chunk.getZ() * 16
+ 15);
return new FaweMask(new CuboidRegion(pos1, pos2)) {
@Override
public boolean isValid(com.sk89q.worldedit.entity.Player player, MaskType type) {
return isAllowed(BukkitAdapter.adapt(player), myplot);
}
};
}
} catch (Exception ignored) {
final WorldCoord mycoord = WorldCoord.parseWorldCoord(location);
if (mycoord.isWilderness()) {
return null;
}
final TownBlock myplot = mycoord.getTownBlockOrNull(); // Will not be null, because of the isWilderness() test above.
boolean isMember = isAllowed(player, myplot);
if (isMember) {
final Location loc1 = mycoord.getLowerMostCornerLocation();
final Location loc2 = mycoord.getUpperMostCornerLocation();
final BlockVector3 pos1 = BlockVector3.at(loc1.getX(), loc1.getY(), loc1.getZ());
final BlockVector3 pos2 = BlockVector3.at(loc2.getX(), loc2.getY(), loc2.getZ());
return new FaweMask(new CuboidRegion(pos1, pos2)) {
@Override
public boolean isValid(com.sk89q.worldedit.entity.Player player, MaskType type) {
return isAllowed(BukkitAdapter.adapt(player), myplot);
}
};
}
return null;
}

View File

@ -21,6 +21,8 @@ package com.sk89q.worldedit.bukkit;
import com.fastasyncworldedit.bukkit.util.WorldUnloadedException;
import com.fastasyncworldedit.core.Fawe;
import com.fastasyncworldedit.core.FaweCache;
import com.fastasyncworldedit.core.configuration.Settings;
import com.fastasyncworldedit.core.internal.exception.FaweException;
import com.fastasyncworldedit.core.queue.IChunkGet;
import com.fastasyncworldedit.core.queue.implementation.packet.ChunkPacket;
@ -242,6 +244,9 @@ public class BukkitWorld extends AbstractWorld {
@Override
public int getBlockLightLevel(BlockVector3 pt) {
//FAWE start - safe edit region
testCoords(pt);
//FAWE end
return getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).getLightLevel();
}
@ -265,6 +270,9 @@ public class BukkitWorld extends AbstractWorld {
@Override
public boolean clearContainerBlockContents(BlockVector3 pt) {
checkNotNull(pt);
//FAWE start - safe edit region
testCoords(pt);
//FAWE end
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
try {
@ -337,6 +345,7 @@ public class BukkitWorld extends AbstractWorld {
@Override
public boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, BlockVector3 pt) {
//FAWE start - allow tree commands to be undone and obey region restrictions
testCoords(pt);
return WorldEditPlugin.getInstance().getBukkitImplAdapter().generateTree(type, editSession, pt, getWorld());
//FAWE end
}
@ -349,6 +358,9 @@ public class BukkitWorld extends AbstractWorld {
@Override
public void checkLoadedChunk(BlockVector3 pt) {
//FAWE start - safe edit region
testCoords(pt);
//FAWE end
World world = getWorld();
//FAWE start
int X = pt.getBlockX() >> 4;
@ -480,6 +492,9 @@ public class BukkitWorld extends AbstractWorld {
@Override
public void simulateBlockMine(BlockVector3 pt) {
//FAWE start - safe edit region
testCoords(pt);
//FAWE end
getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).breakNaturally();
}
@ -493,6 +508,9 @@ public class BukkitWorld extends AbstractWorld {
@Override
public boolean canPlaceAt(BlockVector3 position, com.sk89q.worldedit.world.block.BlockState blockState) {
//FAWE start - safe edit region
testCoords(position);
//FAWE end
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
return adapter.canPlaceAt(getWorld(), position, blockState);
@ -505,6 +523,9 @@ public class BukkitWorld extends AbstractWorld {
@Override
public com.sk89q.worldedit.world.block.BlockState getBlock(BlockVector3 position) {
//FAWE start - safe edit region
testCoords(position);
//FAWE end
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
try {
@ -526,6 +547,9 @@ public class BukkitWorld extends AbstractWorld {
@Override
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) {
//FAWE start - safe edit region
testCoords(position);
//FAWE end
if (worldNativeAccess != null) {
try {
return worldNativeAccess.setBlock(position, block, sideEffects);
@ -545,6 +569,9 @@ public class BukkitWorld extends AbstractWorld {
@Override
public BaseBlock getFullBlock(BlockVector3 position) {
//FAWE start - safe edit region
testCoords(position);
//FAWE end
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
return adapter.getFullBlock(BukkitAdapter.adapt(getWorld(), position));
@ -553,11 +580,25 @@ public class BukkitWorld extends AbstractWorld {
}
}
private void testCoords(BlockVector3 position) throws FaweException {
if (!Settings.settings().REGION_RESTRICTIONS_OPTIONS.RESTRICT_TO_SAFE_RANGE) {
return;
}
int x = position.getX();
int z = position.getZ();
if (x > 30000000 || z > 30000000 || x < -30000000 || z < -30000000) {
throw FaweCache.OUTSIDE_SAFE_REGION;
}
}
@Override
public Set<SideEffect> applySideEffects(
BlockVector3 position, com.sk89q.worldedit.world.block.BlockState previousType,
SideEffectSet sideEffectSet
) {
//FAWE start - safe edit region
testCoords(position);
//FAWE end
if (worldNativeAccess != null) {
worldNativeAccess.applySideEffects(position, previousType, sideEffectSet);
return Sets.intersection(
@ -571,6 +612,9 @@ public class BukkitWorld extends AbstractWorld {
@Override
public boolean useItem(BlockVector3 position, BaseItem item, Direction face) {
//FAWE start - safe edit region
testCoords(position);
//FAWE end
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
return adapter.simulateItemUse(getWorld(), position, item, face);
@ -588,6 +632,9 @@ public class BukkitWorld extends AbstractWorld {
@SuppressWarnings("deprecation")
@Override
public BiomeType getBiome(BlockVector3 position) {
//FAWE start - safe edit region
testCoords(position);
//FAWE end
if (HAS_3D_BIOMES) {
return BukkitAdapter.adapt(getWorld().getBiome(position.getBlockX(), position.getBlockY(), position.getBlockZ()));
} else {
@ -598,6 +645,9 @@ public class BukkitWorld extends AbstractWorld {
@SuppressWarnings("deprecation")
@Override
public boolean setBiome(BlockVector3 position, BiomeType biome) {
//FAWE start - safe edit region
testCoords(position);
//FAWE end
if (HAS_3D_BIOMES) {
getWorld().setBiome(position.getBlockX(), position.getBlockY(), position.getBlockZ(), BukkitAdapter.adapt(biome));
} else {
@ -626,11 +676,13 @@ public class BukkitWorld extends AbstractWorld {
@Override
public void refreshChunk(int chunkX, int chunkZ) {
testCoords(BlockVector3.at(chunkX << 4, 0, chunkZ << 4));
getWorld().refreshChunk(chunkX, chunkZ);
}
@Override
public IChunkGet get(int chunkX, int chunkZ) {
testCoords(BlockVector3.at(chunkX << 4, 0, chunkZ << 4));
return WorldEditPlugin.getInstance().getBukkitImplAdapter().get(getWorldChecked(), chunkX, chunkZ);
}

View File

@ -171,52 +171,68 @@ public enum FaweCache implements Trimable {
public static final FaweBlockBagException BLOCK_BAG = new FaweBlockBagException();
public static final FaweException MANUAL = new FaweException(
Caption.of("fawe.cancel.reason.manual"),
Type.MANUAL
Type.MANUAL,
false
);
public static final FaweException NO_REGION = new FaweException(
Caption.of("fawe.cancel.reason.no.region"),
Type.NO_REGION
Type.NO_REGION,
false
);
public static final FaweException OUTSIDE_REGION = new FaweException(
Caption.of(
"fawe.cancel.reason.outside.region"),
Type.OUTSIDE_REGION,
true
);
public static final FaweException OUTSIDE_SAFE_REGION = new FaweException(
Caption.of(
"fawe.cancel.reason.outside.safe.region"),
Type.OUTSIDE_REGION
);
public static final FaweException MAX_CHECKS = new FaweException(
Caption.of("fawe.cancel.reason.max" + ".checks"),
Type.MAX_CHECKS
Type.MAX_CHECKS,
true
);
public static final FaweException MAX_CHANGES = new FaweException(
Caption.of("fawe.cancel.reason.max" + ".changes"),
Type.MAX_CHANGES
Type.MAX_CHANGES,
false
);
public static final FaweException LOW_MEMORY = new FaweException(
Caption.of("fawe.cancel.reason.low" + ".memory"),
Type.LOW_MEMORY
Type.LOW_MEMORY,
false
);
public static final FaweException MAX_ENTITIES = new FaweException(
Caption.of(
"fawe.cancel.reason.max.entities"),
Type.MAX_ENTITIES
Type.MAX_ENTITIES,
true
);
public static final FaweException MAX_TILES = new FaweException(Caption.of(
"fawe.cancel.reason.max.tiles",
Type.MAX_TILES
Type.MAX_TILES,
true
));
public static final FaweException MAX_ITERATIONS = new FaweException(
Caption.of(
"fawe.cancel.reason.max.iterations"),
Type.MAX_ITERATIONS
Type.MAX_ITERATIONS,
true
);
public static final FaweException PLAYER_ONLY = new FaweException(
Caption.of(
"fawe.cancel.reason.player-only"),
Type.PLAYER_ONLY
Type.PLAYER_ONLY,
false
);
public static final FaweException ACTOR_REQUIRED = new FaweException(
Caption.of(
"fawe.cancel.reason.actor-required"),
Type.ACTOR_REQUIRED
Type.ACTOR_REQUIRED,
false
);
/*

View File

@ -312,6 +312,12 @@ public class Settings extends Config {
" - Any blacklist regions are likely to override any internal allowed regions."
})
public boolean WORLDGUARD_REGION_BLACKLIST = false;
@Comment({
"Restrict all edits to within the safe chunk limits of +/- 30 million blocks",
" - Edits outside this range may induce crashing",
" - Forcefully prevents any edit outside this range"
})
public boolean RESTRICT_TO_SAFE_RANGE = true;
}

View File

@ -20,6 +20,7 @@ import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.block.BaseBlock;
@ -34,19 +35,46 @@ import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
public class LimitExtent extends AbstractDelegateExtent {
private final FaweLimit limit;
private final boolean[] faweExceptionReasonsUsed = new boolean[FaweException.Type.values().length];
private final Consumer<Component> onErrorMessage;
/**
* Create a new instance.
*
* @param extent the extent
* @param limit the limit
*/
public LimitExtent(Extent extent, FaweLimit limit) {
this(extent, limit, c -> {
});
}
/**
* Create a new instance.
*
* @param extent the extent
* @param limit the limit
* @param onErrorMessage consumer to handle a component generated by exceptions
*/
public LimitExtent(Extent extent, FaweLimit limit, Consumer<Component> onErrorMessage) {
super(extent);
this.limit = limit;
this.onErrorMessage = onErrorMessage;
}
private void handleException(FaweException e) {
if (e.ignorable() || !limit.MAX_FAILS()) {
throw e;
}
if (!faweExceptionReasonsUsed[e.getType().ordinal()]) {
faweExceptionReasonsUsed[e.getType().ordinal()] = true;
onErrorMessage.accept(e.getComponent());
}
}
@Override
@ -55,9 +83,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.getEntities(region);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return Collections.emptyList();
}
}
@ -68,9 +94,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.getEntities();
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return Collections.emptyList();
}
}
@ -83,9 +107,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.createEntity(location, entity);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return null;
}
}
@ -98,9 +120,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.createEntity(location, entity, uuid);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return null;
}
}
@ -112,9 +132,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
super.removeEntity(x, y, z, uuid);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
}
}
@ -124,9 +142,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.regenerateChunk(x, z, type, seed);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return false;
}
}
@ -137,9 +153,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.getHighestTerrainBlock(x, z, minY, maxY);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return minY;
}
}
@ -150,9 +164,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.getHighestTerrainBlock(x, z, minY, maxY, filter);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return minY;
}
}
@ -163,9 +175,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.getNearestSurfaceLayer(x, z, y, minY, maxY);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return minY;
}
}
@ -176,9 +186,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, ignoreAir);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return minY;
}
}
@ -189,9 +197,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return minY;
}
}
@ -202,9 +208,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return minY;
}
}
@ -215,9 +219,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, mask);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return minY;
}
}
@ -237,9 +239,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, ignoreAir);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return minY;
}
}
@ -386,9 +386,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
filter.applyBlock(block.init(pos));
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
}
}
return filter;
@ -404,9 +402,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.getBlock(position);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return BlockTypes.AIR.getDefaultState();
}
}
@ -417,9 +413,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.getBlock(x, y, z);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return BlockTypes.AIR.getDefaultState();
}
}
@ -430,9 +424,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.getFullBlock(position);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return BlockTypes.AIR.getDefaultState().toBaseBlock();
}
}
@ -443,9 +435,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.getFullBlock(x, y, z);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return BlockTypes.AIR.getDefaultState().toBaseBlock();
}
}
@ -456,9 +446,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.getBiome(position);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return BiomeTypes.FOREST;
}
}
@ -469,9 +457,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.getBiomeType(x, y, z);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return BiomeTypes.FOREST;
}
}
@ -486,9 +472,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.setBlock(position, block);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return false;
}
}
@ -502,9 +486,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.setBlock(x, y, z, block);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return false;
}
}
@ -516,9 +498,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.setTile(x, y, z, tile);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return false;
}
}
@ -529,9 +509,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.setBiome(position, biome);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return false;
}
}
@ -542,9 +520,7 @@ public class LimitExtent extends AbstractDelegateExtent {
try {
return super.setBiome(x, y, z, biome);
} catch (FaweException e) {
if (e.getType() == FaweException.Type.MANUAL || !limit.MAX_FAILS()) {
throw e;
}
handleException(e);
return false;
}
}

View File

@ -14,6 +14,7 @@ public class FaweException extends RuntimeException {
private final Component message;
private final Type type;
private final boolean ignorable;
/**
* New instance. Defaults to {@link FaweException.Type#OTHER}.
@ -33,8 +34,19 @@ public class FaweException extends RuntimeException {
* New instance of a given {@link FaweException.Type}
*/
public FaweException(Component reason, Type type) {
this(reason, type, false);
}
/**
* New instance of a given {@link FaweException.Type}
*
* @param ignorable if an edit can continue if this exception is caught, e.g. by {@link com.fastasyncworldedit.core.extent.LimitExtent}
* @since TODO
*/
public FaweException(Component reason, Type type, boolean ignorable) {
this.message = reason;
this.type = type;
this.ignorable = ignorable;
}
@Override
@ -55,6 +67,15 @@ public class FaweException extends RuntimeException {
return type;
}
/**
* If an edit can continue if this exception is caught, e.g. by {@link com.fastasyncworldedit.core.extent.LimitExtent}
*
* @since TODO
*/
public boolean ignorable() {
return ignorable;
}
public static FaweException get(Throwable e) {
if (e instanceof FaweException) {
return (FaweException) e;
@ -80,6 +101,7 @@ public class FaweException extends RuntimeException {
MANUAL,
NO_REGION,
OUTSIDE_REGION,
OUTSIDE_SAFE_REGION,
MAX_CHECKS,
MAX_CHANGES,
LOW_MEMORY,

View File

@ -293,7 +293,9 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
if (pair == lastPair) {
return lastChunk;
}
if (!processGet(x, z)) {
if (!processGet(x, z) || (Settings.settings().REGION_RESTRICTIONS_OPTIONS.RESTRICT_TO_SAFE_RANGE
// if any chunk coord is outside 30 million blocks
&& (x > 1875000 || z > 1875000 || x < -1875000 || z < -1875000))) {
lastPair = pair;
lastChunk = NullChunk.getInstance();
return NullChunk.getInstance();

View File

@ -110,6 +110,14 @@ public class AsyncPreloader implements Preloader, Runnable {
Iterator<BlockVector2> chunksIter = chunks.iterator();
while (chunksIter.hasNext() && pair.getValue() == chunks) { // Ensure the queued load is still valid
BlockVector2 chunk = chunksIter.next();
if (Settings.settings().REGION_RESTRICTIONS_OPTIONS.RESTRICT_TO_SAFE_RANGE) {
int x = chunk.getX();
int z = chunk.getZ();
// if any chunk coord is outside 30 million blocks
if (x > 1875000 || z > 1875000 || x < -1875000 || z < -1875000) {
continue;
}
}
queueLoad(world, chunk);
}
}

View File

@ -65,16 +65,19 @@ import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Identifiable;
import com.sk89q.worldedit.util.eventbus.EventBus;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.world.World;
import org.apache.logging.log4j.Logger;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
/**
* A builder-style factory for {@link EditSession EditSessions}.
@ -590,10 +593,17 @@ public final class EditSessionBuilder {
} else {
relighter = NullRelighter.INSTANCE;
}
Consumer<Component> onErrorMessage;
if (getActor() != null) {
onErrorMessage = c -> getActor().print(Caption.of("fawe.error.occurred-continuing", c));
} else {
onErrorMessage = c -> {
};
}
if (limit != null && !limit.isUnlimited() && regionExtent != null) {
this.extent = new LimitExtent(regionExtent, limit);
this.extent = new LimitExtent(regionExtent, limit, onErrorMessage);
} else if (limit != null && !limit.isUnlimited()) {
this.extent = new LimitExtent(this.extent, limit);
this.extent = new LimitExtent(this.extent, limit, onErrorMessage);
} else if (regionExtent != null) {
this.extent = regionExtent;
}

View File

@ -134,6 +134,7 @@
"fawe.error.limit.disallowed-block": "Your limit disallows use of block '{0}'",
"fawe.error.limit.disallowed-property": "Your limit disallows use of property '{0}'",
"fawe.error.region-mask-invalid": "Invalid region mask: {0}",
"fawe.error.occurred-continuing": "Ignorable error occurred during edit: {0}",
"fawe.cancel.count": "Cancelled {0} edits.",
"fawe.cancel.reason.confirm": "Use //confirm to execute {0}",
"fawe.cancel.reason.confirm.region": "Your selection is large ({0} -> {1}, containing {3} blocks). Use //confirm to execute {2}",
@ -149,6 +150,7 @@
"fawe.cancel.reason.max.iterations": "Max iterations",
"fawe.cancel.reason.outside.level": "Outside world",
"fawe.cancel.reason.outside.region": "Outside allowed region (bypass with /wea, or disable `region-restrictions` in config.yml)",
"fawe.cancel.reason.outside.safe.region": "Outside safe edit region of +/- 30,000,000 blocks.",
"fawe.cancel.reason.no.region": "No allowed region (bypass with /wea, or disable `region-restrictions` in config.yml)",
"fawe.cancel.reason.no.region.reason": "No allowed region: {0}",
"fawe.cancel.reason.no.region.plot.noworldeditflag": "Plot flag NoWorldeditFlag set",