3
0
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:
dordsor21 2024-05-31 17:51:50 +01:00
Ursprung 6e4f8770b6
Commit 74d4b57b4f
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 1E53E88969FFCF0B
50 geänderte Dateien mit 1007 neuen und 730 gelöschten Zeilen

Datei anzeigen

@ -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) {

Datei anzeigen

@ -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) {

Datei anzeigen

@ -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);

Datei anzeigen

@ -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
);
} }
} }

Datei anzeigen

@ -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) {

Datei anzeigen

@ -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) {

Datei anzeigen

@ -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);

Datei anzeigen

@ -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
);
} }
} }

Datei anzeigen

@ -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) {

Datei anzeigen

@ -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) {

Datei anzeigen

@ -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);

Datei anzeigen

@ -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
);
} }
} }

Datei anzeigen

@ -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) {

Datei anzeigen

@ -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) {

Datei anzeigen

@ -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);

Datei anzeigen

@ -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
);
} }
} }

Datei anzeigen

@ -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) {

Datei anzeigen

@ -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) {

Datei anzeigen

@ -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()

Datei anzeigen

@ -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
); );
} }

Datei anzeigen

@ -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
} }

Datei anzeigen

@ -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

Datei anzeigen

@ -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);

Datei anzeigen

@ -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;
} }
} }

Datei anzeigen

@ -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);
}
}

Datei anzeigen

@ -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();

Datei anzeigen

@ -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);
}
}
} }

Datei anzeigen

@ -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();
}
} }

Datei anzeigen

@ -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);
}
}

Datei anzeigen

@ -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);
}
}

Datei anzeigen

@ -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;

Datei anzeigen

@ -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();

Datei anzeigen

@ -62,4 +62,13 @@ public interface Filter {
} }
/**
* Signals to the filter the edit has concluded
*
* @since TODO
*/
default void finish() {
}
} }

Datei anzeigen

@ -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.

Datei anzeigen

@ -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();
} }

Datei anzeigen

@ -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);
} }

Datei anzeigen

@ -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.

Datei anzeigen

@ -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

Datei anzeigen

@ -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();

Datei anzeigen

@ -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;

Datei anzeigen

@ -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;

Datei anzeigen

@ -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;

Datei anzeigen

@ -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

Datei anzeigen

@ -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];

Datei anzeigen

@ -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;
} }

Datei anzeigen

@ -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) {

Datei anzeigen

@ -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)));

Datei anzeigen

@ -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

Datei anzeigen

@ -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

Datei anzeigen

@ -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