12 #elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) 14 #if defined(__linux__) 16 #elif defined(__APPLE__) 17 #include <mach/mach.h> 37 #include "BuildInfo.h" 56 m_pDefaultWorld(nullptr),
58 m_MonsterConfig(nullptr),
59 m_CraftingRecipes(nullptr),
60 m_FurnaceRecipe(nullptr),
61 m_BrewingRecipes(nullptr),
63 m_PluginManager(nullptr),
92 timeval Timeout{ 0, 0 };
93 Timeout.tv_usec = 100 * 1000;
97 FD_SET(STDIN_FILENO, &ReadSet);
99 if (select(STDIN_FILENO + 1, &ReadSet,
nullptr,
nullptr, &Timeout) <= 0)
106 std::getline(std::cin, Command);
114 if (!Command.empty())
134 void cRoot::Start(std::unique_ptr<cSettingsRepositoryInterface> a_OverridesRepo)
137 HMENU ConsoleMenu = GetSystemMenu(GetConsoleWindow(), FALSE);
138 EnableMenuItem(ConsoleMenu, SC_CLOSE, MF_GRAYED);
145 if (!a_OverridesRepo->HasValue(
"Server",
"DisableLogFile"))
148 if (!fileLogListenerRet.first)
151 LOGERROR(
"Failed to open log file, aborting");
157 LOG(
"--- Started Log ---");
160 LOG(
"Cuberite " BUILD_SERIES_NAME
" build id: " BUILD_ID);
161 LOG(
"from commit id: " BUILD_COMMIT_ID
" built at: " BUILD_DATETIME);
165 auto BeginTime = std::chrono::steady_clock::now();
169 LOG(
"Creating new server instance...");
172 LOG(
"Reading server config...");
175 if (a_OverridesRepo->HasValue(
"Server",
"ConfigFile"))
180 auto IniFile = cpp14::make_unique<cIniFile>();
185 LOGWARN(
"Regenerating settings.ini, all settings will be reset");
186 IniFile->AddHeaderComment(
" This is the main server configuration");
187 IniFile->AddHeaderComment(
" Most of the settings here can be configured using the webadmin interface, if enabled in webadmin.ini");
190 auto settingsRepo = cpp14::make_unique<cOverridesSettingsRepository>(std::move(IniFile), std::move(a_OverridesRepo));
192 LOG(
"Starting server...");
197 LoadPalettes(settingsRepo->GetValueSet(
"Folders",
"ProtocolPalettes",
"Protocol"));
200 bool ShouldAuthenticate = settingsRepo->GetValueSetB(
"Authentication",
"Authenticate",
true);
201 m_MojangAPI->
Start(*settingsRepo, ShouldAuthenticate);
204 settingsRepo->Flush();
205 LOGERROR(
"Failure starting server, aborting...");
212 LOGD(
"Loading settings...");
219 LOGD(
"Loading worlds...");
222 LOGD(
"Loading plugin manager...");
226 LOGD(
"Loading MonsterConfig...");
230 LOGD(
"Starting Authenticator...");
233 LOGD(
"Starting worlds...");
236 if (settingsRepo->GetValueSetB(
"DeadlockDetect",
"Enabled",
true))
238 LOGD(
"Starting deadlock detector...");
239 dd.
Start(settingsRepo->GetValueSetI(
"DeadlockDetect",
"IntervalSec", 20));
242 settingsRepo->Flush();
244 LOGD(
"Finalising startup...");
249 LOGD(
"Starting InputThread...");
255 catch (std::system_error & a_Exception)
257 LOGERROR(
"cRoot::Start (std::thread) error %i: could not construct input thread; %s", a_Exception.code().value(), a_Exception.what());
260 LOG(
"Startup complete, took %ldms!", static_cast<long int>(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - BeginTime).count()));
266 EnableMenuItem(ConsoleMenu, SC_CLOSE, MF_ENABLED);
279 LOG(
"Shutting down server...");
286 EnableMenuItem(ConsoleMenu, SC_CLOSE, MF_ENABLED);
292 LOGD(
"Shutting down deadlock detector...");
295 LOGD(
"Stopping world threads...");
298 LOGD(
"Stopping authenticator...");
301 LOGD(
"Freeing MonsterConfig...");
305 LOGD(
"Unloading recipes...");
309 LOG(
"Unloading worlds...");
312 LOGD(
"Stopping plugin manager...");
317 LOG(
"Cleaning up...");
331 static_cast<WORD
>(MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC)),
341 if (WriteConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &Record, 1, &Length) == 0)
343 LOGWARN(
"Couldn't notify the input thread; the server will hang before shutdown!");
357 LOG(
"Shutdown successful!");
361 LOG(
"Shutdown successful - restarting...");
363 LOG(
"--- Stopped Log ---");
374 bool SentDisconnect =
false;
378 SentDisconnect =
true;
384 std::this_thread::sleep_for(std::chrono::seconds(1));
406 LOG(
"Loading UpgradeBlockTypePalette...");
410 if (paletteStr.empty())
412 throw std::runtime_error(
"File is empty");
417 catch (
const std::exception & exc)
419 LOGERROR(
"Failed to load the Upgrade block type palette from %s/UpgradeBlockTypePalette.txt: %s\nAborting",
420 aProtocolFolder, exc.what()
427 LOG(
"Loading per-protocol palettes...");
431 if (versions.empty())
433 LOGWARNING(
"No per-protocol palettes were loaded");
437 std::sort(versions.begin(), versions.end());
438 LOG(
"Loaded palettes for protocol versions: %s",
StringJoin(versions,
", "));
450 a_Settings.
AddValue(
"Worlds",
"DefaultWorld",
"world");
451 a_Settings.
AddValue(
"Worlds",
"World",
"world_nether");
452 a_Settings.
AddValue(
"Worlds",
"World",
"world_the_end");
453 a_Settings.
AddValue(
"WorldPaths",
"world",
"world");
454 a_Settings.
AddValue(
"WorldPaths",
"world_nether",
"world_nether");
455 a_Settings.
AddValue(
"WorldPaths",
"world_the_end",
"world_the_end");
457 AStringVector WorldNames{
"world",
"world_nether",
"world_the_end" };
466 auto Worlds = a_Settings.
GetValues(
"Worlds");
468 for (
const auto &
World : Worlds)
470 WorldNames.push_back(
World.second);
475 AString DefaultWorldPath = a_Settings.
GetValueSet(
"WorldPaths", DefaultWorldName, DefaultWorldName);
480 if (Worlds.size() <= 0)
507 bool FoundAdditionalWorlds =
false;
508 for (
auto WorldNameValue : Worlds)
510 AString ValueName = WorldNameValue.first;
511 if (ValueName.compare(
"World") != 0)
515 AString WorldName = WorldNameValue.second;
516 if (WorldName.empty())
520 FoundAdditionalWorlds =
true;
524 AString NetherAppend =
"_nether";
525 AString EndAppend1 =
"_the_end";
533 if ((LowercaseName.size() > NetherAppend.size()) && (LowercaseName.substr(LowercaseName.size() - NetherAppend.size()) == NetherAppend))
539 LinkTo = WorldName.substr(0, WorldName.size() - NetherAppend.size());
542 LinkTo = DefaultWorldName;
547 else if ((LowercaseName.size() > EndAppend1.size()) && (LowercaseName.substr(LowercaseName.size() - EndAppend1.size()) == EndAppend1))
553 LinkTo = WorldName.substr(0, WorldName.size() - EndAppend1.size());
556 LinkTo = DefaultWorldName;
561 else if ((LowercaseName.size() > EndAppend2.size()) && (LowercaseName.substr(LowercaseName.size() - EndAppend2.size()) == EndAppend2))
567 LinkTo = WorldName.substr(0, WorldName.size() - EndAppend2.size());
570 LinkTo = DefaultWorldName;
574 NewWorld =
new cWorld(WorldName.c_str(), WorldPath.c_str(), a_dd, WorldNames, Dimension, LinkTo);
575 m_WorldsByName[WorldName] = NewWorld;
578 if (!FoundAdditionalWorlds)
580 if (a_Settings.
GetKeyComment(
"Worlds", 0) !=
" World=secondworld")
596 itr->second->Start();
597 itr->second->InitializeSpawn();
610 itr->second->Stop(a_DeadlockDetect);
660 if (
World.second !=
nullptr)
662 if (a_Callback(*
World.second))
683 for (cCommandQueue::iterator itr = PendingCommands.begin(), end = PendingCommands.end(); itr != end; ++itr)
723 else if (a_Cmd ==
"restart")
730 LOG(
"Executing console command: \"%s\"", a_Cmd.c_str());
761 res +=
static_cast<int>(itr->second->GetNumChunks());
774 itr->second->QueueSaveAllChunks();
786 itr->second->SetSavingEnabled(a_SavingEnabled);
798 itr.second->SendPlayerList(a_DestPlayer);
810 itr.second->BroadcastPlayerListAddPlayer(a_Player);
822 itr.second->BroadcastPlayerListRemovePlayer(a_Player);
834 itr->second->BroadcastChat(a_Message,
nullptr, a_ChatPrefix);
846 itr->second->BroadcastChat(a_Message);
859 if (!itr->second->ForEachPlayer(a_Callback))
881 bool operator () (
cPlayer & a_Player)
884 if ((Rating > 0) && (Rating >= m_BestRating))
886 m_BestMatch = a_Player.
GetName();
887 if (Rating > m_BestRating)
891 m_BestRating = Rating;
894 if (Rating == m_NameLength)
901 cCallback (
const AString & a_CBPlayerName) :
903 m_NameLength(a_CBPlayerName.length()),
904 m_PlayerName(a_CBPlayerName),
910 unsigned m_NumMatches;
911 } Callback (a_PlayerName);
914 if (Callback.m_NumMatches == 1)
929 if (itr->second->DoWithPlayerByUUID(a_PlayerUUID, a_Callback))
945 if (
World.second->DoWithPlayer(a_PlayerName, a_Callback))
969 PROCESS_MEMORY_COUNTERS_EX pmc;
970 if (GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS *)&pmc,
sizeof(pmc)))
972 return (
int)(pmc.PrivateUsage / 1024);
975 #elif defined(__linux__) 977 std::ifstream StatFile(
"/proc/self/status");
978 if (!StatFile.good())
982 while (StatFile.good())
985 std::getline(StatFile, Line);
986 if (strncmp(Line.c_str(),
"VmSize:", 7) == 0)
988 int res = atoi(Line.c_str() + 8);
989 return (res == 0) ? -1 : res;
993 #elif defined (__APPLE__) 995 struct task_basic_info t_info;
996 mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
998 if (KERN_SUCCESS == task_info(
1001 reinterpret_cast<task_info_t>(&t_info),
1005 return static_cast<int>(t_info.virtual_size / 1024);
1009 LOGINFO(
"%s: Unknown platform, cannot query memory usage", __FUNCTION__);
1021 PROCESS_MEMORY_COUNTERS pmc;
1022 if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc,
sizeof(pmc)))
1024 return (
int)(pmc.WorkingSetSize / 1024);
1027 #elif defined(__linux__) 1029 std::ifstream StatFile(
"/proc/self/status");
1030 if (!StatFile.good())
1034 while (StatFile.good())
1037 std::getline(StatFile, Line);
1038 if (strncmp(Line.c_str(),
"VmRSS:", 6) == 0)
1040 int res = atoi(Line.c_str() + 7);
1041 return (res == 0) ? -1 : res;
1045 #elif defined (__APPLE__) 1047 struct task_basic_info t_info;
1048 mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
1050 if (KERN_SUCCESS == task_info(
1053 reinterpret_cast<task_info_t>(&t_info),
1057 return static_cast<int>(t_info.resident_size / 1024);
1061 LOGINFO(
"%s: Unknown platform, cannot query memory usage", __FUNCTION__);
1072 int SumNumValid = 0;
1073 int SumNumDirty = 0;
1074 int SumNumInLighting = 0;
1075 int SumNumInGenerator = 0;
1085 int NumInLighting = 0;
1087 a_Output.
Out(
"World %s:", World->
GetName().c_str());
1088 a_Output.
Out(
" Num loaded chunks: %d", NumValid);
1089 a_Output.
Out(
" Num dirty chunks: %d", NumDirty);
1090 a_Output.
Out(
" Num chunks in lighting queue: %d", NumInLighting);
1091 a_Output.
Out(
" Num chunks in generator queue: %d", NumInGenerator);
1092 a_Output.
Out(
" Num chunks in storage load queue: %d", NumInLoadQueue);
1093 a_Output.
Out(
" Num chunks in storage save queue: %d", NumInSaveQueue);
1094 int Mem = NumValid *
static_cast<int>(
sizeof(
cChunk));
1095 a_Output.
Out(
" Memory used by chunks: %d KiB (%d MiB)", (Mem + 1023) / 1024, (Mem + 1024 * 1024 - 1) / (1024 * 1024));
1096 a_Output.
Out(
" Per-chunk memory size breakdown:");
1102 SumNumValid += NumValid;
1103 SumNumDirty += NumDirty;
1104 SumNumInLighting += NumInLighting;
1105 SumNumInGenerator += NumInGenerator;
1108 a_Output.
Out(
"Totals:");
1109 a_Output.
Out(
" Num loaded chunks: %d", SumNumValid);
1110 a_Output.
Out(
" Num dirty chunks: %d", SumNumDirty);
1111 a_Output.
Out(
" Num chunks in lighting queue: %d", SumNumInLighting);
1112 a_Output.
Out(
" Num chunks in generator queue: %d", SumNumInGenerator);
1113 a_Output.
Out(
" Memory used by chunks: %d KiB (%d MiB)", (SumMem + 1023) / 1024, (SumMem + 1024 * 1024 - 1) / (1024 * 1024));
cAuthenticator m_Authenticator
BlockTypeRegistry m_BlockTypeRegistry
The storage for all registered block types.
cCriticalSection m_CSPendingCommands
std::unique_ptr< cRankManager > m_RankManager
void Set(void)
Sets the event - releases one thread that has been waiting in Wait().
void ExecuteConsoleCommand(const AString &a_Cmd, cCommandOutputCallback &a_Output)
Executes a console command through the cServer class; does special handling for "stop" and "restart"...
void ExecuteConsoleCommand(const AString &a_Cmd, cCommandOutputCallback &a_Output)
Executes the console command, sends output through the specified callback.
eDimension
Dimension of a world.
void LogChunkStats(cCommandOutputCallback &a_Output)
Writes chunkstats, for each world and totals, to the output callback.
cMonsterConfig * m_MonsterConfig
void BroadcastChat(const AString &a_Message, eMessageType a_ChatPrefix=mtCustom)
Sends a chat message to all connected clients (in all worlds)
cPluginManager * m_PluginManager
int GetTotalChunkCount(void)
Returns the number of chunks loaded.
static int GetPhysicalRAMUsage(void)
Returns the amount of virtual RAM used, in KiB.
std::vector< cCommand > cCommandQueue
BLOCKTYPE BlockTypes[NumBlocks]
The type used for block type operations and storage, AXIS_ORDER ordering.
AString StringJoin(const AStringVector &a_Strings, const AString &a_Delimeter)
Join a list of strings with the given delimiter between entries.
cClientHandlePtr GetClientHandlePtr(void) const
Returns the SharedPtr to client handle associated with the player.
virtual bool AddKeyComment(const AString &keyname, const AString &comment)=0
Add a key comment, will always fail if the repository does not support comments.
AString m_SettingsFilename
which ini file to load settings from, default is settings.ini
static float FASTBREAK_PERCENTAGE
The percentage how much a block has to be broken.
bool ForEachWorld(cWorldListCallback a_Callback)
Calls the callback for each world; returns true if the callback didn't abort (return true) ...
cAttachment AttachListener(std::unique_ptr< cListener > a_Listener)
bool Start(int a_IntervalSec)
Starts the detection.
static AString ReadWholeFile(const AString &a_FileName)
Returns the entire contents of the specified file as a string.
void Start(cSettingsRepositoryInterface &a_Settings, bool a_ShouldAuth)
Initializes the API; reads the settings from the specified ini file.
void QueueExecuteConsoleCommand(const AString &a_Cmd, cCommandOutputCallback &a_Output)
Queues a console command for execution through the cServer class.
cWorld * GetWorld(const AString &a_WorldName)
Returns a pointer to the world specified.
void StopServer()
Stops the server, as if "/stop" was typed in the console.
static char PathSeparator()
const AString & GetName(void) const
static void InputThread(cRoot &a_Params)
void UnloadWorlds(void)
Unloads all worlds from memory.
void RegisterAllBlockHandlers(BlockTypeRegistry &aRegistry)
Registers all the BlockHandler descendants in the specified registry.
void LOGERROR(const char *a_Format, fmt::ArgList a_ArgList)
void AuthenticateUser(int a_ClientID, const AString &a_Name, const cUUID &a_UUID, const Json::Value &a_Properties)
Called by cAuthenticator to auth the specified user.
std::thread m_InputThread
void SendPlayerLists(cPlayer *a_DestPlayer)
Send playerlist of all worlds to player.
Sends all command output to a log, line by line, when the command finishes processing.
void GetChunkStats(int &a_NumValid, int &a_NumDirty, int &a_NumInLightingQueue)
Returns the number of chunks loaded and dirty, and in the lighting queue.
Holds a palette that maps between block type + state and numbers.
static bool m_TerminateEventRaised
If something has told the server to stop; checked periodically in cRoot.
std::unique_ptr< cLogger::cListener > MakeConsoleListener(bool a_IsService)
std::vector< AString > AStringVector
Utilities to allow casting a cWorld to one of its interfaces without including World.h.
static bool m_RunAsService
If set to true, binary will attempt to run as a service on Windows.
std::pair< bool, std::unique_ptr< cLogger::cListener > > MakeFileListener()
static cLogger & GetInstance(void)
Container for a single chat message composed of multiple functional parts.
void LoadWorlds(cDeadlockDetect &a_dd, cSettingsRepositoryInterface &a_Settings, bool a_IsNewIniFile)
Loads the worlds from settings.ini, creates the worldmap.
void Wait(void)
Waits until the event has been set.
bool ForEachPlayer(cPlayerListCallback a_Callback)
Calls the callback for each player in all worlds.
void KickUser(int a_ClientID, const AString &a_Reason)
Kicks the user, no matter in what world they are.
void Out(const char *a_Fmt, fmt::ArgList)
Syntax sugar function, calls Out() with Printf()-ed parameters; appends a newline".
void KickUser(int a_ClientID, const AString &a_Reason)
void Stop(void)
Stops the HTTP server, if it was started.
cFurnaceRecipe * m_FurnaceRecipe
cCraftingRecipes * m_CraftingRecipes
Loads the protocol-specific palettes on startup and provides them to the individual protocol instance...
void SaveAllChunks(void)
Saves all chunks in all worlds.
void StartWorlds(cDeadlockDetect &a_DeadlockDetect)
Starts each world's life.
void LOGINFO(const char *a_Format, fmt::ArgList a_ArgList)
int GetBurnTime(const cItem &a_Fuel) const
Returns the amount of time that the specified fuel burns, in ticks.
virtual AString GetKeyComment(const AString &keyname, const int commentID) const =0
Return a key comment, returns "" for repositories that do not return comments.
void LOGWARNING(const char *a_Format, fmt::ArgList a_ArgList)
bool DoWithPlayerByUUID(const cUUID &a_PlayerUUID, cPlayerListCallback a_Callback)
Finds the player over his uuid and calls the callback.
virtual void AddValue(const AString &a_KeyName, const AString &a_ValueName, const AString &a_Value)=0
Adds a new value to the specified key.
bool FindAndDoWithPlayer(const AString &a_PlayerName, cPlayerListCallback a_Callback)
Finds a player from a partial or complete player name and calls the callback - case-insensitive.
void ReloadPluginsNow(void)
Reloads all plugins, defaulting to settings.ini for settings location.
virtual AString GetValueSet(const AString &keyname, const AString &valuename, const AString &defValue="")=0
Gets the value; if not found, write the default to the repository.
size_t GetStorageSaveQueueLength(void)
void Stop(void)
Signals the thread to terminate and waits until it's finished.
void Stop(void)
Stops the authenticator thread.
void BroadcastPlayerListsAddPlayer(const cPlayer &a_Player, const cClientHandle *a_Exclude=nullptr)
Broadcast playerlist addition through all worlds.
The root of the object hierarchy.
AString TrimString(const AString &str)
Trims whitespace at both ends of the string.
bool InitServer(cSettingsRepositoryInterface &a_Settings, bool a_ShouldAuth)
bool CallHookWorldStarted(cWorld &a_World)
cWorld * GetDefaultWorld(void)
std::atomic_flag m_InputThreadRunFlag
void TickCommands(void)
Executes commands queued in the command queue.
std::chrono::steady_clock::time_point m_StartTime
The current time where the startup of the server has been completed.
void BroadcastPlayerListsRemovePlayer(const cPlayer &a_Player, const cClientHandle *a_Exclude=nullptr)
Broadcast playerlist removal through all worlds.
const AString & GetName(void) const
Returns the name of the world.
virtual std::vector< std::pair< AString, AString > > GetValues(AString a_keyName)=0
returns a vector containing a name, value pair for each value under the key
static int GetFurnaceFuelBurnTime(const cItem &a_Fuel)
Returns the number of ticks for how long the item would fuel a furnace.
Sends all command output to a log, line by line; deletes self when command finishes processing...
std::unique_ptr< ProtocolPalettes > m_ProtocolPalettes
The per-protocol palettes manager.
bool DoWithPlayer(const AString &a_PlayerName, cPlayerListCallback a_Callback)
Finds the player using it's complete username and calls the callback.
void LOG(const char *a_Format, fmt::ArgList a_ArgList)
RAII for cCriticalSection - locks the CS on creation, unlocks on destruction.
int GetGeneratorQueueLength(void)
void SetSavingEnabled(bool a_SavingEnabled)
Sets whether saving chunks is enabled in all worlds (overrides however the worlds were already set) ...
virtual bool DeleteKeyComment(const AString &keyname, const int commentID)=0
Delete a key comment, will always fail if the repository does not support comments.
NIBBLETYPE BlockNibbles[NumBlocks/2]
The type used for block data in nibble format, AXIS_ORDER ordering.
cFurnaceRecipe * GetFurnaceRecipe(void)
static AString GetProtocolVersionTextFromInt(int a_ProtocolVersionNum)
Returns the textual description of the protocol version: 49 -> "1.4.4".
static AString GetVersionTextFromInt(int a_ProtocolVersion)
Translates protocol version number into protocol version text: 49 -> "1.4.4".
void TabCompleteUserName(const AString &a_Text, AStringVector &a_Results)
Appends all usernames starting with a_Text (case-insensitive) into Results.
void Start(std::unique_ptr< cSettingsRepositoryInterface > a_OverridesRepo)
bool Init(void)
Initializes the object.
void StopWorlds(cDeadlockDetect &a_DeadlockDetect)
Stops each world's threads, so that it's safe to unload them.
void LoadPalettes(const AString &aProtocolFolder)
Loads the upgrade palette and the per-protocol palettes.
static int GetVirtualRAMUsage(void)
Returns the amount of virtual RAM used, in KiB.
size_t RateCompareString(const AString &s1, const AString &s2)
Case-insensitive string comparison that returns a rating of equal-ness between [0 - s1...
HEIGHTTYPE HeightMap[Width *Width]
The type used for any heightmap operations and storage; idx = x + Width * z; Height points to the hig...
size_t GetStorageLoadQueueLength(void)
std::unique_ptr< cBrewingRecipes > m_BrewingRecipes
void LoadGlobalSettings()
bool Start(void)
Starts the HTTP server taking care of the webadmin.
Interface for a callback that receives command output The Out() function is called for any output the...
AString StrToLower(const AString &s)
Returns a lower-cased copy of the string.
AStringVector GetPlayerTabCompletionMultiWorld(const AString &a_Text)
Returns the completions for a player name across all worlds.
EMCSBiome BiomeMap[Width *Width]
The type used for any biomemap operations and storage inside Cuberite, using Cuberite biomes (need no...
std::unique_ptr< BlockTypePalette > m_UpgradeBlockTypePalette
The upgrade palette for pre-1.13 blocks.
const AString & GetShutdownMessage(void) const
cCommandQueue m_PendingCommands
void AuthenticateUser(int a_ClientID, const AString &a_Name, const cUUID &a_UUID, const Json::Value &a_Properties)
Authenticates the specified user, called by cAuthenticator.
void Start(cSettingsRepositoryInterface &a_Settings)
Starts the authenticator thread.