summaryrefslogtreecommitdiffstats
path: root/src/Root.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Root.cpp')
-rw-r--r--src/Root.cpp130
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)
+