From 045db422a0625063912a17bd546cc3ba7e5c650d Mon Sep 17 00:00:00 2001 From: malloc Date: Thu, 8 Nov 2018 17:34:56 -0600 Subject: [PATCH] ACTIVE ABILITY: WOOMED --- resources/server/test.ini | 5 ++ src/common/utils/ini.cpp | 53 +++++++++++++++--- src/common/utils/ini.hpp | 88 ++++++++++++++++-------------- src/common/utils/string.hpp | 1 + src/server/hosts/master_client.cpp | 10 ++++ src/server/main.cpp | 68 +++++++++++++++++++---- 6 files changed, 163 insertions(+), 62 deletions(-) create mode 100644 resources/server/test.ini diff --git a/resources/server/test.ini b/resources/server/test.ini new file mode 100644 index 0000000..2e2c9d7 --- /dev/null +++ b/resources/server/test.ini @@ -0,0 +1,5 @@ +; test ini file + +[Test Section] +TEST = ARE YOU SQWOOBIN +ANSWER = TRUE \ No newline at end of file diff --git a/src/common/utils/ini.cpp b/src/common/utils/ini.cpp index adfd0d3..7f77aed 100644 --- a/src/common/utils/ini.cpp +++ b/src/common/utils/ini.cpp @@ -1,6 +1,29 @@ #include "ini.hpp" using namespace sosc::ini; +bool Field::Test() const { + try { + switch(type) { + case INT32: + (int32_t)File::Proxy(name); + break; + case UINT32: + (uint32_t)File::Proxy(name); + break; + case DOUBLE: + (double)File::Proxy(name); + break; + case BOOL: + (bool)File::Proxy(name); + break; + } + + return true; + } catch(...) { + return false; + } +} + File* File::Open (const std::string& filename, const std::vector& rules) { @@ -54,7 +77,7 @@ File* File::Open str::tolower(str::trim(&(parts[0]))); str::trim(&(parts[1])); - if(parts[0] == "" || active_section->values.count(parts[0]) == 0) + if(parts[0] == "" || active_section->values.count(parts[0]) > 0) throw LoadError(ini, line_number, "Duplicate key-value pair field in section." ); @@ -69,16 +92,15 @@ File* File::Open "Required section '", rule.name, "' not found." })); - if(!rule.allow_multiple && ini[rule.name].sections.size() > 1) + if(!rule.allow_multiple && (*ini)[rule.name].sections.size() > 1) throw LoadError(ini, -1, str::join({ "Multiple instances of '", rule.name, "' section " "when explicitely not allowed." })); - for(auto& section : ini[rule.name].sections) { + for(auto& section : (*ini)[rule.name].sections) { for(auto &field : rule.required_fields) { - str::tolower(&field.name); - if(section.values.count(field.name) == 0) + if(section.values.count(str::tolower(field.name)) == 0) throw LoadError(ini, -1, str::join({ "Required field '", field.name, "' in section '", rule.name, "' not found." @@ -115,12 +137,20 @@ const File::SectionList& { str::tolower(&name); if(this->section_lists.count(name) > 0) - return this->section_lists[name]; + return this->section_lists.at(name); else throw std::range_error("Section name not found."); } -const std::string& +bool File::SectionList::HasKey(std::string name) const { + return this->sections[0].HasKey(name); +} + +int File::SectionList::SectionCount() const { + return this->sections.size(); +} + +const File::Proxy& File::SectionList::operator[] (std::string key) const { return this->sections[0][key]; @@ -135,12 +165,17 @@ const File::SectionList::Section& throw std::range_error("Section index out-of-bounds."); } -const std::string& +bool File::SectionList::Section::HasKey(std::string name) const { + str::tolower(&name); + return this->values.count(name) == 1; +} + +const File::Proxy& File::SectionList::Section::operator[] (std::string key) const { str::tolower(&key); if(this->values.count(key) > 0) - return this->values[key]; + return Proxy(this->values.at(key)); else throw std::range_error("Key not found in section."); } diff --git a/src/common/utils/ini.hpp b/src/common/utils/ini.hpp index c6f3215..ac9a1cb 100644 --- a/src/common/utils/ini.hpp +++ b/src/common/utils/ini.hpp @@ -11,11 +11,46 @@ namespace sosc { namespace ini { +struct Field { + enum kType { + STRING, + INT32, + UINT32, + DOUBLE, + BOOL + }; + + explicit Field + (const std::string& name, kType type = STRING) + : name(name), type(type) {} + bool Test() const; + + std::string name; + kType type; +}; + +struct Rule { + Rule() = delete; + Rule( + const std::string& name, + bool required, + bool allow_multiple, + const std::vector& required_fields + ) : name(name), + required(required), + allow_multiple(allow_multiple), + required_fields(required_fields) {}; + + std::string name; + bool required; + bool allow_multiple; + std::vector required_fields; +}; + class File { public: struct Proxy { - std::string value; - Proxy(const std::string& value) : value(value) {}; + explicit Proxy(const std::string& value) : value(value) {}; explicit operator bool() const { if(this->value == "1" || this->value == "true") @@ -34,7 +69,7 @@ public: && !std::is_same, Decayed>::value && !std::is_same, Decayed>::value >::type - > explicit operator T() { + > explicit operator T() const { std::stringstream ss; ss << this->value; @@ -44,58 +79,27 @@ public: else return retval; } - }; - struct Rule { - template - struct Field { - Field(const std::string& name) : name(name) {} - bool Test() { - try { - (T)Proxy(this->name); - return true; - } catch(...) { - return false; - } - } - - std::string name; - }; - - Rule() = delete; - Rule( - const std::string& name, - bool required, - bool allow_multiple, - const std::vector& required_fields - ) : name(name), - required(required), - allow_multiple(allow_multiple), - required_fields(required_fields) {}; - - std::string name; - bool required; - bool allow_multiple; - std::vector required_fields; + std::string value; }; class SectionList { public: class Section { public: - const std::string& operator[] (std::string key) const; + bool HasKey(std::string name) const; + const Proxy& operator[] (std::string key) const; private: - Section() = default; - std::map values; friend class File; }; - const std::string& operator[] (std::string key) const; + bool HasKey(std::string name) const; + int SectionCount() const; + + const Proxy& operator[] (std::string key) const; const Section& operator[] (int index) const; private: - SectionList() = default; - std::vector
sections; friend class File; }; @@ -103,6 +107,8 @@ public: File(const File&) = delete; static File* Open (const std::string& filename, const std::vector& rules = {}); + + bool HasSection(std::string name) const; void Close(); const SectionList& operator[] (std::string name) const; diff --git a/src/common/utils/string.hpp b/src/common/utils/string.hpp index 3fba017..bf16591 100644 --- a/src/common/utils/string.hpp +++ b/src/common/utils/string.hpp @@ -1,6 +1,7 @@ #ifndef SOSC_UTIL_STRING_H #define SOSC_UTIL_STRING_H +#include #include #include #include diff --git a/src/server/hosts/master_client.cpp b/src/server/hosts/master_client.cpp index 81cc3e5..d10db51 100644 --- a/src/server/hosts/master_client.cpp +++ b/src/server/hosts/master_client.cpp @@ -88,6 +88,16 @@ bool sosc::MasterClient::ProcessLogin(Packet &pck) { return true; } +bool sosc::MasterClient::ProcessRegistration(Packet &pck) { + + return true; +} + +bool sosc::MasterClient::ListServers(Packet &pck) { + + return true; +} + bool sosc::MasterClient::Close() { this->sock.Close(); return false; diff --git a/src/server/main.cpp b/src/server/main.cpp index 2fd9716..5dad19c 100644 --- a/src/server/main.cpp +++ b/src/server/main.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "db/database.hpp" #include "hosts/master.hpp" @@ -43,26 +44,69 @@ int main(int argc, char **argv) { if(argc < 2) return -1; - auto test = ini::File::Open("test.ini", { - ini::File::Rule("test section", true, false, { - ini::File::Rule::Field("test") - }), - }); + ini::File* config; + try { + config = ini::File::Open(SOSC_RESC("config.ini"), { + ini::Rule("general", true, false, { + ini::Field("run master", ini::Field::BOOL), + ini::Field("master host", ini::Field::STRING), + ini::Field("master port", ini::Field::UINT32), + }), + ini::Rule("defaults", true, false, { + ini::Field("initial count", ini::Field::UINT32), + ini::Field("initial size", ini::Field::UINT32), + ini::Field("size growth", ini::Field::UINT32), - if(argv[1][0] == 'm') { + ini::Field("max size", ini::Field::INT32), + ini::Field("max count", ini::Field::INT32), + ini::Field("max total", ini::Field::INT32), + ini::Field("tolerance", ini::Field::INT32), + }), + ini::Rule("master", true, false, { + ini::Field("client port", ini::Field::UINT32), + ini::Field("intra port", ini::Field::UINT32), + }), + ini::Rule("slave", false, true, { + ini::Field("port", ini::Field::UINT32), + ini::Field("name", ini::Field::STRING), + }) + }); + } catch(const std::exception& e) { + std::cout << e.what() << std::endl; + return -1; + } + + poolinfo_t info = poolinfo_t(); + info.initial_count = + + if((*config)["master"]["run master"]) { if(!db::init_databases(nullptr)) return -1; _ctx.master_intra = new master_intra_ctx; - master_intra_start(1234, poolinfo_t()); + master_intra_start( + (uint16_t)(*config)["master"]["intra port"], + poolinfo_t() + ); + _ctx.master_client = new master_client_ctx; - master_client_start(8008, poolinfo_t()); - } else { - _ctx.slave_count = 1; + master_client_start( + (uint16_t)(*config)["master"]["client port"], + poolinfo_t() + ); + } + + if(config->HasSection("slave")) { + _ctx.slave_count = (*config)["slave"].SectionCount(); _ctx.slaves = new slave_ctx[_ctx.slave_count]; - for(int i = 0; i < _ctx.slave_count; ++i) - slave_start(1234, poolinfo_t(), _ctx.slaves + i); + for(int i = 0; i < _ctx.slave_count; ++i) { + slave_start( + (uint16_t)(*config)["slave"][i]["port"], + poolinfo_t(), + _ctx.slaves + i + ); + } } std::cout << "Server threads started. Type STOP to cancel." << std::endl;