167 lines
6.0 KiB
C#
167 lines
6.0 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Text.RegularExpressions;
|
|||
|
using System.Threading.Tasks;
|
|||
|
|
|||
|
using SharedLibraryCore;
|
|||
|
using SharedLibraryCore.Interfaces;
|
|||
|
using SharedLibraryCore.Objects;
|
|||
|
using SharedLibraryCore.RCon;
|
|||
|
using SharedLibraryCore.Exceptions;
|
|||
|
using System.Text;
|
|||
|
using System.Linq;
|
|||
|
using System.Net.Http;
|
|||
|
|
|||
|
namespace Application.RconParsers
|
|||
|
{
|
|||
|
public class IW5MRConParser : IRConParser
|
|||
|
{
|
|||
|
private static CommandPrefix Prefixes = new CommandPrefix()
|
|||
|
{
|
|||
|
Tell = "tell {0} {1}",
|
|||
|
Say = "say {0}",
|
|||
|
Kick = "dropClient {0} \"{1}\"",
|
|||
|
Ban = "dropClient {0} \"{1}\"",
|
|||
|
TempBan = "dropClient {0} \"{1}\""
|
|||
|
};
|
|||
|
|
|||
|
public CommandPrefix GetCommandPrefixes() => Prefixes;
|
|||
|
|
|||
|
public async Task<string[]> ExecuteCommandAsync(Connection connection, string command)
|
|||
|
{
|
|||
|
await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND, command, false);
|
|||
|
return new string[] { "Command Executed" };
|
|||
|
}
|
|||
|
|
|||
|
public async Task<Dvar<T>> GetDvarAsync<T>(Connection connection, string dvarName)
|
|||
|
{
|
|||
|
// why can't this be real :(
|
|||
|
if (dvarName == "version")
|
|||
|
return new Dvar<T>(dvarName)
|
|||
|
{
|
|||
|
Value = (T)Convert.ChangeType("IW5 MP 1.9 build 461 Fri Sep 14 00:04:28 2012 win-x86", typeof(T))
|
|||
|
};
|
|||
|
|
|||
|
if (dvarName == "shortversion")
|
|||
|
return new Dvar<T>(dvarName)
|
|||
|
{
|
|||
|
Value = (T)Convert.ChangeType("1.9", typeof(T))
|
|||
|
};
|
|||
|
|
|||
|
if (dvarName == "mapname")
|
|||
|
return new Dvar<T>(dvarName)
|
|||
|
{
|
|||
|
Value = (T)Convert.ChangeType("Unknown", typeof(T))
|
|||
|
};
|
|||
|
|
|||
|
if (dvarName == "g_gametype")
|
|||
|
return new Dvar<T>(dvarName)
|
|||
|
{
|
|||
|
Value = (T)Convert.ChangeType("Unknown", typeof(T))
|
|||
|
};
|
|||
|
|
|||
|
if (dvarName == "fs_game")
|
|||
|
return new Dvar<T>(dvarName)
|
|||
|
{
|
|||
|
Value = (T)Convert.ChangeType("", typeof(T))
|
|||
|
};
|
|||
|
|
|||
|
if (dvarName == "g_logsync")
|
|||
|
return new Dvar<T>(dvarName)
|
|||
|
{
|
|||
|
Value = (T)Convert.ChangeType(1, typeof(T))
|
|||
|
};
|
|||
|
|
|||
|
if (dvarName == "fs_basepath")
|
|||
|
return new Dvar<T>(dvarName)
|
|||
|
{
|
|||
|
Value = (T)Convert.ChangeType("", typeof(T))
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
|
|||
|
string[] LineSplit = await connection.SendQueryAsync(StaticHelpers.QueryType.DVAR, dvarName);
|
|||
|
|
|||
|
if (LineSplit.Length < 4)
|
|||
|
{
|
|||
|
var e = new 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 DvarException($"DVAR \"{dvarName}\" does not exist");
|
|||
|
e.Data["dvar_name"] = dvarName;
|
|||
|
throw e;
|
|||
|
}
|
|||
|
|
|||
|
string DvarName = dvarName;
|
|||
|
string DvarCurrentValue = Regex.Replace(ValueSplit[3].StripColors(), @"\^[0-9]", "");
|
|||
|
|
|||
|
return new Dvar<T>(DvarName)
|
|||
|
{
|
|||
|
Value = (T)Convert.ChangeType(DvarCurrentValue, typeof(T))
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
public async Task<List<Player>> GetStatusAsync(Connection connection)
|
|||
|
{
|
|||
|
string[] response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND, "status");
|
|||
|
return ClientsFromStatus(response);
|
|||
|
}
|
|||
|
|
|||
|
public async Task<bool> SetDvarAsync(Connection connection, string dvarName, object dvarValue)
|
|||
|
{
|
|||
|
// T6M doesn't respond with anything when a value is set, so we can only hope for the best :c
|
|||
|
await connection.SendQueryAsync(StaticHelpers.QueryType.DVAR, $"set {dvarName} {dvarValue}", false);
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
private List<Player> ClientsFromStatus(string[] status)
|
|||
|
{
|
|||
|
List<Player> StatusPlayers = new List<Player>();
|
|||
|
|
|||
|
foreach (string statusLine in status)
|
|||
|
{
|
|||
|
String responseLine = statusLine;
|
|||
|
|
|||
|
if (Regex.Matches(responseLine, @"^ *\d+", RegexOptions.IgnoreCase).Count > 0) // its a client line!
|
|||
|
{
|
|||
|
String[] playerInfo = responseLine.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|||
|
|
|||
|
// this happens when the client is in a zombie state
|
|||
|
if (playerInfo.Length < 5)
|
|||
|
continue;
|
|||
|
int clientId = -1;
|
|||
|
int Ping = -1;
|
|||
|
|
|||
|
Int32.TryParse(playerInfo[2], out Ping);
|
|||
|
string name = Encoding.UTF8.GetString(Encoding.Convert(Utilities.EncodingType, Encoding.UTF8, Utilities.EncodingType.GetBytes(responseLine.Substring(23, 15).StripColors().Trim())));
|
|||
|
long networkId = playerInfo[4].ConvertLong();
|
|||
|
int.TryParse(playerInfo[0], out clientId);
|
|||
|
var regex = Regex.Match(responseLine, @"\d+\.\d+\.\d+.\d+\:\d{1,5}");
|
|||
|
int ipAddress = regex.Value.Split(':')[0].ConvertToIP();
|
|||
|
regex = Regex.Match(responseLine, @" +(\d+ +){3}");
|
|||
|
int score = Int32.Parse(regex.Value.Split(' ', StringSplitOptions.RemoveEmptyEntries)[0]);
|
|||
|
|
|||
|
StatusPlayers.Add(new Player()
|
|||
|
{
|
|||
|
Name = name,
|
|||
|
NetworkId = networkId,
|
|||
|
ClientNumber = clientId,
|
|||
|
IPAddress = ipAddress,
|
|||
|
Ping = Ping,
|
|||
|
Score = score,
|
|||
|
IsBot = networkId < 1
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return StatusPlayers;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|