Initial implementation of IniFile overloading
This commit is contained in:
parent
da58620d45
commit
b9efa02c80
@ -118,7 +118,7 @@ void cPluginManager::ReloadPluginsNow(void)
|
||||
|
||||
|
||||
|
||||
void cPluginManager::ReloadPluginsNow(cIniFile & a_SettingsIni)
|
||||
void cPluginManager::ReloadPluginsNow(cSettingsRepositoryInterface & a_Settings)
|
||||
{
|
||||
LOG("-- Loading Plugins --");
|
||||
|
||||
@ -130,7 +130,7 @@ void cPluginManager::ReloadPluginsNow(cIniFile & a_SettingsIni)
|
||||
RefreshPluginList();
|
||||
|
||||
// Load the plugins:
|
||||
AStringVector ToLoad = GetFoldersToLoad(a_SettingsIni);
|
||||
AStringVector ToLoad = GetFoldersToLoad(a_Settings);
|
||||
for (auto & pluginFolder: ToLoad)
|
||||
{
|
||||
LoadPlugin(pluginFolder);
|
||||
@ -157,16 +157,16 @@ void cPluginManager::ReloadPluginsNow(cIniFile & a_SettingsIni)
|
||||
|
||||
|
||||
|
||||
void cPluginManager::InsertDefaultPlugins(cIniFile & a_SettingsIni)
|
||||
void cPluginManager::InsertDefaultPlugins(cSettingsRepositoryInterface & a_Settings)
|
||||
{
|
||||
a_SettingsIni.AddKeyName("Plugins");
|
||||
a_SettingsIni.AddKeyComment("Plugins", " Plugin=Debuggers");
|
||||
a_SettingsIni.AddKeyComment("Plugins", " Plugin=HookNotify");
|
||||
a_SettingsIni.AddKeyComment("Plugins", " Plugin=ChunkWorx");
|
||||
a_SettingsIni.AddKeyComment("Plugins", " Plugin=APIDump");
|
||||
a_SettingsIni.AddValue("Plugins", "Plugin", "Core");
|
||||
a_SettingsIni.AddValue("Plugins", "Plugin", "TransAPI");
|
||||
a_SettingsIni.AddValue("Plugins", "Plugin", "ChatLog");
|
||||
a_Settings.AddKeyName("Plugins");
|
||||
a_Settings.AddKeyComment("Plugins", " Plugin=Debuggers");
|
||||
a_Settings.AddKeyComment("Plugins", " Plugin=HookNotify");
|
||||
a_Settings.AddKeyComment("Plugins", " Plugin=ChunkWorx");
|
||||
a_Settings.AddKeyComment("Plugins", " Plugin=APIDump");
|
||||
a_Settings.AddValue("Plugins", "Plugin", "Core");
|
||||
a_Settings.AddValue("Plugins", "Plugin", "TransAPI");
|
||||
a_Settings.AddValue("Plugins", "Plugin", "ChatLog");
|
||||
}
|
||||
|
||||
|
||||
@ -1896,25 +1896,23 @@ size_t cPluginManager::GetNumLoadedPlugins(void) const
|
||||
|
||||
|
||||
|
||||
AStringVector cPluginManager::GetFoldersToLoad(cIniFile & a_SettingsIni)
|
||||
AStringVector cPluginManager::GetFoldersToLoad(cSettingsRepositoryInterface & a_Settings)
|
||||
{
|
||||
// Check if the Plugins section exists.
|
||||
int KeyNum = a_SettingsIni.FindKey("Plugins");
|
||||
if (KeyNum == -1)
|
||||
if (a_Settings.KeyExists("Plugins"))
|
||||
{
|
||||
InsertDefaultPlugins(a_SettingsIni);
|
||||
KeyNum = a_SettingsIni.FindKey("Plugins");
|
||||
InsertDefaultPlugins(a_Settings);
|
||||
}
|
||||
|
||||
// Get the list of plugins to load:
|
||||
AStringVector res;
|
||||
int NumPlugins = a_SettingsIni.GetNumValues(KeyNum);
|
||||
for (int i = 0; i < NumPlugins; i++)
|
||||
auto Values = a_Settings.GetValues("Plugins");
|
||||
for (auto NameValue : Values)
|
||||
{
|
||||
AString ValueName = a_SettingsIni.GetValueName(KeyNum, i);
|
||||
AString ValueName = NameValue.first;
|
||||
if (ValueName.compare("Plugin") == 0)
|
||||
{
|
||||
AString PluginFile = a_SettingsIni.GetValue(KeyNum, i);
|
||||
AString PluginFile = NameValue.second;
|
||||
if (!PluginFile.empty())
|
||||
{
|
||||
res.push_back(PluginFile);
|
||||
|
@ -24,6 +24,7 @@ class cPlayer;
|
||||
class cPlugin;
|
||||
class cProjectileEntity;
|
||||
class cWorld;
|
||||
class cSettingsRepositoryInterface;
|
||||
struct TakeDamageInfo;
|
||||
|
||||
typedef SharedPtr<cPlugin> cPluginPtr;
|
||||
@ -364,20 +365,20 @@ private:
|
||||
/** Reloads all plugins, defaulting to settings.ini for settings location */
|
||||
void ReloadPluginsNow(void);
|
||||
|
||||
/** Reloads all plugins with a cIniFile object expected to be initialised to settings.ini */
|
||||
void ReloadPluginsNow(cIniFile & a_SettingsIni);
|
||||
/** Reloads all plugins with a settings repo expected to be initialised to settings.ini */
|
||||
void ReloadPluginsNow(cSettingsRepositoryInterface & a_Settings);
|
||||
|
||||
/** Unloads all plugins */
|
||||
void UnloadPluginsNow(void);
|
||||
|
||||
/** Handles writing default plugins if 'Plugins' key not found using a cIniFile object expected to be intialised to settings.ini */
|
||||
void InsertDefaultPlugins(cIniFile & a_SettingsIni);
|
||||
/** Handles writing default plugins if 'Plugins' key not found using a settings repo expected to be intialised to settings.ini */
|
||||
void InsertDefaultPlugins(cSettingsRepositoryInterface & a_Settings);
|
||||
|
||||
/** Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns crExecuted if the command is executed. */
|
||||
CommandResult HandleCommand(cPlayer & a_Player, const AString & a_Command, bool a_ShouldCheckPermissions);
|
||||
|
||||
/** Returns the folders that are specified in the settings ini to load plugins from. */
|
||||
AStringVector GetFoldersToLoad(cIniFile & a_SettingsIni);
|
||||
AStringVector GetFoldersToLoad(cSettingsRepositoryInterface & a_Settings);
|
||||
} ; // tolua_export
|
||||
|
||||
|
||||
|
@ -48,11 +48,13 @@ SET (SRCS
|
||||
Logger.cpp
|
||||
Map.cpp
|
||||
MapManager.cpp
|
||||
MemorySettingsRepository.cpp
|
||||
MobCensus.cpp
|
||||
MobFamilyCollecter.cpp
|
||||
MobProximityCounter.cpp
|
||||
MobSpawner.cpp
|
||||
MonsterConfig.cpp
|
||||
OverridesSettingsRepository.cpp
|
||||
ProbabDistrib.cpp
|
||||
RankManager.cpp
|
||||
RCONServer.cpp
|
||||
@ -116,11 +118,13 @@ SET (HDRS
|
||||
Map.h
|
||||
MapManager.h
|
||||
Matrix4.h
|
||||
MemorySettingsRepository.h
|
||||
MobCensus.h
|
||||
MobFamilyCollecter.h
|
||||
MobProximityCounter.h
|
||||
MobSpawner.h
|
||||
MonsterConfig.h
|
||||
OverridesSettingsRepository.h
|
||||
ProbabDistrib.h
|
||||
RankManager.h
|
||||
RCONServer.h
|
||||
@ -128,6 +132,7 @@ SET (HDRS
|
||||
Scoreboard.h
|
||||
Server.h
|
||||
SetChunkData.h
|
||||
SettingsRepositoryInterface.h
|
||||
Statistics.h
|
||||
StringCompression.h
|
||||
StringUtils.h
|
||||
@ -142,6 +147,7 @@ SET (HDRS
|
||||
include_directories(".")
|
||||
include_directories ("${CMAKE_CURRENT_SOURCE_DIR}/../lib/sqlite")
|
||||
include_directories ("${CMAKE_CURRENT_SOURCE_DIR}/../lib/SQLiteCpp/include")
|
||||
include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/TCLAP/include")
|
||||
|
||||
configure_file("BuildInfo.h.cmake" "${CMAKE_CURRENT_SOURCE_DIR}/BuildInfo.h")
|
||||
|
||||
|
@ -436,7 +436,7 @@ typename std::enable_if<std::is_arithmetic<T>::value, C>::type CeilC(T a_Value)
|
||||
template <class T, class... Args>
|
||||
std::unique_ptr<T> make_unique(Args&&... args)
|
||||
{
|
||||
return std::unique_ptr<T>(new T(args...));
|
||||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
// a tick is 50 ms
|
||||
|
@ -49,6 +49,9 @@ cIniFile::cIniFile(void) :
|
||||
|
||||
bool cIniFile::ReadFile(const AString & a_FileName, bool a_AllowExampleRedirect)
|
||||
{
|
||||
|
||||
m_Filename = a_FileName;
|
||||
|
||||
// Normally you would use ifstream, but the SGI CC compiler has
|
||||
// a few bugs with ifstream. So ... fstream used.
|
||||
fstream f;
|
||||
@ -56,7 +59,8 @@ bool cIniFile::ReadFile(const AString & a_FileName, bool a_AllowExampleRedirect)
|
||||
AString keyname, valuename, value;
|
||||
AString::size_type pLeft, pRight;
|
||||
bool IsFromExampleRedirect = false;
|
||||
|
||||
|
||||
|
||||
f.open((FILE_IO_PREFIX + a_FileName).c_str(), ios::in);
|
||||
if (f.fail())
|
||||
{
|
||||
@ -650,7 +654,7 @@ void cIniFile::Clear(void)
|
||||
|
||||
|
||||
|
||||
bool cIniFile::HasValue(const AString & a_KeyName, const AString & a_ValueName)
|
||||
bool cIniFile::HasValue(const AString & a_KeyName, const AString & a_ValueName) const
|
||||
{
|
||||
// Find the key:
|
||||
int keyID = FindKey(a_KeyName);
|
||||
@ -889,8 +893,36 @@ void cIniFile::RemoveBom(AString & a_line) const
|
||||
|
||||
|
||||
|
||||
bool cIniFile::KeyExists(AString a_keyname) const
|
||||
{
|
||||
return FindKey(a_keyname) != noID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
std::vector<std::pair<AString, AString>> cIniFile::GetValues(AString a_keyName)
|
||||
{
|
||||
std::vector<std::pair<AString, AString>> ret;
|
||||
int keyID = FindKey(a_keyName);
|
||||
if (keyID == noID)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
for (size_t valueID = 0; valueID < keys[keyID].names.size(); ++valueID)
|
||||
{
|
||||
ret.emplace_back(keys[keyID].names[valueID], keys[keyID].values[valueID]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AStringVector ReadUpgradeIniPorts(
|
||||
cIniFile & a_IniFile,
|
||||
cSettingsRepositoryInterface & a_Settings,
|
||||
const AString & a_KeyName,
|
||||
const AString & a_PortsValueName,
|
||||
const AString & a_OldIPv4ValueName,
|
||||
@ -899,23 +931,23 @@ AStringVector ReadUpgradeIniPorts(
|
||||
)
|
||||
{
|
||||
// Read the regular value, but don't use the default (in order to detect missing value for upgrade):
|
||||
AStringVector Ports = StringSplitAndTrim(a_IniFile.GetValue(a_KeyName, a_PortsValueName), ";,");
|
||||
AStringVector Ports = StringSplitAndTrim(a_Settings.GetValue(a_KeyName, a_PortsValueName), ";,");
|
||||
|
||||
if (Ports.empty())
|
||||
{
|
||||
// Historically there were two separate entries for IPv4 and IPv6, merge them and migrate:
|
||||
AString Ports4 = a_IniFile.GetValue(a_KeyName, a_OldIPv4ValueName, a_DefaultValue);
|
||||
AString Ports6 = a_IniFile.GetValue(a_KeyName, a_OldIPv6ValueName);
|
||||
AString Ports4 = a_Settings.GetValue(a_KeyName, a_OldIPv4ValueName, a_DefaultValue);
|
||||
AString Ports6 = a_Settings.GetValue(a_KeyName, a_OldIPv6ValueName);
|
||||
Ports = MergeStringVectors(StringSplitAndTrim(Ports4, ";,"), StringSplitAndTrim(Ports6, ";,"));
|
||||
a_IniFile.DeleteValue(a_KeyName, a_OldIPv4ValueName);
|
||||
a_IniFile.DeleteValue(a_KeyName, a_OldIPv6ValueName);
|
||||
a_Settings.DeleteValue(a_KeyName, a_OldIPv4ValueName);
|
||||
a_Settings.DeleteValue(a_KeyName, a_OldIPv6ValueName);
|
||||
|
||||
// If those weren't present or were empty, use the default:"
|
||||
if (Ports.empty())
|
||||
{
|
||||
Ports = StringSplitAndTrim(a_DefaultValue, ";,");
|
||||
}
|
||||
a_IniFile.SetValue(a_KeyName, a_PortsValueName, StringsConcat(Ports, ','));
|
||||
a_Settings.SetValue(a_KeyName, a_PortsValueName, StringsConcat(Ports, ','));
|
||||
}
|
||||
|
||||
return Ports;
|
||||
@ -923,4 +955,3 @@ AStringVector ReadUpgradeIniPorts(
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
#include "SettingsRepositoryInterface.h"
|
||||
|
||||
#define MAX_KEYNAME 128
|
||||
#define MAX_VALUENAME 128
|
||||
@ -30,10 +30,12 @@
|
||||
|
||||
// tolua_begin
|
||||
|
||||
class cIniFile
|
||||
class cIniFile : public cSettingsRepositoryInterface
|
||||
{
|
||||
private:
|
||||
bool m_IsCaseInsensitive;
|
||||
|
||||
AString m_Filename;
|
||||
|
||||
struct key
|
||||
{
|
||||
@ -53,15 +55,19 @@ private:
|
||||
void RemoveBom(AString & a_line) const;
|
||||
|
||||
public:
|
||||
|
||||
enum errors
|
||||
{
|
||||
noID = -1,
|
||||
};
|
||||
|
||||
/// Creates a new instance with no data
|
||||
cIniFile(void);
|
||||
|
||||
// tolua_end
|
||||
virtual ~cIniFile() = default;
|
||||
|
||||
virtual std::vector<std::pair<AString, AString>> GetValues(AString a_keyName) override;
|
||||
|
||||
virtual bool KeyExists(const AString a_keyName) const override;
|
||||
|
||||
// tolua_begin
|
||||
|
||||
// Sets whether or not keynames and valuenames should be case sensitive.
|
||||
// The default is case insensitive.
|
||||
void CaseSensitive (void) { m_IsCaseInsensitive = false; }
|
||||
@ -77,11 +83,13 @@ public:
|
||||
/// Writes data stored in class to the specified ini file
|
||||
bool WriteFile(const AString & a_FileName) const;
|
||||
|
||||
virtual bool Flush() override { return WriteFile(m_Filename); }
|
||||
|
||||
/// Deletes all stored ini data (but doesn't touch the file)
|
||||
void Clear(void);
|
||||
|
||||
/** Returns true iff the specified value exists. */
|
||||
bool HasValue(const AString & a_KeyName, const AString & a_ValueName);
|
||||
bool HasValue(const AString & a_KeyName, const AString & a_ValueName) const;
|
||||
|
||||
/// Returns index of specified key, or noID if not found
|
||||
int FindKey(const AString & keyname) const;
|
||||
@ -222,7 +230,7 @@ Reads the list of ports from a_PortsValueName. If that value doesn't exist or is
|
||||
in a_OldIPv4ValueName and a_OldIPv6ValueName; in this case the old values are removed from the INI file.
|
||||
If there is none of the three values or they are all empty, the default is used and stored in the Ports value. */
|
||||
AStringVector ReadUpgradeIniPorts(
|
||||
cIniFile & a_IniFile,
|
||||
cSettingsRepositoryInterface & a_Settings,
|
||||
const AString & a_KeyName,
|
||||
const AString & a_PortsValueName,
|
||||
const AString & a_OldIPv4ValueName,
|
||||
|
312
src/MemorySettingsRepository.cpp
Normal file
312
src/MemorySettingsRepository.cpp
Normal file
@ -0,0 +1,312 @@
|
||||
|
||||
#include "Globals.h"
|
||||
|
||||
#include "MemorySettingsRepository.h"
|
||||
|
||||
|
||||
|
||||
|
||||
bool cMemorySettingsRepository::KeyExists(const AString keyname) const
|
||||
{
|
||||
return m_Map.count(keyname) != 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cMemorySettingsRepository::HasValue(const AString & a_KeyName, const AString & a_ValueName) const
|
||||
{
|
||||
auto outerIter = m_Map.find(a_KeyName);
|
||||
if (outerIter == m_Map.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
auto iter = outerIter->second.find(a_ValueName);
|
||||
if (iter == outerIter->second.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int cMemorySettingsRepository::AddKeyName(const AString & a_keyname)
|
||||
{
|
||||
m_Map.emplace(a_keyname, std::unordered_multimap<AString, sValue>{});
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cMemorySettingsRepository::AddKeyComment(const AString & keyname, const AString & comment)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AString cMemorySettingsRepository::GetKeyComment(const AString & keyname, const int commentID) const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cMemorySettingsRepository::DeleteKeyComment(const AString & keyname, const int commentID)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cMemorySettingsRepository::AddValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value)
|
||||
{
|
||||
if (m_Writable)
|
||||
{
|
||||
m_Map[a_KeyName].emplace(a_ValueName, sValue(a_Value));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void cMemorySettingsRepository::AddValue (const AString & a_KeyName, const AString & a_ValueName, Int64 a_Value)
|
||||
{
|
||||
if (m_Writable)
|
||||
{
|
||||
m_Map[a_KeyName].emplace(a_ValueName, sValue(a_Value));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cMemorySettingsRepository::AddValue (const AString & a_KeyName, const AString & a_ValueName, bool a_Value)
|
||||
{
|
||||
if (m_Writable)
|
||||
{
|
||||
m_Map[a_KeyName].emplace(a_ValueName, sValue(a_Value));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
std::vector<std::pair<AString, AString>> cMemorySettingsRepository::GetValues(AString a_keyName)
|
||||
{
|
||||
std::vector<std::pair<AString, AString>> ret;
|
||||
for (auto pair : m_Map[a_keyName])
|
||||
{
|
||||
ret.emplace_back(pair.first, pair.second.getStringValue());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AString cMemorySettingsRepository::GetValue (const AString & a_KeyName, const AString & a_ValueName, const AString & defValue) const
|
||||
{
|
||||
auto outerIter = m_Map.find(a_KeyName);
|
||||
if (outerIter == m_Map.end())
|
||||
{
|
||||
return defValue;
|
||||
}
|
||||
auto iter = outerIter->second.find(a_ValueName);
|
||||
if (iter == outerIter->second.end())
|
||||
{
|
||||
return defValue;
|
||||
}
|
||||
return iter->second.getStringValue();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AString cMemorySettingsRepository::GetValueSet (const AString & a_KeyName, const AString & a_ValueName, const AString & defValue)
|
||||
{
|
||||
auto outerIter = m_Map.find(a_KeyName);
|
||||
if (outerIter == m_Map.end())
|
||||
{
|
||||
AddValue(a_KeyName, a_ValueName, defValue);
|
||||
return defValue;
|
||||
}
|
||||
auto iter = outerIter->second.find(a_ValueName);
|
||||
if (iter == outerIter->second.end())
|
||||
{
|
||||
AddValue(a_KeyName, a_ValueName, defValue);
|
||||
return defValue;
|
||||
}
|
||||
return iter->second.getStringValue();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cMemorySettingsRepository::GetValueSetI(const AString & a_KeyName, const AString & a_ValueName, const int defValue)
|
||||
{
|
||||
auto outerIter = m_Map.find(a_KeyName);
|
||||
if (outerIter == m_Map.end())
|
||||
{
|
||||
AddValue(a_KeyName, a_ValueName, static_cast<Int64>(defValue));
|
||||
return defValue;
|
||||
}
|
||||
auto iter = outerIter->second.find(a_ValueName);
|
||||
if (iter == outerIter->second.end())
|
||||
{
|
||||
AddValue(a_KeyName, a_ValueName, static_cast<Int64>(defValue));
|
||||
return defValue;
|
||||
}
|
||||
return static_cast<int>(iter->second.getIntValue());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Int64 cMemorySettingsRepository::GetValueSetI(const AString & a_KeyName, const AString & a_ValueName, const Int64 defValue)
|
||||
{
|
||||
auto outerIter = m_Map.find(a_KeyName);
|
||||
if (outerIter == m_Map.end())
|
||||
{
|
||||
AddValue(a_KeyName, a_ValueName, defValue);
|
||||
return defValue;
|
||||
}
|
||||
auto iter = outerIter->second.find(a_ValueName);
|
||||
if (iter == outerIter->second.end())
|
||||
{
|
||||
AddValue(a_KeyName, a_ValueName, defValue);
|
||||
return defValue;
|
||||
}
|
||||
return iter->second.getIntValue();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool cMemorySettingsRepository::GetValueSetB(const AString & a_KeyName, const AString & a_ValueName, const bool defValue)
|
||||
{
|
||||
auto outerIter = m_Map.find(a_KeyName);
|
||||
if (outerIter == m_Map.end())
|
||||
{
|
||||
AddValue(a_KeyName, a_ValueName, defValue);
|
||||
return defValue;
|
||||
}
|
||||
auto iter = outerIter->second.find(a_ValueName);
|
||||
if (iter == outerIter->second.end())
|
||||
{
|
||||
AddValue(a_KeyName, a_ValueName, defValue);
|
||||
return defValue;
|
||||
}
|
||||
return iter->second.getBoolValue();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cMemorySettingsRepository::SetValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value, const bool a_CreateIfNotExists)
|
||||
{
|
||||
if (!m_Writable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
auto outerIter = m_Map.find(a_KeyName);
|
||||
if (outerIter == m_Map.end())
|
||||
{
|
||||
if (a_CreateIfNotExists)
|
||||
{
|
||||
AddValue(a_KeyName, a_ValueName, a_Value);
|
||||
}
|
||||
return a_CreateIfNotExists;
|
||||
}
|
||||
auto iter = outerIter->second.find(a_ValueName);
|
||||
if (iter == outerIter->second.end())
|
||||
{
|
||||
if (a_CreateIfNotExists)
|
||||
{
|
||||
AddValue(a_KeyName, a_ValueName, a_Value);
|
||||
}
|
||||
return a_CreateIfNotExists;
|
||||
}
|
||||
iter->second = sValue(a_Value);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool cMemorySettingsRepository::SetValueI(const AString & a_KeyName, const AString & a_ValueName, const int a_Value, const bool a_CreateIfNotExists)
|
||||
{
|
||||
if (!m_Writable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
auto outerIter = m_Map.find(a_KeyName);
|
||||
if (outerIter == m_Map.end())
|
||||
{
|
||||
if (a_CreateIfNotExists)
|
||||
{
|
||||
AddValue(a_KeyName, a_ValueName, static_cast<Int64>(a_Value));
|
||||
}
|
||||
return a_CreateIfNotExists;
|
||||
}
|
||||
auto iter = outerIter->second.find(a_ValueName);
|
||||
if (iter == outerIter->second.end())
|
||||
{
|
||||
if (a_CreateIfNotExists)
|
||||
{
|
||||
AddValue(a_KeyName, a_ValueName, static_cast<Int64>(a_Value));
|
||||
}
|
||||
return a_CreateIfNotExists;
|
||||
}
|
||||
iter->second = sValue(static_cast<Int64>(a_Value));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cMemorySettingsRepository::DeleteValue(const AString & a_KeyName, const AString & a_ValueName)
|
||||
{
|
||||
if (!m_Writable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
auto outerIter = m_Map.find(a_KeyName);
|
||||
if (outerIter == m_Map.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
auto iter = outerIter->second.find(a_ValueName);
|
||||
if (iter == outerIter->second.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
outerIter->second.erase(iter);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cMemorySettingsRepository::Flush()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
80
src/MemorySettingsRepository.h
Normal file
80
src/MemorySettingsRepository.h
Normal file
@ -0,0 +1,80 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SettingsRepositoryInterface.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
class cMemorySettingsRepository : public cSettingsRepositoryInterface
|
||||
{
|
||||
public:
|
||||
|
||||
virtual bool KeyExists(const AString keyname) const override;
|
||||
|
||||
virtual bool HasValue(const AString & a_KeyName, const AString & a_ValueName) const override;
|
||||
|
||||
virtual int AddKeyName(const AString & keyname) override;
|
||||
|
||||
virtual bool AddKeyComment(const AString & keyname, const AString & comment) override;
|
||||
|
||||
virtual AString GetKeyComment(const AString & keyname, const int commentID) const override;
|
||||
|
||||
virtual bool DeleteKeyComment(const AString & keyname, const int commentID) override;
|
||||
|
||||
virtual void AddValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value) override;
|
||||
void AddValue (const AString & a_KeyName, const AString & a_ValueName, const Int64 a_Value);
|
||||
void AddValue (const AString & a_KeyName, const AString & a_ValueName, const bool a_Value);
|
||||
|
||||
virtual std::vector<std::pair<AString, AString>> GetValues(AString a_keyName) override;
|
||||
|
||||
virtual AString GetValue (const AString & keyname, const AString & valuename, const AString & defValue = "") const override;
|
||||
|
||||
|
||||
virtual AString GetValueSet (const AString & keyname, const AString & valuename, const AString & defValue = "") override;
|
||||
virtual int GetValueSetI(const AString & keyname, const AString & valuename, const int defValue = 0) override;
|
||||
virtual Int64 GetValueSetI(const AString & keyname, const AString & valuename, const Int64 defValue = 0) override;
|
||||
virtual bool GetValueSetB(const AString & keyname, const AString & valuename, const bool defValue = false) override;
|
||||
|
||||
virtual bool SetValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value, const bool a_CreateIfNotExists = true) override;
|
||||
virtual bool SetValueI(const AString & a_KeyName, const AString & a_ValueName, const int a_Value, const bool a_CreateIfNotExists = true) override;
|
||||
|
||||
virtual bool DeleteValue(const AString & keyname, const AString & valuename) override;
|
||||
|
||||
virtual bool Flush() override;
|
||||
|
||||
void SetReadOnly()
|
||||
{
|
||||
m_Writable = false;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool m_Writable = true;
|
||||
|
||||
struct sValue
|
||||
{
|
||||
sValue(AString value) : m_Type(eType::String), m_stringValue (value) {}
|
||||
sValue(Int64 value) : m_Type(eType::Int64), m_intValue(value) {}
|
||||
sValue(bool value) : m_Type(eType::Bool), m_boolValue(value) {}
|
||||
|
||||
AString getStringValue() const { ASSERT(m_Type == eType::String); return m_stringValue; }
|
||||
Int64 getIntValue() const { ASSERT(m_Type == eType::Int64); return m_intValue; }
|
||||
bool getBoolValue() const { ASSERT(m_Type == eType::Bool); return m_boolValue; }
|
||||
private:
|
||||
enum class eType
|
||||
{
|
||||
String,
|
||||
Int64,
|
||||
Bool
|
||||
} m_Type;
|
||||
AString m_stringValue;
|
||||
union
|
||||
{
|
||||
Int64 m_intValue;
|
||||
bool m_boolValue;
|
||||
};
|
||||
};
|
||||
|
||||
std::unordered_map<AString, std::unordered_multimap<AString, sValue>> m_Map{};
|
||||
};
|
||||
|
273
src/OverridesSettingsRepository.cpp
Normal file
273
src/OverridesSettingsRepository.cpp
Normal file
@ -0,0 +1,273 @@
|
||||
|
||||
#include "Globals.h"
|
||||
#include "OverridesSettingsRepository.h"
|
||||
|
||||
cOverridesSettingsRepository::cOverridesSettingsRepository(std::unique_ptr<cSettingsRepositoryInterface> a_Main, std::unique_ptr<cSettingsRepositoryInterface> a_Overrides) :
|
||||
m_Main(std::move(a_Main)),
|
||||
m_Overrides(std::move(a_Overrides))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cOverridesSettingsRepository::KeyExists(const AString a_keyName) const
|
||||
{
|
||||
return m_Overrides->KeyExists(a_keyName) || m_Main->KeyExists(a_keyName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool cOverridesSettingsRepository::HasValue(const AString & a_KeyName, const AString & a_ValueName) const
|
||||
{
|
||||
return m_Overrides->HasValue(a_KeyName, a_ValueName) || m_Main->HasValue(a_KeyName, a_ValueName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cOverridesSettingsRepository::AddKeyName(const AString & a_keyname)
|
||||
{
|
||||
|
||||
if (m_Overrides->KeyExists(a_keyname))
|
||||
{
|
||||
m_Overrides->AddKeyName(a_keyname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m_Main->AddKeyName(a_keyname);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cOverridesSettingsRepository::AddKeyComment(const AString & a_keyname, const AString & a_comment)
|
||||
{
|
||||
if (m_Overrides->KeyExists(a_keyname))
|
||||
{
|
||||
return m_Overrides->AddKeyComment(a_keyname, a_comment);
|
||||
}
|
||||
|
||||
return m_Main->AddKeyComment(a_keyname, a_comment);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AString cOverridesSettingsRepository::GetKeyComment(const AString & a_keyname, const int a_commentID) const
|
||||
{
|
||||
|
||||
if (m_Overrides->KeyExists(a_keyname))
|
||||
{
|
||||
return m_Overrides->GetKeyComment(a_keyname, a_commentID);
|
||||
}
|
||||
|
||||
return m_Main->GetKeyComment(a_keyname, a_commentID);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cOverridesSettingsRepository::DeleteKeyComment(const AString & a_keyname, const int a_commentID)
|
||||
{
|
||||
if (m_Overrides->KeyExists(a_keyname))
|
||||
{
|
||||
return m_Overrides->DeleteKeyComment(a_keyname, a_commentID);
|
||||
}
|
||||
|
||||
return m_Main->DeleteKeyComment(a_keyname, a_commentID);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cOverridesSettingsRepository::AddValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value)
|
||||
{
|
||||
if (m_Overrides->HasValue(a_KeyName, a_ValueName))
|
||||
{
|
||||
m_Overrides->AddValue(a_KeyName, a_ValueName, a_Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Main->AddValue(a_KeyName, a_ValueName, a_Value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
std::vector<std::pair<AString, AString>> cOverridesSettingsRepository::GetValues(AString a_keyName)
|
||||
{
|
||||
auto overrides = m_Overrides->GetValues(a_keyName);
|
||||
auto main = m_Main->GetValues(a_keyName);
|
||||
std::sort(overrides.begin(), overrides.end(), [](std::pair<AString, AString> a, std::pair<AString, AString> b) -> bool { return a < b ;});
|
||||
std::sort(main.begin(), main.end(), [](std::pair<AString, AString> a, std::pair<AString, AString> b) -> bool { return a < b ;});
|
||||
|
||||
std::vector<std::pair<AString, AString>> ret;
|
||||
|
||||
|
||||
size_t overridesIndex = 0;
|
||||
for (auto pair : main)
|
||||
{
|
||||
if (overridesIndex >= overrides.size())
|
||||
{
|
||||
ret.push_back(pair);
|
||||
continue;
|
||||
}
|
||||
if (pair.first == overrides[overridesIndex].first)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
while (pair.first > overrides[overridesIndex].first)
|
||||
{
|
||||
ret.push_back(overrides[overridesIndex]);
|
||||
overridesIndex++;
|
||||
}
|
||||
ret.push_back(pair);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AString cOverridesSettingsRepository::GetValue(const AString & a_KeyName, const AString & a_ValueName, const AString & defValue) const
|
||||
{
|
||||
if (m_Overrides->HasValue(a_KeyName, a_ValueName))
|
||||
{
|
||||
return m_Overrides->GetValue(a_KeyName, a_ValueName, defValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_Main->GetValue(a_KeyName, a_ValueName, defValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AString cOverridesSettingsRepository::GetValueSet (const AString & a_KeyName, const AString & a_ValueName, const AString & defValue)
|
||||
{
|
||||
if (m_Overrides->HasValue(a_KeyName, a_ValueName))
|
||||
{
|
||||
return m_Overrides->GetValueSet(a_KeyName, a_ValueName, defValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_Main->GetValueSet(a_KeyName, a_ValueName, defValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cOverridesSettingsRepository::GetValueSetI(const AString & a_KeyName, const AString & a_ValueName, const int defValue)
|
||||
{
|
||||
if (m_Overrides->HasValue(a_KeyName, a_ValueName))
|
||||
{
|
||||
return m_Overrides->GetValueSetI(a_KeyName, a_ValueName, defValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_Main->GetValueSetI(a_KeyName, a_ValueName, defValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Int64 cOverridesSettingsRepository::GetValueSetI(const AString & a_KeyName, const AString & a_ValueName, const Int64 defValue)
|
||||
{
|
||||
if (m_Overrides->HasValue(a_KeyName, a_ValueName))
|
||||
{
|
||||
return m_Overrides->GetValueSetI(a_KeyName, a_ValueName, defValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_Main->GetValueSetI(a_KeyName, a_ValueName, defValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cOverridesSettingsRepository::GetValueSetB(const AString & a_KeyName, const AString & a_ValueName, const bool defValue)
|
||||
{
|
||||
if (m_Overrides->HasValue(a_KeyName, a_ValueName))
|
||||
{
|
||||
return m_Overrides->GetValueSetB(a_KeyName, a_ValueName, defValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_Main->GetValueSetB(a_KeyName, a_ValueName, defValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cOverridesSettingsRepository::SetValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value, const bool a_CreateIfNotExists)
|
||||
{
|
||||
if (m_Overrides->HasValue(a_KeyName, a_ValueName))
|
||||
{
|
||||
return m_Overrides->SetValue(a_KeyName, a_ValueName, a_Value, a_CreateIfNotExists);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_Main->SetValue(a_KeyName, a_ValueName, a_Value, a_CreateIfNotExists);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cOverridesSettingsRepository::SetValueI(const AString & a_KeyName, const AString & a_ValueName, const int a_Value, const bool a_CreateIfNotExists)
|
||||
{
|
||||
if (m_Overrides->HasValue(a_KeyName, a_ValueName))
|
||||
{
|
||||
return m_Overrides->SetValueI(a_KeyName, a_ValueName, a_Value, a_CreateIfNotExists);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_Main->SetValueI(a_KeyName, a_ValueName, a_Value, a_CreateIfNotExists);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cOverridesSettingsRepository::DeleteValue(const AString & a_KeyName, const AString & a_ValueName)
|
||||
{
|
||||
if (m_Overrides->HasValue(a_KeyName, a_ValueName))
|
||||
{
|
||||
return m_Overrides->DeleteValue(a_KeyName, a_ValueName);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_Overrides->DeleteValue(a_KeyName, a_ValueName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool cOverridesSettingsRepository::Flush()
|
||||
{
|
||||
return m_Overrides->Flush() && m_Main->Flush();
|
||||
}
|
||||
|
52
src/OverridesSettingsRepository.h
Normal file
52
src/OverridesSettingsRepository.h
Normal file
@ -0,0 +1,52 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SettingsRepositoryInterface.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
class cOverridesSettingsRepository : public cSettingsRepositoryInterface
|
||||
{
|
||||
|
||||
public:
|
||||
cOverridesSettingsRepository(std::unique_ptr<cSettingsRepositoryInterface> a_Main, std::unique_ptr<cSettingsRepositoryInterface> a_Overrides);
|
||||
|
||||
virtual ~cOverridesSettingsRepository() = default;
|
||||
|
||||
virtual bool KeyExists(const AString keyname) const override;
|
||||
|
||||
virtual bool HasValue(const AString & a_KeyName, const AString & a_ValueName) const override;
|
||||
|
||||
virtual int AddKeyName(const AString & keyname) override;
|
||||
|
||||
virtual bool AddKeyComment(const AString & keyname, const AString & comment) override;
|
||||
|
||||
virtual AString GetKeyComment(const AString & keyname, const int commentID) const override;
|
||||
|
||||
virtual bool DeleteKeyComment(const AString & keyname, const int commentID) override;
|
||||
|
||||
virtual void AddValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value) override;
|
||||
|
||||
virtual std::vector<std::pair<AString, AString>> GetValues(AString a_keyName) override;
|
||||
|
||||
virtual AString GetValue (const AString & keyname, const AString & valuename, const AString & defValue = "") const override;
|
||||
|
||||
virtual AString GetValueSet (const AString & keyname, const AString & valuename, const AString & defValue = "") override;
|
||||
virtual int GetValueSetI(const AString & keyname, const AString & valuename, const int defValue = 0) override;
|
||||
virtual Int64 GetValueSetI(const AString & keyname, const AString & valuename, const Int64 defValue = 0) override;
|
||||
virtual bool GetValueSetB(const AString & keyname, const AString & valuename, const bool defValue = false) override;
|
||||
|
||||
virtual bool SetValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value, const bool a_CreateIfNotExists = true) override;
|
||||
virtual bool SetValueI(const AString & a_KeyName, const AString & a_ValueName, const int a_Value, const bool a_CreateIfNotExists = true) override;
|
||||
|
||||
virtual bool DeleteValue(const AString & keyname, const AString & valuename) override;
|
||||
|
||||
virtual bool Flush() override;
|
||||
|
||||
private:
|
||||
|
||||
std::unique_ptr<cSettingsRepositoryInterface> m_Main;
|
||||
std::unique_ptr<cSettingsRepositoryInterface> m_Overrides;
|
||||
|
||||
};
|
||||
|
@ -40,11 +40,11 @@ cAuthenticator::~cAuthenticator()
|
||||
|
||||
|
||||
|
||||
void cAuthenticator::ReadINI(cIniFile & IniFile)
|
||||
void cAuthenticator::ReadSettings(cSettingsRepositoryInterface & a_Settings)
|
||||
{
|
||||
m_Server = IniFile.GetValueSet ("Authentication", "Server", DEFAULT_AUTH_SERVER);
|
||||
m_Address = IniFile.GetValueSet ("Authentication", "Address", DEFAULT_AUTH_ADDRESS);
|
||||
m_ShouldAuthenticate = IniFile.GetValueSetB("Authentication", "Authenticate", true);
|
||||
m_Server = a_Settings.GetValueSet ("Authentication", "Server", DEFAULT_AUTH_SERVER);
|
||||
m_Address = a_Settings.GetValueSet ("Authentication", "Address", DEFAULT_AUTH_ADDRESS);
|
||||
m_ShouldAuthenticate = a_Settings.GetValueSetB("Authentication", "Authenticate", true);
|
||||
}
|
||||
|
||||
|
||||
@ -69,9 +69,9 @@ void cAuthenticator::Authenticate(int a_ClientID, const AString & a_UserName, co
|
||||
|
||||
|
||||
|
||||
void cAuthenticator::Start(cIniFile & IniFile)
|
||||
void cAuthenticator::Start(cSettingsRepositoryInterface & a_Settings)
|
||||
{
|
||||
ReadINI(IniFile);
|
||||
ReadSettings(a_Settings);
|
||||
m_ShouldTerminate = false;
|
||||
super::Start();
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
#include "../OSSupport/IsThread.h"
|
||||
|
||||
|
||||
class cSettingsRepositoryInterface;
|
||||
|
||||
|
||||
|
||||
@ -40,13 +40,13 @@ public:
|
||||
~cAuthenticator();
|
||||
|
||||
/** (Re-)read server and address from INI: */
|
||||
void ReadINI(cIniFile & IniFile);
|
||||
void ReadSettings(cSettingsRepositoryInterface & a_Settings);
|
||||
|
||||
/** Queues a request for authenticating a user. If the auth fails, the user will be kicked */
|
||||
void Authenticate(int a_ClientID, const AString & a_UserName, const AString & a_ServerHash);
|
||||
|
||||
/** Starts the authenticator thread. The thread may be started and stopped repeatedly */
|
||||
void Start(cIniFile & IniFile);
|
||||
void Start(cSettingsRepositoryInterface & a_Settings);
|
||||
|
||||
/** Stops the authenticator thread. The thread may be started and stopped repeatedly */
|
||||
void Stop(void);
|
||||
|
@ -226,12 +226,12 @@ cMojangAPI::~cMojangAPI()
|
||||
|
||||
|
||||
|
||||
void cMojangAPI::Start(cIniFile & a_SettingsIni, bool a_ShouldAuth)
|
||||
void cMojangAPI::Start(cSettingsRepositoryInterface & a_Settings, bool a_ShouldAuth)
|
||||
{
|
||||
m_NameToUUIDServer = a_SettingsIni.GetValueSet("MojangAPI", "NameToUUIDServer", DEFAULT_NAME_TO_UUID_SERVER);
|
||||
m_NameToUUIDAddress = a_SettingsIni.GetValueSet("MojangAPI", "NameToUUIDAddress", DEFAULT_NAME_TO_UUID_ADDRESS);
|
||||
m_UUIDToProfileServer = a_SettingsIni.GetValueSet("MojangAPI", "UUIDToProfileServer", DEFAULT_UUID_TO_PROFILE_SERVER);
|
||||
m_UUIDToProfileAddress = a_SettingsIni.GetValueSet("MojangAPI", "UUIDToProfileAddress", DEFAULT_UUID_TO_PROFILE_ADDRESS);
|
||||
m_NameToUUIDServer = a_Settings.GetValueSet("MojangAPI", "NameToUUIDServer", DEFAULT_NAME_TO_UUID_SERVER);
|
||||
m_NameToUUIDAddress = a_Settings.GetValueSet("MojangAPI", "NameToUUIDAddress", DEFAULT_NAME_TO_UUID_ADDRESS);
|
||||
m_UUIDToProfileServer = a_Settings.GetValueSet("MojangAPI", "UUIDToProfileServer", DEFAULT_UUID_TO_PROFILE_SERVER);
|
||||
m_UUIDToProfileAddress = a_Settings.GetValueSet("MojangAPI", "UUIDToProfileAddress", DEFAULT_UUID_TO_PROFILE_ADDRESS);
|
||||
LoadCachesFromDisk();
|
||||
if (a_ShouldAuth)
|
||||
{
|
||||
|
@ -25,7 +25,7 @@ namespace Json
|
||||
|
||||
|
||||
|
||||
|
||||
class cSettingsRepositoryInterface;
|
||||
|
||||
// tolua_begin
|
||||
class cMojangAPI
|
||||
@ -38,7 +38,7 @@ public:
|
||||
|
||||
/** Initializes the API; reads the settings from the specified ini file.
|
||||
Loads cached results from disk. */
|
||||
void Start(cIniFile & a_SettingsIni, bool a_ShouldAuth);
|
||||
void Start(cSettingsRepositoryInterface & a_Settings, bool a_ShouldAuth);
|
||||
|
||||
/** Connects to the specified server using SSL, sends the given request and receives the response.
|
||||
Checks Mojang certificates using the hard-coded Starfield root CA certificate.
|
||||
|
@ -134,15 +134,15 @@ cRCONServer::~cRCONServer()
|
||||
|
||||
|
||||
|
||||
void cRCONServer::Initialize(cIniFile & a_IniFile)
|
||||
void cRCONServer::Initialize(cSettingsRepositoryInterface & a_Settings)
|
||||
{
|
||||
if (!a_IniFile.GetValueSetB("RCON", "Enabled", false))
|
||||
if (!a_Settings.GetValueSetB("RCON", "Enabled", false))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the password, don't allow an empty one:
|
||||
m_Password = a_IniFile.GetValueSet("RCON", "Password", "");
|
||||
m_Password = a_Settings.GetValueSet("RCON", "Password", "");
|
||||
if (m_Password.empty())
|
||||
{
|
||||
LOGWARNING("RCON is requested, but the password is not set. RCON is now disabled.");
|
||||
@ -150,7 +150,7 @@ void cRCONServer::Initialize(cIniFile & a_IniFile)
|
||||
}
|
||||
|
||||
// Read the listening ports for RCON from config:
|
||||
AStringVector Ports = ReadUpgradeIniPorts(a_IniFile, "RCON", "Ports", "PortsIPv4", "PortsIPv6", "25575");
|
||||
AStringVector Ports = ReadUpgradeIniPorts(a_Settings, "RCON", "Ports", "PortsIPv4", "PortsIPv6", "25575");
|
||||
|
||||
// Start listening on each specified port:
|
||||
for (auto port: Ports)
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
// fwd:
|
||||
class cServer;
|
||||
class cIniFile;
|
||||
class cSettingsRepositoryInterface;
|
||||
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ public:
|
||||
cRCONServer(cServer & a_Server);
|
||||
virtual ~cRCONServer();
|
||||
|
||||
void Initialize(cIniFile & a_IniFile);
|
||||
void Initialize(cSettingsRepositoryInterface & a_Settings);
|
||||
|
||||
protected:
|
||||
friend class cRCONCommandOutput;
|
||||
|
57
src/Root.cpp
57
src/Root.cpp
@ -19,6 +19,8 @@
|
||||
#include "LoggerListeners.h"
|
||||
#include "BuildInfo.h"
|
||||
#include "IniFile.h"
|
||||
#include "SettingsRepositoryInterface.h"
|
||||
#include "OverridesSettingsRepository.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <conio.h>
|
||||
@ -96,7 +98,7 @@ void cRoot::InputThread(cRoot & a_Params)
|
||||
|
||||
|
||||
|
||||
void cRoot::Start(void)
|
||||
void cRoot::Start(std::unique_ptr<cSettingsRepositoryInterface> overridesRepo)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HWND hwnd = GetConsoleWindow();
|
||||
@ -130,22 +132,24 @@ void cRoot::Start(void)
|
||||
m_Server = new cServer();
|
||||
|
||||
LOG("Reading server config...");
|
||||
cIniFile IniFile;
|
||||
if (!IniFile.ReadFile("settings.ini"))
|
||||
|
||||
auto IniFile = 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 = 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;
|
||||
}
|
||||
@ -160,29 +164,29 @@ void cRoot::Start(void)
|
||||
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())
|
||||
@ -282,30 +286,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 +320,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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ class cWorld;
|
||||
class cPlayer;
|
||||
class cCommandOutputCallback;
|
||||
class cCompositeChat;
|
||||
class cSettingsRepositoryInterface;
|
||||
|
||||
typedef cItemCallback<cPlayer> cPlayerListCallback;
|
||||
typedef cItemCallback<cWorld> cWorldListCallback;
|
||||
@ -53,7 +54,7 @@ public:
|
||||
cRoot(void);
|
||||
~cRoot();
|
||||
|
||||
void Start(void);
|
||||
void Start(std::unique_ptr<cSettingsRepositoryInterface> overridesRepo);
|
||||
|
||||
// tolua_begin
|
||||
cServer * GetServer(void) { return m_Server; }
|
||||
@ -204,7 +205,7 @@ private:
|
||||
void LoadGlobalSettings();
|
||||
|
||||
/// Loads the worlds from settings.ini, creates the worldmap
|
||||
void LoadWorlds(cIniFile & IniFile);
|
||||
void LoadWorlds(cSettingsRepositoryInterface & a_Settings);
|
||||
|
||||
/// Starts each world's life
|
||||
void StartWorlds(void);
|
||||
|
@ -185,12 +185,12 @@ void cServer::PlayerDestroying(const cPlayer * a_Player)
|
||||
|
||||
|
||||
|
||||
bool cServer::InitServer(cIniFile & a_SettingsIni, bool a_ShouldAuth)
|
||||
bool cServer::InitServer(cSettingsRepositoryInterface & a_Settings, bool a_ShouldAuth)
|
||||
{
|
||||
m_Description = a_SettingsIni.GetValueSet("Server", "Description", "MCServer - in C++!");
|
||||
m_MaxPlayers = a_SettingsIni.GetValueSetI("Server", "MaxPlayers", 100);
|
||||
m_bIsHardcore = a_SettingsIni.GetValueSetB("Server", "HardcoreEnabled", false);
|
||||
m_bAllowMultiLogin = a_SettingsIni.GetValueSetB("Server", "AllowMultiLogin", false);
|
||||
m_Description = a_Settings.GetValueSet("Server", "Description", "MCServer - in C++!");
|
||||
m_MaxPlayers = a_Settings.GetValueSetI("Server", "MaxPlayers", 100);
|
||||
m_bIsHardcore = a_Settings.GetValueSetB("Server", "HardcoreEnabled", false);
|
||||
m_bAllowMultiLogin = a_Settings.GetValueSetB("Server", "AllowMultiLogin", false);
|
||||
m_PlayerCount = 0;
|
||||
m_PlayerCountDiff = 0;
|
||||
|
||||
@ -205,9 +205,9 @@ bool cServer::InitServer(cIniFile & a_SettingsIni, bool a_ShouldAuth)
|
||||
LOGINFO("Compatible clients: %s", MCS_CLIENT_VERSIONS);
|
||||
LOGINFO("Compatible protocol versions %s", MCS_PROTOCOL_VERSIONS);
|
||||
|
||||
m_Ports = ReadUpgradeIniPorts(a_SettingsIni, "Server", "Ports", "Port", "PortsIPv6", "25565");
|
||||
m_Ports = ReadUpgradeIniPorts(a_Settings, "Server", "Ports", "Port", "PortsIPv6", "25565");
|
||||
|
||||
m_RCONServer.Initialize(a_SettingsIni);
|
||||
m_RCONServer.Initialize(a_Settings);
|
||||
|
||||
m_bIsConnected = true;
|
||||
|
||||
@ -226,16 +226,16 @@ bool cServer::InitServer(cIniFile & a_SettingsIni, bool a_ShouldAuth)
|
||||
}
|
||||
|
||||
// Check if both BungeeCord and online mode are on, if so, warn the admin:
|
||||
m_ShouldAllowBungeeCord = a_SettingsIni.GetValueSetB("Authentication", "AllowBungeeCord", false);
|
||||
m_ShouldAllowBungeeCord = a_Settings.GetValueSetB("Authentication", "AllowBungeeCord", false);
|
||||
if (m_ShouldAllowBungeeCord && m_ShouldAuthenticate)
|
||||
{
|
||||
LOGWARNING("WARNING: BungeeCord is allowed and server set to online mode. This is unsafe and will not work properly. Disable either authentication or BungeeCord in settings.ini.");
|
||||
}
|
||||
|
||||
m_ShouldLoadOfflinePlayerData = a_SettingsIni.GetValueSetB("PlayerData", "LoadOfflinePlayerData", false);
|
||||
m_ShouldLoadNamedPlayerData = a_SettingsIni.GetValueSetB("PlayerData", "LoadNamedPlayerData", true);
|
||||
m_ShouldLoadOfflinePlayerData = a_Settings.GetValueSetB("PlayerData", "LoadOfflinePlayerData", false);
|
||||
m_ShouldLoadNamedPlayerData = a_Settings.GetValueSetB("PlayerData", "LoadNamedPlayerData", true);
|
||||
|
||||
m_ClientViewDistance = a_SettingsIni.GetValueSetI("Server", "DefaultViewDistance", cClientHandle::DEFAULT_VIEW_DISTANCE);
|
||||
m_ClientViewDistance = a_Settings.GetValueSetI("Server", "DefaultViewDistance", cClientHandle::DEFAULT_VIEW_DISTANCE);
|
||||
if (m_ClientViewDistance < cClientHandle::MIN_VIEW_DISTANCE)
|
||||
{
|
||||
m_ClientViewDistance = cClientHandle::MIN_VIEW_DISTANCE;
|
||||
|
@ -38,8 +38,8 @@ class cClientHandle;
|
||||
typedef SharedPtr<cClientHandle> cClientHandlePtr;
|
||||
typedef std::list<cClientHandlePtr> cClientHandlePtrs;
|
||||
typedef std::list<cClientHandle *> cClientHandles;
|
||||
class cIniFile;
|
||||
class cCommandOutputCallback;
|
||||
class cSettingsRepositoryInterface;
|
||||
|
||||
|
||||
namespace Json
|
||||
@ -58,7 +58,7 @@ public:
|
||||
// tolua_end
|
||||
|
||||
virtual ~cServer() {}
|
||||
bool InitServer(cIniFile & a_SettingsIni, bool a_ShouldAuth);
|
||||
bool InitServer(cSettingsRepositoryInterface & a_Settings, bool a_ShouldAuth);
|
||||
|
||||
// tolua_begin
|
||||
|
||||
|
46
src/SettingsRepositoryInterface.h
Normal file
46
src/SettingsRepositoryInterface.h
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
class cSettingsRepositoryInterface
|
||||
{
|
||||
public:
|
||||
|
||||
enum errors
|
||||
{
|
||||
noID = -1,
|
||||
};
|
||||
|
||||
virtual ~cSettingsRepositoryInterface() = default;
|
||||
|
||||
virtual bool KeyExists(const AString keyname) const = 0;
|
||||
|
||||
virtual bool HasValue(const AString & a_KeyName, const AString & a_ValueName) const = 0;
|
||||
|
||||
virtual int AddKeyName(const AString & keyname) = 0;
|
||||
|
||||
virtual bool AddKeyComment(const AString & keyname, const AString & comment) = 0;
|
||||
|
||||
virtual AString GetKeyComment(const AString & keyname, const int commentID) const = 0;
|
||||
|
||||
virtual bool DeleteKeyComment(const AString & keyname, const int commentID) = 0;
|
||||
|
||||
virtual void AddValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value) = 0;
|
||||
|
||||
virtual std::vector<std::pair<AString, AString>> GetValues(AString a_keyName) = 0;
|
||||
|
||||
virtual AString GetValue (const AString & keyname, const AString & valuename, const AString & defValue = "") const = 0;
|
||||
|
||||
virtual AString GetValueSet (const AString & keyname, const AString & valuename, const AString & defValue = "") = 0;
|
||||
virtual int GetValueSetI(const AString & keyname, const AString & valuename, const int defValue = 0) = 0;
|
||||
virtual Int64 GetValueSetI(const AString & keyname, const AString & valuename, const Int64 defValue = 0) = 0;
|
||||
virtual bool GetValueSetB(const AString & keyname, const AString & valuename, const bool defValue = false) = 0;
|
||||
|
||||
virtual bool SetValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value, const bool a_CreateIfNotExists = true) = 0;
|
||||
virtual bool SetValueI(const AString & a_KeyName, const AString & a_ValueName, const int a_Value, const bool a_CreateIfNotExists = true) = 0;
|
||||
|
||||
|
||||
virtual bool DeleteValue(const AString & keyname, const AString & valuename) = 0;
|
||||
|
||||
|
||||
virtual bool Flush() = 0;
|
||||
};
|
42
src/main.cpp
42
src/main.cpp
@ -2,6 +2,7 @@
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "Root.h"
|
||||
#include "tclap/CmdLine.h"
|
||||
|
||||
#include <exception>
|
||||
#include <csignal>
|
||||
@ -14,7 +15,7 @@
|
||||
#include "OSSupport/NetworkSingleton.h"
|
||||
#include "BuildInfo.h"
|
||||
|
||||
|
||||
#include "MemorySettingsRepository.h"
|
||||
|
||||
|
||||
|
||||
@ -206,7 +207,7 @@ BOOL CtrlHandler(DWORD fdwCtrlType)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// universalMain - Main startup logic for both standard running and as a service
|
||||
|
||||
void universalMain()
|
||||
void universalMain(std::unique_ptr<cSettingsRepositoryInterface> overridesRepo)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE))
|
||||
@ -226,7 +227,7 @@ void universalMain()
|
||||
#endif
|
||||
{
|
||||
cRoot Root;
|
||||
Root.Start();
|
||||
Root.Start(std::move(overridesRepo));
|
||||
}
|
||||
#if !defined(ANDROID_NDK)
|
||||
catch (std::exception & e)
|
||||
@ -363,14 +364,39 @@ void WINAPI serviceMain(DWORD argc, TCHAR *argv[])
|
||||
|
||||
|
||||
|
||||
std::unique_ptr<cMemorySettingsRepository> parseArguments(int argc, char **argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
TCLAP::CmdLine cmd("MCServer");
|
||||
|
||||
TCLAP::ValueArg<int> slotsArg("s", "max-players", "Maximum number of slots for the server to use, overrides setting in setting.ini", false, -1, "number", cmd);
|
||||
|
||||
cmd.parse(argc, argv);
|
||||
|
||||
int slots = slotsArg.getValue();
|
||||
|
||||
auto repo = make_unique<cMemorySettingsRepository>();
|
||||
|
||||
repo->SetValueI("Server", "MaxPlayers", slots);
|
||||
|
||||
repo->SetReadOnly();
|
||||
|
||||
return repo;
|
||||
}
|
||||
catch (TCLAP::ArgException &e)
|
||||
{
|
||||
printf("error reading command line %s for arg %s", e.error().c_str(), e.argId().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// main:
|
||||
|
||||
int main( int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
UNUSED(argc);
|
||||
UNUSED(argv);
|
||||
|
||||
#if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER)
|
||||
InitLeakFinder();
|
||||
@ -425,6 +451,8 @@ int main( int argc, char **argv)
|
||||
// DEBUG: test the dumpfile creation:
|
||||
// *((int *)0) = 0;
|
||||
|
||||
auto argsRepo = parseArguments(argc, argv);
|
||||
|
||||
// Check if comm logging is to be enabled:
|
||||
for (int i = 0; i < argc; i++)
|
||||
{
|
||||
@ -483,7 +511,7 @@ int main( int argc, char **argv)
|
||||
#endif
|
||||
{
|
||||
// Not running as a service, do normal startup
|
||||
universalMain();
|
||||
universalMain(std::move(argsRepo));
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER)
|
||||
|
Loading…
Reference in New Issue
Block a user