diff --git a/build.gradle.kts b/build.gradle.kts index 20d7b5902..8a445eca1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,7 +11,7 @@ plugins { java `maven-publish` id("com.github.johnrengelman.shadow") version "8.1.1" apply false - id("io.papermc.paperweight.core") version "1.5.13" + id("io.papermc.paperweight.core") version "1.5.15" } allprojects { @@ -69,7 +69,7 @@ repositories { dependencies { paramMappings("net.fabricmc:yarn:1.20.4+build.1:mergedv2") remapper("net.fabricmc:tiny-remapper:0.10.1:fat") - decompiler("net.minecraftforge:forgeflower:2.0.627.2") + decompiler("org.vineflower:vineflower:1.11.0-20240412.144930-14") spigotDecompiler("io.papermc:patched-spigot-fernflower:0.1+build.6") paperclip("io.papermc:paperclip:3.0.3") } @@ -80,7 +80,7 @@ paperweight { paramMappingsRepo = paperMavenPublicUrl remapRepo = paperMavenPublicUrl - decompileRepo = paperMavenPublicUrl + decompileRepo = "https://s01.oss.sonatype.org/content/repositories/snapshots/" craftBukkit { fernFlowerJar = layout.file(spigotDecompiler.elements.map { it.single().asFile }) diff --git a/patches/server/Actually-optimise-explosions.patch b/patches/server/Actually-optimise-explosions.patch index e855e5dc8..cf9d04456 100644 --- a/patches/server/Actually-optimise-explosions.patch +++ b/patches/server/Actually-optimise-explosions.patch @@ -513,9 +513,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - actually optimise explosions float f = explosion.radius() * 2.0F; Vec3 vec3 = explosion.center(); - double d = Math.sqrt(entity.distanceToSqr(vec3)) / (double)f; -- double e = (1.0D - d) * (double)Explosion.getSeenPercent(vec3, entity); -+ double e = (1.0D - d) * seenPercent; // Paper - actually optimise explosions - return (float)((e * e + e) / 2.0D * 7.0D * (double)f + 1.0D); + double d = Math.sqrt(entity.distanceToSqr(vec3)) / f; +- double e = (1.0 - d) * Explosion.getSeenPercent(vec3, entity); ++ double e = (1.0 - d) * seenPercent; // Paper - actually optimise explosions + return (float)((e * e + e) / 2.0 * 7.0 * f + 1.0); } } diff --git a/patches/server/Add-EntityFertilizeEggEvent.patch b/patches/server/Add-EntityFertilizeEggEvent.patch index 190e5b4ae..37919b875 100644 --- a/patches/server/Add-EntityFertilizeEggEvent.patch +++ b/patches/server/Add-EntityFertilizeEggEvent.patch @@ -36,12 +36,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void spawnChildFromBreeding(ServerLevel world, Animal other) { -- this.finalizeSpawnChildFromBreeding(world, other, (AgeableMob)null); +- this.finalizeSpawnChildFromBreeding(world, other, null); + // Paper start - Add EntityFertilizeEggEvent event + final io.papermc.paper.event.entity.EntityFertilizeEggEvent result = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityFertilizeEggEvent(this, other); + if (result.isCancelled()) return; + -+ this.finalizeSpawnChildFromBreeding(world, other, (AgeableMob)null, result.getExperience()); // Paper - use craftbukkit call that takes experience amount ++ this.finalizeSpawnChildFromBreeding(world, other, null, result.getExperience()); // Paper - use craftbukkit call that takes experience amount + // Paper end - Add EntityFertilizeEggEvent event this.getBrain().setMemory(MemoryModuleType.IS_PREGNANT, Unit.INSTANCE); } diff --git a/patches/server/Add-EntityInsideBlockEvent.patch b/patches/server/Add-EntityInsideBlockEvent.patch index b8b8ce27e..23db72bdf 100644 --- a/patches/server/Add-EntityInsideBlockEvent.patch +++ b/patches/server/Add-EntityInsideBlockEvent.patch @@ -265,7 +265,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - entity.makeStuckInBlock(state, new Vec3(0.25D, (double)0.05F, 0.25D)); + entity.makeStuckInBlock(state, new Vec3(0.25, 0.05F, 0.25)); } } diff --git a/src/main/java/net/minecraft/world/level/block/WitherRoseBlock.java b/src/main/java/net/minecraft/world/level/block/WitherRoseBlock.java diff --git a/patches/server/Add-EntityKnockbackByEntityEvent-and-EntityPushedByE.patch b/patches/server/Add-EntityKnockbackByEntityEvent-and-EntityPushedByE.patch index 2e43e9948..641c9970a 100644 --- a/patches/server/Add-EntityKnockbackByEntityEvent-and-EntityPushedByE.patch +++ b/patches/server/Add-EntityKnockbackByEntityEvent-and-EntityPushedByE.patch @@ -89,25 +89,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java @@ -0,0 +0,0 @@ public class RamTarget extends Behavior { - float f = 0.25F * (float)(i - j); + float f = 0.25F * (i - j); float g = Mth.clamp(entity.getSpeed() * 1.65F, 0.2F, 3.0F) + f; float h = livingEntity.isDamageSourceBlocked(world.damageSources().mobAttack(entity)) ? 0.5F : 1.0F; -- livingEntity.knockback((double)(h * g) * this.getKnockbackForce.applyAsDouble(entity), this.ramDirection.x(), this.ramDirection.z()); -+ livingEntity.knockback((double)(h * g) * this.getKnockbackForce.applyAsDouble(entity), this.ramDirection.x(), this.ramDirection.z(), entity, org.bukkit.event.entity.EntityKnockbackEvent.KnockbackCause.ENTITY_ATTACK); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent +- livingEntity.knockback(h * g * this.getKnockbackForce.applyAsDouble(entity), this.ramDirection.x(), this.ramDirection.z()); ++ livingEntity.knockback(h * g * this.getKnockbackForce.applyAsDouble(entity), this.ramDirection.x(), this.ramDirection.z(), entity, org.bukkit.event.entity.EntityKnockbackEvent.KnockbackCause.ENTITY_ATTACK); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent this.finishRam(world, entity); - world.playSound((Player)null, entity, this.getImpactSound.apply(entity), SoundSource.NEUTRAL, 1.0F, 1.0F); + world.playSound(null, entity, this.getImpactSound.apply(entity), SoundSource.NEUTRAL, 1.0F, 1.0F); } else if (this.hasRammedHornBreakingBlock(world, entity)) { diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java b/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java @@ -0,0 +0,0 @@ public class SonicBoom extends Behavior { - target.hurt(world.damageSources().sonicBoom(entity), 10.0F); - double d = 0.5D * (1.0D - target.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE)); - double e = 2.5D * (1.0D - target.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE)); -- target.push(vec33.x() * e, vec33.y() * d, vec33.z() * e); -+ target.push(vec33.x() * e, vec33.y() * d, vec33.z() * e, entity); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent - }); + target.hurt(world.damageSources().sonicBoom(entity), 10.0F); + double d = 0.5 * (1.0 - target.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE)); + double e = 2.5 * (1.0 - target.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE)); +- target.push(vec33.x() * e, vec33.y() * d, vec33.z() * e); ++ target.push(vec33.x() * e, vec33.y() * d, vec33.z() * e, entity); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent + }); } } diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java @@ -170,9 +170,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/monster/hoglin/HoglinBase.java +++ b/src/main/java/net/minecraft/world/entity/monster/hoglin/HoglinBase.java @@ -0,0 +0,0 @@ public interface HoglinBase { - double j = f * (double)(attacker.level().random.nextFloat() * 0.5F + 0.2F); - Vec3 vec3 = (new Vec3(g, 0.0D, h)).normalize().scale(j).yRot(i); - double k = f * (double)attacker.level().random.nextFloat() * 0.5D; + double j = f * (attacker.level().random.nextFloat() * 0.5F + 0.2F); + Vec3 vec3 = new Vec3(g, 0.0, h).normalize().scale(j).yRot(i); + double k = f * attacker.level().random.nextFloat() * 0.5; - target.push(vec3.x, k, vec3.z); + target.push(vec3.x, k, vec3.z, attacker); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent target.hurtMarked = true; diff --git a/patches/server/Add-Listing-API-for-Player.patch b/patches/server/Add-Listing-API-for-Player.patch index 3aa75974c..112790ba0 100644 --- a/patches/server/Add-Listing-API-for-Player.patch +++ b/patches/server/Add-Listing-API-for-Player.patch @@ -25,7 +25,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - Add Listing API for Player public static ClientboundPlayerInfoUpdatePacket createPlayerInitializing(Collection players) { - EnumSet enumSet = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME); + EnumSet enumSet = EnumSet.of( +@@ -0,0 +0,0 @@ public class ClientboundPlayerInfoUpdatePacket implements Packet { + this.entries = buf.readList(buf2 -> { @@ -0,0 +0,0 @@ public class ClientboundPlayerInfoUpdatePacket implements Packet { - return Component.translatable("commands.kick.success", serverPlayer.getDisplayName(), reason); - }, true); + source.sendSuccess(() -> Component.translatable("commands.kick.success", serverPlayer.getDisplayName(), reason), true); + i++; + } diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java diff --git a/patches/server/Add-PlayerShearBlockEvent.patch b/patches/server/Add-PlayerShearBlockEvent.patch index bd19ba6a2..eda34239e 100644 --- a/patches/server/Add-PlayerShearBlockEvent.patch +++ b/patches/server/Add-PlayerShearBlockEvent.patch @@ -55,16 +55,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - Add PlayerShearBlockEvent Direction direction = hit.getDirection(); Direction direction2 = direction.getAxis() == Direction.Axis.Y ? player.getDirection().getOpposite() : direction; - world.playSound((Player)null, pos, SoundEvents.PUMPKIN_CARVE, SoundSource.BLOCKS, 1.0F, 1.0F); + world.playSound(null, pos, SoundEvents.PUMPKIN_CARVE, SoundSource.BLOCKS, 1.0F, 1.0F); world.setBlock(pos, Blocks.CARVED_PUMPKIN.defaultBlockState().setValue(CarvedPumpkinBlock.FACING, direction2), 11); -- ItemEntity itemEntity = new ItemEntity(world, (double)pos.getX() + 0.5D + (double)direction2.getStepX() * 0.65D, (double)pos.getY() + 0.1D, (double)pos.getZ() + 0.5D + (double)direction2.getStepZ() * 0.65D, new ItemStack(Items.PUMPKIN_SEEDS, 4)); -+ // Paper start - Add PlayerShearBlockEvent -+ for (org.bukkit.inventory.ItemStack item : event.getDrops()) { -+ ItemEntity itemEntity = new ItemEntity(world, (double) pos.getX() + 0.5D + (double) direction2.getStepX() * 0.65D, (double) pos.getY() + 0.1D, (double) pos.getZ() + 0.5D + (double) direction2.getStepZ() * 0.65D, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(item)); -+ // Paper end - Add PlayerShearBlockEvent - itemEntity.setDeltaMovement(0.05D * (double)direction2.getStepX() + world.random.nextDouble() * 0.02D, 0.05D, 0.05D * (double)direction2.getStepZ() + world.random.nextDouble() * 0.02D); ++ for (org.bukkit.inventory.ItemStack item : event.getDrops()) { // Paper - Add PlayerShearBlockEvent + ItemEntity itemEntity = new ItemEntity( + world, + pos.getX() + 0.5 + direction2.getStepX() * 0.65, + pos.getY() + 0.1, + pos.getZ() + 0.5 + direction2.getStepZ() * 0.65, +- new ItemStack(Items.PUMPKIN_SEEDS, 4) ++ org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(item) // Paper - Add PlayerShearBlockEvent + ); + itemEntity.setDeltaMovement( + 0.05 * direction2.getStepX() + world.random.nextDouble() * 0.02, 0.05, 0.05 * direction2.getStepZ() + world.random.nextDouble() * 0.02 + ); world.addFreshEntity(itemEntity); + } // Paper - Add PlayerShearBlockEvent - itemStack.hurtAndBreak(1, player, (playerx) -> { - playerx.broadcastBreakEvent(hand); - }); + itemStack.hurtAndBreak(1, player, playerx -> playerx.broadcastBreakEvent(hand)); + world.gameEvent(player, GameEvent.SHEAR, pos); + player.awardStat(Stats.ITEM_USED.get(Items.SHEARS)); diff --git a/patches/server/Add-TargetHitEvent.patch b/patches/server/Add-TargetHitEvent.patch index ccfdf0458..93262fc70 100644 --- a/patches/server/Add-TargetHitEvent.patch +++ b/patches/server/Add-TargetHitEvent.patch @@ -16,9 +16,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + private static void awardTargetHitCriteria(Projectile projectile, BlockHitResult hit, int i) { + // Paper end - Add TargetHitEvent - Entity entity = projectile.getOwner(); - if (entity instanceof ServerPlayer serverPlayer) { + if (projectile.getOwner() instanceof ServerPlayer serverPlayer) { serverPlayer.awardStat(Stats.TARGET_HIT); + CriteriaTriggers.TARGET_BLOCK_HIT.trigger(serverPlayer, projectile, hit.getLocation(), i); @@ -0,0 +0,0 @@ public class TargetBlock extends Block { private static int updateRedstoneOutput(LevelAccessor world, BlockState state, BlockHitResult hitResult, Entity entity) { int i = getRedstoneStrength(hitResult, hitResult.getLocation()); diff --git a/patches/server/Add-WardenAngerChangeEvent.patch b/patches/server/Add-WardenAngerChangeEvent.patch index 53696cbfa..6eee3abe8 100644 --- a/patches/server/Add-WardenAngerChangeEvent.patch +++ b/patches/server/Add-WardenAngerChangeEvent.patch @@ -9,14 +9,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/monster/warden/AngerManagement.java +++ b/src/main/java/net/minecraft/world/entity/monster/warden/AngerManagement.java @@ -0,0 +0,0 @@ public class AngerManagement { + public int increaseAnger(Entity entity, int amount) { boolean bl = !this.angerBySuspect.containsKey(entity); - int i = this.angerBySuspect.computeInt(entity, (suspect, anger) -> { -- return Math.min(150, (anger == null ? 0 : anger) + amount); -+ return Math.min(150, (anger == null ? 0 : anger) + amount); // Paper - diff on change (Warden#increaseAngerAt WardenAngerChangeEvent) - }); +- int i = this.angerBySuspect.computeInt(entity, (suspect, anger) -> Math.min(150, (anger == null ? 0 : anger) + amount)); ++ int i = this.angerBySuspect.computeInt(entity, (suspect, anger) -> Math.min(150, (anger == null ? 0 : anger) + amount)); // Paper - diff on change (Warden#increaseAngerAt WardenAngerChangeEvent) if (bl) { int j = this.angerByUuid.removeInt(entity.getUUID()); + i += j; diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.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 57dbff9c9..c9ab7cfdc 100644 --- a/patches/server/Add-ability-to-configure-frosted_ice-properties.patch +++ b/patches/server/Add-ability-to-configure-frosted_ice-properties.patch @@ -13,9 +13,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + 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(); - + 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)) { @@ -0,0 +0,0 @@ public class FrostedIceBlock extends IceBlock { mutableBlockPos.setWithOffset(pos, direction); BlockState blockState = world.getBlockState(mutableBlockPos); @@ -24,7 +24,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + 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 - Frosted ice options diff --git a/patches/server/Add-and-fix-missing-BlockFadeEvents.patch b/patches/server/Add-and-fix-missing-BlockFadeEvents.patch index 8524a6b2e..74a03a634 100644 --- a/patches/server/Add-and-fix-missing-BlockFadeEvents.patch +++ b/patches/server/Add-and-fix-missing-BlockFadeEvents.patch @@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end - Call BlockFadeEvent this.destroyBlock(world, pos); - world.playSound((Player)null, pos, SoundEvents.FROGSPAWN_HATCH, SoundSource.BLOCKS, 1.0F, 1.0F); + world.playSound(null, pos, SoundEvents.FROGSPAWN_HATCH, SoundSource.BLOCKS, 1.0F, 1.0F); this.spawnTadpoles(world, pos, random); diff --git a/src/main/java/net/minecraft/world/level/block/ScaffoldingBlock.java b/src/main/java/net/minecraft/world/level/block/ScaffoldingBlock.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -57,15 +57,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { if (!this.isReadyToHatch(state)) { - world.playSound((Player)null, pos, SoundEvents.SNIFFER_EGG_CRACK, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); + world.playSound(null, pos, SoundEvents.SNIFFER_EGG_CRACK, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); world.setBlock(pos, state.setValue(HATCH, Integer.valueOf(this.getHatchLevel(state) + 1)), 2); } else { + // Paper start - Call BlockFadeEvent + if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, state.getFluidState().createLegacyBlock()).isCancelled()) { -+ rescheduleTick(world, pos); ++ this.rescheduleTick(world, pos); + return; + } + // Paper end - Call BlockFadeEvent - world.playSound((Player)null, pos, SoundEvents.SNIFFER_EGG_HATCH, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); + world.playSound(null, pos, SoundEvents.SNIFFER_EGG_HATCH, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); world.destroyBlock(pos, false); Sniffer sniffer = EntityType.SNIFFER.create(world); diff --git a/patches/server/Add-missing-forceDrop-toggles.patch b/patches/server/Add-missing-forceDrop-toggles.patch index ee9e4b820..4272df16a 100644 --- a/patches/server/Add-missing-forceDrop-toggles.patch +++ b/patches/server/Add-missing-forceDrop-toggles.patch @@ -16,8 +16,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 entity.spawnAtLocation(itemStack, 0.5F); + entity.forceDrops = false; // Paper - Add missing forceDrop toggles } - } + } diff --git a/src/main/java/net/minecraft/world/entity/animal/Panda.java b/src/main/java/net/minecraft/world/entity/animal/Panda.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Panda.java diff --git a/patches/server/Add-missing-structure-set-seed-configs.patch b/patches/server/Add-missing-structure-set-seed-configs.patch index 824eb169c..b8897b769 100644 --- a/patches/server/Add-missing-structure-set-seed-configs.patch +++ b/patches/server/Add-missing-structure-set-seed-configs.patch @@ -170,13 +170,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + // Paper end - Add missing structure set seed configs - if (!this.isPlacementChunk(calculator, chunkX, chunkZ)) { - return false; -- } else if (this.frequency < 1.0F && !this.frequencyReductionMethod.shouldGenerate(calculator.getLevelSeed(), this.salt, chunkX, chunkZ, this.frequency)) { -+ } else if (this.frequency < 1.0F && !this.frequencyReductionMethod.shouldGenerate(calculator.getLevelSeed(), this.salt, chunkX, chunkZ, this.frequency, saltOverride)) { // Paper - Add missing structure set seed configs - return false; - } else { - return !this.exclusionZone.isPresent() || !this.exclusionZone.get().isPlacementForbidden(calculator, chunkX, chunkZ); + return this.isPlacementChunk(calculator, chunkX, chunkZ) +- && (!(this.frequency < 1.0F) || this.frequencyReductionMethod.shouldGenerate(calculator.getLevelSeed(), this.salt, chunkX, chunkZ, this.frequency)) ++ && (!(this.frequency < 1.0F) || this.frequencyReductionMethod.shouldGenerate(calculator.getLevelSeed(), this.salt, chunkX, chunkZ, this.frequency, saltOverride)) // Paper - Add missing structure set seed configs + && (!this.exclusionZone.isPresent() || !this.exclusionZone.get().isPlacementForbidden(calculator, chunkX, chunkZ)); + } + @@ -0,0 +0,0 @@ public abstract class StructurePlacement { public abstract StructurePlacementType type(); @@ -198,7 +197,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + worldgenRandom.setLargeFeatureWithSalt(seed, chunkX, chunkZ, saltOverride); + } + // Paper end - Add missing structure set seed configs - return worldgenRandom.nextDouble() < (double)frequency; + return worldgenRandom.nextDouble() < frequency; } - private static boolean legacyArbitrarySaltProbabilityReducer(long seed, int salt, int chunkX, int chunkZ, float frequency) { diff --git a/patches/server/Add-more-advancement-API.patch b/patches/server/Add-more-advancement-API.patch index 47911d156..2eea3ee4e 100644 --- a/patches/server/Add-more-advancement-API.patch +++ b/patches/server/Add-more-advancement-API.patch @@ -93,8 +93,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private float y; + public final io.papermc.paper.advancement.AdvancementDisplay paper = new io.papermc.paper.advancement.PaperAdvancementDisplay(this); // Paper - Add more advancement API - public DisplayInfo(ItemStack icon, Component title, Component description, Optional background, AdvancementType frame, boolean showToast, boolean announceToChat, boolean hidden) { - this.title = title; + public DisplayInfo( + ItemStack icon, diff --git a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java diff --git a/patches/server/Add-option-for-strict-advancement-dimension-checks.patch b/patches/server/Add-option-for-strict-advancement-dimension-checks.patch index 07277af7e..9ae27585e 100644 --- a/patches/server/Add-option-for-strict-advancement-dimension-checks.patch +++ b/patches/server/Add-option-for-strict-advancement-dimension-checks.patch @@ -14,7 +14,7 @@ diff --git a/src/main/java/net/minecraft/advancements/critereon/LocationPredicat index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/advancements/critereon/LocationPredicate.java +++ b/src/main/java/net/minecraft/advancements/critereon/LocationPredicate.java -@@ -0,0 +0,0 @@ public record LocationPredicate(Optional po +@@ -0,0 +0,0 @@ public record LocationPredicate( public boolean matches(ServerLevel world, double x, double y, double z) { if (this.position.isPresent() && !this.position.get().matches(x, y, z)) { return false; diff --git a/patches/server/Add-option-to-disable-block-updates.patch b/patches/server/Add-option-to-disable-block-updates.patch index 81696e2a6..e6fed1176 100644 --- a/patches/server/Add-option-to-disable-block-updates.patch +++ b/patches/server/Add-option-to-disable-block-updates.patch @@ -51,27 +51,31 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return this.defaultBlockState(); // Paper - add option to disable block updates BlockGetter blockGetter = ctx.getLevel(); BlockPos blockPos = ctx.getClickedPos(); - return this.defaultBlockState().setValue(DOWN, Boolean.valueOf(!blockGetter.getBlockState(blockPos.below()).is(this))).setValue(UP, Boolean.valueOf(!blockGetter.getBlockState(blockPos.above()).is(this))).setValue(NORTH, Boolean.valueOf(!blockGetter.getBlockState(blockPos.north()).is(this))).setValue(EAST, Boolean.valueOf(!blockGetter.getBlockState(blockPos.east()).is(this))).setValue(SOUTH, Boolean.valueOf(!blockGetter.getBlockState(blockPos.south()).is(this))).setValue(WEST, Boolean.valueOf(!blockGetter.getBlockState(blockPos.west()).is(this))); + return this.defaultBlockState() @@ -0,0 +0,0 @@ public class HugeMushroomBlock extends Block { @Override public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return state; // Paper - add option to disable block updates - return neighborState.is(this) ? state.setValue(PROPERTY_BY_DIRECTION.get(direction), Boolean.valueOf(false)) : super.updateShape(state, direction, neighborState, world, pos, neighborPos); - } + return neighborState.is(this) + ? state.setValue(PROPERTY_BY_DIRECTION.get(direction), Boolean.valueOf(false)) + : super.updateShape(state, direction, neighborState, world, pos, neighborPos); +@@ -0,0 +0,0 @@ public class HugeMushroomBlock extends Block { @Override public BlockState rotate(BlockState state, Rotation rotation) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return state; // Paper - add option to disable block updates - return state.setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.NORTH)), state.getValue(NORTH)).setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.SOUTH)), state.getValue(SOUTH)).setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.EAST)), state.getValue(EAST)).setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.WEST)), state.getValue(WEST)).setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.UP)), state.getValue(UP)).setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.DOWN)), state.getValue(DOWN)); - } + return state.setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.NORTH)), state.getValue(NORTH)) + .setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.SOUTH)), state.getValue(SOUTH)) + .setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.EAST)), state.getValue(EAST)) +@@ -0,0 +0,0 @@ public class HugeMushroomBlock extends Block { @Override public BlockState mirror(BlockState state, Mirror mirror) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return state; // Paper - add option to disable block updates - return state.setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.NORTH)), state.getValue(NORTH)).setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.SOUTH)), state.getValue(SOUTH)).setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.EAST)), state.getValue(EAST)).setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.WEST)), state.getValue(WEST)).setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.UP)), state.getValue(UP)).setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.DOWN)), state.getValue(DOWN)); - } - + return state.setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.NORTH)), state.getValue(NORTH)) + .setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.SOUTH)), state.getValue(SOUTH)) + .setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.EAST)), state.getValue(EAST)) diff --git a/src/main/java/net/minecraft/world/level/block/NoteBlock.java b/src/main/java/net/minecraft/world/level/block/NoteBlock.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/block/NoteBlock.java diff --git a/patches/server/Adventure.patch b/patches/server/Adventure.patch index c95bd261d..47707978b 100644 --- a/patches/server/Adventure.patch +++ b/patches/server/Adventure.patch @@ -2139,11 +2139,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 MinecraftServer minecraftServer = source.getServer(); CompletableFuture completableFuture = filterPlainText(source, message); - Component component = minecraftServer.getChatDecorator().decorate(source.getPlayer(), message.decoratedContent()); -- source.getChatMessageChainer().append(completableFuture, (filtered) -> { +- source.getChatMessageChainer().append(completableFuture, filtered -> { - PlayerChatMessage playerChatMessage2 = message.withUnsignedContent(component).filter(filtered.mask()); + // Paper start - support asynchronous chat decoration + CompletableFuture componentFuture = minecraftServer.getChatDecorator().decorate(source.getPlayer(), source, message.decoratedContent()); -+ source.getChatMessageChainer().append(CompletableFuture.allOf(completableFuture, componentFuture), (filtered) -> { ++ source.getChatMessageChainer().append(CompletableFuture.allOf(completableFuture, componentFuture), filtered -> { + PlayerChatMessage playerChatMessage2 = message.withUnsignedContent(componentFuture.join().component()).filter(completableFuture.join().mask()); + // Paper end - support asynchronous chat decoration callback.accept(playerChatMessage2); @@ -2248,10 +2248,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @FunctionalInterface public interface ChatDecorator { - ChatDecorator PLAIN = (sender, message) -> { -- return message; -+ return CompletableFuture.completedFuture(message); // Paper - adventure; support async chat decoration events - }; +- ChatDecorator PLAIN = (sender, message) -> message; ++ ChatDecorator PLAIN = (sender, message) -> CompletableFuture.completedFuture(message); // Paper - adventure; support async chat decoration events; - Component decorate(@Nullable ServerPlayer sender, Component message); + @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper - adventure; support chat decoration events @@ -2342,11 +2340,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + private static Codec createCodec(Codec selfCodec, @javax.annotation.Nullable java.util.Locale locale) { + // Paper end - adventure; create separate codec for each locale - ComponentContents.Type[] types = new ComponentContents.Type[]{PlainTextContents.TYPE, TranslatableContents.TYPE, KeybindContents.TYPE, ScoreContents.TYPE, SelectorContents.TYPE, NbtContents.TYPE}; - MapCodec mapCodec = createLegacyComponentMatcher(types, ComponentContents.Type::codec, ComponentContents::type, "type"); - Codec codec = RecordCodecBuilder.create((instance) -> { - return instance.group(mapCodec.forGetter(Component::getContents), ExtraCodecs.strictOptionalField(ExtraCodecs.nonEmptyList(selfCodec.listOf()), "extra", List.of()).forGetter(Component::getSiblings), Style.Serializer.MAP_CODEC.forGetter(Component::getStyle)).apply(instance, MutableComponent::new); - }); + ComponentContents.Type[] types = new ComponentContents.Type[]{ + PlainTextContents.TYPE, TranslatableContents.TYPE, KeybindContents.TYPE, ScoreContents.TYPE, SelectorContents.TYPE, NbtContents.TYPE + }; +@@ -0,0 +0,0 @@ public class ComponentSerialization { + ) + .apply(instance, MutableComponent::new) + ); + // Paper start - adventure; create separate codec for each locale + final Codec origCodec = codec; + codec = new Codec<>() { @@ -2375,9 +2375,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + }; + // Paper end - adventure; create separate codec for each locale - return Codec.either(Codec.either(Codec.STRING, ExtraCodecs.nonEmptyList(selfCodec.listOf())), codec).xmap((either) -> { - return either.map((either2) -> { - return either2.map(Component::literal, ComponentSerialization::createFromList); + return Codec.either(Codec.either(Codec.STRING, ExtraCodecs.nonEmptyList(selfCodec.listOf())), codec) + .xmap(either -> either.map(either2 -> either2.map(Component::literal, ComponentSerialization::createFromList), text -> (Component)text), text -> { + String string = text.tryCollapseToString(); diff --git a/src/main/java/net/minecraft/network/chat/ComponentUtils.java b/src/main/java/net/minecraft/network/chat/ComponentUtils.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/network/chat/ComponentUtils.java @@ -2393,7 +2393,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - adventure; pass actual vanilla component MutableComponent mutableComponent = text.getContents().resolve(source, sender, depth + 1); - for(Component component : text.getSiblings()) { + for (Component component : text.getSiblings()) { diff --git a/src/main/java/net/minecraft/network/chat/MessageSignature.java b/src/main/java/net/minecraft/network/chat/MessageSignature.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/network/chat/MessageSignature.java @@ -2406,12 +2406,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public static final Codec CODEC = ExtraCodecs.BASE64_STRING.xmap(MessageSignature::new, MessageSignature::bytes); public static final int BYTES = 256; - public MessageSignature { -- Preconditions.checkState(bs.length == 256, "Invalid message signature size"); -+ Preconditions.checkState(bytes.length == 256, "Invalid message signature size"); // Paper - decompile fix - } - - public static MessageSignature read(FriendlyByteBuf buf) { diff --git a/src/main/java/net/minecraft/network/chat/OutgoingChatMessage.java b/src/main/java/net/minecraft/network/chat/OutgoingChatMessage.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/network/chat/OutgoingChatMessage.java @@ -2427,10 +2421,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end + static OutgoingChatMessage create(PlayerChatMessage message) { - return (OutgoingChatMessage)(message.isSystem() ? new OutgoingChatMessage.Disguised(message.decoratedContent()) : new OutgoingChatMessage.Player(message)); - } + return (OutgoingChatMessage)(message.isSystem() + ? new OutgoingChatMessage.Disguised(message.decoratedContent()) @@ -0,0 +0,0 @@ public interface OutgoingChatMessage { - public static record Disguised(Component content) implements OutgoingChatMessage { + public static record Disguised(@Override Component content) implements OutgoingChatMessage { @Override public void sendToPlayer(ServerPlayer sender, boolean filterMaskEnabled, ChatType.Bound params) { - sender.connection.sendDisguisedChatMessage(this.content, params); @@ -2461,13 +2455,14 @@ diff --git a/src/main/java/net/minecraft/network/chat/PlayerChatMessage.java b/s index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/network/chat/PlayerChatMessage.java +++ b/src/main/java/net/minecraft/network/chat/PlayerChatMessage.java -@@ -0,0 +0,0 @@ import net.minecraft.Util; - import net.minecraft.util.SignatureUpdater; +@@ -0,0 +0,0 @@ import net.minecraft.util.SignatureUpdater; import net.minecraft.util.SignatureValidator; --public record PlayerChatMessage(SignedMessageLink link, @Nullable MessageSignature signature, SignedMessageBody signedBody, @Nullable Component unsignedContent, FilterMask filterMask) { -+// Paper start - adventure; support signed messages -+public record PlayerChatMessage(SignedMessageLink link, @Nullable MessageSignature signature, SignedMessageBody signedBody, @Nullable Component unsignedContent, FilterMask filterMask, @Nullable net.minecraft.network.chat.ChatDecorator.Result result) { + public record PlayerChatMessage( +- SignedMessageLink link, @Nullable MessageSignature signature, SignedMessageBody signedBody, @Nullable Component unsignedContent, FilterMask filterMask ++ SignedMessageLink link, @Nullable MessageSignature signature, SignedMessageBody signedBody, @Nullable Component unsignedContent, FilterMask filterMask, @Nullable net.minecraft.network.chat.ChatDecorator.Result result // Paper - adventure; support signed messages + ) { ++ // Paper start - adventure; support signed messages + public PlayerChatMessage(SignedMessageLink link, @Nullable MessageSignature signature, SignedMessageBody signedBody, @Nullable Component unsignedContent, FilterMask filterMask) { + this(link, signature, signedBody, unsignedContent, filterMask, null); + } @@ -2513,10 +2508,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return new AdventureView(); + } + // Paper end - adventure; support signed messages - public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec((instance) -> { - return instance.group(SignedMessageLink.CODEC.fieldOf("link").forGetter(PlayerChatMessage::link), MessageSignature.CODEC.optionalFieldOf("signature").forGetter((message) -> { - return Optional.ofNullable(message.signature); -@@ -0,0 +0,0 @@ public record PlayerChatMessage(SignedMessageLink link, @Nullable MessageSignatu + public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec( + instance -> instance.group( + SignedMessageLink.CODEC.fieldOf("link").forGetter(PlayerChatMessage::link), +@@ -0,0 +0,0 @@ public record PlayerChatMessage( } public PlayerChatMessage withUnsignedContent(Component unsignedContent) { diff --git a/patches/server/Allow-changing-the-EnderDragon-podium.patch b/patches/server/Allow-changing-the-EnderDragon-podium.patch index 9f8d828f9..ef570b122 100644 --- a/patches/server/Allow-changing-the-EnderDragon-podium.patch +++ b/patches/server/Allow-changing-the-EnderDragon-podium.patch @@ -62,11 +62,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonDeathPhase.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonDeathPhase.java @@ -0,0 +0,0 @@ public class DragonDeathPhase extends AbstractDragonPhaseInstance { - public void doServerTick() { - ++this.time; if (this.targetLocation == null) { -- BlockPos blockPos = this.dragon.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, EndPodiumFeature.getLocation(this.dragon.getFightOrigin())); -+ BlockPos blockPos = this.dragon.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, this.dragon.getPodium()); // Paper - Allow changing the EnderDragon podium + BlockPos blockPos = this.dragon + .level() +- .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, EndPodiumFeature.getLocation(this.dragon.getFightOrigin())); ++ .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, this.dragon.getPodium()); // Paper - Allow changing the EnderDragon podium this.targetLocation = Vec3.atBottomCenterOf(blockPos); } @@ -75,11 +75,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonHoldingPatternPhase.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonHoldingPatternPhase.java @@ -0,0 +0,0 @@ public class DragonHoldingPatternPhase extends AbstractDragonPhaseInstance { - - private void findNewTarget() { if (this.currentPath != null && this.currentPath.isDone()) { -- BlockPos blockPos = this.dragon.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, new BlockPos(EndPodiumFeature.getLocation(this.dragon.getFightOrigin()))); -+ BlockPos blockPos = this.dragon.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium()); // Paper - Allow changing the EnderDragon podium + BlockPos blockPos = this.dragon + .level() +- .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, new BlockPos(EndPodiumFeature.getLocation(this.dragon.getFightOrigin()))); ++ .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, new BlockPos(this.dragon.getPodium())); // Paper - Allow changing the EnderDragon podium int i = this.dragon.getDragonFight() == null ? 0 : this.dragon.getDragonFight().getCrystalsAlive(); if (this.dragon.getRandom().nextInt(i + 3) == 0) { this.dragon.getPhaseManager().setPhase(EnderDragonPhase.LANDING_APPROACH); @@ -88,12 +88,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingApproachPhase.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingApproachPhase.java @@ -0,0 +0,0 @@ public class DragonLandingApproachPhase extends AbstractDragonPhaseInstance { - private void findNewTarget() { - if (this.currentPath == null || this.currentPath.isDone()) { int i = this.dragon.findClosestNode(); -- BlockPos blockPos = this.dragon.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.dragon.getFightOrigin())); -+ BlockPos blockPos = this.dragon.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium()); // Paper - Allow changing the EnderDragon podium - Player player = this.dragon.level().getNearestPlayer(NEAR_EGG_TARGETING, this.dragon, (double)blockPos.getX(), (double)blockPos.getY(), (double)blockPos.getZ()); + BlockPos blockPos = this.dragon + .level() +- .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.dragon.getFightOrigin())); ++ .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium()); // Paper - Allow changing the EnderDragon podium + Player player = this.dragon.level().getNearestPlayer(NEAR_EGG_TARGETING, this.dragon, blockPos.getX(), blockPos.getY(), blockPos.getZ()); int j; if (player != null) { diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingPhase.java @@ -101,25 +101,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingPhase.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingPhase.java @@ -0,0 +0,0 @@ public class DragonLandingPhase extends AbstractDragonPhaseInstance { - @Override public void doServerTick() { if (this.targetLocation == null) { -- this.targetLocation = Vec3.atBottomCenterOf(this.dragon.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.dragon.getFightOrigin()))); -+ this.targetLocation = Vec3.atBottomCenterOf(this.dragon.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium())); // Paper - Allow changing the EnderDragon podium + this.targetLocation = Vec3.atBottomCenterOf( +- this.dragon.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.dragon.getFightOrigin())) ++ this.dragon.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium()) // Paper - Allow changing the EnderDragon podium + ); } - if (this.targetLocation.distanceToSqr(this.dragon.getX(), this.dragon.getY(), this.dragon.getZ()) < 1.0D) { diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonTakeoffPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonTakeoffPhase.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonTakeoffPhase.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonTakeoffPhase.java @@ -0,0 +0,0 @@ public class DragonTakeoffPhase extends AbstractDragonPhaseInstance { - @Override - public void doServerTick() { if (!this.firstTick && this.currentPath != null) { -- BlockPos blockPos = this.dragon.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.dragon.getFightOrigin())); -+ BlockPos blockPos = this.dragon.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium()); // Paper - Allow changing the EnderDragon podium - if (!blockPos.closerToCenterThan(this.dragon.position(), 10.0D)) { + BlockPos blockPos = this.dragon + .level() +- .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.dragon.getFightOrigin())); ++ .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium()); // Paper - Allow changing the EnderDragon podium + if (!blockPos.closerToCenterThan(this.dragon.position(), 10.0)) { this.dragon.getPhaseManager().setPhase(EnderDragonPhase.HOLDING_PATTERN); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java diff --git a/patches/server/Anti-Xray.patch b/patches/server/Anti-Xray.patch index a4f020580..c80d6dbd4 100644 --- a/patches/server/Anti-Xray.patch +++ b/patches/server/Anti-Xray.patch @@ -1009,13 +1009,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public static void extractChunkData(FriendlyByteBuf buf, LevelChunk chunk) { + int chunkSectionIndex = 0; // Paper - Anti-Xray - for(LevelChunkSection levelChunkSection : chunk.getSections()) { + for (LevelChunkSection levelChunkSection : chunk.getSections()) { - levelChunkSection.getBiomes().write(buf); + levelChunkSection.getBiomes().write(buf, null, chunkSectionIndex); // Paper - Anti-Xray + chunkSectionIndex++; // Paper - Anti-Xray } - } + diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java @@ -1031,7 +1031,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end this.heightmaps = new CompoundTag(); - for(Map.Entry entry : chunk.getHeightmaps()) { + for (Entry entry : chunk.getHeightmaps()) { @@ -0,0 +0,0 @@ public class ClientboundLevelChunkPacketData { } @@ -1047,7 +1047,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end this.blockEntitiesData = Lists.newArrayList(); - for(Map.Entry entry2 : chunk.getBlockEntities().entrySet()) { + for (Entry entry2 : chunk.getBlockEntities().entrySet()) { @@ -0,0 +0,0 @@ public class ClientboundLevelChunkPacketData { return byteBuf; } @@ -1058,14 +1058,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public static void extractChunkData(FriendlyByteBuf buf, LevelChunk chunk, com.destroystokyo.paper.antixray.ChunkPacketInfo chunkPacketInfo) { + int chunkSectionIndex = 0; + - for(LevelChunkSection levelChunkSection : chunk.getSections()) { + for (LevelChunkSection levelChunkSection : chunk.getSections()) { - levelChunkSection.write(buf); + levelChunkSection.write(buf, chunkPacketInfo, chunkSectionIndex); + chunkSectionIndex++; + // Paper end } - } + diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkWithLightPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkWithLightPacket.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkWithLightPacket.java @@ -1146,10 +1146,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 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)); +- handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), null, null)); + // Paper start - Anti-Xray + final boolean shouldModify = world.chunkPacketBlockController.shouldModify(handler.player, chunk); -+ handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), (BitSet)null, (BitSet)null, shouldModify)); ++ handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), null, null, shouldModify)); + // Paper end - Anti-Xray // Paper start - PlayerChunkLoadEvent if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) { @@ -1284,8 +1284,8 @@ 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 implements PaletteResize, PalettedContainer - return 0; - }; + private static final int MIN_PALETTE_BITS = 0; + private final PaletteResize dummyPaletteResize = (newSize, added) -> 0; public final IdMap registry; + private final T @org.jetbrains.annotations.Nullable [] presetValues; // Paper - Anti-Xray - Add preset values private volatile PalettedContainer.Data data; @@ -1308,20 +1308,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } public static Codec> codecRO(IdMap idList, Codec entryCodec, PalettedContainer.Strategy paletteProvider, T defaultValue) { - PalettedContainerRO.Unpacker> unpacker = (idListx, paletteProviderx, serialized) -> { -- return unpack(idListx, paletteProviderx, serialized).map((result) -> { -+ return unpack(idListx, paletteProviderx, serialized, defaultValue, null).map((result) -> { // Paper - Anti-Xray - Add preset values - return result; - }); - }; + PalettedContainerRO.Unpacker> unpacker = (idListx, paletteProviderx, serialized) -> unpack( +- idListx, paletteProviderx, serialized ++ idListx, paletteProviderx, serialized, defaultValue, null // Paper - Anti-Xray - Add preset values + ) + .map(result -> (PalettedContainerRO)result); + return codec(idList, entryCodec, paletteProvider, defaultValue, unpacker); @@ -0,0 +0,0 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - }); + ); } -- public PalettedContainer(IdMap idList, PalettedContainer.Strategy paletteProvider, PalettedContainer.Configuration dataProvider, BitStorage storage, List paletteEntries) { + // Paper start - Anti-Xray - Add preset values + @Deprecated @io.papermc.paper.annotation.DoNotUse public PalettedContainer(IdMap idList, PalettedContainer.Strategy paletteProvider, PalettedContainer.Configuration dataProvider, BitStorage storage, List paletteEntries) { this(idList, paletteProvider, dataProvider, storage, paletteEntries, null, null); } -+ public PalettedContainer(IdMap idList, PalettedContainer.Strategy paletteProvider, PalettedContainer.Configuration dataProvider, BitStorage storage, List paletteEntries, T defaultValue, T @org.jetbrains.annotations.Nullable [] presetValues) { + public PalettedContainer( + IdMap idList, + PalettedContainer.Strategy paletteProvider, + PalettedContainer.Configuration dataProvider, + BitStorage storage, +- List paletteEntries ++ List paletteEntries, T defaultValue, T @org.jetbrains.annotations.Nullable [] presetValues + ) { + this.presetValues = presetValues; this.registry = idList; this.strategy = paletteProvider; @@ -1369,7 +1375,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end this.strategy = paletteProvider; this.registry = idList; - this.data = this.createOrReuseData((PalettedContainer.Data)null, 0); + this.data = this.createOrReuseData(null, 0); @@ -0,0 +0,0 @@ public class PalettedContainer implements PaletteResize, PalettedContainer @Override public synchronized int onResize(int newBits, T object) { // Paper - synchronize @@ -1413,7 +1419,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } finally { this.release(); } - } + // Paper start - Anti-Xray; Add chunk packet info @@ -1435,14 +1440,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } finally { this.release(); } - } -- private static DataResult> unpack(IdMap idList, PalettedContainer.Strategy paletteProvider, PalettedContainerRO.PackedData serialized) { -+ private static DataResult> unpack(IdMap idList, PalettedContainer.Strategy paletteProvider, PalettedContainerRO.PackedData serialized, T defaultValue, T @org.jetbrains.annotations.Nullable [] presetValues) { // Paper - Anti-Xray - Add preset values + private static DataResult> unpack( +- IdMap idList, PalettedContainer.Strategy paletteProvider, PalettedContainerRO.PackedData serialized ++ IdMap idList, PalettedContainer.Strategy paletteProvider, PalettedContainerRO.PackedData serialized, T defaultValue, T @org.jetbrains.annotations.Nullable [] presetValues // Paper - Anti-Xray - Add preset values + ) { List list = serialized.paletteEntries(); int i = paletteProvider.size(); - int j = paletteProvider.calculateBitsForSerialization(idList, list.size()); @@ -0,0 +0,0 @@ public class PalettedContainer implements PaletteResize, PalettedContainer } } diff --git a/patches/server/Attempt-to-recalculate-regionfile-header-if-it-is-co.patch b/patches/server/Attempt-to-recalculate-regionfile-header-if-it-is-co.patch index b20c53dfd..a188298a8 100644 --- a/patches/server/Attempt-to-recalculate-regionfile-header-if-it-is-co.patch +++ b/patches/server/Attempt-to-recalculate-regionfile-header-if-it-is-co.patch @@ -772,6 +772,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public class RegionFileVersion { - private static final Int2ObjectMap VERSIONS = new Int2ObjectOpenHashMap<>(); + public static final Int2ObjectMap VERSIONS = new Int2ObjectOpenHashMap<>(); // Paper - private -> public - public static final RegionFileVersion VERSION_GZIP = register(new RegionFileVersion(1, (stream) -> { - return new FastBufferedInputStream(new GZIPInputStream(stream)); - }, (stream) -> { + public static final RegionFileVersion VERSION_GZIP = register( + new RegionFileVersion( + 1, stream -> new FastBufferedInputStream(new GZIPInputStream(stream)), stream -> new BufferedOutputStream(new GZIPOutputStream(stream)) diff --git a/patches/server/Avoid-Lazy-Initialization-for-Enum-Fields.patch b/patches/server/Avoid-Lazy-Initialization-for-Enum-Fields.patch index 63393b27b..927ce733e 100644 --- a/patches/server/Avoid-Lazy-Initialization-for-Enum-Fields.patch +++ b/patches/server/Avoid-Lazy-Initialization-for-Enum-Fields.patch @@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/com/mojang/math/OctahedralGroup.java @@ -0,0 +0,0 @@ public enum OctahedralGroup implements StringRepresentable { this.permutation = axisTransformation; - this.transformation = (new Matrix3f()).scaling(flipX ? -1.0F : 1.0F, flipY ? -1.0F : 1.0F, flipZ ? -1.0F : 1.0F); + this.transformation = new Matrix3f().scaling(flipX ? -1.0F : 1.0F, flipY ? -1.0F : 1.0F, flipZ ? -1.0F : 1.0F); this.transformation.mul(axisTransformation.transformation()); + this.initializeRotationDirections(); // Paper - Avoid Lazy Initialization for Enum Fields } diff --git a/patches/server/Build-system-changes.patch b/patches/server/Build-system-changes.patch index 59ba062a1..1eb663926 100644 --- a/patches/server/Build-system-changes.patch +++ b/patches/server/Build-system-changes.patch @@ -102,14 +102,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/packs/repository/ServerPacksSource.java +++ b/src/main/java/net/minecraft/server/packs/repository/ServerPacksSource.java @@ -0,0 +0,0 @@ public class ServerPacksSource extends BuiltInPackSource { - - @VisibleForTesting public static VanillaPackResources createVanillaPackSource() { -- return (new VanillaPackResourcesBuilder()).setMetadata(BUILT_IN_METADATA).exposeNamespace("minecraft").applyDevelopmentConfig().pushJarResources().build(); -+ return (new VanillaPackResourcesBuilder()).setMetadata(BUILT_IN_METADATA).exposeNamespace("minecraft", ResourceLocation.PAPER_NAMESPACE).applyDevelopmentConfig().pushJarResources().build(); // Paper - } - - @Override + return new VanillaPackResourcesBuilder() + .setMetadata(BUILT_IN_METADATA) +- .exposeNamespace("minecraft") ++ .exposeNamespace("minecraft", ResourceLocation.PAPER_NAMESPACE) // Paper + .applyDevelopmentConfig() + .pushJarResources() + .build(); diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java diff --git a/patches/server/CB-fixes.patch b/patches/server/CB-fixes.patch index c7146b5b4..2039980fb 100644 --- a/patches/server/CB-fixes.patch +++ b/patches/server/CB-fixes.patch @@ -65,14 +65,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private final RandomState randomState; private final LevelHeightAccessor heightAccessor; @@ -0,0 +0,0 @@ public class StructureCheck { - private final Long2ObjectMap> loadedChunks = new Long2ObjectOpenHashMap<>(); - private final Map featureChecks = new HashMap<>(); - -- public StructureCheck(ChunkScanAccess chunkIoWorker, RegistryAccess registryManager, StructureTemplateManager structureTemplateManager, ResourceKey worldKey, ChunkGenerator chunkGenerator, RandomState noiseConfig, LevelHeightAccessor world, BiomeSource biomeSource, long seed, DataFixer dataFixer) { -+ public StructureCheck(ChunkScanAccess chunkIoWorker, RegistryAccess registryManager, StructureTemplateManager structureTemplateManager, ResourceKey worldKey, ChunkGenerator chunkGenerator, RandomState noiseConfig, LevelHeightAccessor world, BiomeSource biomeSource, long seed, DataFixer dataFixer) { // Paper - fix missing CB diff - this.storageAccess = chunkIoWorker; - this.registryAccess = registryManager; - this.structureTemplateManager = structureTemplateManager; + ChunkScanAccess chunkIoWorker, + RegistryAccess registryManager, + StructureTemplateManager structureTemplateManager, +- ResourceKey worldKey, ++ ResourceKey worldKey, // Paper - fix missing CB diff + ChunkGenerator chunkGenerator, + RandomState noiseConfig, + LevelHeightAccessor world, diff --git a/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java b/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java diff --git a/patches/server/Call-BlockGrowEvent-for-missing-blocks.patch b/patches/server/Call-BlockGrowEvent-for-missing-blocks.patch index ade8a18dd..e5b08f1af 100644 --- a/patches/server/Call-BlockGrowEvent-for-missing-blocks.patch +++ b/patches/server/Call-BlockGrowEvent-for-missing-blocks.patch @@ -28,11 +28,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (!this.isReadyToHatch(state)) { + // Paper start + if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, pos, state.setValue(HATCH, Integer.valueOf(this.getHatchLevel(state) + 1)), 2)) { -+ rescheduleTick(world, pos); ++ this.rescheduleTick(world, pos); + return; + } + // Paper end - world.playSound((Player)null, pos, SoundEvents.SNIFFER_EGG_CRACK, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); + world.playSound(null, pos, SoundEvents.SNIFFER_EGG_CRACK, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); - world.setBlock(pos, state.setValue(HATCH, Integer.valueOf(this.getHatchLevel(state) + 1)), 2); } else { // Paper start - Call BlockFadeEvent diff --git a/patches/server/Call-BlockPhysicsEvent-more-often.patch b/patches/server/Call-BlockPhysicsEvent-more-often.patch index b6308b9ce..d1ca93ae6 100644 --- a/patches/server/Call-BlockPhysicsEvent-more-often.patch +++ b/patches/server/Call-BlockPhysicsEvent-more-often.patch @@ -28,5 +28,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end - Call BlockPhysicsEvent if (this.idx < NeighborUpdater.UPDATE_ORDER.length && NeighborUpdater.UPDATE_ORDER[this.idx] == this.skipDirection) { - ++this.idx; + this.idx++; } diff --git a/patches/server/Catch-JsonParseException-in-entity-and-block-entity-.patch b/patches/server/Catch-JsonParseException-in-entity-and-block-entity-.patch index 8e3244f36..ce67932c5 100644 --- a/patches/server/Catch-JsonParseException-in-entity-and-block-entity-.patch +++ b/patches/server/Catch-JsonParseException-in-entity-and-block-entity-.patch @@ -99,5 +99,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - this.name = Component.Serializer.fromJson(nbt.getString("CustomName")); + this.name = io.papermc.paper.util.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException } - } + diff --git a/patches/server/Collision-optimisations.patch b/patches/server/Collision-optimisations.patch index e8534a4e2..2cc4c0420 100644 --- a/patches/server/Collision-optimisations.patch +++ b/patches/server/Collision-optimisations.patch @@ -2470,14 +2470,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/level/BlockCollisions.java +++ b/src/main/java/net/minecraft/world/level/BlockCollisions.java @@ -0,0 +0,0 @@ public class BlockCollisions extends AbstractIterator { - - VoxelShape voxelShape = blockState.getCollisionShape(this.collisionGetter, this.pos, this.context); - if (voxelShape == Shapes.block()) { -- if (!this.box.intersects((double)i, (double)j, (double)k, (double)i + 1.0D, (double)j + 1.0D, (double)k + 1.0D)) { -+ if (!io.papermc.paper.util.CollisionUtil.voxelShapeIntersect(this.box, (double)i, (double)j, (double)k, (double)i + 1.0D, (double)j + 1.0D, (double)k + 1.0D)) { // Paper - keep vanilla behavior for voxelshape intersection - See comment in CollisionUtil - continue; - } - + // Paper end + VoxelShape voxelShape = blockState.getCollisionShape(this.collisionGetter, this.pos, this.context); + if (voxelShape == Shapes.block()) { +- if (this.box.intersects(i, j, k, i + 1.0, j + 1.0, k + 1.0)) { ++ if (io.papermc.paper.util.CollisionUtil.voxelShapeIntersect(this.box, i, j, k, i + 1.0, j + 1.0, k + 1.0)) { // Paper - keep vanilla behavior for voxelshape intersection - See comment in CollisionUtil + return this.resultProvider.apply(this.pos, voxelShape.move(i, j, k)); + } + } else { diff --git a/src/main/java/net/minecraft/world/level/ClipContext.java b/src/main/java/net/minecraft/world/level/ClipContext.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/ClipContext.java @@ -2508,7 +2508,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - optimise collisions + default boolean noCollision(AABB box) { - return this.noCollision((Entity)null, box); + return this.noCollision(null, box); } diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/main/java/net/minecraft/world/level/EntityGetter.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -2522,8 +2522,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (shape.isEmpty()) { - return true; - } else { -- for(Entity entity : this.getEntities(except, shape.bounds())) { -- if (!entity.isRemoved() && entity.blocksBuilding && (except == null || !entity.isPassengerOfSameVehicle(except)) && Shapes.joinIsNotEmpty(shape, Shapes.create(entity.getBoundingBox()), BooleanOp.AND)) { +- for (Entity entity : this.getEntities(except, shape.bounds())) { +- if (!entity.isRemoved() +- && entity.blocksBuilding +- && (except == null || !entity.isPassengerOfSameVehicle(except)) +- && Shapes.joinIsNotEmpty(shape, Shapes.create(entity.getBoundingBox()), BooleanOp.AND)) { - return false; + return false; + } @@ -2561,7 +2564,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } default List getEntityCollisions(@Nullable Entity entity, AABB box) { -- if (box.getSize() < 1.0E-7D) { +- if (box.getSize() < 1.0E-7) { - return List.of(); + // Paper start - optimise collisions + // first behavior change is to correctly check for empty AABB @@ -2580,21 +2583,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + entities = this.getEntities(entity, box, null); } else { - Predicate predicate = entity == null ? EntitySelector.CAN_BE_COLLIDED_WITH : EntitySelector.NO_SPECTATORS.and(entity::canCollideWith); -- List list = this.getEntities(entity, box.inflate(1.0E-7D), predicate); +- List list = this.getEntities(entity, box.inflate(1.0E-7), predicate); - if (list.isEmpty()) { - return List.of(); - } else { -- ImmutableList.Builder builder = ImmutableList.builderWithExpectedSize(list.size()); +- Builder builder = ImmutableList.builderWithExpectedSize(list.size()); - -- for(Entity entity2 : list) { +- for (Entity entity2 : list) { - builder.add(Shapes.create(entity2.getBoundingBox())); - } + entities = this.getHardCollidingEntities(entity, box, null); + } ++ ++ final List ret = new java.util.ArrayList<>(Math.min(25, entities.size())); - return builder.build(); -+ final List ret = new java.util.ArrayList<>(Math.min(25, entities.size())); -+ + for (int i = 0, len = entities.size(); i < len; ++i) { + final Entity otherEntity = entities.get(i); + @@ -3234,23 +3237,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end + public AABB(BlockPos pos) { - this((double)pos.getX(), (double)pos.getY(), (double)pos.getZ(), (double)(pos.getX() + 1), (double)(pos.getY() + 1), (double)(pos.getZ() + 1)); + this(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1); } @@ -0,0 +0,0 @@ public class AABB { } @Nullable -- private static Direction getDirection(AABB box, Vec3 intersectingVector, double[] traceDistanceResult, @Nullable Direction approachDirection, double deltaX, double deltaY, double deltaZ) { -+ public static Direction getDirection(AABB box, Vec3 intersectingVector, double[] traceDistanceResult, @Nullable Direction approachDirection, double deltaX, double deltaY, double deltaZ) { // Paper - optimise collisions - public - if (deltaX > 1.0E-7D) { - approachDirection = clipPoint(traceDistanceResult, approachDirection, deltaX, deltaY, deltaZ, box.minX, box.minY, box.maxY, box.minZ, box.maxZ, Direction.WEST, intersectingVector.x, intersectingVector.y, intersectingVector.z); - } else if (deltaX < -1.0E-7D) { +- private static Direction getDirection( ++ public static Direction getDirection( // Paper - optimise collisions - public + AABB box, Vec3 intersectingVector, double[] traceDistanceResult, @Nullable Direction approachDirection, double deltaX, double deltaY, double deltaZ + ) { + if (deltaX > 1.0E-7) { diff --git a/src/main/java/net/minecraft/world/phys/shapes/ArrayVoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/ArrayVoxelShape.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/phys/shapes/ArrayVoxelShape.java +++ b/src/main/java/net/minecraft/world/phys/shapes/ArrayVoxelShape.java @@ -0,0 +0,0 @@ public class ArrayVoxelShape extends VoxelShape { - this(shape, (DoubleList)DoubleArrayList.wrap(Arrays.copyOf(xPoints, shape.getXSize() + 1)), (DoubleList)DoubleArrayList.wrap(Arrays.copyOf(yPoints, shape.getYSize() + 1)), (DoubleList)DoubleArrayList.wrap(Arrays.copyOf(zPoints, shape.getZSize() + 1))); + ); } - ArrayVoxelShape(DiscreteVoxelShape shape, DoubleList xPoints, DoubleList yPoints, DoubleList zPoints) { @@ -3259,8 +3262,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 int i = shape.getXSize() + 1; int j = shape.getYSize() + 1; @@ -0,0 +0,0 @@ public class ArrayVoxelShape extends VoxelShape { - } else { - throw (IllegalArgumentException)Util.pauseInIde(new IllegalArgumentException("Lengths of point arrays must be consistent with the size of the VoxelShape.")); + new IllegalArgumentException("Lengths of point arrays must be consistent with the size of the VoxelShape.") + ); } + this.initCache(); // Paper - optimise collisions } @@ -3305,11 +3308,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - optimise collisions + // called with the shape of a VoxelShape, so we can expect the cache to exist + final io.papermc.paper.util.collisions.CachedShapeData cache = voxelSet.getOrCreateCachedShapeData(); -+ + +- for (int i = 0; i < bitSetDiscreteVoxelShape.ySize; i++) { +- for (int j = 0; j < bitSetDiscreteVoxelShape.xSize; j++) { +- int k = -1; + final int sizeX = cache.sizeX(); + final int sizeY = cache.sizeY(); + final int sizeZ = cache.sizeZ(); -+ + +- for (int l = 0; l <= bitSetDiscreteVoxelShape.zSize; l++) { +- if (bitSetDiscreteVoxelShape.isFullWide(j, i, l)) { +- if (coalesce) { +- if (k == -1) { +- k = l; +- } +- } else { +- callback.consume(j, i, l, j + 1, i + 1, l + 1); + int indexX; + int indexY = 0; + int indexZ; @@ -3339,21 +3353,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } else { + // same notes about loop order as the above + // this branch is actually important to optimise, as it affects uncached toAabbs() (which affects optimize()) - -- for(int i = 0; i < bitSetDiscreteVoxelShape.ySize; ++i) { -- for(int j = 0; j < bitSetDiscreteVoxelShape.xSize; ++j) { -- int k = -1; ++ + // only clone when we may write to it + bitset = bitset.clone(); - -- for(int l = 0; l <= bitSetDiscreteVoxelShape.zSize; ++l) { -- if (bitSetDiscreteVoxelShape.isFullWide(j, i, l)) { -- if (coalesce) { -- if (k == -1) { -- k = l; -- } -- } else { -- callback.consume(j, i, l, j + 1, i + 1, l + 1); ++ + for (int y = 0; y < sizeY; ++y, indexY += incY) { + indexX = indexY; + for (int x = 0; x < sizeX; ++x, indexX += incX) { @@ -3368,17 +3371,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - int n = i; - bitSetDiscreteVoxelShape.clearZStrip(k, l, j, i); - -- while(bitSetDiscreteVoxelShape.isZStripFull(k, l, m + 1, i)) { +- while (bitSetDiscreteVoxelShape.isZStripFull(k, l, m + 1, i)) { - bitSetDiscreteVoxelShape.clearZStrip(k, l, m + 1, i); -- ++m; +- m++; + + int lastSetZ = io.papermc.paper.util.collisions.FlatBitsetUtil.firstClear(bitset, firstSetZ, endIndex); + if (lastSetZ == -1) { + lastSetZ = endIndex; } -- while(bitSetDiscreteVoxelShape.isXZRectangleFull(j, m + 1, k, l, n + 1)) { -- for(int o = j; o <= m; ++o) { +- while (bitSetDiscreteVoxelShape.isXZRectangleFull(j, m + 1, k, l, n + 1)) { +- for (int o = j; o <= m; o++) { - bitSetDiscreteVoxelShape.clearZStrip(k, l, o, n + 1); + io.papermc.paper.util.collisions.FlatBitsetUtil.clearRange(bitset, firstSetZ, lastSetZ); + @@ -3408,7 +3411,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } } -- ++n; +- n++; + ++endY; + + // passed, so we can clear it @@ -3426,7 +3429,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } } -- + // Paper end - optimise collisions } @@ -3539,8 +3541,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java +++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java @@ -0,0 +0,0 @@ public final class Shapes { - public static final double EPSILON = 1.0E-7D; - public static final double BIG_EPSILON = 1.0E-6D; + public static final double EPSILON = 1.0E-7; + public static final double BIG_EPSILON = 1.0E-6; private static final VoxelShape BLOCK = Util.make(() -> { - DiscreteVoxelShape discreteVoxelShape = new BitSetDiscreteVoxelShape(1, 1, 1); - discreteVoxelShape.fill(0, 0, 0); @@ -3555,8 +3557,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + ); + // Paper end - optimise collisions - force arrayvoxelshape }); - public static final VoxelShape INFINITY = box(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); - private static final VoxelShape EMPTY = new ArrayVoxelShape(new BitSetDiscreteVoxelShape(0, 0, 0), (DoubleList)(new DoubleArrayList(new double[]{0.0D})), (DoubleList)(new DoubleArrayList(new double[]{0.0D})), (DoubleList)(new DoubleArrayList(new double[]{0.0D}))); + public static final VoxelShape INFINITY = box( + Double.NEGATIVE_INFINITY, +@@ -0,0 +0,0 @@ public final class Shapes { + new DoubleArrayList(new double[]{0.0}) + ); + // Paper start - optimise collisions - force arrayvoxelshape + private static final DoubleArrayList[] PARTS_BY_BITS = new DoubleArrayList[] { @@ -3588,13 +3593,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public final class Shapes { public static VoxelShape create(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { - if (!(maxX - minX < 1.0E-7D) && !(maxY - minY < 1.0E-7D) && !(maxZ - minZ < 1.0E-7D)) { + if (!(maxX - minX < 1.0E-7) && !(maxY - minY < 1.0E-7) && !(maxZ - minZ < 1.0E-7)) { - int i = findBits(minX, maxX); - int j = findBits(minY, maxY); - int k = findBits(minZ, maxZ); -- if (i >= 0 && j >= 0 && k >= 0) { -- if (i == 0 && j == 0 && k == 0) { -- return block(); +- if (i < 0 || j < 0 || k < 0) { +- return new ArrayVoxelShape( +- BLOCK.shape, +- DoubleArrayList.wrap(new double[]{minX, maxX}), +- DoubleArrayList.wrap(new double[]{minY, maxY}), +- DoubleArrayList.wrap(new double[]{minZ, maxZ}) +- ); +- } else if (i == 0 && j == 0 && k == 0) { +- return block(); + // Paper start - optimise collisions + // force ArrayVoxelShape in every case + final int bitsX = findBits(minX, maxX); @@ -3603,12 +3614,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (bitsX >= 0 && bitsY >= 0 && bitsZ >= 0) { + if (bitsX == 0 && bitsY == 0 && bitsZ == 0) { + return BLOCK; - } else { -- int l = 1 << i; -- int m = 1 << j; -- int n = 1 << k; -- BitSetDiscreteVoxelShape bitSetDiscreteVoxelShape = BitSetDiscreteVoxelShape.withFilledBounds(l, m, n, (int)Math.round(minX * (double)l), (int)Math.round(minY * (double)m), (int)Math.round(minZ * (double)n), (int)Math.round(maxX * (double)l), (int)Math.round(maxY * (double)m), (int)Math.round(maxZ * (double)n)); -- return new CubeVoxelShape(bitSetDiscreteVoxelShape); ++ } else { + final int sizeX = 1 << bitsX; + final int sizeY = 1 << bitsY; + final int sizeZ = 1 << bitsZ; @@ -3623,15 +3629,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + PARTS_BY_BITS[bitsY], + PARTS_BY_BITS[bitsZ] + ); - } ++ } } else { -- return new ArrayVoxelShape(BLOCK.shape, (DoubleList)DoubleArrayList.wrap(new double[]{minX, maxX}), (DoubleList)DoubleArrayList.wrap(new double[]{minY, maxY}), (DoubleList)DoubleArrayList.wrap(new double[]{minZ, maxZ})); +- int l = 1 << i; +- int m = 1 << j; +- int n = 1 << k; +- BitSetDiscreteVoxelShape bitSetDiscreteVoxelShape = BitSetDiscreteVoxelShape.withFilledBounds( +- l, +- m, +- n, +- (int)Math.round(minX * l), +- (int)Math.round(minY * m), +- (int)Math.round(minZ * n), +- (int)Math.round(maxX * l), +- (int)Math.round(maxY * m), +- (int)Math.round(maxZ * n) + return new ArrayVoxelShape( + BLOCK.shape, + minX == 0.0 && maxX == 1.0 ? io.papermc.paper.util.CollisionUtil.ZERO_ONE : DoubleArrayList.wrap(new double[] { minX, maxX }), + minY == 0.0 && maxY == 1.0 ? io.papermc.paper.util.CollisionUtil.ZERO_ONE : DoubleArrayList.wrap(new double[] { minY, maxY }), + minZ == 0.0 && maxZ == 1.0 ? io.papermc.paper.util.CollisionUtil.ZERO_ONE : DoubleArrayList.wrap(new double[] { minZ, maxZ }) -+ ); + ); +- return new CubeVoxelShape(bitSetDiscreteVoxelShape); } + // Paper end - optimise collisions } else { @@ -3699,9 +3718,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - } else { - IndexMerger indexMerger = createIndexMerger(1, one.getCoords(Direction.Axis.X), two.getCoords(Direction.Axis.X), bl, bl2); - IndexMerger indexMerger2 = createIndexMerger(indexMerger.size() - 1, one.getCoords(Direction.Axis.Y), two.getCoords(Direction.Axis.Y), bl, bl2); -- IndexMerger indexMerger3 = createIndexMerger((indexMerger.size() - 1) * (indexMerger2.size() - 1), one.getCoords(Direction.Axis.Z), two.getCoords(Direction.Axis.Z), bl, bl2); -- BitSetDiscreteVoxelShape bitSetDiscreteVoxelShape = BitSetDiscreteVoxelShape.join(one.shape, two.shape, indexMerger, indexMerger2, indexMerger3, function); -- return (VoxelShape)(indexMerger instanceof DiscreteCubeMerger && indexMerger2 instanceof DiscreteCubeMerger && indexMerger3 instanceof DiscreteCubeMerger ? new CubeVoxelShape(bitSetDiscreteVoxelShape) : new ArrayVoxelShape(bitSetDiscreteVoxelShape, indexMerger.getList(), indexMerger2.getList(), indexMerger3.getList())); +- IndexMerger indexMerger3 = createIndexMerger( +- (indexMerger.size() - 1) * (indexMerger2.size() - 1), one.getCoords(Direction.Axis.Z), two.getCoords(Direction.Axis.Z), bl, bl2 +- ); +- BitSetDiscreteVoxelShape bitSetDiscreteVoxelShape = BitSetDiscreteVoxelShape.join( +- one.shape, two.shape, indexMerger, indexMerger2, indexMerger3, function +- ); +- return (VoxelShape)(indexMerger instanceof DiscreteCubeMerger +- && indexMerger2 instanceof DiscreteCubeMerger +- && indexMerger3 instanceof DiscreteCubeMerger +- ? new CubeVoxelShape(bitSetDiscreteVoxelShape) +- : new ArrayVoxelShape(bitSetDiscreteVoxelShape, indexMerger.getList(), indexMerger2.getList(), indexMerger3.getList())); - } - } + return io.papermc.paper.util.CollisionUtil.joinUnoptimized(one, two, function); // Paper - optimise collisions @@ -3720,19 +3747,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - boolean bl3 = predicate.apply(true, false); - boolean bl4 = predicate.apply(false, true); - -- for(Direction.Axis axis : AxisCycle.AXIS_VALUES) { -- if (shape1.max(axis) < shape2.min(axis) - 1.0E-7D) { +- for (Direction.Axis axis : AxisCycle.AXIS_VALUES) { +- if (shape1.max(axis) < shape2.min(axis) - 1.0E-7) { - return bl3 || bl4; - } - -- if (shape2.max(axis) < shape1.min(axis) - 1.0E-7D) { +- if (shape2.max(axis) < shape1.min(axis) - 1.0E-7) { - return bl3 || bl4; - } - } - - IndexMerger indexMerger = createIndexMerger(1, shape1.getCoords(Direction.Axis.X), shape2.getCoords(Direction.Axis.X), bl3, bl4); -- IndexMerger indexMerger2 = createIndexMerger(indexMerger.size() - 1, shape1.getCoords(Direction.Axis.Y), shape2.getCoords(Direction.Axis.Y), bl3, bl4); -- IndexMerger indexMerger3 = createIndexMerger((indexMerger.size() - 1) * (indexMerger2.size() - 1), shape1.getCoords(Direction.Axis.Z), shape2.getCoords(Direction.Axis.Z), bl3, bl4); +- IndexMerger indexMerger2 = createIndexMerger( +- indexMerger.size() - 1, shape1.getCoords(Direction.Axis.Y), shape2.getCoords(Direction.Axis.Y), bl3, bl4 +- ); +- IndexMerger indexMerger3 = createIndexMerger( +- (indexMerger.size() - 1) * (indexMerger2.size() - 1), shape1.getCoords(Direction.Axis.Z), shape2.getCoords(Direction.Axis.Z), bl3, bl4 +- ); - return joinIsNotEmpty(indexMerger, indexMerger2, indexMerger3, shape1.shape, shape2.shape, predicate); - } - } else { @@ -3742,7 +3773,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return io.papermc.paper.util.CollisionUtil.isJoinNonEmpty(shape1, shape2, predicate); // Paper - optimise collisions } - private static boolean joinIsNotEmpty(IndexMerger mergedX, IndexMerger mergedY, IndexMerger mergedZ, DiscreteVoxelShape shape1, DiscreteVoxelShape shape2, BooleanOp predicate) { + private static boolean joinIsNotEmpty( @@ -0,0 +0,0 @@ public final class Shapes { } @@ -3758,6 +3789,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + if (shape.isEmpty() | neighbor.isEmpty()) { ++ return false; ++ } ++ ++ // we optimise getOpposite, so we can use it ++ // secondly, use our cache to retrieve sliced shape ++ final VoxelShape newFirst = shape.getFaceShapeClamped(direction); ++ if (newFirst.isEmpty()) { return false; - } else { - Direction.Axis axis = direction.getAxis(); @@ -3765,15 +3803,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - VoxelShape voxelShape = axisDirection == Direction.AxisDirection.POSITIVE ? shape : neighbor; - VoxelShape voxelShape2 = axisDirection == Direction.AxisDirection.POSITIVE ? neighbor : shape; - BooleanOp booleanOp = axisDirection == Direction.AxisDirection.POSITIVE ? BooleanOp.ONLY_FIRST : BooleanOp.ONLY_SECOND; -- return DoubleMath.fuzzyEquals(voxelShape.max(axis), 1.0D, 1.0E-7D) && DoubleMath.fuzzyEquals(voxelShape2.min(axis), 0.0D, 1.0E-7D) && !joinIsNotEmpty(new SliceShape(voxelShape, axis, voxelShape.shape.getSize(axis) - 1), new SliceShape(voxelShape2, axis, 0), booleanOp); +- return DoubleMath.fuzzyEquals(voxelShape.max(axis), 1.0, 1.0E-7) +- && DoubleMath.fuzzyEquals(voxelShape2.min(axis), 0.0, 1.0E-7) +- && !joinIsNotEmpty(new SliceShape(voxelShape, axis, voxelShape.shape.getSize(axis) - 1), new SliceShape(voxelShape2, axis, 0), booleanOp); } -+ -+ // we optimise getOpposite, so we can use it -+ // secondly, use our cache to retrieve sliced shape -+ final VoxelShape newFirst = shape.getFaceShapeClamped(direction); -+ if (newFirst.isEmpty()) { -+ return false; -+ } + final VoxelShape newSecond = neighbor.getFaceShapeClamped(direction.getOpposite()); + if (newSecond.isEmpty()) { + return false; @@ -3791,10 +3824,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - boolean bl; - int i; - if (direction.getAxisDirection() == Direction.AxisDirection.POSITIVE) { -- bl = DoubleMath.fuzzyEquals(shape.max(axis), 1.0D, 1.0E-7D); +- bl = DoubleMath.fuzzyEquals(shape.max(axis), 1.0, 1.0E-7); - i = shape.shape.getSize(axis) - 1; - } else { -- bl = DoubleMath.fuzzyEquals(shape.min(axis), 0.0D, 1.0E-7D); +- bl = DoubleMath.fuzzyEquals(shape.min(axis), 0.0, 1.0E-7); - i = 0; - } + return shape.getFaceShapeClamped(direction); // Paper - optimise collisions @@ -3828,7 +3861,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - Direction.AxisDirection axisDirection = direction.getAxisDirection(); - VoxelShape voxelShape = axisDirection == Direction.AxisDirection.POSITIVE ? one : two; - VoxelShape voxelShape2 = axisDirection == Direction.AxisDirection.POSITIVE ? two : one; -- if (!DoubleMath.fuzzyEquals(voxelShape.max(axis), 1.0D, 1.0E-7D)) { +- if (!DoubleMath.fuzzyEquals(voxelShape.max(axis), 1.0, 1.0E-7)) { - voxelShape = empty(); - } + // Paper start - optimise collisions @@ -3837,14 +3870,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return true; + } -- if (!DoubleMath.fuzzyEquals(voxelShape2.min(axis), 0.0D, 1.0E-7D)) { +- if (!DoubleMath.fuzzyEquals(voxelShape2.min(axis), 0.0, 1.0E-7)) { - voxelShape2 = empty(); - } + if (one.isEmpty() & two.isEmpty()) { + return false; + } -- return !joinIsNotEmpty(block(), joinUnoptimized(new SliceShape(voxelShape, axis, voxelShape.shape.getSize(axis) - 1), new SliceShape(voxelShape2, axis, 0), BooleanOp.OR), BooleanOp.ONLY_FIRST); +- return !joinIsNotEmpty( +- block(), +- joinUnoptimized(new SliceShape(voxelShape, axis, voxelShape.shape.getSize(axis) - 1), new SliceShape(voxelShape2, axis, 0), BooleanOp.OR), +- BooleanOp.ONLY_FIRST +- ); - } else { + // we optimise getOpposite, so we can use it + // secondly, use our cache to retrieve sliced shape @@ -3876,17 +3913,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } public static boolean faceShapeOccludes(VoxelShape one, VoxelShape two) { -- if (one != block() && two != block()) { -- if (one.isEmpty() && two.isEmpty()) { -- return false; -- } else { -- return !joinIsNotEmpty(block(), joinUnoptimized(one, two, BooleanOp.OR), BooleanOp.ONLY_FIRST); -- } -- } else { +- return one == block() +- || two == block() +- || (!one.isEmpty() || !two.isEmpty()) && !joinIsNotEmpty(block(), joinUnoptimized(one, two, BooleanOp.OR), BooleanOp.ONLY_FIRST); + // Paper start - optimise collisions + if (one.occludesFullBlockIfCached() || two.occludesFullBlockIfCached()) { - return true; - } ++ return true; ++ } + + final boolean s1Empty = one.isEmpty(); + final boolean s2Empty = two.isEmpty(); @@ -3937,7 +3970,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + private double offsetX; + private double offsetY; + private double offsetZ; -+ private AABB singleAABBRepresentation; ++ @Nullable private AABB singleAABBRepresentation; + private double[] rootCoordinatesX; + private double[] rootCoordinatesY; + private double[] rootCoordinatesZ; @@ -4335,15 +4368,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - if (this.isEmpty()) { - throw (UnsupportedOperationException)Util.pauseInIde(new UnsupportedOperationException("No bounds for empty shape.")); - } else { -- return new AABB(this.min(Direction.Axis.X), this.min(Direction.Axis.Y), this.min(Direction.Axis.Z), this.max(Direction.Axis.X), this.max(Direction.Axis.Y), this.max(Direction.Axis.Z)); +- return new AABB( +- this.min(Direction.Axis.X), +- this.min(Direction.Axis.Y), +- this.min(Direction.Axis.Z), +- this.max(Direction.Axis.X), +- this.max(Direction.Axis.Y), +- this.max(Direction.Axis.Z) +- ); + // Paper start - optimise collisions + if (this.isEmpty) { + throw Util.pauseInIde(new UnsupportedOperationException("No bounds for empty shape.")); - } ++ } + AABB cached = this.cachedBounds; + if (cached != null) { + return cached; -+ } + } + + final io.papermc.paper.util.collisions.CachedShapeData shapeData = this.cachedShapeData; + @@ -4378,26 +4418,32 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public boolean isEmpty() { - return this.shape.isEmpty(); + return this.isEmpty; // Paper - optimise collisions - } - ++ } ++ + // Paper start - optimise collisions + private static DoubleList offsetList(final DoubleList src, final double by) { + if (src instanceof OffsetDoubleList offsetDoubleList) { + return new OffsetDoubleList(offsetDoubleList.delegate, by + offsetDoubleList.offset); + } + return new OffsetDoubleList(src, by); -+ } + } + // Paper end - optimise collisions -+ + public VoxelShape move(double x, double y, double z) { -- return (VoxelShape)(this.isEmpty() ? Shapes.empty() : new ArrayVoxelShape(this.shape, (DoubleList)(new OffsetDoubleList(this.getCoords(Direction.Axis.X), x)), (DoubleList)(new OffsetDoubleList(this.getCoords(Direction.Axis.Y), y)), (DoubleList)(new OffsetDoubleList(this.getCoords(Direction.Axis.Z), z)))); +- return (VoxelShape)(this.isEmpty() +- ? Shapes.empty() +- : new ArrayVoxelShape( + // Paper start - optimise collisions + if (this.isEmpty) { + return Shapes.empty(); + } + + final ArrayVoxelShape ret = new ArrayVoxelShape( -+ this.shape, + this.shape, +- new OffsetDoubleList(this.getCoords(Direction.Axis.X), x), +- new OffsetDoubleList(this.getCoords(Direction.Axis.Y), y), +- new OffsetDoubleList(this.getCoords(Direction.Axis.Z), z) +- )); + offsetList(this.getCoords(Direction.Axis.X), x), + offsetList(this.getCoords(Direction.Axis.Y), y), + offsetList(this.getCoords(Direction.Axis.Z), z) @@ -4414,9 +4460,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public VoxelShape optimize() { - VoxelShape[] voxelShapes = new VoxelShape[]{Shapes.empty()}; -- this.forAllBoxes((minX, minY, minZ, maxX, maxY, maxZ) -> { -- voxelShapes[0] = Shapes.joinUnoptimized(voxelShapes[0], Shapes.box(minX, minY, minZ, maxX, maxY, maxZ), BooleanOp.OR); -- }); +- this.forAllBoxes( +- (minX, minY, minZ, maxX, maxY, maxZ) -> voxelShapes[0] = Shapes.joinUnoptimized( +- voxelShapes[0], Shapes.box(minX, minY, minZ, maxX, maxY, maxZ), BooleanOp.OR +- ) +- ); - return voxelShapes[0]; + // Paper start - optimise collisions + // Optimise merge strategy to increase the number of simple joins, and additionally forward the toAabbs cache @@ -4487,7 +4535,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public void forAllEdges(Shapes.DoubleLineConsumer consumer) { @@ -0,0 +0,0 @@ public abstract class VoxelShape { - }, true); + ); } + // Paper start - optimise collisions @@ -4510,9 +4558,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public List toAabbs() { - List list = Lists.newArrayList(); -- this.forAllBoxes((x1, y1, z1, x2, y2, z2) -> { -- list.add(new AABB(x1, y1, z1, x2, y2, z2)); -- }); +- this.forAllBoxes((x1, y1, z1, x2, y2, z2) -> list.add(new AABB(x1, y1, z1, x2, y2, z2))); - return list; + // Paper start - optimise collisions + io.papermc.paper.util.collisions.CachedToAABBs cachedToAABBs = this.cachedToAABBs; @@ -4536,7 +4582,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public double min(Direction.Axis axis, double from, double to) { @@ -0,0 +0,0 @@ public abstract class VoxelShape { - }) - 1; + return Mth.binarySearch(0, this.shape.getSize(axis) + 1, i -> coord < this.get(axis, i)) - 1; } + // Paper start - optimise collisions @@ -4568,11 +4614,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return null; - } else { - Vec3 vec3 = end.subtract(start); -- if (vec3.lengthSqr() < 1.0E-7D) { +- if (vec3.lengthSqr() < 1.0E-7) { - return null; - } else { -- Vec3 vec32 = start.add(vec3.scale(0.001D)); -- return this.shape.isFullWide(this.findIndex(Direction.Axis.X, vec32.x - (double)pos.getX()), this.findIndex(Direction.Axis.Y, vec32.y - (double)pos.getY()), this.findIndex(Direction.Axis.Z, vec32.z - (double)pos.getZ())) ? new BlockHitResult(vec32, Direction.getNearest(vec3.x, vec3.y, vec3.z).getOpposite(), pos, true) : AABB.clip(this.toAabbs(), start, end, pos); +- Vec3 vec32 = start.add(vec3.scale(0.001)); +- return this.shape +- .isFullWide( +- this.findIndex(Direction.Axis.X, vec32.x - pos.getX()), +- this.findIndex(Direction.Axis.Y, vec32.y - pos.getY()), +- this.findIndex(Direction.Axis.Z, vec32.z - pos.getZ()) +- ) +- ? new BlockHitResult(vec32, Direction.getNearest(vec3.x, vec3.y, vec3.z).getOpposite(), pos, true) +- : AABB.clip(this.toAabbs(), start, end, pos); + } + + final Vec3 directionOpposite = end.subtract(start); @@ -4615,10 +4668,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - if (vec3s[0] == null || target.distanceToSqr(d, e, f) < target.distanceToSqr(vec3s[0])) { - vec3s[0] = new Vec3(d, e, f); - } -+ } - - }); - return Optional.of(vec3s[0]); + } ++ + Vec3 ret = null; + double retDistance = Double.MAX_VALUE; + @@ -4634,7 +4687,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + ret = new Vec3(x, y, z); + retDistance = dist; + } - } ++ } + + return Optional.ofNullable(ret); + // Paper end - optimise collisions diff --git a/patches/server/Configurable-Cartographer-Treasure-Maps.patch b/patches/server/Configurable-Cartographer-Treasure-Maps.patch index 3cb0536e6..e06edd4c2 100644 --- a/patches/server/Configurable-Cartographer-Treasure-Maps.patch +++ b/patches/server/Configurable-Cartographer-Treasure-Maps.patch @@ -30,7 +30,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 Vec3 vec3 = context.getParamOrNull(LootContextParams.ORIGIN); if (vec3 != null) { ServerLevel serverLevel = context.getLevel(); -- BlockPos blockPos = serverLevel.findNearestMapStructure(this.destination, BlockPos.containing(vec3), this.searchRadius, this.skipKnownStructures); + // Paper start - Configurable cartographer treasure maps + if (!serverLevel.paperConfig().environment.treasureMaps.enabled) { + /* @@ -39,8 +38,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + */ + return stack; + } -+ BlockPos blockPos = serverLevel.findNearestMapStructure(this.destination, BlockPos.containing(vec3), this.searchRadius, !serverLevel.paperConfig().environment.treasureMaps.findAlreadyDiscoveredLootTable.or(!this.skipKnownStructures)); + // Paper end - Configurable cartographer treasure maps + BlockPos blockPos = serverLevel.findNearestMapStructure( +- this.destination, BlockPos.containing(vec3), this.searchRadius, this.skipKnownStructures ++ this.destination, BlockPos.containing(vec3), this.searchRadius, !serverLevel.paperConfig().environment.treasureMaps.findAlreadyDiscoveredLootTable.or(!this.skipKnownStructures) // Paper - Configurable cartographer treasure maps + ); if (blockPos != null) { ItemStack itemStack = MapItem.create(serverLevel, blockPos.getX(), blockPos.getZ(), this.zoom, true, true); - MapItem.renderBiomePreviewMap(serverLevel, itemStack); diff --git a/patches/server/Configurable-LootPool-luck-formula.patch b/patches/server/Configurable-LootPool-luck-formula.patch index 130dba5e4..c3fb43877 100644 --- a/patches/server/Configurable-LootPool-luck-formula.patch +++ b/patches/server/Configurable-LootPool-luck-formula.patch @@ -43,7 +43,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 protected abstract class EntryBase implements LootPoolEntry { @Override public int getWeight(float luck) { -- return Math.max(Mth.floor((float)LootPoolSingletonContainer.this.weight + (float)LootPoolSingletonContainer.this.quality * luck), 0); +- return Math.max(Mth.floor(LootPoolSingletonContainer.this.weight + LootPoolSingletonContainer.this.quality * luck), 0); + // Paper start - Configurable LootPool luck formula + // SEE: https://luckformula.emc.gs for details and data + if (LootPoolSingletonContainer.this.lastLuck != null && LootPoolSingletonContainer.this.lastLuck == luck) { diff --git a/patches/server/Configurable-Region-Compression-Format.patch b/patches/server/Configurable-Region-Compression-Format.patch index ab6eda47f..6af3bd6bf 100644 --- a/patches/server/Configurable-Region-Compression-Format.patch +++ b/patches/server/Configurable-Region-Compression-Format.patch @@ -22,9 +22,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileVersion.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileVersion.java @@ -0,0 +0,0 @@ public class RegionFileVersion { - }, (stream) -> { - return stream; - })); + ) + ); + public static final RegionFileVersion VERSION_NONE = register(new RegionFileVersion(3, stream -> stream, stream -> stream)); + + // Paper start - Configurable region compression format + public static RegionFileVersion getCompressionFormat() { diff --git a/patches/server/Configurable-sculk-sensor-listener-range.patch b/patches/server/Configurable-sculk-sensor-listener-range.patch index bb9a158af..baebc0a41 100644 --- a/patches/server/Configurable-sculk-sensor-listener-range.patch +++ b/patches/server/Configurable-sculk-sensor-listener-range.patch @@ -44,8 +44,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 protected SculkSensorBlockEntity(BlockEntityType type, BlockPos pos, BlockState state) { super(type, pos, state); @@ -0,0 +0,0 @@ public class SculkSensorBlockEntity extends BlockEntity implements GameEventList - this.vibrationData = listener; - }); + .resultOrPartial(LOGGER::error) + .ifPresent(listener -> this.vibrationData = listener); } + // Paper start - Configurable sculk sensor listener range + if (nbt.contains(PAPER_LISTENER_RANGE_NBT_KEY)) { @@ -54,7 +54,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.rangeOverride = null; + } + // Paper end - Configurable sculk sensor listener range - } + protected static final String PAPER_LISTENER_RANGE_NBT_KEY = "Paper.ListenerRange"; // Paper - Configurable sculk sensor listener range @@ -62,9 +61,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 protected void saveAdditional(CompoundTag nbt) { super.saveAdditional(nbt); @@ -0,0 +0,0 @@ public class SculkSensorBlockEntity extends BlockEntity implements GameEventList - VibrationSystem.Data.CODEC.encodeStart(NbtOps.INSTANCE, this.vibrationData).resultOrPartial(LOGGER::error).ifPresent((listenerNbt) -> { - nbt.put("listener", listenerNbt); - }); + .encodeStart(NbtOps.INSTANCE, this.vibrationData) + .resultOrPartial(LOGGER::error) + .ifPresent(listenerNbt -> nbt.put("listener", listenerNbt)); + this.saveRangeOverride(nbt); // Paper - Configurable sculk sensor listener range + } + // Paper start - Configurable sculk sensor listener range diff --git a/patches/server/Custom-Potion-Mixes.patch b/patches/server/Custom-Potion-Mixes.patch index f42fac11f..ce94379de 100644 --- a/patches/server/Custom-Potion-Mixes.patch +++ b/patches/server/Custom-Potion-Mixes.patch @@ -66,8 +66,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private static final List> CONTAINER_MIXES = Lists.newArrayList(); + private static final it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap CUSTOM_MIXES = new it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap<>(); // Paper - Custom Potion Mixes private static final List ALLOWED_CONTAINERS = Lists.newArrayList(); - private static final Predicate ALLOWED_CONTAINER = (stack) -> { - for(Ingredient ingredient : ALLOWED_CONTAINERS) { + private static final Predicate ALLOWED_CONTAINER = stack -> { + for (Ingredient ingredient : ALLOWED_CONTAINERS) { @@ -0,0 +0,0 @@ public class PotionBrewing { }; @@ -86,9 +86,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return true; + } + // Paper end - Custom Potion Mixes - if (!ALLOWED_CONTAINER.test(input)) { - return false; - } else { + return ALLOWED_CONTAINER.test(input) && (hasContainerMix(input, ingredient) || hasPotionMix(input, ingredient)); + } + @@ -0,0 +0,0 @@ public class PotionBrewing { public static ItemStack mix(ItemStack ingredient, ItemStack input) { diff --git a/patches/server/Custom-table-implementation-for-blockstate-state-loo.patch b/patches/server/Custom-table-implementation-for-blockstate-state-loo.patch index dadf8da35..4adbbb6ff 100644 --- a/patches/server/Custom-table-implementation-for-blockstate-state-loo.patch +++ b/patches/server/Custom-table-implementation-for-blockstate-state-loo.patch @@ -284,17 +284,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 super(name, type); this.values = ImmutableSet.copyOf(values); @@ -0,0 +0,0 @@ public class EnumProperty & StringRepresentable> extends Prope + this.names.put(string, enum_); } - -+ // Paper start - optimise iblockdata state lookup ++ // Paper start - optimise BlockState lookup + int id = 0; + this.idLookupTable = new int[type.getEnumConstants().length]; + java.util.Arrays.fill(this.idLookupTable, -1); + for (final T value : this.getPossibleValues()) { + this.idLookupTable[value.ordinal()] = id++; + } -+ // Paper end - optimise iblockdata state lookup ++ // Paper end - optimise BlockState lookup } @Override @@ -324,7 +324,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java +++ b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java @@ -0,0 +0,0 @@ public abstract class Property> { - }, this::getName); + ); private final Codec> valueCodec = this.codec.xmap(this::value, Property.Value::value); + // Paper start - optimise iblockdata state lookup diff --git a/patches/server/Do-not-load-chunks-for-Pathfinding.patch b/patches/server/Do-not-load-chunks-for-Pathfinding.patch index 1dc50aa15..a99f80ea7 100644 --- a/patches/server/Do-not-load-chunks-for-Pathfinding.patch +++ b/patches/server/Do-not-load-chunks-for-Pathfinding.patch @@ -9,7 +9,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java +++ b/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java @@ -0,0 +0,0 @@ public class WalkNodeEvaluator extends NodeEvaluator { - for(int n = -1; n <= 1; ++n) { + for (int n = -1; n <= 1; n++) { if (l != 0 || n != 0) { pos.set(i + l, j + m, k + n); - BlockState blockState = world.getBlockState(pos); diff --git a/patches/server/Don-t-load-Chunks-from-Hoppers-and-other-things.patch b/patches/server/Don-t-load-Chunks-from-Hoppers-and-other-things.patch index ea635d04f..c12e84635 100644 --- a/patches/server/Don-t-load-Chunks-from-Hoppers-and-other-things.patch +++ b/patches/server/Don-t-load-Chunks-from-Hoppers-and-other-things.patch @@ -29,4 +29,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - Don't load Chunks from Hoppers and other things if (blockState.is(state.getBlock())) { DoubleBlockCombiner.BlockType blockType2 = typeMapper.apply(blockState); - if (blockType2 != DoubleBlockCombiner.BlockType.SINGLE && blockType != blockType2 && blockState.getValue(directionProperty) == state.getValue(directionProperty)) { + if (blockType2 != DoubleBlockCombiner.BlockType.SINGLE 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 4cea5e5e4..95cad6809 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 @@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class ScoreboardSaveData extends SavedData { ListTag listTag = new ListTag(); - for(PlayerTeam playerTeam : this.scoreboard.getPlayerTeams()) { + for (PlayerTeam playerTeam : this.scoreboard.getPlayerTeams()) { + 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()); diff --git a/patches/server/EnderDragon-Events.patch b/patches/server/EnderDragon-Events.patch index 42fbf03a5..853f3b4f5 100644 --- a/patches/server/EnderDragon-Events.patch +++ b/patches/server/EnderDragon-Events.patch @@ -35,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + else dragonFireball.discard(null); // Paper - EnderDragon Events this.fireballCharge = 0; if (this.currentPath != null) { - while(!this.currentPath.isDone()) { + while (!this.currentPath.isDone()) { diff --git a/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java b/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java diff --git a/patches/server/Entity-Activation-Range-2.0.patch b/patches/server/Entity-Activation-Range-2.0.patch index 4dda42b79..fcb0b85dc 100644 --- a/patches/server/Entity-Activation-Range-2.0.patch +++ b/patches/server/Entity-Activation-Range-2.0.patch @@ -195,7 +195,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public GoalSelector(Supplier profiler) { this.profiler = profiler; @@ -0,0 +0,0 @@ public class GoalSelector { - }); + this.availableGoals.removeIf(goal -> predicate.test(goal.getGoal())); } + // Paper start @@ -213,8 +213,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end public void removeGoal(Goal goal) { - this.availableGoals.stream().filter((wrappedGoal) -> { - return wrappedGoal.getGoal() == goal; + this.availableGoals.stream().filter(wrappedGoal -> wrappedGoal.getGoal() == goal).filter(WrappedGoal::isRunning).forEach(WrappedGoal::stop); + this.availableGoals.removeIf(wrappedGoal -> wrappedGoal.getGoal() == goal); diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java @@ -310,9 +310,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.setEnabled(bl); } + this.immunize(); // Paper - } + public boolean isEnabled() { @@ -0,0 +0,0 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper public boolean suckInItems() { @@ -320,7 +320,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.immunize(); // Paper return true; } else { - for(ItemEntity itemEntity : this.level().getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate(0.25D, 0.0D, 0.25D), EntitySelector.ENTITY_STILL_ALIVE)) { + for (ItemEntity itemEntity : this.level() + .getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate(0.25, 0.0, 0.25), EntitySelector.ENTITY_STILL_ALIVE)) { if (HopperBlockEntity.addItem(this, itemEntity)) { + this.immunize(); // Paper return true; diff --git a/patches/server/Entity-getEntitySpawnReason.patch b/patches/server/Entity-getEntitySpawnReason.patch index 9446dfdda..4565c39ac 100644 --- a/patches/server/Entity-getEntitySpawnReason.patch +++ b/patches/server/Entity-getEntitySpawnReason.patch @@ -124,14 +124,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java @@ -0,0 +0,0 @@ public class SculkShriekerBlockEntity extends BlockEntity implements GameEventLi - } private boolean trySummonWarden(ServerLevel world) { -- return this.warningLevel < 4 ? false : SpawnUtil.trySpawnMob(EntityType.WARDEN, MobSpawnType.TRIGGERED, world, this.getBlockPos(), 20, 5, 6, SpawnUtil.Strategy.ON_TOP_OF_COLLIDER).isPresent(); -+ return this.warningLevel < 4 ? false : SpawnUtil.trySpawnMob(EntityType.WARDEN, MobSpawnType.TRIGGERED, world, this.getBlockPos(), 20, 5, 6, SpawnUtil.Strategy.ON_TOP_OF_COLLIDER, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL, null).isPresent(); // Paper - Entity#getEntitySpawnReason + return this.warningLevel >= 4 +- && SpawnUtil.trySpawnMob(EntityType.WARDEN, MobSpawnType.TRIGGERED, world, this.getBlockPos(), 20, 5, 6, SpawnUtil.Strategy.ON_TOP_OF_COLLIDER) ++ && SpawnUtil.trySpawnMob(EntityType.WARDEN, MobSpawnType.TRIGGERED, world, this.getBlockPos(), 20, 5, 6, SpawnUtil.Strategy.ON_TOP_OF_COLLIDER, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL, null) // Paper - Entity#getEntitySpawnReason + .isPresent(); } - @Override diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java diff --git a/patches/server/EntityPathfindEvent.patch b/patches/server/EntityPathfindEvent.patch index d868610cd..cae253474 100644 --- a/patches/server/EntityPathfindEvent.patch +++ b/patches/server/EntityPathfindEvent.patch @@ -28,9 +28,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override - public Path createPath(BlockPos target, int distance) { + 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; + LevelChunk levelChunk = this.level + .getChunkSource() + .getChunkNow(SectionPos.blockToSectionCoord(target.getX()), SectionPos.blockToSectionCoord(target.getZ())); @@ -0,0 +0,0 @@ public class GroundPathNavigation extends PathNavigation { } @@ -39,7 +39,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return super.createPath(blockPos.above(), entity, distance); // Paper - EntityPathfindEvent } - while(blockPos.getY() < this.level.getMaxBuildHeight() && levelChunk.getBlockState(blockPos).isAir()) { + while (blockPos.getY() < this.level.getMaxBuildHeight() && levelChunk.getBlockState(blockPos).isAir()) { @@ -0,0 +0,0 @@ public class GroundPathNavigation extends PathNavigation { } @@ -47,8 +47,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - return super.createPath(target, distance); + 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()) { + BlockPos blockPos2 = target.above(); + +@@ -0,0 +0,0 @@ public class GroundPathNavigation extends PathNavigation { + blockPos2 = blockPos2.above(); } - return super.createPath(blockPos2, distance); @@ -109,7 +111,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - EntityPathfindEvent if (positions.isEmpty()) { return null; - } else if (this.mob.getY() < (double)this.level.getMinBuildHeight()) { + } else if (this.mob.getY() < this.level.getMinBuildHeight()) { @@ -0,0 +0,0 @@ public abstract class PathNavigation { } else if (this.path != null && !this.path.isDone() && positions.contains(this.targetPos)) { return this.path; @@ -133,7 +135,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - EntityPathfindEvent this.level.getProfiler().push("pathfind"); BlockPos blockPos = useHeadPos ? this.mob.blockPosition().above() : this.mob.blockPosition(); - int i = (int)(followRange + (float)range); + int i = (int)(followRange + range); diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/WallClimberNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/WallClimberNavigation.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/WallClimberNavigation.java diff --git a/patches/server/Expand-PlayerGameModeChangeEvent.patch b/patches/server/Expand-PlayerGameModeChangeEvent.patch index c2fd401ad..142d7fa98 100644 --- a/patches/server/Expand-PlayerGameModeChangeEvent.patch +++ b/patches/server/Expand-PlayerGameModeChangeEvent.patch @@ -11,16 +11,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class DefaultGameModeCommands { GameType gameType = minecraftServer.getForcedGameType(); if (gameType != null) { - for(ServerPlayer serverPlayer : minecraftServer.getPlayerList().getPlayers()) { + for (ServerPlayer serverPlayer : minecraftServer.getPlayerList().getPlayers()) { - if (serverPlayer.setGameMode(gameType)) { -- ++i; +- i++; + // Paper start - Expand PlayerGameModeChangeEvent + org.bukkit.event.player.PlayerGameModeChangeEvent event = serverPlayer.setGameMode(gameType, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.DEFAULT_GAMEMODE, net.kyori.adventure.text.Component.empty()); + if (event != null && event.isCancelled()) { + source.sendSuccess(() -> io.papermc.paper.adventure.PaperAdventure.asVanilla(event.cancelMessage()), false); } + // Paper end - Expand PlayerGameModeChangeEvent -+ ++i; ++ i++; } } @@ -31,13 +31,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class GameModeCommand { int i = 0; - for(ServerPlayer serverPlayer : targets) { + for (ServerPlayer serverPlayer : targets) { - if (serverPlayer.setGameMode(gameMode)) { + // Paper start - Expand PlayerGameModeChangeEvent + org.bukkit.event.player.PlayerGameModeChangeEvent event = serverPlayer.setGameMode(gameMode, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.COMMAND, net.kyori.adventure.text.Component.empty()); + if (event != null && !event.isCancelled()) { logGamemodeChange(context.getSource(), serverPlayer, gameMode); - ++i; + i++; + } else if (event != null && event.cancelMessage() != null) { + context.getSource().sendSuccess(() -> io.papermc.paper.adventure.PaperAdventure.asVanilla(event.cancelMessage()), true); + // Paper end - Expand PlayerGameModeChangeEvent diff --git a/patches/server/Fire-EntityChangeBlockEvent-in-more-places.patch b/patches/server/Fire-EntityChangeBlockEvent-in-more-places.patch index 002a8da2b..f25c6a956 100644 --- a/patches/server/Fire-EntityChangeBlockEvent-in-more-places.patch +++ b/patches/server/Fire-EntityChangeBlockEvent-in-more-places.patch @@ -116,7 +116,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/item/HoneycombItem.java +++ b/src/main/java/net/minecraft/world/item/HoneycombItem.java @@ -0,0 +0,0 @@ public class HoneycombItem extends Item implements SignApplicator { - return getWaxed(blockState).map((state) -> { + return getWaxed(blockState).map(state -> { Player player = context.getPlayer(); ItemStack itemStack = context.getItemInHand(); + // Paper start - EntityChangeBlockEvent @@ -163,7 +163,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } else if (blockState.getBlock() instanceof CampfireBlock && blockState.getValue(CampfireBlock.LIT)) { + afterAction = () -> { // Paper if (!level.isClientSide()) { - level.levelEvent((Player)null, 1009, blockPos, 0); + level.levelEvent(null, 1009, blockPos, 0); } CampfireBlock.dowse(context.getPlayer(), level, blockPos, blockState); diff --git a/patches/server/Fire-event-on-GS4-query.patch b/patches/server/Fire-event-on-GS4-query.patch index 7782f518b..3f72dfe29 100644 --- a/patches/server/Fire-event-on-GS4-query.patch +++ b/patches/server/Fire-event-on-GS4-query.patch @@ -45,7 +45,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + networkDataOutputStream.writeString(queryResponse.getHostname()); + // Paper end this.sendTo(networkDataOutputStream.toByteArray(), packet); - LOGGER.debug("Status [{}]", (Object)socketAddress); + LOGGER.debug("Status [{}]", socketAddress); } @@ -0,0 +0,0 @@ public class QueryThreadGs4 extends GenericThread { this.rulesResponse.writeString("splitnum"); @@ -112,13 +112,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - this.rulesResponse.writeString(this.worldName); + this.rulesResponse.writeString(queryResponse.getMap()); this.rulesResponse.writeString("numplayers"); -- this.rulesResponse.writeString("" + this.serverInterface.getPlayerCount()); +- this.rulesResponse.writeString(this.serverInterface.getPlayerCount() + ""); + this.rulesResponse.writeString(Integer.toString(queryResponse.getCurrentPlayers())); this.rulesResponse.writeString("maxplayers"); -- this.rulesResponse.writeString("" + this.maxPlayers); +- this.rulesResponse.writeString(this.maxPlayers + ""); + this.rulesResponse.writeString(Integer.toString(queryResponse.getMaxPlayers())); this.rulesResponse.writeString("hostport"); -- this.rulesResponse.writeString("" + this.serverPort); +- this.rulesResponse.writeString(this.serverPort + ""); + this.rulesResponse.writeString(Integer.toString(queryResponse.getPort())); this.rulesResponse.writeString("hostip"); - this.rulesResponse.writeString(this.hostIp); @@ -130,5 +130,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - String[] strings = this.serverInterface.getPlayerNames(); + String[] strings = queryResponse.getPlayers().toArray(String[]::new); - for(String string : strings) { + for (String string : strings) { this.rulesResponse.writeString(string); diff --git a/patches/server/Firework-API-s.patch b/patches/server/Firework-API-s.patch index e993500f5..aa4cfe46d 100644 --- a/patches/server/Firework-API-s.patch +++ b/patches/server/Firework-API-s.patch @@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public int lifetime; @Nullable public LivingEntity attachedToEntity; -+ public java.util.UUID spawningEntity; // Paper ++ @Nullable public java.util.UUID spawningEntity; // Paper public FireworkRocketEntity(EntityType type, Level world) { super(type, world); @@ -60,9 +60,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java +++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java @@ -0,0 +0,0 @@ public class FireworkRocketItem extends Item { - Vec3 vec3 = context.getClickLocation(); - Direction direction = context.getClickedFace(); - FireworkRocketEntity fireworkRocketEntity = new FireworkRocketEntity(level, context.getPlayer(), vec3.x + (double)direction.getStepX() * 0.15D, vec3.y + (double)direction.getStepY() * 0.15D, vec3.z + (double)direction.getStepZ() * 0.15D, itemStack); + vec3.z + direction.getStepZ() * 0.15, + itemStack + ); + fireworkRocketEntity.spawningEntity = context.getPlayer() == null ? null : context.getPlayer().getUUID(); // Paper level.addFreshEntity(fireworkRocketEntity); itemStack.shrink(1); diff --git a/patches/server/Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch b/patches/server/Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch index b985d4e16..324bd51c6 100644 --- a/patches/server/Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch +++ b/patches/server/Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch @@ -21,10 +21,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public final void addPlayerListener(PlayerAdvancements manager, CriterionTrigger.Listener conditions) { -- this.players.computeIfAbsent(manager, (managerx) -> { -+ manager.criterionData.computeIfAbsent(this, (managerx) -> { // Paper - fix AdvancementDataPlayer leak - return Sets.newHashSet(); - }).add(conditions); +- this.players.computeIfAbsent(manager, managerx -> Sets.newHashSet()).add(conditions); ++ manager.criterionData.computeIfAbsent(this, managerx -> Sets.newHashSet()).add(conditions); // Paper - fix AdvancementDataPlayer leak } @Override @@ -38,8 +36,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + manager.criterionData.remove(this); // Paper - fix AdvancementDataPlayer leak } } - -@@ -0,0 +0,0 @@ public abstract class SimpleCriterionTrigger> behaviors = new ShufflingList<>(false); // Paper - Fix Concurrency issue in ShufflingList during worldgen private Behavior.Status status = Behavior.Status.STOPPED; - public GateBehavior(Map, MemoryStatus> requiredMemoryState, Set> memoriesToForgetWhenStopped, GateBehavior.OrderPolicy order, GateBehavior.RunningPolicy runMode, List, Integer>> tasks) { + public GateBehavior( diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java b/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java @@ -53,9 +53,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } public ShufflingList shuffle() { -- this.entries.forEach((entry) -> { -- entry.setRandom(this.random.nextFloat()); -- }); +- this.entries.forEach(entry -> entry.setRandom(this.random.nextFloat())); - this.entries.sort(Comparator.comparingDouble(ShufflingList.WeightedEntry::getRandWeight)); - return this; + // Paper start - Fix Concurrency issue in ShufflingList during worldgen diff --git a/patches/server/Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch b/patches/server/Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch index b3bad6af4..c13b6c7f5 100644 --- a/patches/server/Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch +++ b/patches/server/Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch @@ -14,11 +14,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java @@ -0,0 +0,0 @@ public class VillagerGoalPackages { - private static final float STROLL_SPEED_MODIFIER = 0.4F; - - public static ImmutableList>> getCorePackage(VillagerProfession profession, float speed) { -- return ImmutableList.of(Pair.of(0, new Swim(0.8F)), Pair.of(0, InteractWithDoor.create()), Pair.of(0, new LookAtTargetSink(45, 90)), Pair.of(0, new VillagerPanicTrigger()), Pair.of(0, WakeUp.create()), Pair.of(0, ReactToBell.create()), Pair.of(0, SetRaidStatus.create()), Pair.of(0, ValidateNearbyPoi.create(profession.heldJobSite(), MemoryModuleType.JOB_SITE)), Pair.of(0, ValidateNearbyPoi.create(profession.acquirableJobSite(), MemoryModuleType.POTENTIAL_JOB_SITE)), Pair.of(1, new MoveToTargetSink()), Pair.of(2, PoiCompetitorScan.create()), Pair.of(3, new LookAndFollowTradingPlayerSink(speed)), Pair.of(5, GoToWantedItem.create(speed, false, 4)), Pair.of(6, AcquirePoi.create(profession.acquirableJobSite(), MemoryModuleType.JOB_SITE, MemoryModuleType.POTENTIAL_JOB_SITE, true, Optional.empty())), Pair.of(7, new GoToPotentialJobSite(speed)), Pair.of(8, YieldJobSite.create(speed)), Pair.of(10, AcquirePoi.create((poiType) -> { -+ return ImmutableList.of(Pair.of(0, new Swim(0.8F)), Pair.of(0, InteractWithDoor.create()), Pair.of(0, new LookAtTargetSink(45, 90)), Pair.of(0, new VillagerPanicTrigger()), Pair.of(0, WakeUp.create()), Pair.of(0, ReactToBell.create()), Pair.of(0, SetRaidStatus.create()), Pair.of(0, ValidateNearbyPoi.create(profession.heldJobSite(), MemoryModuleType.JOB_SITE)), Pair.of(0, ValidateNearbyPoi.create(profession.acquirableJobSite(), MemoryModuleType.POTENTIAL_JOB_SITE)), Pair.of(1, new MoveToTargetSink()), Pair.of(2, PoiCompetitorScan.create()), Pair.of(3, new LookAndFollowTradingPlayerSink(speed)), Pair.of(5, GoToWantedItem.create(villager -> !villager.isSleeping(), speed, false, 4)), Pair.of(6, AcquirePoi.create(profession.acquirableJobSite(), MemoryModuleType.JOB_SITE, MemoryModuleType.POTENTIAL_JOB_SITE, true, Optional.empty())), Pair.of(7, new GoToPotentialJobSite(speed)), Pair.of(8, YieldJobSite.create(speed)), Pair.of(10, AcquirePoi.create((poiType) -> { // Paper - Fix MC-157464 - return poiType.is(PoiTypes.HOME); - }, MemoryModuleType.HOME, false, Optional.of((byte)14))), Pair.of(10, AcquirePoi.create((poiType) -> { - return poiType.is(PoiTypes.MEETING); + Pair.of(1, new MoveToTargetSink()), + Pair.of(2, PoiCompetitorScan.create()), + Pair.of(3, new LookAndFollowTradingPlayerSink(speed)), +- Pair.of(5, GoToWantedItem.create(speed, false, 4)), ++ Pair.of(5, GoToWantedItem.create(villager -> !villager.isSleeping(), speed, false, 4)), // Paper - Fix MC-157464 + Pair.of( + 6, AcquirePoi.create(profession.acquirableJobSite(), MemoryModuleType.JOB_SITE, MemoryModuleType.POTENTIAL_JOB_SITE, true, Optional.empty()) + ), diff --git a/patches/server/Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch b/patches/server/Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch index 363c9630d..62e07456f 100644 --- a/patches/server/Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch +++ b/patches/server/Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch @@ -32,7 +32,7 @@ diff --git a/src/main/java/net/minecraft/server/Services.java b/src/main/java/ne index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/Services.java +++ b/src/main/java/net/minecraft/server/Services.java -@@ -0,0 +0,0 @@ public record Services(MinecraftSessionService sessionService, ServicesKeySet se +@@ -0,0 +0,0 @@ public record Services( return java.util.Objects.requireNonNull(this.paperConfigurations); } // Paper end - add paper configuration files diff --git a/patches/server/Fix-Spigot-growth-modifiers.patch b/patches/server/Fix-Spigot-growth-modifiers.patch index 31ff9674e..30071fa15 100644 --- a/patches/server/Fix-Spigot-growth-modifiers.patch +++ b/patches/server/Fix-Spigot-growth-modifiers.patch @@ -87,7 +87,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (random.nextFloat() < (world.spigotConfig.saplingModifier / (100.0F * 7))) { // Paper - Fix Spigot growth modifiers this.advanceTree(world, pos, state, random); } - + } else { diff --git a/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java b/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java diff --git a/patches/server/Fix-a-bunch-of-vanilla-bugs.patch b/patches/server/Fix-a-bunch-of-vanilla-bugs.patch index 0babf43fa..0945ee6be 100644 --- a/patches/server/Fix-a-bunch-of-vanilla-bugs.patch +++ b/patches/server/Fix-a-bunch-of-vanilla-bugs.patch @@ -91,27 +91,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/commands/DeOpCommands.java +++ b/src/main/java/net/minecraft/server/commands/DeOpCommands.java @@ -0,0 +0,0 @@ public class DeOpCommands { + if (playerList.isOp(gameProfile)) { playerList.deop(gameProfile); - ++i; - source.sendSuccess(() -> { -- return Component.translatable("commands.deop.success", targets.iterator().next().getName()); -+ return Component.translatable("commands.deop.success", gameProfile.getName()); // Paper - fixes MC-253721 - }, true); + i++; +- source.sendSuccess(() -> Component.translatable("commands.deop.success", targets.iterator().next().getName()), true); ++ source.sendSuccess(() -> Component.translatable("commands.deop.success", gameProfile.getName()), true); // Paper - fixes MC-253721 } } + diff --git a/src/main/java/net/minecraft/server/commands/OpCommand.java b/src/main/java/net/minecraft/server/commands/OpCommand.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/commands/OpCommand.java +++ b/src/main/java/net/minecraft/server/commands/OpCommand.java @@ -0,0 +0,0 @@ public class OpCommand { + if (!playerList.isOp(gameProfile)) { playerList.op(gameProfile); - ++i; - source.sendSuccess(() -> { -- return Component.translatable("commands.op.success", targets.iterator().next().getName()); -+ return Component.translatable("commands.op.success", gameProfile.getName()); // Paper - fixes MC-253721 - }, true); + i++; +- source.sendSuccess(() -> Component.translatable("commands.op.success", targets.iterator().next().getName()), true); ++ source.sendSuccess(() -> Component.translatable("commands.op.success", gameProfile.getName()), true); // Paper - fixes MC-253721 } } + diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -211,7 +211,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/world/entity/ai/goal/BegGoal.java @@ -0,0 +0,0 @@ public class BegGoal extends Goal { private boolean playerHoldingInteresting(Player player) { - for(InteractionHand interactionHand : InteractionHand.values()) { + for (InteractionHand interactionHand : InteractionHand.values()) { ItemStack itemStack = player.getItemInHand(interactionHand); - if (this.wolf.isTame() && itemStack.is(Items.BONE)) { + if (!this.wolf.isTame() && itemStack.is(Items.BONE)) { // Paper - Fix MC-84789 @@ -268,7 +268,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/ai/goal/SwellGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/SwellGoal.java @@ -0,0 +0,0 @@ public class SwellGoal extends Goal { - return this.creeper.getSwellDir() > 0 || livingEntity != null && this.creeper.distanceToSqr(livingEntity) < 9.0D; + return this.creeper.getSwellDir() > 0 || livingEntity != null && this.creeper.distanceToSqr(livingEntity) < 9.0; } + // Paper start - Fix MC-179072 @@ -344,7 +344,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return 0; } else { + cat.moveTo(pos, 0.0F, 0.0F); // Paper - move up - Fix MC-147659 - cat.finalizeSpawn(world, world.getCurrentDifficultyAt(pos), MobSpawnType.NATURAL, (SpawnGroupData)null, (CompoundTag)null); + cat.finalizeSpawn(world, world.getCurrentDifficultyAt(pos), MobSpawnType.NATURAL, null, null); - cat.moveTo(pos, 0.0F, 0.0F); world.addFreshEntityWithPassengers(cat); return 1; @@ -392,7 +392,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/item/BundleItem.java +++ b/src/main/java/net/minecraft/world/item/BundleItem.java @@ -0,0 +0,0 @@ public class BundleItem extends Item { - }); + removeOne(stack).ifPresent(removedStack -> add(stack, slot.safeInsert(removedStack))); } else if (itemStack.getItem().canFitInsideContainerItems()) { int i = (64 - getContentWeight(stack)) / getWeight(itemStack); - int j = add(stack, slot.safeTake(itemStack.getCount(), i, player)); @@ -414,14 +414,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/item/SaddleItem.java +++ b/src/main/java/net/minecraft/world/item/SaddleItem.java @@ -0,0 +0,0 @@ public class SaddleItem extends Item { - if (entity instanceof Saddleable saddleable) { - if (entity.isAlive() && !saddleable.isSaddled() && saddleable.isSaddleable()) { - if (!user.level().isClientSide) { -- saddleable.equipSaddle(SoundSource.NEUTRAL); -+ saddleable.equipSaddle(SoundSource.NEUTRAL, stack.copyWithCount(1)); // Paper - Fix saddles losing nbt data - MC-191591 - entity.level().gameEvent(entity, GameEvent.EQUIP, entity.position()); - stack.shrink(1); - } + public InteractionResult interactLivingEntity(ItemStack stack, Player user, LivingEntity entity, InteractionHand hand) { + if (entity instanceof Saddleable saddleable && entity.isAlive() && !saddleable.isSaddled() && saddleable.isSaddleable()) { + if (!user.level().isClientSide) { +- saddleable.equipSaddle(SoundSource.NEUTRAL); ++ saddleable.equipSaddle(SoundSource.NEUTRAL, stack.copyWithCount(1)); // Paper - Fix saddles losing nbt data - MC-191591 + entity.level().gameEvent(entity, GameEvent.EQUIP, entity.position()); + stack.shrink(1); + } diff --git a/src/main/java/net/minecraft/world/level/block/AzaleaBlock.java b/src/main/java/net/minecraft/world/level/block/AzaleaBlock.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/block/AzaleaBlock.java diff --git a/patches/server/Fix-concurrenct-access-to-lookups-field-in-RegistryO.patch b/patches/server/Fix-concurrenct-access-to-lookups-field-in-RegistryO.patch index f1a43151b..bbc3b82f1 100644 --- a/patches/server/Fix-concurrenct-access-to-lookups-field-in-RegistryO.patch +++ b/patches/server/Fix-concurrenct-access-to-lookups-field-in-RegistryO.patch @@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/resources/RegistryOps.java @@ -0,0 +0,0 @@ public class RegistryOps extends DelegatingOps { - private static RegistryOps.RegistryInfoLookup memoizeLookup(final RegistryOps.RegistryInfoLookup registryInfoGetter) { + private static RegistryOps.RegistryInfoLookup memoizeLookup(RegistryOps.RegistryInfoLookup registryInfoGetter) { return new RegistryOps.RegistryInfoLookup() { - private final Map>, Optional>> lookups = new HashMap<>(); + // The concurrent access occurs on the Netty IO threads when serializing packets. @@ -26,8 +26,3 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public Optional> lookup(ResourceKey> registryRef) { -- return this.lookups.computeIfAbsent(registryRef, registryInfoGetter::lookup); -+ return (Optional>)this.lookups.computeIfAbsent(registryRef, registryInfoGetter::lookup); // Paper - fix concurrent access to lookups field - } - }; - } diff --git a/patches/server/Fix-entity-type-tags-suggestions-in-selectors.patch b/patches/server/Fix-entity-type-tags-suggestions-in-selectors.patch index 9327e5053..18aaa7a54 100644 --- a/patches/server/Fix-entity-type-tags-suggestions-in-selectors.patch +++ b/patches/server/Fix-entity-type-tags-suggestions-in-selectors.patch @@ -122,9 +122,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java +++ b/src/main/java/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java @@ -0,0 +0,0 @@ public class EntitySelectorOptions { - public static final DynamicCommandExceptionType ERROR_ENTITY_TYPE_INVALID = new DynamicCommandExceptionType((entity) -> { - return Component.translatableEscape("argument.entity.options.type.invalid", entity); - }); + public static final DynamicCommandExceptionType ERROR_ENTITY_TYPE_INVALID = new DynamicCommandExceptionType( + entity -> Component.translatableEscape("argument.entity.options.type.invalid", entity) + ); + // Paper start - tell clients to ask server for suggestions for EntityArguments + public static final DynamicCommandExceptionType ERROR_ENTITY_TAG_INVALID = new DynamicCommandExceptionType((object) -> { + return io.papermc.paper.adventure.PaperAdventure @@ -143,14 +143,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 OPTIONS.put(id, new EntitySelectorOptions.Option(handler, condition, description)); @@ -0,0 +0,0 @@ public class EntitySelectorOptions { - if (reader.isTag()) { - TagKey> tagKey = TagKey.create(Registries.ENTITY_TYPE, ResourceLocation.read(reader.getReader())); -+ // Paper start - tell clients to ask server for suggestions for EntityArguments; throw error if invalid entity tag (only on suggestions to keep cmd success behavior) -+ if (reader.parsingEntityArgumentSuggestions && io.papermc.paper.configuration.GlobalConfiguration.get().commands.fixTargetSelectorTagCompletion && net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.getTag(tagKey).isEmpty()) { -+ reader.getReader().setCursor(i); -+ throw ERROR_ENTITY_TAG_INVALID.createWithContext(reader.getReader(), tagKey); -+ } -+ // Paper end - tell clients to ask server for suggestions for EntityArguments - reader.addPredicate((entity) -> { - return entity.getType().is(tagKey) != bl; - }); + if (reader.isTag()) { + TagKey> tagKey = TagKey.create(Registries.ENTITY_TYPE, ResourceLocation.read(reader.getReader())); ++ // Paper start - tell clients to ask server for suggestions for EntityArguments; throw error if invalid entity tag (only on suggestions to keep cmd success behavior) ++ if (reader.parsingEntityArgumentSuggestions && io.papermc.paper.configuration.GlobalConfiguration.get().commands.fixTargetSelectorTagCompletion && net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.getTag(tagKey).isEmpty()) { ++ reader.getReader().setCursor(i); ++ throw ERROR_ENTITY_TAG_INVALID.createWithContext(reader.getReader(), tagKey); ++ } ++ // Paper end - tell clients to ask server for suggestions for EntityArguments + reader.addPredicate(entity -> entity.getType().is(tagKey) != bl); + } else { + ResourceLocation resourceLocation = ResourceLocation.read(reader.getReader()); diff --git a/patches/server/Fix-invulnerable-end-crystals.patch b/patches/server/Fix-invulnerable-end-crystals.patch index 58a31f92e..35cd34851 100644 --- a/patches/server/Fix-invulnerable-end-crystals.patch +++ b/patches/server/Fix-invulnerable-end-crystals.patch @@ -58,7 +58,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class SpikeFeature extends Feature { endCrystal.setBeamTarget(config.getCrystalBeamTarget()); endCrystal.setInvulnerable(config.isCrystalInvulnerable()); - endCrystal.moveTo((double)spike.getCenterX() + 0.5D, (double)(spike.getHeight() + 1), (double)spike.getCenterZ() + 0.5D, random.nextFloat() * 360.0F, 0.0F); + endCrystal.moveTo(spike.getCenterX() + 0.5, spike.getHeight() + 1, spike.getCenterZ() + 0.5, random.nextFloat() * 360.0F, 0.0F); + endCrystal.generatedByDragonFight = true; // Paper - Fix invulnerable end crystals world.addFreshEntity(endCrystal); BlockPos blockPos2 = endCrystal.blockPosition(); diff --git a/patches/server/Fix-issues-with-mob-conversion.patch b/patches/server/Fix-issues-with-mob-conversion.patch index e7ab5b664..915ce191b 100644 --- a/patches/server/Fix-issues-with-mob-conversion.patch +++ b/patches/server/Fix-issues-with-mob-conversion.patch @@ -38,9 +38,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.timeInOverworld = 0; + } + // Paper end - Fix issues with mob conversion - } + @Override diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java diff --git a/patches/server/Fix-missing-chunks-due-to-integer-overflow.patch b/patches/server/Fix-missing-chunks-due-to-integer-overflow.patch index 32c9ee588..e8db52328 100644 --- a/patches/server/Fix-missing-chunks-due-to-integer-overflow.patch +++ b/patches/server/Fix-missing-chunks-due-to-integer-overflow.patch @@ -22,8 +22,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 int j = z / 2; int k = x % 2; int l = z % 2; -- float f = 100.0F - Mth.sqrt((float)(x * x + z * z)) * 8.0F; +- float f = 100.0F - Mth.sqrt(x * x + z * z) * 8.0F; + float f = 100.0F - Mth.sqrt((long) x * (long) x + (long) z * (long) z) * 8.0F; // Paper - cast ints to long to avoid integer overflow f = Mth.clamp(f, -100.0F, 80.0F); - for(int m = -12; m <= 12; ++m) { + for (int m = -12; m <= 12; m++) { diff --git a/patches/server/Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch b/patches/server/Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch index 050ad6d8d..ab5a4c649 100644 --- a/patches/server/Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch +++ b/patches/server/Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch @@ -22,6 +22,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 level.scheduleTick(tick.pos(), fluid, tick.delay(), tick.priority()); }); + UpgradeData.BlockFixers.values(); // Paper - force the class init so that we don't access CHUNKY_FIXERS before all BlockFixers are initialised - CHUNKY_FIXERS.forEach((logic) -> { - logic.processChunk(level); - }); + CHUNKY_FIXERS.forEach(logic -> logic.processChunk(level)); + } + diff --git a/patches/server/Fix-some-rails-connecting-improperly.patch b/patches/server/Fix-some-rails-connecting-improperly.patch index 48459128b..e72949763 100644 --- a/patches/server/Fix-some-rails-connecting-improperly.patch +++ b/patches/server/Fix-some-rails-connecting-improperly.patch @@ -67,7 +67,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end - Fix some rails connecting improperly - for(int i = 0; i < this.connections.size(); ++i) { + for (int i = 0; i < this.connections.size(); i++) { RailState railState = this.getRail(this.connections.get(i)); - if (railState != null) { + if (railState != null && railState.isValid()) { // Paper - Fix some rails connecting improperly diff --git a/patches/server/Fix-swamp-hut-cat-generation-deadlock.patch b/patches/server/Fix-swamp-hut-cat-generation-deadlock.patch index f45bb2249..e9ff1f23f 100644 --- a/patches/server/Fix-swamp-hut-cat-generation-deadlock.patch +++ b/patches/server/Fix-swamp-hut-cat-generation-deadlock.patch @@ -37,9 +37,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public List startsForStructure(ChunkPos pos, Predicate predicate, @Nullable ServerLevelAccessor levelAccessor) { + Map map = (levelAccessor == null ? this.level : levelAccessor).getChunk(pos.x, pos.z, ChunkStatus.STRUCTURE_REFERENCES).getAllReferences(); + // Paper end - Fix swamp hut cat generation deadlock - ImmutableList.Builder builder = ImmutableList.builder(); + Builder builder = ImmutableList.builder(); - for(Map.Entry entry : map.entrySet()) { + for (Entry entry : map.entrySet()) { @@ -0,0 +0,0 @@ public class StructureManager { } @@ -51,12 +51,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - Fix swamp hut cat generation deadlock Registry registry = this.registryAccess().registryOrThrow(Registries.STRUCTURE); - for(StructureStart structureStart : this.startsForStructure(new ChunkPos(pos), (structure) -> { - return registry.getHolder(registry.getId(structure)).map((reference) -> { - return reference.is(structureTag); - }).orElse(false); -- })) { -+ }, levelAccessor)) { // Paper - Fix swamp hut cat generation deadlock + for (StructureStart structureStart : this.startsForStructure( +- new ChunkPos(pos), structure -> registry.getHolder(registry.getId(structure)).map(reference -> reference.is(structureTag)).orElse(false) ++ new ChunkPos(pos), structure -> registry.getHolder(registry.getId(structure)).map(reference -> reference.is(structureTag)).orElse(false), levelAccessor // Paper - Fix swamp hut cat generation deadlock + )) { if (this.structureHasPieceAt(pos, structureStart)) { return structureStart; - } diff --git a/patches/server/Fix-text-display-error-on-spawn.patch b/patches/server/Fix-text-display-error-on-spawn.patch index 766604b70..819503bf9 100644 --- a/patches/server/Fix-text-display-error-on-spawn.patch +++ b/patches/server/Fix-text-display-error-on-spawn.patch @@ -9,11 +9,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/Display.java +++ b/src/main/java/net/minecraft/world/entity/Display.java @@ -0,0 +0,0 @@ public abstract class Display extends Entity { - byte b = loadFlag((byte)0, nbt, "shadow", (byte)1); - b = loadFlag(b, nbt, "see_through", (byte)2); b = loadFlag(b, nbt, "default_background", (byte)4); -- Optional optional = Display.TextDisplay.Align.CODEC.decode(NbtOps.INSTANCE, nbt.get("alignment")).resultOrPartial(Util.prefix("Display entity", Display.LOGGER::error)).map(Pair::getFirst); -+ Optional optional = Display.TextDisplay.Align.CODEC.decode(NbtOps.INSTANCE, nbt.get("alignment")).result().map(Pair::getFirst); // Paper - Hide text display error on spawn + Optional optional = Display.TextDisplay.Align.CODEC + .decode(NbtOps.INSTANCE, nbt.get("alignment")) +- .resultOrPartial(Util.prefix("Display entity", Display.LOGGER::error)) ++ .result() // Paper - Hide text display error on spawn + .map(Pair::getFirst); if (optional.isPresent()) { - byte var10000; - switch ((Display.TextDisplay.Align)optional.get()) { + b = switch ((Display.TextDisplay.Align)optional.get()) { diff --git a/patches/server/Fixes-and-additions-to-the-SpawnReason-API.patch b/patches/server/Fixes-and-additions-to-the-SpawnReason-API.patch index c87efa95a..f31afc628 100644 --- a/patches/server/Fixes-and-additions-to-the-SpawnReason-API.patch +++ b/patches/server/Fixes-and-additions-to-the-SpawnReason-API.patch @@ -39,13 +39,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java @@ -0,0 +0,0 @@ public class FrogspawnBlock extends Block { int k = random.nextInt(1, 361); - tadpole.moveTo(d, (double)pos.getY() - 0.5D, e, (float)k, 0.0F); + tadpole.moveTo(d, pos.getY() - 0.5, e, k, 0.0F); tadpole.setPersistenceRequired(); - world.addFreshEntity(tadpole); + world.addFreshEntity(tadpole, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); // Paper - use correct spawn reason } } - + } diff --git a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java @@ -57,5 +57,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - world.addFreshEntity(sniffer); + world.addFreshEntity(sniffer, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); // Paper - use correct spawn reason } - } + } diff --git a/patches/server/Flat-bedrock-generator-settings.patch b/patches/server/Flat-bedrock-generator-settings.patch index 4be766242..b02ea581b 100644 --- a/patches/server/Flat-bedrock-generator-settings.patch +++ b/patches/server/Flat-bedrock-generator-settings.patch @@ -172,12 +172,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/level/levelgen/carver/CarvingContext.java +++ b/src/main/java/net/minecraft/world/level/levelgen/carver/CarvingContext.java @@ -0,0 +0,0 @@ public class CarvingContext extends WorldGenerationContext { - private final RandomState randomState; - private final SurfaceRules.RuleSource surfaceRule; - -- public CarvingContext(NoiseBasedChunkGenerator noiseChunkGenerator, RegistryAccess registryManager, LevelHeightAccessor heightLimitView, NoiseChunk chunkNoiseSampler, RandomState noiseConfig, SurfaceRules.RuleSource materialRule) { + LevelHeightAccessor heightLimitView, + NoiseChunk chunkNoiseSampler, + RandomState noiseConfig, +- SurfaceRules.RuleSource materialRule ++ SurfaceRules.RuleSource materialRule, @javax.annotation.Nullable net.minecraft.world.level.Level level // Paper - Flat bedrock generator settings + ) { - super(noiseChunkGenerator, heightLimitView); -+ public CarvingContext(NoiseBasedChunkGenerator noiseChunkGenerator, RegistryAccess registryManager, LevelHeightAccessor heightLimitView, NoiseChunk chunkNoiseSampler, RandomState noiseConfig, SurfaceRules.RuleSource materialRule, @javax.annotation.Nullable net.minecraft.world.level.Level level) { // Paper - Flat bedrock generator settings + super(noiseChunkGenerator, heightLimitView, level); // Paper - Flat bedrock generator settings this.registryAccess = registryManager; this.noiseChunk = chunkNoiseSampler; diff --git a/patches/server/Handle-Large-Packets-disconnecting-client.patch b/patches/server/Handle-Large-Packets-disconnecting-client.patch index b6a4c3db3..8564779c0 100644 --- a/patches/server/Handle-Large-Packets-disconnecting-client.patch +++ b/patches/server/Handle-Large-Packets-disconnecting-client.patch @@ -58,7 +58,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - Handle large packets disconnecting client ProtocolSwapHandler.swapProtocolIfNeeded(attribute, packet); } - } } } diff --git a/patches/server/Handle-Oversized-block-entities-in-chunks.patch b/patches/server/Handle-Oversized-block-entities-in-chunks.patch index d24b11098..da2af1a0e 100644 --- a/patches/server/Handle-Oversized-block-entities-in-chunks.patch +++ b/patches/server/Handle-Oversized-block-entities-in-chunks.patch @@ -33,7 +33,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.blockEntitiesData = Lists.newArrayList(); + int totalTileEntities = 0; // Paper - Handle oversized block entities in chunks - for(Map.Entry entry2 : chunk.getBlockEntities().entrySet()) { + for (Entry entry2 : chunk.getBlockEntities().entrySet()) { + // Paper start - Handle oversized block entities in chunks + if (++totalTileEntities > TE_LIMIT) { + var packet = entry2.getValue().getUpdatePacket(); @@ -45,7 +45,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - Handle oversized block entities in chunks this.blockEntitiesData.add(ClientboundLevelChunkPacketData.BlockEntityInfo.create(entry2.getValue())); } - + } diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkWithLightPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkWithLightPacket.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkWithLightPacket.java diff --git a/patches/server/Improve-BlockPosition-inlining.patch b/patches/server/Improve-BlockPosition-inlining.patch index cf1268b95..6877f7eca 100644 --- a/patches/server/Improve-BlockPosition-inlining.patch +++ b/patches/server/Improve-BlockPosition-inlining.patch @@ -30,10 +30,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override - public boolean equals(Object object) { + public final boolean equals(Object object) { // Paper - Perf: Final for inline - if (this == object) { - return true; - } else if (!(object instanceof Vec3i)) { -@@ -0,0 +0,0 @@ public class Vec3i implements Comparable { + return this == object || object instanceof Vec3i vec3i && this.getX() == vec3i.getX() && this.getY() == vec3i.getY() && this.getZ() == vec3i.getZ(); } @Override diff --git a/patches/server/Improve-Server-Thread-Pool-and-Thread-Priorities.patch b/patches/server/Improve-Server-Thread-Pool-and-Thread-Priorities.patch index ebc611cd4..bda02662f 100644 --- a/patches/server/Improve-Server-Thread-Pool-and-Thread-Priorities.patch +++ b/patches/server/Improve-Server-Thread-Pool-and-Thread-Priorities.patch @@ -75,7 +75,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 executorService = MoreExecutors.newDirectExecutorService(); } else { - AtomicInteger atomicInteger = new AtomicInteger(1); -- executorService = new ForkJoinPool(i, (pool) -> { +- executorService = new ForkJoinPool(i, pool -> { - ForkJoinWorkerThread forkJoinWorkerThread = new ForkJoinWorkerThread(pool) { + executorService = new java.util.concurrent.ThreadPoolExecutor(i, i,0L, TimeUnit.MILLISECONDS, new java.util.concurrent.LinkedBlockingQueue<>(), target -> new io.papermc.paper.util.ServerWorkerThread(target, s, priorityModifier)); + } diff --git a/patches/server/Improve-ServerGUI.patch b/patches/server/Improve-ServerGUI.patch index fdaf15d93..ef9212292 100644 --- a/patches/server/Improve-ServerGUI.patch +++ b/patches/server/Improve-ServerGUI.patch @@ -73,10 +73,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + tpsAvg[g] = format( tps[g] ); + } this.msgs[0] = "Memory use: " + l / 1024L / 1024L + " mb (" + Runtime.getRuntime().freeMemory() * 100L / Runtime.getRuntime().maxMemory() + "% free)"; - this.msgs[1] = "Avg tick: " + DECIMAL_FORMAT.format((double)this.server.getAverageTickTimeNanos() / (double)TimeUtil.NANOSECONDS_PER_MILLISECOND) + " ms"; + this.msgs[1] = "Avg tick: " + DECIMAL_FORMAT.format((double)this.server.getAverageTickTimeNanos() / TimeUtil.NANOSECONDS_PER_MILLISECOND) + " ms"; + this.msgs[2] = "TPS from last 1m, 5m, 15m: " + String.join(", ", tpsAvg); + // Paper end - Improve ServerGUI - this.values[this.vp++ & 255] = (int)(l * 100L / Runtime.getRuntime().maxMemory()); + this.values[this.vp++ & 0xFF] = (int)(l * 100L / Runtime.getRuntime().maxMemory()); this.repaint(); } @@ -0,0 +0,0 @@ public class StatsComponent extends JComponent { diff --git a/patches/server/Improve-boat-collision-performance.patch b/patches/server/Improve-boat-collision-performance.patch index b30c5bbe4..e91650e41 100644 --- a/patches/server/Improve-boat-collision-performance.patch +++ b/patches/server/Improve-boat-collision-performance.patch @@ -9,11 +9,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/Util.java +++ b/src/main/java/net/minecraft/Util.java @@ -0,0 +0,0 @@ public class Util { - }).findFirst().orElseThrow(() -> { - return new IllegalStateException("No jar file system provider found"); - }); + .filter(fileSystemProvider -> fileSystemProvider.getScheme().equalsIgnoreCase("jar")) + .findFirst() + .orElseThrow(() -> new IllegalStateException("No jar file system provider found")); + public static final double COLLISION_EPSILON = 1.0E-7; // Paper - Improve boat collision performance - private static Consumer thePauser = (message) -> { + private static Consumer thePauser = message -> { }; diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java diff --git a/patches/server/Improve-death-events.patch b/patches/server/Improve-death-events.patch index 95f0b8562..5e82b7b7e 100644 --- a/patches/server/Improve-death-events.patch +++ b/patches/server/Improve-death-events.patch @@ -326,23 +326,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.spawnAtLocation(Blocks.CHEST); } -- this.setChest(false); -+ //this.setCarryingChest(false); // Paper - moved to post death logic - } - - } - ++ //this.setChest(false); // Paper - moved to post death logic ++ } ++ } ++ + // Paper start + protected void postDeathDropItems(org.bukkit.event.entity.EntityDeathEvent event) { + if (this.hasChest() && (event == null || !event.isCancelled())) { -+ this.setChest(false); -+ } -+ } + this.setChest(false); + } + } + // Paper end -+ + @Override public void addAdditionalSaveData(CompoundTag nbt) { - super.addAdditionalSaveData(nbt); diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java diff --git a/patches/server/Improve-exact-choice-recipe-ingredients.patch b/patches/server/Improve-exact-choice-recipe-ingredients.patch index da0959a1f..7d1bc99bd 100644 --- a/patches/server/Improve-exact-choice-recipe-ingredients.patch +++ b/patches/server/Improve-exact-choice-recipe-ingredients.patch @@ -153,11 +153,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.stackedContents.initialize(recipe.value()); // Paper - Improve exact choice recipe ingredients entity.getInventory().fillStackedContents(this.stackedContents); this.menu.fillCraftSlotsStackedContents(this.stackedContents); - if (this.stackedContents.canCraft(recipe.value(), (IntList)null)) { + if (this.stackedContents.canCraft((Recipe)recipe.value(), null)) { @@ -0,0 +0,0 @@ public class ServerPlaceRecipe implements PlaceRecipe implements PlaceRecipe directoryStream = Files.newDirectoryStream(path)) { - for(Path path2 : directoryStream) { + for (Path path2 : directoryStream) { String string = path2.getFileName().toString(); + // Paper start - Improve logging and errors + if (!Files.isDirectory(path2)) { diff --git a/patches/server/Improve-performance-of-mass-crafts.patch b/patches/server/Improve-performance-of-mass-crafts.patch index 6a45c1e8c..6fab3c76a 100644 --- a/patches/server/Improve-performance-of-mass-crafts.patch +++ b/patches/server/Improve-performance-of-mass-crafts.patch @@ -44,7 +44,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - NonNullList nonNullList = player.level().getRecipeManager().getRemainingItemsFor(RecipeType.CRAFTING, this.craftSlots, player.level()); + NonNullList nonNullList = player.level().getRecipeManager().getRemainingItemsFor(RecipeType.CRAFTING, this.craftSlots, player.level(), this.craftSlots.getCurrentRecipe() != null ? this.craftSlots.getCurrentRecipe().id() : null); // Paper - Perf: Improve mass crafting; check last recipe used first - for(int i = 0; i < nonNullList.size(); ++i) { + for (int i = 0; i < nonNullList.size(); i++) { ItemStack itemStack = this.craftSlots.getItem(i); diff --git a/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java b/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/patches/server/Improve-tag-parser-handling.patch b/patches/server/Improve-tag-parser-handling.patch index 91d119750..e26914afa 100644 --- a/patches/server/Improve-tag-parser-handling.patch +++ b/patches/server/Improve-tag-parser-handling.patch @@ -64,7 +64,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + private int depth; // Paper public static CompoundTag parseTag(String string) throws CommandSyntaxException { - return (new TagParser(new StringReader(string))).readSingleStruct(); + return new TagParser(new StringReader(string)).readSingleStruct(); @@ -0,0 +0,0 @@ public class TagParser { public CompoundTag readStruct() throws CommandSyntaxException { @@ -97,21 +97,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return listTag; } } -@@ -0,0 +0,0 @@ public class TagParser { - } - - if (typeReader == ByteTag.TYPE) { -- list.add((T)((NumericTag)tag).getAsByte()); -+ list.add((T)((NumericTag)tag).getAsNumber()); // Paper - decompile fix - } else if (typeReader == LongTag.TYPE) { -- list.add((T)((NumericTag)tag).getAsLong()); -+ list.add((T)((NumericTag)tag).getAsNumber()); // Paper - decompile fix - } else { -- list.add((T)((NumericTag)tag).getAsInt()); -+ list.add((T)((NumericTag)tag).getAsNumber()); // Paper - decompile fix - } - - if (this.hasElementSeparator()) { @@ -0,0 +0,0 @@ public class TagParser { this.reader.skipWhitespace(); this.reader.expect(c); @@ -143,7 +128,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - Count visited parts this.decompose(); - for(FormattedText formattedText : this.decomposedParts) { + for (FormattedText formattedText : this.decomposedParts) { @@ -0,0 +0,0 @@ public class TranslatableContents implements ComponentContents { return Optional.empty(); diff --git a/patches/server/Improved-Watchdog-Support.patch b/patches/server/Improved-Watchdog-Support.patch index d2e51e513..64e2efee4 100644 --- a/patches/server/Improved-Watchdog-Support.patch +++ b/patches/server/Improved-Watchdog-Support.patch @@ -289,7 +289,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (var3.getCause() instanceof ThreadDeath) throw var3; // Paper LOGGER.error(LogUtils.FATAL_MARKER, "Error executing task on {}", this.name(), var3); } - + } 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/Inline-shift-direction-fields.patch b/patches/server/Inline-shift-direction-fields.patch index e7f579cf0..95b4d6b3b 100644 --- a/patches/server/Inline-shift-direction-fields.patch +++ b/patches/server/Inline-shift-direction-fields.patch @@ -11,17 +11,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/core/Direction.java +++ b/src/main/java/net/minecraft/core/Direction.java @@ -0,0 +0,0 @@ public enum Direction implements StringRepresentable { - })).toArray((i) -> { - return new Direction[i]; - }); + .sorted(Comparator.comparingInt(direction -> direction.data2d)) + .toArray(Direction[]::new); + + // Paper start - Perf: Inline shift direction fields + private final int adjX; + private final int adjY; + private final int adjZ; + // Paper end - Perf: Inline shift direction fields - ++ private Direction(int id, int idOpposite, int idHorizontal, String name, Direction.AxisDirection direction, Direction.Axis axis, Vec3i vector) { this.data3d = id; + this.data2d = idHorizontal; @@ -0,0 +0,0 @@ public enum Direction implements StringRepresentable { this.axis = axis; this.axisDirection = direction; diff --git a/patches/server/Lazily-create-LootContext-for-criterions.patch b/patches/server/Lazily-create-LootContext-for-criterions.patch index 3cd6a89c5..3c74f4542 100644 --- a/patches/server/Lazily-create-LootContext-for-criterions.patch +++ b/patches/server/Lazily-create-LootContext-for-criterions.patch @@ -19,7 +19,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + LootContext lootContext = null; // EntityPredicate.createContext(player, player); // Paper - Perf: lazily create LootContext for criterions List> list = null; - for(CriterionTrigger.Listener listener : set) { + for (CriterionTrigger.Listener listener : set) { T simpleInstance = listener.trigger(); if (predicate.test(simpleInstance)) { Optional optional = simpleInstance.player(); diff --git a/patches/server/LootTable-API-and-replenishable-lootables.patch b/patches/server/LootTable-API-and-replenishable-lootables.patch index 5a992e7cd..15bd22ede 100644 --- a/patches/server/LootTable-API-and-replenishable-lootables.patch +++ b/patches/server/LootTable-API-and-replenishable-lootables.patch @@ -606,7 +606,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - } else { - ContainerHelper.saveAllItems(nbt, this.getItemStacks()); } - + ContainerHelper.saveAllItems(nbt, this.getItemStacks()); // Paper - always save the items, table may still remain } @@ -618,7 +617,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - } else { - ContainerHelper.loadAllItems(nbt, this.getItemStacks()); } - + ContainerHelper.loadAllItems(nbt, this.getItemStacks()); // Paper - always load the items, table may still remain } @@ -634,14 +632,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 CriteriaTriggers.GENERATE_LOOT.trigger((ServerPlayer)player, this.getLootTable()); } -- this.setLootTable((ResourceLocation)null); +- this.setLootTable(null); + this.getLootableData().processRefill(player); // Paper - LootParams.Builder builder = (new LootParams.Builder((ServerLevel)this.level())).withParameter(LootContextParams.ORIGIN, this.position()); + LootParams.Builder builder = new LootParams.Builder((ServerLevel)this.level()).withParameter(LootContextParams.ORIGIN, this.position()); if (player != null) { builder.withLuck(player.getLuck()).withParameter(LootContextParams.THIS_ENTITY, player); @@ -0,0 +0,0 @@ public interface ContainerEntity extends Container, MenuProvider { default boolean isChestVehicleStillValid(Player player) { - return !this.isRemoved() && this.position().closerThan(player.position(), 8.0D); + return !this.isRemoved() && this.position().closerThan(player.position(), 8.0); } + // Paper start + default Entity getEntity() { @@ -717,7 +715,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Override public boolean isEmpty() { - this.unpackLootTable((Player)null); + this.unpackLootTable(null); diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBrushableBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBrushableBlock.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBrushableBlock.java diff --git a/patches/server/MC-145656-Fix-Follow-Range-Initial-Target.patch b/patches/server/MC-145656-Fix-Follow-Range-Initial-Target.patch index bc59e9764..e4cb734cc 100644 --- a/patches/server/MC-145656-Fix-Follow-Range-Initial-Target.patch +++ b/patches/server/MC-145656-Fix-Follow-Range-Initial-Target.patch @@ -22,10 +22,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java @@ -0,0 +0,0 @@ public class TargetingConditions { - if (this.range > 0.0D) { - double d = this.testInvisible ? targetEntity.getVisibilityPercent(baseEntity) : 1.0D; -- double e = Math.max(this.range * d, 2.0D); -+ double e = Math.max((this.useFollowRange ? this.getFollowRange(baseEntity) : this.range) * d, 2.0D); // Paper - Fix MC-145656 + if (this.range > 0.0) { + double d = this.testInvisible ? targetEntity.getVisibilityPercent(baseEntity) : 1.0; +- double e = Math.max(this.range * d, 2.0); ++ double e = Math.max((this.useFollowRange ? this.getFollowRange(baseEntity) : this.range) * d, 2.0); // Paper - Fix MC-145656 double f = baseEntity.distanceToSqr(targetEntity.getX(), targetEntity.getY(), targetEntity.getZ()); if (f > e * e) { return false; diff --git a/patches/server/MC-4-Fix-item-position-desync.patch b/patches/server/MC-4-Fix-item-position-desync.patch index e73295dd0..c984de996 100644 --- a/patches/server/MC-4-Fix-item-position-desync.patch +++ b/patches/server/MC-4-Fix-item-position-desync.patch @@ -16,14 +16,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @VisibleForTesting static long encode(double value) { -- return Math.round(value * 4096.0D); -+ return Math.round(value * 4096.0D); // Paper - Fix MC-4; diff on change +- return Math.round(value * 4096.0); ++ return Math.round(value * 4096.0); // Paper - Fix MC-4; diff on change } @VisibleForTesting static double decode(long value) { -- return (double)value / 4096.0D; -+ return (double)value / 4096.0D; // Paper - Fix MC-4; diff on change +- return value / 4096.0; ++ return value / 4096.0; // Paper - Fix MC-4; diff on change } public Vec3 decode(long x, long y, long z) { @@ -39,9 +39,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (this instanceof ItemEntity) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.fixEntityPositionDesync) { + // encode/decode from ClientboundMoveEntityPacket -+ x = Mth.lfloor(x * 4096.0D) * (1 / 4096.0D); -+ y = Mth.lfloor(y * 4096.0D) * (1 / 4096.0D); -+ z = Mth.lfloor(z * 4096.0D) * (1 / 4096.0D); ++ x = Mth.lfloor(x * 4096.0) * (1 / 4096.0); ++ y = Mth.lfloor(y * 4096.0) * (1 / 4096.0); ++ z = Mth.lfloor(z * 4096.0) * (1 / 4096.0); + } + } + // Paper end - Fix MC-4 diff --git a/patches/server/MC-Dev-fixes.patch b/patches/server/MC-Dev-fixes.patch index 3e9c9a43a..21ff1755b 100644 --- a/patches/server/MC-Dev-fixes.patch +++ b/patches/server/MC-Dev-fixes.patch @@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + int u = this.index / i; // Paper - decomp fix + int offsetY = u % j; // Paper - decomp fix + int offsetZ = u / j; // Paper - decomp fix - ++this.index; + this.index++; - return this.cursor.set(startX + i, startY + k, startZ + l); + return this.cursor.set(startX + offsetX, startY + offsetY, startZ + offsetZ); // Paper - decomp fix } @@ -31,77 +31,55 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java +++ b/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java @@ -0,0 +0,0 @@ public class BuiltInRegistries { - LOADERS.put(resourceLocation, () -> { - return initializer.run(registry); - }); -- WRITABLE_REGISTRY.register(key, registry, lifecycle); -+ WRITABLE_REGISTRY.register((ResourceKey) key, registry, lifecycle); // Paper - decompile fix + Bootstrap.checkBootstrapCalled(() -> "registry " + key); + ResourceLocation resourceLocation = key.location(); + LOADERS.put(resourceLocation, () -> initializer.run(registry)); +- WRITABLE_REGISTRY.register((ResourceKey>)key, registry, lifecycle); ++ WRITABLE_REGISTRY.register((ResourceKey)key, registry, lifecycle); // Paper - decompile fix return registry; } +diff --git a/src/main/java/net/minecraft/nbt/TagParser.java b/src/main/java/net/minecraft/nbt/TagParser.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/nbt/TagParser.java ++++ b/src/main/java/net/minecraft/nbt/TagParser.java +@@ -0,0 +0,0 @@ public class TagParser { + } + + if (typeReader == ByteTag.TYPE) { +- list.add((T)((NumericTag)tag).getAsByte()); ++ list.add((T)(Byte)((NumericTag)tag).getAsByte()); // Paper - decompile fix + } else if (typeReader == LongTag.TYPE) { +- list.add((T)((NumericTag)tag).getAsLong()); ++ list.add((T)(Long)((NumericTag)tag).getAsLong()); // Paper - decompile fix + } else { +- list.add((T)((NumericTag)tag).getAsInt()); ++ list.add((T)(Integer)((NumericTag)tag).getAsInt()); // Paper - decompile fix + } + + if (!this.hasElementSeparator()) { diff --git a/src/main/java/net/minecraft/network/ConnectionProtocol.java b/src/main/java/net/minecraft/network/ConnectionProtocol.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/network/ConnectionProtocol.java +++ b/src/main/java/net/minecraft/network/ConnectionProtocol.java @@ -0,0 +0,0 @@ public enum ConnectionProtocol { - PLAY("play", protocol().addFlow(PacketFlow.CLIENTBOUND, (new ConnectionProtocol.PacketSet()).withBundlePacket(ClientboundBundlePacket.class, ClientboundBundlePacket::new).addPacket(ClientboundAddEntityPacket.class, ClientboundAddEntityPacket::new).addPacket(ClientboundAddExperienceOrbPacket.class, ClientboundAddExperienceOrbPacket::new).addPacket(ClientboundAnimatePacket.class, ClientboundAnimatePacket::new).addPacket(ClientboundAwardStatsPacket.class, ClientboundAwardStatsPacket::new).addPacket(ClientboundBlockChangedAckPacket.class, ClientboundBlockChangedAckPacket::new).addPacket(ClientboundBlockDestructionPacket.class, ClientboundBlockDestructionPacket::new).addPacket(ClientboundBlockEntityDataPacket.class, ClientboundBlockEntityDataPacket::new).addPacket(ClientboundBlockEventPacket.class, ClientboundBlockEventPacket::new).addPacket(ClientboundBlockUpdatePacket.class, ClientboundBlockUpdatePacket::new).addPacket(ClientboundBossEventPacket.class, ClientboundBossEventPacket::new).addPacket(ClientboundChangeDifficultyPacket.class, ClientboundChangeDifficultyPacket::new).addPacket(ClientboundChunkBatchFinishedPacket.class, ClientboundChunkBatchFinishedPacket::new).addPacket(ClientboundChunkBatchStartPacket.class, ClientboundChunkBatchStartPacket::new).addPacket(ClientboundChunksBiomesPacket.class, ClientboundChunksBiomesPacket::new).addPacket(ClientboundClearTitlesPacket.class, ClientboundClearTitlesPacket::new).addPacket(ClientboundCommandSuggestionsPacket.class, ClientboundCommandSuggestionsPacket::new).addPacket(ClientboundCommandsPacket.class, ClientboundCommandsPacket::new).addPacket(ClientboundContainerClosePacket.class, ClientboundContainerClosePacket::new).addPacket(ClientboundContainerSetContentPacket.class, ClientboundContainerSetContentPacket::new).addPacket(ClientboundContainerSetDataPacket.class, ClientboundContainerSetDataPacket::new).addPacket(ClientboundContainerSetSlotPacket.class, ClientboundContainerSetSlotPacket::new).addPacket(ClientboundCooldownPacket.class, ClientboundCooldownPacket::new).addPacket(ClientboundCustomChatCompletionsPacket.class, ClientboundCustomChatCompletionsPacket::new).addPacket(ClientboundCustomPayloadPacket.class, ClientboundCustomPayloadPacket::new).addPacket(ClientboundDamageEventPacket.class, ClientboundDamageEventPacket::new).addPacket(ClientboundDeleteChatPacket.class, ClientboundDeleteChatPacket::new).addPacket(ClientboundDisconnectPacket.class, ClientboundDisconnectPacket::new).addPacket(ClientboundDisguisedChatPacket.class, ClientboundDisguisedChatPacket::new).addPacket(ClientboundEntityEventPacket.class, ClientboundEntityEventPacket::new).addPacket(ClientboundExplodePacket.class, ClientboundExplodePacket::new).addPacket(ClientboundForgetLevelChunkPacket.class, ClientboundForgetLevelChunkPacket::new).addPacket(ClientboundGameEventPacket.class, ClientboundGameEventPacket::new).addPacket(ClientboundHorseScreenOpenPacket.class, ClientboundHorseScreenOpenPacket::new).addPacket(ClientboundHurtAnimationPacket.class, ClientboundHurtAnimationPacket::new).addPacket(ClientboundInitializeBorderPacket.class, ClientboundInitializeBorderPacket::new).addPacket(ClientboundKeepAlivePacket.class, ClientboundKeepAlivePacket::new).addPacket(ClientboundLevelChunkWithLightPacket.class, ClientboundLevelChunkWithLightPacket::new).addPacket(ClientboundLevelEventPacket.class, ClientboundLevelEventPacket::new).addPacket(ClientboundLevelParticlesPacket.class, ClientboundLevelParticlesPacket::new).addPacket(ClientboundLightUpdatePacket.class, ClientboundLightUpdatePacket::new).addPacket(ClientboundLoginPacket.class, ClientboundLoginPacket::new).addPacket(ClientboundMapItemDataPacket.class, ClientboundMapItemDataPacket::new).addPacket(ClientboundMerchantOffersPacket.class, ClientboundMerchantOffersPacket::new).addPacket(ClientboundMoveEntityPacket.Pos.class, ClientboundMoveEntityPacket.Pos::read).addPacket(ClientboundMoveEntityPacket.PosRot.class, ClientboundMoveEntityPacket.PosRot::read).addPacket(ClientboundMoveEntityPacket.Rot.class, ClientboundMoveEntityPacket.Rot::read).addPacket(ClientboundMoveVehiclePacket.class, ClientboundMoveVehiclePacket::new).addPacket(ClientboundOpenBookPacket.class, ClientboundOpenBookPacket::new).addPacket(ClientboundOpenScreenPacket.class, ClientboundOpenScreenPacket::new).addPacket(ClientboundOpenSignEditorPacket.class, ClientboundOpenSignEditorPacket::new).addPacket(ClientboundPingPacket.class, ClientboundPingPacket::new).addPacket(ClientboundPongResponsePacket.class, ClientboundPongResponsePacket::new).addPacket(ClientboundPlaceGhostRecipePacket.class, ClientboundPlaceGhostRecipePacket::new).addPacket(ClientboundPlayerAbilitiesPacket.class, ClientboundPlayerAbilitiesPacket::new).addPacket(ClientboundPlayerChatPacket.class, ClientboundPlayerChatPacket::new).addPacket(ClientboundPlayerCombatEndPacket.class, ClientboundPlayerCombatEndPacket::new).addPacket(ClientboundPlayerCombatEnterPacket.class, ClientboundPlayerCombatEnterPacket::new).addPacket(ClientboundPlayerCombatKillPacket.class, ClientboundPlayerCombatKillPacket::new).addPacket(ClientboundPlayerInfoRemovePacket.class, ClientboundPlayerInfoRemovePacket::new).addPacket(ClientboundPlayerInfoUpdatePacket.class, ClientboundPlayerInfoUpdatePacket::new).addPacket(ClientboundPlayerLookAtPacket.class, ClientboundPlayerLookAtPacket::new).addPacket(ClientboundPlayerPositionPacket.class, ClientboundPlayerPositionPacket::new).addPacket(ClientboundRecipePacket.class, ClientboundRecipePacket::new).addPacket(ClientboundRemoveEntitiesPacket.class, ClientboundRemoveEntitiesPacket::new).addPacket(ClientboundRemoveMobEffectPacket.class, ClientboundRemoveMobEffectPacket::new).addPacket(ClientboundResetScorePacket.class, ClientboundResetScorePacket::new).addPacket(ClientboundResourcePackPopPacket.class, ClientboundResourcePackPopPacket::new).addPacket(ClientboundResourcePackPushPacket.class, ClientboundResourcePackPushPacket::new).addPacket(ClientboundRespawnPacket.class, ClientboundRespawnPacket::new).addPacket(ClientboundRotateHeadPacket.class, ClientboundRotateHeadPacket::new).addPacket(ClientboundSectionBlocksUpdatePacket.class, ClientboundSectionBlocksUpdatePacket::new).addPacket(ClientboundSelectAdvancementsTabPacket.class, ClientboundSelectAdvancementsTabPacket::new).addPacket(ClientboundServerDataPacket.class, ClientboundServerDataPacket::new).addPacket(ClientboundSetActionBarTextPacket.class, ClientboundSetActionBarTextPacket::new).addPacket(ClientboundSetBorderCenterPacket.class, ClientboundSetBorderCenterPacket::new).addPacket(ClientboundSetBorderLerpSizePacket.class, ClientboundSetBorderLerpSizePacket::new).addPacket(ClientboundSetBorderSizePacket.class, ClientboundSetBorderSizePacket::new).addPacket(ClientboundSetBorderWarningDelayPacket.class, ClientboundSetBorderWarningDelayPacket::new).addPacket(ClientboundSetBorderWarningDistancePacket.class, ClientboundSetBorderWarningDistancePacket::new).addPacket(ClientboundSetCameraPacket.class, ClientboundSetCameraPacket::new).addPacket(ClientboundSetCarriedItemPacket.class, ClientboundSetCarriedItemPacket::new).addPacket(ClientboundSetChunkCacheCenterPacket.class, ClientboundSetChunkCacheCenterPacket::new).addPacket(ClientboundSetChunkCacheRadiusPacket.class, ClientboundSetChunkCacheRadiusPacket::new).addPacket(ClientboundSetDefaultSpawnPositionPacket.class, ClientboundSetDefaultSpawnPositionPacket::new).addPacket(ClientboundSetDisplayObjectivePacket.class, ClientboundSetDisplayObjectivePacket::new).addPacket(ClientboundSetEntityDataPacket.class, ClientboundSetEntityDataPacket::new).addPacket(ClientboundSetEntityLinkPacket.class, ClientboundSetEntityLinkPacket::new).addPacket(ClientboundSetEntityMotionPacket.class, ClientboundSetEntityMotionPacket::new).addPacket(ClientboundSetEquipmentPacket.class, ClientboundSetEquipmentPacket::new).addPacket(ClientboundSetExperiencePacket.class, ClientboundSetExperiencePacket::new).addPacket(ClientboundSetHealthPacket.class, ClientboundSetHealthPacket::new).addPacket(ClientboundSetObjectivePacket.class, ClientboundSetObjectivePacket::new).addPacket(ClientboundSetPassengersPacket.class, ClientboundSetPassengersPacket::new).addPacket(ClientboundSetPlayerTeamPacket.class, ClientboundSetPlayerTeamPacket::new).addPacket(ClientboundSetScorePacket.class, ClientboundSetScorePacket::new).addPacket(ClientboundSetSimulationDistancePacket.class, ClientboundSetSimulationDistancePacket::new).addPacket(ClientboundSetSubtitleTextPacket.class, ClientboundSetSubtitleTextPacket::new).addPacket(ClientboundSetTimePacket.class, ClientboundSetTimePacket::new).addPacket(ClientboundSetTitleTextPacket.class, ClientboundSetTitleTextPacket::new).addPacket(ClientboundSetTitlesAnimationPacket.class, ClientboundSetTitlesAnimationPacket::new).addPacket(ClientboundSoundEntityPacket.class, ClientboundSoundEntityPacket::new).addPacket(ClientboundSoundPacket.class, ClientboundSoundPacket::new).addPacket(ClientboundStartConfigurationPacket.class, ClientboundStartConfigurationPacket::new).addPacket(ClientboundStopSoundPacket.class, ClientboundStopSoundPacket::new).addPacket(ClientboundSystemChatPacket.class, ClientboundSystemChatPacket::new).addPacket(ClientboundTabListPacket.class, ClientboundTabListPacket::new).addPacket(ClientboundTagQueryPacket.class, ClientboundTagQueryPacket::new).addPacket(ClientboundTakeItemEntityPacket.class, ClientboundTakeItemEntityPacket::new).addPacket(ClientboundTeleportEntityPacket.class, ClientboundTeleportEntityPacket::new).addPacket(ClientboundTickingStatePacket.class, ClientboundTickingStatePacket::new).addPacket(ClientboundTickingStepPacket.class, ClientboundTickingStepPacket::new).addPacket(ClientboundUpdateAdvancementsPacket.class, ClientboundUpdateAdvancementsPacket::new).addPacket(ClientboundUpdateAttributesPacket.class, ClientboundUpdateAttributesPacket::new).addPacket(ClientboundUpdateMobEffectPacket.class, ClientboundUpdateMobEffectPacket::new).addPacket(ClientboundUpdateRecipesPacket.class, ClientboundUpdateRecipesPacket::new).addPacket(ClientboundUpdateTagsPacket.class, ClientboundUpdateTagsPacket::new)).addFlow(PacketFlow.SERVERBOUND, (new ConnectionProtocol.PacketSet()).addPacket(ServerboundAcceptTeleportationPacket.class, ServerboundAcceptTeleportationPacket::new).addPacket(ServerboundBlockEntityTagQuery.class, ServerboundBlockEntityTagQuery::new).addPacket(ServerboundChangeDifficultyPacket.class, ServerboundChangeDifficultyPacket::new).addPacket(ServerboundChatAckPacket.class, ServerboundChatAckPacket::new).addPacket(ServerboundChatCommandPacket.class, ServerboundChatCommandPacket::new).addPacket(ServerboundChatPacket.class, ServerboundChatPacket::new).addPacket(ServerboundChatSessionUpdatePacket.class, ServerboundChatSessionUpdatePacket::new).addPacket(ServerboundChunkBatchReceivedPacket.class, ServerboundChunkBatchReceivedPacket::new).addPacket(ServerboundClientCommandPacket.class, ServerboundClientCommandPacket::new).addPacket(ServerboundClientInformationPacket.class, ServerboundClientInformationPacket::new).addPacket(ServerboundCommandSuggestionPacket.class, ServerboundCommandSuggestionPacket::new).addPacket(ServerboundConfigurationAcknowledgedPacket.class, ServerboundConfigurationAcknowledgedPacket::new).addPacket(ServerboundContainerButtonClickPacket.class, ServerboundContainerButtonClickPacket::new).addPacket(ServerboundContainerClickPacket.class, ServerboundContainerClickPacket::new).addPacket(ServerboundContainerClosePacket.class, ServerboundContainerClosePacket::new).addPacket(ServerboundContainerSlotStateChangedPacket.class, ServerboundContainerSlotStateChangedPacket::new).addPacket(ServerboundCustomPayloadPacket.class, ServerboundCustomPayloadPacket::new).addPacket(ServerboundEditBookPacket.class, ServerboundEditBookPacket::new).addPacket(ServerboundEntityTagQuery.class, ServerboundEntityTagQuery::new).addPacket(ServerboundInteractPacket.class, ServerboundInteractPacket::new).addPacket(ServerboundJigsawGeneratePacket.class, ServerboundJigsawGeneratePacket::new).addPacket(ServerboundKeepAlivePacket.class, ServerboundKeepAlivePacket::new).addPacket(ServerboundLockDifficultyPacket.class, ServerboundLockDifficultyPacket::new).addPacket(ServerboundMovePlayerPacket.Pos.class, ServerboundMovePlayerPacket.Pos::read).addPacket(ServerboundMovePlayerPacket.PosRot.class, ServerboundMovePlayerPacket.PosRot::read).addPacket(ServerboundMovePlayerPacket.Rot.class, ServerboundMovePlayerPacket.Rot::read).addPacket(ServerboundMovePlayerPacket.StatusOnly.class, ServerboundMovePlayerPacket.StatusOnly::read).addPacket(ServerboundMoveVehiclePacket.class, ServerboundMoveVehiclePacket::new).addPacket(ServerboundPaddleBoatPacket.class, ServerboundPaddleBoatPacket::new).addPacket(ServerboundPickItemPacket.class, ServerboundPickItemPacket::new).addPacket(ServerboundPingRequestPacket.class, ServerboundPingRequestPacket::new).addPacket(ServerboundPlaceRecipePacket.class, ServerboundPlaceRecipePacket::new).addPacket(ServerboundPlayerAbilitiesPacket.class, ServerboundPlayerAbilitiesPacket::new).addPacket(ServerboundPlayerActionPacket.class, ServerboundPlayerActionPacket::new).addPacket(ServerboundPlayerCommandPacket.class, ServerboundPlayerCommandPacket::new).addPacket(ServerboundPlayerInputPacket.class, ServerboundPlayerInputPacket::new).addPacket(ServerboundPongPacket.class, ServerboundPongPacket::new).addPacket(ServerboundRecipeBookChangeSettingsPacket.class, ServerboundRecipeBookChangeSettingsPacket::new).addPacket(ServerboundRecipeBookSeenRecipePacket.class, ServerboundRecipeBookSeenRecipePacket::new).addPacket(ServerboundRenameItemPacket.class, ServerboundRenameItemPacket::new).addPacket(ServerboundResourcePackPacket.class, ServerboundResourcePackPacket::new).addPacket(ServerboundSeenAdvancementsPacket.class, ServerboundSeenAdvancementsPacket::new).addPacket(ServerboundSelectTradePacket.class, ServerboundSelectTradePacket::new).addPacket(ServerboundSetBeaconPacket.class, ServerboundSetBeaconPacket::new).addPacket(ServerboundSetCarriedItemPacket.class, ServerboundSetCarriedItemPacket::new).addPacket(ServerboundSetCommandBlockPacket.class, ServerboundSetCommandBlockPacket::new).addPacket(ServerboundSetCommandMinecartPacket.class, ServerboundSetCommandMinecartPacket::new).addPacket(ServerboundSetCreativeModeSlotPacket.class, ServerboundSetCreativeModeSlotPacket::new).addPacket(ServerboundSetJigsawBlockPacket.class, ServerboundSetJigsawBlockPacket::new).addPacket(ServerboundSetStructureBlockPacket.class, ServerboundSetStructureBlockPacket::new).addPacket(ServerboundSignUpdatePacket.class, ServerboundSignUpdatePacket::new).addPacket(ServerboundSwingPacket.class, ServerboundSwingPacket::new).addPacket(ServerboundTeleportToEntityPacket.class, ServerboundTeleportToEntityPacket::new).addPacket(ServerboundUseItemOnPacket.class, ServerboundUseItemOnPacket::new).addPacket(ServerboundUseItemPacket.class, ServerboundUseItemPacket::new))), - STATUS("status", protocol().addFlow(PacketFlow.SERVERBOUND, (new ConnectionProtocol.PacketSet()).addPacket(ServerboundStatusRequestPacket.class, ServerboundStatusRequestPacket::new).addPacket(ServerboundPingRequestPacket.class, ServerboundPingRequestPacket::new)).addFlow(PacketFlow.CLIENTBOUND, (new ConnectionProtocol.PacketSet()).addPacket(ClientboundStatusResponsePacket.class, ClientboundStatusResponsePacket::new).addPacket(ClientboundPongResponsePacket.class, ClientboundPongResponsePacket::new))), - LOGIN("login", protocol().addFlow(PacketFlow.CLIENTBOUND, (new ConnectionProtocol.PacketSet()).addPacket(ClientboundLoginDisconnectPacket.class, ClientboundLoginDisconnectPacket::new).addPacket(ClientboundHelloPacket.class, ClientboundHelloPacket::new).addPacket(ClientboundGameProfilePacket.class, ClientboundGameProfilePacket::new).addPacket(ClientboundLoginCompressionPacket.class, ClientboundLoginCompressionPacket::new).addPacket(ClientboundCustomQueryPacket.class, ClientboundCustomQueryPacket::new)).addFlow(PacketFlow.SERVERBOUND, (new ConnectionProtocol.PacketSet()).addPacket(ServerboundHelloPacket.class, ServerboundHelloPacket::new).addPacket(ServerboundKeyPacket.class, ServerboundKeyPacket::new).addPacket(ServerboundCustomQueryAnswerPacket.class, ServerboundCustomQueryAnswerPacket::read).addPacket(ServerboundLoginAcknowledgedPacket.class, ServerboundLoginAcknowledgedPacket::new))), -- CONFIGURATION("configuration", protocol().addFlow(PacketFlow.CLIENTBOUND, (new ConnectionProtocol.PacketSet()).addPacket(ClientboundCustomPayloadPacket.class, ClientboundCustomPayloadPacket::new).addPacket(ClientboundDisconnectPacket.class, ClientboundDisconnectPacket::new).addPacket(ClientboundFinishConfigurationPacket.class, ClientboundFinishConfigurationPacket::new).addPacket(ClientboundKeepAlivePacket.class, ClientboundKeepAlivePacket::new).addPacket(ClientboundPingPacket.class, ClientboundPingPacket::new).addPacket(ClientboundRegistryDataPacket.class, ClientboundRegistryDataPacket::new).addPacket(ClientboundResourcePackPopPacket.class, ClientboundResourcePackPopPacket::new).addPacket(ClientboundResourcePackPushPacket.class, ClientboundResourcePackPushPacket::new).addPacket(ClientboundUpdateEnabledFeaturesPacket.class, ClientboundUpdateEnabledFeaturesPacket::new).addPacket(ClientboundUpdateTagsPacket.class, ClientboundUpdateTagsPacket::new)).addFlow(PacketFlow.SERVERBOUND, (new ConnectionProtocol.PacketSet()).addPacket(ServerboundClientInformationPacket.class, ServerboundClientInformationPacket::new).addPacket(ServerboundCustomPayloadPacket.class, ServerboundCustomPayloadPacket::new).addPacket(ServerboundFinishConfigurationPacket.class, ServerboundFinishConfigurationPacket::new).addPacket(ServerboundKeepAlivePacket.class, ServerboundKeepAlivePacket::new).addPacket(ServerboundPongPacket.class, ServerboundPongPacket::new).addPacket(ServerboundResourcePackPacket.class, ServerboundResourcePackPacket::new))); -+ CONFIGURATION("configuration", protocol().addFlow(PacketFlow.CLIENTBOUND, (new ConnectionProtocol.PacketSet()).addPacket(ClientboundCustomPayloadPacket.class, ClientboundCustomPayloadPacket::new).addPacket(ClientboundDisconnectPacket.class, ClientboundDisconnectPacket::new).addPacket(ClientboundFinishConfigurationPacket.class, ClientboundFinishConfigurationPacket::new).addPacket(ClientboundKeepAlivePacket.class, ClientboundKeepAlivePacket::new).addPacket(ClientboundPingPacket.class, ClientboundPingPacket::new).addPacket(ClientboundRegistryDataPacket.class, ClientboundRegistryDataPacket::new).addPacket(ClientboundResourcePackPopPacket.class, ClientboundResourcePackPopPacket::new).addPacket(ClientboundResourcePackPushPacket.class, ClientboundResourcePackPushPacket::new).addPacket(ClientboundUpdateEnabledFeaturesPacket.class, ClientboundUpdateEnabledFeaturesPacket::new).addPacket(ClientboundUpdateTagsPacket.class, ClientboundUpdateTagsPacket::new)).addFlow(PacketFlow.SERVERBOUND, (new ConnectionProtocol.PacketSet()).addPacket(ServerboundClientInformationPacket.class, ServerboundClientInformationPacket::new).addPacket(ServerboundCustomPayloadPacket.class, ServerboundCustomPayloadPacket::new).addPacket(ServerboundFinishConfigurationPacket.class, ServerboundFinishConfigurationPacket::new).addPacket(ServerboundKeepAlivePacket.class, ServerboundKeepAlivePacket::new).addPacket(ServerboundPongPacket.class, ServerboundPongPacket::new).addPacket(ServerboundResourcePackPacket.class, ServerboundResourcePackPacket::new))); // Paper - decompile fix - - public static final int NOT_REGISTERED = -1; - private final String id; -diff --git a/src/main/java/net/minecraft/network/chat/ComponentSerialization.java b/src/main/java/net/minecraft/network/chat/ComponentSerialization.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/network/chat/ComponentSerialization.java -+++ b/src/main/java/net/minecraft/network/chat/ComponentSerialization.java -@@ -0,0 +0,0 @@ public class ComponentSerialization { - for(MapDecoder mapDecoder : this.codecs) { - DataResult dataResult = mapDecoder.decode(dynamicOps, mapLike); - if (dataResult.result().isPresent()) { -- return dataResult; -+ return (DataResult) dataResult; // Paper - decomp fix - } - } - -@@ -0,0 +0,0 @@ public class ComponentSerialization { - } - - public RecordBuilder encode(T object, DynamicOps dynamicOps, RecordBuilder recordBuilder) { -- MapEncoder mapEncoder = this.encoderGetter.apply(object); -+ MapEncoder mapEncoder = (MapEncoder) this.encoderGetter.apply(object); // Paper - decomp fix - return mapEncoder.encode(object, dynamicOps, recordBuilder); - } - -diff --git a/src/main/java/net/minecraft/network/chat/ComponentUtils.java b/src/main/java/net/minecraft/network/chat/ComponentUtils.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/network/chat/ComponentUtils.java -+++ b/src/main/java/net/minecraft/network/chat/ComponentUtils.java -@@ -0,0 +0,0 @@ public class ComponentUtils { - ComponentContents string = text.getContents(); - if (string instanceof TranslatableContents) { - TranslatableContents translatableContents = (TranslatableContents)string; -- String string = translatableContents.getKey(); - String string2 = translatableContents.getFallback(); -- return string2 != null || Language.getInstance().has(string); -+ return string2 != null || Language.getInstance().has(translatableContents.getKey()); // Paper - decompile fix - } - } - -diff --git a/src/main/java/net/minecraft/resources/RegistryDataLoader.java b/src/main/java/net/minecraft/resources/RegistryDataLoader.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/resources/RegistryDataLoader.java -+++ b/src/main/java/net/minecraft/resources/RegistryDataLoader.java -@@ -0,0 +0,0 @@ public class RegistryDataLoader { - return new RegistryOps.RegistryInfoLookup() { - @Override - public Optional> lookup(ResourceKey> registryRef) { -- return Optional.ofNullable(map.get(registryRef)); -+ return Optional.ofNullable((RegistryOps.RegistryInfo) map.get(registryRef)); // Paper - decompile fix - } - }; - } + protocol() + .addFlow( + PacketFlow.CLIENTBOUND, +- new ConnectionProtocol.PacketSet() ++ new ConnectionProtocol.PacketSet() // Paper - decompile fix + .addPacket(ClientboundCustomPayloadPacket.class, ClientboundCustomPayloadPacket::new) + .addPacket(ClientboundDisconnectPacket.class, ClientboundDisconnectPacket::new) + .addPacket(ClientboundFinishConfigurationPacket.class, ClientboundFinishConfigurationPacket::new) +@@ -0,0 +0,0 @@ public enum ConnectionProtocol { + ) + .addFlow( + PacketFlow.SERVERBOUND, +- new ConnectionProtocol.PacketSet() ++ new ConnectionProtocol.PacketSet() // Paper - decompile fix + .addPacket(ServerboundClientInformationPacket.class, ServerboundClientInformationPacket::new) + .addPacket(ServerboundCustomPayloadPacket.class, ServerboundCustomPayloadPacket::new) + .addPacket(ServerboundFinishConfigurationPacket.class, ServerboundFinishConfigurationPacket::new) diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java @@ -115,19 +93,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 }, this).thenCompose((immutablelist) -> { MultiPackResourceManager resourcemanager = new MultiPackResourceManager(PackType.SERVER_DATA, immutablelist); -diff --git a/src/main/java/net/minecraft/server/level/Ticket.java b/src/main/java/net/minecraft/server/level/Ticket.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/level/Ticket.java -+++ b/src/main/java/net/minecraft/server/level/Ticket.java -@@ -0,0 +0,0 @@ public final class Ticket implements Comparable> { - return i; - } else { - int j = Integer.compare(System.identityHashCode(this.type), System.identityHashCode(ticket.type)); -- return j != 0 ? j : this.type.getComparator().compare(this.key, ticket.key); -+ return j != 0 ? j : this.type.getComparator().compare(this.key, (T)ticket.key); // Paper - decompile fix - } - } - diff --git a/src/main/java/net/minecraft/util/SortedArraySet.java b/src/main/java/net/minecraft/util/SortedArraySet.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/util/SortedArraySet.java @@ -141,32 +106,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } public static SortedArraySet create(Comparator comparator) { -diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java -+++ b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java -@@ -0,0 +0,0 @@ public class Frog extends Animal implements VariantHolder { - - @Override - public Brain getBrain() { -- return super.getBrain(); -+ return (Brain) super.getBrain(); // Paper - decompile fix - } - - @Override -diff --git a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java -+++ b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java -@@ -0,0 +0,0 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { - - @Override - public Brain getBrain() { -- return super.getBrain(); -+ return (Brain) super.getBrain(); // Paper - decompile fix - } - - @Override diff --git a/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java b/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java @@ -180,42 +119,3 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 })); this.byName = Maps.newHashMap(builder.build()); // CraftBukkit RecipeManager.LOGGER.info("Loaded {} recipes", map1.size()); -diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- 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 implements PaletteResize, PalettedContainer - } - - private static > Codec codec(IdMap idList, Codec entryCodec, PalettedContainer.Strategy provider, T defaultValue, PalettedContainerRO.Unpacker reader) { -- return RecordCodecBuilder.create((instance) -> { -+ return RecordCodecBuilder.>create((instance) -> { // Paper - decompile fix - return instance.group(entryCodec.mapResult(ExtraCodecs.orElsePartial(defaultValue)).listOf().fieldOf("palette").forGetter(PalettedContainerRO.PackedData::paletteEntries), Codec.LONG_STREAM.optionalFieldOf("data").forGetter(PalettedContainerRO.PackedData::storage)).apply(instance, PalettedContainerRO.PackedData::new); - }).comapFlatMap((serialized) -> { - return reader.read(idList, provider, serialized); -diff --git a/src/main/java/net/minecraft/world/level/entity/EntityLookup.java b/src/main/java/net/minecraft/world/level/entity/EntityLookup.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/world/level/entity/EntityLookup.java -+++ b/src/main/java/net/minecraft/world/level/entity/EntityLookup.java -@@ -0,0 +0,0 @@ public class EntityLookup { - public void getEntities(EntityTypeTest filter, AbortableIterationConsumer consumer) { - for(T entityAccess : this.byId.values()) { - U entityAccess2 = (U)((EntityAccess)filter.tryCast(entityAccess)); -- if (entityAccess2 != null && consumer.accept((T)entityAccess2).shouldAbort()) { -+ if (entityAccess2 != null && consumer.accept(entityAccess2).shouldAbort()) { // Paper - decompile fix - return; - } - } -diff --git a/src/main/java/net/minecraft/world/level/entity/EntitySection.java b/src/main/java/net/minecraft/world/level/entity/EntitySection.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/world/level/entity/EntitySection.java -+++ b/src/main/java/net/minecraft/world/level/entity/EntitySection.java -@@ -0,0 +0,0 @@ public class EntitySection { - } else { - for(T entityAccess : collection) { - U entityAccess2 = (U)((EntityAccess)type.tryCast(entityAccess)); -- if (entityAccess2 != null && entityAccess.getBoundingBox().intersects(box) && consumer.accept((T)entityAccess2).shouldAbort()) { -+ if (entityAccess2 != null && entityAccess.getBoundingBox().intersects(box) && consumer.accept(entityAccess2).shouldAbort()) { // Paper - decompile fix - return AbortableIterationConsumer.Continuation.ABORT; - } - } diff --git a/patches/server/MC-Utils.patch b/patches/server/MC-Utils.patch index 59b880ddd..6a69de83f 100644 --- a/patches/server/MC-Utils.patch +++ b/patches/server/MC-Utils.patch @@ -7040,8 +7040,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java +++ b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java @@ -0,0 +0,0 @@ public abstract class BlockableEventLoop implements Profiler + runnable.run(); } - } + // Paper start + public void scheduleOnMain(Runnable r0) { @@ -7360,9 +7360,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Nullable ChunkAccess getChunkIfLoadedImmediately(int x, int z); // Paper - ifLoaded api (we need this since current impl blocks if the chunk is loading) + @Nullable default ChunkAccess getChunkIfLoadedImmediately(BlockPos pos) { return this.getChunkIfLoadedImmediately(pos.getX() >> 4, pos.getZ() >> 4);} + - /** @deprecated */ @Deprecated boolean hasChunk(int chunkX, int chunkZ); + diff --git a/src/main/java/net/minecraft/world/level/PathNavigationRegion.java b/src/main/java/net/minecraft/world/level/PathNavigationRegion.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/PathNavigationRegion.java diff --git a/patches/server/Make-water-animal-spawn-height-configurable.patch b/patches/server/Make-water-animal-spawn-height-configurable.patch index 46015998e..205b44d68 100644 --- a/patches/server/Make-water-animal-spawn-height-configurable.patch +++ b/patches/server/Make-water-animal-spawn-height-configurable.patch @@ -9,7 +9,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java +++ b/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java @@ -0,0 +0,0 @@ public abstract class WaterAnimal extends PathfinderMob { - public static boolean checkSurfaceWaterAnimalSpawnRules(EntityType type, LevelAccessor world, MobSpawnType reason, BlockPos pos, RandomSource random) { + ) { int i = world.getSeaLevel(); int j = i - 13; + // Paper start - Make water animal spawn height configurable diff --git a/patches/server/Manually-inline-methods-in-BlockPosition.patch b/patches/server/Manually-inline-methods-in-BlockPosition.patch index 70e4fb4ff..9fee55062 100644 --- a/patches/server/Manually-inline-methods-in-BlockPosition.patch +++ b/patches/server/Manually-inline-methods-in-BlockPosition.patch @@ -49,8 +49,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/core/Vec3i.java +++ b/src/main/java/net/minecraft/core/Vec3i.java @@ -0,0 +0,0 @@ public class Vec3i implements Comparable { - return IntStream.of(vec.getX(), vec.getY(), vec.getZ()); - }); + vec -> IntStream.of(vec.getX(), vec.getY(), vec.getZ()) + ); public static final Vec3i ZERO = new Vec3i(0, 0, 0); - private int x; - private int y; @@ -60,4 +60,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + protected int z; // Paper - Perf: Manually inline methods in BlockPosition; protected public static Codec offsetCodec(int maxAbsValue) { - return ExtraCodecs.validate(CODEC, (vec) -> { + return ExtraCodecs.validate( diff --git a/patches/server/Missing-effect-cause.patch b/patches/server/Missing-effect-cause.patch index e549a6be6..9ffa0fd48 100644 --- a/patches/server/Missing-effect-cause.patch +++ b/patches/server/Missing-effect-cause.patch @@ -35,11 +35,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/item/SuspiciousStewItem.java +++ b/src/main/java/net/minecraft/world/item/SuspiciousStewItem.java @@ -0,0 +0,0 @@ public class SuspiciousStewItem extends Item { + @Override public ItemStack finishUsingItem(ItemStack stack, Level world, LivingEntity user) { ItemStack itemStack = super.finishUsingItem(stack, world, user); - listPotionEffects(itemStack, (effect) -> { -- user.addEffect(effect.createEffectInstance()); -+ user.addEffect(effect.createEffectInstance(), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD); // Paper - Add missing effect cause - }); +- listPotionEffects(itemStack, effect -> user.addEffect(effect.createEffectInstance())); ++ listPotionEffects(itemStack, effect -> user.addEffect(effect.createEffectInstance(), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD)); // Paper - Add missing effect cause return user instanceof Player && ((Player)user).getAbilities().instabuild ? itemStack : new ItemStack(Items.BOWL); } + } diff --git a/patches/server/Multiple-Entries-with-Scoreboards.patch b/patches/server/Multiple-Entries-with-Scoreboards.patch index 11c79fdbb..ad0e6c847 100644 --- a/patches/server/Multiple-Entries-with-Scoreboards.patch +++ b/patches/server/Multiple-Entries-with-Scoreboards.patch @@ -9,7 +9,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java @@ -0,0 +0,0 @@ public class ClientboundSetPlayerTeamPacket implements Packet property = (Property)object; -- return this.clazz.equals(property.clazz) && this.name.equals(property.name); -- } +- return this == object || object instanceof Property property && this.clazz.equals(property.clazz) && this.name.equals(property.name); + return this == object; // Paper - Perf: Optimize hashCode/equals } diff --git a/patches/server/Optimise-general-POI-access.patch b/patches/server/Optimise-general-POI-access.patch index 3f11b1bde..74db7a83d 100644 --- a/patches/server/Optimise-general-POI-access.patch +++ b/patches/server/Optimise-general-POI-access.patch @@ -845,18 +845,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java @@ -0,0 +0,0 @@ public class AcquirePoi { - return true; - } - }; -- Set, BlockPos>> set = poiManager.findAllClosestFirstWithType(poiPredicate, predicate2, entity.blockPosition(), 48, PoiManager.Occupancy.HAS_SPACE).limit(5L).collect(Collectors.toSet()); -+ // Paper start - optimise POI access -+ java.util.List, BlockPos>> poiposes = new java.util.ArrayList<>(); -+ io.papermc.paper.util.PoiAccess.findNearestPoiPositions(poiManager, poiPredicate, predicate2, entity.blockPosition(), 48, 48*48, PoiManager.Occupancy.HAS_SPACE, false, 5, poiposes); -+ Set, BlockPos>> set = new java.util.HashSet<>(poiposes); -+ // Paper end - optimise POI access - Path path = findPathToPois(entity, set); - if (path != null && path.canReach()) { - BlockPos blockPos = path.getTarget(); + return true; + } + }; +- Set, BlockPos>> set = poiManager.findAllClosestFirstWithType( +- poiPredicate, predicate2, entity.blockPosition(), 48, PoiManager.Occupancy.HAS_SPACE +- ) +- .limit(5L) +- .collect(Collectors.toSet()); ++ // Paper start - optimise POI access ++ java.util.List, BlockPos>> poiposes = new java.util.ArrayList<>(); ++ io.papermc.paper.util.PoiAccess.findNearestPoiPositions(poiManager, poiPredicate, predicate2, entity.blockPosition(), 48, 48*48, PoiManager.Occupancy.HAS_SPACE, false, 5, poiposes); ++ Set, BlockPos>> set = new java.util.HashSet<>(poiposes); ++ // Paper end - optimise POI access + Path path = findPathToPois(entity, set); + if (path != null && path.canReach()) { + BlockPos blockPos = path.getTarget(); diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java @@ -865,9 +869,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return true; } }; -- Set, BlockPos>> set = poiManager.findAllWithType((holder) -> { -- return holder.is(PoiTypes.HOME); -- }, predicate, entity.blockPosition(), 48, PoiManager.Occupancy.ANY).collect(Collectors.toSet()); +- Set, BlockPos>> set = poiManager.findAllWithType( +- holder -> holder.is(PoiTypes.HOME), predicate, entity.blockPosition(), 48, PoiManager.Occupancy.ANY +- ) +- .collect(Collectors.toSet()); - Path path = AcquirePoi.findPathToPois(entity, set); + // Paper start - optimise POI access + java.util.List, BlockPos>> poiposes = new java.util.ArrayList<>(); @@ -883,9 +888,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java +++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java @@ -0,0 +0,0 @@ public class PoiManager extends SectionStorage { - } - - public Optional find(Predicate> typePredicate, Predicate posPredicate, BlockPos pos, int radius, PoiManager.Occupancy occupationStatus) { + public Optional find( + Predicate> typePredicate, Predicate posPredicate, BlockPos pos, int radius, PoiManager.Occupancy occupationStatus + ) { - return this.findAll(typePredicate, posPredicate, pos, radius, occupationStatus).findFirst(); + // Paper start - re-route to faster logic + BlockPos ret = io.papermc.paper.util.PoiAccess.findAnyPoiPosition(this, typePredicate, posPredicate, pos, radius, occupationStatus, false); @@ -894,21 +899,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } public Optional findClosest(Predicate> typePredicate, BlockPos pos, int radius, PoiManager.Occupancy occupationStatus) { -- return this.getInRange(typePredicate, pos, radius, occupationStatus).map(PoiRecord::getPos).min(Comparator.comparingDouble((blockPos2) -> { -- return blockPos2.distSqr(pos); -- })); +- return this.getInRange(typePredicate, pos, radius, occupationStatus) +- .map(PoiRecord::getPos) +- .min(Comparator.comparingDouble(blockPos2 -> blockPos2.distSqr(pos))); + // Paper start - re-route to faster logic + BlockPos ret = io.papermc.paper.util.PoiAccess.findClosestPoiDataPosition(this, typePredicate, null, pos, radius, radius * radius, occupationStatus, false); + return Optional.ofNullable(ret); + // Paper end - re-route to faster logic } - public Optional, BlockPos>> findClosestWithType(Predicate> typePredicate, BlockPos pos, int radius, PoiManager.Occupancy occupationStatus) { -- return this.getInRange(typePredicate, pos, radius, occupationStatus).min(Comparator.comparingDouble((poi) -> { -- return poi.getPos().distSqr(pos); -- })).map((poi) -> { -- return Pair.of(poi.getPoiType(), poi.getPos()); -- }); + public Optional, BlockPos>> findClosestWithType( + Predicate> typePredicate, BlockPos pos, int radius, PoiManager.Occupancy occupationStatus + ) { +- return this.getInRange(typePredicate, pos, radius, occupationStatus) +- .min(Comparator.comparingDouble(poi -> poi.getPos().distSqr(pos))) +- .map(poi -> Pair.of(poi.getPoiType(), poi.getPos())); + // Paper start - re-route to faster logic + return Optional.ofNullable(io.papermc.paper.util.PoiAccess.findClosestPoiDataTypeAndPosition( + this, typePredicate, null, pos, radius, radius * radius, occupationStatus, false @@ -916,10 +921,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - re-route to faster logic } - public Optional findClosest(Predicate> typePredicate, Predicate posPredicate, BlockPos pos, int radius, PoiManager.Occupancy occupationStatus) { -- return this.getInRange(typePredicate, pos, radius, occupationStatus).map(PoiRecord::getPos).filter(posPredicate).min(Comparator.comparingDouble((blockPos2) -> { -- return blockPos2.distSqr(pos); -- })); + public Optional findClosest( + Predicate> typePredicate, Predicate posPredicate, BlockPos pos, int radius, PoiManager.Occupancy occupationStatus + ) { +- return this.getInRange(typePredicate, pos, radius, occupationStatus) +- .map(PoiRecord::getPos) +- .filter(posPredicate) +- .min(Comparator.comparingDouble(blockPos2 -> blockPos2.distSqr(pos))); + // Paper start - re-route to faster logic + BlockPos ret = io.papermc.paper.util.PoiAccess.findClosestPoiDataPosition(this, typePredicate, posPredicate, pos, radius, radius * radius, occupationStatus, false); + return Optional.ofNullable(ret); @@ -927,25 +935,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } public Optional take(Predicate> typePredicate, BiPredicate, BlockPos> biPredicate, BlockPos pos, int radius) { -- return this.getInRange(typePredicate, pos, radius, PoiManager.Occupancy.HAS_SPACE).filter((poi) -> { -- return biPredicate.test(poi.getPoiType(), poi.getPos()); -- }).findFirst().map((poi) -> { +- return this.getInRange(typePredicate, pos, radius, PoiManager.Occupancy.HAS_SPACE) +- .filter(poi -> biPredicate.test(poi.getPoiType(), poi.getPos())) +- .findFirst() + // Paper start - re-route to faster logic + final @javax.annotation.Nullable PoiRecord closest = io.papermc.paper.util.PoiAccess.findClosestPoiDataRecord( + this, typePredicate, biPredicate, pos, radius, radius * radius, Occupancy.HAS_SPACE, false + ); -+ return Optional.ofNullable(closest).map(poi -> { ++ return Optional.ofNullable(closest) + // Paper end - re-route to faster logic - poi.acquireTicket(); - return poi.getPos(); - }); - } - - public Optional getRandom(Predicate> typePredicate, Predicate positionPredicate, PoiManager.Occupancy occupationStatus, BlockPos pos, int radius, RandomSource random) { + .map(poi -> { + poi.acquireTicket(); + return poi.getPos(); +@@ -0,0 +0,0 @@ public class PoiManager extends SectionStorage { + int radius, + RandomSource random + ) { - List list = Util.toShuffledList(this.getInRange(typePredicate, pos, radius, occupationStatus), random); -- return list.stream().filter((poi) -> { -- return positionPredicate.test(poi.getPos()); -- }).findFirst().map(PoiRecord::getPos); +- return list.stream().filter(poi -> positionPredicate.test(poi.getPos())).findFirst().map(PoiRecord::getPos); + // Paper start - re-route to faster logic + List list = new java.util.ArrayList<>(); + io.papermc.paper.util.PoiAccess.findAnyPoiRecords( diff --git a/patches/server/Optimise-nearby-player-retrieval.patch b/patches/server/Optimise-nearby-player-retrieval.patch index 45d3c3df8..dc06e27b1 100644 --- a/patches/server/Optimise-nearby-player-retrieval.patch +++ b/patches/server/Optimise-nearby-player-retrieval.patch @@ -135,9 +135,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override protected void doTick(ServerLevel world, LivingEntity entity) { -- List list = world.players().stream().filter(EntitySelector.NO_SPECTATORS).filter((player) -> { -- return entity.closerThan(player, 16.0D); -- }).sorted(Comparator.comparingDouble(entity::distanceToSqr)).collect(Collectors.toList()); +- List list = world.players() +- .stream() +- .filter(EntitySelector.NO_SPECTATORS) +- .filter(player -> entity.closerThan(player, 16.0)) +- .sorted(Comparator.comparingDouble(entity::distanceToSqr)) +- .collect(Collectors.toList()); + // Paper start - Perf: optimise nearby player retrieval & remove streams from hot code + io.papermc.paper.util.player.NearbyPlayers nearbyPlayers = world.chunkSource.chunkMap.getNearbyPlayers(); + net.minecraft.world.phys.Vec3 entityPos = entity.position(); @@ -164,13 +167,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + players.sort(Comparator.comparingDouble(entity::distanceToSqr)); Brain brain = entity.getBrain(); - brain.setMemory(MemoryModuleType.NEAREST_PLAYERS, list); -- List list2 = list.stream().filter((player) -> { -- return isEntityTargetable(entity, player); -- }).collect(Collectors.toList()); +- List list2 = list.stream().filter(player -> isEntityTargetable(entity, player)).collect(Collectors.toList()); - brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_PLAYER, list2.isEmpty() ? null : list2.get(0)); -- Optional optional = list2.stream().filter((player) -> { -- return isEntityAttackable(entity, player); -- }).findFirst(); +- Optional optional = list2.stream().filter(player -> isEntityAttackable(entity, player)).findFirst(); - brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, optional); + + brain.setMemory(MemoryModuleType.NEAREST_PLAYERS, players); @@ -200,10 +199,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java @@ -0,0 +0,0 @@ public class TargetingConditions { public static final TargetingConditions DEFAULT = forCombat(); - private static final double MIN_VISIBILITY_DISTANCE_FOR_INVISIBLE_TARGET = 2.0D; + private static final double MIN_VISIBILITY_DISTANCE_FOR_INVISIBLE_TARGET = 2.0; private final boolean isCombat; -- private double range = -1.0D; -+ public double range = -1.0D; // Paper - public +- private double range = -1.0; ++ public double range = -1.0; // Paper - public private boolean checkLineOfSight = true; private boolean testInvisible = true; @Nullable @@ -214,15 +213,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public interface EntityGetter { T livingEntity = null; - for(T livingEntity2 : entityList) { + for (T livingEntity2 : entityList) { + // Paper start - optimise nearby player retrieval; move up + // don't check entities outside closest range + double e = livingEntity2.distanceToSqr(x, y, z); -+ if (d == -1.0D || e < d) { ++ if (d == -1.0 || e < d) { + // Paper end - move up if (targetPredicate.test(entity, livingEntity2)) { - double e = livingEntity2.distanceToSqr(x, y, z); -- if (d == -1.0D || e < d) { +- if (d == -1.0 || e < d) { + // Paper - optimise nearby player retrieval; move up d = e; livingEntity = livingEntity2; diff --git a/patches/server/Optimise-random-block-ticking.patch b/patches/server/Optimise-random-block-ticking.patch index d9e71cec8..8a6f9859c 100644 --- a/patches/server/Optimise-random-block-ticking.patch +++ b/patches/server/Optimise-random-block-ticking.patch @@ -309,7 +309,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Override public void getAll(IntConsumer action) { - for(int i = 0; i < this.size; ++i) { + for (int i = 0; i < this.size; i++) { diff --git a/src/main/java/net/minecraft/world/entity/animal/Turtle.java b/src/main/java/net/minecraft/world/entity/animal/Turtle.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java diff --git a/patches/server/Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch b/patches/server/Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch index 15b2ddda7..78248cd7d 100644 --- a/patches/server/Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch +++ b/patches/server/Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch @@ -13,7 +13,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } public static class Builder { -- private final Map> spawners = Stream.of(MobCategory.values()).collect(ImmutableMap.toImmutableMap((mobCategory) -> { + // Paper start - Perf: keep track of data in a pair set to give O(1) contains calls - we have to hook removals incase plugins mess with it + public static class MobList extends java.util.ArrayList { + java.util.Set biomes = new java.util.HashSet<>(); @@ -45,12 +44,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + // use toImmutableEnumMap collector -+ private final Map> spawners = (Map) Stream.of(MobCategory.values()).collect(Maps.toImmutableEnumMap((mobCategory) -> { - return mobCategory; - }, (mobCategory) -> { -- return Lists.newArrayList(); -+ return new MobList(); // Use MobList instead of ArrayList - })); + private final Map> spawners = Stream.of(MobCategory.values()) +- .collect(ImmutableMap.toImmutableMap(mobCategory -> (MobCategory)mobCategory, mobCategory -> Lists.newArrayList())); ++ .collect(Maps.toImmutableEnumMap(mobCategory -> (MobCategory)mobCategory, mobCategory -> new MobList())); // Use MobList instead of ArrayList + // Paper end - Perf: keep track of data in a pair set to give O(1) contains calls private final Map, MobSpawnSettings.MobSpawnCost> mobSpawnCosts = Maps.newLinkedHashMap(); private float creatureGenerationProbability = 0.1F; diff --git a/patches/server/Optimize-Bit-Operations-by-inlining.patch b/patches/server/Optimize-Bit-Operations-by-inlining.patch index 55f98cc7f..f96263e2f 100644 --- a/patches/server/Optimize-Bit-Operations-by-inlining.patch +++ b/patches/server/Optimize-Bit-Operations-by-inlining.patch @@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/core/BlockPos.java +++ b/src/main/java/net/minecraft/core/BlockPos.java @@ -0,0 +0,0 @@ public class BlockPos extends Vec3i { - }).stable(); + .stable(); private static final Logger LOGGER = LogUtils.getLogger(); public static final BlockPos ZERO = new BlockPos(0, 0, 0); - private static final int PACKED_X_LENGTH = 1 + Mth.log2(Mth.smallestEncompassingPowerOfTwo(30000000)); @@ -76,9 +76,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public static long asLong(int x, int y, int z) { - long l = 0L; -- l |= ((long)x & PACKED_X_MASK) << X_OFFSET; -- l |= ((long)y & PACKED_Y_MASK) << 0; -- return l | ((long)z & PACKED_Z_MASK) << Z_OFFSET; +- l |= (x & PACKED_X_MASK) << X_OFFSET; +- l |= (y & PACKED_Y_MASK) << 0; +- return l | (z & PACKED_Z_MASK) << Z_OFFSET; + return (((long) x & (long) 67108863) << 38) | (((long) y & (long) 4095)) | (((long) z & (long) 67108863) << 12); // Paper - inline constants and simplify } @@ -180,9 +180,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public static long asLong(int x, int y, int z) { - long l = 0L; -- l |= ((long)x & 4194303L) << 42; -- l |= ((long)y & 1048575L) << 0; -- return l | ((long)z & 4194303L) << 20; +- l |= (x & 4194303L) << 42; +- l |= (y & 1048575L) << 0; +- return l | (z & 4194303L) << 20; + return (((long) x & 4194303L) << 42) | (((long) y & 1048575L)) | (((long) z & 4194303L) << 20); // Paper - Simplify to reduce instruction count } @@ -210,4 +210,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return betweenClosedStream(center.x - radius, 0, center.z - radius, center.x + radius, 15, center.z + radius); // Paper - simplify/inline } - public static Stream betweenClosedStream(final int minX, final int minY, final int minZ, final int maxX, final int maxY, final int maxZ) { + public static Stream betweenClosedStream(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { diff --git a/patches/server/Optimize-Collision-to-not-load-chunks.patch b/patches/server/Optimize-Collision-to-not-load-chunks.patch index 77f7ad089..ad5ad34c7 100644 --- a/patches/server/Optimize-Collision-to-not-load-chunks.patch +++ b/patches/server/Optimize-Collision-to-not-load-chunks.patch @@ -42,55 +42,53 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/level/BlockCollisions.java +++ b/src/main/java/net/minecraft/world/level/BlockCollisions.java @@ -0,0 +0,0 @@ public class BlockCollisions extends AbstractIterator { + @Override protected T computeNext() { - while(true) { - if (this.cursor.advance()) { -- int i = this.cursor.nextX(); -- int j = this.cursor.nextY(); -- int k = this.cursor.nextZ(); -+ int i = this.cursor.nextX(); final int x = i; // Paper -+ int j = this.cursor.nextY(); final int y = j; // Paper -+ int k = this.cursor.nextZ(); final int z = k; // Paper - int l = this.cursor.getNextType(); - if (l == 3) { - continue; - } -+ // Paper start - ensure we don't load chunks -+ final @Nullable Entity source = this.context instanceof net.minecraft.world.phys.shapes.EntityCollisionContext entityContext ? entityContext.getEntity() : null; -+ boolean far = source != null && io.papermc.paper.util.MCUtil.distanceSq(source.getX(), y, source.getZ(), x, y, z) > 14; -+ this.pos.set(x, y, z); - + while (this.cursor.advance()) { +- int i = this.cursor.nextX(); +- int j = this.cursor.nextY(); +- int k = this.cursor.nextZ(); ++ int i = this.cursor.nextX(); final int x = i; // Paper - OBFHELPER ++ int j = this.cursor.nextY(); final int y = j; // Paper - OBFHELPER ++ int k = this.cursor.nextZ(); final int z = k; // Paper - OBFHELPER + int l = this.cursor.getNextType(); + if (l != 3) { - BlockGetter blockGetter = this.getChunk(i, k); -- if (blockGetter == null) { -+ BlockState blockState; -+ if (this.collisionGetter instanceof net.minecraft.server.level.WorldGenRegion) { -+ BlockGetter blockGetter = this.getChunk(x, z); -+ if (blockGetter == null) { -+ continue; +- if (blockGetter != null) { +- this.pos.set(i, j, k); +- BlockState blockState = blockGetter.getBlockState(this.pos); +- if ((!this.onlySuffocatingBlocks || blockState.isSuffocating(blockGetter, this.pos)) +- && (l != 1 || blockState.hasLargeCollisionShape()) +- && (l != 2 || blockState.is(Blocks.MOVING_PISTON))) { ++ // Paper start - ensure we don't load chunks ++ // BlockGetter blockGetter = this.getChunk(i, k); ++ if (true) { ++ final @Nullable Entity source = this.context instanceof net.minecraft.world.phys.shapes.EntityCollisionContext entityContext ? entityContext.getEntity() : null; ++ boolean far = source != null && io.papermc.paper.util.MCUtil.distanceSq(source.getX(), y, source.getZ(), x, y, z) > 14; ++ this.pos.set(x, y, z); ++ BlockState blockState; ++ if (this.collisionGetter instanceof net.minecraft.server.level.WorldGenRegion) { ++ BlockGetter blockGetter = this.getChunk(x, z); ++ if (blockGetter == null) { ++ continue; ++ } ++ blockState = blockGetter.getBlockState(this.pos); ++ } else if ((!far && source instanceof net.minecraft.server.level.ServerPlayer) || (source != null && source.collisionLoadChunks)) { ++ blockState = this.collisionGetter.getBlockState(this.pos); ++ } else { ++ blockState = this.collisionGetter.getBlockStateIfLoaded(this.pos); + } -+ blockState = blockGetter.getBlockState(this.pos); -+ } else if ((!far && source instanceof net.minecraft.server.level.ServerPlayer) || (source != null && source.collisionLoadChunks)) { -+ blockState = this.collisionGetter.getBlockState(this.pos); -+ } else { -+ blockState = this.collisionGetter.getBlockStateIfLoaded(this.pos); -+ } -+ -+ if (blockState == null) { -+ if (!(source instanceof net.minecraft.server.level.ServerPlayer) || source.level().paperConfig().chunks.preventMovingIntoUnloadedChunks) { -+ return this.resultProvider.apply(new BlockPos.MutableBlockPos(x, y, z), Shapes.create(far ? source.getBoundingBox() : new AABB(new BlockPos(x, y, z)))); ++ if (blockState == null) { ++ if (!(source instanceof net.minecraft.server.level.ServerPlayer) || source.level().paperConfig().chunks.preventMovingIntoUnloadedChunks) { ++ return this.resultProvider.apply(new BlockPos.MutableBlockPos(x, y, z), Shapes.create(far ? source.getBoundingBox() : new AABB(new BlockPos(x, y, z)))); ++ } ++ continue; + } -+ // Paper end - continue; - } - -- this.pos.set(i, j, k); -- BlockState blockState = blockGetter.getBlockState(this.pos); -- if (this.onlySuffocatingBlocks && !blockState.isSuffocating(blockGetter, this.pos) || l == 1 && !blockState.hasLargeCollisionShape() || l == 2 && !blockState.is(Blocks.MOVING_PISTON)) { -+ // Paper - moved up -+ if (/*this.onlySuffocatingBlocks && (!blockState.isSuffocating(blockGetter, this.pos)) ||*/ l == 1 && !blockState.hasLargeCollisionShape() || l == 2 && !blockState.is(Blocks.MOVING_PISTON)) { // Paper - onlySuffocatingBlocks is only true on the client, so we don't care about it here - continue; - } - ++ if (/*(!this.onlySuffocatingBlocks || blockState.isSuffocating(blockGetter, this.pos)) &&*/ (l != 1 || blockState.hasLargeCollisionShape()) && (l != 2 || blockState.is(Blocks.MOVING_PISTON))) { // Paper - onlySuffocatingBlocks is only true on the client, so we don't care about it here ++ // Paper end + VoxelShape voxelShape = blockState.getCollisionShape(this.collisionGetter, this.pos, this.context); + if (voxelShape == Shapes.block()) { + if (this.box.intersects(i, j, k, i + 1.0, j + 1.0, k + 1.0)) { diff --git a/src/main/java/net/minecraft/world/level/CollisionGetter.java b/src/main/java/net/minecraft/world/level/CollisionGetter.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/CollisionGetter.java @@ -100,7 +98,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 default boolean noCollision(@Nullable Entity entity, AABB box) { + try { if (entity != null) entity.collisionLoadChunks = true; // Paper - for(VoxelShape voxelShape : this.getBlockCollisions(entity, box)) { + for (VoxelShape voxelShape : this.getBlockCollisions(entity, box)) { if (!voxelShape.isEmpty()) { return false; } diff --git a/patches/server/Optimize-DataBits.patch b/patches/server/Optimize-DataBits.patch index 45a212026..5f7f238fb 100644 --- a/patches/server/Optimize-DataBits.patch +++ b/patches/server/Optimize-DataBits.patch @@ -42,10 +42,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private int cellIndex(int index) { - long l = Integer.toUnsignedLong(this.divideMul); - long m = Integer.toUnsignedLong(this.divideAdd); -- return (int)((long)index * l + m >> 32 >> this.divideShift); +- return (int)(index * l + m >> 32 >> this.divideShift); + //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 ++ return (int) (index * this.divideMulUnsigned + this.divideAddUnsigned >> 32 >> this.divideShift); // Paper - Perf: Optimize SimpleBitStorage } @Override diff --git a/patches/server/Optimize-GoalSelector-Goal.Flag-Set-operations.patch b/patches/server/Optimize-GoalSelector-Goal.Flag-Set-operations.patch index 7792bf878..c14d5b29a 100644 --- a/patches/server/Optimize-GoalSelector-Goal.Flag-Set-operations.patch +++ b/patches/server/Optimize-GoalSelector-Goal.Flag-Set-operations.patch @@ -79,16 +79,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } // Paper end public void removeGoal(Goal goal) { -- this.availableGoals.stream().filter((wrappedGoal) -> { -- return wrappedGoal.getGoal() == goal; -- }).filter(WrappedGoal::isRunning).forEach(WrappedGoal::stop); -- this.availableGoals.removeIf((wrappedGoal) -> { -- return wrappedGoal.getGoal() == goal; -- }); +- this.availableGoals.stream().filter(wrappedGoal -> wrappedGoal.getGoal() == goal).filter(WrappedGoal::isRunning).forEach(WrappedGoal::stop); +- this.availableGoals.removeIf(wrappedGoal -> wrappedGoal.getGoal() == goal); - } - - private static boolean goalContainsAnyFlags(WrappedGoal goal, EnumSet controls) { -- for(Goal.Flag flag : goal.getFlags()) { +- for (Goal.Flag flag : goal.getFlags()) { - if (controls.contains(flag)) { - return true; + // Paper start - remove streams from pathfindergoalselector @@ -111,7 +107,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } private static boolean goalCanBeReplacedForAllFlags(WrappedGoal goal, Map goalsByControl) { -- for(Goal.Flag flag : goal.getFlags()) { +- for (Goal.Flag flag : goal.getFlags()) { + // Paper start + long flagIterator = goal.getFlags().getBackingSet(); + int wrappedGoalSize = goal.getFlags().size(); @@ -125,18 +121,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class GoalSelector { profilerFiller.push("goalCleanup"); - for(WrappedGoal wrappedGoal : this.availableGoals) { + for (WrappedGoal wrappedGoal : this.availableGoals) { - if (wrappedGoal.isRunning() && (goalContainsAnyFlags(wrappedGoal, this.disabledFlags) || !wrappedGoal.canContinueToUse())) { -+ if (wrappedGoal.isRunning() && (goalContainsAnyFlags(wrappedGoal, this.goalTypes) || !wrappedGoal.canContinueToUse())) { ++ if (wrappedGoal.isRunning() && (goalContainsAnyFlags(wrappedGoal, this.goalTypes) || !wrappedGoal.canContinueToUse())) { // Paper - Perf: optimize goal types by removing streams wrappedGoal.stop(); } } @@ -0,0 +0,0 @@ public class GoalSelector { profilerFiller.push("goalUpdate"); - for(WrappedGoal wrappedGoal2 : this.availableGoals) { -- if (!wrappedGoal2.isRunning() && !goalContainsAnyFlags(wrappedGoal2, this.disabledFlags) && goalCanBeReplacedForAllFlags(wrappedGoal2, this.lockedFlags) && wrappedGoal2.canUse()) { -- for(Goal.Flag flag : wrappedGoal2.getFlags()) { + for (WrappedGoal wrappedGoal2 : this.availableGoals) { +- if (!wrappedGoal2.isRunning() +- && !goalContainsAnyFlags(wrappedGoal2, this.disabledFlags) +- && goalCanBeReplacedForAllFlags(wrappedGoal2, this.lockedFlags) +- && wrappedGoal2.canUse()) { +- for (Goal.Flag flag : wrappedGoal2.getFlags()) { + // Paper start + if (!wrappedGoal2.isRunning() && !goalContainsAnyFlags(wrappedGoal2, this.goalTypes) && goalCanBeReplacedForAllFlags(wrappedGoal2, this.lockedFlags) && wrappedGoal2.canUse()) { + long flagIterator = wrappedGoal2.getFlags().getBackingSet(); diff --git a/patches/server/Optimize-Hoppers.patch b/patches/server/Optimize-Hoppers.patch index eda6ca466..23768f1a4 100644 --- a/patches/server/Optimize-Hoppers.patch +++ b/patches/server/Optimize-Hoppers.patch @@ -729,7 +729,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc @Override public boolean isEmpty() { - this.unpackLootTable((Player)null); + this.unpackLootTable(null); - return this.getItems().stream().allMatch(ItemStack::isEmpty); + // Paper start - Perf: Optimize Hoppers + for (final ItemStack itemStack : this.getItems()) { @@ -743,8 +743,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public ItemStack getItem(int slot) { -- this.unpackLootTable((Player)null); -+ if (slot == 0) this.unpackLootTable((Player) null); // Paper - Perf: Optimize Hoppers +- this.unpackLootTable(null); ++ if (slot == 0) this.unpackLootTable(null); // Paper - Perf: Optimize Hoppers return this.getItems().get(slot); } diff --git a/patches/server/Optimize-MappedRegistry.patch b/patches/server/Optimize-MappedRegistry.patch index bb71144bb..9bde73651 100644 --- a/patches/server/Optimize-MappedRegistry.patch +++ b/patches/server/Optimize-MappedRegistry.patch @@ -15,14 +15,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private static final Logger LOGGER = LogUtils.getLogger(); final ResourceKey> key; private final ObjectList> byId = new ObjectArrayList<>(256); -- private final Reference2IntMap toId = Util.make(new Reference2IntOpenHashMap<>(), (map) -> { -+ private final Reference2IntMap toId = Util.make(new Reference2IntOpenHashMap<>(2048), (map) -> { // Paper - Perf: Use bigger expected size to reduce collisions - map.defaultReturnValue(-1); - }); +- private final Reference2IntMap toId = Util.make(new Reference2IntOpenHashMap<>(), map -> map.defaultReturnValue(-1)); - private final Map> byLocation = new HashMap<>(); - private final Map, Holder.Reference> byKey = new HashMap<>(); - private final Map> byValue = new IdentityHashMap<>(); - private final Map lifecycles = new IdentityHashMap<>(); ++ private final Reference2IntMap toId = Util.make(new Reference2IntOpenHashMap<>(2048), map -> map.defaultReturnValue(-1)); // Paper - Perf: Use bigger expected size to reduce collisions + private final Map> byLocation = new HashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions + private final Map, Holder.Reference> byKey = new HashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions + private final Map> byValue = new IdentityHashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions diff --git a/patches/server/Optimize-NetworkManager-Exception-Handling.patch b/patches/server/Optimize-NetworkManager-Exception-Handling.patch index 4d0128221..23031e1f9 100644 --- a/patches/server/Optimize-NetworkManager-Exception-Handling.patch +++ b/patches/server/Optimize-NetworkManager-Exception-Handling.patch @@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public Packet createPacket(int id, FriendlyByteBuf buf) { + if (id < 0 || id >= this.idToDeserializer.size()) return null; // Paper - Perf: Optimize exception handling Function> function = this.idToDeserializer.get(id); - return function != null ? function.apply(buf) : null; + return (Packet)(function != null ? function.apply(buf) : null); } diff --git a/src/main/java/net/minecraft/network/Varint21FrameDecoder.java b/src/main/java/net/minecraft/network/Varint21FrameDecoder.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/patches/server/Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch b/patches/server/Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch index 4c3e09c65..5abb5da66 100644 --- a/patches/server/Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch +++ b/patches/server/Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch @@ -23,9 +23,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (node == null) { return null; } else { -- Map map = positions.stream().collect(Collectors.toMap((pos) -> { -- return this.nodeEvaluator.getGoal((double)pos.getX(), (double)pos.getY(), (double)pos.getZ()); -- }, Function.identity())); +- Map map = positions.stream() +- .collect(Collectors.toMap(pos -> this.nodeEvaluator.getGoal(pos.getX(), pos.getY(), pos.getZ()), Function.identity())); + // Paper start - Perf: remove streams and optimize collection + List> map = Lists.newArrayList(); + for (BlockPos pos : positions) { @@ -57,19 +56,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 int i = 0; - Set set3 = Sets.newHashSetWithExpectedSize(set.size()); + List> entryList = Lists.newArrayListWithExpectedSize(positions.size()); // Paper - optimize collection - int j = (int)((float)this.maxVisitedNodes * rangeMultiplier); + int j = (int)(this.maxVisitedNodes * rangeMultiplier); - while(!this.openSet.isEmpty()) { + while (!this.openSet.isEmpty()) { @@ -0,0 +0,0 @@ public class PathFinder { Node node = this.openSet.pop(); node.closed = true; -- for(Target target : set) { +- for (Target target : set) { + // Paper start - optimize collection -+ for(int i1 = 0; i1 < positions.size(); i1++) { ++ for (int i1 = 0; i1 < positions.size(); i1++) { + final Map.Entry entry = positions.get(i1); + Target target = entry.getKey(); - if (node.distanceManhattan(target) <= (float)distance) { + if (node.distanceManhattan(target) <= distance) { target.setReached(); - set3.add(target); + entryList.add(entry); @@ -95,11 +94,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } -- Optional optional = !set3.isEmpty() ? set3.stream().map((node) -> { -- return this.reconstructPath(node.getBestNode(), positions.get(node), true); -- }).min(Comparator.comparingInt(Path::getNodeCount)) : set.stream().map((target) -> { -- return this.reconstructPath(target.getBestNode(), positions.get(target), false); -- }).min(Comparator.comparingDouble(Path::getDistToTarget).thenComparingInt(Path::getNodeCount)); +- Optional optional = !set3.isEmpty() +- ? set3.stream().map(node -> this.reconstructPath(node.getBestNode(), positions.get(node), true)).min(Comparator.comparingInt(Path::getNodeCount)) +- : set.stream() +- .map(targetx -> this.reconstructPath(targetx.getBestNode(), positions.get(targetx), false)) +- .min(Comparator.comparingDouble(Path::getDistToTarget).thenComparingInt(Path::getNodeCount)); + // Paper start - Perf: remove streams and optimize collection + Path best = null; + boolean entryListIsEmpty = entryList.isEmpty(); @@ -124,7 +123,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + private float getBestH(Node node, List> targets) { // Paper - Perf: remove streams and optimize collection; Set -> List> float f = Float.MAX_VALUE; -- for(Target target : targets) { +- for (Target target : targets) { + // Paper start - Perf: remove streams and optimize collection + for (int i = 0, targetsSize = targets.size(); i < targetsSize; i++) { + final Target target = targets.get(i).getKey(); diff --git a/patches/server/Optimize-VarInts.patch b/patches/server/Optimize-VarInts.patch index ddebaa35b..562dbeed0 100644 --- a/patches/server/Optimize-VarInts.patch +++ b/patches/server/Optimize-VarInts.patch @@ -24,8 +24,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + VARINT_EXACT_BYTE_LENGTHS[32] = 1; // Special case for the number 0. + } + public static int getByteSizeOld(int i) { -+ //Paper end - Optimize VarInts - for(int j = 1; j < 5; ++j) { ++ // Paper end - Optimize VarInts + for (int j = 1; j < 5; j++) { if ((i & -1 << j * 7) == 0) { return j; @@ -0,0 +0,0 @@ public class VarInt { @@ -47,6 +47,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + public static ByteBuf writeOld(ByteBuf buf, int i) { + // Paper end - Optimize VarInts - while((i & -128) != 0) { + while ((i & -128) != 0) { buf.writeByte(i & 127 | 128); i >>>= 7; diff --git a/patches/server/Optimize-Voxel-Shape-Merging.patch b/patches/server/Optimize-Voxel-Shape-Merging.patch index 4cfb49cc3..14c230a58 100644 --- a/patches/server/Optimize-Voxel-Shape-Merging.patch +++ b/patches/server/Optimize-Voxel-Shape-Merging.patch @@ -93,12 +93,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper note - Rewrite below as optimized order if instead of nasty ternary if (first instanceof CubePointRange && second instanceof CubePointRange) { long l = lcm(i, j); - if ((long)size * l <= 256L) { + if (size * l <= 256L) { @@ -0,0 +0,0 @@ public final class Shapes { } } -- if (first.getDouble(i) < second.getDouble(0) - 1.0E-7D) { +- if (first.getDouble(i) < second.getDouble(0) - 1.0E-7) { + // Paper start - Identical happens more often than Disjoint + if (i == j && Objects.equals(first, second)) { + if (first instanceof IdenticalMerger) { @@ -107,12 +107,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return (IndexMerger) second; + } + return new IdenticalMerger(first); -+ } else if (first.getDouble(i) < second.getDouble(0) - 1.0E-7D) { ++ } else if (first.getDouble(i) < second.getDouble(0) - 1.0E-7) { return new NonOverlappingMerger(first, second, false); - } else if (second.getDouble(j) < first.getDouble(0) - 1.0E-7D) { + } else if (second.getDouble(j) < first.getDouble(0) - 1.0E-7) { return new NonOverlappingMerger(second, first, true); } else { -- return (IndexMerger)(i == j && Objects.equals(first, second) ? new IdenticalMerger(first) : new IndirectMerger(first, second, includeFirst, includeSecond)); +- return (IndexMerger)(i == j && Objects.equals(first, second) +- ? new IdenticalMerger(first) +- : new IndirectMerger(first, second, includeFirst, includeSecond)); + return new IndirectMerger(first, second, includeFirst, includeSecond); } + // Paper end diff --git a/patches/server/Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch b/patches/server/Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch index 1c51dcd12..e67a0c969 100644 --- a/patches/server/Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch +++ b/patches/server/Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch @@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/core/Vec3i.java +++ b/src/main/java/net/minecraft/core/Vec3i.java @@ -0,0 +0,0 @@ public class Vec3i implements Comparable { - }); + ); } + // Paper start diff --git a/patches/server/Paper-config-files.patch b/patches/server/Paper-config-files.patch index ac0a2321f..b1072801b 100644 --- a/patches/server/Paper-config-files.patch +++ b/patches/server/Paper-config-files.patch @@ -4874,10 +4874,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import net.minecraft.server.players.GameProfileCache; import net.minecraft.util.SignatureValidator; --public record Services(MinecraftSessionService sessionService, ServicesKeySet servicesKeySet, GameProfileRepository profileRepository, GameProfileCache profileCache) { -+// Paper start - add paper configuration files -+public record Services(MinecraftSessionService sessionService, ServicesKeySet servicesKeySet, GameProfileRepository profileRepository, GameProfileCache profileCache, @javax.annotation.Nullable io.papermc.paper.configuration.PaperConfigurations paperConfigurations) { + + public record Services( +- MinecraftSessionService sessionService, ServicesKeySet servicesKeySet, GameProfileRepository profileRepository, GameProfileCache profileCache ++ MinecraftSessionService sessionService, ServicesKeySet servicesKeySet, GameProfileRepository profileRepository, GameProfileCache profileCache, @javax.annotation.Nullable io.papermc.paper.configuration.PaperConfigurations paperConfigurations // Paper - add paper configuration files + ) { ++ // Paper start - add paper configuration files + public Services(MinecraftSessionService sessionService, ServicesKeySet servicesKeySet, GameProfileRepository profileRepository, GameProfileCache profileCache) { + this(sessionService, servicesKeySet, profileRepository, profileCache, null); + } diff --git a/patches/server/Player-Chunk-Load-Unload-Events.patch b/patches/server/Player-Chunk-Load-Unload-Events.patch index a9cc82675..35cc60a99 100644 --- a/patches/server/Player-Chunk-Load-Unload-Events.patch +++ b/patches/server/Player-Chunk-Load-Unload-Events.patch @@ -18,12 +18,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end - PlayerChunkUnloadEvent } - } + @@ -0,0 +0,0 @@ public class PlayerChunkSender { private static void sendChunk(ServerGamePacketListenerImpl handler, ServerLevel world, LevelChunk chunk) { - handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), (BitSet)null, (BitSet)null)); + handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), null, 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(); diff --git a/patches/server/Player-affects-spawning-API.patch b/patches/server/Player-affects-spawning-API.patch index 3e8f00ef8..0b87a9598 100644 --- a/patches/server/Player-affects-spawning-API.patch +++ b/patches/server/Player-affects-spawning-API.patch @@ -112,7 +112,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - Affects Spawning API @Nullable default Player getNearestPlayer(double x, double y, double z, double maxDistance, @Nullable Predicate targetPredicate) { - double d = -1.0D; + double d = -1.0; @@ -0,0 +0,0 @@ public interface EntityGetter { return this.getNearestPlayer(x, y, z, maxDistance, predicate); } @@ -132,7 +132,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - Affects Spawning API + default boolean hasNearbyAlivePlayer(double x, double y, double z, double range) { - for(Player player : this.players()) { + for (Player player : this.players()) { if (EntitySelector.NO_SPECTATORS.test(player) && EntitySelector.LIVING_ENTITY_STILL_ALIVE.test(player)) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/patches/server/PlayerLaunchProjectileEvent.patch b/patches/server/PlayerLaunchProjectileEvent.patch index 9bf21e939..0fc93f989 100644 --- a/patches/server/PlayerLaunchProjectileEvent.patch +++ b/patches/server/PlayerLaunchProjectileEvent.patch @@ -95,8 +95,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public InteractionResultHolder use(Level world, Player user, InteractionHand hand) { ItemStack itemStack = user.getItemInHand(hand); -- world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.EXPERIENCE_BOTTLE_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); -+ // world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.EXPERIENCE_BOTTLE_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); // Paper - PlayerLaunchProjectileEvent; moved down +- world.playSound( +- null, +- user.getX(), +- user.getY(), +- user.getZ(), +- SoundEvents.EXPERIENCE_BOTTLE_THROW, +- SoundSource.NEUTRAL, +- 0.5F, +- 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F) +- ); ++ // Paper - PlayerLaunchProjectileEvent; moved down if (!world.isClientSide) { ThrownExperienceBottle thrownExperienceBottle = new ThrownExperienceBottle(world, user); thrownExperienceBottle.setItem(itemStack); @@ -111,7 +120,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); + } + -+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EXPERIENCE_BOTTLE_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (net.minecraft.world.entity.Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F)); ++ world.playSound( ++ null, ++ user.getX(), ++ user.getY(), ++ user.getZ(), ++ SoundEvents.EXPERIENCE_BOTTLE_THROW, ++ SoundSource.NEUTRAL, ++ 0.5F, ++ 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F) ++ ); + user.awardStat(Stats.ITEM_USED.get(this)); + } else { + if (user instanceof net.minecraft.server.level.ServerPlayer) { @@ -136,8 +154,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java +++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java @@ -0,0 +0,0 @@ public class FireworkRocketItem extends Item { - Direction direction = context.getClickedFace(); - FireworkRocketEntity fireworkRocketEntity = new FireworkRocketEntity(level, context.getPlayer(), vec3.x + (double)direction.getStepX() * 0.15D, vec3.y + (double)direction.getStepY() * 0.15D, vec3.z + (double)direction.getStepZ() * 0.15D, itemStack); + itemStack + ); fireworkRocketEntity.spawningEntity = context.getPlayer() == null ? null : context.getPlayer().getUUID(); // Paper - level.addFreshEntity(fireworkRocketEntity); - itemStack.shrink(1); @@ -161,8 +179,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - PlayerLaunchProjectileEvent + InteractionResultHolder wrapper = super.use(world, user, hand); + if (wrapper.getResult() != net.minecraft.world.InteractionResult.FAIL) { - world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.LINGERING_POTION_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); ++ // Paper end - PlayerLaunchProjectileEvent + world.playSound( + null, + user.getX(), +@@ -0,0 +0,0 @@ public class LingeringPotionItem extends ThrowablePotionItem { + 0.5F, + 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F) + ); - return super.use(world, user, hand); ++ // Paper start - PlayerLaunchProjectileEvent + } + return wrapper; + // Paper end - PlayerLaunchProjectileEvent @@ -222,8 +248,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - PlayerLaunchProjectileEvent + InteractionResultHolder wrapper = super.use(world, user, hand); + if (wrapper.getResult() != net.minecraft.world.InteractionResult.FAIL) { - world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.SPLASH_POTION_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); ++ // Paper end - PlayerLaunchProjectileEvent + world.playSound( + null, + user.getX(), +@@ -0,0 +0,0 @@ public class SplashPotionItem extends ThrowablePotionItem { + 0.5F, + 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F) + ); - return super.use(world, user, hand); ++ // Paper start - PlayerLaunchProjectileEvent + } + return wrapper; + // Paper end - PlayerLaunchProjectileEvent diff --git a/patches/server/Prevent-causing-expired-keys-from-impacting-new-join.patch b/patches/server/Prevent-causing-expired-keys-from-impacting-new-join.patch index a71d4a8a1..c534ced4d 100644 --- a/patches/server/Prevent-causing-expired-keys-from-impacting-new-join.patch +++ b/patches/server/Prevent-causing-expired-keys-from-impacting-new-join.patch @@ -9,20 +9,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java @@ -0,0 +0,0 @@ public class ClientboundPlayerInfoUpdatePacket implements Packet { - serialized.chatSession = buf.readNullable(RemoteChatSession.Data::read); - }, (buf, entry) -> { -- buf.writeNullable(entry.chatSession, RemoteChatSession.Data::write); -+ // Paper start - Prevent causing expired keys from impacting new joins -+ RemoteChatSession.Data chatSession = entry.chatSession; -+ if (chatSession != null && chatSession.profilePublicKey().hasExpired()) { -+ chatSession = null; -+ } -+ buf.writeNullable(chatSession, RemoteChatSession.Data::write); -+ // Paper end - Prevent causing expired keys from impacting new joins }), - UPDATE_GAME_MODE((serialized, buf) -> { - serialized.gameMode = GameType.byId(buf.readVarInt()); + INITIALIZE_CHAT( + (serialized, buf) -> serialized.chatSession = buf.readNullable(RemoteChatSession.Data::read), +- (buf, entry) -> buf.writeNullable(entry.chatSession, RemoteChatSession.Data::write) ++ // Paper start - Prevent causing expired keys from impacting new joins ++ (buf, entry) -> { ++ RemoteChatSession.Data chatSession = entry.chatSession; ++ if (chatSession != null && chatSession.profilePublicKey().hasExpired()) { ++ chatSession = null; ++ } ++ buf.writeNullable(chatSession, RemoteChatSession.Data::write); ++ } ++ // Paper end - Prevent causing expired keys from impacting new joins + ), + UPDATE_GAME_MODE((serialized, buf) -> serialized.gameMode = GameType.byId(buf.readVarInt()), (buf, entry) -> buf.writeVarInt(entry.gameMode().getId())), + UPDATE_LISTED((serialized, buf) -> serialized.listed = buf.readBoolean(), (buf, entry) -> buf.writeBoolean(entry.listed())), diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java diff --git a/patches/server/Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch b/patches/server/Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch index 89672d2f5..fc35874c0 100644 --- a/patches/server/Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch +++ b/patches/server/Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch @@ -15,6 +15,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - BlockState blockState = world.getBlockState(globalPos.pos()); + BlockState blockState = world.getBlockStateIfLoaded(globalPos.pos()); // Paper - Prevent sync chunk loads when villagers try to find beds + if (blockState == null) { return false; } // Paper - Prevent sync chunk loads when villagers try to find beds - return globalPos.pos().closerToCenterThan(entity.position(), 2.0D) && blockState.is(BlockTags.BEDS) && !blockState.getValue(BedBlock.OCCUPIED); + return globalPos.pos().closerToCenterThan(entity.position(), 2.0) && blockState.is(BlockTags.BEDS) && !blockState.getValue(BedBlock.OCCUPIED); } } diff --git a/patches/server/Rate-options-and-timings-for-sensors-and-behaviors.patch b/patches/server/Rate-options-and-timings-for-sensors-and-behaviors.patch index 6d602b103..82d74d951 100644 --- a/patches/server/Rate-options-and-timings-for-sensors-and-behaviors.patch +++ b/patches/server/Rate-options-and-timings-for-sensors-and-behaviors.patch @@ -71,7 +71,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this.hasRequiredMemories(entity) && this.checkExtraStartConditions(world, entity)) { this.status = Behavior.Status.RUNNING; int i = this.minDuration + world.getRandom().nextInt(this.maxDuration + 1 - this.minDuration); - this.endTimestamp = time + (long)i; + this.endTimestamp = time + i; + this.timing.startTiming(); // Paper - behavior timings this.start(world, entity, time); + this.timing.stopTiming(); // Paper - behavior timings @@ -89,15 +89,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.doStop(world, entity, time); } + this.timing.stopTiming(); // Paper - behavior timings - } + protected void tick(ServerLevel world, E entity, long time) { diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java +++ b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java @@ -0,0 +0,0 @@ public abstract class Sensor { - private static final TargetingConditions ATTACK_TARGET_CONDITIONS_IGNORE_INVISIBILITY_AND_LINE_OF_SIGHT = TargetingConditions.forCombat().range(16.0D).ignoreLineOfSight().ignoreInvisibilityTesting(); + .ignoreInvisibilityTesting(); private final int scanRate; private long timeToTick; + // Paper start - configurable sensor tick rate and timings @@ -116,13 +116,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.timing = co.aikar.timings.MinecraftTimings.getSensorTimings(configKey, senseInterval); + // Paper end this.scanRate = senseInterval; - this.timeToTick = (long)RANDOM.nextInt(senseInterval); + this.timeToTick = RANDOM.nextInt(senseInterval); } @@ -0,0 +0,0 @@ public abstract class Sensor { public final void tick(ServerLevel world, E entity) { if (--this.timeToTick <= 0L) { -- this.timeToTick = (long)this.scanRate; +- this.timeToTick = this.scanRate; + // Paper start - configurable sensor tick rate and timings + this.timeToTick = java.util.Objects.requireNonNullElse(world.paperConfig().tickRates.sensor.get(entity.getType(), this.configKey), this.scanRate); + this.timing.startTiming(); @@ -130,5 +130,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.doTick(world, entity); + this.timing.stopTiming(); // Paper - sensor timings } - } + diff --git a/patches/server/Reduce-allocation-of-Vec3D-by-entity-tracker.patch b/patches/server/Reduce-allocation-of-Vec3D-by-entity-tracker.patch index a92bba64f..375ba1b8e 100644 --- a/patches/server/Reduce-allocation-of-Vec3D-by-entity-tracker.patch +++ b/patches/server/Reduce-allocation-of-Vec3D-by-entity-tracker.patch @@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ import org.jetbrains.annotations.VisibleForTesting; public class VecDeltaCodec { - private static final double TRUNCATION_STEPS = 4096.0D; + private static final double TRUNCATION_STEPS = 4096.0; - private Vec3 base = Vec3.ZERO; + public Vec3 base = Vec3.ZERO; // Paper diff --git a/patches/server/Reduce-blockpos-allocation-from-pathfinding.patch b/patches/server/Reduce-blockpos-allocation-from-pathfinding.patch index 4acae7b00..b411871f3 100644 --- a/patches/server/Reduce-blockpos-allocation-from-pathfinding.patch +++ b/patches/server/Reduce-blockpos-allocation-from-pathfinding.patch @@ -18,11 +18,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } @@ -0,0 +0,0 @@ public class WalkNodeEvaluator extends NodeEvaluator { - } else if (blockState.is(Blocks.COCOA)) { - return BlockPathTypes.COCOA; - } else if (!blockState.is(Blocks.WITHER_ROSE) && !blockState.is(Blocks.POINTED_DRIPSTONE)) { -- FluidState fluidState = world.getFluidState(pos); -+ FluidState fluidState = blockState.getFluidState(); // Paper - Perf: Reduce blockpos allocation from pathfinding - if (fluidState.is(FluidTags.LAVA)) { - return BlockPathTypes.LAVA; - } else if (isBurningBlock(blockState)) { + } else if (blockState.is(Blocks.COCOA)) { + return BlockPathTypes.COCOA; + } else if (!blockState.is(Blocks.WITHER_ROSE) && !blockState.is(Blocks.POINTED_DRIPSTONE)) { +- FluidState fluidState = world.getFluidState(pos); ++ FluidState fluidState = blockState.getFluidState(); // Paper - Perf: Reduce blockpos allocation from pathfinding + if (fluidState.is(FluidTags.LAVA)) { + return BlockPathTypes.LAVA; + } else if (isBurningBlock(blockState)) { diff --git a/patches/server/Reduce-memory-footprint-of-CompoundTag.patch b/patches/server/Reduce-memory-footprint-of-CompoundTag.patch index d7fbad64d..97c62fa3e 100644 --- a/patches/server/Reduce-memory-footprint-of-CompoundTag.patch +++ b/patches/server/Reduce-memory-footprint-of-CompoundTag.patch @@ -19,7 +19,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap map = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f); // Paper - Reduce memory footprint of CompoundTag byte b; - while((b = input.readByte()) != 0) { + while ((b = input.readByte()) != 0) { @@ -0,0 +0,0 @@ public class CompoundTag implements Tag { } diff --git a/patches/server/Remap-fixes.patch b/patches/server/Remap-fixes.patch index 873596353..aac51edd1 100644 --- a/patches/server/Remap-fixes.patch +++ b/patches/server/Remap-fixes.patch @@ -20,9 +20,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + int centerY = center.getY(); + int centerZ = center.getZ(); + // Paper end - return () -> { - return new AbstractIterator() { + return () -> new AbstractIterator() { private final BlockPos.MutableBlockPos cursor = new BlockPos.MutableBlockPos(); + private int currentDepth; @@ -0,0 +0,0 @@ public class BlockPos extends Vec3i { protected BlockPos computeNext() { if (this.zMirror) { diff --git a/patches/server/Remote-Connections-shouldn-t-hold-up-shutdown.patch b/patches/server/Remote-Connections-shouldn-t-hold-up-shutdown.patch index 58848bcea..6dbf86fe4 100644 --- a/patches/server/Remote-Connections-shouldn-t-hold-up-shutdown.patch +++ b/patches/server/Remote-Connections-shouldn-t-hold-up-shutdown.patch @@ -41,4 +41,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - don't wait for remote connections private void closeSocket(ServerSocket socket) { - LOGGER.debug("closeSocket: {}", (Object)socket); + LOGGER.debug("closeSocket: {}", socket); diff --git a/patches/server/Remove-UpgradeData-neighbour-ticks-outside-of-range.patch b/patches/server/Remove-UpgradeData-neighbour-ticks-outside-of-range.patch index fd4d3c122..65cb13486 100644 --- a/patches/server/Remove-UpgradeData-neighbour-ticks-outside-of-range.patch +++ b/patches/server/Remove-UpgradeData-neighbour-ticks-outside-of-range.patch @@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/level/chunk/UpgradeData.java +++ b/src/main/java/net/minecraft/world/level/chunk/UpgradeData.java @@ -0,0 +0,0 @@ public class UpgradeData { - + } } + // Paper start - filter out relocated neighbour ticks @@ -46,5 +46,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - filter out relocated neighbour ticks + Level level = chunk.getLevel(); - this.neighborBlockTicks.forEach((tick) -> { + this.neighborBlockTicks.forEach(tick -> { Block block = tick.type() == Blocks.AIR ? level.getBlockState(tick.pos()).getBlock() : tick.type(); diff --git a/patches/server/Remove-client-side-code-using-deprecated-for-removal.patch b/patches/server/Remove-client-side-code-using-deprecated-for-removal.patch index 49eaf5034..96ebdc863 100644 --- a/patches/server/Remove-client-side-code-using-deprecated-for-removal.patch +++ b/patches/server/Remove-client-side-code-using-deprecated-for-removal.patch @@ -15,16 +15,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public void openUrl(URL url) { - try { -- Process process = AccessController.doPrivileged((PrivilegedExceptionAction)(() -> { -- return Runtime.getRuntime().exec(this.getOpenUrlArguments(url)); -- })); +- Process process = AccessController.doPrivileged( +- (PrivilegedExceptionAction)(() -> Runtime.getRuntime().exec(this.getOpenUrlArguments(url))) +- ); - process.getInputStream().close(); - process.getErrorStream().close(); - process.getOutputStream().close(); - } catch (IOException | PrivilegedActionException var3) { - Util.LOGGER.error("Couldn't open url '{}'", url, var3); - } -- + throw new IllegalStateException("This method is not useful on dedicated servers."); // Paper - Fix warnings on build by removing client-only code } diff --git a/patches/server/Remove-streams-from-hot-code.patch b/patches/server/Remove-streams-from-hot-code.patch index 19518bdb3..fca4da6dc 100644 --- a/patches/server/Remove-streams-from-hot-code.patch +++ b/patches/server/Remove-streams-from-hot-code.patch @@ -23,11 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public final void tickOrStop(ServerLevel world, E entity, long time) { -- this.behaviors.stream().filter((task) -> { -- return task.getStatus() == Behavior.Status.RUNNING; -- }).forEach((task) -> { -- task.tickOrStop(world, entity, time); -- }); +- this.behaviors.stream().filter(task -> task.getStatus() == Behavior.Status.RUNNING).forEach(task -> task.tickOrStop(world, entity, time)); + // Paper start - Perf: Remove streams from hot code + for (final BehaviorControl task : this.behaviors) { + if (task.getStatus() == Behavior.Status.RUNNING) { @@ -35,18 +31,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + // Paper end - Perf: Remove streams from hot code - if (this.behaviors.stream().noneMatch((task) -> { - return task.getStatus() == Behavior.Status.RUNNING; - })) { + if (this.behaviors.stream().noneMatch(task -> task.getStatus() == Behavior.Status.RUNNING)) { + this.doStop(world, entity, time); + } @@ -0,0 +0,0 @@ public class GateBehavior implements BehaviorControl @Override public final void doStop(ServerLevel world, E entity, long time) { this.status = Behavior.Status.STOPPED; -- this.behaviors.stream().filter((task) -> { -- return task.getStatus() == Behavior.Status.RUNNING; -- }).forEach((task) -> { -- task.doStop(world, entity, time); -- }); +- this.behaviors.stream().filter(task -> task.getStatus() == Behavior.Status.RUNNING).forEach(task -> task.doStop(world, entity, time)); - this.exitErasedMemories.forEach(entity.getBrain()::eraseMemory); + // Paper start - Perf: Remove streams from hot code + for (final BehaviorControl task : this.behaviors) { @@ -68,11 +60,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - Perf: Remove streams from hot code @Override - public void apply(Stream> tasks, ServerLevel world, E entity, long time) { -- tasks.filter((task) -> { -- return task.getStatus() == Behavior.Status.STOPPED; -- }).filter((task) -> { -- return task.tryStart(world, entity, time); -- }).findFirst(); +- tasks.filter(task -> task.getStatus() == Behavior.Status.STOPPED).filter(task -> task.tryStart(world, entity, time)).findFirst(); + public void apply(ShufflingList> tasks, ServerLevel world, E entity, long time) { + for (final BehaviorControl task : tasks) { + if (task.getStatus() == Behavior.Status.STOPPED && task.tryStart(world, entity, time)) { @@ -86,11 +74,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - Perf: Remove streams from hot code @Override - public void apply(Stream> tasks, ServerLevel world, E entity, long time) { -- tasks.filter((task) -> { -- return task.getStatus() == Behavior.Status.STOPPED; -- }).forEach((task) -> { -- task.tryStart(world, entity, time); -- }); +- tasks.filter(task -> task.getStatus() == Behavior.Status.STOPPED).forEach(task -> task.tryStart(world, entity, time)); + public void apply(ShufflingList> tasks, ServerLevel world, E entity, long time) { + for (final BehaviorControl task : tasks) { + if (task.getStatus() == Behavior.Status.STOPPED) { @@ -110,7 +94,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java +++ b/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java @@ -0,0 +0,0 @@ public class GossipContainer { - }); + return this.gossips.entrySet().stream().flatMap(entry -> entry.getValue().unpack(entry.getKey())); } + // Paper start - Perf: Remove streams from hot code @@ -134,23 +118,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return Collections.emptyList(); } else { @@ -0,0 +0,0 @@ public class GossipContainer { - } public T store(DynamicOps ops) { -- return GossipContainer.GossipEntry.LIST_CODEC.encodeStart(ops, this.unpack().toList()).resultOrPartial((error) -> { -+ return GossipContainer.GossipEntry.LIST_CODEC.encodeStart(ops, this.decompress()).resultOrPartial((error) -> { // Paper - Perf: Remove streams from hot code - LOGGER.warn("Failed to serialize gossips: {}", (Object)error); - }).orElseGet(ops::emptyList); + return GossipContainer.GossipEntry.LIST_CODEC +- .encodeStart(ops, this.unpack().toList()) ++ .encodeStart(ops, this.decompress()) // Paper - Perf: Remove streams from hot code + .resultOrPartial(error -> LOGGER.warn("Failed to serialize gossips: {}", error)) + .orElseGet(ops::emptyList); } @@ -0,0 +0,0 @@ public class GossipContainer { final Object2IntMap entries = new Object2IntOpenHashMap<>(); public int weightedValue(Predicate gossipTypeFilter) { -- return this.entries.object2IntEntrySet().stream().filter((entry) -> { -- return gossipTypeFilter.test(entry.getKey()); -- }).mapToInt((entry) -> { -- return entry.getIntValue() * (entry.getKey()).weight; -- }).sum(); +- return this.entries +- .object2IntEntrySet() +- .stream() +- .filter(entry -> gossipTypeFilter.test(entry.getKey())) +- .mapToInt(entry -> entry.getIntValue() * entry.getKey().weight) +- .sum(); + // Paper start - Perf: Remove streams from hot code + int weight = 0; + for (Object2IntMap.Entry entry : entries.object2IntEntrySet()) { @@ -176,18 +161,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java +++ b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java @@ -0,0 +0,0 @@ public class NearestItemSensor extends Sensor { + @Override protected void doTick(ServerLevel world, Mob entity) { Brain brain = entity.getBrain(); - List list = world.getEntitiesOfClass(ItemEntity.class, entity.getBoundingBox().inflate(32.0D, 16.0D, 32.0D), (itemEntity) -> { -- return true; -+ return itemEntity.closerThan(entity, MAX_DISTANCE_TO_WANTED_ITEM) && entity.wantsToPickUp(itemEntity.getItem()); // Paper - Perf: Move predicate into getEntities - }); +- List list = world.getEntitiesOfClass(ItemEntity.class, entity.getBoundingBox().inflate(32.0, 16.0, 32.0), itemEntity -> true); ++ List list = world.getEntitiesOfClass(ItemEntity.class, entity.getBoundingBox().inflate(32.0, 16.0, 32.0), itemEntity -> itemEntity.closerThan(entity, MAX_DISTANCE_TO_WANTED_ITEM) && entity.wantsToPickUp(itemEntity.getItem())); // Paper - Perf: Move predicate into getEntities list.sort(Comparator.comparingDouble(entity::distanceToSqr)); -- Optional optional = list.stream().filter((itemEntity) -> { -- return entity.wantsToPickUp(itemEntity.getItem()); -- }).filter((itemEntity) -> { -- return itemEntity.closerThan(entity, 32.0D); -- }).filter(entity::hasLineOfSight).findFirst(); +- Optional optional = list.stream() +- .filter(itemEntity -> entity.wantsToPickUp(itemEntity.getItem())) +- .filter(itemEntity -> itemEntity.closerThan(entity, 32.0)) +- .filter(entity::hasLineOfSight) +- .findFirst(); - brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, optional); + // Paper start - Perf: remove streams from hot code + ItemEntity nearest = null; @@ -209,35 +193,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 int j = pos.getMinBlockZ(); ObjectList objectList = new ObjectArrayList<>(10); ObjectList objectList2 = new ObjectArrayList<>(32); -- world.startsForStructure(pos, (structure) -> { +- world.startsForStructure(pos, structure -> structure.terrainAdaptation() != TerrainAdjustment.NONE) +- .forEach( +- start -> { + // Paper start - Perf: Remove streams from hot code + for (net.minecraft.world.level.levelgen.structure.StructureStart start : world.startsForStructure(pos, (structure) -> { - return structure.terrainAdaptation() != TerrainAdjustment.NONE; -- }).forEach((start) -> { ++ return structure.terrainAdaptation() != TerrainAdjustment.NONE; + })) { // Paper end - Perf: Remove streams from hot code - TerrainAdjustment terrainAdjustment = start.getStructure().terrainAdaptation(); + TerrainAdjustment terrainAdjustment = start.getStructure().terrainAdaptation(); - for(StructurePiece structurePiece : start.getPieces()) { + for (StructurePiece structurePiece : start.getPieces()) { @@ -0,0 +0,0 @@ public class Beardifier implements DensityFunctions.BeardifierOrMarker { - } - - for(JigsawJunction jigsawJunction : poolElementStructurePiece.getJunctions()) { -- int i = jigsawJunction.getSourceX(); -- int j = jigsawJunction.getSourceZ(); -- if (i > i - 12 && j > j - 12 && i < i + 15 + 12 && j < j + 15 + 12) { -+ // Paper start - decompile fix -+ int i2 = jigsawJunction.getSourceX(); -+ int j2 = jigsawJunction.getSourceZ(); -+ if (i2 > i - 12 && j2 > j - 12 && i2 < i + 15 + 12 && j2 < j + 15 + 12) { -+ // Paper end - decompile fix - objectList2.add(jigsawJunction); } } -@@ -0,0 +0,0 @@ public class Beardifier implements DensityFunctions.BeardifierOrMarker { - } - } - -- }); + } +- } +- ); + } // Paper - Perf: Remove streams from hot code return new Beardifier(objectList.iterator(), objectList2.iterator()); } diff --git a/patches/server/Rewrite-chunk-system.patch b/patches/server/Rewrite-chunk-system.patch index 48643174c..5045db74d 100644 --- a/patches/server/Rewrite-chunk-system.patch +++ b/patches/server/Rewrite-chunk-system.patch @@ -18934,7 +18934,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public final boolean hasSkyLight; // Paper end - replace light engine impl @@ -0,0 +0,0 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - public ThreadedLevelLightEngine(LightChunkGetter chunkProvider, ChunkMap chunkStorage, boolean hasBlockLight, ProcessorMailbox processor, ProcessorHandle> executor) { + ) { super(chunkProvider, false, false); // Paper - destroy vanilla light engine state this.chunkMap = chunkStorage; - this.sorterMailbox = executor; @@ -18984,7 +18984,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - if (this.lightTasks.size() >= 1000) { - this.runUpdate(); - } -- - }, ChunkPos.asLong(x, z), completedLevelSupplier)); + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } @@ -19031,17 +19030,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - if (!excludeBlocks) { - super.propagateLightSources(chunkPos); - } -- -- }, () -> { -- return "lightChunk " + chunkPos + " " + excludeBlocks; -- })); +- }, () -> "lightChunk " + chunkPos + " " + excludeBlocks)); - return CompletableFuture.supplyAsync(() -> { - chunk.setLightCorrect(true); - this.chunkMap.releaseLightTicket(chunkPos); - return chunk; -- }, (task) -> { -- this.addTask(chunkPos.x, chunkPos.z, ThreadedLevelLightEngine.TaskType.POST_UPDATE, task); -- }); +- }, task -> this.addTask(chunkPos.x, chunkPos.z, ThreadedLevelLightEngine.TaskType.POST_UPDATE, task)); + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } @@ -19052,7 +19046,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - this.scheduled.set(false); - }); - } -- + // Paper - rewrite chunk system } @@ -19061,7 +19054,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - ObjectListIterator> objectListIterator = this.lightTasks.iterator(); - - int j; -- for(j = 0; objectListIterator.hasNext() && j < i; ++j) { +- for (j = 0; objectListIterator.hasNext() && j < i; j++) { - Pair pair = objectListIterator.next(); - if (pair.getFirst() == ThreadedLevelLightEngine.TaskType.PRE_UPDATE) { - pair.getSecond().run(); @@ -19071,7 +19064,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - objectListIterator.back(j); - this.theLightEngine.propagateChanges(); // Paper - rewrite light engine - -- for(int var5 = 0; objectListIterator.hasNext() && var5 < i; ++var5) { +- for (int var5 = 0; objectListIterator.hasNext() && var5 < i; var5++) { - Pair pair2 = objectListIterator.next(); - if (pair2.getFirst() == ThreadedLevelLightEngine.TaskType.POST_UPDATE) { - pair2.getSecond().run(); @@ -19079,7 +19072,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - - objectListIterator.remove(); - } -- + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } @@ -19201,7 +19193,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } // Paper end - PlayerChunkUnloadEvent - } -- } + // Paper end - rewrite player chunk loader @@ -19217,7 +19208,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - private static void sendChunk(ServerGamePacketListenerImpl handler, ServerLevel world, LevelChunk chunk) { + public static void sendChunk(ServerGamePacketListenerImpl handler, ServerLevel world, LevelChunk chunk) { // Paper - rewrite chunk loader - public + handler.player.serverLevel().chunkSource.chunkMap.getVisibleChunkIfPresent(chunk.getPos().toLong()).addPlayer(handler.player); - handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), (BitSet)null, (BitSet)null)); + handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), null, null)); // Paper start - PlayerChunkLoadEvent if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) { @@ -0,0 +0,0 @@ public class PlayerChunkSender { @@ -19225,8 +19216,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public void onChunkBatchReceivedByClient(float desiredBatchSize) { + if (true) return; // Paper - rewrite player chunk loader - --this.unacknowledgedBatches; - this.desiredChunksPerTick = Double.isNaN((double)desiredBatchSize) ? 0.01F : Mth.clamp(desiredBatchSize, 0.01F, 64.0F); + this.unacknowledgedBatches--; + this.desiredChunksPerTick = Double.isNaN(desiredBatchSize) ? 0.01F : Mth.clamp(desiredBatchSize, 0.01F, 64.0F); if (this.unacknowledgedBatches == 0) { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -19607,8 +19598,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + io.papermc.paper.chunk.system.poi.PoiChunk ret = manager.getPoiChunkIfLoaded(chunkX, chunkZ, true); + + return ret == null ? Optional.empty() : ret.getSectionForVanilla(chunkY); -+ } -+ + } + + @Override + public Optional getOrLoad(long pos) { + int chunkX = io.papermc.paper.util.CoordinateUtils.getChunkSectionX(pos); @@ -19670,8 +19661,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.onSectionLoad(SectionPos.asLong(chunkX, sectionY, chunkZ)); + } + } - } - ++ } ++ + public void checkConsistency(net.minecraft.world.level.chunk.ChunkAccess chunk) { + int chunkX = chunk.getPos().x; + int chunkZ = chunk.getPos().z; @@ -19685,17 +19676,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - rewrite chunk system + public void checkConsistencyWithBlocks(SectionPos sectionPos, LevelChunkSection chunkSection) { - Util.ifElse(this.getOrLoad(sectionPos.asLong()), (poiSet) -> { - poiSet.refresh((populator) -> { + Util.ifElse(this.getOrLoad(sectionPos.asLong()), poiSet -> poiSet.refresh(populator -> { + if (mayHavePoi(chunkSection)) { @@ -0,0 +0,0 @@ public class PoiManager extends SectionStorage { - }).map((pair) -> { - return pair.getFirst().chunk(); - }).filter((chunkPos) -> { -- return this.loadedChunks.add(chunkPos.toLong()); -+ return true; // Paper - rewrite chunk system - }).forEach((chunkPos) -> { - world.getChunk(chunkPos.x, chunkPos.z, ChunkStatus.EMPTY); - }); + .map(sectionPos -> Pair.of(sectionPos, this.getOrLoad(sectionPos.asLong()))) + .filter(pair -> !pair.getSecond().map(PoiSection::isValid).orElse(false)) + .map(pair -> pair.getFirst().chunk()) +- .filter(chunkPos -> this.loadedChunks.add(chunkPos.toLong())) ++ // Paper - rewrite chunk system + .forEach(chunkPos -> world.getChunk(chunkPos.x, chunkPos.z, ChunkStatus.EMPTY)); + } + @@ -0,0 +0,0 @@ public class PoiManager extends SectionStorage { @Override @@ -19752,7 +19743,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public final Optional noAllocateOptional = Optional.of(this); // Paper - rewrite chunk system public static Codec codec(Runnable updateListener) { - return RecordCodecBuilder.create((instance) -> { + return RecordCodecBuilder.create( @@ -0,0 +0,0 @@ public class PoiSection { this(updateListener, true, ImmutableList.of()); } @@ -20550,38 +20541,40 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public CompletableFuture> loadEntities(ChunkPos pos) { -- return this.emptyChunks.contains(pos.toLong()) ? CompletableFuture.completedFuture(emptyChunk(pos)) : this.worker.loadAsync(pos).thenApplyAsync((nbt) -> { -- if (nbt.isEmpty()) { -- this.emptyChunks.add(pos.toLong()); -- return emptyChunk(pos); -- } else { -- try { -- ChunkPos chunkPos2 = readChunkPos(nbt.get()); -- if (!Objects.equals(pos, chunkPos2)) { -- LOGGER.error("Chunk file at {} is in the wrong location. (Expected {}, got {})", pos, pos, chunkPos2); +- return this.emptyChunks.contains(pos.toLong()) +- ? CompletableFuture.completedFuture(emptyChunk(pos)) +- : this.worker.loadAsync(pos).thenApplyAsync(nbt -> { +- if (nbt.isEmpty()) { +- this.emptyChunks.add(pos.toLong()); +- return emptyChunk(pos); +- } else { +- try { +- ChunkPos chunkPos2 = readChunkPos(nbt.get()); +- if (!Objects.equals(pos, chunkPos2)) { +- LOGGER.error("Chunk file at {} is in the wrong location. (Expected {}, got {})", pos, pos, chunkPos2); +- } +- } catch (Exception var6) { +- LOGGER.warn("Failed to parse chunk {} position info", pos, var6); - } -- } catch (Exception var6) { -- LOGGER.warn("Failed to parse chunk {} position info", pos, var6); -- } - -- CompoundTag compoundTag = this.upgradeChunkTag(nbt.get()); -- ListTag listTag = compoundTag.getList("Entities", 10); -- List list = EntityType.loadEntitiesRecursive(listTag, this.level).collect(ImmutableList.toImmutableList()); -- return new ChunkEntities<>(pos, list); -- } -- }, this.entityDeserializerQueue::tell); +- CompoundTag compoundTag = this.upgradeChunkTag(nbt.get()); +- ListTag listTag = compoundTag.getList("Entities", 10); +- List list = EntityType.loadEntitiesRecursive(listTag, this.level).collect(ImmutableList.toImmutableList()); +- return new ChunkEntities<>(pos, list); +- } +- }, this.entityDeserializerQueue::tell); + throw new UnsupportedOperationException(); // Paper - rewrite chunk system - copy out read logic into readEntities -+ } -+ + } + +- private static ChunkPos readChunkPos(CompoundTag chunkNbt) { + // Paper start - rewrite chunk system + public static List readEntities(ServerLevel level, CompoundTag compoundTag) { + ListTag listTag = compoundTag.getList("Entities", 10); + List list = EntityType.loadEntitiesRecursive(listTag, level).collect(ImmutableList.toImmutableList()); + return list; - } ++ } + // Paper end - rewrite chunk system - -- private static ChunkPos readChunkPos(CompoundTag chunkNbt) { ++ + public static ChunkPos readChunkPos(CompoundTag chunkNbt) { // Paper - public int[] is = chunkNbt.getIntArray("Position"); return new ChunkPos(is[0], is[1]); @@ -20598,23 +20591,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 ChunkPos chunkPos = dataList.getPos(); if (dataList.isEmpty()) { if (this.emptyChunks.add(chunkPos.toLong())) { -- this.worker.store(chunkPos, (CompoundTag)null); +- this.worker.store(chunkPos, null); + // Paper - rewrite chunk system } - } else { - ListTag listTag = new ListTag(); -- dataList.getEntities().forEach((entity) -> { -- CompoundTag compoundTag = new CompoundTag(); -- if (entity.save(compoundTag)) { -- listTag.add(compoundTag); +- dataList.getEntities().forEach(entity -> { +- CompoundTag compoundTagx = new CompoundTag(); +- if (entity.save(compoundTagx)) { +- listTag.add(compoundTagx); - } -- - }); - CompoundTag compoundTag = NbtUtils.addCurrentDataVersion(new CompoundTag()); - compoundTag.put("Entities", listTag); - writeChunkPos(compoundTag, chunkPos); -- this.worker.store(chunkPos, compoundTag).exceptionally((ex) -> { +- this.worker.store(chunkPos, compoundTag).exceptionally(ex -> { - LOGGER.error("Failed to store chunk {}", chunkPos, ex); - return null; - }); @@ -20922,7 +20913,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public final RegistryAccess registryAccess; // Paper - rewrite chunk system protected final LevelHeightAccessor levelHeightAccessor; - public SectionStorage(Path path, Function> codecFactory, Function factory, DataFixer dataFixer, DataFixTypes dataFixTypes, boolean dsync, RegistryAccess dynamicRegistryManager, LevelHeightAccessor world) { + public SectionStorage( +@@ -0,0 +0,0 @@ public class SectionStorage implements AutoCloseable { + RegistryAccess dynamicRegistryManager, + LevelHeightAccessor world + ) { + super(path, dsync); // Paper - remove mojang I/O thread this.codec = codecFactory; this.factory = factory; @@ -20941,12 +20936,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private void readColumn(ChunkPos pos) { - Optional optional = this.tryRead(pos).join(); - RegistryOps registryOps = RegistryOps.create(NbtOps.INSTANCE, this.registryAccess); -- this.readColumn(pos, registryOps, optional.orElse((CompoundTag)null)); +- this.readColumn(pos, registryOps, optional.orElse(null)); + throw new IllegalStateException("Only chunk system can load in state, offending class:" + this.getClass().getName()); // Paper - rewrite chunk system } private CompletableFuture> tryRead(ChunkPos pos) { -- return this.worker.loadAsync(pos).exceptionally((throwable) -> { +- return this.worker.loadAsync(pos).exceptionally(throwable -> { - if (throwable instanceof IOException iOException) { - LOGGER.error("Error reading chunk {} data from disk", pos, iOException); - return Optional.empty(); @@ -20966,7 +20961,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private void readColumn(ChunkPos pos, DynamicOps ops, @Nullable T data) { + if (true) throw new IllegalStateException("Only chunk system can load in state, offending class:" + this.getClass().getName()); // Paper - rewrite chunk system if (data == null) { - for(int i = this.levelHeightAccessor.getMinSection(); i < this.levelHeightAccessor.getMaxSection(); ++i) { + for (int i = this.levelHeightAccessor.getMinSection(); i < this.levelHeightAccessor.getMaxSection(); i++) { this.storage.put(getKey(pos, i), Optional.empty()); @@ -0,0 +0,0 @@ public class SectionStorage implements AutoCloseable { Dynamic dynamic = this.writeColumn(pos, registryOps); @@ -20975,7 +20970,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - this.worker.store(pos, (CompoundTag)tag); + try { this.write(pos, (CompoundTag)tag); } catch (IOException ioexception) { SectionStorage.LOGGER.error("Error writing data to disk", ioexception); } // Paper - nuke IOWorker } else { - LOGGER.error("Expected compound tag, got {}", (Object)tag); + LOGGER.error("Expected compound tag, got {}", tag); } @@ -0,0 +0,0 @@ public class SectionStorage implements AutoCloseable { } @@ -21015,7 +21010,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - if (this.iterated == this.active) { - this.passive.clear(); - -- for(Int2ObjectMap.Entry entry : Int2ObjectMaps.fastIterable(this.active)) { +- for (Entry entry : Int2ObjectMaps.fastIterable(this.active)) { - this.passive.put(entry.getIntKey(), entry.getValue()); - } - @@ -21024,7 +21019,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - this.passive = int2ObjectMap; - } + // Paper - replace with better logic, do not delay removals - } public void add(Entity entity) { @@ -21053,7 +21047,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - this.iterated = this.active; - - try { -- for(Entity entity : this.active.values()) { +- for (Entity entity : this.active.values()) { - action.accept(entity); - } - } finally { @@ -21067,7 +21061,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + while (iterator.hasNext()) { + action.accept(iterator.next()); } -- + } finally { + iterator.finishedIterating(); } @@ -21202,8 +21195,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end - rewrite chunk system - synchronise this class - public StructureCheck(ChunkScanAccess chunkIoWorker, RegistryAccess registryManager, StructureTemplateManager structureTemplateManager, ResourceKey worldKey, ChunkGenerator chunkGenerator, RandomState noiseConfig, LevelHeightAccessor world, BiomeSource biomeSource, long seed, DataFixer dataFixer) { // Paper - fix missing CB diff - this.storageAccess = chunkIoWorker; + public StructureCheck( + ChunkScanAccess chunkIoWorker, @@ -0,0 +0,0 @@ public class StructureCheck { public StructureCheckResult checkStart(ChunkPos pos, Structure type, boolean skipReferencedStructures) { @@ -21217,23 +21210,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (structureCheckResult != null) { return structureCheckResult; } else { -- boolean bl = this.featureChecks.computeIfAbsent(type, (structure2) -> { -- return new Long2BooleanOpenHashMap(); -- }).computeIfAbsent(l, (chunkPos) -> { -+ boolean bl = this.featureChecksSafe.computeIfAbsent(type, (structure2) -> { // Paper - rewrite chunk system - synchronise this class -+ return new SynchronisedLong2BooleanMap(PER_FEATURE_CHECK_LIMIT); // Paper - rewrite chunk system - synchronise this class -+ }).getOrCompute(l, (chunkPos) -> { // Paper - rewrite chunk system - synchronise this class - return this.canCreateStructure(pos, type); - }); +- boolean bl = this.featureChecks +- .computeIfAbsent(type, structure2 -> new Long2BooleanOpenHashMap()) +- .computeIfAbsent(l, chunkPos -> this.canCreateStructure(pos, type)); ++ boolean bl = this.featureChecksSafe // Paper - rewrite chunk system - synchronise this class ++ .computeIfAbsent(type, structure2 -> new SynchronisedLong2BooleanMap(PER_FEATURE_CHECK_LIMIT)) // Paper - rewrite chunk system - synchronise this class ++ .getOrCompute(l, chunkPos -> this.canCreateStructure(pos, type)); // Paper - rewrite chunk system - synchronise this class return !bl ? StructureCheckResult.START_NOT_PRESENT : StructureCheckResult.CHUNK_LOAD_NEEDED; + } + } @@ -0,0 +0,0 @@ public class StructureCheck { } private void storeFullResults(long pos, Object2IntMap referencesByStructure) { - this.loadedChunks.put(pos, deduplicateEmptyMap(referencesByStructure)); -- this.featureChecks.values().forEach((generationPossibilityByChunkPos) -> { -- generationPossibilityByChunkPos.remove(pos); -- }); +- this.featureChecks.values().forEach(generationPossibilityByChunkPos -> generationPossibilityByChunkPos.remove(pos)); + // Paper start - rewrite chunk system - synchronise this class + this.loadedChunksSafe.put(pos, deduplicateEmptyMap(referencesByStructure)); + // once we insert into loadedChunks, we don't really need to be very careful about removing everything @@ -21257,8 +21248,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } + // Paper end - rewrite chunk system - synchronise this class - referencesByStructure.computeInt(structure, (feature, references) -> { - return references == null ? 1 : references + 1; + referencesByStructure.computeInt(structure, (feature, references) -> references == null ? 1 : references + 1); + return referencesByStructure; diff --git a/src/main/java/net/minecraft/world/ticks/LevelChunkTicks.java b/src/main/java/net/minecraft/world/ticks/LevelChunkTicks.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/ticks/LevelChunkTicks.java @@ -21298,9 +21289,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.dirty = true; // Paper - add dirty flag this.scheduleUnchecked(orderedTick); } - + } @@ -0,0 +0,0 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon - while(iterator.hasNext()) { + while (iterator.hasNext()) { ScheduledTick scheduledTick = iterator.next(); if (predicate.test(scheduledTick)) { - iterator.remove(); @@ -21315,7 +21306,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.lastSaved = l; // Paper - add dirty system to level ticks ListTag listTag = new ListTag(); if (this.pendingTicks != null) { - for(SavedTick savedTick : this.pendingTicks) { + for (SavedTick savedTick : this.pendingTicks) { @@ -0,0 +0,0 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon public void unpack(long time) { @@ -21327,7 +21318,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - add dirty system to level chunk ticks int i = -this.pendingTicks.size(); - for(SavedTick savedTick : this.pendingTicks) { + for (SavedTick savedTick : this.pendingTicks) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java diff --git a/patches/server/Rewrite-dataconverter-system.patch b/patches/server/Rewrite-dataconverter-system.patch index 8a7e8e89b..79898568a 100644 --- a/patches/server/Rewrite-dataconverter-system.patch +++ b/patches/server/Rewrite-dataconverter-system.patch @@ -24868,7 +24868,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - route to new converter system OptionalDynamic optionalDynamic = dynamic2.get("Sections"); - for(int l = this.levelHeightAccessor.getMinSection(); l < this.levelHeightAccessor.getMaxSection(); ++l) { + for (int l = this.levelHeightAccessor.getMinSection(); l < this.levelHeightAccessor.getMaxSection(); l++) { diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java b/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java diff --git a/patches/server/Significantly-improve-performance-of-the-end-generat.patch b/patches/server/Significantly-improve-performance-of-the-end-generat.patch index 142d23766..3d266bd9b 100644 --- a/patches/server/Significantly-improve-performance-of-the-end-generat.patch +++ b/patches/server/Significantly-improve-performance-of-the-end-generat.patch @@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/level/levelgen/DensityFunctions.java +++ b/src/main/java/net/minecraft/world/level/levelgen/DensityFunctions.java @@ -0,0 +0,0 @@ public final class DensityFunctions { - public static final KeyDispatchDataCodec CODEC = KeyDispatchDataCodec.of(MapCodec.unit(new DensityFunctions.EndIslandDensityFunction(0L))); + ); private static final float ISLAND_THRESHOLD = -0.9F; private final SimplexNoise islandNoise; + // Paper start - Perf: Optimize end generation @@ -37,11 +37,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 f = Mth.clamp(f, -100.0F, 80.0F); + NoiseCache cache = noiseCache.get().computeIfAbsent(sampler, noiseKey -> new NoiseCache()); // Paper - Perf: Optimize end generation - for(int m = -12; m <= 12; ++m) { - for(int n = -12; n <= 12; ++n) { - long o = (long)(i + m); - long p = (long)(j + n); -- if (o * o + p * p > 4096L && sampler.getValue((double)o, (double)p) < (double)-0.9F) { + for (int m = -12; m <= 12; m++) { + for (int n = -12; n <= 12; n++) { + long o = i + m; + long p = j + n; +- if (o * o + p * p > 4096L && sampler.getValue(o, p) < -0.9F) { - float g = (Mth.abs((float)o) * 3439.0F + Mth.abs((float)p) * 147.0F) % 13.0F + 9.0F; + // Paper start - Perf: Optimize end generation by using a noise cache + long key = net.minecraft.world.level.ChunkPos.asLong((int) o, (int) p); @@ -50,14 +50,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (cache.keys[index] == key) { + g = cache.values[index]; + } else { -+ if (o * o + p * p > 4096L && sampler.getValue((double)o, (double)p) < (double)-0.9F) { -+ g = (Mth.abs((float) o) * 3439.0F + Mth.abs((float) p) * 147.0F) % 13.0F + 9.0F; ++ if (o * o + p * p > 4096L && sampler.getValue((double)o, (double)p) < -0.9F) { ++ g = (Mth.abs((float)o) * 3439.0F + Mth.abs((float)p) * 147.0F) % 13.0F + 9.0F; + } + cache.keys[index] = key; + cache.values[index] = g; + } + if (g != Float.MIN_VALUE) { + // Paper end - Perf: Optimize end generation - float h = (float)(k - m * 2); - float q = (float)(l - n * 2); + float h = k - m * 2; + float q = l - n * 2; float r = 100.0F - Mth.sqrt(h * h + q * q) * g; diff --git a/patches/server/Skip-POI-finding-if-stuck-in-vehicle.patch b/patches/server/Skip-POI-finding-if-stuck-in-vehicle.patch index 01c7f1b1a..3d51d5db7 100644 --- a/patches/server/Skip-POI-finding-if-stuck-in-vehicle.patch +++ b/patches/server/Skip-POI-finding-if-stuck-in-vehicle.patch @@ -23,10 +23,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java @@ -0,0 +0,0 @@ public class AcquirePoi { - return false; - } else { - mutableLong.setValue(time + 20L + (long)world.getRandom().nextInt(20)); -+ if (entity.getNavigation().isStuck()) mutableLong.add(200); // Paper - Perf: Wait an additional 10s to check again if they're stuck - PoiManager poiManager = world.getPoiManager(); - long2ObjectMap.long2ObjectEntrySet().removeIf((entry) -> { - return !entry.getValue().isStillValid(time); + return false; + } else { + mutableLong.setValue(time + 20L + world.getRandom().nextInt(20)); ++ if (entity.getNavigation().isStuck()) mutableLong.add(200); // Paper - Perf: Wait an additional 10s to check again if they're stuck + PoiManager poiManager = world.getPoiManager(); + long2ObjectMap.long2ObjectEntrySet().removeIf(entry -> !entry.getValue().isStillValid(time)); + Predicate predicate2 = pos -> { diff --git a/patches/server/Starlight.patch b/patches/server/Starlight.patch index a04aeffea..e6fe8a50a 100644 --- a/patches/server/Starlight.patch +++ b/patches/server/Starlight.patch @@ -4549,7 +4549,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public final boolean hasSkyLight; + // Paper end - replace light engine impl + - public ThreadedLevelLightEngine(LightChunkGetter chunkProvider, ChunkMap chunkStorage, boolean hasBlockLight, ProcessorMailbox processor, ProcessorHandle> executor) { + public ThreadedLevelLightEngine( + LightChunkGetter chunkProvider, + ChunkMap chunkStorage, +@@ -0,0 +0,0 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl + ProcessorMailbox processor, + ProcessorHandle> executor + ) { - super(chunkProvider, true, hasBlockLight); + super(chunkProvider, false, false); // Paper - destroy vanilla light engine state this.chunkMap = chunkStorage; @@ -4675,8 +4681,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + LOGGER.error("Failed to remove ticket level for post chunk task " + new ChunkPos(chunkX, chunkZ), thr); + } + }); - } - ++ } ++ + @Override + public boolean hasLightWork() { + // route to new light engine @@ -4696,22 +4702,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (sky == 15) return 15; + final int block = this.theLightEngine.getBlockReader().getLightValue(pos); + return Math.max(sky, block); -+ } + } + // Paper end - replace light engine imp -+ + @Override public void close() { - } @@ -0,0 +0,0 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl @Override public void checkBlock(BlockPos pos) { - BlockPos blockPos = pos.immutable(); -- this.addTask(SectionPos.blockToSectionCoord(pos.getX()), SectionPos.blockToSectionCoord(pos.getZ()), ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> { -- super.checkBlock(blockPos); -- }, () -> { -- return "checkBlock " + blockPos; -- })); +- this.addTask( +- SectionPos.blockToSectionCoord(pos.getX()), +- SectionPos.blockToSectionCoord(pos.getZ()), +- ThreadedLevelLightEngine.TaskType.PRE_UPDATE, +- Util.name(() -> super.checkBlock(blockPos), () -> "checkBlock " + blockPos) +- ); + // Paper start - replace light engine impl + final BlockPos posCopy = pos.immutable(); + this.queueTaskForSection(posCopy.getX() >> 4, posCopy.getY() >> 4, posCopy.getZ() >> 4, () -> { @@ -4722,20 +4728,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 protected void updateChunkStatus(ChunkPos pos) { + if (true) return; // Paper - replace light engine impl - this.addTask(pos.x, pos.z, () -> { - return 0; - }, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> { + this.addTask(pos.x, pos.z, () -> 0, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> { + super.retainData(pos, false); + super.setLightEnabled(pos, false); @@ -0,0 +0,0 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl @Override public void updateSectionStatus(SectionPos pos, boolean notReady) { -- this.addTask(pos.x(), pos.z(), () -> { -- return 0; -- }, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> { -- super.updateSectionStatus(pos, notReady); -- }, () -> { -- return "updateSectionStatus " + pos + " " + notReady; -- })); +- this.addTask( +- pos.x(), +- pos.z(), +- () -> 0, +- ThreadedLevelLightEngine.TaskType.PRE_UPDATE, +- Util.name(() -> super.updateSectionStatus(pos, notReady), () -> "updateSectionStatus " + pos + " " + notReady) +- ); + // Paper start - replace light engine impl + this.queueTaskForSection(pos.getX(), pos.getY(), pos.getZ(), () -> { + return this.theLightEngine.sectionChange(pos, notReady); @@ -4746,34 +4752,33 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void propagateLightSources(ChunkPos chunkPos) { + if (true) return; // Paper - replace light engine impl - this.addTask(chunkPos.x, chunkPos.z, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> { - super.propagateLightSources(chunkPos); - }, () -> { + this.addTask( + chunkPos.x, + chunkPos.z, @@ -0,0 +0,0 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl @Override public void setLightEnabled(ChunkPos pos, boolean retainData) { + if (true) return; // Paper - replace light engine impl - this.addTask(pos.x, pos.z, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> { - super.setLightEnabled(pos, retainData); - }, () -> { + this.addTask( + pos.x, + pos.z, @@ -0,0 +0,0 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl @Override public void queueSectionData(LightLayer lightType, SectionPos pos, @Nullable DataLayer nibbles) { + if (true) return; // Paper - replace light engine impl - this.addTask(pos.x(), pos.z(), () -> { - return 0; - }, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> { + this.addTask( + pos.x(), + pos.z(), @@ -0,0 +0,0 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl @Override public void retainData(ChunkPos pos, boolean retainData) { + if (true) return; // Paper - replace light engine impl - this.addTask(pos.x, pos.z, () -> { - return 0; - }, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> { -@@ -0,0 +0,0 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl + this.addTask( + pos.x, pos.z, () -> 0, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> super.retainData(pos, retainData), () -> "retainData " + pos) + ); } public CompletableFuture initializeLight(ChunkAccess chunk, boolean bl) { @@ -4835,7 +4840,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - super.runLightUpdates(); + this.theLightEngine.propagateChanges(); // Paper - rewrite light engine - for(int var5 = 0; objectListIterator.hasNext() && var5 < i; ++var5) { + for (int var5 = 0; objectListIterator.hasNext() && var5 < i; var5++) { Pair pair2 = objectListIterator.next(); diff --git a/src/main/java/net/minecraft/server/level/TicketType.java b/src/main/java/net/minecraft/server/level/TicketType.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/patches/server/Synchronize-PalettedContainer-instead-of-ThreadingDe.patch b/patches/server/Synchronize-PalettedContainer-instead-of-ThreadingDe.patch index 1685367df..4b2607129 100644 --- a/patches/server/Synchronize-PalettedContainer-instead-of-ThreadingDe.patch +++ b/patches/server/Synchronize-PalettedContainer-instead-of-ThreadingDe.patch @@ -54,7 +54,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 int j = this.data.storage.getAndSet(index, i); return this.data.palette.valueFor(j); @@ -0,0 +0,0 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - + } } - private void set(int index, T value) { @@ -63,7 +63,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.data.storage.set(index, i); } @@ -0,0 +0,0 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - }); + intSet.forEach(id -> action.accept(palette.valueFor(id))); } - public void read(FriendlyByteBuf buf) { diff --git a/patches/server/Use-Velocity-compression-and-cipher-natives.patch b/patches/server/Use-Velocity-compression-and-cipher-natives.patch index 0ee0e5b92..9d51f8829 100644 --- a/patches/server/Use-Velocity-compression-and-cipher-natives.patch +++ b/patches/server/Use-Velocity-compression-and-cipher-natives.patch @@ -179,8 +179,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public class CompressionEncoder extends MessageToByteEncoder { - private final byte[] encodeBuf = new byte[8192]; -+ private final byte[] encodeBuf; // Paper - Use Velocity cipher ++ @javax.annotation.Nullable private final byte[] encodeBuf; // Paper - Use Velocity cipher ++ @javax.annotation.Nullable // Paper - Use Velocity cipher private final Deflater deflater; ++ @javax.annotation.Nullable // Paper - Use Velocity cipher + private final com.velocitypowered.natives.compression.VelocityCompressor compressor; // Paper - Use Velocity cipher private int threshold; @@ -188,7 +190,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public CompressionEncoder(int compressionThreshold) { + this(null, compressionThreshold); + } -+ public CompressionEncoder(com.velocitypowered.natives.compression.VelocityCompressor compressor, int compressionThreshold) { ++ public CompressionEncoder(@javax.annotation.Nullable com.velocitypowered.natives.compression.VelocityCompressor compressor, int compressionThreshold) { this.threshold = compressionThreshold; - this.deflater = new Deflater(); + if (compressor == null) { @@ -209,8 +211,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 VarInt.write(byteBuf2, 0); byteBuf2.writeBytes(byteBuf); } else { -+ // Paper start - Use Velocity cipher -+ if (this.deflater != null) { ++ if (this.deflater != null) { // Paper - Use Velocity cipher byte[] bs = new byte[i]; byteBuf.readBytes(bs); VarInt.write(byteBuf2, bs.length); @@ -218,6 +219,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } this.deflater.reset(); ++ // Paper start - Use Velocity cipher + return; + } + @@ -228,12 +230,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } finally { + compatibleIn.release(); + } -+ // Paper end - Use Velocity cipher - } - - } - -+ // Paper start - Use Velocity cipher ++ } ++ } ++ + @Override + protected ByteBuf allocateBuffer(ChannelHandlerContext ctx, ByteBuf msg, boolean preferDirect) throws Exception{ + if (this.compressor != null) { @@ -256,13 +255,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { + if (this.compressor != null) { + this.compressor.close(); -+ } -+ } -+ // Paper end - Use Velocity cipher -+ - public int getThreshold() { - return this.threshold; ++ // Paper end - Use Velocity cipher + } } + diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/network/Connection.java diff --git a/patches/server/Use-a-Shared-Random-for-Entities.patch b/patches/server/Use-a-Shared-Random-for-Entities.patch index f2362291f..26cd4a976 100644 --- a/patches/server/Use-a-Shared-Random-for-Entities.patch +++ b/patches/server/Use-a-Shared-Random-for-Entities.patch @@ -106,8 +106,8 @@ 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 - Share random for entities to make them more random +- this.random.setSeed(this.getId()); ++ //this.random.setSeed(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/Validate-ResourceLocation-in-NBT-reading.patch b/patches/server/Validate-ResourceLocation-in-NBT-reading.patch index c156da55b..836160872 100644 --- a/patches/server/Validate-ResourceLocation-in-NBT-reading.patch +++ b/patches/server/Validate-ResourceLocation-in-NBT-reading.patch @@ -109,7 +109,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.setLootTable(ResourceLocation.tryParse(nbt.getString("LootTable"))); // Paper - Validate ResourceLocation this.setLootTableSeed(nbt.getLong("LootTableSeed")); } - + ContainerHelper.loadAllItems(nbt, this.getItemStacks()); // Paper - always load the items, table may still remain diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java diff --git a/patches/server/Write-SavedData-IO-async.patch b/patches/server/Write-SavedData-IO-async.patch index 1eba3b099..3bd690831 100644 --- a/patches/server/Write-SavedData-IO-async.patch +++ b/patches/server/Write-SavedData-IO-async.patch @@ -186,5 +186,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end - Write SavedData IO async } - }); + } diff --git a/patches/server/check-global-player-list-where-appropriate.patch b/patches/server/check-global-player-list-where-appropriate.patch index 01847bc23..f9a412126 100644 --- a/patches/server/check-global-player-list-where-appropriate.patch +++ b/patches/server/check-global-player-list-where-appropriate.patch @@ -80,6 +80,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Nullable + private static ServerPlayer tryGetPlayer0(@Nullable Entity entity) { + // Paper end - check global player list where appropriate - if (entity instanceof ServerPlayer serverPlayer) { - return serverPlayer; + if (entity instanceof ServerPlayer) { + return (ServerPlayer)entity; } else { diff --git a/patches/server/living-entity-allow-attribute-registration.patch b/patches/server/living-entity-allow-attribute-registration.patch index 43119db07..744b47105 100644 --- a/patches/server/living-entity-allow-attribute-registration.patch +++ b/patches/server/living-entity-allow-attribute-registration.patch @@ -9,8 +9,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java +++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java @@ -0,0 +0,0 @@ public class AttributeMap { + }, () -> LOGGER.warn("Ignoring unknown attribute '{}'", string)); } - } + + // Paper - start - living entity allow attribute registration