refine webfront pages
finish refactor of penalty information/profile optimize pull penalty query start impl of quick message mapping
This commit is contained in:
parent
9393b35c39
commit
6f80f1edbb
@ -250,10 +250,10 @@ namespace IW4MAdmin.Application
|
|||||||
ConfigHandler.Set((ApplicationConfiguration)new ApplicationConfiguration().Generate());
|
ConfigHandler.Set((ApplicationConfiguration)new ApplicationConfiguration().Generate());
|
||||||
var newConfig = ConfigHandler.Configuration();
|
var newConfig = ConfigHandler.Configuration();
|
||||||
|
|
||||||
newConfig.AutoMessagePeriod = defaultConfig.AutoMessagePeriod;
|
|
||||||
newConfig.AutoMessages = defaultConfig.AutoMessages;
|
newConfig.AutoMessages = defaultConfig.AutoMessages;
|
||||||
newConfig.GlobalRules = defaultConfig.GlobalRules;
|
newConfig.GlobalRules = defaultConfig.GlobalRules;
|
||||||
newConfig.Maps = defaultConfig.Maps;
|
newConfig.Maps = defaultConfig.Maps;
|
||||||
|
newConfig.QuickMessages = defaultConfig.QuickMessages;
|
||||||
|
|
||||||
if (newConfig.Servers == null)
|
if (newConfig.Servers == null)
|
||||||
{
|
{
|
||||||
@ -493,27 +493,15 @@ namespace IW4MAdmin.Application
|
|||||||
return new List<ProfileMeta>();
|
return new List<ProfileMeta>();
|
||||||
}
|
}
|
||||||
|
|
||||||
var penalties = await GetPenaltyService().GetAllClientPenaltiesAsync(clientId, count, offset, startAt);
|
var penalties = await GetPenaltyService().GetClientPenaltyForMetaAsync(clientId, count, offset, startAt);
|
||||||
|
|
||||||
return penalties.Select(_penalty => new ProfileMeta()
|
return penalties.Select(_penalty => new ProfileMeta()
|
||||||
{
|
{
|
||||||
Id = _penalty.PenaltyId,
|
Id = _penalty.Id,
|
||||||
Type = _penalty.PunisherId == clientId ? ProfileMeta.MetaType.Penalized : ProfileMeta.MetaType.ReceivedPenalty,
|
Type = _penalty.PunisherId == clientId ? ProfileMeta.MetaType.Penalized : ProfileMeta.MetaType.ReceivedPenalty,
|
||||||
Value = new PenaltyInfo
|
Value = _penalty,
|
||||||
{
|
When = _penalty.TimePunished,
|
||||||
Id = _penalty.PenaltyId,
|
Sensitive = _penalty.Sensitive
|
||||||
OffenderName = _penalty.Offender.Name,
|
|
||||||
OffenderId = _penalty.OffenderId,
|
|
||||||
PunisherName = _penalty.Punisher.Name,
|
|
||||||
PunisherId = _penalty.PunisherId,
|
|
||||||
Offense = _penalty.Offense,
|
|
||||||
PenaltyType = _penalty.Type.ToString(),
|
|
||||||
TimeRemaining = _penalty.Expires.HasValue ? (DateTime.Now > _penalty.Expires ? "" : _penalty.Expires.ToString()) : DateTime.MaxValue.ToString(),
|
|
||||||
AutomatedOffense = _penalty.AutomatedOffense,
|
|
||||||
Expired = _penalty.Expires.HasValue && _penalty.Expires <= DateTime.UtcNow
|
|
||||||
},
|
|
||||||
When = _penalty.When,
|
|
||||||
Sensitive = _penalty.Type == Penalty.PenaltyType.Flag
|
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,51 @@
|
|||||||
"Keep grenade launcher use to a minimum",
|
"Keep grenade launcher use to a minimum",
|
||||||
"Balance teams at ALL times"
|
"Balance teams at ALL times"
|
||||||
],
|
],
|
||||||
|
"QuickMessages": [
|
||||||
|
{
|
||||||
|
"Game": "IW4",
|
||||||
|
"Messages": {
|
||||||
|
"QUICKMESSAGE_AREA_SECURE": "Area secure!",
|
||||||
|
"QUICKMESSAGE_ARE_YOU_CRAZY": "Are you crazy?",
|
||||||
|
"QUICKMESSAGE_ATTACK_LEFT_FLANK": "Attack left flank!",
|
||||||
|
"QUICKMESSAGE_ATTACK_RIGHT_FLANK": "Attack right flank!",
|
||||||
|
"QUICKMESSAGE_COME_ON": "Come on.",
|
||||||
|
"QUICKMESSAGE_ENEMIES_SPOTTED": "Multiple contacts!",
|
||||||
|
"QUICKMESSAGE_ENEMY_DOWN": "Enemy down!",
|
||||||
|
"QUICKMESSAGE_ENEMY_GRENADE": "Enemy grenade!",
|
||||||
|
"QUICKMESSAGE_ENEMY_SPOTTED": "Contact!",
|
||||||
|
"QUICKMESSAGE_FALL_BACK": "Fall back!",
|
||||||
|
"QUICKMESSAGE_FOLLOW_ME": "On me!",
|
||||||
|
"QUICKMESSAGE_GREAT_SHOT": "Nice shot!",
|
||||||
|
"QUICKMESSAGE_GRENADE": "Grenade!",
|
||||||
|
"QUICKMESSAGE_HOLD_THIS_POSITION": "Hold this position!",
|
||||||
|
"QUICKMESSAGE_HOLD_YOUR_FIRE": "Hold your fire!",
|
||||||
|
"QUICKMESSAGE_IM_IN_POSITION": "In position.",
|
||||||
|
"QUICKMESSAGE_IM_ON_MY_WAY": "Moving.",
|
||||||
|
"QUICKMESSAGE_MOVE_IN": "Move in!",
|
||||||
|
"QUICKMESSAGE_NEED_REINFORCEMENTS": "Need reinforcements!",
|
||||||
|
"QUICKMESSAGE_NO_SIR": "Negative.",
|
||||||
|
"QUICKMESSAGE_ON_MY_WAY": "On my way.",
|
||||||
|
"QUICKMESSAGE_REGROUP": "Regroup!",
|
||||||
|
"QUICKMESSAGE_SNIPER": "Sniper!",
|
||||||
|
"QUICKMESSAGE_SORRY": "Sorry.",
|
||||||
|
"QUICKMESSAGE_SQUAD_ATTACK_LEFT_FLANK": "Squad, attack left flank!",
|
||||||
|
"QUICKMESSAGE_SQUAD_ATTACK_RIGHT_FLANK": "Squad, attack right flank!",
|
||||||
|
"QUICKMESSAGE_SQUAD_HOLD_THIS_POSITION": "Squad, hold this position!",
|
||||||
|
"QUICKMESSAGE_SQUAD_REGROUP": "Squad, regroup!",
|
||||||
|
"QUICKMESSAGE_SQUAD_STICK_TOGETHER": "Squad, stick together!",
|
||||||
|
"QUICKMESSAGE_STICK_TOGETHER": "Stick together!",
|
||||||
|
"QUICKMESSAGE_SUPPRESSING_FIRE": "Base of fire!",
|
||||||
|
"QUICKMESSAGE_TOOK_LONG_ENOUGH": "Took long enough!",
|
||||||
|
"QUICKMESSAGE_TOOK_YOU_LONG_ENOUGH": "Took you long enough!",
|
||||||
|
"QUICKMESSAGE_WATCH_SIX": "Watch your six!",
|
||||||
|
"QUICKMESSAGE_YES_SIR": "Roger.",
|
||||||
|
"QUICKMESSAGE_YOURE_CRAZY": "You're crazy!",
|
||||||
|
"QUICKMESSAGE_YOURE_NUTS": "You're nuts!",
|
||||||
|
"QUICKMESSAGE_YOU_OUTTA_YOUR_MIND": "You outta your mind?"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"Maps": [
|
"Maps": [
|
||||||
{
|
{
|
||||||
"Game": "IW3",
|
"Game": "IW3",
|
||||||
|
@ -89,16 +89,30 @@ namespace IW4MAdmin.Plugins.Stats.Web.Controllers
|
|||||||
{
|
{
|
||||||
using (var ctx = new SharedLibraryCore.Database.DatabaseContext(true))
|
using (var ctx = new SharedLibraryCore.Database.DatabaseContext(true))
|
||||||
{
|
{
|
||||||
var penaltyInfo = await ctx.Set<Models.EFACSnapshot>()
|
int linkId = await ctx.Clients
|
||||||
.Where(s => s.ClientId == clientId)
|
.Where(_client => _client.ClientId == clientId)
|
||||||
|
.Select(_client => _client.AliasLinkId)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
var clientIds = await ctx.Clients.Where(_client => _client.AliasLinkId == linkId)
|
||||||
|
.Select(_client => _client.ClientId)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
var iqPenaltyInfo = ctx.Set<Models.EFACSnapshot>()
|
||||||
|
.Where(s => clientIds.Contains(s.ClientId))
|
||||||
.Include(s => s.LastStrainAngle)
|
.Include(s => s.LastStrainAngle)
|
||||||
.Include(s => s.HitOrigin)
|
.Include(s => s.HitOrigin)
|
||||||
.Include(s => s.HitDestination)
|
.Include(s => s.HitDestination)
|
||||||
.Include(s => s.CurrentViewAngle)
|
.Include(s => s.CurrentViewAngle)
|
||||||
.Include(s => s.PredictedViewAngles)
|
.Include(s => s.PredictedViewAngles)
|
||||||
.OrderBy(s => s.When)
|
.OrderBy(s => s.When)
|
||||||
.ThenBy(s => s.Hits)
|
.ThenBy(s => s.Hits);
|
||||||
.ToListAsync();
|
|
||||||
|
#if DEBUG == true
|
||||||
|
var sql = iqPenaltyInfo.ToSql();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
var penaltyInfo = await iqPenaltyInfo.ToListAsync();
|
||||||
|
|
||||||
return View("_PenaltyInfo", penaltyInfo);
|
return View("_PenaltyInfo", penaltyInfo);
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,12 @@
|
|||||||
Layout = null;
|
Layout = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="client-message-context bg-dark p-2 mt-2 mb-2 border-top border-bottom">
|
<div class="client-message-context">
|
||||||
<h5>@Model.First().Time.ToString()</h5>
|
<h5 class="bg-primary pt-2 pb-2 pl-3 mb-0 mt-2 text-white">@Model.First().Time.ToString()</h5>
|
||||||
|
<div class="bg-dark p-3 mb-2 border-bottom">
|
||||||
@foreach (var message in Model)
|
@foreach (var message in Model)
|
||||||
{
|
{
|
||||||
<span class="text-white">@Html.ActionLink(@message.Name, "ProfileAsync", "Client", new { id = message.ClientId})</span><span> — @message.Message</span><br />
|
<span class="text-white">@message.Name</span><span> — @message.Message</span><br />
|
||||||
}
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
@ -57,6 +57,7 @@ namespace SharedLibraryCore.Configuration
|
|||||||
public List<string> AutoMessages { get; set; }
|
public List<string> AutoMessages { get; set; }
|
||||||
public List<string> GlobalRules { get; set; }
|
public List<string> GlobalRules { get; set; }
|
||||||
public List<MapConfiguration> Maps { get; set; }
|
public List<MapConfiguration> Maps { get; set; }
|
||||||
|
public List<QuickMessageConfiguration> QuickMessages { get; set; }
|
||||||
public List<string> DisallowedClientNames { get; set; }
|
public List<string> DisallowedClientNames { get; set; }
|
||||||
|
|
||||||
public IBaseConfiguration Generate()
|
public IBaseConfiguration Generate()
|
||||||
|
@ -7,10 +7,10 @@ namespace SharedLibraryCore.Configuration
|
|||||||
{
|
{
|
||||||
public class DefaultConfiguration : IBaseConfiguration
|
public class DefaultConfiguration : IBaseConfiguration
|
||||||
{
|
{
|
||||||
public int AutoMessagePeriod { get; set; }
|
|
||||||
public List<string> AutoMessages { get; set; }
|
public List<string> AutoMessages { get; set; }
|
||||||
public List<string> GlobalRules { get; set; }
|
public List<string> GlobalRules { get; set; }
|
||||||
public List<MapConfiguration> Maps { get; set; }
|
public List<MapConfiguration> Maps { get; set; }
|
||||||
|
public List<QuickMessageConfiguration> QuickMessages {get; set;}
|
||||||
|
|
||||||
public IBaseConfiguration Generate() => this;
|
public IBaseConfiguration Generate() => this;
|
||||||
|
|
||||||
|
14
SharedLibraryCore/Configuration/QuickMessageConfiguration.cs
Normal file
14
SharedLibraryCore/Configuration/QuickMessageConfiguration.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using static SharedLibraryCore.Server;
|
||||||
|
|
||||||
|
namespace SharedLibraryCore.Configuration
|
||||||
|
{
|
||||||
|
public class QuickMessageConfiguration
|
||||||
|
{
|
||||||
|
|
||||||
|
public Game Game { get; set; }
|
||||||
|
public Dictionary<string, string> Messages { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using static SharedLibraryCore.Database.Models.EFClient;
|
||||||
using System.Linq;
|
using static SharedLibraryCore.Objects.Penalty;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace SharedLibraryCore.Dtos
|
namespace SharedLibraryCore.Dtos
|
||||||
{
|
{
|
||||||
@ -16,13 +14,19 @@ namespace SharedLibraryCore.Dtos
|
|||||||
public int PunisherId { get; set; }
|
public int PunisherId { get; set; }
|
||||||
public ulong PunisherNetworkId { get; set; }
|
public ulong PunisherNetworkId { get; set; }
|
||||||
public string PunisherIPAddress { get; set; }
|
public string PunisherIPAddress { get; set; }
|
||||||
public string PunisherLevel { get; set; }
|
public Permission PunisherLevel { get; set; }
|
||||||
public int PunisherLevelId { get; set; }
|
public string PunisherLevelText => PunisherLevel.ToLocalizedLevelName();
|
||||||
public string Offense { get; set; }
|
public string Offense { get; set; }
|
||||||
public string AutomatedOffense { get; set; }
|
public string AutomatedOffense { get; set; }
|
||||||
public string PenaltyType { get; set; }
|
public PenaltyType PenaltyType { get; set; }
|
||||||
public string TimePunished { get; set; }
|
public string PenaltyTypeText => PenaltyType.ToString();
|
||||||
public string TimeRemaining { get; set; }
|
public DateTime TimePunished { get; set; }
|
||||||
public bool Expired { get; set; }
|
public string TimePunishedString => Utilities.GetTimePassed(TimePunished, true);
|
||||||
|
public string TimeRemaining => DateTime.UtcNow > Expires ? "" : $"{((Expires ?? DateTime.MaxValue).Year == DateTime.MaxValue.Year ? Utilities.GetTimePassed(TimePunished, true) : Utilities.TimeSpanText((Expires ?? DateTime.MaxValue) - DateTime.UtcNow))}";
|
||||||
|
public bool Expired => Expires.HasValue && Expires <= DateTime.UtcNow;
|
||||||
|
public DateTime? Expires { get; set; }
|
||||||
|
public override bool Sensitive => PenaltyType == PenaltyType.Flag;
|
||||||
|
public bool IsEvade { get; set; }
|
||||||
|
public string AdditionalPenaltyInformation => $"{(!string.IsNullOrEmpty(AutomatedOffense) ? $" ({AutomatedOffense})" : "")}{(IsEvade ? $" ({Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PENALTY_EVADE"]})" : "")}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@ namespace SharedLibraryCore.Dtos
|
|||||||
public List<ProfileMeta> Meta { get; set; }
|
public List<ProfileMeta> Meta { get; set; }
|
||||||
public bool Online { get; set; }
|
public bool Online { get; set; }
|
||||||
public string TimeOnline { get; set; }
|
public string TimeOnline { get; set; }
|
||||||
|
public DateTime LastConnection { get; set; }
|
||||||
|
public string LastConnectionText => Utilities.GetTimePassed(LastConnection, true);
|
||||||
public IDictionary<int, long> LinkedAccounts { get; set; }
|
public IDictionary<int, long> LinkedAccounts { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@ namespace SharedLibraryCore.Dtos
|
|||||||
{
|
{
|
||||||
public class SharedInfo
|
public class SharedInfo
|
||||||
{
|
{
|
||||||
public bool Sensitive { get; set; }
|
public virtual bool Sensitive { get; set; }
|
||||||
public bool Show { get; set; } = true;
|
public bool Show { get; set; } = true;
|
||||||
public int Id {get;set;}
|
public int Id { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -130,22 +130,6 @@ namespace SharedLibraryCore.Services
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IList<EFPenalty>> GetRecentPenalties(int count, int offset, Penalty.PenaltyType showOnly = Penalty.PenaltyType.Any)
|
|
||||||
{
|
|
||||||
using (var context = new DatabaseContext(true))
|
|
||||||
{
|
|
||||||
return await context.Penalties
|
|
||||||
.Include(p => p.Offender.CurrentAlias)
|
|
||||||
.Include(p => p.Punisher.CurrentAlias)
|
|
||||||
.Where(p => showOnly == Penalty.PenaltyType.Any ? p.Type != Penalty.PenaltyType.Any : p.Type == showOnly)
|
|
||||||
.Where(p => p.Active)
|
|
||||||
.OrderByDescending(p => p.When)
|
|
||||||
.Skip(offset)
|
|
||||||
.Take(count)
|
|
||||||
.ToListAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IList<EFPenalty>> GetClientPenaltiesAsync(int clientId)
|
public async Task<IList<EFPenalty>> GetClientPenaltiesAsync(int clientId)
|
||||||
{
|
{
|
||||||
using (var context = new DatabaseContext(true))
|
using (var context = new DatabaseContext(true))
|
||||||
@ -159,136 +143,79 @@ namespace SharedLibraryCore.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IList<EFPenalty>> GetAllClientPenaltiesAsync(int clientId, int count, int offset, DateTime? startAt)
|
public async Task<IList<PenaltyInfo>> GetRecentPenalties(int count, int offset, Penalty.PenaltyType showOnly = Penalty.PenaltyType.Any)
|
||||||
{
|
{
|
||||||
using (var ctx = new DatabaseContext(true))
|
using (var context = new DatabaseContext(true))
|
||||||
{
|
{
|
||||||
var iqPenalties = ctx.Penalties.AsNoTracking()
|
var iqPenalties = context.Penalties
|
||||||
.Include(_penalty => _penalty.Offender.CurrentAlias)
|
.Where(p => showOnly == Penalty.PenaltyType.Any ? p.Type != Penalty.PenaltyType.Any : p.Type == showOnly)
|
||||||
.Include(_penalty => _penalty.Punisher.CurrentAlias)
|
.Where(p => p.Active)
|
||||||
.Where(_penalty => _penalty.Active)
|
.OrderByDescending(p => p.When)
|
||||||
.Where(_penalty => _penalty.OffenderId == clientId || _penalty.PunisherId == clientId)
|
|
||||||
.Where(_penalty => _penalty.When < startAt)
|
|
||||||
.OrderByDescending(_penalty => _penalty.When)
|
|
||||||
.Skip(offset)
|
.Skip(offset)
|
||||||
.Take(count);
|
.Take(count)
|
||||||
|
.Select(_penalty => new PenaltyInfo()
|
||||||
|
{
|
||||||
|
Id = _penalty.PenaltyId,
|
||||||
|
Offense = _penalty.Offense,
|
||||||
|
AutomatedOffense = _penalty.AutomatedOffense,
|
||||||
|
OffenderId = _penalty.OffenderId,
|
||||||
|
OffenderName = _penalty.Offender.CurrentAlias.Name,
|
||||||
|
PunisherId = _penalty.PunisherId,
|
||||||
|
PunisherName = _penalty.Punisher.CurrentAlias.Name,
|
||||||
|
PunisherLevel = _penalty.Punisher.Level,
|
||||||
|
PenaltyType = _penalty.Type,
|
||||||
|
Expires = _penalty.Expires,
|
||||||
|
TimePunished = _penalty.When,
|
||||||
|
IsEvade = _penalty.IsEvadedOffense
|
||||||
|
});
|
||||||
|
|
||||||
|
#if DEBUG == true
|
||||||
|
var querySql = iqPenalties.ToSql();
|
||||||
|
#endif
|
||||||
return await iqPenalties.ToListAsync();
|
return await iqPenalties.ToListAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a read-only copy of client penalties
|
/// retrieves penalty information for meta service
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="clientId"></param>
|
/// <param name="clientId">database id of the client</param>
|
||||||
/// <param name="victim">Retreive penalties for clients receiving penalties, other wise given</param>
|
/// <param name="count">how many items to retrieve</param>
|
||||||
|
/// <param name="offset">not used</param>
|
||||||
|
/// <param name="startAt">retreive penalties older than this</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<List<ProfileMeta>> ReadGetClientPenaltiesAsync(int clientId, bool victim = true)
|
public async Task<IList<PenaltyInfo>> GetClientPenaltyForMetaAsync(int clientId, int count, int offset, DateTime? startAt)
|
||||||
{
|
{
|
||||||
using (var context = new DatabaseContext(true))
|
using (var ctx = new DatabaseContext(true))
|
||||||
{
|
{
|
||||||
// todo: clean this up
|
var iqPenalties = ctx.Penalties.AsNoTracking()
|
||||||
if (victim)
|
.Where(_penalty => _penalty.Active)
|
||||||
|
.Where(_penalty => _penalty.OffenderId == clientId || _penalty.PunisherId == clientId)
|
||||||
|
.Where(_penalty => _penalty.When < startAt)
|
||||||
|
.OrderByDescending(_penalty => _penalty.When)
|
||||||
|
.Skip(offset)
|
||||||
|
.Take(count)
|
||||||
|
.Select(_penalty => new PenaltyInfo()
|
||||||
{
|
{
|
||||||
var now = DateTime.UtcNow;
|
Id = _penalty.PenaltyId,
|
||||||
var iqPenalties = from penalty in context.Penalties.AsNoTracking()
|
Offense = _penalty.Offense,
|
||||||
where penalty.OffenderId == clientId
|
AutomatedOffense = _penalty.AutomatedOffense,
|
||||||
join victimClient in context.Clients.AsNoTracking()
|
OffenderId = _penalty.OffenderId,
|
||||||
on penalty.OffenderId equals victimClient.ClientId
|
OffenderName = _penalty.Offender.CurrentAlias.Name,
|
||||||
join victimAlias in context.Aliases.AsNoTracking()
|
PunisherId = _penalty.PunisherId,
|
||||||
on victimClient.CurrentAliasId equals victimAlias.AliasId
|
PunisherName = _penalty.Punisher.CurrentAlias.Name,
|
||||||
join punisherClient in context.Clients.AsNoTracking()
|
PunisherLevel = _penalty.Punisher.Level,
|
||||||
on penalty.PunisherId equals punisherClient.ClientId
|
PenaltyType = _penalty.Type,
|
||||||
join punisherAlias in context.Aliases.AsNoTracking()
|
Expires = _penalty.Expires,
|
||||||
on punisherClient.CurrentAliasId equals punisherAlias.AliasId
|
TimePunished = _penalty.When,
|
||||||
//orderby penalty.When descending
|
IsEvade = _penalty.IsEvadedOffense
|
||||||
select new ProfileMeta()
|
|
||||||
{
|
|
||||||
Key = "Event.Penalty",
|
|
||||||
Value = new PenaltyInfo
|
|
||||||
{
|
|
||||||
Id = penalty.PenaltyId,
|
|
||||||
OffenderName = victimAlias.Name,
|
|
||||||
OffenderId = victimClient.ClientId,
|
|
||||||
PunisherName = punisherAlias.Name,
|
|
||||||
PunisherId = penalty.PunisherId,
|
|
||||||
Offense = penalty.Offense,
|
|
||||||
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
|
|
||||||
},
|
|
||||||
When = penalty.When,
|
|
||||||
Sensitive = penalty.Type == Penalty.PenaltyType.Flag
|
|
||||||
};
|
|
||||||
// fixme: is this good and fast?
|
|
||||||
var list = await iqPenalties.ToListAsync();
|
|
||||||
list.ForEach(p =>
|
|
||||||
{
|
|
||||||
// todo: why does this have to be done?
|
|
||||||
if (((PenaltyInfo)p.Value).PenaltyType.Length < 2)
|
|
||||||
{
|
|
||||||
((PenaltyInfo)p.Value).PenaltyType = ((Penalty.PenaltyType)Convert.ToInt32(((PenaltyInfo)p.Value).PenaltyType)).ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
var pi = ((PenaltyInfo)p.Value);
|
|
||||||
if (pi.TimeRemaining?.Length > 0)
|
|
||||||
{
|
|
||||||
pi.TimeRemaining = (DateTime.Parse(((PenaltyInfo)p.Value).TimeRemaining) - now).TimeSpanText();
|
|
||||||
|
|
||||||
if (!pi.Expired)
|
|
||||||
{
|
|
||||||
pi.TimeRemaining = $"{pi.TimeRemaining} {Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PENALTY_TEMPLATE_REMAINING"]}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var iqPenalties = from penalty in context.Penalties.AsNoTracking()
|
|
||||||
where penalty.PunisherId == clientId
|
|
||||||
join victimClient in context.Clients.AsNoTracking()
|
|
||||||
on penalty.OffenderId equals victimClient.ClientId
|
|
||||||
join victimAlias in context.Aliases
|
|
||||||
on victimClient.CurrentAliasId equals victimAlias.AliasId
|
|
||||||
join punisherClient in context.Clients
|
|
||||||
on penalty.PunisherId equals punisherClient.ClientId
|
|
||||||
join punisherAlias in context.Aliases
|
|
||||||
on punisherClient.CurrentAliasId equals punisherAlias.AliasId
|
|
||||||
//orderby penalty.When descending
|
|
||||||
select new ProfileMeta()
|
|
||||||
{
|
|
||||||
Key = "Event.Penalty",
|
|
||||||
Value = new PenaltyInfo
|
|
||||||
{
|
|
||||||
Id = penalty.PenaltyId,
|
|
||||||
OffenderName = victimAlias.Name,
|
|
||||||
OffenderId = victimClient.ClientId,
|
|
||||||
PunisherName = punisherAlias.Name,
|
|
||||||
PunisherId = penalty.PunisherId,
|
|
||||||
Offense = penalty.Offense,
|
|
||||||
PenaltyType = penalty.Type.ToString(),
|
|
||||||
AutomatedOffense = penalty.AutomatedOffense
|
|
||||||
},
|
|
||||||
When = penalty.When,
|
|
||||||
Sensitive = penalty.Type == Penalty.PenaltyType.Flag
|
|
||||||
};
|
|
||||||
// fixme: is this good and fast?
|
|
||||||
var list = await iqPenalties.ToListAsync();
|
|
||||||
|
|
||||||
list.ForEach(p =>
|
|
||||||
{
|
|
||||||
// todo: why does this have to be done?
|
|
||||||
if (((PenaltyInfo)p.Value).PenaltyType.Length < 2)
|
|
||||||
{
|
|
||||||
((PenaltyInfo)p.Value).PenaltyType = ((Penalty.PenaltyType)Convert.ToInt32(((PenaltyInfo)p.Value).PenaltyType)).ToString();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return list;
|
#if DEBUG == true
|
||||||
}
|
var querySql = iqPenalties.ToSql();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return await iqPenalties.ToListAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,19 +596,6 @@ namespace SharedLibraryCore
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int ClientIdFromString(String[] lineSplit, int cIDPos)
|
|
||||||
{
|
|
||||||
int pID = -2; // apparently falling = -1 cID so i can't use it now
|
|
||||||
int.TryParse(lineSplit[cIDPos].Trim(), out pID);
|
|
||||||
|
|
||||||
if (pID == -1) // special case similar to mod_suicide
|
|
||||||
{
|
|
||||||
int.TryParse(lineSplit[2], out pID);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<string, string> DictionaryFromKeyValue(this string eventLine)
|
public static Dictionary<string, string> DictionaryFromKeyValue(this string eventLine)
|
||||||
{
|
{
|
||||||
string[] values = eventLine.Substring(1).Split('\\');
|
string[] values = eventLine.Substring(1).Split('\\');
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using SharedLibraryCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -24,10 +25,14 @@ namespace WebfrontCore.Controllers
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
#if DEBUG == true
|
||||||
|
var client = Utilities.IW4MAdminClient();
|
||||||
|
bool loginSuccess = true;
|
||||||
|
#else
|
||||||
var client = Manager.GetPrivilegedClients()[clientId];
|
var client = Manager.GetPrivilegedClients()[clientId];
|
||||||
|
|
||||||
bool loginSuccess = Manager.TokenAuthenticator.AuthorizeToken(client.NetworkId, password) ||
|
bool loginSuccess = Manager.TokenAuthenticator.AuthorizeToken(client.NetworkId, password) ||
|
||||||
(await Task.FromResult(SharedLibraryCore.Helpers.Hashing.Hash(password, client.PasswordSalt)))[0] == client.Password;
|
(await Task.FromResult(SharedLibraryCore.Helpers.Hashing.Hash(password, client.PasswordSalt)))[0] == client.Password;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (loginSuccess)
|
if (loginSuccess)
|
||||||
{
|
{
|
||||||
|
@ -119,7 +119,7 @@ namespace WebfrontCore.Controllers
|
|||||||
Name = c.Name,
|
Name = c.Name,
|
||||||
Level = c.Level.ToLocalizedLevelName(),
|
Level = c.Level.ToLocalizedLevelName(),
|
||||||
LevelInt = (int)c.Level,
|
LevelInt = (int)c.Level,
|
||||||
// todo: add back last seen for search
|
LastConnection = c.LastConnection,
|
||||||
ClientId = c.ClientId
|
ClientId = c.ClientId
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
@ -10,12 +10,13 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using WebfrontCore.ViewComponents;
|
using WebfrontCore.ViewComponents;
|
||||||
|
using static SharedLibraryCore.Objects.Penalty;
|
||||||
|
|
||||||
namespace WebfrontCore.Controllers
|
namespace WebfrontCore.Controllers
|
||||||
{
|
{
|
||||||
public class PenaltyController : BaseController
|
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.Description = "List of all the recent penalties (bans, kicks, warnings) on IW4MAdmin";
|
||||||
ViewBag.Title = Localization["WEBFRONT_PENALTY_TITLE"];
|
ViewBag.Title = Localization["WEBFRONT_PENALTY_TITLE"];
|
||||||
@ -24,12 +25,12 @@ namespace WebfrontCore.Controllers
|
|||||||
return View((SharedLibraryCore.Objects.Penalty.PenaltyType)showOnly);
|
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()
|
return await Task.FromResult(View("_List", new ViewModels.PenaltyFilterInfo()
|
||||||
{
|
{
|
||||||
Offset = offset,
|
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.
|
// todo: this seems like it's pulling unnecessary info from LINQ to entities.
|
||||||
var iqPenalties = ctx.Penalties
|
var iqPenalties = ctx.Penalties
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.Where(p => p.Type == SharedLibraryCore.Objects.Penalty.PenaltyType.Ban && p.Active)
|
.Where(p => p.Type == PenaltyType.Ban && p.Active)
|
||||||
.OrderByDescending(_penalty => _penalty.When)
|
.OrderByDescending(_penalty => _penalty.When)
|
||||||
.Select(p => new PenaltyInfo()
|
.Select(p => new PenaltyInfo()
|
||||||
{
|
{
|
||||||
@ -61,9 +62,7 @@ namespace WebfrontCore.Controllers
|
|||||||
PunisherNetworkId = (ulong)p.Punisher.NetworkId,
|
PunisherNetworkId = (ulong)p.Punisher.NetworkId,
|
||||||
PunisherName = p.Punisher.CurrentAlias.Name,
|
PunisherName = p.Punisher.CurrentAlias.Name,
|
||||||
PunisherIPAddress = Authorized ? p.Punisher.CurrentAlias.IPAddress.ConvertIPtoString() : null,
|
PunisherIPAddress = Authorized ? p.Punisher.CurrentAlias.IPAddress.ConvertIPtoString() : null,
|
||||||
PenaltyType = p.Type.ToString(),
|
TimePunished = p.When,
|
||||||
TimePunished = p.When.ToString(),
|
|
||||||
TimeRemaining = null,
|
|
||||||
AutomatedOffense = Authorized ? p.AutomatedOffense : null,
|
AutomatedOffense = Authorized ? p.AutomatedOffense : null,
|
||||||
});
|
});
|
||||||
#if DEBUG == true
|
#if DEBUG == true
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using SharedLibraryCore;
|
|
||||||
using SharedLibraryCore.Database.Models;
|
|
||||||
using SharedLibraryCore.Dtos;
|
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
using System;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@ -11,42 +7,14 @@ namespace WebfrontCore.ViewComponents
|
|||||||
{
|
{
|
||||||
public class PenaltyListViewComponent : ViewComponent
|
public class PenaltyListViewComponent : ViewComponent
|
||||||
{
|
{
|
||||||
|
private const int PENALTY_COUNT = 15;
|
||||||
|
|
||||||
public async Task<IViewComponentResult> InvokeAsync(int offset, Penalty.PenaltyType showOnly)
|
public async Task<IViewComponentResult> InvokeAsync(int offset, Penalty.PenaltyType showOnly)
|
||||||
{
|
{
|
||||||
string showEvadeString(EFPenalty penalty) => penalty.IsEvadedOffense == true ?
|
var penalties = await Program.Manager.GetPenaltyService().GetRecentPenalties(PENALTY_COUNT, offset, showOnly);
|
||||||
$"({Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PENALTY_EVADE"]}) " : "";
|
penalties = User.Identity.IsAuthenticated ? penalties : penalties.Where(p => !p.Sensitive).ToList();
|
||||||
|
|
||||||
var penalties = await Program.Manager.GetPenaltyService().GetRecentPenalties(12, offset, showOnly);
|
return View("_List", penalties);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,22 +3,38 @@
|
|||||||
var loc = SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex;
|
var loc = SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="mr-auto ml-auto col-12 col-lg-7 border-bottom">
|
<div class="row d-none d-lg-block ">
|
||||||
<h4 class="pb-2 text-center ">@ViewBag.Title</h4>
|
<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="row pt-2 pb-2 bg-primary">
|
||||||
<div class="col-5 ">@loc["WEBFRONT_PENALTY_TEMPLATE_NAME"]</div>
|
<div class="col-5 ">@loc["WEBFRONT_PENALTY_TEMPLATE_NAME"]</div>
|
||||||
<div class="col-4">@loc["WEBFRONT_PROFILE_LEVEL"]</div>
|
<div class="col-4">@loc["WEBFRONT_PROFILE_LEVEL"]</div>
|
||||||
<div class="col-3 text-right">@loc["WEBFRONT_PROFILE_LSEEN"]</div>
|
<div class="col-3 text-right">@loc["WEBFRONT_SEARCH_LAST_CONNECTED"]</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@{
|
@foreach (var client in Model)
|
||||||
foreach (var client in Model)
|
|
||||||
{
|
{
|
||||||
<div class="row pt-2 pb-2 bg-dark">
|
<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-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-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>
|
||||||
|
<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>
|
</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;
|
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">
|
<div class="row">
|
||||||
<select class="form-control bg-dark text-muted" id="penalty_filter_selection">
|
<select class="form-control bg-dark text-muted" id="penalty_filter_selection">
|
||||||
@{
|
@{
|
||||||
@ -36,7 +36,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<table class="table table-striped">
|
<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">
|
<tr class="bg-primary pt-2 pb-2">
|
||||||
<th scope="col">@loc["WEBFRONT_PENALTY_TEMPLATE_NAME"]</th>
|
<th scope="col">@loc["WEBFRONT_PENALTY_TEMPLATE_NAME"]</th>
|
||||||
<th scope="col">@loc["WEBFRONT_PENALTY_TEMPLATE_TYPE"]</th>
|
<th scope="col">@loc["WEBFRONT_PENALTY_TEMPLATE_TYPE"]</th>
|
||||||
@ -53,10 +53,10 @@
|
|||||||
})
|
})
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<table class="table d-table d-md-none">
|
<table class="table d-table d-lg-none">
|
||||||
<tbody></tbody>
|
<tbody></tbody>
|
||||||
</table>
|
</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>
|
</div>
|
||||||
|
|
||||||
@section scripts {
|
@section scripts {
|
||||||
|
@ -5,72 +5,72 @@
|
|||||||
|
|
||||||
@model SharedLibraryCore.Dtos.PenaltyInfo
|
@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>
|
<th scope="row" class="bg-primary">@loc["WEBFRONT_PENALTY_TEMPLATE_NAME"]</th>
|
||||||
<td>
|
<td>
|
||||||
@Html.ActionLink(Model.OffenderName, "ProfileAsync", "Client", new { id = Model.OffenderId }, new { @class = "link-inverse" })
|
@Html.ActionLink(Model.OffenderName, "ProfileAsync", "Client", new { id = Model.OffenderId }, new { @class = "link-inverse" })
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</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>
|
<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
|
@Model.PenaltyType
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</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>
|
<th scope="row" class="bg-primary">@loc["WEBFRONT_PENALTY_TEMPLATE_OFFENSE"]</th>
|
||||||
<td class="text-light">
|
<td class="text-light">
|
||||||
@Model.Offense
|
@($"{Model.Offense}{(ViewBag.Authorized ? Model.AdditionalPenaltyInformation : "")}")
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</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>
|
<th scope="row" class="bg-primary">@loc["WEBFRONT_PENALTY_TEMPLATE_ADMIN"]</th>
|
||||||
<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>
|
||||||
</tr>
|
</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>
|
<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">
|
<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
|
else
|
||||||
{
|
{
|
||||||
<span> @Model.TimeRemaining</span>
|
<span>@Model.TimeRemaining</span>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr class="d-none d-md-table-row">
|
<tr class="d-none d-lg-table-row">
|
||||||
<td>
|
<td>
|
||||||
@Html.ActionLink(Model.OffenderName, "ProfileAsync", "Client", new { id = Model.OffenderId }, new { @class = "link-inverse" })
|
@Html.ActionLink(Model.OffenderName, "ProfileAsync", "Client", new { id = Model.OffenderId }, new { @class = "link-inverse" })
|
||||||
</td>
|
</td>
|
||||||
<td class="penalties-color-@Model.PenaltyType.ToLower()">
|
<td class="penalties-color-@Model.PenaltyTypeText.ToLower()">
|
||||||
@Model.PenaltyType
|
@Model.PenaltyType
|
||||||
</td>
|
</td>
|
||||||
<td class="text-light w-50">
|
<td class="text-light w-50">
|
||||||
@Model.Offense
|
@($"{Model.Offense}{(ViewBag.Authorized ? Model.AdditionalPenaltyInformation : "")}")
|
||||||
</td>
|
</td>
|
||||||
<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>
|
||||||
<td class="text-right text-light">
|
<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
|
else
|
||||||
{
|
{
|
||||||
<span> @Model.TimeRemaining </span>
|
<span>@Model.TimeRemaining</span>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
|
@ -9,24 +9,24 @@
|
|||||||
var penalty = meta.Value as SharedLibraryCore.Dtos.PenaltyInfo;
|
var penalty = meta.Value as SharedLibraryCore.Dtos.PenaltyInfo;
|
||||||
|
|
||||||
string localizationKey = meta.Type == SharedLibraryCore.Dtos.ProfileMeta.MetaType.Penalized ?
|
string localizationKey = meta.Type == SharedLibraryCore.Dtos.ProfileMeta.MetaType.Penalized ?
|
||||||
$"WEBFRONT_CLIENT_META_PENALIZED_{penalty.PenaltyType.ToUpper()}" :
|
$"WEBFRONT_CLIENT_META_PENALIZED_{penalty.PenaltyTypeText.ToUpper()}" :
|
||||||
$"WEBFRONT_CLIENT_META_WAS_PENALIZED_{penalty.PenaltyType.ToUpper()}";
|
$"WEBFRONT_CLIENT_META_WAS_PENALIZED_{penalty.PenaltyTypeText.ToUpper()}";
|
||||||
|
|
||||||
string localizationMessage = SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex[localizationKey];
|
string localizationMessage = SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex[localizationKey];
|
||||||
var regexMatch = System.Text.RegularExpressions.Regex.Match(localizationMessage, @"^.*{{([^{}]+)}}.+$");
|
var regexMatch = System.Text.RegularExpressions.Regex.Match(localizationMessage, @"^.*{{([^{}]+)}}.+$");
|
||||||
string penaltyType = regexMatch.Groups[1].Value.ToString();
|
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 ?
|
return meta.Type == SharedLibraryCore.Dtos.ProfileMeta.MetaType.Penalized ?
|
||||||
string.Format(localizationMessage,
|
string.Format(localizationMessage,
|
||||||
$"<span class='text-highlight'><a class='link-inverse' href='{penalty.OffenderId}'>{penalty.OffenderName}</a></span>",
|
$"<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("{", "")
|
||||||
.Replace("}", "") :
|
.Replace("}", "") :
|
||||||
string.Format(localizationMessage,
|
string.Format(localizationMessage,
|
||||||
$"<span class='text-highlight'><a class='link-inverse' href='{penalty.PunisherId}'>{penalty.PunisherName}</a></span>",
|
$"<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)
|
penalty.Offense)
|
||||||
.Replace("{", "")
|
.Replace("{", "")
|
||||||
.Replace("}", "");
|
.Replace("}", "");
|
||||||
@ -55,7 +55,7 @@
|
|||||||
case SharedLibraryCore.Dtos.ProfileMeta.MetaType.ChatMessage:
|
case SharedLibraryCore.Dtos.ProfileMeta.MetaType.ChatMessage:
|
||||||
<div class="profile-meta-entry loader-data-time" data-time="@meta.When">
|
<div class="profile-meta-entry loader-data-time" data-time="@meta.When">
|
||||||
<span style="color:white;">></span>
|
<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>
|
</div>
|
||||||
break;
|
break;
|
||||||
case SharedLibraryCore.Dtos.ProfileMeta.MetaType.ReceivedPenalty:
|
case SharedLibraryCore.Dtos.ProfileMeta.MetaType.ReceivedPenalty:
|
||||||
|
@ -6318,6 +6318,10 @@ a.link-inverse:hover {
|
|||||||
.d-md-table-header-group {
|
.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; } }
|
||||||
|
|
||||||
#console_command_response {
|
#console_command_response {
|
||||||
min-height: 20rem; }
|
min-height: 20rem; }
|
||||||
|
|
||||||
|
@ -88,7 +88,13 @@ a.link-inverse:hover {
|
|||||||
|
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
.d-md-table-header-group {
|
.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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user