diff --git a/Application/ApplicationManager.cs b/Application/ApplicationManager.cs index 7305d9796..b120c55d1 100644 --- a/Application/ApplicationManager.cs +++ b/Application/ApplicationManager.cs @@ -388,42 +388,80 @@ namespace IW4MAdmin.Application #endregion #region META - async Task> getLastMap(int clientId) + async Task> getProfileMeta(int clientId, int offset, int count) { - var meta = await _metaService.GetPersistentMeta("LastMapPlayed", new EFClient() { ClientId = clientId }); + var metaList = new List(); - return meta == null ? new List() : new List() + // we don't want to return anything because it means we're trying to retrieve paged meta data + if (count > 1) { - new ProfileMeta() - { - Id = meta.MetaId, - Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_LAST_MAP"], - Value = meta.Value, - Show = true - } + return metaList; + } - }; - } + var lastMapMeta = await _metaService.GetPersistentMeta("LastMapPlayed", new EFClient() { ClientId = clientId }); - async Task> getLastServer(int clientId) - { - var meta = await _metaService.GetPersistentMeta("LastServerPlayed", new EFClient() { ClientId = clientId }); - - return meta == null ? new List() : new List() + metaList.Add(new ProfileMeta() { - new ProfileMeta() - { - Id = meta.MetaId, - Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_LAST_SERVER"], - Value = meta.Value, - Show = true - } + Id = lastMapMeta.MetaId, + Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_LAST_MAP"], + Value = lastMapMeta.Value, + Show = true, + Type = ProfileMeta.MetaType.Information + }); - }; - } + var lastServerMeta = await _metaService.GetPersistentMeta("LastServerPlayed", new EFClient() { ClientId = clientId }); - MetaService.AddRuntimeMeta(getLastMap); - MetaService.AddRuntimeMeta(getLastServer); + metaList.Add(new ProfileMeta() + { + Id = lastServerMeta.MetaId, + Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_LAST_SERVER"], + Value = lastServerMeta.Value, + Show = true, + Type = ProfileMeta.MetaType.Information + }); + + var client = await GetClientService().Get(clientId); + + metaList.Add(new ProfileMeta() + { + Id = client.ClientId, + Key = $"{Utilities.CurrentLocalization.LocalizationIndex["GLOBAL_TIME_HOURS"]} {Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_PLAYER"]}", + Value = Math.Round(client.TotalConnectionTime / 3600.0, 1).ToString("#,##0"), + Show = true, + Type = ProfileMeta.MetaType.Information + }); + + metaList.Add(new ProfileMeta() + { + Id = client.ClientId, + Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_FSEEN"], + Value = Utilities.GetTimePassed(client.FirstConnection, false), + Show = true, + Type = ProfileMeta.MetaType.Information + }); + + metaList.Add(new ProfileMeta() + { + Id = client.ClientId, + Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_LSEEN"], + Value = Utilities.GetTimePassed(client.LastConnection, false), + Show = true, + Type = ProfileMeta.MetaType.Information + }); + + metaList.Add(new ProfileMeta() + { + Id = client.ClientId, + Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_CONNECTIONS"], + Value = client.Connections, + Show = true, + Type = ProfileMeta.MetaType.Information + }); + + return metaList; + }; + + MetaService.AddRuntimeMeta(getProfileMeta); #endregion #region INIT diff --git a/Plugins/Stats/Plugin.cs b/Plugins/Stats/Plugin.cs index c653d9a9a..5b083370a 100644 --- a/Plugins/Stats/Plugin.cs +++ b/Plugins/Stats/Plugin.cs @@ -124,8 +124,13 @@ namespace IW4MAdmin.Plugins.Stats "/Stats/TopPlayersAsync"); // meta data info - async Task> getStats(int clientId) + async Task> getStats(int clientId, int offset, int count) { + if (count > 1) + { + return new List(); + } + IList clientStats; using (var ctx = new DatabaseContext(disableTracking: true)) { @@ -146,38 +151,50 @@ namespace IW4MAdmin.Plugins.Stats { Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_RANKING"], Value = "#" + await StatManager.GetClientOverallRanking(clientId), + Type = ProfileMeta.MetaType.Information }, new ProfileMeta() { Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_TEXT_KILLS"], - Value = kills + Value = kills, + Type = ProfileMeta.MetaType.Information }, new ProfileMeta() { Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_TEXT_DEATHS"], - Value = deaths + Value = deaths, + Type = ProfileMeta.MetaType.Information }, new ProfileMeta() { Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_TEXT_KDR"], - Value = kdr + Value = kdr, + Type = ProfileMeta.MetaType.Information }, new ProfileMeta() { Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_COMMANDS_PERFORMANCE"], - Value = performance + Value = performance, + Type = ProfileMeta.MetaType.Information }, new ProfileMeta() { Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_META_SPM"], - Value = spm + Value = spm, + Type = ProfileMeta.MetaType.Information } }; } - async Task> getAnticheatInfo(int clientId) + async Task> getAnticheatInfo(int clientId, int offset, int count) { + if (count > 1) + { + return new List(); + } + IList clientStats; + using (var ctx = new DatabaseContext(disableTracking: true)) { clientStats = await ctx.Set() @@ -221,24 +238,28 @@ namespace IW4MAdmin.Plugins.Stats { Key = "Chest Ratio", Value = chestRatio, + Type = ProfileMeta.MetaType.Information, Sensitive = true }, new ProfileMeta() { Key = "Abdomen Ratio", Value = abdomenRatio, + Type = ProfileMeta.MetaType.Information, Sensitive = true }, new ProfileMeta() { Key = "Chest To Abdomen Ratio", Value = chestAbdomenRatio, + Type = ProfileMeta.MetaType.Information, Sensitive = true }, new ProfileMeta() { Key = "Headshot Ratio", Value = headRatio, + Type = ProfileMeta.MetaType.Information, Sensitive = true }, new ProfileMeta() @@ -246,49 +267,64 @@ namespace IW4MAdmin.Plugins.Stats Key = "Hit Offset Average", // todo: make sure this is wrapped somewhere else Value = $"{Math.Round(((float)hitOffsetAverage), 4).ToString(new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName))}°", + Type = ProfileMeta.MetaType.Information, Sensitive = true }, new ProfileMeta() { Key = "Max Strain", Value = Math.Round(maxStrain, 3), + Type = ProfileMeta.MetaType.Information, Sensitive = true }, }; } - async Task> getMessages(int clientId) + async Task> getMessages(int clientId, int offset, int count) { + if (count <= 1) + { + using (var ctx = new DatabaseContext(true)) + { + return new List + { + new ProfileMeta() + { + Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_MESSAGES"], + Value = await ctx.Set().CountAsync(), + Type = ProfileMeta.MetaType.Information + } + }; + } + } + List messageMeta; using (var ctx = new DatabaseContext(disableTracking: true)) { - var messages = ctx.Set().Where(m => m.ClientId == clientId); + var messages = ctx.Set().Where(m => m.ClientId == clientId) + .OrderByDescending(_message => _message.TimeSent) + .Skip(offset) + .Take(count); messageMeta = await messages.Select(m => new ProfileMeta() { - Key = "EventMessage", + Key = null, Value = m.Message, When = m.TimeSent, - Extra = m.ServerId.ToString() + Extra = m.ServerId.ToString(), + Type = ProfileMeta.MetaType.ChatMessage }).ToListAsync(); } - messageMeta.Add(new ProfileMeta() - { - Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_MESSAGES"], - Value = messageMeta.Count - }); - return messageMeta; } - MetaService.AddRuntimeMeta(getStats); - if (Config.Configuration().EnableAntiCheat) { MetaService.AddRuntimeMeta(getAnticheatInfo); } + MetaService.AddRuntimeMeta(getStats); MetaService.AddRuntimeMeta(getMessages); async Task totalKills(Server server) diff --git a/SharedLibraryCore/Dtos/PenaltyInfo.cs b/SharedLibraryCore/Dtos/PenaltyInfo.cs index 9f51eedba..995bc0985 100644 --- a/SharedLibraryCore/Dtos/PenaltyInfo.cs +++ b/SharedLibraryCore/Dtos/PenaltyInfo.cs @@ -10,17 +10,19 @@ namespace SharedLibraryCore.Dtos { public string OffenderName { get; set; } public int OffenderId { get; set; } + public ulong OffenderNetworkId { get; set; } + public string OffenderIPAddress { get; set; } public string PunisherName { get; set; } public int PunisherId { get; set; } + public ulong PunisherNetworkId { get; set; } + public string PunisherIPAddress { get; set; } public string PunisherLevel { get; set; } public int PunisherLevelId { get; set; } public string Offense { get; set; } public string AutomatedOffense { get; set; } - public string Type { get; set; } + public string PenaltyType { get; set; } public string TimePunished { get; set; } public string TimeRemaining { get; set; } public bool Expired { get; set; } - public string IPAddress { get; set; } - public ulong NetworkId { get; set; } } } diff --git a/SharedLibraryCore/Dtos/PlayerInfo.cs b/SharedLibraryCore/Dtos/PlayerInfo.cs index 0c11dab35..eb1f4cb0e 100644 --- a/SharedLibraryCore/Dtos/PlayerInfo.cs +++ b/SharedLibraryCore/Dtos/PlayerInfo.cs @@ -18,10 +18,10 @@ namespace SharedLibraryCore.Dtos public List IPs { get; set; } public bool HasActivePenalty { get; set; } public string ActivePenaltyType { get; set; } - public int ConnectionCount { get; set; } - public string LastSeen { get; set; } - public string FirstSeen { get; set; } - public string TimePlayed { get; set; } + //public int ConnectionCount { get; set; } + //public string LastSeen { get; set; } + //public string FirstSeen { get; set; } + //public string TimePlayed { get; set; } public bool Authenticated { get; set; } public List Meta { get; set; } public bool Online { get; set; } diff --git a/SharedLibraryCore/Dtos/ProfileMeta.cs b/SharedLibraryCore/Dtos/ProfileMeta.cs index 7c9380520..b0a30c978 100644 --- a/SharedLibraryCore/Dtos/ProfileMeta.cs +++ b/SharedLibraryCore/Dtos/ProfileMeta.cs @@ -8,11 +8,22 @@ namespace SharedLibraryCore.Dtos { public class ProfileMeta : SharedInfo { + public enum MetaType + { + Other, + Information, + AliasUpdate, + ChatMessage + } + public DateTime When { get; set; } public string WhenString => Utilities.GetTimePassed(When, false); public string Key { get; set; } public dynamic Value { get; set; } public string Extra { get; set; } public virtual string Class => Value.GetType().ToString(); + public MetaType Type { get; set; } + public int? Column { get; set; } + public int? Order { get; set; } } } diff --git a/SharedLibraryCore/Services/MetaService.cs b/SharedLibraryCore/Services/MetaService.cs index 456b3edb9..7910d24ef 100644 --- a/SharedLibraryCore/Services/MetaService.cs +++ b/SharedLibraryCore/Services/MetaService.cs @@ -11,7 +11,7 @@ namespace SharedLibraryCore.Services { public class MetaService { - private static List>>> _metaActions = new List>>>(); + private static List>>> _metaActions = new List>>>(); /// /// adds or updates meta key and value to the database @@ -71,7 +71,7 @@ namespace SharedLibraryCore.Services /// aads a meta task to the runtime meta list /// /// - public static void AddRuntimeMeta(Func>> metaAction) + public static void AddRuntimeMeta(Func>> metaAction) { _metaActions.Add(metaAction); } @@ -80,14 +80,16 @@ namespace SharedLibraryCore.Services /// retrieves all the runtime meta information for given client idea /// /// id of the client + /// number of meta items to retrieve + /// offset from the first item /// - public static async Task> GetRuntimeMeta(int clientId) + public static async Task> GetRuntimeMeta(int clientId, int offset = 0, int count = int.MaxValue) { var meta = new List(); foreach (var action in _metaActions) { - meta.AddRange(await action(clientId)); + meta.AddRange(await action(clientId, offset, count)); } return meta; diff --git a/SharedLibraryCore/Services/PenaltyService.cs b/SharedLibraryCore/Services/PenaltyService.cs index 31f59eba7..d131b1e97 100644 --- a/SharedLibraryCore/Services/PenaltyService.cs +++ b/SharedLibraryCore/Services/PenaltyService.cs @@ -195,7 +195,7 @@ namespace SharedLibraryCore.Services PunisherName = punisherAlias.Name, PunisherId = penalty.PunisherId, Offense = penalty.Offense, - Type = penalty.Type.ToString(), + PenaltyType = penalty.Type.ToString(), TimeRemaining = penalty.Expires.HasValue ? (now > penalty.Expires ? "" : penalty.Expires.ToString()) : DateTime.MaxValue.ToString(), AutomatedOffense = penalty.AutomatedOffense, Expired = penalty.Expires.HasValue && penalty.Expires <= DateTime.UtcNow @@ -208,9 +208,9 @@ namespace SharedLibraryCore.Services list.ForEach(p => { // todo: why does this have to be done? - if (((PenaltyInfo)p.Value).Type.Length < 2) + if (((PenaltyInfo)p.Value).PenaltyType.Length < 2) { - ((PenaltyInfo)p.Value).Type = ((Penalty.PenaltyType)Convert.ToInt32(((PenaltyInfo)p.Value).Type)).ToString(); + ((PenaltyInfo)p.Value).PenaltyType = ((Penalty.PenaltyType)Convert.ToInt32(((PenaltyInfo)p.Value).PenaltyType)).ToString(); } var pi = ((PenaltyInfo)p.Value); @@ -251,7 +251,7 @@ namespace SharedLibraryCore.Services PunisherName = punisherAlias.Name, PunisherId = penalty.PunisherId, Offense = penalty.Offense, - Type = penalty.Type.ToString(), + PenaltyType = penalty.Type.ToString(), AutomatedOffense = penalty.AutomatedOffense }, When = penalty.When, @@ -263,9 +263,9 @@ namespace SharedLibraryCore.Services list.ForEach(p => { // todo: why does this have to be done? - if (((PenaltyInfo)p.Value).Type.Length < 2) + if (((PenaltyInfo)p.Value).PenaltyType.Length < 2) { - ((PenaltyInfo)p.Value).Type = ((Penalty.PenaltyType)Convert.ToInt32(((PenaltyInfo)p.Value).Type)).ToString(); + ((PenaltyInfo)p.Value).PenaltyType = ((Penalty.PenaltyType)Convert.ToInt32(((PenaltyInfo)p.Value).PenaltyType)).ToString(); } }); diff --git a/WebfrontCore/Controllers/ClientController.cs b/WebfrontCore/Controllers/ClientController.cs index 9fe100188..0eb081ea9 100644 --- a/WebfrontCore/Controllers/ClientController.cs +++ b/WebfrontCore/Controllers/ClientController.cs @@ -34,10 +34,6 @@ namespace WebfrontCore.Controllers ClientId = client.ClientId, IPAddress = client.IPAddressString, NetworkId = client.NetworkId, - ConnectionCount = client.Connections, - FirstSeen = Utilities.GetTimePassed(client.FirstConnection, false), - LastSeen = Utilities.GetTimePassed(client.LastConnection, false), - TimePlayed = Math.Round(client.TotalConnectionTime / 3600.0, 1).ToString("#,##0"), Meta = new List(), Aliases = client.AliasLink.Children .Where(a => a.Name != client.Name) @@ -59,7 +55,7 @@ namespace WebfrontCore.Controllers LinkedAccounts = client.LinkedAccounts }; - var meta = await MetaService.GetRuntimeMeta(client.ClientId); + var meta = await MetaService.GetRuntimeMeta(client.ClientId, 0, 1); var penaltyMeta = await Manager.GetPenaltyService() .ReadGetClientPenaltiesAsync(client.ClientId); var administeredPenaltiesMeta = await Manager.GetPenaltyService() @@ -76,19 +72,19 @@ namespace WebfrontCore.Controllers }); } - if (Authorized) - { - clientDto.Meta.AddRange(client.AliasLink.Children - .GroupBy(a => a.Name) - .Select(a => a.First()) - .Select(a => new ProfileMeta() - { - Key = "AliasEvent", - Value = $"{Localization["WEBFRONT_CLIENT_META_JOINED"]} {a.Name}", - Sensitive = true, - When = a.DateAdded - })); - } + //if (Authorized) + //{ + // clientDto.Meta.AddRange(client.AliasLink.Children + // .GroupBy(a => a.Name) + // .Select(a => a.First()) + // .Select(a => new ProfileMeta() + // { + // Value = $"{Localization["WEBFRONT_CLIENT_META_JOINED"]} {a.Name}", + // Sensitive = true, + // When = a.DateAdded, + // Type = ProfileMeta.MetaType.AliasUpdate + // })); + //} if (Authorized) { @@ -118,6 +114,7 @@ namespace WebfrontCore.Controllers Value = m.Value, Show = false, })); + clientDto.Meta = clientDto.Meta .OrderByDescending(m => m.When) .ToList(); @@ -173,13 +170,25 @@ namespace WebfrontCore.Controllers Name = c.Name, Level = c.Level.ToLocalizedLevelName(), LevelInt = (int)c.Level, - ClientId = c.ClientId, - LastSeen = Utilities.GetTimePassed(c.LastConnection, false) + // todo: add back last seen for search + ClientId = c.ClientId }) .ToList(); ViewBag.Title = $"{clientsDto.Count} {Localization["WEBFRONT_CLIENT_SEARCH_MATCHING"]} \"{clientName}\""; return View("Find/Index", clientsDto); } + + public async Task Meta(int id, int count, int offset) + { + var meta = await MetaService.GetRuntimeMeta(id, offset, count); + + if (meta.Count == 0) + { + return Ok(); + } + + return View("Components/ProfileMetaList/_List", meta); + } } } diff --git a/WebfrontCore/Controllers/PenaltyController.cs b/WebfrontCore/Controllers/PenaltyController.cs index b5e1fe59e..6d1c5084a 100644 --- a/WebfrontCore/Controllers/PenaltyController.cs +++ b/WebfrontCore/Controllers/PenaltyController.cs @@ -46,20 +46,25 @@ namespace WebfrontCore.Controllers { // todo: this seems like it's pulling unnecessary info from LINQ to entities. var iqPenalties = ctx.Penalties + .AsNoTracking() .Where(p => p.Type == SharedLibraryCore.Objects.Penalty.PenaltyType.Ban && p.Active) .OrderByDescending(_penalty => _penalty.When) .Select(p => new PenaltyInfo() { Id = p.PenaltyId, OffenderId = p.OffenderId, + OffenderName = p.Offender.CurrentAlias.Name, + OffenderNetworkId = (ulong)p.Offender.NetworkId, + OffenderIPAddress = Authorized ? p.Offender.CurrentAlias.IPAddress.ConvertIPtoString() : null, Offense = p.Offense, PunisherId = p.PunisherId, - Type = p.Type.ToString(), + PunisherNetworkId = (ulong)p.Punisher.NetworkId, + PunisherName = p.Punisher.CurrentAlias.Name, + PunisherIPAddress = Authorized ? p.Punisher.CurrentAlias.IPAddress.ConvertIPtoString() : null, + PenaltyType = p.Type.ToString(), TimePunished = p.When.ToString(), - TimeRemaining = "", - AutomatedOffense = Authorized ? p.AutomatedOffense : "", - NetworkId = (ulong)p.Offender.NetworkId, - IPAddress = Authorized ? p.Offender.IPAddressString : "" + TimeRemaining = null, + AutomatedOffense = Authorized ? p.AutomatedOffense : null, }); #if DEBUG == true var querySql = iqPenalties.ToSql(); diff --git a/WebfrontCore/Startup.cs b/WebfrontCore/Startup.cs index 150b57c8b..8e64dd8b2 100644 --- a/WebfrontCore/Startup.cs +++ b/WebfrontCore/Startup.cs @@ -29,6 +29,19 @@ namespace WebfrontCore // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { + // allow CORS + services.AddCors(_options => + { + _options.AddPolicy("AllowAll", + _builder => + { + _builder.AllowAnyOrigin() + .AllowAnyMethod() + .AllowAnyHeader() + .AllowCredentials(); + }); + }); + // Add framework services. var mvcBuilder = services.AddMvc() .ConfigureApplicationPartManager(_ => @@ -98,6 +111,7 @@ namespace WebfrontCore app.UseStaticFiles(); app.UseAuthentication(); + app.UseCors("AllowAll"); app.UseMvc(routes => { diff --git a/WebfrontCore/ViewComponents/PenaltyListViewComponent.cs b/WebfrontCore/ViewComponents/PenaltyListViewComponent.cs index f3a2b55ab..c95c63abc 100644 --- a/WebfrontCore/ViewComponents/PenaltyListViewComponent.cs +++ b/WebfrontCore/ViewComponents/PenaltyListViewComponent.cs @@ -33,7 +33,7 @@ namespace WebfrontCore.ViewComponents $"{showEvadeString(p)}{p.AutomatedOffense}" : $"{showEvadeString(p)}{p.Offense}", #endif - Type = p.Type.ToString(), + PenaltyType = p.Type.ToString(), TimePunished = Utilities.GetTimePassed(p.When, false), // show time passed if ban TimeRemaining = DateTime.UtcNow > p.Expires ? "" : $"{((p.Expires ?? DateTime.MaxValue).Year == DateTime.MaxValue.Year ? Utilities.GetTimePassed(p.When, true) : Utilities.TimeSpanText((p.Expires ?? DateTime.MaxValue) - DateTime.UtcNow))}", diff --git a/WebfrontCore/ViewComponents/ProfileMetaListViewComponent.cs b/WebfrontCore/ViewComponents/ProfileMetaListViewComponent.cs new file mode 100644 index 000000000..b12c2b83c --- /dev/null +++ b/WebfrontCore/ViewComponents/ProfileMetaListViewComponent.cs @@ -0,0 +1,15 @@ +using Microsoft.AspNetCore.Mvc; +using SharedLibraryCore.Services; +using System.Threading.Tasks; + +namespace WebfrontCore.ViewComponents +{ + public class ProfileMetaListViewComponent : ViewComponent + { + public async Task InvokeAsync(int clientId, int count, int offset) + { + var meta = await MetaService.GetRuntimeMeta(clientId, offset, count); + return View("_List", meta); + } + } +} diff --git a/WebfrontCore/Views/Client/Find/Index.cshtml b/WebfrontCore/Views/Client/Find/Index.cshtml index edf986ec1..61aa6e168 100644 --- a/WebfrontCore/Views/Client/Find/Index.cshtml +++ b/WebfrontCore/Views/Client/Find/Index.cshtml @@ -17,7 +17,7 @@
@Html.ActionLink(client.Name, "ProfileAsync", "Client", new { id = client.ClientId })
@client.Level
-
@client.LastSeen @loc["WEBFRONT_PENALTY_TEMPLATE_AGO"]
+ @*
@client.LastSeen @loc["WEBFRONT_PENALTY_TEMPLATE_AGO"]
*@
} } diff --git a/WebfrontCore/Views/Client/Profile/Index.cshtml b/WebfrontCore/Views/Client/Profile/Index.cshtml index fdfd7943d..13d552b68 100644 --- a/WebfrontCore/Views/Client/Profile/Index.cshtml +++ b/WebfrontCore/Views/Client/Profile/Index.cshtml @@ -5,6 +5,9 @@ var loc = SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex; string gravatarUrl = Model.Meta.FirstOrDefault(m => m.Key == "GravatarEmail")?.Value; bool isTempBanned = Model.ActivePenaltyType == "TempBan"; + var informationMeta = Model.Meta + .Where(_meta => _meta.Type == SharedLibraryCore.Dtos.ProfileMeta.MetaType.Information) + .ToList(); }
@@ -76,27 +79,41 @@
+
-
- @loc["WEBFRONT_PROFILE_PLAYER"] @Model.TimePlayed @loc["GLOBAL_TIME_HOURS"] -
-
- @loc["WEBFRONT_PROFILE_FSEEN"] @Model.FirstSeen @loc["WEBFRONT_PENALTY_TEMPLATE_AGO"] -
-
- @loc["WEBFRONT_PROFILE_LSEEN"] @Model.LastSeen @loc["WEBFRONT_PENALTY_TEMPLATE_AGO"] -
+ @for (int i = 0; i < informationMeta.Count; i += 3) + { +
+ @informationMeta[i].Value + @informationMeta[i].Key +
+ }
+ @for (int i = 1; i < informationMeta.Count; i += 3) + { +
+ @informationMeta[i].Value + @informationMeta[i].Key +
+ }
+ @for (int i = 2; i < informationMeta.Count; i += 3) + { +
+ @informationMeta[i].Value + @informationMeta[i].Key +
+ }
+ @await Component.InvokeAsync("ProfileMetaList", new { clientId = Model.ClientId, count = 30, offset = 0 })
@@ -105,12 +122,9 @@ } @section scripts { - + + } diff --git a/WebfrontCore/Views/Penalty/_Penalty.cshtml b/WebfrontCore/Views/Penalty/_Penalty.cshtml index 83477e3d8..b92117678 100644 --- a/WebfrontCore/Views/Penalty/_Penalty.cshtml +++ b/WebfrontCore/Views/Penalty/_Penalty.cshtml @@ -13,9 +13,9 @@ - @loc["WEBFRONT_PENALTY_TEMPLATE_TYPE"] - - @Model.Type + @loc["WEBFRONT_PENALTY_TEMPLATE_PenaltyType"] + + @Model.PenaltyType @@ -53,8 +53,8 @@ @Html.ActionLink(Model.OffenderName, "ProfileAsync", "Client", new { id = Model.OffenderId }, new { @class = "link-inverse" }) - - @Model.Type + + @Model.PenaltyType @Model.Offense diff --git a/WebfrontCore/Views/Shared/Components/ProfileMetaList/_List.cshtml b/WebfrontCore/Views/Shared/Components/ProfileMetaList/_List.cshtml new file mode 100644 index 000000000..cb9fe9d09 --- /dev/null +++ b/WebfrontCore/Views/Shared/Components/ProfileMetaList/_List.cshtml @@ -0,0 +1,20 @@ +@model List +@{Layout = null;} + +
+ + @SharedLibraryCore.Utilities.GetTimePassed(Model.FirstOrDefault()?.When ?? DateTime.Now, true) +
+ +@foreach (var meta in Model) +{ + @switch (meta.Type) + { + case SharedLibraryCore.Dtos.ProfileMeta.MetaType.ChatMessage: +
+ > + @meta.Value +
+ break; + } +} \ No newline at end of file diff --git a/WebfrontCore/wwwroot/js/profile.js b/WebfrontCore/wwwroot/js/profile.js index 591c6c6ef..915418510 100644 --- a/WebfrontCore/wwwroot/js/profile.js +++ b/WebfrontCore/wwwroot/js/profile.js @@ -1,13 +1,4 @@ -// keeps track of how many events have been displayed -let count = 1; -let metaIndex = 0; - -$(document).ready(function () { - - if (typeof clientInfo === 'undefined') { - return false; - } - +$(document).ready(function () { /* Expand alias tab if they have any */ @@ -19,51 +10,6 @@ $(document).ready(function () { } }); - /* - load the initial 40 events - */ - $.each(clientInfo.Meta, function (index, meta) { - if (meta.key.includes("Event")) { - loadMeta(meta); - if (count % 40 === 0) { - count++; - return false; - } - count++; - } - }); - - /* - load additional events on scroll - */ - $(window).scroll(function () { - if ($(window).scrollTop() === $(document).height() - $(window).height() || $(document).height() === $(window).height()) { - while (count % 40 !== 0 && count < clientInfo.Meta.length) { - loadMeta(clientInfo.Meta[count - 1]); - count++; - } - count++; - } - }); - - /* - load meta thats not an event - */ - $.each(clientInfo.Meta, function (index, meta) { - if (!meta.key.includes("Event")) { - let metaString = `
${meta.value} ${meta.key}
`; - - // todo: fix the view so we don't have the 3 hardcoded meta - if (metaIndex % 3 == 0 && metaIndex < 7) { - metaIndex++; - } - let selector = '#profile_meta_' + (metaIndex % 3); - $(selector).append(metaString); - - metaIndex++; - } - }); - /* * load context of chat */ @@ -150,88 +96,3 @@ $(document).ready(function () { }); }); }); - -function penaltyToName(penaltyName) { - switch (penaltyName) { - case "Flag": - return "Flagged"; - case "Warning": - return "Warned"; - case "Report": - return "Reported"; - case "Ban": - return "Banned"; - case "Kick": - return "Kicked"; - case "TempBan": - return "Temp Banned"; - case "Unban": - return "Unbanned"; - } -} - -function shouldIncludePlural(num) { - return num > 1 ? 's' : ''; -} - -let mostRecentDate = 0; -let currentStepAmount = 0; -let lastStep = ''; -// todo: fix -function timeStep(stepDifference) { - let hours = stepDifference / (1000 * 60 * 60); - let days = stepDifference / (1000 * 60 * 60 * 24); - let weeks = stepDifference / (1000 * 60 * 60 * 24 * 7); - - if (Math.round(weeks) > Math.round(currentStepAmount / 24 * 7)) { - currentStepAmount = Math.round(weeks); - return `${currentStepAmount} week${shouldIncludePlural(currentStepAmount)} ago`; - } - - if (Math.round(days) > Math.round(currentStepAmount / 24)) { - currentStepAmount = Math.round(days); - return `${currentStepAmount} day${shouldIncludePlural(currentStepAmount)} ago`; - } - - if (Math.round(hours) > currentStepAmount) { - currentStepAmount = Math.round(hours); - return `${currentStepAmount} hour${shouldIncludePlural(currentStepAmount)} ago`; - } -} - -function loadMeta(meta) { - let eventString = ''; - const metaDate = moment.utc(meta.when).valueOf(); - - if (mostRecentDate === 0) { - mostRecentDate = metaDate; - } - - const step = timeStep(moment.utc().valueOf() - metaDate); - - if (step !== lastStep && step !== undefined && metaDate > 0) { - $('#profile_events').append(' ' + step + ''); - lastStep = step; - } - - // it's a penalty - if (meta.class.includes("Penalty")) { - if (meta.value.punisherId !== clientInfo.clientId) { - const timeRemaining = meta.value.type === 'TempBan' && meta.value.timeRemaining.length > 0 ? - `(${meta.value.timeRemaining})` : - ''; - eventString = `
${penaltyToName(meta.value.type)} by ${meta.value.punisherName} for ${meta.value.offense} ${timeRemaining}
`; - } - else { - eventString = `
${penaltyToName(meta.value.type)} ${meta.value.offenderName} for ${meta.value.offense}
`; - } - } - else if (meta.key.includes("Alias")) { - eventString = `
${meta.value}
`; - } - // it's a message - else if (meta.key.includes("Event")) { - eventString = `
> ${meta.value}
`; - } - $('#profile_events').append(eventString); -}