feat(CS-P1): periodic Castle Siege plugin (per-context tick + custom config)
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
// <copyright file="CastleSiegeEventPlugIn.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.GameLogic.PlugIns.PeriodicTasks;
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using System.Runtime.InteropServices;
|
||||
using MUnique.OpenMU.GameLogic.CastleSiege;
|
||||
using MUnique.OpenMU.PlugIns;
|
||||
|
||||
/// <summary>
|
||||
/// Drives the Castle Siege phase state machine: ticks it every second and carries its configuration.
|
||||
/// State is per-<see cref="IGameContext"/> and kept in memory (P1: no persistence).
|
||||
/// </summary>
|
||||
[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<CastleSiegeConfiguration>, ISupportDefaultCustomConfiguration
|
||||
{
|
||||
private static readonly ConcurrentDictionary<IGameContext, CastleSiegeContext> Contexts = new();
|
||||
|
||||
/// <inheritdoc />
|
||||
public CastleSiegeConfiguration? Configuration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Castle Siege context for a game context, if the periodic tick has initialized it.
|
||||
/// </summary>
|
||||
/// <param name="gameContext">The game context.</param>
|
||||
/// <returns>The context, or <c>null</c> if not yet initialized.</returns>
|
||||
/// <remarks>Static so GM chat commands can reach the state machine without a plugin instance
|
||||
/// (<c>GetKnownPlugInsOf</c> returns Types, not instances). The tick runs every second, so the
|
||||
/// context exists within ~1s of server start.</remarks>
|
||||
public static CastleSiegeContext? TryGetContext(IGameContext gameContext)
|
||||
=> Contexts.TryGetValue(gameContext, out var context) ? context : null;
|
||||
|
||||
/// <inheritdoc />
|
||||
public object CreateDefaultConfig() => new CastleSiegeConfiguration();
|
||||
|
||||
/// <inheritdoc />
|
||||
public async ValueTask ExecuteTaskAsync(GameContext gameContext)
|
||||
{
|
||||
var context = Contexts.GetOrAdd(gameContext, _ => new CastleSiegeContext(this.Configuration ?? new CastleSiegeConfiguration()));
|
||||
await context.TickAsync(DateTime.UtcNow).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ForceStart()
|
||||
{
|
||||
// Force-start applies to every active game context's siege.
|
||||
foreach (var context in Contexts.Values)
|
||||
{
|
||||
_ = context.ForceStartRegistrationAsync(DateTime.UtcNow);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user