diff options
-rwxr-xr-x | src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp | 39 | ||||
-rwxr-xr-x | src/server/game/Server/WorldSession.h | 7 | ||||
-rwxr-xr-x | src/server/shared/Threading/Callback.h | 118 |
3 files changed, 109 insertions, 55 deletions
diff --git a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp index 017fd5a78ad..2a4e1c50ac5 100755 --- a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp @@ -394,7 +394,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte This is much more efficient than synchronous requests on packet handler, and much less DoS prone. It also prevents data syncrhonisation errors. */ - switch (createInfo->Stage) + switch (_charCreateCallback.GetStage()) { case 0: { @@ -404,8 +404,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte data << uint8(CHAR_CREATE_NAME_IN_USE); SendPacket(&data); delete createInfo; - _charCreateCallback.SetParam(NULL); - _charCreateCallback.FreeResult(); + _charCreateCallback.Reset(); return; } @@ -416,8 +415,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte _charCreateCallback.FreeResult(); _charCreateCallback.SetFutureResult(LoginDatabase.AsyncQuery(stmt)); - - createInfo->Stage++; + _charCreateCallback.NextStage(); } break; case 1: @@ -438,8 +436,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte data << uint8(CHAR_CREATE_ACCOUNT_LIMIT); SendPacket(&data); delete createInfo; - _charCreateCallback.SetParam(NULL); - _charCreateCallback.FreeResult(); + _charCreateCallback.Reset(); return; } @@ -451,8 +448,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte _charCreateCallback.FreeResult(); _charCreateCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt)); - - createInfo->Stage++; + _charCreateCallback.NextStage(); } break; case 2: @@ -468,8 +464,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte data << uint8(CHAR_CREATE_SERVER_LIMIT); SendPacket(&data); delete createInfo; - _charCreateCallback.SetParam(NULL); - _charCreateCallback.FreeResult(); + _charCreateCallback.Reset(); return; } } @@ -485,11 +480,11 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte stmt->setUInt32(0, GetAccountId()); stmt->setUInt32(1, (skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT) ? 10 : 1); _charCreateCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt)); - createInfo->Stage++; + _charCreateCallback.NextStage(); return; } - createInfo->Stage++; + _charCreateCallback.NextStage(); HandleCharCreateCallback(PreparedQueryResult(NULL), createInfo); // Will jump to case 3 } break; @@ -523,8 +518,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte data << uint8(CHAR_CREATE_UNIQUE_CLASS_LIMIT); SendPacket(&data); delete createInfo; - _charCreateCallback.SetParam(NULL); - _charCreateCallback.FreeResult(); + _charCreateCallback.Reset(); return; } } @@ -551,8 +545,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte data << uint8(CHAR_CREATE_PVP_TEAMS_VIOLATION); SendPacket(&data); delete createInfo; - _charCreateCallback.SetParam(NULL); - _charCreateCallback.FreeResult(); + _charCreateCallback.Reset(); return; } } @@ -584,8 +577,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte data << uint8(CHAR_CREATE_UNIQUE_CLASS_LIMIT); SendPacket(&data); delete createInfo; - _charCreateCallback.SetParam(NULL); - _charCreateCallback.FreeResult(); + _charCreateCallback.Reset(); return; } } @@ -606,8 +598,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte data << uint8(CHAR_CREATE_LEVEL_REQUIREMENT); SendPacket(&data); delete createInfo; - _charCreateCallback.SetParam(NULL); - _charCreateCallback.FreeResult(); + _charCreateCallback.Reset(); return; } @@ -628,8 +619,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte data << uint8(CHAR_CREATE_ERROR); SendPacket(&data); delete createInfo; - _charCreateCallback.SetParam(NULL); - _charCreateCallback.FreeResult(); + _charCreateCallback.Reset(); return; } @@ -670,8 +660,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte sWorld->AddCharacterNameData(newChar.GetGUIDLow(), std::string(newChar.GetName()), newChar.getGender(), newChar.getRace(), newChar.getClass()); delete createInfo; - _charCreateCallback.SetParam(NULL); - _charCreateCallback.FreeResult(); + _charCreateCallback.Reset(); } break; } diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 5f36dbc9547..d1f607704b9 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -184,7 +184,7 @@ class CharacterCreateInfo protected: CharacterCreateInfo(std::string name, uint8 race, uint8 cclass, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair, uint8 outfitId, WorldPacket& data) : Name(name), Race(race), Class(cclass), Gender(gender), Skin(skin), Face(face), HairStyle(hairStyle), HairColor(hairColor), FacialHair(facialHair), - OutfitId(outfitId), Data(data), CharCount(0), Stage(0) + OutfitId(outfitId), Data(data), CharCount(0) {} /// User specified variables @@ -203,9 +203,6 @@ class CharacterCreateInfo /// Server side data uint8 CharCount; - /// Internal - uint8 Stage; // Stage of the callback chain - private: virtual ~CharacterCreateInfo(){}; }; @@ -904,7 +901,7 @@ class WorldSession QueryCallback<QueryResult, uint32> _unstablePetCallback; QueryCallback<QueryResult, uint32> _stableSwapCallback; QueryCallback<QueryResult, uint64> _sendStabledPetCallback; - QueryCallback<PreparedQueryResult, CharacterCreateInfo*> _charCreateCallback; + QueryCallback<PreparedQueryResult, CharacterCreateInfo*, true> _charCreateCallback; QueryResultHolderFuture _charLoginCallback; private: diff --git a/src/server/shared/Threading/Callback.h b/src/server/shared/Threading/Callback.h index f8c3118ec8e..809dba729d3 100755 --- a/src/server/shared/Threading/Callback.h +++ b/src/server/shared/Threading/Callback.h @@ -29,109 +29,177 @@ typedef ACE_Future<PreparedQueryResult> PreparedQueryResultFuture; issued the request. <ParamType> is variable type of parameter that is used as parameter for the callback function. */ -template <typename Result, typename ParamType> +#define CALLBACK_STAGE_INVALID uint8(-1) + +template <typename Result, typename ParamType, bool chain = false> class QueryCallback { public: - QueryCallback() {} + QueryCallback() : _stage(chain ? 0 : CALLBACK_STAGE_INVALID) {} //! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery void SetFutureResult(ACE_Future<Result> value) { - result = value; + _result = value; } ACE_Future<Result> GetFutureResult() { - return result; + return _result; } int IsReady() { - return result.ready(); + return _result.ready(); } void GetResult(Result& res) { - result.get(res); + _result.get(res); } void FreeResult() { - result.cancel(); + _result.cancel(); } void SetParam(ParamType value) { - param = value; + _param = value; } ParamType GetParam() { - return param; + return _param; + } + + //! Resets the stage of the callback chain + void ResetStage() + { + if (!chain) + return; + + _stage = 0; + } + + //! Advances the callback chain to the next stage, so upper level code can act on its results accordingly + void NextStage() + { + if (!chain) + return; + + ++_stage; + } + + //! Returns the callback stage (or CALLBACK_STAGE_INVALID if invalid) + uint8 GetStage() + { + return _stage; + } + + //! Resets all underlying variables (param, result and stage) + void Reset() + { + SetParam(NULL); + FreeResult(); + ResetStage(); } private: - ACE_Future<Result> result; - ParamType param; + ACE_Future<Result> _result; + ParamType _param; + uint8 _stage; }; -template <typename Result, typename ParamType1, typename ParamType2> +template <typename Result, typename ParamType1, typename ParamType2, bool chain = false> class QueryCallback_2 { public: - QueryCallback_2() {} + QueryCallback_2() : _stage(chain ? 0 : CALLBACK_STAGE_INVALID) {} //! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery void SetFutureResult(ACE_Future<Result> value) { - result = value; + _result = value; } ACE_Future<Result> GetFutureResult() { - return result; + return _result; } int IsReady() { - return result.ready(); + return _result.ready(); } void GetResult(Result& res) { - result.get(res); + _result.get(res); } void FreeResult() { - result.cancel(); + _result.cancel(); } void SetFirstParam(ParamType1 value) { - param_1 = value; + _param_1 = value; } void SetSecondParam(ParamType2 value) { - param_2 = value; + _param_2 = value; } ParamType1 GetFirstParam() { - return param_1; + return _param_1; } ParamType2 GetSecondParam() { - return param_2; + return _param_2; + } + + //! Resets the stage of the callback chain + void ResetStage() + { + if (!chain) + return; + + _stage = 0; + } + + //! Advances the callback chain to the next stage, so upper level code can act on its results accordingly + void NextStage() + { + if (!chain) + return; + + ++_stage; + } + + //! Returns the callback stage (or CALLBACK_STAGE_INVALID if invalid) + uint8 GetStage() + { + return _stage; + } + + //! Resets all underlying variables (param, result and stage) + void Reset() + { + SetParam(NULL); + FreeResult(); + ResetStage(); } private: - ACE_Future<Result> result; - ParamType1 param_1; - ParamType2 param_2; + ACE_Future<Result> _result; + ParamType1 _param_1; + ParamType2 _param_2; + uint8 _stage; }; #endif
\ No newline at end of file |