From 53e22b11857fed62e2313d6d84d90f88ed412ffb Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Mon, 29 Jul 2013 12:13:03 +0100 Subject: Changed everyting to Unix line endings. --- Tools/AnvilStats/Statistics.cpp | 1046 +++++++++++++++++++-------------------- 1 file changed, 523 insertions(+), 523 deletions(-) (limited to 'Tools/AnvilStats/Statistics.cpp') diff --git a/Tools/AnvilStats/Statistics.cpp b/Tools/AnvilStats/Statistics.cpp index 2f30e158a..b5b3cb176 100644 --- a/Tools/AnvilStats/Statistics.cpp +++ b/Tools/AnvilStats/Statistics.cpp @@ -1,523 +1,523 @@ - -// Statistics.cpp - -// Implements the various statistics-collecting classes - -#include "Globals.h" -#include "Statistics.h" -#include "../../source/WorldStorage/FastNBT.h" - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cStatistics::cStats: - -cStatistics::cStats::cStats(void) : - m_TotalChunks(0), - m_BiomeNumChunks(0), - m_BlockNumChunks(0), - m_NumEntities(0), - m_NumTileEntities(0), - m_NumTileTicks(0), - m_MinChunkX(0x7fffffff), - m_MaxChunkX(0x80000000), - m_MinChunkZ(0x7fffffff), - m_MaxChunkZ(0x80000000) -{ - memset(m_BiomeCounts, 0, sizeof(m_BiomeCounts)); - memset(m_BlockCounts, 0, sizeof(m_BlockCounts)); - memset(m_SpawnerEntity, 0, sizeof(m_SpawnerEntity)); -} - - - - - -void cStatistics::cStats::Add(const cStatistics::cStats & a_Stats) -{ - for (int i = 0; i <= 255; i++) - { - m_BiomeCounts[i] += a_Stats.m_BiomeCounts[i]; - } - for (int i = 0; i <= 255; i++) - { - for (int j = 0; j <= 255; j++) - { - m_BlockCounts[i][j] += a_Stats.m_BlockCounts[i][j]; - } - } - for (int i = 0; i < ARRAYCOUNT(m_SpawnerEntity); i++) - { - m_SpawnerEntity[i] += a_Stats.m_SpawnerEntity[i]; - } - m_BiomeNumChunks += a_Stats.m_BiomeNumChunks; - m_BlockNumChunks += a_Stats.m_BlockNumChunks; - m_TotalChunks += a_Stats.m_TotalChunks; - m_NumEntities += a_Stats.m_NumEntities; - m_NumTileEntities += a_Stats.m_NumTileEntities; - m_NumTileTicks += a_Stats.m_NumTileTicks; - UpdateCoordsRange(a_Stats.m_MinChunkX, a_Stats.m_MinChunkZ); - UpdateCoordsRange(a_Stats.m_MinChunkX, a_Stats.m_MinChunkZ); -} - - - - - -void cStatistics::cStats::UpdateCoordsRange(int a_ChunkX, int a_ChunkZ) -{ - if (a_ChunkX < m_MinChunkX) - { - m_MinChunkX = a_ChunkX; - } - if (a_ChunkX > m_MaxChunkX) - { - m_MaxChunkX = a_ChunkX; - } - if (a_ChunkZ < m_MinChunkZ) - { - m_MinChunkZ = a_ChunkZ; - } - if (a_ChunkZ > m_MaxChunkZ) - { - m_MaxChunkZ = a_ChunkZ; - } -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cStatistics: - -cStatistics::cStatistics(void) -{ -} - - - - - -bool cStatistics::OnNewChunk(int a_ChunkX, int a_ChunkZ) -{ - m_Stats.m_TotalChunks++; - m_Stats.UpdateCoordsRange(a_ChunkX, a_ChunkZ); - m_IsBiomesValid = false; - m_IsFirstSectionInChunk = true; - return false; -} - - - - - -bool cStatistics::OnBiomes(const unsigned char * a_BiomeData) -{ - for (int i = 0; i < 16 * 16; i++) - { - m_Stats.m_BiomeCounts[a_BiomeData[i]] += 1; - } - m_Stats.m_BiomeNumChunks += 1; - memcpy(m_BiomeData, a_BiomeData, sizeof(m_BiomeData)); - m_IsBiomesValid = true; - return false; -} - - - - - - -bool cStatistics::OnSection -( - unsigned char a_Y, - const BLOCKTYPE * a_BlockTypes, - const NIBBLETYPE * a_BlockAdditional, - const NIBBLETYPE * a_BlockMeta, - const NIBBLETYPE * a_BlockLight, - const NIBBLETYPE * a_BlockSkyLight -) -{ - if (!m_IsBiomesValid) - { - // 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++) - { - for (int z = 0; z < 16; z++) - { - for (int x = 0; x < 16; x++) - { - unsigned char Biome = m_BiomeData[x + 16 * z]; // Cannot use cChunkDef, different datatype - unsigned char BlockType = cChunkDef::GetBlock(a_BlockTypes, x, y, z); - m_Stats.m_BlockCounts[Biome][BlockType] += 1; - } - } - } - - m_Stats.m_BlockNumChunks += m_IsFirstSectionInChunk ? 1 : 0; - m_IsFirstSectionInChunk = false; - - return false; -} - - - - - -bool cStatistics::OnEmptySection(unsigned char a_Y) -{ - if (!m_IsBiomesValid) - { - // The current biome data is not valid, we don't have the means for sorting the BlockTypes into per-biome arrays - return true; - } - - // Add air to all columns: - for (int z = 0; z < 16; z++) - { - for (int x = 0; x < 16; x++) - { - unsigned char Biome = m_BiomeData[x + 16 * z]; // Cannot use cChunkDef, different datatype - 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; -} - - - - - -bool cStatistics::OnEntity( - const AString & a_EntityType, - double a_PosX, double a_PosY, double a_PosZ, - double a_SpeedX, double a_SpeedY, double a_SpeedZ, - float a_Yaw, float a_Pitch, - float a_FallDistance, - short a_FireTicksLeft, - short a_AirTicks, - char a_IsOnGround, - cParsedNBT & a_NBT, - int a_NBTTag -) -{ - m_Stats.m_NumEntities += 1; - - // TODO - - return false; -} - - - - - -bool cStatistics::OnTileEntity( - const AString & a_EntityType, - int a_PosX, int a_PosY, int a_PosZ, - cParsedNBT & a_NBT, - int a_NBTTag -) -{ - m_Stats.m_NumTileEntities += 1; - - if (a_EntityType == "MobSpawner") - { - OnSpawner(a_NBT, a_NBTTag); - } - - return false; -} - - - - - -bool cStatistics::OnTileTick( - int a_BlockType, - int a_TicksLeft, - int a_PosX, int a_PosY, int a_PosZ -) -{ - m_Stats.m_NumTileTicks += 1; - return false; -} - - - - - -void cStatistics::OnSpawner(cParsedNBT & a_NBT, int a_TileEntityTag) -{ - int EntityIDTag = a_NBT.FindChildByName(a_TileEntityTag, "EntityId"); - if ((EntityIDTag < 0) || (a_NBT.GetType(EntityIDTag) != TAG_String)) - { - return; - } - eEntityType Ent = GetEntityType(a_NBT.GetString(EntityIDTag)); - if (Ent < ARRAYCOUNT(m_Stats.m_SpawnerEntity)) - { - m_Stats.m_SpawnerEntity[Ent] += 1; - } -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cStatisticsFactory: - -cStatisticsFactory::cStatisticsFactory(void) : - m_BeginTick(clock()) -{ -} - - - - - -cStatisticsFactory::~cStatisticsFactory() -{ - // Join the results together: - LOG("cStatistics:"); - LOG(" Joining results..."); - 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++) - { - for (int j = 0; j < 255; j++) - { - TotalBlocks += m_CombinedStats.m_BlockCounts[i][j]; - } - } - 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"); - SaveStatistics(); - LOG(" Biomes.xls"); - SaveBiomes(); - LOG(" BlockTypes.xls"); - SaveBlockTypes(); - LOG(" BiomeBlockTypes.xls"); - SaveBiomeBlockTypes(); - LOG(" Spawners.xls"); - SaveSpawners(); -} - - - - - -void cStatisticsFactory::JoinResults(void) -{ - for (cCallbacks::iterator itr = m_Callbacks.begin(), end = m_Callbacks.end(); itr != end; ++itr) - { - m_CombinedStats.Add(((cStatistics *)(*itr))->GetStats()); - } // for itr - m_Callbacks[] -} - - - - - -void cStatisticsFactory::SaveBiomes(void) -{ - cFile f; - if (!f.Open("Biomes.xls", cFile::fmWrite)) - { - LOG("Cannot write to file Biomes.xls. Statistics not written."); - return; - } - double TotalColumns = (double)(m_CombinedStats.m_BiomeNumChunks) * 16 * 16 / 100; // Total number of columns processed; convert into percent - if (TotalColumns < 1) - { - // Avoid division by zero - TotalColumns = 1; - } - for (int i = 0; i <= 255; i++) - { - AString Line; - Printf(Line, "%s\t%d\t%llu\t%.05f\n", GetBiomeString(i), i, m_CombinedStats.m_BiomeCounts[i], ((double)(m_CombinedStats.m_BiomeCounts[i])) / TotalColumns); - f.Write(Line.c_str(), Line.length()); - } -} - - - - - -void cStatisticsFactory::SaveBlockTypes(void) -{ - cFile f; - if (!f.Open("BlockTypes.xls", cFile::fmWrite)) - { - LOG("Cannot write to file Biomes.xls. Statistics not written."); - return; - } - double TotalBlocks = ((double)(m_CombinedStats.m_BlockNumChunks)) * 16 * 16 * 256 / 100; // Total number of blocks processed; convert into percent - if (TotalBlocks < 1) - { - // Avoid division by zero - TotalBlocks = 1; - } - for (int i = 0; i <= 255; i++) - { - UInt64 Count = 0; - for (int Biome = 0; Biome <= 255; ++Biome) - { - Count += m_CombinedStats.m_BlockCounts[Biome][i]; - } - AString Line; - Printf(Line, "%s\t%d\t%llu\t%.08f\n", GetBlockTypeString(i), i, Count, ((double)Count) / TotalBlocks); - f.Write(Line.c_str(), Line.length()); - } -} - - - - - -void cStatisticsFactory::SaveBiomeBlockTypes(void) -{ - // Export as two tables: biomes 0-127 and 128-255, because OpenOffice doesn't support more than 256 columns - cFile f; - if (!f.Open("BiomeBlockTypes.xls", cFile::fmWrite)) - { - 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++) - { - const char * BiomeName = GetBiomeString(Biome); - if ((BiomeName != NULL) && (BiomeName[0] != 0)) - { - AppendPrintf(Header, "\t%s (%d)", BiomeName, Biome); - } - else - { - AppendPrintf(Header, "\t%d", Biome); - } - } - Header.append("\n"); - f.Write(Header.c_str(), Header.length()); - - for (int BlockType = 0; BlockType <= 255; BlockType++) - { - AString Line; - Printf(Line, "%s\t%d", GetBlockTypeString(BlockType), BlockType); - for (int Biome = 0; Biome <= 127; Biome++) - { - AppendPrintf(Line, "\t%llu", m_CombinedStats.m_BlockCounts[Biome][BlockType]); - } - Line.append("\n"); - f.Write(Line.c_str(), Line.length()); - } - - Header.assign("\n\nBiomes 127-255:\nBlockType\tBlockType"); - for (int Biome = 0; Biome <= 127; Biome++) - { - const char * BiomeName = GetBiomeString(Biome); - if ((BiomeName != NULL) && (BiomeName[0] != 0)) - { - AppendPrintf(Header, "\t%s (%d)", BiomeName, Biome); - } - else - { - AppendPrintf(Header, "\t%d", Biome); - } - } - Header.append("\n"); - f.Write(Header.c_str(), Header.length()); - - for (int BlockType = 0; BlockType <= 255; BlockType++) - { - AString Line; - Printf(Line, "%s\t%d", GetBlockTypeString(BlockType), BlockType); - for (int Biome = 128; Biome <= 255; Biome++) - { - AppendPrintf(Line, "\t%llu", m_CombinedStats.m_BlockCounts[Biome][BlockType]); - } - Line.append("\n"); - f.Write(Line.c_str(), Line.length()); - } -} - - - - - - -void cStatisticsFactory::SaveStatistics(void) -{ - cFile f; - if (!f.Open("Statistics.txt", cFile::fmWrite)) - { - 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); - if (Elapsed > 0) - { - f.Printf("Chunk processing speed: %.02f chunks per second\n", (double)(m_CombinedStats.m_TotalChunks) / Elapsed); - } - f.Printf("Biomes counted for %llu chunks.\n", m_CombinedStats.m_BiomeNumChunks); - f.Printf("Blocktypes counted for %llu chunks.\n", m_CombinedStats.m_BlockNumChunks); - f.Printf("Total blocks counted: %llu\n", m_CombinedStats.m_BlockNumChunks * 16 * 16 * 256); - f.Printf("Total biomes counted: %llu\n", m_CombinedStats.m_BiomeNumChunks * 16 * 16); - f.Printf("Total entities counted: %llu\n", m_CombinedStats.m_NumEntities); - f.Printf("Total tile entities counted: %llu\n", m_CombinedStats.m_NumTileEntities); - f.Printf("Total tile ticks counted: %llu\n", m_CombinedStats.m_NumTileTicks); - f.Printf("Chunk coord ranges:\n"); - f.Printf("\tX: %d .. %d\n", m_CombinedStats.m_MinChunkX, m_CombinedStats.m_MaxChunkX); - f.Printf("\tZ: %d .. %d\n", m_CombinedStats.m_MinChunkZ, m_CombinedStats.m_MaxChunkZ); -} - - - - - -void cStatisticsFactory::SaveSpawners(void) -{ - cFile f; - if (!f.Open("Spawners.xls", cFile::fmWrite)) - { - 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++) - { - f.Printf("%s\t%llu\t%0.4f\n", GetEntityTypeString((eEntityType)i), m_CombinedStats.m_SpawnerEntity[i], (double)(m_CombinedStats.m_SpawnerEntity[i]) / m_CombinedStats.m_BlockNumChunks); - } -} - - - - + +// Statistics.cpp + +// Implements the various statistics-collecting classes + +#include "Globals.h" +#include "Statistics.h" +#include "../../source/WorldStorage/FastNBT.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cStatistics::cStats: + +cStatistics::cStats::cStats(void) : + m_TotalChunks(0), + m_BiomeNumChunks(0), + m_BlockNumChunks(0), + m_NumEntities(0), + m_NumTileEntities(0), + m_NumTileTicks(0), + m_MinChunkX(0x7fffffff), + m_MaxChunkX(0x80000000), + m_MinChunkZ(0x7fffffff), + m_MaxChunkZ(0x80000000) +{ + memset(m_BiomeCounts, 0, sizeof(m_BiomeCounts)); + memset(m_BlockCounts, 0, sizeof(m_BlockCounts)); + memset(m_SpawnerEntity, 0, sizeof(m_SpawnerEntity)); +} + + + + + +void cStatistics::cStats::Add(const cStatistics::cStats & a_Stats) +{ + for (int i = 0; i <= 255; i++) + { + m_BiomeCounts[i] += a_Stats.m_BiomeCounts[i]; + } + for (int i = 0; i <= 255; i++) + { + for (int j = 0; j <= 255; j++) + { + m_BlockCounts[i][j] += a_Stats.m_BlockCounts[i][j]; + } + } + for (int i = 0; i < ARRAYCOUNT(m_SpawnerEntity); i++) + { + m_SpawnerEntity[i] += a_Stats.m_SpawnerEntity[i]; + } + m_BiomeNumChunks += a_Stats.m_BiomeNumChunks; + m_BlockNumChunks += a_Stats.m_BlockNumChunks; + m_TotalChunks += a_Stats.m_TotalChunks; + m_NumEntities += a_Stats.m_NumEntities; + m_NumTileEntities += a_Stats.m_NumTileEntities; + m_NumTileTicks += a_Stats.m_NumTileTicks; + UpdateCoordsRange(a_Stats.m_MinChunkX, a_Stats.m_MinChunkZ); + UpdateCoordsRange(a_Stats.m_MinChunkX, a_Stats.m_MinChunkZ); +} + + + + + +void cStatistics::cStats::UpdateCoordsRange(int a_ChunkX, int a_ChunkZ) +{ + if (a_ChunkX < m_MinChunkX) + { + m_MinChunkX = a_ChunkX; + } + if (a_ChunkX > m_MaxChunkX) + { + m_MaxChunkX = a_ChunkX; + } + if (a_ChunkZ < m_MinChunkZ) + { + m_MinChunkZ = a_ChunkZ; + } + if (a_ChunkZ > m_MaxChunkZ) + { + m_MaxChunkZ = a_ChunkZ; + } +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cStatistics: + +cStatistics::cStatistics(void) +{ +} + + + + + +bool cStatistics::OnNewChunk(int a_ChunkX, int a_ChunkZ) +{ + m_Stats.m_TotalChunks++; + m_Stats.UpdateCoordsRange(a_ChunkX, a_ChunkZ); + m_IsBiomesValid = false; + m_IsFirstSectionInChunk = true; + return false; +} + + + + + +bool cStatistics::OnBiomes(const unsigned char * a_BiomeData) +{ + for (int i = 0; i < 16 * 16; i++) + { + m_Stats.m_BiomeCounts[a_BiomeData[i]] += 1; + } + m_Stats.m_BiomeNumChunks += 1; + memcpy(m_BiomeData, a_BiomeData, sizeof(m_BiomeData)); + m_IsBiomesValid = true; + return false; +} + + + + + + +bool cStatistics::OnSection +( + unsigned char a_Y, + const BLOCKTYPE * a_BlockTypes, + const NIBBLETYPE * a_BlockAdditional, + const NIBBLETYPE * a_BlockMeta, + const NIBBLETYPE * a_BlockLight, + const NIBBLETYPE * a_BlockSkyLight +) +{ + if (!m_IsBiomesValid) + { + // 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++) + { + for (int z = 0; z < 16; z++) + { + for (int x = 0; x < 16; x++) + { + unsigned char Biome = m_BiomeData[x + 16 * z]; // Cannot use cChunkDef, different datatype + unsigned char BlockType = cChunkDef::GetBlock(a_BlockTypes, x, y, z); + m_Stats.m_BlockCounts[Biome][BlockType] += 1; + } + } + } + + m_Stats.m_BlockNumChunks += m_IsFirstSectionInChunk ? 1 : 0; + m_IsFirstSectionInChunk = false; + + return false; +} + + + + + +bool cStatistics::OnEmptySection(unsigned char a_Y) +{ + if (!m_IsBiomesValid) + { + // The current biome data is not valid, we don't have the means for sorting the BlockTypes into per-biome arrays + return true; + } + + // Add air to all columns: + for (int z = 0; z < 16; z++) + { + for (int x = 0; x < 16; x++) + { + unsigned char Biome = m_BiomeData[x + 16 * z]; // Cannot use cChunkDef, different datatype + 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; +} + + + + + +bool cStatistics::OnEntity( + const AString & a_EntityType, + double a_PosX, double a_PosY, double a_PosZ, + double a_SpeedX, double a_SpeedY, double a_SpeedZ, + float a_Yaw, float a_Pitch, + float a_FallDistance, + short a_FireTicksLeft, + short a_AirTicks, + char a_IsOnGround, + cParsedNBT & a_NBT, + int a_NBTTag +) +{ + m_Stats.m_NumEntities += 1; + + // TODO + + return false; +} + + + + + +bool cStatistics::OnTileEntity( + const AString & a_EntityType, + int a_PosX, int a_PosY, int a_PosZ, + cParsedNBT & a_NBT, + int a_NBTTag +) +{ + m_Stats.m_NumTileEntities += 1; + + if (a_EntityType == "MobSpawner") + { + OnSpawner(a_NBT, a_NBTTag); + } + + return false; +} + + + + + +bool cStatistics::OnTileTick( + int a_BlockType, + int a_TicksLeft, + int a_PosX, int a_PosY, int a_PosZ +) +{ + m_Stats.m_NumTileTicks += 1; + return false; +} + + + + + +void cStatistics::OnSpawner(cParsedNBT & a_NBT, int a_TileEntityTag) +{ + int EntityIDTag = a_NBT.FindChildByName(a_TileEntityTag, "EntityId"); + if ((EntityIDTag < 0) || (a_NBT.GetType(EntityIDTag) != TAG_String)) + { + return; + } + eEntityType Ent = GetEntityType(a_NBT.GetString(EntityIDTag)); + if (Ent < ARRAYCOUNT(m_Stats.m_SpawnerEntity)) + { + m_Stats.m_SpawnerEntity[Ent] += 1; + } +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cStatisticsFactory: + +cStatisticsFactory::cStatisticsFactory(void) : + m_BeginTick(clock()) +{ +} + + + + + +cStatisticsFactory::~cStatisticsFactory() +{ + // Join the results together: + LOG("cStatistics:"); + LOG(" Joining results..."); + 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++) + { + for (int j = 0; j < 255; j++) + { + TotalBlocks += m_CombinedStats.m_BlockCounts[i][j]; + } + } + 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"); + SaveStatistics(); + LOG(" Biomes.xls"); + SaveBiomes(); + LOG(" BlockTypes.xls"); + SaveBlockTypes(); + LOG(" BiomeBlockTypes.xls"); + SaveBiomeBlockTypes(); + LOG(" Spawners.xls"); + SaveSpawners(); +} + + + + + +void cStatisticsFactory::JoinResults(void) +{ + for (cCallbacks::iterator itr = m_Callbacks.begin(), end = m_Callbacks.end(); itr != end; ++itr) + { + m_CombinedStats.Add(((cStatistics *)(*itr))->GetStats()); + } // for itr - m_Callbacks[] +} + + + + + +void cStatisticsFactory::SaveBiomes(void) +{ + cFile f; + if (!f.Open("Biomes.xls", cFile::fmWrite)) + { + LOG("Cannot write to file Biomes.xls. Statistics not written."); + return; + } + double TotalColumns = (double)(m_CombinedStats.m_BiomeNumChunks) * 16 * 16 / 100; // Total number of columns processed; convert into percent + if (TotalColumns < 1) + { + // Avoid division by zero + TotalColumns = 1; + } + for (int i = 0; i <= 255; i++) + { + AString Line; + Printf(Line, "%s\t%d\t%llu\t%.05f\n", GetBiomeString(i), i, m_CombinedStats.m_BiomeCounts[i], ((double)(m_CombinedStats.m_BiomeCounts[i])) / TotalColumns); + f.Write(Line.c_str(), Line.length()); + } +} + + + + + +void cStatisticsFactory::SaveBlockTypes(void) +{ + cFile f; + if (!f.Open("BlockTypes.xls", cFile::fmWrite)) + { + LOG("Cannot write to file Biomes.xls. Statistics not written."); + return; + } + double TotalBlocks = ((double)(m_CombinedStats.m_BlockNumChunks)) * 16 * 16 * 256 / 100; // Total number of blocks processed; convert into percent + if (TotalBlocks < 1) + { + // Avoid division by zero + TotalBlocks = 1; + } + for (int i = 0; i <= 255; i++) + { + UInt64 Count = 0; + for (int Biome = 0; Biome <= 255; ++Biome) + { + Count += m_CombinedStats.m_BlockCounts[Biome][i]; + } + AString Line; + Printf(Line, "%s\t%d\t%llu\t%.08f\n", GetBlockTypeString(i), i, Count, ((double)Count) / TotalBlocks); + f.Write(Line.c_str(), Line.length()); + } +} + + + + + +void cStatisticsFactory::SaveBiomeBlockTypes(void) +{ + // Export as two tables: biomes 0-127 and 128-255, because OpenOffice doesn't support more than 256 columns + cFile f; + if (!f.Open("BiomeBlockTypes.xls", cFile::fmWrite)) + { + 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++) + { + const char * BiomeName = GetBiomeString(Biome); + if ((BiomeName != NULL) && (BiomeName[0] != 0)) + { + AppendPrintf(Header, "\t%s (%d)", BiomeName, Biome); + } + else + { + AppendPrintf(Header, "\t%d", Biome); + } + } + Header.append("\n"); + f.Write(Header.c_str(), Header.length()); + + for (int BlockType = 0; BlockType <= 255; BlockType++) + { + AString Line; + Printf(Line, "%s\t%d", GetBlockTypeString(BlockType), BlockType); + for (int Biome = 0; Biome <= 127; Biome++) + { + AppendPrintf(Line, "\t%llu", m_CombinedStats.m_BlockCounts[Biome][BlockType]); + } + Line.append("\n"); + f.Write(Line.c_str(), Line.length()); + } + + Header.assign("\n\nBiomes 127-255:\nBlockType\tBlockType"); + for (int Biome = 0; Biome <= 127; Biome++) + { + const char * BiomeName = GetBiomeString(Biome); + if ((BiomeName != NULL) && (BiomeName[0] != 0)) + { + AppendPrintf(Header, "\t%s (%d)", BiomeName, Biome); + } + else + { + AppendPrintf(Header, "\t%d", Biome); + } + } + Header.append("\n"); + f.Write(Header.c_str(), Header.length()); + + for (int BlockType = 0; BlockType <= 255; BlockType++) + { + AString Line; + Printf(Line, "%s\t%d", GetBlockTypeString(BlockType), BlockType); + for (int Biome = 128; Biome <= 255; Biome++) + { + AppendPrintf(Line, "\t%llu", m_CombinedStats.m_BlockCounts[Biome][BlockType]); + } + Line.append("\n"); + f.Write(Line.c_str(), Line.length()); + } +} + + + + + + +void cStatisticsFactory::SaveStatistics(void) +{ + cFile f; + if (!f.Open("Statistics.txt", cFile::fmWrite)) + { + 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); + if (Elapsed > 0) + { + f.Printf("Chunk processing speed: %.02f chunks per second\n", (double)(m_CombinedStats.m_TotalChunks) / Elapsed); + } + f.Printf("Biomes counted for %llu chunks.\n", m_CombinedStats.m_BiomeNumChunks); + f.Printf("Blocktypes counted for %llu chunks.\n", m_CombinedStats.m_BlockNumChunks); + f.Printf("Total blocks counted: %llu\n", m_CombinedStats.m_BlockNumChunks * 16 * 16 * 256); + f.Printf("Total biomes counted: %llu\n", m_CombinedStats.m_BiomeNumChunks * 16 * 16); + f.Printf("Total entities counted: %llu\n", m_CombinedStats.m_NumEntities); + f.Printf("Total tile entities counted: %llu\n", m_CombinedStats.m_NumTileEntities); + f.Printf("Total tile ticks counted: %llu\n", m_CombinedStats.m_NumTileTicks); + f.Printf("Chunk coord ranges:\n"); + f.Printf("\tX: %d .. %d\n", m_CombinedStats.m_MinChunkX, m_CombinedStats.m_MaxChunkX); + f.Printf("\tZ: %d .. %d\n", m_CombinedStats.m_MinChunkZ, m_CombinedStats.m_MaxChunkZ); +} + + + + + +void cStatisticsFactory::SaveSpawners(void) +{ + cFile f; + if (!f.Open("Spawners.xls", cFile::fmWrite)) + { + 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++) + { + f.Printf("%s\t%llu\t%0.4f\n", GetEntityTypeString((eEntityType)i), m_CombinedStats.m_SpawnerEntity[i], (double)(m_CombinedStats.m_SpawnerEntity[i]) / m_CombinedStats.m_BlockNumChunks); + } +} + + + + -- cgit v1.2.3