From 05afaf00a912d0bf4c0eb0b54c2e73321f96bf84 Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Sat, 22 Apr 2023 00:21:50 +0200 Subject: [PATCH] Address incompatibilities after CraftChunk changes in spigot (#2179) --- .../adapters/adapter-1_19_4/build.gradle.kts | 2 +- .../fawe/v1_19_R3/PaperweightFaweAdapter.java | 48 ------------------- .../PaperweightFaweWorldNativeAccess.java | 2 +- .../v1_19_R3/PaperweightPlatformAdapter.java | 33 +++++++++++-- .../fawe/v1_19_R3/regen/PaperweightRegen.java | 7 ++- 5 files changed, 37 insertions(+), 55 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_19_4/build.gradle.kts index 8fb3980de..4d1c1ada5 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_19_4/build.gradle.kts @@ -9,6 +9,6 @@ repositories { } dependencies { - paperDevBundle("1.19.4-R0.1-20230331.112431-38") + paperDevBundle("1.19.4-R0.1-20230412.010331-64") compileOnly("io.papermc:paperlib") } diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java index 5edcb8618..e23e18a2e 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java @@ -306,54 +306,6 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements return SideEffectSet.defaults().getSideEffectsToApply(); } - public boolean setBlock(org.bukkit.Chunk chunk, int x, int y, int z, BlockStateHolder state, boolean update) { - CraftChunk craftChunk = (CraftChunk) chunk; - LevelChunk levelChunk = craftChunk.getHandle(); - Level level = levelChunk.getLevel(); - - BlockPos blockPos = new BlockPos(x, y, z); - net.minecraft.world.level.block.state.BlockState blockState = ((PaperweightBlockMaterial) state.getMaterial()).getState(); - LevelChunkSection[] levelChunkSections = levelChunk.getSections(); - int y4 = y >> 4; - LevelChunkSection section = levelChunkSections[y4]; - - net.minecraft.world.level.block.state.BlockState existing; - if (section == null) { - existing = ((PaperweightBlockMaterial) BlockTypes.AIR.getDefaultState().getMaterial()).getState(); - } else { - existing = section.getBlockState(x & 15, y & 15, z & 15); - } - - levelChunk.removeBlockEntity(blockPos); // Force delete the old tile entity - - CompoundBinaryTag compoundTag = state instanceof BaseBlock ? state.getNbt() : null; - if (compoundTag != null || existing instanceof TileEntityBlock) { - level.setBlock(blockPos, blockState, 0); - // remove tile - if (compoundTag != null) { - // We will assume that the tile entity was created for us, - // though we do not do this on the Forge version - BlockEntity blockEntity = level.getBlockEntity(blockPos); - if (blockEntity != null) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) fromNativeBinary(compoundTag); - tag.put("x", IntTag.valueOf(x)); - tag.put("y", IntTag.valueOf(y)); - tag.put("z", IntTag.valueOf(z)); - blockEntity.load(tag); // readTagIntoTileEntity - load data - } - } - } else { - if (existing == blockState) { - return true; - } - levelChunk.setBlockState(blockPos, blockState, false); - } - if (update) { - level.getMinecraftWorld().sendBlockUpdated(blockPos, existing, blockState, 0); - } - return true; - } - @Override public WorldNativeAccess createWorldNativeAccess(org.bukkit.World world) { return new PaperweightFaweWorldNativeAccess( diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweWorldNativeAccess.java index 4dead58fa..dbe0150a9 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweWorldNativeAccess.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweWorldNativeAccess.java @@ -102,7 +102,7 @@ public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess currentTick; if (nextTick || cachedChanges.size() >= 1024) { if (nextTick) { diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java index 115246ce3..33be73c69 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java @@ -41,6 +41,8 @@ import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.GlobalPalette; import net.minecraft.world.level.chunk.HashMapPalette; import net.minecraft.world.level.chunk.LevelChunk; @@ -57,6 +59,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -74,6 +77,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.Semaphore; import java.util.function.Function; +import static java.lang.invoke.MethodType.methodType; import static net.minecraft.core.registries.Registries.BIOME; public final class PaperweightPlatformAdapter extends NMSAdapter { @@ -103,6 +107,12 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { private static final MethodHandle methodRemoveGameEventListener; private static final MethodHandle methodremoveTickingBlockEntity; + /* + * This is a workaround for the changes from https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/commits/1fddefce1cdce44010927b888432bf70c0e88cde#src/main/java/org/bukkit/craftbukkit/CraftChunk.java + * and is only needed to support 1.19.4 versions before *and* after this change. + */ + private static final MethodHandle CRAFT_CHUNK_GET_HANDLE; + private static final Field fieldRemove; static final boolean POST_CHUNK_REWRITE; @@ -111,6 +121,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { private static Field SERVER_LEVEL_ENTITY_MANAGER; static { + final MethodHandles.Lookup lookup = MethodHandles.lookup(); try { fieldData = PalettedContainer.class.getDeclaredField(Refraction.pickName("data", "d")); fieldData.setAccessible(true); @@ -136,7 +147,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { "b" ), long.class); getVisibleChunkIfPresent.setAccessible(true); - methodGetVisibleChunk = MethodHandles.lookup().unreflect(getVisibleChunkIfPresent); + methodGetVisibleChunk = lookup.unreflect(getVisibleChunkIfPresent); Unsafe unsafe = ReflectionUtils.getUnsafe(); if (!PaperLib.isPaper()) { @@ -160,7 +171,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { ServerLevel.class ); removeGameEventListener.setAccessible(true); - methodRemoveGameEventListener = MethodHandles.lookup().unreflect(removeGameEventListener); + methodRemoveGameEventListener = lookup.unreflect(removeGameEventListener); Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod( Refraction.pickName( @@ -169,7 +180,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { ), BlockPos.class ); removeBlockEntityTicker.setAccessible(true); - methodremoveTickingBlockEntity = MethodHandles.lookup().unreflect(removeBlockEntityTicker); + methodremoveTickingBlockEntity = lookup.unreflect(removeBlockEntityTicker); fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "p")); fieldRemove.setAccessible(true); @@ -208,6 +219,20 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { rethrow.printStackTrace(); throw new RuntimeException(rethrow); } + MethodHandle craftChunkGetHandle; + final MethodType type = methodType(ChunkAccess.class); + try { + craftChunkGetHandle = lookup.findVirtual(CraftChunk.class, "getHandle", type); + } catch (NoSuchMethodException | IllegalAccessException e) { + try { + final MethodType newType = methodType(ChunkAccess.class, ChunkStatus.class); + craftChunkGetHandle = lookup.findVirtual(CraftChunk.class, "getHandle", newType); + craftChunkGetHandle = MethodHandles.insertArguments(craftChunkGetHandle, 1, ChunkStatus.FULL); + } catch (NoSuchMethodException | IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } + CRAFT_CHUNK_GET_HANDLE = craftChunkGetHandle; } static boolean setSectionAtomic( @@ -280,7 +305,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { CompletableFuture future = serverLevel.getWorld().getChunkAtAsync(chunkX, chunkZ, true, true); try { CraftChunk chunk = (CraftChunk) future.get(); - return chunk.getHandle(); + return (LevelChunk) CRAFT_CHUNK_GET_HANDLE.invoke(chunk); } catch (Throwable e) { e.printStackTrace(); } diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/regen/PaperweightRegen.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/regen/PaperweightRegen.java index 282baeb21..4f22e8734 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/regen/PaperweightRegen.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/regen/PaperweightRegen.java @@ -60,6 +60,7 @@ import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; +import org.bukkit.Chunk; import org.bukkit.craftbukkit.v1_19_R3.CraftServer; import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; import org.bukkit.craftbukkit.v1_19_R3.generator.CustomChunkGenerator; @@ -440,7 +441,11 @@ public class PaperweightRegen extends Regenerator blockPopulator.populate(freshWorld.getWorld(), random, levelChunk.getBukkitChunk())); + TaskManager.taskManager().task(() -> { + final CraftWorld world = freshWorld.getWorld(); + final Chunk chunk = world.getChunkAt(levelChunk.locX, levelChunk.locZ); + blockPopulator.populate(world, random, chunk); + }); } @Override