aboutsummaryrefslogtreecommitdiffhomepage
path: root/paper-server
diff options
context:
space:
mode:
authorNassim Jahnke <[email protected]>2024-12-21 13:21:47 +0100
committerNassim Jahnke <[email protected]>2024-12-21 13:21:47 +0100
commit82216a59fef17863c86192c2754417480baa71c1 (patch)
treea306753dfabe366899eb3db881ed76b85e9ea746 /paper-server
parente0593e9286838e696db5efd2883cf8ef3d41528e (diff)
downloadPaper-82216a59fef17863c86192c2754417480baa71c1.tar.gz
Paper-82216a59fef17863c86192c2754417480baa71c1.zip
Apply some feature patches to files instead
They're small and/or really shouldn't be left unapplied
Diffstat (limited to 'paper-server')
-rw-r--r--paper-server/patches/features/0002-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch98
-rw-r--r--paper-server/patches/features/0003-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch135
-rw-r--r--paper-server/patches/features/0014-Check-distance-in-entity-interactions.patch68
-rw-r--r--paper-server/patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch244
-rw-r--r--paper-server/patches/sources/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java.patch (renamed from paper-server/patches/features/0001-Add-PaperHooks.patch)258
-rw-r--r--paper-server/patches/sources/net/minecraft/Util.java.patch8
-rw-r--r--paper-server/patches/sources/net/minecraft/core/Vec3i.java.patch11
-rw-r--r--paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch9
-rw-r--r--paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch15
-rw-r--r--paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch21
-rw-r--r--paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch9
-rw-r--r--paper-server/patches/sources/net/minecraft/world/level/Level.java.patch9
-rw-r--r--paper-server/patches/sources/net/minecraft/world/level/chunk/ChunkAccess.java.patch8
-rw-r--r--paper-server/patches/sources/net/minecraft/world/level/chunk/ImposterProtoChunk.java.patch15
-rw-r--r--paper-server/patches/sources/net/minecraft/world/level/chunk/ProtoChunk.java.patch21
-rw-r--r--paper-server/patches/sources/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java.patch73
16 files changed, 424 insertions, 578 deletions
diff --git a/paper-server/patches/features/0002-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch b/paper-server/patches/features/0002-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch
deleted file mode 100644
index 4f1d53e0e3..0000000000
--- a/paper-server/patches/features/0002-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar <[email protected]>
-Date: Thu, 3 Mar 2016 02:07:55 -0600
-Subject: [PATCH] Optimize isInWorldBounds and getBlockState for inlining
-
-Hot methods, so reduce # of instructions for the method.
-
-Move is valid location test to the BlockPosition class so that it can access local variables.
-
-Replace all calls to the new place to the unnecessary forward.
-
-Optimize getType and getBlockData to manually inline and optimize the calls
-
-diff --git a/net/minecraft/core/Vec3i.java b/net/minecraft/core/Vec3i.java
-index 03e2178430849d26c9826517e34ad069c94fc00a..11555ce7159ca6c8ddfe9691f86d3720c07cb086 100644
---- a/net/minecraft/core/Vec3i.java
-+++ b/net/minecraft/core/Vec3i.java
-@@ -28,6 +28,12 @@ public class Vec3i implements Comparable<Vec3i> {
- );
- }
-
-+ // Paper start
-+ public final boolean isInsideBuildHeightAndWorldBoundsHorizontal(net.minecraft.world.level.LevelHeightAccessor levelHeightAccessor) {
-+ return getX() >= -30000000 && getZ() >= -30000000 && getX() < 30000000 && getZ() < 30000000 && !levelHeightAccessor.isOutsideBuildHeight(getY());
-+ }
-+ // Paper end
-+
- public Vec3i(int x, int y, int z) {
- this.x = x;
- this.y = y;
-diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
-index e0239091729f6be138c037951fd5c138497ee358..691fee2e2097244126f4fac0f5d00bf6916b9766 100644
---- a/net/minecraft/world/level/Level.java
-+++ b/net/minecraft/world/level/Level.java
-@@ -350,7 +350,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
- // Paper end
-
- public boolean isInWorldBounds(BlockPos pos) {
-- return !this.isOutsideBuildHeight(pos) && isInWorldBoundsHorizontal(pos);
-+ return pos.isInsideBuildHeightAndWorldBoundsHorizontal(this); // Paper - use better/optimized check
- }
-
- public static boolean isInSpawnableBounds(BlockPos pos) {
-diff --git a/net/minecraft/world/level/chunk/ChunkAccess.java b/net/minecraft/world/level/chunk/ChunkAccess.java
-index f68f3f5e8ef39a0dc371e75110227a39791c04c8..12d9b532e466ec4e46920d409b5f1b3ae60b80f8 100644
---- a/net/minecraft/world/level/chunk/ChunkAccess.java
-+++ b/net/minecraft/world/level/chunk/ChunkAccess.java
-@@ -130,6 +130,7 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
- return GameEventListenerRegistry.NOOP;
- }
-
-+ public abstract BlockState getBlockState(final int x, final int y, final int z); // Paper
- @Nullable
- public abstract BlockState setBlockState(BlockPos pos, BlockState state, boolean isMoving);
-
-diff --git a/net/minecraft/world/level/chunk/ImposterProtoChunk.java b/net/minecraft/world/level/chunk/ImposterProtoChunk.java
-index 6c43e5e685871289968db8171342fd84189edcba..e7c0f4da8508fbca467326f475668d66454d7b77 100644
---- a/net/minecraft/world/level/chunk/ImposterProtoChunk.java
-+++ b/net/minecraft/world/level/chunk/ImposterProtoChunk.java
-@@ -56,6 +56,12 @@ public class ImposterProtoChunk extends ProtoChunk {
- public BlockState getBlockState(BlockPos pos) {
- return this.wrapped.getBlockState(pos);
- }
-+ // Paper start
-+ @Override
-+ public final BlockState getBlockState(final int x, final int y, final int z) {
-+ return this.wrapped.getBlockStateFinal(x, y, z);
-+ }
-+ // Paper end
-
- @Override
- public FluidState getFluidState(BlockPos pos) {
-diff --git a/net/minecraft/world/level/chunk/ProtoChunk.java b/net/minecraft/world/level/chunk/ProtoChunk.java
-index e359b5f694210f05e5675a995dbfc1a95cec76db..8c333d7f390d823a7c7f303e2f444f52ec16f799 100644
---- a/net/minecraft/world/level/chunk/ProtoChunk.java
-+++ b/net/minecraft/world/level/chunk/ProtoChunk.java
-@@ -99,12 +99,18 @@ public class ProtoChunk extends ChunkAccess {
-
- @Override
- public BlockState getBlockState(BlockPos pos) {
-- int y = pos.getY();
-+ // Paper start
-+ return getBlockState(pos.getX(), pos.getY(), pos.getZ());
-+ }
-+ public BlockState getBlockState(final int x, final int y, final int z) {
-+ // Paper end
- if (this.isOutsideBuildHeight(y)) {
- return Blocks.VOID_AIR.defaultBlockState();
- } else {
-- LevelChunkSection section = this.getSection(this.getSectionIndex(y));
-- return section.hasOnlyAir() ? Blocks.AIR.defaultBlockState() : section.getBlockState(pos.getX() & 15, y & 15, pos.getZ() & 15);
-+ // Paper start
-+ LevelChunkSection section = this.getSections()[this.getSectionIndex(y)];
-+ return section.hasOnlyAir() ? Blocks.AIR.defaultBlockState() : section.getBlockState(x & 15, y & 15, z & 15);
-+ // Paper end
- }
- }
-
diff --git a/paper-server/patches/features/0003-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch b/paper-server/patches/features/0003-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch
deleted file mode 100644
index a547df5f1b..0000000000
--- a/paper-server/patches/features/0003-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch
+++ /dev/null
@@ -1,135 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar <[email protected]>
-Date: Fri, 29 Apr 2016 20:02:00 -0400
-Subject: [PATCH] Improve Maps (in item frames) performance and bug fixes
-
-Maps used a modified version of rendering to support plugin controlled
-imaging on maps. The Craft Map Renderer is much slower than Vanilla,
-causing maps in item frames to cause a noticeable hit on server performance.
-
-This updates the map system to not use the Craft system if we detect that no
-custom renderers are in use, defaulting to the much simpler Vanilla system.
-
-Additionally, numerous issues to player position tracking on maps has been fixed.
-
-diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
-index 1f66adcd70aae7eac3d9f9539163905695581631..34a53bf34d10c56e6f53ce9aab2fc2780509f2f1 100644
---- a/net/minecraft/server/level/ServerLevel.java
-+++ b/net/minecraft/server/level/ServerLevel.java
-@@ -2282,7 +2282,9 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
- }
-
- map.carriedByPlayers.remove(player);
-- map.carriedBy.removeIf(holdingPlayer -> holdingPlayer.player == player);
-+ if (map.carriedBy.removeIf(holdingPlayer -> holdingPlayer.player == player)) {
-+ map.decorations.remove(player.getName().getString()); // Paper
-+ }
- }
- }
- }
-diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
-index 36e0d3f225a71b75ece7bf3fceeba47af948a6df..ff5889f8fed0707a6654d9d21862e32e2ebc866d 100644
---- a/net/minecraft/server/level/ServerPlayer.java
-+++ b/net/minecraft/server/level/ServerPlayer.java
-@@ -2594,6 +2594,14 @@ public class ServerPlayer extends Player {
- this.awardStat(Stats.DROP);
- }
-
-+ // Paper start - remove player from map on drop
-+ if (item.getItem() == net.minecraft.world.item.Items.FILLED_MAP) {
-+ final MapItemSavedData mapData = MapItem.getSavedData(item, this.level());
-+ if (mapData != null) {
-+ mapData.tickCarriedBy(this, item);
-+ }
-+ }
-+ // Paper end - remove player from map on drop
- return itemEntity;
- }
- }
-diff --git a/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java b/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
-index fd50bd77e4dc7b18240afe5505c6e6f0f869c127..f60c2f3a3dfc69f50225b6ee7333ada5e9dfd090 100644
---- a/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
-+++ b/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
-@@ -67,6 +67,7 @@ public class MapItemSavedData extends SavedData {
- public final Map<String, MapDecoration> decorations = Maps.newLinkedHashMap();
- private final Map<String, MapFrame> frameMarkers = Maps.newHashMap();
- private int trackedDecorationCount;
-+ private org.bukkit.craftbukkit.map.RenderData vanillaRender = new org.bukkit.craftbukkit.map.RenderData(); // Paper
-
- // CraftBukkit start
- public final org.bukkit.craftbukkit.map.CraftMapView mapView;
-@@ -92,6 +93,7 @@ public class MapItemSavedData extends SavedData {
- // CraftBukkit start
- this.mapView = new org.bukkit.craftbukkit.map.CraftMapView(this);
- this.server = (org.bukkit.craftbukkit.CraftServer) org.bukkit.Bukkit.getServer();
-+ this.vanillaRender.buffer = colors; // Paper
- // CraftBukkit end
- }
-
-@@ -163,6 +165,7 @@ public class MapItemSavedData extends SavedData {
- if (byteArray.length == 16384) {
- mapItemSavedData.colors = byteArray;
- }
-+ mapItemSavedData.vanillaRender.buffer = byteArray; // Paper
-
- RegistryOps<Tag> registryOps = levelRegistry.createSerializationContext(NbtOps.INSTANCE);
-
-@@ -337,7 +340,7 @@ public class MapItemSavedData extends SavedData {
- this.trackedDecorationCount--;
- }
-
-- this.setDecorationsDirty();
-+ if (mapDecoration != null) this.setDecorationsDirty(); // Paper - only mark dirty if a change occurs
- }
-
- public static void addTargetDecoration(ItemStack stack, BlockPos pos, String type, Holder<MapDecorationType> mapDecorationType) {
-@@ -610,7 +613,16 @@ public class MapItemSavedData extends SavedData {
- @Nullable
- Packet<?> nextUpdatePacket(MapId mapId) {
- MapItemSavedData.MapPatch mapPatch;
-- org.bukkit.craftbukkit.map.RenderData render = MapItemSavedData.this.mapView.render((org.bukkit.craftbukkit.entity.CraftPlayer) this.player.getBukkitEntity()); // CraftBukkit
-+ // Paper start
-+ if (!this.dirtyData && this.tick % 5 != 0) {
-+ // this won't end up sending, so don't render it!
-+ this.tick++;
-+ return null;
-+ }
-+
-+ final boolean vanillaMaps = this.shouldUseVanillaMap();
-+ org.bukkit.craftbukkit.map.RenderData render = !vanillaMaps ? MapItemSavedData.this.mapView.render((org.bukkit.craftbukkit.entity.CraftPlayer) this.player.getBukkitEntity()) : MapItemSavedData.this.vanillaRender; // CraftBukkit // Paper
-+ // Paper end
- if (this.dirtyData) {
- this.dirtyData = false;
- mapPatch = this.createPatch(render.buffer); // CraftBukkit
-@@ -623,6 +635,7 @@ public class MapItemSavedData extends SavedData {
- this.dirtyDecorations = false;
- // CraftBukkit start
- java.util.Collection<MapDecoration> icons = new java.util.ArrayList<MapDecoration>();
-+ if (vanillaMaps) this.addSeenPlayers(icons); // Paper
-
- for (org.bukkit.map.MapCursor cursor : render.cursors) {
- if (cursor.isVisible()) {
-@@ -658,6 +671,23 @@ public class MapItemSavedData extends SavedData {
- private void markDecorationsDirty() {
- this.dirtyDecorations = true;
- }
-+
-+ // Paper start
-+ private void addSeenPlayers(java.util.Collection<MapDecoration> icons) {
-+ org.bukkit.entity.Player player = (org.bukkit.entity.Player) this.player.getBukkitEntity();
-+ MapItemSavedData.this.decorations.forEach((name, mapIcon) -> {
-+ // If this cursor is for a player check visibility with vanish system
-+ org.bukkit.entity.Player other = org.bukkit.Bukkit.getPlayerExact(name); // Spigot
-+ if (other == null || player.canSee(other)) {
-+ icons.add(mapIcon);
-+ }
-+ });
-+ }
-+
-+ private boolean shouldUseVanillaMap() {
-+ return mapView.getRenderers().size() == 1 && mapView.getRenderers().getFirst().getClass() == org.bukkit.craftbukkit.map.CraftMapRenderer.class;
-+ }
-+ // Paper end
- }
-
- record MapDecorationLocation(Holder<MapDecorationType> type, byte x, byte y, byte rot) {
diff --git a/paper-server/patches/features/0014-Check-distance-in-entity-interactions.patch b/paper-server/patches/features/0014-Check-distance-in-entity-interactions.patch
deleted file mode 100644
index 39272633a7..0000000000
--- a/paper-server/patches/features/0014-Check-distance-in-entity-interactions.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Spottedleaf <[email protected]>
-Date: Mon, 2 Aug 2021 10:10:40 +0200
-Subject: [PATCH] Check distance in entity interactions
-
-
-diff --git a/net/minecraft/Util.java b/net/minecraft/Util.java
-index ae1d53cefb9cede1c93cb8b22122a4a2d2d9a40c..80a7a85e1a03a1ca406259207e1ae3b909b3284f 100644
---- a/net/minecraft/Util.java
-+++ b/net/minecraft/Util.java
-@@ -130,6 +130,7 @@ public class Util {
- .findFirst()
- .orElseThrow(() -> new IllegalStateException("No jar file system provider found"));
- private static Consumer<String> thePauser = string -> {};
-+ public static final double COLLISION_EPSILON = 1.0E-7; // Paper - Check distance in entity interactions
-
- public static <K, V> Collector<Entry<? extends K, ? extends V>, ?, Map<K, V>> toMap() {
- return Collectors.toMap(Entry::getKey, Entry::getValue);
-diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
-index 9bf5addb07f40cc50e80a46c0ee7944e938620fb..635e6e49483194c43b0ab47b5e1bacfe84613c3a 100644
---- a/net/minecraft/world/entity/LivingEntity.java
-+++ b/net/minecraft/world/entity/LivingEntity.java
-@@ -1385,7 +1385,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
- this.hurtCurrentlyUsedShield(amount);
- f1 = amount;
- amount = 0.0F;
-- if (!damageSource.is(DamageTypeTags.IS_PROJECTILE) && damageSource.getDirectEntity() instanceof LivingEntity livingEntity) {
-+ if (!damageSource.is(DamageTypeTags.IS_PROJECTILE) && damageSource.getDirectEntity() instanceof LivingEntity livingEntity && livingEntity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper - Check distance in entity interactions
- this.blockUsingShield(livingEntity);
- }
-
-@@ -1470,6 +1470,14 @@ public abstract class LivingEntity extends Entity implements Attackable {
- d = damageSource.getSourcePosition().x() - this.getX();
- d1 = damageSource.getSourcePosition().z() - this.getZ();
- }
-+ // Paper start - Check distance in entity interactions; see for loop in knockback method
-+ if (Math.abs(d) > 200) {
-+ d = Math.random() - Math.random();
-+ }
-+ if (Math.abs(d1) > 200) {
-+ d1 = Math.random() - Math.random();
-+ }
-+ // Paper end - Check distance in entity interactions
-
- this.knockback(0.4F, d, d1, damageSource.getDirectEntity(), damageSource.getDirectEntity() == null ? io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.DAMAGE : io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK); // CraftBukkit // Paper - knockback events
- if (!flag) {
-@@ -2342,7 +2350,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
- this.hurtCurrentlyUsedShield((float) -event.getDamage(DamageModifier.BLOCKING));
- Entity entity = damageSource.getDirectEntity();
-
-- if (!damageSource.is(DamageTypeTags.IS_PROJECTILE) && entity instanceof LivingEntity) { // Paper - Fix shield disable inconsistency
-+ if (!damageSource.is(DamageTypeTags.IS_PROJECTILE) && entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper - Fix shield disable inconsistency & Check distance in entity interactions
- this.blockUsingShield((LivingEntity) entity);
- }
- }
-diff --git a/net/minecraft/world/entity/vehicle/AbstractBoat.java b/net/minecraft/world/entity/vehicle/AbstractBoat.java
-index 3bdb3b0984d0fee21b2c094e1d4c1f917ab68f92..54a4bf2f7df87b4a694187ade81ba158f83f0246 100644
---- a/net/minecraft/world/entity/vehicle/AbstractBoat.java
-+++ b/net/minecraft/world/entity/vehicle/AbstractBoat.java
-@@ -638,7 +638,7 @@ public abstract class AbstractBoat extends VehicleEntity implements Leashable {
- this.waterLevel = this.getY(1.0);
- double d2 = this.getWaterLevelAbove() - this.getBbHeight() + 0.101;
- if (this.level().noCollision(this, this.getBoundingBox().move(0.0, d2 - this.getY(), 0.0))) {
-- this.setPos(this.getX(), d2, this.getZ());
-+ this.move(MoverType.SELF, new Vec3(0.0D, d2 - this.getY(), 0.0D)); // Paper - Check distance in entity interactions // TODO Still needed??
- this.setDeltaMovement(this.getDeltaMovement().multiply(1.0, 0.0, 1.0));
- this.lastYd = 0.0;
- }
diff --git a/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch b/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch
new file mode 100644
index 0000000000..d736409b62
--- /dev/null
+++ b/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch
@@ -0,0 +1,244 @@
+--- /dev/null
++++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java
+@@ -1,0 +_,241 @@
++package ca.spottedleaf.moonrise.paper;
++
++import ca.spottedleaf.moonrise.common.PlatformHooks;
++import ca.spottedleaf.moonrise.paper.util.BaseChunkSystemHooks;
++import com.mojang.datafixers.DSL;
++import com.mojang.datafixers.DataFixer;
++import com.mojang.serialization.Dynamic;
++import java.util.Collection;
++import net.minecraft.core.BlockPos;
++import net.minecraft.nbt.CompoundTag;
++import net.minecraft.nbt.NbtOps;
++import net.minecraft.server.level.ChunkHolder;
++import net.minecraft.server.level.GenerationChunkHolder;
++import net.minecraft.server.level.ServerLevel;
++import net.minecraft.server.level.ServerPlayer;
++import net.minecraft.world.entity.Entity;
++import net.minecraft.world.entity.boss.EnderDragonPart;
++import net.minecraft.world.level.BlockGetter;
++import net.minecraft.world.level.ChunkPos;
++import net.minecraft.world.level.Level;
++import net.minecraft.world.level.block.state.BlockState;
++import net.minecraft.world.level.chunk.ChunkAccess;
++import net.minecraft.world.level.chunk.LevelChunk;
++import net.minecraft.world.level.chunk.ProtoChunk;
++import net.minecraft.world.level.chunk.storage.SerializableChunkData;
++import net.minecraft.world.level.entity.EntityTypeTest;
++import net.minecraft.world.phys.AABB;
++import java.util.List;
++import java.util.function.Predicate;
++
++public final class PaperHooks extends BaseChunkSystemHooks implements PlatformHooks {
++
++ @Override
++ public String getBrand() {
++ return "Paper";
++ }
++
++ @Override
++ public int getLightEmission(final BlockState blockState, final BlockGetter world, final BlockPos pos) {
++ return blockState.getLightEmission();
++ }
++
++ @Override
++ public Predicate<BlockState> maybeHasLightEmission() {
++ return (final BlockState state) -> {
++ return state.getLightEmission() != 0;
++ };
++ }
++
++ @Override
++ public boolean hasCurrentlyLoadingChunk() {
++ return false;
++ }
++
++ @Override
++ public LevelChunk getCurrentlyLoadingChunk(final GenerationChunkHolder holder) {
++ return null;
++ }
++
++ @Override
++ public void setCurrentlyLoading(final GenerationChunkHolder holder, final LevelChunk levelChunk) {
++
++ }
++
++ @Override
++ public void chunkFullStatusComplete(final LevelChunk newChunk, final ProtoChunk original) {
++
++ }
++
++ @Override
++ public boolean allowAsyncTicketUpdates() {
++ return true;
++ }
++
++ @Override
++ public void onChunkHolderTicketChange(final ServerLevel world, final ChunkHolder holder, final int oldLevel, final int newLevel) {
++
++ }
++
++ @Override
++ public void chunkUnloadFromWorld(final LevelChunk chunk) {
++
++ }
++
++ @Override
++ public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data) {
++
++ }
++
++ @Override
++ public void onChunkWatch(final ServerLevel world, final LevelChunk chunk, final ServerPlayer player) {
++
++ }
++
++ @Override
++ public void onChunkUnWatch(final ServerLevel world, final ChunkPos chunk, final ServerPlayer player) {
++
++ }
++
++ @Override
++ public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate<? super Entity> predicate, final List<Entity> into) {
++ final Collection<EnderDragonPart> parts = world.dragonParts();
++ if (parts.isEmpty()) {
++ return;
++ }
++
++ for (final EnderDragonPart part : parts) {
++ if (part != entity && part.getBoundingBox().intersects(boundingBox) && (predicate == null || predicate.test(part))) {
++ into.add(part);
++ }
++ }
++ }
++
++ @Override
++ public <T extends Entity> void addToGetEntities(final Level world, final EntityTypeTest<Entity, T> entityTypeTest, final AABB boundingBox, final Predicate<? super T> predicate, final List<? super T> into, final int maxCount) {
++ if (into.size() >= maxCount) {
++ // fix neoforge issue: do not add if list is already full
++ return;
++ }
++
++ final Collection<EnderDragonPart> parts = world.dragonParts();
++ if (parts.isEmpty()) {
++ return;
++ }
++ for (final EnderDragonPart part : parts) {
++ if (!part.getBoundingBox().intersects(boundingBox)) {
++ continue;
++ }
++ final T casted = (T)entityTypeTest.tryCast(part);
++ if (casted != null && (predicate == null || predicate.test(casted))) {
++ into.add(casted);
++ if (into.size() >= maxCount) {
++ break;
++ }
++ }
++ }
++ }
++
++ @Override
++ public void entityMove(final Entity entity, final long oldSection, final long newSection) {
++
++ }
++
++ @Override
++ public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event) {
++ return true;
++ }
++
++ @Override
++ public boolean configFixMC224294() {
++ return true;
++ }
++
++ @Override
++ public boolean configAutoConfigSendDistance() {
++ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.autoConfigSendDistance;
++ }
++
++ @Override
++ public double configPlayerMaxLoadRate() {
++ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkLoadRate;
++ }
++
++ @Override
++ public double configPlayerMaxGenRate() {
++ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkGenerateRate;
++ }
++
++ @Override
++ public double configPlayerMaxSendRate() {
++ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkSendRate;
++ }
++
++ @Override
++ public int configPlayerMaxConcurrentLoads() {
++ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkLoads;
++ }
++
++ @Override
++ public int configPlayerMaxConcurrentGens() {
++ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkGenerates;
++ }
++
++ @Override
++ public long configAutoSaveInterval(final ServerLevel world) {
++ return world.paperConfig().chunks.autoSaveInterval.value();
++ }
++
++ @Override
++ public int configMaxAutoSavePerTick(final ServerLevel world) {
++ return world.paperConfig().chunks.maxAutoSaveChunksPerTick;
++ }
++
++ @Override
++ public boolean configFixMC159283() {
++ return true;
++ }
++
++ @Override
++ public boolean forceNoSave(final ChunkAccess chunk) {
++ return chunk instanceof LevelChunk levelChunk && levelChunk.mustNotSave;
++ }
++
++ @Override
++ public CompoundTag convertNBT(final DSL.TypeReference type, final DataFixer dataFixer, final CompoundTag nbt,
++ final int fromVersion, final int toVersion) {
++ return (CompoundTag)dataFixer.update(
++ type, new Dynamic<>(NbtOps.INSTANCE, nbt), fromVersion, toVersion
++ ).getValue();
++ }
++
++ @Override
++ public boolean hasMainChunkLoadHook() {
++ return false;
++ }
++
++ @Override
++ public void mainChunkLoad(final ChunkAccess chunk, final SerializableChunkData chunkData) {
++
++ }
++
++ @Override
++ public List<Entity> modifySavedEntities(final ServerLevel world, final int chunkX, final int chunkZ, final List<Entity> entities) {
++ return entities;
++ }
++
++ @Override
++ public void unloadEntity(final Entity entity) {
++ entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, org.bukkit.event.entity.EntityRemoveEvent.Cause.UNLOAD);
++ }
++
++ @Override
++ public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk) {
++ net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities());
++ }
++
++ @Override
++ public int modifyEntityTrackingRange(final Entity entity, final int currentRange) {
++ return org.spigotmc.TrackingRange.getEntityTrackingRange(entity, currentRange);
++ }
++}
diff --git a/paper-server/patches/features/0001-Add-PaperHooks.patch b/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java.patch
index 5df4d535a5..1835941481 100644
--- a/paper-server/patches/features/0001-Add-PaperHooks.patch
+++ b/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java.patch
@@ -1,262 +1,6 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Spottedleaf <[email protected]>
-Date: Mon, 16 Dec 2024 09:03:35 -0800
-Subject: [PATCH] Add PaperHooks
-
-
-diff --git a/ca/spottedleaf/moonrise/paper/PaperHooks.java b/ca/spottedleaf/moonrise/paper/PaperHooks.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..2988c418b34d6f699a9c24406cfd6949465b64f0
---- /dev/null
-+++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java
-@@ -0,0 +1,241 @@
-+package ca.spottedleaf.moonrise.paper;
-+
-+import ca.spottedleaf.moonrise.common.PlatformHooks;
-+import ca.spottedleaf.moonrise.paper.util.BaseChunkSystemHooks;
-+import com.mojang.datafixers.DSL;
-+import com.mojang.datafixers.DataFixer;
-+import com.mojang.serialization.Dynamic;
-+import java.util.Collection;
-+import net.minecraft.core.BlockPos;
-+import net.minecraft.nbt.CompoundTag;
-+import net.minecraft.nbt.NbtOps;
-+import net.minecraft.server.level.ChunkHolder;
-+import net.minecraft.server.level.GenerationChunkHolder;
-+import net.minecraft.server.level.ServerLevel;
-+import net.minecraft.server.level.ServerPlayer;
-+import net.minecraft.world.entity.Entity;
-+import net.minecraft.world.entity.boss.EnderDragonPart;
-+import net.minecraft.world.level.BlockGetter;
-+import net.minecraft.world.level.ChunkPos;
-+import net.minecraft.world.level.Level;
-+import net.minecraft.world.level.block.state.BlockState;
-+import net.minecraft.world.level.chunk.ChunkAccess;
-+import net.minecraft.world.level.chunk.LevelChunk;
-+import net.minecraft.world.level.chunk.ProtoChunk;
-+import net.minecraft.world.level.chunk.storage.SerializableChunkData;
-+import net.minecraft.world.level.entity.EntityTypeTest;
-+import net.minecraft.world.phys.AABB;
-+import java.util.List;
-+import java.util.function.Predicate;
-+
-+public final class PaperHooks extends BaseChunkSystemHooks implements PlatformHooks {
-+
-+ @Override
-+ public String getBrand() {
-+ return "Paper";
-+ }
-+
-+ @Override
-+ public int getLightEmission(final BlockState blockState, final BlockGetter world, final BlockPos pos) {
-+ return blockState.getLightEmission();
-+ }
-+
-+ @Override
-+ public Predicate<BlockState> maybeHasLightEmission() {
-+ return (final BlockState state) -> {
-+ return state.getLightEmission() != 0;
-+ };
-+ }
-+
-+ @Override
-+ public boolean hasCurrentlyLoadingChunk() {
-+ return false;
-+ }
-+
-+ @Override
-+ public LevelChunk getCurrentlyLoadingChunk(final GenerationChunkHolder holder) {
-+ return null;
-+ }
-+
-+ @Override
-+ public void setCurrentlyLoading(final GenerationChunkHolder holder, final LevelChunk levelChunk) {
-+
-+ }
-+
-+ @Override
-+ public void chunkFullStatusComplete(final LevelChunk newChunk, final ProtoChunk original) {
-+
-+ }
-+
-+ @Override
-+ public boolean allowAsyncTicketUpdates() {
-+ return true;
-+ }
-+
-+ @Override
-+ public void onChunkHolderTicketChange(final ServerLevel world, final ChunkHolder holder, final int oldLevel, final int newLevel) {
-+
-+ }
-+
-+ @Override
-+ public void chunkUnloadFromWorld(final LevelChunk chunk) {
-+
-+ }
-+
-+ @Override
-+ public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data) {
-+
-+ }
-+
-+ @Override
-+ public void onChunkWatch(final ServerLevel world, final LevelChunk chunk, final ServerPlayer player) {
-+
-+ }
-+
-+ @Override
-+ public void onChunkUnWatch(final ServerLevel world, final ChunkPos chunk, final ServerPlayer player) {
-+
-+ }
-+
-+ @Override
-+ public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate<? super Entity> predicate, final List<Entity> into) {
-+ final Collection<EnderDragonPart> parts = world.dragonParts();
-+ if (parts.isEmpty()) {
-+ return;
-+ }
-+
-+ for (final EnderDragonPart part : parts) {
-+ if (part != entity && part.getBoundingBox().intersects(boundingBox) && (predicate == null || predicate.test(part))) {
-+ into.add(part);
-+ }
-+ }
-+ }
-+
-+ @Override
-+ public <T extends Entity> void addToGetEntities(final Level world, final EntityTypeTest<Entity, T> entityTypeTest, final AABB boundingBox, final Predicate<? super T> predicate, final List<? super T> into, final int maxCount) {
-+ if (into.size() >= maxCount) {
-+ // fix neoforge issue: do not add if list is already full
-+ return;
-+ }
-+
-+ final Collection<EnderDragonPart> parts = world.dragonParts();
-+ if (parts.isEmpty()) {
-+ return;
-+ }
-+ for (final EnderDragonPart part : parts) {
-+ if (!part.getBoundingBox().intersects(boundingBox)) {
-+ continue;
-+ }
-+ final T casted = (T)entityTypeTest.tryCast(part);
-+ if (casted != null && (predicate == null || predicate.test(casted))) {
-+ into.add(casted);
-+ if (into.size() >= maxCount) {
-+ break;
-+ }
-+ }
-+ }
-+ }
-+
-+ @Override
-+ public void entityMove(final Entity entity, final long oldSection, final long newSection) {
-+
-+ }
-+
-+ @Override
-+ public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event) {
-+ return true;
-+ }
-+
-+ @Override
-+ public boolean configFixMC224294() {
-+ return true;
-+ }
-+
-+ @Override
-+ public boolean configAutoConfigSendDistance() {
-+ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.autoConfigSendDistance;
-+ }
-+
-+ @Override
-+ public double configPlayerMaxLoadRate() {
-+ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkLoadRate;
-+ }
-+
-+ @Override
-+ public double configPlayerMaxGenRate() {
-+ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkGenerateRate;
-+ }
-+
-+ @Override
-+ public double configPlayerMaxSendRate() {
-+ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkSendRate;
-+ }
-+
-+ @Override
-+ public int configPlayerMaxConcurrentLoads() {
-+ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkLoads;
-+ }
-+
-+ @Override
-+ public int configPlayerMaxConcurrentGens() {
-+ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkGenerates;
-+ }
-+
-+ @Override
-+ public long configAutoSaveInterval(final ServerLevel world) {
-+ return world.paperConfig().chunks.autoSaveInterval.value();
-+ }
-+
-+ @Override
-+ public int configMaxAutoSavePerTick(final ServerLevel world) {
-+ return world.paperConfig().chunks.maxAutoSaveChunksPerTick;
-+ }
-+
-+ @Override
-+ public boolean configFixMC159283() {
-+ return true;
-+ }
-+
-+ @Override
-+ public boolean forceNoSave(final ChunkAccess chunk) {
-+ return chunk instanceof LevelChunk levelChunk && levelChunk.mustNotSave;
-+ }
-+
-+ @Override
-+ public CompoundTag convertNBT(final DSL.TypeReference type, final DataFixer dataFixer, final CompoundTag nbt,
-+ final int fromVersion, final int toVersion) {
-+ return (CompoundTag)dataFixer.update(
-+ type, new Dynamic<>(NbtOps.INSTANCE, nbt), fromVersion, toVersion
-+ ).getValue();
-+ }
-+
-+ @Override
-+ public boolean hasMainChunkLoadHook() {
-+ return false;
-+ }
-+
-+ @Override
-+ public void mainChunkLoad(final ChunkAccess chunk, final SerializableChunkData chunkData) {
-+
-+ }
-+
-+ @Override
-+ public List<Entity> modifySavedEntities(final ServerLevel world, final int chunkX, final int chunkZ, final List<Entity> entities) {
-+ return entities;
-+ }
-+
-+ @Override
-+ public void unloadEntity(final Entity entity) {
-+ entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, org.bukkit.event.entity.EntityRemoveEvent.Cause.UNLOAD);
-+ }
-+
-+ @Override
-+ public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk) {
-+ net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities());
-+ }
-+
-+ @Override
-+ public int modifyEntityTrackingRange(final Entity entity, final int currentRange) {
-+ return org.spigotmc.TrackingRange.getEntityTrackingRange(entity, currentRange);
-+ }
-+}
-diff --git a/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java b/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..34b45bc11124efb22f0f3ae5b2ad8f445c719476
--- /dev/null
+++ b/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java
-@@ -0,0 +1,332 @@
+@@ -1,0 +_,332 @@
+package ca.spottedleaf.moonrise.paper.util;
+
+import ca.spottedleaf.concurrentutil.util.Priority;
diff --git a/paper-server/patches/sources/net/minecraft/Util.java.patch b/paper-server/patches/sources/net/minecraft/Util.java.patch
index 946139d552..ebf86ad6c2 100644
--- a/paper-server/patches/sources/net/minecraft/Util.java.patch
+++ b/paper-server/patches/sources/net/minecraft/Util.java.patch
@@ -28,6 +28,14 @@
private static final DateTimeFormatter FILENAME_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss", Locale.ROOT);
public static final int LINEAR_LOOKUP_THRESHOLD = 8;
private static final Set<String> ALLOWED_UNTRUSTED_LINK_PROTOCOLS = Set.of("http", "https");
+@@ -113,6 +_,7 @@
+ .findFirst()
+ .orElseThrow(() -> new IllegalStateException("No jar file system provider found"));
+ private static Consumer<String> thePauser = string -> {};
++ public static final double COLLISION_EPSILON = 1.0E-7; // Paper - Check distance in entity interactions
+
+ public static <K, V> Collector<Entry<? extends K, ? extends V>, ?, Map<K, V>> toMap() {
+ return Collectors.toMap(Entry::getKey, Entry::getValue);
@@ -135,7 +_,7 @@
}
diff --git a/paper-server/patches/sources/net/minecraft/core/Vec3i.java.patch b/paper-server/patches/sources/net/minecraft/core/Vec3i.java.patch
index cd374686c0..09caa51586 100644
--- a/paper-server/patches/sources/net/minecraft/core/Vec3i.java.patch
+++ b/paper-server/patches/sources/net/minecraft/core/Vec3i.java.patch
@@ -47,3 +47,14 @@
return this.z;
}
+@@ -235,4 +_,10 @@
+ public String toShortString() {
+ return this.getX() + ", " + this.getY() + ", " + this.getZ();
+ }
++
++ // Paper start - Perf: Optimize isInWorldBounds
++ public final boolean isInsideBuildHeightAndWorldBoundsHorizontal(final net.minecraft.world.level.LevelHeightAccessor levelHeightAccessor) {
++ return this.getX() >= -30000000 && this.getZ() >= -30000000 && this.getX() < 30000000 && this.getZ() < 30000000 && !levelHeightAccessor.isOutsideBuildHeight(this.getY());
++ }
++ // Paper end - Perf: Optimize isInWorldBounds
+ }
diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch
index b8d9ca742e..6bb71f81a0 100644
--- a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch
+++ b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch
@@ -1059,7 +1059,7 @@
String string = "onTrackingStart called during navigation iteration";
Util.logAndPauseIfInIde(
"onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration")
-@@ -1757,10 +_,51 @@
+@@ -1757,10 +_,52 @@
}
entity.updateDynamicGameEventListener(DynamicGameEventListener::add);
@@ -1081,8 +1081,7 @@
@Override
public void onTrackingEnd(Entity entity) {
+ org.spigotmc.AsyncCatcher.catchOp("entity unregister"); // Spigot
-+ // Spigot start
-+ // TODO I don't think this is needed anymore
++ // Spigot start // TODO I don't think this is needed anymore
+ if (entity instanceof Player player) {
+ for (final ServerLevel level : ServerLevel.this.getServer().getAllLevels()) {
+ for (final Optional<net.minecraft.world.level.saveddata.SavedData> savedData : level.getDataStorage().cache.values()) {
@@ -1091,7 +1090,9 @@
+ }
+
+ map.carriedByPlayers.remove(player);
-+ map.carriedBy.removeIf(holdingPlayer -> holdingPlayer.player == player);
++ if (map.carriedBy.removeIf(holdingPlayer -> holdingPlayer.player == player)) {
++ map.decorations.remove(player.getName().getString());
++ }
+ }
+ }
+ }
diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch
index 7c69b49dd9..c32e052b23 100644
--- a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch
+++ b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch
@@ -1342,7 +1342,7 @@
}
public SectionPos getLastSectionPos() {
-@@ -1930,16 +_,41 @@
+@@ -1930,21 +_,54 @@
}
@Override
@@ -1386,6 +1386,19 @@
}
this.awardStat(Stats.DROP);
+ }
+
++ // Paper start - remove player from map on drop
++ if (item.getItem() == net.minecraft.world.item.Items.FILLED_MAP) {
++ final MapItemSavedData mapData = MapItem.getSavedData(item, this.level());
++ if (mapData != null) {
++ mapData.tickCarriedBy(this, item);
++ }
++ }
++ // Paper end - remove player from map on drop
+ return itemEntity;
+ }
+ }
@@ -1955,6 +_,11 @@
return null;
} else {
diff --git a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch
index df1aedb289..84c9704c87 100644
--- a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch
@@ -497,7 +497,7 @@
return false;
} else if (damageSource.is(DamageTypeTags.IS_FIRE) && this.hasEffect(MobEffects.FIRE_RESISTANCE)) {
return false;
-@@ -1116,10 +_,11 @@
+@@ -1116,47 +_,71 @@
amount = 0.0F;
}
@@ -512,7 +512,11 @@
this.hurtCurrentlyUsedShield(amount);
f1 = amount;
amount = 0.0F;
-@@ -1130,33 +_,56 @@
+- if (!damageSource.is(DamageTypeTags.IS_PROJECTILE) && damageSource.getDirectEntity() instanceof LivingEntity livingEntity) {
++ if (!damageSource.is(DamageTypeTags.IS_PROJECTILE) && damageSource.getDirectEntity() instanceof LivingEntity livingEntity && livingEntity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper - Check distance in entity interactions
+ this.blockUsingShield(livingEntity);
+ }
+
flag = true;
}
@@ -584,9 +588,18 @@
this.markHurt();
}
-@@ -1186,7 +_,7 @@
+@@ -1185,8 +_,16 @@
+ d = damageSource.getSourcePosition().x() - this.getX();
d1 = damageSource.getSourcePosition().z() - this.getZ();
}
++ // Paper start - Check distance in entity interactions; see for loop in knockback method
++ if (Math.abs(d) > 200) {
++ d = Math.random() - Math.random();
++ }
++ if (Math.abs(d1) > 200) {
++ d1 = Math.random() - Math.random();
++ }
++ // Paper end - Check distance in entity interactions
- this.knockback(0.4F, d, d1);
+ this.knockback(0.4F, d, d1, damageSource.getDirectEntity(), damageSource.getDirectEntity() == null ? io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.DAMAGE : io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK); // CraftBukkit // Paper - knockback events
@@ -1110,7 +1123,7 @@
+ this.hurtCurrentlyUsedShield((float) -event.getDamage(DamageModifier.BLOCKING));
+ Entity entity = damageSource.getDirectEntity();
+
-+ if (!damageSource.is(DamageTypeTags.IS_PROJECTILE) && entity instanceof LivingEntity) { // Paper - Fix shield disable inconsistency
++ if (!damageSource.is(DamageTypeTags.IS_PROJECTILE) && entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper - Fix shield disable inconsistency & Check distance in entity interactions
+ this.blockUsingShield((LivingEntity) entity);
+ }
+ }
diff --git a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch
index a5d91baad1..3d61d83b48 100644
--- a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch
@@ -75,6 +75,15 @@
this.applyEffectsFromBlocks();
this.applyEffectsFromBlocks();
this.tickBubbleColumn();
+@@ -598,7 +_,7 @@
+ this.waterLevel = this.getY(1.0);
+ double d2 = this.getWaterLevelAbove() - this.getBbHeight() + 0.101;
+ if (this.level().noCollision(this, this.getBoundingBox().move(0.0, d2 - this.getY(), 0.0))) {
+- this.setPos(this.getX(), d2, this.getZ());
++ this.move(MoverType.SELF, new Vec3(0.0D, d2 - this.getY(), 0.0D)); // Paper - Fix some exploit with boats // TODO Still needed?
+ this.setDeltaMovement(this.getDeltaMovement().multiply(1.0, 0.0, 1.0));
+ this.lastYd = 0.0;
+ }
@@ -762,11 +_,18 @@
@Override
diff --git a/paper-server/patches/sources/net/minecraft/world/level/Level.java.patch b/paper-server/patches/sources/net/minecraft/world/level/Level.java.patch
index 66f1c0a2ed..9958bd72b6 100644
--- a/paper-server/patches/sources/net/minecraft/world/level/Level.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/level/Level.java.patch
@@ -241,7 +241,7 @@
@Override
public boolean isClientSide() {
-@@ -167,6 +_,13 @@
+@@ -167,8 +_,15 @@
return null;
}
@@ -253,14 +253,17 @@
+ // Paper end
+
public boolean isInWorldBounds(BlockPos pos) {
- return !this.isOutsideBuildHeight(pos) && isInWorldBoundsHorizontal(pos);
+- return !this.isOutsideBuildHeight(pos) && isInWorldBoundsHorizontal(pos);
++ return pos.isInsideBuildHeightAndWorldBoundsHorizontal(this); // Paper - Perf: Optimize isInWorldBounds
}
+
+ public static boolean isInSpawnableBounds(BlockPos pos) {
@@ -176,21 +_,84 @@
}
private static boolean isInWorldBoundsHorizontal(BlockPos pos) {
- return pos.getX() >= -30000000 && pos.getZ() >= -30000000 && pos.getX() < 30000000 && pos.getZ() < 30000000;
-+ return pos.getX() >= -30000000 && pos.getZ() >= -30000000 && pos.getX() < 30000000 && pos.getZ() < 30000000; // Diff on change warnUnsafeChunk()
++ return pos.getX() >= -30000000 && pos.getZ() >= -30000000 && pos.getX() < 30000000 && pos.getZ() < 30000000; // Diff on change warnUnsafeChunk() and isInsideBuildHeightAndWorldBoundsHorizontal
}
private static boolean isOutsideSpawnableHeight(int y) {
diff --git a/paper-server/patches/sources/net/minecraft/world/level/chunk/ChunkAccess.java.patch b/paper-server/patches/sources/net/minecraft/world/level/chunk/ChunkAccess.java.patch
index baf2047d7c..d1b5769824 100644
--- a/paper-server/patches/sources/net/minecraft/world/level/chunk/ChunkAccess.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/level/chunk/ChunkAccess.java.patch
@@ -39,6 +39,14 @@
}
private static void replaceMissingSections(Registry<Biome> biomeRegistry, LevelChunkSection[] sections) {
+@@ -123,6 +_,7 @@
+ return GameEventListenerRegistry.NOOP;
+ }
+
++ public abstract BlockState getBlockState(final int x, final int y, final int z); // Paper
+ @Nullable
+ public abstract BlockState setBlockState(BlockPos pos, BlockState state, boolean isMoving);
+
@@ -273,6 +_,7 @@
public boolean tryMarkSaved() {
if (this.unsaved) {
diff --git a/paper-server/patches/sources/net/minecraft/world/level/chunk/ImposterProtoChunk.java.patch b/paper-server/patches/sources/net/minecraft/world/level/chunk/ImposterProtoChunk.java.patch
new file mode 100644
index 0000000000..da521db813
--- /dev/null
+++ b/paper-server/patches/sources/net/minecraft/world/level/chunk/ImposterProtoChunk.java.patch
@@ -0,0 +1,15 @@
+--- a/net/minecraft/world/level/chunk/ImposterProtoChunk.java
++++ b/net/minecraft/world/level/chunk/ImposterProtoChunk.java
+@@ -56,6 +_,12 @@
+ public BlockState getBlockState(BlockPos pos) {
+ return this.wrapped.getBlockState(pos);
+ }
++ // Paper start
++ @Override
++ public final BlockState getBlockState(final int x, final int y, final int z) {
++ return this.wrapped.getBlockStateFinal(x, y, z);
++ }
++ // Paper end
+
+ @Override
+ public FluidState getFluidState(BlockPos pos) {
diff --git a/paper-server/patches/sources/net/minecraft/world/level/chunk/ProtoChunk.java.patch b/paper-server/patches/sources/net/minecraft/world/level/chunk/ProtoChunk.java.patch
index 9988645334..d0111479a1 100644
--- a/paper-server/patches/sources/net/minecraft/world/level/chunk/ProtoChunk.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/level/chunk/ProtoChunk.java.patch
@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/chunk/ProtoChunk.java
+++ b/net/minecraft/world/level/chunk/ProtoChunk.java
-@@ -85,6 +_,18 @@
+@@ -85,14 +_,32 @@
return new ChunkAccess.PackedTicks(this.blockTicks.pack(gametime), this.fluidTicks.pack(gametime));
}
@@ -18,4 +18,21 @@
+
@Override
public BlockState getBlockState(BlockPos pos) {
- int y = pos.getY();
+- int y = pos.getY();
++ // Paper start
++ return getBlockState(pos.getX(), pos.getY(), pos.getZ());
++ }
++ public BlockState getBlockState(final int x, final int y, final int z) {
++ // Paper end
+ if (this.isOutsideBuildHeight(y)) {
+ return Blocks.VOID_AIR.defaultBlockState();
+ } else {
+- LevelChunkSection section = this.getSection(this.getSectionIndex(y));
+- return section.hasOnlyAir() ? Blocks.AIR.defaultBlockState() : section.getBlockState(pos.getX() & 15, y & 15, pos.getZ() & 15);
++ // Paper start
++ LevelChunkSection section = this.getSections()[this.getSectionIndex(y)];
++ return section.hasOnlyAir() ? Blocks.AIR.defaultBlockState() : section.getBlockState(x & 15, y & 15, z & 15);
++ // Paper end
+ }
+ }
+
diff --git a/paper-server/patches/sources/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java.patch b/paper-server/patches/sources/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java.patch
index b03e362a20..9aa3e55368 100644
--- a/paper-server/patches/sources/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java.patch
@@ -1,26 +1,35 @@
--- a/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
+++ b/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
+@@ -61,6 +_,7 @@
+ public byte scale;
+ public byte[] colors = new byte[16384];
+ public boolean locked;
++ private final org.bukkit.craftbukkit.map.RenderData vanillaRender = new org.bukkit.craftbukkit.map.RenderData(); // Paper - Use Vanilla map renderer when possible
+ public final List<MapItemSavedData.HoldingPlayer> carriedBy = Lists.newArrayList();
+ public final Map<Player, MapItemSavedData.HoldingPlayer> carriedByPlayers = Maps.newHashMap();
+ private final Map<String, MapBanner> bannerMarkers = Maps.newHashMap();
@@ -68,6 +_,13 @@
private final Map<String, MapFrame> frameMarkers = Maps.newHashMap();
private int trackedDecorationCount;
+ // CraftBukkit start
+ public final org.bukkit.craftbukkit.map.CraftMapView mapView;
-+ private org.bukkit.craftbukkit.CraftServer server;
-+ public java.util.UUID uniqueId = null;
++ private final org.bukkit.craftbukkit.CraftServer server;
++ public java.util.UUID uniqueId;
+ public MapId id;
+ // CraftBukkit end
+
public static SavedData.Factory<MapItemSavedData> factory() {
return new SavedData.Factory<>(() -> {
throw new IllegalStateException("Should never create an empty map saved data");
-@@ -82,6 +_,10 @@
+@@ -82,6 +_,11 @@
this.trackingPosition = trackingPosition;
this.unlimitedTracking = unlimitedTracking;
this.locked = locked;
+ // CraftBukkit start
+ this.mapView = new org.bukkit.craftbukkit.map.CraftMapView(this);
+ this.server = (org.bukkit.craftbukkit.CraftServer) org.bukkit.Bukkit.getServer();
++ this.vanillaRender.buffer = colors; // Paper - Use Vanilla map renderer when possible
+ // CraftBukkit end
}
@@ -76,6 +85,14 @@
int _int = tag.getInt("xCenter");
int _int1 = tag.getInt("zCenter");
byte b = (byte)Mth.clamp(tag.getByte("scale"), 0, 4);
+@@ -114,6 +_,7 @@
+ if (byteArray.length == 16384) {
+ mapItemSavedData.colors = byteArray;
+ }
++ mapItemSavedData.vanillaRender.buffer = byteArray; // Paper - Use Vanilla map renderer when possible
+
+ RegistryOps<Tag> registryOps = levelRegistry.createSerializationContext(NbtOps.INSTANCE);
+
@@ -154,6 +_,25 @@
.encodeStart(NbtOps.INSTANCE, this.dimension.location())
.resultOrPartial(LOGGER::error)
@@ -115,6 +132,15 @@
}
MapDecorations mapDecorations = mapStack.getOrDefault(DataComponents.MAP_DECORATIONS, MapDecorations.EMPTY);
+@@ -267,7 +_,7 @@
+ this.trackedDecorationCount--;
+ }
+
+- this.setDecorationsDirty();
++ if (mapDecoration != null) this.setDecorationsDirty(); // Paper - only mark dirty if a change occurs
+ }
+
+ public static void addTargetDecoration(ItemStack stack, BlockPos pos, String type, Holder<MapDecorationType> mapDecorationType) {
@@ -421,7 +_,7 @@
return true;
}
@@ -142,11 +168,21 @@
}
}
-@@ -540,17 +_,27 @@
+@@ -540,17 +_,38 @@
@Nullable
Packet<?> nextUpdatePacket(MapId mapId) {
MapItemSavedData.MapPatch mapPatch;
-+ org.bukkit.craftbukkit.map.RenderData render = MapItemSavedData.this.mapView.render((org.bukkit.craftbukkit.entity.CraftPlayer) this.player.getBukkitEntity()); // CraftBukkit
++ // Paper start
++ if (!this.dirtyData && this.tick % 5 != 0) {
++ // this won't end up sending, so don't render it!
++ this.tick++;
++ return null;
++ }
++
++ final boolean vanillaMaps = this.shouldUseVanillaMap();
++ // Use Vanilla map renderer when possible - much simpler/faster than the CB rendering
++ org.bukkit.craftbukkit.map.RenderData render = !vanillaMaps ? MapItemSavedData.this.mapView.render((org.bukkit.craftbukkit.entity.CraftPlayer) this.player.getBukkitEntity()) : MapItemSavedData.this.vanillaRender;
++ // Paper end
if (this.dirtyData) {
this.dirtyData = false;
- mapPatch = this.createPatch();
@@ -157,11 +193,12 @@
Collection<MapDecoration> collection;
- if (this.dirtyDecorations && this.tick++ % 5 == 0) {
-+ if ((true || this.dirtyDecorations) && this.tick++ % 5 == 0) { // CraftBukkit - custom maps don't update this yet
++ if ((true || this.dirtyDecorations) && this.tick++ % 5 == 0) { // CraftBukkit - custom maps don't update this yet // TODO fix this
this.dirtyDecorations = false;
- collection = MapItemSavedData.this.decorations.values();
+ // CraftBukkit start
+ java.util.Collection<MapDecoration> icons = new java.util.ArrayList<MapDecoration>();
++ if (vanillaMaps) this.addSeenPlayers(icons); // Paper
+
+ for (org.bukkit.map.MapCursor cursor : render.cursors) {
+ if (cursor.isVisible()) {
@@ -173,3 +210,27 @@
} else {
collection = null;
}
+@@ -578,6 +_,23 @@
+ private void markDecorationsDirty() {
+ this.dirtyDecorations = true;
+ }
++
++ // Paper start
++ private void addSeenPlayers(java.util.Collection<MapDecoration> icons) {
++ org.bukkit.entity.Player player = (org.bukkit.entity.Player) this.player.getBukkitEntity();
++ MapItemSavedData.this.decorations.forEach((name, mapIcon) -> {
++ // If this cursor is for a player check visibility with vanish system
++ org.bukkit.entity.Player other = org.bukkit.Bukkit.getPlayerExact(name); // Spigot
++ if (other == null || player.canSee(other)) {
++ icons.add(mapIcon);
++ }
++ });
++ }
++
++ private boolean shouldUseVanillaMap() {
++ return mapView.getRenderers().size() == 1 && mapView.getRenderers().getFirst().getClass() == org.bukkit.craftbukkit.map.CraftMapRenderer.class;
++ }
++ // Paper end
+ }
+
+ record MapDecorationLocation(Holder<MapDecorationType> type, byte x, byte y, byte rot) {