From cead22a206617207d8f757b57e064eea39d0b2f2 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Sat, 29 Sep 2012 13:33:45 +0000 Subject: AnvilStats: Overall statistics and mobspawner statistics. git-svn-id: http://mc-server.googlecode.com/svn/trunk@899 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- AnvilStats/Statistics.cpp | 249 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 204 insertions(+), 45 deletions(-) (limited to 'AnvilStats/Statistics.cpp') diff --git a/AnvilStats/Statistics.cpp b/AnvilStats/Statistics.cpp index 7856fa9b1..f786cac79 100644 --- a/AnvilStats/Statistics.cpp +++ b/AnvilStats/Statistics.cpp @@ -5,22 +5,66 @@ #include "Globals.h" #include "Statistics.h" -#include "Utils.h" +#include "../source/WorldStorage/FastNBT.h" /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cStatistics: +// cStatistics::cStats: -cStatistics::cStatistics(void) : +cStatistics::cStats::cStats(void) : m_TotalChunks(0), m_BiomeNumChunks(0), - m_BlockNumChunks(0) + m_BlockNumChunks(0), + m_NumEntities(0), + m_NumTileEntities(0), + m_NumTileTicks(0) { 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; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cStatistics: + +cStatistics::cStatistics(void) +{ } @@ -29,7 +73,7 @@ cStatistics::cStatistics(void) : bool cStatistics::OnNewChunk(int a_ChunkX, int a_ChunkZ) { - m_TotalChunks++; + m_Stats.m_TotalChunks++; m_IsBiomesValid = false; m_IsFirstSectionInChunk = true; return false; @@ -43,9 +87,9 @@ bool cStatistics::OnBiomes(const unsigned char * a_BiomeData) { for (int i = 0; i < 16 * 16; i++) { - m_BiomeCounts[a_BiomeData[i]] += 1; + m_Stats.m_BiomeCounts[a_BiomeData[i]] += 1; } - m_BiomeNumChunks += 1; + m_Stats.m_BiomeNumChunks += 1; memcpy(m_BiomeData, a_BiomeData, sizeof(m_BiomeData)); m_IsBiomesValid = true; return false; @@ -80,12 +124,12 @@ bool cStatistics::OnSection { unsigned char Biome = m_BiomeData[x + 16 * z]; // Cannot use cChunkDef, different datatype unsigned char BlockType = cChunkDef::GetBlock(a_BlockTypes, x, y, z); - m_BlockCounts[Biome][BlockType] += 1; + m_Stats.m_BlockCounts[Biome][BlockType] += 1; } } } - m_BlockNumChunks += m_IsFirstSectionInChunk ? 1 : 0; + m_Stats.m_BlockNumChunks += m_IsFirstSectionInChunk ? 1 : 0; m_IsFirstSectionInChunk = false; return false; @@ -109,10 +153,72 @@ bool cStatistics::OnEmptySection(unsigned char a_Y) for (int x = 0; x < 16; x++) { unsigned char Biome = m_BiomeData[x + 16 * z]; // Cannot use cChunkDef, different datatype - m_BlockCounts[Biome][0] += 16; // 16 blocks in a column, all air + 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; } @@ -120,17 +226,44 @@ bool cStatistics::OnEmptySection(unsigned char a_Y) +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 %d chunks went through", m_TotalChunks); - LOG(" Biomes processed for %d chunks", m_BiomeNumChunks); + LOG(" Total %d chunks went through", m_CombinedStats.m_TotalChunks); + LOG(" Biomes processed for %d chunks", m_CombinedStats.m_BiomeNumChunks); // Check the number of blocks processed Int64 TotalBlocks = 0; @@ -138,20 +271,24 @@ cStatisticsFactory::~cStatisticsFactory() { for (int j = 0; j < 255; j++) { - TotalBlocks += m_BlockCounts[i][j]; + TotalBlocks += m_CombinedStats.m_BlockCounts[i][j]; } } - Int64 ExpTotalBlocks = (Int64)m_BlockNumChunks * 16LL * 16LL * 256LL; - LOG(" BlockIDs processed for %d chunks, %lld blocks (exp %lld; %s)", m_BlockNumChunks, TotalBlocks, ExpTotalBlocks, (TotalBlocks == ExpTotalBlocks) ? "match" : "failed"); + Int64 ExpTotalBlocks = (Int64)(m_CombinedStats.m_BlockNumChunks) * 16LL * 16LL * 256LL; + LOG(" BlockIDs processed for %d chunks, %lld blocks (exp %lld; %s)", m_CombinedStats.m_BlockNumChunks, TotalBlocks, ExpTotalBlocks, (TotalBlocks == ExpTotalBlocks) ? "match" : "failed"); // Save statistics: LOG(" Saving statistics into files:"); - LOG(" Biomes.txt"); + LOG(" Statistics.txt"); + SaveStatistics(); + LOG(" Biomes.xls"); SaveBiomes(); - LOG(" BlockTypes.txt"); + LOG(" BlockTypes.xls"); SaveBlockTypes(); - LOG(" BiomeBlockTypes.txt"); + LOG(" BiomeBlockTypes.xls"); SaveBiomeBlockTypes(); + LOG(" Spawners.xls"); + SaveSpawners(); } @@ -160,28 +297,9 @@ cStatisticsFactory::~cStatisticsFactory() void cStatisticsFactory::JoinResults(void) { - m_BiomeNumChunks = 0; - m_BlockNumChunks = 0; - m_TotalChunks = 0; - memset(m_BiomeCounts, 0, sizeof(m_BiomeCounts)); - memset(m_BlockCounts, 0, sizeof(m_BlockCounts)); for (cCallbacks::iterator itr = m_Callbacks.begin(), end = m_Callbacks.end(); itr != end; ++itr) { - cStatistics * stats = (cStatistics *)(*itr); - for (int i = 0; i <= 255; i++) - { - m_BiomeCounts[i] += stats->m_BiomeCounts[i]; - } - for (int i = 0; i <= 255; i++) - { - for (int j = 0; j <= 255; j++) - { - m_BlockCounts[i][j] += stats->m_BlockCounts[i][j]; - } - } - m_BiomeNumChunks += stats->m_BiomeNumChunks; - m_BlockNumChunks += stats->m_BlockNumChunks; - m_TotalChunks += stats->m_TotalChunks; + m_CombinedStats.Add(((cStatistics *)(*itr))->GetStats()); } // for itr - m_Callbacks[] } @@ -197,7 +315,7 @@ void cStatisticsFactory::SaveBiomes(void) LOG("Cannot write to file Biomes.xls. Statistics not written."); return; } - double TotalColumns = (double)m_BiomeNumChunks * 16 * 16; // Total number of columns processed + 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 @@ -206,7 +324,7 @@ void cStatisticsFactory::SaveBiomes(void) for (int i = 0; i <= 255; i++) { AString Line; - Printf(Line, "%s\t%d\t%d\t%.05f\n", GetBiomeString(i), i, m_BiomeCounts[i], ((double)m_BiomeCounts[i]) / TotalColumns); + Printf(Line, "%s\t%d\t%d\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()); } } @@ -223,7 +341,7 @@ void cStatisticsFactory::SaveBlockTypes(void) LOG("Cannot write to file Biomes.xls. Statistics not written."); return; } - double TotalBlocks = ((double)m_BlockNumChunks) * 16 * 16 * 256 / 100; // Total number of blocks processed + 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 @@ -234,13 +352,12 @@ void cStatisticsFactory::SaveBlockTypes(void) int Count = 0; for (int Biome = 0; Biome <= 255; ++Biome) { - Count += m_BlockCounts[Biome][i]; + Count += m_CombinedStats.m_BlockCounts[Biome][i]; } AString Line; Printf(Line, "%s\t%d\t%d\t%.08f\n", GetBlockTypeString(i), i, Count, ((double)Count) / TotalBlocks); f.Write(Line.c_str(), Line.length()); } - // TODO } @@ -282,7 +399,7 @@ void cStatisticsFactory::SaveBiomeBlockTypes(void) Printf(Line, "%s\t%d", GetBlockTypeString(BlockType), BlockType); for (int Biome = 0; Biome <= 127; Biome++) { - AppendPrintf(Line, "\t%d", m_BlockCounts[Biome][BlockType]); + AppendPrintf(Line, "\t%d", m_CombinedStats.m_BlockCounts[Biome][BlockType]); } Line.append("\n"); f.Write(Line.c_str(), Line.length()); @@ -310,7 +427,7 @@ void cStatisticsFactory::SaveBiomeBlockTypes(void) Printf(Line, "%s\t%d", GetBlockTypeString(BlockType), BlockType); for (int Biome = 128; Biome <= 255; Biome++) { - AppendPrintf(Line, "\t%d", m_BlockCounts[Biome][BlockType]); + AppendPrintf(Line, "\t%d", m_CombinedStats.m_BlockCounts[Biome][BlockType]); } Line.append("\n"); f.Write(Line.c_str(), Line.length()); @@ -321,3 +438,45 @@ void cStatisticsFactory::SaveBiomeBlockTypes(void) + +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: %d\n", m_CombinedStats.m_TotalChunks); + f.Printf("Chunk processing speed: %.02f chunks per second\n", (double)(m_CombinedStats.m_TotalChunks) / Elapsed); + f.Printf("Biomes counted for %d chunks.\n", m_CombinedStats.m_BiomeNumChunks); + f.Printf("Blocktypes counted for %d chunks.\n", m_CombinedStats.m_BlockNumChunks); + f.Printf("Total blocks counted: %lld\n", (Int64)(m_CombinedStats.m_BlockNumChunks) * 16 * 16 * 256); + f.Printf("Total biomes counted: %lld\n", (Int64)(m_CombinedStats.m_BiomeNumChunks) * 16 * 16); + f.Printf("Total entities counted: %d\n", m_CombinedStats.m_NumEntities); + f.Printf("Total tile entities counted: %d\n", m_CombinedStats.m_NumTileEntities); + f.Printf("Total tile ticks counted: %d\n", m_CombinedStats.m_NumTileTicks); +} + + + + + +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%d\t%0.4f\n", GetEntityTypeString((eEntityType)i), m_CombinedStats.m_SpawnerEntity[i], (double)(m_CombinedStats.m_SpawnerEntity[i]) / m_CombinedStats.m_BlockNumChunks); + } +} \ No newline at end of file -- cgit v1.2.3