diff options
-rw-r--r-- | src/char/char.cpp | 437 | ||||
-rw-r--r-- | src/char/char.hpp | 20 | ||||
-rw-r--r-- | src/char/consts.hpp | 31 | ||||
-rw-r--r-- | src/char/fwd.hpp | 14 | ||||
-rw-r--r-- | src/char/globals.cpp | 68 | ||||
-rw-r--r-- | src/char/globals.hpp | 59 | ||||
-rw-r--r-- | src/char/int_party.cpp | 25 | ||||
-rw-r--r-- | src/char/int_party.hpp | 5 | ||||
-rw-r--r-- | src/char/int_storage.cpp | 26 | ||||
-rw-r--r-- | src/char/int_storage.hpp | 5 | ||||
-rw-r--r-- | src/char/inter.cpp | 55 | ||||
-rw-r--r-- | src/char/inter.hpp | 20 | ||||
-rw-r--r-- | src/high/extract_mmo.cpp | 5 | ||||
-rw-r--r-- | src/high/extract_mmo.hpp | 1 |
14 files changed, 350 insertions, 421 deletions
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<struct mmo_map_server, MAX_MAP_SERVERS> server; -static -Array<Session *, MAX_MAP_SERVERS> server_session; -static -Array<int, MAX_MAP_SERVERS> 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<CharName>("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<CharName>("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<char_session_data *>(sd); + really_delete1 static_cast<char_::char_session_data *>(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<AuthFifoEntry, 256> auth_fifo; -static -auto auth_fifo_iter = auth_fifo.begin(); - -static -CharId char_id_count = wrap<CharId>(150000); -static -std::vector<CharPair> 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_Account> 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<Session *> 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<Session *>(std::declval<Array<Session *, MAX_MAP_SERVERS> *>())) { @@ -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, "<HTML>\n"_fmt); - FPRINTF(fp2, " <META http-equiv=\"Refresh\" content=\"%d\">\n"_fmt, online_refresh_html); // update on client explorer every x seconds + FPRINTF(fp2, " <META http-equiv=\"Refresh\" content=\"%d\">\n"_fmt, char_conf.online_refresh_html); // update on client explorer every x seconds FPRINTF(fp2, " <HEAD>\n"_fmt); FPRINTF(fp2, " <TITLE>Online Players on %s</TITLE>\n"_fmt, - server_name); + char_conf.server_name); FPRINTF(fp2, " </HEAD>\n"_fmt); FPRINTF(fp2, " <BODY>\n"_fmt); FPRINTF(fp2, " <H3>Online Players on %s (%s):</H3>\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, " <td>"_fmt); - if (gml.satisfies(online_gm_display_min_level)) + if (gml.satisfies(char_conf.online_gm_display_min_level)) FPRINTF(fp2, "<b>"_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, "</b> (GM)"_fmt); FPRINTF(fp2, "</td>\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<AccountEmail>(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<XString> w1, io::Spanned<ZString> 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<uint8_t>(h->h_addr[0]), - static_cast<uint8_t>(h->h_addr[1]), - static_cast<uint8_t>(h->h_addr[2]), - static_cast<uint8_t>(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<XString> w1, io::Spanned<ZString> w2) +bool char_config(io::Spanned<XString> key, io::Spanned<ZString> value) +{ + return parse_char_conf(char_conf, key, value); +} + +static +bool char_lan_config(io::Spanned<XString> key, io::Spanned<ZString> value) +{ + return parse_char_lan_conf(char_lan_conf, key, value); +} + +static +bool inter_config(io::Spanned<XString> key, io::Spanned<ZString> value) { - struct hostent *h = nullptr; + return parse_inter_conf(inter_conf, key, value); +} +static +bool char_confs(io::Spanned<XString> key, io::Spanned<ZString> value) +{ + if (key.data == "char_conf"_s) { - if (w1.data == "userid"_s) - userid = stringish<AccountName>(w2.data); - else if (w1.data == "passwd"_s) - passwd = stringish<AccountPass>(w2.data); - else if (w1.data == "server_name"_s) - { - server_name = stringish<ServerName>(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<uint8_t>(h->h_addr[0]), - static_cast<uint8_t>(h->h_addr[1]), - static_cast<uint8_t>(h->h_addr[2]), - static_cast<uint8_t>(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<uint8_t>(h->h_addr[0]), - static_cast<uint8_t>(h->h_addr[1]), - static_cast<uint8_t>(h->h_addr[2]), - static_cast<uint8_t>(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<CharName>(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<XString> key, io::Spanned<ZString> 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<ZString> argv) { + using namespace tmwa::char_; ZString argv0 = argv.pop_front(); bool loaded_config_yet = false; @@ -3000,12 +2754,12 @@ int do_init(Slice<ZString> 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<ZString> 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<ZString> 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 diff --git a/src/char/char.hpp b/src/char/char.hpp index bcbdeb3..4f55c04 100644 --- a/src/char/char.hpp +++ b/src/char/char.hpp @@ -22,19 +22,36 @@ #include "fwd.hpp" +#include "../ints/udl.hpp" + #include "../generic/array.hpp" #include "../net/ip.hpp" #include "../high/mmo.hpp" +#include "consts.hpp" + namespace tmwa { -constexpr int MAX_MAP_SERVERS = 30; +namespace char_ +{ constexpr std::chrono::seconds DEFAULT_AUTOSAVE_INTERVAL = 5_min; +constexpr +GmLevel default_gm_level = GmLevel::from(0_u32); +struct AuthFifoEntry +{ + AccountId account_id; + CharId char_id; + int login_id1, login_id2; + IP4Address ip; + int delflag; + SEX sex; + unsigned short packet_tmw_version; +}; struct mmo_map_server { @@ -54,4 +71,5 @@ void char_log(XString line); #define CHAR_LOG(fmt, ...) \ char_log(STRPRINTF(fmt, ## __VA_ARGS__)) +} // namespace char_ } // namespace tmwa diff --git a/src/char/consts.hpp b/src/char/consts.hpp new file mode 100644 index 0000000..e3b6c57 --- /dev/null +++ b/src/char/consts.hpp @@ -0,0 +1,31 @@ +#pragma once +// consts.hpp - Constants for tmwa-char. +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// 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 <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + + +namespace tmwa +{ +namespace char_ +{ +constexpr +int MAX_MAP_SERVERS = 30; +} // namespace char_ +} // namespace tmwa diff --git a/src/char/fwd.hpp b/src/char/fwd.hpp index ff2bf22..8086083 100644 --- a/src/char/fwd.hpp +++ b/src/char/fwd.hpp @@ -22,6 +22,7 @@ #include "../ints/fwd.hpp" // rank 1 #include "../strings/fwd.hpp" // rank 1 +#include "../compat/fwd.hpp" // rank 2 #include "../generic/fwd.hpp" // rank 3 #include "../io/fwd.hpp" // rank 4 #include "../net/fwd.hpp" // rank 5 @@ -34,5 +35,16 @@ namespace tmwa { -// meh, add more when I feel like it +namespace char_ +{ + struct CharConf; + struct CharLanConf; + struct InterConf; + + struct AuthFifoEntry; + struct mmo_map_server; + + struct accreg; + // meh, add more when I feel like it +} // namespace char_ } // namespace tmwa diff --git a/src/char/globals.cpp b/src/char/globals.cpp new file mode 100644 index 0000000..6733ad5 --- /dev/null +++ b/src/char/globals.cpp @@ -0,0 +1,68 @@ +#include "globals.hpp" +// globals.cpp - Evil global variables for tmwa-char. +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// 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 <http://www.gnu.org/licenses/>. + +#include "../compat/time_t.hpp" + +#include "../generic/db.hpp" + +#include "../proto2/net-Storage.hpp" + +#include "char.hpp" +#include "char_conf.hpp" +#include "char_lan_conf.hpp" +#include "inter.hpp" +#include "inter_conf.hpp" + +#include "../poison.hpp" + + +namespace tmwa +{ + namespace char_ + { + CharConf char_conf; + CharLanConf char_lan_conf; + InterConf inter_conf; + Array<mmo_map_server, MAX_MAP_SERVERS> server; + Array<Session *, MAX_MAP_SERVERS> server_session; + // Map-server anti-freeze system. Counter. 5 ok, 4...0 freezed + Array<int, MAX_MAP_SERVERS> server_freezeflag; + Session *login_session, *char_session; + const CharName WISP_SERVER_NAME = stringish<CharName>("Server"_s); + std::array<AuthFifoEntry, 256> auth_fifo; + decltype(auth_fifo)::iterator auth_fifo_iter = auth_fifo.begin(); + CharId char_id_count = wrap<CharId>(150000); + std::vector<CharPair> char_keys; + std::vector<GM_Account> gm_accounts; + // same size of char_keys, and id value of current server (or -1) + std::vector<Session *> online_chars; + // to update online files when we receiving information from a server (not less than 8 seconds) + TimeT update_online; + // For forked DB writes + pid_t pid = 0; + + Map<AccountId, accreg> accreg_db; + + Map<PartyId, PartyMost> party_db; + PartyId party_newid = wrap<PartyId>(100_u32); + + Map<AccountId, Storage> storage_db; + } // namespace char_ +} // namespace tmwa diff --git a/src/char/globals.hpp b/src/char/globals.hpp new file mode 100644 index 0000000..2df3f21 --- /dev/null +++ b/src/char/globals.hpp @@ -0,0 +1,59 @@ +#pragma once +// globals.hpp - Evil global variables for tmwa-char. +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// 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 <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + +#include <sys/types.h> + +#include <array> +#include <vector> + +#include "consts.hpp" + + +namespace tmwa +{ + namespace char_ + { + extern CharConf char_conf; + extern CharLanConf char_lan_conf; + extern InterConf inter_conf; + extern Array<mmo_map_server, MAX_MAP_SERVERS> server; + extern Array<Session *, MAX_MAP_SERVERS> server_session; + extern Array<int, MAX_MAP_SERVERS> server_freezeflag; + extern Session *login_session, *char_session; + extern const CharName WISP_SERVER_NAME; + extern std::array<AuthFifoEntry, 256> auth_fifo; + extern AuthFifoEntry *auth_fifo_iter; + extern CharId char_id_count; + extern std::vector<CharPair> char_keys; + extern std::vector<GM_Account> gm_accounts; + extern std::vector<Session *> online_chars; + extern TimeT update_online; + extern pid_t pid; + + extern Map<AccountId, accreg> accreg_db; + + extern Map<PartyId, PartyMost> party_db; + extern PartyId party_newid; + + extern Map<AccountId, Storage> storage_db; + } // namespace char_ +} // namespace tmwa diff --git a/src/char/int_party.cpp b/src/char/int_party.cpp index a16bc20..5ee65ad 100644 --- a/src/char/int_party.cpp +++ b/src/char/int_party.cpp @@ -44,20 +44,17 @@ #include "../wire/packets.hpp" #include "char.hpp" +#include "globals.hpp" #include "inter.hpp" +#include "inter_conf.hpp" #include "../poison.hpp" namespace tmwa { -AString party_txt = "save/party.txt"_s; - -static -Map<PartyId, PartyMost> party_db; -static -PartyId party_newid = wrap<PartyId>(100_u32); - +namespace char_ +{ static void mapif_party_broken(PartyId party_id, int flag); static @@ -91,6 +88,7 @@ AString inter_party_tostr(PartyPair p) return AString(str); } +} // namespace char_ static bool impl_extract(XString str, PartyPair *pp) @@ -131,6 +129,8 @@ bool impl_extract(XString str, PartyPair *pp) return true; } +namespace char_ +{ static void party_check_deleted_init(PartyPair p) { @@ -155,7 +155,7 @@ void party_check_deleted_init(PartyPair p) // パーティデータのロード void inter_party_init(void) { - io::ReadFile in(party_txt); + io::ReadFile in(inter_conf.party_txt); if (!in.is_open()) return; @@ -186,7 +186,7 @@ void inter_party_init(void) } else { - PRINTF("int_party: broken data [%s] line %d\n"_fmt, party_txt, + PRINTF("int_party: broken data [%s] line %d\n"_fmt, inter_conf.party_txt, c + 1); } c++; @@ -204,11 +204,11 @@ void inter_party_save_sub(PartyPair data, io::WriteFile& fp) // パーティーデータのセーブ int inter_party_save(void) { - io::WriteLock fp(party_txt); + io::WriteLock fp(inter_conf.party_txt); if (!fp.is_open()) { PRINTF("int_party: cant write [%s] !!! data is lost !!!\n"_fmt, - party_txt); + inter_conf.party_txt); return 1; } for (auto& pair : party_db) @@ -261,7 +261,7 @@ int party_check_exp_share(PartyPair p) } } - return (maxlv == 0 || maxlv - minlv <= party_share_level); + return (maxlv == 0 || maxlv - minlv <= inter_conf.party_share_level); } // パーティが空かどうかチェック @@ -822,4 +822,5 @@ void inter_party_leave(PartyId party_id, AccountId account_id) { mapif_parse_PartyLeave(nullptr, party_id, account_id); } +} // namespace char_ } // namespace tmwa diff --git a/src/char/int_party.hpp b/src/char/int_party.hpp index 79b3bd4..d66afbf 100644 --- a/src/char/int_party.hpp +++ b/src/char/int_party.hpp @@ -25,12 +25,13 @@ namespace tmwa { +namespace char_ +{ void inter_party_init(void); int inter_party_save(void); RecvResult inter_party_parse_frommap(Session *ms, uint16_t); void inter_party_leave(PartyId party_id, AccountId account_id); - -extern AString party_txt; +} // namespace char_ } // namespace tmwa diff --git a/src/char/int_storage.cpp b/src/char/int_storage.cpp index 0c76678..32af231 100644 --- a/src/char/int_storage.cpp +++ b/src/char/int_storage.cpp @@ -42,18 +42,16 @@ #include "../wire/packets.hpp" +#include "globals.hpp" +#include "inter_conf.hpp" + #include "../poison.hpp" namespace tmwa { -// ファイル名のデフォルト -// inter_config_read()で再設定される -AString storage_txt = "save/storage.txt"_s; - -static -Map<AccountId, Storage> storage_db; - +namespace char_ +{ // 倉庫データを文字列に変換 static AString storage_tostr(Storage *p) @@ -92,6 +90,7 @@ AString storage_tostr(Storage *p) return AString(); return AString(str); } +} // namespace char_ // 文字列を倉庫データに変換 static @@ -118,6 +117,8 @@ bool impl_extract(XString str, Storage *p) return true; } +namespace char_ +{ // アカウントから倉庫データインデックスを得る(新規倉庫追加可能) Borrowed<Storage> account2storage(AccountId account_id) { @@ -132,10 +133,10 @@ void inter_storage_init(void) { int c = 0; - io::ReadFile in(storage_txt); + io::ReadFile in(inter_conf.storage_txt); if (!in.is_open()) { - PRINTF("cant't read : %s\n"_fmt, storage_txt); + PRINTF("cant't read : %s\n"_fmt, inter_conf.storage_txt); return; } @@ -150,7 +151,7 @@ void inter_storage_init(void) else { PRINTF("int_storage: broken data [%s] line %d\n"_fmt, - storage_txt, c); + inter_conf.storage_txt, c); } c++; } @@ -168,12 +169,12 @@ void inter_storage_save_sub(Storage *data, io::WriteFile& fp) // 倉庫データを書き込む int inter_storage_save(void) { - io::WriteLock fp(storage_txt); + io::WriteLock fp(inter_conf.storage_txt); if (!fp.is_open()) { PRINTF("int_storage: cant write [%s] !!! data is lost !!!\n"_fmt, - storage_txt); + inter_conf.storage_txt); return 1; } for (auto& pair : storage_db) @@ -270,4 +271,5 @@ RecvResult inter_storage_parse_frommap(Session *ms, uint16_t packet_id) } return rv; } +} // namespace char_ } // namespace tmwa diff --git a/src/char/int_storage.hpp b/src/char/int_storage.hpp index c03ebff..3741061 100644 --- a/src/char/int_storage.hpp +++ b/src/char/int_storage.hpp @@ -25,12 +25,13 @@ namespace tmwa { +namespace char_ +{ void inter_storage_init(void); int inter_storage_save(void); void inter_storage_delete(AccountId account_id); Borrowed<Storage> account2storage(AccountId account_id); RecvResult inter_storage_parse_frommap(Session *ms, uint16_t); - -extern AString storage_txt; +} // namespace char_ } // namespace tmwa diff --git a/src/char/inter.cpp b/src/char/inter.cpp index df05434..3bf3bfc 100644 --- a/src/char/inter.cpp +++ b/src/char/inter.cpp @@ -50,6 +50,8 @@ #include "../wire/packets.hpp" #include "char.hpp" +#include "globals.hpp" +#include "inter_conf.hpp" #include "int_party.hpp" #include "int_storage.hpp" @@ -58,20 +60,8 @@ namespace tmwa { -static -AString accreg_txt = "save/accreg.txt"_s; - -struct accreg +namespace char_ { - AccountId account_id; - int reg_num; - Array<GlobalReg, ACCOUNT_REG_NUM> reg; -}; -static -Map<AccountId, struct accreg> accreg_db; - -int party_share_level = 10; - //-------------------------------------------------------- // アカウント変数を文字列へ変換 @@ -112,7 +102,7 @@ void inter_accreg_init(void) { int c = 0; - io::ReadFile in(accreg_txt); + io::ReadFile in(inter_conf.accreg_txt); if (!in.is_open()) return; AString line; @@ -125,7 +115,7 @@ void inter_accreg_init(void) } else { - PRINTF("inter: accreg: broken data [%s] line %d\n"_fmt, accreg_txt, + PRINTF("inter: accreg: broken data [%s] line %d\n"_fmt, inter_conf.accreg_txt, c); } c++; @@ -147,11 +137,11 @@ void inter_accreg_save_sub(struct accreg *reg, io::WriteFile& fp) static int inter_accreg_save(void) { - io::WriteLock fp(accreg_txt); + io::WriteLock fp(inter_conf.accreg_txt); if (!fp.is_open()) { PRINTF("int_accreg: cant write [%s] !!! data is lost !!!\n"_fmt, - accreg_txt); + inter_conf.accreg_txt); return 1; } for (auto& pair : accreg_db) @@ -160,36 +150,6 @@ int inter_accreg_save(void) return 0; } -bool inter_config(io::Spanned<XString> w1, io::Spanned<ZString> w2) -{ - { - if (w1.data == "storage_txt"_s) - { - storage_txt = w2.data; - } - else if (w1.data == "party_txt"_s) - { - party_txt = w2.data; - } - else if (w1.data == "accreg_txt"_s) - { - accreg_txt = w2.data; - } - else if (w1.data == "party_share_level"_s) - { - party_share_level = atoi(w2.data.c_str()); - if (party_share_level < 0) - party_share_level = 0; - } - else - { - return false; - } - } - - return true; -} - // セーブ void inter_save(void) { @@ -489,4 +449,5 @@ RecvResult inter_parse_frommap(Session *ms, uint16_t packet_id) return rv; } +} // namespace char_ } // namespace tmwa diff --git a/src/char/inter.hpp b/src/char/inter.hpp index 741bc8d..c641254 100644 --- a/src/char/inter.hpp +++ b/src/char/inter.hpp @@ -22,13 +22,27 @@ #include "fwd.hpp" +#include "../generic/array.hpp" + +#include "../mmo/consts.hpp" +#include "../mmo/ids.hpp" + +#include "../proto2/net-GlobalReg.hpp" + namespace tmwa { -bool inter_config(io::Spanned<XString> key, io::Spanned<ZString> value); +namespace char_ +{ +struct accreg +{ + AccountId account_id; + int reg_num; + Array<GlobalReg, ACCOUNT_REG_NUM> reg; +}; + void inter_init2(); void inter_save(void); RecvResult inter_parse_frommap(Session *ms, uint16_t packet_id); - -extern int party_share_level; +} // namespace char_ } // namespace tmwa diff --git a/src/high/extract_mmo.cpp b/src/high/extract_mmo.cpp index dae6a3b..ab4290d 100644 --- a/src/high/extract_mmo.cpp +++ b/src/high/extract_mmo.cpp @@ -92,4 +92,9 @@ bool impl_extract(XString str, NpcEvent *ev) XString mid; return extract(str, record<':'>(&ev->npc, &mid, &ev->label)) && !mid; } + +bool impl_extract(XString str, Point *p) +{ + return extract(str, record<','>(&p->map_, &p->x, &p->y)); +} } // namespace tmwa diff --git a/src/high/extract_mmo.hpp b/src/high/extract_mmo.hpp index 5fcd06f..f374658 100644 --- a/src/high/extract_mmo.hpp +++ b/src/high/extract_mmo.hpp @@ -29,4 +29,5 @@ bool impl_extract(XString str, MapName *m); bool impl_extract(XString str, CharName *out); bool impl_extract(XString str, NpcEvent *ev); +bool impl_extract(XString str, Point *p); } // namespace tmwa |