diff --git a/rcon/main.cpp b/rcon/main.cpp new file mode 100644 index 0000000..e64504f --- /dev/null +++ b/rcon/main.cpp @@ -0,0 +1,202 @@ +#include "main.h" + +//-------------------------------------------------- + +bool bQuitApp = false; +HANDLE hConsoleExecuteEvent; +SOCKET s = INVALID_SOCKET; +char* szHost = NULL; +WORD wPort = 0; +char* szPassword= NULL; +sockaddr_in to; +BYTE ipblock[4] = { 0 }; + +//-------------------------------------------------- + +void logprintf(char* format, ...) +{ + va_list ap; + va_start(ap, format); + char buffer[512]; + vsprintf(buffer, format, ap); + va_end(ap); + puts(buffer); +} + +//-------------------------------------------------- + +BOOL WINAPI CtrlHandler(DWORD dwType) +{ + switch (dwType) + { + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: + case CTRL_CLOSE_EVENT: + case CTRL_LOGOFF_EVENT: + case CTRL_SHUTDOWN_EVENT: + bQuitApp = true; + return TRUE; + } + return FALSE; +} + +//-------------------------------------------------- + +DWORD WINAPI NetworkPumpThread(void* pParam) +{ + int to_size = sizeof(to); + char buf[1024]; + int len; + while (true) + { + Sleep(100); + + len = recvfrom(s, buf, sizeof(buf), 0, (sockaddr*)&to, &to_size); + if (len > 13) + { + char* buf_ptr = &buf[11]; + WORD wStrLen = *(WORD*)buf_ptr; + buf_ptr += sizeof(WORD); + char* szMsg = (char*)malloc(wStrLen + 1); + memcpy(szMsg, buf_ptr, wStrLen); + szMsg[wStrLen] = 0; + logprintf("%s", szMsg); + free(szMsg); + } + } + return 0; +} + +//-------------------------------------------------- + +void SendCommand(char* szCommand); + +//-------------------------------------------------- + +DWORD WINAPI ConsoleInputThread(void* pParam) +{ + while (true) + { + Sleep(100); + + char buf[512]; + DWORD dwRead; + ReadConsole(GetStdHandle(STD_INPUT_HANDLE), buf, 512, &dwRead, NULL); + if (dwRead > 2) + { + buf[dwRead-2] = 0; + SendCommand(buf); + } + } + return 0; +} + +//-------------------------------------------------- + +void SendCommand(char* szCommand) +{ + char* newdata = (char*)malloc(11 + strlen(szCommand) + strlen(szPassword) + (sizeof(WORD) * 2)); + char* keep_ptr = newdata; + *(DWORD*)newdata = 0x504D4153; + newdata += sizeof(DWORD); + *(BYTE*)newdata = ipblock[0]; + newdata += sizeof(BYTE); + *(BYTE*)newdata = ipblock[1]; + newdata += sizeof(BYTE); + *(BYTE*)newdata = ipblock[2]; + newdata += sizeof(BYTE); + *(BYTE*)newdata = ipblock[3]; + newdata += sizeof(BYTE); + *(WORD*)newdata = wPort; + newdata += sizeof(WORD); + *newdata = 'x'; + newdata++; + + WORD wStrLen = (WORD)strlen(szPassword); + *(WORD*)newdata = wStrLen; + newdata += sizeof(WORD); + memcpy(newdata, szPassword, wStrLen); + newdata += wStrLen; + + wStrLen = (WORD)strlen(szCommand); + *(WORD*)newdata = wStrLen; + newdata += sizeof(WORD); + memcpy(newdata, szCommand, wStrLen); + newdata += wStrLen; + + sendto(s, keep_ptr, (int)(newdata - keep_ptr), 0, (sockaddr*)&to, sizeof(to)); + free(keep_ptr); +} + +//-------------------------------------------------- + +int main (int argc, char** argv) +{ + WSADATA wsaData; + WSAStartup(0x0202, &wsaData); + + // Print welcome message. + puts("\n SA:MP Command Line Remote Console Client"); + puts(" ----------------------------------------"); + puts(" (C) Copyright 2005-2006 SA:MP Team, v1.0\n"); + + // If there's not enough command line args, print usage. + if (argc < 3) + { + puts(" Usage:"); + puts(" rcon "); + exit(0); + } + + char* szHost = argv[1]; + + hostent* he = gethostbyname(szHost); + if (he) + { + in_addr in; + memcpy(&in, he->h_addr, he->h_length); + szHost = inet_ntoa(in); + } + + int ip = inet_addr(szHost); + if (ip == -1) + { + logprintf("ERROR: Bad host."); + return 0; + } + + sscanf(szHost, "%d.%d.%d.%d", &ipblock[0], &ipblock[1], &ipblock[2], &ipblock[3]); + wPort = (WORD)atoi(argv[2]); + szPassword = argv[3]; + logprintf("Remote Console: %d.%d.%d.%d:%d...\n", ipblock[0], ipblock[1], ipblock[2], ipblock[3], wPort); + + to.sin_family = AF_INET; + to.sin_port = htons(wPort); + to.sin_addr.s_addr = inet_addr(szHost); + + s = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); + sockaddr_in s_in; + s_in.sin_addr.S_un.S_addr = INADDR_ANY; + s_in.sin_family = AF_INET; + s_in.sin_port = 0; + bind(s, (sockaddr*)&s_in, sizeof(s_in)); + + // Setup the console + SetConsoleCtrlHandler(CtrlHandler, TRUE); + DWORD dwThreadId; + HANDLE hConsoleThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ConsoleInputThread, NULL, 0, &dwThreadId); + HANDLE hNetworkThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)NetworkPumpThread, NULL, 0, &dwThreadId); + + SendCommand("echo RCON admin connected to server."); + + // While not wanting to quit... + while (!bQuitApp) + { + Sleep(100); + } + + return 0; +} + +//-------------------------------------------------- +// EOF \ No newline at end of file diff --git a/rcon/main.h b/rcon/main.h new file mode 100644 index 0000000..7485112 --- /dev/null +++ b/rcon/main.h @@ -0,0 +1,11 @@ +#pragma once + +#pragma comment(lib, "wsock32.lib") + +#include +#include +#include + +extern bool bQuitApp; + +void logprintf(char* format, ...); \ No newline at end of file diff --git a/rcon/rcon.dsp b/rcon/rcon.dsp index 3ae31cd..db513c7 100644 --- a/rcon/rcon.dsp +++ b/rcon/rcon.dsp @@ -48,8 +48,8 @@ BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 !ELSEIF "$(CFG)" == "rcon - Win32 Debug" @@ -63,16 +63,16 @@ LINK32=link.exe # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept !ENDIF @@ -83,10 +83,18 @@ LINK32=link.exe # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\main.cpp +# End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\main.h +# End Source File # End Group # Begin Group "Resource Files" diff --git a/rcon/rcon.ncb b/rcon/rcon.ncb index b1a02a8..1dadd45 100644 Binary files a/rcon/rcon.ncb and b/rcon/rcon.ncb differ diff --git a/rcon/rcon.opt b/rcon/rcon.opt index 57fc3df..a5ec287 100644 Binary files a/rcon/rcon.opt and b/rcon/rcon.opt differ