summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2013-05-18 17:37:33 -0700
committerBen Longbons <b.r.longbons@gmail.com>2013-05-18 18:49:39 -0700
commitac359e696f162090840dab488a6ef4981d35bbda (patch)
tree2ee04de23428bba264d1e39c80d5f50180d1b555
parentfd00d50574064db9edfcccc4286ed8f1b55b185a (diff)
downloadtmwa-ac359e696f162090840dab488a6ef4981d35bbda.tar.gz
tmwa-ac359e696f162090840dab488a6ef4981d35bbda.tar.bz2
tmwa-ac359e696f162090840dab488a6ef4981d35bbda.tar.xz
tmwa-ac359e696f162090840dab488a6ef4981d35bbda.zip
Tweak a little memory management in char-server
-rw-r--r--Makefile2
-rw-r--r--src/char/char.cpp1176
-rw-r--r--src/char/char.hpp3
-rw-r--r--src/char/inter.cpp6
-rw-r--r--src/common/mmo.hpp2
-rw-r--r--src/common/sanity.hpp7
-rw-r--r--src/common/socket.cpp47
-rw-r--r--src/common/socket.hpp28
-rw-r--r--src/ladmin/ladmin.cpp10
-rw-r--r--src/login/login.cpp31
-rw-r--r--src/map/atcommand.cpp283
-rw-r--r--src/map/chat.cpp181
-rw-r--r--src/map/chat.hpp12
-rw-r--r--src/map/chrif.cpp16
-rw-r--r--src/map/clif.cpp151
-rw-r--r--src/map/intif.cpp16
-rw-r--r--src/map/map.cpp61
-rw-r--r--src/map/map.hpp20
-rw-r--r--src/map/map.t.hpp1
-rw-r--r--src/map/mob.cpp16
-rw-r--r--src/map/npc.cpp3
-rw-r--r--src/map/party.cpp19
-rw-r--r--src/map/pc.cpp30
-rw-r--r--src/map/pc.hpp5
-rw-r--r--src/map/script.cpp30
-rw-r--r--src/map/skill.cpp4
26 files changed, 826 insertions, 1334 deletions
diff --git a/Makefile b/Makefile
index 56ab981..c071f82 100644
--- a/Makefile
+++ b/Makefile
@@ -62,7 +62,7 @@ eathena-monitor: ${BUILD_DIR}/tool/eathena-monitor
${BUILD_DIR}/char/char: ${BUILD_DIR}/char/char.o ${BUILD_DIR}/char/inter.o ${BUILD_DIR}/char/int_party.o ${BUILD_DIR}/char/int_storage.o ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/lock.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/cxxstdio.o ${BUILD_DIR}/common/extract.o
${BUILD_DIR}/ladmin/ladmin: ${BUILD_DIR}/ladmin/ladmin.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/cxxstdio.o
${BUILD_DIR}/login/login: ${BUILD_DIR}/login/login.o ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/lock.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/cxxstdio.o ${BUILD_DIR}/common/extract.o
-${BUILD_DIR}/map/map: ${BUILD_DIR}/map/map.o ${BUILD_DIR}/map/tmw.o ${BUILD_DIR}/map/magic-interpreter-lexer.o ${BUILD_DIR}/map/magic-interpreter-parser.o ${BUILD_DIR}/map/magic-interpreter-base.o ${BUILD_DIR}/map/magic-expr.o ${BUILD_DIR}/map/magic-stmt.o ${BUILD_DIR}/map/magic.o ${BUILD_DIR}/map/map.o ${BUILD_DIR}/map/chrif.o ${BUILD_DIR}/map/clif.o ${BUILD_DIR}/map/pc.o ${BUILD_DIR}/map/npc.o ${BUILD_DIR}/map/chat.o ${BUILD_DIR}/map/path.o ${BUILD_DIR}/map/itemdb.o ${BUILD_DIR}/map/mob.o ${BUILD_DIR}/map/script.o ${BUILD_DIR}/map/storage.o ${BUILD_DIR}/map/skill.o ${BUILD_DIR}/map/skill-pools.o ${BUILD_DIR}/map/atcommand.o ${BUILD_DIR}/map/battle.o ${BUILD_DIR}/map/intif.o ${BUILD_DIR}/map/trade.o ${BUILD_DIR}/map/party.o ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/map/grfio.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/lock.o ${BUILD_DIR}/common/nullpo.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/cxxstdio.o ${BUILD_DIR}/common/extract.o
+${BUILD_DIR}/map/map: ${BUILD_DIR}/map/map.o ${BUILD_DIR}/map/tmw.o ${BUILD_DIR}/map/magic-interpreter-lexer.o ${BUILD_DIR}/map/magic-interpreter-parser.o ${BUILD_DIR}/map/magic-interpreter-base.o ${BUILD_DIR}/map/magic-expr.o ${BUILD_DIR}/map/magic-stmt.o ${BUILD_DIR}/map/magic.o ${BUILD_DIR}/map/map.o ${BUILD_DIR}/map/chrif.o ${BUILD_DIR}/map/clif.o ${BUILD_DIR}/map/pc.o ${BUILD_DIR}/map/npc.o ${BUILD_DIR}/map/path.o ${BUILD_DIR}/map/itemdb.o ${BUILD_DIR}/map/mob.o ${BUILD_DIR}/map/script.o ${BUILD_DIR}/map/storage.o ${BUILD_DIR}/map/skill.o ${BUILD_DIR}/map/skill-pools.o ${BUILD_DIR}/map/atcommand.o ${BUILD_DIR}/map/battle.o ${BUILD_DIR}/map/intif.o ${BUILD_DIR}/map/trade.o ${BUILD_DIR}/map/party.o ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/map/grfio.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/lock.o ${BUILD_DIR}/common/nullpo.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/cxxstdio.o ${BUILD_DIR}/common/extract.o
${BUILD_DIR}/tool/eathena-monitor: ${BUILD_DIR}/tool/eathena-monitor.o ${BUILD_DIR}/common/utils.o
# silence build warnings for code beyond my control
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 <netdb.h>
#include <unistd.h>
+#include <cassert>
#include <cstdlib>
#include <cstring>
#include <ctime>
@@ -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<char_session_data *>(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<AuthFifoEntry, 256> 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<mmo_charstatus> 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_Account> 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<int> 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<char *>(const_cast<uint8_t *>(dat));
- int i, j;
- struct char_session_data *sd = (struct char_session_data *)session[fd]->session_data;
+ char_session_data *sd = static_cast<char_session_data *>(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<Option>(0x0000); // Option is only declared
- char_dat[i].karma = 0;
- char_dat[i].manner = 0;
- char_dat[i].party_id = 0;
- //char_dat[i].guild_id = 0;
- char_dat[i].hair = dat[33];
- char_dat[i].hair_color = dat[31];
- char_dat[i].clothes_color = 0;
- char_dat[i].inventory[0].nameid = start_weapon; // Knife
- char_dat[i].inventory[0].amount = 1;
- char_dat[i].inventory[0].equip = EPOS::WEAPON;
- char_dat[i].inventory[0].identify = 1;
- char_dat[i].inventory[0].broken = 0;
- char_dat[i].inventory[1].nameid = start_armor; // Cotton Shirt
- char_dat[i].inventory[1].amount = 1;
- char_dat[i].inventory[1].equip = EPOS::MISC1;
- char_dat[i].inventory[1].identify = 1;
- char_dat[i].inventory[1].broken = 0;
- char_dat[i].weapon = ItemLook::BLADE;
- char_dat[i].shield = 0;
- char_dat[i].head_top = 0;
- char_dat[i].head_mid = 0;
- char_dat[i].head_bottom = 0;
- memcpy(&char_dat[i].last_point, &start_point, sizeof(start_point));
- memcpy(&char_dat[i].save_point, &start_point, sizeof(start_point));
- char_num++;
-
- return i;
+ mmo_charstatus cd {};
+
+ cd.char_id = char_id_count++;
+ cd.account_id = sd->account_id;
+ cd.char_num = dat[30];
+ strcpy(cd.name, cdat);
+ cd.species = 0;
+ cd.base_level = 1;
+ cd.job_level = 1;
+ cd.base_exp = 0;
+ cd.job_exp = 0;
+ cd.zeny = start_zeny;
+ cd.attrs[ATTR::STR] = dat[24];
+ cd.attrs[ATTR::AGI] = dat[25];
+ cd.attrs[ATTR::VIT] = dat[26];
+ cd.attrs[ATTR::INT] = dat[27];
+ cd.attrs[ATTR::DEX] = dat[28];
+ cd.attrs[ATTR::LUK] = dat[29];
+ cd.max_hp = 40 * (100 + cd.attrs[ATTR::VIT]) / 100;
+ cd.max_sp = 11 * (100 + cd.attrs[ATTR::INT]) / 100;
+ cd.hp = cd.max_hp;
+ cd.sp = cd.max_sp;
+ cd.status_point = 0;
+ cd.skill_point = 0;
+ cd.option = static_cast<Option>(0x0000); // Option is only declared
+ cd.karma = 0;
+ cd.manner = 0;
+ cd.party_id = 0;
+ //cd.guild_id = 0;
+ cd.hair = dat[33];
+ cd.hair_color = dat[31];
+ cd.clothes_color = 0;
+ // TODO: remove this - it's not used
+ cd.inventory[0].nameid = start_weapon; // Knife
+ cd.inventory[0].amount = 1;
+ cd.inventory[0].equip = EPOS::WEAPON;
+ cd.inventory[0].identify = 1;
+ cd.inventory[0].broken = 0;
+ cd.inventory[1].nameid = start_armor; // Cotton Shirt
+ cd.inventory[1].amount = 1;
+ cd.inventory[1].equip = EPOS::MISC1;
+ cd.inventory[1].identify = 1;
+ cd.inventory[1].broken = 0;
+ cd.weapon = ItemLook::BLADE;
+ cd.shield = 0;
+ cd.head_top = 0;
+ cd.head_mid = 0;
+ cd.head_bottom = 0;
+ memcpy(&cd.last_point, &start_point, sizeof(start_point));
+ memcpy(&cd.save_point, &start_point, sizeof(start_point));
+ char_data.push_back(std::move(cd));
+ online_chars.push_back(-1);
+
+ return &char_data.back();
}
//-------------------------------------------------------------
@@ -815,99 +783,11 @@ int make_new_char(int fd, const uint8_t *dat)
static
void create_online_files(void)
{
- int i, j, k, l; // for loops
- int players; // count the number of players
- FILE *fp; // for the txt file
- FILE *fp2; // for the html file
- char temp[256]; // to prepare what we must display
- int id[char_num];
-
- // Get number of online players, id of each online players
- players = 0;
- // sort online characters.
- for (i = 0; i < char_num; i++)
- {
- if (online_chars[i] != -1)
- {
- id[players] = i;
- // use sorting option
- switch (online_sorting_option)
- {
- case 1: // by name (without case sensitive)
- {
- char *p_name = char_dat[i].name; //speed up sorting when there are a lot of players. But very rarely players have same name.
- for (j = 0; j < players; j++)
- if (strcasecmp(p_name, char_dat[id[j]].name) < 0 ||
- // if same name, we sort with case sensitive.
- (strcasecmp(p_name, char_dat[id[j]].name) == 0 &&
- strcmp(p_name, char_dat[id[j]].name) < 0))
- {
- for (k = players; k > j; k--)
- id[k] = id[k - 1];
- id[j] = i; // id[players]
- break;
- }
- }
- break;
- case 2: // by zeny
- for (j = 0; j < players; j++)
- if (char_dat[i].zeny < char_dat[id[j]].zeny ||
- // if same number of zenys, we sort by name.
- (char_dat[i].zeny == char_dat[id[j]].zeny &&
- strcasecmp(char_dat[i].name,
- char_dat[id[j]].name) < 0))
- {
- for (k = players; k > j; k--)
- id[k] = id[k - 1];
- id[j] = i; // id[players]
- break;
- }
- break;
- case 3: // by base level
- for (j = 0; j < players; j++)
- if (char_dat[i].base_level <
- char_dat[id[j]].base_level ||
- // if same base level, we sort by base exp.
- (char_dat[i].base_level ==
- char_dat[id[j]].base_level
- && char_dat[i].base_exp <
- char_dat[id[j]].base_exp))
- {
- for (k = players; k > j; k--)
- id[k] = id[k - 1];
- id[j] = i; // id[players]
- break;
- }
- break;
- case 5: // by location map name
- {
- int cpm_result; // A lot of player maps are identical. So, test if done often twice.
- for (j = 0; j < players; j++)
- if ((cpm_result = strcmp(char_dat[i].last_point.map, char_dat[id[j]].last_point.map)) < 0 || // no map are identical and with upper cases (not use strcasecmp)
- // if same map name, we sort by name.
- (cpm_result == 0 &&
- strcasecmp(char_dat[i].name,
- char_dat[id[j]].name) < 0))
- {
- for (k = players; k > j; k--)
- id[k] = id[k - 1];
- id[j] = i; // id[players]
- break;
- }
- }
- break;
- default: // 0 or invalid value: no sorting
- break;
- }
- players++;
- }
- }
-
// write files
- fp = fopen_(online_txt_filename, "w");
+ FILE *fp = fopen_(online_txt_filename, "w");
if (fp != NULL)
{
- fp2 = fopen_(online_html_filename, "w");
+ FILE *fp2 = fopen_(online_html_filename, "w");
if (fp2 != NULL)
{
// get time
@@ -927,14 +807,16 @@ void create_online_files(void)
FPRINTF(fp, "Online Players on %s (%s):\n", server_name, timetemp);
FPRINTF(fp, "\n");
- // If we display at least 1 player
- if (players > 0)
+ int players = 0;
+ // This used to be conditional on having any players,
+ // but this simplifies the logic.
+ //if (players > 0)
{
- j = 0; // count the number of characters for the txt version and to set the separate line
+ int j = 0; // count the number of characters for the txt version and to set the separate line
FPRINTF(fp2, " <table border=\"1\" cellspacing=\"1\">\n");
FPRINTF(fp2, " <tr>\n");
{
- FPRINTF(fp2, " <td><b>Name</b></td>\n");
+ FPRINTF(fp2, " <th>Name</th>\n");
{
FPRINTF(fp, "Name "); // 30
j += 30;
@@ -942,46 +824,49 @@ void create_online_files(void)
}
FPRINTF(fp2, " </tr>\n");
FPRINTF(fp, "\n");
- for (k = 0; k < j; k++)
+ for (int k = 0; k < j; k++)
FPRINTF(fp, "-");
FPRINTF(fp, "\n");
// display each player.
- for (i = 0; i < players; i++)
+ for (struct mmo_charstatus& cd : char_data)
{
- // get id of the character (more speed)
- j = id[i];
+ if (online_chars[&cd - &char_data.front()] == -1)
+ continue;
FPRINTF(fp2, " <tr>\n");
// displaying the character name
- { // without/with 'GM' display
- strcpy(temp, char_dat[j].name);
- l = isGM(char_dat[j].account_id);
+ {
+ // without/with 'GM' display
+ int gml = isGM(cd.account_id);
{
- if (l >= online_gm_display_min_level)
- FPRINTF(fp, "%-24s (GM) ", temp);
+ if (gml >= online_gm_display_min_level)
+ FPRINTF(fp, "%-24s (GM) ", cd.name);
else
- FPRINTF(fp, "%-24s ", temp);
+ FPRINTF(fp, "%-24s ", cd.name);
}
// name of the character in the html (no < >, because that create problem in html code)
FPRINTF(fp2, " <td>");
- if (l >= online_gm_display_min_level)
+ if (gml >= online_gm_display_min_level)
FPRINTF(fp2, "<b>");
- for (k = 0; temp[k]; k++)
+ for (int k = 0; cd.name[k]; k++)
{
- switch (temp[k])
+ switch (cd.name[k])
{
- case '<': // <
- FPRINTF(fp2, "&lt;");
- break;
- case '>': // >
- FPRINTF(fp2, "&gt;");
- break;
- default:
- FPRINTF(fp2, "%c", temp[k]);
- break;
+ case '&':
+ FPRINTF(fp2, "&amp;");
+ break;
+ case '<':
+ FPRINTF(fp2, "&lt;");
+ break;
+ case '>':
+ FPRINTF(fp2, "&gt;");
+ break;
+ default:
+ FPRINTF(fp2, "%c", cd.name[k]);
+ break;
};
}
- if (l >= online_gm_display_min_level)
+ if (gml >= online_gm_display_min_level)
FPRINTF(fp2, "</b> (GM)");
FPRINTF(fp2, "</td>\n");
}
@@ -997,10 +882,10 @@ void create_online_files(void)
{
FPRINTF(fp2, " <p>No user is online.</p>\n");
FPRINTF(fp, "No user is online.\n");
- // no display if only 1 player
}
else if (players == 1)
{
+ // no display if only 1 player
}
else
{
@@ -1037,10 +922,9 @@ int count_users(void)
// [Fate] Find inventory item based on equipment mask, return view. ID must match view ID (!).
//----------------------------------------
static
-int find_equip_view(struct mmo_charstatus *p, EPOS equipmask)
+int find_equip_view(const mmo_charstatus *p, EPOS equipmask)
{
- int i;
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (int i = 0; i < MAX_INVENTORY; i++)
if (p->inventory[i].nameid && p->inventory[i].amount
&& bool(p->inventory[i].equip & equipmask))
return p->inventory[i].nameid;
@@ -1053,38 +937,34 @@ int find_equip_view(struct mmo_charstatus *p, EPOS equipmask)
static
int mmo_char_send006b(int fd, struct char_session_data *sd)
{
- int i, j, found_num;
- struct mmo_charstatus *p;
- const int offset = 24;
-
- found_num = 0;
- for (i = 0; i < char_num; i++)
+ int found_num = 0;
+ std::array<const mmo_charstatus *, 9> found_char;
+ for (const mmo_charstatus& cd : char_data)
{
- if (char_dat[i].account_id == sd->account_id)
+ if (cd.account_id == sd->account_id)
{
- sd->found_char[found_num] = i;
+ found_char[found_num] = &cd;
found_num++;
if (found_num == 9)
break;
}
}
- for (i = found_num; i < 9; i++)
- sd->found_char[i] = -1;
+ const int offset = 24;
memset(WFIFOP(fd, 0), 0, offset + found_num * 106);
WFIFOW(fd, 0) = 0x6b;
WFIFOW(fd, 2) = offset + found_num * 106;
- for (i = 0; i < found_num; i++)
+ for (int i = 0; i < found_num; i++)
{
- p = &char_dat[sd->found_char[i]];
- j = offset + (i * 106); // increase speed of code
+ const mmo_charstatus *p = found_char[i];
+ int j = offset + (i * 106);
WFIFOL(fd, j) = p->char_id;
WFIFOL(fd, j + 4) = p->base_exp;
WFIFOL(fd, j + 8) = p->zeny;
WFIFOL(fd, j + 12) = p->job_exp;
- WFIFOL(fd, j + 16) = 0; //p->job_level; // [Fate] We no longer reveal this to the player, as its meaning is weird.
+ WFIFOL(fd, j + 16) = p->job_level;
WFIFOW(fd, j + 20) = find_equip_view(p, EPOS::SHOES);
WFIFOW(fd, j + 22) = find_equip_view(p, EPOS::GLOVES);
@@ -1134,16 +1014,13 @@ int mmo_char_send006b(int fd, struct char_session_data *sd)
static
int set_account_reg2(int acc, int num, struct global_reg *reg)
{
- int i, c;
-
- c = 0;
- for (i = 0; i < char_num; i++)
+ int c = 0;
+ for (mmo_charstatus& cd : char_data)
{
- if (char_dat[i].account_id == acc)
+ if (cd.account_id == acc)
{
- memcpy(char_dat[i].account_reg2, reg,
- sizeof(char_dat[i].account_reg2));
- char_dat[i].account_reg2_num = num;
+ memcpy(cd.account_reg2, reg, sizeof(cd.account_reg2));
+ cd.account_reg2_num = num;
c++;
}
}
@@ -1154,7 +1031,6 @@ int set_account_reg2(int acc, int num, struct global_reg *reg)
static
int char_divorce(struct mmo_charstatus *cs)
{
- int i;
uint8_t buf[10];
if (cs == NULL)
@@ -1172,20 +1048,20 @@ int char_divorce(struct mmo_charstatus *cs)
WBUFW(buf, 0) = 0x2b12;
WBUFL(buf, 2) = cs->char_id;
- for (i = 0; i < char_num; i++)
+ for (mmo_charstatus& cd : char_data)
{
- if (char_dat[i].char_id == cs->partner_id
- && char_dat[i].partner_id == cs->char_id)
+ if (cd.char_id == cs->partner_id
+ && cd.partner_id == cs->char_id)
{
WBUFL(buf, 6) = cs->partner_id;
mapif_sendall(buf, 10);
cs->partner_id = 0;
- char_dat[i].partner_id = 0;
+ cd.partner_id = 0;
return 0;
}
// The other char doesn't have us as their partner, so just clear our partner
// Don't worry about this, as the map server should verify itself that the other doesn't have us as a partner, and so won't mess with their marriage
- else if (char_dat[i].char_id == cs->partner_id)
+ else if (cd.char_id == cs->partner_id)
{
WBUFL(buf, 6) = cs->partner_id;
mapif_sendall(buf, 10);
@@ -1208,13 +1084,13 @@ int char_divorce(struct mmo_charstatus *cs)
static
int disconnect_player(int accound_id)
{
- int i;
- struct char_session_data *sd;
-
// disconnect player if online on char-server
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (sd = (struct char_session_data*)session[i]->session_data))
+ if (!session[i])
+ continue;
+ struct char_session_data *sd = static_cast<char_session_data *>(session[i]->session_data.get());
+ if (sd)
{
if (sd->account_id == accound_id)
{
@@ -1252,8 +1128,6 @@ int char_delete(struct mmo_charstatus *cs)
static
void parse_tologin(int fd)
{
- struct char_session_data *sd;
-
// only login-server can have an access to here.
// so, if it isn't the login-server, we disconnect the session (fd != login_fd).
if (fd != login_fd || session[fd]->eof)
@@ -1268,7 +1142,7 @@ void parse_tologin(int fd)
return;
}
- sd = (struct char_session_data*)session[fd]->session_data;
+ char_session_data *sd = static_cast<char_session_data *>(session[fd]->session_data.get());
while (RFIFOREST(fd) >= 2)
{
@@ -1309,8 +1183,10 @@ void parse_tologin(int fd)
// PRINTF("parse_tologin 2713 : %d\n", RFIFOB(fd,6));
for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (sd = (struct char_session_data*)session[i]->session_data)
- && sd->account_id == RFIFOL(fd, 2))
+ if (!session[i])
+ continue;
+ sd = static_cast<char_session_data *>(session[i]->session_data.get());
+ if (sd && sd->account_id == RFIFOL(fd, 2))
{
if (RFIFOB(fd, 6) != 0)
{
@@ -1352,7 +1228,10 @@ void parse_tologin(int fd)
return;
for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (sd = (struct char_session_data*)session[i]->session_data))
+ if (!session[i])
+ continue;
+ sd = static_cast<char_session_data *>(session[i]->session_data.get());
+ if (sd)
{
if (sd->account_id == RFIFOL(fd, 2))
{
@@ -1385,31 +1264,30 @@ void parse_tologin(int fd)
if (RFIFOREST(fd) < 7)
return;
{
- int acc, sex, i, j;
unsigned char buf[7];
- acc = RFIFOL(fd, 2);
- sex = RFIFOB(fd, 6);
+ int acc = RFIFOL(fd, 2);
+ int sex = RFIFOB(fd, 6);
RFIFOSKIP(fd, 7);
if (acc > 0)
{
- for (i = 0; i < char_num; i++)
+ for (struct mmo_charstatus& cd : char_data)
{
- if (char_dat[i].account_id == acc)
+ if (cd.account_id == acc)
{
- char_dat[i].sex = sex;
+ cd.sex = sex;
// auth_fifo[i].sex = sex;
// to avoid any problem with equipment and invalid sex, equipment is unequiped.
- for (j = 0; j < MAX_INVENTORY; j++)
+ for (int j = 0; j < MAX_INVENTORY; j++)
{
- if (char_dat[i].inventory[j].nameid
- && bool(char_dat[i].inventory[j].equip))
- char_dat[i].inventory[j].equip = EPOS::ZERO;
+ if (cd.inventory[j].nameid
+ && bool(cd.inventory[j].equip))
+ cd.inventory[j].equip = EPOS::ZERO;
}
- char_dat[i].weapon = ItemLook::NONE;
- char_dat[i].shield = 0;
- char_dat[i].head_top = 0;
- char_dat[i].head_mid = 0;
- char_dat[i].head_bottom = 0;
+ cd.weapon = ItemLook::NONE;
+ cd.shield = 0;
+ cd.head_top = 0;
+ cd.head_mid = 0;
+ cd.head_bottom = 0;
}
}
// disconnect player if online on char-server
@@ -1522,9 +1400,9 @@ void parse_tologin(int fd)
WBUFL(buf, 6) = dest_id;
mapif_sendall(buf, 10); // forward package to map servers
- for (int i = 0; i < char_num; i++)
+ for (struct mmo_charstatus& cd : char_data)
{
- struct mmo_charstatus *c = char_dat + i;
+ struct mmo_charstatus *c = &cd;
struct storage *s = account2storage(c->account_id);
int changes = 0;
int j;
@@ -1561,47 +1439,25 @@ void parse_tologin(int fd)
if (RFIFOREST(fd) < 6)
return;
// Deletion of all characters of the account
- for (int i = 0; i < char_num; i++)
+#warning "This comment is a lie, but it's still true."
+ // needs to use index because they may move during resize
+ for (int idx = 0; idx < char_data.size(); idx++)
{
- if (char_dat[i].account_id == RFIFOL(fd, 2))
+ mmo_charstatus& cd = char_data[idx];
+ if (cd.account_id == RFIFOL(fd, 2))
{
- char_delete(&char_dat[i]);
- if (i < char_num - 1)
+ char_delete(&cd);
+ if (&cd != &char_data.back())
{
- memcpy(&char_dat[i], &char_dat[char_num - 1],
- sizeof(struct mmo_charstatus));
+ std::swap(cd, char_data.back());
// if moved character owns to deleted account, check again it's character
- if (char_dat[i].account_id == RFIFOL(fd, 2))
+ if (cd.account_id == RFIFOL(fd, 2))
{
- i--;
+ idx--;
// Correct moved character reference in the character's owner by [Yor]
}
- else
- {
- int j, k;
- struct char_session_data *sd2;
- for (j = 0; j < fd_max; j++)
- {
- if (session[j]
- && (sd2 = (struct char_session_data*)session[j]->session_data)
- && sd2->account_id ==
- char_dat[char_num - 1].account_id)
- {
- for (k = 0; k < 9; k++)
- {
- if (sd2->found_char[k] ==
- char_num - 1)
- {
- sd2->found_char[k] = i;
- break;
- }
- }
- break;
- }
- }
- }
}
- char_num--;
+ char_data.pop_back();
}
}
// Deletion of the storage
@@ -1642,21 +1498,16 @@ void parse_tologin(int fd)
return;
{
uint8_t buf[32000];
- if (gm_account != NULL)
- free(gm_account);
- CREATE(gm_account, struct gm_account, (RFIFOW(fd, 2) - 4) / 5);
- GM_num = 0;
+ gm_accounts.clear();
+ gm_accounts.resize((RFIFOW(fd, 2) - 4) / 5);
for (int i = 4; i < RFIFOW(fd, 2); i = i + 5)
{
- gm_account[GM_num].account_id = RFIFOL(fd, i);
- gm_account[GM_num].level = (int) RFIFOB(fd, i + 4);
- //PRINTF("GM account: %d -> level %d\n", gm_account[GM_num].account_id, gm_account[GM_num].level);
- GM_num++;
+ gm_accounts.push_back({(int) RFIFOL(fd, i), (int) RFIFOB(fd, i + 4)});
}
- PRINTF("From login-server: receiving of %d GM accounts information.\n",
- GM_num);
- CHAR_LOG("From login-server: receiving of %d GM accounts information.\n",
- GM_num);
+ PRINTF("From login-server: receiving of %zu GM accounts information.\n",
+ gm_accounts.size());
+ CHAR_LOG("From login-server: receiving of %zu GM accounts information.\n",
+ gm_accounts.size());
create_online_files(); // update online players files (perhaps some online players change of GM level)
// send new gm acccounts level to map-servers
memcpy(buf, RFIFOP(fd, 0), RFIFOW(fd, 2));
@@ -1676,7 +1527,10 @@ void parse_tologin(int fd)
for (i = 0; i < fd_max; i++)
{
- if (session[i] && (sd = (struct char_session_data*)session[i]->session_data))
+ if (!session[i])
+ continue;
+ sd = static_cast<char_session_data *>(session[i]->session_data.get());
+ if (sd)
{
if (sd->account_id == acc)
{
@@ -1727,9 +1581,7 @@ void map_anti_freeze_system(TimerData *, tick_t)
static
void parse_frommap(int fd)
{
- int i, j;
int id;
-
for (id = 0; id < MAX_MAP_SERVERS; id++)
if (server_fd[id] == fd)
break;
@@ -1741,9 +1593,9 @@ void parse_frommap(int fd)
fd);
memset(&server[id], 0, sizeof(struct mmo_map_server));
server_fd[id] = -1;
- for (j = 0; j < char_num; j++)
- if (online_chars[j] == fd)
- online_chars[j] = -1;
+ for (int& oci : online_chars)
+ if (oci == fd)
+ oci = -1;
create_online_files(); // update online players files (to remove all online players of this server)
}
delete_session(fd);
@@ -1771,9 +1623,10 @@ void parse_frommap(int fd)
case 0x2afa:
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd, 2))
return;
+ {
memset(server[id].map, 0, sizeof(server[id].map));
- j = 0;
- for (i = 4; i < RFIFOW(fd, 2); i += 16)
+ int j = 0;
+ for (int i = 4; i < RFIFOW(fd, 2); i += 16)
{
memcpy(server[id].map[j], RFIFOP(fd, i), 16);
// PRINTF("set map %d.%d : %s\n", id, j, server[id].map[j]);
@@ -1794,7 +1647,6 @@ void parse_frommap(int fd)
WFIFOSET(fd, 27);
{
unsigned char buf[16384];
- int x;
if (j == 0)
{
PRINTF("WARNING: Map-Server %d have NO map.\n", id);
@@ -1812,7 +1664,7 @@ void parse_frommap(int fd)
mapif_sendallwos(fd, buf, WBUFW(buf, 2));
}
// Transmitting the maps of the other map-servers to the new map-server
- for (x = 0; x < MAX_MAP_SERVERS; x++)
+ for (int x = 0; x < MAX_MAP_SERVERS; x++)
{
if (server_fd[x] >= 0 && x != id)
{
@@ -1820,7 +1672,7 @@ void parse_frommap(int fd)
WFIFOL(fd, 4) = server[x].ip;
WFIFOW(fd, 8) = server[x].port;
j = 0;
- for (i = 0; i < MAX_MAP_PER_SERVER; i++)
+ for (int i = 0; i < MAX_MAP_PER_SERVER; i++)
if (server[x].map[i][0])
memcpy(WFIFOP(fd, 10 + (j++) * 16),
server[x].map[i], 16);
@@ -1832,6 +1684,7 @@ void parse_frommap(int fd)
}
}
}
+ }
RFIFOSKIP(fd, RFIFOW(fd, 2));
break;
@@ -1840,37 +1693,42 @@ void parse_frommap(int fd)
if (RFIFOREST(fd) < 22)
return;
//PRINTF("auth_fifo search: account: %d, char: %d, secure: %08x-%08x\n", RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14));
- for (i = 0; i < AUTH_FIFO_SIZE; i++)
+ for (AuthFifoEntry& afi : auth_fifo)
{
- if (auth_fifo[i].account_id == RFIFOL(fd, 2) &&
- auth_fifo[i].char_id == RFIFOL(fd, 6) &&
- auth_fifo[i].login_id1 == RFIFOL(fd, 10) &&
+ if (afi.account_id == RFIFOL(fd, 2) &&
+ afi.char_id == RFIFOL(fd, 6) &&
+ afi.login_id1 == RFIFOL(fd, 10) &&
// here, it's the only area where it's possible that we doesn't know login_id2 (map-server asks just after 0x72 packet, that doesn't given the value)
- (auth_fifo[i].login_id2 == RFIFOL(fd, 14) || RFIFOL(fd, 14) == 0) && // relate to the versions higher than 18
- (!check_ip_flag || auth_fifo[i].ip == RFIFOL(fd, 18))
- && !auth_fifo[i].delflag)
+ (afi.login_id2 == RFIFOL(fd, 14) || RFIFOL(fd, 14) == 0) && // relate to the versions higher than 18
+ (!check_ip_flag || afi.ip == RFIFOL(fd, 18))
+ && !afi.delflag)
{
- auth_fifo[i].delflag = 1;
+ mmo_charstatus *cd = nullptr;
+ for (mmo_charstatus& cdi : char_data)
+ {
+ if (cdi.char_id == afi.char_id)
+ break;
+ }
+ assert (cd && "uh-oh - deleted while in queue?");
+ afi.delflag = 1;
WFIFOW(fd, 0) = 0x2afd;
WFIFOW(fd, 2) = 18 + sizeof(struct mmo_charstatus);
WFIFOL(fd, 4) = RFIFOL(fd, 2);
- WFIFOL(fd, 8) = auth_fifo[i].login_id2;
- WFIFOL(fd, 12) = static_cast<time_t>(auth_fifo[i].connect_until_time);
- char_dat[auth_fifo[i].char_pos].sex =
- auth_fifo[i].sex;
- WFIFOW(fd, 16) = auth_fifo[i].packet_tmw_version;
+ WFIFOL(fd, 8) = afi.login_id2;
+ WFIFOL(fd, 12) = static_cast<time_t>(afi.connect_until_time);
+ cd->sex = afi.sex;
+ WFIFOW(fd, 16) = afi.packet_tmw_version;
FPRINTF(stderr,
- "From queue index %d: recalling packet version %d\n",
- i, auth_fifo[i].packet_tmw_version);
+ "From queue index %zd: recalling packet version %d\n",
+ (&afi - &auth_fifo.front()), afi.packet_tmw_version);
memcpy(WFIFOP(fd, 18),
- &char_dat[auth_fifo[i].char_pos],
+ cd,
sizeof(struct mmo_charstatus));
WFIFOSET(fd, WFIFOW(fd, 2));
//PRINTF("auth_fifo search success (auth #%d, account %d, character: %d).\n", i, RFIFOL(fd,2), RFIFOL(fd,6));
- break;
+ goto x2afc_out;
}
}
- if (i == AUTH_FIFO_SIZE)
{
WFIFOW(fd, 0) = 0x2afe;
WFIFOL(fd, 2) = RFIFOL(fd, 2);
@@ -1878,6 +1736,7 @@ void parse_frommap(int fd)
PRINTF("auth_fifo search error! account %d not authentified.\n",
RFIFOL(fd, 2));
}
+ x2afc_out:
RFIFOSKIP(fd, 22);
break;
@@ -1889,18 +1748,17 @@ void parse_frommap(int fd)
if (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 (i = 0; i < char_num; i++)
- if (online_chars[i] == id)
- online_chars[i] = -1;
+ for (int& oci : online_chars)
+ if (oci == id)
+ oci = -1;
// add online players in the list by [Yor]
- for (i = 0; i < server[id].users; i++)
+ for (int i = 0; i < server[id].users; i++)
{
int char_id = RFIFOL(fd, 6 + i * 4);
- for (j = 0; j < char_num; j++)
- if (char_dat[j].char_id == char_id)
+ for (const mmo_charstatus& cd : char_data)
+ if (cd.char_id == char_id)
{
- online_chars[j] = id;
- //PRINTF("%d\n", char_id);
+ online_chars[&cd - &char_data.front()] = id;
break;
}
}
@@ -1912,22 +1770,22 @@ void parse_frommap(int fd)
// only every 8 sec. (normally, 1 server send users every 5 sec.) Don't update every time, because that takes time, but only every 2 connection.
// it set to 8 sec because is more than 5 (sec) and if we have more than 1 map-server, informations can be received in shifted.
}
- RFIFOSKIP(fd, 6 + i * 4);
+ RFIFOSKIP(fd, RFIFOW(fd, 2));
break;
// キャラデータ保存
case 0x2b01:
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd, 2))
return;
- for (i = 0; i < char_num; i++)
+ for (mmo_charstatus& cd : char_data)
{
- if (char_dat[i].account_id == RFIFOL(fd, 4) &&
- char_dat[i].char_id == RFIFOL(fd, 8))
+ if (cd.account_id == RFIFOL(fd, 4) &&
+ cd.char_id == RFIFOL(fd, 8))
+ {
+ memcpy(&cd, RFIFOP(fd, 12), sizeof(struct mmo_charstatus));
break;
+ }
}
- if (i != char_num)
- memcpy(&char_dat[i], RFIFOP(fd, 12),
- sizeof(struct mmo_charstatus));
RFIFOSKIP(fd, RFIFOW(fd, 2));
break;
@@ -1935,18 +1793,16 @@ void parse_frommap(int fd)
case 0x2b02:
if (RFIFOREST(fd) < 18)
return;
- if (auth_fifo_pos >= AUTH_FIFO_SIZE)
- auth_fifo_pos = 0;
- //PRINTF("auth_fifo set (auth #%d) - account: %d, secure: %08x-%08x\n", auth_fifo_pos, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10));
- auth_fifo[auth_fifo_pos].account_id = RFIFOL(fd, 2);
- auth_fifo[auth_fifo_pos].char_id = 0;
- auth_fifo[auth_fifo_pos].login_id1 = RFIFOL(fd, 6);
- auth_fifo[auth_fifo_pos].login_id2 = RFIFOL(fd, 10);
- auth_fifo[auth_fifo_pos].delflag = 2;
- auth_fifo[auth_fifo_pos].char_pos = 0;
- auth_fifo[auth_fifo_pos].connect_until_time = TimeT(); // unlimited/unknown time by default (not display in map-server)
- auth_fifo[auth_fifo_pos].ip = RFIFOL(fd, 14);
- auth_fifo_pos++;
+ if (auth_fifo_iter == auth_fifo.end())
+ auth_fifo_iter = auth_fifo.begin();
+ auth_fifo_iter->account_id = RFIFOL(fd, 2);
+ auth_fifo_iter->char_id = 0;
+ auth_fifo_iter->login_id1 = RFIFOL(fd, 6);
+ auth_fifo_iter->login_id2 = RFIFOL(fd, 10);
+ auth_fifo_iter->delflag = 2;
+ auth_fifo_iter->connect_until_time = TimeT(); // unlimited/unknown time by default (not display in map-server)
+ auth_fifo_iter->ip = RFIFOL(fd, 14);
+ auth_fifo_iter++;
WFIFOW(fd, 0) = 0x2b03;
WFIFOL(fd, 2) = RFIFOL(fd, 2);
WFIFOB(fd, 6) = 0;
@@ -1958,30 +1814,29 @@ void parse_frommap(int fd)
case 0x2b05:
if (RFIFOREST(fd) < 49)
return;
- if (auth_fifo_pos >= AUTH_FIFO_SIZE)
- auth_fifo_pos = 0;
+ if (auth_fifo_iter == auth_fifo.end())
+ auth_fifo_iter = auth_fifo.begin();
WFIFOW(fd, 0) = 0x2b06;
memcpy(WFIFOP(fd, 2), RFIFOP(fd, 2), 42);
- //PRINTF("auth_fifo set (auth#%d) - account: %d, secure: 0x%08x-0x%08x\n", auth_fifo_pos, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10));
- auth_fifo[auth_fifo_pos].account_id = RFIFOL(fd, 2);
- auth_fifo[auth_fifo_pos].char_id = RFIFOL(fd, 14);
- auth_fifo[auth_fifo_pos].login_id1 = RFIFOL(fd, 6);
- auth_fifo[auth_fifo_pos].login_id2 = RFIFOL(fd, 10);
- auth_fifo[auth_fifo_pos].delflag = 0;
- auth_fifo[auth_fifo_pos].sex = RFIFOB(fd, 44);
- auth_fifo[auth_fifo_pos].connect_until_time = TimeT(); // unlimited/unknown time by default (not display in map-server)
- auth_fifo[auth_fifo_pos].ip = RFIFOL(fd, 45);
- for (i = 0; i < char_num; i++)
- if (char_dat[i].account_id == RFIFOL(fd, 2) &&
- char_dat[i].char_id == RFIFOL(fd, 14))
+ auth_fifo_iter->account_id = RFIFOL(fd, 2);
+ auth_fifo_iter->char_id = RFIFOL(fd, 14);
+ auth_fifo_iter->login_id1 = RFIFOL(fd, 6);
+ auth_fifo_iter->login_id2 = RFIFOL(fd, 10);
+ auth_fifo_iter->delflag = 0;
+ auth_fifo_iter->sex = RFIFOB(fd, 44);
+ auth_fifo_iter->connect_until_time = TimeT(); // unlimited/unknown time by default (not display in map-server)
+ auth_fifo_iter->ip = RFIFOL(fd, 45);
+
+ // default, if not found in the loop
+ WFIFOW(fd, 6) = 1;
+ for (const mmo_charstatus& cd : char_data)
+ if (cd.account_id == RFIFOL(fd, 2) &&
+ cd.char_id == RFIFOL(fd, 14))
{
- auth_fifo[auth_fifo_pos].char_pos = i;
- auth_fifo_pos++;
+ auth_fifo_iter++;
WFIFOL(fd, 6) = 0;
break;
}
- if (i == char_num)
- WFIFOW(fd, 6) = 1;
WFIFOSET(fd, 44);
RFIFOSKIP(fd, 49);
break;
@@ -1990,18 +1845,21 @@ void parse_frommap(int fd)
case 0x2b08:
if (RFIFOREST(fd) < 6)
return;
- for (i = 0; i < char_num; i++)
+ {
+ const char (*name)[24] = &unknown_char_name;
+ for (const mmo_charstatus& cd : char_data)
{
- if (char_dat[i].char_id == RFIFOL(fd, 2))
+ if (cd.char_id == RFIFOL(fd, 2))
+ {
+ name = &cd.name;
break;
+ }
}
WFIFOW(fd, 0) = 0x2b09;
WFIFOL(fd, 2) = RFIFOL(fd, 2);
- if (i != char_num)
- memcpy(WFIFOP(fd, 6), char_dat[i].name, 24);
- else
- memcpy(WFIFOP(fd, 6), unknown_char_name, 24);
+ memcpy(WFIFOP(fd, 6), *name, 24);
WFIFOSET(fd, 30);
+ }
RFIFOSKIP(fd, 6);
break;
@@ -2047,32 +1905,30 @@ void parse_frommap(int fd)
{
char character_name[24];
int acc = RFIFOL(fd, 2); // account_id of who ask (-1 if nobody)
- memcpy(character_name, RFIFOP(fd, 6), 24);
- character_name[sizeof(character_name) - 1] = '\0';
+ strzcpy(character_name, static_cast<const char *>(RFIFOP(fd, 6)), 24);
// prepare answer
WFIFOW(fd, 0) = 0x2b0f; // answer
WFIFOL(fd, 2) = acc; // who want do operation
WFIFOW(fd, 30) = RFIFOW(fd, 30); // type of operation: 1-block, 2-ban, 3-unblock, 4-unban, 5-changesex
// search character
- i = search_character_index(character_name);
- if (i >= 0)
+ const mmo_charstatus *cd = search_character(character_name);
+ if (cd)
{
- memcpy(WFIFOP(fd, 6), search_character_name(i), 24); // put correct name if found
+ memcpy(WFIFOP(fd, 6), cd->name, 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))
{
case 1: // block
if (acc == -1
- || isGM(acc) >=
- isGM(char_dat[i].account_id))
+ || isGM(acc) >= isGM(cd->account_id))
{
if (login_fd > 0)
{ // don't send request if no login-server
WFIFOW(login_fd, 0) = 0x2724;
- WFIFOL(login_fd, 2) = char_dat[i].account_id; // account value
+ WFIFOL(login_fd, 2) = cd->account_id; // account value
WFIFOL(login_fd, 6) = 5; // status of the account
WFIFOSET(login_fd, 10);
-// PRINTF("char : status -> login: account %d, status: %d \n", char_dat[i].account_id, 5);
+// PRINTF("char : status -> login: account %d, status: %d \n", char_data[i].account_id, 5);
}
else
WFIFOW(fd, 32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
@@ -2082,13 +1938,12 @@ void parse_frommap(int fd)
break;
case 2: // ban
if (acc == -1
- || isGM(acc) >=
- isGM(char_dat[i].account_id))
+ || isGM(acc) >= isGM(cd->account_id))
{
if (login_fd > 0)
{ // don't send request if no login-server
WFIFOW(login_fd, 0) = 0x2725;
- WFIFOL(login_fd, 2) = char_dat[i].account_id; // account value
+ 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
@@ -2097,7 +1952,7 @@ void parse_frommap(int fd)
WFIFOW(login_fd, 16) = RFIFOW(fd, 42); // second
WFIFOSET(login_fd, 18);
// PRINTF("char : status -> login: account %d, ban: %dy %dm %dd %dh %dmn %ds\n",
-// char_dat[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));
+// 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));
}
else
WFIFOW(fd, 32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
@@ -2107,16 +1962,15 @@ void parse_frommap(int fd)
break;
case 3: // unblock
if (acc == -1
- || isGM(acc) >=
- isGM(char_dat[i].account_id))
+ || isGM(acc) >= isGM(cd->account_id))
{
if (login_fd > 0)
{ // don't send request if no login-server
WFIFOW(login_fd, 0) = 0x2724;
- WFIFOL(login_fd, 2) = char_dat[i].account_id; // account value
+ WFIFOL(login_fd, 2) = cd->account_id; // account value
WFIFOL(login_fd, 6) = 0; // status of the account
WFIFOSET(login_fd, 10);
-// PRINTF("char : status -> login: account %d, status: %d \n", char_dat[i].account_id, 0);
+// PRINTF("char : status -> login: account %d, status: %d \n", char_data[i].account_id, 0);
}
else
WFIFOW(fd, 32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
@@ -2126,15 +1980,14 @@ void parse_frommap(int fd)
break;
case 4: // unban
if (acc == -1
- || isGM(acc) >=
- isGM(char_dat[i].account_id))
+ || isGM(acc) >= isGM(cd->account_id))
{
if (login_fd > 0)
{ // don't send request if no login-server
WFIFOW(login_fd, 0) = 0x272a;
- WFIFOL(login_fd, 2) = char_dat[i].account_id; // account value
+ WFIFOL(login_fd, 2) = cd->account_id; // account value
WFIFOSET(login_fd, 6);
-// PRINTF("char : status -> login: account %d, unban request\n", char_dat[i].account_id);
+// PRINTF("char : status -> login: account %d, unban request\n", char_data[i].account_id);
}
else
WFIFOW(fd, 32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
@@ -2144,15 +1997,14 @@ void parse_frommap(int fd)
break;
case 5: // changesex
if (acc == -1
- || isGM(acc) >=
- isGM(char_dat[i].account_id))
+ || isGM(acc) >= isGM(cd->account_id))
{
if (login_fd > 0)
{ // don't send request if no login-server
WFIFOW(login_fd, 0) = 0x2727;
- WFIFOL(login_fd, 2) = char_dat[i].account_id; // account value
+ WFIFOL(login_fd, 2) = cd->account_id; // account value
WFIFOSET(login_fd, 6);
-// PRINTF("char : status -> login: account %d, change sex request\n", char_dat[i].account_id);
+// PRINTF("char : status -> login: account %d, change sex request\n", char_data[i].account_id);
}
else
WFIFOW(fd, 32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
@@ -2185,8 +2037,8 @@ void parse_frommap(int fd)
return;
{
struct global_reg reg[ACCOUNT_REG2_NUM];
- int p, acc;
- acc = RFIFOL(fd, 4);
+ int p, j;
+ int acc = RFIFOL(fd, 4);
for (p = 8, j = 0;
p < RFIFOW(fd, 2) && j < ACCOUNT_REG2_NUM;
p += 36, j++)
@@ -2217,12 +2069,12 @@ void parse_frommap(int fd)
if (RFIFOREST(fd) < 4)
return;
{
- for (i = 0; i < char_num; i++)
- if (char_dat[i].char_id == RFIFOL(fd, 2))
+ for (mmo_charstatus& cd : char_data)
+ if (cd.char_id == RFIFOL(fd, 2))
+ {
+ char_divorce(&cd);
break;
-
- if (i != char_num)
- char_divorce(&char_dat[i]);
+ }
RFIFOSKIP(fd, 6);
break;
@@ -2305,30 +2157,23 @@ void handle_x0066(int fd, struct char_session_data *sd, uint8_t rfifob_2, uint8_
{
const char *ip = ip2str(session[fd]->client_addr.sin_addr);
- // if we activated email creation and email is default email
- if (email_creation != 0 && strcmp(sd->email, "a@a.com") == 0
- && login_fd > 0)
- { // to modify an e-mail, login-server must be online
- WFIFOW(fd, 0) = 0x70;
- WFIFOB(fd, 2) = 0; // 00 = Incorrect Email address
- WFIFOSET(fd, 3);
-
- // otherwise, load the character
- }
- else
{
- int ch;
- for (ch = 0; ch < 9; ch++)
- if (sd->found_char[ch] >= 0
- && char_dat[sd->found_char[ch]].char_num == rfifob_2)
+ mmo_charstatus *cd = nullptr;
+ for (mmo_charstatus& cdi : char_data)
+ {
+ if (cdi.account_id == sd->account_id && cdi.char_num == rfifob_2)
+ {
+ cd = &cdi;
break;
- if (ch != 9)
+ }
+ }
+ if (cd)
{
CHAR_LOG("Character Selected, Account ID: %d, Character Slot: %d, Character Name: %s [%s]\n",
sd->account_id, rfifob_2,
- char_dat[sd->found_char[ch]].name, ip);
+ cd->name, ip);
// searching map server
- int i = search_mapserver(char_dat[sd->found_char[ch]].last_point.map);
+ int i = search_mapserver(cd->last_point.map);
// if map is not found, we check major cities
if (i < 0)
{
@@ -2340,7 +2185,7 @@ void handle_x0066(int fd, struct char_session_data *sd, uint8_t rfifob_2, uint8_
&& server[j].map[0][0])
{ // change save point to one of map found on the server (the first)
i = j;
- memcpy(char_dat[sd->found_char[ch]].last_point.map,
+ memcpy(cd->last_point.map,
server[j].map[0], 16);
PRINTF("Map-server #%d found with a map: '%s'.\n",
j, server[j].map[0]);
@@ -2357,13 +2202,13 @@ void handle_x0066(int fd, struct char_session_data *sd, uint8_t rfifob_2, uint8_
}
}
WFIFOW(fd, 0) = 0x71;
- WFIFOL(fd, 2) = char_dat[sd->found_char[ch]].char_id;
+ WFIFOL(fd, 2) = cd->char_id;
memcpy(WFIFOP(fd, 6),
- char_dat[sd->found_char[ch]].last_point.map,
+ cd->last_point.map,
16);
PRINTF("Character selection '%s' (account: %d, slot: %d) [%s]\n",
- char_dat[sd->found_char[ch]].name,
- sd->account_id, ch, ip);
+ cd->name,
+ 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);
@@ -2371,25 +2216,18 @@ void handle_x0066(int fd, struct char_session_data *sd, uint8_t rfifob_2, uint8_
WFIFOL(fd, 22) = server[i].ip;
WFIFOW(fd, 26) = server[i].port;
WFIFOSET(fd, 28);
- if (auth_fifo_pos >= AUTH_FIFO_SIZE)
- auth_fifo_pos = 0;
- //PRINTF("auth_fifo set #%d - account %d, char: %d, secure: %08x-%08x\n", auth_fifo_pos, sd->account_id, char_dat[sd->found_char[ch]].char_id, sd->login_id1, sd->login_id2);
- auth_fifo[auth_fifo_pos].account_id = sd->account_id;
- auth_fifo[auth_fifo_pos].char_id =
- char_dat[sd->found_char[ch]].char_id;
- auth_fifo[auth_fifo_pos].login_id1 = sd->login_id1;
- auth_fifo[auth_fifo_pos].login_id2 = sd->login_id2;
- auth_fifo[auth_fifo_pos].delflag = 0;
- auth_fifo[auth_fifo_pos].char_pos =
- sd->found_char[ch];
- auth_fifo[auth_fifo_pos].sex = sd->sex;
- auth_fifo[auth_fifo_pos].connect_until_time =
- sd->connect_until_time;
- auth_fifo[auth_fifo_pos].ip =
- session[fd]->client_addr.sin_addr.s_addr;
- auth_fifo[auth_fifo_pos].packet_tmw_version =
- sd->packet_tmw_version;
- auth_fifo_pos++;
+ if (auth_fifo_iter == auth_fifo.end())
+ auth_fifo_iter = auth_fifo.begin();
+ auth_fifo_iter->account_id = sd->account_id;
+ auth_fifo_iter->char_id = cd->char_id;
+ auth_fifo_iter->login_id1 = sd->login_id1;
+ auth_fifo_iter->login_id2 = sd->login_id2;
+ auth_fifo_iter->delflag = 0;
+ auth_fifo_iter->sex = sd->sex;
+ auth_fifo_iter->connect_until_time = sd->connect_until_time;
+ auth_fifo_iter->ip = session[fd]->client_addr.sin_addr.s_addr;
+ auth_fifo_iter->packet_tmw_version = sd->packet_tmw_version;
+ auth_fifo_iter++;
}
}
}
@@ -2397,9 +2235,7 @@ void handle_x0066(int fd, struct char_session_data *sd, uint8_t rfifob_2, uint8_
static
void parse_char(int fd)
{
- int i, ch;
char email[40];
- struct char_session_data *sd;
unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
if (login_fd < 0 || session[fd]->eof)
@@ -2410,7 +2246,7 @@ void parse_char(int fd)
return;
}
- sd = (struct char_session_data*)session[fd]->session_data;
+ char_session_data *sd = static_cast<char_session_data *>(session[fd]->session_data.get());
while (RFIFOREST(fd) >= 2)
{
@@ -2442,17 +2278,17 @@ void parse_char(int fd)
if (RFIFOREST(fd) < 17)
return;
{
- int GM_value;
- if ((GM_value = isGM(RFIFOL(fd, 2))))
+ int GM_value = isGM(RFIFOL(fd, 2));
+ if (GM_value)
PRINTF("Account Logged On; Account ID: %d (GM level %d).\n",
- RFIFOL(fd, 2), GM_value);
+ RFIFOL(fd, 2), GM_value);
else
PRINTF("Account Logged On; Account ID: %d.\n",
RFIFOL(fd, 2));
if (sd == NULL)
{
- CREATE(sd, struct char_session_data, 1);
- session[fd]->session_data = sd;
+ sd = new char_session_data();
+ session[fd]->session_data.reset(sd);
memcpy(sd->email, "no mail", 40); // 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)
}
@@ -2465,17 +2301,16 @@ void parse_char(int fd)
WFIFOL(fd, 0) = RFIFOL(fd, 2);
WFIFOSET(fd, 4);
// search authentification
- for (i = 0; i < AUTH_FIFO_SIZE; i++)
+ for (AuthFifoEntry& afi : auth_fifo)
{
- if (auth_fifo[i].account_id == sd->account_id &&
- auth_fifo[i].login_id1 == sd->login_id1 &&
- auth_fifo[i].login_id2 == sd->login_id2 && // relate to the versions higher than 18
- (!check_ip_flag
- || auth_fifo[i].ip ==
- session[fd]->client_addr.sin_addr.s_addr)
- && auth_fifo[i].delflag == 2)
+ if (afi.account_id == sd->account_id
+ && afi.login_id1 == sd->login_id1
+ && afi.login_id2 == sd->login_id2
+ && (!check_ip_flag
+ || afi.ip == session[fd]->client_addr.sin_addr.s_addr)
+ && afi.delflag == 2)
{
- auth_fifo[i].delflag = 1;
+ afi.delflag = 1;
if (max_connect_user == 0
|| count_users() < max_connect_user)
{
@@ -2487,7 +2322,7 @@ void parse_char(int fd)
WFIFOSET(login_fd, 6);
}
// Record client version
- auth_fifo[i].packet_tmw_version =
+ afi.packet_tmw_version =
sd->packet_tmw_version;
// send characters to player
mmo_char_send006b(fd, sd);
@@ -2499,14 +2334,14 @@ void parse_char(int fd)
WFIFOB(fd, 2) = 0;
WFIFOSET(fd, 3);
}
- break;
+ goto x65_out;
}
}
// authentification not found
- if (i == AUTH_FIFO_SIZE)
{
if (login_fd > 0)
- { // don't send request if no login-server
+ {
+ // don't send request if no login-server
WFIFOW(login_fd, 0) = 0x2712; // ask login-server to authentify an account
WFIFOL(login_fd, 2) = sd->account_id;
WFIFOL(login_fd, 6) = sd->login_id1;
@@ -2524,6 +2359,7 @@ void parse_char(int fd)
}
}
}
+ x65_out:
RFIFOSKIP(fd, 17);
break;
@@ -2537,8 +2373,9 @@ void parse_char(int fd)
case 0x67: // 作成
if (!sd || RFIFOREST(fd) < 37)
return;
- i = make_new_char(fd, static_cast<const uint8_t *>(RFIFOP(fd, 2)));
- if (i < 0)
+ {
+ const struct mmo_charstatus *cd = make_new_char(fd, static_cast<const uint8_t *>(RFIFOP(fd, 2)));
+ if (!cd)
{
WFIFOW(fd, 0) = 0x6e;
WFIFOB(fd, 2) = 0x00;
@@ -2550,58 +2387,45 @@ void parse_char(int fd)
WFIFOW(fd, 0) = 0x6d;
memset(WFIFOP(fd, 2), 0, 106);
- WFIFOL(fd, 2) = char_dat[i].char_id;
- WFIFOL(fd, 2 + 4) = char_dat[i].base_exp;
- WFIFOL(fd, 2 + 8) = char_dat[i].zeny;
- WFIFOL(fd, 2 + 12) = char_dat[i].job_exp;
- WFIFOL(fd, 2 + 16) = char_dat[i].job_level;
+ WFIFOL(fd, 2) = cd->char_id;
+ WFIFOL(fd, 2 + 4) = cd->base_exp;
+ WFIFOL(fd, 2 + 8) = cd->zeny;
+ WFIFOL(fd, 2 + 12) = cd->job_exp;
+ WFIFOL(fd, 2 + 16) = cd->job_level;
- WFIFOL(fd, 2 + 28) = char_dat[i].karma;
- WFIFOL(fd, 2 + 32) = char_dat[i].manner;
+ WFIFOL(fd, 2 + 28) = cd->karma;
+ WFIFOL(fd, 2 + 32) = cd->manner;
WFIFOW(fd, 2 + 40) = 0x30;
- WFIFOW(fd, 2 + 42) =
- (char_dat[i].hp > 0x7fff) ? 0x7fff : char_dat[i].hp;
- WFIFOW(fd, 2 + 44) =
- (char_dat[i].max_hp >
- 0x7fff) ? 0x7fff : char_dat[i].max_hp;
- WFIFOW(fd, 2 + 46) =
- (char_dat[i].sp > 0x7fff) ? 0x7fff : char_dat[i].sp;
- WFIFOW(fd, 2 + 48) =
- (char_dat[i].max_sp >
- 0x7fff) ? 0x7fff : char_dat[i].max_sp;
- WFIFOW(fd, 2 + 50) = static_cast<uint16_t>(DEFAULT_WALK_SPEED.count()); // char_dat[i].speed;
- WFIFOW(fd, 2 + 52) = char_dat[i].species;
- WFIFOW(fd, 2 + 54) = char_dat[i].hair;
-
- WFIFOW(fd, 2 + 58) = char_dat[i].base_level;
- WFIFOW(fd, 2 + 60) = char_dat[i].skill_point;
-
- WFIFOW(fd, 2 + 64) = char_dat[i].shield;
- WFIFOW(fd, 2 + 66) = char_dat[i].head_top;
- WFIFOW(fd, 2 + 68) = char_dat[i].head_mid;
- WFIFOW(fd, 2 + 70) = char_dat[i].hair_color;
-
- memcpy(WFIFOP(fd, 2 + 74), char_dat[i].name, 24);
-
- WFIFOB(fd, 2 + 98) = min(char_dat[i].attrs[ATTR::STR], 255);
- WFIFOB(fd, 2 + 99) = min(char_dat[i].attrs[ATTR::AGI], 255);
- WFIFOB(fd, 2 + 100) = min(char_dat[i].attrs[ATTR::VIT], 255);
- WFIFOB(fd, 2 + 101) = min(char_dat[i].attrs[ATTR::INT], 255);
- WFIFOB(fd, 2 + 102) = min(char_dat[i].attrs[ATTR::DEX], 255);
- WFIFOB(fd, 2 + 103) = min(char_dat[i].attrs[ATTR::LUK], 255);
- WFIFOB(fd, 2 + 104) = char_dat[i].char_num;
+ WFIFOW(fd, 2 + 42) = min(cd->hp, 0x7fff);
+ WFIFOW(fd, 2 + 44) = min(cd->max_hp, 0x7fff);
+ WFIFOW(fd, 2 + 46) = min(cd->sp, 0x7fff);
+ WFIFOW(fd, 2 + 48) = min(cd->max_sp, 0x7fff);
+ WFIFOW(fd, 2 + 50) = static_cast<uint16_t>(DEFAULT_WALK_SPEED.count()); // char_data[i].speed;
+ WFIFOW(fd, 2 + 52) = cd->species;
+ WFIFOW(fd, 2 + 54) = cd->hair;
+
+ WFIFOW(fd, 2 + 58) = cd->base_level;
+ WFIFOW(fd, 2 + 60) = cd->skill_point;
+
+ WFIFOW(fd, 2 + 64) = cd->shield;
+ WFIFOW(fd, 2 + 66) = cd->head_top;
+ WFIFOW(fd, 2 + 68) = cd->head_mid;
+ WFIFOW(fd, 2 + 70) = cd->hair_color;
+
+ memcpy(WFIFOP(fd, 2 + 74), cd->name, 24);
+
+ WFIFOB(fd, 2 + 98) = min(cd->attrs[ATTR::STR], 255);
+ WFIFOB(fd, 2 + 99) = min(cd->attrs[ATTR::AGI], 255);
+ WFIFOB(fd, 2 + 100) = min(cd->attrs[ATTR::VIT], 255);
+ WFIFOB(fd, 2 + 101) = min(cd->attrs[ATTR::INT], 255);
+ WFIFOB(fd, 2 + 102) = min(cd->attrs[ATTR::DEX], 255);
+ WFIFOB(fd, 2 + 103) = min(cd->attrs[ATTR::LUK], 255);
+ WFIFOB(fd, 2 + 104) = cd->char_num;
WFIFOSET(fd, 108);
+ }
RFIFOSKIP(fd, 37);
- for (ch = 0; ch < 9; ch++)
- {
- if (sd->found_char[ch] == -1)
- {
- sd->found_char[ch] = i;
- break;
- }
- }
break;
case 0x68: // delete char //Yor's Fix
@@ -2611,123 +2435,49 @@ void parse_char(int fd)
if (e_mail_check(email) == 0)
strzcpy(email, "a@a.com", 40); // default e-mail
- // if we activated email creation and email is default email
- if (email_creation != 0 && strcmp(sd->email, "a@a.com") == 0
- && login_fd > 0)
- { // to modify an e-mail, login-server must be online
- // if sended email is incorrect e-mail
- if (strcmp(email, "a@a.com") == 0)
- {
- WFIFOW(fd, 0) = 0x70;
- WFIFOB(fd, 2) = 0; // 00 = Incorrect Email address
- WFIFOSET(fd, 3);
- RFIFOSKIP(fd, 46);
- // we act like we have selected a character
- }
- else
+ {
{
- // we change the packet to set it like selection.
- for (i = 0; i < 9; i++)
- if (char_dat[sd->found_char[i]].char_id ==
- RFIFOL(fd, 2))
+ struct mmo_charstatus *cs = nullptr;
+ for (mmo_charstatus& cd : char_data)
+ {
+ if (cd.char_id == RFIFOL(fd, 2))
{
- // we save new e-mail
- memcpy(sd->email, email, 40);
- // we send new e-mail to login-server ('online' login-server is checked before)
- WFIFOW(login_fd, 0) = 0x2715;
- WFIFOL(login_fd, 2) = sd->account_id;
- memcpy(WFIFOP(login_fd, 6), email, 40);
- WFIFOSET(login_fd, 46);
- RFIFOSKIP(fd, 46);
- handle_x0066(fd, sd, char_dat[sd->found_char[i]].char_num, p);
+ cs = &cd;
break;
}
- if (i == 9)
- {
- WFIFOW(fd, 0) = 0x70;
- WFIFOB(fd, 2) = 0; // 00 = Incorrect Email address
- WFIFOSET(fd, 3);
- RFIFOSKIP(fd, 46);
}
- }
- // otherwise, we delete the character
- }
- else
- {
- /*if (strcasecmp(email, sd->email) != 0) { // if it's an invalid email
- * WFIFOW(fd, 0) = 0x70;
- * WFIFOB(fd, 2) = 0; // 00 = Incorrect Email address
- * WFIFOSET(fd, 3);
- * // if mail is correct
- * } else { */
- for (i = 0; i < 9; i++)
- {
- struct mmo_charstatus *cs = NULL;
- if (sd->found_char[i] >= 0
- && (cs =
- &char_dat[sd->found_char[i]])->char_id ==
- RFIFOL(fd, 2))
+ if (cs)
{
char_delete(cs); // deletion process
- if (sd->found_char[i] != char_num - 1)
+ if (cs != &char_data.back())
{
- memcpy(&char_dat[sd->found_char[i]],
- &char_dat[char_num - 1],
- sizeof(struct mmo_charstatus));
- // Correct moved character reference in the character's owner
- {
- int j, k;
- struct char_session_data *sd2;
- for (j = 0; j < fd_max; j++)
- {
- if (session[j]
- && (sd2 = (struct char_session_data*)
- session[j]->session_data)
- && sd2->account_id ==
- char_dat[char_num - 1].account_id)
- {
- for (k = 0; k < 9; k++)
- {
- if (sd2->found_char[k] ==
- char_num - 1)
- {
- sd2->found_char[k] =
- sd->found_char[i];
- break;
- }
- }
- break;
- }
- }
- }
+ std::swap(*cs, char_data.back());
}
- char_num--;
- for (ch = i; ch < 9 - 1; ch++)
- sd->found_char[ch] = sd->found_char[ch + 1];
- sd->found_char[8] = -1;
+ char_data.pop_back();
WFIFOW(fd, 0) = 0x6f;
WFIFOSET(fd, 2);
- break;
+ goto x68_out;
}
}
- if (i == 9)
{
WFIFOW(fd, 0) = 0x70;
WFIFOB(fd, 2) = 0;
WFIFOSET(fd, 3);
}
- //}
- RFIFOSKIP(fd, 46);
}
+ x68_out:
+ RFIFOSKIP(fd, 46);
break;
case 0x2af8: // マップサーバーログイン
if (RFIFOREST(fd) < 60)
return;
+ {
+ int i;
WFIFOW(fd, 0) = 0x2af9;
for (i = 0; i < MAX_MAP_SERVERS; i++)
{
@@ -2760,17 +2510,17 @@ void parse_char(int fd)
// send gm acccounts level to map-servers
len = 4;
WFIFOW(fd, 0) = 0x2b15;
- for (i = 0; i < GM_num; i++)
+ for (const GM_Account& gma : gm_accounts)
{
- WFIFOL(fd, len) = gm_account[i].account_id;
- WFIFOB(fd, len + 4) =
- (unsigned char) gm_account[i].level;
+ WFIFOL(fd, len) = gma.account_id;
+ WFIFOB(fd, len + 4) = (unsigned char) gma.level;
len += 5;
}
WFIFOW(fd, 2) = len;
WFIFOSET(fd, len);
return;
}
+ }
break;
case 0x187: // Alive信号?
@@ -3111,10 +2861,6 @@ int char_config_read(const char *cfgName)
{
char_new = atoi(w2.c_str());
}
- else if (w1 == "email_creation")
- {
- email_creation = config_switch(w2.c_str());
- }
else if (w1 == "char_txt")
{
strzcpy(char_txt, w2.c_str(), sizeof(char_txt));
@@ -3235,21 +2981,17 @@ int char_config_read(const char *cfgName)
void term_func(void)
{
- int i;
-
// write online players files with no player
- for (i = 0; i < char_num; i++)
- online_chars[i] = -1;
+ std::fill(online_chars.begin(), online_chars.end(), -1);
create_online_files();
- free(online_chars);
+ online_chars.clear();
mmo_char_sync();
inter_save();
- if (gm_account != NULL)
- free(gm_account);
+ gm_accounts.clear();
- free(char_dat);
+ char_data.clear();
delete_session(login_fd);
delete_session(char_fd);
diff --git a/src/char/char.hpp b/src/char/char.hpp
index be9167e..a08e28c 100644
--- a/src/char/char.hpp
+++ b/src/char/char.hpp
@@ -18,8 +18,7 @@ struct mmo_map_server
char map[MAX_MAP_PER_SERVER][16];
};
-int search_character_index(const char *character_name);
-char *search_character_name(int index);
+const mmo_charstatus *search_character(const char *character_name);
int mapif_sendall(const uint8_t *buf, unsigned int len);
int mapif_sendallwos(int fd, const uint8_t *buf, unsigned int len);
diff --git a/src/char/inter.cpp b/src/char/inter.cpp
index 9efb28c..59a2945 100644
--- a/src/char/inter.cpp
+++ b/src/char/inter.cpp
@@ -381,7 +381,6 @@ static
int mapif_parse_WisRequest(int fd)
{
static int wisid = 0;
- int index;
if (RFIFOW(fd, 2) - 52 <= 0)
{ // normaly, impossible, but who knows...
@@ -390,7 +389,8 @@ int mapif_parse_WisRequest(int fd)
}
// search if character exists before to ask all map-servers
- if ((index = search_character_index((const char *)RFIFOP(fd, 28))) == -1)
+ const mmo_charstatus *mcs = search_character(static_cast<const char *>(RFIFOP(fd, 28)));
+ if (!mcs)
{
unsigned char buf[27];
WBUFW(buf, 0) = 0x3802;
@@ -402,7 +402,7 @@ int mapif_parse_WisRequest(int fd)
else
{
// to be sure of the correct name, rewrite it
- strzcpy(static_cast<char *>(const_cast<void *>(RFIFOP(fd, 28))), search_character_name(index), 24);
+ strzcpy(static_cast<char *>(const_cast<void *>(RFIFOP(fd, 28))), mcs->name, 24);
// if source is destination, don't ask other servers.
if (strcmp((const char *)RFIFOP(fd, 4), (const char *)RFIFOP(fd, 28)) == 0)
{
diff --git a/src/common/mmo.hpp b/src/common/mmo.hpp
index 32d4285..e72bf80 100644
--- a/src/common/mmo.hpp
+++ b/src/common/mmo.hpp
@@ -203,7 +203,7 @@ struct storage
struct map_session_data;
-struct gm_account
+struct GM_Account
{
int account_id;
int level;
diff --git a/src/common/sanity.hpp b/src/common/sanity.hpp
index e54739f..74e24df 100644
--- a/src/common/sanity.hpp
+++ b/src/common/sanity.hpp
@@ -29,12 +29,15 @@
# endif // __GNUC_MINOR__ == 6
# ifdef __GLIBCXX__
// versions of libstdc++ from gcc
-// 4.6.0, 4.6.1, 4.6.2, 4.6.3
+// 4.6.0, 4.6.1, 4.6.2, 4.6.3, 4.6.4
# if __GLIBCXX__ == 20110325 \
|| __GLIBCXX__ == 20110627 \
|| __GLIBCXX__ == 20111026 \
|| __GLIBCXX__ == 20120301 \
- || __GLIBCXX__ == 20121127 // prerelease in Debian wheezy
+ || __GLIBCXX__ == 20130412 \
+ /* various Debian snapshots */ \
+ || __GLIBCXX__ == 20121127 \
+ || __GLIBCXX__ == 20130114
# define WORKAROUND_GCC46_LIBRARY
# endif // __GLIBCXX__ == ...
# endif // defined __GLIBCXX__
diff --git a/src/common/socket.cpp b/src/common/socket.cpp
index 2acbeb8..db944cc 100644
--- a/src/common/socket.cpp
+++ b/src/common/socket.cpp
@@ -29,13 +29,13 @@ const uint32_t RFIFO_SIZE = 65536;
static
const uint32_t WFIFO_SIZE = 65536;
-struct socket_data *session[FD_SETSIZE];
+std::array<std::unique_ptr<struct socket_data>, FD_SETSIZE> session;
/// clean up by discarding handled bytes
inline
void RFIFOFLUSH(int fd)
{
- memmove(session[fd]->rdata, RFIFOP(fd, 0), RFIFOREST(fd));
+ memmove(&session[fd]->rdata[0], RFIFOP(fd, 0), RFIFOREST(fd));
session[fd]->rdata_size = RFIFOREST(fd);
session[fd]->rdata_pos = 0;
}
@@ -53,9 +53,9 @@ static
void null_parse(int fd);
/// Default parser for new connections
static
-void(*default_func_parse)(int) = null_parse;
+void (*default_func_parse)(int) = null_parse;
-void set_defaultparse(void(*defaultparse)(int))
+void set_defaultparse(void (*defaultparse)(int))
{
default_func_parse = defaultparse;
}
@@ -67,7 +67,7 @@ void recv_to_fifo(int fd)
if (session[fd]->eof)
return;
- ssize_t len = read(fd, session[fd]->rdata + session[fd]->rdata_size,
+ ssize_t len = read(fd, &session[fd]->rdata[session[fd]->rdata_size],
RFIFOSPACE(fd));
if (len > 0)
@@ -87,14 +87,14 @@ void send_from_fifo(int fd)
if (session[fd]->eof)
return;
- ssize_t len = write(fd, session[fd]->wdata, session[fd]->wdata_size);
+ ssize_t len = write(fd, &session[fd]->wdata[0], session[fd]->wdata_size);
if (len > 0)
{
session[fd]->wdata_size -= len;
if (session[fd]->wdata_size)
{
- memmove(session[fd]->wdata, session[fd]->wdata + len,
+ memmove(&session[fd]->wdata[0], &session[fd]->wdata[len],
session[fd]->wdata_size);
}
session[fd]->connected = 1;
@@ -160,9 +160,9 @@ void connect_client(int listen_fd)
fcntl(fd, F_SETFL, O_NONBLOCK);
- CREATE(session[fd], struct socket_data, 1);
- CREATE(session[fd]->rdata, uint8_t, RFIFO_SIZE);
- CREATE(session[fd]->wdata, uint8_t, WFIFO_SIZE);
+ session[fd].reset(new socket_data());
+ session[fd]->rdata.new_(RFIFO_SIZE);
+ session[fd]->wdata.new_(WFIFO_SIZE);
session[fd]->max_rdata = RFIFO_SIZE;
session[fd]->max_wdata = WFIFO_SIZE;
@@ -219,7 +219,7 @@ int make_listen_port(uint16_t port)
FD_SET(fd, &readfds);
- CREATE(session[fd], struct socket_data, 1);
+ session[fd].reset(new socket_data());
session[fd]->func_recv = connect_client;
session[fd]->created = TimeT::now();
@@ -265,9 +265,9 @@ int make_connection(uint32_t ip, uint16_t port)
FD_SET(fd, &readfds);
- CREATE(session[fd], struct socket_data, 1);
- CREATE(session[fd]->rdata, uint8_t, RFIFO_SIZE);
- CREATE(session[fd]->wdata, uint8_t, WFIFO_SIZE);
+ session[fd].reset(new socket_data());
+ session[fd]->rdata.new_(RFIFO_SIZE);
+ session[fd]->wdata.new_(WFIFO_SIZE);
session[fd]->max_rdata = RFIFO_SIZE;
session[fd]->max_wdata = WFIFO_SIZE;
@@ -293,12 +293,11 @@ void delete_session(int fd)
FD_CLR(fd, &readfds);
if (session[fd])
{
- free(session[fd]->rdata);
- free(session[fd]->wdata);
- free(session[fd]->session_data);
- free(session[fd]);
+ session[fd]->rdata.delete_();
+ session[fd]->wdata.delete_();
+ session[fd]->session_data.reset();
+ session[fd].reset();
}
- session[fd] = NULL;
// just close() would try to keep sending buffers
shutdown(fd, SHUT_RDWR);
@@ -314,22 +313,22 @@ void delete_session(int fd)
void realloc_fifo(int fd, size_t rfifo_size, size_t wfifo_size)
{
- struct socket_data *s = session[fd];
+ const std::unique_ptr<socket_data>& s = session[fd];
if (s->max_rdata != rfifo_size && s->rdata_size < rfifo_size)
{
- RECREATE(s->rdata, uint8_t, rfifo_size);
+ s->rdata.resize(rfifo_size);
s->max_rdata = rfifo_size;
}
if (s->max_wdata != wfifo_size && s->wdata_size < wfifo_size)
{
- RECREATE(s->wdata, uint8_t, wfifo_size);
+ s->wdata.resize(wfifo_size);
s->max_wdata = wfifo_size;
}
}
void WFIFOSET(int fd, size_t len)
{
- struct socket_data *s = session[fd];
+ std::unique_ptr<socket_data>& s = session[fd];
if (s->wdata_size + len + 16384 > s->max_wdata)
{
realloc_fifo(fd, s->max_rdata, s->max_wdata << 1);
@@ -413,7 +412,7 @@ void do_socket(void)
void RFIFOSKIP(int fd, size_t len)
{
- struct socket_data *s = session[fd];
+ std::unique_ptr<socket_data>& s = session[fd];
s->rdata_pos += len;
if (s->rdata_size < s->rdata_pos)
diff --git a/src/common/socket.hpp b/src/common/socket.hpp
index d7c6b9c..d526379 100644
--- a/src/common/socket.hpp
+++ b/src/common/socket.hpp
@@ -7,9 +7,21 @@
# include <cstdio>
+# include <array>
+
+# include "dumb_ptr.hpp"
# include "utils.hpp"
# include "timer.t.hpp"
+struct SessionData
+{
+};
+struct SessionDeleter
+{
+ // defined per-server
+ void operator()(SessionData *sd);
+};
+
// Struct declaration
struct socket_data
@@ -23,7 +35,7 @@ struct socket_data
/// Since this is a single-threaded application, it can't block
/// These are the read/write queues
- uint8_t *rdata, *wdata;
+ dumb_ptr<uint8_t[]> rdata, wdata;
size_t max_rdata, max_wdata;
/// How much is actually in the queue
size_t rdata_size, wdata_size;
@@ -37,15 +49,15 @@ struct socket_data
/// Only called when select() indicates the socket is ready
/// If, after that, nothing is read, it sets eof
// These could probably be hard-coded with a little work
- void(*func_recv)(int);
- void(*func_send)(int);
+ void (*func_recv)(int);
+ void (*func_send)(int);
/// This is the important one
/// Set to different functions depending on whether the connection
/// is a player or a server/ladmin
/// Can be set explicitly or via set_defaultparse
- void(*func_parse)(int);
+ void (*func_parse)(int);
/// Server-specific data type
- void *session_data;
+ std::unique_ptr<SessionData, SessionDeleter> session_data;
};
// save file descriptors for important stuff
@@ -56,7 +68,7 @@ constexpr int CONNECT_TIMEOUT = 15;
/// Everyone who has connected
// note: call delete_session(i) to null out an element
-extern struct socket_data *session[FD_SETSIZE];
+extern std::array<std::unique_ptr<socket_data>, FD_SETSIZE> session;
/// Maximum used FD, +1
extern int fd_max;
@@ -102,7 +114,7 @@ size_t RFIFOREST(int fd)
inline
const void *RFIFOP(int fd, size_t pos)
{
- return session[fd]->rdata + session[fd]->rdata_pos + pos;
+ return &session[fd]->rdata[session[fd]->rdata_pos + pos];
}
inline
uint8_t RFIFOB(int fd, size_t pos)
@@ -156,7 +168,7 @@ size_t WFIFOSPACE(int fd)
inline
void *WFIFOP(int fd, size_t pos)
{
- return session[fd]->wdata + session[fd]->wdata_size + pos;
+ return &session[fd]->wdata[session[fd]->wdata_size + pos];
}
inline
uint8_t& WFIFOB(int fd, size_t pos)
diff --git a/src/ladmin/ladmin.cpp b/src/ladmin/ladmin.cpp
index d6a30dd..458df39 100644
--- a/src/ladmin/ladmin.cpp
+++ b/src/ladmin/ladmin.cpp
@@ -3,6 +3,8 @@
#include <netdb.h>
#include <unistd.h>
+#include <cassert>
+
#include <fstream>
#include "../common/cxxstdio.hpp"
@@ -233,6 +235,14 @@ int list_first, list_last, list_type, list_count; // parameter to display a lis
static
int already_exit_function = 0; // sometimes, the exit function is called twice... so, don't log twice the message
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmissing-noreturn"
+void SessionDeleter::operator()(SessionData *)
+{
+ assert(false && "ladmin does not have sessions");
+}
+#pragma GCC diagnostic pop
+
//------------------------------
// Writing function of logs file
//------------------------------
diff --git a/src/login/login.cpp b/src/login/login.cpp
index 861336d..1d05d49 100644
--- a/src/login/login.cpp
+++ b/src/login/login.cpp
@@ -142,12 +142,18 @@ int start_limited_time = -1; // Starting additional sec from now for the limit
static
int check_ip_flag = 1; // It's to check IP of a player between login-server and char-server (part of anti-hacking system)
-struct login_session_data
+
+struct login_session_data : SessionData
{
int md5keylen;
char md5key[20];
};
+void SessionDeleter::operator()(SessionData *sd)
+{
+ delete static_cast<login_session_data *>(sd);
+}
+
constexpr int AUTH_FIFO_SIZE = 256;
struct
{
@@ -172,6 +178,7 @@ struct AuthData
int account_reg2_num;
struct global_reg account_reg2[ACCOUNT_REG2_NUM];
};
+static
std::vector<AuthData> auth_data;
static
@@ -184,7 +191,7 @@ static
int level_new_gm = 60;
static
-Map<int, struct gm_account> gm_account_db;
+Map<int, GM_Account> gm_account_db;
static
pid_t pid = 0; // For forked DB writes
@@ -225,7 +232,7 @@ void login_log(const_string line)
static
int isGM(int account_id)
{
- struct gm_account *p = gm_account_db.search(account_id);
+ GM_Account *p = gm_account_db.search(account_id);
if (p == NULL)
return 0;
return p->level;
@@ -263,7 +270,7 @@ int read_gm_account(void)
if ((line[0] == '/' && line[1] == '/') || line[0] == '\0'
|| line[0] == '\n' || line[0] == '\r')
continue;
- struct gm_account p {};
+ GM_Account p {};
if (sscanf(line, "%d %d", &p.account_id, &p.level) != 2
&& sscanf(line, "%d: %d", &p.account_id, &p.level) != 2)
PRINTF("read_gm_account: file [%s], invalid 'id_acount level' format.\n",
@@ -3128,21 +3135,13 @@ void parse_login(int fd)
case 0x01db: // Sending request of the coding key
case 0x791a: // Sending request of the coding key (administration packet)
{
- struct login_session_data *ld;
if (session[fd]->session_data)
{
PRINTF("login: abnormal request of MD5 key (already opened session).\n");
session[fd]->eof = 1;
return;
}
- CREATE(ld, struct login_session_data, 1);
- session[fd]->session_data = ld;
- if (!ld)
- {
- PRINTF("login: Request for md5 key: memory allocation failure (malloc)!\n");
- session[fd]->eof = 1;
- return;
- }
+ std::unique_ptr<login_session_data, SessionDeleter> ld{new login_session_data()};
if (RFIFOW(fd, 0) == 0x01db)
{
LOGIN_LOG("Sending request of the coding key (ip: %s)\n",
@@ -3165,6 +3164,7 @@ void parse_login(int fd)
WFIFOW(fd, 2) = 4 + ld->md5keylen;
memcpy(WFIFOP(fd, 4), ld->md5key, ld->md5keylen);
WFIFOSET(fd, WFIFOW(fd, 2));
+ session[fd]->session_data = std::move(ld);
}
break;
@@ -3295,9 +3295,10 @@ void parse_login(int fd)
}
else
{
- struct login_session_data *ld = (struct login_session_data *)session[fd]->session_data;
+ struct login_session_data *ld = static_cast<login_session_data *>(session[fd]->session_data.get());
if (RFIFOW(fd, 2) == 0)
- { // non encrypted password
+ {
+ // non encrypted password
char password[24];
strzcpy(password, static_cast<const char *>(RFIFOP(fd, 4)), 24);
remove_control_chars(password);
diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp
index 5fffaa3..e4ec17b 100644
--- a/src/map/atcommand.cpp
+++ b/src/map/atcommand.cpp
@@ -910,8 +910,7 @@ int atcommand_jump(const int fd, struct map_session_data *sd,
int atcommand_who(const int fd, struct map_session_data *sd,
const char *, const char *message)
{
- struct map_session_data *pl_sd;
- int i, j, count;
+ int count;
int pl_GM_level, GM_level;
char match_text[100];
char player_name[24];
@@ -921,24 +920,27 @@ int atcommand_who(const int fd, struct map_session_data *sd,
if (sscanf(message, "%99[^\n]", match_text) < 1)
strcpy(match_text, "");
- for (j = 0; match_text[j]; j++)
+ for (int j = 0; match_text[j]; j++)
match_text[j] = tolower(match_text[j]);
count = 0;
GM_level = pc_isGM(sd);
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
- && pl_sd->state.auth)
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd && pl_sd->state.auth)
{
pl_GM_level = pc_isGM(pl_sd);
if (!
((battle_config.hide_GM_session
|| bool(pl_sd->status.option & Option::HIDE))
&& (pl_GM_level > GM_level)))
- { // you can look only lower or same level
+ {
+ // you can look only lower or same level
memcpy(player_name, pl_sd->status.name, 24);
- for (j = 0; player_name[j]; j++)
+ for (int j = 0; player_name[j]; j++)
player_name[j] = tolower(player_name[j]);
if (strstr(player_name, match_text) != NULL)
{
@@ -981,8 +983,7 @@ int atcommand_who(const int fd, struct map_session_data *sd,
int atcommand_whogroup(const int fd, struct map_session_data *sd,
const char *, const char *message)
{
- struct map_session_data *pl_sd;
- int i, j, count;
+ int count;
int pl_GM_level, GM_level;
char match_text[100];
char player_name[24];
@@ -993,27 +994,31 @@ int atcommand_whogroup(const int fd, struct map_session_data *sd,
if (sscanf(message, "%99[^\n]", match_text) < 1)
strcpy(match_text, "");
- for (j = 0; match_text[j]; j++)
+ for (int j = 0; match_text[j]; j++)
match_text[j] = tolower(match_text[j]);
count = 0;
GM_level = pc_isGM(sd);
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
- && pl_sd->state.auth)
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd && pl_sd->state.auth)
{
pl_GM_level = pc_isGM(pl_sd);
if (!
((battle_config.hide_GM_session
|| bool(pl_sd->status.option & Option::HIDE))
&& (pl_GM_level > GM_level)))
- { // you can look only lower or same level
+ {
+ // you can look only lower or same level
memcpy(player_name, pl_sd->status.name, 24);
- for (j = 0; player_name[j]; j++)
+ for (int j = 0; player_name[j]; j++)
player_name[j] = tolower(player_name[j]);
if (strstr(player_name, match_text) != NULL)
- { // search with no case sensitive
+ {
+ // search with no case sensitive
p = party_search(pl_sd->status.party_id);
const char *temp0 = p ? p->name : "None";
std::string output;
@@ -1048,8 +1053,7 @@ int atcommand_whogroup(const int fd, struct map_session_data *sd,
int atcommand_whomap(const int fd, struct map_session_data *sd,
const char *, const char *message)
{
- struct map_session_data *pl_sd;
- int i, count;
+ int count;
int pl_GM_level, GM_level;
int map_id;
char map_name[100];
@@ -1069,10 +1073,12 @@ int atcommand_whomap(const int fd, struct map_session_data *sd,
count = 0;
GM_level = pc_isGM(sd);
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
- && pl_sd->state.auth)
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd && pl_sd->state.auth)
{
pl_GM_level = pc_isGM(pl_sd);
if (!
@@ -1114,8 +1120,7 @@ int atcommand_whomap(const int fd, struct map_session_data *sd,
int atcommand_whomapgroup(const int fd, struct map_session_data *sd,
const char *, const char *message)
{
- struct map_session_data *pl_sd;
- int i, count;
+ int count;
int pl_GM_level, GM_level;
int map_id = 0;
char map_name[100];
@@ -1136,10 +1141,12 @@ int atcommand_whomapgroup(const int fd, struct map_session_data *sd,
count = 0;
GM_level = pc_isGM(sd);
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
- && pl_sd->state.auth)
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd && pl_sd->state.auth)
{
pl_GM_level = pc_isGM(pl_sd);
if (!
@@ -1187,8 +1194,7 @@ int atcommand_whomapgroup(const int fd, struct map_session_data *sd,
int atcommand_whogm(const int fd, struct map_session_data *sd,
const char *, const char *message)
{
- struct map_session_data *pl_sd;
- int i, j, count;
+ int count;
int pl_GM_level, GM_level;
char match_text[100];
char player_name[24];
@@ -1199,15 +1205,17 @@ int atcommand_whogm(const int fd, struct map_session_data *sd,
if (sscanf(message, "%99[^\n]", match_text) < 1)
strcpy(match_text, "");
- for (j = 0; match_text[j]; j++)
+ for (int j = 0; match_text[j]; j++)
match_text[j] = tolower(match_text[j]);
count = 0;
GM_level = pc_isGM(sd);
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
- && pl_sd->state.auth)
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd && pl_sd->state.auth)
{
pl_GM_level = pc_isGM(pl_sd);
if (pl_GM_level > 0)
@@ -1219,7 +1227,7 @@ int atcommand_whogm(const int fd, struct map_session_data *sd,
{
// you can look only lower or same level
memcpy(player_name, pl_sd->status.name, 24);
- for (j = 0; player_name[j]; j++)
+ for (int j = 0; player_name[j]; j++)
player_name[j] = tolower(player_name[j]);
if (strstr(player_name, match_text) != NULL)
{
@@ -1879,9 +1887,6 @@ int atcommand_gm(const int fd, struct map_session_data *sd,
int atcommand_pvpoff(const int fd, struct map_session_data *sd,
const char *, const char *)
{
- struct map_session_data *pl_sd;
- int i;
-
if (battle_config.pk_mode)
{ //disable command if server is in PK mode [Valaris]
clif_displaymessage(fd, "This option cannot be used in PK Mode.");
@@ -1891,10 +1896,12 @@ int atcommand_pvpoff(const int fd, struct map_session_data *sd,
if (map[sd->bl.m].flag.pvp)
{
map[sd->bl.m].flag.pvp = 0;
- for (i = 0; i < fd_max; i++)
- { //人数分ループ
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
- && pl_sd->state.auth)
+ for (int i = 0; i < fd_max; i++)
+ {
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd && pl_sd->state.auth)
{
if (sd->bl.m == pl_sd->bl.m)
{
@@ -1920,9 +1927,6 @@ int atcommand_pvpoff(const int fd, struct map_session_data *sd,
int atcommand_pvpon(const int fd, struct map_session_data *sd,
const char *, const char *)
{
- struct map_session_data *pl_sd;
- int i;
-
if (battle_config.pk_mode)
{ //disable command if server is in PK mode [Valaris]
clif_displaymessage(fd, "This option cannot be used in PK Mode.");
@@ -1932,10 +1936,12 @@ int atcommand_pvpon(const int fd, struct map_session_data *sd,
if (!map[sd->bl.m].flag.pvp && !map[sd->bl.m].flag.nopvp)
{
map[sd->bl.m].flag.pvp = 1;
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
- && pl_sd->state.auth)
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd && pl_sd->state.auth)
{
if (sd->bl.m == pl_sd->bl.m && !pl_sd->pvp_timer)
{
@@ -2702,15 +2708,15 @@ int atcommand_character_stats(const int fd, struct map_session_data *,
int atcommand_character_stats_all(const int fd, struct map_session_data *,
const char *, const char *)
{
- int i;
int count;
- struct map_session_data *pl_sd;
count = 0;
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
- && pl_sd->state.auth)
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd && pl_sd->state.auth)
{
std::string gmlevel;
if (pc_isGM(pl_sd) > 0)
@@ -3149,12 +3155,12 @@ int atcommand_character_save(const int fd, struct map_session_data *sd,
int atcommand_doom(const int fd, struct map_session_data *sd,
const char *, const char *)
{
- struct map_session_data *pl_sd;
- int i;
-
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd
&& pl_sd->state.auth && i != fd
&& pc_isGM(sd) >= pc_isGM(pl_sd))
{ // you can doom only lower or same gm level
@@ -3174,12 +3180,12 @@ int atcommand_doom(const int fd, struct map_session_data *sd,
int atcommand_doommap(const int fd, struct map_session_data *sd,
const char *, const char *)
{
- struct map_session_data *pl_sd;
- int i;
-
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd
&& pl_sd->state.auth && i != fd && sd->bl.m == pl_sd->bl.m
&& pc_isGM(sd) >= pc_isGM(pl_sd))
{ // you can doom only lower or same gm level
@@ -3218,12 +3224,12 @@ void atcommand_raise_sub(struct map_session_data *sd)
int atcommand_raise(const int fd, struct map_session_data *,
const char *, const char *)
{
- int i;
-
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i])
- atcommand_raise_sub((struct map_session_data *)session[i]->session_data);
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ atcommand_raise_sub(pl_sd);
}
clif_displaymessage(fd, "Mercy has been granted.");
@@ -3237,12 +3243,12 @@ int atcommand_raise(const int fd, struct map_session_data *,
int atcommand_raisemap(const int fd, struct map_session_data *sd,
const char *, const char *)
{
- struct map_session_data *pl_sd;
- int i;
-
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd
&& pl_sd->state.auth && sd->bl.m == pl_sd->bl.m)
atcommand_raise_sub(pl_sd);
}
@@ -3475,14 +3481,15 @@ int atcommand_kick(const int fd, struct map_session_data *sd,
int atcommand_kickall(const int fd, struct map_session_data *sd,
const char *, const char *)
{
- struct map_session_data *pl_sd;
- int i;
-
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd
&& pl_sd->state.auth && pc_isGM(sd) >= pc_isGM(pl_sd))
- { // you can kick only lower or same gm level
+ {
+ // you can kick only lower or same gm level
if (sd->status.account_id != pl_sd->status.account_id)
clif_GM_kick(sd, pl_sd, 0);
}
@@ -3747,13 +3754,12 @@ int atcommand_party(const int fd, struct map_session_data *sd,
int atcommand_mapexit(const int, struct map_session_data *sd,
const char *, const char *)
{
- struct map_session_data *pl_sd;
- int i;
-
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
- && pl_sd->state.auth)
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd && pl_sd->state.auth)
{
if (sd->status.account_id != pl_sd->status.account_id)
clif_GM_kick(sd, pl_sd, 0);
@@ -4248,8 +4254,6 @@ int atcommand_charzeny(const int fd, struct map_session_data *,
int atcommand_recallall(const int fd, struct map_session_data *sd,
const char *, const char *)
{
- struct map_session_data *pl_sd;
- int i;
int count;
if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto
@@ -4261,13 +4265,17 @@ int atcommand_recallall(const int fd, struct map_session_data *sd,
}
count = 0;
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd
&& pl_sd->state.auth
&& sd->status.account_id != pl_sd->status.account_id
&& pc_isGM(sd) >= pc_isGM(pl_sd))
- { // you can recall only lower or same level
+ {
+ // you can recall only lower or same level
if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
count++;
@@ -4295,8 +4303,6 @@ int atcommand_recallall(const int fd, struct map_session_data *sd,
int atcommand_partyrecall(const int fd, struct map_session_data *sd,
const char *, const char *message)
{
- int i;
- struct map_session_data *pl_sd;
char party_name[100];
struct party *p;
int count;
@@ -4322,10 +4328,12 @@ int atcommand_partyrecall(const int fd, struct map_session_data *sd,
(p = party_search(atoi(message))) != NULL)
{
count = 0;
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
- && pl_sd->state.auth
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd && pl_sd->state.auth
&& sd->status.account_id != pl_sd->status.account_id
&& pl_sd->status.party_id == p->party_id)
{
@@ -4431,18 +4439,15 @@ int atcommand_reloadgmdb(const int fd, struct map_session_data *,
* 0 = no additional information
* 1 = Show users in that map and their location
* 2 = Shows NPCs in that map
- * 3 = Shows the shops/chats in that map (not implemented)
*------------------------------------------
*/
int atcommand_mapinfo(const int fd, struct map_session_data *sd,
const char *, const char *message)
{
- struct map_session_data *pl_sd;
struct npc_data *nd = NULL;
- struct chat_data *cd = NULL;
char map_name[100];
const char *direction = NULL;
- int m_id, i, chat_num, list = 0;
+ int m_id, list = 0;
memset(map_name, '\0', sizeof(map_name));
@@ -4473,18 +4478,6 @@ int atcommand_mapinfo(const int fd, struct map_session_data *sd,
clif_displaymessage(fd, output);
output = STRPRINTF("NPCs In Map: %d", map[m_id].npc_num);
clif_displaymessage(fd, output);
- chat_num = 0;
- for (i = 0; i < fd_max; i++)
- {
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
- && pl_sd->state.auth
- && (cd = (struct chat_data *) map_id2bl(pl_sd->chatID)))
- {
- chat_num++;
- }
- }
- output = STRPRINTF("Chats In Map: %d", chat_num);
- clif_displaymessage(fd, output);
clif_displaymessage(fd, "------ Map Flags ------");
output = STRPRINTF("Player vs Player: %s | No Party: %s",
(map[m_id].flag.pvp) ? "True" : "False",
@@ -4522,10 +4515,12 @@ int atcommand_mapinfo(const int fd, struct map_session_data *sd,
break;
case 1:
clif_displaymessage(fd, "----- Players in Map -----");
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
- && pl_sd->state.auth
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd && pl_sd->state.auth
&& strcmp(pl_sd->mapname, map_name) == 0)
{
output = STRPRINTF(
@@ -4537,7 +4532,7 @@ int atcommand_mapinfo(const int fd, struct map_session_data *sd,
break;
case 2:
clif_displaymessage(fd, "----- NPCs in Map -----");
- for (i = 0; i < map[m_id].npc_num;)
+ for (int i = 0; i < map[m_id].npc_num;)
{
nd = map[m_id].npc[i];
switch (nd->dir)
@@ -4582,32 +4577,9 @@ int atcommand_mapinfo(const int fd, struct map_session_data *sd,
clif_displaymessage(fd, output);
}
break;
- case 3:
- clif_displaymessage(fd, "----- Chats in Map -----");
- for (i = 0; i < fd_max; i++)
- {
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
- && pl_sd->state.auth
- && (cd = (struct chat_data *) map_id2bl(pl_sd->chatID))
- && strcmp(pl_sd->mapname, map_name) == 0
- && cd->usersd[0] == pl_sd)
- {
- output = STRPRINTF(
- "Chat %d: %s | Player: %s | Location: %d %d", i,
- cd->title, pl_sd->status.name, cd->bl.x,
- cd->bl.y);
- clif_displaymessage(fd, output);
- output = STRPRINTF(
- " Users: %d/%d | Password: %s | Public: %s",
- cd->users, cd->limit, cd->pass,
- (cd->pub) ? "Yes" : "No");
- clif_displaymessage(fd, output);
- }
- }
- break;
default: // normally impossible to arrive here
clif_displaymessage(fd,
- "Please, enter at least a valid list number (usage: @mapinfo <0-3> [map]).");
+ "Please, enter at least a valid list number (usage: @mapinfo <0-2> [map]).");
return -1;
}
@@ -4977,8 +4949,7 @@ int atcommand_charignorelist(const int fd, struct map_session_data *,
if (count > 0)
for (i = 0;
- i <
- (int)(sizeof(pl_sd->ignore) / sizeof(pl_sd->ignore[0]));
+ i < (int)(sizeof(pl_sd->ignore) / sizeof(pl_sd->ignore[0]));
i++)
if (pl_sd->ignore[i].name[0])
clif_displaymessage(fd, pl_sd->ignore[i].name);
@@ -5172,8 +5143,7 @@ int atcommand_email(const int fd, struct map_session_data *sd,
int atcommand_effect(const int fd, struct map_session_data *sd,
const char *, const char *message)
{
- struct map_session_data *pl_sd;
- int type = 0, flag = 0, i;
+ int type = 0, flag = 0;
if (!message || !*message || sscanf(message, "%d %d", &type, &flag) < 2)
{
@@ -5188,10 +5158,12 @@ int atcommand_effect(const int fd, struct map_session_data *sd,
}
else
{
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
- && pl_sd->state.auth)
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd && pl_sd->state.auth)
{
clif_specialeffect(&pl_sd->bl, type, flag);
clif_displaymessage(pl_sd->fd, "Your Effect Has Changed."); // Your effect has changed.
@@ -6529,10 +6501,8 @@ int atcommand_skill_learn(const int fd, struct map_session_data *,
int atcommand_ipcheck(const int fd, struct map_session_data *,
const char *, const char *message)
{
- struct map_session_data *pl_sd;
struct sockaddr_in sai;
char character[25];
- int i;
socklen_t sa_len = sizeof(struct sockaddr);
unsigned long ip;
@@ -6544,6 +6514,7 @@ int atcommand_ipcheck(const int fd, struct map_session_data *,
return -1;
}
+ map_session_data *pl_sd;
if ((pl_sd = map_nick2sd(character)) == NULL)
{
clif_displaymessage(fd, "Character not found.");
@@ -6562,10 +6533,12 @@ int atcommand_ipcheck(const int fd, struct map_session_data *,
// We now have the IP address of a character.
// Loop over all logged in sessions looking for matches.
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
- && pl_sd->state.auth)
+ if (!session[i])
+ continue;
+ pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd && pl_sd->state.auth)
{
if (getpeername(pl_sd->fd, (struct sockaddr *)&sai, &sa_len))
continue;
@@ -6589,12 +6562,12 @@ int atcommand_ipcheck(const int fd, struct map_session_data *,
int atcommand_doomspot(const int fd, struct map_session_data *sd,
const char *, const char *)
{
- struct map_session_data *pl_sd;
- int i;
-
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd
&& pl_sd->state.auth && i != fd && sd->bl.m == pl_sd->bl.m
&& sd->bl.x == pl_sd->bl.x && sd->bl.y == pl_sd->bl.y
&& pc_isGM(sd) >= pc_isGM(pl_sd))
diff --git a/src/map/chat.cpp b/src/map/chat.cpp
deleted file mode 100644
index 0d3bb95..0000000
--- a/src/map/chat.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-#include "chat.hpp"
-
-#include <cstdlib>
-#include <cstring>
-
-#include "../common/nullpo.hpp"
-
-#include "map.hpp"
-#include "npc.hpp"
-#include "pc.hpp"
-
-#include "../poison.hpp"
-
-static
-int chat_triggerevent(struct chat_data *cd);
-static
-int chat_npckickall(struct chat_data *cd);
-
-/*==========================================
- * チャットルームから抜ける
- *------------------------------------------
- */
-int chat_leavechat(struct map_session_data *sd)
-{
- struct chat_data *cd;
- int i, leavechar;
-
- nullpo_retr(1, sd);
-
- cd = (struct chat_data *) map_id2bl(sd->chatID);
- if (cd == NULL)
- return 1;
-
- for (i = 0, leavechar = -1; i < cd->users; i++)
- {
- if (cd->usersd[i] == sd)
- {
- leavechar = i;
- break;
- }
- }
- if (leavechar < 0) // そのchatに所属していないらしい (バグ時のみ)
- return -1;
-
- cd->users--;
- pc_setchatid(sd, 0);
-
- if (cd->users == 0 && (*cd->owner)->type == BL::PC)
- {
- // 全員居なくなった&PCのチャットなので消す
- map_delobject(cd->bl.id, BL::CHAT); // freeまでしてくれる
- }
- else
- {
- for (i = leavechar; i < cd->users; i++)
- cd->usersd[i] = cd->usersd[i + 1];
- if (leavechar == 0 && (*cd->owner)->type == BL::PC)
- {
- // PCのチャットなので所有者が抜けたので位置変更
- cd->bl.x = cd->usersd[0]->bl.x;
- cd->bl.y = cd->usersd[0]->bl.y;
- }
- }
-
- return 0;
-}
-
-/*==========================================
- * npcチャットルーム作成
- *------------------------------------------
- */
-int chat_createnpcchat(struct npc_data *nd, int limit, int pub, int trigger,
- const char *title, int titlelen, const char *ev)
-{
- struct chat_data *cd;
-
- nullpo_retr(1, nd);
-
- CREATE(cd, struct chat_data, 1);
-
- cd->limit = cd->trigger = limit;
- if (trigger > 0)
- cd->trigger = trigger;
- cd->pub = pub;
- cd->users = 0;
- memcpy(cd->pass, "", 8);
- if (titlelen >= sizeof(cd->title) - 1)
- titlelen = sizeof(cd->title) - 1;
- memcpy(cd->title, title, titlelen);
- cd->title[titlelen] = 0;
-
- cd->bl.m = nd->bl.m;
- cd->bl.x = nd->bl.x;
- cd->bl.y = nd->bl.y;
- cd->bl.type = BL::CHAT;
- cd->owner_ = (struct block_list *) nd;
- cd->owner = &cd->owner_;
- memcpy(cd->npc_event, ev, sizeof(cd->npc_event));
-
- cd->bl.id = map_addobject(&cd->bl);
- if (cd->bl.id == 0)
- {
- free(cd);
- return 0;
- }
- nd->chat_id = cd->bl.id;
-
- return 0;
-}
-
-/*==========================================
- * npcチャットルーム削除
- *------------------------------------------
- */
-int chat_deletenpcchat(struct npc_data *nd)
-{
- struct chat_data *cd;
-
- nullpo_ret(nd);
- cd = (struct chat_data *) map_id2bl(nd->chat_id);
- nullpo_ret(cd);
-
- chat_npckickall(cd);
- map_delobject(cd->bl.id, BL::CHAT); // freeまでしてくれる
- nd->chat_id = 0;
-
- return 0;
-}
-
-/*==========================================
- * 規定人数以上でイベントが定義されてるなら実行
- *------------------------------------------
- */
-int chat_triggerevent(struct chat_data *cd)
-{
- nullpo_ret(cd);
-
- if (cd->users >= cd->trigger && cd->npc_event[0])
- npc_event_do(cd->npc_event);
- return 0;
-}
-
-/*==========================================
- * イベントの有効化
- *------------------------------------------
- */
-int chat_enableevent(struct chat_data *cd)
-{
- nullpo_ret(cd);
-
- cd->trigger &= 0x7f;
- chat_triggerevent(cd);
- return 0;
-}
-
-/*==========================================
- * イベントの無効化
- *------------------------------------------
- */
-int chat_disableevent(struct chat_data *cd)
-{
- nullpo_ret(cd);
-
- cd->trigger |= 0x80;
- return 0;
-}
-
-/*==========================================
- * チャットルームから全員蹴り出す
- *------------------------------------------
- */
-int chat_npckickall(struct chat_data *cd)
-{
- nullpo_ret(cd);
-
- while (cd->users > 0)
- {
- chat_leavechat(cd->usersd[cd->users - 1]);
- }
- return 0;
-}
diff --git a/src/map/chat.hpp b/src/map/chat.hpp
deleted file mode 100644
index ead7b49..0000000
--- a/src/map/chat.hpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef CHAT_HPP
-#define CHAT_HPP
-
-int chat_leavechat(struct map_session_data *);
-
-int chat_createnpcchat(struct npc_data *nd, int limit, int pub, int trigger,
- const char *title, int titlelen, const char *ev);
-int chat_deletenpcchat(struct npc_data *nd);
-int chat_enableevent(struct chat_data *cd);
-int chat_disableevent(struct chat_data *cd);
-
-#endif // CHAT_HPP
diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp
index 6742f88..4757c0a 100644
--- a/src/map/chrif.cpp
+++ b/src/map/chrif.cpp
@@ -199,7 +199,7 @@ int chrif_changemapserver(struct map_session_data *sd, char *name, int x,
s_ip = 0;
for (i = 0; i < fd_max; i++)
- if (session[i] && session[i]->session_data == sd)
+ if (session[i] && session[i]->session_data.get() == sd)
{
s_ip = session[i]->client_addr.sin_addr.s_addr;
break;
@@ -310,7 +310,7 @@ int chrif_authreq(struct map_session_data *sd)
return -1;
for (i = 0; i < fd_max; i++)
- if (session[i] && session[i]->session_data == sd)
+ if (session[i] && session[i]->session_data.get() == sd)
{
WFIFOW(char_fd, 0) = 0x2afc;
WFIFOL(char_fd, 2) = sd->bl.id;
@@ -340,7 +340,7 @@ int chrif_charselectreq(struct map_session_data *sd)
s_ip = 0;
for (i = 0; i < fd_max; i++)
- if (session[i] && session[i]->session_data == sd)
+ if (session[i] && session[i]->session_data.get() == sd)
{
s_ip = session[i]->client_addr.sin_addr.s_addr;
break;
@@ -1161,16 +1161,18 @@ void chrif_parse(int fd)
static
void send_users_tochar(TimerData *, tick_t)
{
- int users = 0, i;
- struct map_session_data *sd;
+ int users = 0;
if (char_fd <= 0 || session[char_fd] == NULL)
return;
WFIFOW(char_fd, 0) = 0x2aff;
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (sd = (struct map_session_data *)session[i]->session_data) && sd->state.auth &&
+ if (!session[i])
+ continue;
+ map_session_data *sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (sd && sd->state.auth &&
!((battle_config.hide_GM_session
|| sd->state.shroud_active
|| bool(sd->status.option & Option::HIDE)) && pc_isGM(sd)))
diff --git a/src/map/clif.cpp b/src/map/clif.cpp
index 1deb1f3..4e70418 100644
--- a/src/map/clif.cpp
+++ b/src/map/clif.cpp
@@ -66,11 +66,7 @@ enum class SendWho
ALL_SAMEMAP,
AREA,
AREA_WOS,
- AREA_WOC,
- AREA_WOSC,
AREA_CHAT_WOC,
- CHAT,
- CHAT_WOS,
PARTY,
PARTY_WOS,
PARTY_SAMEMAP,
@@ -164,14 +160,14 @@ int clif_getport(void)
*/
int clif_countusers(void)
{
- int users = 0, i;
- struct map_session_data *sd;
+ int users = 0;
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (sd = (struct map_session_data *)session[i]->session_data) && sd
- && sd->state.auth && !(battle_config.hide_GM_session
- && pc_isGM(sd)))
+ if (!session[i])
+ continue;
+ map_session_data *sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (sd && sd->state.auth && !(battle_config.hide_GM_session && pc_isGM(sd)))
users++;
}
return users;
@@ -181,15 +177,14 @@ int clif_countusers(void)
* 全てのclientに対してfunc()実行
*------------------------------------------
*/
-int clif_foreachclient(std::function<void(struct map_session_data *)> func)
+int clif_foreachclient(std::function<void (struct map_session_data *)> func)
{
- int i;
- struct map_session_data *sd;
-
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (sd = (struct map_session_data *)session[i]->session_data) && sd
- && sd->state.auth)
+ if (!session[i])
+ continue;
+ map_session_data *sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (sd && sd->state.auth)
func(sd);
}
return 0;
@@ -238,17 +233,10 @@ void clif_send_sub(struct block_list *bl, const unsigned char *buf, int len,
clif_emotion_towards(src_bl, bl, EMOTE_IGNORED);
return;
}
- FALLTHROUGH;
- case SendWho::AREA_WOC:
- if ((sd && sd->chatID) || (bl && bl == src_bl))
+ if (bl && bl == src_bl)
return;
break;
- case SendWho::AREA_WOSC:
- if ((sd) && sd->chatID
- && sd->chatID == ((struct map_session_data *) src_bl)->chatID)
- return;
- break;
}
if (session[sd->fd] != NULL)
@@ -280,9 +268,6 @@ void clif_send_sub(struct block_list *bl, const unsigned char *buf, int len,
static
int clif_send(const uint8_t *buf, int len, struct block_list *bl, SendWho type)
{
- int i;
- struct map_session_data *sd;
- struct chat_data *cd;
struct party *p = NULL;
int x0 = 0, x1 = 0, y0 = 0, y1 = 0;
@@ -300,12 +285,10 @@ int clif_send(const uint8_t *buf, int len, struct block_list *bl, SendWho type)
switch (type)
{
case SendWho::AREA:
- case SendWho::AREA_WOC:
type = SendWho::SELF;
break;
case SendWho::AREA_WOS:
- case SendWho::AREA_WOSC:
return 1;
default:
@@ -318,13 +301,16 @@ int clif_send(const uint8_t *buf, int len, struct block_list *bl, SendWho type)
switch (type)
{
case SendWho::ALL_CLIENT: // 全クライアントに送信
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (sd = (struct map_session_data *)session[i]->session_data) != NULL
- && sd->state.auth)
+ if (!session[i])
+ continue;
+ map_session_data *sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (sd && sd->state.auth)
{
if (clif_parse_func_table[RBUFW(buf, 0)].len)
- { // packet must exist
+ {
+ // packet must exist
memcpy(WFIFOP(i, 0), buf, len);
WFIFOSET(i, len);
}
@@ -332,13 +318,16 @@ int clif_send(const uint8_t *buf, int len, struct block_list *bl, SendWho type)
}
break;
case SendWho::ALL_SAMEMAP: // 同じマップの全クライアントに送信
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (sd = (struct map_session_data *)session[i]->session_data) != NULL
- && sd->state.auth && sd->bl.m == bl->m)
+ if (!session[i])
+ continue;
+ map_session_data *sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (sd && sd->state.auth && sd->bl.m == bl->m)
{
if (clif_parse_func_table[RBUFW(buf, 0)].len)
- { // packet must exist
+ {
+ // packet must exist
memcpy(WFIFOP(i, 0), buf, len);
WFIFOSET(i, len);
}
@@ -347,8 +336,6 @@ int clif_send(const uint8_t *buf, int len, struct block_list *bl, SendWho type)
break;
case SendWho::AREA:
case SendWho::AREA_WOS:
- case SendWho::AREA_WOC:
- case SendWho::AREA_WOSC:
map_foreachinarea(std::bind(clif_send_sub, ph::_1, buf, len, bl, type),
bl->m, bl->x - AREA_SIZE, bl->y - AREA_SIZE,
bl->x + AREA_SIZE, bl->y + AREA_SIZE, BL::PC);
@@ -358,30 +345,6 @@ int clif_send(const uint8_t *buf, int len, struct block_list *bl, SendWho type)
bl->m, bl->x - (AREA_SIZE), bl->y - (AREA_SIZE),
bl->x + (AREA_SIZE), bl->y + (AREA_SIZE), BL::PC);
break;
- case SendWho::CHAT:
- case SendWho::CHAT_WOS:
- cd = (struct chat_data *) bl;
- if (bl->type == BL::PC)
- {
- sd = (struct map_session_data *) bl;
- cd = (struct chat_data *) map_id2bl(sd->chatID);
- }
- else if (bl->type != BL::CHAT)
- break;
- if (cd == NULL)
- break;
- for (i = 0; i < cd->users; i++)
- {
- if (type == SendWho::CHAT_WOS
- && cd->usersd[i] == (struct map_session_data *) bl)
- continue;
- if (clif_parse_func_table[RBUFW(buf, 0)].len)
- { // packet must exist
- memcpy(WFIFOP(cd->usersd[i]->fd, 0), buf, len);
- WFIFOSET(cd->usersd[i]->fd, len);
- }
- }
- break;
case SendWho::PARTY_AREA: // 同じ画面内の全パーティーメンバに送信
case SendWho::PARTY_AREA_WOS: // 自分以外の同じ画面内の全パーティーメンバに送信
@@ -396,7 +359,7 @@ int clif_send(const uint8_t *buf, int len, struct block_list *bl, SendWho type)
case SendWho::PARTY_SAMEMAP_WOS: // 自分以外の同じマップの全パーティーメンバに送信
if (bl->type == BL::PC)
{
- sd = (struct map_session_data *) bl;
+ struct map_session_data *sd = (struct map_session_data *) bl;
if (sd->partyspy > 0)
{
p = party_search(sd->partyspy);
@@ -409,14 +372,14 @@ int clif_send(const uint8_t *buf, int len, struct block_list *bl, SendWho type)
}
if (p)
{
- for (i = 0; i < MAX_PARTY; i++)
+ for (int i = 0; i < MAX_PARTY; i++)
{
- if ((sd = p->member[i].sd) != NULL)
+ struct map_session_data *sd = p->member[i].sd;
+ if (sd)
{
if (sd->bl.id == bl->id && (type == SendWho::PARTY_WOS ||
type == SendWho::PARTY_SAMEMAP_WOS
- || type ==
- SendWho::PARTY_AREA_WOS))
+ || type == SendWho::PARTY_AREA_WOS))
continue;
if (type != SendWho::PARTY && type != SendWho::PARTY_WOS && bl->m != sd->bl.m) // マップチェック
continue;
@@ -425,21 +388,25 @@ int clif_send(const uint8_t *buf, int len, struct block_list *bl, SendWho type)
sd->bl.x > x1 || sd->bl.y > y1))
continue;
if (clif_parse_func_table[RBUFW(buf, 0)].len)
- { // packet must exist
+ {
+ // packet must exist
memcpy(WFIFOP(sd->fd, 0), buf, len);
WFIFOSET(sd->fd, len);
}
}
}
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (sd = (struct map_session_data *)session[i]->session_data) != NULL
- && sd->state.auth)
+ if (!session[i])
+ continue;
+ map_session_data *sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (sd && sd->state.auth)
{
if (sd->partyspy == p->party_id)
{
if (clif_parse_func_table[RBUFW(buf, 0)].len)
- { // packet must exist
+ {
+ // packet must exist
memcpy(WFIFOP(sd->fd, 0), buf, len);
WFIFOSET(sd->fd, len);
}
@@ -449,12 +416,15 @@ int clif_send(const uint8_t *buf, int len, struct block_list *bl, SendWho type)
}
break;
case SendWho::SELF:
- sd = (struct map_session_data *) bl;
+ {
+ map_session_data *sd = (struct map_session_data *) bl;
if (clif_parse_func_table[RBUFW(buf, 0)].len)
- { // packet must exist
+ {
+ // packet must exist
memcpy(WFIFOP(sd->fd, 0), buf, len);
WFIFOSET(sd->fd, len);
}
+ }
break;
default:
@@ -3676,16 +3646,15 @@ int clif_specialeffect(struct block_list *bl, int type, int flag)
if (flag == 2)
{
- struct map_session_data *sd = NULL;
- int i;
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (sd = (struct map_session_data *)session[i]->session_data) != NULL
- && sd->state.auth && sd->bl.m == bl->m)
+ if (!session[i])
+ continue;
+ struct map_session_data *sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (sd && sd->state.auth && sd->bl.m == bl->m)
clif_specialeffect(&sd->bl, type, 1);
}
}
-
else if (flag == 1)
clif_send(buf, clif_parse_func_table[0x19b].len, bl, SendWho::SELF);
else if (!flag)
@@ -3706,7 +3675,6 @@ int clif_specialeffect(struct block_list *bl, int type, int flag)
static
void clif_parse_WantToConnection(int fd, struct map_session_data *sd)
{
- struct map_session_data *old_sd;
int account_id; // account_id in the packet
if (sd)
@@ -3727,7 +3695,8 @@ void clif_parse_WantToConnection(int fd, struct map_session_data *sd)
WFIFOSET(fd, 4);
// if same account already connected, we disconnect the 2 sessions
- if ((old_sd = map_id2sd(account_id)) != NULL)
+ struct map_session_data *old_sd = map_id2sd(account_id);
+ if (old_sd)
{
clif_authfail_fd(fd, 2); // same id
clif_authfail_fd(old_sd->fd, 2); // same id
@@ -3736,8 +3705,8 @@ void clif_parse_WantToConnection(int fd, struct map_session_data *sd)
}
else
{
- CREATE(sd, struct map_session_data, 1);
- session[fd]->session_data = sd;
+ sd = new map_session_data();
+ session[fd]->session_data.reset(sd);
sd->fd = fd;
pc_setnewpc(sd, account_id, RFIFOL(fd, 6), RFIFOL(fd, 10),
@@ -3888,9 +3857,6 @@ void clif_parse_WalkToXY(int fd, struct map_session_data *sd)
if (sd->npc_id != 0 || sd->state.storage_open)
return;
- if (sd->chatID)
- return;
-
if (sd->canmove_tick > gettick())
return;
@@ -4094,8 +4060,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data *sd)
WBUFL(reinterpret_cast<uint8_t *>(buf), 4) = sd->bl.id;
// evil multiuse buffer!
- clif_send((const uint8_t *)buf, msg_len + 8, &sd->bl,
- sd->chatID ? SendWho::CHAT_WOS : SendWho::AREA_CHAT_WOC);
+ clif_send((const uint8_t *)buf, msg_len + 8, &sd->bl, SendWho::AREA_CHAT_WOC);
}
/* Send the message back to the speaker. */
@@ -5583,7 +5548,7 @@ func_table clif_parse_func_table[0x0220] =
static
int clif_check_packet_flood(int fd, int cmd)
{
- struct map_session_data *sd = (struct map_session_data *)session[fd]->session_data;
+ map_session_data *sd = static_cast<map_session_data *>(session[fd]->session_data.get());
tick_t tick = gettick();
// sd will not be set if the client hasn't requested
@@ -5800,7 +5765,7 @@ static
void clif_parse(int fd)
{
int packet_len = 0, cmd = 0;
- struct map_session_data *sd = (struct map_session_data *)session[fd]->session_data;
+ map_session_data *sd = static_cast<map_session_data *>(session[fd]->session_data.get());
if (!sd || (sd && !sd->state.auth))
{
diff --git a/src/map/intif.cpp b/src/map/intif.cpp
index 6c8edf5..6a9008e 100644
--- a/src/map/intif.cpp
+++ b/src/map/intif.cpp
@@ -332,9 +332,9 @@ int intif_parse_WisEnd(int fd)
// Received wisp message from map-server via char-server for ALL gm
static
int mapif_parse_WisToGM(int fd)
-{ // 0x3003/0x3803 <packet_len>.w <wispname>.24B <min_gm_level>.w <message>.?B
- int i, min_gm_level, len;
- struct map_session_data *pl_sd;
+{
+ // 0x3003/0x3803 <packet_len>.w <wispname>.24B <min_gm_level>.w <message>.?B
+ int min_gm_level, len;
char Wisp_name[24];
char mbuf[255];
@@ -350,12 +350,16 @@ int mapif_parse_WisToGM(int fd)
memcpy(message, RFIFOP(fd, 30), len);
message[len - 1] = '\0';
// information is sended to all online GM
- for (i = 0; i < fd_max; i++)
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
- && pl_sd->state.auth)
+ for (int i = 0; i < fd_max; i++)
+ {
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd && pl_sd->state.auth)
if (pc_isGM(pl_sd) >= min_gm_level)
clif_wis_message(i, Wisp_name, message,
strlen(message) + 1);
+ }
if (message != mbuf)
free(message);
diff --git a/src/map/map.cpp b/src/map/map.cpp
index a3f600a..30354c7 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -22,7 +22,6 @@
#include "atcommand.hpp"
#include "battle.hpp"
-#include "chat.hpp"
#include "chrif.hpp"
#include "clif.hpp"
#include "grfio.hpp"
@@ -92,6 +91,11 @@ char wisp_server_name[24] = "Server"; // can be modified in char-server config
static
int map_delmap(const char *mapname);
+void SessionDeleter::operator()(SessionData *sd)
+{
+ delete static_cast<map_session_data *>(sd);
+}
+
/*==========================================
* 全map鯖総計での接続数設定
* (char鯖から送られてくる)
@@ -511,9 +515,8 @@ void map_foreachinmovearea(std::function<void(struct block_list *)> func,
continue;
if ((bl)
&& ((dx > 0 && bl->x < x0 + dx)
- || (dx < 0 && bl->x > x1 + dx) || (dy > 0
- && bl->y <
- y0 + dy)
+ || (dx < 0 && bl->x > x1 + dx)
+ || (dy > 0 && bl->y < y0 + dy)
|| (dy < 0 && bl->y > y1 + dy))
&& bl_list_count < BL_LIST_MAX)
bl_list[bl_list_count++] = bl;
@@ -530,9 +533,8 @@ void map_foreachinmovearea(std::function<void(struct block_list *)> func,
continue;
if ((bl)
&& ((dx > 0 && bl->x < x0 + dx)
- || (dx < 0 && bl->x > x1 + dx) || (dy > 0
- && bl->y <
- y0 + dy)
+ || (dx < 0 && bl->x > x1 + dx)
+ || (dy > 0 && bl->y < y0 + dy)
|| (dy < 0 && bl->y > y1 + dy))
&& bl_list_count < BL_LIST_MAX)
bl_list[bl_list_count++] = bl;
@@ -939,9 +941,6 @@ void map_quit(struct map_session_data *sd)
{
nullpo_retv(sd);
- if (sd->chatID) // チャットから出る
- chat_leavechat(sd);
-
if (sd->trade_partner) // 取引を中断する
trade_tradecancel(sd);
@@ -992,6 +991,8 @@ void map_quit(struct map_session_data *sd)
*/
struct map_session_data *map_id2sd(int id)
{
+ // This is bogus.
+ // However, there might be differences for de-auth'ed accounts.
// remove search from db, because:
// 1 - all players, npc, items and mob are in this db (to search, it's not speed, and search in session is more sure)
// 2 - DB seems not always correct. Sometimes, when a player disconnects, its id (account value) is not removed and structure
@@ -1006,12 +1007,17 @@ struct map_session_data *map_id2sd(int id)
return (struct map_session_data*)bl;
return NULL;
*/
- int i;
- struct map_session_data *sd = NULL;
-
- for (i = 0; i < fd_max; i++)
- if (session[i] && (sd = (struct map_session_data *)session[i]->session_data) && sd->bl.id == id)
- return sd;
+ for (int i = 0; i < fd_max; i++)
+ {
+ if (!session[i])
+ continue;
+ if (session[i]->session_data)
+ {
+ map_session_data *sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (sd->bl.id == id)
+ return sd;
+ }
+ }
return NULL;
}
@@ -1037,11 +1043,14 @@ char *map_charid2nick(int id)
static
struct map_session_data *map_get_session(int i)
{
- struct map_session_data *d;
-
- if (i >= 0 && i < fd_max
- && session[i] && (d = (struct map_session_data *)session[i]->session_data) && d->state.auth)
- return d;
+ if (i >= 0 && i < fd_max)
+ {
+ if (!session[i])
+ return nullptr;
+ map_session_data *d = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (d && d->state.auth)
+ return d;
+ }
return NULL;
}
@@ -1049,8 +1058,7 @@ struct map_session_data *map_get_session(int i)
static
struct map_session_data *map_get_session_forward(int start)
{
- int i;
- for (i = start; i < fd_max; i++)
+ for (int i = start; i < fd_max; i++)
{
struct map_session_data *d = map_get_session(i);
if (d)
@@ -1104,7 +1112,6 @@ struct map_session_data *map_nick2sd(const char *nick)
{
int i, quantity = 0, nicklen;
struct map_session_data *sd = NULL;
- struct map_session_data *pl_sd = NULL;
if (nick == NULL)
return NULL;
@@ -1113,8 +1120,10 @@ struct map_session_data *map_nick2sd(const char *nick)
for (i = 0; i < fd_max; i++)
{
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
- && pl_sd->state.auth)
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd && pl_sd->state.auth)
{
// Without case sensitive check (increase the number of similar character names found)
if (strncasecmp(pl_sd->status.name, nick, nicklen) == 0)
diff --git a/src/map/map.hpp b/src/map/map.hpp
index 374282d..7233241 100644
--- a/src/map/map.hpp
+++ b/src/map/map.hpp
@@ -8,6 +8,7 @@
#include <functional>
#include "../common/db.hpp"
+#include "../common/socket.hpp"
#include "../common/timer.t.hpp"
#include "battle.t.hpp"
@@ -78,7 +79,7 @@ struct quick_regeneration
unsigned char tickdelay; // number of ticks to next update
};
-struct map_session_data
+struct map_session_data : SessionData
{
struct block_list bl;
struct
@@ -143,7 +144,6 @@ struct map_session_data
unsigned storage:1;
unsigned divorce:1;
} npc_flags;
- unsigned int chatID;
Timer attacktimer;
int attacktarget;
@@ -476,22 +476,6 @@ struct flooritem_data
struct item item_data;
};
-struct chat_data
-{
- struct block_list bl;
-
- char pass[8]; /* password */
- char title[61]; /* room title max 60 */
- unsigned char limit; /* join limit */
- unsigned char trigger;
- unsigned char users; /* current users */
- unsigned char pub; /* room attribute */
- struct map_session_data *usersd[20];
- struct block_list *owner_;
- struct block_list **owner;
- char npc_event[50];
-};
-
extern interval_t autosave_interval;
extern int save_settings;
diff --git a/src/map/map.t.hpp b/src/map/map.t.hpp
index c57ea06..172572f 100644
--- a/src/map/map.t.hpp
+++ b/src/map/map.t.hpp
@@ -72,7 +72,6 @@ enum class BL : uint8_t
NPC,
MOB,
ITEM,
- CHAT,
SPELL,
};
enum class NpcSubtype : uint8_t
diff --git a/src/map/mob.cpp b/src/map/mob.cpp
index be9e71d..8921803 100644
--- a/src/map/mob.cpp
+++ b/src/map/mob.cpp
@@ -2695,12 +2695,12 @@ int mob_damage(struct block_list *src, struct mob_data *md, int damage,
sd = mvp_sd;
else
{
- struct map_session_data *tmp_sd;
- int i;
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (tmp_sd = (struct map_session_data *)session[i]->session_data)
- && tmp_sd->state.auth)
+ if (!session[i])
+ continue;
+ map_session_data *tmp_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (tmp_sd && tmp_sd->state.auth)
{
if (md->bl.m == tmp_sd->bl.m)
{
@@ -3060,8 +3060,7 @@ void mobskill_castend_id(TimerData *, tick_t tick, int id)
range = skill_get_range(md->skillid, md->skilllv);
if (range < 0)
range = battle_get_range(&md->bl) - (range + 1);
- if (range + battle_config.mob_skill_add_range <
- distance(md->bl.x, md->bl.y, bl->x, bl->y))
+ if (range + battle_config.mob_skill_add_range < distance(md->bl.x, md->bl.y, bl->x, bl->y))
return;
md->skilldelay[md->skillidx] = tick;
@@ -3113,8 +3112,7 @@ void mobskill_castend_pos(TimerData *, tick_t tick, int id)
range = skill_get_range(md->skillid, md->skilllv);
if (range < 0)
range = battle_get_range(&md->bl) - (range + 1);
- if (range + battle_config.mob_skill_add_range <
- distance(md->bl.x, md->bl.y, md->skillx, md->skilly))
+ if (range + battle_config.mob_skill_add_range < distance(md->bl.x, md->bl.y, md->skillx, md->skilly))
return;
md->skilldelay[md->skillidx] = tick;
diff --git a/src/map/npc.cpp b/src/map/npc.cpp
index c08a0e7..440d1a1 100644
--- a/src/map/npc.cpp
+++ b/src/map/npc.cpp
@@ -854,8 +854,7 @@ int npc_selllist(struct map_session_data *sd, int n,
return 1;
nameid = sd->status.inventory[item_list[i * 2] - 2].nameid;
if (nameid == 0 ||
- sd->status.inventory[item_list[i * 2] - 2].amount <
- item_list[i * 2 + 1])
+ sd->status.inventory[item_list[i * 2] - 2].amount < item_list[i * 2 + 1])
return 1;
if (sd->trade_partner != 0)
return 2; // cant sell while trading
diff --git a/src/map/party.cpp b/src/map/party.cpp
index f737601..594fdf7 100644
--- a/src/map/party.cpp
+++ b/src/map/party.cpp
@@ -126,14 +126,14 @@ int party_request_info(int party_id)
static
int party_check_member(struct party *p)
{
- int i;
- struct map_session_data *sd;
-
nullpo_ret(p);
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (sd = (struct map_session_data *)session[i]->session_data) && sd->state.auth)
+ if (!session[i])
+ continue;
+ map_session_data *sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (sd && sd->state.auth)
{
if (sd->status.party_id == p->party_id)
{
@@ -167,11 +167,12 @@ int party_check_member(struct party *p)
// 情報所得失敗(そのIDのキャラを全部未所属にする)
int party_recv_noinfo(int party_id)
{
- int i;
- struct map_session_data *sd;
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
{
- if (session[i] && (sd = (struct map_session_data *)session[i]->session_data) && sd->state.auth)
+ if (!session[i])
+ continue;
+ map_session_data *sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (sd && sd->state.auth)
{
if (sd->status.party_id == party_id)
sd->status.party_id = 0;
diff --git a/src/map/pc.cpp b/src/map/pc.cpp
index a098978..2699741 100644
--- a/src/map/pc.cpp
+++ b/src/map/pc.cpp
@@ -12,7 +12,6 @@
#include "atcommand.hpp"
#include "battle.hpp"
-#include "chat.hpp"
#include "chrif.hpp"
#include "clif.hpp"
#include "intif.hpp"
@@ -217,7 +216,7 @@ earray<EPOS, EQUIP, EQUIP::COUNT> equip_pos //=
}};
static
-struct gm_account *gm_account = NULL;
+struct GM_Account *gm_accounts = NULL;
static
int GM_num = 0;
@@ -242,8 +241,8 @@ int pc_isGM(struct map_session_data *sd)
nullpo_ret(sd);
for (i = 0; i < GM_num; i++)
- if (gm_account[i].account_id == sd->status.account_id)
- return gm_account[i].level;
+ if (gm_accounts[i].account_id == sd->status.account_id)
+ return gm_accounts[i].level;
return 0;
}
@@ -271,17 +270,17 @@ int pc_set_gm_level(int account_id, int level)
int i;
for (i = 0; i < GM_num; i++)
{
- if (account_id == gm_account[i].account_id)
+ if (account_id == gm_accounts[i].account_id)
{
- gm_account[i].level = level;
+ gm_accounts[i].level = level;
return 0;
}
}
GM_num++;
- RECREATE(gm_account, struct gm_account, GM_num);
- gm_account[GM_num - 1].account_id = account_id;
- gm_account[GM_num - 1].level = level;
+ RECREATE(gm_accounts, struct GM_Account, GM_num);
+ gm_accounts[GM_num - 1].account_id = account_id;
+ gm_accounts[GM_num - 1].level = level;
return 0;
}
@@ -2360,8 +2359,6 @@ int pc_setpos(struct map_session_data *sd, const char *mapname_org, int x, int y
nullpo_ret(sd);
- if (sd->chatID) // チャットから出る
- chat_leavechat(sd);
if (sd->trade_partner) // 取引を中断する
trade_tradecancel(sd);
if (sd->state.storage_open)
@@ -5399,16 +5396,15 @@ void pc_autosave(TimerData *, tick_t)
int pc_read_gm_account(int fd)
{
int i = 0;
- if (gm_account != NULL)
- free(gm_account);
+ if (gm_accounts != NULL)
+ free(gm_accounts);
GM_num = 0;
- CREATE(gm_account, struct gm_account, (RFIFOW(fd, 2) - 4) / 5);
+ CREATE(gm_accounts, struct GM_Account, (RFIFOW(fd, 2) - 4) / 5);
for (i = 4; i < RFIFOW(fd, 2); i = i + 5)
{
- gm_account[GM_num].account_id = RFIFOL(fd, i);
- gm_account[GM_num].level = (int) RFIFOB(fd, i + 4);
- //PRINTF("GM account: %d -> level %d\n", gm_account[GM_num].account_id, gm_account[GM_num].level);
+ gm_accounts[GM_num].account_id = RFIFOL(fd, i);
+ gm_accounts[GM_num].level = (int) RFIFOB(fd, i + 4);
GM_num++;
}
return GM_num;
diff --git a/src/map/pc.hpp b/src/map/pc.hpp
index baf1487..1f2ab71 100644
--- a/src/map/pc.hpp
+++ b/src/map/pc.hpp
@@ -28,11 +28,6 @@ void pc_setdir(struct map_session_data *sd, DIR b)
sd->dir = (b);
}
inline
-void pc_setchatid(struct map_session_data *sd, int n)
-{
- sd->chatID = n;
-}
-inline
bool pc_isinvisible(struct map_session_data *sd)
{
return bool(sd->status.option & Option::HIDE);
diff --git a/src/map/script.cpp b/src/map/script.cpp
index b5e2aca..43bcebf 100644
--- a/src/map/script.cpp
+++ b/src/map/script.cpp
@@ -3551,11 +3551,8 @@ void builtin_getmapflag(ScriptState *st)
static
void builtin_pvpon(ScriptState *st)
{
- int m, i;
- struct map_session_data *pl_sd = NULL;
-
const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- m = map_mapname2mapid(str);
+ int m = map_mapname2mapid(str);
if (m >= 0 && !map[m].flag.pvp && !map[m].flag.nopvp)
{
map[m].flag.pvp = 1;
@@ -3563,10 +3560,12 @@ void builtin_pvpon(ScriptState *st)
if (battle_config.pk_mode) // disable ranking functions if pk_mode is on [Valaris]
return;
- for (i = 0; i < fd_max; i++)
- { //人数分ループ
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
- && pl_sd->state.auth)
+ for (int i = 0; i < fd_max; i++)
+ {
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd && pl_sd->state.auth)
{
if (m == pl_sd->bl.m && !pl_sd->pvp_timer)
{
@@ -3586,11 +3585,8 @@ void builtin_pvpon(ScriptState *st)
static
void builtin_pvpoff(ScriptState *st)
{
- int m, i;
- struct map_session_data *pl_sd = NULL;
-
const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- m = map_mapname2mapid(str);
+ int m = map_mapname2mapid(str);
if (m >= 0 && map[m].flag.pvp && map[m].flag.nopvp)
{
map[m].flag.pvp = 0;
@@ -3598,10 +3594,12 @@ void builtin_pvpoff(ScriptState *st)
if (battle_config.pk_mode) // disable ranking options if pk_mode is on [Valaris]
return;
- for (i = 0; i < fd_max; i++)
- { //人数分ループ
- if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
- && pl_sd->state.auth)
+ for (int i = 0; i < fd_max; i++)
+ {
+ if (!session[i])
+ continue;
+ map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get());
+ if (pl_sd && pl_sd->state.auth)
{
if (m == pl_sd->bl.m)
{
diff --git a/src/map/skill.cpp b/src/map/skill.cpp
index 47a2e5c..31621c8 100644
--- a/src/map/skill.cpp
+++ b/src/map/skill.cpp
@@ -255,10 +255,6 @@ int skill_attack(BF attack_type, struct block_list *src,
return 0;
if (bl->type == BL::PC && pc_isdead((struct map_session_data *) bl)) //対象がPCですでに死んでいたら何もしない
return 0;
- if (src->type == BL::PC && ((struct map_session_data *) src)->chatID) //術者がPCでチャット中なら何もしない
- return 0;
- if (dsrc->type == BL::PC && ((struct map_session_data *) dsrc)->chatID) //術者がPCでチャット中なら何もしない
- return 0;
//何もしない判定ここまで