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
|
||||
#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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
CHECK_THREAD;
|
||||
|
@ -60,6 +60,7 @@ public:
|
||||
bool ReadBEUTF16String16(AString & a_Value); // string length as BE short, then string as UTF-16BE
|
||||
bool ReadVarInt (UInt32 & a_Value);
|
||||
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, ...)
|
||||
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 WriteVarInt (UInt32 a_Value);
|
||||
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
|
||||
bool ReadBuf(void * a_Buffer, int a_Count);
|
||||
|
Loading…
Reference in New Issue
Block a user