diff options
Diffstat (limited to 'Tools')
36 files changed, 2071 insertions, 818 deletions
diff --git a/Tools/AnvilStats/AnvilStats.vcproj b/Tools/AnvilStats/AnvilStats.vcproj index 038f32b97..c7a2e9390 100644 --- a/Tools/AnvilStats/AnvilStats.vcproj +++ b/Tools/AnvilStats/AnvilStats.vcproj @@ -41,7 +41,7 @@ <Tool Name="VCCLCompilerTool" Optimization="0" - AdditionalIncludeDirectories=""..\..\zlib-1.2.7"" + AdditionalIncludeDirectories=""..\..\lib"" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" MinimalRebuild="true" BasicRuntimeChecks="3" @@ -118,7 +118,7 @@ Name="VCCLCompilerTool" Optimization="2" EnableIntrinsicFunctions="true" - AdditionalIncludeDirectories=""..\..\zlib-1.2.7"" + AdditionalIncludeDirectories=""..\..\lib"" PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" RuntimeLibrary="0" EnableFunctionLevelLinking="true" @@ -196,7 +196,7 @@ Name="VCCLCompilerTool" Optimization="2" EnableIntrinsicFunctions="true" - AdditionalIncludeDirectories=""..\..\zlib-1.2.7"" + AdditionalIncludeDirectories=""..\..\lib"" PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" RuntimeLibrary="0" EnableFunctionLevelLinking="true" @@ -374,27 +374,27 @@ Name="shared" > <File - RelativePath="..\..\source\OSSupport\CriticalSection.cpp" + RelativePath="..\..\src\OSSupport\CriticalSection.cpp" > </File> <File - RelativePath="..\..\source\OSSupport\CriticalSection.h" + RelativePath="..\..\src\OSSupport\CriticalSection.h" > </File> <File - RelativePath="..\..\source\Endianness.h" + RelativePath="..\..\src\Endianness.h" > </File> <File - RelativePath="..\..\source\OSSupport\Event.cpp" + RelativePath="..\..\src\OSSupport\Event.cpp" > </File> <File - RelativePath="..\..\source\OSSupport\Event.h" + RelativePath="..\..\src\OSSupport\Event.h" > </File> <File - RelativePath="..\..\source\WorldStorage\FastNBT.cpp" + RelativePath="..\..\src\WorldStorage\FastNBT.cpp" > <FileConfiguration Name="Debug|Win32" @@ -422,39 +422,39 @@ </FileConfiguration> </File> <File - RelativePath="..\..\source\WorldStorage\FastNBT.h" + RelativePath="..\..\src\WorldStorage\FastNBT.h" > </File> <File - RelativePath="..\..\source\OSSupport\File.cpp" + RelativePath="..\..\src\OSSupport\File.cpp" > </File> <File - RelativePath="..\..\source\OSSupport\File.h" + RelativePath="..\..\src\OSSupport\File.h" > </File> <File - RelativePath="..\..\source\OSSupport\GZipFile.cpp" + RelativePath="..\..\src\OSSupport\GZipFile.cpp" > </File> <File - RelativePath="..\..\source\OSSupport\GZipFile.h" + RelativePath="..\..\src\OSSupport\GZipFile.h" > </File> <File - RelativePath="..\..\source\OSSupport\IsThread.cpp" + RelativePath="..\..\src\OSSupport\IsThread.cpp" > </File> <File - RelativePath="..\..\source\OSSupport\IsThread.h" + RelativePath="..\..\src\OSSupport\IsThread.h" > </File> <File - RelativePath="..\..\source\StringUtils.cpp" + RelativePath="..\..\src\StringUtils.cpp" > </File> <File - RelativePath="..\..\source\StringUtils.h" + RelativePath="..\..\src\StringUtils.h" > </File> </Filter> diff --git a/Tools/AnvilStats/ChunkExtract.cpp b/Tools/AnvilStats/ChunkExtract.cpp index 71e804e73..96287ebef 100644 --- a/Tools/AnvilStats/ChunkExtract.cpp +++ b/Tools/AnvilStats/ChunkExtract.cpp @@ -5,7 +5,7 @@ #include "Globals.h" #include "ChunkExtract.h" -#include "../../source/OSSupport/GZipFile.h" +#include "../../src/OSSupport/GZipFile.h" diff --git a/Tools/AnvilStats/Globals.h b/Tools/AnvilStats/Globals.h index db5d3c635..c673ecb01 100644 --- a/Tools/AnvilStats/Globals.h +++ b/Tools/AnvilStats/Globals.h @@ -138,6 +138,7 @@ typedef unsigned short UInt16; // CRT stuff: +#include <sys/stat.h> #include <assert.h> #include <stdio.h> #include <math.h> @@ -162,12 +163,12 @@ typedef unsigned short UInt16; // Common headers (part 1, without macros): -#include "../../source/StringUtils.h" -#include "../../source/OSSupport/CriticalSection.h" -#include "../../source/OSSupport/Semaphore.h" -#include "../../source/OSSupport/Event.h" -#include "../../source/OSSupport/IsThread.h" -#include "../../source/OSSupport/File.h" +#include "../../src/StringUtils.h" +#include "../../src/OSSupport/CriticalSection.h" +#include "../../src/OSSupport/Semaphore.h" +#include "../../src/OSSupport/Event.h" +#include "../../src/OSSupport/IsThread.h" +#include "../../src/OSSupport/File.h" @@ -220,8 +221,8 @@ public: // Common headers (part 2, with macros): -#include "../../source/ChunkDef.h" -#include "../../source/BlockID.h" +#include "../../src/ChunkDef.h" +#include "../../src/BlockID.h" diff --git a/Tools/AnvilStats/Processor.cpp b/Tools/AnvilStats/Processor.cpp index 8e1cc4c4b..a16f78c18 100644 --- a/Tools/AnvilStats/Processor.cpp +++ b/Tools/AnvilStats/Processor.cpp @@ -6,8 +6,8 @@ #include "Globals.h" #include "Processor.h" #include "Callback.h" -#include "../../source/WorldStorage/FastNBT.h" -#include "zlib.h" +#include "../../src/WorldStorage/FastNBT.h" +#include "zlib/zlib.h" #include "Utils.h" @@ -554,8 +554,8 @@ void cProcessor::PopulateFileQueue(const AString & a_WorldFolder) { Path.push_back(cFile::PathSeparator); } - AStringList AllFiles = GetDirectoryContents(Path.c_str()); - for (AStringList::iterator itr = AllFiles.begin(), end = AllFiles.end(); itr != end; ++itr) + AStringVector AllFiles = cFile::GetFolderContents(Path.c_str()); + for (AStringVector::iterator itr = AllFiles.begin(), end = AllFiles.end(); itr != end; ++itr) { if (itr->rfind(".mca") != itr->length() - 4) { diff --git a/Tools/AnvilStats/Statistics.cpp b/Tools/AnvilStats/Statistics.cpp index b5b3cb176..f7519fd37 100644 --- a/Tools/AnvilStats/Statistics.cpp +++ b/Tools/AnvilStats/Statistics.cpp @@ -5,7 +5,7 @@ #include "Globals.h" #include "Statistics.h" -#include "../../source/WorldStorage/FastNBT.h" +#include "../../src/WorldStorage/FastNBT.h" diff --git a/Tools/BiomeVisualiser/.gitignore b/Tools/BiomeVisualiser/.gitignore new file mode 100644 index 000000000..b4e15dc3c --- /dev/null +++ b/Tools/BiomeVisualiser/.gitignore @@ -0,0 +1,3 @@ +Debug/ +logs/ +Release/ diff --git a/Tools/BiomeVisualiser/BiomeCache.cpp b/Tools/BiomeVisualiser/BiomeCache.cpp index b3c308422..7d9301d8f 100644 --- a/Tools/BiomeVisualiser/BiomeCache.cpp +++ b/Tools/BiomeVisualiser/BiomeCache.cpp @@ -258,6 +258,11 @@ void cBiomeCache::FilterOutItems(cItems & a_Items, int a_MinChunkX, int a_MaxChu void cBiomeCache::thrProcessQueueItem(void) { + if (m_Source == NULL) + { + return; + } + cItem * Item = NULL; { cCSLock Lock(m_CS); diff --git a/Tools/BiomeVisualiser/BiomeCache.h b/Tools/BiomeVisualiser/BiomeCache.h index bf1503d4c..da4d6c761 100644 --- a/Tools/BiomeVisualiser/BiomeCache.h +++ b/Tools/BiomeVisualiser/BiomeCache.h @@ -17,7 +17,7 @@ While the area is being filled, requests for biomes may already come, such reque #include "BiomeSource.h" -#include "../source/OSSupport/IsThread.h" +#include "../src/OSSupport/IsThread.h" diff --git a/Tools/BiomeVisualiser/BiomeColors.cpp b/Tools/BiomeVisualiser/BiomeColors.cpp new file mode 100644 index 000000000..1fd0cb7a0 --- /dev/null +++ b/Tools/BiomeVisualiser/BiomeColors.cpp @@ -0,0 +1,114 @@ + +// BiomeColors.cpp + +// Implements the g_BiomeColors[] array preparation based on a stored biome-to-color map + +#include "Globals.h" +#include "BiomeColors.h" + + + + + +int g_BiomeColors[256]; + + + + + +static struct +{ + EMCSBiome Biome; + int Color; +} g_BiomeColorMap[] = +{ + { biOcean, 0x000070 }, + { biPlains, 0x8db360 }, + { biDesert, 0xfa9418 }, + { biExtremeHills, 0x606060 }, + { biForest, 0x056621 }, + { biTaiga, 0x0b6659 }, + { biSwampland, 0x2fffda }, + { biRiver, 0x3030af }, + { biHell, 0x7f0000 }, + { biSky, 0x007fff }, + { biFrozenOcean, 0xa0a0df }, + { biFrozenRiver, 0xa0a0ff }, + { biIcePlains, 0xffffff }, + { biIceMountains, 0xa0a0a0 }, + { biMushroomIsland, 0xff00ff }, + { biMushroomShore, 0xa000ff }, + { biBeach, 0xfade55 }, + { biDesertHills, 0xd25f12 }, + { biForestHills, 0x22551c }, + { biTaigaHills, 0x163933 }, + { biExtremeHillsEdge, 0x7f8f7f }, + { biJungle, 0x537b09 }, + { biJungleHills, 0x2c4205 }, + + { biJungleEdge, 0x628b17 }, + { biDeepOcean, 0x000030 }, + { biStoneBeach, 0xa2a284 }, + { biColdBeach, 0xfaf0c0 }, + { biBirchForest, 0x307444 }, + { biBirchForestHills, 0x1f5f32 }, + { biRoofedForest, 0x40511a }, + { biColdTaiga, 0x31554a }, + { biColdTaigaHills, 0x597d72 }, + { biMegaTaiga, 0x596651 }, + { biMegaTaigaHills, 0x596659 }, + { biExtremeHillsPlus, 0x507050 }, + { biSavanna, 0xbdb25f }, + { biSavannaPlateau, 0xa79d64 }, + { biMesa, 0xd94515 }, + { biMesaPlateauF, 0xb09765 }, + { biMesaPlateau, 0xca8c65 }, + + // M variants: + { biSunflowerPlains, 0xb5db88 }, + { biDesertM, 0xffbc40 }, + { biExtremeHillsM, 0x888888 }, + { biFlowerForest, 0x2d8e49 }, + { biTaigaM, 0x338e81 }, + { biSwamplandM, 0x07f9b2 }, + { biIcePlainsSpikes, 0xb4dcdc }, + { biJungleM, 0x7ba331 }, + { biJungleEdgeM, 0x628b17 }, + { biBirchForestM, 0x589c6c }, + { biBirchForestHillsM, 0x47875a }, + { biRoofedForestM, 0x687942 }, + { biColdTaigaM, 0x243f36 }, + { biMegaSpruceTaiga, 0x454f3e }, + { biMegaSpruceTaigaHills, 0x454f4e }, + { biExtremeHillsPlusM, 0x789878 }, + { biSavannaM, 0xe5da87 }, + { biSavannaPlateauM, 0xa79d74 }, + { biMesaBryce, 0xff6d3d }, + { biMesaPlateauFM, 0xd8bf8d }, + { biMesaPlateauM, 0xf2b48d }, +} ; + + + + + +static class cBiomeColorsInitializer +{ +public: + cBiomeColorsInitializer(void) + { + // Reset all colors to gray: + for (size_t i = 0; i < ARRAYCOUNT(g_BiomeColors); i++) + { + g_BiomeColors[i] = 0x7f7f7f; + } + for (size_t i = 0; i < ARRAYCOUNT(g_BiomeColorMap); i++) + { + g_BiomeColors[g_BiomeColorMap[i].Biome] = g_BiomeColorMap[i].Color; + } + } +} g_Initializer; + + + + diff --git a/Tools/BiomeVisualiser/BiomeColors.h b/Tools/BiomeVisualiser/BiomeColors.h new file mode 100644 index 000000000..0cb0f578c --- /dev/null +++ b/Tools/BiomeVisualiser/BiomeColors.h @@ -0,0 +1,15 @@ + +// BiomeColors.h + +// Declares the g_BiomeColors[] array used for biome color lookup + + + + + +extern int g_BiomeColors[256]; + + + + + diff --git a/Tools/BiomeVisualiser/BiomeRenderer.cpp b/Tools/BiomeVisualiser/BiomeRenderer.cpp index 98548179c..758eb4b48 100644 --- a/Tools/BiomeVisualiser/BiomeRenderer.cpp +++ b/Tools/BiomeVisualiser/BiomeRenderer.cpp @@ -7,6 +7,7 @@ #include "BiomeRenderer.h" #include "Pixmap.h" #include "Timer.h" +#include "BiomeColors.h" @@ -96,40 +97,11 @@ bool cBiomeRenderer::Render(cPixmap & a_Pixmap) int cBiomeRenderer::GetBiomeColor(EMCSBiome a_Biome) { - if ((a_Biome < 0) || (a_Biome > biMaxBiome)) + if ((a_Biome < 0) || (a_Biome >= ARRAYCOUNT(g_BiomeColors))) { - return 0xcfcfcf; // LtGray for unknown biomes + return 0xff0000; } - - static int BiomeColor[] = - { - // RGB: - 0x0000ff, /* Ocean */ - 0x00cf3f, /* Plains */ - 0xffff00, /* Desert */ - 0x7f7f7f, /* Extreme Hills */ - 0x00cf00, /* Forest */ - 0x007f3f, /* Taiga */ - 0x3f7f00, /* Swampland */ - 0x003fff, /* River */ - 0x7f0000, /* Hell */ - 0x007fff, /* Sky */ - 0x3f3fff, /* Frozen Ocean */ - 0x3f3fff, /* Frozen River */ - 0x7fffcf, /* Ice Plains */ - 0x3fcf7f, /* Ice Mountains */ - 0xcf00cf, /* Mushroom Island */ - 0x7f00ff, /* Mushroom Island Shore */ - 0xffff3f, /* Beach */ - 0xcfcf00, /* Desert Hills */ - 0x00cf3f, /* Forest Hills */ - 0x006f1f, /* Taiga Hills */ - 0x7f8f7f, /* Extreme Hills Edge */ - 0x004f00, /* Jungle */ - 0x003f00, /* Jungle Hills */ - } ; - - return BiomeColor[a_Biome]; + return g_BiomeColors[a_Biome]; } diff --git a/Tools/BiomeVisualiser/BiomeViewWnd.cpp b/Tools/BiomeVisualiser/BiomeViewWnd.cpp index 3dd1bb4e0..5c1240bc7 100644 --- a/Tools/BiomeVisualiser/BiomeViewWnd.cpp +++ b/Tools/BiomeVisualiser/BiomeViewWnd.cpp @@ -7,7 +7,7 @@ #include "BiomeViewWnd.h" #include "BiomeCache.h" #include "GeneratorBiomeSource.h" -#include "../iniFile/iniFile.h" +#include "iniFile/iniFile.h" @@ -34,6 +34,8 @@ bool cBiomeViewWnd::Create(HWND a_ParentWnd, LPCTSTR a_Title) { ASSERT(m_Wnd == NULL); + InitBiomeView(); + // Create a regular STATIC window, then override its window procedure with our own. No need for obnoxious RegisterWindowClass() stuff. m_Wnd = CreateWindow("STATIC", a_Title, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 400, 300, a_ParentWnd, NULL, GetModuleHandle(NULL), NULL); if (m_Wnd == NULL) @@ -43,11 +45,6 @@ bool cBiomeViewWnd::Create(HWND a_ParentWnd, LPCTSTR a_Title) } SetWindowLongPtr(m_Wnd, GWLP_WNDPROC, m_Thunk); - cIniFile IniFile; - cBiomeGen * BioGen = new cBioGenMultiStepMap(2); - BioGen->Initialize(IniFile); - m_Renderer.SetSource(new cGeneratorBiomeSource(BioGen)); - return true; } @@ -55,6 +52,20 @@ bool cBiomeViewWnd::Create(HWND a_ParentWnd, LPCTSTR a_Title) +void cBiomeViewWnd::InitBiomeView(void) +{ + cIniFile IniFile; + IniFile.ReadFile("world.ini"); + int Seed = IniFile.GetValueSetI("Generator", "Seed", 0); + bool CacheOffByDefault = false; + m_BiomeGen = cBiomeGen::CreateBiomeGen(IniFile, Seed, CacheOffByDefault); + m_Renderer.SetSource(new cGeneratorBiomeSource(m_BiomeGen)); + IniFile.WriteFile("world.ini"); +} + + + + LRESULT cBiomeViewWnd::WndProc(HWND a_Wnd, UINT a_Msg, WPARAM wParam, LPARAM lParam) { diff --git a/Tools/BiomeVisualiser/BiomeViewWnd.h b/Tools/BiomeVisualiser/BiomeViewWnd.h index 88e808ab3..e3f70c7e6 100644 --- a/Tools/BiomeVisualiser/BiomeViewWnd.h +++ b/Tools/BiomeVisualiser/BiomeViewWnd.h @@ -3,6 +3,12 @@ // Declares the cBiomeViewWnd class representing the window that displays biomes + + + + +#pragma once + #include "WndProcThunk.h" #include "BiomeRenderer.h" #include "BiomeCache.h" @@ -12,6 +18,13 @@ +// fwd: +class cBiomeGen; + + + + + class cBiomeViewWnd { public: @@ -26,9 +39,15 @@ protected: cBiomeRenderer m_Renderer; cPixmap m_Pixmap; + /// The generator that is to be visualised + cBiomeGen * m_BiomeGen; + bool m_IsLButtonDown; POINT m_MouseDown; + + void InitBiomeView(void); + LRESULT WndProc(HWND a_Wnd, UINT a_Msg, WPARAM wParam, LPARAM lParam); // Message handlers: diff --git a/Tools/BiomeVisualiser/BiomeVisualiser.cpp b/Tools/BiomeVisualiser/BiomeVisualiser.cpp index e1d379f83..a36111d77 100644 --- a/Tools/BiomeVisualiser/BiomeVisualiser.cpp +++ b/Tools/BiomeVisualiser/BiomeVisualiser.cpp @@ -21,8 +21,8 @@ int WINAPI WinMain(HINSTANCE a_Instance, HINSTANCE a_PrevInstance, LPSTR a_CmdLi -cBiomeVisualiser::cBiomeVisualiser(void) - // : m_Logger(Printf("BiomeVisualiser_%08x", time(NULL))) +cBiomeVisualiser::cBiomeVisualiser(void) : + m_Logger(new cMCLogger(Printf("BiomeVisualiser_%08x.log", time(NULL)))) { } diff --git a/Tools/BiomeVisualiser/BiomeVisualiser.h b/Tools/BiomeVisualiser/BiomeVisualiser.h index 3fa90646b..4f8ce7513 100644 --- a/Tools/BiomeVisualiser/BiomeVisualiser.h +++ b/Tools/BiomeVisualiser/BiomeVisualiser.h @@ -23,7 +23,7 @@ public: protected: cBiomeViewWnd m_MainWnd; - cMCLogger m_Logger; + cMCLogger * m_Logger; } ; diff --git a/Tools/BiomeVisualiser/BiomeVisualiser.vcproj b/Tools/BiomeVisualiser/BiomeVisualiser.vcproj index 522606d60..e42870b13 100644 --- a/Tools/BiomeVisualiser/BiomeVisualiser.vcproj +++ b/Tools/BiomeVisualiser/BiomeVisualiser.vcproj @@ -41,7 +41,7 @@ <Tool Name="VCCLCompilerTool" Optimization="0" - AdditionalIncludeDirectories="../../source" + AdditionalIncludeDirectories="../../src;../../lib" PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS" MinimalRebuild="true" BasicRuntimeChecks="3" @@ -119,7 +119,7 @@ InlineFunctionExpansion="2" EnableIntrinsicFunctions="true" FavorSizeOrSpeed="1" - AdditionalIncludeDirectories="../../source" + AdditionalIncludeDirectories="../../src;../../lib" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS" RuntimeLibrary="0" EnableFunctionLevelLinking="true" @@ -199,7 +199,7 @@ InlineFunctionExpansion="2" EnableIntrinsicFunctions="true" FavorSizeOrSpeed="1" - AdditionalIncludeDirectories="../../source" + AdditionalIncludeDirectories="../../src;../../lib" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS" RuntimeLibrary="0" EnableFunctionLevelLinking="true" @@ -269,6 +269,10 @@ > </File> <File + RelativePath=".\BiomeColors.cpp" + > + </File> + <File RelativePath=".\BiomeRenderer.cpp" > </File> @@ -320,19 +324,35 @@ Name="Shared" > <File - RelativePath="..\..\source\BlockID.cpp" + RelativePath="..\..\src\BlockID.cpp" + > + </File> + <File + RelativePath="..\..\src\BlockID.h" + > + </File> + <File + RelativePath="..\..\src\ChunkDef.h" + > + </File> + <File + RelativePath="..\..\src\Enchantments.cpp" > </File> <File - RelativePath="..\..\source\BlockID.h" + RelativePath="..\..\src\Enchantments.h" > </File> <File - RelativePath="..\..\source\ChunkDef.h" + RelativePath="..\..\src\WorldStorage\FastNBT.cpp" > </File> <File - RelativePath="..\..\source\Globals.cpp" + RelativePath="..\..\src\WorldStorage\FastNBT.h" + > + </File> + <File + RelativePath="..\..\src\Globals.cpp" > <FileConfiguration Name="Debug|Win32" @@ -360,90 +380,94 @@ </FileConfiguration> </File> <File - RelativePath="..\..\source\Globals.h" + RelativePath="..\..\src\Globals.h" > </File> <File - RelativePath="..\..\source\Log.cpp" + RelativePath="..\..\src\Item.h" > </File> <File - RelativePath="..\..\source\Log.h" + RelativePath="..\..\src\Log.cpp" > </File> <File - RelativePath="..\..\source\MCLogger.cpp" + RelativePath="..\..\src\Log.h" > </File> <File - RelativePath="..\..\source\MCLogger.h" + RelativePath="..\..\src\MCLogger.cpp" > </File> <File - RelativePath="..\..\source\Noise.cpp" + RelativePath="..\..\src\MCLogger.h" > </File> <File - RelativePath="..\..\source\Noise.h" + RelativePath="..\..\src\Noise.cpp" > </File> <File - RelativePath="..\..\source\Noise.inc" + RelativePath="..\..\src\Noise.h" > </File> <File - RelativePath="..\..\source\StringUtils.cpp" + RelativePath="..\..\src\Noise.inc" > </File> <File - RelativePath="..\..\source\StringUtils.h" + RelativePath="..\..\src\StringUtils.cpp" + > + </File> + <File + RelativePath="..\..\src\StringUtils.h" + > + </File> + <File + RelativePath="..\..\src\VoronoiMap.cpp" + > + </File> + <File + RelativePath="..\..\src\VoronoiMap.h" > </File> <Filter Name="OSSupport" > <File - RelativePath="..\..\source\OSSupport\CriticalSection.cpp" + RelativePath="..\..\src\OSSupport\CriticalSection.cpp" > </File> <File - RelativePath="..\..\source\OSSupport\CriticalSection.h" + RelativePath="..\..\src\OSSupport\CriticalSection.h" > </File> <File - RelativePath="..\..\source\OSSupport\Event.cpp" + RelativePath="..\..\src\OSSupport\Event.cpp" > </File> <File - RelativePath="..\..\source\OSSupport\Event.h" + RelativePath="..\..\src\OSSupport\Event.h" > </File> <File - RelativePath="..\..\source\OSSupport\File.cpp" + RelativePath="..\..\src\OSSupport\File.cpp" > </File> <File - RelativePath="..\..\source\OSSupport\File.h" + RelativePath="..\..\src\OSSupport\File.h" > </File> <File - RelativePath="..\..\source\OSSupport\IsThread.cpp" + RelativePath="..\..\src\OSSupport\IsThread.cpp" > </File> <File - RelativePath="..\..\source\OSSupport\IsThread.h" + RelativePath="..\..\src\OSSupport\IsThread.h" > </File> <File - RelativePath="..\..\source\OSSupport\MakeDir.cpp" - > - </File> - <File - RelativePath="..\..\source\OSSupport\MakeDir.h" - > - </File> - <File - RelativePath="..\..\source\OSSupport\Sleep.h" + RelativePath="..\..\src\OSSupport\Sleep.h" > </File> </Filter> @@ -451,15 +475,15 @@ Name="Generating" > <File - RelativePath="..\..\source\Generating\BioGen.cpp" + RelativePath="..\..\src\Generating\BioGen.cpp" > </File> <File - RelativePath="..\..\source\Generating\BioGen.h" + RelativePath="..\..\src\Generating\BioGen.h" > </File> <File - RelativePath="..\..\source\Generating\ComposableGenerator.h" + RelativePath="..\..\src\Generating\ComposableGenerator.h" > </File> </Filter> @@ -467,16 +491,20 @@ Name="iniFile" > <File - RelativePath="..\..\iniFile\iniFile.cpp" + RelativePath="..\..\lib\iniFile\iniFile.cpp" > </File> <File - RelativePath="..\..\iniFile\iniFile.h" + RelativePath="..\..\lib\iniFile\iniFile.h" > </File> </Filter> </Filter> </Filter> + <File + RelativePath=".\BiomeColors.h" + > + </File> </Files> <Globals> </Globals> diff --git a/Tools/BiomeVisualiser/GeneratorBiomeSource.h b/Tools/BiomeVisualiser/GeneratorBiomeSource.h index 0b47e5f93..751aed245 100644 --- a/Tools/BiomeVisualiser/GeneratorBiomeSource.h +++ b/Tools/BiomeVisualiser/GeneratorBiomeSource.h @@ -3,7 +3,7 @@ // Declares the cGeneratorBiomeSource that adapts a cBiomeGen into a cBiomeSource -#include "../source/Generating/BioGen.h" +#include "../src/Generating/BioGen.h" #include "BiomeSource.h" diff --git a/Tools/BlockZapper/.gitignore b/Tools/BlockZapper/.gitignore new file mode 100644 index 000000000..b4e15dc3c --- /dev/null +++ b/Tools/BlockZapper/.gitignore @@ -0,0 +1,3 @@ +Debug/ +logs/ +Release/ diff --git a/Tools/BlockZapper/BlockZapper.sln b/Tools/BlockZapper/BlockZapper.sln index 9a71b9311..f65451d1b 100644 --- a/Tools/BlockZapper/BlockZapper.sln +++ b/Tools/BlockZapper/BlockZapper.sln @@ -6,7 +6,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BlockZapper", "BlockZapper. {EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA} = {EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\..\mc-server.clean\VC2008\zlib.vcproj", "{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\VC2008\zlib.vcproj", "{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/Tools/BlockZapper/BlockZapper.vcproj b/Tools/BlockZapper/BlockZapper.vcproj index 2a98197eb..4fa27dd31 100644 --- a/Tools/BlockZapper/BlockZapper.vcproj +++ b/Tools/BlockZapper/BlockZapper.vcproj @@ -41,7 +41,7 @@ <Tool Name="VCCLCompilerTool" Optimization="0" - AdditionalIncludeDirectories="../../source;../../zlib-1.2.7" + AdditionalIncludeDirectories="../../src;../../lib" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" MinimalRebuild="true" BasicRuntimeChecks="3" @@ -116,7 +116,7 @@ Name="VCCLCompilerTool" Optimization="2" EnableIntrinsicFunctions="true" - AdditionalIncludeDirectories="../../source;../../zlib-1.2.7" + AdditionalIncludeDirectories="../../src;../../lib" PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" RuntimeLibrary="0" EnableFunctionLevelLinking="true" @@ -222,70 +222,62 @@ Name="shared" > <File - RelativePath="..\..\source\Log.cpp" + RelativePath="..\..\src\Log.cpp" > </File> <File - RelativePath="..\..\source\Log.h" + RelativePath="..\..\src\Log.h" > </File> <File - RelativePath="..\..\source\MCLogger.cpp" + RelativePath="..\..\src\MCLogger.cpp" > </File> <File - RelativePath="..\..\source\MCLogger.h" + RelativePath="..\..\src\MCLogger.h" > </File> <File - RelativePath="..\..\source\StringCompression.cpp" + RelativePath="..\..\src\StringCompression.cpp" > </File> <File - RelativePath="..\..\source\StringCompression.h" + RelativePath="..\..\src\StringCompression.h" > </File> <File - RelativePath="..\..\source\StringUtils.cpp" + RelativePath="..\..\src\StringUtils.cpp" > </File> <File - RelativePath="..\..\source\StringUtils.h" + RelativePath="..\..\src\StringUtils.h" > </File> <Filter Name="OSSupport" > <File - RelativePath="..\..\source\OSSupport\CriticalSection.cpp" + RelativePath="..\..\src\OSSupport\CriticalSection.cpp" > </File> <File - RelativePath="..\..\source\OSSupport\CriticalSection.h" + RelativePath="..\..\src\OSSupport\CriticalSection.h" > </File> <File - RelativePath="..\..\source\OSSupport\File.cpp" + RelativePath="..\..\src\OSSupport\File.cpp" > </File> <File - RelativePath="..\..\source\OSSupport\File.h" + RelativePath="..\..\src\OSSupport\File.h" > </File> <File - RelativePath="..\..\source\OSSupport\IsThread.cpp" + RelativePath="..\..\src\OSSupport\IsThread.cpp" > </File> <File - RelativePath="..\..\source\OSSupport\IsThread.h" - > - </File> - <File - RelativePath="..\..\source\OSSupport\MakeDir.cpp" - > - </File> - <File - RelativePath="..\..\source\OSSupport\MakeDir.h" + RelativePath="..\..\src\OSSupport\IsThread.h" > </File> </Filter> @@ -293,11 +285,11 @@ Name="WorldStorage" > <File - RelativePath="..\..\source\WorldStorage\FastNBT.cpp" + RelativePath="..\..\src\WorldStorage\FastNBT.cpp" > </File> <File - RelativePath="..\..\source\WorldStorage\FastNBT.h" + RelativePath="..\..\src\WorldStorage\FastNBT.h" > </File> </Filter> diff --git a/Tools/BlockZapper/GNUmakefile b/Tools/BlockZapper/GNUmakefile index edd5f9009..0ef5eb3cc 100644 --- a/Tools/BlockZapper/GNUmakefile +++ b/Tools/BlockZapper/GNUmakefile @@ -100,8 +100,8 @@ endif # INCLUDE = -I.\ - -I../../source\ - -I../../zlib-1.2.7\ + -I../../src\ + -I../../lib\ @@ -114,16 +114,16 @@ INCLUDE = -I.\ SOURCES := $(shell find . '(' -name '*.cpp' -o -name '*.c' ')') SHAREDSOURCES := \ - source/Log.cpp \ - source/MCLogger.cpp \ - source/Noise.cpp \ - source/StringCompression.cpp \ - source/StringUtils.cpp \ - source/OSSupport/CriticalSection.cpp \ - source/OSSupport/File.cpp \ - source/OSSupport/IsThread.cpp \ - source/OSSupport/MakeDir.cpp \ - source/WorldStorage/FastNBT.cpp + src/Log.cpp \ + src/MCLogger.cpp \ + src/Noise.cpp \ + src/StringCompression.cpp \ + src/StringUtils.cpp \ + src/OSSupport/CriticalSection.cpp \ + src/OSSupport/File.cpp \ + src/OSSupport/IsThread.cpp \ + src/OSSupport/MakeDir.cpp \ + src/WorldStorage/FastNBT.cpp SHAREDSOURCES := $(filter-out %minigzip.c,$(SHAREDSOURCES)) @@ -142,8 +142,6 @@ BlockZapper : $(OBJECTS) $(SHAREDOBJECTS) clean : rm -rf $(BUILDDIR) BlockZapper -install : MCServer - cp MCServer MCServer @@ -175,7 +173,7 @@ $(BUILDDIR)%.o: %.cpp @sed -e 's/.*://' -e 's/\\$$//' < $(patsubst %.o,%.d,$@).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(patsubst %.o,%.d,$@) @rm -f $(patsubst %.o,%.d,$@).tmp -$(BUILDDIR)source/%.o: ../../source/%.cpp +$(BUILDDIR)src/%.o: ../../src/%.cpp @mkdir -p $(dir $@) $(CC) $(CXX_OPTIONS) -c $(INCLUDE) $< -o $@ @$(CC) $(CXX_OPTIONS) -MM $(INCLUDE) $< > $(patsubst %.o,%.d,$@) diff --git a/Tools/BlockZapper/Globals.h b/Tools/BlockZapper/Globals.h index e27315ec5..3826c72fa 100644 --- a/Tools/BlockZapper/Globals.h +++ b/Tools/BlockZapper/Globals.h @@ -7,7 +7,7 @@ -#include "../../source/Globals.h" +#include "../../src/Globals.h" diff --git a/Tools/BlockZapper/Zapper.cpp b/Tools/BlockZapper/Zapper.cpp index 702f968ab..304d49770 100644 --- a/Tools/BlockZapper/Zapper.cpp +++ b/Tools/BlockZapper/Zapper.cpp @@ -7,7 +7,7 @@ #include "WorldStorage/FastNBT.h" #include "StringCompression.h" -#include "zlib.h" +#include "zlib/zlib.h" #include "Zapper.h" diff --git a/Tools/MemDumpAnalysis/.gitignore b/Tools/MemDumpAnalysis/.gitignore new file mode 100644 index 000000000..b4e15dc3c --- /dev/null +++ b/Tools/MemDumpAnalysis/.gitignore @@ -0,0 +1,3 @@ +Debug/ +logs/ +Release/ diff --git a/Tools/MemDumpAnalysis/Globals.h b/Tools/MemDumpAnalysis/Globals.h index 92d27da2c..d5fc2abfa 100644 --- a/Tools/MemDumpAnalysis/Globals.h +++ b/Tools/MemDumpAnalysis/Globals.h @@ -9,7 +9,7 @@ #pragma once -#include "../../source/Globals.h" +#include "../../src/Globals.h" /* // System headers: @@ -23,12 +23,12 @@ #include <string> // Common: -#include "../source/StringUtils.h" -#include "../source/OSSupport/File.h" +#include "../src/StringUtils.h" +#include "../src/OSSupport/File.h" */ // Libraries: -#include "../../expat/expat.h" +#include "expat/expat.h" diff --git a/Tools/MemDumpAnalysis/MemDumpAnalysis.vcproj b/Tools/MemDumpAnalysis/MemDumpAnalysis.vcproj index 345dfa962..8283fd531 100644 --- a/Tools/MemDumpAnalysis/MemDumpAnalysis.vcproj +++ b/Tools/MemDumpAnalysis/MemDumpAnalysis.vcproj @@ -41,6 +41,7 @@ <Tool Name="VCCLCompilerTool" Optimization="0" + AdditionalIncludeDirectories="../../lib" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;COMPILED_FROM_DSP;XML_STATIC" MinimalRebuild="true" BasicRuntimeChecks="3" @@ -61,7 +62,7 @@ /> <Tool Name="VCLinkerTool" - OutputFile="$(ProjectDir)\..\MCServer\$(ProjectName)_debug.exe" + OutputFile="$(ProjectDir)\..\..\MCServer\$(ProjectName)_debug.exe" LinkIncremental="2" GenerateDebugInformation="true" SubSystem="1" @@ -116,6 +117,7 @@ Name="VCCLCompilerTool" Optimization="2" EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../lib" PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;COMPILED_FROM_DSP;XML_STATIC" RuntimeLibrary="2" EnableFunctionLevelLinking="true" @@ -135,7 +137,7 @@ /> <Tool Name="VCLinkerTool" - OutputFile="$(ProjectDir)\..\MCServer\$(ProjectName).exe" + OutputFile="$(ProjectDir)\..\..\MCServer\$(ProjectName).exe" LinkIncremental="1" GenerateDebugInformation="true" SubSystem="1" @@ -211,47 +213,47 @@ Name="expat" > <File - RelativePath="..\..\expat\ascii.h" + RelativePath="..\..\lib\expat\ascii.h" > </File> <File - RelativePath="..\..\expat\asciitab.h" + RelativePath="..\..\lib\expat\asciitab.h" > </File> <File - RelativePath="..\..\expat\expat.h" + RelativePath="..\..\lib\expat\expat.h" > </File> <File - RelativePath="..\..\expat\expat_external.h" + RelativePath="..\..\lib\expat\expat_external.h" > </File> <File - RelativePath="..\..\expat\iasciitab.h" + RelativePath="..\..\lib\expat\iasciitab.h" > </File> <File - RelativePath="..\..\expat\internal.h" + RelativePath="..\..\lib\expat\internal.h" > </File> <File - RelativePath="..\..\expat\latin1tab.h" + RelativePath="..\..\lib\expat\latin1tab.h" > </File> <File - RelativePath="..\..\expat\nametab.h" + RelativePath="..\..\lib\expat\nametab.h" > </File> <File - RelativePath="..\..\expat\utf8tab.h" + RelativePath="..\..\lib\expat\utf8tab.h" > </File> <File - RelativePath="..\..\expat\winconfig.h" + RelativePath="..\..\lib\expat\winconfig.h" > </File> <File - RelativePath="..\..\expat\xmlparse.c" + RelativePath="..\..\lib\expat\xmlparse.c" > <FileConfiguration Name="Debug|Win32" @@ -271,7 +273,7 @@ </FileConfiguration> </File> <File - RelativePath="..\..\expat\xmlrole.c" + RelativePath="..\..\lib\expat\xmlrole.c" > <FileConfiguration Name="Debug|Win32" @@ -291,11 +293,11 @@ </FileConfiguration> </File> <File - RelativePath="..\..\expat\xmlrole.h" + RelativePath="..\..\lib\expat\xmlrole.h" > </File> <File - RelativePath="..\..\expat\xmltok.c" + RelativePath="..\..\lib\expat\xmltok.c" > <FileConfiguration Name="Debug|Win32" @@ -315,11 +317,11 @@ </FileConfiguration> </File> <File - RelativePath="..\..\expat\xmltok.h" + RelativePath="..\..\lib\expat\xmltok.h" > </File> <File - RelativePath="..\..\expat\xmltok_impl.c" + RelativePath="..\..\lib\expat\xmltok_impl.c" > <FileConfiguration Name="Debug|Win32" @@ -339,11 +341,11 @@ </FileConfiguration> </File> <File - RelativePath="..\..\expat\xmltok_impl.h" + RelativePath="..\..\lib\expat\xmltok_impl.h" > </File> <File - RelativePath="..\..\expat\xmltok_ns.c" + RelativePath="..\..\lib\expat\xmltok_ns.c" > <FileConfiguration Name="Debug|Win32" @@ -373,62 +375,54 @@ Name="shared" > <File - RelativePath="..\..\source\Log.cpp" + RelativePath="..\..\src\Log.cpp" > </File> <File - RelativePath="..\..\source\Log.h" + RelativePath="..\..\src\Log.h" > </File> <File - RelativePath="..\..\source\MCLogger.cpp" + RelativePath="..\..\src\MCLogger.cpp" > </File> <File - RelativePath="..\..\source\MCLogger.h" + RelativePath="..\..\src\MCLogger.h" > </File> <File - RelativePath="..\..\source\StringUtils.cpp" + RelativePath="..\..\src\StringUtils.cpp" > </File> <File - RelativePath="..\..\source\StringUtils.h" + RelativePath="..\..\src\StringUtils.h" > </File> <Filter Name="OSSupport" > <File - RelativePath="..\..\source\OSSupport\CriticalSection.cpp" + RelativePath="..\..\src\OSSupport\CriticalSection.cpp" > </File> <File - RelativePath="..\..\source\OSSupport\CriticalSection.h" + RelativePath="..\..\src\OSSupport\CriticalSection.h" > </File> <File - RelativePath="..\..\source\OSSupport\File.cpp" + RelativePath="..\..\src\OSSupport\File.cpp" > </File> <File - RelativePath="..\..\source\OSSupport\File.h" + RelativePath="..\..\src\OSSupport\File.h" > </File> <File - RelativePath="..\..\source\OSSupport\IsThread.cpp" + RelativePath="..\..\src\OSSupport\IsThread.cpp" > </File> <File - RelativePath="..\..\source\OSSupport\IsThread.h" - > - </File> - <File - RelativePath="..\..\source\OSSupport\MakeDir.cpp" - > - </File> - <File - RelativePath="..\..\source\OSSupport\MakeDir.h" + RelativePath="..\..\src\OSSupport\IsThread.h" > </File> </Filter> diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp index e985c2ff6..0b49859cb 100644 --- a/Tools/ProtoProxy/Connection.cpp +++ b/Tools/ProtoProxy/Connection.cpp @@ -15,7 +15,14 @@ -#ifdef _DEBUG +/// When defined, the following macro causes a sleep after each parsed packet (DEBUG-mode only) +// #define SLEEP_AFTER_PACKET + + + + + +#if defined(_DEBUG) && defined(SLEEP_AFTER_PACKET) #define DebugSleep Sleep #else #define DebugSleep(X) @@ -45,7 +52,7 @@ #define CLIENTSEND(...) SendData(m_ClientSocket, __VA_ARGS__, "Client") #define SERVERSEND(...) SendData(m_ServerSocket, __VA_ARGS__, "Server") -#define CLIENTENCRYPTSEND(...) SendEncryptedData(m_ClientSocket, m_ClientEncryptor, __VA_ARGS__, "Client") +#define CLIENTENCRYPTSEND(...) SendData(m_ClientSocket, __VA_ARGS__, "Client") // The client conn is always unencrypted #define SERVERENCRYPTSEND(...) SendEncryptedData(m_ServerSocket, m_ServerEncryptor, __VA_ARGS__, "Server") #define COPY_TO_SERVER() \ @@ -92,19 +99,20 @@ CLIENTENCRYPTSEND(ToClient.data(), ToClient.size()); \ break; \ } \ - case csWaitingForEncryption: \ + /* case csWaitingForEncryption: \ { \ Log("Waiting for client encryption, queued %u bytes", ToClient.size()); \ m_ClientEncryptionBuffer.append(ToClient.data(), ToClient.size()); \ break; \ } \ + */ \ } \ DebugSleep(50); \ } #define HANDLE_CLIENT_READ(Proc) \ { \ - if (!Proc()) \ + if (!Proc) \ { \ AString Leftover; \ m_ClientBuffer.ReadAgain(Leftover); \ @@ -116,7 +124,7 @@ #define HANDLE_SERVER_READ(Proc) \ { \ - if (!Proc()) \ + if (!Proc) \ { \ m_ServerBuffer.ResetRead(); \ return true; \ @@ -135,106 +143,6 @@ typedef unsigned char Byte; -enum -{ - PACKET_KEEPALIVE = 0x00, - PACKET_LOGIN = 0x01, - PACKET_HANDSHAKE = 0x02, - PACKET_CHAT_MESSAGE = 0x03, - PACKET_TIME_UPDATE = 0x04, - PACKET_ENTITY_EQUIPMENT = 0x05, - PACKET_COMPASS = 0x06, - PACKET_USE_ENTITY = 0x07, - PACKET_UPDATE_HEALTH = 0x08, - PACKET_PLAYER_ON_GROUND = 0x0a, - PACKET_PLAYER_POSITION = 0x0b, - PACKET_PLAYER_LOOK = 0x0c, - PACKET_PLAYER_POSITION_LOOK = 0x0d, - PACKET_BLOCK_DIG = 0x0e, - PACKET_BLOCK_PLACE = 0x0f, - PACKET_SLOT_SELECT = 0x10, - PACKET_PLAYER_ANIMATION = 0x12, - PACKET_ENTITY_ACTION = 0x13, - PACKET_SPAWN_NAMED_ENTITY = 0x14, - PACKET_SPAWN_PICKUP = 0x15, - PACKET_COLLECT_PICKUP = 0x16, - PACKET_SPAWN_OBJECT_VEHICLE = 0x17, - PACKET_SPAWN_MOB = 0x18, - PACKET_SPAWN_PAINTING = 0x19, - PACKET_SPAWN_EXPERIENCE_ORB = 0x1a, - PACKET_ENTITY_VELOCITY = 0x1c, - PACKET_DESTROY_ENTITIES = 0x1d, - PACKET_ENTITY = 0x1e, - PACKET_ENTITY_RELATIVE_MOVE = 0x1f, - PACKET_ENTITY_LOOK = 0x20, - PACKET_ENTITY_RELATIVE_MOVE_LOOK = 0x21, - PACKET_ENTITY_TELEPORT = 0x22, - PACKET_ENTITY_HEAD_LOOK = 0x23, - PACKET_ENTITY_STATUS = 0x26, - PACKET_ATTACH_ENTITY = 0x27, - PACKET_ENTITY_METADATA = 0x28, - PACKET_ENTITY_EFFECT = 0x29, - PACKET_ENTITY_EFFECT_REMOVE = 0x2a, - PACKET_SET_EXPERIENCE = 0x2b, - PACKET_ENTITY_PROPERTIES = 0x2c, - PACKET_MAP_CHUNK = 0x33, - PACKET_MULTI_BLOCK_CHANGE = 0x34, - PACKET_BLOCK_CHANGE = 0x35, - PACKET_BLOCK_ACTION = 0x36, - PACKET_MAP_CHUNK_BULK = 0x38, - PACKET_SOUND_EFFECT = 0x3d, - PACKET_NAMED_SOUND_EFFECT = 0x3e, - PACKET_CHANGE_GAME_STATE = 0x46, - PACKET_WINDOW_OPEN = 0x64, - PACKET_WINDOW_CLOSE = 0x65, - PACKET_WINDOW_CLICK = 0x66, - PACKET_SET_SLOT = 0x67, - PACKET_WINDOW_CONTENTS = 0x68, - PACKET_CREATIVE_INVENTORY_ACTION = 0x6b, - PACKET_UPDATE_SIGN = 0x82, - PACKET_UPDATE_TILE_ENTITY = 0x84, - PACKET_PLAYER_LIST_ITEM = 0xc9, - PACKET_PLAYER_ABILITIES = 0xca, - PACKET_INCREMENT_STATISTIC = 0xc8, - PACKET_TAB_COMPLETION = 0xcb, - PACKET_LOCALE_AND_VIEW = 0xcc, - PACKET_CLIENT_STATUSES = 0xcd, - PACKET_PLUGIN_MESSAGE = 0xfa, - PACKET_ENCRYPTION_KEY_RESPONSE = 0xfc, - PACKET_ENCRYPTION_KEY_REQUEST = 0xfd, - PACKET_PING = 0xfe, - PACKET_KICK = 0xff, - - // Synonyms: - PACKET_DISCONNECT = PACKET_KICK, -} ; - - - - -enum -{ - OBJECT_BOAT = 1, - OBJECT_MINECART = 10, - OBJECT_MINECART_STORAGE = 11, - OBJECT_MINECART_POWERED = 12, - OBJECT_MINECART_TNT = 13, - OBJECT_MINECART_HOPPER = 14, - OBJECT_TNT = 50, - OBJECT_ENDERCRYSTAL = 51, - OBJECT_ARROW = 60, - OBJECT_SNOWBALL = 61, - OBJECT_EGG = 62, - OBJECT_FALLING_BLOCK = 70, - OBJECT_EYE_OF_ENDER = 72, - OBJECT_DRAGON_EGG = 74, - OBJECT_FISHING_FLOAT = 90, -} ; - - - - - AString PrintableAbsIntTriplet(int a_X, int a_Y, int a_Z, double a_Divisor = 32) { return Printf("<%d, %d, %d> ~ {%.02f, %.02f, %.02f}", @@ -262,7 +170,10 @@ cConnection::cConnection(SOCKET a_ClientSocket, cServer & a_Server) : m_Nonce(0), m_ClientBuffer(1024 KiB), m_ServerBuffer(1024 KiB), - m_HasClientPinged(false) + m_HasClientPinged(false), + m_ServerProtocolState(-1), + m_ClientProtocolState(-1), + m_IsServerEncrypted(false) { // Create the Logs subfolder, if not already created: #if defined(_WIN32) @@ -271,7 +182,7 @@ cConnection::cConnection(SOCKET a_ClientSocket, cServer & a_Server) : mkdir("Logs", 0777); #endif - Printf(m_LogNameBase, "Logs/Log_%d", (int)time(NULL)); + Printf(m_LogNameBase, "Logs/Log_%d_%d", (int)time(NULL), a_ClientSocket); AString fnam(m_LogNameBase); fnam.append(".log"); m_LogFile = fopen(fnam.c_str(), "w"); @@ -299,7 +210,7 @@ void cConnection::Run(void) Log("Cannot connect to server; aborting"); return; } - + while (true) { fd_set ReadFDs; @@ -349,6 +260,9 @@ void cConnection::Log(const char * a_Format, ...) // Log to file: cCSLock Lock(m_CSLog); fputs(FullMsg.c_str(), m_LogFile); + #ifdef _DEBUG + fflush(m_LogFile); + #endif // _DEBUG // Log to screen: // std::cout << FullMsg; @@ -445,7 +359,6 @@ bool cConnection::RelayFromServer(void) { m_ServerDecryptor.ProcessData((byte *)Buffer, (byte *)Buffer, res); DataLog(Buffer, res, "Decrypted %d bytes from the SERVER", res); - m_ClientEncryptor.ProcessData((byte *)Buffer, (byte *)Buffer, res); return CLIENTSEND(Buffer, res); } } @@ -478,13 +391,10 @@ bool cConnection::RelayFromClient(void) } case csEncryptedUnderstood: { - m_ClientDecryptor.ProcessData((byte *)Buffer, (byte *)Buffer, res); - DataLog(Buffer, res, "Decrypted %d bytes from the CLIENT", res); return DecodeClientsPackets(Buffer, res); } case csEncryptedUnknown: { - m_ClientDecryptor.ProcessData((byte *)Buffer, (byte *)Buffer, res); DataLog(Buffer, res, "Decrypted %d bytes from the CLIENT", res); m_ServerEncryptor.ProcessData((byte *)Buffer, (byte *)Buffer, res); return SERVERSEND(Buffer, res); @@ -509,7 +419,7 @@ double cConnection::GetRelativeTime(void) bool cConnection::SendData(SOCKET a_Socket, const char * a_Data, int a_Size, const char * a_Peer) { - DataLog(a_Data, a_Size, "Sending data to %s", a_Peer); + DataLog(a_Data, a_Size, "Sending data to %s, %d bytes", a_Peer, a_Size); int res = send(a_Socket, a_Data, a_Size, 0); if (res <= 0) @@ -582,66 +492,97 @@ bool cConnection::DecodeClientsPackets(const char * a_Data, int a_Size) while (m_ClientBuffer.CanReadBytes(1)) { - unsigned char PacketType; - m_ClientBuffer.ReadByte(PacketType); - Log("Decoding client's packets, there are now %d bytes in the queue; next packet is 0x%02x", m_ClientBuffer.GetReadableSpace(), PacketType); - switch (PacketType) + UInt32 PacketLen; + if ( + !m_ClientBuffer.ReadVarInt(PacketLen) || + !m_ClientBuffer.CanReadBytes(PacketLen) + ) { - case PACKET_BLOCK_DIG: HANDLE_CLIENT_READ(HandleClientBlockDig); break; - case PACKET_BLOCK_PLACE: HANDLE_CLIENT_READ(HandleClientBlockPlace); break; - case PACKET_CHAT_MESSAGE: HANDLE_CLIENT_READ(HandleClientChatMessage); break; - case PACKET_CLIENT_STATUSES: HANDLE_CLIENT_READ(HandleClientClientStatuses); break; - case PACKET_CREATIVE_INVENTORY_ACTION: HANDLE_CLIENT_READ(HandleClientCreativeInventoryAction); break; - case PACKET_DISCONNECT: HANDLE_CLIENT_READ(HandleClientDisconnect); break; - case PACKET_ENCRYPTION_KEY_RESPONSE: HANDLE_CLIENT_READ(HandleClientEncryptionKeyResponse); break; - case PACKET_ENTITY_ACTION: HANDLE_CLIENT_READ(HandleClientEntityAction); break; - case PACKET_HANDSHAKE: HANDLE_CLIENT_READ(HandleClientHandshake); break; - case PACKET_KEEPALIVE: HANDLE_CLIENT_READ(HandleClientKeepAlive); break; - case PACKET_LOCALE_AND_VIEW: HANDLE_CLIENT_READ(HandleClientLocaleAndView); break; - case PACKET_PING: HANDLE_CLIENT_READ(HandleClientPing); break; - case PACKET_PLAYER_ABILITIES: HANDLE_CLIENT_READ(HandleClientPlayerAbilities); break; - case PACKET_PLAYER_ANIMATION: HANDLE_CLIENT_READ(HandleClientAnimation); break; - case PACKET_PLAYER_LOOK: HANDLE_CLIENT_READ(HandleClientPlayerLook); break; - case PACKET_PLAYER_ON_GROUND: HANDLE_CLIENT_READ(HandleClientPlayerOnGround); break; - case PACKET_PLAYER_POSITION: HANDLE_CLIENT_READ(HandleClientPlayerPosition); break; - case PACKET_PLAYER_POSITION_LOOK: HANDLE_CLIENT_READ(HandleClientPlayerPositionLook); break; - case PACKET_PLUGIN_MESSAGE: HANDLE_CLIENT_READ(HandleClientPluginMessage); break; - case PACKET_SLOT_SELECT: HANDLE_CLIENT_READ(HandleClientSlotSelect); break; - case PACKET_TAB_COMPLETION: HANDLE_CLIENT_READ(HandleClientTabCompletion); break; - case PACKET_UPDATE_SIGN: HANDLE_CLIENT_READ(HandleClientUpdateSign); break; - case PACKET_USE_ENTITY: HANDLE_CLIENT_READ(HandleClientUseEntity); break; - case PACKET_WINDOW_CLICK: HANDLE_CLIENT_READ(HandleClientWindowClick); break; - case PACKET_WINDOW_CLOSE: HANDLE_CLIENT_READ(HandleClientWindowClose); break; - default: + // Not a complete packet yet + break; + } + UInt32 PacketType, PacketReadSoFar; + PacketReadSoFar = m_ClientBuffer.GetReadableSpace(); + VERIFY(m_ClientBuffer.ReadVarInt(PacketType)); + PacketReadSoFar -= m_ClientBuffer.GetReadableSpace(); + Log("Decoding client's packets, there are now %d bytes in the queue; next packet is 0x%0x, %u bytes long", m_ClientBuffer.GetReadableSpace(), PacketType, PacketLen); + switch (m_ClientProtocolState) + { + case -1: { - if (m_ClientState == csEncryptedUnderstood) + // No initial handshake received yet + switch (PacketType) { - Log("****************** Unknown packet 0x%02x from the client while encrypted; continuing to relay blind only", PacketType); - AString Data; - m_ClientBuffer.ResetRead(); - m_ClientBuffer.ReadAll(Data); - DataLog(Data.data(), Data.size(), "Current data in the client packet queue: %d bytes", Data.size()); - m_ClientState = csEncryptedUnknown; - m_ClientBuffer.ResetRead(); - if (m_ServerState == csUnencrypted) - { - SERVERSEND(m_ClientBuffer); - } - else - { - SERVERENCRYPTSEND(m_ClientBuffer); - } - return true; + case 0x00: HANDLE_CLIENT_READ(HandleClientHandshake()); break; + default: HANDLE_CLIENT_READ(HandleClientUnknownPacket(PacketType, PacketLen, PacketReadSoFar)); break; } - else + break; + } // case -1 + + case 1: + { + // Status query + switch (PacketType) { - Log("Unknown packet 0x%02x from the client while unencrypted; aborting connection", PacketType); - return false; + case 0x00: HANDLE_CLIENT_READ(HandleClientStatusRequest()); break; + case 0x01: HANDLE_CLIENT_READ(HandleClientStatusPing()); break; + default: HANDLE_CLIENT_READ(HandleClientUnknownPacket(PacketType, PacketLen, PacketReadSoFar)); break; } + break; } - } // switch (PacketType) + + case 2: + { + // Login + switch (PacketType) + { + case 0x00: HANDLE_CLIENT_READ(HandleClientLoginStart()); break; + case 0x01: HANDLE_CLIENT_READ(HandleClientLoginEncryptionKeyResponse()); break; + default: HANDLE_CLIENT_READ(HandleClientUnknownPacket(PacketType, PacketLen, PacketReadSoFar)); break; + } + break; + } + + case 3: + { + // Game: + switch (PacketType) + { + case 0x00: HANDLE_CLIENT_READ(HandleClientKeepAlive()); break; + case 0x01: HANDLE_CLIENT_READ(HandleClientChatMessage()); break; + case 0x02: HANDLE_CLIENT_READ(HandleClientUseEntity()); break; + case 0x03: HANDLE_CLIENT_READ(HandleClientPlayerOnGround()); break; + case 0x04: HANDLE_CLIENT_READ(HandleClientPlayerPosition()); break; + case 0x05: HANDLE_CLIENT_READ(HandleClientPlayerLook()); break; + case 0x06: HANDLE_CLIENT_READ(HandleClientPlayerPositionLook()); break; + case 0x07: HANDLE_CLIENT_READ(HandleClientBlockDig()); break; + case 0x08: HANDLE_CLIENT_READ(HandleClientBlockPlace()); break; + case 0x09: HANDLE_CLIENT_READ(HandleClientSlotSelect()); break; + case 0x0a: HANDLE_CLIENT_READ(HandleClientAnimation()); break; + case 0x0b: HANDLE_CLIENT_READ(HandleClientEntityAction()); break; + case 0x0d: HANDLE_CLIENT_READ(HandleClientWindowClose()); break; + case 0x0e: HANDLE_CLIENT_READ(HandleClientWindowClick()); break; + case 0x10: HANDLE_CLIENT_READ(HandleClientCreativeInventoryAction()); break; + case 0x12: HANDLE_CLIENT_READ(HandleClientUpdateSign()); break; + case 0x13: HANDLE_CLIENT_READ(HandleClientPlayerAbilities()); break; + case 0x14: HANDLE_CLIENT_READ(HandleClientTabCompletion()); break; + case 0x15: HANDLE_CLIENT_READ(HandleClientLocaleAndView()); break; + case 0x16: HANDLE_CLIENT_READ(HandleClientClientStatuses()); break; + case 0x17: HANDLE_CLIENT_READ(HandleClientPluginMessage()); break; + default: HANDLE_CLIENT_READ(HandleClientUnknownPacket(PacketType, PacketLen, PacketReadSoFar)); break; + } + break; + } // case 3 - Game + + default: + { + Log("Receiving server packets while in an unknown protocol state (%d)!", m_ClientProtocolState); + HANDLE_CLIENT_READ(HandleClientUnknownPacket(PacketType, PacketLen, PacketReadSoFar)); + break; + } + } // switch (m_ProtocolState) m_ClientBuffer.CommitRead(); - } // while (CanReadBytes(1)) + } // while (true) return true; } @@ -665,93 +606,138 @@ bool cConnection::DecodeServersPackets(const char * a_Data, int a_Size) // Client hasn't finished encryption handshake yet, don't send them any data yet } - while (m_ServerBuffer.CanReadBytes(1)) + while (true) { - unsigned char PacketType; - m_ServerBuffer.ReadByte(PacketType); - Log("Decoding server's packets, there are now %d bytes in the queue; next packet is 0x%02x", m_ServerBuffer.GetReadableSpace(), PacketType); + UInt32 PacketLen; + if ( + !m_ServerBuffer.ReadVarInt(PacketLen) || + !m_ServerBuffer.CanReadBytes(PacketLen) + ) + { + // Not a complete packet yet + m_ServerBuffer.ResetRead(); + break; + } + if (PacketLen == 0) + { + m_ServerBuffer.ResetRead(); + AString All; + m_ServerBuffer.ReadAll(All); + DataLog(All.data(), All.size(), "====== Received a bad packet length? Inspect the contents below ======"); + m_ServerBuffer.CommitRead(); // Try to recover by marking everything as read + break; + } + UInt32 PacketType, PacketReadSoFar; + PacketReadSoFar = m_ServerBuffer.GetReadableSpace(); + VERIFY(m_ServerBuffer.ReadVarInt(PacketType)); + PacketReadSoFar -= m_ServerBuffer.GetReadableSpace(); + Log("Decoding server's packets, there are now %d bytes in the queue; next packet is 0x%0x, %u bytes long", m_ServerBuffer.GetReadableSpace(), PacketType, PacketLen); LogFlush(); - switch (PacketType) + switch (m_ServerProtocolState) { - case PACKET_ATTACH_ENTITY: HANDLE_SERVER_READ(HandleServerAttachEntity); break; - case PACKET_BLOCK_ACTION: HANDLE_SERVER_READ(HandleServerBlockAction); break; - case PACKET_BLOCK_CHANGE: HANDLE_SERVER_READ(HandleServerBlockChange); break; - case PACKET_CHANGE_GAME_STATE: HANDLE_SERVER_READ(HandleServerChangeGameState); break; - case PACKET_CHAT_MESSAGE: HANDLE_SERVER_READ(HandleServerChatMessage); break; - case PACKET_COLLECT_PICKUP: HANDLE_SERVER_READ(HandleServerCollectPickup); break; - case PACKET_COMPASS: HANDLE_SERVER_READ(HandleServerCompass); break; - case PACKET_DESTROY_ENTITIES: HANDLE_SERVER_READ(HandleServerDestroyEntities); break; - case PACKET_ENCRYPTION_KEY_REQUEST: HANDLE_SERVER_READ(HandleServerEncryptionKeyRequest); break; - case PACKET_ENCRYPTION_KEY_RESPONSE: HANDLE_SERVER_READ(HandleServerEncryptionKeyResponse); break; - case PACKET_ENTITY: HANDLE_SERVER_READ(HandleServerEntity); break; - case PACKET_ENTITY_EQUIPMENT: HANDLE_SERVER_READ(HandleServerEntityEquipment); break; - case PACKET_ENTITY_HEAD_LOOK: HANDLE_SERVER_READ(HandleServerEntityHeadLook); break; - case PACKET_ENTITY_LOOK: HANDLE_SERVER_READ(HandleServerEntityLook); break; - case PACKET_ENTITY_METADATA: HANDLE_SERVER_READ(HandleServerEntityMetadata); break; - case PACKET_ENTITY_PROPERTIES: HANDLE_SERVER_READ(HandleServerEntityProperties); break; - case PACKET_ENTITY_RELATIVE_MOVE: HANDLE_SERVER_READ(HandleServerEntityRelativeMove); break; - case PACKET_ENTITY_RELATIVE_MOVE_LOOK: HANDLE_SERVER_READ(HandleServerEntityRelativeMoveLook); break; - case PACKET_ENTITY_STATUS: HANDLE_SERVER_READ(HandleServerEntityStatus); break; - case PACKET_ENTITY_TELEPORT: HANDLE_SERVER_READ(HandleServerEntityTeleport); break; - case PACKET_ENTITY_VELOCITY: HANDLE_SERVER_READ(HandleServerEntityVelocity); break; - case PACKET_INCREMENT_STATISTIC: HANDLE_SERVER_READ(HandleServerIncrementStatistic); break; - case PACKET_KEEPALIVE: HANDLE_SERVER_READ(HandleServerKeepAlive); break; - case PACKET_KICK: HANDLE_SERVER_READ(HandleServerKick); break; - case PACKET_LOGIN: HANDLE_SERVER_READ(HandleServerLogin); break; - case PACKET_MAP_CHUNK: HANDLE_SERVER_READ(HandleServerMapChunk); break; - case PACKET_MAP_CHUNK_BULK: HANDLE_SERVER_READ(HandleServerMapChunkBulk); break; - case PACKET_MULTI_BLOCK_CHANGE: HANDLE_SERVER_READ(HandleServerMultiBlockChange); break; - case PACKET_NAMED_SOUND_EFFECT: HANDLE_SERVER_READ(HandleServerNamedSoundEffect); break; - case PACKET_PLAYER_ABILITIES: HANDLE_SERVER_READ(HandleServerPlayerAbilities); break; - case PACKET_PLAYER_ANIMATION: HANDLE_SERVER_READ(HandleServerPlayerAnimation); break; - case PACKET_PLAYER_LIST_ITEM: HANDLE_SERVER_READ(HandleServerPlayerListItem); break; - case PACKET_PLAYER_POSITION_LOOK: HANDLE_SERVER_READ(HandleServerPlayerPositionLook); break; - case PACKET_PLUGIN_MESSAGE: HANDLE_SERVER_READ(HandleServerPluginMessage); break; - case PACKET_SET_EXPERIENCE: HANDLE_SERVER_READ(HandleServerSetExperience); break; - case PACKET_SET_SLOT: HANDLE_SERVER_READ(HandleServerSetSlot); break; - case PACKET_SLOT_SELECT: HANDLE_SERVER_READ(HandleServerSlotSelect); break; - case PACKET_SOUND_EFFECT: HANDLE_SERVER_READ(HandleServerSoundEffect); break; - case PACKET_SPAWN_MOB: HANDLE_SERVER_READ(HandleServerSpawnMob); break; - case PACKET_SPAWN_NAMED_ENTITY: HANDLE_SERVER_READ(HandleServerSpawnNamedEntity); break; - case PACKET_SPAWN_OBJECT_VEHICLE: HANDLE_SERVER_READ(HandleServerSpawnObjectVehicle); break; - case PACKET_SPAWN_PAINTING: HANDLE_SERVER_READ(HandleServerSpawnPainting); break; - case PACKET_SPAWN_PICKUP: HANDLE_SERVER_READ(HandleServerSpawnPickup); break; - case PACKET_TAB_COMPLETION: HANDLE_SERVER_READ(HandleServerTabCompletion); break; - case PACKET_TIME_UPDATE: HANDLE_SERVER_READ(HandleServerTimeUpdate); break; - case PACKET_UPDATE_HEALTH: HANDLE_SERVER_READ(HandleServerUpdateHealth); break; - case PACKET_UPDATE_SIGN: HANDLE_SERVER_READ(HandleServerUpdateSign); break; - case PACKET_UPDATE_TILE_ENTITY: HANDLE_SERVER_READ(HandleServerUpdateTileEntity); break; - case PACKET_WINDOW_CLOSE: HANDLE_SERVER_READ(HandleServerWindowClose); break; - case PACKET_WINDOW_CONTENTS: HANDLE_SERVER_READ(HandleServerWindowContents); break; - case PACKET_WINDOW_OPEN: HANDLE_SERVER_READ(HandleServerWindowOpen); break; - default: + case -1: { - if (m_ServerState == csEncryptedUnderstood) + Log("Receiving data from the server without an initial handshake message!"); + HANDLE_SERVER_READ(HandleServerUnknownPacket(PacketType, PacketLen, PacketReadSoFar)); + break; + } + + case 1: + { + // Status query: + switch (PacketType) { - Log("********************** Unknown packet 0x%02x from the server while encrypted; continuing to relay blind only", PacketType); - AString Data; - m_ServerBuffer.ResetRead(); - m_ServerBuffer.ReadAll(Data); - DataLog(Data.data(), Data.size(), "Current data in the server packet queue: %d bytes", Data.size()); - m_ServerState = csEncryptedUnknown; - m_ServerBuffer.ResetRead(); - if (m_ClientState == csUnencrypted) - { - CLIENTSEND(m_ServerBuffer); - } - else - { - CLIENTENCRYPTSEND(m_ServerBuffer); - } - return true; + case 0x00: HANDLE_SERVER_READ(HandleServerStatusResponse()); break; + case 0x01: HANDLE_SERVER_READ(HandleServerStatusPing()); break; + default: HANDLE_SERVER_READ(HandleServerUnknownPacket(PacketType, PacketLen, PacketReadSoFar)); break; } - else + break; + } + + case 2: + { + // Login: + switch (PacketType) { - Log("Unknown packet 0x%02x from the server while unencrypted; aborting connection", PacketType); - return false; + case 0x00: HANDLE_SERVER_READ(HandleServerLoginDisconnect()); break; + case 0x01: HANDLE_SERVER_READ(HandleServerLoginEncryptionKeyRequest()); break; + case 0x02: HANDLE_SERVER_READ(HandleServerLoginSuccess()); break; + default: HANDLE_SERVER_READ(HandleServerUnknownPacket(PacketType, PacketLen, PacketReadSoFar)); break; } + break; } - } // switch (PacketType) + + case 3: + { + // Game: + switch (PacketType) + { + case 0x00: HANDLE_SERVER_READ(HandleServerKeepAlive()); break; + case 0x01: HANDLE_SERVER_READ(HandleServerJoinGame()); break; + case 0x02: HANDLE_SERVER_READ(HandleServerChatMessage()); break; + case 0x03: HANDLE_SERVER_READ(HandleServerTimeUpdate()); break; + case 0x04: HANDLE_SERVER_READ(HandleServerEntityEquipment()); break; + case 0x05: HANDLE_SERVER_READ(HandleServerCompass()); break; + case 0x06: HANDLE_SERVER_READ(HandleServerUpdateHealth()); break; + case 0x07: HANDLE_SERVER_READ(HandleServerRespawn()); break; + case 0x08: HANDLE_SERVER_READ(HandleServerPlayerPositionLook()); break; + case 0x09: HANDLE_SERVER_READ(HandleServerSlotSelect()); break; + case 0x0a: HANDLE_SERVER_READ(HandleServerUseBed()); break; + case 0x0b: HANDLE_SERVER_READ(HandleServerPlayerAnimation()); break; + case 0x0c: HANDLE_SERVER_READ(HandleServerSpawnNamedEntity()); break; + case 0x0d: HANDLE_SERVER_READ(HandleServerCollectPickup()); break; + case 0x0e: HANDLE_SERVER_READ(HandleServerSpawnObjectVehicle()); break; + case 0x0f: HANDLE_SERVER_READ(HandleServerSpawnMob()); break; + case 0x10: HANDLE_SERVER_READ(HandleServerSpawnPainting()); break; + case 0x11: HANDLE_SERVER_READ(HandleServerSpawnExperienceOrbs()); break; + case 0x12: HANDLE_SERVER_READ(HandleServerEntityVelocity()); break; + case 0x13: HANDLE_SERVER_READ(HandleServerDestroyEntities()); break; + case 0x14: HANDLE_SERVER_READ(HandleServerEntity()); break; + case 0x15: HANDLE_SERVER_READ(HandleServerEntityRelativeMove()); break; + case 0x16: HANDLE_SERVER_READ(HandleServerEntityLook()); break; + case 0x17: HANDLE_SERVER_READ(HandleServerEntityRelativeMoveLook()); break; + case 0x18: HANDLE_SERVER_READ(HandleServerEntityTeleport()); break; + case 0x19: HANDLE_SERVER_READ(HandleServerEntityHeadLook()); break; + case 0x1a: HANDLE_SERVER_READ(HandleServerEntityStatus()); break; + case 0x1b: HANDLE_SERVER_READ(HandleServerAttachEntity()); break; + case 0x1c: HANDLE_SERVER_READ(HandleServerEntityMetadata()); break; + case 0x1f: HANDLE_SERVER_READ(HandleServerSetExperience()); break; + case 0x20: HANDLE_SERVER_READ(HandleServerEntityProperties()); break; + case 0x21: HANDLE_SERVER_READ(HandleServerMapChunk()); break; + case 0x22: HANDLE_SERVER_READ(HandleServerMultiBlockChange()); break; + case 0x23: HANDLE_SERVER_READ(HandleServerBlockChange()); break; + case 0x24: HANDLE_SERVER_READ(HandleServerBlockAction()); break; + case 0x26: HANDLE_SERVER_READ(HandleServerMapChunkBulk()); break; + case 0x27: HANDLE_SERVER_READ(HandleServerExplosion()); break; + case 0x28: HANDLE_SERVER_READ(HandleServerSoundEffect()); break; + case 0x29: HANDLE_SERVER_READ(HandleServerNamedSoundEffect()); break; + case 0x2b: HANDLE_SERVER_READ(HandleServerChangeGameState()); break; + case 0x2d: HANDLE_SERVER_READ(HandleServerWindowOpen()); break; + case 0x2e: HANDLE_SERVER_READ(HandleServerWindowClose()); break; + case 0x2f: HANDLE_SERVER_READ(HandleServerSetSlot()); break; + case 0x30: HANDLE_SERVER_READ(HandleServerWindowContents()); break; + case 0x33: HANDLE_SERVER_READ(HandleServerUpdateSign()); break; + case 0x35: HANDLE_SERVER_READ(HandleServerUpdateTileEntity()); break; + case 0x37: HANDLE_SERVER_READ(HandleServerStatistics()); break; + case 0x38: HANDLE_SERVER_READ(HandleServerPlayerListItem()); break; + case 0x39: HANDLE_SERVER_READ(HandleServerPlayerAbilities()); break; + case 0x3a: HANDLE_SERVER_READ(HandleServerTabCompletion()); break; + case 0x3f: HANDLE_SERVER_READ(HandleServerPluginMessage()); break; + case 0x40: HANDLE_SERVER_READ(HandleServerKick()); break; + default: HANDLE_SERVER_READ(HandleServerUnknownPacket(PacketType, PacketLen, PacketReadSoFar)); break; + } // switch (PacketType) + break; + } // case 3 - Game + + // TODO: Move this elsewhere + default: + { + Log("Received a packet from the server while in an unknown state: %d", m_ServerProtocolState); + HANDLE_SERVER_READ(HandleServerUnknownPacket(PacketType, PacketLen, PacketReadSoFar)); + break; + } + } // switch (m_ProtocolState) + m_ServerBuffer.CommitRead(); } // while (CanReadBytes(1)) return true; @@ -761,6 +747,76 @@ bool cConnection::DecodeServersPackets(const char * a_Data, int a_Size) +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// packet handling, client-side, initial handshake: + +bool cConnection::HandleClientHandshake(void) +{ + // Read the packet from the client: + HANDLE_CLIENT_PACKET_READ(ReadVarInt, UInt32, ProtocolVersion); + HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, ServerHost); + HANDLE_CLIENT_PACKET_READ(ReadBEShort, short, ServerPort); + HANDLE_CLIENT_PACKET_READ(ReadVarInt, UInt32, NextState); + m_ClientBuffer.CommitRead(); + + Log("Received an initial handshake packet from the client:"); + Log(" ProtocolVersion = %u", ProtocolVersion); + Log(" ServerHost = \"%s\"", ServerHost.c_str()); + Log(" ServerPort = %d", ServerPort); + Log(" NextState = %u", NextState); + + // Send the same packet to the server, but with our port: + cByteBuffer Packet(512); + Packet.WriteVarInt(0); // Packet type - initial handshake + Packet.WriteVarInt(ProtocolVersion); + Packet.WriteVarUTF8String(ServerHost); + Packet.WriteBEShort(m_Server.GetConnectPort()); + Packet.WriteVarInt(NextState); + AString Pkt; + Packet.ReadAll(Pkt); + cByteBuffer ToServer(512); + ToServer.WriteVarUTF8String(Pkt); + SERVERSEND(ToServer); + + m_ClientProtocolState = (int)NextState; + m_ServerProtocolState = (int)NextState; + + return true; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// packet handling, client-side, login: + +bool cConnection::HandleClientLoginEncryptionKeyResponse(void) +{ + Log("Client: Unexpected packet: encryption key response"); + return true; +} + + + + + +bool cConnection::HandleClientLoginStart(void) +{ + HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, UserName); + Log("Received a login start packet from the client:"); + Log(" Username = \"%s\"", UserName.c_str()); + COPY_TO_SERVER(); + return true; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// packet handling, client-side, game: + bool cConnection::HandleClientAnimation(void) { HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, EntityID); @@ -824,7 +880,7 @@ bool cConnection::HandleClientBlockPlace(void) bool cConnection::HandleClientChatMessage(void) { - HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, Message); + HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, Message); Log("Received a PACKET_CHAT_MESSAGE from the client:"); Log(" Message = \"%s\"", Message.c_str()); COPY_TO_SERVER(); @@ -870,7 +926,7 @@ bool cConnection::HandleClientCreativeInventoryAction(void) bool cConnection::HandleClientDisconnect(void) { - HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, Reason); + HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, Reason); Log("Received a PACKET_DISCONNECT from the client:"); Log(" Reason = \"%s\"", Reason.c_str()); COPY_TO_SERVER(); @@ -881,42 +937,15 @@ bool cConnection::HandleClientDisconnect(void) -bool cConnection::HandleClientEncryptionKeyResponse(void) -{ - HANDLE_CLIENT_PACKET_READ(ReadBEShort, short, EncKeyLength); - AString EncKey; - if (!m_ClientBuffer.ReadString(EncKey, EncKeyLength)) - { - return true; - } - HANDLE_CLIENT_PACKET_READ(ReadBEShort, short, EncNonceLength); - AString EncNonce; - if (!m_ClientBuffer.ReadString(EncNonce, EncNonceLength)) - { - return true; - } - if ((EncKeyLength > MAX_ENC_LEN) || (EncNonceLength > MAX_ENC_LEN)) - { - Log("Client: Too long encryption params"); - return true; - } - StartClientEncryption(EncKey, EncNonce); - return true; -} - - - - - bool cConnection::HandleClientEntityAction(void) { HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, PlayerID); HANDLE_CLIENT_PACKET_READ(ReadByte, Byte, ActionType); - HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, UnknownHorseVal); + HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, HorseJumpBoost); Log("Received a PACKET_ENTITY_ACTION from the client:"); Log(" PlayerID = %d", PlayerID); Log(" ActionType = %d", ActionType); - Log(" UnknownHorseVal = %d (0x%08x)", UnknownHorseVal, UnknownHorseVal); + Log(" HorseJumpBoost = %d (0x%08x)", HorseJumpBoost, HorseJumpBoost); COPY_TO_SERVER(); return true; } @@ -925,37 +954,6 @@ bool cConnection::HandleClientEntityAction(void) -bool cConnection::HandleClientHandshake(void) -{ - // Read the packet from the client: - HANDLE_CLIENT_PACKET_READ(ReadByte, Byte, ProtocolVersion); - HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, Username); - HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, ServerHost); - HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, ServerPort); - m_ClientBuffer.CommitRead(); - - Log("Received a PACKET_HANDSHAKE from the client:"); - Log(" ProtocolVersion = %d", ProtocolVersion); - Log(" Username = \"%s\"", Username.c_str()); - Log(" ServerHost = \"%s\"", ServerHost.c_str()); - Log(" ServerPort = %d", ServerPort); - - // Send the same packet to the server, but with our port: - cByteBuffer ToServer(512); - ToServer.WriteByte (PACKET_HANDSHAKE); - ToServer.WriteByte (ProtocolVersion); - ToServer.WriteBEUTF16String16(Username); - ToServer.WriteBEUTF16String16(ServerHost); - ToServer.WriteBEInt (m_Server.GetConnectPort()); - SERVERSEND(ToServer); - - return true; -} - - - - - bool cConnection::HandleClientKeepAlive(void) { HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, ID); @@ -970,11 +968,12 @@ bool cConnection::HandleClientKeepAlive(void) bool cConnection::HandleClientLocaleAndView(void) { - HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, Locale); - HANDLE_CLIENT_PACKET_READ(ReadChar, char, ViewDistance); - HANDLE_CLIENT_PACKET_READ(ReadChar, char, ChatFlags); - HANDLE_CLIENT_PACKET_READ(ReadChar, char, Difficulty); - HANDLE_CLIENT_PACKET_READ(ReadChar, char, ShowCape); + HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, Locale); + HANDLE_CLIENT_PACKET_READ(ReadChar, char, ViewDistance); + HANDLE_CLIENT_PACKET_READ(ReadChar, char, ChatFlags); + HANDLE_CLIENT_PACKET_READ(ReadChar, char, Unused); + HANDLE_CLIENT_PACKET_READ(ReadChar, char, Difficulty); + HANDLE_CLIENT_PACKET_READ(ReadChar, char, ShowCape); Log("Received a PACKET_LOCALE_AND_VIEW from the client"); COPY_TO_SERVER(); return true; @@ -999,7 +998,7 @@ bool cConnection::HandleClientPing(void) bool cConnection::HandleClientPlayerAbilities(void) { - HANDLE_CLIENT_PACKET_READ(ReadChar, char, Flags); + HANDLE_CLIENT_PACKET_READ(ReadChar, char, Flags); HANDLE_CLIENT_PACKET_READ(ReadBEFloat, float, FlyingSpeed); HANDLE_CLIENT_PACKET_READ(ReadBEFloat, float, WalkingSpeed); Log("Receives a PACKET_PLAYER_ABILITIES from the client:"); @@ -1030,7 +1029,7 @@ bool cConnection::HandleClientPlayerLook(void) bool cConnection::HandleClientPlayerOnGround(void) { - HANDLE_CLIENT_PACKET_READ(ReadChar, char, OnGround); + HANDLE_CLIENT_PACKET_READ(ReadChar, char, OnGround); Log("Received a PACKET_PLAYER_ON_GROUND from the client"); COPY_TO_SERVER(); return true; @@ -1043,8 +1042,8 @@ bool cConnection::HandleClientPlayerOnGround(void) bool cConnection::HandleClientPlayerPosition(void) { HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, PosX); - HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, Stance); HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, PosY); + HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, Stance); HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, PosZ); HANDLE_CLIENT_PACKET_READ(ReadChar, char, IsOnGround); Log("Received a PACKET_PLAYER_POSITION from the client"); @@ -1062,8 +1061,8 @@ bool cConnection::HandleClientPlayerPosition(void) bool cConnection::HandleClientPlayerPositionLook(void) { HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, PosX); - HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, Stance); HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, PosY); + HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, Stance); HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, PosZ); HANDLE_CLIENT_PACKET_READ(ReadBEFloat, float, Yaw); HANDLE_CLIENT_PACKET_READ(ReadBEFloat, float, Pitch); @@ -1071,7 +1070,7 @@ bool cConnection::HandleClientPlayerPositionLook(void) Log("Received a PACKET_PLAYER_POSITION_LOOK from the client"); Log(" Pos = {%.03f, %.03f, %.03f}", PosX, PosY, PosZ); Log(" Stance = %.03f", Stance); - Log(" Y, P = %.03f, %.03f", Yaw, Pitch); + Log(" Yaw, Pitch = <%.03f, %.03f>", Yaw, Pitch); Log(" IsOnGround = %s", IsOnGround ? "true" : "false"); COPY_TO_SERVER(); @@ -1084,7 +1083,7 @@ bool cConnection::HandleClientPlayerPositionLook(void) bool cConnection::HandleClientPluginMessage(void) { - HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, ChannelName); + HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, ChannelName); HANDLE_CLIENT_PACKET_READ(ReadBEShort, short, Length); AString Data; if (!m_ClientBuffer.ReadString(Data, Length)) @@ -1115,9 +1114,33 @@ bool cConnection::HandleClientSlotSelect(void) +bool cConnection::HandleClientStatusPing(void) +{ + HANDLE_CLIENT_PACKET_READ(ReadBEInt64, Int64, Time); + Log("Received the status ping packet from the client:"); + Log(" Time = %lld", Time); + COPY_TO_SERVER(); + return true; +} + + + + + +bool cConnection::HandleClientStatusRequest(void) +{ + Log("Received the status request packet from the client"); + COPY_TO_SERVER(); + return true; +} + + + + + bool cConnection::HandleClientTabCompletion(void) { - HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, Query); + HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, Query); Log("Received a PACKET_TAB_COMPLETION query from the client"); Log(" Query = \"%s\"", Query.c_str()); COPY_TO_SERVER(); @@ -1130,13 +1153,13 @@ bool cConnection::HandleClientTabCompletion(void) bool cConnection::HandleClientUpdateSign(void) { - HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, BlockX); - HANDLE_CLIENT_PACKET_READ(ReadBEShort, short, BlockY); - HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, BlockZ); - HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, Line1); - HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, Line2); - HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, Line3); - HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, Line4); + HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, BlockX); + HANDLE_CLIENT_PACKET_READ(ReadBEShort, short, BlockY); + HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, BlockZ); + HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, Line1); + HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, Line2); + HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, Line3); + HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, Line4); Log("Received a PACKET_UPDATE_SIGN from the client:"); Log(" Block = {%d, %d, %d}", BlockX, BlockY, BlockZ); Log(" Lines = \"%s\", \"%s\", \"%s\", \"%s\"", Line1.c_str(), Line2.c_str(), Line3.c_str(), Line4.c_str()); @@ -1150,11 +1173,9 @@ bool cConnection::HandleClientUpdateSign(void) bool cConnection::HandleClientUseEntity(void) { - HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, PlayerID); HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, EntityID); HANDLE_CLIENT_PACKET_READ(ReadChar, char, MouseButton); Log("Received a PACKET_USE_ENTITY from the client:"); - Log(" PlayerID = %d", PlayerID); Log(" EntityID = %d", EntityID); Log(" MouseButton = %d", MouseButton); COPY_TO_SERVER(); @@ -1169,9 +1190,9 @@ bool cConnection::HandleClientWindowClick(void) { HANDLE_CLIENT_PACKET_READ(ReadChar, char, WindowID); HANDLE_CLIENT_PACKET_READ(ReadBEShort, short, SlotNum); - HANDLE_CLIENT_PACKET_READ(ReadChar, char, IsRightClick); + HANDLE_CLIENT_PACKET_READ(ReadChar, char, Button); HANDLE_CLIENT_PACKET_READ(ReadBEShort, short, TransactionID); - HANDLE_CLIENT_PACKET_READ(ReadChar, char, IsShiftClick); + HANDLE_CLIENT_PACKET_READ(ReadChar, char, Mode); AString Item; if (!ParseSlot(m_ClientBuffer, Item)) { @@ -1180,7 +1201,7 @@ bool cConnection::HandleClientWindowClick(void) Log("Received a PACKET_WINDOW_CLICK from the client"); Log(" WindowID = %d", WindowID); Log(" SlotNum = %d", SlotNum); - Log(" IsRclk = %d, IsShift = %d", IsRightClick, IsShiftClick); + Log(" Button = %d, Mode = %d", Button, Mode); Log(" TransactionID = 0x%x", TransactionID); Log(" ClickedItem = %s", Item.c_str()); COPY_TO_SERVER(); @@ -1204,6 +1225,100 @@ bool cConnection::HandleClientWindowClose(void) +bool cConnection::HandleClientUnknownPacket(UInt32 a_PacketType, UInt32 a_PacketLen, UInt32 a_PacketReadSoFar) +{ + AString Data; + if (!m_ClientBuffer.ReadString(Data, a_PacketLen - a_PacketReadSoFar)) + { + return false; + } + DataLog(Data.data(), Data.size(), "****************** Unknown packet 0x%x from the client; relaying and ignoring", a_PacketType); + COPY_TO_SERVER(); + return true; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// packet handling, server-side, login: + +bool cConnection::HandleServerLoginDisconnect(void) +{ + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Reason); + Log("Received a login-disconnect packet from the server:"); + Log(" Reason = \"%s\"", Reason.c_str()); + COPY_TO_SERVER(); + return true; +} + + + + + +bool cConnection::HandleServerLoginEncryptionKeyRequest(void) +{ + // Read the packet from the server: + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, ServerID); + HANDLE_SERVER_PACKET_READ(ReadBEShort, short, PublicKeyLength); + AString PublicKey; + if (!m_ServerBuffer.ReadString(PublicKey, PublicKeyLength)) + { + return false; + } + HANDLE_SERVER_PACKET_READ(ReadBEShort, short, NonceLength); + AString Nonce; + if (!m_ServerBuffer.ReadString(Nonce, NonceLength)) + { + return false; + } + Log("Got PACKET_ENCRYPTION_KEY_REQUEST from the SERVER:"); + Log(" ServerID = %s", ServerID.c_str()); + + // Reply to the server: + SendEncryptionKeyResponse(PublicKey, Nonce); + + // Do not send to client - we want the client connection open + return true; +} + + + + + +bool cConnection::HandleServerLoginSuccess(void) +{ + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, UUID); + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Username); + Log("Received a login success packet from the server:"); + Log(" UUID = \"%s\"", UUID.c_str()); + Log(" Username = \"%s\"", Username.c_str()); + + Log("Server is now in protocol state Game."); + m_ServerProtocolState = 3; + + if (m_IsServerEncrypted) + { + Log("Server communication is now encrypted"); + m_ServerState = csEncryptedUnderstood; + DataLog(m_ServerEncryptionBuffer.data(), m_ServerEncryptionBuffer.size(), "Sending the queued data to server (%u bytes):", m_ServerEncryptionBuffer.size()); + SERVERENCRYPTSEND(m_ServerEncryptionBuffer.data(), m_ServerEncryptionBuffer.size()); + m_ServerEncryptionBuffer.clear(); + } + COPY_TO_CLIENT(); + Log("Client is now in protocol state Game."); + m_ClientProtocolState = 3; + return true; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// packet handling, server-side, game: + bool cConnection::HandleServerAttachEntity(void) { HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID); @@ -1223,16 +1338,16 @@ bool cConnection::HandleServerAttachEntity(void) bool cConnection::HandleServerBlockAction(void) { - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockX); - HANDLE_SERVER_PACKET_READ(ReadBEShort, short, BlockY); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockZ); - HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Byte1); - HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Byte2); - HANDLE_SERVER_PACKET_READ(ReadBEShort, short, BlockID); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockX); + HANDLE_SERVER_PACKET_READ(ReadBEShort, short, BlockY); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockZ); + HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Byte1); + HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Byte2); + HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, BlockID); Log("Received a PACKET_BLOCK_ACTION from the server:"); Log(" Pos = {%d, %d, %d}", BlockX, BlockY, BlockZ); Log(" Bytes = (%d, %d) == (0x%x, 0x%x)", Byte1, Byte2, Byte1, Byte2); - Log(" BlockID = %d", BlockID); + Log(" BlockID = %u", BlockID); COPY_TO_CLIENT(); return true; } @@ -1243,11 +1358,11 @@ bool cConnection::HandleServerBlockAction(void) bool cConnection::HandleServerBlockChange(void) { - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockX); - HANDLE_SERVER_PACKET_READ(ReadByte, Byte, BlockY); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockZ); - HANDLE_SERVER_PACKET_READ(ReadBEShort, short, BlockType); - HANDLE_SERVER_PACKET_READ(ReadChar, char, BlockMeta); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockX); + HANDLE_SERVER_PACKET_READ(ReadByte, Byte, BlockY); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockZ); + HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, BlockType); + HANDLE_SERVER_PACKET_READ(ReadChar, char, BlockMeta); Log("Received a PACKET_BLOCK_CHANGE from the server"); COPY_TO_CLIENT(); return true; @@ -1259,11 +1374,11 @@ bool cConnection::HandleServerBlockChange(void) bool cConnection::HandleServerChangeGameState(void) { - HANDLE_SERVER_PACKET_READ(ReadChar, char, Reason); - HANDLE_SERVER_PACKET_READ(ReadChar, char, Data); + HANDLE_SERVER_PACKET_READ(ReadChar, char, Reason); + HANDLE_SERVER_PACKET_READ(ReadBEFloat, float, Data); Log("Received a PACKET_CHANGE_GAME_STATE from the server:"); Log(" Reason = %d", Reason); - Log(" Data = %d", Data); + Log(" Data = %f", Data); COPY_TO_CLIENT(); return true; } @@ -1274,7 +1389,7 @@ bool cConnection::HandleServerChangeGameState(void) bool cConnection::HandleServerChatMessage(void) { - HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, Message); + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Message); Log("Received a PACKET_CHAT_MESSAGE from the server:"); Log(" Message = \"%s\"", Message.c_str()); COPY_TO_CLIENT(); @@ -1332,48 +1447,6 @@ bool cConnection::HandleServerDestroyEntities(void) -bool cConnection::HandleServerEncryptionKeyRequest(void) -{ - // Read the packet from the server: - HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, ServerID); - HANDLE_SERVER_PACKET_READ(ReadBEShort, short, PublicKeyLength); - AString PublicKey; - if (!m_ServerBuffer.ReadString(PublicKey, PublicKeyLength)) - { - return false; - } - HANDLE_SERVER_PACKET_READ(ReadBEShort, short, NonceLength); - AString Nonce; - if (!m_ServerBuffer.ReadString(Nonce, NonceLength)) - { - return false; - } - Log("Got PACKET_ENCRYPTION_KEY_REQUEST from the SERVER:"); - Log(" ServerID = %s", ServerID.c_str()); - - // Reply to the server: - SendEncryptionKeyResponse(PublicKey, Nonce); - - // Send a 0xFD Encryption Key Request http://wiki.vg/Protocol#0xFD to the client, using our own key: - Log("Sending PACKET_ENCRYPTION_KEY_REQUEST to the CLIENT"); - AString key; - StringSink sink(key); // GCC won't allow inline instantiation in the following line, damned temporary refs - m_Server.GetPublicKey().Save(sink); - cByteBuffer ToClient(512); - ToClient.WriteByte (PACKET_ENCRYPTION_KEY_REQUEST); - ToClient.WriteBEUTF16String16(ServerID); - ToClient.WriteBEShort ((short)key.size()); - ToClient.WriteBuf (key.data(), key.size()); - ToClient.WriteBEShort (4); - ToClient.WriteBEInt (m_Nonce); // Using 'this' as the cryptographic nonce, so that we don't have to generate one each time :) - CLIENTSEND(ToClient); - return true; -} - - - - - bool cConnection::HandleServerEntity(void) { HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID); @@ -1472,20 +1545,18 @@ bool cConnection::HandleServerEntityProperties(void) for (int i = 0; i < Count; i++) { - HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, Key); - HANDLE_SERVER_PACKET_READ(ReadBEDouble, double, Value); - Log(" \"%s\" = %f", Key.c_str(), Value); - } // for i - - HANDLE_SERVER_PACKET_READ(ReadBEShort, short, ListLength); - Log(" ListLength = %d", ListLength); - for (int i = 0; i < ListLength; i++) - { - HANDLE_SERVER_PACKET_READ(ReadBEInt64, Int64, UUIDHi); - HANDLE_SERVER_PACKET_READ(ReadBEInt64, Int64, UUIDLo); - HANDLE_SERVER_PACKET_READ(ReadBEDouble, double, DblVal); - HANDLE_SERVER_PACKET_READ(ReadByte, Byte, ByteVal); - Log(" [%d] = {0x%08llx%08llx, %f, %i}", i, UUIDHi, UUIDLo, DblVal, ByteVal); + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Key); + HANDLE_SERVER_PACKET_READ(ReadBEDouble, double, Value); + HANDLE_SERVER_PACKET_READ(ReadBEShort, short, ListLength); + Log(" \"%s\" = %f; %d modifiers", Key.c_str(), Value, ListLength); + for (short j = 0; j < ListLength; j++) + { + HANDLE_SERVER_PACKET_READ(ReadBEInt64, Int64, UUIDHi); + HANDLE_SERVER_PACKET_READ(ReadBEInt64, Int64, UUIDLo); + HANDLE_SERVER_PACKET_READ(ReadBEDouble, double, DblVal); + HANDLE_SERVER_PACKET_READ(ReadByte, Byte, ByteVal); + Log(" [%d] = {0x%08llx%08llx, %f, %u}", j, UUIDHi, UUIDLo, DblVal, ByteVal); + } } // for i COPY_TO_CLIENT(); return true; @@ -1550,7 +1621,7 @@ bool cConnection::HandleServerEntityStatus(void) bool cConnection::HandleServerEntityTeleport(void) { - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID); HANDLE_SERVER_PACKET_READ(ReadBEInt, int, AbsX); HANDLE_SERVER_PACKET_READ(ReadBEInt, int, AbsY); HANDLE_SERVER_PACKET_READ(ReadBEInt, int, AbsZ); @@ -1558,7 +1629,7 @@ bool cConnection::HandleServerEntityTeleport(void) HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Pitch); Log("Received a PACKET_ENTITY_TELEPORT from the server:"); Log(" EntityID = %d", EntityID); - Log(" Pos = (%d, %d, %d) ~ {%.02f, %.02f, %.02f}", AbsX, AbsY, AbsZ, (double)AbsX / 32, (double)AbsY / 32, (double)AbsZ / 32); + Log(" Pos = %s", PrintableAbsIntTriplet(AbsX, AbsY, AbsZ).c_str()); Log(" Yaw = %d", Yaw); Log(" Pitch = %d", Pitch); COPY_TO_CLIENT(); @@ -1586,6 +1657,49 @@ bool cConnection::HandleServerEntityVelocity(void) +bool cConnection::HandleServerExplosion(void) +{ + HANDLE_SERVER_PACKET_READ(ReadBEFloat, float, PosX); + HANDLE_SERVER_PACKET_READ(ReadBEFloat, float, PosY); + HANDLE_SERVER_PACKET_READ(ReadBEFloat, float, PosZ); + HANDLE_SERVER_PACKET_READ(ReadBEFloat, float, Force); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, NumRecords); + struct sCoords + { + int x, y, z; + + sCoords(int a_X, int a_Y, int a_Z) : x(a_X), y(a_Y), z(a_Z) {} + } ; + std::vector<sCoords> Records; + Records.reserve(NumRecords); + int PosXI = (int)PosX, PosYI = (int)PosY, PosZI = (int)PosZ; + for (int i = 0; i < NumRecords; i++) + { + HANDLE_SERVER_PACKET_READ(ReadChar, char, rx); + HANDLE_SERVER_PACKET_READ(ReadChar, char, ry); + HANDLE_SERVER_PACKET_READ(ReadChar, char, rz); + Records.push_back(sCoords(PosXI + rx, PosYI + ry, PosZI + rz)); + } + HANDLE_SERVER_PACKET_READ(ReadBEFloat, float, PlayerMotionX); + HANDLE_SERVER_PACKET_READ(ReadBEFloat, float, PlayerMotionY); + HANDLE_SERVER_PACKET_READ(ReadBEFloat, float, PlayerMotionZ); + Log("Received a PACKET_EXPLOSION from the server:"); + Log(" Pos = {%.02f, %.02f, %.02f}", PosX, PosY, PosZ); + Log(" Force = %.02f", Force); + Log(" NumRecords = %d", NumRecords); + for (int i = 0; i < NumRecords; i++) + { + Log(" Records[%d] = {%d, %d, %d}", i, Records[i].x, Records[i].y, Records[i].z); + } + Log(" Player motion = <%.02f, %.02f, %.02f>", PlayerMotionX, PlayerMotionY, PlayerMotionZ); + COPY_TO_CLIENT(); + return true; +} + + + + + bool cConnection::HandleServerIncrementStatistic(void) { // 0xc8 @@ -1602,12 +1716,22 @@ bool cConnection::HandleServerIncrementStatistic(void) -bool cConnection::HandleServerKeepAlive(void) +bool cConnection::HandleServerJoinGame(void) { - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PingID); - Log("Received a PACKET_KEEP_ALIVE from the server:"); - Log(" ID = %d", PingID); - COPY_TO_CLIENT() + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID); + HANDLE_SERVER_PACKET_READ(ReadChar, char, GameMode); + HANDLE_SERVER_PACKET_READ(ReadChar, char, Dimension); + HANDLE_SERVER_PACKET_READ(ReadChar, char, Difficulty); + HANDLE_SERVER_PACKET_READ(ReadChar, char, MaxPlayers); + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, LevelType); + Log("Received a PACKET_LOGIN from the server:"); + Log(" EntityID = %d", EntityID); + Log(" GameMode = %d", GameMode); + Log(" Dimension = %d", Dimension); + Log(" Difficulty = %d", Difficulty); + Log(" MaxPlayers = %d", MaxPlayers); + Log(" LevelType = \"%s\"", LevelType.c_str()); + COPY_TO_CLIENT(); return true; } @@ -1615,19 +1739,12 @@ bool cConnection::HandleServerKeepAlive(void) -bool cConnection::HandleServerEncryptionKeyResponse(void) +bool cConnection::HandleServerKeepAlive(void) { - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, Lengths); - if (Lengths != 0) - { - Log("Lengths are not zero!"); - return true; - } - Log("Server communication is now encrypted"); - m_ServerState = csEncryptedUnderstood; - DataLog(m_ServerEncryptionBuffer.data(), m_ServerEncryptionBuffer.size(), "Sending the queued data to server (%u bytes):", m_ServerEncryptionBuffer.size()); - SERVERENCRYPTSEND(m_ServerEncryptionBuffer.data(), m_ServerEncryptionBuffer.size()); - m_ServerEncryptionBuffer.clear(); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PingID); + Log("Received a PACKET_KEEP_ALIVE from the server:"); + Log(" ID = %d", PingID); + COPY_TO_CLIENT() return true; } @@ -1637,7 +1754,7 @@ bool cConnection::HandleServerEncryptionKeyResponse(void) bool cConnection::HandleServerKick(void) { - HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, Reason); + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Reason); Log("Received PACKET_KICK from the SERVER:"); if (m_HasClientPinged) { @@ -1707,31 +1824,6 @@ bool cConnection::HandleServerKick(void) -bool cConnection::HandleServerLogin(void) -{ - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID); - HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, LevelType); - HANDLE_SERVER_PACKET_READ(ReadChar, char, GameMode); - HANDLE_SERVER_PACKET_READ(ReadChar, char, Dimension); - HANDLE_SERVER_PACKET_READ(ReadChar, char, Difficulty); - HANDLE_SERVER_PACKET_READ(ReadChar, char, Unused); - HANDLE_SERVER_PACKET_READ(ReadChar, char, MaxPlayers); - Log("Received a PACKET_LOGIN from the server:"); - Log(" EntityID = %d", EntityID); - Log(" LevelType = \"%s\"", LevelType.c_str()); - Log(" GameMode = %d", GameMode); - Log(" Dimension = %d", Dimension); - Log(" Difficulty = %d", Difficulty); - Log(" Unused = %d", Unused); - Log(" MaxPlayers = %d", MaxPlayers); - COPY_TO_CLIENT(); - return true; -} - - - - - bool cConnection::HandleServerMapChunk(void) { HANDLE_SERVER_PACKET_READ(ReadBEInt, int, ChunkX); @@ -1811,6 +1903,7 @@ bool cConnection::HandleServerMapChunkBulk(void) // TODO: Save the compressed data into a file for later analysis COPY_TO_CLIENT(); + Sleep(50); return true; } @@ -1842,15 +1935,15 @@ bool cConnection::HandleServerMultiBlockChange(void) bool cConnection::HandleServerNamedSoundEffect(void) { - HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, SoundName); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ); - HANDLE_SERVER_PACKET_READ(ReadBEFloat, float, Volume); - HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Pitch); + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, SoundName); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ); + HANDLE_SERVER_PACKET_READ(ReadBEFloat, float, Volume); + HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Pitch); Log("Received a PACKET_NAMED_SOUND_EFFECT from the server:"); Log(" SoundName = \"%s\"", SoundName.c_str()); - Log(" Pos = (%d, %d, %d) ~ {%d, %d, %d}", PosX, PosY, PosZ, PosX / 8, PosY / 8, PosZ / 8); + Log(" Pos = %s", PrintableAbsIntTriplet(PosX, PosY, PosZ, 8).c_str()); Log(" Volume = %f", Volume); Log(" Pitch = %d", Pitch); COPY_TO_CLIENT(); @@ -1880,10 +1973,10 @@ bool cConnection::HandleServerPlayerAbilities(void) bool cConnection::HandleServerPlayerAnimation(void) { - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PlayerID); - HANDLE_SERVER_PACKET_READ(ReadByte, Byte, AnimationID); + HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, PlayerID); + HANDLE_SERVER_PACKET_READ(ReadByte, Byte, AnimationID); Log("Received a PACKET_PLAYER_ANIMATION from the server:"); - Log(" PlayerID: %d (0x%x)", PlayerID, PlayerID); + Log(" PlayerID: %u (0x%x)", PlayerID, PlayerID); Log(" Animation: %d", AnimationID); COPY_TO_CLIENT(); return true; @@ -1895,7 +1988,7 @@ bool cConnection::HandleServerPlayerAnimation(void) bool cConnection::HandleServerPlayerListItem(void) { - HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, PlayerName); + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, PlayerName); HANDLE_SERVER_PACKET_READ(ReadChar, char, IsOnline); HANDLE_SERVER_PACKET_READ(ReadBEShort, short, Ping); Log("Received a PACKET_PLAYERLIST_ITEM from the server:"); @@ -1912,7 +2005,6 @@ bool cConnection::HandleServerPlayerListItem(void) bool cConnection::HandleServerPlayerPositionLook(void) { HANDLE_SERVER_PACKET_READ(ReadBEDouble, double, PosX); - HANDLE_SERVER_PACKET_READ(ReadBEDouble, double, Stance); HANDLE_SERVER_PACKET_READ(ReadBEDouble, double, PosY); HANDLE_SERVER_PACKET_READ(ReadBEDouble, double, PosZ); HANDLE_SERVER_PACKET_READ(ReadBEFloat, float, Yaw); @@ -1932,7 +2024,7 @@ bool cConnection::HandleServerPlayerPositionLook(void) bool cConnection::HandleServerPluginMessage(void) { - HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, ChannelName); + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, ChannelName); HANDLE_SERVER_PACKET_READ(ReadBEShort, short, Length); AString Data; if (!m_ServerBuffer.ReadString(Data, Length)) @@ -1942,7 +2034,26 @@ bool cConnection::HandleServerPluginMessage(void) Log("Received a PACKET_PLUGIN_MESSAGE from the server"); Log(" ChannelName = \"%s\"", ChannelName.c_str()); DataLog(Data.data(), Length, " Data: %d bytes", Length); - COPY_TO_SERVER(); + COPY_TO_CLIENT(); + return true; +} + + + + + +bool cConnection::HandleServerRespawn(void) +{ + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, Dimension); + HANDLE_SERVER_PACKET_READ(ReadChar, char, Difficulty); + HANDLE_SERVER_PACKET_READ(ReadChar, char, GameMode); + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, LevelType); + Log("Received a respawn packet from the server:"); + Log(" Dimension = %d", Dimension); + Log(" Difficulty = %d", Difficulty); + Log(" GameMode = %d", GameMode); + Log(" LevelType = \"%s\"", LevelType.c_str()); + COPY_TO_CLIENT(); return true; } @@ -1990,7 +2101,7 @@ bool cConnection::HandleServerSetSlot(void) bool cConnection::HandleServerSlotSelect(void) { - HANDLE_SERVER_PACKET_READ(ReadBEShort, short, SlotNum); + HANDLE_SERVER_PACKET_READ(ReadByte, Byte, SlotNum); Log("Received a PACKET_SLOT_SELECT from the server:"); Log(" SlotNum = %d", SlotNum); COPY_TO_CLIENT(); @@ -2022,19 +2133,38 @@ bool cConnection::HandleServerSoundEffect(void) +bool cConnection::HandleServerSpawnExperienceOrbs(void) +{ + HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, EntityID); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ); + HANDLE_SERVER_PACKET_READ(ReadBEShort, short, Count); + Log("Received a SPAWN_EXPERIENCE_ORBS packet from the server:"); + Log(" EntityID = %u (0x%x)", EntityID, EntityID); + Log(" Pos = %s", PrintableAbsIntTriplet(PosX, PosY, PosZ).c_str()); + Log(" Count = %d", Count); + COPY_TO_CLIENT(); + return true; +} + + + + + bool cConnection::HandleServerSpawnMob(void) { - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID); - HANDLE_SERVER_PACKET_READ(ReadChar, char, MobType); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ); - HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Yaw); - HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Pitch); - HANDLE_SERVER_PACKET_READ(ReadByte, Byte, HeadYaw); - HANDLE_SERVER_PACKET_READ(ReadBEShort, short, VelocityX); - HANDLE_SERVER_PACKET_READ(ReadBEShort, short, VelocityY); - HANDLE_SERVER_PACKET_READ(ReadBEShort, short, VelocityZ); + HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, EntityID); + HANDLE_SERVER_PACKET_READ(ReadChar, char, MobType); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ); + HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Yaw); + HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Pitch); + HANDLE_SERVER_PACKET_READ(ReadByte, Byte, HeadYaw); + HANDLE_SERVER_PACKET_READ(ReadBEShort, short, VelocityX); + HANDLE_SERVER_PACKET_READ(ReadBEShort, short, VelocityY); + HANDLE_SERVER_PACKET_READ(ReadBEShort, short, VelocityZ); AString Metadata; if (!ParseMetadata(m_ServerBuffer, Metadata)) { @@ -2043,7 +2173,7 @@ bool cConnection::HandleServerSpawnMob(void) AString HexDump; CreateHexDump(HexDump, Metadata.data(), Metadata.size(), 32); Log("Received a PACKET_SPAWN_MOB from the server:"); - Log(" EntityID = %d", EntityID); + Log(" EntityID = %u (0x%x)", EntityID, EntityID); Log(" MobType = %d", MobType); Log(" Pos = %s", PrintableAbsIntTriplet(PosX, PosY, PosZ).c_str()); Log(" Angles = [%d, %d, %d]", Yaw, Pitch, HeadYaw); @@ -2060,14 +2190,15 @@ bool cConnection::HandleServerSpawnMob(void) bool cConnection::HandleServerSpawnNamedEntity(void) { - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID); - HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, EntityName); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ); - HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Yaw); - HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Pitch); - HANDLE_SERVER_PACKET_READ(ReadBEShort, short, CurrentItem); + HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, EntityID); + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, EntityUUID); + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, EntityName); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ); + HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Yaw); + HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Pitch); + HANDLE_SERVER_PACKET_READ(ReadBEShort, short, CurrentItem); AString Metadata; if (!ParseMetadata(m_ServerBuffer, Metadata)) { @@ -2076,8 +2207,9 @@ bool cConnection::HandleServerSpawnNamedEntity(void) AString HexDump; CreateHexDump(HexDump, Metadata.data(), Metadata.size(), 32); Log("Received a PACKET_SPAWN_NAMED_ENTITY from the server:"); - Log(" EntityID = %d (0x%x)", EntityID, EntityID); - Log(" Name = %s", EntityName.c_str()); + Log(" EntityID = %u (0x%x)", EntityID, EntityID); + Log(" UUID = \"%s\"", EntityUUID.c_str()); + Log(" Name = \"%s\"", EntityName.c_str()); Log(" Pos = %s", PrintableAbsIntTriplet(PosX, PosY, PosZ).c_str()); Log(" Rotation = <yaw %d, pitch %d>", Yaw, Pitch); Log(" CurrentItem = %d", CurrentItem); @@ -2100,7 +2232,9 @@ bool cConnection::HandleServerSpawnObjectVehicle(void) m_ServerBuffer.ResetRead(); m_ServerBuffer.ReadAll(Buffer); m_ServerBuffer.ResetRead(); - m_ServerBuffer.SkipRead(1); + UInt32 PacketLen, PacketType; + m_ServerBuffer.ReadVarInt(PacketLen); + m_ServerBuffer.ReadVarInt(PacketType); if (Buffer.size() > 128) { // Only log up to 128 bytes @@ -2109,14 +2243,14 @@ bool cConnection::HandleServerSpawnObjectVehicle(void) DataLog(Buffer.data(), Buffer.size(), "Buffer while parsing the PACKET_SPAWN_OBJECT_VEHICLE packet (%d bytes):", Buffer.size()); #endif // _DEBUG - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID); - HANDLE_SERVER_PACKET_READ(ReadChar, char, ObjType); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ); - HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Yaw); - HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Pitch); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, DataIndicator); + HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, EntityID); + HANDLE_SERVER_PACKET_READ(ReadByte, Byte, ObjType); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ); + HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Pitch); + HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Yaw); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, DataIndicator); AString ExtraData; short VelocityX, VelocityY, VelocityZ; if (DataIndicator != 0) @@ -2149,7 +2283,7 @@ bool cConnection::HandleServerSpawnObjectVehicle(void) */ } Log("Received a PACKET_SPAWN_OBJECT_VEHICLE from the server:"); - Log(" EntityID = %d (0x%x)", EntityID, EntityID); + Log(" EntityID = %u (0x%x)", EntityID, EntityID); Log(" ObjType = %d (0x%x)", ObjType, ObjType); Log(" Pos = %s", PrintableAbsIntTriplet(PosX, PosY, PosZ).c_str()); Log(" Rotation = <yaw %d, pitch %d>", Yaw, Pitch); @@ -2169,14 +2303,14 @@ bool cConnection::HandleServerSpawnObjectVehicle(void) bool cConnection::HandleServerSpawnPainting(void) { - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID); - HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, ImageName); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, Direction); + HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, EntityID); + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, ImageName); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, Direction); Log("Received a PACKET_SPAWN_PAINTING from the server:"); - Log(" EntityID = %d", EntityID); + Log(" EntityID = %u", EntityID); Log(" ImageName = \"%s\"", ImageName.c_str()); Log(" Pos = %s", PrintableAbsIntTriplet(PosX, PosY, PosZ).c_str()); Log(" Direction = %d", Direction); @@ -2215,9 +2349,65 @@ bool cConnection::HandleServerSpawnPickup(void) +bool cConnection::HandleServerStatistics(void) +{ + HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, NumEntries); + for (UInt32 i = 0; i < NumEntries; i++) + { + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, StatName); + HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, StatValue); + } + COPY_TO_CLIENT(); + return true; +} + + + + +bool cConnection::HandleServerStatusPing(void) +{ + HANDLE_SERVER_PACKET_READ(ReadBEInt64, Int64, Time); + Log("Received server's ping response:"); + Log(" Time = %lld", Time); + COPY_TO_CLIENT(); + return true; +} + + + + + +bool cConnection::HandleServerStatusResponse(void) +{ + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Response); + Log("Received server's status response:"); + Log(" Response: %s", Response.c_str()); + + // Modify the response to show that it's being proto-proxied: + size_t idx = Response.find("\"description\":\""); + if (idx != AString::npos) + { + Response.assign(Response.substr(0, idx + 15) + "ProtoProxy: " + Response.substr(idx + 15)); + } + cByteBuffer Packet(1000); + Packet.WriteVarInt(0); // Packet type - status response + Packet.WriteVarUTF8String(Response); + AString Pkt; + Packet.ReadAll(Pkt); + cByteBuffer ToClient(1000); + ToClient.WriteVarUTF8String(Pkt); + CLIENTSEND(ToClient); + return true; +} + + + + + bool cConnection::HandleServerTabCompletion(void) { - HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, Results); + HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, NumResults); + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Results); Log("Received a PACKET_TAB_COMPLETION from the server, results given:"); // Parse the zero-terminated list of results: @@ -2275,10 +2465,10 @@ bool cConnection::HandleServerUpdateSign(void) HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockX); HANDLE_SERVER_PACKET_READ(ReadBEShort, short, BlockY); HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockZ); - HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, Line1); - HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, Line2); - HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, Line3); - HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, Line4); + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Line1); + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Line2); + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Line3); + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Line4); Log("Received a PACKET_UPDATE_SIGN from the server:"); Log(" Block = {%d, %d, %d}", BlockX, BlockY, BlockZ); Log(" Lines = \"%s\", \"%s\", \"%s\", \"%s\"", Line1.c_str(), Line2.c_str(), Line3.c_str(), Line4.c_str()); @@ -2305,7 +2495,24 @@ bool cConnection::HandleServerUpdateTileEntity(void) Log("Received a PACKET_UPDATE_TILE_ENTITY from the server:"); Log(" Block = {%d, %d, %d}", BlockX, BlockY, BlockZ); Log(" Action = %d", Action); - DataLog(Data.data(), Data.size(), " Data (%d bytes)", Data.size()); + DataLog(Data.data(), Data.size(), " Data (%u bytes)", Data.size()); + COPY_TO_CLIENT(); + return true; +} + + + + + +bool cConnection::HandleServerUseBed(void) +{ + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BedX); + HANDLE_SERVER_PACKET_READ(ReadByte, Byte, BedY); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BedZ); + Log("Received a use bed packet from the server:"); + Log(" EntityID = %d", EntityID); + Log(" Bed = {%d, %d, %d}", BedX, BedY, BedZ); COPY_TO_CLIENT(); return true; } @@ -2357,14 +2564,14 @@ bool cConnection::HandleServerWindowOpen(void) { HANDLE_SERVER_PACKET_READ(ReadChar, char, WindowID); HANDLE_SERVER_PACKET_READ(ReadChar, char, WindowType); - HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, Title); + HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Title); HANDLE_SERVER_PACKET_READ(ReadByte, Byte, NumSlots); HANDLE_SERVER_PACKET_READ(ReadByte, Byte, UseProvidedTitle); - int HorseInt = 0; + int HorseEntityID = 0; if (WindowType == 11) // Horse / Donkey / Mule { HANDLE_SERVER_PACKET_READ(ReadBEInt, int, intHorseInt); - HorseInt = intHorseInt; + HorseEntityID = intHorseInt; } Log("Received a PACKET_WINDOW_OPEN from the server:"); Log(" WindowID = %d", WindowID); @@ -2373,8 +2580,25 @@ bool cConnection::HandleServerWindowOpen(void) Log(" NumSlots = %d", NumSlots); if (WindowType == 11) { - Log(" HorseInt = %d (0x%08x)", HorseInt, HorseInt); + Log(" HorseEntityID = %d (0x%08x)", HorseEntityID, HorseEntityID); + } + COPY_TO_CLIENT(); + return true; +} + + + + + +bool cConnection::HandleServerUnknownPacket(UInt32 a_PacketType, UInt32 a_PacketLen, UInt32 a_PacketReadSoFar) +{ + AString Data; + ASSERT(a_PacketLen >= a_PacketReadSoFar); + if (!m_ServerBuffer.ReadString(Data, a_PacketLen - a_PacketReadSoFar)) + { + return false; } + DataLog(Data.data(), Data.size(), "****************** Unknown packet 0x%x from the server; relaying and ignoring", a_PacketType); COPY_TO_CLIENT(); return true; } @@ -2457,15 +2681,20 @@ bool cConnection::ParseMetadata(cByteBuffer & a_Buffer, AString & a_Metadata) case 1: Length = 2; break; // short case 2: Length = 4; break; // int case 3: Length = 4; break; // float - case 4: // string16 + case 4: // UTF-8 string with VarInt length { - short Len = 0; - if (!a_Buffer.ReadBEShort(Len)) + UInt32 Len; + int rs = a_Buffer.GetReadableSpace(); + if (!a_Buffer.ReadVarInt(Len)) { return false; } - short NetLen = htons(Len); - a_Metadata.append((char *)&NetLen, 2); + rs = rs - a_Buffer.GetReadableSpace(); + cByteBuffer LenBuf(8); + LenBuf.WriteVarInt(Len); + AString VarLen; + LenBuf.ReadAll(VarLen); + a_Metadata.append(VarLen); Length = Len; break; } @@ -2484,6 +2713,7 @@ bool cConnection::ParseMetadata(cByteBuffer & a_Buffer, AString & a_Metadata) break; } case 6: Length = 12; break; // 3 * int + case 7: default: { ASSERT(!"Unknown metadata type"); @@ -2544,11 +2774,21 @@ void cConnection::LogMetadata(const AString & a_Metadata, size_t a_IndentCount) pos += 4; break; } - case 4: // string16 + case 4: // UTF-8 string with VarInt length { - short Length = (a_Metadata[pos + 1] << 8) | a_Metadata[pos + 2]; - Log("%sstring[%d] = \"%*s\"", Indent.c_str(), Index, Length, a_Metadata.c_str() + pos + 3); - pos += Length + 2; + cByteBuffer bb(10); + int RestLen = (int)a_Metadata.size() - pos - 1; + if (RestLen > 8) + { + RestLen = 8; + } + bb.Write(a_Metadata.data() + pos + 1, RestLen); + UInt32 Length; + int rs = bb.GetReadableSpace(); + bb.ReadVarInt(Length); + rs = rs - bb.GetReadableSpace(); + Log("%sstring[%d] = \"%*s\"", Indent.c_str(), Index, Length, a_Metadata.c_str() + pos + rs + 1); + pos += Length + rs + 2; break; } case 5: @@ -2622,68 +2862,14 @@ void cConnection::SendEncryptionKeyResponse(const AString & a_ServerPublicKey, c // Send the packet to the server: Log("Sending PACKET_ENCRYPTION_KEY_RESPONSE to the SERVER"); cByteBuffer ToServer(1024); - ToServer.WriteByte(PACKET_ENCRYPTION_KEY_RESPONSE); + ToServer.WriteByte(0x01); // To server: Encryption key response ToServer.WriteBEShort(EncryptedLength); ToServer.WriteBuf(EncryptedSecret, EncryptedLength); ToServer.WriteBEShort(EncryptedLength); ToServer.WriteBuf(EncryptedNonce, EncryptedLength); SERVERSEND(ToServer); - m_ServerState = csWaitingForEncryption; -} - - - - - -void cConnection::StartClientEncryption(const AString & a_EncKey, const AString & a_EncNonce) -{ - // Decrypt EncNonce using privkey - RSAES<PKCS1v15>::Decryptor rsaDecryptor(m_Server.GetPrivateKey()); - time_t CurTime = time(NULL); - RandomPool rng; - rng.Put((const byte *)&CurTime, sizeof(CurTime)); - byte DecryptedNonce[MAX_ENC_LEN]; - DecodingResult res = rsaDecryptor.Decrypt(rng, (const byte *)a_EncNonce.data(), a_EncNonce.size(), DecryptedNonce); - if (!res.isValidCoding || (res.messageLength != 4)) - { - Log("Client: Bad nonce length"); - return; - } - if (ntohl(*((int *)DecryptedNonce)) != m_Nonce) - { - Log("Bad nonce value"); - return; - } - - // Decrypt the symmetric encryption key using privkey: - byte SharedSecret[MAX_ENC_LEN]; - res = rsaDecryptor.Decrypt(rng, (const byte *)a_EncKey.data(), a_EncKey.size(), SharedSecret); - if (!res.isValidCoding || (res.messageLength != 16)) - { - Log("Bad key length"); - return; - } - - // Send encryption key response: - cByteBuffer ToClient(6); - ToClient.WriteByte((char)0xfc); - ToClient.WriteBEShort(0); - ToClient.WriteBEShort(0); - CLIENTSEND(ToClient); - - // Start the encryption: - m_ClientEncryptor.SetKey(SharedSecret, 16, MakeParameters(Name::IV(), ConstByteArrayParameter(SharedSecret, 16))(Name::FeedbackSize(), 1)); - m_ClientDecryptor.SetKey(SharedSecret, 16, MakeParameters(Name::IV(), ConstByteArrayParameter(SharedSecret, 16))(Name::FeedbackSize(), 1)); - Log("Client connection is now encrypted"); - m_ClientState = csEncryptedUnderstood; - - // Send the queued data: - DataLog(m_ClientEncryptionBuffer.data(), m_ClientEncryptionBuffer.size(), "Sending the queued data to client (%u bytes):", m_ClientEncryptionBuffer.size()); - CLIENTENCRYPTSEND(m_ClientEncryptionBuffer.data(), m_ClientEncryptionBuffer.size()); - m_ClientEncryptionBuffer.clear(); - - // Handle all postponed server data - DecodeServersPackets(NULL, 0); + m_ServerState = csEncryptedUnderstood; + m_IsServerEncrypted = true; } diff --git a/Tools/ProtoProxy/Connection.h b/Tools/ProtoProxy/Connection.h index c30a28727..abb8b6cd0 100644 --- a/Tools/ProtoProxy/Connection.h +++ b/Tools/ProtoProxy/Connection.h @@ -10,7 +10,7 @@ #pragma once #include "ByteBuffer.h" -#include "../../source/OSSupport/Timer.h" +#include "OSSupport/Timer.h" @@ -71,14 +71,27 @@ protected: Decryptor m_ServerDecryptor; Encryptor m_ServerEncryptor; - Decryptor m_ClientDecryptor; - Encryptor m_ClientEncryptor; - - AString m_ClientEncryptionBuffer; // Buffer for the data to be sent to the client once encryption is established AString m_ServerEncryptionBuffer; // Buffer for the data to be sent to the server once encryption is established /// Set to true when PACKET_PING is received from the client; will cause special parsing for server kick bool m_HasClientPinged; + + /* + The protocol states can be one of: + -1: no initial handshake received yet + 1: status + 2: login + 3: game + */ + /// State the to-server protocol is in (as defined by the initial handshake / login), -1 if no initial handshake received yet + int m_ServerProtocolState; + + /// State the to-client protocol is in (as defined by the initial handshake / login), -1 if no initial handshake received yet + int m_ClientProtocolState; + + /// True if the server connection has provided encryption keys + bool m_IsServerEncrypted; + bool ConnectToServer(void); @@ -109,7 +122,18 @@ protected: /// Decodes packets coming from the server, sends appropriate counterparts to the client; returns false if the connection is to be dropped bool DecodeServersPackets(const char * a_Data, int a_Size); - // Packet handling, client-side: + // Packet handling, client-side, initial: + bool HandleClientHandshake(void); + + // Packet handling, client-side, status: + bool HandleClientStatusPing(void); + bool HandleClientStatusRequest(void); + + // Packet handling, client-side, login: + bool HandleClientLoginEncryptionKeyResponse(void); + bool HandleClientLoginStart(void); + + // Packet handling, client-side, game: bool HandleClientAnimation(void); bool HandleClientBlockDig(void); bool HandleClientBlockPlace(void); @@ -117,9 +141,7 @@ protected: bool HandleClientClientStatuses(void); bool HandleClientCreativeInventoryAction(void); bool HandleClientDisconnect(void); - bool HandleClientEncryptionKeyResponse(void); bool HandleClientEntityAction(void); - bool HandleClientHandshake(void); bool HandleClientKeepAlive(void); bool HandleClientLocaleAndView(void); bool HandleClientPing(void); @@ -135,8 +157,15 @@ protected: bool HandleClientUseEntity(void); bool HandleClientWindowClick(void); bool HandleClientWindowClose(void); + + bool HandleClientUnknownPacket(UInt32 a_PacketType, UInt32 a_PacketLen, UInt32 a_PacketReadSoFar); + + // Packet handling, server-side, login: + bool HandleServerLoginDisconnect(void); + bool HandleServerLoginEncryptionKeyRequest(void); + bool HandleServerLoginSuccess(void); - // Packet handling, server-side: + // Packet handling, server-side, game: bool HandleServerAttachEntity(void); bool HandleServerBlockAction(void); bool HandleServerBlockChange(void); @@ -145,8 +174,6 @@ protected: bool HandleServerCollectPickup(void); bool HandleServerCompass(void); bool HandleServerDestroyEntities(void); - bool HandleServerEncryptionKeyRequest(void); - bool HandleServerEncryptionKeyResponse(void); bool HandleServerEntity(void); bool HandleServerEntityEquipment(void); bool HandleServerEntityHeadLook(void); @@ -158,7 +185,9 @@ protected: bool HandleServerEntityStatus(void); bool HandleServerEntityTeleport(void); bool HandleServerEntityVelocity(void); + bool HandleServerExplosion(void); bool HandleServerIncrementStatistic(void); + bool HandleServerJoinGame(void); bool HandleServerKeepAlive(void); bool HandleServerKick(void); bool HandleServerLogin(void); @@ -171,24 +200,32 @@ protected: bool HandleServerPlayerListItem(void); bool HandleServerPlayerPositionLook(void); bool HandleServerPluginMessage(void); + bool HandleServerRespawn(void); bool HandleServerSetExperience(void); bool HandleServerSetSlot(void); bool HandleServerSlotSelect(void); bool HandleServerSoundEffect(void); + bool HandleServerSpawnExperienceOrbs(void); bool HandleServerSpawnMob(void); bool HandleServerSpawnNamedEntity(void); bool HandleServerSpawnObjectVehicle(void); bool HandleServerSpawnPainting(void); bool HandleServerSpawnPickup(void); + bool HandleServerStatistics(void); + bool HandleServerStatusPing(void); + bool HandleServerStatusResponse(void); bool HandleServerTabCompletion(void); bool HandleServerTimeUpdate(void); bool HandleServerUpdateHealth(void); bool HandleServerUpdateSign(void); bool HandleServerUpdateTileEntity(void); + bool HandleServerUseBed(void); bool HandleServerWindowClose(void); bool HandleServerWindowContents(void); bool HandleServerWindowOpen(void); + bool HandleServerUnknownPacket(UInt32 a_PacketType, UInt32 a_PacketLen, UInt32 a_PacketReadSoFar); + /// Parses the slot data in a_Buffer into item description; returns true if successful, false if not enough data bool ParseSlot(cByteBuffer & a_Buffer, AString & a_ItemDesc); diff --git a/Tools/ProtoProxy/Globals.h b/Tools/ProtoProxy/Globals.h index 3b154b866..8424aca81 100644 --- a/Tools/ProtoProxy/Globals.h +++ b/Tools/ProtoProxy/Globals.h @@ -70,6 +70,10 @@ typedef long long Int64; typedef int Int32; typedef short Int16; +typedef unsigned long long UInt64; +typedef unsigned int UInt32; +typedef unsigned short UInt16; + diff --git a/Tools/ProtoProxy/ProtoProxy.vcproj b/Tools/ProtoProxy/ProtoProxy.vcproj index 926bbe586..0b3c77bc5 100644 --- a/Tools/ProtoProxy/ProtoProxy.vcproj +++ b/Tools/ProtoProxy/ProtoProxy.vcproj @@ -41,7 +41,7 @@ <Tool Name="VCCLCompilerTool" Optimization="0" - AdditionalIncludeDirectories="../..;../../source" + AdditionalIncludeDirectories="../../lib;../../src" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS" MinimalRebuild="true" BasicRuntimeChecks="3" @@ -117,7 +117,7 @@ Name="VCCLCompilerTool" Optimization="2" EnableIntrinsicFunctions="true" - AdditionalIncludeDirectories="../..;../../source" + AdditionalIncludeDirectories="../../lib;../../src" PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS" RuntimeLibrary="0" EnableFunctionLevelLinking="true" @@ -225,45 +225,49 @@ Name="shared" > <File - RelativePath="..\..\source\ByteBuffer.cpp" + RelativePath="..\..\src\ByteBuffer.cpp" > </File> <File - RelativePath="..\..\source\ByteBuffer.h" + RelativePath="..\..\src\ByteBuffer.h" > </File> <File - RelativePath="..\..\source\OSSupport\CriticalSection.cpp" + RelativePath="..\..\src\StringUtils.cpp" > </File> <File - RelativePath="..\..\source\OSSupport\CriticalSection.h" + RelativePath="..\..\src\StringUtils.h" > </File> - <File - RelativePath="..\..\source\OSSupport\IsThread.cpp" - > - </File> - <File - RelativePath="..\..\source\OSSupport\IsThread.h" - > - </File> - <File - RelativePath="..\..\source\StringUtils.cpp" - > - </File> - <File - RelativePath="..\..\source\StringUtils.h" + <Filter + Name="OSSupport" > - </File> - <File - RelativePath="..\..\source\OSSupport\Timer.cpp" - > - </File> - <File - RelativePath="..\..\source\OSSupport\Timer.h" - > - </File> + <File + RelativePath="..\..\src\OSSupport\CriticalSection.cpp" + > + </File> + <File + RelativePath="..\..\src\OSSupport\CriticalSection.h" + > + </File> + <File + RelativePath="..\..\src\OSSupport\IsThread.cpp" + > + </File> + <File + RelativePath="..\..\src\OSSupport\IsThread.h" + > + </File> + <File + RelativePath="..\..\src\OSSupport\Timer.cpp" + > + </File> + <File + RelativePath="..\..\src\OSSupport\Timer.h" + > + </File> + </Filter> </Filter> <File RelativePath=".\ProtoProxy.txt" diff --git a/Tools/RCONClient/.gitignore b/Tools/RCONClient/.gitignore new file mode 100644 index 000000000..e124797c5 --- /dev/null +++ b/Tools/RCONClient/.gitignore @@ -0,0 +1,7 @@ +Debug/ +logs/ +Release/ +*.suo +*.user +*.ncb +*.sdf diff --git a/Tools/RCONClient/Globals.cpp b/Tools/RCONClient/Globals.cpp new file mode 100644 index 000000000..13c6ae709 --- /dev/null +++ b/Tools/RCONClient/Globals.cpp @@ -0,0 +1,10 @@ + +// Globals.cpp + +// This file is used for precompiled header generation in MSVC environments + +#include "Globals.h" + + + + diff --git a/Tools/RCONClient/Globals.h b/Tools/RCONClient/Globals.h new file mode 100644 index 000000000..a3a2f2846 --- /dev/null +++ b/Tools/RCONClient/Globals.h @@ -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 ) ) + + + + + diff --git a/Tools/RCONClient/RCONClient.cpp b/Tools/RCONClient/RCONClient.cpp new file mode 100644 index 000000000..288363a66 --- /dev/null +++ b/Tools/RCONClient/RCONClient.cpp @@ -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; +} + + + + diff --git a/Tools/RCONClient/RCONClient.sln b/Tools/RCONClient/RCONClient.sln new file mode 100644 index 000000000..0a8596e43 --- /dev/null +++ b/Tools/RCONClient/RCONClient.sln @@ -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 diff --git a/Tools/RCONClient/RCONClient.vcproj b/Tools/RCONClient/RCONClient.vcproj new file mode 100644 index 000000000..82b79d2a3 --- /dev/null +++ b/Tools/RCONClient/RCONClient.vcproj @@ -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="../../src" + 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="../../src" + 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="..\..\src\ByteBuffer.cpp" + > + </File> + <File + RelativePath="..\..\src\ByteBuffer.h" + > + </File> + <File + RelativePath="..\..\src\Log.cpp" + > + </File> + <File + RelativePath="..\..\src\Log.h" + > + </File> + <File + RelativePath="..\..\src\MCLogger.cpp" + > + </File> + <File + RelativePath="..\..\src\MCLogger.h" + > + </File> + <File + RelativePath="..\..\src\StringUtils.cpp" + > + </File> + <File + RelativePath="..\..\src\StringUtils.h" + > + </File> + <Filter + Name="OSSupport" + > + <File + RelativePath="..\..\src\OSSupport\CriticalSection.cpp" + > + </File> + <File + RelativePath="..\..\src\OSSupport\CriticalSection.h" + > + </File> + <File + RelativePath="..\..\src\OSSupport\File.cpp" + > + </File> + <File + RelativePath="..\..\src\OSSupport\File.h" + > + </File> + <File + RelativePath="..\..\src\OSSupport\IsThread.cpp" + > + </File> + <File + RelativePath="..\..\src\OSSupport\IsThread.h" + > + </File> + <File + RelativePath="..\..\src\OSSupport\Socket.cpp" + > + </File> + <File + RelativePath="..\..\src\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> |