This commit is contained in:
2026-01-20 20:33:59 +01:00
commit b16a40e431
583 changed files with 87339 additions and 0 deletions

View File

@@ -0,0 +1,675 @@
---
title: Player Events
type: docs
weight: 1
---
Events triggered by player actions and state changes.
## Connection Events
### PlayerSetupConnectEvent
{{< badge "Cancellable" >}}
Fired during player connection setup. Can be cancelled to prevent connection or redirect to another server.
**Package:** `com.hypixel.hytale.server.core.event.events.player`
{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| uuid | `UUID` | Player's unique identifier |
| username | `String` | Player's username |
| auth | `PlayerAuthentication` | Authentication information |
| referralData | `byte[]` | Data from referral (if redirected) |
| referralSource | `HostAddress` | Server that referred player |
{{< /tab >}}
{{< tab >}}
- `getUuid()` - Returns player UUID
- `getUsername()` - Returns player username
- `getAuth()` - Returns authentication data
- `getReferralData()` - Returns referral data (may be null)
- `isReferralConnection()` - Check if redirected from another server
- `getReferralSource()` - Returns source server address
- `referToServer(host, port)` - Redirect player to another server
- `referToServer(host, port, data)` - Redirect with data
- `getReason()` - Get disconnect reason message
- `setReason(String)` - Set disconnect reason message
- `isCancelled()` - Check if cancelled
- `setCancelled(boolean)` - Cancel connection
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(PlayerSetupConnectEvent.class, event -> {
String username = event.getUsername();
UUID uuid = event.getUuid();
// Ban check
if (isBanned(uuid)) {
event.setCancelled(true);
event.setReason("You are banned from this server!");
return;
}
// Redirect to different server based on condition
if (shouldRedirect(uuid)) {
event.referToServer("lobby.example.com", 25565);
}
});
```
{{< /tab >}}
{{< /tabs >}}
---
### PlayerConnectEvent
Fired when a player connects to the server. Use this to set the spawn world.
**Package:** `com.hypixel.hytale.server.core.event.events.player`
{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| holder | `Holder<EntityStore>` | Entity store holder |
| playerRef | `PlayerRef` | Reference to the connecting player |
| world | `World` | The world player will spawn in |
{{< /tab >}}
{{< tab >}}
- `getHolder()` - Returns the entity store holder
- `getPlayerRef()` - Returns the player reference
- `getPlayer()` - Returns the Player object (deprecated)
- `getWorld()` - Returns current spawn world (may be null)
- `setWorld(World)` - Set the world player will spawn in
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(PlayerConnectEvent.class, event -> {
PlayerRef playerRef = event.getPlayerRef();
getLogger().at(Level.INFO).log("Player connecting: " + playerRef.getUsername());
// Set spawn world
World lobbyWorld = Universe.get().getWorld("lobby");
if (lobbyWorld != null) {
event.setWorld(lobbyWorld);
}
});
```
{{< /tab >}}
{{< /tabs >}}
{{< callout type="warning" >}}
The `getPlayer()` method is deprecated. Prefer using `getPlayerRef()` or `getHolder()` to access player data.
{{< /callout >}}
---
### PlayerSetupDisconnectEvent
Fired when a player disconnects during the setup phase (before fully connecting).
**Package:** `com.hypixel.hytale.server.core.event.events.player`
{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| uuid | `UUID` | Player's unique identifier |
| username | `String` | Player's username |
| auth | `PlayerAuthentication` | Authentication information |
| disconnectReason | `DisconnectReason` | Why the player disconnected |
{{< /tab >}}
{{< tab >}}
- `getUuid()` - Returns player UUID
- `getUsername()` - Returns player username
- `getAuth()` - Returns authentication data
- `getDisconnectReason()` - Returns disconnect reason
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(PlayerSetupDisconnectEvent.class, event -> {
String username = event.getUsername();
PacketHandler.DisconnectReason reason = event.getDisconnectReason();
getLogger().at(Level.INFO).log("Player " + username + " disconnected during setup: " + reason);
// Cleanup any pre-connection data
cleanupPendingData(event.getUuid());
});
```
{{< /tab >}}
{{< /tabs >}}
---
### PlayerReadyEvent
Fired when a player is fully ready and loaded into the game. This is the safe point to interact with the player.
**Package:** `com.hypixel.hytale.server.core.event.events.player`
{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| playerRef | `Ref<EntityStore>` | Entity store reference |
| player | `Player` | The player object |
| readyId | `int` | Ready event identifier |
{{< /tab >}}
{{< tab >}}
- `getPlayer()` - Returns the Player object
- `getPlayerRef()` - Returns the entity store reference
- `getReadyId()` - Returns the ready event ID
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(PlayerReadyEvent.class, event -> {
Player player = event.getPlayer();
// Player is fully loaded, safe to send complex data
player.sendMessage(Message.raw("Welcome to the server!"));
loadPlayerData(player);
sendWelcomeScreen(player);
});
```
{{< /tab >}}
{{< /tabs >}}
---
### PlayerDisconnectEvent
Fired when a player disconnects from the server.
**Package:** `com.hypixel.hytale.server.core.event.events.player`
{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| playerRef | `PlayerRef` | Reference to the disconnecting player |
{{< /tab >}}
{{< tab >}}
- `getPlayerRef()` - Returns the player reference
- `getDisconnectReason()` - Returns why the player disconnected
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(PlayerDisconnectEvent.class, event -> {
PlayerRef playerRef = event.getPlayerRef();
savePlayerData(playerRef.getUuid());
getLogger().at(Level.INFO).log(playerRef.getUsername() + " has left the server");
// Check disconnect reason
PacketHandler.DisconnectReason reason = event.getDisconnectReason();
getLogger().at(Level.INFO).log("Reason: " + reason);
});
```
{{< /tab >}}
{{< /tabs >}}
---
## World Events
### AddPlayerToWorldEvent
Fired when a player is added to a world.
**Package:** `com.hypixel.hytale.server.core.event.events.player`
{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| holder | `Holder<EntityStore>` | Entity store holder |
| world | `World` | The world being entered |
| broadcastJoinMessage | `boolean` | Whether to broadcast join message |
{{< /tab >}}
{{< tab >}}
- `getHolder()` - Returns the entity store holder
- `getWorld()` - Returns the world
- `shouldBroadcastJoinMessage()` - Check if join message will be sent
- `setBroadcastJoinMessage(boolean)` - Control join message broadcast
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(AddPlayerToWorldEvent.class, event -> {
World world = event.getWorld();
// Disable default join message for silent joins
if (isSilentJoin(event.getHolder())) {
event.setBroadcastJoinMessage(false);
}
applyWorldEffects(event.getHolder(), world);
});
```
{{< /tab >}}
{{< /tabs >}}
---
### DrainPlayerFromWorldEvent
Fired when a player is removed from a world (before teleporting to another or disconnecting).
**Package:** `com.hypixel.hytale.server.core.event.events.player`
{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| holder | `Holder<EntityStore>` | Entity store holder |
| world | `World` | The world being left |
| transform | `Transform` | Player's position/rotation |
{{< /tab >}}
{{< tab >}}
- `getHolder()` - Returns the entity store holder
- `getWorld()` - Returns the world being left
- `setWorld(World)` - Change destination world
- `getTransform()` - Returns player's transform
- `setTransform(Transform)` - Set spawn transform in new world
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(DrainPlayerFromWorldEvent.class, event -> {
World world = event.getWorld();
removeWorldEffects(event.getHolder());
saveWorldProgress(event.getHolder(), world);
// Optionally redirect to different world
World newWorld = Universe.get().getWorld("hub");
if (newWorld != null) {
event.setWorld(newWorld);
}
});
```
{{< /tab >}}
{{< /tabs >}}
---
## Chat Events
### PlayerChatEvent
{{< badge "Cancellable" >}} {{< badge "Async" >}}
Fired when a player sends a chat message. This event is asynchronous.
**Package:** `com.hypixel.hytale.server.core.event.events.player`
{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| sender | `PlayerRef` | The player sending the message |
| targets | `List<PlayerRef>` | Players who will receive the message |
| content | `String` | The message content |
| formatter | `Formatter` | Message formatting handler |
{{< /tab >}}
{{< tab >}}
- `getSender()` - Returns the sending player reference
- `setSender(PlayerRef)` - Change the sender
- `getContent()` - Returns the message content
- `setContent(String)` - Modify the message
- `getTargets()` - Returns message recipients
- `setTargets(List<PlayerRef>)` - Change recipients
- `getFormatter()` - Returns the message formatter
- `setFormatter(Formatter)` - Set custom formatter
- `isCancelled()` - Check if cancelled
- `setCancelled(boolean)` - Cancel the message
{{< /tab >}}
{{< tab >}}
```java
// PlayerChatEvent has String key and is async - use registerAsyncGlobal()
getEventRegistry().registerAsyncGlobal(PlayerChatEvent.class, future -> {
return future.thenApply(event -> {
PlayerRef sender = event.getSender();
String message = event.getContent();
// Filter bad words
if (containsBadWord(message)) {
event.setCancelled(true);
// Use PlayerRef.sendMessage() directly
sender.sendMessage(Message.raw("Please don't use that word!"));
return event;
}
// Add prefix based on rank
String prefix = getPlayerPrefix(sender);
event.setContent(prefix + message);
// Custom formatter
event.setFormatter((playerRef, msg) ->
Message.translation("custom.chat.format")
.param("name", playerRef.getUsername())
.param("message", msg)
);
return event;
});
});
```
{{< /tab >}}
{{< /tabs >}}
{{< callout type="info" >}}
**Async Event:** This event runs asynchronously. Use `sender.getReference()` to check if the player is still online (returns null or invalid reference if disconnected).
{{< /callout >}}
---
## Crafting Events
### PlayerCraftEvent
{{< badge "Deprecated" >}}
Fired when a player crafts an item.
**Package:** `com.hypixel.hytale.server.core.event.events.player`
{{< callout type="warning" >}}
**Deprecated:** This event is marked for removal. Use `CraftRecipeEvent` from the ECS events instead.
{{< /callout >}}
{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| ref | `Ref<EntityStore>` | Entity store reference |
| player | `Player` | The crafting player |
| craftedRecipe | `CraftingRecipe` | The recipe being crafted |
| quantity | `int` | Number of items crafted |
{{< /tab >}}
{{< tab >}}
- `getPlayer()` - Returns the Player object
- `getPlayerRef()` - Returns entity store reference
- `getCraftedRecipe()` - Returns the crafting recipe
- `getQuantity()` - Returns number crafted
{{< /tab >}}
{{< tab >}}
```java
// Deprecated - prefer CraftRecipeEvent
getEventRegistry().register(PlayerCraftEvent.class, event -> {
Player player = event.getPlayer();
CraftingRecipe recipe = event.getCraftedRecipe();
int quantity = event.getQuantity();
getLogger().at(Level.INFO).log(player.getDisplayName() + " crafted " + quantity + " items");
});
```
{{< /tab >}}
{{< /tabs >}}
---
## Input Events
### PlayerMouseButtonEvent
{{< badge "Cancellable" >}}
Fired when a player presses a mouse button.
**Package:** `com.hypixel.hytale.server.core.event.events.player`
{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| playerRef | `PlayerRef` | Reference to the player |
| clientUseTime | `long` | Client-side timestamp |
| itemInHand | `Item` | The item being held |
| targetBlock | `Vector3i` | Block being targeted |
| targetEntity | `Entity` | Entity being targeted |
| screenPoint | `Vector2f` | Screen coordinates |
| mouseButton | `MouseButtonEvent` | Which button was pressed |
{{< /tab >}}
{{< tab >}}
- `getPlayer()` - Returns the Player object
- `getPlayerRef()` - Returns entity store reference
- `getPlayerRefComponent()` - Returns PlayerRef component
- `getClientUseTime()` - Returns client timestamp
- `getItemInHand()` - Returns held item
- `getTargetBlock()` - Returns targeted block position
- `getTargetEntity()` - Returns targeted entity
- `getScreenPoint()` - Returns screen coordinates
- `getMouseButton()` - Returns mouse button info
- `isCancelled()` - Check if cancelled
- `setCancelled(boolean)` - Cancel the input
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(PlayerMouseButtonEvent.class, event -> {
Player player = event.getPlayer();
// Prevent input during cutscene
if (isInCutscene(player)) {
event.setCancelled(true);
return;
}
// Custom item interaction
Item item = event.getItemInHand();
if (item != null && item.getId().equals("magic_wand")) {
handleMagicWandUse(player, event.getTargetBlock());
}
});
```
{{< /tab >}}
{{< /tabs >}}
---
### PlayerMouseMotionEvent
{{< badge "Cancellable" >}}
Fired when a player moves their mouse (camera rotation, aiming).
**Package:** `com.hypixel.hytale.server.core.event.events.player`
{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| playerRef | `Ref<EntityStore>` | Entity store reference |
| player | `Player` | The player |
| clientUseTime | `long` | Client-side timestamp |
| itemInHand | `Item` | The item being held |
| targetBlock | `Vector3i` | Block being targeted |
| targetEntity | `Entity` | Entity being targeted |
| screenPoint | `Vector2f` | Screen coordinates |
| mouseMotion | `MouseMotionEvent` | Mouse motion data |
{{< /tab >}}
{{< tab >}}
- `getPlayer()` - Returns the Player object
- `getPlayerRef()` - Returns entity store reference
- `getClientUseTime()` - Returns client timestamp
- `getItemInHand()` - Returns held item
- `getTargetBlock()` - Returns targeted block position
- `getTargetEntity()` - Returns targeted entity
- `getScreenPoint()` - Returns screen coordinates
- `getMouseMotion()` - Returns mouse motion data
- `isCancelled()` - Check if cancelled
- `setCancelled(boolean)` - Cancel the motion event
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(PlayerMouseMotionEvent.class, event -> {
Player player = event.getPlayer();
// Track what the player is looking at
Entity target = event.getTargetEntity();
if (target != null) {
updatePlayerTarget(player, target);
}
// Track camera movement for analytics
trackCameraMovement(player, event.getMouseMotion());
});
```
{{< /tab >}}
{{< /tabs >}}
---
## Interaction Events
### PlayerInteractEvent
{{< badge "Deprecated" >}} {{< badge "Cancellable" >}}
Fired when a player interacts with the world.
**Package:** `com.hypixel.hytale.server.core.event.events.player`
{{< callout type="warning" >}}
**Deprecated:** This event is deprecated. Use more specific events like `UseBlockEvent`, `PlayerMouseButtonEvent`, or ECS interaction events instead.
{{< /callout >}}
{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| actionType | `InteractionType` | Type of interaction |
| clientUseTime | `long` | Client timestamp |
| itemInHand | `ItemStack` | Item being used |
| targetBlock | `Vector3i` | Block being targeted |
| targetEntity | `Entity` | Entity being targeted |
{{< /tab >}}
{{< tab >}}
- `getPlayer()` - Returns the Player object
- `getActionType()` - Returns interaction type
- `getClientUseTime()` - Returns client timestamp
- `getItemInHand()` - Returns item in hand
- `getTargetBlock()` - Returns targeted block
- `getTargetEntity()` - Returns targeted entity
- `getTargetRef()` - Returns target entity reference
- `isCancelled()` - Check if cancelled
- `setCancelled(boolean)` - Cancel interaction
{{< /tab >}}
{{< tab >}}
```java
// Deprecated - prefer UseBlockEvent or PlayerMouseButtonEvent
getEventRegistry().register(PlayerInteractEvent.class, event -> {
Player player = event.getPlayer();
InteractionType action = event.getActionType();
// Handle interaction
});
```
{{< /tab >}}
{{< /tabs >}}
---
## Practical Examples
### Complete Welcome System
```java
public class WelcomePlugin extends JavaPlugin {
private final Set<UUID> firstJoinPlayers = new HashSet<>();
@Override
public void start() {
// Track setup phase
getEventRegistry().register(PlayerSetupConnectEvent.class, event -> {
if (isFirstJoin(event.getUuid())) {
firstJoinPlayers.add(event.getUuid());
}
});
// Welcome when fully ready
getEventRegistry().register(PlayerReadyEvent.class, event -> {
Player player = event.getPlayer();
if (firstJoinPlayers.remove(player.getUuid())) {
// First time player
player.sendMessage(Message.raw("Welcome to the server for the first time!"));
giveStarterKit(player);
} else {
// Returning player
player.sendMessage(Message.raw("Welcome back, " + player.getDisplayName() + "!"));
}
});
// Save on disconnect
getEventRegistry().register(PlayerDisconnectEvent.class, event -> {
savePlayerData(event.getPlayerRef().getUuid());
});
}
}
```
### Server Referral System
```java
public class ReferralPlugin extends JavaPlugin {
@Override
public void start() {
getEventRegistry().register(PlayerSetupConnectEvent.class, event -> {
// Check if player came from referral
if (event.isReferralConnection()) {
byte[] data = event.getReferralData();
HostAddress source = event.getReferralSource();
getLogger().at(Level.INFO).log("Player referred from " + source.host);
}
// Redirect based on load balancing
String targetServer = getOptimalServer();
if (!isThisServer(targetServer)) {
event.referToServer(targetServer, 25565, createReferralData());
}
});
}
}
```
### Chat Filter System
```java
public class ChatFilterPlugin extends JavaPlugin {
private final Set<String> bannedWords = new HashSet<>();
private final Map<UUID, Integer> warnings = new HashMap<>();
@Override
public void start() {
loadBannedWords();
getEventRegistry().register(PlayerChatEvent.class, event -> {
PlayerRef sender = event.getSender();
String message = event.getContent().toLowerCase();
for (String banned : bannedWords) {
if (message.contains(banned)) {
event.setCancelled(true);
Player player = sender.getPlayer();
if (player != null) {
int count = warnings.merge(sender.getUuid(), 1, Integer::sum);
player.sendMessage(Message.raw("Warning " + count + "/3: Watch your language!"));
if (count >= 3) {
player.kick("Too many chat violations");
}
}
return;
}
}
});
}
}
```