More work modifying client stuff

This commit is contained in:
RaidMax 2018-11-07 20:30:11 -06:00
parent ed83c4c011
commit 9bdd7d1b8a
14 changed files with 255 additions and 307 deletions

View File

@ -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);
}
}
}

View File

@ -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
};
}

View File

@ -33,7 +33,7 @@ namespace IW4MAdmin.Application.EventParsers
return new GameEvent()
{
Type = GameEvent.EventType.Join,
Type = GameEvent.EventType.PreConnect,
Origin = new EFClient()
{
ClientId = 1

View File

@ -79,6 +79,7 @@ namespace IW4MAdmin.Application.IO
foreach (var ev in events)
{
Server.Manager.GetEventHandler().AddEvent(ev);
await ev.WaitAsync();
}
PreviousFileSize = fileSize;

View File

@ -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
}

View File

@ -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);

View File

@ -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

View File

@ -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");

View File

@ -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]

View File

@ -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

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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)
{

View File

@ -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>