Index: src/framework/Utilities/Callback.h =================================================================== --- src/framework/Utilities/Callback.h (revision 6657) +++ src/framework/Utilities/Callback.h (working copy) @@ -107,6 +107,88 @@ _Callback(_Callback < Class > const& cb) : m_object(cb.m_object), m_method(cb.m_method) {} }; + + /// ---- Statics ---- + + template < typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void, typename ParamType4 = void > + class _SCallback + { + protected: + typedef void (*Method)(ParamType1, ParamType2, ParamType3, ParamType4); + Method m_method; + ParamType1 m_param1; + ParamType2 m_param2; + ParamType3 m_param3; + ParamType4 m_param4; + void _Execute() { (*m_method)(m_param1, m_param2, m_param3, m_param4); } + public: + _SCallback(Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3, ParamType4 param4) + : m_method(method), m_param1(param1), m_param2(param2), m_param3(param3), m_param4(param4) {} + _SCallback(_SCallback < ParamType1, ParamType2, ParamType3, ParamType4> const& cb) + : m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3), m_param4(cb.m_param4) {} + }; + + template < typename ParamType1, typename ParamType2, typename ParamType3 > + class _SCallback < ParamType1, ParamType2, ParamType3 > + { + protected: + typedef void (*Method)(ParamType1, ParamType2, ParamType3); + Method m_method; + ParamType1 m_param1; + ParamType2 m_param2; + ParamType3 m_param3; + void _Execute() { (*m_method)(m_param1, m_param2, m_param3); } + public: + _SCallback(Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3) + : m_method(method), m_param1(param1), m_param2(param2) {} + _SCallback(_SCallback < ParamType1, ParamType2, ParamType3 > const& cb) + : m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3) {} + }; + + template < typename ParamType1, typename ParamType2 > + class _SCallback < ParamType1, ParamType2 > + { + protected: + typedef void (*Method)(ParamType1, ParamType2); + Method m_method; + ParamType1 m_param1; + ParamType2 m_param2; + void _Execute() { (*m_method)(m_param1, m_param2); } + public: + _SCallback(Method method, ParamType1 param1, ParamType2 param2) + : m_method(method), m_param1(param1), m_param2(param2) {} + _SCallback(_SCallback < ParamType1, ParamType2 > const& cb) + : m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2) {} + }; + + template < typename ParamType1 > + class _SCallback < ParamType1 > + { + protected: + typedef void (*Method)(ParamType1); + Method m_method; + ParamType1 m_param1; + void _Execute() { (*m_method)(m_param1); } + public: + _SCallback(Method method, ParamType1 param1) + : m_method(method), m_param1(param1) {} + _SCallback(_SCallback < ParamType1 > const& cb) + : m_method(cb.m_method), m_param1(cb.m_param1) {} + }; + + template < > + class _SCallback < > + { + protected: + typedef void (*Method)(); + Method m_method; + void _Execute() { (*m_method)(); } + public: + _SCallback(Method method) + : m_method(method) {} + _SCallback(_SCallback <> const& cb) + : m_method(cb.m_method) {} + }; } /// --------- GENERIC CALLBACKS ---------- @@ -250,6 +332,51 @@ QueryCallback(Class *object, typename QC0::Method method, QueryResult* result) : _IQueryCallback< QC0 >(QC0(object, method, result)) {} }; + + /// ---- Statics ---- + + template < typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void > + class SQueryCallback : + public _IQueryCallback< _SCallback < QueryResult*, ParamType1, ParamType2, ParamType3 > > + { + private: + typedef _SCallback < QueryResult*, ParamType1, ParamType2, ParamType3 > QC3; + public: + SQueryCallback(typename QC3::Method method, QueryResult* result, ParamType1 param1, ParamType2 param2, ParamType3 param3) + : _IQueryCallback< QC3 >(QC3(method, result, param1, param2, param3)) {} + }; + + template < typename ParamType1, typename ParamType2 > + class SQueryCallback < ParamType1, ParamType2 > : + public _IQueryCallback< _SCallback < QueryResult*, ParamType1, ParamType2 > > + { + private: + typedef _SCallback < QueryResult*, ParamType1, ParamType2 > QC2; + public: + SQueryCallback(typename QC2::Method method, QueryResult* result, ParamType1 param1, ParamType2 param2) + : _IQueryCallback< QC2 >(QC2(method, result, param1, param2)) {} + }; + + template < typename ParamType1 > + class SQueryCallback < ParamType1 > : + public _IQueryCallback< _SCallback < QueryResult*, ParamType1 > > + { + private: + typedef _SCallback < QueryResult*, ParamType1 > QC1; + public: + SQueryCallback(typename QC1::Method method, QueryResult* result, ParamType1 param1) + : _IQueryCallback< QC1 >(QC1(method, result, param1)) {} + }; + + template < > + class SQueryCallback < > : public _IQueryCallback< _SCallback < QueryResult* > > + { + private: + typedef _SCallback < QueryResult* > QC0; + public: + SQueryCallback(QC0::Method method, QueryResult* result) + : _IQueryCallback< QC0 >(QC0(method, result)) {} + }; } #endif Index: src/game/QueryHandler.cpp =================================================================== --- src/game/QueryHandler.cpp (revision 6657) +++ src/game/QueryHandler.cpp (working copy) @@ -57,61 +57,13 @@ SendPacket(&data); } -class NameQueryHandler -{ -public: - void SendNameQueryOpcodeFromDBCallBack(QueryResult *result, uint32 accountId) - { - if(!result) - return; - - WorldSession * session = sWorld.FindSession(accountId); - if(!session) - { - delete result; - return; - } - - Field *fields = result->Fetch(); - uint32 guid = fields[0].GetUInt32(); - std::string name = fields[1].GetCppString(); - uint32 field = 0; - if(name == "") - name = session->GetMangosString(LANG_NON_EXIST_CHARACTER); - else - field = fields[2].GetUInt32(); - - // guess size - WorldPacket data( SMSG_NAME_QUERY_RESPONSE, (8+1+4+4+4+10) ); - data << MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER); - data << name; - data << (uint8)0; - data << (uint32)(field & 0xFF); - data << (uint32)((field >> 16) & 0xFF); - data << (uint32)((field >> 8) & 0xFF); - - // if the first declined name field (3) is empty, the rest must be too - if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) && fields[3].GetCppString() != "") - { - data << (uint8)1; // is declined - for(int i = 3; i < MAX_DECLINED_NAME_CASES+3; ++i) - data << fields[i].GetCppString(); - } - else - data << (uint8)0; // is declined - - session->SendPacket( &data ); - delete result; - } -} nameQueryHandler; - void WorldSession::SendNameQueryOpcodeFromDB(uint64 guid) { - CharacterDatabase.AsyncPQuery(&nameQueryHandler, &NameQueryHandler::SendNameQueryOpcodeFromDBCallBack, GetAccountId(), + CharacterDatabase.AsyncPQuery(&WorldSession::SendNameQueryOpcodeFromDBCallBack, GetAccountId(), !sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) ? // ------- Query Without Declined Names -------- // 0 1 2 - "SELECT characters.guid, name, SUBSTRING(data, LENGTH(SUBSTRING_INDEX(data, ' ', '%u'))+2, LENGTH(SUBSTRING_INDEX(data, ' ', '%u')) - LENGTH(SUBSTRING_INDEX(data, ' ', '%u'))-1) " + "SELECT guid, name, SUBSTRING(data, LENGTH(SUBSTRING_INDEX(data, ' ', '%u'))+2, LENGTH(SUBSTRING_INDEX(data, ' ', '%u')) - LENGTH(SUBSTRING_INDEX(data, ' ', '%u'))-1) " "FROM characters WHERE guid = '%u'" : // --------- Query With Declined Names --------- @@ -123,6 +75,50 @@ UNIT_FIELD_BYTES_0, UNIT_FIELD_BYTES_0+1, UNIT_FIELD_BYTES_0, GUID_LOPART(guid)); } +void WorldSession::SendNameQueryOpcodeFromDBCallBack(QueryResult *result, uint32 accountId) +{ + if(!result) + return; + + WorldSession * session = sWorld.FindSession(accountId); + if(!session) + { + delete result; + return; + } + + Field *fields = result->Fetch(); + uint32 guid = fields[0].GetUInt32(); + std::string name = fields[1].GetCppString(); + uint32 field = 0; + if(name == "") + name = session->GetMangosString(LANG_NON_EXIST_CHARACTER); + else + field = fields[2].GetUInt32(); + + // guess size + WorldPacket data( SMSG_NAME_QUERY_RESPONSE, (8+1+4+4+4+10) ); + data << MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER); + data << name; + data << (uint8)0; + data << (uint32)(field & 0xFF); + data << (uint32)((field >> 16) & 0xFF); + data << (uint32)((field >> 8) & 0xFF); + + // if the first declined name field (3) is empty, the rest must be too + if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) && fields[3].GetCppString() != "") + { + data << (uint8)1; // is declined + for(int i = 3; i < MAX_DECLINED_NAME_CASES+3; ++i) + data << fields[i].GetCppString(); + } + else + data << (uint8)0; // is declined + + session->SendPacket( &data ); + delete result; +} + void WorldSession::HandleNameQueryOpcode( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data,8); Index: src/game/WorldSession.h =================================================================== --- src/game/WorldSession.h (revision 6657) +++ src/game/WorldSession.h (working copy) @@ -116,6 +116,7 @@ //void SendTestCreatureQueryOpcode( uint32 entry, uint64 guid, uint32 testvalue ); void SendNameQueryOpcode(Player* p); void SendNameQueryOpcodeFromDB(uint64 guid); + static void SendNameQueryOpcodeFromDBCallBack(QueryResult *result, uint32 accountId); void SendTrainerList( uint64 guid ); void SendTrainerList( uint64 guid,std::string strTitle ); Index: src/shared/Database/Database.h =================================================================== --- src/shared/Database/Database.h (revision 6657) +++ src/shared/Database/Database.h (working copy) @@ -59,10 +59,14 @@ bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*), const char *sql); template bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql); + template + bool AsyncQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql); template bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*), const char *format,...) ATTR_PRINTF(4,5); template bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(5,6); + template + bool AsyncPQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(5,6); template bool DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, SqlQueryHolder*), SqlQueryHolder *holder); template Index: src/shared/Database/DatabaseImpl.h =================================================================== --- src/shared/Database/DatabaseImpl.h (revision 6657) +++ src/shared/Database/DatabaseImpl.h (working copy) @@ -45,6 +45,18 @@ return true; } +template +bool +Database::AsyncQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql) +{ + if (!sql) return false; + ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current(); + QueryQueues::iterator itr = m_queryQueues.find(queryThread); + if (itr == m_queryQueues.end()) return false; + m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::SQueryCallback(method, (QueryResult*)NULL, param1), itr->second)); + return true; +} + template bool Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*), const char *format,...) @@ -87,6 +99,28 @@ return AsyncQuery(object, method, param1, szQuery); } +template +bool +Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...) +{ + if(!format) return false; + + va_list ap; + char szQuery [MAX_QUERY_LEN]; + va_start(ap, format); + int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap ); + va_end(ap); + + if(res==-1) + { + sLog.outError("SQL Query truncated (and not execute) for format: %s",format); + return false; + } + + return AsyncQuery(method, param1, szQuery); +} + + template bool Database::DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, SqlQueryHolder*), SqlQueryHolder *holder) Index: src/shared/Database/SqlOperations.h =================================================================== --- src/shared/Database/SqlOperations.h (revision 6657) +++ src/shared/Database/SqlOperations.h (working copy) @@ -56,10 +56,14 @@ { private: std::queue m_queue; + int8 m_counter; public: - SqlTransaction() {} + SqlTransaction() : m_counter(0) {} void DelayExecute(const char *sql) { m_queue.push(strdup(sql)); } void Execute(Database *db); + + int8 GetCounter() const { return m_counter; } + void SetCounter(int8 counter) { m_counter = counter; } }; /// ---- ASYNC QUERIES ----