Table of Contents

Class GuildSystemRuntimeData

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

Runtime data container for guild system state. Manages guild invitations and database synchronization state separately from GuildSystem logic.

public class GuildSystemRuntimeData : RuntimeDataContainer, IRuntimeDataContainer<INetworkManagerWrapper, ServerManager, NetworkConnection, IRuntimeDataContainer>, IServerComponent<INetworkManagerWrapper, ServerManager, NetworkConnection, IRuntimeDataContainer>, IGuildSystemRuntimeData, IRuntimeDataContainer, IServerComponent
Inheritance
GuildSystemRuntimeData
Implements
Inherited Members

Properties

IngressGuard

Shared ingress guard for per-connection per-operation debounce and in-flight tracking.

public IngressGuard IngressGuard { get; }

Property Value

IngressGuard

LastFetchTime

Timestamp of the last successful database fetch for guild updates.

public DateTime LastFetchTime { get; set; }

Property Value

DateTime

NextInvitationSweepUtc

Next scheduled UTC time for invitation cleanup.

public DateTime NextInvitationSweepUtc { get; set; }

Property Value

DateTime

Methods

BeginMembershipRemoval(long)

Marks a character's guild membership as being removed.

public void BeginMembershipRemoval(long characterID)

Parameters

characterID long

The character leaving or being kicked.

Remarks

Kick and leave both delete the membership row from a background task, and the character keeps a live IGuildController.ID until the delete lands. Disconnecting inside that window ran the ordinary disconnect persist, which upserts the membership row from that still-live controller — putting the player straight back into the guild they had just been removed from. This flag is what the disconnect path checks so it does not resurrect a membership that is being deleted.

Clear()

Clears all guild runtime data.

public override void Clear()

EndMembershipRemoval(long)

Clears the membership-removal marker for a character.

public void EndMembershipRemoval(long characterID)

Parameters

characterID long

The character whose removal has finished.

EndUpdatePump()

Atomically transitions the update pump from in-flight back to idle.

public void EndUpdatePump()

InitializeOnce()

Initializes the guild runtime data container.

public override ServerComponentInitializationStatus InitializeOnce()

Returns

ServerComponentInitializationStatus

IsMembershipRemovalInFlight(long)

Reports whether a character's guild membership is currently being removed.

public bool IsMembershipRemovalInFlight(long characterID)

Parameters

characterID long

The character to test.

Returns

bool

True while a removal is in flight.

OnDeinitialize()

Deinitializes the guild runtime data container.

protected override void OnDeinitialize()

RemovePendingInvitation(long)

Removes a pending invitation for a target character.

public bool RemovePendingInvitation(long targetCharacterID)

Parameters

targetCharacterID long

Invited target character identifier.

Returns

bool

True when removed; otherwise false.

SweepApplicationCooldowns(DateTime, TimeSpan, int, int)

Removes expired application cooldown entries.

public int SweepApplicationCooldowns(DateTime nowUtc, TimeSpan ttl, int maxScan, int maxRemove)

Parameters

nowUtc DateTime

Current UTC time.

ttl TimeSpan

Entry lifetime.

maxScan int

Maximum entries scanned.

maxRemove int

Maximum entries removed.

Returns

int

The number of entries removed.

SweepExpiredInvitations(DateTime, TimeSpan, int, int)

Sweeps expired invitations using bounded scan/remove limits.

public int SweepExpiredInvitations(DateTime nowUtc, TimeSpan ttl, int maxScan, int maxRemove)

Parameters

nowUtc DateTime

Current UTC timestamp.

ttl TimeSpan

Invitation time-to-live.

maxScan int

Maximum queue entries to scan.

maxRemove int

Maximum expired entries to remove.

Returns

int

Number of removed invitations.

SweepInviteCooldowns(DateTime, TimeSpan, int, int)

Sweeps expired invite cooldown entries using bounded scan/remove limits.

public int SweepInviteCooldowns(DateTime nowUtc, TimeSpan ttl, int maxScan, int maxRemove)

Parameters

nowUtc DateTime

Current UTC timestamp.

ttl TimeSpan

Cooldown entry time-to-live.

maxScan int

Maximum queue entries to scan.

maxRemove int

Maximum expired entries to remove.

Returns

int

Number of removed entries.

TryAddPendingInvitation(long, PendingGuildInvitation)

Attempts to add a new pending invitation.

public bool TryAddPendingInvitation(long targetCharacterID, PendingGuildInvitation invitation)

Parameters

targetCharacterID long

Invited target character identifier.

invitation PendingGuildInvitation

The invitation to hold.

Returns

bool

True when inserted; false when an invitation is already pending.

TryBeginApplicationCooldown(long, TimeSpan, DateTime)

Begins the per-character guild application cooldown, if it is not already running.

public bool TryBeginApplicationCooldown(long characterID, TimeSpan cooldown, DateTime nowUtc)

Parameters

characterID long

The applying character.

cooldown TimeSpan

Minimum interval between applications.

nowUtc DateTime

Current UTC time.

Returns

bool

True when the application may proceed.

Remarks

Keyed on the APPLICANT alone, not on (applicant, guild). The per-guild case is already covered by the unique index on the application table; what is not covered, and what this exists for, is one player applying to every guild in the directory in turn.

TryBeginInviteCooldown(long, long, TimeSpan, DateTime)

Records an invitation attempt against a specific target and reports whether it is allowed by the per-target cooldown.

public bool TryBeginInviteCooldown(long inviterCharacterID, long targetCharacterID, TimeSpan cooldown, DateTime nowUtc)

Parameters

inviterCharacterID long

The character sending the invitation.

targetCharacterID long

The character being invited.

cooldown TimeSpan

Minimum interval between invitations to the same target.

nowUtc DateTime

Current UTC timestamp.

Returns

bool

True when the invitation may proceed; false while the cooldown is active.

Remarks

The pending-invitation slot is NOT a rate limit: declining clears it immediately, so an inviter could re-send the moment the target dismissed the dialog and keep a modal on their screen indefinitely. The connection-level debounce does not help either — it is a hundred milliseconds and is per connection, not per target, so it caps the rate without capping the harassment. This is the per-(inviter, target) limit that does.

TryBeginUpdatePump()

Atomically transitions the update pump from idle to in-flight. Returns true if this call won the race; false if a pump is already in flight.

public bool TryBeginUpdatePump()

Returns

bool

TryGetPendingInvitation(long, out PendingGuildInvitation)

Tries to get a pending guild invitation for the target character.

public bool TryGetPendingInvitation(long targetCharacterID, out PendingGuildInvitation invitation)

Parameters

targetCharacterID long

Invited target character identifier.

invitation PendingGuildInvitation

Resolved invitation when found.

Returns

bool

True when a pending invitation exists; otherwise false.

Remarks

Deliberately does NOT touch the entry's last-seen timestamp. The TTL is measured against IssuedUtc, which the reader cannot move; touching on read would let a late accept refresh the very entry the sweep was about to expire, which is exactly the behaviour that let a stale dialog stay live indefinitely.