mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-06-12 04:23:54 +00:00
Cherry-pick WNA, minor changes. 1.16 VERY WIP
First noticed incident of operations ruining ChunkSections. Do not build and use this unless you're testing. Rushed some of the changes, gotta sleep. Would be nice to get a review of this one from @mattbdev and @dordsor21
This commit is contained in:
@ -7,8 +7,8 @@ applyShadowConfiguration()
|
||||
apply(plugin = "fabric-loom")
|
||||
|
||||
val minecraftVersion = "1.15.2"
|
||||
val yarnMappings = "1.15.2+build.8:v2"
|
||||
val loaderVersion = "0.7.6+build.180"
|
||||
val yarnMappings = "1.15.2+build.14:v2"
|
||||
val loaderVersion = "0.7.8+build.189"
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy {
|
||||
|
@ -25,6 +25,7 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.fabric.internal.NBTConverter;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.registry.state.BooleanProperty;
|
||||
|
@ -36,9 +36,10 @@ import com.mojang.datafixers.DataFixerBuilder;
|
||||
import com.mojang.datafixers.Dynamic;
|
||||
import com.mojang.datafixers.schemas.Schema;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import net.minecraft.datafixers.NbtOps;
|
||||
import net.minecraft.datafixers.Schemas;
|
||||
import net.minecraft.datafixers.TypeReferences;
|
||||
import com.sk89q.worldedit.fabric.internal.NBTConverter;
|
||||
import net.minecraft.datafixer.NbtOps;
|
||||
import net.minecraft.datafixer.Schemas;
|
||||
import net.minecraft.datafixer.TypeReferences;
|
||||
import net.minecraft.nbt.FloatTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
|
@ -25,6 +25,7 @@ import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.entity.metadata.EntityProperties;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.fabric.internal.NBTConverter;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.NullWorld;
|
||||
|
@ -202,7 +202,7 @@ class FabricPlatform extends AbstractPlatform implements MultiUserPlatform {
|
||||
}
|
||||
|
||||
private static final Set<SideEffect> SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet(
|
||||
SideEffect.CONNECTIONS,
|
||||
SideEffect.VALIDATION,
|
||||
SideEffect.ENTITY_AI,
|
||||
SideEffect.LIGHTING,
|
||||
SideEffect.NEIGHBORS
|
||||
|
@ -25,6 +25,7 @@ import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.extension.platform.AbstractPlayerActor;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.fabric.internal.NBTConverter;
|
||||
import com.sk89q.worldedit.fabric.mixin.AccessorServerPlayerEntity;
|
||||
import com.sk89q.worldedit.fabric.net.handler.WECUIPacketHandler;
|
||||
import com.sk89q.worldedit.internal.cui.CUIEvent;
|
||||
@ -42,10 +43,10 @@ import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.network.packet.BlockEntityUpdateS2CPacket;
|
||||
import net.minecraft.client.network.packet.BlockUpdateS2CPacket;
|
||||
import net.minecraft.client.network.packet.CustomPayloadS2CPacket;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
|
||||
import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket;
|
||||
import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
|
@ -34,6 +34,8 @@ import com.sk89q.worldedit.blocks.BaseItem;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.fabric.internal.FabricWorldNativeAccess;
|
||||
import com.sk89q.worldedit.fabric.internal.NBTConverter;
|
||||
import com.sk89q.worldedit.internal.Constants;
|
||||
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
@ -64,7 +66,6 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUsageContext;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.WorldGenerationProgressListener;
|
||||
import net.minecraft.server.world.ChunkHolder;
|
||||
import net.minecraft.server.world.ServerChunkManager;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.ActionResult;
|
||||
@ -129,6 +130,7 @@ public class FabricWorld extends AbstractWorld {
|
||||
private static final net.minecraft.block.BlockState JUNGLE_SHRUB = Blocks.OAK_LEAVES.getDefaultState().with(LeavesBlock.PERSISTENT, Boolean.TRUE);
|
||||
|
||||
private final WeakReference<World> worldRef;
|
||||
private final FabricWorldNativeAccess worldNativeAccess;
|
||||
|
||||
/**
|
||||
* Construct a new world.
|
||||
@ -138,6 +140,7 @@ public class FabricWorld extends AbstractWorld {
|
||||
FabricWorld(World world) {
|
||||
checkNotNull(world);
|
||||
this.worldRef = new WeakReference<>(world);
|
||||
this.worldNativeAccess = new FabricWorldNativeAccess(worldRef);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -191,98 +194,14 @@ public class FabricWorld extends AbstractWorld {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void markAndNotifyBlock(World world, BlockPos pos, @Nullable WorldChunk worldChunk, net.minecraft.block.BlockState blockState,
|
||||
net.minecraft.block.BlockState state, SideEffectSet sideEffectSet) {
|
||||
Block block = state.getBlock();
|
||||
net.minecraft.block.BlockState blockState2 = world.getBlockState(pos);
|
||||
if (blockState2 == state) {
|
||||
if (blockState != blockState2) {
|
||||
world.checkBlockRerender(pos, blockState, blockState2);
|
||||
}
|
||||
|
||||
if (world.isClient || worldChunk.getLevelType() != null && worldChunk.getLevelType().isAfter(ChunkHolder.LevelType.TICKING)) {
|
||||
if (sideEffectSet.shouldApply(SideEffect.ENTITY_AI)) {
|
||||
world.updateListeners(pos, blockState, state, UPDATE | NOTIFY);
|
||||
} else {
|
||||
// If we want to skip entity AI, just call the chunk dirty flag.
|
||||
((ServerChunkManager) world.getChunkManager()).markForUpdate(pos);
|
||||
}
|
||||
}
|
||||
|
||||
if (!world.isClient && sideEffectSet.shouldApply(SideEffect.NEIGHBORS)) {
|
||||
world.updateNeighbors(pos, blockState.getBlock());
|
||||
if (state.hasComparatorOutput()) {
|
||||
world.updateHorizontalAdjacent(pos, block);
|
||||
}
|
||||
}
|
||||
|
||||
if (sideEffectSet.shouldApply(SideEffect.CONNECTIONS)) {
|
||||
blockState.method_11637(world, pos, 2);
|
||||
state.updateNeighborStates(world, pos, 2);
|
||||
state.method_11637(world, pos, 2);
|
||||
}
|
||||
|
||||
// This is disabled for other platforms, but keep it for mods.
|
||||
world.onBlockChanged(pos, blockState, blockState2);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
|
||||
checkNotNull(position);
|
||||
checkNotNull(block);
|
||||
|
||||
World world = getWorldChecked();
|
||||
int x = position.getBlockX();
|
||||
int y = position.getBlockY();
|
||||
int z = position.getBlockZ();
|
||||
|
||||
// First set the block
|
||||
WorldChunk chunk = world.getChunk(x >> 4, z >> 4);
|
||||
BlockPos pos = new BlockPos(x, y, z);
|
||||
net.minecraft.block.BlockState old = chunk.getBlockState(pos);
|
||||
OptionalInt stateId = BlockStateIdAccess.getBlockStateId(block.toImmutableState());
|
||||
net.minecraft.block.BlockState newState = stateId.isPresent() ? Block.getStateFromRawId(stateId.getAsInt()) : FabricAdapter.adapt(block.toImmutableState());
|
||||
net.minecraft.block.BlockState successState = chunk.setBlockState(pos, newState, false);
|
||||
boolean successful = successState != null;
|
||||
|
||||
// Create the TileEntity
|
||||
if (successful || old == newState) {
|
||||
if (block instanceof BaseBlock) {
|
||||
CompoundTag tag = ((BaseBlock) block).getNbtData();
|
||||
if (tag != null) {
|
||||
net.minecraft.nbt.CompoundTag nativeTag = NBTConverter.toNative(tag);
|
||||
BlockEntity tileEntity = getWorld().getWorldChunk(pos).getBlockEntity(pos);
|
||||
if (tileEntity != null) {
|
||||
tileEntity.fromTag(nativeTag);
|
||||
tileEntity.setPos(pos);
|
||||
tileEntity.setWorld(world);
|
||||
successful = true; // update if TE changed as well
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (successful) {
|
||||
if (sideEffects.getState(SideEffect.LIGHTING) == SideEffect.State.ON) {
|
||||
world.getChunkManager().getLightingProvider().checkBlock(pos);
|
||||
}
|
||||
markAndNotifyBlock(world, pos, chunk, old, newState, sideEffects);
|
||||
}
|
||||
|
||||
return successful;
|
||||
return worldNativeAccess.setBlock(position, block, sideEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SideEffect> applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) throws WorldEditException {
|
||||
BlockPos pos = new BlockPos(position.getX(), position.getY(), position.getZ());
|
||||
net.minecraft.block.BlockState oldData = FabricAdapter.adapt(previousType);
|
||||
net.minecraft.block.BlockState newData = getWorld().getBlockState(pos);
|
||||
|
||||
if (sideEffectSet.getState(SideEffect.LIGHTING) == SideEffect.State.ON) {
|
||||
getWorld().getChunkManager().getLightingProvider().checkBlock(pos);
|
||||
}
|
||||
markAndNotifyBlock(getWorld(), pos, null, oldData, newData, sideEffectSet); // Update
|
||||
worldNativeAccess.applySideEffects(position, previousType, sideEffectSet);
|
||||
return Sets.intersection(FabricWorldEdit.inst.getPlatform().getSupportedSideEffects(), sideEffectSet.getSideEffectsToApply());
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* 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 Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.fabric.internal;
|
||||
|
||||
import com.sk89q.worldedit.fabric.FabricAdapter;
|
||||
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
|
||||
import com.sk89q.worldedit.internal.wna.WorldNativeAccess;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.world.ChunkHolder;
|
||||
import net.minecraft.server.world.ServerChunkManager;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.WorldChunk;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Objects;
|
||||
|
||||
public class FabricWorldNativeAccess implements WorldNativeAccess<WorldChunk, BlockState, BlockPos> {
|
||||
private static final int UPDATE = 1, NOTIFY = 2;
|
||||
|
||||
private final WeakReference<World> world;
|
||||
|
||||
public FabricWorldNativeAccess(WeakReference<World> world) {
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
private World getWorld() {
|
||||
return Objects.requireNonNull(world.get(), "The reference to the world was lost");
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldChunk getChunk(int x, int z) {
|
||||
return getWorld().getChunk(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState toNative(com.sk89q.worldedit.world.block.BlockState state) {
|
||||
int stateId = BlockStateIdAccess.getBlockStateId(state);
|
||||
return BlockStateIdAccess.isValidInternalId(stateId)
|
||||
? Block.getStateFromRawId(stateId)
|
||||
: FabricAdapter.adapt(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(WorldChunk chunk, BlockPos position) {
|
||||
return chunk.getBlockState(position);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockState setBlockState(WorldChunk chunk, BlockPos position, BlockState state) {
|
||||
return chunk.setBlockState(position, state, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getValidBlockForPosition(BlockState block, BlockPos position) {
|
||||
return Block.getRenderingState(block, getWorld(), position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getPosition(int x, int y, int z) {
|
||||
return new BlockPos(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLightingForBlock(BlockPos position) {
|
||||
getWorld().getChunkManager().getLightingProvider().checkBlock(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateTileEntity(BlockPos position, com.sk89q.jnbt.CompoundTag tag) {
|
||||
CompoundTag nativeTag = NBTConverter.toNative(tag);
|
||||
BlockEntity tileEntity = getWorld().getWorldChunk(position).getBlockEntity(position);
|
||||
if (tileEntity == null) {
|
||||
return false;
|
||||
}
|
||||
tileEntity.setLocation(getWorld(), position);
|
||||
tileEntity.fromTag(nativeTag);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyBlockUpdate(BlockPos position, BlockState oldState, BlockState newState) {
|
||||
getWorld().updateListeners(position, oldState, newState, UPDATE | NOTIFY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkTicking(WorldChunk chunk) {
|
||||
return chunk.getLevelType().isAfter(ChunkHolder.LevelType.TICKING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markBlockChanged(BlockPos position) {
|
||||
((ServerChunkManager) getWorld().getChunkManager()).markForUpdate(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyNeighbors(BlockPos pos, BlockState oldState, BlockState newState) {
|
||||
getWorld().updateNeighbors(pos, oldState.getBlock());
|
||||
if (newState.hasComparatorOutput()) {
|
||||
getWorld().updateHorizontalAdjacent(pos, newState.getBlock());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNeighbors(BlockPos pos, BlockState oldState, BlockState newState) {
|
||||
World world = getWorld();
|
||||
// method_11637 = updateDiagonalNeighbors
|
||||
oldState.method_11637(world, pos, NOTIFY);
|
||||
newState.updateNeighborStates(world, pos, NOTIFY);
|
||||
newState.method_11637(world, pos, NOTIFY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockStateChange(BlockPos pos, BlockState oldState, BlockState newState) {
|
||||
getWorld().onBlockChanged(pos, oldState, newState);
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.fabric;
|
||||
package com.sk89q.worldedit.fabric.internal;
|
||||
|
||||
import com.sk89q.jnbt.ByteArrayTag;
|
||||
import com.sk89q.jnbt.ByteTag;
|
||||
@ -44,7 +44,7 @@ import java.util.Set;
|
||||
/**
|
||||
* Converts between JNBT and Minecraft NBT classes.
|
||||
*/
|
||||
final class NBTConverter {
|
||||
public final class NBTConverter {
|
||||
|
||||
private NBTConverter() {
|
||||
}
|
@ -23,15 +23,9 @@ import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.fabric.FabricAdapter;
|
||||
import com.sk89q.worldedit.fabric.FabricPlayer;
|
||||
import com.sk89q.worldedit.fabric.FabricWorldEdit;
|
||||
import net.fabricmc.fabric.api.network.PacketConsumer;
|
||||
import net.fabricmc.fabric.api.network.PacketContext;
|
||||
import net.fabricmc.fabric.api.network.ServerSidePacketRegistry;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.packet.CustomPayloadS2CPacket;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.network.packet.CustomPayloadC2SPacket;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -58,4 +52,4 @@ public final class WECUIPacketHandler {
|
||||
session.describeCUI(actor);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user