From ae4fa23884c9a3d3c7094e9df3f491da9b089763 Mon Sep 17 00:00:00 2001 From: RaidMax Date: Tue, 13 Mar 2018 16:30:22 -0500 Subject: [PATCH] vpn check updates, fixed some issues, "masked" status is now sensitive discord link in webfront if configured --- Plugins/SimpleStats/Helpers/StatManager.cs | 44 +++++++-------- SharedLibrary/Database/Repair.cs | 3 ++ SharedLibrary/Event.cs | 2 +- SharedLibrary/Helpers/Vector3.cs | 7 +++ SharedLibrary/ServerConfiguration.cs | 2 + WebfrontCore/Application/Config/web.cfg | 2 - WebfrontCore/Application/Main.cs | 24 ++++----- WebfrontCore/Application/Manager.cs | 54 +++++++++---------- WebfrontCore/Application/Misc/VPNCheck.cs | 15 ++++-- WebfrontCore/Application/Server.cs | 38 ++++++++----- .../ServerConfigurationGenerator.cs | 14 ++++- WebfrontCore/Controllers/BaseController.cs | 2 + WebfrontCore/Controllers/ClientController.cs | 16 ++++-- WebfrontCore/Controllers/ConsoleController.cs | 3 ++ WebfrontCore/Controllers/HomeController.cs | 8 ++- WebfrontCore/Controllers/PenaltyController.cs | 25 ++++++++- .../PublishProfiles/FolderProfile.pubxml | 2 +- .../Views/Client/Privileged/Index.cshtml | 1 + .../Views/Client/Profile/Index.cshtml | 9 ++-- WebfrontCore/Views/Console/Index.cshtml | 1 + WebfrontCore/Views/Server/_Server.cshtml | 1 + WebfrontCore/Views/Shared/Error.cshtml | 18 +------ WebfrontCore/Views/Shared/_Layout.cshtml | 20 ++++--- WebfrontCore/appsettings.Release.json | 21 ++++++++ WebfrontCore/appsettings.json | 8 +++ WebfrontCore/wwwroot/js/profile.js | 12 +++-- _customcallbacks.gsc | 2 +- 27 files changed, 235 insertions(+), 119 deletions(-) delete mode 100644 WebfrontCore/Application/Config/web.cfg create mode 100644 WebfrontCore/appsettings.Release.json diff --git a/Plugins/SimpleStats/Helpers/StatManager.cs b/Plugins/SimpleStats/Helpers/StatManager.cs index 04bfb62c..b69778b9 100644 --- a/Plugins/SimpleStats/Helpers/StatManager.cs +++ b/Plugins/SimpleStats/Helpers/StatManager.cs @@ -226,7 +226,7 @@ namespace StatsPlugin.Helpers }; if (kill.DeathType == IW4Info.MeansOfDeath.MOD_SUICIDE && - kill.Damage == 10000) + kill.Damage == 100000) { // suicide by switching teams so let's not count it against them return; @@ -247,31 +247,33 @@ namespace StatsPlugin.Helpers //statsSvc.KillStatsSvc.Insert(kill); //await statsSvc.KillStatsSvc.SaveChangesAsync(); - - async Task executePenalty(Cheat.DetectionPenaltyResult penalty) + if (attacker.CurrentServer.Config.EnableAntiCheat) { - switch (penalty.ClientPenalty) + async Task executePenalty(Cheat.DetectionPenaltyResult penalty) { - case Penalty.PenaltyType.Ban: - await attacker.Ban("You appear to be cheating", new Player() { ClientId = 1 }); - break; - case Penalty.PenaltyType.Flag: - if (attacker.Level != Player.Permission.User) + switch (penalty.ClientPenalty) + { + case Penalty.PenaltyType.Ban: + await attacker.Ban("You appear to be cheating", new Player() { ClientId = 1 }); break; - var flagCmd = new CFlag(); - await flagCmd.ExecuteAsync(new Event(Event.GType.Flag, $"{(int)penalty.Bone}-{Math.Round(penalty.RatioAmount, 2).ToString()}@{penalty.KillCount}", new Player() - { - ClientId = 1, - Level = Player.Permission.Console, - ClientNumber = -1, - CurrentServer = attacker.CurrentServer - }, attacker, attacker.CurrentServer)); - break; + case Penalty.PenaltyType.Flag: + if (attacker.Level != Player.Permission.User) + break; + var flagCmd = new CFlag(); + await flagCmd.ExecuteAsync(new Event(Event.GType.Flag, $"{(int)penalty.Bone}-{Math.Round(penalty.RatioAmount, 2).ToString()}@{penalty.KillCount}", new Player() + { + ClientId = 1, + Level = Player.Permission.Console, + ClientNumber = -1, + CurrentServer = attacker.CurrentServer + }, attacker, attacker.CurrentServer)); + break; + } } - } - await executePenalty(playerDetection.ProcessKill(kill)); - await executePenalty(playerDetection.ProcessTotalRatio(playerStats)); + await executePenalty(playerDetection.ProcessKill(kill)); + await executePenalty(playerDetection.ProcessTotalRatio(playerStats)); + } } public async Task AddStandardKill(Player attacker, Player victim) diff --git a/SharedLibrary/Database/Repair.cs b/SharedLibrary/Database/Repair.cs index 3584b4ff..2a15216a 100644 --- a/SharedLibrary/Database/Repair.cs +++ b/SharedLibrary/Database/Repair.cs @@ -8,6 +8,9 @@ namespace SharedLibrary.Database { public static void Run(ILogger log) { + if (!System.IO.File.Exists($"{Utilities.OperatingDirectory}Database.sdf")) + return; + SqlCeEngine engine = new SqlCeEngine(@"Data Source=|DataDirectory|\Database.sdf"); if (false == engine.Verify()) { diff --git a/SharedLibrary/Event.cs b/SharedLibrary/Event.cs index 1d5afe7c..5c75587a 100644 --- a/SharedLibrary/Event.cs +++ b/SharedLibrary/Event.cs @@ -42,7 +42,7 @@ namespace SharedLibrary public Event(GType t, string d, Player O, Player T, Server S) { Type = t; - Data = d.Trim(); + Data = d?.Trim(); Origin = O; Target = T; Owner = S; diff --git a/SharedLibrary/Helpers/Vector3.cs b/SharedLibrary/Helpers/Vector3.cs index 2ba489b3..2f895904 100644 --- a/SharedLibrary/Helpers/Vector3.cs +++ b/SharedLibrary/Helpers/Vector3.cs @@ -40,5 +40,12 @@ namespace SharedLibrary.Helpers { return Math.Round(Math.Sqrt(Math.Pow(b.X - a.X, 2) + Math.Pow(b.Y - a.Y, 2) + Math.Pow(b.Z - a.Z, 2)), 2); } + + public double DotProduct(Vector3 a) => (a.X * this.X) + (a.Y * this.Y) + (a.Z * this.Z); + + public double Magnitude() => Math.Sqrt((X * X) + (Y * Y) + (Z * Z)); + + public double AngleBetween(Vector3 a) => Math.Acos(this.DotProduct(a) / (a.Magnitude() * this.Magnitude())); + } } diff --git a/SharedLibrary/ServerConfiguration.cs b/SharedLibrary/ServerConfiguration.cs index 4f8ee262..f819320a 100644 --- a/SharedLibrary/ServerConfiguration.cs +++ b/SharedLibrary/ServerConfiguration.cs @@ -12,6 +12,8 @@ namespace SharedLibrary public bool AllowTrustedRank; public string RestartUsername; public string RestartPassword; + public bool EnableAntiCheat; + public bool AllowClientVpn; public override string Filename() { diff --git a/WebfrontCore/Application/Config/web.cfg b/WebfrontCore/Application/Config/web.cfg deleted file mode 100644 index 499c2157..00000000 --- a/WebfrontCore/Application/Config/web.cfg +++ /dev/null @@ -1,2 +0,0 @@ -127.0.0.1 -80 \ No newline at end of file diff --git a/WebfrontCore/Application/Main.cs b/WebfrontCore/Application/Main.cs index 447fd7fd..df44b89d 100644 --- a/WebfrontCore/Application/Main.cs +++ b/WebfrontCore/Application/Main.cs @@ -12,8 +12,6 @@ namespace IW4MAdmin { public class Program { - [DllImport("kernel32.dll")] - public static extern bool AllocConsole(); static public double Version { get; private set; } static public ApplicationManager ServerManager = ApplicationManager.GetInstance(); public static string OperatingDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + Path.DirectorySeparatorChar; @@ -33,15 +31,20 @@ namespace IW4MAdmin try { + + /*var v1 = SharedLibrary.Helpers.Vector3.Parse("(737, 1117, 268)"); + var v2 = SharedLibrary.Helpers.Vector3.Parse("(1510, 672.98, -228.66)"); + double angleBetween = v1.AngleBetween(v2);*/ + + CheckDirectories(); - Task.Run(async () => - { - ServerManager = ApplicationManager.GetInstance(); - SharedLibrary.Database.Repair.Run(ServerManager.Logger); - await ServerManager.Init(); - ServerManager.Start(); - }); + + + ServerManager = ApplicationManager.GetInstance(); + SharedLibrary.Database.Repair.Run(ServerManager.Logger); + ServerManager.Init().Wait(); + Task.Run(() => ServerManager.Start()); Task.Run(() => { @@ -95,9 +98,6 @@ namespace IW4MAdmin if (!Directory.Exists($"{curDirectory}Logs")) Directory.CreateDirectory($"{curDirectory}Logs"); - if (!Directory.Exists($"{curDirectory}Database")) - Directory.CreateDirectory($"{curDirectory}Database"); - if (!Directory.Exists($"{curDirectory}Plugins")) Directory.CreateDirectory($"{curDirectory}Plugins"); } diff --git a/WebfrontCore/Application/Manager.cs b/WebfrontCore/Application/Manager.cs index ff9da110..c4cecbb5 100644 --- a/WebfrontCore/Application/Manager.cs +++ b/WebfrontCore/Application/Manager.cs @@ -104,40 +104,38 @@ namespace IW4MAdmin { var Conf = ServerConfiguration.Read(file); - Task.Run(async () => + try { - try + var ServerInstance = new IW4MServer(this, Conf); + await ServerInstance.Initialize(); + + lock (_servers) { - var ServerInstance = new IW4MServer(this, Conf); - await ServerInstance.Initialize(); - - lock (_servers) - { - _servers.Add(ServerInstance); - } - - Logger.WriteVerbose($"Now monitoring {ServerInstance.Hostname}"); - - // this way we can keep track of execution time and see if problems arise. - var Status = new AsyncStatus(ServerInstance, UPDATE_FREQUENCY); - lock (TaskStatuses) - { - TaskStatuses.Add(Status); - } + _servers.Add(ServerInstance); } - catch (ServerException e) + Logger.WriteVerbose($"Now monitoring {ServerInstance.Hostname}"); + + // this way we can keep track of execution time and see if problems arise. + var Status = new AsyncStatus(ServerInstance, UPDATE_FREQUENCY); + lock (TaskStatuses) { - Logger.WriteError($"Not monitoring server {Conf.IP}:{Conf.Port} due to uncorrectable errors"); - if (e.GetType() == typeof(DvarException)) - Logger.WriteDebug($"Could not get the dvar value for {(e as DvarException).Data["dvar_name"]} (ensure the server has a map loaded)"); - else if (e.GetType() == typeof(NetworkException)) - { - Logger.WriteDebug(e.Message); - Logger.WriteDebug($"Internal Exception: {e.Data["internal_exception"]}"); - } + TaskStatuses.Add(Status); } - }); + } + + catch (ServerException e) + { + Logger.WriteError($"Not monitoring server {Conf.IP}:{Conf.Port} due to uncorrectable errors"); + if (e.GetType() == typeof(DvarException)) + Logger.WriteDebug($"Could not get the dvar value for {(e as DvarException).Data["dvar_name"]} (ensure the server has a map loaded)"); + else if (e.GetType() == typeof(NetworkException)) + { + Logger.WriteDebug(e.Message); + Logger.WriteDebug($"Internal Exception: {e.Data["internal_exception"]}"); + } + } + } #endregion diff --git a/WebfrontCore/Application/Misc/VPNCheck.cs b/WebfrontCore/Application/Misc/VPNCheck.cs index b64574e6..8fceb737 100644 --- a/WebfrontCore/Application/Misc/VPNCheck.cs +++ b/WebfrontCore/Application/Misc/VPNCheck.cs @@ -1,4 +1,6 @@ -using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -9,13 +11,18 @@ namespace WebfrontCore.Application.Misc { public static async Task UsingVPN(string ip) { +#if DEBUG + return false; +#endif try { using (var RequestClient = new System.Net.Http.HttpClient()) { - string response = await RequestClient.GetStringAsync($"http://check.getipintel.net/check.php?ip={ip}&contact=raidmax@live.com"); - double probability = Convert.ToDouble(response); - return probability > 0.9; + RequestClient.DefaultRequestHeaders.Add("X-Key", Startup.Configuration["VPN:APIKey"]); + string response = await RequestClient.GetStringAsync($"http://v2.api.iphub.info/ip/{ip}"); + var responseJson = JsonConvert.DeserializeObject(response); + int blockType = Convert.ToInt32(responseJson["block"]); + return blockType == 1; } } diff --git a/WebfrontCore/Application/Server.cs b/WebfrontCore/Application/Server.cs index f83134ea..c31e8276 100644 --- a/WebfrontCore/Application/Server.cs +++ b/WebfrontCore/Application/Server.cs @@ -92,7 +92,7 @@ namespace IW4MAdmin if (existingAlias == null) { Logger.WriteDebug($"Client {polledPlayer} has connected previously under a different ip/name"); - client.CurrentAlias = new SharedLibrary.Database.Models.EFAlias() + client.CurrentAlias = new EFAlias() { IPAddress = polledPlayer.IPAddress, Name = polledPlayer.Name, @@ -143,7 +143,7 @@ namespace IW4MAdmin await ExecuteEvent(new Event(Event.GType.Connect, "", player, null, this)); - if (await VPNCheck.UsingVPN(player.IPAddressString)) + if (Config.AllowClientVpn && await VPNCheck.UsingVPN(player.IPAddressString)) { await player.Kick("VPNs are not allowed on this server", new Player() { ClientId = 1 }); } @@ -288,10 +288,9 @@ namespace IW4MAdmin { E.Target = matchingPlayers.First(); E.Data = Regex.Replace(E.Data, Regex.Escape($"\"{E.Target.Name}\""), "", RegexOptions.IgnoreCase).Trim(); + E.Data = Regex.Replace(E.Data, Regex.Escape($"{E.Target.Name}"), "", RegexOptions.IgnoreCase).Trim(); - if ((E.Data.ToLower().Trim() == E.Target.Name.ToLower().Trim() || - E.Data == String.Empty) && - C.RequiresTarget) + if (E.Data.Length == 0 && C.RequiredArgumentCount > 1) { await E.Origin.Tell($"Not enough arguments supplied!"); await E.Origin.Tell(C.Syntax); @@ -375,7 +374,7 @@ namespace IW4MAdmin #if DEBUG Logger.WriteInfo($"Polling players took {(DateTime.Now - now).TotalMilliseconds}ms"); #endif - + Throttled = false; for (int i = 0; i < Players.Count; i++) { if (CurrentPlayers.Find(p => p.ClientNumber == i) == null && Players[i] != null) @@ -561,7 +560,20 @@ namespace IW4MAdmin DVAR onelog = null; if (GameName == Game.IW4) - onelog = await this.GetDvarAsync("iw4x_onelog"); + { + try + { + onelog = await this.GetDvarAsync("iw4x_onelog"); + } + + catch (Exception) + { + onelog = new DVAR("iw4x_onelog") + { + Value = -1 + }; + } + } try { @@ -580,8 +592,10 @@ namespace IW4MAdmin this.FSGame = game.Value; await this.SetDvarAsync("sv_kickbantime", 60); - await this.SetDvarAsync("sv_network_fps", 1000); - await this.SetDvarAsync("com_maxfps", 1000); + + // I don't think this belongs in an admin tool + /*await this.SetDvarAsync("sv_network_fps", 1000); + await this.SetDvarAsync("com_maxfps", 1000);*/ if (logsync.Value == 0 || logfile.Value == string.Empty) { @@ -603,7 +617,7 @@ namespace IW4MAdmin } #endif - string mainPath = (GameName == Game.IW4) ? "userraw" : "main"; + string mainPath = (GameName == Game.IW4 && onelog.Value >=0) ? "userraw" : "main"; string logPath = (game.Value == "" || onelog?.Value == 1) ? $"{ basepath.Value.Replace("\\", "/")}/{mainPath}/{logfile.Value}" : @@ -626,8 +640,8 @@ namespace IW4MAdmin //#endif Logger.WriteInfo($"Log file is {logPath}"); #if !DEBUG - await Broadcast("IW4M Admin is now ^2ONLINE"); - + await Broadcast("IW4M Admin is now ^2ONLINE"); + #endif } diff --git a/WebfrontCore/Application/ServerConfigurationGenerator.cs b/WebfrontCore/Application/ServerConfigurationGenerator.cs index c888bdc6..06272d35 100644 --- a/WebfrontCore/Application/ServerConfigurationGenerator.cs +++ b/WebfrontCore/Application/ServerConfigurationGenerator.cs @@ -17,6 +17,8 @@ namespace IW4MAdmin string Password; bool AllowMultipleOwners; bool AllowTrustedRank; + bool AntiCheat; + bool AllowVpns; while (IP == String.Empty) { @@ -57,13 +59,23 @@ namespace IW4MAdmin Console.Write("Allow trusted rank? [y/n]: "); AllowTrustedRank = (Console.ReadLine().ToLower().FirstOrDefault() as char?) == 'y'; + Console.Write("Allow server-side anti-cheat [y/n]: "); + AntiCheat = (Console.ReadLine().ToLower().FirstOrDefault() as char?) == 'y'; + + Console.Write("Allow client VPNS [y/n]: "); + AllowVpns = (Console.ReadLine().ToLower().FirstOrDefault() as char?) == 'y'; + var config = new ServerConfiguration() { IP = IP, Password = Password, Port = Port, AllowMultipleOwners = AllowMultipleOwners, - AllowTrustedRank = AllowTrustedRank + AllowTrustedRank = AllowTrustedRank, + RestartPassword = "", + RestartUsername = "", + EnableAntiCheat = AntiCheat, + AllowClientVpn = AllowVpns }; config.Write(); diff --git a/WebfrontCore/Controllers/BaseController.cs b/WebfrontCore/Controllers/BaseController.cs index bc4665cd..f6c835df 100644 --- a/WebfrontCore/Controllers/BaseController.cs +++ b/WebfrontCore/Controllers/BaseController.cs @@ -21,6 +21,8 @@ namespace WebfrontCore.Controllers Authorized = context.HttpContext.Connection.RemoteIpAddress.ToString() == "127.0.0.1" || Manager.AdministratorIPs.Contains(context.HttpContext.Connection.RemoteIpAddress.ToString().ConvertToIP()); ViewBag.Authorized = Authorized; + ViewBag.Url = Startup.Configuration["Web:Address"]; + ViewBag.DiscordLink = Startup.Configuration["Discord:InviteLink"]; base.OnActionExecuting(context); } } diff --git a/WebfrontCore/Controllers/ClientController.cs b/WebfrontCore/Controllers/ClientController.cs index d60689f3..00559eb6 100644 --- a/WebfrontCore/Controllers/ClientController.cs +++ b/WebfrontCore/Controllers/ClientController.cs @@ -50,7 +50,7 @@ namespace WebfrontCore.Controllers { Key = "Masked", Value = client.Masked ? "Is" : "Is not", - Sensitive = false, + Sensitive = true, When = DateTime.MinValue }); @@ -61,7 +61,12 @@ namespace WebfrontCore.Controllers .OrderByDescending(m => m.When) .ToList(); - ViewBag.Title = clientDto.Name; + ViewBag.Title = clientDto.Name.Substring(clientDto.Name.Length - 1).ToLower()[0] == 's' ? + clientDto.Name + "'" : + clientDto.Name + "'s"; + ViewBag.Title += " Profile"; + ViewBag.Description = $"Client information for {clientDto.Name}"; + ViewBag.Keywords = $"IW4MAdmin, client, profile, {clientDto.Name}"; return View("Profile/Index", clientDto); } @@ -84,7 +89,10 @@ namespace WebfrontCore.Controllers }); } - ViewBag.Title = "Current Privileged Users"; + ViewBag.Title = "Privileged Clients"; + ViewBag.Description = "List of all privileged clients on IW4MAdmin"; + ViewBag.Keywords = "IW4MAdmin, privileged, admins, clients, administrators"; + return View("Privileged/Index", adminsDict); } @@ -102,7 +110,7 @@ namespace WebfrontCore.Controllers }) .ToList(); - ViewBag.Name = $"Clients Matching \"{clientName}\""; + ViewBag.Title = $"Clients Matching \"{clientName}\""; return View("Find/Index", clientsDto); } } diff --git a/WebfrontCore/Controllers/ConsoleController.cs b/WebfrontCore/Controllers/ConsoleController.cs index ecad3237..52ab4286 100644 --- a/WebfrontCore/Controllers/ConsoleController.cs +++ b/WebfrontCore/Controllers/ConsoleController.cs @@ -19,7 +19,10 @@ namespace WebfrontCore.Controllers ID = s.GetHashCode(), }); + ViewBag.Description = "Use the IW4MAdmin web console to execute commands"; ViewBag.Title = "Web Console"; + ViewBag.Keywords = "IW4MAdmin, console, execute, commands"; + return View(activeServers); } diff --git a/WebfrontCore/Controllers/HomeController.cs b/WebfrontCore/Controllers/HomeController.cs index a7242bec..601b5fee 100644 --- a/WebfrontCore/Controllers/HomeController.cs +++ b/WebfrontCore/Controllers/HomeController.cs @@ -12,14 +12,18 @@ namespace WebfrontCore.Controllers { public IActionResult Index() { + ViewBag.Description = "IW4MAdmin is a complete server administration tool for IW4x."; ViewBag.Title = "Server Overview"; + ViewBag.Keywords = "IW4MAdmin, server, administration, IW4x, MW2, Modern Warfare 2"; + return View(); } public IActionResult Error() { - // return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); - return null; + ViewBag.Description = "IW4MAdmin encountered and error"; + ViewBag.Title = "Error!"; + return View(); } } } diff --git a/WebfrontCore/Controllers/PenaltyController.cs b/WebfrontCore/Controllers/PenaltyController.cs index b8959aa3..8a72cf3a 100644 --- a/WebfrontCore/Controllers/PenaltyController.cs +++ b/WebfrontCore/Controllers/PenaltyController.cs @@ -1,6 +1,8 @@ using Microsoft.AspNetCore.Mvc; using SharedLibrary; +using SharedLibrary.Database.Models; using SharedLibrary.Dtos; +using SharedLibrary.Services; using System; using System.Collections.Generic; using System.Linq; @@ -13,7 +15,10 @@ namespace WebfrontCore.Controllers { public IActionResult List() { - ViewBag.Title = "Penalty List"; + ViewBag.Description = "List of all the recent penalties (bans, kicks, warnings) on IW4MAdmin"; + ViewBag.Title = "Client Penalties"; + ViewBag.Keywords = "IW4MAdmin, penalties, ban, kick, warns"; + return View(); } @@ -21,5 +26,23 @@ namespace WebfrontCore.Controllers { return View("_List", offset); } + + public async Task PublicAsync() + { + var penalties = await (new GenericRepository()) + .FindAsync(p => p.Type == SharedLibrary.Objects.Penalty.PenaltyType.Ban && p.Active); + + var penaltiesDto = penalties.Select(p => new PenaltyInfo() + { + OffenderId = p.OffenderId, + Offense = p.Offense, + PunisherId = p.PunisherId, + Type = p.Type.ToString(), + TimePunished = p.When.ToString(), + TimeRemaining = p.Expires.ToString() + }).ToList(); + + return Json(penaltiesDto); + } } } diff --git a/WebfrontCore/Properties/PublishProfiles/FolderProfile.pubxml b/WebfrontCore/Properties/PublishProfiles/FolderProfile.pubxml index f4400e5d..282b04b6 100644 --- a/WebfrontCore/Properties/PublishProfiles/FolderProfile.pubxml +++ b/WebfrontCore/Properties/PublishProfiles/FolderProfile.pubxml @@ -13,7 +13,7 @@ by editing this MSBuild file. In order to learn more about this please visit htt True False 65340d7d-5831-406c-acad-b13ba634bde2 - C:\Users\User\Desktop\stuff\IW4M-Admin\IW4M-Admin\WebfrontCore\bin\x86\Release\PublishOutput + C:\Projects\IW4M-Admin\Publish True net452 win7-x86 diff --git a/WebfrontCore/Views/Client/Privileged/Index.cshtml b/WebfrontCore/Views/Client/Privileged/Index.cshtml index 14348652..317cffa3 100644 --- a/WebfrontCore/Views/Client/Privileged/Index.cshtml +++ b/WebfrontCore/Views/Client/Privileged/Index.cshtml @@ -1,4 +1,5 @@ @model Dictionary> +

@ViewBag.Title

diff --git a/WebfrontCore/Views/Client/Profile/Index.cshtml b/WebfrontCore/Views/Client/Profile/Index.cshtml index e64c605e..1cd86a0a 100644 --- a/WebfrontCore/Views/Client/Profile/Index.cshtml +++ b/WebfrontCore/Views/Client/Profile/Index.cshtml @@ -1,9 +1,12 @@ @model SharedLibrary.Dtos.PlayerInfo - +@{ + string match = System.Text.RegularExpressions.Regex.Match(Model.Name.ToUpper(), "[A-Z]").Value; + string shortCode = match == string.Empty ? "?" : match; +}
- @Model.Name[0].ToString().ToUpper() + @shortCode
@@ -29,7 +32,7 @@ { foreach (string ip in Model.IPs) { - @ip + @ip
} } diff --git a/WebfrontCore/Views/Console/Index.cshtml b/WebfrontCore/Views/Console/Index.cshtml index da938837..7c80bb62 100644 --- a/WebfrontCore/Views/Console/Index.cshtml +++ b/WebfrontCore/Views/Console/Index.cshtml @@ -1,4 +1,5 @@ @model IEnumerable +
@Html.DropDownList("Server", Model.Select(s => new SelectListItem() { Text = s.Name, Value = s.ID.ToString() }).ToList(), new { @class = "form-control bg-dark text-light", id="console_server_select" }) diff --git a/WebfrontCore/Views/Server/_Server.cshtml b/WebfrontCore/Views/Server/_Server.cshtml index 9092eee9..ab196771 100644 --- a/WebfrontCore/Views/Server/_Server.cshtml +++ b/WebfrontCore/Views/Server/_Server.cshtml @@ -3,6 +3,7 @@ @{ Layout = null; + ViewBag.Description += Model.Name + ", "; }
diff --git a/WebfrontCore/Views/Shared/Error.cshtml b/WebfrontCore/Views/Shared/Error.cshtml index ec2ea6bd..48524426 100644 --- a/WebfrontCore/Views/Shared/Error.cshtml +++ b/WebfrontCore/Views/Shared/Error.cshtml @@ -1,22 +1,6 @@ -@model ErrorViewModel -@{ +@{ ViewData["Title"] = "Error"; }

Error.

An error occurred while processing your request.

- -@if (Model.ShowRequestId) -{ -

- Request ID: @Model.RequestId -

-} - -

Development Mode

-

- Swapping to Development environment will display more detailed information about the error that occurred. -

-

- Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. -

diff --git a/WebfrontCore/Views/Shared/_Layout.cshtml b/WebfrontCore/Views/Shared/_Layout.cshtml index c37f2715..6c5571e5 100644 --- a/WebfrontCore/Views/Shared/_Layout.cshtml +++ b/WebfrontCore/Views/Shared/_Layout.cshtml @@ -3,7 +3,14 @@ - IW4MAdmin::@ViewBag.Title + @ViewBag.Title | IW4MAdmin + + + + + + + @@ -27,6 +34,10 @@ + @if (ViewBag.DiscordLink != string.Empty) + { + + }
@@ -41,14 +52,11 @@ -
@@ -69,4 +77,4 @@ @RenderSection("scripts", required: false) - + \ No newline at end of file diff --git a/WebfrontCore/appsettings.Release.json b/WebfrontCore/appsettings.Release.json new file mode 100644 index 00000000..138ffa65 --- /dev/null +++ b/WebfrontCore/appsettings.Release.json @@ -0,0 +1,21 @@ +{ + "Logging": { + "IncludeScopes": false, + "LogLevel": { + "Default": "Trace", + "System": "Information", + "Microsoft": "None" + } + }, + "Web": { + "Address": "127.0.0.1:5000" + }, + "VPN": { + "APIKey": "" + }, + "IW4MAdmin": { + }, + "Discord": { + "InviteLink" : "" + } +} diff --git a/WebfrontCore/appsettings.json b/WebfrontCore/appsettings.json index aac58dad..138ffa65 100644 --- a/WebfrontCore/appsettings.json +++ b/WebfrontCore/appsettings.json @@ -9,5 +9,13 @@ }, "Web": { "Address": "127.0.0.1:5000" + }, + "VPN": { + "APIKey": "" + }, + "IW4MAdmin": { + }, + "Discord": { + "InviteLink" : "" } } diff --git a/WebfrontCore/wwwroot/js/profile.js b/WebfrontCore/wwwroot/js/profile.js index a9011de0..7a9e26fe 100644 --- a/WebfrontCore/wwwroot/js/profile.js +++ b/WebfrontCore/wwwroot/js/profile.js @@ -53,10 +53,16 @@ $(document).ready(function () { get ip geolocation info into modal */ $('.ip-locate-link').click(function (e) { - $.getJSON("http://ip-api.com/json/" + $(this).data("ip")) + e.preventDefault(); + const ip = $(this).data("ip"); + $.getJSON("http://ip-api.com/json/" + ip) .done(function (response) { - $('.modal-title').text($(this).data("ip")); - $('.modal-body').text(JSON.stringify(response, null, 4)); + $('.modal-title').text(ip); + $('.modal-body').text(""); + $('.modal-body').append("ASN — " + response["as"] + "
"); + $('.modal-body').append("ISP — " + response["isp"] + "
"); + $('.modal-body').append("Organization — " + response["org"] + "
"); + $('.modal-body').append("Location — " + response["city"] + ", " + response["regionName"] + ", " + response["country"] + "
"); $('#mainModal').modal(); }); diff --git a/_customcallbacks.gsc b/_customcallbacks.gsc index 9eff3d2e..d2d01f9a 100644 --- a/_customcallbacks.gsc +++ b/_customcallbacks.gsc @@ -19,6 +19,6 @@ Callback_PlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vD else if(!isPlayer(attacker) && sMeansOfDeath == "MOD_FALLING") _attacker = victim; - logPrint("ScriptKill;" + _attacker.guid + ";" + victim.guid + ";" + _attacker.origin + ";" + victim.origin + ";" + iDamage + ";" + sWeapon + ";" + sHitLoc + ";" + sMeansOfDeath + ";" + _attacker.angles + ";" + gettime() + "\n"); + logPrint("ScriptKill;" + _attacker.guid + ";" + victim.guid + ";" + _attacker.origin + ";" + victim.origin + ";" + iDamage + ";" + sWeapon + ";" + sHitLoc + ";" + sMeansOfDeath + ";" + _attacker getPlayerAngles() + ";" + vDir + ";" + gettime() + "\n"); self maps\mp\gametypes\_damage::Callback_PlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration ); } \ No newline at end of file