1
0
mirror of https://github.com/RaidMax/IW4M-Admin.git synced 2025-06-10 15:20:48 -05:00

implement new eventing system

This commit is contained in:
RaidMax
2023-04-05 09:54:57 -05:00
parent 53a6ef2ec3
commit ebe69a94ad
39 changed files with 1410 additions and 526 deletions

View File

@ -51,7 +51,7 @@ namespace IW4MAdmin.Application
public static BuildNumber Version { get; } = BuildNumber.Parse(Utilities.GetVersionAsString());
private static ApplicationManager _serverManager;
private static Task _applicationTask;
private static ServiceProvider _serviceProvider;
private static IServiceProvider _serviceProvider;
/// <summary>
/// entrypoint of the application
@ -112,23 +112,24 @@ namespace IW4MAdmin.Application
ConfigurationMigration.MoveConfigFolder10518(null);
ConfigurationMigration.CheckDirectories();
ConfigurationMigration.RemoveObsoletePlugins20210322();
logger.LogDebug("Configuring services...");
var services = await ConfigureServices(args);
_serviceProvider = services.BuildServiceProvider();
var versionChecker = _serviceProvider.GetRequiredService<IMasterCommunication>();
_serverManager = (ApplicationManager) _serviceProvider.GetRequiredService<IManager>();
translationLookup = _serviceProvider.GetRequiredService<ITranslationLookup>();
_applicationTask = RunApplicationTasksAsync(logger, services);
var tasks = new[]
{
versionChecker.CheckVersion(),
_applicationTask
};
var configHandler = new BaseConfigurationHandler<ApplicationConfiguration>("IW4MAdminSettings");
await configHandler.BuildAsync();
_serviceProvider = WebfrontCore.Program.InitializeServices(ConfigureServices,
(configHandler.Configuration() ?? new ApplicationConfiguration()).WebfrontBindUrl);
_serverManager = (ApplicationManager)_serviceProvider.GetRequiredService<IManager>();
translationLookup = _serviceProvider.GetRequiredService<ITranslationLookup>();
await _serverManager.Init();
await Task.WhenAll(tasks);
_applicationTask = Task.WhenAll(RunApplicationTasksAsync(logger, _serviceProvider),
_serverManager.Start());
await _applicationTask;
logger.LogInformation("Shutdown completed successfully");
}
catch (Exception e)
@ -178,21 +179,20 @@ namespace IW4MAdmin.Application
{
goto restart;
}
await _serviceProvider.DisposeAsync();
}
/// <summary>
/// runs the core application tasks
/// </summary>
/// <returns></returns>
private static async Task RunApplicationTasksAsync(ILogger logger, IServiceCollection services)
private static Task RunApplicationTasksAsync(ILogger logger, IServiceProvider serviceProvider)
{
var webfrontTask = _serverManager.GetApplicationSettings().Configuration().EnableWebFront
? WebfrontCore.Program.Init(_serverManager, _serviceProvider, services, _serverManager.CancellationToken)
? WebfrontCore.Program.GetWebHostTask(_serverManager.CancellationToken)
: Task.CompletedTask;
var collectionService = _serviceProvider.GetRequiredService<IServerDataCollector>();
var collectionService = serviceProvider.GetRequiredService<IServerDataCollector>();
var versionChecker = serviceProvider.GetRequiredService<IMasterCommunication>();
// we want to run this one on a manual thread instead of letting the thread pool handle it,
// because we can't exit early from waiting on console input, and it prevents us from restarting
@ -203,18 +203,15 @@ namespace IW4MAdmin.Application
var tasks = new[]
{
versionChecker.CheckVersion(),
webfrontTask,
_serverManager.Start(),
_serviceProvider.GetRequiredService<IMasterCommunication>()
serviceProvider.GetRequiredService<IMasterCommunication>()
.RunUploadStatus(_serverManager.CancellationToken),
collectionService.BeginCollectionAsync(cancellationToken: _serverManager.CancellationToken)
};
logger.LogDebug("Starting webfront and input tasks");
await Task.WhenAll(tasks);
logger.LogInformation("Shutdown completed successfully");
Console.WriteLine(Utilities.CurrentLocalization.LocalizationIndex["MANAGER_SHUTDOWN_SUCCESS"]);
return Task.WhenAll(tasks);
}
/// <summary>
@ -302,8 +299,21 @@ namespace IW4MAdmin.Application
var (plugins, commands, configurations) = pluginImporter.DiscoverAssemblyPluginImplementations();
foreach (var pluginType in plugins)
{
defaultLogger.LogDebug("Registered plugin type {Name}", pluginType.FullName);
serviceCollection.AddSingleton(typeof(IPlugin), pluginType);
var isV2 = pluginType.GetInterface(nameof(IPluginV2), false) != null;
defaultLogger.LogDebug("Registering plugin type {Name}", pluginType.FullName);
serviceCollection.AddSingleton(!isV2 ? typeof(IPlugin) : typeof(IPluginV2), pluginType);
try
{
var registrationMethod = pluginType.GetMethod(nameof(IPluginV2.RegisterDependencies));
registrationMethod?.Invoke(null, new object[] { serviceCollection });
}
catch (Exception ex)
{
defaultLogger.LogError(ex, "Could not register plugin of type {Type}", pluginType.Name);
}
}
// register the plugin commands
@ -351,13 +361,11 @@ namespace IW4MAdmin.Application
/// <summary>
/// Configures the dependency injection services
/// </summary>
private static async Task<IServiceCollection> ConfigureServices(string[] args)
private static void ConfigureServices(IServiceCollection serviceCollection)
{
// todo: this is a quick fix
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
// setup the static resources (config/master api/translations)
var serviceCollection = new ServiceCollection();
serviceCollection.AddConfiguration<ApplicationConfiguration>("IW4MAdminSettings")
.AddConfiguration<DefaultSettings>()
.AddConfiguration<CommandConfiguration>()
@ -365,14 +373,10 @@ namespace IW4MAdmin.Application
// for legacy purposes. update at some point
var appConfigHandler = new BaseConfigurationHandler<ApplicationConfiguration>("IW4MAdminSettings");
await appConfigHandler.BuildAsync();
var defaultConfigHandler = new BaseConfigurationHandler<DefaultSettings>("DefaultSettings");
await defaultConfigHandler.BuildAsync();
appConfigHandler.BuildAsync().GetAwaiter().GetResult();
var commandConfigHandler = new BaseConfigurationHandler<CommandConfiguration>("CommandConfiguration");
await commandConfigHandler.BuildAsync();
var statsCommandHandler = new BaseConfigurationHandler<StatsConfiguration>("StatsPluginSettings");
await statsCommandHandler.BuildAsync();
var defaultConfig = defaultConfigHandler.Configuration();
commandConfigHandler.BuildAsync().GetAwaiter().GetResult();
var appConfig = appConfigHandler.Configuration();
var masterUri = Utilities.IsDevelopment
? new Uri("http://127.0.0.1:8080")
@ -385,13 +389,6 @@ namespace IW4MAdmin.Application
var masterRestClient = RestClient.For<IMasterApi>(httpClient);
var translationLookup = Configure.Initialize(Utilities.DefaultLogger, masterRestClient, appConfig);
if (appConfig == null)
{
appConfig = (ApplicationConfiguration) new ApplicationConfiguration().Generate();
appConfigHandler.Set(appConfig);
await appConfigHandler.Save();
}
// register override level names
foreach (var (key, value) in appConfig.OverridePermissionLevelNames)
{
@ -402,17 +399,10 @@ namespace IW4MAdmin.Application
}
// build the dependency list
HandlePluginRegistration(appConfig, serviceCollection, masterRestClient);
serviceCollection
.AddBaseLogger(appConfig)
.AddSingleton(defaultConfig)
.AddSingleton<IServiceCollection>(serviceCollection)
.AddSingleton<IConfigurationHandler<DefaultSettings>, BaseConfigurationHandler<DefaultSettings>>()
.AddSingleton((IConfigurationHandler<ApplicationConfiguration>) appConfigHandler)
.AddSingleton<IConfigurationHandler<CommandConfiguration>>(commandConfigHandler)
.AddSingleton(appConfig)
.AddSingleton(statsCommandHandler.Configuration() ?? new StatsConfiguration())
.AddSingleton(serviceProvider =>
serviceProvider.GetRequiredService<IConfigurationHandler<CommandConfiguration>>()
.Configuration() ?? new CommandConfiguration())
@ -464,7 +454,9 @@ namespace IW4MAdmin.Application
.AddSingleton<IServerDataCollector, ServerDataCollector>()
.AddSingleton<IGeoLocationService>(new GeoLocationService(Path.Join(".", "Resources", "GeoLite2-Country.mmdb")))
.AddSingleton<IAlertManager, AlertManager>()
#pragma warning disable CS0618
.AddTransient<IScriptPluginTimerHelper, ScriptPluginTimerHelper>()
#pragma warning restore CS0618
.AddSingleton<IInteractionRegistration, InteractionRegistration>()
.AddSingleton<IRemoteCommandService, RemoteCommandService>()
.AddSingleton(new ConfigurationWatcher())
@ -472,19 +464,10 @@ namespace IW4MAdmin.Application
.AddSingleton<IScriptPluginFactory, ScriptPluginFactory>()
.AddSingleton(translationLookup)
.AddDatabaseContextOptions(appConfig);
if (args.Contains("serialevents"))
{
serviceCollection.AddSingleton<IEventHandler, SerialGameEventHandler>();
}
else
{
serviceCollection.AddSingleton<IEventHandler, GameEventHandler>();
}
serviceCollection.AddSingleton<ICoreEventHandler, CoreEventHandler>();
serviceCollection.AddSource();
return serviceCollection;
HandlePluginRegistration(appConfig, serviceCollection, masterRestClient);
}
private static ILogger BuildDefaultLogger<T>(ApplicationConfiguration appConfig)