Inter server C++ conversion (#2322)

* Renamed inter.c to inter.cpp and refactored it

* Converted inter_server.conf to inter_server.yml

* Updated the makefiles

* Refactored inter-server storage handling logic

* Fixed a bug with wrong maximum being displayed
When you took out an item of the storage it would always display the maximum amount of the normal storage.

* Fixed a bug with storages that are over maximum

Thanks to @Akkarinage, @Lemongrass3110 and @Jeybla
This commit is contained in:
Jittapan Pluemsumran
2017-08-14 06:27:58 +07:00
committed by Lemongrass3110
parent f9c6b92a63
commit cc1d26fe74
30 changed files with 246 additions and 184 deletions

View File

@@ -18,6 +18,12 @@ CHAR_OBJ = $(shell ls *.c | sed -e "s/\.c/\.o/g") $(shell ls *.cpp | sed -e "s/\
CHAR_DIR_OBJ = $(CHAR_OBJ:%=obj/%)
CHAR_H = $(shell ls ../char/*.h)
YAML_CPP_OBJ = $(shell find ../../3rdparty/yaml-cpp/ -type f -name "*.cpp" | sed -e "s/\.cpp/\.o/g" )
YAML_CPP_DIR_OBJ = $(YAML_CPP_OBJ:%=obj/%)
YAML_CPP_AR = ../../3rdparty/yaml-cpp/obj/yaml-cpp.a
YAML_CPP_H = $(shell find ../../3rdparty/yaml-cpp/ -type f -name "*.h")
YAML_CPP_INCLUDE = -I../../3rdparty/yaml-cpp/include
HAVE_MYSQL=@HAVE_MYSQL@
ifeq ($(HAVE_MYSQL),yes)
SERVER_DEPENDS=char-server
@@ -26,8 +32,6 @@ else
endif
ALL_DEPENDS=server
CXXFLAGS=-std=c++11
@SET_MAKE@
#####################################################################
@@ -51,9 +55,9 @@ help:
#####################################################################
char-server: obj $(CHAR_DIR_OBJ) $(LIBCONFIG_AR) $(COMMON_AR)
char-server: obj $(CHAR_DIR_OBJ) $(LIBCONFIG_AR) $(COMMON_AR) $(YAML_CPP_AR)
@echo " LD @OCHR@@EXEEXT@"
@@CXX@ @LDFLAGS@ -o ../../@OCHR@@EXEEXT@ $(CHAR_DIR_OBJ) $(LIBCONFIG_AR) $(COMMON_AR) $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @MYSQL_LIBS@
@@CXX@ @LDFLAGS@ -o ../../@OCHR@@EXEEXT@ $(CHAR_DIR_OBJ) $(LIBCONFIG_AR) $(COMMON_AR) $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) $(YAML_CPP_AR) @LIBS@ @MYSQL_LIBS@
needs_mysql:
@echo "MySQL not found or disabled by the configure script"
@@ -63,13 +67,13 @@ obj:
@echo " MKDIR obj"
@-mkdir obj
obj/%.o: %.c $(CHAR_H) $(COMMON_H) $(MT19937AR_H) $(LIBCONFIG_H)
obj/%.o: %.c $(CHAR_H) $(COMMON_H) $(MT19937AR_H) $(LIBCONFIG_H) $(YAML_CPP_H)
@echo " CC $<"
@@CC@ @CFLAGS@ $(COMMON_INCLUDE) $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
@@CC@ @CFLAGS@ $(COMMON_INCLUDE) $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) $(YAML_CPP_INCLUDE) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
obj/%.o: %.cpp $(CHAR_H) $(COMMON_H) $(MT19937AR_H) $(LIBCONFIG_H)
obj/%.o: %.cpp $(CHAR_H) $(COMMON_H) $(MT19937AR_H) $(LIBCONFIG_H) $(YAML_CPP_H)
@echo " CXX $<"
@@CXX@ @CXXFLAGS@ $(COMMON_INCLUDE) $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
@@CXX@ @CXXFLAGS@ $(COMMON_INCLUDE) $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) $(YAML_CPP_INCLUDE) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
# missing object files
$(COMMON_AR):
@@ -80,3 +84,6 @@ $(MT19937AR_OBJ):
$(LIBCONFIG_AR):
@$(MAKE) -C ../../3rdparty/libconfig
$(YAML_CPP_AR):
@$(MAKE) -C ../../3rdparty/yaml-cpp

View File

@@ -94,6 +94,7 @@
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>$(DefineConstants);WIN32;FD_SETSIZE=4096;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\yaml-cpp\include\</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -109,6 +110,7 @@
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>$(DefineConstants);WIN32;FD_SETSIZE=4096;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\yaml-cpp\include\</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -126,6 +128,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>$(DefineConstants);WIN32;FD_SETSIZE=4096;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\yaml-cpp\include\</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -145,6 +148,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>$(DefineConstants);WIN32;FD_SETSIZE=4096;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\yaml-cpp\include\</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -182,7 +186,7 @@
<ClCompile Include="char_cnslif.c" />
<ClCompile Include="char_logif.c" />
<ClCompile Include="char_mapif.c" />
<ClCompile Include="inter.c" />
<ClCompile Include="inter.cpp" />
<ClCompile Include="int_achievement.c" />
<ClCompile Include="int_auction.c" />
<ClCompile Include="int_clan.c" />
@@ -194,7 +198,7 @@
<ClCompile Include="int_party.c" />
<ClCompile Include="int_pet.c" />
<ClCompile Include="int_quest.c" />
<ClCompile Include="int_storage.c" />
<ClCompile Include="int_storage.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@@ -112,10 +112,10 @@
<ClCompile Include="int_quest.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="int_storage.c">
<ClCompile Include="int_storage.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="inter.c">
<ClCompile Include="inter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="int_clan.c">

View File

@@ -4,6 +4,13 @@
#ifndef _INT_ACHIEVEMENT_SQL_H_
#define _INT_ACHIEVEMENT_SQL_H_
#ifdef __cplusplus
extern "C" {
#endif
int inter_achievement_parse_frommap(int fd);
#ifdef __cplusplus
}
#endif
#endif /* _INT_ACHIEVEMENT_SQL_H_ */

View File

@@ -4,9 +4,17 @@
#ifndef _INT_AUCTION_SQL_H_
#define _INT_AUCTION_SQL_H_
#ifdef __cplusplus
extern "C" {
#endif
int inter_auction_parse_frommap(int fd);
int inter_auction_sql_init(void);
void inter_auction_sql_final(void);
#ifdef __cplusplus
}
#endif
#endif /* _INT_AUCTION_SQL_H_ */

View File

@@ -4,7 +4,16 @@
#ifndef _INT_CLAN_H_
#define _INT_CLAN_H_
int inter_clan_parse_frommap( int fd );
int inter_clan_init(void);
void inter_clan_final(void);
#ifdef __cplusplus
extern "C" {
#endif
int inter_clan_parse_frommap( int fd );
int inter_clan_init(void);
void inter_clan_final(void);
#ifdef __cplusplus
}
#endif
#endif /* _INT_CLAN_H_ */

View File

@@ -4,7 +4,15 @@
#ifndef _QUEST_H_
#define _QUEST_H_
#ifdef __cplusplus
extern "C" {
#endif
int inter_quest_parse_frommap(int fd);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,6 +1,8 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
#include "int_storage.h"
#include "../common/malloc.h"
#include "../common/mmo.h"
#include "../common/showmsg.h"
@@ -12,23 +14,13 @@
#include <stdlib.h>
#define STORAGE_MEMINC 16
/**
* Check if sotrage ID is valid
* Check if storage ID is valid
* @param id Storage ID
* @return True:Valid, False:Invalid
**/
bool inter_premiumStorage_exists(uint8 id) {
if (interserv_config.storages && interserv_config.storage_count) {
int i;
for (i = 0; i < interserv_config.storage_count; i++) {
if (interserv_config.storages[i].id == id)
return true;
}
}
return false;
return interserv_config.storages.find(id) != interserv_config.storages.end();
}
/**
@@ -37,13 +29,8 @@ bool inter_premiumStorage_exists(uint8 id) {
* @return Max amount
**/
int inter_premiumStorage_getMax(uint8 id) {
if (interserv_config.storages && interserv_config.storage_count) {
int i;
for (i = 0; i < interserv_config.storage_count; i++) {
if (&interserv_config.storages[i] && interserv_config.storages[i].id == id)
return interserv_config.storages[i].max_num;
}
}
if (inter_premiumStorage_exists(id))
return interserv_config.storages[id]->max_num;
return MAX_STORAGE;
}
@@ -53,13 +40,8 @@ int inter_premiumStorage_getMax(uint8 id) {
* @return Table name
**/
const char *inter_premiumStorage_getTableName(uint8 id) {
if (interserv_config.storages && interserv_config.storage_count) {
int i;
for (i = 0; i < interserv_config.storage_count; i++) {
if (&interserv_config.storages[i] && interserv_config.storages[i].id == id)
return interserv_config.storages[i].table;
}
}
if (inter_premiumStorage_exists(id))
return interserv_config.storages[id]->table;
return schema_config.storage_db;
}
@@ -69,13 +51,8 @@ const char *inter_premiumStorage_getTableName(uint8 id) {
* @return printable name
**/
const char *inter_premiumStorage_getPrintableName(uint8 id) {
if (interserv_config.storages && interserv_config.storage_count) {
int i;
for (i = 0; i < interserv_config.storage_count; i++) {
if (&interserv_config.storages[i] && interserv_config.storages[i].id == id)
return interserv_config.storages[i].name;
}
}
if (inter_premiumStorage_exists(id))
return interserv_config.storages[id]->name;
return "Storage";
}
@@ -170,20 +147,18 @@ bool guild_storage_fromsql(int guild_id, struct s_storage* p)
}
static void inter_storage_checkDB(void) {
int i = 0;
// Checking storage tables
for (i = 0; i < interserv_config.storage_count; i++) {
if (!&interserv_config.storages[i] || !interserv_config.storages[i].name || !interserv_config.storages[i].table || *interserv_config.storages[i].table == '\0')
continue;
for (auto storage_table : interserv_config.storages) {
if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `id`,`account_id`,`nameid`,`amount`,`equip`,`identify`,`refine`,"
"`attribute`,`card0`,`card1`,`card2`,`card3`,`option_id0`,`option_val0`,`option_parm0`,`option_id1`,`option_val1`,`option_parm1`,"
"`option_id2`,`option_val2`,`option_parm2`,`option_id3`,`option_val3`,`option_parm3`,`option_id4`,`option_val4`,`option_parm4`,"
"`expire_time`,`bound`,`unique_id`"
" FROM `%s` LIMIT 1;", interserv_config.storages[i].table) ){
" FROM `%s` LIMIT 1;", storage_table.second->table)) {
Sql_ShowDebug(sql_handle);
}else{
Sql_FreeResult(sql_handle);
}
}
Sql_FreeResult(sql_handle);
}
//---------------------------------------------------------
@@ -381,7 +356,7 @@ bool mapif_parse_itembound_retrieve(int fd)
memcpy(&items[count++], &item, sizeof(struct item));
Sql_FreeResult(sql_handle);
ShowInfo("Found '"CL_WHITE"%d"CL_RESET"' guild bound item(s) from CID = "CL_WHITE"%d"CL_RESET", AID = %d, Guild ID = "CL_WHITE"%d"CL_RESET".\n", count, char_id, account_id, guild_id);
ShowInfo("Found '" CL_WHITE "%d" CL_RESET "' guild bound item(s) from CID = " CL_WHITE "%d" CL_RESET ", AID = %d, Guild ID = " CL_WHITE "%d" CL_RESET ".\n", count, char_id, account_id, guild_id);
if (!count) { //No items found - No need to continue
StringBuf_Destroy(&buf);
SqlStmt_Free(stmt);

View File

@@ -4,6 +4,8 @@
#ifndef _INT_STORAGE_SQL_H_
#define _INT_STORAGE_SQL_H_
#include "../common/cbasetypes.h"
#ifdef __cplusplus
extern "C" {
#endif

View File

@@ -2,6 +2,7 @@
// For more information, see LICENCE in the main folder
#include "../common/mmo.h"
#include "../common/cbasetypes.h"
#include "../common/malloc.h"
#include "../common/strlib.h"
#include "../common/showmsg.h"
@@ -24,6 +25,10 @@
#include "int_clan.h"
#include "int_achievement.h"
#include <yaml-cpp/yaml.h>
#include <string>
#include <vector>
#include <stdlib.h>
#include <sys/stat.h> // for stat/lstat/fstat - [Dekamaster/Ultimate GM Tool]
@@ -345,7 +350,7 @@ void geoip_readdb(void){
geoip_cache = (unsigned char *) aMalloc(sizeof(unsigned char) * bufa.st_size);
if(fread(geoip_cache, sizeof(unsigned char), bufa.st_size, db) != bufa.st_size) { ShowError("geoip_cache reading didn't read all elements \n"); }
fclose(db);
ShowStatus("Finished Reading "CL_GREEN"GeoIP"CL_RESET" Database.\n");
ShowStatus("Finished Reading " CL_GREEN "GeoIP" CL_RESET " Database.\n");
}
/* [Dekamaster/Nightroad] */
/* WHY NOT A DBMAP: There are millions of entries in GeoIP and it has its own algorithm to go quickly through them, a DBMap wouldn't be efficient */
@@ -804,7 +809,7 @@ static int inter_config_read(const char* cfgName)
else if(!strcmpi(w1,"log_inter"))
charserv_config.log_inter = atoi(w2);
else if(!strcmpi(w1,"inter_server_conf"))
strcpy(interserv_config.cfgFile, w2);
interserv_config.cfgFile = w2;
else if(!strcmpi(w1,"import"))
inter_config_read(w2);
}
@@ -833,85 +838,102 @@ int inter_log(char* fmt, ...)
return 0;
}
static void yaml_invalid_warning(const char* fmt, YAML::Node &node, std::string &file) {
YAML::Emitter out;
out << node;
ShowWarning(fmt, file.c_str());
ShowMessage("%s\n", out.c_str());
}
/**
* Read inter config file
**/
static void inter_config_readConf(void) {
int count = 0;
config_setting_t *config = NULL;
std::vector<std::string> directories = { "conf/", "conf/import/" };
static const std::string file_name(interserv_config.cfgFile);
if (conf_read_file(&interserv_config.cfg, interserv_config.cfgFile))
return;
for (auto directory : directories) {
std::string current_file = directory + file_name;
YAML::Node config;
int count = 0;
// Read storages
config = config_lookup(&interserv_config.cfg, "storages");
if (config && (count = config_setting_length(config))) {
int i;
for (i = 0; i < count; i++) {
int id, max_num;
const char *name, *tablename;
struct s_storage_table table;
config_setting_t *entry = config_setting_get_elem(config, i);
if (!config_setting_lookup_int(entry, "id", &id)) {
ShowConfigWarning(entry, "inter_config_readConf: Cannot find storage \"id\" in member %d", i);
continue;
}
if (!config_setting_lookup_string(entry, "name", &name)) {
ShowConfigWarning(entry, "inter_config_readConf: Cannot find storage \"name\" in member %d", i);
continue;
}
if (!config_setting_lookup_string(entry, "table", &tablename)) {
ShowConfigWarning(entry, "inter_config_readConf: Cannot find storage \"table\" in member %d", i);
continue;
}
if (!config_setting_lookup_int(entry, "max", &max_num))
max_num = MAX_STORAGE;
else if (max_num > MAX_STORAGE) {
ShowConfigWarning(entry, "Storage \"%s\" has \"max\" %d, max is MAX_STORAGE (%d)!\n", name, max_num, MAX_STORAGE);
max_num = MAX_STORAGE;
}
memset(&table, 0, sizeof(struct s_storage_table));
RECREATE(interserv_config.storages, struct s_storage_table, interserv_config.storage_count+1);
interserv_config.storages[interserv_config.storage_count].id = id;
safestrncpy(interserv_config.storages[interserv_config.storage_count].name, name, NAME_LENGTH);
safestrncpy(interserv_config.storages[interserv_config.storage_count].table, tablename, DB_NAME_LEN);
interserv_config.storages[interserv_config.storage_count].max_num = max_num;
interserv_config.storage_count++;
try {
config = YAML::LoadFile(current_file);
}
catch (std::exception &e) {
ShowError("Cannot read storage definition file '" CL_WHITE "%s" CL_RESET "' (Caused by : " CL_WHITE "%s" CL_RESET ").\n", current_file.c_str(), e.what());
return;
}
}
ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' storage informations in '"CL_WHITE"%s"CL_RESET"'\n", interserv_config.storage_count, interserv_config.cfgFile);
if (config["Storages"]) {
for (auto node : config["Storages"]) {
unsigned int id;
if (!node["ID"]) {
yaml_invalid_warning("inter_config_readConf: Storage definition with no ID field in '" CL_WHITE "%s" CL_RESET "', skipping.\n", node, current_file);
continue;
}
try {
id = node["ID"].as<unsigned int>();
}
catch (std::exception) {
yaml_invalid_warning("inter_config_readConf: Storage definition with invalid ID field in '" CL_WHITE "%s" CL_RESET "', skipping.\n", node, current_file);
continue;
}
if( id > UINT8_MAX ){
yaml_invalid_warning("inter_config_readConf: Storage definition with invalid ID field in '" CL_WHITE "%s" CL_RESET "', skipping.\n", node, current_file);
continue;
}
bool existing = inter_premiumStorage_exists(id);
auto storage_table = existing ? interserv_config.storages[id] : std::make_shared<s_storage_table>();
if (!existing && (!node["Name"] || !node["Table"])) {
yaml_invalid_warning("inter_config_readConf: Invalid storage definition in '" CL_WHITE "%s" CL_RESET "'.\n", node, current_file);
continue;
}
if (node["Name"])
safestrncpy(storage_table->name, node["Name"].as<std::string>().c_str(), NAME_LENGTH);
if(node["Table"])
safestrncpy(storage_table->table, node["Table"].as<std::string>().c_str(), DB_NAME_LEN);
if (node["Max"]) {
try {
storage_table->max_num = node["Max"].as<uint16>();
}
catch (std::exception) {
yaml_invalid_warning("inter_config_readConf: Storage definition with invalid Max field in '" CL_WHITE "%s" CL_RESET "', skipping.\n", node, current_file);
continue;
}
}
else if (!existing)
storage_table->max_num = MAX_STORAGE;
if (!existing) {
storage_table->id = (uint8)id;
interserv_config.storages[id] = storage_table;
}
count++;
}
}
ShowStatus("Done reading '" CL_WHITE "%d" CL_RESET "' storage information in '" CL_WHITE "%s" CL_RESET "'\n", count, current_file.c_str());
}
}
void inter_config_finalConf(void) {
if (interserv_config.storages)
aFree(interserv_config.storages);
interserv_config.storages = NULL;
interserv_config.storage_count = 0;
config_destroy(&interserv_config.cfg);
}
static void inter_config_defaults(void) {
interserv_config.storage_count = 0;
interserv_config.storages = NULL;
safestrncpy(interserv_config.cfgFile, "conf/inter_server.conf", sizeof(interserv_config.cfgFile));
interserv_config.cfgFile = "inter_server.yml";
}
// initialize
int inter_init_sql(const char *file)
{
//int i;
inter_config_defaults();
inter_config_read(file);
@@ -977,15 +999,15 @@ void inter_final(void)
* @param fd
**/
void inter_Storage_sendInfo(int fd) {
int size = sizeof(struct s_storage_table), len = 4 + interserv_config.storage_count * size, i = 0;
int size = sizeof(struct s_storage_table), len = 4 + interserv_config.storages.size() * size, offset;
// Send storage table information
WFIFOHEAD(fd, len);
WFIFOW(fd, 0) = 0x388c;
WFIFOW(fd, 2) = len;
for (i = 0; i < interserv_config.storage_count; i++) {
if (!&interserv_config.storages[i] || !interserv_config.storages[i].name)
continue;
memcpy(WFIFOP(fd, 4 + size*i), &interserv_config.storages[i], size);
offset = 4;
for (auto storage : interserv_config.storages) {
memcpy(WFIFOP(fd, offset), storage.second.get(), size);
offset += size;
}
WFIFOSET(fd, len);
}

View File

@@ -4,20 +4,22 @@
#ifndef _INTER_SQL_H_
#define _INTER_SQL_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "../common/cbasetypes.h"
#include "../common/conf.h"
#include "../common/mmo.h"
#include "../common/sql.h"
#ifdef __cplusplus // C codes can't see this
#include <memory>
#include <unordered_map>
extern "C" {
struct Inter_Config {
char cfgFile[128]; ///< Inter-Config file
config_t cfg; ///< Config
struct s_storage_table *storages; ///< Storage name & table information
uint8 storage_count; ///< Number of available storage
std::string cfgFile; ///< Inter-Config file
std::unordered_map< uint8, std::shared_ptr<s_storage_table> > storages; ///< Storage name & table information
};
#endif
extern struct Inter_Config interserv_config;