mirror of
https://github.com/BX-Team/DivineMC.git
synced 2025-12-19 14:59:25 +00:00
move some sources patches to features; add some new api patches
This commit is contained in:
@@ -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<Player> 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.
|
||||
+ * <p>
|
||||
+ * 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.
|
||||
+ * <p>
|
||||
+ * 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
|
||||
@@ -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}
|
||||
* <p>
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@@ -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}
|
||||
* <p>
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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.Key<?>, 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
|
||||
|
||||
@@ -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<Packet<?>> {
|
||||
@@ -23,7 +23,15 @@ index 5b46036868b6c9d082e35591e58735e16adaae62..0cd7cfb4ef5303f8f756640ed0f7e49b
|
||||
public Channel channel;
|
||||
public SocketAddress address;
|
||||
// Spigot start
|
||||
@@ -542,10 +546,16 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -325,6 +329,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
|
||||
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<Packet<?>> {
|
||||
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<Packet<?>> {
|
||||
@@ -554,33 +565,52 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -115,7 +123,7 @@ index 5b46036868b6c9d082e35591e58735e16adaae62..0cd7cfb4ef5303f8f756640ed0f7e49b
|
||||
return true;
|
||||
}
|
||||
// Paper end - Optimize network
|
||||
@@ -914,15 +943,40 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -913,15 +943,40 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
// Paper start - Optimize network
|
||||
public void clearPacketQueue() {
|
||||
final net.minecraft.server.level.ServerPlayer player = getPlayer();
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
@@ -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) {
|
||||
@@ -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) {
|
||||
@@ -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.Key<?>, 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
|
||||
@@ -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();
|
||||
@@ -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
|
||||
}
|
||||
@@ -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() {
|
||||
Reference in New Issue
Block a user