huge commit for webfront facelift

This commit is contained in:
RaidMax
2022-04-19 18:43:58 -05:00
parent 4023ca37d4
commit 4fbe0ee0ed
105 changed files with 2981 additions and 2545 deletions

View File

@ -80,7 +80,7 @@ namespace WebfrontCore.Controllers.API
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> LoginAsync([FromRoute] int clientId,
public async Task<IActionResult> Login([FromRoute] int clientId,
[FromBody, Required] PasswordRequest request)
{
if (clientId == 0)
@ -145,7 +145,7 @@ namespace WebfrontCore.Controllers.API
[HttpPost("{clientId:int}/logout")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> LogoutAsync()
public async Task<IActionResult> Logout()
{
if (Authorized)
{
@ -170,4 +170,4 @@ namespace WebfrontCore.Controllers.API
public string Password { get; set; }
}
}
}
}

View File

@ -19,11 +19,11 @@ namespace WebfrontCore.Controllers
}
[HttpGet]
public async Task<IActionResult> LoginAsync(int clientId, string password)
public async Task<IActionResult> Login(int clientId, string password)
{
if (clientId == 0 || string.IsNullOrEmpty(password))
{
return Unauthorized();
return Unauthorized("Invalid credentials");
}
try
@ -63,20 +63,20 @@ namespace WebfrontCore.Controllers
: HttpContext.Connection.RemoteIpAddress.ToString()
});
return Ok();
return Ok($"Welcome {privilegedClient.Name}. You are now logged in");
}
}
catch (Exception)
{
return Unauthorized();
return Unauthorized("Could not validate credentials");
}
return Unauthorized();
return Unauthorized("Invalid credentials");
}
[HttpGet]
public async Task<IActionResult> LogoutAsync()
public async Task<IActionResult> Logout()
{
if (Authorized)
{

View File

@ -69,25 +69,25 @@ namespace WebfrontCore.Controllers
public IActionResult BanForm()
{
var info = new ActionInfo()
var info = new ActionInfo
{
ActionButtonLabel = Localization["WEBFRONT_ACTION_BAN_NAME"],
Name = "Ban",
Inputs = new List<InputInfo>()
Inputs = new List<InputInfo>
{
new InputInfo()
new()
{
Name = "Reason",
Label = Localization["WEBFRONT_ACTION_LABEL_REASON"],
},
new InputInfo()
new()
{
Name = "PresetReason",
Type = "select",
Label = Localization["WEBFRONT_ACTION_LABEL_PRESET_REASON"],
Values = GetPresetPenaltyReasons()
},
new InputInfo()
new()
{
Name = "Duration",
Label = Localization["WEBFRONT_ACTION_LABEL_DURATION"],
@ -134,7 +134,7 @@ namespace WebfrontCore.Controllers
var server = Manager.GetServers().First();
return await Task.FromResult(RedirectToAction("ExecuteAsync", "Console", new
return await Task.FromResult(RedirectToAction("Execute", "Console", new
{
serverId = server.EndPoint,
command
@ -143,13 +143,13 @@ namespace WebfrontCore.Controllers
public IActionResult UnbanForm()
{
var info = new ActionInfo()
var info = new ActionInfo
{
ActionButtonLabel = Localization["WEBFRONT_ACTION_UNBAN_NAME"],
Name = "Unban",
Inputs = new List<InputInfo>()
Inputs = new List<InputInfo>
{
new InputInfo()
new()
{
Name = "Reason",
Label = Localization["WEBFRONT_ACTION_LABEL_REASON"],
@ -162,57 +162,59 @@ namespace WebfrontCore.Controllers
return View("_ActionForm", info);
}
public async Task<IActionResult> UnbanAsync(int targetId, string Reason)
public async Task<IActionResult> UnbanAsync(int targetId, string reason)
{
var server = Manager.GetServers().First();
return await Task.FromResult(RedirectToAction("ExecuteAsync", "Console", new
return await Task.FromResult(RedirectToAction("Execute", "Console", new
{
serverId = server.EndPoint,
command = $"{_appConfig.CommandPrefix}{_unbanCommandName} @{targetId} {Reason}"
command = $"{_appConfig.CommandPrefix}{_unbanCommandName} @{targetId} {reason}"
}));
}
public IActionResult LoginForm()
{
var login = new ActionInfo()
var login = new ActionInfo
{
ActionButtonLabel = Localization["WEBFRONT_ACTION_LOGIN_NAME"],
Name = "Login",
Inputs = new List<InputInfo>()
Inputs = new List<InputInfo>
{
new InputInfo()
new()
{
Name = "clientId",
Label = Localization["WEBFRONT_ACTION_LABEL_ID"]
Label = Localization["WEBFRONT_ACTION_LABEL_ID"],
Required = true
},
new InputInfo()
new()
{
Name = "Password",
Label = Localization["WEBFRONT_ACTION_LABEL_PASSWORD"],
Type = "password",
Required = true
}
},
Action = "LoginAsync"
Action = "Login"
};
return View("_ActionForm", login);
}
public async Task<IActionResult> LoginAsync(int clientId, string password)
public async Task<IActionResult> Login(int clientId, string password)
{
return await Task.FromResult(RedirectToAction("LoginAsync", "Account", new {clientId, password}));
return await Task.FromResult(RedirectToAction("Login", "Account", new {clientId, password}));
}
public IActionResult EditForm()
{
var info = new ActionInfo()
var info = new ActionInfo
{
ActionButtonLabel = Localization["WEBFRONT_ACTION_LABEL_EDIT"],
Name = "Edit",
Inputs = new List<InputInfo>()
Inputs = new List<InputInfo>
{
new InputInfo()
new()
{
Name = "level",
Label = Localization["WEBFRONT_PROFILE_LEVEL"],
@ -235,7 +237,7 @@ namespace WebfrontCore.Controllers
{
var server = Manager.GetServers().First();
return await Task.FromResult(RedirectToAction("ExecuteAsync", "Console", new
return await Task.FromResult(RedirectToAction("Execute", "Console", new
{
serverId = server.EndPoint,
command = $"{_appConfig.CommandPrefix}{_setLevelCommandName} @{targetId} {level}"
@ -244,7 +246,7 @@ namespace WebfrontCore.Controllers
public IActionResult GenerateLoginTokenForm()
{
var info = new ActionInfo()
var info = new ActionInfo
{
ActionButtonLabel = Localization["WEBFRONT_ACTION_LABEL_GENERATE_TOKEN"],
Name = "GenerateLoginToken",
@ -267,19 +269,19 @@ namespace WebfrontCore.Controllers
public IActionResult ChatForm(long id)
{
var info = new ActionInfo()
var info = new ActionInfo
{
ActionButtonLabel = Localization["WEBFRONT_ACTION_LABEL_SUBMIT_MESSAGE"],
Name = "Chat",
Inputs = new List<InputInfo>
{
new InputInfo()
new()
{
Name = "message",
Type = "text",
Label = Localization["WEBFRONT_ACTION_LABEL_MESSAGE"]
},
new InputInfo()
new()
{
Name = "id",
Value = id.ToString(),
@ -294,7 +296,7 @@ namespace WebfrontCore.Controllers
public async Task<IActionResult> ChatAsync(long id, string message)
{
var server = Manager.GetServers().First(_server => _server.EndPoint == id);
var server = Manager.GetServers().First(server => server.EndPoint == id);
server.ChatHistory.Add(new SharedLibraryCore.Dtos.ChatInfo()
{
@ -305,7 +307,7 @@ namespace WebfrontCore.Controllers
Time = DateTime.Now
});
return await Task.FromResult(RedirectToAction("ExecuteAsync", "Console", new
return await Task.FromResult(RedirectToAction("Execute", "Console", new
{
serverId = server.EndPoint,
command = $"{_appConfig.CommandPrefix}{_sayCommandName} {message}"
@ -318,7 +320,7 @@ namespace WebfrontCore.Controllers
foreach (var client in clients)
{
client.IPAddress =
_appConfig.HasPermission(Client.Level, WebfrontEntity.IPAddress, WebfrontPermission.Read)
_appConfig.HasPermission(Client.Level, WebfrontEntity.ClientIPAddress, WebfrontPermission.Read)
? client.IPAddress
: null;
}
@ -328,18 +330,18 @@ namespace WebfrontCore.Controllers
public IActionResult FlagForm()
{
var info = new ActionInfo()
var info = new ActionInfo
{
ActionButtonLabel = Localization["WEBFRONT_ACTION_FLAG_NAME"],
Name = "Flag",
Inputs = new List<InputInfo>()
Inputs = new List<InputInfo>
{
new InputInfo()
new()
{
Name = "reason",
Label = Localization["WEBFRONT_ACTION_LABEL_REASON"],
},
new InputInfo()
new()
{
Name = "PresetReason",
Type = "select",
@ -358,7 +360,7 @@ namespace WebfrontCore.Controllers
{
var server = Manager.GetServers().First();
return await Task.FromResult(RedirectToAction("ExecuteAsync", "Console", new
return await Task.FromResult(RedirectToAction("Execute", "Console", new
{
serverId = server.EndPoint,
command = $"{_appConfig.CommandPrefix}{_flagCommandName} @{targetId} {presetReason ?? reason}"
@ -367,13 +369,13 @@ namespace WebfrontCore.Controllers
public IActionResult UnflagForm()
{
var info = new ActionInfo()
var info = new ActionInfo
{
ActionButtonLabel = Localization["WEBFRONT_ACTION_UNFLAG_NAME"],
Name = "Unflag",
Inputs = new List<InputInfo>()
Inputs = new List<InputInfo>
{
new InputInfo()
new()
{
Name = "reason",
Label = Localization["WEBFRONT_ACTION_LABEL_REASON"],
@ -390,7 +392,7 @@ namespace WebfrontCore.Controllers
{
var server = Manager.GetServers().First();
return await Task.FromResult(RedirectToAction("ExecuteAsync", "Console", new
return await Task.FromResult(RedirectToAction("Execute", "Console", new
{
serverId = server.EndPoint,
command = $"{_appConfig.CommandPrefix}{_unflagCommandName} @{targetId} {reason}"
@ -399,25 +401,25 @@ namespace WebfrontCore.Controllers
public IActionResult KickForm(int id)
{
var info = new ActionInfo()
var info = new ActionInfo
{
ActionButtonLabel = Localization["WEBFRONT_ACTION_KICK_NAME"],
Name = "Kick",
Inputs = new List<InputInfo>()
Inputs = new List<InputInfo>
{
new InputInfo()
new()
{
Name = "reason",
Label = Localization["WEBFRONT_ACTION_LABEL_REASON"],
},
new InputInfo()
new()
{
Name = "PresetReason",
Type = "select",
Label = Localization["WEBFRONT_ACTION_LABEL_PRESET_REASON"],
Values = GetPresetPenaltyReasons()
},
new InputInfo()
new()
{
Name = "targetId",
Type = "hidden",
@ -433,14 +435,14 @@ namespace WebfrontCore.Controllers
public async Task<IActionResult> KickAsync(int targetId, string reason, string presetReason = null)
{
var client = Manager.GetActiveClients().FirstOrDefault(_client => _client.ClientId == targetId);
var client = Manager.GetActiveClients().FirstOrDefault(client => client.ClientId == targetId);
if (client == null)
{
return BadRequest(Localization["WEBFRONT_ACTION_KICK_DISCONNECT"]);
}
return await Task.FromResult(RedirectToAction("ExecuteAsync", "Console", new
return await Task.FromResult(RedirectToAction("Execute", "Console", new
{
serverId = client.CurrentServer.EndPoint,
command = $"{_appConfig.CommandPrefix}{_kickCommandName} {client.ClientNumber} {presetReason ?? reason}"
@ -449,9 +451,9 @@ namespace WebfrontCore.Controllers
private Dictionary<string, string> GetPresetPenaltyReasons() => _appConfig.PresetPenaltyReasons.Values
.Concat(_appConfig.GlobalRules)
.Concat(_appConfig.Servers.SelectMany(server => server.Rules ?? new string[0]))
.Concat(_appConfig.Servers.SelectMany(server => server.Rules ?? Array.Empty<string>()))
.Distinct()
.Select((value, index) => new
.Select((value, _) => new
{
Value = value
})

View File

@ -22,14 +22,22 @@ namespace WebfrontCore.Controllers
{
private readonly IMetaServiceV2 _metaService;
private readonly StatsConfiguration _config;
private readonly IGeoLocationService _geoLocationService;
public ClientController(IManager manager, IMetaServiceV2 metaService, StatsConfiguration config) : base(manager)
public ClientController(IManager manager, IMetaServiceV2 metaService, StatsConfiguration config,
IGeoLocationService geoLocationService) : base(manager)
{
_metaService = metaService;
_config = config;
_geoLocationService = geoLocationService;
}
public async Task<IActionResult> ProfileAsync(int id, MetaType? metaFilterType, CancellationToken token = default)
[Obsolete]
public IActionResult ProfileAsync(int id, MetaType? metaFilterType,
CancellationToken token = default) => RedirectToAction("Profile", "Client", new
{ id, metaFilterType, token });
public async Task<IActionResult> Profile(int id, MetaType? metaFilterType, CancellationToken token = default)
{
var client = await Manager.GetClientService().Get(id);
@ -43,7 +51,8 @@ namespace WebfrontCore.Controllers
var persistentMetaTask = new[]
{
_metaService.GetPersistentMetaByLookup(EFMeta.ClientTagV2, EFMeta.ClientTagNameV2, client.ClientId, token),
_metaService.GetPersistentMetaByLookup(EFMeta.ClientTagV2, EFMeta.ClientTagNameV2, client.ClientId,
token),
_metaService.GetPersistentMeta("GravatarEmail", client.ClientId, token)
};
@ -74,6 +83,7 @@ namespace WebfrontCore.Controllers
}
displayLevel = string.IsNullOrEmpty(client.Tag) ? displayLevel : $"{displayLevel} ({client.Tag})";
var ingameClient = Manager.GetActiveClients().FirstOrDefault(c => c.ClientId == client.ClientId);
var clientDto = new PlayerInfo
{
@ -81,29 +91,38 @@ namespace WebfrontCore.Controllers
Level = displayLevel,
LevelInt = displayLevelInt,
ClientId = client.ClientId,
IPAddress = PermissionsSet.HasPermission(WebfrontEntity.IPAddress, WebfrontPermission.Read) ? client.IPAddressString : null,
IPAddress = PermissionsSet.HasPermission(WebfrontEntity.ClientIPAddress, WebfrontPermission.Read)
? client.IPAddressString
: null,
NetworkId = client.NetworkId,
Meta = new List<InformationResponse>(),
Aliases = client.AliasLink.Children
.Select(_alias => _alias.Name)
.GroupBy(_alias => _alias.StripColors())
.Select(alias => (alias.Name, alias.DateAdded))
.GroupBy(alias => alias.Name.StripColors())
// we want the longest "duplicate" name
.Select(_grp => _grp.OrderByDescending(_name => _name.Length).First())
.Select(grp => grp.OrderByDescending(item => item.Name.Length).First())
.Distinct()
.OrderBy(a => a)
.ToList(),
IPs = PermissionsSet.HasPermission(WebfrontEntity.IPAddress, WebfrontPermission.Read) ? client.AliasLink.Children
.Where(i => i.IPAddress != null)
.OrderByDescending(i => i.DateAdded)
.Select(i => i.IPAddress.ConvertIPtoString())
.Prepend(client.CurrentAlias.IPAddress.ConvertIPtoString())
.Distinct()
.ToList() : new List<string>(),
HasActivePenalty = activePenalties.Any(_penalty => _penalty.Type != EFPenalty.PenaltyType.Flag),
Online = Manager.GetActiveClients().FirstOrDefault(c => c.ClientId == client.ClientId) != null,
IPs = PermissionsSet.HasPermission(WebfrontEntity.ClientIPAddress, WebfrontPermission.Read)
? client.AliasLink.Children
.Select(alias => (alias.IPAddress.ConvertIPtoString(), alias.DateAdded))
.GroupBy(alias => alias.Item1)
.Select(grp => grp.OrderByDescending(item => item.DateAdded).First())
.Distinct()
.ToList()
: new List<(string, DateTime)>(),
HasActivePenalty = activePenalties.Any(penalty => penalty.Type != EFPenalty.PenaltyType.Flag),
Online = ingameClient != null,
TimeOnline = (DateTime.UtcNow - client.LastConnection).HumanizeForCurrentCulture(),
LinkedAccounts = client.LinkedAccounts,
MetaFilterType = metaFilterType
MetaFilterType = metaFilterType,
ConnectProtocolUrl = ingameClient?.CurrentServer.EventParser.URLProtocolFormat.FormatExt(
ingameClient.CurrentServer.ResolvedIpEndPoint.Address.IsInternal()
? Program.Manager.ExternalIPAddress
: ingameClient.CurrentServer.IP,
ingameClient.CurrentServer.Port),
CurrentServerName = ingameClient?.CurrentServer?.Hostname,
GeoLocationInfo = await _geoLocationService.Locate(client.IPAddressString)
};
var meta = await _metaService.GetRuntimeMeta<InformationResponse>(new ClientPaginationRequest
@ -126,9 +145,9 @@ namespace WebfrontCore.Controllers
clientDto.Meta.AddRange(Authorized ? meta : meta.Where(m => !m.IsSensitive));
var strippedName = clientDto.Name.StripColors();
ViewBag.Title = strippedName.Substring(strippedName.Length - 1).ToLower()[0] == 's' ?
strippedName + "'" :
strippedName + "'s";
ViewBag.Title = strippedName.Substring(strippedName.Length - 1).ToLower()[0] == 's'
? strippedName + "'"
: strippedName + "'s";
ViewBag.Title += " " + Localization["WEBFRONT_CLIENT_PROFILE_TITLE"];
ViewBag.Description = $"Client information for {strippedName}";
ViewBag.Keywords = $"IW4MAdmin, client, profile, {strippedName}";
@ -137,13 +156,13 @@ namespace WebfrontCore.Controllers
return View("Profile/Index", clientDto);
}
public async Task<IActionResult> PrivilegedAsync()
public async Task<IActionResult> Privileged()
{
if (Manager.GetApplicationSettings().Configuration().EnablePrivilegedUserPrivacy && !Authorized)
{
return RedirectToAction("Index", "Home");
}
var admins = (await Manager.GetClientService().GetPrivilegedClients())
.OrderByDescending(_client => _client.Level)
.ThenBy(_client => _client.Name);
@ -160,7 +179,8 @@ namespace WebfrontCore.Controllers
adminsDict[admin.Level].Add(new ClientInfo()
{
Name = admin.Name,
ClientId = admin.ClientId
ClientId = admin.ClientId,
LastConnection = admin.LastConnection
});
}
@ -171,7 +191,7 @@ namespace WebfrontCore.Controllers
return View("Privileged/Index", adminsDict);
}
public async Task<IActionResult> FindAsync(string clientName)
public async Task<IActionResult> Find(string clientName)
{
if (string.IsNullOrWhiteSpace(clientName))
{
@ -189,11 +209,13 @@ namespace WebfrontCore.Controllers
}
}
ViewBag.Title = $"{clientsDto.Count} {Localization["WEBFRONT_CLIENT_SEARCH_MATCHING"]} \"{clientName}\"";
ViewBag.SearchTerm = clientName;
ViewBag.ResultCount = clientsDto.Count;
return View("Find/Index", clientsDto);
}
public IActionResult Meta(int id, int count, int offset, long? startAt, MetaType? metaFilterType, CancellationToken token)
public IActionResult Meta(int id, int count, int offset, long? startAt, MetaType? metaFilterType,
CancellationToken token)
{
var request = new ClientPaginationRequest
{

View File

@ -42,15 +42,20 @@ namespace IW4MAdmin.Plugins.Web.StatsWeb.Controllers
}
[HttpGet]
public IActionResult TopPlayersAsync()
public IActionResult TopPlayers(string serverId = null)
{
ViewBag.Title = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_STATS_INDEX_TITLE"];
ViewBag.Description = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_STATS_INDEX_DESC"];
ViewBag.Servers = _manager.GetServers()
.Select(_server => new ServerInfo() {Name = _server.Hostname, ID = _server.EndPoint});
ViewBag.Localization = _translationLookup;
ViewBag.SelectedServerId = serverId;
return View("~/Views/Client/Statistics/Index.cshtml");
return View("~/Views/Client/Statistics/Index.cshtml", _manager.GetServers()
.Select(server => new ServerInfo
{
Name = server.Hostname,
IPAddress = server.IP,
Port = server.Port
}));
}
[HttpGet]
@ -169,7 +174,7 @@ namespace IW4MAdmin.Plugins.Web.StatsWeb.Controllers
var penalty = await context.Penalties
.Select(_penalty => new
{_penalty.OffenderId, _penalty.PenaltyId, _penalty.When, _penalty.AutomatedOffense})
{ _penalty.OffenderId, _penalty.PenaltyId, _penalty.When, _penalty.AutomatedOffense })
.FirstOrDefaultAsync(_penalty => _penalty.PenaltyId == penaltyId);
if (penalty == null)

View File

@ -39,7 +39,7 @@ namespace WebfrontCore.Controllers
return Unauthorized();
}
return View("Index", Manager.GetApplicationSettings().Configuration());
return RedirectToAction("Files");
}
public async Task<IActionResult> Files()
@ -256,4 +256,4 @@ namespace WebfrontCore.Controllers
.Where(_attr => _attr.GetType() == typeof(ConfigurationIgnore))
.FirstOrDefault() as ConfigurationIgnore) != null;
}
}
}

View File

@ -34,11 +34,11 @@ namespace WebfrontCore.Controllers
return View(activeServers);
}
public async Task<IActionResult> ExecuteAsync(long serverId, string command)
public async Task<IActionResult> Execute(long serverId, string command)
{
var server = Manager.GetServers().First(s => s.EndPoint == serverId);
var client = new EFClient()
var client = new EFClient
{
ClientId = Client.ClientId,
Level = Client.Level,
@ -50,7 +50,7 @@ namespace WebfrontCore.Controllers
}
};
var remoteEvent = new GameEvent()
var remoteEvent = new GameEvent
{
Type = GameEvent.EventType.Command,
Data = command.StartsWith(_appconfig.CommandPrefix) ||
@ -97,15 +97,15 @@ namespace WebfrontCore.Controllers
{
response = new[]
{
new CommandResponseInfo()
new CommandResponseInfo
{
ClientId = client.ClientId,
Response = Utilities.CurrentLocalization.LocalizationIndex["COMMADS_RESTART_SUCCESS"]
}
};
}
return View("_Response", response);
return remoteEvent.Failed ? StatusCode(400, response) : Ok(response);
}
}
}
}

View File

@ -30,49 +30,15 @@ namespace WebfrontCore.Controllers
return View(showOnly);
}
public async Task<IActionResult> ListAsync(int offset = 0, EFPenalty.PenaltyType showOnly = EFPenalty.PenaltyType.Any, bool hideAutomatedPenalties = true)
public async Task<IActionResult> ListAsync(int offset = 0, int count = 30, EFPenalty.PenaltyType showOnly = EFPenalty.PenaltyType.Any, bool hideAutomatedPenalties = true)
{
return await Task.FromResult(View("_List", new ViewModels.PenaltyFilterInfo()
return await Task.FromResult(View("_List", new ViewModels.PenaltyFilterInfo
{
Offset = offset,
Count = count,
ShowOnly = showOnly,
IgnoreAutomated = hideAutomatedPenalties
}));
}
/// <summary>
/// retrieves all permanent bans ordered by ban date
/// if request is authorized, it will include the client's ip address.
/// </summary>
/// <returns></returns>
public async Task<IActionResult> PublicAsync()
{
IList<PenaltyInfo> penalties;
await using var ctx = _contextFactory.CreateContext(false);
var iqPenalties = ctx.Penalties
.AsNoTracking()
.Where(p => p.Type == EFPenalty.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,
PunisherNetworkId = (ulong)p.Punisher.NetworkId,
PunisherName = p.Punisher.CurrentAlias.Name,
PunisherIPAddress = Authorized ? p.Punisher.CurrentAlias.IPAddress.ConvertIPtoString() : null,
TimePunished = p.When,
AutomatedOffense = Authorized ? p.AutomatedOffense : null,
});
penalties = await iqPenalties.ToListAsync();
return Json(penalties);
}
}
}

View File

@ -28,7 +28,7 @@ namespace WebfrontCore.Controllers
return NotFound();
}
var serverInfo = new ServerInfo()
var serverInfo = new ServerInfo
{
Name = s.Hostname,
ID = s.EndPoint,
@ -44,7 +44,7 @@ namespace WebfrontCore.Controllers
ClientId = p.ClientId,
Level = p.Level.ToLocalizedLevelName(),
LevelInt = (int) p.Level,
ZScore = p.GetAdditionalProperty<EFClientStatistics>(IW4MAdmin.Plugins.Stats.Helpers.StatManager
ZScore = p.GetAdditionalProperty<EFClientStatistics>(StatManager
.CLIENT_STATS_KEY)?.ZScore
}).ToList(),
ChatHistory = s.ChatHistory.ToList(),
@ -55,37 +55,40 @@ namespace WebfrontCore.Controllers
}
[HttpGet]
public ActionResult Scoreboard()
public ActionResult Scoreboard(string serverId)
{
ViewBag.Title = Localization["WEBFRONT_TITLE_SCOREBOARD"];
ViewBag.SelectedServerId = string.IsNullOrEmpty(serverId) ? Manager.GetServers().FirstOrDefault()?.ToString() : serverId;
return View(ProjectScoreboard(Manager.GetServers(), null, true));
return View(ProjectScoreboard(Manager.GetServers(), null, true, false));
}
[HttpGet("[controller]/{id}/scoreboard")]
public ActionResult Scoreboard(long id, [FromQuery]string order = null, [FromQuery] bool down = true)
public ActionResult Scoreboard(string id, [FromQuery]string order = null, [FromQuery] bool down = true)
{
var server = Manager.GetServers().FirstOrDefault(srv => srv.EndPoint == id);
var server = Manager.GetServers().FirstOrDefault(srv => srv.ToString() == id);
if (server == null)
{
return NotFound();
}
ViewBag.SelectedServerId = id;
return View("_Scoreboard", ProjectScoreboard(new[] {server}, order, down).First());
}
private static IEnumerable<ScoreboardInfo> ProjectScoreboard(IEnumerable<Server> servers, string order,
bool down)
bool down, bool includeDetails = true)
{
return servers.Select(server => new ScoreboardInfo
return servers.Select((server, index) => new ScoreboardInfo
{
OrderByKey = order,
ShouldOrderDescending = down,
MapName = server.CurrentMap.ToString(),
ServerName = server.Hostname,
ServerId = server.EndPoint,
ClientInfo = server.GetClientsAsList().Select(client =>
ServerId = server.ToString(),
ClientInfo = index == 0 && !includeDetails || includeDetails ? server.GetClientsAsList().Select(client =>
new
{
stats = client.GetAdditionalProperty<EFClientStatistics>(StatManager.CLIENT_STATS_KEY),
@ -104,7 +107,7 @@ namespace WebfrontCore.Controllers
ZScore = clientData.stats?.ZScore == null || clientData.stats.ZScore == 0 ? null : clientData.stats.ZScore,
Team = clientData.client.Team
})
.ToList()
.ToList() : new List<ClientScoreboardInfo>()
}).ToList();
}
}