refine webfront pages
finish refactor of penalty information/profile optimize pull penalty query start impl of quick message mapping
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SharedLibraryCore;
|
||||
using System;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
@ -24,10 +25,14 @@ namespace WebfrontCore.Controllers
|
||||
|
||||
try
|
||||
{
|
||||
#if DEBUG == true
|
||||
var client = Utilities.IW4MAdminClient();
|
||||
bool loginSuccess = true;
|
||||
#else
|
||||
var client = Manager.GetPrivilegedClients()[clientId];
|
||||
|
||||
bool loginSuccess = Manager.TokenAuthenticator.AuthorizeToken(client.NetworkId, password) ||
|
||||
(await Task.FromResult(SharedLibraryCore.Helpers.Hashing.Hash(password, client.PasswordSalt)))[0] == client.Password;
|
||||
#endif
|
||||
|
||||
if (loginSuccess)
|
||||
{
|
||||
|
@ -119,7 +119,7 @@ namespace WebfrontCore.Controllers
|
||||
Name = c.Name,
|
||||
Level = c.Level.ToLocalizedLevelName(),
|
||||
LevelInt = (int)c.Level,
|
||||
// todo: add back last seen for search
|
||||
LastConnection = c.LastConnection,
|
||||
ClientId = c.ClientId
|
||||
})
|
||||
.ToList();
|
||||
|
@ -10,12 +10,13 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using WebfrontCore.ViewComponents;
|
||||
using static SharedLibraryCore.Objects.Penalty;
|
||||
|
||||
namespace WebfrontCore.Controllers
|
||||
{
|
||||
public class PenaltyController : BaseController
|
||||
{
|
||||
public IActionResult List(int showOnly = (int)SharedLibraryCore.Objects.Penalty.PenaltyType.Any)
|
||||
public IActionResult List(PenaltyType showOnly = PenaltyType.Any)
|
||||
{
|
||||
ViewBag.Description = "List of all the recent penalties (bans, kicks, warnings) on IW4MAdmin";
|
||||
ViewBag.Title = Localization["WEBFRONT_PENALTY_TITLE"];
|
||||
@ -24,12 +25,12 @@ namespace WebfrontCore.Controllers
|
||||
return View((SharedLibraryCore.Objects.Penalty.PenaltyType)showOnly);
|
||||
}
|
||||
|
||||
public async Task<IActionResult> ListAsync(int offset = 0, int showOnly = (int)SharedLibraryCore.Objects.Penalty.PenaltyType.Any)
|
||||
public async Task<IActionResult> ListAsync(int offset = 0, PenaltyType showOnly = PenaltyType.Any)
|
||||
{
|
||||
return await Task.FromResult(View("_List", new ViewModels.PenaltyFilterInfo()
|
||||
{
|
||||
Offset = offset,
|
||||
ShowOnly = (SharedLibraryCore.Objects.Penalty.PenaltyType)showOnly
|
||||
ShowOnly = showOnly
|
||||
}));
|
||||
}
|
||||
|
||||
@ -47,7 +48,7 @@ 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)
|
||||
.Where(p => p.Type == PenaltyType.Ban && p.Active)
|
||||
.OrderByDescending(_penalty => _penalty.When)
|
||||
.Select(p => new PenaltyInfo()
|
||||
{
|
||||
@ -61,9 +62,7 @@ namespace WebfrontCore.Controllers
|
||||
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 = null,
|
||||
TimePunished = p.When,
|
||||
AutomatedOffense = Authorized ? p.AutomatedOffense : null,
|
||||
});
|
||||
#if DEBUG == true
|
||||
|
@ -1,9 +1,5 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Dtos;
|
||||
using SharedLibraryCore.Objects;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -11,42 +7,14 @@ namespace WebfrontCore.ViewComponents
|
||||
{
|
||||
public class PenaltyListViewComponent : ViewComponent
|
||||
{
|
||||
private const int PENALTY_COUNT = 15;
|
||||
|
||||
public async Task<IViewComponentResult> InvokeAsync(int offset, Penalty.PenaltyType showOnly)
|
||||
{
|
||||
string showEvadeString(EFPenalty penalty) => penalty.IsEvadedOffense == true ?
|
||||
$"({Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PENALTY_EVADE"]}) " : "";
|
||||
var penalties = await Program.Manager.GetPenaltyService().GetRecentPenalties(PENALTY_COUNT, offset, showOnly);
|
||||
penalties = User.Identity.IsAuthenticated ? penalties : penalties.Where(p => !p.Sensitive).ToList();
|
||||
|
||||
var penalties = await Program.Manager.GetPenaltyService().GetRecentPenalties(12, offset, showOnly);
|
||||
var penaltiesDto = penalties.Select(p => new PenaltyInfo()
|
||||
{
|
||||
Id = p.PenaltyId,
|
||||
OffenderId = p.OffenderId,
|
||||
OffenderName = p.Offender.Name,
|
||||
PunisherId = p.PunisherId,
|
||||
PunisherName = p.Punisher.Name,
|
||||
PunisherLevel = p.Punisher.Level.ToLocalizedLevelName(),
|
||||
PunisherLevelId = (int)p.Punisher.Level,
|
||||
#if DEBUG
|
||||
Offense = !string.IsNullOrEmpty(p.AutomatedOffense) ? p.AutomatedOffense : p.Offense,
|
||||
#else
|
||||
Offense = (User.Identity.IsAuthenticated && !string.IsNullOrEmpty(p.AutomatedOffense)) ?
|
||||
$"{showEvadeString(p)}{p.AutomatedOffense}" :
|
||||
$"{showEvadeString(p)}{p.Offense}",
|
||||
#endif
|
||||
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))}",
|
||||
Sensitive = p.Type == Penalty.PenaltyType.Flag,
|
||||
AutomatedOffense = p.AutomatedOffense
|
||||
});
|
||||
|
||||
#if DEBUG
|
||||
penaltiesDto = penaltiesDto.ToList();
|
||||
#else
|
||||
penaltiesDto = User.Identity.IsAuthenticated ? penaltiesDto.ToList() : penaltiesDto.Where(p => !p.Sensitive).ToList();
|
||||
#endif
|
||||
return View("_List", penaltiesDto);
|
||||
return View("_List", penalties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,40 @@
|
||||
@model List<SharedLibraryCore.Dtos.PlayerInfo>
|
||||
@{
|
||||
@{
|
||||
var loc = SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex;
|
||||
}
|
||||
|
||||
<div class="mr-auto ml-auto col-12 col-lg-7 border-bottom">
|
||||
<h4 class="pb-2 text-center ">@ViewBag.Title</h4>
|
||||
<div class="row pt-2 pb-2 bg-primary">
|
||||
<div class="col-5 ">@loc["WEBFRONT_PENALTY_TEMPLATE_NAME"]</div>
|
||||
<div class="col-4">@loc["WEBFRONT_PROFILE_LEVEL"]</div>
|
||||
<div class="col-3 text-right">@loc["WEBFRONT_PROFILE_LSEEN"]</div>
|
||||
</div>
|
||||
<div class="row d-none d-lg-block ">
|
||||
<h4 class="pb-2 text-center col-12">@ViewBag.Title</h4>
|
||||
<div class="mr-auto ml-auto col-12 col-lg-8 border-bottom">
|
||||
<div class="row pt-2 pb-2 bg-primary">
|
||||
<div class="col-5 ">@loc["WEBFRONT_PENALTY_TEMPLATE_NAME"]</div>
|
||||
<div class="col-4">@loc["WEBFRONT_PROFILE_LEVEL"]</div>
|
||||
<div class="col-3 text-right">@loc["WEBFRONT_SEARCH_LAST_CONNECTED"]</div>
|
||||
</div>
|
||||
|
||||
@{
|
||||
foreach (var client in Model)
|
||||
@foreach (var client in Model)
|
||||
{
|
||||
<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.LastConnectionText</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row d-lg-none">
|
||||
<div class="w-100 bg-primary text-center h3 mb-0 p-3" style="border-bottom: 1px solid #222">@ViewBag.Title</div>
|
||||
@foreach (var client in Model)
|
||||
{
|
||||
<div class="col-5 bg-primary font-weight-bold" style="border-bottom: 1px solid #222">
|
||||
<div class="p-2">@loc["WEBFRONT_PENALTY_TEMPLATE_NAME"]</div>
|
||||
<div class="p-2">@loc["WEBFRONT_PROFILE_LEVEL"]</div>
|
||||
<div class="p-2">@loc["WEBFRONT_SEARCH_LAST_CONNECTED"]</div>
|
||||
</div>
|
||||
<div class="col-7 bg-dark border-bottom">
|
||||
<div class="p-2">@Html.ActionLink(client.Name, "ProfileAsync", "Client", new { id = client.ClientId },new { @class = "link-inverse" } )</div>
|
||||
<div class="p-2 level-color-@client.LevelInt">@client.Level</div>
|
||||
<div class="p-2 text-white-50">@client.LastConnectionText</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
@ -1,12 +0,0 @@
|
||||
@model IEnumerable<SharedLibraryCore.Dtos.ChatInfo>
|
||||
@{
|
||||
Layout = null;
|
||||
}
|
||||
|
||||
<div class="client-message-context bg-dark p-2 mt-2 mb-2 border-top border-bottom">
|
||||
<h5>@Model.First().Time.ToString()</h5>
|
||||
@foreach (var message in Model)
|
||||
{
|
||||
<span class="text-white">@message.Name</span><span> — @message.Message</span><br />
|
||||
}
|
||||
</div>
|
@ -2,7 +2,7 @@
|
||||
@{
|
||||
var loc = SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex;
|
||||
}
|
||||
<h4 class="pb-3 text-center ">@ViewBag.Title</h4>
|
||||
<h4 class="pb-3 text-center">@ViewBag.Title</h4>
|
||||
<div class="row">
|
||||
<select class="form-control bg-dark text-muted" id="penalty_filter_selection">
|
||||
@{
|
||||
@ -36,7 +36,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<table class="table table-striped">
|
||||
<thead class="d-none d-md-table-header-group">
|
||||
<thead class="d-none d-lg-table-header-group">
|
||||
<tr class="bg-primary pt-2 pb-2">
|
||||
<th scope="col">@loc["WEBFRONT_PENALTY_TEMPLATE_NAME"]</th>
|
||||
<th scope="col">@loc["WEBFRONT_PENALTY_TEMPLATE_TYPE"]</th>
|
||||
@ -53,10 +53,10 @@
|
||||
})
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="table d-table d-md-none">
|
||||
<table class="table d-table d-lg-none">
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
<span id="load_penalties_button" class="oi oi-chevron-bottom text-center text-primary w-100 h3 pb-0 mb-0 d-none d-md-block"></span>
|
||||
<span id="load_penalties_button" class="oi oi-chevron-bottom text-center text-primary w-100 h3 pb-0 mb-0 d-none d-lg-block"></span>
|
||||
</div>
|
||||
|
||||
@section scripts {
|
||||
|
@ -5,72 +5,72 @@
|
||||
|
||||
@model SharedLibraryCore.Dtos.PenaltyInfo
|
||||
|
||||
<tr class="d-table-row d-md-none bg-dark">
|
||||
<tr class="d-table-row d-lg-none bg-dark">
|
||||
<th scope="row" class="bg-primary">@loc["WEBFRONT_PENALTY_TEMPLATE_NAME"]</th>
|
||||
<td>
|
||||
@Html.ActionLink(Model.OffenderName, "ProfileAsync", "Client", new { id = Model.OffenderId }, new { @class = "link-inverse" })
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="d-table-row d-md-none bg-dark">
|
||||
<tr class="d-table-row d-lg-none bg-dark">
|
||||
<th scope="row" class="bg-primary">@loc["WEBFRONT_PENALTY_TEMPLATE_TYPE"]</th>
|
||||
<td class="penalties-color-@Model.PenaltyType.ToLower()">
|
||||
<td class="penalties-color-@Model.PenaltyTypeText.ToLower()">
|
||||
@Model.PenaltyType
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="d-table-row d-md-none bg-dark">
|
||||
<tr class="d-table-row d-lg-none bg-dark">
|
||||
<th scope="row" class="bg-primary">@loc["WEBFRONT_PENALTY_TEMPLATE_OFFENSE"]</th>
|
||||
<td class="text-light">
|
||||
@Model.Offense
|
||||
@($"{Model.Offense}{(ViewBag.Authorized ? Model.AdditionalPenaltyInformation : "")}")
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="d-table-row d-md-none bg-dark">
|
||||
<tr class="d-table-row d-lg-none bg-dark">
|
||||
<th scope="row" class="bg-primary">@loc["WEBFRONT_PENALTY_TEMPLATE_ADMIN"]</th>
|
||||
<td>
|
||||
@Html.ActionLink(Model.PunisherName, "ProfileAsync", "Client", new { id = Model.PunisherId }, new { @class = "level-color-" + Model.PunisherLevelId })
|
||||
@Html.ActionLink(Model.PunisherName, "ProfileAsync", "Client", new { id = Model.PunisherId }, new { @class = "level-color-" + (int)Model.PunisherLevel })
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="d-table-row d-md-none bg-dark">
|
||||
<tr class="d-table-row d-lg-none bg-dark">
|
||||
<th scope="row" class="w-25 bg-primary" style="border-bottom: 1px solid #222">@loc["WEBFRONT_PENALTY_TEMPLATE_TIME"]</th>
|
||||
<td class="text-light mb-2 border-bottom">
|
||||
@{
|
||||
if (Model.TimeRemaining == string.Empty)
|
||||
if (Model.Expired)
|
||||
{
|
||||
<span>@Model.TimePunished @loc["WEBFRONT_PENALTY_TEMPLATE_AGO"]</span>
|
||||
<span>@Model.TimePunishedString</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span> @Model.TimeRemaining</span>
|
||||
<span>@Model.TimeRemaining</span>
|
||||
}
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="d-none d-md-table-row">
|
||||
<tr class="d-none d-lg-table-row">
|
||||
<td>
|
||||
@Html.ActionLink(Model.OffenderName, "ProfileAsync", "Client", new { id = Model.OffenderId }, new { @class = "link-inverse" })
|
||||
</td>
|
||||
<td class="penalties-color-@Model.PenaltyType.ToLower()">
|
||||
<td class="penalties-color-@Model.PenaltyTypeText.ToLower()">
|
||||
@Model.PenaltyType
|
||||
</td>
|
||||
<td class="text-light w-50">
|
||||
@Model.Offense
|
||||
@($"{Model.Offense}{(ViewBag.Authorized ? Model.AdditionalPenaltyInformation : "")}")
|
||||
</td>
|
||||
<td>
|
||||
@Html.ActionLink(Model.PunisherName, "ProfileAsync", "Client", new { id = Model.PunisherId }, new { @class = "level-color-" + Model.PunisherLevelId })
|
||||
@Html.ActionLink(Model.PunisherName, "ProfileAsync", "Client", new { id = Model.PunisherId }, new { @class = "level-color-" + (int)Model.PunisherLevel })
|
||||
</td>
|
||||
<td class="text-right text-light">
|
||||
@{
|
||||
if (Model.TimeRemaining == string.Empty)
|
||||
if (Model.Expired)
|
||||
{
|
||||
<span>@Model.TimePunished @loc["WEBFRONT_PENALTY_TEMPLATE_AGO"]</span>
|
||||
<span>@Model.TimePunishedString</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span> @Model.TimeRemaining </span>
|
||||
<span>@Model.TimeRemaining</span>
|
||||
}
|
||||
}
|
||||
</td>
|
||||
|
@ -9,24 +9,24 @@
|
||||
var penalty = meta.Value as SharedLibraryCore.Dtos.PenaltyInfo;
|
||||
|
||||
string localizationKey = meta.Type == SharedLibraryCore.Dtos.ProfileMeta.MetaType.Penalized ?
|
||||
$"WEBFRONT_CLIENT_META_PENALIZED_{penalty.PenaltyType.ToUpper()}" :
|
||||
$"WEBFRONT_CLIENT_META_WAS_PENALIZED_{penalty.PenaltyType.ToUpper()}";
|
||||
$"WEBFRONT_CLIENT_META_PENALIZED_{penalty.PenaltyTypeText.ToUpper()}" :
|
||||
$"WEBFRONT_CLIENT_META_WAS_PENALIZED_{penalty.PenaltyTypeText.ToUpper()}";
|
||||
|
||||
string localizationMessage = SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex[localizationKey];
|
||||
var regexMatch = System.Text.RegularExpressions.Regex.Match(localizationMessage, @"^.*{{([^{}]+)}}.+$");
|
||||
string penaltyType = regexMatch.Groups[1].Value.ToString();
|
||||
|
||||
localizationMessage = localizationMessage.Replace(penaltyType, $"<span class='penalties-color-{penalty.PenaltyType.ToLower()}'>{penaltyType}</span>");
|
||||
localizationMessage = localizationMessage.Replace(penaltyType, $"<span class='penalties-color-{penalty.PenaltyTypeText.ToLower()}'>{penaltyType}</span>");
|
||||
|
||||
return meta.Type == SharedLibraryCore.Dtos.ProfileMeta.MetaType.Penalized ?
|
||||
string.Format(localizationMessage,
|
||||
$"<span class='text-highlight'><a class='link-inverse' href='{penalty.OffenderId}'>{penalty.OffenderName}</a></span>",
|
||||
$"<span class='automated-penalty-info-detailed text-white' data-clientid='{penalty.OffenderId}'>{penalty.Offense}</span>")
|
||||
$"<span class='{(ViewBag.Authorized ? "automated-penalty-info-detailed" : "")} text-white' data-clientid='{penalty.OffenderId}'>{penalty.Offense} {(ViewBag.Authorized ? penalty.AdditionalPenaltyInformation : "")}</span>")
|
||||
.Replace("{", "")
|
||||
.Replace("}", "") :
|
||||
string.Format(localizationMessage,
|
||||
$"<span class='text-highlight'><a class='link-inverse' href='{penalty.PunisherId}'>{penalty.PunisherName}</a></span>",
|
||||
$"<span class='automated-penalty-info-detailed text-white' data-clientid='{penalty.OffenderId}'>{(ViewBag.Authorized && !string.IsNullOrEmpty(penalty.AutomatedOffense) ? $"{penalty.Offense} ({penalty.AutomatedOffense})" : penalty.Offense)}</span>",
|
||||
$"<span class='{(ViewBag.Authorized ? "automated-penalty-info-detailed" : "")} text-white' data-clientid='{penalty.OffenderId}'>{penalty.Offense} {(ViewBag.Authorized ? penalty.AdditionalPenaltyInformation : "")}</span>",
|
||||
penalty.Offense)
|
||||
.Replace("{", "")
|
||||
.Replace("}", "");
|
||||
@ -55,7 +55,7 @@
|
||||
case SharedLibraryCore.Dtos.ProfileMeta.MetaType.ChatMessage:
|
||||
<div class="profile-meta-entry loader-data-time" data-time="@meta.When">
|
||||
<span style="color:white;">></span>
|
||||
<span class="client-message text-muted" data-serverid="@meta.Extra" data-when="@meta.When"> @meta.Value</span>
|
||||
<span class="client-message text-muted" data-serverid="@meta.Extra" data-when="@meta.When" title="@SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_MESSAGE_CONTEXT"]"> @meta.Value</span>
|
||||
</div>
|
||||
break;
|
||||
case SharedLibraryCore.Dtos.ProfileMeta.MetaType.ReceivedPenalty:
|
||||
|
@ -6318,6 +6318,10 @@ a.link-inverse:hover {
|
||||
.d-md-table-header-group {
|
||||
display: table-header-group !important; } }
|
||||
|
||||
@media (min-width: 992px) {
|
||||
.d-lg-table-header-group {
|
||||
display: table-header-group !important; } }
|
||||
|
||||
#console_command_response {
|
||||
min-height: 20rem; }
|
||||
|
||||
|
@ -88,7 +88,13 @@ a.link-inverse:hover {
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.d-md-table-header-group {
|
||||
display: table-header-group !important
|
||||
display: table-header-group !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
.d-lg-table-header-group {
|
||||
display: table-header-group !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user