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.core.FaweCache;
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.queue.IBatchProcessor;
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.util.Direction;
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.nbt.BinaryTag;
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) {
return Block.stateById(ordinalToIbdID[blockState.getOrdinal()]);
return Block.stateById(getOrdinalToIbdID()[blockState.getOrdinal()]);
}
@Override
@ -614,13 +613,8 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
}
@Override
public PlacementStateProcessor getPlatformPlacementProcessor(
Extent extent,
BlockTypeMask mask,
boolean secondPass,
boolean includeUnedited
) {
return new PaperweightPlacementStateProcessor(extent, mask, secondPass, includeUnedited);
public PlacementStateProcessor getPlatformPlacementProcessor(Extent extent, BlockTypeMask mask, Region region ) {
return new PaperweightPlacementStateProcessor(extent, mask, region);
}
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.util.LogManagerCompat;
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.BiomeTypes;
import com.sk89q.worldedit.world.block.BlockTypesCache;
@ -822,7 +823,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
nmsChunk.mustNotSave = false;
nmsChunk.setUnsaved(true);
// 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);
}
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.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.extent.Extent;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.FluidTags;
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.state.BlockState;
import net.minecraft.world.level.material.FluidState;
@ -20,17 +20,15 @@ import javax.annotation.Nullable;
public class PaperweightLevelProxy extends ServerLevel {
private PaperweightFaweAdapter adapter;
private Extent extent;
private ServerLevel serverLevel;
private boolean enabled = false;
private PaperweightPlacementStateProcessor processor;
@SuppressWarnings("DataFlowIssue")
public PaperweightLevelProxy() {
private PaperweightLevelProxy() {
super(null, null, null, null, null, null, null, true, 0L, null, true, null, null, null);
throw new IllegalStateException("Cannot be instantiated");
}
public static PaperweightLevelProxy getInstance(ServerLevel level, Extent extent) {
public static PaperweightLevelProxy getInstance(PaperweightPlacementStateProcessor processor) {
Unsafe unsafe = ReflectionUtils.getUnsafe();
PaperweightLevelProxy newLevel;
@ -39,45 +37,41 @@ public class PaperweightLevelProxy extends ServerLevel {
} catch (InstantiationException e) {
throw new RuntimeException(e);
}
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin
.getInstance()
.getBukkitImplAdapter());
newLevel.extent = extent;
newLevel.serverLevel = level;
newLevel.processor = processor;
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin.getInstance().getBukkitImplAdapter());
return newLevel;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@Nullable
@Override
public BlockEntity getBlockEntity(@Nonnull BlockPos blockPos) {
if (!enabled) {
if (blockPos.getX() == Integer.MAX_VALUE) {
return null;
}
BlockEntity tileEntity = this.serverLevel.getChunkAt(blockPos).getBlockEntity(blockPos);
if (tileEntity == null) {
com.sk89q.jnbt.CompoundTag tag = processor.getTileAt(blockPos.getX(), blockPos.getY(), blockPos.getZ());
if (tag == null) {
return null;
}
BlockEntity newEntity = tileEntity.getType().create(blockPos, getBlockState(blockPos));
newEntity.load((CompoundTag) adapter.fromNativeBinary(this.extent.getFullBlock(
blockPos.getX(),
blockPos.getY(),
blockPos.getZ()
).getNbtReference().getValue()));
return newEntity;
BlockState state = adapter.adapt(processor.getBlockStateAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
if (!(state.getBlock() instanceof EntityBlock entityBlock)) {
return null;
}
BlockEntity tileEntity = entityBlock.newBlockEntity(blockPos, state);
tileEntity.load((CompoundTag) adapter.fromNative(tag));
return tileEntity;
}
@Override
@Nonnull
public BlockState getBlockState(@Nonnull BlockPos blockPos) {
if (!enabled) {
if (blockPos.getX() == Integer.MAX_VALUE) {
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);
}
@ -85,7 +79,7 @@ public class PaperweightLevelProxy extends ServerLevel {
@Override
@Nonnull
public FluidState getFluidState(@Nonnull BlockPos pos) {
if (!enabled) {
if (pos.getX() == Integer.MAX_VALUE) {
return Fluids.EMPTY.defaultFluidState();
}
return getBlockState(pos).getFluidState();
@ -94,7 +88,7 @@ public class PaperweightLevelProxy extends ServerLevel {
@SuppressWarnings("unused")
@Override
public boolean isWaterAt(@Nonnull BlockPos pos) {
if (!enabled) {
if (pos.getX() == Integer.MAX_VALUE) {
return false;
}
return getBlockState(pos).getFluidState().is(FluidTags.WATER);

Datei anzeigen

@ -1,28 +1,23 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3;
import com.fastasyncworldedit.core.extent.processor.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.fastasyncworldedit.core.extent.PlacementStateProcessor;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.BlockTypeMask;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.Region;
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.BlockTypesCache;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
import javax.annotation.Nullable;
import java.util.Queue;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
public class PaperweightPlacementStateProcessor extends PlacementStateProcessor {
@ -32,47 +27,22 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
private final FaweMutableBlockPlaceContext mutableBlockPlaceContext;
private final PaperweightLevelProxy proxyLevel;
public PaperweightPlacementStateProcessor(
final Extent extent,
final BlockTypeMask mask,
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
);
public PaperweightPlacementStateProcessor(Extent extent, BlockTypeMask mask, Region region) {
super(extent, mask, region);
this.proxyLevel = PaperweightLevelProxy.getInstance(this);
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
}
private PaperweightPlacementStateProcessor(
Extent extent,
BlockTypeMask mask,
boolean secondPass,
boolean includeUnedited,
Queue<IntTriple> crossChunkSecondPasses,
PaperweightLevelProxy proxyLevel
Map<SecondPass, Character> crossChunkSecondPasses,
ThreadLocal<PlacementStateProcessor> threadProcessors,
Region region,
AtomicBoolean finished
) {
super(extent, mask, secondPass, includeUnedited, crossChunkSecondPasses);
this.proxyLevel = proxyLevel;
super(extent, mask, crossChunkSecondPasses, threadProcessors, region, finished);
this.proxyLevel = PaperweightLevelProxy.getInstance(this);
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
}
@ -94,8 +64,8 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
new BlockHitResult(pos, side, blockPos, false),
side.getOpposite()
));
return newState == null ? BlockTypesCache.ReservedIDs.AIR :
adapter.ibdIDToOrdinal(Block.BLOCK_STATE_REGISTRY.getId(newState));
return newState == null ? BlockTypesCache.ReservedIDs.AIR : adapter.ibdIDToOrdinal(Block.BLOCK_STATE_REGISTRY.getId(
newState));
}
@Override
@ -104,19 +74,12 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
if (child == getExtent()) {
return this;
}
return new PaperweightPlacementStateProcessor(child, mask, secondPass, includeUnedited);
return new PaperweightPlacementStateProcessor(child, mask, region);
}
@Override
public PlacementStateProcessor fork() {
return new PaperweightPlacementStateProcessor(
extent,
mask,
secondPass,
includeUnedited,
crossChunkSecondPasses,
proxyLevel
);
return new PaperweightPlacementStateProcessor(extent, mask, postCompleteSecondPasses, threadProcessors, region, finished);
}
}

Datei anzeigen

@ -4,7 +4,7 @@ import com.fastasyncworldedit.bukkit.adapter.FaweAdapter;
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
import com.fastasyncworldedit.core.FaweCache;
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.queue.IBatchProcessor;
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.util.Direction;
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.nbt.BinaryTag;
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) {
return Block.stateById(ordinalToIbdID[blockState.getOrdinal()]);
return Block.stateById(getOrdinalToIbdID()[blockState.getOrdinal()]);
}
@Override
@ -614,13 +613,8 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
}
@Override
public PlacementStateProcessor getPlatformPlacementProcessor(
Extent extent,
BlockTypeMask mask,
boolean secondPass,
boolean includeUnedited
) {
return new PaperweightPlacementStateProcessor(extent, mask, secondPass, includeUnedited);
public PlacementStateProcessor getPlatformPlacementProcessor(Extent extent, BlockTypeMask mask, Region region) {
return new PaperweightPlacementStateProcessor(extent, mask, region);
}
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.util.LogManagerCompat;
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.BiomeTypes;
import com.sk89q.worldedit.world.block.BlockTypesCache;
@ -820,7 +821,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
nmsChunk.mustNotSave = false;
nmsChunk.setUnsaved(true);
// 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);
}
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.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.extent.Extent;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.FluidTags;
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.state.BlockState;
import net.minecraft.world.level.material.FluidState;
@ -20,17 +20,15 @@ import javax.annotation.Nullable;
public class PaperweightLevelProxy extends ServerLevel {
private PaperweightFaweAdapter adapter;
private Extent extent;
private ServerLevel serverLevel;
private boolean enabled = false;
private PaperweightPlacementStateProcessor processor;
@SuppressWarnings("DataFlowIssue")
public PaperweightLevelProxy() {
private PaperweightLevelProxy() {
super(null, null, null, null, null, null, null, true, 0L, null, true, null, null, null, null);
throw new IllegalStateException("Cannot be instantiated");
}
public static PaperweightLevelProxy getInstance(ServerLevel level, Extent extent) {
public static PaperweightLevelProxy getInstance(PaperweightPlacementStateProcessor processor) {
Unsafe unsafe = ReflectionUtils.getUnsafe();
PaperweightLevelProxy newLevel;
@ -39,45 +37,41 @@ public class PaperweightLevelProxy extends ServerLevel {
} catch (InstantiationException e) {
throw new RuntimeException(e);
}
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin
.getInstance()
.getBukkitImplAdapter());
newLevel.extent = extent;
newLevel.serverLevel = level;
newLevel.processor = processor;
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin.getInstance().getBukkitImplAdapter());
return newLevel;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@Nullable
@Override
public BlockEntity getBlockEntity(@Nonnull BlockPos blockPos) {
if (!enabled) {
if (blockPos.getX() == Integer.MAX_VALUE) {
return null;
}
BlockEntity tileEntity = this.serverLevel.getChunkAt(blockPos).getBlockEntity(blockPos);
if (tileEntity == null) {
com.sk89q.jnbt.CompoundTag tag = processor.getTileAt(blockPos.getX(), blockPos.getY(), blockPos.getZ());
if (tag == null) {
return null;
}
BlockEntity newEntity = tileEntity.getType().create(blockPos, getBlockState(blockPos));
newEntity.load((CompoundTag) adapter.fromNativeBinary(this.extent.getFullBlock(
blockPos.getX(),
blockPos.getY(),
blockPos.getZ()
).getNbtReference().getValue()));
return newEntity;
BlockState state = adapter.adapt(processor.getBlockStateAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
if (!(state.getBlock() instanceof EntityBlock entityBlock)) {
return null;
}
BlockEntity tileEntity = entityBlock.newBlockEntity(blockPos, state);
tileEntity.load((CompoundTag) adapter.fromNative(tag));
return tileEntity;
}
@Override
@Nonnull
public BlockState getBlockState(@Nonnull BlockPos blockPos) {
if (!enabled) {
if (blockPos.getX() == Integer.MAX_VALUE) {
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);
}
@ -85,7 +79,7 @@ public class PaperweightLevelProxy extends ServerLevel {
@Override
@Nonnull
public FluidState getFluidState(@Nonnull BlockPos pos) {
if (!enabled) {
if (pos.getX() == Integer.MAX_VALUE) {
return Fluids.EMPTY.defaultFluidState();
}
return getBlockState(pos).getFluidState();
@ -94,7 +88,7 @@ public class PaperweightLevelProxy extends ServerLevel {
@SuppressWarnings("unused")
@Override
public boolean isWaterAt(@Nonnull BlockPos pos) {
if (!enabled) {
if (pos.getX() == Integer.MAX_VALUE) {
return false;
}
return getBlockState(pos).getFluidState().is(FluidTags.WATER);

Datei anzeigen

@ -1,28 +1,23 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1;
import com.fastasyncworldedit.core.extent.processor.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.fastasyncworldedit.core.extent.PlacementStateProcessor;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.BlockTypeMask;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.Region;
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.BlockTypesCache;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld;
import javax.annotation.Nullable;
import java.util.Queue;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
public class PaperweightPlacementStateProcessor extends PlacementStateProcessor {
@ -32,47 +27,22 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
private final FaweMutableBlockPlaceContext mutableBlockPlaceContext;
private final PaperweightLevelProxy proxyLevel;
public PaperweightPlacementStateProcessor(
final Extent extent,
final BlockTypeMask mask,
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
);
public PaperweightPlacementStateProcessor(Extent extent, BlockTypeMask mask, Region region) {
super(extent, mask, region);
this.proxyLevel = PaperweightLevelProxy.getInstance(this);
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
}
private PaperweightPlacementStateProcessor(
Extent extent,
BlockTypeMask mask,
boolean secondPass,
boolean includeUnedited,
Queue<IntTriple> crossChunkSecondPasses,
PaperweightLevelProxy proxyLevel
Map<SecondPass, Character> crossChunkSecondPasses,
ThreadLocal<PlacementStateProcessor> threadProcessors,
Region region,
AtomicBoolean finished
) {
super(extent, mask, secondPass, includeUnedited, crossChunkSecondPasses);
this.proxyLevel = proxyLevel;
super(extent, mask, crossChunkSecondPasses, threadProcessors, region, finished);
this.proxyLevel = PaperweightLevelProxy.getInstance(this);
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
}
@ -104,19 +74,12 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
if (child == getExtent()) {
return this;
}
return new PaperweightPlacementStateProcessor(child, mask, secondPass, includeUnedited);
return new PaperweightPlacementStateProcessor(child, mask, region);
}
@Override
public PlacementStateProcessor fork() {
return new PaperweightPlacementStateProcessor(
extent,
mask,
secondPass,
includeUnedited,
crossChunkSecondPasses,
proxyLevel
);
return new PaperweightPlacementStateProcessor(extent, mask, postCompleteSecondPasses, threadProcessors, region, finished);
}
}

Datei anzeigen

@ -4,7 +4,7 @@ import com.fastasyncworldedit.bukkit.adapter.FaweAdapter;
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
import com.fastasyncworldedit.core.FaweCache;
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.queue.IBatchProcessor;
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.util.Direction;
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.nbt.BinaryTag;
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) {
return Block.stateById(ordinalToIbdID[blockState.getOrdinal()]);
return Block.stateById(getOrdinalToIbdID()[blockState.getOrdinal()]);
}
@Override
@ -617,13 +616,8 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
}
@Override
public PlacementStateProcessor getPlatformPlacementProcessor(
Extent extent,
BlockTypeMask mask,
boolean secondPass,
boolean includeUnedited
) {
return new PaperweightPlacementStateProcessor(extent, mask, secondPass, includeUnedited);
public PlacementStateProcessor getPlatformPlacementProcessor(Extent extent, BlockTypeMask mask, Region region) {
return new PaperweightPlacementStateProcessor(extent, mask, region);
}
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.util.LogManagerCompat;
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.BiomeTypes;
import com.sk89q.worldedit.world.block.BlockTypesCache;
import io.papermc.lib.PaperLib;
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.server.level.ServerLevel;
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.BlockEntity;
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.lighting.LevelLightEngine;
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 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.ConcurrentHashMap;
import java.util.concurrent.Future;
@ -807,7 +829,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
nmsChunk.mustNotSave = false;
nmsChunk.setUnsaved(true);
// 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);
}
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.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.extent.Extent;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.FluidTags;
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.state.BlockState;
import net.minecraft.world.level.material.FluidState;
@ -20,17 +20,15 @@ import javax.annotation.Nullable;
public class PaperweightLevelProxy extends ServerLevel {
private PaperweightFaweAdapter adapter;
private Extent extent;
private ServerLevel serverLevel;
private boolean enabled = false;
private PaperweightPlacementStateProcessor processor;
@SuppressWarnings("DataFlowIssue")
public PaperweightLevelProxy() {
private PaperweightLevelProxy() {
super(null, null, null, null, null, null, null, true, 0L, null, true, null, null, null, null);
throw new IllegalStateException("Cannot be instantiated");
}
public static PaperweightLevelProxy getInstance(ServerLevel level, Extent extent) {
public static PaperweightLevelProxy getInstance(PaperweightPlacementStateProcessor processor) {
Unsafe unsafe = ReflectionUtils.getUnsafe();
PaperweightLevelProxy newLevel;
@ -39,45 +37,41 @@ public class PaperweightLevelProxy extends ServerLevel {
} catch (InstantiationException e) {
throw new RuntimeException(e);
}
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin
.getInstance()
.getBukkitImplAdapter());
newLevel.extent = extent;
newLevel.serverLevel = level;
newLevel.processor = processor;
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin.getInstance().getBukkitImplAdapter());
return newLevel;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@Nullable
@Override
public BlockEntity getBlockEntity(@Nonnull BlockPos blockPos) {
if (!enabled) {
if (blockPos.getX() == Integer.MAX_VALUE) {
return null;
}
BlockEntity tileEntity = this.serverLevel.getChunkAt(blockPos).getBlockEntity(blockPos);
if (tileEntity == null) {
com.sk89q.jnbt.CompoundTag tag = processor.getTileAt(blockPos.getX(), blockPos.getY(), blockPos.getZ());
if (tag == null) {
return null;
}
BlockEntity newEntity = tileEntity.getType().create(blockPos, getBlockState(blockPos));
newEntity.load((CompoundTag) adapter.fromNativeBinary(this.extent.getFullBlock(
blockPos.getX(),
blockPos.getY(),
blockPos.getZ()
).getNbtReference().getValue()));
return newEntity;
BlockState state = adapter.adapt(processor.getBlockStateAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
if (!(state.getBlock() instanceof EntityBlock entityBlock)) {
return null;
}
BlockEntity tileEntity = entityBlock.newBlockEntity(blockPos, state);
tileEntity.load((CompoundTag) adapter.fromNative(tag));
return tileEntity;
}
@Override
@Nonnull
public BlockState getBlockState(@Nonnull BlockPos blockPos) {
if (!enabled) {
if (blockPos.getX() == Integer.MAX_VALUE) {
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);
}
@ -85,7 +79,7 @@ public class PaperweightLevelProxy extends ServerLevel {
@Override
@Nonnull
public FluidState getFluidState(@Nonnull BlockPos pos) {
if (!enabled) {
if (pos.getX() == Integer.MAX_VALUE) {
return Fluids.EMPTY.defaultFluidState();
}
return getBlockState(pos).getFluidState();
@ -94,7 +88,7 @@ public class PaperweightLevelProxy extends ServerLevel {
@SuppressWarnings("unused")
@Override
public boolean isWaterAt(@Nonnull BlockPos pos) {
if (!enabled) {
if (pos.getX() == Integer.MAX_VALUE) {
return false;
}
return getBlockState(pos).getFluidState().is(FluidTags.WATER);

Datei anzeigen

@ -1,28 +1,23 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R2;
import com.fastasyncworldedit.core.extent.processor.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.fastasyncworldedit.core.extent.PlacementStateProcessor;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.BlockTypeMask;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.Region;
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.BlockTypesCache;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import org.bukkit.craftbukkit.v1_20_R2.CraftWorld;
import javax.annotation.Nullable;
import java.util.Queue;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
public class PaperweightPlacementStateProcessor extends PlacementStateProcessor {
@ -32,47 +27,22 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
private final FaweMutableBlockPlaceContext mutableBlockPlaceContext;
private final PaperweightLevelProxy proxyLevel;
public PaperweightPlacementStateProcessor(
final Extent extent,
final BlockTypeMask mask,
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
);
public PaperweightPlacementStateProcessor(Extent extent, BlockTypeMask mask, Region region) {
super(extent, mask, region);
this.proxyLevel = PaperweightLevelProxy.getInstance(this);
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
}
private PaperweightPlacementStateProcessor(
Extent extent,
BlockTypeMask mask,
boolean secondPass,
boolean includeUnedited,
Queue<IntTriple> crossChunkSecondPasses,
PaperweightLevelProxy proxyLevel
Map<SecondPass, Character> crossChunkSecondPasses,
ThreadLocal<PlacementStateProcessor> threadProcessors,
Region region,
AtomicBoolean finished
) {
super(extent, mask, secondPass, includeUnedited, crossChunkSecondPasses);
this.proxyLevel = proxyLevel;
super(extent, mask, crossChunkSecondPasses, threadProcessors, region, finished);
this.proxyLevel = PaperweightLevelProxy.getInstance(this);
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
}
@ -94,8 +64,8 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
new BlockHitResult(pos, side, blockPos, false),
side.getOpposite()
));
return newState == null ? BlockTypesCache.ReservedIDs.AIR :
adapter.ibdIDToOrdinal(Block.BLOCK_STATE_REGISTRY.getId(newState));
return newState == null ? BlockTypesCache.ReservedIDs.AIR : adapter.ibdIDToOrdinal(Block.BLOCK_STATE_REGISTRY.getId(
newState));
}
@Override
@ -104,19 +74,12 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
if (child == getExtent()) {
return this;
}
return new PaperweightPlacementStateProcessor(child, mask, secondPass, includeUnedited);
return new PaperweightPlacementStateProcessor(child, mask, region);
}
@Override
public PlacementStateProcessor fork() {
return new PaperweightPlacementStateProcessor(
extent,
mask,
secondPass,
includeUnedited,
crossChunkSecondPasses,
proxyLevel
);
return new PaperweightPlacementStateProcessor(extent, mask, postCompleteSecondPasses, threadProcessors, region, finished);
}
}

Datei anzeigen

@ -4,7 +4,7 @@ import com.fastasyncworldedit.bukkit.adapter.FaweAdapter;
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
import com.fastasyncworldedit.core.FaweCache;
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.queue.IBatchProcessor;
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.util.Direction;
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.nbt.BinaryTag;
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) {
return Block.stateById(ordinalToIbdID[blockState.getOrdinal()]);
return Block.stateById(getOrdinalToIbdID()[blockState.getOrdinal()]);
}
@Override
@ -484,7 +483,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
@Override
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(
getServerLevel(world),
new BlockPos(blockVector3.getX(), blockVector3.getY(), blockVector3.getZ())
@ -615,13 +614,8 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
}
@Override
public PlacementStateProcessor getPlatformPlacementProcessor(
Extent extent,
BlockTypeMask mask,
boolean secondPass,
boolean includeUnedited
) {
return new PaperweightPlacementStateProcessor(extent, mask, secondPass, includeUnedited);
public PlacementStateProcessor getPlatformPlacementProcessor(Extent extent, BlockTypeMask mask, Region region) {
return new PaperweightPlacementStateProcessor(extent, mask, region);
}
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.util.LogManagerCompat;
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.BiomeTypes;
import com.sk89q.worldedit.world.block.BlockTypesCache;
import io.papermc.lib.PaperLib;
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.server.level.ServerLevel;
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.BlockEntity;
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.lighting.LevelLightEngine;
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 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.ConcurrentHashMap;
import java.util.concurrent.Future;
@ -807,7 +829,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
nmsChunk.mustNotSave = false;
nmsChunk.setUnsaved(true);
// 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);
}
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.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.extent.Extent;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.FluidTags;
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.state.BlockState;
import net.minecraft.world.level.material.FluidState;
@ -20,17 +20,15 @@ import javax.annotation.Nullable;
public class PaperweightLevelProxy extends ServerLevel {
private PaperweightFaweAdapter adapter;
private Extent extent;
private ServerLevel serverLevel;
private boolean enabled = false;
private PaperweightPlacementStateProcessor processor;
@SuppressWarnings("DataFlowIssue")
public PaperweightLevelProxy() {
private PaperweightLevelProxy() {
super(null, null, null, null, null, null, null, true, 0L, null, true, null, null, null, null);
throw new IllegalStateException("Cannot be instantiated");
}
public static PaperweightLevelProxy getInstance(ServerLevel level, Extent extent) {
public static PaperweightLevelProxy getInstance(PaperweightPlacementStateProcessor processor) {
Unsafe unsafe = ReflectionUtils.getUnsafe();
PaperweightLevelProxy newLevel;
@ -39,45 +37,41 @@ public class PaperweightLevelProxy extends ServerLevel {
} catch (InstantiationException e) {
throw new RuntimeException(e);
}
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin
.getInstance()
.getBukkitImplAdapter());
newLevel.extent = extent;
newLevel.serverLevel = level;
newLevel.processor = processor;
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin.getInstance().getBukkitImplAdapter());
return newLevel;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@Nullable
@Override
public BlockEntity getBlockEntity(@Nonnull BlockPos blockPos) {
if (!enabled) {
if (blockPos.getY() == Integer.MAX_VALUE) {
return null;
}
BlockEntity tileEntity = this.serverLevel.getChunkAt(blockPos).getBlockEntity(blockPos);
if (tileEntity == null) {
com.sk89q.jnbt.CompoundTag tag = processor.getTileAt(blockPos.getX(), blockPos.getY(), blockPos.getZ());
if (tag == null) {
return null;
}
BlockEntity newEntity = tileEntity.getType().create(blockPos, getBlockState(blockPos));
newEntity.load((CompoundTag) adapter.fromNativeBinary(this.extent.getFullBlock(
blockPos.getX(),
blockPos.getY(),
blockPos.getZ()
).getNbtReference().getValue()));
return newEntity;
BlockState state = adapter.adapt(processor.getBlockStateAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
if (!(state.getBlock() instanceof EntityBlock entityBlock)) {
return null;
}
BlockEntity tileEntity = entityBlock.newBlockEntity(blockPos, state);
tileEntity.load((CompoundTag) adapter.fromNative(tag));
return tileEntity;
}
@Override
@Nonnull
public BlockState getBlockState(@Nonnull BlockPos blockPos) {
if (!enabled) {
if (blockPos.getY() == Integer.MAX_VALUE) {
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);
}
@ -85,7 +79,7 @@ public class PaperweightLevelProxy extends ServerLevel {
@Override
@Nonnull
public FluidState getFluidState(@Nonnull BlockPos pos) {
if (!enabled) {
if (pos.getY() == Integer.MAX_VALUE) {
return Fluids.EMPTY.defaultFluidState();
}
return getBlockState(pos).getFluidState();
@ -94,7 +88,7 @@ public class PaperweightLevelProxy extends ServerLevel {
@SuppressWarnings("unused")
@Override
public boolean isWaterAt(@Nonnull BlockPos pos) {
if (!enabled) {
if (pos.getY() == Integer.MAX_VALUE) {
return false;
}
return getBlockState(pos).getFluidState().is(FluidTags.WATER);

Datei anzeigen

@ -1,28 +1,23 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R3;
import com.fastasyncworldedit.core.extent.processor.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.fastasyncworldedit.core.extent.PlacementStateProcessor;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.BlockTypeMask;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.Region;
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.BlockTypesCache;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import org.bukkit.craftbukkit.v1_20_R3.CraftWorld;
import javax.annotation.Nullable;
import java.util.Queue;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
public class PaperweightPlacementStateProcessor extends PlacementStateProcessor {
@ -32,59 +27,28 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
private final FaweMutableBlockPlaceContext mutableBlockPlaceContext;
private final PaperweightLevelProxy proxyLevel;
public PaperweightPlacementStateProcessor(
final Extent extent,
final BlockTypeMask mask,
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
);
public PaperweightPlacementStateProcessor(Extent extent, BlockTypeMask mask, Region region) {
super(extent, mask, region);
this.proxyLevel = PaperweightLevelProxy.getInstance(this);
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
}
private PaperweightPlacementStateProcessor(
Extent extent,
BlockTypeMask mask,
boolean secondPass,
boolean includeUnedited,
Queue<IntTriple> crossChunkSecondPasses,
PaperweightLevelProxy proxyLevel
Map<SecondPass, Character> crossChunkSecondPasses,
ThreadLocal<PlacementStateProcessor> threadProcessors,
Region region,
AtomicBoolean finished
) {
super(extent, mask, secondPass, includeUnedited, crossChunkSecondPasses);
this.proxyLevel = proxyLevel;
super(extent, mask, crossChunkSecondPasses, threadProcessors, region, finished);
this.proxyLevel = PaperweightLevelProxy.getInstance(this);
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
}
@Override
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();
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),
side.getOpposite()
));
return newState == null ? BlockTypesCache.ReservedIDs.AIR :
adapter.ibdIDToOrdinal(Block.BLOCK_STATE_REGISTRY.getId(newState));
return newState == null ? BlockTypesCache.ReservedIDs.AIR : adapter.ibdIDToOrdinal(Block.BLOCK_STATE_REGISTRY.getId(
newState));
}
@Override
@ -104,19 +68,12 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
if (child == getExtent()) {
return this;
}
return new PaperweightPlacementStateProcessor(child, mask, secondPass, includeUnedited);
return new PaperweightPlacementStateProcessor(child, mask, region);
}
@Override
public PlacementStateProcessor fork() {
return new PaperweightPlacementStateProcessor(
extent,
mask,
secondPass,
includeUnedited,
crossChunkSecondPasses,
proxyLevel
);
return new PaperweightPlacementStateProcessor(extent, mask, postCompleteSecondPasses, threadProcessors, region, finished);
}
}

Datei anzeigen

@ -4,7 +4,7 @@ import com.fastasyncworldedit.bukkit.adapter.FaweAdapter;
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
import com.fastasyncworldedit.core.FaweCache;
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.queue.IBatchProcessor;
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) {
return Block.stateById(ordinalToIbdID[blockState.getOrdinal()]);
return Block.stateById(getOrdinalToIbdID()[blockState.getOrdinal()]);
}
@Override
@ -638,13 +638,8 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
}
@Override
public PlacementStateProcessor getPlatformPlacementProcessor(
Extent extent,
BlockTypeMask mask,
boolean secondPass,
boolean includeUnedited
) {
return new PaperweightPlacementStateProcessor(extent, mask, secondPass, includeUnedited);
public PlacementStateProcessor getPlatformPlacementProcessor(Extent extent, BlockTypeMask mask, Region region) {
return new PaperweightPlacementStateProcessor(extent, mask, region);
}
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.util.LogManagerCompat;
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.BiomeTypes;
import com.sk89q.worldedit.world.block.BlockTypesCache;
import io.papermc.lib.PaperLib;
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.server.dedicated.DedicatedServer;
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.BlockEntity;
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.lighting.LevelLightEngine;
import org.apache.logging.log4j.Logger;
@ -53,7 +65,17 @@ import org.bukkit.craftbukkit.block.CraftBlock;
import org.bukkit.event.entity.CreatureSpawnEvent;
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.ConcurrentHashMap;
import java.util.concurrent.Future;
@ -809,7 +831,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
nmsChunk.mustNotSave = false;
nmsChunk.setUnsaved(true);
// 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);
}
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.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.extent.Extent;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.FluidTags;
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.state.BlockState;
import net.minecraft.world.level.material.FluidState;
@ -19,17 +19,17 @@ import javax.annotation.Nullable;
public class PaperweightLevelProxy extends ServerLevel {
protected ServerLevel serverLevel;
private PaperweightPlacementStateProcessor processor;
private PaperweightFaweAdapter adapter;
private Extent extent;
private ServerLevel serverLevel;
@SuppressWarnings("DataFlowIssue")
public PaperweightLevelProxy() {
private PaperweightLevelProxy() {
super(null, null, null, null, null, null, null, true, 0L, null, true, null, null, null, null);
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();
PaperweightLevelProxy newLevel;
@ -38,11 +38,9 @@ public class PaperweightLevelProxy extends ServerLevel {
} catch (InstantiationException e) {
throw new RuntimeException(e);
}
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin
.getInstance()
.getBukkitImplAdapter());
newLevel.extent = extent;
newLevel.serverLevel = level;
newLevel.processor = processor;
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin.getInstance().getBukkitImplAdapter());
newLevel.serverLevel = serverLevel;
return newLevel;
}
@ -52,21 +50,17 @@ public class PaperweightLevelProxy extends ServerLevel {
if (blockPos.getX() == Integer.MAX_VALUE) {
return null;
}
BlockEntity tileEntity = this.serverLevel.getChunkAt(blockPos).getBlockEntity(blockPos);
if (tileEntity == null) {
com.sk89q.jnbt.CompoundTag tag = processor.getTileAt(blockPos.getX(), blockPos.getY(), blockPos.getZ());
if (tag == null) {
return null;
}
BlockEntity newEntity = tileEntity.getType().create(blockPos, getBlockState(blockPos));
newEntity.loadWithComponents(
(CompoundTag) adapter.fromNativeBinary(this.extent.getFullBlock(
blockPos.getX(),
blockPos.getY(),
blockPos.getZ()
).getNbtReference().getValue()),
this.serverLevel.registryAccess()
);
return newEntity;
BlockState state = adapter.adapt(processor.getBlockStateAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
if (!(state.getBlock() instanceof EntityBlock entityBlock)) {
return null;
}
BlockEntity tileEntity = entityBlock.newBlockEntity(blockPos, state);
tileEntity.loadWithComponents((CompoundTag) adapter.fromNative(tag), serverLevel.registryAccess());
return tileEntity;
}
@Override
@ -75,7 +69,7 @@ public class PaperweightLevelProxy extends ServerLevel {
if (blockPos.getX() == Integer.MAX_VALUE) {
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.getY(),
blockPos.getZ()

Datei anzeigen

@ -1,28 +1,29 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
import com.fastasyncworldedit.core.extent.processor.PlacementStateProcessor;
import com.fastasyncworldedit.core.math.IntTriple;
import com.fastasyncworldedit.core.extent.PlacementStateProcessor;
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.extent.Extent;
import com.sk89q.worldedit.function.mask.BlockTypeMask;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.Region;
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.BlockTypesCache;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import org.bukkit.craftbukkit.CraftWorld;
import javax.annotation.Nullable;
import java.util.Queue;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
public class PaperweightPlacementStateProcessor extends PlacementStateProcessor {
@ -32,20 +33,12 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
private final PaperweightLevelProxy proxyLevel;
private final FaweMutableBlockPlaceContext mutableBlockPlaceContext;
public PaperweightPlacementStateProcessor(
Extent extent,
BlockTypeMask mask,
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.");
public PaperweightPlacementStateProcessor(Extent extent, BlockTypeMask mask, Region region) {
super(extent, mask, region);
World world = ExtentTraverser.getWorldFromExtent(extent);
if (world == null) {
throw new UnsupportedOperationException(
"World is required for PlacementStateProcessor but none found in given extent.");
}
BukkitWorld bukkitWorld;
if (world instanceof WorldWrapper wrapper) {
@ -53,34 +46,40 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
} else {
bukkitWorld = (BukkitWorld) world;
}
this.proxyLevel = PaperweightLevelProxy.getInstance(((CraftWorld) bukkitWorld.getWorld()).getHandle(),
extent
);
this.proxyLevel = PaperweightLevelProxy.getInstance(((CraftWorld) bukkitWorld.getWorld()).getHandle(), this);
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
}
private PaperweightPlacementStateProcessor(
Extent extent,
BlockTypeMask mask,
boolean secondPass,
boolean includeUnedited,
Queue<IntTriple> crossChunkSecondPasses,
PaperweightLevelProxy proxyLevel
Map<SecondPass, Character> crossChunkSecondPasses,
ServerLevel serverLevel,
ThreadLocal<PlacementStateProcessor> threadProcessors,
Region region,
AtomicBoolean finished
) {
super(extent, mask, secondPass, includeUnedited, crossChunkSecondPasses);
this.proxyLevel = proxyLevel;
super(extent, mask, crossChunkSecondPasses, threadProcessors, region, finished);
this.proxyLevel = PaperweightLevelProxy.getInstance(serverLevel, this);
this.mutableBlockPlaceContext = new FaweMutableBlockPlaceContext(proxyLevel);
}
@Override
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();
Vec3 pos = new Vec3(clickPos.x(), clickPos.y(), clickPos.z());
net.minecraft.core.Direction side = net.minecraft.core.Direction.valueOf(clickedFaceDirection.toString());
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()
));
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()) {
return this;
}
return new PaperweightPlacementStateProcessor(child, mask, secondPass, includeUnedited);
return new PaperweightPlacementStateProcessor(child, mask, region);
}
@Override
@ -101,10 +100,11 @@ public class PaperweightPlacementStateProcessor extends PlacementStateProcessor
return new PaperweightPlacementStateProcessor(
extent,
mask,
secondPass,
includeUnedited,
crossChunkSecondPasses,
proxyLevel
postCompleteSecondPasses,
proxyLevel.serverLevel,
threadProcessors,
region,
finished
);
}

Datei anzeigen

@ -21,7 +21,7 @@ package com.sk89q.worldedit.bukkit;
import com.fastasyncworldedit.bukkit.util.MinecraftVersion;
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.queue.IBatchProcessor;
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.function.mask.BlockTypeMask;
import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.SideEffect;
import com.sk89q.worldedit.util.lifecycle.Lifecycled;
import com.sk89q.worldedit.world.DataFixer;
@ -314,13 +315,8 @@ public class BukkitServerInterface extends AbstractPlatform implements MultiUser
}
@Override
public PlacementStateProcessor getPlatformPlacementProcessor(
Extent extent,
BlockTypeMask mask,
boolean secondPass,
boolean includeUnedited
) {
return this.plugin.getBukkitImplAdapter().getPlatformPlacementProcessor(extent, mask, secondPass, includeUnedited);
public PlacementStateProcessor getPlatformPlacementProcessor(Extent extent, BlockTypeMask mask, Region region) {
return this.plugin.getBukkitImplAdapter().getPlatformPlacementProcessor(extent, mask, region);
}
//FAWE end
}

Datei anzeigen

@ -23,7 +23,7 @@ import com.fastasyncworldedit.bukkit.FaweBukkit;
import com.fastasyncworldedit.bukkit.adapter.IBukkitAdapter;
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
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.queue.IBatchProcessor;
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.
* @since TODO
*/
default PlacementStateProcessor getPlatformPlacementProcessor(
Extent extent,
BlockTypeMask mask,
boolean secondPass,
boolean includeUnedited
) {
default PlacementStateProcessor getPlatformPlacementProcessor(Extent extent, BlockTypeMask mask, Region region) {
return null;
}
//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.regions.Region;
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.world.World;
import org.apache.logging.log4j.Logger;
@ -352,8 +354,12 @@ public class FaweAPI {
if (unwrapped instanceof IQueueExtent) {
queue = (IQueueExtent) unwrapped;
} else if (Settings.settings().QUEUE.PARALLEL_THREADS > 1) {
ParallelQueueExtent parallel =
new ParallelQueueExtent(Fawe.instance().getQueueHandler(), world, true);
ParallelQueueExtent parallel = new ParallelQueueExtent(
Fawe.instance().getQueueHandler(),
world,
true,
SideEffectSet.none().with(SideEffect.LIGHTING, SideEffect.State.ON)
);
queue = parallel.getExtent();
} else {
queue = Fawe.instance().getQueueHandler().getQueue(world);

Datei anzeigen

@ -784,11 +784,6 @@ public class Settings extends Config {
})
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.clipboard.Clipboard;
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.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
@ -215,12 +214,6 @@ public class PassthroughExtent extends AbstractDelegateExtent {
return getExtent().setBiome(position, biome);
}
@Override
@Nullable
public Operation commit() {
return getExtent().commit();
}
@Override
public boolean 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.math.IntPair;
import com.fastasyncworldedit.core.math.IntTriple;
import com.fastasyncworldedit.core.extent.processor.ProcessorScope;
import com.fastasyncworldedit.core.function.mask.AdjacentAny2DMask;
import com.fastasyncworldedit.core.math.BlockVector3ChunkMap;
import com.fastasyncworldedit.core.math.MutableBlockVector3;
import com.fastasyncworldedit.core.math.MutableVector3;
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.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.Direction;
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.BlockTypesCache;
import java.util.ArrayDeque;
import java.util.EnumSet;
import java.util.Queue;
import java.util.Map;
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;
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 int CHUNK_BLOCK_POS_MASK = -1 << 4;
private static volatile boolean SETUP = false;
private static BlockTypeMask DEFAULT_MASK = null;
private static BlockTypeMask SECOND_MASK = null;
private static BlockTypeMask REQUIRES_SECOND_PASS = null;
private static AdjacentAny2DMask ADJACENT_STAIR_MASK = null;
protected final Extent extent;
protected final BlockTypeMask mask;
protected final boolean includeUnedited;
protected final boolean secondPass;
protected final Queue<IntTriple> crossChunkSecondPasses;
protected final Region region;
protected final Map<SecondPass, Character> postCompleteSecondPasses;
protected final ThreadLocal<PlacementStateProcessor> threadProcessors;
protected final AtomicBoolean finished;
private final MutableVector3 clickPos = new MutableVector3();
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
*
* @param extent Extent to use
* @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
*/
public PlacementStateProcessor(Extent extent, BlockTypeMask mask, boolean secondPass, boolean includeUnedited) {
public PlacementStateProcessor(Extent extent, BlockTypeMask mask, Region region) {
super(extent);
// 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.
@ -73,24 +81,27 @@ public abstract class PlacementStateProcessor extends AbstractDelegateExtent imp
}
this.extent = extent;
this.mask = mask == null ? DEFAULT_MASK : mask;
this.secondPass = secondPass;
this.includeUnedited = includeUnedited;
this.crossChunkSecondPasses = secondPass ? null : new ConcurrentLinkedQueue<>();
this.region = region;
this.postCompleteSecondPasses = new ConcurrentHashMap<>();
this.threadProcessors = ThreadLocal.withInitial(this::fork);
this.finished = new AtomicBoolean();
}
protected PlacementStateProcessor(
Extent extent,
BlockTypeMask mask,
boolean secondPass,
boolean includeUnedited,
Queue<IntTriple> crossChunkSecondPasses
Map<SecondPass, Character> crossChunkSecondPasses,
ThreadLocal<PlacementStateProcessor> threadProcessors,
Region region,
AtomicBoolean finished
) {
super(extent);
this.extent = extent;
this.mask = mask;
this.secondPass = secondPass;
this.includeUnedited = includeUnedited;
this.crossChunkSecondPasses = crossChunkSecondPasses;
this.region = region;
this.postCompleteSecondPasses = crossChunkSecondPasses;
this.threadProcessors = threadProcessors;
this.finished = finished;
}
private static void setup() {
@ -121,12 +132,7 @@ public abstract class PlacementStateProcessor extends AbstractDelegateExtent imp
BlockTypes.VINE,
BlockTypes.REDSTONE_WIRE
);
BlockCategory[] categories = new BlockCategory[]{
BlockCategories.FENCES,
BlockCategories.FENCE_GATES,
BlockCategories.WALLS,
BlockCategories.CAVE_VINES
};
BlockCategory[] categories = new BlockCategory[]{BlockCategories.FENCES, BlockCategories.FENCE_GATES, BlockCategories.WALLS, BlockCategories.CAVE_VINES};
for (BlockCategory category : categories) {
if (category != null) {
REQUIRES_SECOND_PASS.add(category.getAll());
@ -148,145 +154,129 @@ public abstract class PlacementStateProcessor extends AbstractDelegateExtent imp
BlockTypes.BROWN_MUSHROOM_BLOCK,
BlockTypes.RED_MUSHROOM_BLOCK
);
categories = new BlockCategory[]{
BlockCategories.STAIRS,
BlockCategories.BAMBOO_BLOCKS,
BlockCategories.TALL_FLOWERS
};
categories = new BlockCategory[]{BlockCategories.STAIRS, BlockCategories.BAMBOO_BLOCKS, BlockCategories.TALL_FLOWERS};
for (BlockCategory category : categories) {
if (category != null) {
DEFAULT_MASK.add(category.getAll());
}
}
SECOND_MASK = new BlockTypeMask(new NullExtent());
SECOND_MASK.add(BlockCategories.STAIRS.getAll());
BlockTypeMask stairs = new BlockTypeMask(new NullExtent(), BlockCategories.STAIRS.getAll());
ADJACENT_STAIR_MASK = new AdjacentAny2DMask(stairs, false);
SETUP = true;
}
@Override
public IChunkSet processSet(IChunk iChunk, IChunkGet iChunkGet, IChunkSet iChunkSet) {
int chunkX = iChunk.getX() << 4;
int chunkZ = iChunk.getZ() << 4;
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;
public IChunkSet processSet(IChunk iChunk, IChunkGet chunkGet, IChunkSet chunkSet) {
if (finished.get()) {
return chunkSet;
}
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(
IChunkGet iChunkGet,
IChunkSet iChunkSet,
char[] get,
char[] set,
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;
private void initProcess(IChunk iChunk, IChunkGet chunkGet, IChunkSet chunkSet) {
this.processChunkX = iChunk.getX() << 4;
this.processChunkZ = iChunk.getZ() << 4;
this.processChunkGet = chunkGet;
this.processChunkSet = chunkSet;
}
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];
if (secondPasses == null && secondPass) {
if (!REQUIRES_SECOND_PASS.test(state.getBlockType())) {
return;
if (firstPass && !BlockCategories.STAIRS.contains(state)) {
continue;
}
if (!mask.test(state)) {
continue;
}
if (!mask.test(state.getBlockType())) {
return;
if (!firstPass && REQUIRES_SECOND_PASS.test(state)) {
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);
if (newOrdinal == ordinal) {
return;
}
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);
continue;
}
set[index] = newOrdinal;
}
}
}
@Override
public ProcessorScope getScope() {
return ProcessorScope.CHANGING_BLOCKS;
}
@Override
public void finish() {
flush();
}
@Override
public void flush() {
IntTriple coords;
while ((coords = crossChunkSecondPasses.poll()) != null) {
BlockState state = extent.getBlock(coords.x(), coords.y(), coords.z());
char ordinal = state.getOrdinalChar();
if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) {
finished.set(true);
for (Map.Entry<SecondPass, Character> entry : postCompleteSecondPasses.entrySet()) {
BlockState state;
char ordinal = entry.getValue();
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;
}
if (!mask.test(state.getBlockType())) {
continue;
if (secondPass.tile != null) {
extent.setTile(secondPass.x, secondPass.y, secondPass.z, secondPass.tile);
}
char newOrdinal = getBlockOrdinal(coords.x(), coords.y(), coords.z(), state);
if (newOrdinal == ordinal) {
continue;
}
extent.setBlock(coords.x(), coords.y(), coords.z(), BlockTypesCache.states[newOrdinal]);
extent.setBlock(secondPass.x, secondPass.y, secondPass.z, BlockTypesCache.states[newOrdinal]);
}
postCompleteSecondPasses.clear();
}
@Override
public abstract PlacementStateProcessor fork();
// Require block type to avoid duplicate lookup
protected abstract char getStateAtFor(
int x,
int y,
@ -297,6 +287,55 @@ public abstract class PlacementStateProcessor extends AbstractDelegateExtent imp
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) {
EnumSet<Direction> dirs = Direction.getDirections(state);
Direction clickedFaceDirection = null; // This should be always be set by the below.
@ -339,10 +378,16 @@ public abstract class PlacementStateProcessor extends AbstractDelegateExtent imp
@Override
public void applyBlock(FilterBlock block) {
BlockState state = BlockTypesCache.states[block.getOrdinal()];
if (!mask.test(state.getBlockType())) {
if (finished.get()) {
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 newOrdinal = getBlockOrdinal(block.x(), block.y(), block.z(), block.getBlock());
if (ordinal != newOrdinal) {
@ -356,13 +401,17 @@ public abstract class PlacementStateProcessor extends AbstractDelegateExtent imp
orDefault = extent;
}
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;
}
char newOrdinal = getBlockOrdinal(set.x(), set.y(), set.z(), block.toBlockState());
if (block.getOrdinalChar() != newOrdinal) {
BlockState newState = BlockTypesCache.states[newOrdinal];
orDefault.setBlock(set, newState);
orDefault.setBlock(set.x(), set.y(), set.z(), newState);
CompoundBinaryTag nbt = block.getNbt();
if (nbt != null && newState.getBlockType() == block.getBlockType()) {
orDefault.setTile(set.x(), set.y(), set.z(), (CompoundTag) nbt.asBinaryTag());
@ -373,9 +422,16 @@ public abstract class PlacementStateProcessor extends AbstractDelegateExtent imp
}
@Override
public BaseBlock applyBlock(final BlockVector3 position) {
public BaseBlock applyBlock(BlockVector3 position) {
if (finished.get()) {
return null;
}
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;
}
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];
CompoundBinaryTag nbt = block.getNbt();
if (nbt != null && state.getBlockType() == block.getBlockType()) {
return state.toBaseBlock(nbt);
state.toBaseBlock(nbt);
}
return state.toBaseBlock();
}
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
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);
}
@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) {
this.mask = CachedMask.cache(mask);
this.mask = mask;
mutable = new MutableBlockVector3();
this.minY = minY;
this.maxY = maxY;

Datei anzeigen

@ -436,7 +436,6 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet {
} catch (EOFException ignored) {
} catch (Exception e) {
e.printStackTrace();
e.printStackTrace();
}
try {
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 javax.annotation.Nullable;
import java.io.Flushable;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.function.Function;
public interface IBatchProcessor extends Flushable {
public interface IBatchProcessor {
/**
* 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.function.operation.Operation;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockStateHolder;
@ -127,4 +128,19 @@ public interface IChunkSet extends IBlocks, OutputExtent {
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;
}
@Override
default void finish() {
getParent().finish();
}
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.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.SideEffectSet;
import javax.annotation.Nullable;
import java.io.Flushable;
@ -78,6 +79,20 @@ public interface IQueueExtent<T extends IChunk> extends Flushable, Trimable, ICh
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
* 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.IQueueExtent;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.mask.BlockMask;
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
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.Pattern;
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.regions.Region;
import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BaseBlock;
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 org.apache.logging.log4j.Logger;
import java.io.Flushable;
import javax.annotation.Nullable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@ -57,11 +61,12 @@ public class ParallelQueueExtent extends PassthroughExtent {
// not very important)
private final boolean[] faweExceptionReasonsUsed = new boolean[FaweException.Type.values().length];
private final boolean fastmode;
private final SideEffectSet sideEffectSet;
private int changes;
private int lastException = Integer.MIN_VALUE;
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()));
this.world = world;
this.handler = handler;
@ -74,6 +79,7 @@ public class ParallelQueueExtent extends PassthroughExtent {
((MultiBatchProcessor) this.postProcessor.getProcessor()).setFaweExceptionArray(faweExceptionReasonsUsed);
}
this.fastmode = fastmode;
this.sideEffectSet = sideEffectSet == null ? SideEffectSet.defaults() : sideEffectSet;
}
/**
@ -120,7 +126,12 @@ public class ParallelQueueExtent extends PassthroughExtent {
@SuppressWarnings("rawtypes")
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
@ -138,19 +149,17 @@ public class ParallelQueueExtent extends PassthroughExtent {
BlockVector2 pos = chunksIter.next();
getExtent().apply(null, filter, region, pos.x(), pos.z(), full);
}
getExtent().flush();
filter.finish();
} else {
final ForkJoinTask[] tasks = IntStream.range(0, size).mapToObj(i -> handler.submit(() -> {
try {
final Filter newFilter = filter.fork();
// Create a chunk that we will reuse/reset for each operation
final SingleThreadQueueExtent queue = (SingleThreadQueueExtent) getNewQueue();
queue.setFastMode(fastmode);
queue.setFaweExceptionArray(faweExceptionReasonsUsed);
enter(queue);
synchronized (queue) {
try {
ChunkFilterBlock block = null;
while (true) {
// Get the next chunk posWeakChunk
final int chunkX;
@ -165,10 +174,8 @@ public class ParallelQueueExtent extends PassthroughExtent {
}
block = queue.apply(block, newFilter, region, chunkX, chunkZ, full);
}
if (newFilter instanceof Flushable flushable) {
flushable.flush();
}
queue.flush();
filter.finish();
} catch (Throwable t) {
if (t instanceof FaweException) {
Fawe.handleFaweException(faweExceptionReasonsUsed, (FaweException) t, LOGGER);
@ -205,6 +212,24 @@ public class ParallelQueueExtent extends PassthroughExtent {
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
public int countBlocks(Region region, Mask searchMask) {
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.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.world.World;
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
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 int lastException = Integer.MIN_VALUE;
private int exceptionCount = 0;
private SideEffectSet sideEffectSet = SideEffectSet.defaults();
public SingleThreadQueueExtent() {
}
@ -110,6 +112,16 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
this.fastmode = fastmode;
}
@Override
public void setSideEffectSet(SideEffectSet sideEffectSet) {
this.sideEffectSet = sideEffectSet;
}
@Override
public SideEffectSet getSideEffectSet() {
return sideEffectSet;
}
@Override
public int getMinY() {
return minY;
@ -120,6 +132,10 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
return maxY;
}
public World getWorld() {
return world;
}
/**
* 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
@ -278,10 +294,16 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
private ChunkHolder poolOrCreate(int chunkX, int chunkZ) {
ChunkHolder next = create(false);
next.init(this, chunkX, chunkZ);
next.setFastMode(isFastMode());
return next;
}
@Override
public IQueueChunk wrap(IQueueChunk chunk) {
chunk.setFastMode(isFastMode());
chunk.setSideEffectSet(getSideEffectSet());
return chunk;
}
@Override
public final IQueueChunk getOrCreateChunk(int x, int z) {
getChunkLock.lock();

Datei anzeigen

@ -6,6 +6,7 @@ import com.fastasyncworldedit.core.queue.IChunkSet;
import com.fastasyncworldedit.core.util.collection.MemBlockSet;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
@ -211,6 +212,16 @@ public class BitSetBlocks implements IChunkSet {
return false;
}
@Override
public void setSideEffectSet(SideEffectSet sideEffectSet) {
}
@Override
public SideEffectSet getSideEffectSet() {
return SideEffectSet.none();
}
@Override
public int getSectionCount() {
return layers;

Datei anzeigen

@ -9,6 +9,7 @@ import com.fastasyncworldedit.core.queue.Pool;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypesCache;
@ -42,6 +43,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
public EnumMap<HeightMapType, int[]> heightMaps;
private boolean fastMode = false;
private int bitMask = -1;
private SideEffectSet sideEffectSet = SideEffectSet.defaults();
private CharSetBlocks() {
// Expand as we go
@ -372,10 +374,21 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
heightMaps != null ? new EnumMap<>(heightMaps) : null,
defaultOrdinal(),
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) {
if (lightArr == null) {
return null;

Datei anzeigen

@ -9,6 +9,7 @@ import com.fastasyncworldedit.core.queue.IChunkSet;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
@ -50,6 +51,7 @@ public class ThreadUnsafeCharBlocks implements IChunkSet, IBlocks {
private Map<HeightMapType, int[]> heightMaps;
private boolean fastMode;
private int bitMask;
private SideEffectSet sideEffectSet;
/**
* 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,
char defaultOrdinal,
boolean fastMode,
int bitMask
int bitMask,
SideEffectSet sideEffectSet
) {
this.blocks = blocks;
this.minSectionPosition = minSectionPosition;
@ -86,6 +89,7 @@ public class ThreadUnsafeCharBlocks implements IChunkSet, IBlocks {
this.defaultOrdinal = defaultOrdinal;
this.fastMode = fastMode;
this.bitMask = bitMask;
this.sideEffectSet = sideEffectSet;
}
@Override
@ -479,10 +483,21 @@ public class ThreadUnsafeCharBlocks implements IChunkSet, IBlocks {
heightMaps != null ? new HashMap<>(heightMaps) : null,
defaultOrdinal,
fastMode,
bitMask
bitMask,
sideEffectSet
);
}
@Override
public void setSideEffectSet(SideEffectSet sideEffectSet) {
this.sideEffectSet = sideEffectSet;
}
@Override
public SideEffectSet getSideEffectSet() {
return sideEffectSet;
}
@Override
public boolean trim(boolean aggressive) {
return false;

Datei anzeigen

@ -15,6 +15,7 @@ import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
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 createCopy = false;
private long initTime = -1L;
private SideEffectSet sideEffectSet;
private ChunkHolder() {
this.delegate = NULL;
@ -159,6 +161,16 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
return chunkSet != null && chunkSet.hasBiomes(layer);
}
@Override
public void setSideEffectSet(SideEffectSet sideEffectSet) {
this.sideEffectSet = sideEffectSet;
}
@Override
public SideEffectSet getSideEffectSet() {
return sideEffectSet;
}
public boolean 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) {
final IChunkGet get = getOrCreateGet();
final IChunkSet set = getOrCreateSet();
set.setFastMode(fastmode);
try {
block.filter(this, get, set, filter, region, full);
} finally {
@ -967,13 +978,21 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
return chunkSet;
}
public final IChunkSet getChunkSet() {
return chunkSet;
}
/**
* Create a wrapped set object
* - The purpose of wrapping is to allow different extents to intercept / alter behavior
* - e.g., caching, optimizations, filtering
*/
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
public synchronized T call() {
if (chunkSet != null && !chunkSet.isEmpty()) {
chunkSet.setBitMask(bitMask);
IChunkSet copy = chunkSet.createCopy();
return this.call(copy, () -> {
// Do nothing

Datei anzeigen

@ -8,6 +8,7 @@ import com.fastasyncworldedit.core.queue.IQueueChunk;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
@ -87,6 +88,16 @@ public final class NullChunk implements IQueueChunk {
return false;
}
@Override
public void setSideEffectSet(SideEffectSet sideEffectSet) {
}
@Override
public SideEffectSet getSideEffectSet() {
return SideEffectSet.none();
}
@Nonnull
public int[] getHeightMap(@Nullable HeightMapType type) {
return new int[256];

Datei anzeigen

@ -1,7 +1,11 @@
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.Extent;
import com.sk89q.worldedit.world.World;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -21,6 +25,26 @@ public class ExtentTraverser<T extends Extent> {
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() {
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.internal.util.LogManagerCompat;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionIntersection;
import com.sk89q.worldedit.util.Identifiable;
import com.sk89q.worldedit.util.SideEffect;
import com.sk89q.worldedit.util.SideEffectSet;
@ -484,7 +485,12 @@ public final class EditSessionBuilder {
if (unwrapped instanceof IQueueExtent) {
extent = queue = (IQueueExtent) unwrapped;
} 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();
extent = parallel;
} 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
if (placeChunks) {
if (this.sideEffectSet.shouldApply(SideEffect.LIGHTING) &&
((relightMode != null && relightMode != RelightMode.NONE) || (relightMode == null && Settings.settings().LIGHTING.MODE > 0))) {
if (this.sideEffectSet.shouldApply(SideEffect.LIGHTING) || (relightMode != null && relightMode != RelightMode.NONE)) {
relighter = WorldEdit
.getInstance()
.getPlatformManager()
@ -573,17 +578,16 @@ public final class EditSessionBuilder {
if (this.sideEffectSet.shouldApply(SideEffect.HEIGHTMAPS)) {
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
.getInstance()
.getPlatformManager()
.queryCapability(Capability.WORLD_EDITING)
.getPlatformPlacementProcessor(
queue,
null,
Settings.settings().GENERAL.PERFORM_SECOND_UPDATE_PASS,
true
));
.getPlatformPlacementProcessor(extent, null, region));
}
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.function.GroundFunction;
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.Mask;
import com.sk89q.worldedit.function.mask.MaskIntersection;
@ -904,9 +903,7 @@ public class RegionCommands {
@Confirm(Confirm.Processor.REGION)
@Preload(Preload.PreloadCheck.PRELOAD)
public int fixblocks(
Actor actor, EditSession editSession, @Selection Region region,
@Switch(name = 'n', desc = "Do not perform a second pass ")
boolean noSecondPass
Actor actor, EditSession editSession, @Selection Region region
) {
int affected = editSession.setBlocks(
region,
@ -914,7 +911,7 @@ public class RegionCommands {
.getInstance()
.getPlatformManager()
.queryCapability(Capability.WORLD_EDITING)
.getPlatformPlacementProcessor(editSession, null, !noSecondPass, true)
.getPlatformPlacementProcessor(editSession, null, region)
);
if (affected != 0) {
actor.print(Caption.of("worldedit.set.done", TextComponent.of(affected)));

Datei anzeigen

@ -19,16 +19,16 @@
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.RelighterFactory;
import com.fastasyncworldedit.core.queue.IBatchProcessor;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.BlockTypeMask;
import com.sk89q.worldedit.internal.util.NonAbstractForCompatibility;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.registry.Keyed;
import com.sk89q.worldedit.util.SideEffect;
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
*/
default PlacementStateProcessor getPlatformPlacementProcessor(
Extent extent,
BlockTypeMask mask,
boolean secondPass,
boolean includeUnedited
) {
default PlacementStateProcessor getPlatformPlacementProcessor(Extent extent, BlockTypeMask mask, @Nullable Region region) {
return null;
}
//FAWE end

Datei anzeigen

@ -21,6 +21,7 @@ package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.extent.Extent;
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.BlockTypes;
@ -140,6 +141,10 @@ public class BlockTypeMask extends AbstractExtentMask {
public boolean test(BlockType block) {
return types[block.getInternalId()];
}
public <B extends BlockStateHolder<B>> boolean test(B blockStateHolder) {
return types[blockStateHolder.getBlockType().getInternalId()];
}
//FAWE end
@Nullable

Datei anzeigen

@ -27,7 +27,7 @@ public enum SideEffect {
//FAWE start - adjust defaults, add history and heightmaps
HISTORY(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),
UPDATE(State.OFF, true),
//FAWE end