Init
This commit is contained in:
675
content/core-concepts/events/event-reference/player-events.en.md
Normal file
675
content/core-concepts/events/event-reference/player-events.en.md
Normal 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;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user