2015-03-08 17:20:10 -04:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Net;
|
|
|
|
|
using System.Net.Sockets;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
|
|
|
|
|
//DILEMMA -- Seperate intance of RCON for each server or no?
|
|
|
|
|
namespace IW4MAdmin
|
|
|
|
|
{
|
|
|
|
|
class RCON
|
|
|
|
|
{
|
|
|
|
|
enum Type
|
|
|
|
|
{
|
|
|
|
|
Query,
|
|
|
|
|
Execute,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public RCON(Server I)
|
|
|
|
|
{
|
|
|
|
|
sv_connection = new UdpClient();
|
|
|
|
|
sv_connection.Client.SendTimeout = 1000;
|
|
|
|
|
sv_connection.Client.ReceiveTimeout = 1000;
|
|
|
|
|
Instance = I;
|
2015-03-13 19:40:16 -04:00
|
|
|
|
toSend = new Queue<RCON_Request>();
|
2015-03-08 17:20:10 -04:00
|
|
|
|
}
|
2015-03-09 21:28:37 -04:00
|
|
|
|
|
2015-03-08 17:20:10 -04:00
|
|
|
|
//We want to read the reponse
|
|
|
|
|
public String[] responseSendRCON(String message)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2015-03-13 19:40:16 -04:00
|
|
|
|
String STR_REQUEST = String.Empty;
|
2015-03-08 17:20:10 -04:00
|
|
|
|
if (message != "getstatus")
|
2015-03-13 19:40:16 -04:00
|
|
|
|
STR_REQUEST = String.Format("ÿÿÿÿrcon {0} {1}", Instance.getPassword(), message);
|
2015-03-08 17:20:10 -04:00
|
|
|
|
else
|
|
|
|
|
STR_REQUEST = String.Format("ÿÿÿÿ getstatus");
|
|
|
|
|
|
|
|
|
|
Byte[] Request_ = Encoding.Unicode.GetBytes(STR_REQUEST);
|
|
|
|
|
Byte[] Request = new Byte[Request_.Length/2];
|
|
|
|
|
|
|
|
|
|
int count = 0; //This is kinda hacky but Unicode -> ASCII doesn't seem to be working correctly for this.
|
|
|
|
|
foreach (Byte b in Request_)
|
|
|
|
|
{
|
|
|
|
|
if (b != 0)
|
|
|
|
|
Request[count/2] = b;
|
|
|
|
|
count++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
System.Net.IPAddress IP = System.Net.IPAddress.Parse(Instance.getIP());
|
|
|
|
|
IPEndPoint endPoint = new IPEndPoint(IP, Instance.getPort());
|
|
|
|
|
|
|
|
|
|
sv_connection.Connect(endPoint);
|
|
|
|
|
sv_connection.Send(Request, Request.Length);
|
|
|
|
|
|
2015-03-13 19:40:16 -04:00
|
|
|
|
String incoming = String.Empty;
|
|
|
|
|
byte[] bufferRecv = new byte[65536];
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
// loop on receiving the bytes
|
|
|
|
|
bufferRecv = sv_connection.Receive(ref endPoint);
|
|
|
|
|
|
|
|
|
|
// only decode the bytes received
|
|
|
|
|
incoming += (Encoding.ASCII.GetString(bufferRecv, 0, bufferRecv.Length));
|
|
|
|
|
} while (sv_connection.Available > 0);
|
|
|
|
|
|
|
|
|
|
int num = int.Parse("0a", System.Globalization.NumberStyles.AllowHexSpecifier);
|
2015-03-08 17:20:10 -04:00
|
|
|
|
|
2015-03-13 19:40:16 -04:00
|
|
|
|
String[] response = incoming.Split(new char[] {(char)num} , StringSplitOptions.RemoveEmptyEntries);
|
2015-03-10 16:45:20 -04:00
|
|
|
|
|
|
|
|
|
if(response[1] == "Invalid password.")
|
|
|
|
|
{
|
|
|
|
|
Instance.Log.Write("Invalid RCON password specified", Log.Level.Debug);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
return response;
|
2015-03-08 17:20:10 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
catch (SocketException)
|
|
|
|
|
{
|
|
|
|
|
Instance.Log.Write("Unable to reach server for sending RCON", Log.Level.Debug);
|
2015-03-13 19:40:16 -04:00
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
catch (System.InvalidOperationException)
|
|
|
|
|
{
|
|
|
|
|
Instance.Log.Write("RCON Connection terminated by server. Uh-OH", Log.Level.Debug);
|
2015-03-08 17:20:10 -04:00
|
|
|
|
sv_connection.Close();
|
2015-03-13 19:40:16 -04:00
|
|
|
|
sv_connection = new UdpClient();
|
2015-03-08 17:20:10 -04:00
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-13 19:40:16 -04:00
|
|
|
|
public String[] addRCON(String Message)
|
2015-03-08 17:20:10 -04:00
|
|
|
|
{
|
2015-03-13 19:40:16 -04:00
|
|
|
|
RCON_Request newReq = new RCON_Request(Message);
|
|
|
|
|
toSend.Enqueue(newReq);
|
|
|
|
|
return newReq.waitForResponse();
|
2015-03-08 17:20:10 -04:00
|
|
|
|
}
|
|
|
|
|
|
2015-03-16 16:40:30 -04:00
|
|
|
|
public void Reset()
|
|
|
|
|
{
|
|
|
|
|
sv_connection.Close();
|
|
|
|
|
sv_connection = new UdpClient();
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-08 17:20:10 -04:00
|
|
|
|
public void ManageRCONQueue()
|
|
|
|
|
{
|
2015-03-14 12:42:36 -04:00
|
|
|
|
while (Instance.isRunning)
|
2015-03-08 17:20:10 -04:00
|
|
|
|
{
|
|
|
|
|
if (toSend.Count > 0)
|
|
|
|
|
{
|
2015-03-13 19:40:16 -04:00
|
|
|
|
RCON_Request Current = toSend.Peek();
|
|
|
|
|
Current.Response = responseSendRCON(Current.Request);
|
2015-03-08 17:20:10 -04:00
|
|
|
|
toSend.Dequeue();
|
2015-03-11 21:25:14 -04:00
|
|
|
|
Utilities.Wait(0.567);
|
2015-03-08 17:20:10 -04:00
|
|
|
|
}
|
2015-03-09 21:28:37 -04:00
|
|
|
|
else
|
2015-03-11 21:25:14 -04:00
|
|
|
|
Utilities.Wait(0.01);
|
2015-03-08 17:20:10 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private UdpClient sv_connection;
|
|
|
|
|
private Server Instance;
|
2015-03-13 19:40:16 -04:00
|
|
|
|
private Queue<RCON_Request> toSend;
|
2015-03-08 17:20:10 -04:00
|
|
|
|
}
|
2015-03-13 19:40:16 -04:00
|
|
|
|
|
|
|
|
|
class RCON_Request
|
|
|
|
|
{
|
|
|
|
|
public RCON_Request(String IN)
|
|
|
|
|
{
|
|
|
|
|
Request = IN;
|
|
|
|
|
Response = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String[] waitForResponse()
|
|
|
|
|
{
|
|
|
|
|
DateTime Start = DateTime.Now;
|
|
|
|
|
DateTime Current = DateTime.Now;
|
|
|
|
|
while (Response == null && (Current-Start).TotalMilliseconds < 1000)
|
|
|
|
|
{
|
|
|
|
|
Thread.Sleep(1);
|
|
|
|
|
Current = DateTime.Now;
|
|
|
|
|
}
|
|
|
|
|
return Response;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String Request;
|
|
|
|
|
public String[] Response;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-08 17:20:10 -04:00
|
|
|
|
}
|