Interface IdentityService


public interface IdentityService
Packet-level identity masking: what other clients are told a player is called and looks like.

Everything this service does is presentation. The masked player keeps their real UUID, their real profile, their real name on the server, their statistics and every stored record; only the packets leaving the server carry the alias and skin instead. Nothing is ever written to a profile, a head, a corpse, an item or a database, which is what makes a mask removable at any instant and impossible to leak into the next match.

Zentrix routes its own player-facing text through this service, so a mask reaches nametags, the tab list, chat, death and elimination messages, scoreboards, GUIs, teammate trackers, corpses, player heads and command suggestions without the caller doing anything else. Console output and debug logging deliberately keep the real name.

Example


 IdentityService identities = ZentrixAPI.get().getIdentityService();

 // Put a player behind an alias for the length of a match.
 IdentityHandle handle = identities.mask(
         this, game, player, MaskedIdentity.ofAlias("Player_7"));

 // Render somebody's name the way the match should see it.
 String shown = identities.getDisplayName(target.getUniqueId());

 // And take it off again; Zentrix would do this on its own at the end of the match.
 handle.release();
 

Every method is safe to call from the main thread. getDisplayName(UUID) and the mask* text helpers are also safe from other threads, because they only read the alias table.

Since:
1.6.0
  • Method Summary

    Modifier and Type
    Method
    Description
    @NotNull String
    getDisplayName(@Nullable UUID playerId)
    The name a player should be shown under: their alias while masked, their real name otherwise.
    @NotNull String
    getDisplayName(@Nullable org.bukkit.entity.Player player)
    The name a player should be shown under.
    getIdentity(@Nullable UUID playerId)
    The face a player is currently wearing, empty when they are not masked.
    @NotNull Collection<UUID>
    Every masked player on the server.
    @NotNull Collection<UUID>
    getMasked(@NotNull ZentrixGame game)
    Every masked player of one match.
    boolean
    isMasked(@Nullable UUID playerId)
     
    boolean
    Whether the packet layer needed for masking is available on this server.
    mask(@NotNull org.bukkit.plugin.Plugin owner, @NotNull ZentrixGame game, @NotNull org.bukkit.entity.Player player, @NotNull MaskedIdentity identity)
    Puts a player behind an alias and, when the identity carries one, a skin.
    @NotNull org.bukkit.inventory.ItemStack
    maskHead(@Nullable org.bukkit.inventory.ItemStack head)
    Rewrites a player head so it shows the masked owner's alias and skin instead of theirs.
    @NotNull String
    maskText(@Nullable String text)
    Replaces every masked player's real name in a piece of text with their alias.
    @NotNull net.kyori.adventure.text.Component
    maskText(@Nullable net.kyori.adventure.text.Component text)
    The component form of maskText(String), applied to every literal part.
    void
    refresh(@NotNull org.bukkit.entity.Player player)
    Re-sends a player's mask to everybody who can see them.
    @NotNull Optional<UUID>
    resolveAlias(@Nullable String alias)
    The player hiding behind an alias, empty when nobody is.
    boolean
    unmask(@NotNull UUID playerId)
    Removes a player's mask and restores their real profile and skin to everybody.
    int
    unmaskAll(@NotNull ZentrixGame game)
    Removes every mask belonging to one match.
    int
    unmaskAll(@NotNull org.bukkit.plugin.Plugin owner)
    Removes every mask a plugin applied, across every match.
  • Method Details

    • isSupported

      boolean isSupported()
      Whether the packet layer needed for masking is available on this server.

      False means every masking call is a no-op and names are shown unchanged, which is what a caller should check before promising players anonymity.

    • mask

      @NotNull @NotNull IdentityHandle mask(@NotNull @NotNull org.bukkit.plugin.Plugin owner, @NotNull @NotNull ZentrixGame game, @NotNull @NotNull org.bukkit.entity.Player player, @NotNull @NotNull MaskedIdentity identity)
      Puts a player behind an alias and, when the identity carries one, a skin.

      Applying a mask to an already masked player replaces the previous one and releases its handle. The mask survives respawning, revival, dimension transfers and reconnecting: Zentrix re-sends it whenever the client would otherwise see the real profile again.

      Parameters:
      owner - the plugin asking for the mask; its shutdown removes the mask again
      game - the match the mask belongs to; it is removed when that match ends
      player - the player to mask
      identity - the face to wear
      Returns:
      the handle, or an already-released handle when masking is unsupported
    • unmask

      boolean unmask(@NotNull @NotNull UUID playerId)
      Removes a player's mask and restores their real profile and skin to everybody.

      Idempotent, and safe for a player who is offline: the restoration is queued and enforced when they next connect.

      Returns:
      true when a mask was removed
    • unmaskAll

      int unmaskAll(@NotNull @NotNull ZentrixGame game)
      Removes every mask belonging to one match.
      Returns:
      how many masks were removed
    • unmaskAll

      int unmaskAll(@NotNull @NotNull org.bukkit.plugin.Plugin owner)
      Removes every mask a plugin applied, across every match.
      Returns:
      how many masks were removed
    • refresh

      void refresh(@NotNull @NotNull org.bukkit.entity.Player player)
      Re-sends a player's mask to everybody who can see them.

      Zentrix already does this after respawning, revival, world changes and reconnects. Call it yourself only after something outside Zentrix re-sent the real profile.

    • isMasked

      boolean isMasked(@Nullable @Nullable UUID playerId)
    • getIdentity

      @NotNull @NotNull Optional<MaskedIdentity> getIdentity(@Nullable @Nullable UUID playerId)
      The face a player is currently wearing, empty when they are not masked.
    • resolveAlias

      @NotNull @NotNull Optional<UUID> resolveAlias(@Nullable @Nullable String alias)
      The player hiding behind an alias, empty when nobody is. Compared case-insensitively.
    • getMasked

      @NotNull @NotNull Collection<UUID> getMasked(@NotNull @NotNull ZentrixGame game)
      Every masked player of one match.
    • getMasked

      @NotNull @NotNull Collection<UUID> getMasked()
      Every masked player on the server.
    • getDisplayName

      @NotNull @NotNull String getDisplayName(@Nullable @Nullable UUID playerId)
      The name a player should be shown under: their alias while masked, their real name otherwise.

      This is the one call every piece of player-facing text needs. It never returns null, and falls back to the last known real name for a player who is offline.

    • getDisplayName

      @NotNull @NotNull String getDisplayName(@Nullable @Nullable org.bukkit.entity.Player player)
      The name a player should be shown under.
    • maskText

      @NotNull @NotNull String maskText(@Nullable @Nullable String text)
      Replaces every masked player's real name in a piece of text with their alias.

      For text that was already assembled from names — a death message, a scoreboard line, a formatted chat line — where the individual names are no longer separable. Whole words only, so a name that happens to be a substring of another word is left alone.

    • maskText

      @NotNull @NotNull net.kyori.adventure.text.Component maskText(@Nullable @Nullable net.kyori.adventure.text.Component text)
      The component form of maskText(String), applied to every literal part.
    • maskHead

      @NotNull @NotNull org.bukkit.inventory.ItemStack maskHead(@Nullable @Nullable org.bukkit.inventory.ItemStack head)
      Rewrites a player head so it shows the masked owner's alias and skin instead of theirs.

      The item is copied, never edited in place, and an item that is not a head or whose owner is not masked is returned unchanged. Use this wherever a head is about to be shown to players; the stored item keeps the real owner, so nothing false is ever persisted.