diff --git a/patches/server/Add-Alternate-Current-redstone-implementation.patch b/patches/server/Add-Alternate-Current-redstone-implementation.patch index 1e3a938dae..045a4205d5 100644 --- a/patches/server/Add-Alternate-Current-redstone-implementation.patch +++ b/patches/server/Add-Alternate-Current-redstone-implementation.patch @@ -2013,11 +2013,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel { public final UUID uuid; - public boolean hasPhysicsEvent = true; // Paper + public boolean hasPhysicsEvent = true; // Paper - BlockPhysicsEvent public boolean hasEntityMoveEvent; // Paper - Add EntityMoveEvent + private final alternate.current.wire.WireHandler wireHandler = new alternate.current.wire.WireHandler(this); // Paper - optimize redstone (Alternate Current) - @Override public LevelChunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI + public LevelChunk getChunkIfLoaded(int x, int z) { return this.chunkSource.getChunkAtIfLoadedImmediately(x, z); // Paper - Use getChunkIfLoadedImmediately @@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel { return crashreportsystemdetails; diff --git a/patches/server/Add-EntityMoveEvent.patch b/patches/server/Add-EntityMoveEvent.patch index 4d107692d7..5de8d63f0a 100644 --- a/patches/server/Add-EntityMoveEvent.patch +++ b/patches/server/Add-EntityMoveEvent.patch @@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper + worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - BlockPhysicsEvent + worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent this.profiler.push(() -> { @@ -23,10 +23,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel { public final LevelStorageSource.LevelStorageAccess convertable; public final UUID uuid; - public boolean hasPhysicsEvent = true; // Paper + public boolean hasPhysicsEvent = true; // Paper - BlockPhysicsEvent + public boolean hasEntityMoveEvent; // Paper - Add EntityMoveEvent - @Override public LevelChunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI + public LevelChunk getChunkIfLoaded(int x, int z) { return this.chunkSource.getChunk(x, z, false); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/patches/server/Add-PlayerInitialSpawnEvent.patch b/patches/server/Add-PlayerInitialSpawnEvent.patch index 05b222dce5..0075528ea2 100644 --- a/patches/server/Add-PlayerInitialSpawnEvent.patch +++ b/patches/server/Add-PlayerInitialSpawnEvent.patch @@ -32,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - set raw so we aren't fully joined to the world (not added to chunk or world) + player.setPosRaw(loc.getX(), loc.getY(), loc.getZ()); + player.setRot(loc.getYaw(), loc.getPitch()); -+ // Paper end ++ // Paper end - set raw so we aren't fully joined to the world // Spigot end // CraftBukkit - Moved message to after join diff --git a/patches/server/Add-Unix-domain-socket-support.patch b/patches/server/Add-Unix-domain-socket-support.patch index cd5ab47c16..467dea0c8b 100644 --- a/patches/server/Add-Unix-domain-socket-support.patch +++ b/patches/server/Add-Unix-domain-socket-support.patch @@ -123,7 +123,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 org.apache.logging.log4j.LogManager.getLogger().debug("Failed to check connection throttle", t); } @@ -0,0 +0,0 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL - // Paper end + // Paper end - PlayerHandshakeEvent // if (org.spigotmc.SpigotConfig.bungee) { // Paper - comment out, we check above! if ( ( split.length == 3 || split.length == 4 ) && ( ServerHandshakePacketListenerImpl.BYPASS_HOSTCHECK || ServerHandshakePacketListenerImpl.HOST_PATTERN.matcher( split[1] ).matches() ) ) { // Paper - Add bypass host check + // Paper start - Unix domain socket support diff --git a/patches/server/Add-World-Util-Methods.patch b/patches/server/Add-World-Util-Methods.patch index d32d1351cd..b556b7aaf7 100644 --- a/patches/server/Add-World-Util-Methods.patch +++ b/patches/server/Add-World-Util-Methods.patch @@ -5,19 +5,6 @@ Subject: [PATCH] Add World Util Methods Methods that can be used for other patches to help improve logic. -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 { - public final LevelStorageSource.LevelStorageAccess convertable; - public final UUID uuid; - -- public LevelChunk getChunkIfLoaded(int x, int z) { -+ @Override public LevelChunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI - return this.chunkSource.getChunk(x, z, false); - } - 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 diff --git a/patches/server/Add-ability-to-configure-frosted_ice-properties.patch b/patches/server/Add-ability-to-configure-frosted_ice-properties.patch index dd3ac5482e..57dbff9c99 100644 --- a/patches/server/Add-ability-to-configure-frosted_ice-properties.patch +++ b/patches/server/Add-ability-to-configure-frosted_ice-properties.patch @@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { -+ if (!world.paperConfig().environment.frostedIce.enabled) return; // Paper - add ability to disable frosted ice ++ if (!world.paperConfig().environment.frostedIce.enabled) return; // Paper - Frosted ice options if ((random.nextInt(3) == 0 || this.fewerNeigboursThan(world, pos, 4)) && world.getMaxLocalRawBrightness(pos) > 11 - state.getValue(AGE) - state.getLightBlock(world, pos) && this.slightlyMelt(state, world, pos)) { BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); @@ -21,13 +21,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 BlockState blockState = world.getBlockState(mutableBlockPos); if (blockState.is(this) && !this.slightlyMelt(blockState, world, mutableBlockPos)) { - world.scheduleTick(mutableBlockPos, this, Mth.nextInt(random, 20, 40)); -+ world.scheduleTick(mutableBlockPos, this, Mth.nextInt(random, world.paperConfig().environment.frostedIce.delay.min, world.paperConfig().environment.frostedIce.delay.max)); // Paper - use configurable min/max delay ++ world.scheduleTick(mutableBlockPos, this, Mth.nextInt(random, world.paperConfig().environment.frostedIce.delay.min, world.paperConfig().environment.frostedIce.delay.max)); // Paper - Frosted ice options } } } else { - world.scheduleTick(pos, this, Mth.nextInt(random, 20, 40)); -+ world.scheduleTick(pos, this, Mth.nextInt(random, world.paperConfig().environment.frostedIce.delay.min, world.paperConfig().environment.frostedIce.delay.max)); // Paper - use configurable min/max delay ++ world.scheduleTick(pos, this, Mth.nextInt(random, world.paperConfig().environment.frostedIce.delay.min, world.paperConfig().environment.frostedIce.delay.max)); // Paper - Frosted ice options } } diff --git a/patches/server/Add-bypass-host-check.patch b/patches/server/Add-bypass-host-check.patch index 4bc32b2957..7f73a878df 100644 --- a/patches/server/Add-bypass-host-check.patch +++ b/patches/server/Add-bypass-host-check.patch @@ -21,7 +21,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.server = server; @@ -0,0 +0,0 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL if (!handledByEvent && proxyLogicEnabled) { - // Paper end + // Paper end - PlayerHandshakeEvent // if (org.spigotmc.SpigotConfig.bungee) { // Paper - comment out, we check above! - if ( ( split.length == 3 || split.length == 4 ) && ( ServerHandshakePacketListenerImpl.HOST_PATTERN.matcher( split[1] ).matches() ) ) { + if ( ( split.length == 3 || split.length == 4 ) && ( ServerHandshakePacketListenerImpl.BYPASS_HOSTCHECK || ServerHandshakePacketListenerImpl.HOST_PATTERN.matcher( split[1] ).matches() ) ) { // Paper - Add bypass host check diff --git a/patches/server/Add-configurable-height-for-slime-spawn.patch b/patches/server/Add-configurable-height-for-slime-spawn.patch index 800e6348ae..f6e9dabfa5 100644 --- a/patches/server/Add-configurable-height-for-slime-spawn.patch +++ b/patches/server/Add-configurable-height-for-slime-spawn.patch @@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy { ChunkPos chunkcoordintpair = new ChunkPos(pos); - boolean flag = world.getMinecraftWorld().paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(chunkcoordintpair.x, chunkcoordintpair.z, ((WorldGenLevel) world).getSeed(), world.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper + boolean flag = world.getMinecraftWorld().paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(chunkcoordintpair.x, chunkcoordintpair.z, ((WorldGenLevel) world).getSeed(), world.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper - if (random.nextInt(10) == 0 && flag && pos.getY() < 40) { + // Paper start - Replace rules for Height in Slime Chunks diff --git a/patches/server/Add-configurable-portal-search-radius.patch b/patches/server/Add-configurable-portal-search-radius.patch index e58fce8934..557b404317 100644 --- a/patches/server/Add-configurable-portal-search-radius.patch +++ b/patches/server/Add-configurable-portal-search-radius.patch @@ -13,12 +13,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 BlockPos blockposition = worldborder.clampToBounds(this.getX() * d0, this.getY(), this.getZ() * d0); // CraftBukkit start - CraftPortalEvent event = this.callPortalEvent(this, destination, new Vec3(blockposition.getX(), blockposition.getY(), blockposition.getZ()), PlayerTeleportEvent.TeleportCause.NETHER_PORTAL, flag2 ? 16 : 128, 16); -+ // Paper start ++ // Paper start - Configurable portal search radius + int portalSearchRadius = destination.paperConfig().environment.portalSearchRadius; + if (level.paperConfig().environment.portalSearchVanillaDimensionScaling && flag2) { // == THE_NETHER + portalSearchRadius = (int) (portalSearchRadius / destination.dimensionType().coordinateScale()); + } -+ // Paper end ++ // Paper end - Configurable portal search radius + CraftPortalEvent event = this.callPortalEvent(this, destination, new Vec3(blockposition.getX(), blockposition.getY(), blockposition.getZ()), PlayerTeleportEvent.TeleportCause.NETHER_PORTAL, portalSearchRadius, destination.paperConfig().environment.portalCreateRadius); // Paper start - configurable portal radius if (event == null) { return null; @@ -32,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public Optional findPortalAround(BlockPos pos, boolean destIsNether, WorldBorder worldBorder) { // CraftBukkit start - return this.findPortalAround(pos, worldBorder, destIsNether ? 16 : 128); // Search Radius -+ return this.findPortalAround(pos, worldBorder, destIsNether ? level.paperConfig().environment.portalCreateRadius : level.paperConfig().environment.portalSearchRadius); // Search Radius // Paper - search Radius ++ return this.findPortalAround(pos, worldBorder, destIsNether ? level.paperConfig().environment.portalCreateRadius : level.paperConfig().environment.portalSearchRadius); // Search Radius // Paper - Configurable portal search radius } public Optional findPortalAround(BlockPos blockposition, WorldBorder worldborder, int i) { diff --git a/patches/server/Add-exception-reporting-event.patch b/patches/server/Add-exception-reporting-event.patch index 1f27509c2e..46c3e2d483 100644 --- a/patches/server/Add-exception-reporting-event.patch +++ b/patches/server/Add-exception-reporting-event.patch @@ -63,7 +63,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 root = NbtIo.readCompressed(new java.io.FileInputStream(file5), NbtAccounter.unlimitedHeap()); } catch (Exception exception) { exception.printStackTrace(); -+ ServerInternalException.reportInternalException(exception); // Paper ++ ServerInternalException.reportInternalException(exception); // Paper - ServerExceptionEvent } if (root != null) { @@ -71,7 +71,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 NbtIo.writeCompressed(root, new java.io.FileOutputStream(file2)); } catch (Exception exception) { exception.printStackTrace(); -+ ServerInternalException.reportInternalException(exception); // Paper ++ ServerInternalException.reportInternalException(exception); // Paper - ServerExceptionEvent } } // CraftBukkit end @@ -83,7 +83,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 entityzombie.finalizeSpawn(world, world.getCurrentDifficultyAt(entityzombie.blockPosition()), MobSpawnType.EVENT, (SpawnGroupData) null, (CompoundTag) null); } catch (Exception exception) { VillageSiege.LOGGER.warn("Failed to create zombie for village siege at {}", vec3d, exception); -+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exception); // Paper ++ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exception); // Paper - ServerExceptionEvent return; } @@ -106,7 +106,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // Paper start - Prevent tile entity and entity crashes final String msg = String.format("Entity threw exception at %s:%s,%s,%s", entity.level().getWorld().getName(), entity.getX(), entity.getY(), entity.getZ()); MinecraftServer.LOGGER.error(msg, throwable); -+ getCraftServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable))); ++ getCraftServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable))); // Paper - ServerExceptionEvent entity.discard(); // Paper end } @@ -118,7 +118,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 NaturalSpawner.LOGGER.warn("Can't spawn entity of type: {}", BuiltInRegistries.ENTITY_TYPE.getKey(type)); } catch (Exception exception) { NaturalSpawner.LOGGER.warn("Failed to create mob", exception); -+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exception); // Paper ++ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exception); // Paper - ServerExceptionEvent } return null; @@ -126,7 +126,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 entity = biomesettingsmobs_c.type.create(world.getLevel()); } catch (Exception exception) { NaturalSpawner.LOGGER.warn("Failed to create mob", exception); -+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exception); // Paper ++ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exception); // Paper - ServerExceptionEvent continue; } @@ -150,7 +150,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - + " (" + this.getBlockState(blockposition) + ") where there was no entity tile!"); - System.out.println("Chunk coordinates: " + (this.chunkPos.x * 16) + "," + (this.chunkPos.z * 16)); - new Exception().printStackTrace(); -+ // Paper start ++ // Paper start - ServerExceptionEvent + ServerInternalException e = new ServerInternalException( + "Attempted to place a tile entity (" + blockEntity + ") at " + blockEntity.getBlockPos().getX() + "," + + blockEntity.getBlockPos().getY() + "," + blockEntity.getBlockPos().getZ() @@ -159,7 +159,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + "\nWorld: " + level.getLevel().dimension().location()); + e.printStackTrace(); + ServerInternalException.reportInternalException(e); -+ // Paper end ++ // Paper end - ServerExceptionEvent // CraftBukkit end } } @@ -167,7 +167,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // Paper start - Prevent tile entity and entity crashes final String msg = String.format("BlockEntity threw exception at %s:%s,%s,%s", LevelChunk.this.getLevel().getWorld().getName(), this.getPos().getX(), this.getPos().getY(), this.getPos().getZ()); net.minecraft.server.MinecraftServer.LOGGER.error(msg, throwable); -+ net.minecraft.world.level.chunk.LevelChunk.this.level.getCraftServer().getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new ServerInternalException(msg, throwable))); ++ net.minecraft.world.level.chunk.LevelChunk.this.level.getCraftServer().getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new ServerInternalException(msg, throwable))); // Paper - ServerExceptionEvent LevelChunk.this.removeBlockEntity(this.getPos()); // Paper end // Spigot start @@ -179,7 +179,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return true; } } catch (IOException ioexception) { -+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(ioexception); // Paper ++ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(ioexception); // Paper - ServerExceptionEvent return false; } } @@ -187,7 +187,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 ((java.nio.Buffer) buf).position(5); // CraftBukkit - decompile error filechannel.write(buf); } catch (Throwable throwable) { -+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(throwable); // Paper ++ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(throwable); // Paper - ServerExceptionEvent if (filechannel != null) { try { filechannel.close(); diff --git a/patches/server/Add-handshake-event-to-allow-plugins-to-handle-clien.patch b/patches/server/Add-handshake-event-to-allow-plugins-to-handle-clien.patch index 6914840304..9d9f0762f1 100644 --- a/patches/server/Add-handshake-event-to-allow-plugins-to-handle-clien.patch +++ b/patches/server/Add-handshake-event-to-allow-plugins-to-handle-clien.patch @@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.connection.disconnect(ichatmutablecomponent); } else { this.connection.setListener(new ServerLoginPacketListenerImpl(this.server, this.connection)); -+ // Paper start - handshake event ++ // Paper start - PlayerHandshakeEvent + boolean proxyLogicEnabled = org.spigotmc.SpigotConfig.bungee; + boolean handledByEvent = false; + // Try and handle the handshake through the event @@ -50,7 +50,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - if (org.spigotmc.SpigotConfig.bungee) { + // Don't try and handle default logic if it's been handled by the event. + if (!handledByEvent && proxyLogicEnabled) { -+ // Paper end ++ // Paper end - PlayerHandshakeEvent + // if (org.spigotmc.SpigotConfig.bungee) { // Paper - comment out, we check above! if ( ( split.length == 3 || split.length == 4 ) && ( ServerHandshakePacketListenerImpl.HOST_PATTERN.matcher( split[1] ).matches() ) ) { this.connection.hostname = split[0]; diff --git a/patches/server/All-chunks-are-slime-spawn-chunks-toggle.patch b/patches/server/All-chunks-are-slime-spawn-chunks-toggle.patch index 1fb755eba0..3f00aba727 100644 --- a/patches/server/All-chunks-are-slime-spawn-chunks-toggle.patch +++ b/patches/server/All-chunks-are-slime-spawn-chunks-toggle.patch @@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 ChunkPos chunkcoordintpair = new ChunkPos(pos); - boolean flag = WorldgenRandom.seedSlimeChunk(chunkcoordintpair.x, chunkcoordintpair.z, ((WorldGenLevel) world).getSeed(), world.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot -+ boolean flag = world.getMinecraftWorld().paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(chunkcoordintpair.x, chunkcoordintpair.z, ((WorldGenLevel) world).getSeed(), world.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper ++ boolean flag = world.getMinecraftWorld().paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(chunkcoordintpair.x, chunkcoordintpair.z, ((WorldGenLevel) world).getSeed(), world.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper if (random.nextInt(10) == 0 && flag && pos.getY() < 40) { return checkMobSpawnRules(type, world, spawnReason, pos, random); diff --git a/patches/server/Async-GameProfileCache-saving.patch b/patches/server/Async-GameProfileCache-saving.patch index 6c9a19c7ca..c0fbb3d199 100644 --- a/patches/server/Async-GameProfileCache-saving.patch +++ b/patches/server/Async-GameProfileCache-saving.patch @@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) { MinecraftServer.LOGGER.info("Saving usercache.json"); - this.getProfileCache().save(); -+ this.getProfileCache().save(false); // Paper ++ this.getProfileCache().save(false); // Paper - Perf: Async GameProfileCache saving } // Spigot end io.papermc.paper.chunk.system.io.RegionFileIOThread.close(true); // Paper // Paper - rewrite chunk system @@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this.convertOldUsers()) { - this.getProfileCache().save(); -+ this.getProfileCache().save(false); // Paper ++ this.getProfileCache().save(false); // Paper - Perf: Async GameProfileCache saving } if (!OldUsersConverter.serverReadyAfterUserconversion(this)) { @@ -39,7 +39,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.safeAdd(usercache_usercacheentry); - if( !org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly ) this.save(); // Spigot - skip saving if disabled -+ if( !org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly ) this.save(true); // Spigot - skip saving if disabled // Paper - async ++ if( !org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly ) this.save(true); // Spigot - skip saving if disabled // Paper - Perf: Async GameProfileCache saving } private long getNextOperation() { @@ -48,7 +48,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (flag && !org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) { // Spigot - skip saving if disabled - this.save(); -+ this.save(true); // Paper ++ this.save(true); // Paper - Perf: Async GameProfileCache saving } return optional; @@ -57,7 +57,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } - public void save() { -+ public void save(boolean asyncSave) { // Paper ++ public void save(boolean asyncSave) { // Paper - Perf: Async GameProfileCache saving JsonArray jsonarray = new JsonArray(); DateFormat dateformat = GameProfileCache.createDateFormat(); @@ -65,7 +65,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 jsonarray.add(GameProfileCache.writeGameProfile(usercache_usercacheentry, dateformat)); }); String s = this.gson.toJson(jsonarray); -+ Runnable save = () -> { // Paper ++ Runnable save = () -> { // Paper - Perf: Async GameProfileCache saving try { BufferedWriter bufferedwriter = Files.newWriter(this.file, StandardCharsets.UTF_8); @@ -73,14 +73,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } catch (IOException ioexception) { ; } -+ // Paper start ++ // Paper start - Perf: Async GameProfileCache saving + }; + if (asyncSave) { + io.papermc.paper.util.MCUtil.scheduleAsyncTask(save); + } else { + save.run(); + } -+ // Paper end ++ // Paper end - Perf: Async GameProfileCache saving } diff --git a/patches/server/Chunk-Save-Reattempt.patch b/patches/server/Chunk-Save-Reattempt.patch index 6d260baab6..68bcd76d14 100644 --- a/patches/server/Chunk-Save-Reattempt.patch +++ b/patches/server/Chunk-Save-Reattempt.patch @@ -13,8 +13,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return true; } } catch (IOException ioexception) { -- com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(ioexception); // Paper -+ com.destroystokyo.paper.util.SneakyThrow.sneaky(ioexception); // Paper - we want the upper try/catch to retry this +- com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(ioexception); // Paper - ServerExceptionEvent ++ com.destroystokyo.paper.util.SneakyThrow.sneaky(ioexception); // Paper - Chunk save reattempt; we want the upper try/catch to retry this return false; } } @@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } // Paper end - rewrite chunk system try { // Paper -+ int attempts = 0; Exception laste = null; while (attempts++ < 5) { try { // Paper ++ int attempts = 0; Exception laste = null; while (attempts++ < 5) { try { // Paper - Chunk save reattempt if (nbt == null) { regionfile.clear(pos); @@ -34,7 +34,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 dataoutputstream.close(); } } -+ // Paper start ++ // Paper start - Chunk save reattempt + return; + } catch (Exception ex) { + laste = ex; @@ -45,7 +45,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(laste); + net.minecraft.server.MinecraftServer.LOGGER.error("Failed to save chunk " + pos, laste); + } -+ // Paper end ++ // Paper end - Chunk save reattempt } finally { // Paper start regionfile.fileLock.unlock(); } // Paper end diff --git a/patches/server/Configurable-Disabling-Cat-Chest-Detection.patch b/patches/server/Configurable-Disabling-Cat-Chest-Detection.patch index 3f6d94cc1d..8b82916913 100644 --- a/patches/server/Configurable-Disabling-Cat-Chest-Detection.patch +++ b/patches/server/Configurable-Disabling-Cat-Chest-Detection.patch @@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (world.getMinecraftWorld().paperConfig().entities.behavior.disableChestCatDetection) { + return false; + } -+ // Paper end ++ // Paper end - Option to disable chest cat detection List list = world.getEntitiesOfClass(Cat.class, new AABB((double) pos.getX(), (double) (pos.getY() + 1), (double) pos.getZ(), (double) (pos.getX() + 1), (double) (pos.getY() + 2), (double) (pos.getZ() + 1))); if (!list.isEmpty()) { diff --git a/patches/server/Configurable-Non-Player-Arrow-Despawn-Rate.patch b/patches/server/Configurable-Non-Player-Arrow-Despawn-Rate.patch index c5e06c7e6b..3ce19525b8 100644 --- a/patches/server/Configurable-Non-Player-Arrow-Despawn-Rate.patch +++ b/patches/server/Configurable-Non-Player-Arrow-Despawn-Rate.patch @@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 protected void tickDespawn() { ++this.life; - if (this.life >= ((this instanceof ThrownTrident) ? this.level().spigotConfig.tridentDespawnRate : this.level().spigotConfig.arrowDespawnRate)) { // Spigot -+ if (this.life >= (pickup == Pickup.CREATIVE_ONLY ? this.level().paperConfig().entities.spawning.creativeArrowDespawnRate.value() : (pickup == Pickup.DISALLOWED ? this.level().paperConfig().entities.spawning.nonPlayerArrowDespawnRate.value() : ((this instanceof ThrownTrident) ? this.level().spigotConfig.tridentDespawnRate : this.level().spigotConfig.arrowDespawnRate)))) { // Spigot // Paper - TODO: Extract this to init? ++ if (this.life >= (pickup == Pickup.CREATIVE_ONLY ? this.level().paperConfig().entities.spawning.creativeArrowDespawnRate.value() : (pickup == Pickup.DISALLOWED ? this.level().paperConfig().entities.spawning.nonPlayerArrowDespawnRate.value() : ((this instanceof ThrownTrident) ? this.level().spigotConfig.tridentDespawnRate : this.level().spigotConfig.arrowDespawnRate)))) { // Spigot // Paper - Configurable non-player arrow despawn rate; TODO: Extract this to init? this.discard(); } diff --git a/patches/server/Configurable-Player-Collision.patch b/patches/server/Configurable-Player-Collision.patch index ff1f82067b..3c277eb5ad 100644 --- a/patches/server/Configurable-Player-Collision.patch +++ b/patches/server/Configurable-Player-Collision.patch @@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 buf.writeByte(this.options); buf.writeUtf(this.nametagVisibility); - buf.writeUtf(this.collisionRule); -+ buf.writeUtf(!io.papermc.paper.configuration.GlobalConfiguration.get().collisions.enablePlayerCollisions ? "never" : this.collisionRule); // Paper ++ buf.writeUtf(!io.papermc.paper.configuration.GlobalConfiguration.get().collisions.enablePlayerCollisions ? "never" : this.collisionRule); // Paper - Configurable player collision buf.writeEnum(this.color); buf.writeComponent(this.playerPrefix); buf.writeComponent(this.playerSuffix); @@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldLoadEvent(worldserver.getWorld())); } -+ // Paper start - Handle collideRule team for player collision toggle ++ // Paper start - Configurable player collision; Handle collideRule team for player collision toggle + final ServerScoreboard scoreboard = this.getScoreboard(); + final java.util.Collection toRemove = scoreboard.getPlayerTeams().stream().filter(team -> team.getName().startsWith("collideRule_")).map(net.minecraft.world.scores.PlayerTeam::getName).collect(java.util.stream.Collectors.toList()); + for (String teamName : toRemove) { @@ -37,7 +37,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + net.minecraft.world.scores.PlayerTeam collideTeam = scoreboard.addPlayerTeam(this.getPlayerList().collideRuleTeamName); + collideTeam.setSeeFriendlyInvisibles(false); // Because we want to mimic them not being on a team at all + } -+ // Paper end ++ // Paper end - Configurable player collision + this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.POSTWORLD); this.server.getPluginManager().callEvent(new ServerLoadEvent(ServerLoadEvent.LoadType.STARTUP)); @@ -50,7 +50,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit start private CraftServer cserver; private final Map playersByName = new java.util.HashMap<>(); -+ public @Nullable String collideRuleTeamName; // Paper - Team name used for collideRule ++ public @Nullable String collideRuleTeamName; // Paper - Configurable player collision public PlayerList(MinecraftServer server, LayeredRegistryAccess registryManager, PlayerDataStorage saveHandler, int maxPlayers) { this.cserver = server.server = new CraftServer((DedicatedServer) server, this); @@ -58,13 +58,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 player.initInventoryMenu(); // CraftBukkit - Moved from above, added world -+ // Paper start - Add to collideRule team if needed ++ // Paper start - Configurable player collision; Add to collideRule team if needed + final net.minecraft.world.scores.Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard(); + final PlayerTeam collideRuleTeam = scoreboard.getPlayerTeam(this.collideRuleTeamName); + if (this.collideRuleTeamName != null && collideRuleTeam != null && player.getTeam() == null) { + scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam); + } -+ // Paper end ++ // Paper end - Configurable player collision PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), s1, player.getId(), worldserver1.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ()); } @@ -72,7 +72,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 entityplayer.doTick(); // SPIGOT-924 // CraftBukkit end -+ // Paper start - Remove from collideRule team if needed ++ // Paper start - Configurable player collision; Remove from collideRule team if needed + if (this.collideRuleTeamName != null) { + final net.minecraft.world.scores.Scoreboard scoreBoard = this.server.getLevel(Level.OVERWORLD).getScoreboard(); + final PlayerTeam team = scoreBoard.getPlayersTeam(this.collideRuleTeamName); @@ -80,7 +80,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + scoreBoard.removePlayerFromTeam(entityplayer.getScoreboardName(), team); + } + } -+ // Paper end ++ // Paper end - Configurable player collision + this.save(entityplayer); if (entityplayer.isPassenger()) { @@ -89,13 +89,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } // CraftBukkit end -+ // Paper start - Remove collideRule team if it exists ++ // Paper start - Configurable player collision; Remove collideRule team if it exists + if (this.collideRuleTeamName != null) { + final net.minecraft.world.scores.Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard(); + final PlayerTeam team = scoreboard.getPlayersTeam(this.collideRuleTeamName); + if (team != null) scoreboard.removePlayerTeam(team); + } -+ // Paper end ++ // Paper end - Configurable player collision } // CraftBukkit start diff --git a/patches/server/Configurable-RCON-IP-address.patch b/patches/server/Configurable-RCON-IP-address.patch index 6adf07b882..6ffd8499a7 100644 --- a/patches/server/Configurable-RCON-IP-address.patch +++ b/patches/server/Configurable-RCON-IP-address.patch @@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private final DedicatedServerProperties.WorldDimensionData worldDimensionData; public final WorldOptions worldOptions; -+ public final String rconIp; // Paper - Add rcon ip ++ public final String rconIp; // Paper - Configurable rcon ip + // CraftBukkit start public DedicatedServerProperties(Properties properties, OptionSet optionset) { @@ -28,7 +28,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - Configurable rcon ip + final String rconIp = this.getStringRaw("rcon.ip"); + this.rconIp = rconIp == null ? this.serverIp : rconIp; -+ // Paper end ++ // Paper end - Configurable rcon ip } // CraftBukkit start diff --git a/patches/server/Configurable-random-tick-rates-for-blocks.patch b/patches/server/Configurable-random-tick-rates-for-blocks.patch index 51f231a7a1..64880e5b1d 100644 --- a/patches/server/Configurable-random-tick-rates-for-blocks.patch +++ b/patches/server/Configurable-random-tick-rates-for-blocks.patch @@ -16,8 +16,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { int i = (Integer) state.getValue(FarmBlock.MOISTURE); -+ if (i > 0 && world.paperConfig().tickRates.wetFarmland != 1 && (world.paperConfig().tickRates.wetFarmland < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % world.paperConfig().tickRates.wetFarmland != 0)) { return; } // Paper -+ if (i == 0 && world.paperConfig().tickRates.dryFarmland != 1 && (world.paperConfig().tickRates.dryFarmland < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % world.paperConfig().tickRates.dryFarmland != 0)) { return; } // Paper ++ if (i > 0 && world.paperConfig().tickRates.wetFarmland != 1 && (world.paperConfig().tickRates.wetFarmland < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % world.paperConfig().tickRates.wetFarmland != 0)) { return; } // Paper - Configurable random tick rates for blocks ++ if (i == 0 && world.paperConfig().tickRates.dryFarmland != 1 && (world.paperConfig().tickRates.dryFarmland < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % world.paperConfig().tickRates.dryFarmland != 0)) { return; } // Paper - Configurable random tick rates for blocks if (!FarmBlock.isNearWater(world, pos) && !world.isRainingAt(pos.above())) { if (i > 0) { @@ -37,7 +37,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { -+ if (this instanceof GrassBlock && world.paperConfig().tickRates.grassSpread != 1 && (world.paperConfig().tickRates.grassSpread < 1 || (MinecraftServer.currentTick + pos.hashCode()) % world.paperConfig().tickRates.grassSpread != 0)) { return; } // Paper ++ if (this instanceof GrassBlock && world.paperConfig().tickRates.grassSpread != 1 && (world.paperConfig().tickRates.grassSpread < 1 || (MinecraftServer.currentTick + pos.hashCode()) % world.paperConfig().tickRates.grassSpread != 0)) { return; } // Paper - Configurable random tick rates for blocks if (!SpreadingSnowyDirtBlock.canBeGrass(state, world, pos)) { // CraftBukkit start if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, Blocks.DIRT.defaultBlockState()).isCancelled()) { diff --git a/patches/server/Configurable-spawn-chances-for-skeleton-horses.patch b/patches/server/Configurable-spawn-chances-for-skeleton-horses.patch index 9df500ec0a..0ee7892050 100644 --- a/patches/server/Configurable-spawn-chances-for-skeleton-horses.patch +++ b/patches/server/Configurable-spawn-chances-for-skeleton-horses.patch @@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this.isRainingAt(blockposition)) { DifficultyInstance difficultydamagescaler = this.getCurrentDifficultyAt(blockposition); - boolean flag1 = this.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.getEffectiveDifficulty() * 0.01D && !this.getBlockState(blockposition.below()).is(Blocks.LIGHTNING_ROD); -+ boolean flag1 = this.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.getEffectiveDifficulty() * this.paperConfig().entities.spawning.skeletonHorseThunderSpawnChance.or(0.01D) && !this.getBlockState(blockposition.below()).is(Blocks.LIGHTNING_ROD); // Paper ++ boolean flag1 = this.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.getEffectiveDifficulty() * this.paperConfig().entities.spawning.skeletonHorseThunderSpawnChance.or(0.01D) && !this.getBlockState(blockposition.below()).is(Blocks.LIGHTNING_ROD); // Paper - Configurable spawn chances for skeleton horses if (flag1) { SkeletonHorse entityhorseskeleton = (SkeletonHorse) EntityType.SKELETON_HORSE.create(this); diff --git a/patches/server/Deobfuscate-stacktraces-in-log-messages-crash-report.patch b/patches/server/Deobfuscate-stacktraces-in-log-messages-crash-report.patch index 3cf0c1274b..eff4570a03 100644 --- a/patches/server/Deobfuscate-stacktraces-in-log-messages-crash-report.patch +++ b/patches/server/Deobfuscate-stacktraces-in-log-messages-crash-report.patch @@ -596,7 +596,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } catch (Exception exception) { - exception.printStackTrace(); + io.papermc.paper.util.TraceUtil.printStackTrace(exception); // Paper - ServerInternalException.reportInternalException(exception); // Paper + ServerInternalException.reportInternalException(exception); // Paper - ServerExceptionEvent } @@ -0,0 +0,0 @@ public class OldUsersConverter { @@ -605,7 +605,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } catch (Exception exception) { - exception.printStackTrace(); + io.papermc.paper.util.TraceUtil.printStackTrace(exception); // Paper - ServerInternalException.reportInternalException(exception); // Paper + ServerInternalException.reportInternalException(exception); // Paper - ServerExceptionEvent } } diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -619,7 +619,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - e.printStackTrace(); + io.papermc.paper.util.TraceUtil.printStackTrace(e); ServerInternalException.reportInternalException(e); - // Paper end + // Paper end - ServerExceptionEvent // CraftBukkit end diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/patches/server/Disable-Scoreboards-for-non-players-by-default.patch b/patches/server/Disable-Scoreboards-for-non-players-by-default.patch index aaee97d1b0..d6b3f871d8 100644 --- a/patches/server/Disable-Scoreboards-for-non-players-by-default.patch +++ b/patches/server/Disable-Scoreboards-for-non-players-by-default.patch @@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Nullable public PlayerTeam getTeam() { -+ if (!this.level().paperConfig().scoreboards.allowNonPlayerEntitiesOnScoreboards && !(this instanceof Player)) { return null; } // Paper ++ if (!this.level().paperConfig().scoreboards.allowNonPlayerEntitiesOnScoreboards && !(this instanceof Player)) { return null; } // Paper - Perf: Disable Scoreboards for non players by default return this.level().getScoreboard().getPlayersTeam(this.getScoreboardName()); } @@ -30,7 +30,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (nbt.contains("Team", 8)) { String s = nbt.getString("Team"); PlayerTeam scoreboardteam = this.level().getScoreboard().getPlayerTeam(s); -+ if (!this.level().paperConfig().scoreboards.allowNonPlayerEntitiesOnScoreboards && !(this instanceof net.minecraft.world.entity.player.Player)) { scoreboardteam = null; } // Paper ++ if (!this.level().paperConfig().scoreboards.allowNonPlayerEntitiesOnScoreboards && !(this instanceof net.minecraft.world.entity.player.Player)) { scoreboardteam = null; } // Paper - Perf: Disable Scoreboards for non players by default boolean flag = scoreboardteam != null && this.level().getScoreboard().addPlayerToTeam(this.getStringUUID(), scoreboardteam); if (!flag) { diff --git a/patches/server/Do-not-load-chunks-for-Pathfinding.patch b/patches/server/Do-not-load-chunks-for-Pathfinding.patch index 81d756a44c..1dc50aa15e 100644 --- a/patches/server/Do-not-load-chunks-for-Pathfinding.patch +++ b/patches/server/Do-not-load-chunks-for-Pathfinding.patch @@ -13,12 +13,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (l != 0 || n != 0) { pos.set(i + l, j + m, k + n); - BlockState blockState = world.getBlockState(pos); -+ // Paper start ++ // Paper start - Do not load chunks during pathfinding + BlockState blockState = world.getBlockStateIfLoaded(pos); + if (blockState == null) { + return BlockPathTypes.BLOCKED; + } else { -+ // Paper end ++ // Paper end - Do not load chunks during pathfinding if (blockState.is(Blocks.CACTUS) || blockState.is(Blocks.SWEET_BERRY_BUSH)) { return BlockPathTypes.DANGER_OTHER; } @@ -35,8 +35,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 protected static BlockPathTypes getBlockPathTypeRaw(BlockGetter world, BlockPos pos) { - BlockState blockState = world.getBlockState(pos); -+ BlockState blockState = world.getBlockStateIfLoaded(pos); // Paper -+ if (blockState == null) return BlockPathTypes.BLOCKED; // Paper ++ BlockState blockState = world.getBlockStateIfLoaded(pos); // Paper - Do not load chunks during pathfinding ++ if (blockState == null) return BlockPathTypes.BLOCKED; // Paper - Do not load chunks during pathfinding Block block = blockState.getBlock(); if (blockState.isAir()) { return BlockPathTypes.OPEN; diff --git a/patches/server/Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch b/patches/server/Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch index a77a2c98ff..4cea5e5e4d 100644 --- a/patches/server/Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch +++ b/patches/server/Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch @@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 ListTag listTag = new ListTag(); for(PlayerTeam playerTeam : this.scoreboard.getPlayerTeams()) { -+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().scoreboards.saveEmptyScoreboardTeams && playerTeam.getPlayers().isEmpty()) continue; // Paper ++ if (!io.papermc.paper.configuration.GlobalConfiguration.get().scoreboards.saveEmptyScoreboardTeams && playerTeam.getPlayers().isEmpty()) continue; // Paper - Don't save empty scoreboard teams to scoreboard.dat CompoundTag compoundTag = new CompoundTag(); compoundTag.putString("Name", playerTeam.getName()); compoundTag.putString("DisplayName", Component.Serializer.toJson(playerTeam.getDisplayName())); diff --git a/patches/server/Drop-carried-item-when-player-has-disconnected.patch b/patches/server/Drop-carried-item-when-player-has-disconnected.patch index 790560c6fe..e2b7b61abc 100644 --- a/patches/server/Drop-carried-item-when-player-has-disconnected.patch +++ b/patches/server/Drop-carried-item-when-player-has-disconnected.patch @@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -0,0 +0,0 @@ public abstract class PlayerList { } - // Paper end + // Paper end - Configurable player collision + // Paper - Drop carried item when player has disconnected + if (!entityplayer.containerMenu.getCarried().isEmpty()) { diff --git a/patches/server/Entity-getEntitySpawnReason.patch b/patches/server/Entity-getEntitySpawnReason.patch index deff36c67a..6ea9bc5b1a 100644 --- a/patches/server/Entity-getEntitySpawnReason.patch +++ b/patches/server/Entity-getEntitySpawnReason.patch @@ -65,7 +65,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } } - // Paper end + // Paper end - Share random for entities to make them more random + public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper diff --git a/patches/server/EntityPathfindEvent.patch b/patches/server/EntityPathfindEvent.patch index 46ec66ae31..d868610cd0 100644 --- a/patches/server/EntityPathfindEvent.patch +++ b/patches/server/EntityPathfindEvent.patch @@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public Path createPath(Entity entity, int distance) { - return this.createPath(entity.blockPosition(), distance); -+ return this.createPath(entity.blockPosition(), entity, distance); // Paper - Forward target entity ++ return this.createPath(entity.blockPosition(), entity, distance); // Paper - EntityPathfindEvent } @Override @@ -27,7 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override - public Path createPath(BlockPos target, int distance) { -+ public Path createPath(BlockPos target, @javax.annotation.Nullable Entity entity, int distance) { // Paper ++ public Path createPath(BlockPos target, @javax.annotation.Nullable Entity entity, int distance) { // Paper - EntityPathfindEvent LevelChunk levelChunk = this.level.getChunkSource().getChunkNow(SectionPos.blockToSectionCoord(target.getX()), SectionPos.blockToSectionCoord(target.getZ())); if (levelChunk == null) { return null; @@ -36,7 +36,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (blockPos.getY() > this.level.getMinBuildHeight()) { - return super.createPath(blockPos.above(), distance); -+ return super.createPath(blockPos.above(), entity, distance); // Paper ++ return super.createPath(blockPos.above(), entity, distance); // Paper - EntityPathfindEvent } while(blockPos.getY() < this.level.getMaxBuildHeight() && levelChunk.getBlockState(blockPos).isAir()) { @@ -45,14 +45,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (!levelChunk.getBlockState(target).isSolid()) { - return super.createPath(target, distance); -+ return super.createPath(target, entity, distance); // Paper ++ return super.createPath(target, entity, distance); // Paper - EntityPathfindEvent } else { BlockPos blockPos2; for(blockPos2 = target.above(); blockPos2.getY() < this.level.getMaxBuildHeight() && levelChunk.getBlockState(blockPos2).isSolid(); blockPos2 = blockPos2.above()) { } - return super.createPath(blockPos2, distance); -+ return super.createPath(blockPos2, entity, distance); // Paper ++ return super.createPath(blockPos2, entity, distance); // Paper - EntityPathfindEvent } } } @@ -60,7 +60,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public Path createPath(Entity entity, int distance) { - return this.createPath(entity.blockPosition(), distance); -+ return this.createPath(entity.blockPosition(), entity, distance); // Paper - Forward target entity ++ return this.createPath(entity.blockPosition(), entity, distance); // Paper - EntityPathfindEvent } private int getSurfaceY() { @@ -73,13 +73,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Nullable public Path createPath(BlockPos target, int distance) { - return this.createPath(ImmutableSet.of(target), 8, false, distance); -+ // Paper start - add target entity parameter ++ // Paper start - EntityPathfindEvent + return this.createPath(target, null, distance); + } + @Nullable + public Path createPath(BlockPos target, @Nullable Entity entity, int distance) { + return this.createPath(ImmutableSet.of(target), entity, 8, false, distance); -+ // Paper end ++ // Paper end - EntityPathfindEvent } @Nullable @@ -88,7 +88,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Nullable public Path createPath(Entity entity, int distance) { - return this.createPath(ImmutableSet.of(entity.blockPosition()), 16, true, distance); -+ return this.createPath(ImmutableSet.of(entity.blockPosition()), entity, 16, true, distance); // Paper ++ return this.createPath(ImmutableSet.of(entity.blockPosition()), entity, 16, true, distance); // Paper - EntityPathfindEvent } @Nullable @@ -96,6 +96,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Nullable protected Path createPath(Set positions, int range, boolean useHeadPos, int distance, float followRange) { ++ // Paper start - EntityPathfindEvent + return this.createPath(positions, null, range, useHeadPos, distance, followRange); + } + @@ -105,7 +106,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + @Nullable protected Path createPath(Set positions, @Nullable Entity target, int range, boolean useHeadPos, int distance, float followRange) { -+ // Paper end ++ // Paper end - EntityPathfindEvent if (positions.isEmpty()) { return null; } else if (this.mob.getY() < (double)this.level.getMinBuildHeight()) { @@ -113,7 +114,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } else if (this.path != null && !this.path.isDone() && positions.contains(this.targetPos)) { return this.path; } else { -+ // Paper start - Pathfind event ++ // Paper start - EntityPathfindEvent + boolean copiedSet = false; + for (BlockPos possibleTarget : positions) { + if (!new com.destroystokyo.paper.event.entity.EntityPathfindEvent(this.mob.getBukkitEntity(), @@ -129,7 +130,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + } -+ // Paper end ++ // Paper end - EntityPathfindEvent this.level.getProfiler().push("pathfind"); BlockPos blockPos = useHeadPos ? this.mob.blockPosition().above() : this.mob.blockPosition(); int i = (int)(followRange + (float)range); @@ -142,10 +143,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override - public Path createPath(BlockPos target, int distance) { -+ public Path createPath(BlockPos target, @Nullable Entity entity, int distance) { // Paper ++ public Path createPath(BlockPos target, @Nullable Entity entity, int distance) { // Paper - EntityPathfindEvent this.pathToPosition = target; - return super.createPath(target, distance); -+ return super.createPath(target, entity, distance); // Paper ++ return super.createPath(target, entity, distance); // Paper - EntityPathfindEvent } @Override diff --git a/patches/server/Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch b/patches/server/Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch index 3ce338b7ea..abf4fad11e 100644 --- a/patches/server/Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch +++ b/patches/server/Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch @@ -102,12 +102,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - Fire PlayerJoinEvent when Player is actually ready player.initInventoryMenu(); // CraftBukkit - Moved from above, added world - // Paper start - Add to collideRule team if needed -@@ -0,0 +0,0 @@ public abstract class PlayerList { - scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam); - } - // Paper end -+ // CraftBukkit - Moved from above, added world - PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), s1, player.getId(), worldserver1.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ()); - } - + // Paper start - Configurable player collision; Add to collideRule team if needed diff --git a/patches/server/Fix-block-place-logic.patch b/patches/server/Fix-block-place-logic.patch index 41b238568c..2438b0ad79 100644 --- a/patches/server/Fix-block-place-logic.patch +++ b/patches/server/Fix-block-place-logic.patch @@ -49,7 +49,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 iblockdata1.updateIndirectNeighbourShapes(this, blockposition, k, j - 1); // Don't call an event for the old block to limit event spam CraftWorld world = ((ServerLevel) this).getWorld(); + boolean cancelledUpdates = false; // Paper - Fix block place logic - if (world != null && ((ServerLevel)this).hasPhysicsEvent) { // Paper + if (world != null && ((ServerLevel)this).hasPhysicsEvent) { // Paper - BlockPhysicsEvent BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), CraftBlockData.fromData(iblockdata)); this.getCraftServer().getPluginManager().callEvent(event); diff --git a/patches/server/Friction-API.patch b/patches/server/Friction-API.patch index b2464444b3..863ce9addc 100644 --- a/patches/server/Friction-API.patch +++ b/patches/server/Friction-API.patch @@ -38,9 +38,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 nbt.putShort("HurtTime", (short) this.hurtTime); nbt.putInt("HurtByTimestamp", this.lastHurtByMobTimestamp); @@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable { - absorptionAmount = 0; } this.internalSetAbsorptionAmount(absorptionAmount); + // Paper end - Check for NaN + // Paper start - Friction API + if (nbt.contains("Paper.FrictionState")) { + String fs = nbt.getString("Paper.FrictionState"); @@ -51,9 +51,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + // Paper end - Friction API - // Paper end if (nbt.contains("Attributes", 9) && this.level() != null && !this.level().isClientSide) { this.getAttributes().load(nbt.getList("Attributes", 10)); + } diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java diff --git a/patches/server/Improve-Player-chat-API-handling.patch b/patches/server/Improve-Player-chat-API-handling.patch index 5daa7a6e5b..3844bee337 100644 --- a/patches/server/Improve-Player-chat-API-handling.patch +++ b/patches/server/Improve-Player-chat-API-handling.patch @@ -74,7 +74,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.getHandle().connection.chat(msg, playerChatMessage, false); + } + } -+ // Paper end ++ // Paper end - Improve chat handling } @Override diff --git a/patches/server/Improved-Watchdog-Support.patch b/patches/server/Improved-Watchdog-Support.patch index e7ad9cfb17..f4003acb0b 100644 --- a/patches/server/Improved-Watchdog-Support.patch +++ b/patches/server/Improved-Watchdog-Support.patch @@ -122,7 +122,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this.metricsRecorder.isRecording()) { this.cancelRecordingMetrics(); @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper + worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - BlockPhysicsEvent net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java diff --git a/patches/server/LootTable-API-Replenishable-Lootables-Feature.patch b/patches/server/LootTable-API-and-replenishable-lootables.patch similarity index 99% rename from patches/server/LootTable-API-Replenishable-Lootables-Feature.patch rename to patches/server/LootTable-API-and-replenishable-lootables.patch index 49efc6769b..5ce986f628 100644 --- a/patches/server/LootTable-API-Replenishable-Lootables-Feature.patch +++ b/patches/server/LootTable-API-and-replenishable-lootables.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 1 May 2016 21:19:14 -0400 -Subject: [PATCH] LootTable API & Replenishable Lootables Feature +Subject: [PATCH] LootTable API and replenishable lootables Provides an API to control the loot table for an object. Also provides a feature that any Lootable Inventory (Chests in Structures) @@ -509,7 +509,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } - // Paper end + // Paper end - Share random for entities to make them more random + public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper private CraftEntity bukkitEntity; diff --git a/patches/server/Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch b/patches/server/Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch index 172191f35c..71510d239f 100644 --- a/patches/server/Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch +++ b/patches/server/Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch @@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 while (iterator.hasNext()) { ServerLevel worldserver = (ServerLevel) iterator.next(); -+ worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper ++ worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - BlockPhysicsEvent this.profiler.push(() -> { return worldserver + " " + worldserver.dimension().location(); @@ -25,9 +25,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit start public final LevelStorageSource.LevelStorageAccess convertable; public final UUID uuid; -+ public boolean hasPhysicsEvent = true; // Paper ++ public boolean hasPhysicsEvent = true; // Paper - BlockPhysicsEvent - @Override public LevelChunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI + public LevelChunk getChunkIfLoaded(int x, int z) { return this.chunkSource.getChunk(x, z, false); 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 @@ -38,7 +38,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 iblockdata1.updateIndirectNeighbourShapes(this, blockposition, k, j - 1); // Don't call an event for the old block to limit event spam CraftWorld world = ((ServerLevel) this).getWorld(); - if (world != null) { -+ if (world != null && ((ServerLevel)this).hasPhysicsEvent) { // Paper ++ if (world != null && ((ServerLevel)this).hasPhysicsEvent) { // Paper - BlockPhysicsEvent BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), CraftBlockData.fromData(iblockdata)); this.getCraftServer().getPluginManager().callEvent(event); diff --git a/patches/server/Only-write-chunk-data-to-disk-if-it-serializes-witho.patch b/patches/server/Only-write-chunk-data-to-disk-if-it-serializes-witho.patch index 6aaee02c2a..0750d26d25 100644 --- a/patches/server/Only-write-chunk-data-to-disk-if-it-serializes-witho.patch +++ b/patches/server/Only-write-chunk-data-to-disk-if-it-serializes-witho.patch @@ -79,7 +79,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - } + // Paper - don't write garbage data to disk if writing serialization fails; move into try block to only write if successfully serialized } - // Paper start + // Paper start - Chunk save reattempt return; @@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable { } diff --git a/patches/server/Optimize-DataBits.patch b/patches/server/Optimize-DataBits.patch index 084ba363dd..e3ae8f867c 100644 --- a/patches/server/Optimize-DataBits.patch +++ b/patches/server/Optimize-DataBits.patch @@ -20,8 +20,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private final int valuesPerLong; - private final int divideMul; - private final int divideAdd; -+ private final int divideMul; private final long divideMulUnsigned; // Paper - referenced in b(int) with 2 Integer.toUnsignedLong calls -+ private final int divideAdd; private final long divideAddUnsigned; // Paper ++ private final int divideMul; private final long divideMulUnsigned; // Paper - Perf: Optimize SimpleBitStorage; referenced in b(int) with 2 Integer.toUnsignedLong calls ++ private final int divideAdd; private final long divideAddUnsigned; // Paper - Perf: Optimize SimpleBitStorage private final int divideShift; public SimpleBitStorage(int elementBits, int size, int[] data) { @@ -31,8 +31,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 int i = 3 * (this.valuesPerLong - 1); - this.divideMul = MAGIC[i + 0]; - this.divideAdd = MAGIC[i + 1]; -+ this.divideMul = MAGIC[i + 0]; this.divideMulUnsigned = Integer.toUnsignedLong(this.divideMul); // Paper -+ this.divideAdd = MAGIC[i + 1]; this.divideAddUnsigned = Integer.toUnsignedLong(this.divideAdd); // Paper ++ this.divideMul = MAGIC[i + 0]; this.divideMulUnsigned = Integer.toUnsignedLong(this.divideMul); // Paper - Perf: Optimize SimpleBitStorage ++ this.divideAdd = MAGIC[i + 1]; this.divideAddUnsigned = Integer.toUnsignedLong(this.divideAdd); // Paper - Perf: Optimize SimpleBitStorage this.divideShift = MAGIC[i + 2]; int j = (size + this.valuesPerLong - 1) / this.valuesPerLong; if (data != null) { @@ -43,18 +43,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - long l = Integer.toUnsignedLong(this.divideMul); - long m = Integer.toUnsignedLong(this.divideAdd); - return (int)((long)index * l + m >> 32 >> this.divideShift); -+ //long l = Integer.toUnsignedLong(this.divideMul); // Paper -+ //long m = Integer.toUnsignedLong(this.divideAdd); // Paper -+ return (int) ((long) index * this.divideMulUnsigned + this.divideAddUnsigned >> 32 >> this.divideShift); // Paper ++ //long l = Integer.toUnsignedLong(this.divideMul); // Paper - Perf: Optimize SimpleBitStorage ++ //long m = Integer.toUnsignedLong(this.divideAdd); // Paper - Perf: Optimize SimpleBitStorage ++ return (int) ((long) index * this.divideMulUnsigned + this.divideAddUnsigned >> 32 >> this.divideShift); // Paper - Perf: Optimize SimpleBitStorage } @Override - public int getAndSet(int index, int value) { - Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); - Validate.inclusiveBetween(0L, this.mask, (long)value); -+ public final int getAndSet(int index, int value) { // Paper - make final for inline -+ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper -+ //Validate.inclusiveBetween(0L, this.mask, (long)value); // Paper ++ public final int getAndSet(int index, int value) { // Paper - Perf: Optimize SimpleBitStorage ++ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage ++ //Validate.inclusiveBetween(0L, this.mask, (long)value); // Paper - Perf: Optimize SimpleBitStorage int i = this.cellIndex(index); long l = this.data[i]; int j = (index - i * this.valuesPerLong) * this.bits; @@ -65,9 +65,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - public void set(int index, int value) { - Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); - Validate.inclusiveBetween(0L, this.mask, (long)value); -+ public final void set(int index, int value) { // Paper - make final for inline -+ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper -+ //Validate.inclusiveBetween(0L, this.mask, (long)value); // Paper ++ public final void set(int index, int value) { // Paper - Perf: Optimize SimpleBitStorage ++ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage ++ //Validate.inclusiveBetween(0L, this.mask, (long)value); // Paper - Perf: Optimize SimpleBitStorage int i = this.cellIndex(index); long l = this.data[i]; int j = (index - i * this.valuesPerLong) * this.bits; @@ -77,8 +77,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override - public int get(int index) { - Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); -+ public final int get(int index) { // Paper - make final for inline -+ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); ++ public final int get(int index) { // Paper - Perf: Optimize SimpleBitStorage ++ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); - Perf: Optimize SimpleBitStorage int i = this.cellIndex(index); long l = this.data[i]; int j = (index - i * this.valuesPerLong) * this.bits; @@ -93,9 +93,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - public int getAndSet(int index, int value) { - Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); - Validate.inclusiveBetween(0L, 0L, (long)value); -+ public final int getAndSet(int index, int value) { // Paper - make final for inline -+ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper -+ //Validate.inclusiveBetween(0L, 0L, (long)value); // Paper ++ public final int getAndSet(int index, int value) { // Paper - Perf: Optimize SimpleBitStorage ++ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage ++ //Validate.inclusiveBetween(0L, 0L, (long)value); // Paper - Perf: Optimize SimpleBitStorage return 0; } @@ -103,16 +103,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - public void set(int index, int value) { - Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); - Validate.inclusiveBetween(0L, 0L, (long)value); -+ public final void set(int index, int value) { // Paper - make final for inline -+ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper -+ //Validate.inclusiveBetween(0L, 0L, (long)value); // Paper ++ public final void set(int index, int value) { // Paper - Perf: Optimize SimpleBitStorage ++ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage ++ //Validate.inclusiveBetween(0L, 0L, (long)value); // Paper - Perf: Optimize SimpleBitStorage } @Override - public int get(int index) { - Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); -+ public final int get(int index) { // Paper - make final for inline -+ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper ++ public final int get(int index) { // Paper - Perf: Optimize SimpleBitStorage ++ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage return 0; } diff --git a/patches/server/Optimize-Hoppers.patch b/patches/server/Optimize-Hoppers.patch index cc6a0cb60b..080813cd32 100644 --- a/patches/server/Optimize-Hoppers.patch +++ b/patches/server/Optimize-Hoppers.patch @@ -56,7 +56,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper + worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - BlockPhysicsEvent + net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent diff --git a/patches/server/Optional-TNT-doesn-t-move-in-water.patch b/patches/server/Optional-TNT-doesn-t-move-in-water.patch index e3ea9ba361..fb9532a5ab 100644 --- a/patches/server/Optional-TNT-doesn-t-move-in-water.patch +++ b/patches/server/Optional-TNT-doesn-t-move-in-water.patch @@ -4,19 +4,6 @@ Date: Sun, 22 May 2016 20:20:55 -0500 Subject: [PATCH] Optional TNT doesn't move in water -diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/level/ServerEntity.java -+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java -@@ -0,0 +0,0 @@ public class ServerEntity { - @Nullable - private List> trackedDataValues; - // CraftBukkit start -- private final Set trackedPlayers; -+ final Set trackedPlayers; // Paper - private -> package - - public ServerEntity(ServerLevel worldserver, Entity entity, int i, boolean flag, Consumer> consumer, Set trackedPlayers) { - this.trackedPlayers = trackedPlayers; diff --git a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java @@ -25,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } -+ // Paper start - Optional prevent TNT from moving in water ++ // Paper start - Option to prevent TNT from moving in water + if (!this.isRemoved() && this.wasTouchingWater && this.level().paperConfig().fixes.preventTntFromMovingInWater) { + /* + * Author: Jedediah Smith @@ -45,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + }); + } + } -+ // Paper end ++ // Paper end - Option to prevent TNT from moving in water } private void explode() { @@ -54,10 +41,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return (BlockState) this.entityData.get(PrimedTnt.DATA_BLOCK_STATE_ID); } + -+ // Paper start - Optional prevent TNT from moving in water ++ // Paper start - Option to prevent TNT from moving in water + @Override + public boolean isPushedByFluid() { + return !level().paperConfig().fixes.preventTntFromMovingInWater && super.isPushedByFluid(); + } -+ // Paper end ++ // Paper end - Option to prevent TNT from moving in water } diff --git a/patches/server/Prevent-Pathfinding-out-of-World-Border.patch b/patches/server/Prevent-Pathfinding-out-of-World-Border.patch index c5d557a0bb..106163df0c 100644 --- a/patches/server/Prevent-Pathfinding-out-of-World-Border.patch +++ b/patches/server/Prevent-Pathfinding-out-of-World-Border.patch @@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java @@ -0,0 +0,0 @@ public abstract class PathNavigation { - // Paper start - Pathfind event + // Paper start - EntityPathfindEvent boolean copiedSet = false; for (BlockPos possibleTarget : positions) { - if (!new com.destroystokyo.paper.event.entity.EntityPathfindEvent(this.mob.getBukkitEntity(), diff --git a/patches/server/Sanitise-RegionFileCache-and-make-configurable.patch b/patches/server/Sanitise-RegionFileCache-and-make-configurable.patch index 1d713471f4..0d96af8f1e 100644 --- a/patches/server/Sanitise-RegionFileCache-and-make-configurable.patch +++ b/patches/server/Sanitise-RegionFileCache-and-make-configurable.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Antony Riley Date: Tue, 29 Mar 2016 08:22:55 +0300 -Subject: [PATCH] Sanitise RegionFileCache and make configurable. +Subject: [PATCH] Sanitise RegionFileCache and make configurable RegionFileCache prior to this patch would close every single open region file upon reaching a size of 256. @@ -19,7 +19,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } // 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 ++ if (this.regionCache.size() >= io.papermc.paper.configuration.GlobalConfiguration.get().misc.regionFileCacheSize) { // Paper - Sanitise RegionFileCache and make configurable. ((RegionFile) this.regionCache.removeLast()).close(); } diff --git a/patches/server/Throw-exception-on-world-create-while-being-ticked.patch b/patches/server/Throw-exception-on-world-create-while-being-ticked.patch index bee2573d09..9e9cca842b 100644 --- a/patches/server/Throw-exception-on-world-create-while-being-ticked.patch +++ b/patches/server/Throw-exception-on-world-create-while-being-ticked.patch @@ -35,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + Iterator iterator = this.getAllLevels().iterator(); // Paper - Throw exception on world create while being ticked; move down while (iterator.hasNext()) { ServerLevel worldserver = (ServerLevel) iterator.next(); - worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper + worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - BlockPhysicsEvent @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop= level; } -+ // Paper start ++ // Paper start - Share random for entities to make them more random + public static RandomSource SHARED_RANDOM = new RandomRandomSource(); + private static final class RandomRandomSource extends java.util.Random implements net.minecraft.world.level.levelgen.BitRandomSource { + private boolean locked = false; @@ -84,7 +84,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return super.nextGaussian(); + } + } -+ // Paper end ++ // Paper end - Share random for entities to make them more random + private CraftEntity bukkitEntity; @@ -94,7 +94,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.stuckSpeedMultiplier = Vec3.ZERO; this.nextStep = 1.0F; - this.random = RandomSource.create(); -+ this.random = SHARED_RANDOM; // Paper ++ this.random = SHARED_RANDOM; // Paper - Share random for entities to make them more random this.remainingFireTicks = -this.getFireImmuneTicks(); this.fluidHeight = new Object2DoubleArrayMap(2); this.fluidOnEyes = new HashSet(); @@ -107,7 +107,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public Squid(EntityType type, Level world) { super(type, world); - this.random.setSeed((long)this.getId()); -+ //this.random.setSeed((long)this.getId()); // Paper - we set the random to shared, do not clobber the seed ++ //this.random.setSeed((long)this.getId()); // Paper - Share random for entities to make them more random this.tentacleSpeed = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F; } diff --git a/patches/server/Use-getChunkIfLoadedImmediately-in-places.patch b/patches/server/Use-getChunkIfLoadedImmediately-in-places.patch index 271bef1f73..69569b6fe9 100644 --- a/patches/server/Use-getChunkIfLoadedImmediately-in-places.patch +++ b/patches/server/Use-getChunkIfLoadedImmediately-in-places.patch @@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel { public boolean hasEntityMoveEvent; // Paper - Add EntityMoveEvent - @Override public LevelChunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI + public LevelChunk getChunkIfLoaded(int x, int z) { - return this.chunkSource.getChunk(x, z, false); + return this.chunkSource.getChunkAtIfLoadedImmediately(x, z); // Paper - Use getChunkIfLoadedImmediately } diff --git a/patches/server/fix-converting-txt-to-json-file.patch b/patches/server/fix-converting-txt-to-json-file.patch index 7ca9e526f5..e26a9f98e9 100644 --- a/patches/server/fix-converting-txt-to-json-file.patch +++ b/patches/server/fix-converting-txt-to-json-file.patch @@ -42,7 +42,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } - if (this.convertOldUsers()) { -- this.getProfileCache().save(false); // Paper +- this.getProfileCache().save(false); // Paper - Perf: Async GameProfileCache saving - } if (!OldUsersConverter.serverReadyAfterUserconversion(this)) { diff --git a/patches/server/handle-NaN-health-absorb-values-and-repair-bad-data.patch b/patches/server/handle-NaN-health-absorb-values-and-repair-bad-data.patch index d1649d2052..97ca9a420d 100644 --- a/patches/server/handle-NaN-health-absorb-values-and-repair-bad-data.patch +++ b/patches/server/handle-NaN-health-absorb-values-and-repair-bad-data.patch @@ -13,13 +13,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void readAdditionalSaveData(CompoundTag nbt) { - this.internalSetAbsorptionAmount(nbt.getFloat("AbsorptionAmount")); -+ // Paper start - jvm keeps optimizing the setter ++ // Paper start - Check for NaN + float absorptionAmount = nbt.getFloat("AbsorptionAmount"); + if (Float.isNaN(absorptionAmount)) { + absorptionAmount = 0; + } + this.internalSetAbsorptionAmount(absorptionAmount); -+ // Paper end ++ // Paper end - Check for NaN if (nbt.contains("Attributes", 9) && this.level() != null && !this.level().isClientSide) { this.getAttributes().load(nbt.getList("Attributes", 10)); } @@ -27,10 +27,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } public void setHealth(float health) { -+ // Paper start ++ // Paper start - Check for NaN + if (Float.isNaN(health)) { health = getMaxHealth(); if (this.valid) { + System.err.println("[NAN-HEALTH] " + getScoreboardName() + " had NaN health set"); -+ } } // Paper end ++ } } // Paper end - Check for NaN // CraftBukkit start - Handle scaled health if (this instanceof ServerPlayer) { org.bukkit.craftbukkit.entity.CraftPlayer player = ((ServerPlayer) this).getBukkitEntity(); @@ -39,7 +39,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public final void setAbsorptionAmount(float absorptionAmount) { - this.internalSetAbsorptionAmount(Mth.clamp(absorptionAmount, 0.0F, this.getMaxAbsorption())); -+ this.internalSetAbsorptionAmount(!Float.isNaN(absorptionAmount) ? Mth.clamp(absorptionAmount, 0.0F, this.getMaxAbsorption()) : 0.0F); // Paper ++ this.internalSetAbsorptionAmount(!Float.isNaN(absorptionAmount) ? Mth.clamp(absorptionAmount, 0.0F, this.getMaxAbsorption()) : 0.0F); // Paper - Check for NaN } protected void internalSetAbsorptionAmount(float absorptionAmount) { @@ -51,7 +51,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } public void setRealHealth(double health) { -+ if (Double.isNaN(health)) {return;} // Paper ++ if (Double.isNaN(health)) {return;} // Paper - Check for NaN this.health = health; } diff --git a/patches/server/optimize-dirt-and-snow-spreading.patch b/patches/server/optimize-dirt-and-snow-spreading.patch index 689d7a7740..00ebea1389 100644 --- a/patches/server/optimize-dirt-and-snow-spreading.patch +++ b/patches/server/optimize-dirt-and-snow-spreading.patch @@ -41,7 +41,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - if (this instanceof GrassBlock && world.paperConfig().tickRates.grassSpread != 1 && (world.paperConfig().tickRates.grassSpread < 1 || (MinecraftServer.currentTick + pos.hashCode()) % world.paperConfig().tickRates.grassSpread != 0)) { return; } // Paper + if (this instanceof GrassBlock && world.paperConfig().tickRates.grassSpread != 1 && (world.paperConfig().tickRates.grassSpread < 1 || (MinecraftServer.currentTick + pos.hashCode()) % world.paperConfig().tickRates.grassSpread != 0)) { return; } // Paper - Configurable random tick rates for blocks - if (!SpreadingSnowyDirtBlock.canBeGrass(state, world, pos)) { + // Paper start - Perf: optimize dirt and snow spreading + net.minecraft.world.level.chunk.ChunkAccess cachedBlockChunk = world.getChunkIfLoaded(pos);