only unload plugins once at shutdown

clean up some doc warnings
This commit is contained in:
RaidMax 2022-03-24 11:34:32 -05:00
parent c93f896bc5
commit a863f78678
16 changed files with 69 additions and 42 deletions

View File

@ -587,16 +587,29 @@ namespace IW4MAdmin.Application
public async Task Start() => await UpdateServerStates(); public async Task Start() => await UpdateServerStates();
public void Stop() public async Task Stop()
{ {
_tokenSource.Cancel(); _tokenSource.Cancel();
foreach (var plugin in Plugins)
{
try
{
await plugin.OnUnloadAsync();
}
catch (Exception ex)
{
_logger.LogError(ex, "Could not cleanly unload plugin {PluginName}", plugin.Name);
}
}
IsRunning = false; IsRunning = false;
} }
public void Restart() public void Restart()
{ {
IsRestartRequested = true; IsRestartRequested = true;
Stop(); Stop().GetAwaiter().GetResult();
} }
[Obsolete] [Obsolete]

View File

@ -903,11 +903,6 @@ namespace IW4MAdmin
await e.WaitAsync(Utilities.DefaultCommandTimeout, new CancellationTokenRegistration().Token); await e.WaitAsync(Utilities.DefaultCommandTimeout, new CancellationTokenRegistration().Token);
} }
foreach (var plugin in Manager.Plugins)
{
await plugin.OnUnloadAsync();
}
} }
DateTime start = DateTime.Now; DateTime start = DateTime.Now;

View File

@ -77,8 +77,12 @@ namespace IW4MAdmin.Application
/// <param name="e"></param> /// <param name="e"></param>
private static async void OnCancelKey(object sender, ConsoleCancelEventArgs e) private static async void OnCancelKey(object sender, ConsoleCancelEventArgs e)
{ {
_serverManager?.Stop(); if (_serverManager is not null)
if (_applicationTask != null) {
await _serverManager.Stop();
}
if (_applicationTask is not null)
{ {
await _applicationTask; await _applicationTask;
} }
@ -153,8 +157,11 @@ namespace IW4MAdmin.Application
{ {
Console.WriteLine(e.Message); Console.WriteLine(e.Message);
} }
_serverManager?.Stop(); if (_serverManager is not null)
{
await _serverManager?.Stop();
}
Console.WriteLine(exitMessage); Console.WriteLine(exitMessage);
await Console.In.ReadAsync(new char[1], 0, 1); await Console.In.ReadAsync(new char[1], 0, 1);

View File

@ -33,10 +33,9 @@ namespace SharedLibraryCore.Commands
RequiresTarget = false; RequiresTarget = false;
} }
public override Task ExecuteAsync(GameEvent E) public override async Task ExecuteAsync(GameEvent E)
{ {
E.Owner.Manager.Stop(); await E.Owner.Manager.Stop();
return Task.CompletedTask;
} }
} }
@ -731,7 +730,7 @@ namespace SharedLibraryCore.Commands
var ruleFormat = rules.Select(r => $"- {r}"); var ruleFormat = rules.Select(r => $"- {r}");
if (gameEvent.Message.IsBroadcastCommand(_config.BroadcastCommandPrefix)) if (gameEvent.Message.IsBroadcastCommand(_config.BroadcastCommandPrefix))
{ {
gameEvent.Owner.Broadcast(ruleFormat); await gameEvent.Owner.BroadcastAsync(ruleFormat, token: gameEvent.Owner.Manager.CancellationToken);
} }
else else
{ {

View File

@ -8,6 +8,7 @@ namespace SharedLibraryCore.Helpers
/// Generate password hash and salt /// Generate password hash and salt
/// </summary> /// </summary>
/// <param name="password">plaintext password</param> /// <param name="password">plaintext password</param>
/// <param name="saltStr">salt of password</param>
/// <returns></returns> /// <returns></returns>
public static string[] Hash(string password, string saltStr = null) public static string[] Hash(string password, string saltStr = null)
{ {
@ -35,4 +36,4 @@ namespace SharedLibraryCore.Helpers
}; };
} }
} }
} }

View File

@ -32,7 +32,7 @@ namespace SharedLibraryCore.Interfaces
ConcurrentDictionary<long, GameEvent> ProcessingEvents { get; } ConcurrentDictionary<long, GameEvent> ProcessingEvents { get; }
Task Init(); Task Init();
Task Start(); Task Start();
void Stop(); Task Stop();
void Restart(); void Restart();
[Obsolete] [Obsolete]
@ -103,4 +103,4 @@ namespace SharedLibraryCore.Interfaces
/// </summary> /// </summary>
event EventHandler<GameEvent> OnGameEventExecuted; event EventHandler<GameEvent> OnGameEventExecuted;
} }
} }

View File

@ -17,6 +17,7 @@ namespace SharedLibraryCore.Interfaces
/// <param name="metaKey">key of meta data</param> /// <param name="metaKey">key of meta data</param>
/// <param name="metaValue">value of the meta data</param> /// <param name="metaValue">value of the meta data</param>
/// <param name="client">client to save the meta for</param> /// <param name="client">client to save the meta for</param>
/// <param name="linkedMeta"></param>
/// <returns></returns> /// <returns></returns>
Task AddPersistentMeta(string metaKey, string metaValue, EFClient client, EFMeta linkedMeta = null); Task AddPersistentMeta(string metaKey, string metaValue, EFClient client, EFMeta linkedMeta = null);

View File

@ -42,7 +42,6 @@ public interface IMetaServiceV2
/// <param name="lookupId">Id in the list of lookup values</param> /// <param name="lookupId">Id in the list of lookup values</param>
/// <param name="clientId">id of the client</param> /// <param name="clientId">id of the client</param>
/// <param name="token"></param> /// <param name="token"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns> /// <returns></returns>
Task SetPersistentMetaForLookupKey(string metaKey, string lookupKey, int lookupId, int clientId, Task SetPersistentMetaForLookupKey(string metaKey, string lookupKey, int lookupId, int clientId,
CancellationToken token = default); CancellationToken token = default);
@ -100,7 +99,6 @@ public interface IMetaServiceV2
/// <param name="lookupKey"></param> /// <param name="lookupKey"></param>
/// <param name="clientId"></param> /// <param name="clientId"></param>
/// <param name="token"></param> /// <param name="token"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns> /// <returns></returns>
Task<EFMeta> GetPersistentMetaByLookup(string metaKey, string lookupKey, int clientId, Task<EFMeta> GetPersistentMetaByLookup(string metaKey, string lookupKey, int clientId,
CancellationToken token = default); CancellationToken token = default);
@ -141,7 +139,6 @@ public interface IMetaServiceV2
/// removes meta key with given value /// removes meta key with given value
/// </summary> /// </summary>
/// <param name="metaKey">key of the meta data</param> /// <param name="metaKey">key of the meta data</param>
/// <param name="metaValue">value of the meta data</param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task RemovePersistentMeta(string metaKey, CancellationToken token = default); Task RemovePersistentMeta(string metaKey, CancellationToken token = default);

View File

@ -14,6 +14,7 @@ namespace SharedLibraryCore.Interfaces
/// </summary> /// </summary>
/// <param name="type">type of RCon query to perform</param> /// <param name="type">type of RCon query to perform</param>
/// <param name="parameters">optional parameter list</param> /// <param name="parameters">optional parameter list</param>
/// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<string[]> SendQueryAsync(StaticHelpers.QueryType type, string parameters = "", CancellationToken token = default); Task<string[]> SendQueryAsync(StaticHelpers.QueryType type, string parameters = "", CancellationToken token = default);

View File

@ -52,6 +52,7 @@ namespace SharedLibraryCore.Interfaces
/// <param name="connection">RCon connection to retrieve with</param> /// <param name="connection">RCon connection to retrieve with</param>
/// <param name="dvarName">name of DVAR</param> /// <param name="dvarName">name of DVAR</param>
/// <param name="fallbackValue">default value to return if dvar retrieval fails</param> /// <param name="fallbackValue">default value to return if dvar retrieval fails</param>
/// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<Dvar<T>> GetDvarAsync<T>(IRConConnection connection, string dvarName, T fallbackValue = default, CancellationToken token = default); Task<Dvar<T>> GetDvarAsync<T>(IRConConnection connection, string dvarName, T fallbackValue = default, CancellationToken token = default);
@ -61,6 +62,7 @@ namespace SharedLibraryCore.Interfaces
/// <param name="connection">RCon connection to use</param> /// <param name="connection">RCon connection to use</param>
/// <param name="dvarName">name of DVAR to set</param> /// <param name="dvarName">name of DVAR to set</param>
/// <param name="dvarValue">value to set DVAR to</param> /// <param name="dvarValue">value to set DVAR to</param>
/// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<bool> SetDvarAsync(IRConConnection connection, string dvarName, object dvarValue, CancellationToken token = default); Task<bool> SetDvarAsync(IRConConnection connection, string dvarName, object dvarValue, CancellationToken token = default);
@ -69,13 +71,15 @@ namespace SharedLibraryCore.Interfaces
/// </summary> /// </summary>
/// <param name="connection">RCon connection to use</param> /// <param name="connection">RCon connection to use</param>
/// <param name="command">console command to execute</param> /// <param name="command">console command to execute</param>
/// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<string[]> ExecuteCommandAsync(IRConConnection connection, string command, CancellationToken token = default); Task<string[]> ExecuteCommandAsync(IRConConnection connection, string command, CancellationToken token = default);
/// <summary> /// <summary>
/// get the list of connected clients from status response /// get the list of connected clients from status response
/// </summary> /// </summary>
/// <param name="connection">RCon connection to use</param> /// <param name="connection">RCon connection to use</param>
/// <param name="token"></param>
/// <returns> /// <returns>
/// <see cref="IStatusResponse" /> /// <see cref="IStatusResponse" />
/// </returns> /// </returns>

View File

@ -16,8 +16,8 @@
/// resolves a service with the given name and generic params /// resolves a service with the given name and generic params
/// </summary> /// </summary>
/// <param name="serviceName">class name of service</param> /// <param name="serviceName">class name of service</param>
/// <param name="genericParams">generic class names</param> /// <param name="genericParameters">generic class names</param>
/// <returns></returns> /// <returns></returns>
object ResolveService(string serviceName, string[] genericParameters); object ResolveService(string serviceName, string[] genericParameters);
} }
} }

View File

@ -14,8 +14,9 @@ namespace SharedLibraryCore.Interfaces
/// <summary> /// <summary>
/// authorizes given token /// authorizes given token
/// </summary> /// </summary>
/// <param name="networkId">network id of the client to authorize</param>
/// <param name="token">token to authorize</param> /// <param name="token">token to authorize</param>
/// <returns>true if token authorized successfully, false otherwise</returns> /// <returns>true if token authorized successfully, false otherwise</returns>
bool AuthorizeToken(long networkId, string token); bool AuthorizeToken(long networkId, string token);
} }
} }

View File

@ -307,6 +307,7 @@ namespace SharedLibraryCore.Database.Models
/// </summary> /// </summary>
/// <param name="flagReason">reason for flagging</param> /// <param name="flagReason">reason for flagging</param>
/// <param name="sender">client performing the flag</param> /// <param name="sender">client performing the flag</param>
/// <param name="flagLength">how long the flag should last</param>
/// <returns>game event for the flag</returns> /// <returns>game event for the flag</returns>
public GameEvent Flag(string flagReason, EFClient sender, TimeSpan? flagLength = null) public GameEvent Flag(string flagReason, EFClient sender, TimeSpan? flagLength = null)
{ {
@ -442,6 +443,7 @@ namespace SharedLibraryCore.Database.Models
/// </summary> /// </summary>
/// <param name="banReason">reason for the ban</param> /// <param name="banReason">reason for the ban</param>
/// <param name="sender">client performing the ban</param> /// <param name="sender">client performing the ban</param>
/// <param name="isEvade">obsolete</param>
public GameEvent Ban(string banReason, EFClient sender, bool isEvade) public GameEvent Ban(string banReason, EFClient sender, bool isEvade)
{ {
var e = new GameEvent var e = new GameEvent

View File

@ -159,14 +159,13 @@ namespace SharedLibraryCore
/// Add a player to the server's player list /// Add a player to the server's player list
/// </summary> /// </summary>
/// <param name="P">EFClient pulled from memory reading</param> /// <param name="P">EFClient pulled from memory reading</param>
/// <returns>True if player added sucessfully, false otherwise</returns> /// <returns>True if player added successfully, false otherwise</returns>
public abstract Task<EFClient> OnClientConnected(EFClient P); public abstract Task<EFClient> OnClientConnected(EFClient P);
/// <summary> /// <summary>
/// Remove player by client number /// Remove player by client number
/// </summary> /// </summary>
/// <param name="cNum">Client ID of player to be removed</param> /// <returns>true if removal succeeded, false otherwise</returns>
/// <returns>true if removal succeded, false otherwise</returns>
public abstract Task OnClientDisconnected(EFClient client); public abstract Task OnClientDisconnected(EFClient client);
/// <summary> /// <summary>
@ -219,6 +218,7 @@ namespace SharedLibraryCore
/// Send a message to all players /// Send a message to all players
/// </summary> /// </summary>
/// <param name="message">Message to be sent to all players</param> /// <param name="message">Message to be sent to all players</param>
/// <param name="sender">Client that initiated the broadcast</param>
public GameEvent Broadcast(string message, EFClient sender = null) public GameEvent Broadcast(string message, EFClient sender = null)
{ {
var formattedMessage = string.Format(RconParser.Configuration.CommandPrefixes.Say ?? "", var formattedMessage = string.Format(RconParser.Configuration.CommandPrefixes.Say ?? "",
@ -322,39 +322,44 @@ namespace SharedLibraryCore
/// Kick a player from the server /// Kick a player from the server
/// </summary> /// </summary>
/// <param name="reason">Reason for kicking</param> /// <param name="reason">Reason for kicking</param>
/// <param name="Target">EFClient to kick</param> /// <param name="target">EFClient to kick</param>
public Task Kick(string reason, EFClient Target, EFClient Origin) /// <param name="origin">Client initating the kick</param>
public Task Kick(string reason, EFClient target, EFClient origin)
{ {
return Kick(reason, Target, Origin, null); return Kick(reason, target, origin, null);
} }
/// <summary> /// <summary>
/// Temporarily ban a player ( default 1 hour ) from the server /// Temporarily ban a player ( default 1 hour ) from the server
/// </summary> /// </summary>
/// <param name="reason">Reason for banning the player</param> /// <param name="reason">Reason for banning the player</param>
/// <param name="Target">The player to ban</param> /// <param name="length">Duration of the ban</param>
public abstract Task TempBan(string reason, TimeSpan length, EFClient Target, EFClient Origin); /// <param name="target">The client to ban</param>
/// <param name="origin">The client performing the ban</param>
public abstract Task TempBan(string reason, TimeSpan length, EFClient target, EFClient origin);
/// <summary> /// <summary>
/// Perm ban a player from the server /// Perm ban a player from the server
/// </summary> /// </summary>
/// <param name="Reason">The reason for the ban</param> /// <param name="reason">The reason for the ban</param>
/// <param name="Target">The person to ban</param> /// <param name="target">The person to ban</param>
/// <param name="Origin">The person who banned the target</param> /// <param name="origin">The person who banned the target</param>
public abstract Task Ban(string Reason, EFClient Target, EFClient Origin, bool isEvade = false); /// <param name="isEvade">obsolete</param>
public abstract Task Ban(string reason, EFClient target, EFClient origin, bool isEvade = false);
public abstract Task Warn(string Reason, EFClient Target, EFClient Origin); public abstract Task Warn(string reason, EFClient target, EFClient origin);
/// <summary> /// <summary>
/// Unban a player by npID / GUID /// Unban a player by npID / GUID
/// </summary> /// </summary>
/// <param name="npID">npID of the player</param> /// <param name="reason">reason for unban</param>
/// <param name="targetClient">I don't remember what this is for</param> /// <param name="targetClient">client being unbanned</param>
/// <param name="originClient">client performing the unban</param>
/// <returns></returns> /// <returns></returns>
public abstract Task Unban(string reason, EFClient targetClient, EFClient originClient); public abstract Task Unban(string reason, EFClient targetClient, EFClient originClient);
/// <summary> /// <summary>
/// Change the current searver map /// Change the current server map
/// </summary> /// </summary>
/// <param name="mapName">Non-localized map name</param> /// <param name="mapName">Non-localized map name</param>
public async Task LoadMap(string mapName) public async Task LoadMap(string mapName)

View File

@ -593,7 +593,6 @@ namespace SharedLibraryCore.Services
/// <param name="newPermission"></param> /// <param name="newPermission"></param>
/// <param name="temporalClient"></param> /// <param name="temporalClient"></param>
/// <param name="origin"></param> /// <param name="origin"></param>
/// <param name="ctx"></param>
/// <returns></returns> /// <returns></returns>
public virtual async Task UpdateLevel(Permission newPermission, EFClient temporalClient, EFClient origin) public virtual async Task UpdateLevel(Permission newPermission, EFClient temporalClient, EFClient origin)
{ {

View File

@ -121,7 +121,9 @@ namespace WebfrontCore
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<IAuditInformationRepository>()); services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<IAuditInformationRepository>());
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<ITranslationLookup>()); services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<ITranslationLookup>());
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<IEnumerable<IManagerCommand>>()); services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<IEnumerable<IManagerCommand>>());
#pragma warning disable CS0618
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<IMetaService>()); services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<IMetaService>());
#pragma warning restore CS0618
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<IMetaServiceV2>()); services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<IMetaServiceV2>());
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<ApplicationConfiguration>()); services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<ApplicationConfiguration>());
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<ClientService>()); services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<ClientService>());