feat(CS): persist owner/phase/registrations across restarts via plugin config JSON
Some checks failed
.NET Core / build (push) Has been cancelled
Some checks failed
.NET Core / build (push) Has been cancelled
Castle Siege state was in-memory, so the castle owner (and thus the P4 hunting-map reward) reset on every server restart/redeploy. Now the context marks itself dirty on any persistable change (phase transition, registration, owner set); the plugin's periodic tick writes a snapshot into its own PlugInConfiguration CustomConfiguration (a JSON blob already stored in PostgreSQL - no schema migration) and restores it on startup. Battle state (defenses/switches/occupier) stays transient. +2 unit tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,7 @@ public class CastleSiegeContext
|
||||
private DateTime _phaseStartedUtc;
|
||||
private string? _occupier;
|
||||
private int _defensesRemaining;
|
||||
private bool _dirty;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="CastleSiegeContext"/> class.</summary>
|
||||
/// <param name="configuration">The cycle timing configuration.</param>
|
||||
@@ -40,6 +41,9 @@ public class CastleSiegeContext
|
||||
/// <summary>Gets the current phase.</summary>
|
||||
public CastleSiegePhase Phase { get; private set; }
|
||||
|
||||
/// <summary>Gets the UTC time the current phase started (used for persistence/restore).</summary>
|
||||
public DateTime PhaseStartedUtc => this._phaseStartedUtc;
|
||||
|
||||
/// <summary>Gets the current owner guild name, or null if unowned.</summary>
|
||||
public string? OwnerGuildName { get; private set; }
|
||||
|
||||
@@ -134,12 +138,50 @@ public class CastleSiegeContext
|
||||
&& !this._registeredGuilds.Contains(guildName))
|
||||
{
|
||||
this._registeredGuilds.Add(guildName);
|
||||
this._dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Admin: sets (or clears) the current owner guild name.</summary>
|
||||
/// <param name="guildName">The owner guild name, or null to clear.</param>
|
||||
public void SetOwner(string? guildName) => this.OwnerGuildName = guildName;
|
||||
public void SetOwner(string? guildName)
|
||||
{
|
||||
this.OwnerGuildName = guildName;
|
||||
this._dirty = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the persistable state changed since the last call, resetting the flag.
|
||||
/// Called each tick by the plugin to decide whether to write state to the database.
|
||||
/// </summary>
|
||||
public bool ConsumeDirty()
|
||||
{
|
||||
var dirty = this._dirty;
|
||||
this._dirty = false;
|
||||
return dirty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restores persisted state on startup (owner, phase, phase-start, registrations) directly, without
|
||||
/// firing <see cref="PhaseChanged"/> or marking the state dirty. Battle state stays cleared.
|
||||
/// </summary>
|
||||
/// <param name="owner">The persisted owner guild name, or null.</param>
|
||||
/// <param name="phase">The persisted phase.</param>
|
||||
/// <param name="phaseStartedUtc">When the persisted phase started (UTC), or null to keep the default.</param>
|
||||
/// <param name="registeredGuilds">The persisted registered guild names, or null.</param>
|
||||
public void RestoreState(string? owner, CastleSiegePhase phase, DateTime? phaseStartedUtc, IEnumerable<string>? registeredGuilds)
|
||||
{
|
||||
this.OwnerGuildName = owner;
|
||||
this.Phase = phase;
|
||||
this._phaseStartedUtc = phaseStartedUtc ?? this._phaseStartedUtc;
|
||||
this._registeredGuilds.Clear();
|
||||
if (registeredGuilds is not null)
|
||||
{
|
||||
this._registeredGuilds.AddRange(registeredGuilds);
|
||||
}
|
||||
|
||||
this._dirty = false;
|
||||
}
|
||||
|
||||
/// <summary>Sets how many castle defenses (gates + guardian statues) exist this siege (when spawned).</summary>
|
||||
/// <param name="count">The defense count.</param>
|
||||
@@ -222,6 +264,7 @@ public class CastleSiegeContext
|
||||
{
|
||||
this.Phase = phase;
|
||||
this._phaseStartedUtc = now;
|
||||
this._dirty = true;
|
||||
this.PhaseChanged?.Invoke(phase);
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user