diff --git a/Application/API/Master/Heartbeat.cs b/Application/API/Master/Heartbeat.cs deleted file mode 100644 index cab6a81cc..000000000 --- a/Application/API/Master/Heartbeat.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using RestEase; - -namespace IW4MAdmin.Application.API.Master -{ - /// - /// Defines the heartbeat functionality for IW4MAdmin - /// - public class Heartbeat - { - /// - /// Sends heartbeat to master server - /// - /// - /// - /// - public static async Task Send(ApplicationManager mgr, bool firstHeartbeat = false) - { - var api = Endpoint.Get(); - - if (firstHeartbeat) - { - var token = await api.Authenticate(new AuthenticationId() - { - Id = mgr.GetApplicationSettings().Configuration().Id - }); - - api.AuthorizationToken = $"Bearer {token.AccessToken}"; - } - - var instance = new ApiInstance() - { - Id = mgr.GetApplicationSettings().Configuration().Id, - Uptime = (int)(DateTime.UtcNow - mgr.StartTime).TotalSeconds, - Version = Program.Version, - Servers = mgr.Servers.Select(s => - new ApiServer() - { - ClientNum = s.ClientNum, - Game = s.GameName.ToString(), - Version = s.Version, - Gametype = s.Gametype, - Hostname = s.Hostname, - Map = s.CurrentMap.Name, - MaxClientNum = s.MaxClients, - Id = s.EndPoint, - Port = (short)s.Port, - IPAddress = s.IP - }).ToList() - }; - - Response response = null; - - if (firstHeartbeat) - { - response = await api.AddInstance(instance); - } - - else - { - response = await api.UpdateInstance(instance.Id, instance); - } - - if (response.ResponseMessage.StatusCode != System.Net.HttpStatusCode.OK) - { - mgr.Logger.WriteWarning($"Response code from master is {response.ResponseMessage.StatusCode}, message is {response.StringContent}"); - } - } - } -} diff --git a/Application/API/Master/IMasterApi.cs b/Application/API/Master/IMasterApi.cs index d31c22e82..afac522c5 100644 --- a/Application/API/Master/IMasterApi.cs +++ b/Application/API/Master/IMasterApi.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Collections.Generic; using System.Threading.Tasks; using Newtonsoft.Json; using RestEase; @@ -37,16 +35,6 @@ namespace IW4MAdmin.Application.API.Master public string Message { get; set; } } - public class Endpoint - { -#if !DEBUG - private static readonly IMasterApi api = RestClient.For("http://api.raidmax.org:5000"); -#else - private static readonly IMasterApi api = RestClient.For("http://127.0.0.1"); -#endif - public static IMasterApi Get() => api; - } - /// /// Defines the capabilities of the master API /// diff --git a/Application/ApplicationManager.cs b/Application/ApplicationManager.cs index 6c15459bc..1d059d37c 100644 --- a/Application/ApplicationManager.cs +++ b/Application/ApplicationManager.cs @@ -648,85 +648,7 @@ namespace IW4MAdmin.Application } } - private async Task SendHeartbeat() - { - bool connected = false; - - while (!_tokenSource.IsCancellationRequested) - { - if (!connected) - { - try - { - await Heartbeat.Send(this, true); - connected = true; - } - - catch (Exception e) - { - connected = false; - Logger.WriteWarning($"Could not connect to heartbeat server - {e.Message}"); - } - } - - else - { - try - { - await Heartbeat.Send(this); - } - - catch (System.Net.Http.HttpRequestException e) - { - Logger.WriteWarning($"Could not send heartbeat - {e.Message}"); - } - - catch (AggregateException e) - { - Logger.WriteWarning($"Could not send heartbeat - {e.Message}"); - var exceptions = e.InnerExceptions.Where(ex => ex.GetType() == typeof(RestEase.ApiException)); - - foreach (var ex in exceptions) - { - if (((RestEase.ApiException)ex).StatusCode == System.Net.HttpStatusCode.Unauthorized) - { - connected = false; - } - } - } - - catch (RestEase.ApiException e) - { - Logger.WriteWarning($"Could not send heartbeat - {e.Message}"); - if (e.StatusCode == System.Net.HttpStatusCode.Unauthorized) - { - connected = false; - } - } - - catch (Exception e) - { - Logger.WriteWarning($"Could not send heartbeat - {e.Message}"); - } - - } - - try - { - await Task.Delay(30000, _tokenSource.Token); - } - catch { break; } - } - } - - public async Task Start() - { - await Task.WhenAll(new[] - { - SendHeartbeat(), - UpdateServerStates() - }); - } + public async Task Start() => await UpdateServerStates(); public void Stop() { diff --git a/Application/Localization/Configure.cs b/Application/Localization/Configure.cs index a22e88da8..2a275c724 100644 --- a/Application/Localization/Configure.cs +++ b/Application/Localization/Configure.cs @@ -11,7 +11,7 @@ namespace IW4MAdmin.Application.Localization { public class Configure { - public static ITranslationLookup Initialize(bool useLocalTranslation, string customLocale = null) + public static ITranslationLookup Initialize(bool useLocalTranslation, IMasterApi apiInstance, string customLocale = null) { string currentLocale = string.IsNullOrEmpty(customLocale) ? CultureInfo.CurrentCulture.Name : customLocale; string[] localizationFiles = Directory.GetFiles(Path.Join(Utilities.OperatingDirectory, "Localization"), $"*.{currentLocale}.json"); @@ -20,8 +20,7 @@ namespace IW4MAdmin.Application.Localization { try { - var api = Endpoint.Get(); - var localization = api.GetLocalization(currentLocale).Result; + var localization = apiInstance.GetLocalization(currentLocale).Result; Utilities.CurrentLocalization = localization; return localization.LocalizationIndex; } diff --git a/Application/Main.cs b/Application/Main.cs index 919a99c8f..d0da6cd53 100644 --- a/Application/Main.cs +++ b/Application/Main.cs @@ -1,9 +1,11 @@ -using IW4MAdmin.Application.EventParsers; +using IW4MAdmin.Application.API.Master; +using IW4MAdmin.Application.EventParsers; using IW4MAdmin.Application.Factories; using IW4MAdmin.Application.Helpers; using IW4MAdmin.Application.Migration; using IW4MAdmin.Application.Misc; using Microsoft.Extensions.DependencyInjection; +using RestEase; using SharedLibraryCore; using SharedLibraryCore.Configuration; using SharedLibraryCore.Exceptions; @@ -23,7 +25,6 @@ namespace IW4MAdmin.Application public static BuildNumber Version { get; private set; } = BuildNumber.Parse(Utilities.GetVersionAsString()); public static ApplicationManager ServerManager; private static Task ApplicationTask; - private static readonly BuildNumber _fallbackVersion = BuildNumber.Parse("99.99.99.99"); private static ServiceProvider serviceProvider; /// @@ -76,12 +77,13 @@ namespace IW4MAdmin.Application var services = ConfigureServices(args); serviceProvider = services.BuildServiceProvider(); + var versionChecker = serviceProvider.GetRequiredService(); ServerManager = (ApplicationManager)serviceProvider.GetRequiredService(); translationLookup = serviceProvider.GetRequiredService(); ServerManager.Logger.WriteInfo(Utilities.CurrentLocalization.LocalizationIndex["MANAGER_VERSION"].FormatExt(Version)); - await CheckVersion(translationLookup); + await versionChecker.CheckVersion(); await ServerManager.Init(); } @@ -155,6 +157,7 @@ namespace IW4MAdmin.Application { ServerManager.Start(), webfrontTask, + serviceProvider.GetRequiredService().RunUploadStatus(ServerManager.CancellationToken) }; await Task.WhenAll(tasks); @@ -162,68 +165,6 @@ namespace IW4MAdmin.Application ServerManager.Logger.WriteVerbose(Utilities.CurrentLocalization.LocalizationIndex["MANAGER_SHUTDOWN_SUCCESS"]); } - /// - /// checks for latest version of the application - /// notifies user if an update is available - /// - /// - private static async Task CheckVersion(ITranslationLookup translationLookup) - { - var api = API.Master.Endpoint.Get(); - var loc = translationLookup; - - var version = new API.Master.VersionInfo() - { - CurrentVersionStable = _fallbackVersion - }; - - try - { - version = await api.GetVersion(1); - } - - catch (Exception e) - { - ServerManager.Logger.WriteWarning(loc["MANAGER_VERSION_FAIL"]); - while (e.InnerException != null) - { - e = e.InnerException; - } - - ServerManager.Logger.WriteDebug(e.Message); - } - - if (version.CurrentVersionStable == _fallbackVersion) - { - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine(loc["MANAGER_VERSION_FAIL"]); - Console.ForegroundColor = ConsoleColor.Gray; - } - -#if !PRERELEASE - else if (version.CurrentVersionStable > Version) - { - Console.ForegroundColor = ConsoleColor.DarkYellow; - Console.WriteLine($"IW4MAdmin {loc["MANAGER_VERSION_UPDATE"]} [v{version.CurrentVersionStable.ToString()}]"); - Console.WriteLine(loc["MANAGER_VERSION_CURRENT"].FormatExt($"[v{Version.ToString()}]")); - Console.ForegroundColor = ConsoleColor.Gray; - } -#else - else if (version.CurrentVersionPrerelease > Version) - { - Console.ForegroundColor = ConsoleColor.DarkYellow; - Console.WriteLine($"IW4MAdmin-Prerelease {loc["MANAGER_VERSION_UPDATE"]} [v{version.CurrentVersionPrerelease.ToString()}-pr]"); - Console.WriteLine(loc["MANAGER_VERSION_CURRENT"].FormatExt($"[v{Version.ToString()}-pr]")); - Console.ForegroundColor = ConsoleColor.Gray; - } -#endif - else - { - Console.ForegroundColor = ConsoleColor.Green; - Console.WriteLine(loc["MANAGER_VERSION_SUCCESS"]); - Console.ForegroundColor = ConsoleColor.Gray; - } - } /// /// reads input from the console and executes entered commands on the default server @@ -299,9 +240,12 @@ namespace IW4MAdmin.Application { var config = _serviceProvider.GetRequiredService>().Configuration(); return Localization.Configure.Initialize(useLocalTranslation: config?.UseLocalTranslations ?? false, + apiInstance: _serviceProvider.GetRequiredService(), customLocale: config?.EnableCustomLocale ?? false ? (config.CustomLocale ?? "en-US") : "en-US"); }) - .AddSingleton(); + .AddSingleton() + .AddSingleton(_serviceProvider => RestClient.For(Utilities.IsDevelopment ? new Uri("http://127.0.0.1:8080") : _serviceProvider.GetRequiredService().MasterUrl)) + .AddSingleton(); if (args.Contains("serialevents")) { diff --git a/Application/Misc/MasterCommunication.cs b/Application/Misc/MasterCommunication.cs new file mode 100644 index 000000000..60dc6891d --- /dev/null +++ b/Application/Misc/MasterCommunication.cs @@ -0,0 +1,209 @@ +using IW4MAdmin.Application.API.Master; +using RestEase; +using SharedLibraryCore; +using SharedLibraryCore.Configuration; +using SharedLibraryCore.Helpers; +using SharedLibraryCore.Interfaces; +using System; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace IW4MAdmin.Application.Misc +{ + /// + /// implementation of IMasterCommunication + /// talks to the master server + /// + class MasterCommunication : IMasterCommunication + { + private readonly ILogger _logger; + private readonly ITranslationLookup _transLookup; + private readonly IMasterApi _apiInstance; + private readonly IManager _manager; + private readonly ApplicationConfiguration _appConfig; + private readonly BuildNumber _fallbackVersion = BuildNumber.Parse("99.99.99.99"); + private readonly int _apiVersion = 1; + + private bool firstHeartBeat = true; + + public MasterCommunication(ILogger logger, ApplicationConfiguration appConfig, ITranslationLookup translationLookup, IMasterApi apiInstance, IManager manager) + { + _logger = logger; + _transLookup = translationLookup; + _apiInstance = apiInstance; + _appConfig = appConfig; + _manager = manager; + } + + /// + /// checks for latest version of the application + /// notifies user if an update is available + /// + /// + public async Task CheckVersion() + { + var version = new VersionInfo() + { + CurrentVersionStable = _fallbackVersion + }; + + try + { + version = await _apiInstance.GetVersion(_apiVersion); + } + + catch (Exception e) + { + _logger.WriteWarning(_transLookup["MANAGER_VERSION_FAIL"]); + while (e.InnerException != null) + { + e = e.InnerException; + } + + _logger.WriteDebug(e.Message); + } + + if (version.CurrentVersionStable == _fallbackVersion) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine(_transLookup["MANAGER_VERSION_FAIL"]); + Console.ForegroundColor = ConsoleColor.Gray; + } + +#if !PRERELEASE + else if (version.CurrentVersionStable > Program.Version) + { + Console.ForegroundColor = ConsoleColor.DarkYellow; + Console.WriteLine($"IW4MAdmin {_transLookup["MANAGER_VERSION_UPDATE"]} [v{version.CurrentVersionStable.ToString()}]"); + Console.WriteLine(_transLookup["MANAGER_VERSION_CURRENT"].FormatExt($"[v{Program.Version.ToString()}]")); + Console.ForegroundColor = ConsoleColor.Gray; + } +#else + else if (version.CurrentVersionPrerelease > Program.Version) + { + Console.ForegroundColor = ConsoleColor.DarkYellow; + Console.WriteLine($"IW4MAdmin-Prerelease {_transLookup["MANAGER_VERSION_UPDATE"]} [v{version.CurrentVersionPrerelease.ToString()}-pr]"); + Console.WriteLine(_transLookup["MANAGER_VERSION_CURRENT"].FormatExt($"[v{Program.Version.ToString()}-pr]")); + Console.ForegroundColor = ConsoleColor.Gray; + } +#endif + else + { + Console.ForegroundColor = ConsoleColor.Green; + Console.WriteLine(_transLookup["MANAGER_VERSION_SUCCESS"]); + Console.ForegroundColor = ConsoleColor.Gray; + } + } + + public async Task RunUploadStatus(CancellationToken token) + { + // todo: clean up this logic + bool connected; + + while (!token.IsCancellationRequested) + { + try + { + await UploadStatus(); + } + + catch (System.Net.Http.HttpRequestException e) + { + _logger.WriteWarning($"Could not send heartbeat - {e.Message}"); + } + + catch (AggregateException e) + { + _logger.WriteWarning($"Could not send heartbeat - {e.Message}"); + var exceptions = e.InnerExceptions.Where(ex => ex.GetType() == typeof(ApiException)); + + foreach (var ex in exceptions) + { + if (((ApiException)ex).StatusCode == System.Net.HttpStatusCode.Unauthorized) + { + connected = false; + } + } + } + + catch (ApiException e) + { + _logger.WriteWarning($"Could not send heartbeat - {e.Message}"); + if (e.StatusCode == System.Net.HttpStatusCode.Unauthorized) + { + connected = false; + } + } + + catch (Exception e) + { + _logger.WriteWarning($"Could not send heartbeat - {e.Message}"); + } + + + try + { + await Task.Delay(30000, token); + } + + catch + { + break; + } + } + } + + private async Task UploadStatus() + { + if (firstHeartBeat) + { + var token = await _apiInstance.Authenticate(new AuthenticationId + { + Id = _appConfig.Id + }); + + _apiInstance.AuthorizationToken = $"Bearer {token.AccessToken}"; + } + + var instance = new ApiInstance + { + Id = _appConfig.Id, + Uptime = (int)(DateTime.UtcNow - (_manager as ApplicationManager).StartTime).TotalSeconds, + Version = Program.Version, + Servers = _manager.GetServers().Select(s => + new ApiServer() + { + ClientNum = s.ClientNum, + Game = s.GameName.ToString(), + Version = s.Version, + Gametype = s.Gametype, + Hostname = s.Hostname, + Map = s.CurrentMap.Name, + MaxClientNum = s.MaxClients, + Id = s.EndPoint, + Port = (short)s.Port, + IPAddress = s.IP + }).ToList() + }; + + Response response = null; + + if (firstHeartBeat) + { + response = await _apiInstance.AddInstance(instance); + } + + else + { + response = await _apiInstance.UpdateInstance(instance.Id, instance); + firstHeartBeat = false; + } + + if (response.ResponseMessage.StatusCode != System.Net.HttpStatusCode.OK) + { + _logger.WriteWarning($"Response code from master is {response.ResponseMessage.StatusCode}, message is {response.StringContent}"); + } + } + } +} diff --git a/Plugins/ScriptPlugins/ParserT7.js b/Plugins/ScriptPlugins/ParserT7.js index e462576cd..a379f4a86 100644 --- a/Plugins/ScriptPlugins/ParserT7.js +++ b/Plugins/ScriptPlugins/ParserT7.js @@ -14,7 +14,7 @@ var plugin = { rconParser = manager.GenerateDynamicRConParser(this.name); eventParser = manager.GenerateDynamicEventParser(this.name); - rconParser.Configuration.Status.Pattern = '^ *([0-9]+) +-?([0-9]+) +((?:[A-Z]+|[0-9]+)) +((?:[a-z]|[0-9]){8,32}|(?:[a-z]|[0-9]){8,32}|bot[0-9]+|(?:[0-9]+)) *(.{0,32}) +(\\d+\\.\\d+\\.\\d+.\\d+\\:-*\\d{1,5}|0+.0+:-*\\d{1,5}|loopback|unknown)(?:\\([0-9]+\\)) +(-*[0-9]+) *$' + rconParser.Configuration.Status.Pattern = '^ *([0-9]+) +-?([0-9]+) +((?:[A-Z]+|[0-9]+)) +((?:[a-z]|[0-9]){8,32}|(?:[a-z]|[0-9]){8,32}|bot[0-9]+|(?:[0-9]+)) *(.{0,32}) +(\\d+\\.\\d+\\.\\d+.\\d+\\:-*\\d{1,5}|0+.0+:-*\\d{1,5}|loopback|unknown)(?:\\([0-9]+\\)) +(-*[0-9]+) *$'; rconParser.Configuration.StatusHeader.Pattern = 'num +score +ping +xuid +name +address +qport'; rconParser.Configuration.CommandPrefixes.Kick = 'clientkick {0}'; rconParser.Configuration.CommandPrefixes.Ban = 'clientkick {0}'; diff --git a/SharedLibraryCore/Configuration/ApplicationConfiguration.cs b/SharedLibraryCore/Configuration/ApplicationConfiguration.cs index 51d2dc253..30b454193 100644 --- a/SharedLibraryCore/Configuration/ApplicationConfiguration.cs +++ b/SharedLibraryCore/Configuration/ApplicationConfiguration.cs @@ -98,6 +98,8 @@ namespace SharedLibraryCore.Configuration public string WebfrontUrl => string.IsNullOrEmpty(ManualWebfrontUrl) ? WebfrontBindUrl?.Replace("0.0.0.0", "127.0.0.1") : ManualWebfrontUrl; [ConfigurationIgnore] public bool IgnoreServerConnectionLost { get; set; } + [ConfigurationIgnore] + public Uri MasterUrl { get; set; } = new Uri("https://fn-p.master.threadsafe.sh/"); public IBaseConfiguration Generate() { diff --git a/SharedLibraryCore/Configuration/Validation/ApplicationConfigurationValidator.cs b/SharedLibraryCore/Configuration/Validation/ApplicationConfigurationValidator.cs index 24c7de9b3..5238035d0 100644 --- a/SharedLibraryCore/Configuration/Validation/ApplicationConfigurationValidator.cs +++ b/SharedLibraryCore/Configuration/Validation/ApplicationConfigurationValidator.cs @@ -67,6 +67,10 @@ namespace SharedLibraryCore.Configuration.Validation RuleForEach(_app => _app.Servers) .NotEmpty() .SetValidator(new ServerConfigurationValidator()); + + RuleFor(_app => _app.MasterUrl) + .NotNull() + .Must(_url => _url != null && _url.Scheme == Uri.UriSchemeHttp); } } } diff --git a/SharedLibraryCore/Interfaces/IMasterCommunication.cs b/SharedLibraryCore/Interfaces/IMasterCommunication.cs new file mode 100644 index 000000000..bb2782b30 --- /dev/null +++ b/SharedLibraryCore/Interfaces/IMasterCommunication.cs @@ -0,0 +1,24 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace SharedLibraryCore.Interfaces +{ + /// + /// defines the capabilities of the communication to the master server + /// + public interface IMasterCommunication + { + /// + /// checks the current version of IW4MAdmin against the master version + /// + /// + Task CheckVersion(); + + /// + /// Sends heart beats to the master + /// + /// Cancellation token + /// + Task RunUploadStatus(CancellationToken token); + } +} diff --git a/SharedLibraryCore/Services/ClientService.cs b/SharedLibraryCore/Services/ClientService.cs index 808c474f1..094e09bd0 100644 --- a/SharedLibraryCore/Services/ClientService.cs +++ b/SharedLibraryCore/Services/ClientService.cs @@ -541,10 +541,6 @@ namespace SharedLibraryCore.Services LastConnection = client.LastConnection }; -#if DEBUG == true - var clientsSql = iqClients.ToSql(); -#endif - return await iqClients.ToListAsync(); } } @@ -601,9 +597,7 @@ namespace SharedLibraryCore.Services LastConnection = _client.LastConnection, ClientId = _client.ClientId, }); -#if DEBUG == true - var iqClientsSql = iqClients.ToSql(); -#endif + var clients = await iqClientProjection.ToListAsync(); // this is so we don't try to evaluate this in the linq to entities query @@ -635,9 +629,7 @@ namespace SharedLibraryCore.Services { var startOfPeriod = DateTime.UtcNow.AddHours(-24); var iqQuery = context.Clients.Where(_client => _client.LastConnection >= startOfPeriod); -#if DEBUG - string sql = iqQuery.ToSql(); -#endif + return await iqQuery.CountAsync(); } } @@ -664,9 +656,6 @@ namespace SharedLibraryCore.Services LastConnection = _client.FirstConnection }); -#if DEBUG - var sql = iqClients.ToSql(); -#endif return await iqClients.ToListAsync(); } } diff --git a/SharedLibraryCore/Services/PenaltyService.cs b/SharedLibraryCore/Services/PenaltyService.cs index 0939d55cd..1e23fbae4 100644 --- a/SharedLibraryCore/Services/PenaltyService.cs +++ b/SharedLibraryCore/Services/PenaltyService.cs @@ -88,9 +88,6 @@ namespace SharedLibraryCore.Services IsEvade = _penalty.IsEvadedOffense }); -#if DEBUG == true - var querySql = iqPenalties.ToSql(); -#endif return await iqPenalties.ToListAsync(); } } @@ -136,9 +133,6 @@ namespace SharedLibraryCore.Services IsEvade = _penalty.IsEvadedOffense }); -#if DEBUG == true - var querySql = iqPenalties.ToSql(); -#endif return await iqPenalties.Distinct().ToListAsync(); } } @@ -167,11 +161,6 @@ namespace SharedLibraryCore.Services .SelectMany(a => a.Link.ReceivedPenalties) .Where(filter); -#if DEBUG == true - var penaltiesSql = iqLinkPenalties.ToSql(); - var ipPenaltiesSql = iqIPPenalties.ToSql(); -#endif - var activePenalties = (await iqLinkPenalties.ToListAsync()) .Union(await iqIPPenalties.ToListAsync()) .Distinct(); diff --git a/SharedLibraryCore/Utilities.cs b/SharedLibraryCore/Utilities.cs index daaeafffa..534b82bf6 100644 --- a/SharedLibraryCore/Utilities.cs +++ b/SharedLibraryCore/Utilities.cs @@ -964,7 +964,12 @@ namespace SharedLibraryCore } public static bool ShouldHideLevel(this Permission perm) => perm == Permission.Flagged; - + + /// + /// indicates if running in development mode + /// + /// + public static bool IsDevelopment => Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development"; /// @@ -981,12 +986,5 @@ namespace SharedLibraryCore return path; } - -#if DEBUG == true - public static string ToSql(this IQueryable query) where TEntity : class - { - return ""; - } -#endif } } diff --git a/WebfrontCore/Controllers/PenaltyController.cs b/WebfrontCore/Controllers/PenaltyController.cs index a7b32c3f1..041732333 100644 --- a/WebfrontCore/Controllers/PenaltyController.cs +++ b/WebfrontCore/Controllers/PenaltyController.cs @@ -68,9 +68,6 @@ namespace WebfrontCore.Controllers TimePunished = p.When, AutomatedOffense = Authorized ? p.AutomatedOffense : null, }); -#if DEBUG == true - var querySql = iqPenalties.ToSql(); -#endif penalties = await iqPenalties.ToListAsync(); }