mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-27 19:37:35 +01:00
Many improvements to chunk prioritization and bug fixes
Fixed a few bugs, and made numerous improvements. Fixed issue where a sync chunk load could have its ticket removed and the priority ticket could expire... Still not perfect there but better than before. Also fixed few other misc issues such as watchdog cpu usage, chunk queue update had risk of double enqueue due to it no longer being a set. Added much more information about chunk state to watchdog prints. I see some more room for improvement even, but this is much better than before. Fixes #3407 Fixes #3411 Fixes #3395 Fixes #3389
This commit is contained in:
parent
c82b292ab0
commit
7e1525ea2d
@ -5,19 +5,28 @@ Subject: [PATCH] ChunkMapDistance CME
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||
index ae661297774f51c8b61fc08ca43e13ba368d0021..682a64c775adc1254f12d9f93b23375735ed4895 100644
|
||||
index ae661297774f51c8b61fc08ca43e13ba368d0021..83da76fdc495225b563cecbdb71422aec2b534f3 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||
@@ -33,7 +33,7 @@ public abstract class ChunkMapDistance {
|
||||
@@ -33,7 +33,16 @@ public abstract class ChunkMapDistance {
|
||||
private final ChunkMapDistance.a e = new ChunkMapDistance.a();
|
||||
private final ChunkMapDistance.b f = new ChunkMapDistance.b(8);
|
||||
private final ChunkMapDistance.c g = new ChunkMapDistance.c(33);
|
||||
- private final Set<PlayerChunk> pendingChunkUpdates = Sets.newHashSet();
|
||||
+ private final java.util.Queue<PlayerChunk> pendingChunkUpdates = new java.util.ArrayDeque<>(); // PAIL pendingChunkUpdates // Paper - use a queue
|
||||
+ // Paper start use a queue, but still keep unique requirement
|
||||
+ public final java.util.Queue<PlayerChunk> pendingChunkUpdates = new java.util.ArrayDeque<PlayerChunk>() {
|
||||
+ @Override
|
||||
+ public boolean add(PlayerChunk o) {
|
||||
+ if (o.isUpdateQueued) return true;
|
||||
+ o.isUpdateQueued = true;
|
||||
+ return super.add(o);
|
||||
+ }
|
||||
+ };
|
||||
+ // Paper end
|
||||
private final ChunkTaskQueueSorter i;
|
||||
private final Mailbox<ChunkTaskQueueSorter.a<Runnable>> j;
|
||||
private final Mailbox<ChunkTaskQueueSorter.b> k;
|
||||
@@ -94,26 +94,12 @@ public abstract class ChunkMapDistance {
|
||||
@@ -94,26 +103,14 @@ public abstract class ChunkMapDistance {
|
||||
;
|
||||
}
|
||||
|
||||
@ -43,9 +52,23 @@ index ae661297774f51c8b61fc08ca43e13ba368d0021..682a64c775adc1254f12d9f93b233757
|
||||
- // CraftBukkit end
|
||||
-
|
||||
+ while(!this.pendingChunkUpdates.isEmpty()) {
|
||||
+ this.pendingChunkUpdates.remove().a(playerchunkmap);
|
||||
+ PlayerChunk remove = this.pendingChunkUpdates.remove();
|
||||
+ remove.isUpdateQueued = false;
|
||||
+ remove.a(playerchunkmap);
|
||||
+ }
|
||||
+ // Paper end
|
||||
return true;
|
||||
} else {
|
||||
if (!this.l.isEmpty()) {
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
index 6e9f402fb0faccc222b4289deb36e2d85a66eb7c..980044b9a81232e7d0eab8e4947db6ca1f845c1c 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
@@ -18,6 +18,7 @@ public class PlayerChunk {
|
||||
private static final CompletableFuture<Either<Chunk, PlayerChunk.Failure>> UNLOADED_CHUNK_FUTURE = CompletableFuture.completedFuture(PlayerChunk.UNLOADED_CHUNK);
|
||||
private static final List<ChunkStatus> CHUNK_STATUSES = ChunkStatus.a();
|
||||
private static final PlayerChunk.State[] CHUNK_STATES = PlayerChunk.State.values();
|
||||
+ boolean isUpdateQueued = false; // Paper
|
||||
private final AtomicReferenceArray<CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>>> statusFutures;
|
||||
private volatile CompletableFuture<Either<Chunk, PlayerChunk.Failure>> fullChunkFuture; private int fullChunkCreateCount; private volatile boolean isFullChunkReady; // Paper - cache chunk ticking stage
|
||||
private volatile CompletableFuture<Either<Chunk, PlayerChunk.Failure>> tickingFuture; private volatile boolean isTickingReady; // Paper - cache chunk ticking stage
|
||||
|
@ -399,10 +399,10 @@ index 206d04dcce1d7d074cf7151a083bdc626b0b8e07..f75f48a3d0b0bc1da3c5ae3b3cf20b64
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
index 6e9f402fb0faccc222b4289deb36e2d85a66eb7c..a640cb3845a853780b8cc2dbfc6e9be3728817e7 100644
|
||||
index 980044b9a81232e7d0eab8e4947db6ca1f845c1c..47e3e618c9e683e6975fb64e1094dc7078574dae 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
@@ -26,7 +26,7 @@ public class PlayerChunk {
|
||||
@@ -27,7 +27,7 @@ public class PlayerChunk {
|
||||
public int oldTicketLevel;
|
||||
private int ticketLevel;
|
||||
private int n;
|
||||
|
@ -108,10 +108,10 @@ index 8b499c815c77bf5b356d4216ba6cbf2a329c9aca..cfed5f51431ec5aecb538a321327bfb6
|
||||
this.methodProfiler.enter("snooper");
|
||||
if (((DedicatedServer) this).getDedicatedServerProperties().snooperEnabled && !this.snooper.d() && this.ticks > 100) { // Spigot
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
index a640cb3845a853780b8cc2dbfc6e9be3728817e7..3d255b19647fb37f53a420c907bc634181580c18 100644
|
||||
index 47e3e618c9e683e6975fb64e1094dc7078574dae..ed9ada49c7cc1131691bd6e005b2380274ef23e3 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
@@ -40,6 +40,9 @@ public class PlayerChunk {
|
||||
@@ -41,6 +41,9 @@ public class PlayerChunk {
|
||||
|
||||
private final PlayerChunkMap chunkMap; // Paper
|
||||
|
||||
@ -121,7 +121,7 @@ index a640cb3845a853780b8cc2dbfc6e9be3728817e7..3d255b19647fb37f53a420c907bc6341
|
||||
public PlayerChunk(ChunkCoordIntPair chunkcoordintpair, int i, LightEngine lightengine, PlayerChunk.c playerchunk_c, PlayerChunk.d playerchunk_d) {
|
||||
this.statusFutures = new AtomicReferenceArray(PlayerChunk.CHUNK_STATUSES.size());
|
||||
this.fullChunkFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE;
|
||||
@@ -385,7 +388,19 @@ public class PlayerChunk {
|
||||
@@ -386,7 +389,19 @@ public class PlayerChunk {
|
||||
boolean flag2 = playerchunk_state.isAtLeast(PlayerChunk.State.BORDER);
|
||||
boolean flag3 = playerchunk_state1.isAtLeast(PlayerChunk.State.BORDER);
|
||||
|
||||
@ -141,7 +141,7 @@ index a640cb3845a853780b8cc2dbfc6e9be3728817e7..3d255b19647fb37f53a420c907bc6341
|
||||
if (!flag2 && flag3) {
|
||||
// Paper start - cache ticking ready status
|
||||
int expectCreateCount = ++this.fullChunkCreateCount;
|
||||
@@ -505,8 +520,32 @@ public class PlayerChunk {
|
||||
@@ -506,8 +521,32 @@ public class PlayerChunk {
|
||||
}
|
||||
|
||||
public void m() {
|
||||
|
@ -108,10 +108,10 @@ index f0a052eec2fb72b11dc70bf62a5e57f599bbc190..2f95174fcc467908808ed3f2dc956bdc
|
||||
@Nullable
|
||||
private PersistentStructureLegacy c;
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
index 3d255b19647fb37f53a420c907bc634181580c18..040d4b41ea2223937ca22de2d40560f97b310f9a 100644
|
||||
index ed9ada49c7cc1131691bd6e005b2380274ef23e3..52ea4f05a0c7f29f62f31bb032a5ceb905107e60 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
@@ -114,6 +114,19 @@ public class PlayerChunk {
|
||||
@@ -115,6 +115,19 @@ public class PlayerChunk {
|
||||
Either<IChunkAccess, PlayerChunk.Failure> either = (Either<IChunkAccess, PlayerChunk.Failure>) statusFuture.getNow(null);
|
||||
return either == null ? null : (Chunk) either.left().orElse(null);
|
||||
}
|
||||
|
@ -160,6 +160,44 @@ index fa1c920ea6092259149f9e7f9cd7cc1ed27bf338..98acbfa44dd9042b26fdf719d7748f92
|
||||
}
|
||||
|
||||
public static Timing getTickList(WorldServer worldserver, String timingsType) {
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java
|
||||
index af810987846efcd2bffbd23c31481b2d31c168dd..331493a172f58e71b464d635efdba461082bd27d 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperCommand.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.destroystokyo.paper;
|
||||
|
||||
+import com.destroystokyo.paper.io.chunk.ChunkTaskManager;
|
||||
import com.google.common.base.Functions;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -28,14 +29,14 @@ public class PaperCommand extends Command {
|
||||
public PaperCommand(String name) {
|
||||
super(name);
|
||||
this.description = "Paper related commands";
|
||||
- this.usageMessage = "/paper [heap | entity | reload | version | debug | chunkinfo]";
|
||||
+ this.usageMessage = "/paper [heap | entity | reload | version | debug | dumpwaiting | chunkinfo]";
|
||||
this.setPermission("bukkit.command.paper");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException {
|
||||
if (args.length <= 1)
|
||||
- return getListMatchingLast(args, "heap", "entity", "reload", "version", "debug", "chunkinfo");
|
||||
+ return getListMatchingLast(args, "heap", "entity", "reload", "version", "debug", "dumpwaiting", "chunkinfo");
|
||||
|
||||
switch (args[0].toLowerCase(Locale.ENGLISH))
|
||||
{
|
||||
@@ -127,6 +128,9 @@ public class PaperCommand extends Command {
|
||||
case "debug":
|
||||
doDebug(sender, args);
|
||||
break;
|
||||
+ case "dumpwaiting":
|
||||
+ ChunkTaskManager.dumpAllChunkLoadInfo();
|
||||
+ break;
|
||||
case "chunkinfo":
|
||||
doChunkInfo(sender, args);
|
||||
break;
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
index dbd14399707cdd43f98af40191be8ff3e76edf43..74295466e53db06d0d019a13768f3575ac61d699 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
@ -1809,10 +1847,10 @@ index 0000000000000000000000000000000000000000..1dfa8abfd869ca97e4cc566d44e509b4
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..2b20c159f6bb425be70201cf33159aa9e949eb54
|
||||
index 0000000000000000000000000000000000000000..d9580eb998801edd34c610ced3f82f9627c6685b
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java
|
||||
@@ -0,0 +1,492 @@
|
||||
@@ -0,0 +1,502 @@
|
||||
+package com.destroystokyo.paper.io.chunk;
|
||||
+
|
||||
+import com.destroystokyo.paper.io.PaperFileIOThread;
|
||||
@ -1824,7 +1862,9 @@ index 0000000000000000000000000000000000000000..2b20c159f6bb425be70201cf33159aa9
|
||||
+import net.minecraft.server.IChunkAccess;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
+import net.minecraft.server.NBTTagCompound;
|
||||
+import net.minecraft.server.PlayerChunk;
|
||||
+import net.minecraft.server.WorldServer;
|
||||
+import org.apache.commons.lang.StringUtils;
|
||||
+import org.apache.logging.log4j.Level;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.spigotmc.AsyncCatcher;
|
||||
@ -1912,20 +1952,28 @@ index 0000000000000000000000000000000000000000..2b20c159f6bb425be70201cf33159aa9
|
||||
+ // log current status of chunk to indicate whether we're waiting on generation or loading
|
||||
+ net.minecraft.server.PlayerChunk chunkHolder = chunkInfo.world.getChunkProvider().playerChunkMap.getVisibleChunk(key);
|
||||
+
|
||||
+ if (chunkHolder == null) {
|
||||
+ PaperFileIOThread.LOGGER.log(Level.ERROR, "Chunk Holder - null");
|
||||
+ } else {
|
||||
+ IChunkAccess chunk = chunkHolder.getAvailableChunkNow();
|
||||
+ net.minecraft.server.ChunkStatus holderStatus = chunkHolder.getChunkHolderStatus();
|
||||
+ PaperFileIOThread.LOGGER.log(Level.ERROR, "Chunk Holder - non-null");
|
||||
+ PaperFileIOThread.LOGGER.log(Level.ERROR, "Chunk Status - " + ((chunk == null) ? "null chunk" : chunk.getChunkStatus().toString()));
|
||||
+ PaperFileIOThread.LOGGER.log(Level.ERROR, "Chunk Holder Status - " + ((holderStatus == null) ? "null" : holderStatus.toString()));
|
||||
+ }
|
||||
+
|
||||
+ dumpChunkInfo(chunkHolder, chunkInfo.chunkX, chunkInfo.chunkZ);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ static void dumpChunkInfo(PlayerChunk chunkHolder, int x, int z) {
|
||||
+ dumpChunkInfo(chunkHolder, x, z, 0);
|
||||
+ }
|
||||
+ static void dumpChunkInfo(PlayerChunk chunkHolder, int x, int z, int indent) {
|
||||
+ String indentStr = StringUtils.repeat(" ", indent);
|
||||
+ if (chunkHolder == null) {
|
||||
+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Holder - null for (" + x +"," + z +")");
|
||||
+ } else {
|
||||
+ IChunkAccess chunk = chunkHolder.getAvailableChunkNow();
|
||||
+ net.minecraft.server.ChunkStatus holderStatus = chunkHolder.getChunkHolderStatus();
|
||||
+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Holder - non-null");
|
||||
+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Status - " + ((chunk == null) ? "null chunk" : chunk.getChunkStatus().toString()));
|
||||
+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Ticket Status - " + PlayerChunk.getChunkStatus(chunkHolder.getTicketLevel()));
|
||||
+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Holder Status - " + ((holderStatus == null) ? "null" : holderStatus.toString()));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static void initGlobalLoadThreads(int threads) {
|
||||
+ if (threads <= 0 || globalWorkers != null) {
|
||||
+ return;
|
||||
@ -3004,10 +3052,10 @@ index 4c52c57c02571353f71772e3650932f314da62ca..71daa0cb08d69c16bded510d1a490534
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
index 040d4b41ea2223937ca22de2d40560f97b310f9a..bf592125f4ce5d7ea6e802e637ee3bfbe25d23aa 100644
|
||||
index 52ea4f05a0c7f29f62f31bb032a5ceb905107e60..0f1576effe10795bcb8ed3b519f4dbafdf9ea6ed 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
@@ -127,6 +127,18 @@ public class PlayerChunk {
|
||||
@@ -128,6 +128,18 @@ public class PlayerChunk {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -3026,7 +3074,7 @@ index 040d4b41ea2223937ca22de2d40560f97b310f9a..bf592125f4ce5d7ea6e802e637ee3bfb
|
||||
// Paper end
|
||||
|
||||
public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> getStatusFutureUnchecked(ChunkStatus chunkstatus) {
|
||||
@@ -352,7 +364,7 @@ public class PlayerChunk {
|
||||
@@ -353,7 +365,7 @@ public class PlayerChunk {
|
||||
ChunkStatus chunkstatus = getChunkStatus(this.oldTicketLevel);
|
||||
ChunkStatus chunkstatus1 = getChunkStatus(this.ticketLevel);
|
||||
boolean flag = this.oldTicketLevel <= PlayerChunkMap.GOLDEN_TICKET;
|
||||
@ -3035,7 +3083,7 @@ index 040d4b41ea2223937ca22de2d40560f97b310f9a..bf592125f4ce5d7ea6e802e637ee3bfb
|
||||
PlayerChunk.State playerchunk_state = getChunkState(this.oldTicketLevel);
|
||||
PlayerChunk.State playerchunk_state1 = getChunkState(this.ticketLevel);
|
||||
// CraftBukkit start
|
||||
@@ -388,6 +400,12 @@ public class PlayerChunk {
|
||||
@@ -389,6 +401,12 @@ public class PlayerChunk {
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -11,12 +11,13 @@ it must be enabled by setting the startup flag -Dpaper.debug-sync-loads=true
|
||||
To get a debug log for sync loads, the command is /paper syncloadinfo
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java
|
||||
index af810987846efcd2bffbd23c31481b2d31c168dd..ddb60e9a48e5e7225ad575240b94fda24b6b78ca 100644
|
||||
index 331493a172f58e71b464d635efdba461082bd27d..182b440ba4802d199b8e44f7779b3401ace495d5 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperCommand.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
|
||||
@@ -1,9 +1,13 @@
|
||||
@@ -1,10 +1,14 @@
|
||||
package com.destroystokyo.paper;
|
||||
|
||||
import com.destroystokyo.paper.io.chunk.ChunkTaskManager;
|
||||
+import com.destroystokyo.paper.io.SyncLoadFinder;
|
||||
import com.google.common.base.Functions;
|
||||
import com.google.common.collect.Iterables;
|
||||
@ -28,7 +29,7 @@ index af810987846efcd2bffbd23c31481b2d31c168dd..ddb60e9a48e5e7225ad575240b94fda2
|
||||
import net.minecraft.server.*;
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
@@ -18,6 +22,9 @@ import org.bukkit.craftbukkit.CraftWorld;
|
||||
@@ -19,6 +23,9 @@ import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
@ -38,24 +39,24 @@ index af810987846efcd2bffbd23c31481b2d31c168dd..ddb60e9a48e5e7225ad575240b94fda2
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
@@ -28,14 +35,14 @@ public class PaperCommand extends Command {
|
||||
@@ -29,14 +36,14 @@ public class PaperCommand extends Command {
|
||||
public PaperCommand(String name) {
|
||||
super(name);
|
||||
this.description = "Paper related commands";
|
||||
- this.usageMessage = "/paper [heap | entity | reload | version | debug | chunkinfo]";
|
||||
+ this.usageMessage = "/paper [heap | entity | reload | version | debug | chunkinfo | syncloadinfo]";
|
||||
- this.usageMessage = "/paper [heap | entity | reload | version | debug | dumpwaiting | chunkinfo]";
|
||||
+ this.usageMessage = "/paper [heap | entity | reload | version | debug | dumpwaiting | chunkinfo | syncloadinfo]";
|
||||
this.setPermission("bukkit.command.paper");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException {
|
||||
if (args.length <= 1)
|
||||
- return getListMatchingLast(args, "heap", "entity", "reload", "version", "debug", "chunkinfo");
|
||||
+ return getListMatchingLast(args, "heap", "entity", "reload", "version", "debug", "chunkinfo", "syncloadinfo");
|
||||
- return getListMatchingLast(args, "heap", "entity", "reload", "version", "debug", "dumpwaiting", "chunkinfo");
|
||||
+ return getListMatchingLast(args, "heap", "entity", "reload", "version", "debug", "dumpwaiting", "chunkinfo", "syncloadinfo");
|
||||
|
||||
switch (args[0].toLowerCase(Locale.ENGLISH))
|
||||
{
|
||||
@@ -130,6 +137,9 @@ public class PaperCommand extends Command {
|
||||
@@ -134,6 +141,9 @@ public class PaperCommand extends Command {
|
||||
case "chunkinfo":
|
||||
doChunkInfo(sender, args);
|
||||
break;
|
||||
@ -65,7 +66,7 @@ index af810987846efcd2bffbd23c31481b2d31c168dd..ddb60e9a48e5e7225ad575240b94fda2
|
||||
case "ver":
|
||||
case "version":
|
||||
Command ver = org.bukkit.Bukkit.getServer().getCommandMap().getCommand("version");
|
||||
@@ -146,6 +156,40 @@ public class PaperCommand extends Command {
|
||||
@@ -150,6 +160,40 @@ public class PaperCommand extends Command {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ sets the excessive tick delay to the specified ticks (defaults to
|
||||
60 * 20 ticks, aka 60 seconds)
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
index f4836e2da1061e7aa62ddb01c8ca7b3467b18415..647f6fc8efb350fbd0bc4c40358a998f8b89b96a 100644
|
||||
index 74295466e53db06d0d019a13768f3575ac61d699..f1b41e16c8ce8323a896339c5d822f8ff7d8f7e6 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
@@ -369,6 +369,13 @@ public class PaperConfig {
|
||||
@ -883,7 +883,7 @@ index 0000000000000000000000000000000000000000..118988c39e58f28e8a2851792b9c014f
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java
|
||||
index 063f8eb08635aaa44803f2a67d118805294ae938..58ba1209155e05e802171800f4420e3ae419950f 100644
|
||||
index 3fcfe416d26808fa1c9bfdc5b413b149764c544a..3bf17ccdaef21322b787db538d569e0bc614ef22 100644
|
||||
--- a/src/main/java/net/minecraft/server/BlockPosition.java
|
||||
+++ b/src/main/java/net/minecraft/server/BlockPosition.java
|
||||
@@ -126,6 +126,7 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali
|
||||
@ -895,7 +895,7 @@ index 063f8eb08635aaa44803f2a67d118805294ae938..58ba1209155e05e802171800f4420e3a
|
||||
return this.b(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
index e67e00653575c3e57fe16980d2ff074d8413a95e..ca1b5b3b094b847f96742d8466fc42c5bdedbff5 100644
|
||||
index 4f65c3aca4e1c299114c03339605e0749a969653..fd998e4fb1534690a2ef8c1bca55e0ae9fe855f9 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
@@ -200,6 +200,13 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
@ -984,10 +984,10 @@ index 33cfeabdee03195a294f303f28044a313cb1c4ed..2287e47d1b891135a5f2579ec324c705
|
||||
public String toString() {
|
||||
return this.e + ": " + this.a + ", " + this.b + ", " + this.c + ", " + this.f;
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
index bf592125f4ce5d7ea6e802e637ee3bfbe25d23aa..3d610e41969768da0d2848fa1ae195035ccfd660 100644
|
||||
index 0f1576effe10795bcb8ed3b519f4dbafdf9ea6ed..afc92dd031cdaf725b85c0b301d5a5a21da54720 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
@@ -472,7 +472,9 @@ public class PlayerChunk {
|
||||
@@ -473,7 +473,9 @@ public class PlayerChunk {
|
||||
PlayerChunk.this.isTickingReady = true;
|
||||
|
||||
|
||||
@ -1161,7 +1161,7 @@ index f533860bbed19ff2915c90186c259b466f41ce90..3f1aa5ced697490b5481ba992cf5af5d
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
index fcbc9f29139ce5cd3b165130006f9c326a5d9eea..5173731dc55db416a312e13afd09e4e69d829e45 100644
|
||||
index 5519fb529dd8e1f93aab79dbc434715e08edb94f..be61f898cc96afeffe6ff2eb0ae3c4ce8da10b80 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -170,6 +170,15 @@ public class WorldServer extends World {
|
||||
|
@ -313,10 +313,18 @@ index aefea3a9a8b9b75c62bd20018be7cd166a213001..123de5ac9026508e21cdc225f0962f5c
|
||||
String[] split = restartScript.split( " " );
|
||||
if ( split.length > 0 && new File( split[0] ).isFile() )
|
||||
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
index 5bdcdcf9e85b73086722783bff26321d03382bb9..fe4b8caf28b2d36b2034ac90b1a76dea7b691feb 100644
|
||||
index 5bdcdcf9e85b73086722783bff26321d03382bb9..513c1041c34ebb3ac1775674a3f4526693759c08 100644
|
||||
--- a/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
@@ -41,6 +41,7 @@ public class WatchdogThread extends Thread
|
||||
@@ -13,6 +13,7 @@ import org.bukkit.Bukkit;
|
||||
public class WatchdogThread extends Thread
|
||||
{
|
||||
|
||||
+ public static final boolean DISABLE_WATCHDOG = Boolean.getBoolean("disable.watchdog"); // Paper
|
||||
private static WatchdogThread instance;
|
||||
private final long timeoutTime;
|
||||
private final long earlyWarningEvery; // Paper - Timeout time for just printing a dump but not restarting
|
||||
@@ -41,6 +42,7 @@ public class WatchdogThread extends Thread
|
||||
{
|
||||
if ( instance == null )
|
||||
{
|
||||
@ -324,13 +332,13 @@ index 5bdcdcf9e85b73086722783bff26321d03382bb9..fe4b8caf28b2d36b2034ac90b1a76dea
|
||||
instance = new WatchdogThread( timeoutTime * 1000L, restart );
|
||||
instance.start();
|
||||
}
|
||||
@@ -67,12 +68,13 @@ public class WatchdogThread extends Thread
|
||||
@@ -67,12 +69,13 @@ public class WatchdogThread extends Thread
|
||||
// Paper start
|
||||
Logger log = Bukkit.getServer().getLogger();
|
||||
long currentTime = monotonicMillis();
|
||||
- if ( lastTick != 0 && currentTime > lastTick + earlyWarningEvery && !Boolean.getBoolean("disable.watchdog") )
|
||||
+ MinecraftServer server = MinecraftServer.getServer();
|
||||
+ if (lastTick != 0 && hasStarted && (!server.isRunning() || (currentTime > lastTick + earlyWarningEvery && !Boolean.getBoolean("disable.watchdog")) ))
|
||||
+ if (lastTick != 0 && hasStarted && (!server.isRunning() || (currentTime > lastTick + earlyWarningEvery && !DISABLE_WATCHDOG) ))
|
||||
{
|
||||
- boolean isLongTimeout = currentTime > lastTick + timeoutTime;
|
||||
+ boolean isLongTimeout = currentTime > lastTick + timeoutTime || (!server.isRunning() && !server.hasStopped() && currentTime > lastTick + 1000);
|
||||
@ -341,7 +349,7 @@ index 5bdcdcf9e85b73086722783bff26321d03382bb9..fe4b8caf28b2d36b2034ac90b1a76dea
|
||||
lastEarlyWarning = currentTime;
|
||||
if (isLongTimeout) {
|
||||
// Paper end
|
||||
@@ -114,7 +116,7 @@ public class WatchdogThread extends Thread
|
||||
@@ -114,7 +117,7 @@ public class WatchdogThread extends Thread
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
|
||||
ChunkTaskManager.dumpAllChunkLoadInfo(); // Paper
|
||||
@ -350,7 +358,7 @@ index 5bdcdcf9e85b73086722783bff26321d03382bb9..fe4b8caf28b2d36b2034ac90b1a76dea
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
//
|
||||
// Paper start - Only print full dump on long timeouts
|
||||
@@ -135,9 +137,24 @@ public class WatchdogThread extends Thread
|
||||
@@ -135,9 +138,24 @@ public class WatchdogThread extends Thread
|
||||
|
||||
if ( isLongTimeout )
|
||||
{
|
||||
|
@ -7,10 +7,10 @@ Subject: [PATCH] Don't crash if player is attempted to be removed from
|
||||
I suspect it deals with teleporting as it uses players current x/y/z
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||
index 682a64c775adc1254f12d9f93b23375735ed4895..534bb87caf88f0f1bf7988494274b762ab7210e1 100644
|
||||
index 83da76fdc495225b563cecbdb71422aec2b534f3..4e0ea454f00c69f03023f01c1d4bd2eda5553a02 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||
@@ -226,6 +226,7 @@ public abstract class ChunkMapDistance {
|
||||
@@ -237,6 +237,7 @@ public abstract class ChunkMapDistance {
|
||||
public void b(SectionPosition sectionposition, EntityPlayer entityplayer) {
|
||||
long i = sectionposition.u().pair();
|
||||
ObjectSet<EntityPlayer> objectset = (ObjectSet) this.c.get(i);
|
||||
|
@ -6,7 +6,7 @@ Subject: [PATCH] Optimize isOutsideRange to use distance maps
|
||||
Use a distance map to find the players in range quickly
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||
index 534bb87caf88f0f1bf7988494274b762ab7210e1..b98abed74f214932b4a226f12645f987191b0097 100644
|
||||
index 4e0ea454f00c69f03023f01c1d4bd2eda5553a02..353b186060b2c0417a49ab3865ea5972c859b016 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||
@@ -31,7 +31,7 @@ public abstract class ChunkMapDistance {
|
||||
@ -16,9 +16,9 @@ index 534bb87caf88f0f1bf7988494274b762ab7210e1..b98abed74f214932b4a226f12645f987
|
||||
- private final ChunkMapDistance.b f = new ChunkMapDistance.b(8);
|
||||
+ public static final int MOB_SPAWN_RANGE = 8; //private final ChunkMapDistance.b f = new ChunkMapDistance.b(8); // Paper - no longer used
|
||||
private final ChunkMapDistance.c g = new ChunkMapDistance.c(33);
|
||||
private final java.util.Queue<PlayerChunk> pendingChunkUpdates = new java.util.ArrayDeque<>(); // PAIL pendingChunkUpdates // Paper - use a queue
|
||||
private final ChunkTaskQueueSorter i;
|
||||
@@ -41,6 +41,8 @@ public abstract class ChunkMapDistance {
|
||||
// Paper start use a queue, but still keep unique requirement
|
||||
public final java.util.Queue<PlayerChunk> pendingChunkUpdates = new java.util.ArrayDeque<PlayerChunk>() {
|
||||
@@ -50,6 +50,8 @@ public abstract class ChunkMapDistance {
|
||||
private final Executor m;
|
||||
private long currentTick;
|
||||
|
||||
@ -27,7 +27,7 @@ index 534bb87caf88f0f1bf7988494274b762ab7210e1..b98abed74f214932b4a226f12645f987
|
||||
protected ChunkMapDistance(Executor executor, Executor executor1) {
|
||||
executor1.getClass();
|
||||
Mailbox<Runnable> mailbox = Mailbox.a("player ticket throttler", executor1::execute);
|
||||
@@ -85,7 +87,7 @@ public abstract class ChunkMapDistance {
|
||||
@@ -94,7 +96,7 @@ public abstract class ChunkMapDistance {
|
||||
protected abstract PlayerChunk a(long i, int j, @Nullable PlayerChunk playerchunk, int k);
|
||||
|
||||
public boolean a(PlayerChunkMap playerchunkmap) {
|
||||
@ -36,7 +36,7 @@ index 534bb87caf88f0f1bf7988494274b762ab7210e1..b98abed74f214932b4a226f12645f987
|
||||
this.g.a();
|
||||
int i = Integer.MAX_VALUE - this.e.a(Integer.MAX_VALUE);
|
||||
boolean flag = i != 0;
|
||||
@@ -219,7 +221,7 @@ public abstract class ChunkMapDistance {
|
||||
@@ -230,7 +232,7 @@ public abstract class ChunkMapDistance {
|
||||
((ObjectSet) this.c.computeIfAbsent(i, (j) -> {
|
||||
return new ObjectOpenHashSet();
|
||||
})).add(entityplayer);
|
||||
@ -45,7 +45,7 @@ index 534bb87caf88f0f1bf7988494274b762ab7210e1..b98abed74f214932b4a226f12645f987
|
||||
this.g.b(i, 0, true);
|
||||
}
|
||||
|
||||
@@ -231,7 +233,7 @@ public abstract class ChunkMapDistance {
|
||||
@@ -242,7 +244,7 @@ public abstract class ChunkMapDistance {
|
||||
objectset.remove(entityplayer);
|
||||
if (objectset.isEmpty()) {
|
||||
this.c.remove(i);
|
||||
@ -54,7 +54,7 @@ index 534bb87caf88f0f1bf7988494274b762ab7210e1..b98abed74f214932b4a226f12645f987
|
||||
this.g.b(i, Integer.MAX_VALUE, false);
|
||||
}
|
||||
|
||||
@@ -255,13 +257,17 @@ public abstract class ChunkMapDistance {
|
||||
@@ -266,13 +268,17 @@ public abstract class ChunkMapDistance {
|
||||
}
|
||||
|
||||
public int b() {
|
||||
@ -161,10 +161,10 @@ index 79c2187b7383336e7574709e6d4ad805e557976f..0560eca744cb2032bb6a3faf5aeafa95
|
||||
super((World) worldserver, gameprofile);
|
||||
playerinteractmanager.player = this;
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
index 3d610e41969768da0d2848fa1ae195035ccfd660..c4aad20a2952cc34e334ba665a6e0910d5609497 100644
|
||||
index afc92dd031cdaf725b85c0b301d5a5a21da54720..6980d19f36c18cdbed6679dbdf04afd694e078b6 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
@@ -43,6 +43,18 @@ public class PlayerChunk {
|
||||
@@ -44,6 +44,18 @@ public class PlayerChunk {
|
||||
long lastAutoSaveTime; // Paper - incremental autosave
|
||||
long inactiveTimeStart; // Paper - incremental autosave
|
||||
|
||||
@ -183,7 +183,7 @@ index 3d610e41969768da0d2848fa1ae195035ccfd660..c4aad20a2952cc34e334ba665a6e0910
|
||||
public PlayerChunk(ChunkCoordIntPair chunkcoordintpair, int i, LightEngine lightengine, PlayerChunk.c playerchunk_c, PlayerChunk.d playerchunk_d) {
|
||||
this.statusFutures = new AtomicReferenceArray(PlayerChunk.CHUNK_STATUSES.size());
|
||||
this.fullChunkFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE;
|
||||
@@ -59,6 +71,7 @@ public class PlayerChunk {
|
||||
@@ -60,6 +72,7 @@ public class PlayerChunk {
|
||||
this.n = this.oldTicketLevel;
|
||||
this.a(i);
|
||||
this.chunkMap = (PlayerChunkMap)playerchunk_d; // Paper
|
||||
|
@ -79,10 +79,10 @@ index 750fb07756f7e40b21f8ab0925f2e842aae50f7b..8c1f3290d23795b58a30274c9437dc7d
|
||||
|
||||
public final boolean areNeighboursLoaded(final int radius) {
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||
index b98abed74f214932b4a226f12645f987191b0097..716d4eab382244ee9bc4855bf0f026e65ec057d6 100644
|
||||
index 353b186060b2c0417a49ab3865ea5972c859b016..586a20fe5c77c2ad5fa26f337a94a16e21d8b5e2 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||
@@ -252,7 +252,7 @@ public abstract class ChunkMapDistance {
|
||||
@@ -263,7 +263,7 @@ public abstract class ChunkMapDistance {
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ index b98abed74f214932b4a226f12645f987191b0097..716d4eab382244ee9bc4855bf0f026e6
|
||||
this.g.a(i);
|
||||
}
|
||||
|
||||
@@ -371,7 +371,7 @@ public abstract class ChunkMapDistance {
|
||||
@@ -382,7 +382,7 @@ public abstract class ChunkMapDistance {
|
||||
|
||||
private void a(long i, int j, boolean flag, boolean flag1) {
|
||||
if (flag != flag1) {
|
||||
@ -114,20 +114,10 @@ index 0560eca744cb2032bb6a3faf5aeafa95a7a6815e..07a6fc3d88e7d44bfab7f3d6a0eef7dc
|
||||
super((World) worldserver, gameprofile);
|
||||
playerinteractmanager.player = this;
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
index c4aad20a2952cc34e334ba665a6e0910d5609497..845e5d2a8ee025ac61cf916de04e0797e32db568 100644
|
||||
index 6980d19f36c18cdbed6679dbdf04afd694e078b6..03fb688fe4bdc19b4bc36b1f1d5b40c61e7bef9b 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
@@ -47,14 +47,28 @@ public class PlayerChunk {
|
||||
// cached here to avoid a map lookup
|
||||
com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<EntityPlayer> playersInMobSpawnRange;
|
||||
com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<EntityPlayer> playersInChunkTickRange;
|
||||
+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<EntityPlayer> playersInTickingRange;
|
||||
|
||||
void updateRanges() {
|
||||
long key = net.minecraft.server.MCUtil.getCoordinateKey(this.location);
|
||||
this.playersInMobSpawnRange = this.chunkMap.playerMobSpawnMap.getObjectsInRange(key);
|
||||
this.playersInChunkTickRange = this.chunkMap.playerChunkTickRangeMap.getObjectsInRange(key);
|
||||
+ this.playersInTickingRange = this.chunkMap.playerViewDistanceTickMap.getObjectsInRange(key);
|
||||
@@ -56,6 +56,18 @@ public class PlayerChunk {
|
||||
}
|
||||
// Paper end - optimise isOutsideOfRange
|
||||
|
||||
@ -146,7 +136,7 @@ index c4aad20a2952cc34e334ba665a6e0910d5609497..845e5d2a8ee025ac61cf916de04e0797
|
||||
public PlayerChunk(ChunkCoordIntPair chunkcoordintpair, int i, LightEngine lightengine, PlayerChunk.c playerchunk_c, PlayerChunk.d playerchunk_d) {
|
||||
this.statusFutures = new AtomicReferenceArray(PlayerChunk.CHUNK_STATUSES.size());
|
||||
this.fullChunkFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE;
|
||||
@@ -210,7 +224,7 @@ public class PlayerChunk {
|
||||
@@ -211,7 +223,7 @@ public class PlayerChunk {
|
||||
}
|
||||
|
||||
public void a(int i, int j, int k) {
|
||||
@ -155,7 +145,7 @@ index c4aad20a2952cc34e334ba665a6e0910d5609497..845e5d2a8ee025ac61cf916de04e0797
|
||||
|
||||
if (chunk != null) {
|
||||
this.r |= 1 << (j >> 4);
|
||||
@@ -230,7 +244,7 @@ public class PlayerChunk {
|
||||
@@ -231,7 +243,7 @@ public class PlayerChunk {
|
||||
}
|
||||
|
||||
public void a(EnumSkyBlock enumskyblock, int i) {
|
||||
@ -164,7 +154,7 @@ index c4aad20a2952cc34e334ba665a6e0910d5609497..845e5d2a8ee025ac61cf916de04e0797
|
||||
|
||||
if (chunk != null) {
|
||||
chunk.setNeedsSaving(true);
|
||||
@@ -315,9 +329,48 @@ public class PlayerChunk {
|
||||
@@ -316,9 +328,48 @@ public class PlayerChunk {
|
||||
}
|
||||
|
||||
private void a(Packet<?> packet, boolean flag) {
|
||||
|
@ -7,10 +7,10 @@ This lets you run /paper fixlight <chunkRadius> (max 5) to automatically
|
||||
fix all light data in the chunks.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java
|
||||
index ddb60e9a48e5e7225ad575240b94fda24b6b78ca..beb50f78e8b2f79d45e2e7fdc932e947138be7aa 100644
|
||||
index 182b440ba4802d199b8e44f7779b3401ace495d5..10b72083322b7f8e3e14525b3e834f5374ec369d 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperCommand.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
|
||||
@@ -19,6 +19,7 @@ import org.bukkit.command.Command;
|
||||
@@ -20,6 +20,7 @@ import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
@ -18,24 +18,24 @@ index ddb60e9a48e5e7225ad575240b94fda24b6b78ca..beb50f78e8b2f79d45e2e7fdc932e947
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
@@ -35,14 +36,14 @@ public class PaperCommand extends Command {
|
||||
@@ -36,14 +37,14 @@ public class PaperCommand extends Command {
|
||||
public PaperCommand(String name) {
|
||||
super(name);
|
||||
this.description = "Paper related commands";
|
||||
- this.usageMessage = "/paper [heap | entity | reload | version | debug | chunkinfo | syncloadinfo]";
|
||||
+ this.usageMessage = "/paper [heap | entity | reload | version | debug | chunkinfo | syncloadinfo | fixlight]";
|
||||
- this.usageMessage = "/paper [heap | entity | reload | version | debug | dumpwaiting | chunkinfo | syncloadinfo]";
|
||||
+ this.usageMessage = "/paper [heap | entity | reload | version | debug | dumpwaiting | chunkinfo | syncloadinfo | fixlight]";
|
||||
this.setPermission("bukkit.command.paper");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException {
|
||||
if (args.length <= 1)
|
||||
- return getListMatchingLast(args, "heap", "entity", "reload", "version", "debug", "chunkinfo", "syncloadinfo");
|
||||
+ return getListMatchingLast(args, "heap", "entity", "reload", "version", "debug", "chunkinfo", "syncloadinfo", "fixlight");
|
||||
- return getListMatchingLast(args, "heap", "entity", "reload", "version", "debug", "dumpwaiting", "chunkinfo", "syncloadinfo");
|
||||
+ return getListMatchingLast(args, "heap", "entity", "reload", "version", "debug", "dumpwaiting", "chunkinfo", "syncloadinfo", "fixlight");
|
||||
|
||||
switch (args[0].toLowerCase(Locale.ENGLISH))
|
||||
{
|
||||
@@ -140,6 +141,9 @@ public class PaperCommand extends Command {
|
||||
@@ -144,6 +145,9 @@ public class PaperCommand extends Command {
|
||||
case "syncloadinfo":
|
||||
this.doSyncLoadInfo(sender, args);
|
||||
break;
|
||||
@ -45,7 +45,7 @@ index ddb60e9a48e5e7225ad575240b94fda24b6b78ca..beb50f78e8b2f79d45e2e7fdc932e947
|
||||
case "ver":
|
||||
case "version":
|
||||
Command ver = org.bukkit.Bukkit.getServer().getCommandMap().getCommand("version");
|
||||
@@ -156,6 +160,75 @@ public class PaperCommand extends Command {
|
||||
@@ -160,6 +164,75 @@ public class PaperCommand extends Command {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -122,10 +122,10 @@ index ddb60e9a48e5e7225ad575240b94fda24b6b78ca..beb50f78e8b2f79d45e2e7fdc932e947
|
||||
if (!SyncLoadFinder.ENABLED) {
|
||||
sender.sendMessage(ChatColor.RED + "This command requires the server startup flag '-Dpaper.debug-sync-loads=true' to be set.");
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
index 845e5d2a8ee025ac61cf916de04e0797e32db568..9e95c6b54f0855ddde6db6bd3e768e87fee6c21a 100644
|
||||
index 03fb688fe4bdc19b4bc36b1f1d5b40c61e7bef9b..aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
@@ -328,6 +328,7 @@ public class PlayerChunk {
|
||||
@@ -327,6 +327,7 @@ public class PlayerChunk {
|
||||
|
||||
}
|
||||
|
||||
|
@ -22,20 +22,68 @@ view distance holds on you.
|
||||
Chunks in front of the player have higher priority, to help with
|
||||
fast traveling players keep up with their movement.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java
|
||||
index d9580eb998801edd34c610ced3f82f9627c6685b..537a22b72aa2c90f0102b035843e09c54e5ae39f 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java
|
||||
@@ -4,7 +4,10 @@ import com.destroystokyo.paper.io.PaperFileIOThread;
|
||||
import com.destroystokyo.paper.io.IOUtil;
|
||||
import com.destroystokyo.paper.io.PrioritizedTaskQueue;
|
||||
import com.destroystokyo.paper.io.QueueExecutorThread;
|
||||
+import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
+import net.minecraft.server.ChunkCoordIntPair;
|
||||
import net.minecraft.server.ChunkRegionLoader;
|
||||
+import net.minecraft.server.ChunkStatus;
|
||||
import net.minecraft.server.IAsyncTaskHandler;
|
||||
import net.minecraft.server.IChunkAccess;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
@@ -118,6 +121,32 @@ public final class ChunkTaskManager {
|
||||
PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Status - " + ((chunk == null) ? "null chunk" : chunk.getChunkStatus().toString()));
|
||||
PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Ticket Status - " + PlayerChunk.getChunkStatus(chunkHolder.getTicketLevel()));
|
||||
PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Holder Status - " + ((holderStatus == null) ? "null" : holderStatus.toString()));
|
||||
+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Holder Priority - " + chunkHolder.getCurrentPriority());
|
||||
+ synchronized (chunkHolder.neighborPriorities) {
|
||||
+ if (!chunkHolder.neighborPriorities.isEmpty()) {
|
||||
+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Neighbors Requested Priority: ");
|
||||
+ for (Long2ObjectMap.Entry<Integer> entry : chunkHolder.neighborPriorities.long2ObjectEntrySet()) {
|
||||
+ ChunkCoordIntPair r = new ChunkCoordIntPair(entry.getLongKey());
|
||||
+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + " (" + r.x + "," + r.z + "): " + entry.getValue());
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ synchronized (chunkHolder.neighbors) {
|
||||
+ if (!chunkHolder.neighbors.isEmpty()) {
|
||||
+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Neighbors: ");
|
||||
+ for (PlayerChunk neighbor : chunkHolder.neighbors.keySet()) {
|
||||
+ ChunkStatus status = neighbor.getChunkHolderStatus();
|
||||
+ if (status != null && status.isAtLeastStatus(PlayerChunk.getChunkStatus(neighbor.getTicketLevel()))) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ int nx = neighbor.location.x;
|
||||
+ int nz = neighbor.location.z;
|
||||
+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + " " + nx + "," + nz + " in " + chunkHolder.getWorld().getWorld().getName() + ":");
|
||||
+ dumpChunkInfo(neighbor, nx, nz, indent + 1);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||
index 716d4eab382244ee9bc4855bf0f026e65ec057d6..20052dcbc71899165ac99801fa9f7753672ba997 100644
|
||||
index 586a20fe5c77c2ad5fa26f337a94a16e21d8b5e2..58407f488bbd8bda8781959d7c9da5d09f2a3cc4 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||
@@ -143,7 +143,7 @@ public abstract class ChunkMapDistance {
|
||||
@@ -154,7 +154,7 @@ public abstract class ChunkMapDistance {
|
||||
Ticket<?> ticket1 = (Ticket) arraysetsorted.a(ticket); // CraftBukkit - decompile error
|
||||
|
||||
ticket1.a(this.currentTick);
|
||||
- if (ticket.b() < j) {
|
||||
+ if (ticket.b() < j || (ticket.getTicketType() == TicketType.PRIORITY && ((Ticket<Integer>) ticket).getObjectReason() < j)) { // Paper - check priority tickets too
|
||||
+ if (ticket.b() < j || (ticket.getTicketType() == TicketType.PRIORITY && (30 - ticket.priority) < j)) { // Paper - check priority tickets too
|
||||
this.e.b(i, ticket.b(), true);
|
||||
}
|
||||
|
||||
@@ -171,6 +171,48 @@ public abstract class ChunkMapDistance {
|
||||
@@ -182,6 +182,54 @@ public abstract class ChunkMapDistance {
|
||||
this.addTicketAtLevel(tickettype, chunkcoordintpair, i, t0);
|
||||
}
|
||||
|
||||
@ -45,8 +93,15 @@ index 716d4eab382244ee9bc4855bf0f026e65ec057d6..20052dcbc71899165ac99801fa9f7753
|
||||
+ }
|
||||
+ public boolean markHighPriority(ChunkCoordIntPair coords, int priority) {
|
||||
+ priority = Math.min(30, Math.max(1, priority));
|
||||
+ Ticket<Integer> ticket = new Ticket<Integer>(TicketType.PRIORITY, 31, priority);
|
||||
+ return this.addTicket(coords.pair(), ticket);
|
||||
+ long pair = coords.pair();
|
||||
+ int currentPriority = getChunkPriority(coords);
|
||||
+ if (currentPriority > priority) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ Ticket<Integer> ticket = new Ticket<Integer>(TicketType.PRIORITY, 31, 0);
|
||||
+ ticket.priority = priority;
|
||||
+ this.removeTicket(pair, ticket);
|
||||
+ return this.addTicket(pair, ticket);
|
||||
+ }
|
||||
+ public int getChunkPriority(ChunkCoordIntPair coords) {
|
||||
+ int priority = 0;
|
||||
@ -55,36 +110,35 @@ index 716d4eab382244ee9bc4855bf0f026e65ec057d6..20052dcbc71899165ac99801fa9f7753
|
||||
+ return priority;
|
||||
+ }
|
||||
+ for (Ticket<?> ticket : tickets) {
|
||||
+ if (ticket.getTicketType() != TicketType.PRIORITY) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ //noinspection unchecked
|
||||
+ Ticket<Integer> prioTicket = (Ticket<Integer>) ticket;
|
||||
+ if (prioTicket.getObjectReason() > priority) {
|
||||
+ priority = prioTicket.getObjectReason();
|
||||
+ if (ticket.getTicketType() == TicketType.PRIORITY && ticket.priority > 0) {
|
||||
+ return ticket.priority;
|
||||
+ }
|
||||
+ }
|
||||
+ return priority;
|
||||
+ }
|
||||
+ public void clearPriorityTickets(ChunkCoordIntPair coords) {
|
||||
+
|
||||
+ public void refreshUrgentTicket(ChunkCoordIntPair coords) {
|
||||
+ ArraySetSorted<Ticket<?>> tickets = this.tickets.get(coords.pair());
|
||||
+ java.util.List<Ticket<?>> toRemove = new java.util.ArrayList<>();
|
||||
+ if (tickets == null) return;
|
||||
+ if (tickets == null) {
|
||||
+ markUrgent(coords);
|
||||
+ return;
|
||||
+ }
|
||||
+ for (Ticket<?> ticket : tickets) {
|
||||
+ if (ticket.getTicketType() == TicketType.PRIORITY) {
|
||||
+ toRemove.add(ticket);
|
||||
+ ticket.setCurrentTick(this.currentTick);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ for (Ticket<?> ticket : toRemove) {
|
||||
+ this.removeTicket(coords.pair(), ticket);
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+ public void clearPriorityTickets(ChunkCoordIntPair coords) {
|
||||
+ this.removeTicket(coords.pair(), new Ticket<Integer>(TicketType.PRIORITY, 31, 0));
|
||||
+ }
|
||||
+ // Paper end
|
||||
public <T> boolean addTicketAtLevel(TicketType<T> ticketType, ChunkCoordIntPair chunkcoordintpair, int level, T identifier) {
|
||||
return this.addTicket(chunkcoordintpair.pair(), new Ticket<>(ticketType, level, identifier));
|
||||
// CraftBukkit end
|
||||
@@ -386,7 +428,8 @@ public abstract class ChunkMapDistance {
|
||||
@@ -397,7 +445,8 @@ public abstract class ChunkMapDistance {
|
||||
|
||||
});
|
||||
}, i, () -> {
|
||||
@ -95,7 +149,7 @@ index 716d4eab382244ee9bc4855bf0f026e65ec057d6..20052dcbc71899165ac99801fa9f7753
|
||||
} else {
|
||||
ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
index 0a99b347d8497f097ef1da6560a5d0adc1374f25..d6f629d45e05167c22b6cd08a9709809a32b15a1 100644
|
||||
index 0a99b347d8497f097ef1da6560a5d0adc1374f25..e57e4c739b86646ef148c1f8e06ca160dbc778a1 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
@@ -431,6 +431,16 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
@ -115,7 +169,7 @@ index 0a99b347d8497f097ef1da6560a5d0adc1374f25..d6f629d45e05167c22b6cd08a9709809
|
||||
// Paper end
|
||||
|
||||
@Nullable
|
||||
@@ -469,6 +479,8 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
@@ -469,14 +479,22 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
|
||||
if (!completablefuture.isDone()) { // Paper
|
||||
// Paper start - async chunk io/loading
|
||||
@ -124,15 +178,22 @@ index 0a99b347d8497f097ef1da6560a5d0adc1374f25..d6f629d45e05167c22b6cd08a9709809
|
||||
this.world.asyncChunkTaskManager.raisePriority(x, z, com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGHEST_PRIORITY);
|
||||
com.destroystokyo.paper.io.chunk.ChunkTaskManager.pushChunkWait(this.world, x, z);
|
||||
// Paper end
|
||||
@@ -477,6 +489,7 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
this.serverThreadQueue.awaitTasks(completablefuture::isDone);
|
||||
com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.world, x, z); // Paper - sync load info
|
||||
this.world.timings.syncChunkLoad.startTiming(); // Paper
|
||||
- this.serverThreadQueue.awaitTasks(completablefuture::isDone);
|
||||
+ // Paper start - keep priority ticket refreshed
|
||||
+ this.serverThreadQueue.awaitTasks(() -> {
|
||||
+ this.chunkMapDistance.refreshUrgentTicket(pair);
|
||||
+ return completablefuture.isDone();
|
||||
+ });
|
||||
+ // PAper end
|
||||
com.destroystokyo.paper.io.chunk.ChunkTaskManager.popChunkWait(); // Paper - async chunk debug
|
||||
this.world.timings.syncChunkLoad.stopTiming(); // Paper
|
||||
+ this.clearPriorityTickets(pair); // Paper
|
||||
} // Paper
|
||||
ichunkaccess = (IChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> {
|
||||
return ichunkaccess1;
|
||||
@@ -529,6 +542,7 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
@@ -529,6 +547,7 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
if (flag && !currentlyUnloading) {
|
||||
// CraftBukkit end
|
||||
this.chunkMapDistance.a(TicketType.UNKNOWN, chunkcoordintpair, l, chunkcoordintpair);
|
||||
@ -140,7 +201,7 @@ index 0a99b347d8497f097ef1da6560a5d0adc1374f25..d6f629d45e05167c22b6cd08a9709809
|
||||
if (this.a(playerchunk, l)) {
|
||||
GameProfilerFiller gameprofilerfiller = this.world.getMethodProfiler();
|
||||
|
||||
@@ -541,8 +555,13 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
@@ -541,8 +560,13 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -181,26 +242,36 @@ index d129c7f54d9f65fff6f512d8ff5f1c3866632603..9b9536fba4a62c0153b921e678e6a968
|
||||
chunkData.addProperty("queued-for-unload", chunkMap.unloadQueue.contains(playerChunk.location.pair()));
|
||||
chunkData.addProperty("status", status == null ? "unloaded" : status.toString());
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
index 9e95c6b54f0855ddde6db6bd3e768e87fee6c21a..44721a4f446bdd5bf4575e4168a0570afd71c4d4 100644
|
||||
index aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44..46462298c7d02fcf31bb8da502a3ee5d98fe7905 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
@@ -25,7 +25,7 @@ public class PlayerChunk {
|
||||
@@ -26,8 +26,8 @@ public class PlayerChunk {
|
||||
private CompletableFuture<IChunkAccess> chunkSave;
|
||||
public int oldTicketLevel;
|
||||
private int ticketLevel;
|
||||
- private int n;
|
||||
+ private int n; public final int getCurrentPriority() { return n; } // Paper - OBFHELPER
|
||||
final ChunkCoordIntPair location; // Paper - private -> package
|
||||
- final ChunkCoordIntPair location; // Paper - private -> package
|
||||
+ volatile int n; public final int getCurrentPriority() { return n; } // Paper - OBFHELPER - make volatile since this is concurrently accessed
|
||||
+ public final ChunkCoordIntPair location; // Paper - private -> public
|
||||
private final short[] dirtyBlocks;
|
||||
private int dirtyCount;
|
||||
@@ -68,6 +68,92 @@ public class PlayerChunk {
|
||||
private int r;
|
||||
@@ -40,6 +40,7 @@ public class PlayerChunk {
|
||||
private boolean hasBeenLoaded;
|
||||
|
||||
private final PlayerChunkMap chunkMap; // Paper
|
||||
+ public WorldServer getWorld() { return chunkMap.world; } // Paper
|
||||
|
||||
long lastAutoSaveTime; // Paper - incremental autosave
|
||||
long inactiveTimeStart; // Paper - incremental autosave
|
||||
@@ -67,6 +68,92 @@ public class PlayerChunk {
|
||||
return null;
|
||||
}
|
||||
// Paper end - no-tick view distance
|
||||
+ // Paper start - Chunk gen/load priority system
|
||||
+ volatile int neighborPriority = -1;
|
||||
+ final java.util.concurrent.ConcurrentHashMap<PlayerChunk, Integer> neighbors = new java.util.concurrent.ConcurrentHashMap<>();
|
||||
+ final it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<Integer> neighborPriorities = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>();
|
||||
+ public final java.util.concurrent.ConcurrentHashMap<PlayerChunk, ChunkStatus> neighbors = new java.util.concurrent.ConcurrentHashMap<>();
|
||||
+ public final it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<Integer> neighborPriorities = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>();
|
||||
+
|
||||
+ public int getPreferredPriority() {
|
||||
+ int priority = neighborPriority; // if we have a neighbor priority, use it
|
||||
@ -221,10 +292,10 @@ index 9e95c6b54f0855ddde6db6bd3e768e87fee6c21a..44721a4f446bdd5bf4575e4168a0570a
|
||||
+ return Math.max(1, Math.min(PlayerChunkMap.GOLDEN_TICKET, priority));
|
||||
+ }
|
||||
+ public void onNeighborRequest(PlayerChunk neighbor, ChunkStatus status) {
|
||||
+ int currentPriority = getCurrentPriority();
|
||||
+ if (!neighborPriorities.containsKey(neighbor.location.pair()) && (neighbor.neighborPriority == -1 || neighbor.neighborPriority > currentPriority)) {
|
||||
+ this.neighbors.put(neighbor, currentPriority);
|
||||
+ neighbor.setNeighborPriority(this, Math.max(1, currentPriority));
|
||||
+ int priority = getCurrentPriority() + 1;
|
||||
+ if (!neighborPriorities.containsKey(neighbor.location.pair()) && (neighbor.neighborPriority == -1 || neighbor.neighborPriority > priority)) {
|
||||
+ this.neighbors.put(neighbor, status);
|
||||
+ neighbor.setNeighborPriority(this, Math.max(1, priority));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
@ -286,7 +357,7 @@ index 9e95c6b54f0855ddde6db6bd3e768e87fee6c21a..44721a4f446bdd5bf4575e4168a0570a
|
||||
|
||||
public PlayerChunk(ChunkCoordIntPair chunkcoordintpair, int i, LightEngine lightengine, PlayerChunk.c playerchunk_c, PlayerChunk.d playerchunk_d) {
|
||||
this.statusFutures = new AtomicReferenceArray(PlayerChunk.CHUNK_STATUSES.size());
|
||||
@@ -166,6 +252,12 @@ public class PlayerChunk {
|
||||
@@ -165,6 +252,12 @@ public class PlayerChunk {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -299,26 +370,15 @@ index 9e95c6b54f0855ddde6db6bd3e768e87fee6c21a..44721a4f446bdd5bf4575e4168a0570a
|
||||
// Paper end
|
||||
|
||||
public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> getStatusFutureUnchecked(ChunkStatus chunkstatus) {
|
||||
@@ -419,8 +511,18 @@ public class PlayerChunk {
|
||||
@@ -418,6 +511,7 @@ public class PlayerChunk {
|
||||
return this.n;
|
||||
}
|
||||
|
||||
+ private void setPriority(int i) { d(i); } // Paper - OBFHELPER
|
||||
private void d(int i) {
|
||||
+ if (i == n) return; // Paper
|
||||
this.n = i;
|
||||
+ // Paper start
|
||||
+ this.neighbors.keySet().forEach(neighbor -> {
|
||||
+ if (neighbor.getCurrentPriority() > i) {
|
||||
+ neighbor.setNeighborPriority(this, i);
|
||||
+ this.w.changePriority(neighbor.location, neighbor::getCurrentPriority, neighbor.getCurrentPriority(), neighbor::setPriority);
|
||||
+ }
|
||||
+ });
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public void a(int i) {
|
||||
@@ -508,6 +610,7 @@ public class PlayerChunk {
|
||||
@@ -507,6 +601,7 @@ public class PlayerChunk {
|
||||
Chunk fullChunk = either.left().get();
|
||||
PlayerChunk.this.isFullChunkReady = true;
|
||||
fullChunk.playerChunk = PlayerChunk.this;
|
||||
@ -326,16 +386,40 @@ index 9e95c6b54f0855ddde6db6bd3e768e87fee6c21a..44721a4f446bdd5bf4575e4168a0570a
|
||||
|
||||
|
||||
}
|
||||
@@ -583,7 +686,7 @@ public class PlayerChunk {
|
||||
@@ -581,8 +676,30 @@ public class PlayerChunk {
|
||||
this.entityTickingFuture.complete(PlayerChunk.UNLOADED_CHUNK); this.isEntityTickingReady = false; // Paper - cache chunk ticking stage
|
||||
this.entityTickingFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE;
|
||||
}
|
||||
|
||||
-
|
||||
- this.w.a(this.location, this::k, this.ticketLevel, this::d);
|
||||
+ this.w.a(this.location, this::k, getPreferredPriority(), this::d); // Paper - preferred priority
|
||||
+ // Paper start - raise IO/load priority if priority changes, use our preferred priority
|
||||
+ int priority = getPreferredPriority();
|
||||
+ if (getCurrentPriority() > priority) {
|
||||
+ int ioPriority = com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY;
|
||||
+ if (priority <= 10) {
|
||||
+ ioPriority = com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGHEST_PRIORITY;
|
||||
+ } else if (priority <= 20) {
|
||||
+ ioPriority = com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGH_PRIORITY;
|
||||
+ }
|
||||
+ chunkMap.world.asyncChunkTaskManager.raisePriority(location.x, location.z, ioPriority);
|
||||
+ }
|
||||
+ this.w.a(this.location, this::getCurrentPriority, priority, this::setPriority); // use preferred priority
|
||||
+ this.neighbors.forEach((neighbor, neighborDesired) -> {
|
||||
+ ChunkStatus neighborCurrent = neighbor.getChunkHolderStatus();
|
||||
+ if (neighborCurrent == null || !neighborCurrent.isAtLeastStatus(neighborDesired)) {
|
||||
+ if (neighbor.getCurrentPriority() > priority + 1 && neighbor.neighborPriority > priority + 1) {
|
||||
+ neighbor.setNeighborPriority(this, priority + 1);
|
||||
+ // Pending chunk update will run this same code here for the neighbor to update their priority
|
||||
+ // And since we are in the poll loop when this method runs, it should happen immediately after this.
|
||||
+ chunkMap.chunkDistanceManager.pendingChunkUpdates.add(neighbor);
|
||||
+ }
|
||||
+ }
|
||||
+ });
|
||||
+ // Paper end
|
||||
this.oldTicketLevel = this.ticketLevel;
|
||||
// CraftBukkit start
|
||||
// ChunkLoadEvent: Called after the chunk is loaded: isChunkLoaded returns true and chunk is ready to be modified by plugins.
|
||||
@@ -670,6 +773,7 @@ public class PlayerChunk {
|
||||
@@ -669,6 +786,7 @@ public class PlayerChunk {
|
||||
|
||||
public interface c {
|
||||
|
||||
@ -489,6 +573,26 @@ index e772095e1c44842f743661a326c2a9a8a677ab02..5621416660d2722f26582fcecd5b61a1
|
||||
});
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/Ticket.java b/src/main/java/net/minecraft/server/Ticket.java
|
||||
index 7a8397815a5b7f79f3e3a0348aeedf63fe879f8f..a7cd67b0d5e49a4492dc14ec80e442a0f32671d3 100644
|
||||
--- a/src/main/java/net/minecraft/server/Ticket.java
|
||||
+++ b/src/main/java/net/minecraft/server/Ticket.java
|
||||
@@ -8,6 +8,7 @@ public final class Ticket<T> implements Comparable<Ticket<?>> {
|
||||
private final int b;
|
||||
public final T identifier; public final T getObjectReason() { return this.identifier; } // Paper - OBFHELPER
|
||||
private long d; public final long getCreationTick() { return this.d; } // Paper - OBFHELPER
|
||||
+ public int priority = 0; // Paper
|
||||
|
||||
protected Ticket(TicketType<T> tickettype, int i, T t0) {
|
||||
this.a = tickettype;
|
||||
@@ -56,6 +57,7 @@ public final class Ticket<T> implements Comparable<Ticket<?>> {
|
||||
return this.b;
|
||||
}
|
||||
|
||||
+ protected final void setCurrentTick(long i) { a(i); } // Paper - OBFHELPER
|
||||
protected void a(long i) {
|
||||
this.d = i;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/TicketType.java b/src/main/java/net/minecraft/server/TicketType.java
|
||||
index 8055f5998213ab1c6c10d03d88d2b14d220a5e40..4913205c15a2b6d5ea058890b02090b494e9c177 100644
|
||||
--- a/src/main/java/net/minecraft/server/TicketType.java
|
||||
|
Loading…
Reference in New Issue
Block a user