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"
|
#include "ini.hpp"
|
||||||
using namespace sosc::ini;
|
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
|
File* File::Open
|
||||||
(const std::string& filename, const std::vector<Rule>& rules)
|
(const std::string& filename, const std::vector<Rule>& rules)
|
||||||
{
|
{
|
||||||
|
@ -54,7 +77,7 @@ File* File::Open
|
||||||
str::tolower(str::trim(&(parts[0])));
|
str::tolower(str::trim(&(parts[0])));
|
||||||
str::trim(&(parts[1]));
|
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,
|
throw LoadError(ini, line_number,
|
||||||
"Duplicate key-value pair field in section."
|
"Duplicate key-value pair field in section."
|
||||||
);
|
);
|
||||||
|
@ -69,16 +92,15 @@ File* File::Open
|
||||||
"Required section '", rule.name, "' not found."
|
"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({
|
throw LoadError(ini, -1, str::join({
|
||||||
"Multiple instances of '", rule.name, "' section "
|
"Multiple instances of '", rule.name, "' section "
|
||||||
"when explicitely not allowed."
|
"when explicitely not allowed."
|
||||||
}));
|
}));
|
||||||
|
|
||||||
for(auto& section : ini[rule.name].sections) {
|
for(auto& section : (*ini)[rule.name].sections) {
|
||||||
for(auto &field : rule.required_fields) {
|
for(auto &field : rule.required_fields) {
|
||||||
str::tolower(&field.name);
|
if(section.values.count(str::tolower(field.name)) == 0)
|
||||||
if(section.values.count(field.name) == 0)
|
|
||||||
throw LoadError(ini, -1, str::join({
|
throw LoadError(ini, -1, str::join({
|
||||||
"Required field '", field.name, "' in section '",
|
"Required field '", field.name, "' in section '",
|
||||||
rule.name, "' not found."
|
rule.name, "' not found."
|
||||||
|
@ -115,12 +137,20 @@ const File::SectionList&
|
||||||
{
|
{
|
||||||
str::tolower(&name);
|
str::tolower(&name);
|
||||||
if(this->section_lists.count(name) > 0)
|
if(this->section_lists.count(name) > 0)
|
||||||
return this->section_lists[name];
|
return this->section_lists.at(name);
|
||||||
else
|
else
|
||||||
throw std::range_error("Section name not found.");
|
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
|
File::SectionList::operator[] (std::string key) const
|
||||||
{
|
{
|
||||||
return this->sections[0][key];
|
return this->sections[0][key];
|
||||||
|
@ -135,12 +165,17 @@ const File::SectionList::Section&
|
||||||
throw std::range_error("Section index out-of-bounds.");
|
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
|
File::SectionList::Section::operator[] (std::string key) const
|
||||||
{
|
{
|
||||||
str::tolower(&key);
|
str::tolower(&key);
|
||||||
if(this->values.count(key) > 0)
|
if(this->values.count(key) > 0)
|
||||||
return this->values[key];
|
return Proxy(this->values.at(key));
|
||||||
else
|
else
|
||||||
throw std::range_error("Key not found in section.");
|
throw std::range_error("Key not found in section.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,46 @@
|
||||||
|
|
||||||
namespace sosc {
|
namespace sosc {
|
||||||
namespace ini {
|
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 {
|
class File {
|
||||||
public:
|
public:
|
||||||
struct Proxy {
|
struct Proxy {
|
||||||
std::string value;
|
explicit Proxy(const std::string& value) : value(value) {};
|
||||||
Proxy(const std::string& value) : value(value) {};
|
|
||||||
|
|
||||||
explicit operator bool() const {
|
explicit operator bool() const {
|
||||||
if(this->value == "1" || this->value == "true")
|
if(this->value == "1" || this->value == "true")
|
||||||
|
@ -34,7 +69,7 @@ public:
|
||||||
&& !std::is_same<std::allocator<char>, Decayed>::value
|
&& !std::is_same<std::allocator<char>, Decayed>::value
|
||||||
&& !std::is_same<std::initializer_list<char>, Decayed>::value
|
&& !std::is_same<std::initializer_list<char>, Decayed>::value
|
||||||
>::type
|
>::type
|
||||||
> explicit operator T() {
|
> explicit operator T() const {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << this->value;
|
ss << this->value;
|
||||||
|
|
||||||
|
@ -44,58 +79,27 @@ public:
|
||||||
else
|
else
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
struct Rule {
|
std::string value;
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SectionList {
|
class SectionList {
|
||||||
public:
|
public:
|
||||||
class Section {
|
class Section {
|
||||||
public:
|
public:
|
||||||
const std::string& operator[] (std::string key) const;
|
bool HasKey(std::string name) const;
|
||||||
|
const Proxy& operator[] (std::string key) const;
|
||||||
private:
|
private:
|
||||||
Section() = default;
|
|
||||||
|
|
||||||
std::map<std::string, std::string> values;
|
std::map<std::string, std::string> values;
|
||||||
friend class File;
|
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;
|
const Section& operator[] (int index) const;
|
||||||
private:
|
private:
|
||||||
SectionList() = default;
|
|
||||||
|
|
||||||
std::vector<Section> sections;
|
std::vector<Section> sections;
|
||||||
friend class File;
|
friend class File;
|
||||||
};
|
};
|
||||||
|
@ -103,6 +107,8 @@ public:
|
||||||
File(const File&) = delete;
|
File(const File&) = delete;
|
||||||
static File* Open
|
static File* Open
|
||||||
(const std::string& filename, const std::vector<Rule>& rules = {});
|
(const std::string& filename, const std::vector<Rule>& rules = {});
|
||||||
|
|
||||||
|
bool HasSection(std::string name) const;
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
const SectionList& operator[] (std::string name) const;
|
const SectionList& operator[] (std::string name) const;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef SOSC_UTIL_STRING_H
|
#ifndef SOSC_UTIL_STRING_H
|
||||||
#define SOSC_UTIL_STRING_H
|
#define SOSC_UTIL_STRING_H
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
|
@ -88,6 +88,16 @@ bool sosc::MasterClient::ProcessLogin(Packet &pck) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sosc::MasterClient::ProcessRegistration(Packet &pck) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sosc::MasterClient::ListServers(Packet &pck) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool sosc::MasterClient::Close() {
|
bool sosc::MasterClient::Close() {
|
||||||
this->sock.Close();
|
this->sock.Close();
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <sock/pool.hpp>
|
||||||
|
|
||||||
#include "db/database.hpp"
|
#include "db/database.hpp"
|
||||||
#include "hosts/master.hpp"
|
#include "hosts/master.hpp"
|
||||||
|
@ -43,26 +44,69 @@ int main(int argc, char **argv) {
|
||||||
if(argc < 2)
|
if(argc < 2)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
auto test = ini::File::Open("test.ini", {
|
ini::File* config;
|
||||||
ini::File::Rule("test section", true, false, {
|
try {
|
||||||
ini::File::Rule::Field<bool>("test")
|
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))
|
if(!db::init_databases(nullptr))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
_ctx.master_intra = new master_intra_ctx;
|
_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;
|
_ctx.master_client = new master_client_ctx;
|
||||||
master_client_start(8008, poolinfo_t());
|
master_client_start(
|
||||||
} else {
|
(uint16_t)(*config)["master"]["client port"],
|
||||||
_ctx.slave_count = 1;
|
poolinfo_t()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(config->HasSection("slave")) {
|
||||||
|
_ctx.slave_count = (*config)["slave"].SectionCount();
|
||||||
_ctx.slaves = new slave_ctx[_ctx.slave_count];
|
_ctx.slaves = new slave_ctx[_ctx.slave_count];
|
||||||
|
|
||||||
for(int i = 0; i < _ctx.slave_count; ++i)
|
for(int i = 0; i < _ctx.slave_count; ++i) {
|
||||||
slave_start(1234, poolinfo_t(), _ctx.slaves + 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;
|
std::cout << "Server threads started. Type STOP to cancel." << std::endl;
|
||||||
|
|
Loading…
Reference in a new issue