summaryrefslogtreecommitdiff
path: root/src/login/account_sql.c
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2018-01-16 02:34:27 +0300
committerAndrei Karas <akaras@inbox.ru>2018-02-09 18:34:43 +0300
commit6813c20bb80ccbb390b320539b2d186aeb989f33 (patch)
tree1b9a78a9a2a11c219998cc86578296ac30de0c54 /src/login/account_sql.c
parenteb0d54e10cf59a72c78dae6101c12a8de0c9d381 (diff)
downloadhercules-6813c20bb80ccbb390b320539b2d186aeb989f33.tar.gz
hercules-6813c20bb80ccbb390b320539b2d186aeb989f33.tar.bz2
hercules-6813c20bb80ccbb390b320539b2d186aeb989f33.tar.xz
hercules-6813c20bb80ccbb390b320539b2d186aeb989f33.zip
Remove suffix "_sql" from files in login directory.
Diffstat (limited to 'src/login/account_sql.c')
-rw-r--r--src/login/account_sql.c871
1 files changed, 0 insertions, 871 deletions
diff --git a/src/login/account_sql.c b/src/login/account_sql.c
deleted file mode 100644
index 66ede6cfa..000000000
--- a/src/login/account_sql.c
+++ /dev/null
@@ -1,871 +0,0 @@
-/**
- * This file is part of Hercules.
- * http://herc.ws - http://github.com/HerculesWS/Hercules
- *
- * Copyright (C) 2012-2016 Hercules Dev Team
- * Copyright (C) Athena Dev Teams
- *
- * Hercules is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#define HERCULES_CORE
-
-#include "config/core.h" // CONSOLE_INPUT
-#include "account.h"
-
-#include "common/cbasetypes.h"
-#include "common/conf.h"
-#include "common/console.h"
-#include "common/memmgr.h"
-#include "common/mmo.h"
-#include "common/nullpo.h"
-#include "common/showmsg.h"
-#include "common/socket.h"
-#include "common/sql.h"
-#include "common/strlib.h"
-
-#include <stdlib.h>
-
-/// global defines
-#define ACCOUNT_SQL_DB_VERSION 20110114
-
-/// internal structure
-typedef struct AccountDB_SQL
-{
- AccountDB vtable; // public interface
-
- struct Sql *accounts; // SQL accounts storage
-
- // Sql settings
- char db_hostname[32];
- uint16 db_port;
- char db_username[32];
- char db_password[100];
- char db_database[32];
- char codepage[32];
- // other settings
- bool case_sensitive;
- char account_db[32];
- char global_acc_reg_num_db[32];
- char global_acc_reg_str_db[32];
-
-
-} AccountDB_SQL;
-
-/// internal structure
-typedef struct AccountDBIterator_SQL
-{
- AccountDBIterator vtable; // public interface
-
- AccountDB_SQL* db;
- int last_account_id;
-} AccountDBIterator_SQL;
-
-/// internal functions
-static bool account_db_sql_init(AccountDB* self);
-static void account_db_sql_destroy(AccountDB* self);
-static bool account_db_sql_get_property(AccountDB* self, const char* key, char* buf, size_t buflen);
-static bool account_db_sql_set_property(AccountDB* self, struct config_t *config, bool imported);
-static bool account_db_sql_create(AccountDB* self, struct mmo_account* acc);
-static bool account_db_sql_remove(AccountDB* self, const int account_id);
-static bool account_db_sql_save(AccountDB* self, const struct mmo_account* acc);
-static bool account_db_sql_load_num(AccountDB* self, struct mmo_account* acc, const int account_id);
-static bool account_db_sql_load_str(AccountDB* self, struct mmo_account* acc, const char* userid);
-static AccountDBIterator* account_db_sql_iterator(AccountDB* self);
-static void account_db_sql_iter_destroy(AccountDBIterator* self);
-static bool account_db_sql_iter_next(AccountDBIterator* self, struct mmo_account* acc);
-
-static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int account_id);
-static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, bool is_new);
-
-/// public constructor
-AccountDB* account_db_sql(void)
-{
- AccountDB_SQL* db = (AccountDB_SQL*)aCalloc(1, sizeof(AccountDB_SQL));
-
- // set up the vtable
- db->vtable.init = &account_db_sql_init;
- db->vtable.destroy = &account_db_sql_destroy;
- db->vtable.get_property = &account_db_sql_get_property;
- db->vtable.set_property = &account_db_sql_set_property;
- db->vtable.save = &account_db_sql_save;
- db->vtable.create = &account_db_sql_create;
- db->vtable.remove = &account_db_sql_remove;
- db->vtable.load_num = &account_db_sql_load_num;
- db->vtable.load_str = &account_db_sql_load_str;
- db->vtable.iterator = &account_db_sql_iterator;
-
- // initialize to default values
- db->accounts = NULL;
- // Sql settings
- safestrncpy(db->db_hostname, "127.0.0.1", sizeof(db->db_hostname));
- db->db_port = 3306;
- safestrncpy(db->db_username, "ragnarok", sizeof(db->db_username));
- safestrncpy(db->db_password, "ragnarok", sizeof(db->db_password));
- safestrncpy(db->db_database, "ragnarok", sizeof(db->db_database));
- safestrncpy(db->codepage, "", sizeof(db->codepage));
- // other settings
- db->case_sensitive = false;
- safestrncpy(db->account_db, "login", sizeof(db->account_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;
-}
-
-
-/* ------------------------------------------------------------------------- */
-
-
-/// establishes database connection
-static bool account_db_sql_init(AccountDB* self)
-{
- AccountDB_SQL* db = (AccountDB_SQL*)self;
- struct Sql *sql_handle = NULL;
-
- nullpo_ret(db);
-
- db->accounts = SQL->Malloc();
- sql_handle = db->accounts;
-
- if (SQL_ERROR == SQL->Connect(sql_handle, db->db_username, db->db_password,
- db->db_hostname, db->db_port, db->db_database)) {
- Sql_ShowDebug(sql_handle);
- SQL->Free(db->accounts);
- db->accounts = NULL;
- return false;
- }
-
- if (db->codepage[0] != '\0' && SQL_ERROR == SQL->SetEncoding(sql_handle, db->codepage))
- Sql_ShowDebug(sql_handle);
-
- Sql_HerculesUpdateCheck(db->accounts);
-#ifdef CONSOLE_INPUT
- console->input->setSQL(db->accounts);
-#endif
- return true;
-}
-
-/// disconnects from database
-static void account_db_sql_destroy(AccountDB* self)
-{
- AccountDB_SQL* db = (AccountDB_SQL*)self;
-
- nullpo_retv(db);
- SQL->Free(db->accounts);
- db->accounts = NULL;
- aFree(db);
-}
-
-/// Gets a property from this database.
-static bool account_db_sql_get_property(AccountDB* self, const char* key, char* buf, size_t buflen)
-{
- /* TODO:
- * This functionality is not being used as of now, it was removed in
- * commit 5479f9631f8579d03fbfd14d8a49c7976226a156, it is meant to get
- * engine properties when more than one engine is available. I'll
- * re-add it as soon as I can, following the new standards. If anyone
- * is interested in this functionality you can contact me in our boards
- * and I'll try to add it sooner (Pan) [Panikon]
- */
-#if 0
- AccountDB_SQL* db = (AccountDB_SQL*)self;
- const char* signature;
-
- nullpo_ret(db);
- nullpo_ret(key);
- nullpo_ret(buf);
- signature = "engine.";
- if( strncmpi(key, signature, strlen(signature)) == 0 )
- {
- key += strlen(signature);
- if( strcmpi(key, "name") == 0 )
- safesnprintf(buf, buflen, "sql");
- else
- if( strcmpi(key, "version") == 0 )
- safesnprintf(buf, buflen, "%d", ACCOUNT_SQL_DB_VERSION);
- else
- if( strcmpi(key, "comment") == 0 )
- safesnprintf(buf, buflen, "SQL Account Database");
- else
- return false;// not found
- return true;
- }
-
- signature = "account.sql.";
- if( strncmpi(key, signature, strlen(signature)) == 0 )
- {
- key += strlen(signature);
- if( strcmpi(key, "db_hostname") == 0 )
- safesnprintf(buf, buflen, "%s", db->db_hostname);
- else
- if( strcmpi(key, "db_port") == 0 )
- safesnprintf(buf, buflen, "%d", db->db_port);
- else
- if( strcmpi(key, "db_username") == 0 )
- safesnprintf(buf, buflen, "%s", db->db_username);
- else
- if( strcmpi(key, "db_password") == 0 )
- safesnprintf(buf, buflen, "%s", db->db_password);
- else
- if( strcmpi(key, "db_database") == 0 )
- safesnprintf(buf, buflen, "%s", db->db_database);
- else
- if( strcmpi(key, "codepage") == 0 )
- safesnprintf(buf, buflen, "%s", db->codepage);
- else
- if( strcmpi(key, "case_sensitive") == 0 )
- safesnprintf(buf, buflen, "%d", (db->case_sensitive ? 1 : 0));
- else
- if( strcmpi(key, "account_db") == 0 )
- safesnprintf(buf, buflen, "%s", db->account_db);
- else
- 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;
- }
-
- return false;// not found
-#endif // 0
- return false;
-}
-
-/**
- * Reads the 'inter_configuration' config file and initializes required variables.
- *
- * @param db Self.
- * @param filename Path to configuration file
- * @param imported Whether the current config is imported from another file.
- *
- * @retval false in case of error.
- */
-bool account_db_read_inter(AccountDB_SQL *db, const char *filename, bool imported)
-{
- struct config_t config;
- struct config_setting_t *setting = NULL;
-
- nullpo_retr(false, db);
- nullpo_retr(false, filename);
-
- if (!libconfig->load_file(&config, filename))
- return false; // Error message is already shown by libconfig->load_file
-
- if ((setting = libconfig->lookup(&config, "inter_configuration/database_names")) == NULL) {
- libconfig->destroy(&config);
- if (imported)
- return true;
- ShowError("account_db_sql_set_property: inter_configuration/database_names was not found!\n");
- return false;
- }
- libconfig->setting_lookup_mutable_string(setting, "account_db", db->account_db, sizeof(db->account_db));
-
- if ((setting = libconfig->lookup(&config, "inter_configuration/database_names/registry")) == NULL) {
- libconfig->destroy(&config);
- if (imported)
- return true;
- ShowError("account_db_sql_set_property: inter_configuration/database_names/registry was not found!\n");
- return false;
- }
- libconfig->setting_lookup_mutable_string(setting, "global_acc_reg_str_db", db->global_acc_reg_str_db, sizeof(db->global_acc_reg_str_db));
- libconfig->setting_lookup_mutable_string(setting, "global_acc_reg_num_db", db->global_acc_reg_num_db, sizeof(db->global_acc_reg_num_db));
-
- // TODO: Proper import mechanism for this file
-
- libconfig->destroy(&config);
- return true;
-}
-
-/**
- * Loads the sql configuration.
- *
- * @param self Self.
- * @param config The current config being parsed.
- * @param imported Whether the current config is imported from another file.
- *
- * @retval false in case of error.
- */
-static bool account_db_sql_set_property(AccountDB* self, struct config_t *config, bool imported)
-{
- AccountDB_SQL* db = (AccountDB_SQL*)self;
- struct config_setting_t *setting = NULL;
-
- nullpo_ret(db);
- nullpo_ret(config);
-
- if ((setting = libconfig->lookup(config, "login_configuration/account/sql_connection")) == NULL) {
- if (imported)
- return true;
- ShowError("account_db_sql_set_property: login_configuration/account/sql_connection was not found!\n");
- ShowWarning("account_db_sql_set_property: Defaulting sql_connection...\n");
- return false;
- }
-
- libconfig->setting_lookup_mutable_string(setting, "db_hostname", db->db_hostname, sizeof(db->db_hostname));
- libconfig->setting_lookup_mutable_string(setting, "db_username", db->db_username, sizeof(db->db_username));
- libconfig->setting_lookup_mutable_string(setting, "db_password", db->db_password, sizeof(db->db_password));
- libconfig->setting_lookup_mutable_string(setting, "db_database", db->db_database, sizeof(db->db_database));
- libconfig->setting_lookup_mutable_string(setting, "codepage", db->codepage, sizeof(db->codepage)); // FIXME: Why do we need both codepage and default_codepage?
- libconfig->setting_lookup_uint16(setting, "db_port", &db->db_port);
- libconfig->setting_lookup_bool_real(setting, "case_sensitive", &db->case_sensitive);
-
- account_db_read_inter(db, "conf/common/inter-server.conf", imported);
-
- return true;
-}
-
-/// create a new account entry
-/// If acc->account_id is -1, the account id will be auto-generated,
-/// and its value will be written to acc->account_id if everything succeeds.
-static bool account_db_sql_create(AccountDB* self, struct mmo_account* acc)
-{
- AccountDB_SQL* db = (AccountDB_SQL*)self;
- struct Sql *sql_handle;
-
- // decide on the account id to assign
- int account_id;
- nullpo_ret(db);
- nullpo_ret(acc);
- sql_handle = db->accounts;
- if( acc->account_id != -1 )
- {// caller specifies it manually
- account_id = acc->account_id;
- }
- else
- {// ask the database
- char* data;
- size_t len;
-
- if( SQL_SUCCESS != SQL->Query(sql_handle, "SELECT MAX(`account_id`)+1 FROM `%s`", db->account_db) )
- {
- Sql_ShowDebug(sql_handle);
- return false;
- }
- if( SQL_SUCCESS != SQL->NextRow(sql_handle) )
- {
- Sql_ShowDebug(sql_handle);
- SQL->FreeResult(sql_handle);
- return false;
- }
-
- SQL->GetData(sql_handle, 0, &data, &len);
- account_id = ( data != NULL ) ? atoi(data) : 0;
- SQL->FreeResult(sql_handle);
-
- if( account_id < START_ACCOUNT_NUM )
- account_id = START_ACCOUNT_NUM;
-
- }
-
- // zero value is prohibited
- if( account_id == 0 )
- return false;
-
- // absolute maximum
- if( account_id > END_ACCOUNT_NUM )
- return false;
-
- // insert the data into the database
- acc->account_id = account_id;
- return mmo_auth_tosql(db, acc, true);
-}
-
-/// delete an existing account entry + its regs
-static bool account_db_sql_remove(AccountDB* self, const int account_id)
-{
- AccountDB_SQL* db = (AccountDB_SQL*)self;
- struct Sql *sql_handle;
- bool result = false;
-
- nullpo_ret(db);
- sql_handle = db->accounts;
- 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->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;
-
- result &= ( SQL_SUCCESS == SQL->QueryStr(sql_handle, (result == true) ? "COMMIT" : "ROLLBACK") );
-
- return result;
-}
-
-/// update an existing account with the provided new data (both account and regs)
-static bool account_db_sql_save(AccountDB* self, const struct mmo_account* acc)
-{
- AccountDB_SQL* db = (AccountDB_SQL*)self;
- return mmo_auth_tosql(db, acc, false);
-}
-
-/// retrieve data from db and store it in the provided data structure
-static bool account_db_sql_load_num(AccountDB* self, struct mmo_account* acc, const int account_id)
-{
- AccountDB_SQL* db = (AccountDB_SQL*)self;
- return mmo_auth_fromsql(db, acc, account_id);
-}
-
-/// retrieve data from db and store it in the provided data structure
-static bool account_db_sql_load_str(AccountDB* self, struct mmo_account* acc, const char* userid)
-{
- AccountDB_SQL* db = (AccountDB_SQL*)self;
- struct Sql *sql_handle;
- char esc_userid[2*NAME_LENGTH+1];
- int account_id;
- char* data;
-
- nullpo_ret(db);
- sql_handle = db->accounts;
- SQL->EscapeString(sql_handle, esc_userid, userid);
-
- // get the list of account IDs for this user ID
- if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `account_id` FROM `%s` WHERE `userid`= %s '%s'",
- db->account_db, (db->case_sensitive ? "BINARY" : ""), esc_userid) )
- {
- Sql_ShowDebug(sql_handle);
- return false;
- }
-
- if( SQL->NumRows(sql_handle) > 1 )
- {// serious problem - duplicate account
- ShowError("account_db_sql_load_str: multiple accounts found when retrieving data for account '%s'!\n", userid);
- SQL->FreeResult(sql_handle);
- return false;
- }
-
- if( SQL_SUCCESS != SQL->NextRow(sql_handle) )
- {// no such entry
- SQL->FreeResult(sql_handle);
- return false;
- }
-
- SQL->GetData(sql_handle, 0, &data, NULL);
- account_id = atoi(data);
-
- return account_db_sql_load_num(self, acc, account_id);
-}
-
-
-/// Returns a new forward iterator.
-static AccountDBIterator* account_db_sql_iterator(AccountDB* self)
-{
- AccountDB_SQL* db = (AccountDB_SQL*)self;
- AccountDBIterator_SQL* iter;
-
- nullpo_retr(NULL, db);
- iter = (AccountDBIterator_SQL*)aCalloc(1, sizeof(AccountDBIterator_SQL));
- // set up the vtable
- iter->vtable.destroy = &account_db_sql_iter_destroy;
- iter->vtable.next = &account_db_sql_iter_next;
-
- // fill data
- iter->db = db;
- iter->last_account_id = -1;
-
- return &iter->vtable;
-}
-
-
-/// Destroys this iterator, releasing all allocated memory (including itself).
-static void account_db_sql_iter_destroy(AccountDBIterator* self)
-{
- AccountDBIterator_SQL* iter = (AccountDBIterator_SQL*)self;
- aFree(iter);
-}
-
-
-/// Fetches the next account in the database.
-static bool account_db_sql_iter_next(AccountDBIterator* self, struct mmo_account* acc)
-{
- AccountDBIterator_SQL* iter = (AccountDBIterator_SQL*)self;
- AccountDB_SQL* db;
- struct Sql *sql_handle;
- char* data;
-
- nullpo_ret(iter);
- db = (AccountDB_SQL*)iter->db;
- nullpo_ret(db);
- sql_handle = db->accounts;
- // get next account ID
- if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `account_id` FROM `%s` WHERE `account_id` > '%d' ORDER BY `account_id` ASC LIMIT 1",
- db->account_db, iter->last_account_id) )
- {
- Sql_ShowDebug(sql_handle);
- return false;
- }
-
- if( SQL_SUCCESS == SQL->NextRow(sql_handle) &&
- SQL_SUCCESS == SQL->GetData(sql_handle, 0, &data, NULL) &&
- data != NULL )
- {// get account data
- int account_id;
- account_id = atoi(data);
- if( mmo_auth_fromsql(db, acc, account_id) )
- {
- iter->last_account_id = account_id;
- SQL->FreeResult(sql_handle);
- return true;
- }
- }
- SQL->FreeResult(sql_handle);
- return false;
-}
-
-
-static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int account_id)
-{
- struct Sql *sql_handle;
- char* data;
-
- nullpo_ret(db);
- nullpo_ret(acc);
- sql_handle = db->accounts;
- // retrieve login entry for the specified account
- if( SQL_ERROR == SQL->Query(sql_handle,
- "SELECT `account_id`,`userid`,`user_pass`,`sex`,`email`,`group_id`,`state`,`unban_time`,`expiration_time`,`logincount`,`lastlogin`,`last_ip`,`birthdate`,`character_slots`,`pincode`,`pincode_change` FROM `%s` WHERE `account_id` = %d",
- db->account_db, account_id )
- ) {
- Sql_ShowDebug(sql_handle);
- return false;
- }
-
- if( SQL_SUCCESS != SQL->NextRow(sql_handle) )
- {// no such entry
- SQL->FreeResult(sql_handle);
- return false;
- }
-
- SQL->GetData(sql_handle, 0, &data, NULL); acc->account_id = atoi(data);
- SQL->GetData(sql_handle, 1, &data, NULL); safestrncpy(acc->userid, data, sizeof(acc->userid));
- SQL->GetData(sql_handle, 2, &data, NULL); safestrncpy(acc->pass, data, sizeof(acc->pass));
- SQL->GetData(sql_handle, 3, &data, NULL); acc->sex = data[0];
- SQL->GetData(sql_handle, 4, &data, NULL); safestrncpy(acc->email, data, sizeof(acc->email));
- SQL->GetData(sql_handle, 5, &data, NULL); acc->group_id = atoi(data);
- SQL->GetData(sql_handle, 6, &data, NULL); acc->state = (unsigned int)strtoul(data, NULL, 10);
- SQL->GetData(sql_handle, 7, &data, NULL); acc->unban_time = atol(data);
- SQL->GetData(sql_handle, 8, &data, NULL); acc->expiration_time = atol(data);
- SQL->GetData(sql_handle, 9, &data, NULL); acc->logincount = (unsigned int)strtoul(data, NULL, 10);
- SQL->GetData(sql_handle, 10, &data, NULL); safestrncpy(acc->lastlogin, data != NULL ? data : "(never)", sizeof(acc->lastlogin));
- SQL->GetData(sql_handle, 11, &data, NULL); safestrncpy(acc->last_ip, data, sizeof(acc->last_ip));
- SQL->GetData(sql_handle, 12, &data, NULL); safestrncpy(acc->birthdate, data != NULL ? data : "0000-00-00", sizeof(acc->birthdate));
- SQL->GetData(sql_handle, 13, &data, NULL); acc->char_slots = (uint8)atoi(data);
- SQL->GetData(sql_handle, 14, &data, NULL); safestrncpy(acc->pincode, data, sizeof(acc->pincode));
- SQL->GetData(sql_handle, 15, &data, NULL); acc->pincode_change = (unsigned int)atol(data);
-
- SQL->FreeResult(sql_handle);
-
- return true;
-}
-
-static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, bool is_new)
-{
- struct Sql *sql_handle;
- struct SqlStmt *stmt;
- bool result = false;
-
- nullpo_ret(db);
- nullpo_ret(acc);
- sql_handle = db->accounts;
- stmt = SQL->StmtMalloc(sql_handle);
-
- // try
- do
- {
-
- if( SQL_SUCCESS != SQL->QueryStr(sql_handle, "START TRANSACTION") )
- {
- Sql_ShowDebug(sql_handle);
- break;
- }
-
- if( is_new )
- {// insert into account table
- if( SQL_SUCCESS != SQL->StmtPrepare(stmt,
- "INSERT INTO `%s` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `group_id`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`, `birthdate`, `character_slots`, `pincode`, `pincode_change`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
- db->account_db)
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 0, SQLDT_INT, &acc->account_id, sizeof acc->account_id)
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 1, SQLDT_STRING, acc->userid, strlen(acc->userid))
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 2, SQLDT_STRING, acc->pass, strlen(acc->pass))
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 3, SQLDT_ENUM, &acc->sex, sizeof acc->sex)
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 4, SQLDT_STRING, &acc->email, strlen(acc->email))
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 5, SQLDT_INT, &acc->group_id, sizeof acc->group_id)
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 6, SQLDT_UINT, &acc->state, sizeof acc->state)
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 7, SQLDT_TIME, &acc->unban_time, sizeof acc->unban_time)
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 8, SQLDT_TIME, &acc->expiration_time, sizeof acc->expiration_time)
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 9, SQLDT_UINT, &acc->logincount, sizeof acc->logincount)
- || SQL_SUCCESS != (acc->lastlogin[0] < '1' || acc->lastlogin[0] > '9' ?
- SQL->StmtBindParam(stmt, 10, SQLDT_NULL, NULL, 0) :
- SQL->StmtBindParam(stmt, 10, SQLDT_STRING, &acc->lastlogin, strlen(acc->lastlogin))
- )
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 11, SQLDT_STRING, &acc->last_ip, strlen(acc->last_ip))
- || SQL_SUCCESS != (acc->birthdate[0] == '0' ?
- SQL->StmtBindParam(stmt, 12, SQLDT_NULL, NULL, 0) :
- SQL->StmtBindParam(stmt, 12, SQLDT_STRING, &acc->birthdate, strlen(acc->birthdate))
- )
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 13, SQLDT_UINT8, &acc->char_slots, sizeof acc->char_slots)
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 14, SQLDT_STRING, &acc->pincode, strlen(acc->pincode))
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 15, SQLDT_UINT, &acc->pincode_change, sizeof acc->pincode_change)
- || SQL_SUCCESS != SQL->StmtExecute(stmt)
- ) {
- SqlStmt_ShowDebug(stmt);
- break;
- }
- } else {// update account table
- if( SQL_SUCCESS != SQL->StmtPrepare(stmt, "UPDATE `%s` SET `userid`=?,`user_pass`=?,`sex`=?,`email`=?,`group_id`=?,`state`=?,`unban_time`=?,`expiration_time`=?,`logincount`=?,`lastlogin`=?,`last_ip`=?,`birthdate`=?,`character_slots`=?,`pincode`=?,`pincode_change`=? WHERE `account_id` = '%d'", db->account_db, acc->account_id)
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 0, SQLDT_STRING, acc->userid, strlen(acc->userid))
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 1, SQLDT_STRING, acc->pass, strlen(acc->pass))
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 2, SQLDT_ENUM, &acc->sex, sizeof acc->sex)
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 3, SQLDT_STRING, acc->email, strlen(acc->email))
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 4, SQLDT_INT, &acc->group_id, sizeof acc->group_id)
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 5, SQLDT_UINT, &acc->state, sizeof acc->state)
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 6, SQLDT_TIME, &acc->unban_time, sizeof acc->unban_time)
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 7, SQLDT_TIME, &acc->expiration_time, sizeof acc->expiration_time)
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 8, SQLDT_UINT, &acc->logincount, sizeof acc->logincount)
- || SQL_SUCCESS != (acc->lastlogin[0] < '1' || acc->lastlogin[0] > '9' ?
- SQL->StmtBindParam(stmt, 9, SQLDT_NULL, NULL, 0) :
- SQL->StmtBindParam(stmt, 9, SQLDT_STRING, &acc->lastlogin, strlen(acc->lastlogin))
- )
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 10, SQLDT_STRING, &acc->last_ip, strlen(acc->last_ip))
- || SQL_SUCCESS != (acc->birthdate[0] == '0' ?
- SQL->StmtBindParam(stmt, 11, SQLDT_NULL, NULL, 0) :
- SQL->StmtBindParam(stmt, 11, SQLDT_STRING, &acc->birthdate, strlen(acc->birthdate))
- )
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 12, SQLDT_UINT8, &acc->char_slots, sizeof acc->char_slots)
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 13, SQLDT_STRING, &acc->pincode, strlen(acc->pincode))
- || SQL_SUCCESS != SQL->StmtBindParam(stmt, 14, SQLDT_UINT, &acc->pincode_change, sizeof acc->pincode_change)
- || SQL_SUCCESS != SQL->StmtExecute(stmt)
- ) {
- SqlStmt_ShowDebug(stmt);
- break;
- }
- }
-
- // if we got this far, everything was successful
- result = true;
-
- } while(0);
- // finally
-
- result &= ( SQL_SUCCESS == SQL->QueryStr(sql_handle, (result == true) ? "COMMIT" : "ROLLBACK") );
- SQL->StmtFree(stmt);
-
- return result;
-}
-
-struct Sql *account_db_sql_up(AccountDB* self)
-{
- AccountDB_SQL* db = (AccountDB_SQL*)self;
- return db ? db->accounts : NULL;
-}
-void mmo_save_accreg2(AccountDB* self, int fd, int account_id, int char_id)
-{
- struct Sql *sql_handle;
- AccountDB_SQL* db = (AccountDB_SQL*)self;
- int count = RFIFOW(fd, 12);
-
- nullpo_retv(db);
- sql_handle = db->accounts;
- if (count) {
- int cursor = 14, i;
- char key[SCRIPT_VARNAME_LENGTH+1], sval[254];
-
- for (i = 0; i < count; i++) {
- unsigned int index;
- int len = RFIFOB(fd, cursor);
- safestrncpy(key, RFIFOP(fd, cursor + 1), min((int)sizeof(key), len));
- cursor += len + 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','%u')", 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:
- len = RFIFOB(fd, cursor);
- safestrncpy(sval, RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len));
- cursor += len + 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)
-{
- struct Sql *sql_handle;
- AccountDB_SQL* db = (AccountDB_SQL*)self;
- char* data;
- int plen = 0;
- size_t len;
-
- nullpo_retv(db);
- sql_handle = db->accounts;
- 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(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(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(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);
-}