diff --git a/patches/server/0002-Tuinity-Server-Patches.patch b/patches/server/0002-Tuinity-Server-Patches.patch index 28b5ae057..2a21faadc 100644 --- a/patches/server/0002-Tuinity-Server-Patches.patch +++ b/patches/server/0002-Tuinity-Server-Patches.patch @@ -1,4 +1,4 @@ -From b723fbb203556bc1025da7a7a88c11475102daa7 Mon Sep 17 00:00:00 2001 +From cae53f41f02d848e12a4077faf88bfc495553350 Mon Sep 17 00:00:00 2001 From: Spottedleaf 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> j; private final Mailbox 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 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> 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> 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> 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 void removeAllTicketsFor(TicketType ticketType, int ticketLevel, T ticketIdentifier) { @@ -4691,7 +4701,7 @@ index 73d1570765..cb2e67d159 100644 Ticket target = new Ticket<>(ticketType, ticketLevel, ticketIdentifier); for (java.util.Iterator>> 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 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 onComplete) { -- CompletableFuture> 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 onComplete, boolean createFuture) { -+ CompletableFuture> 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 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>> 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> 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 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 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 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 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 f() { @@ -7726,7 +7646,7 @@ index 57bea926a6..1504094369 100644 while (objectbidirectionaliterator.hasNext()) { Entry 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 list = Lists.newArrayList(); List 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 list = Lists.newArrayList(); List 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 { }; } diff --git a/patches/server/0013-Zombie-horse-naturally-spawn.patch b/patches/server/0013-Zombie-horse-naturally-spawn.patch index 2899d9c0f..7256c00f2 100644 --- a/patches/server/0013-Zombie-horse-naturally-spawn.patch +++ b/patches/server/0013-Zombie-horse-naturally-spawn.patch @@ -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 Date: Sun, 7 Jul 2019 19:52:16 -0500 Subject: [PATCH] Zombie horse naturally spawn diff --git a/patches/server/0042-Implement-AFK-API.patch b/patches/server/0042-Implement-AFK-API.patch index 69b1b0bab..5b5841675 100644 --- a/patches/server/0042-Implement-AFK-API.patch +++ b/patches/server/0042-Implement-AFK-API.patch @@ -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 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 {