---
title: Événements Serveur
type: docs
weight: 6
---

Événements liés au cycle de vie du serveur, aux plugins et aux opérations système.

## Événements du Cycle de Vie du Serveur

### BootEvent

Déclenché quand le serveur finit de démarrer. C'est un événement marqueur sans champs.

**Package :** `com.hypixel.hytale.server.core.event.events`

{{< tabs items="Champs,Exemple" >}}
{{< tab >}}
Cet événement n'a pas de champs. C'est une simple notification que le démarrage est terminé.
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(BootEvent.class, event -> {
    getLogger().at(Level.INFO).log("Démarrage du serveur terminé !");

    // Initialiser les fonctionnalités post-démarrage
    initializeMetrics();
    startBackgroundTasks();
    openConnectionsToExternalServices();
});
```
{{< /tab >}}
{{< /tabs >}}

---

### ShutdownEvent

Déclenché quand le serveur s'arrête. C'est un événement marqueur avec des constantes de priorité.

**Package :** `com.hypixel.hytale.server.core.event.events`

{{< tabs items="Constantes,Exemple" >}}
{{< tab >}}
| Constante | Valeur | Description |
|-----------|--------|-------------|
| `DISCONNECT_PLAYERS` | -48 | Priorité pour déconnecter les joueurs |
| `UNBIND_LISTENERS` | -40 | Priorité pour délier les listeners réseau |
| `SHUTDOWN_WORLDS` | -32 | Priorité pour arrêter les mondes |

Utilisez ces constantes avec `EventPriority` pour ordonner les handlers d'arrêt.
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(ShutdownEvent.class, event -> {
    getLogger().at(Level.INFO).log("Arrêt du serveur !");

    // Effectuer le nettoyage
    saveAllPlayerData();
    closeExternalConnections();
    flushMetrics();
});

// Utiliser les constantes de priorité pour l'ordre
getEventRegistry().register(
    ShutdownEvent.DISCONNECT_PLAYERS,
    ShutdownEvent.class,
    event -> {
        // Notifier les joueurs avant la déconnexion
        Universe.get().getPlayers().forEach(player ->
            player.sendMessage(Message.raw("Le serveur s'arrête !"))
        );
    }
);
```
{{< /tab >}}
{{< /tabs >}}

{{< callout type="warning" >}}
**Important :** Gardez les handlers d'arrêt rapides et synchrones. Le serveur peut forcer l'arrêt si les handlers prennent trop de temps.
{{< /callout >}}

---

## Événements de Plugin

### PluginSetupEvent

Déclenché quand un plugin est en cours de configuration (avant le démarrage).

**Package :** `com.hypixel.hytale.server.core.event.events.plugin`

{{< tabs items="Champs,Méthodes,Exemple" >}}
{{< tab >}}
| Champ | Type | Description |
|-------|------|-------------|
| plugin | `JavaPlugin` | Le plugin en configuration |
| pluginInfo | `PluginInfo` | Métadonnées du plugin |
{{< /tab >}}
{{< tab >}}
- `getPlugin()` - Retourne l'instance du plugin
- `getPluginInfo()` - Retourne les métadonnées du plugin
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(PluginSetupEvent.class, event -> {
    PluginInfo info = event.getPluginInfo();

    getLogger().at(Level.INFO).log("Configuration du plugin : " + info.getName() +
        " v" + info.getVersion());

    // Vérifier les dépendances du plugin
    if (isDependencyPlugin(info.getName())) {
        registerDependencyHooks(event.getPlugin());
    }
});
```
{{< /tab >}}
{{< /tabs >}}

---

### PluginEnableEvent

Déclenché quand un plugin est activé.

**Package :** `com.hypixel.hytale.server.core.event.events.plugin`

{{< tabs items="Champs,Méthodes,Exemple" >}}
{{< tab >}}
| Champ | Type | Description |
|-------|------|-------------|
| plugin | `JavaPlugin` | Le plugin activé |
{{< /tab >}}
{{< tab >}}
- `getPlugin()` - Retourne l'instance du plugin
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(PluginEnableEvent.class, event -> {
    JavaPlugin plugin = event.getPlugin();

    getLogger().at(Level.INFO).log("Plugin activé : " + plugin.getName());

    // Se connecter à d'autres plugins
    if (plugin.getName().equals("Economy")) {
        hookEconomyPlugin(plugin);
    }
});
```
{{< /tab >}}
{{< /tabs >}}

---

### PluginDisableEvent

Déclenché quand un plugin est désactivé.

**Package :** `com.hypixel.hytale.server.core.event.events.plugin`

{{< tabs items="Champs,Méthodes,Exemple" >}}
{{< tab >}}
| Champ | Type | Description |
|-------|------|-------------|
| plugin | `JavaPlugin` | Le plugin désactivé |
{{< /tab >}}
{{< tab >}}
- `getPlugin()` - Retourne l'instance du plugin
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(PluginDisableEvent.class, event -> {
    JavaPlugin plugin = event.getPlugin();

    getLogger().at(Level.INFO).log("Plugin désactivé : " + plugin.getName());

    // Se déconnecter des autres plugins
    if (plugin.getName().equals("Economy")) {
        unhookEconomyPlugin();
    }
});
```
{{< /tab >}}
{{< /tabs >}}

---

## Événements de Tick

### ServerTickEvent

Déclenché à chaque tick serveur (typiquement 20 fois par seconde).

**Package :** `com.hypixel.hytale.server.core.event.events.server`

{{< tabs items="Champs,Méthodes,Exemple" >}}
{{< tab >}}
| Champ | Type | Description |
|-------|------|-------------|
| tickNumber | `long` | Numéro du tick actuel |
| deltaTime | `float` | Temps depuis le dernier tick (secondes) |
{{< /tab >}}
{{< tab >}}
- `getTickNumber()` - Retourne le compte de ticks actuel
- `getDeltaTime()` - Retourne le delta time en secondes
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(ServerTickEvent.class, event -> {
    long tick = event.getTickNumber();

    // Exécuter toutes les secondes (20 ticks)
    if (tick % 20 == 0) {
        updateScoreboards();
    }

    // Exécuter toutes les minutes (1200 ticks)
    if (tick % 1200 == 0) {
        saveAutoSave();
        cleanupExpiredData();
    }
});
```
{{< /tab >}}
{{< /tabs >}}

{{< callout type="warning" >}}
**Performance Critique :** Cet événement se déclenche 20 fois par seconde. Gardez les handlers extrêmement légers. Utilisez le comptage de ticks pour les tâches périodiques au lieu de s'exécuter à chaque tick.
{{< /callout >}}

---

## Événements de Commande

### CommandExecuteEvent

{{< badge "Annulable" >}}

Déclenché quand une commande est exécutée.

**Package :** `com.hypixel.hytale.server.core.event.events.command`

{{< tabs items="Champs,Méthodes,Exemple" >}}
{{< tab >}}
| Champ | Type | Description |
|-------|------|-------------|
| sender | `CommandSender` | Qui a exécuté la commande |
| command | `String` | Nom de la commande |
| args | `String[]` | Arguments de la commande |
{{< /tab >}}
{{< tab >}}
- `getSender()` - Retourne l'expéditeur de la commande
- `getCommand()` - Retourne le nom de la commande
- `getArgs()` - Retourne le tableau d'arguments
- `isCancelled()` - Vérifie si annulé
- `setCancelled(boolean)` - Annule la commande
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(CommandExecuteEvent.class, event -> {
    CommandSender sender = event.getSender();
    String command = event.getCommand();

    // Logger toutes les commandes
    getLogger().at(Level.INFO).log(sender.getName() + " a exécuté : /" + command +
        " " + String.join(" ", event.getArgs()));

    // Bloquer certaines commandes pour les non-ops
    if (command.equals("stop") && !sender.isOp()) {
        event.setCancelled(true);
        sender.sendMessage("Vous n'avez pas la permission !");
    }
});
```
{{< /tab >}}
{{< /tabs >}}

---

## Exemples Pratiques

### Plugin de Métriques Serveur

```java
public class MetricsPlugin extends JavaPlugin {

    private long startTime;
    private long tickCount = 0;
    private long lastTickTime;

    @Override
    public void start() {
        // Suivre le démarrage du serveur
        getEventRegistry().register(BootEvent.class, event -> {
            startTime = System.currentTimeMillis();
            lastTickTime = startTime;
            getLogger().at(Level.INFO).log("Démarrage terminé, suivi des métriques...");
        });

        // Calculer les TPS
        getEventRegistry().register(ServerTickEvent.class, event -> {
            tickCount++;

            // Calculer les TPS toutes les secondes
            if (tickCount % 20 == 0) {
                long now = System.currentTimeMillis();
                long elapsed = now - lastTickTime;
                double tps = 20000.0 / elapsed;
                lastTickTime = now;

                if (tps < 18.0) {
                    getLogger().warning("TPS faibles : " + String.format("%.2f", tps));
                }
            }
        });

        // Sauvegarder les métriques à l'arrêt
        getEventRegistry().register(ShutdownEvent.class, event -> {
            long uptime = System.currentTimeMillis() - startTime;
            saveMetrics(uptime, tickCount);
        });
    }
}
```

### Gestionnaire de Dépendances de Plugins

```java
public class DependencyPlugin extends JavaPlugin {

    private final Map<String, JavaPlugin> loadedDependencies = new HashMap<>();
    private final Set<String> requiredPlugins = Set.of("Economy", "Permissions");

    @Override
    public void start() {
        // Suivre le chargement des plugins
        getEventRegistry().register(PluginEnableEvent.class, event -> {
            JavaPlugin plugin = event.getPlugin();

            if (requiredPlugins.contains(plugin.getName())) {
                loadedDependencies.put(plugin.getName(), plugin);
                getLogger().at(Level.INFO).log("Dépendance chargée : " + plugin.getName());

                // Vérifier si toutes les dépendances sont chargées
                if (loadedDependencies.keySet().containsAll(requiredPlugins)) {
                    initializeDependentFeatures();
                }
            }
        });

        // Gérer le déchargement de dépendance
        getEventRegistry().register(PluginDisableEvent.class, event -> {
            JavaPlugin plugin = event.getPlugin();

            if (loadedDependencies.remove(plugin.getName()) != null) {
                getLogger().warning("Dépendance déchargée : " + plugin.getName());
                disableDependentFeatures();
            }
        });
    }
}
```

### Journalisation & Limitation de Débit des Commandes

```java
public class CommandSecurityPlugin extends JavaPlugin {

    private final Map<UUID, List<Long>> commandHistory = new HashMap<>();
    private static final int MAX_COMMANDS_PER_SECOND = 5;

    @Override
    public void start() {
        getEventRegistry().register(CommandExecuteEvent.class, event -> {
            CommandSender sender = event.getSender();

            // Ne limiter que les joueurs
            if (!(sender instanceof Player)) return;

            Player player = (Player) sender;
            UUID uuid = player.getUuid();

            // Obtenir l'historique des commandes
            List<Long> history = commandHistory.computeIfAbsent(
                uuid, k -> new ArrayList<>()
            );

            long now = System.currentTimeMillis();

            // Supprimer les anciennes entrées (plus d'1 seconde)
            history.removeIf(time -> now - time > 1000);

            // Vérifier la limite de débit
            if (history.size() >= MAX_COMMANDS_PER_SECOND) {
                event.setCancelled(true);
                player.sendMessage("Trop de commandes ! Veuillez ralentir.");
                getLogger().warning("Limité : " + player.getDisplayName());
                return;
            }

            // Enregistrer cette commande
            history.add(now);

            // Logger dans un fichier
            logCommand(player, event.getCommand(), event.getArgs());
        });

        // Nettoyer à la déconnexion
        getEventRegistry().register(PlayerDisconnectEvent.class, event -> {
            commandHistory.remove(event.getPlayer().getUuid());
        });
    }
}
```

### Gestionnaire de Tâches Planifiées

```java
public class SchedulerPlugin extends JavaPlugin {

    private final List<ScheduledTask> tasks = new ArrayList<>();

    @Override
    public void start() {
        // Planifier diverses tâches
        scheduleTask("autosave", 6000, this::autoSave);      // Toutes les 5 minutes
        scheduleTask("cleanup", 72000, this::cleanup);        // Toutes les heures
        scheduleTask("broadcast", 12000, this::broadcast);    // Toutes les 10 minutes

        // Exécuter les tâches selon le tick
        getEventRegistry().register(ServerTickEvent.class, event -> {
            long tick = event.getTickNumber();

            for (ScheduledTask task : tasks) {
                if (tick % task.interval() == 0) {
                    try {
                        task.runnable().run();
                    } catch (Exception e) {
                        getLogger().error("Tâche échouée : " + task.name(), e);
                    }
                }
            }
        });
    }

    private void scheduleTask(String name, int intervalTicks, Runnable runnable) {
        tasks.add(new ScheduledTask(name, intervalTicks, runnable));
    }

    record ScheduledTask(String name, int interval, Runnable runnable) {}
}
```

## Bonnes Pratiques

{{< callout type="info" >}}
**Directives pour les Événements Serveur :**
- Gardez les handlers de `ShutdownEvent` rapides et fiables
- Utilisez le comptage de ticks dans `ServerTickEvent` pour les tâches périodiques
- Nettoyez les ressources dans `PluginDisableEvent`
- Initialisez les fonctionnalités inter-plugins dans `PluginEnableEvent`
- Loggez les exécutions de commandes importantes pour l'audit
{{< /callout >}}

{{< callout type="error" >}}
**Critique :** Ne jamais effectuer d'opérations bloquantes (I/O, réseau, base de données) directement dans `ServerTickEvent`. Utilisez des tâches asynchrones à la place.
{{< /callout >}}
