Sistema Eventi
Cos’è il Sistema Eventi?
Gli eventi in Spigot/Paper permettono al tuo plugin di reagire a ciò che accade nel server: giocatori che si connettono, blocchi che vengono rotti, mob che spawnano, ecc. È il meccanismo principale per aggiungere funzionalità custom.
Registrare un Listener
1. Creare la Classe Listener
```java public class PlayerListener implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
player.sendMessage("§aBenvenuto, " + player.getName() + "!");
}
} ```
2. Registrare il Listener
Nella classe principale del plugin:
```java public class MyPlugin extends JavaPlugin {
@Override
public void onEnable() {
// Registra il listener
getServer().getPluginManager().registerEvents(new PlayerListener(), this);
}
} ```
Event Handler
Annotazione @EventHandler
```java @EventHandler public void onBlockBreak(BlockBreakEvent event) { // Codice eseguito quando un blocco viene rotto } ```
Priorità degli Eventi
Controlla l’ordine di esecuzione quando più plugin ascoltano lo stesso evento:
```java @EventHandler(priority = EventPriority.HIGHEST) public void onPlayerDeath(PlayerDeathEvent event) { // Eseguito per ultimo (dopo altri plugin) } ```
Ordini di priorità (dal primo all’ultimo):
LOWESTLOWNORMAL(default)HIGHHIGHESTMONITOR(solo per osservare, NON modificare l’evento)
ignoreCancelled
Ignora l’evento se è già stato cancellato da un altro plugin:
```java @EventHandler(ignoreCancelled = true) public void onBlockPlace(BlockPlaceEvent event) { // Non viene eseguito se l’evento è già stato cancellato } ```
Eventi Comuni
Eventi Giocatore
```java // Join/Quit @EventHandler public void onJoin(PlayerJoinEvent event) { Player player = event.getPlayer(); event.setJoinMessage(“§e” + player.getName() + " è entrato!"); }
@EventHandler public void onQuit(PlayerQuitEvent event) { event.setQuitMessage(“§e” + event.getPlayer().getName() + " è uscito!"); }
// Chat @EventHandler public void onChat(AsyncPlayerChatEvent event) { String message = event.getMessage();
// Blocca parolacce
if (message.contains("parolaccia")) {
event.setCancelled(true);
event.getPlayer().sendMessage("§cLinguaggio inappropriato!");
}
}
// Movimento @EventHandler public void onMove(PlayerMoveEvent event) { Location from = event.getFrom(); Location to = event.getTo();
// Controlla se il giocatore si è spostato di almeno 1 blocco
if (from.getBlockX() != to.getBlockX() ||
from.getBlockY() != to.getBlockY() ||
from.getBlockZ() != to.getBlockZ()) {
// Giocatore si è mosso
}
}
// Morte @EventHandler public void onDeath(PlayerDeathEvent event) { Player player = event.getEntity(); event.setDeathMessage(player.getName() + " è morto in modo epico!");
// Mantieni l'inventario
event.setKeepInventory(true);
event.setKeepLevel(true);
} ```
Eventi Blocchi
```java // Rottura blocco @EventHandler public void onBlockBreak(BlockBreakEvent event) { Block block = event.getBlock(); Player player = event.getPlayer();
// Impedisci di rompere diamanti
if (block.getType() == Material.DIAMOND_ORE) {
event.setCancelled(true);
player.sendMessage("§cNon puoi rompere diamanti!");
}
}
// Piazzamento blocco @EventHandler public void onBlockPlace(BlockPlaceEvent event) { Block block = event.getBlock();
// Impedisci di piazzare TNT
if (block.getType() == Material.TNT) {
event.setCancelled(true);
event.getPlayer().sendMessage("§cTNT disabilitato!");
}
}
// Crescita piante @EventHandler public void onCropGrow(BlockGrowEvent event) { // Velocizza la crescita (esempio: cancella l’evento e fai crescere istantaneamente) event.getBlock().setType(Material.WHEAT); // Esempio semplificato } ```
Eventi Entità
```java // Spawn mob @EventHandler public void onCreatureSpawn(CreatureSpawnEvent event) { // Impedisci spawn di creeper if (event.getEntityType() == EntityType.CREEPER) { event.setCancelled(true); } }
// Danno entità @EventHandler public void onEntityDamage(EntityDamageEvent event) { // Impedisci danni da caduta if (event.getCause() == EntityDamageEvent.DamageCause.FALL) { event.setCancelled(true); } }
// Morte mob @EventHandler public void onEntityDeath(EntityDeathEvent event) { LivingEntity entity = event.getEntity();
// Drop custom per zombie
if (entity.getType() == EntityType.ZOMBIE) {
event.getDrops().clear();
event.getDrops().add(new ItemStack(Material.DIAMOND, 1));
}
} ```
Eventi Inventario
```java // Click inventario @EventHandler public void onInventoryClick(InventoryClickEvent event) { Player player = (Player) event.getWhoClicked(); ItemStack item = event.getCurrentItem();
// Impedisci di spostare item specifici
if (item != null && item.getType() == Material.BEDROCK) {
event.setCancelled(true);
player.sendMessage("§cNon puoi spostare questo item!");
}
}
// Crafting @EventHandler public void onCraft(CraftItemEvent event) { ItemStack result = event.getRecipe().getResult();
// Impedisci crafting di TNT
if (result.getType() == Material.TNT) {
event.setCancelled(true);
event.getWhoClicked().sendMessage("§cCrafting TNT disabilitato!");
}
} ```
Cancellare Eventi
Molti eventi sono Cancellable, permettendoti di impedire che accadano:
```java @EventHandler public void onBlockBreak(BlockBreakEvent event) { if (!event.getPlayer().hasPermission(“myplugin.break”)) { event.setCancelled(true); // Impedisce la rottura del blocco event.getPlayer().sendMessage(“§cNon hai il permesso!”); } } ```
Eventi Custom
Puoi creare i tuoi eventi personalizzati:
```java public class CustomEvent extends Event implements Cancellable { private static final HandlerList HANDLERS = new HandlerList(); private boolean cancelled = false; private final Player player; private final String message;
public CustomEvent(Player player, String message) {
this.player = player;
this.message = message;
}
public Player getPlayer() {
return player;
}
public String getMessage() {
return message;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
@Override
public HandlerList getHandlers() {
return HANDLERS;
}
public static HandlerList getHandlerList() {
return HANDLERS;
}
} ```
Chiamare l’Evento Custom
```java CustomEvent event = new CustomEvent(player, “Hello!”); Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) { // L’evento non è stato cancellato, procedi } ```
Best Practices
- Usa EventPriority.MONITOR solo per osservare: Non modificare l’evento in MONITOR
- Controlla null: Alcuni metodi degli eventi possono restituire
null - Ottimizza eventi frequenti: Eventi come
PlayerMoveEventvengono chiamati molto spesso, evita operazioni pesanti - ignoreCancelled = true: Usa quando non vuoi gestire eventi già cancellati
- Eventi async:
AsyncPlayerChatEventè async, fai attenzione con operazioni non thread-safe
Errori Comuni
Listener non registrato
// SBAGLIATO: dimenticato di registrare
new PlayerListener(); // Non fa nulla!
// CORRETTO
getServer().getPluginManager().registerEvents(new PlayerListener(), this);
Dimenticare @EventHandler
// SBAGLIATO: manca @EventHandler
public void onJoin(PlayerJoinEvent event) { }
// CORRETTO
@EventHandler
public void onJoin(PlayerJoinEvent event) { }
Modificare eventi in MONITOR
// SBAGLIATO: modifica in MONITOR
@EventHandler(priority = EventPriority.MONITOR)
public void onBreak(BlockBreakEvent event) {
event.setCancelled(true); // Non farlo in MONITOR!
}
Conclusione
Il sistema eventi è il cuore di ogni plugin Spigot/Paper. Padroneggiare gli eventi ti permette di creare plugin potenti e reattivi che si integrano perfettamente con il gameplay di Minecraft.