diff --git a/Makefile.in b/Makefile.in index bf4e105e0d..05e4d4e81e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -7,7 +7,7 @@ ifeq ($(HAVE_MYSQL),yes) SERVER_DEPENDS=common login char map import COMMON_DEPENDS=mt19937ar libconfig yaml-cpp LOGIN_DEPENDS=mt19937ar libconfig common - CHAR_DEPENDS=mt19937ar libconfig common + CHAR_DEPENDS=mt19937ar libconfig common yaml-cpp MAP_DEPENDS=mt19937ar libconfig common yaml-cpp else ALL_DEPENDS=needs_mysql diff --git a/conf/import-tmpl/inter_server.conf b/conf/import-tmpl/inter_server.conf deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/conf/import-tmpl/inter_server.yml b/conf/import-tmpl/inter_server.yml new file mode 100644 index 0000000000..85e71fe78e --- /dev/null +++ b/conf/import-tmpl/inter_server.yml @@ -0,0 +1,17 @@ +# Config for Storages +# +# To access the premium storage, use script command 'openstorage2'. +# If premium storages are added, copy the structure of the storage table and match the table name in this config. +# The 'max' of premium storages are not adjusted by 'vip_storage_increase' config nor MIN_STORAGE. +# +# Structure: +# - ID: // (int) Storage ID will be used for script command 'openstorage2'. +# Name: "" // (string) Storage name will be sent to the client to display on the title bar. +# Table: "" // (string) Name of table where storage is saved. The table stucture is the same as the default storage table. +# Max: // (int) *optional* Maximum number of items in storage. MAX_STORAGE will be used if no value is defined. +############################################################################################################################################### +#Storages: +# - ID: 1 +# Name: "VIP Storage" +# Table: "vip_storage" +# Max: 300 diff --git a/conf/inter_athena.conf b/conf/inter_athena.conf index 8328e5ca50..5938f2e20e 100644 --- a/conf/inter_athena.conf +++ b/conf/inter_athena.conf @@ -153,6 +153,6 @@ roulette_table: db_roulette // Use SQL item_db, mob_db and mob_skill_db for the map server? (yes/no) use_sql_db: no -inter_server_conf: conf/inter_server.conf +inter_server_conf: inter_server.yml import: conf/import/inter_conf.txt diff --git a/conf/inter_server.conf b/conf/inter_server.conf deleted file mode 100644 index 3f0bc2f852..0000000000 --- a/conf/inter_server.conf +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Config for Storages - * - * To access the premium storage, use script command 'openstorage2'. - * If premium storages are added, copy the structure of the storage table and match the table name in this config. - * The 'max' of premium storages are not adjusted by 'vip_storage_increase' config nor MIN_STORAGE. - * - * Structure: -{ - id: // (int) Storage ID will be used for script command 'openstorage2'. - name: "" // (string) Storage name will be sent to the client to display on the title bar. - table: "" // (string) Name of table where storage is saved. The table stucture is the same as the default storage table. - max: // (int) *optional* Maximum number of items in storage. MAX_STORAGE will be used if no value is defined. -}, // Use comma to add more storages - **/ - -storages: ( -{ - // Default Storage - // DO NOT CHANGE THIS UNLESS YOU KNOW WHAT YOU ARE DOING - id: 0 - name: "Storage" - table: "storage" - //max: 600 -} -) diff --git a/conf/inter_server.yml b/conf/inter_server.yml new file mode 100644 index 0000000000..70cd3d09c7 --- /dev/null +++ b/conf/inter_server.yml @@ -0,0 +1,34 @@ +# This file is a part of rAthena. +# Copyright(C) 2017 rAthena Development Team +# https://rathena.org - https://github.com/rathena +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +########################################################################### +# Config for Storages +# +# To access the premium storage, use script command 'openstorage2'. +# If premium storages are added, copy the structure of the storage table and match the table name in this config. +# The 'max' of premium storages are not adjusted by 'vip_storage_increase' config nor MIN_STORAGE. +# +# Structure: +# - ID: // (int) Storage ID will be used for script command 'openstorage2'. +# Name: "" // (string) Storage name will be sent to the client to display on the title bar. +# Table: "" // (string) Name of table where storage is saved. The table stucture is the same as the default storage table. +# Max: // (int) *optional* Maximum number of items in storage. MAX_STORAGE will be used if no value is defined. + +Storages: + - ID: 0 + Name: "Storage" + Table: "storage" diff --git a/configure b/configure index ffd6e161eb..53ab81fe6c 100755 --- a/configure +++ b/configure @@ -4951,7 +4951,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu CFLAGS="$CFLAGS -pipe -ffast-math -Wall" CPPFLAGS="$CPPFLAGS -I../common" - +CXXFLAGS="$CXXFLAGS -std=c++11" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 diff --git a/configure.in b/configure.in index 6d527190af..1f22fdb709 100644 --- a/configure.in +++ b/configure.in @@ -440,6 +440,7 @@ AC_LANG([C++]) CFLAGS="$CFLAGS -pipe -ffast-math -Wall" CPPFLAGS="$CPPFLAGS -I../common" +CXXFLAGS="$CXXFLAGS -std=c++11" AC_C_BIGENDIAN( diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 0c20f96a28..9d5df1faca 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -5158,7 +5158,7 @@ window, to avoid any disruption when both windows overlap. *openstorage2 ,{,}; Just like the 'openstorage' command, except this command can open additional storages -by the specified . For , please read the conf/inter_server.conf +by the specified . For , please read the conf/inter_server.yml for storage groups. Values for are: diff --git a/rAthena.sln b/rAthena.sln index 27346a5ca5..410c2620fc 100644 --- a/rAthena.sln +++ b/rAthena.sln @@ -43,6 +43,7 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "char-server", "src\char\char-server.vcxproj", "{FED3A941-0AF7-49FE-85CF-E1DFDC0EBB23}" ProjectSection(ProjectDependencies) = postProject {F8FD7B1E-8E1C-4CC3-9CD1-2E28F77B6559} = {F8FD7B1E-8E1C-4CC3-9CD1-2E28F77B6559} + {61D6A599-6BED-4154-A9FC-40553BD972E0} = {61D6A599-6BED-4154-A9FC-40553BD972E0} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "map-server", "src\map\map-server.vcxproj", "{B4114A9C-EEA4-433C-A830-56119A984F24}" diff --git a/src/char/Makefile.in b/src/char/Makefile.in index 1d3dfe9af0..1bd34581f9 100644 --- a/src/char/Makefile.in +++ b/src/char/Makefile.in @@ -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 diff --git a/src/char/char-server.vcxproj b/src/char/char-server.vcxproj index f515e8ad25..18471e7c2c 100644 --- a/src/char/char-server.vcxproj +++ b/src/char/char-server.vcxproj @@ -94,6 +94,7 @@ Disabled $(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) MultiThreadedDebug + $(SolutionDir)3rdparty\yaml-cpp\include\ Console @@ -109,6 +110,7 @@ Disabled $(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) MultiThreadedDebug + $(SolutionDir)3rdparty\yaml-cpp\include\ Console @@ -126,6 +128,7 @@ true $(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) MultiThreaded + $(SolutionDir)3rdparty\yaml-cpp\include\ Console @@ -145,6 +148,7 @@ true $(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) MultiThreaded + $(SolutionDir)3rdparty\yaml-cpp\include\ Console @@ -182,7 +186,7 @@ - + @@ -194,7 +198,7 @@ - + diff --git a/src/char/char-server.vcxproj.filters b/src/char/char-server.vcxproj.filters index cc6aa2d202..74a9c20510 100644 --- a/src/char/char-server.vcxproj.filters +++ b/src/char/char-server.vcxproj.filters @@ -112,10 +112,10 @@ Source Files - + Source Files - + Source Files diff --git a/src/char/int_achievement.h b/src/char/int_achievement.h index 908c61dcbc..1e9e501ab1 100644 --- a/src/char/int_achievement.h +++ b/src/char/int_achievement.h @@ -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_ */ diff --git a/src/char/int_auction.h b/src/char/int_auction.h index bf26b152c0..83a3428f1c 100644 --- a/src/char/int_auction.h +++ b/src/char/int_auction.h @@ -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_ */ diff --git a/src/char/int_clan.h b/src/char/int_clan.h index c21e6ecffa..d698bcd152 100644 --- a/src/char/int_clan.h +++ b/src/char/int_clan.h @@ -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_ */ diff --git a/src/char/int_quest.h b/src/char/int_quest.h index b0403f4361..8da9b3efdf 100644 --- a/src/char/int_quest.h +++ b/src/char/int_quest.h @@ -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 diff --git a/src/char/int_storage.c b/src/char/int_storage.cpp similarity index 91% rename from src/char/int_storage.c rename to src/char/int_storage.cpp index f53811d4ca..c450882cb4 100644 --- a/src/char/int_storage.c +++ b/src/char/int_storage.cpp @@ -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 - -#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); diff --git a/src/char/int_storage.h b/src/char/int_storage.h index bb7910b3aa..d1435d0ce1 100644 --- a/src/char/int_storage.h +++ b/src/char/int_storage.h @@ -4,6 +4,8 @@ #ifndef _INT_STORAGE_SQL_H_ #define _INT_STORAGE_SQL_H_ +#include "../common/cbasetypes.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/src/char/inter.c b/src/char/inter.cpp similarity index 93% rename from src/char/inter.c rename to src/char/inter.cpp index 135c944107..a0843e069f 100644 --- a/src/char/inter.c +++ b/src/char/inter.cpp @@ -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 + +#include +#include #include #include // 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 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(); + } + 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(); + + 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().c_str(), NAME_LENGTH); + if(node["Table"]) + safestrncpy(storage_table->table, node["Table"].as().c_str(), DB_NAME_LEN); + if (node["Max"]) { + try { + storage_table->max_num = node["Max"].as(); + } + 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); } diff --git a/src/char/inter.h b/src/char/inter.h index e437cd710e..9469c814c1 100644 --- a/src/char/inter.h +++ b/src/char/inter.h @@ -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 +#include + +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 > storages; ///< Storage name & table information }; +#endif extern struct Inter_Config interserv_config; diff --git a/src/common/Makefile.in b/src/common/Makefile.in index c3f07ceeb4..3416f614b3 100644 --- a/src/common/Makefile.in +++ b/src/common/Makefile.in @@ -29,8 +29,6 @@ else endif ALL_DEPENDS=server -CXXFLAG =-std=c++11 - @SET_MAKE@ ##################################################################### @@ -73,7 +71,7 @@ obj/%.o: %.c $(COMMON_H) $(MT19937AR_H) $(LIBCONFIG_H) $(YAML_CPP_H) obj/%.o: %.cpp $(COMMON_H) $(MT19937AR_H) $(LIBCONFIG_H) $(YAML_CPP_H) @echo " CXX $<" - @@CXX@ $(CXXFLAG) @CFLAGS_AR@ $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) $(YAML_CPP_INCLUDE) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $< + @@CXX@ @CXXFLAGS@ @CFLAGS_AR@ $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) $(YAML_CPP_INCLUDE) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $< obj/mini%.o: %.c $(COMMON_H) $(MT19937AR_H) $(LIBCONFIG_H) $(YAML_CPP_H) @echo " CC $<" @@ -81,7 +79,7 @@ obj/mini%.o: %.c $(COMMON_H) $(MT19937AR_H) $(LIBCONFIG_H) $(YAML_CPP_H) obj/mini%.o: %.cpp $(COMMON_H) $(MT19937AR_H) $(LIBCONFIG_H) $(YAML_CPP_H) @echo " CXX $<" - @@CXX@ $(CXXFLAG) @CFLAGS_AR@ $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) $(YAML_CPP_INCLUDE) @MYSQL_CFLAGS@ -DMINICORE @CPPFLAGS@ -c $(OUTPUT_OPTION) $< + @@CXX@ @CXXFLAGS@ @CFLAGS_AR@ $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) $(YAML_CPP_INCLUDE) @MYSQL_CFLAGS@ -DMINICORE @CPPFLAGS@ -c $(OUTPUT_OPTION) $< # missing object files $(MT19937AR_OBJ): diff --git a/src/common/malloc.h b/src/common/malloc.h index 1f273c9335..1660b870cd 100644 --- a/src/common/malloc.h +++ b/src/common/malloc.h @@ -4,10 +4,11 @@ #ifndef _MALLOC_H_ #define _MALLOC_H_ +#include "cbasetypes.h" + #ifdef __cplusplus extern "C" { #endif -#include "cbasetypes.h" #define ALC_MARK __FILE__, __LINE__, __func__ diff --git a/src/common/sql.h b/src/common/sql.h index e86b0b3b2d..8b03e1bf34 100644 --- a/src/common/sql.h +++ b/src/common/sql.h @@ -4,14 +4,12 @@ #ifndef _COMMON_SQL_H_ #define _COMMON_SQL_H_ -#ifdef __cplusplus -extern "C" { -#endif - #include "cbasetypes.h" #include // va_list - +#ifdef __cplusplus +extern "C" { +#endif // Return codes #define SQL_ERROR -1 diff --git a/src/common/strlib.h b/src/common/strlib.h index 441d51993e..930f65526d 100644 --- a/src/common/strlib.h +++ b/src/common/strlib.h @@ -4,10 +4,6 @@ #ifndef _STRLIB_H_ #define _STRLIB_H_ -#ifdef __cplusplus -extern "C" { -#endif - #include "cbasetypes.h" #include @@ -21,6 +17,10 @@ extern "C" { #undef __USED_GNU #endif +#ifdef __cplusplus +extern "C" { +#endif + char* jstrescape (char* pt); char* jstrescapecpy (char* pt, const char* spt); int jmemescapecpy (char* pt, const char* spt, int size); diff --git a/src/login/Makefile.in b/src/login/Makefile.in index f6d3ba67a7..7c13d48ef6 100644 --- a/src/login/Makefile.in +++ b/src/login/Makefile.in @@ -23,8 +23,6 @@ else endif ALL_DEPENDS=server -CXXFLAGS=-std=c++11 - @SET_MAKE@ ##################################################################### diff --git a/src/map/Makefile.in b/src/map/Makefile.in index 41079d0980..35d5f368df 100644 --- a/src/map/Makefile.in +++ b/src/map/Makefile.in @@ -37,8 +37,6 @@ else PCRE_CFLAGS= endif -CXXFLAGS=-std=c++11 - @SET_MAKE@ ##################################################################### diff --git a/src/map/intif.c b/src/map/intif.c index f0720eec14..408da1c51f 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -3509,11 +3509,6 @@ void intif_parse_StorageInfo_recv(int fd) { storage_db = NULL; for (i = 0; i < count; i++) { - char name[NAME_LENGTH + 1]; - - safestrncpy(name, RFIFOCP(fd, 5 + size * i), NAME_LENGTH); - if (name[0] == '\0') - continue; RECREATE(storage_db, struct s_storage_table, storage_count+1); memcpy(&storage_db[storage_count], RFIFOP(fd, 4 + size * i), size); storage_count++; diff --git a/src/map/map-server.vcxproj b/src/map/map-server.vcxproj index 139b5dc7e6..bbc87e1c7a 100644 --- a/src/map/map-server.vcxproj +++ b/src/map/map-server.vcxproj @@ -270,7 +270,7 @@ - + diff --git a/src/map/storage.c b/src/map/storage.c index 5895ce7854..8f6a8174c8 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -290,6 +290,9 @@ static int storage_additem(struct map_session_data* sd, struct s_storage *stor, } } + if( stor->amount >= stor->max_amount ) + return 2; + // find free slot ARR_FIND( 0, stor->max_amount, i, stor->u.items_storage[i].nameid == 0 ); if( i >= stor->max_amount ) @@ -325,7 +328,7 @@ int storage_delitem(struct map_session_data* sd, struct s_storage *stor, int ind memset(&stor->u.items_storage[index],0,sizeof(stor->u.items_storage[0])); stor->amount--; if( sd->state.storage_flag == 1 || sd->state.storage_flag == 3 ) - clif_updatestorageamount(sd, stor->amount, sd->storage.max_amount); + clif_updatestorageamount(sd, stor->amount, stor->max_amount); } if( sd->state.storage_flag == 1 || sd->state.storage_flag == 3 )