diff --git a/Application/GameEventHandler.cs b/Application/GameEventHandler.cs index ba9d75217..b370e883b 100644 --- a/Application/GameEventHandler.cs +++ b/Application/GameEventHandler.cs @@ -5,6 +5,7 @@ using SharedLibraryCore.Interfaces; using System; using System.Linq; using System.Threading; +using System.Threading.Tasks; namespace IW4MAdmin.Application { @@ -12,9 +13,6 @@ namespace IW4MAdmin.Application { readonly ApplicationManager Manager; private readonly EventProfiler _profiler; - private delegate void GameEventAddedEventHandler(object sender, GameEventArgs args); - private event GameEventAddedEventHandler GameEventAdded; - private static readonly GameEvent.EventType[] overrideEvents = new[] { GameEvent.EventType.Connect, @@ -27,14 +25,16 @@ namespace IW4MAdmin.Application { Manager = (ApplicationManager)mgr; _profiler = new EventProfiler(mgr.GetLogger(0)); - GameEventAdded += GameEventHandler_GameEventAdded; } - private async void GameEventHandler_GameEventAdded(object sender, GameEventArgs args) + private Task GameEventHandler_GameEventAdded(object sender, GameEventArgs args) { +#if DEBUG var start = DateTime.Now; - await Manager.ExecuteEvent(args.Event); +#endif EventApi.OnGameEvent(sender, args); + return Manager.ExecuteEvent(args.Event); + #if DEBUG _profiler.Profile(start, DateTime.Now, args.Event); #endif @@ -53,7 +53,8 @@ namespace IW4MAdmin.Application #if DEBUG gameEvent.Owner.Logger.WriteDebug($"Adding event with id {gameEvent.Id}"); #endif - GameEventAdded?.Invoke(this, new GameEventArgs(null, false, gameEvent)); + //GameEventAdded?.Invoke(this, new GameEventArgs(null, false, gameEvent)); + Task.Run(() => GameEventHandler_GameEventAdded(this, new GameEventArgs(null, false, gameEvent))); } #if DEBUG else diff --git a/Application/IW4MServer.cs b/Application/IW4MServer.cs index 0cca3c739..498679fba 100644 --- a/Application/IW4MServer.cs +++ b/Application/IW4MServer.cs @@ -152,36 +152,49 @@ namespace IW4MAdmin } } - foreach (var plugin in Manager.Plugins) + try { - try - { - // we don't want to run the events on parser plugins - if (plugin is ScriptPlugin scriptPlugin && scriptPlugin.IsParser) - { - continue; - } + var loginPlugin = Manager.Plugins.FirstOrDefault(_plugin => _plugin.Name == "Login"); - await plugin.OnEventAsync(E, this); - } - catch (AuthorizationException e) + if (loginPlugin != null) { - E.Origin.Tell($"{loc["COMMAND_NOTAUTHORIZED"]} - {e.Message}"); - canExecuteCommand = false; - } - catch (Exception Except) - { - Logger.WriteError($"{loc["SERVER_PLUGIN_ERROR"]} [{plugin.Name}]"); - Logger.WriteDebug(Except.GetExceptionInfo()); + await loginPlugin.OnEventAsync(E, this); } } + catch (AuthorizationException e) + { + E.Origin.Tell($"{loc["COMMAND_NOTAUTHORIZED"]} - {e.Message}"); + canExecuteCommand = false; + } + // hack: this prevents commands from getting executing that 'shouldn't' be if (E.Type == GameEvent.EventType.Command && E.Extra is Command command && (canExecuteCommand || E.Origin?.Level == Permission.Console)) { await command.ExecuteAsync(E); } + + var pluginTasks = Manager.Plugins.Where(_plugin => _plugin.Name != "Login").Select(async _plugin => + { + try + { + // we don't want to run the events on parser plugins + if (_plugin is ScriptPlugin scriptPlugin && scriptPlugin.IsParser) + { + return; + } + + await _plugin.OnEventAsync(E, this); + } + catch (Exception Except) + { + Logger.WriteError($"{loc["SERVER_PLUGIN_ERROR"]} [{_plugin.Name}]"); + Logger.WriteDebug(Except.GetExceptionInfo()); + } + }); + + Parallel.ForEach(pluginTasks, async (_task) => await _task); } catch (Exception e) @@ -944,6 +957,11 @@ namespace IW4MAdmin var logsync = await this.GetDvarAsync("g_logsync"); var ip = await this.GetDvarAsync("net_ip"); + if (Manager.GetApplicationSettings().Configuration().EnableCustomSayName) + { + await this.SetDvarAsync("sv_sayname", Manager.GetApplicationSettings().Configuration().CustomSayName); + } + try { var website = await this.GetDvarAsync("_website"); diff --git a/Application/RCon/RConConnection.cs b/Application/RCon/RConConnection.cs index 9e9634b79..3ced4b19a 100644 --- a/Application/RCon/RConConnection.cs +++ b/Application/RCon/RConConnection.cs @@ -220,7 +220,7 @@ namespace IW4MAdmin.Application.RCon var statusHeaderMatch = config.StatusHeader.PatternMatcher.Match(responseString); if (statusHeaderMatch.Success) { - splitStatusStrings.Insert(0, responseString); + splitStatusStrings.Insert(0, responseString.TrimEnd('\0')); } else diff --git a/Plugins/LiveRadar/Plugin.cs b/Plugins/LiveRadar/Plugin.cs index 8558713fe..20cd22466 100644 --- a/Plugins/LiveRadar/Plugin.cs +++ b/Plugins/LiveRadar/Plugin.cs @@ -17,6 +17,7 @@ namespace LiveRadar public string Author => "RaidMax"; private readonly IConfigurationHandler _configurationHandler; + private bool addedPage; public Plugin(IConfigurationHandlerFactory configurationHandlerFactory) { @@ -27,11 +28,13 @@ namespace LiveRadar { // if it's an IW4 game, with custom callbacks, we want to // enable the live radar page - if (E.Type == GameEvent.EventType.Start && + if (E.Type == GameEvent.EventType.Start && S.GameName == Server.Game.IW4 && - S.CustomCallback) + S.CustomCallback && + !addedPage) { E.Owner.Manager.GetPageList().Pages.Add(Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_RADAR_TITLE"], "/Radar/All"); + addedPage = true; } if (E.Type == GameEvent.EventType.Unknown) diff --git a/SharedLibraryCore/Database/DatabaseContext.cs b/SharedLibraryCore/Database/DatabaseContext.cs index c0201dff8..2e158526d 100644 --- a/SharedLibraryCore/Database/DatabaseContext.cs +++ b/SharedLibraryCore/Database/DatabaseContext.cs @@ -95,10 +95,10 @@ namespace SharedLibraryCore.Database { default: case "mysql": - optionsBuilder.UseMySql(_ConnectionString); + optionsBuilder.UseMySql(_ConnectionString, _options => _options.EnableRetryOnFailure()); break; case "postgresql": - optionsBuilder.UseNpgsql(_ConnectionString); + optionsBuilder.UseNpgsql(_ConnectionString, _options => _options.EnableRetryOnFailure()); break; } } diff --git a/SharedLibraryCore/Events/GameEvent.cs b/SharedLibraryCore/Events/GameEvent.cs index 3298d085a..9d78585f9 100644 --- a/SharedLibraryCore/Events/GameEvent.cs +++ b/SharedLibraryCore/Events/GameEvent.cs @@ -273,11 +273,11 @@ namespace SharedLibraryCore if (!processed) { + Owner?.Logger.WriteError("Waiting for event to complete timed out"); + Owner?.Logger.WriteDebug($"{Id}, {Type}, {Data}, {Extra}, {FailReason.ToString()}, {Message}, {Origin}, {Target}"); #if DEBUG throw new Exception(); #endif - Owner?.Logger.WriteError("Waiting for event to complete timed out"); - Owner?.Logger.WriteDebug($"{Id}, {Type}, {Data}, {Extra}, {FailReason.ToString()}, {Message}, {Origin}, {Target}"); } diff --git a/SharedLibraryCore/Server.cs b/SharedLibraryCore/Server.cs index 0807eb191..2ca24a086 100644 --- a/SharedLibraryCore/Server.cs +++ b/SharedLibraryCore/Server.cs @@ -147,7 +147,7 @@ namespace SharedLibraryCore protected async Task Tell(string message, EFClient target) { #if !DEBUG - string formattedMessage = string.Format(RconParser.Configuration.CommandPrefixes.Tell, target.ClientNumber, $"{(CustomSayEnabled ? $"{CustomSayName}: " : "")}{message.FixIW4ForwardSlash()}"); + string formattedMessage = string.Format(RconParser.Configuration.CommandPrefixes.Tell, target.ClientNumber, $"{(CustomSayEnabled && GameName == Game.IW4 ? $"{CustomSayName}: " : "")}{message.FixIW4ForwardSlash()}"); if (target.ClientNumber > -1 && message.Length > 0 && target.Level != EFClient.Permission.Console) await this.ExecuteCommandAsync(formattedMessage); #else