Compare commits

..
Author SHA1 Message Date
Jake Potrebic fd5c62850a Bytecode Modification Framework 2026-08-10 18:20:44 +02:00
1095 changed files with 27111 additions and 46365 deletions

No files matched your search

+1 -1
View File
@@ -1,4 +1,4 @@
Paper [![Version](https://img.shields.io/maven-metadata/v?metadataUrl=https%3A%2F%2Fartifactory.papermc.io%2Fartifactory%2Funiverse%2Fio%2Fpapermc%2Fpaper%2Fpaper-api%2Fmaven-metadata.xml&strategy=highestVersion&filter=26.2.*&label=version&color=%23344ceb
Paper [![Version](https://img.shields.io/maven-metadata/v?metadataUrl=https%3A%2F%2Fartifactory.papermc.io%2Fartifactory%2Funiverse%2Fio%2Fpapermc%2Fpaper%2Fpaper-api%2Fmaven-metadata.xml&strategy=highestVersion&filter=26.2*&label=version&color=%23344ceb
)](https://papermc.io/downloads/paper)
[![Paper Build Status](https://img.shields.io/github/actions/workflow/status/PaperMC/Paper/build.yml?branch=main)](https://github.com/PaperMC/Paper/actions)
[![Discord](https://img.shields.io/discord/289587909051416579.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/papermc)
@@ -6,55 +6,96 @@ import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.inventory.InventoryEvent;
import org.bukkit.inventory.AnvilInventory;
import org.bukkit.inventory.InventoryView;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
* Called when an anvil is damaged from being used
*/
public interface AnvilDamagedEvent extends InventoryEvent, Cancellable {
@NullMarked
public class AnvilDamagedEvent extends InventoryEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private DamageState damageState;
private boolean cancelled;
@ApiStatus.Internal
public AnvilDamagedEvent(final InventoryView inventory, final @Nullable BlockData blockData) {
super(inventory);
this.damageState = DamageState.getState(blockData);
}
@Override
AnvilInventory getInventory();
public AnvilInventory getInventory() {
return (AnvilInventory) super.getInventory();
}
/**
* Gets the new state of damage on the anvil
*
* @return Damage state
*/
DamageState getDamageState();
public DamageState getDamageState() {
return this.damageState;
}
/**
* Sets the new state of damage on the anvil
*
* @param damageState Damage state
*/
void setDamageState(DamageState damageState);
public void setDamageState(final DamageState damageState) {
this.damageState = damageState;
}
/**
* Gets if anvil is breaking on this use
*
* @return {@code true} if breaking
*/
boolean isBreaking();
public boolean isBreaking() {
return this.damageState == DamageState.BROKEN;
}
/**
* Sets if anvil is breaking on this use
*
* @param breaking {@code true} if breaking
*/
void setBreaking(boolean breaking);
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
public void setBreaking(final boolean breaking) {
if (breaking) {
this.damageState = DamageState.BROKEN;
} else if (this.damageState == DamageState.BROKEN) {
this.damageState = DamageState.DAMAGED;
}
return Holder.HANDLER_LIST;
}
@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;
}
/**
* Represents the amount of damage on an anvil block
*/
enum DamageState {
public enum DamageState {
FULL(Material.ANVIL),
CHIPPED(Material.CHIPPED_ANVIL),
DAMAGED(Material.DAMAGED_ANVIL),
@@ -1,50 +1,88 @@
package com.destroystokyo.paper.event.block;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.block.BlockEvent;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.potion.PotionEffect;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when a beacon effect is being applied to a player.
*/
public interface BeaconEffectEvent extends BlockEvent, PlayerEvent, Cancellable {
@NullMarked
public class BeaconEffectEvent extends BlockEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Player player;
private final boolean primary;
private PotionEffect effect;
private boolean cancelled;
@ApiStatus.Internal
public BeaconEffectEvent(final Block beacon, final PotionEffect effect, final Player player, final boolean primary) {
super(beacon);
this.effect = effect;
this.player = player;
this.primary = primary;
}
/**
* Gets the potion effect being applied.
*
* @return Potion effect
*/
PotionEffect getEffect();
public PotionEffect getEffect() {
return this.effect;
}
/**
* Sets the potion effect that will be applied.
*
* @param effect Potion effect
*/
void setEffect(PotionEffect effect);
public void setEffect(final PotionEffect effect) {
this.effect = effect;
}
/**
* Gets the player who the potion effect is being applied to.
*
* @return Affected player
*/
@Override
Player getPlayer();
public Player getPlayer() {
return this.player;
}
/**
* Gets whether the effect is a primary beacon effect.
*
* @return {@code true} if this event represents a primary effect
*/
boolean isPrimary();
public boolean isPrimary() {
return this.primary;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@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;
}
}
@@ -1,9 +1,12 @@
package com.destroystokyo.paper.event.block;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.block.BlockExpEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired anytime the server intends to 'destroy' a block through some triggering reason.
@@ -15,65 +18,103 @@ import org.bukkit.event.block.BlockExpEvent;
* <p>
* Events such as leaves decaying, pistons retracting (where the block is moving), does NOT fire this event.
*/
public interface BlockDestroyEvent extends BlockExpEvent, Cancellable {
@NullMarked
public class BlockDestroyEvent extends BlockExpEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final BlockData newState;
private boolean willDrop;
private boolean playEffect = true;
private BlockData effectBlock;
private boolean cancelled;
@ApiStatus.Internal
public BlockDestroyEvent(final Block block, final BlockData newState, final BlockData effectBlock, final int xp, final boolean willDrop) {
super(block, xp);
this.newState = newState;
this.effectBlock = effectBlock;
this.willDrop = willDrop;
}
/**
* Gets the effect that will be played when the block is broken.
*
* @return block break effect
*/
BlockData getEffectBlock();
public BlockData getEffectBlock() {
return this.effectBlock;
}
/**
* Sets the effect that will be played when the block is broken.
* Note: {@link #playEffect()} must be {@code true} in order for this effect to be
* Note: {@link BlockDestroyEvent#playEffect()} must be {@code true} in order for this effect to be
* played.
*
* @param effectBlock block effect
*/
void setEffectBlock(BlockData effectBlock);
public void setEffectBlock(final BlockData effectBlock) {
this.effectBlock = effectBlock.clone();
}
/**
* @return The new state of this block (Air, or a Fluid type)
*/
BlockData getNewState();
public BlockData getNewState() {
return this.newState.clone();
}
/**
* @return If the server is going to drop the block in question with this destroy event
*/
boolean willDrop();
public boolean willDrop() {
return this.willDrop;
}
/**
* @param willDrop If the server is going to drop the block in question with this destroy event
*/
void setWillDrop(boolean willDrop);
public void setWillDrop(final boolean willDrop) {
this.willDrop = willDrop;
}
/**
* @return If the server is going to play the sound effect for this destruction
*/
boolean playEffect();
public boolean playEffect() {
return this.playEffect;
}
/**
* @param playEffect If the server should play the sound effect for this destruction
*/
void setPlayEffect(boolean playEffect);
public void setPlayEffect(final boolean playEffect) {
this.playEffect = playEffect;
}
/**
* @return If the event is cancelled, meaning the block will not be destroyed
*/
@Override
boolean isCancelled();
public boolean isCancelled() {
return this.cancelled;
}
/**
* If the event is cancelled, the block will remain in its previous state.
*/
@Override
void setCancelled(boolean cancel);
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,6 +1,7 @@
package com.destroystokyo.paper.event.block;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
@@ -8,7 +9,9 @@ import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.block.BlockEvent;
import org.jspecify.annotations.Nullable;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Called when TNT block is about to turn into {@link TNTPrimed}
@@ -20,14 +23,31 @@ import org.jspecify.annotations.Nullable;
* @deprecated use {@link org.bukkit.event.block.TNTPrimeEvent}
*/
@Deprecated(forRemoval = true, since = "1.19.4")
public interface TNTPrimeEvent extends BlockEvent, Cancellable {
public class TNTPrimeEvent extends BlockEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
@NotNull private final PrimeReason reason;
@Nullable private final Entity primerEntity;
private boolean cancelled;
@ApiStatus.Internal
public TNTPrimeEvent(@NotNull Block block, @NotNull PrimeReason reason, @Nullable Entity primerEntity) {
super(block);
this.reason = reason;
this.primerEntity = primerEntity;
}
/**
* Gets the TNT prime reason
*
* @return Prime reason
*/
PrimeReason getReason();
@NotNull
public PrimeReason getReason() {
return this.reason;
}
/**
* Gets the TNT primer {@link Entity}.
@@ -38,7 +58,10 @@ public interface TNTPrimeEvent extends BlockEvent, Cancellable {
*
* @return The {@link Entity} who primed the TNT
*/
@Nullable Entity getPrimerEntity();
@Nullable
public Entity getPrimerEntity() {
return this.primerEntity;
}
/**
* Gets whether spawning {@link TNTPrimed} should be cancelled or not
@@ -46,7 +69,9 @@ public interface TNTPrimeEvent extends BlockEvent, Cancellable {
* @return Whether spawning {@link TNTPrimed} should be cancelled or not
*/
@Override
boolean isCancelled();
public boolean isCancelled() {
return this.cancelled;
}
/**
* Sets whether to cancel spawning {@link TNTPrimed} or not
@@ -54,16 +79,22 @@ public interface TNTPrimeEvent extends BlockEvent, Cancellable {
* @param cancel whether spawning {@link TNTPrimed} should be cancelled or not
*/
@Override
void setCancelled(boolean cancel);
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
enum PrimeReason {
@NotNull
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
@NotNull
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
public enum PrimeReason {
/**
* When TNT prime was caused by other explosion (chain reaction)
*/
@@ -1,4 +0,0 @@
@NullMarked
package com.destroystokyo.paper.event.block;
import org.jspecify.annotations.NullMarked;
@@ -2,9 +2,12 @@ package com.destroystokyo.paper.event.brigadier;
import com.mojang.brigadier.tree.RootCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired any time a Brigadier RootCommandNode is generated for a player to inform the client of commands.
@@ -27,26 +30,45 @@ import org.jetbrains.annotations.ApiStatus;
* <p>This is a draft/experimental API and is subject to change.</p>
*/
@ApiStatus.Experimental
public interface AsyncPlayerSendCommandsEvent<S extends CommandSourceStack> extends PlayerEvent {
@NullMarked
public class AsyncPlayerSendCommandsEvent<S extends CommandSourceStack> extends PlayerEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final RootCommandNode<S> node;
private final boolean hasFiredAsync;
@ApiStatus.Internal
public AsyncPlayerSendCommandsEvent(final Player player, final RootCommandNode<S> node, final boolean hasFiredAsync) {
super(player, !Bukkit.isPrimaryThread());
this.node = node;
this.hasFiredAsync = hasFiredAsync;
}
/**
* Gets the full Root Command Node being sent to the client, which is mutable.
*
* @return the root command node
*/
RootCommandNode<S> getCommandNode();
public RootCommandNode<S> getCommandNode() {
return this.node;
}
/**
* Gets if this event has already fired asynchronously.
*
* @return whether this event has already fired asynchronously
*/
boolean hasFiredAsync();
public boolean hasFiredAsync() {
return this.hasFiredAsync;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,37 +1,67 @@
package com.destroystokyo.paper.event.brigadier;
import com.mojang.brigadier.suggestion.Suggestions;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when sending {@link Suggestions} to the client. Will be called asynchronously if a plugin
* marks the {@link com.destroystokyo.paper.event.server.AsyncTabCompleteEvent} event handled asynchronously,
* otherwise called synchronously.
*/
public interface AsyncPlayerSendSuggestionsEvent extends PlayerEvent, Cancellable {
@NullMarked
public class AsyncPlayerSendSuggestionsEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private Suggestions suggestions;
private final String buffer;
private boolean cancelled;
@ApiStatus.Internal
public AsyncPlayerSendSuggestionsEvent(final Player player, final Suggestions suggestions, final String buffer) {
super(player, !Bukkit.isPrimaryThread());
this.suggestions = suggestions;
this.buffer = buffer;
}
/**
* Gets the input buffer sent to request these suggestions.
*
* @return the input buffer
*/
String getBuffer();
public String getBuffer() {
return this.buffer;
}
/**
* Gets the suggestions to be sent to client.
*
* @return the suggestions
*/
Suggestions getSuggestions();
public Suggestions getSuggestions() {
return this.suggestions;
}
/**
* Sets the suggestions to be sent to client.
*
* @param suggestions suggestions
*/
void setSuggestions(Suggestions suggestions);
public void setSuggestions(final Suggestions suggestions) {
this.suggestions = suggestions;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
/**
* Cancels sending suggestions to the client.
@@ -39,12 +69,16 @@ public interface AsyncPlayerSendSuggestionsEvent extends PlayerEvent, Cancellabl
* {@inheritDoc}
*/
@Override
void setCancelled(boolean cancel);
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,7 +1,6 @@
package com.destroystokyo.paper.event.brigadier;
import com.destroystokyo.paper.brigadier.BukkitBrigadierCommand;
import com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource;
import com.mojang.brigadier.tree.ArgumentCommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode;
import com.mojang.brigadier.tree.RootCommandNode;
@@ -10,6 +9,7 @@ import org.bukkit.command.Command;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.server.ServerEvent;
import org.jetbrains.annotations.NotNull;
/**
* Fired anytime the server synchronizes Bukkit commands to Brigadier.
@@ -22,14 +22,37 @@ import org.bukkit.event.server.ServerEvent;
*/
@Deprecated(since = "1.20.6")
@Warning(reason = "This event has been superseded by the Commands API and will be removed in a future release. Listen to LifecycleEvents.COMMANDS instead.", value = true)
public interface CommandRegisteredEvent<S extends BukkitBrigadierCommandSource> extends ServerEvent, Cancellable {
public class CommandRegisteredEvent<S extends com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource> extends ServerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final String commandLabel;
private final Command command;
private final com.destroystokyo.paper.brigadier.BukkitBrigadierCommand<S> brigadierCommand;
private final RootCommandNode<S> root;
private final ArgumentCommandNode<S, String> defaultArgs;
private LiteralCommandNode<S> literal;
private boolean rawCommand = false;
private boolean cancelled;
public CommandRegisteredEvent(String commandLabel, com.destroystokyo.paper.brigadier.BukkitBrigadierCommand<S> brigadierCommand, Command command, RootCommandNode<S> root, LiteralCommandNode<S> literal, ArgumentCommandNode<S, String> defaultArgs) {
this.commandLabel = commandLabel;
this.brigadierCommand = brigadierCommand;
this.command = command;
this.root = root;
this.literal = literal;
this.defaultArgs = defaultArgs;
}
/**
* Gets the command label of the {@link Command} being registered.
*
* @return the command label
*/
String getCommandLabel();
public String getCommandLabel() {
return this.commandLabel;
}
/**
* Gets the {@link BukkitBrigadierCommand} for the {@link Command} being registered. This can be used
@@ -39,36 +62,27 @@ public interface CommandRegisteredEvent<S extends BukkitBrigadierCommandSource>
*
* @return the {@link BukkitBrigadierCommand}
*/
BukkitBrigadierCommand<S> getBrigadierCommand();
public BukkitBrigadierCommand<S> getBrigadierCommand() {
return this.brigadierCommand;
}
/**
* Gets the {@link Command} being registered.
*
* @return the {@link Command}
*/
Command getCommand();
public Command getCommand() {
return this.command;
}
/**
* Gets the {@link RootCommandNode} which is being registered to.
*
* @return the {@link RootCommandNode}
*/
RootCommandNode<S> getRoot();
/**
* Gets the {@link LiteralCommandNode} to be registered for the {@link Command}.
*
* @return the {@link LiteralCommandNode}
*/
LiteralCommandNode<S> getLiteral();
/**
* Sets the {@link LiteralCommandNode} used to register this command. The default literal is mutable, so
* this is primarily if you want to completely replace the object.
*
* @param literal new node
*/
void setLiteral(LiteralCommandNode<S> literal);
public RootCommandNode<S> getRoot() {
return this.root;
}
/**
* Gets the Bukkit APIs default arguments node (greedy string), for if
@@ -76,7 +90,28 @@ public interface CommandRegisteredEvent<S extends BukkitBrigadierCommandSource>
*
* @return default arguments node
*/
ArgumentCommandNode<S, String> getDefaultArgs();
public ArgumentCommandNode<S, String> getDefaultArgs() {
return this.defaultArgs;
}
/**
* Gets the {@link LiteralCommandNode} to be registered for the {@link Command}.
*
* @return the {@link LiteralCommandNode}
*/
public LiteralCommandNode<S> getLiteral() {
return this.literal;
}
/**
* Sets the {@link LiteralCommandNode} used to register this command. The default literal is mutable, so
* this is primarily if you want to completely replace the object.
*
* @param literal new node
*/
public void setLiteral(LiteralCommandNode<S> literal) {
this.literal = literal;
}
/**
* Gets whether this command should is treated as "raw".
@@ -84,7 +119,9 @@ public interface CommandRegisteredEvent<S extends BukkitBrigadierCommandSource>
* @see #setRawCommand(boolean)
* @return whether this command is treated as "raw"
*/
boolean isRawCommand();
public boolean isRawCommand() {
return this.rawCommand;
}
/**
* Sets whether this command should be treated as "raw".
@@ -98,7 +135,14 @@ public interface CommandRegisteredEvent<S extends BukkitBrigadierCommandSource>
*
* @param rawCommand whether this command should be treated as "raw"
*/
void setRawCommand(boolean rawCommand);
public void setRawCommand(final boolean rawCommand) {
this.rawCommand = rawCommand;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
/**
* Cancels registering this command to Brigadier, but will remain in Bukkit Command Map. Can be used to hide a
@@ -107,12 +151,17 @@ public interface CommandRegisteredEvent<S extends BukkitBrigadierCommandSource>
* {@inheritDoc}
*/
@Override
void setCancelled(boolean cancel);
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@NotNull
public HandlerList getHandlers() {
return HANDLER_LIST;
}
@NotNull
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,4 +0,0 @@
@NullMarked
package com.destroystokyo.paper.event.brigadier;
import org.jspecify.annotations.NullMarked;
@@ -2,18 +2,59 @@ package com.destroystokyo.paper.event.entity;
import io.papermc.paper.event.entity.EntityIgniteEvent;
import org.bukkit.entity.Creeper;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.checkerframework.checker.index.qual.Positive;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when a Creeper is ignited either by a
* flint and steel, {@link Creeper#ignite()} or
* {@link Creeper#setIgnited(boolean)}.
*/
public interface CreeperIgniteEvent extends EntityIgniteEvent {
@NullMarked
public class CreeperIgniteEvent extends EntityIgniteEvent {
private boolean ignited;
@ApiStatus.Internal
public CreeperIgniteEvent(final Creeper creeper, final boolean ignited) {
super(creeper, creeper.getMaxFuseTicks());
this.ignited = ignited;
}
@Override
Creeper getEntity();
public Creeper getEntity() {
return (Creeper) super.getEntity();
}
boolean isIgnited();
public boolean isIgnited() {
return this.ignited;
}
void setIgnited(boolean ignited);
public void setIgnited(final boolean ignited) {
this.ignited = ignited;
}
@Override
public @Positive int getFuseTime() {
return this.getEntity().getMaxFuseTicks();
}
@Override
public void setFuseTime(final @Positive int ticks) {
this.getEntity().setMaxFuseTicks(ticks);
}
@Override
public boolean isCancelled() {
return super.isCancelled();
}
@Override
public void setCancelled(final boolean cancel) {
super.setCancelled(cancel);
}
}
@@ -7,35 +7,68 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.jetbrains.annotations.Unmodifiable;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired when a DragonFireball collides with a block/entity and spawns an AreaEffectCloud
*/
public interface EnderDragonFireballHitEvent extends EntityEvent, Cancellable {
@NullMarked
public class EnderDragonFireballHitEvent extends EntityEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Collection<LivingEntity> targets;
private final AreaEffectCloud areaEffectCloud;
private boolean cancelled;
@ApiStatus.Internal
public EnderDragonFireballHitEvent(final DragonFireball fireball, final Collection<LivingEntity> targets, final AreaEffectCloud areaEffectCloud) {
super(fireball);
this.targets = targets;
this.areaEffectCloud = areaEffectCloud;
}
/**
* The fireball involved in this event
*/
@Override
DragonFireball getEntity();
public DragonFireball getEntity() {
return (DragonFireball) super.getEntity();
}
/**
* The living entities hit by fireball
*
* @return the targets
*/
@Unmodifiable Collection<LivingEntity> getTargets();
public Collection<LivingEntity> getTargets() {
return this.targets;
}
/**
* @return The area effect cloud spawned in this collision
*/
AreaEffectCloud getAreaEffectCloud();
public AreaEffectCloud getAreaEffectCloud() {
return this.areaEffectCloud;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@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;
}
}
@@ -5,27 +5,57 @@ import org.bukkit.entity.EnderDragon;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired when an EnderDragon spawns an AreaEffectCloud by shooting flames
*/
public interface EnderDragonFlameEvent extends EntityEvent, Cancellable {
@NullMarked
public class EnderDragonFlameEvent extends EntityEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final AreaEffectCloud areaEffectCloud;
private boolean cancelled;
@ApiStatus.Internal
public EnderDragonFlameEvent(final EnderDragon enderDragon, final AreaEffectCloud areaEffectCloud) {
super(enderDragon);
this.areaEffectCloud = areaEffectCloud;
}
/**
* The enderdragon involved in this event
*/
@Override
EnderDragon getEntity();
public EnderDragon getEntity() {
return (EnderDragon) super.getEntity();
}
/**
* @return The area effect cloud spawned in this collision
*/
AreaEffectCloud getAreaEffectCloud();
public AreaEffectCloud getAreaEffectCloud() {
return this.areaEffectCloud;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@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;
}
}
@@ -5,27 +5,57 @@ import org.bukkit.entity.EnderDragon;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired when an EnderDragon shoots a fireball
*/
public interface EnderDragonShootFireballEvent extends EntityEvent, Cancellable {
@NullMarked
public class EnderDragonShootFireballEvent extends EntityEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final DragonFireball fireball;
private boolean cancelled;
@ApiStatus.Internal
public EnderDragonShootFireballEvent(final EnderDragon entity, final DragonFireball fireball) {
super(entity);
this.fireball = fireball;
}
/**
* The enderdragon shooting the fireball
*/
@Override
EnderDragon getEntity();
public EnderDragon getEntity() {
return (EnderDragon) super.getEntity();
}
/**
* @return The fireball being shot
*/
DragonFireball getFireball();
public DragonFireball getFireball() {
return this.fireball;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@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;
}
}
@@ -28,6 +28,8 @@ import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired when an Enderman determines if it should attack a player or not.
@@ -35,7 +37,19 @@ import org.bukkit.event.entity.EntityEvent;
* Starts off cancelled if the player is wearing a pumpkin head or is not looking
* at the Enderman, according to Vanilla rules.
*/
public interface EndermanAttackPlayerEvent extends EntityEvent, Cancellable {
@NullMarked
public class EndermanAttackPlayerEvent extends EntityEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Player player;
private boolean cancelled;
@ApiStatus.Internal
public EndermanAttackPlayerEvent(final Enderman entity, final Player player) {
super(entity);
this.player = player;
}
/**
* The enderman considering attacking
@@ -43,20 +57,26 @@ public interface EndermanAttackPlayerEvent extends EntityEvent, Cancellable {
* @return The enderman considering attacking
*/
@Override
Enderman getEntity();
public Enderman getEntity() {
return (Enderman) super.getEntity();
}
/**
* The player the Enderman is considering attacking
*
* @return The player the Enderman is considering attacking
*/
Player getPlayer();
public Player getPlayer() {
return this.player;
}
/**
* @return If cancelled, the enderman will not attack
*/
@Override
boolean isCancelled();
public boolean isCancelled() {
return this.cancelled;
}
/**
* {@inheritDoc}
@@ -64,12 +84,16 @@ public interface EndermanAttackPlayerEvent extends EntityEvent, Cancellable {
* Cancels if the Enderman will attack this player
*/
@Override
void setCancelled(boolean cancel);
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -4,18 +4,41 @@ import org.bukkit.entity.Enderman;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
public interface EndermanEscapeEvent extends EntityEvent, Cancellable {
@NullMarked
public class EndermanEscapeEvent extends EntityEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Reason reason;
private boolean cancelled;
@ApiStatus.Internal
public EndermanEscapeEvent(final Enderman entity, final Reason reason) {
super(entity);
this.reason = reason;
}
@Override
Enderman getEntity();
public Enderman getEntity() {
return (Enderman) super.getEntity();
}
/**
* Gets the reason the enderman is trying to escape.
*
* @return The reason
*/
Reason getReason();
public Reason getReason() {
return this.reason;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
/**
* Cancels the escape.
@@ -25,16 +48,20 @@ public interface EndermanEscapeEvent extends EntityEvent, Cancellable {
* innate immunities or damage behavior like arrows where the damage never happens.
*/
@Override
void setCancelled(boolean cancel);
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
enum Reason {
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
public enum Reason {
/**
* The enderman has stopped attacking and ran away
*/
@@ -1,28 +1,44 @@
package com.destroystokyo.paper.event.entity;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.EntityEvent;
import org.bukkit.event.world.WorldEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired any time an entity is being added to the world for any reason (including a chunk loading).
* <p>
* Not to be confused with {@link CreatureSpawnEvent}
*/
public interface EntityAddToWorldEvent extends EntityEvent, WorldEvent {
@NullMarked
public class EntityAddToWorldEvent extends EntityEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final World world;
@ApiStatus.Internal
public EntityAddToWorldEvent(final Entity entity, final World world) {
super(entity);
this.world = world;
}
/**
* @return The world that the entity is being added to
*/
@Override
World getWorld();
public World getWorld() {
return this.world;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -4,21 +4,47 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when an entity jumps
* <p>
* Cancelling the event will stop the entity from jumping
*/
public interface EntityJumpEvent extends EntityEvent, Cancellable {
@NullMarked
public class EntityJumpEvent extends EntityEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private boolean cancelled;
@ApiStatus.Internal
public EntityJumpEvent(final LivingEntity entity) {
super(entity);
}
@Override
LivingEntity getEntity();
public LivingEntity getEntity() {
return (LivingEntity) super.getEntity();
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@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;
}
}
@@ -1,33 +1,52 @@
package com.destroystokyo.paper.event.entity;
import io.papermc.paper.event.entity.EntityKnockbackEvent;
import io.papermc.paper.event.entity.EntityPushedByEntityAttackEvent;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired when an Entity is knocked back by the hit of another Entity. The acceleration
* vector can be modified. If this event is cancelled, the entity is not knocked back.
*/
public interface EntityKnockbackByEntityEvent extends EntityPushedByEntityAttackEvent {
@NullMarked
public class EntityKnockbackByEntityEvent extends EntityPushedByEntityAttackEvent {
private final float knockbackStrength;
@ApiStatus.Internal
public EntityKnockbackByEntityEvent(final LivingEntity entity, final Entity hitBy, final EntityKnockbackEvent.Cause cause, final float knockbackStrength, final Vector knockback) {
super(entity, cause, hitBy, knockback);
this.knockbackStrength = knockbackStrength;
}
/**
* @return the entity which was knocked back
*/
@Override
LivingEntity getEntity();
public LivingEntity getEntity() {
return (LivingEntity) super.getEntity();
}
/**
* @return the original knockback strength.
* @apiNote this value doesn't necessarily relate to {@link #getKnockback()}.
*/
@ApiStatus.Obsolete(since = "1.20.6")
float getKnockbackStrength();
public float getKnockbackStrength() {
return this.knockbackStrength;
}
/**
* Gets the causing entity. Same as {@link #getPushedBy()}.
*
* @return the Entity which hit
*/
Entity getHitBy();
public Entity getHitBy() {
return super.getPushedBy();
}
}
@@ -5,6 +5,8 @@ import org.bukkit.entity.Entity;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
@@ -13,7 +15,21 @@ import org.jspecify.annotations.Nullable;
* This event does not fire for the entities actual movement. Only when it
* is choosing to start moving to a location.
*/
public interface EntityPathfindEvent extends EntityEvent, Cancellable {
@NullMarked
public class EntityPathfindEvent extends EntityEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final @Nullable Entity targetEntity;
private final Location location;
private boolean cancelled;
@ApiStatus.Internal
public EntityPathfindEvent(final Entity entity, final Location location, final @Nullable Entity targetEntity) {
super(entity);
this.targetEntity = targetEntity;
this.location = location;
}
/**
* The Entity that is pathfinding.
@@ -21,7 +37,9 @@ public interface EntityPathfindEvent extends EntityEvent, Cancellable {
* @return The Entity that is pathfinding.
*/
@Override
Entity getEntity();
public Entity getEntity() {
return this.entity;
}
/**
* If the Entity is trying to pathfind to an entity, this is the entity in relation.
@@ -30,34 +48,37 @@ public interface EntityPathfindEvent extends EntityEvent, Cancellable {
*
* @return The entity target or {@code null}
*/
@Nullable Entity getTargetEntity();
/**
* The Location of where the entity is about to move to.
* <br>
* Note that if the target happened to of been an entity
*
* @return Location of where the entity is trying to pathfind to.
*/
Location getTargetLocation();
/**
* The Location of where the entity is about to move to.
* <br>
* Note that if the target happened to of been an entity
*
* @return Location of where the entity is trying to pathfind to.
* @deprecated use {@link #getTargetLocation()}
*/
@Deprecated(forRemoval = true)
default Location getLoc() {
return this.getTargetLocation();
public @Nullable Entity getTargetEntity() {
return this.targetEntity;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
/**
* The Location of where the entity is about to move to.
* <br>
* Note that if the target happened to of been an entity
*
* @return Location of where the entity is trying to pathfind to.
*/
public Location getLoc() {
return this.location.clone();
}
@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;
}
}
@@ -1,26 +1,42 @@
package com.destroystokyo.paper.event.entity;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.bukkit.event.world.WorldEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired any time an entity is being removed from a world for any reason (including a chunk unloading).
* Note: The entity is updated prior to this event being called, as such, the entity's world may not be equal to {@link #getWorld()}.
*/
public interface EntityRemoveFromWorldEvent extends EntityEvent, WorldEvent {
@NullMarked
public class EntityRemoveFromWorldEvent extends EntityEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final World world;
@ApiStatus.Internal
public EntityRemoveFromWorldEvent(final Entity entity, final World world) {
super(entity);
this.world = world;
}
/**
* @return The world that the entity is being removed from
*/
@Override
World getWorld();
public World getWorld() {
return this.world;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,17 +1,33 @@
package com.destroystokyo.paper.event.entity;
import org.bukkit.Location;
import org.bukkit.block.EndGateway;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityTeleportEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired any time an entity attempts to teleport in an end gateway
*/
public interface EntityTeleportEndGatewayEvent extends EntityTeleportEvent {
@NullMarked
public class EntityTeleportEndGatewayEvent extends EntityTeleportEvent {
private final EndGateway gateway;
@ApiStatus.Internal
public EntityTeleportEndGatewayEvent(final Entity entity, final Location from, final Location to, final EndGateway gateway) {
super(entity, from, to);
this.gateway = gateway;
}
/**
* The gateway triggering the teleport
*
* @return EndGateway used
*/
EndGateway getGateway();
public EndGateway getGateway() {
return this.gateway;
}
}
@@ -1,35 +1,65 @@
package com.destroystokyo.paper.event.entity;
import java.util.Collections;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LightningStrike;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityTransformEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired when lightning strikes an entity
*/
public interface EntityZapEvent extends EntityTransformEvent {
@NullMarked
public class EntityZapEvent extends EntityTransformEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final LightningStrike bolt;
private boolean cancelled;
@ApiStatus.Internal
public EntityZapEvent(final Entity entity, final LightningStrike bolt, final Entity replacementEntity) {
super(entity, Collections.singletonList(replacementEntity), TransformReason.LIGHTNING);
this.bolt = bolt;
}
/**
* Gets the lightning bolt that is striking the entity.
*
* @return The lightning bolt responsible for this event
*/
LightningStrike getBolt();
public LightningStrike getBolt() {
return this.bolt;
}
/**
* Gets the entity that will replace the struck entity.
*
* @return The entity that will replace the struck entity
*/
default Entity getReplacementEntity() {
return this.getTransformedEntity();
public Entity getReplacementEntity() {
return super.getTransformedEntity();
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@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;
}
}
@@ -27,32 +27,62 @@ import org.bukkit.entity.ExperienceOrb;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired anytime the server is about to merge 2 experience orbs into one
*/
public interface ExperienceOrbMergeEvent extends EntityEvent, Cancellable {
@NullMarked
public class ExperienceOrbMergeEvent extends EntityEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final ExperienceOrb mergeTarget;
private final ExperienceOrb mergeSource;
private boolean cancelled;
@ApiStatus.Internal
public ExperienceOrbMergeEvent(final ExperienceOrb mergeTarget, final ExperienceOrb mergeSource) {
super(mergeTarget);
this.mergeTarget = mergeTarget;
this.mergeSource = mergeSource;
}
/**
* {@return the orb that will absorb the other experience orb}
* @return The orb that will absorb the other experience orb
*/
ExperienceOrb getMergeTarget();
public ExperienceOrb getMergeTarget() {
return this.mergeTarget;
}
/**
* {@return the orb that is subject to being removed and merged into the target orb}
* @return The orb that is subject to being removed and merged into the target orb
*/
ExperienceOrb getMergeSource();
public ExperienceOrb getMergeSource() {
return this.mergeSource;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
/**
* @param cancel {@code true} if you wish to cancel this event, and prevent the orbs from merging
*/
@Override
void setCancelled(boolean cancel);
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,16 +1,32 @@
package com.destroystokyo.paper.event.entity;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when a phantom is spawned for an exhausted player
*/
public interface PhantomPreSpawnEvent extends PreCreatureSpawnEvent {
@NullMarked
public class PhantomPreSpawnEvent extends PreCreatureSpawnEvent {
private final Entity entity;
@ApiStatus.Internal
public PhantomPreSpawnEvent(final Location location, final Entity entity, final CreatureSpawnEvent.SpawnReason reason) {
super(location, EntityType.PHANTOM, reason);
this.entity = entity;
}
/**
* Get the entity this phantom is spawning for
*
* @return the Entity
*/
Entity getSpawningEntity();
public Entity getSpawningEntity() {
return this.entity;
}
}
@@ -1,40 +1,65 @@
package com.destroystokyo.paper.event.entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired when the server is calculating what chunks to try to spawn monsters in every Monster Spawn Tick event
*/
public interface PlayerNaturallySpawnCreaturesEvent extends PlayerEvent, Cancellable {
@NullMarked
public class PlayerNaturallySpawnCreaturesEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private byte radius;
private boolean cancelled;
@ApiStatus.Internal
public PlayerNaturallySpawnCreaturesEvent(final Player player, final byte radius) {
super(player);
this.radius = radius;
}
/**
* @return The radius of chunks around this player to be included in natural spawn selection
*/
byte getSpawnRadius();
public byte getSpawnRadius() {
return this.radius;
}
/**
* @param radius The radius of chunks around this player to be included in natural spawn selection
*/
void setSpawnRadius(byte radius);
public void setSpawnRadius(final byte radius) {
this.radius = radius;
}
/**
* @return If this player's chunks will be excluded from natural spawns
*/
@Override
boolean isCancelled();
public boolean isCancelled() {
return this.cancelled;
}
/**
* @param cancel {@code true} if you wish to cancel this event, and not include this player's chunks for natural spawning
*/
@Override
void setCancelled(boolean cancel);
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -6,6 +6,8 @@ import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* WARNING: This event only fires for a limited number of cases, and not for every case that {@link CreatureSpawnEvent} does.
@@ -17,27 +19,52 @@ import org.bukkit.event.entity.CreatureSpawnEvent;
* Currently: NATURAL and SPAWNER based reasons. <!-- Please submit a Pull Request for future additions. -->
* Also, Plugins that replace Entity Registrations with their own custom entities might not fire this event.
*/
public interface PreCreatureSpawnEvent extends Event, Cancellable {
@NullMarked
public class PreCreatureSpawnEvent extends Event implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Location location;
private final EntityType type;
private final CreatureSpawnEvent.SpawnReason reason;
private boolean shouldAbortSpawn;
private boolean cancelled;
@ApiStatus.Internal
public PreCreatureSpawnEvent(final Location location, final EntityType type, final CreatureSpawnEvent.SpawnReason reason) {
this.location = location;
this.type = type;
this.reason = reason;
}
/**
* @return The location this creature is being spawned at
*/
Location getSpawnLocation();
public Location getSpawnLocation() {
return this.location.clone();
}
/**
* @return The type of creature being spawned
*/
EntityType getType();
public EntityType getType() {
return this.type;
}
/**
* @return Reason this creature is spawning (ie, NATURAL vs SPAWNER)
*/
CreatureSpawnEvent.SpawnReason getReason();
public CreatureSpawnEvent.SpawnReason getReason() {
return this.reason;
}
/**
* @return If the spawn process should be aborted vs trying more attempts
*/
boolean shouldAbortSpawn();
public boolean shouldAbortSpawn() {
return this.shouldAbortSpawn;
}
/**
* Set this if you are more blanket blocking all types of these spawns, and wish to abort the spawn process from
@@ -45,13 +72,17 @@ public interface PreCreatureSpawnEvent extends Event, Cancellable {
*
* @param shouldAbortSpawn Set if the spawn process should be aborted vs trying more attempts
*/
void setShouldAbortSpawn(boolean shouldAbortSpawn);
public void setShouldAbortSpawn(final boolean shouldAbortSpawn) {
this.shouldAbortSpawn = shouldAbortSpawn;
}
/**
* @return If the spawn of this creature is cancelled or not
*/
@Override
boolean isCancelled();
public boolean isCancelled() {
return this.cancelled;
}
/**
* Cancelling this event is more efficient than cancelling {@link CreatureSpawnEvent}
@@ -59,12 +90,16 @@ public interface PreCreatureSpawnEvent extends Event, Cancellable {
* @param cancel {@code true} if you wish to cancel this event, and abort the spawn of this creature
*/
@Override
void setCancelled(boolean cancel);
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,6 +1,10 @@
package com.destroystokyo.paper.event.entity;
import org.bukkit.Location;
import org.bukkit.entity.EntityType;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called before an entity is spawned into a world by a spawner.
@@ -8,7 +12,18 @@ import org.bukkit.Location;
* This only includes the spawner's location and not the full BlockState snapshot for performance reasons.
* If you really need it you have to get the spawner yourself.
*/
public interface PreSpawnerSpawnEvent extends PreCreatureSpawnEvent {
@NullMarked
public class PreSpawnerSpawnEvent extends PreCreatureSpawnEvent {
Location getSpawnerLocation();
private final Location spawnerLocation;
@ApiStatus.Internal
public PreSpawnerSpawnEvent(final Location location, final EntityType type, final Location spawnerLocation) {
super(location, type, CreatureSpawnEvent.SpawnReason.SPAWNER);
this.spawnerLocation = spawnerLocation;
}
public Location getSpawnerLocation() {
return this.spawnerLocation.clone();
}
}
@@ -6,36 +6,69 @@ import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
/**
* Called when a projectile collides with an entity
* <p>
* This event is called <b>before</b> {@link EntityDamageByEntityEvent}, and cancelling it will allow the projectile to continue flying
*
* @deprecated use {@link org.bukkit.event.entity.ProjectileHitEvent} and check if there is a hit entity
* @deprecated Deprecated, use {@link org.bukkit.event.entity.ProjectileHitEvent} and check if there is a hit entity
*/
@Deprecated(since = "1.19.3")
public interface ProjectileCollideEvent extends EntityEvent, Cancellable {
public class ProjectileCollideEvent extends EntityEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
@NotNull private final Entity collidedWith;
private boolean cancelled;
@ApiStatus.Internal
public ProjectileCollideEvent(@NotNull Projectile projectile, @NotNull Entity collidedWith) {
super(projectile);
this.collidedWith = collidedWith;
}
/**
* Get the projectile that collided
*
* @return the projectile that collided
*/
@Override
Projectile getEntity();
@NotNull
public Projectile getEntity() {
return (Projectile) super.getEntity();
}
/**
* Get the entity the projectile collided with
*
* @return the entity collided with
*/
Entity getCollidedWith();
@NotNull
public Entity getCollidedWith() {
return this.collidedWith;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
@NotNull
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
@NotNull
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
}
@@ -6,22 +6,52 @@ import org.bukkit.entity.SkeletonHorse;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Event called when a player gets close to a skeleton horse and triggers the lightning trap
*/
public interface SkeletonHorseTrapEvent extends EntityEvent, Cancellable {
@NullMarked
public class SkeletonHorseTrapEvent extends EntityEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final List<HumanEntity> eligibleHumans;
private boolean cancelled;
@ApiStatus.Internal
public SkeletonHorseTrapEvent(final SkeletonHorse horse, final List<HumanEntity> eligibleHumans) {
super(horse);
this.eligibleHumans = eligibleHumans;
}
@Override
SkeletonHorse getEntity();
public SkeletonHorse getEntity() {
return (SkeletonHorse) super.getEntity();
}
List<HumanEntity> getEligibleHumans();
public List<HumanEntity> getEligibleHumans() {
return this.eligibleHumans;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@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;
}
}
@@ -1,24 +1,41 @@
package com.destroystokyo.paper.event.entity;
import org.bukkit.entity.AbstractCubeMob;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired when a Slime decides to change its facing direction.
* <p>
* This event does not fire for the entity's actual movement. Only when it
* is choosing to change direction.
*/
public interface SlimeChangeDirectionEvent extends SlimePathfindEvent {
@NullMarked
public class SlimeChangeDirectionEvent extends SlimePathfindEvent {
private float yaw;
@ApiStatus.Internal
public SlimeChangeDirectionEvent(final AbstractCubeMob cubeMob, final float yaw) {
super(cubeMob);
this.yaw = yaw;
}
/**
* Get the new chosen yaw
*
* @return Chosen yaw
*/
float getNewYaw();
public float getNewYaw() {
return this.yaw;
}
/**
* Set the new chosen yaw
*
* @param yaw Chosen yaw
*/
void setNewYaw(float yaw);
public void setNewYaw(final float yaw) {
this.yaw = yaw;
}
}
@@ -4,6 +4,8 @@ import org.bukkit.entity.AbstractCubeMob;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired when a Slime decides to start pathfinding.
@@ -11,7 +13,17 @@ import org.bukkit.event.entity.EntityEvent;
* This event does not fire for the entity's actual movement. Only when it
* is choosing to start moving.
*/
public interface SlimePathfindEvent extends EntityEvent, Cancellable {
@NullMarked
public class SlimePathfindEvent extends EntityEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private boolean cancelled;
@ApiStatus.Internal
public SlimePathfindEvent(final AbstractCubeMob cubeMob) {
super(cubeMob);
}
/**
* The Slime that is pathfinding.
@@ -19,12 +31,26 @@ public interface SlimePathfindEvent extends EntityEvent, Cancellable {
* @return The Slime that is pathfinding.
*/
@Override
AbstractCubeMob getEntity();
public AbstractCubeMob getEntity() {
return (AbstractCubeMob) super.getEntity();
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@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;
}
}
@@ -1,10 +1,20 @@
package com.destroystokyo.paper.event.entity;
import org.bukkit.entity.AbstractCubeMob;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired when a Slime decides to start jumping while swimming in water/lava.
* <p>
* This event does not fire for the entity's actual movement. Only when it
* is choosing to start jumping.
*/
public interface SlimeSwimEvent extends SlimeWanderEvent {
@NullMarked
public class SlimeSwimEvent extends SlimeWanderEvent {
@ApiStatus.Internal
public SlimeSwimEvent(final AbstractCubeMob cubeMob) {
super(cubeMob);
}
}
@@ -1,6 +1,9 @@
package com.destroystokyo.paper.event.entity;
import org.bukkit.entity.AbstractCubeMob;
import org.bukkit.entity.LivingEntity;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired when a Slime decides to change direction to target a LivingEntity.
@@ -8,12 +11,23 @@ import org.bukkit.entity.LivingEntity;
* This event does not fire for the entity's actual movement. Only when it
* is choosing to start moving.
*/
public interface SlimeTargetLivingEntityEvent extends SlimePathfindEvent {
@NullMarked
public class SlimeTargetLivingEntityEvent extends SlimePathfindEvent {
private final LivingEntity target;
@ApiStatus.Internal
public SlimeTargetLivingEntityEvent(final AbstractCubeMob cubeMob, final LivingEntity target) {
super(cubeMob);
this.target = target;
}
/**
* Get the targeted entity
*
* @return Targeted entity
*/
LivingEntity getTarget();
public LivingEntity getTarget() {
return this.target;
}
}
@@ -1,10 +1,20 @@
package com.destroystokyo.paper.event.entity;
import org.bukkit.entity.AbstractCubeMob;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired when a Slime decides to start wandering.
* <p>
* This event does not fire for the entity's actual movement. Only when it
* is choosing to start moving.
*/
public interface SlimeWanderEvent extends SlimePathfindEvent {
@NullMarked
public class SlimeWanderEvent extends SlimePathfindEvent {
@ApiStatus.Internal
public SlimeWanderEvent(final AbstractCubeMob cubeMob) {
super(cubeMob);
}
}
@@ -1,39 +1,54 @@
package com.destroystokyo.paper.event.entity;
import com.google.common.base.Preconditions;
import org.bukkit.entity.Egg;
import org.bukkit.entity.EntityType;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.checkerframework.checker.index.qual.NonNegative;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when a thrown egg might hatch.
* <p>
* This event fires for all thrown eggs that may hatch, players, dispensers, etc.
*/
public interface ThrownEggHatchEvent extends EntityEvent {
@NullMarked
public class ThrownEggHatchEvent extends Event {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Egg egg;
private boolean hatching;
private byte numHatches;
private EntityType hatchType;
@ApiStatus.Internal
public ThrownEggHatchEvent(final Egg egg, final boolean hatching, final byte numHatches, final EntityType hatchingType) {
this.egg = egg;
this.hatching = hatching;
this.numHatches = numHatches;
this.hatchType = hatchingType;
}
/**
* Gets the egg involved in this event.
*
* @return the egg involved in this event
* @deprecated use {@link #getEntity()}
*/
@Deprecated(forRemoval = true)
default Egg getEgg() {
return this.getEntity();
public Egg getEgg() {
return this.egg;
}
@Override
Egg getEntity();
/**
* Gets whether the egg is hatching or not. Will be what the server
* would've done without interaction.
*
* @return boolean Whether the egg is going to hatch or not
*/
boolean isHatching();
public boolean isHatching() {
return this.hatching;
}
/**
* Sets whether the egg will hatch or not.
@@ -41,7 +56,28 @@ public interface ThrownEggHatchEvent extends EntityEvent {
* @param hatching {@code true} if you want the egg to hatch, {@code false} if you want it
* not to
*/
void setHatching(boolean hatching);
public void setHatching(final boolean hatching) {
this.hatching = hatching;
}
/**
* Get the type of the mob being hatched ({@link EntityType#CHICKEN} by default)
*
* @return The type of the mob being hatched by the egg
*/
public EntityType getHatchingType() {
return this.hatchType;
}
/**
* Change the type of mob being hatched by the egg
*
* @param hatchType The type of the mob being hatched by the egg
*/
public void setHatchingType(final EntityType hatchType) {
Preconditions.checkArgument(hatchType.isSpawnable(), "Can't spawn that entity type from an egg!");
this.hatchType = hatchType;
}
/**
* Get the number of mob hatches from the egg. By default, the number will
@@ -54,7 +90,9 @@ public interface ThrownEggHatchEvent extends EntityEvent {
*
* @return The number of mobs going to be hatched by the egg
*/
@NonNegative byte getNumHatches();
public byte getNumHatches() {
return this.numHatches;
}
/**
* Change the number of mobs coming out of the hatched egg
@@ -64,26 +102,16 @@ public interface ThrownEggHatchEvent extends EntityEvent {
*
* @param numHatches The number of mobs coming out of the egg
*/
void setNumHatches(@NonNegative byte numHatches);
public void setNumHatches(final byte numHatches) {
this.numHatches = numHatches;
}
/**
* Get the type of the mob being hatched ({@link EntityType#CHICKEN} by default)
*
* @return The type of the mob being hatched by the egg
*/
EntityType getHatchingType();
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
/**
* Change the type of mob being hatched by the egg
*
* @param hatchType The type of the mob being hatched by the egg
*/
void setHatchingType(EntityType hatchType);
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -4,11 +4,23 @@ import org.bukkit.entity.Turtle;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired when a Turtle decides to go home
*/
public interface TurtleGoHomeEvent extends EntityEvent, Cancellable {
@NullMarked
public class TurtleGoHomeEvent extends EntityEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private boolean cancelled;
@ApiStatus.Internal
public TurtleGoHomeEvent(final Turtle turtle) {
super(turtle);
}
/**
* The turtle going home
@@ -16,12 +28,26 @@ public interface TurtleGoHomeEvent extends EntityEvent, Cancellable {
* @return The turtle
*/
@Override
Turtle getEntity();
public Turtle getEntity() {
return (Turtle) super.getEntity();
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@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;
}
}
@@ -5,12 +5,28 @@ import org.bukkit.entity.Turtle;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.checkerframework.common.value.qual.IntRange;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired when a Turtle lays eggs
*/
public interface TurtleLayEggEvent extends EntityEvent, Cancellable {
@NullMarked
public class TurtleLayEggEvent extends EntityEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Location location;
private int eggCount;
private boolean cancelled;
@ApiStatus.Internal
public TurtleLayEggEvent(final Turtle turtle, final Location location, final int eggCount) {
super(turtle);
this.location = location;
this.eggCount = eggCount;
}
/**
* The turtle laying the eggs
@@ -18,33 +34,57 @@ public interface TurtleLayEggEvent extends EntityEvent, Cancellable {
* @return The turtle
*/
@Override
Turtle getEntity();
public Turtle getEntity() {
return (Turtle) super.getEntity();
}
/**
* Get the location where the eggs are being laid
*
* @return Location of eggs
*/
Location getLocation();
public Location getLocation() {
return this.location.clone();
}
/**
* Get the number of eggs being laid
*
* @return Number of eggs
*/
@IntRange(from = 1, to = 4) int getEggCount();
public int getEggCount() {
return this.eggCount;
}
/**
* Set the number of eggs being laid
*
* @param eggCount Number of eggs
*/
void setEggCount(@IntRange(from = 0, to = 4) int eggCount);
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
public void setEggCount(final int eggCount) {
if (eggCount < 1) {
this.cancelled = true;
return;
}
return Holder.HANDLER_LIST;
this.eggCount = Math.min(eggCount, 4);
}
@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;
}
}
@@ -5,11 +5,25 @@ import org.bukkit.entity.Turtle;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired when a Turtle starts digging to lay eggs
*/
public interface TurtleStartDiggingEvent extends EntityEvent, Cancellable {
@NullMarked
public class TurtleStartDiggingEvent extends EntityEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Location location;
private boolean cancelled;
@ApiStatus.Internal
public TurtleStartDiggingEvent(final Turtle turtle, final Location location) {
super(turtle);
this.location = location;
}
/**
* The turtle digging
@@ -17,19 +31,35 @@ public interface TurtleStartDiggingEvent extends EntityEvent, Cancellable {
* @return The turtle
*/
@Override
Turtle getEntity();
public Turtle getEntity() {
return (Turtle) super.getEntity();
}
/**
* Get the location where the turtle is digging
*
* @return Location where digging
*/
Location getLocation();
public Location getLocation() {
return this.location.clone();
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@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;
}
}
@@ -5,38 +5,67 @@ import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
* Fired when a witch consumes the potion in their hand to buff themselves.
*/
public interface WitchConsumePotionEvent extends EntityEvent, Cancellable {
@NullMarked
public class WitchConsumePotionEvent extends EntityEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private @Nullable ItemStack potion;
private boolean cancelled;
@ApiStatus.Internal
public WitchConsumePotionEvent(final Witch witch, final @Nullable ItemStack potion) {
super(witch);
this.potion = potion;
}
@Override
Witch getEntity();
public Witch getEntity() {
return (Witch) super.getEntity();
}
/**
* @return the potion the witch will consume and have the effects applied.
*/
@Nullable ItemStack getPotion();
public @Nullable ItemStack getPotion() {
return this.potion;
}
/**
* Sets the potion to be consumed and applied to the witch.
*
* @param potion The potion
*/
void setPotion(@Nullable ItemStack potion);
public void setPotion(final @Nullable ItemStack potion) {
this.potion = potion != null ? potion.clone() : null;
}
/**
* @return Event was cancelled or potion was {@code null}
*/
@Override
boolean isCancelled();
public boolean isCancelled() {
return this.cancelled || this.potion == null;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -5,29 +5,61 @@ import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
public interface WitchReadyPotionEvent extends EntityEvent, Cancellable {
@NullMarked
public class WitchReadyPotionEvent extends EntityEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private @Nullable ItemStack potion;
private boolean cancelled;
@ApiStatus.Internal
public WitchReadyPotionEvent(final Witch witch, final @Nullable ItemStack potion) {
super(witch);
this.potion = potion;
}
@Override
Witch getEntity();
public Witch getEntity() {
return (Witch) super.getEntity();
}
/**
* @return the potion the witch is readying to use
*/
@Nullable ItemStack getPotion();
public @Nullable ItemStack getPotion() {
return this.potion;
}
/**
* Sets the potion the which is going to hold and use
*
* @param potion The potion
*/
void setPotion(@Nullable ItemStack potion);
public void setPotion(final @Nullable ItemStack potion) {
this.potion = potion != null ? potion.clone() : null;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@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;
}
}
@@ -6,43 +6,76 @@ import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
* Fired when a witch throws a potion at a player
*/
public interface WitchThrowPotionEvent extends EntityEvent, Cancellable {
@NullMarked
public class WitchThrowPotionEvent extends EntityEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final LivingEntity target;
private @Nullable ItemStack potion;
private boolean cancelled;
@ApiStatus.Internal
public WitchThrowPotionEvent(final Witch witch, final LivingEntity target, final @Nullable ItemStack potion) {
super(witch);
this.target = target;
this.potion = potion;
}
@Override
Witch getEntity();
public Witch getEntity() {
return (Witch) super.getEntity();
}
/**
* @return The target of the potion
*/
LivingEntity getTarget();
public LivingEntity getTarget() {
return this.target;
}
/**
* @return The potion the witch will throw at a player
*/
@Nullable ItemStack getPotion();
public @Nullable ItemStack getPotion() {
return this.potion;
}
/**
* Sets the potion to be thrown at a player
*
* @param potion The potion
*/
void setPotion(@Nullable ItemStack potion);
public void setPotion(final @Nullable ItemStack potion) {
this.potion = potion != null ? potion.clone() : null;
}
/**
* @return Event was cancelled or potion was {@code null}
*/
@Override
boolean isCancelled();
public boolean isCancelled() {
return this.cancelled || this.potion == null;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,4 +0,0 @@
@NullMarked
package com.destroystokyo.paper.event.entity;
import org.jspecify.annotations.NullMarked;
@@ -2,7 +2,11 @@ package com.destroystokyo.paper.event.inventory;
import org.bukkit.Warning;
import org.bukkit.inventory.GrindstoneInventory;
import org.jspecify.annotations.NullMarked;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Called when an item is put in a slot for grinding in a Grindstone
@@ -11,9 +15,17 @@ import org.jspecify.annotations.NullMarked;
*/
@Deprecated(since = "1.16.1")
@Warning
@NullMarked
public interface PrepareGrindstoneEvent extends PrepareResultEvent {
public class PrepareGrindstoneEvent extends PrepareResultEvent {
@ApiStatus.Internal
public PrepareGrindstoneEvent(@NotNull InventoryView inventory, @Nullable ItemStack result) {
super(inventory, result);
}
@NotNull
@Override
GrindstoneInventory getInventory();
public GrindstoneInventory getInventory() {
return (GrindstoneInventory) super.getInventory();
}
}
@@ -1,9 +1,42 @@
package com.destroystokyo.paper.event.inventory;
import org.bukkit.event.inventory.PrepareInventoryResultEvent;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
* Called when an item is put in an inventory containing a result slot
*/
public interface PrepareResultEvent extends PrepareInventoryResultEvent {
@NullMarked
public class PrepareResultEvent extends PrepareInventoryResultEvent {
// HandlerList on PrepareInventoryResultEvent to ensure api compat
@ApiStatus.Internal
public PrepareResultEvent(final InventoryView inventory, final @Nullable ItemStack result) {
super(inventory, result);
}
/**
* Get result item, may be {@code null}.
*
* @return result item
*/
@Override
public @Nullable ItemStack getResult() {
return super.getResult();
}
/**
* Set result item, may be {@code null}.
*
* @param result result item
*/
@Override
public void setResult(final @Nullable ItemStack result) {
super.setResult(result);
}
}
@@ -1,31 +1,67 @@
package com.destroystokyo.paper.event.player;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jspecify.annotations.Nullable;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @deprecated not called anymore
* @deprecated Not used
*/
@Deprecated(since = "1.16.4", forRemoval = true)
public interface IllegalPacketEvent extends PlayerEvent {
public class IllegalPacketEvent extends PlayerEvent {
boolean isShouldKick();
private static final HandlerList HANDLER_LIST = new HandlerList();
void setShouldKick(boolean shouldKick);
@Nullable private final String type;
@Nullable private final String exceptionMessage;
@Nullable private String kickMessage;
private boolean shouldKick = true;
@Nullable String getKickMessage();
@ApiStatus.Internal
public IllegalPacketEvent(@NotNull Player player, @Nullable String type, @Nullable String kickMessage, @NotNull Exception e) {
super(player);
this.type = type;
this.kickMessage = kickMessage;
this.exceptionMessage = e.getMessage();
}
void setKickMessage(@Nullable String kickMessage);
public boolean isShouldKick() {
return this.shouldKick;
}
@Nullable String getType();
public void setShouldKick(boolean shouldKick) {
this.shouldKick = shouldKick;
}
@Nullable String getExceptionMessage();
@Nullable
public String getKickMessage() {
return this.kickMessage;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
public void setKickMessage(@Nullable String kickMessage) {
this.kickMessage = kickMessage;
}
@Nullable
public String getType() {
return this.type;
}
@Nullable
public String getExceptionMessage() {
return this.exceptionMessage;
}
@NotNull
public HandlerList getHandlers() {
return HANDLER_LIST;
}
@NotNull
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -2,41 +2,79 @@ package com.destroystokyo.paper.event.player;
import org.bukkit.advancement.Advancement;
import org.bukkit.advancement.AdvancementProgress;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called after a player is granted a criteria in an advancement.
* If cancelled the criteria will be revoked.
*/
public interface PlayerAdvancementCriterionGrantEvent extends PlayerEvent, Cancellable {
@NullMarked
public class PlayerAdvancementCriterionGrantEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Advancement advancement;
private final String criterion;
private final AdvancementProgress advancementProgress;
private boolean cancelled;
@ApiStatus.Internal
public PlayerAdvancementCriterionGrantEvent(final Player player, final Advancement advancement, final String criterion) {
super(player);
this.advancement = advancement;
this.criterion = criterion;
this.advancementProgress = player.getAdvancementProgress(advancement);
}
/**
* Get the advancement which has been affected.
*
* @return affected advancement
*/
Advancement getAdvancement();
public Advancement getAdvancement() {
return this.advancement;
}
/**
* Get the criterion which has been granted.
*
* @return granted criterion
*/
String getCriterion();
public String getCriterion() {
return this.criterion;
}
/**
* Gets the current {@link AdvancementProgress}.
* Gets the current AdvancementProgress.
*
* @return advancement progress
*/
AdvancementProgress getAdvancementProgress();
public AdvancementProgress getAdvancementProgress() {
return this.advancementProgress;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@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;
}
}
@@ -2,11 +2,13 @@ package com.destroystokyo.paper.event.player;
import java.util.Set;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
import static org.bukkit.Material.*;
@@ -17,8 +19,23 @@ import static org.bukkit.Material.*;
* Not currently called for environmental factors though it <strong>MAY BE IN THE FUTURE</strong>
* @apiNote Use {@link io.papermc.paper.event.entity.EntityEquipmentChangedEvent} for all entity equipment changes
*/
@NullMarked
@ApiStatus.Obsolete(since = "1.21.4")
public interface PlayerArmorChangeEvent extends PlayerEvent {
public class PlayerArmorChangeEvent extends PlayerEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final SlotType slotType;
private final ItemStack oldItem;
private final ItemStack newItem;
@ApiStatus.Internal
public PlayerArmorChangeEvent(final Player player, final SlotType slotType, final ItemStack oldItem, final ItemStack newItem) {
super(player);
this.slotType = slotType;
this.oldItem = oldItem;
this.newItem = newItem;
}
/**
* Gets the type of slot being altered.
@@ -27,41 +44,56 @@ public interface PlayerArmorChangeEvent extends PlayerEvent {
* @deprecated {@link SlotType} does not accurately represent what item types are valid in each slot. Use {@link #getSlot()} instead.
*/
@Deprecated(since = "1.21.4")
SlotType getSlotType();
public SlotType getSlotType() {
return this.slotType;
}
/**
* Gets the slot being altered.
*
* @return slot being altered
*/
EquipmentSlot getSlot();
public EquipmentSlot getSlot() {
return switch (this.slotType) {
case HEAD -> EquipmentSlot.HEAD;
case CHEST -> EquipmentSlot.CHEST;
case LEGS -> EquipmentSlot.LEGS;
case FEET -> EquipmentSlot.FEET;
};
}
/**
* Gets the existing item that's being replaced
*
* @return old item
*/
ItemStack getOldItem();
public ItemStack getOldItem() {
return this.oldItem;
}
/**
* Gets the new item that's replacing the old
*
* @return new item
*/
ItemStack getNewItem();
public ItemStack getNewItem() {
return this.newItem;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
/**
* @deprecated {@link SlotType} does not accurately represent what item types are valid in each slot.
*/
@Deprecated(since = "1.21.4")
enum SlotType {
public enum SlotType {
HEAD(COPPER_HELMET, NETHERITE_HELMET, DIAMOND_HELMET, GOLDEN_HELMET, IRON_HELMET, CHAINMAIL_HELMET, LEATHER_HELMET, CARVED_PUMPKIN, PLAYER_HEAD, SKELETON_SKULL, ZOMBIE_HEAD, CREEPER_HEAD, WITHER_SKELETON_SKULL, TURTLE_HELMET, DRAGON_HEAD, PIGLIN_HEAD),
CHEST(COPPER_CHESTPLATE, NETHERITE_CHESTPLATE, DIAMOND_CHESTPLATE, GOLDEN_CHESTPLATE, IRON_CHESTPLATE, CHAINMAIL_CHESTPLATE, LEATHER_CHESTPLATE, ELYTRA),
LEGS(COPPER_LEGGINGS, NETHERITE_LEGGINGS, DIAMOND_LEGGINGS, GOLDEN_LEGGINGS, IRON_LEGGINGS, CHAINMAIL_LEGGINGS, LEATHER_LEGGINGS),
@@ -1,9 +1,12 @@
package com.destroystokyo.paper.event.player;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when processing a player's attack on an entity when the player's attack strength cooldown is reset.
@@ -14,22 +17,41 @@ import org.bukkit.event.player.PlayerEvent;
* Additionally, the cancellation of event is misleading as the client will reset the cooldown manually.
* So there is no way for the server to control this.
*/
@NullMarked
@Deprecated(since = "26.1", forRemoval = true)
public interface PlayerAttackEntityCooldownResetEvent extends PlayerEvent, Cancellable {
public class PlayerAttackEntityCooldownResetEvent extends PlayerEvent implements Cancellable {
/**
* Returns the entity attacked by the player
*
* @return the entity attacked by the player
*/
Entity getAttackedEntity();
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Entity attackedEntity;
private final float cooledAttackStrength;
private boolean cancelled;
@ApiStatus.Internal
public PlayerAttackEntityCooldownResetEvent(final Player player, final Entity attackedEntity, final float cooledAttackStrength) {
super(player);
this.attackedEntity = attackedEntity;
this.cooledAttackStrength = cooledAttackStrength;
}
/**
* Get the value of the players cooldown attack strength when they initiated the attack
*
* @return returns the original player cooldown value
*/
float getCooledAttackStrength();
public float getCooledAttackStrength() {
return this.cooledAttackStrength;
}
/**
* Returns the entity attacked by the player
*
* @return the entity attacked by the player
*/
public Entity getAttackedEntity() {
return this.attackedEntity;
}
/**
* {@inheritDoc}
@@ -37,7 +59,9 @@ public interface PlayerAttackEntityCooldownResetEvent extends PlayerEvent, Cance
* If an attack cooldown event is cancelled, the players attack strength will remain at the same value instead of being reset.
*/
@Override
boolean isCancelled();
public boolean isCancelled() {
return this.cancelled;
}
/**
* {@inheritDoc}
@@ -45,12 +69,16 @@ public interface PlayerAttackEntityCooldownResetEvent extends PlayerEvent, Cance
* Cancelling this event will prevent the target player from having their cooldown reset from attacking this entity
*/
@Override
void setCancelled(boolean cancel);
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,57 +1,128 @@
package com.destroystokyo.paper.event.player;
import com.destroystokyo.paper.ClientOption;
import com.destroystokyo.paper.ClientOption.ChatVisibility;
import com.destroystokyo.paper.ClientOption.ParticleVisibility;
import com.destroystokyo.paper.SkinParts;
import java.util.Map;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.inventory.MainHand;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when the player changes their client settings
*/
public interface PlayerClientOptionsChangeEvent extends PlayerEvent {
@NullMarked
public class PlayerClientOptionsChangeEvent extends PlayerEvent {
String getLocale();
private static final HandlerList HANDLER_LIST = new HandlerList();
boolean hasLocaleChanged();
private final String locale;
private final int viewDistance;
private final ChatVisibility chatVisibility;
private final boolean chatColors;
private final SkinParts skinparts;
private final MainHand mainHand;
private final boolean allowsServerListings;
private final boolean textFilteringEnabled;
private final ParticleVisibility particleVisibility;
int getViewDistance();
@ApiStatus.Internal
public PlayerClientOptionsChangeEvent(final Player player, final Map<ClientOption<?>, ?> options) {
super(player);
boolean hasViewDistanceChanged();
this.locale = (String) options.get(ClientOption.LOCALE);
this.viewDistance = (int) options.get(ClientOption.VIEW_DISTANCE);
this.chatVisibility = (ChatVisibility) options.get(ClientOption.CHAT_VISIBILITY);
this.chatColors = (boolean) options.get(ClientOption.CHAT_COLORS_ENABLED);
this.skinparts = (SkinParts) options.get(ClientOption.SKIN_PARTS);
this.mainHand = (MainHand) options.get(ClientOption.MAIN_HAND);
this.allowsServerListings = (boolean) options.get(ClientOption.ALLOW_SERVER_LISTINGS);
this.textFilteringEnabled = (boolean) options.get(ClientOption.TEXT_FILTERING_ENABLED);
this.particleVisibility = (ParticleVisibility) options.get(ClientOption.PARTICLE_VISIBILITY);
}
ChatVisibility getChatVisibility();
public String getLocale() {
return this.locale;
}
boolean hasChatVisibilityChanged();
public boolean hasLocaleChanged() {
return !this.locale.equals(this.player.getClientOption(ClientOption.LOCALE));
}
boolean hasChatColorsEnabled();
public int getViewDistance() {
return this.viewDistance;
}
boolean hasChatColorsEnabledChanged();
public boolean hasViewDistanceChanged() {
return this.viewDistance != this.player.getClientOption(ClientOption.VIEW_DISTANCE);
}
SkinParts getSkinParts();
public ChatVisibility getChatVisibility() {
return this.chatVisibility;
}
boolean hasSkinPartsChanged();
public boolean hasChatVisibilityChanged() {
return this.chatVisibility != this.player.getClientOption(ClientOption.CHAT_VISIBILITY);
}
MainHand getMainHand();
public boolean hasChatColorsEnabled() {
return this.chatColors;
}
boolean hasMainHandChanged();
public boolean hasChatColorsEnabledChanged() {
return this.chatColors != this.player.getClientOption(ClientOption.CHAT_COLORS_ENABLED);
}
boolean hasTextFilteringEnabled();
public SkinParts getSkinParts() {
return this.skinparts;
}
boolean hasTextFilteringChanged();
public boolean hasSkinPartsChanged() {
return this.skinparts.getRaw() != this.player.getClientOption(ClientOption.SKIN_PARTS).getRaw();
}
boolean allowsServerListings();
public MainHand getMainHand() {
return this.mainHand;
}
boolean hasAllowServerListingsChanged();
public boolean hasMainHandChanged() {
return this.mainHand != this.player.getClientOption(ClientOption.MAIN_HAND);
}
ParticleVisibility getParticleVisibility();
public boolean hasTextFilteringEnabled() {
return this.textFilteringEnabled;
}
boolean hasParticleVisibilityChanged();
public boolean hasTextFilteringChanged() {
return this.textFilteringEnabled != this.player.getClientOption(ClientOption.TEXT_FILTERING_ENABLED);
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
public boolean allowsServerListings() {
return this.allowsServerListings;
}
public boolean hasAllowServerListingsChanged() {
return this.allowsServerListings != this.player.getClientOption(ClientOption.ALLOW_SERVER_LISTINGS);
}
public ParticleVisibility getParticleVisibility() {
return this.particleVisibility;
}
public boolean hasParticleVisibilityChanged() {
return this.particleVisibility != this.player.getClientOption(ClientOption.PARTICLE_VISIBILITY);
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,14 +1,16 @@
package com.destroystokyo.paper.event.player;
import io.papermc.paper.event.connection.ConnectionEvent;
import java.net.InetAddress;
import java.util.UUID;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* <p>
* This event is invoked when a player has disconnected. It is guaranteed that,
* if the server is in online-mode, that the provided uuid and username have been
* validated.
@@ -32,27 +34,50 @@ import org.bukkit.event.player.PlayerQuitEvent;
* The event may be invoked asynchronously or synchronously. Plugins should check
* {@link Event#isAsynchronous()} and handle accordingly.
*/
public interface PlayerConnectionCloseEvent extends ConnectionEvent {
@NullMarked
public class PlayerConnectionCloseEvent extends Event {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final UUID playerUniqueId;
private final String playerName;
private final InetAddress ipAddress;
@ApiStatus.Internal
public PlayerConnectionCloseEvent(final UUID playerUniqueId, final String playerName, final InetAddress ipAddress, final boolean async) {
super(async);
this.playerUniqueId = playerUniqueId;
this.playerName = playerName;
this.ipAddress = ipAddress;
}
/**
* Returns the {@link UUID} of the player disconnecting.
* Returns the {@code UUID} of the player disconnecting.
*/
UUID getPlayerUniqueId();
public UUID getPlayerUniqueId() {
return this.playerUniqueId;
}
/**
* Returns the name of the player disconnecting.
*/
String getPlayerName();
public String getPlayerName() {
return this.playerName;
}
/**
* Returns the player's IP address.
*/
InetAddress getIpAddress();
public InetAddress getIpAddress() {
return this.ipAddress;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,56 +1,99 @@
package com.destroystokyo.paper.event.player;
import org.bukkit.entity.Firework;
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.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired when a player boosts elytra flight with a firework
*/
public interface PlayerElytraBoostEvent extends PlayerEvent, Cancellable {
@NullMarked
public class PlayerElytraBoostEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final ItemStack itemStack;
private final Firework firework;
private boolean consume = true;
private final EquipmentSlot hand;
private boolean cancelled;
@ApiStatus.Internal
public PlayerElytraBoostEvent(final Player player, final ItemStack itemStack, final Firework firework, final EquipmentSlot hand) {
super(player);
this.itemStack = itemStack;
this.firework = firework;
this.hand = hand;
}
/**
* Get the firework itemstack used
*
* @return ItemStack of firework
*/
ItemStack getItemStack();
public ItemStack getItemStack() {
return this.itemStack;
}
/**
* Get the firework entity that was spawned
*
* @return Firework entity
*/
Firework getFirework();
public Firework getFirework() {
return this.firework;
}
/**
* Get whether to consume the firework or not
*
* @return {@code true} to consume
*/
boolean shouldConsume();
public boolean shouldConsume() {
return this.consume;
}
/**
* Set whether to consume the firework or not
*
* @param consume {@code true} to consume
*/
void setShouldConsume(boolean consume);
public void setShouldConsume(final boolean consume) {
this.consume = consume;
}
/**
* Gets the hand holding the firework used for boosting this player.
*
* @return interaction hand
*/
EquipmentSlot getHand();
public EquipmentSlot getHand() {
return this.hand;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@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;
}
}
@@ -1,10 +1,15 @@
package com.destroystokyo.paper.event.player;
import com.google.common.base.Preconditions;
import java.util.UUID;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
@@ -15,14 +20,44 @@ import org.jspecify.annotations.Nullable;
*
* <p>WARNING: TAMPERING WITH THIS EVENT CAN BE DANGEROUS</p>
*/
public interface PlayerHandshakeEvent extends Event, Cancellable {
@NullMarked
public class PlayerHandshakeEvent extends Event implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final String originalHandshake;
private final String originalSocketAddressHostname;
private @Nullable String serverHostname;
private @Nullable String socketAddressHostname;
private @Nullable UUID uniqueId;
private @Nullable String propertiesJson;
private boolean failed;
private Component failMessage = Component.text("If you wish to use IP forwarding, please enable it in your BungeeCord config as well!", NamedTextColor.YELLOW);
private boolean cancelled;
@Deprecated
@ApiStatus.Internal
public PlayerHandshakeEvent(final String originalHandshake, final boolean cancelled) {
this(originalHandshake, "127.0.0.1", cancelled);
}
@ApiStatus.Internal
public PlayerHandshakeEvent(final String originalHandshake, final String originalSocketAddressHostname, final boolean cancelled) {
super(true);
this.originalHandshake = originalHandshake;
this.originalSocketAddressHostname = originalSocketAddressHostname;
this.cancelled = cancelled;
}
/**
* Gets the original handshake string.
*
* @return the original handshake string
*/
String getOriginalHandshake();
public String getOriginalHandshake() {
return this.originalHandshake;
}
/**
* Gets the original socket address hostname.
@@ -32,7 +67,9 @@ public interface PlayerHandshakeEvent extends Event, Cancellable {
*
* @return the original socket address hostname
*/
String getOriginalSocketAddressHostname();
public String getOriginalSocketAddressHostname() {
return this.originalSocketAddressHostname;
}
/**
* Gets the server hostname string.
@@ -41,7 +78,9 @@ public interface PlayerHandshakeEvent extends Event, Cancellable {
*
* @return the server hostname string
*/
@Nullable String getServerHostname();
public @Nullable String getServerHostname() {
return this.serverHostname;
}
/**
* Sets the server hostname string.
@@ -50,7 +89,9 @@ public interface PlayerHandshakeEvent extends Event, Cancellable {
*
* @param serverHostname the server hostname string
*/
void setServerHostname(String serverHostname);
public void setServerHostname(final String serverHostname) {
this.serverHostname = serverHostname;
}
/**
* Gets the socket address hostname string.
@@ -59,7 +100,9 @@ public interface PlayerHandshakeEvent extends Event, Cancellable {
*
* @return the socket address hostname string
*/
@Nullable String getSocketAddressHostname();
public @Nullable String getSocketAddressHostname() {
return this.socketAddressHostname;
}
/**
* Sets the socket address hostname string.
@@ -68,21 +111,27 @@ public interface PlayerHandshakeEvent extends Event, Cancellable {
*
* @param socketAddressHostname the socket address hostname string
*/
void setSocketAddressHostname(String socketAddressHostname);
public void setSocketAddressHostname(final String socketAddressHostname) {
this.socketAddressHostname = socketAddressHostname;
}
/**
* Gets the unique id.
*
* @return the unique id
*/
@Nullable UUID getUniqueId();
public @Nullable UUID getUniqueId() {
return this.uniqueId;
}
/**
* Sets the unique id.
*
* @param uniqueId the unique id
*/
void setUniqueId(UUID uniqueId);
public void setUniqueId(final UUID uniqueId) {
this.uniqueId = uniqueId;
}
/**
* Gets the profile properties.
@@ -91,7 +140,9 @@ public interface PlayerHandshakeEvent extends Event, Cancellable {
*
* @return the profile properties, as JSON
*/
@Nullable String getPropertiesJson();
public @Nullable String getPropertiesJson() {
return this.propertiesJson;
}
/**
* Determines if authentication failed.
@@ -101,7 +152,9 @@ public interface PlayerHandshakeEvent extends Event, Cancellable {
*
* @return {@code true} if authentication failed, {@code false} otherwise
*/
boolean isFailed();
public boolean isFailed() {
return this.failed;
}
/**
* Sets if authentication failed and the client should be disconnected.
@@ -111,7 +164,9 @@ public interface PlayerHandshakeEvent extends Event, Cancellable {
*
* @param failed {@code true} if authentication failed, {@code false} otherwise
*/
void setFailed(boolean failed);
public void setFailed(final boolean failed) {
this.failed = failed;
}
/**
* Sets the profile properties.
@@ -120,21 +175,27 @@ public interface PlayerHandshakeEvent extends Event, Cancellable {
*
* @param propertiesJson the profile properties, as JSON
*/
void setPropertiesJson(String propertiesJson);
public void setPropertiesJson(final String propertiesJson) {
this.propertiesJson = propertiesJson;
}
/**
* Gets the message to display to the client when authentication fails.
*
* @return the message to display to the client
*/
Component failMessage();
public Component failMessage() {
return this.failMessage;
}
/**
* Sets the message to display to the client when authentication fails.
*
* @param failMessage the message to display to the client
*/
void failMessage(Component failMessage);
public void failMessage(final Component failMessage) {
this.failMessage = failMessage;
}
/**
* Gets the message to display to the client when authentication fails.
@@ -143,7 +204,9 @@ public interface PlayerHandshakeEvent extends Event, Cancellable {
* @deprecated use {@link #failMessage()}
*/
@Deprecated
String getFailMessage();
public String getFailMessage() {
return LegacyComponentSerializer.legacySection().serialize(this.failMessage());
}
/**
* Sets the message to display to the client when authentication fails.
@@ -152,7 +215,10 @@ public interface PlayerHandshakeEvent extends Event, Cancellable {
* @deprecated use {@link #failMessage(Component)}
*/
@Deprecated
void setFailMessage(String failMessage);
public void setFailMessage(final String failMessage) {
Preconditions.checkArgument(failMessage != null && !failMessage.isEmpty(), "fail message cannot be null or empty");
this.failMessage(LegacyComponentSerializer.legacySection().deserialize(failMessage));
}
/**
* {@inheritDoc}
@@ -161,7 +227,9 @@ public interface PlayerHandshakeEvent extends Event, Cancellable {
* be processed.
*/
@Override
boolean isCancelled();
public boolean isCancelled() {
return this.cancelled;
}
/**
* {@inheritDoc}
@@ -170,12 +238,16 @@ public interface PlayerHandshakeEvent extends Event, Cancellable {
* be processed.
*/
@Override
void setCancelled(boolean cancel);
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,10 +1,14 @@
package com.destroystokyo.paper.event.player;
import com.google.common.base.Preconditions;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when the server detects the player is jumping.
@@ -13,21 +17,66 @@ import org.bukkit.event.player.PlayerMoveEvent;
* when checking for jumps via {@link PlayerMoveEvent}, this event is fired whenever
* the server detects that the player is jumping.
*/
public interface PlayerJumpEvent extends PlayerEvent, Cancellable {
@NullMarked
public class PlayerJumpEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Location to;
private Location from;
private boolean cancelled;
@ApiStatus.Internal
public PlayerJumpEvent(final Player player, final Location from, final Location to) {
super(player);
this.from = from;
this.to = to;
}
/**
* {@inheritDoc}
* <p>
* If this event is cancelled, the player will be moved or
* teleported back to the Location as defined by {@link #getFrom()}. This will not
* fire an event
*/
@Override
public boolean isCancelled() {
return this.cancelled;
}
/**
* {@inheritDoc}
* <p>
* If this event is cancelled, the player will be moved or
* teleported back to the Location as defined by {@link #getFrom()}. This will not
* fire an event
*/
@Override
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
/**
* Gets the location this player jumped from
*
* @return Location the player jumped from
*/
Location getFrom();
public Location getFrom() {
return this.from;
}
/**
* Sets the location to mark as where the player jumped from
*
* @param from New location to mark as the players previous location
*/
void setFrom(Location from);
public void setFrom(final Location from) {
Preconditions.checkArgument(from != null, "Cannot use null from location!");
Preconditions.checkArgument(from.getWorld() != null, "Cannot use from location with null world!");
this.from = from.clone();
}
/**
* Gets the location this player jumped to
@@ -37,32 +86,16 @@ public interface PlayerJumpEvent extends PlayerEvent, Cancellable {
*
* @return Location the player jumped to
*/
Location getTo();
public Location getTo() {
return this.to.clone();
}
/**
* {@inheritDoc}
* <p>
* If this event is cancelled, the player will be moved or
* teleported back to the Location as defined by {@link #getFrom()}. This will not
* fire an event
*/
@Override
boolean isCancelled();
public HandlerList getHandlers() {
return HANDLER_LIST;
}
/**
* {@inheritDoc}
* <p>
* If this event is cancelled, the player will be moved or
* teleported back to the Location as defined by {@link #getFrom()}. This will not
* fire an event
*/
@Override
void setCancelled(boolean cancel);
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,11 +1,14 @@
package com.destroystokyo.paper.event.player;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when a player shoots a projectile.
@@ -14,40 +17,76 @@ import org.bukkit.inventory.ItemStack;
* of a bow or crossbow. A plugin may listen to {@link EntityShootBowEvent}
* for these actions instead.
*/
public interface PlayerLaunchProjectileEvent extends PlayerEvent, Cancellable {
@NullMarked
public class PlayerLaunchProjectileEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Projectile projectile;
private final ItemStack itemStack;
private boolean consumeItem = true;
private boolean cancelled;
@ApiStatus.Internal
public PlayerLaunchProjectileEvent(final Player shooter, final ItemStack itemStack, final Projectile projectile) {
super(shooter);
this.itemStack = itemStack;
this.projectile = projectile;
}
/**
* Gets the projectile which will be launched by this event
*
* @return the launched projectile
*/
Projectile getProjectile();
public Projectile getProjectile() {
return this.projectile;
}
/**
* Get the ItemStack used to fire the projectile
*
* @return The ItemStack used
*/
ItemStack getItemStack();
public ItemStack getItemStack() {
return this.itemStack;
}
/**
* Get whether to consume the ItemStack or not
*
* @return {@code true} to consume
*/
boolean shouldConsume();
public boolean shouldConsume() {
return this.consumeItem;
}
/**
* Set whether to consume the ItemStack or not
*
* @param consumeItem {@code true} to consume
*/
void setShouldConsume(boolean consumeItem);
public void setShouldConsume(final boolean consumeItem) {
this.consumeItem = consumeItem;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@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;
}
}
@@ -24,19 +24,41 @@
package com.destroystokyo.paper.event.player;
import org.bukkit.entity.ExperienceOrb;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired when a player is attempting to pick up an experience orb
*/
public interface PlayerPickupExperienceEvent extends PlayerEvent, Cancellable {
@NullMarked
public class PlayerPickupExperienceEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final ExperienceOrb experienceOrb;
private boolean cancelled;
@ApiStatus.Internal
public PlayerPickupExperienceEvent(final Player player, final ExperienceOrb experienceOrb) {
super(player);
this.experienceOrb = experienceOrb;
}
/**
* @return the experience orb that the player is picking up
* @return Returns the Orb that the player is picking up
*/
ExperienceOrb getExperienceOrb();
public ExperienceOrb getExperienceOrb() {
return this.experienceOrb;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
/**
* {@inheritDoc}
@@ -44,12 +66,16 @@ public interface PlayerPickupExperienceEvent extends PlayerEvent, Cancellable {
* If {@code true}, cancels picking up the experience orb, leaving it in the world
*/
@Override
void setCancelled(boolean cancel);
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -2,13 +2,31 @@ package com.destroystokyo.paper.event.player;
import io.papermc.paper.event.player.AbstractRespawnEvent;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired after a player has respawned
*/
public interface PlayerPostRespawnEvent extends AbstractRespawnEvent {
@NullMarked
public class PlayerPostRespawnEvent extends AbstractRespawnEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
@ApiStatus.Internal
public PlayerPostRespawnEvent(
final Player respawnPlayer,
final Location respawnLocation,
final boolean isBedSpawn,
final boolean isAnchorSpawn,
final boolean missingRespawnBlock,
final PlayerRespawnEvent.RespawnReason respawnReason
) {
super(respawnPlayer, respawnLocation, isBedSpawn, isAnchorSpawn, missingRespawnBlock, respawnReason);
}
/**
* Returns the location of the respawned player.
@@ -16,15 +34,17 @@ public interface PlayerPostRespawnEvent extends AbstractRespawnEvent {
* @return location of the respawned player
* @see #getRespawnLocation()
*/
@ApiStatus.Obsolete(since = "1.21.5")
default Location getRespawnedLocation() {
return this.getRespawnLocation();
@ApiStatus.Obsolete
public Location getRespawnedLocation() {
return super.getRespawnLocation();
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -23,25 +23,45 @@
package com.destroystokyo.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.ItemStack;
import org.jspecify.annotations.NullMarked;
/**
* Called when a player is firing a bow and the server is choosing an arrow to use.
*/
public interface PlayerReadyArrowEvent extends PlayerEvent, Cancellable {
@NullMarked
public class PlayerReadyArrowEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final ItemStack bow;
private final ItemStack arrow;
private boolean cancelled;
public PlayerReadyArrowEvent(final Player player, final ItemStack bow, final ItemStack arrow) {
super(player);
this.bow = bow;
this.arrow = arrow;
}
/**
* @return the player is using to fire the arrow
*/
ItemStack getBow();
public ItemStack getBow() {
return this.bow;
}
/**
* @return the arrow that is attempting to be used
*/
ItemStack getArrow();
public ItemStack getArrow() {
return this.arrow;
}
/**
* {@inheritDoc}
@@ -49,18 +69,24 @@ public interface PlayerReadyArrowEvent extends PlayerEvent, Cancellable {
* Whether use of this arrow is cancelled. On cancel, the server will try the next arrow available and fire another event.
*/
@Override
boolean isCancelled();
public boolean isCancelled() {
return this.cancelled;
}
/**
* Cancel use of this arrow. On cancel, the server will try the next arrow available and fire another event.
*/
@Override
void setCancelled(boolean cancel);
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,28 +1,50 @@
package com.destroystokyo.paper.event.player;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when a player clicks a recipe in the recipe book
*/
public interface PlayerRecipeBookClickEvent extends PlayerEvent, Cancellable {
@NullMarked
public class PlayerRecipeBookClickEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private NamespacedKey recipe;
private boolean makeAll;
private boolean cancelled;
@ApiStatus.Internal
public PlayerRecipeBookClickEvent(final Player player, final NamespacedKey recipe, final boolean makeAll) {
super(player);
this.recipe = recipe;
this.makeAll = makeAll;
}
/**
* Gets the namespaced key of the recipe that was clicked by the player
*
* @return The namespaced key of the recipe
*/
NamespacedKey getRecipe();
public NamespacedKey getRecipe() {
return this.recipe;
}
/**
* Changes what recipe is requested. This sets the requested recipe to the recipe with the given key
*
* @param recipe The key of the recipe that should be requested
*/
void setRecipe(NamespacedKey recipe);
public void setRecipe(final NamespacedKey recipe) {
this.recipe = recipe;
}
/**
* Gets a boolean which indicates whether the player requested to make the maximum amount of results. This is
@@ -30,7 +52,9 @@ public interface PlayerRecipeBookClickEvent extends PlayerEvent, Cancellable {
*
* @return {@code true} if shift is pressed while the recipe is clicked
*/
boolean isMakeAll();
public boolean isMakeAll() {
return this.makeAll;
}
/**
* Sets whether the maximum amount of results should be made. If this is {@code true}, the request is handled as if
@@ -38,12 +62,26 @@ public interface PlayerRecipeBookClickEvent extends PlayerEvent, Cancellable {
*
* @param makeAll {@code true} if the request should attempt to make the maximum amount of results
*/
void setMakeAll(boolean makeAll);
public void setMakeAll(final boolean makeAll) {
this.makeAll = makeAll;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@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;
}
}
@@ -6,6 +6,8 @@ import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
@@ -13,14 +15,37 @@ import org.jspecify.annotations.Nullable;
* <br>
* Cancelling this event will prevent the spawn from being set.
*/
public interface PlayerSetSpawnEvent extends PlayerEvent, Cancellable {
@NullMarked
public class PlayerSetSpawnEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Cause cause;
private @Nullable Location location;
private boolean forced;
private boolean notifyPlayer;
private @Nullable Component notification;
private boolean cancelled;
@ApiStatus.Internal
public PlayerSetSpawnEvent(final Player player, final Cause cause, final @Nullable Location location, final boolean forced, final boolean notifyPlayer, final @Nullable Component notification) {
super(player);
this.cause = cause;
this.location = location;
this.forced = forced;
this.notifyPlayer = notifyPlayer;
this.notification = notification;
}
/**
* Gets the cause of this event.
*
* @return the cause
*/
Cause getCause();
public Cause getCause() {
return this.cause;
}
/**
* Gets the location that the spawn is set to. The yaw
@@ -30,7 +55,9 @@ public interface PlayerSetSpawnEvent extends PlayerEvent, Cancellable {
*
* @return the spawn location, or {@code null} if removing the location
*/
@Nullable Location getLocation();
public @Nullable Location getLocation() {
return this.location;
}
/**
* Sets the location to be set as the spawn location. The yaw
@@ -38,21 +65,27 @@ public interface PlayerSetSpawnEvent extends PlayerEvent, Cancellable {
*
* @param location the spawn location, or {@code null} to remove the spawn location
*/
void setLocation(@Nullable Location location);
public void setLocation(final @Nullable Location location) {
this.location = location != null ? location.clone() : null;
}
/**
* Gets if this is a force spawn location
*
* @return {@code true} if forced
*/
boolean isForced();
public boolean isForced() {
return this.forced;
}
/**
* Sets if this is a forced spawn location
*
* @param forced {@code true} to force
*/
void setForced(boolean forced);
public void setForced(final boolean forced) {
this.forced = forced;
}
/**
* Gets if this action will notify the player their spawn
@@ -60,7 +93,9 @@ public interface PlayerSetSpawnEvent extends PlayerEvent, Cancellable {
*
* @return {@code true} to notify
*/
boolean willNotifyPlayer();
public boolean willNotifyPlayer() {
return this.notifyPlayer;
}
/**
* Sets if this action will notify the player that their spawn
@@ -68,7 +103,9 @@ public interface PlayerSetSpawnEvent extends PlayerEvent, Cancellable {
*
* @param notifyPlayer {@code true} to notify
*/
void setNotifyPlayer(boolean notifyPlayer);
public void setNotifyPlayer(final boolean notifyPlayer) {
this.notifyPlayer = notifyPlayer;
}
/**
* Gets the notification message that will be sent to the player
@@ -76,23 +113,39 @@ public interface PlayerSetSpawnEvent extends PlayerEvent, Cancellable {
*
* @return {@code null} if no notification
*/
@Nullable Component getNotification();
public @Nullable Component getNotification() {
return this.notification;
}
/**
* Sets the notification message that will be sent to the player.
*
* @param notification {@code null} to send no message
*/
void setNotification(@Nullable Component notification);
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
public void setNotification(final @Nullable Component notification) {
this.notification = notification;
}
enum Cause {
@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;
}
public enum Cause {
/**
* When a player interacts successfully with a bed.
*/
@@ -1,34 +1,68 @@
package com.destroystokyo.paper.event.player;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Triggered when a player starts spectating an entity in spectator mode.
*/
public interface PlayerStartSpectatingEntityEvent extends PlayerEvent, Cancellable {
@NullMarked
public class PlayerStartSpectatingEntityEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Entity currentSpectatorTarget;
private final Entity newSpectatorTarget;
private boolean cancelled;
@ApiStatus.Internal
public PlayerStartSpectatingEntityEvent(final Player player, final Entity currentSpectatorTarget, final Entity newSpectatorTarget) {
super(player);
this.currentSpectatorTarget = currentSpectatorTarget;
this.newSpectatorTarget = newSpectatorTarget;
}
/**
* Gets the entity that the player is currently spectating or themselves if they weren't spectating anything
*
* @return The entity the player is currently spectating (before they start spectating the new target).
*/
Entity getCurrentSpectatorTarget();
public Entity getCurrentSpectatorTarget() {
return this.currentSpectatorTarget;
}
/**
* Gets the new entity that the player will now be spectating
*
* @return The entity the player is now going to be spectating.
*/
Entity getNewSpectatorTarget();
public Entity getNewSpectatorTarget() {
return this.newSpectatorTarget;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@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;
}
}
@@ -1,26 +1,55 @@
package com.destroystokyo.paper.event.player;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Triggered when a player stops spectating an entity in spectator mode.
*/
public interface PlayerStopSpectatingEntityEvent extends PlayerEvent, Cancellable {
@NullMarked
public class PlayerStopSpectatingEntityEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Entity spectatorTarget;
private boolean cancelled;
@ApiStatus.Internal
public PlayerStopSpectatingEntityEvent(final Player player, final Entity spectatorTarget) {
super(player);
this.spectatorTarget = spectatorTarget;
}
/**
* Gets the entity that the player is spectating
*
* @return The entity the player is currently spectating (before they will stop).
*/
Entity getSpectatorTarget();
public Entity getSpectatorTarget() {
return this.spectatorTarget;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@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;
}
}
@@ -1,17 +1,32 @@
package com.destroystokyo.paper.event.player;
import org.bukkit.Location;
import org.bukkit.block.EndGateway;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired when a teleport is triggered for an End Gateway
*/
public interface PlayerTeleportEndGatewayEvent extends PlayerTeleportEvent {
@NullMarked
public class PlayerTeleportEndGatewayEvent extends PlayerTeleportEvent {
private final EndGateway gateway;
@ApiStatus.Internal
public PlayerTeleportEndGatewayEvent(final Player player, final Location from, final Location to, final EndGateway gateway) {
super(player, from, to, PlayerTeleportEvent.TeleportCause.END_GATEWAY);
this.gateway = gateway;
}
/**
* The gateway triggering the teleport
*
* @return EndGateway used
*/
EndGateway getGateway();
public EndGateway getGateway() {
return this.gateway;
}
}
@@ -1,10 +1,13 @@
package com.destroystokyo.paper.event.player;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
@@ -14,28 +17,51 @@ import org.jspecify.annotations.Nullable;
* This event may be called multiple times per interaction with different interaction hands
* and with or without the clicked position.
*/
public interface PlayerUseUnknownEntityEvent extends PlayerEvent {
@NullMarked
public class PlayerUseUnknownEntityEvent extends PlayerEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final int entityId;
private final boolean attack;
private final EquipmentSlot hand;
private final @Nullable Vector clickedPosition;
@ApiStatus.Internal
public PlayerUseUnknownEntityEvent(final Player player, final int entityId, final boolean attack, final EquipmentSlot hand, final @Nullable Vector clickedPosition) {
super(player);
this.entityId = entityId;
this.attack = attack;
this.hand = hand;
this.clickedPosition = clickedPosition;
}
/**
* Returns the entity id of the unknown entity that was interacted with.
*
* @return the entity id of the entity that was interacted with
*/
int getEntityId();
public int getEntityId() {
return this.entityId;
}
/**
* Returns whether the interaction was an attack.
*
* @return {@code true} if the player is attacking the entity, {@code false} if the player is interacting with the entity
*/
boolean isAttack();
public boolean isAttack() {
return this.attack;
}
/**
* Returns the hand used to perform this interaction.
*
* @return the hand used to interact
*/
EquipmentSlot getHand();
public EquipmentSlot getHand() {
return this.hand;
}
/**
* Returns the position relative to the entity that was clicked, or {@code null} if not available.
@@ -44,12 +70,16 @@ public interface PlayerUseUnknownEntityEvent extends PlayerEvent {
* @return the position relative to the entity that was clicked, or {@code null} if not available
* @see PlayerInteractAtEntityEvent
*/
@Nullable Vector getClickedRelativePosition();
public @Nullable Vector getClickedRelativePosition() {
return this.clickedPosition != null ? this.clickedPosition.clone() : null;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,4 +0,0 @@
@NullMarked
package com.destroystokyo.paper.event.player;
import org.jspecify.annotations.NullMarked;
@@ -28,16 +28,31 @@ import com.destroystokyo.paper.profile.ProfileProperty;
import java.util.Set;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired once a profiles additional properties (such as textures) has been filled
*/
public interface FillProfileEvent extends Event {
@NullMarked
public class FillProfileEvent extends Event {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final PlayerProfile profile;
@ApiStatus.Internal
public FillProfileEvent(final PlayerProfile profile) {
super(!org.bukkit.Bukkit.isPrimaryThread());
this.profile = profile;
}
/**
* @return The Profile that had properties filled
*/
PlayerProfile getPlayerProfile();
public PlayerProfile getPlayerProfile() {
return this.profile;
}
/**
* Same as .getPlayerProfile().getProperties()
@@ -45,12 +60,16 @@ public interface FillProfileEvent extends Event {
* @return The new properties on the profile.
* @see PlayerProfile#getProperties()
*/
Set<ProfileProperty> getProperties();
public Set<ProfileProperty> getProperties() {
return this.profile.getProperties();
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,9 +1,13 @@
package com.destroystokyo.paper.event.profile;
import com.destroystokyo.paper.profile.PlayerProfile;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import java.util.Objects;
import java.util.UUID;
/**
* Allows a plugin to be notified anytime AFTER a Profile has been looked up from the Mojang API
@@ -12,33 +16,52 @@ import org.bukkit.event.HandlerList;
* No guarantees are made about thread execution context for this event. If you need to know, check
* {@link Event#isAsynchronous()}
*/
public interface LookupProfileEvent extends Event {
@NullMarked
public class LookupProfileEvent extends Event {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final PlayerProfile profile;
@ApiStatus.Internal
public LookupProfileEvent(final PlayerProfile profile) {
super(!Bukkit.isPrimaryThread());
this.profile = profile;
}
/**
* Gets the name of the profile that was looked up.
*
* @return the name of the profile
*/
String getName();
public String getName() {
return Objects.requireNonNull(this.profile.getName(), "profile name");
}
/**
* Gets the UUID of the profile that was looked up.
*
* @return the UUID of the profile
*/
UUID getId();
public UUID getId() {
return Objects.requireNonNull(this.profile.getId(), "profile id");
}
/**
* @return The profile that was recently looked up. This profile can be mutated
* @deprecated This event is only called after UUID lookups, properties set here will be ignored. Use {@link FillProfileEvent} for setting properties.
*/
@Deprecated(forRemoval = true, since = "1.21.9")
PlayerProfile getPlayerProfile();
public PlayerProfile getPlayerProfile() {
return this.profile;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -28,18 +28,33 @@ import com.destroystokyo.paper.profile.ProfileProperty;
import java.util.Collection;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Fired when the server is requesting to fill in properties of an incomplete profile, such as textures.
* <p>
* Allows plugins to pre-populate cached properties and avoid a call to the Mojang API
*/
public interface PreFillProfileEvent extends Event {
@NullMarked
public class PreFillProfileEvent extends Event {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final PlayerProfile profile;
@ApiStatus.Internal
public PreFillProfileEvent(final PlayerProfile profile) {
super(!org.bukkit.Bukkit.isPrimaryThread());
this.profile = profile;
}
/**
* @return The profile that needs its properties filled
*/
PlayerProfile getPlayerProfile();
public PlayerProfile getPlayerProfile() {
return this.profile;
}
/**
* Sets the properties on the profile, avoiding the call to the Mojang API
@@ -48,12 +63,16 @@ public interface PreFillProfileEvent extends Event {
* @param properties The properties to set/append
* @see PlayerProfile#setProperties(Collection)
*/
void setProperties(Collection<ProfileProperty> properties);
public void setProperties(final Collection<ProfileProperty> properties) {
this.profile.setProperties(properties);
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,10 +1,14 @@
package com.destroystokyo.paper.event.profile;
import com.destroystokyo.paper.profile.ProfileProperty;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
@@ -17,12 +21,28 @@ import org.jspecify.annotations.Nullable;
* No guarantees are made about thread execution context for this event. If you need to know, check
* {@link Event#isAsynchronous()}
*/
public interface PreLookupProfileEvent extends Event {
@NullMarked
public class PreLookupProfileEvent extends Event {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final String name;
private @Nullable UUID uuid;
private Set<ProfileProperty> properties = new HashSet<>();
@ApiStatus.Internal
public PreLookupProfileEvent(final String name) {
super(!Bukkit.isPrimaryThread());
this.name = name;
}
/**
* @return Name of the profile
*/
String getName();
public String getName() {
return this.name;
}
/**
* If this value is left {@code null} by the completion of the event call, then the server will
@@ -31,7 +51,9 @@ public interface PreLookupProfileEvent extends Event {
*
* @return The UUID of the profile if it has already been provided by a plugin
*/
@Nullable UUID getUUID();
public @Nullable UUID getUUID() {
return this.uuid;
}
/**
* Sets the UUID for this player name. This will skip the initial API call to find the players UUID.
@@ -40,7 +62,9 @@ public interface PreLookupProfileEvent extends Event {
*
* @param uuid the UUID to set for the profile or {@code null} to reset
*/
void setUUID(@Nullable UUID uuid);
public void setUUID(final @Nullable UUID uuid) {
this.uuid = uuid;
}
/**
* @return The currently pending pre-populated properties.
@@ -48,7 +72,9 @@ public interface PreLookupProfileEvent extends Event {
* @deprecated This event is only called for UUID lookups, properties set here will be ignored. Use {@link PreFillProfileEvent} for setting properties.
*/
@Deprecated(forRemoval = true, since = "1.21.9")
Set<ProfileProperty> getProfileProperties();
public Set<ProfileProperty> getProfileProperties() {
return this.properties;
}
/**
* Clears any existing pre-populated properties and uses the supplied properties
@@ -58,7 +84,10 @@ public interface PreLookupProfileEvent extends Event {
* @deprecated This event is only called for UUID lookups, properties set here will be ignored. Use {@link PreFillProfileEvent} for setting properties.
*/
@Deprecated(forRemoval = true, since = "1.21.9")
void setProfileProperties(Set<ProfileProperty> properties);
public void setProfileProperties(final Set<ProfileProperty> properties) {
this.properties = new HashSet<>();
this.properties.addAll(properties);
}
/**
* Adds any properties currently missing to the pre-populated properties set, replacing any that already were set. Use {@link PreFillProfileEvent} for setting properties.
@@ -68,12 +97,17 @@ public interface PreLookupProfileEvent extends Event {
* @deprecated This event is only called for UUID lookups, properties set here will be ignored.
*/
@Deprecated(forRemoval = true, since = "1.21.9")
void addProfileProperties(Set<ProfileProperty> properties);
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
public void addProfileProperties(final Set<ProfileProperty> properties) {
this.properties.addAll(properties);
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -25,9 +25,12 @@ package com.destroystokyo.paper.event.profile;
import com.destroystokyo.paper.profile.PlayerProfile;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
@@ -36,64 +39,102 @@ import org.jspecify.annotations.Nullable;
* Plugins may override/control the servers whitelist with this event,
* and dynamically change the kick message.
*/
public interface ProfileWhitelistVerifyEvent extends Event {
@NullMarked
public class ProfileWhitelistVerifyEvent extends Event {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final PlayerProfile profile;
private final boolean whitelistEnabled;
private final boolean isOp;
private boolean whitelisted;
private @Nullable Component kickMessage;
@ApiStatus.Internal
public ProfileWhitelistVerifyEvent(final PlayerProfile profile, final boolean whitelistEnabled, final boolean whitelisted, final boolean isOp, final @Nullable Component kickMessage) {
this.profile = profile;
this.whitelistEnabled = whitelistEnabled;
this.whitelisted = whitelisted;
this.isOp = isOp;
this.kickMessage = kickMessage;
}
/**
* @return the currently planned message to send to the user if they are not whitelisted
* @deprecated use {@link #kickMessage()}
*/
@Deprecated
@Nullable String getKickMessage();
public @Nullable String getKickMessage() {
return this.kickMessage == null ? null : LegacyComponentSerializer.legacySection().serialize(this.kickMessage);
}
/**
* @param kickMessage The message to send to the player on kick if not whitelisted. May set to {@code null} to use the server configured default
* @deprecated Use {@link #kickMessage(Component)}
*/
@Deprecated
void setKickMessage(@Nullable String kickMessage);
public void setKickMessage(final @Nullable String kickMessage) {
this.kickMessage(kickMessage == null ? null : LegacyComponentSerializer.legacySection().deserialize(kickMessage));
}
/**
* @return the currently planned message to send to the user if they are not whitelisted
*/
@Contract(pure = true)
@Nullable Component kickMessage();
public @Nullable Component kickMessage() {
return this.kickMessage;
}
/**
* @param kickMessage The message to send to the player on kick if not whitelisted. May set to {@code null} to use the server configured default
*/
void kickMessage(@Nullable Component kickMessage);
public void kickMessage(final @Nullable Component kickMessage) {
this.kickMessage = kickMessage;
}
/**
* @return The profile of the player trying to connect
*/
PlayerProfile getPlayerProfile();
public PlayerProfile getPlayerProfile() {
return this.profile;
}
/**
* @return Whether the player is whitelisted to play on this server (whitelist may be off is why it's true)
*/
boolean isWhitelisted();
public boolean isWhitelisted() {
return this.whitelisted;
}
/**
* Changes the players whitelisted state. {@code false} will deny the login
*
* @param whitelisted The new whitelisted state
*/
void setWhitelisted(boolean whitelisted);
public void setWhitelisted(final boolean whitelisted) {
this.whitelisted = whitelisted;
}
/**
* @return if the player obtained whitelist status by having op
*/
boolean isOp();
public boolean isOp() {
return this.isOp;
}
/**
* @return if the server even has whitelist on
*/
boolean isWhitelistEnabled();
public boolean isWhitelistEnabled() {
return this.whitelistEnabled;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,4 +0,0 @@
@NullMarked
package com.destroystokyo.paper.event.profile;
import org.jspecify.annotations.NullMarked;
@@ -24,7 +24,10 @@
package com.destroystokyo.paper.event.server;
import com.google.common.base.Preconditions;
import io.papermc.paper.util.TransformingRandomAccessList;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import net.kyori.adventure.text.Component;
import org.bukkit.Location;
import org.bukkit.command.Command;
@@ -32,6 +35,8 @@ import org.bukkit.command.CommandSender;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
@@ -43,14 +48,52 @@ import org.jspecify.annotations.Nullable;
* <p>
* Only 1 process will be allowed to provide completions, the Async Event, or the standard process.
*/
public interface AsyncTabCompleteEvent extends Event, Cancellable {
@NullMarked
public class AsyncTabCompleteEvent extends Event implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final CommandSender sender;
private final String buffer;
private final boolean isCommand;
private final @Nullable Location location;
private final List<Completion> completions = new ArrayList<>();
private final List<String> stringCompletions = new TransformingRandomAccessList<>(
this.completions,
Completion::suggestion,
Completion::completion
);
private boolean handled;
private boolean cancelled;
@ApiStatus.Internal
public AsyncTabCompleteEvent(final CommandSender sender, final String buffer, final boolean isCommand, final @Nullable Location loc) {
super(true);
this.sender = sender;
this.buffer = buffer;
this.isCommand = isCommand;
this.location = loc;
}
@Deprecated
@ApiStatus.Internal
public AsyncTabCompleteEvent(final CommandSender sender, final List<String> completions, final String buffer, final boolean isCommand, final @Nullable Location loc) {
super(true);
this.sender = sender;
this.completions.addAll(fromStrings(completions));
this.buffer = buffer;
this.isCommand = isCommand;
this.location = loc;
}
/**
* Get the sender completing this command.
*
* @return the {@link CommandSender} instance
*/
CommandSender getSender();
public CommandSender getSender() {
return this.sender;
}
/**
* The list of completions which will be offered to the sender, in order.
@@ -62,7 +105,9 @@ public interface AsyncTabCompleteEvent extends Event, Cancellable {
*
* @return a list of offered completions
*/
List<String> getCompletions();
public List<String> getCompletions() {
return this.stringCompletions;
}
/**
* Set the completions offered, overriding any already set.
@@ -74,7 +119,14 @@ public interface AsyncTabCompleteEvent extends Event, Cancellable {
*
* @param completions the new completions
*/
void setCompletions(List<String> completions);
public void setCompletions(final List<String> completions) {
Preconditions.checkArgument(completions != null, "Completions list cannot be null");
if (completions == this.stringCompletions) {
return;
}
this.completions.clear();
this.completions.addAll(fromStrings(completions));
}
/**
* The list of {@link Completion completions} which will be offered to the sender, in order.
@@ -86,7 +138,9 @@ public interface AsyncTabCompleteEvent extends Event, Cancellable {
*
* @return a list of offered completions
*/
List<Completion> completions();
public List<Completion> completions() {
return this.completions;
}
/**
* Set the {@link Completion completions} offered, overriding any already set.
@@ -98,24 +152,34 @@ public interface AsyncTabCompleteEvent extends Event, Cancellable {
*
* @param newCompletions the new completions
*/
void completions(List<Completion> newCompletions);
public void completions(final List<Completion> newCompletions) {
Preconditions.checkArgument(newCompletions != null, "new completions cannot be null");
this.completions.clear();
this.completions.addAll(newCompletions);
}
/**
* Return the entire buffer which formed the basis of this completion.
*
* @return command buffer, as entered
*/
String getBuffer();
public String getBuffer() {
return this.buffer;
}
/**
* @return {@code true} if it is a command being tab completed, {@code false} if it is a chat message.
*/
boolean isCommand();
public boolean isCommand() {
return this.isCommand;
}
/**
* @return The position looked at by the sender, or {@code null} if none
*/
@Nullable Location getLocation();
public @Nullable Location getLocation() {
return this.location != null ? this.location.clone() : null;
}
/**
* If {@code true}, the standard process of calling {@link Command#tabComplete(CommandSender, String, String[])}
@@ -123,7 +187,9 @@ public interface AsyncTabCompleteEvent extends Event, Cancellable {
*
* @return Is completions considered handled. Always {@code true} if completions is not empty.
*/
boolean isHandled();
public boolean isHandled() {
return !this.completions.isEmpty() || this.handled;
}
/**
* Sets whether to consider the completion request handled.
@@ -132,7 +198,14 @@ public interface AsyncTabCompleteEvent extends Event, Cancellable {
*
* @param handled if this completion should be marked as being handled
*/
void setHandled(boolean handled);
public void setHandled(final boolean handled) {
this.handled = handled;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
/**
* {@inheritDoc}
@@ -140,19 +213,31 @@ public interface AsyncTabCompleteEvent extends Event, Cancellable {
* Will provide no completions, and will not fire the synchronous process
*/
@Override
void setCancelled(boolean cancel);
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
private static List<Completion> fromStrings(final List<String> suggestions) {
final List<Completion> list = new ArrayList<>(suggestions.size());
for (final String suggestion : suggestions) {
list.add(new CompletionImpl(suggestion, null));
}
return Holder.HANDLER_LIST;
return list;
}
/**
* A rich tab completion, consisting of a string suggestion, and a nullable {@link Component} tooltip.
*/
interface Completion {
public interface Completion {
/**
* Get the suggestion string for this {@link Completion}.
@@ -175,7 +260,7 @@ public interface AsyncTabCompleteEvent extends Event, Cancellable {
* @return new completion instance
*/
static Completion completion(final String suggestion) {
return completion(suggestion, null);
return new CompletionImpl(suggestion, null);
}
/**
@@ -188,11 +273,14 @@ public interface AsyncTabCompleteEvent extends Event, Cancellable {
* @return new completion instance
*/
static Completion completion(final String suggestion, final @Nullable Component tooltip) {
Preconditions.checkArgument(suggestion != null, "suggestion cannot be null");
record CompletionImpl(String suggestion, @Nullable Component tooltip) implements Completion {
}
return new CompletionImpl(suggestion, tooltip);
}
}
@ApiStatus.Internal
record CompletionImpl(String suggestion, @Nullable Component tooltip) implements Completion {
CompletionImpl {
Objects.requireNonNull(suggestion, "suggestion");
}
}
}
@@ -10,7 +10,9 @@ import java.util.List;
import org.bukkit.Server;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jspecify.annotations.Nullable;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* This event is fired if server is getting queried over GS4 Query protocol.
@@ -19,47 +21,72 @@ import org.jspecify.annotations.Nullable;
*
* @author Mark Vainomaa
*/
public interface GS4QueryEvent extends Event {
@NullMarked
public final class GS4QueryEvent extends Event {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final QueryType queryType;
private final InetAddress querierAddress;
private QueryResponse response;
@ApiStatus.Internal
public GS4QueryEvent(final QueryType queryType, final InetAddress querierAddress, final QueryResponse response) {
super(true); // should always be called async
this.queryType = queryType;
this.querierAddress = querierAddress;
this.response = response;
}
/**
* Get query type
*
* @return query type
*/
QueryType getQueryType();
public QueryType getQueryType() {
return this.queryType;
}
/**
* Get querier address
*
* @return querier address
*/
InetAddress getQuerierAddress();
public InetAddress getQuerierAddress() {
return this.querierAddress;
}
/**
* Get query response
*
* @return query response
*/
QueryResponse getResponse();
public QueryResponse getResponse() {
return this.response;
}
/**
* Set query response
*
* @param response query response
*/
void setResponse(QueryResponse response);
public void setResponse(final QueryResponse response) {
this.response = Preconditions.checkNotNull(response, "response");
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
/**
* The type of query
*/
enum QueryType {
public enum QueryType {
/**
* Basic query asks only a subset of information, such as motd, game type (hardcoded to <pre>MINECRAFT</pre>), map,
* current players, max players, server port and server motd
@@ -72,7 +99,7 @@ public interface GS4QueryEvent extends Event {
FULL
}
final class QueryResponse {
public static final class QueryResponse {
private final String motd;
private final String gameVersion;
@@ -85,18 +112,7 @@ public interface GS4QueryEvent extends Event {
private final String serverVersion;
private final Collection<PluginInformation> plugins;
private QueryResponse(
final String motd,
final String gameVersion,
final String map,
final int currentPlayers,
final int maxPlayers,
final String hostname,
final int port,
final Collection<String> players,
final String serverVersion,
final Collection<PluginInformation> plugins
) {
private QueryResponse(final String motd, final String gameVersion, final String map, final int currentPlayers, final int maxPlayers, final String hostname, final int port, final Collection<String> players, final String serverVersion, final Collection<PluginInformation> plugins) {
this.motd = motd;
this.gameVersion = gameVersion;
this.map = map;
@@ -232,11 +248,11 @@ public interface GS4QueryEvent extends Event {
*/
public static final class Builder {
private @Nullable String motd;
private @Nullable String gameVersion;
private @Nullable String map;
private @Nullable String hostname;
private @Nullable String serverVersion;
private @MonotonicNonNull String motd;
private @MonotonicNonNull String gameVersion;
private @MonotonicNonNull String map;
private @MonotonicNonNull String hostname;
private @MonotonicNonNull String serverVersion;
private int currentPlayers;
private int maxPlayers;
@@ -249,20 +265,17 @@ public interface GS4QueryEvent extends Event {
}
public Builder motd(final String motd) {
Preconditions.checkArgument(motd != null, "motd cannot be null");
this.motd = motd;
this.motd = Preconditions.checkNotNull(motd, "motd");
return this;
}
public Builder gameVersion(final String gameVersion) {
Preconditions.checkArgument(gameVersion != null, "gameVersion cannot be null");
this.gameVersion = gameVersion;
this.gameVersion = Preconditions.checkNotNull(gameVersion, "gameVersion");
return this;
}
public Builder map(final String map) {
Preconditions.checkArgument(map != null, "map cannot be null");
this.map = map;
this.map = Preconditions.checkNotNull(map, "map");
return this;
}
@@ -279,8 +292,7 @@ public interface GS4QueryEvent extends Event {
}
public Builder hostname(final String hostname) {
Preconditions.checkArgument(hostname != null, "hostname cannot be null");
this.hostname = hostname;
this.hostname = Preconditions.checkNotNull(hostname, "hostname");
return this;
}
@@ -291,14 +303,12 @@ public interface GS4QueryEvent extends Event {
}
public Builder players(final Collection<String> players) {
Preconditions.checkArgument(players != null, "players cannot be null");
this.players.addAll(players);
this.players.addAll(Preconditions.checkNotNull(players, "players"));
return this;
}
public Builder players(final String... players) {
Preconditions.checkArgument(players != null, "players cannot be null");
this.players.addAll(Arrays.asList(players));
this.players.addAll(Arrays.asList(Preconditions.checkNotNull(players, "players")));
return this;
}
@@ -308,20 +318,17 @@ public interface GS4QueryEvent extends Event {
}
public Builder serverVersion(final String serverVersion) {
Preconditions.checkArgument(serverVersion != null, "serverVersion cannot be null");
this.serverVersion = serverVersion;
this.serverVersion = Preconditions.checkNotNull(serverVersion, "serverVersion");
return this;
}
public Builder plugins(final Collection<PluginInformation> plugins) {
Preconditions.checkArgument(plugins != null, "plugins cannot be null");
this.plugins.addAll(plugins);
this.plugins.addAll(Preconditions.checkNotNull(plugins, "plugins"));
return this;
}
public Builder plugins(final PluginInformation... plugins) {
Preconditions.checkArgument(plugins != null, "plugins cannot be null");
this.plugins.addAll(Arrays.asList(plugins));
this.plugins.addAll(Arrays.asList(Preconditions.checkNotNull(plugins, "plugins")));
return this;
}
@@ -336,21 +343,16 @@ public interface GS4QueryEvent extends Event {
* @return response
*/
public QueryResponse build() {
Preconditions.checkState(this.motd != null, "motd is required");
Preconditions.checkState(this.gameVersion != null, "gameVersion is required");
Preconditions.checkState(this.map != null, "map is required");
Preconditions.checkState(this.hostname != null, "hostname is required");
Preconditions.checkState(this.serverVersion != null, "serverVersion is required");
return new QueryResponse(
this.motd,
this.gameVersion,
this.map,
Preconditions.checkNotNull(this.motd, "motd"),
Preconditions.checkNotNull(this.gameVersion, "gameVersion"),
Preconditions.checkNotNull(this.map, "map"),
this.currentPlayers,
this.maxPlayers,
this.hostname,
Preconditions.checkNotNull(this.hostname, "hostname"),
this.port,
ImmutableList.copyOf(this.players),
this.serverVersion,
Preconditions.checkNotNull(this.serverVersion, "serverVersion"),
ImmutableList.copyOf(this.plugins)
);
}
@@ -359,66 +361,34 @@ public interface GS4QueryEvent extends Event {
/**
* Plugin information
*/
public interface PluginInformation {
public static class PluginInformation {
String name();
private String name;
private String version;
String version();
PluginInformation withName(String name);
PluginInformation withVersion(String version);
/**
* @deprecated use {@link #name()}
*/
@Deprecated(forRemoval = true)
default String getName() {
return this.name();
public PluginInformation(final String name, final String version) {
this.name = Preconditions.checkNotNull(name, "name");
this.version = Preconditions.checkNotNull(version, "version");
}
/**
* @deprecated use {@link #withName(String)}
*/
@Deprecated(forRemoval = true)
default void setName(String name) {
this.withName(name); // no op
public String getName() {
return this.name;
}
/**
* @deprecated use {@link #version()}
*/
@Deprecated(forRemoval = true)
default String getVersion() {
return this.version();
public void setName(final String name) {
this.name = name;
}
/**
* @deprecated use {@link #withVersion(String)}
*/
@Deprecated(forRemoval = true)
default void setVersion(String version) {
this.withVersion(version); // no op
public void setVersion(final String version) {
this.version = version;
}
static PluginInformation of(final String name, final String version) {
record PluginInformationImpl(String name, String version) implements PluginInformation {
PluginInformationImpl {
Preconditions.checkArgument(name != null, "name cannot be null");
Preconditions.checkArgument(version != null, "version cannot be null");
}
public String getVersion() {
return this.version;
}
@Override
public PluginInformation withName(final String name) {
return new PluginInformationImpl(name, this.version);
}
@Override
public PluginInformation withVersion(final String version) {
return new PluginInformationImpl(this.name, version);
}
}
return new PluginInformationImpl(name, version);
public static PluginInformation of(final String name, final String version) {
return new PluginInformation(name, version);
}
}
}
@@ -1,28 +1,80 @@
package com.destroystokyo.paper.event.server;
import static java.util.Objects.requireNonNull;
import com.destroystokyo.paper.network.StatusClient;
import com.destroystokyo.paper.profile.PlayerProfile;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import com.destroystokyo.paper.profile.ProfileProperty;
import com.google.common.base.Preconditions;
import io.papermc.paper.util.TransformingRandomAccessList;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.server.ServerListPingEvent;
import org.bukkit.profile.PlayerTextures;
import org.bukkit.util.CachedServerIcon;
import org.jspecify.annotations.Nullable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.UUID;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Extended version of {@link ServerListPingEvent} that allows full control
* of the response sent to the client.
*/
public interface PaperServerListPingEvent extends ServerListPingEvent, Cancellable {
public class PaperServerListPingEvent extends ServerListPingEvent implements Cancellable {
@NotNull private final StatusClient client;
private int numPlayers;
private boolean hidePlayers;
@NotNull private final List<ListedPlayerInfo> listedPlayers = new ArrayList<>();
@NotNull private final TransformingRandomAccessList<ListedPlayerInfo, PlayerProfile> playerSample = new TransformingRandomAccessList<>(
listedPlayers,
info -> new UncheckedPlayerProfile(info.name(), info.id()),
profile -> new ListedPlayerInfo(profile.getName(), profile.getId())
);
@NotNull private String version;
private int protocolVersion;
@Nullable private CachedServerIcon favicon;
private boolean cancelled;
private boolean originalPlayerCount = true;
private Object[] players;
@ApiStatus.Internal
public PaperServerListPingEvent(@NotNull StatusClient client, @NotNull net.kyori.adventure.text.Component motd, int numPlayers, int maxPlayers,
@NotNull String version, int protocolVersion, @Nullable CachedServerIcon favicon) {
super("", client.getAddress().getAddress(), motd, numPlayers, maxPlayers);
this.client = client;
this.numPlayers = numPlayers;
this.version = version;
this.protocolVersion = protocolVersion;
setServerIcon(favicon);
}
/**
* Returns the {@link StatusClient} pinging the server.
*
* @return The client
*/
StatusClient getClient();
@NotNull
public StatusClient getClient() {
return this.client;
}
/**
* {@inheritDoc}
@@ -31,7 +83,13 @@ public interface PaperServerListPingEvent extends ServerListPingEvent, Cancellab
* {@link #shouldHidePlayers()}.</p>
*/
@Override
int getNumPlayers();
public int getNumPlayers() {
if (this.hidePlayers) {
return -1;
}
return this.numPlayers;
}
/**
* Sets the number of players displayed in the server list.
@@ -41,7 +99,12 @@ public interface PaperServerListPingEvent extends ServerListPingEvent, Cancellab
*
* @param numPlayers The number of online players
*/
void setNumPlayers(int numPlayers);
public void setNumPlayers(int numPlayers) {
if (this.numPlayers != numPlayers) {
this.numPlayers = numPlayers;
this.originalPlayerCount = false;
}
}
/**
* {@inheritDoc}
@@ -50,7 +113,13 @@ public interface PaperServerListPingEvent extends ServerListPingEvent, Cancellab
* {@link #shouldHidePlayers()}.
*/
@Override
int getMaxPlayers();
public int getMaxPlayers() {
if (this.hidePlayers) {
return -1;
}
return super.getMaxPlayers();
}
/**
* Returns whether all player related information is hidden in the server
@@ -62,7 +131,9 @@ public interface PaperServerListPingEvent extends ServerListPingEvent, Cancellab
*
* @return {@code true} if the player count is hidden
*/
boolean shouldHidePlayers();
public boolean shouldHidePlayers() {
return this.hidePlayers;
}
/**
* Sets whether all player related information is hidden in the server
@@ -74,7 +145,9 @@ public interface PaperServerListPingEvent extends ServerListPingEvent, Cancellab
*
* @param hidePlayers {@code true} if the player count should be hidden
*/
void setHidePlayers(boolean hidePlayers);
public void setHidePlayers(boolean hidePlayers) {
this.hidePlayers = hidePlayers;
}
/**
* Returns a mutable list of {@link ListedPlayerInfo} that will be displayed
@@ -85,7 +158,10 @@ public interface PaperServerListPingEvent extends ServerListPingEvent, Cancellab
*
* @return The mutable player sample list
*/
List<ListedPlayerInfo> getListedPlayers();
@NotNull
public List<ListedPlayerInfo> getListedPlayers() {
return this.listedPlayers;
}
/**
* Returns a mutable list of {@link PlayerProfile} that will be displayed
@@ -97,22 +173,30 @@ public interface PaperServerListPingEvent extends ServerListPingEvent, Cancellab
* @return The mutable player sample list
* @deprecated Use {@link #getListedPlayers()}, as this does not contain real player profiles
*/
@NotNull
@Deprecated(forRemoval = true, since = "1.20.6")
List<PlayerProfile> getPlayerSample();
public List<PlayerProfile> getPlayerSample() {
return this.playerSample;
}
/**
* Returns the version that will be sent as server version on the client.
*
* @return The server version
*/
String getVersion();
@NotNull
public String getVersion() {
return this.version;
}
/**
* Sets the version that will be sent as server version to the client.
*
* @param version The server version
*/
void setVersion(String version);
public void setVersion(@NotNull String version) {
this.version = requireNonNull(version, "version");
}
/**
* Returns the protocol version that will be sent as the protocol version
@@ -121,7 +205,9 @@ public interface PaperServerListPingEvent extends ServerListPingEvent, Cancellab
* @return The protocol version of the server, or {@code -1} if the server
* has not finished initialization yet
*/
int getProtocolVersion();
public int getProtocolVersion() {
return this.protocolVersion;
}
/**
* Sets the protocol version that will be sent as the protocol version
@@ -129,14 +215,19 @@ public interface PaperServerListPingEvent extends ServerListPingEvent, Cancellab
*
* @param protocolVersion The protocol version of the server
*/
void setProtocolVersion(int protocolVersion);
public void setProtocolVersion(int protocolVersion) {
this.protocolVersion = protocolVersion;
}
/**
* Gets the server icon sent to the client.
*
* @return The icon to send to the client, or {@code null} for none
*/
@Nullable CachedServerIcon getServerIcon();
@Nullable
public CachedServerIcon getServerIcon() {
return this.favicon;
}
/**
* Sets the server icon sent to the client.
@@ -144,7 +235,14 @@ public interface PaperServerListPingEvent extends ServerListPingEvent, Cancellab
* @param icon The icon to send to the client, or {@code null} for none
*/
@Override
void setServerIcon(@Nullable CachedServerIcon icon);
public void setServerIcon(@Nullable CachedServerIcon icon) {
if (icon != null && icon.isEmpty()) {
// Represent empty icons as null
icon = null;
}
this.favicon = icon;
}
/**
* {@inheritDoc}
@@ -153,7 +251,9 @@ public interface PaperServerListPingEvent extends ServerListPingEvent, Cancellab
* without sending a response to the client.
*/
@Override
boolean isCancelled();
public boolean isCancelled() {
return this.cancelled;
}
/**
* {@inheritDoc}
@@ -162,7 +262,9 @@ public interface PaperServerListPingEvent extends ServerListPingEvent, Cancellab
* without sending a response to the client.
*/
@Override
void setCancelled(boolean cancel);
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
/**
* {@inheritDoc}
@@ -179,9 +281,77 @@ public interface PaperServerListPingEvent extends ServerListPingEvent, Cancellab
* </ul>
* @deprecated the Iterable interface will be removed at some point
*/
@NotNull
@Override
@Deprecated(forRemoval = true, since = "1.20.6")
Iterator<Player> iterator();
public Iterator<Player> iterator() {
if (this.players == null) {
this.players = getOnlinePlayers();
}
return new PlayerIterator();
}
protected @NotNull Object @NotNull [] getOnlinePlayers() {
return Bukkit.getOnlinePlayers().toArray();
}
@NotNull
protected Player getBukkitPlayer(@NotNull Object player) {
return (Player) player;
}
@ApiStatus.Internal
private final class PlayerIterator implements Iterator<Player> {
private int next;
private int current;
@Nullable private Player player;
@Override
public boolean hasNext() {
for (; this.next < players.length; this.next++) {
if (players[this.next] != null) {
return true;
}
}
return false;
}
@NotNull
@Override
public Player next() {
if (!hasNext()) {
this.player = null;
throw new NoSuchElementException();
}
this.current = this.next++;
return this.player = getBukkitPlayer(players[this.current]);
}
@Override
public void remove() {
if (this.player == null) {
throw new IllegalStateException();
}
UUID uniqueId = this.player.getUniqueId();
this.player = null;
// Remove player from iterator
players[this.current] = null;
// Remove player from sample
getPlayerSample().removeIf(p -> uniqueId.equals(p.getId()));
// Decrement player count
if (originalPlayerCount) {
numPlayers--;
}
}
}
/**
* Represents a player that will be displayed in the player sample of the server list.
@@ -189,6 +359,131 @@ public interface PaperServerListPingEvent extends ServerListPingEvent, Cancellab
* @param name name of the listed player
* @param id UUID of the listed player
*/
record ListedPlayerInfo(String name, UUID id) {
public record ListedPlayerInfo(@NotNull String name, @NotNull UUID id) {
}
@ApiStatus.Internal
private static final class UncheckedPlayerProfile implements PlayerProfile {
private String name;
private UUID uuid;
public UncheckedPlayerProfile(final @NotNull String name, final @NotNull UUID uuid) {
Preconditions.checkNotNull(name, "name cannot be null");
Preconditions.checkNotNull(uuid, "uuid cannot be null");
this.name = name;
this.uuid = uuid;
}
@Override
public @Nullable UUID getUniqueId() {
return uuid;
}
@Override
public @Nullable String getName() {
return name;
}
@Override
public @NotNull String setName(@Nullable final String name) {
Preconditions.checkNotNull(name, "name cannot be null");
return this.name = name;
}
@Override
public @Nullable UUID getId() {
return uuid;
}
@Override
public @Nullable UUID setId(@Nullable final UUID uuid) {
Preconditions.checkNotNull(uuid, "uuid cannot be null");
return this.uuid = uuid;
}
@Override
public @NotNull PlayerTextures getTextures() {
throw new UnsupportedOperationException();
}
@Override
public void setTextures(@Nullable final PlayerTextures textures) {
throw new UnsupportedOperationException();
}
@Override
public @NotNull Set<ProfileProperty> getProperties() {
throw new UnsupportedOperationException();
}
@Override
public boolean hasProperty(@Nullable final String property) {
throw new UnsupportedOperationException();
}
@Override
public void setProperty(@NotNull final ProfileProperty property) {
throw new UnsupportedOperationException();
}
@Override
public void setProperties(@NotNull final Collection<ProfileProperty> properties) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeProperty(@Nullable final String property) {
throw new UnsupportedOperationException();
}
@Override
public void clearProperties() {
throw new UnsupportedOperationException();
}
@Override
public boolean isComplete() {
return false;
}
@Override
public boolean completeFromCache() {
throw new UnsupportedOperationException();
}
@Override
public boolean completeFromCache(final boolean onlineMode) {
throw new UnsupportedOperationException();
}
@Override
public boolean completeFromCache(final boolean lookupUUID, final boolean onlineMode) {
throw new UnsupportedOperationException();
}
@Override
public boolean complete(final boolean textures) {
throw new UnsupportedOperationException();
}
@Override
public boolean complete(final boolean textures, final boolean onlineMode) {
throw new UnsupportedOperationException();
}
@Override
public @NotNull CompletableFuture<PlayerProfile> update() {
throw new UnsupportedOperationException();
}
@Override
public @NotNull PlayerProfile clone() {
throw new UnsupportedOperationException();
}
@Override
public @NotNull Map<String, Object> serialize() {
throw new UnsupportedOperationException();
}
}
}
@@ -1,25 +1,43 @@
package com.destroystokyo.paper.event.server;
import com.destroystokyo.paper.exception.ServerException;
import org.bukkit.Bukkit;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.server.ServerEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called whenever an exception is thrown in a recoverable section of the server.
*/
public interface ServerExceptionEvent extends ServerEvent {
@NullMarked
public class ServerExceptionEvent extends Event {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final ServerException exception;
@ApiStatus.Internal
public ServerExceptionEvent(final ServerException exception) {
super(!Bukkit.isPrimaryThread());
this.exception = exception;
}
/**
* Gets the wrapped exception that was thrown.
*
* @return Exception thrown
*/
ServerException getException();
public ServerException getException() {
return this.exception;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,23 +1,42 @@
package com.destroystokyo.paper.event.server;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.server.ServerEvent;
import org.checkerframework.checker.index.qual.Positive;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when the server has finished ticking the main loop
*/
public interface ServerTickEndEvent extends ServerEvent {
@NullMarked
public class ServerTickEndEvent extends Event {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final int tickNumber;
private final double tickDuration;
private final long timeEnd;
@ApiStatus.Internal
public ServerTickEndEvent(final int tickNumber, final double tickDuration, final long timeRemaining) {
this.tickNumber = tickNumber;
this.tickDuration = tickDuration;
this.timeEnd = System.nanoTime() + timeRemaining;
}
/**
* @return What tick this was since start (first tick = 1)
*/
@Positive int getTickNumber();
public int getTickNumber() {
return this.tickNumber;
}
/**
* @return Time in milliseconds of how long this tick took
*/
double getTickDuration();
public double getTickDuration() {
return this.tickDuration;
}
/**
* Amount of nanoseconds remaining before the next tick should start.
@@ -28,12 +47,16 @@ public interface ServerTickEndEvent extends ServerEvent {
*
* @return Amount of nanoseconds remaining before the next tick should start
*/
long getTimeRemaining();
public long getTimeRemaining() {
return this.timeEnd - System.nanoTime();
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,23 +1,35 @@
package com.destroystokyo.paper.event.server;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.server.ServerEvent;
import org.checkerframework.checker.index.qual.Positive;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when the server has started ticking the main loop
*/
public interface ServerTickStartEvent extends ServerEvent {
@NullMarked
public class ServerTickStartEvent extends Event {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final int tickNumber;
@ApiStatus.Internal
public ServerTickStartEvent(final int tickNumber) {
this.tickNumber = tickNumber;
}
/**
* @return What tick this is going be since start (first tick = 1)
*/
@Positive int getTickNumber();
public int getTickNumber() {
return this.tickNumber;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -2,25 +2,41 @@ package com.destroystokyo.paper.event.server;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* This event is fired when whitelist is toggled
*
* @author Mark Vainomaa
*/
public interface WhitelistToggleEvent extends Event {
@NullMarked
public class WhitelistToggleEvent extends Event {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final boolean enabled;
@ApiStatus.Internal
public WhitelistToggleEvent(final boolean enabled) {
this.enabled = enabled;
}
/**
* Gets whether whitelist is going to be enabled or not
*
* @return Whether whitelist is going to be enabled or not
*/
boolean isEnabled();
public boolean isEnabled() {
return this.enabled;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,4 +0,0 @@
@NullMarked
package com.destroystokyo.paper.event.server;
import org.jspecify.annotations.NullMarked;
@@ -1,5 +1,9 @@
package com.destroystokyo.paper.exception;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import com.destroystokyo.paper.event.server.ServerExceptionEvent;
/**
* Thrown when the internal server throws a recoverable exception.
*/
@@ -20,4 +24,13 @@ public class ServerInternalException extends ServerException {
protected ServerInternalException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public static void reportInternalException(Throwable cause) {
try {
Bukkit.getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(cause)));
;
} catch (Throwable t) {
Bukkit.getLogger().log(Level.WARNING, "Exception posting ServerExceptionEvent", t); // Don't want to rethrow!
}
}
}
@@ -1,19 +1,46 @@
package com.destroystokyo.paper.loottable;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
@NullMarked
public interface LootableInventoryReplenishEvent extends PlayerEvent, Cancellable {
public class LootableInventoryReplenishEvent extends PlayerEvent implements Cancellable {
LootableInventory getInventory();
private static final HandlerList HANDLER_LIST = new HandlerList();
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
private final LootableInventory inventory;
private boolean cancelled;
@ApiStatus.Internal
public LootableInventoryReplenishEvent(final Player player, final LootableInventory inventory) {
super(player);
this.inventory = inventory;
}
public LootableInventory getInventory() {
return this.inventory;
}
@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;
}
}
@@ -15,7 +15,7 @@ public interface NetworkClient {
*
* @return The client's socket address
*/
InetSocketAddress address();
InetSocketAddress getAddress();
/**
* Returns the protocol version of the client.
@@ -24,7 +24,7 @@ public interface NetworkClient {
* @see <a href="https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol_version_numbers">List of protocol
* version numbers</a>
*/
int protocolVersion();
int getProtocolVersion();
/**
* Returns the virtual host the client is connected to.
@@ -34,6 +34,6 @@ public interface NetworkClient {
*
* @return The client's virtual host, or {@code null} if unknown
*/
@Nullable InetSocketAddress virtualHost();
@Nullable InetSocketAddress getVirtualHost();
}
@@ -3,5 +3,7 @@ package io.papermc.paper.block.bed;
import org.jetbrains.annotations.ApiStatus;
@ApiStatus.Internal
record BedRuleResultImpl(boolean success) implements BedRuleResult {
record BedRuleResultImpl(
boolean success
) implements BedRuleResult {
}
@@ -1,6 +1,5 @@
package io.papermc.paper.connection;
import com.destroystokyo.paper.profile.PlayerProfile;
import java.util.Map;
import com.destroystokyo.paper.ClientOption;
@@ -13,13 +12,6 @@ import org.jspecify.annotations.Nullable;
*/
public interface PlayerCommonConnection extends WritablePlayerCookieConnection, ReadablePlayerCookieConnection, PluginMessageRecipient {
/**
* Gets the profile for this connection.
*
* @return profile
*/
PlayerProfile getProfile();
/**
* Sends data to appear in this connection's report logs.
* This is useful for debugging server state that may be causing
@@ -1,5 +1,6 @@
package io.papermc.paper.connection;
import com.destroystokyo.paper.profile.PlayerProfile;
import net.kyori.adventure.audience.Audience;
public interface PlayerConfigurationConnection extends PlayerCommonConnection {
@@ -13,6 +14,13 @@ public interface PlayerConfigurationConnection extends PlayerCommonConnection {
*/
Audience getAudience();
/**
* Gets the profile for this connection.
*
* @return profile
*/
PlayerProfile getProfile();
/**
* Clears the players chat history and their local chat.
*/
@@ -1,26 +1,41 @@
package io.papermc.paper.event.block;
import org.bukkit.block.Beacon;
import org.bukkit.block.Block;
import org.bukkit.event.HandlerList;
import org.bukkit.event.block.BlockEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when a beacon is activated.
* Activation occurs when the beacon beam becomes visible.
*/
public interface BeaconActivatedEvent extends BlockEvent {
@NullMarked
public class BeaconActivatedEvent extends BlockEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
@ApiStatus.Internal
public BeaconActivatedEvent(final Block beacon) {
super(beacon);
}
/**
* Returns the beacon that was activated.
*
* @return the beacon that was activated.
*/
Beacon getBeacon();
public Beacon getBeacon() {
return (Beacon) this.block.getState();
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,14 +1,26 @@
package io.papermc.paper.event.block;
import org.bukkit.Material;
import org.bukkit.block.Beacon;
import org.bukkit.block.Block;
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 beacon is deactivated, either because its base block(s) or itself were destroyed.
*/
public interface BeaconDeactivatedEvent extends BlockEvent {
@NullMarked
public class BeaconDeactivatedEvent extends BlockEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
@ApiStatus.Internal
public BeaconDeactivatedEvent(final Block beacon) {
super(beacon);
}
/**
* Returns the beacon that was deactivated.
@@ -17,12 +29,16 @@ public interface BeaconDeactivatedEvent extends BlockEvent {
*
* @return The beacon that got deactivated, or {@code null} if it does not exist.
*/
@Nullable Beacon getBeacon();
public @Nullable Beacon getBeacon() {
return this.block.getType() == Material.BEACON ? (Beacon) this.block.getState() : null;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,9 +1,12 @@
package io.papermc.paper.event.block;
import org.bukkit.block.Block;
import org.bukkit.entity.Raider;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.block.BlockEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
/**
* Called when a {@link Raider} is revealed by a bell.
@@ -11,14 +14,33 @@ import org.bukkit.event.block.BlockEvent;
* @deprecated use {@link org.bukkit.event.block.BellResonateEvent}
*/
@Deprecated(since = "1.19.4")
public interface BellRevealRaiderEvent extends BlockEvent, Cancellable {
public class BellRevealRaiderEvent extends BlockEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Raider raider;
private boolean cancelled;
@ApiStatus.Internal
public BellRevealRaiderEvent(@NotNull Block bell, @NotNull Raider raider) {
super(bell);
this.raider = raider;
}
/**
* Gets the raider that the bell revealed.
*
* @return The raider
*/
Raider getEntity();
@NotNull
public Raider getEntity() {
return this.raider;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
/**
* {@inheritDoc}
@@ -26,12 +48,16 @@ public interface BellRevealRaiderEvent extends BlockEvent, Cancellable {
* This does not cancel the particle effects shown on the bell, only the entity.
*/
@Override
void setCancelled(boolean cancel);
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public @NotNull HandlerList getHandlers() {
return HANDLER_LIST;
}
public static @NotNull HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,10 +1,22 @@
package io.papermc.paper.event.block;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Entity;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Called when a bell is rung.
*
* @deprecated use {@link org.bukkit.event.block.BellRingEvent}
*/
@Deprecated(since = "1.19.4")
public interface BellRingEvent extends org.bukkit.event.block.BellRingEvent {
public class BellRingEvent extends org.bukkit.event.block.BellRingEvent {
@ApiStatus.Internal
public BellRingEvent(@NotNull Block block, @NotNull BlockFace direction, @Nullable Entity entity) {
super(block, direction, entity);
}
}
@@ -5,32 +5,53 @@ import org.bukkit.block.Block;
import org.bukkit.event.HandlerList;
import org.bukkit.event.block.BlockExpEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when a block forces another block to break and drop items.
* <p>
* Currently called for piston's and liquid flows.
*/
public interface BlockBreakBlockEvent extends BlockExpEvent {
@NullMarked
public class BlockBreakBlockEvent extends BlockExpEvent {
/**
* Gets the block that cause this (e.g. a piston, or adjacent liquid)
*
* @return the source
*/
Block getSource();
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Block source;
private final List<ItemStack> drops;
@ApiStatus.Internal
public BlockBreakBlockEvent(final Block block, final Block source, final List<ItemStack> drops) {
super(block, 0);
this.source = source;
this.drops = drops;
}
/**
* Gets a mutable list of drops for this event
*
* @return the drops
*/
List<ItemStack> getDrops();
public List<ItemStack> getDrops() {
return this.drops;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
/**
* Gets the block that cause this (e.g. a piston, or adjacent liquid)
*
* @return the source
*/
public Block getSource() {
return this.source;
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,13 +1,29 @@
package io.papermc.paper.event.block;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.event.HandlerList;
import org.bukkit.event.block.BlockEvent;
import org.bukkit.event.entity.EntityEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when the progress of a block break is updated.
*/
public interface BlockBreakProgressUpdateEvent extends BlockEvent, EntityEvent {
@NullMarked
public class BlockBreakProgressUpdateEvent extends BlockEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final float progress;
private final Entity entity;
@ApiStatus.Internal
public BlockBreakProgressUpdateEvent(final Block block, final float progress, final Entity entity) {
super(block);
this.progress = progress;
this.entity = entity;
}
/**
* The progress of the block break
@@ -17,12 +33,25 @@ public interface BlockBreakProgressUpdateEvent extends BlockEvent, EntityEvent {
*
* @return The progress of the block break
*/
float getProgress();
public float getProgress() {
return this.progress;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
/**
* The entity breaking the block.
*
* @return The entity breaking the block
*/
public Entity getEntity() {
return this.entity;
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,29 +1,57 @@
package io.papermc.paper.event.block;
import org.bukkit.block.Block;
import org.bukkit.event.HandlerList;
import org.bukkit.event.block.BlockEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when a block tries to dispense an item, but its inventory is empty.
*/
public interface BlockFailedDispenseEvent extends BlockEvent {
@NullMarked
public class BlockFailedDispenseEvent extends BlockEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
private boolean shouldPlayEffect = true;
@ApiStatus.Internal
public BlockFailedDispenseEvent(final Block block) {
super(block);
}
/**
* @return if the effect should be played
*/
boolean shouldPlayEffect();
public boolean shouldPlayEffect() {
return this.shouldPlayEffect;
}
/**
* Sets if the effect for empty dispensers should be played
*
* @param playEffect if the effect should be played
*/
void shouldPlayEffect(boolean playEffect);
public void shouldPlayEffect(final boolean playEffect) {
this.shouldPlayEffect = playEffect;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
/**
* @return {@link #shouldPlayEffect()}
*/
@Override
public boolean callEvent() {
super.callEvent();
return this.shouldPlayEffect();
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,12 +1,18 @@
package io.papermc.paper.event.block;
import com.google.common.base.Preconditions;
import io.papermc.paper.block.LockableTileState;
import java.util.Objects;
import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.text.Component;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.block.BlockEvent;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
@@ -14,7 +20,24 @@ import org.jspecify.annotations.Nullable;
* <br>
* See {@link #setResult(Result)} to change behavior
*/
public interface BlockLockCheckEvent extends BlockEvent, PlayerEvent {
@NullMarked
public class BlockLockCheckEvent extends BlockEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Player player;
private @Nullable Component lockedMessage;
private @Nullable Sound lockedSound;
private @Nullable ItemStack itemStack;
private Result result = Result.DEFAULT;
@ApiStatus.Internal
public BlockLockCheckEvent(final Block block, final Player player, final Component lockedMessage, final Sound lockedSound) {
super(block);
this.player = player;
this.lockedMessage = lockedMessage;
this.lockedSound = lockedSound;
}
/**
* Gets the snapshot {@link LockableTileState} of the block entity
@@ -22,7 +45,20 @@ public interface BlockLockCheckEvent extends BlockEvent, PlayerEvent {
*
* @return the snapshot block state.
*/
LockableTileState getBlockState();
public LockableTileState getBlockState() {
final BlockState blockState = this.getBlock().getState();
Preconditions.checkState(blockState instanceof LockableTileState, "Block state of lock-checked block is no longer a lockable tile state!");
return (LockableTileState) blockState;
}
/**
* Get the player involved this lock check.
*
* @return the player
*/
public Player getPlayer() {
return this.player;
}
/**
* Gets the itemstack that will be used as the key itemstack. Initially
@@ -33,7 +69,9 @@ public interface BlockLockCheckEvent extends BlockEvent, PlayerEvent {
* @return the item being used as the key item
* @see #isUsingCustomKeyItemStack()
*/
ItemStack getKeyItem();
public ItemStack getKeyItem() {
return Objects.requireNonNullElseGet(this.itemStack, this.player.getInventory()::getItemInMainHand);
}
/**
* Sets the itemstack that will be used as the key item.
@@ -41,19 +79,26 @@ public interface BlockLockCheckEvent extends BlockEvent, PlayerEvent {
* @param stack the stack to use as a key
* @see #resetKeyItem() to clear a custom key item
*/
void setKeyItem(ItemStack stack);
public void setKeyItem(final ItemStack stack) {
Preconditions.checkArgument(stack != null, "stack cannot be null");
this.itemStack = stack;
}
/**
* Reset the key stack to the default (the player's main hand).
*/
void resetKeyItem();
public void resetKeyItem() {
this.itemStack = null;
}
/**
* Checks if a custom key stack has been set.
*
* @return {@code true} if a custom key itemstack has been set
*/
boolean isUsingCustomKeyItemStack();
public boolean isUsingCustomKeyItemStack() {
return this.itemStack != null;
}
/**
* Gets the result of this event.
@@ -61,7 +106,9 @@ public interface BlockLockCheckEvent extends BlockEvent, PlayerEvent {
* @return the result
* @see #setResult(Result)
*/
Result getResult();
public Result getResult() {
return this.result;
}
/**
* Gets the result of this event. {@link Result#DEFAULT} is the default
@@ -72,7 +119,9 @@ public interface BlockLockCheckEvent extends BlockEvent, PlayerEvent {
*
* @param result the result of this event
*/
void setResult(Result result);
public void setResult(final Result result) {
this.result = result;
}
/**
* Shorthand method to set the {@link #getResult()} to {@link Result#DENY},
@@ -81,7 +130,11 @@ public interface BlockLockCheckEvent extends BlockEvent, PlayerEvent {
* @param lockedMessage the message to show if locked (or {@code null} for none)
* @param lockedSound the sound to play if locked (or {@code null} for none)
*/
void denyWithMessageAndSound(@Nullable Component lockedMessage, @Nullable Sound lockedSound);
public void denyWithMessageAndSound(final @Nullable Component lockedMessage, final @Nullable Sound lockedSound) {
this.result = Result.DENY;
this.lockedMessage = lockedMessage;
this.lockedSound = lockedSound;
}
/**
* Gets the locked message that will be sent if the
@@ -89,7 +142,9 @@ public interface BlockLockCheckEvent extends BlockEvent, PlayerEvent {
*
* @return the locked message (or {@code null} if none)
*/
@Nullable Component getLockedMessage();
public @Nullable Component getLockedMessage() {
return this.lockedMessage;
}
/**
* Sets the locked message that will be sent if the
@@ -97,7 +152,9 @@ public interface BlockLockCheckEvent extends BlockEvent, PlayerEvent {
*
* @param lockedMessage the locked message (or {@code null} for none)
*/
void setLockedMessage(@Nullable Component lockedMessage);
public void setLockedMessage(final @Nullable Component lockedMessage) {
this.lockedMessage = lockedMessage;
}
/**
* Gets the locked sound that will play if the
@@ -105,7 +162,9 @@ public interface BlockLockCheckEvent extends BlockEvent, PlayerEvent {
*
* @return the locked sound (or {@code null} if none)
*/
@Nullable Sound getLockedSound();
public @Nullable Sound getLockedSound() {
return this.lockedSound;
}
/**
* Sets the locked sound that will play if the
@@ -113,12 +172,16 @@ public interface BlockLockCheckEvent extends BlockEvent, PlayerEvent {
*
* @param lockedSound the locked sound (or {@code null} for none)
*/
void setLockedSound(@Nullable Sound lockedSound);
public void setLockedSound(final @Nullable Sound lockedSound) {
this.lockedSound = lockedSound;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,30 +1,64 @@
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.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
public interface BlockPreDispenseEvent extends BlockEvent, Cancellable {
@NullMarked
public class BlockPreDispenseEvent extends BlockEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final ItemStack itemStack;
private final int slot;
private boolean cancelled;
@ApiStatus.Internal
public BlockPreDispenseEvent(final Block block, final ItemStack itemStack, final int slot) {
super(block);
this.itemStack = itemStack;
this.slot = slot;
}
/**
* Gets the {@link ItemStack} to be dispensed.
*
* @return The item to be dispensed
*/
ItemStack getItemStack();
public ItemStack getItemStack() {
return this.itemStack;
}
/**
* Gets the inventory slot of the dispenser to dispense from.
*
* @return The inventory slot
*/
int getSlot();
public int getSlot() {
return this.slot;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@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;
}
}
@@ -1,41 +1,66 @@
package io.papermc.paper.event.block;
import org.bukkit.block.Block;
import org.bukkit.event.HandlerList;
import org.bukkit.event.block.BlockEvent;
import org.bukkit.event.inventory.InventoryMoveItemEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when an item is about to be composted by a hopper.
* To prevent hoppers from moving items into composters, cancel the {@link InventoryMoveItemEvent}.
*/
public interface CompostItemEvent extends BlockEvent {
@NullMarked
public class CompostItemEvent extends BlockEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final ItemStack item;
private boolean willRaiseLevel;
@ApiStatus.Internal
public CompostItemEvent(final Block composter, final ItemStack item, final boolean willRaiseLevel) {
super(composter);
this.item = item;
this.willRaiseLevel = willRaiseLevel;
}
/**
* Gets the item that was used on the composter.
*
* @return the item
*/
ItemStack getItem();
public ItemStack getItem() {
return this.item;
}
/**
* Gets whether the composter will rise a level.
*
* @return {@code true} if successful
*/
boolean willRaiseLevel();
public boolean willRaiseLevel() {
return this.willRaiseLevel;
}
/**
* Sets whether the composter will rise a level.
*
* @param willRaiseLevel {@code true} if the composter should rise a level
*/
void setWillRaiseLevel(boolean willRaiseLevel);
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
public void setWillRaiseLevel(final boolean willRaiseLevel) {
this.willRaiseLevel = willRaiseLevel;
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,10 +1,14 @@
package io.papermc.paper.event.block;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.boss.DragonBattle;
import org.bukkit.entity.EnderDragon;
import org.bukkit.event.HandlerList;
import org.bukkit.event.block.BlockFormEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when the {@link EnderDragon} is defeated (killed) in a {@link DragonBattle},
@@ -14,7 +18,18 @@ import org.bukkit.event.block.BlockFormEvent;
* <b>This event might be cancelled by default depending on
* e.g. {@link DragonBattle#hasBeenPreviouslyKilled()} and server configuration.</b>
*/
public interface DragonEggFormEvent extends BlockFormEvent {
@NullMarked
public class DragonEggFormEvent extends BlockFormEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final DragonBattle dragonBattle;
@ApiStatus.Internal
public DragonEggFormEvent(final Block block, final BlockState newState, final DragonBattle dragonBattle) {
super(block, newState);
this.dragonBattle = dragonBattle;
}
/**
* Gets the {@link DragonBattle} associated with this event.
@@ -23,12 +38,16 @@ public interface DragonEggFormEvent extends BlockFormEvent {
*
* @return the dragon battle
*/
DragonBattle getDragonBattle();
public DragonBattle getDragonBattle() {
return this.dragonBattle;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,12 +1,15 @@
package io.papermc.paper.event.block;
import java.util.List;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.block.BlockEvent;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when a player uses shears on a block.
@@ -16,28 +19,62 @@ import org.bukkit.inventory.ItemStack;
* <p>
* Examples include shearing a pumpkin to turn it into a carved pumpkin or shearing a beehive to get honeycomb.
*/
public interface PlayerShearBlockEvent extends PlayerEvent, BlockEvent, Cancellable {
@NullMarked
public class PlayerShearBlockEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Block block;
private final ItemStack item;
private final EquipmentSlot hand;
private final List<ItemStack> drops;
private boolean cancelled;
@ApiStatus.Internal
public PlayerShearBlockEvent(final Player player, final Block block, final ItemStack item, final EquipmentSlot hand, final List<ItemStack> drops) {
super(player);
this.block = block;
this.item = item;
this.hand = hand;
this.drops = drops;
}
/**
* Gets the block being sheared in this event.
*
* @return The {@link Block} which block is being sheared in this event.
*/
public Block getBlock() {
return this.block;
}
/**
* Gets the item used to shear the block.
*
* @return The {@link ItemStack} of the shears.
*/
ItemStack getItem();
public ItemStack getItem() {
return this.item;
}
/**
* Gets the hand used to shear the block.
*
* @return Either {@link EquipmentSlot#HAND} OR {@link EquipmentSlot#OFF_HAND}.
*/
EquipmentSlot getHand();
public EquipmentSlot getHand() {
return this.hand;
}
/**
* Gets the resulting drops of this event.
*
* @return A mutable {@link List list} of {@link ItemStack items} that will be dropped as result of this event.
*/
List<ItemStack> getDrops();
public List<ItemStack> getDrops() {
return this.drops;
}
/**
* Gets whether the shearing of the block should be cancelled or not.
@@ -45,7 +82,9 @@ public interface PlayerShearBlockEvent extends PlayerEvent, BlockEvent, Cancella
* @return Whether the shearing of the block should be cancelled or not.
*/
@Override
boolean isCancelled();
public boolean isCancelled() {
return this.cancelled;
}
/**
* Sets whether the shearing of the block should be cancelled or not.
@@ -53,12 +92,16 @@ public interface PlayerShearBlockEvent extends PlayerEvent, BlockEvent, Cancella
* @param cancel whether the shearing of the block should be cancelled or not.
*/
@Override
void setCancelled(boolean cancel);
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,8 +1,14 @@
package io.papermc.paper.event.block;
import com.google.common.base.Preconditions;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Projectile;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.checkerframework.common.value.qual.IntRange;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Range;
import org.jspecify.annotations.NullMarked;
/**
* Called when a Target Block is hit by a projectile.
@@ -11,26 +17,44 @@ import org.checkerframework.common.value.qual.IntRange;
* and in the case that the shooter is a player, will stop them from receiving
* advancement criteria.
*/
public interface TargetHitEvent extends ProjectileHitEvent {
@NullMarked
public class TargetHitEvent extends ProjectileHitEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
private int signalStrength;
@ApiStatus.Internal
public TargetHitEvent(final Projectile projectile, final Block block, final BlockFace blockFace, final int signalStrength) {
super(projectile, null, block, blockFace);
this.signalStrength = signalStrength;
}
/**
* Gets the strength of the redstone signal to be emitted by the Target block
*
* @return the strength of the redstone signal to be emitted
*/
@IntRange(from = 0, to = 15) int getSignalStrength();
public @Range(from = 0, to = 15) int getSignalStrength() {
return this.signalStrength;
}
/**
* Sets the strength of the redstone signal to be emitted by the Target block
*
* @param signalStrength the strength of the redstone signal to be emitted
*/
void setSignalStrength(@IntRange(from = 0, to = 15) int signalStrength);
public void setSignalStrength(final @Range(from = 0, to = 15) int signalStrength) {
Preconditions.checkArgument(signalStrength >= 0 && signalStrength <= 15, "Signal strength out of range (%s), must be in range [0,15]", signalStrength);
this.signalStrength = signalStrength;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,42 +1,80 @@
package io.papermc.paper.event.block;
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.
*/
public interface VaultChangeStateEvent extends BlockEvent, Cancellable {
@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;
@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.
*/
@Nullable Player getPlayer();
public @Nullable Player getPlayer() {
return this.player;
}
/**
* Gets the state the vault is currently in.
*
* @return The current vault state.
*/
Vault.State getCurrentState();
public Vault.State getCurrentState() {
return this.currentState;
}
/**
* Gets the state the vault is attempting to transition to.
*
* @return The new vault state.
*/
Vault.State getNewState();
public Vault.State getNewState() {
return this.newState;
}
static HandlerList getHandlerList() {
final class Holder {
private static final HandlerList HANDLER_LIST = new HandlerList();
}
return Holder.HANDLER_LIST;
@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;
}
}
@@ -1,4 +0,0 @@
@NullMarked
package io.papermc.paper.event.block;
import org.jspecify.annotations.NullMarked;
Loaded 100 of 1095 files, more files were not shown because too many files have changed in this diff. Show more