Table of Contents

Class DynamicChannelManagerService

Namespace
FishMMO.DiscordBot.Services
Assembly
FishMMO-DiscordBot.dll

Manages dynamically created Discord channels that bridge game world/scene chat to Discord. Implements IHostedService for lifecycle management of the cleanup timer. All inner dictionaries are ConcurrentDictionary<TKey, TValue> for thread safety.

public class DynamicChannelManagerService : IHostedService, IDisposable
Inheritance
DynamicChannelManagerService
Implements
Inherited Members

Constructors

DynamicChannelManagerService(DiscordSocketClient, ILogger<DynamicChannelManagerService>, BotConfigurationService, NpgsqlDbContextFactory)

Initializes a new instance of the DynamicChannelManagerService class.

public DynamicChannelManagerService(DiscordSocketClient discord, ILogger<DynamicChannelManagerService> logger, BotConfigurationService botConfigService, NpgsqlDbContextFactory dbContextFactory)

Parameters

discord DiscordSocketClient

The Discord socket client.

logger ILogger<DynamicChannelManagerService>

Logger instance.

botConfigService BotConfigurationService

Configuration service for persistent channel state.

dbContextFactory NpgsqlDbContextFactory

Factory for creating database contexts.

Properties

TotalManagedChannelCount

Returns the total number of managed channels across all guilds.

public int TotalManagedChannelCount { get; }

Property Value

int

Methods

Dispose()

Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

public void Dispose()

ForceCleanupAsync()

Forces an immediate cleanup of stale channels. Called from admin commands.

public Task<int> ForceCleanupAsync()

Returns

Task<int>

The number of channels removed.

GetManagedChannelState(ulong, long, long)

Retrieves the managed channel state for a given World/Scene combination within a guild. Thread-safe via ConcurrentDictionary<TKey, TValue> reads.

public DynamicGameChatChannelState? GetManagedChannelState(ulong guildId, long worldServerId, long sceneServerId)

Parameters

guildId ulong

The Discord guild ID.

worldServerId long

The game world server ID.

sceneServerId long

The game scene server ID.

Returns

DynamicGameChatChannelState

The channel state, or null if not managed.

GetManagedChannelsForGuild(ulong)

Returns a snapshot list of all managed channels for the specified guild.

public List<(long WorldId, long SceneId, DynamicGameChatChannelState State)> GetManagedChannelsForGuild(ulong guildId)

Parameters

guildId ulong

The Discord guild ID.

Returns

List<(long WorldId, long SceneId, DynamicGameChatChannelState State)>

A list of tuples containing WorldId, SceneId, and the channel state.

GetOrCreateChannelState(ulong, long, string?, long, string?)

Gets or creates a Discord channel for a given game world/scene combination. Creates the Discord category and text channel if they do not already exist. Serialized via FishMMO.DiscordBot.Services.DynamicChannelManagerService.createChannelLock to prevent duplicate channel creation.

public Task<DynamicGameChatChannelState?> GetOrCreateChannelState(ulong guildId, long worldServerId, string? worldServerName, long sceneServerId, string? sceneServerName)

Parameters

guildId ulong

The Discord guild in which to manage channels.

worldServerId long

The game world server ID.

worldServerName string

The world server name (fetched from DB if null or empty).

sceneServerId long

The game scene server ID.

sceneServerName string

The scene server name (fetched from DB if null or empty).

Returns

Task<DynamicGameChatChannelState>

The channel state, or null if the guild was not found.

GetWorldAndSceneIdsFromChannel(SocketTextChannel)

Extracts World and Scene IDs from a Discord channel's name and its category's name. Expects the format "Name-ID" for both category (World) and channel (Scene).

public (long? WorldId, long? SceneId) GetWorldAndSceneIdsFromChannel(SocketTextChannel channel)

Parameters

channel SocketTextChannel

The Discord text channel to extract IDs from.

Returns

(long? WorldId, long? SceneId)

A tuple of (WorldId, SceneId), either of which may be null on parse failure.

IsOurDynamicChannel(ulong, ulong)

Checks whether a Discord channel is one of the dynamically managed game chat channels. Uses O(1) reverse lookup instead of scanning all channels.

public bool IsOurDynamicChannel(ulong guildId, ulong channelId)

Parameters

guildId ulong

The Discord guild ID.

channelId ulong

The Discord channel ID to check.

Returns

bool

true if the channel is managed by this service.

StartAsync(CancellationToken)

Triggered when the application host is ready to start the service.

public Task StartAsync(CancellationToken cancellationToken)

Parameters

cancellationToken CancellationToken

Indicates that the start process has been aborted.

Returns

Task

A Task that represents the asynchronous Start operation.

StopAsync(CancellationToken)

Triggered when the application host is performing a graceful shutdown.

public Task StopAsync(CancellationToken cancellationToken)

Parameters

cancellationToken CancellationToken

Indicates that the shutdown process should no longer be graceful.

Returns

Task

A Task that represents the asynchronous Stop operation.

UpdateChannelActivity(ulong, long, long)

Updates the last-activity timestamp for a managed channel. Does not persist to disk — saves are batched during cleanup or channel creation.

public void UpdateChannelActivity(ulong guildId, long worldServerId, long sceneServerId)

Parameters

guildId ulong

The Discord guild ID.

worldServerId long

The game world server ID.

sceneServerId long

The game scene server ID.