b68b282439
Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Warning: this commit contains more mapping changes from upstream, As always, ensure that you have working backups and test this build before deployment; Developers working on paper will, yet again, need to delete their work/Minecraft/1.13.2 folder Bukkit Changes: 7fca5fd4 SPIGOT-4558: Preserve user order in the face of copied defaults in configurations 15c9b1eb Ignore spurious slot IDs sent by client, e.g. in enchanting tables 5d2a10c5 SPIGOT-3747: Add API for force loaded chunks d6dd2bb3 SPIGOT-3538: Add getHitBlockFace for ProjectileHitEvent 771db4aa SPIGOT-794: Call EntityPlaceEvent for Minecart placement 55462509 Add InventoryView#getSlotType 2f3ce5b6 Remove EntityTransformEvent and CustomItemTagContainer from draft API f04ad7b6 Make ProjectileLaunchEvent extend EntitySpawnEvent ccb85808 Define EntitySpawnEvent b8cc3ebe Add PlayerItemDamageEvent 184a495d Ease ClassLoader Deadlocks Where Possible 11ac4728 Expand Boolean Prompt Values in Conversation API aae62d51 Added getAllSessionData() to the Conversation API. 9290ff91 Add InventoryView#getInventory API 995e530f Add API to get / set base arrow damage CraftBukkit Changes:c4a67eed
SPIGOT-4556: Fix plugins closing inventory during drop events5be2ddcb
Replace version constants with methods to prevent compiler inlininga5b9c7b3
Use API method to create offset command completions2bc7d1df
SPIGOT-3747: Add API for force loaded chunksa408f375
SPIGOT-3538: Add getHitBlockFace for ProjectileHitEventb54b9409
SPIGOT-2864: Make Arrow / Item setTicksLived behave like FallingBlock79ded7a8
SPIGOT-1811: Death message not shown on respawn screenb4a4f15d
SPIGOT-943: InventoryCloseEvent called on death regardless of open inventory0afed592
SPIGOT-794: Call EntityPlaceEvent for Minecart placement2b2d084a
Add InventoryView#getSlotType01a9959a
Do not use deprecated ItemSpawnEvent constructor9642498d
SPIGOT-4547: Call EntitySpawnEvent as general spawn fallback event963f4a5f
Add PlayerItemDamageEvent63db0445
Add API to get / set base arrow damage531c25d7
Add CraftMagicNumbers.MAPPINGS_VERSION for use by NMS pluginsd05c8b14
Mappings Updatebd36e200
SPIGOT-4551: Ignore invalid attribute modifier slots Spigot Changes: 518206a1 Remove redundant trove depend 1959ad21 MC-11211,SPIGOT-4552: Fix placing double slabs at y = 255 29ab5e43 SPIGOT-3661: Allow arguments in restart-script 7cc46316 SPIGOT-852: Growth modifiers for beetroots, potatoes, carrots 82e117e1 Squelch "fatal: Resolve operation not in progress" message 0a1a68e7 Mappings Update & Patch Rebuild
281 Zeilen
12 KiB
Diff
281 Zeilen
12 KiB
Diff
From 55ff099f0d6ecf7d813d7951a9f590020b97d147 Mon Sep 17 00:00:00 2001
|
|
From: Aikar <aikar@aikar.co>
|
|
Date: Wed, 2 Mar 2016 00:52:31 -0600
|
|
Subject: [PATCH] Lighting Queue
|
|
|
|
This provides option to queue lighting updates to ensure they do not cause the server lag
|
|
|
|
diff --git a/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/src/main/java/co/aikar/timings/WorldTimingsHandler.java
|
|
index 145cb274b..eff9dcf54 100644
|
|
--- a/src/main/java/co/aikar/timings/WorldTimingsHandler.java
|
|
+++ b/src/main/java/co/aikar/timings/WorldTimingsHandler.java
|
|
@@ -50,6 +50,8 @@ public class WorldTimingsHandler {
|
|
public final Timing worldSaveLevel;
|
|
public final Timing chunkSaveData;
|
|
|
|
+ public final Timing lightingQueueTimer;
|
|
+
|
|
public WorldTimingsHandler(World server) {
|
|
String name = server.worldData.getName() +" - ";
|
|
|
|
@@ -96,6 +98,8 @@ public class WorldTimingsHandler {
|
|
tracker2 = Timings.ofSafe(name + "tracker stage 2");
|
|
doTick = Timings.ofSafe(name + "doTick");
|
|
tickEntities = Timings.ofSafe(name + "tickEntities");
|
|
+
|
|
+ lightingQueueTimer = Timings.ofSafe(name + "Lighting Queue");
|
|
}
|
|
|
|
public static Timing getTickList(WorldServer worldserver, String timingsType) {
|
|
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
|
index fe148495b..cc69ff3a4 100644
|
|
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
|
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
|
@@ -191,6 +191,13 @@ public class PaperConfig {
|
|
return config.getString(path, config.getString(path));
|
|
}
|
|
|
|
+ public static int maxTickMsLostLightQueue;
|
|
+ private static void lightQueue() {
|
|
+ int badSetting = config.getInt("queue-light-updates-max-loss", 10);
|
|
+ config.set("queue-light-updates-max-loss", null);
|
|
+ maxTickMsLostLightQueue = getInt("settings.queue-light-updates-max-loss", badSetting);
|
|
+ }
|
|
+
|
|
private static void timings() {
|
|
boolean timings = getBoolean("timings.enabled", true);
|
|
boolean verboseTimings = getBoolean("timings.verbose", true);
|
|
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
index 39d565db1..8f6f0288b 100644
|
|
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
@@ -130,4 +130,12 @@ public class PaperWorldConfig {
|
|
netherVoidTopDamage = getBoolean( "nether-ceiling-void-damage", false );
|
|
log("Top of the nether void damage: " + netherVoidTopDamage);
|
|
}
|
|
+
|
|
+ public boolean queueLightUpdates;
|
|
+ private void queueLightUpdates() {
|
|
+ queueLightUpdates = getBoolean("queue-light-updates", false);
|
|
+ log("Lighting Queue enabled: " + queueLightUpdates);
|
|
+ log("Warning: This feature may help reduce TPS loss from light, but comes at the cost of buggy light data");
|
|
+ log("We are working to improve this feature.");
|
|
+ }
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
|
|
index 0a436133a..2afd6befa 100644
|
|
--- a/src/main/java/net/minecraft/server/Chunk.java
|
|
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
|
@@ -94,6 +94,7 @@ public class Chunk implements IChunkAccess {
|
|
return removed;
|
|
}
|
|
}
|
|
+ final PaperLightingQueue.LightingQueue lightingQueue = new PaperLightingQueue.LightingQueue(this);
|
|
// Paper end
|
|
public boolean areNeighborsLoaded(final int radius) {
|
|
switch (radius) {
|
|
@@ -284,7 +285,7 @@ public class Chunk implements IChunkAccess {
|
|
|
|
private void g(boolean flag) {
|
|
this.world.methodProfiler.enter("recheckGaps");
|
|
- if (this.world.areChunksLoaded(new BlockPosition(this.locX * 16 + 8, 0, this.locZ * 16 + 8), 16)) {
|
|
+ if (this.areNeighborsLoaded(1)) { // Paper
|
|
for (int i = 0; i < 16; ++i) {
|
|
for (int j = 0; j < 16; ++j) {
|
|
if (this.g[i + j * 16]) {
|
|
@@ -335,7 +336,7 @@ public class Chunk implements IChunkAccess {
|
|
}
|
|
|
|
private void a(int i, int j, int k, int l) {
|
|
- if (l > k && this.world.areChunksLoaded(new BlockPosition(i, 0, j), 16)) {
|
|
+ if (l > k && this.areNeighborsLoaded(1)) { // Paper
|
|
for (int i1 = k; i1 < l; ++i1) {
|
|
this.world.c(EnumSkyBlock.SKY, new BlockPosition(i, i1, j));
|
|
}
|
|
@@ -535,6 +536,7 @@ public class Chunk implements IChunkAccess {
|
|
if (flag1) {
|
|
this.initLighting();
|
|
} else {
|
|
+ this.runOrQueueLightUpdate(() -> { // Paper - Queue light update
|
|
int i1 = iblockdata.b(this.world, blockposition);
|
|
int j1 = iblockdata1.b(this.world, blockposition);
|
|
|
|
@@ -542,6 +544,7 @@ public class Chunk implements IChunkAccess {
|
|
if (i1 != j1 && (i1 < j1 || this.getBrightness(EnumSkyBlock.SKY, blockposition) > 0 || this.getBrightness(EnumSkyBlock.BLOCK, blockposition) > 0)) {
|
|
this.c(i, k);
|
|
}
|
|
+ }); // Paper
|
|
}
|
|
|
|
TileEntity tileentity;
|
|
@@ -1360,6 +1363,16 @@ public class Chunk implements IChunkAccess {
|
|
return this.D == 8;
|
|
}
|
|
|
|
+ // Paper start
|
|
+ public void runOrQueueLightUpdate(Runnable runnable) {
|
|
+ if (this.world.paperConfig.queueLightUpdates) {
|
|
+ lightingQueue.add(runnable);
|
|
+ } else {
|
|
+ runnable.run();
|
|
+ }
|
|
+ }
|
|
+ // Paper end
|
|
+
|
|
public static enum EnumTileEntityState {
|
|
|
|
IMMEDIATE, QUEUED, CHECK;
|
|
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
|
index 44c1dfe92..fe189a841 100644
|
|
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
|
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
|
@@ -310,6 +310,7 @@ public class ChunkProviderServer implements IChunkProvider {
|
|
return false;
|
|
}
|
|
save = event.isSaveChunk();
|
|
+ chunk.lightingQueue.processUnload(); // Paper
|
|
|
|
// Update neighbor counts
|
|
for (int x = -2; x < 3; x++) {
|
|
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
index b12d9fbe8..f547a6ad7 100644
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
@@ -889,7 +889,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
|
|
protected void a(BooleanSupplier booleansupplier) {
|
|
co.aikar.timings.TimingsManager.FULL_SERVER_TICK.startTiming(); // Paper
|
|
this.slackActivityAccountant.tickStarted(); // Spigot
|
|
- long i = SystemUtils.getMonotonicNanos();
|
|
+ long i = SystemUtils.getMonotonicNanos(); long startTime = i; // Paper
|
|
|
|
++this.ticks;
|
|
if (this.S) {
|
|
@@ -947,6 +947,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
|
|
this.methodProfiler.exit();
|
|
this.methodProfiler.exit();
|
|
org.spigotmc.WatchdogThread.tick(); // Spigot
|
|
+ PaperLightingQueue.processQueue(startTime); // Paper
|
|
this.slackActivityAccountant.tickEnded(l); // Spigot
|
|
co.aikar.timings.TimingsManager.FULL_SERVER_TICK.stopTiming(); // Paper
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/PaperLightingQueue.java b/src/main/java/net/minecraft/server/PaperLightingQueue.java
|
|
new file mode 100644
|
|
index 000000000..9783f3a0d
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/PaperLightingQueue.java
|
|
@@ -0,0 +1,98 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import co.aikar.timings.Timing;
|
|
+import com.destroystokyo.paper.PaperConfig;
|
|
+import it.unimi.dsi.fastutil.objects.ObjectCollection;
|
|
+
|
|
+import java.util.ArrayDeque;
|
|
+
|
|
+class PaperLightingQueue {
|
|
+ private static final long MAX_TIME = (long) (1000000 * (50 + PaperConfig.maxTickMsLostLightQueue));
|
|
+
|
|
+ static void processQueue(long curTime) {
|
|
+ final long startTime = System.nanoTime();
|
|
+ final long maxTickTime = MAX_TIME - (startTime - curTime);
|
|
+
|
|
+ if (maxTickTime <= 0) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ START:
|
|
+ for (World world : MinecraftServer.getServer().getWorlds()) {
|
|
+ if (!world.paperConfig.queueLightUpdates) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ ObjectCollection<Chunk> loadedChunks = ((WorldServer) world).getChunkProvider().chunks.values();
|
|
+ for (Chunk chunk : loadedChunks.toArray(new Chunk[0])) {
|
|
+ if (chunk.lightingQueue.processQueue(startTime, maxTickTime)) {
|
|
+ break START;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ static class LightingQueue extends ArrayDeque<Runnable> {
|
|
+ final private Chunk chunk;
|
|
+
|
|
+ LightingQueue(Chunk chunk) {
|
|
+ super();
|
|
+ this.chunk = chunk;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Processes the lighting queue for this chunk
|
|
+ *
|
|
+ * @param startTime If start Time is 0, we will not limit execution time
|
|
+ * @param maxTickTime Maximum time to spend processing lighting updates
|
|
+ * @return true to abort processing furthur lighting updates
|
|
+ */
|
|
+ private boolean processQueue(long startTime, long maxTickTime) {
|
|
+ if (this.isEmpty()) {
|
|
+ return false;
|
|
+ }
|
|
+ if (isOutOfTime(maxTickTime, startTime)) {
|
|
+ return true;
|
|
+ }
|
|
+ try (Timing ignored = chunk.world.timings.lightingQueueTimer.startTiming()) {
|
|
+ Runnable lightUpdate;
|
|
+ while ((lightUpdate = this.poll()) != null) {
|
|
+ lightUpdate.run();
|
|
+ if (isOutOfTime(maxTickTime, startTime)) {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Flushes lighting updates to unload the chunk
|
|
+ */
|
|
+ void processUnload() {
|
|
+ if (!chunk.world.paperConfig.queueLightUpdates) {
|
|
+ return;
|
|
+ }
|
|
+ processQueue(0, 0); // No timeout
|
|
+
|
|
+ final int radius = 1;
|
|
+ for (int x = chunk.locX - radius; x <= chunk.locX + radius; ++x) {
|
|
+ for (int z = chunk.locZ - radius; z <= chunk.locZ + radius; ++z) {
|
|
+ if (x == chunk.locX && z == chunk.locZ) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ Chunk neighbor = chunk.world.getChunkIfLoaded(x, z);
|
|
+ if (neighbor != null) {
|
|
+ neighbor.lightingQueue.processQueue(0, 0); // No timeout
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static boolean isOutOfTime(long maxTickTime, long startTime) {
|
|
+ return startTime > 0 && System.nanoTime() - startTime > maxTickTime;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
|
index 086d64628..bf05c47a1 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -330,7 +330,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
|
|
|
if (iblockdata2.b(this, blockposition) != iblockdata1.b(this, blockposition) || iblockdata2.e() != iblockdata1.e()) {
|
|
this.methodProfiler.enter("checkLight");
|
|
- this.r(blockposition);
|
|
+ chunk.runOrQueueLightUpdate(() -> this.r(blockposition)); // Paper - Queue light update
|
|
this.methodProfiler.exit();
|
|
}
|
|
|
|
--
|
|
2.20.1
|
|
|