Adjust platform specific code to recent changes (#1997)

* chore: remove usage of MCUtil in StarlightRelighter

* chore: cleanup of unused imports

* hacky shit-fuckery for papers new chunksystem und refactor

* chore: address review comments

* Update dependency io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin to v1.3.9 (#2001)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix: suppress exceptions for field retrieval, cache fields / methods

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This commit is contained in:
Pierre Maurice Schwang 2022-11-02 09:41:20 +01:00 committed by GitHub
parent bbc1db9bd2
commit 2fe54a04b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 82 additions and 11 deletions

View File

@ -12,6 +12,6 @@ repositories {
} }
dependencies { dependencies {
paperDevBundle("1.19.2-R0.1-20220805.230830-1") paperDevBundle("1.19.2-R0.1-20221029.172539-134")
compileOnly("io.papermc:paperlib") compileOnly("io.papermc:paperlib")
} }

View File

@ -55,6 +55,7 @@ import com.sk89q.worldedit.world.block.BlockTypesCache;
import com.sk89q.worldedit.world.entity.EntityType; import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.registry.BlockMaterial; import com.sk89q.worldedit.world.registry.BlockMaterial;
import io.papermc.lib.PaperLib;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.core.WritableRegistry; import net.minecraft.core.WritableRegistry;
@ -97,6 +98,8 @@ import org.bukkit.entity.Player;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -114,6 +117,14 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
IDelegateBukkitImplAdapter<net.minecraft.nbt.Tag> { IDelegateBukkitImplAdapter<net.minecraft.nbt.Tag> {
private static final Logger LOGGER = LogManagerCompat.getLogger(); private static final Logger LOGGER = LogManagerCompat.getLogger();
private static Method CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE;
static {
try {
CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE = ChunkHolder.class.getDeclaredMethod("wasAccessibleSinceLastSave");
} catch (NoSuchMethodException ignored) { // may not be present in newer paper versions
}
}
private final PaperweightAdapter parent; private final PaperweightAdapter parent;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -490,7 +501,7 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket chunkPacket) { public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket chunkPacket) {
ServerLevel nmsWorld = ((CraftWorld) world).getHandle(); ServerLevel nmsWorld = ((CraftWorld) world).getHandle();
ChunkHolder map = PaperweightPlatformAdapter.getPlayerChunk(nmsWorld, chunkPacket.getChunkX(), chunkPacket.getChunkZ()); ChunkHolder map = PaperweightPlatformAdapter.getPlayerChunk(nmsWorld, chunkPacket.getChunkX(), chunkPacket.getChunkZ());
if (map != null && map.wasAccessibleSinceLastSave()) { if (map != null && wasAccessibleSinceLastSave(map)) {
boolean flag = false; boolean flag = false;
// PlayerChunk.d players = map.players; // PlayerChunk.d players = map.players;
Stream<ServerPlayer> stream = /*players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag) Stream<ServerPlayer> stream = /*players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag)
@ -674,4 +685,16 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
return new PaperweightPostProcessor(); return new PaperweightPostProcessor();
} }
private boolean wasAccessibleSinceLastSave(ChunkHolder holder) {
if (!PaperLib.isPaper() || !PaperweightPlatformAdapter.POST_CHUNK_REWRITE) {
try {
return (boolean) CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE.invoke(holder);
} catch (IllegalAccessException | InvocationTargetException ignored) {
// fall-through
}
}
// Papers new chunk system has no related replacement - therefor we assume true.
return true;
}
} }

View File

@ -14,7 +14,6 @@ import com.fastasyncworldedit.core.queue.implementation.blocks.CharGetBlocks;
import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.MathMan;
import com.fastasyncworldedit.core.util.collection.AdaptedMap; import com.fastasyncworldedit.core.util.collection.AdaptedMap;
import com.google.common.base.Suppliers; import com.google.common.base.Suppliers;
import com.google.common.collect.Iterables;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.StringTag;
@ -82,7 +81,6 @@ import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBlocks { public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBlocks {

View File

@ -1,5 +1,6 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R1; package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R1;
import com.destroystokyo.paper.util.maplist.EntityList;
import com.fastasyncworldedit.bukkit.adapter.CachedBukkitAdapter; import com.fastasyncworldedit.bukkit.adapter.CachedBukkitAdapter;
import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore; import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore;
import com.fastasyncworldedit.bukkit.adapter.NMSAdapter; import com.fastasyncworldedit.bukkit.adapter.NMSAdapter;
@ -18,18 +19,18 @@ import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypesCache; import com.sk89q.worldedit.world.block.BlockTypesCache;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import io.papermc.paper.world.ChunkEntitySlices;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
import net.minecraft.core.IdMap; import net.minecraft.core.IdMap;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.core.SectionPos;
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ChunkHolder;
import net.minecraft.server.level.ChunkMap; import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.BitStorage; import net.minecraft.util.BitStorage;
import net.minecraft.util.ExceptionCollector;
import net.minecraft.util.SimpleBitStorage; import net.minecraft.util.SimpleBitStorage;
import net.minecraft.util.ThreadingDetector; import net.minecraft.util.ThreadingDetector;
import net.minecraft.util.ZeroBitStorage; import net.minecraft.util.ZeroBitStorage;
@ -49,6 +50,7 @@ import net.minecraft.world.level.chunk.LinearPalette;
import net.minecraft.world.level.chunk.Palette; import net.minecraft.world.level.chunk.Palette;
import net.minecraft.world.level.chunk.PalettedContainer; import net.minecraft.world.level.chunk.PalettedContainer;
import net.minecraft.world.level.chunk.SingleValuePalette; import net.minecraft.world.level.chunk.SingleValuePalette;
import net.minecraft.world.level.entity.PersistentEntitySectionManager;
import net.minecraft.world.level.gameevent.GameEventDispatcher; import net.minecraft.world.level.gameevent.GameEventDispatcher;
import net.minecraft.world.level.gameevent.GameEventListener; import net.minecraft.world.level.gameevent.GameEventListener;
import org.bukkit.craftbukkit.v1_19_R1.CraftChunk; import org.bukkit.craftbukkit.v1_19_R1.CraftChunk;
@ -106,6 +108,11 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
private static final Field fieldRemove; private static final Field fieldRemove;
static final boolean POST_CHUNK_REWRITE;
private static Method PAPER_CHUNK_GEN_ALL_ENTITIES;
private static Field LEVEL_CHUNK_ENTITIES;
private static Field SERVER_LEVEL_ENTITY_MANAGER;
static { static {
try { try {
fieldData = PalettedContainer.class.getDeclaredField(Refraction.pickName("data", "d")); fieldData = PalettedContainer.class.getDeclaredField(Refraction.pickName("data", "d"));
@ -176,6 +183,27 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
throw new Error("data type scale not a power of two"); throw new Error("data type scale not a power of two");
} }
CHUNKSECTION_SHIFT = 31 - Integer.numberOfLeadingZeros(scale); CHUNKSECTION_SHIFT = 31 - Integer.numberOfLeadingZeros(scale);
boolean chunkRewrite;
try {
ServerLevel.class.getDeclaredMethod("getEntityLookup");
chunkRewrite = true;
PAPER_CHUNK_GEN_ALL_ENTITIES = ChunkEntitySlices.class.getDeclaredMethod("getAllEntities");
} catch (NoSuchMethodException ignored) {
chunkRewrite = false;
}
try {
// Paper - Pre-Chunk-Update
LEVEL_CHUNK_ENTITIES = LevelChunk.class.getDeclaredField("entities");
LEVEL_CHUNK_ENTITIES.setAccessible(true);
} catch (NoSuchFieldException ignored) {
}
try {
// Non-Paper
SERVER_LEVEL_ENTITY_MANAGER = ServerLevel.class.getDeclaredField("entityManager");
LEVEL_CHUNK_ENTITIES.setAccessible(true);
} catch (NoSuchFieldException ignored) {
}
POST_CHUNK_REWRITE = chunkRewrite;
} catch (RuntimeException e) { } catch (RuntimeException e) {
throw e; throw e;
} catch (Throwable rethrow) { } catch (Throwable rethrow) {
@ -590,10 +618,32 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
} }
static List<Entity> getEntities(LevelChunk chunk) { static List<Entity> getEntities(LevelChunk chunk) {
ExceptionCollector<RuntimeException> collector = new ExceptionCollector<>();
if (PaperLib.isPaper()) { if (PaperLib.isPaper()) {
return Arrays.asList(chunk.entities.getRawData()); if (POST_CHUNK_REWRITE) {
try {
//noinspection unchecked
return (List<Entity>) PAPER_CHUNK_GEN_ALL_ENTITIES.invoke(chunk.level.getEntityLookup().getChunk(chunk.locX, chunk.locZ));
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=true]", e);
} }
return chunk.level.entityManager.getEntities(chunk.getPos()); }
try {
EntityList entityList = (EntityList) LEVEL_CHUNK_ENTITIES.get(chunk);
return List.of(entityList.getRawData());
} catch (IllegalAccessException e) {
collector.add(new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=false]", e));
// fall through
}
}
try {
//noinspection unchecked
return ((PersistentEntitySectionManager<Entity>) (SERVER_LEVEL_ENTITY_MANAGER.get(chunk.level))).getEntities(chunk.getPos());
} catch (IllegalAccessException e) {
collector.add(new RuntimeException("Failed to lookup entities [PAPER=false]", e));
}
collector.throwIfPresent();
return List.of();
} }
record FakeIdMapBlock(int size) implements IdMap<net.minecraft.world.level.block.state.BlockState> { record FakeIdMapBlock(int size) implements IdMap<net.minecraft.world.level.block.state.BlockState> {

View File

@ -12,7 +12,7 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
import it.unimi.dsi.fastutil.longs.LongArraySet; import it.unimi.dsi.fastutil.longs.LongArraySet;
import it.unimi.dsi.fastutil.longs.LongIterator; import it.unimi.dsi.fastutil.longs.LongIterator;
import it.unimi.dsi.fastutil.longs.LongSet; import it.unimi.dsi.fastutil.longs.LongSet;
import net.minecraft.server.MCUtil; import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ThreadedLevelLightEngine; import net.minecraft.server.level.ThreadedLevelLightEngine;
import net.minecraft.server.level.TicketType; import net.minecraft.server.level.TicketType;
@ -41,7 +41,7 @@ public class PaperweightStarlightRelighter implements Relighter {
private static final int CHUNKS_PER_BATCH_SQRT_LOG2 = 5; // for shifting private static final int CHUNKS_PER_BATCH_SQRT_LOG2 = 5; // for shifting
private static final TicketType<Unit> FAWE_TICKET = TicketType.create("fawe_ticket", (a, b) -> 0); private static final TicketType<Unit> FAWE_TICKET = TicketType.create("fawe_ticket", (a, b) -> 0);
private static final int LIGHT_LEVEL = MCUtil.getTicketLevelFor(ChunkStatus.LIGHT); private static final int LIGHT_LEVEL = ChunkMap.MAX_VIEW_DISTANCE + ChunkStatus.getDistance(ChunkStatus.LIGHT);
static { static {
MethodHandle tmp = null; MethodHandle tmp = null;

View File

@ -364,7 +364,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
Fawe.instance().getQueueHandler().sync(() -> { Fawe.instance().getQueueHandler().sync(() -> {
try { try {
freshChunkProvider.close(false); freshChunkProvider.close(false);
} catch (IOException e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
}); });