refactor(CS): schedule + periods are config-owned, AdminPanel-editable
Some checks failed
.NET Core / build (push) Has been cancelled

Move the auto-schedule from context-owned state to the plugin config (single source
of truth): RegistrationOpenDays + RegistrationOpenTimes + Registration/Preparation/
SiegeDuration are all editable in the AdminPanel plugin config and take effect live
(context refreshes its config reference each tick via UpdateConfiguration). /csschedule
now writes the config. Removed the duplicate Persisted schedule fields. 12 tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Acentech Dev
2026-07-15 14:52:07 +03:00
parent f586321123
commit 4651ef232c
5 changed files with 61 additions and 69 deletions

View File

@@ -10,19 +10,29 @@ namespace MUnique.OpenMU.GameLogic.CastleSiege;
/// </summary>
public class CastleSiegeConfiguration
{
// --- Schedule &amp; period lengths (editable in the AdminPanel) ---
// A cycle runs: Ownership -> Registration -> Preparation -> Siege(war) -> Settlement -> Ownership.
// It auto-starts when the current day/time matches RegistrationOpenDays + RegistrationOpenTimes.
/// <summary>
/// Gets or sets the times of day at which a new cycle opens registration.
/// Empty by default; admins start cycles manually via chat command in P1.
/// Gets or sets the days of week on which registration auto-opens (UTC). Empty = every day
/// (still requires a time in <see cref="RegistrationOpenTimes"/>); with no times set, auto-start is off.
/// </summary>
public IList<DayOfWeek> RegistrationOpenDays { get; set; } = new List<DayOfWeek>();
/// <summary>
/// Gets or sets the times of day (UTC) at which a new cycle opens registration.
/// Empty = no auto-start (admins start cycles manually via chat command).
/// </summary>
public IList<TimeOnly> RegistrationOpenTimes { get; set; } = new List<TimeOnly>();
/// <summary>Gets or sets how long the registration phase lasts.</summary>
/// <summary>Gets or sets how long the registration period lasts (guilds may register).</summary>
public TimeSpan RegistrationDuration { get; set; } = TimeSpan.FromMinutes(5);
/// <summary>Gets or sets how long the preparation phase lasts.</summary>
/// <summary>Gets or sets how long the preparation period lasts (between registration close and the war).</summary>
public TimeSpan PreparationDuration { get; set; } = TimeSpan.FromMinutes(2);
/// <summary>Gets or sets how long the siege phase lasts.</summary>
/// <summary>Gets or sets how long the war (siege) period lasts.</summary>
public TimeSpan SiegeDuration { get; set; } = TimeSpan.FromMinutes(10);
/// <summary>
@@ -48,15 +58,10 @@ public class CastleSiegeConfiguration
/// <summary>Gets or sets the persisted registered guild names for the current cycle.</summary>
public IList<string> PersistedRegisteredGuilds { get; set; } = new List<string>();
/// <summary>Gets or sets the persisted auto-schedule days of week (empty = manual start only).</summary>
public IList<DayOfWeek> PersistedScheduleDays { get; set; } = new List<DayOfWeek>();
/// <summary>Gets or sets the persisted auto-schedule UTC time of day, or null if unscheduled.</summary>
public TimeOnly? PersistedScheduleTime { get; set; }
/// <summary>
/// Returns true if <paramref name="now"/> falls within a 5-second window of any configured
/// registration-open time.
/// Returns true if <paramref name="now"/> (UTC) matches a scheduled registration-open day and falls
/// within a 5-second window of a configured open time. When <see cref="RegistrationOpenDays"/> is empty,
/// the day is not restricted (every day). When no times are configured, auto-start is disabled.
/// </summary>
/// <param name="now">The current UTC time.</param>
public bool IsRegistrationOpenTime(DateTime now)
@@ -66,6 +71,11 @@ public class CastleSiegeConfiguration
return false;
}
if (this.RegistrationOpenDays.Count > 0 && !this.RegistrationOpenDays.Contains(now.DayOfWeek))
{
return false;
}
var nowTime = TimeOnly.FromDateTime(now);
var earlier = nowTime.Add(TimeSpan.FromSeconds(-5));
return this.RegistrationOpenTimes.Any(p => p.IsBetween(earlier, nowTime));