All pastes #884895 Raw Edit

Mine

public text v1 · immutable
#884895 ·published 2008-01-30 17:26 UTC
rendered paste body
Index: src/shared/Database/Database.h
===================================================================
--- src/shared/Database/Database.h	(révision 5105)
+++ src/shared/Database/Database.h	(copie de travail)
@@ -59,10 +59,14 @@
             bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*), const char *sql);
         template<class Class, typename ParamType1>
             bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql);
+        template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
+            bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql);
         template<class Class>
             bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*), const char *format,...) ATTR_PRINTF(4,5);
         template<class Class, typename ParamType1>
             bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(5,6);
+        template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
+            bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...) ATTR_PRINTF(5,6);
         template<class Class>
             bool DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, SqlQueryHolder*), SqlQueryHolder *holder);
         template<class Class, typename ParamType1>
Index: src/shared/Database/DatabaseImpl.h
===================================================================
--- src/shared/Database/DatabaseImpl.h	(révision 5105)
+++ src/shared/Database/DatabaseImpl.h	(copie de travail)
@@ -45,6 +45,18 @@
     return true;
 }
 
+template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
+bool
+Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, 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::QueryCallback<Class, ParamType1, ParamType2, ParamType3>(object, method, (QueryResult*)NULL, param1, param2, param3), itr->second));
+    return true;
+}
+
 template<class Class>
 bool
 Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*), const char *format,...)
@@ -87,6 +99,28 @@
     return AsyncQuery(object, method, param1, szQuery);
 }
 
+
+template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
+bool
+Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, 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(object, method, param1, param2, param3, szQuery);
+}
+
 template<class Class>
 bool
 Database::DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, SqlQueryHolder*), SqlQueryHolder *holder)
Index: src/game/Player.cpp
===================================================================
--- src/game/Player.cpp	(révision 5105)
+++ src/game/Player.cpp	(copie de travail)
@@ -14077,27 +14065,43 @@
     tokens[index] = buf;
 }
 
-void Player::SetUInt32ValueInDB(uint16 index, uint32 value, uint64 guid)
+class PlayerCallback
 {
-    Tokens tokens;
-    if(!LoadValuesArrayFromDB(tokens,guid))
-        return;
+     public:
+        void CallbackSetUInt32ValueInDB(QueryResult* result, uint16 index, uint32 value, uint64 guid)
+        {
+          if(!result)
+	     return;
+		
+          Tokens tokens;
+	
+	   Field *fields = result->Fetch();
 
-    if(index >= tokens.size())
-        return;
+          tokens = StrSplit(fields[0].GetCppString(), " ");
 
-    char buf[11];
-    snprintf(buf,11,"%u",value);
-    tokens[index] = buf;
+          delete result;
 
-    SaveValuesArrayInDB(tokens,guid);
+          if(index >= tokens.size())
+             return;
+
+         char buf[11];
+         snprintf(buf,11,"%u",value);
+         tokens[index] = buf;
+
+         Player::SaveValuesArrayInDB(tokens,guid);
+        }
+} pCallback;
+
+void Player::SetUInt32ValueInDB(uint16 index, uint32 value, uint64 guid)
+{
+   CharacterDatabase.AsyncPQuery(&pCallback, &PlayerCallback::CallbackSetUInt32ValueInDB, index, value, guid, "SELECT `data` FROM `character` WHERE `guid`='%u'", GUID_LOPART(guid));
 }
 
 void Player::SetFloatValueInDB(uint16 index, float value, uint64 guid)
 {
     uint32 temp;
     memcpy(&temp, &value, sizeof(value));
     Player::SetUInt32ValueInDB(index, temp, guid);
 }
 
 void Player::SendAttackSwingNotStanding()
Index: src/game/ObjectMgr.h
===================================================================
--- src/game/ObjectMgr.h	(révision 5105)
+++ src/game/ObjectMgr.h	(copie de travail)
@@ -277,6 +277,7 @@
 
         //auction messages
         void SendAuctionWonMail( AuctionEntry * auction );
+        void CallbackSendAuctionWonMail(QueryResult *result, AuctionEntry *auction );
         void SendAuctionSuccessfulMail( AuctionEntry * auction );
         void SendAuctionExpiredMail( AuctionEntry * auction );
         uint32 GetAuctionCut( uint32 location, uint32 highBid );
Index: src/game/ObjectMgr.cpp
===================================================================
--- src/game/ObjectMgr.cpp	(révision 5105)
+++ src/game/ObjectMgr.cpp	(copie de travail)
@@ -37,6 +37,7 @@
 #include "GameEvent.h"
 #include "Spell.h"
 #include "Chat.h"
+#include "Database/DatabaseImpl.h"
 
 INSTANTIATE_SINGLETON_1(ObjectMgr);
 
@@ -242,49 +243,17 @@
     uint64 bidder_guid = MAKE_GUID(auction->bidder,HIGHGUID_PLAYER);
     Player *bidder = objmgr.GetPlayer(bidder_guid);
 
-    uint32 bidder_accId = 0;
-
-    // data for gm.log
-    if( sWorld.getConfig(CONFIG_GM_LOG_TRADE) )
+    // prevent DB access for online player
+    if(bidder)
     {
-        uint32 bidder_security = 0;
-        std::string bidder_name;
-        if (bidder)
-        {
-            bidder_accId = bidder->GetSession()->GetAccountId();
-            bidder_security = bidder->GetSession()->GetSecurity();
-            bidder_name = bidder->GetName();
-        }
-        else
-        {
-            bidder_accId = GetPlayerAccountIdByGUID(bidder_guid);
-            bidder_security = GetSecurityByAccount(bidder_accId);
-
-            if(bidder_security > SEC_PLAYER )               // not do redundant DB requests
-            {
-                if(!GetPlayerNameByGUID(bidder_guid,bidder_name))
-                    bidder_name = LANG_UNKNOWN;
-            }
-        }
-
-        if( bidder_security > SEC_PLAYER )
-        {
-            std::string owner_name;
-            if(!GetPlayerNameByGUID(auction->owner,owner_name))
-                owner_name = LANG_UNKNOWN;
-
-            uint32 owner_accid = GetPlayerAccountIdByGUID(auction->owner);
-
-            sLog.outCommand("GM %s (Account: %u) won item in auction: %s (Entry: %u Count: %u) and pay money: %u. Original owner %s (Account: %u)",
-                bidder_name.c_str(),bidder_accId,pItem->GetProto()->Name1,pItem->GetEntry(),pItem->GetCount(),auction->bid,owner_name.c_str(),owner_accid);
-        }
+        std::string bidder_name = bidder->GetName();
     }
-    else if(!bidder)
-        bidder_accId = GetPlayerAccountIdByGUID(bidder_guid);
+    else
+    {
+     CharacterDatabase.AsyncPQuery(this, &ObjectMgr::CallbackSendAuctionWonMail, auction, "SELECT `name` FROM `character` WHERE `guid` = '%u'", GUID_LOPART(bidder_guid));
+     return;
+    }     
 
-    // receiver exist
-    if(bidder || bidder_accId)
-    {
         std::ostringstream msgAuctionWonSubject;
         msgAuctionWonSubject << auction->item_template << ":0:" << AUCTION_WON;
 
@@ -305,32 +274,74 @@
         CharacterDatabase.PExecute("UPDATE `item_instance` SET `owner_guid` = '%u' WHERE `guid`='%u'",auction->bidder,pItem->GetGUIDLow());
         CharacterDatabase.CommitTransaction();
 
-        if (bidder)
-        {
-            bidder->GetSession()->SendAuctionBidderNotification( auction->location, auction->Id, bidder_guid, 0, 0, auction->item_template);
+        bidder->GetSession()->SendAuctionBidderNotification( auction->location, auction->Id, bidder_guid, 0, 0, auction->item_template);
 
-            MailItemsInfo mi;
-            mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
-            bidder->CreateMail(mailId, MAIL_AUCTION, auction->location, msgAuctionWonSubject.str(), itemTextId, &mi, etime, dtime, 0, 0, AUCTION_CHECKED);
-        }
-        else
-        {
-            objmgr.RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
-            delete pItem;
-        }
+        MailItemsInfo mi;
+        mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
+        bidder->CreateMail(mailId, MAIL_AUCTION, auction->location, msgAuctionWonSubject.str(), itemTextId, &mi, etime, dtime, 0, 0, AUCTION_CHECKED);
 
+
         CharacterDatabase.PExecute("INSERT INTO `mail` (`id`,`messageType`,`sender`,`receiver`,`subject`,`itemTextId`,`has_items`,`expire_time`,`deliver_time`,`money`,`cod`,`checked`) "
             "VALUES ('%u', '%d', '%u', '%u', '%s', '%u', '1', '" I64FMTD "','" I64FMTD "', '0', '0', '%d')",
             mailId, MAIL_AUCTION, auction->location, auction->bidder, msgAuctionWonSubject.str().c_str(), itemTextId, (uint64)etime, (uint64)dtime, AUCTION_CHECKED);
         CharacterDatabase.PExecute("INSERT INTO `mail_items` (`mail_id`,`item_guid`,`item_template`) VALUES ('%u', '%u', '%u')", mailId, auction->item_guidlow, auction->item_template);
-    }
-    // receiver not exist
-    else
+
+}
+
+//does not clear ram
+void ObjectMgr::CallbackSendAuctionWonMail(QueryResult *result, AuctionEntry* auction)
+{
+    if(!result)
+      return;
+
+    if(!auction)
+      return;
+
+    Item *pItem = objmgr.GetAItem(auction->item_guidlow);
+
+    if(!pItem)
+      return;
+
+    uint64 bidder_guid = MAKE_GUID(auction->bidder,HIGHGUID_PLAYER);
+
+    std::string bidder_name = (*result)[0].GetCppString();
+
+    delete result;
+
+    uint32 bidder_accId = GetPlayerAccountIdByGUID(bidder_guid);
+
+    if(bidder_accId)
     {
+        std::ostringstream msgAuctionWonSubject;
+        msgAuctionWonSubject << auction->item_template << ":0:" << AUCTION_WON;
+
+        std::ostringstream msgAuctionWonBody;
+        msgAuctionWonBody.width(16);
+        msgAuctionWonBody << std::right << std::hex << auction->owner;
+        msgAuctionWonBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
+        sLog.outDebug( "AuctionWon body string : %s", msgAuctionWonBody.str().c_str() );
+
+        //prepare mail data... :
+        uint32 mailId = this->GenerateMailID();
+        uint32 itemTextId = this->CreateItemText( msgAuctionWonBody.str() );
+        time_t dtime = time(NULL);                          //Will always be instant when from Auction House.
+        time_t etime = dtime + (30 * DAY);
+
+        // set owner to bidder (to prevent delete item with sender char deleting)
+        // owner in `data` will set at mail receive and item extracting
+        CharacterDatabase.PExecute("UPDATE `item_instance` SET `owner_guid` = '%u' WHERE `guid`='%u'",auction->bidder,pItem->GetGUIDLow());
+        CharacterDatabase.CommitTransaction();
+
+        objmgr.RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
+        delete pItem;
+      }
+      // receiver not exist
+      else
+      {
         CharacterDatabase.PExecute("DELETE FROM `item_instance` WHERE `guid`='%u'", pItem->GetGUIDLow());
         objmgr.RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
         delete pItem;
-    }
+      }
 }
 
 //call this method to send mail to auction owner, when auction is successful, it does not clear ram
Index: src/framework/Utilities/Callback.h
===================================================================
--- src/framework/Utilities/Callback.h	(révision 5105)
+++ src/framework/Utilities/Callback.h	(copie de travail)
@@ -23,10 +23,31 @@
 
 namespace MaNGOS
 {
-    template < class Class, typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void, typename ParamType4 = void >
+
+    template < class Class, typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void, typename ParamType4 = void, typename ParamType5 = void >
     class _Callback
     {
         protected:
+            typedef void (Class::*Method)(ParamType1, ParamType2, ParamType3, ParamType4, ParamType5);
+            Class *m_object;
+            Method m_method;
+            ParamType1 m_param1;
+            ParamType2 m_param2;
+            ParamType3 m_param3;
+            ParamType4 m_param4;
+            ParamType5 m_param5;
+            void _Execute() { (m_object->*m_method)(m_param1, m_param2, m_param3, m_param4, m_param5); }
+        public:
+            _Callback(Class *object, Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3, ParamType4 param4, ParamType5 param5)
+                : m_object(object), m_method(method), m_param1(param1), m_param2(param2), m_param3(param3), m_param4(param4), m_param5(param5) {}
+            _Callback(_Callback < Class, ParamType1, ParamType2, ParamType3, ParamType4, ParamType5> const& cb)
+                : m_object(cb.object), 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), m_param5(cb.m_param5) {}
+    };
+
+    template < class Class, typename ParamType1, typename ParamType2, typename ParamType3, typename ParamType4 >
+    class _Callback < Class, ParamType1, ParamType2, ParamType3, ParamType4 >
+    {
+        protected:
             typedef void (Class::*Method)(ParamType1, ParamType2, ParamType3, ParamType4);
             Class *m_object;
             Method m_method;
@@ -38,10 +59,11 @@
         public:
             _Callback(Class *object, Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3, ParamType4 param4)
                 : m_object(object), m_method(method), m_param1(param1), m_param2(param2), m_param3(param3), m_param4(param4) {}
-            _Callback(_Callback < Class, ParamType1, ParamType2, ParamType3, ParamType4> const& cb)
-                : m_object(cb.object), 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) {}
+            _Callback(_Callback < Class, ParamType1, ParamType2, ParamType3, ParamType4 > const& cb)
+                : m_object(cb.m_object), 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 < class Class, typename ParamType1, typename ParamType2, typename ParamType3 >
     class _Callback < Class, ParamType1, ParamType2, ParamType3 >
     {
@@ -55,9 +77,9 @@
             void _Execute() { (m_object->*m_method)(m_param1, m_param2, m_param3); }
         public:
             _Callback(Class *object, Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3)
-                : m_object(object), m_method(method), m_param1(param1), m_param2(param2) {}
+                : m_object(object), m_method(method), m_param1(param1), m_param2(param2), m_param3(param3) {}
             _Callback(_Callback < Class, ParamType1, ParamType2, ParamType3 > const& cb)
-                : m_object(cb.object), m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3) {}
+                : m_object(cb.m_object), m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3) {}
     };
 
     template < class Class, typename ParamType1, typename ParamType2 >
@@ -208,12 +230,26 @@
             QueryResult* GetResult() { return CB::m_param1; }
     };
 
-    template < class Class, typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void >
+
+    template < class Class, typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void, typename ParamType4 = void >
     class QueryCallback :
+        public _IQueryCallback< _Callback < Class, QueryResult*, ParamType1, ParamType2, ParamType3, ParamType4 > >
+    {
+        private:
+            typedef _Callback < Class, QueryResult*, ParamType1, ParamType2, ParamType3, ParamType4 > QC4;
+        public:
+            QueryCallback(Class *object, typename QC4::Method method, QueryResult* result, ParamType1 param1, ParamType2 param2, ParamType3 param3, ParamType4 param4)
+                : _IQueryCallback< QC4 >(QC4(object, method, result, param1, param2, param3, param4)) {}
+    };
+	
+	
+
+    template < class Class, typename ParamType1, typename ParamType2, typename ParamType3 >
+    class QueryCallback < Class, ParamType1, ParamType2, ParamType3 > :
         public _IQueryCallback< _Callback < Class, QueryResult*, ParamType1, ParamType2, ParamType3 > >
     {
         private:
-            typedef _Callback < Class, QueryResult*, ParamType1, ParamType2, ParamType3 > QC3;
+            typedef _Callback < Class, QueryResult*, ParamType1, ParamType2, ParamType3> QC3;
         public:
             QueryCallback(Class *object, typename QC3::Method method, QueryResult* result, ParamType1 param1, ParamType2 param2, ParamType3 param3)
                 : _IQueryCallback< QC3 >(QC3(object, method, result, param1, param2, param3)) {}