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