ACTIVE ABILITY: WOOMED
This commit is contained in:
parent
6092bb9f66
commit
045db422a0
6 changed files with 163 additions and 62 deletions
5
resources/server/test.ini
Normal file
5
resources/server/test.ini
Normal file
|
@ -0,0 +1,5 @@
|
|||
; test ini file
|
||||
|
||||
[Test Section]
|
||||
TEST = ARE YOU SQWOOBIN
|
||||
ANSWER = TRUE
|
|
@ -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<Rule>& 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.");
|
||||
}
|
||||
|
|
|
@ -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<Field>& required_fields
|
||||
) : name(name),
|
||||
required(required),
|
||||
allow_multiple(allow_multiple),
|
||||
required_fields(required_fields) {};
|
||||
|
||||
std::string name;
|
||||
bool required;
|
||||
bool allow_multiple;
|
||||
std::vector<Field> 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<std::allocator<char>, Decayed>::value
|
||||
&& !std::is_same<std::initializer_list<char>, 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<typename T = std::string>
|
||||
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<Field>& required_fields
|
||||
) : name(name),
|
||||
required(required),
|
||||
allow_multiple(allow_multiple),
|
||||
required_fields(required_fields) {};
|
||||
|
||||
std::string name;
|
||||
bool required;
|
||||
bool allow_multiple;
|
||||
std::vector<Field> 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<std::string, std::string> 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<Section> sections;
|
||||
friend class File;
|
||||
};
|
||||
|
@ -103,6 +107,8 @@ public:
|
|||
File(const File&) = delete;
|
||||
static File* Open
|
||||
(const std::string& filename, const std::vector<Rule>& rules = {});
|
||||
|
||||
bool HasSection(std::string name) const;
|
||||
void Close();
|
||||
|
||||
const SectionList& operator[] (std::string name) const;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef SOSC_UTIL_STRING_H
|
||||
#define SOSC_UTIL_STRING_H
|
||||
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <string>
|
||||
#include <ctime>
|
||||
#include <thread>
|
||||
#include <sock/pool.hpp>
|
||||
|
||||
#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<bool>("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;
|
||||
|
|
Loading…
Reference in a new issue