//
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
//
namespace MUnique.OpenMU.GameLogic.PlugIns.PeriodicTasks;
using System.Collections.Concurrent;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic.CastleSiege;
using MUnique.OpenMU.PlugIns;
///
/// Drives the Castle Siege phase state machine: ticks it every second and carries its configuration.
/// State is per- and kept in memory (P1: no persistence).
///
[PlugIn]
[Display(Name = nameof(CastleSiegeEventPlugIn), Description = "Castle Siege event (P1 skeleton: phase state machine + scheduling).")]
[Guid("6E2C8B41-9A4D-4C2E-9E7B-1F2A3B4C5D60")]
public sealed class CastleSiegeEventPlugIn : IPeriodicTaskPlugIn, ISupportCustomConfiguration, ISupportDefaultCustomConfiguration
{
private static readonly ConcurrentDictionary Contexts = new();
///
public CastleSiegeConfiguration? Configuration { get; set; }
///
/// Gets the Castle Siege context for a game context, if the periodic tick has initialized it.
///
/// The game context.
/// The context, or null if not yet initialized.
/// Static so GM chat commands can reach the state machine without a plugin instance
/// (GetKnownPlugInsOf returns Types, not instances). The tick runs every second, so the
/// context exists within ~1s of server start.
public static CastleSiegeContext? TryGetContext(IGameContext gameContext)
=> Contexts.TryGetValue(gameContext, out var context) ? context : null;
///
public object CreateDefaultConfig() => new CastleSiegeConfiguration();
///
public async ValueTask ExecuteTaskAsync(GameContext gameContext)
{
var context = Contexts.GetOrAdd(gameContext, _ => new CastleSiegeContext(this.Configuration ?? new CastleSiegeConfiguration()));
await context.TickAsync(DateTime.UtcNow).ConfigureAwait(false);
}
///
public void ForceStart()
{
// Force-start applies to every active game context's siege.
foreach (var context in Contexts.Values)
{
_ = context.ForceStartRegistrationAsync(DateTime.UtcNow);
}
}
}