parent
c10daa8530
commit
dbb76ef9fe
7
Tools/RCONClient/.gitignore
vendored
Normal file
7
Tools/RCONClient/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
Debug/
|
||||||
|
logs/
|
||||||
|
Release/
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.ncb
|
||||||
|
*.sdf
|
10
Tools/RCONClient/Globals.cpp
Normal file
10
Tools/RCONClient/Globals.cpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
// Globals.cpp
|
||||||
|
|
||||||
|
// This file is used for precompiled header generation in MSVC environments
|
||||||
|
|
||||||
|
#include "Globals.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
208
Tools/RCONClient/Globals.h
Normal file
208
Tools/RCONClient/Globals.h
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
|
||||||
|
// Globals.h
|
||||||
|
|
||||||
|
// This file gets included from every module in the project, so that global symbols may be introduced easily
|
||||||
|
// Also used for precompiled header generation in MSVC environments
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Compiler-dependent stuff:
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
// MSVC produces warning C4481 on the override keyword usage, so disable the warning altogether
|
||||||
|
#pragma warning(disable:4481)
|
||||||
|
|
||||||
|
// Disable some warnings that we don't care about:
|
||||||
|
#pragma warning(disable:4100)
|
||||||
|
|
||||||
|
#define OBSOLETE __declspec(deprecated)
|
||||||
|
|
||||||
|
// No alignment needed in MSVC
|
||||||
|
#define ALIGN_8
|
||||||
|
#define ALIGN_16
|
||||||
|
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
|
||||||
|
// TODO: Can GCC explicitly mark classes as abstract (no instances can be created)?
|
||||||
|
#define abstract
|
||||||
|
|
||||||
|
// TODO: Can GCC mark virtual methods as overriding (forcing them to have a virtual function of the same signature in the base class)
|
||||||
|
#define override
|
||||||
|
|
||||||
|
#define OBSOLETE __attribute__((deprecated))
|
||||||
|
|
||||||
|
#define ALIGN_8 __attribute__((aligned(8)))
|
||||||
|
#define ALIGN_16 __attribute__((aligned(16)))
|
||||||
|
|
||||||
|
// Some portability macros :)
|
||||||
|
#define stricmp strcasecmp
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#error "You are using an unsupported compiler, you might need to #define some stuff here for your compiler"
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Copy and uncomment this into another #elif section based on your compiler identification
|
||||||
|
|
||||||
|
// Explicitly mark classes as abstract (no instances can be created)
|
||||||
|
#define abstract
|
||||||
|
|
||||||
|
// Mark virtual methods as overriding (forcing them to have a virtual function of the same signature in the base class)
|
||||||
|
#define override
|
||||||
|
|
||||||
|
// Mark functions as obsolete, so that their usage results in a compile-time warning
|
||||||
|
#define OBSOLETE
|
||||||
|
|
||||||
|
// Mark types / variables for alignment. Do the platforms need it?
|
||||||
|
#define ALIGN_8
|
||||||
|
#define ALIGN_16
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Integral types with predefined sizes:
|
||||||
|
typedef long long Int64;
|
||||||
|
typedef int Int32;
|
||||||
|
typedef short Int16;
|
||||||
|
|
||||||
|
typedef unsigned long long UInt64;
|
||||||
|
typedef unsigned int UInt32;
|
||||||
|
typedef unsigned short UInt16;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// A macro to disallow the copy constructor and operator= functions
|
||||||
|
// This should be used in the private: declarations for any class that shouldn't allow copying itself
|
||||||
|
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||||
|
TypeName(const TypeName &); \
|
||||||
|
void operator=(const TypeName &)
|
||||||
|
|
||||||
|
// A macro that is used to mark unused function parameters, to avoid pedantic warnings in gcc
|
||||||
|
#define UNUSED(X) (void)(X)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// OS-dependent stuff:
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
|
#define _WIN32_WINNT 0x501 // We want to target WinXP and higher
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <Ws2tcpip.h> // IPv6 stuff
|
||||||
|
|
||||||
|
// Windows SDK defines min and max macros, messing up with our std::min and std::max usage
|
||||||
|
#undef min
|
||||||
|
#undef max
|
||||||
|
|
||||||
|
// Windows SDK defines GetFreeSpace as a constant, probably a Win16 API remnant
|
||||||
|
#ifdef GetFreeSpace
|
||||||
|
#undef GetFreeSpace
|
||||||
|
#endif // GetFreeSpace
|
||||||
|
#else
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h> // for mkdir
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#if !defined(ANDROID_NDK)
|
||||||
|
#include <tr1/memory>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ANDROID_NDK)
|
||||||
|
#define USE_SQUIRREL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ANDROID_NDK)
|
||||||
|
#define FILE_IO_PREFIX "/sdcard/mcserver/"
|
||||||
|
#else
|
||||||
|
#define FILE_IO_PREFIX ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// CRT stuff:
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// STL stuff:
|
||||||
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
#include <deque>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Common headers (part 1, without macros):
|
||||||
|
#include "StringUtils.h"
|
||||||
|
#include "OSSupport/CriticalSection.h"
|
||||||
|
#include "OSSupport/File.h"
|
||||||
|
#include "MCLogger.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Common definitions:
|
||||||
|
|
||||||
|
/// Evaluates to the number of elements in an array (compile-time!)
|
||||||
|
#define ARRAYCOUNT(X) (sizeof(X) / sizeof(*(X)))
|
||||||
|
|
||||||
|
/// Allows arithmetic expressions like "32 KiB" (but consider using parenthesis around it, "(32 KiB)" )
|
||||||
|
#define KiB * 1024
|
||||||
|
|
||||||
|
/// Faster than (int)floorf((float)x / (float)div)
|
||||||
|
#define FAST_FLOOR_DIV( x, div ) ( (x) < 0 ? (((int)x / div) - 1) : ((int)x / div) )
|
||||||
|
|
||||||
|
// Own version of assert() that writes failed assertions to the log for review
|
||||||
|
#ifdef NDEBUG
|
||||||
|
#define ASSERT(x) ((void)0)
|
||||||
|
#else
|
||||||
|
#define ASSERT assert
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Pretty much the same as ASSERT() but stays in Release builds
|
||||||
|
#define VERIFY( x ) ( !!(x) || ( LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), exit(1), 0 ) )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
332
Tools/RCONClient/RCONClient.cpp
Normal file
332
Tools/RCONClient/RCONClient.cpp
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
|
||||||
|
// RCONClient.cpp
|
||||||
|
|
||||||
|
// Implements the main app entrypoint
|
||||||
|
|
||||||
|
#include "Globals.h"
|
||||||
|
#include "OSSupport/Socket.h"
|
||||||
|
#include "ByteBuffer.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// If set to true, verbose messages are output to stderr. Use the "-v" or "--verbose" param to turn on
|
||||||
|
bool g_IsVerbose = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// This class can read and write RCON packets to / from a connected socket
|
||||||
|
class cRCONPacketizer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ptCommand = 2,
|
||||||
|
ptLogin = 3,
|
||||||
|
} ;
|
||||||
|
|
||||||
|
cRCONPacketizer(cSocket & a_Socket);
|
||||||
|
|
||||||
|
/// Sends the packet to the socket and waits until the response is received.
|
||||||
|
/// Returns true if response successfully received, false if the client disconnected or protocol error.
|
||||||
|
/// Dumps the reply payload to stdout.
|
||||||
|
bool SendPacket(int a_PacketType, const AString & a_PacketPayload);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// The socket to use for reading incoming data and writing outgoing data:
|
||||||
|
cSocket & m_Socket;
|
||||||
|
|
||||||
|
/// The RequestID of the packet that is being sent. Incremented when the reply is received
|
||||||
|
int m_RequestID;
|
||||||
|
|
||||||
|
/// Receives the full response and dumps its payload to stdout.
|
||||||
|
/// Returns true if successful, false if the client disconnected or protocol error.
|
||||||
|
bool ReceiveResponse(void);
|
||||||
|
|
||||||
|
/// Parses the received response packet and dumps its payload to stdout.
|
||||||
|
/// Returns true if successful, false on protocol error
|
||||||
|
/// Assumes that the packet length has already been read from the packet
|
||||||
|
/// If the packet is successfully parsed, increments m_RequestID
|
||||||
|
bool ParsePacket(cByteBuffer & a_Buffer, int a_PacketLength);
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cRCONPacketizer::cRCONPacketizer(cSocket & a_Socket) :
|
||||||
|
m_Socket(a_Socket),
|
||||||
|
m_RequestID(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cRCONPacketizer::SendPacket(int a_PacketType, const AString & a_PacketPayload)
|
||||||
|
{
|
||||||
|
// Send the packet:
|
||||||
|
cByteBuffer bb(a_PacketPayload.size() + 30);
|
||||||
|
bb.WriteLEInt(m_RequestID);
|
||||||
|
bb.WriteLEInt(a_PacketType);
|
||||||
|
bb.WriteBuf(a_PacketPayload.data(), a_PacketPayload.size());
|
||||||
|
bb.WriteBEShort(0); // Padding
|
||||||
|
AString Packet;
|
||||||
|
bb.ReadAll(Packet);
|
||||||
|
size_t Length = Packet.size();
|
||||||
|
if (!m_Socket.Send((const char *)&Length, 4))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Network error while sending packet: %d (%s). Aborting.",
|
||||||
|
cSocket::GetLastError(), cSocket::GetLastErrorString().c_str()
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!m_Socket.Send(Packet.data(), Packet.size()))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Network error while sending packet: %d (%s). Aborting.",
|
||||||
|
cSocket::GetLastError(), cSocket::GetLastErrorString().c_str()
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ReceiveResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cRCONPacketizer::ReceiveResponse(void)
|
||||||
|
{
|
||||||
|
// Receive the response:
|
||||||
|
cByteBuffer Buffer(64 KiB);
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
int NumReceived = m_Socket.Receive(buf, sizeof(buf), 0);
|
||||||
|
if (NumReceived == 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "The remote end closed the connection. Aborting.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (NumReceived < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Network error while receiving response: %d, %d (%s). Aborting.",
|
||||||
|
NumReceived, cSocket::GetLastError(), cSocket::GetLastErrorString().c_str()
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Buffer.Write(buf, NumReceived);
|
||||||
|
Buffer.ResetRead();
|
||||||
|
|
||||||
|
// Check if the buffer contains the full packet:
|
||||||
|
if (!Buffer.CanReadBytes(14))
|
||||||
|
{
|
||||||
|
// 14 is the minimum packet size for RCON
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int PacketSize;
|
||||||
|
VERIFY(Buffer.ReadLEInt(PacketSize));
|
||||||
|
if (!Buffer.CanReadBytes(PacketSize))
|
||||||
|
{
|
||||||
|
// The packet is not complete yet
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the packet
|
||||||
|
return ParsePacket(Buffer, PacketSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cRCONPacketizer::ParsePacket(cByteBuffer & a_Buffer, int a_PacketLength)
|
||||||
|
{
|
||||||
|
// Check that the request ID is equal
|
||||||
|
bool IsValid = true;
|
||||||
|
int RequestID = 0;
|
||||||
|
VERIFY(a_Buffer.ReadLEInt(RequestID));
|
||||||
|
if (RequestID != m_RequestID)
|
||||||
|
{
|
||||||
|
if ((RequestID == -1) && (m_RequestID == 0))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Login failed. Aborting.");
|
||||||
|
IsValid = false;
|
||||||
|
// Continue, so that the payload is printed before the program aborts.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "The server returned an invalid request ID, got %d, exp. %d. Aborting.", RequestID, m_RequestID);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the packet type:
|
||||||
|
int PacketType = 0;
|
||||||
|
VERIFY(a_Buffer.ReadLEInt(PacketType));
|
||||||
|
if (PacketType != ptCommand)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "The server returned an unknown packet type: %d. Aborting.", PacketType);
|
||||||
|
IsValid = false;
|
||||||
|
// Continue, so that the payload is printed before the program aborts.
|
||||||
|
}
|
||||||
|
|
||||||
|
AString Payload;
|
||||||
|
VERIFY(a_Buffer.ReadString(Payload, a_PacketLength - 10));
|
||||||
|
|
||||||
|
// Dump the payload to stdout, in a binary mode
|
||||||
|
fwrite(Payload.data(), Payload.size(), 1, stdout);
|
||||||
|
|
||||||
|
if (IsValid)
|
||||||
|
{
|
||||||
|
m_RequestID++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// main:
|
||||||
|
|
||||||
|
int RealMain(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
new cMCLogger; // Create a new logger
|
||||||
|
|
||||||
|
// Parse the cmdline params for server IP, port, password and the commands to send:
|
||||||
|
AString ServerAddress, Password;
|
||||||
|
int ServerPort = -1;
|
||||||
|
AStringVector Commands;
|
||||||
|
for (int i = 1; i < argc; i++)
|
||||||
|
{
|
||||||
|
if (((NoCaseCompare(argv[i], "-s") == 0) || (NoCaseCompare(argv[i], "--server") == 0)) && (i < argc - 1))
|
||||||
|
{
|
||||||
|
ServerAddress = argv[i + 1];
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (((NoCaseCompare(argv[i], "-p") == 0) || (NoCaseCompare(argv[i], "--port") == 0)) && (i < argc - 1))
|
||||||
|
{
|
||||||
|
ServerPort = atoi(argv[i + 1]);
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (((NoCaseCompare(argv[i], "-w") == 0) || (NoCaseCompare(argv[i], "--password") == 0)) && (i < argc - 1))
|
||||||
|
{
|
||||||
|
Password = argv[i + 1];
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (((NoCaseCompare(argv[i], "-c") == 0) || (NoCaseCompare(argv[i], "--cmd") == 0) || (NoCaseCompare(argv[i], "--command") == 0)) && (i < argc - 1))
|
||||||
|
{
|
||||||
|
Commands.push_back(argv[i + 1]);
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (((NoCaseCompare(argv[i], "-f") == 0) || (NoCaseCompare(argv[i], "--file") == 0)) && (i < argc - 1))
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
cFile f(argv[i], cFile::fmRead);
|
||||||
|
if (!f.IsOpen())
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Cannot read commands from file \"%s\", aborting.", argv[i]);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
AString cmd;
|
||||||
|
f.ReadRestOfFile(cmd);
|
||||||
|
Commands.push_back(cmd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((NoCaseCompare(argv[i], "-v") == 0) || (NoCaseCompare(argv[i], "--verbose") == 0))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Verbose output enabled\n");
|
||||||
|
g_IsVerbose = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "Unknown parameter: \"%s\". Aborting.", argv[i]);
|
||||||
|
return 1;
|
||||||
|
} // for i - argv[]
|
||||||
|
|
||||||
|
if (ServerAddress.empty() || (ServerPort < 0))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Server address or port not set. Use the --server and --port parameters to set them. Aborting.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect:
|
||||||
|
if (cSocket::WSAStartup() != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Cannot initialize network stack. Aborting\n");
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
if (g_IsVerbose)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Connecting to \"%s:%d\"...\n", ServerAddress.c_str(), ServerPort);
|
||||||
|
}
|
||||||
|
cSocket s = cSocket::CreateSocket(cSocket::IPv4);
|
||||||
|
if (!s.ConnectIPv4(ServerAddress, (unsigned short)ServerPort))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Cannot connect to \"%s:%d\": %s\n", ServerAddress.c_str(), ServerPort, cSocket::GetLastErrorString().c_str());
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
cRCONPacketizer Packetizer(s);
|
||||||
|
|
||||||
|
// Authenticate using the provided password:
|
||||||
|
if (!Password.empty())
|
||||||
|
{
|
||||||
|
if (g_IsVerbose)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Sending the login packet...\n");
|
||||||
|
}
|
||||||
|
if (!Packetizer.SendPacket(cRCONPacketizer::ptLogin, Password))
|
||||||
|
{
|
||||||
|
// Error message has already been printed, bail out
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (g_IsVerbose)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "No password provided, not sending a login packet.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (AStringVector::const_iterator itr = Commands.begin(), end = Commands.end(); itr != end; ++itr)
|
||||||
|
{
|
||||||
|
if (g_IsVerbose)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Sending command \"%s\"...\n", itr->c_str());
|
||||||
|
}
|
||||||
|
if (!Packetizer.SendPacket(cRCONPacketizer::ptCommand, *itr))
|
||||||
|
{
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
// This redirection function is only so that debugging the program is easier in MSVC - when RealMain exits, it's still possible to place a breakpoint
|
||||||
|
int res = RealMain(argc, argv);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
20
Tools/RCONClient/RCONClient.sln
Normal file
20
Tools/RCONClient/RCONClient.sln
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||||
|
# Visual C++ Express 2008
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RCONClient", "RCONClient.vcproj", "{1A48B032-07D0-4DDD-8362-66C0FC7F7849}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{1A48B032-07D0-4DDD-8362-66C0FC7F7849}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{1A48B032-07D0-4DDD-8362-66C0FC7F7849}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{1A48B032-07D0-4DDD-8362-66C0FC7F7849}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{1A48B032-07D0-4DDD-8362-66C0FC7F7849}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
287
Tools/RCONClient/RCONClient.vcproj
Normal file
287
Tools/RCONClient/RCONClient.vcproj
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
<?xml version="1.0" encoding="windows-1250"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9,00"
|
||||||
|
Name="RCONClient"
|
||||||
|
ProjectGUID="{1A48B032-07D0-4DDD-8362-66C0FC7F7849}"
|
||||||
|
RootNamespace="RCONClient"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
TargetFrameworkVersion="196613"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="../../source"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="2"
|
||||||
|
PrecompiledHeaderThrough="Globals.h"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="2"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="../../source"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
UsePrecompiledHeader="2"
|
||||||
|
PrecompiledHeaderThrough="Globals.h"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="1"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Globals.cpp"
|
||||||
|
>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
UsePrecompiledHeader="1"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
UsePrecompiledHeader="1"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Globals.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\RCONClient.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<Filter
|
||||||
|
Name="shared"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\source\ByteBuffer.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\source\ByteBuffer.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\source\Log.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\source\Log.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\source\MCLogger.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\source\MCLogger.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\source\StringUtils.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\source\StringUtils.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<Filter
|
||||||
|
Name="OSSupport"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\source\OSSupport\CriticalSection.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\source\OSSupport\CriticalSection.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\source\OSSupport\File.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\source\OSSupport\File.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\source\OSSupport\IsThread.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\source\OSSupport\IsThread.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\source\OSSupport\Socket.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\source\OSSupport\Socket.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Filter>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||||
|
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||||
|
>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
@ -13,6 +13,25 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Try to determine endianness:
|
||||||
|
#if ( \
|
||||||
|
defined(__i386__) || defined(__alpha__) || \
|
||||||
|
defined(__ia64) || defined(__ia64__) || \
|
||||||
|
defined(_M_IX86) || defined(_M_IA64) || \
|
||||||
|
defined(_M_ALPHA) || defined(__amd64) || \
|
||||||
|
defined(__amd64__) || defined(_M_AMD64) || \
|
||||||
|
defined(__x86_64) || defined(__x86_64__) || \
|
||||||
|
defined(_M_X64) || defined(__bfin__) || \
|
||||||
|
defined(__ARMEL__) || \
|
||||||
|
(defined(_WIN32) && defined(__ARM__) && defined(_MSC_VER)) \
|
||||||
|
)
|
||||||
|
#define IS_LITTLE_ENDIAN
|
||||||
|
#elif defined (__ARMEB__)
|
||||||
|
#define IS_BIG_ENDIAN
|
||||||
|
#else
|
||||||
|
#error Cannot determine endianness of this platform
|
||||||
|
#endif
|
||||||
|
|
||||||
// If a string sent over the protocol is larger than this, a warning is emitted to the console
|
// If a string sent over the protocol is larger than this, a warning is emitted to the console
|
||||||
#define MAX_STRING_SIZE (512 KiB)
|
#define MAX_STRING_SIZE (512 KiB)
|
||||||
|
|
||||||
@ -416,6 +435,25 @@ bool cByteBuffer::ReadVarUTF8String(AString & a_Value)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cByteBuffer::ReadLEInt(int & a_Value)
|
||||||
|
{
|
||||||
|
CHECK_THREAD;
|
||||||
|
CheckValid();
|
||||||
|
NEEDBYTES(4);
|
||||||
|
ReadBuf(&a_Value, 4);
|
||||||
|
|
||||||
|
#ifdef IS_BIG_ENDIAN
|
||||||
|
// Convert:
|
||||||
|
a_Value = ((a_Value >> 24) & 0xff) | ((a_Value >> 16) & 0xff00) | ((a_Value >> 8) & 0xff0000) | (a_Value & 0xff000000);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cByteBuffer::WriteChar(char a_Value)
|
bool cByteBuffer::WriteChar(char a_Value)
|
||||||
{
|
{
|
||||||
CHECK_THREAD;
|
CHECK_THREAD;
|
||||||
@ -572,6 +610,22 @@ bool cByteBuffer::WriteVarUTF8String(const AString & a_Value)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cByteBuffer::WriteLEInt(int a_Value)
|
||||||
|
{
|
||||||
|
CHECK_THREAD;
|
||||||
|
CheckValid();
|
||||||
|
#ifdef IS_LITTLE_ENDIAN
|
||||||
|
return WriteBuf((const char *)&a_Value, 4);
|
||||||
|
#else
|
||||||
|
int Value = ((a_Value >> 24) & 0xff) | ((a_Value >> 16) & 0xff00) | ((a_Value >> 8) & 0xff0000) | (a_Value & 0xff000000);
|
||||||
|
return WriteBuf((const char *)&Value, 4);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cByteBuffer::ReadBuf(void * a_Buffer, int a_Count)
|
bool cByteBuffer::ReadBuf(void * a_Buffer, int a_Count)
|
||||||
{
|
{
|
||||||
CHECK_THREAD;
|
CHECK_THREAD;
|
||||||
|
@ -60,6 +60,7 @@ public:
|
|||||||
bool ReadBEUTF16String16(AString & a_Value); // string length as BE short, then string as UTF-16BE
|
bool ReadBEUTF16String16(AString & a_Value); // string length as BE short, then string as UTF-16BE
|
||||||
bool ReadVarInt (UInt32 & a_Value);
|
bool ReadVarInt (UInt32 & a_Value);
|
||||||
bool ReadVarUTF8String (AString & a_Value); // string length as VarInt, then string as UTF-8
|
bool ReadVarUTF8String (AString & a_Value); // string length as VarInt, then string as UTF-8
|
||||||
|
bool ReadLEInt (int & a_Value);
|
||||||
|
|
||||||
/// Reads VarInt, assigns it to anything that can be assigned from an UInt32 (unsigned short, char, Byte, double, ...)
|
/// Reads VarInt, assigns it to anything that can be assigned from an UInt32 (unsigned short, char, Byte, double, ...)
|
||||||
template <typename T> bool ReadVarInt(T & a_Value)
|
template <typename T> bool ReadVarInt(T & a_Value)
|
||||||
@ -85,6 +86,7 @@ public:
|
|||||||
bool WriteBEUTF16String16(const AString & a_Value); // string length as BE short, then string as UTF-16BE
|
bool WriteBEUTF16String16(const AString & a_Value); // string length as BE short, then string as UTF-16BE
|
||||||
bool WriteVarInt (UInt32 a_Value);
|
bool WriteVarInt (UInt32 a_Value);
|
||||||
bool WriteVarUTF8String (const AString & a_Value); // string length as VarInt, then string as UTF-8
|
bool WriteVarUTF8String (const AString & a_Value); // string length as VarInt, then string as UTF-8
|
||||||
|
bool WriteLEInt (int a_Value);
|
||||||
|
|
||||||
/// Reads a_Count bytes into a_Buffer; returns true if successful
|
/// Reads a_Count bytes into a_Buffer; returns true if successful
|
||||||
bool ReadBuf(void * a_Buffer, int a_Count);
|
bool ReadBuf(void * a_Buffer, int a_Count);
|
||||||
|
Loading…
Reference in New Issue
Block a user