From 3b98f3439e33b15bba2036c402f9925340fdb2b9 Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Sat, 29 Jun 2013 23:23:43 -0700 Subject: Poison std::string and use the various string classes --- src/char/char.cpp | 430 +++++++++++++++++++---------------------------- src/char/char.hpp | 8 +- src/char/int_party.cpp | 182 ++++++++++---------- src/char/int_party.hpp | 4 +- src/char/int_storage.cpp | 26 +-- src/char/int_storage.hpp | 4 +- src/char/inter.cpp | 99 ++++++----- src/char/inter.hpp | 8 +- 8 files changed, 338 insertions(+), 423 deletions(-) (limited to 'src/char') diff --git a/src/char/char.cpp b/src/char/char.cpp index d7e7a41..6108dca 100644 --- a/src/char/char.cpp +++ b/src/char/char.cpp @@ -12,12 +12,15 @@ #include #include +#include #include #include "../common/core.hpp" #include "../common/cxxstdio.hpp" #include "../common/db.hpp" #include "../common/extract.hpp" +#include "../common/human_time_diff.hpp" +#include "../common/io.hpp" #include "../common/lock.hpp" #include "../common/socket.hpp" #include "../common/timer.hpp" @@ -48,21 +51,21 @@ std::chrono::milliseconds DEFAULT_AUTOSAVE_INTERVAL = static int login_fd, char_fd; static -char userid[24]; +AccountName userid; static -char passwd[24]; +AccountPass passwd; static -char server_name[20]; +ServerName server_name; static -char wisp_server_name[24] = "Server"; +CharName wisp_server_name = stringish("Server"); static -char login_ip_str[16]; +IP_String login_ip_str; static int login_ip; static int login_port = 6900; static -char char_ip_str[16]; +IP_String char_ip_str; static int char_ip; static @@ -72,31 +75,29 @@ int char_maintenance; static int char_new; static -char char_txt[1024]; +FString char_txt; static -char unknown_char_name[24] = "Unknown"; +CharName unknown_char_name = stringish("Unknown"); static -char char_log_filename[1024] = "log/char.log"; +FString char_log_filename = "log/char.log"; //Added for lan support static -char lan_map_ip[128]; +IP_String lan_map_ip; static uint8_t subneti[4]; static uint8_t subnetmaski[4]; static -int name_ignoring_case = 0; // Allow or not identical name for characters but with a different case by [Yor] -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 -char char_name_letters[1024] = ""; // list of letters/symbols authorised (or not) in a character name. by [Yor] +std::bitset<256> char_name_letters; // list of letters/symbols authorised (or not) in a character name. by [Yor] struct char_session_data : SessionData { int account_id, login_id1, login_id2, sex; unsigned short packet_tmw_version; - char email[40]; // e-mail (default: a@a.com) by [Yor] - TimeT connect_until_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited) + AccountEmail email; + TimeT connect_until_time; }; void SessionDeleter::operator()(SessionData *sd) @@ -140,16 +141,16 @@ int start_armor = 1202; // Initial position (it's possible to set it in conf file) static -struct point start_point = { "new_1-1.gat", 53, 111 }; +struct point start_point = { {"001-1.gat"}, 273, 354 }; static std::vector gm_accounts; // online players by [Yor] static -char online_txt_filename[1024] = "online.txt"; +FString online_txt_filename = "online.txt"; static -char online_html_filename[1024] = "online.html"; +FString online_html_filename = "online.html"; static int online_sorting_option = 0; // sorting option to display online players in online files static @@ -168,13 +169,13 @@ pid_t pid = 0; // For forked DB writes //------------------------------ // Writing function of logs file //------------------------------ -void char_log(const_string line) +void char_log(XString line) { - FILE *logfp = fopen_(char_log_filename, "a"); + FILE *logfp = fopen(char_log_filename.c_str(), "a"); if (!logfp) return; log_with_timestamp(logfp, line); - fclose_(logfp); + fclose(logfp); } //---------------------------------------------------------------------- @@ -198,26 +199,16 @@ int isGM(int account_id) // and returns index if only 1 character is found // and similar to the searched name. //---------------------------------------------- -const mmo_charstatus *search_character(const char *character_name) +const mmo_charstatus *search_character(CharName character_name) { - int quantity = 0; - const mmo_charstatus *index = nullptr; for (const mmo_charstatus& cd : char_data) { - // Without case sensitive check (increase the number of similar character names found) - if (strcasecmp(cd.name, character_name) == 0) { // Strict comparison (if found, we finish the function immediatly with correct value) - if (strcmp(cd.name, character_name) == 0) + if (cd.name == character_name) return &cd; - quantity++; - index = &cd; } } - // Here, the exact character name is not found - // We return the found index of a similar account ONLY if there is 1 similar character - if (quantity == 1) - return index; // Exact character name is not found and 0 or more than 1 similar characters have been found ==> we say not found return nullptr; @@ -226,18 +217,16 @@ const mmo_charstatus *search_character(const char *character_name) //------------------------------------------------- // Function to create the character line (for save) //------------------------------------------------- -__inline__ static -std::string mmo_char_tostr(struct mmo_charstatus *p) +static +FString mmo_char_tostr(struct mmo_charstatus *p) { // 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_[0] == '\0') + if (!p->last_point.map_) { - strzcpy(p->last_point.map_, "001-1.gat", 16); - p->last_point.x = 273; - p->last_point.y = 354; + p->last_point = start_point; } - std::string str_p; + MString str_p; str_p += STRPRINTF( "%d\t" "%d,%d\t" @@ -329,11 +318,11 @@ std::string mmo_char_tostr(struct mmo_charstatus *p) p->global_reg[i].value); str_p += '\t'; - return str_p; + return FString(str_p); } static -bool extract(const_string str, struct point *p) +bool extract(XString str, struct point *p) { return extract(str, record<','>(&p->map_, &p->x, &p->y)); } @@ -346,7 +335,7 @@ struct skill_loader }; static -bool extract(const_string str, struct skill_loader *s) +bool extract(XString str, struct skill_loader *s) { uint32_t flags_and_level; if (!extract(str, @@ -361,7 +350,7 @@ bool extract(const_string str, struct skill_loader *s) // Function to set the character from the line (at read of characters file) //------------------------------------------------------------------------- static -bool extract(const_string str, struct mmo_charstatus *p) +bool extract(XString str, struct mmo_charstatus *p) { // initilialise character *p = mmo_charstatus{}; @@ -397,14 +386,14 @@ bool extract(const_string str, struct mmo_charstatus *p) vrec<' '>(&vars)))) return false; - if (strcmp(wisp_server_name, p->name) == 0) + if (wisp_server_name == p->name) return false; for (const mmo_charstatus& cd : char_data) { if (cd.char_id == p->char_id) return false; - if (strcmp(cd.name, p->name) == 0) + if (cd.name == p->name) return false; } @@ -448,7 +437,7 @@ int mmo_char_init(void) char_data.clear(); online_chars.clear(); - std::ifstream in(char_txt); + std::ifstream in(char_txt.c_str()); if (!in.is_open()) { PRINTF("Characters file not found: %s.\n", char_txt); @@ -459,17 +448,13 @@ int mmo_char_init(void) } int line_count = 0; - std::string line; - while (std::getline(in, line)) + FString line; + while (io::getline(in, line)) { line_count++; - if (line[0] == '/' && line[1] == '/') + if (line.startswith("//")) continue; - if (line.back() == '\r') - { - line.back() = 0; - } { int i, j = 0; @@ -511,10 +496,7 @@ static void mmo_char_sync(void) { int lock; - FILE *fp; - - // Data save - fp = lock_fopen(char_txt, &lock); + FILE *fp = lock_fopen(char_txt, &lock); if (fp == NULL) { PRINTF("WARNING: Server can't not save characters.\n"); @@ -525,7 +507,7 @@ void mmo_char_sync(void) // yes, we need a mutable reference to do the saves ... for (mmo_charstatus& cd : char_data) { - std::string line = mmo_char_tostr(&cd); + FString line = mmo_char_tostr(&cd); fwrite(line.data(), 1, line.size(), fp); fputc('\n', fp); } @@ -565,43 +547,17 @@ void mmo_char_sync_timer(TimerData *, tick_t) _exit(0); } -//---------------------------------------------------- -// Remove trailing whitespace from a name -//---------------------------------------------------- -static -void remove_trailing_blanks(char *name) -{ - char *tail = name + strlen(name) - 1; - - while (tail > name && *tail == ' ') - *tail-- = 0; -} - -//---------------------------------------------------- -// Remove prefix whitespace from a name -//---------------------------------------------------- -static -void remove_prefix_blanks(char *name) -{ - char *dst = name; - char *src = name; - - while (*src == ' ') // find first nonblank - ++src; - while ((*dst++ = *src++)); // `strmove' -} - //----------------------------------- // Function to create a new character //----------------------------------- static -mmo_charstatus *make_new_char(int fd, char *name, const uint8_t (&stats)[6], uint8_t slot, uint16_t hair_color, uint16_t hair_style) +mmo_charstatus *make_new_char(int fd, CharName name, const uint8_t (&stats)[6], uint8_t slot, uint16_t hair_color, uint16_t hair_style) { // ugh char_session_data *sd = static_cast(session[fd]->session_data.get()); // remove control characters from the name - if (remove_control_chars(name)) + if (!name.to__actual().is_print()) { CHAR_LOG("Make new char error (control char received in the name): (connection #%d, account: %d).\n", fd, sd->account_id); @@ -609,11 +565,15 @@ mmo_charstatus *make_new_char(int fd, char *name, const uint8_t (&stats)[6], uin } // Eliminate whitespace - remove_trailing_blanks(name); - remove_prefix_blanks(name); + if (name.to__actual() != name.to__actual().strip()) + { + CHAR_LOG("Make new char error (leading/trailing whitespace): (connection #%d, account: %d, name: '%s'.\n", + fd, sd->account_id, name); + return nullptr; + } // check lenght of character name - if (strlen(name) < 4) + if (name.to__actual().size() < 4) { CHAR_LOG("Make new char error (character name too small): (connection #%d, account: %d, name: '%s').\n", fd, sd->account_id, name); @@ -624,22 +584,22 @@ mmo_charstatus *make_new_char(int fd, char *name, const uint8_t (&stats)[6], uin if (char_name_option == 1) { // only letters/symbols in char_name_letters are authorised - for (int i = 0; name[i]; i++) - if (strchr(char_name_letters, name[i]) == NULL) + for (uint8_t c : name.to__actual()) + if (!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", - fd, sd->account_id, name, name[i]); + fd, sd->account_id, name, c); return nullptr; } } else if (char_name_option == 2) { // letters/symbols in char_name_letters are forbidden - for (int i = 0; name[i]; i++) - if (strchr(char_name_letters, name[i]) != NULL) + for (uint8_t c : name.to__actual()) + if (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", - fd, sd->account_id, name, name[i]); + fd, sd->account_id, name, c); return nullptr; } } // else, all letters/symbols are authorised (except control char removed before) @@ -674,9 +634,7 @@ mmo_charstatus *make_new_char(int fd, char *name, const uint8_t (&stats)[6], uin for (const mmo_charstatus& cd : char_data) { - if ((name_ignoring_case != 0 && strcmp(cd.name, name) == 0) - || (name_ignoring_case == 0 - && strcasecmp(cd.name, name) == 0)) + if (cd.name == name) { CHAR_LOG("Make new char error (name already exists): (connection #%d, account: %d) slot %d, name: %s (actual name of other char: %s), stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d.\n", fd, sd->account_id, slot, name, cd.name, @@ -697,7 +655,7 @@ mmo_charstatus *make_new_char(int fd, char *name, const uint8_t (&stats)[6], uin } } - if (strcmp(wisp_server_name, name) == 0) + if (wisp_server_name == name) { CHAR_LOG("Make new char error (name used is wisp name for server): (connection #%d, account: %d) slot %d, name: %s (actual name whisper server: %s), stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d.\n", fd, sd->account_id, slot, name, wisp_server_name, @@ -723,7 +681,7 @@ mmo_charstatus *make_new_char(int fd, char *name, const uint8_t (&stats)[6], uin cd.char_id = char_id_count++; cd.account_id = sd->account_id; cd.char_num = slot; - strcpy(cd.name, name); + cd.name = name; cd.species = 0; cd.base_level = 1; cd.job_level = 1; @@ -771,10 +729,10 @@ static void create_online_files(void) { // write files - FILE *fp = fopen_(online_txt_filename, "w"); + FILE *fp = fopen(online_txt_filename.c_str(), "w"); if (fp != NULL) { - FILE *fp2 = fopen_(online_html_filename, "w"); + FILE *fp2 = fopen(online_html_filename.c_str(), "w"); if (fp2 != NULL) { // get time @@ -836,9 +794,9 @@ void create_online_files(void) FPRINTF(fp2, " "); if (gml >= online_gm_display_min_level) FPRINTF(fp2, ""); - for (int k = 0; cd.name[k]; k++) + for (char c : cd.name.to__actual()) { - switch (cd.name[k]) + switch (c) { case '&': FPRINTF(fp2, "&"); @@ -850,7 +808,7 @@ void create_online_files(void) FPRINTF(fp2, ">"); break; default: - FPRINTF(fp2, "%c", cd.name[k]); + FPRINTF(fp2, "%c", c); break; }; } @@ -882,9 +840,9 @@ void create_online_files(void) } FPRINTF(fp2, " \n"); FPRINTF(fp2, "\n"); - fclose_(fp2); + fclose(fp2); } - fclose_(fp); + fclose(fp); } return; @@ -983,7 +941,7 @@ int mmo_char_send006b(int fd, struct char_session_data *sd) WFIFOW(fd, j + 72) = find_equip_view(p, EPOS::MISC2); // WFIFOW(fd,j+72) = p->clothes_color; - WFIFO_STRING(fd, j + 74, p->name, 24); + WFIFO_STRING(fd, j + 74, p->name.to__actual(), 24); WFIFOB(fd, j + 98) = min(p->attrs[ATTR::STR], 255); WFIFOB(fd, j + 99) = min(p->attrs[ATTR::AGI], 255); @@ -1192,9 +1150,9 @@ void parse_tologin(int fd) // PRINTF("max_connect_user (unlimited) -> accepted.\n"); // else // PRINTF("count_users(): %d < max_connect_user (%d) -> accepted.\n", count_users(), max_connect_user); - RFIFO_STRING(fd, 7, sd->email, 40); - if (e_mail_check(sd->email) == 0) - strzcpy(sd->email, "a@a.com", 40); // default e-mail + sd->email = stringish(RFIFO_STRING<40>(fd, 7)); + if (!e_mail_check(sd->email)) + sd->email = DEFAULT_EMAIL; sd->connect_until_time = static_cast(RFIFOL(fd, 47)); // send characters to player mmo_char_send006b(i, sd); @@ -1226,9 +1184,9 @@ void parse_tologin(int fd) { if (sd->account_id == RFIFOL(fd, 2)) { - RFIFO_STRING(fd, 6, sd->email, 40); - if (e_mail_check(sd->email) == 0) - strzcpy(sd->email, "a@a.com", 40); // default e-mail + sd->email = stringish(RFIFO_STRING<40>(fd, 6)); + if (!e_mail_check(sd->email)) + sd->email = DEFAULT_EMAIL; sd->connect_until_time = static_cast(RFIFOL(fd, 46)); break; } @@ -1309,29 +1267,20 @@ void parse_tologin(int fd) else { size_t len = RFIFOL(fd, 4); - char message[len]; - RFIFO_STRING(fd, 8, message, len); - remove_control_chars(message); - // remove all first spaces - char *p = message; - while (p[0] == ' ') - p++; + FString message = RFIFO_STRING(fd, 8, len).to_print().lstrip(); // if message is only composed of spaces - if (p[0] == '\0') + if (!message) CHAR_LOG("Receiving a message for broadcast, but message is only a lot of spaces.\n"); // else send message to all map-servers else { - { - const char *message_ptr = message; - CHAR_LOG("'ladmin': Receiving a message for broadcast (message (in yellow): %s)\n", - message_ptr); - } + CHAR_LOG("'ladmin': Receiving a message for broadcast (message (in yellow): %s)\n", + message); // send broadcast to all map-servers uint8_t buf[4 + len]; WBUFW(buf, 0) = 0x3800; - WBUFW(buf, 2) = 4 + sizeof(message); - WBUF_STRING(buf, 4, message, sizeof(message)); + WBUFW(buf, 2) = 4 + len; + WBUF_STRING(buf, 4, message, len); mapif_sendall(buf, WBUFW(buf, 2)); } } @@ -1351,7 +1300,7 @@ void parse_tologin(int fd) p < RFIFOW(fd, 2) && j < ACCOUNT_REG2_NUM; p += 36, j++) { - RFIFO_STRING(fd, p, reg[j].str, 32); + reg[j].str = stringish(RFIFO_STRING<32>(fd, p)); reg[j].value = RFIFOL(fd, p + 32); } set_account_reg2(acc, j, reg); @@ -1594,7 +1543,6 @@ void parse_frommap(int fd) { // don't send request if no login-server WFIFOW(login_fd, 0) = 0x2709; WFIFOSET(login_fd, 2); -// PRINTF("char : request from map-server to reload GM accounts -> login-server.\n"); } RFIFOSKIP(fd, 2); break; @@ -1604,13 +1552,12 @@ void parse_frommap(int fd) if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd, 2)) return; { - for (char (&foo)[16] : server[id].maps) - strzcpy(foo, "", 16); + for (MapName &foo : server[id].maps) + foo = MapName(); int j = 0; for (int i = 4; i < RFIFOW(fd, 2); i += 16) { - RFIFO_STRING(fd, i, server[id].maps[j], 16); -// PRINTF("set map %d.%d : %s\n", id, j, server[id].map[j]); + server[id].maps[j] = RFIFO_STRING<16>(fd, i); j++; } { @@ -1624,7 +1571,7 @@ void parse_frommap(int fd) } WFIFOW(fd, 0) = 0x2afb; WFIFOB(fd, 2) = 0; - WFIFO_STRING(fd, 3, wisp_server_name, 24); + WFIFO_STRING(fd, 3, wisp_server_name.to__actual(), 24); WFIFOSET(fd, 27); { unsigned char buf[16384]; @@ -1831,7 +1778,7 @@ void parse_frommap(int fd) if (RFIFOREST(fd) < 6) return; { - const char *name = unknown_char_name; + CharName name = unknown_char_name; for (const mmo_charstatus& cd : char_data) { if (cd.char_id == RFIFOL(fd, 2)) @@ -1842,7 +1789,7 @@ void parse_frommap(int fd) } WFIFOW(fd, 0) = 0x2b09; WFIFOL(fd, 2) = RFIFOL(fd, 2); - WFIFO_STRING(fd, 6, name, 24); + WFIFO_STRING(fd, 6, name.to__actual(), 24); WFIFOSET(fd, 30); } RFIFOSKIP(fd, 6); @@ -1887,9 +1834,8 @@ void parse_frommap(int fd) if (RFIFOREST(fd) < 44) return; { - char character_name[24]; int acc = RFIFOL(fd, 2); // account_id of who ask (-1 if nobody) - RFIFO_STRING(fd, 6, character_name, 24); + CharName character_name = stringish(RFIFO_STRING<24>(fd, 6)); // prepare answer WFIFOW(fd, 0) = 0x2b0f; // answer WFIFOL(fd, 2) = acc; // who want do operation @@ -1898,7 +1844,7 @@ void parse_frommap(int fd) const mmo_charstatus *cd = search_character(character_name); if (cd) { - WFIFO_STRING(fd, 6, cd->name, 24); // put correct name if found + WFIFO_STRING(fd, 6, cd->name.to__actual(), 24); // put correct name if found WFIFOW(fd, 32) = 0; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline switch (RFIFOW(fd, 30)) { @@ -1928,12 +1874,9 @@ void parse_frommap(int fd) { // don't send request if no login-server WFIFOW(login_fd, 0) = 0x2725; WFIFOL(login_fd, 2) = cd->account_id; // account value - WFIFOW(login_fd, 6) = RFIFOW(fd, 32); // year - WFIFOW(login_fd, 8) = RFIFOW(fd, 34); // month - WFIFOW(login_fd, 10) = RFIFOW(fd, 36); // day - WFIFOW(login_fd, 12) = RFIFOW(fd, 38); // hour - WFIFOW(login_fd, 14) = RFIFOW(fd, 40); // minute - WFIFOW(login_fd, 16) = RFIFOW(fd, 42); // second + HumanTimeDiff ban_change; + RFIFO_STRUCT(fd, 32, ban_change); + WFIFO_STRUCT(login_fd, 6, ban_change); WFIFOSET(login_fd, 18); // PRINTF("char : status -> login: account %d, ban: %dy %dm %dd %dh %dmn %ds\n", // char_data[i].account_id, (short)RFIFOW(fd,32), (short)RFIFOW(fd,34), (short)RFIFOW(fd,36), (short)RFIFOW(fd,38), (short)RFIFOW(fd,40), (short)RFIFOW(fd,42)); @@ -2001,7 +1944,7 @@ void parse_frommap(int fd) else { // character name not found - WFIFO_STRING(fd, 6, character_name, 24); + WFIFO_STRING(fd, 6, character_name.to__actual(), 24); WFIFOW(fd, 32) = 1; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline } // send answer if a player ask, not if the server ask @@ -2027,7 +1970,7 @@ void parse_frommap(int fd) p < RFIFOW(fd, 2) && j < ACCOUNT_REG2_NUM; p += 36, j++) { - RFIFO_STRING(fd, p, reg[j].str, 32); + reg[j].str = stringish(RFIFO_STRING<32>(fd, p)); reg[j].value = RFIFOL(fd, p + 32); } set_account_reg2(acc, j, reg); @@ -2079,29 +2022,14 @@ void parse_frommap(int fd) } static -int search_mapserver(const char *map) +int search_mapserver(XString map) { - int i, j; - char temp_map[16]; - int temp_map_len; - -// PRINTF("Searching the map-server for map '%s'... ", map); - strzcpy(temp_map, map, sizeof(temp_map)); - if (strchr(temp_map, '.') != NULL) - temp_map[strchr(temp_map, '.') - temp_map + 1] = '\0'; // suppress the '.gat', but conserve the '.' to be sure of the name of the map - - temp_map_len = strlen(temp_map); - for (i = 0; i < MAX_MAP_SERVERS; i++) + for (int i = 0; i < MAX_MAP_SERVERS; i++) if (server_fd[i] >= 0) - for (j = 0; server[i].maps[j][0]; j++) - //PRINTF("%s : %s = %d\n", server[i].map[j], map, strncmp(server[i].map[j], temp_map, temp_map_len)); - if (strncmp(server[i].maps[j], temp_map, temp_map_len) == 0) - { -// PRINTF("found -> server #%d.\n", i); + for (int j = 0; server[i].maps[j][0]; j++) + if (server[i].maps[j] == map) return i; - } -// PRINTF("not found.\n"); return -1; } @@ -2134,7 +2062,7 @@ int lan_ip_check(unsigned char *p) static void handle_x0066(int fd, struct char_session_data *sd, uint8_t rfifob_2, uint8_t *p) { - const char *ip = ip2str(session[fd]->client_addr.sin_addr); + IP_String ip = ip2str(session[fd]->client_addr.sin_addr); { mmo_charstatus *cd = nullptr; @@ -2164,7 +2092,7 @@ void handle_x0066(int fd, struct char_session_data *sd, uint8_t rfifob_2, uint8_ && server[j].maps[0][0]) { // change save point to one of map found on the server (the first) i = j; - strzcpy(cd->last_point.map_, server[j].maps[0], 16); + cd->last_point.map_ = server[j].maps[0]; PRINTF("Map-server #%d found with a map: '%s'.\n", j, server[j].maps[0]); // coordonates are unknown @@ -2187,7 +2115,7 @@ void handle_x0066(int fd, struct char_session_data *sd, uint8_t rfifob_2, uint8_ sd->account_id, cd->char_num, ip); PRINTF("--Send IP of map-server. "); if (lan_ip_check(p)) - WFIFOL(fd, 22) = inet_addr(lan_map_ip); + WFIFOL(fd, 22) = inet_addr(lan_map_ip.c_str()); else WFIFOL(fd, 22) = server[i].ip; WFIFOW(fd, 26) = server[i].port; @@ -2211,7 +2139,6 @@ void handle_x0066(int fd, struct char_session_data *sd, uint8_t rfifob_2, uint8_ static void parse_char(int fd) { - char email[40]; uint8_t *p = reinterpret_cast(&session[fd]->client_addr.sin_addr); if (login_fd < 0 || session[fd]->eof) @@ -2243,11 +2170,9 @@ void parse_char(int fd) { WFIFOW(login_fd, 0) = 0x2740; WFIFOL(login_fd, 2) = sd->account_id; - char old_pass[24]; - RFIFO_STRING(fd, 2, old_pass, 24); + AccountPass old_pass = stringish(RFIFO_STRING<24>(fd, 2)); WFIFO_STRING(login_fd, 6, old_pass, 24); - char new_pass[24]; - RFIFO_STRING(fd, 26, new_pass, 24); + AccountPass new_pass = stringish(RFIFO_STRING<24>(fd, 26)); WFIFO_STRING(login_fd, 30, new_pass, 24); WFIFOSET(login_fd, 54); } @@ -2269,7 +2194,7 @@ void parse_char(int fd) { session[fd]->session_data = make_unique(); sd = static_cast(session[fd]->session_data.get()); - strzcpy(sd->email, "no mail", 40); // put here a mail without '@' to refuse deletion if we don't receive the e-mail + sd->email = stringish("no mail"); // put here a mail without '@' to refuse deletion if we don't receive the e-mail sd->connect_until_time = TimeT(); // unknow or illimited (not displaying on map-server) } sd->account_id = RFIFOL(fd, 2); @@ -2354,8 +2279,7 @@ void parse_char(int fd) if (!sd || RFIFOREST(fd) < 37) return; { - char name[24]; - RFIFO_STRING(fd, 2, name, 24); + CharName name = stringish(RFIFO_STRING<24>(fd, 2)); uint8_t stats[6]; for (int i = 0; i < 6; ++i) stats[i] = RFIFOB(fd, 26 + i); @@ -2401,7 +2325,7 @@ void parse_char(int fd) WFIFOW(fd, 2 + 68) = cd->head_mid; WFIFOW(fd, 2 + 70) = cd->hair_color; - WFIFO_STRING(fd, 2 + 74, cd->name, 24); + WFIFO_STRING(fd, 2 + 74, cd->name.to__actual(), 24); WFIFOB(fd, 2 + 98) = min(cd->attrs[ATTR::STR], 255); WFIFOB(fd, 2 + 99) = min(cd->attrs[ATTR::AGI], 255); @@ -2419,9 +2343,10 @@ void parse_char(int fd) case 0x68: // delete char //Yor's Fix if (!sd || RFIFOREST(fd) < 46) return; - RFIFO_STRING(fd, 6, email, 40); - if (e_mail_check(email) == 0) - strzcpy(email, "a@a.com", 40); // default e-mail + { + AccountEmail email = stringish(RFIFO_STRING<40>(fd, 6)); + if (!e_mail_check(email)) + email = DEFAULT_EMAIL; { { @@ -2457,6 +2382,7 @@ void parse_char(int fd) WFIFOSET(fd, 3); } } + } x68_out: RFIFOSKIP(fd, 46); break; @@ -2472,12 +2398,10 @@ void parse_char(int fd) if (server_fd[i] < 0) break; } - char userid_[24]; - RFIFO_STRING(fd, 2, userid_, 24); - char passwd_[24]; - RFIFO_STRING(fd, 26, passwd_, 24); - if (i == MAX_MAP_SERVERS || strcmp(userid_, userid) - || strcmp(passwd_, passwd)) + AccountName userid_ = stringish(RFIFO_STRING<24>(fd, 2)); + AccountPass passwd_ = stringish(RFIFO_STRING<24>(fd, 26)); + if (i == MAX_MAP_SERVERS || userid_ != userid + || passwd_ != passwd) { WFIFOB(fd, 2) = 3; WFIFOSET(fd, 3); @@ -2495,8 +2419,8 @@ void parse_char(int fd) server[i].ip = RFIFOL(fd, 54); server[i].port = RFIFOW(fd, 58); server[i].users = 0; - for (char (&mapi)[16] : server[i].maps) - strzcpy(mapi, "", 16); + for (MapName& mapi : server[i].maps) + mapi = MapName(); WFIFOSET(fd, 3); RFIFOSKIP(fd, 60); realloc_fifo(fd, FIFOSIZE_SERVERLINK, @@ -2653,12 +2577,12 @@ void check_connect_login_server(TimerData *, tick_t) // Reading Lan Support configuration by [Yor] //------------------------------------------- static -int lan_config_read(const char *lancfgName) +int lan_config_read(ZString lancfgName) { struct hostent *h = NULL; // set default configuration - strzcpy(lan_map_ip, "127.0.0.1", sizeof(lan_map_ip)); + lan_map_ip = stringish("127.0.0.1"); subneti[0] = 127; subneti[1] = 0; subneti[2] = 0; @@ -2666,7 +2590,7 @@ int lan_config_read(const char *lancfgName) for (int j = 0; j < 4; j++) subnetmaski[j] = 255; - std::ifstream in(lancfgName); + std::ifstream in(lancfgName.c_str()); if (!in.is_open()) { @@ -2676,10 +2600,11 @@ int lan_config_read(const char *lancfgName) PRINTF("---start reading of Lan Support configuration...\n"); - std::string line; - while (std::getline(in, line)) + FString line; + while (io::getline(in, line)) { - std::string w1, w2; + SString w1; + TString w2; if (!split_key_value(line, &w1, &w2)) continue; @@ -2689,7 +2614,7 @@ int lan_config_read(const char *lancfgName) h = gethostbyname(w2.c_str()); if (h != NULL) { - sprintf(lan_map_ip, "%d.%d.%d.%d", + SNPRINTF(lan_map_ip, 16, "%d.%d.%d.%d", static_cast(h->h_addr[0]), static_cast(h->h_addr[1]), static_cast(h->h_addr[2]), @@ -2697,7 +2622,7 @@ int lan_config_read(const char *lancfgName) } else { - strzcpy(lan_map_ip, w2.c_str(), sizeof(lan_map_ip)); + lan_map_ip = stringish(w2); } PRINTF("LAN IP of map-server: %s.\n", lan_map_ip); } @@ -2742,14 +2667,15 @@ int lan_config_read(const char *lancfgName) } else { - PRINTF("WARNING: unknown lan config key: %s\n", w1); + FString w1z = w1; + PRINTF("WARNING: unknown lan config key: %s\n", w1z); } } // sub-network check of the map-server { unsigned char p[4]; - sscanf(lan_map_ip, "%hhu.%hhu.%hhu.%hhu", &p[0], &p[1], &p[2], &p[3]); + SSCANF(lan_map_ip, "%hhu.%hhu.%hhu.%hhu", &p[0], &p[1], &p[2], &p[3]); PRINTF("LAN test of LAN IP of the map-server: "); if (lan_ip_check(p) == 0) { @@ -2763,11 +2689,11 @@ int lan_config_read(const char *lancfgName) } static -int char_config_read(const char *cfgName) +int char_config_read(ZString cfgName) { struct hostent *h = NULL; - std::ifstream in(cfgName); + std::ifstream in(cfgName.c_str()); if (!in.is_open()) { @@ -2775,45 +2701,43 @@ int char_config_read(const char *cfgName) exit(1); } - std::string line; - while (std::getline(in, line)) + FString line; + while (io::getline(in, line)) { - std::string w1, w2; + SString w1; + TString w2; if (!split_key_value(line, &w1, &w2)) continue; if (w1 == "userid") - strzcpy(userid, w2.c_str(), 24); + userid = stringish(w2); else if (w1 == "passwd") - strzcpy(passwd, w2.c_str(), 24); + passwd = stringish(w2); else if (w1 == "server_name") { - strzcpy(server_name, w2.c_str(), sizeof(server_name)); + server_name = stringish(w2); PRINTF("%s server has been intialized\n", w2); } else if (w1 == "wisp_server_name") { if (w2.size() >= 4) - strzcpy(wisp_server_name, w2.c_str(), sizeof(wisp_server_name)); + wisp_server_name = stringish(w2); } else if (w1 == "login_ip") { h = gethostbyname(w2.c_str()); if (h != NULL) { - PRINTF("Login server IP address : %s -> %d.%d.%d.%d\n", w2, + SNPRINTF(login_ip_str, 16, "%d.%d.%d.%d", static_cast(h->h_addr[0]), static_cast(h->h_addr[1]), static_cast(h->h_addr[2]), static_cast(h->h_addr[3])); - sprintf(login_ip_str, "%d.%d.%d.%d", - 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", + w2, login_ip_str); } else - strzcpy(login_ip_str, w2.c_str(), 16); + login_ip_str = stringish(w2); } else if (w1 == "login_port") { @@ -2824,20 +2748,16 @@ int char_config_read(const char *cfgName) h = gethostbyname(w2.c_str()); if (h != NULL) { - PRINTF("Character server IP address : %s -> %d.%d.%d.%d\n", - w2, + SNPRINTF(char_ip_str, 16, "%d.%d.%d.%d", static_cast(h->h_addr[0]), static_cast(h->h_addr[1]), static_cast(h->h_addr[2]), static_cast(h->h_addr[3])); - sprintf(char_ip_str, "%d.%d.%d.%d", - 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", + w2, char_ip_str); } else - strzcpy(char_ip_str, w2.c_str(), 16); + char_ip_str = stringish(w2); } else if (w1 == "char_port") { @@ -2853,7 +2773,7 @@ int char_config_read(const char *cfgName) } else if (w1 == "char_txt") { - strzcpy(char_txt, w2.c_str(), sizeof(char_txt)); + char_txt = w2; } else if (w1 == "max_connect_user") { @@ -2863,7 +2783,7 @@ int char_config_read(const char *cfgName) } else if (w1 == "check_ip_flag") { - check_ip_flag = config_switch(w2.c_str()); + check_ip_flag = config_switch(w2); } else if (w1 == "autosave_time") { @@ -2873,16 +2793,7 @@ int char_config_read(const char *cfgName) } else if (w1 == "start_point") { - char map[32]; - int x, y; - if (SSCANF(w2, "%[^,],%d,%d", map, &x, &y) < 3) - continue; - if (strstr(map, ".gat") != NULL) - { // Verify at least if '.gat' is in the map name - strzcpy(start_point.map_, map, 16); - start_point.x = x; - start_point.y = y; - } + extract(w2, &start_point); } else if (w1 == "start_zeny") { @@ -2904,15 +2815,11 @@ int char_config_read(const char *cfgName) } else if (w1 == "unknown_char_name") { - strzcpy(unknown_char_name, w2.c_str(), 24); + unknown_char_name = stringish(w2); } else if (w1 == "char_log_filename") { - strzcpy(char_log_filename, w2.c_str(), sizeof(char_log_filename)); - } - else if (w1 == "name_ignoring_case") - { - name_ignoring_case = config_switch(w2.c_str()); + char_log_filename = w2; } else if (w1 == "char_name_option") { @@ -2920,15 +2827,16 @@ int char_config_read(const char *cfgName) } else if (w1 == "char_name_letters") { - strzcpy(char_name_letters, w2.c_str(), sizeof(char_name_letters)); + for (uint8_t c : w2) + char_name_letters[c] = true; } else if (w1 == "online_txt_filename") { - strzcpy(online_txt_filename, w2.c_str(), sizeof(online_txt_filename)); + online_txt_filename = w2; } else if (w1 == "online_html_filename") { - strzcpy(online_html_filename, w2.c_str(), sizeof(online_html_filename)); + online_html_filename = w2; } else if (w1 == "online_sorting_option") { @@ -2948,7 +2856,7 @@ int char_config_read(const char *cfgName) } else if (w1 == "anti_freeze_enable") { - anti_freeze_enable = config_switch(w2.c_str()); + anti_freeze_enable = config_switch(w2); } else if (w1 == "anti_freeze_interval") { @@ -2958,11 +2866,12 @@ int char_config_read(const char *cfgName) } else if (w1 == "import") { - char_config_read(w2.c_str()); + char_config_read(w2); } else { - PRINTF("WARNING: unknown char config key: %s\n", w1); + FString w1z = w1; + PRINTF("WARNING: unknown char config key: %s\n", w1z); } } @@ -2988,7 +2897,7 @@ void term_func(void) CHAR_LOG("----End of char-server (normal end with closing of all files).\n"); } -int do_init(int argc, char **argv) +int do_init(int argc, ZString *argv) { int i; @@ -2996,11 +2905,17 @@ int do_init(int argc, char **argv) CHAR_LOG(""); CHAR_LOG("The char-server starting...\n"); - char_config_read((argc < 2) ? CHAR_CONF_NAME : argv[1]); - lan_config_read((argc > 1) ? argv[1] : LOGIN_LAN_CONF_NAME); + 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); - login_ip = inet_addr(login_ip_str); - char_ip = inet_addr(char_ip_str); + login_ip = inet_addr(login_ip_str.c_str()); + char_ip = inet_addr(char_ip_str.c_str()); for (i = 0; i < MAX_MAP_SERVERS; i++) { @@ -3013,7 +2928,10 @@ int do_init(int argc, char **argv) update_online = TimeT::now(); create_online_files(); // update online players files at start of the server - inter_init((argc > 2) ? argv[2] : inter_cfgName); // inter 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 5e16a6a..8e37c64 100644 --- a/src/char/char.hpp +++ b/src/char/char.hpp @@ -15,18 +15,18 @@ struct mmo_map_server long ip; short port; int users; - char maps[MAX_MAP_PER_SERVER][16]; + MapName maps[MAX_MAP_PER_SERVER]; }; -const mmo_charstatus *search_character(const char *character_name); +const mmo_charstatus *search_character(CharName character_name); int mapif_sendall(const uint8_t *buf, unsigned int len); int mapif_sendallwos(int fd, const uint8_t *buf, unsigned int len); int mapif_send(int fd, const uint8_t *buf, unsigned int len); -void char_log(const_string line); +void char_log(XString line); #define CHAR_LOG(fmt, ...) \ - char_log(static_cast(STRPRINTF(fmt, ## __VA_ARGS__))) + char_log(STRPRINTF(fmt, ## __VA_ARGS__)) #endif // CHAR_HPP diff --git a/src/char/int_party.cpp b/src/char/int_party.cpp index 38edb9b..d2c64e1 100644 --- a/src/char/int_party.cpp +++ b/src/char/int_party.cpp @@ -3,8 +3,12 @@ #include #include +#include + #include "../common/cxxstdio.hpp" #include "../common/db.hpp" +#include "../common/extract.hpp" +#include "../common/io.hpp" #include "../common/lock.hpp" #include "../common/mmo.hpp" #include "../common/socket.hpp" @@ -14,7 +18,7 @@ #include "../poison.hpp" -char party_txt[1024] = "save/party.txt"; +FString party_txt = "save/party.txt"; static Map party_db; @@ -30,82 +34,84 @@ void mapif_parse_PartyLeave(int fd, int party_id, int account_id); // パーティデータの文字列への変換 static -std::string inter_party_tostr(struct party *p) +FString inter_party_tostr(struct party *p) { - std::string str = STRPRINTF( - "%d\t" - "%s\t" - "%d,%d\t", - p->party_id, - p->name, - p->exp, p->item); + MString str; + str += STRPRINTF( + "%d\t" + "%s\t" + "%d,%d\t", + p->party_id, + p->name, + p->exp, p->item); for (int i = 0; i < MAX_PARTY; i++) { struct party_member *m = &p->member[i]; + if (!m->account_id) + continue; str += STRPRINTF( "%d,%d\t" "%s\t", m->account_id, m->leader, - (m->account_id > 0) ? m->name : "NoMember"); + m->name); } - return str; + return FString(str); } -// パーティデータの文字列からの変換 static -int inter_party_fromstr(char *str, struct party *p) +bool extract(XString str, party *p) { *p = party(); - if (sscanf(str, - "%d\t" - "%[^\t]\t" - "%d,%d\t", - &p->party_id, - p->name, - &p->exp, &p->item) != 4) - return 1; - - for (int j = 0; j < 3 && str != NULL; j++) - str = strchr(str + 1, '\t'); - - for (int i = 0; i < MAX_PARTY; i++) + // not compatible with the normal extract()ors since it has + // a variable-size element that uses the same separator + std::vector bits; + if (!extract(str, vrec<'\t'>(&bits))) + return false; + auto begin = bits.begin(); + auto end = bits.end(); + if (begin == end || !extract(*begin, &p->party_id)) + return false; + ++begin; + if (begin == end || !extract(*begin, &p->name)) + return false; + ++begin; + if (begin == end || !extract(*begin, record<','>(&p->exp, &p->item))) + return false; + ++begin; + + for (int i = 0; begin != end && i < MAX_PARTY; ++i) { struct party_member *m = &p->member[i]; - if (str == NULL) - return 1; - - if (sscanf(str + 1, - "%d,%d\t" - "%[^\t]\t", - &m->account_id, &m->leader, - m->name) != 3) - return 1; - - for (int j = 0; j < 2 && str != NULL; j++) - str = strchr(str + 1, '\t'); + + if (begin == end || !extract(*begin, record<','>(&m->account_id, &m->leader))) + return false; + ++begin; + if (begin == end || !extract(*begin, &m->name)) + return false; + ++begin; + if (!m->account_id) + --i; } - return 0; + return true; } // パーティデータのロード int inter_party_init(void) { - char line[8192]; - FILE *fp; - int c = 0; - int i, j; - - if ((fp = fopen_(party_txt, "r")) == NULL) + std::ifstream in(party_txt.c_str()); + if (!in.is_open()) return 1; // TODO: convert to use char_id, and change to extract() - while (fgets(line, sizeof(line) - 1, fp)) + FString line; + int c = 0; + while (io::getline(in, line)) { - j = 0; - if (sscanf(line, "%d\t%%newid%%\n%n", &i, &j) == 1 && j > 0 + int i, j = 0; + if (SSCANF(line, "%d\t%%newid%%\n%n", &i, &j) == 1 && j > 0 && party_newid <= i) { party_newid = i; @@ -113,7 +119,7 @@ int inter_party_init(void) } struct party p {}; - if (inter_party_fromstr(line, &p) == 0 && p.party_id > 0) + if (extract(line, &p) && p.party_id > 0) { if (p.party_id >= party_newid) party_newid = p.party_id + 1; @@ -127,7 +133,6 @@ int inter_party_init(void) } c++; } - fclose_(fp); // PRINTF("int_party: %s read done (%d parties)\n", party_txt, c); return 0; @@ -137,7 +142,7 @@ int inter_party_init(void) static void inter_party_save_sub(struct party *data, FILE *fp) { - std::string line = inter_party_tostr(data); + FString line = inter_party_tostr(data); FPRINTF(fp, "%s\n", line); } @@ -164,15 +169,15 @@ int inter_party_save(void) // パーティ名検索用 static -void search_partyname_sub(struct party *p, const char *str, struct party **dst) +void search_partyname_sub(struct party *p, PartyName str, struct party **dst) { - if (strcasecmp(p->name, str) == 0) + if (p->name == str) *dst = p; } // パーティ名検索 static -struct party *search_partyname(const char *str) +struct party *search_partyname(PartyName str) { struct party *p = NULL; for (auto& pair : party_db) @@ -227,7 +232,7 @@ int party_check_empty(struct party *p) // キャラの競合がないかチェック用 static void party_check_conflict_sub(struct party *p, - int party_id, int account_id, const char *nick) + int party_id, int account_id, CharName nick) { int i; @@ -237,7 +242,7 @@ void party_check_conflict_sub(struct party *p, for (i = 0; i < MAX_PARTY; i++) { if (p->member[i].account_id == account_id - && strcmp(p->member[i].name, nick) == 0) + && p->member[i].name == nick) { // 別のパーティに偽の所属データがあるので脱退 PRINTF("int_party: party conflict! %d %d %d\n", account_id, @@ -249,7 +254,7 @@ void party_check_conflict_sub(struct party *p, // キャラの競合がないかチェック static -void party_check_conflict(int party_id, int account_id, const char *nick) +void party_check_conflict(int party_id, int account_id, CharName nick) { for (auto& pair : party_db) party_check_conflict_sub(&pair.second, @@ -342,14 +347,14 @@ void mapif_party_optionchanged(int fd, struct party *p, int account_id, // パーティ脱退通知 static -void mapif_party_leaved(int party_id, int account_id, char *name) +void mapif_party_leaved(int party_id, int account_id, CharName name) { unsigned char buf[34]; WBUFW(buf, 0) = 0x3824; WBUFL(buf, 2) = party_id; WBUFL(buf, 6) = account_id; - WBUF_STRING(buf, 10, name, 24); + WBUF_STRING(buf, 10, name.to__actual(), 24); mapif_sendall(buf, 34); PRINTF("int_party: party leaved %d %d %s\n", party_id, account_id, name); } @@ -382,9 +387,9 @@ void mapif_party_broken(int party_id, int flag) // パーティ内発言 static -void mapif_party_message(int party_id, int account_id, const char *mes) +void mapif_party_message(int party_id, int account_id, XString mes) { - size_t len = strlen(mes); + size_t len = mes.size() + 1; unsigned char buf[len + 12]; WBUFW(buf, 0) = 0x3827; @@ -400,14 +405,11 @@ void mapif_party_message(int party_id, int account_id, const char *mes) // パーティ static -void mapif_parse_CreateParty(int fd, int account_id, const char *name, const char *nick, - const char *map, int lv) +void mapif_parse_CreateParty(int fd, int account_id, PartyName name, CharName nick, + MapName map, int lv) { - int i; - - for (i = 0; i < 24 && name[i]; i++) { - if (!(name[i] & 0xe0) || name[i] == 0x7f) + if (!name.is_print()) { PRINTF("int_party: illegal party name [%s]\n", name); mapif_party_created(fd, account_id, NULL); @@ -423,12 +425,12 @@ void mapif_parse_CreateParty(int fd, int account_id, const char *name, const cha } struct party p {}; p.party_id = party_newid++; - strzcpy(p.name, name, 24); + p.name = name; p.exp = 0; p.item = 0; p.member[0].account_id = account_id; - strzcpy(p.member[0].name, nick, 24); - strzcpy(p.member[0].map, map, 16); + p.member[0].name = nick; + p.member[0].map = map; p.member[0].leader = 1; p.member[0].online = 1; p.member[0].lv = lv; @@ -453,7 +455,7 @@ void mapif_parse_PartyInfo(int fd, int party_id) // パーティ追加要求 static void mapif_parse_PartyAddMember(int fd, int party_id, int account_id, - const char *nick, const char *map, int lv) + CharName nick, MapName map, int lv) { struct party *p = party_db.search(party_id); if (p == NULL) @@ -469,8 +471,8 @@ void mapif_parse_PartyAddMember(int fd, int party_id, int account_id, int flag = 0; p->member[i].account_id = account_id; - strzcpy(p->member[i].name, nick, 24); - strzcpy(p->member[i].map, map, 16); + p->member[i].name = nick; + p->member[i].map = map; p->member[i].leader = 0; p->member[i].online = 1; p->member[i].lv = lv; @@ -493,7 +495,7 @@ void mapif_parse_PartyAddMember(int fd, int party_id, int account_id, // パーティー設定変更要求 static void mapif_parse_PartyChangeOption(int fd, int party_id, int account_id, - int exp, int item) + int exp, int item) { struct party *p = party_db.search(party_id); if (p == NULL) @@ -534,7 +536,7 @@ void mapif_parse_PartyLeave(int, int party_id, int account_id) // パーティマップ更新要求 static void mapif_parse_PartyChangeMap(int fd, int party_id, int account_id, - const char *map, int online, int lv) + MapName map, int online, int lv) { struct party *p = party_db.search(party_id); if (p == NULL) @@ -546,7 +548,7 @@ void mapif_parse_PartyChangeMap(int fd, int party_id, int account_id, continue; int flag = 0; - strzcpy(p->member[i].map, map, 16); + p->member[i].map = map; p->member[i].online = online; p->member[i].lv = lv; mapif_party_membermoved(p, i); @@ -576,14 +578,14 @@ void mapif_parse_BreakParty(int fd, int party_id) // パーティメッセージ送信 static -void mapif_parse_PartyMessage(int, int party_id, int account_id, const char *mes) +void mapif_parse_PartyMessage(int, int party_id, int account_id, XString mes) { mapif_party_message(party_id, account_id, mes); } // パーティチェック要求 static -void mapif_parse_PartyCheck(int, int party_id, int account_id, const char *nick) +void mapif_parse_PartyCheck(int, int party_id, int account_id, CharName nick) { party_check_conflict(party_id, account_id, nick); } @@ -600,12 +602,9 @@ int inter_party_parse_frommap(int fd) case 0x3020: { int account = RFIFOL(fd, 2); - char name[24]; - RFIFO_STRING(fd, 6, name, 24); - char nick[24]; - RFIFO_STRING(fd, 30, nick, 24); - char map[16]; - RFIFO_STRING(fd, 54, map, 16); + PartyName name = stringish(RFIFO_STRING<24>(fd, 6)); + CharName nick = stringish(RFIFO_STRING<24>(fd, 30)); + MapName map = RFIFO_STRING<16>(fd, 54); uint16_t lv = RFIFOW(fd, 70); mapif_parse_CreateParty(fd, account, @@ -625,10 +624,8 @@ int inter_party_parse_frommap(int fd) { int party_id = RFIFOL(fd, 2); int account_id = RFIFOL(fd, 6); - char nick[24]; - RFIFO_STRING(fd, 10, nick, 24); - char map[16]; - RFIFO_STRING(fd, 34, map, 16); + CharName nick = stringish(RFIFO_STRING<24>(fd, 10)); + MapName map = RFIFO_STRING<16>(fd, 34); uint16_t lv = RFIFOW(fd, 50); mapif_parse_PartyAddMember(fd, party_id, @@ -664,8 +661,7 @@ int inter_party_parse_frommap(int fd) { int party_id = RFIFOL(fd, 2); int account_id = RFIFOL(fd, 6); - char map[16]; - RFIFO_STRING(fd, 10, map, 16); + MapName map = RFIFO_STRING<16>(fd, 10); uint8_t online = RFIFOB(fd, 26); uint16_t lv = RFIFOW(fd, 27); mapif_parse_PartyChangeMap(fd, @@ -687,8 +683,7 @@ int inter_party_parse_frommap(int fd) size_t len = RFIFOW(fd, 2) - 12; int party_id = RFIFOL(fd, 4); int account_id = RFIFOL(fd, 8); - char mes[len]; - RFIFO_STRING(fd, 12, mes, len); + FString mes = RFIFO_STRING(fd, 12, len); mapif_parse_PartyMessage(fd, party_id, account_id, @@ -699,8 +694,7 @@ int inter_party_parse_frommap(int fd) { int party_id = RFIFOL(fd, 2); int account_id = RFIFOL(fd, 6); - char nick[24]; - RFIFO_STRING(fd, 10, nick, 24); + CharName nick = stringish(RFIFO_STRING<24>(fd, 10)); mapif_parse_PartyCheck(fd, party_id, account_id, diff --git a/src/char/int_party.hpp b/src/char/int_party.hpp index 8a59b49..d003250 100644 --- a/src/char/int_party.hpp +++ b/src/char/int_party.hpp @@ -1,6 +1,8 @@ #ifndef INT_PARTY_HPP #define INT_PARTY_HPP +#include "../common/strings.hpp" + int inter_party_init(void); int inter_party_save(void); @@ -8,6 +10,6 @@ int inter_party_parse_frommap(int fd); void inter_party_leave(int party_id, int account_id); -extern char party_txt[1024]; +extern FString party_txt; #endif // INT_PARTY_HPP diff --git a/src/char/int_storage.cpp b/src/char/int_storage.cpp index 09ce9d4..aa605bf 100644 --- a/src/char/int_storage.cpp +++ b/src/char/int_storage.cpp @@ -9,6 +9,7 @@ #include "../common/cxxstdio.hpp" #include "../common/db.hpp" #include "../common/extract.hpp" +#include "../common/io.hpp" #include "../common/lock.hpp" #include "../common/mmo.hpp" #include "../common/socket.hpp" @@ -17,16 +18,17 @@ // ファイル名のデフォルト // inter_config_read()で再設定される -char storage_txt[1024] = "save/storage.txt"; +FString storage_txt = "save/storage.txt"; static Map storage_db; // 倉庫データを文字列に変換 static -std::string storage_tostr(struct storage *p) +FString storage_tostr(struct storage *p) { - std::string str = STRPRINTF( + MString str; + str += STRPRINTF( "%d,%d\t", p->account_id, p->storage_amount); @@ -53,13 +55,13 @@ std::string storage_tostr(struct storage *p) str += '\t'; if (!f) - str.clear(); - return str; + return FString(); + return FString(str); } // 文字列を倉庫データに変換 static -bool extract(const_string str, struct storage *p) +bool extract(XString str, struct storage *p) { std::vector storage_items; if (!extract(str, @@ -73,7 +75,7 @@ bool extract(const_string str, struct storage *p) if (p->account_id <= 0) return false; - if (storage_items.size() >= MAX_STORAGE) + if (storage_items.size() > MAX_STORAGE) return false; std::copy(storage_items.begin(), storage_items.end(), p->storage_); @@ -98,15 +100,15 @@ int inter_storage_init(void) { int c = 0; - std::ifstream in(storage_txt); + std::ifstream in(storage_txt.c_str()); if (!in.is_open()) { PRINTF("cant't read : %s\n", storage_txt); return 1; } - std::string line; - while (std::getline(in, line)) + FString line; + while (io::getline(in, line)) { struct storage s {}; if (extract(line, &s)) @@ -127,8 +129,8 @@ int inter_storage_init(void) static void inter_storage_save_sub(struct storage *data, FILE *fp) { - std::string line = storage_tostr(data); - if (!line.empty()) + FString line = storage_tostr(data); + if (line) FPRINTF(fp, "%s\n", line); } diff --git a/src/char/int_storage.hpp b/src/char/int_storage.hpp index 691f16d..a03d70f 100644 --- a/src/char/int_storage.hpp +++ b/src/char/int_storage.hpp @@ -1,6 +1,8 @@ #ifndef INT_STORAGE_HPP #define INT_STORAGE_HPP +#include "../common/strings.hpp" + int inter_storage_init(void); int inter_storage_save(void); void inter_storage_delete(int account_id); @@ -8,6 +10,6 @@ struct storage *account2storage(int account_id); int inter_storage_parse_frommap(int fd); -extern char storage_txt[1024]; +extern FString storage_txt; #endif // INT_STORAGE_HPP diff --git a/src/char/inter.cpp b/src/char/inter.cpp index 68d81e8..3cb51e7 100644 --- a/src/char/inter.cpp +++ b/src/char/inter.cpp @@ -10,6 +10,7 @@ #include "../common/cxxstdio.hpp" #include "../common/db.hpp" #include "../common/extract.hpp" +#include "../common/io.hpp" #include "../common/lock.hpp" #include "../common/socket.hpp" #include "../common/timer.hpp" @@ -25,10 +26,10 @@ // that is the waiting time of answers of all map-servers constexpr std::chrono::minutes WISDATA_TTL = std::chrono::minutes(1); -char inter_log_filename[1024] = "log/inter.log"; +FString inter_log_filename = "log/inter.log"; static -char accreg_txt[1024] = "save/accreg.txt"; +FString accreg_txt = "save/accreg.txt"; struct accreg { @@ -59,8 +60,8 @@ struct WisData { int id, fd, count; tick_t tick; - char src[24], dst[24]; - std::string msg; + CharName src, dst; + FString msg; }; static Map wis_db; @@ -71,17 +72,18 @@ std::vector wis_dellistv; // アカウント変数を文字列へ変換 static -std::string inter_accreg_tostr(struct accreg *reg) +FString inter_accreg_tostr(struct accreg *reg) { - std::string str STRPRINTF("%d\t", reg->account_id); + MString str; + str += STRPRINTF("%d\t", reg->account_id); for (int j = 0; j < reg->reg_num; j++) str += STRPRINTF("%s,%d ", reg->reg[j].str, reg->reg[j].value); - return str; + return FString(str); } // アカウント変数を文字列から変換 static -bool extract(const_string str, struct accreg *reg) +bool extract(XString str, struct accreg *reg) { std::vector vars; if (!extract(str, @@ -105,11 +107,11 @@ int inter_accreg_init(void) { int c = 0; - std::ifstream in(accreg_txt); + std::ifstream in(accreg_txt.c_str()); if (!in.is_open()) return 1; - std::string line; - while (std::getline(in, line)) + FString line; + while (io::getline(in, line)) { struct accreg reg {}; if (extract(line, ®)) @@ -133,7 +135,7 @@ void inter_accreg_save_sub(struct accreg *reg, FILE *fp) { if (reg->reg_num > 0) { - std::string line = inter_accreg_tostr(reg); + FString line = inter_accreg_tostr(reg); fwrite(line.data(), 1, line.size(), fp); fputc('\n', fp); } @@ -166,33 +168,34 @@ int inter_accreg_save(void) *------------------------------------------ */ static -int inter_config_read(const char *cfgName) +int inter_config_read(ZString cfgName) { - std::ifstream in(cfgName); + std::ifstream in(cfgName.c_str()); if (!in.is_open()) { PRINTF("file not found: %s\n", cfgName); return 1; } - std::string line; - while (std::getline(in, line)) + FString line; + while (io::getline(in, line)) { - std::string w1, w2; + SString w1; + TString w2; if (!split_key_value(line, &w1, &w2)) continue; if (w1 == "storage_txt") { - strzcpy(storage_txt, w2.c_str(), sizeof(storage_txt)); + storage_txt = w2; } else if (w1 == "party_txt") { - strzcpy(party_txt, w2.c_str(), sizeof(party_txt)); + party_txt = w2; } else if (w1 == "accreg_txt") { - strzcpy(accreg_txt, w2.c_str(), sizeof(accreg_txt)); + accreg_txt = w2; } else if (w1 == "party_share_level") { @@ -202,15 +205,16 @@ int inter_config_read(const char *cfgName) } else if (w1 == "inter_log_filename") { - strzcpy(inter_log_filename, w2.c_str(), sizeof(inter_log_filename)); + inter_log_filename = w2; } else if (w1 == "import") { - inter_config_read(w2.c_str()); + inter_config_read(w2); } else { - PRINTF("WARNING: unknown inter config key: %s\n", w1); + FString w1z = w1; + PRINTF("WARNING: unknown inter config key: %s\n", w1z); } } @@ -218,25 +222,21 @@ int inter_config_read(const char *cfgName) } // セーブ -int inter_save(void) +void inter_save(void) { inter_party_save(); inter_storage_save(); inter_accreg_save(); - - return 0; } // 初期化 -int inter_init(const char *file) +void inter_init(ZString file) { inter_config_read(file); inter_party_init(); inter_storage_init(); inter_accreg_init(); - - return 0; } //-------------------------------------------------------- @@ -244,9 +244,9 @@ int inter_init(const char *file) // GMメッセージ送信 static -void mapif_GMmessage(const char *mes) +void mapif_GMmessage(XString mes) { - size_t str_len = strlen(mes) + 1; + size_t str_len = mes.size() + 1; size_t msg_len = str_len + 4; uint8_t buf[msg_len]; @@ -266,9 +266,9 @@ void mapif_wis_message(struct WisData *wd) WBUFW(buf, 0) = 0x3801; WBUFW(buf, 2) = 56 + str_size; WBUFL(buf, 4) = wd->id; - WBUF_STRING(buf, 8, wd->src, 24); - WBUF_STRING(buf, 32, wd->dst, 24); - WBUF_STRING(buf, 56, wd->msg.c_str(), str_size); + WBUF_STRING(buf, 8, wd->src.to__actual(), 24); + WBUF_STRING(buf, 32, wd->dst.to__actual(), 24); + WBUF_STRING(buf, 56, wd->msg, str_size); wd->count = mapif_sendall(buf, WBUFW(buf, 2)); } @@ -279,7 +279,7 @@ void mapif_wis_end(struct WisData *wd, int flag) uint8_t buf[27]; WBUFW(buf, 0) = 0x3802; - WBUF_STRING(buf, 2, wd->src, 24); + WBUF_STRING(buf, 2, wd->src.to__actual(), 24); WBUFB(buf, 26) = flag; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target mapif_send(wd->fd, buf, 27); } @@ -362,8 +362,7 @@ void mapif_parse_GMmessage(int fd) { size_t msg_len = RFIFOW(fd, 2); size_t str_len = msg_len - 4; - char buf[str_len]; - RFIFO_STRING(fd, 4, buf, str_len); + FString buf = RFIFO_STRING(fd, 4, str_len); mapif_GMmessage(buf); } @@ -380,10 +379,8 @@ void mapif_parse_WisRequest(int fd) return; } - char from[24]; - char to[24]; - RFIFO_STRING(fd, 4, from, 24); - RFIFO_STRING(fd, 28, to, 24); + CharName from = stringish(RFIFO_STRING<24>(fd, 4)); + CharName to = stringish(RFIFO_STRING<24>(fd, 28)); // search if character exists before to ask all map-servers const mmo_charstatus *mcs = search_character(to); @@ -391,7 +388,7 @@ void mapif_parse_WisRequest(int fd) { uint8_t buf[27]; WBUFW(buf, 0) = 0x3802; - WBUF_STRING(buf, 2, from, 24); + WBUF_STRING(buf, 2, from.to__actual(), 24); WBUFB(buf, 26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target mapif_send(fd, buf, 27); // Character exists. So, ask all map-servers @@ -399,19 +396,19 @@ void mapif_parse_WisRequest(int fd) else { // to be sure of the correct name, rewrite it - strzcpy(to, mcs->name, 24); + to = mcs->name; // if source is destination, don't ask other servers. - if (strcmp(from, to) == 0) + if (from == to) { uint8_t buf[27]; WBUFW(buf, 0) = 0x3802; - WBUF_STRING(buf, 2, from, 24); + WBUF_STRING(buf, 2, from.to__actual(), 24); WBUFB(buf, 26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target mapif_send(fd, buf, 27); } else { - struct WisData wd; + struct WisData wd {}; // Whether the failure of previous wisp/page transmission (timeout) check_ttl_wisdata(); @@ -419,11 +416,9 @@ void mapif_parse_WisRequest(int fd) wd.id = ++wisid; wd.fd = fd; size_t len = RFIFOW(fd, 2) - 52; - RFIFO_STRING(fd, 4, wd.src, 24); - RFIFO_STRING(fd, 28, wd.dst, 24); - char tmpbuf[len]; - RFIFO_STRING(fd, 52, tmpbuf, len); - wd.msg = std::string(tmpbuf); + wd.src = from; + wd.dst = to; + wd.msg = RFIFO_STRING(fd, 52, len); wd.tick = gettick(); wis_db.insert(wd.id, wd); mapif_wis_message(&wd); @@ -480,7 +475,7 @@ void mapif_parse_AccReg(int fd) for (j = 0, p = 8; j < ACCOUNT_REG_NUM && p < RFIFOW(fd, 2); j++, p += 36) { - RFIFO_STRING(fd, p, reg->reg[j].str, 32); + reg->reg[j].str = stringish(RFIFO_STRING<32>(fd, p)); reg->reg[j].value = RFIFOL(fd, p + 32); } reg->reg_num = j; diff --git a/src/char/inter.hpp b/src/char/inter.hpp index 0adbf03..ce8447d 100644 --- a/src/char/inter.hpp +++ b/src/char/inter.hpp @@ -1,8 +1,10 @@ #ifndef INTER_HPP #define INTER_HPP -int inter_init(const char *file); -int inter_save(void); +#include "../common/strings.hpp" + +void inter_init(ZString file); +void inter_save(void); int inter_parse_frommap(int fd); int inter_check_length(int fd, int length); @@ -10,6 +12,6 @@ int inter_check_length(int fd, int length); #define inter_cfgName "conf/inter_athena.conf" extern int party_share_level; -extern char inter_log_filename[1024]; +extern FString inter_log_filename; #endif // INTER_HPP -- cgit v1.2.3-70-g09d2