Fix style of Tools
This commit is contained in:
parent
aff140365d
commit
1926181cb7
@ -31,7 +31,7 @@ int main(int argc, char * argv[])
|
||||
LOG("\nNo method number present, aborting.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
AString WorldFolder;
|
||||
if (argc > 2)
|
||||
{
|
||||
@ -41,7 +41,7 @@ int main(int argc, char * argv[])
|
||||
{
|
||||
WorldFolder = "." + cFile::PathSeparator;
|
||||
}
|
||||
|
||||
|
||||
cCallbackFactory * Factory = NULL;
|
||||
switch (atol(argv[1]))
|
||||
{
|
||||
@ -59,14 +59,10 @@ int main(int argc, char * argv[])
|
||||
}
|
||||
cProcessor Processor;
|
||||
Processor.ProcessWorld(WorldFolder, *Factory);
|
||||
|
||||
|
||||
LOG("Processing finished");
|
||||
|
||||
|
||||
delete Factory;
|
||||
|
||||
|
||||
LOG("Done");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -123,7 +123,7 @@ void cBiomeMap::StartNewRegion(int a_RegionX, int a_RegionZ)
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cBiomeMapFactory:
|
||||
|
||||
cBiomeMapFactory::~cBiomeMapFactory()
|
||||
@ -135,7 +135,3 @@ cBiomeMapFactory::~cBiomeMapFactory()
|
||||
}
|
||||
// TODO: Join all the files into one giant image file
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -20,8 +20,8 @@ class cBiomeMap :
|
||||
{
|
||||
public:
|
||||
cBiomeMap(void);
|
||||
|
||||
/// Saves the last region that it was processing
|
||||
|
||||
/** Saves the last region that it was processing */
|
||||
void Finish(void);
|
||||
|
||||
protected:
|
||||
@ -33,7 +33,7 @@ protected:
|
||||
int m_CurrentRegionZ;
|
||||
bool m_IsCurrentRegionValid;
|
||||
char m_Biomes[16 * 32 * 16 * 32]; // Biome map of the entire current region [x + 16 * 32 * z]
|
||||
|
||||
|
||||
// cCallback overrides:
|
||||
virtual bool OnNewChunk(int a_ChunkX, int a_ChunkZ) override;
|
||||
virtual bool OnHeader(int a_FileOffset, unsigned char a_NumSectors, int a_Timestamp) override { return false; }
|
||||
@ -43,7 +43,7 @@ protected:
|
||||
virtual bool OnLastUpdate(Int64 a_LastUpdate) override { return false; }
|
||||
virtual bool OnTerrainPopulated(bool a_Populated) override { return false; } // We don't care about "populated", the biomes are the same
|
||||
virtual bool OnBiomes(const unsigned char * a_BiomeData) override;
|
||||
|
||||
|
||||
void StartNewRegion(int a_RegionX, int a_RegionZ);
|
||||
} ;
|
||||
|
||||
@ -56,14 +56,10 @@ class cBiomeMapFactory :
|
||||
{
|
||||
public:
|
||||
virtual ~cBiomeMapFactory();
|
||||
|
||||
|
||||
virtual cCallback * CreateNewCallback(void) override
|
||||
{
|
||||
return new cBiomeMap;
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -37,39 +37,39 @@ public:
|
||||
CALLBACK_CONTINUE = false,
|
||||
CALLBACK_ABORT = true,
|
||||
} ;
|
||||
|
||||
|
||||
virtual ~cCallback() {} // Force a virtual destructor in each descendant
|
||||
|
||||
/// Called when a new region file is about to be opened; by default allow the region
|
||||
/** Called when a new region file is about to be opened; by default allow the region */
|
||||
virtual bool OnNewRegion(int a_RegionX, int a_RegionZ) { return CALLBACK_CONTINUE; }
|
||||
|
||||
/// Called to inform the stats module of the chunk coords for newly processing chunk
|
||||
|
||||
/** Called to inform the stats module of the chunk coords for newly processing chunk */
|
||||
virtual bool OnNewChunk(int a_ChunkX, int a_ChunkZ) = 0;
|
||||
|
||||
/// Called to inform about the chunk's data offset in the file (chunk mini-header), the number of sectors it uses and the timestamp field value
|
||||
|
||||
/** Called to inform about the chunk's data offset in the file (chunk mini-header), the number of sectors it uses and the timestamp field value */
|
||||
virtual bool OnHeader(int a_FileOffset, unsigned char a_NumSectors, int a_Timestamp) { return CALLBACK_ABORT; }
|
||||
|
||||
/// Called to inform of the compressed chunk data size and position in the file (offset from file start to the actual data)
|
||||
|
||||
/** Called to inform of the compressed chunk data size and position in the file (offset from file start to the actual data) */
|
||||
virtual bool OnCompressedDataSizePos(int a_CompressedDataSize, int a_DataOffset, char a_CompressionMethod) { return CALLBACK_ABORT; }
|
||||
|
||||
/// Just in case you wanted to process the NBT yourself ;)
|
||||
|
||||
/** Just in case you wanted to process the NBT yourself ;) */
|
||||
virtual bool OnDecompressedData(const char * a_DecompressedNBT, int a_DataSize) { return CALLBACK_ABORT; }
|
||||
|
||||
/// The chunk's NBT should specify chunk coords, these are sent here:
|
||||
|
||||
/** The chunk's NBT should specify chunk coords, these are sent here: */
|
||||
virtual bool OnRealCoords(int a_ChunkX, int a_ChunkZ) { return CALLBACK_ABORT; }
|
||||
|
||||
/// The chunk contains a LastUpdate value specifying the last tick in which it was saved.
|
||||
|
||||
/** The chunk contains a LastUpdate value specifying the last tick in which it was saved. */
|
||||
virtual bool OnLastUpdate(Int64 a_LastUpdate) { return CALLBACK_ABORT; }
|
||||
|
||||
|
||||
virtual bool OnTerrainPopulated(bool a_Populated) { return CALLBACK_ABORT; }
|
||||
|
||||
|
||||
virtual bool OnBiomes(const unsigned char * a_BiomeData) { return CALLBACK_ABORT; }
|
||||
|
||||
|
||||
/** Called when a heightmap for the chunk is read from the file.
|
||||
Note that the heightmap is given in big-endian ints, so if you want it, you need to ntohl() it first!
|
||||
*/
|
||||
virtual bool OnHeightMap(const int * a_HeightMapBE) { return CALLBACK_ABORT; }
|
||||
|
||||
|
||||
/** If there is data for the section, this callback is called; otherwise OnEmptySection() is called instead.
|
||||
All OnSection() callbacks are called first, and only then all the remaining sections are reported in OnEmptySection().
|
||||
*/
|
||||
@ -81,16 +81,16 @@ public:
|
||||
const NIBBLETYPE * a_BlockLight,
|
||||
const NIBBLETYPE * a_BlockSkyLight
|
||||
) { return CALLBACK_ABORT; }
|
||||
|
||||
/** If there is no data for a section, this callback is called; otherwise OnSection() is called instead.
|
||||
|
||||
/** If there is no data for a section, this callback is called; otherwise OnSection() is called instead.
|
||||
OnEmptySection() callbacks are called after all OnSection() callbacks.
|
||||
*/
|
||||
virtual bool OnEmptySection(unsigned char a_Y) { return CALLBACK_CONTINUE; }
|
||||
|
||||
|
||||
/** Called after all sections have been processed via either OnSection() or OnEmptySection().
|
||||
*/
|
||||
virtual bool OnSectionsFinished(void) { return CALLBACK_ABORT; }
|
||||
|
||||
|
||||
/** Called for each entity in the chunk.
|
||||
Common parameters are parsed from the NBT.
|
||||
The callback may parse any other param from the a_NBT and a_NBTTag parameters.
|
||||
@ -108,7 +108,7 @@ public:
|
||||
cParsedNBT & a_NBT,
|
||||
int a_NBTTag
|
||||
) { return CALLBACK_ABORT; }
|
||||
|
||||
|
||||
/** Called for each tile entity in the chunk.
|
||||
Common parameters are parsed from the NBT.
|
||||
The callback may parse any other param from the a_NBT and a_NBTTag parameters.
|
||||
@ -121,14 +121,14 @@ public:
|
||||
int a_NBTTag
|
||||
) { return CALLBACK_ABORT; }
|
||||
|
||||
/// Called for each tile tick in the chunk
|
||||
/** Called for each tile tick in the chunk */
|
||||
virtual bool OnTileTick(
|
||||
int a_BlockType,
|
||||
int a_TicksLeft,
|
||||
int a_PosX, int a_PosY, int a_PosZ
|
||||
) { return CALLBACK_ABORT; }
|
||||
|
||||
/// Called after the entire region file has been processed. No more callbacks for this region will be called. No processing by default
|
||||
|
||||
/** Called after the entire region file has been processed. No more callbacks for this region will be called. No processing by default */
|
||||
virtual void OnRegionFinished(int a_RegionX, int a_RegionZ) {}
|
||||
} ;
|
||||
|
||||
@ -153,11 +153,11 @@ public:
|
||||
delete *itr;
|
||||
}
|
||||
}
|
||||
|
||||
/// Descendants override this method to return the correct callback type
|
||||
|
||||
/** Descendants override this method to return the correct callback type */
|
||||
virtual cCallback * CreateNewCallback(void) = 0;
|
||||
|
||||
/// cProcessor uses this method to request a new callback
|
||||
|
||||
/** cProcessor uses this method to request a new callback */
|
||||
cCallback * GetNewCallback(void)
|
||||
{
|
||||
cCallback * Callback = CreateNewCallback();
|
||||
@ -167,11 +167,7 @@ public:
|
||||
}
|
||||
return Callback;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
cCallbacks m_Callbacks;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -50,10 +50,10 @@ bool cChunkExtract::OnCompressedDataSizePos(int a_CompressedDataSize, int a_Data
|
||||
LOG("Cannot open zchunk file \"%s\" for writing. Chunk [%d, %d] skipped.", ChunkPath.c_str(), mCurChunkX, mCurChunkZ);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Copy data from mAnvilFile to ChunkFile:
|
||||
mAnvilFile.Seek(a_DataOffset);
|
||||
for (int BytesToCopy = a_CompressedDataSize; BytesToCopy > 0; )
|
||||
for (int BytesToCopy = a_CompressedDataSize; BytesToCopy > 0;)
|
||||
{
|
||||
char Buffer[64000];
|
||||
int NumBytes = std::min(BytesToCopy, (int)sizeof(Buffer));
|
||||
@ -101,4 +101,4 @@ void cChunkExtract::OpenAnvilFile(int a_AnvilX, int a_AnvilZ)
|
||||
}
|
||||
mCurAnvilX = a_AnvilX;
|
||||
mCurAnvilZ = a_AnvilZ;
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ class cChunkExtract :
|
||||
{
|
||||
public:
|
||||
cChunkExtract(const AString & iWorldFolder);
|
||||
|
||||
|
||||
protected:
|
||||
AString mWorldFolder;
|
||||
cFile mAnvilFile;
|
||||
@ -28,10 +28,10 @@ protected:
|
||||
int mCurAnvilZ; // Z-coord of mAnvilFile, -"-
|
||||
int mCurChunkX; // X-coord of the chunk being processed
|
||||
int mCurChunkZ; // Z-coord of the chunk being processed
|
||||
|
||||
/// Opens new anvil file into mAnvilFile, sets mCurAnvilX and mCurAnvilZ
|
||||
|
||||
/** Opens new anvil file into mAnvilFile, sets mCurAnvilX and mCurAnvilZ */
|
||||
void OpenAnvilFile(int a_AnvilX, int a_AnvilZ);
|
||||
|
||||
|
||||
// cCallback overrides:
|
||||
virtual bool OnNewChunk(int a_ChunkX, int a_ChunkZ) override;
|
||||
virtual bool OnHeader(int a_FileOffset, unsigned char a_NumSectors, int a_Timestamp) override { return false; }
|
||||
@ -51,7 +51,7 @@ public:
|
||||
mWorldFolder(iWorldFolder)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual cCallback * CreateNewCallback(void) override
|
||||
{
|
||||
return new cChunkExtract(mWorldFolder);
|
||||
@ -60,7 +60,3 @@ public:
|
||||
protected:
|
||||
AString mWorldFolder;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -12,35 +12,35 @@
|
||||
#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 _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
#define OBSOLETE __declspec(deprecated)
|
||||
|
||||
|
||||
// No alignment needed in MSVC
|
||||
#define ALIGN_8
|
||||
#define ALIGN_16
|
||||
|
||||
|
||||
#define FORMATSTRING(formatIndex, va_argsIndex)
|
||||
|
||||
// MSVC has its own custom version of zu format
|
||||
#define SIZE_T_FMT "%Iu"
|
||||
#define SIZE_T_FMT_PRECISION(x) "%" #x "Iu"
|
||||
#define SIZE_T_FMT_HEX "%Ix"
|
||||
|
||||
|
||||
#define NORETURN __declspec(noreturn)
|
||||
|
||||
#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)))
|
||||
@ -54,19 +54,19 @@
|
||||
#define SIZE_T_FMT "%zu"
|
||||
#define SIZE_T_FMT_PRECISION(x) "%" #x "zu"
|
||||
#define SIZE_T_FMT_HEX "%zx"
|
||||
|
||||
|
||||
#define NORETURN __attribute((__noreturn__))
|
||||
|
||||
#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
|
||||
|
||||
@ -114,11 +114,11 @@ typedef unsigned short UInt16;
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <winsock2.h>
|
||||
|
||||
|
||||
// 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
|
||||
@ -193,35 +193,35 @@ typedef unsigned short UInt16;
|
||||
|
||||
// Common definitions:
|
||||
|
||||
#define LOG(x,...) printf(x "\n", __VA_ARGS__)
|
||||
#define LOG(x, ...) printf(x "\n", __VA_ARGS__)
|
||||
#define LOGERROR LOG
|
||||
#define LOGWARNING LOG
|
||||
#define LOGINFO LOG
|
||||
#define LOGWARN LOG
|
||||
|
||||
/// Evaluates to the number of elements in an array (compile-time!)
|
||||
/** 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)" )
|
||||
/** Allows arithmetic expressions like "32 KiB" (but consider using parenthesis around it, "(32 KiB)") */
|
||||
#define KiB * 1024
|
||||
|
||||
/// Allows arithmetic expressions like "32 MiB" (but consider using parenthesis around it, "(32 MiB)" )
|
||||
/** Allows arithmetic expressions like "32 MiB" (but consider using parenthesis around it, "(32 MiB)") */
|
||||
#define MiB * 1024 * 1024
|
||||
|
||||
/// Faster than (int)floorf((float)x / (float)div)
|
||||
#define FAST_FLOOR_DIV( x, div ) ( (x) < 0 ? (((int)x / div) - 1) : ((int)x / div) )
|
||||
/** Faster than (int)floorf((float)x / (float)div) */
|
||||
#define FAST_FLOOR_DIV(x, div) ((x) < 0 ? (((int)x / div) - 1) : ((int)x / div))
|
||||
|
||||
#define TOLUA_TEMPLATE_BIND(...)
|
||||
|
||||
// Own version of assert() that writes failed assertions to the log for review
|
||||
#ifdef _DEBUG
|
||||
#define ASSERT( x ) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), assert(0), 0 ) )
|
||||
#define ASSERT(x) (!!(x) || (LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__), assert(0), 0))
|
||||
#else
|
||||
#define ASSERT(x) ((void)0)
|
||||
#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 ) )
|
||||
#define VERIFY(x) (!!(x) || (LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__), exit(1), 0))
|
||||
|
||||
typedef unsigned char Byte;
|
||||
|
||||
@ -229,11 +229,11 @@ typedef unsigned char Byte;
|
||||
|
||||
|
||||
|
||||
/// A generic interface used mainly in ForEach() functions
|
||||
/** A generic interface used mainly in ForEach() functions */
|
||||
template <typename Type> class cItemCallback
|
||||
{
|
||||
public:
|
||||
/// Called for each item in the internal list; return true to stop the loop, or false to continue enumerating
|
||||
/** Called for each item in the internal list; return true to stop the loop, or false to continue enumerating */
|
||||
virtual bool Item(Type * a_Type) = 0;
|
||||
} ;
|
||||
|
||||
@ -255,8 +255,3 @@ T Clamp(T a_Value, T a_Min, T a_Max)
|
||||
// Common headers (part 2, with macros):
|
||||
#include "../../src/ChunkDef.h"
|
||||
#include "../../src/BlockID.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -55,12 +55,12 @@ bool cHeightBiomeMap::OnNewChunk(int a_ChunkX, int a_ChunkZ)
|
||||
m_CurrentChunkZ = a_ChunkZ;
|
||||
m_CurrentChunkRelX = m_CurrentChunkX - m_CurrentRegionX * 32;
|
||||
m_CurrentChunkRelZ = m_CurrentChunkZ - m_CurrentRegionZ * 32;
|
||||
|
||||
|
||||
ASSERT((m_CurrentChunkRelX >= 0) && (m_CurrentChunkRelX < 32));
|
||||
ASSERT((m_CurrentChunkRelZ >= 0) && (m_CurrentChunkRelZ < 32));
|
||||
|
||||
|
||||
memset(m_BlockTypes, 0, sizeof(m_BlockTypes));
|
||||
|
||||
|
||||
return CALLBACK_CONTINUE;
|
||||
}
|
||||
|
||||
@ -72,7 +72,7 @@ bool cHeightBiomeMap::OnNewChunk(int a_ChunkX, int a_ChunkZ)
|
||||
bool cHeightBiomeMap::OnBiomes(const unsigned char * a_BiomeData)
|
||||
{
|
||||
memcpy(m_ChunkBiomes, a_BiomeData, sizeof(m_ChunkBiomes));
|
||||
|
||||
|
||||
return CALLBACK_CONTINUE;
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ bool cHeightBiomeMap::OnHeightMap(const int * a_HeightMapBE)
|
||||
{
|
||||
m_ChunkHeight[i] = ntohl(a_HeightMapBE[i]);
|
||||
} // for i - m_ChunkHeight
|
||||
|
||||
|
||||
return CALLBACK_CONTINUE;
|
||||
}
|
||||
|
||||
@ -157,12 +157,12 @@ bool cHeightBiomeMap::OnSectionsFinished(void)
|
||||
break; // for y
|
||||
}
|
||||
} // for y
|
||||
|
||||
|
||||
// Set the color based on the biome and height:
|
||||
char Biome = m_ChunkBiomes[16 * z + x];
|
||||
PixelLine[x] = ShadeColor(BiomePalette[Biome], Height);
|
||||
} // for x
|
||||
|
||||
|
||||
// Set the pixelline into the image:
|
||||
SetPixelURow(m_CurrentChunkRelX * 16, m_CurrentChunkRelZ * 16 + z, 16, PixelLine);
|
||||
} // for z
|
||||
@ -173,7 +173,7 @@ bool cHeightBiomeMap::OnSectionsFinished(void)
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cHeightBiomeMapFactory:
|
||||
|
||||
cHeightBiomeMapFactory::~cHeightBiomeMapFactory()
|
||||
@ -203,7 +203,7 @@ cHeightBiomeMapFactory::~cHeightBiomeMapFactory()
|
||||
MaxRegionZ = cb->m_MaxRegionZ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If the size is small enough, write an HTML file referencing all the images in a table:
|
||||
if ((MaxRegionX >= MinRegionX) && (MaxRegionZ >= MinRegionZ) && (MaxRegionX - MinRegionX < 100) && (MaxRegionZ - MinRegionZ < 100))
|
||||
{
|
||||
@ -224,7 +224,3 @@ cHeightBiomeMapFactory::~cHeightBiomeMapFactory()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -19,23 +19,26 @@ class cHeightBiomeMap :
|
||||
public cImageComposingCallback
|
||||
{
|
||||
typedef cImageComposingCallback super;
|
||||
|
||||
|
||||
public:
|
||||
// Minima and maxima for the regions processed through this callback
|
||||
int m_MinRegionX, m_MaxRegionX;
|
||||
int m_MinRegionZ, m_MaxRegionZ;
|
||||
|
||||
|
||||
cHeightBiomeMap(void);
|
||||
|
||||
|
||||
protected:
|
||||
int m_CurrentChunkX; // Absolute chunk coords
|
||||
int m_CurrentChunkZ;
|
||||
int m_CurrentChunkRelX; // Chunk offset from the start of the region
|
||||
int m_CurrentChunkRelZ;
|
||||
|
||||
char m_ChunkBiomes[16 * 16]; ///< Biome-map for the current chunk
|
||||
int m_ChunkHeight[16 * 16]; ///< Height-map for the current chunk
|
||||
BLOCKTYPE m_BlockTypes [16 * 16 * 256]; ///< Block data for the current chunk (between OnSection() and OnSectionsFinished() )
|
||||
|
||||
/** Biome-map for the current chunk */
|
||||
char m_ChunkBiomes[16 * 16];
|
||||
/** Height-map for the current chunk */
|
||||
int m_ChunkHeight[16 * 16];
|
||||
/** Block data for the current chunk (between OnSection() and OnSectionsFinished()) */
|
||||
BLOCKTYPE m_BlockTypes [16 * 16 * 256];
|
||||
|
||||
// cCallback overrides:
|
||||
virtual bool OnNewRegion(int a_RegionX, int a_RegionZ) override;
|
||||
@ -57,7 +60,7 @@ protected:
|
||||
const NIBBLETYPE * a_BlockSkyLight
|
||||
) override;
|
||||
virtual bool OnSectionsFinished(void) override;
|
||||
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@ -69,13 +72,9 @@ class cHeightBiomeMapFactory :
|
||||
{
|
||||
public:
|
||||
virtual ~cHeightBiomeMapFactory();
|
||||
|
||||
|
||||
virtual cCallback * CreateNewCallback(void) override
|
||||
{
|
||||
return new cHeightBiomeMap;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
// HeightMap.cpp
|
||||
|
||||
// Implements the cHeightMap class representing a cCallback descendant that draws a B&W map of heights for the world
|
||||
// Implements the cHeightMap class representing a cCallback descendant that draws a B & W map of heights for the world
|
||||
|
||||
#include "Globals.h"
|
||||
#include "HeightMap.h"
|
||||
@ -253,7 +253,7 @@ bool cHeightMap::IsGround(BLOCKTYPE a_BlockType)
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cHeightMapFactory:
|
||||
|
||||
cHeightMapFactory::~cHeightMapFactory()
|
||||
@ -265,7 +265,3 @@ cHeightMapFactory::~cHeightMapFactory()
|
||||
}
|
||||
// TODO: Join all the files into one giant image file
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
// HeightMap.h
|
||||
|
||||
// Declares the cHeightMap class representing a cCallback descendant that draws a B&W map of heights for the world
|
||||
// Declares the cHeightMap class representing a cCallback descendant that draws a B & W map of heights for the world
|
||||
|
||||
|
||||
|
||||
@ -20,9 +20,9 @@ class cHeightMap :
|
||||
{
|
||||
public:
|
||||
cHeightMap(void);
|
||||
|
||||
|
||||
void Finish(void);
|
||||
|
||||
|
||||
static bool IsGround(BLOCKTYPE a_BlockType);
|
||||
|
||||
protected:
|
||||
@ -33,9 +33,11 @@ protected:
|
||||
int m_CurrentRegionX;
|
||||
int m_CurrentRegionZ;
|
||||
bool m_IsCurrentRegionValid;
|
||||
int m_Height[16 * 32 * 16 * 32]; ///< Height-map of the entire current region [x + 16 * 32 * z]
|
||||
BLOCKTYPE m_BlockTypes[16 * 16 * 256]; ///< Block data of the currently processed chunk (between OnSection() and OnSectionsFinished() )
|
||||
|
||||
/** Height-map of the entire current region [x + 16 * 32 * z] */
|
||||
int m_Height[16 * 32 * 16 * 32];
|
||||
/** Block data of the currently processed chunk (between OnSection() and OnSectionsFinished()) */
|
||||
BLOCKTYPE m_BlockTypes[16 * 16 * 256];
|
||||
|
||||
// cCallback overrides:
|
||||
virtual bool OnNewChunk(int a_ChunkX, int a_ChunkZ) override;
|
||||
virtual bool OnHeader(int a_FileOffset, unsigned char a_NumSectors, int a_Timestamp) override { return false; }
|
||||
@ -68,14 +70,10 @@ class cHeightMapFactory :
|
||||
{
|
||||
public:
|
||||
virtual ~cHeightMapFactory();
|
||||
|
||||
|
||||
virtual cCallback * CreateNewCallback(void) override
|
||||
{
|
||||
return new cHeightMap;
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -35,11 +35,11 @@ bool cImageComposingCallback::OnNewRegion(int a_RegionX, int a_RegionZ)
|
||||
{
|
||||
ASSERT(m_CurrentRegionX == INVALID_REGION_COORD);
|
||||
ASSERT(m_CurrentRegionZ == INVALID_REGION_COORD); // Has any previous region been finished properly?
|
||||
|
||||
|
||||
m_CurrentRegionX = a_RegionX;
|
||||
m_CurrentRegionZ = a_RegionZ;
|
||||
OnEraseImage();
|
||||
|
||||
|
||||
return CALLBACK_CONTINUE;
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ void cImageComposingCallback::OnRegionFinished(int a_RegionX, int a_RegionZ)
|
||||
ASSERT(m_CurrentRegionZ != INVALID_REGION_COORD); // Has a region been started properly?
|
||||
ASSERT(m_CurrentRegionX == a_RegionX);
|
||||
ASSERT(m_CurrentRegionZ == a_RegionZ); // Is it the same region that has been started?
|
||||
|
||||
|
||||
AString FileName = GetFileName(a_RegionX, a_RegionZ);
|
||||
if (!FileName.empty())
|
||||
{
|
||||
@ -61,7 +61,7 @@ void cImageComposingCallback::OnRegionFinished(int a_RegionX, int a_RegionZ)
|
||||
SaveImage(FileName);
|
||||
OnAfterImageSaved(a_RegionX, a_RegionZ, FileName);
|
||||
}
|
||||
|
||||
|
||||
m_CurrentRegionX = INVALID_REGION_COORD;
|
||||
m_CurrentRegionZ = INVALID_REGION_COORD;
|
||||
}
|
||||
@ -122,7 +122,7 @@ void cImageComposingCallback::SetPixel(int a_RelU, int a_RelV, int a_Color)
|
||||
{
|
||||
ASSERT((a_RelU >= 0) && (a_RelU < IMAGE_WIDTH));
|
||||
ASSERT((a_RelV >= 0) && (a_RelV < IMAGE_HEIGHT));
|
||||
|
||||
|
||||
m_ImageData[a_RelU + IMAGE_WIDTH * a_RelV] = a_Color;
|
||||
}
|
||||
|
||||
@ -137,7 +137,7 @@ int cImageComposingCallback::GetPixel(int a_RelU, int a_RelV)
|
||||
// Outside the image data
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return m_ImageData[a_RelU + IMAGE_WIDTH * a_RelV];
|
||||
}
|
||||
|
||||
@ -213,7 +213,3 @@ void cImageComposingCallback::SaveImage(const AString & a_FileName)
|
||||
f.Write(BMPHeader, sizeof(BMPHeader));
|
||||
f.Write(m_ImageData, PIXEL_COUNT * 4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -32,74 +32,70 @@ public:
|
||||
IMAGE_HEIGHT = 32 * 16,
|
||||
PIXEL_COUNT = IMAGE_WIDTH * IMAGE_HEIGHT, ///< Total pixel count of the image data
|
||||
} ;
|
||||
|
||||
|
||||
cImageComposingCallback(const AString & a_FileNamePrefix);
|
||||
virtual ~cImageComposingCallback();
|
||||
|
||||
// cCallback overrides:
|
||||
virtual bool OnNewRegion(int a_RegionX, int a_RegionZ) override;
|
||||
virtual void OnRegionFinished(int a_RegionX, int a_RegionZ) override;
|
||||
|
||||
|
||||
// New introduced overridable functions:
|
||||
|
||||
/// Called when a file is about to be saved, to generate the filename
|
||||
|
||||
/** Called when a file is about to be saved, to generate the filename */
|
||||
virtual AString GetFileName(int a_RegionX, int a_RegionZ);
|
||||
|
||||
/// Called before the file is saved
|
||||
|
||||
/** Called before the file is saved */
|
||||
virtual void OnBeforeImageSaved(int a_RegionX, int a_RegionZ, const AString & a_FileName) {}
|
||||
|
||||
/// Called after the image is saved to a file
|
||||
|
||||
/** Called after the image is saved to a file */
|
||||
virtual void OnAfterImageSaved(int a_RegionX, int a_RegionZ, const AString & a_FileName) {}
|
||||
|
||||
/// Called when a new region is beginning, to erase the image data
|
||||
|
||||
/** Called when a new region is beginning, to erase the image data */
|
||||
virtual void OnEraseImage(void);
|
||||
|
||||
|
||||
// Functions for manipulating the image:
|
||||
|
||||
/// Erases the entire image with the specified color
|
||||
|
||||
/** Erases the entire image with the specified color */
|
||||
void EraseImage(int a_Color);
|
||||
|
||||
/// Erases the specified chunk's portion of the image with the specified color. Note that chunk coords are relative to the current region
|
||||
|
||||
/** Erases the specified chunk's portion of the image with the specified color. Note that chunk coords are relative to the current region */
|
||||
void EraseChunk(int a_Color, int a_RelChunkX, int a_RelChunkZ);
|
||||
|
||||
/// Returns the current region X coord
|
||||
|
||||
/** Returns the current region X coord */
|
||||
int GetCurrentRegionX(void) const { return m_CurrentRegionX; }
|
||||
|
||||
/// Returns the current region Z coord
|
||||
|
||||
/** Returns the current region Z coord */
|
||||
int GetCurrentRegionZ(void) const { return m_CurrentRegionZ; }
|
||||
|
||||
/// Sets the pixel at the specified UV coords to the specified color
|
||||
|
||||
/** Sets the pixel at the specified UV coords to the specified color */
|
||||
void SetPixel(int a_RelU, int a_RelV, int a_Color);
|
||||
|
||||
/// Returns the color of the pixel at the specified UV coords; -1 if outside
|
||||
|
||||
/** Returns the color of the pixel at the specified UV coords; -1 if outside */
|
||||
int GetPixel(int a_RelU, int a_RelV);
|
||||
|
||||
/// Sets a row of pixels. a_Pixels is expected to be a_CountU pixels wide. a_RelUStart + a_CountU is assumed less than image width
|
||||
|
||||
/** Sets a row of pixels. a_Pixels is expected to be a_CountU pixels wide. a_RelUStart + a_CountU is assumed less than image width */
|
||||
void SetPixelURow(int a_RelUStart, int a_RelV, int a_CountU, int * a_Pixels);
|
||||
|
||||
|
||||
/** "Shades" the given color based on the shade amount given
|
||||
Shade amount 0 .. 63 shades the color from black to a_Color.
|
||||
Shade amount 64 .. 127 shades the color from a_Color to white.
|
||||
All other shade amounts have undefined results.
|
||||
*/
|
||||
static int ShadeColor(int a_Color, int a_Shade);
|
||||
|
||||
/// Mixes the two colors in the specified ratio; a_Ratio is between 0 and 256, 0 returning a_Src
|
||||
|
||||
/** Mixes the two colors in the specified ratio; a_Ratio is between 0 and 256, 0 returning a_Src */
|
||||
static int MixColor(int a_Src, int a_Dest, int a_Ratio);
|
||||
|
||||
|
||||
protected:
|
||||
/// Prefix for the filenames, when generated by the default GetFileName() function
|
||||
/** Prefix for the filenames, when generated by the default GetFileName() function */
|
||||
AString m_FileNamePrefix;
|
||||
|
||||
/// Coords of the currently processed region
|
||||
|
||||
/** Coords of the currently processed region */
|
||||
int m_CurrentRegionX, m_CurrentRegionZ;
|
||||
|
||||
/// Raw image data; 1 MiB worth of data, therefore unsuitable for stack allocation. [u + IMAGE_WIDTH * v]
|
||||
|
||||
/** Raw image data; 1 MiB worth of data, therefore unsuitable for stack allocation. [u + IMAGE_WIDTH * v] */
|
||||
int * m_ImageData;
|
||||
|
||||
|
||||
void SaveImage(const AString & a_FileName);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -20,7 +20,7 @@ const int CHUNK_INFLATE_MAX = 1 MiB;
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cProcessor::cThread:
|
||||
|
||||
cProcessor::cThread::cThread(cCallback & a_Callback, cProcessor & a_ParentProcessor) :
|
||||
@ -48,9 +48,9 @@ void cProcessor::cThread::WaitForStart(void)
|
||||
void cProcessor::cThread::Execute(void)
|
||||
{
|
||||
LOG("Started a new thread: %p, ID %d", this, cIsThread::GetCurrentID());
|
||||
|
||||
|
||||
m_HasStarted.Set();
|
||||
|
||||
|
||||
for (;;)
|
||||
{
|
||||
AString FileName = m_ParentProcessor.GetOneFileName();
|
||||
@ -61,7 +61,7 @@ void cProcessor::cThread::Execute(void)
|
||||
}
|
||||
ProcessFile(FileName);
|
||||
} // for-ever
|
||||
|
||||
|
||||
LOG("Thread %p (ID %d) terminated", this, cIsThread::GetCurrentID());
|
||||
}
|
||||
|
||||
@ -72,7 +72,7 @@ void cProcessor::cThread::Execute(void)
|
||||
void cProcessor::cThread::ProcessFile(const AString & a_FileName)
|
||||
{
|
||||
LOG("Processing file \"%s\"", a_FileName.c_str());
|
||||
|
||||
|
||||
size_t idx = a_FileName.rfind("r.");
|
||||
if (idx == AString::npos)
|
||||
{
|
||||
@ -91,14 +91,14 @@ void cProcessor::cThread::ProcessFile(const AString & a_FileName)
|
||||
// Callback doesn't want the region file processed
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
cFile f;
|
||||
if (!f.Open(a_FileName, cFile::fmRead))
|
||||
{
|
||||
LOG("Cannot open file \"%s\", skipping file.", a_FileName.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
AString FileContents;
|
||||
f.ReadRestOfFile(FileContents);
|
||||
if (FileContents.size() < sizeof(8 KiB))
|
||||
@ -106,9 +106,9 @@ void cProcessor::cThread::ProcessFile(const AString & a_FileName)
|
||||
LOG("Cannot read header in file \"%s\", skipping file.", a_FileName.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ProcessFileData(FileContents.data(), FileContents.size(), RegionX * 32, RegionZ * 32);
|
||||
|
||||
|
||||
m_Callback.OnRegionFinished(RegionX, RegionZ);
|
||||
}
|
||||
|
||||
@ -124,16 +124,16 @@ void cProcessor::cThread::ProcessFileData(const char * a_FileData, size_t a_Size
|
||||
{
|
||||
Header[i] = ntohl(HeaderPtr[i]);
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
unsigned Location = Header[i];
|
||||
unsigned Timestamp = Header[i + 1024];
|
||||
if (
|
||||
((Location == 0) && (Timestamp == 0)) || // Official docs' "not present"
|
||||
(Location >> 8 < 2) || // Logical - no chunk can start inside the header
|
||||
((Location & 0xff) == 0) || // Logical - no chunk can be zero bytes
|
||||
((Location >> 8) * 4096 > a_Size) // Logical - no chunk can start at beyond the file end
|
||||
((Location == 0) && (Timestamp == 0)) || // Official docs' "not present"
|
||||
(Location >> 8 < 2) || // Logical - no chunk can start inside the header
|
||||
((Location & 0xff) == 0) || // Logical - no chunk can be zero bytes
|
||||
((Location >> 8) * 4096 > a_Size) // Logical - no chunk can start at beyond the file end
|
||||
)
|
||||
{
|
||||
// Chunk not present in the file
|
||||
@ -159,11 +159,11 @@ void cProcessor::cThread::ProcessChunk(const char * a_FileData, int a_ChunkX, in
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const char * ChunkStart = a_FileData + a_SectorStart * 4096;
|
||||
int ByteSize = ntohl(*(int *)ChunkStart);
|
||||
char CompressionMethod = ChunkStart[4];
|
||||
|
||||
|
||||
if (m_Callback.OnCompressedDataSizePos(ByteSize, a_SectorStart * 4096 + 5, CompressionMethod))
|
||||
{
|
||||
return;
|
||||
@ -195,7 +195,7 @@ void cProcessor::cThread::ProcessCompressedChunkData(int a_ChunkX, int a_ChunkZ,
|
||||
LOG("Decompression failed, skipping chunk [%d, %d]", a_ChunkX, a_ChunkZ);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (m_Callback.OnDecompressedData(Decompressed, strm.total_out))
|
||||
{
|
||||
return;
|
||||
@ -208,7 +208,7 @@ void cProcessor::cThread::ProcessCompressedChunkData(int a_ChunkX, int a_ChunkZ,
|
||||
LOG("NBT Parsing failed, skipping chunk [%d, %d]", a_ChunkX, a_ChunkZ);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ProcessParsedChunkData(a_ChunkX, a_ChunkZ, NBT);
|
||||
}
|
||||
|
||||
@ -235,7 +235,7 @@ void cProcessor::cThread::ProcessParsedChunkData(int a_ChunkX, int a_ChunkZ, cPa
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int LastUpdateTag = a_NBT.FindChildByName(LevelTag, "LastUpdate");
|
||||
if (LastUpdateTag > 0)
|
||||
{
|
||||
@ -244,14 +244,14 @@ void cProcessor::cThread::ProcessParsedChunkData(int a_ChunkX, int a_ChunkZ, cPa
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int TerrainPopulatedTag = a_NBT.FindChildByName(LevelTag, "TerrainPopulated");
|
||||
bool TerrainPopulated = (TerrainPopulatedTag < 0) ? false : (a_NBT.GetByte(TerrainPopulatedTag) != 0);
|
||||
if (m_Callback.OnTerrainPopulated(TerrainPopulated))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int BiomesTag = a_NBT.FindChildByName(LevelTag, "Biomes");
|
||||
if (BiomesTag > 0)
|
||||
{
|
||||
@ -260,7 +260,7 @@ void cProcessor::cThread::ProcessParsedChunkData(int a_ChunkX, int a_ChunkZ, cPa
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int HeightMapTag = a_NBT.FindChildByName(LevelTag, "HeightMap");
|
||||
if (HeightMapTag > 0)
|
||||
{
|
||||
@ -269,22 +269,22 @@ void cProcessor::cThread::ProcessParsedChunkData(int a_ChunkX, int a_ChunkZ, cPa
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ProcessChunkSections(a_ChunkX, a_ChunkZ, a_NBT, LevelTag))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (ProcessChunkEntities(a_ChunkX, a_ChunkZ, a_NBT, LevelTag))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (ProcessChunkTileEntities(a_ChunkX, a_ChunkZ, a_NBT, LevelTag))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (ProcessChunkTileTicks(a_ChunkX, a_ChunkZ, a_NBT, LevelTag))
|
||||
{
|
||||
return;
|
||||
@ -302,7 +302,7 @@ bool cProcessor::cThread::ProcessChunkSections(int a_ChunkX, int a_ChunkZ, cPars
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool SectionProcessed[16];
|
||||
memset(SectionProcessed, 0, sizeof(SectionProcessed));
|
||||
for (int Tag = a_NBT.GetFirstChild(Sections); Tag > 0; Tag = a_NBT.GetNextSibling(Tag))
|
||||
@ -313,12 +313,12 @@ bool cProcessor::cThread::ProcessChunkSections(int a_ChunkX, int a_ChunkZ, cPars
|
||||
int DataTag = a_NBT.FindChildByName(Tag, "Data");
|
||||
int BlockLightTag = a_NBT.FindChildByName(Tag, "BlockLightTag");
|
||||
int SkyLightTag = a_NBT.FindChildByName(Tag, "SkyLight");
|
||||
|
||||
|
||||
if ((YTag < 0) || (BlocksTag < 0) || (DataTag < 0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
unsigned char SectionY = a_NBT.GetByte(YTag);
|
||||
if (SectionY >= 16)
|
||||
{
|
||||
@ -338,7 +338,7 @@ bool cProcessor::cThread::ProcessChunkSections(int a_ChunkX, int a_ChunkZ, cPars
|
||||
}
|
||||
SectionProcessed[SectionY] = true;
|
||||
} // for Tag - Sections[]
|
||||
|
||||
|
||||
// Call the callback for empty sections:
|
||||
for (unsigned char y = 0; y < 16; y++)
|
||||
{
|
||||
@ -350,12 +350,12 @@ bool cProcessor::cThread::ProcessChunkSections(int a_ChunkX, int a_ChunkZ, cPars
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (m_Callback.OnSectionsFinished())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -370,7 +370,7 @@ bool cProcessor::cThread::ProcessChunkEntities(int a_ChunkX, int a_ChunkZ, cPars
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for (int EntityTag = a_NBT.GetFirstChild(EntitiesTag); EntityTag > 0; EntityTag = a_NBT.GetNextSibling(EntityTag))
|
||||
{
|
||||
int PosTag = a_NBT.FindChildByName(EntityTag, "Pos");
|
||||
@ -433,7 +433,7 @@ bool cProcessor::cThread::ProcessChunkTileEntities(int a_ChunkX, int a_ChunkZ, c
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for (int TileEntityTag = a_NBT.GetFirstChild(TileEntitiesTag); TileEntityTag > 0; TileEntityTag = a_NBT.GetNextSibling(TileEntityTag))
|
||||
{
|
||||
if (m_Callback.OnTileEntity(
|
||||
@ -461,7 +461,7 @@ bool cProcessor::cThread::ProcessChunkTileTicks(int a_ChunkX, int a_ChunkZ, cPar
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for (int TileTickTag = a_NBT.GetFirstChild(TileTicksTag); TileTickTag > 0; TileTickTag = a_NBT.GetNextSibling(TileTickTag))
|
||||
{
|
||||
int iTag = a_NBT.FindChildByName(TileTicksTag, "i");
|
||||
@ -491,7 +491,7 @@ bool cProcessor::cThread::ProcessChunkTileTicks(int a_ChunkX, int a_ChunkZ, cPar
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cProcessor:
|
||||
|
||||
cProcessor::cProcessor(void) :
|
||||
@ -514,24 +514,24 @@ cProcessor::~cProcessor()
|
||||
void cProcessor::ProcessWorld(const AString & a_WorldFolder, cCallbackFactory & a_CallbackFactory)
|
||||
{
|
||||
PopulateFileQueue(a_WorldFolder);
|
||||
|
||||
|
||||
if (m_FileQueue.empty())
|
||||
{
|
||||
LOG("No files to process, exitting.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Start as many threads as there are cores, plus one:
|
||||
// (One more thread can be in the file-read IO block while all other threads crunch the numbers)
|
||||
int NumThreads = GetNumCores() + 1;
|
||||
|
||||
|
||||
/*
|
||||
// Limit the number of threads in DEBUG mode to 1 for easier debugging
|
||||
#ifdef _DEBUG
|
||||
NumThreads = 1;
|
||||
#endif // _DEBUG
|
||||
//*/
|
||||
|
||||
|
||||
// Start all the threads:
|
||||
for (int i = 0; i < NumThreads; i++)
|
||||
{
|
||||
@ -589,7 +589,3 @@ AString cProcessor::GetOneFileName(void)
|
||||
m_FileQueue.pop_back();
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -27,20 +27,20 @@ class cProcessor
|
||||
public cIsThread
|
||||
{
|
||||
typedef cIsThread super;
|
||||
|
||||
|
||||
cCallback & m_Callback;
|
||||
cProcessor & m_ParentProcessor;
|
||||
cEvent m_HasStarted;
|
||||
|
||||
|
||||
// cIsThread override:
|
||||
virtual void Execute(void) override;
|
||||
|
||||
|
||||
void ProcessFile(const AString & a_FileName);
|
||||
void ProcessFileData(const char * a_FileData, size_t a_Size, int a_ChunkBaseX, int a_ChunkBaseZ);
|
||||
void ProcessChunk(const char * a_FileData, int a_ChunkX, int a_ChunkZ, unsigned a_SectorStart, unsigned a_SectorSize, unsigned a_TimeStamp);
|
||||
void ProcessCompressedChunkData(int a_ChunkX, int a_ChunkZ, const char * a_CompressedData, int a_CompressedSize);
|
||||
void ProcessParsedChunkData(int a_ChunkX, int a_ChunkZ, cParsedNBT & a_NBT);
|
||||
|
||||
|
||||
// The following processing parts return true if they were interrupted by the callback, causing the processing of current chunk to abort
|
||||
bool ProcessChunkSections(int a_ChunkX, int a_ChunkZ, cParsedNBT & a_NBT, int a_LevelTag);
|
||||
bool ProcessChunkEntities(int a_ChunkX, int a_ChunkZ, cParsedNBT & a_NBT, int a_LevelTag);
|
||||
@ -53,31 +53,27 @@ class cProcessor
|
||||
/** Waits until the thread starts processing the callback code. */
|
||||
void WaitForStart(void);
|
||||
} ;
|
||||
|
||||
|
||||
typedef std::vector<cThread *> cThreads;
|
||||
|
||||
|
||||
public:
|
||||
cProcessor(void);
|
||||
~cProcessor();
|
||||
|
||||
|
||||
void ProcessWorld(const AString & a_WorldFolder, cCallbackFactory & a_CallbackFactory);
|
||||
|
||||
|
||||
protected:
|
||||
bool m_IsShuttingDown; // If true, the threads should stop ASAP
|
||||
|
||||
|
||||
cCriticalSection m_CS;
|
||||
AStringList m_FileQueue;
|
||||
|
||||
|
||||
cThreads m_Threads;
|
||||
|
||||
|
||||
/** Populates m_FileQueue with Anvil files from the specified folder. */
|
||||
void PopulateFileQueue(const AString & a_WorldFolder);
|
||||
|
||||
|
||||
/** Returns one filename from m_FileQueue, and removes the name from the queue. */
|
||||
AString GetOneFileName(void);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cSpringStats::cStats
|
||||
|
||||
cSpringStats::cStats::cStats(void) :
|
||||
@ -41,7 +41,7 @@ void cSpringStats::cStats::Add(const cSpringStats::cStats & a_Other)
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cSpringStats:
|
||||
|
||||
cSpringStats::cSpringStats(void) :
|
||||
@ -99,7 +99,7 @@ bool cSpringStats::OnSectionsFinished(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Calc the spring stats:
|
||||
for (int y = 1; y < 255; y++)
|
||||
{
|
||||
@ -173,14 +173,14 @@ void cSpringStats::TestSpring(int a_RelX, int a_RelY, int a_RelZ, cSpringStats::
|
||||
}
|
||||
} // switch (BlockType)
|
||||
} // for i - Coords[]
|
||||
|
||||
|
||||
if (!HasFluidNextToIt)
|
||||
{
|
||||
// Surrounded by solids on all sides, this is probably not a spring,
|
||||
// but rather a bedrocked lake or something similar. Dont want.
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// No source blocks next to the specified block, so it is a spring. Add it to stats:
|
||||
a_Stats[a_RelY][((unsigned char *)m_Biomes)[a_RelX + 16 * a_RelZ]] += 1;
|
||||
}
|
||||
@ -189,7 +189,7 @@ void cSpringStats::TestSpring(int a_RelX, int a_RelY, int a_RelZ, cSpringStats::
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cSpringStatsFactory:
|
||||
|
||||
cSpringStatsFactory::~cSpringStatsFactory()
|
||||
@ -273,7 +273,3 @@ void cSpringStatsFactory::SaveStatistics(const cSpringStats::cStats::SpringStats
|
||||
f.Write(Line.c_str(), Line.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -22,31 +22,32 @@ public:
|
||||
class cStats
|
||||
{
|
||||
public:
|
||||
/// Per-height, per-biome frequencies of springs
|
||||
/** Per-height, per-biome frequencies of springs */
|
||||
typedef UInt64 SpringStats[256][256];
|
||||
|
||||
|
||||
SpringStats m_LavaSprings;
|
||||
SpringStats m_WaterSprings;
|
||||
|
||||
UInt64 m_TotalChunks; ///< Total number of chunks that are fully processed through this callback(OnSectionsFinished())
|
||||
|
||||
|
||||
/** Total number of chunks that are fully processed through this callback(OnSectionsFinished()) */
|
||||
UInt64 m_TotalChunks;
|
||||
|
||||
cStats(void);
|
||||
void Add(const cStats & a_Other);
|
||||
} ;
|
||||
|
||||
|
||||
cSpringStats(void);
|
||||
|
||||
|
||||
const cStats & GetStats(void) const { return m_Stats; }
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
BLOCKTYPE m_BlockTypes[16 * 16 * 256];
|
||||
NIBBLETYPE m_BlockMetas[16 * 16 * 256 / 2];
|
||||
char m_Biomes[16 * 16];
|
||||
bool m_AreBiomesValid;
|
||||
|
||||
|
||||
cStats m_Stats;
|
||||
|
||||
|
||||
// cCallback overrides:
|
||||
virtual bool OnNewChunk(int a_ChunkX, int a_ChunkZ) override;
|
||||
virtual bool OnHeader(int a_FileOffset, unsigned char a_NumSectors, int a_Timestamp) override { return false; }
|
||||
@ -67,7 +68,7 @@ protected:
|
||||
) override;
|
||||
virtual bool OnSectionsFinished(void) override;
|
||||
|
||||
/// Tests the specified block, if it appears to be a spring, it is added to a_Stats
|
||||
/** Tests the specified block, if it appears to be a spring, it is added to a_Stats */
|
||||
void TestSpring(int a_RelX, int a_RelY, int a_RelZ, cStats::SpringStats & a_Stats);
|
||||
} ;
|
||||
|
||||
@ -80,23 +81,19 @@ class cSpringStatsFactory :
|
||||
{
|
||||
public:
|
||||
virtual ~cSpringStatsFactory();
|
||||
|
||||
|
||||
virtual cCallback * CreateNewCallback(void) override
|
||||
{
|
||||
return new cSpringStats;
|
||||
}
|
||||
|
||||
cSpringStats::cStats m_CombinedStats;
|
||||
|
||||
|
||||
void JoinResults(void);
|
||||
|
||||
/// Saves total per-height data (summed through biomes) for both spring types to the file
|
||||
|
||||
/** Saves total per-height data (summed through biomes) for both spring types to the file */
|
||||
void SaveTotals(const AString & a_FileName);
|
||||
|
||||
/// Saves complete per-height, per-biome statistics for the springs to the file
|
||||
|
||||
/** Saves complete per-height, per-biome statistics for the springs to the file */
|
||||
void SaveStatistics(const cSpringStats::cStats::SpringStats & a_Stats, const AString & a_FileName);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cStatistics::cStats:
|
||||
|
||||
cStatistics::cStats::cStats(void) :
|
||||
@ -97,7 +97,7 @@ void cStatistics::cStats::UpdateCoordsRange(int a_ChunkX, int a_ChunkZ)
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cStatistics:
|
||||
|
||||
cStatistics::cStatistics(void)
|
||||
@ -153,7 +153,7 @@ bool cStatistics::OnSection
|
||||
// The current biome data is not valid, we don't have the means for sorting the BlockTypes into per-biome arrays
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
for (int y = 0; y < 16; y++)
|
||||
{
|
||||
int Height = (int)a_Y * 16 + y;
|
||||
@ -168,10 +168,10 @@ bool cStatistics::OnSection
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_Stats.m_BlockNumChunks += m_IsFirstSectionInChunk ? 1 : 0;
|
||||
m_IsFirstSectionInChunk = false;
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -187,7 +187,7 @@ bool cStatistics::OnEmptySection(unsigned char a_Y)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Add air to all columns:
|
||||
// Add air to all columns:
|
||||
for (int z = 0; z < 16; z++)
|
||||
{
|
||||
for (int x = 0; x < 16; x++)
|
||||
@ -196,10 +196,10 @@ bool cStatistics::OnEmptySection(unsigned char a_Y)
|
||||
m_Stats.m_BlockCounts[Biome][0] += 16; // 16 blocks in a column, all air
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_Stats.m_BlockNumChunks += m_IsFirstSectionInChunk ? 1 : 0;
|
||||
m_IsFirstSectionInChunk = false;
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -221,9 +221,9 @@ bool cStatistics::OnEntity(
|
||||
)
|
||||
{
|
||||
m_Stats.m_NumEntities += 1;
|
||||
|
||||
|
||||
// TODO
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -239,12 +239,12 @@ bool cStatistics::OnTileEntity(
|
||||
)
|
||||
{
|
||||
m_Stats.m_NumTileEntities += 1;
|
||||
|
||||
|
||||
if (a_EntityType == "MobSpawner")
|
||||
{
|
||||
OnSpawner(a_NBT, a_NBTTag);
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -280,7 +280,7 @@ void cStatistics::OnSpawner(cParsedNBT & a_NBT, int a_TileEntityTag)
|
||||
return;
|
||||
}
|
||||
m_Stats.m_SpawnerEntity[Ent] += 1;
|
||||
|
||||
|
||||
// Get the spawner pos:
|
||||
int PosYTag = a_NBT.FindChildByName(a_TileEntityTag, "y");
|
||||
if ((PosYTag < 0) || (a_NBT.GetType(PosYTag) != TAG_Int))
|
||||
@ -295,7 +295,7 @@ void cStatistics::OnSpawner(cParsedNBT & a_NBT, int a_TileEntityTag)
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cStatisticsFactory:
|
||||
|
||||
cStatisticsFactory::cStatisticsFactory(void) :
|
||||
@ -315,7 +315,7 @@ cStatisticsFactory::~cStatisticsFactory()
|
||||
JoinResults();
|
||||
LOG(" Total %llu chunks went through", m_CombinedStats.m_TotalChunks);
|
||||
LOG(" Biomes processed for %llu chunks", m_CombinedStats.m_BiomeNumChunks);
|
||||
|
||||
|
||||
// Check the number of blocks processed
|
||||
UInt64 TotalBlocks = 0;
|
||||
for (int i = 0; i <= 255; i++)
|
||||
@ -327,7 +327,7 @@ cStatisticsFactory::~cStatisticsFactory()
|
||||
}
|
||||
UInt64 ExpTotalBlocks = m_CombinedStats.m_BlockNumChunks * 16LL * 16LL * 256LL;
|
||||
LOG(" BlockIDs processed for %llu chunks, %llu blocks (exp %llu; %s)", m_CombinedStats.m_BlockNumChunks, TotalBlocks, ExpTotalBlocks, (TotalBlocks == ExpTotalBlocks) ? "match" : "failed");
|
||||
|
||||
|
||||
// Save statistics:
|
||||
LOG(" Saving statistics into files:");
|
||||
LOG(" Statistics.txt");
|
||||
@ -429,7 +429,7 @@ void cStatisticsFactory::SavePerHeightBlockTypes(void)
|
||||
LOG("Cannot write to file PerHeightBlockTypes.xls. Statistics not written.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Write header:
|
||||
f.Printf("Blocks 0 - 127:\nHeight");
|
||||
for (int i = 0; i < 128; i++)
|
||||
@ -437,7 +437,7 @@ void cStatisticsFactory::SavePerHeightBlockTypes(void)
|
||||
f.Printf("\t%s(%d)", GetBlockTypeString(i), i);
|
||||
}
|
||||
f.Printf("\n");
|
||||
|
||||
|
||||
// Write first half:
|
||||
for (int y = 0; y < 256; y++)
|
||||
{
|
||||
@ -457,7 +457,7 @@ void cStatisticsFactory::SavePerHeightBlockTypes(void)
|
||||
f.Printf("\t%s(%d)", GetBlockTypeString(i), i);
|
||||
}
|
||||
f.Printf("\n");
|
||||
|
||||
|
||||
// Write second half:
|
||||
for (int y = 0; y < 256; y++)
|
||||
{
|
||||
@ -483,10 +483,10 @@ void cStatisticsFactory::SaveBiomeBlockTypes(void)
|
||||
LOG("Cannot write to file BiomeBlockTypes.xls. Statistics not written.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
AString FileHeader("Biomes 0-127:\n");
|
||||
f.Write(FileHeader.c_str(), FileHeader.length());
|
||||
|
||||
|
||||
AString Header("BlockType\tBlockType");
|
||||
for (int Biome = 0; Biome <= 127; Biome++)
|
||||
{
|
||||
@ -502,7 +502,7 @@ void cStatisticsFactory::SaveBiomeBlockTypes(void)
|
||||
}
|
||||
Header.append("\n");
|
||||
f.Write(Header.c_str(), Header.length());
|
||||
|
||||
|
||||
for (int BlockType = 0; BlockType <= 255; BlockType++)
|
||||
{
|
||||
AString Line;
|
||||
@ -530,7 +530,7 @@ void cStatisticsFactory::SaveBiomeBlockTypes(void)
|
||||
}
|
||||
Header.append("\n");
|
||||
f.Write(Header.c_str(), Header.length());
|
||||
|
||||
|
||||
for (int BlockType = 0; BlockType <= 255; BlockType++)
|
||||
{
|
||||
AString Line;
|
||||
@ -557,7 +557,7 @@ void cStatisticsFactory::SaveStatistics(void)
|
||||
LOG("Cannot write to file Statistics.txt. Statistics not written.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int Elapsed = (clock() - m_BeginTick) / CLOCKS_PER_SEC;
|
||||
f.Printf("Time elapsed: %d seconds (%d hours, %d minutes and %d seconds)\n", Elapsed, Elapsed / 3600, (Elapsed / 60) % 60, Elapsed % 60);
|
||||
f.Printf("Total chunks processed: %llu\n", m_CombinedStats.m_TotalChunks);
|
||||
@ -589,7 +589,7 @@ void cStatisticsFactory::SaveSpawners(void)
|
||||
LOG("Cannot write to file Spawners.xls. Statistics not written.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
f.Printf("Entity type\tTotal count\tCount per chunk\n");
|
||||
for (int i = 0; i < entMax; i++)
|
||||
{
|
||||
@ -609,7 +609,7 @@ void cStatisticsFactory::SavePerHeightSpawners(void)
|
||||
LOG("Cannot write to file PerHeightSpawners.xls. Statistics not written.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Write header:
|
||||
f.Printf("Height\tTotal");
|
||||
for (int i = 0; i < entMax; i++)
|
||||
@ -634,7 +634,3 @@ void cStatisticsFactory::SavePerHeightSpawners(void)
|
||||
f.Printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -35,19 +35,19 @@ public:
|
||||
UInt64 m_PerHeightSpawners[256][entMax + 1]; // First dimension is the height, second dimension is spawned entity type
|
||||
int m_MinChunkX, m_MaxChunkX; // X coords range
|
||||
int m_MinChunkZ, m_MaxChunkZ; // Z coords range
|
||||
|
||||
|
||||
Int64 m;
|
||||
UInt64 m_SpawnerEntity[entMax + 1];
|
||||
|
||||
|
||||
cStats(void);
|
||||
void Add(const cStats & a_Stats);
|
||||
void UpdateCoordsRange(int a_ChunkX, int a_ChunkZ);
|
||||
} ;
|
||||
|
||||
|
||||
cStatistics(void);
|
||||
|
||||
|
||||
const cStats & GetStats(void) const { return m_Stats; }
|
||||
|
||||
|
||||
protected:
|
||||
cStats m_Stats;
|
||||
|
||||
@ -73,9 +73,9 @@ protected:
|
||||
const NIBBLETYPE * a_BlockLight,
|
||||
const NIBBLETYPE * a_BlockSkyLight
|
||||
) override;
|
||||
|
||||
|
||||
virtual bool OnEmptySection(unsigned char a_Y) override;
|
||||
|
||||
|
||||
virtual bool OnSectionsFinished(void) override { return false; } // continue processing
|
||||
|
||||
virtual bool OnEntity(
|
||||
@ -90,20 +90,20 @@ protected:
|
||||
cParsedNBT & a_NBT,
|
||||
int a_NBTTag
|
||||
) override;
|
||||
|
||||
|
||||
virtual bool OnTileEntity(
|
||||
const AString & a_EntityType,
|
||||
int a_PosX, int a_PosY, int a_PosZ,
|
||||
cParsedNBT & a_NBT,
|
||||
int a_NBTTag
|
||||
) override;
|
||||
|
||||
|
||||
virtual bool OnTileTick(
|
||||
int a_BlockType,
|
||||
int a_TicksLeft,
|
||||
int a_PosX, int a_PosY, int a_PosZ
|
||||
) override;
|
||||
|
||||
|
||||
void OnSpawner(cParsedNBT & a_NBT, int a_TileEntityTag);
|
||||
} ;
|
||||
|
||||
@ -117,16 +117,16 @@ class cStatisticsFactory :
|
||||
public:
|
||||
cStatisticsFactory(void);
|
||||
virtual ~cStatisticsFactory();
|
||||
|
||||
|
||||
virtual cCallback * CreateNewCallback(void)
|
||||
{
|
||||
return new cStatistics;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
// The results, combined, are stored here:
|
||||
cStatistics::cStats m_CombinedStats;
|
||||
|
||||
|
||||
clock_t m_BeginTick;
|
||||
|
||||
void JoinResults(void);
|
||||
@ -138,7 +138,3 @@ protected:
|
||||
void SaveSpawners(void);
|
||||
void SavePerHeightSpawners(void);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -238,7 +238,7 @@ const char * GetBlockTypeString(unsigned char a_BlockType)
|
||||
"Wooden Button",
|
||||
"Head",
|
||||
} ;
|
||||
|
||||
|
||||
return (a_BlockType < ARRAYCOUNT(BlockTypeNames)) ? BlockTypeNames[a_BlockType] : "";
|
||||
}
|
||||
|
||||
@ -287,7 +287,3 @@ int GetNumCores(void)
|
||||
} // while (Affinity > 0)
|
||||
return NumCores;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -50,7 +50,7 @@ void ShowHelp(const char * a_ProgramFullName)
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
new cMCLogger; // Create a new logger, it will assign itself as the main logger instance
|
||||
|
||||
|
||||
AString MCAFolder = ".";
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
@ -74,24 +74,20 @@ int main(int argc, char * argv[])
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cRegions Regions;
|
||||
|
||||
|
||||
/*
|
||||
// DEBUG: Read input from a file instead of stdin:
|
||||
std::fstream fs("test_in.txt");
|
||||
Regions.Read(fs);
|
||||
//*/
|
||||
|
||||
|
||||
Regions.Read(std::cin);
|
||||
|
||||
|
||||
cZapper Zapper(MCAFolder);
|
||||
Zapper.ZapRegions(Regions.GetAll());
|
||||
|
||||
|
||||
LOGINFO("Done");
|
||||
return 0;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cRegion:
|
||||
|
||||
cRegion::cRegion(void) :
|
||||
@ -66,7 +66,7 @@ bool cRegion::TouchesChunk(int a_ChunkX, int a_ChunkZ) const
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cRegions:
|
||||
|
||||
void cRegions::Read(std::istream & a_Stream)
|
||||
@ -75,7 +75,7 @@ void cRegions::Read(std::istream & a_Stream)
|
||||
{
|
||||
AString Line;
|
||||
std::getline(a_Stream, Line);
|
||||
|
||||
|
||||
// Process the line
|
||||
AStringVector Split = StringSplit(Line, " \t");
|
||||
AStringVector NonEmpty;
|
||||
@ -110,7 +110,7 @@ void cRegions::Read(std::istream & a_Stream)
|
||||
void cRegions::AddRegion(const AStringVector & a_Split)
|
||||
{
|
||||
ASSERT((a_Split.size() == 6) || (a_Split.size() == 7));
|
||||
|
||||
|
||||
int Coords[6];
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
@ -121,10 +121,10 @@ void cRegions::AddRegion(const AStringVector & a_Split)
|
||||
return;
|
||||
}
|
||||
} // for i - a_Split[]
|
||||
|
||||
|
||||
bool ShouldZapBlocks = true;
|
||||
bool ShouldZapEntities = false;
|
||||
|
||||
|
||||
if (a_Split.size() == 7)
|
||||
{
|
||||
AString Upper = a_Split[6];
|
||||
@ -148,7 +148,7 @@ void cRegions::AddRegion(const AStringVector & a_Split)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Swap coords, if needed:
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
@ -157,11 +157,7 @@ void cRegions::AddRegion(const AStringVector & a_Split)
|
||||
std::swap(Coords[2 * i], Coords[2 * i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Store the region
|
||||
m_Regions.push_back(cRegion(Coords[0], Coords[1], Coords[2], Coords[3], Coords[4], Coords[5], ShouldZapBlocks, ShouldZapEntities));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -20,13 +20,13 @@ struct cRegion
|
||||
int m_MinX, m_MaxX;
|
||||
int m_MinY, m_MaxY;
|
||||
int m_MinZ, m_MaxZ;
|
||||
|
||||
|
||||
bool m_ShouldZapBlocks;
|
||||
bool m_ShouldZapEntities;
|
||||
|
||||
|
||||
cRegion(void);
|
||||
cRegion(int a_MinX, int a_MaxX, int a_MinY, int a_MaxY, int a_MinZ, int a_MaxZ, bool a_ShouldZapBlocks, bool a_ShouldZapEntities);
|
||||
|
||||
|
||||
bool TouchesChunk(int a_ChunkX, int a_ChunkZ) const;
|
||||
} ;
|
||||
|
||||
@ -39,20 +39,16 @@ typedef std::vector<cRegion> cRegionVector;
|
||||
class cRegions
|
||||
{
|
||||
public:
|
||||
/// Reads the list of regions from the specified stream
|
||||
/** Reads the list of regions from the specified stream */
|
||||
void Read(std::istream & a_Stream);
|
||||
|
||||
/// Returns all regions in this container
|
||||
|
||||
/** Returns all regions in this container */
|
||||
const cRegionVector & GetAll(void) const { return m_Regions; }
|
||||
|
||||
|
||||
protected:
|
||||
cRegionVector m_Regions;
|
||||
|
||||
/// Adds a new region based on the contents of the split line. The split must already be the correct size
|
||||
|
||||
/** Adds a new region based on the contents of the split line. The split must already be the correct size */
|
||||
void AddRegion(const AStringVector & a_Split);
|
||||
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
|
||||
|
||||
/// The maximum size of an inflated chunk; raw chunk data is 192 KiB, allow 64 KiB more of entities
|
||||
/** The maximum size of an inflated chunk; raw chunk data is 192 KiB, allow 64 KiB more of entities */
|
||||
#define CHUNK_INFLATE_MAX 256 KiB
|
||||
|
||||
|
||||
@ -115,7 +115,7 @@ void cZapper::ZapRegionInMCAFile(const cRegion & a_Region, int a_MCAX, int a_MCA
|
||||
int ChunkZ = a_MCAZ * ChunksPerMCAZ + (i / ChunksPerMCAX);
|
||||
|
||||
LoadChunkData(fIn, HeaderIn[i], ChunkData, ChunkX, ChunkZ);
|
||||
|
||||
|
||||
if (a_Region.TouchesChunk(ChunkX, ChunkZ))
|
||||
{
|
||||
ZapRegionInRawChunkData(a_Region, ChunkData, ChunkX, ChunkZ);
|
||||
@ -218,14 +218,14 @@ void cZapper::ZapRegionInRawChunkData(const cRegion & a_Region, AString & a_Chun
|
||||
return;
|
||||
}
|
||||
ZapRegionInNBTChunk(a_Region, NBT, a_ChunkX, a_ChunkZ);
|
||||
|
||||
|
||||
cFastNBTWriter Writer;
|
||||
for (int ch = NBT.GetFirstChild(0); ch >= 0; ch = NBT.GetNextSibling(ch))
|
||||
{
|
||||
SerializeNBTTag(NBT, ch, Writer);
|
||||
}
|
||||
Writer.Finish();
|
||||
|
||||
|
||||
/*
|
||||
// DEBUG: Output dst to a file:
|
||||
cFile f2;
|
||||
@ -251,7 +251,7 @@ void cZapper::ZapRegionInNBTChunk(const cRegion & a_Region, cParsedNBT & a_NBT,
|
||||
fprintf(stderr, "Cannot find Level tag in chunk [%d, %d]'s NBT. Skipping chunk.", a_ChunkX, a_ChunkZ);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Create a copy of the region and limit it to the current chunk:
|
||||
int BlockX = a_ChunkX * 16;
|
||||
int BlockZ = a_ChunkZ * 16;
|
||||
@ -273,7 +273,7 @@ void cZapper::ZapRegionInNBTChunk(const cRegion & a_Region, cParsedNBT & a_NBT,
|
||||
}
|
||||
ZapRegionBlocksInNBT(Local, a_NBT, SectionsTag);
|
||||
}
|
||||
|
||||
|
||||
if (a_Region.m_ShouldZapEntities)
|
||||
{
|
||||
int EntitiesTag = a_NBT.FindChildByName(LevelTag, "Entities");
|
||||
@ -320,7 +320,7 @@ void cZapper::ZapRegionBlocksInNBT(const cRegion & a_Region, cParsedNBT & a_NBT,
|
||||
{
|
||||
ZapRegionInNBTSectionNibbles(a_Region, y, (unsigned char *)(a_NBT.GetData(BlockAddTag)));
|
||||
}
|
||||
} // for Child - Level/Sections/[]
|
||||
} // for Child - Level / Sections / []
|
||||
}
|
||||
|
||||
|
||||
@ -426,7 +426,7 @@ void cZapper::SerializeNBTTag(const cParsedNBT & a_NBT, int a_Tag, cFastNBTWrite
|
||||
a_Writer.EndCompound();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
{
|
||||
ASSERT(!"Unknown NBT tag");
|
||||
@ -434,7 +434,3 @@ void cZapper::SerializeNBTTag(const cParsedNBT & a_NBT, int a_Tag, cFastNBTWrite
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -27,54 +27,50 @@ class cZapper
|
||||
{
|
||||
public:
|
||||
cZapper(const AString & a_MCAFolder);
|
||||
|
||||
/// Zaps all the specified regions
|
||||
|
||||
/** Zaps all the specified regions */
|
||||
void ZapRegions(const cRegionVector & a_Regions);
|
||||
|
||||
|
||||
protected:
|
||||
static const int BlocksPerChunkX = 16;
|
||||
static const int BlocksPerChunkZ = 16;
|
||||
static const int ChunksPerMCAX = 32;
|
||||
static const int ChunksPerMCAZ = 32;
|
||||
|
||||
|
||||
AString m_MCAFolder;
|
||||
|
||||
/// Converts from block coords to MCA coords
|
||||
/** Converts from block coords to MCA coords */
|
||||
void BlockToMCA(int a_BlockX, int a_BlockZ, int & a_MCAX, int & a_MCAZ);
|
||||
|
||||
/// Converts from block coords to chunk coords
|
||||
|
||||
/** Converts from block coords to chunk coords */
|
||||
void BlockToChunk(int a_BlockX, int a_BlockZ, int & a_ChunkX, int & a_ChunkZ);
|
||||
|
||||
/// Zaps the specified region in the MCA file with the specified MCA coords
|
||||
|
||||
/** Zaps the specified region in the MCA file with the specified MCA coords */
|
||||
void ZapRegionInMCAFile(const cRegion & a_Region, int a_MCAX, int a_MCAZ);
|
||||
|
||||
|
||||
/** Loads raw compressed chunk data from the specified file
|
||||
* chunk is specified by ChunkHeaderValue, which is the int describing the chunk in file header.
|
||||
*/
|
||||
void LoadChunkData(cFile & a_InFile, int a_ChunkHeaderValue, AString & a_ChunkData, int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
/// Zaps the specified region in the raw (compressed) chunk data.
|
||||
|
||||
/** Zaps the specified region in the raw (compressed) chunk data. */
|
||||
void ZapRegionInRawChunkData(const cRegion & a_Region, AString & a_ChunkData, int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
/// Zaps the specified region in the specified NBT structure
|
||||
|
||||
/** Zaps the specified region in the specified NBT structure */
|
||||
void ZapRegionInNBTChunk(const cRegion & a_Region, cParsedNBT & a_NBT, int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
/// Zaps the blocks in the specified region from the specified NBT
|
||||
|
||||
/** Zaps the blocks in the specified region from the specified NBT */
|
||||
void ZapRegionBlocksInNBT(const cRegion & a_Region, cParsedNBT & a_NBT, int a_SectionsTag);
|
||||
|
||||
/// Zaps the blocks in the specified bytes (types) from one vertical section (16^3 blocks) of a chunk.
|
||||
|
||||
/** Zaps the blocks in the specified bytes (types) from one vertical section (16^3 blocks) of a chunk. */
|
||||
void ZapRegionInNBTSectionBytes(const cRegion & a_Region, int a_SectionY, unsigned char * a_BlockBytes);
|
||||
|
||||
/// Zaps the blocks in the specified nibbles (meta, add) from one vertical section (16^3 blocks) of a chunk.
|
||||
/** Zaps the blocks in the specified nibbles (meta, add) from one vertical section (16^3 blocks) of a chunk. */
|
||||
void ZapRegionInNBTSectionNibbles(const cRegion & a_Region, int a_SectionY, unsigned char * a_BlockNibbles);
|
||||
|
||||
/// Zaps entities in the specified region from the specified NBT
|
||||
|
||||
/** Zaps entities in the specified region from the specified NBT */
|
||||
void ZapRegionEntitiesInNBT(const cRegion & a_Region, cParsedNBT & a_NBT, int a_EntitiesTag);
|
||||
|
||||
/// Serializes the NBT subtree into a writer
|
||||
|
||||
/** Serializes the NBT subtree into a writer */
|
||||
void SerializeNBTTag(const cParsedNBT & a_NBT, int a_Tag, cFastNBTWriter & a_Writer);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "Globals.h"
|
||||
#include "ChunkGenerator.h"
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
cChunkGenerator Generator = cChunkGenerator();
|
||||
}
|
||||
|
@ -59,11 +59,11 @@ static const Color spectrumColors[] =
|
||||
/** Color palette used for displaying biome groups. */
|
||||
static const Color biomeGroupColors[] =
|
||||
{
|
||||
/* bgOcean */ {0x00, 0x00, 0x70},
|
||||
/* bgDesert */ {0xfa, 0x94, 0x18},
|
||||
/* bgTemperate */ {0x05, 0x66, 0x21},
|
||||
/* bgMountains */ {0x60, 0x60, 0x60},
|
||||
/* bgIce */ {0xa0, 0xa0, 0xff},
|
||||
/* bgOcean */ {0x00, 0x00, 0x70},
|
||||
/* bgDesert */ {0xfa, 0x94, 0x18},
|
||||
/* bgTemperate */ {0x05, 0x66, 0x21},
|
||||
/* bgMountains */ {0x60, 0x60, 0x60},
|
||||
/* bgIce */ {0xa0, 0xa0, 0xff},
|
||||
};
|
||||
|
||||
|
||||
@ -110,22 +110,22 @@ biomeColorMap[] =
|
||||
{ biJungleHills, { 0x2c, 0x42, 0x05 }, },
|
||||
|
||||
{ biJungleEdge, { 0x62, 0x8b, 0x17 }, },
|
||||
{ biDeepOcean, { 0x00, 0x00, 0x30 }, },
|
||||
{ biStoneBeach, { 0xa2, 0xa2, 0x84 }, },
|
||||
{ biColdBeach, { 0xfa, 0xf0, 0xc0 }, },
|
||||
{ biBirchForest, { 0x30, 0x74, 0x44 }, },
|
||||
{ biBirchForestHills, { 0x1f, 0x5f, 0x32 }, },
|
||||
{ biRoofedForest, { 0x40, 0x51, 0x1a }, },
|
||||
{ biColdTaiga, { 0x31, 0x55, 0x4a }, },
|
||||
{ biColdTaigaHills, { 0x59, 0x7d, 0x72 }, },
|
||||
{ biMegaTaiga, { 0x59, 0x66, 0x51 }, },
|
||||
{ biMegaTaigaHills, { 0x59, 0x66, 0x59 }, },
|
||||
{ biExtremeHillsPlus, { 0x50, 0x70, 0x50 }, },
|
||||
{ biSavanna, { 0xbd, 0xb2, 0x5f }, },
|
||||
{ biSavannaPlateau, { 0xa7, 0x9d, 0x64 }, },
|
||||
{ biMesa, { 0xd9, 0x45, 0x15 }, },
|
||||
{ biMesaPlateauF, { 0xb0, 0x97, 0x65 }, },
|
||||
{ biMesaPlateau, { 0xca, 0x8c, 0x65 }, },
|
||||
{ biDeepOcean, { 0x00, 0x00, 0x30 }, },
|
||||
{ biStoneBeach, { 0xa2, 0xa2, 0x84 }, },
|
||||
{ biColdBeach, { 0xfa, 0xf0, 0xc0 }, },
|
||||
{ biBirchForest, { 0x30, 0x74, 0x44 }, },
|
||||
{ biBirchForestHills, { 0x1f, 0x5f, 0x32 }, },
|
||||
{ biRoofedForest, { 0x40, 0x51, 0x1a }, },
|
||||
{ biColdTaiga, { 0x31, 0x55, 0x4a }, },
|
||||
{ biColdTaigaHills, { 0x59, 0x7d, 0x72 }, },
|
||||
{ biMegaTaiga, { 0x59, 0x66, 0x51 }, },
|
||||
{ biMegaTaigaHills, { 0x59, 0x66, 0x59 }, },
|
||||
{ biExtremeHillsPlus, { 0x50, 0x70, 0x50 }, },
|
||||
{ biSavanna, { 0xbd, 0xb2, 0x5f }, },
|
||||
{ biSavannaPlateau, { 0xa7, 0x9d, 0x64 }, },
|
||||
{ biMesa, { 0xd9, 0x45, 0x15 }, },
|
||||
{ biMesaPlateauF, { 0xb0, 0x97, 0x65 }, },
|
||||
{ biMesaPlateau, { 0xca, 0x8c, 0x65 }, },
|
||||
|
||||
// M variants:
|
||||
{ biSunflowerPlains, { 0xb5, 0xdb, 0x88 }, },
|
||||
@ -237,7 +237,7 @@ void initializeBiomeColors(void)
|
||||
}
|
||||
|
||||
// Initialize per-biome:
|
||||
for(size_t i = 0; i < ARRAYCOUNT(biomeColorMap); i++)
|
||||
for (size_t i = 0; i < ARRAYCOUNT(biomeColorMap); i++)
|
||||
{
|
||||
auto & dst = biomeColors[biomeColorMap[i].biome];
|
||||
const auto & src = biomeColorMap[i].color;
|
||||
@ -450,7 +450,3 @@ int main(int argc, char ** argv)
|
||||
log("GrownBiomeGenVisualiser finished");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -31,17 +31,17 @@ int main(int argc, char ** argv)
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
auto fileAttachment = cLogger::GetInstance().AttachListener(std::move(fileLogListenerRet.second));
|
||||
|
||||
|
||||
cLogger::InitiateMultithreading();
|
||||
|
||||
|
||||
cMCADefrag Defrag;
|
||||
if (!Defrag.Init(argc, argv))
|
||||
{
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
Defrag.Run();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ int main(int argc, char ** argv)
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cMCADefrag:
|
||||
|
||||
cMCADefrag::cMCADefrag(void) :
|
||||
@ -82,7 +82,7 @@ void cMCADefrag::Run(void)
|
||||
{
|
||||
StartThread();
|
||||
}
|
||||
|
||||
|
||||
// Wait for all the threads to finish:
|
||||
while (!m_Threads.empty())
|
||||
{
|
||||
@ -122,7 +122,7 @@ AString cMCADefrag::GetNextFileName(void)
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cMCADefrag::cThread:
|
||||
|
||||
cMCADefrag::cThread::cThread(cMCADefrag & a_Parent) :
|
||||
@ -161,7 +161,7 @@ void cMCADefrag::cThread::ProcessFile(const AString & a_FileName)
|
||||
return;
|
||||
}
|
||||
LOGINFO("%s", a_FileName.c_str());
|
||||
|
||||
|
||||
// Open input and output files:
|
||||
AString OutFileName = a_FileName + ".new";
|
||||
cFile In, Out;
|
||||
@ -175,7 +175,7 @@ void cMCADefrag::cThread::ProcessFile(const AString & a_FileName)
|
||||
LOGWARNING("Cannot open file %s for writing, skipping file.", OutFileName.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Read the Locations and Timestamps from the input file:
|
||||
Byte Locations[4096];
|
||||
UInt32 Timestamps[1024];
|
||||
@ -189,7 +189,7 @@ void cMCADefrag::cThread::ProcessFile(const AString & a_FileName)
|
||||
LOGWARNING("Cannot read Timestamps in file %s, skipping file.", a_FileName.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Write dummy Locations to the Out file (will be overwritten once the correct ones are known)
|
||||
if (Out.Write(Locations, sizeof(Locations)) != sizeof(Locations))
|
||||
{
|
||||
@ -197,14 +197,14 @@ void cMCADefrag::cThread::ProcessFile(const AString & a_FileName)
|
||||
return;
|
||||
}
|
||||
m_CurrentSectorOut = 2;
|
||||
|
||||
|
||||
// Write a copy of the Timestamps into the Out file:
|
||||
if (Out.Write(Timestamps, sizeof(Timestamps)) != sizeof(Timestamps))
|
||||
{
|
||||
LOGWARNING("Cannot write Timestamps to file %s, skipping file.", OutFileName.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Process each chunk:
|
||||
for (size_t i = 0; i < 1024; i++)
|
||||
{
|
||||
@ -231,7 +231,7 @@ void cMCADefrag::cThread::ProcessFile(const AString & a_FileName)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Write the new Locations into the MCA header:
|
||||
Out.Seek(0);
|
||||
if (Out.Write(Locations, sizeof(Locations)) != sizeof(Locations))
|
||||
@ -239,7 +239,7 @@ void cMCADefrag::cThread::ProcessFile(const AString & a_FileName)
|
||||
LOGWARNING("Cannot write updated Locations to file %s, skipping file.", OutFileName.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Close the files, delete orig, rename new:
|
||||
In.Close();
|
||||
Out.Close();
|
||||
@ -263,7 +263,7 @@ bool cMCADefrag::cThread::ReadChunk(cFile & a_File, const Byte * a_LocationRaw)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Read the exact size:
|
||||
Byte Buf[4];
|
||||
if (a_File.Read(Buf, 4) != 4)
|
||||
@ -277,14 +277,14 @@ bool cMCADefrag::cThread::ReadChunk(cFile & a_File, const Byte * a_LocationRaw)
|
||||
LOGWARNING("Invalid chunk data - SizeInSectors (%d) smaller that RealSize (%d)", SizeInSectors, m_CompressedChunkDataSize);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Read the data:
|
||||
if (a_File.Read(m_CompressedChunkData, static_cast<size_t>(m_CompressedChunkDataSize)) != m_CompressedChunkDataSize)
|
||||
{
|
||||
LOGWARNING("Failed to read chunk data!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Uncompress the data if recompression is active
|
||||
if (m_Parent.m_ShouldRecompress)
|
||||
{
|
||||
@ -294,7 +294,7 @@ bool cMCADefrag::cThread::ReadChunk(cFile & a_File, const Byte * a_LocationRaw)
|
||||
LOGINFO("Chunk failed to uncompress, will be copied verbatim instead.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -312,14 +312,14 @@ bool cMCADefrag::cThread::WriteChunk(cFile & a_File, Byte * a_LocationRaw)
|
||||
LOGINFO("Chunk failed to recompress, will be coped verbatim instead.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Update the Location:
|
||||
a_LocationRaw[0] = static_cast<Byte>(m_CurrentSectorOut >> 16);
|
||||
a_LocationRaw[1] = (m_CurrentSectorOut >> 8) & 0xff;
|
||||
a_LocationRaw[2] = m_CurrentSectorOut & 0xff;
|
||||
a_LocationRaw[3] = static_cast<Byte>((m_CompressedChunkDataSize + (4 KiB) + 3) / (4 KiB)); // +3 because the m_CompressedChunkDataSize doesn't include the exact-length
|
||||
m_CurrentSectorOut += a_LocationRaw[3];
|
||||
|
||||
|
||||
// Write the data length:
|
||||
Byte Buf[4];
|
||||
Buf[0] = static_cast<Byte>(m_CompressedChunkDataSize >> 24);
|
||||
@ -331,14 +331,14 @@ bool cMCADefrag::cThread::WriteChunk(cFile & a_File, Byte * a_LocationRaw)
|
||||
LOGWARNING("Failed to write chunk length!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Write the data:
|
||||
if (a_File.Write(m_CompressedChunkData, static_cast<size_t>(m_CompressedChunkDataSize)) != m_CompressedChunkDataSize)
|
||||
{
|
||||
LOGWARNING("Failed to write chunk data!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Pad onto the next sector:
|
||||
int NumPadding = a_LocationRaw[3] * 4096 - (m_CompressedChunkDataSize + 4);
|
||||
ASSERT(NumPadding >= 0);
|
||||
@ -347,7 +347,7 @@ bool cMCADefrag::cThread::WriteChunk(cFile & a_File, Byte * a_LocationRaw)
|
||||
LOGWARNING("Failed to write padding");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -419,7 +419,7 @@ bool cMCADefrag::cThread::CompressChunk(void)
|
||||
LOGINFO("Too much data for the internal compression buffer!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Compress the data using the highest compression factor:
|
||||
int errorcode = compress2(m_CompressedChunkData + 1, &CompressedSize, m_RawChunkData, static_cast<uLong>(m_RawChunkDataSize), Z_BEST_COMPRESSION);
|
||||
if (errorcode != Z_OK)
|
||||
@ -432,7 +432,3 @@ bool cMCADefrag::cThread::CompressChunk(void)
|
||||
m_CompressedChunkDataSize = static_cast<int>(CompressedSize + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -22,26 +22,26 @@ public:
|
||||
MAX_COMPRESSED_CHUNK_DATA_SIZE = (1 MiB),
|
||||
MAX_RAW_CHUNK_DATA_SIZE = (100 MiB),
|
||||
} ;
|
||||
|
||||
|
||||
cMCADefrag(void);
|
||||
|
||||
|
||||
/** Reads the cmdline params and initializes the app.
|
||||
Returns true if the app should continue, false if not. */
|
||||
bool Init(int argc, char ** argv);
|
||||
|
||||
|
||||
/** Runs the entire app. */
|
||||
void Run(void);
|
||||
|
||||
|
||||
protected:
|
||||
/** A single thread processing MCA files from the queue */
|
||||
class cThread :
|
||||
public cIsThread
|
||||
{
|
||||
typedef cIsThread super;
|
||||
|
||||
|
||||
public:
|
||||
cThread(cMCADefrag & a_Parent);
|
||||
|
||||
|
||||
protected:
|
||||
/** The compression methods, as specified by the MCA compression method byte. */
|
||||
enum
|
||||
@ -50,35 +50,35 @@ protected:
|
||||
COMPRESSION_ZLIB = 2,
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
cMCADefrag & m_Parent;
|
||||
|
||||
|
||||
/** The current compressed chunk data. Valid after a successful ReadChunk().
|
||||
This contains only the compression method byte and the compressed data,
|
||||
but not the exact-length preceding the data in the MCA file. */
|
||||
unsigned char m_CompressedChunkData[MAX_COMPRESSED_CHUNK_DATA_SIZE];
|
||||
|
||||
|
||||
/** Size of the actual current compressed chunk data, excluding the 4 exact-length bytes.
|
||||
This is the amount of bytes in m_CompressedChunkData[] that are valid. */
|
||||
int m_CompressedChunkDataSize;
|
||||
|
||||
|
||||
/** The current raw chunk data. Valid after a successful ReadChunk(), if recompression is active. */
|
||||
unsigned char m_RawChunkData[MAX_RAW_CHUNK_DATA_SIZE];
|
||||
|
||||
|
||||
/** Size of the actual current raw chunk data. */
|
||||
int m_RawChunkDataSize;
|
||||
|
||||
|
||||
/** Number of the sector where the next chunk will be written by WriteChunk(). */
|
||||
int m_CurrentSectorOut;
|
||||
|
||||
|
||||
/** Set to true when the chunk has been successfully uncompressed. Only used if recompression is active.
|
||||
WriteChunk() tests this flag to decide whether to call Compress(). */
|
||||
bool m_IsChunkUncompressed;
|
||||
|
||||
|
||||
|
||||
|
||||
/** Processes the specified file. */
|
||||
void ProcessFile(const AString & a_FileName);
|
||||
|
||||
|
||||
/** Reads the chunk data into m_CompressedChunkData.
|
||||
Calls DecompressChunkData() if recompression is active.
|
||||
a_LocationRaw is the pointer to the first byte of the Location data in the MCA header.
|
||||
@ -90,55 +90,51 @@ protected:
|
||||
a_LocationRaw is the pointer to the first byte of the Location data to be put into the MCA header,
|
||||
the chunk's location is stored in that memory area. Updates m_CurrentSectorOut.
|
||||
Returns true if successful. */
|
||||
bool WriteChunk(cFile & a_File, Byte * a_LocationRaw);
|
||||
|
||||
bool WriteChunk(cFile & a_File, Byte * a_LocationRaw);
|
||||
|
||||
/** Uncompresses the chunk data from m_CompressedChunkData into m_RawChunkData.
|
||||
Returns true if successful, false on failure. */
|
||||
bool UncompressChunk(void);
|
||||
|
||||
|
||||
/** Uncompresses the chunk data from m_CompressedChunkData into m_RawChunkData, using Gzip.
|
||||
Returns true if successful, false on failure. */
|
||||
bool UncompressChunkGzip(void);
|
||||
|
||||
|
||||
/** Uncompresses the chunk data from m_CompressedChunkData into m_RawChunkData, using Zlib.
|
||||
Returns true if successful, false on failure. */
|
||||
bool UncompressChunkZlib(void);
|
||||
|
||||
|
||||
/** Compresses the chunk data from m_RawChunkData into m_CompressedChunkData.
|
||||
Returns true if successful, false on failure. */
|
||||
bool CompressChunk(void);
|
||||
|
||||
|
||||
// cIsThread overrides:
|
||||
virtual void Execute(void) override;
|
||||
} ;
|
||||
|
||||
|
||||
typedef std::list<cThread *> cThreads;
|
||||
|
||||
|
||||
|
||||
|
||||
/** The mutex protecting m_Files agains multithreaded access. */
|
||||
cCriticalSection m_CS;
|
||||
|
||||
|
||||
/** The queue of MCA files to be processed by the threads. Protected by m_CS. */
|
||||
AStringVector m_Queue;
|
||||
|
||||
|
||||
/** List of threads that the server has running. */
|
||||
cThreads m_Threads;
|
||||
|
||||
|
||||
/** The number of threads that should be started. Configurable on the command line. */
|
||||
int m_NumThreads;
|
||||
|
||||
|
||||
/** If set to true, the chunk data is recompressed while saving each MCA file. */
|
||||
bool m_ShouldRecompress;
|
||||
|
||||
|
||||
|
||||
|
||||
/** Starts a new processing thread and adds it to cThreads. */
|
||||
void StartThread(void);
|
||||
|
||||
|
||||
/** Retrieves one file from the queue (and removes it from the queue).
|
||||
Returns an empty string when queue empty. */
|
||||
AString GetNextFileName(void);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,10 +1,6 @@
|
||||
|
||||
// Globals.cpp
|
||||
// Globals.cpp
|
||||
|
||||
// Used for precompiled header generation
|
||||
|
||||
#include "Globals.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -25,7 +25,7 @@ public:
|
||||
int m_Size; ///< Sum of memory block sizes allocated by this function or its children
|
||||
int m_Count; ///< Total number of memory blocks allocated by this function or its children
|
||||
AStringSet m_ChildrenNames;
|
||||
|
||||
|
||||
cFunction(void) :
|
||||
m_Size(0),
|
||||
m_Count(0)
|
||||
@ -66,7 +66,7 @@ bool IsFnBlackListed(const char * a_FnName)
|
||||
"luaM_realloc_",
|
||||
"",
|
||||
} ;
|
||||
|
||||
|
||||
for (int i = 0; i < ARRAYCOUNT(BlackList); i++)
|
||||
{
|
||||
if (strcmp(BlackList[i], a_FnName) == 0)
|
||||
@ -169,7 +169,7 @@ void WriteSizeStatistics(void)
|
||||
{
|
||||
typedef std::vector<std::pair<AString, int> > StringIntPairs;
|
||||
StringIntPairs FnSizes;
|
||||
|
||||
|
||||
cFile f("memdump_totals.txt", cFile::fmWrite);
|
||||
if (!f.IsOpen())
|
||||
{
|
||||
@ -182,7 +182,7 @@ void WriteSizeStatistics(void)
|
||||
FnSizes.push_back(std::pair<AString, int>(itr->first, itr->second.m_Size));
|
||||
} // for itr - g_FnSizes[]
|
||||
std::sort(FnSizes.begin(), FnSizes.end(), CompareFnInt);
|
||||
|
||||
|
||||
for (StringIntPairs::const_iterator itr = FnSizes.begin(), end = FnSizes.end(); itr != end; ++itr)
|
||||
{
|
||||
f.Printf("%d\t%s\n", itr->second, itr->first.c_str());
|
||||
@ -197,7 +197,7 @@ void WriteCountStatistics(void)
|
||||
{
|
||||
typedef std::vector<std::pair<AString, int> > StringIntPairs;
|
||||
StringIntPairs FnCounts;
|
||||
|
||||
|
||||
cFile f("memdump_counts.txt", cFile::fmWrite);
|
||||
if (!f.IsOpen())
|
||||
{
|
||||
@ -210,7 +210,7 @@ void WriteCountStatistics(void)
|
||||
FnCounts.push_back(std::pair<AString, int>(itr->first, itr->second.m_Count));
|
||||
} // for itr - g_FnSizes[]
|
||||
std::sort(FnCounts.begin(), FnCounts.end(), CompareFnInt);
|
||||
|
||||
|
||||
for (StringIntPairs::const_iterator itr = FnCounts.begin(), end = FnCounts.end(); itr != end; ++itr)
|
||||
{
|
||||
f.Printf("%d\t%s\n", itr->second, itr->first.c_str());
|
||||
@ -254,7 +254,7 @@ void WriteDotGraph(void)
|
||||
LOGERROR("Cannot open memdump.dot");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
f.Printf("digraph {\n\tnode [shape=plaintext]\n\n");
|
||||
for (FunctionMap::const_iterator itrF = g_FnMap.begin(), endF = g_FnMap.end(); itrF != endF; ++itrF)
|
||||
{
|
||||
@ -288,11 +288,11 @@ int main(int argc, char * argv[])
|
||||
printf("Cannot open memdump.xml\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// Create the XML parser:
|
||||
XML_Parser Parser = XML_ParserCreate(NULL);
|
||||
XML_SetElementHandler(Parser, OnStartElement, OnEndElement);
|
||||
|
||||
|
||||
// Feed the file through XML parser:
|
||||
char Buffer[512 KiB];
|
||||
while (true)
|
||||
@ -307,15 +307,11 @@ int main(int argc, char * argv[])
|
||||
}
|
||||
XML_Parse(Parser, "", 0, true);
|
||||
f.Close();
|
||||
|
||||
|
||||
// Output the statistics
|
||||
WriteSizeStatistics();
|
||||
WriteCountStatistics();
|
||||
WriteDotGraph();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -10,8 +10,8 @@
|
||||
#pragma once
|
||||
|
||||
// The following macros define the minimum required platform. The minimum required platform
|
||||
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
|
||||
// your application. The macros work by enabling all features available on platform versions up to and
|
||||
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
|
||||
// your application. The macros work by enabling all features available on platform versions up to and
|
||||
// including the version specified.
|
||||
|
||||
// Modify the following defines if you have to target a platform prior to the ones specified below.
|
||||
@ -19,7 +19,3 @@
|
||||
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
|
||||
#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows.
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -20,7 +20,7 @@ not much variance in the coords. The exact sizes and coord ranges were adapted f
|
||||
|
||||
|
||||
|
||||
/// The sizes of the interpolated noise that are calculated:
|
||||
/** The sizes of the interpolated noise that are calculated: */
|
||||
static const int SIZE_X = 33;
|
||||
static const int SIZE_Y = 5;
|
||||
static const int SIZE_Z = 5;
|
||||
@ -115,7 +115,3 @@ int main(int argc, char ** argv)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
|
||||
|
||||
/// When defined, the following macro causes a sleep after each parsed packet (DEBUG-mode only)
|
||||
/** When defined, the following macro causes a sleep after each parsed packet (DEBUG-mode only) */
|
||||
// #define SLEEP_AFTER_PACKET
|
||||
|
||||
|
||||
@ -121,7 +121,7 @@
|
||||
return true; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define HANDLE_SERVER_READ(Proc) \
|
||||
{ \
|
||||
if (!Proc) \
|
||||
@ -130,7 +130,7 @@
|
||||
return true; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -162,7 +162,7 @@ AString PrintableAbsIntTriplet(int a_X, int a_Y, int a_Z, double a_Divisor)
|
||||
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) {}
|
||||
} ;
|
||||
|
||||
@ -185,7 +185,7 @@ struct sChunkMeta
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cConnection:
|
||||
|
||||
cConnection::cConnection(SOCKET a_ClientSocket, cServer & a_Server) :
|
||||
@ -291,14 +291,14 @@ void cConnection::Log(const char * a_Format, ...)
|
||||
va_end(args);
|
||||
AString FullMsg;
|
||||
Printf(FullMsg, "[%5.3f] %s\n", GetRelativeTime(), msg.c_str());
|
||||
|
||||
|
||||
// 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;
|
||||
}
|
||||
@ -317,11 +317,11 @@ void cConnection::DataLog(const void * a_Data, size_t a_Size, const char * a_For
|
||||
AString FullMsg;
|
||||
AString Hex;
|
||||
Printf(FullMsg, "[%5.3f] %s\n%s\n", GetRelativeTime(), msg.c_str(), CreateHexDump(Hex, a_Data, a_Size, 16).c_str());
|
||||
|
||||
|
||||
// Log to file:
|
||||
cCSLock Lock(m_CSLog);
|
||||
fputs(FullMsg.c_str(), m_LogFile);
|
||||
|
||||
|
||||
/*
|
||||
// Log to screen:
|
||||
std::cout << FullMsg;
|
||||
@ -374,9 +374,9 @@ bool cConnection::RelayFromServer(void)
|
||||
Log("Server closed the socket: %d; %d; aborting connection", res, SocketError);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
DataLog(Buffer, static_cast<size_t>(res), "Received %d bytes from the SERVER", res);
|
||||
|
||||
|
||||
switch (m_ServerState)
|
||||
{
|
||||
case csUnencrypted:
|
||||
@ -414,9 +414,9 @@ bool cConnection::RelayFromClient(void)
|
||||
Log("Client closed the socket: %d; %d; aborting connection", res, SocketError);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
DataLog(Buffer, static_cast<size_t>(res), "Received %d bytes from the CLIENT", res);
|
||||
|
||||
|
||||
switch (m_ClientState)
|
||||
{
|
||||
case csUnencrypted:
|
||||
@ -456,7 +456,7 @@ double cConnection::GetRelativeTime(void)
|
||||
bool cConnection::SendData(SOCKET a_Socket, const char * a_Data, size_t a_Size, const char * a_Peer)
|
||||
{
|
||||
DataLog(a_Data, a_Size, "Sending data to %s, %u bytes", a_Peer, static_cast<unsigned>(a_Size));
|
||||
|
||||
|
||||
int res = static_cast<int>(send(a_Socket, a_Data, a_Size, 0)); // Windows uses int for a_Size, Linux uses size_t; but Windows doesn't complain. Return type is int on Windows and ssize_t on Linux
|
||||
if (res <= 0)
|
||||
{
|
||||
@ -525,7 +525,7 @@ bool cConnection::DecodeClientsPackets(const char * a_Data, int a_Size)
|
||||
Log("Too much queued data for the server, aborting connection");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
while (m_ClientBuffer.CanReadBytes(1))
|
||||
{
|
||||
UInt32 PacketLen;
|
||||
@ -556,7 +556,7 @@ bool cConnection::DecodeClientsPackets(const char * a_Data, int a_Size)
|
||||
}
|
||||
break;
|
||||
} // case -1
|
||||
|
||||
|
||||
case 1:
|
||||
{
|
||||
// Status query
|
||||
@ -568,7 +568,7 @@ bool cConnection::DecodeClientsPackets(const char * a_Data, int a_Size)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 2:
|
||||
{
|
||||
// Login
|
||||
@ -580,7 +580,7 @@ bool cConnection::DecodeClientsPackets(const char * a_Data, int a_Size)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 3:
|
||||
{
|
||||
// Game:
|
||||
@ -611,7 +611,7 @@ bool cConnection::DecodeClientsPackets(const char * a_Data, int a_Size)
|
||||
}
|
||||
break;
|
||||
} // case 3 - Game
|
||||
|
||||
|
||||
default:
|
||||
{
|
||||
Log("Receiving server packets while in an unknown protocol state (%d)!", m_ClientProtocolState);
|
||||
@ -635,7 +635,7 @@ bool cConnection::DecodeServersPackets(const char * a_Data, int a_Size)
|
||||
Log("Too much queued data for the client, aborting connection");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (
|
||||
(m_ServerState == csEncryptedUnderstood) &&
|
||||
(m_ClientState == csUnencrypted)
|
||||
@ -643,7 +643,7 @@ 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 (true)
|
||||
{
|
||||
UInt32 PacketLen;
|
||||
@ -679,7 +679,7 @@ bool cConnection::DecodeServersPackets(const char * a_Data, int a_Size)
|
||||
HANDLE_SERVER_READ(HandleServerUnknownPacket(PacketType, PacketLen, PacketReadSoFar));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 1:
|
||||
{
|
||||
// Status query:
|
||||
@ -691,7 +691,7 @@ bool cConnection::DecodeServersPackets(const char * a_Data, int a_Size)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 2:
|
||||
{
|
||||
// Login:
|
||||
@ -704,7 +704,7 @@ bool cConnection::DecodeServersPackets(const char * a_Data, int a_Size)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 3:
|
||||
{
|
||||
// Game:
|
||||
@ -766,7 +766,7 @@ bool cConnection::DecodeServersPackets(const char * a_Data, int a_Size)
|
||||
} // switch (PacketType)
|
||||
break;
|
||||
} // case 3 - Game
|
||||
|
||||
|
||||
// TODO: Move this elsewhere
|
||||
default:
|
||||
{
|
||||
@ -775,7 +775,7 @@ bool cConnection::DecodeServersPackets(const char * a_Data, int a_Size)
|
||||
break;
|
||||
}
|
||||
} // switch (m_ProtocolState)
|
||||
|
||||
|
||||
m_ServerBuffer.CommitRead();
|
||||
} // while (CanReadBytes(1))
|
||||
return true;
|
||||
@ -785,7 +785,7 @@ bool cConnection::DecodeServersPackets(const char * a_Data, int a_Size)
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// packet handling, client-side, initial handshake:
|
||||
|
||||
bool cConnection::HandleClientHandshake(void)
|
||||
@ -796,7 +796,7 @@ bool cConnection::HandleClientHandshake(void)
|
||||
HANDLE_CLIENT_PACKET_READ(ReadBEUInt16, UInt16, 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());
|
||||
@ -815,10 +815,10 @@ bool cConnection::HandleClientHandshake(void)
|
||||
cByteBuffer ToServer(512);
|
||||
ToServer.WriteVarUTF8String(Pkt);
|
||||
SERVERSEND(ToServer);
|
||||
|
||||
|
||||
m_ClientProtocolState = static_cast<int>(NextState);
|
||||
m_ServerProtocolState = static_cast<int>(NextState);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -826,7 +826,7 @@ bool cConnection::HandleClientHandshake(void)
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// packet handling, client-side, login:
|
||||
|
||||
bool cConnection::HandleClientLoginEncryptionKeyResponse(void)
|
||||
@ -852,7 +852,7 @@ bool cConnection::HandleClientLoginStart(void)
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// packet handling, client-side, game:
|
||||
|
||||
bool cConnection::HandleClientAnimation(void)
|
||||
@ -934,7 +934,7 @@ bool cConnection::HandleClientClientStatuses(void)
|
||||
HANDLE_CLIENT_PACKET_READ(ReadBEUInt8, UInt8, Statuses);
|
||||
Log("Received a PACKET_CLIENT_STATUSES from the CLIENT:");
|
||||
Log(" Statuses = %u (0x%02x)", Statuses, Statuses);
|
||||
|
||||
|
||||
COPY_TO_SERVER();
|
||||
return true;
|
||||
}
|
||||
@ -1087,7 +1087,7 @@ bool cConnection::HandleClientPlayerPosition(void)
|
||||
Log("Received a PACKET_PLAYER_POSITION from the client");
|
||||
|
||||
// TODO: list packet contents
|
||||
|
||||
|
||||
COPY_TO_SERVER();
|
||||
return true;
|
||||
}
|
||||
@ -1110,7 +1110,7 @@ bool cConnection::HandleClientPlayerPositionLook(void)
|
||||
Log(" Stance = %.03f", Stance);
|
||||
Log(" Yaw, Pitch = <%.03f, %.03f>", Yaw, Pitch);
|
||||
Log(" IsOnGround = %s", IsOnGround ? "true" : "false");
|
||||
|
||||
|
||||
COPY_TO_SERVER();
|
||||
return true;
|
||||
}
|
||||
@ -1279,7 +1279,7 @@ bool cConnection::HandleClientUnknownPacket(UInt32 a_PacketType, UInt32 a_Packet
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// packet handling, server-side, login:
|
||||
|
||||
bool cConnection::HandleServerLoginDisconnect(void)
|
||||
@ -1314,10 +1314,10 @@ bool cConnection::HandleServerLoginEncryptionKeyRequest(void)
|
||||
Log("Got PACKET_ENCRYPTION_KEY_REQUEST from the SERVER:");
|
||||
Log(" ServerID = %s", ServerID.c_str());
|
||||
DataLog(PublicKey.data(), PublicKey.size(), " Public key (%u bytes)", static_cast<unsigned>(PublicKey.size()));
|
||||
|
||||
|
||||
// Reply to the server:
|
||||
SendEncryptionKeyResponse(PublicKey, Nonce);
|
||||
|
||||
|
||||
// Do not send to client - we want the client connection open
|
||||
return true;
|
||||
}
|
||||
@ -1333,10 +1333,10 @@ bool cConnection::HandleServerLoginSuccess(void)
|
||||
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");
|
||||
@ -1355,7 +1355,7 @@ bool cConnection::HandleServerLoginSuccess(void)
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// packet handling, server-side, game:
|
||||
|
||||
bool cConnection::HandleServerAttachEntity(void)
|
||||
@ -1585,7 +1585,7 @@ bool cConnection::HandleServerEntityProperties(void)
|
||||
Log("Received a PACKET_ENTITY_PROPERTIES from the server:");
|
||||
Log(" EntityID = %u", EntityID);
|
||||
Log(" Count = %u", Count);
|
||||
|
||||
|
||||
for (UInt32 i = 0; i < Count; i++)
|
||||
{
|
||||
HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Key);
|
||||
@ -1797,7 +1797,7 @@ bool cConnection::HandleServerKick(void)
|
||||
{
|
||||
Log(" This was a std reply to client's PING");
|
||||
AStringVector Split;
|
||||
|
||||
|
||||
// Split by NULL chars (StringSplit() won't work here):
|
||||
size_t Last = 0;
|
||||
size_t Len = Reason.size();
|
||||
@ -1813,7 +1813,7 @@ bool cConnection::HandleServerKick(void)
|
||||
{
|
||||
Split.push_back(Reason.substr(Last));
|
||||
}
|
||||
|
||||
|
||||
if (Split.size() == 6)
|
||||
{
|
||||
Log(" Preamble: \"%s\"", Split[0].c_str());
|
||||
@ -1822,7 +1822,7 @@ bool cConnection::HandleServerKick(void)
|
||||
Log(" MOTD: \"%s\"", Split[3].c_str());
|
||||
Log(" Cur players: \"%s\"", Split[4].c_str());
|
||||
Log(" Max players: \"%s\"", Split[5].c_str());
|
||||
|
||||
|
||||
// Modify the MOTD to show that it's being ProtoProxied:
|
||||
Reason.assign(Split[0]);
|
||||
Reason.push_back(0);
|
||||
@ -1876,9 +1876,9 @@ bool cConnection::HandleServerMapChunk(void)
|
||||
Log("Received a PACKET_MAP_CHUNK from the server:");
|
||||
Log(" ChunkPos = [%d, %d]", ChunkX, ChunkZ);
|
||||
Log(" Compressed size = %u (0x%x)", CompressedSize, CompressedSize);
|
||||
|
||||
|
||||
// TODO: Save the compressed data into a file for later analysis
|
||||
|
||||
|
||||
COPY_TO_CLIENT()
|
||||
return true;
|
||||
}
|
||||
@ -1897,7 +1897,7 @@ bool cConnection::HandleServerMapChunkBulk(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Read individual chunk metas.
|
||||
// Need to read them first and only then start logging (in case we don't have the full packet yet)
|
||||
typedef std::vector<sChunkMeta> sChunkMetas;
|
||||
@ -1911,12 +1911,12 @@ bool cConnection::HandleServerMapChunkBulk(void)
|
||||
HANDLE_SERVER_PACKET_READ(ReadBEInt16, Int16, AddBitmap);
|
||||
ChunkMetas.push_back(sChunkMeta(ChunkX, ChunkZ, PrimaryBitmap, AddBitmap));
|
||||
}
|
||||
|
||||
|
||||
Log("Received a PACKET_MAP_CHUNK_BULK from the server:");
|
||||
Log(" ChunkCount = %u", ChunkCount);
|
||||
Log(" Compressed size = %u (0x%x)", CompressedSize, CompressedSize);
|
||||
Log(" IsSkyLightSent = %s", IsSkyLightSent ? "true" : "false");
|
||||
|
||||
|
||||
// Log individual chunk coords:
|
||||
int idx = 0;
|
||||
for (sChunkMetas::iterator itr = ChunkMetas.begin(), end = ChunkMetas.end(); itr != end; ++itr, ++idx)
|
||||
@ -1927,7 +1927,7 @@ bool cConnection::HandleServerMapChunkBulk(void)
|
||||
} // for itr - ChunkMetas[]
|
||||
|
||||
// TODO: Save the compressed data into a file for later analysis
|
||||
|
||||
|
||||
COPY_TO_CLIENT();
|
||||
return true;
|
||||
}
|
||||
@ -2038,7 +2038,7 @@ bool cConnection::HandleServerPlayerPositionLook(void)
|
||||
Log("Received a PACKET_PLAYER_POSITION_LOOK from the server");
|
||||
|
||||
// TODO: list packet contents
|
||||
|
||||
|
||||
COPY_TO_CLIENT();
|
||||
return true;
|
||||
}
|
||||
@ -2304,7 +2304,7 @@ bool cConnection::HandleServerSpawnObjectVehicle(void)
|
||||
}
|
||||
DataLog(Buffer.data(), Buffer.size(), "Buffer while parsing the PACKET_SPAWN_OBJECT_VEHICLE packet (%u bytes):", static_cast<unsigned>(Buffer.size()));
|
||||
#endif // _DEBUG
|
||||
|
||||
|
||||
HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, EntityID);
|
||||
HANDLE_SERVER_PACKET_READ(ReadBEUInt8, UInt8, ObjType);
|
||||
HANDLE_SERVER_PACKET_READ(ReadBEInt32, Int32, PosX);
|
||||
@ -2446,7 +2446,7 @@ 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:
|
||||
const char DescSearch[] = "\"description\":{\"text\":\"";
|
||||
size_t idx = Response.find(DescSearch);
|
||||
@ -2555,7 +2555,7 @@ bool cConnection::HandleServerUpdateTileEntity(void)
|
||||
HANDLE_SERVER_PACKET_READ(ReadBEInt16, Int16, BlockY);
|
||||
HANDLE_SERVER_PACKET_READ(ReadBEInt32, Int32, BlockZ);
|
||||
HANDLE_SERVER_PACKET_READ(ReadBEUInt8, UInt8, Action);
|
||||
HANDLE_SERVER_PACKET_READ(ReadBEUInt16, UInt16, DataLength);
|
||||
HANDLE_SERVER_PACKET_READ(ReadBEUInt16, UInt16, DataLength);
|
||||
|
||||
AString Data;
|
||||
if ((DataLength > 0) && !m_ServerBuffer.ReadString(Data, DataLength))
|
||||
@ -2736,7 +2736,7 @@ bool cConnection::ParseSlot(cByteBuffer & a_Buffer, AString & a_ItemDesc)
|
||||
fclose(f);
|
||||
AppendPrintf(a_ItemDesc, "\n (saved to file \"%s\")", fnam.c_str());
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2901,7 +2901,7 @@ void cConnection::LogMetadata(const AString & a_Metadata, size_t a_IndentCount)
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
Log("%spos[%u] = <%d, %d, %d>", Indent.c_str(), Index,
|
||||
Log("%spos[%u] = <%d, %d, %d>", Indent.c_str(), Index,
|
||||
(a_Metadata[pos + 1] << 24) | (a_Metadata[pos + 2] << 16) | (a_Metadata[pos + 3] << 8) | a_Metadata[pos + 4],
|
||||
(a_Metadata[pos + 5] << 24) | (a_Metadata[pos + 6] << 16) | (a_Metadata[pos + 7] << 8) | a_Metadata[pos + 8],
|
||||
(a_Metadata[pos + 9] << 24) | (a_Metadata[pos + 10] << 16) | (a_Metadata[pos + 11] << 8) | a_Metadata[pos + 12]
|
||||
@ -2939,7 +2939,7 @@ void cConnection::SendEncryptionKeyResponse(const AString & a_ServerPublicKey, c
|
||||
|
||||
m_ServerEncryptor.Init(SharedSecret, SharedSecret);
|
||||
m_ServerDecryptor.Init(SharedSecret, SharedSecret);
|
||||
|
||||
|
||||
// Encrypt the nonce:
|
||||
Byte EncryptedNonce[128];
|
||||
res = PubKey.Encrypt(reinterpret_cast<const Byte *>(a_Nonce.data()), a_Nonce.size(), EncryptedNonce, sizeof(EncryptedNonce));
|
||||
@ -2948,7 +2948,7 @@ void cConnection::SendEncryptionKeyResponse(const AString & a_ServerPublicKey, c
|
||||
Log("Nonce encryption failed: %d (0x%x)", res, res);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Send the packet to the server:
|
||||
Log("Sending PACKET_ENCRYPTION_KEY_RESPONSE to the SERVER");
|
||||
cByteBuffer ToServer(1024);
|
||||
@ -2966,7 +2966,3 @@ void cConnection::SendEncryptionKeyResponse(const AString & a_ServerPublicKey, c
|
||||
m_ServerState = csEncryptedUnderstood;
|
||||
m_IsServerEncrypted = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -25,19 +25,21 @@ class cServer;
|
||||
|
||||
class cConnection
|
||||
{
|
||||
AString m_LogNameBase; ///< Base for the log filename and all files connected to this log
|
||||
|
||||
int m_ItemIdx; ///< Index for the next file into which item metadata should be written (ParseSlot() function)
|
||||
|
||||
/** Base for the log filename and all files connected to this log */
|
||||
AString m_LogNameBase;
|
||||
|
||||
/** Index for the next file into which item metadata should be written (ParseSlot() function) */
|
||||
int m_ItemIdx;
|
||||
|
||||
cCriticalSection m_CSLog;
|
||||
FILE * m_LogFile;
|
||||
|
||||
|
||||
cServer & m_Server;
|
||||
SOCKET m_ClientSocket;
|
||||
SOCKET m_ServerSocket;
|
||||
|
||||
|
||||
std::chrono::steady_clock::time_point m_BeginTick; // Tick when the relative time was first retrieved (used for GetRelativeTime())
|
||||
|
||||
|
||||
enum eConnectionState
|
||||
{
|
||||
csUnencrypted, // The connection is not encrypted. Packets must be decoded in order to be able to start decryption.
|
||||
@ -45,35 +47,35 @@ class cConnection
|
||||
csEncryptedUnknown, // The communication is encrypted, but an unknown packet has been received, so packets cannot be decoded anymore
|
||||
csWaitingForEncryption, // The communication is waiting for the other line to establish encryption
|
||||
};
|
||||
|
||||
|
||||
eConnectionState m_ClientState;
|
||||
eConnectionState m_ServerState;
|
||||
|
||||
|
||||
int m_Nonce;
|
||||
|
||||
|
||||
public:
|
||||
cConnection(SOCKET a_ClientSocket, cServer & a_Server);
|
||||
~cConnection();
|
||||
|
||||
|
||||
void Run(void);
|
||||
|
||||
|
||||
void Log(const char * a_Format, ...);
|
||||
void DataLog(const void * a_Data, size_t a_Size, const char * a_Format, ...);
|
||||
void LogFlush(void);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
cByteBuffer m_ClientBuffer;
|
||||
cByteBuffer m_ServerBuffer;
|
||||
|
||||
|
||||
cAesCfb128Decryptor m_ServerDecryptor;
|
||||
cAesCfb128Encryptor m_ServerEncryptor;
|
||||
|
||||
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
|
||||
|
||||
/** 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
|
||||
@ -81,52 +83,52 @@ protected:
|
||||
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
|
||||
/** 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
|
||||
|
||||
/** 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
|
||||
|
||||
/** True if the server connection has provided encryption keys */
|
||||
bool m_IsServerEncrypted;
|
||||
|
||||
|
||||
|
||||
bool ConnectToServer(void);
|
||||
|
||||
/// Relays data from server to client; returns false if connection aborted
|
||||
|
||||
/** Relays data from server to client; returns false if connection aborted */
|
||||
bool RelayFromServer(void);
|
||||
|
||||
/// Relays data from client to server; returns false if connection aborted
|
||||
|
||||
/** Relays data from client to server; returns false if connection aborted */
|
||||
bool RelayFromClient(void);
|
||||
|
||||
/// Returns the time relative to the first call of this function, in the fractional seconds elapsed
|
||||
|
||||
/** Returns the time relative to the first call of this function, in the fractional seconds elapsed */
|
||||
double GetRelativeTime(void);
|
||||
|
||||
/// Sends data to the specified socket. If sending fails, prints a fail message using a_Peer and returns false.
|
||||
|
||||
/** Sends data to the specified socket. If sending fails, prints a fail message using a_Peer and returns false. */
|
||||
bool SendData(SOCKET a_Socket, const char * a_Data, size_t a_Size, const char * a_Peer);
|
||||
|
||||
/// Sends data to the specified socket. If sending fails, prints a fail message using a_Peer and returns false.
|
||||
|
||||
/** Sends data to the specified socket. If sending fails, prints a fail message using a_Peer and returns false. */
|
||||
bool SendData(SOCKET a_Socket, cByteBuffer & a_Data, const char * a_Peer);
|
||||
|
||||
/// Sends data to the specfied socket, after encrypting it using a_Encryptor. If sending fails, prints a fail message using a_Peer and returns false
|
||||
|
||||
/** Sends data to the specfied socket, after encrypting it using a_Encryptor. If sending fails, prints a fail message using a_Peer and returns false */
|
||||
bool SendEncryptedData(SOCKET a_Socket, cAesCfb128Encryptor & a_Encryptor, const char * a_Data, size_t a_Size, const char * a_Peer);
|
||||
|
||||
/// Sends data to the specfied socket, after encrypting it using a_Encryptor. If sending fails, prints a fail message using a_Peer and returns false
|
||||
|
||||
/** Sends data to the specfied socket, after encrypting it using a_Encryptor. If sending fails, prints a fail message using a_Peer and returns false */
|
||||
bool SendEncryptedData(SOCKET a_Socket, cAesCfb128Encryptor & a_Encryptor, cByteBuffer & a_Data, const char * a_Peer);
|
||||
|
||||
/// Decodes packets coming from the client, sends appropriate counterparts to the server; returns false if the connection is to be dropped
|
||||
|
||||
/** Decodes packets coming from the client, sends appropriate counterparts to the server; returns false if the connection is to be dropped */
|
||||
bool DecodeClientsPackets(const char * a_Data, int a_Size);
|
||||
|
||||
/// Decodes packets coming from the server, sends appropriate counterparts to the client; returns false if the connection is to be dropped
|
||||
/** 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, 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);
|
||||
@ -155,7 +157,7 @@ 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:
|
||||
@ -221,25 +223,21 @@ protected:
|
||||
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
|
||||
/** 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);
|
||||
|
||||
/// Parses the metadata in a_Buffer into raw metadata in an AString; returns true if successful, false if not enough data
|
||||
|
||||
/** Parses the metadata in a_Buffer into raw metadata in an AString; returns true if successful, false if not enough data */
|
||||
bool ParseMetadata(cByteBuffer & a_Buffer, AString & a_Metadata);
|
||||
|
||||
/// Logs the contents of the metadata in the AString, using Log(). Assumes a_Metadata is valid (parsed by ParseMetadata()). The log is indented by a_IndentCount spaces
|
||||
|
||||
/** Logs the contents of the metadata in the AString, using Log(). Assumes a_Metadata is valid (parsed by ParseMetadata()). The log is indented by a_IndentCount spaces */
|
||||
void LogMetadata(const AString & a_Metadata, size_t a_IndentCount);
|
||||
|
||||
/// Send EKResp to the server:
|
||||
|
||||
/** Send EKResp to the server: */
|
||||
void SendEncryptionKeyResponse(const AString & a_ServerPublicKey, const AString & a_Nonce);
|
||||
|
||||
/// Starts client encryption based on the parameters received
|
||||
|
||||
/** Starts client encryption based on the parameters received */
|
||||
void StartClientEncryption(const AString & a_EncryptedSecret, const AString & a_EncryptedNonce);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -195,14 +195,14 @@ typedef unsigned char Byte;
|
||||
|
||||
// Common definitions:
|
||||
|
||||
/// Evaluates to the number of elements in an array (compile-time!)
|
||||
/** 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)" )
|
||||
/* 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) )
|
||||
/* 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
|
||||
@ -212,7 +212,7 @@ typedef unsigned char Byte;
|
||||
#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 ) )
|
||||
#define VERIFY(x) (!!(x) || (LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__), exit(1), 0))
|
||||
|
||||
// C++11 has std::shared_ptr in <memory>, included earlier
|
||||
#define SharedPtr std::shared_ptr
|
||||
@ -222,10 +222,10 @@ typedef unsigned char Byte;
|
||||
|
||||
|
||||
|
||||
/// A generic interface used mainly in ForEach() functions
|
||||
/* A generic interface used mainly in ForEach() functions */
|
||||
template <typename Type> class cItemCallback
|
||||
{
|
||||
public:
|
||||
/// Called for each item in the internal list; return true to stop the loop, or false to continue enumerating
|
||||
/* Called for each item in the internal list; return true to stop the loop, or false to continue enumerating */
|
||||
virtual bool Item(Type * a_Type) = 0;
|
||||
} ;
|
||||
|
@ -52,12 +52,8 @@ int main(int argc, char ** argv)
|
||||
LOGERROR("Server initialization failed: %d", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
Server.Run();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -23,7 +23,7 @@ cServer::cServer(void)
|
||||
int cServer::Init(UInt16 a_ListenPort, UInt16 a_ConnectPort)
|
||||
{
|
||||
m_ConnectPort = a_ConnectPort;
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
WSAData wsa;
|
||||
int res = WSAStartup(0x0202, &wsa);
|
||||
@ -33,7 +33,7 @@ int cServer::Init(UInt16 a_ListenPort, UInt16 a_ConnectPort)
|
||||
return res;
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
|
||||
m_ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (m_ListenSocket < 0)
|
||||
{
|
||||
@ -71,7 +71,7 @@ int cServer::Init(UInt16 a_ListenPort, UInt16 a_ConnectPort)
|
||||
return err;
|
||||
}
|
||||
LOGINFO("Listening for client connections on port %d, connecting to server at localhost:%d", a_ListenPort, a_ConnectPort);
|
||||
|
||||
|
||||
LOGINFO("Generating protocol encryption keypair...");
|
||||
m_PrivateKey.Generate();
|
||||
m_PublicKeyDER = m_PrivateKey.GetPubKeyDER();
|
||||
@ -103,7 +103,3 @@ void cServer::Run(void)
|
||||
LOGINFO("Client disconnected. Ready for another connection.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -22,19 +22,15 @@ class cServer
|
||||
cRsaPrivateKey m_PrivateKey;
|
||||
AString m_PublicKeyDER;
|
||||
UInt16 m_ConnectPort;
|
||||
|
||||
|
||||
public:
|
||||
cServer(void);
|
||||
|
||||
|
||||
int Init(UInt16 a_ListenPort, UInt16 a_ConnectPort);
|
||||
void Run(void);
|
||||
|
||||
|
||||
cRsaPrivateKey & GetPrivateKey(void) { return m_PrivateKey; }
|
||||
const AString & GetPublicKeyDER (void) { return m_PublicKeyDER; }
|
||||
|
||||
|
||||
UInt16 GetConnectPort(void) const { return m_ConnectPort; }
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -17,7 +17,7 @@ static const int DELTA_STEP = 120; // The normal per-notch wheel delta
|
||||
/** Map for converting biome values to colors. Initialized from biomeColors[]. */
|
||||
static uchar biomeToColor[256 * 4];
|
||||
|
||||
/** Map for converting biome values to colors. Used to initialize biomeToColor[].*/
|
||||
/** Map for converting biome values to colors. Used to initialize biomeToColor[]. */
|
||||
static struct
|
||||
{
|
||||
EMCSBiome m_Biome;
|
||||
@ -49,22 +49,22 @@ static struct
|
||||
{ biJungleHills, { 0x2c, 0x42, 0x05 }, },
|
||||
|
||||
{ biJungleEdge, { 0x62, 0x8b, 0x17 }, },
|
||||
{ biDeepOcean, { 0x00, 0x00, 0x30 }, },
|
||||
{ biStoneBeach, { 0xa2, 0xa2, 0x84 }, },
|
||||
{ biColdBeach, { 0xfa, 0xf0, 0xc0 }, },
|
||||
{ biBirchForest, { 0x30, 0x74, 0x44 }, },
|
||||
{ biBirchForestHills, { 0x1f, 0x5f, 0x32 }, },
|
||||
{ biRoofedForest, { 0x40, 0x51, 0x1a }, },
|
||||
{ biColdTaiga, { 0x31, 0x55, 0x4a }, },
|
||||
{ biColdTaigaHills, { 0x59, 0x7d, 0x72 }, },
|
||||
{ biMegaTaiga, { 0x59, 0x66, 0x51 }, },
|
||||
{ biMegaTaigaHills, { 0x59, 0x66, 0x59 }, },
|
||||
{ biExtremeHillsPlus, { 0x50, 0x70, 0x50 }, },
|
||||
{ biSavanna, { 0xbd, 0xb2, 0x5f }, },
|
||||
{ biSavannaPlateau, { 0xa7, 0x9d, 0x64 }, },
|
||||
{ biMesa, { 0xd9, 0x45, 0x15 }, },
|
||||
{ biMesaPlateauF, { 0xb0, 0x97, 0x65 }, },
|
||||
{ biMesaPlateau, { 0xca, 0x8c, 0x65 }, },
|
||||
{ biDeepOcean, { 0x00, 0x00, 0x30 }, },
|
||||
{ biStoneBeach, { 0xa2, 0xa2, 0x84 }, },
|
||||
{ biColdBeach, { 0xfa, 0xf0, 0xc0 }, },
|
||||
{ biBirchForest, { 0x30, 0x74, 0x44 }, },
|
||||
{ biBirchForestHills, { 0x1f, 0x5f, 0x32 }, },
|
||||
{ biRoofedForest, { 0x40, 0x51, 0x1a }, },
|
||||
{ biColdTaiga, { 0x31, 0x55, 0x4a }, },
|
||||
{ biColdTaigaHills, { 0x59, 0x7d, 0x72 }, },
|
||||
{ biMegaTaiga, { 0x59, 0x66, 0x51 }, },
|
||||
{ biMegaTaigaHills, { 0x59, 0x66, 0x59 }, },
|
||||
{ biExtremeHillsPlus, { 0x50, 0x70, 0x50 }, },
|
||||
{ biSavanna, { 0xbd, 0xb2, 0x5f }, },
|
||||
{ biSavannaPlateau, { 0xa7, 0x9d, 0x64 }, },
|
||||
{ biMesa, { 0xd9, 0x45, 0x15 }, },
|
||||
{ biMesaPlateauF, { 0xb0, 0x97, 0x65 }, },
|
||||
{ biMesaPlateau, { 0xca, 0x8c, 0x65 }, },
|
||||
|
||||
// M variants:
|
||||
{ biSunflowerPlains, { 0xb5, 0xdb, 0x88 }, },
|
||||
@ -307,8 +307,8 @@ void BiomeView::drawChunk(int a_ChunkX, int a_ChunkZ)
|
||||
// which need to be shifted to account for panning inside that chunk
|
||||
centerx -= (m_X - centerchunkx * 16) * m_Zoom;
|
||||
centery -= (m_Z - centerchunkz * 16) * m_Zoom;
|
||||
// centerx,y now points to the top left corner of the center chunk
|
||||
// so now calculate our x,y in relation
|
||||
// centerx, centery now points to the top left corner of the center chunk
|
||||
// so now calculate our x, y in relation
|
||||
double chunksize = 16 * m_Zoom;
|
||||
centerx += (a_ChunkX - centerchunkx) * chunksize;
|
||||
centery += (a_ChunkZ - centerchunkz) * chunksize;
|
||||
@ -550,7 +550,3 @@ void BiomeView::keyPressEvent(QKeyEvent * a_Event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -15,9 +15,9 @@
|
||||
// Useful warnings from warning level 4:
|
||||
#pragma warning(3 : 4127) // Conditional expression is constant
|
||||
#pragma warning(3 : 4189) // Local variable is initialized but not referenced
|
||||
#pragma warning(3 : 4245) // Conversion from 'type1' to 'type2', signed/unsigned mismatch
|
||||
#pragma warning(3 : 4245) // Conversion from 'type1' to 'type2', signed / unsigned mismatch
|
||||
#pragma warning(3 : 4310) // Cast truncates constant value
|
||||
#pragma warning(3 : 4389) // Signed/unsigned mismatch
|
||||
#pragma warning(3 : 4389) // Signed / unsigned mismatch
|
||||
#pragma warning(3 : 4505) // Unreferenced local function has been removed
|
||||
#pragma warning(3 : 4701) // Potentially unitialized local variable used
|
||||
#pragma warning(3 : 4702) // Unreachable code
|
||||
@ -254,9 +254,9 @@ template class SizeChecker<UInt16, 2>;
|
||||
#include "src/Logger.h"
|
||||
#else
|
||||
// Logging functions
|
||||
void inline LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2);
|
||||
void inline LOGERROR(const char * a_Format, ...) FORMATSTRING(1, 2);
|
||||
|
||||
void inline LOGERROR(const char* a_Format, ...)
|
||||
void inline LOGERROR(const char * a_Format, ...)
|
||||
{
|
||||
va_list argList;
|
||||
va_start(argList, a_Format);
|
||||
@ -271,14 +271,15 @@ void inline LOGERROR(const char* a_Format, ...)
|
||||
|
||||
// Common definitions:
|
||||
|
||||
/// Evaluates to the number of elements in an array (compile-time!)
|
||||
/** 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)")
|
||||
/** Allows arithmetic expressions like "32 KiB" (but consider using parenthesis
|
||||
around it, "(32 KiB)") */
|
||||
#define KiB * 1024
|
||||
#define MiB * 1024 * 1024
|
||||
|
||||
/// Faster than (int)floorf((float)x / (float)div)
|
||||
/** Faster than (int)floorf((float)x / (float)div) */
|
||||
#define FAST_FLOOR_DIV( x, div) (((x) - (((x) < 0) ? ((div) - 1) : 0)) / (div))
|
||||
|
||||
// Own version of assert() that writes failed assertions to the log for review
|
||||
|
@ -218,14 +218,14 @@ typedef unsigned char Byte;
|
||||
|
||||
// Common definitions:
|
||||
|
||||
/// Evaluates to the number of elements in an array (compile-time!)
|
||||
/** 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)" )
|
||||
/** 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) )
|
||||
/** 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
|
||||
@ -235,4 +235,4 @@ typedef unsigned char Byte;
|
||||
#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 ) )
|
||||
#define VERIFY(x) (!!(x) || (LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__), exit(1), 0))
|
||||
|
@ -18,7 +18,7 @@ bool g_IsVerbose = false;
|
||||
|
||||
|
||||
|
||||
/// This class can read and write RCON packets to / from a connected socket
|
||||
/** This class can read and write RCON packets to / from a connected socket */
|
||||
class cRCONPacketizer
|
||||
{
|
||||
public:
|
||||
@ -27,29 +27,29 @@ public:
|
||||
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.
|
||||
|
||||
/** 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:
|
||||
/** 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
|
||||
|
||||
/** 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.
|
||||
/** 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
|
||||
|
||||
/** 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);
|
||||
} ;
|
||||
|
||||
@ -92,7 +92,7 @@ bool cRCONPacketizer::SendPacket(int a_PacketType, const AString & a_PacketPaylo
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return ReceiveResponse();
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ bool cRCONPacketizer::SendPacket(int a_PacketType, const AString & a_PacketPaylo
|
||||
|
||||
|
||||
bool cRCONPacketizer::ReceiveResponse(void)
|
||||
{
|
||||
{
|
||||
// Receive the response:
|
||||
cByteBuffer Buffer(64 KiB);
|
||||
while (true)
|
||||
@ -122,7 +122,7 @@ bool cRCONPacketizer::ReceiveResponse(void)
|
||||
}
|
||||
Buffer.Write(buf, NumReceived);
|
||||
Buffer.ResetRead();
|
||||
|
||||
|
||||
// Check if the buffer contains the full packet:
|
||||
if (!Buffer.CanReadBytes(14))
|
||||
{
|
||||
@ -136,7 +136,7 @@ bool cRCONPacketizer::ReceiveResponse(void)
|
||||
// The packet is not complete yet
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Parse the packet
|
||||
return ParsePacket(Buffer, PacketSize);
|
||||
}
|
||||
@ -166,7 +166,7 @@ bool cRCONPacketizer::ParsePacket(cByteBuffer & a_Buffer, int a_PacketLength)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check the packet type:
|
||||
int PacketType = 0;
|
||||
VERIFY(a_Buffer.ReadLEInt(PacketType));
|
||||
@ -176,7 +176,7 @@ bool cRCONPacketizer::ParsePacket(cByteBuffer & a_Buffer, int a_PacketLength)
|
||||
IsValid = false;
|
||||
// Continue, so that the payload is printed before the program aborts.
|
||||
}
|
||||
|
||||
|
||||
AString Payload;
|
||||
VERIFY(a_Buffer.ReadString(Payload, a_PacketLength - 10));
|
||||
|
||||
@ -195,7 +195,7 @@ bool cRCONPacketizer::ParsePacket(cByteBuffer & a_Buffer, int a_PacketLength)
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// main:
|
||||
|
||||
int RealMain(int argc, char * argv[])
|
||||
@ -255,14 +255,14 @@ int RealMain(int argc, char * argv[])
|
||||
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:
|
||||
// Connect:
|
||||
if (cSocket::WSAStartup() != 0)
|
||||
{
|
||||
fprintf(stderr, "Cannot initialize network stack. Aborting\n");
|
||||
@ -279,7 +279,7 @@ int RealMain(int argc, char * argv[])
|
||||
return 3;
|
||||
}
|
||||
cRCONPacketizer Packetizer(s);
|
||||
|
||||
|
||||
// Authenticate using the provided password:
|
||||
if (!Password.empty())
|
||||
{
|
||||
@ -300,7 +300,7 @@ int RealMain(int argc, char * argv[])
|
||||
fprintf(stderr, "No password provided, not sending a login packet.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Send each command:
|
||||
for (AStringVector::const_iterator itr = Commands.begin(), end = Commands.end(); itr != end; ++itr)
|
||||
{
|
||||
@ -313,7 +313,7 @@ int RealMain(int argc, char * argv[])
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -327,7 +327,3 @@ int main(int argc, char * argv[])
|
||||
int res = RealMain(argc, argv);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -83,10 +83,10 @@
|
||||
|
||||
// Common definitions:
|
||||
|
||||
/// Evaluates to the number of elements in an array (compile-time!)
|
||||
/** 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)" )
|
||||
/** Allows arithmetic expressions like "32 KiB" (but consider using parenthesis around it, "(32 KiB)") */
|
||||
#define KiB * 1024
|
||||
#define MiB * 1024 * 1024
|
||||
|
||||
|
@ -26,14 +26,14 @@ public:
|
||||
m_IsInComment(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool IsGood(void) const
|
||||
{
|
||||
return !m_Out.fail();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void ProcessFile(const AString & a_FileIn)
|
||||
{
|
||||
std::ifstream In(a_FileIn.c_str());
|
||||
@ -49,14 +49,14 @@ public:
|
||||
PushLine(Line);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
std::ofstream m_Out;
|
||||
bool m_IsInToLua; ///< Set to true if inside a tolua_begin .. tolua_end block
|
||||
bool m_IsInComment; ///< Set to true if previous line has started a multiline comment; only outside tolua blocks
|
||||
AString m_LastComment; ///< Accumulator for a multiline comment preceding a tolua block
|
||||
|
||||
|
||||
|
||||
|
||||
void PushLine(const AString & a_Line)
|
||||
{
|
||||
if (m_IsInToLua)
|
||||
@ -71,7 +71,7 @@ protected:
|
||||
m_Out << a_Line << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (m_IsInComment)
|
||||
{
|
||||
// Inside a multiline comment block, outside of a tolua block; accumulate m_LastComment
|
||||
@ -79,9 +79,9 @@ protected:
|
||||
m_IsInComment = (a_Line.find("*/") == AString::npos);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
AString Trimmed(TrimString(a_Line));
|
||||
|
||||
|
||||
if (Trimmed == "// tolua_begin")
|
||||
{
|
||||
// Beginning of a tolua block
|
||||
@ -93,19 +93,19 @@ protected:
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
size_t CommentBegin = a_Line.find("/*");
|
||||
if (CommentBegin != AString::npos)
|
||||
{
|
||||
m_IsInComment = (a_Line.find("*/", CommentBegin) == AString::npos);
|
||||
m_LastComment = a_Line;
|
||||
}
|
||||
|
||||
|
||||
size_t ExportIdx = a_Line.find("// tolua_export");
|
||||
if (ExportIdx != AString::npos)
|
||||
{
|
||||
// Single-line tolua block
|
||||
|
||||
|
||||
// Strip the export comment and right-trim the line:
|
||||
AString Stripped(a_Line.substr(0, ExportIdx));
|
||||
int End = Stripped.length() - 1;
|
||||
@ -114,7 +114,7 @@ protected:
|
||||
End--;
|
||||
}
|
||||
Stripped.erase(End + 1);
|
||||
|
||||
|
||||
if (!m_LastComment.empty())
|
||||
{
|
||||
m_Out << m_LastComment << std::endl;
|
||||
@ -123,7 +123,7 @@ protected:
|
||||
m_Out << Stripped << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!m_IsInComment)
|
||||
{
|
||||
m_LastComment.clear();
|
||||
@ -147,7 +147,7 @@ bool ParsePackageFile(const AString & a_FileName, AStrings & a_CFiles, AStrings
|
||||
std::cerr << "Cannot open the package file " << a_FileName << "." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
while (!PkgFile.eof())
|
||||
{
|
||||
AString Line;
|
||||
@ -169,7 +169,7 @@ bool ParsePackageFile(const AString & a_FileName, AStrings & a_CFiles, AStrings
|
||||
|
||||
|
||||
|
||||
/// Processes the specified input header file into the output file
|
||||
/** Processes the specified input header file into the output file */
|
||||
void ProcessCFile(const AString & a_CFileIn, const AString & a_CFileOut)
|
||||
{
|
||||
cProcessor p(a_CFileOut);
|
||||
@ -189,14 +189,14 @@ int main(int argc, char * argv[])
|
||||
{
|
||||
AString BaseDir = (argc > 1) ? argv[1] : ".";
|
||||
AString OutDir = (argc > 2) ? argv[2] : "Out";
|
||||
|
||||
|
||||
// Create the output directory:
|
||||
#ifdef _WIN32
|
||||
CreateDirectory(OutDir.c_str(), NULL);
|
||||
#else
|
||||
mkdir(OutDir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
#endif
|
||||
|
||||
|
||||
// Parse the package file
|
||||
AStrings CFiles;
|
||||
AStrings DirectLines;
|
||||
@ -204,7 +204,7 @@ int main(int argc, char * argv[])
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// Process header files:
|
||||
for (AStrings::const_iterator itr = CFiles.begin(), end = CFiles.end(); itr != end; ++itr)
|
||||
{
|
||||
@ -213,10 +213,6 @@ int main(int argc, char * argv[])
|
||||
AString Out = Printf("%s/%04x.h", OutDir.c_str(), cnt++);
|
||||
ProcessCFile(In, Out);
|
||||
} // for itr - CFiles[]
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user