diff options
author | Haru <haru@dotalux.com> | 2015-09-07 01:42:31 +0200 |
---|---|---|
committer | Haru <haru@dotalux.com> | 2016-08-19 21:32:13 +0200 |
commit | ea9ceb17bdf4ea4acf28dca84508b62bd7e94fd4 (patch) | |
tree | d122655c806ae3a9dfea3688e6837da6272ffc7d | |
parent | 9783ce1d536d0f3f5d7e34d90717a65779ff923a (diff) | |
download | hercules-ea9ceb17bdf4ea4acf28dca84508b62bd7e94fd4.tar.gz hercules-ea9ceb17bdf4ea4acf28dca84508b62bd7e94fd4.tar.bz2 hercules-ea9ceb17bdf4ea4acf28dca84508b62bd7e94fd4.tar.xz hercules-ea9ceb17bdf4ea4acf28dca84508b62bd7e94fd4.zip |
Ported inter-server.conf to libconfig
Ported to modern Hercules and cleaned up from Panikon's commits: 40f9ec33868e2240cab013308897898ed252b3e0, a9d646da19e25ab6fcf44dbd1ae7d90c30f6686c, 1aa8581a0aecbfd53e877686c399ffb731dcd75e, 72c645b015ae6130ca7d4309d0fb1413340e7f23, f8c906a0496b9acdae1d8244b1544fa03592061e, 51d88a58983c9552dfd1a0f059e5a031742aed61, 443684b3c77f4c32fe7877a7f8d62debf73b1e93, cf93eafef1f322cd1583226272b7d4008f562da4
Signed-off-by: Haru <haru@dotalux.com>
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | conf/char/char-server.conf | 1 | ||||
-rw-r--r-- | conf/common/inter-server.conf | 119 | ||||
-rw-r--r-- | conf/global/sql_connection.conf | 49 | ||||
-rw-r--r-- | conf/import-tmpl/inter-server.conf | 32 | ||||
-rw-r--r-- | conf/import-tmpl/inter_conf.txt | 0 | ||||
-rw-r--r-- | conf/inter-server.conf | 125 | ||||
-rw-r--r-- | src/char/char.c | 279 | ||||
-rw-r--r-- | src/char/char.h | 5 | ||||
-rw-r--r-- | src/char/inter.c | 114 | ||||
-rw-r--r-- | src/char/inter.h | 6 | ||||
-rw-r--r-- | src/common/sql.c | 96 | ||||
-rw-r--r-- | src/common/sql.h | 2 | ||||
-rw-r--r-- | src/map/map.c | 174 | ||||
-rw-r--r-- | src/map/map.h | 7 | ||||
-rw-r--r-- | src/map/mapreg.h | 6 | ||||
-rw-r--r-- | src/map/mapreg_sql.c | 21 | ||||
-rwxr-xr-x | tools/configconverter.pl | 77 |
18 files changed, 738 insertions, 376 deletions
diff --git a/.gitignore b/.gitignore index 5eccd9969..3302e44cf 100644 --- a/.gitignore +++ b/.gitignore @@ -61,7 +61,6 @@ Thumbs.db # /conf/ /conf/import/*.conf /conf/import/battle_conf.txt -/conf/import/inter_conf.txt /conf/import/log_conf.txt /conf/import/login_conf.txt /conf/import/map_conf.txt diff --git a/conf/char/char-server.conf b/conf/char/char-server.conf index 576925872..4c6ef0348 100644 --- a/conf/char/char-server.conf +++ b/conf/char/char-server.conf @@ -29,6 +29,7 @@ char_configuration: { @include "conf/global/console.conf" + @include "conf/global/sql_connection.conf" // Server name, use alternative character such as ASCII 160 for spaces. // NOTE: Do not use spaces or any of these characters which are not allowed in diff --git a/conf/common/inter-server.conf b/conf/common/inter-server.conf new file mode 100644 index 000000000..fd55b27e5 --- /dev/null +++ b/conf/common/inter-server.conf @@ -0,0 +1,119 @@ +//================= Hercules Configuration ================================ +//= _ _ _ +//= | | | | | | +//= | |_| | ___ _ __ ___ _ _| | ___ ___ +//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __| +//= | | | | __/ | | (__| |_| | | __/\__ \ +//= \_| |_/\___|_| \___|\__,_|_|\___||___/ +//================= License =============================================== +//= This file is part of Hercules. +//= http://herc.ws - http://github.com/HerculesWS/Hercules +//= +//= Copyright (C) 2014-2016 Hercules Dev Team +//= +//= Hercules 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 <http://www.gnu.org/licenses/>. +//========================================================================= +//= Hercules Inter Server configuration file. +//========================================================================= +// Settings that are shared by more than one of the main servers +//========================================================================= + +inter_configuration: { + // Level range for sharing within a party + party_share_level: 15 // FIXME: Split RE and pre-RE + + // Log configuration + log: { + // Log Inter Connections, etc.? + log_inter: true + + // Inter Log Filename + inter_log_filename: "log/inter.log" + + // Log database SQL connection + @include "conf/global/sql_connection.conf" + } + + mysql_reconnect: { + // == MySQL Reconnect Settings + // =========================== + // - mysql_reconnect_type + // - 1: when mysql disconnects during runtime, the server tries to reconnect mysql_reconnect_count times and, + // -- if unsuccessful, the server is shut down + // - 2: when mysql disconnects during runtime it tries to reconnect indefinitely + type: 2 + + // - mysql_reconnect_count + // - number of reconnect attempts the server should do when the database disconnects during runtime + // - only used when mysql_reconnect_type is 1 + count: 1 + } + + // ALL MySQL Database Table names + // DO NOT CHANGE ANYTHING BEYOND THIS LINE UNLESS YOU KNOW YOUR DATABASE DAMN WELL + // this is meant for people who KNOW their stuff, and for some reason want to change their + // database layout. [CLOWNISIUS] + database_names: { + char_db: "char" + interlog_db: "interlog" + ragsrvinfo_db: "ragsrvinfo" + registry: { + acc_reg_num_db: "acc_reg_num_db" + acc_reg_str_db: "acc_reg_str_db" + char_reg_str_db: "char_reg_str_db" + char_reg_num_db: "char_reg_num_db" + + global_acc_reg_num_db: "global_acc_reg_num_db" + global_acc_reg_str_db: "global_acc_reg_str_db" + } + pc: { + hotkey_db: "hotkey" + scdata_db: "sc_data" + cart_db: "cart_inventory" + inventory_db: "inventory" + charlog_db: "charlog" + storage_db: "storage" + skill_db: "skill" + memo_db: "memo" + party_db: "party" + pet_db: "pet" + friend_db: "friends" + mail_db: "mail" + auction_db: "auction" + quest_db: "quest" + homunculus_db: "homunculus" + skill_homunculus_db: "skill_homunculus" + mercenary_db: "mercenary" + mercenary_owner_db: "mercenary_owner" + elemental_db: "elemental" + account_data_db: "account_data" + } + guild: { + main_db: "guild" + alliance_db: "guild_alliance" + castle_db: "guild_castle" + expulsion_db: "guild_expulsion" + member_db: "guild_member" + skill_db: "guild_skill" + position_db: "guild_position" + storage_db: "guild_storage" + } + mapreg_db: "mapreg" + autotrade_merchants_db: "autotrade_merchants" + autotrade_data_db: "autotrade_data" + npc_market_data_db: "npc_market_data" + } +} + +import: "conf/import/inter-server.conf" diff --git a/conf/global/sql_connection.conf b/conf/global/sql_connection.conf new file mode 100644 index 000000000..58c9e6d08 --- /dev/null +++ b/conf/global/sql_connection.conf @@ -0,0 +1,49 @@ +//================= Hercules Configuration ================================ +//= _ _ _ +//= | | | | | | +//= | |_| | ___ _ __ ___ _ _| | ___ ___ +//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __| +//= | | | | __/ | | (__| |_| | | __/\__ \ +//= \_| |_/\___|_| \___|\__,_|_|\___||___/ +//================= License =============================================== +//= This file is part of Hercules. +//= http://herc.ws - http://github.com/HerculesWS/Hercules +//= +//= Copyright (C) 2014-2016 Hercules Dev Team +//= +//= Hercules 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 <http://www.gnu.org/licenses/>. +//========================================================================= +//= SQL connection configuration file. +//========================================================================= +// This file affects how ALL server sql connections work, unless explictly +// defined so in the server configuration file (See +// doc/global_configuration.txt for more information). +//========================================================================= + +sql_connection: { + // [INTER] You can specify the codepage to use in your mySQL tables here. + // (Note that this feature requires MySQL 4.1+) + //default_codepage: "" + + // For IPs, ideally under linux, you want to use localhost instead of 127.0.0.1. + // Under windows, you want to use 127.0.0.1. If you see a message like + // "Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)" + // and you have localhost, switch it to 127.0.0.1 + db_hostname: "127.0.0.1" + db_port: 3306 + db_username: "ragnarok" + db_password: "ragnarok" + db_database: "ragnarok" + //codepage:"" +} diff --git a/conf/import-tmpl/inter-server.conf b/conf/import-tmpl/inter-server.conf new file mode 100644 index 000000000..243dda4ea --- /dev/null +++ b/conf/import-tmpl/inter-server.conf @@ -0,0 +1,32 @@ +//================= Hercules Configuration ================================ +//= _ _ _ +//= | | | | | | +//= | |_| | ___ _ __ ___ _ _| | ___ ___ +//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __| +//= | | | | __/ | | (__| |_| | | __/\__ \ +//= \_| |_/\___|_| \___|\__,_|_|\___||___/ +//================= License =============================================== +//= This file is part of Hercules. +//= http://herc.ws - http://github.com/HerculesWS/Hercules +//= +//= Copyright (C) 2014-2016 Hercules Dev Team +//= +//= Hercules 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 <http://www.gnu.org/licenses/>. +//========================================================================= +//= Hercules Inter Server local configuration file. +//========================================================================= + +inter_configuration: { + // See conf/common/inter-server.conf +} diff --git a/conf/import-tmpl/inter_conf.txt b/conf/import-tmpl/inter_conf.txt deleted file mode 100644 index e69de29bb..000000000 --- a/conf/import-tmpl/inter_conf.txt +++ /dev/null diff --git a/conf/inter-server.conf b/conf/inter-server.conf deleted file mode 100644 index 704d5fc12..000000000 --- a/conf/inter-server.conf +++ /dev/null @@ -1,125 +0,0 @@ -// Hercules InterServer (settings shared/used by more than 1 server) configuration. - -// Options for both versions - -// Log Inter Connections, etc.? -log_inter: 1 - -// Inter Log Filename -inter_log_filename: log/inter.log - -// Level range for sharing within a party -party_share_level: 15 - -// SQL version options only - -// You can specify the codepage to use in your mySQL tables here. -// (Note that this feature requires MySQL 4.1+) -//default_codepage: - - -// For IPs, ideally under linux, you want to use localhost instead of 127.0.0.1 -// Under windows, you want to use 127.0.0.1. If you see a message like -// "Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)" -// and you have localhost, switch it to 127.0.0.1 - -// Global SQL settings -// overridden by local settings when the hostname is defined there -// (currently only the login-server reads/obeys these settings) -sql.db_hostname: 127.0.0.1 -sql.db_port: 3306 -sql.db_username: ragnarok -sql.db_password: ragnarok -sql.db_database: ragnarok -sql.codepage: - -// MySQL Character SQL server -char_server_ip: 127.0.0.1 -char_server_port: 3306 -char_server_id: ragnarok -char_server_pw: ragnarok -char_server_db: ragnarok - -// MySQL Map SQL Server -map_server_ip: 127.0.0.1 -map_server_port: 3306 -map_server_id: ragnarok -map_server_pw: ragnarok -map_server_db: ragnarok - -// MySQL Log SQL Database -log_db_ip: 127.0.0.1 -log_db_port: 3306 -log_db_id: ragnarok -log_db_pw: ragnarok -log_db_db: ragnarok -log_codepage: -log_login_db: loginlog - -// == MySQL Reconnect Settings -// =========================== -// - mysql_reconnect_type -// - 1: when mysql disconnects during runtime, the server tries to reconnect mysql_reconnect_count times and, -// -- if unsuccessful, the server is shut down -// - 2: when mysql disconnects during runtime it tries to reconnect indefinitely -mysql_reconnect_type:2 -// - mysql_reconnect_count -// - number of reconnect attempts the server should do when the database disconnects during runtime -// - only used when mysql_reconnect_type is 1 -mysql_reconnect_count:1 - -// DO NOT CHANGE ANYTHING BEYOND THIS LINE UNLESS YOU KNOW YOUR DATABASE DAMN WELL -// this is meant for people who KNOW their stuff, and for some reason want to change their -// database layout. [CLOWNISIUS] - -// ALL MySQL Database Table names - -//Shared -interreg_db: interreg -global_acc_reg_num_db: global_acc_reg_num_db -global_acc_reg_str_db: global_acc_reg_str_db - -// Char Database Tables -char_db: char -hotkey_db: hotkey -scdata_db: sc_data -cart_db: cart_inventory -inventory_db: inventory -charlog_db: charlog -storage_db: storage -skill_db: skill -interlog_db: interlog -memo_db: memo -guild_db: guild -guild_alliance_db: guild_alliance -guild_castle_db: guild_castle -guild_expulsion_db: guild_expulsion -guild_member_db: guild_member -guild_skill_db: guild_skill -guild_position_db: guild_position -guild_storage_db: guild_storage -party_db: party -pet_db: pet -friend_db: friends -mail_db: mail -auction_db: auction -quest_db: quest -homunculus_db: homunculus -skill_homunculus_db: skill_homunculus -mercenary_db: mercenary -mercenary_owner_db: mercenary_owner -ragsrvinfo_db: ragsrvinfo -elemental_db: elemental -account_data_db: account_data -acc_reg_num_db: acc_reg_num_db -acc_reg_str_db: acc_reg_str_db -char_reg_str_db: char_reg_str_db -char_reg_num_db: char_reg_num_db - -// Map Database Tables -mapreg_db: mapreg -autotrade_merchants_db: autotrade_merchants -autotrade_data_db: autotrade_data -npc_market_data_db: npc_market_data - -import: conf/import/inter_conf.txt diff --git a/src/char/char.c b/src/char/char.c index 2b5c837c5..62b1d8f4c 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -5350,102 +5350,171 @@ static int char_online_data_cleanup(int tid, int64 tick, int id, intptr_t data) return 0; } -void char_sql_config_read(const char* cfgName) +/** + * Reads the 'inter_configuration' config file and initializes required variables. + * + * @param filename Path to configuration file + * @param imported Whether the current config is imported from another file. + * + * @retval false in case of error. + */ +bool char_sql_config_read(const char *filename, bool imported) { - char line[1024], w1[1024], w2[1024]; - FILE* fp; + struct config_t config; + const struct config_setting_t *setting = NULL; + const char *import = NULL; + bool retval = true; - if ((fp = fopen(cfgName, "r")) == NULL) { - ShowError("File not found: %s\n", cfgName); - return; + nullpo_retr(false, filename); + + if (!libconfig->load_file(&config, filename)) + return false; // Error message is already shown by libconfig->load_file + + if ((setting = libconfig->lookup(&config, "inter_configuration/database_names")) == NULL) { + libconfig->destroy(&config); + if (imported) + return true; + ShowError("sql_config_read: inter_configuration/database_names was not found in %s!\n", filename); + return false; } + libconfig->setting_lookup_mutable_string(setting, "char_db", char_db, sizeof(char_db)); + libconfig->setting_lookup_mutable_string(setting, "interlog_db", interlog_db, sizeof(interlog_db)); + libconfig->setting_lookup_mutable_string(setting, "ragsrvinfo_db", ragsrvinfo_db, sizeof(ragsrvinfo_db)); - while(fgets(line, sizeof(line), fp)) - { - if(line[0] == '/' && line[1] == '/') - continue; + if (!chr->sql_config_read_registry(filename, &config, imported)) + retval = false; + if (!chr->sql_config_read_pc(filename, &config, imported)) + retval = false; + if (!chr->sql_config_read_guild(filename, &config, imported)) + retval = false; - if (sscanf(line, "%1023[^:]: %1023[^\r\n]", w1, w2) != 2) - continue; + ShowInfo("Done reading %s.\n", filename); + // import should overwrite any previous configuration, so it should be called last + if (libconfig->lookup_string(&config, "import", &import) == CONFIG_TRUE) { + if (strcmp(import, filename) == 0 || strcmp(import, chr->SQL_CONF_NAME) == 0) { + ShowWarning("sql_config_read: Loop detected in %s! Skipping 'import'...\n", filename); + } else { + if (!chr->sql_config_read(import, true)) + retval = false; + } + } - if(!strcmpi(w1,"char_db")) - safestrncpy(char_db, w2, sizeof(char_db)); - else if(!strcmpi(w1,"scdata_db")) - safestrncpy(scdata_db, w2, sizeof(scdata_db)); - else if(!strcmpi(w1,"cart_db")) - safestrncpy(cart_db, w2, sizeof(cart_db)); - else if(!strcmpi(w1,"inventory_db")) - safestrncpy(inventory_db, w2, sizeof(inventory_db)); - else if(!strcmpi(w1,"charlog_db")) - safestrncpy(charlog_db, w2, sizeof(charlog_db)); - else if(!strcmpi(w1,"storage_db")) - safestrncpy(storage_db, w2, sizeof(storage_db)); - else if(!strcmpi(w1,"skill_db")) - safestrncpy(skill_db, w2, sizeof(skill_db)); - else if(!strcmpi(w1,"interlog_db")) - safestrncpy(interlog_db, w2, sizeof(interlog_db)); - else if(!strcmpi(w1,"memo_db")) - safestrncpy(memo_db, w2, sizeof(memo_db)); - else if(!strcmpi(w1,"guild_db")) - safestrncpy(guild_db, w2, sizeof(guild_db)); - else if(!strcmpi(w1,"guild_alliance_db")) - safestrncpy(guild_alliance_db, w2, sizeof(guild_alliance_db)); - else if(!strcmpi(w1,"guild_castle_db")) - safestrncpy(guild_castle_db, w2, sizeof(guild_castle_db)); - else if(!strcmpi(w1,"guild_expulsion_db")) - safestrncpy(guild_expulsion_db, w2, sizeof(guild_expulsion_db)); - else if(!strcmpi(w1,"guild_member_db")) - safestrncpy(guild_member_db, w2, sizeof(guild_member_db)); - else if(!strcmpi(w1,"guild_skill_db")) - safestrncpy(guild_skill_db, w2, sizeof(guild_skill_db)); - else if(!strcmpi(w1,"guild_position_db")) - safestrncpy(guild_position_db, w2, sizeof(guild_position_db)); - else if(!strcmpi(w1,"guild_storage_db")) - safestrncpy(guild_storage_db, w2, sizeof(guild_storage_db)); - else if(!strcmpi(w1,"party_db")) - safestrncpy(party_db, w2, sizeof(party_db)); - else if(!strcmpi(w1,"pet_db")) - safestrncpy(pet_db, w2, sizeof(pet_db)); - else if(!strcmpi(w1,"mail_db")) - safestrncpy(mail_db, w2, sizeof(mail_db)); - else if(!strcmpi(w1,"auction_db")) - safestrncpy(auction_db, w2, sizeof(auction_db)); - else if(!strcmpi(w1,"friend_db")) - safestrncpy(friend_db, w2, sizeof(friend_db)); - else if(!strcmpi(w1,"hotkey_db")) - safestrncpy(hotkey_db, w2, sizeof(hotkey_db)); - else if(!strcmpi(w1,"quest_db")) - safestrncpy(quest_db,w2,sizeof(quest_db)); - else if(!strcmpi(w1,"homunculus_db")) - safestrncpy(homunculus_db,w2,sizeof(homunculus_db)); - else if(!strcmpi(w1,"skill_homunculus_db")) - safestrncpy(skill_homunculus_db,w2,sizeof(skill_homunculus_db)); - else if(!strcmpi(w1,"mercenary_db")) - safestrncpy(mercenary_db,w2,sizeof(mercenary_db)); - else if(!strcmpi(w1,"mercenary_owner_db")) - safestrncpy(mercenary_owner_db,w2,sizeof(mercenary_owner_db)); - else if(!strcmpi(w1,"ragsrvinfo_db")) - safestrncpy(ragsrvinfo_db,w2,sizeof(ragsrvinfo_db)); - else if(!strcmpi(w1,"elemental_db")) - safestrncpy(elemental_db,w2,sizeof(elemental_db)); - else if(!strcmpi(w1,"account_data_db")) - safestrncpy(account_data_db,w2,sizeof(account_data_db)); - else if(!strcmpi(w1,"char_reg_num_db")) - safestrncpy(char_reg_num_db, w2, sizeof(char_reg_num_db)); - else if(!strcmpi(w1,"char_reg_str_db")) - safestrncpy(char_reg_str_db, w2, sizeof(char_reg_str_db)); - else if(!strcmpi(w1,"acc_reg_str_db")) - safestrncpy(acc_reg_str_db, w2, sizeof(acc_reg_str_db)); - else if(!strcmpi(w1,"acc_reg_num_db")) - safestrncpy(acc_reg_num_db, w2, sizeof(acc_reg_num_db)); - //support the import command, just like any other config - else if(!strcmpi(w1,"import")) - chr->sql_config_read(w2); - else - HPM->parseConf(w1, w2, HPCT_CHAR_INTER); + // TODO HPM->parseConf(w1, w2, HPCT_CHAR_INTER); + + libconfig->destroy(&config); + return retval; +} + +/** + * Reads the 'inter_configuration/database_names/registry' config entry and initializes required variables. + * + * @param filename Path to configuration file (used in error and warning messages). + * @param config The current config being parsed. + * @param imported Whether the current config is imported from another file. + * + * @retval false in case of error. + */ +bool char_sql_config_read_registry(const char *filename, const struct config_t *config, bool imported) +{ + const struct config_setting_t *setting = NULL; + + nullpo_retr(false, filename); + nullpo_retr(false, config); + + if ((setting = libconfig->lookup(config, "inter_configuration/database_names/registry")) == NULL) { + if (imported) + return true; + ShowError("sql_config_read: inter_configuration/database_names/registry was not found in %s!\n", filename); + return false; } - fclose(fp); - ShowInfo("Done reading %s.\n", cfgName); + // Not all registries are read by char-server + libconfig->setting_lookup_mutable_string(setting, "char_reg_num_db", char_reg_num_db, sizeof(char_reg_num_db)); + libconfig->setting_lookup_mutable_string(setting, "char_reg_str_db", char_reg_str_db, sizeof(char_reg_str_db)); + libconfig->setting_lookup_mutable_string(setting, "acc_reg_str_db", acc_reg_str_db, sizeof(acc_reg_str_db)); + libconfig->setting_lookup_mutable_string(setting, "acc_reg_num_db", acc_reg_num_db, sizeof(acc_reg_num_db)); + + return true; +} + +/** + * Reads the 'inter_configuration/database_names/pc' config entry and initializes required variables. + * + * @param filename Path to configuration file (used in error and warning messages). + * @param config The current config being parsed. + * @param imported Whether the current config is imported from another file. + * + * @retval false in case of error. + */ +bool char_sql_config_read_pc(const char *filename, const struct config_t *config, bool imported) +{ + const struct config_setting_t *setting = NULL; + + nullpo_retr(false, filename); + nullpo_retr(false, config); + + if ((setting = libconfig->lookup(config, "inter_configuration/database_names/pc")) == NULL) { + if (imported) + return true; + ShowError("sql_config_read: inter_configuration/database_names/pc was not found in %s!\n", filename); + return false; + } + libconfig->setting_lookup_mutable_string(setting, "hotkey_db", hotkey_db, sizeof(hotkey_db)); + libconfig->setting_lookup_mutable_string(setting, "scdata_db", scdata_db, sizeof(scdata_db)); + libconfig->setting_lookup_mutable_string(setting, "inventory_db", inventory_db, sizeof(inventory_db)); + libconfig->setting_lookup_mutable_string(setting, "cart_db", cart_db, sizeof(cart_db)); + libconfig->setting_lookup_mutable_string(setting, "charlog_db", charlog_db, sizeof(charlog_db)); + libconfig->setting_lookup_mutable_string(setting, "storage_db", storage_db, sizeof(storage_db)); + libconfig->setting_lookup_mutable_string(setting, "skill_db", skill_db, sizeof(skill_db)); + libconfig->setting_lookup_mutable_string(setting, "memo_db", memo_db, sizeof(memo_db)); + libconfig->setting_lookup_mutable_string(setting, "party_db", party_db, sizeof(party_db)); + libconfig->setting_lookup_mutable_string(setting, "pet_db", pet_db, sizeof(pet_db)); + libconfig->setting_lookup_mutable_string(setting, "friend_db", friend_db, sizeof(friend_db)); + libconfig->setting_lookup_mutable_string(setting, "mail_db", mail_db, sizeof(mail_db)); + libconfig->setting_lookup_mutable_string(setting, "auction_db", auction_db, sizeof(auction_db)); + libconfig->setting_lookup_mutable_string(setting, "quest_db", quest_db, sizeof(quest_db)); + libconfig->setting_lookup_mutable_string(setting, "homunculus_db", homunculus_db, sizeof(homunculus_db)); + libconfig->setting_lookup_mutable_string(setting, "skill_homunculus_db", skill_homunculus_db, sizeof(skill_homunculus_db)); + libconfig->setting_lookup_mutable_string(setting, "mercenary_db", mercenary_db, sizeof(mercenary_db)); + libconfig->setting_lookup_mutable_string(setting, "mercenary_owner_db", mercenary_owner_db, sizeof(mercenary_owner_db)); + libconfig->setting_lookup_mutable_string(setting, "elemental_db", elemental_db, sizeof(elemental_db)); + libconfig->setting_lookup_mutable_string(setting, "account_data_db", account_data_db, sizeof(account_data_db)); + + return true; +} + +/** + * Reads the 'inter_configuration/database_names/guild' config entry and initializes required variables. + * + * @param filename Path to configuration file (used in error and warning messages). + * @param config The current config being parsed. + * @param imported Whether the current config is imported from another file. + * + * @retval false in case of error. + */ +bool char_sql_config_read_guild(const char *filename, const struct config_t *config, bool imported) +{ + const struct config_setting_t *setting = NULL; + + nullpo_retr(false, filename); + nullpo_retr(false, config); + + if ((setting = libconfig->lookup(config, "inter_configuration/database_names/guild")) == NULL) { + if (imported) + return true; + ShowError("sql_config_read: inter_configuration/database_names/guild was not found in %s!\n", filename); + return false; + } + + libconfig->setting_lookup_mutable_string(setting, "main_db", guild_db, sizeof(guild_db)); + libconfig->setting_lookup_mutable_string(setting, "alliance_db", guild_alliance_db, sizeof(guild_alliance_db)); + libconfig->setting_lookup_mutable_string(setting, "castle_db", guild_castle_db, sizeof(guild_castle_db)); + libconfig->setting_lookup_mutable_string(setting, "expulsion_db", guild_expulsion_db, sizeof(guild_expulsion_db)); + libconfig->setting_lookup_mutable_string(setting, "member_db", guild_member_db, sizeof(guild_member_db)); + libconfig->setting_lookup_mutable_string(setting, "skill_db", guild_skill_db, sizeof(guild_skill_db)); + libconfig->setting_lookup_mutable_string(setting, "position_db", guild_position_db, sizeof(guild_position_db)); + libconfig->setting_lookup_mutable_string(setting, "storage_db", guild_storage_db, sizeof(guild_storage_db)); + + return true; } /** @@ -5479,6 +5548,8 @@ bool char_config_read(const char *filename, bool imported) retval = false; if (!chr->config_read_database(filename, &config, imported)) retval = false; + if (!inter->config_read_connection(filename, &config, imported)) + retval = false; if (!pincode->config_read(filename, &config, imported)) retval = false; @@ -6095,8 +6166,8 @@ int do_init(int argc, char **argv) { chr->CHAR_CONF_NAME = aStrdup("conf/char/char-server.conf"); chr->NET_CONF_NAME = aStrdup("conf/network.conf"); - chr->SQL_CONF_NAME = aStrdup("conf/inter-server.conf"); - chr->INTER_CONF_NAME = aStrdup("conf/inter-server.conf"); + chr->SQL_CONF_NAME = aStrdup("conf/common/inter-server.conf"); + chr->INTER_CONF_NAME = aStrdup("conf/common/inter-server.conf"); VECTOR_INIT(start_items); @@ -6123,18 +6194,25 @@ int do_init(int argc, char **argv) { cmdline->exec(argc, argv, CMDLINE_OPT_NORMAL); chr->config_read(chr->CHAR_CONF_NAME, false); sockt->net_config_read(chr->NET_CONF_NAME); - chr->sql_config_read(chr->SQL_CONF_NAME); + chr->sql_config_read(chr->SQL_CONF_NAME, false); { // TODO: Remove this when no longer needed. +#define CHECK_OLD_LOCAL_CONF(oldname, newname) do { \ + if (stat((oldname), &fileinfo) == 0 && fileinfo.st_size > 0) { \ + ShowWarning("An old configuration file \"%s\" was found.\n", (oldname)); \ + ShowWarning("If it contains settings you wish to keep, please merge them into \"%s\".\n", (newname)); \ + ShowWarning("Otherwise, just delete it.\n"); \ + ShowInfo("Resuming in 10 seconds...\n"); \ + HSleep(10); \ + } \ +} while (0) struct stat fileinfo; - if (stat("conf/import/char_conf.txt", &fileinfo) == 0 && fileinfo.st_size > 0) { - ShowWarning("An old configuration file \"conf/import/char_conf.txt\" was found.\n"); - ShowWarning("If it contains settings you wish to keep, please merge them into \"conf/import/char-server_local.conf\".\n"); - ShowWarning("Otherwise, just delete it.\n"); - ShowInfo("Resuming in 10 seconds...\n"); - HSleep(10); - } + + CHECK_OLD_LOCAL_CONF("conf/import/char_conf.txt", "conf/import/char-server.conf"); + CHECK_OLD_LOCAL_CONF("conf/import/inter_conf.txt", "conf/import/inter-server.conf"); + +#undef CHECK_OLD_LOCAL_CONF } #ifndef BUILDBOT @@ -6425,6 +6503,9 @@ void char_defaults(void) chr->online_data_cleanup_sub = char_online_data_cleanup_sub; chr->online_data_cleanup = char_online_data_cleanup; chr->sql_config_read = char_sql_config_read; + chr->sql_config_read_registry = char_sql_config_read_registry; + chr->sql_config_read_pc = char_sql_config_read_pc; + chr->sql_config_read_guild = char_sql_config_read_guild; chr->config_read = char_config_read; chr->config_read_database = char_config_read_database; chr->config_read_console = char_config_read_console; diff --git a/src/char/char.h b/src/char/char.h index 74478b747..4dbdfd9db 100644 --- a/src/char/char.h +++ b/src/char/char.h @@ -279,8 +279,11 @@ struct char_interface { int (*check_connect_login_server) (int tid, int64 tick, int id, intptr_t data); int (*online_data_cleanup_sub) (union DBKey key, struct DBData *data, va_list ap); int (*online_data_cleanup) (int tid, int64 tick, int id, intptr_t data); - void (*sql_config_read) (const char* cfgName); + bool (*sql_config_read) (const char *filename, bool imported); + bool (*sql_config_read_registry) (const char *filename, const struct config_t *config, bool imported); + bool (*sql_config_read_pc) (const char *filename, const struct config_t *config, bool imported); + bool (*sql_config_read_guild) (const char *filename, const struct config_t *config, bool imported); bool (*config_read) (const char *filename, bool imported); bool (*config_read_database) (const char *filename, const struct config_t *config, bool imported); bool (*config_read_console) (const char *filename, const struct config_t *config, bool imported); diff --git a/src/char/inter.c b/src/char/inter.c index d1b885eed..4c5eb05e5 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -36,6 +36,7 @@ #include "char/int_storage.h" #include "char/mapif.h" #include "common/cbasetypes.h" +#include "common/conf.h" #include "common/db.h" #include "common/memmgr.h" #include "common/mmo.h" @@ -62,7 +63,7 @@ char char_server_pw[100] = "ragnarok"; char char_server_db[32] = "ragnarok"; char default_codepage[32] = ""; //Feature by irmin. -unsigned int party_share_level = 10; +int party_share_level = 10; // recv. packet list int inter_recv_packet_length[] = { @@ -791,50 +792,84 @@ int inter_accreg_fromsql(int account_id,int char_id, int fd, int type) return 1; } -/*========================================== - * read config file - *------------------------------------------*/ -static int inter_config_read(const char* cfgName) +/** + * Reads the 'char_configuration/sql_connection' config entry and initializes required variables. + * + * @param filename Path to configuration file (used in error and warning messages). + * @param config The current config being parsed. + * @param imported Whether the current config is imported from another file. + * + * @retval false in case of error. + */ +bool inter_config_read_connection(const char *filename, const struct config_t *config, bool imported) { - char line[1024], w1[1024], w2[1024]; - FILE* fp; + const struct config_setting_t *setting = NULL; - nullpo_retr(1, cfgName); - fp = fopen(cfgName, "r"); - if(fp == NULL) { - ShowError("File not found: %s\n", cfgName); - return 1; + nullpo_retr(false, filename); + nullpo_retr(false, config); + + if ((setting = libconfig->lookup(config, "char_configuration/sql_connection")) == NULL) { + if (imported) + return true; + ShowError("char_config_read: char_configuration/sql_connection was not found in %s!\n", filename); + ShowWarning("inter_config_read_connection: Defaulting sql_connection...\n"); + return false; } - while (fgets(line, sizeof(line), fp)) { - int i = sscanf(line, "%1023[^:]: %1023[^\r\n]", w1, w2); - if(i != 2) - continue; + libconfig->setting_lookup_int(setting, "db_port", &char_server_port); + libconfig->setting_lookup_mutable_string(setting, "db_hostname", char_server_ip, sizeof(char_server_ip)); + libconfig->setting_lookup_mutable_string(setting, "db_username", char_server_id, sizeof(char_server_id)); + libconfig->setting_lookup_mutable_string(setting, "db_password", char_server_pw, sizeof(char_server_pw)); + libconfig->setting_lookup_mutable_string(setting, "db_database", char_server_db, sizeof(char_server_db)); + libconfig->setting_lookup_mutable_string(setting, "default_codepage", default_codepage, sizeof(default_codepage)); + + return true; +} - if(!strcmpi(w1,"char_server_ip")) { - safestrncpy(char_server_ip, w2, sizeof(char_server_ip)); - } else if(!strcmpi(w1,"char_server_port")) { - char_server_port = atoi(w2); - } else if(!strcmpi(w1,"char_server_id")) { - safestrncpy(char_server_id, w2, sizeof(char_server_id)); - } else if(!strcmpi(w1,"char_server_pw")) { - safestrncpy(char_server_pw, w2, sizeof(char_server_pw)); - } else if(!strcmpi(w1,"char_server_db")) { - safestrncpy(char_server_db, w2, sizeof(char_server_db)); - } else if(!strcmpi(w1,"default_codepage")) { - safestrncpy(default_codepage, w2, sizeof(default_codepage)); - } else if(!strcmpi(w1,"party_share_level")) - party_share_level = atoi(w2); - else if(!strcmpi(w1,"log_inter")) - inter->enable_logs = atoi(w2) ? true : false; - else if(!strcmpi(w1,"import")) - inter->config_read(w2); +/** + * Reads the 'inter_configuration' config file and initializes required variables. + * + * @param filename Path to configuration file + * @param imported Whether the current config is from an imported file. + * + * @retval false in case of error. + */ +bool inter_config_read(const char *filename, bool imported) +{ + struct config_t config; + const struct config_setting_t *setting = NULL; + const char *import = NULL; + bool retval = true; + + nullpo_retr(false, filename); + + if (!libconfig->load_file(&config, filename)) + return false; + + if ((setting = libconfig->lookup(&config, "inter_configuration")) == NULL) { + libconfig->destroy(&config); + if (imported) + return true; + ShowError("inter_config_read: inter_configuration was not found in %s!\n", filename); + return false; } - fclose(fp); + libconfig->setting_lookup_int(setting, "party_share_level", &party_share_level); + libconfig->setting_lookup_bool_real(setting, "log_inter", &inter->enable_logs); - ShowInfo ("Done reading %s.\n", cfgName); + ShowInfo("Done reading %s.\n", filename); - return 0; + // import should overwrite any previous configuration, so it should be called last + if (libconfig->lookup_string(&config, "import", &import) == CONFIG_TRUE) { + if (strcmp(import, filename) == 0 || strcmp(import, chr->INTER_CONF_NAME) == 0) { + ShowWarning("inter_config_read: Loop detected in %s! Skipping 'import'...\n", filename); + } else { + if (!inter->config_read(import, true)) + retval = false; + } + } + + libconfig->destroy(&config); + return retval; } /** @@ -879,9 +914,7 @@ int inter_log(char* fmt, ...) // initialize int inter_init_sql(const char *file) { - //int i; - - inter->config_read(file); + inter->config_read(file, false); //DB connection initialized inter->sql_handle = SQL->Malloc(); @@ -1385,4 +1418,5 @@ void inter_defaults(void) inter->check_length = inter_check_length; inter->parse_frommap = inter_parse_frommap; inter->final = inter_final; + inter->config_read_connection = inter_config_read_connection; } diff --git a/src/char/inter.h b/src/char/inter.h index db50fd645..57d1db86c 100644 --- a/src/char/inter.h +++ b/src/char/inter.h @@ -28,6 +28,7 @@ /* Forward Declarations */ struct Sql; // common/sql.h +struct config_t; // common/conf.h /** * inter interface @@ -43,7 +44,6 @@ struct inter_interface { void (*msg_to_fd) (int fd, int u_fd, int aid, char *msg, ...) __attribute__((format(printf, 4, 5))); void (*savereg) (int account_id, int char_id, const char *key, unsigned int index, intptr_t val, bool is_string); int (*accreg_fromsql) (int account_id,int char_id, int fd, int type); - int (*config_read) (const char* cfgName); int (*vlog) (char* fmt, va_list ap); int (*log) (char* fmt, ...); int (*init_sql) (const char *file); @@ -53,10 +53,12 @@ struct inter_interface { int (*check_length) (int fd, int length); int (*parse_frommap) (int fd); void (*final) (void); + bool (*config_read) (const char *filename, bool imported); + bool (*config_read_connection) (const char *filename, const struct config_t *config, bool imported); }; #ifdef HERCULES_CORE -extern unsigned int party_share_level; +extern int party_share_level; ///< Share range for parties. void inter_defaults(void); #endif // HERCULES_CORE diff --git a/src/common/sql.c b/src/common/sql.c index 9a90f9807..be0bd43e3 100644 --- a/src/common/sql.c +++ b/src/common/sql.c @@ -2,7 +2,7 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2012-2015 Hercules Dev Team + * Copyright (C) 2012-2016 Hercules Dev Team * Copyright (C) Athena Dev Teams * * Hercules is free software: you can redistribute it and/or modify @@ -23,7 +23,9 @@ #include "sql.h" #include "common/cbasetypes.h" +#include "common/conf.h" #include "common/memmgr.h" +#include "common/nullpo.h" #include "common/showmsg.h" #include "common/strlib.h" #include "common/timer.h" @@ -37,8 +39,8 @@ void hercules_mysql_error_handler(unsigned int ecode); -int mysql_reconnect_type; -unsigned int mysql_reconnect_count; +int mysql_reconnect_type = 2; +int mysql_reconnect_count = 1; struct sql_interface sql_s; struct sql_interface *SQL; @@ -868,55 +870,67 @@ void hercules_mysql_error_handler(unsigned int ecode) { switch( ecode ) { case 2003:/* Can't connect to MySQL (this error only happens here when failing to reconnect) */ if( mysql_reconnect_type == 1 ) { - static unsigned int retry = 1; + static int retry = 1; if( ++retry > mysql_reconnect_count ) { - ShowFatalError("MySQL has been unreachable for too long, %u reconnects were attempted. Shutting Down\n", retry); + ShowFatalError("MySQL has been unreachable for too long, %d reconnects were attempted. Shutting Down\n", retry); exit(EXIT_FAILURE); } } break; } } -void Sql_inter_server_read(const char* cfgName, bool first) { - char line[1024], w1[1024], w2[1024]; - FILE* fp; - - fp = fopen(cfgName, "r"); - if(fp == NULL) { - if( first ) { - ShowFatalError("File not found: %s\n", cfgName); - exit(EXIT_FAILURE); - } else - ShowError("File not found: %s\n", cfgName); - return; + +/** + * Parses mysql_reconnect from inter_configuration. + * + * @param filename Path to configuration file. + * @param imported Whether the current config is imported from another file. + * + * @retval false in case of error. + */ +bool Sql_inter_server_read(const char *filename, bool imported) +{ + struct config_t config; + const struct config_setting_t *setting = NULL; + const char *import = NULL; + bool retval = true; + + nullpo_retr(false, filename); + + if (!libconfig->load_file(&config, filename)) + return false; + + if ((setting = libconfig->lookup(&config, "inter_configuration/mysql_reconnect")) == NULL) { + config_destroy(&config); + if (imported) + return true; + ShowError("Sql_inter_server_read: inter_configuration/mysql_reconnect was not found in %s!\n", filename); + return false; } - while (fgets(line, sizeof(line), fp)) { - int i = sscanf(line, "%1023[^:]: %1023[^\r\n]", w1, w2); - if (i != 2) - continue; + if (libconfig->setting_lookup_int(setting, "type", &mysql_reconnect_type) == CONFIG_TRUE) { + if (mysql_reconnect_type != 1 && mysql_reconnect_type != 2) { + ShowError("%s::inter_configuration/mysql_reconnect/type is set to %d which is not valid, defaulting to 1...\n", filename, mysql_reconnect_type); + mysql_reconnect_type = 1; + } + } + if (libconfig->setting_lookup_int(setting, "count", &mysql_reconnect_count) == CONFIG_TRUE) { + if (mysql_reconnect_count < 1) + mysql_reconnect_count = 1; + } - if(!strcmpi(w1,"mysql_reconnect_type")) { - mysql_reconnect_type = atoi(w2); - switch( mysql_reconnect_type ) { - case 1: - case 2: - break; - default: - ShowError("%s::mysql_reconnect_type is set to %d which is not valid, defaulting to 1...\n", cfgName, mysql_reconnect_type); - mysql_reconnect_type = 1; - break; - } - } else if(!strcmpi(w1,"mysql_reconnect_count")) { - mysql_reconnect_count = atoi(w2); - if( mysql_reconnect_count < 1 ) - mysql_reconnect_count = 1; - } else if(!strcmpi(w1,"import")) - Sql_inter_server_read(w2,false); + // import should overwrite any previous configuration, so it should be called last + if (libconfig->lookup_string(&config, "import", &import) == CONFIG_TRUE) { + if (strcmp(import, filename) == 0 || strcmp(import, "conf/common/inter-server.conf") == 0) { // FIXME: Hardcoded path + ShowWarning("Sql_inter_server_read: Loop detected in %s! Skipping 'import'...\n", filename); + } else { + if (!Sql_inter_server_read(import, true)) + retval = false; + } } - fclose(fp); - return; + libconfig->destroy(&config); + return retval; } void Sql_HerculesUpdateCheck(struct Sql *self) @@ -1019,7 +1033,7 @@ void Sql_HerculesUpdateSkip(struct Sql *self, const char *filename) } void Sql_Init(void) { - Sql_inter_server_read("conf/inter-server.conf",true); + Sql_inter_server_read("conf/common/inter-server.conf", false); // FIXME: Hardcoded path } void sql_defaults(void) { SQL = &sql_s; diff --git a/src/common/sql.h b/src/common/sql.h index 07be829fc..4d9a12cc1 100644 --- a/src/common/sql.h +++ b/src/common/sql.h @@ -2,7 +2,7 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2012-2015 Hercules Dev Team + * Copyright (C) 2012-2016 Hercules Dev Team * Copyright (C) Athena Dev Teams * * Hercules is free software: you can redistribute it and/or modify diff --git a/src/map/map.c b/src/map/map.c index d6425b94e..56af8113b 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -3997,63 +3997,125 @@ void map_reloadnpc(bool clear) { } } -int inter_config_read(char *cfgName) { - char line[1024],w1[1024],w2[1024]; - FILE *fp; +/** + * Reads inter-server.conf and initializes required variables. + * + * @param filename Path to configuration file + * @param imported Whether the current config is imported from another file. + * + * @retval false in case of error. + */ +bool inter_config_read(const char *filename, bool imported) +{ + struct config_t config; + const struct config_setting_t *setting = NULL; + const char *import = NULL; + bool retval = true; - nullpo_retr(1, cfgName); - if (!(fp = fopen(cfgName,"r"))) { - ShowError("File not found: %s\n",cfgName); - return 1; + nullpo_retr(false, filename); + + if (!libconfig->load_file(&config, filename)) + return false; + + if ((setting = libconfig->lookup(&config, "inter_configuration")) == NULL) { + libconfig->destroy(&config); + if (imported) + return true; + ShowError("inter_config_read: inter_configuration was not found in %s!\n", filename); + return false; } - while (fgets(line, sizeof(line), fp)) { - if (line[0] == '/' && line[1] == '/') - continue; - if (sscanf(line,"%1023[^:]: %1023[^\r\n]", w1, w2) < 2) - continue; - /* map sql stuff */ - if(strcmpi(w1,"map_server_ip")==0) - safestrncpy(map->server_ip, w2, sizeof(map->server_ip)); - else if(strcmpi(w1,"map_server_port")==0) - map->server_port=atoi(w2); - else if(strcmpi(w1,"map_server_id")==0) - safestrncpy(map->server_id, w2, sizeof(map->server_id)); - else if(strcmpi(w1,"map_server_pw")==0) - safestrncpy(map->server_pw, w2, sizeof(map->server_pw)); - else if(strcmpi(w1,"map_server_db")==0) - safestrncpy(map->server_db, w2, sizeof(map->server_db)); - else if(strcmpi(w1,"default_codepage")==0) - safestrncpy(map->default_codepage, w2, sizeof(map->default_codepage)); - else if(strcmpi(w1,"autotrade_merchants_db")==0) - safestrncpy(map->autotrade_merchants_db, w2, sizeof(map->autotrade_merchants_db)); - else if(strcmpi(w1,"autotrade_data_db")==0) - safestrncpy(map->autotrade_data_db, w2, sizeof(map->autotrade_data_db)); - else if(strcmpi(w1,"npc_market_data_db")==0) - safestrncpy(map->npc_market_data_db, w2, sizeof(map->npc_market_data_db)); - /* sql log db */ - else if(strcmpi(w1,"log_db_ip")==0) - safestrncpy(logs->db_ip, w2, sizeof(logs->db_ip)); - else if(strcmpi(w1,"log_db_id")==0) - safestrncpy(logs->db_id, w2, sizeof(logs->db_id)); - else if(strcmpi(w1,"log_db_pw")==0) - safestrncpy(logs->db_pw, w2, sizeof(logs->db_pw)); - else if(strcmpi(w1,"log_db_port")==0) - logs->db_port = atoi(w2); - else if(strcmpi(w1,"log_db_db")==0) - safestrncpy(logs->db_name, w2, sizeof(logs->db_name)); - /* mapreg */ - else if( mapreg->config_read(w1,w2) ) - continue; - /* import */ - else if(strcmpi(w1,"import")==0) - map->inter_config_read(w2); - else - HPM->parseConf(w1, w2, HPCT_MAP_INTER); + if (!map->inter_config_read_database_names(filename, &config, imported)) + retval = false; + if (!map->inter_config_read_connection(filename, &config, imported)) + retval = false; + + // TODO HPM->parseConf(w1, w2, HPCT_MAP_INTER); + + // import should overwrite any previous configuration, so it should be called last + if (libconfig->lookup_string(&config, "import", &import) == CONFIG_TRUE) { + if (strcmp(import, filename) == 0 || strcmp(import, map->INTER_CONF_NAME) == 0) { + ShowWarning("inter_config_read: Loop detected in %s! Skipping 'import'...\n", filename); + } else { + if (!map->inter_config_read(import, true)) + retval = false; + } } - fclose(fp); - return 0; + libconfig->destroy(&config); + return retval; +} + +/** + * Reads the 'inter_configuration/log/sql_connection' config entry and initializes required variables. + * + * @param filename Path to configuration file (used in error and warning messages). + * @param config The current config being parsed. + * @param imported Whether the current config is imported from another file. + * + * @retval false in case of error. + */ +bool inter_config_read_connection(const char *filename, const struct config_t *config, bool imported) +{ + const struct config_setting_t *setting = NULL; + + nullpo_retr(false, filename); + nullpo_retr(false, config); + + if ((setting = libconfig->lookup(config, "inter_configuration/log/sql_connection")) == NULL) { + if (imported) + return true; + ShowError("inter_config_read: inter_configuration/log/sql_connection was not found in %s!\n", filename); + return false; + } + + libconfig->setting_lookup_int(setting, "port", &logs->db_port); + libconfig->setting_lookup_mutable_string(setting, "db_hostname", logs->db_ip, sizeof(logs->db_ip)); + libconfig->setting_lookup_mutable_string(setting, "db_username", logs->db_id, sizeof(logs->db_id)); + libconfig->setting_lookup_mutable_string(setting, "db_password", logs->db_pw, sizeof(logs->db_pw)); + libconfig->setting_lookup_mutable_string(setting, "db_database", logs->db_name, sizeof(logs->db_name)); + + return true; +} + +/** + * Reads the 'inter_configuration/database_names' config entry and initializes required variables. + * + * @param filename Path to configuration file (used in error and warning messages). + * @param config The current config being parsed. + * @param imported Whether the current config is imported from another file. + * + * @retval false in case of error. + */ +bool inter_config_read_database_names(const char *filename, const struct config_t *config, bool imported) +{ + const struct config_setting_t *setting = NULL; + bool retval = true; + + nullpo_retr(false, filename); + nullpo_retr(false, config); + + if ((setting = libconfig->lookup(config, "inter_configuration/database_names")) == NULL) { + if (imported) + return true; + ShowError("inter_config_read: inter_configuration/database_names was not found in %s!\n", filename); + return false; + } + + libconfig->setting_lookup_mutable_string(setting, "autotrade_merchants_db", map->autotrade_merchants_db, sizeof(map->autotrade_merchants_db)); + libconfig->setting_lookup_mutable_string(setting, "autotrade_data_db", map->autotrade_data_db, sizeof(map->autotrade_data_db)); + libconfig->setting_lookup_mutable_string(setting, "npc_market_data_db", map->npc_market_data_db, sizeof(map->npc_market_data_db)); + + if (!mapreg->config_read(filename, setting, imported)) + retval = false; + + if ((setting = libconfig->lookup(config, "inter_configuration/database_names/registry")) == NULL) { + if (imported) + return retval; + ShowError("inter_config_read: inter_configuration/database_names/registry was not found in %s!\n", filename); + return false; + } + return retval; } /*======================================= @@ -6077,7 +6139,7 @@ int do_init(int argc, char *argv[]) map_load_defaults(); - map->INTER_CONF_NAME = aStrdup("conf/inter-server.conf"); + map->INTER_CONF_NAME = aStrdup("conf/common/inter-server.conf"); map->LOG_CONF_NAME = aStrdup("conf/logs.conf"); map->MAP_CONF_NAME = aStrdup("conf/map-server.conf"); map->BATTLE_CONF_FILENAME = aStrdup("conf/battle.conf"); @@ -6128,7 +6190,7 @@ int do_init(int argc, char *argv[]) battle->config_read(map->BATTLE_CONF_FILENAME); atcommand->msg_read(map->MSG_CONF_NAME, false); - map->inter_config_read(map->INTER_CONF_NAME); + map->inter_config_read(map->INTER_CONF_NAME, false); logs->config_read(map->LOG_CONF_NAME); } script->config_read(map->SCRIPT_CONF_NAME); @@ -6288,7 +6350,7 @@ void map_defaults(void) { map->night_flag = 0; // 0=day, 1=night [Yor] map->enable_spy = 0; //To enable/disable @spy commands, which consume too much cpu time when sending packets. [Skotlex] - map->INTER_CONF_NAME="conf/inter-server.conf"; + map->INTER_CONF_NAME="conf/common/inter-server.conf"; map->LOG_CONF_NAME="conf/logs.conf"; map->MAP_CONF_NAME = "conf/map-server.conf"; map->BATTLE_CONF_FILENAME = "conf/battle.conf"; @@ -6502,6 +6564,8 @@ void map_defaults(void) { map->config_read_sub = map_config_read_sub; map->reloadnpc_sub = map_reloadnpc_sub; map->inter_config_read = inter_config_read; + map->inter_config_read_database_names = inter_config_read_database_names; + map->inter_config_read_connection = inter_config_read_connection; map->sql_init = map_sql_init; map->sql_close = map_sql_close; map->zone_mf_cache = map_zone_mf_cache; diff --git a/src/map/map.h b/src/map/map.h index dbd30febf..f98e1cb7f 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -2,7 +2,7 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2012-2015 Hercules Dev Team + * Copyright (C) 2012-2016 Hercules Dev Team * Copyright (C) Athena Dev Teams * * Hercules is free software: you can redistribute it and/or modify @@ -33,6 +33,7 @@ /* Forward Declarations */ struct Sql; // common/sql.h +struct config_t; // common/conf.h struct mob_data; struct npc_data; struct channel_data; @@ -1190,7 +1191,9 @@ END_ZEROED_BLOCK; int (*config_read) (char *cfgName); int (*config_read_sub) (char *cfgName); void (*reloadnpc_sub) (char *cfgName); - int (*inter_config_read) (char *cfgName); + bool (*inter_config_read) (const char *filename, bool imported); + bool (*inter_config_read_database_names) (const char *filename, const struct config_t *config, bool imported); + bool (*inter_config_read_connection) (const char *filename, const struct config_t *config, bool imported); int (*sql_init) (void); int (*sql_close) (void); bool (*zone_mf_cache) (int m, char *flag, char *params); diff --git a/src/map/mapreg.h b/src/map/mapreg.h index d19b2bb80..642bce48e 100644 --- a/src/map/mapreg.h +++ b/src/map/mapreg.h @@ -2,7 +2,7 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2012-2015 Hercules Dev Team + * Copyright (C) 2012-2016 Hercules Dev Team * Copyright (C) Athena Dev Teams * * Hercules is free software: you can redistribute it and/or modify @@ -25,6 +25,8 @@ #include "common/hercules.h" #include "common/db.h" +/* Forward Declarations */ +struct config_setting_t; // common/conf.h struct eri; /** Container for a mapreg value */ @@ -61,7 +63,7 @@ struct mapreg_interface { int (*save_timer) (int tid, int64 tick, int id, intptr_t data); int (*destroyreg) (union DBKey key, struct DBData *data, va_list ap); void (*reload) (void); - bool (*config_read) (const char *w1, const char *w2); + bool (*config_read) (const char *filename, const struct config_setting_t *config, bool imported); }; #ifdef HERCULES_CORE diff --git a/src/map/mapreg_sql.c b/src/map/mapreg_sql.c index 82ce39d64..4cdb91b21 100644 --- a/src/map/mapreg_sql.c +++ b/src/map/mapreg_sql.c @@ -2,7 +2,7 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2012-2015 Hercules Dev Team + * Copyright (C) 2012-2016 Hercules Dev Team * Copyright (C) Athena Dev Teams * * Hercules is free software: you can redistribute it and/or modify @@ -25,6 +25,7 @@ #include "map/map.h" // map-"mysql_handle #include "map/script.h" #include "common/cbasetypes.h" +#include "common/conf.h" #include "common/db.h" #include "common/ers.h" #include "common/memmgr.h" @@ -349,13 +350,19 @@ void mapreg_init(void) { /** * Loads the mapreg configuration file. + * + * @param filename Path to configuration file (used in error and warning messages). + * @param config The current config being parsed. + * @param imported Whether the current config is imported from another file. + * + * @retval false in case of error. */ -bool mapreg_config_read(const char* w1, const char* w2) { - nullpo_retr(false, w1); - nullpo_retr(false, w2); - if(!strcmpi(w1, "mapreg_db")) - safestrncpy(mapreg->table, w2, sizeof(mapreg->table)); - else +bool mapreg_config_read(const char *filename, const struct config_setting_t *config, bool imported) +{ + nullpo_retr(false, filename); + nullpo_retr(false, config); + + if (libconfig->setting_lookup_mutable_string(config, "mapreg_db", mapreg->table, sizeof(mapreg->table)) != CONFIG_TRUE) return false; return true; diff --git a/tools/configconverter.pl b/tools/configconverter.pl index 2849270de..c49dc95d9 100755 --- a/tools/configconverter.pl +++ b/tools/configconverter.pl @@ -263,6 +263,83 @@ my @defaults = ( import => {parse => \&parsecfg_string, print => \&printcfg_nil, path => "", default => "conf/import/char_conf.txt"}, } }, + { + files => ['inter-server.conf', 'import/inter_conf.txt'], + settings => { + party_share_level => {parse => \&parsecfg_int, print => \&printcfg_int, path => "inter-server:inter_configuration/", default => 15}, + log_inter => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "inter-server:inter_configuration/log/", default => "true"}, + inter_log_filename => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/log/", default => "log/inter.log"}, + mysql_reconnect_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "inter-server:inter_configuration/mysql_reconnect/type", default => 2}, + mysql_reconnect_count => {parse => \&parsecfg_int, print => \&printcfg_int, path => "inter-server:inter_configuration/mysql_reconnect/count", default => 1}, + log_login_db => {parse => \&parsecfg_string, print => \&printcfg_nil, path => "inter-server:inter_configuration/database_names/login_db", default => "loginlog"}, + char_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/", default => "char"}, + interlog_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/", default => "interlog"}, + ragsrvinfo_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/", default => "ragsrvinfo"}, + acc_reg_num_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/registry/", default => "acc_reg_num_db"}, + acc_reg_str_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/registry/", default => "acc_reg_str_db"}, + char_reg_num_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/registry/", default => "char_reg_num_db"}, + char_reg_str_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/registry/", default => "char_reg_str_db"}, + global_acc_reg_num_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/registry/", default => "global_acc_reg_num_db"}, + global_acc_reg_str_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/registry/", default => "global_acc_reg_str_db"}, + hotkey_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "hotkey"}, + scdata_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "sc_data"}, + cart_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "cart_inventory"}, + inventory_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "inventory"}, + charlog_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "charlog"}, + storage_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "storage"}, + skill_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "skill"}, + memo_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "memo"}, + party_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "party"}, + pet_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "pet"}, + friend_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "friends"}, + mail_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "mail"}, + auction_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "auction"}, + quest_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "quest"}, + homunculus_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "homunculus"}, + skill_homunculus_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "skill_homunculus"}, + mercenary_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "mercenary"}, + mercenary_owner_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "mercenary_owner"}, + elemental_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "elemental"}, + account_data_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "account_data"}, + guild_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/guild/main_db", default => "guild"}, + guild_alliance_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/guild/alliance_db", default => "guild_alliance"}, + guild_castle_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/guild/castle_db", default => "guild_castle"}, + guild_expulsion_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/guild/expulsion_db", default => "guild_expulsion"}, + guild_member_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/guild/member_db", default => "guild_member"}, + guild_skill_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/guild/skill_db", default => "guild_skill"}, + guild_position_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/guild/position_db", default => "guild_position"}, + guild_storage_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/guild/storage_db", default => "guild_storage"}, + mapreg_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/", default => "mapreg"}, + autotrade_merchants_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/", default => "autotrade_merchants"}, + autotrade_data_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/", default => "autotrade_data"}, + npc_market_data_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/", default => "npc_market_data"}, + default_codepage => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/", default => ""}, + 'sql.db_hostname' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_hostname", default => "127.0.0.1"}, + char_server_ip => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_hostname", default => "127.0.0.1"}, + map_server_ip => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_hostname", default => "127.0.0.1"}, + log_db_ip => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_hostname", default => "127.0.0.1"}, + 'sql.db_port' => {parse => \&parsecfg_int, print => \&printcfg_int, path => "sql_connection:sql_connection/db_port", default => 3306}, + char_server_port => {parse => \&parsecfg_int, print => \&printcfg_int, path => "sql_connection:sql_connection/db_port", default => 3306}, + map_server_port => {parse => \&parsecfg_int, print => \&printcfg_int, path => "sql_connection:sql_connection/db_port", default => 3306}, + log_db_port => {parse => \&parsecfg_int, print => \&printcfg_int, path => "sql_connection:sql_connection/db_port", default => 3306}, + 'sql.db_username' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_username", default => "ragnarok"}, + char_server_id => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_username", default => "ragnarok"}, + map_server_id => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_username", default => "ragnarok"}, + log_db_id => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_username", default => "ragnarok"}, + 'sql.db_password' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_password", default => "ragnarok"}, + char_server_pw => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_password", default => "ragnarok"}, + map_server_pw => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_password", default => "ragnarok"}, + log_db_pw => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_password", default => "ragnarok"}, + 'sql.db_database' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_database", default => "ragnarok"}, + char_server_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_database", default => "ragnarok"}, + map_server_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_database", default => "ragnarok"}, + log_db_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_database", default => "ragnarok"}, + 'sql.codepage' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/codepage", default => ""}, + log_codepage => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/codepage", default => ""}, + interreg_db => {parse => \&parsecfg_string, print => \&printcfg_nil, path => "", default => "interreg"}, + import => {parse => \&parsecfg_string, print => \&printcfg_nil, path => "", default => "conf/import/inter_conf.txt"}, + } + }, ); for (@ARGV) { |