auth cookie expires after 30 days

only check hit offset when distance > 3 meters
fix null reference on unauthorized user
fixed stats not showing on profile if anticheat disabled
server client history turns red server is unresponsive
This commit is contained in:
RaidMax 2018-04-04 23:38:45 -05:00
parent c0865b82a0
commit 6d8d021b16
29 changed files with 455 additions and 352 deletions

View File

@ -60,7 +60,7 @@ namespace StatsPlugin.Cheat
var calculatedVector = Vector3.Subtract(kill.KillOrigin, new Vector3((float)x, (float)y, (float)z)); var calculatedVector = Vector3.Subtract(kill.KillOrigin, new Vector3((float)x, (float)y, (float)z));
double angle = trueVector.AngleBetween(calculatedVector); double angle = trueVector.AngleBetween(calculatedVector);
if (kill.AdsPercent > 0.5) if (kill.AdsPercent > 0.5 && kill.Distance > 3)
{ {
var hitLoc = ClientStats.HitLocations var hitLoc = ClientStats.HitLocations
.First(hl => hl.Location == kill.HitLoc); .First(hl => hl.Location == kill.HitLoc);

View File

@ -380,7 +380,7 @@ namespace StatsPlugin.Helpers
double timeSinceLastActive = (DateTime.UtcNow - clientStats.LastActive).TotalSeconds / 60.0; double timeSinceLastActive = (DateTime.UtcNow - clientStats.LastActive).TotalSeconds / 60.0;
// prevent NaN or inactive time lowering SPM // prevent NaN or inactive time lowering SPM
if (timeSinceLastCalc == 0 || timeSinceLastActive > 3) if (timeSinceLastCalc == 0 || timeSinceLastActive > 3 || clientStats.SPM < 1)
return clientStats; return clientStats;
// calculate the players Score Per Minute for the current session // calculate the players Score Per Minute for the current session
@ -403,6 +403,9 @@ namespace StatsPlugin.Helpers
// calculate the new weight against average times the weight against play time // calculate the new weight against average times the weight against play time
clientStats.SPM = (killSPM * SPMAgainstPlayWeight) + (clientStats.SPM * (1 - SPMAgainstPlayWeight)); clientStats.SPM = (killSPM * SPMAgainstPlayWeight) + (clientStats.SPM * (1 - SPMAgainstPlayWeight));
// fixme: how does this happen?
if (clientStats.SPM == double.NaN)
clientStats.SPM = 0;
clientStats.SPM = Math.Round(clientStats.SPM, 3); clientStats.SPM = Math.Round(clientStats.SPM, 3);
clientStats.Skill = Math.Round((clientStats.SPM * KDRWeight), 3); clientStats.Skill = Math.Round((clientStats.SPM * KDRWeight), 3);

View File

@ -105,6 +105,41 @@ namespace StatsPlugin
double skill = Math.Round(clientStats.Sum(c => c.Skill) / clientStats.Count, 2); double skill = Math.Round(clientStats.Sum(c => c.Skill) / clientStats.Count, 2);
double spm = Math.Round(clientStats.Sum(c => c.SPM), 1); double spm = Math.Round(clientStats.Sum(c => c.SPM), 1);
return new List<ProfileMeta>()
{
new ProfileMeta()
{
Key = "Kills",
Value = kills
},
new ProfileMeta()
{
Key = "Deaths",
Value = deaths
},
new ProfileMeta()
{
Key = "KDR",
Value = kdr
},
new ProfileMeta()
{
Key = "Skill",
Value = skill
},
new ProfileMeta()
{
Key = "Score Per Minute",
Value = spm
}
};
}
async Task<List<ProfileMeta>> getAnticheatInfo(int clientId)
{
var statsSvc = new GenericRepository<EFClientStatistics>();
var clientStats = await statsSvc.FindAsync(c => c.ClientId == clientId);
double headRatio = 0; double headRatio = 0;
double chestRatio = 0; double chestRatio = 0;
double abdomenRatio = 0; double abdomenRatio = 0;
@ -134,31 +169,6 @@ namespace StatsPlugin
return new List<ProfileMeta>() return new List<ProfileMeta>()
{ {
new ProfileMeta()
{
Key = "Kills",
Value = kills
},
new ProfileMeta()
{
Key = "Deaths",
Value = deaths
},
new ProfileMeta()
{
Key = "KDR",
Value = kdr
},
new ProfileMeta()
{
Key = "Skill",
Value = skill
},
new ProfileMeta()
{
Key = "Score Per Minute",
Value = spm
},
new ProfileMeta() new ProfileMeta()
{ {
Key = "Chest Ratio", Key = "Chest Ratio",
@ -211,10 +221,13 @@ namespace StatsPlugin
return messageMeta; return messageMeta;
} }
MetaService.AddMeta(getStats);
if (Config.Configuration().EnableAntiCheat) if (Config.Configuration().EnableAntiCheat)
{ {
MetaService.AddMeta(getStats); MetaService.AddMeta(getAnticheatInfo);
} }
MetaService.AddMeta(getMessages); MetaService.AddMeta(getMessages);
// todo: is this fast? make async? // todo: is this fast? make async?
@ -240,10 +253,7 @@ namespace StatsPlugin
Manager = new StatManager(manager); Manager = new StatManager(manager);
} }
public async Task OnTickAsync(Server S) public Task OnTickAsync(Server S) => Utilities.CompletedTask;
{
}
public async Task OnUnloadAsync() public async Task OnUnloadAsync()
{ {

View File

@ -75,13 +75,9 @@ namespace Welcome_Plugin
} }
} }
public async Task OnUnloadAsync() public Task OnUnloadAsync() => Utilities.CompletedTask;
{
}
public async Task OnTickAsync(Server S) public Task OnTickAsync(Server S) => Utilities.CompletedTask;
{
}
public async Task OnEventAsync(Event E, Server S) public async Task OnEventAsync(Event E, Server S)
{ {

View File

@ -457,6 +457,16 @@ namespace SharedLibrary.Commands
await E.Owner.Manager.GetClientService().Update(E.Target); await E.Owner.Manager.GetClientService().Update(E.Target);
} }
try
{
E.Owner.Manager.GetPrivilegedClients().Add(E.Target.ClientId, E.Target);
}
catch (Exception)
{
E.Owner.Manager.GetPrivilegedClients()[E.Target.ClientId] = E.Target;
}
await E.Origin.Tell($"{E.Target.Name} was successfully promoted"); await E.Origin.Tell($"{E.Target.Name} was successfully promoted");
} }
@ -989,12 +999,22 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E) public override async Task ExecuteAsync(Event E)
{ {
if (E.Data.Length < 5)
{
await E.Origin.Tell("Your password must be atleast 5 characters long");
return;
}
string[] hashedPassword = Helpers.Hashing.Hash(E.Data); string[] hashedPassword = Helpers.Hashing.Hash(E.Data);
E.Origin.Password = hashedPassword[0]; E.Origin.Password = hashedPassword[0];
E.Origin.PasswordSalt = hashedPassword[1]; E.Origin.PasswordSalt = hashedPassword[1];
// update the password for the client in privileged
E.Owner.Manager.GetPrivilegedClients()[E.Origin.ClientId] = E.Origin;
await E.Owner.Manager.GetClientService().Update(E.Origin); await E.Owner.Manager.GetClientService().Update(E.Origin);
await E.Origin.Tell("Your password has been set successfully");
} }
} }

View File

@ -56,7 +56,18 @@ namespace SharedLibrary.Database
#if !DEBUG #if !DEBUG
foreach (string dllPath in System.IO.Directory.GetFiles($"{Utilities.OperatingDirectory}Plugins")) foreach (string dllPath in System.IO.Directory.GetFiles($"{Utilities.OperatingDirectory}Plugins"))
#else #else
foreach (string dllPath in System.IO.Directory.GetFiles(/*C:\Projects\IW4M - Admin\WebfrontCore */ $@"{Environment.CurrentDirectory}\bin\x86\Debug\Plugins").Where(f => f.Contains(".dll"))) IEnumerable<string> directoryFiles;
try
{
directoryFiles = Directory.GetFiles($@"{Environment.CurrentDirectory}\bin\x86\Debug\Plugins").Where(f => f.Contains(".dll"));
}
catch(Exception)
{
directoryFiles = Directory.GetFiles($@"{Environment.CurrentDirectory}\Plugins").Where(f => f.Contains(".dll"));
}
foreach (string dllPath in directoryFiles)
#endif #endif
{ {
Assembly library; Assembly library;

View File

@ -2,9 +2,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SharedLibrary.Database.Models namespace SharedLibrary.Database.Models
{ {

View File

@ -18,5 +18,6 @@ namespace SharedLibrary.Dtos
public List<PlayerInfo> Players { get; set; } public List<PlayerInfo> Players { get; set; }
public Helpers.PlayerHistory[] PlayerHistory { get; set; } public Helpers.PlayerHistory[] PlayerHistory { get; set; }
public int ID { get; set; } public int ID { get; set; }
public bool Online { get; set; }
} }
} }

View File

@ -22,5 +22,6 @@ namespace SharedLibrary.Interfaces
ClientService GetClientService(); ClientService GetClientService();
AliasService GetAliasService(); AliasService GetAliasService();
PenaltyService GetPenaltyService(); PenaltyService GetPenaltyService();
IDictionary<int, Player> GetPrivilegedClients();
} }
} }

View File

@ -19,6 +19,6 @@ namespace SharedLibrary.RCon
} }
public static char SeperatorChar = (char)int.Parse("0a", System.Globalization.NumberStyles.AllowHexSpecifier); public static char SeperatorChar = (char)int.Parse("0a", System.Globalization.NumberStyles.AllowHexSpecifier);
public static readonly TimeSpan SocketTimeout = new TimeSpan(0, 0, 1); public static readonly TimeSpan SocketTimeout = new TimeSpan(0, 0, 10);
} }
} }

View File

@ -142,6 +142,7 @@ namespace SharedLibrary
await this.ExecuteCommandAsync($"{sayCommand} {(CustomSayEnabled ? CustomSayName : "")} {Message}"); await this.ExecuteCommandAsync($"{sayCommand} {(CustomSayEnabled ? CustomSayName : "")} {Message}");
#else #else
Logger.WriteVerbose(Message.StripColors()); Logger.WriteVerbose(Message.StripColors());
await Utilities.CompletedTask;
#endif #endif
} }
@ -159,6 +160,7 @@ namespace SharedLibrary
await this.ExecuteCommandAsync($"{tellCommand} {Target.ClientNumber} {(CustomSayEnabled ? CustomSayName : "")} {Message}^7"); await this.ExecuteCommandAsync($"{tellCommand} {Target.ClientNumber} {(CustomSayEnabled ? CustomSayName : "")} {Message}^7");
#else #else
Logger.WriteVerbose($"{Target.ClientNumber}->{Message.StripColors()}"); Logger.WriteVerbose($"{Target.ClientNumber}->{Message.StripColors()}");
await Utilities.CompletedTask;
#endif #endif
if (Target.Level == Player.Permission.Console) if (Target.Level == Player.Permission.Console)

View File

@ -16,8 +16,8 @@ namespace SharedLibrary.Services
{ {
public async Task<EFAlias> Create(EFAlias entity) public async Task<EFAlias> Create(EFAlias entity)
{ {
throw new Exception(); throw await Task.FromResult(new Exception());
using (var context = new DatabaseContext()) /*using (var context = new DatabaseContext())
{ {
var alias = new EFAlias() var alias = new EFAlias()
{ {
@ -32,7 +32,7 @@ namespace SharedLibrary.Services
context.Aliases.Add(entity); context.Aliases.Add(entity);
await context.SaveChangesAsync(); await context.SaveChangesAsync();
return entity; return entity;
} }*/
} }
public Task<EFAlias> CreateProxy() public Task<EFAlias> CreateProxy()
@ -80,14 +80,14 @@ namespace SharedLibrary.Services
public async Task<EFAlias> Update(EFAlias entity) public async Task<EFAlias> Update(EFAlias entity)
{ {
throw new Exception(); throw await Task.FromResult(new Exception());
using (var context = new DatabaseContext()) /*using (var context = new DatabaseContext())
{ {
entity = context.Aliases.Attach(entity); entity = context.Aliases.Attach(entity);
context.Entry(entity).State = EntityState.Modified; context.Entry(entity).State = EntityState.Modified;
await context.SaveChangesAsync(); await context.SaveChangesAsync();
return entity; return entity;
} }*/
} }
public async Task<EFAliasLink> CreateLink(EFAliasLink link) public async Task<EFAliasLink> CreateLink(EFAliasLink link)

View File

@ -59,6 +59,8 @@ namespace SharedLibrary.Services
public async Task<IList<EFPenalty>> Find(Func<EFPenalty, bool> expression) public async Task<IList<EFPenalty>> Find(Func<EFPenalty, bool> expression)
{ {
throw await Task.FromResult(new Exception());
/*
return await Task.FromResult(new List<EFPenalty>()); return await Task.FromResult(new List<EFPenalty>());
// fixme: this is so slow! // fixme: this is so slow!
return await Task.Run(() => return await Task.Run(() =>
@ -70,7 +72,7 @@ namespace SharedLibrary.Services
.Where(expression) .Where(expression)
.Where(p => p.Active) .Where(p => p.Active)
.ToList(); .ToList();
}); });*/
} }
public Task<EFPenalty> Get(int entityID) public Task<EFPenalty> Get(int entityID)

View File

@ -20,6 +20,7 @@ namespace SharedLibrary
public static class Utilities public static class Utilities
{ {
public static string OperatingDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + Path.DirectorySeparatorChar; public static string OperatingDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + Path.DirectorySeparatorChar;
public static readonly Task CompletedTask = Task.FromResult(false);
//Get string with specified number of spaces -- really only for visual output //Get string with specified number of spaces -- really only for visual output
public static String GetSpaces(int Num) public static String GetSpaces(int Num)
@ -52,7 +53,7 @@ namespace SharedLibrary
return newStr; return newStr;
} }
public static List<Player> PlayersFromStatus(String[] Status) public static List<Player> PlayersFromStatus(string[] Status)
{ {
List<Player> StatusPlayers = new List<Player>(); List<Player> StatusPlayers = new List<Player>();

View File

@ -40,7 +40,7 @@ namespace IW4MAdmin
if (type == LogType.Error || type == LogType.Verbose) if (type == LogType.Error || type == LogType.Verbose)
Console.WriteLine(LogLine); Console.WriteLine(LogLine);
//if (type != LogType.Debug) //if (type != LogType.Debug)
File.AppendAllText(FileName, LogLine + Environment.NewLine); File.AppendAllText(FileName, $"{LogLine}{Environment.NewLine}");
#endif #endif
} }
} }

View File

@ -57,8 +57,15 @@ namespace IW4MAdmin
PrivilegedClients = new Dictionary<int, Player>(); PrivilegedClients = new Dictionary<int, Player>();
ServerEventOccurred += EventAPI.OnServerEventOccurred; ServerEventOccurred += EventAPI.OnServerEventOccurred;
ConfigHandler = new BaseConfigurationHandler<ApplicationConfiguration>("IW4MAdminSettings"); ConfigHandler = new BaseConfigurationHandler<ApplicationConfiguration>("IW4MAdminSettings");
Console.CancelKeyPress += new ConsoleCancelEventHandler(OnCancelKey);
} }
private void OnCancelKey(object sender, ConsoleCancelEventArgs args)
{
Stop();
}
public IList<Server> GetServers() public IList<Server> GetServers()
{ {
return Servers; return Servers;
@ -305,5 +312,7 @@ namespace IW4MAdmin
public PenaltyService GetPenaltyService() => PenaltySvc; public PenaltyService GetPenaltyService() => PenaltySvc;
public IConfigurationHandler<ApplicationConfiguration> GetApplicationSettings() => ConfigHandler; public IConfigurationHandler<ApplicationConfiguration> GetApplicationSettings() => ConfigHandler;
public IDictionary<int, Player> GetPrivilegedClients() => PrivilegedClients;
} }
} }

View File

@ -788,7 +788,7 @@ namespace IW4MAdmin
CurrentMap = Maps.Find(m => m.Name == mapname) ?? new Map() { Alias = mapname, Name = mapname }; CurrentMap = Maps.Find(m => m.Name == mapname) ?? new Map() { Alias = mapname, Name = mapname };
// todo: make this more efficient // todo: make this more efficient
((ApplicationManager)(Manager)).PrivilegedClients = new Dictionary<int, Player>(); /*((ApplicationManager)(Manager)).PrivilegedClients = new Dictionary<int, Player>();
var ClientSvc = new ClientService(); var ClientSvc = new ClientService();
var ipList = (await ClientSvc.Find(c => c.Level > Player.Permission.Trusted)) var ipList = (await ClientSvc.Find(c => c.Level > Player.Permission.Trusted))
.Select(c => new .Select(c => new
@ -818,7 +818,7 @@ namespace IW4MAdmin
{ {
continue; continue;
} }
} }*/
} }
if (E.Type == Event.GType.MapEnd) if (E.Type == Event.GType.MapEnd)

View File

@ -2,6 +2,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using System.Security.Claims; using System.Security.Claims;
using System;
namespace WebfrontCore.Controllers namespace WebfrontCore.Controllers
{ {
@ -15,6 +16,8 @@ namespace WebfrontCore.Controllers
return Unauthorized(); return Unauthorized();
} }
try
{
var client = IW4MAdmin.Program.ServerManager.PrivilegedClients[userId]; var client = IW4MAdmin.Program.ServerManager.PrivilegedClients[userId];
string[] hashedPassword = await Task.FromResult(SharedLibrary.Helpers.Hashing.Hash(password, client.PasswordSalt)); string[] hashedPassword = await Task.FromResult(SharedLibrary.Helpers.Hashing.Hash(password, client.PasswordSalt));
@ -29,10 +32,22 @@ namespace WebfrontCore.Controllers
var claimsIdentity = new ClaimsIdentity(claims, "login"); var claimsIdentity = new ClaimsIdentity(claims, "login");
var claimsPrinciple = new ClaimsPrincipal(claimsIdentity); var claimsPrinciple = new ClaimsPrincipal(claimsIdentity);
await HttpContext.Authentication.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrinciple); await HttpContext.Authentication.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrinciple, new Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties()
{
AllowRefresh = true,
ExpiresUtc = DateTime.UtcNow.AddDays(30),
IsPersistent = true,
IssuedUtc = DateTime.UtcNow
});
return Ok(); return Ok();
} }
}
catch (Exception)
{
return Unauthorized();
}
return Unauthorized(); return Unauthorized();
} }

View File

@ -30,8 +30,12 @@ namespace WebfrontCore.Controllers
{ {
var server = Manager.Servers.First(s => s.GetHashCode() == serverId); var server = Manager.Servers.First(s => s.GetHashCode() == serverId);
var client = User.AsPlayer(); var client = new Player()
client.CurrentServer = server; {
ClientId = User.ClientId,
Level = User.Level,
CurrentServer = server
};
var remoteEvent = new Event(Event.GType.Say, command, client, null, server); var remoteEvent = new Event(Event.GType.Say, command, client, null, server);

View File

@ -35,7 +35,7 @@ namespace WebfrontCore.Controllers
LevelInt = (int)p.Level LevelInt = (int)p.Level
}).ToList(), }).ToList(),
ChatHistory = s.ChatHistory.OrderBy(c => c.Time).Take((int)Math.Ceiling(s.ClientNum / 2.0)).ToArray(), ChatHistory = s.ChatHistory.OrderBy(c => c.Time).Take((int)Math.Ceiling(s.ClientNum / 2.0)).ToArray(),
PlayerHistory = s.PlayerHistory.ToArray() PlayerHistory = s.PlayerHistory.ToArray(),
}; };
return PartialView("_ClientActivity", serverInfo); return PartialView("_ClientActivity", serverInfo);
} }

View File

@ -55,7 +55,8 @@ namespace WebfrontCore
AuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme, AuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme,
AutomaticAuthenticate = true, AutomaticAuthenticate = true,
AutomaticChallenge = true, AutomaticChallenge = true,
LoginPath = "/Account/Login/" LoginPath = "/Account/Login/",
ExpireTimeSpan = TimeSpan.FromDays(30),
}); });
app.UseMvc(routes => app.UseMvc(routes =>
@ -65,7 +66,6 @@ namespace WebfrontCore
template: "{controller=Home}/{action=Index}/{id?}"); template: "{controller=Home}/{action=Index}/{id?}");
}); });
//app.UseBasicAuthentication(Authentication.Basic.Generate());
} }
} }
} }

View File

@ -30,7 +30,8 @@ namespace WebfrontCore.ViewComponents
Level = p.Level.ToString(), Level = p.Level.ToString(),
LevelInt = (int)p.Level LevelInt = (int)p.Level
}).ToList(), }).ToList(),
ChatHistory = s.ChatHistory.ToArray() ChatHistory = s.ChatHistory.ToArray(),
Online = !s.Throttled
}).ToList(); }).ToList();
return View("_List", serverInfo); return View("_List", serverInfo);
} }

View File

@ -17,5 +17,5 @@
</div> </div>
<div class="row server-history mb-4"> <div class="row server-history mb-4">
<div class="server-history-row col-md-12" id="server_history_@Model.ID" data-serverid="@Model.ID" data-clienthistory='@Html.Raw(Json.Serialize(Model.PlayerHistory))'></div> <div class="server-history-row col-md-12" id="server_history_@Model.ID" data-serverid="@Model.ID" data-clienthistory='@Html.Raw(Json.Serialize(Model.PlayerHistory))' data-online="@Model.Online"></div>
</div> </div>

View File

@ -44,7 +44,6 @@
} }
else else
{ {
<li class="nav-item text-center text-md-left"><a href="#" id="profile_action_login_btn" class="nav-link profile-action oi oi-key oi-fix-navbar w-100" title="Login" data-action="login" aria-hidden="true"></a></li> <li class="nav-item text-center text-md-left"><a href="#" id="profile_action_login_btn" class="nav-link profile-action oi oi-key oi-fix-navbar w-100" title="Login" data-action="login" aria-hidden="true"></a></li>
} }
</ul> </ul>
@ -82,6 +81,8 @@
</button> </button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="modal-message text-danger mb-3"></div>
<div class="modal-body-content"></div>
</div> </div>
<!--<div class="modal-footer"> <!--<div class="modal-footer">
<button type="button" class="btn btn-primary">Action</button> <button type="button" class="btn btn-primary">Action</button>

View File

@ -3,58 +3,72 @@
} }
.level-color-user, .level-color-guest { .level-color-user, .level-color-guest {
color: #fff;
color: rgba(255, 255, 255, 0.7); color: rgba(255, 255, 255, 0.7);
} }
.level-bgcolor-user, .level-bgcolor-guest { .level-bgcolor-user, .level-bgcolor-guest {
background-color: #fff;
background-color: rgba(255, 255, 255, 0.85); background-color: rgba(255, 255, 255, 0.85);
} }
.level-color-trusted { .level-color-trusted {
color: #749363;
color: rgba(116,147,99,1); color: rgba(116,147,99,1);
} }
.level-bgcolor-trusted, .level-bgcolor-user { .level-bgcolor-trusted {
background-color: #749363;
background-color: rgba(116,147,99,1); background-color: rgba(116,147,99,1);
} }
.level-color-flagged { .level-color-flagged {
color: #fd9c38;
color: rgba(253, 139, 22, 0.85); color: rgba(253, 139, 22, 0.85);
} }
.level-bgcolor-flagged { .level-bgcolor-flagged {
background-color: #fd9c38;
background-color: rgba(253, 139, 22, 0.85); background-color: rgba(253, 139, 22, 0.85);
} }
.level-color-banned, .level-color-console { .level-color-banned, .level-color-console {
color: #ff6060;
color: rgba(255, 69, 69, 0.85); color: rgba(255, 69, 69, 0.85);
} }
.level-bgcolor-banned { .level-bgcolor-banned {
background-color: #ff6060;
background-color: rgba(255, 69, 69, 0.85); background-color: rgba(255, 69, 69, 0.85);
} }
.level-color-moderator { .level-color-moderator {
color: #f0de8b;
color: rgba(235, 211, 101, 0.75); color: rgba(235, 211, 101, 0.75);
} }
.level-bgcolor-moderator { .level-bgcolor-moderator {
background-color: #f0de8b;
background-color: rgba(235, 211, 101, 0.75); background-color: rgba(235, 211, 101, 0.75);
} }
.level-color-administrator { .level-color-administrator {
color: #f1a8e8;
color: rgba(236, 130, 222, 0.69); color: rgba(236, 130, 222, 0.69);
} }
.level-bgcolor-administrator { .level-bgcolor-administrator {
background-color: #f1a8e8;
background-color: rgba(236, 130, 222, 0.69); background-color: rgba(236, 130, 222, 0.69);
} }
.level-color-senioradmin { .level-color-senioradmin {
color: #50bcc3;
color: rgba(50, 177, 185, 0.85); color: rgba(50, 177, 185, 0.85);
} }
.level-bgcolor-senioradmin { .level-bgcolor-senioradmin {
background-color: #50bcc3;
background-color: rgba(50, 177, 185, 0.85); background-color: rgba(50, 177, 185, 0.85);
} }
@ -72,26 +86,32 @@
.penalties-color-kick, .penalties-color-kick,
.penalties-color-unban { .penalties-color-unban {
color: #749363;
color: rgba(116, 147, 99, 1); color: rgba(116, 147, 99, 1);
} }
.penalties-color-report { .penalties-color-report {
color: #749363;
color: rgba(116, 147, 99, 1); color: rgba(116, 147, 99, 1);
} }
.penalties-color-warning { .penalties-color-warning {
color: #f0de8b;
color: rgba(235, 211, 101, 0.75); color: rgba(235, 211, 101, 0.75);
} }
.penalties-color-tempban { .penalties-color-tempban {
color: #fd9c38;
color: rgba(253, 139, 22, 0.85); color: rgba(253, 139, 22, 0.85);
} }
.penalties-color-flag { .penalties-color-flag {
color: #fd9c38;
color: rgba(253, 139, 22, 0.85); color: rgba(253, 139, 22, 0.85);
} }
.penalties-color-ban { .penalties-color-ban {
color: #ff6060;
color: rgba(255, 69, 69, 0.85); color: rgba(255, 69, 69, 0.85);
} }
@ -122,6 +142,7 @@
} }
#profile_level > span.level { #profile_level > span.level {
color: #f1a8e8;
color: rgba(236, 130, 222, 0.69); color: rgba(236, 130, 222, 0.69);
font-weight: bold; font-weight: bold;
font-size: 1.5em; font-size: 1.5em;
@ -137,6 +158,7 @@
} }
#profile_level > span.level { #profile_level > span.level {
color: #f1a8e8;
color: rgba(236, 130, 222, 0.69); color: rgba(236, 130, 222, 0.69);
font-weight: bold; font-weight: bold;
} }

Binary file not shown.

View File

@ -6,12 +6,14 @@
const actionType = $(this).data('action'); const actionType = $(this).data('action');
$.get('/Action/' + actionType + 'Form') $.get('/Action/' + actionType + 'Form')
.done(function (response) { .done(function (response) {
$('#actionModal .modal-body').html(response); $('#actionModal .modal-message').fadeOut('fast');
$('#actionModal .modal-body-content').html(response);
$('#actionModal').modal(); $('#actionModal').modal();
}) })
.fail(function (jqxhr, textStatus, error) { .fail(function (jqxhr, textStatus, error) {
$('#actionModal .modal-body').html('<span class="text-danger">' + error + '</span>'); $('#actionModal .modal-message').text('Error &mdash ' + error);
$('#actionModal').modal(); $('#actionModal').modal();
$('#actionModal .modal-message').fadeIn('fast');
}); });
}); });
@ -29,18 +31,22 @@
location.reload(); location.reload();
} }
else { else {
$('#actionModal .modal-body').html(response); $('#actionModal .modal-message').fadeOut('fast');
$('#actionModal .modal-body-content').html(response);
$('#actionModal').modal(); $('#actionModal').modal();
} }
}) })
.fail(function (jqxhr, textStatus, error) { .fail(function (jqxhr, textStatus, error) {
if (jqxhr.status == 401) { if ($('#actionModal .modal-message').text.length > 0) {
$('#actionModal .modal-body').removeClass('text-danger'); $('#actionModal .modal-message').fadeOut('fast');
$('#actionModal .modal-body').prepend('<div class="text-danger mb-3">Invalid login credentials</div>'); }
if (jqxhr.status === 401) {
$('#actionModal .modal-message').text('Invalid login credentials');
} }
else { else {
$('#actionModal .modal-body').html('<span class="text-danger">Error &mdash; ' + error + '</span>'); $('#actionModal .modal-message').text('Error &mdash; ' + error);
} }
$('#actionModal .modal-message').fadeIn('fast');
}); });
}); });
}); });

View File

@ -1,4 +1,4 @@
function getPlayerHistoryChart(playerHistory, i, width) { function getPlayerHistoryChart(playerHistory, i, width, color) {
/////////////////////////////////////// ///////////////////////////////////////
// thanks to canvasjs :( // thanks to canvasjs :(
playerHistory.forEach(function (item, i) { playerHistory.forEach(function (item, i) {
@ -6,7 +6,7 @@
}); });
return new CanvasJS.Chart(`server_history_${i}`, { return new CanvasJS.Chart(`server_history_${i}`, {
backgroundColor: "#191919", backgroundColor: '#191919',
height: 100, height: 100,
width: width, width: width,
animationEnabled: true, animationEnabled: true,
@ -41,7 +41,7 @@
data: [{ data: [{
showInLegend: false, showInLegend: false,
type: "splineArea", type: "splineArea",
color: "rgba(0, 122, 204, 0.432)", color: color,
markerSize: 0, markerSize: 0,
dataPoints: playerHistory dataPoints: playerHistory
}] }]
@ -53,8 +53,9 @@ var charts = {};
$('.server-history-row').each(function (index, element) { $('.server-history-row').each(function (index, element) {
let clientHistory = $(this).data('clienthistory'); let clientHistory = $(this).data('clienthistory');
let serverId = $(this).data('serverid'); let serverId = $(this).data('serverid');
let color = $(this).data('online') === 'True' ? '#007acc' : '#ff6060'
let width = $('.server-header').first().width(); let width = $('.server-header').first().width();
let historyChart = getPlayerHistoryChart(clientHistory, serverId, width); let historyChart = getPlayerHistoryChart(clientHistory, serverId, width, color);
historyChart.render(); historyChart.render();
charts[serverId] = historyChart; charts[serverId] = historyChart;
}); });