[ci skip] nuke workaround

This commit is contained in:
Etil
2021-11-11 11:56:50 +01:00
committed by GitHub
parent fbe2812c7d
commit 1276813ca7

View File

@@ -1,126 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MeFisto94 <MeFisto94@users.noreply.github.com>
Date: Tue, 12 May 2020 23:02:43 +0200
Subject: [PATCH] (PaperPR) Workaround for Client Lag Spikes (MC-162253)
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 4249f24f4c43c55eb13ca85be6e0b8871a1cace9..0de54c356d8c61bad3f38d022bcab98ca465d7f5 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -2138,27 +2138,42 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
- // Paper start
+ /*
+ // Paper start
private static int getLightMask(final LevelChunk chunk) {
final net.minecraft.world.level.chunk.LevelChunkSection[] chunkSections = chunk.getSections();
int mask = 0;
for (int i = 0; i < chunkSections.length; ++i) {
- /*
Lightmasks have 18 bits, from the -1 (void) section until the 17th (air) section.
Sections go from 0..16. Now whenever a section is not empty, it can potentially change lighting for the section itself, the section below and the section above, hence the bitmask 111b, which is 7d.
- */
mask |= (net.minecraft.world.level.chunk.LevelChunkSection.isEmpty(chunkSections[i]) ? 0 : 7) << i;
- }
+ */
+ // Paper start - Fix MC-162253
+ private static final BitSet lightMask(LevelChunk chunk) {
+ net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunk.getSections();
+ BitSet mask = new BitSet(sections.length + 2); // One light section added above and below
+ for (int i = 0; i < sections.length; i++) {
+ if (!net.minecraft.world.level.chunk.LevelChunkSection.isEmpty(sections[i])) {
+ // Whenever a section is not empty, it can potentially change lighting for the section itself, the section below and the section above
+ // Add one to account for the light section below min y
+ mask.set(i + 0);
+ mask.set(i + 1);
+ mask.set(i + 2);
+ }
+ }
return mask;
}
- private static int getCeilingLightMask(final LevelChunk chunk) {
+ /*
+ private static int getCeilingLightMask(final LevelChunk chunk) {
int mask = getLightMask(chunk);
+ */
+ private static final BitSet ceilingLightMask(LevelChunk chunk) {
/*
It is similar to get highest bit, it would turn an 001010 into an 001111 so basically the highest bit and all below.
@@ -2169,6 +2184,7 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially
@TODO: Implement Leafs suggestion
either use Integer#numberOfLeadingZeros or document what this bithack is supposed to be doing then
*/
+ /*
mask |= mask >> 1;
mask |= mask >> 2;
mask |= mask >> 4;
@@ -2176,13 +2192,58 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially
mask |= mask >> 16;
return mask;
+ */
+ net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunk.getSections();
+ for (int i = sections.length - 1; i >= 0; i--) {
+ if (!net.minecraft.world.level.chunk.LevelChunkSection.isEmpty(sections[i])) {
+ int heighest = i + 3; // Add one to account for the light section below min y and one because blocks might change the light in the section above, and one because toIndex in BitSet is exclusive
+ BitSet mask = new BitSet(heighest);
+ mask.set(0, heighest);
+ return mask;
+ }
+ }
+ return new BitSet();
}
- // Paper end
+ // Paper end - Fix MC-162253
public void playerLoadedChunk(ServerPlayer player, Packet<?>[] packets, LevelChunk chunk) {
if (packets[0] == null) {
packets[0] = new ClientboundLevelChunkPacket(chunk, chunk.level.chunkPacketBlockController.shouldModify(player, chunk)); // Paper - Ani-Xray - Bypass
packets[1] = new ClientboundLightUpdatePacket(chunk.getPos(), this.lightEngine, (BitSet) null, (BitSet) null, true);
+
+ // Paper start - Fix MC-162253
+ final int viewDistance = this.playerChunkManager.getData(player).getTargetSendViewDistance();
+ final int playerChunkX = (int) (player.getX() / 16);
+ final int playerChunkZ = (int) (player.getZ() / 16);
+
+ final BitSet lightMask = lightMask(chunk);
+ for (int x = -1; x <= 1; x++) {
+ for (int z = -1; z <= 1; z++) {
+ if (x == 0 && z == 0) {
+ continue;
+ }
+
+ if (!chunk.isNeighbourLoaded(x, z)) {
+ continue;
+ }
+
+ final int distX = Math.abs(playerChunkX - (chunk.getPos().x + x));
+ final int distZ = Math.abs(playerChunkZ - (chunk.getPos().z + z));
+ if (Math.max(distX, distZ) > viewDistance) {
+ continue;
+ }
+
+ final LevelChunk neighbor = chunk.getRelativeNeighbourIfLoaded(x, z);
+ BitSet updateLightMask = (BitSet) lightMask.clone();
+ updateLightMask.andNot(ceilingLightMask(neighbor));
+ if (updateLightMask.isEmpty()) {
+ continue;
+ }
+
+ player.connection.send(new ClientboundLightUpdatePacket(new ChunkPos(chunk.getPos().x + x, chunk.getPos().z + z), lightEngine, updateLightMask, null, true));
+ }
+ }
+ // Paper end - Fix MC-162253
}
player.trackChunk(chunk.getPos(), packets[0], packets[1]);