PHP Code:
#include <sourcemod>
#include <socket>
#pragma semicolon 1
#pragma newdecls required
int iRconID = 0xDAB;
int iByteSize = 1;
int iIntSize = 4;
int iRconAuthPacket = 3;
int iRconAuthResponsePacket = 2;
int iRconExecCommandPacket = 2;
char szRconPassword [] = "ihatecsgoserverowners";
char szIP [] = "256.256.256.256";
int iPort = 27016;
Handle hSocket = null;
bool bLoggedIn = false;
methodmap RconLoginInfo < StringMap
{
public RconLoginInfo()
{
return view_as<RconLoginInfo>(new StringMap());
}
public void SetCommand(const char [] cmd)
{
this.SetString("command", cmd);
}
public void SetPassword(const char [] pass)
{
this.SetString("password", pass);
}
public void GetPassword(char [] buffer, int size)
{
this.GetString("password", buffer, size);
}
public void GetCommand(char [] buffer, int size)
{
this.GetString("command", buffer, size);
}
};
public void OnPluginStart()
{
RegConsoleCmd("send_rcon", Send_Rcon);
}
public Action Send_Rcon(int client, int iArgs)
{
char szCMD[128];
GetCmdArgString(szCMD, sizeof(szCMD));
if(hSocket && SocketIsConnected(hSocket) && bLoggedIn)
{
SendCommand(szCMD);
}
else
{
LoginQueueCmd(szCMD);
}
}
void LoginQueueCmd(char [] szCMD)
{
Login(szIP, szRconPassword, iPort, szCMD);
}
void Login(char [] ip, char [] password, int port, char [] cmd = "")
{
hSocket = SocketCreate(SOCKET_TCP, OnSocketError);
RconLoginInfo info = new RconLoginInfo();
if(!info)
{
LogMessage("Failed to create login info string map");
return;
}
info.SetPassword(password);
if(strlen(cmd) > 0)
info.SetCommand(cmd);
SocketSetArg(hSocket, info);
SocketConnect(hSocket, OnSocketConnected, OnSocketReceive, OnSocketDisconnected, ip, port);
}
void SendCommand(char [] szCmd)
{
if(hSocket && SocketIsConnected(hSocket) && bLoggedIn && strlen(szCmd) > 0)
{
int iSize = iIntSize*2 + strlen(szCmd) + 1 + iByteSize;
int iFormatSize = iSize+iIntSize;
char [] szRequest = new char[iFormatSize];
int iCurrentIndex = 0;
WriteInt(szRequest, iSize, iCurrentIndex);
WriteInt(szRequest, iRconID, iCurrentIndex);
WriteInt(szRequest, iRconExecCommandPacket, iCurrentIndex);
WriteString(szRequest, szCmd, iCurrentIndex);
WriteNull(szRequest, iCurrentIndex);
SocketSend(hSocket, szRequest, iFormatSize);
LogMessage("Sent %s as a command!", szCmd);
}
}
public int OnSocketConnected(Handle socket, any pack)
{
//Send RCON auth packets.
char szPassword[128];
RconLoginInfo info = view_as<RconLoginInfo>(pack);
info.GetPassword(szPassword, sizeof(szPassword));
int iSize = iIntSize*2 + strlen(szPassword) + 1 + iByteSize;
int iFormatSize = iSize+iIntSize;
char [] szRequest = new char[iFormatSize];
int iCurrentIndex = 0;
WriteInt(szRequest, iSize, iCurrentIndex);
WriteInt(szRequest, iRconID, iCurrentIndex);
WriteInt(szRequest, iRconAuthPacket, iCurrentIndex);
WriteString(szRequest, szPassword, iCurrentIndex);
WriteNull(szRequest, iCurrentIndex);
SocketSend(socket, szRequest, iFormatSize);
}
public int OnSocketReceive(Handle socket, char [] receivedData, const int dataSize, any pack)
{
if(dataSize <= 0 || bLoggedIn)
return 0;
//int size = GetInt(receivedData, 0);
int id = GetInt(receivedData, 4);
int type = GetInt(receivedData, 8);
LogMessage("Got %i id and %i type", id, type);
if(type != iRconAuthResponsePacket) //We are only going to handle auth responses #POC.
return 0;
if(type == iRconAuthResponsePacket && id != iRconID)
{
LogMessage("Incorrect rcon password");
return 0;
}
LogMessage("Authed");
bLoggedIn = true;
RconLoginInfo info = view_as<RconLoginInfo>(pack);
char szCommand[128];
info.GetCommand(szCommand, sizeof(szCommand));
SendCommand(szCommand);
return 1;
}
public int OnSocketDisconnected(Handle socket, any pack)
{
delete socket;
delete view_as<RconLoginInfo>(pack);
bLoggedIn = false;
hSocket = null;
PrintToServer("Disconnected");
}
public int OnSocketError(Handle socket, const int errorType, const int errorNum, any pack)
{
delete view_as<RconLoginInfo>(pack);
delete socket;
bLoggedIn = false;
hSocket = null;
LogMessage("Socket error Type %i Num %i", errorType, errorNum);
}
int GetInt(char [] buffer, int iIndex)
{
return ((buffer[iIndex+3] & 0xff) << 24) | ((buffer[iIndex+2] & 0xff) << 16) | ((buffer[iIndex+1] & 0xff) << 8) | (buffer[iIndex] & 0xff);
}
void WriteInt(char [] buffer, int iInt, int &iPackIndex)
{
for(int i = 0; i < iIntSize; i++)
{
buffer[iPackIndex] = (iInt >> (8*i)) & 0xff;
iPackIndex++;
}
}
void WriteString(char [] buffer, char [] szString, int &iPackIndex)
{
for(int i = 0; i < strlen(szString) + 1; i++)
{
buffer[iPackIndex] = szString[i];
iPackIndex++;
}
}
void WriteNull(char [] buffer, int &iPackIndex)
{
buffer[iPackIndex] = 0x00;
iPackIndex++;
}