From ac359e696f162090840dab488a6ef4981d35bbda Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Sat, 18 May 2013 17:37:33 -0700 Subject: Tweak a little memory management in char-server --- src/char/char.cpp | 1176 +++++++++++++++++++------------------------------ src/char/char.hpp | 3 +- src/char/inter.cpp | 6 +- src/common/mmo.hpp | 2 +- src/common/sanity.hpp | 7 +- src/common/socket.cpp | 47 +- src/common/socket.hpp | 28 +- src/ladmin/ladmin.cpp | 10 + src/login/login.cpp | 31 +- src/map/atcommand.cpp | 283 ++++++------ src/map/chat.cpp | 181 -------- src/map/chat.hpp | 12 - src/map/chrif.cpp | 16 +- src/map/clif.cpp | 151 +++---- src/map/intif.cpp | 16 +- src/map/map.cpp | 61 +-- src/map/map.hpp | 20 +- src/map/map.t.hpp | 1 - src/map/mob.cpp | 16 +- src/map/npc.cpp | 3 +- src/map/party.cpp | 19 +- src/map/pc.cpp | 30 +- src/map/pc.hpp | 5 - src/map/script.cpp | 30 +- src/map/skill.cpp | 4 - 25 files changed, 825 insertions(+), 1333 deletions(-) delete mode 100644 src/map/chat.cpp delete mode 100644 src/map/chat.hpp (limited to 'src') diff --git a/src/char/char.cpp b/src/char/char.cpp index c3c22de..3fc2b87 100644 --- a/src/char/char.cpp +++ b/src/char/char.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -71,11 +72,9 @@ int char_maintenance; static int char_new; static -int email_creation = 0; // disabled by default -static char char_txt[1024]; static -char unknown_char_name[1024] = "Unknown"; +char unknown_char_name[24] = "Unknown"; static char char_log_filename[1024] = "log/char.log"; //Added for lan support @@ -92,26 +91,34 @@ int char_name_option = 0; // Option to know which letters/symbols are autho static char char_name_letters[1024] = ""; // list of letters/symbols authorised (or not) in a character name. by [Yor] -struct char_session_data +struct char_session_data : SessionData { int account_id, login_id1, login_id2, sex; unsigned short packet_tmw_version; - int found_char[9]; 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) }; -#define AUTH_FIFO_SIZE 256 -static -struct +void SessionDeleter::operator()(SessionData *sd) +{ + delete static_cast(sd); +} + +struct AuthFifoEntry { - int account_id, char_id, login_id1, login_id2, ip, char_pos, delflag, - sex; + int account_id; + int char_id; + int login_id1, login_id2; + int ip; + int delflag; + int sex; unsigned short packet_tmw_version; TimeT connect_until_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited) -} auth_fifo[AUTH_FIFO_SIZE]; +}; +static +std::array auth_fifo; static -int auth_fifo_pos = 0; +auto auth_fifo_iter = auth_fifo.begin(); static int check_ip_flag = 1; // It's to check IP of a player between char-server and other servers (part of anti-hacking system) @@ -119,9 +126,7 @@ int check_ip_flag = 1; // It's to check IP of a player between char-serv static int char_id_count = 150000; static -struct mmo_charstatus *char_dat; -static -int char_num, char_max; +std::vector char_data; static int max_connect_user = 0; static @@ -138,9 +143,7 @@ static struct point start_point = { "new_1-1.gat", 53, 111 }; static -struct gm_account *gm_account = NULL; -static -int GM_num = 0; +std::vector gm_accounts; // online players by [Yor] static @@ -155,7 +158,7 @@ static int online_gm_display_min_level = 20; // minimum GM level to display 'GM' when we want to display it static -int *online_chars; // same size of char_dat, and id value of current server (or -1) +std::vector online_chars; // same size of char_data, 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) @@ -181,38 +184,34 @@ void char_log(const_string line) static int isGM(int account_id) { - int i; - - for (i = 0; i < GM_num; i++) - if (gm_account[i].account_id == account_id) - return gm_account[i].level; + for (GM_Account& gma : gm_accounts) + if (gma.account_id == account_id) + return gma.level; return 0; } //---------------------------------------------- // Search an character id -// (return character index or -1 (if not found)) +// (return character pointer or nullptr (if not found)) // If exact character name is not found, // the function checks without case sensitive // and returns index if only 1 character is found // and similar to the searched name. //---------------------------------------------- -int search_character_index(const char *character_name) +const mmo_charstatus *search_character(const char *character_name) { - int i, quantity, index; - - quantity = 0; - index = -1; - for (i = 0; i < char_num; i++) + 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(char_dat[i].name, character_name) == 0) + if (strcasecmp(cd.name, character_name) == 0) { // Strict comparison (if found, we finish the function immediatly with correct value) - if (strcmp(char_dat[i].name, character_name) == 0) - return i; + if (strcmp(cd.name, character_name) == 0) + return &cd; quantity++; - index = i; + index = &cd; } } // Here, the exact character name is not found @@ -221,19 +220,7 @@ int search_character_index(const char *character_name) return index; // Exact character name is not found and 0 or more than 1 similar characters have been found ==> we say not found - return -1; -} - -//------------------------------------- -// Return character name with the index -//------------------------------------- -char *search_character_name(int index) -{ - - if (index >= 0 && index < char_num) - return char_dat[index].name; - - return unknown_char_name; + return nullptr; } //------------------------------------------------- @@ -413,11 +400,11 @@ bool extract(const_string str, struct mmo_charstatus *p) if (strcmp(wisp_server_name, p->name) == 0) return false; - for (int i = 0; i < char_num; i++) + for (const mmo_charstatus& cd : char_data) { - if (char_dat[i].char_id == p->char_id) + if (cd.char_id == p->char_id) return false; - if (strcmp(char_dat[i].name, p->name) == 0) + if (strcmp(cd.name, p->name) == 0) return false; } @@ -458,13 +445,8 @@ bool extract(const_string str, struct mmo_charstatus *p) static int mmo_char_init(void) { - char_max = 256; - CREATE(char_dat, struct mmo_charstatus, 256); - CREATE(online_chars, int, 256); - for (int i = 0; i < char_max; i++) - online_chars[i] = -1; - - char_num = 0; + char_data.clear(); + online_chars.clear(); std::ifstream in(char_txt); if (!in.is_open()) @@ -499,29 +481,22 @@ int mmo_char_init(void) } } - if (char_num >= char_max) - { - char_max += 256; - RECREATE(char_dat, struct mmo_charstatus, char_max); - RECREATE(online_chars, int, char_max); - for (int i = char_max - 256; i < char_max; i++) - online_chars[i] = -1; - } - - if (!extract(line, &char_dat[char_num])) + mmo_charstatus cd {}; + if (!extract(line, &cd)) { CHAR_LOG("Char skipped\n%s", line); continue; } - if (char_dat[char_num].char_id >= char_id_count) - char_id_count = char_dat[char_num].char_id + 1; - char_num++; + if (cd.char_id >= char_id_count) + char_id_count = cd.char_id + 1; + char_data.push_back(std::move(cd)); + online_chars.push_back(-1); } - PRINTF("mmo_char_init: %d characters read in %s.\n", - char_num, char_txt); - CHAR_LOG("mmo_char_init: %d characters read in %s.\n", - char_num, char_txt); + PRINTF("mmo_char_init: %zu characters read in %s.\n", + char_data.size(), char_txt); + CHAR_LOG("mmo_char_init: %zu characters read in %s.\n", + char_data.size(), char_txt); CHAR_LOG("Id for the next created character: %d.\n", char_id_count); @@ -535,7 +510,6 @@ int mmo_char_init(void) static void mmo_char_sync(void) { - int i; int lock; FILE *fp; @@ -545,13 +519,13 @@ void mmo_char_sync(void) { PRINTF("WARNING: Server can't not save characters.\n"); CHAR_LOG("WARNING: Server can't not save characters.\n"); + return; } - else { - for (i = 0; i < char_num; i++) + // yes, we need a mutable reference to do the saves ... + for (mmo_charstatus& cd : char_data) { - // use of sorted index - std::string line = mmo_char_tostr(&char_dat[i]); + std::string line = mmo_char_tostr(&cd); fwrite(line.data(), 1, line.size(), fp); fputc('\n', fp); } @@ -621,12 +595,11 @@ void remove_prefix_blanks(char *name) // Function to create a new character //----------------------------------- static -int make_new_char(int fd, const uint8_t *dat) +mmo_charstatus *make_new_char(int fd, const uint8_t *dat) { // ugh char *cdat = reinterpret_cast(const_cast(dat)); - int i, j; - struct char_session_data *sd = (struct char_session_data *)session[fd]->session_data; + char_session_data *sd = static_cast(session[fd]->session_data.get()); // remove control characters from the name cdat[23] = '\0'; @@ -634,7 +607,7 @@ int make_new_char(int fd, const uint8_t *dat) { CHAR_LOG("Make new char error (control char received in the name): (connection #%d, account: %d).\n", fd, sd->account_id); - return -1; + return nullptr; } // Eliminate whitespace @@ -646,28 +619,30 @@ int make_new_char(int fd, const uint8_t *dat) { CHAR_LOG("Make new char error (character name too small): (connection #%d, account: %d, name: '%s').\n", fd, sd->account_id, cdat); - return -1; + return nullptr; } // Check Authorised letters/symbols in the name of the character if (char_name_option == 1) - { // only letters/symbols in char_name_letters are authorised - for (i = 0; cdat[i]; i++) + { + // only letters/symbols in char_name_letters are authorised + for (int i = 0; cdat[i]; i++) if (strchr(char_name_letters, cdat[i]) == NULL) { 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, cdat, cdat[i]); - return -1; + return nullptr; } } else if (char_name_option == 2) - { // letters/symbols in char_name_letters are forbidden - for (i = 0; cdat[i]; i++) + { + // letters/symbols in char_name_letters are forbidden + for (int i = 0; cdat[i]; i++) if (strchr(char_name_letters, cdat[i]) != NULL) { 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, cdat, cdat[i]); - return -1; + return nullptr; } } // else, all letters/symbols are authorised (except control char removed before) @@ -682,11 +657,11 @@ int make_new_char(int fd, const uint8_t *dat) dat[26], dat[27], dat[28], dat[29], dat[24] + dat[25] + dat[26] + dat[27] + dat[28] + dat[29], dat[33], dat[31]); - return -1; + return nullptr; } // check individual stat value - for (i = 24; i <= 29; i++) + for (int i = 24; i <= 29; i++) { if (dat[i] < 1 || dat[i] > 9) { @@ -695,52 +670,43 @@ int make_new_char(int fd, const uint8_t *dat) dat[26], dat[27], dat[28], dat[29], dat[24] + dat[25] + dat[26] + dat[27] + dat[28] + dat[29], dat[33], dat[31]); - return -1; + return nullptr; } } - for (i = 0; i < char_num; i++) + for (const mmo_charstatus& cd : char_data) { - if ((name_ignoring_case != 0 && strcmp(char_dat[i].name, cdat) == 0) + if ((name_ignoring_case != 0 && strcmp(cd.name, cdat) == 0) || (name_ignoring_case == 0 - && strcasecmp(char_dat[i].name, cdat) == 0)) + && strcasecmp(cd.name, cdat) == 0)) { 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, dat[30], cdat, char_dat[i].name, + fd, sd->account_id, dat[30], cdat, cd.name, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29], dat[24] + dat[25] + dat[26] + dat[27] + dat[28] + dat[29], dat[33], dat[31]); - return -1; + return nullptr; } - if (char_dat[i].account_id == sd->account_id - && char_dat[i].char_num == dat[30]) + if (cd.account_id == sd->account_id + && cd.char_num == dat[30]) { CHAR_LOG("Make new char error (slot already used): (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, dat[30], cdat, char_dat[i].name, + fd, sd->account_id, dat[30], cdat, cd.name, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29], dat[24] + dat[25] + dat[26] + dat[27] + dat[28] + dat[29], dat[33], dat[31]); - return -1; + return nullptr; } } if (strcmp(wisp_server_name, cdat) == 0) { - CHAR_LOG("Make new char error (name used is wisp name for server): (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, dat[30], cdat, char_dat[i].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, dat[30], cdat, wisp_server_name, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29], dat[24] + dat[25] + dat[26] + dat[27] + dat[28] + dat[29], dat[33], dat[31]); - return -1; - } - - if (char_num >= char_max) - { - char_max += 256; - RECREATE(char_dat, struct mmo_charstatus, char_max); - RECREATE(online_chars, int, char_max); - for (j = char_max - 256; j < char_max; j++) - online_chars[j] = -1; + return nullptr; } char ip[16]; @@ -755,58 +721,60 @@ int make_new_char(int fd, const uint8_t *dat) dat[24] + dat[25] + dat[26] + dat[27] + dat[28] + dat[29], dat[33], dat[31], ip); - memset(&char_dat[i], 0, sizeof(struct mmo_charstatus)); - - char_dat[i].char_id = char_id_count++; - char_dat[i].account_id = sd->account_id; - char_dat[i].char_num = dat[30]; - strcpy(char_dat[i].name, cdat); - char_dat[i].species = 0; - char_dat[i].base_level = 1; - char_dat[i].job_level = 1; - char_dat[i].base_exp = 0; - char_dat[i].job_exp = 0; - char_dat[i].zeny = start_zeny; - char_dat[i].attrs[ATTR::STR] = dat[24]; - char_dat[i].attrs[ATTR::AGI] = dat[25]; - char_dat[i].attrs[ATTR::VIT] = dat[26]; - char_dat[i].attrs[ATTR::INT] = dat[27]; - char_dat[i].attrs[ATTR::DEX] = dat[28]; - char_dat[i].attrs[ATTR::LUK] = dat[29]; - char_dat[i].max_hp = 40 * (100 + char_dat[i].attrs[ATTR::VIT]) / 100; - char_dat[i].max_sp = 11 * (100 + char_dat[i].attrs[ATTR::INT]) / 100; - char_dat[i].hp = char_dat[i].max_hp; - char_dat[i].sp = char_dat[i].max_sp; - char_dat[i].status_point = 0; - char_dat[i].skill_point = 0; - char_dat[i].option = static_cast