1
0
Fork 0

Fix style of Tools

This commit is contained in:
Alexander Lyons Harkness 2017-12-23 12:49:08 +00:00
parent aff140365d
commit 1926181cb7
45 changed files with 626 additions and 773 deletions

View File

@ -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");
}

View File

@ -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
}

View 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;
}
} ;

View File

@ -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;
} ;

View File

@ -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;
}
}

View File

@ -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;
} ;

View File

@ -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"

View File

@ -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()
}
}
}

View File

@ -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;
}
} ;

View File

@ -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
}

View 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;
}
} ;

View File

@ -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);
}

View File

@ -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);
} ;

View File

@ -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;
}

View File

@ -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);
} ;

View File

@ -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());
}
}

View File

@ -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);
} ;

View File

@ -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");
}
}

View File

@ -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);
} ;

View File

@ -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;
}

View File

@ -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;
} ;

View File

@ -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));
}

View File

@ -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);
} ;

View File

@ -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
}
}
}

View File

@ -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);
} ;

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
} ;

View File

@ -1,10 +1,6 @@
// Globals.cpp
// Globals.cpp
// Used for precompiled header generation
#include "Globals.h"

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
} ;

View File

@ -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;
} ;

View File

@ -52,12 +52,8 @@ int main(int argc, char ** argv)
LOGERROR("Server initialization failed: %d", res);
return res;
}
Server.Run();
return 0;
}

View File

@ -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.");
}
}

View File

@ -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; }
} ;

View File

@ -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)
}
}
}

View File

@ -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

View File

@ -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))

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}