From c482e420bcf447073ffe3ff8a106a0561e0baadd Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Sat, 10 Jan 2015 17:21:56 -0800 Subject: Use generated config for char --- src/char/char.cpp | 437 ++++++++++++------------------------------------------ 1 file changed, 96 insertions(+), 341 deletions(-) (limited to 'src/char/char.cpp') diff --git a/src/char/char.cpp b/src/char/char.cpp index ff9905f..a9b6834 100644 --- a/src/char/char.cpp +++ b/src/char/char.cpp @@ -78,7 +78,11 @@ #include "../wire/packets.hpp" +#include "char_conf.hpp" +#include "char_lan_conf.hpp" +#include "globals.hpp" #include "inter.hpp" +#include "inter_conf.hpp" #include "int_party.hpp" #include "int_storage.hpp" @@ -87,52 +91,8 @@ namespace tmwa { -static -Array server; -static -Array server_session; -static -Array server_freezeflag; // Map-server anti-freeze system. Counter. 5 ok, 4...0 freezed -static -int anti_freeze_enable = 0; -static -std::chrono::seconds anti_freeze_interval = 6_s; - -static -Session *login_session, *char_session; -static -AccountName userid; -static -AccountPass passwd; -static -ServerName server_name; -static -const CharName WISP_SERVER_NAME = stringish("Server"_s); -static -IP4Address login_ip; -static -int login_port = 6900; -static -IP4Address char_ip; -static -int char_port = 6121; -static -AString char_txt; -static -CharName unknown_char_name = stringish("Unknown"_s); -static -AString char_log_filename = "log/char.log"_s; -//Added for lan support -static -IP4Address lan_map_ip = IP4_LOCALHOST; -static -IP4Mask lan_subnet = IP4Mask(IP4_LOCALHOST, IP4_BROADCAST); -static -std::bitset<256> char_name_letters; // list of letters/symbols authorised (or not) in a character name. by [Yor] -static constexpr -GmLevel default_gm_level = GmLevel::from(0_u32); - - +namespace char_ +{ struct char_session_data : SessionData { AccountId account_id; @@ -141,61 +101,15 @@ struct char_session_data : SessionData unsigned short packet_tmw_version; AccountEmail email; }; +} // namespace char_ void SessionDeleter::operator()(SessionData *sd) { - really_delete1 static_cast(sd); + really_delete1 static_cast(sd); } -struct AuthFifoEntry +namespace char_ { - AccountId account_id; - CharId char_id; - int login_id1, login_id2; - IP4Address ip; - int delflag; - SEX sex; - unsigned short packet_tmw_version; -}; -static -std::array auth_fifo; -static -auto auth_fifo_iter = auth_fifo.begin(); - -static -CharId char_id_count = wrap(150000); -static -std::vector char_keys; -static -int max_connect_user = 0; -static -std::chrono::milliseconds autosave_time = DEFAULT_AUTOSAVE_INTERVAL; - -// Initial position (it's possible to set it in conf file) -static -Point start_point = { {"001-1.gat"_s}, 273, 354 }; - -static -std::vector gm_accounts; - -// online players by [Yor] -static -AString online_txt_filename = "online.txt"_s; -static -AString online_html_filename = "online.html"_s; -static -int online_refresh_html = 20; // refresh time (in sec) of the html file in the explorer -static -GmLevel online_gm_display_min_level = GmLevel::from(20_u32); // minimum GM level to display 'GM' when we want to display it - -static -std::vector online_chars; // same size of char_keys, and id value of current server (or -1) -static -TimeT update_online; // to update online files when we receiving information from a server (not less than 8 seconds) - -static -pid_t pid = 0; // For forked DB writes - auto iter_map_sessions() -> decltype(filter_iterator(std::declval *>())) { @@ -241,7 +155,7 @@ void delete_frommap(Session *sess) //------------------------------ void char_log(XString line) { - io::AppendFile logfp(char_log_filename, true); + io::AppendFile logfp(char_conf.char_log_filename, true); if (!logfp.is_open()) return; log_with_timestamp(logfp, line); @@ -318,7 +232,7 @@ AString mmo_char_tostr(struct CharPair *cp) // on multi-map server, sometimes it's posssible that last_point become void. (reason???) We check that to not lost character at restart. if (!p->last_point.map_) { - p->last_point = start_point; + p->last_point = char_conf.start_point; } MString str_p; @@ -405,12 +319,6 @@ AString mmo_char_tostr(struct CharPair *cp) return AString(str_p); } -static -bool impl_extract(XString str, Point *p) -{ - return extract(str, record<','>(&p->map_, &p->x, &p->y)); -} - struct skill_loader { SkillID id; @@ -429,6 +337,7 @@ bool impl_extract(XString str, struct skill_loader *s) s->flags = SkillFlags(flags_and_level >> 16); return true; } +} // namespace char //------------------------------------------------------------------------- // Function to set the character from the line (at read of characters file) @@ -436,6 +345,8 @@ bool impl_extract(XString str, struct skill_loader *s) static bool impl_extract(XString str, CharPair *cp) { + using namespace tmwa::char_; + CharKey *k = &cp->key; CharData *p = cp->data.get(); @@ -523,6 +434,8 @@ bool impl_extract(XString str, CharPair *cp) return true; } +namespace char_ +{ //--------------------------------- // Function to read characters file //--------------------------------- @@ -532,11 +445,11 @@ int mmo_char_init(void) char_keys.clear(); online_chars.clear(); - io::ReadFile in(char_txt); + io::ReadFile in(char_conf.char_txt); if (!in.is_open()) { - PRINTF("Characters file not found: %s.\n"_fmt, char_txt); - CHAR_LOG("Characters file not found: %s.\n"_fmt, char_txt); + PRINTF("Characters file not found: %s.\n"_fmt, char_conf.char_txt); + CHAR_LOG("Characters file not found: %s.\n"_fmt, char_conf.char_txt); CHAR_LOG("Id for the next created character: %d.\n"_fmt, char_id_count); return 0; @@ -574,9 +487,9 @@ int mmo_char_init(void) } PRINTF("mmo_char_init: %zu characters read in %s.\n"_fmt, - char_keys.size(), char_txt); + char_keys.size(), char_conf.char_txt); CHAR_LOG("mmo_char_init: %zu characters read in %s.\n"_fmt, - char_keys.size(), char_txt); + char_keys.size(), char_conf.char_txt); CHAR_LOG("Id for the next created character: %d.\n"_fmt, char_id_count); @@ -590,7 +503,7 @@ int mmo_char_init(void) static void mmo_char_sync(void) { - io::WriteLock fp(char_txt); + io::WriteLock fp(char_conf.char_txt); if (!fp.is_open()) { PRINTF("WARNING: Server can't not save characters.\n"_fmt); @@ -681,12 +594,14 @@ CharPair *make_new_char(Session *s, CharName name, const Stats6& stats, uint8_t { // only letters/symbols in char_name_letters are authorised for (uint8_t c : name.to__actual()) - if (!char_name_letters[c]) + { + if (!char_conf.char_name_letters[c]) { CHAR_LOG("Make new char error (invalid letter in the name): (connection #%d, account: %d), name: %s, invalid letter: %c.\n"_fmt, s, sd->account_id, name, c); return nullptr; } + } } // TODO this comment is obsolete @@ -800,8 +715,8 @@ CharPair *make_new_char(Session *s, CharName name, const Stats6& stats, uint8_t cd.head_top = ItemNameId(); cd.head_mid = ItemNameId(); cd.head_bottom = ItemNameId(); - cd.last_point = start_point; - cd.save_point = start_point; + cd.last_point = char_conf.start_point; + cd.save_point = char_conf.start_point; char_keys.push_back(std::move(cp)); online_chars.push_back(nullptr); @@ -815,10 +730,10 @@ static void create_online_files(void) { // write files - io::WriteFile fp(online_txt_filename); + io::WriteFile fp(char_conf.online_txt_filename); if (fp.is_open()) { - io::WriteFile fp2(online_html_filename); + io::WriteFile fp2(char_conf.online_html_filename); if (fp2.is_open()) { // get time @@ -826,15 +741,15 @@ void create_online_files(void) stamp_time(timetemp); // write heading FPRINTF(fp2, "\n"_fmt); - FPRINTF(fp2, " \n"_fmt, online_refresh_html); // update on client explorer every x seconds + FPRINTF(fp2, " \n"_fmt, char_conf.online_refresh_html); // update on client explorer every x seconds FPRINTF(fp2, " \n"_fmt); FPRINTF(fp2, " Online Players on %s\n"_fmt, - server_name); + char_conf.server_name); FPRINTF(fp2, " \n"_fmt); FPRINTF(fp2, " \n"_fmt); FPRINTF(fp2, "

Online Players on %s (%s):

\n"_fmt, - server_name, timetemp); - FPRINTF(fp, "Online Players on %s (%s):\n"_fmt, server_name, timetemp); + char_conf.server_name, timetemp); + FPRINTF(fp, "Online Players on %s (%s):\n"_fmt, char_conf.server_name, timetemp); FPRINTF(fp, "\n"_fmt); int players = 0; @@ -870,14 +785,14 @@ void create_online_files(void) // without/with 'GM' display GmLevel gml = isGM(cd.key.account_id); { - if (gml.satisfies(online_gm_display_min_level)) + if (gml.satisfies(char_conf.online_gm_display_min_level)) FPRINTF(fp, "%-24s (GM) "_fmt, cd.key.name); else FPRINTF(fp, "%-24s "_fmt, cd.key.name); } // name of the character in the html (no < >, because that create problem in html code) FPRINTF(fp2, " "_fmt); - if (gml.satisfies(online_gm_display_min_level)) + if (gml.satisfies(char_conf.online_gm_display_min_level)) FPRINTF(fp2, ""_fmt); for (char c : cd.key.name.to__actual()) { @@ -897,7 +812,7 @@ void create_online_files(void) break; }; } - if (gml.satisfies(online_gm_display_min_level)) + if (gml.satisfies(char_conf.online_gm_display_min_level)) FPRINTF(fp2, " (GM)"_fmt); FPRINTF(fp2, "\n"_fmt); } @@ -1257,8 +1172,8 @@ void parse_tologin(Session *ls) fixed_6c.code = 0x42; send_fpacket<0x006c, 3>(s2, fixed_6c); } - else if (max_connect_user == 0 - || count_users() < max_connect_user) + else if (char_conf.max_connect_user == 0 + || count_users() < char_conf.max_connect_user) { sd->email = stringish(fixed.email); if (!e_mail_check(sd->email)) @@ -1812,7 +1727,7 @@ void parse_frommap(Session *ms) server[id].users = head.users; assert (head.users == repeat.size()); - if (anti_freeze_enable) + if (char_conf.anti_freeze_enable) server_freezeflag[id] = 5; // Map anti-freeze system. Counter. 5 ok, 4...0 freezed // remove all previously online players of the server for (Session *& oci : online_chars) @@ -2234,7 +2149,7 @@ int search_mapserver(XString map) static int lan_ip_check(IP4Address addr) { - bool lancheck = lan_subnet.covers(addr); + bool lancheck = char_lan_conf.lan_subnet.covers(addr); PRINTF("LAN test (result): %s.\n"_fmt, (lancheck) ? SGR_BOLD SGR_CYAN "LAN source" SGR_RESET ""_s : SGR_BOLD SGR_GREEN "WAN source" SGR_RESET ""_s); @@ -2299,7 +2214,7 @@ void handle_x0066(Session *s, struct char_session_data *sd, uint8_t rfifob_2, IP sd->account_id, ck->char_num, ip); PRINTF("--Send IP of map-server. "_fmt); if (lan_ip_check(ip)) - fixed_71.ip = lan_map_ip; + fixed_71.ip = char_lan_conf.lan_map_ip; else fixed_71.ip = server[i].ip; fixed_71.port = server[i].port; @@ -2403,8 +2318,8 @@ void parse_char(Session *s) && afi.delflag == 2) { afi.delflag = 1; - if (max_connect_user == 0 - || count_users() < max_connect_user) + if (char_conf.max_connect_user == 0 + || count_users() < char_conf.max_connect_user) { { // there is always a login server @@ -2615,8 +2530,8 @@ void parse_char(Session *s) } AccountName userid_ = fixed.account_name; AccountPass passwd_ = fixed.account_pass; - if (i == MAX_MAP_SERVERS || userid_ != userid - || passwd_ != passwd) + if (i == MAX_MAP_SERVERS || userid_ != char_conf.userid + || passwd_ != char_conf.passwd) { fixed_f9.code = 3; send_fpacket<0x2af9, 3>(s, fixed_f9); @@ -2626,7 +2541,7 @@ void parse_char(Session *s) fixed_f9.code = 0; s->set_parsers(SessionParsers{.func_parse= parse_frommap, .func_delete= delete_frommap}); server_session[i] = s; - if (anti_freeze_enable) + if (char_conf.anti_freeze_enable) server_freezeflag[i] = 5; // Map anti-freeze system. Counter. 5 ok, 4...0 freezed // ignore fixed.unknown server[i].ip = fixed.ip; @@ -2714,19 +2629,19 @@ void check_connect_login_server(TimerData *, tick_t) if (!login_session) { PRINTF("Attempt to connect to login-server...\n"_fmt); - login_session = make_connection(login_ip, login_port, + login_session = make_connection(char_conf.login_ip, char_conf.login_port, SessionParsers{.func_parse= parse_tologin, .func_delete= delete_tologin}); if (!login_session) return; realloc_fifo(login_session, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); Packet_Fixed<0x2710> fixed_10; - fixed_10.account_name = userid; - fixed_10.account_pass = passwd; + fixed_10.account_name = char_conf.userid; + fixed_10.account_pass = char_conf.passwd; fixed_10.unknown = 0; - fixed_10.ip = char_ip; - fixed_10.port = char_port; - fixed_10.server_name = server_name; + fixed_10.ip = char_conf.char_ip; + fixed_10.port = char_conf.char_port; + fixed_10.server_name = char_conf.server_name; fixed_10.unknown2 = 0; fixed_10.maintenance = 0; fixed_10.is_new = 0; @@ -2734,61 +2649,13 @@ void check_connect_login_server(TimerData *, tick_t) } } -//------------------------------------------- -// Reading Lan Support configuration by [Yor] -//------------------------------------------- -static -bool char_lan_config(io::Spanned w1, io::Spanned w2) -{ - struct hostent *h = nullptr; - - { - if (w1.data == "lan_map_ip"_s) - { - // Read map-server Lan IP Address - h = gethostbyname(w2.data.c_str()); - if (h != nullptr) - { - lan_map_ip = IP4Address({ - static_cast(h->h_addr[0]), - static_cast(h->h_addr[1]), - static_cast(h->h_addr[2]), - static_cast(h->h_addr[3]), - }); - } - else - { - PRINTF("Bad IP value: %s\n"_fmt, w2.data); - return false; - } - PRINTF("LAN IP of map-server: %s.\n"_fmt, lan_map_ip); - } - else if (w1.data == "subnet"_s /*backward compatibility*/ - || w1.data == "lan_subnet"_s) - { - if (!extract(w2.data, &lan_subnet)) - { - PRINTF("Bad IP mask: %s\n"_fmt, w2.data); - return false; - } - PRINTF("Sub-network of the map-server: %s.\n"_fmt, - lan_subnet); - } - else - { - 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: "_fmt); - if (!lan_ip_check(lan_map_ip)) + if (!lan_ip_check(char_lan_conf.lan_map_ip)) { PRINTF(SGR_BOLD SGR_RED "***ERROR: LAN IP of the map-server doesn't belong to the specified Sub-network." SGR_RESET "\n"_fmt); return false; @@ -2799,144 +2666,46 @@ bool lan_check() } static -bool char_config(io::Spanned w1, io::Spanned w2) +bool char_config(io::Spanned key, io::Spanned value) +{ + return parse_char_conf(char_conf, key, value); +} + +static +bool char_lan_config(io::Spanned key, io::Spanned value) +{ + return parse_char_lan_conf(char_lan_conf, key, value); +} + +static +bool inter_config(io::Spanned key, io::Spanned value) { - struct hostent *h = nullptr; + return parse_inter_conf(inter_conf, key, value); +} +static +bool char_confs(io::Spanned key, io::Spanned value) +{ + if (key.data == "char_conf"_s) { - if (w1.data == "userid"_s) - userid = stringish(w2.data); - else if (w1.data == "passwd"_s) - passwd = stringish(w2.data); - else if (w1.data == "server_name"_s) - { - server_name = stringish(w2.data); - PRINTF("%s server has been intialized\n"_fmt, w2.data); - } - else if (w1.data == "login_ip"_s) - { - h = gethostbyname(w2.data.c_str()); - if (h != nullptr) - { - login_ip = IP4Address({ - static_cast(h->h_addr[0]), - static_cast(h->h_addr[1]), - static_cast(h->h_addr[2]), - static_cast(h->h_addr[3]), - }); - PRINTF("Login server IP address : %s -> %s\n"_fmt, - w2.data, login_ip); - } - else - { - PRINTF("Bad IP value: %s\n"_fmt, w2.data); - return false; - } - } - else if (w1.data == "login_port"_s) - { - login_port = atoi(w2.data.c_str()); - } - else if (w1.data == "char_ip"_s) - { - h = gethostbyname(w2.data.c_str()); - if (h != nullptr) - { - char_ip = IP4Address({ - static_cast(h->h_addr[0]), - static_cast(h->h_addr[1]), - static_cast(h->h_addr[2]), - static_cast(h->h_addr[3]), - }); - PRINTF("Character server IP address : %s -> %s\n"_fmt, - w2.data, char_ip); - } - else - { - PRINTF("Bad IP value: %s\n"_fmt, w2.data); - return false; - } - } - else if (w1.data == "char_port"_s) - { - char_port = atoi(w2.data.c_str()); - } - else if (w1.data == "char_txt"_s) - { - char_txt = w2.data; - } - else if (w1.data == "max_connect_user"_s) - { - max_connect_user = atoi(w2.data.c_str()); - if (max_connect_user < 0) - max_connect_user = 0; // unlimited online players - } - else if (w1.data == "autosave_time"_s) - { - autosave_time = std::chrono::seconds(atoi(w2.data.c_str())); - if (autosave_time <= std::chrono::seconds::zero()) - autosave_time = DEFAULT_AUTOSAVE_INTERVAL; - } - else if (w1.data == "start_point"_s) - { - extract(w2.data, &start_point); - } - else if (w1.data == "unknown_char_name"_s) - { - unknown_char_name = stringish(w2.data); - } - else if (w1.data == "char_log_filename"_s) - { - char_log_filename = w2.data; - } - else if (w1.data == "char_name_letters"_s) - { - if (!w2.data) - char_name_letters.reset(); - else - for (uint8_t c : w2.data) - char_name_letters[c] = true; - } - else if (w1.data == "online_txt_filename"_s) - { - online_txt_filename = w2.data; - } - else if (w1.data == "online_html_filename"_s) - { - online_html_filename = w2.data; - } - else if (w1.data == "online_gm_display_min_level"_s) - { - // minimum GM level to display 'GM' when we want to display it - return extract(w2.data, &online_gm_display_min_level); - } - else if (w1.data == "online_refresh_html"_s) - { - online_refresh_html = atoi(w2.data.c_str()); - if (online_refresh_html < 1) - online_refresh_html = 1; - } - else if (w1.data == "anti_freeze_enable"_s) - { - anti_freeze_enable = config_switch(w2.data); - } - else if (w1.data == "anti_freeze_interval"_s) - { - anti_freeze_interval = std::max( - std::chrono::seconds(atoi(w2.data.c_str())), - 5_s); - } - else - { - return false; - } + return load_config_file(value.data, char_config); } - - return true; + if (key.data == "char_lan_conf"_s) + { + return load_config_file(value.data, char_lan_config); + } + if (key.data == "inter_conf"_s) + { + return load_config_file(value.data, inter_config); + } + key.span.error("Unknown meta-key for char server"_s); + return false; } +} // namespace char_ void term_func(void) { + using namespace tmwa::char_; // write online players files with no player std::fill(online_chars.begin(), online_chars.end(), nullptr); create_online_files(); @@ -2954,24 +2723,9 @@ void term_func(void) CHAR_LOG("----End of char-server (normal end with closing of all files).\n"_fmt); } -static -bool char_confs(io::Spanned key, io::Spanned value) -{ - bool ok; - ok = char_config(key, value); - if (!ok) - return ok; - ok = char_lan_config(key, value); - if (!ok) - return ok; - ok = inter_config(key, value); - if (!ok) - return ok; - return ok; -} - int do_init(Slice argv) { + using namespace tmwa::char_; ZString argv0 = argv.pop_front(); bool loaded_config_yet = false; @@ -3000,12 +2754,12 @@ int do_init(Slice argv) else { loaded_config_yet = true; - runflag &= load_config_file(argvi, char_confs); + runflag &= load_config_file(argvi, char_::char_confs); } } if (!loaded_config_yet) - runflag &= load_config_file("conf/tmwa-char.conf"_s, char_confs); + runflag &= load_config_file("conf/tmwa-char.conf"_s, char_::char_confs); // a newline in the log... CHAR_LOG(""_fmt); @@ -3019,7 +2773,7 @@ int do_init(Slice argv) update_online = TimeT::now(); create_online_files(); // update online players files at start of the server - char_session = make_listen_port(char_port, SessionParsers{parse_char, delete_char}); + char_session = make_listen_port(char_conf.char_port, SessionParsers{parse_char, delete_char}); Timer(gettick() + 1_s, check_connect_login_server, @@ -3029,25 +2783,26 @@ int do_init(Slice argv) send_users_tologin, 5_s ).detach(); - Timer(gettick() + autosave_time, + Timer(gettick() + char_conf.autosave_time, mmo_char_sync_timer, - autosave_time + char_conf.autosave_time ).detach(); - if (anti_freeze_enable > 0) + if (char_conf.anti_freeze_enable > 0) { Timer(gettick() + 1_s, map_anti_freeze_system, - anti_freeze_interval + char_conf.anti_freeze_interval ).detach(); } CHAR_LOG("The char-server is ready (Server is listening on the port %d).\n"_fmt, - char_port); + char_conf.char_port); PRINTF("The char-server is " SGR_BOLD SGR_GREEN "ready" SGR_RESET " (Server is listening on the port %d).\n\n"_fmt, - char_port); + char_conf.char_port); return 0; } +// namespace char_ ends before term_func and do_init } // namespace tmwa -- cgit v1.2.3-60-g2f50