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)
|
||||
{
|
||||
string[] lineSplit = logLine.Split(';');
|
||||
string cleanedEventName = Regex.Replace(lineSplit[0], @" +[0-9]+:[0-9]+ +", "");
|
||||
string cleanedLogLine = Regex.Replace(logLine, @"^ *[0-9]+:[0-9]+ *", "");
|
||||
string[] lineSplit = cleanedLogLine.Split(';');
|
||||
|
||||
if (cleanedEventName[0] == 'K')
|
||||
if (lineSplit[0][0] == 'K')
|
||||
{
|
||||
return new GameEvent()
|
||||
{
|
||||
Type = GameEvent.EventType.Script,
|
||||
Data = logLine,
|
||||
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 (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()
|
||||
{
|
||||
@ -39,7 +51,7 @@ namespace Application.EventParsers
|
||||
};
|
||||
}
|
||||
|
||||
if (cleanedEventName.Contains("ShutdownGame"))
|
||||
if (lineSplit[0].Contains("ShutdownGame"))
|
||||
{
|
||||
return new GameEvent()
|
||||
{
|
||||
@ -57,7 +69,7 @@ namespace Application.EventParsers
|
||||
};
|
||||
}
|
||||
|
||||
if (cleanedEventName.Contains("InitGame"))
|
||||
if (lineSplit[0].Contains("InitGame"))
|
||||
{
|
||||
return new GameEvent()
|
||||
{
|
||||
|
@ -313,13 +313,9 @@ namespace IW4MAdmin.Application
|
||||
public ClientService GetClientService() => ClientSvc;
|
||||
public AliasService GetAliasService() => AliasSvc;
|
||||
public PenaltyService GetPenaltyService() => PenaltySvc;
|
||||
|
||||
public IConfigurationHandler<ApplicationConfiguration> GetApplicationSettings() => ConfigHandler;
|
||||
|
||||
public IDictionary<int, Player> GetPrivilegedClients() => PrivilegedClients;
|
||||
|
||||
public IEventApi GetEventApi() => Api;
|
||||
|
||||
public bool ShutdownRequested() => !Running;
|
||||
}
|
||||
}
|
||||
|
@ -9,11 +9,49 @@ using SharedLibraryCore.Objects;
|
||||
using SharedLibraryCore.RCon;
|
||||
using SharedLibraryCore.Exceptions;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace Application.RconParsers
|
||||
{
|
||||
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()
|
||||
{
|
||||
Tell = "tell {0} {1}",
|
||||
@ -65,6 +103,8 @@ namespace Application.RconParsers
|
||||
{
|
||||
string[] response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND, "status");
|
||||
return ClientsFromStatus(response);
|
||||
|
||||
//return ClientsFromResponse(connection);
|
||||
}
|
||||
|
||||
public async Task<bool> SetDvarAsync(Connection connection, string dvarName, object dvarValue)
|
||||
@ -74,6 +114,42 @@ namespace Application.RconParsers
|
||||
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)
|
||||
{
|
||||
List<Player> StatusPlayers = new List<Player>();
|
||||
|
@ -48,7 +48,10 @@ namespace IW4MAdmin
|
||||
|
||||
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}");
|
||||
return true;
|
||||
@ -430,6 +433,7 @@ namespace IW4MAdmin
|
||||
DateTime lastCount = DateTime.Now;
|
||||
DateTime tickTime = DateTime.Now;
|
||||
bool firstRun = true;
|
||||
int count = 0;
|
||||
|
||||
override public async Task<bool> ProcessUpdatesAsync(CancellationToken cts)
|
||||
{
|
||||
@ -510,14 +514,13 @@ namespace IW4MAdmin
|
||||
|
||||
if (l_size != LogFile.Length())
|
||||
{
|
||||
// this should be the longest running task
|
||||
await Task.FromResult(lines = LogFile.Tail(12));
|
||||
lines = l_size != -1 ? await LogFile.Tail(12) : lines;
|
||||
if (lines != oldLines)
|
||||
{
|
||||
l_size = LogFile.Length();
|
||||
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)
|
||||
continue;
|
||||
@ -561,6 +564,13 @@ namespace IW4MAdmin
|
||||
return false;
|
||||
}
|
||||
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
Logger.WriteWarning("Event could not parsed properly");
|
||||
Logger.WriteDebug($"Log Line: {lines[count]}");
|
||||
return false;
|
||||
}
|
||||
|
||||
catch (Exception E)
|
||||
{
|
||||
Logger.WriteError($"Encountered error on {IP}:{Port}");
|
||||
@ -654,7 +664,7 @@ namespace IW4MAdmin
|
||||
string mainPath = EventParser.GetGameDir();
|
||||
mainPath = (GameName == Game.IW4 && onelog.Value > 0) ? "main" : mainPath;
|
||||
#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
|
||||
string logPath = game.Value == string.Empty ?
|
||||
$"{basepath.Value.Replace('\\', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{mainPath}{Path.DirectorySeparatorChar}{logfile.Value}" :
|
||||
@ -680,7 +690,7 @@ namespace IW4MAdmin
|
||||
|
||||
Logger.WriteInfo($"Log file is {logPath}");
|
||||
#if DEBUG
|
||||
// LogFile = new RemoteFile("https://raidmax.org/IW4MAdmin/getlog.php");
|
||||
// LogFile = new RemoteFile("https://raidmax.org/IW4MAdmin/getlog.php");
|
||||
#else
|
||||
await Broadcast("IW4M Admin is now ^2ONLINE");
|
||||
#endif
|
||||
|
@ -36,6 +36,9 @@ namespace IW4MAdmin.Plugins.Login
|
||||
|
||||
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 &&
|
||||
E.Owner.Manager.GetPrivilegedClients()[E.Origin.ClientId].Password == null)
|
||||
return Task.CompletedTask;
|
||||
|
@ -36,6 +36,7 @@ namespace SharedLibraryCore
|
||||
// FROM GAME
|
||||
Script,
|
||||
Kill,
|
||||
Damage,
|
||||
Death,
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ using System.Text;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SharedLibraryCore
|
||||
{
|
||||
@ -23,12 +24,6 @@ namespace SharedLibraryCore
|
||||
FileCache = cl.GetStringAsync(Location).Result.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
public override string[] Tail(int lineCount)
|
||||
{
|
||||
// Retrieve();
|
||||
return FileCache;
|
||||
}
|
||||
|
||||
public override long Length()
|
||||
{
|
||||
Retrieve();
|
||||
@ -44,7 +39,8 @@ namespace SharedLibraryCore
|
||||
if (fileName != string.Empty)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -70,20 +66,20 @@ namespace SharedLibraryCore
|
||||
return Handle?.ReadToEnd();
|
||||
}
|
||||
|
||||
public virtual String[] Tail(int lineCount)
|
||||
public virtual async Task<String[]> Tail(int lineCount)
|
||||
{
|
||||
var buffer = new List<string>(lineCount);
|
||||
string line;
|
||||
for (int i = 0; i < lineCount; i++)
|
||||
{
|
||||
line = Handle.ReadLine();
|
||||
line = await Handle.ReadLineAsync();
|
||||
if (line == null) return buffer.ToArray();
|
||||
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
|
||||
|
||||
while (null != (line = Handle.ReadLine()))
|
||||
while (null != (line = await Handle.ReadLineAsync()))
|
||||
{
|
||||
lastLine++;
|
||||
if (lastLine == lineCount) lastLine = 0;
|
||||
|
@ -77,7 +77,8 @@ namespace SharedLibraryCore.Objects
|
||||
public int Score { get; set; }
|
||||
[NotMapped]
|
||||
public IList<Dtos.ProfileMeta> Meta { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public bool IsBot { get; set; }
|
||||
private int _ipaddress;
|
||||
public override int IPAddress
|
||||
{
|
||||
|
@ -34,8 +34,8 @@ namespace SharedLibraryCore.RCon
|
||||
|
||||
public class Connection
|
||||
{
|
||||
IPEndPoint Endpoint;
|
||||
string RConPassword;
|
||||
public IPEndPoint Endpoint { get; private set; }
|
||||
public string RConPassword { get; private set; }
|
||||
Socket ServerConnection;
|
||||
ILogger Log;
|
||||
int FailedSends;
|
||||
|
@ -331,7 +331,8 @@ namespace SharedLibraryCore
|
||||
Level = client.Level,
|
||||
LastConnection = client.LastConnection == DateTime.MinValue ? DateTime.UtcNow : client.LastConnection,
|
||||
CurrentAlias = client.CurrentAlias,
|
||||
CurrentAliasId = client.CurrentAlias.AliasId
|
||||
CurrentAliasId = client.CurrentAlias.AliasId,
|
||||
IsBot = client.NetworkId == -1
|
||||
};
|
||||
}
|
||||
|
||||
@ -366,13 +367,13 @@ namespace SharedLibraryCore
|
||||
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