feat: send one of an error message during edits if otherwise squashed by LimitExtent (#2246)

* feat: send one of an error message during edits if otherwise squashed by LimitExtent

* no region is not ingorable
This commit is contained in:
Jordan 2023-06-12 11:14:24 +01:00 committed by GitHub
parent ed128797ec
commit dae6c69e54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 110 additions and 91 deletions

View File

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

View File

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

View File

@ -14,6 +14,7 @@ public class FaweException extends RuntimeException {
private final Component message; private final Component message;
private final Type type; private final Type type;
private final boolean ignorable;
/** /**
* New instance. Defaults to {@link FaweException.Type#OTHER}. * 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} * New instance of a given {@link FaweException.Type}
*/ */
public FaweException(Component reason, Type 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.message = reason;
this.type = type; this.type = type;
this.ignorable = ignorable;
} }
@Override @Override
@ -55,6 +67,15 @@ public class FaweException extends RuntimeException {
return type; 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) { public static FaweException get(Throwable e) {
if (e instanceof FaweException) { if (e instanceof FaweException) {
return (FaweException) e; return (FaweException) e;

View File

@ -65,16 +65,19 @@ import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Identifiable; import com.sk89q.worldedit.util.Identifiable;
import com.sk89q.worldedit.util.eventbus.EventBus; 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.util.formatting.text.TextComponent;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.function.Consumer;
/** /**
* A builder-style factory for {@link EditSession EditSessions}. * A builder-style factory for {@link EditSession EditSessions}.
@ -590,10 +593,17 @@ public final class EditSessionBuilder {
} else { } else {
relighter = NullRelighter.INSTANCE; 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) { 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()) { } 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) { } else if (regionExtent != null) {
this.extent = regionExtent; 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-block": "Your limit disallows use of block '{0}'",
"fawe.error.limit.disallowed-property": "Your limit disallows use of property '{0}'", "fawe.error.limit.disallowed-property": "Your limit disallows use of property '{0}'",
"fawe.error.region-mask-invalid": "Invalid region mask: {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.count": "Cancelled {0} edits.",
"fawe.cancel.reason.confirm": "Use //confirm to execute {0}", "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}", "fawe.cancel.reason.confirm.region": "Your selection is large ({0} -> {1}, containing {3} blocks). Use //confirm to execute {2}",