Merge remote-tracking branch 'upstream/main'
All checks were successful
SteamWarCI Build successful

This commit is contained in:
2025-04-29 19:41:25 +02:00
18 changed files with 269 additions and 38 deletions

View File

@ -0,0 +1,79 @@
package io.papermc.paper.event.block;
import com.google.common.base.Preconditions;
import org.bukkit.block.Block;
import org.bukkit.block.data.type.Vault;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.block.BlockEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
* Called when a vault block changes state.
*/
@NullMarked
public class VaultChangeStateEvent extends BlockEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final @Nullable Player player;
private final Vault.State currentState;
private final Vault.State newState;
private boolean cancelled = false;
@ApiStatus.Internal
public VaultChangeStateEvent(final Block vaultBlock, final @Nullable Player player, final Vault.State currentState, final Vault.State newState) {
super(vaultBlock);
this.player = player;
this.currentState = currentState;
this.newState = newState;
}
/**
* Gets the player associated with this state change, if applicable.
*
* @return The associated player, or {@code null} if not known.
*/
public @Nullable Player getPlayer() {
return this.player;
}
/**
* Gets the state the vault is currently in.
*
* @return The current vault state.
*/
public Vault.State getCurrentState() {
return currentState;
}
/**
* Gets the state the vault is attempting to transition to.
*
* @return The new vault state.
*/
public Vault.State getNewState() {
return newState;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}

View File

@ -830,9 +830,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
* @param id the id of the map to get * @param id the id of the map to get
* @return a map view if it exists, or null otherwise * @return a map view if it exists, or null otherwise
*/ */
// @Deprecated(since = "1.6.2") // Paper - Not a magic value
@Nullable @Nullable
public MapView getMap(int id); MapView getMap(int id);
/** /**
* Create a new map with an automatically assigned ID. * Create a new map with an automatically assigned ID.

View File

@ -1,5 +1,6 @@
package org.bukkit.entity; package org.bukkit.entity;
import org.bukkit.inventory.EquipmentSlot;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -323,7 +324,6 @@ public interface FishHook extends Projectile {
BOBBING; BOBBING;
} }
// Paper start - More FishHook API
/** /**
* Get the number of ticks the hook needs to wait for a fish to bite. * Get the number of ticks the hook needs to wait for a fish to bite.
* *
@ -367,5 +367,18 @@ public interface FishHook extends Projectile {
* enchantment. * enchantment.
*/ */
void resetFishingState(); void resetFishingState();
// Paper end
/**
* Retrieve this fishhook back to the casting player.
* <p>
* This method will trigger and respect API events, which may be subject to cancellation.
* Plugins listening to {@link org.bukkit.event.player.PlayerFishEvent} might for example cancel this action.
*
* @param slot Slot holding the fishing rod (must be HAND/OFF_HAND)
* @return The amount of damage which would be applied to the itemstack
* @throws IllegalStateException if the fish hook does not have a player casting it.
* @throws IllegalStateException if the player casting it is not holding a
* {@link org.bukkit.inventory.ItemType#FISHING_ROD} in the specified equipment slot.
*/
int retrieve(@NotNull EquipmentSlot slot);
} }

View File

@ -2109,6 +2109,8 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* *
* @param other The other {@link Player} to list. * @param other The other {@link Player} to list.
* @return True if the {@code other} player was not listed. * @return True if the {@code other} player was not listed.
* @throws IllegalStateException if this player can't see the other player
* @see #canSee(Player)
*/ */
boolean listPlayer(Player other); boolean listPlayer(Player other);
// Paper end // Paper end

View File

@ -203,10 +203,10 @@ public class InventoryClickEvent extends InventoryInteractEvent {
/** /**
* If the ClickType is NUMBER_KEY, this method will return the index of * If the ClickType is NUMBER_KEY, this method will return the index of
* the pressed key (0-8). * the pressed key (0-8) and -1 if player swapped with off-hand (or the action is not NUMBER_KEY).
* *
* @return the number on the key minus 1 (range 0-8); or -1 if not * @return the number on the key minus 1 (range 0-8);
* a NUMBER_KEY action * or -1 if ClickType is NUMBER_KEY and player did an off-hand swap. Is also -1 if ClickType is not NUMBER_KEY
*/ */
public int getHotbarButton() { public int getHotbarButton() {
return this.hotbarKey; return this.hotbarKey;

View File

@ -28202,10 +28202,10 @@ index b30f56fbc1fd17259a1d05dc9155fffcab292ca1..11fed81a4696ba18440e755c3b8a5ca3
this.generatingStep = generatingStep; this.generatingStep = generatingStep;
this.cache = cache; this.cache = cache;
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 73717609fccd9af12e2cc39824106f49426b581c..72524ff3399a4477dfa3db2f4e79bb14f6519a8b 100644 index 5ec9e3b37e575e9805bf9f0ce5cae5c1284461d8..78201407a37eced73998b97d5d5c412eaba69af1 100644
--- a/net/minecraft/server/players/PlayerList.java --- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java
@@ -1321,7 +1321,7 @@ public abstract class PlayerList { @@ -1320,7 +1320,7 @@ public abstract class PlayerList {
public void setViewDistance(int viewDistance) { public void setViewDistance(int viewDistance) {
this.viewDistance = viewDistance; this.viewDistance = viewDistance;
@ -28214,7 +28214,7 @@ index 73717609fccd9af12e2cc39824106f49426b581c..72524ff3399a4477dfa3db2f4e79bb14
for (ServerLevel serverLevel : this.server.getAllLevels()) { for (ServerLevel serverLevel : this.server.getAllLevels()) {
if (serverLevel != null) { if (serverLevel != null) {
@@ -1332,7 +1332,7 @@ public abstract class PlayerList { @@ -1331,7 +1331,7 @@ public abstract class PlayerList {
public void setSimulationDistance(int simulationDistance) { public void setSimulationDistance(int simulationDistance) {
this.simulationDistance = simulationDistance; this.simulationDistance = simulationDistance;

View File

@ -5,7 +5,7 @@ Subject: [PATCH] Incremental chunk and player saving
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 00f7f4356d6bffdd31f58b9d798c755edd9cd3ff..ea85cac4a41075efe8525c40755e7ebac6ca9dea 100644 index 094ef7f54ad71795a2d8c2a8d03a32bef6ff2164..79bc1b7d9f640d2322814177eb3e921da8671e87 100644
--- a/net/minecraft/server/MinecraftServer.java --- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java
@@ -952,7 +952,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -952,7 +952,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@ -50,7 +50,7 @@ index 00f7f4356d6bffdd31f58b9d798c755edd9cd3ff..ea85cac4a41075efe8525c40755e7eba
ProfilerFiller profilerFiller = Profiler.get(); ProfilerFiller profilerFiller = Profiler.get();
this.runAllTasks(); // Paper - move runAllTasks() into full server tick (previously for timings) this.runAllTasks(); // Paper - move runAllTasks() into full server tick (previously for timings)
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index debc511cf18d0be813803c200bd1cf0b07ba7974..2a4a40976215ea858c562c3f530db378896c6fcb 100644 index 32db2b9e375c12cbf7abab69cc01e8ac2c7c3b6e..d50d2928ad9f8b34a14621b1fe5c188547e04bd1 100644
--- a/net/minecraft/server/level/ServerLevel.java --- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java
@@ -1317,6 +1317,28 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -1317,6 +1317,28 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@ -83,7 +83,7 @@ index debc511cf18d0be813803c200bd1cf0b07ba7974..2a4a40976215ea858c562c3f530db378
// Paper start - add close param // Paper start - add close param
this.save(progress, flush, skipSave, false); this.save(progress, flush, skipSave, false);
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index bc901bc689c2690ac19e590bff1ae612b7071ee9..8e7ee4dc951eb53ccf65ab71214a0b89bd932ba0 100644 index 3e73c69c9db8cbded28a001b20d9989acb11c638..d1de5aff81da465be79f2f747466734e80ec50dc 100644
--- a/net/minecraft/server/level/ServerPlayer.java --- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java
@@ -189,6 +189,7 @@ import org.slf4j.Logger; @@ -189,6 +189,7 @@ import org.slf4j.Logger;
@ -95,7 +95,7 @@ index bc901bc689c2690ac19e590bff1ae612b7071ee9..8e7ee4dc951eb53ccf65ab71214a0b89
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10; private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10;
private static final int FLY_STAT_RECORDING_SPEED = 25; private static final int FLY_STAT_RECORDING_SPEED = 25;
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 72524ff3399a4477dfa3db2f4e79bb14f6519a8b..6e22aedd36add8e39a82248193f324b36dfa27b5 100644 index 78201407a37eced73998b97d5d5c412eaba69af1..f057e682ccd378f11710dc2e7129cba95788bb18 100644
--- a/net/minecraft/server/players/PlayerList.java --- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java
@@ -486,6 +486,7 @@ public abstract class PlayerList { @@ -486,6 +486,7 @@ public abstract class PlayerList {
@ -106,7 +106,7 @@ index 72524ff3399a4477dfa3db2f4e79bb14f6519a8b..6e22aedd36add8e39a82248193f324b3
this.playerIo.save(player); this.playerIo.save(player);
ServerStatsCounter serverStatsCounter = player.getStats(); // CraftBukkit ServerStatsCounter serverStatsCounter = player.getStats(); // CraftBukkit
if (serverStatsCounter != null) { if (serverStatsCounter != null) {
@@ -1068,9 +1069,23 @@ public abstract class PlayerList { @@ -1067,9 +1068,23 @@ public abstract class PlayerList {
} }
public void saveAll() { public void saveAll() {

View File

@ -48,7 +48,7 @@ index 0000000000000000000000000000000000000000..24a2090e068ad3c0d08705050944abdf
+ } + }
+} +}
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index ea85cac4a41075efe8525c40755e7ebac6ca9dea..7af29d3dc7b337d74cee5df7cbca35c420643370 100644 index 79bc1b7d9f640d2322814177eb3e921da8671e87..f1373fd5fdebb9f4600ba7f32a5df6188de3a0e9 100644
--- a/net/minecraft/server/MinecraftServer.java --- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java
@@ -1706,6 +1706,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -1706,6 +1706,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@ -60,10 +60,10 @@ index ea85cac4a41075efe8525c40755e7ebac6ca9dea..7af29d3dc7b337d74cee5df7cbca35c4
/* Drop global time updates /* Drop global time updates
if (this.tickCount % 20 == 0) { if (this.tickCount % 20 == 0) {
diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java
index 5329dc9259f30011d277336bfc76da18c15d5d81..8391f51b7dd584dd346bda5dccbee900d4fa9c2d 100644 index 72cd623a1a3ce4b7a570a853456b067cd93736b1..ad7852a19ff73368ec9e7e63dcb7a064f78eefa0 100644
--- a/net/minecraft/world/item/ItemStack.java --- a/net/minecraft/world/item/ItemStack.java
+++ b/net/minecraft/world/item/ItemStack.java +++ b/net/minecraft/world/item/ItemStack.java
@@ -832,10 +832,16 @@ public final class ItemStack implements DataComponentHolder { @@ -831,10 +831,16 @@ public final class ItemStack implements DataComponentHolder {
} }
public ItemStack copy() { public ItemStack copy() {

View File

@ -2566,7 +2566,7 @@
); );
} }
} }
@@ -1997,6 +_,7 @@ @@ -1997,27 +_,32 @@
private void resetPlayerChatState(RemoteChatSession chatSession) { private void resetPlayerChatState(RemoteChatSession chatSession) {
this.chatSession = chatSession; this.chatSession = chatSession;
@ -2574,16 +2574,19 @@
this.signedMessageDecoder = chatSession.createMessageDecoder(this.player.getUUID()); this.signedMessageDecoder = chatSession.createMessageDecoder(this.player.getUUID());
this.chatMessageChain this.chatMessageChain
.append( .append(
@@ -2005,7 +_,7 @@ () -> {
+ server.executeBlocking(() -> { // Paper - Broadcast chat session update sync
this.player.setChatSession(chatSession);
this.server this.server
.getPlayerList() .getPlayerList()
.broadcastAll( .broadcastAll(
- new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT), List.of(this.player)) - new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT), List.of(this.player))
+ new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT), List.of(this.player)), this.player // Paper - Use single player info update packet on join + new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT), List.of(this.player)), this.player // Paper - Use single player info update packet on join
); );
+ });
} }
); );
@@ -2013,11 +_,13 @@ }
@Override @Override
public void handleCustomPayload(ServerboundCustomPayloadPacket packet) { public void handleCustomPayload(ServerboundCustomPayloadPacket packet) {

View File

@ -756,7 +756,7 @@
return serverPlayer; return serverPlayer;
} }
@@ -488,24 +_,60 @@ @@ -488,24 +_,59 @@
} }
public void sendActiveEffects(LivingEntity entity, ServerGamePacketListenerImpl connection) { public void sendActiveEffects(LivingEntity entity, ServerGamePacketListenerImpl connection) {
@ -800,12 +800,11 @@
+ // CraftBukkit start - add a world/entity limited version + // CraftBukkit start - add a world/entity limited version
+ public void broadcastAll(Packet packet, net.minecraft.world.entity.player.Player entityhuman) { + public void broadcastAll(Packet packet, net.minecraft.world.entity.player.Player entityhuman) {
+ for (int i = 0; i < this.players.size(); ++i) { + for (ServerPlayer entityplayer : this.players) { // Paper - replace for i with for each for thread safety
+ ServerPlayer entityplayer = this.players.get(i);
+ if (entityhuman != null && !entityplayer.getBukkitEntity().canSee(entityhuman.getBukkitEntity())) { + if (entityhuman != null && !entityplayer.getBukkitEntity().canSee(entityhuman.getBukkitEntity())) {
+ continue; + continue;
+ } + }
+ ((ServerPlayer) this.players.get(i)).connection.send(packet); + ((ServerPlayer) entityplayer).connection.send(packet); // Paper - replace for i with for each for thread safety
+ } + }
+ } + }
+ +

View File

@ -0,0 +1,40 @@
--- a/net/minecraft/world/InteractionResult.java
+++ b/net/minecraft/world/InteractionResult.java
@@ -30,18 +_,34 @@
public record Pass() implements InteractionResult {
}
- public record Success(InteractionResult.SwingSource swingSource, InteractionResult.ItemContext itemContext) implements InteractionResult {
+ // Paper start - track more context in interaction result
+ public record PaperSuccessContext(net.minecraft.core.@org.jspecify.annotations.Nullable BlockPos placedBlockPosition) {
+ static PaperSuccessContext DEFAULT = new PaperSuccessContext(null);
+
+ public PaperSuccessContext placedBlockAt(final net.minecraft.core.BlockPos blockPos) {
+ return new PaperSuccessContext(blockPos);
+ }
+ }
+ public record Success(InteractionResult.SwingSource swingSource, InteractionResult.ItemContext itemContext, PaperSuccessContext paperSuccessContext) implements InteractionResult {
+ public InteractionResult.Success configurePaper(final java.util.function.UnaryOperator<PaperSuccessContext> edit) {
+ return new InteractionResult.Success(this.swingSource, this.itemContext, edit.apply(this.paperSuccessContext));
+ }
+
+ public Success(final net.minecraft.world.InteractionResult.SwingSource swingSource, final net.minecraft.world.InteractionResult.ItemContext itemContext) {
+ this(swingSource, itemContext, PaperSuccessContext.DEFAULT);
+ }
+ // Paper end - track more context in interaction result
@Override
public boolean consumesAction() {
return true;
}
public InteractionResult.Success heldItemTransformedTo(ItemStack stack) {
- return new InteractionResult.Success(this.swingSource, new InteractionResult.ItemContext(true, stack));
+ return new InteractionResult.Success(this.swingSource, new InteractionResult.ItemContext(true, stack), this.paperSuccessContext); // Paper - track more context in interaction result
}
public InteractionResult.Success withoutItem() {
- return new InteractionResult.Success(this.swingSource, InteractionResult.ItemContext.NONE);
+ return new InteractionResult.Success(this.swingSource, InteractionResult.ItemContext.NONE, this.paperSuccessContext); // Paper - track more context in interaction result
}
public boolean wasItemInteraction() {

View File

@ -56,6 +56,15 @@
level.playSound( level.playSound(
player, player,
clickedPos, clickedPos,
@@ -88,7 +_,7 @@
);
level.gameEvent(GameEvent.BLOCK_PLACE, clickedPos, GameEvent.Context.of(player, blockState));
itemInHand.consume(1, player);
- return InteractionResult.SUCCESS;
+ return InteractionResult.SUCCESS.configurePaper(e -> e.placedBlockAt(clickedPos.immutable())); // Paper - track placed block position from block item
}
}
}
@@ -137,8 +_,19 @@ @@ -137,8 +_,19 @@
protected boolean canPlace(BlockPlaceContext context, BlockState state) { protected boolean canPlace(BlockPlaceContext context, BlockState state) {

View File

@ -23,7 +23,7 @@
} }
} }
}; };
@@ -373,10 +_,167 @@ @@ -373,10 +_,166 @@
return InteractionResult.PASS; return InteractionResult.PASS;
} else { } else {
Item item = this.getItem(); Item item = this.getItem();
@ -175,10 +175,9 @@
+ } + }
+ +
+ // SPIGOT-1288 - play sound stripped from BlockItem + // SPIGOT-1288 - play sound stripped from BlockItem
+ if (this.item instanceof BlockItem) { + if (this.item instanceof BlockItem && success.paperSuccessContext().placedBlockPosition() != null) {
+ // Paper start - Fix spigot sound playing for BlockItem ItemStacks + // Paper start - Fix spigot sound playing for BlockItem ItemStacks
+ BlockPos pos = new net.minecraft.world.item.context.BlockPlaceContext(context).getClickedPos(); + net.minecraft.world.level.block.state.BlockState state = serverLevel.getBlockState(success.paperSuccessContext().placedBlockPosition());
+ net.minecraft.world.level.block.state.BlockState state = serverLevel.getBlockState(pos);
+ net.minecraft.world.level.block.SoundType soundType = state.getSoundType(); + net.minecraft.world.level.block.SoundType soundType = state.getSoundType();
+ // Paper end - Fix spigot sound playing for BlockItem ItemStacks + // Paper end - Fix spigot sound playing for BlockItem ItemStacks
+ serverLevel.playSound(player, clickedPos, soundType.getPlaceSound(), net.minecraft.sounds.SoundSource.BLOCKS, (soundType.getVolume() + 1.0F) / 2.0F, soundType.getPitch() * 0.8F); + serverLevel.playSound(player, clickedPos, soundType.getPlaceSound(), net.minecraft.sounds.SoundSource.BLOCKS, (soundType.getVolume() + 1.0F) / 2.0F, soundType.getPitch() * 0.8F);

View File

@ -1,17 +1,52 @@
--- a/net/minecraft/world/level/block/entity/vault/VaultBlockEntity.java --- a/net/minecraft/world/level/block/entity/vault/VaultBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/vault/VaultBlockEntity.java +++ b/net/minecraft/world/level/block/entity/vault/VaultBlockEntity.java
@@ -260,6 +_,11 @@ @@ -260,7 +_,12 @@
if (!list.isEmpty()) { if (!list.isEmpty()) {
player.awardStat(Stats.ITEM_USED.get(stack.getItem())); player.awardStat(Stats.ITEM_USED.get(stack.getItem()));
stack.consume(config.keyItem().getCount(), player); stack.consume(config.keyItem().getCount(), player);
- unlock(level, state, pos, config, serverData, sharedData, list);
+ // CraftBukkit start + // CraftBukkit start
+ org.bukkit.event.block.BlockDispenseLootEvent vaultDispenseLootEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockDispenseLootEvent(level, pos, player, list); + org.bukkit.event.block.BlockDispenseLootEvent vaultDispenseLootEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockDispenseLootEvent(level, pos, player, list);
+ if (vaultDispenseLootEvent.isCancelled()) return; + if (vaultDispenseLootEvent.isCancelled()) return;
+ list = vaultDispenseLootEvent.getDispensedLoot().stream().map(org.bukkit.craftbukkit.inventory.CraftItemStack::asNMSCopy).toList(); + list = vaultDispenseLootEvent.getDispensedLoot().stream().map(org.bukkit.craftbukkit.inventory.CraftItemStack::asNMSCopy).toList();
+ // CraftBukkit end + // CraftBukkit end
unlock(level, state, pos, config, serverData, sharedData, list); + unlock(level, state, pos, config, serverData, sharedData, list, player); // Paper - Vault API
serverData.addToRewardedPlayers(player); serverData.addToRewardedPlayers(player);
sharedData.updateConnectedPlayersWithinRange(level, pos, serverData, config, config.deactivationRange()); sharedData.updateConnectedPlayersWithinRange(level, pos, serverData, config, config.deactivationRange());
}
@@ -269,8 +_,30 @@
}
static void setVaultState(ServerLevel level, BlockPos pos, BlockState oldState, BlockState newState, VaultConfig config, VaultSharedData sharedData) {
- VaultState vaultState = oldState.getValue(VaultBlock.STATE);
- VaultState vaultState1 = newState.getValue(VaultBlock.STATE);
+ // Paper start - Vault API
+ setVaultState(level, pos, oldState, newState, config,sharedData, null);
+ }
+
+ static void setVaultState(ServerLevel level, BlockPos pos, BlockState oldState, BlockState newState, VaultConfig config, VaultSharedData sharedData, @Nullable Player associatedPlayer) {
+ VaultState vaultState = oldState.getValue(VaultBlock.STATE); final VaultState oldVaultState = vaultState;
+ VaultState vaultState1 = newState.getValue(VaultBlock.STATE); final VaultState newVaultState = vaultState1;
+ org.bukkit.entity.Player apiAssociatedPlayer = null;
+ if (associatedPlayer != null) {
+ apiAssociatedPlayer = (org.bukkit.entity.Player) associatedPlayer.getBukkitEntity();
+ } else if (newVaultState == VaultState.ACTIVE) {
+ final Set<UUID> connectedPlayers = sharedData.getConnectedPlayers();
+ if (!connectedPlayers.isEmpty()) { // Used over sharedData#hasConnectedPlayers to ensure belows iterator#next is always okay.
+ apiAssociatedPlayer = level.getCraftServer().getPlayer(connectedPlayers.iterator().next());
+ }
+ }
+ final io.papermc.paper.event.block.VaultChangeStateEvent event = new io.papermc.paper.event.block.VaultChangeStateEvent(
+ org.bukkit.craftbukkit.block.CraftBlock.at(level, pos),
+ apiAssociatedPlayer,
+ org.bukkit.craftbukkit.block.data.CraftBlockData.toBukkit(oldVaultState, org.bukkit.block.data.type.Vault.State.class),
+ org.bukkit.craftbukkit.block.data.CraftBlockData.toBukkit(newVaultState, org.bukkit.block.data.type.Vault.State.class)
+ );
+ if (!event.callEvent()) return;
+ // Paper end - Vault API
level.setBlock(pos, newState, 3);
vaultState.onTransition(level, pos, vaultState1, config, sharedData, newState.getValue(VaultBlock.OMINOUS));
}
@@ -282,6 +_,11 @@ @@ -282,6 +_,11 @@
ItemStack randomDisplayItemFromLootTable = getRandomDisplayItemFromLootTable( ItemStack randomDisplayItemFromLootTable = getRandomDisplayItemFromLootTable(
level, pos, config.overrideLootTableToDisplay().orElse(config.lootTable()) level, pos, config.overrideLootTableToDisplay().orElse(config.lootTable())
@ -24,3 +59,29 @@
sharedData.setDisplayItem(randomDisplayItemFromLootTable); sharedData.setDisplayItem(randomDisplayItemFromLootTable);
} }
} }
@@ -304,10 +_,24 @@
VaultSharedData sharedData,
List<ItemStack> itemsToEject
) {
+ // Paper start - Vault API
+ unlock(level, state, pos, config, serverData, sharedData, itemsToEject, null);
+ }
+ private static void unlock(
+ ServerLevel level,
+ BlockState state,
+ BlockPos pos,
+ VaultConfig config,
+ VaultServerData serverData,
+ VaultSharedData sharedData,
+ List<ItemStack> itemsToEject,
+ final @Nullable Player associatedPlayer
+ ) {
+ // Paper end - Vault API
serverData.setItemsToEject(itemsToEject);
sharedData.setDisplayItem(serverData.getNextItemToEject());
serverData.pauseStateUpdatingUntil(level.getGameTime() + 14L);
- setVaultState(level, pos, state, state.setValue(VaultBlock.STATE, VaultState.UNLOCKING), config, sharedData);
+ setVaultState(level, pos, state, state.setValue(VaultBlock.STATE, VaultState.UNLOCKING), config, sharedData, associatedPlayer); // Paper - Vault API
}
private static List<ItemStack> resolveItemsToEject(ServerLevel level, VaultConfig config, BlockPos pos, Player player, ItemStack key) {

View File

@ -40,6 +40,7 @@ import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import net.minecraft.Optionull;
import net.minecraft.advancements.AdvancementHolder; import net.minecraft.advancements.AdvancementHolder;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands; import net.minecraft.commands.Commands;
@ -1943,12 +1944,13 @@ public final class CraftServer implements Server {
} }
@Override @Override
@Deprecated
public CraftMapView getMap(int id) { public CraftMapView getMap(int id) {
MapItemSavedData mapData = this.console.getLevel(net.minecraft.world.level.Level.OVERWORLD).getMapData(new MapId(id)); final net.minecraft.world.level.Level overworld = this.console.overworld();
if (mapData == null) { if (overworld == null) return null;
return null;
} final MapItemSavedData mapData = overworld.getMapData(new MapId(id));
if (mapData == null) return null;
return mapData.mapView; return mapData.mapView;
} }
@ -2261,7 +2263,11 @@ public final class CraftServer implements Server {
@Override @Override
public GameMode getDefaultGameMode() { public GameMode getDefaultGameMode() {
return GameMode.getByValue(this.console.getLevel(net.minecraft.world.level.Level.OVERWORLD).serverLevelData.getGameType().getId()); return GameMode.getByValue(Optionull.mapOrDefault(
this.console.getLevel(net.minecraft.world.level.Level.OVERWORLD),
l -> l.serverLevelData.getGameType(),
this.console.getProperties().gamemode
).getId());
} }
@Override @Override

View File

@ -165,7 +165,7 @@ public class CraftBlockData implements BlockData {
* @throws IllegalStateException if the Enum could not be converted * @throws IllegalStateException if the Enum could not be converted
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static <B extends Enum<B>> B toBukkit(Enum<?> nms, Class<B> bukkit) { public static <B extends Enum<B>> B toBukkit(Enum<?> nms, Class<B> bukkit) {
if (nms instanceof Direction) { if (nms instanceof Direction) {
return (B) CraftBlock.notchToBlockFace((Direction) nms); return (B) CraftBlock.notchToBlockFace((Direction) nms);
} }

View File

@ -2,10 +2,16 @@ package org.bukkit.craftbukkit.entity;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.FishingHook; import net.minecraft.world.entity.projectile.FishingHook;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import org.bukkit.craftbukkit.CraftEquipmentSlot;
import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.FishHook; import org.bukkit.entity.FishHook;
import org.bukkit.inventory.EquipmentSlot;
public class CraftFishHook extends CraftProjectile implements FishHook { public class CraftFishHook extends CraftProjectile implements FishHook {
private double biteChance = -1; private double biteChance = -1;
@ -233,4 +239,18 @@ public class CraftFishHook extends CraftProjectile implements FishHook {
hook.resetTimeUntilLured(); hook.resetTimeUntilLured();
hook.timeUntilHooked = 0; // Reset time until hooked, will be repopulated once lured time is ticked down. hook.timeUntilHooked = 0; // Reset time until hooked, will be repopulated once lured time is ticked down.
} }
@Override
public int retrieve(EquipmentSlot slot) {
Preconditions.checkArgument(slot == EquipmentSlot.HAND || slot == EquipmentSlot.OFF_HAND, "Equipment slot must be HAND or OFF_HAND");
final FishingHook fishingHook = getHandle();
final Player playerOwner = fishingHook.getPlayerOwner();
Preconditions.checkState(playerOwner != null, "Player owner cannot be null");
final InteractionHand hand = CraftEquipmentSlot.getHand(slot);
final ItemStack itemInHand = playerOwner.getItemInHand(hand);
Preconditions.checkState(itemInHand.is(Items.FISHING_ROD), "Item in slot is not a FISHING_ROD");
return fishingHook.retrieve(itemInHand, hand);
}
} }

View File

@ -57,6 +57,7 @@
# If you need help with the configuration or have any questions related to Paper, # If you need help with the configuration or have any questions related to Paper,
# join us in our Discord or check the docs page. # join us in our Discord or check the docs page.
# #
# File Reference: https://docs.papermc.io/paper/reference/bukkit-help-configuration/
# Docs: https://docs.papermc.io/ # Docs: https://docs.papermc.io/
# Discord: https://discord.gg/papermc # Discord: https://discord.gg/papermc
# Website: https://papermc.io/ # Website: https://papermc.io/