continue rework of profile
start moving profile info out of javascript into componentview rework meta data to include count and offset
This commit is contained in:
parent
1e2e2218e3
commit
7b8126d57e
@ -388,42 +388,80 @@ namespace IW4MAdmin.Application
|
||||
#endregion
|
||||
|
||||
#region META
|
||||
async Task<List<ProfileMeta>> getLastMap(int clientId)
|
||||
async Task<List<ProfileMeta>> getProfileMeta(int clientId, int offset, int count)
|
||||
{
|
||||
var meta = await _metaService.GetPersistentMeta("LastMapPlayed", new EFClient() { ClientId = clientId });
|
||||
var metaList = new List<ProfileMeta>();
|
||||
|
||||
return meta == null ? new List<ProfileMeta>() : new List<ProfileMeta>()
|
||||
// we don't want to return anything because it means we're trying to retrieve paged meta data
|
||||
if (count > 1)
|
||||
{
|
||||
new ProfileMeta()
|
||||
return metaList;
|
||||
}
|
||||
|
||||
var lastMapMeta = await _metaService.GetPersistentMeta("LastMapPlayed", new EFClient() { ClientId = clientId });
|
||||
|
||||
metaList.Add(new ProfileMeta()
|
||||
{
|
||||
Id = meta.MetaId,
|
||||
Id = lastMapMeta.MetaId,
|
||||
Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_LAST_MAP"],
|
||||
Value = meta.Value,
|
||||
Show = true
|
||||
}
|
||||
Value = lastMapMeta.Value,
|
||||
Show = true,
|
||||
Type = ProfileMeta.MetaType.Information
|
||||
});
|
||||
|
||||
};
|
||||
}
|
||||
var lastServerMeta = await _metaService.GetPersistentMeta("LastServerPlayed", new EFClient() { ClientId = clientId });
|
||||
|
||||
async Task<List<ProfileMeta>> getLastServer(int clientId)
|
||||
metaList.Add(new ProfileMeta()
|
||||
{
|
||||
var meta = await _metaService.GetPersistentMeta("LastServerPlayed", new EFClient() { ClientId = clientId });
|
||||
|
||||
return meta == null ? new List<ProfileMeta>() : new List<ProfileMeta>()
|
||||
{
|
||||
new ProfileMeta()
|
||||
{
|
||||
Id = meta.MetaId,
|
||||
Id = lastServerMeta.MetaId,
|
||||
Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_LAST_SERVER"],
|
||||
Value = meta.Value,
|
||||
Show = true
|
||||
}
|
||||
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(getLastMap);
|
||||
MetaService.AddRuntimeMeta(getLastServer);
|
||||
MetaService.AddRuntimeMeta(getProfileMeta);
|
||||
#endregion
|
||||
|
||||
#region INIT
|
||||
|
@ -124,8 +124,13 @@ namespace IW4MAdmin.Plugins.Stats
|
||||
"/Stats/TopPlayersAsync");
|
||||
|
||||
// meta data info
|
||||
async Task<List<ProfileMeta>> getStats(int clientId)
|
||||
async Task<List<ProfileMeta>> getStats(int clientId, int offset, int count)
|
||||
{
|
||||
if (count > 1)
|
||||
{
|
||||
return new List<ProfileMeta>();
|
||||
}
|
||||
|
||||
IList<EFClientStatistics> 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<List<ProfileMeta>> getAnticheatInfo(int clientId)
|
||||
async Task<List<ProfileMeta>> getAnticheatInfo(int clientId, int offset, int count)
|
||||
{
|
||||
if (count > 1)
|
||||
{
|
||||
return new List<ProfileMeta>();
|
||||
}
|
||||
|
||||
IList<EFClientStatistics> clientStats;
|
||||
|
||||
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||
{
|
||||
clientStats = await ctx.Set<EFClientStatistics>()
|
||||
@ -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<List<ProfileMeta>> getMessages(int clientId)
|
||||
async Task<List<ProfileMeta>> getMessages(int clientId, int offset, int count)
|
||||
{
|
||||
if (count <= 1)
|
||||
{
|
||||
using (var ctx = new DatabaseContext(true))
|
||||
{
|
||||
return new List<ProfileMeta>
|
||||
{
|
||||
new ProfileMeta()
|
||||
{
|
||||
Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_MESSAGES"],
|
||||
Value = await ctx.Set<EFClientMessage>().CountAsync(),
|
||||
Type = ProfileMeta.MetaType.Information
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
List<ProfileMeta> messageMeta;
|
||||
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||
{
|
||||
var messages = ctx.Set<EFClientMessage>().Where(m => m.ClientId == clientId);
|
||||
var messages = ctx.Set<EFClientMessage>().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<string> totalKills(Server server)
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
@ -18,10 +18,10 @@ namespace SharedLibraryCore.Dtos
|
||||
public List<string> 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<ProfileMeta> Meta { get; set; }
|
||||
public bool Online { get; set; }
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ namespace SharedLibraryCore.Services
|
||||
{
|
||||
public class MetaService
|
||||
{
|
||||
private static List<Func<int, Task<List<ProfileMeta>>>> _metaActions = new List<Func<int, Task<List<ProfileMeta>>>>();
|
||||
private static List<Func<int, int, int, Task<List<ProfileMeta>>>> _metaActions = new List<Func<int, int, int, Task<List<ProfileMeta>>>>();
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
/// <param name="metaAction"></param>
|
||||
public static void AddRuntimeMeta(Func<int, Task<List<ProfileMeta>>> metaAction)
|
||||
public static void AddRuntimeMeta(Func<int, int, int, Task<List<ProfileMeta>>> metaAction)
|
||||
{
|
||||
_metaActions.Add(metaAction);
|
||||
}
|
||||
@ -80,14 +80,16 @@ namespace SharedLibraryCore.Services
|
||||
/// retrieves all the runtime meta information for given client idea
|
||||
/// </summary>
|
||||
/// <param name="clientId">id of the client</param>
|
||||
/// <param name="count">number of meta items to retrieve</param>
|
||||
/// <param name="offset">offset from the first item</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<List<ProfileMeta>> GetRuntimeMeta(int clientId)
|
||||
public static async Task<List<ProfileMeta>> GetRuntimeMeta(int clientId, int offset = 0, int count = int.MaxValue)
|
||||
{
|
||||
var meta = new List<ProfileMeta>();
|
||||
|
||||
foreach (var action in _metaActions)
|
||||
{
|
||||
meta.AddRange(await action(clientId));
|
||||
meta.AddRange(await action(clientId, offset, count));
|
||||
}
|
||||
|
||||
return meta;
|
||||
|
@ -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();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -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<ProfileMeta>(),
|
||||
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<IActionResult> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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 =>
|
||||
{
|
||||
|
@ -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))}",
|
||||
|
15
WebfrontCore/ViewComponents/ProfileMetaListViewComponent.cs
Normal file
15
WebfrontCore/ViewComponents/ProfileMetaListViewComponent.cs
Normal file
@ -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<IViewComponentResult> InvokeAsync(int clientId, int count, int offset)
|
||||
{
|
||||
var meta = await MetaService.GetRuntimeMeta(clientId, offset, count);
|
||||
return View("_List", meta);
|
||||
}
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@
|
||||
<div class="row pt-2 pb-2 bg-dark">
|
||||
<div class="col-5">@Html.ActionLink(client.Name, "ProfileAsync", "Client", new { id = client.ClientId })</div>
|
||||
<div class="col-4 level-color-@client.LevelInt">@client.Level</div>
|
||||
<div class="col-3 text-right">@client.LastSeen @loc["WEBFRONT_PENALTY_TEMPLATE_AGO"]</div>
|
||||
@*<div class="col-3 text-right">@client.LastSeen @loc["WEBFRONT_PENALTY_TEMPLATE_AGO"]</div>*@
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
<div id="profile_wrapper" class="pb-3 row d-flex flex-column flex-lg-row">
|
||||
@ -76,27 +79,41 @@
|
||||
</div>
|
||||
|
||||
<div id="profile_info" class="row d-block d-lg-flex flex-row border-bottom border-top pt-2 pb-2">
|
||||
|
||||
<div id="profile_meta_0" class="text-center text-lg-left mr-0 mr-lg-4">
|
||||
<div id="profile_time_played" class="text-muted">
|
||||
@loc["WEBFRONT_PROFILE_PLAYER"] <span class="text-primary">@Model.TimePlayed</span> @loc["GLOBAL_TIME_HOURS"]
|
||||
</div>
|
||||
<div id="profile_first_seen" class="text-muted">
|
||||
@loc["WEBFRONT_PROFILE_FSEEN"] <span class="text-primary">@Model.FirstSeen</span> @loc["WEBFRONT_PENALTY_TEMPLATE_AGO"]
|
||||
</div>
|
||||
<div id="profile_last_seen" class="text-muted">
|
||||
@loc["WEBFRONT_PROFILE_LSEEN"] <span class="text-primary">@Model.LastSeen</span> @loc["WEBFRONT_PENALTY_TEMPLATE_AGO"]
|
||||
@for (int i = 0; i < informationMeta.Count; i += 3)
|
||||
{
|
||||
<div class="profile-meta-entry">
|
||||
<span class="profile-meta-value text-primary">@informationMeta[i].Value</span>
|
||||
<span class="profile-meta-title text-muted"> @informationMeta[i].Key</span>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="text-center text-lg-left mr-0 mr-lg-4" id="profile_meta_1">
|
||||
@for (int i = 1; i < informationMeta.Count; i += 3)
|
||||
{
|
||||
<div class="profile-meta-entry">
|
||||
<span class="profile-meta-value text-primary">@informationMeta[i].Value</span>
|
||||
<span class="profile-meta-title text-muted"> @informationMeta[i].Key</span>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="text-center text-lg-left" id="profile_meta_2">
|
||||
@for (int i = 2; i < informationMeta.Count; i += 3)
|
||||
{
|
||||
<div class="profile-meta-entry">
|
||||
<span class="profile-meta-value text-primary">@informationMeta[i].Value</span>
|
||||
<span class="profile-meta-title text-muted"> @informationMeta[i].Key</span>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row d-md-flex pt-2">
|
||||
<div id="profile_events" class="text-muted text-left ml-sm-0">
|
||||
@await Component.InvokeAsync("ProfileMetaList", new { clientId = Model.ClientId, count = 30, offset = 0 })
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -105,12 +122,9 @@
|
||||
}
|
||||
|
||||
@section scripts {
|
||||
<script>
|
||||
const clientInfo = {};
|
||||
clientInfo.clientId = @Model.ClientId;
|
||||
clientInfo.Meta = @Html.Raw(Json.Serialize(@Model.Meta.Where(m => m.Show)));
|
||||
</script>
|
||||
<environment include="Development">
|
||||
<script type="text/javascript" src="~/js/loader.js"></script>
|
||||
<script type="text/javascript" src="~/js/profile.js"></script>
|
||||
</environment>
|
||||
<script>initLoader('/Client/Meta/@Model.ClientId', '#profile_events', 30);</script>
|
||||
}
|
||||
|
@ -13,9 +13,9 @@
|
||||
</tr>
|
||||
|
||||
<tr class="d-table-row d-md-none bg-dark">
|
||||
<th scope="row" class="bg-primary">@loc["WEBFRONT_PENALTY_TEMPLATE_TYPE"]</th>
|
||||
<td class="penalties-color-@Model.Type.ToLower()">
|
||||
@Model.Type
|
||||
<th scope="row" class="bg-primary">@loc["WEBFRONT_PENALTY_TEMPLATE_PenaltyType"]</th>
|
||||
<td class="penalties-color-@Model.PenaltyType.ToLower()">
|
||||
@Model.PenaltyType
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@ -53,8 +53,8 @@
|
||||
<td>
|
||||
@Html.ActionLink(Model.OffenderName, "ProfileAsync", "Client", new { id = Model.OffenderId }, new { @class = "link-inverse" })
|
||||
</td>
|
||||
<td class="penalties-color-@Model.Type.ToLower()">
|
||||
@Model.Type
|
||||
<td class="penalties-color-@Model.PenaltyType.ToLower()">
|
||||
@Model.PenaltyType
|
||||
</td>
|
||||
<td class="text-light w-50">
|
||||
@Model.Offense
|
||||
|
@ -0,0 +1,20 @@
|
||||
@model List<SharedLibraryCore.Dtos.ProfileMeta>
|
||||
@{Layout = null;}
|
||||
|
||||
<div class="p2 text-white profile-event-timestep">
|
||||
<span class="text-primary">—</span>
|
||||
<span>@SharedLibraryCore.Utilities.GetTimePassed(Model.FirstOrDefault()?.When ?? DateTime.Now, true)</span>
|
||||
</div>
|
||||
|
||||
@foreach (var meta in Model)
|
||||
{
|
||||
@switch (meta.Type)
|
||||
{
|
||||
case SharedLibraryCore.Dtos.ProfileMeta.MetaType.ChatMessage:
|
||||
<div>
|
||||
<span style="color:white;">></span>
|
||||
<span class="client-message text-muted" data-serverid="@meta.Extra" data-when="@meta.When"> @meta.Value</span>
|
||||
</div>
|
||||
break;
|
||||
}
|
||||
}
|
@ -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 = `<div class="profile-meta-entry"><span class="profile-meta-value text-primary">${meta.value}</span><span class="profile-meta-title text-muted"> ${meta.key}</span></div>`;
|
||||
|
||||
// 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('<span class="p2 text-white profile-event-timestep"><span class="text-primary">—</span> ' + step + '</span>');
|
||||
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 = `<div><span class="penalties-color-${meta.value.type.toLowerCase()}">${penaltyToName(meta.value.type)}</span> by <span class="text-highlight"> <a class="link-inverse" href="${meta.value.punisherId}">${meta.value.punisherName}</a></span > for <span style="color: white; " class="automated-penalty-info-detailed" data-clientid="${meta.value.offenderId}">${meta.value.offense}</span><span class="text-muted"> ${timeRemaining}</span></div>`;
|
||||
}
|
||||
else {
|
||||
eventString = `<div><span class="penalties-color-${meta.value.type.toLowerCase()}">${penaltyToName(meta.value.type)} </span> <span class="text-highlight"><a class="link-inverse" href="${meta.value.offenderId}"> ${meta.value.offenderName}</a></span > for <span style="color: white;" class="automated-penalty-info-detailed" data-clientid="${meta.value.offenderId}">${meta.value.offense}</span></div>`;
|
||||
}
|
||||
}
|
||||
else if (meta.key.includes("Alias")) {
|
||||
eventString = `<div><span class="text-success">${meta.value}</span></div>`;
|
||||
}
|
||||
// it's a message
|
||||
else if (meta.key.includes("Event")) {
|
||||
eventString = `<div><span style="color:white;">></span><span class="client-message text-muted" data-serverid="${meta.extra}" data-when="${meta.when}"> ${meta.value}</span></div>`;
|
||||
}
|
||||
$('#profile_events').append(eventString);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user