Re: Executing Commands Through Across Servers
GL HF
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++; }
This is heavily a POC do not use it live >_>
|