[ci skip] Move some disruptive patches back

This commit is contained in:
Nassim Jahnke 2024-01-23 15:43:48 +01:00
parent 88d3d87993
commit 091f54138b
23 changed files with 91 additions and 120 deletions

View file

@ -85,37 +85,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return true;
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
// Paper start - Optimize this method
ChunkPos chunkPos = new ChunkPos(x, z);
+ ChunkAccess immediate = world.getChunkSource().getChunkAtIfLoadedImmediately(x, z); // Paper
+ if (immediate != null) return true; // Paper
if (!generate) {
- ChunkAccess immediate = world.getChunkSource().getChunkAtImmediately(x, z);
+
+ //IChunkAccess immediate = world.getChunkProvider().getChunkAtImmediately(x, z); // Paper
if (immediate == null) {
immediate = world.getChunkSource().chunkMap.getUnloadingChunk(x, z);
}
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
if (!(immediate instanceof ImposterProtoChunk) && !(immediate instanceof net.minecraft.world.level.chunk.LevelChunk)) {
return false; // not full status
}
- world.getChunkSource().addRegionTicket(TicketType.PLUGIN, chunkPos, 1, Unit.INSTANCE);
+ world.getChunkSource().addRegionTicket(TicketType.PLUGIN, chunkPos, 0, Unit.INSTANCE); // Paper
world.getChunk(x, z); // make sure we're at ticket level 32 or lower
return true;
}
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
// we do this so we do not re-read the chunk data on disk
}
- world.getChunkSource().addRegionTicket(TicketType.PLUGIN, chunkPos, 1, Unit.INSTANCE);
+ world.getChunkSource().addRegionTicket(TicketType.PLUGIN, chunkPos, 0, Unit.INSTANCE); // Paper
world.getChunkSource().getChunk(x, z, ChunkStatus.FULL, true);
return true;
// Paper end - Optimize this method
if (chunk instanceof net.minecraft.world.level.chunk.LevelChunk) {
- this.world.getChunkSource().addRegionTicket(TicketType.PLUGIN, new ChunkPos(x, z), 1, Unit.INSTANCE);
+ this.world.getChunkSource().addRegionTicket(TicketType.PLUGIN, new ChunkPos(x, z), 0, Unit.INSTANCE); // Paper
return true;
}
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
io.papermc.paper.chunk.system.ChunkSystem.scheduleChunkLoad(this.getHandle(), x, z, gen, ChunkStatus.FULL, true, priority, (c) -> {
net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> {

View file

@ -9,9 +9,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, S
// Spigot end
// Paper start
protected int numCollisions = 0; // Paper - Cap entity collisions
public long activatedImmunityTick = Integer.MIN_VALUE; // Paper
public boolean isTemporarilyActive; // Paper
+ public boolean fromNetherPortal; // Paper - Add option to nerf pigmen from nether portals
public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one
@javax.annotation.Nullable

View file

@ -275,8 +275,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end - Add mobcaps commands
+
public static void spawnCategoryForChunk(MobCategory group, ServerLevel world, LevelChunk chunk, NaturalSpawner.SpawnPredicate checker, NaturalSpawner.AfterSpawnCallback runner) {
// Paper start - Optional per player mob spawns
spawnCategoryForChunk(group, world, chunk, checker, runner, Integer.MAX_VALUE, null);
BlockPos blockposition = NaturalSpawner.getRandomPosWithin(world, chunk);
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

View file

@ -55,7 +55,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public final Path regionFile; // Paper
public RegionFile(Path file, Path directory, boolean dsync) throws IOException {
this(file, directory, RegionFileVersion.VERSION_DEFLATE, dsync);
this(file, directory, RegionFileVersion.getCompressionFormat(), dsync); // Paper - Configurable region compression format
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
public RegionFile(Path file, Path directory, RegionFileVersion outputChunkStreamVersion, boolean dsync) throws IOException {
@ -66,9 +66,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.version = outputChunkStreamVersion;
if (!Files.isDirectory(directory, new LinkOption[0])) {
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
}
public static final int MAX_CHUNK_SIZE = 500 * 1024 * 1024; // Paper - don't write garbage data to disk if writing serialization fails
+ // Paper start
+ private final byte[] oversized = new byte[1024];
+ private int oversizedCount;
@ -206,6 +206,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
try {
NbtIo.write(nbt, (DataOutput) dataoutputstream);
+ regionfile.setOversized(pos.x, pos.z, false); // Paper - We don't do this anymore, mojang stores differently, but clear old meta flag if it exists to get rid of our own meta file once last oversized is gone
} catch (Throwable throwable) {
if (dataoutputstream != null) {
try {
// Paper start - don't write garbage data to disk if writing serialization fails
dataoutputstream.close(); // Only write if successful
} catch (final RegionFileSizeException e) {

View file

@ -9,7 +9,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(Registries.BIOME), world); // Paper - Anti-Xray - Add parameters
return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(Registries.BIOME));
}
+ // Paper start - Allow delegation to vanilla chunk gen

View file

@ -1151,9 +1151,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ final boolean shouldModify = world.chunkPacketBlockController.shouldModify(handler.player, chunk);
+ handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), (BitSet)null, (BitSet)null, shouldModify));
+ // Paper end - Anti-Xray
ChunkPos chunkPos = chunk.getPos();
DebugPackets.sendPoiPacketsForChunk(world, chunkPos);
}
// Paper start - PlayerChunkLoadEvent
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();
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
@ -1277,9 +1277,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ private final T @org.jetbrains.annotations.Nullable [] presetValues; // Paper - Anti-Xray - Add preset values
private volatile PalettedContainer.Data<T> data;
private final PalettedContainer.Strategy strategy;
private final ThreadingDetector threadingDetector = new ThreadingDetector("PalettedContainer");
// private final ThreadingDetector threadingDetector = new ThreadingDetector("PalettedContainer"); // Paper - unused
@@ -0,0 +0,0 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
this.threadingDetector.checkAndUnlock();
// this.threadingDetector.checkAndUnlock(); // Paper - disable this
}
- public static <T> Codec<PalettedContainer<T>> codecRW(IdMap<T> idList, Codec<T> entryCodec, PalettedContainer.Strategy paletteProvider, T defaultValue) {
@ -1359,7 +1359,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.data = this.createOrReuseData((PalettedContainer.Data<T>)null, 0);
@@ -0,0 +0,0 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
@Override
public int onResize(int newBits, T object) {
public synchronized int onResize(int newBits, T object) { // Paper - synchronize
PalettedContainer.Data<T> data = this.data;
+
+ // Paper start - Anti-Xray - Add preset values
@ -1403,12 +1403,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
+ // Paper start - Anti-Xray - Add chunk packet info
+ // Paper start - Anti-Xray; Add chunk packet info
+ @Override
+ @Deprecated @io.papermc.paper.annotation.DoNotUse public void write(FriendlyByteBuf buf) { this.write(buf, null, 0); }
@Override
- public void write(FriendlyByteBuf buf) {
+ public void write(FriendlyByteBuf buf, @Nullable com.destroystokyo.paper.antixray.ChunkPacketInfo<T> chunkPacketInfo, int chunkSectionIndex) {
- public synchronized void write(FriendlyByteBuf buf) { // Paper - synchronize
+ public synchronized void write(FriendlyByteBuf buf, @Nullable com.destroystokyo.paper.antixray.ChunkPacketInfo<T> chunkPacketInfo, int chunkSectionIndex) { // Paper - Synchronize
this.acquire();
try {
@ -1569,7 +1569,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(Registries.BIOME), world); // Paper - Anti-Xray - Add parameters
}
@Override
// Paper start - Allow delegation to vanilla chunk gen
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java

View file

@ -12,8 +12,8 @@ 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 - Optimize network
+ private static final int MAX_PER_TICK = io.papermc.paper.configuration.GlobalConfiguration.get().misc.maxJoinsPerTick; // Paper - Buffer joins to world
+ private static int joinAttemptsThisTick; // Paper - Buffer joins to world

View file

@ -9,7 +9,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 {
// Paper end - Cache chunk status
public final java.util.concurrent.locks.ReentrantLock fileLock = new java.util.concurrent.locks.ReentrantLock(); // Paper
public RegionFile(Path file, Path directory, boolean dsync) throws IOException {
- this(file, directory, RegionFileVersion.VERSION_DEFLATE, dsync);

View file

@ -514,7 +514,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return new DefaultEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Local Client IO #%d").setDaemon(true).setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(LOGGER)).build()); // Paper
});
private final PacketFlow receiving;
private final Queue<WrappedConsumer> pendingActions = Queues.newConcurrentLinkedQueue();
private final Queue<Consumer<Connection>> pendingActions = Queues.newConcurrentLinkedQueue();
@@ -0,0 +0,0 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
}

View file

@ -116,11 +116,11 @@ 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, S
// Spigot end
// Paper start
protected int numCollisions = 0; // Paper - Cap entity collisions
+ public long activatedImmunityTick = Integer.MIN_VALUE; // Paper
+ public boolean isTemporarilyActive; // Paper
public boolean fromNetherPortal; // Paper - Add option to nerf pigmen from nether portals
+ public long activatedImmunityTick = Integer.MIN_VALUE; // Paper - EAR
+ public boolean isTemporarilyActive; // Paper - EAR
public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one
@javax.annotation.Nullable
private org.bukkit.util.Vector origin;
@ -344,7 +344,7 @@ 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 {
public Map<BlockPos, BlockEntity> capturedTileEntities = new HashMap<>();
public Map<BlockPos, BlockEntity> capturedTileEntities = new java.util.LinkedHashMap<>(); // Paper - Retain block place order when capturing blockstates
public List<ItemEntity> captureDrops;
public final it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<SpawnCategory> ticksPerSpawnCategory = new it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<>();
+ // Paper start

View file

@ -36,7 +36,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ @Nullable
+ public CompoundTag readConvertChunkSync(ChunkPos pos) throws IOException {
+ CompoundTag nbttagcompound = this.readSync(pos);
+ // Paper start - Cache chunk status on disk
+ if (nbttagcompound == null) {
+ return null;
+ }
@ -49,10 +48,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.updateChunkStatusOnDisk(pos, nbttagcompound);
+
+ return nbttagcompound;
+ // Paper end
+ }
+
+ // Paper start - chunk status cache "api"
+ public ChunkStatus getChunkStatusOnDiskIfCached(ChunkPos chunkPos) {
+ net.minecraft.world.level.chunk.storage.RegionFile regionFile = regionFileCache.getRegionFileIfLoaded(chunkPos);
+
@ -89,7 +86,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ // Paper end - Cache chunk status on disk
+
boolean anyPlayerCloseEnoughForSpawning(ChunkPos pos) {
public boolean anyPlayerCloseEnoughForSpawning(ChunkPos pos) { // Paper - public
// Spigot start
return this.anyPlayerCloseEnoughForSpawning(pos, false);
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
@ -125,7 +122,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end - Cache chunk status
+
public RegionFile(Path file, Path directory, boolean dsync) throws IOException {
this(file, directory, RegionFileVersion.VERSION_DEFLATE, dsync);
this(file, directory, RegionFileVersion.getCompressionFormat(), dsync); // Paper - Configurable region compression format
}
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
return this.getOffset(pos) != 0;
@ -153,8 +150,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
NbtIo.write(nbt, (DataOutput) dataoutputstream);
+ regionfile.setStatus(pos.x, pos.z, ChunkSerializer.getStatus(nbt)); // Paper - Cache chunk status
regionfile.setOversized(pos.x, pos.z, false); // Paper - We don't do this anymore, mojang stores differently, but clear old meta flag if it exists to get rid of our own meta file once last oversized is gone
} catch (Throwable throwable) {
if (dataoutputstream != null) {
// Paper start - don't write garbage data to disk if writing serialization fails
dataoutputstream.close(); // Only write if successful
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@ -186,35 +183,38 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
}
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public boolean loadChunk(int x, int z, boolean generate) {
org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
warnUnsafeChunk("loading a faraway chunk", x, z); // Paper
- ChunkAccess chunk = this.world.getChunkSource().getChunk(x, z, generate || isChunkGenerated(x, z) ? ChunkStatus.FULL : ChunkStatus.EMPTY, true); // Paper
+ // Paper start - Optimize this method
+ ChunkPos chunkPos = new ChunkPos(x, z);
-
- // If generate = false, but the chunk already exists, we will get this back.
- if (chunk instanceof ImposterProtoChunk) {
- // We then cycle through again to get the full chunk immediately, rather than after the ticket addition
- chunk = this.world.getChunkSource().getChunk(x, z, ChunkStatus.FULL, true);
- }
-
- if (chunk instanceof net.minecraft.world.level.chunk.LevelChunk) {
- this.world.getChunkSource().addRegionTicket(TicketType.PLUGIN, new ChunkPos(x, z), 0, Unit.INSTANCE); // Paper
+ // Paper start - Optimize this method
+ ChunkPos chunkPos = new ChunkPos(x, z);
+ ChunkAccess immediate = world.getChunkSource().getChunkAtIfLoadedImmediately(x, z);
+ if (immediate != null) {
+ // Plugins should use plugin tickets instead of this method to keep a chunk perpetually loaded
return true;
}
- return false;
+ if (!generate) {
+ ChunkAccess immediate = world.getChunkSource().getChunkAtImmediately(x, z);
+ if (immediate == null) {
+ immediate = world.getChunkSource().chunkMap.getUnloadingChunk(x, z);
+ }
+ immediate = world.getChunkSource().chunkMap.getUnloadingChunk(x, z);
+ if (immediate != null) {
+ if (!(immediate instanceof ImposterProtoChunk) && !(immediate instanceof net.minecraft.world.level.chunk.LevelChunk)) {
+ return false; // not full status
+ }
+ world.getChunkSource().addRegionTicket(TicketType.PLUGIN, chunkPos, 1, Unit.INSTANCE);
+ world.getChunkSource().addRegionTicket(TicketType.PLUGIN, chunkPos, 0, Unit.INSTANCE); // Paper
+ world.getChunk(x, z); // make sure we're at ticket level 32 or lower
+ return true;
+ }
- if (chunk instanceof net.minecraft.world.level.chunk.LevelChunk) {
- this.world.getChunkSource().addRegionTicket(TicketType.PLUGIN, new ChunkPos(x, z), 1, Unit.INSTANCE);
- return true;
+ net.minecraft.world.level.chunk.storage.RegionFile file;
+ try {
+ file = world.getChunkSource().chunkMap.regionFileCache.getRegionFile(chunkPos, false);
@ -234,10 +234,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ // fall through to load
+ // we do this so we do not re-read the chunk data on disk
}
- return false;
+ world.getChunkSource().addRegionTicket(TicketType.PLUGIN, chunkPos, 1, Unit.INSTANCE);
+ }
+ world.getChunkSource().addRegionTicket(TicketType.PLUGIN, chunkPos, 0, Unit.INSTANCE); // Paper
+ world.getChunkSource().getChunk(x, z, ChunkStatus.FULL, true);
+ return true;
+ // Paper end - Optimize this method

View file

@ -117,8 +117,8 @@ 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
// CraftBukkit end
}
// Paper end - Cache chunk status on disk
- boolean anyPlayerCloseEnoughForSpawning(ChunkPos pos) {
+ public boolean anyPlayerCloseEnoughForSpawning(ChunkPos pos) { // Paper - public

View file

@ -12,9 +12,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
Vec3 vec3d = new Vec3(this.getX(), this.getEyeY(), this.getZ());
Vec3 vec3d1 = new Vec3(entity.getX(), entity.getEyeY(), entity.getZ());
- return vec3d1.distanceTo(vec3d) > 128.0D ? false : this.level().clipDirect(vec3d, vec3d1, net.minecraft.world.phys.shapes.CollisionContext.of(this)) == HitResult.Type.MISS; // Paper
- return vec3d1.distanceTo(vec3d) > 128.0D ? false : this.level().clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS;
+ // Paper - diff on change - used in CraftLivingEntity#hasLineOfSight(Location) and CraftWorld#lineOfSightExists
+ return vec3d1.distanceToSqr(vec3d) > 128.0D * 128.0D ? false : this.level().clipDirect(vec3d, vec3d1, net.minecraft.world.phys.shapes.CollisionContext.of(this)) == HitResult.Type.MISS; // Paper - Perf: Use distance squared
+ return vec3d1.distanceToSqr(vec3d) > 128.0D * 128.0D ? false : this.level().clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS; // Paper - Perf: Use distance squared
}
}

View file

@ -12,19 +12,17 @@ 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 {
}
}
+
+ public static final int MAX_CHUNK_SIZE = 500 * 1024 * 1024; // Paper - don't write garbage data to disk if writing serialization fails
+
// Paper end
private class ChunkBuffer extends ByteArrayOutputStream {
private final ChunkPos pos;
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
super.write(RegionFile.this.version.getId());
this.pos = chunkcoordintpair;
}
+ // Paper start - don't write garbage data to disk if writing serialization fails
+ @Override
+ public void write(final int b) {
@ -42,21 +40,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ super.write(b, off, len);
+ }
+ // Paper end - don't write garbage data to disk if writing serialization fails
+
public void close() throws IOException {
ByteBuffer bytebuffer = ByteBuffer.wrap(this.buf, 0, this.count);
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- 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 {
try {
NbtIo.write(nbt, (DataOutput) dataoutputstream);
regionfile.setStatus(pos.x, pos.z, ChunkSerializer.getStatus(nbt)); // Paper - Cache chunk status
regionfile.setOversized(pos.x, pos.z, false); // Paper - We don't do this anymore, mojang stores differently, but clear old meta flag if it exists to get rid of our own meta file once last oversized is gone
+ dataoutputstream.close(); // Paper - only write if successful
+ // Paper start - don't write garbage data to disk if writing serialization fails
+ } catch (RegionFileSizeException e) {
+ dataoutputstream.close(); // Only write if successful
+ } catch (final RegionFileSizeException e) {
+ attempts = 5; // Don't retry
+ regionfile.clear(pos);
+ throw e;

View file

@ -32,7 +32,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<?>> {
return new DefaultEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Local Client IO #%d").setDaemon(true).build());
return new DefaultEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Local Client IO #%d").setDaemon(true).setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(LOGGER)).build()); // Paper
});
private final PacketFlow receiving;
- private final Queue<Consumer<Connection>> pendingActions = Queues.newConcurrentLinkedQueue();
@ -210,8 +210,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
+ // Paper end - Optimize network
public void tick() {
this.flushQueue();
private static final int MAX_PER_TICK = io.papermc.paper.configuration.GlobalConfiguration.get().misc.maxJoinsPerTick; // Paper - Buffer joins to world
private static int joinAttemptsThisTick; // Paper - Buffer joins to world
@@ -0,0 +0,0 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
public void disconnect(Component disconnectReason) {
// Spigot Start

View file

@ -152,7 +152,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
@@ -0,0 +0,0 @@ public final class NaturalSpawner {
}
// Paper end - Add mobcaps commands
public static void spawnCategoryForChunk(MobCategory group, ServerLevel world, LevelChunk chunk, NaturalSpawner.SpawnPredicate checker, NaturalSpawner.AfterSpawnCallback runner) {
+ // Paper start - Optional per player mob spawns

View file

@ -21,9 +21,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Paper end - rewrite player chunk loader
@@ -0,0 +0,0 @@ public class PlayerChunkSender {
final boolean shouldModify = world.chunkPacketBlockController.shouldModify(handler.player, chunk);
handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), (BitSet)null, (BitSet)null, shouldModify));
// Paper end - Anti-Xray
public static void sendChunk(ServerGamePacketListenerImpl handler, ServerLevel world, LevelChunk chunk) { // Paper - rewrite chunk loader - public
handler.player.serverLevel().chunkSource.chunkMap.getVisibleChunkIfPresent(chunk.getPos().toLong()).addPlayer(handler.player);
handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), (BitSet)null, (BitSet)null));
+ // Paper start - PlayerChunkLoadEvent
+ 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();

View file

@ -21,4 +21,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public Map<BlockPos, BlockEntity> capturedTileEntities = new java.util.LinkedHashMap<>(); // Paper - Retain block place order when capturing blockstates
public List<ItemEntity> captureDrops;
public final it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<SpawnCategory> ticksPerSpawnCategory = new it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<>();
// Paper start
public boolean populating;

View file

@ -30,11 +30,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
Vec3 vec3d = new Vec3(this.getX(), this.getEyeY(), this.getZ());
Vec3 vec3d1 = new Vec3(entity.getX(), entity.getEyeY(), entity.getZ());
- return vec3d1.distanceTo(vec3d) > 128.0D ? false : this.level().clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS;
+ return vec3d1.distanceTo(vec3d) > 128.0D ? false : this.level().clipDirect(vec3d, vec3d1, net.minecraft.world.phys.shapes.CollisionContext.of(this)) == HitResult.Type.MISS; // Paper
// Paper - diff on change - used in CraftLivingEntity#hasLineOfSight(Location) and CraftWorld#lineOfSightExists
- return vec3d1.distanceToSqr(vec3d) > 128.0D * 128.0D ? false : this.level().clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS; // Paper - Perf: Use distance squared
+ return vec3d1.distanceToSqr(vec3d) > 128.0D * 128.0D ? false : this.level().clipDirect(vec3d, vec3d1, net.minecraft.world.phys.shapes.CollisionContext.of(this)) == HitResult.Type.MISS; // Paper - Perf: Use distance squared & strip raytracing
}
}
@ -58,10 +58,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return hitResult == null ? null : hitResult.getType();
+ }
+ // Paper end
+
// CraftBukkit start - moved block handling into separate method for use by Block#rayTrace
default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition) {
BlockState iblockdata = this.getBlockState(blockposition);
// Paper start - Add predicate for blocks when raytracing
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/Level.java

View file

@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
@@ -0,0 +0,0 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
private final T @org.jetbrains.annotations.Nullable [] presetValues; // Paper - Anti-Xray - Add preset values
public final IdMap<T> registry;
private volatile PalettedContainer.Data<T> data;
private final PalettedContainer.Strategy strategy;
- private final ThreadingDetector threadingDetector = new ThreadingDetector("PalettedContainer");
@ -34,7 +34,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // this.threadingDetector.checkAndUnlock(); // Paper - disable this
}
// Paper start - Anti-Xray - Add preset values
public static <T> Codec<PalettedContainer<T>> codecRW(IdMap<T> idList, Codec<T> entryCodec, PalettedContainer.Strategy paletteProvider, T defaultValue) {
@@ -0,0 +0,0 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
}
@ -42,8 +42,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- public int onResize(int newBits, T object) {
+ public synchronized int onResize(int newBits, T object) { // Paper - synchronize
PalettedContainer.Data<T> data = this.data;
// Paper start - Anti-Xray - Add preset values
PalettedContainer.Data<T> data2 = this.createOrReuseData(data, newBits);
data2.copyFrom(data.palette, data.storage);
@@ -0,0 +0,0 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
return this.getAndSet(this.strategy.getIndex(x, y, z), value);
}
@ -72,11 +72,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
try {
@@ -0,0 +0,0 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
}
@Override
@Deprecated @io.papermc.paper.annotation.DoNotUse public void write(FriendlyByteBuf buf) { this.write(buf, null, 0); }
@Override
- public void write(FriendlyByteBuf buf, @Nullable com.destroystokyo.paper.antixray.ChunkPacketInfo<T> chunkPacketInfo, int chunkSectionIndex) {
+ public synchronized void write(FriendlyByteBuf buf, @Nullable com.destroystokyo.paper.antixray.ChunkPacketInfo<T> chunkPacketInfo, int chunkSectionIndex) { // Paper - synchronize
- public void write(FriendlyByteBuf buf) {
+ public synchronized void write(FriendlyByteBuf buf) { // Paper - synchronize
this.acquire();
try {

View file

@ -37,7 +37,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
public abstract ResourceKey<LevelStem> getTypeKey();
protected Level(WritableLevelData worlddatamutable, ResourceKey<Level> resourcekey, RegistryAccess iregistrycustom, Holder<DimensionType> holder, Supplier<ProfilerFiller> supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function<org.spigotmc.SpigotWorldConfig, io.papermc.paper.configuration.WorldConfiguration> paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - create paper world config; Async-Anti-Xray: Pass executor
protected Level(WritableLevelData worlddatamutable, ResourceKey<Level> resourcekey, RegistryAccess iregistrycustom, Holder<DimensionType> holder, Supplier<ProfilerFiller> supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function<org.spigotmc.SpigotWorldConfig, io.papermc.paper.configuration.WorldConfiguration> paperWorldConfigCreator) { // Paper - create paper world config
diff --git a/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java b/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java

View file

@ -59,9 +59,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public boolean loadChunk(int x, int z, boolean generate) {
org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
+ warnUnsafeChunk("loading a faraway chunk", x, z); // Paper
// Paper start - Optimize this method
ChunkPos chunkPos = new ChunkPos(x, z);
ChunkAccess immediate = world.getChunkSource().getChunkAtIfLoadedImmediately(x, z); // Paper
ChunkAccess chunk = this.world.getChunkSource().getChunk(x, z, generate || isChunkGenerated(x, z) ? ChunkStatus.FULL : ChunkStatus.EMPTY, true); // Paper
// If generate = false, but the chunk already exists, we will get this back.
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override

View file

@ -3,7 +3,7 @@ import sys
# Use inside of server patch dir
# py ../../scripts/moveback.py ''
patch_target = 1009 # TODO: Update this
patch_target = 998 # TODO: Update this
def increment_number(filename):