started work on T6M parsing rest api
fixed bug in login program preventing regular users from executing commands make log reading async and changed encoding to UTF7
This commit is contained in:
parent
2964fd71b2
commit
2fc2109a2e
@ -12,22 +12,34 @@ namespace Application.EventParsers
|
|||||||
{
|
{
|
||||||
public GameEvent GetEvent(Server server, string logLine)
|
public GameEvent GetEvent(Server server, string logLine)
|
||||||
{
|
{
|
||||||
string[] lineSplit = logLine.Split(';');
|
string cleanedLogLine = Regex.Replace(logLine, @"^ *[0-9]+:[0-9]+ *", "");
|
||||||
string cleanedEventName = Regex.Replace(lineSplit[0], @" +[0-9]+:[0-9]+ +", "");
|
string[] lineSplit = cleanedLogLine.Split(';');
|
||||||
|
|
||||||
if (cleanedEventName[0] == 'K')
|
if (lineSplit[0][0] == 'K')
|
||||||
{
|
{
|
||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
{
|
{
|
||||||
Type = GameEvent.EventType.Script,
|
Type = GameEvent.EventType.Script,
|
||||||
Data = logLine,
|
Data = cleanedLogLine,
|
||||||
Origin = server.GetPlayersAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 6)),
|
Origin = server.GetPlayersAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 6)),
|
||||||
Target = server.GetPlayersAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 2)),
|
Target = server.GetPlayersAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 2)),
|
||||||
Owner = server
|
Owner = server
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cleanedEventName == "say")
|
if (lineSplit[0][0] == 'D')
|
||||||
|
{
|
||||||
|
return new GameEvent()
|
||||||
|
{
|
||||||
|
Type = GameEvent.EventType.Damage,
|
||||||
|
Data = cleanedLogLine,
|
||||||
|
Origin = server.GetPlayersAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 6)),
|
||||||
|
Target = server.GetPlayersAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 2)),
|
||||||
|
Owner = server
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lineSplit[0] == "say")
|
||||||
{
|
{
|
||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
{
|
{
|
||||||
@ -39,7 +51,7 @@ namespace Application.EventParsers
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cleanedEventName.Contains("ShutdownGame"))
|
if (lineSplit[0].Contains("ShutdownGame"))
|
||||||
{
|
{
|
||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
{
|
{
|
||||||
@ -57,7 +69,7 @@ namespace Application.EventParsers
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cleanedEventName.Contains("InitGame"))
|
if (lineSplit[0].Contains("InitGame"))
|
||||||
{
|
{
|
||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
{
|
{
|
||||||
|
@ -313,13 +313,9 @@ namespace IW4MAdmin.Application
|
|||||||
public ClientService GetClientService() => ClientSvc;
|
public ClientService GetClientService() => ClientSvc;
|
||||||
public AliasService GetAliasService() => AliasSvc;
|
public AliasService GetAliasService() => AliasSvc;
|
||||||
public PenaltyService GetPenaltyService() => PenaltySvc;
|
public PenaltyService GetPenaltyService() => PenaltySvc;
|
||||||
|
|
||||||
public IConfigurationHandler<ApplicationConfiguration> GetApplicationSettings() => ConfigHandler;
|
public IConfigurationHandler<ApplicationConfiguration> GetApplicationSettings() => ConfigHandler;
|
||||||
|
|
||||||
public IDictionary<int, Player> GetPrivilegedClients() => PrivilegedClients;
|
public IDictionary<int, Player> GetPrivilegedClients() => PrivilegedClients;
|
||||||
|
|
||||||
public IEventApi GetEventApi() => Api;
|
public IEventApi GetEventApi() => Api;
|
||||||
|
|
||||||
public bool ShutdownRequested() => !Running;
|
public bool ShutdownRequested() => !Running;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,49 @@ using SharedLibraryCore.Objects;
|
|||||||
using SharedLibraryCore.RCon;
|
using SharedLibraryCore.RCon;
|
||||||
using SharedLibraryCore.Exceptions;
|
using SharedLibraryCore.Exceptions;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
|
||||||
namespace Application.RconParsers
|
namespace Application.RconParsers
|
||||||
{
|
{
|
||||||
public class T6MRConParser : IRConParser
|
public class T6MRConParser : IRConParser
|
||||||
{
|
{
|
||||||
|
class T6MResponse
|
||||||
|
{
|
||||||
|
public class SInfo
|
||||||
|
{
|
||||||
|
public short Com_maxclients { get; set; }
|
||||||
|
public string Game { get; set; }
|
||||||
|
public string Gametype { get; set; }
|
||||||
|
public string Mapname { get; set; }
|
||||||
|
public short NumBots { get; set; }
|
||||||
|
public short NumClients { get; set; }
|
||||||
|
public short Round { get; set; }
|
||||||
|
public string Sv_hostname { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PInfo
|
||||||
|
{
|
||||||
|
public short Assists { get; set; }
|
||||||
|
public string Clan { get; set; }
|
||||||
|
public short Deaths { get; set; }
|
||||||
|
public short Downs { get; set; }
|
||||||
|
public short Headshots { get; set; }
|
||||||
|
public short Id { get; set; }
|
||||||
|
public bool IsBot { get; set; }
|
||||||
|
public short Kills { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public short Ping { get; set; }
|
||||||
|
public short Revives { get; set; }
|
||||||
|
public int Score { get; set; }
|
||||||
|
public long Xuid { get; set; }
|
||||||
|
public string Ip { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public SInfo Info { get; set; }
|
||||||
|
public PInfo[] Players { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
private static CommandPrefix Prefixes = new CommandPrefix()
|
private static CommandPrefix Prefixes = new CommandPrefix()
|
||||||
{
|
{
|
||||||
Tell = "tell {0} {1}",
|
Tell = "tell {0} {1}",
|
||||||
@ -65,6 +103,8 @@ namespace Application.RconParsers
|
|||||||
{
|
{
|
||||||
string[] response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND, "status");
|
string[] response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND, "status");
|
||||||
return ClientsFromStatus(response);
|
return ClientsFromStatus(response);
|
||||||
|
|
||||||
|
//return ClientsFromResponse(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> SetDvarAsync(Connection connection, string dvarName, object dvarValue)
|
public async Task<bool> SetDvarAsync(Connection connection, string dvarName, object dvarValue)
|
||||||
@ -74,6 +114,42 @@ namespace Application.RconParsers
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<List<Player>> ClientsFromResponse(Connection conn)
|
||||||
|
{
|
||||||
|
using (var client = new HttpClient())
|
||||||
|
{
|
||||||
|
client.BaseAddress = new Uri($"http://{conn.Endpoint.Address}:{conn.Endpoint.Port}/");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var parameters = new FormUrlEncodedContent(new[]
|
||||||
|
{
|
||||||
|
new KeyValuePair<string, string>("rcon_password", conn.RConPassword)
|
||||||
|
});
|
||||||
|
|
||||||
|
var serverResponse = await client.PostAsync("/info", parameters);
|
||||||
|
var serverResponseObject = Newtonsoft.Json.JsonConvert.DeserializeObject<T6MResponse>(await serverResponse.Content.ReadAsStringAsync());
|
||||||
|
|
||||||
|
return serverResponseObject.Players.Select(p => new Player()
|
||||||
|
{
|
||||||
|
Name = p.Name,
|
||||||
|
NetworkId = p.Xuid,
|
||||||
|
ClientNumber = p.Id,
|
||||||
|
IPAddress = p.Ip.Split(':')[0].ConvertToIP(),
|
||||||
|
Ping = p.Ping,
|
||||||
|
Score = p.Score,
|
||||||
|
IsBot = p.IsBot,
|
||||||
|
}).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (HttpRequestException e)
|
||||||
|
{
|
||||||
|
throw new NetworkException(e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private List<Player> ClientsFromStatus(string[] status)
|
private List<Player> ClientsFromStatus(string[] status)
|
||||||
{
|
{
|
||||||
List<Player> StatusPlayers = new List<Player>();
|
List<Player> StatusPlayers = new List<Player>();
|
||||||
|
@ -48,7 +48,10 @@ namespace IW4MAdmin
|
|||||||
|
|
||||||
override public async Task<bool> AddPlayer(Player polledPlayer)
|
override public async Task<bool> AddPlayer(Player polledPlayer)
|
||||||
{
|
{
|
||||||
if (polledPlayer.Ping == 999 || polledPlayer.Ping < 1 || polledPlayer.ClientNumber > (MaxClients) || polledPlayer.ClientNumber < 0)
|
|
||||||
|
if ((polledPlayer.Ping == 999 && !polledPlayer.IsBot)||
|
||||||
|
polledPlayer.Ping < 1 || polledPlayer.ClientNumber > (MaxClients) ||
|
||||||
|
polledPlayer.ClientNumber < 0)
|
||||||
{
|
{
|
||||||
//Logger.WriteDebug($"Skipping client not in connected state {P}");
|
//Logger.WriteDebug($"Skipping client not in connected state {P}");
|
||||||
return true;
|
return true;
|
||||||
@ -430,6 +433,7 @@ namespace IW4MAdmin
|
|||||||
DateTime lastCount = DateTime.Now;
|
DateTime lastCount = DateTime.Now;
|
||||||
DateTime tickTime = DateTime.Now;
|
DateTime tickTime = DateTime.Now;
|
||||||
bool firstRun = true;
|
bool firstRun = true;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
override public async Task<bool> ProcessUpdatesAsync(CancellationToken cts)
|
override public async Task<bool> ProcessUpdatesAsync(CancellationToken cts)
|
||||||
{
|
{
|
||||||
@ -510,14 +514,13 @@ namespace IW4MAdmin
|
|||||||
|
|
||||||
if (l_size != LogFile.Length())
|
if (l_size != LogFile.Length())
|
||||||
{
|
{
|
||||||
// this should be the longest running task
|
lines = l_size != -1 ? await LogFile.Tail(12) : lines;
|
||||||
await Task.FromResult(lines = LogFile.Tail(12));
|
|
||||||
if (lines != oldLines)
|
if (lines != oldLines)
|
||||||
{
|
{
|
||||||
l_size = LogFile.Length();
|
l_size = LogFile.Length();
|
||||||
int end = (lines.Length == oldLines.Length) ? lines.Length - 1 : Math.Abs((lines.Length - oldLines.Length)) - 1;
|
int end = (lines.Length == oldLines.Length) ? lines.Length - 1 : Math.Abs((lines.Length - oldLines.Length)) - 1;
|
||||||
|
|
||||||
for (int count = 0; count < lines.Length; count++)
|
for (count = 0; count < lines.Length; count++)
|
||||||
{
|
{
|
||||||
if (lines.Length < 1 && oldLines.Length < 1)
|
if (lines.Length < 1 && oldLines.Length < 1)
|
||||||
continue;
|
continue;
|
||||||
@ -561,6 +564,13 @@ namespace IW4MAdmin
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
catch (InvalidOperationException)
|
||||||
|
{
|
||||||
|
Logger.WriteWarning("Event could not parsed properly");
|
||||||
|
Logger.WriteDebug($"Log Line: {lines[count]}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
catch (Exception E)
|
catch (Exception E)
|
||||||
{
|
{
|
||||||
Logger.WriteError($"Encountered error on {IP}:{Port}");
|
Logger.WriteError($"Encountered error on {IP}:{Port}");
|
||||||
@ -654,7 +664,7 @@ namespace IW4MAdmin
|
|||||||
string mainPath = EventParser.GetGameDir();
|
string mainPath = EventParser.GetGameDir();
|
||||||
mainPath = (GameName == Game.IW4 && onelog.Value > 0) ? "main" : mainPath;
|
mainPath = (GameName == Game.IW4 && onelog.Value > 0) ? "main" : mainPath;
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
// basepath.Value = @"\\192.168.88.253\Call of Duty Black Ops II";
|
basepath.Value = @"\\192.168.88.253\Call of Duty Black Ops II";
|
||||||
#endif
|
#endif
|
||||||
string logPath = game.Value == string.Empty ?
|
string logPath = game.Value == string.Empty ?
|
||||||
$"{basepath.Value.Replace('\\', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{mainPath}{Path.DirectorySeparatorChar}{logfile.Value}" :
|
$"{basepath.Value.Replace('\\', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{mainPath}{Path.DirectorySeparatorChar}{logfile.Value}" :
|
||||||
|
@ -36,6 +36,9 @@ namespace IW4MAdmin.Plugins.Login
|
|||||||
|
|
||||||
if (E.Type == GameEvent.EventType.Command)
|
if (E.Type == GameEvent.EventType.Command)
|
||||||
{
|
{
|
||||||
|
if (E.Origin.Level < SharedLibraryCore.Objects.Player.Permission.Moderator)
|
||||||
|
return Task.CompletedTask;
|
||||||
|
|
||||||
if (((Command)E.Extra).Name == new SharedLibraryCore.Commands.CSetPassword().Name &&
|
if (((Command)E.Extra).Name == new SharedLibraryCore.Commands.CSetPassword().Name &&
|
||||||
E.Owner.Manager.GetPrivilegedClients()[E.Origin.ClientId].Password == null)
|
E.Owner.Manager.GetPrivilegedClients()[E.Origin.ClientId].Password == null)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
@ -36,6 +36,7 @@ namespace SharedLibraryCore
|
|||||||
// FROM GAME
|
// FROM GAME
|
||||||
Script,
|
Script,
|
||||||
Kill,
|
Kill,
|
||||||
|
Damage,
|
||||||
Death,
|
Death,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ using System.Text;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace SharedLibraryCore
|
namespace SharedLibraryCore
|
||||||
{
|
{
|
||||||
@ -23,12 +24,6 @@ namespace SharedLibraryCore
|
|||||||
FileCache = cl.GetStringAsync(Location).Result.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
FileCache = cl.GetStringAsync(Location).Result.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string[] Tail(int lineCount)
|
|
||||||
{
|
|
||||||
// Retrieve();
|
|
||||||
return FileCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override long Length()
|
public override long Length()
|
||||||
{
|
{
|
||||||
Retrieve();
|
Retrieve();
|
||||||
@ -44,7 +39,8 @@ namespace SharedLibraryCore
|
|||||||
if (fileName != string.Empty)
|
if (fileName != string.Empty)
|
||||||
{
|
{
|
||||||
Name = fileName;
|
Name = fileName;
|
||||||
Handle = new StreamReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
|
Handle = new StreamReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 4096, true), Encoding.UTF7);
|
||||||
|
|
||||||
sze = Handle.BaseStream.Length;
|
sze = Handle.BaseStream.Length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,20 +66,20 @@ namespace SharedLibraryCore
|
|||||||
return Handle?.ReadToEnd();
|
return Handle?.ReadToEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual String[] Tail(int lineCount)
|
public virtual async Task<String[]> Tail(int lineCount)
|
||||||
{
|
{
|
||||||
var buffer = new List<string>(lineCount);
|
var buffer = new List<string>(lineCount);
|
||||||
string line;
|
string line;
|
||||||
for (int i = 0; i < lineCount; i++)
|
for (int i = 0; i < lineCount; i++)
|
||||||
{
|
{
|
||||||
line = Handle.ReadLine();
|
line = await Handle.ReadLineAsync();
|
||||||
if (line == null) return buffer.ToArray();
|
if (line == null) return buffer.ToArray();
|
||||||
buffer.Add(line);
|
buffer.Add(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
int lastLine = lineCount - 1; //The index of the last line read from the buffer. Everything > this index was read earlier than everything <= this indes
|
int lastLine = lineCount - 1; //The index of the last line read from the buffer. Everything > this index was read earlier than everything <= this indes
|
||||||
|
|
||||||
while (null != (line = Handle.ReadLine()))
|
while (null != (line = await Handle.ReadLineAsync()))
|
||||||
{
|
{
|
||||||
lastLine++;
|
lastLine++;
|
||||||
if (lastLine == lineCount) lastLine = 0;
|
if (lastLine == lineCount) lastLine = 0;
|
||||||
|
@ -77,7 +77,8 @@ namespace SharedLibraryCore.Objects
|
|||||||
public int Score { get; set; }
|
public int Score { get; set; }
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public IList<Dtos.ProfileMeta> Meta { get; set; }
|
public IList<Dtos.ProfileMeta> Meta { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public bool IsBot { get; set; }
|
||||||
private int _ipaddress;
|
private int _ipaddress;
|
||||||
public override int IPAddress
|
public override int IPAddress
|
||||||
{
|
{
|
||||||
|
@ -34,8 +34,8 @@ namespace SharedLibraryCore.RCon
|
|||||||
|
|
||||||
public class Connection
|
public class Connection
|
||||||
{
|
{
|
||||||
IPEndPoint Endpoint;
|
public IPEndPoint Endpoint { get; private set; }
|
||||||
string RConPassword;
|
public string RConPassword { get; private set; }
|
||||||
Socket ServerConnection;
|
Socket ServerConnection;
|
||||||
ILogger Log;
|
ILogger Log;
|
||||||
int FailedSends;
|
int FailedSends;
|
||||||
|
@ -331,7 +331,8 @@ namespace SharedLibraryCore
|
|||||||
Level = client.Level,
|
Level = client.Level,
|
||||||
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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,13 +367,13 @@ namespace SharedLibraryCore
|
|||||||
return pID;
|
return pID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<Dvar<T>> GetDvarAsync<T>(this Server server, string dvarName) => await server.RconParser.GetDvarAsync<T>(server.RemoteConnection, dvarName);
|
public static Task<Dvar<T>> GetDvarAsync<T>(this Server server, string dvarName) => server.RconParser.GetDvarAsync<T>(server.RemoteConnection, dvarName);
|
||||||
|
|
||||||
public static async Task SetDvarAsync(this Server server, string dvarName, object dvarValue) => await server.RconParser.SetDvarAsync(server.RemoteConnection, dvarName, dvarValue);
|
public static Task SetDvarAsync(this Server server, string dvarName, object dvarValue) => server.RconParser.SetDvarAsync(server.RemoteConnection, dvarName, dvarValue);
|
||||||
|
|
||||||
public static async Task<string[]> ExecuteCommandAsync(this Server server, string commandName) => await server.RconParser.ExecuteCommandAsync(server.RemoteConnection, commandName);
|
public static Task<string[]> ExecuteCommandAsync(this Server server, string commandName) => server.RconParser.ExecuteCommandAsync(server.RemoteConnection, commandName);
|
||||||
|
|
||||||
public static async Task<List<Player>> GetStatusAsync(this Server server) => await server.RconParser.GetStatusAsync(server.RemoteConnection);
|
public static Task<List<Player>> GetStatusAsync(this Server server) => server.RconParser.GetStatusAsync(server.RemoteConnection);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user