2018-03-29 17:01:57 -04:00
2019-07-07 20:56:15 +00:00
# include <StdAfx.h>
2018-03-29 17:01:57 -04:00
# include "Database2.h"
# include "DatabaseIO.h"
# include "SHA512.h"
2019-11-23 20:34:53 +00:00
# include "Config.h"
2018-03-29 17:01:57 -04:00
2019-07-07 20:56:15 +00:00
uint64_t g_RandomAdminPassword = 0 ; // this is used for the admin login
2018-03-29 17:01:57 -04:00
CDatabaseIO : : CDatabaseIO ( )
{
blob_query_buffer = new BYTE [ BLOB_QUERY_BUFFER_LENGTH ] ;
}
CDatabaseIO : : ~ CDatabaseIO ( )
{
SafeDeleteArray ( blob_query_buffer ) ;
}
2020-06-06 23:22:18 +00:00
bool CDatabaseIO : : IsUserNameValid ( const std : : string & username )
{
for ( const char & c : username )
{
if ( c > = ' a ' & & c < = ' z ' )
continue ;
if ( c > = ' A ' & & c < = ' Z ' )
continue ;
if ( c > = ' 0 ' & & c < = ' 9 ' )
continue ;
if ( c = = ' _ ' )
continue ;
if ( c = = ' - ' )
continue ;
return false ;
}
return true ;
}
2018-03-29 17:01:57 -04:00
bool CDatabaseIO : : VerifyAccount ( const char * username , const char * password , AccountInformation_t * pAccountInfo , int * pError )
{
2020-06-06 23:22:18 +00:00
return VerifyAccount ( g_pDB2 - > GetInternalConnection ( ) , username , password , pAccountInfo , pError ) ;
}
2018-03-29 17:01:57 -04:00
2020-06-06 23:22:18 +00:00
bool CDatabaseIO : : VerifyAccount ( void * dbc , const char * username , const char * password , AccountInformation_t * pAccountInfo , int * pError )
{
* pError = DBIO_ERROR_NONE ;
2018-03-29 17:01:57 -04:00
2020-06-06 23:22:18 +00:00
std : : string salt ;
2018-03-29 17:01:57 -04:00
{
2020-06-06 23:22:18 +00:00
mysql_statement < 1 > salt_query ( ( MYSQL * ) dbc , " SELECT password_salt FROM accounts WHERE username=? LIMIT 1 " ) ;
if ( ! salt_query )
2018-03-29 17:01:57 -04:00
{
2020-06-06 23:22:18 +00:00
* pError = VERIFYACCOUNT_ERROR_QUERY_FAILED ;
return false ;
}
2018-03-29 17:01:57 -04:00
2020-06-06 23:22:18 +00:00
salt_query . bind ( 0 , username ) ;
2018-03-29 17:01:57 -04:00
2020-06-06 23:22:18 +00:00
if ( ! salt_query . execute ( ) )
{
* pError = VERIFYACCOUNT_ERROR_QUERY_FAILED ;
return false ;
2018-03-29 17:01:57 -04:00
}
2020-06-06 23:22:18 +00:00
salt . resize ( 64 ) ;
unsigned long length = 0 ;
mysql_statement_results < 1 > salt_row ;
salt_row . bind ( 0 , salt , salt . capacity ( ) , & length ) ;
if ( ! salt_query . bindResults ( salt_row ) )
2018-03-29 17:01:57 -04:00
{
* pError = VERIFYACCOUNT_ERROR_QUERY_FAILED ;
return false ;
}
2020-06-06 23:22:18 +00:00
if ( ! salt_row . next ( ) )
{
* pError = VERIFYACCOUNT_ERROR_DOESNT_EXIST ;
return false ;
}
salt . resize ( length ) ;
2018-03-29 17:01:57 -04:00
}
bool bIsAdmin = false ;
2019-07-07 20:56:15 +00:00
if ( ! stricmp ( username , " admin " ) )
2018-03-29 17:01:57 -04:00
{
if ( ! strcmp ( password , csprintf ( " %I64u " , g_RandomAdminPassword ) ) )
{
bIsAdmin = true ;
//*pError = VERIFYACCOUNT_ERROR_BAD_LOGIN;
//return false;
}
//bIsAdmin = true;
}
2020-06-06 23:22:18 +00:00
std : : string pass = password + salt ;
std : : string hashed = SHA512 ( pass . c_str ( ) , pass . length ( ) ) . substr ( 0 , 64 ) ;
mysql_statement < 3 > login_query ( ( MYSQL * ) dbc , " SELECT id, date_created, access, banned FROM accounts WHERE username=? AND password=? LIMIT 1 " ) ;
if ( ! login_query )
return true ;
login_query . bind ( 0 , username ) ;
login_query . bind ( 1 , hashed ) ;
if ( login_query . execute ( ) )
2018-03-29 17:01:57 -04:00
{
2020-06-06 23:22:18 +00:00
uint16_t banned = 0 ;
2018-03-29 17:01:57 -04:00
2020-06-06 23:22:18 +00:00
mysql_statement_results < 4 > login_row ;
login_row . bind ( 0 , pAccountInfo - > id ) ;
login_row . bind ( 1 , pAccountInfo - > dateCreated ) ;
login_row . bind ( 2 , pAccountInfo - > access ) ;
login_row . bind ( 3 , banned ) ;
if ( login_query . bindResults ( login_row ) )
{
if ( login_row . next ( ) )
2018-03-29 17:01:57 -04:00
{
2020-06-06 23:22:18 +00:00
pAccountInfo - > username = username ;
pAccountInfo - > banned = banned ! = 0 ;
return true ;
2018-03-29 17:01:57 -04:00
}
else
{
* pError = VERIFYACCOUNT_ERROR_BAD_LOGIN ;
return false ;
}
}
}
2020-06-06 23:22:18 +00:00
* pError = VERIFYACCOUNT_ERROR_QUERY_FAILED ;
return false ;
2018-03-29 17:01:57 -04:00
}
bool CDatabaseIO : : CreateAccount ( const char * username , const char * password , int * pError , const char * ipaddress )
2020-06-06 23:22:18 +00:00
{
return CreateAccount ( g_pDB2 - > GetInternalConnection ( ) , username , password , pError , ipaddress ) ;
}
bool CDatabaseIO : : CreateAccount ( void * dbc , const char * username , const char * password , int * pError , const char * ipaddress )
2018-03-29 17:01:57 -04:00
{
unsigned int usernameLength = ( unsigned int ) strlen ( username ) ;
if ( usernameLength < MIN_USERNAME_LENGTH | | usernameLength > MAX_USERNAME_LENGTH )
{
* pError = CREATEACCOUNT_ERROR_BAD_USERNAME ;
return false ;
}
2020-06-06 23:22:18 +00:00
if ( ! IsUserNameValid ( username ) )
2018-03-29 17:01:57 -04:00
{
* pError = CREATEACCOUNT_ERROR_BAD_USERNAME ;
return false ;
}
unsigned int passwordLength = ( unsigned int ) strlen ( password ) ;
if ( passwordLength < MIN_PASSWORD_LENGTH | | passwordLength > MAX_PASSWORD_LENGTH )
{
* pError = CREATEACCOUNT_ERROR_BAD_PASSWORD ;
return false ;
}
* pError = DBIO_ERROR_NONE ;
// Create random salt
2019-07-07 20:56:15 +00:00
uint32_t randomValue = Random : : GenUInt ( 0 , 100000 ) ;
2018-03-29 17:01:57 -04:00
std : : string passwordSalt = SHA512 ( & randomValue , sizeof ( randomValue ) ) . substr ( 0 , 16 ) ;
// Apply salt
std : : string saltedPassword = password + passwordSalt ;
std : : string hashedSaltedPassword = SHA512 ( saltedPassword . c_str ( ) , saltedPassword . length ( ) ) . substr ( 0 , 64 ) ;
uint64_t accountID = 0 ;
2020-06-06 23:22:18 +00:00
mysql_statement < 4 > query ( ( MYSQL * ) dbc , " INSERT INTO accounts (username, password, password_salt, date_created, access, created_ip_address) VALUES (?, ?, ?, UNIX_TIMESTAMP(), 1, ?) " ) ;
if ( ! query )
return false ;
2018-03-29 17:01:57 -04:00
2020-06-06 23:22:18 +00:00
query . bind ( 0 , username ) ;
query . bind ( 1 , hashedSaltedPassword ) ;
query . bind ( 2 , passwordSalt ) ;
query . bind ( 3 , ipaddress ) ;
if ( query . execute ( ) )
{
accountID = query . lastInsertId ( ) ;
2018-03-29 17:01:57 -04:00
}
2020-06-06 23:22:18 +00:00
if ( ! accountID )
2018-03-29 17:01:57 -04:00
{
* pError = CREATEACCOUNT_ERROR_QUERY_FAILED ;
return false ;
}
return true ;
}
2019-01-25 02:26:45 -06:00
bool CDatabaseIO : : UpdateBan ( unsigned int account_id , bool ban )
{
2020-06-06 23:22:18 +00:00
//return g_pDB2->Query("UPDATE accounts SET banned = %u WHERE id = %u", ban, account_id);
int banned = ban ? 1 : 0 ;
g_pDB2 - > QueueAsyncQuery ( " UPDATE accounts SET banned = ? WHERE id = ? " , banned , account_id ) ;
return true ;
2019-01-25 02:26:45 -06:00
}
2019-05-28 15:59:42 +00:00
std : : list < HouseInfo_t > CDatabaseIO : : GetHousingData ( )
{
std : : list < HouseInfo_t > results ;
if ( g_pDB2 - > Query ( " SELECT house_id, data, LENGTH(data) FROM houses; " ) )
{
CSQLResult * pQueryResult = g_pDB2 - > GetResult ( ) ;
if ( pQueryResult )
{
while ( SQLResultRow_t Row = pQueryResult - > FetchRow ( ) )
{
HouseInfo_t res ;
res . house_id = strtoul ( Row [ 0 ] , NULL , 10 ) ;
2019-07-07 20:56:15 +00:00
//res.houseBlob = Row[1];
2019-05-28 15:59:42 +00:00
res . houseBlobLen = strtoul ( Row [ 2 ] , NULL , 10 ) ;
2019-07-07 20:56:15 +00:00
res . houseBlob = new uint8_t [ res . houseBlobLen ] ;
memcpy ( res . houseBlob , Row [ 1 ] , res . houseBlobLen ) ;
2019-05-28 15:59:42 +00:00
results . push_back ( res ) ;
}
delete pQueryResult ;
}
}
return results ;
}
std : : list < unsigned int > CDatabaseIO : : GetAllCharacterIDs ( )
{
std : : list < unsigned int > results ;
if ( g_pDB2 - > Query ( " SELECT weenie_id FROM characters; " ) )
{
CSQLResult * pQueryResult = g_pDB2 - > GetResult ( ) ;
if ( pQueryResult )
{
while ( SQLResultRow_t Row = pQueryResult - > FetchRow ( ) )
{
results . push_back ( strtoul ( Row [ 0 ] , NULL , 10 ) ) ;
}
delete pQueryResult ;
}
}
return results ;
}
2019-11-23 20:34:53 +00:00
std : : string CDatabaseIO : : GetEmailOfAccount ( unsigned int character_id )
{
std : : string result ;
if ( g_pDB2 - > Query ( " SELECT ac.email FROM accounts ac JOIN characters cc ON cc.account_id = ac.id WHERE cc.weenie_id = %u " , character_id ) )
{
CSQLResult * pQueryResult = g_pDB2 - > GetResult ( ) ;
if ( pQueryResult )
{
while ( SQLResultRow_t Row = pQueryResult - > FetchRow ( ) )
{
result = Row [ 0 ] ;
}
delete pQueryResult ;
}
}
return result ;
}
bool CDatabaseIO : : SetEmailOfAccount ( std : : string email , unsigned int character_id )
{
if ( ! g_pDB2 - > Query ( " UPDATE accounts AS ac JOIN characters as cc on cc.account_id = ac.id SET ac.email = '%s' WHERE cc.weenie_id = %u; " , email . c_str ( ) , character_id ) )
return false ;
if ( ! g_pDB2 - > Query ( " UPDATE accounts AS ac JOIN characters as cc on cc.account_id = ac.id SET ac.emailsetused = 1 WHERE cc.weenie_id = %u; " , character_id ) )
SERVER_ERROR < < " Failed to set one time email flag to true for character: " < < character_id < < " using email " < < email ;
return true ;
}
bool CDatabaseIO : : IsEmailAlreadySet ( unsigned int character_id )
{
bool result = false ;
if ( g_pDB2 - > Query ( " SELECT count(*) FROM accounts ac JOIN characters cc ON cc.account_id = ac.id WHERE ac.emailsetused = 1 AND cc.weenie_id = %u; " , character_id ) )
{
CSQLResult * pQueryResult = g_pDB2 - > GetResult ( ) ;
if ( pQueryResult )
{
while ( SQLResultRow_t Row = pQueryResult - > FetchRow ( ) )
{
if ( strtoul ( Row [ 0 ] , NULL , 10 ) > 0 )
result = true ;
}
delete pQueryResult ;
}
}
return result ;
}
2019-05-28 15:59:42 +00:00
std : : list < unsigned int > CDatabaseIO : : GetBannedAccountIDs ( )
{
std : : list < unsigned int > results ;
if ( g_pDB2 - > Query ( " SELECT id FROM accounts WHERE banned = 1; " ) )
{
CSQLResult * pQueryResult = g_pDB2 - > GetResult ( ) ;
if ( pQueryResult )
{
while ( SQLResultRow_t Row = pQueryResult - > FetchRow ( ) )
{
results . push_back ( strtoul ( Row [ 0 ] , NULL , 10 ) ) ;
}
delete pQueryResult ;
}
}
return results ;
}
std : : list < unsigned int > CDatabaseIO : : GetBannedCharacterIDs ( )
{
std : : list < unsigned int > results ;
if ( g_pDB2 - > Query ( " SELECT weenie_id FROM characters; " ) )
{
CSQLResult * pQueryResult = g_pDB2 - > GetResult ( ) ;
if ( pQueryResult )
{
while ( SQLResultRow_t Row = pQueryResult - > FetchRow ( ) )
{
results . push_back ( strtoul ( Row [ 0 ] , NULL , 10 ) ) ;
}
delete pQueryResult ;
}
}
return results ;
}
2019-01-25 02:26:45 -06:00
2018-03-29 17:01:57 -04:00
std : : list < unsigned int > CDatabaseIO : : GetWeeniesAt ( unsigned int block_id )
{
std : : list < unsigned int > results ;
2019-07-12 04:09:01 +00:00
if ( g_pDB2 - > Query ( " SELECT weenie_id FROM blocks WHERE block_id = %u; " , block_id ) )
2018-03-29 17:01:57 -04:00
{
CSQLResult * pQueryResult = g_pDB2 - > GetResult ( ) ;
if ( pQueryResult )
{
while ( SQLResultRow_t Row = pQueryResult - > FetchRow ( ) )
{
results . push_back ( strtoul ( Row [ 0 ] , NULL , 10 ) ) ;
}
delete pQueryResult ;
}
}
return results ;
}
2019-02-10 01:02:56 +00:00
std : : string CDatabaseIO : : LoadCharacterTitles ( unsigned int character_id )
{
std : : string result ;
2019-07-12 04:09:01 +00:00
if ( g_pDB2 - > Query ( " SELECT titles FROM character_titles WHERE character_id = %u; " , character_id ) )
2019-02-10 01:02:56 +00:00
{
CSQLResult * pQueryResult = g_pDB2 - > GetResult ( ) ;
if ( pQueryResult )
{
while ( SQLResultRow_t Row = pQueryResult - > FetchRow ( ) )
{
result = Row [ 0 ] ;
} ;
delete pQueryResult ;
}
}
return result ;
}
2019-07-12 04:09:01 +00:00
std : : string CDatabaseIO : : LoadCharacterCorpses ( unsigned int character_id )
{
std : : string result ;
if ( g_pDB2 - > Query ( " SELECT corpses FROM character_corpses WHERE character_id = %u; " , character_id ) )
{
CSQLResult * pQueryResult = g_pDB2 - > GetResult ( ) ;
if ( pQueryResult )
{
while ( SQLResultRow_t Row = pQueryResult - > FetchRow ( ) )
{
result = Row [ 0 ] ;
} ;
delete pQueryResult ;
}
}
return result ;
}
2019-02-10 01:02:56 +00:00
bool CDatabaseIO : : SaveCharacterTitles ( unsigned int character_id , std : : string titles )
{
if ( ! g_pDB2 - > Query ( " REPLACE INTO character_titles (character_id, titles) VALUES (%u, '%s'); " , character_id , titles . c_str ( ) ) )
return false ;
return true ;
}
2019-07-12 04:09:01 +00:00
bool CDatabaseIO : : SaveCharacterCorpses ( unsigned int character_id , std : : string corpselist )
{
if ( ! g_pDB2 - > Query ( " REPLACE INTO character_corpses (character_id, corpses) VALUES (%u, '%s'); " , character_id , corpselist . c_str ( ) ) )
return false ;
return true ;
}
2019-11-23 20:34:53 +00:00
2019-02-17 16:21:58 -08:00
bool CDatabaseIO : : DeleteCharacterTitles ( unsigned int character_id )
{
if ( ! g_pDB2 - > Query ( " DELETE FROM character_titles WHERE character_id = %u " , character_id ) )
return false ;
return true ;
}
2019-02-10 01:02:56 +00:00
2019-11-23 20:34:53 +00:00
bool CDatabaseIO : : DeleteCharacterInventory ( unsigned int character_id )
{
if ( ! g_pDB2 - > Query ( " DELETE FROM weenies WHERE top_level_object_id = %u " , character_id ) )
{
SERVER_ERROR < < " CHAR DELETE: Failed to delete inventory for weenie - " < < character_id ;
return false ;
}
return true ;
}
2018-03-29 17:01:57 -04:00
bool CDatabaseIO : : AddOrUpdateWeenieToBlock ( unsigned int weenie_id , unsigned int block_id )
{
2019-07-12 04:09:01 +00:00
return g_pDB2 - > Query ( " INSERT INTO blocks (weenie_id, block_id) VALUES (%u, %u) ON DUPLICATE KEY UPDATE block_id = %u; " , weenie_id , block_id , block_id ) ;
2018-03-29 17:01:57 -04:00
}
bool CDatabaseIO : : RemoveWeenieFromBlock ( unsigned int weenie_id )
{
2019-07-12 04:09:01 +00:00
return g_pDB2 - > Query ( " DELETE FROM blocks WHERE weenie_id = %u; " , weenie_id ) ;
2018-03-29 17:01:57 -04:00
}
std : : list < CharacterDesc_t > CDatabaseIO : : GetCharacterList ( unsigned int account_id )
{
std : : list < CharacterDesc_t > results ;
2019-11-23 20:34:53 +00:00
std : : vector < unsigned int > charsToDelete ;
2019-01-08 12:25:04 -06:00
mysql_statement < 1 > statement = g_pDB2 - > QueryEx (
2020-08-07 10:58:05 -07:00
" SELECT account_id, weenie_id, name, date_created, instance_ts, ts_deleted, gag_timer FROM characters WHERE account_id = ? ORDER BY ts_login DESC; " ,
2019-01-08 12:25:04 -06:00
account_id ) ;
if ( statement )
2018-03-29 17:01:57 -04:00
{
2020-08-07 10:58:05 -07:00
CharacterDesc_t desc = { 0 , 0 , " " , 0 , 0 , 0 , 0.0 } ;
2019-01-08 12:25:04 -06:00
desc . name . resize ( 64 ) ;
unsigned long length = 0 ;
2020-08-07 10:58:05 -07:00
mysql_statement_results < 7 > row ;
2019-01-08 12:25:04 -06:00
row . bind ( 0 , desc . account_id ) ;
row . bind ( 1 , desc . weenie_id ) ;
row . bind ( 2 , desc . name , desc . name . capacity ( ) , & length ) ;
row . bind ( 3 , desc . date_created ) ;
row . bind ( 4 , desc . instance_ts ) ;
2019-11-23 20:34:53 +00:00
row . bind ( 5 , desc . ts_deleted ) ;
2020-08-07 10:58:05 -07:00
row . bind ( 6 , desc . gag_timer ) ;
2019-01-08 12:25:04 -06:00
if ( statement . bindResults ( row ) )
2018-03-29 17:01:57 -04:00
{
2019-01-08 12:25:04 -06:00
while ( row . next ( ) )
2018-03-29 17:01:57 -04:00
{
2019-11-23 20:34:53 +00:00
int32_t ts_delete = 0 ;
if ( desc . ts_deleted )
{
auto now = std : : chrono : : system_clock : : now ( ) ;
uint32_t ts = ( uint32_t ) std : : chrono : : system_clock : : to_time_t ( now ) ;
ts_delete = g_pConfig - > GetDeleteCharLifespan ( ) - ( ts - desc . ts_deleted ) ;
if ( ts_delete < = 0 )
{
charsToDelete . push_back ( desc . weenie_id ) ;
continue ;
}
desc . ts_deleted = ts_delete ;
}
2019-01-08 12:25:04 -06:00
CharacterDesc_t entry = desc ;
entry . name . resize ( length ) ;
2018-03-29 17:01:57 -04:00
results . push_back ( entry ) ;
}
}
}
2019-11-23 20:34:53 +00:00
for ( auto it = charsToDelete . begin ( ) ; it ! = charsToDelete . end ( ) ; + + it ) {
DeleteCharacter ( * it , true ) ;
}
2018-03-29 17:01:57 -04:00
return results ;
}
2020-08-07 10:58:05 -07:00
2018-09-21 06:16:42 -07:00
std : : list < CharacterSquelch_t > CDatabaseIO : : GetCharacterSquelch ( unsigned int character_id )
{
std : : list < CharacterSquelch_t > results ;
if ( g_pDB2 - > Query ( " SELECT squelched_id, account_id, isip, isspeech, istell, iscombat, ismagic, isemote, isadvancement, isappraisal, isspellcasting, isallegiance, isfellowhip, iscombatenemy, isrecall, iscrafting FROM character_squelch WHERE character_id = %u " , character_id ) )
{
CSQLResult * pQueryResult = g_pDB2 - > GetResult ( ) ;
if ( pQueryResult )
{
while ( SQLResultRow_t Row = pQueryResult - > FetchRow ( ) )
{
CharacterSquelch_t entry ;
entry . squelched_id = strtoul ( Row [ 0 ] , NULL , 10 ) ;
entry . account_id = strtoul ( Row [ 1 ] , NULL , 10 ) ;
entry . isIp = Row [ 2 ] ;
entry . isSpeech = Row [ 3 ] ;
entry . isTell = Row [ 4 ] ;
entry . isCombat = Row [ 5 ] ;
entry . isMagic = Row [ 6 ] ;
entry . isEmote = Row [ 7 ] ;
entry . isAdvancement = Row [ 8 ] ;
entry . isAppraisal = Row [ 9 ] ;
entry . isSpellcasting = Row [ 10 ] ;
entry . isAllegiance = Row [ 11 ] ;
entry . isFellowship = Row [ 12 ] ;
entry . isCombatEnemy = Row [ 13 ] ;
entry . isRecall = Row [ 14 ] ;
entry . isCrafting = Row [ 15 ] ;
results . push_back ( entry ) ;
}
delete pQueryResult ;
}
}
return results ;
}
bool CDatabaseIO : : SaveCharacterSquelch ( unsigned int character_id , CharacterSquelch_t data )
{
return g_pDB2 - > Query ( " INSERT INTO character_squelch(character_id, squelched_id, account_id, isip, isspeech, istell, iscombat, ismagic, isemote, isadvancement, isappraisal, isspellcasting, isallegiance, isfellowhip, iscombatenemy, isrecall, iscrafting) VALUES "
" (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) ON DUPLICATE KEY UPDATE "
2018-09-24 22:40:27 -07:00
" isip = %u, isspeech = %u, istell = %u, iscombat = %u, ismagic = %u, isemote = %u, isadvancement = %u, isappraisal = %u, isspellcasting = %u, isallegiance = %u, isfellowhip = %u, iscombatenemy = %u, isrecall = %u, iscrafting = %u; " ,
2018-09-21 06:16:42 -07:00
character_id , data . squelched_id , data . account_id , data . isIp , data . isSpeech , data . isTell , data . isCombat , data . isMagic , data . isEmote , data . isAdvancement ,
data . isAppraisal , data . isSpellcasting , data . isAllegiance , data . isFellowship , data . isCombatEnemy , data . isRecall , data . isCrafting ,
2018-09-24 22:40:27 -07:00
data . isIp , data . isSpeech , data . isTell , data . isCombat , data . isMagic , data . isEmote , data . isAdvancement ,
2018-09-21 06:16:42 -07:00
data . isAppraisal , data . isSpellcasting , data . isAllegiance , data . isFellowship , data . isCombatEnemy , data . isRecall , data . isCrafting ) ;
}
bool CDatabaseIO : : RemoveCharacterSquelch ( unsigned int character_id , CharacterSquelch_t data )
{
2018-09-24 22:40:27 -07:00
return g_pDB2 - > Query ( " DELETE FROM character_squelch WHERE character_id = %u AND squelched_id = %u; " , character_id , data . squelched_id ) ;
2018-09-21 06:16:42 -07:00
}
2020-08-07 10:58:05 -07:00
std : : list < CharacterGags_t > CDatabaseIO : : GetServerGagData ( )
{
std : : list < CharacterGags_t > results ;
mysql_statement < 0 > statement = g_pDB2 - > QueryEx (
" SELECT name, gag_timer, gag_count FROM characters WHERE gag_timer != 0 ORDER BY name; " ) ;
if ( statement )
{
CharacterGags_t desc = { " " , 0 , 0 } ;
desc . name . resize ( 64 ) ;
unsigned long length = 0 ;
mysql_statement_results < 3 > row ;
row . bind ( 0 , desc . name , desc . name . capacity ( ) , & length ) ;
row . bind ( 1 , desc . gag_timer ) ;
row . bind ( 2 , desc . gag_count ) ;
if ( statement . bindResults ( row ) )
{
while ( row . next ( ) )
{
CharacterGags_t entry = desc ;
entry . name . resize ( length ) ;
results . push_back ( entry ) ;
}
}
}
return results ;
}
CharacterGags_t CDatabaseIO : : GetCharacterGagData ( unsigned int character_id )
{
CharacterGags_t result = { " " , 0 , 0 } ;
mysql_statement < 1 > statement = g_pDB2 - > QueryEx (
" SELECT name, gag_timer, gag_count FROM characters WHERE weenie_id = ?; " , character_id ) ;
if ( statement )
{
result . name . resize ( 64 ) ;
unsigned long length = 0 ;
mysql_statement_results < 3 > row ;
row . bind ( 0 , result . name , result . name . capacity ( ) , & length ) ;
row . bind ( 1 , result . gag_timer ) ;
row . bind ( 2 , result . gag_count ) ;
if ( statement . bindResults ( row ) )
{
if ( row . next ( ) )
{
result . name . resize ( length ) ;
}
}
}
return result ;
}
bool CDatabaseIO : : SaveServerGag ( unsigned int character_id , double duration , bool account )
{
int gagCount = 1 ;
if ( g_pDB2 - > Query ( " SELECT gag_count FROM characters WHERE weenie_id = %u; " , character_id ) )
{
CSQLResult * pQueryResult = g_pDB2 - > GetResult ( ) ;
if ( pQueryResult )
{
SQLResultRow_t Row = pQueryResult - > FetchRow ( ) ;
if ( Row )
{
gagCount = strtoul ( Row [ 0 ] , NULL , 10 ) ;
}
delete pQueryResult ;
}
}
if ( ! g_pDB2 - > Query ( " UPDATE characters SET gag_timer = %f, gag_count = %d WHERE weenie_id=%u " , duration , + + gagCount , character_id ) )
{
SERVER_ERROR < < " GAG UPDATE: Failed on Weenie ID - " < < character_id ;
return false ;
}
if ( account )
{
uint32_t accountId = GetPlayerAccountId ( character_id ) ;
std : : vector < unsigned int > characters ;
if ( g_pDB2 - > Query ( " SELECT weenie_id FROM characters where account_id = %u; " , accountId ) )
{
CSQLResult * pQueryResult = g_pDB2 - > GetResult ( ) ;
if ( pQueryResult )
{
while ( SQLResultRow_t Row = pQueryResult - > FetchRow ( ) )
{
characters . push_back ( strtoul ( Row [ 0 ] , NULL , 10 ) ) ;
}
delete pQueryResult ;
}
}
for ( auto chr : characters )
SaveServerGag ( chr , duration ) ;
}
return true ;
}
bool CDatabaseIO : : RemoveServerGag ( unsigned int character_id , bool account )
{
if ( ! g_pDB2 - > Query ( " UPDATE characters SET gag_timer = 0.0 WHERE weenie_id=%u " , character_id ) )
{
SERVER_ERROR < < " GAG REMOVE: Failed on Weenie ID - " < < character_id ;
return false ;
}
if ( account )
{
uint32_t accountId = GetPlayerAccountId ( character_id ) ;
std : : vector < unsigned int > characters ;
if ( g_pDB2 - > Query ( " SELECT weenie_id FROM characters where account_id = %u; " , accountId ) )
{
CSQLResult * pQueryResult = g_pDB2 - > GetResult ( ) ;
if ( pQueryResult )
{
while ( SQLResultRow_t Row = pQueryResult - > FetchRow ( ) )
{
characters . push_back ( strtoul ( Row [ 0 ] , NULL , 10 ) ) ;
}
delete pQueryResult ;
}
}
for ( auto chr : characters )
RemoveServerGag ( chr ) ;
}
return true ;
}
2019-07-07 20:56:15 +00:00
uint32_t CDatabaseIO : : GetPlayerAccountId ( unsigned int character_id )
2018-09-21 06:16:42 -07:00
{
2019-07-07 20:56:15 +00:00
uint32_t accountToSquelch = 0 ;
2018-09-24 22:40:27 -07:00
if ( g_pDB2 - > Query ( " SELECT account_id FROM characters WHERE weenie_id = %u; " , character_id ) )
{
CSQLResult * pQueryResult = g_pDB2 - > GetResult ( ) ;
if ( pQueryResult )
{
SQLResultRow_t Row = pQueryResult - > FetchRow ( ) ;
2018-10-03 06:19:56 -07:00
if ( Row )
{
accountToSquelch = strtoul ( Row [ 0 ] , NULL , 10 ) ;
}
2018-09-24 22:40:27 -07:00
delete pQueryResult ;
}
}
return accountToSquelch ;
2018-09-21 06:16:42 -07:00
}
2018-06-26 13:25:24 +01:00
CharacterDesc_t CDatabaseIO : : GetCharacterInfo ( unsigned int weenie_id )
{
2019-11-23 20:34:53 +00:00
CharacterDesc_t result = { 0 , 0 , " " , 0 , 0 , 0 } ;
2018-06-26 13:25:24 +01:00
2019-01-08 12:25:04 -06:00
mysql_statement < 1 > statement = g_pDB2 - > QueryEx (
2019-11-23 20:34:53 +00:00
" SELECT account_id, weenie_id, name, date_created, instance_ts, ts_deleted FROM characters WHERE weenie_id = ?; " ,
2019-01-08 12:25:04 -06:00
weenie_id ) ;
if ( statement )
2018-06-26 13:25:24 +01:00
{
2019-01-08 12:25:04 -06:00
result . name . resize ( 64 ) ;
unsigned long length = 0 ;
2019-11-23 20:34:53 +00:00
mysql_statement_results < 6 > row ;
2019-01-08 12:25:04 -06:00
row . bind ( 0 , result . account_id ) ;
row . bind ( 1 , result . weenie_id ) ;
row . bind ( 2 , result . name , result . name . capacity ( ) , & length ) ;
row . bind ( 3 , result . date_created ) ;
row . bind ( 4 , result . instance_ts ) ;
2019-11-23 20:34:53 +00:00
row . bind ( 5 , result . ts_deleted ) ;
2019-01-08 12:25:04 -06:00
if ( statement . bindResults ( row ) )
2018-06-26 13:25:24 +01:00
{
2019-01-08 12:25:04 -06:00
if ( row . next ( ) )
2018-09-28 17:44:12 -07:00
{
2019-01-08 12:25:04 -06:00
result . name . resize ( length ) ;
2018-09-28 17:44:12 -07:00
}
2018-06-26 13:25:24 +01:00
}
}
return result ;
}
2018-03-29 17:01:57 -04:00
bool CDatabaseIO : : CreateCharacter ( unsigned int account_id , unsigned int weenie_id , const char * name )
{
return g_pDB2 - > Query ( " INSERT INTO characters (account_id, weenie_id, name, date_created, instance_ts) VALUES (%u, %u, '%s', UNIX_TIMESTAMP(), 1) " ,
account_id , weenie_id , g_pDB2 - > EscapeString ( name ) . c_str ( ) ) ;
}
2019-11-23 20:34:53 +00:00
bool CDatabaseIO : : DeleteCharacter ( unsigned int weenie_id , bool force )
2018-03-29 17:01:57 -04:00
{
2019-11-23 20:34:53 +00:00
if ( force )
{
DeleteCharacterTitles ( weenie_id ) ;
DeleteCharacterInventory ( weenie_id ) ;
return g_pDB2 - > Query ( " DELETE FROM characters WHERE weenie_id = %u " , weenie_id ) ;
}
auto now = std : : chrono : : system_clock : : now ( ) ;
uint32_t ts = ( uint32_t ) std : : chrono : : system_clock : : to_time_t ( now ) ;
if ( ! g_pDB2 - > Query ( " UPDATE characters SET ts_deleted=%u WHERE weenie_id=%u " , ts , weenie_id ) )
{
SERVER_ERROR < < " CHAR DELETE: Failed on Weenie ID - " < < weenie_id ;
return false ;
}
return true ;
}
bool CDatabaseIO : : IsCharacterDeleting ( unsigned int weenie_id )
{
mysql_statement < 1 > statement = g_pDB2 - > QueryEx (
" SELECT ts_deleted FROM characters WHERE ts_deleted > 0 AND weenie_id = ? " ,
weenie_id ) ;
if ( statement )
{
uint32_t result_id = 0 ;
mysql_statement_results < 1 > result ;
result . bind ( 0 , result_id ) ;
if ( statement . bindResults ( result ) )
{
if ( result . next ( ) )
{
return true ;
}
}
}
return false ;
}
bool CDatabaseIO : : RestoreCharacter ( unsigned int weenie_id )
{
if ( ! g_pDB2 - > Query ( " UPDATE characters SET ts_deleted = 0 WHERE weenie_id = %u; " , weenie_id ) )
return false ;
return true ;
2018-03-29 17:01:57 -04:00
}
bool CDatabaseIO : : SetCharacterInstanceTS ( unsigned int weenie_id , unsigned int instance_ts )
{
2019-11-23 20:34:53 +00:00
auto now = std : : chrono : : system_clock : : now ( ) ;
uint32_t ts = ( uint32_t ) std : : chrono : : system_clock : : to_time_t ( now ) ;
auto statement = g_pDB2 - > Query ( " UPDATE characters SET instance_ts=%u, ts_login=%u WHERE weenie_id=%u; " , instance_ts , ts , weenie_id ) ;
if ( statement )
return true ;
SERVER_ERROR < < " CHAR LOGIN: Failed to set Instance or Login timestampes for Weenie ID - " < < weenie_id ;
return false ;
2018-03-29 17:01:57 -04:00
}
2018-08-10 21:51:08 -07:00
bool CDatabaseIO : : IDRangeTableExistsAndValid ( )
{
bool retval = false ;
2019-01-08 12:25:04 -06:00
mysql_statement < 0 > statement = g_pDB2 - > QueryEx ( " SELECT unused FROM idranges WHERE unused > 2147999999 LIMIT 1 " ) ;
if ( statement )
2018-08-10 21:51:08 -07:00
{
2019-01-08 12:25:04 -06:00
unsigned int current = 0 ;
mysql_statement_results < 1 > result ;
result . bind ( 0 , current ) ;
if ( statement . bindResults ( result ) )
2018-08-10 21:51:08 -07:00
{
2019-01-08 12:25:04 -06:00
if ( result . next ( ) )
{
retval = true ;
}
2018-08-10 21:51:08 -07:00
}
}
return retval ;
}
std : : list < unsigned int > CDatabaseIO : : GetNextIDRange ( unsigned int rangeStart , unsigned int count )
{
2018-12-27 15:47:25 -06:00
mysql_statement < 2 > statement = g_pDB2 - > QueryEx (
" SELECT unused FROM idranges WHERE unused > ? limit ?; " ,
rangeStart , count ) ;
2018-08-10 21:51:08 -07:00
2018-12-27 15:47:25 -06:00
std : : list < unsigned int > found ;
if ( statement )
2018-08-10 21:51:08 -07:00
{
2018-12-27 15:47:25 -06:00
unsigned int current = 0 ;
mysql_statement_results < 1 > result ;
result . bind ( 0 , current ) ;
if ( statement . bindResults ( result ) )
2018-08-10 21:51:08 -07:00
{
2019-01-08 12:25:04 -06:00
while ( result . next ( ) )
2018-08-10 21:51:08 -07:00
{
2018-12-27 15:47:25 -06:00
found . push_back ( current ) ;
2018-08-10 21:51:08 -07:00
}
}
}
2018-12-27 15:47:25 -06:00
return found ;
2018-08-10 21:51:08 -07:00
}
2018-08-04 17:24:12 -07:00
2018-03-29 17:01:57 -04:00
unsigned int CDatabaseIO : : GetHighestWeenieID ( unsigned int min_range , unsigned int max_range )
{
2019-11-23 20:34:53 +00:00
uint32_t minId = min_range ;
2018-03-29 17:01:57 -04:00
2019-11-24 16:02:23 -08:00
if ( g_pDB2 - > Query ( " SELECT COALESCE(max(id), %u) FROM weenies WHERE id >= %u AND id < %u; " , min_range , min_range , max_range ) )
2018-03-29 17:01:57 -04:00
{
2019-11-23 20:34:53 +00:00
CSQLResult * pQueryResult = g_pDB2 - > GetResult ( ) ;
if ( pQueryResult )
2018-12-27 15:47:25 -06:00
{
2019-11-23 20:34:53 +00:00
SQLResultRow_t Row = pQueryResult - > FetchRow ( ) ;
if ( Row )
2018-12-27 15:47:25 -06:00
{
2019-11-23 20:34:53 +00:00
minId = strtoul ( Row [ 0 ] , NULL , 10 ) ;
2018-12-27 15:47:25 -06:00
}
2019-11-23 20:34:53 +00:00
delete pQueryResult ;
2018-03-29 17:01:57 -04:00
}
}
2019-11-23 20:34:53 +00:00
return minId ;
2018-03-29 17:01:57 -04:00
}
bool CDatabaseIO : : IsCharacterNameOpen ( const char * name )
{
2018-12-28 18:00:10 -06:00
std : : string tmp ( name ) ;
2018-12-27 15:47:25 -06:00
mysql_statement < 1 > statement = g_pDB2 - > QueryEx (
" SELECT weenie_id FROM characters WHERE name = ? " ,
2018-12-28 18:00:10 -06:00
tmp ) ;
2018-03-29 17:01:57 -04:00
2018-12-27 15:47:25 -06:00
if ( statement )
2018-03-29 17:01:57 -04:00
{
2018-12-27 15:47:25 -06:00
unsigned int id = 0 ;
mysql_statement_results < 1 > result ;
result . bind ( 0 , id ) ;
if ( statement . bindResults ( result ) )
2018-03-29 17:01:57 -04:00
{
2018-12-27 15:47:25 -06:00
if ( result . next ( ) )
{
return false ;
}
return true ;
2018-03-29 17:01:57 -04:00
}
}
2018-12-27 15:47:25 -06:00
SERVER_ERROR < < " Error on IsCharacterNameOpen: " < < statement . error ( ) ;
return false ;
2018-03-29 17:01:57 -04:00
}
bool CDatabaseIO : : IsPlayerCharacter ( unsigned int weenie_id )
{
2019-01-08 12:25:04 -06:00
mysql_statement < 1 > statement = g_pDB2 - > QueryEx (
" SELECT weenie_id FROM characters WHERE weenie_id = ? " ,
weenie_id ) ;
2018-12-14 16:34:18 -06:00
if ( statement )
2018-03-29 17:01:57 -04:00
{
2019-01-08 12:25:04 -06:00
uint32_t result_id = 0 ;
mysql_statement_results < 1 > result ;
result . bind ( 0 , result_id ) ;
2018-12-14 16:34:18 -06:00
2019-01-08 12:25:04 -06:00
if ( statement . bindResults ( result ) )
2018-03-29 17:01:57 -04:00
{
2019-01-08 12:25:04 -06:00
if ( result . next ( ) )
2018-12-14 16:34:18 -06:00
{
2019-01-08 12:25:04 -06:00
return true ;
2018-12-14 16:34:18 -06:00
}
2018-03-29 17:01:57 -04:00
}
}
2018-12-14 16:34:18 -06:00
return false ;
2018-03-29 17:01:57 -04:00
}
2019-07-07 20:56:15 +00:00
uint32_t CDatabaseIO : : GetPlayerCharacterId ( const char * name )
2018-03-29 17:01:57 -04:00
{
2018-12-14 16:34:18 -06:00
uint32_t id = 0 ;
2019-01-08 12:25:04 -06:00
mysql_statement < 1 > statement = g_pDB2 - > QueryEx (
" SELECT weenie_id FROM characters WHERE name = ? " ,
name ) ;
2018-12-14 16:34:18 -06:00
if ( statement )
2018-03-29 17:01:57 -04:00
{
2019-01-08 12:25:04 -06:00
mysql_statement_results < 1 > result ;
result . bind ( 0 , id ) ;
2018-12-14 16:34:18 -06:00
2019-01-08 12:25:04 -06:00
if ( statement . bindResults ( result ) )
2018-03-29 17:01:57 -04:00
{
2019-01-08 12:25:04 -06:00
result . next ( ) ;
2018-03-29 17:01:57 -04:00
}
}
2018-12-14 16:34:18 -06:00
2019-07-07 20:56:15 +00:00
return ( uint32_t ) id ;
2018-03-29 17:01:57 -04:00
}
2019-07-07 20:56:15 +00:00
std : : string CDatabaseIO : : GetPlayerCharacterName ( uint32_t weenie_id )
2018-03-29 17:01:57 -04:00
{
std : : string result ;
2018-12-14 16:34:18 -06:00
2019-01-08 12:25:04 -06:00
mysql_statement < 1 > statement = g_pDB2 - > QueryEx (
" SELECT name FROM characters WHERE weenie_id = ? " ,
weenie_id ) ;
2018-12-14 16:34:18 -06:00
if ( statement )
2018-03-29 17:01:57 -04:00
{
2019-01-08 12:25:04 -06:00
unsigned long length = 0 ;
mysql_statement_results < 1 > results ;
results . bind ( 0 , result , 64 , & length ) ;
2018-12-14 16:34:18 -06:00
2019-01-08 12:25:04 -06:00
if ( statement . bindResults ( results ) )
2018-03-29 17:01:57 -04:00
{
2019-01-08 12:25:04 -06:00
if ( results . next ( ) )
2018-12-14 16:34:18 -06:00
{
2019-01-08 12:25:04 -06:00
result . resize ( length ) ;
2018-12-14 16:34:18 -06:00
}
2018-03-29 17:01:57 -04:00
}
}
2018-12-14 16:34:18 -06:00
return result ;
2018-03-29 17:01:57 -04:00
}
/*
bool CDatabaseIO : : CreateOrUpdateWeenie ( unsigned int weenie_id , unsigned int top_level_object_id , unsigned int block_id , void * data , unsigned int data_length )
{
// synchronous, deprecated
return CreateOrUpdateWeenie ( ( MYSQL * ) g_pDB2 - > GetInternalConnection ( ) , weenie_id , top_level_object_id , block_id , data , data_length ) ;
}
*/
bool CDatabaseIO : : CreateOrUpdateWeenie ( unsigned int weenie_id , unsigned int top_level_object_id , unsigned int block_id , void * data , unsigned int data_length )
{
IncrementPendingSave ( weenie_id ) ;
g_pDB2 - > QueueAsyncQuery ( new CMYSQLSaveWeenieQuery ( weenie_id , top_level_object_id , block_id , data , data_length ) ) ;
return true ;
}
bool CDatabaseIO : : GetWeenie ( unsigned int weenie_id , unsigned int * top_level_object_id , unsigned int * block_id , void * * data , unsigned long * data_length )
{
// this is so bad...
while ( GetNumPendingSaves ( weenie_id ) )
2019-02-26 21:05:30 +00:00
std : : this_thread : : yield ( ) ;
2018-03-29 17:01:57 -04:00
2018-12-14 17:44:20 -06:00
mysql_statement < 1 > statement = g_pDB2 - > QueryEx (
" SELECT top_level_object_id, block_id, data FROM weenies WHERE id = ? " ,
weenie_id ) ;
2018-03-29 17:01:57 -04:00
2018-12-14 16:34:18 -06:00
if ( statement )
{
2018-12-14 17:44:20 -06:00
mysql_statement_results < 3 > result ;
result . bind ( 0 , top_level_object_id ) ;
result . bind ( 1 , block_id ) ;
result . bind ( 2 , blob_query_buffer , BLOB_QUERY_BUFFER_LENGTH , data_length ) ;
2018-03-29 17:01:57 -04:00
2018-12-14 17:44:20 -06:00
if ( statement . bindResults ( result ) )
2018-12-14 16:34:18 -06:00
{
2018-12-14 17:44:20 -06:00
if ( result . next ( ) )
2018-12-14 16:34:18 -06:00
{
2018-12-14 17:44:20 -06:00
* data = blob_query_buffer ;
return true ;
2018-12-14 16:34:18 -06:00
}
}
}
2018-03-29 17:01:57 -04:00
2018-12-27 15:47:25 -06:00
SERVER_ERROR < < " Error on GetWeenie: " < < statement . error ( ) ;
2018-12-14 16:34:18 -06:00
return false ;
}
2018-03-29 17:01:57 -04:00
2018-12-14 16:34:18 -06:00
bool CDatabaseIO : : DeleteWeenie ( unsigned int weenie_id )
{
2019-01-08 12:25:04 -06:00
mysql_statement < 2 > statement = g_pDB2 - > QueryEx (
2019-08-22 21:28:18 +00:00
" DELETE FROM weenies WHERE id = ?; " ,
2019-01-08 12:25:04 -06:00
weenie_id , weenie_id ) ;
2018-03-29 17:01:57 -04:00
2018-12-14 16:34:18 -06:00
if ( statement )
2018-03-29 17:01:57 -04:00
{
2019-01-08 12:25:04 -06:00
return true ;
2018-03-29 17:01:57 -04:00
}
2019-01-08 12:25:04 -06:00
SERVER_ERROR < < " Error on DeleteWeenie: " < < statement . error ( ) ;
2018-12-14 16:34:18 -06:00
return false ;
2018-03-29 17:01:57 -04:00
}
bool CDatabaseIO : : IsWeenieInDatabase ( unsigned int weenie_id )
{
2018-12-14 17:44:20 -06:00
mysql_statement < 1 > statement = g_pDB2 - > QueryEx (
" SELECT id FROM weenies WHERE id = ? " ,
weenie_id ) ;
2018-12-14 16:34:18 -06:00
if ( statement )
2018-03-29 17:01:57 -04:00
{
2018-12-14 17:44:20 -06:00
uint32_t result_id = 0 ;
mysql_statement_results < 1 > result ;
result . bind ( 0 , result_id ) ;
2018-12-14 16:34:18 -06:00
2018-12-14 17:44:20 -06:00
if ( statement . bindResults ( result ) )
2018-03-29 17:01:57 -04:00
{
2018-12-14 17:44:20 -06:00
if ( result . next ( ) )
2018-12-14 16:34:18 -06:00
{
2018-12-14 17:44:20 -06:00
return true ;
2018-12-14 16:34:18 -06:00
}
2018-03-29 17:01:57 -04:00
}
}
2018-12-14 16:34:18 -06:00
return false ;
2018-03-29 17:01:57 -04:00
}
bool CDatabaseIO : : CreateOrUpdateGlobalData ( DBIOGlobalDataID id , void * data , unsigned long data_length )
{
2019-01-08 12:25:04 -06:00
mysql_statement < 2 > statement = g_pDB2 - > CreateQuery < 2 > ( " REPLACE INTO globals (id, data) VALUES (?, ?) " ) ;
2018-12-14 16:34:18 -06:00
if ( statement )
2018-03-29 17:01:57 -04:00
{
2019-01-08 12:25:04 -06:00
uint32_t gid = ( uint32_t ) id ;
statement . bind ( 0 , gid ) ;
2018-12-14 16:34:18 -06:00
statement . bind ( 1 , data , data_length ) ;
2018-03-29 17:01:57 -04:00
2018-12-14 16:34:18 -06:00
if ( statement . execute ( ) )
return true ;
}
2019-01-08 12:25:04 -06:00
SERVER_ERROR < < " Error on CreateOrUpdateGlobalData for " < < id < < " : " < < statement . error ( ) ;
2018-12-14 16:34:18 -06:00
return false ;
2018-03-29 17:01:57 -04:00
}
bool CDatabaseIO : : GetGlobalData ( DBIOGlobalDataID id , void * * data , unsigned long * data_length )
{
2019-01-08 12:25:04 -06:00
uint32_t gid = ( uint32_t ) id ;
2018-12-14 17:44:20 -06:00
mysql_statement < 1 > statement = g_pDB2 - > QueryEx (
" SELECT data FROM globals WHERE id = ? " ,
2019-01-08 12:25:04 -06:00
gid ) ;
2018-03-29 17:01:57 -04:00
2018-12-14 16:34:18 -06:00
if ( statement )
2018-03-29 17:01:57 -04:00
{
2018-12-14 17:44:20 -06:00
mysql_statement_results < 1 > result ;
result . bind ( 0 , blob_query_buffer , BLOB_QUERY_BUFFER_LENGTH , data_length ) ;
2018-03-29 17:01:57 -04:00
2018-12-14 17:44:20 -06:00
if ( statement . bindResults ( result ) )
2018-12-14 16:34:18 -06:00
{
2018-12-14 17:44:20 -06:00
if ( result . next ( ) )
2018-12-14 16:34:18 -06:00
{
2018-12-14 17:44:20 -06:00
* data = blob_query_buffer ;
return true ;
2018-12-14 16:34:18 -06:00
}
2020-06-06 23:22:18 +00:00
return false ;
2018-12-14 16:34:18 -06:00
}
2018-03-29 17:01:57 -04:00
}
2019-01-08 12:25:04 -06:00
SERVER_ERROR < < " Error on GetGlobalData: " < < statement . error ( ) ;
2018-12-14 16:34:18 -06:00
return false ;
2018-03-29 17:01:57 -04:00
}
bool CDatabaseIO : : CreateOrUpdateHouseData ( unsigned int house_id , void * data , unsigned int data_length )
{
IncrementPendingSave ( house_id ) ;
g_pDB2 - > QueueAsyncQuery ( new CMYSQLSaveHouseQuery ( house_id , data , data_length ) ) ;
return true ;
}
bool CDatabaseIO : : GetHouseData ( unsigned int house_id , void * * data , unsigned long * data_length )
{
// this is so bad...
while ( GetNumPendingSaves ( house_id ) )
2019-02-26 21:05:30 +00:00
std : : this_thread : : yield ( ) ;
2018-03-29 17:01:57 -04:00
2019-01-08 12:25:04 -06:00
mysql_statement < 1 > statement = g_pDB2 - > QueryEx (
" SELECT data FROM houses WHERE house_id = ? " ,
house_id ) ;
2018-03-29 17:01:57 -04:00
2018-12-14 16:34:18 -06:00
if ( statement )
2018-03-29 17:01:57 -04:00
{
2019-01-08 12:25:04 -06:00
mysql_statement_results < 1 > result ;
result . bind ( 0 , blob_query_buffer , BLOB_QUERY_BUFFER_LENGTH , data_length ) ;
2018-03-29 17:01:57 -04:00
2019-01-08 12:25:04 -06:00
if ( statement . bindResults ( result ) )
2018-12-14 16:34:18 -06:00
{
2019-01-08 12:25:04 -06:00
if ( result . next ( ) )
2018-12-14 16:34:18 -06:00
{
2019-01-08 12:25:04 -06:00
* data = blob_query_buffer ;
return true ;
2018-12-14 16:34:18 -06:00
}
2020-06-06 23:22:18 +00:00
return false ;
2018-12-14 16:34:18 -06:00
}
}
2018-03-29 17:01:57 -04:00
2019-01-08 12:25:04 -06:00
SERVER_ERROR < < " Error on GetHouseData: " < < statement . error ( ) ;
2018-12-14 16:34:18 -06:00
return false ;
2018-03-29 17:01:57 -04:00
}
// CLockable _pendingSavesLock;
2019-07-07 20:56:15 +00:00
// std::unordered_map<uint32_t, uint32_t> _pendingSaves;
2018-03-29 17:01:57 -04:00
2019-07-07 20:56:15 +00:00
void CDatabaseIO : : IncrementPendingSave ( uint32_t weenie_id )
2018-03-29 17:01:57 -04:00
{
_pendingSavesLock . Lock ( ) ;
2019-07-07 20:56:15 +00:00
std : : unordered_map < uint32_t , uint32_t > : : iterator i = _pendingSaves . find ( weenie_id ) ;
2018-03-29 17:01:57 -04:00
if ( i ! = _pendingSaves . end ( ) )
{
i - > second + + ;
}
else
{
2019-07-07 20:56:15 +00:00
_pendingSaves . insert ( std : : pair < uint32_t , uint32_t > ( weenie_id , 1 ) ) ;
2018-03-29 17:01:57 -04:00
}
_pendingSavesLock . Unlock ( ) ;
}
2019-07-07 20:56:15 +00:00
void CDatabaseIO : : DecrementPendingSave ( uint32_t weenie_id )
2018-03-29 17:01:57 -04:00
{
_pendingSavesLock . Lock ( ) ;
2019-07-07 20:56:15 +00:00
std : : unordered_map < uint32_t , uint32_t > : : iterator i = _pendingSaves . find ( weenie_id ) ;
2018-03-29 17:01:57 -04:00
if ( i ! = _pendingSaves . end ( ) )
{
if ( i - > second < = 1 )
_pendingSaves . erase ( i ) ;
else
i - > second - - ;
}
_pendingSavesLock . Unlock ( ) ;
}
2019-07-07 20:56:15 +00:00
uint32_t CDatabaseIO : : GetNumPendingSaves ( uint32_t weenie_id )
2018-03-29 17:01:57 -04:00
{
_pendingSavesLock . Lock ( ) ;
2019-07-07 20:56:15 +00:00
std : : unordered_map < uint32_t , uint32_t > : : iterator i = _pendingSaves . find ( weenie_id ) ;
2018-03-29 17:01:57 -04:00
2019-07-07 20:56:15 +00:00
uint32_t numSaves = 0 ;
2018-03-29 17:01:57 -04:00
if ( i ! = _pendingSaves . end ( ) )
{
numSaves = i - > second ;
}
_pendingSavesLock . Unlock ( ) ;
return numSaves ;
}
2019-06-06 20:51:11 -07:00
bool CDatabaseIO : : IsAlreadyFriend ( unsigned int character_id , unsigned int friend_id )
{
mysql_statement < 2 > statement = g_pDB2 - > QueryEx (
2019-06-12 04:15:28 +00:00
" SELECT friend_id FROM character_friends WHERE character_id = ? AND friend_id = ? AND friend_type = 1; " , character_id , friend_id ) ;
2019-06-06 20:51:11 -07:00
if ( statement )
{
unsigned int id = 0 ;
mysql_statement_results < 1 > result ;
result . bind ( 0 , id ) ;
if ( statement . bindResults ( result ) )
{
if ( result . next ( ) )
{
return true ;
}
return false ;
}
}
return false ;
}
2019-05-28 14:45:19 +00:00
bool CDatabaseIO : : AddCharacterFriend ( unsigned int character_id , unsigned int friend_id )
{
if ( ! g_pDB2 - > Query ( " REPLACE INTO character_friends (character_id, friend_type, friend_id) VALUES (%u, 1, %u); " , character_id , friend_id ) )
return false ;
if ( ! g_pDB2 - > Query ( " REPLACE INTO character_friends (character_id, friend_type, friend_id) VALUES (%u, 2, %u); " , friend_id , character_id ) )
return false ;
return true ;
}
bool CDatabaseIO : : RemoveCharacterFriend ( unsigned int character_id , unsigned int frenemy_id )
{
if ( ! g_pDB2 - > Query ( " DELETE FROM character_friends WHERE character_id = %u AND friend_id = %u; " , character_id , frenemy_id ) )
return false ;
if ( ! g_pDB2 - > Query ( " DELETE FROM character_friends WHERE friend_id = %u AND character_id = %u; " , frenemy_id , character_id ) )
return false ;
return true ;
}
void CDatabaseIO : : DeleteCharFriends ( unsigned int character_id )
{
g_pDB2 - > Query ( " DELETE FROM character_friends WHERE character_id = %u; " , character_id ) ;
g_pDB2 - > Query ( " DELETE FROM character_friends WHERE friend_id = %u; " , character_id ) ;
}
2020-02-28 19:11:41 +00:00
bool CDatabaseIO : : SaveWindowData ( unsigned int character_id , BYTE * data , unsigned long data_length )
{
mysql_statement < 3 > statement = g_pDB2 - > CreateQuery < 3 > ( " REPLACE INTO character_windowdata (character_id, bloblength, windowblob) VALUES (?,?, ?) " ) ;
if ( statement )
{
uint32_t gid = ( uint32_t ) character_id ;
statement . bind ( 0 , gid ) ;
statement . bind ( 1 , data_length ) ;
statement . bind ( 2 , data , data_length ) ;
if ( statement . execute ( ) )
return true ;
}
SERVER_ERROR < < " Error on saving window data for " < < character_id < < " : " < < statement . error ( ) ;
return false ;
}
int CDatabaseIO : : LoadWindowData ( unsigned int character_id , BYTE * * data )
{
int retVal = 0 ;
unsigned long * data_length = 0 ;
uint32_t gid = ( uint32_t ) character_id ;
mysql_statement < 1 > statement = g_pDB2 - > QueryEx (
" SELECT bloblength, windowblob FROM character_windowdata WHERE character_id = ? " ,
gid ) ;
if ( statement )
{
mysql_statement_results < 2 > result ;
result . bind ( 0 , retVal ) ;
result . bind ( 1 , blob_query_buffer , BLOB_QUERY_BUFFER_LENGTH , data_length ) ;
if ( statement . bindResults ( result ) )
{
if ( result . next ( ) )
{
* data = blob_query_buffer ;
return retVal ;
}
2020-06-06 23:22:18 +00:00
return false ;
2020-02-28 19:11:41 +00:00
}
}
SERVER_ERROR < < " Error on reading window data for " < < character_id < < " : " < < statement . error ( ) ;
return retVal ;
}
2019-05-28 14:45:19 +00:00
void CDatabaseIO : : ClearFriendsList ( unsigned int character_id )
{
g_pDB2 - > Query ( " DELETE FROM character_friends WHERE character_id = %u; " , character_id ) ;
}
std : : list < CharacterDesc_t > CDatabaseIO : : GetFriends ( unsigned int character_id )
{
std : : list < CharacterDesc_t > results ;
mysql_statement < 1 > statement = g_pDB2 - > QueryEx (
" SELECT 0, cf.friend_id, c.name, 0, 0 FROM characters c JOIN character_friends cf ON cf.friend_id = c.weenie_id WHERE cf.friend_type = 1 AND cf.character_id = ? " ,
character_id ) ;
if ( statement )
{
CharacterDesc_t desc = { 0 , 0 , " " , 0 , 0 } ;
desc . name . resize ( 64 ) ;
unsigned long length = 0 ;
mysql_statement_results < 5 > row ;
row . bind ( 0 , desc . account_id ) ;
row . bind ( 1 , desc . weenie_id ) ;
row . bind ( 2 , desc . name , desc . name . capacity ( ) , & length ) ;
row . bind ( 3 , desc . date_created ) ;
row . bind ( 4 , desc . instance_ts ) ;
if ( statement . bindResults ( row ) )
{
while ( row . next ( ) )
{
CharacterDesc_t entry = desc ;
entry . name . resize ( length ) ;
results . push_back ( entry ) ;
}
}
}
return results ;
}
std : : list < CharacterDesc_t > CDatabaseIO : : GetFriendsOf ( unsigned int character_id )
{
std : : list < CharacterDesc_t > results ;
mysql_statement < 1 > statement = g_pDB2 - > QueryEx (
" SELECT 0, cf.friend_id, c.name, 0, 0 FROM characters c JOIN character_friends cf ON cf.friend_id = c.weenie_id WHERE cf.friend_type = 2 AND cf.character_id = ? " ,
character_id ) ;
if ( statement )
{
CharacterDesc_t desc = { 0 , 0 , " " , 0 , 0 } ;
desc . name . resize ( 64 ) ;
unsigned long length = 0 ;
mysql_statement_results < 5 > row ;
row . bind ( 0 , desc . account_id ) ;
row . bind ( 1 , desc . weenie_id ) ;
row . bind ( 2 , desc . name , desc . name . capacity ( ) , & length ) ;
row . bind ( 3 , desc . date_created ) ;
row . bind ( 4 , desc . instance_ts ) ;
if ( statement . bindResults ( row ) )
{
while ( row . next ( ) )
{
CharacterDesc_t entry = desc ;
entry . name . resize ( length ) ;
results . push_back ( entry ) ;
}
}
}
return results ;
2019-07-12 04:09:01 +00:00
}