Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-11-19 17:30:08 +01:00
Add processing capability
Dieser Commit ist enthalten in:
Ursprung
6e4f8770b6
Commit
74d4b57b4f
@ -4,7 +4,7 @@ import com.fastasyncworldedit.bukkit.adapter.FaweAdapter;
|
|||||||
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
|
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
|
||||||
import com.fastasyncworldedit.core.FaweCache;
|
import com.fastasyncworldedit.core.FaweCache;
|
||||||
import com.fastasyncworldedit.core.entity.LazyBaseEntity;
|
import com.fastasyncworldedit.core.entity.LazyBaseEntity;
|
||||||
import com.fastasyncworldedit.core.extent.processor.PlacementStateProcessor;
|
import com.fastasyncworldedit.core.extent.PlacementStateProcessor;
|
||||||
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
||||||
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
||||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||||
@ -36,7 +36,6 @@ import com.sk89q.worldedit.registry.state.IntegerProperty;
|
|||||||
import com.sk89q.worldedit.registry.state.Property;
|
import com.sk89q.worldedit.registry.state.Property;
|
||||||
import com.sk89q.worldedit.util.Direction;
|
import com.sk89q.worldedit.util.Direction;
|
||||||
import com.sk89q.worldedit.util.SideEffect;
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
import com.sk89q.worldedit.util.SideEffectSet;
|
|
||||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||||
import com.sk89q.worldedit.util.nbt.BinaryTag;
|
import com.sk89q.worldedit.util.nbt.BinaryTag;
|
||||||
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
||||||
@ -442,7 +441,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
}
|
}
|
||||||
|
|
||||||
public net.minecraft.world.level.block.state.BlockState adapt(BlockState blockState) {
|
public net.minecraft.world.level.block.state.BlockState adapt(BlockState blockState) {
|
||||||
return Block.stateById(ordinalToIbdID[blockState.getOrdinal()]);
|
return Block.stateById(getOrdinalToIbdID()[blockState.getOrdinal()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -614,13 +613,8 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlacementStateProcessor getPlatformPlacementProcessor(
|
public PlacementStateProcessor getPlatformPlacementProcessor(Extent extent, BlockTypeMask mask, Region region ) {
|
||||||
Extent extent,
|
return new PaperweightPlacementStateProcessor(extent, mask, region);
|
||||||
BlockTypeMask mask,
|
|
||||||
boolean secondPass,
|
|
||||||
boolean includeUnedited
|
|
||||||
) {
|
|
||||||
return new PaperweightPlacementStateProcessor(extent, mask, secondPass, includeUnedited);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean wasAccessibleSinceLastSave(ChunkHolder holder) {
|
private boolean wasAccessibleSinceLastSave(ChunkHolder holder) {
|
||||||
|
@ -24,6 +24,7 @@ import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.nbt.PaperweightLazy
|
|||||||
import com.sk89q.worldedit.internal.Constants;
|
import com.sk89q.worldedit.internal.Constants;
|
||||||
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;
|
||||||
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
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.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
@ -822,7 +823,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
nmsChunk.mustNotSave = false;
|
nmsChunk.mustNotSave = false;
|
||||||
nmsChunk.setUnsaved(true);
|
nmsChunk.setUnsaved(true);
|
||||||
// send to player
|
// send to player
|
||||||
if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) {
|
if (!set.getSideEffectSet().shouldApply(SideEffect.LIGHTING) || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) {
|
||||||
this.send(finalMask, finalLightUpdate);
|
this.send(finalMask, finalLightUpdate);
|
||||||
}
|
}
|
||||||
if (finalizer != null) {
|
if (finalizer != null) {
|
||||||
|
@ -2,12 +2,12 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3;
|
|||||||
|
|
||||||
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
||||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.tags.FluidTags;
|
import net.minecraft.tags.FluidTags;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
@ -20,17 +20,15 @@ import javax.annotation.Nullable;
|
|||||||
public class PaperweightLevelProxy extends ServerLevel {
|
public class PaperweightLevelProxy extends ServerLevel {
|
||||||
|
|
||||||
private PaperweightFaweAdapter adapter;
|
private PaperweightFaweAdapter adapter;
|
||||||
private Extent extent;
|
private PaperweightPlacementStateProcessor processor;
|
||||||
private ServerLevel serverLevel;
|
|
||||||
private boolean enabled = false;
|
|
||||||
|
|
||||||
@SuppressWarnings("DataFlowIssue")
|
@SuppressWarnings("DataFlowIssue")
|
||||||
public PaperweightLevelProxy() {
|
private PaperweightLevelProxy() {
|
||||||
super(null, null, null, null, null, null, null, true, 0L, null, true, null, null, null);
|
super(null, null, null, null, null, null, null, true, 0L, null, true, null, null, null);
|
||||||
throw new IllegalStateException("Cannot be instantiated");
|
throw new IllegalStateException("Cannot be instantiated");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PaperweightLevelProxy getInstance(ServerLevel level, Extent extent) {
|
public static PaperweightLevelProxy getInstance(PaperweightPlacementStateProcessor processor) {
|
||||||
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
||||||
|
|
||||||
PaperweightLevelProxy newLevel;
|
PaperweightLevelProxy newLevel;
|
||||||
@ -39,45 +37,41 @@ public class PaperweightLevelProxy extends ServerLevel {
|
|||||||
} catch (InstantiationException e) {
|
} catch (InstantiationException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin
|
newLevel.processor = processor;
|
||||||
.getInstance()
|
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin.getInstance().getBukkitImplAdapter());
|
||||||
.getBukkitImplAdapter());
|
|
||||||
newLevel.extent = extent;
|
|
||||||
newLevel.serverLevel = level;
|
|
||||||
return newLevel;
|
return newLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEnabled(boolean enabled) {
|
|
||||||
this.enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public BlockEntity getBlockEntity(@Nonnull BlockPos blockPos) {
|
public BlockEntity getBlockEntity(@Nonnull BlockPos blockPos) {
|
||||||
if (!enabled) {
|
if (blockPos.getX() == Integer.MAX_VALUE) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
BlockEntity tileEntity = this.serverLevel.getChunkAt(blockPos).getBlockEntity(blockPos);
|
com.sk89q.jnbt.CompoundTag tag = processor.getTileAt(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
||||||
if (tileEntity == null) {
|
if (tag == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
BlockEntity newEntity = tileEntity.getType().create(blockPos, getBlockState(blockPos));
|
BlockState state = adapter.adapt(processor.getBlockStateAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
|
||||||
newEntity.load((CompoundTag) adapter.fromNativeBinary(this.extent.getFullBlock(
|
if (!(state.getBlock() instanceof EntityBlock entityBlock)) {
|
||||||
blockPos.getX(),
|
return null;
|
||||||
blockPos.getY(),
|
}
|
||||||
blockPos.getZ()
|
BlockEntity tileEntity = entityBlock.newBlockEntity(blockPos, state);
|
||||||
).getNbtReference().getValue()));
|
tileEntity.load((CompoundTag) adapter.fromNative(tag));
|
||||||
|
return tileEntity;
|
||||||
return newEntity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public BlockState getBlockState(@Nonnull BlockPos blockPos) {
|
public BlockState getBlockState(@Nonnull BlockPos blockPos) {
|
||||||
if (!enabled) {
|
if (blockPos.getX() == Integer.MAX_VALUE) {
|
||||||
return Blocks.AIR.defaultBlockState();
|
return Blocks.AIR.defaultBlockState();
|
||||||
}
|
}
|
||||||
com.sk89q.worldedit.world.block.BlockState state = this.extent.getBlock(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
com.sk89q.worldedit.world.block.BlockState state = processor.getBlockStateAt(
|
||||||
|
blockPos.getX(),
|
||||||
|
blockPos.getY(),
|
||||||
|
blockPos.getZ()
|
||||||
|
);
|
||||||
return adapter.adapt(state);
|
return adapter.adapt(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +79,7 @@ public class PaperweightLevelProxy extends ServerLevel {
|
|||||||
@Override
|
@Override
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public FluidState getFluidState(@Nonnull BlockPos pos) {
|
public FluidState getFluidState(@Nonnull BlockPos pos) {
|
||||||
if (!enabled) {
|
if (pos.getX() == Integer.MAX_VALUE) {
|
||||||
return Fluids.EMPTY.defaultFluidState();
|
return Fluids.EMPTY.defaultFluidState();
|
||||||
}
|
}
|
||||||
return getBlockState(pos).getFluidState();
|
return getBlockState(pos).getFluidState();
|
||||||
@ -94,7 +88,7 @@ public class PaperweightLevelProxy extends ServerLevel {
|
|||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Override
|
@Override
|
||||||
public boolean isWaterAt(@Nonnull BlockPos pos) {
|
public boolean isWaterAt(@Nonnull BlockPos pos) {
|
||||||
if (!enabled) {
|
if (pos.getX() == Integer.MAX_VALUE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return getBlockState(pos).getFluidState().is(FluidTags.WATER);
|
return getBlockState(pos).getFluidState().is(FluidTags.WATER);
|
||||||
|
@ -1,28 +1,23 @@
|
|||||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3;
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3;
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.extent.processor.PlacementStateProcessor;
|
import com.fastasyncworldedit.core.extent.PlacementStateProcessor;
|
||||||
import com.fastasyncworldedit.core.math.IntTriple;
|
|
||||||
import com.fastasyncworldedit.core.util.ExtentTraverser;
|
|
||||||
import com.fastasyncworldedit.core.wrappers.WorldWrapper;
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
|
||||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.math.Vector3;
|
import com.sk89q.worldedit.math.Vector3;
|
||||||
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.Direction;
|
import com.sk89q.worldedit.util.Direction;
|
||||||
import com.sk89q.worldedit.world.World;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Queue;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class PaperweightPlacementStateProcessor extends PlacementStateProcessor {
|
public class PaperweightPlacementStateProcessor extends PlacementStateProcessor {
|
||||||
|
|
||||||
@ -32,47 +27,22 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
|
|||||||
private final FaweMutableBlockPlaceContext mutableBlockPlaceContext;
|
private final FaweMutableBlockPlaceContext mutableBlockPlaceContext;
|
||||||
private final PaperweightLevelProxy proxyLevel;
|
private final PaperweightLevelProxy proxyLevel;
|
||||||
|
|
||||||
public PaperweightPlacementStateProcessor(
|
public PaperweightPlacementStateProcessor(Extent extent, BlockTypeMask mask, Region region) {
|
||||||
final Extent extent,
|
super(extent, mask, region);
|
||||||
final BlockTypeMask mask,
|
this.proxyLevel = PaperweightLevelProxy.getInstance(this);
|
||||||
boolean secondPass,
|
|
||||||
boolean includeUnedited
|
|
||||||
) {
|
|
||||||
super(extent, mask, secondPass, includeUnedited);
|
|
||||||
World world;
|
|
||||||
if (extent.isWorld()) {
|
|
||||||
world = (World) extent;
|
|
||||||
} else if (extent instanceof EditSession session) {
|
|
||||||
world = session.getWorld();
|
|
||||||
} else if ((world = new ExtentTraverser<>(extent).findAndGet(BukkitWorld.class)) == null) {
|
|
||||||
throw new UnsupportedOperationException("Cannot find world of extent.");
|
|
||||||
}
|
|
||||||
BukkitWorld bukkitWorld;
|
|
||||||
if (world instanceof WorldWrapper wrapper) {
|
|
||||||
bukkitWorld = (BukkitWorld) wrapper.getParent();
|
|
||||||
} else {
|
|
||||||
bukkitWorld = (BukkitWorld) world;
|
|
||||||
}
|
|
||||||
PaperweightLevelProxy proxyLevel = PaperweightLevelProxy.getInstance(
|
|
||||||
((CraftWorld) bukkitWorld.getWorld()).getHandle(),
|
|
||||||
extent
|
|
||||||
);
|
|
||||||
this.proxyLevel = PaperweightLevelProxy.getInstance(((CraftWorld) bukkitWorld.getWorld()).getHandle(),
|
|
||||||
extent
|
|
||||||
);
|
|
||||||
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PaperweightPlacementStateProcessor(
|
private PaperweightPlacementStateProcessor(
|
||||||
Extent extent,
|
Extent extent,
|
||||||
BlockTypeMask mask,
|
BlockTypeMask mask,
|
||||||
boolean secondPass,
|
Map<SecondPass, Character> crossChunkSecondPasses,
|
||||||
boolean includeUnedited,
|
ThreadLocal<PlacementStateProcessor> threadProcessors,
|
||||||
Queue<IntTriple> crossChunkSecondPasses,
|
Region region,
|
||||||
PaperweightLevelProxy proxyLevel
|
AtomicBoolean finished
|
||||||
) {
|
) {
|
||||||
super(extent, mask, secondPass, includeUnedited, crossChunkSecondPasses);
|
super(extent, mask, crossChunkSecondPasses, threadProcessors, region, finished);
|
||||||
this.proxyLevel = proxyLevel;
|
this.proxyLevel = PaperweightLevelProxy.getInstance(this);
|
||||||
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,8 +64,8 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
|
|||||||
new BlockHitResult(pos, side, blockPos, false),
|
new BlockHitResult(pos, side, blockPos, false),
|
||||||
side.getOpposite()
|
side.getOpposite()
|
||||||
));
|
));
|
||||||
return newState == null ? BlockTypesCache.ReservedIDs.AIR :
|
return newState == null ? BlockTypesCache.ReservedIDs.AIR : adapter.ibdIDToOrdinal(Block.BLOCK_STATE_REGISTRY.getId(
|
||||||
adapter.ibdIDToOrdinal(Block.BLOCK_STATE_REGISTRY.getId(newState));
|
newState));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -104,19 +74,12 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
|
|||||||
if (child == getExtent()) {
|
if (child == getExtent()) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
return new PaperweightPlacementStateProcessor(child, mask, secondPass, includeUnedited);
|
return new PaperweightPlacementStateProcessor(child, mask, region);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlacementStateProcessor fork() {
|
public PlacementStateProcessor fork() {
|
||||||
return new PaperweightPlacementStateProcessor(
|
return new PaperweightPlacementStateProcessor(extent, mask, postCompleteSecondPasses, threadProcessors, region, finished);
|
||||||
extent,
|
|
||||||
mask,
|
|
||||||
secondPass,
|
|
||||||
includeUnedited,
|
|
||||||
crossChunkSecondPasses,
|
|
||||||
proxyLevel
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import com.fastasyncworldedit.bukkit.adapter.FaweAdapter;
|
|||||||
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
|
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
|
||||||
import com.fastasyncworldedit.core.FaweCache;
|
import com.fastasyncworldedit.core.FaweCache;
|
||||||
import com.fastasyncworldedit.core.entity.LazyBaseEntity;
|
import com.fastasyncworldedit.core.entity.LazyBaseEntity;
|
||||||
import com.fastasyncworldedit.core.extent.processor.PlacementStateProcessor;
|
import com.fastasyncworldedit.core.extent.PlacementStateProcessor;
|
||||||
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
||||||
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
||||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||||
@ -36,7 +36,6 @@ import com.sk89q.worldedit.registry.state.IntegerProperty;
|
|||||||
import com.sk89q.worldedit.registry.state.Property;
|
import com.sk89q.worldedit.registry.state.Property;
|
||||||
import com.sk89q.worldedit.util.Direction;
|
import com.sk89q.worldedit.util.Direction;
|
||||||
import com.sk89q.worldedit.util.SideEffect;
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
import com.sk89q.worldedit.util.SideEffectSet;
|
|
||||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||||
import com.sk89q.worldedit.util.nbt.BinaryTag;
|
import com.sk89q.worldedit.util.nbt.BinaryTag;
|
||||||
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
||||||
@ -442,7 +441,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
}
|
}
|
||||||
|
|
||||||
public net.minecraft.world.level.block.state.BlockState adapt(BlockState blockState) {
|
public net.minecraft.world.level.block.state.BlockState adapt(BlockState blockState) {
|
||||||
return Block.stateById(ordinalToIbdID[blockState.getOrdinal()]);
|
return Block.stateById(getOrdinalToIbdID()[blockState.getOrdinal()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -614,13 +613,8 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlacementStateProcessor getPlatformPlacementProcessor(
|
public PlacementStateProcessor getPlatformPlacementProcessor(Extent extent, BlockTypeMask mask, Region region) {
|
||||||
Extent extent,
|
return new PaperweightPlacementStateProcessor(extent, mask, region);
|
||||||
BlockTypeMask mask,
|
|
||||||
boolean secondPass,
|
|
||||||
boolean includeUnedited
|
|
||||||
) {
|
|
||||||
return new PaperweightPlacementStateProcessor(extent, mask, secondPass, includeUnedited);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean wasAccessibleSinceLastSave(ChunkHolder holder) {
|
private boolean wasAccessibleSinceLastSave(ChunkHolder holder) {
|
||||||
|
@ -24,6 +24,7 @@ import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.nbt.PaperweightLazy
|
|||||||
import com.sk89q.worldedit.internal.Constants;
|
import com.sk89q.worldedit.internal.Constants;
|
||||||
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;
|
||||||
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
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.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
@ -820,7 +821,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
nmsChunk.mustNotSave = false;
|
nmsChunk.mustNotSave = false;
|
||||||
nmsChunk.setUnsaved(true);
|
nmsChunk.setUnsaved(true);
|
||||||
// send to player
|
// send to player
|
||||||
if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) {
|
if (!set.getSideEffectSet().shouldApply(SideEffect.LIGHTING) || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) {
|
||||||
this.send(finalMask, finalLightUpdate);
|
this.send(finalMask, finalLightUpdate);
|
||||||
}
|
}
|
||||||
if (finalizer != null) {
|
if (finalizer != null) {
|
||||||
|
@ -2,12 +2,12 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1;
|
|||||||
|
|
||||||
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
||||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.tags.FluidTags;
|
import net.minecraft.tags.FluidTags;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
@ -20,17 +20,15 @@ import javax.annotation.Nullable;
|
|||||||
public class PaperweightLevelProxy extends ServerLevel {
|
public class PaperweightLevelProxy extends ServerLevel {
|
||||||
|
|
||||||
private PaperweightFaweAdapter adapter;
|
private PaperweightFaweAdapter adapter;
|
||||||
private Extent extent;
|
private PaperweightPlacementStateProcessor processor;
|
||||||
private ServerLevel serverLevel;
|
|
||||||
private boolean enabled = false;
|
|
||||||
|
|
||||||
@SuppressWarnings("DataFlowIssue")
|
@SuppressWarnings("DataFlowIssue")
|
||||||
public PaperweightLevelProxy() {
|
private PaperweightLevelProxy() {
|
||||||
super(null, null, null, null, null, null, null, true, 0L, null, true, null, null, null, null);
|
super(null, null, null, null, null, null, null, true, 0L, null, true, null, null, null, null);
|
||||||
throw new IllegalStateException("Cannot be instantiated");
|
throw new IllegalStateException("Cannot be instantiated");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PaperweightLevelProxy getInstance(ServerLevel level, Extent extent) {
|
public static PaperweightLevelProxy getInstance(PaperweightPlacementStateProcessor processor) {
|
||||||
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
||||||
|
|
||||||
PaperweightLevelProxy newLevel;
|
PaperweightLevelProxy newLevel;
|
||||||
@ -39,45 +37,41 @@ public class PaperweightLevelProxy extends ServerLevel {
|
|||||||
} catch (InstantiationException e) {
|
} catch (InstantiationException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin
|
newLevel.processor = processor;
|
||||||
.getInstance()
|
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin.getInstance().getBukkitImplAdapter());
|
||||||
.getBukkitImplAdapter());
|
|
||||||
newLevel.extent = extent;
|
|
||||||
newLevel.serverLevel = level;
|
|
||||||
return newLevel;
|
return newLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEnabled(boolean enabled) {
|
|
||||||
this.enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public BlockEntity getBlockEntity(@Nonnull BlockPos blockPos) {
|
public BlockEntity getBlockEntity(@Nonnull BlockPos blockPos) {
|
||||||
if (!enabled) {
|
if (blockPos.getX() == Integer.MAX_VALUE) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
BlockEntity tileEntity = this.serverLevel.getChunkAt(blockPos).getBlockEntity(blockPos);
|
com.sk89q.jnbt.CompoundTag tag = processor.getTileAt(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
||||||
if (tileEntity == null) {
|
if (tag == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
BlockEntity newEntity = tileEntity.getType().create(blockPos, getBlockState(blockPos));
|
BlockState state = adapter.adapt(processor.getBlockStateAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
|
||||||
newEntity.load((CompoundTag) adapter.fromNativeBinary(this.extent.getFullBlock(
|
if (!(state.getBlock() instanceof EntityBlock entityBlock)) {
|
||||||
blockPos.getX(),
|
return null;
|
||||||
blockPos.getY(),
|
}
|
||||||
blockPos.getZ()
|
BlockEntity tileEntity = entityBlock.newBlockEntity(blockPos, state);
|
||||||
).getNbtReference().getValue()));
|
tileEntity.load((CompoundTag) adapter.fromNative(tag));
|
||||||
|
return tileEntity;
|
||||||
return newEntity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public BlockState getBlockState(@Nonnull BlockPos blockPos) {
|
public BlockState getBlockState(@Nonnull BlockPos blockPos) {
|
||||||
if (!enabled) {
|
if (blockPos.getX() == Integer.MAX_VALUE) {
|
||||||
return Blocks.AIR.defaultBlockState();
|
return Blocks.AIR.defaultBlockState();
|
||||||
}
|
}
|
||||||
com.sk89q.worldedit.world.block.BlockState state = this.extent.getBlock(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
com.sk89q.worldedit.world.block.BlockState state = processor.getBlockStateAt(
|
||||||
|
blockPos.getX(),
|
||||||
|
blockPos.getY(),
|
||||||
|
blockPos.getZ()
|
||||||
|
);
|
||||||
return adapter.adapt(state);
|
return adapter.adapt(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +79,7 @@ public class PaperweightLevelProxy extends ServerLevel {
|
|||||||
@Override
|
@Override
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public FluidState getFluidState(@Nonnull BlockPos pos) {
|
public FluidState getFluidState(@Nonnull BlockPos pos) {
|
||||||
if (!enabled) {
|
if (pos.getX() == Integer.MAX_VALUE) {
|
||||||
return Fluids.EMPTY.defaultFluidState();
|
return Fluids.EMPTY.defaultFluidState();
|
||||||
}
|
}
|
||||||
return getBlockState(pos).getFluidState();
|
return getBlockState(pos).getFluidState();
|
||||||
@ -94,7 +88,7 @@ public class PaperweightLevelProxy extends ServerLevel {
|
|||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Override
|
@Override
|
||||||
public boolean isWaterAt(@Nonnull BlockPos pos) {
|
public boolean isWaterAt(@Nonnull BlockPos pos) {
|
||||||
if (!enabled) {
|
if (pos.getX() == Integer.MAX_VALUE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return getBlockState(pos).getFluidState().is(FluidTags.WATER);
|
return getBlockState(pos).getFluidState().is(FluidTags.WATER);
|
||||||
|
@ -1,28 +1,23 @@
|
|||||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1;
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1;
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.extent.processor.PlacementStateProcessor;
|
import com.fastasyncworldedit.core.extent.PlacementStateProcessor;
|
||||||
import com.fastasyncworldedit.core.math.IntTriple;
|
|
||||||
import com.fastasyncworldedit.core.util.ExtentTraverser;
|
|
||||||
import com.fastasyncworldedit.core.wrappers.WorldWrapper;
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
|
||||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.math.Vector3;
|
import com.sk89q.worldedit.math.Vector3;
|
||||||
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.Direction;
|
import com.sk89q.worldedit.util.Direction;
|
||||||
import com.sk89q.worldedit.world.World;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Queue;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class PaperweightPlacementStateProcessor extends PlacementStateProcessor {
|
public class PaperweightPlacementStateProcessor extends PlacementStateProcessor {
|
||||||
|
|
||||||
@ -32,47 +27,22 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
|
|||||||
private final FaweMutableBlockPlaceContext mutableBlockPlaceContext;
|
private final FaweMutableBlockPlaceContext mutableBlockPlaceContext;
|
||||||
private final PaperweightLevelProxy proxyLevel;
|
private final PaperweightLevelProxy proxyLevel;
|
||||||
|
|
||||||
public PaperweightPlacementStateProcessor(
|
public PaperweightPlacementStateProcessor(Extent extent, BlockTypeMask mask, Region region) {
|
||||||
final Extent extent,
|
super(extent, mask, region);
|
||||||
final BlockTypeMask mask,
|
this.proxyLevel = PaperweightLevelProxy.getInstance(this);
|
||||||
boolean secondPass,
|
|
||||||
boolean includeUnedited
|
|
||||||
) {
|
|
||||||
super(extent, mask, secondPass, includeUnedited);
|
|
||||||
World world;
|
|
||||||
if (extent.isWorld()) {
|
|
||||||
world = (World) extent;
|
|
||||||
} else if (extent instanceof EditSession session) {
|
|
||||||
world = session.getWorld();
|
|
||||||
} else if ((world = new ExtentTraverser<>(extent).findAndGet(BukkitWorld.class)) == null) {
|
|
||||||
throw new UnsupportedOperationException("Cannot find world of extent.");
|
|
||||||
}
|
|
||||||
BukkitWorld bukkitWorld;
|
|
||||||
if (world instanceof WorldWrapper wrapper) {
|
|
||||||
bukkitWorld = (BukkitWorld) wrapper.getParent();
|
|
||||||
} else {
|
|
||||||
bukkitWorld = (BukkitWorld) world;
|
|
||||||
}
|
|
||||||
PaperweightLevelProxy proxyLevel = PaperweightLevelProxy.getInstance(
|
|
||||||
((CraftWorld) bukkitWorld.getWorld()).getHandle(),
|
|
||||||
extent
|
|
||||||
);
|
|
||||||
this.proxyLevel = PaperweightLevelProxy.getInstance(((CraftWorld) bukkitWorld.getWorld()).getHandle(),
|
|
||||||
extent
|
|
||||||
);
|
|
||||||
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PaperweightPlacementStateProcessor(
|
private PaperweightPlacementStateProcessor(
|
||||||
Extent extent,
|
Extent extent,
|
||||||
BlockTypeMask mask,
|
BlockTypeMask mask,
|
||||||
boolean secondPass,
|
Map<SecondPass, Character> crossChunkSecondPasses,
|
||||||
boolean includeUnedited,
|
ThreadLocal<PlacementStateProcessor> threadProcessors,
|
||||||
Queue<IntTriple> crossChunkSecondPasses,
|
Region region,
|
||||||
PaperweightLevelProxy proxyLevel
|
AtomicBoolean finished
|
||||||
) {
|
) {
|
||||||
super(extent, mask, secondPass, includeUnedited, crossChunkSecondPasses);
|
super(extent, mask, crossChunkSecondPasses, threadProcessors, region, finished);
|
||||||
this.proxyLevel = proxyLevel;
|
this.proxyLevel = PaperweightLevelProxy.getInstance(this);
|
||||||
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,19 +74,12 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
|
|||||||
if (child == getExtent()) {
|
if (child == getExtent()) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
return new PaperweightPlacementStateProcessor(child, mask, secondPass, includeUnedited);
|
return new PaperweightPlacementStateProcessor(child, mask, region);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlacementStateProcessor fork() {
|
public PlacementStateProcessor fork() {
|
||||||
return new PaperweightPlacementStateProcessor(
|
return new PaperweightPlacementStateProcessor(extent, mask, postCompleteSecondPasses, threadProcessors, region, finished);
|
||||||
extent,
|
|
||||||
mask,
|
|
||||||
secondPass,
|
|
||||||
includeUnedited,
|
|
||||||
crossChunkSecondPasses,
|
|
||||||
proxyLevel
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import com.fastasyncworldedit.bukkit.adapter.FaweAdapter;
|
|||||||
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
|
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
|
||||||
import com.fastasyncworldedit.core.FaweCache;
|
import com.fastasyncworldedit.core.FaweCache;
|
||||||
import com.fastasyncworldedit.core.entity.LazyBaseEntity;
|
import com.fastasyncworldedit.core.entity.LazyBaseEntity;
|
||||||
import com.fastasyncworldedit.core.extent.processor.PlacementStateProcessor;
|
import com.fastasyncworldedit.core.extent.PlacementStateProcessor;
|
||||||
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
||||||
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
||||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||||
@ -35,7 +35,6 @@ import com.sk89q.worldedit.registry.state.IntegerProperty;
|
|||||||
import com.sk89q.worldedit.registry.state.Property;
|
import com.sk89q.worldedit.registry.state.Property;
|
||||||
import com.sk89q.worldedit.util.Direction;
|
import com.sk89q.worldedit.util.Direction;
|
||||||
import com.sk89q.worldedit.util.SideEffect;
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
import com.sk89q.worldedit.util.SideEffectSet;
|
|
||||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||||
import com.sk89q.worldedit.util.nbt.BinaryTag;
|
import com.sk89q.worldedit.util.nbt.BinaryTag;
|
||||||
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
||||||
@ -445,7 +444,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
}
|
}
|
||||||
|
|
||||||
public net.minecraft.world.level.block.state.BlockState adapt(BlockState blockState) {
|
public net.minecraft.world.level.block.state.BlockState adapt(BlockState blockState) {
|
||||||
return Block.stateById(ordinalToIbdID[blockState.getOrdinal()]);
|
return Block.stateById(getOrdinalToIbdID()[blockState.getOrdinal()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -617,13 +616,8 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlacementStateProcessor getPlatformPlacementProcessor(
|
public PlacementStateProcessor getPlatformPlacementProcessor(Extent extent, BlockTypeMask mask, Region region) {
|
||||||
Extent extent,
|
return new PaperweightPlacementStateProcessor(extent, mask, region);
|
||||||
BlockTypeMask mask,
|
|
||||||
boolean secondPass,
|
|
||||||
boolean includeUnedited
|
|
||||||
) {
|
|
||||||
return new PaperweightPlacementStateProcessor(extent, mask, secondPass, includeUnedited);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean wasAccessibleSinceLastSave(ChunkHolder holder) {
|
private boolean wasAccessibleSinceLastSave(ChunkHolder holder) {
|
||||||
|
@ -24,12 +24,17 @@ import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R2.nbt.PaperweightLazy
|
|||||||
import com.sk89q.worldedit.internal.Constants;
|
import com.sk89q.worldedit.internal.Constants;
|
||||||
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;
|
||||||
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
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.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import io.papermc.paper.event.block.BeaconDeactivatedEvent;
|
import io.papermc.paper.event.block.BeaconDeactivatedEvent;
|
||||||
import net.minecraft.core.*;
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.core.IdMap;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.core.SectionPos;
|
||||||
import net.minecraft.nbt.IntTag;
|
import net.minecraft.nbt.IntTag;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.sounds.SoundEvents;
|
import net.minecraft.sounds.SoundEvents;
|
||||||
@ -42,7 +47,14 @@ import net.minecraft.world.level.biome.Biome;
|
|||||||
import net.minecraft.world.level.block.entity.BeaconBlockEntity;
|
import net.minecraft.world.level.block.entity.BeaconBlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.chunk.*;
|
import net.minecraft.world.level.chunk.DataLayer;
|
||||||
|
import net.minecraft.world.level.chunk.HashMapPalette;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||||
|
import net.minecraft.world.level.chunk.LinearPalette;
|
||||||
|
import net.minecraft.world.level.chunk.Palette;
|
||||||
|
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||||
|
import net.minecraft.world.level.chunk.PalettedContainerRO;
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
@ -52,7 +64,17 @@ import org.bukkit.craftbukkit.v1_20_R2.block.CraftBlock;
|
|||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.*;
|
import java.util.AbstractSet;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
@ -807,7 +829,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
nmsChunk.mustNotSave = false;
|
nmsChunk.mustNotSave = false;
|
||||||
nmsChunk.setUnsaved(true);
|
nmsChunk.setUnsaved(true);
|
||||||
// send to player
|
// send to player
|
||||||
if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) {
|
if (!set.getSideEffectSet().shouldApply(SideEffect.LIGHTING) || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) {
|
||||||
this.send(finalMask, finalLightUpdate);
|
this.send(finalMask, finalLightUpdate);
|
||||||
}
|
}
|
||||||
if (finalizer != null) {
|
if (finalizer != null) {
|
||||||
|
@ -2,12 +2,12 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R2;
|
|||||||
|
|
||||||
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
||||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.tags.FluidTags;
|
import net.minecraft.tags.FluidTags;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
@ -20,17 +20,15 @@ import javax.annotation.Nullable;
|
|||||||
public class PaperweightLevelProxy extends ServerLevel {
|
public class PaperweightLevelProxy extends ServerLevel {
|
||||||
|
|
||||||
private PaperweightFaweAdapter adapter;
|
private PaperweightFaweAdapter adapter;
|
||||||
private Extent extent;
|
private PaperweightPlacementStateProcessor processor;
|
||||||
private ServerLevel serverLevel;
|
|
||||||
private boolean enabled = false;
|
|
||||||
|
|
||||||
@SuppressWarnings("DataFlowIssue")
|
@SuppressWarnings("DataFlowIssue")
|
||||||
public PaperweightLevelProxy() {
|
private PaperweightLevelProxy() {
|
||||||
super(null, null, null, null, null, null, null, true, 0L, null, true, null, null, null, null);
|
super(null, null, null, null, null, null, null, true, 0L, null, true, null, null, null, null);
|
||||||
throw new IllegalStateException("Cannot be instantiated");
|
throw new IllegalStateException("Cannot be instantiated");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PaperweightLevelProxy getInstance(ServerLevel level, Extent extent) {
|
public static PaperweightLevelProxy getInstance(PaperweightPlacementStateProcessor processor) {
|
||||||
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
||||||
|
|
||||||
PaperweightLevelProxy newLevel;
|
PaperweightLevelProxy newLevel;
|
||||||
@ -39,45 +37,41 @@ public class PaperweightLevelProxy extends ServerLevel {
|
|||||||
} catch (InstantiationException e) {
|
} catch (InstantiationException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin
|
newLevel.processor = processor;
|
||||||
.getInstance()
|
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin.getInstance().getBukkitImplAdapter());
|
||||||
.getBukkitImplAdapter());
|
|
||||||
newLevel.extent = extent;
|
|
||||||
newLevel.serverLevel = level;
|
|
||||||
return newLevel;
|
return newLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEnabled(boolean enabled) {
|
|
||||||
this.enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public BlockEntity getBlockEntity(@Nonnull BlockPos blockPos) {
|
public BlockEntity getBlockEntity(@Nonnull BlockPos blockPos) {
|
||||||
if (!enabled) {
|
if (blockPos.getX() == Integer.MAX_VALUE) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
BlockEntity tileEntity = this.serverLevel.getChunkAt(blockPos).getBlockEntity(blockPos);
|
com.sk89q.jnbt.CompoundTag tag = processor.getTileAt(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
||||||
if (tileEntity == null) {
|
if (tag == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
BlockEntity newEntity = tileEntity.getType().create(blockPos, getBlockState(blockPos));
|
BlockState state = adapter.adapt(processor.getBlockStateAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
|
||||||
newEntity.load((CompoundTag) adapter.fromNativeBinary(this.extent.getFullBlock(
|
if (!(state.getBlock() instanceof EntityBlock entityBlock)) {
|
||||||
blockPos.getX(),
|
return null;
|
||||||
blockPos.getY(),
|
}
|
||||||
blockPos.getZ()
|
BlockEntity tileEntity = entityBlock.newBlockEntity(blockPos, state);
|
||||||
).getNbtReference().getValue()));
|
tileEntity.load((CompoundTag) adapter.fromNative(tag));
|
||||||
|
return tileEntity;
|
||||||
return newEntity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public BlockState getBlockState(@Nonnull BlockPos blockPos) {
|
public BlockState getBlockState(@Nonnull BlockPos blockPos) {
|
||||||
if (!enabled) {
|
if (blockPos.getX() == Integer.MAX_VALUE) {
|
||||||
return Blocks.AIR.defaultBlockState();
|
return Blocks.AIR.defaultBlockState();
|
||||||
}
|
}
|
||||||
com.sk89q.worldedit.world.block.BlockState state = this.extent.getBlock(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
com.sk89q.worldedit.world.block.BlockState state = processor.getBlockStateAt(
|
||||||
|
blockPos.getX(),
|
||||||
|
blockPos.getY(),
|
||||||
|
blockPos.getZ()
|
||||||
|
);
|
||||||
return adapter.adapt(state);
|
return adapter.adapt(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +79,7 @@ public class PaperweightLevelProxy extends ServerLevel {
|
|||||||
@Override
|
@Override
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public FluidState getFluidState(@Nonnull BlockPos pos) {
|
public FluidState getFluidState(@Nonnull BlockPos pos) {
|
||||||
if (!enabled) {
|
if (pos.getX() == Integer.MAX_VALUE) {
|
||||||
return Fluids.EMPTY.defaultFluidState();
|
return Fluids.EMPTY.defaultFluidState();
|
||||||
}
|
}
|
||||||
return getBlockState(pos).getFluidState();
|
return getBlockState(pos).getFluidState();
|
||||||
@ -94,7 +88,7 @@ public class PaperweightLevelProxy extends ServerLevel {
|
|||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Override
|
@Override
|
||||||
public boolean isWaterAt(@Nonnull BlockPos pos) {
|
public boolean isWaterAt(@Nonnull BlockPos pos) {
|
||||||
if (!enabled) {
|
if (pos.getX() == Integer.MAX_VALUE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return getBlockState(pos).getFluidState().is(FluidTags.WATER);
|
return getBlockState(pos).getFluidState().is(FluidTags.WATER);
|
||||||
|
@ -1,28 +1,23 @@
|
|||||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R2;
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R2;
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.extent.processor.PlacementStateProcessor;
|
import com.fastasyncworldedit.core.extent.PlacementStateProcessor;
|
||||||
import com.fastasyncworldedit.core.math.IntTriple;
|
|
||||||
import com.fastasyncworldedit.core.util.ExtentTraverser;
|
|
||||||
import com.fastasyncworldedit.core.wrappers.WorldWrapper;
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
|
||||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.math.Vector3;
|
import com.sk89q.worldedit.math.Vector3;
|
||||||
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.Direction;
|
import com.sk89q.worldedit.util.Direction;
|
||||||
import com.sk89q.worldedit.world.World;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import org.bukkit.craftbukkit.v1_20_R2.CraftWorld;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Queue;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class PaperweightPlacementStateProcessor extends PlacementStateProcessor {
|
public class PaperweightPlacementStateProcessor extends PlacementStateProcessor {
|
||||||
|
|
||||||
@ -32,47 +27,22 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
|
|||||||
private final FaweMutableBlockPlaceContext mutableBlockPlaceContext;
|
private final FaweMutableBlockPlaceContext mutableBlockPlaceContext;
|
||||||
private final PaperweightLevelProxy proxyLevel;
|
private final PaperweightLevelProxy proxyLevel;
|
||||||
|
|
||||||
public PaperweightPlacementStateProcessor(
|
public PaperweightPlacementStateProcessor(Extent extent, BlockTypeMask mask, Region region) {
|
||||||
final Extent extent,
|
super(extent, mask, region);
|
||||||
final BlockTypeMask mask,
|
this.proxyLevel = PaperweightLevelProxy.getInstance(this);
|
||||||
boolean secondPass,
|
|
||||||
boolean includeUnedited
|
|
||||||
) {
|
|
||||||
super(extent, mask, secondPass, includeUnedited);
|
|
||||||
World world;
|
|
||||||
if (extent.isWorld()) {
|
|
||||||
world = (World) extent;
|
|
||||||
} else if (extent instanceof EditSession session) {
|
|
||||||
world = session.getWorld();
|
|
||||||
} else if ((world = new ExtentTraverser<>(extent).findAndGet(BukkitWorld.class)) == null) {
|
|
||||||
throw new UnsupportedOperationException("Cannot find world of extent.");
|
|
||||||
}
|
|
||||||
BukkitWorld bukkitWorld;
|
|
||||||
if (world instanceof WorldWrapper wrapper) {
|
|
||||||
bukkitWorld = (BukkitWorld) wrapper.getParent();
|
|
||||||
} else {
|
|
||||||
bukkitWorld = (BukkitWorld) world;
|
|
||||||
}
|
|
||||||
PaperweightLevelProxy proxyLevel = PaperweightLevelProxy.getInstance(
|
|
||||||
((CraftWorld) bukkitWorld.getWorld()).getHandle(),
|
|
||||||
extent
|
|
||||||
);
|
|
||||||
this.proxyLevel = PaperweightLevelProxy.getInstance(((CraftWorld) bukkitWorld.getWorld()).getHandle(),
|
|
||||||
extent
|
|
||||||
);
|
|
||||||
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PaperweightPlacementStateProcessor(
|
private PaperweightPlacementStateProcessor(
|
||||||
Extent extent,
|
Extent extent,
|
||||||
BlockTypeMask mask,
|
BlockTypeMask mask,
|
||||||
boolean secondPass,
|
Map<SecondPass, Character> crossChunkSecondPasses,
|
||||||
boolean includeUnedited,
|
ThreadLocal<PlacementStateProcessor> threadProcessors,
|
||||||
Queue<IntTriple> crossChunkSecondPasses,
|
Region region,
|
||||||
PaperweightLevelProxy proxyLevel
|
AtomicBoolean finished
|
||||||
) {
|
) {
|
||||||
super(extent, mask, secondPass, includeUnedited, crossChunkSecondPasses);
|
super(extent, mask, crossChunkSecondPasses, threadProcessors, region, finished);
|
||||||
this.proxyLevel = proxyLevel;
|
this.proxyLevel = PaperweightLevelProxy.getInstance(this);
|
||||||
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,8 +64,8 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
|
|||||||
new BlockHitResult(pos, side, blockPos, false),
|
new BlockHitResult(pos, side, blockPos, false),
|
||||||
side.getOpposite()
|
side.getOpposite()
|
||||||
));
|
));
|
||||||
return newState == null ? BlockTypesCache.ReservedIDs.AIR :
|
return newState == null ? BlockTypesCache.ReservedIDs.AIR : adapter.ibdIDToOrdinal(Block.BLOCK_STATE_REGISTRY.getId(
|
||||||
adapter.ibdIDToOrdinal(Block.BLOCK_STATE_REGISTRY.getId(newState));
|
newState));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -104,19 +74,12 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
|
|||||||
if (child == getExtent()) {
|
if (child == getExtent()) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
return new PaperweightPlacementStateProcessor(child, mask, secondPass, includeUnedited);
|
return new PaperweightPlacementStateProcessor(child, mask, region);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlacementStateProcessor fork() {
|
public PlacementStateProcessor fork() {
|
||||||
return new PaperweightPlacementStateProcessor(
|
return new PaperweightPlacementStateProcessor(extent, mask, postCompleteSecondPasses, threadProcessors, region, finished);
|
||||||
extent,
|
|
||||||
mask,
|
|
||||||
secondPass,
|
|
||||||
includeUnedited,
|
|
||||||
crossChunkSecondPasses,
|
|
||||||
proxyLevel
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import com.fastasyncworldedit.bukkit.adapter.FaweAdapter;
|
|||||||
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
|
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
|
||||||
import com.fastasyncworldedit.core.FaweCache;
|
import com.fastasyncworldedit.core.FaweCache;
|
||||||
import com.fastasyncworldedit.core.entity.LazyBaseEntity;
|
import com.fastasyncworldedit.core.entity.LazyBaseEntity;
|
||||||
import com.fastasyncworldedit.core.extent.processor.PlacementStateProcessor;
|
import com.fastasyncworldedit.core.extent.PlacementStateProcessor;
|
||||||
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
||||||
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
||||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||||
@ -34,7 +34,6 @@ import com.sk89q.worldedit.registry.state.IntegerProperty;
|
|||||||
import com.sk89q.worldedit.registry.state.Property;
|
import com.sk89q.worldedit.registry.state.Property;
|
||||||
import com.sk89q.worldedit.util.Direction;
|
import com.sk89q.worldedit.util.Direction;
|
||||||
import com.sk89q.worldedit.util.SideEffect;
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
import com.sk89q.worldedit.util.SideEffectSet;
|
|
||||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||||
import com.sk89q.worldedit.util.nbt.BinaryTag;
|
import com.sk89q.worldedit.util.nbt.BinaryTag;
|
||||||
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
||||||
@ -444,7 +443,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
}
|
}
|
||||||
|
|
||||||
public net.minecraft.world.level.block.state.BlockState adapt(BlockState blockState) {
|
public net.minecraft.world.level.block.state.BlockState adapt(BlockState blockState) {
|
||||||
return Block.stateById(ordinalToIbdID[blockState.getOrdinal()]);
|
return Block.stateById(getOrdinalToIbdID()[blockState.getOrdinal()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -484,7 +483,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canPlaceAt(org.bukkit.World world, BlockVector3 blockVector3, BlockState blockState) {
|
public boolean canPlaceAt(org.bukkit.World world, BlockVector3 blockVector3, BlockState blockState) {
|
||||||
net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(ordinalToIbdID[blockState.getOrdinal()]);
|
net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(getOrdinalToIbdID()[blockState.getOrdinal()]);
|
||||||
return blockState1.hasPostProcess(
|
return blockState1.hasPostProcess(
|
||||||
getServerLevel(world),
|
getServerLevel(world),
|
||||||
new BlockPos(blockVector3.getX(), blockVector3.getY(), blockVector3.getZ())
|
new BlockPos(blockVector3.getX(), blockVector3.getY(), blockVector3.getZ())
|
||||||
@ -615,13 +614,8 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlacementStateProcessor getPlatformPlacementProcessor(
|
public PlacementStateProcessor getPlatformPlacementProcessor(Extent extent, BlockTypeMask mask, Region region) {
|
||||||
Extent extent,
|
return new PaperweightPlacementStateProcessor(extent, mask, region);
|
||||||
BlockTypeMask mask,
|
|
||||||
boolean secondPass,
|
|
||||||
boolean includeUnedited
|
|
||||||
) {
|
|
||||||
return new PaperweightPlacementStateProcessor(extent, mask, secondPass, includeUnedited);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean wasAccessibleSinceLastSave(ChunkHolder holder) {
|
private boolean wasAccessibleSinceLastSave(ChunkHolder holder) {
|
||||||
|
@ -24,12 +24,17 @@ import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R3.nbt.PaperweightLazy
|
|||||||
import com.sk89q.worldedit.internal.Constants;
|
import com.sk89q.worldedit.internal.Constants;
|
||||||
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;
|
||||||
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
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.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import io.papermc.paper.event.block.BeaconDeactivatedEvent;
|
import io.papermc.paper.event.block.BeaconDeactivatedEvent;
|
||||||
import net.minecraft.core.*;
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.core.IdMap;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.core.SectionPos;
|
||||||
import net.minecraft.nbt.IntTag;
|
import net.minecraft.nbt.IntTag;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.sounds.SoundEvents;
|
import net.minecraft.sounds.SoundEvents;
|
||||||
@ -42,7 +47,14 @@ import net.minecraft.world.level.biome.Biome;
|
|||||||
import net.minecraft.world.level.block.entity.BeaconBlockEntity;
|
import net.minecraft.world.level.block.entity.BeaconBlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.chunk.*;
|
import net.minecraft.world.level.chunk.DataLayer;
|
||||||
|
import net.minecraft.world.level.chunk.HashMapPalette;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||||
|
import net.minecraft.world.level.chunk.LinearPalette;
|
||||||
|
import net.minecraft.world.level.chunk.Palette;
|
||||||
|
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||||
|
import net.minecraft.world.level.chunk.PalettedContainerRO;
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
@ -52,7 +64,17 @@ import org.bukkit.craftbukkit.v1_20_R3.block.CraftBlock;
|
|||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.*;
|
import java.util.AbstractSet;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
@ -807,7 +829,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
nmsChunk.mustNotSave = false;
|
nmsChunk.mustNotSave = false;
|
||||||
nmsChunk.setUnsaved(true);
|
nmsChunk.setUnsaved(true);
|
||||||
// send to player
|
// send to player
|
||||||
if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) {
|
if (!set.getSideEffectSet().shouldApply(SideEffect.LIGHTING) || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) {
|
||||||
this.send(finalMask, finalLightUpdate);
|
this.send(finalMask, finalLightUpdate);
|
||||||
}
|
}
|
||||||
if (finalizer != null) {
|
if (finalizer != null) {
|
||||||
|
@ -2,12 +2,12 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R3;
|
|||||||
|
|
||||||
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
||||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.tags.FluidTags;
|
import net.minecraft.tags.FluidTags;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
@ -20,17 +20,15 @@ import javax.annotation.Nullable;
|
|||||||
public class PaperweightLevelProxy extends ServerLevel {
|
public class PaperweightLevelProxy extends ServerLevel {
|
||||||
|
|
||||||
private PaperweightFaweAdapter adapter;
|
private PaperweightFaweAdapter adapter;
|
||||||
private Extent extent;
|
private PaperweightPlacementStateProcessor processor;
|
||||||
private ServerLevel serverLevel;
|
|
||||||
private boolean enabled = false;
|
|
||||||
|
|
||||||
@SuppressWarnings("DataFlowIssue")
|
@SuppressWarnings("DataFlowIssue")
|
||||||
public PaperweightLevelProxy() {
|
private PaperweightLevelProxy() {
|
||||||
super(null, null, null, null, null, null, null, true, 0L, null, true, null, null, null, null);
|
super(null, null, null, null, null, null, null, true, 0L, null, true, null, null, null, null);
|
||||||
throw new IllegalStateException("Cannot be instantiated");
|
throw new IllegalStateException("Cannot be instantiated");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PaperweightLevelProxy getInstance(ServerLevel level, Extent extent) {
|
public static PaperweightLevelProxy getInstance(PaperweightPlacementStateProcessor processor) {
|
||||||
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
||||||
|
|
||||||
PaperweightLevelProxy newLevel;
|
PaperweightLevelProxy newLevel;
|
||||||
@ -39,45 +37,41 @@ public class PaperweightLevelProxy extends ServerLevel {
|
|||||||
} catch (InstantiationException e) {
|
} catch (InstantiationException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin
|
newLevel.processor = processor;
|
||||||
.getInstance()
|
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin.getInstance().getBukkitImplAdapter());
|
||||||
.getBukkitImplAdapter());
|
|
||||||
newLevel.extent = extent;
|
|
||||||
newLevel.serverLevel = level;
|
|
||||||
return newLevel;
|
return newLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEnabled(boolean enabled) {
|
|
||||||
this.enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public BlockEntity getBlockEntity(@Nonnull BlockPos blockPos) {
|
public BlockEntity getBlockEntity(@Nonnull BlockPos blockPos) {
|
||||||
if (!enabled) {
|
if (blockPos.getY() == Integer.MAX_VALUE) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
BlockEntity tileEntity = this.serverLevel.getChunkAt(blockPos).getBlockEntity(blockPos);
|
com.sk89q.jnbt.CompoundTag tag = processor.getTileAt(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
||||||
if (tileEntity == null) {
|
if (tag == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
BlockEntity newEntity = tileEntity.getType().create(blockPos, getBlockState(blockPos));
|
BlockState state = adapter.adapt(processor.getBlockStateAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
|
||||||
newEntity.load((CompoundTag) adapter.fromNativeBinary(this.extent.getFullBlock(
|
if (!(state.getBlock() instanceof EntityBlock entityBlock)) {
|
||||||
blockPos.getX(),
|
return null;
|
||||||
blockPos.getY(),
|
}
|
||||||
blockPos.getZ()
|
BlockEntity tileEntity = entityBlock.newBlockEntity(blockPos, state);
|
||||||
).getNbtReference().getValue()));
|
tileEntity.load((CompoundTag) adapter.fromNative(tag));
|
||||||
|
return tileEntity;
|
||||||
return newEntity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public BlockState getBlockState(@Nonnull BlockPos blockPos) {
|
public BlockState getBlockState(@Nonnull BlockPos blockPos) {
|
||||||
if (!enabled) {
|
if (blockPos.getY() == Integer.MAX_VALUE) {
|
||||||
return Blocks.AIR.defaultBlockState();
|
return Blocks.AIR.defaultBlockState();
|
||||||
}
|
}
|
||||||
com.sk89q.worldedit.world.block.BlockState state = this.extent.getBlock(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
com.sk89q.worldedit.world.block.BlockState state = processor.getBlockStateAt(
|
||||||
|
blockPos.getX(),
|
||||||
|
blockPos.getY(),
|
||||||
|
blockPos.getZ()
|
||||||
|
);
|
||||||
return adapter.adapt(state);
|
return adapter.adapt(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +79,7 @@ public class PaperweightLevelProxy extends ServerLevel {
|
|||||||
@Override
|
@Override
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public FluidState getFluidState(@Nonnull BlockPos pos) {
|
public FluidState getFluidState(@Nonnull BlockPos pos) {
|
||||||
if (!enabled) {
|
if (pos.getY() == Integer.MAX_VALUE) {
|
||||||
return Fluids.EMPTY.defaultFluidState();
|
return Fluids.EMPTY.defaultFluidState();
|
||||||
}
|
}
|
||||||
return getBlockState(pos).getFluidState();
|
return getBlockState(pos).getFluidState();
|
||||||
@ -94,7 +88,7 @@ public class PaperweightLevelProxy extends ServerLevel {
|
|||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Override
|
@Override
|
||||||
public boolean isWaterAt(@Nonnull BlockPos pos) {
|
public boolean isWaterAt(@Nonnull BlockPos pos) {
|
||||||
if (!enabled) {
|
if (pos.getY() == Integer.MAX_VALUE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return getBlockState(pos).getFluidState().is(FluidTags.WATER);
|
return getBlockState(pos).getFluidState().is(FluidTags.WATER);
|
||||||
|
@ -1,28 +1,23 @@
|
|||||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R3;
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R3;
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.extent.processor.PlacementStateProcessor;
|
import com.fastasyncworldedit.core.extent.PlacementStateProcessor;
|
||||||
import com.fastasyncworldedit.core.math.IntTriple;
|
|
||||||
import com.fastasyncworldedit.core.util.ExtentTraverser;
|
|
||||||
import com.fastasyncworldedit.core.wrappers.WorldWrapper;
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
|
||||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.math.Vector3;
|
import com.sk89q.worldedit.math.Vector3;
|
||||||
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.Direction;
|
import com.sk89q.worldedit.util.Direction;
|
||||||
import com.sk89q.worldedit.world.World;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import org.bukkit.craftbukkit.v1_20_R3.CraftWorld;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Queue;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class PaperweightPlacementStateProcessor extends PlacementStateProcessor {
|
public class PaperweightPlacementStateProcessor extends PlacementStateProcessor {
|
||||||
|
|
||||||
@ -32,59 +27,28 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
|
|||||||
private final FaweMutableBlockPlaceContext mutableBlockPlaceContext;
|
private final FaweMutableBlockPlaceContext mutableBlockPlaceContext;
|
||||||
private final PaperweightLevelProxy proxyLevel;
|
private final PaperweightLevelProxy proxyLevel;
|
||||||
|
|
||||||
public PaperweightPlacementStateProcessor(
|
public PaperweightPlacementStateProcessor(Extent extent, BlockTypeMask mask, Region region) {
|
||||||
final Extent extent,
|
super(extent, mask, region);
|
||||||
final BlockTypeMask mask,
|
this.proxyLevel = PaperweightLevelProxy.getInstance(this);
|
||||||
boolean secondPass,
|
|
||||||
boolean includeUnedited
|
|
||||||
) {
|
|
||||||
super(extent, mask, secondPass, includeUnedited);
|
|
||||||
World world;
|
|
||||||
if (extent.isWorld()) {
|
|
||||||
world = (World) extent;
|
|
||||||
} else if (extent instanceof EditSession session) {
|
|
||||||
world = session.getWorld();
|
|
||||||
} else if ((world = new ExtentTraverser<>(extent).findAndGet(BukkitWorld.class)) == null) {
|
|
||||||
throw new UnsupportedOperationException("Cannot find world of extent.");
|
|
||||||
}
|
|
||||||
BukkitWorld bukkitWorld;
|
|
||||||
if (world instanceof WorldWrapper wrapper) {
|
|
||||||
bukkitWorld = (BukkitWorld) wrapper.getParent();
|
|
||||||
} else {
|
|
||||||
bukkitWorld = (BukkitWorld) world;
|
|
||||||
}
|
|
||||||
PaperweightLevelProxy proxyLevel = PaperweightLevelProxy.getInstance(
|
|
||||||
((CraftWorld) bukkitWorld.getWorld()).getHandle(),
|
|
||||||
extent
|
|
||||||
);
|
|
||||||
this.proxyLevel = PaperweightLevelProxy.getInstance(((CraftWorld) bukkitWorld.getWorld()).getHandle(),
|
|
||||||
extent
|
|
||||||
);
|
|
||||||
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PaperweightPlacementStateProcessor(
|
private PaperweightPlacementStateProcessor(
|
||||||
Extent extent,
|
Extent extent,
|
||||||
BlockTypeMask mask,
|
BlockTypeMask mask,
|
||||||
boolean secondPass,
|
Map<SecondPass, Character> crossChunkSecondPasses,
|
||||||
boolean includeUnedited,
|
ThreadLocal<PlacementStateProcessor> threadProcessors,
|
||||||
Queue<IntTriple> crossChunkSecondPasses,
|
Region region,
|
||||||
PaperweightLevelProxy proxyLevel
|
AtomicBoolean finished
|
||||||
) {
|
) {
|
||||||
super(extent, mask, secondPass, includeUnedited, crossChunkSecondPasses);
|
super(extent, mask, crossChunkSecondPasses, threadProcessors, region, finished);
|
||||||
this.proxyLevel = proxyLevel;
|
this.proxyLevel = PaperweightLevelProxy.getInstance(this);
|
||||||
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected char getStateAtFor(
|
protected char getStateAtFor(
|
||||||
int x,
|
int x, int y, int z, BlockState state, Vector3 clickPos, Direction clickedFaceDirection, BlockVector3 clickedBlock
|
||||||
int y,
|
|
||||||
int z,
|
|
||||||
BlockState state,
|
|
||||||
Vector3 clickPos,
|
|
||||||
Direction clickedFaceDirection,
|
|
||||||
BlockVector3 clickedBlock
|
|
||||||
) {
|
) {
|
||||||
Block block = ((PaperweightBlockMaterial) state.getMaterial()).getBlock();
|
Block block = ((PaperweightBlockMaterial) state.getMaterial()).getBlock();
|
||||||
Vec3 pos = new Vec3(clickPos.x(), clickPos.y(), clickPos.z());
|
Vec3 pos = new Vec3(clickPos.x(), clickPos.y(), clickPos.z());
|
||||||
@ -94,8 +58,8 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
|
|||||||
new BlockHitResult(pos, side, blockPos, false),
|
new BlockHitResult(pos, side, blockPos, false),
|
||||||
side.getOpposite()
|
side.getOpposite()
|
||||||
));
|
));
|
||||||
return newState == null ? BlockTypesCache.ReservedIDs.AIR :
|
return newState == null ? BlockTypesCache.ReservedIDs.AIR : adapter.ibdIDToOrdinal(Block.BLOCK_STATE_REGISTRY.getId(
|
||||||
adapter.ibdIDToOrdinal(Block.BLOCK_STATE_REGISTRY.getId(newState));
|
newState));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -104,19 +68,12 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
|
|||||||
if (child == getExtent()) {
|
if (child == getExtent()) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
return new PaperweightPlacementStateProcessor(child, mask, secondPass, includeUnedited);
|
return new PaperweightPlacementStateProcessor(child, mask, region);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlacementStateProcessor fork() {
|
public PlacementStateProcessor fork() {
|
||||||
return new PaperweightPlacementStateProcessor(
|
return new PaperweightPlacementStateProcessor(extent, mask, postCompleteSecondPasses, threadProcessors, region, finished);
|
||||||
extent,
|
|
||||||
mask,
|
|
||||||
secondPass,
|
|
||||||
includeUnedited,
|
|
||||||
crossChunkSecondPasses,
|
|
||||||
proxyLevel
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import com.fastasyncworldedit.bukkit.adapter.FaweAdapter;
|
|||||||
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
|
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
|
||||||
import com.fastasyncworldedit.core.FaweCache;
|
import com.fastasyncworldedit.core.FaweCache;
|
||||||
import com.fastasyncworldedit.core.entity.LazyBaseEntity;
|
import com.fastasyncworldedit.core.entity.LazyBaseEntity;
|
||||||
import com.fastasyncworldedit.core.extent.processor.PlacementStateProcessor;
|
import com.fastasyncworldedit.core.extent.PlacementStateProcessor;
|
||||||
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
||||||
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
||||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||||
@ -453,7 +453,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
}
|
}
|
||||||
|
|
||||||
public net.minecraft.world.level.block.state.BlockState adapt(BlockState blockState) {
|
public net.minecraft.world.level.block.state.BlockState adapt(BlockState blockState) {
|
||||||
return Block.stateById(ordinalToIbdID[blockState.getOrdinal()]);
|
return Block.stateById(getOrdinalToIbdID()[blockState.getOrdinal()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -638,13 +638,8 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlacementStateProcessor getPlatformPlacementProcessor(
|
public PlacementStateProcessor getPlatformPlacementProcessor(Extent extent, BlockTypeMask mask, Region region) {
|
||||||
Extent extent,
|
return new PaperweightPlacementStateProcessor(extent, mask, region);
|
||||||
BlockTypeMask mask,
|
|
||||||
boolean secondPass,
|
|
||||||
boolean includeUnedited
|
|
||||||
) {
|
|
||||||
return new PaperweightPlacementStateProcessor(extent, mask, secondPass, includeUnedited);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean wasAccessibleSinceLastSave(ChunkHolder holder) {
|
private boolean wasAccessibleSinceLastSave(ChunkHolder holder) {
|
||||||
|
@ -24,12 +24,17 @@ import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.nbt.PaperweightLazy
|
|||||||
import com.sk89q.worldedit.internal.Constants;
|
import com.sk89q.worldedit.internal.Constants;
|
||||||
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;
|
||||||
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
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.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import io.papermc.paper.event.block.BeaconDeactivatedEvent;
|
import io.papermc.paper.event.block.BeaconDeactivatedEvent;
|
||||||
import net.minecraft.core.*;
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.core.IdMap;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.core.SectionPos;
|
||||||
import net.minecraft.nbt.IntTag;
|
import net.minecraft.nbt.IntTag;
|
||||||
import net.minecraft.server.dedicated.DedicatedServer;
|
import net.minecraft.server.dedicated.DedicatedServer;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
@ -43,7 +48,14 @@ import net.minecraft.world.level.biome.Biome;
|
|||||||
import net.minecraft.world.level.block.entity.BeaconBlockEntity;
|
import net.minecraft.world.level.block.entity.BeaconBlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.chunk.*;
|
import net.minecraft.world.level.chunk.DataLayer;
|
||||||
|
import net.minecraft.world.level.chunk.HashMapPalette;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||||
|
import net.minecraft.world.level.chunk.LinearPalette;
|
||||||
|
import net.minecraft.world.level.chunk.Palette;
|
||||||
|
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||||
|
import net.minecraft.world.level.chunk.PalettedContainerRO;
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
@ -53,7 +65,17 @@ import org.bukkit.craftbukkit.block.CraftBlock;
|
|||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.*;
|
import java.util.AbstractSet;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
@ -809,7 +831,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
nmsChunk.mustNotSave = false;
|
nmsChunk.mustNotSave = false;
|
||||||
nmsChunk.setUnsaved(true);
|
nmsChunk.setUnsaved(true);
|
||||||
// send to player
|
// send to player
|
||||||
if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) {
|
if (!set.getSideEffectSet().shouldApply(SideEffect.LIGHTING) || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) {
|
||||||
this.send(finalMask, finalLightUpdate);
|
this.send(finalMask, finalLightUpdate);
|
||||||
}
|
}
|
||||||
if (finalizer != null) {
|
if (finalizer != null) {
|
||||||
|
@ -2,12 +2,12 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
|||||||
|
|
||||||
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
||||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.tags.FluidTags;
|
import net.minecraft.tags.FluidTags;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
@ -19,17 +19,17 @@ import javax.annotation.Nullable;
|
|||||||
|
|
||||||
public class PaperweightLevelProxy extends ServerLevel {
|
public class PaperweightLevelProxy extends ServerLevel {
|
||||||
|
|
||||||
|
protected ServerLevel serverLevel;
|
||||||
|
private PaperweightPlacementStateProcessor processor;
|
||||||
private PaperweightFaweAdapter adapter;
|
private PaperweightFaweAdapter adapter;
|
||||||
private Extent extent;
|
|
||||||
private ServerLevel serverLevel;
|
|
||||||
|
|
||||||
@SuppressWarnings("DataFlowIssue")
|
@SuppressWarnings("DataFlowIssue")
|
||||||
public PaperweightLevelProxy() {
|
private PaperweightLevelProxy() {
|
||||||
super(null, null, null, null, null, null, null, true, 0L, null, true, null, null, null, null);
|
super(null, null, null, null, null, null, null, true, 0L, null, true, null, null, null, null);
|
||||||
throw new IllegalStateException("Cannot be instantiated");
|
throw new IllegalStateException("Cannot be instantiated");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PaperweightLevelProxy getInstance(ServerLevel level, Extent extent) {
|
public static PaperweightLevelProxy getInstance(ServerLevel serverLevel, PaperweightPlacementStateProcessor processor) {
|
||||||
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
||||||
|
|
||||||
PaperweightLevelProxy newLevel;
|
PaperweightLevelProxy newLevel;
|
||||||
@ -38,11 +38,9 @@ public class PaperweightLevelProxy extends ServerLevel {
|
|||||||
} catch (InstantiationException e) {
|
} catch (InstantiationException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin
|
newLevel.processor = processor;
|
||||||
.getInstance()
|
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin.getInstance().getBukkitImplAdapter());
|
||||||
.getBukkitImplAdapter());
|
newLevel.serverLevel = serverLevel;
|
||||||
newLevel.extent = extent;
|
|
||||||
newLevel.serverLevel = level;
|
|
||||||
return newLevel;
|
return newLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,21 +50,17 @@ public class PaperweightLevelProxy extends ServerLevel {
|
|||||||
if (blockPos.getX() == Integer.MAX_VALUE) {
|
if (blockPos.getX() == Integer.MAX_VALUE) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
BlockEntity tileEntity = this.serverLevel.getChunkAt(blockPos).getBlockEntity(blockPos);
|
com.sk89q.jnbt.CompoundTag tag = processor.getTileAt(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
||||||
if (tileEntity == null) {
|
if (tag == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
BlockEntity newEntity = tileEntity.getType().create(blockPos, getBlockState(blockPos));
|
BlockState state = adapter.adapt(processor.getBlockStateAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
|
||||||
newEntity.loadWithComponents(
|
if (!(state.getBlock() instanceof EntityBlock entityBlock)) {
|
||||||
(CompoundTag) adapter.fromNativeBinary(this.extent.getFullBlock(
|
return null;
|
||||||
blockPos.getX(),
|
}
|
||||||
blockPos.getY(),
|
BlockEntity tileEntity = entityBlock.newBlockEntity(blockPos, state);
|
||||||
blockPos.getZ()
|
tileEntity.loadWithComponents((CompoundTag) adapter.fromNative(tag), serverLevel.registryAccess());
|
||||||
).getNbtReference().getValue()),
|
return tileEntity;
|
||||||
this.serverLevel.registryAccess()
|
|
||||||
);
|
|
||||||
|
|
||||||
return newEntity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -75,7 +69,7 @@ public class PaperweightLevelProxy extends ServerLevel {
|
|||||||
if (blockPos.getX() == Integer.MAX_VALUE) {
|
if (blockPos.getX() == Integer.MAX_VALUE) {
|
||||||
return Blocks.AIR.defaultBlockState();
|
return Blocks.AIR.defaultBlockState();
|
||||||
}
|
}
|
||||||
com.sk89q.worldedit.world.block.BlockState state = this.extent.getBlock(
|
com.sk89q.worldedit.world.block.BlockState state = processor.getBlockStateAt(
|
||||||
blockPos.getX(),
|
blockPos.getX(),
|
||||||
blockPos.getY(),
|
blockPos.getY(),
|
||||||
blockPos.getZ()
|
blockPos.getZ()
|
||||||
|
@ -1,28 +1,29 @@
|
|||||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.extent.processor.PlacementStateProcessor;
|
import com.fastasyncworldedit.core.extent.PlacementStateProcessor;
|
||||||
import com.fastasyncworldedit.core.math.IntTriple;
|
|
||||||
import com.fastasyncworldedit.core.util.ExtentTraverser;
|
import com.fastasyncworldedit.core.util.ExtentTraverser;
|
||||||
import com.fastasyncworldedit.core.wrappers.WorldWrapper;
|
import com.fastasyncworldedit.core.wrappers.WorldWrapper;
|
||||||
import com.sk89q.worldedit.EditSession;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
||||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.math.Vector3;
|
import com.sk89q.worldedit.math.Vector3;
|
||||||
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.Direction;
|
import com.sk89q.worldedit.util.Direction;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import org.bukkit.craftbukkit.CraftWorld;
|
import org.bukkit.craftbukkit.CraftWorld;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Queue;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class PaperweightPlacementStateProcessor extends PlacementStateProcessor {
|
public class PaperweightPlacementStateProcessor extends PlacementStateProcessor {
|
||||||
|
|
||||||
@ -32,20 +33,12 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
|
|||||||
private final PaperweightLevelProxy proxyLevel;
|
private final PaperweightLevelProxy proxyLevel;
|
||||||
private final FaweMutableBlockPlaceContext mutableBlockPlaceContext;
|
private final FaweMutableBlockPlaceContext mutableBlockPlaceContext;
|
||||||
|
|
||||||
public PaperweightPlacementStateProcessor(
|
public PaperweightPlacementStateProcessor(Extent extent, BlockTypeMask mask, Region region) {
|
||||||
Extent extent,
|
super(extent, mask, region);
|
||||||
BlockTypeMask mask,
|
World world = ExtentTraverser.getWorldFromExtent(extent);
|
||||||
boolean secondPass,
|
if (world == null) {
|
||||||
boolean includeUnedited
|
throw new UnsupportedOperationException(
|
||||||
) {
|
"World is required for PlacementStateProcessor but none found in given extent.");
|
||||||
super(extent, mask, secondPass, includeUnedited);
|
|
||||||
World world;
|
|
||||||
if (extent.isWorld()) {
|
|
||||||
world = (World) extent;
|
|
||||||
} else if (extent instanceof EditSession session) {
|
|
||||||
world = session.getWorld();
|
|
||||||
} else if ((world = new ExtentTraverser<>(extent).findAndGet(BukkitWorld.class)) == null) {
|
|
||||||
throw new UnsupportedOperationException("Cannot find world of extent.");
|
|
||||||
}
|
}
|
||||||
BukkitWorld bukkitWorld;
|
BukkitWorld bukkitWorld;
|
||||||
if (world instanceof WorldWrapper wrapper) {
|
if (world instanceof WorldWrapper wrapper) {
|
||||||
@ -53,34 +46,40 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
|
|||||||
} else {
|
} else {
|
||||||
bukkitWorld = (BukkitWorld) world;
|
bukkitWorld = (BukkitWorld) world;
|
||||||
}
|
}
|
||||||
this.proxyLevel = PaperweightLevelProxy.getInstance(((CraftWorld) bukkitWorld.getWorld()).getHandle(),
|
this.proxyLevel = PaperweightLevelProxy.getInstance(((CraftWorld) bukkitWorld.getWorld()).getHandle(), this);
|
||||||
extent
|
|
||||||
);
|
|
||||||
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PaperweightPlacementStateProcessor(
|
private PaperweightPlacementStateProcessor(
|
||||||
Extent extent,
|
Extent extent,
|
||||||
BlockTypeMask mask,
|
BlockTypeMask mask,
|
||||||
boolean secondPass,
|
Map<SecondPass, Character> crossChunkSecondPasses,
|
||||||
boolean includeUnedited,
|
ServerLevel serverLevel,
|
||||||
Queue<IntTriple> crossChunkSecondPasses,
|
ThreadLocal<PlacementStateProcessor> threadProcessors,
|
||||||
PaperweightLevelProxy proxyLevel
|
Region region,
|
||||||
|
AtomicBoolean finished
|
||||||
) {
|
) {
|
||||||
super(extent, mask, secondPass, includeUnedited, crossChunkSecondPasses);
|
super(extent, mask, crossChunkSecondPasses, threadProcessors, region, finished);
|
||||||
this.proxyLevel = proxyLevel;
|
this.proxyLevel = PaperweightLevelProxy.getInstance(serverLevel, this);
|
||||||
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected char getStateAtFor(
|
protected char getStateAtFor(
|
||||||
int x, int y, int z, BlockState state, Vector3 clickPos, Direction clickedFaceDirection, BlockVector3 clickedBlock
|
int x,
|
||||||
|
int y,
|
||||||
|
int z,
|
||||||
|
BlockState state,
|
||||||
|
Vector3 clickPos,
|
||||||
|
Direction clickedFaceDirection,
|
||||||
|
BlockVector3 clickedBlock
|
||||||
) {
|
) {
|
||||||
Block block = ((PaperweightBlockMaterial) state.getMaterial()).getBlock();
|
Block block = ((PaperweightBlockMaterial) state.getMaterial()).getBlock();
|
||||||
Vec3 pos = new Vec3(clickPos.x(), clickPos.y(), clickPos.z());
|
Vec3 pos = new Vec3(clickPos.x(), clickPos.y(), clickPos.z());
|
||||||
net.minecraft.core.Direction side = net.minecraft.core.Direction.valueOf(clickedFaceDirection.toString());
|
net.minecraft.core.Direction side = net.minecraft.core.Direction.valueOf(clickedFaceDirection.toString());
|
||||||
BlockPos blockPos = new BlockPos(clickedBlock.x(), clickedBlock.y(), clickedBlock.z());
|
BlockPos blockPos = new BlockPos(clickedBlock.x(), clickedBlock.y(), clickedBlock.z());
|
||||||
net.minecraft.world.level.block.state.BlockState newState = block.getStateForPlacement(mutableBlockPlaceContext.withSetting(new BlockHitResult(pos, side, blockPos, false),
|
net.minecraft.world.level.block.state.BlockState newState = block.getStateForPlacement(mutableBlockPlaceContext.withSetting(
|
||||||
|
new BlockHitResult(pos, side, blockPos, false),
|
||||||
side.getOpposite()
|
side.getOpposite()
|
||||||
));
|
));
|
||||||
return newState == null ? BlockTypesCache.ReservedIDs.AIR : adapter.ibdIDToOrdinal(Block.BLOCK_STATE_REGISTRY.getId(
|
return newState == null ? BlockTypesCache.ReservedIDs.AIR : adapter.ibdIDToOrdinal(Block.BLOCK_STATE_REGISTRY.getId(
|
||||||
@ -93,7 +92,7 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
|
|||||||
if (child == getExtent()) {
|
if (child == getExtent()) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
return new PaperweightPlacementStateProcessor(child, mask, secondPass, includeUnedited);
|
return new PaperweightPlacementStateProcessor(child, mask, region);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -101,10 +100,11 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
|
|||||||
return new PaperweightPlacementStateProcessor(
|
return new PaperweightPlacementStateProcessor(
|
||||||
extent,
|
extent,
|
||||||
mask,
|
mask,
|
||||||
secondPass,
|
postCompleteSecondPasses,
|
||||||
includeUnedited,
|
proxyLevel.serverLevel,
|
||||||
crossChunkSecondPasses,
|
threadProcessors,
|
||||||
proxyLevel
|
region,
|
||||||
|
finished
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ package com.sk89q.worldedit.bukkit;
|
|||||||
|
|
||||||
import com.fastasyncworldedit.bukkit.util.MinecraftVersion;
|
import com.fastasyncworldedit.bukkit.util.MinecraftVersion;
|
||||||
import com.fastasyncworldedit.core.configuration.Settings;
|
import com.fastasyncworldedit.core.configuration.Settings;
|
||||||
import com.fastasyncworldedit.core.extent.processor.PlacementStateProcessor;
|
import com.fastasyncworldedit.core.extent.PlacementStateProcessor;
|
||||||
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
||||||
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
@ -41,6 +41,7 @@ import com.sk89q.worldedit.extension.platform.Watchdog;
|
|||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
||||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||||
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.SideEffect;
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
import com.sk89q.worldedit.util.lifecycle.Lifecycled;
|
import com.sk89q.worldedit.util.lifecycle.Lifecycled;
|
||||||
import com.sk89q.worldedit.world.DataFixer;
|
import com.sk89q.worldedit.world.DataFixer;
|
||||||
@ -314,13 +315,8 @@ public class BukkitServerInterface extends AbstractPlatform implements MultiUser
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlacementStateProcessor getPlatformPlacementProcessor(
|
public PlacementStateProcessor getPlatformPlacementProcessor(Extent extent, BlockTypeMask mask, Region region) {
|
||||||
Extent extent,
|
return this.plugin.getBukkitImplAdapter().getPlatformPlacementProcessor(extent, mask, region);
|
||||||
BlockTypeMask mask,
|
|
||||||
boolean secondPass,
|
|
||||||
boolean includeUnedited
|
|
||||||
) {
|
|
||||||
return this.plugin.getBukkitImplAdapter().getPlatformPlacementProcessor(extent, mask, secondPass, includeUnedited);
|
|
||||||
}
|
}
|
||||||
//FAWE end
|
//FAWE end
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ import com.fastasyncworldedit.bukkit.FaweBukkit;
|
|||||||
import com.fastasyncworldedit.bukkit.adapter.IBukkitAdapter;
|
import com.fastasyncworldedit.bukkit.adapter.IBukkitAdapter;
|
||||||
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
|
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
|
||||||
import com.fastasyncworldedit.core.Fawe;
|
import com.fastasyncworldedit.core.Fawe;
|
||||||
import com.fastasyncworldedit.core.extent.processor.PlacementStateProcessor;
|
import com.fastasyncworldedit.core.extent.PlacementStateProcessor;
|
||||||
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
||||||
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
||||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||||
@ -368,12 +368,7 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
|
|||||||
* Returns an {@link PlacementStateProcessor} instance for processing placed blocks to "fix" them.
|
* Returns an {@link PlacementStateProcessor} instance for processing placed blocks to "fix" them.
|
||||||
* @since TODO
|
* @since TODO
|
||||||
*/
|
*/
|
||||||
default PlacementStateProcessor getPlatformPlacementProcessor(
|
default PlacementStateProcessor getPlatformPlacementProcessor(Extent extent, BlockTypeMask mask, Region region) {
|
||||||
Extent extent,
|
|
||||||
BlockTypeMask mask,
|
|
||||||
boolean secondPass,
|
|
||||||
boolean includeUnedited
|
|
||||||
) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
//FAWE end
|
//FAWE end
|
||||||
|
@ -32,6 +32,8 @@ import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
|||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
|
import com.sk89q.worldedit.util.SideEffectSet;
|
||||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
@ -352,8 +354,12 @@ public class FaweAPI {
|
|||||||
if (unwrapped instanceof IQueueExtent) {
|
if (unwrapped instanceof IQueueExtent) {
|
||||||
queue = (IQueueExtent) unwrapped;
|
queue = (IQueueExtent) unwrapped;
|
||||||
} else if (Settings.settings().QUEUE.PARALLEL_THREADS > 1) {
|
} else if (Settings.settings().QUEUE.PARALLEL_THREADS > 1) {
|
||||||
ParallelQueueExtent parallel =
|
ParallelQueueExtent parallel = new ParallelQueueExtent(
|
||||||
new ParallelQueueExtent(Fawe.instance().getQueueHandler(), world, true);
|
Fawe.instance().getQueueHandler(),
|
||||||
|
world,
|
||||||
|
true,
|
||||||
|
SideEffectSet.none().with(SideEffect.LIGHTING, SideEffect.State.ON)
|
||||||
|
);
|
||||||
queue = parallel.getExtent();
|
queue = parallel.getExtent();
|
||||||
} else {
|
} else {
|
||||||
queue = Fawe.instance().getQueueHandler().getQueue(world);
|
queue = Fawe.instance().getQueueHandler().getQueue(world);
|
||||||
|
@ -784,11 +784,6 @@ public class Settings extends Config {
|
|||||||
})
|
})
|
||||||
public boolean UNSTUCK_ON_GENERATE = true;
|
public boolean UNSTUCK_ON_GENERATE = true;
|
||||||
|
|
||||||
@Comment({
|
|
||||||
"If edits that have a block update processor applied should also perform a second pass",
|
|
||||||
})
|
|
||||||
public boolean PERFORM_SECOND_UPDATE_PASS = true;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.fastasyncworldedit.core.extension.factory.parser.mask;
|
||||||
|
|
||||||
|
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
|
||||||
|
import com.fastasyncworldedit.core.function.mask.Adjacent2DMask;
|
||||||
|
import com.fastasyncworldedit.core.function.mask.AdjacentAny2DMask;
|
||||||
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
|
import com.sk89q.worldedit.command.util.SuggestionHelper;
|
||||||
|
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||||
|
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class Adjacent2DMaskParser extends RichParser<Mask> {
|
||||||
|
|
||||||
|
public Adjacent2DMaskParser(WorldEdit worldEdit) {
|
||||||
|
super(worldEdit, "~2d", "adjacent2d");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||||
|
if (index == 0) {
|
||||||
|
return worldEdit.getMaskFactory().getSuggestions(argumentInput).stream();
|
||||||
|
} else if (index == 1 || index == 2) {
|
||||||
|
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
|
||||||
|
}
|
||||||
|
return Stream.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Mask parseFromInput(@Nonnull String[] arguments, ParserContext context) throws InputParseException {
|
||||||
|
if (arguments.length == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Mask subMask = worldEdit.getMaskFactory().parseFromInput(arguments[0], context);
|
||||||
|
int min = arguments.length > 1 ? Integer.parseInt(arguments[1]) : -1;
|
||||||
|
int max = arguments.length > 2 ? Integer.parseInt(arguments[2]) : -1;
|
||||||
|
if (min == -1 && max == -1) {
|
||||||
|
min = 1;
|
||||||
|
max = 4;
|
||||||
|
} else if (max == -1) {
|
||||||
|
max = min;
|
||||||
|
}
|
||||||
|
if (max >= 4 && min == 1) {
|
||||||
|
return new AdjacentAny2DMask(subMask);
|
||||||
|
}
|
||||||
|
return new Adjacent2DMask(subMask, min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -10,7 +10,6 @@ import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
|||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.function.operation.Operation;
|
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
@ -215,12 +214,6 @@ public class PassthroughExtent extends AbstractDelegateExtent {
|
|||||||
return getExtent().setBiome(position, biome);
|
return getExtent().setBiome(position, biome);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public Operation commit() {
|
|
||||||
return getExtent().commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean cancel() {
|
public boolean cancel() {
|
||||||
return getExtent().cancel();
|
return getExtent().cancel();
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package com.fastasyncworldedit.core.extent.processor;
|
package com.fastasyncworldedit.core.extent;
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.extent.filter.block.FilterBlock;
|
import com.fastasyncworldedit.core.extent.filter.block.FilterBlock;
|
||||||
import com.fastasyncworldedit.core.math.IntPair;
|
import com.fastasyncworldedit.core.extent.processor.ProcessorScope;
|
||||||
import com.fastasyncworldedit.core.math.IntTriple;
|
import com.fastasyncworldedit.core.function.mask.AdjacentAny2DMask;
|
||||||
|
import com.fastasyncworldedit.core.math.BlockVector3ChunkMap;
|
||||||
import com.fastasyncworldedit.core.math.MutableBlockVector3;
|
import com.fastasyncworldedit.core.math.MutableBlockVector3;
|
||||||
import com.fastasyncworldedit.core.math.MutableVector3;
|
import com.fastasyncworldedit.core.math.MutableVector3;
|
||||||
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
||||||
@ -18,6 +19,7 @@ import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
|||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.math.Vector3;
|
import com.sk89q.worldedit.math.Vector3;
|
||||||
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.registry.state.Property;
|
import com.sk89q.worldedit.registry.state.Property;
|
||||||
import com.sk89q.worldedit.util.Direction;
|
import com.sk89q.worldedit.util.Direction;
|
||||||
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
||||||
@ -28,39 +30,45 @@ import com.sk89q.worldedit.world.block.BlockState;
|
|||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.Queue;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public abstract class PlacementStateProcessor extends AbstractDelegateExtent implements IBatchProcessor, Pattern {
|
public abstract class PlacementStateProcessor extends AbstractDelegateExtent implements IBatchProcessor, Pattern {
|
||||||
|
|
||||||
private static final Direction[] NESW = new Direction[]{Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST};
|
private static final Direction[] NESW = new Direction[]{Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST};
|
||||||
|
private static final int CHUNK_BLOCK_POS_MASK = -1 << 4;
|
||||||
|
|
||||||
private static volatile boolean SETUP = false;
|
private static volatile boolean SETUP = false;
|
||||||
private static BlockTypeMask DEFAULT_MASK = null;
|
private static BlockTypeMask DEFAULT_MASK = null;
|
||||||
private static BlockTypeMask SECOND_MASK = null;
|
|
||||||
private static BlockTypeMask REQUIRES_SECOND_PASS = null;
|
private static BlockTypeMask REQUIRES_SECOND_PASS = null;
|
||||||
|
private static AdjacentAny2DMask ADJACENT_STAIR_MASK = null;
|
||||||
|
|
||||||
protected final Extent extent;
|
protected final Extent extent;
|
||||||
protected final BlockTypeMask mask;
|
protected final BlockTypeMask mask;
|
||||||
protected final boolean includeUnedited;
|
protected final Region region;
|
||||||
protected final boolean secondPass;
|
protected final Map<SecondPass, Character> postCompleteSecondPasses;
|
||||||
protected final Queue<IntTriple> crossChunkSecondPasses;
|
protected final ThreadLocal<PlacementStateProcessor> threadProcessors;
|
||||||
|
protected final AtomicBoolean finished;
|
||||||
private final MutableVector3 clickPos = new MutableVector3();
|
private final MutableVector3 clickPos = new MutableVector3();
|
||||||
private final MutableBlockVector3 clickedBlock = new MutableBlockVector3();
|
private final MutableBlockVector3 clickedBlock = new MutableBlockVector3();
|
||||||
|
|
||||||
|
private IChunkGet processChunkGet = null;
|
||||||
|
private IChunkSet processChunkSet = null;
|
||||||
|
private int processChunkX;
|
||||||
|
private int processChunkZ;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process/extent/pattern for performing block updates, e.g. stair shape and glass pane connections
|
* Process/extent/pattern for performing block updates, e.g. stair shape and glass pane connections
|
||||||
*
|
*
|
||||||
* @param extent Extent to use
|
* @param extent Extent to use
|
||||||
* @param mask Mask of blocks to perform updates on
|
* @param mask Mask of blocks to perform updates on
|
||||||
* @param secondPass Perform a second pass typically around stairs. May perform cross-chunk second passes too
|
|
||||||
* @param includeUnedited if unedited blocks should be processed as well
|
|
||||||
* @since TODO
|
* @since TODO
|
||||||
*/
|
*/
|
||||||
public PlacementStateProcessor(Extent extent, BlockTypeMask mask, boolean secondPass, boolean includeUnedited) {
|
public PlacementStateProcessor(Extent extent, BlockTypeMask mask, Region region) {
|
||||||
super(extent);
|
super(extent);
|
||||||
// Required here as child classes are located within adapters and will therefore be statically accessed on startup,
|
// Required here as child classes are located within adapters and will therefore be statically accessed on startup,
|
||||||
// meaning we attempt to access BlockTypes class before it is correctly initialised.
|
// meaning we attempt to access BlockTypes class before it is correctly initialised.
|
||||||
@ -73,24 +81,27 @@ public abstract class PlacementStateProcessor extends AbstractDelegateExtent imp
|
|||||||
}
|
}
|
||||||
this.extent = extent;
|
this.extent = extent;
|
||||||
this.mask = mask == null ? DEFAULT_MASK : mask;
|
this.mask = mask == null ? DEFAULT_MASK : mask;
|
||||||
this.secondPass = secondPass;
|
this.region = region;
|
||||||
this.includeUnedited = includeUnedited;
|
this.postCompleteSecondPasses = new ConcurrentHashMap<>();
|
||||||
this.crossChunkSecondPasses = secondPass ? null : new ConcurrentLinkedQueue<>();
|
this.threadProcessors = ThreadLocal.withInitial(this::fork);
|
||||||
|
this.finished = new AtomicBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PlacementStateProcessor(
|
protected PlacementStateProcessor(
|
||||||
Extent extent,
|
Extent extent,
|
||||||
BlockTypeMask mask,
|
BlockTypeMask mask,
|
||||||
boolean secondPass,
|
Map<SecondPass, Character> crossChunkSecondPasses,
|
||||||
boolean includeUnedited,
|
ThreadLocal<PlacementStateProcessor> threadProcessors,
|
||||||
Queue<IntTriple> crossChunkSecondPasses
|
Region region,
|
||||||
|
AtomicBoolean finished
|
||||||
) {
|
) {
|
||||||
super(extent);
|
super(extent);
|
||||||
this.extent = extent;
|
this.extent = extent;
|
||||||
this.mask = mask;
|
this.mask = mask;
|
||||||
this.secondPass = secondPass;
|
this.region = region;
|
||||||
this.includeUnedited = includeUnedited;
|
this.postCompleteSecondPasses = crossChunkSecondPasses;
|
||||||
this.crossChunkSecondPasses = crossChunkSecondPasses;
|
this.threadProcessors = threadProcessors;
|
||||||
|
this.finished = finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setup() {
|
private static void setup() {
|
||||||
@ -121,12 +132,7 @@ public abstract class PlacementStateProcessor extends AbstractDelegateExtent imp
|
|||||||
BlockTypes.VINE,
|
BlockTypes.VINE,
|
||||||
BlockTypes.REDSTONE_WIRE
|
BlockTypes.REDSTONE_WIRE
|
||||||
);
|
);
|
||||||
BlockCategory[] categories = new BlockCategory[]{
|
BlockCategory[] categories = new BlockCategory[]{BlockCategories.FENCES, BlockCategories.FENCE_GATES, BlockCategories.WALLS, BlockCategories.CAVE_VINES};
|
||||||
BlockCategories.FENCES,
|
|
||||||
BlockCategories.FENCE_GATES,
|
|
||||||
BlockCategories.WALLS,
|
|
||||||
BlockCategories.CAVE_VINES
|
|
||||||
};
|
|
||||||
for (BlockCategory category : categories) {
|
for (BlockCategory category : categories) {
|
||||||
if (category != null) {
|
if (category != null) {
|
||||||
REQUIRES_SECOND_PASS.add(category.getAll());
|
REQUIRES_SECOND_PASS.add(category.getAll());
|
||||||
@ -148,145 +154,129 @@ public abstract class PlacementStateProcessor extends AbstractDelegateExtent imp
|
|||||||
BlockTypes.BROWN_MUSHROOM_BLOCK,
|
BlockTypes.BROWN_MUSHROOM_BLOCK,
|
||||||
BlockTypes.RED_MUSHROOM_BLOCK
|
BlockTypes.RED_MUSHROOM_BLOCK
|
||||||
);
|
);
|
||||||
categories = new BlockCategory[]{
|
categories = new BlockCategory[]{BlockCategories.STAIRS, BlockCategories.BAMBOO_BLOCKS, BlockCategories.TALL_FLOWERS};
|
||||||
BlockCategories.STAIRS,
|
|
||||||
BlockCategories.BAMBOO_BLOCKS,
|
|
||||||
BlockCategories.TALL_FLOWERS
|
|
||||||
};
|
|
||||||
for (BlockCategory category : categories) {
|
for (BlockCategory category : categories) {
|
||||||
if (category != null) {
|
if (category != null) {
|
||||||
DEFAULT_MASK.add(category.getAll());
|
DEFAULT_MASK.add(category.getAll());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SECOND_MASK = new BlockTypeMask(new NullExtent());
|
BlockTypeMask stairs = new BlockTypeMask(new NullExtent(), BlockCategories.STAIRS.getAll());
|
||||||
SECOND_MASK.add(BlockCategories.STAIRS.getAll());
|
ADJACENT_STAIR_MASK = new AdjacentAny2DMask(stairs, false);
|
||||||
SETUP = true;
|
SETUP = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IChunkSet processSet(IChunk iChunk, IChunkGet iChunkGet, IChunkSet iChunkSet) {
|
public IChunkSet processSet(IChunk iChunk, IChunkGet chunkGet, IChunkSet chunkSet) {
|
||||||
int chunkX = iChunk.getX() << 4;
|
if (finished.get()) {
|
||||||
int chunkZ = iChunk.getZ() << 4;
|
return chunkSet;
|
||||||
for (int layer = iChunkGet.getMinSectionPosition(); layer <= iChunkGet.getMaxSectionPosition(); layer++) {
|
|
||||||
int layerY = layer << 4;
|
|
||||||
char[] set = iChunkSet.loadIfPresent(layer);
|
|
||||||
char[] get = null;
|
|
||||||
if (set == null) {
|
|
||||||
if (!includeUnedited) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
PlacementStateProcessor threadProcessor = threadProcessors.get();
|
||||||
|
try {
|
||||||
|
threadProcessor.initProcess(iChunk, chunkGet, chunkSet);
|
||||||
|
return threadProcessor.process();
|
||||||
|
} finally {
|
||||||
|
threadProcessor.uninit();
|
||||||
}
|
}
|
||||||
Queue<IntPair> secondPasses = this.secondPass ? new ArrayDeque<>() : null;
|
|
||||||
for (int y = 0, i = 0; y < 16; y++) {
|
|
||||||
int blockY = layerY + y;
|
|
||||||
// Perform second pass to ensure changes to stairs are propagated to fences, walls, etc.
|
|
||||||
// Always perform if within chunk boundaries as this is not very costly.
|
|
||||||
// Only perform outside chunk boundaries if secondPass is not null
|
|
||||||
for (int z = 0; z < 16; z++) {
|
|
||||||
int blockZ = chunkZ + z;
|
|
||||||
for (int x = 0; x < 16; x++, i++) {
|
|
||||||
int blockX = chunkX + x;
|
|
||||||
checkAndPerformUpdate(iChunkGet, iChunkSet, get, set, layer, i, blockX, blockY, blockZ, x, z, secondPasses);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!secondPass || secondPasses.isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
IntPair pair;
|
|
||||||
while ((pair = secondPasses.poll()) != null) {
|
|
||||||
int x = pair.x();
|
|
||||||
int z = pair.z();
|
|
||||||
int blockX = chunkX + x;
|
|
||||||
int blockZ = chunkZ + z;
|
|
||||||
if (x < 0 || x > 15 || z < 0 || z > 15) {
|
|
||||||
crossChunkSecondPasses.add(new IntTriple(blockX, blockY, blockZ));
|
|
||||||
}
|
|
||||||
int index = (y & 15) << 8 | z << 4 | x;
|
|
||||||
checkAndPerformUpdate(iChunkGet, iChunkSet, get, set, layer, index, blockX, blockY, blockZ, x, z, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return iChunkSet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAndPerformUpdate(
|
private void initProcess(IChunk iChunk, IChunkGet chunkGet, IChunkSet chunkSet) {
|
||||||
IChunkGet iChunkGet,
|
this.processChunkX = iChunk.getX() << 4;
|
||||||
IChunkSet iChunkSet,
|
this.processChunkZ = iChunk.getZ() << 4;
|
||||||
char[] get,
|
this.processChunkGet = chunkGet;
|
||||||
char[] set,
|
this.processChunkSet = chunkSet;
|
||||||
int layer,
|
|
||||||
int index,
|
|
||||||
int blockX,
|
|
||||||
int blockY,
|
|
||||||
int blockZ,
|
|
||||||
int x,
|
|
||||||
int z,
|
|
||||||
Queue<IntPair> secondPasses
|
|
||||||
) {
|
|
||||||
char ordinal = set == null ? BlockTypesCache.ReservedIDs.__RESERVED__ : set[index];
|
|
||||||
if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) {
|
|
||||||
if (!includeUnedited) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (get == null) {
|
|
||||||
get = iChunkGet.load(layer);
|
private void uninit() {
|
||||||
|
this.processChunkGet = null;
|
||||||
|
this.processChunkSet = null;
|
||||||
}
|
}
|
||||||
ordinal = get[index];
|
|
||||||
|
private IChunkSet process() {
|
||||||
|
Map<BlockVector3, CompoundTag> setTiles = processChunkSet.getTiles();
|
||||||
|
for (int layer = processChunkGet.getMinSectionPosition(); layer <= processChunkGet.getMaxSectionPosition(); layer++) {
|
||||||
|
int layerY = layer << 4;
|
||||||
|
char[] set = processChunkSet.loadIfPresent(layer);
|
||||||
|
if (set == null) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
for (int y = 0, i = 0; y < 16; y++, i += 256) {
|
||||||
|
int blockY = layerY + y;
|
||||||
|
checkAndPerformUpdate(setTiles, set, i, blockY, true);
|
||||||
|
checkAndPerformUpdate(setTiles, set, i, blockY, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return processChunkSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkAndPerformUpdate(Map<BlockVector3, CompoundTag> setTiles, char[] set, int index, int blockY, boolean firstPass) {
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
int blockZ = processChunkZ + z;
|
||||||
|
for (int x = 0; x < 16; x++, index++) {
|
||||||
|
int blockX = processChunkX + x;
|
||||||
|
char ordinal = set[index];
|
||||||
BlockState state = BlockTypesCache.states[ordinal];
|
BlockState state = BlockTypesCache.states[ordinal];
|
||||||
if (secondPasses == null && secondPass) {
|
if (firstPass && !BlockCategories.STAIRS.contains(state)) {
|
||||||
if (!REQUIRES_SECOND_PASS.test(state.getBlockType())) {
|
continue;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
if (!mask.test(state)) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
if (!mask.test(state.getBlockType())) {
|
if (!firstPass && REQUIRES_SECOND_PASS.test(state)) {
|
||||||
return;
|
postCompleteSecondPasses.put(new SecondPass(
|
||||||
|
blockX,
|
||||||
|
blockY,
|
||||||
|
blockZ,
|
||||||
|
setTiles.isEmpty() ? null : ((BlockVector3ChunkMap<CompoundTag>) setTiles).remove(x, blockY, z)
|
||||||
|
), ordinal);
|
||||||
|
set[index] = BlockTypesCache.ReservedIDs.__RESERVED__;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
char newOrdinal = getBlockOrdinal(blockX, blockY, blockZ, state);
|
char newOrdinal = getBlockOrdinal(blockX, blockY, blockZ, state);
|
||||||
if (newOrdinal == ordinal) {
|
if (newOrdinal == ordinal) {
|
||||||
return;
|
continue;
|
||||||
}
|
|
||||||
if (secondPasses != null && (BlockCategories.STAIRS.contains(state) || secondPass && SECOND_MASK.test(state.getBlockType()))) {
|
|
||||||
secondPasses.add(new IntPair(x - 1, z));
|
|
||||||
secondPasses.add(new IntPair(x + 1, z));
|
|
||||||
secondPasses.add(new IntPair(x, z - 1));
|
|
||||||
secondPasses.add(new IntPair(x, z + 1));
|
|
||||||
}
|
|
||||||
if (set == null) {
|
|
||||||
set = iChunkSet.load(layer);
|
|
||||||
}
|
}
|
||||||
set[index] = newOrdinal;
|
set[index] = newOrdinal;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProcessorScope getScope() {
|
public ProcessorScope getScope() {
|
||||||
return ProcessorScope.CHANGING_BLOCKS;
|
return ProcessorScope.CHANGING_BLOCKS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finish() {
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() {
|
public void flush() {
|
||||||
IntTriple coords;
|
finished.set(true);
|
||||||
while ((coords = crossChunkSecondPasses.poll()) != null) {
|
for (Map.Entry<SecondPass, Character> entry : postCompleteSecondPasses.entrySet()) {
|
||||||
BlockState state = extent.getBlock(coords.x(), coords.y(), coords.z());
|
BlockState state;
|
||||||
char ordinal = state.getOrdinalChar();
|
char ordinal = entry.getValue();
|
||||||
if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) {
|
SecondPass secondPass = entry.getKey();
|
||||||
|
if (ordinal != 0) {
|
||||||
|
state = BlockTypesCache.states[ordinal];
|
||||||
|
} else {
|
||||||
|
state = extent.getBlock(secondPass.x, secondPass.y, secondPass.z);
|
||||||
|
}
|
||||||
|
char newOrdinal = getBlockOrdinal(secondPass.x, secondPass.y, secondPass.z, state);
|
||||||
|
if (newOrdinal == state.getOrdinalChar() && ordinal == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!mask.test(state.getBlockType())) {
|
if (secondPass.tile != null) {
|
||||||
continue;
|
extent.setTile(secondPass.x, secondPass.y, secondPass.z, secondPass.tile);
|
||||||
}
|
}
|
||||||
char newOrdinal = getBlockOrdinal(coords.x(), coords.y(), coords.z(), state);
|
extent.setBlock(secondPass.x, secondPass.y, secondPass.z, BlockTypesCache.states[newOrdinal]);
|
||||||
if (newOrdinal == ordinal) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
extent.setBlock(coords.x(), coords.y(), coords.z(), BlockTypesCache.states[newOrdinal]);
|
|
||||||
}
|
}
|
||||||
|
postCompleteSecondPasses.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract PlacementStateProcessor fork();
|
public abstract PlacementStateProcessor fork();
|
||||||
|
|
||||||
// Require block type to avoid duplicate lookup
|
|
||||||
protected abstract char getStateAtFor(
|
protected abstract char getStateAtFor(
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
@ -297,6 +287,55 @@ public abstract class PlacementStateProcessor extends AbstractDelegateExtent imp
|
|||||||
BlockVector3 clickedBlock
|
BlockVector3 clickedBlock
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public BlockState getBlockStateAt(int x, int y, int z) {
|
||||||
|
Character ord = postCompleteSecondPasses.get(new SecondPass(x, y, z, null));
|
||||||
|
if (ord != null && ord != 0) {
|
||||||
|
return BlockTypesCache.states[ord];
|
||||||
|
}
|
||||||
|
if (processChunkSet == null || (x & CHUNK_BLOCK_POS_MASK) != processChunkX || (z & CHUNK_BLOCK_POS_MASK) != processChunkZ) {
|
||||||
|
return extent.getBlock(x, y, z);
|
||||||
|
}
|
||||||
|
char[] set = processChunkSet.loadIfPresent(y >> 4);
|
||||||
|
if (set == null) {
|
||||||
|
return processChunkGet.getBlock(x & 15, y, z & 15);
|
||||||
|
}
|
||||||
|
char ordinal = set[(y & 15) << 8 | (z & 15) << 4 | (x & 15)];
|
||||||
|
if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) {
|
||||||
|
return processChunkGet.getBlock(x & 15, y, z & 15);
|
||||||
|
}
|
||||||
|
return BlockTypesCache.states[ordinal];
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompoundTag getTileAt(int x, int y, int z) {
|
||||||
|
SecondPass secondPass = new SecondPass(x, y, z, null);
|
||||||
|
Character ord = postCompleteSecondPasses.get(secondPass);
|
||||||
|
if (ord != null && ord != 0) {
|
||||||
|
// This should be rare enough...
|
||||||
|
for (SecondPass pass : postCompleteSecondPasses.keySet()) {
|
||||||
|
if (pass.hashCode() == secondPass.hashCode()) {
|
||||||
|
return pass.tile != null ? pass.tile : BlockTypesCache.states[ord].getNbtData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return BlockTypesCache.states[ord].getNbtData();
|
||||||
|
}
|
||||||
|
if (processChunkSet == null || (x & CHUNK_BLOCK_POS_MASK) != processChunkX || (z & CHUNK_BLOCK_POS_MASK) != processChunkZ) {
|
||||||
|
return extent.getFullBlock(x, y, z).getNbtData();
|
||||||
|
}
|
||||||
|
CompoundTag tile = processChunkSet.getTile(x & 15, y, z & 15);
|
||||||
|
if (tile != null) {
|
||||||
|
return tile;
|
||||||
|
}
|
||||||
|
char[] set = processChunkSet.loadIfPresent(y >> 4);
|
||||||
|
if (set == null) {
|
||||||
|
return processChunkGet.getFullBlock(x & 15, y, z & 15).getNbtData();
|
||||||
|
}
|
||||||
|
char ordinal = set[(y & 15) << 8 | (z & 15) << 4 | (x & 15)];
|
||||||
|
if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) {
|
||||||
|
return processChunkGet.getFullBlock(x & 15, y, z & 15).getNbtData();
|
||||||
|
}
|
||||||
|
return BlockTypesCache.states[ordinal].getNbtData();
|
||||||
|
}
|
||||||
|
|
||||||
private char getBlockOrdinal(final int blockX, final int blockY, final int blockZ, final BlockState state) {
|
private char getBlockOrdinal(final int blockX, final int blockY, final int blockZ, final BlockState state) {
|
||||||
EnumSet<Direction> dirs = Direction.getDirections(state);
|
EnumSet<Direction> dirs = Direction.getDirections(state);
|
||||||
Direction clickedFaceDirection = null; // This should be always be set by the below.
|
Direction clickedFaceDirection = null; // This should be always be set by the below.
|
||||||
@ -339,10 +378,16 @@ public abstract class PlacementStateProcessor extends AbstractDelegateExtent imp
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyBlock(FilterBlock block) {
|
public void applyBlock(FilterBlock block) {
|
||||||
BlockState state = BlockTypesCache.states[block.getOrdinal()];
|
if (finished.get()) {
|
||||||
if (!mask.test(state.getBlockType())) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
BlockState state = BlockTypesCache.states[block.getOrdinal()];
|
||||||
|
if (!mask.test(state)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (REQUIRES_SECOND_PASS.test(block.getBlock()) && ADJACENT_STAIR_MASK.test(extent, block)) {
|
||||||
|
postCompleteSecondPasses.put(new SecondPass(block), (char) 0);
|
||||||
|
}
|
||||||
char ordinal = (char) block.getOrdinal();
|
char ordinal = (char) block.getOrdinal();
|
||||||
char newOrdinal = getBlockOrdinal(block.x(), block.y(), block.z(), block.getBlock());
|
char newOrdinal = getBlockOrdinal(block.x(), block.y(), block.z(), block.getBlock());
|
||||||
if (ordinal != newOrdinal) {
|
if (ordinal != newOrdinal) {
|
||||||
@ -356,13 +401,17 @@ public abstract class PlacementStateProcessor extends AbstractDelegateExtent imp
|
|||||||
orDefault = extent;
|
orDefault = extent;
|
||||||
}
|
}
|
||||||
BaseBlock block = orDefault.getFullBlock(get);
|
BaseBlock block = orDefault.getFullBlock(get);
|
||||||
if (!mask.test(block.getBlockType())) {
|
if (!mask.test(block)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (REQUIRES_SECOND_PASS.test(block) && ADJACENT_STAIR_MASK.test(extent, set)) {
|
||||||
|
postCompleteSecondPasses.put(new SecondPass(set), (char) 0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
char newOrdinal = getBlockOrdinal(set.x(), set.y(), set.z(), block.toBlockState());
|
char newOrdinal = getBlockOrdinal(set.x(), set.y(), set.z(), block.toBlockState());
|
||||||
if (block.getOrdinalChar() != newOrdinal) {
|
if (block.getOrdinalChar() != newOrdinal) {
|
||||||
BlockState newState = BlockTypesCache.states[newOrdinal];
|
BlockState newState = BlockTypesCache.states[newOrdinal];
|
||||||
orDefault.setBlock(set, newState);
|
orDefault.setBlock(set.x(), set.y(), set.z(), newState);
|
||||||
CompoundBinaryTag nbt = block.getNbt();
|
CompoundBinaryTag nbt = block.getNbt();
|
||||||
if (nbt != null && newState.getBlockType() == block.getBlockType()) {
|
if (nbt != null && newState.getBlockType() == block.getBlockType()) {
|
||||||
orDefault.setTile(set.x(), set.y(), set.z(), (CompoundTag) nbt.asBinaryTag());
|
orDefault.setTile(set.x(), set.y(), set.z(), (CompoundTag) nbt.asBinaryTag());
|
||||||
@ -373,9 +422,16 @@ public abstract class PlacementStateProcessor extends AbstractDelegateExtent imp
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock applyBlock(final BlockVector3 position) {
|
public BaseBlock applyBlock(BlockVector3 position) {
|
||||||
|
if (finished.get()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
BaseBlock block = extent.getFullBlock(position);
|
BaseBlock block = extent.getFullBlock(position);
|
||||||
if (!mask.test(block.getBlockType())) {
|
if (!mask.test(block)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (REQUIRES_SECOND_PASS.test(block) && ADJACENT_STAIR_MASK.test(extent, position)) {
|
||||||
|
postCompleteSecondPasses.put(new SecondPass(position), (char) 0);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
char newOrdinal = getBlockOrdinal(position.x(), position.y(), position.z(), block.toBlockState());
|
char newOrdinal = getBlockOrdinal(position.x(), position.y(), position.z(), block.toBlockState());
|
||||||
@ -383,11 +439,24 @@ public abstract class PlacementStateProcessor extends AbstractDelegateExtent imp
|
|||||||
BlockState state = BlockTypesCache.states[newOrdinal];
|
BlockState state = BlockTypesCache.states[newOrdinal];
|
||||||
CompoundBinaryTag nbt = block.getNbt();
|
CompoundBinaryTag nbt = block.getNbt();
|
||||||
if (nbt != null && state.getBlockType() == block.getBlockType()) {
|
if (nbt != null && state.getBlockType() == block.getBlockType()) {
|
||||||
return state.toBaseBlock(nbt);
|
state.toBaseBlock(nbt);
|
||||||
}
|
}
|
||||||
return state.toBaseBlock();
|
return state.toBaseBlock();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected record SecondPass(int x, int y, int z, CompoundTag tile) {
|
||||||
|
|
||||||
|
private SecondPass(BlockVector3 pos) {
|
||||||
|
this(pos.x(), pos.y(), pos.z(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return (x ^ (z << 12)) ^ (y << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -30,8 +30,21 @@ public final class LinkedFilter<T extends Filter, S extends Filter> extends Dele
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LinkedFilter<LinkedFilter<T, S>, Filter> newInstance(Filter other) {
|
public LinkedFilter<? extends Filter, ? extends Filter> newInstance(Filter other) {
|
||||||
|
if (other == this) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
// Assume parent filter forked and there we do not want to continue using this instances parent in the new instance
|
||||||
|
if (getParent() == other || getParent().getClass().equals(other.getClass())) {
|
||||||
|
return new LinkedFilter<>(other, child);
|
||||||
|
}
|
||||||
return new LinkedFilter<>(this, other);
|
return new LinkedFilter<>(this, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finish() {
|
||||||
|
getParent().finish();
|
||||||
|
getChild().finish();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
package com.fastasyncworldedit.core.function.mask;
|
||||||
|
|
||||||
|
import com.fastasyncworldedit.core.math.MutableBlockVector3;
|
||||||
|
import com.sk89q.worldedit.function.mask.AbstractMask;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
|
||||||
|
public class Adjacent2DMask extends AbstractMask {
|
||||||
|
|
||||||
|
private final int min;
|
||||||
|
private final int max;
|
||||||
|
private final Mask mask;
|
||||||
|
private final MutableBlockVector3 vector;
|
||||||
|
|
||||||
|
public Adjacent2DMask(Mask mask, int requiredMin, int requiredMax) {
|
||||||
|
this.mask = mask;
|
||||||
|
this.min = requiredMin;
|
||||||
|
this.max = requiredMax;
|
||||||
|
this.vector = new MutableBlockVector3();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(BlockVector3 bv) {
|
||||||
|
vector.setComponents(bv);
|
||||||
|
double x = bv.x();
|
||||||
|
double z = bv.z();
|
||||||
|
vector.mutX(x + 1);
|
||||||
|
int count = 0;
|
||||||
|
if (mask.test(vector) && ++count == min && max >= 4) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
vector.mutX(x - 1);
|
||||||
|
if (mask.test(vector) && ++count == min && max >= 4) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
vector.mutX(x);
|
||||||
|
vector.mutZ(z + 1);
|
||||||
|
if (mask.test(vector) && ++count == min && max >= 4) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
vector.mutZ(z - 1);
|
||||||
|
if (mask.test(vector) && ++count == min && max >= 4) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return count >= min && count <= max;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mask copy() {
|
||||||
|
return new Adjacent2DMask(mask.copy(), min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package com.fastasyncworldedit.core.function.mask;
|
||||||
|
|
||||||
|
import com.fastasyncworldedit.core.math.MutableBlockVector3;
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
|
||||||
|
import com.sk89q.worldedit.function.mask.AbstractMask;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just an optimized version of the Adjacent Mask for single adjacency.
|
||||||
|
*/
|
||||||
|
public class AdjacentAny2DMask extends AbstractMask {
|
||||||
|
|
||||||
|
private final Mask mask;
|
||||||
|
private final MutableBlockVector3 mutable;
|
||||||
|
|
||||||
|
public AdjacentAny2DMask(Mask mask) {
|
||||||
|
this(mask, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AdjacentAny2DMask(Mask mask, boolean cache) {
|
||||||
|
this.mask = cache ? CachedMask.cache(mask) : mask;
|
||||||
|
mutable = new MutableBlockVector3();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(BlockVector3 v) {
|
||||||
|
int x = v.x();
|
||||||
|
int y = v.y();
|
||||||
|
int z = v.z();
|
||||||
|
if (mask.test(mutable.setComponents(x + 1, y, z))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (mask.test(mutable.setComponents(x - 1, y, z))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (mask.test(mutable.setComponents(x, y, z + 1))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return mask.test(mutable.setComponents(x, y, z - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean test(Extent extent, BlockVector3 v) {
|
||||||
|
AbstractExtentMask extentMask = (AbstractExtentMask) mask;
|
||||||
|
int x = v.x();
|
||||||
|
int y = v.y();
|
||||||
|
int z = v.z();
|
||||||
|
if (extentMask.test(extent, mutable.setComponents(x + 1, y, z))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (extentMask.test(extent, mutable.setComponents(x - 1, y, z))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (extentMask.test(extent, mutable.setComponents(x, y, z + 1))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return extentMask.test(extent, mutable.setComponents(x, y, z - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mask copy() {
|
||||||
|
return new AdjacentAny2DMask(mask.copy(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -23,7 +23,7 @@ public class AdjacentAnyMask extends AbstractMask implements ResettableMask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AdjacentAnyMask(CachedMask mask, int minY, int maxY) {
|
AdjacentAnyMask(CachedMask mask, int minY, int maxY) {
|
||||||
this.mask = CachedMask.cache(mask);
|
this.mask = mask;
|
||||||
mutable = new MutableBlockVector3();
|
mutable = new MutableBlockVector3();
|
||||||
this.minY = minY;
|
this.minY = minY;
|
||||||
this.maxY = maxY;
|
this.maxY = maxY;
|
||||||
|
@ -436,7 +436,6 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet {
|
|||||||
} catch (EOFException ignored) {
|
} catch (EOFException ignored) {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
is.close();
|
is.close();
|
||||||
|
@ -62,4 +62,13 @@ public interface Filter {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signals to the filter the edit has concluded
|
||||||
|
*
|
||||||
|
* @since TODO
|
||||||
|
*/
|
||||||
|
default void finish() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,14 +10,13 @@ import com.sk89q.worldedit.math.BlockVector3;
|
|||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.io.Flushable;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public interface IBatchProcessor extends Flushable {
|
public interface IBatchProcessor {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process a chunk that has been set.
|
* Process a chunk that has been set.
|
||||||
|
@ -5,6 +5,7 @@ import com.sk89q.jnbt.CompoundTag;
|
|||||||
import com.sk89q.worldedit.extent.OutputExtent;
|
import com.sk89q.worldedit.extent.OutputExtent;
|
||||||
import com.sk89q.worldedit.function.operation.Operation;
|
import com.sk89q.worldedit.function.operation.Operation;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.util.SideEffectSet;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
|
|
||||||
@ -127,4 +128,19 @@ public interface IChunkSet extends IBlocks, OutputExtent {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the side effects to be used when settings these blocks
|
||||||
|
*
|
||||||
|
* @since TODO
|
||||||
|
*/
|
||||||
|
void setSideEffectSet(@Nonnull SideEffectSet sideEffectSet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the side effects to be used when settings these blocks
|
||||||
|
*
|
||||||
|
* @since TODO
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
SideEffectSet getSideEffectSet();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,11 @@ public interface IDelegateFilter extends Filter {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void finish() {
|
||||||
|
getParent().finish();
|
||||||
|
}
|
||||||
|
|
||||||
Filter newInstance(Filter other);
|
Filter newInstance(Filter other);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import com.sk89q.worldedit.function.operation.Operation;
|
|||||||
import com.sk89q.worldedit.math.BlockVector2;
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import com.sk89q.worldedit.util.SideEffectSet;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.io.Flushable;
|
import java.io.Flushable;
|
||||||
@ -78,6 +79,20 @@ public interface IQueueExtent<T extends IChunk> extends Flushable, Trimable, ICh
|
|||||||
|
|
||||||
boolean isFastMode();
|
boolean isFastMode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the side effects to be used with this extent
|
||||||
|
*
|
||||||
|
* @since TODO
|
||||||
|
*/
|
||||||
|
void setSideEffectSet(SideEffectSet sideEffectSet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the side effects to be used with this extent
|
||||||
|
*
|
||||||
|
* @since TODO
|
||||||
|
*/
|
||||||
|
SideEffectSet getSideEffectSet();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new root IChunk object. Full chunks will be reused, so a more optimized chunk can be
|
* Create a new root IChunk object. Full chunks will be reused, so a more optimized chunk can be
|
||||||
* returned in that case.
|
* returned in that case.
|
||||||
|
@ -18,11 +18,14 @@ import com.fastasyncworldedit.core.queue.Filter;
|
|||||||
import com.fastasyncworldedit.core.queue.IQueueChunk;
|
import com.fastasyncworldedit.core.queue.IQueueChunk;
|
||||||
import com.fastasyncworldedit.core.queue.IQueueExtent;
|
import com.fastasyncworldedit.core.queue.IQueueExtent;
|
||||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||||
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
import com.sk89q.worldedit.function.operation.Operation;
|
||||||
|
import com.sk89q.worldedit.function.operation.RunContext;
|
||||||
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||||
@ -30,6 +33,7 @@ import com.sk89q.worldedit.math.BlockVector2;
|
|||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.Countable;
|
import com.sk89q.worldedit.util.Countable;
|
||||||
|
import com.sk89q.worldedit.util.SideEffectSet;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
@ -37,7 +41,7 @@ import com.sk89q.worldedit.world.block.BlockStateHolder;
|
|||||||
import com.sk89q.worldedit.world.block.BlockType;
|
import com.sk89q.worldedit.world.block.BlockType;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.io.Flushable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -57,11 +61,12 @@ public class ParallelQueueExtent extends PassthroughExtent {
|
|||||||
// not very important)
|
// not very important)
|
||||||
private final boolean[] faweExceptionReasonsUsed = new boolean[FaweException.Type.values().length];
|
private final boolean[] faweExceptionReasonsUsed = new boolean[FaweException.Type.values().length];
|
||||||
private final boolean fastmode;
|
private final boolean fastmode;
|
||||||
|
private final SideEffectSet sideEffectSet;
|
||||||
private int changes;
|
private int changes;
|
||||||
private int lastException = Integer.MIN_VALUE;
|
private int lastException = Integer.MIN_VALUE;
|
||||||
private int exceptionCount = 0;
|
private int exceptionCount = 0;
|
||||||
|
|
||||||
public ParallelQueueExtent(QueueHandler handler, World world, boolean fastmode) {
|
public ParallelQueueExtent(QueueHandler handler, World world, boolean fastmode, @Nullable SideEffectSet sideEffectSet) {
|
||||||
super(handler.getQueue(world, new BatchProcessorHolder(), new BatchProcessorHolder()));
|
super(handler.getQueue(world, new BatchProcessorHolder(), new BatchProcessorHolder()));
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
@ -74,6 +79,7 @@ public class ParallelQueueExtent extends PassthroughExtent {
|
|||||||
((MultiBatchProcessor) this.postProcessor.getProcessor()).setFaweExceptionArray(faweExceptionReasonsUsed);
|
((MultiBatchProcessor) this.postProcessor.getProcessor()).setFaweExceptionArray(faweExceptionReasonsUsed);
|
||||||
}
|
}
|
||||||
this.fastmode = fastmode;
|
this.fastmode = fastmode;
|
||||||
|
this.sideEffectSet = sideEffectSet == null ? SideEffectSet.defaults() : sideEffectSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -120,7 +126,12 @@ public class ParallelQueueExtent extends PassthroughExtent {
|
|||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
private IQueueExtent<IQueueChunk> getNewQueue() {
|
private IQueueExtent<IQueueChunk> getNewQueue() {
|
||||||
return handler.getQueue(world, this.processor, this.postProcessor);
|
SingleThreadQueueExtent queue = (SingleThreadQueueExtent) handler.getQueue(world, this.processor, this.postProcessor);
|
||||||
|
queue.setFastMode(fastmode);
|
||||||
|
queue.setSideEffectSet(sideEffectSet);
|
||||||
|
queue.setFaweExceptionArray(faweExceptionReasonsUsed);
|
||||||
|
enter(queue);
|
||||||
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -138,19 +149,17 @@ public class ParallelQueueExtent extends PassthroughExtent {
|
|||||||
BlockVector2 pos = chunksIter.next();
|
BlockVector2 pos = chunksIter.next();
|
||||||
getExtent().apply(null, filter, region, pos.x(), pos.z(), full);
|
getExtent().apply(null, filter, region, pos.x(), pos.z(), full);
|
||||||
}
|
}
|
||||||
|
getExtent().flush();
|
||||||
|
filter.finish();
|
||||||
} else {
|
} else {
|
||||||
final ForkJoinTask[] tasks = IntStream.range(0, size).mapToObj(i -> handler.submit(() -> {
|
final ForkJoinTask[] tasks = IntStream.range(0, size).mapToObj(i -> handler.submit(() -> {
|
||||||
try {
|
try {
|
||||||
final Filter newFilter = filter.fork();
|
final Filter newFilter = filter.fork();
|
||||||
// Create a chunk that we will reuse/reset for each operation
|
// Create a chunk that we will reuse/reset for each operation
|
||||||
final SingleThreadQueueExtent queue = (SingleThreadQueueExtent) getNewQueue();
|
final SingleThreadQueueExtent queue = (SingleThreadQueueExtent) getNewQueue();
|
||||||
queue.setFastMode(fastmode);
|
|
||||||
queue.setFaweExceptionArray(faweExceptionReasonsUsed);
|
|
||||||
enter(queue);
|
|
||||||
synchronized (queue) {
|
synchronized (queue) {
|
||||||
try {
|
try {
|
||||||
ChunkFilterBlock block = null;
|
ChunkFilterBlock block = null;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// Get the next chunk posWeakChunk
|
// Get the next chunk posWeakChunk
|
||||||
final int chunkX;
|
final int chunkX;
|
||||||
@ -165,10 +174,8 @@ public class ParallelQueueExtent extends PassthroughExtent {
|
|||||||
}
|
}
|
||||||
block = queue.apply(block, newFilter, region, chunkX, chunkZ, full);
|
block = queue.apply(block, newFilter, region, chunkX, chunkZ, full);
|
||||||
}
|
}
|
||||||
if (newFilter instanceof Flushable flushable) {
|
|
||||||
flushable.flush();
|
|
||||||
}
|
|
||||||
queue.flush();
|
queue.flush();
|
||||||
|
filter.finish();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
if (t instanceof FaweException) {
|
if (t instanceof FaweException) {
|
||||||
Fawe.handleFaweException(faweExceptionReasonsUsed, (FaweException) t, LOGGER);
|
Fawe.handleFaweException(faweExceptionReasonsUsed, (FaweException) t, LOGGER);
|
||||||
@ -205,6 +212,24 @@ public class ParallelQueueExtent extends PassthroughExtent {
|
|||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Operation commitBefore() {
|
||||||
|
return new Operation() {
|
||||||
|
@Override
|
||||||
|
public Operation resume(final RunContext run) throws WorldEditException {
|
||||||
|
getExtent().commit();
|
||||||
|
processor.flush();
|
||||||
|
getExtent().flush();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int countBlocks(Region region, Mask searchMask) {
|
public int countBlocks(Region region, Mask searchMask) {
|
||||||
return
|
return
|
||||||
|
@ -27,6 +27,7 @@ import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
|||||||
import com.sk89q.worldedit.math.BlockVector2;
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import com.sk89q.worldedit.util.SideEffectSet;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
@ -68,6 +69,7 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
|
|||||||
private boolean[] faweExceptionReasonsUsed = new boolean[FaweException.Type.values().length];
|
private boolean[] faweExceptionReasonsUsed = new boolean[FaweException.Type.values().length];
|
||||||
private int lastException = Integer.MIN_VALUE;
|
private int lastException = Integer.MIN_VALUE;
|
||||||
private int exceptionCount = 0;
|
private int exceptionCount = 0;
|
||||||
|
private SideEffectSet sideEffectSet = SideEffectSet.defaults();
|
||||||
|
|
||||||
public SingleThreadQueueExtent() {
|
public SingleThreadQueueExtent() {
|
||||||
}
|
}
|
||||||
@ -110,6 +112,16 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
|
|||||||
this.fastmode = fastmode;
|
this.fastmode = fastmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSideEffectSet(SideEffectSet sideEffectSet) {
|
||||||
|
this.sideEffectSet = sideEffectSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SideEffectSet getSideEffectSet() {
|
||||||
|
return sideEffectSet;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMinY() {
|
public int getMinY() {
|
||||||
return minY;
|
return minY;
|
||||||
@ -120,6 +132,10 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
|
|||||||
return maxY;
|
return maxY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public World getWorld() {
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the cached boolean array of length {@code FaweException.Type.values().length} that determines if a thrown
|
* Sets the cached boolean array of length {@code FaweException.Type.values().length} that determines if a thrown
|
||||||
* {@link FaweException} of type {@link FaweException.Type} should be output to console, rethrown to attempt to be visible
|
* {@link FaweException} of type {@link FaweException.Type} should be output to console, rethrown to attempt to be visible
|
||||||
@ -278,10 +294,16 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
|
|||||||
private ChunkHolder poolOrCreate(int chunkX, int chunkZ) {
|
private ChunkHolder poolOrCreate(int chunkX, int chunkZ) {
|
||||||
ChunkHolder next = create(false);
|
ChunkHolder next = create(false);
|
||||||
next.init(this, chunkX, chunkZ);
|
next.init(this, chunkX, chunkZ);
|
||||||
next.setFastMode(isFastMode());
|
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IQueueChunk wrap(IQueueChunk chunk) {
|
||||||
|
chunk.setFastMode(isFastMode());
|
||||||
|
chunk.setSideEffectSet(getSideEffectSet());
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final IQueueChunk getOrCreateChunk(int x, int z) {
|
public final IQueueChunk getOrCreateChunk(int x, int z) {
|
||||||
getChunkLock.lock();
|
getChunkLock.lock();
|
||||||
|
@ -6,6 +6,7 @@ import com.fastasyncworldedit.core.queue.IChunkSet;
|
|||||||
import com.fastasyncworldedit.core.util.collection.MemBlockSet;
|
import com.fastasyncworldedit.core.util.collection.MemBlockSet;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.util.SideEffectSet;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
@ -211,6 +212,16 @@ public class BitSetBlocks implements IChunkSet {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSideEffectSet(SideEffectSet sideEffectSet) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SideEffectSet getSideEffectSet() {
|
||||||
|
return SideEffectSet.none();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSectionCount() {
|
public int getSectionCount() {
|
||||||
return layers;
|
return layers;
|
||||||
|
@ -9,6 +9,7 @@ import com.fastasyncworldedit.core.queue.Pool;
|
|||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.util.SideEffectSet;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
@ -42,6 +43,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
|||||||
public EnumMap<HeightMapType, int[]> heightMaps;
|
public EnumMap<HeightMapType, int[]> heightMaps;
|
||||||
private boolean fastMode = false;
|
private boolean fastMode = false;
|
||||||
private int bitMask = -1;
|
private int bitMask = -1;
|
||||||
|
private SideEffectSet sideEffectSet = SideEffectSet.defaults();
|
||||||
|
|
||||||
private CharSetBlocks() {
|
private CharSetBlocks() {
|
||||||
// Expand as we go
|
// Expand as we go
|
||||||
@ -372,10 +374,21 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
|||||||
heightMaps != null ? new EnumMap<>(heightMaps) : null,
|
heightMaps != null ? new EnumMap<>(heightMaps) : null,
|
||||||
defaultOrdinal(),
|
defaultOrdinal(),
|
||||||
fastMode,
|
fastMode,
|
||||||
bitMask
|
bitMask,
|
||||||
|
sideEffectSet
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSideEffectSet(SideEffectSet sideEffectSet) {
|
||||||
|
this.sideEffectSet = sideEffectSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SideEffectSet getSideEffectSet() {
|
||||||
|
return sideEffectSet;
|
||||||
|
}
|
||||||
|
|
||||||
static char[][] createLightCopy(char[][] lightArr, int sectionCount) {
|
static char[][] createLightCopy(char[][] lightArr, int sectionCount) {
|
||||||
if (lightArr == null) {
|
if (lightArr == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -9,6 +9,7 @@ import com.fastasyncworldedit.core.queue.IChunkSet;
|
|||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
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;
|
||||||
|
import com.sk89q.worldedit.util.SideEffectSet;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
@ -50,6 +51,7 @@ public class ThreadUnsafeCharBlocks implements IChunkSet, IBlocks {
|
|||||||
private Map<HeightMapType, int[]> heightMaps;
|
private Map<HeightMapType, int[]> heightMaps;
|
||||||
private boolean fastMode;
|
private boolean fastMode;
|
||||||
private int bitMask;
|
private int bitMask;
|
||||||
|
private SideEffectSet sideEffectSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New instance given the data stored in a {@link CharSetBlocks} instance.
|
* New instance given the data stored in a {@link CharSetBlocks} instance.
|
||||||
@ -70,7 +72,8 @@ public class ThreadUnsafeCharBlocks implements IChunkSet, IBlocks {
|
|||||||
Map<HeightMapType, int[]> heightMaps,
|
Map<HeightMapType, int[]> heightMaps,
|
||||||
char defaultOrdinal,
|
char defaultOrdinal,
|
||||||
boolean fastMode,
|
boolean fastMode,
|
||||||
int bitMask
|
int bitMask,
|
||||||
|
SideEffectSet sideEffectSet
|
||||||
) {
|
) {
|
||||||
this.blocks = blocks;
|
this.blocks = blocks;
|
||||||
this.minSectionPosition = minSectionPosition;
|
this.minSectionPosition = minSectionPosition;
|
||||||
@ -86,6 +89,7 @@ public class ThreadUnsafeCharBlocks implements IChunkSet, IBlocks {
|
|||||||
this.defaultOrdinal = defaultOrdinal;
|
this.defaultOrdinal = defaultOrdinal;
|
||||||
this.fastMode = fastMode;
|
this.fastMode = fastMode;
|
||||||
this.bitMask = bitMask;
|
this.bitMask = bitMask;
|
||||||
|
this.sideEffectSet = sideEffectSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -479,10 +483,21 @@ public class ThreadUnsafeCharBlocks implements IChunkSet, IBlocks {
|
|||||||
heightMaps != null ? new HashMap<>(heightMaps) : null,
|
heightMaps != null ? new HashMap<>(heightMaps) : null,
|
||||||
defaultOrdinal,
|
defaultOrdinal,
|
||||||
fastMode,
|
fastMode,
|
||||||
bitMask
|
bitMask,
|
||||||
|
sideEffectSet
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSideEffectSet(SideEffectSet sideEffectSet) {
|
||||||
|
this.sideEffectSet = sideEffectSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SideEffectSet getSideEffectSet() {
|
||||||
|
return sideEffectSet;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean trim(boolean aggressive) {
|
public boolean trim(boolean aggressive) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -15,6 +15,7 @@ import com.sk89q.jnbt.CompoundTag;
|
|||||||
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;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import com.sk89q.worldedit.util.SideEffectSet;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
@ -50,6 +51,7 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
private boolean isInit = false; // Lighting handles queue differently. It relies on the chunk cache and not doing init.
|
private boolean isInit = false; // Lighting handles queue differently. It relies on the chunk cache and not doing init.
|
||||||
private boolean createCopy = false;
|
private boolean createCopy = false;
|
||||||
private long initTime = -1L;
|
private long initTime = -1L;
|
||||||
|
private SideEffectSet sideEffectSet;
|
||||||
|
|
||||||
private ChunkHolder() {
|
private ChunkHolder() {
|
||||||
this.delegate = NULL;
|
this.delegate = NULL;
|
||||||
@ -159,6 +161,16 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
return chunkSet != null && chunkSet.hasBiomes(layer);
|
return chunkSet != null && chunkSet.hasBiomes(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSideEffectSet(SideEffectSet sideEffectSet) {
|
||||||
|
this.sideEffectSet = sideEffectSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SideEffectSet getSideEffectSet() {
|
||||||
|
return sideEffectSet;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isInit() {
|
public boolean isInit() {
|
||||||
return isInit;
|
return isInit;
|
||||||
}
|
}
|
||||||
@ -898,7 +910,6 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
public synchronized void filterBlocks(Filter filter, ChunkFilterBlock block, @Nullable Region region, boolean full) {
|
public synchronized void filterBlocks(Filter filter, ChunkFilterBlock block, @Nullable Region region, boolean full) {
|
||||||
final IChunkGet get = getOrCreateGet();
|
final IChunkGet get = getOrCreateGet();
|
||||||
final IChunkSet set = getOrCreateSet();
|
final IChunkSet set = getOrCreateSet();
|
||||||
set.setFastMode(fastmode);
|
|
||||||
try {
|
try {
|
||||||
block.filter(this, get, set, filter, region, full);
|
block.filter(this, get, set, filter, region, full);
|
||||||
} finally {
|
} finally {
|
||||||
@ -967,13 +978,21 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
return chunkSet;
|
return chunkSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final IChunkSet getChunkSet() {
|
||||||
|
return chunkSet;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a wrapped set object
|
* Create a wrapped set object
|
||||||
* - The purpose of wrapping is to allow different extents to intercept / alter behavior
|
* - The purpose of wrapping is to allow different extents to intercept / alter behavior
|
||||||
* - e.g., caching, optimizations, filtering
|
* - e.g., caching, optimizations, filtering
|
||||||
*/
|
*/
|
||||||
private IChunkSet newWrappedSet() {
|
private IChunkSet newWrappedSet() {
|
||||||
return extent.getCachedSet(chunkX, chunkZ);
|
IChunkSet set = extent.getCachedSet(chunkX, chunkZ);
|
||||||
|
set.setFastMode(fastmode);
|
||||||
|
set.setSideEffectSet(sideEffectSet);
|
||||||
|
set.setBitMask(bitMask);
|
||||||
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1004,7 +1023,6 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
@Override
|
@Override
|
||||||
public synchronized T call() {
|
public synchronized T call() {
|
||||||
if (chunkSet != null && !chunkSet.isEmpty()) {
|
if (chunkSet != null && !chunkSet.isEmpty()) {
|
||||||
chunkSet.setBitMask(bitMask);
|
|
||||||
IChunkSet copy = chunkSet.createCopy();
|
IChunkSet copy = chunkSet.createCopy();
|
||||||
return this.call(copy, () -> {
|
return this.call(copy, () -> {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
|
@ -8,6 +8,7 @@ import com.fastasyncworldedit.core.queue.IQueueChunk;
|
|||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import com.sk89q.worldedit.util.SideEffectSet;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
@ -87,6 +88,16 @@ public final class NullChunk implements IQueueChunk {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSideEffectSet(SideEffectSet sideEffectSet) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SideEffectSet getSideEffectSet() {
|
||||||
|
return SideEffectSet.none();
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public int[] getHeightMap(@Nullable HeightMapType type) {
|
public int[] getHeightMap(@Nullable HeightMapType type) {
|
||||||
return new int[256];
|
return new int[256];
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
package com.fastasyncworldedit.core.util;
|
package com.fastasyncworldedit.core.util;
|
||||||
|
|
||||||
|
import com.fastasyncworldedit.core.queue.implementation.ParallelQueueExtent;
|
||||||
|
import com.fastasyncworldedit.core.queue.implementation.SingleThreadQueueExtent;
|
||||||
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.world.World;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -21,6 +25,26 @@ public class ExtentTraverser<T extends Extent> {
|
|||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the world backing the given extent, if present, else null.
|
||||||
|
*
|
||||||
|
* @since TODO
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static World getWorldFromExtent(Extent extent) {
|
||||||
|
if (extent.isWorld()) {
|
||||||
|
return (World) extent;
|
||||||
|
} else if (extent instanceof EditSession session) {
|
||||||
|
return session.getWorld();
|
||||||
|
} else if (extent instanceof SingleThreadQueueExtent stqe) {
|
||||||
|
return stqe.getWorld();
|
||||||
|
} else if (extent instanceof ParallelQueueExtent pqe) {
|
||||||
|
return ((SingleThreadQueueExtent) pqe.getExtent()).getWorld();
|
||||||
|
} else {
|
||||||
|
return new ExtentTraverser<>(extent).findAndGet(World.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean exists() {
|
public boolean exists() {
|
||||||
return root != null;
|
return root != null;
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,7 @@ import com.sk89q.worldedit.extent.Extent;
|
|||||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import com.sk89q.worldedit.regions.RegionIntersection;
|
||||||
import com.sk89q.worldedit.util.Identifiable;
|
import com.sk89q.worldedit.util.Identifiable;
|
||||||
import com.sk89q.worldedit.util.SideEffect;
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
import com.sk89q.worldedit.util.SideEffectSet;
|
import com.sk89q.worldedit.util.SideEffectSet;
|
||||||
@ -484,7 +485,12 @@ public final class EditSessionBuilder {
|
|||||||
if (unwrapped instanceof IQueueExtent) {
|
if (unwrapped instanceof IQueueExtent) {
|
||||||
extent = queue = (IQueueExtent) unwrapped;
|
extent = queue = (IQueueExtent) unwrapped;
|
||||||
} else if (Settings.settings().QUEUE.PARALLEL_THREADS > 1 && !Fawe.isMainThread()) {
|
} else if (Settings.settings().QUEUE.PARALLEL_THREADS > 1 && !Fawe.isMainThread()) {
|
||||||
ParallelQueueExtent parallel = new ParallelQueueExtent(Fawe.instance().getQueueHandler(), world, fastMode);
|
ParallelQueueExtent parallel = new ParallelQueueExtent(
|
||||||
|
Fawe.instance().getQueueHandler(),
|
||||||
|
world,
|
||||||
|
fastMode,
|
||||||
|
sideEffectSet
|
||||||
|
);
|
||||||
queue = parallel.getExtent();
|
queue = parallel.getExtent();
|
||||||
extent = parallel;
|
extent = parallel;
|
||||||
} else {
|
} else {
|
||||||
@ -560,8 +566,7 @@ public final class EditSessionBuilder {
|
|||||||
}
|
}
|
||||||
// There's no need to do the below (and it'll also just be a pain to implement) if we're not placing chunks
|
// There's no need to do the below (and it'll also just be a pain to implement) if we're not placing chunks
|
||||||
if (placeChunks) {
|
if (placeChunks) {
|
||||||
if (this.sideEffectSet.shouldApply(SideEffect.LIGHTING) &&
|
if (this.sideEffectSet.shouldApply(SideEffect.LIGHTING) || (relightMode != null && relightMode != RelightMode.NONE)) {
|
||||||
((relightMode != null && relightMode != RelightMode.NONE) || (relightMode == null && Settings.settings().LIGHTING.MODE > 0))) {
|
|
||||||
relighter = WorldEdit
|
relighter = WorldEdit
|
||||||
.getInstance()
|
.getInstance()
|
||||||
.getPlatformManager()
|
.getPlatformManager()
|
||||||
@ -573,17 +578,16 @@ public final class EditSessionBuilder {
|
|||||||
if (this.sideEffectSet.shouldApply(SideEffect.HEIGHTMAPS)) {
|
if (this.sideEffectSet.shouldApply(SideEffect.HEIGHTMAPS)) {
|
||||||
queue.addProcessor(new HeightmapProcessor(world.getMinY(), world.getMaxY()));
|
queue.addProcessor(new HeightmapProcessor(world.getMinY(), world.getMaxY()));
|
||||||
}
|
}
|
||||||
if (this.sideEffectSet.shouldApply(SideEffect.UPDATE) || this.sideEffectSet.shouldApply(SideEffect.NEIGHBORS)) {
|
if (this.sideEffectSet.shouldApply(SideEffect.UPDATE) || this.sideEffectSet.shouldApply(SideEffect.NEIGHBORS) || this.sideEffectSet.shouldApply(
|
||||||
|
SideEffect.VALIDATION)) {
|
||||||
|
Region region = allowedRegions == null || allowedRegions.length == 0
|
||||||
|
? null
|
||||||
|
: allowedRegions.length == 1 ? allowedRegions[0] : new RegionIntersection(allowedRegions);
|
||||||
queue.addProcessor(WorldEdit
|
queue.addProcessor(WorldEdit
|
||||||
.getInstance()
|
.getInstance()
|
||||||
.getPlatformManager()
|
.getPlatformManager()
|
||||||
.queryCapability(Capability.WORLD_EDITING)
|
.queryCapability(Capability.WORLD_EDITING)
|
||||||
.getPlatformPlacementProcessor(
|
.getPlatformPlacementProcessor(extent, null, region));
|
||||||
queue,
|
|
||||||
null,
|
|
||||||
Settings.settings().GENERAL.PERFORM_SECOND_UPDATE_PASS,
|
|
||||||
true
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Settings.settings().EXPERIMENTAL.KEEP_ENTITIES_IN_BLOCKS) {
|
if (!Settings.settings().EXPERIMENTAL.KEEP_ENTITIES_IN_BLOCKS) {
|
||||||
|
@ -41,7 +41,6 @@ import com.sk89q.worldedit.extension.platform.Actor;
|
|||||||
import com.sk89q.worldedit.extension.platform.Capability;
|
import com.sk89q.worldedit.extension.platform.Capability;
|
||||||
import com.sk89q.worldedit.function.GroundFunction;
|
import com.sk89q.worldedit.function.GroundFunction;
|
||||||
import com.sk89q.worldedit.function.generator.FloraGenerator;
|
import com.sk89q.worldedit.function.generator.FloraGenerator;
|
||||||
import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
|
||||||
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.function.mask.MaskIntersection;
|
import com.sk89q.worldedit.function.mask.MaskIntersection;
|
||||||
@ -904,9 +903,7 @@ public class RegionCommands {
|
|||||||
@Confirm(Confirm.Processor.REGION)
|
@Confirm(Confirm.Processor.REGION)
|
||||||
@Preload(Preload.PreloadCheck.PRELOAD)
|
@Preload(Preload.PreloadCheck.PRELOAD)
|
||||||
public int fixblocks(
|
public int fixblocks(
|
||||||
Actor actor, EditSession editSession, @Selection Region region,
|
Actor actor, EditSession editSession, @Selection Region region
|
||||||
@Switch(name = 'n', desc = "Do not perform a second pass ")
|
|
||||||
boolean noSecondPass
|
|
||||||
) {
|
) {
|
||||||
int affected = editSession.setBlocks(
|
int affected = editSession.setBlocks(
|
||||||
region,
|
region,
|
||||||
@ -914,7 +911,7 @@ public class RegionCommands {
|
|||||||
.getInstance()
|
.getInstance()
|
||||||
.getPlatformManager()
|
.getPlatformManager()
|
||||||
.queryCapability(Capability.WORLD_EDITING)
|
.queryCapability(Capability.WORLD_EDITING)
|
||||||
.getPlatformPlacementProcessor(editSession, null, !noSecondPass, true)
|
.getPlatformPlacementProcessor(editSession, null, region)
|
||||||
);
|
);
|
||||||
if (affected != 0) {
|
if (affected != 0) {
|
||||||
actor.print(Caption.of("worldedit.set.done", TextComponent.of(affected)));
|
actor.print(Caption.of("worldedit.set.done", TextComponent.of(affected)));
|
||||||
|
@ -19,16 +19,16 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.extension.platform;
|
package com.sk89q.worldedit.extension.platform;
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.extent.processor.PlacementStateProcessor;
|
import com.fastasyncworldedit.core.extent.PlacementStateProcessor;
|
||||||
import com.fastasyncworldedit.core.extent.processor.lighting.Relighter;
|
import com.fastasyncworldedit.core.extent.processor.lighting.Relighter;
|
||||||
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
||||||
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
||||||
import com.sk89q.worldedit.LocalConfiguration;
|
import com.sk89q.worldedit.LocalConfiguration;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
|
||||||
import com.sk89q.worldedit.entity.Player;
|
import com.sk89q.worldedit.entity.Player;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
||||||
import com.sk89q.worldedit.internal.util.NonAbstractForCompatibility;
|
import com.sk89q.worldedit.internal.util.NonAbstractForCompatibility;
|
||||||
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.registry.Keyed;
|
import com.sk89q.worldedit.registry.Keyed;
|
||||||
import com.sk89q.worldedit.util.SideEffect;
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
import com.sk89q.worldedit.util.io.ResourceLoader;
|
import com.sk89q.worldedit.util.io.ResourceLoader;
|
||||||
@ -281,15 +281,12 @@ public interface Platform extends Keyed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an {@link PlacementStateProcessor} instance for processing placed blocks to "fix" them.
|
* Returns an {@link PlacementStateProcessor} instance for processing placed blocks to "fix" them. Optional region to
|
||||||
|
* prevent any changes outside of, as sometimes block neighbours will also be updated otherwise.
|
||||||
|
*
|
||||||
* @since TODO
|
* @since TODO
|
||||||
*/
|
*/
|
||||||
default PlacementStateProcessor getPlatformPlacementProcessor(
|
default PlacementStateProcessor getPlatformPlacementProcessor(Extent extent, BlockTypeMask mask, @Nullable Region region) {
|
||||||
Extent extent,
|
|
||||||
BlockTypeMask mask,
|
|
||||||
boolean secondPass,
|
|
||||||
boolean includeUnedited
|
|
||||||
) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
//FAWE end
|
//FAWE end
|
||||||
|
@ -21,6 +21,7 @@ package com.sk89q.worldedit.function.mask;
|
|||||||
|
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
import com.sk89q.worldedit.world.block.BlockType;
|
import com.sk89q.worldedit.world.block.BlockType;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
|
|
||||||
@ -140,6 +141,10 @@ public class BlockTypeMask extends AbstractExtentMask {
|
|||||||
public boolean test(BlockType block) {
|
public boolean test(BlockType block) {
|
||||||
return types[block.getInternalId()];
|
return types[block.getInternalId()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <B extends BlockStateHolder<B>> boolean test(B blockStateHolder) {
|
||||||
|
return types[blockStateHolder.getBlockType().getInternalId()];
|
||||||
|
}
|
||||||
//FAWE end
|
//FAWE end
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -27,7 +27,7 @@ public enum SideEffect {
|
|||||||
//FAWE start - adjust defaults, add history and heightmaps
|
//FAWE start - adjust defaults, add history and heightmaps
|
||||||
HISTORY(State.ON, true),
|
HISTORY(State.ON, true),
|
||||||
HEIGHTMAPS(State.ON, true),
|
HEIGHTMAPS(State.ON, true),
|
||||||
LIGHTING(State.OFF, true), // Off defaults to falling through to config
|
LIGHTING(Settings.settings().LIGHTING.MODE == 0 ? State.OFF : State.ON, true),
|
||||||
NEIGHBORS(State.OFF, true),
|
NEIGHBORS(State.OFF, true),
|
||||||
UPDATE(State.OFF, true),
|
UPDATE(State.OFF, true),
|
||||||
//FAWE end
|
//FAWE end
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren