1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-02 08:57:44 +00:00

Player loading moved over to new DB system

This commit is contained in:
Mordred 2017-10-04 23:28:38 +02:00
parent ac0a935885
commit 8cf1dcd1ee
4 changed files with 152 additions and 110 deletions

View file

@ -21,4 +21,17 @@ void Core::Db::CharaDbConnection::doPrepareStatements()
prepareStatement( CHAR_INS_TEST, "INSERT INTO zoneservers ( id, ip, port ) VALUES ( ?, ?, ?);", CONNECTION_BOTH );
prepareStatement( CHAR_SEL_LOAD, "SELECT c.Name, c.PrimaryTerritoryId, c.Hp, c.Mp, c.Gp, c.Mode, "
"c.Pos_0_0, c.Pos_0_1, c.Pos_0_2, c.Pos_0_3, c.FirstLogin, "
"c.Customize, c.ModelMainWeapon, c.ModelSubWeapon, c.ModelEquip, "
"cd.GuardianDeity, cd.BirthDay, cd.BirthMonth, cd.Status, cd.Class, "
"cd.Homepoint, cd.HowTo, c.ContentId, c.Voice, cd.QuestCompleteFlags, "
"cd.QuestTracking, c.IsNewGame, cd.Aetheryte, cd.unlocks, cd.Discovery, "
"cd.StartTown, cd.TotalPlayTime, c.IsNewAdventurer, cd.GrandCompany, "
"cd.GrandCompanyRank, cd.CFPenaltyUntil, cd.OpeningSequence, cd.GMRank "
"FROM charabase AS c "
" INNER JOIN charadetail AS cd "
" ON c.CharacterId = cd.CharacterId "
"WHERE c.CharacterId = ?;", CONNECTION_SYNCH );
}

View file

@ -11,6 +11,7 @@ class DbConnectionInfo;
enum CharaDbStatements : uint32_t
{
CHAR_SEL_LOAD,
CHAR_INS_TEST,
MAX_STATEMENTS

View file

@ -13,6 +13,11 @@
#include <time.h>
#include <Server_Common/Database/DbLoader.h>
#include <Server_Common/Database/CharaDbConnection.h>
#include <Server_Common/Database/DbWorkerPool.h>
#include <Server_Common/Database/PreparedStatement.h>
#include "Player.h"
#include "src/servers/Server_Zone/Zone/ZoneMgr.h"
@ -27,11 +32,15 @@
#include "src/servers/Server_Zone/StatusEffect/StatusEffectContainer.h"
#include "src/servers/Server_Zone/Inventory/Inventory.h"
#include "src/libraries/sapphire/mysqlConnector/MySqlConnector.h"
extern Core::Logger g_log;
extern Core::Db::Database g_database;
extern Core::ServerZone g_serverZone;
extern Core::ZoneMgr g_zoneMgr;
extern Core::Data::ExdData g_exdData;
extern Core::Db::DbWorkerPool< Core::Db::CharaDbConnection > g_charaDb;
using namespace Core::Common;
using namespace Core::Network::Packets;
@ -40,72 +49,30 @@ using namespace Core::Network::Packets::Server;
// load player from the db
bool Core::Entity::Player::load( uint32_t charId, Core::SessionPtr pSession )
{
// TODO: can't help but think that the whole player loading could be handled better...
const std::string char_id_str = std::to_string( charId );
auto pQR = g_database.query( "SELECT "
"c.Name, "
"c.PrimaryTerritoryId, "
"c.Hp, "
"c.Mp, "
"c.Gp, "
"c.Mode, "
"c.Pos_0_0, "
"c.Pos_0_1, "
"c.Pos_0_2, "
"c.Pos_0_3, "
"c.FirstLogin, " // 10
"c.Customize, "
"c.ModelMainWeapon, "
"c.ModelSubWeapon, "
"c.ModelEquip, "
"cd.GuardianDeity, "
"cd.BirthDay, "
"cd.BirthMonth, "
"cd.Status, "
"cd.Class, "
"cd.Homepoint, " // 20
"cd.HowTo, "
"c.ContentId, "
"c.Voice, "
"cd.QuestCompleteFlags, "
"cd.QuestTracking, "
"c.IsNewGame, "
"cd.Aetheryte, "
"cd.unlocks, "
"cd.Discovery, "
"cd.StartTown, " // 30
"cd.TotalPlayTime, "
"c.IsNewAdventurer, "
"cd.GrandCompany, "
"cd.GrandCompanyRank, "
"cd.CFPenaltyUntil, "
"cd.OpeningSequence, "
"cd.GMRank "
"FROM charabase AS c "
" INNER JOIN charadetail AS cd "
" ON c.CharacterId = cd.CharacterId "
"WHERE c.CharacterId = " + char_id_str + ";" );
boost::scoped_ptr< Core::Db::PreparedStatement > stmt( g_charaDb.getPreparedStatement( Core::Db::CharaDbStatements::CHAR_SEL_LOAD ) );
stmt->setUInt( 1, charId );
if( !pQR )
{
g_log.error( "Player id " + char_id_str + " does not exist!" );
auto res = dynamic_cast< Mysql::PreparedResultSet* >( g_charaDb.query( stmt.get() ) );
if( !res->next() )
return false;
}
m_id = charId;
Db::Field *field = pQR->fetch();
auto name = res->getString( "Name" );
strcpy( m_name, name.c_str() );
strcpy( m_name, field[0].getString().c_str() );
auto zoneId = res->getUInt( "PrimaryTerritoryId" );
ZonePtr pCurrZone = g_zoneMgr.getZone( field[1].get< int32_t >() );
m_zoneId = field[1].get< int32_t >();
ZonePtr pCurrZone = g_zoneMgr.getZone( zoneId );
m_zoneId = zoneId;
// see if a valid zone could be found for the character
if( !pCurrZone )
{
g_log.error( "[" + char_id_str + "] Zone " + std::to_string( field[1].get< int32_t >() ) + "not found!" );
g_log.error( "[" + char_id_str + "] Zone " + std::to_string( zoneId ) + " not found!" );
g_log.error( "[" + char_id_str + "] Setting default zone instead" );
// default to new gridania
@ -118,60 +85,125 @@ bool Core::Entity::Player::load( uint32_t charId, Core::SessionPtr pSession )
setRotation( 0.0f );
}
m_hp = field[2].get< uint16_t >();
m_mp = field[3].get< uint16_t >();
m_hp = res->getUInt( "Hp" );
m_mp = res->getUInt( "Mp" );
m_tp = 0;
m_pos.x = field[6].getFloat();
m_pos.y = field[7].getFloat();
m_pos.z = field[8].getFloat();
setRotation( field[9].getFloat() );
m_pos.x = res->getFloat( "Pos_0_0" );
m_pos.y = res->getFloat( "Pos_0_1" );
m_pos.z = res->getFloat( "Pos_0_2" );
setRotation( res->getFloat( "Pos_0_3" ) );
field[11].getBinary( reinterpret_cast< char* >( m_customize ), sizeof( m_customize ) );
auto custom = res->getBlobVector( "Customize" );
memcpy( reinterpret_cast< char* >( m_customize ), custom.data(), custom.size() );
m_modelMainWeapon = field[12].getUInt64();
m_modelMainWeapon = res->getUInt64( "ModelMainWeapon" );
field[14].getBinary( reinterpret_cast< char* >( m_modelEquip ), sizeof( m_modelEquip ) );
auto modelEq = res->getBlobVector( "ModelEquip" );
memcpy( reinterpret_cast< char* >( m_modelEquip ), modelEq.data(), modelEq.size() );
m_guardianDeity = field[15].get< uint8_t >();
m_birthDay = field[16].get< uint8_t >();
m_birthMonth = field[17].get< uint8_t >();
m_status = static_cast< ActorStatus >( field[18].get< uint8_t >() );
m_class = static_cast< ClassJob >( field[19].get< uint8_t >() );
m_homePoint = field[20].get< uint8_t >();
m_guardianDeity = res->getUInt( "GuardianDeity" );
m_birthDay = res->getUInt( "BirthDay" );
m_birthMonth = res->getUInt( "BirthMonth" );
m_status = static_cast< ActorStatus >( res->getUInt( "Status" ) );
m_class = static_cast< ClassJob >( res->getUInt( "Class" ) );
m_homePoint = res->getUInt( "Homepoint" );
field[21].getBinary( reinterpret_cast< char* >( m_howTo ), sizeof( m_howTo ) );
auto howTo = res->getBlobVector( "HowTo" );
memcpy( reinterpret_cast< char* >( m_howTo ), howTo.data(), howTo.size() );
m_contentId = field[22].getUInt64();
m_contentId = res->getUInt64( "ContentId" );
m_voice = field[23].get< uint32_t >();
m_voice = res->getUInt( "Voice" );
field[24].getBinary( reinterpret_cast< char* >( m_questCompleteFlags ), sizeof( m_questCompleteFlags ) );
auto questCompleteFlags = res->getBlobVector( "QuestCompleteFlags" );
memcpy( reinterpret_cast< char* >( m_questCompleteFlags ), questCompleteFlags.data(), questCompleteFlags.size() );
field[25].getBinary( reinterpret_cast< char* >( m_questTracking ), sizeof( m_questTracking ) );
auto questTracking = res->getBlobVector( "QuestTracking" );
memcpy( reinterpret_cast< char* >( m_questTracking ), questTracking.data(), questTracking.size() );
m_bNewGame = field[26].getBool();
m_bNewGame = res->getBoolean( "IsNewGame" );
field[27].getBinary( reinterpret_cast< char* >( m_aetheryte ), sizeof( m_aetheryte ) );
auto aetheryte = res->getBlobVector( "Aetheryte" );
memcpy( reinterpret_cast< char* >( m_aetheryte ), aetheryte.data(), aetheryte.size() );
field[28].getBinary( reinterpret_cast< char* >( m_unlocks ), sizeof( m_unlocks ) );
auto unlocks = res->getBlobVector( "unlocks" );
memcpy( reinterpret_cast< char* >( m_unlocks ), unlocks.data(), unlocks.size() );
field[29].getBinary( reinterpret_cast< char* >( m_discovery ), sizeof( m_discovery ) );
auto discovery = res->getBlobVector( "Discovery" );
memcpy( reinterpret_cast< char* >( m_discovery ), discovery.data(), discovery.size() );
m_startTown = field[30].get< int8_t >();
m_playTime = field[31].get< uint32_t >();
m_startTown = res->getUInt( "StartTown" );
m_playTime = res->getUInt( "TotalPlayTime" );
m_bNewAdventurer = field[32].getBool();
m_bNewAdventurer = res->getBoolean( "IsNewAdventurer" );
m_gc = res->getUInt( "GrandCompany" );
auto gcRank = res->getBlobVector( "GrandCompanyRank" );
memcpy( reinterpret_cast< char* >( m_gcRank ), gcRank.data(), gcRank.size() );
m_cfPenaltyUntil = res->getUInt( "CFPenaltyUntil" );
m_openingSequence = res->getUInt( "OpeningSequence" );
m_gmRank = res->getUInt( "GMRank" );
//auto pQR = g_database.query( "SELECT "
// "c.Name, "
// "c.PrimaryTerritoryId, "
// "c.Hp, "
// "c.Mp, "
// "c.Gp, "
// "c.Mode, "
// "c.Pos_0_0, "
// "c.Pos_0_1, "
// "c.Pos_0_2, "
// "c.Pos_0_3, "
// "c.FirstLogin, " // 10
// "c.Customize, "
// "c.ModelMainWeapon, "
// "c.ModelSubWeapon, "
// "c.ModelEquip, "
// "cd.GuardianDeity, "
// "cd.BirthDay, "
// "cd.BirthMonth, "
// "cd.Status, "
// "cd.Class, "
// "cd.Homepoint, " // 20
// "cd.HowTo, "
// "c.ContentId, "
// "c.Voice, "
// "cd.QuestCompleteFlags, "
// "cd.QuestTracking, "
// "c.IsNewGame, "
// "cd.Aetheryte, "
// "cd.unlocks, "
// "cd.Discovery, "
// "cd.StartTown, " // 30
// "cd.TotalPlayTime, "
// "c.IsNewAdventurer, "
// "cd.GrandCompany, "
// "cd.GrandCompanyRank, "
// "cd.CFPenaltyUntil, "
// "cd.OpeningSequence, "
// "cd.GMRank "
// "FROM charabase AS c "
// " INNER JOIN charadetail AS cd "
// " ON c.CharacterId = cd.CharacterId "
// "WHERE c.CharacterId = " + char_id_str + ";" );
//if( !pQR )
//{
// g_log.error( "Player id " + char_id_str + " does not exist!" );
// return false;
//}
//
//Db::Field *field = pQR->fetch();
m_gc = field[33].get< uint8_t >();
field[34].getBinary( reinterpret_cast< char* >( m_gcRank ), sizeof( m_gcRank ) );
m_cfPenaltyUntil = field[35].get< uint32_t >();
m_openingSequence = field[36].get< uint32_t >();
m_gmRank = field[37].get< uint8_t >();
m_pCell = nullptr;

View file

@ -51,7 +51,7 @@ Core::Scripting::ScriptManager g_scriptMgr;
Core::Data::ExdData g_exdData;
Core::ZoneMgr g_zoneMgr;
Core::LinkshellMgr g_linkshellMgr;
Core::Db::DbWorkerPool< Core::Db::CharaDbConnection > CharacterDatabase;
Core::Db::DbWorkerPool< Core::Db::CharaDbConnection > g_charaDb;
Core::ServerZone::ServerZone( const std::string& configPath, uint16_t serverId )
: m_configPath( configPath ),
@ -185,16 +185,16 @@ bool Core::ServerZone::loadSettings( int32_t argc, char* argv[] )
info.syncThreads = m_pConfig->getValue< uint8_t >( "Settings.General.Mysql.SyncThreads", 2 );
info.asyncThreads = m_pConfig->getValue< uint8_t >( "Settings.General.Mysql.AsyncThreads", 2 );
loader.addDb( CharacterDatabase, info );
loader.addDb( g_charaDb, info );
if( !loader.initDbs() )
return false;
// execute() runs asynchronous
CharacterDatabase.execute( "INSERT INTO zoneservers ( id, ip, port ) VALUES ( 101, '127.0.0.1', 54555);" );
CharacterDatabase.execute( "DELETE FROM zoneservers WHERE id = 101" );
g_charaDb.execute( "INSERT INTO zoneservers ( id, ip, port ) VALUES ( 101, '127.0.0.1', 54555);" );
g_charaDb.execute( "DELETE FROM zoneservers WHERE id = 101" );
// query runs synchronous
boost::scoped_ptr< Mysql::ResultSet > res( CharacterDatabase.query( "SELECT id,ip,port FROM zoneservers" ) );
boost::scoped_ptr< Mysql::ResultSet > res( g_charaDb.query( "SELECT id,ip,port FROM zoneservers" ) );
while( res->next() )
{
g_log.info( "id: " + std::to_string( res->getUInt( "id" ) ) );
@ -202,26 +202,26 @@ bool Core::ServerZone::loadSettings( int32_t argc, char* argv[] )
g_log.info( "port: " + std::to_string( res->getUInt( "port" ) ) );
}
auto stmt = CharacterDatabase.getPreparedStatement( Core::Db::CharaDbStatements::CHAR_INS_TEST );
auto stmt = g_charaDb.getPreparedStatement( Core::Db::CharaDbStatements::CHAR_INS_TEST );
stmt->setUInt( 1, 2345 );
stmt->setString( 2, "123.123.123.123" );
stmt->setUInt( 3, 3306 );
CharacterDatabase.execute( stmt );
g_charaDb.execute( stmt );
//stmt->setUInt( 1, 245 );
//stmt->setString( 2, "12.12.12.12" );
//stmt->setUInt( 3, 3306 );
//CharacterDatabase.execute( stmt );
//try
//{
try
{
// // bunch of test cases for db wrapper
// Mysql::MySqlBase base;
// g_log.info( base.getVersionInfo() );
Mysql::MySqlBase base;
g_log.info( base.getVersionInfo() );
// Mysql::optionMap options;
// options[ MYSQL_OPT_RECONNECT ] = "1";
Mysql::optionMap options;
options[ MYSQL_OPT_RECONNECT ] = "1";
// boost::scoped_ptr< Mysql::Connection > con( base.connect( "127.0.0.1", "root", "", options, 3306 ) );
boost::scoped_ptr< Mysql::Connection > con( base.connect( "127.0.0.1", "root", "", options, 3306 ) );
// if( con->getAutoCommit() )
// g_log.info( "autocommit active" );
@ -236,7 +236,7 @@ bool Core::ServerZone::loadSettings( int32_t argc, char* argv[] )
// if( con->getAutoCommit() )
// g_log.info( "autocommit active" );
// con->setSchema( "sapphire" );
con->setSchema( "sapphire" );
// boost::scoped_ptr< Mysql::Statement > stmt( con->createStatement() );
// bool t1 = stmt->execute( "DELETE FROM zoneservers WHERE id = 101" );
@ -274,10 +274,6 @@ bool Core::ServerZone::loadSettings( int32_t argc, char* argv[] )
// auto blob = res1->getBlobVector( "Customize" );
// }
// boost::scoped_ptr< Mysql::PreparedStatement > pstmt2( con->prepareStatement( "DELETE FROM zoneservers WHERE id = ?" ) );
// pstmt2->setInt( 1, 1021 );
// pstmt2->execute();
// pstmt2->setInt( 1, 1001 );
// pstmt2->execute();
@ -299,11 +295,11 @@ bool Core::ServerZone::loadSettings( int32_t argc, char* argv[] )
// pstmt->setInt( 1, 1001 );
// pstmt->execute();
//}
//catch( std::runtime_error e )
//{
// g_log.error( e.what() );
//}
}
catch( std::runtime_error e )
{
g_log.error( e.what() );
}
Db::DatabaseParams params;