From 09f2a1f64d8fa4beded58cdb2f61ac809ed7f46a Mon Sep 17 00:00:00 2001 From: Olion Date: Sat, 24 Jun 2017 15:57:46 +0300 Subject: [PATCH 01/14] DetailsEmote for quests (SMSG packet structure) --- src/game/WorldHandlers/GossipDef.cpp | 27 ++++++++++++--------------- src/game/WorldHandlers/QuestDef.cpp | 7 ++++++- src/game/WorldHandlers/QuestDef.h | 2 ++ 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/game/WorldHandlers/GossipDef.cpp b/src/game/WorldHandlers/GossipDef.cpp index 70175d32..6a189461 100644 --- a/src/game/WorldHandlers/GossipDef.cpp +++ b/src/game/WorldHandlers/GossipDef.cpp @@ -457,9 +457,10 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* pQuest, ObjectGuid guid { ItemPrototype const* IProto; - data << uint32(pQuest->GetRewChoiceItemsCount()); + uint32 count = pQuest->GetRewChoiceItemsCount(); + data << uint32(count); - for (uint32 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i) + for (uint32 i = 0; i < count; ++i) { data << uint32(pQuest->RewChoiceItemId[i]); data << uint32(pQuest->RewChoiceItemCount[i]); @@ -472,9 +473,10 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* pQuest, ObjectGuid guid { data << uint32(0x00); } } - data << uint32(pQuest->GetRewItemsCount()); + count = pQuest->GetRewItemsCount(); + data << uint32(count); - for (uint32 i = 0; i < QUEST_REWARDS_COUNT; ++i) + for (uint32 i = 0; i < count; ++i) { data << uint32(pQuest->RewItemId[i]); data << uint32(pQuest->RewItemCount[i]); @@ -490,19 +492,14 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* pQuest, ObjectGuid guid data << uint32(pQuest->GetRewOrReqMoney()); } - data << pQuest->GetReqItemsCount(); - for (uint32 i = 0; i < QUEST_OBJECTIVES_COUNT; i++) - { - data << pQuest->ReqItemId[i]; - data << pQuest->ReqItemCount[i]; - } + data << uint32(pQuest->GetRewSpell()); - - data << pQuest->GetReqCreatureOrGOcount(); - for (uint32 i = 0; i < QUEST_OBJECTIVES_COUNT; i++) + uint32 count = pQuest->GetDetailsEmoteCount(); + data << uint32(count); + for (uint32 i = 0; i < count; ++i) { - data << uint32(pQuest->ReqCreatureOrGOId[i]); - data << pQuest->ReqCreatureOrGOCount[i]; + data << uint32(pQuest->DetailsEmote[i]); + data << uint32(pQuest->DetailsEmoteDelay[i]); // delay between emotes in ms } GetMenuSession()->SendPacket(&data); diff --git a/src/game/WorldHandlers/QuestDef.cpp b/src/game/WorldHandlers/QuestDef.cpp index 59a004ba..dde56a18 100644 --- a/src/game/WorldHandlers/QuestDef.cpp +++ b/src/game/WorldHandlers/QuestDef.cpp @@ -115,8 +115,13 @@ Quest::Quest(Field* questRecord) PointY = questRecord[103].GetFloat(); PointOpt = questRecord[104].GetUInt32(); + m_detailsemotecount = 0; for (int i = 0; i < QUEST_EMOTE_COUNT; ++i) - { DetailsEmote[i] = questRecord[105 + i].GetUInt32(); } + { + DetailsEmote[i] = questRecord[105 + i].GetUInt32(); + if (DetailsEmote[i] != 0) + m_detailsemotecount = i + 1; + } for (int i = 0; i < QUEST_EMOTE_COUNT; ++i) { DetailsEmoteDelay[i] = questRecord[109 + i].GetUInt32(); } diff --git a/src/game/WorldHandlers/QuestDef.h b/src/game/WorldHandlers/QuestDef.h index 9676eac5..65734e9c 100644 --- a/src/game/WorldHandlers/QuestDef.h +++ b/src/game/WorldHandlers/QuestDef.h @@ -249,6 +249,7 @@ class Quest uint32 GetPointOpt() const { return PointOpt; } uint32 GetIncompleteEmote() const { return IncompleteEmote; } uint32 GetCompleteEmote() const { return CompleteEmote; } + uint32 GetDetailsEmoteCount() const { return m_detailsemotecount; } uint32 GetQuestStartScript() const { return QuestStartScript; } uint32 GetQuestCompleteScript() const { return QuestCompleteScript; } @@ -296,6 +297,7 @@ class Quest uint32 m_reqCreatureOrGOcount; uint32 m_rewchoiceitemscount; uint32 m_rewitemscount; + uint32 m_detailsemotecount; // actual allowed value 0..4 bool m_isActive; From ef7fa1acde08cee12a0c7f2156e28c159e1551cd Mon Sep 17 00:00:00 2001 From: Olion Date: Sun, 25 Jun 2017 01:02:18 +0300 Subject: [PATCH 02/14] Prevent Racial leaders PvP dropping due to faction rules --- src/game/Object/Creature.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/game/Object/Creature.cpp b/src/game/Object/Creature.cpp index f5324364..c5fc9267 100644 --- a/src/game/Object/Creature.cpp +++ b/src/game/Object/Creature.cpp @@ -456,7 +456,8 @@ bool Creature::UpdateEntry(uint32 Entry, Team team, const CreatureData* data /*= if (factionTemplate->factionFlags & FACTION_TEMPLATE_FLAG_PVP) SetPvP(true); else - SetPvP(false); + if (!IsRacialLeader()) + SetPvP(false); } // Try difficulty dependend version before falling back to base entry From 171e825695e1db8316b02911b013fd5575640f88 Mon Sep 17 00:00:00 2001 From: Olion Date: Sun, 25 Jun 2017 01:12:13 +0300 Subject: [PATCH 03/14] Racial Leaders (SMSG packet structure) --- src/game/WorldHandlers/QueryHandler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/game/WorldHandlers/QueryHandler.cpp b/src/game/WorldHandlers/QueryHandler.cpp index 751f875d..01e8bcc0 100644 --- a/src/game/WorldHandlers/QueryHandler.cpp +++ b/src/game/WorldHandlers/QueryHandler.cpp @@ -165,7 +165,8 @@ void WorldSession::HandleCreatureQueryOpcode(WorldPacket& recv_data) else { data << uint32(Creature::ChooseDisplayId(ci)); } // workaround, way to manage models must be fixed - data << uint16(ci->civilian); // wdbFeild14 + data << uint8(ci->civilian); // wdbFeild14 + data << uint8(ci->RacialLeader); SendPacket(&data); DEBUG_LOG("WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE"); } From 6da4dcf7229600cf2d73bf5f2d215b82faa5eb94 Mon Sep 17 00:00:00 2001 From: Olion Date: Tue, 27 Jun 2017 21:43:28 +0300 Subject: [PATCH 04/14] MSG_QUEST_PUSH_RESULT packet structure fix --- src/game/ChatCommands/debugcmds.cpp | 4 +++- src/game/Object/Player.cpp | 7 +++---- src/game/Object/Player.h | 2 +- src/game/Server/Opcodes.cpp | 2 +- src/game/WorldHandlers/QuestHandler.cpp | 5 ++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/game/ChatCommands/debugcmds.cpp b/src/game/ChatCommands/debugcmds.cpp index 3a07f8dd..6e462733 100644 --- a/src/game/ChatCommands/debugcmds.cpp +++ b/src/game/ChatCommands/debugcmds.cpp @@ -309,8 +309,10 @@ bool ChatHandler::HandleDebugSendQuestPartyMsgCommand(char* args) uint32 msg; if (!ExtractUInt32(&args, msg)) { return false; } + if (msg > 0xFF) + { return false; } - m_session->GetPlayer()->SendPushToPartyResponse(m_session->GetPlayer(), msg); + m_session->GetPlayer()->SendPushToPartyResponse(m_session->GetPlayer(), uint8(msg)); return true; } diff --git a/src/game/Object/Player.cpp b/src/game/Object/Player.cpp index a9d20dcb..c41dacd9 100644 --- a/src/game/Object/Player.cpp +++ b/src/game/Object/Player.cpp @@ -13742,14 +13742,13 @@ void Player::SendQuestConfirmAccept(const Quest* pQuest, Player* pReceiver) } } -void Player::SendPushToPartyResponse(Player* pPlayer, uint32 msg) +void Player::SendPushToPartyResponse(Player* pPlayer, uint8 msg) { if (pPlayer) { - WorldPacket data(MSG_QUEST_PUSH_RESULT, (8 + 4 + 1)); + WorldPacket data(MSG_QUEST_PUSH_RESULT, (8 + 1)); data << pPlayer->GetObjectGuid(); - data << uint32(msg); // valid values: 0-8 - data << uint8(0); + data << uint8(msg); // enum QuestShareMessages GetSession()->SendPacket(&data); DEBUG_LOG("WORLD: Sent MSG_QUEST_PUSH_RESULT"); } diff --git a/src/game/Object/Player.h b/src/game/Object/Player.h index 921c533e..5e2c0826 100644 --- a/src/game/Object/Player.h +++ b/src/game/Object/Player.h @@ -1385,7 +1385,7 @@ class Player : public Unit void SendQuestTimerFailed(uint32 quest_id); void SendCanTakeQuestResponse(uint32 msg) const; void SendQuestConfirmAccept(Quest const* pQuest, Player* pReceiver); - void SendPushToPartyResponse(Player* pPlayer, uint32 msg); + void SendPushToPartyResponse(Player* pPlayer, uint8 msg); void SendQuestUpdateAddItem(Quest const* pQuest, uint32 item_idx, uint32 count); void SendQuestUpdateAddCreatureOrGo(Quest const* pQuest, ObjectGuid guid, uint32 creatureOrGO_idx, uint32 count); diff --git a/src/game/Server/Opcodes.cpp b/src/game/Server/Opcodes.cpp index 16a815fa..a37e6dd0 100644 --- a/src/game/Server/Opcodes.cpp +++ b/src/game/Server/Opcodes.cpp @@ -688,7 +688,7 @@ void Opcodes::BuildOpcodeList() /*[-ZERO] Need check */ /*0x273*/ StoreOpcode(SMSG_STABLE_RESULT, "SMSG_STABLE_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x274*/ StoreOpcode(CMSG_STABLE_REVIVE_PET, "CMSG_STABLE_REVIVE_PET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStableRevivePet); /*0x275*/ StoreOpcode(CMSG_STABLE_SWAP_PET, "CMSG_STABLE_SWAP_PET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStableSwapPet); - /*[-ZERO] Need check */ /*0x276*/ StoreOpcode(MSG_QUEST_PUSH_RESULT, "MSG_QUEST_PUSH_RESULT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPushResult); + /*0x276*/ StoreOpcode(MSG_QUEST_PUSH_RESULT, "MSG_QUEST_PUSH_RESULT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPushResult); /*[-ZERO] Need check */ /*0x277*/ StoreOpcode(SMSG_PLAY_MUSIC, "SMSG_PLAY_MUSIC", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x278*/ StoreOpcode(SMSG_PLAY_OBJECT_SOUND, "SMSG_PLAY_OBJECT_SOUND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x279*/ StoreOpcode(CMSG_REQUEST_PET_INFO, "CMSG_REQUEST_PET_INFO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPetInfoOpcode); diff --git a/src/game/WorldHandlers/QuestHandler.cpp b/src/game/WorldHandlers/QuestHandler.cpp index f1e74638..c11d239c 100644 --- a/src/game/WorldHandlers/QuestHandler.cpp +++ b/src/game/WorldHandlers/QuestHandler.cpp @@ -489,10 +489,9 @@ void WorldSession::HandleQuestPushResult(WorldPacket& recvPacket) if (Player* pPlayer = ObjectAccessor::FindPlayer(_player->GetDividerGuid())) { - WorldPacket data(MSG_QUEST_PUSH_RESULT, (8 + 4 + 1)); + WorldPacket data(MSG_QUEST_PUSH_RESULT, (8 + 1)); data << ObjectGuid(guid); - data << uint32(msg); // valid values: 0-8 - data << uint8(0); + data << uint8(msg); // enum QuestShareMessages pPlayer->GetSession()->SendPacket(&data); _player->ClearDividerGuid(); } From 96a7a010bcd0f971029043ddc0a1c9bf9e9aedb5 Mon Sep 17 00:00:00 2001 From: Olion Date: Wed, 28 Jun 2017 18:46:39 +0300 Subject: [PATCH 05/14] SMSG_PET_NAME_INVALID contains no data --- src/game/WorldHandlers/PetHandler.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/game/WorldHandlers/PetHandler.cpp b/src/game/WorldHandlers/PetHandler.cpp index 6b4b86fa..cf8e9a19 100644 --- a/src/game/WorldHandlers/PetHandler.cpp +++ b/src/game/WorldHandlers/PetHandler.cpp @@ -695,10 +695,6 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket) void WorldSession::SendPetNameInvalid(uint32 error, const std::string& name) { - // [-ZERO] Need check - WorldPacket data(SMSG_PET_NAME_INVALID, 4 + name.size() + 1 + 1); - data << uint32(error); - data << name; - data << uint8(0); // possible not exist in 1.12.* + WorldPacket data(SMSG_PET_NAME_INVALID, 0); SendPacket(&data); } From 0317133b64a052a8e29f59e0b216551c62b1121f Mon Sep 17 00:00:00 2001 From: Olion Date: Wed, 28 Jun 2017 18:59:11 +0300 Subject: [PATCH 06/14] Use SMSG_GMTICKET_UPDATETEXT; introduce named constants GMTICKET_RESPONCE_ --- src/game/Object/GMTicketMgr.h | 10 ++++++++++ src/game/WorldHandlers/GMTicketHandler.cpp | 21 +++++++++++++++------ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/game/Object/GMTicketMgr.h b/src/game/Object/GMTicketMgr.h index fb27b1cd..2545629e 100644 --- a/src/game/Object/GMTicketMgr.h +++ b/src/game/Object/GMTicketMgr.h @@ -33,6 +33,16 @@ #include "SharedDefines.h" #include +enum GMTicketResponse +{ + GMTICKET_RESPONSE_ALREADY_EXIST = 1, + GMTICKET_RESPONSE_CREATE_SUCCESS = 2, + GMTICKET_RESPONSE_CREATE_ERROR = 3, + GMTICKET_RESPONSE_UPDATE_SUCCESS = 4, + GMTICKET_RESPONSE_UPDATE_ERROR = 5, + GMTICKET_RESPONSE_TICKET_DELETED = 9 +}; + /** * \addtogroup game * @{ diff --git a/src/game/WorldHandlers/GMTicketHandler.cpp b/src/game/WorldHandlers/GMTicketHandler.cpp index 5de56ab9..6be4a48b 100644 --- a/src/game/WorldHandlers/GMTicketHandler.cpp +++ b/src/game/WorldHandlers/GMTicketHandler.cpp @@ -78,11 +78,20 @@ void WorldSession::HandleGMTicketUpdateTextOpcode(WorldPacket& recv_data) std::string ticketText; recv_data >> ticketText; + GMTicketResponse responce = GMTICKET_RESPONSE_UPDATE_SUCCESS; if (GMTicket* ticket = sTicketMgr.GetGMTicket(GetPlayer()->GetObjectGuid())) - { ticket->SetText(ticketText.c_str()); } + { + ticket->SetText(ticketText.c_str()); + } else - { sLog.outError("Ticket update: Player %s (GUID: %u) doesn't have active ticket", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow()); } - + { + sLog.outError("Ticket update: Player %s (GUID: %u) doesn't have active ticket", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow()); + responce = GMTICKET_RESPONSE_UPDATE_ERROR; + } + + WorldPacket data(SMSG_GMTICKET_UPDATETEXT, 4); + data << uint32(responce); + SendPacket(&data); } //A statusCode of 3 would mean that the client should show the survey now @@ -102,7 +111,7 @@ void WorldSession::HandleGMTicketDeleteTicketOpcode(WorldPacket& /*recv_data*/) sTicketMgr.Delete(GetPlayer()->GetObjectGuid()); WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4); - data << uint32(9); + data << uint32(GMTICKET_RESPONSE_TICKET_DELETED); SendPacket(&data); SendGMTicketGetTicket(0x0A); @@ -126,7 +135,7 @@ void WorldSession::HandleGMTicketCreateOpcode(WorldPacket& recv_data) if (sTicketMgr.GetGMTicket(GetPlayer()->GetObjectGuid())) { WorldPacket data(SMSG_GMTICKET_CREATE, 4); - data << uint32(1); // 1 - You already have GM ticket + data << uint32(GMTICKET_RESPONSE_ALREADY_EXIST); // 1 - You already have GM ticket SendPacket(&data); return; } @@ -136,7 +145,7 @@ void WorldSession::HandleGMTicketCreateOpcode(WorldPacket& recv_data) SendQueryTimeResponse(); WorldPacket data(SMSG_GMTICKET_CREATE, 4); - data << uint32(2); // 2 - nothing appears (3-error creating, 5-error updating) + data << uint32(GMTICKET_RESPONSE_CREATE_SUCCESS); // 2 - nothing appears (3-error creating, 5-error updating) SendPacket(&data); // TODO: Guard player map From 43a5be52b0499817d13bc1d7cdf959667eb841b8 Mon Sep 17 00:00:00 2001 From: Olion Date: Wed, 28 Jun 2017 19:01:04 +0300 Subject: [PATCH 07/14] Corrected values of constants for SMSG_RAID_GROUP_ONLY --- src/game/Object/Player.cpp | 4 ++-- src/game/Object/Player.h | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/game/Object/Player.cpp b/src/game/Object/Player.cpp index c41dacd9..2338a9d6 100644 --- a/src/game/Object/Player.cpp +++ b/src/game/Object/Player.cpp @@ -17464,7 +17464,7 @@ void Player::UpdateHomebindTime(uint32 time) // hide reminder WorldPacket data(SMSG_RAID_GROUP_ONLY, 4 + 4); data << uint32(0); - data << uint32(ERR_RAID_GROUP_NONE); // error used only when timer = 0 + data << uint32(ERR_RAID_GROUP_REQUIRED); // error used only when timer = 0 GetSession()->SendPacket(&data); } // instance is valid, reset homebind timer @@ -17487,7 +17487,7 @@ void Player::UpdateHomebindTime(uint32 time) // send message to player WorldPacket data(SMSG_RAID_GROUP_ONLY, 4 + 4); data << uint32(m_HomebindTimer); - data << uint32(ERR_RAID_GROUP_NONE); // error used only when timer = 0 + data << uint32(ERR_RAID_GROUP_REQUIRED); // error used only when timer = 0 GetSession()->SendPacket(&data); DEBUG_LOG("PLAYER: Player '%s' (GUID: %u) will be teleported to homebind in 60 seconds", GetName(), GetGUIDLow()); } diff --git a/src/game/Object/Player.h b/src/game/Object/Player.h index 5e2c0826..c4f6d7c6 100644 --- a/src/game/Object/Player.h +++ b/src/game/Object/Player.h @@ -330,11 +330,13 @@ typedef std::list ItemDurationList; enum RaidGroupError { - ERR_RAID_GROUP_NONE = 0, - ERR_RAID_GROUP_LOWLEVEL = 1, - ERR_RAID_GROUP_ONLY = 2, - ERR_RAID_GROUP_FULL = 3, - ERR_RAID_GROUP_REQUIREMENTS_UNMATCH = 4 + ERR_RAID_GROUP_REQUIRED = 1, + ERR_RAID_GROUP_FULL = 2 + //ERR_RAID_GROUP_NONE = 0, + //ERR_RAID_GROUP_LOWLEVEL = 1, + //ERR_RAID_GROUP_ONLY = 2, + //ERR_RAID_GROUP_FULL = 3, + //ERR_RAID_GROUP_REQUIREMENTS_UNMATCH = 4 }; enum DrunkenState From 5128b38050b8f8a20482079cb8bc14d7c4fa8974 Mon Sep 17 00:00:00 2001 From: Olion Date: Wed, 28 Jun 2017 19:03:02 +0300 Subject: [PATCH 08/14] Refactoring of #14 --- src/game/Object/SpellMgr.cpp | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/game/Object/SpellMgr.cpp b/src/game/Object/SpellMgr.cpp index 20b0e98a..c9599a72 100644 --- a/src/game/Object/SpellMgr.cpp +++ b/src/game/Object/SpellMgr.cpp @@ -904,16 +904,6 @@ bool IsPositiveSpell(SpellEntry const* spellproto) bool IsSingleTargetSpell(SpellEntry const* spellInfo) { - switch (spellInfo->Id) - { - case 339: // Druid Roots Rank 1 - case 1062: // Druid Roots Rank 2 - case 5195: // Druid Roots Rank 3 - case 5196: // Druid Roots Rank 4 - case 9852: // Druid Roots Rank 5 - case 9853: // Druid Roots Rank 6 - return true; - } // hunter's mark and similar if (spellInfo->SpellVisual == 3239) { return true; } @@ -943,19 +933,21 @@ bool IsSingleTargetSpell(SpellEntry const* spellInfo) case 24664: // Sleep (group targets) return false; } - // can not be cast on another target while not cooled down anyway - if (GetSpellDuration(spellInfo) < int32(GetSpellRecoveryTime(spellInfo))) - { return false; } - // all other single target spells have if it has AttributesEx - if (spellInfo->AttributesEx & (1 << 18)) + if (spellInfo->HasAttribute(SPELL_ATTR_EX_UNK18)) { return true; } + // can not be cast on another target while not cooled down anyway + //if (GetSpellDuration(spellInfo) < int32(GetSpellRecoveryTime(spellInfo))) + // { return true; } + // other single target // Fear if ((spellInfo->SpellIconID == 98 && spellInfo->SpellVisual == 336) // Banish || (spellInfo->SpellIconID == 96 && spellInfo->SpellVisual == 1305) + // Entangling roots + || spellInfo->IsFitToFamily(SPELLFAMILY_DRUID, ClassFamilyMask(UI64LIT(0x0200))) ) { return true; } // TODO - need found Judgements rule From 3a7e0253c12eca31774beb61a898a56ca5a636ef Mon Sep 17 00:00:00 2001 From: Olion Date: Wed, 28 Jun 2017 19:37:09 +0300 Subject: [PATCH 09/14] SMSG_OPEN_CONTAINER implemented --- src/game/Object/Player.cpp | 8 ++++++++ src/game/Object/Player.h | 1 + 2 files changed, 9 insertions(+) diff --git a/src/game/Object/Player.cpp b/src/game/Object/Player.cpp index 2338a9d6..0569bc54 100644 --- a/src/game/Object/Player.cpp +++ b/src/game/Object/Player.cpp @@ -11212,6 +11212,14 @@ void Player::SendEquipError(InventoryResult msg, Item* pItem, Item* pItem2, uint GetSession()->SendPacket(&data); } +void Player::SendOpenContainer() +{ + DEBUG_LOG("WORLD: Sent SMSG_OPEN_CONTAINER"); + WorldPacket data(SMSG_OPEN_CONTAINER, 8); // opens the main bag in the UI + data << GetObjectGuid(); + GetSession()->SendPacket(&data); +} + void Player::SendBuyError(BuyResult msg, Creature* pCreature, uint32 item, uint32 param) { DEBUG_LOG("WORLD: Sent SMSG_BUY_FAILED"); diff --git a/src/game/Object/Player.h b/src/game/Object/Player.h index c4f6d7c6..a9b65618 100644 --- a/src/game/Object/Player.h +++ b/src/game/Object/Player.h @@ -1222,6 +1222,7 @@ class Player : public Unit void SendEquipError(InventoryResult msg, Item* pItem, Item* pItem2 = NULL, uint32 itemid = 0) const; void SendBuyError(BuyResult msg, Creature* pCreature, uint32 item, uint32 param); void SendSellError(SellResult msg, Creature* pCreature, ObjectGuid itemGuid, uint32 param); + void SendOpenContainer(); void AddWeaponProficiency(uint32 newflag) { m_WeaponProficiency |= newflag; From 2eaea4fba97eb4c4209210009dd07ff6d35d63a5 Mon Sep 17 00:00:00 2001 From: bdebaere Date: Thu, 29 Jun 2017 01:22:20 +0200 Subject: [PATCH 10/14] Add IsSeatedState() to handle AURA_INTERRUPT_FLAG_NOT_SEATED. * Update Unit.cpp Add IsSeatedState() to handle AURA_INTERRUPT_FLAG_NOT_SEATED. * Update Unit.h Add IsSeatedState() to handle AURA_INTERRUPT_FLAG_NOT_SEATED. * Update Unit.cpp Pointer reference --- src/game/Object/Unit.cpp | 10 ++++++++-- src/game/Object/Unit.h | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/game/Object/Unit.cpp b/src/game/Object/Unit.cpp index 9a46b40d..2713f400 100644 --- a/src/game/Object/Unit.cpp +++ b/src/game/Object/Unit.cpp @@ -8801,12 +8801,18 @@ bool Unit::IsStandState() const return !IsSitState() && s != UNIT_STAND_STATE_SLEEP && s != UNIT_STAND_STATE_KNEEL; } +bool Unit::IsSeatedState() const +{ + uint8 standState = getStandState(); + return standState != UNIT_STAND_STATE_SLEEP && standState != UNIT_STAND_STATE_STAND; +} + void Unit::SetStandState(uint8 state) { SetByteValue(UNIT_FIELD_BYTES_1, 0, state); - if (IsStandState()) - { RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_NOT_SEATED); } + if (!IsSeatedState()) + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_NOT_SEATED); if (GetTypeId() == TYPEID_PLAYER) { diff --git a/src/game/Object/Unit.h b/src/game/Object/Unit.h index f42c3ccf..110a3184 100644 --- a/src/game/Object/Unit.h +++ b/src/game/Object/Unit.h @@ -1785,6 +1785,8 @@ class Unit : public WorldObject * @return true if the Unit is standing normally, false otherwise */ bool IsStandState() const; + + bool IsSeatedState() const; /** * Change the stand state for this Unit. For possible values check * UnitStandStateType. From c3d42291b558dc255de31c308db794e0edb20501 Mon Sep 17 00:00:00 2001 From: Olion Date: Thu, 29 Jun 2017 20:26:09 +0300 Subject: [PATCH 11/14] Refactoring Mount/Unmount: code split between Unit and Player --- src/game/Object/Player.cpp | 51 ++++++++++++++++++++++++++++++++++++++ src/game/Object/Player.h | 2 ++ src/game/Object/Unit.cpp | 33 ------------------------ src/game/Object/Unit.h | 4 +-- 4 files changed, 55 insertions(+), 35 deletions(-) diff --git a/src/game/Object/Player.cpp b/src/game/Object/Player.cpp index 0569bc54..2d0a0803 100644 --- a/src/game/Object/Player.cpp +++ b/src/game/Object/Player.cpp @@ -17191,6 +17191,57 @@ void Player::ContinueTaxiFlight() GetSession()->SendDoFlight(mountDisplayId, path, startNode); } +void Player::Mount(uint32 mount, uint32 spellId) +{ + if (!mount) + { return; } + + Unit::Mount(mount, spellId); + + // Called by Taxi system / GM command + if (!spellId) + { + UnsummonPetTemporaryIfAny(); + } + // Called by mount aura + else + { + // Normal case (Unsummon only permanent pet) + if (Pet* pet = GetPet()) + { + if (pet->IsPermanentPetFor((Player*)this) && + sWorld.getConfig(CONFIG_BOOL_PET_UNSUMMON_AT_MOUNT)) + { + UnsummonPetTemporaryIfAny(); + } + else + { + pet->ApplyModeFlags(PET_MODE_DISABLE_ACTIONS, true); + } + } + } +} + +void Player::Unmount(bool from_aura) +{ + if (!IsMounted()) + { return; } + + Unit::Unmount(from_aura); + + // only resummon old pet if the player is already added to a map + // this prevents adding a pet to a not created map which would otherwise cause a crash + // (it could probably happen when logging in after a previous crash) + if (Pet* pet = GetPet()) + { + pet->ApplyModeFlags(PET_MODE_DISABLE_ACTIONS, false); + } + else + { + ResummonPetTemporaryUnSummonedIfAny(); + } +} + void Player::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs) { // last check 1.12 diff --git a/src/game/Object/Player.h b/src/game/Object/Player.h index a9b65618..a9566300 100644 --- a/src/game/Object/Player.h +++ b/src/game/Object/Player.h @@ -992,6 +992,8 @@ class Player : public Unit bool ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid = 0); // mount_id can be used in scripting calls void ContinueTaxiFlight(); + void Mount(uint32 mount, uint32 spellId = 0) override; + void Unmount(bool from_aura = false) override; bool isAcceptTickets() const { return GetSession()->GetSecurity() >= SEC_GAMEMASTER && (m_ExtraFlags & PLAYER_EXTRA_GM_ACCEPT_TICKETS); } void SetAcceptTicket(bool on) { if (on) { m_ExtraFlags |= PLAYER_EXTRA_GM_ACCEPT_TICKETS; } else { m_ExtraFlags &= ~PLAYER_EXTRA_GM_ACCEPT_TICKETS; } } bool isAcceptWhispers() const { return m_ExtraFlags & PLAYER_EXTRA_ACCEPT_WHISPERS; } diff --git a/src/game/Object/Unit.cpp b/src/game/Object/Unit.cpp index 2713f400..9f2eb35e 100644 --- a/src/game/Object/Unit.cpp +++ b/src/game/Object/Unit.cpp @@ -6407,28 +6407,6 @@ void Unit::Mount(uint32 mount, uint32 spellId) RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNTING); SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, mount); - - if (GetTypeId() == TYPEID_PLAYER) - { - // Called by Taxi system / GM command - if (!spellId) - { ((Player*)this)->UnsummonPetTemporaryIfAny(); } - // Called by mount aura - else - { - // Normal case (Unsummon only permanent pet) - if (Pet* pet = GetPet()) - { - if (pet->IsPermanentPetFor((Player*)this) && - sWorld.getConfig(CONFIG_BOOL_PET_UNSUMMON_AT_MOUNT)) - { - ((Player*)this)->UnsummonPetTemporaryIfAny(); - } - else - { pet->ApplyModeFlags(PET_MODE_DISABLE_ACTIONS, true); } - } - } - } } void Unit::Unmount(bool from_aura) @@ -6447,17 +6425,6 @@ void Unit::Unmount(bool from_aura) data << GetPackGUID(); SendMessageToSet(&data, true); } - - // only resummon old pet if the player is already added to a map - // this prevents adding a pet to a not created map which would otherwise cause a crash - // (it could probably happen when logging in after a previous crash) - if (GetTypeId() == TYPEID_PLAYER) - { - if (Pet* pet = GetPet()) - { pet->ApplyModeFlags(PET_MODE_DISABLE_ACTIONS, false); } - else - { ((Player*)this)->ResummonPetTemporaryUnSummonedIfAny(); } - } } bool Unit::IsNearWaypoint(float currentPositionX, float currentPositionY, float currentPositionZ, float destinationPostionX, float destinationPostionY, float destinationPostionZ, float distanceX, float distanceY, float distanceZ) diff --git a/src/game/Object/Unit.h b/src/game/Object/Unit.h index 110a3184..0bc3a258 100644 --- a/src/game/Object/Unit.h +++ b/src/game/Object/Unit.h @@ -1815,7 +1815,7 @@ class Unit : public WorldObject * @param spellId id of the spell used to summon the mount, if 0 is passed in this is treated * as a GM command or the Taxi service mounting the Player. */ - void Mount(uint32 mount, uint32 spellId = 0); + virtual void Mount(uint32 mount, uint32 spellId = 0); /** * Unmounts this Unit by sending the SMSG_DISMOUNT to the client if it was a dismount * not issued by a GM / the Taxi service. Also changes the UNIT_FIELD_MOUNTDISPLAYID @@ -1823,7 +1823,7 @@ class Unit : public WorldObject * @param from_aura if this was true the Unit was probably interrupted by a spell * or something hitting it forcing a dismount. */ - void Unmount(bool from_aura = false); + virtual void Unmount(bool from_aura = false); /** * Returns the maximum skill value the given Unit can have. Ie: the sword skill can From 202bc62be08e4839e5ac04fb4af9f555df1b39dd Mon Sep 17 00:00:00 2001 From: Olion Date: Thu, 29 Jun 2017 20:27:19 +0300 Subject: [PATCH 12/14] Implement SMSG_MOUNTRESULT, SMSG_DISMOUNTRESULT (yet unused) --- src/game/Object/Player.cpp | 14 ++++++++++++++ src/game/Object/Player.h | 25 +++++++++++++++++++++++++ src/game/Server/Opcodes.cpp | 4 ++-- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/game/Object/Player.cpp b/src/game/Object/Player.cpp index 2d0a0803..241cc3cd 100644 --- a/src/game/Object/Player.cpp +++ b/src/game/Object/Player.cpp @@ -17242,6 +17242,20 @@ void Player::Unmount(bool from_aura) } } +void Player::SendMountResult(PlayerMountResult result) +{ + WorldPacket data(SMSG_MOUNTRESULT, 4); + data << uint32(result); + GetSession()->SendPacket(&data); +} + +void Player::SendDismountResult(PlayerDismountResult result) +{ + WorldPacket data(SMSG_DISMOUNTRESULT, 4); + data << uint32(result); + GetSession()->SendPacket(&data); +} + void Player::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs) { // last check 1.12 diff --git a/src/game/Object/Player.h b/src/game/Object/Player.h index a9566300..ab2afe9d 100644 --- a/src/game/Object/Player.h +++ b/src/game/Object/Player.h @@ -725,6 +725,29 @@ enum PlayerRestState REST_STATE_RAF_LINKED = 0x04 // Exact use unknown }; +enum PlayerMountResult +{ + MOUNTRESULT_INVALIDMOUNTEE = 0, // You can't mount that unit! + MOUNTRESULT_TOOFARAWAY = 1, // That mount is too far away! + MOUNTRESULT_ALREADYMOUNTED = 2, // You're already mounted! + MOUNTRESULT_NOTMOUNTABLE = 3, // That unit can't be mounted! + MOUNTRESULT_NOTYOURPET = 4, // That mount isn't your pet! + MOUNTRESULT_OTHER = 5, // internal + MOUNTRESULT_LOOTING = 6, // You can't mount while looting! + MOUNTRESULT_RACECANTMOUNT = 7, // You can't mount because of your race! + MOUNTRESULT_SHAPESHIFTED = 8, // You can't mount while shapeshifted! + MOUNTRESULT_FORCEDDISMOUNT = 9, // You dismount before continuing. + MOUNTRESULT_OK = 10 // no error +}; + +enum PlayerDismountResult +{ + DISMOUNTRESULT_NOPET = 0, // internal + DISMOUNTRESULT_NOTMOUNTED = 1, // You're not mounted! + DISMOUNTRESULT_NOTYOURPET = 2, // internal + DISMOUNTRESULT_OK = 3 // no error +}; + class PlayerTaxi { public: @@ -994,6 +1017,8 @@ class Player : public Unit void ContinueTaxiFlight(); void Mount(uint32 mount, uint32 spellId = 0) override; void Unmount(bool from_aura = false) override; + void SendMountResult(PlayerMountResult result); + void SendDismountResult(PlayerDismountResult result); bool isAcceptTickets() const { return GetSession()->GetSecurity() >= SEC_GAMEMASTER && (m_ExtraFlags & PLAYER_EXTRA_GM_ACCEPT_TICKETS); } void SetAcceptTicket(bool on) { if (on) { m_ExtraFlags |= PLAYER_EXTRA_GM_ACCEPT_TICKETS; } else { m_ExtraFlags &= ~PLAYER_EXTRA_GM_ACCEPT_TICKETS; } } bool isAcceptWhispers() const { return m_ExtraFlags & PLAYER_EXTRA_ACCEPT_WHISPERS; } diff --git a/src/game/Server/Opcodes.cpp b/src/game/Server/Opcodes.cpp index a37e6dd0..2f003907 100644 --- a/src/game/Server/Opcodes.cpp +++ b/src/game/Server/Opcodes.cpp @@ -426,8 +426,8 @@ void Opcodes::BuildOpcodeList() /*[-ZERO] Need check */ /*0x16B*/ StoreOpcode(SMSG_DUEL_WINNER, "SMSG_DUEL_WINNER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x16C*/ StoreOpcode(CMSG_DUEL_ACCEPTED, "CMSG_DUEL_ACCEPTED", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDuelAcceptedOpcode); /*[-ZERO] Need check */ /*0x16D*/ StoreOpcode(CMSG_DUEL_CANCELLED, "CMSG_DUEL_CANCELLED", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDuelCancelledOpcode); - /*[-ZERO] Need check */ /*0x16E*/ StoreOpcode(SMSG_MOUNTRESULT, "SMSG_MOUNTRESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); - /*[-ZERO] Need check */ /*0x16F*/ StoreOpcode(SMSG_DISMOUNTRESULT, "SMSG_DISMOUNTRESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); + /*0x16E*/ StoreOpcode(SMSG_MOUNTRESULT, "SMSG_MOUNTRESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); + /*0x16F*/ StoreOpcode(SMSG_DISMOUNTRESULT, "SMSG_DISMOUNTRESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x170*/ StoreOpcode(SMSG_PUREMOUNT_CANCELLED_OBSOLETE, "SMSG_PUREMOUNT_CANCELLED_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x171*/ StoreOpcode(CMSG_MOUNTSPECIAL_ANIM, "CMSG_MOUNTSPECIAL_ANIM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMountSpecialAnimOpcode); /*[-ZERO] Need check */ /*0x172*/ StoreOpcode(SMSG_MOUNTSPECIAL_ANIM, "SMSG_MOUNTSPECIAL_ANIM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); From b6767e2a8af1a10bfa425e3d82d4683acbe56677 Mon Sep 17 00:00:00 2001 From: Olion Date: Sat, 1 Jul 2017 10:34:47 +0300 Subject: [PATCH 13/14] SMSG_TRANSFER_ABORTED has no data except uint8 TransferAbortReason --- src/game/Object/Player.h | 3 +-- src/game/Server/Opcodes.cpp | 2 +- src/game/Server/WorldSession.cpp | 4 +--- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/game/Object/Player.h b/src/game/Object/Player.h index ab2afe9d..90cf016d 100644 --- a/src/game/Object/Player.h +++ b/src/game/Object/Player.h @@ -602,13 +602,12 @@ enum TradeSlots TRADE_SLOT_NONTRADED = 6 }; -// [-ZERO] Need fix, or maybe not exists enum TransferAbortReason { - TRANSFER_ABORT_NONE = 0x00, TRANSFER_ABORT_MAX_PLAYERS = 0x01, // Transfer Aborted: instance is full TRANSFER_ABORT_NOT_FOUND = 0x02, // Transfer Aborted: instance not found TRANSFER_ABORT_TOO_MANY_INSTANCES = 0x03, // You have entered too many instances recently. + TRANSFER_ABORT_SILENTLY = 0x04, // no message shown; the same effect give values above 5 TRANSFER_ABORT_ZONE_IN_COMBAT = 0x05, // Unable to zone in while an encounter is in progress. }; diff --git a/src/game/Server/Opcodes.cpp b/src/game/Server/Opcodes.cpp index 2f003907..907d5ae8 100644 --- a/src/game/Server/Opcodes.cpp +++ b/src/game/Server/Opcodes.cpp @@ -124,7 +124,7 @@ void Opcodes::BuildOpcodeList() /*0x03D*/ StoreOpcode(CMSG_PLAYER_LOGIN, "CMSG_PLAYER_LOGIN", STATUS_AUTHED, PROCESS_INPLACE, &WorldSession::HandlePlayerLoginOpcode); /*[-ZERO] Need check */ /*0x03E*/ StoreOpcode(SMSG_NEW_WORLD, "SMSG_NEW_WORLD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x03F*/ StoreOpcode(SMSG_TRANSFER_PENDING, "SMSG_TRANSFER_PENDING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); - /*[-ZERO] Need check */ /*0x040*/ StoreOpcode(SMSG_TRANSFER_ABORTED, "SMSG_TRANSFER_ABORTED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); + /*0x040*/ StoreOpcode(SMSG_TRANSFER_ABORTED, "SMSG_TRANSFER_ABORTED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x041*/ StoreOpcode(SMSG_CHARACTER_LOGIN_FAILED, "SMSG_CHARACTER_LOGIN_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x042*/ StoreOpcode(SMSG_LOGIN_SETTIMESPEED, "SMSG_LOGIN_SETTIMESPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x043*/ StoreOpcode(SMSG_GAMETIME_UPDATE, "SMSG_GAMETIME_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); diff --git a/src/game/Server/WorldSession.cpp b/src/game/Server/WorldSession.cpp index c89708a8..7dac04d5 100644 --- a/src/game/Server/WorldSession.cpp +++ b/src/game/Server/WorldSession.cpp @@ -780,10 +780,8 @@ void WorldSession::SaveTutorialsData() // Send chat information about aborted transfer (mostly used by Player::SendTransferAbortedByLockstatus()) void WorldSession::SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg) { - WorldPacket data(SMSG_TRANSFER_ABORTED, 4 + 2); - data << uint32(mapid); + WorldPacket data(SMSG_TRANSFER_ABORTED, 1); data << uint8(reason); // transfer abort reason - data << uint8(0); // arg. not used SendPacket(&data); } From c87cca2d2134b7164bba743010db6d9466730c61 Mon Sep 17 00:00:00 2001 From: Olion Date: Sun, 2 Jul 2017 15:59:13 +0300 Subject: [PATCH 14/14] CMSG_MOVE_SET_RAW_POSITION handling. ToDo: use also MSG_MOVE_SET_RAW_POSITION_ACK. --- src/game/Server/Opcodes.cpp | 12 ++++++------ src/game/Server/WorldSession.h | 1 + src/game/WorldHandlers/MiscHandler.cpp | 21 +++++++++++++++++++++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/game/Server/Opcodes.cpp b/src/game/Server/Opcodes.cpp index 907d5ae8..3114363c 100644 --- a/src/game/Server/Opcodes.cpp +++ b/src/game/Server/Opcodes.cpp @@ -123,7 +123,7 @@ void Opcodes::BuildOpcodeList() /*0x03C*/ StoreOpcode(SMSG_CHAR_DELETE, "SMSG_CHAR_DELETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*0x03D*/ StoreOpcode(CMSG_PLAYER_LOGIN, "CMSG_PLAYER_LOGIN", STATUS_AUTHED, PROCESS_INPLACE, &WorldSession::HandlePlayerLoginOpcode); /*[-ZERO] Need check */ /*0x03E*/ StoreOpcode(SMSG_NEW_WORLD, "SMSG_NEW_WORLD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); - /*[-ZERO] Need check */ /*0x03F*/ StoreOpcode(SMSG_TRANSFER_PENDING, "SMSG_TRANSFER_PENDING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); + /*0x03F*/ StoreOpcode(SMSG_TRANSFER_PENDING, "SMSG_TRANSFER_PENDING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*0x040*/ StoreOpcode(SMSG_TRANSFER_ABORTED, "SMSG_TRANSFER_ABORTED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x041*/ StoreOpcode(SMSG_CHARACTER_LOGIN_FAILED, "SMSG_CHARACTER_LOGIN_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x042*/ StoreOpcode(SMSG_LOGIN_SETTIMESPEED, "SMSG_LOGIN_SETTIMESPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); @@ -285,7 +285,7 @@ void Opcodes::BuildOpcodeList() /*0x0DE*/ StoreOpcode(SMSG_MOVE_WATER_WALK, "SMSG_MOVE_WATER_WALK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*0x0DF*/ StoreOpcode(SMSG_MOVE_LAND_WALK, "SMSG_MOVE_LAND_WALK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*0x0E0*/ StoreOpcode(MSG_MOVE_SET_RAW_POSITION_ACK, "MSG_MOVE_SET_RAW_POSITION_ACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL); - /*0x0E1*/ StoreOpcode(CMSG_MOVE_SET_RAW_POSITION, "CMSG_MOVE_SET_RAW_POSITION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL); + /*0x0E1*/ StoreOpcode(CMSG_MOVE_SET_RAW_POSITION, "CMSG_MOVE_SET_RAW_POSITION", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveSetRawPosition); /*0x0E2*/ StoreOpcode(SMSG_FORCE_RUN_SPEED_CHANGE, "SMSG_FORCE_RUN_SPEED_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*0x0E3*/ StoreOpcode(CMSG_FORCE_RUN_SPEED_CHANGE_ACK, "CMSG_FORCE_RUN_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAckOpcodes); /*0x0E4*/ StoreOpcode(SMSG_FORCE_RUN_BACK_SPEED_CHANGE, "SMSG_FORCE_RUN_BACK_SPEED_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); @@ -519,9 +519,9 @@ void Opcodes::BuildOpcodeList() /*[-ZERO] Need check */ /*0x1C8*/ StoreOpcode(SMSG_FISH_NOT_HOOKED, "SMSG_FISH_NOT_HOOKED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x1C9*/ StoreOpcode(SMSG_FISH_ESCAPED, "SMSG_FISH_ESCAPED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x1CA*/ StoreOpcode(CMSG_BUG, "CMSG_BUG", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleBugOpcode); - /*[-ZERO] Need check */ /*0x1CB*/ StoreOpcode(SMSG_NOTIFICATION, "SMSG_NOTIFICATION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); + /*0x1CB*/ StoreOpcode(SMSG_NOTIFICATION, "SMSG_NOTIFICATION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x1CC*/ StoreOpcode(CMSG_PLAYED_TIME, "CMSG_PLAYED_TIME", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandlePlayedTime); - /*[-ZERO] Need check */ /*0x1CD*/ StoreOpcode(SMSG_PLAYED_TIME, "SMSG_PLAYED_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); + /*0x1CD*/ StoreOpcode(SMSG_PLAYED_TIME, "SMSG_PLAYED_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x1CE*/ StoreOpcode(CMSG_QUERY_TIME, "CMSG_QUERY_TIME", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleQueryTimeOpcode); /*[-ZERO] Need check */ /*0x1CF*/ StoreOpcode(SMSG_QUERY_TIME_RESPONSE, "SMSG_QUERY_TIME_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x1D0*/ StoreOpcode(SMSG_LOG_XPGAIN, "SMSG_LOG_XPGAIN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); @@ -755,8 +755,8 @@ void Opcodes::BuildOpcodeList() /*[-ZERO] Need check */ /*0x2B6*/ StoreOpcode(SMSG_SCRIPT_MESSAGE, "SMSG_SCRIPT_MESSAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*0x2B7*/ StoreOpcode(SMSG_DUEL_COUNTDOWN, "SMSG_DUEL_COUNTDOWN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x2B8*/ StoreOpcode(SMSG_AREA_TRIGGER_MESSAGE, "SMSG_AREA_TRIGGER_MESSAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); - /*[-ZERO] Need check */ /*0x2B9*/ StoreOpcode(CMSG_TOGGLE_HELM, "CMSG_TOGGLE_HELM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleShowingHelmOpcode); - /*[-ZERO] Need check */ /*0x2BA*/ StoreOpcode(CMSG_TOGGLE_CLOAK, "CMSG_TOGGLE_CLOAK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleShowingCloakOpcode); + /*0x2B9*/ StoreOpcode(CMSG_TOGGLE_HELM, "CMSG_TOGGLE_HELM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleShowingHelmOpcode); + /*0x2BA*/ StoreOpcode(CMSG_TOGGLE_CLOAK, "CMSG_TOGGLE_CLOAK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleShowingCloakOpcode); /*0x2BB*/ StoreOpcode(SMSG_MEETINGSTONE_JOINFAILED, "SMSG_MEETINGSTONE_JOINFAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x2BC*/ StoreOpcode(SMSG_PLAYER_SKINNED, "SMSG_PLAYER_SKINNED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); /*[-ZERO] Need check */ /*0x2BD*/ StoreOpcode(SMSG_DURABILITY_DAMAGE_DEATH, "SMSG_DURABILITY_DAMAGE_DEATH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide); diff --git a/src/game/Server/WorldSession.h b/src/game/Server/WorldSession.h index 8fe32005..4a9f76b5 100644 --- a/src/game/Server/WorldSession.h +++ b/src/game/Server/WorldSession.h @@ -709,6 +709,7 @@ class WorldSession void HandleWardenDataOpcode(WorldPacket& recv_data); void HandleWorldTeleportOpcode(WorldPacket& recv_data); + void HandleMoveSetRawPosition(WorldPacket& recv_data); void HandleMinimapPingOpcode(WorldPacket& recv_data); void HandleRandomRollOpcode(WorldPacket& recv_data); void HandleFarSightOpcode(WorldPacket& recv_data); diff --git a/src/game/WorldHandlers/MiscHandler.cpp b/src/game/WorldHandlers/MiscHandler.cpp index cff9c02d..065a7362 100644 --- a/src/game/WorldHandlers/MiscHandler.cpp +++ b/src/game/WorldHandlers/MiscHandler.cpp @@ -1065,6 +1065,27 @@ void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recv_data) { SendNotification(LANG_YOU_NOT_HAVE_PERMISSION); } } +void WorldSession::HandleMoveSetRawPosition(WorldPacket& recv_data) +{ + DEBUG_LOG("WORLD: Received opcode CMSG_MOVE_SET_RAW_POSITION from %s", GetPlayer()->GetGuidStr().c_str()); + // write in client console: setrawpos x y z o + // For now, it is implemented like worldport but on the same map. Consider using MSG_MOVE_SET_RAW_POSITION_ACK. + float PosX, PosY, PosZ, PosO; + recv_data >> PosX >> PosY >> PosZ >> PosO; + //DEBUG_LOG("Set to: X=%f, Y=%f, Z=%f, orient=%f", PosX, PosY, PosZ, PosO); + + if (!GetPlayer()->IsInWorld() || GetPlayer()->IsTaxiFlying()) + { + DEBUG_LOG("Player '%s' (GUID: %u) in a transfer, ignore setrawpos command.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow()); + return; + } + + if (GetSecurity() >= SEC_ADMINISTRATOR) + { GetPlayer()->TeleportTo(GetPlayer()->GetMapId(), PosX, PosY, PosZ, PosO); } + else + { SendNotification(LANG_YOU_NOT_HAVE_PERMISSION); } +} + void WorldSession::HandleWhoisOpcode(WorldPacket& recv_data) { DEBUG_LOG("WORLD: Received opcode CMSG_WHOIS");