Table of Contents

Namespace FishMMO.Server.Implementation

Namespaces

FishMMO.Server.Implementation.LoginServer
FishMMO.Server.Implementation.Smtp
FishMMO.Server.Implementation.World

Classes

AccountManager

Unity/FishNet concrete account manager for FishNet.Connection.NetworkConnection. All logic lives in AccountManager<TConnection> in FishMMO-Auth.

AccountVerificationPolicy

Single source of truth for the development-only "skip email verification" policy driven by the AutoVerifyAccounts configuration key.

Two call sites must agree on this answer:

  • Account creation, which persists verified = true instead of generating a verify code, queueing a verification email, and enrolling mandatory TOTP.
  • The login lookup, which otherwise rejects an unverified account once verification_email_sent_at has been stamped. Without the login side honouring the flag, accounts created before auto-verify was enabled (or created against a production build) stay locked out of a local server forever.

The compile-time guard is deliberate: a production player build ignores the key entirely, so a Development LoginServer.cfg that leaks into a production deployment cannot re-enable the bypass. Consequently the flag also has no effect in a server binary built with the Production working environment — build the server with the Development working environment for local testing.

AsyncWorkerData

Centralized async work queue.

Replaces fire-and-forget _ = SomeAsync(...) across all server systems with a bounded, backpressure-aware pool that runs work items concurrently while preserving FIFO order between items that share an entity key.

Design:

  • Work runs concurrently, capped by FishMMO.Server.Implementation.AsyncWorkerData.maxConcurrency. A slow item delays only the items ordered behind it.
  • Items sharing an entityKey run in the order they were enqueued, one at a time.
  • Bounded admission: Enqueue(Func<Task>, string) returns false once FishMMO.Server.Implementation.AsyncWorkerData.maxOutstandingItems items are accepted but unfinished.
  • Nothing ever executes on the calling thread — see FishMMO.Server.Implementation.AsyncWorkerData.DispatchUnordered(FishMMO.Server.Implementation.AsyncWorkerData.AsyncWorkItem).

Usage:

// Unordered — runs as soon as a concurrency slot is free:
asyncWorkerData.Enqueue(() => PersistInventoryAsync(dto));

// Ordered — this character's items run in enqueue order, one at a time:
asyncWorkerData.Enqueue(() => SaveCharacterAsync(charData), characterID);

Systems declare dependency via: [RequiresDataContainer(typeof(AsyncWorkerData))]

BaseServerAuthenticator

Abstract base MonoBehaviour authenticator that routes FishNet transport callbacks to an engine-independent BaseAuthenticatorCore<TConnection> instance. All handshake, TTL, rate-limit, and worker logic lives in the core; this class bridges FishNet lifecycle events (broadcasts, connection state) to the core.

FishNetNetworkWrapper

Wraps FishNet NetworkManager with a clean abstraction for server orchestration.

KickRequestSystem

System for processing kick requests from the database and disconnecting accounts as needed. Periodically polls the database for new kick requests and processes them asynchronously. Kick/Disconnect calls are marshalled back to the main thread via a RuntimeDataContainer queue.

KickRequestSystemMainThreadQueueData

Main-thread queue data container for KickRequestSystem. Separate concrete type ensures the DataContainerRegistry creates an independent instance for this system.

KickRequestSystemQueueData

Runtime data container for kick request processing state. Manages kick request database polling state separately from KickRequestSystem logic.

MainThreadQueueData

Base runtime data container providing a thread-safe main-thread action queue. Async worker threads enqueue actions via Enqueue(), and the main thread drains them via Drain() each frame (typically in OnLateUpdate).

Each system that needs main-thread marshalling should have its own concrete subclass so the DataContainerRegistry creates separate instances per system.

MainThreadQueueHelper

Shared utility for main-thread queue drain and enqueue operations. Eliminates copy-paste boilerplate across server systems (D1).

Back-pressure observability: the underlying MainThreadQueueData enforces a hard capacity cap (currently 10,000 pending actions) and returns false from TryEnqueue when full. Most call sites discard that bool because there is no useful off-thread fallback — the response broadcast is already on the main thread by contract. To keep the loss visible to operators, every rejected enqueue is counted here in a per-queue-type drop counter and surfaced through a rate-limited warning. A sustained non-zero drop rate indicates the main thread is stalling long enough for async DB workers to saturate the queue (10K * 16 ms drain budget ≈ several seconds of hang) and is a stronger DoS / GC-pause signal than any individual client time-out.

PeriodicCallbackData

Internal data structure for tracking periodic callback state.

PhysicsTicker

Handles ticking the physics simulation for a specific PhysicsScene using FishNet's TimeManager events.

RuntimeDataContainer

Base class for all runtime data containers in the FishMMO server architecture. Provides registration, initialization, and lifecycle management for server data storage. Data containers store mutable state separate from ServerBehaviour logic.

RuntimeDataContainerFactory

Factory for creating RuntimeDataContainer instances via reflection. Validates container types and instantiates them using parameterless constructors.

RuntimeDataContainerRegistry

Handles registration, lookup, and initialization of IRuntimeDataContainer instances. Provides global access and lifecycle management for runtime data containers. Extends the generic ServerComponentRegistry to provide container-specific initialization.

Server

Composition root: orchestrates Core and Implementation into a running server.

ServerAddressProvider

Provides various IP address formats by interacting with the FishNet transport layer and server overrides.

ServerAuthenticator

SRP-6a server authenticator. Delegates all handshake, channel, worker, and protocol logic to SrpAuthenticatorCore<TConnection> in FishMMO-Auth. This class bridges FishNet broadcast events to the core and provides Unity/DB callbacks.

ServerBehaviour

Base class for all server-side behaviours in the FishMMO server architecture. Provides registration, initialization, and lifecycle management for server behaviours.

ServerBehaviourRegistry

Handles registration, lookup, and initialization of IServerBehaviour instances. Provides global access and lifecycle management for server-side behaviours. Extends the generic ServerComponentRegistry to provide behaviour-specific initialization.

ServerComponentRegistry<TNetworkManager, TConnection, TServerComponent>

Generic base implementation for server component registries. Handles registration, lookup, and lifecycle management of server components. Can be extended for specific component types (behaviours, data containers, etc.).

ServerLauncher

Launches the server by preloading required scenes and handling addressable asset events. Supports command-line arguments for selecting server type.

ServerWindowTitleUpdater

Updates the server window or console title to reflect current server status, including transport type, connection state, and client count. Supports Windows, Linux, and OSX platforms.

ServerWindowTitleUpdaterRuntimeData

Runtime data container for ServerWindowTitleUpdater mutable state. Stores the transient window title string and countdown timer separate from the ServerBehaviour configuration.

SigningKeyKekProvider

Loads the deployment-shared 32-byte AES-256 KEK used by KeyEnvelope to wrap per-LoginServer HMAC signing keys at rest. The KEK MUST be identical across the LoginServer process (which writes wrapped blobs) and every World/Scene server (which unwraps them) for a given deployment.

SrpAccountManager

Unity/FishNet concrete SRP account manager for FishNet.Connection.NetworkConnection. All logic lives in SrpAccountManager<TConnection> in FishMMO-Auth.

SystemMainThreadQueueData

Shared base class for per-system main-thread queue runtime containers. Concrete system queue containers should inherit this type to keep declarations minimal.

TokenAccountManager

Unity/FishNet concrete token account manager for FishNet.Connection.NetworkConnection. All logic lives in TokenAccountManager<TConnection> in FishMMO-Auth.

TokenServerAuthenticator

Token-based server authenticator for World and Scene servers. Delegates all handshake, channel, worker, and protocol logic to TokenAuthenticatorCore<TConnection> in FishMMO-Auth. This class bridges FishNet broadcast events to the core and provides Unity/DB callbacks.

UnitySyncOverAsync

Blocks the calling thread on an async operation without risking a SynchronizationContext deadlock.

Unity installs a UnitySynchronizationContext on the main thread; continuations posted to it only run when the player loop drains them. Any await in the callee that captures that context — i.e. any await without ConfigureAwait(false), anywhere in the call chain — can therefore never resume while the main thread sits in GetResult()/.Result/.Wait(). The server then stays alive but never finishes InitializeOnce, so the transport never binds its port.

Shutdown paths only. OnDestroy/OnApplicationQuit cannot yield and the process exits immediately afterwards, so there is no continuation to hand work to — a bounded block is the only way to flush pending state before exit. Startup has no such constraint and must not use this: behaviours initialize through ServerBehaviour.InitializeOnceAsync, driven by Server's initialization coroutine, which leaves the main thread free to drain continuations.

Where a bounded block genuinely is required, route it through here rather than hand-rolling Task.Run(...).Wait(...): call sites should not have to audit an entire EF/Npgsql call chain to know whether blocking is safe.

Structs

SigningKeyKekProvider.KekLoadResult

Outcome of a KEK load. Kek is non-null only when Success is true; otherwise Error explains why, for fail-closed callers.

Interfaces

INetworkManagerWrapper

Interface for network-related operations, decoupling the Server class from the concrete FishNet implementation.

IServerAuthenticator

Common interface for server authenticators (both SRP-based and token-based). Provides the Server reference and worker lifecycle methods needed by AttachLoginAuthenticator(IServer<INetworkManagerWrapper, NetworkConnection, IServerBehaviour>).