summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--conf/char/char-server.conf1
-rw-r--r--conf/common/inter-server.conf119
-rw-r--r--conf/global/sql_connection.conf49
-rw-r--r--conf/import-tmpl/inter-server.conf32
-rw-r--r--conf/import-tmpl/inter_conf.txt0
-rw-r--r--conf/inter-server.conf125
-rw-r--r--src/char/char.c279
-rw-r--r--src/char/char.h5
-rw-r--r--src/char/inter.c114
-rw-r--r--src/char/inter.h6
-rw-r--r--src/common/sql.c96
-rw-r--r--src/common/sql.h2
-rw-r--r--src/map/map.c174
-rw-r--r--src/map/map.h7
-rw-r--r--src/map/mapreg.h6
-rw-r--r--src/map/mapreg_sql.c21
-rwxr-xr-xtools/configconverter.pl77
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) {