Table of Contents

Class ChatSystem

Namespace
FishMMO.Server.Implementation.World.SceneServer
Assembly
FishMMO.Server.dll

Manages all chat functionality including public, party, guild, whisper, and system messages with rate limiting and spam protection. Game logic and Broadcasts run synchronously on the main thread. Database operations are fire-and-forget async to avoid blocking the main thread. Results from async DB queries that require main-thread Broadcasts are marshalled via IChatSystemMainThreadQueueData.

[CreateAssetMenu(fileName = "ChatSystem", menuName = "FishMMO/Server/SceneServer/Chat System", order = 1)]
[RequiresDataContainer(typeof(ChatSystemRuntimeData))]
[RequiresDataContainer(typeof(ChatSystemMainThreadQueueData))]
[RequiresDataContainer(typeof(AsyncWorkerData))]
public class ChatSystem : ServerBehaviour, IServerBehaviour<INetworkManagerWrapper, ServerManager, NetworkConnection, IServerBehaviour>, IServerComponent<INetworkManagerWrapper, ServerManager, NetworkConnection, IServerBehaviour>, IChatSystem, IServerBehaviour, IServerComponent, IChatHelper
Inheritance
Object
ScriptableObject
ChatSystem
Implements
IServerBehaviour<INetworkManagerWrapper, ServerManager, NetworkConnection, IServerBehaviour>
IServerComponent<INetworkManagerWrapper, ServerManager, NetworkConnection, IServerBehaviour>
Inherited Members
ScriptableObject.SetDirty()
ScriptableObject.CreateInstance<T>()
Object.GetEntityId()
Object.GetInstanceID()
Object.GetHashCode()
Object.InstantiateAsync<T>(T)
Object.InstantiateAsync<T>(T, Transform)
Object.InstantiateAsync<T>(T, Vector3, Quaternion)
Object.InstantiateAsync<T>(T, Transform, Vector3, Quaternion)
Object.Instantiate(Object, Vector3, Quaternion)
Object.Instantiate(Object, Vector3, Quaternion, Transform)
Object.Instantiate(Object)
Object.Instantiate(Object, Scene)
Object.Instantiate<T>(T, InstantiateParameters)
Object.Instantiate<T>(T, Vector3, Quaternion, InstantiateParameters)
Object.Instantiate(Object, Transform)
Object.Instantiate<T>(T)
Object.Instantiate<T>(T, Vector3, Quaternion)
Object.Instantiate<T>(T, Vector3, Quaternion, Transform)
Object.Instantiate<T>(T, Transform)
Object.Destroy(Object)
Object.DestroyImmediate(Object)
Object.DontDestroyOnLoad(Object)
Object.DestroyObject(Object)
Object.FindObjectsOfType<T>()
Object.FindObjectsByType<T>(FindObjectsSortMode)
Object.FindObjectsByType<T>(FindObjectsInactive, FindObjectsSortMode)
Object.FindObjectOfType<T>()
Object.FindFirstObjectByType<T>()
Object.FindAnyObjectByType<T>()
Object.FindFirstObjectByType<T>(FindObjectsInactive)
Object.FindAnyObjectByType<T>(FindObjectsInactive)
Object.FindObjectsByType<T>()
Object.FindObjectsByType<T>(FindObjectsInactive)
Object.ToString()
Object.name
Object.hideFlags

Properties

AllowRepeatMessages

If true, allows repeat messages from clients without spam filtering.

public bool AllowRepeatMessages { get; }

Property Value

bool

MaxMessageLength

Maximum allowed chat message length.

public int MaxMessageLength { get; }

Property Value

int

MessageFetchCount

Number of chat messages to fetch per database poll.

public int MessageFetchCount { get; }

Property Value

int

MessagePumpRate

The server chat message pump rate limit in seconds.

public float MessagePumpRate { get; }

Property Value

float

MessageRateLimit

The server chat rate limit in milliseconds. Should match the client's UIChat.messageRateLimit.

public float MessageRateLimit { get; }

Property Value

float

Methods

GetChannelCommand(ChatChannel)

Gets the chat command handler for a specific chat channel.

public ChatCommand GetChannelCommand(ChatChannel channel)

Parameters

channel ChatChannel

Chat channel to get the command for.

Returns

ChatCommand

Chat command delegate for the channel.

InitializeOnce()

Initializes the chat system, registering broadcast handlers and chat helper commands.

public override ServerComponentInitializationStatus InitializeOnce()

Returns

ServerComponentInitializationStatus

OnDeinitialize()

Cleans up the chat system, unregistering broadcast handlers and chat helper commands.

public override void OnDeinitialize()

OnGuildChat(IPlayerCharacter, ChatBroadcast)

Handles guild chat messages, querying guild members asynchronously from the database and marshalling Broadcasts back to the main thread. Returns false to suppress the synchronous DB save — the async path handles persistence when broadcast succeeds.

public bool OnGuildChat(IPlayerCharacter sender, ChatBroadcast msg)

Parameters

sender IPlayerCharacter

Player character sending the message.

msg ChatBroadcast

Chat broadcast message.

Returns

bool

False — persistence is handled inside the async path.

OnPartyChat(IPlayerCharacter, ChatBroadcast)

Handles party chat messages, querying party members asynchronously from the database and marshalling Broadcasts back to the main thread. Returns false to suppress the synchronous DB save — the async path handles persistence when broadcast succeeds.

public bool OnPartyChat(IPlayerCharacter sender, ChatBroadcast msg)

Parameters

sender IPlayerCharacter

Player character sending the message.

msg ChatBroadcast

Chat broadcast message.

Returns

bool

False — persistence is handled inside the async path.

OnRegionChat(IPlayerCharacter, ChatBroadcast)

Handles region chat messages, broadcasting to all connections in the sender's scene.

public bool OnRegionChat(IPlayerCharacter sender, ChatBroadcast msg)

Parameters

sender IPlayerCharacter

Player character sending the message.

msg ChatBroadcast

Chat broadcast message.

Returns

bool

False to prevent message from being written to the database.

OnSayChat(IPlayerCharacter, ChatBroadcast)

Handles say (local) chat messages, broadcasting to all observers of the sender.

public bool OnSayChat(IPlayerCharacter sender, ChatBroadcast msg)

Parameters

sender IPlayerCharacter

Player character sending the message.

msg ChatBroadcast

Chat broadcast message.

Returns

bool

False to prevent message from being written to the database.

Remarks

Scoped by the sender's observer set, which is already range-limited: the player distance condition admits a viewer at up to 100 m, so an observer of the speaker is by construction someone standing near enough to hear them. Re-deriving earshot from positions here would be a second copy of a radius the interest system already applies, and the two would drift the moment either was retuned.

OnSendDiscordMessage(long, long, string)

Allows the server to send Discord messages to a specific world server.

public void OnSendDiscordMessage(long worldServerID, long sceneServerID, string message)

Parameters

worldServerID long

World server ID to send the message to.

sceneServerID long

Scene server ID (for context).

message string

Discord message text.

OnSendSystemMessage(NetworkConnection, string)

Allows the server to send system messages to the connection.

public void OnSendSystemMessage(NetworkConnection conn, string message)

Parameters

conn NetworkConnection

Network connection to send the system message to.

message string

System message text.

OnTeamChat(IPlayerCharacter, ChatBroadcast)

Delivers a team message to the sender's teammates in the arena they are standing in.

public bool OnTeamChat(IPlayerCharacter sender, ChatBroadcast msg)

Parameters

sender IPlayerCharacter
msg ChatBroadcast

Returns

bool

Remarks

Local and synchronous. Every seat of a match is connected to the scene server hosting its instance, so there is no other server to reach and no database to go through; the team registry the coordinator publishes says who is on which side. A sender who is not seated in a live-or-pending arena match is told so rather than silently dropped.

Not persisted. The channel exists only for the duration of a match, and a chat history query has no team to resolve it against afterwards.

OnTellChat(IPlayerCharacter, ChatBroadcast)

Handles tell (private) chat messages. Queries the target character asynchronously from the database, marshals Broadcasts to the main thread, and persists the message on success. Returns false to suppress the synchronous DB save — the async path handles persistence.

public bool OnTellChat(IPlayerCharacter sender, ChatBroadcast msg)

Parameters

sender IPlayerCharacter

Player character sending the message.

msg ChatBroadcast

Chat broadcast message.

Returns

bool

False — persistence is handled inside the async path.

OnTradeChat(IPlayerCharacter, ChatBroadcast)

Handles trade chat messages. Live messages are buffered per-world for batched delivery. Pump-sourced messages (sender == null) are broadcast immediately.

public bool OnTradeChat(IPlayerCharacter sender, ChatBroadcast msg)

Parameters

sender IPlayerCharacter

Player character sending the message, or null for pump-sourced.

msg ChatBroadcast

Chat broadcast message.

Returns

bool

True if message was accepted (live sender), false otherwise.

OnUpdate(float)

Each frame: drain the lock-free incoming chat queue, then the main-thread action queue.

protected override void OnUpdate(float deltaTime)

Parameters

deltaTime float

OnWorldChat(IPlayerCharacter, ChatBroadcast)

Handles world chat messages. Live messages are buffered per-world for batched delivery. Pump-sourced messages (sender == null) are broadcast immediately.

public bool OnWorldChat(IPlayerCharacter sender, ChatBroadcast msg)

Parameters

sender IPlayerCharacter

Player character sending the message, or null for pump-sourced.

msg ChatBroadcast

Chat broadcast message.

Returns

bool

True if message was accepted (live sender), false otherwise.