baseline: OpenMU upstream b5a0961 (fresh source)

This commit is contained in:
Acentech Dev
2026-07-14 19:00:35 +03:00
parent 450402e47d
commit 36fc125d5c
11968 changed files with 748705 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
// <copyright file="GameServerHostedServiceWrapper.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.Host;
using System.Collections.Generic;
using System.Threading;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using MUnique.OpenMU.Dapr.Common;
using MUnique.OpenMU.Interfaces;
using MUnique.OpenMU.PlugIns;
using MUnique.OpenMU.Web.Map;
/// <summary>
/// A wrapper which takes a <see cref="Interfaces.IGameServer"/> and wraps it as <see cref="IHostedLifecycleService"/>,
/// so that additional initialization can be done before actually starting it.
/// The actual server start is deferred to <see cref="StartedAsync"/> which is called after the web application
/// has started (i.e. the HTTP API is already available), breaking the circular startup dependency with the Dapr sidecar.
/// TODO: listen to configuration changes/database reinit.
/// See also: ServerContainerBase.
/// </summary>
public class GameServerHostedServiceWrapper : IHostedLifecycleService
{
private readonly IServiceProvider _serviceProvider;
private IGameServer? _gameServer;
/// <summary>
/// Initializes a new instance of the <see cref="GameServerHostedServiceWrapper"/> class.
/// </summary>
/// <param name="serviceProvider">The service provider.</param>
public GameServerHostedServiceWrapper(IServiceProvider serviceProvider)
{
this._serviceProvider = serviceProvider;
}
/// <inheritdoc/>
public Task StartingAsync(CancellationToken cancellationToken) => Task.CompletedTask;
/// <inheritdoc/>
public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask;
/// <inheritdoc/>
public async Task StartedAsync(CancellationToken cancellationToken)
{
await this._serviceProvider.WaitForDatabaseInitializationAsync(cancellationToken).ConfigureAwait(false);
if (this._serviceProvider.GetService<ICollection<PlugInConfiguration>>() is { } plugInCollection)
{
if (plugInCollection is not List<PlugInConfiguration> plugInConfigurations)
{
throw new InvalidOperationException($"The registered {nameof(ICollection<PlugInConfiguration>)} must be a {nameof(List<PlugInConfiguration>)} to be able to load plugin configurations.");
}
await this._serviceProvider.TryLoadPlugInConfigurationsAsync(plugInConfigurations).ConfigureAwait(false);
}
this._gameServer = this._serviceProvider.GetRequiredService<IGameServer>();
var initializer = this._serviceProvider.GetRequiredService<GameServerInitializer>();
await initializer.InitializeAsync().ConfigureAwait(false);
await ((ObservableGameServerAdapter)this._serviceProvider.GetRequiredService<IObservableGameServer>())
.InitializeAsync().ConfigureAwait(false);
await this._gameServer.StartAsync(cancellationToken).ConfigureAwait(false);
}
/// <inheritdoc/>
public Task StoppingAsync(CancellationToken cancellationToken) => Task.CompletedTask;
/// <inheritdoc/>
public Task StopAsync(CancellationToken cancellationToken)
{
return this._gameServer?.StopAsync(cancellationToken) ?? Task.CompletedTask;
}
/// <inheritdoc/>
public Task StoppedAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}