Class VoiceModule

All Implemented Interfaces:
CommandOwner

public class VoiceModule extends JavaPlugin
Server-side voice chat module. Routes player voice to nearby listeners by proximity, and exposes the plugin voice-emit API (openEntityVoice(Ref), openPositionalVoice(World, Vector3d), openDirectVoice(Collection)) for emitting Opus streams from entity-tracked, fixed-position, and non-spatial direct sources.
  • Field Details

  • Constructor Details

  • Method Details

    • get

      public static VoiceModule get()
    • scheduleImmediatePositionUpdate

      public void scheduleImmediatePositionUpdate(@Nonnull PlayerRef playerRef)
      Schedules an immediate position cache update for a player. This ensures the player's position is available for voice routing right away, without waiting for the periodic position update task (~100ms). Called on player connect and on respawn after death.
    • getPlayerState

      @Nullable public VoicePlayerState getPlayerState(@Nonnull UUID playerId)
      Gets the voice state for a player.
    • setPlayerVoiceChannel

      public void setPlayerVoiceChannel(@Nonnull UUID playerId, @Nullable String channel)
      Assigns a player to a named voice channel, or clears the assignment when channel is null.

      A speaker with a channel is heard only by that channel's members, and channel-less speech stays public. Channel membership does not restrict what the player hears: members still hear public world speech around them. Explicit delivery chosen by an interceptor bypasses channels.

      Parameters:
      playerId - the player to assign
      channel - the channel name, or null to make the player's speech public again
    • getVoiceRouter

      public VoiceRouter getVoiceRouter()
      Gets the voice router for routing voice packets.
    • addPlayerVoiceInterceptor

      @Nonnull public Registration addPlayerVoiceInterceptor(@Nonnull PlayerVoiceInterceptor interceptor)
      Registers a hook invoked for each inbound player voice frame, letting a plugin observe, rewrite, re- route, or drop it, at EventPriority.NORMAL priority. See addPlayerVoiceInterceptor(EventPriority, PlayerVoiceInterceptor) to control ordering.
      Parameters:
      interceptor - the hook to install
      Returns:
      a handle whose Registration.unregister() removes the interceptor. Call it from the plugin's shutdown(), or the interceptor keeps running and pins the plugin in memory
    • addPlayerVoiceInterceptor

      @Nonnull public Registration addPlayerVoiceInterceptor(@Nonnull EventPriority priority, @Nonnull PlayerVoiceInterceptor interceptor)
      Registers a hook invoked for each inbound player voice frame at the given priority. Interceptors run from EventPriority.FIRST to EventPriority.LAST, and ties run in registration order, so a LAST interceptor sees the audience and audio that earlier ones chose and gets the final say. See PlayerVoiceInterceptor for the threading and safety contract and PlayerVoiceFrame for the controls.
      Parameters:
      priority - when this interceptor runs relative to the others
      interceptor - the hook to install
      Returns:
      a handle whose Registration.unregister() removes the interceptor. Call it from the plugin's shutdown(), or the interceptor keeps running and pins the plugin in memory
    • openEntityVoice

      @Nonnull public VoiceSpeaker openEntityVoice(@Nonnull Ref<EntityStore> entity)
      Opens a voice stream that follows an entity, heard by nearby players. The entity's network id drives the overhead speaking indicator and the speaker auto-closes when the entity despawns. Push Opus frames via VoiceSpeaker.pushOpus(byte[]) and VoiceSpeaker.close() when done.

      The entity's position is sampled immediately so a clip started right away is spatialized; any frame pushed in the brief window before that first sample completes is dropped.

      Parameters:
      entity - the entity the speaker follows; the speaker auto-closes when it despawns
      Returns:
      a handle for pushing Opus frames and closing the stream
    • openPositionalVoice

      @Nonnull public PositionalVoiceSpeaker openPositionalVoice(@Nonnull World world, @Nonnull org.joml.Vector3d position)
      Opens a voice stream at a world position, heard by nearby players. Move it afterwards with PositionalVoiceSpeaker.setPosition(Vector3d). Does not apply the underwater muffle. Only entity speakers sample fluid state.
      Parameters:
      world - the world the speaker emits in
      position - the initial emit position; movable later via PositionalVoiceSpeaker.setPosition(Vector3d)
      Returns:
      a positional speaker handle for pushing Opus frames, moving the source, and closing the stream
      Throws:
      IllegalArgumentException - if any coordinate of position is not finite
    • openDirectVoice

      @Nonnull public VoiceSpeaker openDirectVoice(@Nonnull Collection<UUID> listeners)
      Opens a non-spatial voice stream delivered to exactly the given players (any world, no distance falloff), playing at the listener.

      The listener set is copied and fixed at open time; there is no add/remove API, so changing membership means closing this speaker and opening a new one.

      Parameters:
      listeners - the players to deliver to; copied on open, must contain no null elements
      Returns:
      a handle for pushing Opus frames and closing the stream
      Throws:
      NullPointerException - if listeners contains a null element
    • isVoiceEnabled

      public boolean isVoiceEnabled()
      Checks if voice is enabled on the server.
    • setVoiceEnabled

      public void setVoiceEnabled(boolean enabled)
      Sets whether voice is enabled on the server.
    • isDeadPlayersCanHear

      public boolean isDeadPlayersCanHear()
      Checks if dead players can hear living players' voice. Configurable per-server; defaults to false for competitive integrity.
    • getMaxHearingDistance

      public float getMaxHearingDistance()
      Gets the maximum distance at which voice can be heard.
    • setMaxHearingDistance

      public void setMaxHearingDistance(float distance)
      Sets the maximum hearing distance.
    • getReferenceDistance

      public float getReferenceDistance()
      Gets the full volume distance (distance at which voice is heard at 100% volume).
    • setReferenceDistance

      public void setReferenceDistance(float distance)
      Sets the full volume distance.
    • isPlayerMuted

      public boolean isPlayerMuted(@Nonnull UUID playerId)
      Checks if a player is globally muted on the server.
    • mutePlayer

      public boolean mutePlayer(@Nonnull UUID playerId)
      Globally mutes a player on the server.
      Returns:
      true if the player was muted, false if already muted
    • unmutePlayer

      public boolean unmutePlayer(@Nonnull UUID playerId)
      Unmutes a globally muted player.
      Returns:
      true if the player was unmuted, false if not muted
    • getGloballyMutedPlayers

      public Set<UUID> getGloballyMutedPlayers()
      Gets the set of globally muted players.
    • getMaxPacketsPerSecond

      public int getMaxPacketsPerSecond()
      Gets the max packets per second for rate limiting.
    • getBurstCapacity

      public int getBurstCapacity()
      Gets the burst capacity for token bucket rate limiting.
    • getMaxPacketSize

      public int getMaxPacketSize()
      Gets the max packet size for validation.
    • getCachedPosition

      @Nullable public VoiceModule.PositionSnapshot getCachedPosition(@Nonnull UUID playerId)
      Gets a cached position snapshot for a player. Thread-safe for use from voice executor.
    • getVoiceExecutor

      public ExecutorService getVoiceExecutor(@Nonnull UUID speakerId)
      Gets the voice executor for routing voice packets off the WorldThread. Partitions by speaker UUID to maintain per-speaker ordering while parallelizing across speakers.
    • isShutdown

      public boolean isShutdown()
      Whether the module has been shut down.
    • getPlayerStates

      public Map<UUID, VoicePlayerState> getPlayerStates()
      Gets the map of player states (thread-safe).