2018-04-11 18:24:21 -04:00
|
|
|
|
using System;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using SharedLibraryCore.Interfaces;
|
|
|
|
|
using SharedLibraryCore.Objects;
|
|
|
|
|
using SharedLibraryCore;
|
|
|
|
|
using SharedLibraryCore.RCon;
|
|
|
|
|
using SharedLibraryCore.Exceptions;
|
2018-11-05 22:01:29 -05:00
|
|
|
|
using SharedLibraryCore.Database.Models;
|
2018-04-11 18:24:21 -04:00
|
|
|
|
|
2018-08-07 14:43:09 -04:00
|
|
|
|
namespace IW4MAdmin.Application.RconParsers
|
2018-04-11 18:24:21 -04:00
|
|
|
|
{
|
2018-04-13 02:32:30 -04:00
|
|
|
|
class IW4RConParser : IRConParser
|
2018-04-11 18:24:21 -04:00
|
|
|
|
{
|
2018-08-03 22:11:58 -04:00
|
|
|
|
private static readonly CommandPrefix Prefixes = new CommandPrefix()
|
2018-04-13 02:32:30 -04:00
|
|
|
|
{
|
|
|
|
|
Tell = "tellraw {0} {1}",
|
|
|
|
|
Say = "sayraw {0}",
|
|
|
|
|
Kick = "clientkick {0} \"{1}\"",
|
|
|
|
|
Ban = "clientkick {0} \"{1}\"",
|
|
|
|
|
TempBan = "tempbanclient {0} \"{1}\""
|
|
|
|
|
};
|
2018-04-29 16:44:04 -04:00
|
|
|
|
|
2018-08-03 22:11:58 -04:00
|
|
|
|
private static readonly string StatusRegex = @"^( *[0-9]+) +-*([0-9]+) +((?:[A-Z]+|[0-9]+)) +((?:[a-z]|[0-9]){16}|(?:[a-z]|[0-9]){32}|bot[0-9]+|(?:[0-9]+)) *(.{0,32}) +([0-9]+) +(\d+\.\d+\.\d+.\d+\:-*\d{1,5}|0+.0+:-*\d{1,5}|loopback) +(-*[0-9]+) +([0-9]+) *$";
|
2018-04-29 16:44:04 -04:00
|
|
|
|
|
2018-04-11 18:24:21 -04:00
|
|
|
|
public async Task<string[]> ExecuteCommandAsync(Connection connection, string command)
|
|
|
|
|
{
|
2018-08-28 17:32:59 -04:00
|
|
|
|
var response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND, command);
|
2018-05-10 01:34:29 -04:00
|
|
|
|
return response.Skip(1).ToArray();
|
2018-04-11 18:24:21 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<Dvar<T>> GetDvarAsync<T>(Connection connection, string dvarName)
|
|
|
|
|
{
|
|
|
|
|
string[] LineSplit = await connection.SendQueryAsync(StaticHelpers.QueryType.DVAR, dvarName);
|
|
|
|
|
|
2018-04-21 18:18:20 -04:00
|
|
|
|
if (LineSplit.Length < 3)
|
2018-04-11 18:24:21 -04:00
|
|
|
|
{
|
|
|
|
|
var e = new DvarException($"DVAR \"{dvarName}\" does not exist");
|
|
|
|
|
e.Data["dvar_name"] = dvarName;
|
|
|
|
|
throw e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string[] ValueSplit = LineSplit[1].Split(new char[] { '"' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
|
|
2018-04-21 18:18:20 -04:00
|
|
|
|
if (ValueSplit.Length < 5)
|
2018-04-11 18:24:21 -04:00
|
|
|
|
{
|
|
|
|
|
var e = new DvarException($"DVAR \"{dvarName}\" does not exist");
|
|
|
|
|
e.Data["dvar_name"] = dvarName;
|
|
|
|
|
throw e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string DvarName = Regex.Replace(ValueSplit[0], @"\^[0-9]", "");
|
|
|
|
|
string DvarCurrentValue = Regex.Replace(ValueSplit[2], @"\^[0-9]", "");
|
|
|
|
|
string DvarDefaultValue = Regex.Replace(ValueSplit[4], @"\^[0-9]", "");
|
|
|
|
|
|
|
|
|
|
return new Dvar<T>(DvarName)
|
|
|
|
|
{
|
|
|
|
|
Value = (T)Convert.ChangeType(DvarCurrentValue, typeof(T))
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-05 22:01:29 -05:00
|
|
|
|
public async Task<List<EFClient>> GetStatusAsync(Connection connection)
|
2018-04-11 18:24:21 -04:00
|
|
|
|
{
|
|
|
|
|
string[] response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND, "status");
|
|
|
|
|
return ClientsFromStatus(response);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<bool> SetDvarAsync(Connection connection, string dvarName, object dvarValue)
|
|
|
|
|
{
|
|
|
|
|
return (await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND, $"set {dvarName} {dvarValue}")).Length > 0;
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-11 00:52:20 -04:00
|
|
|
|
public virtual CommandPrefix GetCommandPrefixes() => Prefixes;
|
2018-04-13 02:32:30 -04:00
|
|
|
|
|
2018-11-05 22:01:29 -05:00
|
|
|
|
private List<EFClient> ClientsFromStatus(string[] Status)
|
2018-04-11 18:24:21 -04:00
|
|
|
|
{
|
2018-11-05 22:01:29 -05:00
|
|
|
|
List<EFClient> StatusPlayers = new List<EFClient>();
|
2018-04-11 18:24:21 -04:00
|
|
|
|
|
2018-04-21 18:18:20 -04:00
|
|
|
|
if (Status.Length < 4)
|
|
|
|
|
throw new ServerException("Unexpected status response received");
|
|
|
|
|
|
2018-05-03 01:25:49 -04:00
|
|
|
|
int validMatches = 0;
|
2018-04-11 18:24:21 -04:00
|
|
|
|
foreach (String S in Status)
|
|
|
|
|
{
|
|
|
|
|
String responseLine = S.Trim();
|
|
|
|
|
|
2018-04-29 16:44:04 -04:00
|
|
|
|
var regex = Regex.Match(responseLine, StatusRegex, RegexOptions.IgnoreCase);
|
2018-05-03 01:25:49 -04:00
|
|
|
|
|
2018-04-29 16:44:04 -04:00
|
|
|
|
if (regex.Success)
|
2018-04-11 18:24:21 -04:00
|
|
|
|
{
|
2018-05-03 01:25:49 -04:00
|
|
|
|
validMatches++;
|
2018-04-29 16:44:04 -04:00
|
|
|
|
int clientNumber = int.Parse(regex.Groups[1].Value);
|
|
|
|
|
int score = int.Parse(regex.Groups[2].Value);
|
|
|
|
|
|
|
|
|
|
int ping = 999;
|
|
|
|
|
|
|
|
|
|
// their state can be CNCT, ZMBI etc
|
|
|
|
|
if (regex.Groups[3].Value.Length <= 3)
|
|
|
|
|
{
|
|
|
|
|
ping = int.Parse(regex.Groups[3].Value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long networkId = regex.Groups[4].Value.ConvertLong();
|
|
|
|
|
string name = regex.Groups[5].Value.StripColors().Trim();
|
|
|
|
|
int ip = regex.Groups[7].Value.Split(':')[0].ConvertToIP();
|
|
|
|
|
|
2018-11-05 22:01:29 -05:00
|
|
|
|
var P = new EFClient()
|
2018-04-11 18:24:21 -04:00
|
|
|
|
{
|
2018-04-29 16:44:04 -04:00
|
|
|
|
Name = name,
|
|
|
|
|
NetworkId = networkId,
|
|
|
|
|
ClientNumber = clientNumber,
|
2018-08-07 14:43:09 -04:00
|
|
|
|
IPAddress = ip == 0 ? int.MinValue : ip,
|
2018-04-29 16:44:04 -04:00
|
|
|
|
Ping = ping,
|
2018-04-21 18:18:20 -04:00
|
|
|
|
Score = score,
|
2018-08-27 18:07:54 -04:00
|
|
|
|
IsBot = ip == 0,
|
2018-11-05 22:01:29 -05:00
|
|
|
|
State = EFClient.ClientState.Connecting
|
2018-04-11 18:24:21 -04:00
|
|
|
|
};
|
|
|
|
|
StatusPlayers.Add(P);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-05 16:36:26 -04:00
|
|
|
|
// this happens if status is requested while map is rotating
|
2018-05-03 01:25:49 -04:00
|
|
|
|
if (Status.Length > 5 && validMatches == 0)
|
|
|
|
|
{
|
2018-05-24 15:48:57 -04:00
|
|
|
|
throw new ServerException("Server is rotating map");
|
2018-05-03 01:25:49 -04:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-11 18:24:21 -04:00
|
|
|
|
return StatusPlayers;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|