SPM and skill is rounded in profile now

fixed web console not waiting for reponse
fixed password not saving over time
web users level update properly now when promoted/demoted
This commit is contained in:
RaidMax 2018-04-28 16:39:45 -05:00
parent bb90a807b7
commit 8071fb37bc
12 changed files with 94 additions and 59 deletions

View File

@ -156,7 +156,7 @@ namespace IW4MAdmin.Application
} }
ServerManager.Start(); ServerManager.Start().Wait();
ServerManager.Logger.WriteVerbose(loc["MANAGER_SHUTDOWN_SUCCESS"]); ServerManager.Logger.WriteVerbose(loc["MANAGER_SHUTDOWN_SUCCESS"]);
} }

View File

@ -389,19 +389,17 @@ namespace IW4MAdmin.Application
} }
} }
public void Start() public async Task Start()
{ {
#if !DEBUG #if !DEBUG
// start heartbeat // start heartbeat
HeartbeatTimer = new Timer(SendHeartbeat, new HeartbeatState(), 0, 30000); HeartbeatTimer = new Timer(SendHeartbeat, new HeartbeatState(), 0, 30000);
#endif #endif
// start polling servers // this needs to be run seperately from the main thread
// StatusUpdateTimer = new Timer(UpdateStatus, null, 0, 5000);
Task.Run(() => UpdateStatus(null)); Task.Run(() => UpdateStatus(null));
GameEvent newEvent; GameEvent newEvent;
Task.Run(async () =>
{
while (Running) while (Running)
{ {
// wait for new event to be added // wait for new event to be added
@ -440,7 +438,6 @@ namespace IW4MAdmin.Application
S.Broadcast(Utilities.CurrentLocalization.LocalizationSet["BROADCAST_OFFLINE"]).Wait(); S.Broadcast(Utilities.CurrentLocalization.LocalizationSet["BROADCAST_OFFLINE"]).Wait();
#endif #endif
_servers.Clear(); _servers.Clear();
}).Wait();
} }

View File

@ -36,7 +36,7 @@ namespace IW4MAdmin
// todo: make this better with collisions // todo: make this better with collisions
int id = Math.Abs($"{IP}:{Port.ToString()}".Select(a => (int)a).Sum()); int id = Math.Abs($"{IP}:{Port.ToString()}".Select(a => (int)a).Sum());
// this is a nasty fix for get hashcode being changed // hack: this is a nasty fix for get hashcode being changed
switch (id) switch (id)
{ {
case 765: case 765:
@ -455,7 +455,7 @@ namespace IW4MAdmin
else if (E.Type == GameEvent.EventType.Script) else if (E.Type == GameEvent.EventType.Script)
{ {
Manager.GetEventHandler().AddEvent(new GameEvent(GameEvent.EventType.Kill, E.Data, E.Origin, E.Target, this)); Manager.GetEventHandler().AddEvent(GameEvent.TranferWaiter(GameEvent.EventType.Kill, E));
} }
if (E.Type == GameEvent.EventType.Say && E.Data.Length >= 2) if (E.Type == GameEvent.EventType.Say && E.Data.Length >= 2)
@ -483,17 +483,12 @@ namespace IW4MAdmin
Logger.WriteWarning("Requested event (command) requiring target does not have a target!"); Logger.WriteWarning("Requested event (command) requiring target does not have a target!");
} }
Manager.GetEventHandler().AddEvent(new GameEvent() E.Extra = C;
{
Type = GameEvent.EventType.Command,
Data = E.Data,
Origin = E.Origin, // reprocess event as a command
Target = E.Target, Manager.GetEventHandler().AddEvent(GameEvent.TranferWaiter(GameEvent.EventType.Command, E));
Owner = this,
Extra = C,
Remote = E.Remote,
Message = E.Message
});
} }
} }
@ -988,6 +983,8 @@ namespace IW4MAdmin
}; };
await Manager.GetPenaltyService().Create(newPenalty); await Manager.GetPenaltyService().Create(newPenalty);
// prevent them from logging in again
Manager.GetPrivilegedClients().Remove(Target.ClientId);
} }
override public async Task Unban(string reason, Player Target, Player Origin) override public async Task Unban(string reason, Player Target, Player Origin)

View File

@ -103,8 +103,8 @@ namespace IW4MAdmin.Plugins.Stats
int kills = clientStats.Sum(c => c.Kills); int kills = clientStats.Sum(c => c.Kills);
int deaths = clientStats.Sum(c => c.Deaths); int deaths = clientStats.Sum(c => c.Deaths);
double kdr = Math.Round(kills / (double)deaths, 2); double kdr = Math.Round(kills / (double)deaths, 2);
double skill = Math.Round(clientStats.Sum(c => c.Skill) / clientStats.Count, 2); double skill = Math.Round(clientStats.Sum(c => c.Skill) / clientStats.Where(c => c.Skill > 0).Count(), 2);
double spm = Math.Round(clientStats.Sum(c => c.SPM), 1); double spm = Math.Round(clientStats.Sum(c => c.SPM) / clientStats.Where(c => c.SPM > 0).Count(), 1);
return new List<ProfileMeta>() return new List<ProfileMeta>()
{ {

View File

@ -441,7 +441,7 @@ namespace SharedLibraryCore.Commands
} }
} }
if (newPerm > Player.Permission.Banned) else if (newPerm > Player.Permission.Banned)
{ {
var ActiveClient = E.Owner.Manager.GetActiveClients() var ActiveClient = E.Owner.Manager.GetActiveClients()
.FirstOrDefault(p => p.NetworkId == E.Target.NetworkId); .FirstOrDefault(p => p.NetworkId == E.Target.NetworkId);
@ -465,6 +465,7 @@ namespace SharedLibraryCore.Commands
catch (Exception) catch (Exception)
{ {
// this updates their privilege level to the webfront claims
E.Owner.Manager.GetPrivilegedClients()[E.Target.ClientId] = E.Target; E.Owner.Manager.GetPrivilegedClients()[E.Target.ClientId] = E.Target;
} }

View File

@ -55,6 +55,27 @@ namespace SharedLibraryCore
OnProcessed = new ManualResetEventSlim(); OnProcessed = new ManualResetEventSlim();
} }
public static GameEvent TranferWaiter(EventType newType, GameEvent e)
{
var newEvent = new GameEvent()
{
Data = e.Data,
Extra = e.Extra,
Message = e.Message,
OnProcessed = e.OnProcessed,
Origin = e.Origin,
Owner = e.Owner,
Remote = e.Remote,
Target = e.Target,
Type = newType
};
// hack: prevent the previous event from completing until this one is done
e.OnProcessed = new ManualResetEventSlim();
return newEvent;
}
public EventType Type; public EventType Type;
public string Data; // Data is usually the message sent by player public string Data; // Data is usually the message sent by player
public string Message; public string Message;
@ -63,6 +84,6 @@ namespace SharedLibraryCore
public Server Owner; public Server Owner;
public Boolean Remote = false; public Boolean Remote = false;
public object Extra { get; set; } public object Extra { get; set; }
public ManualResetEventSlim OnProcessed { get; private set; } public ManualResetEventSlim OnProcessed { get; set; }
} }
} }

View File

@ -10,7 +10,7 @@ namespace SharedLibraryCore.Interfaces
public interface IManager public interface IManager
{ {
Task Init(); Task Init();
void Start(); Task Start();
void Stop(); void Stop();
ILogger GetLogger(); ILogger GetLogger();
IList<Server> GetServers(); IList<Server> GetServers();

View File

@ -255,7 +255,7 @@ namespace SharedLibraryCore.RCon
if (FailedReceives >= 4) if (FailedReceives >= 4)
{ {
throw new NetworkException($"Could not receive data from the {ServerConnection.RemoteEndPoint}"); throw new NetworkException($"Could not receive data from {ServerConnection.RemoteEndPoint}");
} }
} }

View File

@ -134,9 +134,10 @@ namespace SharedLibraryCore.Services
{ {
using (var context = new DatabaseContext()) using (var context = new DatabaseContext())
{ {
context.ChangeTracker.AutoDetectChangesEnabled = false;
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
if (victim) if (victim)
{ {
context.ChangeTracker.AutoDetectChangesEnabled = false;
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
var iqPenalties = from penalty in context.Penalties.AsNoTracking() var iqPenalties = from penalty in context.Penalties.AsNoTracking()
where penalty.OffenderId == clientId where penalty.OffenderId == clientId
@ -163,20 +164,21 @@ namespace SharedLibraryCore.Services
TimeRemaining = now > penalty.Expires ? "" : penalty.Expires.ToString() TimeRemaining = now > penalty.Expires ? "" : penalty.Expires.ToString()
}, },
When = penalty.When, When = penalty.When,
Sensitive = penalty.Type == Objects.Penalty.PenaltyType.Flag Sensitive = penalty.Type == Penalty.PenaltyType.Flag
}; };
// fixme: is this good and fast? // fixme: is this good and fast?
var list = await iqPenalties.ToListAsync(); var list = await iqPenalties.ToListAsync();
list.ForEach(p => list.ForEach(p =>
{ {
// todo: why does this have to be done?
if (((PenaltyInfo)p.Value).Type.Length < 2)
((PenaltyInfo)p.Value).Type = ((Penalty.PenaltyType)Convert.ToInt32(((PenaltyInfo)p.Value).Type)).ToString();
var pi = ((PenaltyInfo)p.Value); var pi = ((PenaltyInfo)p.Value);
if (pi.TimeRemaining.Length > 0) if (pi.TimeRemaining.Length > 0)
pi.TimeRemaining = (DateTime.Parse(((PenaltyInfo)p.Value).TimeRemaining) - now).TimeSpanText(); pi.TimeRemaining = (DateTime.Parse(((PenaltyInfo)p.Value).TimeRemaining) - now).TimeSpanText();
// todo: why does this have to be done?
if (pi.Type.Length > 2) });
pi.Type = ((Penalty.PenaltyType)Convert.ToInt32(pi.Type)).ToString();
}
);
return list; return list;
} }
@ -268,7 +270,7 @@ namespace SharedLibraryCore.Services
{ {
await internalContext.Clients await internalContext.Clients
.Where(c => c.AliasLinkId == p.LinkId) .Where(c => c.AliasLinkId == p.LinkId)
.ForEachAsync(c => c.Level = Objects.Player.Permission.User); .ForEachAsync(c => c.Level = Player.Permission.User);
await internalContext.SaveChangesAsync(); await internalContext.SaveChangesAsync();
} }

View File

@ -325,7 +325,9 @@ namespace SharedLibraryCore
LastConnection = client.LastConnection == DateTime.MinValue ? DateTime.UtcNow : client.LastConnection, LastConnection = client.LastConnection == DateTime.MinValue ? DateTime.UtcNow : client.LastConnection,
CurrentAlias = client.CurrentAlias, CurrentAlias = client.CurrentAlias,
CurrentAliasId = client.CurrentAlias.AliasId, CurrentAliasId = client.CurrentAlias.AliasId,
IsBot = client.NetworkId == -1 IsBot = client.NetworkId == -1,
Password = client.Password,
PasswordSalt = client.PasswordSalt
}; };
} }

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
@ -47,12 +48,25 @@ namespace WebfrontCore.Controllers
Client.ClientId = Convert.ToInt32(base.User.Claims.First(c => c.Type == ClaimTypes.Sid).Value); Client.ClientId = Convert.ToInt32(base.User.Claims.First(c => c.Type == ClaimTypes.Sid).Value);
Client.Level = (Player.Permission)Enum.Parse(typeof(Player.Permission), User.Claims.First(c => c.Type == ClaimTypes.Role).Value); Client.Level = (Player.Permission)Enum.Parse(typeof(Player.Permission), User.Claims.First(c => c.Type == ClaimTypes.Role).Value);
Client.CurrentAlias = new EFAlias() { Name = User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value }; Client.CurrentAlias = new EFAlias() { Name = User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value };
var stillExists = Manager.GetPrivilegedClients()[Client.ClientId];
// this happens if their level has been updated
if (stillExists.Level != Client.Level)
{
Client.Level = stillExists.Level;
}
} }
catch (InvalidOperationException) catch (InvalidOperationException)
{ {
} }
catch (System.Collections.Generic.KeyNotFoundException)
{
// force the "banned" client to be signed out
HttpContext.SignOutAsync().Wait();
}
} }
else else

View File

@ -48,6 +48,7 @@ namespace WebfrontCore.Controllers
Manager.GetEventHandler().AddEvent(remoteEvent); Manager.GetEventHandler().AddEvent(remoteEvent);
// wait for the event to process // wait for the event to process
await Task.Run(() => remoteEvent.OnProcessed.Wait()); await Task.Run(() => remoteEvent.OnProcessed.Wait());
var response = server.CommandResult.Where(c => c.ClientId == client.ClientId).ToList(); var response = server.CommandResult.Where(c => c.ClientId == client.ClientId).ToList();