1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-27 06:47:45 +00:00

Updated a number of queries to use new system

This commit is contained in:
Mordred 2017-10-07 23:10:13 +02:00
parent 292cd2d412
commit 7e2770a536
19 changed files with 280 additions and 278 deletions

@ -1 +1 @@
Subproject commit 71e7fc3744abc424c52413f579d60e1916594532 Subproject commit c71860d79596a93e5668169ac3f0309397c7218c

View file

@ -5,7 +5,7 @@ Core::Db::CharaDbConnection::CharaDbConnection( ConnectionInfo& connInfo ) : DbC
{ {
} }
Core::Db::CharaDbConnection::CharaDbConnection( Core::LockedWaitQueue< Operation * >* q, Core::Db::CharaDbConnection::CharaDbConnection( Core::LockedWaitQueue< boost::shared_ptr< Operation > >* q,
ConnectionInfo& connInfo) : DbConnection( q, connInfo ) ConnectionInfo& connInfo) : DbConnection( q, connInfo )
{ {
} }
@ -21,23 +21,37 @@ void Core::Db::CharaDbConnection::doPrepareStatements()
prepareStatement( CHAR_INS_TEST, "INSERT INTO zoneservers ( id, ip, port ) VALUES ( ?, ?, ?);", CONNECTION_BOTH ); 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, " prepareStatement( CHAR_SEL_LOAD, "SELECT ContentId, Name, Hp, Mp, Tp, Gp, Mode, Mount, InvincibleGM, Voice, "
"c.Pos_0_0, c.Pos_0_1, c.Pos_0_2, c.Pos_0_3, c.FirstLogin, " "Customize, ModelMainWeapon, ModelSubWeapon, ModelSystemWeapon, "
"c.Customize, c.ModelMainWeapon, c.ModelSubWeapon, c.ModelEquip, " "ModelEquip, EmoteModeType, FirstLoginTime, Language, IsNewGame, "
"cd.GuardianDeity, cd.BirthDay, cd.BirthMonth, cd.Status, cd.Class, " "IsNewAdventurer, TerritoryType, TerritoryId, PosX, PosY, PosZ, PosR, "
"cd.Homepoint, cd.HowTo, c.ContentId, c.Voice, cd.QuestCompleteFlags, " "OTerritoryType, OTerritoryId, OPosX, OPosY, OPosZ, OPosR, GuardianDeity, "
"cd.QuestTracking, c.IsNewGame, cd.Aetheryte, cd.unlocks, cd.Discovery, " "BirthDay, BirthMonth, Class, Status, TotalPlayTime, FirstClass, HomePoint, "
"cd.StartTown, cd.TotalPlayTime, c.IsNewAdventurer, cd.GrandCompany, " "FavoritePoint, RestPoint, StartTown, ActiveTitle, TitleList, Achievement, "
"cd.GrandCompanyRank, cd.CFPenaltyUntil, cd.OpeningSequence, cd.GMRank " "Aetheryte, HowTo, Minions, Mounts, EquippedMannequin, ConfigFlags, "
"FROM charabase AS c " "QuestCompleteFlags, OpeningSequence, QuestTracking, GrandCompany, "
" INNER JOIN charadetail AS cd " "GrandCompanyRank, Discovery, GMRank, Unlocks, CFPenaltyUntil "
" ON c.CharacterId = cd.CharacterId " "FROM charainfo WHERE CharacterId = ?;", CONNECTION_SYNCH );
"WHERE c.CharacterId = ?;", CONNECTION_SYNCH );
prepareStatement( CHAR_SEL_LOAD_MINIMAL, "SELECT Name, Customize, ModelEquip, TerritoryId, GuardianDeity, "
"Class, ContentId, BirthDay, BirthMonth "
"FROM charainfo WHERE CharacterId = ?;", CONNECTION_SYNCH );
prepareStatement( CHAR_SEL_LOAD_CLASSINFO, "SELECT * FROM characlass WHERE CharacterId = ?;", CONNECTION_SYNCH ); prepareStatement( CHAR_SEL_LOAD_CLASSINFO, "SELECT * FROM characlass WHERE CharacterId = ?;", CONNECTION_SYNCH );
prepareStatement( CHAR_SEL_LOAD_SEARCHINFO, "SELECT * FROM charainfosearch WHERE CharacterId = ?;", CONNECTION_SYNCH ); prepareStatement( CHAR_SEL_LOAD_SEARCHINFO, "SELECT * FROM charainfosearch WHERE CharacterId = ?;", CONNECTION_SYNCH );
prepareStatement( CHAR_SEL_LOAD_QUESTINFO, "SELECT * FROM charaquest WHERE CharacterId = ?;", CONNECTION_SYNCH ); prepareStatement( CHAR_SEL_LOAD_QUESTINFO, "SELECT * FROM charaquest WHERE CharacterId = ?;", CONNECTION_SYNCH );
prepareStatement( CHAR_INS_CHARINFO, "INSERT INTO charainfo (AccountId, CharacterId, ContentId, Name, Hp, Mp, "
"Customize, Voice, IsNewGame, TerritoryId, PosX, PosY, PosZ, PosR, ModelEquip, "
"IsNewAdventurer, GuardianDeity, Birthday, BirthMonth, Class, Status, FirstClass, "
"HomePoint, StartTown, Discovery, HowTo, QuestCompleteFlags, Unlocks, QuestTracking, "
"Aetheryte, GMRank, UPDATE_DATE ) "
"VALUES ( ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW() );",
CONNECTION_SYNCH );

View file

@ -12,9 +12,11 @@ class DbConnectionInfo;
enum CharaDbStatements : uint32_t enum CharaDbStatements : uint32_t
{ {
CHAR_SEL_LOAD, CHAR_SEL_LOAD,
CHAR_SEL_LOAD_MINIMAL,
CHAR_SEL_LOAD_CLASSINFO, CHAR_SEL_LOAD_CLASSINFO,
CHAR_SEL_LOAD_SEARCHINFO, CHAR_SEL_LOAD_SEARCHINFO,
CHAR_SEL_LOAD_QUESTINFO, CHAR_SEL_LOAD_QUESTINFO,
CHAR_INS_CHARINFO,
CHAR_INS_TEST, CHAR_INS_TEST,
MAX_STATEMENTS MAX_STATEMENTS
@ -26,7 +28,7 @@ public:
typedef CharaDbStatements Statements; typedef CharaDbStatements Statements;
CharaDbConnection( ConnectionInfo& connInfo ); CharaDbConnection( ConnectionInfo& connInfo );
CharaDbConnection( Core::LockedWaitQueue< Operation* >* q, ConnectionInfo &connInfo ); CharaDbConnection( Core::LockedWaitQueue< boost::shared_ptr< Operation > >* q, ConnectionInfo &connInfo );
~CharaDbConnection(); ~CharaDbConnection();

View file

@ -4,6 +4,7 @@
#include "src/servers/Server_Common/Logging/Logger.h" #include "src/servers/Server_Common/Logging/Logger.h"
#include "PreparedStatement.h" #include "PreparedStatement.h"
#include <boost/make_shared.hpp>
extern Core::Logger g_log; extern Core::Logger g_log;
@ -19,7 +20,8 @@ Core::Db::DbConnection::DbConnection( ConnectionInfo &connInfo ) :
} }
Core::Db::DbConnection::DbConnection( Core::LockedWaitQueue<Operation *>* queue, Core::Db::ConnectionInfo& connInfo ) : Core::Db::DbConnection::DbConnection( Core::LockedWaitQueue< boost::shared_ptr< Operation > >* queue,
Core::Db::ConnectionInfo& connInfo ) :
m_reconnecting( false ), m_reconnecting( false ),
m_prepareError( false ), m_prepareError( false ),
m_queue( queue ), m_queue( queue ),
@ -27,7 +29,7 @@ Core::Db::DbConnection::DbConnection( Core::LockedWaitQueue<Operation *>* queue,
m_connectionInfo( connInfo ), m_connectionInfo( connInfo ),
m_connectionFlags( CONNECTION_ASYNC ) m_connectionFlags( CONNECTION_ASYNC )
{ {
m_worker = std::unique_ptr< DbWorker >( new DbWorker( m_queue, this ) ); m_worker = boost::make_shared< DbWorker >( m_queue, this );
} }
Core::Db::DbConnection::~DbConnection() Core::Db::DbConnection::~DbConnection()
@ -51,18 +53,16 @@ void Core::Db::DbConnection::close()
uint32_t Core::Db::DbConnection::open() uint32_t Core::Db::DbConnection::open()
{ {
Mysql::MySqlBase base; boost::shared_ptr< Mysql::MySqlBase > base( new Mysql::MySqlBase() );
Mysql::optionMap options; Mysql::optionMap options;
options[ MYSQL_OPT_RECONNECT ] = "1"; options[ MYSQL_OPT_RECONNECT ] = "1";
options[ MYSQL_SET_CHARSET_NAME ] = "utf8"; options[ MYSQL_SET_CHARSET_NAME ] = "utf8";
try try
{ {
m_pConnection = std::shared_ptr< Mysql::Connection >( base.connect( m_connectionInfo.host, m_pConnection = base->connect( m_connectionInfo.host, m_connectionInfo.user, m_connectionInfo.password,
m_connectionInfo.user, options, m_connectionInfo.port );
m_connectionInfo.password,
options,
m_connectionInfo.port ) );
m_pConnection->setSchema( m_connectionInfo.database ); m_pConnection->setSchema( m_connectionInfo.database );
} }
catch( std::runtime_error& e ) catch( std::runtime_error& e )
@ -113,7 +113,7 @@ bool Core::Db::DbConnection::execute( const std::string& sql )
{ {
try try
{ {
Mysql::Statement* stmt( m_pConnection->createStatement() ); auto stmt = m_pConnection->createStatement();
bool result = stmt->execute( sql ); bool result = stmt->execute( sql );
return result; return result;
} }
@ -124,12 +124,12 @@ bool Core::Db::DbConnection::execute( const std::string& sql )
} }
} }
Mysql::ResultSet *Core::Db::DbConnection::query( const std::string& sql ) boost::shared_ptr< Mysql::ResultSet > Core::Db::DbConnection::query( const std::string& sql )
{ {
try try
{ {
Mysql::Statement* stmt( m_pConnection->createStatement() ); auto stmt = m_pConnection->createStatement();
Mysql::ResultSet* result = stmt->executeQuery( sql ); auto result = stmt->executeQuery( sql );
return result; return result;
} }
catch( std::runtime_error& e ) catch( std::runtime_error& e )
@ -140,15 +140,15 @@ Mysql::ResultSet *Core::Db::DbConnection::query( const std::string& sql )
} }
Mysql::ResultSet* Core::Db::DbConnection::query( Core::Db::PreparedStatement* stmt ) boost::shared_ptr< Mysql::ResultSet > Core::Db::DbConnection::query( boost::shared_ptr< Core::Db::PreparedStatement > stmt )
{ {
Mysql::ResultSet* res = nullptr; boost::shared_ptr< Mysql::ResultSet > res( nullptr );
if( !stmt ) if( !stmt )
return nullptr; return nullptr;
uint32_t index = stmt->getIndex(); uint32_t index = stmt->getIndex();
Mysql::PreparedStatement* pStmt = getPreparedStatement( index ); auto pStmt = getPreparedStatement( index );
if( !pStmt ) if( !pStmt )
return nullptr; return nullptr;
@ -167,14 +167,14 @@ Mysql::ResultSet* Core::Db::DbConnection::query( Core::Db::PreparedStatement* st
} }
bool Core::Db::DbConnection::execute( Core::Db::PreparedStatement* stmt ) bool Core::Db::DbConnection::execute( boost::shared_ptr< Core::Db::PreparedStatement > stmt )
{ {
if( !stmt ) if( !stmt )
return false; return false;
uint32_t index = stmt->getIndex(); uint32_t index = stmt->getIndex();
Mysql::PreparedStatement* pStmt = getPreparedStatement( index ); auto pStmt = getPreparedStatement( index );
if( !pStmt ) if( !pStmt )
return false; return false;
@ -192,10 +192,10 @@ bool Core::Db::DbConnection::execute( Core::Db::PreparedStatement* stmt )
} }
} }
Mysql::PreparedStatement* Core::Db::DbConnection::getPreparedStatement( uint32_t index ) boost::shared_ptr< Mysql::PreparedStatement > Core::Db::DbConnection::getPreparedStatement( uint32_t index )
{ {
assert( index < m_stmts.size() ); assert( index < m_stmts.size() );
Mysql::PreparedStatement* ret = m_stmts[index].get(); auto ret = m_stmts[index];
if( !ret ) if( !ret )
nullptr; nullptr;
@ -215,7 +215,7 @@ void Core::Db::DbConnection::prepareStatement( uint32_t index, const std::string
return; return;
} }
Mysql::PreparedStatement* pStmt = nullptr; boost::shared_ptr< Mysql::PreparedStatement > pStmt( nullptr );
try try
{ {
@ -227,7 +227,7 @@ void Core::Db::DbConnection::prepareStatement( uint32_t index, const std::string
m_prepareError = true; m_prepareError = true;
} }
m_stmts[index] = std::unique_ptr< Mysql::PreparedStatement >( pStmt ); m_stmts[index] = boost::shared_ptr< Mysql::PreparedStatement >( pStmt );
} }

View file

@ -9,6 +9,8 @@
#include "src/servers/Server_Common/Util/LockedWaitQueue.h" #include "src/servers/Server_Common/Util/LockedWaitQueue.h"
#include <Server_Common/Util/LockedWaitQueue.h> #include <Server_Common/Util/LockedWaitQueue.h>
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <boost/move/unique_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
namespace Mysql namespace Mysql
{ {
@ -49,13 +51,13 @@ namespace Db
typedef std::map< uint32_t, std::pair< std::string, ConnectionFlags > > PreparedStatementMap; typedef std::map< uint32_t, std::pair< std::string, ConnectionFlags > > PreparedStatementMap;
class DbConnection class DbConnection : public boost::enable_shared_from_this< DbConnection >
{ {
public: public:
// Constructor for synchronous connections. // Constructor for synchronous connections.
DbConnection( ConnectionInfo& connInfo ); DbConnection( ConnectionInfo& connInfo );
// Constructor for asynchronous connections. // Constructor for asynchronous connections.
DbConnection( Core::LockedWaitQueue< Operation* >* queue, ConnectionInfo& connInfo ); DbConnection( Core::LockedWaitQueue< boost::shared_ptr< Operation > >* queue, ConnectionInfo& connInfo );
virtual ~DbConnection(); virtual ~DbConnection();
virtual uint32_t open(); virtual uint32_t open();
@ -64,9 +66,9 @@ namespace Db
bool prepareStatements(); bool prepareStatements();
bool execute( const std::string& sql ); bool execute( const std::string& sql );
bool execute( PreparedStatement* stmt ); bool execute( boost::shared_ptr< PreparedStatement > stmt );
Mysql::ResultSet* query( const std::string& sql ); boost::shared_ptr< Mysql::ResultSet > query( const std::string& sql );
Mysql::ResultSet* query( PreparedStatement* stmt ); boost::shared_ptr< Mysql::ResultSet > query( boost::shared_ptr< PreparedStatement > stmt );
void beginTransaction(); void beginTransaction();
void rollbackTransaction(); void rollbackTransaction();
@ -79,22 +81,22 @@ namespace Db
void unlock(); void unlock();
std::shared_ptr< Mysql::Connection > getConnection() { return m_pConnection; } boost::shared_ptr< Mysql::Connection > getConnection() { return m_pConnection; }
Mysql::PreparedStatement* getPreparedStatement( uint32_t index ); boost::shared_ptr< Mysql::PreparedStatement > getPreparedStatement( uint32_t index );
void prepareStatement( uint32_t index, const std::string& sql, ConnectionFlags flags ); void prepareStatement( uint32_t index, const std::string& sql, ConnectionFlags flags );
virtual void doPrepareStatements() = 0; virtual void doPrepareStatements() = 0;
protected: protected:
std::vector< std::unique_ptr< Mysql::PreparedStatement > > m_stmts; std::vector< boost::shared_ptr< Mysql::PreparedStatement > > m_stmts;
PreparedStatementMap m_queries; PreparedStatementMap m_queries;
bool m_reconnecting; bool m_reconnecting;
bool m_prepareError; bool m_prepareError;
private: private:
LockedWaitQueue< Operation* >* m_queue; LockedWaitQueue< boost::shared_ptr< Operation > >* m_queue;
std::unique_ptr< DbWorker > m_worker; boost::shared_ptr< DbWorker > m_worker;
std::shared_ptr< Mysql::Connection > m_pConnection; boost::shared_ptr< Mysql::Connection > m_pConnection;
ConnectionInfo& m_connectionInfo; ConnectionInfo& m_connectionInfo;
ConnectionFlags m_connectionFlags; ConnectionFlags m_connectionFlags;
std::mutex m_mutex; std::mutex m_mutex;

View file

@ -2,7 +2,7 @@
#include "Operation.h" #include "Operation.h"
#include <Server_Common/Util/LockedWaitQueue.h> #include <Server_Common/Util/LockedWaitQueue.h>
Core::Db::DbWorker::DbWorker( Core::LockedWaitQueue< Operation* >* newQueue, DbConnection* pConn ) Core::Db::DbWorker::DbWorker( Core::LockedWaitQueue< boost::shared_ptr< Operation > >* newQueue, DbConnection* pConn )
{ {
m_pConn = pConn; m_pConn = pConn;
m_queue = newQueue; m_queue = newQueue;
@ -24,7 +24,7 @@ void Core::Db::DbWorker::workerThread()
while( true ) while( true )
{ {
Operation* operation = nullptr; boost::shared_ptr< Operation > operation = nullptr;
m_queue->waitAndPop( operation ); m_queue->waitAndPop( operation );
@ -33,7 +33,5 @@ void Core::Db::DbWorker::workerThread()
operation->setConnection( m_pConn ); operation->setConnection( m_pConn );
operation->call(); operation->call();
delete operation;
} }
} }

View file

@ -4,6 +4,7 @@
#include <atomic> #include <atomic>
#include <thread> #include <thread>
#include <Server_Common/Util/LockedWaitQueue.h> #include <Server_Common/Util/LockedWaitQueue.h>
#include <boost/shared_ptr.hpp>
namespace Core namespace Core
{ {
@ -15,11 +16,11 @@ namespace Db
class DbWorker class DbWorker
{ {
public: public:
DbWorker( LockedWaitQueue< Operation* >* newQueue, DbConnection* connection ); DbWorker( LockedWaitQueue< boost::shared_ptr< Operation > >* newQueue, DbConnection* connection );
~DbWorker(); ~DbWorker();
private: private:
LockedWaitQueue< Operation* >* m_queue; LockedWaitQueue< boost::shared_ptr< Operation > >* m_queue;
DbConnection* m_pConn; DbConnection* m_pConn;
void workerThread(); void workerThread();

View file

@ -5,6 +5,7 @@
#include "StatementTask.h" #include "StatementTask.h"
#include "Operation.h" #include "Operation.h"
#include "CharaDbConnection.h" #include "CharaDbConnection.h"
#include <boost/make_shared.hpp>
#include <Server_Common/Logging/Logger.h> #include <Server_Common/Logging/Logger.h>
extern Core::Logger g_log; extern Core::Logger g_log;
@ -20,7 +21,7 @@ class PingOperation : public Core::Db::Operation
template< class T > template< class T >
Core::Db::DbWorkerPool<T>::DbWorkerPool() Core::Db::DbWorkerPool<T>::DbWorkerPool()
: m_queue( new Core::LockedWaitQueue< Operation* >() ), : m_queue( new Core::LockedWaitQueue< boost::shared_ptr< Operation > >() ),
m_asyncThreads( 0 ), m_asyncThreads( 0 ),
m_synchThreads( 0 ) m_synchThreads( 0 )
{ {
@ -33,9 +34,9 @@ Core::Db::DbWorkerPool< T >::~DbWorkerPool()
} }
template< class T > template< class T >
void Core::Db::DbWorkerPool<T>::setConnectionInfo( const ConnectionInfo& info, void Core::Db::DbWorkerPool< T >::setConnectionInfo( const ConnectionInfo& info,
uint8_t asyncThreads, uint8_t asyncThreads,
uint8_t synchThreads) uint8_t synchThreads)
{ {
m_connectionInfo = info; m_connectionInfo = info;
m_asyncThreads = asyncThreads; m_asyncThreads = asyncThreads;
@ -96,31 +97,31 @@ bool Core::Db::DbWorkerPool<T>::prepareStatements()
} }
template< class T > template< class T >
Mysql::ResultSet* Core::Db::DbWorkerPool<T>::query( const std::string& sql, T* connection ) boost::shared_ptr< Mysql::ResultSet > Core::Db::DbWorkerPool< T >::query( const std::string& sql, boost::shared_ptr< T > connection )
{ {
if( !connection ) if( !connection )
connection = getFreeConnection(); connection = getFreeConnection();
Mysql::ResultSet* result = connection->query( sql ); boost::shared_ptr< Mysql::ResultSet > result = connection->query( sql );
connection->unlock(); connection->unlock();
return result; return result;
} }
template< class T > template< class T >
Mysql::PreparedResultSet* Core::Db::DbWorkerPool<T>::query( PreparedStatement* stmt ) boost::shared_ptr< Mysql::PreparedResultSet > Core::Db::DbWorkerPool< T >::query( boost::shared_ptr< PreparedStatement > stmt )
{ {
auto connection = getFreeConnection(); auto connection = getFreeConnection();
auto ret = dynamic_cast< Mysql::PreparedResultSet* >( connection->query( stmt ) ); auto ret = boost::static_pointer_cast< Mysql::PreparedResultSet >( connection->query( stmt ) );
connection->unlock(); connection->unlock();
return ret; return ret;
} }
template< class T > template< class T >
Core::Db::PreparedStatement* Core::Db::DbWorkerPool< T >::getPreparedStatement( PreparedStatementIndex index ) boost::shared_ptr< Core::Db::PreparedStatement > Core::Db::DbWorkerPool< T >::getPreparedStatement( PreparedStatementIndex index )
{ {
return new PreparedStatement( index ); return boost::make_shared< PreparedStatement >( index );
} }
template< class T > template< class T >
@ -149,7 +150,7 @@ void Core::Db::DbWorkerPool< T >::keepAlive()
const auto count = m_connections[IDX_ASYNC].size(); const auto count = m_connections[IDX_ASYNC].size();
for( uint8_t i = 0; i < count; ++i ) for( uint8_t i = 0; i < count; ++i )
enqueue( new PingOperation ); enqueue( boost::make_shared< PingOperation >() );
} }
template< class T > template< class T >
@ -162,11 +163,11 @@ uint32_t Core::Db::DbWorkerPool< T >::openConnections( InternalIndex type, uint8
switch (type) switch (type)
{ {
case IDX_ASYNC: case IDX_ASYNC:
return std::unique_ptr<T>( new T( m_queue.get(), m_connectionInfo ) ); return boost::make_shared< T >( m_queue.get(), m_connectionInfo );
case IDX_SYNCH: case IDX_SYNCH:
return std::unique_ptr<T>( new T( m_connectionInfo ) ); return boost::make_shared< T >( m_connectionInfo );
default: default:
return std::unique_ptr<T>(); return boost::shared_ptr< T >( nullptr );
} }
}(); }();
@ -176,10 +177,7 @@ uint32_t Core::Db::DbWorkerPool< T >::openConnections( InternalIndex type, uint8
m_connections[type].clear(); m_connections[type].clear();
return error; return error;
} }
else m_connections[type].push_back( connection );
{
m_connections[type].push_back( std::move( connection ) );
}
} }
return 0; return 0;
@ -188,29 +186,29 @@ uint32_t Core::Db::DbWorkerPool< T >::openConnections( InternalIndex type, uint8
template< class T > template< class T >
unsigned long Core::Db::DbWorkerPool< T >::escapeString( char *to, const char *from, unsigned long length ) unsigned long Core::Db::DbWorkerPool< T >::escapeString( char *to, const char *from, unsigned long length )
{ {
if (!to || !from || !length) if( !to || !from || !length )
return 0; return 0;
return mysql_real_escape_string( return mysql_real_escape_string(
m_connections[IDX_SYNCH].front()->getConnection()->getRawCon(), to, from, length); m_connections[IDX_SYNCH].front()->getConnection()->getRawCon(), to, from, length );
} }
template< class T > template< class T >
void Core::Db::DbWorkerPool< T >::enqueue( Operation* op ) void Core::Db::DbWorkerPool< T >::enqueue( boost::shared_ptr< Operation > op )
{ {
m_queue->push( op ); m_queue->push( op );
} }
template< class T > template< class T >
T* Core::Db::DbWorkerPool< T >::getFreeConnection() boost::shared_ptr< T > Core::Db::DbWorkerPool< T >::getFreeConnection()
{ {
uint8_t i = 0; uint8_t i = 0;
const auto numCons = m_connections[IDX_SYNCH].size(); const auto numCons = m_connections[IDX_SYNCH].size();
T* connection = nullptr; boost::shared_ptr< T > connection = nullptr;
while( true ) while( true )
{ {
connection = m_connections[IDX_SYNCH][i++ % numCons].get(); connection = m_connections[IDX_SYNCH][i++ % numCons];
if (connection->lockIfReady()) if (connection->lockIfReady())
break; break;
@ -228,34 +226,31 @@ const std::string& Core::Db::DbWorkerPool< T >::getDatabaseName() const
template< class T > template< class T >
void Core::Db::DbWorkerPool< T >::execute( const std::string& sql ) void Core::Db::DbWorkerPool< T >::execute( const std::string& sql )
{ {
StatementTask* task = new StatementTask( sql ); auto task = boost::make_shared< StatementTask >( sql );
enqueue( task ); enqueue( task );
} }
template< class T > template< class T >
void Core::Db::DbWorkerPool< T >::execute( PreparedStatement* stmt ) void Core::Db::DbWorkerPool< T >::execute( boost::shared_ptr< PreparedStatement > stmt )
{ {
PreparedStatementTask* task = new PreparedStatementTask(stmt); auto task = boost::make_shared< PreparedStatementTask >( stmt );
enqueue( task ); enqueue( task );
} }
template< class T > template< class T >
void Core::Db::DbWorkerPool< T >::directExecute( const std::string& sql ) void Core::Db::DbWorkerPool< T >::directExecute( const std::string& sql )
{ {
T* connection = getFreeConnection(); auto connection = getFreeConnection();
connection->execute( sql ); connection->execute( sql );
connection->unlock(); connection->unlock();
} }
template< class T > template< class T >
void Core::Db::DbWorkerPool< T >::directExecute( PreparedStatement* stmt ) void Core::Db::DbWorkerPool< T >::directExecute( boost::shared_ptr< PreparedStatement > stmt )
{ {
T* connection = getFreeConnection(); auto connection = getFreeConnection();
connection->execute( stmt ); connection->execute( stmt );
connection->unlock(); connection->unlock();
//! Delete proxy-class. Not needed anymore
delete stmt;
} }
/* /*
@ -278,7 +273,4 @@ void DatabaseWorkerPool<T>::ExecuteOrAppend(SQLTransaction& trans, PreparedState
} }
*/ */
template class Core::Db::DbWorkerPool< Core::Db::CharaDbConnection >; template class Core::Db::DbWorkerPool< Core::Db::CharaDbConnection >;
//template class TC_DATABASE_API DatabaseWorkerPool<LoginDatabaseConnection>;
//template class TC_DATABASE_API DatabaseWorkerPool<WorldDatabaseConnection>;
//template class TC_DATABASE_API DatabaseWorkerPool<CharacterDatabaseConnection>;

View file

@ -49,17 +49,17 @@ public:
// Async execution // Async execution
void execute( const std::string& sql ); void execute( const std::string& sql );
void execute( PreparedStatement* stmt ); void execute( boost::shared_ptr< PreparedStatement > stmt );
// Sync execution // Sync execution
void directExecute( const std::string& sql ); void directExecute( const std::string& sql );
void directExecute( PreparedStatement* stmt ); void directExecute( boost::shared_ptr< PreparedStatement > stmt );
Mysql::ResultSet* query( const std::string& sql, T* connection = nullptr ); boost::shared_ptr< Mysql::ResultSet > query( const std::string& sql, boost::shared_ptr< T > connection = nullptr );
Mysql::PreparedResultSet* query( PreparedStatement* stmt ); boost::shared_ptr< Mysql::PreparedResultSet > query( boost::shared_ptr< PreparedStatement > stmt );
typedef typename T::Statements PreparedStatementIndex; typedef typename T::Statements PreparedStatementIndex;
PreparedStatement* getPreparedStatement( PreparedStatementIndex index ); boost::shared_ptr< PreparedStatement > getPreparedStatement( PreparedStatementIndex index );
void escapeString( std::string& str ); void escapeString( std::string& str );
@ -70,14 +70,14 @@ private:
unsigned long escapeString( char *to, const char *from, unsigned long length ); unsigned long escapeString( char *to, const char *from, unsigned long length );
void enqueue( Operation* op ); void enqueue( boost::shared_ptr< Operation > op );
T* getFreeConnection(); boost::shared_ptr< T > getFreeConnection();
const std::string& getDatabaseName() const; const std::string& getDatabaseName() const;
std::unique_ptr< Core::LockedWaitQueue< Operation* > > m_queue; std::unique_ptr< Core::LockedWaitQueue< boost::shared_ptr< Operation > > > m_queue;
std::array< std::vector< std::unique_ptr< T > >, IDX_SIZE > m_connections; std::array< std::vector< boost::shared_ptr< T > >, IDX_SIZE > m_connections;
ConnectionInfo m_connectionInfo; ConnectionInfo m_connectionInfo;
uint8_t m_asyncThreads; uint8_t m_asyncThreads;
uint8_t m_synchThreads; uint8_t m_synchThreads;

View file

@ -44,10 +44,12 @@ void Core::Db::PreparedStatement::bindParameters()
break; break;
case TYPE_BINARY: case TYPE_BINARY:
{ {
std::stringstream is; std::stringstream *is = new std::stringstream;
is.rdbuf()->pubsetbuf( reinterpret_cast< char* >( &m_statementData[i].binary[0] ),
m_statementData[i].binary.size() ); for( auto entry : m_statementData[i].binary )
m_stmt->setBlob( i, &is ); is->rdbuf()->sputc( static_cast< char > ( entry ) );
m_stmt->setBlob( i, is );
} }
break; break;
case TYPE_NULL: case TYPE_NULL:
@ -97,7 +99,7 @@ void Core::Db::PreparedStatement::setInt( uint8_t index, int32_t value )
void Core::Db::PreparedStatement::setInt64( uint8_t index, int64_t value ) void Core::Db::PreparedStatement::setInt64( uint8_t index, int64_t value )
{ {
if( index >= m_statementData.size() ) if( index >= m_statementData.size() )
m_statementData.resize(index+1); m_statementData.resize( index + 1);
m_statementData[index].data.i64 = value; m_statementData[index].data.i64 = value;
m_statementData[index].type = TYPE_I64; m_statementData[index].type = TYPE_I64;
@ -144,7 +146,7 @@ uint32_t Core::Db::PreparedStatement::getIndex() const
return m_index; return m_index;
} }
void Core::Db::PreparedStatement::setMysqlPS( Mysql::PreparedStatement* pStmt ) void Core::Db::PreparedStatement::setMysqlPS( boost::shared_ptr< Mysql::PreparedStatement> pStmt )
{ {
m_stmt = pStmt; m_stmt = pStmt;
} }

View file

@ -3,6 +3,7 @@
#include <stdint.h> #include <stdint.h>
#include <vector> #include <vector>
#include <string> #include <string>
#include <boost/shared_ptr.hpp>
#include "Operation.h" #include "Operation.h"
namespace Mysql namespace Mysql
@ -61,12 +62,12 @@ namespace Db
void setNull( uint8_t index ); void setNull( uint8_t index );
uint32_t getIndex() const; uint32_t getIndex() const;
void setMysqlPS( Mysql::PreparedStatement* pStmt ); void setMysqlPS( boost::shared_ptr< Mysql::PreparedStatement > pStmt );
void bindParameters(); void bindParameters();
protected: protected:
Mysql::PreparedStatement* m_stmt; boost::shared_ptr< Mysql::PreparedStatement > m_stmt;
uint32_t m_index; uint32_t m_index;
std::vector< PreparedStatementData > m_statementData; std::vector< PreparedStatementData > m_statementData;

View file

@ -39,7 +39,7 @@ bool Core::Db::StatementTask::execute()
Core::Db::PreparedStatementTask::PreparedStatementTask( Core::Db::PreparedStatement *stmt, bool async ) : Core::Db::PreparedStatementTask::PreparedStatementTask( boost::shared_ptr< Core::Db::PreparedStatement > stmt, bool async ) :
m_stmt(stmt) m_stmt(stmt)
//, m_result(nullptr) //, m_result(nullptr)
{ {
@ -48,7 +48,6 @@ Core::Db::PreparedStatementTask::PreparedStatementTask( Core::Db::PreparedStatem
Core::Db::PreparedStatementTask::~PreparedStatementTask() Core::Db::PreparedStatementTask::~PreparedStatementTask()
{ {
delete m_stmt;
//if (m_has_result && m_result != nullptr) //if (m_has_result && m_result != nullptr)
// delete m_result; // delete m_result;
} }

View file

@ -2,6 +2,7 @@
#define SAPPHIRE_STATEMENTTASK_H #define SAPPHIRE_STATEMENTTASK_H
#include <string> #include <string>
#include <boost/shared_ptr.hpp>
#include "Operation.h" #include "Operation.h"
namespace Core namespace Core
@ -31,18 +32,17 @@ namespace Db
// QueryResultPromise *m_result; // QueryResultPromise *m_result;
}; };
//- Lower-level class, enqueuable operation
class PreparedStatementTask : public Operation class PreparedStatementTask : public Operation
{ {
public: public:
PreparedStatementTask( PreparedStatement* stmt, bool async = false); PreparedStatementTask( boost::shared_ptr< PreparedStatement > stmt, bool async = false);
~PreparedStatementTask(); ~PreparedStatementTask();
bool execute() override; bool execute() override;
//PreparedQueryResultFuture getFuture() { return m_result->get_future(); } //PreparedQueryResultFuture getFuture() { return m_result->get_future(); }
protected: protected:
PreparedStatement* m_stmt; boost::shared_ptr< PreparedStatement > m_stmt;
bool m_hasResult; bool m_hasResult;
//PreparedQueryResultPromise* m_result; //PreparedQueryResultPromise* m_result;
}; };

View file

@ -1,13 +1,19 @@
#include "PlayerMinimal.h" #include "PlayerMinimal.h"
//#include "Core/Server_Game/CServerGame.h" #include <Server_Common/Util/Util.h>
#include <src/servers/Server_Common/Util/Util.h> #include <Server_Common/Database/Database.h>
#include <src/servers/Server_Common/Database/Database.h> #include <Server_Common/Common.h>
#include <src/servers/Server_Common/Common.h> #include <Server_Common/Exd/ExdData.h>
#include <src/servers/Server_Common/Exd/ExdData.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 "src/libraries/sapphire/mysqlConnector/MySqlConnector.h"
extern Core::Db::Database g_database; extern Core::Db::Database g_database;
extern Core::Db::DbWorkerPool< Core::Db::CharaDbConnection > g_charaDb;
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdData g_exdData;
namespace Core { namespace Core {
@ -15,7 +21,7 @@ namespace Core {
using namespace Common; using namespace Common;
// player constructor // player constructor
PlayerMinimal::PlayerMinimal( void ) : m_iD( 0 ) PlayerMinimal::PlayerMinimal( void ) : m_id( 0 )
{ {
@ -32,46 +38,37 @@ namespace Core {
void PlayerMinimal::load( uint32_t charId ) void PlayerMinimal::load( uint32_t charId )
{ {
boost::shared_ptr<Db::QueryResult> pQR = g_database.query( "SELECT c.Name, " Core::Db::PreparedStmtScopedPtr stmt( g_charaDb.getPreparedStatement(
" c.Customize, " Core::Db::CharaDbStatements::CHAR_SEL_LOAD_MINIMAL ) );
" cpc.BirthDay, "
" cpc.BirthMonth, " stmt->setUInt( 1, charId );
" cpc.GuardianDeity, " Mysql::PreparedResultSetScopedPtr res( g_charaDb.query( stmt.get() ) );
" cpc.Class, "
" c.ModelEquip, " if( !res->next() )
" c.ContentId, "
" c.PrimaryTerritoryId "
" FROM charabase AS c "
" INNER JOIN charadetail AS cpc "
" ON cpc.CharacterId = c.CharacterId "
" WHERE c.CharacterId = " + std::to_string( charId ) + ";" );
if( !pQR )
{
return; return;
}
m_iD = charId; m_id = charId;
Db::Field *field = pQR->fetch();
memset( m_name, 0, 32 ); memset( m_name, 0, 32 );
strcpy( m_name, field[0].getString().c_str() ); strcpy( m_name, res->getString( "Name" ).c_str() );
field[1].getBinary( (char*)m_look, 26 );
field[6].getBinary( (char*)m_modelEquip, 40 );
auto customize = res->getBlobVector( "Customize" );
memcpy( (char*)m_look, customize.data(), customize.size() );
for( int32_t i = 0; i < 26; i++ ) for( int32_t i = 0; i < 26; i++ )
{ {
m_lookMap[i] = m_look[i]; m_lookMap[i] = m_look[i];
} }
setBirthDay( field[2].get< int8_t >(), field[3].get< int8_t >() ); auto modelEquip = res->getBlobVector( "ModelEquip" );
m_guardianDeity = field[4].get< int8_t >(); memcpy( (char*)m_modelEquip, modelEquip.data(), modelEquip.size() );
m_class = field[5].get< int8_t >();
m_contentId = field[7].getUInt64();
m_zoneId = field[8].get< uint16_t >(); setBirthDay( res->getUInt8( "BirthDay" ), res->getUInt8( "BirthMonth" ) );
m_guardianDeity = res->getUInt8( "GuardianDeity" );
m_class = res->getUInt8( "Class" );
m_contentId = res->getUInt64( "ContentId" );
m_zoneId = res->getUInt8( "TerritoryId" );
auto pQR2 = g_database.query( "SELECT * FROM characlass WHERE CharacterId = " + std::to_string( charId ) + ";" ); auto pQR2 = g_database.query( "SELECT * FROM characlass WHERE CharacterId = " + std::to_string( charId ) + ";" );
@ -159,23 +156,17 @@ namespace Core {
void PlayerMinimal::saveAsNew() void PlayerMinimal::saveAsNew()
{ {
char customize[32]; std::vector< uint8_t > customize( 32 );
char howTo[32]; std::vector< uint8_t > howTo( 32 );
memset( howTo, 0, 32 ); std::vector< uint8_t > aetherytes( 12 );
std::vector< uint8_t > discovery( 411 );
std::vector< uint8_t > questComplete( 200 );
std::vector< uint8_t > unlocks( 64 );
std::vector< uint8_t > modelEquip( 40 );
std::vector< uint8_t > questTracking8(10);
std::vector< int16_t > questTracking = { -1, -1, -1, -1, -1 };
char aetherytes[12]; memcpy( questTracking8.data(), questTracking.data(), questTracking8.size() );
memset( aetherytes, 0, 12 );
char discovery[411];
memset( discovery, 0, 411 );
char questComplete[200];
memset( questComplete, 0, 200 );
char unlocks[64];
memset( unlocks, 0, 64 );
int16_t questTracking[5] = { -1, -1, -1, -1, -1 };
uint16_t size = static_cast< uint16_t >( m_lookMap.size() ); uint16_t size = static_cast< uint16_t >( m_lookMap.size() );
@ -186,6 +177,7 @@ namespace Core {
uint32_t equipModel[10]; uint32_t equipModel[10];
memset( equipModel, 0, 40 ); memset( equipModel, 0, 40 );
memcpy( modelEquip.data(), equipModel, modelEquip.size() );
uint32_t startZone; uint32_t startZone;
float x, y, z, o; float x, y, z, o;
@ -226,133 +218,114 @@ namespace Core {
break; break;
} }
g_database.execute( "INSERT INTO charabase " // "(AccountId, CharacterId, ContentId, Name, Hp, Mp, "
"(Hp, " // "Customize, Voice, IsNewGame, TerritoryId, PosX, PosY, PosZ, PosR, ModelEquip, "
" Mp, " // "IsNewAdventurer, GuardianDeity, Birthday, BirthMonth, Class, Status, FirstClass, "
" CharacterId, " // "HomePoint, StartTown, Discovery, HowTo, QuestCompleteFlags, Unlocks, QuestTracking, "
" ContentId, " // "Aetheryte, GMRank, UPDATE_DATE )
" Customize, "
" Name, "
" Voice, "
" FirstLogin, "
" IsNewGame, "
" PrimaryTerritoryId, "
" Pos_0_0, "
" Pos_0_1, "
" Pos_0_2, "
" Pos_0_3, "
" AccountId, "
" ModelEquip, "
" IsNewAdventurer, "
" UPDATE_DATE ) "
" VALUES (100, 100, " + std::to_string( m_iD ) + ", " + std::to_string( m_contentId ) + ", " +
" UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)customize, size ) ) + "'), " +
"'" + g_database.escapeString( std::string( m_name ) ) + "', " + std::to_string( m_voice ) + ", 1, 1, " +
std::to_string( startZone ) + ", " + std::to_string( x ) + ", " +
std::to_string( y ) + ", " + std::to_string( z ) + ", " + std::to_string( o ) + ", " +
std::to_string( m_accountId ) + ", UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)equipModel, 40 ) ) + "'), 1, NOW());" );
g_database.execute( "INSERT INTO charadetail " Core::Db::PreparedStatement* stmt( g_charaDb.getPreparedStatement(
"(CharacterId, " Core::Db::CharaDbStatements::CHAR_INS_CHARINFO ) );
" GuardianDeity, "
" Birthday, "
" BirthMonth, "
" Class, "
" CreateUnixTime, "
" IsActive, "
" Status, "
" FirstClass, "
" HomePoint, "
" StartTown, "
" Discovery, "
" HowTo, "
" QuestCompleteFlags, "
" unlocks, "
" QuestTracking, "
" Aetheryte, "
" GMRank, "
" UPDATE_DATE ) "
" VALUES (" + std::to_string( m_iD ) + ", "
+ std::to_string( m_guardianDeity ) + ", "
+ std::to_string( m_birthDay ) + ", "
+ std::to_string( m_birthMonth ) + ", "
+ std::to_string( m_class ) + ", UNIX_TIMESTAMP(NOW()), 1, 1, "
+ std::to_string( m_class ) + ", 2, "
+ std::to_string( startTown ) + ", "
+ "UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)discovery, 411 ) ) + "'), "
+ "UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)howTo, 32 ) ) + "'), "
+ "UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)questComplete, 200 ) ) + "'), "
+ "UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)unlocks, 64 ) ) + "'), "
+ "UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)questTracking, 10 ) ) + "'), "
+ "UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)aetherytes, 12 ) ) + "'),"
+ std::to_string( m_gmRank ) + ", NOW());" );
stmt->setInt( 1, m_accountId );
stmt->setInt( 2, m_id );
stmt->setInt64( 3, m_contentId );
stmt->setString( 4, std::string( m_name ) );
stmt->setInt( 5, 100 );
stmt->setInt( 6, 100 );
stmt->setBinary( 7, customize );
stmt->setInt( 8, m_voice );
stmt->setInt( 9, 1 );
stmt->setInt( 10, startZone );
stmt->setDouble( 11, x );
stmt->setDouble( 12, y );
stmt->setDouble( 13, z );
stmt->setDouble( 14, o );
stmt->setBinary( 15, modelEquip );
stmt->setInt( 16, 1 );
stmt->setInt( 17, m_guardianDeity );
stmt->setInt( 18, m_birthDay );
stmt->setInt( 19, m_birthMonth );
stmt->setInt( 20, m_class );
stmt->setInt( 21, 1 );
stmt->setInt( 22, m_class );
stmt->setInt( 23, 2 );
stmt->setInt( 24, startTown );
stmt->setBinary( 25, discovery );
stmt->setBinary( 26, howTo );
stmt->setBinary( 27, questComplete );
stmt->setBinary( 28, unlocks );
stmt->setBinary( 29, questTracking8 );
stmt->setBinary( 30, aetherytes );
stmt->setInt( 31, m_gmRank );
g_charaDb.directExecute( stmt );
g_database.execute( "INSERT INTO characlass (CharacterId, Lv_" + std::to_string( g_exdData.m_classJobInfoMap[m_class].exp_idx ) + ", UPDATE_DATE ) " g_database.execute( "INSERT INTO characlass (CharacterId, Lv_" + std::to_string( g_exdData.m_classJobInfoMap[m_class].exp_idx ) + ", UPDATE_DATE ) "
" VALUES (" + std::to_string( m_iD ) + ", 1, NOW());" ); " VALUES (" + std::to_string( m_id ) + ", 1, NOW());" );
g_database.execute( "INSERT INTO charaquest (CharacterId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaquest (CharacterId, UPDATE_DATE ) "
" VALUES (" + std::to_string( m_iD ) + ", NOW());" ); " VALUES (" + std::to_string( m_id ) + ", NOW());" );
g_database.execute( "INSERT INTO charainfosearch (CharacterId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charainfosearch (CharacterId, UPDATE_DATE ) "
" VALUES (" + std::to_string( m_iD ) + ", NOW());" ); " VALUES (" + std::to_string( m_id ) + ", NOW());" );
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SET UP INVENTORIES // SET UP INVENTORIES
g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( InventoryType::Bag0 ) + ", " + std::to_string( m_iD ) + ", NOW());" ); "VALUES ( " + std::to_string( InventoryType::Bag0 ) + ", " + std::to_string( m_id ) + ", NOW());" );
g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( InventoryType::Bag1 ) + ", " + std::to_string( m_iD ) + ", NOW());" ); "VALUES ( " + std::to_string( InventoryType::Bag1 ) + ", " + std::to_string( m_id ) + ", NOW());" );
g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( InventoryType::Bag2 ) + ", " + std::to_string( m_iD ) + ", NOW());" ); "VALUES ( " + std::to_string( InventoryType::Bag2 ) + ", " + std::to_string( m_id ) + ", NOW());" );
g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( InventoryType::Bag3 ) + ", " + std::to_string( m_iD ) + ", NOW());" ); "VALUES ( " + std::to_string( InventoryType::Bag3 ) + ", " + std::to_string( m_id ) + ", NOW());" );
g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( InventoryType::ArmoryOff ) + ", " + std::to_string( m_iD ) + ", NOW());" ); "VALUES ( " + std::to_string( InventoryType::ArmoryOff ) + ", " + std::to_string( m_id ) + ", NOW());" );
g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( InventoryType::ArmoryHead ) + ", " + std::to_string( m_iD ) + ", NOW());" ); "VALUES ( " + std::to_string( InventoryType::ArmoryHead ) + ", " + std::to_string( m_id ) + ", NOW());" );
g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( InventoryType::ArmoryBody ) + ", " + std::to_string( m_iD ) + ", NOW());" ); "VALUES ( " + std::to_string( InventoryType::ArmoryBody ) + ", " + std::to_string( m_id ) + ", NOW());" );
g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( InventoryType::ArmoryHand ) + ", " + std::to_string( m_iD ) + ", NOW());" ); "VALUES ( " + std::to_string( InventoryType::ArmoryHand ) + ", " + std::to_string( m_id ) + ", NOW());" );
g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( InventoryType::ArmoryWaist ) + ", " + std::to_string( m_iD ) + ", NOW());" ); "VALUES ( " + std::to_string( InventoryType::ArmoryWaist ) + ", " + std::to_string( m_id ) + ", NOW());" );
g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( InventoryType::ArmoryLegs ) + ", " + std::to_string( m_iD ) + ", NOW());" ); "VALUES ( " + std::to_string( InventoryType::ArmoryLegs ) + ", " + std::to_string( m_id ) + ", NOW());" );
g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( InventoryType::ArmoryFeet ) + ", " + std::to_string( m_iD ) + ", NOW());" ); "VALUES ( " + std::to_string( InventoryType::ArmoryFeet ) + ", " + std::to_string( m_id ) + ", NOW());" );
g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( InventoryType::ArmotyNeck ) + ", " + std::to_string( m_iD ) + ", NOW());" ); "VALUES ( " + std::to_string( InventoryType::ArmotyNeck ) + ", " + std::to_string( m_id ) + ", NOW());" );
g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( InventoryType::ArmoryEar ) + ", " + std::to_string( m_iD ) + ", NOW());" ); "VALUES ( " + std::to_string( InventoryType::ArmoryEar ) + ", " + std::to_string( m_id ) + ", NOW());" );
g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE )" g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE )"
"VALUES ( " + std::to_string( InventoryType::ArmoryWrist ) + ", " + std::to_string( m_iD ) + ", NOW());" ); "VALUES ( " + std::to_string( InventoryType::ArmoryWrist ) + ", " + std::to_string( m_id ) + ", NOW());" );
g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( InventoryType::ArmoryRing ) + ", " + std::to_string( m_iD ) + ", NOW());" ); "VALUES ( " + std::to_string( InventoryType::ArmoryRing ) + ", " + std::to_string( m_id ) + ", NOW());" );
g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( InventoryType::ArmoryMain ) + ", " + std::to_string( m_iD ) + ", NOW());" ); "VALUES ( " + std::to_string( InventoryType::ArmoryMain ) + ", " + std::to_string( m_id ) + ", NOW());" );
g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( InventoryType::Currency ) + ", " + std::to_string( m_iD ) + ", NOW());" ); "VALUES ( " + std::to_string( InventoryType::Currency ) + ", " + std::to_string( m_id ) + ", NOW());" );
g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaiteminventory (storageId, CharacterId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( InventoryType::Crystal ) + ", " + std::to_string( m_iD ) + ", NOW());" ); "VALUES ( " + std::to_string( InventoryType::Crystal ) + ", " + std::to_string( m_id ) + ", NOW());" );
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SETUP EQUIPMENT / STARTING GEAR // SETUP EQUIPMENT / STARTING GEAR
@ -390,19 +363,19 @@ namespace Core {
} }
g_database.execute( "INSERT INTO charaglobalitem (CharacterId, ItemId, catalogId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaglobalitem (CharacterId, ItemId, catalogId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( m_iD ) + ", " + std::to_string( uniqueId ) + ", " + "VALUES ( " + std::to_string( m_id ) + ", " + std::to_string( uniqueId ) + ", " +
std::to_string( weaponId ) + ", NOW());" ); std::to_string( weaponId ) + ", NOW());" );
g_database.execute( "INSERT INTO charaglobalitem (CharacterId, ItemId, catalogId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaglobalitem (CharacterId, ItemId, catalogId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( m_iD ) + ", " + std::to_string( bodyUid ) + ", " + "VALUES ( " + std::to_string( m_id ) + ", " + std::to_string( bodyUid ) + ", " +
std::to_string( body ) + ", NOW());" ); std::to_string( body ) + ", NOW());" );
g_database.execute( "INSERT INTO charaglobalitem (CharacterId, ItemId, catalogId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaglobalitem (CharacterId, ItemId, catalogId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( m_iD ) + ", " + std::to_string( handsUid ) + ", " + "VALUES ( " + std::to_string( m_id ) + ", " + std::to_string( handsUid ) + ", " +
std::to_string( hands ) + ", NOW());" ); std::to_string( hands ) + ", NOW());" );
g_database.execute( "INSERT INTO charaglobalitem (CharacterId, ItemId, catalogId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaglobalitem (CharacterId, ItemId, catalogId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( m_iD ) + ", " + std::to_string( legsUid ) + ", " + "VALUES ( " + std::to_string( m_id ) + ", " + std::to_string( legsUid ) + ", " +
std::to_string( legs ) + ", NOW());" ); std::to_string( legs ) + ", NOW());" );
g_database.execute( "INSERT INTO charaglobalitem (CharacterId, ItemId, catalogId, UPDATE_DATE ) " g_database.execute( "INSERT INTO charaglobalitem (CharacterId, ItemId, catalogId, UPDATE_DATE ) "
"VALUES ( " + std::to_string( m_iD ) + ", " + std::to_string( feetUid ) + ", " + "VALUES ( " + std::to_string( m_id ) + ", " + std::to_string( feetUid ) + ", " +
std::to_string( feet ) + ", NOW());" ); std::to_string( feet ) + ", NOW());" );
g_database.execute( "INSERT INTO charaitemgearset (storageId, CharacterId, " g_database.execute( "INSERT INTO charaitemgearset (storageId, CharacterId, "
"container_" + std::to_string( EquipSlot::MainHand ) + ", " "container_" + std::to_string( EquipSlot::MainHand ) + ", "
@ -411,7 +384,7 @@ namespace Core {
"container_" + std::to_string( EquipSlot::Legs ) + ", " "container_" + std::to_string( EquipSlot::Legs ) + ", "
"container_" + std::to_string( EquipSlot::Feet ) + ", " "container_" + std::to_string( EquipSlot::Feet ) + ", "
"UPDATE_DATE ) " "UPDATE_DATE ) "
"VALUES ( " + std::to_string( InventoryType::GearSet0 ) + ", " + std::to_string( m_iD ) + ", " + "VALUES ( " + std::to_string( InventoryType::GearSet0 ) + ", " + std::to_string( m_id ) + ", " +
std::to_string( uniqueId ) + ", " + std::to_string( uniqueId ) + ", " +
std::to_string( bodyUid ) + ", " + std::to_string( bodyUid ) + ", " +
std::to_string( handsUid ) + ", " + std::to_string( handsUid ) + ", " +

View file

@ -32,12 +32,12 @@ namespace Core {
// return the id of the actor // return the id of the actor
uint32_t getId() const uint32_t getId() const
{ {
return m_iD; return m_id;
} }
void setId( uint32_t id ) void setId( uint32_t id )
{ {
m_iD = id; m_id = id;
} }
void setContentId( uint64_t id ) void setContentId( uint64_t id )
@ -154,7 +154,7 @@ namespace Core {
private: private:
uint32_t m_accountId; uint32_t m_accountId;
uint32_t m_iD; uint32_t m_id;
uint64_t m_contentId; uint64_t m_contentId;
uint8_t m_guardianDeity; uint8_t m_guardianDeity;

View file

@ -209,7 +209,7 @@ std::vector<Core::PlayerMinimal> Core::Network::SapphireAPI::getCharList( uint32
std::vector<Core::PlayerMinimal> charList; std::vector<Core::PlayerMinimal> charList;
boost::shared_ptr<Core::Db::QueryResult> pQR = g_database.query( "SELECT CharacterId, ContentId FROM charabase WHERE AccountId = " + std::to_string( accountId ) + ";" ); boost::shared_ptr<Core::Db::QueryResult> pQR = g_database.query( "SELECT CharacterId, ContentId FROM charainfo WHERE AccountId = " + std::to_string( accountId ) + ";" );
if( !pQR ) if( !pQR )
{ {
@ -236,7 +236,7 @@ std::vector<Core::PlayerMinimal> Core::Network::SapphireAPI::getCharList( uint32
bool Core::Network::SapphireAPI::checkNameTaken( std::string name ) bool Core::Network::SapphireAPI::checkNameTaken( std::string name )
{ {
std::string query = "SELECT * FROM charabase WHERE Name = '" + g_database.escapeString( name ) + "';"; std::string query = "SELECT * FROM charainfo WHERE Name = '" + g_database.escapeString( name ) + "';";
auto pQR = g_database.query( query ); auto pQR = g_database.query( query );
@ -250,7 +250,7 @@ uint32_t Core::Network::SapphireAPI::getNextCharId()
{ {
int32_t charId = 0; int32_t charId = 0;
boost::shared_ptr<Core::Db::QueryResult> pQR = g_database.query( "SELECT MAX(CharacterId) FROM charabase" ); boost::shared_ptr<Core::Db::QueryResult> pQR = g_database.query( "SELECT MAX(CharacterId) FROM charainfo" );
if( !pQR ) if( !pQR )
{ {
@ -270,7 +270,7 @@ uint64_t Core::Network::SapphireAPI::getNextContentId()
{ {
uint64_t contentId = 0; uint64_t contentId = 0;
boost::shared_ptr<Core::Db::QueryResult> pQR = g_database.query( "SELECT MAX(ContentId) FROM charabase" ); boost::shared_ptr<Core::Db::QueryResult> pQR = g_database.query( "SELECT MAX(ContentId) FROM charainfo" );
if( !pQR ) if( !pQR )
{ {

View file

@ -17,6 +17,12 @@
#include <src/servers/Server_Common/Exd/ExdData.h> #include <src/servers/Server_Common/Exd/ExdData.h>
#include <src/servers/Server_Common/Crypt/base64.h> #include <src/servers/Server_Common/Crypt/base64.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>
//Added for the default_resource example //Added for the default_resource example
#include <fstream> #include <fstream>
#include <string> #include <string>
@ -31,6 +37,7 @@
Core::Logger g_log; Core::Logger g_log;
Core::Db::Database g_database; Core::Db::Database g_database;
Core::Db::DbWorkerPool< Core::Db::CharaDbConnection > g_charaDb;
Core::Data::ExdData g_exdData; Core::Data::ExdData g_exdData;
Core::Network::SapphireAPI g_sapphireAPI; Core::Network::SapphireAPI g_sapphireAPI;
@ -140,6 +147,21 @@ bool loadSettings( int32_t argc, char* argv[] )
return false; return false;
} }
Core::Db::DbLoader loader;
Core::Db::ConnectionInfo info;
info.password = m_pConfig->getValue< std::string >( "Settings.General.Mysql.Pass", "" );
info.host = m_pConfig->getValue< std::string >( "Settings.General.Mysql.Host", "127.0.0.1" );
info.database = m_pConfig->getValue< std::string >( "Settings.General.Mysql.Database", "sapphire" );
info.port = m_pConfig->getValue< uint16_t >( "Settings.General.Mysql.Port", 3306 );
info.user = m_pConfig->getValue< std::string >( "Settings.General.Mysql.Username", "root" );
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( g_charaDb, info );
if( !loader.initDbs() )
return false;
Core::Db::DatabaseParams params; Core::Db::DatabaseParams params;
params.bufferSize = 16384; params.bufferSize = 16384;
params.connectionCount = 3; params.connectionCount = 3;

View file

@ -51,11 +51,10 @@ bool Core::Entity::Player::load( uint32_t charId, Core::SessionPtr pSession )
{ {
const std::string char_id_str = std::to_string( charId ); const std::string char_id_str = std::to_string( charId );
Core::Db::PreparedStmtScopedPtr stmt( g_charaDb.getPreparedStatement( auto stmt = g_charaDb.getPreparedStatement( Core::Db::CharaDbStatements::CHAR_SEL_LOAD );
Core::Db::CharaDbStatements::CHAR_SEL_LOAD ) );
stmt->setUInt( 1, charId ); stmt->setUInt( 1, charId );
Mysql::PreparedResultSetScopedPtr res( g_charaDb.query( stmt.get() ) ); auto res = g_charaDb.query( stmt );
if( !res->next() ) if( !res->next() )
return false; return false;
@ -65,7 +64,7 @@ bool Core::Entity::Player::load( uint32_t charId, Core::SessionPtr pSession )
auto name = res->getString( "Name" ); auto name = res->getString( "Name" );
strcpy( m_name, name.c_str() ); strcpy( m_name, name.c_str() );
auto zoneId = res->getUInt( "PrimaryTerritoryId" ); auto zoneId = res->getUInt( "TerritoryId" );
ZonePtr pCurrZone = g_zoneMgr.getZone( zoneId ); ZonePtr pCurrZone = g_zoneMgr.getZone( zoneId );
m_zoneId = zoneId; m_zoneId = zoneId;
@ -91,10 +90,10 @@ bool Core::Entity::Player::load( uint32_t charId, Core::SessionPtr pSession )
m_mp = res->getUInt( "Mp" ); m_mp = res->getUInt( "Mp" );
m_tp = 0; m_tp = 0;
m_pos.x = res->getFloat( "Pos_0_0" ); m_pos.x = res->getFloat( "PosX" );
m_pos.y = res->getFloat( "Pos_0_1" ); m_pos.y = res->getFloat( "PosY" );
m_pos.z = res->getFloat( "Pos_0_2" ); m_pos.z = res->getFloat( "PosZ" );
setRotation( res->getFloat( "Pos_0_3" ) ); setRotation( res->getFloat( "PosR" ) );
auto custom = res->getBlobVector( "Customize" ); auto custom = res->getBlobVector( "Customize" );
memcpy( reinterpret_cast< char* >( m_customize ), custom.data(), custom.size() ); memcpy( reinterpret_cast< char* >( m_customize ), custom.data(), custom.size() );
@ -129,7 +128,7 @@ bool Core::Entity::Player::load( uint32_t charId, Core::SessionPtr pSession )
auto aetheryte = res->getBlobVector( "Aetheryte" ); auto aetheryte = res->getBlobVector( "Aetheryte" );
memcpy( reinterpret_cast< char* >( m_aetheryte ), aetheryte.data(), aetheryte.size() ); memcpy( reinterpret_cast< char* >( m_aetheryte ), aetheryte.data(), aetheryte.size() );
auto unlocks = res->getBlobVector( "unlocks" ); auto unlocks = res->getBlobVector( "Unlocks" );
memcpy( reinterpret_cast< char* >( m_unlocks ), unlocks.data(), unlocks.size() ); memcpy( reinterpret_cast< char* >( m_unlocks ), unlocks.data(), unlocks.size() );
auto discovery = res->getBlobVector( "Discovery" ); auto discovery = res->getBlobVector( "Discovery" );
@ -208,11 +207,10 @@ bool Core::Entity::Player::load( uint32_t charId, Core::SessionPtr pSession )
bool Core::Entity::Player::loadActiveQuests() bool Core::Entity::Player::loadActiveQuests()
{ {
Core::Db::PreparedStmtScopedPtr stmt( g_charaDb.getPreparedStatement( auto stmt = g_charaDb.getPreparedStatement( Core::Db::CharaDbStatements::CHAR_SEL_LOAD_QUESTINFO );
Core::Db::CharaDbStatements::CHAR_SEL_LOAD_QUESTINFO ) );
stmt->setUInt( 1, m_id ); stmt->setUInt( 1, m_id );
Mysql::PreparedResultSetScopedPtr res( g_charaDb.query( stmt.get() ) ); auto res = g_charaDb.query( stmt );
if( !res->next() ) if( !res->next() )
return false; return false;
@ -264,10 +262,9 @@ bool Core::Entity::Player::loadActiveQuests()
bool Core::Entity::Player::loadClassData() bool Core::Entity::Player::loadClassData()
{ {
Core::Db::PreparedStmtScopedPtr stmt( g_charaDb.getPreparedStatement( auto stmt = g_charaDb.getPreparedStatement( Core::Db::CharaDbStatements::CHAR_SEL_LOAD_CLASSINFO );
Core::Db::CharaDbStatements::CHAR_SEL_LOAD_CLASSINFO ) );
stmt->setUInt( 1, m_id ); stmt->setUInt( 1, m_id );
Mysql::PreparedResultSetScopedPtr res( g_charaDb.query( stmt.get() ) ); auto res = g_charaDb.query( stmt );
if( !res->next() ) if( !res->next() )
return false; return false;
@ -284,10 +281,9 @@ bool Core::Entity::Player::loadClassData()
bool Core::Entity::Player::loadSearchInfo() bool Core::Entity::Player::loadSearchInfo()
{ {
Core::Db::PreparedStmtScopedPtr stmt( g_charaDb.getPreparedStatement( auto stmt = g_charaDb.getPreparedStatement( Core::Db::CharaDbStatements::CHAR_SEL_LOAD_SEARCHINFO );
Core::Db::CharaDbStatements::CHAR_SEL_LOAD_SEARCHINFO ) );
stmt->setUInt( 1, m_id ); stmt->setUInt( 1, m_id );
Mysql::PreparedResultSetScopedPtr res( g_charaDb.query( stmt.get() ) ); auto res = g_charaDb.query( stmt );
if( !res->next() ) if( !res->next() )
return false; return false;

View file

@ -194,7 +194,7 @@ bool Core::ServerZone::loadSettings( int32_t argc, char* argv[] )
g_charaDb.execute( "DELETE FROM zoneservers WHERE id = 101" ); g_charaDb.execute( "DELETE FROM zoneservers WHERE id = 101" );
// query runs synchronous // query runs synchronous
boost::scoped_ptr< Mysql::ResultSet > res( g_charaDb.query( "SELECT id,ip,port FROM zoneservers" ) ); auto res = g_charaDb.query( "SELECT id,ip,port FROM zoneservers" );
while( res->next() ) while( res->next() )
{ {
g_log.info( "id: " + std::to_string( res->getUInt( "id" ) ) ); g_log.info( "id: " + std::to_string( res->getUInt( "id" ) ) );
@ -215,13 +215,13 @@ bool Core::ServerZone::loadSettings( int32_t argc, char* argv[] )
try try
{ {
// // bunch of test cases for db wrapper // // bunch of test cases for db wrapper
Mysql::MySqlBase base; boost::shared_ptr< Mysql::MySqlBase > base( new Mysql::MySqlBase() );
g_log.info( base.getVersionInfo() ); g_log.info( base->getVersionInfo() );
Mysql::optionMap options; Mysql::optionMap options;
options[ MYSQL_OPT_RECONNECT ] = "1"; options[ MYSQL_OPT_RECONNECT ] = "1";
boost::scoped_ptr< Mysql::Connection > con( base.connect( "127.0.0.1", "root", "", options, 3306 ) ); auto con = base->connect( "127.0.0.1", "root", "", options, 3306 );
// if( con->getAutoCommit() ) // if( con->getAutoCommit() )
// g_log.info( "autocommit active" ); // g_log.info( "autocommit active" );