mirror of
https://github.com/PurpurMC/Purpur.git
synced 2026-02-17 16:37:43 +01:00
Update Tuinity patches
This commit is contained in:
@@ -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 {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user