diff --git a/divinemc-api/paper-patches/features/0008-Paper-PR-Player-standing-on-position-API.patch b/divinemc-api/paper-patches/features/0008-Paper-PR-Player-standing-on-position-API.patch new file mode 100644 index 0000000..e4ca07b --- /dev/null +++ b/divinemc-api/paper-patches/features/0008-Paper-PR-Player-standing-on-position-API.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> +Date: Sun, 23 Mar 2025 16:52:42 +0300 +Subject: [PATCH] Paper PR: Player standing on position API + + +diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java +index 82117a1b258d43f68ff803c4c1af0a33c99065a8..cb8232faed9423dd570e3a6b0ea664182074a1ac 100644 +--- a/src/main/java/org/bukkit/entity/Entity.java ++++ b/src/main/java/org/bukkit/entity/Entity.java +@@ -1197,6 +1197,33 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent + void broadcastHurtAnimation(@NotNull java.util.Collection players); + // Paper end - broadcast hurt animation + ++ // Paper start - Player standing on position API ++ /** ++ * Gets the block that is currently being used to calculate movement effects (i.e. friction) on the entity. ++ *

++ * Examples: ++ * - When standing on a slab under an ice block, this will return the position of the ice block. ++ * - When flying on top of a flower placed on a grass block, this will return the position of the grass block (although this technically will not affect your movement). ++ * ++ * @return block used for movement effects ++ */ ++ @NotNull ++ org.bukkit.block.Block getMovementAffectingBlock(); ++ ++ /** ++ * Gets the block that is currently supporting the entity. ++ * This takes into account the collisions of blocks under the entity. ++ *

++ * Examples: ++ * - When standing on a slab under an ice block, this will return the position of the slab. ++ * - When flying on top of a flower placed on a grass block, this will return null, as no block is supporting the entity. ++ * ++ * @return block currently supporting the entity, or null if no block is currently supporting the entity ++ */ ++ @Nullable ++ org.bukkit.block.Block getSupportingBlock(); ++ // Paper end - Player standing on position API ++ + // Purpur start - Ridables + /** + * Get the riding player diff --git a/divinemc-api/src/main/java/io/papermc/paper/event/block/BlockFillBottleEvent.java b/divinemc-api/src/main/java/io/papermc/paper/event/block/BlockFillBottleEvent.java new file mode 100644 index 0000000..f6daff9 --- /dev/null +++ b/divinemc-api/src/main/java/io/papermc/paper/event/block/BlockFillBottleEvent.java @@ -0,0 +1,78 @@ +package io.papermc.paper.event.block; + +import org.bukkit.block.Block; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.block.BlockEvent; +import org.bukkit.inventory.ItemStack; +import org.jspecify.annotations.NullMarked; + +/** + * Called when a {@link org.bukkit.block.Dispenser} fills up a bottle. + */ +@NullMarked +public class BlockFillBottleEvent extends BlockEvent implements Cancellable { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final ItemStack bottle; + private ItemStack resultItem; + private boolean cancelled; + + public BlockFillBottleEvent(Block block, ItemStack bottle, ItemStack resultItem) { + super(block); + this.bottle = bottle; + this.resultItem = resultItem; + } + + /** + * Gets the bottle item that's being filled. + * + * @return the bottle item + */ + public ItemStack getBottle() { + return this.bottle; + } + + /** + * Gets the result of the glass bottle that's being filled. + * + * @return the result of the filling + */ + public ItemStack getResultItem() { + return this.resultItem; + } + + /** + * Sets the result of the glass bottle being filled. + * + * @param resultItem the result of the filling + */ + public void setResultItem(ItemStack resultItem) { + this.resultItem = resultItem; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + /** + * {@inheritDoc} + *

+ * Cancelling this event will prevent {@link #getBottle()} from being + * replaced/consumed. + */ + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/divinemc-api/src/main/java/io/papermc/paper/event/player/PlayerFillBottleEvent.java b/divinemc-api/src/main/java/io/papermc/paper/event/player/PlayerFillBottleEvent.java new file mode 100644 index 0000000..145fd46 --- /dev/null +++ b/divinemc-api/src/main/java/io/papermc/paper/event/player/PlayerFillBottleEvent.java @@ -0,0 +1,87 @@ +package io.papermc.paper.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; +import org.jspecify.annotations.NullMarked; + +@NullMarked +public class PlayerFillBottleEvent extends PlayerEvent implements Cancellable { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final EquipmentSlot hand; + private final ItemStack bottle; + private ItemStack resultItem; + private boolean cancelled; + + public PlayerFillBottleEvent(Player player, EquipmentSlot hand, ItemStack bottle, ItemStack resultItem) { + super(player); + this.hand = hand; + this.bottle = bottle; + this.resultItem = resultItem; + } + + /** + * The hand used to fill the bottle. + * + * @return the hand + */ + public EquipmentSlot getHand() { + return this.hand; + } + + /** + * Gets the bottle item that's being filled. + * + * @return the bottle item + */ + public ItemStack getBottle() { + return this.bottle; + } + + /** + * Gets the result of the bottle that's being filled. + * + * @return the result of the filling + */ + public ItemStack getResultItem() { + return this.resultItem; + } + + /** + * Sets the result of the bottle being filled. + * + * @param resultItem the result of the filling + */ + public void setResultItem(ItemStack resultItem) { + this.resultItem = resultItem; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + /** + * {@inheritDoc} + *

+ * Cancelling this event will prevent {@link #getBottle()} from being + * replaced/consumed. + */ + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/divinemc-server/minecraft-patches/features/0010-Math-Optimizations.patch b/divinemc-server/minecraft-patches/features/0010-Math-Optimizations.patch index 70db00d..54f44f6 100644 --- a/divinemc-server/minecraft-patches/features/0010-Math-Optimizations.patch +++ b/divinemc-server/minecraft-patches/features/0010-Math-Optimizations.patch @@ -37,9 +37,23 @@ index aa755b8b7f8bc5910322e0c5b520f603da06a85a..e781dea43279aa77cc40a7afd2281c32 public static Transformation identity() { diff --git a/net/minecraft/util/Mth.java b/net/minecraft/util/Mth.java -index ae1ab070a93b46a0790eed3feda1d09f5fbe9b25..3befc00c10ce8f29d3ee1ea493c2b220df5eaaea 100644 +index ab3a221c115992d0f4ea921aa92cf0976b815ff4..076a931341da486162f289a5f19d3d6736df7768 100644 --- a/net/minecraft/util/Mth.java +++ b/net/minecraft/util/Mth.java +@@ -46,11 +46,11 @@ public class Mth { + private static final double[] COS_TAB = new double[257]; + + public static float sin(float value) { +- return SIN[(int)(value * 10430.378F) & 65535]; ++ return net.caffeinemc.mods.lithium.common.util.math.CompactSineLUT.sin(value); // DivineMC - Math Optimizations + } + + public static float cos(float value) { +- return SIN[(int)(value * 10430.378F + 16384.0F) & 65535]; ++ return net.caffeinemc.mods.lithium.common.util.math.CompactSineLUT.cos(value); // DivineMC - Math Optimizations + } + + public static float sqrt(float value) { @@ -58,18 +58,15 @@ public class Mth { } diff --git a/divinemc-server/minecraft-patches/features/0012-World-and-Noise-gen-optimizations.patch b/divinemc-server/minecraft-patches/features/0012-World-and-Noise-gen-optimizations.patch index ae0ed30..7d2dcd3 100644 --- a/divinemc-server/minecraft-patches/features/0012-World-and-Noise-gen-optimizations.patch +++ b/divinemc-server/minecraft-patches/features/0012-World-and-Noise-gen-optimizations.patch @@ -799,6 +799,18 @@ index 131923282c9ecbcb1d7f45a826da907c02bd2716..36dd3eb0cb29d546531aec91a9c486be } private static double getBeardContribution(int x, int y, int z, int height) { +diff --git a/net/minecraft/world/level/levelgen/BelowZeroRetrogen.java b/net/minecraft/world/level/levelgen/BelowZeroRetrogen.java +index 4993ace2b3d615570de3d4b6621aeba3a3e7fe99..1be79332446559c95ae3048a71a6634fd01cf2e2 100644 +--- a/net/minecraft/world/level/levelgen/BelowZeroRetrogen.java ++++ b/net/minecraft/world/level/levelgen/BelowZeroRetrogen.java +@@ -82,6 +82,7 @@ public final class BelowZeroRetrogen { + } + + public void applyBedrockMask(ProtoChunk chunk) { ++ if (org.bxteam.divinemc.DivineConfig.smoothBedrockLayer) return; // DivineMC - Smooth bedrock layer + LevelHeightAccessor heightAccessorForGeneration = chunk.getHeightAccessorForGeneration(); + int minY = heightAccessorForGeneration.getMinY(); + int maxY = heightAccessorForGeneration.getMaxY(); diff --git a/net/minecraft/world/level/levelgen/LegacyRandomSource.java b/net/minecraft/world/level/levelgen/LegacyRandomSource.java index c67168517774a0ad9ca43422a79ef14a8ea0c2e8..026dfbbb6c3fd5cd274dcbf721e5cf3af889e3d9 100644 --- a/net/minecraft/world/level/levelgen/LegacyRandomSource.java diff --git a/divinemc-server/minecraft-patches/features/0013-Chunk-System-optimization.patch b/divinemc-server/minecraft-patches/features/0013-Chunk-System-optimization.patch index a7c67de..c120f72 100644 --- a/divinemc-server/minecraft-patches/features/0013-Chunk-System-optimization.patch +++ b/divinemc-server/minecraft-patches/features/0013-Chunk-System-optimization.patch @@ -96,7 +96,7 @@ index 866f38eb0f379ffbe2888023a7d1c290f521a231..08666b4aa1c7663861dc361f60e6f1cc if (indexer == null) { return dfl; diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -index b28083be4384d6c5efbdce898a0e9d7a2f5bd3d3..76b8d42ae530b59cdaba0583365a557da6b90ede 100644 +index 8ef5a1aaac9c27873ce746eb281f77bb318a3c69..76b8d42ae530b59cdaba0583365a557da6b90ede 100644 --- a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java @@ -301,7 +301,7 @@ public final class RegionizedPlayerChunkLoader { @@ -125,7 +125,31 @@ index b28083be4384d6c5efbdce898a0e9d7a2f5bd3d3..76b8d42ae530b59cdaba0583365a557d { this.chunkTicketStage.defaultReturnValue(CHUNK_TICKET_STAGE_NONE); } -@@ -499,7 +500,7 @@ public final class RegionizedPlayerChunkLoader { +@@ -384,10 +385,19 @@ public final class RegionizedPlayerChunkLoader { + final int centerX = PlayerChunkLoaderData.this.lastChunkX; + final int centerZ = PlayerChunkLoaderData.this.lastChunkZ; + +- return Integer.compare( +- Math.abs(c1x - centerX) + Math.abs(c1z - centerZ), +- Math.abs(c2x - centerX) + Math.abs(c2z - centerZ) +- ); ++ // DivineMC start - Chunk Loading Priority Optimization ++ if (org.bxteam.divinemc.DivineConfig.chunkTaskPriority == org.bxteam.divinemc.server.chunk.ChunkTaskPriority.EUCLIDEAN_CIRCLE_PATTERN) { ++ return Integer.compare( ++ (c1x - centerX) * (c1x - centerX) + (c1z - centerZ) * (c1z - centerZ), ++ (c2x - centerX) * (c2x - centerX) + (c2z - centerZ) * (c2z - centerZ) ++ ); ++ } else { ++ return Integer.compare( ++ Math.abs(c1x - centerX) + Math.abs(c1z - centerZ), ++ Math.abs(c2x - centerX) + Math.abs(c2z - centerZ) ++ ); ++ } ++ // DivineMC end - Chunk Loading Priority Optimization + }; + private final LongHeapPriorityQueue sendQueue = new LongHeapPriorityQueue(CLOSEST_MANHATTAN_DIST); + private final LongHeapPriorityQueue tickingQueue = new LongHeapPriorityQueue(CLOSEST_MANHATTAN_DIST); +@@ -490,7 +500,7 @@ public final class RegionizedPlayerChunkLoader { } @Override @@ -134,7 +158,7 @@ index b28083be4384d6c5efbdce898a0e9d7a2f5bd3d3..76b8d42ae530b59cdaba0583365a557d final long chunk = CoordinateUtils.getChunkKey(chunkX, chunkZ); // note: by the time this is called, the tick cleanup should have ran - so, if the chunk is at // the tick stage it was deemed in range for loading. Thus, we need to move it to generated -@@ -633,7 +634,7 @@ public final class RegionizedPlayerChunkLoader { +@@ -624,7 +634,7 @@ public final class RegionizedPlayerChunkLoader { return Math.max(Math.abs(dx), Math.abs(dz)) <= this.lastTickDistance; } @@ -143,7 +167,7 @@ index b28083be4384d6c5efbdce898a0e9d7a2f5bd3d3..76b8d42ae530b59cdaba0583365a557d for (int dz = -radius; dz <= radius; ++dz) { for (int dx = -radius; dx <= radius; ++dx) { if ((dx | dz) == 0) { -@@ -652,19 +653,11 @@ public final class RegionizedPlayerChunkLoader { +@@ -643,19 +653,11 @@ public final class RegionizedPlayerChunkLoader { return true; } @@ -164,7 +188,7 @@ index b28083be4384d6c5efbdce898a0e9d7a2f5bd3d3..76b8d42ae530b59cdaba0583365a557d // try to progress chunk loads while (!this.loadingQueue.isEmpty()) { -@@ -691,8 +684,7 @@ public final class RegionizedPlayerChunkLoader { +@@ -682,8 +684,7 @@ public final class RegionizedPlayerChunkLoader { } // try to push more chunk loads @@ -174,7 +198,7 @@ index b28083be4384d6c5efbdce898a0e9d7a2f5bd3d3..76b8d42ae530b59cdaba0583365a557d if (maxLoadsThisTick > 0) { final LongArrayList chunks = new LongArrayList(maxLoadsThisTick); for (int i = 0; i < maxLoadsThisTick; ++i) { -@@ -767,9 +759,7 @@ public final class RegionizedPlayerChunkLoader { +@@ -758,9 +759,7 @@ public final class RegionizedPlayerChunkLoader { } // try to push more chunk generations @@ -185,7 +209,7 @@ index b28083be4384d6c5efbdce898a0e9d7a2f5bd3d3..76b8d42ae530b59cdaba0583365a557d long ratedGensThisTick = 0L; while (!this.genQueue.isEmpty()) { final long chunkKey = this.genQueue.firstLong(); -@@ -799,8 +789,6 @@ public final class RegionizedPlayerChunkLoader { +@@ -790,8 +789,6 @@ public final class RegionizedPlayerChunkLoader { ); this.generatingQueue.enqueue(chunkKey); } @@ -194,7 +218,7 @@ index b28083be4384d6c5efbdce898a0e9d7a2f5bd3d3..76b8d42ae530b59cdaba0583365a557d // try to pull ticking chunks while (!this.tickingQueue.isEmpty()) { -@@ -830,10 +818,10 @@ public final class RegionizedPlayerChunkLoader { +@@ -821,10 +818,10 @@ public final class RegionizedPlayerChunkLoader { } // try to pull sending chunks @@ -207,7 +231,7 @@ index b28083be4384d6c5efbdce898a0e9d7a2f5bd3d3..76b8d42ae530b59cdaba0583365a557d final long pendingSend = this.sendQueue.firstLong(); final int pendingSendX = CoordinateUtils.getChunkX(pendingSend); final int pendingSendZ = CoordinateUtils.getChunkZ(pendingSend); -@@ -898,9 +886,6 @@ public final class RegionizedPlayerChunkLoader { +@@ -889,9 +886,6 @@ public final class RegionizedPlayerChunkLoader { // reset limiters, they will start at a zero allocation final long time = System.nanoTime(); @@ -217,7 +241,7 @@ index b28083be4384d6c5efbdce898a0e9d7a2f5bd3d3..76b8d42ae530b59cdaba0583365a557d // now we can update this.update(); -@@ -919,10 +904,10 @@ public final class RegionizedPlayerChunkLoader { +@@ -910,10 +904,10 @@ public final class RegionizedPlayerChunkLoader { ); } @@ -230,7 +254,7 @@ index b28083be4384d6c5efbdce898a0e9d7a2f5bd3d3..76b8d42ae530b59cdaba0583365a557d } final ViewDistances playerDistances = ((ChunkSystemServerPlayer)this.player).moonrise$getViewDistanceHolder().getViewDistances(); final ViewDistances worldDistances = ((ChunkSystemServerLevel)this.world).moonrise$getViewDistanceHolder().getViewDistances(); -@@ -1071,7 +1056,7 @@ public final class RegionizedPlayerChunkLoader { +@@ -1062,7 +1056,7 @@ public final class RegionizedPlayerChunkLoader { this.flushDelayedTicketOps(); } @@ -239,7 +263,7 @@ index b28083be4384d6c5efbdce898a0e9d7a2f5bd3d3..76b8d42ae530b59cdaba0583365a557d TickThread.ensureTickThread(this.player, "Cannot add player asynchronously"); if (this.removed) { throw new IllegalStateException("Removing removed player chunk loader"); -@@ -1099,7 +1084,7 @@ public final class RegionizedPlayerChunkLoader { +@@ -1090,7 +1084,7 @@ public final class RegionizedPlayerChunkLoader { } public LongOpenHashSet getSentChunksRaw() { diff --git a/divinemc-server/minecraft-patches/features/0015-Some-optimizations.patch b/divinemc-server/minecraft-patches/features/0015-Some-optimizations.patch index 583a736..0d09051 100644 --- a/divinemc-server/minecraft-patches/features/0015-Some-optimizations.patch +++ b/divinemc-server/minecraft-patches/features/0015-Some-optimizations.patch @@ -345,6 +345,19 @@ index 66f3565b978f2ed91cb2bc3a816f1701c0873c73..b4e19cc65701d5ef94e1cc0a7473225c @Override protected final void serverAiStep() { this.noActionTime++; +diff --git a/net/minecraft/world/level/GameRules.java b/net/minecraft/world/level/GameRules.java +index 5ded2f808a9fcb26856567de6bc56e206f948a84..02d64a5ea756b2c91a71b7a0fc0f21219983616a 100644 +--- a/net/minecraft/world/level/GameRules.java ++++ b/net/minecraft/world/level/GameRules.java +@@ -249,7 +249,7 @@ public class GameRules { + } + + private GameRules(Map, GameRules.Value> rules, FeatureFlagSet enabledFeatures) { +- this.rules = rules; ++ this.rules = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(rules); // DivineMC - lithium: collections.gamerules + this.enabledFeatures = enabledFeatures; + + // Paper start - Perf: Use array for gamerule storage diff --git a/net/minecraft/world/level/LocalMobCapCalculator.java b/net/minecraft/world/level/LocalMobCapCalculator.java index 9641219c190261dea0db5f95f040a705ba0a3ff9..91966607f8f48b56e2c7e9389bd7d8acda99a48d 100644 --- a/net/minecraft/world/level/LocalMobCapCalculator.java diff --git a/divinemc-server/minecraft-patches/features/0039-Leaf-Optimize-Connection.flushQueue.patch b/divinemc-server/minecraft-patches/features/0039-Leaf-Optimize-Connection.flushQueue.patch index f49a0c6..aaf0b4e 100644 --- a/divinemc-server/minecraft-patches/features/0039-Leaf-Optimize-Connection.flushQueue.patch +++ b/divinemc-server/minecraft-patches/features/0039-Leaf-Optimize-Connection.flushQueue.patch @@ -7,7 +7,7 @@ Original author - Taiyou06 Original patch - https://github.com/Winds-Studio/Leaf/pull/235 diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java -index 5b46036868b6c9d082e35591e58735e16adaae62..0cd7cfb4ef5303f8f756640ed0f7e49b51bf9627 100644 +index 00a82873d226f113278632a53c0faca420dd67d4..332f33dcdd337397c06ce8ace97d048942e321af 100644 --- a/net/minecraft/network/Connection.java +++ b/net/minecraft/network/Connection.java @@ -85,7 +85,11 @@ public class Connection extends SimpleChannelInboundHandler> { @@ -23,7 +23,15 @@ index 5b46036868b6c9d082e35591e58735e16adaae62..0cd7cfb4ef5303f8f756640ed0f7e49b public Channel channel; public SocketAddress address; // Spigot start -@@ -542,10 +546,16 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -325,6 +329,7 @@ public class Connection extends SimpleChannelInboundHandler> { + + private static void syncAfterConfigurationChange(ChannelFuture future) { + try { ++ if (ca.spottedleaf.moonrise.common.util.TickThread.isTickThread()) net.minecraft.server.MinecraftServer.getServer().managedBlock(future::isDone); // DivineMC - Don't block main thread in Connection#syncAfterConfigurationChange + future.syncUninterruptibly(); + } catch (Exception var2) { + if (var2 instanceof ClosedChannelException) { +@@ -541,10 +546,16 @@ public class Connection extends SimpleChannelInboundHandler> { if (io.papermc.paper.util.MCUtil.isMainThread()) { return this.processQueue(); } else if (this.isPending) { @@ -43,7 +51,7 @@ index 5b46036868b6c9d082e35591e58735e16adaae62..0cd7cfb4ef5303f8f756640ed0f7e49b } return false; } -@@ -555,33 +565,52 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -554,33 +565,52 @@ public class Connection extends SimpleChannelInboundHandler> { return true; } @@ -115,7 +123,7 @@ index 5b46036868b6c9d082e35591e58735e16adaae62..0cd7cfb4ef5303f8f756640ed0f7e49b return true; } // Paper end - Optimize network -@@ -914,15 +943,40 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -913,15 +943,40 @@ public class Connection extends SimpleChannelInboundHandler> { // Paper start - Optimize network public void clearPacketQueue() { final net.minecraft.server.level.ServerPlayer player = getPlayer(); diff --git a/divinemc-server/minecraft-patches/features/0049-Paper-PR-Add-FillBottleEvents-for-player-and-dispens.patch b/divinemc-server/minecraft-patches/features/0049-Paper-PR-Add-FillBottleEvents-for-player-and-dispens.patch new file mode 100644 index 0000000..ab22096 --- /dev/null +++ b/divinemc-server/minecraft-patches/features/0049-Paper-PR-Add-FillBottleEvents-for-player-and-dispens.patch @@ -0,0 +1,146 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> +Date: Sun, 23 Mar 2025 16:47:24 +0300 +Subject: [PATCH] Paper PR: Add FillBottleEvents for player and dispenser + + +diff --git a/net/minecraft/core/cauldron/CauldronInteraction.java b/net/minecraft/core/cauldron/CauldronInteraction.java +index b402f6a6ecb8047bbb791b212fba375f4c9e6af5..f381f3ecd27315e06ca6883006a8a4c3eb443c34 100644 +--- a/net/minecraft/core/cauldron/CauldronInteraction.java ++++ b/net/minecraft/core/cauldron/CauldronInteraction.java +@@ -63,7 +63,12 @@ public interface CauldronInteraction { + } + // CraftBukkit end + Item item = stack.getItem(); +- player.setItemInHand(hand, ItemUtils.createFilledResult(stack, player, new ItemStack(Items.GLASS_BOTTLE))); ++ // DivineMC start - Paper PR: Add FillBottleEvents for player and dispenser ++ final io.papermc.paper.event.player.PlayerFillBottleEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerFillBottleEvent(player, hand, stack, ItemUtils.createFilledResult(stack, player, new ItemStack(Items.GLASS_BOTTLE))); ++ if (event.isCancelled()) { ++ return InteractionResult.PASS; ++ } ++ // DivineMC end - Paper PR: Add FillBottleEvents for player and dispenser + player.awardStat(Stats.USE_CAULDRON); + player.awardStat(Stats.ITEM_USED.get(item)); + // level.setBlockAndUpdate(pos, Blocks.WATER_CAULDRON.defaultBlockState()); // CraftBukkit +diff --git a/net/minecraft/core/dispenser/DispenseItemBehavior.java b/net/minecraft/core/dispenser/DispenseItemBehavior.java +index c8c8351f5645cf4041d26b0e02c072546ad329c6..75a695aaf0dd2f58e1fa5e1c532ae298c2a2abdb 100644 +--- a/net/minecraft/core/dispenser/DispenseItemBehavior.java ++++ b/net/minecraft/core/dispenser/DispenseItemBehavior.java +@@ -727,13 +727,25 @@ public interface DispenseItemBehavior { + blockStateBase -> blockStateBase.hasProperty(BeehiveBlock.HONEY_LEVEL) && blockStateBase.getBlock() instanceof BeehiveBlock + ) + && blockState.getValue(BeehiveBlock.HONEY_LEVEL) >= 5) { ++ // DivineMC start - Paper PR: Add FillBottleEvents for player and dispenser ++ final io.papermc.paper.event.block.BlockFillBottleEvent bottleEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFillBottleEvent(serverLevel, blockSource.pos(), item, new ItemStack(Items.HONEY_BOTTLE)); ++ if (bottleEvent.isCancelled()) { ++ return item; ++ } ++ // DivineMC end - Paper PR: Add FillBottleEvents for player and dispenser + ((BeehiveBlock)blockState.getBlock()) + .releaseBeesAndResetHoneyLevel(serverLevel, blockState, blockPos, null, BeehiveBlockEntity.BeeReleaseStatus.BEE_RELEASED); + this.setSuccess(true); +- return this.takeLiquid(blockSource, item, new ItemStack(Items.HONEY_BOTTLE)); ++ return this.takeLiquid(blockSource, item, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(bottleEvent.getResultItem())); // DivineMC - Paper PR: Add FillBottleEvents for player and dispenser + } else if (serverLevel.getFluidState(blockPos).is(FluidTags.WATER)) { ++ // DivineMC start - Paper PR: Add FillBottleEvents for player and dispenser ++ final io.papermc.paper.event.block.BlockFillBottleEvent bottleEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFillBottleEvent(serverLevel, blockSource.pos(), item, PotionContents.createItemStack(Items.POTION, Potions.WATER)); ++ if (bottleEvent.isCancelled()) { ++ return item; ++ } ++ // DivineMC end - Paper PR: Add FillBottleEvents for player and dispenser + this.setSuccess(true); +- return this.takeLiquid(blockSource, item, PotionContents.createItemStack(Items.POTION, Potions.WATER)); ++ return this.takeLiquid(blockSource, item, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(bottleEvent.getResultItem())); // DivineMC - Paper PR: Add FillBottleEvents for player and dispenser + } else { + return super.execute(blockSource, item); + } +diff --git a/net/minecraft/world/item/BottleItem.java b/net/minecraft/world/item/BottleItem.java +index 105f9166297de2bfa6bdcfa9f6a0ffb00c0242ac..111f43fc5c74577f8f3067a4f84be7a6f96fdfb2 100644 +--- a/net/minecraft/world/item/BottleItem.java ++++ b/net/minecraft/world/item/BottleItem.java +@@ -35,6 +35,18 @@ public class BottleItem extends Item { + ); + ItemStack itemInHand = player.getItemInHand(hand); + if (!entitiesOfClass.isEmpty()) { ++ // DivineMC start - Paper PR: Add FillBottleEvents for player and dispenser ++ final io.papermc.paper.event.player.PlayerFillBottleEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerFillBottleEvent(player, hand, itemInHand, new ItemStack(Items.DRAGON_BREATH)); ++ //noinspection DuplicatedCode ++ if (event.isCancelled()) { ++ player.containerMenu.sendAllDataToRemote(); ++ return InteractionResult.PASS; ++ } ++ final ItemStack resultItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getResultItem()); ++ if (resultItem.is(itemInHand.getItem())) { ++ player.containerMenu.sendAllDataToRemote(); ++ } ++ // DivineMC end - Paper PR: Add FillBottleEvents for player and dispenser + AreaEffectCloud areaEffectCloud = entitiesOfClass.get(0); + areaEffectCloud.setRadius(areaEffectCloud.getRadius() - 0.5F); + level.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.BOTTLE_FILL_DRAGONBREATH, SoundSource.NEUTRAL, 1.0F, 1.0F); +@@ -43,7 +55,7 @@ public class BottleItem extends Item { + CriteriaTriggers.PLAYER_INTERACTED_WITH_ENTITY.trigger(serverPlayer, itemInHand, areaEffectCloud); + } + +- return InteractionResult.SUCCESS.heldItemTransformedTo(this.turnBottleIntoItem(itemInHand, player, new ItemStack(Items.DRAGON_BREATH))); ++ return InteractionResult.SUCCESS.heldItemTransformedTo(this.turnBottleIntoItem(itemInHand, player, resultItem)); // DivineMC - Paper PR: Add FillBottleEvents for player and dispenser + } else { + BlockHitResult playerPovHitResult = getPlayerPOVHitResult(level, player, ClipContext.Fluid.SOURCE_ONLY); + if (playerPovHitResult.getType() == HitResult.Type.MISS) { +@@ -56,10 +68,22 @@ public class BottleItem extends Item { + } + + if (level.getFluidState(blockPos).is(FluidTags.WATER)) { ++ // DivineMC start - Paper PR: Add FillBottleEvents for player and dispenser ++ final io.papermc.paper.event.player.PlayerFillBottleEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerFillBottleEvent(player, hand, itemInHand, PotionContents.createItemStack(Items.POTION, Potions.WATER)); ++ //noinspection DuplicatedCode ++ if (event.isCancelled()) { ++ player.containerMenu.sendAllDataToRemote(); ++ return InteractionResult.PASS; ++ } ++ final ItemStack resultItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getResultItem()); ++ if (resultItem.is(itemInHand.getItem())) { ++ player.containerMenu.sendAllDataToRemote(); ++ } ++ // DivineMC end - Paper PR: Add FillBottleEvents for player and dispenser + level.playSound(player, player.getX(), player.getY(), player.getZ(), SoundEvents.BOTTLE_FILL, SoundSource.NEUTRAL, 1.0F, 1.0F); + level.gameEvent(player, GameEvent.FLUID_PICKUP, blockPos); + return InteractionResult.SUCCESS +- .heldItemTransformedTo(this.turnBottleIntoItem(itemInHand, player, PotionContents.createItemStack(Items.POTION, Potions.WATER))); ++ .heldItemTransformedTo(this.turnBottleIntoItem(itemInHand, player, resultItem)); // DivineMC - Paper PR: Add FillBottleEvents for player and dispenser + } + } + +diff --git a/net/minecraft/world/level/block/BeehiveBlock.java b/net/minecraft/world/level/block/BeehiveBlock.java +index fd49500f735e3482a0118316bd7a4340f41fe8be..4160c0649be830476b5bbea97557d9a505672abc 100644 +--- a/net/minecraft/world/level/block/BeehiveBlock.java ++++ b/net/minecraft/world/level/block/BeehiveBlock.java +@@ -158,12 +158,26 @@ public class BeehiveBlock extends BaseEntityBlock { + flag = true; + level.gameEvent(player, GameEvent.SHEAR, pos); + } else if (stack.is(Items.GLASS_BOTTLE)) { ++ // DivineMC start - Paper PR: Add FillBottleEvents for player and dispenser ++ final io.papermc.paper.event.player.PlayerFillBottleEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerFillBottleEvent(player, hand, stack, new ItemStack(Items.HONEY_BOTTLE)); ++ //noinspection DuplicatedCode ++ if (event.isCancelled()) { ++ player.containerMenu.sendAllDataToRemote(); ++ return InteractionResult.PASS; ++ } ++ final ItemStack resultItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getResultItem()); ++ if (resultItem.is(stack.getItem())) { ++ player.containerMenu.sendAllDataToRemote(); ++ } ++ // DivineMC end - Paper PR: Add FillBottleEvents for player and dispenser + stack.shrink(1); + level.playSound(player, player.getX(), player.getY(), player.getZ(), SoundEvents.BOTTLE_FILL, SoundSource.BLOCKS, 1.0F, 1.0F); + if (stack.isEmpty()) { +- player.setItemInHand(hand, new ItemStack(Items.HONEY_BOTTLE)); +- } else if (!player.getInventory().add(new ItemStack(Items.HONEY_BOTTLE))) { +- player.drop(new ItemStack(Items.HONEY_BOTTLE), false); ++ // DivineMC start - Paper PR: Add FillBottleEvents for player and dispenser ++ player.setItemInHand(hand, resultItem); ++ } else if (!player.getInventory().add(resultItem)) { ++ player.drop(resultItem, false); ++ // DivineMC end - Paper PR: Add FillBottleEvents for player and dispenser + } + + flag = true; diff --git a/divinemc-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java.patch b/divinemc-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java.patch deleted file mode 100644 index d9d3b97..0000000 --- a/divinemc-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -+++ b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -@@ -380,10 +_,19 @@ - final int centerX = PlayerChunkLoaderData.this.lastChunkX; - final int centerZ = PlayerChunkLoaderData.this.lastChunkZ; - -- return Integer.compare( -- Math.abs(c1x - centerX) + Math.abs(c1z - centerZ), -- Math.abs(c2x - centerX) + Math.abs(c2z - centerZ) -- ); -+ // DivineMC start - Chunk Loading Priority Optimization -+ if (org.bxteam.divinemc.DivineConfig.chunkTaskPriority == org.bxteam.divinemc.server.chunk.ChunkTaskPriority.EUCLIDEAN_CIRCLE_PATTERN) { -+ return Integer.compare( -+ (c1x - centerX) * (c1x - centerX) + (c1z - centerZ) * (c1z - centerZ), -+ (c2x - centerX) * (c2x - centerX) + (c2z - centerZ) * (c2z - centerZ) -+ ); -+ } else { -+ return Integer.compare( -+ Math.abs(c1x - centerX) + Math.abs(c1z - centerZ), -+ Math.abs(c2x - centerX) + Math.abs(c2z - centerZ) -+ ); -+ } -+ // DivineMC end - Chunk Loading Priority Optimization - }; - private final LongHeapPriorityQueue sendQueue = new LongHeapPriorityQueue(CLOSEST_MANHATTAN_DIST); - private final LongHeapPriorityQueue tickingQueue = new LongHeapPriorityQueue(CLOSEST_MANHATTAN_DIST); diff --git a/divinemc-server/minecraft-patches/sources/net/minecraft/network/Connection.java.patch b/divinemc-server/minecraft-patches/sources/net/minecraft/network/Connection.java.patch deleted file mode 100644 index 44491e2..0000000 --- a/divinemc-server/minecraft-patches/sources/net/minecraft/network/Connection.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/net/minecraft/network/Connection.java -+++ b/net/minecraft/network/Connection.java -@@ -325,6 +_,7 @@ - - private static void syncAfterConfigurationChange(ChannelFuture future) { - try { -+ if (ca.spottedleaf.moonrise.common.util.TickThread.isTickThread()) net.minecraft.server.MinecraftServer.getServer().managedBlock(future::isDone); // ShreddedPaper - Don't block main thread in Connection#syncAfterConfigurationChange - future.syncUninterruptibly(); - } catch (Exception var2) { - if (var2 instanceof ClosedChannelException) { diff --git a/divinemc-server/minecraft-patches/sources/net/minecraft/util/Mth.java.patch b/divinemc-server/minecraft-patches/sources/net/minecraft/util/Mth.java.patch deleted file mode 100644 index 2933219..0000000 --- a/divinemc-server/minecraft-patches/sources/net/minecraft/util/Mth.java.patch +++ /dev/null @@ -1,16 +0,0 @@ ---- a/net/minecraft/util/Mth.java -+++ b/net/minecraft/util/Mth.java -@@ -46,11 +_,11 @@ - private static final double[] COS_TAB = new double[257]; - - public static float sin(float value) { -- return SIN[(int)(value * 10430.378F) & 65535]; -+ return net.caffeinemc.mods.lithium.common.util.math.CompactSineLUT.sin(value); // DivineMC - lithium: CompactSineLUT - } - - public static float cos(float value) { -- return SIN[(int)(value * 10430.378F + 16384.0F) & 65535]; -+ return net.caffeinemc.mods.lithium.common.util.math.CompactSineLUT.cos(value); // DivineMC - lithium: CompactSineLUT - } - - public static float sqrt(float value) { diff --git a/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/GameRules.java.patch b/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/GameRules.java.patch deleted file mode 100644 index 56a0ade..0000000 --- a/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/GameRules.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/level/GameRules.java -+++ b/net/minecraft/world/level/GameRules.java -@@ -249,7 +_,7 @@ - } - - private GameRules(Map, GameRules.Value> rules, FeatureFlagSet enabledFeatures) { -- this.rules = rules; -+ this.rules = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(rules); // DivineMC - lithium: collections.gamerules - this.enabledFeatures = enabledFeatures; - - // Paper start - Perf: Use array for gamerule storage diff --git a/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/levelgen/BelowZeroRetrogen.java.patch b/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/levelgen/BelowZeroRetrogen.java.patch deleted file mode 100644 index 28e1f7d..0000000 --- a/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/levelgen/BelowZeroRetrogen.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/net/minecraft/world/level/levelgen/BelowZeroRetrogen.java -+++ b/net/minecraft/world/level/levelgen/BelowZeroRetrogen.java -@@ -82,6 +_,7 @@ - } - - public void applyBedrockMask(ProtoChunk chunk) { -+ if (org.bxteam.divinemc.DivineConfig.smoothBedrockLayer) return; // DivineMC - Smooth bedrock layer - LevelHeightAccessor heightAccessorForGeneration = chunk.getHeightAccessorForGeneration(); - int minY = heightAccessorForGeneration.getMinY(); - int maxY = heightAccessorForGeneration.getMaxY(); diff --git a/divinemc-server/paper-patches/features/0012-Paper-PR-Add-FillBottleEvents-for-player-and-dispens.patch b/divinemc-server/paper-patches/features/0012-Paper-PR-Add-FillBottleEvents-for-player-and-dispens.patch new file mode 100644 index 0000000..07707d4 --- /dev/null +++ b/divinemc-server/paper-patches/features/0012-Paper-PR-Add-FillBottleEvents-for-player-and-dispens.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> +Date: Sun, 23 Mar 2025 16:39:45 +0300 +Subject: [PATCH] Paper PR: Add FillBottleEvents for player and dispenser + + +diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +index 2690de512d0d8be1ae31879c113255742b9af4c1..2220e82ecea67c3421488fe29d32f38f52a79f3f 100644 +--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java ++++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +@@ -2304,4 +2304,18 @@ public class CraftEventFactory { + return event; + } + // Paper end - add EntityFertilizeEggEvent ++ ++ // DivineMC start - Paper PR: Add FillBottleEvents for player and dispenser ++ public static io.papermc.paper.event.player.PlayerFillBottleEvent callPlayerFillBottleEvent(net.minecraft.world.entity.player.Player player, InteractionHand hand, ItemStack glassBottle, ItemStack resultItem) { ++ final io.papermc.paper.event.player.PlayerFillBottleEvent event = new io.papermc.paper.event.player.PlayerFillBottleEvent(((org.bukkit.entity.Player) player.getBukkitEntity()), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), CraftItemStack.asBukkitCopy(glassBottle), CraftItemStack.asCraftMirror(resultItem)); ++ event.callEvent(); ++ return event; ++ } ++ ++ public static io.papermc.paper.event.block.BlockFillBottleEvent callBlockFillBottleEvent(LevelAccessor level, BlockPos blockPos, ItemStack glassBottle, ItemStack resultItem) { ++ final io.papermc.paper.event.block.BlockFillBottleEvent event = new io.papermc.paper.event.block.BlockFillBottleEvent(CraftBlock.at(level, blockPos), CraftItemStack.asBukkitCopy(glassBottle), CraftItemStack.asCraftMirror(resultItem)); ++ event.callEvent(); ++ return event; ++ } ++ // DivineMC end - Paper PR: Add FillBottleEvents for player and dispenser + } diff --git a/divinemc-server/paper-patches/features/0013-Paper-PR-Player-standing-on-position-API.patch b/divinemc-server/paper-patches/features/0013-Paper-PR-Player-standing-on-position-API.patch new file mode 100644 index 0000000..574cf0c --- /dev/null +++ b/divinemc-server/paper-patches/features/0013-Paper-PR-Player-standing-on-position-API.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> +Date: Sun, 23 Mar 2025 16:53:16 +0300 +Subject: [PATCH] Paper PR: Player standing on position API + + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +index 614e407814fe47dab58fbcbc49d8e9dd54b4245e..c0f25f97519d59919d965f53ea87dada537f3f00 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +@@ -1355,6 +1355,20 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { + } + // Paper end - broadcast hurt animation + ++ // Paper start - Player standing on position API ++ @Override ++ public org.bukkit.block.Block getMovementAffectingBlock() { ++ return CraftBlock.at(this.getHandle().level(), this.getHandle().getBlockPosBelowThatAffectsMyMovement()); ++ } ++ ++ @Override ++ public org.bukkit.block.Block getSupportingBlock() { ++ return this.getHandle().mainSupportingBlockPos ++ .map((pos) -> CraftBlock.at(this.getHandle().level(), pos)) ++ .orElse(null); ++ } ++ // Paper end - Player standing on position API ++ + // Purpur start - Ridables + @Override + public org.bukkit.entity.Player getRider() {