exit works correctly again
changes to rcon for T6M hopefully fixed some stat issues (spm and database errors)
This commit is contained in:
parent
d1283b96a1
commit
1a50391bfe
@ -37,7 +37,6 @@ namespace IW4MAdmin.Application
|
|||||||
|
|
||||||
ServerManager = ApplicationManager.GetInstance();
|
ServerManager = ApplicationManager.GetInstance();
|
||||||
ServerManager.Init().Wait();
|
ServerManager.Init().Wait();
|
||||||
Task.Run(() => ServerManager.Start());
|
|
||||||
|
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
@ -60,11 +59,12 @@ namespace IW4MAdmin.Application
|
|||||||
Console.Write('>');
|
Console.Write('>');
|
||||||
|
|
||||||
} while (ServerManager.Running);
|
} while (ServerManager.Running);
|
||||||
|
|
||||||
Console.WriteLine("Shutdown complete");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
WebfrontCore.Program.Init(ServerManager);
|
Task.Run(() => WebfrontCore.Program.Init(ServerManager));
|
||||||
|
ServerManager.Start();
|
||||||
|
ServerManager.Logger.WriteVerbose("Shutdown complete");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -662,7 +662,7 @@ namespace IW4MAdmin
|
|||||||
// patch for T5M:V2 log path
|
// patch for T5M:V2 log path
|
||||||
mainPath = (GameName == Game.T5M) ? "rzodemo" : mainPath;
|
mainPath = (GameName == Game.T5M) ? "rzodemo" : mainPath;
|
||||||
// patch for T6M:PLUTONIUM
|
// patch for T6M:PLUTONIUM
|
||||||
mainPath = (GameName == Game.T6M) ? "t6r/data" : mainPath;
|
mainPath = (GameName == Game.T6M) ? $"t6r{Path.DirectorySeparatorChar}data" : mainPath;
|
||||||
|
|
||||||
string logPath = (game.Value == "" || onelog?.Value == 1) ?
|
string logPath = (game.Value == "" || onelog?.Value == 1) ?
|
||||||
$"{basepath.Value.Replace('\\', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{mainPath}{Path.DirectorySeparatorChar}{logfile.Value}" :
|
$"{basepath.Value.Replace('\\', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{mainPath}{Path.DirectorySeparatorChar}{logfile.Value}" :
|
||||||
@ -682,7 +682,7 @@ namespace IW4MAdmin
|
|||||||
|
|
||||||
Logger.WriteInfo($"Log file is {logPath}");
|
Logger.WriteInfo($"Log file is {logPath}");
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
//LogFile = new RemoteFile("https://raidmax.org/IW4MAdmin/getlog.php");
|
LogFile = new RemoteFile("https://raidmax.org/IW4MAdmin/getlog.php");
|
||||||
#else
|
#else
|
||||||
await Broadcast("IW4M Admin is now ^2ONLINE");
|
await Broadcast("IW4M Admin is now ^2ONLINE");
|
||||||
#endif
|
#endif
|
||||||
|
@ -156,6 +156,10 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
|
|
||||||
detectionStats.TryAdd(pl.ClientId, new Cheat.Detection(Log, clientStats));
|
detectionStats.TryAdd(pl.ClientId, new Cheat.Detection(Log, clientStats));
|
||||||
|
|
||||||
|
// todo: look at this more
|
||||||
|
statsSvc.ClientStatSvc.Update(clientStats);
|
||||||
|
await statsSvc.ClientStatSvc.SaveChangesAsync();
|
||||||
|
|
||||||
return clientStats;
|
return clientStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,6 +196,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
UpdateStats(clientStats);
|
UpdateStats(clientStats);
|
||||||
|
|
||||||
// todo: should this be saved every disconnect?
|
// todo: should this be saved every disconnect?
|
||||||
|
statsSvc.ClientStatSvc.Update(clientStats);
|
||||||
await statsSvc.ClientStatSvc.SaveChangesAsync();
|
await statsSvc.ClientStatSvc.SaveChangesAsync();
|
||||||
// increment the total play time
|
// increment the total play time
|
||||||
serverStats.TotalPlayTime += (int)(DateTime.UtcNow - pl.LastConnection).TotalSeconds;
|
serverStats.TotalPlayTime += (int)(DateTime.UtcNow - pl.LastConnection).TotalSeconds;
|
||||||
@ -260,15 +265,17 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var playerDetection = Servers[serverId].PlayerDetections[attacker.ClientId];
|
var clientDetection = Servers[serverId].PlayerDetections[attacker.ClientId];
|
||||||
var playerStats = Servers[serverId].PlayerStats[attacker.ClientId];
|
var clientStats = Servers[serverId].PlayerStats[attacker.ClientId];
|
||||||
|
|
||||||
// increment their hit count
|
// increment their hit count
|
||||||
if (kill.DeathType == IW4Info.MeansOfDeath.MOD_PISTOL_BULLET ||
|
if (kill.DeathType == IW4Info.MeansOfDeath.MOD_PISTOL_BULLET ||
|
||||||
kill.DeathType == IW4Info.MeansOfDeath.MOD_RIFLE_BULLET ||
|
kill.DeathType == IW4Info.MeansOfDeath.MOD_RIFLE_BULLET ||
|
||||||
kill.DeathType == IW4Info.MeansOfDeath.MOD_HEAD_SHOT)
|
kill.DeathType == IW4Info.MeansOfDeath.MOD_HEAD_SHOT)
|
||||||
{
|
{
|
||||||
playerStats.HitLocations.Single(hl => hl.Location == kill.HitLoc).HitCount += 1;
|
clientStats.HitLocations.Single(hl => hl.Location == kill.HitLoc).HitCount += 1;
|
||||||
|
|
||||||
|
statsSvc.ClientStatSvc.Update(clientStats);
|
||||||
await statsSvc.ClientStatSvc.SaveChangesAsync();
|
await statsSvc.ClientStatSvc.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,8 +306,8 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await executePenalty(playerDetection.ProcessKill(kill));
|
await executePenalty(clientDetection.ProcessKill(kill));
|
||||||
await executePenalty(playerDetection.ProcessTotalRatio(playerStats));
|
await executePenalty(clientDetection.ProcessTotalRatio(clientStats));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,7 +357,9 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
|
|
||||||
// todo: do we want to save this immediately?
|
// todo: do we want to save this immediately?
|
||||||
var statsSvc = ContextThreads[serverId];
|
var statsSvc = ContextThreads[serverId];
|
||||||
statsSvc.ClientStatSvc.SaveChanges();
|
statsSvc.ClientStatSvc.Update(attackerStats);
|
||||||
|
statsSvc.ClientStatSvc.Update(victimStats);
|
||||||
|
await statsSvc.ClientStatSvc.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -393,16 +402,18 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private EFClientStatistics UpdateStats(EFClientStatistics clientStats)
|
private EFClientStatistics UpdateStats(EFClientStatistics clientStats)
|
||||||
{
|
{
|
||||||
|
// prevent NaN or inactive time lowering SPM
|
||||||
|
if ((DateTime.UtcNow - clientStats.LastStatCalculation).TotalSeconds / 60.0 < 0.1 ||
|
||||||
|
(DateTime.UtcNow - clientStats.LastActive).TotalSeconds / 60.0 > 3 ||
|
||||||
|
clientStats.SessionScore < 1)
|
||||||
|
return clientStats;
|
||||||
|
|
||||||
double timeSinceLastCalc = (DateTime.UtcNow - clientStats.LastStatCalculation).TotalSeconds / 60.0;
|
double timeSinceLastCalc = (DateTime.UtcNow - clientStats.LastStatCalculation).TotalSeconds / 60.0;
|
||||||
double timeSinceLastActive = (DateTime.UtcNow - clientStats.LastActive).TotalSeconds / 60.0;
|
double timeSinceLastActive = (DateTime.UtcNow - clientStats.LastActive).TotalSeconds / 60.0;
|
||||||
|
|
||||||
// prevent NaN or inactive time lowering SPM
|
|
||||||
if (timeSinceLastCalc == 0 || timeSinceLastActive > 3 || clientStats.SPM < 1)
|
|
||||||
return clientStats;
|
|
||||||
|
|
||||||
// calculate the players Score Per Minute for the current session
|
// calculate the players Score Per Minute for the current session
|
||||||
int currentScore = clientStats.SessionScore;
|
int scoreDifference = clientStats.LastScore == 0 ? 0 : clientStats.SessionScore - clientStats.LastScore;
|
||||||
double killSPM = currentScore / (timeSinceLastCalc * 60.0);
|
double killSPM = scoreDifference / timeSinceLastCalc;
|
||||||
|
|
||||||
// calculate how much the KDR should weigh
|
// calculate how much the KDR should weigh
|
||||||
// 1.637 is a Eddie-Generated number that weights the KDR nicely
|
// 1.637 is a Eddie-Generated number that weights the KDR nicely
|
||||||
@ -427,7 +438,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
clientStats.Skill = Math.Round((clientStats.SPM * KDRWeight), 3);
|
clientStats.Skill = Math.Round((clientStats.SPM * KDRWeight), 3);
|
||||||
|
|
||||||
clientStats.LastStatCalculation = DateTime.UtcNow;
|
clientStats.LastStatCalculation = DateTime.UtcNow;
|
||||||
clientStats.LastScore = currentScore;
|
clientStats.LastScore = clientStats.SessionScore;
|
||||||
|
|
||||||
return clientStats;
|
return clientStats;
|
||||||
}
|
}
|
||||||
|
@ -177,10 +177,10 @@ namespace SharedLibraryCore.RCon
|
|||||||
{
|
{
|
||||||
case StaticHelpers.QueryType.DVAR:
|
case StaticHelpers.QueryType.DVAR:
|
||||||
case StaticHelpers.QueryType.COMMAND:
|
case StaticHelpers.QueryType.COMMAND:
|
||||||
queryString = $"ÿÿÿÿ\x02rcon {RConPassword} {parameters}";
|
queryString = $"ÿÿÿÿrcon {RConPassword} {parameters}";
|
||||||
break;
|
break;
|
||||||
case StaticHelpers.QueryType.GET_STATUS:
|
case StaticHelpers.QueryType.GET_STATUS:
|
||||||
queryString = "ÿÿÿÿ\x02getstatus";
|
queryString = "ÿÿÿÿgetstatus";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,6 +233,12 @@ namespace SharedLibraryCore.RCon
|
|||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
|
// t6m doesn't respond to set requests
|
||||||
|
if (type == StaticHelpers.QueryType.DVAR && parameters.Contains("set "))
|
||||||
|
{
|
||||||
|
return await Task.FromResult(new string[] { "" });
|
||||||
|
}
|
||||||
|
|
||||||
FailedReceives++;
|
FailedReceives++;
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
Log.WriteDebug($"{FailedReceives} failed receives from {ServerConnection.RemoteEndPoint.ToString()}");
|
Log.WriteDebug($"{FailedReceives} failed receives from {ServerConnection.RemoteEndPoint.ToString()}");
|
||||||
|
@ -52,7 +52,7 @@ namespace SharedLibraryCore
|
|||||||
return newStr;
|
return newStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Player> PlayersFromStatus(string[] Status)
|
public static List<Player> PlayersFromStatus(this Server sv, string[] Status)
|
||||||
{
|
{
|
||||||
List<Player> StatusPlayers = new List<Player>();
|
List<Player> StatusPlayers = new List<Player>();
|
||||||
|
|
||||||
@ -65,9 +65,22 @@ namespace SharedLibraryCore
|
|||||||
String[] playerInfo = responseLine.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
String[] playerInfo = responseLine.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
int cID = -1;
|
int cID = -1;
|
||||||
int Ping = -1;
|
int Ping = -1;
|
||||||
Int32.TryParse(playerInfo[2], out Ping);
|
|
||||||
String cName = Encoding.UTF8.GetString(Encoding.Convert(Encoding.UTF7, Encoding.UTF8, Encoding.UTF7.GetBytes(StripColors(responseLine.Substring(46, 18)).Trim())));
|
try
|
||||||
long npID = Regex.Match(responseLine, @"([a-z]|[0-9]){16}", RegexOptions.IgnoreCase).Value.ConvertLong();
|
{
|
||||||
|
Ping = (sv.GameName != Game.T6M) ?
|
||||||
|
Int32.Parse(playerInfo[2]) :
|
||||||
|
Int32.Parse(playerInfo[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (FormatException) { }
|
||||||
|
String cName = (sv.GameName != Game.T6M) ?
|
||||||
|
Encoding.UTF8.GetString(Encoding.Convert(Encoding.UTF7, Encoding.UTF8, Encoding.UTF7.GetBytes(StripColors(responseLine.Substring(46, 18)).Trim()))) :
|
||||||
|
Encoding.UTF8.GetString(Encoding.Convert(Encoding.UTF7, Encoding.UTF8, Encoding.UTF7.GetBytes(StripColors(responseLine.Substring(50, 15)).Trim())));
|
||||||
|
long npID = sv.GameName != Game.T6M ?
|
||||||
|
Regex.Match(responseLine, @"([a-z]|[0-9]){16}", RegexOptions.IgnoreCase).Value.ConvertLong() :
|
||||||
|
playerInfo[4].ConvertLong();
|
||||||
|
|
||||||
int.TryParse(playerInfo[0], out cID);
|
int.TryParse(playerInfo[0], out cID);
|
||||||
var regex = Regex.Match(responseLine, @"\d+\.\d+\.\d+.\d+\:\d{1,5}");
|
var regex = Regex.Match(responseLine, @"\d+\.\d+\.\d+.\d+\:\d{1,5}");
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@ -76,7 +89,9 @@ namespace SharedLibraryCore
|
|||||||
|
|
||||||
int cIP = regex.Value.Split(':')[0].ConvertToIP();
|
int cIP = regex.Value.Split(':')[0].ConvertToIP();
|
||||||
regex = Regex.Match(responseLine, @"[0-9]{1,2}\s+[0-9]+\s+");
|
regex = Regex.Match(responseLine, @"[0-9]{1,2}\s+[0-9]+\s+");
|
||||||
int score = Int32.Parse(regex.Value.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[1]);
|
int score = (sv.GameName != Game.T6M) ?
|
||||||
|
Int32.Parse(regex.Value.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[1]) :
|
||||||
|
Int32.Parse(playerInfo[1]);
|
||||||
Player P = new Player() { Name = cName, NetworkId = npID, ClientNumber = cID, IPAddress = cIP, Ping = Ping, Score = score };
|
Player P = new Player() { Name = cName, NetworkId = npID, ClientNumber = cID, IPAddress = cIP, Ping = Ping, Score = score };
|
||||||
StatusPlayers.Add(P);
|
StatusPlayers.Add(P);
|
||||||
}
|
}
|
||||||
@ -391,10 +406,32 @@ namespace SharedLibraryCore
|
|||||||
|
|
||||||
public static async Task<DVAR<T>> GetDvarAsync<T>(this Server server, string dvarName)
|
public static async Task<DVAR<T>> GetDvarAsync<T>(this Server server, string dvarName)
|
||||||
{
|
{
|
||||||
string[] LineSplit = server.GameName != Game.T6M ?
|
string[] LineSplit = null;
|
||||||
await server.RemoteConnection.SendQueryAsync(QueryType.DVAR, dvarName) :
|
bool t6m = false;
|
||||||
await server.RemoteConnection.SendQueryAsync(QueryType.COMMAND, $"get {dvarName}");
|
if (server.GameName == Game.UKN)
|
||||||
|
{
|
||||||
|
LineSplit = await server.RemoteConnection.SendQueryAsync(QueryType.COMMAND, $"get {dvarName}");
|
||||||
|
if (LineSplit.Where(l => l.Contains("Unknown command")).Count() > 0)
|
||||||
|
{
|
||||||
|
LineSplit = await server.RemoteConnection.SendQueryAsync(QueryType.DVAR, dvarName);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
t6m = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (server.GameName == Game.T6M)
|
||||||
|
{
|
||||||
|
LineSplit = await server.RemoteConnection.SendQueryAsync(QueryType.COMMAND, $"get {dvarName}");
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LineSplit = await server.RemoteConnection.SendQueryAsync(QueryType.DVAR, dvarName); ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server.GameName != Game.T6M && !t6m)
|
||||||
|
{
|
||||||
if (LineSplit.Length < 3)
|
if (LineSplit.Length < 3)
|
||||||
{
|
{
|
||||||
var e = new Exceptions.DvarException($"DVAR \"{dvarName}\" does not exist");
|
var e = new Exceptions.DvarException($"DVAR \"{dvarName}\" does not exist");
|
||||||
@ -418,6 +455,33 @@ namespace SharedLibraryCore
|
|||||||
return new DVAR<T>(DvarName) { Value = (T)Convert.ChangeType(DvarCurrentValue, typeof(T)) };
|
return new DVAR<T>(DvarName) { Value = (T)Convert.ChangeType(DvarCurrentValue, typeof(T)) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (LineSplit.Length < 2)
|
||||||
|
{
|
||||||
|
var e = new Exceptions.DvarException($"DVAR \"{dvarName}\" does not exist");
|
||||||
|
e.Data["dvar_name"] = dvarName;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] ValueSplit = LineSplit[1].Split(new char[] { '"' });
|
||||||
|
|
||||||
|
if (ValueSplit.Length == 0)
|
||||||
|
{
|
||||||
|
var e = new Exceptions.DvarException($"DVAR \"{dvarName}\" does not exist");
|
||||||
|
e.Data["dvar_name"] = dvarName;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
string DvarName = dvarName;
|
||||||
|
string DvarCurrentValue = Regex.Replace(ValueSplit[1], @"\^[0-9]", "");
|
||||||
|
|
||||||
|
return new DVAR<T>(DvarName) { Value = (T)Convert.ChangeType(DvarCurrentValue, typeof(T)) };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static async Task SetDvarAsync(this Server server, string dvarName, object dvarValue)
|
public static async Task SetDvarAsync(this Server server, string dvarName, object dvarValue)
|
||||||
{
|
{
|
||||||
await server.RemoteConnection.SendQueryAsync(QueryType.DVAR, $"set {dvarName} {dvarValue}");
|
await server.RemoteConnection.SendQueryAsync(QueryType.DVAR, $"set {dvarName} {dvarValue}");
|
||||||
@ -435,7 +499,7 @@ namespace SharedLibraryCore
|
|||||||
#else
|
#else
|
||||||
string[] response = await server.RemoteConnection.SendQueryAsync(QueryType.DVAR, "status");
|
string[] response = await server.RemoteConnection.SendQueryAsync(QueryType.DVAR, "status");
|
||||||
#endif
|
#endif
|
||||||
return Utilities.PlayersFromStatus(response);
|
return server.PlayersFromStatus(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsRunningOnMono() => Type.GetType("Mono.Runtime") != null;
|
public static bool IsRunningOnMono() => Type.GetType("Mono.Runtime") != null;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user