mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-29 15:49:00 +01:00
Chunk system patch
This commit is contained in:
parent
05f9968013
commit
9bf842c13e
52 changed files with 625 additions and 370 deletions
|
@ -34,8 +34,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper
|
||||
+ public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - there are a lot of changes to do if we change all methods leading to the event
|
||||
|
||||
public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) {
|
||||
super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile);
|
||||
// Paper start - replace player chunk loader
|
||||
private final java.util.concurrent.atomic.AtomicReference<io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances> viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1));
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
|
|
|
@ -2038,10 +2038,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
|
||||
private ExplosionInteraction() {}
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
// Paper end
|
||||
+ // Paper start - optimize redstone (Alternate Current)
|
||||
+ public alternate.current.wire.WireHandler getWireHandler() {
|
||||
+ // This method is overridden in ServerLevel.
|
||||
|
@ -2051,7 +2050,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // an instance of Level to ServerLevel.
|
||||
+ return null;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ // Paper end - optimize redstone (Alternate Current)
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java b/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
|
|
|
@ -69,7 +69,7 @@ diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
|
||||
private static WatchdogThread instance;
|
||||
private long timeoutTime;
|
||||
private boolean restart;
|
||||
|
@ -80,7 +80,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
private volatile long lastTick;
|
||||
private volatile boolean stopping;
|
||||
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
|
||||
super( "Paper Watchdog Thread" );
|
||||
this.timeoutTime = timeoutTime;
|
||||
this.restart = restart;
|
||||
|
@ -89,7 +89,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
|
||||
private static long monotonicMillis()
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
|
||||
while ( !this.stopping )
|
||||
{
|
||||
//
|
||||
|
@ -110,7 +110,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
log.log( Level.SEVERE, "------------------------------" );
|
||||
log.log( Level.SEVERE, "The server has stopped responding! This is (probably) not a Paper bug." ); // Paper
|
||||
log.log( Level.SEVERE, "If you see a plugin in the Server thread dump below, then please report it to that author" );
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
|
||||
}
|
||||
}
|
||||
// Paper end
|
||||
|
@ -122,6 +122,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper end - Different message for short timeout
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
|
||||
io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(isLongTimeout); // Paper // Paper - rewrite chunk system
|
||||
WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
//
|
||||
|
|
|
@ -244,7 +244,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause
|
||||
return;
|
||||
}
|
||||
// CraftBukkit end
|
||||
// Paper start
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
// Paper start - validate pick item position
|
||||
if (!(packet.getSlot() >= 0 && packet.getSlot() < this.player.getInventory().items.size())) {
|
||||
|
|
|
@ -198,9 +198,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/io/papermc/paper/command/PaperCommand.java
|
||||
+++ b/src/main/java/io/papermc/paper/command/PaperCommand.java
|
||||
@@ -0,0 +0,0 @@ public final class PaperCommand extends Command {
|
||||
commands.put(Set.of("version"), new VersionCommand());
|
||||
commands.put(Set.of("dumpplugins"), new DumpPluginsCommand());
|
||||
commands.put(Set.of("fixlight"), new FixLightCommand());
|
||||
commands.put(Set.of("debug", "chunkinfo", "holderinfo"), new ChunkDebugCommand());
|
||||
+ commands.put(Set.of("syncloadinfo"), new SyncLoadInfoCommand());
|
||||
|
||||
return commands.entrySet().stream()
|
||||
|
@ -304,27 +304,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
|
||||
@Nullable
|
||||
@Override
|
||||
public ChunkAccess getChunk(int x, int z, ChunkStatus leastStatus, boolean create) {
|
||||
+ final int x1 = x; final int z1 = z; // Paper - conflict on variable change
|
||||
if (Thread.currentThread() != this.mainThread) {
|
||||
return (ChunkAccess) CompletableFuture.supplyAsync(() -> {
|
||||
return this.getChunk(x, z, leastStatus, create);
|
||||
@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
|
||||
|
||||
Objects.requireNonNull(completablefuture);
|
||||
if (!completablefuture.isDone()) { // Paper
|
||||
// Paper start - async chunk io/loading
|
||||
io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.pushChunkWait(this.level, x1, z1); // Paper - rewrite chunk system
|
||||
// Paper end
|
||||
+ com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x1, z1); // Paper - sync load info
|
||||
this.level.timings.syncChunkLoad.startTiming(); // Paper
|
||||
chunkproviderserver_b.managedBlock(completablefuture::isDone);
|
||||
this.level.timings.syncChunkLoad.stopTiming(); // Paper
|
||||
io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.popChunkWait(); // Paper - async chunk debug // Paper - rewrite chunk system
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
|
||||
this.entityLookup = new io.papermc.paper.chunk.system.entity.EntityLookup(this, new EntityCallbacks()); // Paper - rewrite chunk system
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
|
|
|
@ -57,21 +57,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java
|
||||
@@ -0,0 +0,0 @@ public class DummyGeneratorAccess implements WorldGenLevel {
|
||||
public boolean destroyBlock(BlockPos pos, boolean drop, Entity breakingEntity, int maxUpdateDepth) {
|
||||
return false; // SPIGOT-6515
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void scheduleTick(BlockPos pos, Fluid fluid, int delay) {
|
||||
+ }
|
||||
@Override
|
||||
public <T> void getEntitiesByClass(Class<? extends T> clazz, Entity except, AABB box, List<? super T> into, Predicate<? super T> predicate) {}
|
||||
// Paper end
|
||||
+ // Paper start - add more methods
|
||||
+ public void scheduleTick(BlockPos pos, Fluid fluid, int delay) {}
|
||||
+
|
||||
+ @Override
|
||||
+ public void scheduleTick(BlockPos pos, Block block, int delay, net.minecraft.world.ticks.TickPriority priority) {
|
||||
+ }
|
||||
+ public void scheduleTick(BlockPos pos, Block block, int delay, net.minecraft.world.ticks.TickPriority priority) {}
|
||||
+
|
||||
+ @Override
|
||||
+ public void scheduleTick(BlockPos pos, Fluid fluid, int delay, net.minecraft.world.ticks.TickPriority priority) {
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ public void scheduleTick(BlockPos pos, Fluid fluid, int delay, net.minecraft.world.ticks.TickPriority priority) {}
|
||||
+ // Paper end - add more methods
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/io/papermc/paper/command/PaperCommand.java
|
||||
+++ b/src/main/java/io/papermc/paper/command/PaperCommand.java
|
||||
@@ -0,0 +0,0 @@ public final class PaperCommand extends Command {
|
||||
commands.put(Set.of("fixlight"), new FixLightCommand());
|
||||
commands.put(Set.of("debug", "chunkinfo", "holderinfo"), new ChunkDebugCommand());
|
||||
commands.put(Set.of("syncloadinfo"), new SyncLoadInfoCommand());
|
||||
commands.put(Set.of("dumpitem"), new DumpItemCommand());
|
||||
+ commands.put(Set.of("mobcaps", "playermobcaps"), new MobcapsCommand());
|
||||
|
|
|
@ -65,7 +65,7 @@ diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
|
||||
log.log( Level.SEVERE, "During the run of the server, a physics stackoverflow was supressed" );
|
||||
log.log( Level.SEVERE, "near " + net.minecraft.world.level.Level.lastPhysicsProblem );
|
||||
}
|
||||
|
@ -85,4 +85,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper end
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
|
||||
WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
|
||||
io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(isLongTimeout); // Paper // Paper - rewrite chunk system
|
||||
|
|
|
@ -41,18 +41,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
+import java.util.zip.InflaterInputStream; // Paper
|
||||
+
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.Util;
|
||||
+import net.minecraft.nbt.CompoundTag;
|
||||
+import net.minecraft.nbt.NbtIo;
|
||||
+import net.minecraft.nbt.CompoundTag; // Paper
|
||||
+import net.minecraft.nbt.NbtIo; // Paper
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
|
||||
private final IntBuffer timestamps;
|
||||
@VisibleForTesting
|
||||
protected final RegionBitmap usedSectors;
|
||||
public final java.util.concurrent.locks.ReentrantLock fileLock = new java.util.concurrent.locks.ReentrantLock(true); // Paper
|
||||
+ public final Path regionFile; // Paper
|
||||
|
||||
public RegionFile(Path file, Path directory, boolean dsync) throws IOException {
|
||||
|
@ -218,7 +217,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public CompoundTag read(ChunkPos pos) throws IOException {
|
||||
// CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing
|
||||
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable {
|
||||
// CraftBukkit end
|
||||
try { // Paper
|
||||
DataInputStream datainputstream = regionfile.getChunkDataInputStream(pos);
|
||||
|
||||
+ // Paper start
|
||||
|
|
|
@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ this.getProfileCache().save(false); // Paper
|
||||
}
|
||||
// Spigot end
|
||||
|
||||
io.papermc.paper.chunk.system.io.RegionFileIOThread.close(true); // Paper // Paper - rewrite chunk system
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
|
|
|
@ -37,6 +37,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]))); // Paper
|
||||
return;
|
||||
}
|
||||
// Paper start
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
}
|
||||
// Paper end
|
||||
// CraftBukkit end
|
||||
+ // Paper start - async tab completion
|
||||
+ TAB_COMPLETE_EXECUTOR.execute(() -> {
|
||||
|
|
|
@ -559,8 +559,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import io.papermc.paper.math.BlockPosition;
|
||||
import io.papermc.paper.math.FinePosition;
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.level.ClipContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
+import com.mojang.authlib.GameProfile;
|
||||
|
|
|
@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/network/Connection.java
|
||||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -0,0 +0,0 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
}
|
||||
} // Paper end - add pending task queue
|
||||
}
|
||||
|
||||
+ private static final int MAX_PER_TICK = io.papermc.paper.configuration.GlobalConfiguration.get().misc.maxJoinsPerTick; // Paper
|
||||
|
|
|
@ -23,9 +23,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable {
|
||||
|
||||
protected void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException {
|
||||
RegionFile regionfile = this.getRegionFile(pos, false); // CraftBukkit
|
||||
}
|
||||
// Paper end - rewrite chunk system
|
||||
try { // Paper
|
||||
+ int attempts = 0; Exception laste = null; while (attempts++ < 5) { try { // Paper
|
||||
|
||||
if (nbt == null) {
|
||||
|
@ -46,6 +46,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ net.minecraft.server.MinecraftServer.LOGGER.error("Failed to save chunk " + pos, laste);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
} finally { // Paper start
|
||||
regionfile.fileLock.unlock();
|
||||
} // Paper end
|
||||
|
|
|
@ -644,7 +644,7 @@ diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
|
||||
log.log( Level.SEVERE, "During the run of the server, a plugin set an excessive velocity on an entity" );
|
||||
log.log( Level.SEVERE, "This may be the cause of the issue, or it may be entirely unrelated" );
|
||||
log.log( Level.SEVERE, org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getMessage());
|
||||
|
@ -653,7 +653,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
{
|
||||
log.log( Level.SEVERE, "\t\t" + stack );
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
|
||||
}
|
||||
log.log( Level.SEVERE, "\tStack:" );
|
||||
//
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Sun, 18 Jun 2023 23:04:46 -0700
|
||||
Subject: [PATCH] Do not read tile entities in chunks that are positioned
|
||||
outside of the chunk
|
||||
|
||||
The tile entities are not accessible and so should not be loaded.
|
||||
This can happen as a result of users moving regionfiles around,
|
||||
which would cause a crash on Folia but would appear to function
|
||||
fine on Paper.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
||||
for (int k1 = 0; k1 < nbttaglist3.size(); ++k1) {
|
||||
CompoundTag nbttagcompound4 = nbttaglist3.getCompound(k1);
|
||||
|
||||
+ // Paper start - do not read tile entities positioned outside the chunk
|
||||
+ BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound4);
|
||||
+ if ((blockposition.getX() >> 4) != chunkPos.x || (blockposition.getZ() >> 4) != chunkPos.z) {
|
||||
+ LOGGER.warn("Tile entity serialized in chunk " + chunkPos + " in world '" + world.getWorld().getName() + "' positioned at " + blockposition + " is located outside of the chunk");
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Paper end - do not read tile entities positioned outside the chunk
|
||||
((ChunkAccess) object1).setBlockEntityNbt(nbttagcompound4);
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
||||
CompoundTag nbttagcompound1 = nbttaglist1.getCompound(i);
|
||||
boolean flag = nbttagcompound1.getBoolean("keepPacked");
|
||||
|
||||
+ // Paper start - do not read tile entities positioned outside the chunk
|
||||
+ BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound1); // moved up
|
||||
+ ChunkPos chunkPos = chunk.getPos();
|
||||
+ if ((blockposition.getX() >> 4) != chunkPos.x || (blockposition.getZ() >> 4) != chunkPos.z) {
|
||||
+ LOGGER.warn("Tile entity serialized in chunk " + chunkPos + " in world '" + world.getWorld().getName() + "' positioned at " + blockposition + " is located outside of the chunk");
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Paper end - do not read tile entities positioned outside the chunk
|
||||
+
|
||||
if (flag) {
|
||||
chunk.setBlockEntityNbt(nbttagcompound1);
|
||||
} else {
|
||||
- BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound1);
|
||||
+ // Paper - do not read tile entities positioned outside the chunk - move up
|
||||
BlockEntity tileentity = BlockEntity.loadStatic(blockposition, chunk.getBlockState(blockposition), nbttagcompound1);
|
||||
|
||||
if (tileentity != null) {
|
|
@ -20,4 +20,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ if (objectset == null || objectset.isEmpty()) { // Paper
|
||||
this.playersPerChunk.remove(i);
|
||||
this.naturalSpawnChunkCounter.update(i, Integer.MAX_VALUE, false);
|
||||
this.playerTicketManager.update(i, Integer.MAX_VALUE, false);
|
||||
//this.playerTicketManager.update(i, Integer.MAX_VALUE, false); // Paper - no longer used
|
||||
|
|
|
@ -18,4 +18,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ if (true) return true; // Paper - this isn't even needed anymore, light is purged updating to 1.14+, why are we holding up the conversion process reading chunk data off disk - return true, we need to set light populated to true so the converter recognizes the chunk as being "full"
|
||||
ChunkPos pos = new ChunkPos(x, z);
|
||||
if (cps != null) {
|
||||
com.google.common.base.Preconditions.checkState(org.bukkit.Bukkit.isPrimaryThread(), "primary thread");
|
||||
//com.google.common.base.Preconditions.checkState(org.bukkit.Bukkit.isPrimaryThread(), "primary thread"); // Paper - this function is now MT-Safe
|
||||
|
|
|
@ -10,8 +10,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
return;
|
||||
}
|
||||
// Paper end
|
||||
// CraftBukkit end
|
||||
+ // Paper start - Don't suggest if tab-complete is disabled
|
||||
+ if (org.spigotmc.SpigotConfig.tabComplete < 0) {
|
||||
|
|
|
@ -39,11 +39,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/org/spigotmc/ActivationRange.java
|
||||
+++ b/src/main/java/org/spigotmc/ActivationRange.java
|
||||
@@ -0,0 +0,0 @@ public class ActivationRange
|
||||
ActivationType.VILLAGER.boundingBox = player.getBoundingBox().inflate( villagerActivationRange, worldHeight, villagerActivationRange );
|
||||
// Paper end
|
||||
|
||||
- world.getEntities().get(maxBB, ActivationRange::activateEntity);
|
||||
+ world.getEntities().get(world.paperConfig().entities.markers.tick ? null : (e) -> !(e instanceof net.minecraft.world.entity.Marker), maxBB, ActivationRange::activateEntity); // Paper - configurable marker ticking
|
||||
}
|
||||
MinecraftTimings.entityActivationCheckTimer.stopTiming();
|
||||
}
|
||||
// Paper start
|
||||
java.util.List<Entity> entities = world.getEntities((Entity)null, maxBB, null);
|
||||
+ boolean tickMarkers = world.paperConfig().entities.markers.tick; // Paper - configurable marker ticking
|
||||
for (int i = 0; i < entities.size(); i++) {
|
||||
Entity entity = entities.get(i);
|
||||
+ // Paper start - configurable marker ticking
|
||||
+ if (!tickMarkers && entity instanceof net.minecraft.world.entity.Marker) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Paper end - configurable marker ticking
|
||||
ActivationRange.activateEntity(entity);
|
||||
}
|
||||
// Paper end
|
||||
|
|
|
@ -65,10 +65,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
+ checkDupeUUID(world, entity); // Paper
|
||||
return !needsRemoval;
|
||||
}));
|
||||
}), position); // Paper - rewrite chunk system
|
||||
// CraftBukkit end
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
});
|
||||
throw new UnsupportedOperationException(); // Paper - rewrite chunk system
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
|
@ -115,5 +115,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ // Paper end
|
||||
public CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>> prepareTickingChunk(ChunkHolder holder) {
|
||||
CompletableFuture<Either<List<ChunkAccess>, ChunkHolder.ChunkLoadingFailure>> completablefuture = this.getChunkRangeFuture(holder, 1, (i) -> {
|
||||
return ChunkStatus.FULL;
|
||||
throw new UnsupportedOperationException(); // Paper - rewrite chunk system
|
||||
}
|
||||
|
|
|
@ -28,9 +28,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) {
|
||||
+ // Paper end
|
||||
if (this.position.x != x || this.position.y != y || this.position.z != z) {
|
||||
this.position = new Vec3(x, y, z);
|
||||
int i = Mth.floor(x);
|
||||
// Paper start - rewrite chunk system
|
||||
if (this.updatingSectionStatus) {
|
||||
LOGGER.error("Refusing to update position for entity " + this + " to position " + new Vec3(x, y, z) + " since it is processing a section status update", new Throwable());
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
this.levelCallback.onMove();
|
||||
}
|
||||
|
|
|
@ -564,8 +564,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ ActivationType.VILLAGER.boundingBox = player.getBoundingBox().inflate( villagerActivationRange, worldHeight, villagerActivationRange );
|
||||
+ // Paper end
|
||||
|
||||
world.getEntities().get(maxBB, ActivationRange::activateEntity);
|
||||
}
|
||||
// Paper start
|
||||
java.util.List<Entity> entities = world.getEntities((Entity)null, maxBB, null);
|
||||
@@ -0,0 +0,0 @@ public class ActivationRange
|
||||
* @param entity
|
||||
* @return
|
||||
|
@ -628,8 +628,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
{
|
||||
- return true;
|
||||
+ return 20; // Paper
|
||||
}
|
||||
- if ( entity instanceof Villager && ( (Villager) entity ).canBreed() )
|
||||
+ }
|
||||
+ // Paper start
|
||||
+ if (entity instanceof Bee) {
|
||||
+ Bee bee = (Bee)entity;
|
||||
|
@ -657,7 +656,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ return config.villagersWorkImmunityFor;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
- if ( entity instanceof Villager && ( (Villager) entity ).canBreed() )
|
||||
+ if ( entity instanceof Llama && ( (Llama) entity ).inCaravan() )
|
||||
{
|
||||
- return true;
|
||||
|
@ -685,11 +685,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper start
|
||||
+ if (entity instanceof Mob && ((Mob) entity).targetSelector.hasTasks() ) {
|
||||
+ return 0;
|
||||
+ }
|
||||
}
|
||||
+ if (entity instanceof Pillager) {
|
||||
+ Pillager pillager = (Pillager) entity;
|
||||
+ // TODO:?
|
||||
}
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
// SPIGOT-6644: Otherwise the target refresh tick will be missed
|
||||
|
|
|
@ -64,9 +64,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/network/Connection.java
|
||||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -0,0 +0,0 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@Nullable
|
||||
BandwidthDebugMonitor bandwidthDebugMonitor;
|
||||
public String hostname = ""; // CraftBukkit - add field
|
||||
}
|
||||
}
|
||||
// Paper end - add pending task queue
|
||||
+ // Paper start - NetworkClient implementation
|
||||
+ public int protocolVersion;
|
||||
+ public java.net.InetSocketAddress virtualHost;
|
||||
|
|
|
@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
// Paper end
|
||||
|
||||
private CompletableFuture<Optional<CompoundTag>> readChunk(ChunkPos chunkPos) {
|
||||
- return this.read(chunkPos).thenApplyAsync((optional) -> {
|
||||
|
@ -97,7 +97,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
|
||||
protected final RegionBitmap usedSectors;
|
||||
public final java.util.concurrent.locks.ReentrantLock fileLock = new java.util.concurrent.locks.ReentrantLock(true); // Paper
|
||||
public final Path regionFile; // Paper
|
||||
|
||||
+ // Paper start - Cache chunk status
|
||||
|
@ -135,8 +135,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
private static int getOffsetIndex(ChunkPos pos) {
|
||||
return pos.getRegionLocalX() + pos.getRegionLocalZ() * 32;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
|
||||
synchronized (this) {
|
||||
try {
|
||||
// Paper end
|
||||
+ this.closed = true; // Paper
|
||||
try {
|
||||
this.padToFullSector();
|
||||
|
|
|
@ -330,10 +330,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable {
|
||||
this.sync = dsync;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
// Paper start
|
||||
+ @Nullable
|
||||
+ public static ChunkPos getRegionFileCoordinates(Path file) {
|
||||
+ String fileName = file.getFileName().toString();
|
||||
|
@ -356,11 +355,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ return null;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
private RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit
|
||||
long i = ChunkPos.asLong(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ());
|
||||
RegionFile regionfile = (RegionFile) this.regionCache.getAndMoveToFirst(i);
|
||||
public synchronized RegionFile getRegionFileIfLoaded(ChunkPos chunkcoordintpair) {
|
||||
return this.regionCache.getAndMoveToFirst(ChunkPos.asLong(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ()));
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
|
|
|
@ -15,9 +15,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
}
|
||||
// Paper end
|
||||
|
||||
public boolean updatingSectionStatus = false;
|
||||
// Paper end
|
||||
+ // Paper start - make end portalling safe
|
||||
+ public BlockPos portalBlock;
|
||||
+ public ServerLevel portalWorld;
|
||||
|
@ -48,10 +48,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ this.teleportTo(worldserver, null);
|
||||
+ }
|
||||
+ // Paper end - make end portalling safe
|
||||
+
|
||||
|
||||
public Entity(EntityType<?> type, Level world) {
|
||||
this.id = Entity.ENTITY_COUNTER.incrementAndGet();
|
||||
this.passengers = ImmutableList.of();
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
+ io.papermc.paper.log.CustomLogManager.forceReset(); // Paper - Reset loggers after shutdown
|
||||
this.onServerExit();
|
||||
// Paper end
|
||||
// Paper end - move final shutdown items here
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
|
|
|
@ -51,8 +51,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
|
||||
// Paper start
|
||||
// Paper end - optimize redstone (Alternate Current)
|
||||
// Paper start - notify observers even if grow failed
|
||||
public void checkCapturedTreeStateForObserverNotify(final BlockPos pos, final CraftBlockState craftBlockState) {
|
||||
- if (craftBlockState.getPosition().getY() == pos.getY() && this.getBlockState(craftBlockState.getPosition()) == craftBlockState.getHandle()) { // notify observers if the block state is the same and the Y level equals the original y level (for mega trees)
|
||||
+ // notify observers if the block state is the same and the Y level equals the original y level (for mega trees)
|
||||
|
|
|
@ -90,7 +90,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper End
|
||||
// Spigot End
|
||||
|
||||
protected void runServer() {
|
||||
public static volatile RuntimeException chunkSystemCrash; // Paper - rewrite chunk system
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
// Spigot start
|
||||
|
@ -99,6 +99,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ long start = System.nanoTime(), curTime, tickSection = start; // Paper - Further improve server tick loop
|
||||
+ lastTick = start - TICK_TIME; // Paper
|
||||
while (this.running) {
|
||||
// Paper start - rewrite chunk system
|
||||
// guarantee that nothing can stop the server from halting if it can at least still tick
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
throw this.chunkSystemCrash;
|
||||
}
|
||||
// Paper end - rewrite chunk system
|
||||
- long i = (curTime = Util.getMillis()) - this.nextTickTime;
|
||||
+ long i = ((curTime = System.nanoTime()) / (1000L * 1000L)) - this.nextTickTime; // Paper
|
||||
|
||||
|
|
|
@ -41,5 +41,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ // Paper end - block invalid positions
|
||||
// Paper end
|
||||
// Paper start - fix MC-4
|
||||
if (this instanceof ItemEntity) {
|
||||
// Paper start - rewrite chunk system
|
||||
if (this.updatingSectionStatus) {
|
||||
|
|
|
@ -183,7 +183,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+++ b/src/main/java/org/spigotmc/AsyncCatcher.java
|
||||
@@ -0,0 +0,0 @@ public class AsyncCatcher
|
||||
{
|
||||
if ( (AsyncCatcher.enabled || io.papermc.paper.util.TickThread.STRICT_THREAD_CHECKS) && Thread.currentThread() != MinecraftServer.getServer().serverThread ) // Paper
|
||||
if ( !io.papermc.paper.util.TickThread.isTickThread() ) // Paper // Paper - rewrite chunk system
|
||||
{
|
||||
+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); // Paper
|
||||
throw new IllegalStateException( "Asynchronous " + reason + "!" );
|
||||
|
|
|
@ -92,7 +92,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+
|
||||
public static <S extends MinecraftServer> S spin(Function<Thread, S> serverFactory) {
|
||||
AtomicReference<S> atomicreference = new AtomicReference();
|
||||
Thread thread = new Thread(() -> {
|
||||
Thread thread = new io.papermc.paper.util.TickThread(() -> { // Paper - rewrite chunk system
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
// CraftBukkit start
|
||||
|
@ -122,12 +122,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
if (this.metricsRecorder.isRecording()) {
|
||||
this.cancelRecordingMetrics();
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.getProfileCache().save(false); // Paper
|
||||
}
|
||||
// Spigot end
|
||||
|
||||
+ // Paper start - move final shutdown items here
|
||||
+ LOGGER.info("Flushing Chunk IO");
|
||||
+ // TODO chunk system patch has a line here
|
||||
+ // Paper end - move final shutdown items here
|
||||
io.papermc.paper.chunk.system.io.RegionFileIOThread.close(true); // Paper // Paper - rewrite chunk system
|
||||
+ // Paper start - move final shutdown items here
|
||||
+ LOGGER.info("Closing Thread Pool");
|
||||
+ Util.shutdownExecutors(); // Paper
|
||||
+ LOGGER.info("Closing Server");
|
||||
|
@ -136,7 +138,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ } catch (Exception e) {
|
||||
+ }
|
||||
+ this.onServerExit();
|
||||
+ // Paper end
|
||||
+ // Paper end - move final shutdown items here
|
||||
}
|
||||
|
||||
public String getLocalIp() {
|
||||
|
@ -474,14 +476,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.Bukkit;
|
||||
public class WatchdogThread extends Thread
|
||||
public final class WatchdogThread extends io.papermc.paper.util.TickThread // Paper - rewrite chunk system
|
||||
{
|
||||
|
||||
+ public static final boolean DISABLE_WATCHDOG = Boolean.getBoolean("disable.watchdog"); // Paper
|
||||
private static WatchdogThread instance;
|
||||
private long timeoutTime;
|
||||
private boolean restart;
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
|
||||
{
|
||||
if ( WatchdogThread.instance == null )
|
||||
{
|
||||
|
@ -489,7 +491,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
WatchdogThread.instance = new WatchdogThread( timeoutTime * 1000L, restart );
|
||||
WatchdogThread.instance.start();
|
||||
} else
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
|
||||
// Paper start
|
||||
Logger log = Bukkit.getServer().getLogger();
|
||||
long currentTime = WatchdogThread.monotonicMillis();
|
||||
|
@ -506,7 +508,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
lastEarlyWarning = currentTime;
|
||||
if (isLongTimeout) {
|
||||
// Paper end
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
|
||||
|
||||
if ( isLongTimeout )
|
||||
{
|
||||
|
|
|
@ -32,9 +32,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
}
|
||||
public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) {
|
||||
// Paper end
|
||||
return;
|
||||
}
|
||||
// Paper end - rewrite chunk system
|
||||
+ // Paper start - fix MC-4
|
||||
+ if (this instanceof ItemEntity) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.fixEntityPositionDesync) {
|
||||
|
|
|
@ -35,15 +35,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
return null;
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Paper start
|
||||
// Paper end - optimize redstone (Alternate Current)
|
||||
+ // Paper start - notify observers even if grow failed
|
||||
+ public void checkCapturedTreeStateForObserverNotify(final BlockPos pos, final CraftBlockState craftBlockState) {
|
||||
+ if (craftBlockState.getPosition().getY() == pos.getY() && this.getBlockState(craftBlockState.getPosition()) == craftBlockState.getHandle()) { // notify observers if the block state is the same and the Y level equals the original y level (for mega trees)
|
||||
+ this.notifyAndUpdatePhysics(craftBlockState.getPosition(), null, craftBlockState.getHandle(), craftBlockState.getHandle(), craftBlockState.getHandle(), craftBlockState.getFlag(), 512);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ // Paper end - notify observers even if grow failed
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/SaplingBlock.java b/src/main/java/net/minecraft/world/level/block/SaplingBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
|
|
|
@ -10,8 +10,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
});
|
||||
}
|
||||
// Paper end
|
||||
|
||||
+ // Paper start - optimise getPlayerByUUID
|
||||
+ @Nullable
|
||||
|
|
|
@ -976,12 +976,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ private final Map<Holder<PoiType>, Set<PoiRecord>> byType = Maps.newHashMap(); public final Map<Holder<PoiType>, Set<PoiRecord>> getData() { return this.byType; } // Paper - public accessor
|
||||
private final Runnable setDirty;
|
||||
private boolean isValid;
|
||||
|
||||
public final Optional<PoiSection> noAllocateOptional = Optional.of(this); // Paper - rewrite chunk system
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java
|
||||
@@ -0,0 +0,0 @@ public class SectionStorage<R> implements AutoCloseable {
|
||||
@@ -0,0 +0,0 @@ public class SectionStorage<R> extends RegionFileStorage implements AutoCloseabl
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
|
@ -24,7 +24,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
gameprofilerfiller.incrementCounter("getChunk");
|
||||
@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
|
||||
if (Thread.currentThread() != this.mainThread) {
|
||||
if (!io.papermc.paper.util.TickThread.isTickThread()) { // Paper - rewrite chunk system
|
||||
return null;
|
||||
} else {
|
||||
- this.level.getProfiler().incrementCounter("getChunkNow");
|
||||
|
|
|
@ -26,5 +26,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
+ // Paper end
|
||||
// CraftBukkit end
|
||||
return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && Thread.currentThread() != this.thread ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE));
|
||||
return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && !io.papermc.paper.util.TickThread.isTickThread() ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE)); // Paper - rewrite chunk system
|
||||
}
|
||||
|
|
|
@ -43,7 +43,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
return () -> {
|
||||
return this.getIndirectPassengersStream().iterator();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
// Paper end - rewrite chunk system
|
||||
|
||||
public boolean hasExactlyOnePlayerPassenger() {
|
||||
+ if (this.passengers.isEmpty()) { return false; } // Paper
|
||||
|
|
|
@ -10,8 +10,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/io/papermc/paper/command/PaperCommand.java
|
||||
+++ b/src/main/java/io/papermc/paper/command/PaperCommand.java
|
||||
@@ -0,0 +0,0 @@ public final class PaperCommand extends Command {
|
||||
commands.put(Set.of("dumpplugins"), new DumpPluginsCommand());
|
||||
commands.put(Set.of("fixlight"), new FixLightCommand());
|
||||
commands.put(Set.of("debug", "chunkinfo", "holderinfo"), new ChunkDebugCommand());
|
||||
commands.put(Set.of("syncloadinfo"), new SyncLoadInfoCommand());
|
||||
+ commands.put(Set.of("dumpitem"), new DumpItemCommand());
|
||||
|
||||
|
|
|
@ -9,23 +9,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/network/PlayerChunkSender.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/PlayerChunkSender.java
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkSender {
|
||||
public void dropChunk(ServerPlayer player, ChunkPos pos) {
|
||||
if (!this.pendingChunks.remove(pos.toLong()) && player.isAlive()) {
|
||||
player.connection.send(new ClientboundForgetLevelChunkPacket(pos));
|
||||
+ // Paper start
|
||||
+ if(io.papermc.paper.event.packet.PlayerChunkUnloadEvent.getHandlerList().getRegisteredListeners().length > 0){
|
||||
+ new io.papermc.paper.event.packet.PlayerChunkUnloadEvent(player.getBukkitEntity().getWorld().getChunkAt(pos.longKey), player.getBukkitEntity()).callEvent();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
// Paper start - rewrite player chunk loader
|
||||
public static void dropChunkStatic(ServerPlayer player, ChunkPos pos) {
|
||||
player.connection.send(new ClientboundForgetLevelChunkPacket(pos));
|
||||
+ // Paper start
|
||||
+ if (io.papermc.paper.event.packet.PlayerChunkUnloadEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
+ new io.papermc.paper.event.packet.PlayerChunkUnloadEvent(player.getBukkitEntity().getWorld().getChunkAt(pos.longKey), player.getBukkitEntity()).callEvent();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
// Paper end - rewrite player chunk loader
|
||||
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkSender {
|
||||
|
||||
private static void sendChunk(ServerGamePacketListenerImpl handler, ServerLevel world, LevelChunk chunk) {
|
||||
public static void sendChunk(ServerGamePacketListenerImpl handler, ServerLevel world, LevelChunk chunk) { // Paper - rewrite chunk loader - public
|
||||
handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), (BitSet)null, (BitSet)null));
|
||||
+ // Paper start
|
||||
+ if(io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0){
|
||||
+ if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
+ new io.papermc.paper.event.packet.PlayerChunkLoadEvent(new org.bukkit.craftbukkit.CraftChunk(chunk), handler.getPlayer().getBukkitEntity()).callEvent();
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
|
|
@ -76,5 +76,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> cachedSingleHashSet; // Paper
|
||||
+ public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper
|
||||
|
||||
public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) {
|
||||
super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile);
|
||||
// Paper start - replace player chunk loader
|
||||
private final java.util.concurrent.atomic.AtomicReference<io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances> viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1));
|
||||
|
|
|
@ -38,4 +38,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper - move up
|
||||
|
||||
this.getServer().prepareLevels(internal.getChunkSource().chunkMap.progressListener, internal);
|
||||
internal.entityManager.tick(); // SPIGOT-6526: Load pending entities so they are available to the API
|
||||
//internal.entityManager.tick(); // SPIGOT-6526: Load pending entities so they are available to the API // Paper - rewrite chunk system
|
||||
|
|
|
@ -2354,9 +2354,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+import net.minecraft.network.protocol.game.ClientboundSetChunkCacheRadiusPacket;
|
||||
+import net.minecraft.network.protocol.game.ClientboundSetSimulationDistancePacket;
|
||||
+import net.minecraft.server.level.ChunkMap;
|
||||
+import net.minecraft.server.level.ChunkTrackingView;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
+import net.minecraft.server.level.TicketType;
|
||||
+import net.minecraft.server.network.PlayerChunkSender;
|
||||
+import net.minecraft.world.level.ChunkPos;
|
||||
+import net.minecraft.world.level.GameRules;
|
||||
+import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
|
@ -2815,8 +2817,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+
|
||||
+ private void sendChunk(final int chunkX, final int chunkZ) {
|
||||
+ if (this.sentChunks.add(CoordinateUtils.getChunkKey(chunkX, chunkZ))) {
|
||||
+ this.world.getChunkSource().chunkMap.updateChunkTracking(this.player,
|
||||
+ new ChunkPos(chunkX, chunkZ), new MutableObject<>(), false, true); // unloaded, loaded
|
||||
+ PlayerChunkSender.sendChunk(this.player.connection, this.world, this.world.getChunkIfLoaded(chunkX, chunkZ));
|
||||
+ return;
|
||||
+ }
|
||||
+ throw new IllegalStateException();
|
||||
|
@ -2830,8 +2831,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+
|
||||
+ private void sendUnloadChunkRaw(final int chunkX, final int chunkZ) {
|
||||
+ this.player.serverLevel().getChunkSource().chunkMap.updateChunkTracking(this.player,
|
||||
+ new ChunkPos(chunkX, chunkZ), null, true, false); // unloaded, loaded
|
||||
+ PlayerChunkSender.dropChunkStatic(this.player, new ChunkPos(chunkX, chunkZ));
|
||||
+ }
|
||||
+
|
||||
+ private final SingleUserAreaMap<PlayerChunkLoaderData> broadcastMap = new SingleUserAreaMap<>(this) {
|
||||
|
@ -2900,11 +2900,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ private static boolean wantChunkLoaded(final int centerX, final int centerZ, final int chunkX, final int chunkZ,
|
||||
+ final int sendRadius) {
|
||||
+ // expect sendRadius to be = 1 + target viewable radius
|
||||
+ return ChunkMap.isChunkInRange(chunkX, chunkZ, centerX, centerZ, sendRadius);
|
||||
+ return ChunkTrackingView.isWithinDistance(centerX, centerZ, sendRadius, chunkX, chunkZ, true);
|
||||
+ }
|
||||
+
|
||||
+ private static int getClientViewDistance(final ServerPlayer player) {
|
||||
+ final Integer vd = player.clientViewDistance;
|
||||
+ final Integer vd = player.requestedViewDistance();
|
||||
+ return vd == null ? -1 : Math.max(0, vd.intValue());
|
||||
+ }
|
||||
+
|
||||
|
@ -3122,20 +3122,34 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // try to push more chunk generations
|
||||
+ final long maxGens = Math.max(0L, Math.min(MAX_RATE, Math.min(this.genQueue.size(), this.getMaxChunkGenerates())));
|
||||
+ final int maxGensThisTick = (int)this.chunkGenerateTicketLimiter.takeAllocation(time, genRate, maxGens);
|
||||
+ for (int i = 0; i < maxGensThisTick; ++i) {
|
||||
+ final long chunk = this.genQueue.dequeueLong();
|
||||
+ final byte prev = this.chunkTicketStage.put(chunk, CHUNK_TICKET_STAGE_GENERATING);
|
||||
+ int ratedGensThisTick = 0;
|
||||
+ while (!this.genQueue.isEmpty()) {
|
||||
+ final long chunkKey = this.genQueue.firstLong();
|
||||
+ final int chunkX = CoordinateUtils.getChunkX(chunkKey);
|
||||
+ final int chunkZ = CoordinateUtils.getChunkZ(chunkKey);
|
||||
+ final ChunkAccess chunk = this.world.chunkSource.getChunkAtImmediately(chunkX, chunkZ);
|
||||
+ if (chunk.getStatus() != ChunkStatus.FULL) {
|
||||
+ // only rate limit actual generations
|
||||
+ if ((ratedGensThisTick + 1) > maxGensThisTick) {
|
||||
+ break;
|
||||
+ }
|
||||
+ ++ratedGensThisTick;
|
||||
+ }
|
||||
+
|
||||
+ this.genQueue.dequeueLong();
|
||||
+
|
||||
+ final byte prev = this.chunkTicketStage.put(chunkKey, CHUNK_TICKET_STAGE_GENERATING);
|
||||
+ if (prev != CHUNK_TICKET_STAGE_LOADED) {
|
||||
+ throw new IllegalStateException("Previous state should be " + CHUNK_TICKET_STAGE_LOADED + ", not " + prev);
|
||||
+ }
|
||||
+ this.pushDelayedTicketOp(
|
||||
+ ChunkHolderManager.TicketOperation.addAndRemove(
|
||||
+ chunk,
|
||||
+ chunkKey,
|
||||
+ REGION_PLAYER_TICKET, GENERATED_TICKET_LEVEL, this.idBoxed,
|
||||
+ REGION_PLAYER_TICKET, LOADED_TICKET_LEVEL, this.idBoxed
|
||||
+ )
|
||||
+ );
|
||||
+ this.generatingQueue.enqueue(chunk);
|
||||
+ this.generatingQueue.enqueue(chunkKey);
|
||||
+ }
|
||||
+
|
||||
+ // try to pull ticking chunks
|
||||
|
@ -3783,6 +3797,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+import net.minecraft.util.Mth;
|
||||
+import net.minecraft.world.entity.Entity;
|
||||
+import net.minecraft.world.entity.EntityType;
|
||||
+import net.minecraft.world.level.ChunkPos;
|
||||
+import net.minecraft.world.level.entity.EntityInLevelCallback;
|
||||
+import net.minecraft.world.level.entity.EntityTypeTest;
|
||||
+import net.minecraft.world.level.entity.LevelCallback;
|
||||
|
@ -3790,6 +3805,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+import net.minecraft.world.level.entity.LevelEntityGetter;
|
||||
+import net.minecraft.world.level.entity.Visibility;
|
||||
+import net.minecraft.world.phys.AABB;
|
||||
+import net.minecraft.world.phys.Vec3;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+import org.slf4j.Logger;
|
||||
|
@ -4076,22 +4092,55 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ this.getChunk(x, z).updateStatus(newStatus, this);
|
||||
+ }
|
||||
+
|
||||
+ public void addLegacyChunkEntities(final List<Entity> entities) {
|
||||
+ for (int i = 0, len = entities.size(); i < len; ++i) {
|
||||
+ this.addEntity(entities.get(i), true);
|
||||
+ public void addLegacyChunkEntities(final List<Entity> entities, final ChunkPos forChunk) {
|
||||
+ this.addEntityChunk(entities, forChunk, true);
|
||||
+ }
|
||||
+
|
||||
+ public void addEntityChunkEntities(final List<Entity> entities, final ChunkPos forChunk) {
|
||||
+ this.addEntityChunk(entities, forChunk, true);
|
||||
+ }
|
||||
+
|
||||
+ public void addWorldGenChunkEntities(final List<Entity> entities, final ChunkPos forChunk) {
|
||||
+ this.addEntityChunk(entities, forChunk, false);
|
||||
+ }
|
||||
+
|
||||
+ private void addRecursivelySafe(final Entity root, final boolean fromDisk) {
|
||||
+ if (!this.addEntity(root, fromDisk)) {
|
||||
+ // possible we are a passenger, and so should dismount from any valid entity in the world
|
||||
+ root.stopRiding(true);
|
||||
+ return;
|
||||
+ }
|
||||
+ for (final Entity passenger : root.getPassengers()) {
|
||||
+ this.addRecursivelySafe(passenger, fromDisk);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public void addEntityChunkEntities(final List<Entity> entities) {
|
||||
+ private void addEntityChunk(final List<Entity> entities, final ChunkPos forChunk, final boolean fromDisk) {
|
||||
+ for (int i = 0, len = entities.size(); i < len; ++i) {
|
||||
+ this.addEntity(entities.get(i), true);
|
||||
+ }
|
||||
+ }
|
||||
+ final Entity entity = entities.get(i);
|
||||
+ if (entity.isPassenger()) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ public void addWorldGenChunkEntities(final List<Entity> entities) {
|
||||
+ for (int i = 0, len = entities.size(); i < len; ++i) {
|
||||
+ this.addEntity(entities.get(i), false);
|
||||
+ }
|
||||
+ if (!entity.chunkPosition().equals(forChunk)) {
|
||||
+ LOGGER.warn("Root entity " + entity + " is outside of serialized chunk " + forChunk);
|
||||
+ // can't set removed here, as we may not own the chunk position
|
||||
+ // skip the entity
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ final Vec3 rootPosition = entity.position();
|
||||
+
|
||||
+ // always adjust positions before adding passengers in case plugins access the entity, and so that
|
||||
+ // they are added to the right entity chunk
|
||||
+ for (final Entity passenger : entity.getIndirectPassengers()) {
|
||||
+ if (!passenger.chunkPosition().equals(forChunk)) {
|
||||
+ passenger.setPosRaw(rootPosition.x, rootPosition.y, rootPosition.z, true);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ this.addRecursivelySafe(entity, fromDisk);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public boolean addNewEntity(final Entity entity) {
|
||||
|
@ -6538,7 +6587,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ final ServerLevel world = this.world;
|
||||
+ final ProtoChunk protoChunk = (ProtoChunk)this.fromChunk;
|
||||
+ chunk = new LevelChunk(this.world, protoChunk, (final LevelChunk unused) -> {
|
||||
+ ChunkMap.postLoadProtoChunk(world, protoChunk.getEntities());
|
||||
+ ChunkMap.postLoadProtoChunk(world, protoChunk.getEntities(), protoChunk.getPos()); // Paper - rewrite chunk system
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
|
@ -11054,7 +11103,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ if (entityChunk != null) {
|
||||
+ final List<Entity> entities = EntityStorage.readEntities(this.world, entityChunk);
|
||||
+
|
||||
+ this.world.getEntityLookup().addEntityChunkEntities(entities);
|
||||
+ this.world.getEntityLookup().addEntityChunkEntities(entities, new ChunkPos(this.chunkX, this.chunkZ));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
|
@ -16775,7 +16824,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -0,0 +0,0 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@Nullable
|
||||
private volatile Component delayedDisconnect;
|
||||
BandwidthDebugMonitor bandwidthDebugMonitor;
|
||||
public String hostname = ""; // CraftBukkit - add field
|
||||
+ // Paper start - add pending task queue
|
||||
+ private final Queue<Runnable> pendingTasks = new java.util.concurrent.ConcurrentLinkedQueue<>();
|
||||
|
@ -16808,7 +16857,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
private void flushQueue() {
|
||||
+ try { // Paper - add pending task queue
|
||||
if (this.channel != null && this.channel.isOpen()) {
|
||||
Queue queue = this.queue;
|
||||
Queue queue = this.pendingActions;
|
||||
|
||||
@@ -0,0 +0,0 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
|
||||
|
@ -17067,6 +17116,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public final ChunkHolder.PlayerProvider playerProvider;
|
||||
- private boolean wasAccessibleSinceLastSave;
|
||||
- private CompletableFuture<Void> pendingFullStateConfirmation;
|
||||
- private CompletableFuture<?> sendSync;
|
||||
+ // Paper - rewrite chunk system
|
||||
|
||||
private final ChunkMap chunkMap; // Paper
|
||||
|
@ -17114,6 +17164,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ public boolean hasChunkBeenSent() {
|
||||
+ return this.playersSentChunkTo.size() != 0;
|
||||
+ }
|
||||
+
|
||||
+ public boolean hasBeenSent(ServerPlayer to) {
|
||||
+ return this.playersSentChunkTo.contains(to);
|
||||
+ }
|
||||
+ // Paper end - replace player chunk loader
|
||||
+ public ChunkHolder(ChunkPos pos, LevelHeightAccessor world, LevelLightEngine lightingProvider, ChunkHolder.PlayerProvider playersWatchingChunkProvider, io.papermc.paper.chunk.system.scheduling.NewChunkHolder newChunkHolder) { // Paper - rewrite chunk system
|
||||
+ this.newChunkHolder = newChunkHolder; // Paper - rewrite chunk system
|
||||
|
@ -17121,6 +17175,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
this.blockChangedLightSectionFilter = new BitSet();
|
||||
this.skyChangedLightSectionFilter = new BitSet();
|
||||
- this.pendingFullStateConfirmation = CompletableFuture.completedFuture(null); // CraftBukkit - decompile error
|
||||
- this.sendSync = CompletableFuture.completedFuture(null); // CraftBukkit - decompile error
|
||||
+ // Paper - rewrite chunk system
|
||||
this.pos = pos;
|
||||
this.levelHeightAccessor = world;
|
||||
|
@ -17216,6 +17271,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper end - rewrite chunk system
|
||||
}
|
||||
|
||||
public CompletableFuture<?> getChunkSendSyncFuture() {
|
||||
- return this.sendSync;
|
||||
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public LevelChunk getChunkToSend() {
|
||||
- return !this.sendSync.isDone() ? null : this.getTickingChunk();
|
||||
+ return this.getSendingChunk(); // Paper - rewrite chunk system
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public final LevelChunk getFullChunk() { // Paper - final for inline
|
||||
- CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>> completablefuture = this.getFullChunkFuture();
|
||||
|
@ -17415,8 +17481,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
});
|
||||
}
|
||||
|
||||
- public void addSendDependency(CompletableFuture<?> postProcessingFuture) {
|
||||
- if (this.sendSync.isDone()) {
|
||||
- this.sendSync = postProcessingFuture;
|
||||
- } else {
|
||||
- this.sendSync = this.sendSync.thenCombine(postProcessingFuture, (object, object1) -> {
|
||||
- return null;
|
||||
- });
|
||||
- }
|
||||
-
|
||||
- }
|
||||
+ // Paper - rewrite chunk system
|
||||
+
|
||||
|
||||
public FullChunkStatus getFullStatus() {
|
||||
- return ChunkLevel.fullStatus(this.ticketLevel);
|
||||
+ return this.newChunkHolder.getChunkStatus(); // Paper - rewrite chunk system) {
|
||||
|
@ -17692,7 +17768,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
private static final int MIN_VIEW_DISTANCE = 2;
|
||||
public static final int MIN_VIEW_DISTANCE = 2;
|
||||
public static final int MAX_VIEW_DISTANCE = 32;
|
||||
public static final int FORCED_TICKET_LEVEL = ChunkLevel.byStatus(FullChunkStatus.ENTITY_TICKING);
|
||||
- public final Long2ObjectLinkedOpenHashMap<ChunkHolder> updatingChunkMap = new Long2ObjectLinkedOpenHashMap();
|
||||
|
@ -17725,7 +17801,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public final Int2ObjectMap<ChunkMap.TrackedEntity> entityMap;
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
private final Queue<Runnable> unloadQueue;
|
||||
int viewDistance;
|
||||
private int serverViewDistance;
|
||||
|
||||
- // CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback()
|
||||
- public final CallbackExecutor callbackExecutor = new CallbackExecutor();
|
||||
|
@ -17754,8 +17830,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
void addPlayerToDistanceMaps(ServerPlayer player) {
|
||||
+ this.level.playerChunkLoader.addPlayer(player); // Paper - replace chunk loader
|
||||
int chunkX = MCUtil.getChunkCoordinate(player.getX());
|
||||
int chunkZ = MCUtil.getChunkCoordinate(player.getZ());
|
||||
int chunkX = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getX());
|
||||
int chunkZ = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getZ());
|
||||
// Note: players need to be explicitly added to distance maps before they can be updated
|
||||
}
|
||||
|
||||
|
@ -17765,8 +17841,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
int chunkX = MCUtil.getChunkCoordinate(player.getX());
|
||||
int chunkZ = MCUtil.getChunkCoordinate(player.getZ());
|
||||
int chunkX = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getX());
|
||||
int chunkZ = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getZ());
|
||||
// Note: players need to be explicitly added to distance maps before they can be updated
|
||||
+ this.level.playerChunkLoader.updatePlayer(player); // Paper - replace chunk loader
|
||||
}
|
||||
|
@ -17817,6 +17893,36 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
this.overworldDataStorage = persistentStateManagerFactory;
|
||||
this.poiManager = new PoiManager(path.resolve("poi"), dataFixer, dsync, iregistrycustom, world);
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
boolean isChunkTracked(ServerPlayer player, int chunkX, int chunkZ) {
|
||||
- return player.getChunkTrackingView().contains(chunkX, chunkZ) && !player.connection.chunkSender.isPending(ChunkPos.asLong(chunkX, chunkZ));
|
||||
+ // Paper start - rewrite player chunk loader
|
||||
+ return this.level.playerChunkLoader.isChunkSent(player, chunkX, chunkZ);
|
||||
+ // Paper end - rewrite player chunk loader
|
||||
}
|
||||
|
||||
private boolean isChunkOnTrackedBorder(ServerPlayer player, int chunkX, int chunkZ) {
|
||||
- if (!this.isChunkTracked(player, chunkX, chunkZ)) {
|
||||
- return false;
|
||||
- } else {
|
||||
- for (int k = -1; k <= 1; ++k) {
|
||||
- for (int l = -1; l <= 1; ++l) {
|
||||
- if ((k != 0 || l != 0) && !this.isChunkTracked(player, chunkX + k, chunkZ + l)) {
|
||||
- return true;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return false;
|
||||
- }
|
||||
+ // Paper start - rewrite player chunk loader
|
||||
+ return this.level.playerChunkLoader.isChunkSent(player, chunkX, chunkZ, true);
|
||||
+ // Paper end - rewrite player chunk loader
|
||||
}
|
||||
|
||||
protected ThreadedLevelLightEngine getLightEngine() {
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
||||
@Nullable
|
||||
protected ChunkHolder getUpdatingChunkIfPresent(long pos) {
|
||||
|
@ -17847,6 +17953,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
public String getChunkDebugData(ChunkPos chunkPos) {
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
||||
// Paper start
|
||||
public final int getEffectiveViewDistance() {
|
||||
- // TODO this needs to be checked on update
|
||||
- // Mojang currently sets it to +1 of the configured view distance. So subtract one to get the one we really want.
|
||||
- //TODO check if +0 is correct now
|
||||
- return this.viewDistance;
|
||||
+ return this.serverViewDistance;
|
||||
}
|
||||
// Paper end
|
||||
|
||||
private CompletableFuture<Either<List<ChunkAccess>, ChunkHolder.ChunkLoadingFailure>> getChunkRangeFuture(ChunkHolder centerChunk, int margin, IntFunction<ChunkStatus> distanceToStatus) {
|
||||
|
@ -17903,7 +18018,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
-
|
||||
- Optional<ChunkAccess> optional = either.left();
|
||||
-
|
||||
- if (!optional.isPresent()) {
|
||||
- if (optional.isEmpty()) {
|
||||
- return Either.right(new ChunkHolder.ChunkLoadingFailure() {
|
||||
- public String toString() {
|
||||
- ChunkPos chunkcoordintpair2 = new ChunkPos(j + l1 % (margin * 2 + 1), k + l1 / (margin * 2 + 1));
|
||||
|
@ -18005,7 +18120,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
protected void saveAllChunks(boolean flush) {
|
||||
- if (flush) {
|
||||
- List<ChunkHolder> list = (List) io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).collect(Collectors.toList()); // Paper
|
||||
- List<ChunkHolder> list = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).toList(); // Paper
|
||||
- MutableBoolean mutableboolean = new MutableBoolean();
|
||||
-
|
||||
- do {
|
||||
|
@ -18286,11 +18401,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
|
||||
- private static void postLoadProtoChunk(ServerLevel world, List<CompoundTag> nbt) {
|
||||
+ public static void postLoadProtoChunk(ServerLevel world, List<CompoundTag> nbt) { // Paper - public
|
||||
+ public static void postLoadProtoChunk(ServerLevel world, List<CompoundTag> nbt, ChunkPos position) { // Paper - public and add chunk position parameter
|
||||
if (!nbt.isEmpty()) {
|
||||
// CraftBukkit start - these are spawned serialized (DefinedStructure) and we don't call an add event below at the moment due to ordering complexities
|
||||
world.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(nbt, world).filter((entity) -> {
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
needsRemoval = true;
|
||||
}
|
||||
return !needsRemoval;
|
||||
- }));
|
||||
+ }), position); // Paper - rewrite chunk system
|
||||
// CraftBukkit end
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> protoChunkToFullChunk(ChunkHolder chunkHolder) {
|
||||
|
@ -18351,6 +18474,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
- return either.ifLeft((chunk) -> {
|
||||
- chunk.postProcessGeneration();
|
||||
- this.level.startTickingChunk(chunk);
|
||||
- CompletableFuture<?> completablefuture2 = holder.getChunkSendSyncFuture();
|
||||
-
|
||||
- if (completablefuture2.isDone()) {
|
||||
- this.onChunkReadyToSend(chunk);
|
||||
- } else {
|
||||
- completablefuture2.thenAcceptAsync((object) -> {
|
||||
- this.onChunkReadyToSend(chunk);
|
||||
- }, this.mainThreadExecutor);
|
||||
- }
|
||||
-
|
||||
- });
|
||||
- }, this.mainThreadExecutor);
|
||||
-
|
||||
|
@ -18358,27 +18491,29 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
- this.tickingGenerated.getAndIncrement();
|
||||
- return null;
|
||||
- });
|
||||
- completablefuture1.thenAcceptAsync((either) -> {
|
||||
- either.ifLeft((chunk) -> {
|
||||
- MutableObject<ClientboundLevelChunkWithLightPacket> mutableobject = new MutableObject();
|
||||
-
|
||||
- this.getPlayers(holder.getPos(), false).forEach((entityplayer) -> {
|
||||
- this.playerLoadedChunk(entityplayer, mutableobject, chunk);
|
||||
- });
|
||||
- });
|
||||
- }, (runnable) -> {
|
||||
- this.mainThreadMailbox.tell(ChunkTaskPriorityQueueSorter.message(holder, runnable));
|
||||
- });
|
||||
- return completablefuture1;
|
||||
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
|
||||
}
|
||||
|
||||
private void onChunkReadyToSend(LevelChunk chunk) {
|
||||
- ChunkPos chunkcoordintpair = chunk.getPos();
|
||||
- Iterator iterator = this.playerMap.getAllPlayers().iterator();
|
||||
-
|
||||
- while (iterator.hasNext()) {
|
||||
- ServerPlayer entityplayer = (ServerPlayer) iterator.next();
|
||||
-
|
||||
- if (entityplayer.getChunkTrackingView().contains(chunkcoordintpair)) {
|
||||
- ChunkMap.markChunkPendingToSend(entityplayer, chunk);
|
||||
- }
|
||||
- }
|
||||
+ throw new UnsupportedOperationException(); // Paper - rewrite player chunk loader
|
||||
|
||||
}
|
||||
|
||||
public CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>> prepareAccessibleChunk(ChunkHolder holder) {
|
||||
- return this.getChunkRangeFuture(holder, 1, ChunkStatus::getStatusAroundFullChunk).thenApplyAsync((either) -> {
|
||||
- return either.mapLeft((list) -> {
|
||||
- LevelChunk chunk = (LevelChunk) list.get(list.size() / 2);
|
||||
-
|
||||
- return chunk;
|
||||
- return (LevelChunk) list.get(list.size() / 2);
|
||||
- });
|
||||
- }, (runnable) -> {
|
||||
- this.mainThreadMailbox.tell(ChunkTaskPriorityQueueSorter.message(holder, runnable));
|
||||
|
@ -18474,88 +18609,67 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
- this.markPositionReplaceable(pos);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- ChunkStatus.ChunkType chunkstatus_type = ChunkSerializer.getChunkTypeFromTag(nbttagcompound);
|
||||
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
|
||||
+ }
|
||||
|
||||
- ChunkStatus.ChunkType chunkstatus_type = ChunkSerializer.getChunkTypeFromTag(nbttagcompound);
|
||||
+ // Paper start - replace player loader system
|
||||
+ public void setTickViewDistance(int distance) {
|
||||
+ this.level.playerChunkLoader.setTickDistance(distance);
|
||||
+ }
|
||||
|
||||
- return this.markPosition(pos, chunkstatus_type) == 1;
|
||||
- }
|
||||
+ // Paper start - replace player loader system
|
||||
+ public void setTickViewDistance(int distance) {
|
||||
+ this.level.playerChunkLoader.setTickDistance(distance);
|
||||
}
|
||||
|
||||
+ public void setSendViewDistance(int distance) {
|
||||
+ this.level.playerChunkLoader.setSendDistance(distance);
|
||||
+ }
|
||||
}
|
||||
+ // Paper end - replace player loader system
|
||||
public void setViewDistance(int watchDistance) {
|
||||
|
||||
- protected void setServerViewDistance(int watchDistance) {
|
||||
+ public void setServerViewDistance(int watchDistance) { // Paper - replace player loader system
|
||||
int j = Mth.clamp(watchDistance, 2, 32);
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
int k = this.viewDistance;
|
||||
|
||||
this.viewDistance = j;
|
||||
- this.distanceManager.updatePlayerTickets(this.viewDistance);
|
||||
- Iterator objectiterator = io.papermc.paper.chunk.system.ChunkSystem.getUpdatingChunkHolders(this.level).iterator(); // Paper
|
||||
if (j != this.serverViewDistance) {
|
||||
this.serverViewDistance = j;
|
||||
- this.distanceManager.updatePlayerTickets(this.serverViewDistance);
|
||||
- Iterator iterator = this.playerMap.getAllPlayers().iterator();
|
||||
-
|
||||
- while (objectiterator.hasNext()) {
|
||||
- ChunkHolder playerchunk = (ChunkHolder) objectiterator.next();
|
||||
- ChunkPos chunkcoordintpair = playerchunk.getPos();
|
||||
- MutableObject<ClientboundLevelChunkWithLightPacket> mutableobject = new MutableObject();
|
||||
- while (iterator.hasNext()) {
|
||||
- ServerPlayer entityplayer = (ServerPlayer) iterator.next();
|
||||
-
|
||||
- this.getPlayers(chunkcoordintpair, false).forEach((entityplayer) -> {
|
||||
- SectionPos sectionposition = entityplayer.getLastSectionPos();
|
||||
- boolean flag = ChunkMap.isChunkInRange(chunkcoordintpair.x, chunkcoordintpair.z, sectionposition.x(), sectionposition.z(), k);
|
||||
- boolean flag1 = ChunkMap.isChunkInRange(chunkcoordintpair.x, chunkcoordintpair.z, sectionposition.x(), sectionposition.z(), this.viewDistance);
|
||||
-
|
||||
- this.updateChunkTracking(entityplayer, chunkcoordintpair, mutableobject, flag, flag1);
|
||||
- });
|
||||
- this.updateChunkTracking(entityplayer);
|
||||
- }
|
||||
+ this.level.playerChunkLoader.setLoadDistance(this.viewDistance + 1); // Paper - replace player loader system
|
||||
+ this.level.playerChunkLoader.setLoadDistance(this.serverViewDistance + 1); // Paper - replace player loader system
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- protected void updateChunkTracking(ServerPlayer player, ChunkPos pos, MutableObject<ClientboundLevelChunkWithLightPacket> packet, boolean oldWithinViewDistance, boolean newWithinViewDistance) {
|
||||
+ public void updateChunkTracking(ServerPlayer player, ChunkPos pos, MutableObject<ClientboundLevelChunkWithLightPacket> packet, boolean oldWithinViewDistance, boolean newWithinViewDistance) { // Paper - public
|
||||
+ io.papermc.paper.util.TickThread.ensureTickThread(this.level, pos, "May not update chunk tracking for chunk async"); // Paper - replace chunk loader system
|
||||
+ io.papermc.paper.util.TickThread.ensureTickThread(player, "May not update chunk tracking for player async"); // Paper - replace chunk loader system
|
||||
if (player.level() == this.level) {
|
||||
+ ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos.toLong()); // Paper - replace chunk loader system - move up
|
||||
if (newWithinViewDistance && !oldWithinViewDistance) {
|
||||
- ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos.toLong());
|
||||
+ // Paper - replace chunk loader system - move up
|
||||
|
||||
if (playerchunk != null) {
|
||||
- LevelChunk chunk = playerchunk.getTickingChunk();
|
||||
+ LevelChunk chunk = playerchunk.getSendingChunk(); // Paper - replace chunk loader system
|
||||
|
||||
if (chunk != null) {
|
||||
+ playerchunk.addPlayer(player); // Paper - replace chunk loader system
|
||||
this.playerLoadedChunk(player, packet, chunk);
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
if (!newWithinViewDistance && oldWithinViewDistance) {
|
||||
+ // Paper start - replace chunk loader system
|
||||
+ if (playerchunk != null) {
|
||||
+ playerchunk.removePlayer(player);
|
||||
+ } else {
|
||||
+ LOGGER.warn("ChunkHolder at " + pos + " in world '" + this.level.getWorld().getName() + "' does not exist to untrack chunk for " + player, new Throwable());
|
||||
+ }
|
||||
+ // Paper end - replace chunk loader system
|
||||
player.untrackChunk(pos);
|
||||
}
|
||||
|
||||
- }
|
||||
+ } else { LOGGER.warn("Mismatch in world for chunk " + pos + " in world '" + this.level.getWorld().getName() + "' for player " + player, new Throwable()); } // Paper - replace chunk loader system
|
||||
int getPlayerViewDistance(ServerPlayer player) {
|
||||
- return Mth.clamp(player.requestedViewDistance(), 2, this.serverViewDistance);
|
||||
+ return io.papermc.paper.chunk.system.ChunkSystem.getSendViewDistance(player); // Paper - per player view distance
|
||||
}
|
||||
|
||||
public int size() {
|
||||
private void markChunkPendingToSend(ServerPlayer player, ChunkPos pos) {
|
||||
- LevelChunk chunk = this.getChunkToSend(pos.toLong());
|
||||
-
|
||||
- if (chunk != null) {
|
||||
- ChunkMap.markChunkPendingToSend(player, chunk);
|
||||
- }
|
||||
+ throw new UnsupportedOperationException(); // Paper - per player view distance
|
||||
|
||||
}
|
||||
|
||||
private static void markChunkPendingToSend(ServerPlayer player, LevelChunk chunk) {
|
||||
- player.connection.chunkSender.markChunkPendingToSend(chunk);
|
||||
+ throw new UnsupportedOperationException(); // Paper - rewrite player chunk loader
|
||||
}
|
||||
|
||||
private static void dropChunk(ServerPlayer player, ChunkPos pos) {
|
||||
- player.connection.chunkSender.dropChunk(player, pos);
|
||||
+ // Paper - rewrite player chunk loader
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
|
@ -18625,90 +18739,93 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
return this.read(chunkPos).thenApplyAsync((optional) -> {
|
||||
return optional.map((nbttagcompound) -> this.upgradeChunkTag(nbttagcompound, chunkPos)); // CraftBukkit
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
this.distanceManager.addPlayer(SectionPos.of((EntityAccess) player), player);
|
||||
}
|
||||
|
||||
- player.setChunkTrackingView(ChunkTrackingView.EMPTY);
|
||||
- this.updateChunkTracking(player);
|
||||
+ // Paper - handled by player chunk loader
|
||||
this.addPlayerToDistanceMaps(player); // Paper - distance maps
|
||||
} else {
|
||||
SectionPos sectionposition = player.getLastSectionPos();
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
this.removePlayerFromDistanceMaps(player); // Paper - distance maps
|
||||
- this.applyChunkTrackingView(player, ChunkTrackingView.EMPTY);
|
||||
+ // Paper - handled by player chunk loader
|
||||
}
|
||||
|
||||
- for (int k = i - this.viewDistance - 1; k <= i + this.viewDistance + 1; ++k) {
|
||||
- for (int l = j - this.viewDistance - 1; l <= j + this.viewDistance + 1; ++l) {
|
||||
- if (ChunkMap.isChunkInRange(k, l, i, j, this.viewDistance)) {
|
||||
- ChunkPos chunkcoordintpair = new ChunkPos(k, l);
|
||||
-
|
||||
- this.updateChunkTracking(player, chunkcoordintpair, new MutableObject(), !added, added);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ // Paper - handled by player chunk loader
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
SectionPos sectionposition = SectionPos.of((EntityAccess) player);
|
||||
this.playerMap.unIgnorePlayer(player);
|
||||
}
|
||||
|
||||
player.setLastSectionPos(sectionposition);
|
||||
- player.connection.send(new ClientboundSetChunkCacheCenterPacket(sectionposition.x(), sectionposition.z()));
|
||||
+ //player.connection.send(new ClientboundSetChunkCacheCenterPacket(sectionposition.x(), sectionposition.z())); // Paper - handled by player chunk loader
|
||||
return sectionposition;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
int l1;
|
||||
int i2;
|
||||
|
||||
- if (Math.abs(i1 - i) <= k1 * 2 && Math.abs(j1 - j) <= k1 * 2) {
|
||||
- l1 = Math.min(i, i1) - k1;
|
||||
- i2 = Math.min(j, j1) - k1;
|
||||
- int j2 = Math.max(i, i1) + k1;
|
||||
- int k2 = Math.max(j, j1) + k1;
|
||||
-
|
||||
- for (int l2 = l1; l2 <= j2; ++l2) {
|
||||
- for (int i3 = i2; i3 <= k2; ++i3) {
|
||||
- boolean flag3 = ChunkMap.isChunkInRange(l2, i3, i1, j1, this.viewDistance);
|
||||
- boolean flag4 = ChunkMap.isChunkInRange(l2, i3, i, j, this.viewDistance);
|
||||
-
|
||||
- this.updateChunkTracking(player, new ChunkPos(l2, i3), new MutableObject(), flag3, flag4);
|
||||
- }
|
||||
- }
|
||||
- } else {
|
||||
- boolean flag5;
|
||||
- boolean flag6;
|
||||
-
|
||||
- for (l1 = i1 - k1; l1 <= i1 + k1; ++l1) {
|
||||
- for (i2 = j1 - k1; i2 <= j1 + k1; ++i2) {
|
||||
- if (ChunkMap.isChunkInRange(l1, i2, i1, j1, this.viewDistance)) {
|
||||
- flag5 = true;
|
||||
- flag6 = false;
|
||||
- this.updateChunkTracking(player, new ChunkPos(l1, i2), new MutableObject(), true, false);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- for (l1 = i - k1; l1 <= i + k1; ++l1) {
|
||||
- for (i2 = j - k1; i2 <= j + k1; ++i2) {
|
||||
- if (ChunkMap.isChunkInRange(l1, i2, i, j, this.viewDistance)) {
|
||||
- flag5 = false;
|
||||
- flag6 = true;
|
||||
- this.updateChunkTracking(player, new ChunkPos(l1, i2), new MutableObject(), false, true);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ // Paper - replaced by PlayerChunkLoader
|
||||
- this.updateChunkTracking(player);
|
||||
+ // Paper - replaced by PlayerChunkLoader
|
||||
}
|
||||
|
||||
this.updateMaps(player); // Paper - distance maps
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
private void updateChunkTracking(ServerPlayer player) {
|
||||
- ChunkPos chunkcoordintpair = player.chunkPosition();
|
||||
- int i = this.getPlayerViewDistance(player);
|
||||
- ChunkTrackingView chunktrackingview = player.getChunkTrackingView();
|
||||
-
|
||||
- if (chunktrackingview instanceof ChunkTrackingView.Positioned) {
|
||||
- ChunkTrackingView.Positioned chunktrackingview_a = (ChunkTrackingView.Positioned) chunktrackingview;
|
||||
-
|
||||
- if (chunktrackingview_a.center().equals(chunkcoordintpair) && chunktrackingview_a.viewDistance() == i) {
|
||||
- return;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- this.applyChunkTrackingView(player, ChunkTrackingView.of(chunkcoordintpair, i));
|
||||
+ throw new UnsupportedOperationException(); // Paper - replaced by PlayerChunkLoader
|
||||
}
|
||||
|
||||
private void applyChunkTrackingView(ServerPlayer player, ChunkTrackingView chunkFilter) {
|
||||
- if (player.level() == this.level) {
|
||||
- ChunkTrackingView chunktrackingview1 = player.getChunkTrackingView();
|
||||
-
|
||||
- if (chunkFilter instanceof ChunkTrackingView.Positioned) {
|
||||
- label15:
|
||||
- {
|
||||
- ChunkTrackingView.Positioned chunktrackingview_a = (ChunkTrackingView.Positioned) chunkFilter;
|
||||
-
|
||||
- if (chunktrackingview1 instanceof ChunkTrackingView.Positioned) {
|
||||
- ChunkTrackingView.Positioned chunktrackingview_a1 = (ChunkTrackingView.Positioned) chunktrackingview1;
|
||||
-
|
||||
- if (chunktrackingview_a1.center().equals(chunktrackingview_a.center())) {
|
||||
- break label15;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- player.connection.send(new ClientboundSetChunkCacheCenterPacket(chunktrackingview_a.center().x, chunktrackingview_a.center().z));
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- ChunkTrackingView.difference(chunktrackingview1, chunkFilter, (chunkcoordintpair) -> {
|
||||
- this.markChunkPendingToSend(player, chunkcoordintpair);
|
||||
- }, (chunkcoordintpair) -> {
|
||||
- ChunkMap.dropChunk(player, chunkcoordintpair);
|
||||
- });
|
||||
- player.setChunkTrackingView(chunkFilter);
|
||||
- }
|
||||
+ throw new UnsupportedOperationException(); // Paper - replaced by PlayerChunkLoader
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServerPlayer> getPlayers(ChunkPos chunkPos, boolean onlyOnWatchDistanceEdge) {
|
||||
- Set<ServerPlayer> set = this.playerMap.getPlayers(chunkPos.toLong());
|
||||
- Set<ServerPlayer> set = this.playerMap.getAllPlayers();
|
||||
- Builder<ServerPlayer> builder = ImmutableList.builder();
|
||||
- Iterator iterator = set.iterator();
|
||||
-
|
||||
- while (iterator.hasNext()) {
|
||||
- ServerPlayer entityplayer = (ServerPlayer) iterator.next();
|
||||
- SectionPos sectionposition = entityplayer.getLastSectionPos();
|
||||
-
|
||||
- if (onlyOnWatchDistanceEdge && ChunkMap.isChunkOnRangeBorder(chunkPos.x, chunkPos.z, sectionposition.x(), sectionposition.z(), this.viewDistance) || !onlyOnWatchDistanceEdge && ChunkMap.isChunkInRange(chunkPos.x, chunkPos.z, sectionposition.x(), sectionposition.z(), this.viewDistance)) {
|
||||
- if (onlyOnWatchDistanceEdge && this.isChunkOnTrackedBorder(entityplayer, chunkPos.x, chunkPos.z) || !onlyOnWatchDistanceEdge && this.isChunkTracked(entityplayer, chunkPos.x, chunkPos.z)) {
|
||||
- builder.add(entityplayer);
|
||||
- }
|
||||
+ // Paper start - per player view distance
|
||||
|
@ -18725,6 +18842,39 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
public void addEntity(Entity entity) {
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
protected void tick() {
|
||||
- Iterator iterator = this.playerMap.getAllPlayers().iterator();
|
||||
-
|
||||
- while (iterator.hasNext()) {
|
||||
- ServerPlayer entityplayer = (ServerPlayer) iterator.next();
|
||||
-
|
||||
- this.updateChunkTracking(entityplayer);
|
||||
- }
|
||||
+ // Paper - replaced by PlayerChunkLoader
|
||||
|
||||
List<ServerPlayer> list = Lists.newArrayList();
|
||||
List<ServerPlayer> list1 = this.level.players();
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
public void waitForLightBeforeSending(ChunkPos centerPos, int radius) {
|
||||
- int j = radius + 1;
|
||||
-
|
||||
- ChunkPos.rangeClosed(centerPos, j).forEach((chunkcoordintpair1) -> {
|
||||
- ChunkHolder playerchunk = this.getVisibleChunkIfPresent(chunkcoordintpair1.toLong());
|
||||
-
|
||||
- if (playerchunk != null) {
|
||||
- playerchunk.addSendDependency(this.lightEngine.waitForPendingTasks(chunkcoordintpair1.x, chunkcoordintpair1.z));
|
||||
- }
|
||||
-
|
||||
- });
|
||||
+ // Paper - rewrite player chunk loader
|
||||
}
|
||||
|
||||
private class ChunkDistanceManager extends DistanceManager {
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
||||
@Override
|
||||
protected boolean isChunkToRemove(long pos) {
|
||||
|
@ -18733,15 +18883,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
|
||||
@Nullable
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot
|
||||
if (player != this.entity) {
|
||||
Vec3 vec3d = player.position().subtract(this.entity.position());
|
||||
- double d0 = (double) Math.min(this.getEffectiveRange(), ChunkMap.this.viewDistance * 16);
|
||||
+ double d0 = (double) Math.min(this.getEffectiveRange(), io.papermc.paper.chunk.system.ChunkSystem.getSendViewDistance(player) * 16); // Paper - per player view distance
|
||||
double d1 = vec3d.x * vec3d.x + vec3d.z * vec3d.z;
|
||||
double d2 = d0 * d0;
|
||||
boolean flag = d1 <= d2 && this.entity.broadcastToPlayer(player);
|
||||
diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/DistanceManager.java
|
||||
|
@ -19048,7 +19189,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
protected void updatePlayerTickets(int viewDistance) {
|
||||
- this.playerTicketManager.updateViewDistance(viewDistance);
|
||||
+ this.chunkMap.setViewDistance(viewDistance);// Paper - route to player chunk manager
|
||||
+ this.chunkMap.setServerViewDistance(viewDistance);// Paper - route to player chunk manager
|
||||
}
|
||||
|
||||
// Paper start
|
||||
|
@ -19721,8 +19862,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
java.util.function.Consumer<net.minecraft.world.level.chunk.ChunkAccess> consumer = (net.minecraft.world.level.chunk.ChunkAccess chunk) -> {
|
||||
if (chunk != null) {
|
||||
- int ticketLevel = Math.max(33, chunkProvider.chunkMap.getUpdatingChunkIfPresent(chunk.getPos().toLong()).getTicketLevel());
|
||||
+ synchronized (ret) { // Folia - region threading - make callback thread-safe TODO rebase
|
||||
ret.add(chunk);
|
||||
- ticketLevels.add(ticketLevel);
|
||||
+ } // Folia - region threading - make callback thread-safe TODO rebase
|
||||
chunkProvider.addTicketAtLevel(TicketType.FUTURE_AWAIT, chunk.getPos(), ticketLevel, holderIdentifier);
|
||||
}
|
||||
- if (++loadedChunks[0] == requiredChunks) {
|
||||
|
@ -19985,7 +20128,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
});
|
||||
this.chunkSource.getGeneratorState().ensureStructuresGenerated();
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
}, "random_sequences");
|
||||
return (RandomSequences) this.getDataStorage().computeIfAbsent(RandomSequences.factory(l), "random_sequences");
|
||||
});
|
||||
this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
|
||||
+
|
||||
|
@ -20131,14 +20274,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ return this.entityLookup; // Paper - rewrite chunk system
|
||||
}
|
||||
|
||||
public void addLegacyChunkEntities(Stream<Entity> entities) {
|
||||
- public void addLegacyChunkEntities(Stream<Entity> entities) {
|
||||
- this.entityManager.addLegacyChunkEntities(entities);
|
||||
+ this.entityLookup.addLegacyChunkEntities(entities.toList()); // Paper - rewrite chunk system
|
||||
+ public void addLegacyChunkEntities(Stream<Entity> entities, ChunkPos forChunk) { // Paper - rewrite chunk system
|
||||
+ this.entityLookup.addLegacyChunkEntities(entities.toList(), forChunk); // Paper - rewrite chunk system
|
||||
}
|
||||
|
||||
public void addWorldGenChunkEntities(Stream<Entity> entities) {
|
||||
- public void addWorldGenChunkEntities(Stream<Entity> entities) {
|
||||
- this.entityManager.addWorldGenChunkEntities(entities);
|
||||
+ this.entityLookup.addWorldGenChunkEntities(entities.toList()); // Paper - rewrite chunk system
|
||||
+ public void addWorldGenChunkEntities(Stream<Entity> entities, ChunkPos forChunk) { // Paper - rewrite chunk system
|
||||
+ this.entityLookup.addWorldGenChunkEntities(entities.toList(), forChunk); // Paper - rewrite chunk system
|
||||
}
|
||||
|
||||
public void startTickingChunk(LevelChunk chunk) {
|
||||
|
@ -20207,6 +20352,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public boolean isRealPlayer; // Paper
|
||||
public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> cachedSingleHashSet; // Paper
|
||||
|
||||
+ // Paper start - replace player chunk loader
|
||||
+ private final java.util.concurrent.atomic.AtomicReference<io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances> viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1));
|
||||
+ public io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
|
||||
+
|
||||
|
@ -20248,8 +20394,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ return input.setSendViewDistance(distance);
|
||||
+ });
|
||||
+ }
|
||||
+ // Paper end - replace player chunk loader
|
||||
+
|
||||
public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile) {
|
||||
public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) {
|
||||
super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile);
|
||||
this.chatVisibility = ChatVisiblity.FULL;
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java b/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java
|
||||
|
@ -20425,7 +20572,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
|
||||
}
|
||||
|
||||
static enum TaskType {
|
||||
public CompletableFuture<?> waitForPendingTasks(int x, int z) {
|
||||
diff --git a/src/main/java/net/minecraft/server/level/Ticket.java b/src/main/java/net/minecraft/server/level/Ticket.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/Ticket.java
|
||||
|
@ -20522,11 +20669,55 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ public <T> void getEntitiesByClass(Class<? extends T> clazz, Entity except, AABB box, List<? super T> into, Predicate<? super T> predicate) {}
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/network/PlayerChunkSender.java b/src/main/java/net/minecraft/server/network/PlayerChunkSender.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/PlayerChunkSender.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/PlayerChunkSender.java
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkSender {
|
||||
this.pendingChunks.add(chunk.getPos().toLong());
|
||||
}
|
||||
|
||||
+ // Paper start - rewrite player chunk loader
|
||||
+ public static void dropChunkStatic(ServerPlayer player, ChunkPos pos) {
|
||||
+ player.connection.send(new ClientboundForgetLevelChunkPacket(pos));
|
||||
+ }
|
||||
+ // Paper end - rewrite player chunk loader
|
||||
+
|
||||
public void dropChunk(ServerPlayer player, ChunkPos pos) {
|
||||
if (!this.pendingChunks.remove(pos.toLong()) && player.isAlive()) {
|
||||
- player.connection.send(new ClientboundForgetLevelChunkPacket(pos));
|
||||
+ dropChunkStatic(player, pos); // Paper - rewrite player chunk loader - move into own method
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void sendNextChunks(ServerPlayer player) {
|
||||
+ if (true) return; // Paper - rewrite player chunk loader
|
||||
if (this.unacknowledgedBatches < this.maxUnacknowledgedBatches) {
|
||||
float f = Math.max(1.0F, this.desiredChunksPerTick);
|
||||
this.batchQuota = Math.min(this.batchQuota + this.desiredChunksPerTick, f);
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkSender {
|
||||
}
|
||||
}
|
||||
|
||||
- private static void sendChunk(ServerGamePacketListenerImpl handler, ServerLevel world, LevelChunk chunk) {
|
||||
+ public static void sendChunk(ServerGamePacketListenerImpl handler, ServerLevel world, LevelChunk chunk) { // Paper - rewrite chunk loader - public
|
||||
handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), (BitSet)null, (BitSet)null));
|
||||
ChunkPos chunkPos = chunk.getPos();
|
||||
DebugPackets.sendPoiPacketsForChunk(world, chunkPos);
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkSender {
|
||||
}
|
||||
|
||||
public void onChunkBatchReceivedByClient(float desiredBatchSize) {
|
||||
+ if (true) return; // Paper - rewrite player chunk loader
|
||||
--this.unacknowledgedBatches;
|
||||
this.desiredChunksPerTick = Double.isNaN((double)desiredBatchSize) ? 0.01F : Mth.clamp(desiredBatchSize, 0.01F, 64.0F);
|
||||
if (this.unacknowledgedBatches == 0) {
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
this.disconnect(Component.translatable("disconnect.spam"));
|
||||
return;
|
||||
}
|
||||
|
@ -20545,25 +20736,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
boolean flag1 = gamerules.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO);
|
||||
boolean flag2 = gamerules.getBoolean(GameRules.RULE_LIMITED_CRAFTING);
|
||||
|
||||
// Spigot - view distance
|
||||
- playerconnection.send(new ClientboundLoginPacket(player.getId(), worlddata.isHardcore(), player.gameMode.getGameModeForPlayer(), player.gameMode.getPreviousGameModeForPlayer(), this.server.levelKeys(), this.synchronizedRegistries, worldserver1.dimensionTypeId(), worldserver1.dimension(), BiomeManager.obfuscateSeed(worldserver1.getSeed()), this.getMaxPlayers(), worldserver1.spigotConfig.viewDistance, worldserver1.spigotConfig.simulationDistance, flag1, !flag, worldserver1.isDebug(), worldserver1.isFlat(), player.getLastDeathLocation(), player.getPortalCooldown()));
|
||||
+ playerconnection.send(new ClientboundLoginPacket(player.getId(), worlddata.isHardcore(), player.gameMode.getGameModeForPlayer(), player.gameMode.getPreviousGameModeForPlayer(), this.server.levelKeys(), this.synchronizedRegistries, worldserver1.dimensionTypeId(), worldserver1.dimension(), BiomeManager.obfuscateSeed(worldserver1.getSeed()), this.getMaxPlayers(), worldserver1.getWorld().getSendViewDistance(), worldserver1.getWorld().getSimulationDistance(), flag1, !flag, worldserver1.isDebug(), worldserver1.isFlat(), player.getLastDeathLocation(), player.getPortalCooldown())); // Paper - replace old player chunk management
|
||||
- playerconnection.send(new ClientboundLoginPacket(player.getId(), worlddata.isHardcore(), this.server.levelKeys(), this.getMaxPlayers(), worldserver1.spigotConfig.viewDistance, worldserver1.spigotConfig.simulationDistance, flag1, !flag, flag2, player.createCommonSpawnInfo(worldserver1)));
|
||||
+ playerconnection.send(new ClientboundLoginPacket(player.getId(), worlddata.isHardcore(), this.server.levelKeys(), this.getMaxPlayers(), worldserver1.getWorld().getSendViewDistance(), worldserver1.getWorld().getSimulationDistance(), flag1, !flag, flag2, player.createCommonSpawnInfo(worldserver1))); // Paper - replace old player chunk management
|
||||
player.getBukkitEntity().sendSupportedChannels(); // CraftBukkit
|
||||
playerconnection.send(new ClientboundUpdateEnabledFeaturesPacket(FeatureFlags.REGISTRY.toNames(worldserver1.enabledFeatures())));
|
||||
playerconnection.send(new ClientboundCustomPayloadPacket(ClientboundCustomPayloadPacket.BRAND, (new FriendlyByteBuf(Unpooled.buffer())).writeUtf(this.getServer().getServerModName())));
|
||||
playerconnection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
|
||||
playerconnection.send(new ClientboundPlayerAbilitiesPacket(player.getAbilities()));
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
// CraftBukkit start
|
||||
LevelData worlddata = worldserver1.getLevelData();
|
||||
entityplayer1.connection.send(new ClientboundRespawnPacket(worldserver1.dimensionTypeId(), worldserver1.dimension(), BiomeManager.obfuscateSeed(worldserver1.getSeed()), entityplayer1.gameMode.getGameModeForPlayer(), entityplayer1.gameMode.getPreviousGameModeForPlayer(), worldserver1.isDebug(), worldserver1.isFlat(), (byte) i, entityplayer1.getLastDeathLocation(), entityplayer1.getPortalCooldown()));
|
||||
LevelData worlddata = worldserver2.getLevelData();
|
||||
|
||||
entityplayer1.connection.send(new ClientboundRespawnPacket(entityplayer1.createCommonSpawnInfo(worldserver2), (byte) i));
|
||||
- entityplayer1.connection.send(new ClientboundSetChunkCacheRadiusPacket(worldserver1.spigotConfig.viewDistance)); // Spigot
|
||||
- entityplayer1.connection.send(new ClientboundSetSimulationDistancePacket(worldserver1.spigotConfig.simulationDistance)); // Spigot
|
||||
+ entityplayer1.connection.send(new ClientboundSetChunkCacheRadiusPacket(worldserver1.getWorld().getSendViewDistance())); // Spigot // Paper - replace old player chunk management
|
||||
+ entityplayer1.connection.send(new ClientboundSetSimulationDistancePacket(worldserver1.getWorld().getSimulationDistance())); // Spigot // Paper - replace old player chunk management
|
||||
entityplayer1.spawnIn(worldserver1);
|
||||
entityplayer1.unsetRemoved();
|
||||
entityplayer1.connection.teleport(CraftLocation.toBukkit(entityplayer1.position(), worldserver1.getWorld(), entityplayer1.getYRot(), entityplayer1.getXRot()));
|
||||
entityplayer1.connection.teleport(CraftLocation.toBukkit(entityplayer1.position(), worldserver2.getWorld(), entityplayer1.getYRot(), entityplayer1.getXRot())); // CraftBukkit
|
||||
entityplayer1.connection.send(new ClientboundSetDefaultSpawnPositionPacket(worldserver1.getSharedSpawnPos(), worldserver1.getSharedSpawnAngle()));
|
||||
entityplayer1.connection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
|
||||
public void setViewDistance(int viewDistance) {
|
||||
|
@ -21689,6 +21880,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
nbttagcompound.put("PostProcessing", ChunkSerializer.packOffsets(chunk.getPostProcessing()));
|
||||
CompoundTag nbttagcompound3 = new CompoundTag();
|
||||
Iterator iterator1 = chunk.getHeightmaps().iterator();
|
||||
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
||||
|
||||
return nbttaglist == null && nbttaglist1 == null ? null : (chunk) -> {
|
||||
if (nbttaglist != null) {
|
||||
- world.addLegacyChunkEntities(EntityType.loadEntitiesRecursive(nbttaglist, world));
|
||||
+ world.addLegacyChunkEntities(EntityType.loadEntitiesRecursive(nbttaglist, world), chunk.getPos()); // Paper - rewrite chunk system
|
||||
}
|
||||
|
||||
if (nbttaglist1 != null) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
||||
|
@ -22798,7 +22998,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ throw new IllegalArgumentException("View distance " + viewDistance + " is out of range of [2, 32]");
|
||||
+ }
|
||||
+ net.minecraft.server.level.ChunkMap chunkMap = getHandle().getChunkSource().chunkMap;
|
||||
+ chunkMap.setViewDistance(viewDistance);
|
||||
+ chunkMap.setServerViewDistance(viewDistance);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
|
@ -15,9 +15,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable {
|
||||
if (regionfile != null) {
|
||||
return regionfile;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
// Paper end - cache regionfile does not exist state
|
||||
- if (this.regionCache.size() >= 256) {
|
||||
+ if (this.regionCache.size() >= io.papermc.paper.configuration.GlobalConfiguration.get().misc.regionFileCacheSize) { // Paper - configurable
|
||||
((RegionFile) this.regionCache.removeLast()).close();
|
||||
|
|
|
@ -66,7 +66,7 @@ diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
|
||||
|
||||
private WatchdogThread(long timeoutTime, boolean restart)
|
||||
{
|
||||
|
@ -75,7 +75,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
this.timeoutTime = timeoutTime;
|
||||
this.restart = restart;
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
|
||||
{
|
||||
Logger log = Bukkit.getServer().getLogger();
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
|
@ -93,12 +93,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
//
|
||||
if ( net.minecraft.world.level.Level.lastPhysicsProblem != null )
|
||||
{
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
|
||||
}
|
||||
//
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
- log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Spigot!):" );
|
||||
+ log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
|
||||
io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(isLongTimeout); // Paper // Paper - rewrite chunk system
|
||||
WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
//
|
||||
|
|
|
@ -8,7 +8,7 @@ diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
|
||||
while ( !this.stopping )
|
||||
{
|
||||
//
|
||||
|
|
|
@ -19,9 +19,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
private QueryThreadGs4 queryThreadGs4;
|
||||
// private final RemoteControlCommandListener rconConsoleSource; // CraftBukkit - remove field
|
||||
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
}
|
||||
|
||||
public void handleConsoleInput(String command, CommandSourceStack commandSource) {
|
||||
return;
|
||||
}
|
||||
// Paper end - rewrite chunk system
|
||||
- this.consoleInput.add(new ConsoleInput(command, commandSource));
|
||||
+ this.serverCommandQueue.add(new ConsoleInput(command, commandSource)); // Paper - use proper queue
|
||||
}
|
||||
|
|
|
@ -14,5 +14,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
+ internal.keepSpawnInMemory = creator.keepSpawnLoaded().toBooleanOrElse(internal.getWorld().getKeepSpawnInMemory()); // Paper
|
||||
this.getServer().prepareLevels(internal.getChunkSource().chunkMap.progressListener, internal);
|
||||
internal.entityManager.tick(); // SPIGOT-6526: Load pending entities so they are available to the API
|
||||
//internal.entityManager.tick(); // SPIGOT-6526: Load pending entities so they are available to the API // Paper - rewrite chunk system
|
||||
|
||||
|
|
|
@ -261,8 +261,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
private int serverViewDistance;
|
||||
+ public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobDistanceMap; // Paper
|
||||
|
||||
// CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback()
|
||||
public final CallbackExecutor callbackExecutor = new CallbackExecutor();
|
||||
// Paper - rewrite chunk system
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
int chunkX = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getX());
|
||||
int chunkZ = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getZ());
|
||||
|
@ -275,6 +275,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
|
||||
void removePlayerFromDistanceMaps(ServerPlayer player) {
|
||||
this.level.playerChunkLoader.removePlayer(player); // Paper - replace chunk loader
|
||||
|
||||
+ // Paper start - per player mob spawning
|
||||
+ if (this.playerMobDistanceMap != null) {
|
||||
|
@ -284,9 +285,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
|
||||
void updateMaps(ServerPlayer player) {
|
||||
int chunkX = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getX());
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
int chunkZ = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getZ());
|
||||
// Note: players need to be explicitly added to distance maps before they can be updated
|
||||
this.level.playerChunkLoader.updatePlayer(player); // Paper - replace chunk loader
|
||||
+
|
||||
+ // Paper start - per player mob spawning
|
||||
+ if (this.playerMobDistanceMap != null) {
|
||||
|
|
|
@ -112,8 +112,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper end
|
||||
+
|
||||
public void save(@Nullable ProgressListener progressListener, boolean flush, boolean savingDisabled) {
|
||||
ServerChunkCache chunkproviderserver = this.getChunkSource();
|
||||
|
||||
// Paper start - rewrite chunk system - add close param
|
||||
this.save(progressListener, flush, savingDisabled, false);
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
|
|
Loading…
Reference in a new issue