Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-10-04 20:51:05 +02:00
Add for 1.21
Dieser Commit ist enthalten in:
Ursprung
45a9a557af
Commit
609dd009b4
@ -886,12 +886,12 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final Set<SideEffect> SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet(
|
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.LIGHTING,
|
||||||
SideEffect.VALIDATION,
|
SideEffect.NEIGHBORS
|
||||||
SideEffect.ENTITY_AI,
|
//FAWE end
|
||||||
SideEffect.EVENTS,
|
|
||||||
SideEffect.UPDATE
|
|
||||||
);
|
);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,6 +4,7 @@ import com.fastasyncworldedit.bukkit.adapter.FaweAdapter;
|
|||||||
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
|
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
|
||||||
import com.fastasyncworldedit.core.FaweCache;
|
import com.fastasyncworldedit.core.FaweCache;
|
||||||
import com.fastasyncworldedit.core.entity.LazyBaseEntity;
|
import com.fastasyncworldedit.core.entity.LazyBaseEntity;
|
||||||
|
import com.fastasyncworldedit.core.extent.processor.PlacementStateProcessor;
|
||||||
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
||||||
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
||||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||||
@ -12,6 +13,7 @@ import com.fastasyncworldedit.core.util.NbtUtils;
|
|||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.sk89q.jnbt.Tag;
|
import com.sk89q.jnbt.Tag;
|
||||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
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.bukkit.adapter.impl.fawe.v1_21_R1.regen.PaperweightRegen;
|
||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
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.block.BlockStateIdAccess;
|
||||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||||
import com.sk89q.worldedit.internal.wna.WorldNativeAccess;
|
import com.sk89q.worldedit.internal.wna.WorldNativeAccess;
|
||||||
@ -293,9 +296,16 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
return state.toBaseBlock();
|
return state.toBaseBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Set<SideEffect> SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet(
|
||||||
|
SideEffect.HISTORY,
|
||||||
|
SideEffect.HEIGHTMAPS,
|
||||||
|
SideEffect.LIGHTING,
|
||||||
|
SideEffect.NEIGHBORS
|
||||||
|
);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<SideEffect> getSupportedSideEffects() {
|
public Set<SideEffect> getSupportedSideEffects() {
|
||||||
return SideEffectSet.defaults().getSideEffectsToApply();
|
return SUPPORTED_SIDE_EFFECTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -443,6 +453,10 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
return material.getCraftBlockData();
|
return material.getCraftBlockData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public net.minecraft.world.level.block.state.BlockState adapt(BlockState blockState) {
|
||||||
|
return Block.stateById(getOrdinalToIbdID()[blockState.getOrdinal()]);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket chunkPacket) {
|
public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket chunkPacket) {
|
||||||
ServerLevel nmsWorld = getServerLevel(world);
|
ServerLevel nmsWorld = getServerLevel(world);
|
||||||
@ -624,6 +638,11 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
return new PaperweightPostProcessor();
|
return new PaperweightPostProcessor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlacementStateProcessor getPlatformPlacementProcessor(Extent extent, BlockTypeMask mask, Region region) {
|
||||||
|
return new PaperweightPlacementStateProcessor(extent, mask, region);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean wasAccessibleSinceLastSave(ChunkHolder holder) {
|
private boolean wasAccessibleSinceLastSave(ChunkHolder holder) {
|
||||||
if (!PaperLib.isPaper() || !PaperweightPlatformAdapter.POST_CHUNK_REWRITE) {
|
if (!PaperLib.isPaper() || !PaperweightPlatformAdapter.POST_CHUNK_REWRITE) {
|
||||||
try {
|
try {
|
||||||
|
@ -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};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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.Constants;
|
||||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
@ -816,15 +817,16 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
if (bitMask == 0 && biomes == null && !lightUpdate) {
|
if (bitMask == 0 && biomes == null && !lightUpdate) {
|
||||||
callback = null;
|
callback = null;
|
||||||
} else {
|
} else {
|
||||||
int finalMask = bitMask != 0 ? bitMask : lightUpdate ? set.getBitMask() : 0;
|
final int finalBitMask = bitMask;
|
||||||
boolean finalLightUpdate = lightUpdate;
|
|
||||||
callback = () -> {
|
callback = () -> {
|
||||||
// Set Modified
|
// Set Modified
|
||||||
nmsChunk.setLightCorrect(true); // Set Modified
|
nmsChunk.setLightCorrect(true); // Set Modified
|
||||||
nmsChunk.mustNotSave = false;
|
nmsChunk.mustNotSave = false;
|
||||||
nmsChunk.setUnsaved(true);
|
nmsChunk.setUnsaved(true);
|
||||||
// send to player
|
// send to player
|
||||||
if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalMask == 0 && biomes != null) {
|
if (!set
|
||||||
|
.getSideEffectSet()
|
||||||
|
.shouldApply(SideEffect.LIGHTING) || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalBitMask == 0 && biomes != null) {
|
||||||
this.send();
|
this.send();
|
||||||
}
|
}
|
||||||
if (finalizer != null) {
|
if (finalizer != null) {
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren