Files
Documentation/content/world/player-refs.fr.md
2026-01-20 20:33:59 +01:00

6.2 KiB

title, type, weight
title type weight
PlayerRef docs 4

PlayerRef fournit un moyen thread-safe de référencer les joueurs à travers les mondes et les threads.

Pourquoi PlayerRef ?

{{< callout type="warning" >}} Les références directes à Player ne doivent jamais être stockées ou utilisées à travers les threads. Utilisez toujours PlayerRef pour :

  • Les opérations asynchrones
  • Le stockage de références de joueurs
  • Le suivi des joueurs entre mondes {{< /callout >}}

Obtenir un PlayerRef

import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import java.util.UUID;

Player player = ...;
PlayerRef ref = player.getPlayerRef();

// PlayerRef contient les données essentielles du joueur
UUID uuid = ref.getUuid();
String name = ref.getUsername();  // Note : getUsername(), PAS getName()

Utiliser PlayerRef dans le Code Async

import com.hypixel.hytale.server.core.event.events.player.PlayerConnectEvent;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.component.Ref;
import java.util.concurrent.CompletableFuture;

getEventRegistry().register(PlayerConnectEvent.class, event -> {
    PlayerRef ref = event.getPlayerRef();
    World world = event.getWorld();

    // Utiliser ref dans les opérations async
    CompletableFuture.runAsync(() -> {
        // Sûr d'utiliser ref ici
        PlayerData data = loadPlayerData(ref.getUuid());

        // Retourner au thread du monde pour interagir avec le joueur
        if (world != null) {
            world.execute(() -> {
                Ref<EntityStore> entityRef = ref.getReference();
                if (entityRef != null && entityRef.isValid()) {
                    applyData(entityRef, data);
                }
                // sendMessage est directement sur PlayerRef
                ref.sendMessage(Message.raw("Vos données ont été chargées !"));
            });
        }
    });
});

Méthodes de PlayerRef

PlayerRef ref = player.getPlayerRef();

// Obtenir l'UUID du joueur (toujours disponible)
UUID uuid = ref.getUuid();

// Obtenir le nom d'utilisateur du joueur (toujours disponible)
// Note : C'est getUsername(), PAS getName()
String name = ref.getUsername();

// Obtenir la référence d'entité
Ref<EntityStore> entityRef = ref.getReference();

// Vérifier si la référence est valide
boolean isValid = ref.isValid();

// Envoyer un message directement au joueur
ref.sendMessage(Message.raw("Bonjour !"));

// Obtenir le transform (position/rotation)
Transform transform = ref.getTransform();

{{< callout type="warning" >}} Note : PlayerRef.getPlayer() n'existe PAS. PlayerRef stocke les données essentielles qui survivent aux changements de monde, mais ne détient pas de référence Player directe. {{< /callout >}}

PlayerRefs du Monde

Les mondes fournissent l'accès aux PlayerRefs :

import com.hypixel.hytale.server.core.universe.Universe;
import java.util.Collection;
import java.util.List;

World world = Universe.get().getWorld("default");

// Obtenir tous les refs de joueurs dans ce monde
Collection<PlayerRef> playerRefs = world.getPlayerRefs();

// Obtenir tous les joueurs actifs (retourne List<Player>)
List<Player> players = world.getPlayers();

Stocker les Références de Joueurs

import com.hypixel.hytale.server.core.event.events.player.PlayerDisconnectEvent;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class MyPlugin extends JavaPlugin {
    // Stocker les PlayerRefs, PAS les Players
    private final Map<UUID, PlayerData> playerData = new ConcurrentHashMap<>();

    public MyPlugin(JavaPluginInit init) {
        super(init);
    }

    @Override
    public void setup() {
        getEventRegistry().register(PlayerConnectEvent.class, event -> {
            PlayerRef ref = event.getPlayerRef();
            playerData.put(ref.getUuid(), new PlayerData(ref));
        });

        getEventRegistry().register(PlayerDisconnectEvent.class, event -> {
            playerData.remove(event.getPlayerRef().getUuid());
        });
    }
}

class PlayerData {
    private final PlayerRef playerRef;
    private int score;

    public PlayerData(PlayerRef ref) {
        this.playerRef = ref;
    }

    public void addScore(int amount) {
        this.score += amount;
        playerRef.sendMessage(Message.raw("Score : " + score));
    }
}

Messagerie Inter-Mondes

// Envoyer un message au joueur peu importe son monde actuel
public void sendGlobalMessage(PlayerRef ref, String message) {
    // PlayerRef.sendMessage gère la messagerie inter-mondes directement
    ref.sendMessage(Message.raw(message));
}

// Diffuser à tous les joueurs dans tous les mondes
public void broadcastAll(String message) {
    Message msg = Message.raw(message);
    for (World world : Universe.get().getWorlds().values()) {
        for (PlayerRef ref : world.getPlayerRefs()) {
            ref.sendMessage(msg);
        }
    }
}

PlayerRef vs Player

Fonctionnalité Player PlayerRef
Thread-safe Non Oui
Stockable Non Oui
Inter-mondes Non Oui
Obtenir UUID Oui Oui
Obtenir Nom Oui (getDisplayName()) Oui (getUsername())
Envoyer Message Oui Oui (directement)
Obtenir Position Via TransformComponent Via getTransform()

Bonnes Pratiques

{{< callout type="info" >}} Utilisez toujours PlayerRef quand :

  • Vous stockez des références de joueurs au-delà de la méthode actuelle
  • Vous passez à des tâches asynchrones
  • Vous suivez les joueurs à travers les changements de monde
  • Vous construisez des structures de données liées aux joueurs {{< /callout >}}
// Bien : Stocker PlayerRef
private final Map<UUID, PlayerRef> trackedPlayers = new ConcurrentHashMap<>();

// Mauvais : Stocker Player directement
// private final Map<UUID, Player> players = new HashMap<>(); // NE FAITES PAS ÇA

// Bien : Utiliser ref en async
CompletableFuture.runAsync(() -> {
    PlayerRef ref = ...;
    // ref est sûr ici
});

// Mauvais : Utiliser Player en async
// CompletableFuture.runAsync(() -> {
//     Player player = ...;  // PAS SÛR
// });