Add RequestExtent to be used when a delayed EditSession is needed.

For example, if you set a mask that takes an extent (many of them),
and then move to another world, the mask will test blocks in the old
world and return bad results.
This commit is contained in:
wizjany 2019-03-16 00:49:21 -04:00
parent d186cce393
commit 25631af31c
11 changed files with 145 additions and 56 deletions

View File

@ -47,6 +47,7 @@ import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.session.request.RequestExtent;
import com.sk89q.worldedit.util.HandSide;
import com.sk89q.worldedit.util.command.binding.Switch;
import com.sk89q.worldedit.util.command.parametric.Optional;
@ -81,7 +82,7 @@ public class BrushCommands {
max = 2
)
@CommandPermissions("worldedit.brush.sphere")
public void sphereBrush(Player player, LocalSession session, EditSession editSession, Pattern fill,
public void sphereBrush(Player player, LocalSession session, Pattern fill,
@Optional("2") double radius, @Switch('h') boolean hollow) throws WorldEditException {
worldEdit.checkMaxBrushRadius(radius);
@ -110,7 +111,7 @@ public class BrushCommands {
max = 3
)
@CommandPermissions("worldedit.brush.cylinder")
public void cylinderBrush(Player player, LocalSession session, EditSession editSession, Pattern fill,
public void cylinderBrush(Player player, LocalSession session, Pattern fill,
@Optional("2") double radius, @Optional("1") int height, @Switch('h') boolean hollow) throws WorldEditException {
worldEdit.checkMaxBrushRadius(radius);
worldEdit.checkMaxBrushRadius(height);
@ -141,7 +142,7 @@ public class BrushCommands {
"stood relative to the copied area when you copied it."
)
@CommandPermissions("worldedit.brush.clipboard")
public void clipboardBrush(Player player, LocalSession session, EditSession editSession, @Switch('a') boolean ignoreAir, @Switch('p') boolean usingOrigin) throws WorldEditException {
public void clipboardBrush(Player player, LocalSession session, @Switch('a') boolean ignoreAir, @Switch('p') boolean usingOrigin) throws WorldEditException {
ClipboardHolder holder = session.getClipboard();
Clipboard clipboard = holder.getClipboard();
@ -168,7 +169,7 @@ public class BrushCommands {
max = 3
)
@CommandPermissions("worldedit.brush.smooth")
public void smoothBrush(Player player, LocalSession session, EditSession editSession,
public void smoothBrush(Player player, LocalSession session,
@Optional("2") double radius, @Optional("4") int iterations, @Optional Mask mask) throws WorldEditException {
worldEdit.checkMaxBrushRadius(radius);
@ -187,14 +188,14 @@ public class BrushCommands {
max = 1
)
@CommandPermissions("worldedit.brush.ex")
public void extinguishBrush(Player player, LocalSession session, EditSession editSession, @Optional("5") double radius) throws WorldEditException {
public void extinguishBrush(Player player, LocalSession session, @Optional("5") double radius) throws WorldEditException {
worldEdit.checkMaxBrushRadius(radius);
BrushTool tool = session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType());
Pattern fill = new BlockPattern(BlockTypes.AIR.getDefaultState());
tool.setFill(fill);
tool.setSize(radius);
tool.setMask(new BlockTypeMask(editSession, BlockTypes.FIRE));
tool.setMask(new BlockTypeMask(new RequestExtent(), BlockTypes.FIRE));
tool.setBrush(new SphereBrush(), "worldedit.brush.ex");
player.print(String.format("Extinguisher equipped (%.0f).", radius));
@ -213,7 +214,7 @@ public class BrushCommands {
max = 1
)
@CommandPermissions("worldedit.brush.gravity")
public void gravityBrush(Player player, LocalSession session, EditSession editSession, @Optional("5") double radius, @Switch('h') boolean fromMaxY) throws WorldEditException {
public void gravityBrush(Player player, LocalSession session, @Optional("5") double radius, @Switch('h') boolean fromMaxY) throws WorldEditException {
worldEdit.checkMaxBrushRadius(radius);
BrushTool tool = session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType());
@ -244,7 +245,7 @@ public class BrushCommands {
max = 1
)
@CommandPermissions("worldedit.brush.butcher")
public void butcherBrush(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
public void butcherBrush(Player player, LocalSession session, CommandContext args) throws WorldEditException {
LocalConfiguration config = worldEdit.getConfiguration();
double radius = args.argsLength() > 0 ? args.getDouble(0) : 5;

View File

@ -28,6 +28,7 @@ import com.sk89q.worldedit.function.mask.BiomeMask2D;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.Masks;
import com.sk89q.worldedit.internal.registry.InputParser;
import com.sk89q.worldedit.session.request.RequestExtent;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.biome.Biomes;
import com.sk89q.worldedit.world.registry.BiomeRegistry;
@ -59,6 +60,6 @@ public class BiomeMaskParser extends InputParser<Mask> {
biomes.add(biome);
}
return Masks.asMask(new BiomeMask2D(context.requireExtent(), biomes));
return Masks.asMask(new BiomeMask2D(new RequestExtent(), biomes));
}
}

View File

@ -22,11 +22,10 @@ package com.sk89q.worldedit.extension.factory.parser.mask;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.BlockCategoryMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.internal.registry.InputParser;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.session.request.RequestExtent;
import com.sk89q.worldedit.world.block.BlockCategory;
public class BlockCategoryMaskParser extends InputParser<Mask> {
@ -41,14 +40,12 @@ public class BlockCategoryMaskParser extends InputParser<Mask> {
return null;
}
Extent extent = Request.request().getEditSession();
// This means it's a tag mask.
BlockCategory category = BlockCategory.REGISTRY.get(input.substring(2).toLowerCase());
if (category == null) {
throw new InputParseException("Unrecognised tag '" + input.substring(2) + '\'');
} else {
return new BlockCategoryMask(extent, category);
return new BlockCategoryMask(new RequestExtent(), category);
}
}
}

View File

@ -20,20 +20,13 @@
package com.sk89q.worldedit.extension.factory.parser.mask;
import com.google.common.base.Splitter;
import com.google.common.collect.Maps;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.BlockStateMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.NoiseFilter;
import com.sk89q.worldedit.internal.registry.InputParser;
import com.sk89q.worldedit.math.noise.RandomNoise;
import com.sk89q.worldedit.session.request.Request;
import java.util.Arrays;
import java.util.stream.Collectors;
import com.sk89q.worldedit.session.request.RequestExtent;
public class BlockStateMaskParser extends InputParser<Mask> {
@ -46,11 +39,11 @@ public class BlockStateMaskParser extends InputParser<Mask> {
if (!(input.startsWith("^[") || input.startsWith("^=[")) || !input.endsWith("]")) {
return null;
}
Extent extent = Request.request().getEditSession();
boolean strict = input.charAt(1) == '=';
String states = input.substring(2 + (strict ? 1 : 0), input.length() - 1);
try {
return new BlockStateMask(extent,
return new BlockStateMask(new RequestExtent(),
Splitter.on(',').omitEmptyStrings().trimResults().withKeyValueSeparator('=').split(states),
strict);
} catch (Exception e) {

View File

@ -23,11 +23,10 @@ import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.NoMatchException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.BlockMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.internal.registry.InputParser;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.session.request.RequestExtent;
import com.sk89q.worldedit.world.block.BaseBlock;
import java.util.Set;
@ -41,9 +40,8 @@ public class BlocksMaskParser extends InputParser<Mask> {
super(worldEdit);
}
@Override
public Mask parseFromInput(String component, ParserContext context) throws InputParseException {
Extent extent = Request.request().getEditSession();
ParserContext tempContext = new ParserContext(context);
tempContext.setRestricted(false);
tempContext.setPreferringWildcard(true);
@ -52,7 +50,7 @@ public class BlocksMaskParser extends InputParser<Mask> {
if (holders.isEmpty()) {
return null;
}
return new BlockMask(extent, holders);
return new BlockMask(new RequestExtent(), holders);
} catch (NoMatchException e) {
return null;
}

View File

@ -21,13 +21,11 @@ package com.sk89q.worldedit.extension.factory.parser.mask;
import com.google.common.collect.Lists;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.session.request.RequestExtent;
import java.util.List;
@ -43,9 +41,7 @@ public class ExistingMaskParser extends SimpleInputParser<Mask> {
}
@Override
public Mask parseFromSimpleInput(String input, ParserContext context) throws InputParseException {
Extent extent = Request.request().getEditSession();
return new ExistingBlockMask(extent);
public Mask parseFromSimpleInput(String input, ParserContext context) {
return new ExistingBlockMask(new RequestExtent());
}
}

View File

@ -31,6 +31,7 @@ import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
import com.sk89q.worldedit.session.SessionOwner;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.session.request.RequestExtent;
import java.util.function.IntSupplier;
@ -49,7 +50,7 @@ public class ExpressionMaskParser extends InputParser<Mask> {
try {
Expression exp = Expression.compile(input.substring(1), "x", "y", "z");
WorldEditExpressionEnvironment env = new WorldEditExpressionEnvironment(
Request.request().getEditSession(), Vector3.ONE, Vector3.ZERO);
new RequestExtent(), Vector3.ONE, Vector3.ZERO);
exp.setEnvironment(env);
if (context.getActor() instanceof SessionOwner) {
SessionOwner owner = (SessionOwner) context.getActor();

View File

@ -22,7 +22,6 @@ package com.sk89q.worldedit.extension.factory.parser.mask;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.MaskIntersection;
@ -30,7 +29,7 @@ import com.sk89q.worldedit.function.mask.Masks;
import com.sk89q.worldedit.function.mask.OffsetMask;
import com.sk89q.worldedit.internal.registry.InputParser;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.session.request.RequestExtent;
public class OffsetMaskParser extends InputParser<Mask> {
@ -45,13 +44,11 @@ public class OffsetMaskParser extends InputParser<Mask> {
return null;
}
Extent extent = Request.request().getEditSession();
Mask submask;
if (input.length() > 1) {
submask = worldEdit.getMaskFactory().parseFromInput(input.substring(1), context);
} else {
submask = new ExistingBlockMask(extent);
submask = new ExistingBlockMask(new RequestExtent());
}
OffsetMask offsetMask = new OffsetMask(submask, BlockVector3.at(0, firstChar == '>' ? -1 : 1, 0));
return new MaskIntersection(offsetMask, Masks.negate(submask));

View File

@ -21,13 +21,11 @@ package com.sk89q.worldedit.extension.factory.parser.mask;
import com.google.common.collect.Lists;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.SolidBlockMask;
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.session.request.RequestExtent;
import java.util.List;
@ -43,9 +41,7 @@ public class SolidMaskParser extends SimpleInputParser<Mask> {
}
@Override
public Mask parseFromSimpleInput(String input, ParserContext context) throws InputParseException {
Extent extent = Request.request().getEditSession();
return new SolidBlockMask(extent);
public Mask parseFromSimpleInput(String input, ParserContext context) {
return new SolidBlockMask(new RequestExtent());
}
}

View File

@ -19,7 +19,7 @@
package com.sk89q.worldedit.regions.shape;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.internal.expression.runtime.ExpressionEnvironment;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
@ -29,10 +29,10 @@ public class WorldEditExpressionEnvironment implements ExpressionEnvironment {
private final Vector3 unit;
private final Vector3 zero2;
private Vector3 current = Vector3.ZERO;
private EditSession editSession;
private Extent extent;
public WorldEditExpressionEnvironment(EditSession editSession, Vector3 unit, Vector3 zero) {
this.editSession = editSession;
public WorldEditExpressionEnvironment(Extent extent, Vector3 unit, Vector3 zero) {
this.extent = extent;
this.unit = unit;
this.zero2 = zero.add(0.5, 0.5, 0.5);
}
@ -48,7 +48,7 @@ public class WorldEditExpressionEnvironment implements ExpressionEnvironment {
@Override
public int getBlockType(double x, double y, double z) {
return editSession.getBlock(toWorld(x, y, z)).getBlockType().getLegacyId();
return extent.getBlock(toWorld(x, y, z)).getBlockType().getLegacyId();
}
@Override
@ -58,7 +58,7 @@ public class WorldEditExpressionEnvironment implements ExpressionEnvironment {
@Override
public int getBlockTypeAbs(double x, double y, double z) {
return editSession.getBlock(BlockVector3.at(x, y, z)).getBlockType().getLegacyId();
return extent.getBlock(BlockVector3.at(x, y, z)).getBlockType().getLegacyId();
}
@Override
@ -68,7 +68,7 @@ public class WorldEditExpressionEnvironment implements ExpressionEnvironment {
@Override
public int getBlockTypeRel(double x, double y, double z) {
return editSession.getBlock(toWorldRel(x, y, z).toBlockPoint()).getBlockType().getLegacyId();
return extent.getBlock(toWorldRel(x, y, z).toBlockPoint()).getBlockType().getLegacyId();
}
@Override

View File

@ -0,0 +1,109 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.session.request;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import javax.annotation.Nullable;
import java.util.List;
public class RequestExtent implements Extent {
private EditSession extent;
protected Extent getExtent() {
if (extent == null) {
extent = Request.request().getEditSession();
}
return extent;
}
@Override
public BlockVector3 getMinimumPoint() {
return getExtent().getMinimumPoint();
}
@Override
public BlockVector3 getMaximumPoint() {
return getExtent().getMaximumPoint();
}
@Override
public List<? extends Entity> getEntities(Region region) {
return getExtent().getEntities(region);
}
@Override
public List<? extends Entity> getEntities() {
return getExtent().getEntities();
}
@Override
@Nullable
public Entity createEntity(Location location, BaseEntity entity) {
return getExtent().createEntity(location, entity);
}
@Override
public BlockState getBlock(BlockVector3 position) {
return getExtent().getBlock(position);
}
@Override
public BaseBlock getFullBlock(BlockVector3 position) {
return getExtent().getFullBlock(position);
}
@Override
public BiomeType getBiome(BlockVector2 position) {
return getExtent().getBiome(position);
}
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 position, T block) throws WorldEditException {
return getExtent().setBlock(position, block);
}
@Override
public boolean setBiome(BlockVector2 position, BiomeType biome) {
return getExtent().setBiome(position, biome);
}
@Override
@Nullable
public Operation commit() {
Operation commit = getExtent().commit();
extent = null;
return commit;
}
}