SocketSvcModApi - SocketSVC Docs
SocketSVC Docs

SocketSvcModApi

Spatial speaker API for Fabric/NeoForge/Forge server mods - the mod-side equivalent of the Paper plugin's SocketSvcApi, identifying callers by mod id instead of a Bukkit plugin.

Generated from source

Interface com.socketsvc.api.SocketSvcModApi — generated from SocketSvcModApi.java. Edit the Javadoc in the Java source, then run pnpm gen:api.

package com.socketsvc.api;

public interface SocketSvcModApi { ... }

Spatial speaker API for Fabric/NeoForge/Forge server mods - the mod-side equivalent of the Paper plugin's SocketSvcApi, identifying callers by mod id instead of a Bukkit plugin. The channel, position and PCM types are shared with Paper, so addon logic ports unchanged.

Look it up lazily with #get(); it is null until the dedicated server has started and SocketSVC's listener is up, and becomes null again when the server stops.

Constants

ConstantDescription
int API_VERSION = 42 added the voice group methods; 3 added the voice mute and client-presence methods; 4 added the microphone tap. Each addition is appended to the bottom of this interface and documented with the version that brought it.

Methods

get

static SocketSvcModApi get()

register

static void register(SocketSvcModApi api)

Called by SocketSVC itself; not for addons.

createLocationalChannel

LocationalAudioChannel createLocationalChannel(String ownerModId, SpatialPosition position, SpatialSettings settings)

createLocationalChannel

LocationalAudioChannel createLocationalChannel(String ownerModId, UUID id, String name, SpatialPosition position, SpatialSettings settings)

supportsSpatialAudio

boolean supportsSpatialAudio(UUID player)

Whether player's client negotiated spatial audio.

closeOwner

void closeOwner(String ownerModId)

Closes every channel ownerModId created.

placeholder

default String placeholder(UUID viewer, String identifier)

Resolves a SocketSVC placeholder identifier - the same set served as %socketsvc:<identifier>% through Text Placeholder API, documented under "Placeholders" in the server docs.

For mods that want the values without a placeholder framework in between, or on a loader where none is installed. Safe to call from any thread.

ParameterDescription
viewerthe player to answer player-scoped identifiers about, or null

Returns: the value, or null if the identifier is not one of SocketSVC's

isVoiceGroupsEnabled

default boolean isVoiceGroupsEnabled()

Whether the operator has switched voice groups on.

voiceGroups

default java.util.List<VoiceGroupInfo> voiceGroups()

Every live group, ordered by name. Empty while groups are disabled.

voiceGroupOf

default VoiceGroupInfo voiceGroupOf(UUID player)

The group player is in, or null.

voiceGroup

default VoiceGroupInfo voiceGroup(UUID groupId)

One group by id, or null if it has been disbanded.

createVoiceGroup

default UUID createVoiceGroup(String name, String password, VoiceGroupType type)

Creates a group with no members.

Created groups are persistent, because a group with nobody in it and no persistence would be disbanded the instant it was made. The per-player policy switches (allow-player-created, allow-passwords, allow-persistent) do not apply here: they exist to restrain players, and an addon is the operator's own code.

ParameterDescription
passwordnull for a group anyone may join

Returns: the new group's id, or null if it was refused (name taken, invalid, or the server is already at groups.max-groups)

addToVoiceGroup

default boolean addToVoiceGroup(UUID player, UUID groupId)

Puts player in groupId without asking for its password, leaving whichever group they were in. False if the group is gone or full.

removeFromVoiceGroup

default boolean removeFromVoiceGroup(UUID player)

Takes player out of whatever group they are in. False if they were in none.

removeVoiceGroup

default boolean removeVoiceGroup(UUID groupId)

Disbands a group, whoever is in it. False if it was already gone.

setVoiceGroupType

default boolean setVoiceGroupType(UUID groupId, VoiceGroupType type)

Changes a live group's type; audible immediately, on the next relayed frame.

isVoiceMuted

default boolean isVoiceMuted(UUID player)

Whether player may not talk right now, for any reason - an individual mute or the server-wide one they are not exempt from. This is the question a chat or moderation addon actually wants; #voiceMute answers the narrower one.

voiceMute

default VoiceMuteInfo voiceMute(UUID player)

The individual mute against player, or null - including when they are silenced only by the server-wide mute.

voiceMutes

default java.util.List<VoiceMuteInfo> voiceMutes()

Every individual mute, longest-standing first.

muteVoice

default boolean muteVoice(UUID player, long durationMillis, String reason, String moderator)

Mutes player, replacing any mute already against them.

ParameterDescription
durationMillishow long it lasts, or 0 for a mute that stands until lifted
reasonshown to the muted player; null for none. Trimmed, capped at 200 characters, and refused if it carries control characters
moderatorrecorded on the mute and shown in /ssvc-server mutes; null for an addon that would rather not say

Returns: whether anything changed. False when the player already held exactly this mute, or when they hold socketsvc.mute.exempt

unmuteVoice

default boolean unmuteVoice(UUID player)

Lifts an individual mute. False if there was none. Does not touch the server-wide mute.

isEveryoneVoiceMuted

default boolean isEveryoneVoiceMuted()

Whether everybody without socketsvc.mute.exempt is currently silenced.

setEveryoneVoiceMuted

default boolean setEveryoneVoiceMuted(boolean muted)

Silences, or stops silencing, everybody without socketsvc.mute.exempt.

Returns: whether this changed anything

voiceClientState

default VoiceClientState voiceClientState(UUID player)

Whether player is running the SocketSVC client mod.

Answered from plugin-channel registration - the same question SocketSVC already asks before it sends that player a handshake - and deliberately not from whether they have a live voice session, which also depends on the voice port being reachable from where they are.

Three states, because for a moment after somebody joins the honest answer is that nobody knows yet: see VoiceClientState. An addon that acts on ABSENT should say what it does about UNKNOWN rather than treating it as a no.

hasVoiceClient

default boolean hasVoiceClient(UUID player)

#voiceClientState collapsed to the one state most callers want. false for a player nobody has heard from yet, so do not use this to decide whether to refuse somebody - voiceClientState is the one that can tell "no" from "not yet".

requiresVoiceClient

default boolean requiresVoiceClient()

Whether this server refuses players without the client mod (require-client.enabled). Off unless an operator switched it on.

isMicrophoneTapEnabled

default boolean isMicrophoneTapEnabled()

Whether the operator has switched microphone taps on (microphone-tap.enabled). Check this once and hide your own feature rather than letting #subscribeMicrophone throw.

subscribeMicrophone

default MicrophoneTapHandle subscribeMicrophone(String ownerModId, MicrophoneTap.Format format, MicrophoneTap tap)

Receives every microphone frame from every player who holds socketsvc.bridge, until the returned handle is closed.

Audio arrives on the relay's network thread, 50 times a second per talking player. Do not block in the callback and do not touch the server's world or entity state from it.

closeOwner(ownerModId) closes these too, and the server stopping closes all of them, so a mod that taps for its whole lifetime can discard the handle.

ParameterDescription
ownerModIdyour mod id; named in the log line announcing the subscription
formatMicrophoneTap.Format#OPUS for the client's own frames, MicrophoneTap.Format#PCM to also get them decoded

Throws IllegalStateException: when microphone-tap.enabled is false, the mod is unknown, or the server already has the maximum number of subscriptions. The message says which

canTapMicrophone

default boolean canTapMicrophone(UUID player)

Whether player's microphone may currently reach a tap - the socketsvc.bridge check the relay itself applies, so a plugin can tell a player why it is not hearing them.

Nested types

  • final class Registry