3
0
Mirror von https://github.com/IntellectualSites/FastAsyncWorldEdit.git synchronisiert 2024-07-05 18:28:03 +02:00
Dieser Commit ist enthalten in:
dordsor21 2024-06-30 09:59:43 +01:00
Ursprung 45a9a557af
Commit 609dd009b4
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 1E53E88969FFCF0B
7 geänderte Dateien mit 623 neuen und 9 gelöschten Zeilen

Datei anzeigen

@ -886,12 +886,12 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
}
private static final Set<SideEffect> SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet(
SideEffect.NEIGHBORS,
//FAWE start - FAWE-supported side effects
SideEffect.HISTORY,
SideEffect.HEIGHTMAPS,
SideEffect.LIGHTING,
SideEffect.VALIDATION,
SideEffect.ENTITY_AI,
SideEffect.EVENTS,
SideEffect.UPDATE
SideEffect.NEIGHBORS
//FAWE end
);
@Override

Datei anzeigen

@ -0,0 +1,240 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_21_R1;
import com.fastasyncworldedit.core.internal.exception.FaweException;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.adapter.Refraction;
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1.PaperweightFaweAdapter;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.world.block.BlockTypes;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.FluidTags;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.phys.AABB;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
public class PaperweightServerLevelDelegateProxy implements InvocationHandler {
private static final Logger LOGGER = LogManagerCompat.getLogger();
// FAWE start - extent not EditSession
private final Extent editSession;
//FAWE end
private final ServerLevel serverLevel;
//FAWE start - use FAWE adapter
private final PaperweightFaweAdapter adapter = ((PaperweightFaweAdapter) WorldEditPlugin
.getInstance()
.getBukkitImplAdapter());
//FAWE end
//FAWE start - force error if method not caught by this instance
private final boolean errorOnPassthrough;
//FAWE end
private PaperweightServerLevelDelegateProxy(EditSession editSession, ServerLevel serverLevel, PaperweightAdapter adapter) {
this.editSession = editSession;
this.serverLevel = serverLevel;
//FAWE start
this.errorOnPassthrough = false;
//FAWE end
}
public static WorldGenLevel newInstance(EditSession editSession, ServerLevel serverLevel, PaperweightAdapter adapter) {
return (WorldGenLevel) Proxy.newProxyInstance(
serverLevel.getClass().getClassLoader(),
serverLevel.getClass().getInterfaces(),
new PaperweightServerLevelDelegateProxy(editSession, serverLevel, adapter)
);
}
//FAWE start - force error if method not caught by this instance
private PaperweightServerLevelDelegateProxy(Extent extent, ServerLevel serverLevel, boolean errorOnPassthrough) {
this.editSession = extent;
this.serverLevel = serverLevel;
this.errorOnPassthrough = errorOnPassthrough;
}
public static WorldGenLevel newInstance(Extent extent, ServerLevel serverLevel, boolean errorOnPassthrough) {
return (WorldGenLevel) Proxy.newProxyInstance(
serverLevel.getClass().getClassLoader(),
serverLevel.getClass().getInterfaces(),
new PaperweightServerLevelDelegateProxy(extent, serverLevel, errorOnPassthrough)
);
}
//FAWE end
@Nullable
private BlockEntity getBlockEntity(BlockPos blockPos) {
BlockEntity tileEntity = this.serverLevel.getChunkAt(blockPos).getBlockEntity(blockPos);
if (tileEntity == null) {
return null;
}
BlockEntity newEntity = tileEntity.getType().create(blockPos, getBlockState(blockPos));
newEntity.loadWithComponents(
(CompoundTag) adapter.fromNativeLin(this.editSession.getFullBlock(
blockPos.getX(),
blockPos.getY(),
blockPos.getZ()
).getNbtReference().getValue()),
this.serverLevel.registryAccess()
);
return newEntity;
}
private BlockState getBlockState(BlockPos blockPos) {
return adapter.adapt(this.editSession.getBlock(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
}
private boolean setBlock(BlockPos blockPos, BlockState blockState) {
try {
return editSession.setBlock(blockPos.getX(), blockPos.getY(), blockPos.getZ(), adapter.adapt(blockState));
} catch (MaxChangedBlocksException e) {
throw new RuntimeException(e);
}
}
private boolean removeBlock(BlockPos blockPos, boolean bl) {
try {
return editSession.setBlock(blockPos.getX(), blockPos.getY(), blockPos.getZ(), BlockTypes.AIR.getDefaultState());
} catch (MaxChangedBlocksException e) {
throw new RuntimeException(e);
}
}
private FluidState getFluidState(BlockPos pos) {
return getBlockState(pos).getFluidState();
}
private boolean isWaterAt(BlockPos pos) {
return getBlockState(pos).getFluidState().is(FluidTags.WATER);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//FAWE start - cannot use switch where method names are equal
String methodName = method.getName();
if (Refraction.pickName("getBlockState", "a_").equals(methodName)) {
if (args.length == 1 && args[0] instanceof BlockPos blockPos) {
// getBlockState
return getBlockState(blockPos);
}
}
if (Refraction.pickName("getBlockEntity", "c_").equals(methodName)) {
if (args.length == 1 && args[0] instanceof BlockPos blockPos) {
// getBlockEntity
return getBlockEntity(blockPos);
}
}
if ("a".equals(methodName) || "setBlock".equals(methodName) || "removeBlock".equals(methodName) || "destroyBlock".equals(
methodName)) {
if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof BlockState blockState) {
// setBlock
return setBlock(blockPos, blockState);
} else if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof Boolean bl) {
// removeBlock (and also matches destroyBlock)
return removeBlock(blockPos, bl);
}
}
//FAWE start
if (Refraction.pickName("getFluidState", "b_").equals(methodName)) { //net.minecraft.world.level.BlockGetter
if (args.length == 1 && args[0] instanceof BlockPos blockPos) {
return getFluidState(blockPos);
}
}
if (Refraction.pickName("isWaterAt", "z").equals(methodName)) { //net.minecraft.world.level.LevelReader
if (args.length == 1 && args[0] instanceof BlockPos blockPos) {
return isWaterAt(blockPos);
}
}
if (Refraction.pickName("getEntities", "a_").equals(methodName)) { //net.minecraft.world.level.EntityGetter
if (args.length == 2 && args[0] instanceof Entity && args[1] instanceof AABB) {
return new ArrayList<>();
}
}
// Specific passthroughs that we want to allow
// net.minecraft.world.level.BlockAndTintGetter
if (Refraction.pickName("getRawBrightness", "b").equals(methodName)) {
return method.invoke(this.serverLevel, args);
}
// net.minecraft.world.level.LevelHeightAccessor
if (Refraction.pickName("getMaxBuildHeight", "al").equals(methodName)) {
if (args.length == 0) {
return method.invoke(this.serverLevel, args);
}
}
// net.minecraft.world.level.SignalGetter
if (Refraction.pickName("hasNeighborSignal", "C").equals(methodName)) {
if (args.length == 1 && args[0] instanceof BlockPos) {
return method.invoke(this.serverLevel, args);
}
}
if (Refraction.pickName("getSignal", "c").equals(methodName)) {
if (args.length == 2 && args[0] instanceof BlockPos && args[1] instanceof Direction) {
return method.invoke(this.serverLevel, args);
}
}
if (Refraction.pickName("getControlInputSignal", "a").equals(methodName)) {
if (args.length == 3 && args[0] instanceof BlockPos && args[1] instanceof Direction && args[2] instanceof Boolean) {
return method.invoke(this.serverLevel, args);
}
}
if (Refraction.pickName("getDirectSignal", "a").equals(methodName)) {
if (args.length == 2 && args[0] instanceof BlockPos && args[1] instanceof Direction) {
return method.invoke(this.serverLevel, args);
}
}
//FAWE start - force error if method not caught by this instance
if (errorOnPassthrough) {
LOGGER.error(
"""
Attempted passthough of method {}.
Method argument types: {}
Method argument values: {}
""",
method.getName(),
Arrays.stream(args).map(a -> a.getClass().getName()).toList(),
Arrays.stream(args).map(Object::toString).toList()
);
throw new FaweException("Method required passthrough.");
}
//FAWE end
return method.invoke(this.serverLevel, args);
}
}

Datei anzeigen

@ -4,6 +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.processor.lighting.RelighterFactory;
import com.fastasyncworldedit.core.queue.IBatchProcessor;
import com.fastasyncworldedit.core.queue.IChunkGet;
@ -12,6 +13,7 @@ import com.fastasyncworldedit.core.util.NbtUtils;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import com.mojang.serialization.Codec;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.blocks.BaseItemStack;
@ -21,6 +23,7 @@ import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1.nbt.PaperweightLazy
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1.regen.PaperweightRegen;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.BlockTypeMask;
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.internal.wna.WorldNativeAccess;
@ -293,9 +296,16 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
return state.toBaseBlock();
}
private static final Set<SideEffect> SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet(
SideEffect.HISTORY,
SideEffect.HEIGHTMAPS,
SideEffect.LIGHTING,
SideEffect.NEIGHBORS
);
@Override
public Set<SideEffect> getSupportedSideEffects() {
return SideEffectSet.defaults().getSideEffectsToApply();
return SUPPORTED_SIDE_EFFECTS;
}
@Override
@ -443,6 +453,10 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
return material.getCraftBlockData();
}
public net.minecraft.world.level.block.state.BlockState adapt(BlockState blockState) {
return Block.stateById(getOrdinalToIbdID()[blockState.getOrdinal()]);
}
@Override
public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket chunkPacket) {
ServerLevel nmsWorld = getServerLevel(world);
@ -624,6 +638,11 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
return new PaperweightPostProcessor();
}
@Override
public PlacementStateProcessor getPlatformPlacementProcessor(Extent extent, BlockTypeMask mask, Region region) {
return new PaperweightPlacementStateProcessor(extent, mask, region);
}
private boolean wasAccessibleSinceLastSave(ChunkHolder holder) {
if (!PaperLib.isPaper() || !PaperweightPlatformAdapter.POST_CHUNK_REWRITE) {
try {

Datei anzeigen

@ -0,0 +1,143 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class PaperweightFaweMutableBlockPlaceContext extends BlockPlaceContext {
private static final BlockHitResult DEFAULT_BLOCK_HIT = new BlockHitResult(
new Vec3(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE),
Direction.NORTH,
new BlockPos(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE),
false
);
private final ServerLevel level;
private BlockHitResult hitResult = null;
private Direction direction = null;
private BlockPos relativePos;
@SuppressWarnings("DataFlowIssue")
public PaperweightFaweMutableBlockPlaceContext(ServerLevel level) {
super(
level,
null,
null,
null,
DEFAULT_BLOCK_HIT
);
this.level = level;
this.replaceClicked = false;
}
public PaperweightFaweMutableBlockPlaceContext withSetting(BlockHitResult hitResult, Direction direction) {
this.hitResult = hitResult;
this.direction = direction;
this.relativePos = hitResult.getBlockPos().relative(hitResult.getDirection());
return this;
}
@Override
@Nonnull
public BlockPos getClickedPos() {
return this.relativePos;
}
@Override
@Nonnull
public Direction getClickedFace() {
return this.hitResult.getDirection();
}
@Override
@Nonnull
public Vec3 getClickLocation() {
return this.hitResult.getLocation();
}
@Override
public boolean isInside() {
return this.hitResult.isInside();
}
@Override
@SuppressWarnings("NullableProblems")
public ItemStack getItemInHand() {
return ItemStack.EMPTY;
}
@Nullable
@Override
public Player getPlayer() {
return null;
}
@Override
@SuppressWarnings("NullableProblems")
public InteractionHand getHand() {
return null;
}
@Override
@Nonnull
public Level getLevel() {
return this.level;
}
@Override
@Nonnull
public Direction getHorizontalDirection() {
return this.direction.getAxis() == Direction.Axis.Y ? Direction.NORTH : this.direction;
}
@Override
public boolean isSecondaryUseActive() {
return false;
}
@Override
public float getRotation() {
return (float) (this.direction.get2DDataValue() * 90);
}
@Override
public boolean canPlace() {
return this.getLevel().getBlockState(this.getClickedPos()).canBeReplaced(this);
}
@Override
public boolean replacingClickedOnBlock() {
return false;
}
@Override
@Nonnull
public Direction getNearestLookingDirection() {
return direction;
}
@Override
@Nonnull
public Direction getNearestLookingVerticalDirection() {
return direction.getAxis() == Direction.Axis.Y ? Direction.UP : Direction.DOWN;
}
@Override
@Nonnull
public Direction[] getNearestLookingDirections() {
return new Direction[]{direction};
}
}

Datei anzeigen

@ -24,6 +24,7 @@ import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_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;
@ -816,15 +817,16 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
if (bitMask == 0 && biomes == null && !lightUpdate) {
callback = null;
} else {
int finalMask = bitMask != 0 ? bitMask : lightUpdate ? set.getBitMask() : 0;
boolean finalLightUpdate = lightUpdate;
final int finalBitMask = bitMask;
callback = () -> {
// Set Modified
nmsChunk.setLightCorrect(true); // Set Modified
nmsChunk.mustNotSave = false;
nmsChunk.setUnsaved(true);
// send to player
if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalMask == 0 && biomes != null) {
if (!set
.getSideEffectSet()
.shouldApply(SideEffect.LIGHTING) || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalBitMask == 0 && biomes != null) {
this.send();
}
if (finalizer != null) {

Datei anzeigen

@ -0,0 +1,99 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1;
import com.fastasyncworldedit.core.util.ReflectionUtils;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
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;
import net.minecraft.world.level.material.Fluids;
import sun.misc.Unsafe;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class PaperweightLevelProxy extends ServerLevel {
protected ServerLevel serverLevel;
private PaperweightPlacementStateProcessor processor;
private PaperweightFaweAdapter adapter;
@SuppressWarnings("DataFlowIssue")
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 serverLevel, PaperweightPlacementStateProcessor processor) {
Unsafe unsafe = ReflectionUtils.getUnsafe();
PaperweightLevelProxy newLevel;
try {
newLevel = (PaperweightLevelProxy) unsafe.allocateInstance(PaperweightLevelProxy.class);
} catch (InstantiationException e) {
throw new RuntimeException(e);
}
newLevel.processor = processor;
newLevel.adapter = ((PaperweightFaweAdapter) WorldEditPlugin.getInstance().getBukkitImplAdapter());
newLevel.serverLevel = serverLevel;
return newLevel;
}
@Nullable
@Override
public BlockEntity getBlockEntity(@Nonnull BlockPos blockPos) {
if (blockPos.getX() == Integer.MAX_VALUE) {
return null;
}
com.sk89q.jnbt.CompoundTag tag = processor.getTileAt(blockPos.getX(), blockPos.getY(), blockPos.getZ());
if (tag == null) {
return null;
}
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
@Nonnull
public BlockState getBlockState(@Nonnull BlockPos blockPos) {
if (blockPos.getX() == Integer.MAX_VALUE) {
return Blocks.AIR.defaultBlockState();
}
com.sk89q.worldedit.world.block.BlockState state = processor.getBlockStateAt(
blockPos.getX(),
blockPos.getY(),
blockPos.getZ()
);
return adapter.adapt(state);
}
@SuppressWarnings("unused")
@Override
@Nonnull
public FluidState getFluidState(@Nonnull BlockPos pos) {
if (pos.getX() == Integer.MAX_VALUE) {
return Fluids.EMPTY.defaultFluidState();
}
return getBlockState(pos).getFluidState();
}
@SuppressWarnings("unused")
@Override
public boolean isWaterAt(@Nonnull BlockPos pos) {
if (pos.getX() == Integer.MAX_VALUE) {
return false;
}
return getBlockState(pos).getFluidState().is(FluidTags.WATER);
}
}

Datei anzeigen

@ -0,0 +1,111 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1;
import com.fastasyncworldedit.core.extent.processor.PlacementStateProcessor;
import com.fastasyncworldedit.core.util.ExtentTraverser;
import com.fastasyncworldedit.core.wrappers.WorldWrapper;
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.Map;
import java.util.concurrent.atomic.AtomicBoolean;
public class PaperweightPlacementStateProcessor extends PlacementStateProcessor {
private final PaperweightFaweAdapter adapter = ((PaperweightFaweAdapter) WorldEditPlugin
.getInstance()
.getBukkitImplAdapter());
private final PaperweightLevelProxy proxyLevel;
private final PaperweightFaweMutableBlockPlaceContext mutableBlockPlaceContext;
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) {
bukkitWorld = (BukkitWorld) wrapper.getParent();
} else {
bukkitWorld = (BukkitWorld) world;
}
this.proxyLevel = PaperweightLevelProxy.getInstance(((CraftWorld) bukkitWorld.getWorld()).getHandle(), this);
this.mutableBlockPlaceContext = new PaperweightFaweMutableBlockPlaceContext(proxyLevel);
}
private PaperweightPlacementStateProcessor(
Extent extent,
BlockTypeMask mask,
Map<SecondPass, Character> crossChunkSecondPasses,
ServerLevel serverLevel,
ThreadLocal<PlacementStateProcessor> threadProcessors,
Region region,
AtomicBoolean finished
) {
super(extent, mask, crossChunkSecondPasses, threadProcessors, region, finished);
this.proxyLevel = PaperweightLevelProxy.getInstance(serverLevel, this);
this.mutableBlockPlaceContext = new PaperweightFaweMutableBlockPlaceContext(proxyLevel);
}
@Override
protected char getStateAtFor(
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),
side.getOpposite()
));
return newState == null ? BlockTypesCache.ReservedIDs.AIR : adapter.ibdIDToOrdinal(Block.BLOCK_STATE_REGISTRY.getId(
newState));
}
@Override
@Nullable
public Extent construct(Extent child) {
if (child == getExtent()) {
return this;
}
return new PaperweightPlacementStateProcessor(child, mask, region);
}
@Override
public PlacementStateProcessor fork() {
return new PaperweightPlacementStateProcessor(
extent,
mask,
postCompleteSecondPasses,
proxyLevel.serverLevel,
threadProcessors,
region,
finished
);
}
}