From 34f0540da418b01dd4d49f6ecf72569d3cfecfdf Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Sat, 25 Jan 2014 09:43:09 -0800 Subject: Implement unified config parsing (mostly) --- src/admin/ladmin.cpp | 67 ++++++------ src/char/char.cpp | 156 ++++++++++++++-------------- src/char/char.hpp | 4 - src/char/int_party.cpp | 7 +- src/char/int_party.hpp | 2 +- src/char/int_storage.cpp | 6 +- src/char/int_storage.hpp | 2 +- src/char/inter.cpp | 43 ++------ src/char/inter.hpp | 5 +- src/common/config_parse.cpp | 154 ++++++++++++++++++++++++++++ src/common/config_parse.hpp | 36 +++++++ src/common/core.cpp | 18 +++- src/common/core.hpp | 5 +- src/common/utils.cpp | 22 ---- src/common/utils.hpp | 2 - src/common/version.cpp | 18 ++++ src/common/version.hpp | 35 +++++++ src/login/login.cpp | 192 +++++++++++++++++++---------------- src/map/atcommand.cpp | 91 +++-------------- src/map/atcommand.hpp | 2 +- src/map/battle.cpp | 46 ++++++--- src/map/battle.hpp | 3 +- src/map/chrif.cpp | 4 +- src/map/chrif.hpp | 2 +- src/map/clif.cpp | 8 +- src/map/clif.hpp | 2 +- src/map/itemdb.cpp | 74 ++------------ src/map/itemdb.hpp | 2 +- src/map/magic-interpreter-parser.ypp | 19 ++-- src/map/magic-interpreter.hpp | 3 +- src/map/magic.cpp | 5 - src/map/magic.hpp | 5 - src/map/map.cpp | 148 +++++++++++++++++---------- src/map/map.hpp | 1 - src/map/mob.cpp | 69 ++++--------- src/map/mob.hpp | 5 +- src/map/npc.cpp | 19 ++-- src/map/npc.hpp | 2 +- src/map/pc.cpp | 8 +- src/map/pc.hpp | 2 +- src/map/script.cpp | 32 +++--- src/map/script.hpp | 1 - src/map/skill.cpp | 61 ++++------- src/map/skill.hpp | 2 +- src/map/storage.cpp | 4 - src/map/storage.hpp | 1 - src/monitor/main.cpp | 24 ++++- src/strings/fstring.tcc | 1 + 48 files changed, 759 insertions(+), 661 deletions(-) create mode 100644 src/common/config_parse.cpp create mode 100644 src/common/config_parse.hpp diff --git a/src/admin/ladmin.cpp b/src/admin/ladmin.cpp index 93002c6..ff83530 100644 --- a/src/admin/ladmin.cpp +++ b/src/admin/ladmin.cpp @@ -15,6 +15,7 @@ #include "../io/read.hpp" #include "../io/write.hpp" +#include "../common/config_parse.hpp" #include "../common/core.hpp" #include "../common/human_time_diff.hpp" #include "../common/md5calc.hpp" @@ -25,7 +26,6 @@ #include "../poison.hpp" -#define LADMIN_CONF_NAME "conf/ladmin_athena.conf" static int eathena_interactive_session; @@ -2784,29 +2784,10 @@ int Connect_login_server(void) return 0; } -//----------------------------------- -// Reading general configuration file -//----------------------------------- static -int ladmin_config_read(ZString cfgName) +bool admin_confs(XString w1, ZString w2) { - io::ReadFile in(cfgName); - if (!in.is_open()) { - PRINTF("\033[0mConfiguration file (%s) not found.\n", cfgName); - return 1; - } - - Iprintf("\033[0m---Start reading of Ladmin configuration file (%s)\n", - cfgName); - FString line; - while (in.getline(line)) - { - XString w1; - ZString w2; - if (!split_key_value(line, &w1, &w2)) - continue; - if (w1 == "login_ip") { struct hostent *h = gethostbyname(w2.c_str()); @@ -2834,19 +2815,13 @@ int ladmin_config_read(ZString cfgName) { ladmin_log_filename = w2; } - else if (w1 == "import") - { - ladmin_config_read(w2); - } else { PRINTF("WARNING: unknown ladmin config key: %s\n", FString(w1)); + return false; } } - - Iprintf("---End reading of Ladmin configuration file.\n"); - - return 0; + return true; } //-------------------------------------- @@ -2871,9 +2846,39 @@ void term_func(void) //------------------------ int do_init(int argc, ZString *argv) { + bool loaded_config_yet = false; + for (int i = 1; i < argc; ++i) + { + if (argv[i].startswith('-')) + { + if (argv[i] == "--help") + { + PRINTF("Usage: %s [--help] [--version] [files...]\n", + argv[0]); + exit(0); + } + else if (argv[i] == "--version") + { + PRINTF("%s\n", CURRENT_VERSION_STRING); + exit(0); + } + else + { + FPRINTF(stderr, "Unknown argument: %s\n", argv[i]); + runflag = false; + } + } + else + { + loaded_config_yet = true; + runflag &= load_config_file(argv[i], admin_confs); + } + } + + if (!loaded_config_yet) + runflag &= load_config_file("conf/tmwa-admin.conf", admin_confs); + eathena_interactive_session = isatty(0); - // read ladmin configuration - ladmin_config_read((argc > 1) ? argv[1] : LADMIN_CONF_NAME); LADMIN_LOG(""); LADMIN_LOG("Configuration file readed.\n"); diff --git a/src/char/char.cpp b/src/char/char.cpp index 5c5179d..cb159c3 100644 --- a/src/char/char.cpp +++ b/src/char/char.cpp @@ -24,6 +24,7 @@ #include "../io/lock.hpp" #include "../io/read.hpp" +#include "../common/config_parse.hpp" #include "../common/core.hpp" #include "../common/db.hpp" #include "../common/extract.hpp" @@ -80,9 +81,9 @@ static FString char_log_filename = "log/char.log"; //Added for lan support static -IP4Address lan_map_ip; +IP4Address lan_map_ip = IP4_LOCALHOST; static -IP4Mask lan_subnet; +IP4Mask lan_subnet = IP4Mask(IP4_LOCALHOST, IP4_BROADCAST); static int char_name_option = 0; // Option to know which letters/symbols are authorised in the name of a character (0: all, 1: only those in char_name_letters, 2: all EXCEPT those in char_name_letters) by [Yor] static @@ -451,7 +452,7 @@ int mmo_char_init(void) { line_count++; - if (line.startswith("//")) + if (is_comment(line)) continue; { @@ -2536,32 +2537,11 @@ void check_connect_login_server(TimerData *, tick_t) // Reading Lan Support configuration by [Yor] //------------------------------------------- static -int lan_config_read(ZString lancfgName) +bool char_lan_config(XString w1, ZString w2) { struct hostent *h = NULL; - // set default configuration - lan_map_ip = IP4_LOCALHOST; - lan_subnet = IP4Mask(IP4_LOCALHOST, IP4_BROADCAST); - - io::ReadFile in(lancfgName); - - if (!in.is_open()) - { - PRINTF("LAN support configuration file not found: %s\n", lancfgName); - return 1; - } - - PRINTF("---start reading of Lan Support configuration...\n"); - - FString line; - while (in.getline(line)) { - XString w1; - ZString w2; - if (!split_key_value(line, &w1, &w2)) - continue; - if (w1 == "lan_map_ip") { // Read map-server Lan IP Address @@ -2577,8 +2557,8 @@ int lan_config_read(ZString lancfgName) } else { - PRINTF("Bad IP value: %s\n", line); - abort(); + PRINTF("Bad IP value: %s\n", w2); + return false; } PRINTF("LAN IP of map-server: %s.\n", lan_map_ip); } @@ -2587,54 +2567,42 @@ int lan_config_read(ZString lancfgName) { if (!extract(w2, &lan_subnet)) { - PRINTF("Bad IP mask: %s\n", line); - abort(); + PRINTF("Bad IP mask: %s\n", w2); + return false; } PRINTF("Sub-network of the map-server: %s.\n", lan_subnet); } else { - FString w1z = w1; - PRINTF("WARNING: unknown lan config key: %s\n", w1z); + return false; } } + return true; +} +static +bool lan_check() +{ // sub-network check of the map-server { PRINTF("LAN test of LAN IP of the map-server: "); if (!lan_ip_check(lan_map_ip)) { PRINTF("\033[1;31m***ERROR: LAN IP of the map-server doesn't belong to the specified Sub-network.\033[0m\n"); + return false; } } - PRINTF("---End reading of Lan Support configuration...\n"); - - return 0; + return true; } static -int char_config_read(ZString cfgName) +bool char_config(XString w1, ZString w2) { struct hostent *h = NULL; - io::ReadFile in(cfgName); - - if (!in.is_open()) { - PRINTF("Configuration file not found: %s.\n", cfgName); - exit(1); - } - - FString line; - while (in.getline(line)) - { - XString w1; - ZString w2; - if (!split_key_value(line, &w1, &w2)) - continue; - if (w1 == "userid") userid = stringish(w2); else if (w1 == "passwd") @@ -2665,8 +2633,8 @@ int char_config_read(ZString cfgName) } else { - PRINTF("Bad IP value: %s\n", line); - abort(); + PRINTF("Bad IP value: %s\n", w2); + return false; } } else if (w1 == "login_port") @@ -2689,8 +2657,8 @@ int char_config_read(ZString cfgName) } else { - PRINTF("Bad IP value: %s\n", line); - abort(); + PRINTF("Bad IP value: %s\n", w2); + return false; } } else if (w1 == "char_port") @@ -2775,18 +2743,13 @@ int char_config_read(ZString cfgName) std::chrono::seconds(atoi(w2.c_str())), std::chrono::seconds(5)); } - else if (w1 == "import") - { - char_config_read(w2); - } else { - FString w1z = w1; - PRINTF("WARNING: unknown char config key: %s\n", w1z); + return false; } } - return 0; + return true; } void term_func(void) @@ -2808,39 +2771,70 @@ void term_func(void) CHAR_LOG("----End of char-server (normal end with closing of all files).\n"); } +static +bool char_confs(XString key, ZString value) +{ + unsigned sum = 0; + sum += char_config(key, value); + sum += char_lan_config(key, value); + sum += inter_config(key, value); + if (sum >= 2) + abort(); + return sum; +} + int do_init(int argc, ZString *argv) { - int i; + for (int i = 0; i < MAX_MAP_SERVERS; i++) + { + server[i] = mmo_map_server{}; + server_fd[i] = -1; + } + + bool loaded_config_yet = false; + for (int i = 1; i < argc; ++i) + { + if (argv[i].startswith('-')) + { + if (argv[i] == "--help") + { + PRINTF("Usage: %s [--help] [--version] [files...]\n", + argv[0]); + exit(0); + } + else if (argv[i] == "--version") + { + PRINTF("%s\n", CURRENT_VERSION_STRING); + exit(0); + } + else + { + FPRINTF(stderr, "Unknown argument: %s\n", argv[i]); + runflag = false; + } + } + else + { + loaded_config_yet = true; + runflag &= load_config_file(argv[i], char_confs); + } + } + + if (!loaded_config_yet) + runflag &= load_config_file("conf/tmwa-char.conf", char_confs); // a newline in the log... CHAR_LOG(""); CHAR_LOG("The char-server starting...\n"); - if (argc > 1) - char_config_read(argv[1]); - else - char_config_read(CHAR_CONF_NAME); - if (argc > 1) - lan_config_read(argv[2]); - else - lan_config_read(LOGIN_LAN_CONF_NAME); - - for (i = 0; i < MAX_MAP_SERVERS; i++) - { - server[i] = mmo_map_server{}; - server_fd[i] = -1; - } + runflag &= lan_check(); + inter_init2(); mmo_char_init(); update_online = TimeT::now(); create_online_files(); // update online players files at start of the server - if (argc > 3) - inter_init(argv[3]); - else - inter_init(inter_cfgName); - // set_termfunc (do_final); set_defaultparse(parse_char); diff --git a/src/char/char.hpp b/src/char/char.hpp index f24acbc..27bdd36 100644 --- a/src/char/char.hpp +++ b/src/char/char.hpp @@ -9,10 +9,6 @@ constexpr int MAX_MAP_SERVERS = 30; -# define CHAR_CONF_NAME "conf/char_athena.conf" - -# define LOGIN_LAN_CONF_NAME "conf/lan_support.conf" - struct mmo_map_server { IP4Address ip; diff --git a/src/char/int_party.cpp b/src/char/int_party.cpp index 2972689..1fc0c05 100644 --- a/src/char/int_party.cpp +++ b/src/char/int_party.cpp @@ -102,11 +102,11 @@ bool extract(XString str, party *p) } // パーティデータのロード -int inter_party_init(void) +void inter_party_init(void) { io::ReadFile in(party_txt); if (!in.is_open()) - return 1; + return; // TODO: convert to use char_id, and change to extract() FString line; @@ -136,9 +136,6 @@ int inter_party_init(void) } c++; } -// PRINTF("int_party: %s read done (%d parties)\n", party_txt, c); - - return 0; } // パーティーデータのセーブ用 diff --git a/src/char/int_party.hpp b/src/char/int_party.hpp index e5a3ab9..4e5547c 100644 --- a/src/char/int_party.hpp +++ b/src/char/int_party.hpp @@ -3,7 +3,7 @@ # include "../strings/fwd.hpp" -int inter_party_init(void); +void inter_party_init(void); int inter_party_save(void); int inter_party_parse_frommap(int fd); diff --git a/src/char/int_storage.cpp b/src/char/int_storage.cpp index 4e52215..323a451 100644 --- a/src/char/int_storage.cpp +++ b/src/char/int_storage.cpp @@ -100,7 +100,7 @@ struct storage *account2storage(int account_id) //--------------------------------------------------------- // 倉庫データを読み込む -int inter_storage_init(void) +void inter_storage_init(void) { int c = 0; @@ -108,7 +108,7 @@ int inter_storage_init(void) if (!in.is_open()) { PRINTF("cant't read : %s\n", storage_txt); - return 1; + return; } FString line; @@ -126,8 +126,6 @@ int inter_storage_init(void) } c++; } - - return 0; } static diff --git a/src/char/int_storage.hpp b/src/char/int_storage.hpp index 6c13923..23d7441 100644 --- a/src/char/int_storage.hpp +++ b/src/char/int_storage.hpp @@ -3,7 +3,7 @@ # include "../strings/fwd.hpp" -int inter_storage_init(void); +void inter_storage_init(void); int inter_storage_save(void); void inter_storage_delete(int account_id); struct storage *account2storage(int account_id); diff --git a/src/char/inter.cpp b/src/char/inter.cpp index 38e6194..a0569a7 100644 --- a/src/char/inter.cpp +++ b/src/char/inter.cpp @@ -15,6 +15,7 @@ #include "../io/lock.hpp" #include "../io/read.hpp" +#include "../common/config_parse.hpp" #include "../common/db.hpp" #include "../common/extract.hpp" #include "../common/socket.hpp" @@ -106,13 +107,13 @@ bool extract(XString str, struct accreg *reg) // アカウント変数の読み込み static -int inter_accreg_init(void) +void inter_accreg_init(void) { int c = 0; io::ReadFile in(accreg_txt); if (!in.is_open()) - return 1; + return; FString line; while (in.getline(line)) { @@ -128,8 +129,6 @@ int inter_accreg_init(void) } c++; } - - return 0; } // アカウント変数のセーブ用 @@ -160,30 +159,9 @@ int inter_accreg_save(void) return 0; } -//-------------------------------------------------------- - -/*========================================== - * 設定ファイルを読み込む - *------------------------------------------ - */ -static -int inter_config_read(ZString cfgName) +bool inter_config(XString w1, ZString w2) { - io::ReadFile in(cfgName); - if (!in.is_open()) - { - PRINTF("file not found: %s\n", cfgName); - return 1; - } - - FString line; - while (in.getline(line)) { - XString w1; - ZString w2; - if (!split_key_value(line, &w1, &w2)) - continue; - if (w1 == "storage_txt") { storage_txt = w2; @@ -202,18 +180,13 @@ int inter_config_read(ZString cfgName) if (party_share_level < 0) party_share_level = 0; } - else if (w1 == "import") - { - inter_config_read(w2); - } else { - FString w1z = w1; - PRINTF("WARNING: unknown inter config key: %s\n", w1z); + return false; } } - return 0; + return true; } // セーブ @@ -225,10 +198,8 @@ void inter_save(void) } // 初期化 -void inter_init(ZString file) +void inter_init2() { - inter_config_read(file); - inter_party_init(); inter_storage_init(); inter_accreg_init(); diff --git a/src/char/inter.hpp b/src/char/inter.hpp index ece340a..ae508f6 100644 --- a/src/char/inter.hpp +++ b/src/char/inter.hpp @@ -3,14 +3,13 @@ # include "../strings/fwd.hpp" -void inter_init(ZString file); +bool inter_config(XString key, ZString value); +void inter_init2(); void inter_save(void); int inter_parse_frommap(int fd); int inter_check_length(int fd, int length); -# define inter_cfgName "conf/inter_athena.conf" - extern int party_share_level; #endif // INTER_HPP diff --git a/src/common/config_parse.cpp b/src/common/config_parse.cpp new file mode 100644 index 0000000..d677d8e --- /dev/null +++ b/src/common/config_parse.cpp @@ -0,0 +1,154 @@ +#include "config_parse.hpp" +// config_parse.hpp - Framework for per-server config parsers. +// +// Copyright © 2014 Ben Longbons +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "../strings/xstring.hpp" +#include "../strings/zstring.hpp" + +#include "../io/cxxstdio.hpp" +#include "../io/line.hpp" + +#include "version.hpp" + +#include "../poison.hpp" + +bool is_comment(XString line) +{ + return not line or line.startswith("//"); +} + +template +inline +bool config_split_impl(ZS line, XString *key, ZS *value) +{ + // unconditionally fail if line contains control characters + if (std::find_if(line.begin(), line.end(), + [](unsigned char c) { return c < ' '; } + ) != line.end()) + return false; + // try to find a colon, fail if not found + typename ZS::iterator colon = std::find(line.begin(), line.end(), ':'); + if (colon == line.end()) + return false; + + *key = line.xislice_h(colon).strip(); + // move past the colon and any spaces + ++colon; + *value = line.xislice_t(colon).lstrip(); + return true; +} + +// eventually this should go away +bool config_split(ZString line, XString *key, ZString *value) +{ + return config_split_impl(line, key, value); +} +// and use this instead +bool config_split(XString line, XString *key, XString *value) +{ + return config_split_impl(line, key, value); +} + +/// Master config parser. This handles 'import' and 'version-ge' etc. +/// Then it defers to the inferior parser for a line it does not understand. +bool load_config_file(ZString filename, ConfigItemParser slave) +{ + io::LineReader in(filename); + if (!in.is_open()) + { + PRINTF("Unable to open file: %s\n", filename); + return false; + } + io::Line line; + bool rv = true; + while (in.read_line(line)) + { + if (is_comment(line.text)) + continue; + XString key; + ZString value; + if (!config_split(line.text, &key, &value)) + { + line.error("Bad config line"); + rv = false; + continue; + } + if (key == "import") + { + rv &= load_config_file(value, slave); + continue; + } + else if (key == "version-lt") + { + Version vers; + if (!extract(value, &vers)) + { + rv = false; + continue; + } + if (CURRENT_VERSION < vers) + continue; + break; + } + else if (key == "version-le") + { + Version vers; + if (!extract(value, &vers)) + { + rv = false; + continue; + } + if (CURRENT_VERSION <= vers) + continue; + break; + } + else if (key == "version-gt") + { + Version vers; + if (!extract(value, &vers)) + { + rv = false; + continue; + } + if (CURRENT_VERSION > vers) + continue; + break; + } + else if (key == "version-ge") + { + Version vers; + if (!extract(value, &vers)) + { + rv = false; + continue; + } + if (CURRENT_VERSION >= vers) + continue; + break; + } + else if (!slave(key, value)) + { + line.error("Bad config key or value"); + rv = false; + continue; + } + // nothing to see here, move along + } + return rv; +} diff --git a/src/common/config_parse.hpp b/src/common/config_parse.hpp new file mode 100644 index 0000000..6a55174 --- /dev/null +++ b/src/common/config_parse.hpp @@ -0,0 +1,36 @@ +#ifndef TMWA_COMMON_CONFIG_PARSE_HPP +#define TMWA_COMMON_CONFIG_PARSE_HPP +// config_parse.hpp - Framework for per-server config parsers. +// +// Copyright © 2014 Ben Longbons +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +# include "../sanity.hpp" + +# include "../strings/fwd.hpp" + +typedef bool (*ConfigItemParser)(XString key, ZString value); + +bool is_comment(XString line); +bool config_split(ZString line, XString *key, ZString *value); +bool config_split(XString line, XString *key, XString *value); + +/// Master config parser. This handles 'import' and 'version-ge' etc. +/// Then it defers to the inferior parser for a line it does not understand. +bool load_config_file(ZString filename, ConfigItemParser slave); + +#endif // TMWA_COMMON_CONFIG_PARSE_HPP diff --git a/src/common/core.cpp b/src/common/core.cpp index 727babd..fe2f660 100644 --- a/src/common/core.cpp +++ b/src/common/core.cpp @@ -10,6 +10,8 @@ #include "../strings/zstring.hpp" +#include "../io/cxxstdio.hpp" + #include "random.hpp" #include "socket.hpp" #include "timer.hpp" @@ -46,12 +48,15 @@ sigfunc compat_signal(int signo, sigfunc func) return oact.sa_handler; } +volatile +bool runflag = true; + static void chld_proc(int) { wait(NULL); } -static __attribute__((noreturn)) +static void sig_proc(int) { for (int i = 1; i < 31; ++i) @@ -59,12 +64,9 @@ void sig_proc(int) #pragma GCC diagnostic ignored "-Wold-style-cast" compat_signal(i, SIG_IGN); #pragma GCC diagnostic pop - term_func(); - _exit(0); + runflag = false; } -bool runflag = true; - /* Note about fatal signals: @@ -83,6 +85,12 @@ int main(int argc, char **argv) for (int i = 0; i < argc; ++i) args[i] = ZString(strings::really_construct_from_a_pointer, argv[i], nullptr); do_init(argc, args); + + if (!runflag) + { + PRINTF("Fatal error during startup; exiting\n"); + return 1; + } // set up exit handlers *after* the initialization has happened. // This is because term_func is likely to depend on successful init. diff --git a/src/common/core.hpp b/src/common/core.hpp index f93f5a1..8141e9c 100644 --- a/src/common/core.hpp +++ b/src/common/core.hpp @@ -8,9 +8,8 @@ /// core.c contains a server-independent main() function /// and then runs a do_sendrecv loop -/// When this is cleared, the server exits gracefully -/// only used by map server's GM command: @mapexit -extern bool runflag; +/// When this is cleared, the server exits gracefully. +extern volatile bool runflag; /// This is an external function defined by each server /// This function must register stuff for the parse loop diff --git a/src/common/utils.cpp b/src/common/utils.cpp index 7f9a7ee..3a26e6d 100644 --- a/src/common/utils.cpp +++ b/src/common/utils.cpp @@ -65,28 +65,6 @@ int config_switch(ZString str) abort(); } -bool split_key_value(ZString line, XString *w1, ZString *w2) -{ - if (line.startswith("//")) - return false; - if (!line) - return false; - - if (std::find_if(line.begin(), line.end(), - [](unsigned char c) { return c < ' '; } - ) != line.end()) - return false; - ZString::iterator colon = std::find(line.begin(), line.end(), ':'); - if (colon == line.end()) - return false; - *w1 = line.xislice_h(colon); - ++colon; - while (std::isspace(*colon)) - ++colon; - *w2 = line.xislice_t(colon); - return true; -} - static_assert(sizeof(timestamp_seconds_buffer) == 20, "seconds buffer"); static_assert(sizeof(timestamp_milliseconds_buffer) == 24, "millis buffer"); diff --git a/src/common/utils.hpp b/src/common/utils.hpp index f975e34..161cbd4 100644 --- a/src/common/utils.hpp +++ b/src/common/utils.hpp @@ -29,8 +29,6 @@ struct is_trivially_copyable bool e_mail_check(XString email); int config_switch (ZString str); -bool split_key_value(ZString line, XString *w1, ZString *w2); - inline void really_memcpy(uint8_t *dest, const uint8_t *src, size_t n) { diff --git a/src/common/version.cpp b/src/common/version.cpp index 1ee4071..811ffdf 100644 --- a/src/common/version.cpp +++ b/src/common/version.cpp @@ -2,6 +2,18 @@ #include "../conf/version.hpp" +#include "../strings/xstring.hpp" + +#include "extract.hpp" + +Version CURRENT_VERSION = +{ + VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, + VERSION_DEVEL, + + 0, 0, + VENDOR_VERSION, +}; Version CURRENT_LOGIN_SERVER_VERSION = { VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, @@ -33,3 +45,9 @@ Version CURRENT_MAP_SERVER_VERSION = const char CURRENT_VERSION_STRING[] = "TMWA " S(VERSION_MAJOR) "." S(VERSION_MINOR) "." S(VERSION_PATCH) " dev" S(VERSION_DEVEL) " (" VENDOR " " S(VENDOR_VERSION) ")"; + +bool extract(XString str, Version *vers) +{ + *vers = {}; + return extract(str, record<'.'>(&vers->major, &vers->minor, &vers->patch)); +} diff --git a/src/common/version.hpp b/src/common/version.hpp index 677806b..a2c4e05 100644 --- a/src/common/version.hpp +++ b/src/common/version.hpp @@ -3,6 +3,8 @@ # include +# include "../strings/fwd.hpp" + // TODO make these bitwise enums # define TMWA_FLAG_REGISTRATION 0x01 @@ -25,10 +27,43 @@ struct Version }; static_assert(sizeof(Version) == 8, "this is sent over the network, can't change"); +extern Version CURRENT_VERSION; + extern Version CURRENT_LOGIN_SERVER_VERSION; extern Version CURRENT_CHAR_SERVER_VERSION; extern Version CURRENT_MAP_SERVER_VERSION; extern const char CURRENT_VERSION_STRING[]; +bool extract(XString str, Version *vers); + +constexpr +bool operator < (Version l, Version r) +{ + return (l.major < r.major + || (l.major == r.major + && (l.minor < r.minor + || (l.minor == r.minor + && (l.patch < r.patch + || (l.patch == r.patch + && (l.devel < r.devel + || (l.devel == r.devel + && l.vend < r.vend)))))))); +} +constexpr +bool operator > (Version l, Version r) +{ + return r < l; +} +constexpr +bool operator <= (Version l, Version r) +{ + return !(r < l); +} +constexpr +bool operator >= (Version l, Version r) +{ + return !(l < r); +} + #endif // TMWA_COMMON_VERSION_HPP diff --git a/src/login/login.cpp b/src/login/login.cpp index 6ba09d2..ea2d19c 100644 --- a/src/login/login.cpp +++ b/src/login/login.cpp @@ -24,6 +24,7 @@ #include "../io/lock.hpp" #include "../io/read.hpp" +#include "../common/config_parse.hpp" #include "../common/core.hpp" #include "../common/db.hpp" #include "../common/extract.hpp" @@ -40,9 +41,6 @@ constexpr int MAX_SERVERS = 30; -#define LOGIN_CONF_NAME "conf/login_athena.conf" -#define LAN_CONF_NAME "conf/lan_support.conf" - constexpr int START_ACCOUNT_NUM = 2000000; constexpr int END_ACCOUNT_NUM = 100000000; @@ -77,9 +75,9 @@ int new_account = 0; static int login_port = 6900; static -IP4Address lan_char_ip; +IP4Address lan_char_ip = IP4_LOCALHOST; static -IP4Mask lan_subnet; +IP4Mask lan_subnet = IP4Mask(IP4_LOCALHOST, IP4_BROADCAST); static FString update_host; static @@ -272,9 +270,7 @@ int read_gm_account(void) FString line; while (fp.getline(line) && c < 4000) { - if (!line) - continue; - if (line.startswith("//")) + if (is_comment(line)) continue; GM_Account p {}; if (!extract(line, record<' '>(&p.account_id, &p.level))) @@ -540,6 +536,7 @@ int mmo_auth_init(void) if (!in.is_open()) { // no account file -> no account -> no login, including char-server (ERROR) + // not anymore! :-) PRINTF("\033[1;31mmmo_auth_init: Accounts file [%s] not found.\033[0m\n", account_filename); return 0; @@ -548,7 +545,7 @@ int mmo_auth_init(void) FString line; while (in.getline(line)) { - if (line.startswith("//")) + if (is_comment(line)) continue; if (std::find_if(line.begin(), line.end(), [](unsigned char c) { return c < ' ' && c != '\t'; } @@ -2005,7 +2002,7 @@ void parse_admin(int fd) FString line; while (fp.getline(line)) { - if (!line || line.startswith("//")) + if (is_comment(line)) fp2.put_line(line); else { @@ -3138,33 +3135,11 @@ void parse_login(int fd) // Reading Lan Support configuration //---------------------------------- static -int login_lan_config_read(ZString lancfgName) +bool login_lan_config(XString w1, ZString w2) { struct hostent *h = NULL; - // set default configuration - lan_char_ip = IP4_LOCALHOST; - lan_subnet = IP4Mask(IP4_LOCALHOST, IP4_BROADCAST); - - io::ReadFile in(lancfgName); - - if (!in.is_open()) { - PRINTF("***WARNING: LAN Support configuration file is not found: %s\n", - lancfgName); - return 1; - } - - PRINTF("---Start reading Lan Support configuration file\n"); - - FString line; - while (in.getline(line)) - { - XString w1; - ZString w2; - if (!split_key_value(line, &w1, &w2)) - continue; - if (w1 == "lan_char_ip") { // Read Char-Server Lan IP Address @@ -3180,8 +3155,8 @@ int login_lan_config_read(ZString lancfgName) } else { - PRINTF("Bad IP value: %s\n", line); - abort(); + PRINTF("Bad IP value: %s\n", w2); + return false; } PRINTF("LAN IP of char-server: %s.\n", lan_char_ip); } @@ -3190,19 +3165,23 @@ int login_lan_config_read(ZString lancfgName) { if (!extract(w2, &lan_subnet)) { - PRINTF("Bad IP mask: %s\n", line); - abort(); + PRINTF("Bad IP mask: %s\n", w2); + return false; } PRINTF("Sub-network of the char-server: %s.\n", lan_subnet); } else { - FString w1z = w1; - PRINTF("WARNING: unknown lan-config key: %s\n", w1z); + return false; } } + return true; +} +static +bool lan_check() +{ // log the LAN configuration LOGIN_LOG("The LAN configuration of the server is set:\n"); LOGIN_LOG("- with LAN IP of char-server: %s.\n", lan_char_ip); @@ -3216,37 +3195,20 @@ int login_lan_config_read(ZString lancfgName) { PRINTF("\033[1;31m***ERROR: LAN IP of the char-server doesn't belong to the specified Sub-network\033[0m\n"); LOGIN_LOG("***ERROR: LAN IP of the char-server doesn't belong to the specified Sub-network.\n"); + return false; } } - PRINTF("---End reading of Lan Support configuration file\n"); - - return 0; + return true; } //----------------------------------- // Reading general configuration file //----------------------------------- static -int login_config_read(ZString cfgName) +bool login_config(XString w1, ZString w2) { - io::ReadFile in(cfgName); - if (!in.is_open()) { - PRINTF("Configuration file (%s) not found.\n", cfgName); - return 1; - } - - PRINTF("---Start reading of Login Server configuration file (%s)\n", - cfgName); - FString line; - while (in.getline(line)) - { - XString w1; - ZString w2; - if (!split_key_value(line, &w1, &w2)) - continue; - if (w1 == "admin_state") { admin_state = config_switch(w2); @@ -3279,8 +3241,8 @@ int login_config_read(ZString cfgName) IP4Mask n; if (!extract(w2, &n)) { - PRINTF("Bad IP mask: %s\n", line); - abort(); + PRINTF("Bad IP mask: %s\n", w2); + return false; } access_ladmin.push_back(n); } @@ -3363,7 +3325,10 @@ int login_config_read(ZString cfgName) else if (w2 == "mutual-failture" || w2 == "mutual-failure") access_order = ACO::MUTUAL_FAILURE; else + { PRINTF("Bad order: %s\n", w2); + return false; + } } else if (w1 == "allow") { @@ -3388,8 +3353,8 @@ int login_config_read(ZString cfgName) IP4Mask n; if (!extract(w2, &n)) { - PRINTF("Bad IP mask: %s\n", line); - abort(); + PRINTF("Bad IP mask: %s\n", w2); + return false; } access_allow.push_back(n); } @@ -3418,8 +3383,8 @@ int login_config_read(ZString cfgName) IP4Mask n; if (!extract(w2, &n)) { - PRINTF("Bad IP mask: %s\n", line); - abort(); + PRINTF("Bad IP mask: %s\n", w2); + return false; } access_deny.push_back(n); } @@ -3435,10 +3400,6 @@ int login_config_read(ZString cfgName) std::chrono::seconds(atoi(w2.c_str())), std::chrono::seconds(5)); } - else if (w1 == "import") - { - login_config_read(w2); - } else if (w1 == "update_host") { update_host = w2; @@ -3457,26 +3418,25 @@ int login_config_read(ZString cfgName) } else { - FString w1z = w1; - PRINTF("WARNING: unknown login config key: %s\n", w1z); + return false; } } - PRINTF("---End reading of Login Server configuration file.\n"); - - return 0; + return true; } //------------------------------------- // Displaying of configuration warnings //------------------------------------- static -void display_conf_warnings(void) +bool display_conf_warnings(void) { + bool rv = true; if (admin_state != 0 && admin_state != 1) { PRINTF("***WARNING: Invalid value for admin_state parameter -> set to 0 (no remote admin).\n"); admin_state = 0; + rv = false; } if (admin_state == 1) @@ -3484,6 +3444,7 @@ void display_conf_warnings(void) if (!admin_pass) { PRINTF("***WARNING: Administrator password is void (admin_pass).\n"); + rv = false; } else if (admin_pass == stringish("admin")) { @@ -3496,6 +3457,7 @@ void display_conf_warnings(void) { PRINTF("***WARNING: 'To GM become' password is void (gm_pass).\n"); PRINTF(" We highly recommend that you set one password.\n"); + rv = false; } else if (gm_pass == "gm") { @@ -3507,18 +3469,21 @@ void display_conf_warnings(void) { PRINTF("***WARNING: Invalid value for level_new_gm parameter -> set to 60 (default).\n"); level_new_gm = 60; + rv = false; } if (new_account != 0 && new_account != 1) { PRINTF("***WARNING: Invalid value for new_account parameter -> set to 0 (no new account).\n"); new_account = 0; + rv = false; } if (login_port < 1024 || login_port > 65535) { PRINTF("***WARNING: Invalid value for login_port parameter -> set to 6900 (default).\n"); login_port = 6900; + rv = false; } if (gm_account_filename_check_timer.count() < 0) @@ -3526,18 +3491,21 @@ void display_conf_warnings(void) PRINTF("***WARNING: Invalid value for gm_account_filename_check_timer parameter.\n"); PRINTF(" -> set to 15 sec (default).\n"); gm_account_filename_check_timer = std::chrono::seconds(15); + rv = false; } else if (gm_account_filename_check_timer == std::chrono::seconds(1)) { PRINTF("***WARNING: Invalid value for gm_account_filename_check_timer parameter.\n"); PRINTF(" -> set to 2 sec (minimum value).\n"); gm_account_filename_check_timer = std::chrono::seconds(2); + rv = false; } if (save_unknown_packets != 0 && save_unknown_packets != 1) { PRINTF("WARNING: Invalid value for save_unknown_packets parameter -> set to 0-no save.\n"); save_unknown_packets = 0; + rv = false; } if (display_parse_login != 0 && display_parse_login != 1) @@ -3545,6 +3513,7 @@ void display_conf_warnings(void) PRINTF("***WARNING: Invalid value for display_parse_login parameter\n"); PRINTF(" -> set to 0 (no display).\n"); display_parse_login = 0; + rv = false; } if (display_parse_admin != 0 && display_parse_admin != 1) @@ -3552,6 +3521,7 @@ void display_conf_warnings(void) PRINTF("***WARNING: Invalid value for display_parse_admin parameter\n"); PRINTF(" -> set to 0 (no display).\n"); display_parse_admin = 0; + rv = false; } if (display_parse_fromchar < 0 || display_parse_fromchar > 2) @@ -3559,6 +3529,7 @@ void display_conf_warnings(void) PRINTF("***WARNING: Invalid value for display_parse_fromchar parameter\n"); PRINTF(" -> set to 0 (no display).\n"); display_parse_fromchar = 0; + rv = false; } if (min_level_to_connect < 0) @@ -3567,6 +3538,7 @@ void display_conf_warnings(void) min_level_to_connect); PRINTF(" -> set to 0 (any player).\n"); min_level_to_connect = 0; + rv = false; } else if (min_level_to_connect > 99) { // 0: all players, 1-99 at least gm level x @@ -3574,6 +3546,7 @@ void display_conf_warnings(void) min_level_to_connect); PRINTF(" -> set to 99 (only GM level 99).\n"); min_level_to_connect = 99; + rv = false; } if (add_to_unlimited_account != 0 && add_to_unlimited_account != 1) @@ -3581,6 +3554,7 @@ void display_conf_warnings(void) PRINTF("***WARNING: Invalid value for add_to_unlimited_account parameter\n"); PRINTF(" -> set to 0 (impossible to add a time to an unlimited account).\n"); add_to_unlimited_account = 0; + rv = false; } if (start_limited_time < -1) @@ -3588,6 +3562,7 @@ void display_conf_warnings(void) PRINTF("***WARNING: Invalid value for start_limited_time parameter\n"); PRINTF(" -> set to -1 (new accounts are created with unlimited time).\n"); start_limited_time = -1; + rv = false; } if (check_ip_flag != 0 && check_ip_flag != 1) @@ -3595,6 +3570,7 @@ void display_conf_warnings(void) PRINTF("***WARNING: Invalid value for check_ip_flag parameter\n"); PRINTF(" -> set to 1 (check players ip between login-server & char-server).\n"); check_ip_flag = 1; + rv = false; } if (access_order == ACO::DENY_ALLOW) @@ -3603,6 +3579,7 @@ void display_conf_warnings(void) { PRINTF("***WARNING: The IP security order is 'deny,allow' (allow if not deny).\n"); PRINTF(" And you refuse ALL IP.\n"); + rv = false; } } else if (access_order == ACO::ALLOW_DENY) @@ -3611,6 +3588,7 @@ void display_conf_warnings(void) { PRINTF("***WARNING: The IP security order is 'allow,deny' (deny if not allow).\n"); PRINTF(" But, NO IP IS AUTHORISED!\n"); + rv = false; } } else @@ -3621,14 +3599,17 @@ void display_conf_warnings(void) PRINTF("***WARNING: The IP security order is 'mutual-failture'\n"); PRINTF(" (allow if in the allow list and not in the deny list).\n"); PRINTF(" But, NO IP IS AUTHORISED!\n"); + rv = false; } else if (access_deny.size() == 1 && access_deny.front().mask() == IP4Address()) { PRINTF("***WARNING: The IP security order is mutual-failture\n"); PRINTF(" (allow if in the allow list and not in the deny list).\n"); PRINTF(" But, you refuse ALL IP!\n"); + rv = false; } } + return rv; } //------------------------------- @@ -3825,22 +3806,61 @@ void term_func(void) LOGIN_LOG("----End of login-server (normal end with closing of all files).\n"); } +static +bool login_confs(XString key, ZString value) +{ + unsigned sum = 0; + sum += login_config(key, value); + sum += login_lan_config(key, value); + if (sum >= 2) + abort(); + return sum; +} + //------------------------------ // Main function of login-server //------------------------------ int do_init(int argc, ZString *argv) { - // read login-server configuration - if (argc > 1) - login_config_read(argv[1]); - else - login_config_read(LOGIN_CONF_NAME); - display_conf_warnings(); // not in login_config_read, because we can use 'import' option, and display same message twice or more - save_config_in_log(); // not before, because log file name can be changed - if (argc > 2) - login_lan_config_read(argv[2]); - else - login_lan_config_read(LAN_CONF_NAME); + bool loaded_config_yet = false; + for (int i = 1; i < argc; ++i) + { + if (argv[i].startswith('-')) + { + if (argv[i] == "--help") + { + PRINTF("Usage: %s [--help] [--version] [files...]\n", + argv[0]); + exit(0); + } + else if (argv[i] == "--version") + { + PRINTF("%s\n", CURRENT_VERSION_STRING); + exit(0); + } + else + { + FPRINTF(stderr, "Unknown argument: %s\n", argv[i]); + runflag = false; + } + } + else + { + loaded_config_yet = true; + runflag &= load_config_file(argv[i], login_confs); + } + } + + if (!loaded_config_yet) + runflag &= load_config_file("conf/tmwa-login.conf", login_confs); + + // not in login_config_read, because we can use 'import' option, and display same message twice or more + // (why is that bad?) + runflag &= display_conf_warnings(); + // not before, because log file name can be changed + // (that doesn't stop the char-server though) + save_config_in_log(); + runflag &= lan_check(); for (int i = 0; i < AUTH_FIFO_SIZE; i++) auth_fifo[i].delflag = 1; diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index 5256121..9687968 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -14,6 +14,7 @@ #include "../io/read.hpp" #include "../io/write.hpp" +#include "../common/config_parse.hpp" #include "../common/core.hpp" #include "../common/extract.hpp" #include "../common/human_time_diff.hpp" @@ -317,22 +318,29 @@ AtCommandInfo *get_atcommandinfo_byname(XString name) return atcommand_info.search(name); } -int atcommand_config_read(ZString cfgName) +bool atcommand_config_read(ZString cfgName) { io::ReadFile in(cfgName); if (!in.is_open()) { PRINTF("At commands configuration file not found: %s\n", cfgName); - return 1; + return false; } + bool rv = true; FString line; while (in.getline(line)) { + if (is_comment(line)) + continue; XString w1; ZString w2; - if (!split_key_value(line, &w1, &w2)) + if (!config_split(line, &w1, &w2)) + { + PRINTF("Bad config line: %s\n", line); + rv = false; continue; + } AtCommandInfo *p = get_atcommandinfo_byname(w1); if (p != NULL) { @@ -343,12 +351,15 @@ int atcommand_config_read(ZString cfgName) p->level = 0; } else if (w1 == "import") - atcommand_config_read(w2); + rv &= atcommand_config_read(w2); else + { PRINTF("%s: bad line: %s\n", cfgName, line); + rv = false; + } } - return 0; + return rv; } /// @ command processing functions @@ -3383,61 +3394,6 @@ ATCE atcommand_partyrecall(const int fd, dumb_ptr sd, return ATCE::OKAY; } -static -ATCE atcommand_reloaditemdb(const int fd, dumb_ptr, - ZString) -{ - itemdb_reload(); - clif_displaymessage(fd, "Item database reloaded."); - - return ATCE::OKAY; -} - -static -ATCE atcommand_reloadmobdb(const int fd, dumb_ptr, - ZString) -{ - mob_reload(); - clif_displaymessage(fd, "Monster database reloaded."); - - return ATCE::OKAY; -} - -static -ATCE atcommand_reloadskilldb(const int fd, dumb_ptr, - ZString) -{ - skill_reload(); - clif_displaymessage(fd, "Skill database reloaded."); - - return ATCE::OKAY; -} - -static -ATCE atcommand_reloadscript(const int fd, dumb_ptr, - ZString) -{ - do_init_npc(); - do_init_script(); - - npc_event_do_oninit(); - - clif_displaymessage(fd, "Scripts reloaded."); - - return ATCE::OKAY; -} - -static -ATCE atcommand_reloadgmdb(const int fd, dumb_ptr, - ZString) -{ - chrif_reloadGMdb(); - - clif_displaymessage(fd, "Login-server asked to reload GM accounts and their level."); - - return ATCE::OKAY; -} - static ATCE atcommand_mapinfo(const int fd, dumb_ptr sd, ZString message) @@ -5331,21 +5287,6 @@ Map atcommand_info = {"charstreset", {"", 60, atcommand_charstreset, "Reset a player's stat points"}}, - {"reloaditemdb", {"", - 99, atcommand_reloaditemdb, - "Allegedly to reload the item database"}}, - {"reloadmobdb", {"", - 99, atcommand_reloadmobdb, - "Allegedly to reload the mob database"}}, - {"reloadskilldb", {"", - 99, atcommand_reloadskilldb, - "Allegedly to reload the skill database"}}, - {"reloadscript", {"", - 99, atcommand_reloadscript, - "Allegedly to reload the script database"}}, - {"reloadgmdb", {"", - 99, atcommand_reloadgmdb, - "Unnecessarily reload the GM database"}}, {"charreset", {"", 60, atcommand_charreset, "Reset a player's skills, stats, and magic"}}, diff --git a/src/map/atcommand.hpp b/src/map/atcommand.hpp index 31f1432..b494a25 100644 --- a/src/map/atcommand.hpp +++ b/src/map/atcommand.hpp @@ -10,7 +10,7 @@ bool is_atcommand(const int fd, dumb_ptr sd, ZString message, int gmlvl); -int atcommand_config_read(ZString cfgName); +bool atcommand_config_read(ZString cfgName); void log_atcommand(dumb_ptr sd, ZString cmd); diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 05bacd4..35cef79 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -8,6 +8,7 @@ #include "../io/cxxstdio.hpp" #include "../io/read.hpp" +#include "../common/config_parse.hpp" #include "../common/nullpo.hpp" #include "../common/random.hpp" @@ -21,7 +22,13 @@ #include "../poison.hpp" -struct Battle_Config battle_config; + +static Battle_Config init_battle_config(); + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" +struct Battle_Config battle_config = init_battle_config(); +#pragma GCC diagnostic pop /*========================================== * 自分をロックしている対象の数を返す(汎用) @@ -2289,15 +2296,12 @@ int battle_check_range(dumb_ptr src, dumb_ptr bl, bl->bl_x - dx, bl->bl_y - dy, 0x10001) != -1) ? 1 : 0; } -/*========================================== - * 設定ファイルを読み込む - *------------------------------------------ - */ -int battle_config_read(ZString cfgName) +Battle_Config init_battle_config() { - static int count = 0; - - if ((count++) == 0) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" + Battle_Config battle_config; +#pragma GCC diagnostic pop { battle_config.warp_point_debug = 0; battle_config.enemy_critical = 0; @@ -2403,12 +2407,17 @@ int battle_config_read(ZString cfgName) battle_config.mob_splash_radius = -1; } + return battle_config; +} +bool battle_config_read(ZString cfgName) +{ + bool rv = true; io::ReadFile in(cfgName); if (!in.is_open()) { PRINTF("file not found: %s\n", cfgName); - return 1; + return false; } FString line; @@ -2522,10 +2531,16 @@ int battle_config_read(ZString cfgName) BATTLE_CONFIG_VAR(mob_splash_radius), }; + if (is_comment(line)) + continue; XString w1; ZString w2; - if (!split_key_value(line, &w1, &w2)) + if (!config_split(line, &w1, &w2)) + { + PRINTF("Bad config line: %s\n", line); + rv = false; continue; + } if (w1 == "import") { @@ -2541,12 +2556,17 @@ int battle_config_read(ZString cfgName) } PRINTF("WARNING: unknown battle conf key: %s\n", FString(w1)); + rv = false; continue_outer: ; } - if (--count == 0) + return rv; +} + +void battle_config_check() +{ { if (static_cast(battle_config.flooritem_lifetime) < std::chrono::seconds(1)) battle_config.flooritem_lifetime = std::chrono::duration_cast(LIFETIME_FLOORITEM).count(); @@ -2657,6 +2677,4 @@ int battle_config_read(ZString cfgName) else if (battle_config.mask_ip_gms > 1) battle_config.mask_ip_gms = 1; } - - return 0; } diff --git a/src/map/battle.hpp b/src/map/battle.hpp index 02a32ad..32c479e 100644 --- a/src/map/battle.hpp +++ b/src/map/battle.hpp @@ -202,6 +202,7 @@ extern struct Battle_Config int mob_splash_radius; } battle_config; -int battle_config_read(ZString cfgName); +bool battle_config_read(ZString cfgName); +void battle_config_check(); #endif // BATTLE_HPP diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp index 4afccb7..5b9f96f 100644 --- a/src/map/chrif.cpp +++ b/src/map/chrif.cpp @@ -1187,7 +1187,7 @@ void check_connect_char_server(TimerData *, tick_t) * *------------------------------------------ */ -int do_init_chrif (void) +void do_init_chrif(void) { Timer(gettick() + std::chrono::seconds(1), check_connect_char_server, @@ -1197,6 +1197,4 @@ int do_init_chrif (void) send_users_tochar, std::chrono::seconds(5) ).detach(); - - return 0; } diff --git a/src/map/chrif.hpp b/src/map/chrif.hpp index 51c6d20..dfa2d35 100644 --- a/src/map/chrif.hpp +++ b/src/map/chrif.hpp @@ -34,7 +34,7 @@ int chrif_saveaccountreg2(dumb_ptr sd); int chrif_reloadGMdb(void); int chrif_send_divorce(int char_id); -int do_init_chrif (void); +void do_init_chrif(void); // only used by intif.cpp extern int char_fd; diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 5b7c21d..b4ac24a 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -5597,14 +5597,8 @@ void clif_parse(int fd) RFIFOSKIP(fd, packet_len); } -/*========================================== - * - *------------------------------------------ - */ -int do_init_clif (void) +void do_init_clif(void) { set_defaultparse(clif_parse); make_listen_port(map_port); - - return 0; } diff --git a/src/map/clif.hpp b/src/map/clif.hpp index bf7393c..ad51fc8 100644 --- a/src/map/clif.hpp +++ b/src/map/clif.hpp @@ -161,6 +161,6 @@ int clif_GM_kick(dumb_ptr sd, dumb_ptr tsd, int clif_foreachclient(std::function)>); -int do_init_clif (void); +void do_init_clif(void); #endif // CLIF_HPP diff --git a/src/map/itemdb.cpp b/src/map/itemdb.cpp index 313ff23..bcef583 100644 --- a/src/map/itemdb.cpp +++ b/src/map/itemdb.cpp @@ -10,6 +10,7 @@ #include "../io/cxxstdio.hpp" #include "../io/read.hpp" +#include "../common/config_parse.hpp" #include "../common/db.hpp" #include "../common/extract.hpp" #include "../common/nullpo.hpp" @@ -29,11 +30,6 @@ Map item_db; // Function declarations -static -void itemdb_read(void); -static -int itemdb_readdb(void); - /*========================================== * 名前で検索用 *------------------------------------------ @@ -148,15 +144,11 @@ int itemdb_isequip3(int nameid) || type == ItemType::_8); } -/*========================================== - * アイテムデータベースの読み込み - *------------------------------------------ - */ -static -int itemdb_readdb(void) +bool itemdb_readdb(ZString filename) { + bool rv = true; + int ln = 0, lines = 0; - ZString filename = "db/item_db.txt"; { io::ReadFile in(filename); @@ -164,7 +156,7 @@ int itemdb_readdb(void) if (!in.is_open()) { PRINTF("can't read %s\n", filename); - exit(1); + return false; } lines = 0; @@ -173,9 +165,7 @@ int itemdb_readdb(void) while (in.getline(line)) { lines++; - if (!line) - continue; - if (line.startswith("//")) + if (is_comment(line)) continue; // a line is 17 normal fields followed by 2 {} fields // the fields are separated by ", *", but there may be , @@ -212,6 +202,7 @@ int itemdb_readdb(void) { PRINTF("%s:%d: error: bad item line: %s\n", filename, lines, line); + rv = false; continue; } @@ -245,7 +236,8 @@ int itemdb_readdb(void) } PRINTF("read %s done (count=%d)\n", filename, ln); } - return 0; + + return rv; } /*========================================== @@ -259,18 +251,6 @@ void itemdb_final(struct item_data *id) id->equip_script.reset(); } -void itemdb_reload(void) -{ - /* - * - * - * itemdb_read(); - * - */ - - do_init_itemdb(); -} - /*========================================== * *------------------------------------------ @@ -281,39 +261,3 @@ void do_final_itemdb(void) itemdb_final(&pair.second); item_db.clear(); } - -/* -static -FILE *dfp; -static -int itemdebug(void *key,void *data,_va_list ap){ -// struct item_data *id=(struct item_data *)data; - FPRINTF(dfp,"%6d", (int)key); - return 0; -} -void itemdebugtxt() -{ - dfp=fopen_("itemdebug.txt","wt"); - numdb_foreach(item_db,itemdebug); - fclose_(dfp); -} -*/ - -/*==================================== - * Removed item_value_db, don't re-add - *------------------------------------ - */ -static -void itemdb_read(void) -{ - itemdb_readdb(); -} - -/*========================================== - * - *------------------------------------------ - */ -void do_init_itemdb(void) -{ - itemdb_read(); -} diff --git a/src/map/itemdb.hpp b/src/map/itemdb.hpp index e41be41..2ec8f1c 100644 --- a/src/map/itemdb.hpp +++ b/src/map/itemdb.hpp @@ -77,6 +77,6 @@ int itemdb_isequip3(int); void itemdb_reload(void); void do_final_itemdb(void); -void do_init_itemdb(void); +bool itemdb_readdb(ZString filename); #endif // ITEMDB_HPP diff --git a/src/map/magic-interpreter-parser.ypp b/src/map/magic-interpreter-parser.ypp index d59519a..0e03afb 100644 --- a/src/map/magic-interpreter-parser.ypp +++ b/src/map/magic-interpreter-parser.ypp @@ -1381,16 +1381,17 @@ void INTERN_ASSERT(ZString name, int id) { int zid = intern_id(name); if (zid != id) + { FPRINTF(stderr, "[magic-conf] INTERNAL ERROR: Builtin special var %s interned to %d, not %d as it should be!\n", name, zid, id); - error_flag = 1; + error_flag = 1; + } } extern FILE *magic_frontend_in; -// must be called after itemdb initialisation -int magic_init(const char *conffile) +bool magic_init0() { error_flag = 0; @@ -1404,18 +1405,24 @@ int magic_init(const char *conffile) INTERN_ASSERT("script_target", VAR_SCRIPTTARGET); INTERN_ASSERT("location", VAR_LOCATION); - magic_frontend_in = fopen(conffile, "r"); + return !error_flag; +} + +// must be called after itemdb initialisation +bool magic_init1(ZString conffile) +{ + magic_frontend_in = fopen(conffile.c_str(), "r"); if (!magic_frontend_in) { FPRINTF(stderr, "[magic-conf] Magic configuration file `%s' not found -> no magic.\n", conffile); - return 0; + return false; } magic_frontend_parse(); PRINTF("[magic-conf] Magic initialised. %zu spells, %zu teleport anchors.\n", magic_conf.spells_by_name.size(), magic_conf.anchors_by_name.size()); - return error_flag; + return !error_flag; } extern int magic_frontend_lineno; diff --git a/src/map/magic-interpreter.hpp b/src/map/magic-interpreter.hpp index 8afb8af..19f8574 100644 --- a/src/map/magic-interpreter.hpp +++ b/src/map/magic-interpreter.hpp @@ -445,8 +445,9 @@ struct proc_t {} }; +bool magic_init0(); // must be called after itemdb initialisation -int magic_init(const char *); +bool magic_init1(ZString filename); void spell_update_location(dumb_ptr invocation); #endif // MAGIC_INTERPRETER_HPP diff --git a/src/map/magic.cpp b/src/map/magic.cpp index fd848f5..2e521b2 100644 --- a/src/map/magic.cpp +++ b/src/map/magic.cpp @@ -104,8 +104,3 @@ int magic_message(dumb_ptr caster, XString source_invocation) return 0; /* Not a spell */ } - -void do_init_magic(void) -{ - magic_init(MAGIC_CONFIG_FILE); -} diff --git a/src/map/magic.hpp b/src/map/magic.hpp index 79e2a84..30c6e62 100644 --- a/src/map/magic.hpp +++ b/src/map/magic.hpp @@ -43,11 +43,6 @@ void magic_unshroud(dumb_ptr character); void spell_effect_report_termination(int invocation, int bl_id, StatusChange sc_id, int supplanted); -/** - * Initialise all spells, read config data - */ -void do_init_magic(void); - /** * Identifies the invocation used to trigger a spell * diff --git a/src/map/map.cpp b/src/map/map.cpp index 32df1fd..e141ae1 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -19,6 +19,7 @@ #include "../io/write.hpp" #include "../io/read.hpp" +#include "../common/config_parse.hpp" #include "../common/core.hpp" #include "../common/db.hpp" #include "../common/extract.hpp" @@ -26,6 +27,7 @@ #include "../common/nullpo.hpp" #include "../common/socket.hpp" #include "../common/timer.hpp" +#include "../common/version.hpp" #include "atcommand.hpp" #include "battle.hpp" @@ -73,7 +75,6 @@ interval_t autosave_time = DEFAULT_AUTOSAVE_INTERVAL; int save_settings = 0xFFFF; FString motd_txt = "conf/motd.txt"; -FString help_txt = "conf/help.txt"; CharName wisp_server_name = stringish("Server"); // can be modified in char-server configuration file @@ -1271,8 +1272,10 @@ bool map_readmap(map_local *m, size_t num, MapName fn) *------------------------------------------ */ static -int map_readallmap(void) +bool map_readallmap(void) { + // I am increasingly of the opinion that this needs to be moved earlier. + int maps_removed = 0; int num = 0; @@ -1299,9 +1302,10 @@ int map_readallmap(void) { PRINTF("Cowardly refusing to keep going after removing %d maps.\n", maps_removed); - exit(1); + return false; } - return 0; + + return true; } /*========================================== @@ -1427,7 +1431,7 @@ void map_log(XString line) *------------------------------------------ */ static -int map_config_read(ZString cfgName) +bool map_config_read(ZString cfgName) { struct hostent *h = NULL; @@ -1435,16 +1439,23 @@ int map_config_read(ZString cfgName) if (!in.is_open()) { PRINTF("Map configuration file not found at: %s\n", cfgName); - exit(1); + return false; } + bool rv = true; FString line; while (in.getline(line)) { + if (is_comment(line)) + continue; XString w1; ZString w2; - if (!split_key_value(line, &w1, &w2)) + if (!config_split(line, &w1, &w2)) + { + PRINTF("Bad config line: %s\n", line); + rv = false; continue; + } if (w1 == "userid") { AccountName name = stringish(w2); @@ -1473,7 +1484,7 @@ int map_config_read(ZString cfgName) else { PRINTF("Bad IP value: %s\n", line); - abort(); + return false; } chrif_setip(w2ip); } @@ -1499,7 +1510,7 @@ int map_config_read(ZString cfgName) else { PRINTF("Bad IP value: %s\n", line); - abort(); + return false; } clif_setip(w2ip); } @@ -1535,10 +1546,6 @@ int map_config_read(ZString cfgName) { motd_txt = w2; } - else if (w1 == "help_txt") - { - help_txt = w2; - } else if (w1 == "mapreg_txt") { mapreg_txt = w2; @@ -1553,11 +1560,11 @@ int map_config_read(ZString cfgName) } else if (w1 == "import") { - map_config_read(w2); + rv &= map_config_read(w2); } } - return 0; + return rv; } static @@ -1618,14 +1625,6 @@ void term_func(void) map_close_logfile(); } -/// --help was passed -// FIXME this should produce output -static __attribute__((noreturn)) -void map_helpscreen(void) -{ - exit(1); -} - int compare_item(struct item *a, struct item *b) { return ((a->nameid == b->nameid) && @@ -1637,56 +1636,93 @@ int compare_item(struct item *a, struct item *b) (a->card[2] == b->card[2]) && (a->card[3] == b->card[3])); } +static +bool map_confs(XString key, ZString value) +{ + if (key == "map_conf") + return map_config_read(value); + if (key == "battle_conf") + return battle_config_read(value); + if (key == "atcommand_conf") + return atcommand_config_read(value); + + if (key == "item_db") + return itemdb_readdb(value); + if (key == "mob_db") + return mob_readdb(value); + if (key == "mob_skill_db") + return mob_readskilldb(value); + if (key == "skill_db") + return skill_readdb(value); + if (key == "magic_conf") + return magic_init1(value); + PRINTF("unknown map conf key: %s\n", FString(key)); + return false; +} + /*====================================================== * Map-Server Init and Command-line Arguments [Valaris] *------------------------------------------------------ */ int do_init(int argc, ZString *argv) { - int i; - - ZString MAP_CONF_NAME = "conf/map_athena.conf"; - ZString BATTLE_CONF_FILENAME = "conf/battle_athena.conf"; - ZString ATCOMMAND_CONF_FILENAME = "conf/atcommand_athena.conf"; + runflag &= magic_init0(); - for (i = 1; i < argc; i++) + bool loaded_config_yet = false; + for (int i = 1; i < argc; ++i) { - - if (argv[i] == "--help" || argv[i] == "-h" - || argv[i] == "-?" || argv[i] == "/?") - map_helpscreen(); - else if (argv[i] == "--map_config") - MAP_CONF_NAME = argv[++i]; - else if (argv[i] == "--battle_config") - BATTLE_CONF_FILENAME = argv[++i]; - else if (argv[i] == "--atcommand_config") - ATCOMMAND_CONF_FILENAME = argv[++i]; - else if (argv[i] == "--write-atcommand-config") + if (argv[i].startswith('-')) + { + if (argv[i] == "--help") + { + PRINTF("Usage: %s [--help] [--version] [--write_atcommand_config outfile] [files...]\n", + argv[0]); + exit(0); + } + else if (argv[i] == "--version") + { + PRINTF("%s\n", CURRENT_VERSION_STRING); + exit(0); + } + else if (argv[i] == "--write-atcommand-config") + { + ++i; + if (i == argc) + { + PRINTF("Missing argument\n"); + exit(1); + } + ZString filename = argv[i]; + atcommand_config_write(filename); + exit(0); + } + else + { + FPRINTF(stderr, "Unknown argument: %s\n", argv[i]); + runflag = false; + } + } + else { - ZString filename = argv[++i]; - atcommand_config_write(filename); - exit(0); + loaded_config_yet = true; + runflag &= load_config_file(argv[i], map_confs); } } - map_config_read(MAP_CONF_NAME); - battle_config_read(BATTLE_CONF_FILENAME); - atcommand_config_read(ATCOMMAND_CONF_FILENAME); - script_config_read(); + if (!loaded_config_yet) + runflag &= load_config_file("conf/tmwa-map.conf", map_confs); - map_readallmap(); + battle_config_check(); + runflag &= map_readallmap(); - do_init_chrif (); - do_init_clif (); - do_init_itemdb(); - do_init_mob(); // npcの初期化時内でmob_spawnして、mob_dbを参照するのでinit_npcより先 + do_init_chrif(); + do_init_clif(); + do_init_mob2(); do_init_script(); - do_init_npc(); + + runflag &= do_init_npc(); do_init_pc(); do_init_party(); - do_init_storage(); - do_init_skill(); - do_init_magic(); npc_event_do_oninit(); // npcのOnInitイベント実行 diff --git a/src/map/map.hpp b/src/map/map.hpp index 882fde6..0038e67 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -575,7 +575,6 @@ extern interval_t autosave_time; extern int save_settings; extern FString motd_txt; -extern FString help_txt; extern CharName wisp_server_name; diff --git a/src/map/mob.cpp b/src/map/mob.cpp index 960c58e..d68c580 100644 --- a/src/map/mob.cpp +++ b/src/map/mob.cpp @@ -14,6 +14,7 @@ #include "../io/cxxstdio.hpp" #include "../io/read.hpp" +#include "../common/config_parse.hpp" #include "../common/extract.hpp" #include "../common/nullpo.hpp" #include "../common/random.hpp" @@ -3408,31 +3409,24 @@ bool extract(XString str, LevelElement *le) return false; } -/*========================================== - * db/mob_db.txt reading - *------------------------------------------ - */ -static -int mob_readdb(void) +bool mob_readdb(ZString filename) { - ZString filename = "db/mob_db.txt"; - - for (mob_db_& e : mob_db) - e = mob_db_{}; - + bool rv = true; { io::ReadFile in(filename); if (!in.is_open()) { - return -1; + PRINTF("Unable to read mob db: %s\n", filename); + return false; } FString line; while (in.getline(line)) { int mob_class; - if (!line || line.startswith("//")) + if (is_comment(line)) continue; + struct mob_db_ mdbv {}; XString ignore; @@ -3501,6 +3495,7 @@ int mob_readdb(void) if (!okay || mob_class <= 1000 || mob_class > 2000) { PRINTF("bad mob line: %s\n", line); + rv = false; continue; } @@ -3554,7 +3549,7 @@ int mob_readdb(void) } PRINTF("read %s done\n", filename); } - return 0; + return rv; } template<> @@ -3625,28 +3620,22 @@ bool extract(XString str, MobSkillTarget *mst) return false; } -/*========================================== - * db/mob_skill_db.txt reading - *------------------------------------------ - */ -static -int mob_readskilldb(void) +bool mob_readskilldb(ZString filename) { - ZString filename = "db/mob_skill_db.txt"; - + bool rv = true; { io::ReadFile in(filename); if (!in.is_open()) { PRINTF("can't read %s\n", filename); - return 0; + return false; } FString line; while (in.getline(line)) { int mob_id; - if (line.startswith("//")) + if (is_comment(line)) continue; XString blah; @@ -3692,43 +3681,29 @@ int mob_readskilldb(void) else if (cancellable == "no") msv.cancel = false; else + { + rv = false; continue; + } msv.casttime = std::chrono::milliseconds(casttime); msv.delay = std::chrono::milliseconds(delay); if (mob_id <= 0) + { + rv = false; continue; + } mob_db[mob_id].skills.push_back(std::move(msv)); } PRINTF("read %s done\n", filename); } - return 0; + return rv; } -void mob_reload(void) +void do_init_mob2(void) { - /* - * - * - * mob_read(); - * - */ - - do_init_mob(); -} - -/*========================================== - * Circumference initialization of mob - *------------------------------------------ - */ -int do_init_mob(void) -{ - mob_readdb(); - - mob_readskilldb(); - Timer(gettick() + MIN_MOBTHINKTIME, mob_ai_hard, MIN_MOBTHINKTIME @@ -3737,6 +3712,4 @@ int do_init_mob(void) mob_ai_lazy, MIN_MOBTHINKTIME * 10 ).detach(); - - return 0; } diff --git a/src/map/mob.hpp b/src/map/mob.hpp index b0445de..bc8350a 100644 --- a/src/map/mob.hpp +++ b/src/map/mob.hpp @@ -84,7 +84,10 @@ short mob_get_head_mid(int); short mob_get_head_buttom(int); short mob_get_clothes_color(int); //player mob dye [Valaris] int mob_get_equip(int); // mob equip [Valaris] -int do_init_mob(void); + +bool mob_readdb(ZString filename); +bool mob_readskilldb(ZString filename); +void do_init_mob2(void); int mob_delete(dumb_ptr md); int mob_catch_delete(dumb_ptr md, BeingRemoveWhy type); diff --git a/src/map/npc.cpp b/src/map/npc.cpp index f5a1f21..4a116b2 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -15,6 +15,7 @@ #include "../io/cxxstdio.hpp" #include "../io/read.hpp" +#include "../common/config_parse.hpp" #include "../common/db.hpp" #include "../common/extract.hpp" #include "../common/nullpo.hpp" @@ -1711,8 +1712,9 @@ void npc_free(dumb_ptr nd) * npc初期化 *------------------------------------------ */ -int do_init_npc(void) +bool do_init_npc(void) { + bool rv = true; // other fields unused ev_tm_b.tm_min = -1; ev_tm_b.tm_hour = -1; @@ -1725,7 +1727,8 @@ int do_init_npc(void) if (!fp.is_open()) { PRINTF("file not found : %s\n", nsl); - exit(1); + rv = false; + continue; } PRINTF("\rLoading NPCs [%d]: %-54s", npc_id - START_NPC_NUM, nsl); @@ -1737,14 +1740,13 @@ int do_init_npc(void) ZString w4z; lines++; - if (!zline) - continue; - if (zline.startswith("//")) + if (is_comment(zline)) continue; if (!extract(zline, record<'|', 3>(&w1, &w2, &w3, &w4x)) || !w1 || !w2 || !w3) { FPRINTF(stderr, "%s:%d: Broken script line: %s\n", nsl, lines, zline); + rv = false; continue; } if (&*w4x.end() == &*zline.end()) @@ -1762,6 +1764,7 @@ int do_init_npc(void) { // "mapname" is not assigned to this server FPRINTF(stderr, "%s:%d: Map not found: %s\n", nsl, lines, mapname); + rv = false; continue; } } @@ -1801,6 +1804,7 @@ int do_init_npc(void) else { PRINTF("odd script line: %s\n", zline); + script_errors++; } } fflush(stdout); @@ -1811,8 +1815,7 @@ int do_init_npc(void) if (script_errors) { PRINTF("Cowardly refusing to continue after %d errors\n", script_errors); - abort(); + rv = false; } - - return 0; + return rv; } diff --git a/src/map/npc.hpp b/src/map/npc.hpp index 0bc00ed..17eea04 100644 --- a/src/map/npc.hpp +++ b/src/map/npc.hpp @@ -48,7 +48,7 @@ void npc_free(dumb_ptr npc); void npc_addsrcfile(FString); void npc_delsrcfile(FString); -int do_init_npc(void); +bool do_init_npc(void); int npc_event_do_oninit(void); int npc_event_doall_l(ScriptLabel name, int rid, int argc, struct argrec_t *argv); diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 4cfa107..73639dd 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -5269,11 +5269,7 @@ void pc_calc_sigma(void) } } -/*========================================== - * pc関 係初期化 - *------------------------------------------ - */ -int do_init_pc(void) +void do_init_pc(void) { pc_calc_sigma(); natural_heal_prev_tick = gettick() + NATURAL_HEAL_INTERVAL; @@ -5284,8 +5280,6 @@ int do_init_pc(void) Timer(gettick() + autosave_time, pc_autosave ).detach(); - - return 0; } void pc_cleanup(dumb_ptr sd) diff --git a/src/map/pc.hpp b/src/map/pc.hpp index 40d0e76..54394a2 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -153,6 +153,6 @@ int pc_logout(dumb_ptr sd); // [fate] Player logs out void pc_show_motd(dumb_ptr sd); -int do_init_pc(void); +void do_init_pc(void); #endif // PC_HPP diff --git a/src/map/script.cpp b/src/map/script.cpp index e947208..51f228f 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -16,6 +16,7 @@ #include "../io/lock.hpp" #include "../io/read.hpp" +#include "../common/config_parse.hpp" #include "../common/core.hpp" #include "../common/db.hpp" #include "../common/extract.hpp" @@ -89,13 +90,20 @@ const char *pos_str[11] = static struct Script_Config { - int warn_func_no_comma; - int warn_cmd_no_comma; - int warn_func_mismatch_paramnum; - int warn_cmd_mismatch_paramnum; - int check_cmdcount; - int check_gotocount; + static const + int warn_func_no_comma = 1; + static const + int warn_cmd_no_comma = 1; + static const + int warn_func_mismatch_paramnum = 1; + static const + int warn_cmd_mismatch_paramnum = 1; + static const + int check_cmdcount = 8192; + static const + int check_gotocount = 512; } script_config; + static int parse_cmd_if = 0; static @@ -698,7 +706,7 @@ void read_constdb(void) FString line; while (in.getline(line)) { - if (line.startswith("//")) + if (is_comment(line)) continue; FString name; @@ -5001,16 +5009,6 @@ void script_autosave_mapreg(TimerData *, tick_t) script_save_mapreg(); } -void script_config_read() -{ - script_config.warn_func_no_comma = 1; - script_config.warn_cmd_no_comma = 1; - script_config.warn_func_mismatch_paramnum = 1; - script_config.warn_cmd_mismatch_paramnum = 1; - script_config.check_cmdcount = 8192; - script_config.check_gotocount = 512; -} - void do_final_script(void) { if (mapreg_dirty >= 0) diff --git a/src/map/script.hpp b/src/map/script.hpp index da1d3ce..a05ecf6 100644 --- a/src/map/script.hpp +++ b/src/map/script.hpp @@ -159,7 +159,6 @@ Map scriptlabel_db; extern UPMap userfunc_db; -void script_config_read(); void do_init_script(void); void do_final_script(void); diff --git a/src/map/skill.cpp b/src/map/skill.cpp index 5c8ba09..2253d9d 100644 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -1173,29 +1173,21 @@ SP scan_stat(XString statname) return SP::ZERO; } -/*========================================== - * スキル関係ファイル読み込み - * skill_db.txt スキルデータ - * skill_cast_db.txt スキルの詠唱時間とディレイデータ - *------------------------------------------ - */ -static -int skill_readdb(void) +bool skill_readdb(ZString filename) { - /* The main skill database */ - for (skill_db_& skdb : skill_db) - skdb = skill_db_{}; - - io::ReadFile in("db/skill_db.txt"); + io::ReadFile in(filename); if (!in.is_open()) { - PRINTF("can't read db/skill_db.txt\n"); - return 1; + PRINTF("can't read %s\n", filename); + return false; } + bool rv = true; FString line_; while (in.getline(line_)) { + // is_comment only works for whole-line comments + // that could change once the Z dependency is dropped ... XString comment = "//"; XString line = line_.xislice_h(std::search(line_.begin(), line_.end(), comment.begin(), comment.end())).rstrip(); if (!line) @@ -1228,16 +1220,25 @@ int skill_readdb(void) ) ) ) + { + rv = false; continue; + } if (/*i < SkillID() ||*/ i > SkillID::MAX_SKILL_DB) + { + rv = false; continue; + } if (castcancel == "yes") skdb.castcancel = true; else if (castcancel == "no") skdb.castcancel = false; else + { + rv = false; continue; + } if (flags == "passive") { @@ -1252,7 +1253,10 @@ int skill_readdb(void) else if (flags == "no") skdb.poolflags = SkillFlags::ZERO; else + { + rv = false; continue; + } skdb.stat = scan_stat(stat); @@ -1265,32 +1269,9 @@ int skill_readdb(void) skill_db[i] = skdb; skill_lookup_by_id(i).desc = FString(tmp); } - PRINTF("read db/skill_db.txt done\n"); - - return 0; -} - -void skill_reload(void) -{ - /* - * - * - * - * - */ - - do_init_skill(); -} + PRINTF("read %s done\n", filename); -/*========================================== - * スキル関係初期化処理 - *------------------------------------------ - */ -int do_init_skill(void) -{ - skill_readdb(); - - return 0; + return rv; } constexpr size_t num_names = sizeof(skill_names) / sizeof(skill_names[0]); diff --git a/src/map/skill.hpp b/src/map/skill.hpp index 14ff1b5..5f29443 100644 --- a/src/map/skill.hpp +++ b/src/map/skill.hpp @@ -57,7 +57,7 @@ skill_name_db& skill_lookup_by_name(XString name); struct block_list; struct map_session_data; -int do_init_skill(void); +bool skill_readdb(ZString filename); // スキルデータベースへのアクセサ int skill_get_hit(SkillID id); diff --git a/src/map/storage.cpp b/src/map/storage.cpp index 54bc792..d6832c8 100644 --- a/src/map/storage.cpp +++ b/src/map/storage.cpp @@ -21,10 +21,6 @@ static Map storage_db; -void do_init_storage(void) -{ -} - void do_final_storage(void) { storage_db.clear(); diff --git a/src/map/storage.hpp b/src/map/storage.hpp index f923ebe..76be7d6 100644 --- a/src/map/storage.hpp +++ b/src/map/storage.hpp @@ -10,7 +10,6 @@ int storage_storageopen(dumb_ptr sd); int storage_storageadd(dumb_ptr sd, int index, int amount); int storage_storageget(dumb_ptr sd, int index, int amount); int storage_storageclose(dumb_ptr sd); -void do_init_storage(void); void do_final_storage(void); struct storage *account2storage(int account_id); struct storage *account2storage2(int account_id); diff --git a/src/monitor/main.cpp b/src/monitor/main.cpp index 934e24f..1bc9880 100644 --- a/src/monitor/main.cpp +++ b/src/monitor/main.cpp @@ -22,6 +22,7 @@ #include "../io/cxxstdio.hpp" #include "../io/read.hpp" +#include "../common/config_parse.hpp" #include "../common/utils.hpp" #include "../poison.hpp" @@ -57,7 +58,7 @@ FString make_path(XString base, XString path) } static -void parse_option(XString name, ZString value) +bool parse_option(XString name, ZString value) { if (name == "login_server") login_server = value; @@ -72,12 +73,15 @@ void parse_option(XString name, ZString value) FString name_ = name; FPRINTF(stderr, "WARNING: ingnoring invalid option '%s' : '%s'\n", name_, value); + return false; } + return true; } static -void read_config(ZString filename) +bool read_config(ZString filename) { + bool rv = true; io::ReadFile in(filename); if (!in.is_open()) { @@ -88,13 +92,25 @@ void read_config(ZString filename) FString line; while (in.getline(line)) { + if (is_comment(line)) + continue; XString name; ZString value; - if (!split_key_value(line, &name, &value)) + if (!config_split(line, &name, &value)) + { + PRINTF("Bad line: %s\n", line); + rv = false; continue; + } - parse_option(name, value); + if (!parse_option(name, value)) + { + PRINTF("Bad key/value: %s\n", line); + rv = false; + continue; + } } + return rv; } static diff --git a/src/strings/fstring.tcc b/src/strings/fstring.tcc index 9c5f37b..8072fb0 100644 --- a/src/strings/fstring.tcc +++ b/src/strings/fstring.tcc @@ -24,6 +24,7 @@ namespace strings template void FString::_assign(It b, It e) { + owned = nullptr; if (b == e) { *this = FString(); -- cgit v1.2.3-60-g2f50