summaryrefslogtreecommitdiff
path: root/src/char
diff options
context:
space:
mode:
Diffstat (limited to 'src/char')
-rw-r--r--src/char/char.c112
-rw-r--r--src/char/char.h15
-rw-r--r--src/char/inter.c417
3 files changed, 351 insertions, 193 deletions
diff --git a/src/char/char.c b/src/char/char.c
index 9b3f1443d..a6588dc09 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -45,7 +45,6 @@ char inventory_db[256] = "inventory";
char charlog_db[256] = "charlog";
char storage_db[256] = "storage";
char interlog_db[256] = "interlog";
-char reg_db[256] = "global_reg_value";
char skill_db[256] = "skill";
char memo_db[256] = "memo";
char guild_db[256] = "guild";
@@ -71,6 +70,10 @@ char ragsrvinfo_db[256] = "ragsrvinfo";
char elemental_db[256] = "elemental";
char interreg_db[32] = "interreg";
char account_data_db[256] = "account_data";
+char acc_reg_num_db[32] = "acc_reg_num_db";
+char acc_reg_str_db[32] = "acc_reg_str_db";
+char char_reg_str_db[32] = "char_reg_str_db";
+char char_reg_num_db[32] = "char_reg_num_db";
// show loading/saving messages
int save_log = 1;
@@ -1793,7 +1796,9 @@ int delete_char_sql(int char_id)
Sql_ShowDebug(sql_handle);
/* delete character registry */
- if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) )
+ if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", char_reg_str_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", char_reg_num_db, char_id) )
Sql_ShowDebug(sql_handle);
/* delete skills */
@@ -2460,17 +2465,12 @@ int parse_fromlogin(int fd) {
break;
// reply to an account_reg2 registry request
- case 0x2729:
+ case 0x3804:
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
-
- { //Receive account_reg2 registry, forward to map servers.
- unsigned char buf[13+ACCOUNT_REG2_NUM*sizeof(struct global_reg)];
- memcpy(buf,RFIFOP(fd,0), RFIFOW(fd,2));
- WBUFW(buf,0) = 0x3804; //Map server can now receive all kinds of reg values with the same packet. [Skotlex]
- mapif_sendall(buf, WBUFW(buf,2));
+ //Receive account_reg2 registry, forward to map servers.
+ mapif_sendall(RFIFOP(fd, 0), RFIFOW(fd,2));
RFIFOSKIP(fd, RFIFOW(fd,2));
- }
break;
// State change of account/ban notification (from login-server)
@@ -2603,21 +2603,76 @@ int request_accreg2(int account_id, int char_id)
}
return 0;
}
-
-//Send packet forward to login-server for account saving
-int save_accreg2(unsigned char* buf, int len)
-{
- if (login_fd > 0) {
- WFIFOHEAD(login_fd,len+4);
- memcpy(WFIFOP(login_fd,4), buf, len);
- WFIFOW(login_fd,0) = 0x2728;
- WFIFOW(login_fd,2) = len+4;
- WFIFOSET(login_fd,len+4);
- return 1;
+/**
+ * Handles global account reg saving that continues with global_accreg_to_login_add and global_accreg_to_send
+ **/
+void global_accreg_to_login_start (int account_id, int char_id) {
+ WFIFOHEAD(login_fd, 60000 + 300);
+ WFIFOW(login_fd,0) = 0x2728;
+ WFIFOW(login_fd,2) = 14;
+ WFIFOL(login_fd,4) = account_id;
+ WFIFOL(login_fd,8) = char_id;
+ WFIFOW(login_fd,12) = 0;/* count */
+}
+/**
+ * Completes global account reg saving that starts global_accreg_to_login_start and continues with global_accreg_to_login_add
+ **/
+void global_accreg_to_login_send (void) {
+ WFIFOSET(login_fd, WFIFOW(login_fd,2));
+}
+/**
+ * Handles global account reg saving that starts global_accreg_to_login_start and ends with global_accreg_to_send
+ **/
+void global_accreg_to_login_add (const char *key, unsigned int index, intptr_t val, bool is_string) {
+ int nlen = WFIFOW(login_fd, 2);
+ size_t len;
+
+ len = strlen(key)+1;
+
+ WFIFOB(login_fd, nlen) = (unsigned char)len;/* won't be higher; the column size is 32 */
+ nlen += 1;
+
+ safestrncpy((char*)WFIFOP(login_fd,nlen), key, len);
+ nlen += len;
+
+ WFIFOL(login_fd, nlen) = index;
+ nlen += 4;
+
+ if( is_string ) {
+ WFIFOB(login_fd, nlen) = val ? 2 : 3;
+ nlen += 1;
+
+ if( val ) {
+ char *sval = (char*)val;
+ len = strlen(sval)+1;
+
+ WFIFOB(login_fd, nlen) = (unsigned char)len;/* won't be higher; the column size is 254 */
+ nlen += 1;
+
+ safestrncpy((char*)WFIFOP(login_fd,nlen), sval, len);
+ nlen += len;
+ }
+
+ } else {
+ WFIFOB(login_fd, nlen) = val ? 0 : 1;
+ nlen += 1;
+
+ if( val ) {
+ WFIFOL(login_fd, nlen) = (int)val;
+ nlen += 4;
+ }
+
+ }
+
+ WFIFOW(login_fd,12) += 1;
+
+ WFIFOW(login_fd, 2) = nlen;
+ if( WFIFOW(login_fd, 2) > 60000 ) {
+ int account_id = WFIFOL(login_fd,4), char_id = WFIFOL(login_fd,8);
+ global_accreg_to_login_send();
+ global_accreg_to_login_start(account_id,char_id);/* prepare next */
}
- return 0;
}
-
void char_read_fame_list(void) {
int i;
char* data;
@@ -4901,8 +4956,6 @@ void sql_config_read(const char* cfgName)
safestrncpy(charlog_db, w2, sizeof(charlog_db));
else if(!strcmpi(w1,"storage_db"))
safestrncpy(storage_db, w2, sizeof(storage_db));
- else if(!strcmpi(w1,"reg_db"))
- safestrncpy(reg_db, w2, sizeof(reg_db));
else if(!strcmpi(w1,"skill_db"))
safestrncpy(skill_db, w2, sizeof(skill_db));
else if(!strcmpi(w1,"interlog_db"))
@@ -4955,6 +5008,15 @@ void sql_config_read(const char* cfgName)
safestrncpy(interreg_db,w2,sizeof(interreg_db));
else if(!strcmpi(w1,"account_data_db"))
safestrncpy(account_data_db,w2,sizeof(account_data_db));
+ else if(!strcmpi(w1,"char_reg_num_db"))
+ safestrncpy(char_reg_num_db, w2, sizeof(char_reg_num_db));
+ else if(!strcmpi(w1,"char_reg_str_db"))
+ safestrncpy(char_reg_str_db, w2, sizeof(char_reg_str_db));
+ else if(!strcmpi(w1,"acc_reg_str_db"))
+ safestrncpy(acc_reg_str_db, w2, sizeof(acc_reg_str_db));
+ else if(!strcmpi(w1,"acc_reg_num_db"))
+ safestrncpy(acc_reg_num_db, w2, sizeof(acc_reg_num_db));
+
//support the import command, just like any other config
else if(!strcmpi(w1,"import"))
sql_config_read(w2);
diff --git a/src/char/char.h b/src/char/char.h
index c6aa1b66d..3e3774c1f 100644
--- a/src/char/char.h
+++ b/src/char/char.h
@@ -1,5 +1,6 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
+// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+// See the LICENSE file
+// Portions Copyright (c) Athena Dev Teams
#ifndef _CHAR_SQL_H_
#define _CHAR_SQL_H_
@@ -68,7 +69,6 @@ int char_child(int parent_id, int child_id);
int char_family(int pl1,int pl2,int pl3);
int request_accreg2(int account_id, int char_id);
-int save_accreg2(unsigned char* buf, int len);
int login_fd;
extern int char_name_option;
extern char char_name_letters[];
@@ -83,7 +83,6 @@ extern char inventory_db[256];
extern char charlog_db[256];
extern char storage_db[256];
extern char interlog_db[256];
-extern char reg_db[256];
extern char skill_db[256];
extern char memo_db[256];
extern char guild_db[256];
@@ -106,6 +105,10 @@ extern char mercenary_owner_db[256];
extern char ragsrvinfo_db[256];
extern char elemental_db[256];
extern char interreg_db[32];
+extern char acc_reg_num_db[32];
+extern char acc_reg_str_db[32];
+extern char char_reg_str_db[32];
+extern char char_reg_num_db[32];
extern int db_use_sql_item_db;
extern int db_use_sql_mob_db;
@@ -114,4 +117,8 @@ extern int db_use_sql_mob_skill_db;
extern int guild_exp_rate;
extern int log_inter;
+void global_accreg_to_login_start (int account_id, int char_id);
+void global_accreg_to_login_send (void);
+void global_accreg_to_login_add (const char *key, unsigned int index, intptr_t val, bool is_string);
+
#endif /* _CHAR_SQL_H_ */
diff --git a/src/char/inter.c b/src/char/inter.c
index 63e1564ff..34ecebd36 100644
--- a/src/char/inter.c
+++ b/src/char/inter.c
@@ -42,7 +42,6 @@ char char_server_pw[32] = "ragnarok";
char char_server_db[32] = "ragnarok";
char default_codepage[32] = ""; //Feature by irmin.
-static struct accreg *accreg_pt;
unsigned int party_share_level = 10;
// recv. packet list
@@ -592,127 +591,225 @@ void mapif_parse_accinfo(int fd) {
return;
}
-//--------------------------------------------------------
-// Save registry to sql
-int inter_accreg_tosql(int account_id, int char_id, struct accreg* reg, int type)
-{
- struct global_reg* r;
- StringBuf buf;
- int i;
-
- if( account_id <= 0 )
- return 0;
- reg->account_id = account_id;
- reg->char_id = char_id;
-
- //`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`)
- switch( type )
- {
- case 3: //Char Reg
- if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) )
- Sql_ShowDebug(sql_handle);
- account_id = 0;
- break;
- case 2: //Account Reg
- if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `type`=2 AND `account_id`='%d'", reg_db, account_id) )
- Sql_ShowDebug(sql_handle);
- char_id = 0;
- break;
- case 1: //Account2 Reg
- ShowError("inter_accreg_tosql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n");
- return 0;
- default:
- ShowError("inter_accreg_tosql: Invalid type %d\n", type);
- return 0;
- }
-
- if( reg->reg_num <= 0 )
- return 0;
-
- StrBuf->Init(&buf);
- StrBuf->Printf(&buf, "INSERT INTO `%s` (`type`,`account_id`,`char_id`,`str`,`value`) VALUES ", reg_db);
-
- for( i = 0; i < reg->reg_num; ++i ) {
- r = &reg->reg[i];
- if( r->str[0] != '\0' && r->value[0] != '\0' ) {
- char str[32];
- char val[256];
-
- if( i > 0 )
- StrBuf->AppendStr(&buf, ",");
-
- SQL->EscapeString(sql_handle, str, r->str);
- SQL->EscapeString(sql_handle, val, r->value);
-
- StrBuf->Printf(&buf, "('%d','%d','%d','%s','%s')", type, account_id, char_id, str, val);
+/**
+ * Handles save reg data from map server and distributes accordingly.
+ *
+ * @param val either str or int, depending on type
+ * @param type false when int, true otherwise
+ **/
+void inter_savereg(int account_id, int char_id, const char *key, unsigned int index, intptr_t val, bool is_string) {
+ /* to login server we go! */
+ if( key[0] == '#' && key[1] == '#' ) {/* global account reg */
+ global_accreg_to_login_add(key,index,val,is_string);
+ } else if ( key[0] == '#' ) {/* local account reg */
+ if( is_string ) {
+ if( val ) {
+ if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%s')", acc_reg_str_db, account_id, key, index, (char*)val) )
+ Sql_ShowDebug(sql_handle);
+ } else {
+ if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", acc_reg_str_db, account_id, key, index) )
+ Sql_ShowDebug(sql_handle);
+ }
+ } else {
+ if( val ) {
+ if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%d')", acc_reg_num_db, account_id, key, index, (int)val) )
+ Sql_ShowDebug(sql_handle);
+ } else {
+ if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", acc_reg_num_db, account_id, key, index) )
+ Sql_ShowDebug(sql_handle);
+ }
+ }
+ } else { /* char reg */
+ if( is_string ) {
+ if( val ) {
+ if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`char_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%s')", char_reg_str_db, char_id, key, index, (char*)val) )
+ Sql_ShowDebug(sql_handle);
+ } else {
+ if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", char_reg_str_db, char_id, key, index) )
+ Sql_ShowDebug(sql_handle);
+ }
+ } else {
+ if( val ) {
+ if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`char_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%d')", char_reg_num_db, char_id, key, index, (int)val) )
+ Sql_ShowDebug(sql_handle);
+ } else {
+ if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", char_reg_num_db, char_id, key, index) )
+ Sql_ShowDebug(sql_handle);
+ }
}
}
-
- if( SQL_ERROR == SQL->QueryStr(sql_handle, StrBuf->Value(&buf)) ) {
- Sql_ShowDebug(sql_handle);
- }
-
- StrBuf->Destroy(&buf);
-
- return 1;
+
}
// Load account_reg from sql (type=2)
-int inter_accreg_fromsql(int account_id,int char_id, struct accreg *reg, int type)
+int inter_accreg_fromsql(int account_id,int char_id, int fd, int type)
{
- struct global_reg* r;
char* data;
size_t len;
- int i;
+ unsigned int plen = 0;
- if( reg == NULL)
- return 0;
-
- memset(reg, 0, sizeof(struct accreg));
- reg->account_id = account_id;
- reg->char_id = char_id;
+ switch( type ) {
+ case 3: //char reg
+ if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `char_id`='%d'", char_reg_str_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+ break;
+ case 2: //account reg
+ if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", acc_reg_str_db, account_id) )
+ Sql_ShowDebug(sql_handle);
+ break;
+ case 1: //account2 reg
+ ShowError("inter_accreg_fromsql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n");
+ return 0;
+ default:
+ ShowError("inter_accreg_fromsql: Invalid type %d\n", type);
+ return 0;
+ }
+
+ WFIFOHEAD(fd, 60000 + 300);
+ WFIFOW(fd, 0) = 0x3804;
+ /* 0x2 = length, set prior to being sent */
+ WFIFOL(fd, 4) = account_id;
+ WFIFOL(fd, 8) = char_id;
+ WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */
+ WFIFOB(fd, 13) = 1;/* is string type */
+ WFIFOW(fd, 14) = 0;/* count */
+ plen = 16;
+
+ /**
+ * Vessel!
+ *
+ * str type
+ * { keyLength(B), key(<keyLength>), index(L), valLength(B), val(<valLength>) }
+ **/
+ while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) {
+
+ SQL->GetData(sql_handle, 0, &data, NULL);
+ len = strlen(data)+1;
+
+ WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 32 */
+ plen += 1;
+
+ safestrncpy((char*)WFIFOP(fd,plen), data, len);
+ plen += len;
+
+ SQL->GetData(sql_handle, 1, &data, NULL);
+
+ WFIFOL(fd, plen) = (unsigned int)atol(data);
+ plen += 4;
+
+ SQL->GetData(sql_handle, 2, &data, NULL);
+ len = strlen(data)+1;
+
+ WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 254 */
+ plen += 1;
+
+ safestrncpy((char*)WFIFOP(fd,plen), data, len);
+ plen += len;
+
+ WFIFOW(fd, 14) += 1;
+
+ if( plen > 60000 ) {
+ WFIFOW(fd, 2) = plen;
+ WFIFOSET(fd, plen);
+
+ /* prepare follow up */
+ WFIFOHEAD(fd, 60000 + 300);
+ WFIFOW(fd, 0) = 0x3804;
+ /* 0x2 = length, set prior to being sent */
+ WFIFOL(fd, 4) = account_id;
+ WFIFOL(fd, 8) = char_id;
+ WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */
+ WFIFOB(fd, 13) = 1;/* is string type */
+ WFIFOW(fd, 14) = 0;/* count */
+ plen = 16;
+ }
+ }
+
+ /* mark & go. */
+ WFIFOW(fd, 2) = plen;
+ WFIFOSET(fd, plen);
- //`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`)
- switch( type )
- {
- case 3: //char reg
- if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `str`, `value` FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) )
- Sql_ShowDebug(sql_handle);
- break;
- case 2: //account reg
- if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `str`, `value` FROM `%s` WHERE `type`=2 AND `account_id`='%d'", reg_db, account_id) )
- Sql_ShowDebug(sql_handle);
- break;
- case 1: //account2 reg
- ShowError("inter_accreg_fromsql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n");
- return 0;
- default:
- ShowError("inter_accreg_fromsql: Invalid type %d\n", type);
- return 0;
+ SQL->FreeResult(sql_handle);
+
+ switch( type ) {
+ case 3: //char reg
+ if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `char_id`='%d'", char_reg_num_db, char_id) )
+ Sql_ShowDebug(sql_handle);
+ break;
+ case 2: //account reg
+ if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", acc_reg_num_db, account_id) )
+ Sql_ShowDebug(sql_handle);
+ break;
+ case 1: //account2 reg
+ ShowError("inter_accreg_fromsql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n");
+ return 0;
}
- for( i = 0; i < MAX_REG_NUM && SQL_SUCCESS == SQL->NextRow(sql_handle); ++i )
- {
- r = &reg->reg[i];
- // str
- SQL->GetData(sql_handle, 0, &data, &len);
- memcpy(r->str, data, min(len, sizeof(r->str)));
- // value
- SQL->GetData(sql_handle, 1, &data, &len);
- memcpy(r->value, data, min(len, sizeof(r->value)));
+
+ WFIFOHEAD(fd, 60000 + 300);
+ WFIFOW(fd, 0) = 0x3804;
+ /* 0x2 = length, set prior to being sent */
+ WFIFOL(fd, 4) = account_id;
+ WFIFOL(fd, 8) = char_id;
+ WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */
+ WFIFOB(fd, 13) = 0;/* is int type */
+ WFIFOW(fd, 14) = 0;/* count */
+ plen = 16;
+
+ /**
+ * Vessel!
+ *
+ * int type
+ * { keyLength(B), key(<keyLength>), index(L), value(L) }
+ **/
+ while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) {
+
+ SQL->GetData(sql_handle, 0, &data, NULL);
+ len = strlen(data)+1;
+
+ WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 32 */
+ plen += 1;
+
+ safestrncpy((char*)WFIFOP(fd,plen), data, len);
+ plen += len;
+
+ SQL->GetData(sql_handle, 1, &data, NULL);
+
+ WFIFOL(fd, plen) = (unsigned int)atol(data);
+ plen += 4;
+
+ SQL->GetData(sql_handle, 2, &data, NULL);
+
+ WFIFOL(fd, plen) = atoi(data);
+ plen += 4;
+
+ WFIFOW(fd, 14) += 1;
+
+ if( plen > 60000 ) {
+ WFIFOW(fd, 2) = plen;
+ WFIFOSET(fd, plen);
+
+ /* prepare follow up */
+ WFIFOHEAD(fd, 60000 + 300);
+ WFIFOW(fd, 0) = 0x3804;
+ /* 0x2 = length, set prior to being sent */
+ WFIFOL(fd, 4) = account_id;
+ WFIFOL(fd, 8) = char_id;
+ WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */
+ WFIFOB(fd, 13) = 0;/* is int type */
+ WFIFOW(fd, 14) = 0;/* count */
+ plen = 16;
+ }
}
- reg->reg_num = i;
+
+ /* mark as complete & go. */
+ WFIFOB(fd, 12) = type;
+ WFIFOW(fd, 2) = plen;
+ WFIFOSET(fd, plen);
+
SQL->FreeResult(sql_handle);
return 1;
}
-// Initialize
-int inter_accreg_sql_init(void)
-{
- CREATE(accreg_pt, struct accreg, 1);
- return 0;
-
-}
-
/*==========================================
* read config file
*------------------------------------------*/
@@ -833,7 +930,6 @@ int inter_init_sql(const char *file)
inter_homunculus_sql_init();
inter_mercenary_sql_init();
inter_elemental_sql_init();
- inter_accreg_sql_init();
inter_mail_sql_init();
inter_auction_sql_init();
@@ -857,8 +953,6 @@ void inter_final(void)
inter_mail_sql_final();
inter_auction_sql_final();
- if (accreg_pt) aFree(accreg_pt);
-
do_final_msg();
return;
}
@@ -921,36 +1015,15 @@ int mapif_wis_end(struct WisData *wd, int flag)
}
// Account registry transfer to map-server
-static void mapif_account_reg(int fd, unsigned char *src)
-{
- WBUFW(src,0)=0x3804; //NOTE: writing to RFIFO
- mapif_sendallwos(fd, src, WBUFW(src,2));
-}
+//static void mapif_account_reg(int fd, unsigned char *src)
+//{
+// WBUFW(src,0)=0x3804; //NOTE: writing to RFIFO
+// mapif_sendallwos(fd, src, WBUFW(src,2));
+//}
// Send the requested account_reg
-int mapif_account_reg_reply(int fd,int account_id,int char_id, int type)
-{
- struct accreg *reg=accreg_pt;
- WFIFOHEAD(fd, 13 + 5000);
- inter_accreg_fromsql(account_id,char_id,reg,type);
-
- WFIFOW(fd,0)=0x3804;
- WFIFOL(fd,4)=account_id;
- WFIFOL(fd,8)=char_id;
- WFIFOB(fd,12)=type;
- if(reg->reg_num==0){
- WFIFOW(fd,2)=13;
- }else{
- int i,p;
- for (p=13,i = 0; i < reg->reg_num && p < 5000; i++) {
- p+= sprintf((char*)WFIFOP(fd,p), "%s", reg->reg[i].str)+1; //We add 1 to consider the '\0' in place.
- p+= sprintf((char*)WFIFOP(fd,p), "%s", reg->reg[i].value)+1;
- }
- WFIFOW(fd,2)=p;
- if (p>= 5000)
- ShowWarning("Too many acc regs for %d:%d, not all values were loaded.\n", account_id, char_id);
- }
- WFIFOSET(fd,WFIFOW(fd,2));
+int mapif_account_reg_reply(int fd,int account_id,int char_id, int type) {
+ inter_accreg_fromsql(account_id,char_id,fd,type);
return 0;
}
@@ -1128,34 +1201,50 @@ int mapif_parse_WisToGM(int fd)
// Save account_reg into sql (type=2)
int mapif_parse_Registry(int fd)
{
- int j,p,len, max;
- struct accreg *reg=accreg_pt;
-
- memset(accreg_pt,0,sizeof(struct accreg));
- switch (RFIFOB(fd, 12)) {
- case 3: //Character registry
- max = GLOBAL_REG_NUM;
- break;
- case 2: //Account Registry
- max = ACCOUNT_REG_NUM;
- break;
- case 1: //Account2 registry, must be sent over to login server.
- return save_accreg2(RFIFOP(fd,4), RFIFOW(fd,2)-4);
- default:
- return 1;
- }
- for(j=0,p=13;j<max && p<RFIFOW(fd,2);j++){
- sscanf((char*)RFIFOP(fd,p), "%31c%n",reg->reg[j].str,&len);
- reg->reg[j].str[len]='\0';
- p +=len+1; //+1 to skip the '\0' between strings.
- sscanf((char*)RFIFOP(fd,p), "%255c%n",reg->reg[j].value,&len);
- reg->reg[j].value[len]='\0';
- p +=len+1;
- }
- reg->reg_num=j;
+ int account_id = RFIFOL(fd, 4), char_id = RFIFOL(fd, 8), count = RFIFOW(fd, 12);
+
+ if( count ) {
+ int cursor = 14, i;
+ char key[32], sval[254];
+ unsigned int index;
+
+ global_accreg_to_login_start(account_id,char_id);
+
+ for(i = 0; i < count; i++) {
+ safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor));
+ cursor += RFIFOB(fd, cursor) + 1;
+
+ index = RFIFOL(fd, cursor);
+ cursor += 4;
+
+ switch (RFIFOB(fd, cursor++)) {
+ /* int */
+ case 0:
+ inter_savereg(account_id,char_id,key,index,RFIFOL(fd, cursor),false);
+ cursor += 4;
+ break;
+ case 1:
+ inter_savereg(account_id,char_id,key,index,0,false);
+ break;
+ /* str */
+ case 2:
+ safestrncpy(sval, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor));
+ cursor += RFIFOB(fd, cursor) + 1;
+ inter_savereg(account_id,char_id,key,index,(intptr_t)sval,true);
+ break;
+ case 3:
+ inter_savereg(account_id,char_id,key,index,0,true);
+ break;
+
+ default:
+ ShowError("mapif_parse_Registry: unknown type %d\n",RFIFOB(fd, cursor - 1));
+ return 1;
+ }
- inter_accreg_tosql(RFIFOL(fd,4),RFIFOL(fd,8),reg, RFIFOB(fd,12));
- mapif_account_reg(fd,RFIFOP(fd,0)); // Send updated accounts to other map servers.
+ }
+
+ global_accreg_to_login_send();
+ }
return 0;
}