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
-
IRuntimeDataContainer<INetworkManagerWrapper, ServerManager, NetworkConnection, IRuntimeDataContainer>
- Inherited Members
Properties
IngressGuard
Shared ingress guard for per-connection per-operation debounce and in-flight tracking.
public IngressGuard IngressGuard { get; }
Property Value
LastFetchTime
Timestamp of the last successful database fetch for guild updates.
public DateTime LastFetchTime { get; set; }
Property Value
NextInvitationSweepUtc
Next scheduled UTC time for invitation cleanup.
public DateTime NextInvitationSweepUtc { get; set; }
Property Value
Methods
BeginMembershipRemoval(long)
Marks a character's guild membership as being removed.
public void BeginMembershipRemoval(long characterID)
Parameters
characterIDlongThe 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
characterIDlongThe 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
IsMembershipRemovalInFlight(long)
Reports whether a character's guild membership is currently being removed.
public bool IsMembershipRemovalInFlight(long characterID)
Parameters
characterIDlongThe 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
targetCharacterIDlongInvited 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
nowUtcDateTimeCurrent UTC time.
ttlTimeSpanEntry lifetime.
maxScanintMaximum entries scanned.
maxRemoveintMaximum 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
nowUtcDateTimeCurrent UTC timestamp.
ttlTimeSpanInvitation time-to-live.
maxScanintMaximum queue entries to scan.
maxRemoveintMaximum 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
nowUtcDateTimeCurrent UTC timestamp.
ttlTimeSpanCooldown entry time-to-live.
maxScanintMaximum queue entries to scan.
maxRemoveintMaximum 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
targetCharacterIDlongInvited target character identifier.
invitationPendingGuildInvitationThe 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
characterIDlongThe applying character.
cooldownTimeSpanMinimum interval between applications.
nowUtcDateTimeCurrent 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
inviterCharacterIDlongThe character sending the invitation.
targetCharacterIDlongThe character being invited.
cooldownTimeSpanMinimum interval between invitations to the same target.
nowUtcDateTimeCurrent 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
TryGetPendingInvitation(long, out PendingGuildInvitation)
Tries to get a pending guild invitation for the target character.
public bool TryGetPendingInvitation(long targetCharacterID, out PendingGuildInvitation invitation)
Parameters
targetCharacterIDlongInvited target character identifier.
invitationPendingGuildInvitationResolved 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.