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"]);
}

View File

@ -389,58 +389,55 @@ namespace IW4MAdmin.Application
}
}
public void Start()
public async Task Start()
{
#if !DEBUG
// start heartbeat
HeartbeatTimer = new Timer(SendHeartbeat, new HeartbeatState(), 0, 30000);
#endif
// start polling servers
// StatusUpdateTimer = new Timer(UpdateStatus, null, 0, 5000);
// this needs to be run seperately from the main thread
Task.Run(() => UpdateStatus(null));
GameEvent newEvent;
Task.Run(async () =>
while (Running)
{
while (Running)
// wait for new event to be added
OnEvent.Wait();
// todo: sequencially or parallelize?
while ((newEvent = Handler.GetNextEvent()) != null)
{
// wait for new event to be added
OnEvent.Wait();
// todo: sequencially or parallelize?
while ((newEvent = Handler.GetNextEvent()) != null)
try
{
try
{
await newEvent.Owner.ExecuteEvent(newEvent);
await newEvent.Owner.ExecuteEvent(newEvent);
#if DEBUG
Logger.WriteDebug("Processed Event");
Logger.WriteDebug("Processed Event");
#endif
}
catch (Exception E)
{
Logger.WriteError($"{Utilities.CurrentLocalization.LocalizationSet["SERVER_ERROR_EXCEPTION"]} {newEvent.Owner}");
Logger.WriteDebug("Error Message: " + E.Message);
Logger.WriteDebug("Error Trace: " + E.StackTrace);
newEvent.OnProcessed.Set();
continue;
}
// tell anyone waiting for the output that we're done
newEvent.OnProcessed.Set();
}
// signal that all events have been processed
OnEvent.Reset();
catch (Exception E)
{
Logger.WriteError($"{Utilities.CurrentLocalization.LocalizationSet["SERVER_ERROR_EXCEPTION"]} {newEvent.Owner}");
Logger.WriteDebug("Error Message: " + E.Message);
Logger.WriteDebug("Error Trace: " + E.StackTrace);
newEvent.OnProcessed.Set();
continue;
}
// tell anyone waiting for the output that we're done
newEvent.OnProcessed.Set();
}
// signal that all events have been processed
OnEvent.Reset();
}
#if !DEBUG
HeartbeatTimer.Change(0, Timeout.Infinite);
foreach (var S in Servers)
S.Broadcast(Utilities.CurrentLocalization.LocalizationSet["BROADCAST_OFFLINE"]).Wait();
#endif
_servers.Clear();
}).Wait();
_servers.Clear();
}

View File

@ -36,7 +36,7 @@ namespace IW4MAdmin
// todo: make this better with collisions
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)
{
case 765:
@ -455,7 +455,7 @@ namespace IW4MAdmin
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)
@ -483,17 +483,12 @@ namespace IW4MAdmin
Logger.WriteWarning("Requested event (command) requiring target does not have a target!");
}
Manager.GetEventHandler().AddEvent(new GameEvent()
{
Type = GameEvent.EventType.Command,
Data = E.Data,
Origin = E.Origin,
Target = E.Target,
Owner = this,
Extra = C,
Remote = E.Remote,
Message = E.Message
});
E.Extra = C;
// reprocess event as a command
Manager.GetEventHandler().AddEvent(GameEvent.TranferWaiter(GameEvent.EventType.Command, E));
}
}
@ -988,6 +983,8 @@ namespace IW4MAdmin
};
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)

View File

@ -103,8 +103,8 @@ namespace IW4MAdmin.Plugins.Stats
int kills = clientStats.Sum(c => c.Kills);
int deaths = clientStats.Sum(c => c.Deaths);
double kdr = Math.Round(kills / (double)deaths, 2);
double skill = Math.Round(clientStats.Sum(c => c.Skill) / clientStats.Count, 2);
double spm = Math.Round(clientStats.Sum(c => c.SPM), 1);
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) / clientStats.Where(c => c.SPM > 0).Count(), 1);
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()
.FirstOrDefault(p => p.NetworkId == E.Target.NetworkId);
@ -465,6 +465,7 @@ namespace SharedLibraryCore.Commands
catch (Exception)
{
// this updates their privilege level to the webfront claims
E.Owner.Manager.GetPrivilegedClients()[E.Target.ClientId] = E.Target;
}

View File

@ -55,6 +55,27 @@ namespace SharedLibraryCore
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 string Data; // Data is usually the message sent by player
public string Message;
@ -63,6 +84,6 @@ namespace SharedLibraryCore
public Server Owner;
public Boolean Remote = false;
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
{
Task Init();
void Start();
Task Start();
void Stop();
ILogger GetLogger();
IList<Server> GetServers();

View File

@ -255,7 +255,7 @@ namespace SharedLibraryCore.RCon
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())
{
context.ChangeTracker.AutoDetectChangesEnabled = false;
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
if (victim)
{
context.ChangeTracker.AutoDetectChangesEnabled = false;
var now = DateTime.UtcNow;
var iqPenalties = from penalty in context.Penalties.AsNoTracking()
where penalty.OffenderId == clientId
@ -163,20 +164,21 @@ namespace SharedLibraryCore.Services
TimeRemaining = now > penalty.Expires ? "" : penalty.Expires.ToString()
},
When = penalty.When,
Sensitive = penalty.Type == Objects.Penalty.PenaltyType.Flag
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).Type.Length < 2)
((PenaltyInfo)p.Value).Type = ((Penalty.PenaltyType)Convert.ToInt32(((PenaltyInfo)p.Value).Type)).ToString();
var pi = ((PenaltyInfo)p.Value);
if (pi.TimeRemaining.Length > 0)
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;
}
@ -268,7 +270,7 @@ namespace SharedLibraryCore.Services
{
await internalContext.Clients
.Where(c => c.AliasLinkId == p.LinkId)
.ForEachAsync(c => c.Level = Objects.Player.Permission.User);
.ForEachAsync(c => c.Level = Player.Permission.User);
await internalContext.SaveChangesAsync();
}

View File

@ -325,7 +325,9 @@ namespace SharedLibraryCore
LastConnection = client.LastConnection == DateTime.MinValue ? DateTime.UtcNow : client.LastConnection,
CurrentAlias = client.CurrentAlias,
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.Linq;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
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.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 };
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 (System.Collections.Generic.KeyNotFoundException)
{
// force the "banned" client to be signed out
HttpContext.SignOutAsync().Wait();
}
}
else

View File

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