vpn check updates, fixed some issues,
"masked" status is now sensitive discord link in webfront if configured
This commit is contained in:
parent
5c0aa7d14f
commit
e974de8e63
@ -226,7 +226,7 @@ namespace StatsPlugin.Helpers
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (kill.DeathType == IW4Info.MeansOfDeath.MOD_SUICIDE &&
|
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
|
// suicide by switching teams so let's not count it against them
|
||||||
return;
|
return;
|
||||||
@ -247,31 +247,33 @@ namespace StatsPlugin.Helpers
|
|||||||
|
|
||||||
//statsSvc.KillStatsSvc.Insert(kill);
|
//statsSvc.KillStatsSvc.Insert(kill);
|
||||||
//await statsSvc.KillStatsSvc.SaveChangesAsync();
|
//await statsSvc.KillStatsSvc.SaveChangesAsync();
|
||||||
|
if (attacker.CurrentServer.Config.EnableAntiCheat)
|
||||||
async Task executePenalty(Cheat.DetectionPenaltyResult penalty)
|
|
||||||
{
|
{
|
||||||
switch (penalty.ClientPenalty)
|
async Task executePenalty(Cheat.DetectionPenaltyResult penalty)
|
||||||
{
|
{
|
||||||
case Penalty.PenaltyType.Ban:
|
switch (penalty.ClientPenalty)
|
||||||
await attacker.Ban("You appear to be cheating", new Player() { ClientId = 1 });
|
{
|
||||||
break;
|
case Penalty.PenaltyType.Ban:
|
||||||
case Penalty.PenaltyType.Flag:
|
await attacker.Ban("You appear to be cheating", new Player() { ClientId = 1 });
|
||||||
if (attacker.Level != Player.Permission.User)
|
|
||||||
break;
|
break;
|
||||||
var flagCmd = new CFlag();
|
case Penalty.PenaltyType.Flag:
|
||||||
await flagCmd.ExecuteAsync(new Event(Event.GType.Flag, $"{(int)penalty.Bone}-{Math.Round(penalty.RatioAmount, 2).ToString()}@{penalty.KillCount}", new Player()
|
if (attacker.Level != Player.Permission.User)
|
||||||
{
|
break;
|
||||||
ClientId = 1,
|
var flagCmd = new CFlag();
|
||||||
Level = Player.Permission.Console,
|
await flagCmd.ExecuteAsync(new Event(Event.GType.Flag, $"{(int)penalty.Bone}-{Math.Round(penalty.RatioAmount, 2).ToString()}@{penalty.KillCount}", new Player()
|
||||||
ClientNumber = -1,
|
{
|
||||||
CurrentServer = attacker.CurrentServer
|
ClientId = 1,
|
||||||
}, attacker, attacker.CurrentServer));
|
Level = Player.Permission.Console,
|
||||||
break;
|
ClientNumber = -1,
|
||||||
|
CurrentServer = attacker.CurrentServer
|
||||||
|
}, attacker, attacker.CurrentServer));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
await executePenalty(playerDetection.ProcessKill(kill));
|
await executePenalty(playerDetection.ProcessKill(kill));
|
||||||
await executePenalty(playerDetection.ProcessTotalRatio(playerStats));
|
await executePenalty(playerDetection.ProcessTotalRatio(playerStats));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task AddStandardKill(Player attacker, Player victim)
|
public async Task AddStandardKill(Player attacker, Player victim)
|
||||||
|
@ -8,6 +8,9 @@ namespace SharedLibrary.Database
|
|||||||
{
|
{
|
||||||
public static void Run(ILogger log)
|
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");
|
SqlCeEngine engine = new SqlCeEngine(@"Data Source=|DataDirectory|\Database.sdf");
|
||||||
if (false == engine.Verify())
|
if (false == engine.Verify())
|
||||||
{
|
{
|
||||||
|
@ -42,7 +42,7 @@ namespace SharedLibrary
|
|||||||
public Event(GType t, string d, Player O, Player T, Server S)
|
public Event(GType t, string d, Player O, Player T, Server S)
|
||||||
{
|
{
|
||||||
Type = t;
|
Type = t;
|
||||||
Data = d.Trim();
|
Data = d?.Trim();
|
||||||
Origin = O;
|
Origin = O;
|
||||||
Target = T;
|
Target = T;
|
||||||
Owner = S;
|
Owner = S;
|
||||||
|
@ -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);
|
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()));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@ namespace SharedLibrary
|
|||||||
public bool AllowTrustedRank;
|
public bool AllowTrustedRank;
|
||||||
public string RestartUsername;
|
public string RestartUsername;
|
||||||
public string RestartPassword;
|
public string RestartPassword;
|
||||||
|
public bool EnableAntiCheat;
|
||||||
|
public bool AllowClientVpn;
|
||||||
|
|
||||||
public override string Filename()
|
public override string Filename()
|
||||||
{
|
{
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
127.0.0.1
|
|
||||||
80
|
|
@ -12,8 +12,6 @@ namespace IW4MAdmin
|
|||||||
{
|
{
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
[DllImport("kernel32.dll")]
|
|
||||||
public static extern bool AllocConsole();
|
|
||||||
static public double Version { get; private set; }
|
static public double Version { get; private set; }
|
||||||
static public ApplicationManager ServerManager = ApplicationManager.GetInstance();
|
static public ApplicationManager ServerManager = ApplicationManager.GetInstance();
|
||||||
public static string OperatingDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + Path.DirectorySeparatorChar;
|
public static string OperatingDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + Path.DirectorySeparatorChar;
|
||||||
@ -33,15 +31,20 @@ namespace IW4MAdmin
|
|||||||
|
|
||||||
try
|
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();
|
CheckDirectories();
|
||||||
|
|
||||||
Task.Run(async () =>
|
|
||||||
{
|
|
||||||
ServerManager = ApplicationManager.GetInstance();
|
ServerManager = ApplicationManager.GetInstance();
|
||||||
SharedLibrary.Database.Repair.Run(ServerManager.Logger);
|
SharedLibrary.Database.Repair.Run(ServerManager.Logger);
|
||||||
await ServerManager.Init();
|
ServerManager.Init().Wait();
|
||||||
ServerManager.Start();
|
Task.Run(() => ServerManager.Start());
|
||||||
});
|
|
||||||
|
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
@ -95,9 +98,6 @@ namespace IW4MAdmin
|
|||||||
if (!Directory.Exists($"{curDirectory}Logs"))
|
if (!Directory.Exists($"{curDirectory}Logs"))
|
||||||
Directory.CreateDirectory($"{curDirectory}Logs");
|
Directory.CreateDirectory($"{curDirectory}Logs");
|
||||||
|
|
||||||
if (!Directory.Exists($"{curDirectory}Database"))
|
|
||||||
Directory.CreateDirectory($"{curDirectory}Database");
|
|
||||||
|
|
||||||
if (!Directory.Exists($"{curDirectory}Plugins"))
|
if (!Directory.Exists($"{curDirectory}Plugins"))
|
||||||
Directory.CreateDirectory($"{curDirectory}Plugins");
|
Directory.CreateDirectory($"{curDirectory}Plugins");
|
||||||
}
|
}
|
||||||
|
@ -104,40 +104,38 @@ namespace IW4MAdmin
|
|||||||
{
|
{
|
||||||
var Conf = ServerConfiguration.Read(file);
|
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);
|
_servers.Add(ServerInstance);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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");
|
TaskStatuses.Add(Status);
|
||||||
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"]}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
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
|
#endregion
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using System;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -9,13 +11,18 @@ namespace WebfrontCore.Application.Misc
|
|||||||
{
|
{
|
||||||
public static async Task<bool> UsingVPN(string ip)
|
public static async Task<bool> UsingVPN(string ip)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (var RequestClient = new System.Net.Http.HttpClient())
|
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");
|
RequestClient.DefaultRequestHeaders.Add("X-Key", Startup.Configuration["VPN:APIKey"]);
|
||||||
double probability = Convert.ToDouble(response);
|
string response = await RequestClient.GetStringAsync($"http://v2.api.iphub.info/ip/{ip}");
|
||||||
return probability > 0.9;
|
var responseJson = JsonConvert.DeserializeObject<JObject>(response);
|
||||||
|
int blockType = Convert.ToInt32(responseJson["block"]);
|
||||||
|
return blockType == 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ namespace IW4MAdmin
|
|||||||
if (existingAlias == null)
|
if (existingAlias == null)
|
||||||
{
|
{
|
||||||
Logger.WriteDebug($"Client {polledPlayer} has connected previously under a different ip/name");
|
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,
|
IPAddress = polledPlayer.IPAddress,
|
||||||
Name = polledPlayer.Name,
|
Name = polledPlayer.Name,
|
||||||
@ -143,7 +143,7 @@ namespace IW4MAdmin
|
|||||||
await ExecuteEvent(new Event(Event.GType.Connect, "", player, null, this));
|
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 });
|
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.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();
|
||||||
|
E.Data = Regex.Replace(E.Data, Regex.Escape($"{E.Target.Name}"), "", RegexOptions.IgnoreCase).Trim();
|
||||||
|
|
||||||
if ((E.Data.ToLower().Trim() == E.Target.Name.ToLower().Trim() ||
|
if (E.Data.Length == 0 && C.RequiredArgumentCount > 1)
|
||||||
E.Data == String.Empty) &&
|
|
||||||
C.RequiresTarget)
|
|
||||||
{
|
{
|
||||||
await E.Origin.Tell($"Not enough arguments supplied!");
|
await E.Origin.Tell($"Not enough arguments supplied!");
|
||||||
await E.Origin.Tell(C.Syntax);
|
await E.Origin.Tell(C.Syntax);
|
||||||
@ -375,7 +374,7 @@ namespace IW4MAdmin
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
Logger.WriteInfo($"Polling players took {(DateTime.Now - now).TotalMilliseconds}ms");
|
Logger.WriteInfo($"Polling players took {(DateTime.Now - now).TotalMilliseconds}ms");
|
||||||
#endif
|
#endif
|
||||||
|
Throttled = false;
|
||||||
for (int i = 0; i < Players.Count; i++)
|
for (int i = 0; i < Players.Count; i++)
|
||||||
{
|
{
|
||||||
if (CurrentPlayers.Find(p => p.ClientNumber == i) == null && Players[i] != null)
|
if (CurrentPlayers.Find(p => p.ClientNumber == i) == null && Players[i] != null)
|
||||||
@ -561,7 +560,20 @@ namespace IW4MAdmin
|
|||||||
|
|
||||||
DVAR<int> onelog = null;
|
DVAR<int> onelog = null;
|
||||||
if (GameName == Game.IW4)
|
if (GameName == Game.IW4)
|
||||||
onelog = await this.GetDvarAsync<int>("iw4x_onelog");
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
onelog = await this.GetDvarAsync<int>("iw4x_onelog");
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
onelog = new DVAR<int>("iw4x_onelog")
|
||||||
|
{
|
||||||
|
Value = -1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -580,8 +592,10 @@ namespace IW4MAdmin
|
|||||||
this.FSGame = game.Value;
|
this.FSGame = game.Value;
|
||||||
|
|
||||||
await this.SetDvarAsync("sv_kickbantime", 60);
|
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)
|
if (logsync.Value == 0 || logfile.Value == string.Empty)
|
||||||
{
|
{
|
||||||
@ -603,7 +617,7 @@ namespace IW4MAdmin
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#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) ?
|
string logPath = (game.Value == "" || onelog?.Value == 1) ?
|
||||||
$"{ basepath.Value.Replace("\\", "/")}/{mainPath}/{logfile.Value}" :
|
$"{ basepath.Value.Replace("\\", "/")}/{mainPath}/{logfile.Value}" :
|
||||||
@ -626,8 +640,8 @@ namespace IW4MAdmin
|
|||||||
//#endif
|
//#endif
|
||||||
Logger.WriteInfo($"Log file is {logPath}");
|
Logger.WriteInfo($"Log file is {logPath}");
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
await Broadcast("IW4M Admin is now ^2ONLINE");
|
await Broadcast("IW4M Admin is now ^2ONLINE");
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@ namespace IW4MAdmin
|
|||||||
string Password;
|
string Password;
|
||||||
bool AllowMultipleOwners;
|
bool AllowMultipleOwners;
|
||||||
bool AllowTrustedRank;
|
bool AllowTrustedRank;
|
||||||
|
bool AntiCheat;
|
||||||
|
bool AllowVpns;
|
||||||
|
|
||||||
while (IP == String.Empty)
|
while (IP == String.Empty)
|
||||||
{
|
{
|
||||||
@ -57,13 +59,23 @@ namespace IW4MAdmin
|
|||||||
Console.Write("Allow trusted rank? [y/n]: ");
|
Console.Write("Allow trusted rank? [y/n]: ");
|
||||||
AllowTrustedRank = (Console.ReadLine().ToLower().FirstOrDefault() as char?) == 'y';
|
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()
|
var config = new ServerConfiguration()
|
||||||
{
|
{
|
||||||
IP = IP,
|
IP = IP,
|
||||||
Password = Password,
|
Password = Password,
|
||||||
Port = Port,
|
Port = Port,
|
||||||
AllowMultipleOwners = AllowMultipleOwners,
|
AllowMultipleOwners = AllowMultipleOwners,
|
||||||
AllowTrustedRank = AllowTrustedRank
|
AllowTrustedRank = AllowTrustedRank,
|
||||||
|
RestartPassword = "",
|
||||||
|
RestartUsername = "",
|
||||||
|
EnableAntiCheat = AntiCheat,
|
||||||
|
AllowClientVpn = AllowVpns
|
||||||
};
|
};
|
||||||
|
|
||||||
config.Write();
|
config.Write();
|
||||||
|
@ -21,6 +21,8 @@ namespace WebfrontCore.Controllers
|
|||||||
Authorized = context.HttpContext.Connection.RemoteIpAddress.ToString() == "127.0.0.1" ||
|
Authorized = context.HttpContext.Connection.RemoteIpAddress.ToString() == "127.0.0.1" ||
|
||||||
Manager.AdministratorIPs.Contains(context.HttpContext.Connection.RemoteIpAddress.ToString().ConvertToIP());
|
Manager.AdministratorIPs.Contains(context.HttpContext.Connection.RemoteIpAddress.ToString().ConvertToIP());
|
||||||
ViewBag.Authorized = Authorized;
|
ViewBag.Authorized = Authorized;
|
||||||
|
ViewBag.Url = Startup.Configuration["Web:Address"];
|
||||||
|
ViewBag.DiscordLink = Startup.Configuration["Discord:InviteLink"];
|
||||||
base.OnActionExecuting(context);
|
base.OnActionExecuting(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ namespace WebfrontCore.Controllers
|
|||||||
{
|
{
|
||||||
Key = "Masked",
|
Key = "Masked",
|
||||||
Value = client.Masked ? "Is" : "Is not",
|
Value = client.Masked ? "Is" : "Is not",
|
||||||
Sensitive = false,
|
Sensitive = true,
|
||||||
When = DateTime.MinValue
|
When = DateTime.MinValue
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -61,7 +61,12 @@ namespace WebfrontCore.Controllers
|
|||||||
.OrderByDescending(m => m.When)
|
.OrderByDescending(m => m.When)
|
||||||
.ToList();
|
.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);
|
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);
|
return View("Privileged/Index", adminsDict);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +110,7 @@ namespace WebfrontCore.Controllers
|
|||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
ViewBag.Name = $"Clients Matching \"{clientName}\"";
|
ViewBag.Title = $"Clients Matching \"{clientName}\"";
|
||||||
return View("Find/Index", clientsDto);
|
return View("Find/Index", clientsDto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,10 @@ namespace WebfrontCore.Controllers
|
|||||||
ID = s.GetHashCode(),
|
ID = s.GetHashCode(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ViewBag.Description = "Use the IW4MAdmin web console to execute commands";
|
||||||
ViewBag.Title = "Web Console";
|
ViewBag.Title = "Web Console";
|
||||||
|
ViewBag.Keywords = "IW4MAdmin, console, execute, commands";
|
||||||
|
|
||||||
return View(activeServers);
|
return View(activeServers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,14 +12,18 @@ namespace WebfrontCore.Controllers
|
|||||||
{
|
{
|
||||||
public IActionResult Index()
|
public IActionResult Index()
|
||||||
{
|
{
|
||||||
|
ViewBag.Description = "IW4MAdmin is a complete server administration tool for IW4x.";
|
||||||
ViewBag.Title = "Server Overview";
|
ViewBag.Title = "Server Overview";
|
||||||
|
ViewBag.Keywords = "IW4MAdmin, server, administration, IW4x, MW2, Modern Warfare 2";
|
||||||
|
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IActionResult Error()
|
public IActionResult Error()
|
||||||
{
|
{
|
||||||
// return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
ViewBag.Description = "IW4MAdmin encountered and error";
|
||||||
return null;
|
ViewBag.Title = "Error!";
|
||||||
|
return View();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using SharedLibrary;
|
using SharedLibrary;
|
||||||
|
using SharedLibrary.Database.Models;
|
||||||
using SharedLibrary.Dtos;
|
using SharedLibrary.Dtos;
|
||||||
|
using SharedLibrary.Services;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -13,7 +15,10 @@ namespace WebfrontCore.Controllers
|
|||||||
{
|
{
|
||||||
public IActionResult List()
|
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();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,5 +26,23 @@ namespace WebfrontCore.Controllers
|
|||||||
{
|
{
|
||||||
return View("_List", offset);
|
return View("_List", offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> PublicAsync()
|
||||||
|
{
|
||||||
|
var penalties = await (new GenericRepository<EFPenalty>())
|
||||||
|
.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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ by editing this MSBuild file. In order to learn more about this please visit htt
|
|||||||
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
|
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
|
||||||
<ExcludeApp_Data>False</ExcludeApp_Data>
|
<ExcludeApp_Data>False</ExcludeApp_Data>
|
||||||
<ProjectGuid>65340d7d-5831-406c-acad-b13ba634bde2</ProjectGuid>
|
<ProjectGuid>65340d7d-5831-406c-acad-b13ba634bde2</ProjectGuid>
|
||||||
<publishUrl>C:\Users\User\Desktop\stuff\IW4M-Admin\IW4M-Admin\WebfrontCore\bin\x86\Release\PublishOutput</publishUrl>
|
<publishUrl>C:\Projects\IW4M-Admin\Publish</publishUrl>
|
||||||
<DeleteExistingFiles>True</DeleteExistingFiles>
|
<DeleteExistingFiles>True</DeleteExistingFiles>
|
||||||
<TargetFramework>net452</TargetFramework>
|
<TargetFramework>net452</TargetFramework>
|
||||||
<RuntimeIdentifier>win7-x86</RuntimeIdentifier>
|
<RuntimeIdentifier>win7-x86</RuntimeIdentifier>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
@model Dictionary<SharedLibrary.Objects.Player.Permission, IList<SharedLibrary.Dtos.ClientInfo>>
|
@model Dictionary<SharedLibrary.Objects.Player.Permission, IList<SharedLibrary.Dtos.ClientInfo>>
|
||||||
|
|
||||||
<h4 class="pb-2 text-center ">@ViewBag.Title</h4>
|
<h4 class="pb-2 text-center ">@ViewBag.Title</h4>
|
||||||
|
|
||||||
<div class="row border-bottom">
|
<div class="row border-bottom">
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
@model SharedLibrary.Dtos.PlayerInfo
|
@model SharedLibrary.Dtos.PlayerInfo
|
||||||
|
@{
|
||||||
|
string match = System.Text.RegularExpressions.Regex.Match(Model.Name.ToUpper(), "[A-Z]").Value;
|
||||||
|
string shortCode = match == string.Empty ? "?" : match;
|
||||||
|
}
|
||||||
<div id="profile_wrapper" class="row d-flex d-sm-inline-flex justify-content-center justify-content-left pb-3">
|
<div id="profile_wrapper" class="row d-flex d-sm-inline-flex justify-content-center justify-content-left pb-3">
|
||||||
<div class="mr-auto ml-auto ml-sm-0 mr-sm-0">
|
<div class="mr-auto ml-auto ml-sm-0 mr-sm-0">
|
||||||
<div id="profile_avatar" class="mb-4 mb-md-0 text-center level-bgcolor-@Model.Level.ToLower()">
|
<div id="profile_avatar" class="mb-4 mb-md-0 text-center level-bgcolor-@Model.Level.ToLower()">
|
||||||
<span class="profile-shortcode">@Model.Name[0].ToString().ToUpper()</span>
|
<span class="profile-shortcode">@shortCode</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="profile_info" class="text-center text-sm-left pr-3 pl-3">
|
<div id="profile_info" class="text-center text-sm-left pr-3 pl-3">
|
||||||
@ -29,7 +32,7 @@
|
|||||||
{
|
{
|
||||||
foreach (string ip in Model.IPs)
|
foreach (string ip in Model.IPs)
|
||||||
{
|
{
|
||||||
<a class="ip-locate-link" href="#" data-ip="@ip">@ip</a>
|
<a class="ip-locate-link" href="#" data-ip="@ip">@ip</a><br/>
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
@model IEnumerable<SharedLibrary.Dtos.ServerInfo>
|
@model IEnumerable<SharedLibrary.Dtos.ServerInfo>
|
||||||
|
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
<div id="console" class="col-md-8">
|
<div id="console" class="col-md-8">
|
||||||
@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" })
|
@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" })
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
@{
|
@{
|
||||||
Layout = null;
|
Layout = null;
|
||||||
|
ViewBag.Description += Model.Name + ", ";
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="row server-header">
|
<div class="row server-header">
|
||||||
|
@ -1,22 +1,6 @@
|
|||||||
@model ErrorViewModel
|
@{
|
||||||
@{
|
|
||||||
ViewData["Title"] = "Error";
|
ViewData["Title"] = "Error";
|
||||||
}
|
}
|
||||||
|
|
||||||
<h1 class="text-danger">Error.</h1>
|
<h1 class="text-danger">Error.</h1>
|
||||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||||
|
|
||||||
@if (Model.ShowRequestId)
|
|
||||||
{
|
|
||||||
<p>
|
|
||||||
<strong>Request ID:</strong> <code>@Model.RequestId</code>
|
|
||||||
</p>
|
|
||||||
}
|
|
||||||
|
|
||||||
<h3>Development Mode</h3>
|
|
||||||
<p>
|
|
||||||
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<strong>Development environment should not be enabled in deployed applications</strong>, 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 <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>, and restarting the application.
|
|
||||||
</p>
|
|
||||||
|
@ -3,7 +3,14 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<title>IW4MAdmin::@ViewBag.Title</title>
|
<title>@ViewBag.Title | IW4MAdmin</title>
|
||||||
|
<meta property="og:title" content="@ViewBag.Title | IW4MAdmin">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:image" content="/favicon.ico">
|
||||||
|
<meta property="og:description" content="@ViewBag.Description">
|
||||||
|
<meta property="og:url" content="@ViewBag.Url">
|
||||||
|
<meta name="description" content="@ViewBag.Description">
|
||||||
|
<meta name="keywords" content="@ViewBag.Keywords">
|
||||||
<link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
|
<link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
|
||||||
<environment names="Development">
|
<environment names="Development">
|
||||||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
|
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
|
||||||
@ -27,6 +34,10 @@
|
|||||||
<li class="nav-item text-center text-md-left">@Html.ActionLink("Penalties", "List", "Penalty", new { area = "" }, new { @class = "nav-link" })</li>
|
<li class="nav-item text-center text-md-left">@Html.ActionLink("Penalties", "List", "Penalty", new { area = "" }, new { @class = "nav-link" })</li>
|
||||||
<li class="nav-item text-center text-md-left">@Html.ActionLink("Admins", "PrivilegedAsync", "Client", new { area = "" }, new { @class = "nav-link" })</li>
|
<li class="nav-item text-center text-md-left">@Html.ActionLink("Admins", "PrivilegedAsync", "Client", new { area = "" }, new { @class = "nav-link" })</li>
|
||||||
<li class="nav-item text-center text-md-left">@Html.ActionLink("Console", "Index", "Console", new { area = "" }, new { @class = "nav-link" })</li>
|
<li class="nav-item text-center text-md-left">@Html.ActionLink("Console", "Index", "Console", new { area = "" }, new { @class = "nav-link" })</li>
|
||||||
|
@if (ViewBag.DiscordLink != string.Empty)
|
||||||
|
{
|
||||||
|
<li class="nav-item text-center text-md-left"><a href="@ViewBag.DiscordLink" target="_blank"></a></li>
|
||||||
|
}
|
||||||
</ul>
|
</ul>
|
||||||
<form class="form-inline text-primary pt-3 pb-3" method="get" action="/Client/FindAsync">
|
<form class="form-inline text-primary pt-3 pb-3" method="get" action="/Client/FindAsync">
|
||||||
<input id="client_search" name="clientName" class="form-control mr-auto ml-auto mr-md-2" type="text" placeholder="Find Player" />
|
<input id="client_search" name="clientName" class="form-control mr-auto ml-auto mr-md-2" type="text" placeholder="Find Player" />
|
||||||
@ -41,14 +52,11 @@
|
|||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title" id="mainModalLabel"></h5>
|
<h5 class="modal-title" id="mainModalLabel"></h5>
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
<span aria-hidden="true">×</span>
|
<span aria-hidden="true" class="text-danger">×</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -69,4 +77,4 @@
|
|||||||
</environment>
|
</environment>
|
||||||
@RenderSection("scripts", required: false)
|
@RenderSection("scripts", required: false)
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
21
WebfrontCore/appsettings.Release.json
Normal file
21
WebfrontCore/appsettings.Release.json
Normal file
@ -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" : ""
|
||||||
|
}
|
||||||
|
}
|
@ -9,5 +9,13 @@
|
|||||||
},
|
},
|
||||||
"Web": {
|
"Web": {
|
||||||
"Address": "127.0.0.1:5000"
|
"Address": "127.0.0.1:5000"
|
||||||
|
},
|
||||||
|
"VPN": {
|
||||||
|
"APIKey": ""
|
||||||
|
},
|
||||||
|
"IW4MAdmin": {
|
||||||
|
},
|
||||||
|
"Discord": {
|
||||||
|
"InviteLink" : ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,10 +53,16 @@ $(document).ready(function () {
|
|||||||
get ip geolocation info into modal
|
get ip geolocation info into modal
|
||||||
*/
|
*/
|
||||||
$('.ip-locate-link').click(function (e) {
|
$('.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) {
|
.done(function (response) {
|
||||||
$('.modal-title').text($(this).data("ip"));
|
$('.modal-title').text(ip);
|
||||||
$('.modal-body').text(JSON.stringify(response, null, 4));
|
$('.modal-body').text("");
|
||||||
|
$('.modal-body').append("ASN — " + response["as"] + "<br/>");
|
||||||
|
$('.modal-body').append("ISP — " + response["isp"] + "<br/>");
|
||||||
|
$('.modal-body').append("Organization — " + response["org"] + "<br/>");
|
||||||
|
$('.modal-body').append("Location — " + response["city"] + ", " + response["regionName"] + ", " + response["country"] + "<br/>");
|
||||||
$('#mainModal').modal();
|
$('#mainModal').modal();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -19,6 +19,6 @@ Callback_PlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vD
|
|||||||
else if(!isPlayer(attacker) && sMeansOfDeath == "MOD_FALLING")
|
else if(!isPlayer(attacker) && sMeansOfDeath == "MOD_FALLING")
|
||||||
_attacker = victim;
|
_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 );
|
self maps\mp\gametypes\_damage::Callback_PlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration );
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user