summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/char/char.c95
-rw-r--r--src/char/char.h3
-rw-r--r--src/char/inter.c109
-rw-r--r--src/char/inter.h13
-rw-r--r--src/char/mapif.c3
-rw-r--r--src/char/mapif.h2
6 files changed, 145 insertions, 80 deletions
diff --git a/src/char/char.c b/src/char/char.c
index 3f55bd699..04db83eb9 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -1534,12 +1534,56 @@ int char_rename_char_sql(struct char_session_data *sd, int char_id)
return 0;
}
-int char_check_char_name(char * name, char * esc_name)
+/**
+ * Checks if the given name exists in the database.
+ *
+ * @param name The name to check.
+ * @param esc_name Escaped version of the name, optional for faster processing.
+ * @retval true if the character name already exists.
+ */
+bool char_name_exists(const char *name, const char *esc_name)
+{
+ char esc_name2[NAME_LENGTH * 2 + 1];
+
+ nullpo_retr(true, name);
+
+ if (esc_name == NULL) {
+ SQL->EscapeStringLen(inter->sql_handle, esc_name2, name, strnlen(name, NAME_LENGTH));
+ esc_name = esc_name2;
+ }
+
+ if (name_ignoring_case) {
+ if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT 1 FROM `%s` WHERE BINARY `name` = '%s' LIMIT 1", char_db, esc_name)) {
+ Sql_ShowDebug(inter->sql_handle);
+ return true;
+ }
+ } else {
+ if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT 1 FROM `%s` WHERE `name` = '%s' LIMIT 1", char_db, esc_name)) {
+ Sql_ShowDebug(inter->sql_handle);
+ return true;
+ }
+ }
+ if (SQL->NumRows(inter->sql_handle) > 0)
+ return true;
+
+ return false;
+}
+
+/**
+ * Checks if the given name is valid for a new character.
+ *
+ * @param name The name to check.
+ * @param esc_name Escaped version of the name, optional for faster processing.
+ * @retval 0 if the name is valid.
+ * @retval -1 if the name already exists or is reserved
+ * @retval -2 if the name is too short or contains special characters.
+ * @retval -5 if the name contains forbidden characters.
+ */
+int char_check_char_name(const char *name, const char *esc_name)
{
int i;
nullpo_retr(-2, name);
- nullpo_retr(-2, esc_name);
// check length of character name
if (name[0] == '\0')
@@ -1550,9 +1594,16 @@ int char_check_char_name(char * name, char * esc_name)
**/
if( strlen( name ) < 4 )
return -2;
- // check content of character name
- if( remove_control_chars(name) )
- return -2; // control chars in name
+
+ {
+ // check content of character name
+ char *name_copy = aStrdup(name);
+ if (remove_control_chars(name_copy)) {
+ aFree(name_copy);
+ return -2; // control chars in name
+ }
+ aFree(name_copy);
+ }
// check for reserved names
if( strcmpi(name, wisp_server_name) == 0 )
@@ -1571,19 +1622,9 @@ int char_check_char_name(char * name, char * esc_name)
if( strchr(char_name_letters, name[i]) != NULL )
return -5;
}
- if( name_ignoring_case ) {
- if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT 1 FROM `%s` WHERE BINARY `name` = '%s' LIMIT 1", char_db, esc_name) ) {
- Sql_ShowDebug(inter->sql_handle);
- return -2;
- }
- } else {
- if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT 1 FROM `%s` WHERE `name` = '%s' LIMIT 1", char_db, esc_name) ) {
- Sql_ShowDebug(inter->sql_handle);
- return -2;
- }
- }
- if( SQL->NumRows(inter->sql_handle) > 0 )
- return -1; // name already exists
+
+ if (chr->name_exists(name, esc_name))
+ return -1;
return 0;
}
@@ -2550,14 +2591,14 @@ void char_parse_fromlogin_update_ip(int fd)
void char_parse_fromlogin_accinfo2_failed(int fd)
{
- mapif->parse_accinfo2(false, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14),
+ inter->accinfo2(false, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14),
NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1, 0, 0);
RFIFOSKIP(fd,18);
}
void char_parse_fromlogin_accinfo2_ok(int fd)
{
- mapif->parse_accinfo2(true, RFIFOL(fd,167), RFIFOL(fd,171), RFIFOL(fd,175), RFIFOL(fd,179),
+ inter->accinfo2(true, RFIFOL(fd,167), RFIFOL(fd,171), RFIFOL(fd,175), RFIFOL(fd,179),
RFIFOP(fd,2), RFIFOP(fd,26), RFIFOP(fd,59), RFIFOP(fd,99), RFIFOP(fd,119),
RFIFOP(fd,151), RFIFOP(fd,156), RFIFOL(fd,115), RFIFOL(fd,143), RFIFOL(fd,147));
RFIFOSKIP(fd,183);
@@ -4727,7 +4768,6 @@ void char_parse_char_rename_char(int fd, struct char_session_data* sd)
{
int i, cid =RFIFOL(fd,2);
char name[NAME_LENGTH];
- char esc_name[NAME_LENGTH*2+1];
safestrncpy(name, RFIFOP(fd,6), NAME_LENGTH);
RFIFOSKIP(fd,30);
@@ -4736,8 +4776,7 @@ void char_parse_char_rename_char(int fd, struct char_session_data* sd)
return;
normalize_name(name,TRIM_CHARS);
- SQL->EscapeStringLen(inter->sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
- if( !chr->check_char_name(name,esc_name) ) {
+ if (chr->check_char_name(name, NULL) == 0) {
i = 1;
safestrncpy(sd->new_name, name, NAME_LENGTH);
} else {
@@ -4752,7 +4791,6 @@ void char_parse_char_rename_char2(int fd, struct char_session_data* sd)
{
int i, aid = RFIFOL(fd,2), cid =RFIFOL(fd,6);
char name[NAME_LENGTH];
- char esc_name[NAME_LENGTH*2+1];
safestrncpy(name, RFIFOP(fd,10), NAME_LENGTH);
RFIFOSKIP(fd,34);
@@ -4763,14 +4801,12 @@ void char_parse_char_rename_char2(int fd, struct char_session_data* sd)
return;
normalize_name(name,TRIM_CHARS);
- SQL->EscapeStringLen(inter->sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
- if( !chr->check_char_name(name,esc_name) )
- {
+ if (chr->check_char_name(name, NULL) == 0) {
i = 1;
safestrncpy(sd->new_name, name, NAME_LENGTH);
- }
- else
+ } else {
i = 0;
+ }
chr->allow_rename(fd, i);
}
@@ -6316,6 +6352,7 @@ void char_defaults(void)
chr->mmo_char_sql_init = char_mmo_char_sql_init;
chr->char_slotchange = char_char_slotchange;
chr->rename_char_sql = char_rename_char_sql;
+ chr->name_exists = char_name_exists;
chr->check_char_name = char_check_char_name;
chr->make_new_char_sql = char_make_new_char_sql;
chr->divorce_char_sql = char_divorce_char_sql;
diff --git a/src/char/char.h b/src/char/char.h
index a644f11ab..4d816583a 100644
--- a/src/char/char.h
+++ b/src/char/char.h
@@ -147,7 +147,8 @@ struct char_interface {
int (*mmo_char_sql_init) (void);
bool (*char_slotchange) (struct char_session_data *sd, int fd, unsigned short from, unsigned short to);
int (*rename_char_sql) (struct char_session_data *sd, int char_id);
- int (*check_char_name) (char * name, char * esc_name);
+ bool (*name_exists) (const char *name, const char *esc_name);
+ int (*check_char_name) (const char *name, const char *esc_name);
int (*make_new_char_sql) (struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short starting_job, uint8 sex);
int (*divorce_char_sql) (int partner_id1, int partner_id2);
int (*count_users) (void);
diff --git a/src/char/inter.c b/src/char/inter.c
index cd363e8a2..1fdb61e70 100644
--- a/src/char/inter.c
+++ b/src/char/inter.c
@@ -81,11 +81,6 @@ int inter_recv_packet_length[] = {
-1,10,-1, 6, 0, 20,10,11, -1,6 + NAME_LENGTH, 0, 0, 0, 0, 0, 0, // 3090- Homunculus packets [albator], RoDEX packets
};
-struct WisData {
- int id, fd, count, len;
- int64 tick;
- unsigned char src[24], dst[24], msg[512];
-};
static struct DBMap *wis_db = NULL; // int wis_id -> struct WisData*
static int wis_dellist[WISDELLIST_MAX], wis_delnum;
@@ -446,15 +441,12 @@ void inter_msg_to_fd(int fd, int u_fd, int aid, char *msg, ...)
}
/* [Dekamaster/Nightroad] */
-void mapif_parse_accinfo(int fd)
+void inter_accinfo(int u_fd, int aid, int castergroup, const char *query, int map_fd)
{
- int u_fd = RFIFOL(fd,2), aid = RFIFOL(fd,6), castergroup = RFIFOL(fd,10);
- char query[NAME_LENGTH], query_esq[NAME_LENGTH*2+1];
+ char query_esq[NAME_LENGTH*2+1];
int account_id;
char *data;
- safestrncpy(query, RFIFOP(fd,14), NAME_LENGTH);
-
SQL->EscapeString(inter->sql_handle, query_esq, query);
account_id = atoi(query);
@@ -464,10 +456,10 @@ void mapif_parse_accinfo(int fd)
if ( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `account_id`,`name`,`class`,`base_level`,`job_level`,`online` FROM `%s` WHERE `name` LIKE '%s' LIMIT 10", char_db, query_esq)
|| SQL->NumRows(inter->sql_handle) == 0 ) {
if( SQL->NumRows(inter->sql_handle) == 0 ) {
- inter->msg_to_fd(fd, u_fd, aid, "No matches were found for your criteria, '%s'",query);
+ inter->msg_to_fd(map_fd, u_fd, aid, "No matches were found for your criteria, '%s'",query);
} else {
Sql_ShowDebug(inter->sql_handle);
- inter->msg_to_fd(fd, u_fd, aid, "An error occurred, bother your admin about it.");
+ inter->msg_to_fd(map_fd, u_fd, aid, "An error occurred, bother your admin about it.");
}
SQL->FreeResult(inter->sql_handle);
return;
@@ -477,7 +469,7 @@ void mapif_parse_accinfo(int fd)
SQL->GetData(inter->sql_handle, 0, &data, NULL); account_id = atoi(data);
SQL->FreeResult(inter->sql_handle);
} else {// more than one, listing... [Dekamaster/Nightroad]
- inter->msg_to_fd(fd, u_fd, aid, "Your query returned the following %d results, please be more specific...",(int)SQL->NumRows(inter->sql_handle));
+ inter->msg_to_fd(map_fd, u_fd, aid, "Your query returned the following %d results, please be more specific...",(int)SQL->NumRows(inter->sql_handle));
while ( SQL_SUCCESS == SQL->NextRow(inter->sql_handle) ) {
int class;
int base_level, job_level, online;
@@ -490,7 +482,7 @@ void mapif_parse_accinfo(int fd)
SQL->GetData(inter->sql_handle, 4, &data, NULL); job_level = atoi(data);
SQL->GetData(inter->sql_handle, 5, &data, NULL); online = atoi(data);
- inter->msg_to_fd(fd, u_fd, aid, "[AID: %d] %s | %s | Level: %d/%d | %s", account_id, name, inter->job_name(class), base_level, job_level, online?"Online":"Offline");
+ inter->msg_to_fd(map_fd, u_fd, aid, "[AID: %d] %s | %s | Level: %d/%d | %s", account_id, name, inter->job_name(class), base_level, job_level, online?"Online":"Offline");
}
SQL->FreeResult(inter->sql_handle);
return;
@@ -501,12 +493,23 @@ void mapif_parse_accinfo(int fd)
/* it will only get here if we have a single match */
/* and we will send packet with account id to login server asking for account info */
if( account_id ) {
- mapif->on_parse_accinfo(account_id, u_fd, aid, castergroup, fd);
+ mapif->on_parse_accinfo(account_id, u_fd, aid, castergroup, map_fd);
}
return;
}
-void mapif_parse_accinfo2(bool success, int map_fd, int u_fd, int u_aid, int account_id, const char *userid, const char *user_pass,
+
+void mapif_parse_accinfo(int fd)
+{
+ char query[NAME_LENGTH];
+ int u_fd = RFIFOL(fd,2), aid = RFIFOL(fd,6), castergroup = RFIFOL(fd,10);
+
+ safestrncpy(query, RFIFOP(fd,14), NAME_LENGTH);
+
+ inter->accinfo(u_fd, aid, castergroup, query, fd);
+}
+
+void inter_accinfo2(bool success, int map_fd, int u_fd, int u_aid, int account_id, const char *userid, const char *user_pass,
const char *email, const char *last_ip, const char *lastlogin, const char *pin_code, const char *birthdate,
int group_id, int logincount, int state)
{
@@ -1147,6 +1150,38 @@ int inter_check_ttl_wisdata(void)
return 0;
}
+struct WisData *inter_add_wisdata(int fd, const unsigned char *src, const unsigned char *dst, const unsigned char *msg, int msg_len)
+{
+ static int wisid = 0;
+ struct WisData *wd;
+
+ CREATE(wd, struct WisData, 1);
+
+ // Whether the failure of previous wisp/page transmission (timeout)
+ inter->check_ttl_wisdata();
+
+ wd->id = ++wisid;
+ wd->fd = fd;
+ wd->len = msg_len;
+ memcpy(wd->src, src, NAME_LENGTH);
+ memcpy(wd->dst, dst, NAME_LENGTH);
+ memcpy(wd->msg, msg, wd->len);
+ wd->tick = timer->gettick();
+ idb_put(wis_db, wd->id, wd);
+
+ return wd;
+}
+
+struct WisData *inter_get_wisdata(int id)
+{
+ return idb_get(wis_db, id);
+}
+
+void inter_remove_wisdata(int id)
+{
+ idb_remove(wis_db, id);
+}
+
//--------------------------------------------------------
// broadcast sending
@@ -1162,7 +1197,6 @@ int mapif_parse_WisRequest(int fd)
{
struct WisData* wd;
char name[NAME_LENGTH];
- char esc_name[NAME_LENGTH*2+1];// escaped name
char* data;
size_t len;
@@ -1179,17 +1213,12 @@ int mapif_parse_WisRequest(int fd)
safestrncpy(name, RFIFOP(fd,28), NAME_LENGTH); //Received name may be too large and not contain \0! [Skotlex]
- SQL->EscapeStringLen(inter->sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
- if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `name` FROM `%s` WHERE `name`='%s'", char_db, esc_name) )
- Sql_ShowDebug(inter->sql_handle);
-
// search if character exists before to ask all map-servers
- if( SQL_SUCCESS != SQL->NextRow(inter->sql_handle) )
- {
+ if (!chr->name_exists(name, NULL)) {
mapif->wis_response(fd, RFIFOP(fd, 4), 1);
- }
- else
- {// Character exists. So, ask all map-servers
+ } else {
+ // Character exists. So, ask all map-servers
+
// to be sure of the correct name, rewrite it
SQL->GetData(inter->sql_handle, 0, &data, &len);
memset(name, 0, NAME_LENGTH);
@@ -1197,23 +1226,8 @@ int mapif_parse_WisRequest(int fd)
// if source is destination, don't ask other servers.
if (strncmp(RFIFOP(fd,4), name, NAME_LENGTH) == 0) {
mapif->wis_response(fd, RFIFOP(fd, 4), 1);
- }
- else
- {
- static int wisid = 0;
- CREATE(wd, struct WisData, 1);
-
- // Whether the failure of previous wisp/page transmission (timeout)
- inter->check_ttl_wisdata();
-
- wd->id = ++wisid;
- wd->fd = fd;
- wd->len= RFIFOW(fd,2)-52;
- memcpy(wd->src, RFIFOP(fd, 4), NAME_LENGTH);
- memcpy(wd->dst, RFIFOP(fd,28), NAME_LENGTH);
- memcpy(wd->msg, RFIFOP(fd,52), wd->len);
- wd->tick = timer->gettick();
- idb_put(wis_db, wd->id, wd);
+ } else {
+ wd = inter->add_wisdata(fd, RFIFOP(fd, 4), RFIFOP(fd, 28), RFIFOP(fd, 52), RFIFOW(fd, 2) - 52);
mapif->wis_message(wd);
}
}
@@ -1231,13 +1245,13 @@ int mapif_parse_WisReply(int fd)
id = RFIFOL(fd,2);
flag = RFIFOB(fd,6);
- wd = (struct WisData*)idb_get(wis_db, id);
+ wd = inter->get_wisdata(id);
if (wd == NULL)
return 0; // This wisp was probably suppress before, because it was timeout of because of target was found on another map-server
if ((--wd->count) <= 0 || flag != 1) {
mapif->wis_end(wd, flag); // flag: 0: success to send whisper, 1: target character is not logged in?, 2: ignored by target
- idb_remove(wis_db, id);
+ inter->remove_wisdata(id);
}
return 0;
@@ -1461,4 +1475,9 @@ void inter_defaults(void)
inter->final = inter_final;
inter->config_read_log = inter_config_read_log;
inter->config_read_connection = inter_config_read_connection;
+ inter->accinfo = inter_accinfo;
+ inter->accinfo2 = inter_accinfo2;
+ inter->add_wisdata = inter_add_wisdata;
+ inter->get_wisdata = inter_get_wisdata;
+ inter->remove_wisdata = inter_remove_wisdata;
}
diff --git a/src/char/inter.h b/src/char/inter.h
index 7f901927c..94ee3ab60 100644
--- a/src/char/inter.h
+++ b/src/char/inter.h
@@ -30,6 +30,12 @@
struct Sql; // common/sql.h
struct config_t; // common/conf.h
+struct WisData {
+ int id, fd, count, len;
+ int64 tick;
+ unsigned char src[24], dst[24], msg[512];
+};
+
/**
* inter interface
**/
@@ -56,6 +62,13 @@ struct inter_interface {
bool (*config_read) (const char *filename, bool imported);
bool (*config_read_log) (const char *filename, const struct config_t *config, bool imported);
bool (*config_read_connection) (const char *filename, const struct config_t *config, bool imported);
+ void (*accinfo) (int u_fd, int aid, int castergroup, const char *query, int map_fd);
+ void (*accinfo2) (bool success, int map_fd, int u_fd, int u_aid, int account_id, const char *userid, const char *user_pass,
+ const char *email, const char *last_ip, const char *lastlogin, const char *pin_code, const char *birthdate,
+ int group_id, int logincount, int state);
+ struct WisData *(*add_wisdata) (int fd, const unsigned char *src, const unsigned char *dst, const unsigned char *msg, int msg_len);
+ struct WisData *(*get_wisdata) (int id);
+ void (*remove_wisdata) (int id);
};
#ifdef HERCULES_CORE
diff --git a/src/char/mapif.c b/src/char/mapif.c
index 1dfa08b82..269bfc397 100644
--- a/src/char/mapif.c
+++ b/src/char/mapif.c
@@ -2013,8 +2013,6 @@ void mapif_parse_ItemBoundRetrieve(int fd)
}
void mapif_parse_accinfo(int fd);
-void mapif_parse_accinfo2(bool success, int map_fd, int u_fd, int u_aid, int account_id, const char *userid, const char *user_pass,
- const char *email, const char *last_ip, const char *lastlogin, const char *pin_code, const char *birthdate, int group_id, int logincount, int state);
int mapif_broadcast(const unsigned char *mes, int len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY, int sfd);
int mapif_wis_message(struct WisData *wd);
void mapif_wis_response(int fd, const unsigned char *src, int flag);
@@ -2208,7 +2206,6 @@ void mapif_defaults(void) {
mapif->itembound_ack = mapif_itembound_ack;
mapif->parse_ItemBoundRetrieve = mapif_parse_ItemBoundRetrieve;
mapif->parse_accinfo = mapif_parse_accinfo;
- mapif->parse_accinfo2 = mapif_parse_accinfo2;
mapif->broadcast = mapif_broadcast;
mapif->wis_message = mapif_wis_message;
mapif->wis_response = mapif_wis_response;
diff --git a/src/char/mapif.h b/src/char/mapif.h
index c5dd86f8f..d67ce1c79 100644
--- a/src/char/mapif.h
+++ b/src/char/mapif.h
@@ -174,8 +174,6 @@ struct mapif_interface {
int (*itembound_ack) (int fd, int aid, int guild_id);
void (*parse_ItemBoundRetrieve) (int fd);
void (*parse_accinfo) (int fd);
- void (*parse_accinfo2) (bool success, int map_fd, int u_fd, int u_aid, int account_id, const char *userid, const char *user_pass,
- const char *email, const char *last_ip, const char *lastlogin, const char *pin_code, const char *birthdate, int group_id, int logincount, int state);
int (*broadcast) (const unsigned char *mes, int len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY, int sfd);
int (*wis_message) (struct WisData *wd);
void (*wis_response) (int fd, const unsigned char *src, int flag);