More work modifying client stuff
This commit is contained in:
parent
ed83c4c011
commit
9bdd7d1b8a
@ -1,83 +0,0 @@
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Interfaces;
|
||||
using SharedLibraryCore.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace IW4MAdmin.Application.Core
|
||||
{
|
||||
class ClientAuthentication : IClientAuthentication
|
||||
{
|
||||
private Queue<EFClient> ClientAuthenticationQueue;
|
||||
private Dictionary<long, EFClient> AuthenticatedClients;
|
||||
|
||||
public ClientAuthentication()
|
||||
{
|
||||
ClientAuthenticationQueue = new Queue<EFClient>();
|
||||
AuthenticatedClients = new Dictionary<long, EFClient>();
|
||||
}
|
||||
|
||||
public void AuthenticateClients(IList<EFClient> clients)
|
||||
{
|
||||
// we need to un-auth all the clients that have disconnected
|
||||
var clientNetworkIds = clients.Select(c => c.NetworkId);
|
||||
var clientsToRemove = AuthenticatedClients.Keys.Where(c => !clientNetworkIds.Contains(c));
|
||||
// remove them
|
||||
foreach (long Id in clientsToRemove.ToList())
|
||||
{
|
||||
AuthenticatedClients.Remove(Id);
|
||||
}
|
||||
|
||||
// loop through the polled clients to see if they've been authenticated yet
|
||||
foreach (var client in clients)
|
||||
{
|
||||
// they've not been authenticated
|
||||
if (!AuthenticatedClients.TryGetValue(client.NetworkId, out EFClient value))
|
||||
{
|
||||
// authenticate them
|
||||
client.State = EFClient.ClientState.Authenticated;
|
||||
AuthenticatedClients.Add(client.NetworkId, client);
|
||||
}
|
||||
else
|
||||
{
|
||||
// this update their ping
|
||||
// todo: this seems kinda hacky
|
||||
value.Ping = client.Ping;
|
||||
value.Score = client.Score;
|
||||
}
|
||||
}
|
||||
|
||||
// empty out the queue of clients detected through log
|
||||
while (ClientAuthenticationQueue.Count > 0)
|
||||
{
|
||||
// grab each client that's connected via log
|
||||
var clientToAuthenticate = ClientAuthenticationQueue.Dequeue();
|
||||
// if they're not already authed, auth them
|
||||
if (!AuthenticatedClients.TryGetValue(clientToAuthenticate.NetworkId, out EFClient value))
|
||||
{
|
||||
// authenticate them
|
||||
clientToAuthenticate.State = EFClient.ClientState.Authenticated;
|
||||
AuthenticatedClients.Add(clientToAuthenticate.NetworkId, clientToAuthenticate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IList<EFClient> GetAuthenticatedClients()
|
||||
{
|
||||
if (AuthenticatedClients.Values.Count > 18)
|
||||
{
|
||||
Program.ServerManager.GetLogger(0).WriteError($"auth client count is {AuthenticatedClients.Values.Count}, this is bad");
|
||||
return AuthenticatedClients.Values.Take(18).ToList();
|
||||
}
|
||||
|
||||
return AuthenticatedClients.Values.ToList();
|
||||
}
|
||||
|
||||
public void RequestClientAuthentication(EFClient client)
|
||||
{
|
||||
ClientAuthenticationQueue.Enqueue(client);
|
||||
}
|
||||
}
|
||||
}
|
@ -144,7 +144,7 @@ namespace IW4MAdmin.Application.EventParsers
|
||||
{
|
||||
return new GameEvent()
|
||||
{
|
||||
Type = GameEvent.EventType.Join,
|
||||
Type = GameEvent.EventType.PreConnect,
|
||||
Data = logLine,
|
||||
Owner = server,
|
||||
Origin = new EFClient()
|
||||
@ -159,26 +159,26 @@ namespace IW4MAdmin.Application.EventParsers
|
||||
}
|
||||
}
|
||||
|
||||
//if (eventType == "Q")
|
||||
//{
|
||||
// var regexMatch = Regex.Match(logLine, @"^(Q;)(.{1,32});([0-9]+);(.*)$");
|
||||
// if (regexMatch.Success)
|
||||
// {
|
||||
// return new GameEvent()
|
||||
// {
|
||||
// Type = GameEvent.EventType.Quit,
|
||||
// Data = logLine,
|
||||
// Owner = server,
|
||||
// Origin = new Player()
|
||||
// {
|
||||
// Name = regexMatch.Groups[4].ToString().StripColors(),
|
||||
// NetworkId = regexMatch.Groups[2].ToString().ConvertLong(),
|
||||
// ClientNumber = Convert.ToInt32(regexMatch.Groups[3].ToString()),
|
||||
// State = Player.ClientState.Connecting
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
//}
|
||||
if (eventType == "Q")
|
||||
{
|
||||
var regexMatch = Regex.Match(logLine, @"^(Q;)(.{1,32});([0-9]+);(.*)$");
|
||||
if (regexMatch.Success)
|
||||
{
|
||||
return new GameEvent()
|
||||
{
|
||||
Type = GameEvent.EventType.PreDisconnect,
|
||||
Data = logLine,
|
||||
Owner = server,
|
||||
Origin = new EFClient()
|
||||
{
|
||||
Name = regexMatch.Groups[4].ToString().StripColors(),
|
||||
NetworkId = regexMatch.Groups[2].ToString().ConvertLong(),
|
||||
ClientNumber = Convert.ToInt32(regexMatch.Groups[3].ToString()),
|
||||
State = EFClient.ClientState.Disconnecting
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (eventType.Contains("ExitLevel"))
|
||||
{
|
||||
@ -186,14 +186,8 @@ namespace IW4MAdmin.Application.EventParsers
|
||||
{
|
||||
Type = GameEvent.EventType.MapEnd,
|
||||
Data = lineSplit[0],
|
||||
Origin = new EFClient()
|
||||
{
|
||||
ClientId = 1
|
||||
},
|
||||
Target = new EFClient()
|
||||
{
|
||||
ClientId = 1
|
||||
},
|
||||
Origin = Utilities.IW4MAdminClient(server),
|
||||
Target = Utilities.IW4MAdminClient(server),
|
||||
Owner = server
|
||||
};
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ namespace IW4MAdmin.Application.EventParsers
|
||||
|
||||
return new GameEvent()
|
||||
{
|
||||
Type = GameEvent.EventType.Join,
|
||||
Type = GameEvent.EventType.PreConnect,
|
||||
Origin = new EFClient()
|
||||
{
|
||||
ClientId = 1
|
||||
|
@ -79,6 +79,7 @@ namespace IW4MAdmin.Application.IO
|
||||
foreach (var ev in events)
|
||||
{
|
||||
Server.Manager.GetEventHandler().AddEvent(ev);
|
||||
await ev.WaitAsync();
|
||||
}
|
||||
|
||||
PreviousFileSize = fileSize;
|
||||
|
@ -32,6 +32,7 @@ namespace IW4MAdmin
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
// hack: my laziness
|
||||
if ($"{IP}:{Port.ToString()}" == "66.150.121.184:28965")
|
||||
{
|
||||
return 886229536;
|
||||
@ -56,16 +57,6 @@ namespace IW4MAdmin
|
||||
return Id;
|
||||
}
|
||||
|
||||
public async Task OnClientJoined(EFClient polledClient)
|
||||
{
|
||||
var existingClient = Clients[polledClient.ClientNumber];
|
||||
|
||||
if (existingClient != null)
|
||||
{
|
||||
await existingClient.OnJoin(polledClient.IPAddress);
|
||||
}
|
||||
}
|
||||
|
||||
override public async Task OnClientConnected(EFClient clientFromLog)
|
||||
{
|
||||
Logger.WriteDebug($"Client slot #{clientFromLog.ClientNumber} now reserved");
|
||||
@ -119,40 +110,49 @@ namespace IW4MAdmin
|
||||
Clients[client.ClientNumber] = client;
|
||||
client.OnConnect();
|
||||
|
||||
// this only happens the preconnect event occurred from RCon polling
|
||||
if (clientFromLog.IPAddress != 0)
|
||||
{
|
||||
await client.OnJoin(clientFromLog.IPAddress);
|
||||
}
|
||||
|
||||
client.State = EFClient.ClientState.Connected;
|
||||
#if DEBUG == true
|
||||
Logger.WriteDebug($"End PreConnect for {client}");
|
||||
#endif
|
||||
var e = new GameEvent()
|
||||
{
|
||||
Origin = client,
|
||||
Owner = this,
|
||||
Type = GameEvent.EventType.Connect
|
||||
};
|
||||
|
||||
Manager.GetEventHandler().AddEvent(e);
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteError($"{loc["SERVER_ERROR_ADDPLAYER"]} {clientFromLog.Name}::{clientFromLog.NetworkId}");
|
||||
Logger.WriteDebug(ex.Message);
|
||||
Logger.WriteDebug(ex.StackTrace);
|
||||
Logger.WriteError($"{loc["SERVER_ERROR_ADDPLAYER"]} {clientFromLog}");
|
||||
Logger.WriteError(ex.GetExceptionInfo());
|
||||
}
|
||||
}
|
||||
|
||||
//Remove player by CLIENT NUMBER
|
||||
override public async Task RemoveClient(int cNum)
|
||||
override public async Task OnClientDisconnected(EFClient client)
|
||||
{
|
||||
if (cNum >= 0 && Clients[cNum] != null)
|
||||
Logger.WriteInfo($"Client {client} [{client.State.ToString().ToLower()}] disconnecting...");
|
||||
await client.OnDisconnect();
|
||||
Clients[client.ClientNumber] = null;
|
||||
#if DEBUG == true
|
||||
Logger.WriteDebug($"End PreDisconnect for {client}");
|
||||
#endif
|
||||
var e = new GameEvent()
|
||||
{
|
||||
EFClient Leaving = Clients[cNum];
|
||||
Origin = client,
|
||||
Owner = this,
|
||||
Type = GameEvent.EventType.Disconnect
|
||||
};
|
||||
|
||||
// occurs when the player disconnects via log before being authenticated by RCon
|
||||
if (Leaving.State != EFClient.ClientState.Connected)
|
||||
{
|
||||
Clients[cNum] = null;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
Logger.WriteInfo($"Client {Leaving} [{Leaving.State.ToString().ToLower()}] disconnecting...");
|
||||
Leaving.State = EFClient.ClientState.Disconnecting;
|
||||
Leaving.TotalConnectionTime += Leaving.ConnectionLength;
|
||||
Leaving.LastConnection = DateTime.UtcNow;
|
||||
await Manager.GetClientService().Update(Leaving);
|
||||
Clients[cNum] = null;
|
||||
}
|
||||
}
|
||||
Manager.GetEventHandler().AddEvent(e);
|
||||
}
|
||||
|
||||
public override async Task ExecuteEvent(GameEvent E)
|
||||
@ -218,27 +218,34 @@ namespace IW4MAdmin
|
||||
/// <returns></returns>
|
||||
override protected async Task<bool> ProcessEvent(GameEvent E)
|
||||
{
|
||||
if (E.Type == GameEvent.EventType.Connect)
|
||||
if (E.Type == GameEvent.EventType.PreConnect)
|
||||
{
|
||||
E.Origin.State = EFClient.ClientState.Authenticated;
|
||||
await OnClientConnected(E.Origin);
|
||||
bool clientExists = GetClientsAsList().Exists(_client => _client.NetworkId.Equals(E.Origin));
|
||||
|
||||
ChatHistory.Add(new ChatInfo()
|
||||
if (!clientExists)
|
||||
{
|
||||
Name = E.Origin.Name,
|
||||
Message = "CONNECTED",
|
||||
Time = DateTime.UtcNow
|
||||
});
|
||||
#if DEBUG == true
|
||||
Logger.WriteDebug($"Begin PreConnect for {E.Origin}");
|
||||
#endif
|
||||
await OnClientConnected(E.Origin);
|
||||
|
||||
if (E.Origin.Level > EFClient.Permission.Moderator)
|
||||
{
|
||||
E.Origin.Tell(string.Format(loc["SERVER_REPORT_COUNT"], E.Owner.Reports.Count));
|
||||
ChatHistory.Add(new ChatInfo()
|
||||
{
|
||||
Name = E.Origin.Name,
|
||||
Message = "CONNECTED",
|
||||
Time = DateTime.UtcNow
|
||||
});
|
||||
|
||||
if (E.Origin.Level > EFClient.Permission.Moderator)
|
||||
{
|
||||
E.Origin.Tell(string.Format(loc["SERVER_REPORT_COUNT"], E.Owner.Reports.Count));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (E.Type == GameEvent.EventType.Join)
|
||||
{
|
||||
await OnClientJoined(E.Origin);
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
else if (E.Type == GameEvent.EventType.Flag)
|
||||
@ -303,13 +310,9 @@ namespace IW4MAdmin
|
||||
|
||||
else if (E.Type == GameEvent.EventType.Quit)
|
||||
{
|
||||
var origin = Clients.FirstOrDefault(p => p != null && p.NetworkId == E.Origin.NetworkId);
|
||||
var origin = GetClientsAsList().FirstOrDefault(_client => _client.NetworkId.Equals(E.Origin));
|
||||
|
||||
if (origin != null &&
|
||||
// we only want to forward the event if they are connected.
|
||||
origin.State == EFClient.ClientState.Connected &&
|
||||
// make sure we don't get the disconnect event from every time the game ends
|
||||
origin.ConnectionLength < Manager.GetApplicationSettings().Configuration().RConPollRate)
|
||||
if (origin != null)
|
||||
{
|
||||
var e = new GameEvent()
|
||||
{
|
||||
@ -321,29 +324,45 @@ namespace IW4MAdmin
|
||||
Manager.GetEventHandler().AddEvent(e);
|
||||
}
|
||||
|
||||
else if (origin != null &&
|
||||
origin.State != EFClient.ClientState.Connected)
|
||||
else
|
||||
{
|
||||
await RemoveClient(origin.ClientNumber);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
else if (E.Type == GameEvent.EventType.Disconnect)
|
||||
else if (E.Type == GameEvent.EventType.PreDisconnect)
|
||||
{
|
||||
ChatHistory.Add(new ChatInfo()
|
||||
{
|
||||
Name = E.Origin.Name,
|
||||
Message = "DISCONNECTED",
|
||||
Time = DateTime.UtcNow
|
||||
});
|
||||
// predisconnect comes from minimal rcon polled players and minimal log players
|
||||
// so we need to disconnect the "full" version of the client
|
||||
var client = GetClientsAsList().FirstOrDefault(_client => _client.Equals(E.Origin));
|
||||
|
||||
var currentState = E.Origin.State;
|
||||
await RemoveClient(E.Origin.ClientNumber);
|
||||
|
||||
if (currentState != EFClient.ClientState.Connected)
|
||||
if (client != null)
|
||||
{
|
||||
throw new ServerException("Disconnecting player was not in a connected state");
|
||||
#if DEBUG == true
|
||||
Logger.WriteDebug($"Begin PreDisconnect for {client}");
|
||||
#endif
|
||||
ChatHistory.Add(new ChatInfo()
|
||||
{
|
||||
Name = client.Name,
|
||||
Message = "DISCONNECTED",
|
||||
Time = DateTime.UtcNow
|
||||
});
|
||||
|
||||
await OnClientDisconnected(client);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
else if (E.Type == GameEvent.EventType.Update)
|
||||
{
|
||||
#if DEBUG == true
|
||||
Logger.WriteDebug($"Begin Update for {E.Origin}");
|
||||
#endif
|
||||
await OnClientUpdate(E.Origin);
|
||||
}
|
||||
|
||||
if (E.Type == GameEvent.EventType.Say)
|
||||
@ -440,6 +459,24 @@ namespace IW4MAdmin
|
||||
return true;
|
||||
}
|
||||
|
||||
private Task OnClientUpdate(EFClient origin)
|
||||
{
|
||||
var client = Clients[origin.ClientNumber];
|
||||
|
||||
if (client != null)
|
||||
{
|
||||
client.Ping = origin.Ping;
|
||||
client.Score = origin.Score;
|
||||
|
||||
if (origin.IPAddress == 0)
|
||||
{
|
||||
return client.OnJoin(origin.IPAddress);
|
||||
}
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// lists the connecting and disconnecting clients via RCon response
|
||||
/// array index 0 = connecting clients
|
||||
@ -471,9 +508,15 @@ namespace IW4MAdmin
|
||||
}
|
||||
|
||||
var disconnectingClients = currentClients.Except(polledClients);
|
||||
var connectingClients = polledClients.Except(currentClients.Where(c => c.State == EFClient.ClientState.Connected));
|
||||
var connectingClients = polledClients.Except(currentClients);
|
||||
var updatedClients = polledClients.Except(connectingClients);
|
||||
|
||||
return new List<EFClient>[] { connectingClients.ToList(), disconnectingClients.ToList() };
|
||||
return new List<EFClient>[]
|
||||
{
|
||||
connectingClients.ToList(),
|
||||
disconnectingClients.ToList(),
|
||||
updatedClients.ToList()
|
||||
};
|
||||
}
|
||||
|
||||
DateTime start = DateTime.Now;
|
||||
@ -484,21 +527,30 @@ namespace IW4MAdmin
|
||||
{
|
||||
try
|
||||
{
|
||||
#region SHUTDOWN
|
||||
if (Manager.ShutdownRequested())
|
||||
{
|
||||
// todo: fix up disconnect
|
||||
//for (int i = 0; i < EFClients.Count; i++)
|
||||
// await RemoveClient(i);
|
||||
foreach (var client in GetClientsAsList())
|
||||
{
|
||||
var e = new GameEvent()
|
||||
{
|
||||
Type = GameEvent.EventType.PreDisconnect,
|
||||
Origin = client,
|
||||
Owner = this,
|
||||
};
|
||||
|
||||
Manager.GetEventHandler().AddEvent(e);
|
||||
await e.WaitAsync();
|
||||
}
|
||||
|
||||
foreach (var plugin in SharedLibraryCore.Plugins.PluginImporter.ActivePlugins)
|
||||
{
|
||||
await plugin.OnUnloadAsync();
|
||||
}
|
||||
}
|
||||
|
||||
// only check every 2 minutes if the server doesn't seem to be responding
|
||||
/* if ((DateTime.Now - LastPoll).TotalMinutes < 0.5 && ConnectionErrors >= 1)
|
||||
return true;*/
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
try
|
||||
{
|
||||
@ -514,7 +566,7 @@ namespace IW4MAdmin
|
||||
|
||||
var e = new GameEvent()
|
||||
{
|
||||
Type = GameEvent.EventType.Disconnect,
|
||||
Type = GameEvent.EventType.PreDisconnect,
|
||||
Origin = disconnectingClient,
|
||||
Owner = this
|
||||
};
|
||||
@ -531,16 +583,9 @@ namespace IW4MAdmin
|
||||
// this are our new connecting clients
|
||||
foreach (var client in polledClients[0])
|
||||
{
|
||||
// this prevents duplicate events from being sent to the event api
|
||||
if (GetClientsAsList().Count(c => c.NetworkId == client.NetworkId &&
|
||||
c.State == EFClient.ClientState.Connected) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var e = new GameEvent()
|
||||
{
|
||||
Type = GameEvent.EventType.Connect,
|
||||
Type = GameEvent.EventType.PreConnect,
|
||||
Origin = client,
|
||||
Owner = this
|
||||
};
|
||||
@ -552,11 +597,29 @@ namespace IW4MAdmin
|
||||
// wait for all the connect tasks to finish
|
||||
await Task.WhenAll(waiterList.Select(e => e.WaitAsync(10 * 1000)));
|
||||
|
||||
waiterList.Clear();
|
||||
// these are the clients that have updated
|
||||
foreach (var client in polledClients[2])
|
||||
{
|
||||
var e = new GameEvent()
|
||||
{
|
||||
Type = GameEvent.EventType.Update,
|
||||
Origin = client,
|
||||
Owner = this
|
||||
};
|
||||
|
||||
Manager.GetEventHandler().AddEvent(e);
|
||||
waiterList.Add(e);
|
||||
}
|
||||
|
||||
await Task.WhenAll(waiterList.Select(e => e.WaitAsync(10 * 1000)));
|
||||
|
||||
if (ConnectionErrors > 0)
|
||||
{
|
||||
Logger.WriteVerbose($"{loc["MANAGER_CONNECTION_REST"]} {IP}:{Port}");
|
||||
Throttled = false;
|
||||
}
|
||||
|
||||
ConnectionErrors = 0;
|
||||
LastPoll = DateTime.Now;
|
||||
}
|
||||
@ -576,20 +639,6 @@ namespace IW4MAdmin
|
||||
LastMessage = DateTime.Now - start;
|
||||
lastCount = DateTime.Now;
|
||||
|
||||
// todo: re-enable on tick
|
||||
/*
|
||||
if ((DateTime.Now - tickTime).TotalMilliseconds >= 1000)
|
||||
{
|
||||
foreach (var Plugin in SharedLibraryCore.Plugins.PluginImporter.ActivePlugins)
|
||||
{
|
||||
if (cts.IsCancellationRequested)
|
||||
break;
|
||||
|
||||
await Plugin.OnTickAsync(this);
|
||||
}
|
||||
tickTime = DateTime.Now;
|
||||
}*/
|
||||
|
||||
// update the player history
|
||||
if ((lastCount - playerCountStart).TotalMinutes >= SharedLibraryCore.Helpers.PlayerHistory.UpdateInterval)
|
||||
{
|
||||
@ -849,7 +898,7 @@ namespace IW4MAdmin
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
await Target.CurrentServer.RemoveClient(Target.ClientNumber);
|
||||
await Target.CurrentServer.OnClientDisconnected(Target);
|
||||
#endif
|
||||
|
||||
var newPenalty = new Penalty()
|
||||
@ -887,7 +936,7 @@ namespace IW4MAdmin
|
||||
await Target.CurrentServer.ExecuteCommandAsync(formattedKick);
|
||||
}
|
||||
#else
|
||||
await Target.CurrentServer.RemoveClient(Target.ClientNumber);
|
||||
await Target.CurrentServer.OnClientDisconnected(Target);
|
||||
#endif
|
||||
|
||||
Penalty newPenalty = new Penalty()
|
||||
@ -933,7 +982,7 @@ namespace IW4MAdmin
|
||||
string formattedString = String.Format(RconParser.GetCommandPrefixes().Kick, Target.ClientNumber, $"{loc["SERVER_BAN_TEXT"]} - ^5{Message} ^7({loc["SERVER_BAN_APPEAL"]} {Website})^7");
|
||||
await Target.CurrentServer.ExecuteCommandAsync(formattedString);
|
||||
#else
|
||||
await Target.CurrentServer.RemoveClient(Target.ClientNumber);
|
||||
await Target.CurrentServer.OnClientDisconnected(Target);
|
||||
#endif
|
||||
}
|
||||
|
@ -85,29 +85,7 @@ namespace IW4MAdmin.Application
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// if the origin client is not in an authorized state (detected by RCon) don't execute the event
|
||||
if (GameEvent.ShouldOriginEventBeDelayed(newEvent))
|
||||
{
|
||||
Logger.WriteDebug($"Delaying origin execution of event type {newEvent.Type} for {newEvent.Origin} because they are not authed");
|
||||
if (newEvent.Type == GameEvent.EventType.Command)
|
||||
{
|
||||
newEvent.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["SERVER_DELAYED_EVENT_WAIT"]);
|
||||
}
|
||||
|
||||
// offload it to the player to keep
|
||||
newEvent.Origin.DelayedEvents.Enqueue(newEvent);
|
||||
}
|
||||
|
||||
// if the target client is not in an authorized state (detected by RCon) don't execute the event
|
||||
else if (GameEvent.ShouldTargetEventBeDelayed(newEvent))
|
||||
{
|
||||
Logger.WriteDebug($"Delaying target execution of event type {newEvent.Type} for {newEvent.Target} because they are not authed");
|
||||
// offload it to the player to keep
|
||||
newEvent.Target.DelayedEvents.Enqueue(newEvent);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
{
|
||||
|
||||
await newEvent.Owner.ExecuteEvent(newEvent);
|
||||
|
@ -1,22 +1,26 @@
|
||||
aniso8601==3.0.2
|
||||
APScheduler==3.5.3
|
||||
certifi==2018.10.15
|
||||
chardet==3.0.4
|
||||
click==6.7
|
||||
Flask==1.0.2
|
||||
Flask-JWT==0.3.2
|
||||
Flask-JWT-Extended==3.8.1
|
||||
Flask-RESTful==0.3.6
|
||||
idna==2.7
|
||||
itsdangerous==0.24
|
||||
Jinja2==2.10
|
||||
MarkupSafe==1.0
|
||||
marshmallow==3.0.0b8
|
||||
pip==9.0.3
|
||||
PyJWT==1.4.2
|
||||
pytz==2018.5
|
||||
setuptools==39.0.1
|
||||
six==1.11.0
|
||||
Werkzeug==0.14.1
|
||||
certifi==2018.10.15
|
||||
chardet==3.0.4
|
||||
idna==2.7
|
||||
psutil==5.4.8
|
||||
pygal==2.4.0
|
||||
PyJWT==1.4.2
|
||||
pytz==2018.7
|
||||
requests==2.20.0
|
||||
setuptools==40.5.0
|
||||
six==1.11.0
|
||||
timeago==1.0.8
|
||||
tzlocal==1.5.1
|
||||
urllib3==1.24
|
||||
Werkzeug==0.14.1
|
||||
|
@ -244,7 +244,6 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
{
|
||||
int serverId = pl.CurrentServer.GetHashCode();
|
||||
|
||||
|
||||
if (!Servers.ContainsKey(serverId))
|
||||
{
|
||||
Log.WriteError($"[Stats::AddPlayer] Server with id {serverId} could not be found");
|
||||
|
@ -41,13 +41,13 @@ namespace SharedLibraryCore.Database.Models
|
||||
public virtual string Name
|
||||
{
|
||||
get { return CurrentAlias.Name; }
|
||||
set { }
|
||||
set { CurrentAlias.Name = value; }
|
||||
}
|
||||
[NotMapped]
|
||||
public virtual int IPAddress
|
||||
{
|
||||
get { return CurrentAlias.IPAddress; }
|
||||
set { }
|
||||
set { CurrentAlias.IPAddress = value; }
|
||||
}
|
||||
|
||||
[NotMapped]
|
||||
|
@ -1,8 +1,7 @@
|
||||
using System;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Objects;
|
||||
|
||||
namespace SharedLibraryCore
|
||||
{
|
||||
@ -74,6 +73,18 @@ namespace SharedLibraryCore
|
||||
/// the current map changed
|
||||
/// </summary>
|
||||
MapChange,
|
||||
/// <summary>
|
||||
/// a client was detected as starting to connect
|
||||
/// </summary>
|
||||
PreConnect,
|
||||
/// <summary>
|
||||
/// a client was detecting as starting to disconnect
|
||||
/// </summary>
|
||||
PreDisconnect,
|
||||
/// <summary>
|
||||
/// a client's information was updated
|
||||
/// </summary>
|
||||
Update,
|
||||
|
||||
// events "generated" by clients
|
||||
/// <summary>
|
||||
@ -159,7 +170,10 @@ namespace SharedLibraryCore
|
||||
}
|
||||
|
||||
static long NextEventId;
|
||||
static long GetNextEventId() => Interlocked.Increment(ref NextEventId);
|
||||
static long GetNextEventId()
|
||||
{
|
||||
return Interlocked.Increment(ref NextEventId);
|
||||
}
|
||||
|
||||
public GameEvent()
|
||||
{
|
||||
@ -186,11 +200,14 @@ namespace SharedLibraryCore
|
||||
/// asynchronously wait for GameEvent to be processed
|
||||
/// </summary>
|
||||
/// <returns>waitable task </returns>
|
||||
public Task<GameEvent> WaitAsync(int timeOut = int.MaxValue) => Task.Run(() =>
|
||||
public Task<GameEvent> WaitAsync(int timeOut = int.MaxValue)
|
||||
{
|
||||
OnProcessed.Wait(timeOut);
|
||||
return this;
|
||||
});
|
||||
return Task.Run(() =>
|
||||
{
|
||||
OnProcessed.Wait(timeOut);
|
||||
return this;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// determine whether an event should be delayed or not
|
||||
|
@ -1,28 +0,0 @@
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace SharedLibraryCore.Interfaces
|
||||
{
|
||||
public interface IClientAuthentication
|
||||
{
|
||||
/// <summary>
|
||||
/// request authentication when a client join event
|
||||
/// occurs in the log, as no IP is given
|
||||
/// </summary>
|
||||
/// <param name="client">client that has joined from the log</param>
|
||||
void RequestClientAuthentication(EFClient client);
|
||||
/// <summary>
|
||||
/// get all clients that have been authenticated by the status poll
|
||||
/// </summary>
|
||||
/// <returns>list of all authenticated clients</returns>
|
||||
IList<EFClient> GetAuthenticatedClients();
|
||||
/// <summary>
|
||||
/// authenticate a list of clients from status poll
|
||||
/// </summary>
|
||||
/// <param name="clients">list of clients to authenticate</param>
|
||||
void AuthenticateClients(IList<EFClient> clients);
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Objects;
|
||||
using SharedLibraryCore.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
@ -18,11 +17,6 @@ namespace SharedLibraryCore.Database.Models
|
||||
/// </summary>
|
||||
Connecting,
|
||||
/// <summary>
|
||||
/// represents when the client has been parsed by RCon,
|
||||
/// but has not been validated against the database
|
||||
/// </summary>
|
||||
Authenticated,
|
||||
/// <summary>
|
||||
/// represents when the client has been authenticated by RCon
|
||||
/// and validated by the database
|
||||
/// </summary>
|
||||
@ -86,6 +80,7 @@ namespace SharedLibraryCore.Database.Models
|
||||
{
|
||||
{ "_reportCount", 0 }
|
||||
};
|
||||
CurrentAlias = CurrentAlias ?? new EFAlias();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
@ -410,7 +405,7 @@ namespace SharedLibraryCore.Database.Models
|
||||
public void OnConnect()
|
||||
{
|
||||
var loc = Utilities.CurrentLocalization.LocalizationIndex;
|
||||
//#if !DEBUG
|
||||
#if !DEBUG
|
||||
if (Name.Length < 3)
|
||||
{
|
||||
CurrentServer.Logger.WriteDebug($"Kicking {this} because their name is too short");
|
||||
@ -435,7 +430,7 @@ namespace SharedLibraryCore.Database.Models
|
||||
}
|
||||
|
||||
// reserved slots stuff
|
||||
if ((CurrentServer.GetClientsAsList().Count(_client => !_client.IsPrivileged()) - CurrentServer.MaxClients) < CurrentServer.ServerConfig.ReservedSlotNumber &&
|
||||
if (CurrentServer.MaxClients - (CurrentServer.GetClientsAsList().Count(_client => !_client.IsPrivileged())) < CurrentServer.ServerConfig.ReservedSlotNumber &&
|
||||
!this.IsPrivileged())
|
||||
{
|
||||
CurrentServer.Logger.WriteDebug($"Kicking {this} their spot is reserved");
|
||||
@ -446,13 +441,34 @@ namespace SharedLibraryCore.Database.Models
|
||||
LastConnection = DateTime.UtcNow;
|
||||
Connections += 1;
|
||||
|
||||
//#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
public async Task OnDisconnect()
|
||||
{
|
||||
State = ClientState.Disconnecting;
|
||||
TotalConnectionTime += ConnectionLength;
|
||||
LastConnection = DateTime.UtcNow;
|
||||
await CurrentServer.Manager.GetClientService().Update(this);
|
||||
}
|
||||
|
||||
public async Task OnJoin(int ipAddress)
|
||||
{
|
||||
// todo: fix this up
|
||||
CurrentAlias.IPAddress = IPAddress;
|
||||
var existingAlias = AliasLink.Children
|
||||
.FirstOrDefault(a => a.Name == Name && a.IPAddress == ipAddress);
|
||||
|
||||
if (existingAlias == null)
|
||||
{
|
||||
CurrentServer.Logger.WriteDebug($"Client {this} has connected previously under a different ip/name");
|
||||
|
||||
CurrentAlias = new EFAlias()
|
||||
{
|
||||
IPAddress = ipAddress,
|
||||
Name = Name
|
||||
};
|
||||
}
|
||||
|
||||
await CurrentServer.Manager.GetClientService().Update(this);
|
||||
|
||||
var loc = Utilities.CurrentLocalization.LocalizationIndex;
|
||||
@ -477,9 +493,8 @@ namespace SharedLibraryCore.Database.Models
|
||||
CurrentServer.Logger.WriteInfo($"Banned client {this} trying to join...");
|
||||
var autoKickClient = Utilities.IW4MAdminClient(CurrentServer);
|
||||
|
||||
|
||||
// reban the "evading" guid
|
||||
if (Level != Permission.Banned &&
|
||||
if (Level != Permission.Banned &&
|
||||
currentBan.Type == Penalty.PenaltyType.Ban)
|
||||
{
|
||||
// hack: re apply the automated offense to the reban
|
||||
@ -501,11 +516,7 @@ namespace SharedLibraryCore.Database.Models
|
||||
|
||||
else
|
||||
{
|
||||
//string formattedKick = String.Format(
|
||||
// RconParser.GetCommandPrefixes().Kick,
|
||||
// polledPlayer.ClientNumber,
|
||||
// $"{loc["SERVER_TB_REMAIN"]} ({(currentBan.Expires.Value - DateTime.UtcNow).TimeSpanText()} {loc["WEBFRONT_PENALTY_TEMPLATE_REMAINING"]})");
|
||||
//await this.ExecuteCommandAsync(formattedKick);
|
||||
Kick($"{loc["SERVER_TB_REMAIN"]} ({(currentBan.Expires.Value - DateTime.UtcNow).TimeSpanText()} {loc["WEBFRONT_PENALTY_TEMPLATE_REMAINING"]})", autoKickClient);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,11 +106,17 @@ namespace SharedLibraryCore.RCon
|
||||
try
|
||||
{
|
||||
response = await SendPayloadAsync(payload, waitForResponse);
|
||||
|
||||
if (response.Length == 0)
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
connectionState.OnComplete.Release(1);
|
||||
connectionState.ConnectionAttempts = 0;
|
||||
}
|
||||
|
||||
catch/* (Exception ex)*/
|
||||
catch
|
||||
{
|
||||
if (connectionState.ConnectionAttempts < StaticHelpers.AllowedConnectionFails)
|
||||
{
|
||||
|
@ -79,7 +79,7 @@ namespace SharedLibraryCore
|
||||
/// </summary>
|
||||
/// <param name="cNum">Client ID of player to be removed</param>
|
||||
/// <returns>true if removal succeded, false otherwise</returns>
|
||||
abstract public Task RemoveClient(int cNum);
|
||||
abstract public Task OnClientDisconnected(EFClient client);
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
Loading…
Reference in New Issue
Block a user