From 11e0c73ffd23a506c68ae351641a7ca74085ca81 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 24 Sep 2013 20:52:37 +0200 Subject: Implemented basic HTTP message header parsing. --- source/Root.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source/Root.cpp') diff --git a/source/Root.cpp b/source/Root.cpp index 3933535f1..823bd8e13 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -135,11 +135,9 @@ void cRoot::Start(void) { LOGWARNING("webadmin.ini inaccessible, wabadmin is disabled"); } - - if (WebIniFile.GetValueB("WebAdmin", "Enabled", false)) + else { - LOG("Creating WebAdmin..."); - m_WebAdmin = new cWebAdmin(8080); + m_WebServer.Initialize(WebIniFile); } LOG("Loading settings..."); -- cgit v1.2.3 From f4efcb90808603bbfce5a149f5490bd6fceb880f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 27 Sep 2013 18:14:26 +0200 Subject: Rewritten HTTPServer to split into cHTTPConnection, cHTTPRequest and cHTTPResponse classes. --- source/Root.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/Root.cpp') diff --git a/source/Root.cpp b/source/Root.cpp index 823bd8e13..821dd0928 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -137,7 +137,7 @@ void cRoot::Start(void) } else { - m_WebServer.Initialize(WebIniFile); + m_HTTPServer.Initialize(WebIniFile); } LOG("Loading settings..."); -- cgit v1.2.3 From cc5c56d545c0735d28a99b89d4970bd507608f7f Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 28 Sep 2013 20:36:01 +0100 Subject: Minor startup streamlining * LOGD'd unneeded debugging messages, streamlining startup + Added a basic timer for how long in seconds it took to start up + Added two checks for plural (plugin/s, second/s) --- source/Root.cpp | 64 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 23 deletions(-) (limited to 'source/Root.cpp') diff --git a/source/Root.cpp b/source/Root.cpp index 3933535f1..24ff77e42 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -21,6 +21,7 @@ #include "../iniFile/iniFile.h" #include +#include @@ -91,6 +92,17 @@ void cRoot::InputThread(void * a_Params) void cRoot::Start(void) { + time_t timer; + struct tm y2k; + double seconds; + double finishseconds; + + y2k.tm_hour = 0; y2k.tm_min = 0; y2k.tm_sec = 0; + y2k.tm_year = 100; y2k.tm_mon = 0; y2k.tm_mday = 1; + + time(&timer); + seconds = difftime(timer,mktime(&y2k)); + cDeadlockDetect dd; delete m_Log; m_Log = new cMCLogger(); @@ -125,7 +137,7 @@ void cRoot::Start(void) LOG("Starting server..."); if (!m_Server->InitServer(IniFile)) { - LOGERROR("Failed to start server, shutting down."); + LOGERROR("Failure starting server, aborting..."); return; } IniFile.WriteFile(); @@ -138,45 +150,51 @@ void cRoot::Start(void) if (WebIniFile.GetValueB("WebAdmin", "Enabled", false)) { - LOG("Creating WebAdmin..."); + LOGD("Creating WebAdmin..."); m_WebAdmin = new cWebAdmin(8080); } - LOG("Loading settings..."); + LOGD("Loading settings..."); m_GroupManager = new cGroupManager(); m_CraftingRecipes = new cCraftingRecipes; m_FurnaceRecipe = new cFurnaceRecipe(); - LOG("Loading worlds..."); + LOGD("Loading worlds..."); LoadWorlds(); - LOG("Loading plugin manager..."); + LOGD("Loading plugin manager..."); m_PluginManager = new cPluginManager(); m_PluginManager->ReloadPluginsNow(); - LOG("Loading MonsterConfig..."); + LOGD("Loading MonsterConfig..."); m_MonsterConfig = new cMonsterConfig; // This sets stuff in motion - LOG("Starting Authenticator..."); + LOGD("Starting Authenticator..."); m_Authenticator.Start(); - LOG("Starting worlds..."); + LOGD("Starting worlds..."); StartWorlds(); - LOG("Starting deadlock detector..."); + LOGD("Starting deadlock detector..."); dd.Start(); - LOG("Starting server..."); + LOGD("Finalising startup..."); m_Server->Start(); #if !defined(ANDROID_NDK) - LOG("Starting InputThread..."); + LOGD("Starting InputThread..."); m_InputThread = new cThread( InputThread, this, "cRoot::InputThread" ); m_InputThread->Start( false ); // We should NOT wait? Otherwise we canīt stop the server from other threads than the input thread #endif - LOG("Initialization done, server running now."); + time(&timer); + finishseconds = difftime(timer,mktime(&y2k)); + finishseconds -= seconds; + + if ((finishseconds > 1) || (finishseconds == 0)) { LOG("Startup complete, took %.f seconds!", finishseconds); } + else { LOG("Startup complete, took 1 second!"); } + while (!m_bStop && !m_bRestart) // These are modified by external threads { cSleep::MilliSleep(1000); @@ -190,37 +208,37 @@ void cRoot::Start(void) LOG("Shutting down server..."); m_Server->Shutdown(); - LOG("Shutting down deadlock detector..."); + LOGD("Shutting down deadlock detector..."); dd.Stop(); - LOG("Stopping world threads..."); + LOGD("Stopping world threads..."); StopWorlds(); - LOG("Stopping authenticator..."); + LOGD("Stopping authenticator..."); m_Authenticator.Stop(); - LOG("Freeing MonsterConfig..."); + LOGD("Freeing MonsterConfig..."); delete m_MonsterConfig; m_MonsterConfig = NULL; - LOG("Stopping WebAdmin..."); + LOGD("Stopping WebAdmin..."); delete m_WebAdmin; m_WebAdmin = NULL; - LOG("Unloading recipes..."); + LOGD("Unloading recipes..."); delete m_FurnaceRecipe; m_FurnaceRecipe = NULL; delete m_CraftingRecipes; m_CraftingRecipes = NULL; - LOG("Forgetting groups..."); + LOGD("Forgetting groups..."); delete m_GroupManager; m_GroupManager = 0; - LOG("Unloading worlds..."); + LOGD("Unloading worlds..."); UnloadWorlds(); - LOG("Stopping plugin manager..."); + LOGD("Stopping plugin manager..."); delete m_PluginManager; m_PluginManager = NULL; cItemHandler::Deinit(); cBlockHandler::Deinit(); - LOG("Destroying server..."); + LOG("Cleaning up..."); //delete HeartBeat; HeartBeat = 0; delete m_Server; m_Server = 0; - LOG("Shutdown done."); + LOG("Shutdown successful!"); } delete m_Log; m_Log = 0; -- cgit v1.2.3 From 9c7cfd29ad435d98ab70ad32282b9ec4dac666cd Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 29 Sep 2013 21:37:50 +0100 Subject: Improvements to startup timer As suggested by xoft. Also reverted changes of displayed protocol version. --- source/Root.cpp | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) (limited to 'source/Root.cpp') diff --git a/source/Root.cpp b/source/Root.cpp index 24ff77e42..c33af52ad 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -17,11 +17,11 @@ #include "Protocol/ProtocolRecognizer.h" // for protocol version constants #include "CommandOutput.h" #include "DeadlockDetect.h" +#include "OSSupport/Timer.h" #include "../iniFile/iniFile.h" #include -#include @@ -92,16 +92,9 @@ void cRoot::InputThread(void * a_Params) void cRoot::Start(void) { - time_t timer; - struct tm y2k; - double seconds; - double finishseconds; + cTimer Time; - y2k.tm_hour = 0; y2k.tm_min = 0; y2k.tm_sec = 0; - y2k.tm_year = 100; y2k.tm_mon = 0; y2k.tm_mday = 1; - - time(&timer); - seconds = difftime(timer,mktime(&y2k)); + long long mseconds = Time.GetNowTime(); cDeadlockDetect dd; delete m_Log; @@ -188,12 +181,11 @@ void cRoot::Start(void) m_InputThread->Start( false ); // We should NOT wait? Otherwise we canīt stop the server from other threads than the input thread #endif - time(&timer); - finishseconds = difftime(timer,mktime(&y2k)); - finishseconds -= seconds; + long long finishmseconds = Time.GetNowTime(); + finishmseconds -= mseconds; - if ((finishseconds > 1) || (finishseconds == 0)) { LOG("Startup complete, took %.f seconds!", finishseconds); } - else { LOG("Startup complete, took 1 second!"); } + if ((finishmseconds > 1) || (finishmseconds == 0)) { LOG("Startup complete, took %i miliseconds!", finishmseconds); } // Milisecs, why not :P + else { LOG("Startup complete, took 1 milisecond!"); } while (!m_bStop && !m_bRestart) // These are modified by external threads { -- cgit v1.2.3 From 20902e125c9b042ff77ddf4419e3eb9474de674e Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 30 Sep 2013 21:17:52 +0100 Subject: Removed unneeded statement Also LOGINFO'd "Starting WebAdmin" --- source/Root.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source/Root.cpp') diff --git a/source/Root.cpp b/source/Root.cpp index c33af52ad..abe153b30 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -184,8 +184,7 @@ void cRoot::Start(void) long long finishmseconds = Time.GetNowTime(); finishmseconds -= mseconds; - if ((finishmseconds > 1) || (finishmseconds == 0)) { LOG("Startup complete, took %i miliseconds!", finishmseconds); } // Milisecs, why not :P - else { LOG("Startup complete, took 1 milisecond!"); } + LOG("Startup complete, took %i ms!", finishmseconds); while (!m_bStop && !m_bRestart) // These are modified by external threads { -- cgit v1.2.3 From b5c90d7b20fede4e643e96417684c7c009d063cb Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 5 Oct 2013 23:08:16 +0200 Subject: WebAdmin uses the new HTTP functionality. This is a partial implementation of #183. --- source/Root.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'source/Root.cpp') diff --git a/source/Root.cpp b/source/Root.cpp index 821dd0928..57e5dfcc4 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -130,15 +130,9 @@ void cRoot::Start(void) } IniFile.WriteFile(); - cIniFile WebIniFile("webadmin.ini"); - if (!WebIniFile.ReadFile()) - { - LOGWARNING("webadmin.ini inaccessible, wabadmin is disabled"); - } - else - { - m_HTTPServer.Initialize(WebIniFile); - } + LOG("Initialising WebAdmin..."); + m_WebAdmin = new cWebAdmin(); + m_WebAdmin->Init(); LOG("Loading settings..."); m_GroupManager = new cGroupManager(); @@ -167,6 +161,9 @@ void cRoot::Start(void) LOG("Starting server..."); m_Server->Start(); + + LOG("Starting WebAdmin..."); + m_WebAdmin->Start(); #if !defined(ANDROID_NDK) LOG("Starting InputThread..."); -- cgit v1.2.3 From 68605b6dce17d48687006b0aec9b308774e4f894 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 7 Oct 2013 10:45:42 +0200 Subject: Fixed startup timings on server restart. --- source/Root.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source/Root.cpp') diff --git a/source/Root.cpp b/source/Root.cpp index abe153b30..c2a402b7f 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -92,10 +92,6 @@ void cRoot::InputThread(void * a_Params) void cRoot::Start(void) { - cTimer Time; - - long long mseconds = Time.GetNowTime(); - cDeadlockDetect dd; delete m_Log; m_Log = new cMCLogger(); @@ -103,6 +99,9 @@ void cRoot::Start(void) m_bStop = false; while (!m_bStop) { + cTimer Time; + long long mseconds = Time.GetNowTime(); + m_bRestart = false; LoadGlobalSettings(); -- cgit v1.2.3 From a120507be027ba18d5443e76061b47e0c624f229 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 8 Oct 2013 20:12:34 +0200 Subject: Implemented the two memory-statistics functions in cRoot. This fixes #185. cWebAdmin::GetMemoryUsage() is accessible but deprecated (with a warning output to the screen). --- source/Root.cpp | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 2 deletions(-) (limited to 'source/Root.cpp') diff --git a/source/Root.cpp b/source/Root.cpp index 26e6d347d..290a5269a 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -21,13 +21,19 @@ #include "../iniFile/iniFile.h" -#include +#ifdef _WIN32 + #include +#elif defined(__linux__) + #include +#elif defined(__APPLE__) + #include +#endif -cRoot* cRoot::s_Root = 0; +cRoot* cRoot::s_Root = NULL; @@ -571,6 +577,110 @@ AString cRoot::GetProtocolVersionTextFromInt(int a_ProtocolVersion) +int cRoot::GetVirtualRAMUsage(void) +{ + #ifdef _WIN32 + PROCESS_MEMORY_COUNTERS_EX pmc; + if (GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS *)&pmc, sizeof(pmc))) + { + return (int)(pmc.PrivateUsage / 1024); + } + return -1; + #elif defined(__linux__) + // Code adapted from http://stackoverflow.com/questions/63166/how-to-determine-cpu-and-memory-consumption-from-inside-a-process + std::ifstream StatFile("/proc/self/status"); + if (!StatFile.good()) + { + return -1; + } + while (StatFile.good()) + { + AString Line; + std::getline(StatFile, Line); + if (strncmp(Line.c_str(), "VmSize:", 7) == 0) + { + int res = atoi(Line.c_str() + 8); + return (res == 0) ? -1 : res; // If parsing failed, return -1 + } + } + return -1; + #elif defined (__APPLE__) + // Code adapted from http://stackoverflow.com/questions/63166/how-to-determine-cpu-and-memory-consumption-from-inside-a-process + struct task_basic_info t_info; + mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; + + if (KERN_SUCCESS == task_info( + mach_task_self(), + TASK_BASIC_INFO, + (task_info_t)&t_info, + &t_info_count + )) + { + return (int)(t_info.virtual_size / 1024); + } + return -1; + #else + LOGINFO("%s: Unknown platform, cannot query memory usage", __FUNCTION__); + return -1; + #endif +} + + + + + +int cRoot::GetPhysicalRAMUsage(void) +{ + #ifdef _WIN32 + PROCESS_MEMORY_COUNTERS pmc; + if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) + { + return (int)(pmc.WorkingSetSize / 1024); + } + return -1; + #elif defined(__linux__) + // Code adapted from http://stackoverflow.com/questions/63166/how-to-determine-cpu-and-memory-consumption-from-inside-a-process + std::ifstream StatFile("/proc/self/status"); + if (!StatFile.good()) + { + return -1; + } + while (StatFile.good()) + { + AString Line; + std::getline(StatFile, Line); + if (strncmp(Line.c_str(), "VmRSS:", 7) == 0) + { + int res = atoi(Line.c_str() + 8); + return (res == 0) ? -1 : res; // If parsing failed, return -1 + } + } + return -1; + #elif defined (__APPLE__) + // Code adapted from http://stackoverflow.com/questions/63166/how-to-determine-cpu-and-memory-consumption-from-inside-a-process + struct task_basic_info t_info; + mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; + + if (KERN_SUCCESS == task_info( + mach_task_self(), + TASK_BASIC_INFO, + (task_info_t)&t_info, + &t_info_count + )) + { + return (int)(t_info.resident_size / 1024); + } + return -1; + #else + LOGINFO("%s: Unknown platform, cannot query memory usage", __FUNCTION__); + return -1; + #endif +} + + + + + void cRoot::LogChunkStats(cCommandOutputCallback & a_Output) { int SumNumValid = 0; -- cgit v1.2.3 From e6bb025a9fc0beafc65aa8131d8836105b3b2943 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 18 Oct 2013 12:50:35 +0200 Subject: Fixed webadmin logging. This fixes #262. --- source/Root.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'source/Root.cpp') diff --git a/source/Root.cpp b/source/Root.cpp index 290a5269a..1f6437784 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -140,7 +140,6 @@ void cRoot::Start(void) } IniFile.WriteFile(); - LOG("Initialising WebAdmin..."); m_WebAdmin = new cWebAdmin(); m_WebAdmin->Init(); @@ -172,7 +171,6 @@ void cRoot::Start(void) LOGD("Finalising startup..."); m_Server->Start(); - LOG("Starting WebAdmin..."); m_WebAdmin->Start(); #if !defined(ANDROID_NDK) @@ -210,7 +208,6 @@ void cRoot::Start(void) LOGD("Freeing MonsterConfig..."); delete m_MonsterConfig; m_MonsterConfig = NULL; - LOGD("Stopping WebAdmin..."); delete m_WebAdmin; m_WebAdmin = NULL; LOGD("Unloading recipes..."); delete m_FurnaceRecipe; m_FurnaceRecipe = NULL; -- cgit v1.2.3 From 9e9198e0907d3d6fd353c683478007f418d86dd8 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 25 Oct 2013 11:15:44 +0200 Subject: cIniFile doesn't store filename internally anymore. --- source/Root.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source/Root.cpp') diff --git a/source/Root.cpp b/source/Root.cpp index 1f6437784..f47de972c 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -116,8 +116,8 @@ void cRoot::Start(void) m_Server = new cServer(); LOG("Reading server config..."); - cIniFile IniFile("settings.ini"); - if (!IniFile.ReadFile()) + cIniFile IniFile; + if (!IniFile.ReadFile("settings.ini")) { LOGWARNING("settings.ini inaccessible, all settings are reset to default values"); } @@ -138,7 +138,7 @@ void cRoot::Start(void) LOGERROR("Failure starting server, aborting..."); return; } - IniFile.WriteFile(); + IniFile.WriteFile("settings.ini"); m_WebAdmin = new cWebAdmin(); m_WebAdmin->Init(); @@ -247,7 +247,8 @@ void cRoot::LoadGlobalSettings() void cRoot::LoadWorlds(void) { - cIniFile IniFile("settings.ini"); IniFile.ReadFile(); + cIniFile IniFile; + IniFile.ReadFile("settings.ini"); // Doesn't matter if success or not // First get the default world AString DefaultWorldName = IniFile.GetValueSet("Worlds", "DefaultWorld", "world"); -- cgit v1.2.3 From 77661f4c594190ff93de4924d62aaac9e112e8a2 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 26 Oct 2013 17:08:28 +0200 Subject: Both the LoadWorlds() function and cAuthenticator now use the cIniFile object from the Root::Start() function. --- source/Root.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'source/Root.cpp') diff --git a/source/Root.cpp b/source/Root.cpp index 1f6437784..df98c3537 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -149,7 +149,7 @@ void cRoot::Start(void) m_FurnaceRecipe = new cFurnaceRecipe(); LOGD("Loading worlds..."); - LoadWorlds(); + LoadWorlds(IniFile); LOGD("Loading plugin manager..."); m_PluginManager = new cPluginManager(); @@ -160,7 +160,7 @@ void cRoot::Start(void) // This sets stuff in motion LOGD("Starting Authenticator..."); - m_Authenticator.Start(); + m_Authenticator.Start(IniFile); LOGD("Starting worlds..."); StartWorlds(); @@ -245,10 +245,8 @@ void cRoot::LoadGlobalSettings() -void cRoot::LoadWorlds(void) +void cRoot::LoadWorlds(cIniFile IniFile) { - cIniFile IniFile("settings.ini"); IniFile.ReadFile(); - // First get the default world AString DefaultWorldName = IniFile.GetValueSet("Worlds", "DefaultWorld", "world"); m_pDefaultWorld = new cWorld( DefaultWorldName.c_str() ); -- cgit v1.2.3 From cb06f35cb80c2162c3b1e9e329fc81b5d8b417da Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 26 Oct 2013 19:47:12 +0200 Subject: Changed "cIniFile IniFile" to cIniFile & IniFile" --- source/Root.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/Root.cpp') diff --git a/source/Root.cpp b/source/Root.cpp index df98c3537..346bb2c9f 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -245,7 +245,7 @@ void cRoot::LoadGlobalSettings() -void cRoot::LoadWorlds(cIniFile IniFile) +void cRoot::LoadWorlds(cIniFile & IniFile) { // First get the default world AString DefaultWorldName = IniFile.GetValueSet("Worlds", "DefaultWorld", "world"); -- cgit v1.2.3 From a7d44d69ddd8bfd5cd749dc9bcdf23597ae6d1cd Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 27 Oct 2013 09:09:39 +0100 Subject: Authenticator doesn't save the ini file. Didn't load it -> shouldn't save it. --- source/Root.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source/Root.cpp') diff --git a/source/Root.cpp b/source/Root.cpp index 2397fc875..e992ff614 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -138,7 +138,6 @@ void cRoot::Start(void) LOGERROR("Failure starting server, aborting..."); return; } - IniFile.WriteFile("settings.ini"); m_WebAdmin = new cWebAdmin(); m_WebAdmin->Init(); @@ -162,6 +161,8 @@ void cRoot::Start(void) LOGD("Starting Authenticator..."); m_Authenticator.Start(IniFile); + IniFile.WriteFile("settings.ini"); + LOGD("Starting worlds..."); StartWorlds(); -- cgit v1.2.3 From e832736e0bf315585f873b43520d1d771930a1c2 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 4 Nov 2013 21:51:24 +0000 Subject: Autogeneration of settings.ini and webadmin.ini Fixes issue #75 --- source/Root.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'source/Root.cpp') diff --git a/source/Root.cpp b/source/Root.cpp index e992ff614..8ec94629b 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -119,8 +119,12 @@ void cRoot::Start(void) cIniFile IniFile; if (!IniFile.ReadFile("settings.ini")) { - LOGWARNING("settings.ini inaccessible, all settings are reset to default values"); + LOGWARN("Regenerating settings.ini, all settings will be reset"); + IniFile.AddHeaderComment(" This is the main server configuration"); + IniFile.AddHeaderComment(" Most of the settings here can be configured using the webadmin interface, if enabled in webadmin.ini"); + IniFile.AddHeaderComment(" See: http://www.mc-server.org/wiki/doku.php?id=configure:settings.ini for further configuration help"); } + m_PrimaryServerVersion = IniFile.GetValueI("Server", "PrimaryServerVersion", 0); if (m_PrimaryServerVersion == 0) { @@ -129,7 +133,7 @@ void cRoot::Start(void) else { // Make a note in the log that the primary server version is explicitly set in the ini file - LOGINFO("settings.ini: [Server].PrimaryServerVersion set to %d.", m_PrimaryServerVersion); + LOGINFO("Primary server version set explicitly to %d.", m_PrimaryServerVersion); } LOG("Starting server..."); @@ -152,7 +156,7 @@ void cRoot::Start(void) LOGD("Loading plugin manager..."); m_PluginManager = new cPluginManager(); - m_PluginManager->ReloadPluginsNow(); + m_PluginManager->ReloadPluginsNow(IniFile); LOGD("Loading MonsterConfig..."); m_MonsterConfig = new cMonsterConfig; @@ -261,6 +265,7 @@ void cRoot::LoadWorlds(cIniFile & IniFile) return; } + bool FoundAdditionalWorlds = false; for (unsigned int i = 0; i < NumWorlds; i++) { AString ValueName = IniFile.GetValueName(KeyNum, i ); @@ -273,9 +278,15 @@ void cRoot::LoadWorlds(cIniFile & IniFile) { continue; } + FoundAdditionalWorlds = true; cWorld* NewWorld = new cWorld( WorldName.c_str() ); m_WorldsByName[ WorldName ] = NewWorld; } // for i - Worlds + + if (!FoundAdditionalWorlds) + { + IniFile.AddKeyComment("Worlds", " World=secondworld"); + } } -- cgit v1.2.3 From 41451100c171af3c21e10141d6651b1ef89477b6 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 7 Nov 2013 22:33:46 +0000 Subject: Added hardcore client effect Also fixed multiple world comments issue. --- source/Root.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source/Root.cpp') diff --git a/source/Root.cpp b/source/Root.cpp index 8ec94629b..4760c3ef1 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -285,7 +285,10 @@ void cRoot::LoadWorlds(cIniFile & IniFile) if (!FoundAdditionalWorlds) { - IniFile.AddKeyComment("Worlds", " World=secondworld"); + if (IniFile.GetKeyComment("Worlds", 0) != " World=secondworld") + { + IniFile.AddKeyComment("Worlds", " World=secondworld"); + } } } -- cgit v1.2.3 From 09e4f041dd7e2f4a7384e374e88ffbb4b76b3789 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 10 Nov 2013 22:58:14 +0100 Subject: Fixed cRoot::FindAndDoWithPlayer(). Now /kick and /ban work. --- source/Root.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/Root.cpp') diff --git a/source/Root.cpp b/source/Root.cpp index 4760c3ef1..701832be7 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -547,9 +547,9 @@ bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallbac } if (Rating == NameLength) // Perfect match { - return false; + return true; } - return true; + return false; } public: -- cgit v1.2.3 From 90fc51c4d03a941035b07d9d303ec542ff257b8b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 15 Nov 2013 10:13:32 +0100 Subject: cRoot::SaveAllChunks() doesn't wait for the save (deadlocks). Rather, it only queues the save task onto each world's tick thread. --- source/Root.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/Root.cpp') diff --git a/source/Root.cpp b/source/Root.cpp index 701832be7..be5a0553c 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -489,7 +489,7 @@ void cRoot::SaveAllChunks(void) { for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr) { - itr->second->SaveAllChunks(); + itr->second->QueueSaveAllChunks(); } } -- cgit v1.2.3 From 675b4aa878f16291ce33fced48a2bc7425f635ae Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sun, 24 Nov 2013 14:19:41 +0000 Subject: Moved source to src --- source/Root.cpp | 744 -------------------------------------------------------- 1 file changed, 744 deletions(-) delete mode 100644 source/Root.cpp (limited to 'source/Root.cpp') diff --git a/source/Root.cpp b/source/Root.cpp deleted file mode 100644 index be5a0553c..000000000 --- a/source/Root.cpp +++ /dev/null @@ -1,744 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "Root.h" -#include "Server.h" -#include "World.h" -#include "WebAdmin.h" -#include "FurnaceRecipe.h" -#include "GroupManager.h" -#include "CraftingRecipes.h" -#include "PluginManager.h" -#include "MonsterConfig.h" -#include "Entities/Player.h" -#include "Blocks/BlockHandler.h" -#include "Items/ItemHandler.h" -#include "Chunk.h" -#include "Protocol/ProtocolRecognizer.h" // for protocol version constants -#include "CommandOutput.h" -#include "DeadlockDetect.h" -#include "OSSupport/Timer.h" - -#include "../iniFile/iniFile.h" - -#ifdef _WIN32 - #include -#elif defined(__linux__) - #include -#elif defined(__APPLE__) - #include -#endif - - - - - -cRoot* cRoot::s_Root = NULL; - - - - - -cRoot::cRoot() - : m_Server( NULL ) - , m_MonsterConfig( NULL ) - , m_GroupManager( NULL ) - , m_CraftingRecipes(NULL) - , m_FurnaceRecipe( NULL ) - , m_WebAdmin( NULL ) - , m_PluginManager( NULL ) - , m_Log( NULL ) - , m_bStop( false ) - , m_bRestart( false ) - , m_InputThread( NULL ) - , m_pDefaultWorld( NULL ) -{ - s_Root = this; -} - - - - - -cRoot::~cRoot() -{ - s_Root = 0; -} - - - - - -void cRoot::InputThread(void * a_Params) -{ - cRoot & self = *(cRoot*)a_Params; - - cLogCommandOutputCallback Output; - - while (!(self.m_bStop || self.m_bRestart) && std::cin.good()) - { - std::string Command; - std::getline(std::cin, Command); - if (!Command.empty()) - { - self.ExecuteConsoleCommand(Command, Output); - } - } - - if (!(self.m_bStop || self.m_bRestart)) - { - // We have come here because the std::cin has received an EOF and the server is still running; stop the server: - self.m_bStop = true; - } -} - - - - - -void cRoot::Start(void) -{ - cDeadlockDetect dd; - delete m_Log; - m_Log = new cMCLogger(); - - m_bStop = false; - while (!m_bStop) - { - cTimer Time; - long long mseconds = Time.GetNowTime(); - - m_bRestart = false; - - LoadGlobalSettings(); - - LOG("Creating new server instance..."); - m_Server = new cServer(); - - LOG("Reading server config..."); - cIniFile IniFile; - if (!IniFile.ReadFile("settings.ini")) - { - LOGWARN("Regenerating settings.ini, all settings will be reset"); - IniFile.AddHeaderComment(" This is the main server configuration"); - IniFile.AddHeaderComment(" Most of the settings here can be configured using the webadmin interface, if enabled in webadmin.ini"); - IniFile.AddHeaderComment(" See: http://www.mc-server.org/wiki/doku.php?id=configure:settings.ini for further configuration help"); - } - - m_PrimaryServerVersion = IniFile.GetValueI("Server", "PrimaryServerVersion", 0); - if (m_PrimaryServerVersion == 0) - { - m_PrimaryServerVersion = cProtocolRecognizer::PROTO_VERSION_LATEST; - } - else - { - // Make a note in the log that the primary server version is explicitly set in the ini file - LOGINFO("Primary server version set explicitly to %d.", m_PrimaryServerVersion); - } - - LOG("Starting server..."); - if (!m_Server->InitServer(IniFile)) - { - LOGERROR("Failure starting server, aborting..."); - return; - } - - m_WebAdmin = new cWebAdmin(); - m_WebAdmin->Init(); - - LOGD("Loading settings..."); - m_GroupManager = new cGroupManager(); - m_CraftingRecipes = new cCraftingRecipes; - m_FurnaceRecipe = new cFurnaceRecipe(); - - LOGD("Loading worlds..."); - LoadWorlds(IniFile); - - LOGD("Loading plugin manager..."); - m_PluginManager = new cPluginManager(); - m_PluginManager->ReloadPluginsNow(IniFile); - - LOGD("Loading MonsterConfig..."); - m_MonsterConfig = new cMonsterConfig; - - // This sets stuff in motion - LOGD("Starting Authenticator..."); - m_Authenticator.Start(IniFile); - - IniFile.WriteFile("settings.ini"); - - LOGD("Starting worlds..."); - StartWorlds(); - - LOGD("Starting deadlock detector..."); - dd.Start(); - - LOGD("Finalising startup..."); - m_Server->Start(); - - m_WebAdmin->Start(); - - #if !defined(ANDROID_NDK) - LOGD("Starting InputThread..."); - m_InputThread = new cThread( InputThread, this, "cRoot::InputThread" ); - m_InputThread->Start( false ); // We should NOT wait? Otherwise we canīt stop the server from other threads than the input thread - #endif - - long long finishmseconds = Time.GetNowTime(); - finishmseconds -= mseconds; - - LOG("Startup complete, took %i ms!", finishmseconds); - - while (!m_bStop && !m_bRestart) // These are modified by external threads - { - cSleep::MilliSleep(1000); - } - - #if !defined(ANDROID_NDK) - delete m_InputThread; m_InputThread = NULL; - #endif - - // Deallocate stuffs - LOG("Shutting down server..."); - m_Server->Shutdown(); - - LOGD("Shutting down deadlock detector..."); - dd.Stop(); - - LOGD("Stopping world threads..."); - StopWorlds(); - - LOGD("Stopping authenticator..."); - m_Authenticator.Stop(); - - LOGD("Freeing MonsterConfig..."); - delete m_MonsterConfig; m_MonsterConfig = NULL; - delete m_WebAdmin; m_WebAdmin = NULL; - LOGD("Unloading recipes..."); - delete m_FurnaceRecipe; m_FurnaceRecipe = NULL; - delete m_CraftingRecipes; m_CraftingRecipes = NULL; - LOGD("Forgetting groups..."); - delete m_GroupManager; m_GroupManager = 0; - LOGD("Unloading worlds..."); - UnloadWorlds(); - - LOGD("Stopping plugin manager..."); - delete m_PluginManager; m_PluginManager = NULL; - - cItemHandler::Deinit(); - cBlockHandler::Deinit(); - - LOG("Cleaning up..."); - //delete HeartBeat; HeartBeat = 0; - delete m_Server; m_Server = 0; - LOG("Shutdown successful!"); - } - - delete m_Log; m_Log = 0; -} - - - - - -void cRoot::LoadGlobalSettings() -{ - // Nothing needed yet -} - - - - - -void cRoot::LoadWorlds(cIniFile & IniFile) -{ - // First get the default world - AString DefaultWorldName = IniFile.GetValueSet("Worlds", "DefaultWorld", "world"); - m_pDefaultWorld = new cWorld( DefaultWorldName.c_str() ); - m_WorldsByName[ DefaultWorldName ] = m_pDefaultWorld; - - // Then load the other worlds - unsigned int KeyNum = IniFile.FindKey("Worlds"); - unsigned int NumWorlds = IniFile.GetNumValues( KeyNum ); - if (NumWorlds <= 0) - { - return; - } - - bool FoundAdditionalWorlds = false; - for (unsigned int i = 0; i < NumWorlds; i++) - { - AString ValueName = IniFile.GetValueName(KeyNum, i ); - if (ValueName.compare("World") != 0) - { - continue; - } - AString WorldName = IniFile.GetValue(KeyNum, i ); - if (WorldName.empty()) - { - continue; - } - FoundAdditionalWorlds = true; - cWorld* NewWorld = new cWorld( WorldName.c_str() ); - m_WorldsByName[ WorldName ] = NewWorld; - } // for i - Worlds - - if (!FoundAdditionalWorlds) - { - if (IniFile.GetKeyComment("Worlds", 0) != " World=secondworld") - { - IniFile.AddKeyComment("Worlds", " World=secondworld"); - } - } -} - - - - - -void cRoot::StartWorlds(void) -{ - for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr) - { - itr->second->Start(); - itr->second->InitializeSpawn(); - } -} - - - - - -void cRoot::StopWorlds(void) -{ - for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr) - { - itr->second->Stop(); - } -} - - - - - -void cRoot::UnloadWorlds(void) -{ - m_pDefaultWorld = NULL; - for( WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr ) - { - delete itr->second; - } - m_WorldsByName.clear(); -} - - - - - -cWorld* cRoot::GetDefaultWorld() -{ - return m_pDefaultWorld; -} - - - - - -cWorld* cRoot::GetWorld( const AString & a_WorldName ) -{ - WorldMap::iterator itr = m_WorldsByName.find( a_WorldName ); - if( itr != m_WorldsByName.end() ) - return itr->second; - return 0; -} - - - - - -bool cRoot::ForEachWorld(cWorldListCallback & a_Callback) -{ - for (WorldMap::iterator itr = m_WorldsByName.begin(), itr2 = itr; itr != m_WorldsByName.end(); itr = itr2) - { - ++itr2; - if (a_Callback.Item(itr->second)) - { - return false; - } - } - return true; -} - - - - - -void cRoot::TickCommands(void) -{ - // Execute any pending commands: - cCommandQueue PendingCommands; - { - cCSLock Lock(m_CSPendingCommands); - std::swap(PendingCommands, m_PendingCommands); - } - for (cCommandQueue::iterator itr = PendingCommands.begin(), end = PendingCommands.end(); itr != end; ++itr) - { - ExecuteConsoleCommand(itr->m_Command, *(itr->m_Output)); - } -} - - - - - -void cRoot::QueueExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallback & a_Output) -{ - // Some commands are built-in: - if (a_Cmd == "stop") - { - m_bStop = true; - } - else if (a_Cmd == "restart") - { - m_bRestart = true; - } - - // Put the command into a queue (Alleviates FS #363): - cCSLock Lock(m_CSPendingCommands); - m_PendingCommands.push_back(cCommand(a_Cmd, &a_Output)); -} - - - - - -void cRoot::QueueExecuteConsoleCommand(const AString & a_Cmd) -{ - // Some commands are built-in: - if (a_Cmd == "stop") - { - m_bStop = true; - } - else if (a_Cmd == "restart") - { - m_bRestart = true; - } - - // Put the command into a queue (Alleviates FS #363): - cCSLock Lock(m_CSPendingCommands); - m_PendingCommands.push_back(cCommand(a_Cmd, new cLogCommandDeleteSelfOutputCallback)); -} - - - - - -void cRoot::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallback & a_Output) -{ - // Some commands are built-in: - if (a_Cmd == "stop") - { - m_bStop = true; - } - else if (a_Cmd == "restart") - { - m_bRestart = true; - } - - LOG("Executing console command: \"%s\"", a_Cmd.c_str()); - m_Server->ExecuteConsoleCommand(a_Cmd, a_Output); -} - - - - - -void cRoot::KickUser(int a_ClientID, const AString & a_Reason) -{ - m_Server->KickUser(a_ClientID, a_Reason); -} - - - - - -void cRoot::AuthenticateUser(int a_ClientID) -{ - m_Server->AuthenticateUser(a_ClientID); -} - - - - - -int cRoot::GetTotalChunkCount(void) -{ - int res = 0; - for ( WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr ) - { - res += itr->second->GetNumChunks(); - } - return res; -} - - - - - -void cRoot::SaveAllChunks(void) -{ - for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr) - { - itr->second->QueueSaveAllChunks(); - } -} - - - - - -void cRoot::BroadcastChat(const AString & a_Message) -{ - for (WorldMap::iterator itr = m_WorldsByName.begin(), end = m_WorldsByName.end(); itr != end; ++itr) - { - itr->second->BroadcastChat(a_Message); - } // for itr - m_WorldsByName[] -} - - - - - -bool cRoot::ForEachPlayer(cPlayerListCallback & a_Callback) -{ - for (WorldMap::iterator itr = m_WorldsByName.begin(), itr2 = itr; itr != m_WorldsByName.end(); itr = itr2) - { - ++itr2; - if (!itr->second->ForEachPlayer(a_Callback)) - { - return false; - } - } - return true; -} - - - - - -bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback) -{ - class cCallback : public cPlayerListCallback - { - unsigned int BestRating; - unsigned int NameLength; - const AString PlayerName; - - cPlayerListCallback & m_Callback; - virtual bool Item (cPlayer * a_pPlayer) - { - unsigned int Rating = RateCompareString (PlayerName, a_pPlayer->GetName()); - if (Rating > 0 && Rating >= BestRating) - { - BestMatch = a_pPlayer; - if( Rating > BestRating ) NumMatches = 0; - BestRating = Rating; - ++NumMatches; - } - if (Rating == NameLength) // Perfect match - { - return true; - } - return false; - } - - public: - cCallback (const AString & a_PlayerName, cPlayerListCallback & a_Callback) - : m_Callback( a_Callback ) - , BestMatch( NULL ) - , BestRating( 0 ) - , NumMatches( 0 ) - , NameLength( a_PlayerName.length() ) - , PlayerName( a_PlayerName ) - {} - - cPlayer * BestMatch; - unsigned int NumMatches; - } Callback (a_PlayerName, a_Callback); - ForEachPlayer( Callback ); - - if (Callback.NumMatches == 1) - { - return a_Callback.Item (Callback.BestMatch); - } - return false; -} - - - - - -AString cRoot::GetProtocolVersionTextFromInt(int a_ProtocolVersion) -{ - return cProtocolRecognizer::GetVersionTextFromInt(a_ProtocolVersion); -} - - - - - -int cRoot::GetVirtualRAMUsage(void) -{ - #ifdef _WIN32 - PROCESS_MEMORY_COUNTERS_EX pmc; - if (GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS *)&pmc, sizeof(pmc))) - { - return (int)(pmc.PrivateUsage / 1024); - } - return -1; - #elif defined(__linux__) - // Code adapted from http://stackoverflow.com/questions/63166/how-to-determine-cpu-and-memory-consumption-from-inside-a-process - std::ifstream StatFile("/proc/self/status"); - if (!StatFile.good()) - { - return -1; - } - while (StatFile.good()) - { - AString Line; - std::getline(StatFile, Line); - if (strncmp(Line.c_str(), "VmSize:", 7) == 0) - { - int res = atoi(Line.c_str() + 8); - return (res == 0) ? -1 : res; // If parsing failed, return -1 - } - } - return -1; - #elif defined (__APPLE__) - // Code adapted from http://stackoverflow.com/questions/63166/how-to-determine-cpu-and-memory-consumption-from-inside-a-process - struct task_basic_info t_info; - mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; - - if (KERN_SUCCESS == task_info( - mach_task_self(), - TASK_BASIC_INFO, - (task_info_t)&t_info, - &t_info_count - )) - { - return (int)(t_info.virtual_size / 1024); - } - return -1; - #else - LOGINFO("%s: Unknown platform, cannot query memory usage", __FUNCTION__); - return -1; - #endif -} - - - - - -int cRoot::GetPhysicalRAMUsage(void) -{ - #ifdef _WIN32 - PROCESS_MEMORY_COUNTERS pmc; - if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) - { - return (int)(pmc.WorkingSetSize / 1024); - } - return -1; - #elif defined(__linux__) - // Code adapted from http://stackoverflow.com/questions/63166/how-to-determine-cpu-and-memory-consumption-from-inside-a-process - std::ifstream StatFile("/proc/self/status"); - if (!StatFile.good()) - { - return -1; - } - while (StatFile.good()) - { - AString Line; - std::getline(StatFile, Line); - if (strncmp(Line.c_str(), "VmRSS:", 7) == 0) - { - int res = atoi(Line.c_str() + 8); - return (res == 0) ? -1 : res; // If parsing failed, return -1 - } - } - return -1; - #elif defined (__APPLE__) - // Code adapted from http://stackoverflow.com/questions/63166/how-to-determine-cpu-and-memory-consumption-from-inside-a-process - struct task_basic_info t_info; - mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; - - if (KERN_SUCCESS == task_info( - mach_task_self(), - TASK_BASIC_INFO, - (task_info_t)&t_info, - &t_info_count - )) - { - return (int)(t_info.resident_size / 1024); - } - return -1; - #else - LOGINFO("%s: Unknown platform, cannot query memory usage", __FUNCTION__); - return -1; - #endif -} - - - - - -void cRoot::LogChunkStats(cCommandOutputCallback & a_Output) -{ - int SumNumValid = 0; - int SumNumDirty = 0; - int SumNumInLighting = 0; - int SumNumInGenerator = 0; - int SumMem = 0; - for (WorldMap::iterator itr = m_WorldsByName.begin(), end = m_WorldsByName.end(); itr != end; ++itr) - { - cWorld * World = itr->second; - int NumInGenerator = World->GetGeneratorQueueLength(); - int NumInSaveQueue = World->GetStorageSaveQueueLength(); - int NumInLoadQueue = World->GetStorageLoadQueueLength(); - int NumValid = 0; - int NumDirty = 0; - int NumInLighting = 0; - World->GetChunkStats(NumValid, NumDirty, NumInLighting); - a_Output.Out("World %s:", World->GetName().c_str()); - a_Output.Out(" Num loaded chunks: %d", NumValid); - a_Output.Out(" Num dirty chunks: %d", NumDirty); - a_Output.Out(" Num chunks in lighting queue: %d", NumInLighting); - a_Output.Out(" Num chunks in generator queue: %d", NumInGenerator); - a_Output.Out(" Num chunks in storage load queue: %d", NumInLoadQueue); - a_Output.Out(" Num chunks in storage save queue: %d", NumInSaveQueue); - int Mem = NumValid * sizeof(cChunk); - a_Output.Out(" Memory used by chunks: %d KiB (%d MiB)", (Mem + 1023) / 1024, (Mem + 1024 * 1024 - 1) / (1024 * 1024)); - a_Output.Out(" Per-chunk memory size breakdown:"); - a_Output.Out(" block types: %6d bytes (%3d KiB)", sizeof(cChunkDef::BlockTypes), (sizeof(cChunkDef::BlockTypes) + 1023) / 1024); - a_Output.Out(" block metadata: %6d bytes (%3d KiB)", sizeof(cChunkDef::BlockNibbles), (sizeof(cChunkDef::BlockNibbles) + 1023) / 1024); - a_Output.Out(" block lighting: %6d bytes (%3d KiB)", 2 * sizeof(cChunkDef::BlockNibbles), (2 * sizeof(cChunkDef::BlockNibbles) + 1023) / 1024); - a_Output.Out(" heightmap: %6d bytes (%3d KiB)", sizeof(cChunkDef::HeightMap), (sizeof(cChunkDef::HeightMap) + 1023) / 1024); - a_Output.Out(" biomemap: %6d bytes (%3d KiB)", sizeof(cChunkDef::BiomeMap), (sizeof(cChunkDef::BiomeMap) + 1023) / 1024); - int Rest = sizeof(cChunk) - sizeof(cChunkDef::BlockTypes) - 3 * sizeof(cChunkDef::BlockNibbles) - sizeof(cChunkDef::HeightMap) - sizeof(cChunkDef::BiomeMap); - a_Output.Out(" other: %6d bytes (%3d KiB)", Rest, (Rest + 1023) / 1024); - SumNumValid += NumValid; - SumNumDirty += NumDirty; - SumNumInLighting += NumInLighting; - SumNumInGenerator += NumInGenerator; - SumMem += Mem; - } - a_Output.Out("Totals:"); - a_Output.Out(" Num loaded chunks: %d", SumNumValid); - a_Output.Out(" Num dirty chunks: %d", SumNumDirty); - a_Output.Out(" Num chunks in lighting queue: %d", SumNumInLighting); - a_Output.Out(" Num chunks in generator queue: %d", SumNumInGenerator); - a_Output.Out(" Memory used by chunks: %d KiB (%d MiB)", (SumMem + 1023) / 1024, (SumMem + 1024 * 1024 - 1) / (1024 * 1024)); -} - - - - -- cgit v1.2.3