diff options
Diffstat (limited to 'src/Root.cpp')
-rw-r--r-- | src/Root.cpp | 130 |
1 files changed, 82 insertions, 48 deletions
diff --git a/src/Root.cpp b/src/Root.cpp index 349608e8d..3ba391b7f 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -19,6 +19,11 @@ #include "LoggerListeners.h" #include "BuildInfo.h" #include "IniFile.h" +#include "SettingsRepositoryInterface.h" +#include "OverridesSettingsRepository.h" +#include "SelfTests.h" + +#include <iostream> #ifdef _WIN32 #include <conio.h> @@ -70,7 +75,7 @@ cRoot::~cRoot() void cRoot::InputThread(cRoot & a_Params) { cLogCommandOutputCallback Output; - + while (!cRoot::m_ShouldStop && !a_Params.m_bRestart && !m_TerminateEventRaised && std::cin.good()) { AString Command; @@ -96,24 +101,29 @@ void cRoot::InputThread(cRoot & a_Params) -void cRoot::Start(void) +void cRoot::Start(std::unique_ptr<cSettingsRepositoryInterface> overridesRepo) { #ifdef _WIN32 HWND hwnd = GetConsoleWindow(); HMENU hmenu = GetSystemMenu(hwnd, FALSE); EnableMenuItem(hmenu, SC_CLOSE, MF_GRAYED); // Disable close button when starting up; it causes problems with our CTRL-CLOSE handling #endif - - cLogger::cListener * consoleLogListener = MakeConsoleListener(); + + cLogger::cListener * consoleLogListener = MakeConsoleListener(m_RunAsService); cLogger::cListener * fileLogListener = new cFileListener(); cLogger::GetInstance().AttachListener(consoleLogListener); cLogger::GetInstance().AttachListener(fileLogListener); - - LOG("--- Started Log ---\n"); + + LOG("--- Started Log ---"); #ifdef BUILD_ID - LOG("MCServer " BUILD_SERIES_NAME " build id: " BUILD_ID); - LOG("from commit id: " BUILD_COMMIT_ID " built at: " BUILD_DATETIME); + LOG("MCServer " BUILD_SERIES_NAME " build id: " BUILD_ID); + LOG("from commit id: " BUILD_COMMIT_ID " built at: " BUILD_DATETIME); + #endif + + // Run the self-tests registered previously via cSelfTests::Register(): + #ifdef SELF_TEST + cSelfTests::ExecuteAll(); #endif cDeadlockDetect dd; @@ -130,22 +140,24 @@ void cRoot::Start(void) m_Server = new cServer(); LOG("Reading server config..."); - cIniFile IniFile; - if (!IniFile.ReadFile("settings.ini")) + + auto IniFile = cpp14::make_unique<cIniFile>(); + 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://wiki.mc-server.org/doku.php?id=configure:settings.ini for further configuration help"); + 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://wiki.mc-server.org/doku.php?id=configure:settings.ini for further configuration help"); } + auto settingsRepo = cpp14::make_unique<cOverridesSettingsRepository>(std::move(IniFile), std::move(overridesRepo)); LOG("Starting server..."); m_MojangAPI = new cMojangAPI; - bool ShouldAuthenticate = IniFile.GetValueSetB("Authentication", "Authenticate", true); - m_MojangAPI->Start(IniFile, ShouldAuthenticate); // Mojang API needs to be started before plugins, so that plugins may use it for DB upgrades on server init - if (!m_Server->InitServer(IniFile, ShouldAuthenticate)) + bool ShouldAuthenticate = settingsRepo->GetValueSetB("Authentication", "Authenticate", true); + m_MojangAPI->Start(*settingsRepo, ShouldAuthenticate); // Mojang API needs to be started before plugins, so that plugins may use it for DB upgrades on server init + if (!m_Server->InitServer(*settingsRepo, ShouldAuthenticate)) { - IniFile.WriteFile("settings.ini"); + settingsRepo->Flush(); LOGERROR("Failure starting server, aborting..."); return; } @@ -158,31 +170,31 @@ void cRoot::Start(void) m_RankManager->Initialize(*m_MojangAPI); m_CraftingRecipes = new cCraftingRecipes; m_FurnaceRecipe = new cFurnaceRecipe(); - + LOGD("Loading worlds..."); - LoadWorlds(IniFile); + LoadWorlds(*settingsRepo); LOGD("Loading plugin manager..."); m_PluginManager = new cPluginManager(); - m_PluginManager->ReloadPluginsNow(IniFile); - + m_PluginManager->ReloadPluginsNow(*settingsRepo); + LOGD("Loading MonsterConfig..."); m_MonsterConfig = new cMonsterConfig; // This sets stuff in motion LOGD("Starting Authenticator..."); - m_Authenticator.Start(IniFile); - + m_Authenticator.Start(*settingsRepo); + LOGD("Starting worlds..."); StartWorlds(); - - if (IniFile.GetValueSetB("DeadlockDetect", "Enabled", true)) + + if (settingsRepo->GetValueSetB("DeadlockDetect", "Enabled", true)) { LOGD("Starting deadlock detector..."); - dd.Start(IniFile.GetValueSetI("DeadlockDetect", "IntervalSec", 20)); + dd.Start(settingsRepo->GetValueSetI("DeadlockDetect", "IntervalSec", 20)); } - - IniFile.WriteFile("settings.ini"); + + settingsRepo->Flush(); LOGD("Finalising startup..."); if (m_Server->Start()) @@ -203,6 +215,10 @@ void cRoot::Start(void) #endif LOG("Startup complete, took %ldms!", static_cast<long int>(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - BeginTime).count())); + + // Save the current time + m_StartTime = std::chrono::steady_clock::now(); + #ifdef _WIN32 EnableMenuItem(hmenu, SC_CLOSE, MF_ENABLED); // Re-enable close button #endif @@ -247,9 +263,9 @@ void cRoot::Start(void) delete m_FurnaceRecipe; m_FurnaceRecipe = nullptr; delete m_CraftingRecipes; m_CraftingRecipes = nullptr; - LOGD("Unloading worlds..."); + LOG("Unloading worlds..."); UnloadWorlds(); - + LOGD("Stopping plugin manager..."); delete m_PluginManager; m_PluginManager = nullptr; @@ -260,9 +276,9 @@ void cRoot::Start(void) LOG("Shutdown successful!"); } - + LOG("--- Stopped Log ---"); - + cLogger::GetInstance().DetachListener(consoleLogListener); delete consoleLogListener; cLogger::GetInstance().DetachListener(fileLogListener); @@ -282,30 +298,29 @@ void cRoot::LoadGlobalSettings() -void cRoot::LoadWorlds(cIniFile & IniFile) +void cRoot::LoadWorlds(cSettingsRepositoryInterface & a_Settings) { // First get the default world - AString DefaultWorldName = IniFile.GetValueSet("Worlds", "DefaultWorld", "world"); + AString DefaultWorldName = a_Settings.GetValueSet("Worlds", "DefaultWorld", "world"); m_pDefaultWorld = new cWorld(DefaultWorldName.c_str()); m_WorldsByName[ DefaultWorldName ] = m_pDefaultWorld; // Then load the other worlds - int KeyNum = IniFile.FindKey("Worlds"); - int NumWorlds = IniFile.GetNumValues(KeyNum); - if (NumWorlds <= 0) + auto Worlds = a_Settings.GetValues("Worlds"); + if (Worlds.size() <= 0) { return; } - + bool FoundAdditionalWorlds = false; - for (int i = 0; i < NumWorlds; i++) + for (auto WorldNameValue : Worlds) { - AString ValueName = IniFile.GetValueName(KeyNum, i); + AString ValueName = WorldNameValue.first; if (ValueName.compare("World") != 0) { continue; } - AString WorldName = IniFile.GetValue(KeyNum, i); + AString WorldName = WorldNameValue.second; if (WorldName.empty()) { continue; @@ -317,10 +332,10 @@ void cRoot::LoadWorlds(cIniFile & IniFile) if (!FoundAdditionalWorlds) { - if (IniFile.GetKeyComment("Worlds", 0) != " World=secondworld") + if (a_Settings.GetKeyComment("Worlds", 0) != " World=secondworld") { - IniFile.DeleteKeyComment("Worlds", 0); - IniFile.AddKeyComment("Worlds", " World=secondworld"); + a_Settings.DeleteKeyComment("Worlds", 0); + a_Settings.AddKeyComment("Worlds", " World=secondworld"); } } } @@ -329,7 +344,7 @@ void cRoot::LoadWorlds(cIniFile & IniFile) -cWorld * cRoot::CreateAndInitializeWorld(const AString & a_WorldName, eDimension a_Dimension, const AString & a_OverworldName) +cWorld * cRoot::CreateAndInitializeWorld(const AString & a_WorldName, eDimension a_Dimension, const AString & a_OverworldName, bool a_InitSpawn) { cWorld * World = m_WorldsByName[a_WorldName]; if (World != nullptr) @@ -340,7 +355,10 @@ cWorld * cRoot::CreateAndInitializeWorld(const AString & a_WorldName, eDimension cWorld * NewWorld = new cWorld(a_WorldName.c_str(), a_Dimension, a_OverworldName); m_WorldsByName[a_WorldName] = NewWorld; NewWorld->Start(); - NewWorld->InitializeSpawn(); + if (a_InitSpawn) + { + NewWorld->InitializeSpawn(); + } m_PluginManager->CallHookWorldStarted(*NewWorld); return NewWorld; } @@ -551,6 +569,23 @@ void cRoot::SaveAllChunks(void) +void cRoot::SendPlayerLists(cPlayer * a_DestPlayer) +{ + for (const auto & itr : m_WorldsByName) + { + itr.second->SendPlayerList(a_DestPlayer); + } // for itr - m_WorldsByName[] +} + + + +void cRoot::BroadcastPlayerListsAddPlayer(const cPlayer & a_Player, const cClientHandle * a_Exclude) +{ + for (const auto & itr : m_WorldsByName) + { + itr.second->BroadcastPlayerListAddPlayer(a_Player); + } // for itr - m_WorldsByName[] +} void cRoot::BroadcastChat(const AString & a_Message, eMessageType a_ChatPrefix) @@ -575,8 +610,6 @@ void cRoot::BroadcastChat(const cCompositeChat & a_Message) - - bool cRoot::ForEachPlayer(cPlayerListCallback & a_Callback) { for (WorldMap::iterator itr = m_WorldsByName.begin(), itr2 = itr; itr != m_WorldsByName.end(); itr = itr2) @@ -851,3 +884,4 @@ int cRoot::GetFurnaceFuelBurnTime(const cItem & a_Fuel) + |