Fixed the ban loop bug (client goes into zombie state if immediately kicked upon joining, and won't disconnect until a timeout)

This commit is contained in:
RaidMax 2017-05-28 20:07:33 -05:00
parent 28fcc7b922
commit bc452cfd93
14 changed files with 48 additions and 64 deletions

View File

@ -322,7 +322,7 @@ copy /Y "$(ProjectDir)lib\SQLite.Interop.dll" "$(SolutionDir)BUILD\lib"
if $(ConfigurationName) == Release powershell.exe -file "$(SolutionDir)DEPLOY\publish_nightly.ps1" %25iw4madmin_version%25</PostBuildEvent>
if $(ConfigurationName) == Release powershell.exe -file "$(SolutionDir)DEPLOY\publish_nightly.ps1" 1.3</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -23,6 +23,9 @@ namespace IW4MAdmin
public Logger(string fn)
{
FileName = fn;
if (File.Exists(fn))
File.Delete(fn);
}
void Write(string msg, LogType type)

View File

@ -16,11 +16,10 @@ namespace IW4MAdmin
static void Main(string[] args)
{
Version = 1.3;
double latestVersion = 0;
handler = new ConsoleEventDelegate(OnProcessExit);
SetConsoleCtrlHandler(handler, true);
double.TryParse(CheckUpdate(), out latestVersion);
double.TryParse(CheckUpdate(), out double latestVersion);
Console.WriteLine("=====================================================");
Console.WriteLine(" IW4M ADMIN");
Console.WriteLine(" by RaidMax ");

View File

@ -83,7 +83,7 @@ namespace IW4MAdmin
Servers.Add(ServerInstance);
// this way we can keep track of execution time and see if problems arise.
var Status = new AsyncStatus(ServerInstance);
var Status = new AsyncStatus(ServerInstance, UPDATE_FREQUENCY);
TaskStatuses.Add(Status);
Logger.WriteVerbose($"Now monitoring {ServerInstance.Hostname}");
@ -123,7 +123,7 @@ namespace IW4MAdmin
{
Status.Update(new Task(() => (Status.Dependant as Server).ProcessUpdatesAsync(Status.GetToken())));
if (Status.RunAverage > 500)
Logger.WriteWarning($"Update task average execution is longer than desired for {(Status.Dependant as Server).getIP()}::{(Status.Dependant as Server).getPort()}");
Logger.WriteWarning($"Update task average execution is longer than desired for {(Status.Dependant as Server).getIP()}::{(Status.Dependant as Server).getPort()} [{Status.RunAverage}ms]");
}
}

View File

@ -2,13 +2,10 @@
using System.Collections.Generic;
using System.Threading;
using System.IO;
using System.Runtime.InteropServices;
using System.Linq;
using SharedLibrary;
using SharedLibrary.Network;
using System.Threading.Tasks;
using System.Net;
namespace IW4MAdmin
{
@ -36,7 +33,7 @@ namespace IW4MAdmin
}
}
public override List<Aliases> getAliases(Player Origin)
public override List<Aliases> GetAliases(Player Origin)
{
List<Aliases> allAliases = new List<Aliases>();
@ -52,14 +49,17 @@ namespace IW4MAdmin
return allAliases;
}
//Add player object p to `players` list
override public async Task<bool> AddPlayer(Player P)
{
if (P.clientID < 0 || P.clientID > (Players.Count-1)) // invalid index
if (P.clientID < 0 || P.clientID > (Players.Count-1) || P.Ping < 1 || P.Ping == 999) // invalid index
return false;
if (Players[P.clientID] != null && Players[P.clientID].npID == P.npID) // if someone has left and a new person has taken their spot between polls
{
// update their ping
Players[P.clientID].Ping = P.Ping;
return true;
}
Logger.WriteDebug($"Client slot #{P.clientID} now reserved");
@ -86,6 +86,7 @@ namespace IW4MAdmin
await this.ExecuteCommandAsync("clientkick " + P.clientID + " \"Please do not impersonate an admin^7\"");
}
// below this needs to be optimized ~ 425ms runtime
NewPlayer.updateName(P.Name.Trim());
NewPlayer.Alias = aliasDB.getPlayer(NewPlayer.databaseID);
@ -122,24 +123,8 @@ namespace IW4MAdmin
if (NewPlayer.Level == Player.Permission.Banned) // their guid is already banned so no need to check aliases
{
String Message;
Logger.WriteInfo($"Banned client {P.Name}::{P.npID} trying to connect...");
if (NewPlayer.lastOffense != null)
Message = "Previously banned for ^5" + NewPlayer.lastOffense;
else
Message = "Previous Ban";
await NewPlayer.Kick(Message, NewPlayer);
if (Players[NewPlayer.clientID] != null)
{
lock (Players)
{
Players[NewPlayer.clientID] = null;
}
}
await NewPlayer.Kick(NewPlayer.lastOffense != null ? "^7Previously banned for ^5 " + NewPlayer.lastOffense : "^7Previous Ban", NewPlayer);
return true;
}
@ -161,25 +146,15 @@ namespace IW4MAdmin
Logger.WriteDebug($"Banned client {aP.Name}::{aP.npID} is connecting with new alias {NewPlayer.Name}");
NewPlayer.lastOffense = String.Format("Evading ( {0} )", aP.Name);
if (B.Reason != null)
await NewPlayer.Ban("^7Previously Banned: ^5" + B.Reason, NewPlayer);
else
await NewPlayer.Ban("^7Previous Ban", NewPlayer);
await NewPlayer.Ban(B.Reason != null ? "^7Previously banned for ^5 " + B.Reason : "^7Previous Ban", NewPlayer);
Players[NewPlayer.clientID] = null;
lock (Players)
{
if (Players[NewPlayer.clientID] != null)
Players[NewPlayer.clientID] = null;
}
return true;
}
}
lock (Players)
{
Players[NewPlayer.clientID] = null; // just in case we have shit in the way
Players[NewPlayer.clientID] = NewPlayer;
}
Players[NewPlayer.clientID] = null;
Players[NewPlayer.clientID] = NewPlayer;
#if DEBUG == FALSE
await NewPlayer.Tell($"Welcome ^5{NewPlayer.Name} ^7this is your ^5{NewPlayer.TimesConnected()} ^7time connecting!");
#endif
@ -471,7 +446,6 @@ namespace IW4MAdmin
Logger.WriteError("Unexpected error on \"" + Hostname + "\"");
Logger.WriteDebug("Error Message: " + E.Message);
Logger.WriteDebug("Error Trace: " + E.StackTrace);
return 1;
}
#endif
}
@ -702,7 +676,7 @@ namespace IW4MAdmin
if (Target.clientID > -1)
{
await this.ExecuteCommandAsync($"tempbanclient {Target.clientID } \"^1Player Temporarily Banned: ^5{ Reason } (1 hour)\"");
Penalty newPenalty = new Penalty(Penalty.Type.TempBan, SharedLibrary.Utilities.StripColors(Reason), Target.npID, Origin.npID, DateTime.Now, Target.IP);
Penalty newPenalty = new Penalty(Penalty.Type.TempBan, Reason.StripColors(), Target.npID, Origin.npID, DateTime.Now, Target.IP);
await Task.Run(() =>
{
Manager.GetClientPenalties().AddPenalty(newPenalty);
@ -710,11 +684,9 @@ namespace IW4MAdmin
}
}
private String getWebsiteString()
private String GetWebsiteString()
{
if (Website != null)
return String.Format(" (appeal at {0})", Website);
return " (appeal at this server's website)";
return Website != null ? $" (appeal at {Website}" : " (appeal at this server's website)";
}
override public async Task Ban(String Message, Player Target, Player Origin)
@ -734,7 +706,7 @@ namespace IW4MAdmin
{
var activeClient = server.getPlayers().Find(x => x.npID == Target.npID);
if (activeClient != null)
await server.ExecuteCommandAsync("tempbanclient " + activeClient.clientID + " \"" + Message + "^7" + getWebsiteString() + "^7\"");
await server.ExecuteCommandAsync("tempbanclient " + activeClient.clientID + " \"" + Message + "^7" + GetWebsiteString() + "^7\"");
}
}

View File

@ -619,7 +619,7 @@ namespace IW4MAdmin
{
if (pp == null) continue;
var playerAliases = Manager.GetInstance().Servers.First().getAliases(pp);
var playerAliases = Manager.GetInstance().Servers.First().GetAliases(pp);
PlayerInfo eachPlayer = new PlayerInfo();
eachPlayer.playerID = pp.databaseID;
eachPlayer.playerIP = pp.IP;

Binary file not shown.

View File

@ -12,15 +12,17 @@ namespace SharedLibrary
CancellationToken Token;
DateTime StartTime;
int TimesRun;
int UpdateFrequency;
public double RunAverage { get; private set; }
public object Dependant { get; private set; }
public Task RequestedTask { get; private set; }
public AsyncStatus(object dependant)
public AsyncStatus(object dependant, int frequency)
{
Token = new CancellationToken();
StartTime = DateTime.Now;
Dependant = dependant;
UpdateFrequency = frequency;
// technically 0 but it's faster than checking for division by 0
TimesRun = 1;
}
@ -40,10 +42,10 @@ namespace SharedLibrary
RequestedTask = T;
RequestedTask.Start();
if (TimesRun > 100)
if (TimesRun > 25)
TimesRun = 1;
RunAverage = RunAverage + ((DateTime.Now - StartTime).TotalMilliseconds - RunAverage) / TimesRun;
RunAverage = RunAverage + ((DateTime.Now - StartTime).TotalMilliseconds - RunAverage - UpdateFrequency) / TimesRun;
StartTime = DateTime.Now;
}
}

View File

@ -41,6 +41,11 @@ namespace SharedLibrary
return ((Player)obj).npID == this.npID;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public Player(string n, string id, int num, int l)
{
Name = n;
@ -178,6 +183,8 @@ namespace SharedLibrary
public DateTime LastConnection { get; private set; }
public Server currentServer { get; private set; }
public int Ping;
public Event lastEvent;
public String lastOffense;
public int Warnings;

View File

@ -32,12 +32,13 @@ namespace SharedLibrary.Network
{
String[] playerInfo = responseLine.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
int cID = -1;
int Ping = -1;
Int32.TryParse(playerInfo[2], out Ping);
String cName = Utilities.StripColors(responseLine.Substring(46, 18)).Trim();
String npID = responseLine.Substring(29, 17).Trim(); // DONT TOUCH PLZ
int.TryParse(playerInfo[0], out cID);
String cIP = responseLine.Substring(72, 20).Trim().Split(':')[0];
Player P = new Player(cName, npID, cID, cIP);
Player P = new Player(cName, npID, cID, cIP) { Ping = Ping };
StatusPlayers.Add(P);
}
}

View File

@ -121,13 +121,13 @@ namespace SharedLibrary
/// Get any know aliases ( name or ip based ) from the database
/// </summary>
/// <param name="Origin">Player to scan for aliases</param>
abstract public List<Aliases> getAliases(Player Origin);
abstract public List<Aliases> GetAliases(Player Origin);
public List<Player> getPlayerAliases(Player Origin)
{
List<int> databaseIDs = new List<int>();
foreach (Aliases A in getAliases(Origin))
foreach (Aliases A in GetAliases(Origin))
databaseIDs.Add(A.Number);
return Manager.GetClientDatabase().getPlayers(databaseIDs);

View File

@ -268,9 +268,9 @@ namespace SharedLibrary
case 100:
return "One-Hundreth (amazing!)";
case 500:
return "^7You're really ^5dedicated ^7to this server! This is your ^5500th ^7time connecting!";
return "you're really ^5dedicated ^7to this server! This is your ^5500th^7";
case 1000:
return "WOW! Soldier, it's your ^11000th ^7time connecting! You deserve a medal.";
return "you deserve a medal. it's your ^11000th^7";
default:
return connection.ToString() + Prefix;

View File

@ -5,7 +5,6 @@ using SharedLibrary;
using SharedLibrary.Network;
using SharedLibrary.Interfaces;
using System.Threading.Tasks;
using System.Threading;
namespace Votemap_Plugin
{
@ -223,7 +222,6 @@ namespace Votemap_Plugin
public async Task OnTickAsync(Server S)
{
var serverVotes = getServerVotes(S.getPort());
Thread.Sleep(500);
if (serverVotes != null)
{

View File

@ -53,10 +53,12 @@ namespace Welcome_Plugin
Player newPlayer = E.Origin;
if (newPlayer.Level >= Player.Permission.Trusted && !E.Origin.Masked)
await E.Owner.Broadcast(Utilities.levelToColor(newPlayer.Level) + " ^5" + newPlayer.Name + " ^7has joined the server.");
await E.Owner.Broadcast(Utilities.levelToColor(newPlayer.Level) + " ^5" + newPlayer.Name + " ^7has joined the server.");
await newPlayer.Tell($"Welcome ^5{newPlayer.Name}^7, this your ^5{newPlayer.TimesConnected()} ^7time connecting!");
if (newPlayer.Level == Player.Permission.Flagged)
await E.Owner.ToAdmins($"^1NOTICE: ^7Flagged player ^5{newPlayer.Name}^7 has joined!");
await E.Owner.ToAdmins($"^1NOTICE: ^7Flagged player ^5{newPlayer.Name}^7 has joined!");
else
{