diff --git a/Application/EventParsers/BaseEventParser.cs b/Application/EventParsers/BaseEventParser.cs index 13eb466c6..84bfce046 100644 --- a/Application/EventParsers/BaseEventParser.cs +++ b/Application/EventParsers/BaseEventParser.cs @@ -104,7 +104,6 @@ namespace IW4MAdmin.Application.EventParsers Type = GameEvent.EventType.Command, Data = message, Origin = new EFClient() { NetworkId = originId }, - Target = Utilities.IW4MAdminClient(), Message = message }; } @@ -114,7 +113,6 @@ namespace IW4MAdmin.Application.EventParsers Type = GameEvent.EventType.Say, Data = message, Origin = new EFClient() { NetworkId = originId }, - Target = Utilities.IW4MAdminClient(), Message = message }; } @@ -166,8 +164,6 @@ namespace IW4MAdmin.Application.EventParsers if (regexMatch.Success) { - bool isBot = regexMatch.Groups[Configuration.Join.GroupMapping[ParserRegex.GroupType.OriginNetworkId]].ToString().Contains("bot"); - return new GameEvent() { Type = GameEvent.EventType.PreConnect, @@ -181,9 +177,7 @@ namespace IW4MAdmin.Application.EventParsers NetworkId = regexMatch.Groups[Configuration.Join.GroupMapping[ParserRegex.GroupType.OriginNetworkId]].ToString().ConvertGuidToLong(), ClientNumber = Convert.ToInt32(regexMatch.Groups[Configuration.Join.GroupMapping[ParserRegex.GroupType.OriginClientNumber]].ToString()), State = EFClient.ClientState.Connecting, - IsBot = isBot - }, - Target = Utilities.IW4MAdminClient() + } }; } } @@ -206,8 +200,7 @@ namespace IW4MAdmin.Application.EventParsers NetworkId = regexMatch.Groups[Configuration.Quit.GroupMapping[ParserRegex.GroupType.OriginNetworkId]].ToString().ConvertGuidToLong(), ClientNumber = Convert.ToInt32(regexMatch.Groups[Configuration.Quit.GroupMapping[ParserRegex.GroupType.OriginClientNumber]].ToString()), State = EFClient.ClientState.Disconnecting - }, - Target = Utilities.IW4MAdminClient() + } }; } } @@ -244,8 +237,7 @@ namespace IW4MAdmin.Application.EventParsers { Type = GameEvent.EventType.JoinTeam, Data = logLine, - Origin = new EFClient() { NetworkId = lineSplit[1].ConvertGuidToLong() }, - Target = Utilities.IW4MAdminClient() + Origin = new EFClient() { NetworkId = lineSplit[1].ConvertGuidToLong() } }; } diff --git a/Application/IO/GameLogReader.cs b/Application/IO/GameLogReader.cs index 807c756cf..9f9a7226d 100644 --- a/Application/IO/GameLogReader.cs +++ b/Application/IO/GameLogReader.cs @@ -57,13 +57,13 @@ namespace IW4MAdmin.Application.IO try { var gameEvent = Parser.GenerateGameEvent(eventLine); - // we don't want to add the even if ignoreBots is on and the event comes froma bot - if (!ignoreBots.Value || (ignoreBots.Value && (gameEvent.Origin.NetworkId != -1 || gameEvent.Target.NetworkId != -1))) + // we don't want to add the event if ignoreBots is on and the event comes from a bot + if (!ignoreBots.Value || (ignoreBots.Value && !((gameEvent.Origin?.IsBot ?? false) || (gameEvent.Target?.IsBot ?? false)))) { gameEvent.Owner = server; - // we need to pull the "live" versions of the client (only if the client id isn't IW4MAdmin - gameEvent.Origin = gameEvent.Origin.ClientId == 1 ? gameEvent.Origin : server.GetClientsAsList().First(_client => _client.NetworkId == gameEvent.Origin.NetworkId); - gameEvent.Target = gameEvent.Target.ClientId == 1 ? gameEvent.Target : server.GetClientsAsList().First(_client => _client.NetworkId == gameEvent.Target.NetworkId); + // we need to pull the "live" versions of the client (only if the client id isn't IW4MAdmin) + gameEvent.Origin = gameEvent.Origin == null || gameEvent.Origin.NetworkId == 1 ? gameEvent.Origin : server.GetClientsAsList().First(_client => _client.NetworkId == gameEvent.Origin.NetworkId); + gameEvent.Target = gameEvent.Target == null || gameEvent.Target.NetworkId == 1 ? gameEvent.Target : server.GetClientsAsList().First(_client => _client.NetworkId == gameEvent.Target.NetworkId); events.Add(gameEvent); } @@ -74,6 +74,7 @@ namespace IW4MAdmin.Application.IO if (!ignoreBots.Value) { server.Logger.WriteWarning("Could not find client in client list when parsing event line"); + server.Logger.WriteDebug(eventLine); } } diff --git a/Application/IO/GameLogReaderHttp.cs b/Application/IO/GameLogReaderHttp.cs index 47e112aa0..db8ddfc0b 100644 --- a/Application/IO/GameLogReaderHttp.cs +++ b/Application/IO/GameLogReaderHttp.cs @@ -61,13 +61,13 @@ namespace IW4MAdmin.Application.IO try { var gameEvent = Parser.GenerateGameEvent(eventLine); - // we don't want to add the even if ignoreBots is on and the event comes froma bot - if (!ignoreBots.Value || (ignoreBots.Value && (gameEvent.Origin.NetworkId != -1 || gameEvent.Target.NetworkId != -1))) + // we don't want to add the event if ignoreBots is on and the event comes from a bot + if (!ignoreBots.Value || (ignoreBots.Value && !((gameEvent.Origin?.IsBot ?? false) || (gameEvent.Target?.IsBot ?? false)))) { gameEvent.Owner = server; - // we need to pull the "live" versions of the client (only if the client id isn't IW4MAdmin - gameEvent.Origin = gameEvent.Origin.ClientId == 1 ? gameEvent.Origin : server.GetClientsAsList().First(_client => _client.NetworkId == gameEvent.Origin.NetworkId); - gameEvent.Target = gameEvent.Target.ClientId == 1 ? gameEvent.Target : server.GetClientsAsList().First(_client => _client.NetworkId == gameEvent.Target.NetworkId); + // we need to pull the "live" versions of the client (only if the client id isn't IW4MAdmin) + gameEvent.Origin = gameEvent.Origin == null || gameEvent.Origin.NetworkId == 1 ? gameEvent.Origin : server.GetClientsAsList().First(_client => _client.NetworkId == gameEvent.Origin.NetworkId); + gameEvent.Target = gameEvent.Target == null || gameEvent.Target.NetworkId == 1 ? gameEvent.Target : server.GetClientsAsList().First(_client => _client.NetworkId == gameEvent.Target.NetworkId); events.Add(gameEvent); } @@ -81,6 +81,7 @@ namespace IW4MAdmin.Application.IO if (!ignoreBots.Value) { server.Logger.WriteWarning("Could not find client in client list when parsing event line"); + server.Logger.WriteDebug(eventLine); } } diff --git a/Application/IW4MServer.cs b/Application/IW4MServer.cs index 903df21bf..4dfccf0aa 100644 --- a/Application/IW4MServer.cs +++ b/Application/IW4MServer.cs @@ -38,55 +38,45 @@ namespace IW4MAdmin { Logger.WriteDebug($"Client slot #{clientFromLog.ClientNumber} now reserved"); - try + EFClient client = await Manager.GetClientService().GetUnique(clientFromLog.NetworkId); + + // first time client is connecting to server + if (client == null) { - EFClient client = await Manager.GetClientService().GetUnique(clientFromLog.NetworkId); + Logger.WriteDebug($"Client {clientFromLog} first time connecting"); + clientFromLog.CurrentServer = this; + client = await Manager.GetClientService().Create(clientFromLog); + } - // first time client is connecting to server - if (client == null) - { - Logger.WriteDebug($"Client {clientFromLog} first time connecting"); - clientFromLog.CurrentServer = this; - client = await Manager.GetClientService().Create(clientFromLog); - } + /// this is only a temporary version until the IPAddress is transmitted + client.CurrentAlias = new EFAlias() + { + Name = clientFromLog.Name, + IPAddress = clientFromLog.IPAddress + }; - /// this is only a temporary version until the IPAddress is transmitted - client.CurrentAlias = new EFAlias() - { - Name = clientFromLog.Name, - IPAddress = clientFromLog.IPAddress - }; + Logger.WriteInfo($"Client {client} connected..."); - Logger.WriteInfo($"Client {client} connected..."); + // Do the player specific stuff + client.ClientNumber = clientFromLog.ClientNumber; + client.Score = clientFromLog.Score; + client.Ping = clientFromLog.Ping; + client.CurrentServer = this; - // Do the player specific stuff - client.ClientNumber = clientFromLog.ClientNumber; - client.IsBot = clientFromLog.IsBot; - client.Score = clientFromLog.Score; - client.Ping = clientFromLog.Ping; - client.CurrentServer = this; - - Clients[client.ClientNumber] = client; + Clients[client.ClientNumber] = client; #if DEBUG == true - Logger.WriteDebug($"End PreConnect for {client}"); + Logger.WriteDebug($"End PreConnect for {client}"); #endif - var e = new GameEvent() - { - Origin = client, - Owner = this, - Type = GameEvent.EventType.Connect - }; - - Manager.GetEventHandler().AddEvent(e); - await client.OnJoin(client.IPAddress); - client.State = ClientState.Connected; - } - - catch (Exception ex) + var e = new GameEvent() { - Logger.WriteError($"{loc["SERVER_ERROR_ADDPLAYER"]} {clientFromLog}"); - Logger.WriteError(ex.GetExceptionInfo()); - } + Origin = client, + Owner = this, + Type = GameEvent.EventType.Connect + }; + + Manager.GetEventHandler().AddEvent(e); + await client.OnJoin(client.IPAddress); + client.State = ClientState.Connected; } override public async Task OnClientDisconnected(EFClient client) @@ -229,7 +219,19 @@ namespace IW4MAdmin #endif // we can go ahead and put them in so that they don't get re added Clients[E.Origin.ClientNumber] = E.Origin; - await OnClientConnected(E.Origin); + try + { + await OnClientConnected(E.Origin); + } + + catch (Exception ex) + { + Logger.WriteError($"{loc["SERVER_ERROR_ADDPLAYER"]} {E.Origin}"); + Logger.WriteDebug(ex.GetExceptionInfo()); + + Clients[E.Origin.ClientNumber] = null; + return false; + } ChatHistory.Add(new ChatInfo() { @@ -825,7 +827,7 @@ namespace IW4MAdmin // this DVAR isn't set until the a map is loaded await this.SetDvarAsync("logfile", 2); await this.SetDvarAsync("g_logsync", 2); // set to 2 for continous in other games, clamps to 1 for IW4 - //await this.SetDvarAsync("g_log", "games_mp.log"); + //await this.SetDvarAsync("g_log", "games_mp.log"); Logger.WriteWarning("Game log file not properly initialized, restarting map..."); await this.ExecuteCommandAsync("map_restart"); logfile = await this.GetDvarAsync("g_log"); diff --git a/Application/Main.cs b/Application/Main.cs index db26b61d3..1fa987613 100644 --- a/Application/Main.cs +++ b/Application/Main.cs @@ -2,6 +2,7 @@ using SharedLibraryCore; using System; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace IW4MAdmin.Application @@ -112,14 +113,19 @@ namespace IW4MAdmin.Application WebfrontCore.Program.Init(ServerManager, ServerManager.CancellationToken) : Task.CompletedTask; + // 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 + var inputThread = new Thread(async () => await ReadConsoleInput()); + inputThread.Start(); + var tasks = new[] { ServerManager.Start(), webfrontTask, - ReadConsoleInput(), }; await Task.WhenAll(tasks); + inputThread.Abort(); ServerManager.Logger.WriteVerbose(Utilities.CurrentLocalization.LocalizationIndex["MANAGER_SHUTDOWN_SUCCESS"]); } diff --git a/Application/RconParsers/BaseRConParser.cs b/Application/RconParsers/BaseRConParser.cs index 32535eddb..de8076f7b 100644 --- a/Application/RconParsers/BaseRConParser.cs +++ b/Application/RconParsers/BaseRConParser.cs @@ -155,7 +155,6 @@ namespace IW4MAdmin.Application.RconParsers IPAddress = ip, Ping = ping, Score = score, - IsBot = ip == null, State = EFClient.ClientState.Connecting }; diff --git a/Plugins/Stats/Helpers/StatManager.cs b/Plugins/Stats/Helpers/StatManager.cs index ace642c39..95f8f3500 100644 --- a/Plugins/Stats/Helpers/StatManager.cs +++ b/Plugins/Stats/Helpers/StatManager.cs @@ -499,7 +499,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers AttackerId = attacker.ClientId, VictimId = victim.ClientId, ServerId = serverId, - Map = ParseEnum.Get(map, typeof(IW4Info.MapName)), + //Map = ParseEnum.Get(map, typeof(IW4Info.MapName)), DeathOrigin = vDeathOrigin, KillOrigin = vKillOrigin, DeathType = ParseEnum.Get(type, typeof(IW4Info.MeansOfDeath)), @@ -577,7 +577,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers clientDetection.QueuedHits = clientDetection.QueuedHits.OrderBy(_hits => _hits.TimeOffset).ToList(); var oldestHit = clientDetection.QueuedHits.First(); clientDetection.QueuedHits.RemoveAt(0); - await ApplyPenalty(clientDetection.ProcessHit(oldestHit, isDamage), attacker, ctx); + await ApplyPenalty(clientDetection.ProcessHit(oldestHit, isDamage), attacker, ctx); } await ApplyPenalty(clientDetection.ProcessTotalRatio(clientStats), attacker, ctx); @@ -1231,43 +1231,24 @@ namespace IW4MAdmin.Plugins.Stats.Helpers public static async Task GetIdForServer(Server server) { - // hack: my laziness - if ($"{server.IP}:{server.GetPort().ToString()}" == "66.150.121.184:28965") - { - return 886229536; - } + long id = HashCode.Combine(server.IP, server.GetPort()); + id = id < 0 ? Math.Abs(id) : id; + long? serverId; - else if ($"{server.IP}:{server.GetPort().ToString()}" == "66.150.121.184:28960") + // todo: cache this eventually, as it shouldn't change + using (var ctx = new DatabaseContext(disableTracking: true)) { - return 1645744423; - } - - else if ($"{server.IP}:{server.GetPort().ToString()}" == "66.150.121.184:28970") - { - return 1645809959; - } - - else - { - long id = HashCode.Combine(server.IP, server.GetPort()); - id = id < 0 ? Math.Abs(id) : id; - long? serverId; - - // todo: cache this eventually, as it shouldn't change - using (var ctx = new DatabaseContext(disableTracking: true)) - { - serverId = (await ctx.Set().FirstOrDefaultAsync(_server => _server.ServerId == server.EndPoint || + serverId = (await ctx.Set().FirstOrDefaultAsync(_server => _server.ServerId == server.EndPoint || _server.EndPoint == server.ToString() || _server.ServerId == id))?.ServerId; - } - - if (!serverId.HasValue) - { - return id; - } - - return serverId.Value; } + + if (!serverId.HasValue) + { + return id; + } + + return serverId.Value; } } } diff --git a/Plugins/Stats/Plugin.cs b/Plugins/Stats/Plugin.cs index f4b1fefe6..6fee44e59 100644 --- a/Plugins/Stats/Plugin.cs +++ b/Plugins/Stats/Plugin.cs @@ -471,7 +471,7 @@ namespace IW4MAdmin.Plugins.Stats /// private bool ShouldIgnoreEvent(EFClient origin, EFClient target) { - return ((origin.ClientId <= 1 && target.ClientId <= 1) || ((target.IsBot || origin.IsBot) && ServerManager.GetApplicationSettings().Configuration().IgnoreBots)); + return (origin.ClientId <= 1 && target.ClientId <= 1); } } } diff --git a/SharedLibraryCore/Objects/EFClient.cs b/SharedLibraryCore/Objects/EFClient.cs index 562657302..af339b1c1 100644 --- a/SharedLibraryCore/Objects/EFClient.cs +++ b/SharedLibraryCore/Objects/EFClient.cs @@ -712,7 +712,7 @@ namespace SharedLibraryCore.Database.Models [NotMapped] public int Score { get; set; } [NotMapped] - public bool IsBot { get; set; } + public bool IsBot => NetworkId == -1; [NotMapped] public ClientState State { get; set; } diff --git a/WebfrontCore/Controllers/BaseController.cs b/WebfrontCore/Controllers/BaseController.cs index a25700f6f..79bb4fc49 100644 --- a/WebfrontCore/Controllers/BaseController.cs +++ b/WebfrontCore/Controllers/BaseController.cs @@ -105,6 +105,7 @@ namespace WebfrontCore.Controllers ViewBag.SocialLink = SocialLink ?? ""; ViewBag.SocialTitle = SocialTitle; ViewBag.Pages = Pages; + ViewBag.Localization = Utilities.CurrentLocalization.LocalizationIndex; base.OnActionExecuting(context); } diff --git a/WebfrontCore/Controllers/ConsoleController.cs b/WebfrontCore/Controllers/ConsoleController.cs index ca8b5c85a..3cbac828d 100644 --- a/WebfrontCore/Controllers/ConsoleController.cs +++ b/WebfrontCore/Controllers/ConsoleController.cs @@ -52,26 +52,42 @@ namespace WebfrontCore.Controllers Manager.GetEventHandler().AddEvent(remoteEvent); List response; - // wait for the event to process - if (!(await remoteEvent.WaitAsync(Utilities.DefaultCommandTimeout, server.Manager.CancellationToken)).Failed) - { - response = server.CommandResult.Where(c => c.ClientId == client.ClientId).ToList(); - // remove the added command response - for (int i = 0; i < response.Count; i++) + try + { + // wait for the event to process + if (!(await remoteEvent.WaitAsync(Utilities.DefaultCommandTimeout, server.Manager.CancellationToken)).Failed) { - server.CommandResult.Remove(response[i]); + response = server.CommandResult.Where(c => c.ClientId == client.ClientId).ToList(); + + // remove the added command response + for (int i = 0; i < response.Count; i++) + { + server.CommandResult.Remove(response[i]); + } + } + + else + { + response = new List() + { + new CommandResponseInfo() + { + ClientId = client.ClientId, + Response = Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_COMMAND_TIMEOUT"] + } + }; } } - else + catch (System.OperationCanceledException) { response = new List() { new CommandResponseInfo() { ClientId = client.ClientId, - Response = Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_COMMAND_TIMEOUT"] + Response = Utilities.CurrentLocalization.LocalizationIndex["COMMADS_RESTART_SUCCESS"] } }; } diff --git a/WebfrontCore/Views/Shared/_Layout.cshtml b/WebfrontCore/Views/Shared/_Layout.cshtml index 6860fa0e6..7655fbafc 100644 --- a/WebfrontCore/Views/Shared/_Layout.cshtml +++ b/WebfrontCore/Views/Shared/_Layout.cshtml @@ -156,6 +156,13 @@ + @RenderSection("scripts", required: false) \ No newline at end of file diff --git a/WebfrontCore/wwwroot/js/console.js b/WebfrontCore/wwwroot/js/console.js index 56f2ad42c..f5b84803d 100644 --- a/WebfrontCore/wwwroot/js/console.js +++ b/WebfrontCore/wwwroot/js/console.js @@ -7,7 +7,7 @@ } if (command[0] !== '!') { - $('#console_command_response').text('All commands must start with !').addClass('text-danger'); + $('#console_command_response').text(_localization['WEBFRONT_CONSOLE_COMMAND']).addClass('text-danger'); return false; } showLoader(); @@ -20,7 +20,7 @@ .fail(function (jqxhr, textStatus, error) { errorLoader(); hideLoader(); - $('#console_command_response').text('Could not execute command: ' + error).addClass('text-danger'); + $('#console_command_response').text(_localization['WEBFRONT_CONSOLE_ERROR'] + error).addClass('text-danger'); }); } diff --git a/WebfrontCore/wwwroot/js/penalty.js b/WebfrontCore/wwwroot/js/penalty.js index 2af7c6f95..f9662c518 100644 --- a/WebfrontCore/wwwroot/js/penalty.js +++ b/WebfrontCore/wwwroot/js/penalty.js @@ -29,10 +29,10 @@ if ($('#penalty_table').length === 1) { $('#penalty_filter_selection').change(function() { location = location.href.split('?')[0] + "?showOnly=" + $('#penalty_filter_selection').val(); }); + /* https://stackoverflow.com/questions/19731730/jquery-js-detect-users-scroll-attempt-without-any-window-overflow-to-scroll */ - $('html').bind('mousewheel DOMMouseScroll', function (e) { var delta = (e.originalEvent.wheelDelta || -e.originalEvent.detail); @@ -44,7 +44,6 @@ if ($('#penalty_table').length === 1) { /* https://stackoverflow.com/questions/3898130/check-if-a-user-has-scrolled-to-the-bottom */ - var _throttleTimer = null; var _throttleDelay = 100; var $window = $(window); diff --git a/WebfrontCore/wwwroot/js/profile.js b/WebfrontCore/wwwroot/js/profile.js index 74de5c6fc..f81f218e3 100644 --- a/WebfrontCore/wwwroot/js/profile.js +++ b/WebfrontCore/wwwroot/js/profile.js @@ -60,33 +60,33 @@ $.getJSON('https://extreme-ip-lookup.com/json/' + ip) .done(function (response) { $('#mainModal .modal-title').text(ip); - $('#mainModal .modal-body').text(""); + $('#mainModal .modal-body').text(''); if (response.ipName.length > 0) { - $('#mainModal .modal-body').append("Hostname — " + response.ipName + '
'); + $('#mainModal .modal-body').append(`${_localization['WEBFRONT_PROFILE_LOOKUP_HOSTNAME']} — ${response.ipName}
`); } if (response.isp.length > 0) { - $('#mainModal .modal-body').append("ISP — " + response.isp + '
'); + $('#mainModal .modal-body').append(`${_localization['WEBFRONT_PROFILE_LOOKUP_ISP']} — ${response.isp}
`); } if (response.org.length > 0) { - $('#mainModal .modal-body').append("Organization — " + response.org + '
'); + $('#mainModal .modal-body').append(`${_localization['WEBFRONT_PROFILE_LOOKUP_ORG']} — ${response.org}
`); } if (response['businessName'].length > 0) { - $('#mainModal .modal-body').append("Business — " + response.businessName + '
'); + $('#mainModal .modal-body').append(`${_localization['WEBFRONT_PROFILE_LOOKUP_BUSINESS']} — ${response.businessName}
`); } if (response['businessWebsite'].length > 0) { - $('#mainModal .modal-body').append("Website — " + response.businessWebsite + '
'); + $('#mainModal .modal-body').append(`${_localization['WEBFRONT_PROFILE_LOOKUP_WEBSITE']} — ${response.businessWebsite}
`); } if (response.city.length > 0 || response.region.length > 0 || response.country.length > 0) { - $('#mainModal .modal-body').append("Location — "); + $('#mainModal .modal-body').append(`${_localization['WEBFRONT_PROFILE_LOOKUP_LOCATION']} — `); } if (response.city.length > 0) { $('#mainModal .modal-body').append(response.city); } if (response.region.length > 0) { - $('#mainModal .modal-body').append(', ' + response.region); + $('#mainModal .modal-body').append((response.city.length > 0 ? ', ' : '') + response.region); } if (response.country.length > 0) { - $('#mainModal .modal-body').append(', ' + response.country); + $('#mainModal .modal-body').append((response.country.length > 0 ? ', ' : '') + response.country); } $('#mainModal').modal(); diff --git a/WebfrontCore/wwwroot/js/server.js b/WebfrontCore/wwwroot/js/server.js index c9c23458c..da19c018f 100644 --- a/WebfrontCore/wwwroot/js/server.js +++ b/WebfrontCore/wwwroot/js/server.js @@ -84,7 +84,7 @@ function refreshClientActivity() { $('#server_clientactivity_' + serverId).html(response); }) .fail(function (jqxhr, textStatus, error) { - $('#server_clientactivity_' + serverId).html(" Could not load client activity - " + error); + $('#server_clientactivity_' + serverId).html(''); }); }); } diff --git a/WebfrontCore/wwwroot/js/stats.js b/WebfrontCore/wwwroot/js/stats.js index 1728fadd9..6338176a6 100644 --- a/WebfrontCore/wwwroot/js/stats.js +++ b/WebfrontCore/wwwroot/js/stats.js @@ -31,7 +31,7 @@ } }, title: { - text: "Performance History", + text: _localization['WEBFRONT_STATS_PERFORMANCE_HISTORY'], fontSize: 14 }, axisX: { @@ -39,14 +39,14 @@ lineThickness: 0, tickThickness: 0, margin: 0, - valueFormatString: " ", + valueFormatString: ' ', }, axisY: { labelFontSize: 12, interval: interval, gridThickness: 0, lineThickness: 0.5, - valueFormatString: "#,##0", + valueFormatString: '#,##0', minimum: min, maximum: max }, @@ -54,7 +54,7 @@ dockInsidePlotArea: true }, data: [{ - type: "splineArea", + type: 'splineArea', color: 'rgba(0, 122, 204, 0.25)', markerSize: 3.5, dataPoints: fixedData