summaryrefslogtreecommitdiff
path: root/src/login
diff options
context:
space:
mode:
Diffstat (limited to 'src/login')
-rw-r--r--src/login/account.h10
-rw-r--r--src/login/account_sql.c271
-rw-r--r--src/login/login.c51
-rw-r--r--src/login/login.h5
4 files changed, 225 insertions, 112 deletions
diff --git a/src/login/account.h b/src/login/account.h
index f55e38b0c..74a9e9626 100644
--- a/src/login/account.h
+++ b/src/login/account.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 __ACCOUNT_H_INCLUDED__
#define __ACCOUNT_H_INCLUDED__
@@ -32,8 +33,6 @@ struct mmo_account
char lastlogin[24]; // date+time of last successful login
char last_ip[16]; // save of last IP of connection
char birthdate[10+1]; // assigned birth date (format: YYYY-MM-DD, default: 0000-00-00)
- int account_reg2_num;
- struct global_reg account_reg2[ACCOUNT_REG2_NUM]; // account script variables (stored on login server)
};
@@ -137,4 +136,7 @@ struct AccountDB
Sql *account_db_sql_up(AccountDB* self);
+void mmo_send_accreg2(AccountDB* self, int fd, int account_id, int char_id);
+void mmo_save_accreg2(AccountDB* self, int fd, int account_id, int char_id);
+
#endif // __ACCOUNT_H_INCLUDED__
diff --git a/src/login/account_sql.c b/src/login/account_sql.c
index 283eb3a0d..1483196ab 100644
--- a/src/login/account_sql.c
+++ b/src/login/account_sql.c
@@ -9,6 +9,7 @@
#include "../common/strlib.h"
#include "../common/timer.h"
#include "../common/console.h"
+#include "../common/socket.h"
#include "account.h"
#include <stdlib.h>
#include <string.h>
@@ -40,7 +41,9 @@ typedef struct AccountDB_SQL
// other settings
bool case_sensitive;
char account_db[32];
- char accreg_db[32];
+ char global_acc_reg_num_db[32];
+ char global_acc_reg_str_db[32];
+
} AccountDB_SQL;
@@ -106,7 +109,8 @@ AccountDB* account_db_sql(void)
// other settings
db->case_sensitive = false;
safestrncpy(db->account_db, "login", sizeof(db->account_db));
- safestrncpy(db->accreg_db, "global_reg_value", sizeof(db->accreg_db));
+ safestrncpy(db->global_acc_reg_num_db, "global_acc_reg_num_db", sizeof(db->global_acc_reg_num_db));
+ safestrncpy(db->global_acc_reg_str_db, "global_acc_reg_str_db", sizeof(db->global_acc_reg_str_db));
return &db->vtable;
}
@@ -250,8 +254,11 @@ static bool account_db_sql_get_property(AccountDB* self, const char* key, char*
if( strcmpi(key, "account_db") == 0 )
safesnprintf(buf, buflen, "%s", db->account_db);
else
- if( strcmpi(key, "accreg_db") == 0 )
- safesnprintf(buf, buflen, "%s", db->accreg_db);
+ if( strcmpi(key, "global_acc_reg_str_db") == 0 )
+ safesnprintf(buf, buflen, "%s", db->global_acc_reg_str_db);
+ else
+ if( strcmpi(key, "global_acc_reg_num_db") == 0 )
+ safesnprintf(buf, buflen, "%s", db->global_acc_reg_num_db);
else
return false;// not found
return true;
@@ -321,8 +328,11 @@ static bool account_db_sql_set_property(AccountDB* self, const char* key, const
if( strcmpi(key, "account_db") == 0 )
safestrncpy(db->account_db, value, sizeof(db->account_db));
else
- if( strcmpi(key, "accreg_db") == 0 )
- safestrncpy(db->accreg_db, value, sizeof(db->accreg_db));
+ if( strcmpi(key, "global_acc_reg_str_db") == 0 )
+ safestrncpy(db->global_acc_reg_str_db, value, sizeof(db->global_acc_reg_str_db));
+ else
+ if( strcmpi(key, "global_acc_reg_num_db") == 0 )
+ safestrncpy(db->global_acc_reg_num_db, value, sizeof(db->global_acc_reg_num_db));
else
return false;// not found
return true;
@@ -393,7 +403,9 @@ static bool account_db_sql_remove(AccountDB* self, const int account_id)
if( SQL_SUCCESS != SQL->QueryStr(sql_handle, "START TRANSACTION")
|| SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->account_db, account_id)
- || SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->accreg_db, account_id) )
+ || SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->global_acc_reg_num_db, account_id)
+ || SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->global_acc_reg_str_db, account_id)
+ )
Sql_ShowDebug(sql_handle);
else
result = true;
@@ -520,7 +532,6 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int acc
{
Sql* sql_handle = db->accounts;
char* data;
- int i = 0;
// retrieve login entry for the specified account
if( SQL_ERROR == SQL->Query(sql_handle,
@@ -556,27 +567,6 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int acc
SQL->FreeResult(sql_handle);
-
- // retrieve account regs for the specified user
- if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `str`,`value` FROM `%s` WHERE `type`='1' AND `account_id`='%d'", db->accreg_db, acc->account_id) )
- {
- Sql_ShowDebug(sql_handle);
- return false;
- }
-
- acc->account_reg2_num = (int)SQL->NumRows(sql_handle);
-
- while( SQL_SUCCESS == SQL->NextRow(sql_handle) )
- {
- SQL->GetData(sql_handle, 0, &data, NULL); safestrncpy(acc->account_reg2[i].str, data, sizeof(acc->account_reg2[i].str));
- SQL->GetData(sql_handle, 1, &data, NULL); safestrncpy(acc->account_reg2[i].value, data, sizeof(acc->account_reg2[i].value));
- ++i;
- }
- SQL->FreeResult(sql_handle);
-
- if( i != acc->account_reg2_num )
- return false;
-
return true;
}
@@ -585,7 +575,6 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
Sql* sql_handle = db->accounts;
SqlStmt* stmt = SQL->StmtMalloc(sql_handle);
bool result = false;
- int i;
// try
do
@@ -647,34 +636,6 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
}
}
- // remove old account regs
- if( SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `type`='1' AND `account_id`='%d'", db->accreg_db, acc->account_id) )
- {
- Sql_ShowDebug(sql_handle);
- break;
- }
- // insert new account regs
- if( SQL_SUCCESS != SQL->StmtPrepare(stmt, "INSERT INTO `%s` (`type`, `account_id`, `str`, `value`) VALUES ( 1 , '%d' , ? , ? );", db->accreg_db, acc->account_id) )
- {
- SqlStmt_ShowDebug(stmt);
- break;
- }
- for( i = 0; i < acc->account_reg2_num; ++i )
- {
- if( SQL_SUCCESS != SQL->StmtBindParam(stmt, 0, SQLDT_STRING, (void*)acc->account_reg2[i].str, strlen(acc->account_reg2[i].str))
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 1, SQLDT_STRING, (void*)acc->account_reg2[i].value, strlen(acc->account_reg2[i].value))
- || SQL_SUCCESS != SQL->StmtExecute(stmt)
- ) {
- SqlStmt_ShowDebug(stmt);
- break;
- }
- }
- if( i < acc->account_reg2_num )
- {
- result = false;
- break;
- }
-
// if we got this far, everything was successful
result = true;
@@ -686,6 +647,7 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
return result;
}
+
Sql* account_db_sql_up(AccountDB* self) {
AccountDB_SQL* db = (AccountDB_SQL*)self;
Sql_HerculesUpdateCheck(db->accounts);
@@ -694,3 +656,196 @@ Sql* account_db_sql_up(AccountDB* self) {
#endif
return db->accounts;
}
+void mmo_save_accreg2(AccountDB* self, int fd, int account_id, int char_id) {
+ Sql* sql_handle = ((AccountDB_SQL*)self)->accounts;
+ AccountDB_SQL* db = (AccountDB_SQL*)self;
+ int count = RFIFOW(fd, 12);
+
+ if( count ) {
+ int cursor = 14, i;
+ char key[32], sval[254];
+ unsigned int index;
+
+ 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:
+ if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%d')", db->global_acc_reg_num_db, account_id, key, index, RFIFOL(fd, cursor)) )
+ Sql_ShowDebug(sql_handle);
+ cursor += 4;
+ break;
+ case 1:
+ if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", db->global_acc_reg_num_db, account_id, key, index) )
+ Sql_ShowDebug(sql_handle);
+ break;
+ /* str */
+ case 2:
+ safestrncpy(sval, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor));
+ cursor += RFIFOB(fd, cursor) + 1;
+ if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%s')", db->global_acc_reg_str_db, account_id, key, index, sval) )
+ Sql_ShowDebug(sql_handle);
+ break;
+ case 3:
+ if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", db->global_acc_reg_str_db, account_id, key, index) )
+ Sql_ShowDebug(sql_handle);
+ break;
+
+ default:
+ ShowError("mmo_save_accreg2: DA HOO UNKNOWN TYPE %d\n",RFIFOB(fd, cursor - 1));
+ return;
+ }
+
+ }
+
+ }
+
+}
+void mmo_send_accreg2(AccountDB* self, int fd, int account_id, int char_id) {
+ Sql* sql_handle = ((AccountDB_SQL*)self)->accounts;
+ AccountDB_SQL* db = (AccountDB_SQL*)self;
+ char* data;
+ int plen = 0;
+ size_t len;
+
+ if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", db->global_acc_reg_str_db, account_id) )
+ Sql_ShowDebug(sql_handle);
+
+ 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);
+
+ SQL->FreeResult(sql_handle);
+
+ if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", db->global_acc_reg_num_db, account_id) )
+ Sql_ShowDebug(sql_handle);
+
+ 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;
+ }
+ }
+
+ /* mark as complete & go. */
+ WFIFOB(fd, 12) = 1;
+ WFIFOW(fd, 2) = plen;
+ WFIFOSET(fd, plen);
+
+ SQL->FreeResult(sql_handle);
+}
diff --git a/src/login/login.c b/src/login/login.c
index 57a2d0b74..e9d0eac9d 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -704,30 +704,8 @@ int parse_fromchar(int fd)
if( !accounts->load_num(accounts, &acc, account_id) )
ShowStatus("Char-server '%s': receiving (from the char-server) of account_reg2 (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
- else
- {
- int len;
- int p;
- ShowNotice("char-server '%s': receiving (from the char-server) of account_reg2 (account: %d, ip: %s).\n", server[id].name, account_id, ip);
- for( j = 0, p = 13; j < ACCOUNT_REG2_NUM && p < RFIFOW(fd,2); ++j )
- {
- sscanf((char*)RFIFOP(fd,p), "%31c%n", acc.account_reg2[j].str, &len);
- acc.account_reg2[j].str[len]='\0';
- p +=len+1; //+1 to skip the '\0' between strings.
- sscanf((char*)RFIFOP(fd,p), "%255c%n", acc.account_reg2[j].value, &len);
- acc.account_reg2[j].value[len]='\0';
- p +=len+1;
- remove_control_chars(acc.account_reg2[j].str);
- remove_control_chars(acc.account_reg2[j].value);
- }
- acc.account_reg2_num = j;
-
- // Save
- accounts->save(accounts, &acc);
-
- // Sending information towards the other char-servers.
- RFIFOW(fd,0) = 0x2729;// reusing read buffer
- charif_sendallwos(fd, RFIFOP(fd,0), RFIFOW(fd,2));
+ else {
+ mmo_save_accreg2(accounts,fd,account_id,RFIFOL(fd, 8));
}
RFIFOSKIP(fd,RFIFOW(fd,2));
}
@@ -797,34 +775,11 @@ int parse_fromchar(int fd)
if (RFIFOREST(fd) < 10)
return 0;
{
- struct mmo_account acc;
- size_t off;
-
int account_id = RFIFOL(fd,2);
int char_id = RFIFOL(fd,6);
RFIFOSKIP(fd,10);
- WFIFOHEAD(fd,ACCOUNT_REG2_NUM*sizeof(struct global_reg));
- WFIFOW(fd,0) = 0x2729;
- WFIFOL(fd,4) = account_id;
- WFIFOL(fd,8) = char_id;
- WFIFOB(fd,12) = 1; //Type 1 for Account2 registry
-
- off = 13;
- if( accounts->load_num(accounts, &acc, account_id) )
- {
- for( j = 0; j < acc.account_reg2_num; j++ )
- {
- if( acc.account_reg2[j].str[0] != '\0' )
- {
- off += sprintf((char*)WFIFOP(fd,off), "%s", acc.account_reg2[j].str)+1; //We add 1 to consider the '\0' in place.
- off += sprintf((char*)WFIFOP(fd,off), "%s", acc.account_reg2[j].value)+1;
- }
- }
- }
-
- WFIFOW(fd,2) = (uint16)off;
- WFIFOSET(fd,WFIFOW(fd,2));
+ mmo_send_accreg2(accounts,fd,account_id,char_id);
}
break;
diff --git a/src/login/login.h b/src/login/login.h
index 80cbee74b..d6a021125 100644
--- a/src/login/login.h
+++ b/src/login/login.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 _LOGIN_H_
#define _LOGIN_H_