6.2 KiB
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
// });