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:
parent
bb90a807b7
commit
8071fb37bc
@ -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"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,58 +389,55 @@ 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
|
||||||
|
OnEvent.Wait();
|
||||||
|
|
||||||
|
// todo: sequencially or parallelize?
|
||||||
|
while ((newEvent = Handler.GetNextEvent()) != null)
|
||||||
{
|
{
|
||||||
// wait for new event to be added
|
try
|
||||||
OnEvent.Wait();
|
|
||||||
|
|
||||||
// todo: sequencially or parallelize?
|
|
||||||
while ((newEvent = Handler.GetNextEvent()) != null)
|
|
||||||
{
|
{
|
||||||
try
|
await newEvent.Owner.ExecuteEvent(newEvent);
|
||||||
{
|
|
||||||
await newEvent.Owner.ExecuteEvent(newEvent);
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
Logger.WriteDebug("Processed Event");
|
Logger.WriteDebug("Processed Event");
|
||||||
#endif
|
#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
|
catch (Exception E)
|
||||||
OnEvent.Reset();
|
{
|
||||||
|
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
|
#if !DEBUG
|
||||||
HeartbeatTimer.Change(0, Timeout.Infinite);
|
HeartbeatTimer.Change(0, Timeout.Infinite);
|
||||||
|
|
||||||
foreach (var S in Servers)
|
foreach (var S in Servers)
|
||||||
S.Broadcast(Utilities.CurrentLocalization.LocalizationSet["BROADCAST_OFFLINE"]).Wait();
|
S.Broadcast(Utilities.CurrentLocalization.LocalizationSet["BROADCAST_OFFLINE"]).Wait();
|
||||||
#endif
|
#endif
|
||||||
_servers.Clear();
|
_servers.Clear();
|
||||||
}).Wait();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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>()
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user