Update Tuinity patches

This commit is contained in:
William Blake Galbreath
2020-03-19 18:24:21 -05:00
parent 7273589372
commit 66f4378995
3 changed files with 205 additions and 234 deletions

View File

@@ -1,4 +1,4 @@
From b723fbb203556bc1025da7a7a88c11475102daa7 Mon Sep 17 00:00:00 2001
From cae53f41f02d848e12a4077faf88bfc495553350 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Fri, 14 Dec 2018 21:53:58 -0800
Subject: [PATCH] Tuinity Server Patches
@@ -12,7 +12,7 @@ Subject: [PATCH] Tuinity Server Patches
.../tuinity/chunk/ChunkRegionManager.java | 165 +++
.../chunk/QueuedChangesMapLong2Int.java | 155 +++
.../chunk/QueuedChangesMapLong2Object.java | 170 +++
.../tuinity/tuinity/config/TuinityConfig.java | 257 +++++
.../tuinity/tuinity/config/TuinityConfig.java | 253 +++++
.../server/TickListServerInterval.java | 42 +
.../tuinity/server/TuinityTickList.java | 614 +++++++++++
.../com/tuinity/tuinity/util/ChunkList.java | 119 +++
@@ -36,17 +36,17 @@ Subject: [PATCH] Tuinity Server Patches
.../net/minecraft/server/AxisAlignedBB.java | 2 +
src/main/java/net/minecraft/server/Chunk.java | 135 +++
.../java/net/minecraft/server/ChunkMap.java | 15 +-
.../minecraft/server/ChunkMapDistance.java | 387 ++++++-
.../minecraft/server/ChunkProviderServer.java | 182 +++-
.../minecraft/server/ChunkMapDistance.java | 401 ++++++-
.../minecraft/server/ChunkProviderServer.java | 141 ++-
.../minecraft/server/ChunkRegionLoader.java | 12 +-
.../net/minecraft/server/ChunkStatus.java | 5 +-
.../net/minecraft/server/ChunkStatus.java | 4 +-
.../net/minecraft/server/DedicatedServer.java | 3 +-
.../minecraft/server/DoubleListOffset.java | 2 +-
src/main/java/net/minecraft/server/EULA.java | 2 +-
.../java/net/minecraft/server/Entity.java | 100 ++
.../minecraft/server/EntityEnderDragon.java | 4 +-
.../minecraft/server/EntityInsentient.java | 19 +-
.../net/minecraft/server/EntityPlayer.java | 45 +-
.../net/minecraft/server/EntityPlayer.java | 43 +-
.../minecraft/server/EntityTrackerEntry.java | 41 +-
.../net/minecraft/server/EntityWither.java | 4 +-
.../java/net/minecraft/server/HeightMap.java | 5 +-
@@ -71,13 +71,13 @@ Subject: [PATCH] Tuinity Server Patches
.../server/PathfinderGoalWrapped.java | 6 +-
.../minecraft/server/PathfinderNormal.java | 4 +-
.../server/PathfinderTargetCondition.java | 1 +
.../net/minecraft/server/PlayerChunk.java | 97 +-
.../net/minecraft/server/PlayerChunkMap.java | 995 +++++++++++++++---
.../net/minecraft/server/PlayerChunk.java | 94 +-
.../net/minecraft/server/PlayerChunkMap.java | 997 +++++++++++++++---
.../server/PlayerInteractManager.java | 45 +-
.../net/minecraft/server/PlayerInventory.java | 6 +-
.../java/net/minecraft/server/PlayerList.java | 6 +-
.../java/net/minecraft/server/ProtoChunk.java | 16 +-
.../java/net/minecraft/server/RegionFile.java | 420 +++++++-
.../java/net/minecraft/server/RegionFile.java | 468 +++++++-
.../minecraft/server/RegionFileBitSet.java | 26 +-
.../net/minecraft/server/RegionFileCache.java | 45 +-
.../server/RegionFileCompression.java | 7 +-
@@ -98,7 +98,7 @@ Subject: [PATCH] Tuinity Server Patches
.../craftbukkit/entity/CraftPlayer.java | 37 +-
.../java/org/spigotmc/ActivationRange.java | 41 +-
src/main/java/org/spigotmc/AsyncCatcher.java | 2 +-
94 files changed, 6965 insertions(+), 479 deletions(-)
94 files changed, 6980 insertions(+), 477 deletions(-)
create mode 100644 src/main/java/com/tuinity/tuinity/chunk/ChunkRegionManager.java
create mode 100644 src/main/java/com/tuinity/tuinity/chunk/QueuedChangesMapLong2Int.java
create mode 100644 src/main/java/com/tuinity/tuinity/chunk/QueuedChangesMapLong2Object.java
@@ -822,10 +822,10 @@ index 0000000000..e5bb56cca9
\ No newline at end of file
diff --git a/src/main/java/com/tuinity/tuinity/config/TuinityConfig.java b/src/main/java/com/tuinity/tuinity/config/TuinityConfig.java
new file mode 100644
index 0000000000..189f2f0468
index 0000000000..534a6bc7e6
--- /dev/null
+++ b/src/main/java/com/tuinity/tuinity/config/TuinityConfig.java
@@ -0,0 +1,257 @@
@@ -0,0 +1,253 @@
+package com.tuinity.tuinity.config;
+
+import ca.spottedleaf.concurrentutil.util.Throw;
@@ -936,25 +936,11 @@ index 0000000000..189f2f0468
+ tickThreads = TuinityConfig.getInt("server-tick-threads", 1); // will be 4 in the future
+ }*/
+
+ public static int delayChunkUnloadsBy;
+
+ private static void delayChunkUnloadsBy() {
+ delayChunkUnloadsBy = TuinityConfig.getInt("delay-chunkunloads-by", 10) * 20;
+ if (delayChunkUnloadsBy >= 0) {
+ TicketType.DELAYED_UNLOAD.loadPeriod = delayChunkUnloadsBy;
+ }
+ }
+
+ public static int maxChunkLoadsPerPlayer;
+ public static double maxChunkSendsPerPlayer; // per second
+
+ public static int[] maxChunkSendsPerPlayerChoice = new int[100];
+
+ private static void maxChunkLoadsPerPlayer() {
+ maxChunkLoadsPerPlayer = TuinityConfig.getInt("max-pending-chunk-tickets-per-player", 5);
+ if (maxChunkLoadsPerPlayer <= -1) {
+ maxChunkLoadsPerPlayer = Integer.MAX_VALUE;
+ }
+ maxChunkSendsPerPlayer = TuinityConfig.getDouble("target-chunk-sends-per-player-per-second", 40.0);
+ if (maxChunkSendsPerPlayer <= -1.0) {
+ maxChunkSendsPerPlayer = Integer.MAX_VALUE;
@@ -986,6 +972,16 @@ index 0000000000..189f2f0468
+ }
+ }
+
+ public static int delayChunkUnloadsBy;
+
+ private static void delayChunkUnloadsBy() {
+ delayChunkUnloadsBy = TuinityConfig.getInt("delay-chunkunloads-by", 10) * 20;
+ if (delayChunkUnloadsBy >= 0) {
+ TicketType.DELAYED_UNLOAD.loadPeriod = delayChunkUnloadsBy;
+ }
+ }
+
+
+ public static final class WorldConnfig {
+
+ public final String worldName;
@@ -4402,7 +4398,7 @@ index 55f9f4e6e7..d3c616e72d 100644
this.a(ChunkCoordIntPair.a, i, j, flag);
}
diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java
index 73d1570765..cb2e67d159 100644
index 73d1570765..6826c0369c 100644
--- a/src/main/java/net/minecraft/server/ChunkMapDistance.java
+++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java
@@ -1,5 +1,6 @@
@@ -4431,7 +4427,7 @@ index 73d1570765..cb2e67d159 100644
private final ChunkTaskQueueSorter i;
private final Mailbox<ChunkTaskQueueSorter.a<Runnable>> j;
private final Mailbox<ChunkTaskQueueSorter.b> k;
@@ -41,6 +42,96 @@ public abstract class ChunkMapDistance {
@@ -41,6 +42,110 @@ public abstract class ChunkMapDistance {
private final Executor m;
private long currentTick;
@@ -4460,28 +4456,42 @@ index 73d1570765..cb2e67d159 100644
+ }
+ };
+
+ protected final ChunkMapDistance.TicketTracker playerNoTickViewDistanceHandler = new TicketTracker(33) { // loaded ticket level
+ @Override
+ protected int tryQueueChunk(int chunkX, int chunkZ, EntityPlayer player) {
+ long coordinate = Util.getCoordinateKey(chunkX, chunkZ);
+ PlayerChunk currentChunk = ChunkMapDistance.this.chunkMap.chunkMap.getUpdating(coordinate);
+ if (currentChunk != null && currentChunk.getTicketLevel() <= this.ticketLevel) {
+ this.chunkReferenceMap.putIfAbsent(coordinate, LOADED_PLAYER_REFERENCE);
+ ChunkMapDistance.this.addTicket(coordinate, new Ticket<>(TicketType.PLAYER, this.ticketLevel, new ChunkCoordIntPair(chunkX, chunkZ)));
+ return ALREADY_QUEUED;
+ }
+ if (this.chunkReferenceMap.putIfAbsent(coordinate, player.getId()) == -1) {
+ ChunkMapDistance.this.addTicket(coordinate, new Ticket<>(TicketType.PLAYER, this.ticketLevel, new ChunkCoordIntPair(chunkX, chunkZ)));
+ return QUEUED;
+ }
+ return ALREADY_QUEUED;
+ }
+ // this is copied from ChunkMapDistance.a(long, int, boolean, boolean), TODO check on update
+ // this is invoked if and only if there are no other players in range of the chunk.
+ public void playerMoveInRange(final int chunkX, final int chunkZ, final int fromX, final int fromZ) {
+ final long coordinate = Util.getCoordinateKey(chunkX, chunkZ);
+
+ @Override
+ protected int getMaxChunkLoads(EntityPlayer player) {
+ return com.tuinity.tuinity.config.TuinityConfig.maxChunkLoadsPerPlayer; // per-player limits instead of global?
+ }
+ };
+ final int dist = Math.max(Math.abs(chunkX - fromX), Math.abs(chunkZ - fromZ));
+ Ticket<?> ticket = new Ticket<>(TicketType.PLAYER, 33, new ChunkCoordIntPair(chunkX, chunkZ));
+
+ ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { // Craftbukkit - decompile error
+ ChunkMapDistance.this.m.execute(() -> {
+ if (ChunkMapDistance.this.chunkMap.playerViewDistanceNoTickMap.getObjectsInRange(coordinate) != null) {
+ ChunkMapDistance.this.addTicket(coordinate, ticket);
+ ChunkMapDistance.this.l.add(coordinate);
+ } else {
+ ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> { // Craftbukkit - decompile error
+ }, coordinate, false));
+ }
+ });
+ }, coordinate, () -> {
+ return dist;
+ }));
+ }
+
+ // this is copied from ChunkMapDistance.a(long, int, boolean, boolean), TODO check on update
+ // this is invoked if and only if there are no other players in range of the chunk.
+ public void playerMoveOutOfRange(final int chunkX, final int chunkZ, final int fromX, final int fromZ) {
+ final long coordinate = Util.getCoordinateKey(chunkX, chunkZ);
+
+ Ticket<?> ticket = new Ticket<>(TicketType.PLAYER, 33, new ChunkCoordIntPair(chunkX, chunkZ));
+
+ ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> { // Craftbukkit - decompile error
+ ChunkMapDistance.this.m.execute(() -> {
+ ChunkMapDistance.this.removeTicket(coordinate, ticket);
+ });
+ }, coordinate, true));
+ }
+ // Tuinity end
+
+ // Tuinity start - delay chunk unloads
@@ -4528,7 +4538,7 @@ index 73d1570765..cb2e67d159 100644
protected ChunkMapDistance(Executor executor, Executor executor1) {
executor1.getClass();
Mailbox<Runnable> mailbox = Mailbox.a("player ticket throttler", executor1::execute);
@@ -53,15 +144,34 @@ public abstract class ChunkMapDistance {
@@ -53,15 +158,34 @@ public abstract class ChunkMapDistance {
}
protected void purgeTickets() {
@@ -4564,7 +4574,7 @@ index 73d1570765..cb2e67d159 100644
this.e.b(entry.getLongKey(), a((ArraySetSorted) entry.getValue()), false);
}
@@ -72,6 +182,7 @@ public abstract class ChunkMapDistance {
@@ -72,6 +196,7 @@ public abstract class ChunkMapDistance {
}
@@ -4572,7 +4582,7 @@ index 73d1570765..cb2e67d159 100644
private static int a(ArraySetSorted<Ticket<?>> arraysetsorted) {
return !arraysetsorted.isEmpty() ? ((Ticket) arraysetsorted.b()).b() : PlayerChunkMap.GOLDEN_TICKET + 1;
}
@@ -85,8 +196,8 @@ public abstract class ChunkMapDistance {
@@ -85,8 +210,8 @@ public abstract class ChunkMapDistance {
protected abstract PlayerChunk a(long i, int j, @Nullable PlayerChunk playerchunk, int k);
public boolean a(PlayerChunkMap playerchunkmap) {
@@ -4583,7 +4593,7 @@ index 73d1570765..cb2e67d159 100644
int i = Integer.MAX_VALUE - this.e.a(Integer.MAX_VALUE);
boolean flag = i != 0;
@@ -136,6 +247,7 @@ public abstract class ChunkMapDistance {
@@ -136,6 +261,7 @@ public abstract class ChunkMapDistance {
}
private boolean addTicket(long i, Ticket<?> ticket) { // CraftBukkit - void -> boolean
@@ -4591,7 +4601,7 @@ index 73d1570765..cb2e67d159 100644
ArraySetSorted<Ticket<?>> arraysetsorted = this.e(i);
int j = a(arraysetsorted);
Ticket<?> ticket1 = (Ticket) arraysetsorted.a(ticket); // CraftBukkit - decompile error
@@ -149,11 +261,17 @@ public abstract class ChunkMapDistance {
@@ -149,11 +275,17 @@ public abstract class ChunkMapDistance {
}
private boolean removeTicket(long i, Ticket<?> ticket) { // CraftBukkit - void -> boolean
@@ -4609,7 +4619,7 @@ index 73d1570765..cb2e67d159 100644
}
if (arraysetsorted.isEmpty()) {
@@ -197,6 +315,7 @@ public abstract class ChunkMapDistance {
@@ -197,6 +329,7 @@ public abstract class ChunkMapDistance {
}
private ArraySetSorted<Ticket<?>> e(long i) {
@@ -4617,7 +4627,7 @@ index 73d1570765..cb2e67d159 100644
return (ArraySetSorted) this.tickets.computeIfAbsent(i, (j) -> {
return ArraySetSorted.a(4);
});
@@ -214,24 +333,26 @@ public abstract class ChunkMapDistance {
@@ -214,24 +347,26 @@ public abstract class ChunkMapDistance {
}
public void a(SectionPosition sectionposition, EntityPlayer entityplayer) {
@@ -4648,7 +4658,7 @@ index 73d1570765..cb2e67d159 100644
}
}
@@ -249,18 +370,29 @@ public abstract class ChunkMapDistance {
@@ -249,18 +384,29 @@ public abstract class ChunkMapDistance {
return s;
}
@@ -4683,7 +4693,7 @@ index 73d1570765..cb2e67d159 100644
}
public String c() {
@@ -269,6 +401,7 @@ public abstract class ChunkMapDistance {
@@ -269,6 +415,7 @@ public abstract class ChunkMapDistance {
// CraftBukkit start
public <T> void removeAllTicketsFor(TicketType<T> ticketType, int ticketLevel, T ticketIdentifier) {
@@ -4691,7 +4701,7 @@ index 73d1570765..cb2e67d159 100644
Ticket<T> target = new Ticket<>(ticketType, ticketLevel, ticketIdentifier);
for (java.util.Iterator<ArraySetSorted<Ticket<?>>> iterator = this.tickets.values().iterator(); iterator.hasNext();) {
@@ -327,6 +460,222 @@ public abstract class ChunkMapDistance {
@@ -327,6 +474,222 @@ public abstract class ChunkMapDistance {
}
}
@@ -4914,7 +4924,7 @@ index 73d1570765..cb2e67d159 100644
class c extends ChunkMapDistance.b {
private int e = 0;
@@ -344,7 +693,7 @@ public abstract class ChunkMapDistance {
@@ -344,7 +707,7 @@ public abstract class ChunkMapDistance {
}
public void a(int i) {
@@ -4923,7 +4933,7 @@ index 73d1570765..cb2e67d159 100644
while (objectiterator.hasNext()) {
it.unimi.dsi.fastutil.longs.Long2ByteMap.Entry it_unimi_dsi_fastutil_longs_long2bytemap_entry = (it.unimi.dsi.fastutil.longs.Long2ByteMap.Entry) objectiterator.next();
@@ -425,7 +774,7 @@ public abstract class ChunkMapDistance {
@@ -425,7 +788,7 @@ public abstract class ChunkMapDistance {
class b extends ChunkMap {
@@ -4933,78 +4943,10 @@ index 73d1570765..cb2e67d159 100644
protected b(int i) {
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
index 1dcd0980ec..203719518e 100644
index 1dcd0980ec..c39029c3ad 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -126,7 +126,6 @@ public class ChunkProviderServer extends IChunkProvider {
}
// Paper end - rewrite ticklistserver
-
public ChunkProviderServer(WorldServer worldserver, File file, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, ChunkGenerator<?> chunkgenerator, int i, WorldLoadListener worldloadlistener, Supplier<WorldPersistentData> supplier) {
this.world = worldserver;
this.serverThreadQueue = new ChunkProviderServer.a(worldserver);
@@ -315,7 +314,16 @@ public class ChunkProviderServer extends IChunkProvider {
}
private void bringToStatusAsync(int x, int z, ChunkCoordIntPair chunkPos, ChunkStatus status, java.util.function.Consumer<IChunkAccess> onComplete) {
- CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> future = this.getChunkFutureMainThread(x, z, status, true);
+ // Tuinity start - add createFuture param
+ this.bringToStatusAsync(x, z, chunkPos, status, onComplete, true);
+ }
+ private void bringToStatusAsync(int x, int z, ChunkCoordIntPair chunkPos, ChunkStatus status, java.util.function.Consumer<IChunkAccess> onComplete, boolean createFuture) {
+ CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> future = this.getChunkFutureMainThread(x, z, status, createFuture);
+
+ if (future.isDone() && future.getNow(null).right().isPresent() && !createFuture) {
+ return;
+ }
+ // Tuinity end
Long identifier = Long.valueOf(this.asyncLoadSeqCounter++);
int ticketLevel = MCUtil.getTicketLevelFor(status);
this.addTicketAtLevel(TicketType.ASYNC_LOAD, chunkPos, ticketLevel, identifier);
@@ -357,9 +365,18 @@ public class ChunkProviderServer extends IChunkProvider {
public IChunkAccess getChunkAt(int i, int j, ChunkStatus chunkstatus, boolean flag) {
final int x = i; final int z = j; // Paper - conflict on variable change
if (Thread.currentThread() != this.serverThread) {
- return (IChunkAccess) CompletableFuture.supplyAsync(() -> {
- return this.getChunkAt(i, j, chunkstatus, flag);
- }, this.serverThreadQueue).join();
+ // Tuinity start - improve async access - prevents plugins from sync loading chunks
+ Chunk chunk = this.getChunkAtIfLoadedImmediately(x, z);
+ if (chunk != null) {
+ return chunk;
+ }
+
+ CompletableFuture<IChunkAccess> future = new CompletableFuture<>();
+ this.serverThreadQueue.execute(() -> {
+ this.bringToStatusAsync(x, z, new ChunkCoordIntPair(x, z), chunkstatus, future::complete, flag);
+ });
+ return future.join();
+ // Tuinity end
} else {
// Paper start - optimise for loaded chunks
Chunk ifLoaded = this.getChunkAtIfLoadedMainThread(i, j);
@@ -391,6 +408,19 @@ public class ChunkProviderServer extends IChunkProvider {
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
+ // Tuinity start - improve sync loading prioritisation
+ // lighting requires neighbours in a 1 radius to load
+ if (chunkstatus.isAtLeast(ChunkStatus.LIGHT)) {
+ for (int dx = -1; dx <= 1; ++dx) {
+ for (int dz = -1; dz <= 1; ++dz) {
+ int chunkLightX = dx + x;
+ int chunkLightZ = dz + z;
+ this.bringToStatusAsync(chunkLightX, chunkLightZ, new ChunkCoordIntPair(chunkLightX, chunkLightZ), ChunkStatus.LIGHT.getPreviousStatus(), (c) -> {});
+ this.world.asyncChunkTaskManager.raisePriority(chunkLightX, chunkLightZ, com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGHEST_PRIORITY);
+ }
+ }
+ }
+ // Tuinity end
com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.world, x, z); // Paper - sync load info
this.world.timings.chunkAwait.startTiming(); // Paper
this.serverThreadQueue.awaitTasks(completablefuture::isDone);
@@ -520,27 +550,39 @@ public class ChunkProviderServer extends IChunkProvider {
@@ -520,27 +520,39 @@ public class ChunkProviderServer extends IChunkProvider {
public final boolean isInEntityTickingChunk(Entity entity) { return this.a(entity); } // Paper - OBFHELPER
@Override public boolean a(Entity entity) {
@@ -5056,19 +4998,18 @@ index 1dcd0980ec..203719518e 100644
}
private boolean a(long i, Function<PlayerChunk, CompletableFuture<Either<Chunk, PlayerChunk.Failure>>> function) {
@@ -604,6 +646,11 @@ public class ChunkProviderServer extends IChunkProvider {
@@ -604,6 +616,10 @@ public class ChunkProviderServer extends IChunkProvider {
this.chunkMapDistance.purgeTickets();
this.tickDistanceManager();
this.world.timings.doChunkMap.stopTiming(); // Spigot
+ // Tuinity start
+ this.playerChunkMap.getChunkMapDistanceManager().playerNoTickViewDistanceHandler.tick();
+ this.playerChunkMap.getChunkMapDistanceManager().playerTickViewDistanceHandler.tick();
+ this.playerChunkMap.chunkSendThrottler.tick();
+ // Tuinity end
this.world.getMethodProfiler().exitEnter("chunks");
this.world.timings.chunks.startTiming(); // Paper - timings
this.tickChunks();
@@ -616,6 +663,12 @@ public class ChunkProviderServer extends IChunkProvider {
@@ -616,6 +632,12 @@ public class ChunkProviderServer extends IChunkProvider {
this.clearCache();
}
@@ -5081,7 +5022,7 @@ index 1dcd0980ec..203719518e 100644
private void tickChunks() {
long i = this.world.getTime();
long j = i - this.lastTickTime;
@@ -626,6 +679,36 @@ public class ChunkProviderServer extends IChunkProvider {
@@ -626,6 +648,36 @@ public class ChunkProviderServer extends IChunkProvider {
boolean flag1 = this.world.getGameRules().getBoolean(GameRules.DO_MOB_SPAWNING) && !world.getPlayers().isEmpty(); // CraftBukkit
if (!flag) {
@@ -5118,7 +5059,7 @@ index 1dcd0980ec..203719518e 100644
this.world.getMethodProfiler().enter("pollingChunks");
int k = this.world.getGameRules().getInt(GameRules.RANDOM_TICK_SPEED);
BlockPosition blockposition = this.world.getSpawn();
@@ -643,11 +726,10 @@ public class ChunkProviderServer extends IChunkProvider {
@@ -643,11 +695,10 @@ public class ChunkProviderServer extends IChunkProvider {
EnumCreatureType[] aenumcreaturetype = EnumCreatureType.values();
// Paper start - per player mob spawning
int[] worldMobCount;
@@ -5133,7 +5074,7 @@ index 1dcd0980ec..203719518e 100644
// re-set mob counts
for (EntityPlayer player : this.world.players) {
Arrays.fill(player.mobCounts, 0);
@@ -660,20 +742,13 @@ public class ChunkProviderServer extends IChunkProvider {
@@ -660,20 +711,13 @@ public class ChunkProviderServer extends IChunkProvider {
this.world.timings.countNaturalMobs.stopTiming(); // Paper - timings
this.world.getMethodProfiler().exit();
@@ -5161,7 +5102,7 @@ index 1dcd0980ec..203719518e 100644
this.world.getMethodProfiler().enter("broadcast");
this.world.timings.broadcastChunkUpdates.startTiming(); // Paper - timings
@@ -682,10 +757,10 @@ public class ChunkProviderServer extends IChunkProvider {
@@ -682,10 +726,10 @@ public class ChunkProviderServer extends IChunkProvider {
this.world.getMethodProfiler().exit();
ChunkCoordIntPair chunkcoordintpair = playerchunk.i();
@@ -5174,7 +5115,7 @@ index 1dcd0980ec..203719518e 100644
this.world.getMethodProfiler().enter("spawner");
this.world.timings.mobSpawn.startTiming(); // Spigot
EnumCreatureType[] aenumcreaturetype1 = aenumcreaturetype;
@@ -730,9 +805,23 @@ public class ChunkProviderServer extends IChunkProvider {
@@ -730,9 +774,23 @@ public class ChunkProviderServer extends IChunkProvider {
if (this.world.paperConfig.perPlayerMobSpawns) {
int minDiff = Integer.MAX_VALUE;
@@ -5199,7 +5140,7 @@ index 1dcd0980ec..203719518e 100644
difference = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff;
}
@@ -754,7 +843,22 @@ public class ChunkProviderServer extends IChunkProvider {
@@ -754,7 +812,22 @@ public class ChunkProviderServer extends IChunkProvider {
this.world.timings.chunkTicks.stopTiming(); // Spigot // Paper
}
}
@@ -5256,7 +5197,7 @@ index 4349d22cc8..d529b795c5 100644
nbttagcompound1.setString("Status", ichunkaccess.getChunkStatus().d());
ChunkConverter chunkconverter = ichunkaccess.p();
diff --git a/src/main/java/net/minecraft/server/ChunkStatus.java b/src/main/java/net/minecraft/server/ChunkStatus.java
index 88f1674616..fd7b10429d 100644
index 88f1674616..25654520e7 100644
--- a/src/main/java/net/minecraft/server/ChunkStatus.java
+++ b/src/main/java/net/minecraft/server/ChunkStatus.java
@@ -103,7 +103,7 @@ public class ChunkStatus {
@@ -5277,14 +5218,6 @@ index 88f1674616..fd7b10429d 100644
this.t = chunkstatus == null ? 0 : chunkstatus.c() + 1;
}
@@ -217,6 +217,7 @@ public class ChunkStatus {
return this.z;
}
+ public final boolean isAtLeast(ChunkStatus status) { return this.b(status); } // Tuinity - OBFHELPER
public boolean b(ChunkStatus chunkstatus) {
return this.c() >= chunkstatus.c();
}
diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java
index 349a0ea213..ede4369399 100644
--- a/src/main/java/net/minecraft/server/DedicatedServer.java
@@ -5505,7 +5438,7 @@ index 1991cee43d..27ef476001 100644
} else {
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index e7bfbc3307..fc185136fb 100644
index e7bfbc3307..d49c45ce7f 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -104,6 +104,39 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
@@ -5558,11 +5491,7 @@ index e7bfbc3307..fc185136fb 100644
}
// Yes, this doesn't match Vanilla, but it's the best we can do for now.
@@ -1770,11 +1806,18 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
public void a(ChunkCoordIntPair chunkcoordintpair, Packet<?> packet, Packet<?> packet1) {
this.playerConnection.sendPacket(packet1);
this.playerConnection.sendPacket(packet);
+ this.loadedChunks.add(com.tuinity.tuinity.util.Util.getCoordinateKey(chunkcoordintpair)); // Tuinity - rate limit chunk sending
@@ -1773,8 +1809,13 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
public void a(ChunkCoordIntPair chunkcoordintpair) {
@@ -5573,7 +5502,6 @@ index e7bfbc3307..fc185136fb 100644
+ // Tuinity end - remove ChunkCoordIntPair allocation
if (this.isAlive()) {
- this.playerConnection.sendPacket(new PacketPlayOutUnloadChunk(chunkcoordintpair.x, chunkcoordintpair.z));
+ this.loadedChunks.remove(com.tuinity.tuinity.util.Util.getCoordinateKey(x, z)); // Tuinity - rate limit chunk sending
+ this.playerConnection.sendPacket(new PacketPlayOutUnloadChunk(x, z)); // Tuinity
}
@@ -6751,7 +6679,7 @@ index e35ec2db07..e7dfe22acd 100644
if (entityliving == entityliving1) {
return false;
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
index 9f8818c2d4..0e24f4e7a1 100644
index 9f8818c2d4..cc5ae6eef4 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 {
@@ -6860,17 +6788,7 @@ index 9f8818c2d4..0e24f4e7a1 100644
}
public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> a(ChunkStatus chunkstatus, PlayerChunkMap playerchunkmap) {
@@ -445,6 +506,9 @@ public class PlayerChunk {
fullChunk.playerChunk = PlayerChunk.this;
+ // Tuinity start - per player view distance implementation
+ PlayerChunk.this.chunkMap.getChunkMapDistanceManager().playerNoTickViewDistanceHandler.onChunkLoad(this.location.x, this.location.z);
+ // Tuinity end - per player view distance implementation
}
});
// Paper end
@@ -505,8 +569,19 @@ public class PlayerChunk {
@@ -505,8 +566,19 @@ public class PlayerChunk {
PlayerChunk.this.isEntityTickingReady = true;
@@ -6890,7 +6808,7 @@ index 9f8818c2d4..0e24f4e7a1 100644
}
});
// Paper end
@@ -515,6 +590,18 @@ public class PlayerChunk {
@@ -515,6 +587,18 @@ public class PlayerChunk {
if (flag6 && !flag7) {
this.entityTickingFuture.complete(PlayerChunk.UNLOADED_CHUNK); this.isEntityTickingReady = false; // Paper - cache chunk ticking stage
@@ -6910,7 +6828,7 @@ index 9f8818c2d4..0e24f4e7a1 100644
}
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 57bea926a6..1504094369 100644
index 57bea926a6..9346a2c292 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -55,8 +55,9 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -7230,7 +7148,7 @@ index 57bea926a6..1504094369 100644
void addPlayerToDistanceMaps(EntityPlayer player) {
this.updateMaps(player);
@@ -134,10 +422,91 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -134,10 +422,89 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
// Paper end
@@ -7243,7 +7161,6 @@ index 57bea926a6..1504094369 100644
+
+ // Tuinity start - per player view distance
+ this.getChunkMapDistanceManager().playerTickViewDistanceHandler.addPlayer(player);
+ this.getChunkMapDistanceManager().playerNoTickViewDistanceHandler.addPlayer(player);
+ this.chunkSendThrottler.addPlayer(player);
+ // Tuinity end - per player view distance
+ }
@@ -7255,7 +7172,6 @@ index 57bea926a6..1504094369 100644
+ this.playerViewDistanceTickMap.remove(player);
+ this.playerViewDistanceNoTickMap.remove(player);
+ this.getChunkMapDistanceManager().playerTickViewDistanceHandler.removePlayer(player);
+ this.getChunkMapDistanceManager().playerNoTickViewDistanceHandler.removePlayer(player);
+ this.chunkSendThrottler.removePlayer(player);
+ // Tuinity end - per player view distance
+
@@ -7323,7 +7239,7 @@ index 57bea926a6..1504094369 100644
this.pendingUnload = new Long2ObjectLinkedOpenHashMap();
this.loadedChunks = new LongOpenHashSet();
this.unloadQueue = new LongOpenHashSet();
@@ -166,7 +535,155 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -166,7 +533,159 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
this.l = supplier;
this.m = new VillagePlace(new File(this.w, "poi"), datafixer, this.world); // Paper
this.setViewDistance(i);
@@ -7346,16 +7262,20 @@ index 57bea926a6..1504094369 100644
+ });
+ this.chunkDistanceManager.playerTickViewDistanceHandler.areaMap = this.playerViewDistanceTickMap;
+ this.playerViewDistanceNoTickMap = new com.tuinity.tuinity.util.map.PlayerAreaMap(sets,
+ null,
+ (EntityPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ,
+ com.tuinity.tuinity.util.map.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<EntityPlayer> newState) -> {
+ if (newState.size() != 1) {
+ return;
+ }
+ PlayerChunkMap.this.chunkDistanceManager.playerMoveInRange(rangeX, rangeZ, currPosX, currPosZ);
+ },
+ (EntityPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ,
+ com.tuinity.tuinity.util.map.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<EntityPlayer> newState) -> {
+ if (newState != null) {
+ return;
+ }
+ PlayerChunkMap.this.chunkDistanceManager.playerNoTickViewDistanceHandler.playerMoveOutOfRange(rangeX, rangeZ);
+ PlayerChunkMap.this.chunkDistanceManager.playerMoveOutOfRange(rangeX, rangeZ, currPosX, currPosZ);
+ });
+ this.chunkDistanceManager.playerNoTickViewDistanceHandler.areaMap = this.playerViewDistanceNoTickMap;
+ final Packet[] tempPacket = new Packet[2];
+ this.playerViewDistanceBroadcastMap = new com.tuinity.tuinity.util.map.PlayerAreaMap(sets,
+ (EntityPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ,
+ com.tuinity.tuinity.util.map.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<EntityPlayer> newState) -> {
@@ -7366,8 +7286,8 @@ index 57bea926a6..1504094369 100644
+ },
+ (EntityPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ,
+ com.tuinity.tuinity.util.map.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<EntityPlayer> newState) -> {
+ PlayerChunkMap.this.sendChunk(player, rangeX, rangeZ, tempPacket, true, false); // unloaded, loaded
+ java.util.Arrays.fill(tempPacket, null);
+ PlayerChunkMap.this.sendChunk(player, rangeX, rangeZ, null, true, false); // unloaded, loaded
+ player.loadedChunks.remove(com.tuinity.tuinity.util.Util.getCoordinateKey(rangeX, rangeZ));
+ });
+ // Tuinity end - per player view distance
+
@@ -7480,7 +7400,7 @@ index 57bea926a6..1504094369 100644
}
public void updatePlayerMobTypeMap(Entity entity) {
@@ -177,15 +694,30 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -177,15 +696,30 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
int chunkZ = (int)Math.floor(entity.locZ()) >> 4;
int index = entity.getEntityType().getEnumCreatureType().ordinal();
@@ -7512,7 +7432,7 @@ index 57bea926a6..1504094369 100644
private static double a(ChunkCoordIntPair chunkcoordintpair, Entity entity) {
double d0 = (double) (chunkcoordintpair.x * 16 + 8);
double d1 = (double) (chunkcoordintpair.z * 16 + 8);
@@ -213,8 +745,13 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -213,8 +747,13 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
private static int a(ChunkCoordIntPair chunkcoordintpair, int i, int j) {
@@ -7528,7 +7448,7 @@ index 57bea926a6..1504094369 100644
return Math.max(Math.abs(k), Math.abs(l));
}
@@ -225,12 +762,17 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -225,12 +764,17 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@Nullable
protected PlayerChunk getUpdatingChunk(long i) {
@@ -7548,7 +7468,7 @@ index 57bea926a6..1504094369 100644
}
protected IntSupplier c(long i) {
@@ -308,6 +850,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -308,6 +852,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@Nullable
private PlayerChunk a(long i, int j, @Nullable PlayerChunk playerchunk, int k) {
@@ -7556,7 +7476,7 @@ index 57bea926a6..1504094369 100644
if (k > PlayerChunkMap.GOLDEN_TICKET && j > PlayerChunkMap.GOLDEN_TICKET) {
return playerchunk;
} else {
@@ -327,11 +870,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -327,11 +872,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
playerchunk = (PlayerChunk) this.pendingUnload.remove(i);
if (playerchunk != null) {
playerchunk.a(j);
@@ -7570,7 +7490,7 @@ index 57bea926a6..1504094369 100644
this.updatingChunksModified = true;
}
@@ -411,7 +955,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -411,7 +957,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
protected void save(boolean flag) {
if (flag) {
@@ -7579,7 +7499,7 @@ index 57bea926a6..1504094369 100644
MutableBoolean mutableboolean = new MutableBoolean();
do {
@@ -439,7 +983,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -439,7 +985,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
// this.i(); // Paper - nuke IOWorker
PlayerChunkMap.LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", this.w.getName());
} else {
@@ -7588,7 +7508,7 @@ index 57bea926a6..1504094369 100644
IChunkAccess ichunkaccess = (IChunkAccess) playerchunk.getChunkSave().getNow(null); // CraftBukkit - decompile error
if (ichunkaccess instanceof ProtoChunkExtension || ichunkaccess instanceof Chunk) {
@@ -482,7 +1026,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -482,7 +1028,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
while (longiterator.hasNext()) { // Spigot
long j = longiterator.nextLong();
longiterator.remove(); // Spigot
@@ -7597,7 +7517,7 @@ index 57bea926a6..1504094369 100644
if (playerchunk != null) {
this.pendingUnload.put(j, playerchunk);
@@ -610,7 +1154,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -610,7 +1156,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
if (!this.updatingChunksModified) {
return false;
} else {
@@ -7606,7 +7526,7 @@ index 57bea926a6..1504094369 100644
this.updatingChunksModified = false;
return true;
}
@@ -903,11 +1447,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -903,11 +1449,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
completablefuture1.thenAcceptAsync((either) -> {
either.mapLeft((chunk) -> {
this.u.getAndIncrement();
@@ -7619,7 +7539,7 @@ index 57bea926a6..1504094369 100644
return Either.left(chunk);
});
}, (runnable) -> {
@@ -1011,58 +1551,70 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1011,58 +1553,70 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
} // Paper
}
@@ -7711,7 +7631,7 @@ index 57bea926a6..1504094369 100644
}
protected PlayerChunkMap.a e() {
@@ -1070,12 +1622,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1070,12 +1624,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
protected Iterable<PlayerChunk> f() {
@@ -7726,7 +7646,7 @@ index 57bea926a6..1504094369 100644
while (objectbidirectionaliterator.hasNext()) {
Entry<PlayerChunk> entry = (Entry) objectbidirectionaliterator.next();
@@ -1265,31 +1817,53 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1265,31 +1819,53 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
return isOutsideOfRange(chunkcoordintpair, false);
}
@@ -7800,7 +7720,7 @@ index 57bea926a6..1504094369 100644
private boolean b(EntityPlayer entityplayer) {
return entityplayer.isSpectator() && !this.world.getGameRules().getBoolean(GameRules.SPECTATORS_GENERATE_CHUNKS);
}
@@ -1315,13 +1889,11 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1315,13 +1891,11 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
}
@@ -7818,7 +7738,7 @@ index 57bea926a6..1504094369 100644
}
@@ -1329,11 +1901,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1329,11 +1903,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
SectionPosition sectionposition = SectionPosition.a((Entity) entityplayer);
entityplayer.a(sectionposition);
@@ -7832,7 +7752,7 @@ index 57bea926a6..1504094369 100644
ObjectIterator objectiterator = this.trackedEntities.values().iterator();
while (objectiterator.hasNext()) {
@@ -1345,6 +1918,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1345,6 +1920,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
playerchunkmap_entitytracker.updatePlayer(entityplayer);
}
}
@@ -7840,7 +7760,7 @@ index 57bea926a6..1504094369 100644
int i = MathHelper.floor(entityplayer.locX()) >> 4;
int j = MathHelper.floor(entityplayer.locZ()) >> 4;
@@ -1384,56 +1958,53 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1384,56 +1960,53 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
int k1;
int l1;
@@ -7935,7 +7855,7 @@ index 57bea926a6..1504094369 100644
}
protected void addEntity(Entity entity) {
@@ -1452,11 +2023,36 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1452,11 +2025,36 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker
this.trackedEntities.put(entity.getId(), playerchunkmap_entitytracker);
@@ -7972,7 +7892,7 @@ index 57bea926a6..1504094369 100644
ObjectIterator objectiterator = this.trackedEntities.values().iterator();
while (objectiterator.hasNext()) {
@@ -1466,6 +2062,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1466,6 +2064,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
playerchunkmap_entitytracker1.updatePlayer(entityplayer);
}
}
@@ -7980,7 +7900,7 @@ index 57bea926a6..1504094369 100644
}
}
@@ -1494,9 +2091,102 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1494,9 +2093,102 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
playerchunkmap_entitytracker1.a();
}
entity.tracker = null; // Paper - We're no longer tracked
@@ -8083,7 +8003,7 @@ index 57bea926a6..1504094369 100644
List<EntityPlayer> list = Lists.newArrayList();
List<EntityPlayer> list1 = this.world.getPlayers();
@@ -1554,6 +2244,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1554,6 +2246,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
@@ -8091,7 +8011,7 @@ index 57bea926a6..1504094369 100644
private void a(EntityPlayer entityplayer, Packet<?>[] apacket, Chunk chunk) {
if (apacket[0] == null) {
apacket[0] = new PacketPlayOutMapChunk(chunk, 65535, true); // Paper - Anti-Xray
@@ -1564,6 +2255,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1564,6 +2257,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
PacketDebug.a(this.world, chunk.getPos());
List<Entity> list = Lists.newArrayList();
List<Entity> list1 = Lists.newArrayList();
@@ -8099,7 +8019,7 @@ index 57bea926a6..1504094369 100644
ObjectIterator objectiterator = this.trackedEntities.values().iterator();
while (objectiterator.hasNext()) {
@@ -1581,6 +2273,32 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1581,6 +2275,32 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
}
}
@@ -8132,7 +8052,7 @@ index 57bea926a6..1504094369 100644
Iterator iterator;
Entity entity1;
@@ -1618,7 +2336,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1618,7 +2338,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
public class EntityTracker {
@@ -8141,7 +8061,7 @@ index 57bea926a6..1504094369 100644
private final Entity tracker;
private final int trackingDistance;
private SectionPosition e;
@@ -1684,10 +2402,13 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1684,10 +2404,13 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
public void updatePlayer(EntityPlayer entityplayer) {
org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot
if (entityplayer != this.tracker) {
@@ -8159,7 +8079,7 @@ index 57bea926a6..1504094369 100644
if (flag) {
boolean flag1 = this.tracker.attachedToPlayer;
@@ -1696,7 +2417,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1696,7 +2419,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
PlayerChunk playerchunk = PlayerChunkMap.this.getVisibleChunk(chunkcoordintpair.pair());
if (playerchunk != null && playerchunk.getChunk() != null) {
@@ -8168,7 +8088,7 @@ index 57bea926a6..1504094369 100644
}
}
@@ -1738,6 +2459,44 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1738,6 +2461,44 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
return i;
}
@@ -8423,10 +8343,10 @@ index f376e21068..5a883aac14 100644
}
diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java
index df728e2c0a..5bd7b8f553 100644
index df728e2c0a..99eb8bb059 100644
--- a/src/main/java/net/minecraft/server/RegionFile.java
+++ b/src/main/java/net/minecraft/server/RegionFile.java
@@ -28,14 +28,342 @@ public class RegionFile implements AutoCloseable {
@@ -28,14 +28,349 @@ public class RegionFile implements AutoCloseable {
private static final Logger LOGGER = LogManager.getLogger();
private static final ByteBuffer b = ByteBuffer.allocateDirect(1);
private final FileChannel dataFile;
@@ -8499,6 +8419,22 @@ index df728e2c0a..5bd7b8f553 100644
+ return length.getInt(0);
+ }
+
+ private void backupRegionFile() {
+ File backup = new File(this.file.getParent(), this.file.getName() + "." + new java.util.Random().nextLong() + ".backup");
+ this.backupRegionFile(backup);
+ }
+
+ private void backupRegionFile(File to) {
+ try {
+ this.dataFile.force(true);
+ MinecraftServer.LOGGER.warn("Backing up regionfile \"" + this.file.getAbsolutePath() + "\" to " + to.getAbsolutePath());
+ java.nio.file.Files.copy(this.file.toPath(), to.toPath());
+ MinecraftServer.LOGGER.warn("Backed up the regionfile to " + to.getAbsolutePath());
+ } catch (IOException ex) {
+ MinecraftServer.LOGGER.error("Failed to backup to " + to.getAbsolutePath(), ex);
+ }
+ }
+
+ // note: only call for CHUNK regionfiles
+ void recalculateHeader() throws IOException {
+ if (!this.canRecalcHeader) {
@@ -8509,16 +8445,7 @@ index df728e2c0a..5bd7b8f553 100644
+
+ // try to backup file so maybe it could be sent to us for further investigation
+
+ File backup = new File(this.file.getParent(), this.file.getName() + "." + new java.util.Random().nextLong() + ".backup");
+ try {
+ this.dataFile.force(true);
+ MinecraftServer.LOGGER.warn("Backing up to " + backup.getAbsolutePath());
+ java.nio.file.Files.copy(this.file.toPath(), backup.toPath());
+ MinecraftServer.LOGGER.warn("Backed up the regionfile " + backup.getAbsolutePath());
+ } catch (IOException ex) {
+ MinecraftServer.LOGGER.error("Failed to backup to " + backup.getAbsolutePath(), ex);
+ }
+
+ this.backupRegionFile();
+ NBTTagCompound[] compounds = new NBTTagCompound[32 * 32]; // only in the regionfile (i.e exclude mojang/aikar oversized data)
+ int[] rawLengths = new int[32 * 32]; // length of chunk data including 4 byte length field, bytes
+ int[] sectorOffsets = new int[32 * 32]; // in sectors
@@ -8634,7 +8561,7 @@ index df728e2c0a..5bd7b8f553 100644
+ continue;
+ }
+
+ if (compounds[location] != null && ChunkRegionLoader.getLastWorldSaveTime(compound) > ChunkRegionLoader.getLastWorldSaveTime(compounds[location])) {
+ if (compounds[location] == null || ChunkRegionLoader.getLastWorldSaveTime(compound) > ChunkRegionLoader.getLastWorldSaveTime(compounds[location])) {
+ oversized[location] = true;
+ oversizedCompressionTypes[location] = compression;
+ }
@@ -8773,7 +8700,7 @@ index df728e2c0a..5bd7b8f553 100644
public final java.util.concurrent.locks.ReentrantLock fileLock = new java.util.concurrent.locks.ReentrantLock(true); // Paper
// Paper start - Cache chunk status
@@ -63,10 +391,21 @@ public class RegionFile implements AutoCloseable {
@@ -63,10 +398,21 @@ public class RegionFile implements AutoCloseable {
// Paper end
public RegionFile(File file, File file1) throws IOException {
@@ -8796,27 +8723,71 @@ index df728e2c0a..5bd7b8f553 100644
this.file = java_nio_file_path.toFile(); // Paper
this.f = ByteBuffer.allocateDirect(8192);
initOversizedState();
@@ -90,6 +429,8 @@ public class RegionFile implements AutoCloseable {
@@ -90,12 +436,15 @@ public class RegionFile implements AutoCloseable {
RegionFile.LOGGER.warn("Region file {} has truncated header: {}", java_nio_file_path, i);
}
+ boolean needsHeaderRecalc = false; // Tuinity - recalculate header on header corruption
- for (int j = 0; j < 1024; ++j) {
+ boolean needsHeaderRecalc = false; // Tuinity - recalculate header on header corruption
+ boolean hasBackedUp = false; // Tuinity - recalculate header on header corruption
+
for (int j = 0; j < 1024; ++j) {
+ for (int j = 0; j < 1024; ++j) { // Tuinity - diff on change, we expect j to be the header location
int k = this.g.get(j);
@@ -105,20 +446,53 @@ public class RegionFile implements AutoCloseable {
if (k != 0) {
- int l = b(k);
- int i1 = a(k);
+ int l = b(k); // Tuinity - diff on change, we expect l to be offset in file
+ int i1 = a(k); // Tuinity - diff on change, we expect i1 to be sector length of region
// Spigot start
if (i1 == 255) {
// We're maxed out, so we need to read the proper length from the section
@@ -105,20 +454,87 @@ public class RegionFile implements AutoCloseable {
}
// Spigot end
- this.freeSectors.a(l, i1);
+ needsHeaderRecalc |= !this.freeSectors.tryAllocate(l, i1); // Tuinity - recalculate header on header corruption
+ // Tuinity start - recalculate header on header corruption
+ if (l < 0 || i1 < 0 || (l + i1) < 0) {
+ if (canRecalcHeader) {
+ MinecraftServer.LOGGER.error("Detected invalid header for regionfile " + this.file.getAbsolutePath() + "! Recalculating header...");
+ needsHeaderRecalc = true;
+ break;
+ } else {
+ // location = chunkX | (chunkZ << 5);
+ MinecraftServer.LOGGER.fatal("Detected invalid header for regionfile " + this.file.getAbsolutePath() +
+ "! Cannot recalculate, removing local chunk (" + (j & 31) + "," + (j >>> 5) + ") from header");
+ if (!hasBackedUp) {
+ hasBackedUp = true;
+ this.backupRegionFile();
+ }
+ this.getTimestamps().put(j, 0); // be consistent, delete the timestamp too
+ this.getOffsets().put(j, 0); // delete the entry from header
+ continue;
+ }
+ }
+ boolean failedToAllocate = !this.freeSectors.tryAllocate(l, i1);
+ if (failedToAllocate && !canRecalcHeader) {
+ // location = chunkX | (chunkZ << 5);
+ MinecraftServer.LOGGER.fatal("Detected invalid header for regionfile " + this.file.getAbsolutePath() +
+ "! Cannot recalculate, removing local chunk (" + (j & 31) + "," + (j >>> 5) + ") from header");
+ if (!hasBackedUp) {
+ hasBackedUp = true;
+ this.backupRegionFile();
+ }
+ this.getTimestamps().put(j, 0); // be consistent, delete the timestamp too
+ this.getOffsets().put(j, 0); // delete the entry from header
+ continue;
+ }
+ needsHeaderRecalc |= failedToAllocate;
+ // Tuinity end - recalculate header on header corruption
}
}
+
+ // Tuinity start - recalculate header on header corruption
+ // we move the recalc here so comparison to old header is correct when logging to console
+ if (needsHeaderRecalc) { // true if header gave us overlapping allocations
+ MinecraftServer.LOGGER.error("Recalculating regionfile " + this.file.getAbsolutePath() + ", header gave conflicting offsets & locations");
+ this.recalculateHeader();
+ }
+ // Tuinity end
@@ -8861,7 +8832,7 @@ index df728e2c0a..5bd7b8f553 100644
@Nullable public synchronized DataInputStream getReadStream(ChunkCoordIntPair chunkCoordIntPair) throws IOException { return a(chunkCoordIntPair);} // Paper - OBFHELPER
@Nullable
public synchronized DataInputStream a(ChunkCoordIntPair chunkcoordintpair) throws IOException {
@@ -142,6 +516,12 @@ public class RegionFile implements AutoCloseable {
@@ -142,6 +558,12 @@ public class RegionFile implements AutoCloseable {
this.dataFile.read(bytebuffer, (long) (j * 4096));
((java.nio.Buffer) bytebuffer).flip();
if (bytebuffer.remaining() < 5) {
@@ -8874,7 +8845,7 @@ index df728e2c0a..5bd7b8f553 100644
RegionFile.LOGGER.error("Chunk {} header is truncated: expected {} but read {}", chunkcoordintpair, l, bytebuffer.remaining());
return null;
} else {
@@ -150,6 +530,12 @@ public class RegionFile implements AutoCloseable {
@@ -150,6 +572,12 @@ public class RegionFile implements AutoCloseable {
if (i1 == 0) {
RegionFile.LOGGER.warn("Chunk {} is allocated, but stream is missing", chunkcoordintpair);
@@ -8887,7 +8858,7 @@ index df728e2c0a..5bd7b8f553 100644
return null;
} else {
int j1 = i1 - 1;
@@ -162,9 +548,21 @@ public class RegionFile implements AutoCloseable {
@@ -162,9 +590,21 @@ public class RegionFile implements AutoCloseable {
return this.a(chunkcoordintpair, b(b0));
} else if (j1 > bytebuffer.remaining()) {
RegionFile.LOGGER.error("Chunk {} stream is truncated: expected {} but read {}", chunkcoordintpair, j1, bytebuffer.remaining());
@@ -8909,7 +8880,7 @@ index df728e2c0a..5bd7b8f553 100644
return null;
} else {
return this.a(chunkcoordintpair, b0, a(bytebuffer, j1));
@@ -323,10 +721,15 @@ public class RegionFile implements AutoCloseable {
@@ -323,10 +763,15 @@ public class RegionFile implements AutoCloseable {
}
private ByteBuffer a() {
@@ -8926,7 +8897,7 @@ index df728e2c0a..5bd7b8f553 100644
((java.nio.Buffer) bytebuffer).flip();
return bytebuffer;
}
@@ -363,6 +766,7 @@ public class RegionFile implements AutoCloseable {
@@ -363,6 +808,7 @@ public class RegionFile implements AutoCloseable {
};
}

View File

@@ -1,4 +1,4 @@
From 280b6a3ede0afa2c334ffe2871ba558781395da3 Mon Sep 17 00:00:00 2001
From c5f15c41693d0d4c58c5e42fb342857b4423c5ca Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sun, 7 Jul 2019 19:52:16 -0500
Subject: [PATCH] Zombie horse naturally spawn

View File

@@ -1,4 +1,4 @@
From 34500d05a6229d4d245a70708d55ab1cb994f43a Mon Sep 17 00:00:00 2001
From e1dc0a3743aee405fe8149535575f49817094c97 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 8 Aug 2019 15:29:15 -0500
Subject: [PATCH] Implement AFK API
@@ -36,7 +36,7 @@ index de22cad764..9d26bd1e4c 100644
super(EntityTypes.PLAYER, world);
this.bV = ItemStack.a;
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index 24ce25ba60..4694edc5de 100644
index b396e0464b..d5e75828ca 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -1653,8 +1653,51 @@ public class EntityPlayer extends EntityHuman implements ICrafting {