AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
WorldSession Class Reference

Player session in the World. More...

#include "WorldSession.h"

Classes

class  DosProtection
 

Public Member Functions

 WorldSession (uint32 id, std::string &&name, uint32 accountFlags, std::shared_ptr< WorldSocket > sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter, bool skipQueue, uint32 TotalTime)
 WorldSession constructor.
 
 ~WorldSession ()
 WorldSession destructor.
 
uint32 GetAccountFlags () const
 
bool HasAccountFlag (uint32 flag) const
 
void UpdateAccountFlag (uint32 flag, bool remove=false)
 
void ValidateAccountFlags ()
 
bool IsGMAccount () const
 
bool PlayerLoading () const
 
bool PlayerLogout () const
 
bool PlayerRecentlyLoggedOut () const
 
bool PlayerLogoutWithSave () const
 
void ReadAddonsInfo (ByteBuffer &data)
 
void SendAddonsInfo ()
 
void ReadMovementInfo (WorldPacket &data, MovementInfo *mi)
 
void WriteMovementInfo (WorldPacket *data, MovementInfo *mi)
 
void SynchronizeMovement (MovementInfo &movementInfo)
 
void HandleMoverRelocation (MovementInfo &movementInfo, Unit *mover)
 
bool VerifyMovementInfo (MovementInfo const &movementInfo, Player *plrMover, Unit *mover, Opcodes opcode) const
 
bool ProcessMovementInfo (MovementInfo &movementInfo, Unit *mover, Player *plrMover, WorldPacket &recvData)
 
void SendPacket (WorldPacket const *packet)
 Send a packet to the client.
 
void SendPetNameInvalid (uint32 error, std::string const &name, DeclinedName *declinedName)
 
void SendPartyResult (PartyOperation operation, std::string const &member, PartyResult res, uint32 val=0)
 
void SendAreaTriggerMessage (std::string_view str)
 
template<typename... Args>
void SendAreaTriggerMessage (char const *fmt, Args &&... args)
 
template<typename... Args>
void SendAreaTriggerMessage (uint32 strId, Args &&... args)
 
void SendSetPhaseShift (uint32 phaseShift)
 
void SendTimeQueryResponse ()
 
void SendAuthResponse (uint8 code, bool shortForm, uint32 queuePos=0)
 
void SendClientCacheVersion (uint32 version)
 
AccountTypes GetSecurity () const
 
bool CanSkipQueue () const
 
uint32 GetAccountId () const
 
PlayerGetPlayer () const
 
std::string const & GetPlayerName () const
 
std::string GetPlayerInfo () const
 
uint32 GetCurrentVendor () const
 
void SetCurrentVendor (uint32 vendorEntry)
 
ObjectGuid::LowType GetGuidLow () const
 Get player guid if available. Use for logging purposes only.
 
void SetSecurity (AccountTypes security)
 
std::string const & GetRemoteAddress ()
 
void SetPlayer (Player *player)
 
uint8 Expansion () const
 
void SetTotalTime (uint32 TotalTime)
 
uint32 GetTotalTime () const
 
void InitWarden (SessionKey const &, std::string const &os)
 
WardenGetWarden ()
 
void SetInQueue (bool state)
 Session in auth.queue currently.
 
bool isLogingOut () const
 Is the user engaged in a log out process?
 
void SetLogoutStartTime (time_t requestTime)
 Engage the logout process for the user.
 
bool ShouldLogOut (time_t currTime) const
 Is logout cooldown expired?
 
void LogoutPlayer (bool save)
 Log the player out
 
void KickPlayer (bool setKicked=true)
 
void KickPlayer (std::string const &reason, bool setKicked=true)
 Kick a player out of the World.
 
bool ValidateHyperlinksAndMaybeKick (std::string_view str)
 
bool DisallowHyperlinksAndMaybeKick (std::string_view str)
 
void QueuePacket (WorldPacket *new_packet)
 Add an incoming packet to the queue.
 
bool Update (uint32 diff, PacketFilter &updater)
 Update the WorldSession (triggered by World update)
 
void SendAuthWaitQueue (uint32 position)
 Handle the authentication waiting queue (to be completed)
 
void SendNameQueryOpcode (ObjectGuid guid)
 
void SendTrainerList (ObjectGuid guid)
 
void SendTrainerList (ObjectGuid guid, std::string const &strTitle)
 
void SendListInventory (ObjectGuid guid, uint32 vendorEntry=0)
 
void SendShowBank (ObjectGuid guid)
 
bool CanOpenMailBox (ObjectGuid guid)
 
void SendShowMailBox (ObjectGuid guid)
 
void SendTabardVendorActivate (ObjectGuid guid)
 
void SendSpiritResurrect ()
 
void SendBindPoint (Creature *npc)
 
void SendAttackStop (Unit const *enemy)
 
void SendBattleGroundList (ObjectGuid guid, BattlegroundTypeId bgTypeId=BATTLEGROUND_RB)
 
void SendTradeStatus (TradeStatus status)
 
void SendUpdateTrade (bool trader_data=true)
 
void SendCancelTrade (TradeStatus status)
 
void SendPetitionQueryOpcode (ObjectGuid petitionguid)
 
void HandleClientCastFlags (WorldPacket &recvPacket, uint8 castFlags, SpellCastTargets &targets)
 
void SendPetNameQuery (ObjectGuid guid, uint32 petnumber)
 
void SendStablePet (ObjectGuid guid)
 
void SendStablePetCallback (ObjectGuid guid, PreparedQueryResult result)
 
void SendStableResult (uint8 guid)
 
bool CheckStableMaster (ObjectGuid guid)
 
AccountDataGetAccountData (AccountDataType type)
 
void SetAccountData (AccountDataType type, time_t tm, std::string const &data)
 
void SendAccountDataTimes (uint32 mask)
 
void LoadAccountData (PreparedQueryResult result, uint32 mask)
 
void LoadTutorialsData (PreparedQueryResult result)
 
void SendTutorialsData ()
 
void SaveTutorialsData (CharacterDatabaseTransaction trans)
 
uint32 GetTutorialInt (uint8 index) const
 
void SetTutorialInt (uint8 index, uint32 value)
 
void SendAuctionHello (ObjectGuid guid, Creature *unit)
 
void SendAuctionCommandResult (uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError=0)
 
void SendAuctionBidderNotification (uint32 location, uint32 auctionId, ObjectGuid bidder, uint32 bidSum, uint32 diff, uint32 item_template)
 
void SendAuctionOwnerNotification (AuctionEntry *auction)
 
void SendEnchantmentLog (ObjectGuid target, ObjectGuid caster, uint32 itemId, uint32 enchantId)
 
void SendItemEnchantTimeUpdate (ObjectGuid Playerguid, ObjectGuid Itemguid, uint32 slot, uint32 Duration)
 
void SendTaxiStatus (ObjectGuid guid)
 
void SendTaxiMenu (Creature *unit)
 
void SendDoFlight (uint32 mountDisplayId, uint32 path, uint32 pathNode=0)
 
bool SendLearnNewTaxiNode (Creature *unit)
 
void SendDiscoverNewTaxiNode (uint32 nodeid)
 
void SendArenaTeamCommandResult (uint32 team_action, std::string const &team, std::string const &player, uint32 error_id=0)
 
void SendNotInArenaTeamPacket (uint8 type)
 
void SendPetitionShowList (ObjectGuid guid)
 
void BuildPartyMemberStatsChangedPacket (Player *player, WorldPacket *data)
 
void DoLootRelease (ObjectGuid lguid)
 
LocaleConstant GetSessionDbcLocale () const
 
LocaleConstant GetSessionDbLocaleIndex () const
 
std::string GetAcoreString (uint32 entry) const
 
std::string const * GetModuleString (std::string module, uint32 id) const
 
uint32 GetLatency () const
 
void SetLatency (uint32 latency)
 
void UpdateTimeOutTime (uint32 diff)
 
void ResetTimeOutTime (bool onlyActive)
 
bool IsConnectionIdle () const
 
uint32 GetRecruiterId () const
 
bool IsARecruiter () const
 
time_t GetCalendarEventCreationCooldown () const
 
void SetCalendarEventCreationCooldown (time_t cooldown)
 
void ResetTimeSync ()
 
void SendTimeSync ()
 
uint32 GetOrderCounter () const
 
void IncrementOrderCounter ()
 
void Handle_NULL (WorldPacket &null)
 
void Handle_EarlyProccess (WorldPacket &recvPacket)
 
void Handle_ServerSide (WorldPacket &recvPacket)
 
void Handle_Deprecated (WorldPacket &recvPacket)
 
void HandleCharEnumOpcode (WorldPacket &recvPacket)
 
void HandleCharDeleteOpcode (WorldPacket &recvPacket)
 
void HandleCharCreateOpcode (WorldPacket &recvPacket)
 
void HandlePlayerLoginOpcode (WorldPacket &recvPacket)
 
void HandleCharEnum (PreparedQueryResult result)
 
void HandlePlayerLoginFromDB (LoginQueryHolder const &holder)
 
void HandlePlayerLoginToCharInWorld (Player *pCurrChar)
 
void HandlePlayerLoginToCharOutOfWorld (Player *pCurrChar)
 
void HandleCharFactionOrRaceChange (WorldPacket &recvData)
 
void HandleCharFactionOrRaceChangeCallback (std::shared_ptr< CharacterFactionChangeInfo > factionChangeInfo, PreparedQueryResult result)
 
void SendCharCreate (ResponseCodes result)
 
void SendCharDelete (ResponseCodes result)
 
void SendCharLoginFailed (LoginFailureReason reason)
 
void SendCharRename (ResponseCodes result, CharacterRenameInfo const *renameInfo)
 
void SendCharCustomize (ResponseCodes result, CharacterCustomizeInfo const *customizeInfo)
 
void SendCharFactionChange (ResponseCodes result, CharacterFactionChangeInfo const *factionChangeInfo)
 
void SendSetPlayerDeclinedNamesResult (DeclinedNameResult result, ObjectGuid guid)
 
void HandlePlayedTime (WorldPackets::Character::PlayedTimeClient &packet)
 
void HandleMoveRootAck (WorldPacket &recvPacket)
 
void HandleInspectOpcode (WorldPacket &recvPacket)
 
void HandleInspectHonorStatsOpcode (WorldPacket &recvPacket)
 
void HandleMountSpecialAnimOpcode (WorldPacket &recvdata)
 
void HandleShowingHelmOpcode (WorldPackets::Character::ShowingHelm &packet)
 
void HandleShowingCloakOpcode (WorldPackets::Character::ShowingCloak &packet)
 
void HandleRepairItemOpcode (WorldPacket &recvPacket)
 
void HandleMoveKnockBackAck (WorldPacket &recvPacket)
 
void HandleMoveTeleportAck (WorldPacket &recvPacket)
 
void HandleForceSpeedChangeAck (WorldPacket &recvData)
 
void HandleRepopRequestOpcode (WorldPacket &recvPacket)
 
void HandleAutostoreLootItemOpcode (WorldPacket &recvPacket)
 
void HandleLootMoneyOpcode (WorldPacket &recvPacket)
 
void HandleLootOpcode (WorldPacket &recvPacket)
 
void HandleLootReleaseOpcode (WorldPacket &recvPacket)
 
void HandleLootMasterGiveOpcode (WorldPacket &recvPacket)
 
void HandleWhoOpcode (WorldPacket &recvPacket)
 
void HandleLogoutRequestOpcode (WorldPackets::Character::LogoutRequest &logoutRequest)
 
void HandlePlayerLogoutOpcode (WorldPackets::Character::PlayerLogout &playerLogout)
 
void HandleLogoutCancelOpcode (WorldPackets::Character::LogoutCancel &logoutCancel)
 
void HandleGMTicketCreateOpcode (WorldPacket &recvPacket)
 
void HandleGMTicketUpdateOpcode (WorldPacket &recvPacket)
 
void HandleGMTicketDeleteOpcode (WorldPacket &recvPacket)
 
void HandleGMTicketGetTicketOpcode (WorldPacket &recvPacket)
 
void HandleGMTicketSystemStatusOpcode (WorldPacket &recvPacket)
 
void HandleGMSurveySubmit (WorldPacket &recvPacket)
 
void HandleReportLag (WorldPacket &recvPacket)
 
void HandleGMResponseResolve (WorldPacket &recvPacket)
 
void HandleTogglePvP (WorldPacket &recvPacket)
 
void HandleZoneUpdateOpcode (WorldPacket &recvPacket)
 
void HandleSetSelectionOpcode (WorldPacket &recvPacket)
 
void HandleStandStateChangeOpcode (WorldPacket &recvPacket)
 
void HandleEmoteOpcode (WorldPackets::Chat::EmoteClient &packet)
 
void HandleContactListOpcode (WorldPacket &recvPacket)
 
void HandleAddFriendOpcode (WorldPacket &recvPacket)
 
void HandleDelFriendOpcode (WorldPacket &recvPacket)
 
void HandleAddIgnoreOpcode (WorldPacket &recvPacket)
 
void HandleDelIgnoreOpcode (WorldPacket &recvPacket)
 
void HandleSetContactNotesOpcode (WorldPacket &recvPacket)
 
void HandleBugOpcode (WorldPacket &recvPacket)
 
void HandleSetAmmoOpcode (WorldPacket &recvPacket)
 
void HandleItemNameQueryOpcode (WorldPacket &recvPacket)
 
void HandleAreaTriggerOpcode (WorldPacket &recvPacket)
 
void HandleSetFactionAtWar (WorldPacket &recvData)
 
void HandleSetFactionCheat (WorldPacket &recvData)
 
void HandleSetWatchedFactionOpcode (WorldPacket &recvData)
 
void HandleSetFactionInactiveOpcode (WorldPacket &recvData)
 
void HandleUpdateAccountData (WorldPacket &recvPacket)
 
void HandleRequestAccountData (WorldPacket &recvPacket)
 
void HandleSetActionButtonOpcode (WorldPacket &recvPacket)
 
void HandleGameObjectUseOpcode (WorldPacket &recPacket)
 
void HandleGameobjectReportUse (WorldPacket &recvPacket)
 
void HandleNameQueryOpcode (WorldPackets::Query::NameQuery &packet)
 
void HandleTimeQueryOpcode (WorldPackets::Query::TimeQuery &packet)
 
void HandleCreatureQueryOpcode (WorldPacket &recvPacket)
 Only static data is sent in this packet !!!
 
void HandleGameObjectQueryOpcode (WorldPacket &recvPacket)
 Only static data is sent in this packet !!!
 
void HandleMoveWorldportAckOpcode (WorldPacket &recvPacket)
 
void HandleMoveWorldportAck ()
 
void HandleMovementOpcodes (WorldPacket &recvPacket)
 
void HandleSetActiveMoverOpcode (WorldPacket &recvData)
 
void HandleMoveNotActiveMover (WorldPacket &recvData)
 
void HandleDismissControlledVehicle (WorldPacket &recvData)
 
void HandleRequestVehicleExit (WorldPacket &recvData)
 
void HandleChangeSeatsOnControlledVehicle (WorldPacket &recvData)
 
void HandleMoveTimeSkippedOpcode (WorldPacket &recvData)
 
void HandleRequestRaidInfoOpcode (WorldPacket &recvData)
 
void HandleBattlefieldStatusOpcode (WorldPacket &recvData)
 
void HandleGroupInviteOpcode (WorldPacket &recvPacket)
 
void HandleGroupAcceptOpcode (WorldPacket &recvPacket)
 
void HandleGroupDeclineOpcode (WorldPacket &recvPacket)
 
void HandleGroupUninviteOpcode (WorldPacket &recvPacket)
 
void HandleGroupUninviteGuidOpcode (WorldPacket &recvPacket)
 
void HandleGroupSetLeaderOpcode (WorldPacket &recvPacket)
 
void HandleGroupDisbandOpcode (WorldPacket &recvPacket)
 
void HandleOptOutOfLootOpcode (WorldPacket &recvData)
 
void HandleLootMethodOpcode (WorldPacket &recvPacket)
 
void HandleLootRoll (WorldPacket &recvData)
 
void HandleRequestPartyMemberStatsOpcode (WorldPacket &recvData)
 
void HandleGroupSwapSubGroupOpcode (WorldPacket &recvData)
 
void HandleRaidTargetUpdateOpcode (WorldPacket &recvData)
 
void HandleRaidReadyCheckOpcode (WorldPacket &recvData)
 
void HandleRaidReadyCheckFinishedOpcode (WorldPacket &recvData)
 
void HandleGroupRaidConvertOpcode (WorldPacket &recvData)
 
void HandleGroupChangeSubGroupOpcode (WorldPacket &recvData)
 
void HandleGroupAssistantLeaderOpcode (WorldPacket &recvData)
 
void HandlePartyAssignmentOpcode (WorldPacket &recvData)
 
void HandlePetitionBuyOpcode (WorldPacket &recvData)
 
void HandlePetitionShowSignOpcode (WorldPacket &recvData)
 
void HandlePetitionQueryOpcode (WorldPacket &recvData)
 
void HandlePetitionRenameOpcode (WorldPacket &recvData)
 
void HandlePetitionSignOpcode (WorldPacket &recvData)
 
void HandlePetitionDeclineOpcode (WorldPacket &recvData)
 
void HandleOfferPetitionOpcode (WorldPacket &recvData)
 
void HandleTurnInPetitionOpcode (WorldPacket &recvData)
 
void HandleGuildQueryOpcode (WorldPackets::Guild::QueryGuildInfo &query)
 
void HandleGuildCreateOpcode (WorldPackets::Guild::GuildCreate &packet)
 
void HandleGuildInviteOpcode (WorldPackets::Guild::GuildInviteByName &packet)
 
void HandleGuildRemoveOpcode (WorldPackets::Guild::GuildOfficerRemoveMember &packet)
 
void HandleGuildAcceptOpcode (WorldPackets::Guild::AcceptGuildInvite &invite)
 
void HandleGuildDeclineOpcode (WorldPackets::Guild::GuildDeclineInvitation &decline)
 
void HandleGuildInfoOpcode (WorldPackets::Guild::GuildGetInfo &packet)
 
void HandleGuildEventLogQueryOpcode (WorldPackets::Guild::GuildEventLogQuery &packet)
 
void HandleGuildRosterOpcode (WorldPackets::Guild::GuildGetRoster &packet)
 
void HandleGuildPromoteOpcode (WorldPackets::Guild::GuildPromoteMember &promote)
 
void HandleGuildDemoteOpcode (WorldPackets::Guild::GuildDemoteMember &demote)
 
void HandleGuildLeaveOpcode (WorldPackets::Guild::GuildLeave &leave)
 
void HandleGuildDisbandOpcode (WorldPackets::Guild::GuildDelete &packet)
 
void HandleGuildLeaderOpcode (WorldPackets::Guild::GuildSetGuildMaster &packet)
 
void HandleGuildMOTDOpcode (WorldPackets::Guild::GuildUpdateMotdText &packet)
 
void HandleGuildSetPublicNoteOpcode (WorldPackets::Guild::GuildSetMemberNote &packet)
 
void HandleGuildSetOfficerNoteOpcode (WorldPackets::Guild::GuildSetMemberNote &packet)
 
void HandleGuildRankOpcode (WorldPackets::Guild::GuildSetRankPermissions &packet)
 
void HandleGuildAddRankOpcode (WorldPackets::Guild::GuildAddRank &packet)
 
void HandleGuildDelRankOpcode (WorldPackets::Guild::GuildDeleteRank &packet)
 
void HandleGuildChangeInfoTextOpcode (WorldPackets::Guild::GuildUpdateInfoText &packet)
 
void HandleSaveGuildEmblemOpcode (WorldPackets::Guild::SaveGuildEmblem &packet)
 
void HandleTaxiNodeStatusQueryOpcode (WorldPacket &recvPacket)
 
void HandleTaxiQueryAvailableNodes (WorldPacket &recvPacket)
 
void HandleActivateTaxiOpcode (WorldPacket &recvPacket)
 
void HandleActivateTaxiExpressOpcode (WorldPacket &recvPacket)
 
void HandleMoveSplineDoneOpcode (WorldPacket &recvPacket)
 
void SendActivateTaxiReply (ActivateTaxiReply reply)
 
void HandleTabardVendorActivateOpcode (WorldPacket &recvPacket)
 
void HandleTrainerListOpcode (WorldPacket &recvPacket)
 
void HandleTrainerBuySpellOpcode (WorldPacket &recvPacket)
 
void HandlePetitionShowListOpcode (WorldPacket &recvPacket)
 
void HandleGossipHelloOpcode (WorldPacket &recvPacket)
 
void HandleGossipSelectOptionOpcode (WorldPacket &recvPacket)
 
void HandleSpiritHealerActivateOpcode (WorldPacket &recvPacket)
 
void HandleNpcTextQueryOpcode (WorldPacket &recvPacket)
 
void HandleBinderActivateOpcode (WorldPacket &recvPacket)
 
void HandleListStabledPetsOpcode (WorldPacket &recvPacket)
 
void HandleStablePet (WorldPacket &recvPacket)
 
void HandleUnstablePet (WorldPacket &recvPacket)
 
void HandleBuyStableSlot (WorldPacket &recvPacket)
 
void HandleStableRevivePet (WorldPacket &recvPacket)
 
void HandleStableSwapPet (WorldPacket &recvPacket)
 
void HandleOpenWrappedItemCallback (uint8 bagIndex, uint8 slot, ObjectGuid::LowType itemLowGUID, PreparedQueryResult result)
 
void HandleLoadActionsSwitchSpec (PreparedQueryResult result)
 
void HandleCharacterAuraFrozen (PreparedQueryResult result)
 
void HandleDuelAcceptedOpcode (WorldPacket &recvPacket)
 
void HandleDuelCancelledOpcode (WorldPacket &recvPacket)
 
void HandleAcceptTradeOpcode (WorldPacket &recvPacket)
 
void HandleBeginTradeOpcode (WorldPacket &recvPacket)
 
void HandleBusyTradeOpcode (WorldPacket &recvPacket)
 
void HandleCancelTradeOpcode (WorldPacket &recvPacket)
 
void HandleClearTradeItemOpcode (WorldPacket &recvPacket)
 
void HandleIgnoreTradeOpcode (WorldPacket &recvPacket)
 
void HandleInitiateTradeOpcode (WorldPacket &recvPacket)
 
void HandleSetTradeGoldOpcode (WorldPacket &recvPacket)
 
void HandleSetTradeItemOpcode (WorldPacket &recvPacket)
 
void HandleUnacceptTradeOpcode (WorldPacket &recvPacket)
 
void HandleAuctionHelloOpcode (WorldPacket &recvPacket)
 
void HandleAuctionListItems (WorldPacket &recvData)
 
void HandleAuctionListBidderItems (WorldPacket &recvData)
 
void HandleAuctionSellItem (WorldPacket &recvData)
 
void HandleAuctionRemoveItem (WorldPacket &recvData)
 
void HandleAuctionListOwnerItems (WorldPacket &recvData)
 
void HandleAuctionPlaceBid (WorldPacket &recvData)
 
void HandleAuctionListPendingSales (WorldPacket &recvData)
 
void HandleBankerActivateOpcode (WorldPacket &recvData)
 
void HandleAutoBankItemOpcode (WorldPackets::Bank::AutoBankItem &packet)
 
void HandleAutoStoreBankItemOpcode (WorldPackets::Bank::AutoStoreBankItem &packet)
 
void HandleBuyBankSlotOpcode (WorldPackets::Bank::BuyBankSlot &buyBankSlot)
 
void HandleGetMailList (WorldPacket &recvData)
 
void HandleSendMail (WorldPacket &recvData)
 
void HandleMailTakeMoney (WorldPacket &recvData)
 
void HandleMailTakeItem (WorldPacket &recvData)
 
void HandleMailMarkAsRead (WorldPacket &recvData)
 
void HandleMailReturnToSender (WorldPacket &recvData)
 
void HandleMailDelete (WorldPacket &recvData)
 
void HandleItemTextQuery (WorldPacket &recvData)
 
void HandleMailCreateTextItem (WorldPacket &recvData)
 
void HandleQueryNextMailTime (WorldPacket &recvData)
 
void HandleCancelChanneling (WorldPacket &recvData)
 
void HandleSplitItemOpcode (WorldPackets::Item::SplitItem &packet)
 
void HandleSwapInvItemOpcode (WorldPackets::Item::SwapInventoryItem &packet)
 
void HandleDestroyItemOpcode (WorldPackets::Item::DestroyItem &packet)
 
void HandleAutoEquipItemOpcode (WorldPackets::Item::AutoEquipItem &packet)
 
void HandleItemQuerySingleOpcode (WorldPacket &recvPacket)
 
void HandleSellItemOpcode (WorldPackets::Item::SellItem &packet)
 
void HandleBuyItemInSlotOpcode (WorldPackets::Item::BuyItemInSlot &packet)
 
void HandleBuyItemOpcode (WorldPackets::Item::BuyItem &packet)
 
void HandleListInventoryOpcode (WorldPackets::Item::ListInventory &packet)
 
void HandleAutoStoreBagItemOpcode (WorldPackets::Item::AutoStoreBagItem &packet)
 
void HandleReadItem (WorldPackets::Item::ReadItem &packet)
 
void HandleAutoEquipItemSlotOpcode (WorldPackets::Item::AutoEquipItemSlot &packet)
 
void HandleSwapItem (WorldPackets::Item::SwapItem &packet)
 
void HandleBuybackItem (WorldPackets::Item::BuybackItem &packet)
 
void HandleWrapItemOpcode (WorldPackets::Item::WrapItem &packet)
 
void HandleAttackSwingOpcode (WorldPacket &recvPacket)
 
void HandleAttackStopOpcode (WorldPacket &recvPacket)
 
void HandleSetSheathedOpcode (WorldPackets::Combat::SetSheathed &packet)
 
void HandleUseItemOpcode (WorldPacket &recvPacket)
 
void HandleOpenItemOpcode (WorldPacket &recvPacket)
 
void HandleCastSpellOpcode (WorldPacket &recvPacket)
 
void HandleCancelCastOpcode (WorldPacket &recvPacket)
 
void HandleCancelAuraOpcode (WorldPacket &recvPacket)
 
void HandleCancelGrowthAuraOpcode (WorldPacket &recvPacket)
 
void HandleCancelAutoRepeatSpellOpcode (WorldPacket &recvPacket)
 
void HandleLearnTalentOpcode (WorldPacket &recvPacket)
 
void HandleLearnPreviewTalents (WorldPacket &recvPacket)
 
void HandleTalentWipeConfirmOpcode (WorldPacket &recvPacket)
 
void HandleUnlearnSkillOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverStatusQueryOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverStatusMultipleQuery (WorldPacket &recvPacket)
 
void HandleQuestgiverHelloOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverAcceptQuestOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverQueryQuestOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverChooseRewardOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverRequestRewardOpcode (WorldPacket &recvPacket)
 
void HandleQuestQueryOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverCancel (WorldPacket &recvData)
 
void HandleQuestLogSwapQuest (WorldPacket &recvData)
 
void HandleQuestLogRemoveQuest (WorldPacket &recvData)
 
void HandleQuestConfirmAccept (WorldPacket &recvData)
 
void HandleQuestgiverCompleteQuest (WorldPacket &recvData)
 
void HandleQuestgiverQuestAutoLaunch (WorldPacket &recvPacket)
 
void HandlePushQuestToParty (WorldPacket &recvPacket)
 
void HandleQuestPushResult (WorldPacket &recvPacket)
 
void HandleMessagechatOpcode (WorldPacket &recvPacket)
 
void SendPlayerNotFoundNotice (std::string const &name)
 
void SendPlayerAmbiguousNotice (std::string const &name)
 
void SendWrongFactionNotice ()
 
void SendChatRestrictedNotice (ChatRestrictionType restriction)
 
void HandleTextEmoteOpcode (WorldPacket &recvPacket)
 
void HandleChatIgnoredOpcode (WorldPacket &recvPacket)
 
void HandleReclaimCorpseOpcode (WorldPacket &recvPacket)
 
void HandleCorpseQueryOpcode (WorldPacket &recvPacket)
 
void HandleCorpseMapPositionQuery (WorldPackets::Query::CorpseMapPositionQuery &packet)
 
void HandleResurrectResponseOpcode (WorldPacket &recvPacket)
 
void HandleSummonResponseOpcode (WorldPacket &recvData)
 
void HandleJoinChannel (WorldPacket &recvPacket)
 
void HandleLeaveChannel (WorldPacket &recvPacket)
 
void HandleChannelList (WorldPacket &recvPacket)
 
void HandleChannelPassword (WorldPacket &recvPacket)
 
void HandleChannelSetOwner (WorldPacket &recvPacket)
 
void HandleChannelOwner (WorldPacket &recvPacket)
 
void HandleChannelModerator (WorldPacket &recvPacket)
 
void HandleChannelUnmoderator (WorldPacket &recvPacket)
 
void HandleChannelMute (WorldPacket &recvPacket)
 
void HandleChannelUnmute (WorldPacket &recvPacket)
 
void HandleChannelInvite (WorldPacket &recvPacket)
 
void HandleChannelKick (WorldPacket &recvPacket)
 
void HandleChannelBan (WorldPacket &recvPacket)
 
void HandleChannelUnban (WorldPacket &recvPacket)
 
void HandleChannelAnnouncements (WorldPacket &recvPacket)
 
void HandleChannelModerateOpcode (WorldPacket &recvPacket)
 
void HandleChannelDeclineInvite (WorldPacket &recvPacket)
 
void HandleChannelDisplayListQuery (WorldPacket &recvPacket)
 
void HandleGetChannelMemberCount (WorldPacket &recvPacket)
 
void HandleSetChannelWatch (WorldPacket &recvPacket)
 
void HandleClearChannelWatch (WorldPacket &recvPacket)
 
void HandleCompleteCinematic (WorldPacket &recvPacket)
 
void HandleNextCinematicCamera (WorldPacket &recvPacket)
 
void HandlePageTextQueryOpcode (WorldPacket &recvPacket)
 Only static data is sent in this packet !!!
 
void HandleTutorialFlag (WorldPacket &recvData)
 
void HandleTutorialClear (WorldPacket &recvData)
 
void HandleTutorialReset (WorldPacket &recvData)
 
void HandlePetAction (WorldPacket &recvData)
 
void HandlePetStopAttack (WorldPackets::Pet::PetStopAttack &packet)
 
void HandlePetActionHelper (Unit *pet, ObjectGuid guid1, uint32 spellid, uint16 flag, ObjectGuid guid2)
 
void HandlePetNameQuery (WorldPacket &recvData)
 
void HandlePetSetAction (WorldPacket &recvData)
 
void HandlePetAbandon (WorldPackets::Pet::PetAbandon &packet)
 
void HandlePetRename (WorldPacket &recvData)
 
void HandlePetCancelAuraOpcode (WorldPacket &recvPacket)
 
void HandlePetSpellAutocastOpcode (WorldPackets::Pet::PetSpellAutocast &packet)
 
void HandlePetCastSpellOpcode (WorldPacket &recvPacket)
 
void HandlePetLearnTalent (WorldPacket &recvPacket)
 
void HandleLearnPreviewTalentsPet (WorldPacket &recvPacket)
 
void HandleSetActionBarToggles (WorldPacket &recvData)
 
void HandleCharRenameOpcode (WorldPacket &recvData)
 
void HandleCharRenameCallBack (std::shared_ptr< CharacterRenameInfo > renameInfo, PreparedQueryResult result)
 
void HandleSetPlayerDeclinedNames (WorldPacket &recvData)
 
void HandleTotemDestroyed (WorldPackets::Totem::TotemDestroyed &totemDestroyed)
 
void HandleDismissCritter (WorldPackets::Pet::DismissCritter &dismissCritter)
 
void HandleBattlemasterHelloOpcode (WorldPacket &recvData)
 
void HandleBattlemasterJoinOpcode (WorldPacket &recvData)
 
void HandleBattlegroundPlayerPositionsOpcode (WorldPacket &recvData)
 
void HandlePVPLogDataOpcode (WorldPacket &recvData)
 
void HandleBattleFieldPortOpcode (WorldPacket &recvData)
 
void HandleBattlefieldListOpcode (WorldPacket &recvData)
 
void HandleBattlefieldLeaveOpcode (WorldPacket &recvData)
 
void HandleBattlemasterJoinArena (WorldPacket &recvData)
 
void HandleReportPvPAFK (WorldPacket &recvData)
 
void HandleWardenDataOpcode (WorldPacket &recvData)
 
void HandleWorldTeleportOpcode (WorldPacket &recvData)
 
void HandleMinimapPingOpcode (WorldPackets::Misc::MinimapPingClient &packet)
 
void HandleRandomRollOpcode (WorldPackets::Misc::RandomRollClient &packet)
 
void HandleFarSightOpcode (WorldPacket &recvData)
 
void HandleSetDungeonDifficultyOpcode (WorldPacket &recvData)
 
void HandleSetRaidDifficultyOpcode (WorldPacket &recvData)
 
void HandleMoveFlagChangeOpcode (WorldPacket &recvData)
 
void HandleSetTitleOpcode (WorldPacket &recvData)
 
void HandleRealmSplitOpcode (WorldPacket &recvData)
 
void HandleTimeSyncResp (WorldPacket &recvData)
 
void HandleWhoisOpcode (WorldPacket &recvData)
 
void HandleResetInstancesOpcode (WorldPacket &recvData)
 
void HandleHearthAndResurrect (WorldPacket &recvData)
 
void HandleInstanceLockResponse (WorldPacket &recvPacket)
 
void HandleUpdateMissileTrajectory (WorldPacket &recvPacket)
 
void SendBfInvitePlayerToWar (uint32 battleId, uint32 zoneId, uint32 time)
 
void SendBfInvitePlayerToQueue (uint32 battleId)
 
void SendBfQueueInviteResponse (uint32 battleId, uint32 zoneId, bool canQueue=true, bool full=false)
 
void SendBfEntered (uint32 battleId)
 
void SendBfLeaveMessage (uint32 battleId, BFLeaveReason reason=BF_LEAVE_REASON_EXITED)
 
void HandleBfQueueInviteResponse (WorldPacket &recvData)
 
void HandleBfEntryInviteResponse (WorldPacket &recvData)
 
void HandleBfExitRequest (WorldPacket &recvData)
 
void HandleLfgSetCommentOpcode (WorldPacket &recvData)
 
void HandleLfgPlayerLockInfoRequestOpcode (WorldPacket &recvData)
 
void HandleLfgPartyLockInfoRequestOpcode (WorldPacket &recvData)
 
void HandleLfgJoinOpcode (WorldPackets::LFG::LFGJoin &lfgJoin)
 
void HandleLfgLeaveOpcode (WorldPackets::LFG::LFGLeave &lfgleave)
 
void HandleLfgSetRolesOpcode (WorldPacket &recvData)
 
void HandleLfgProposalResultOpcode (WorldPacket &recvData)
 
void HandleLfgSetBootVoteOpcode (WorldPacket &recvData)
 
void HandleLfgTeleportOpcode (WorldPacket &recvData)
 
void HandleLfrSearchJoinOpcode (WorldPacket &recvData)
 
void HandleLfrSearchLeaveOpcode (WorldPacket &recvData)
 
void HandleLfgGetStatus (WorldPacket &recvData)
 
void SendLfgUpdatePlayer (lfg::LfgUpdateData const &updateData)
 
void SendLfgUpdateParty (lfg::LfgUpdateData const &updateData)
 
void SendLfgRoleChosen (ObjectGuid guid, uint8 roles)
 
void SendLfgRoleCheckUpdate (lfg::LfgRoleCheck const &pRoleCheck)
 
void SendLfgLfrList (bool update)
 
void SendLfgJoinResult (lfg::LfgJoinResultData const &joinData)
 
void SendLfgQueueStatus (lfg::LfgQueueStatusData const &queueData)
 
void SendLfgPlayerReward (lfg::LfgPlayerRewardData const &lfgPlayerRewardData)
 
void SendLfgBootProposalUpdate (lfg::LfgPlayerBoot const &boot)
 
void SendLfgUpdateProposal (lfg::LfgProposal const &proposal)
 
void SendLfgDisabled ()
 
void SendLfgOfferContinue (uint32 dungeonEntry)
 
void SendLfgTeleportError (uint8 err)
 
void HandleInspectArenaTeamsOpcode (WorldPacket &recvData)
 
void HandleArenaTeamQueryOpcode (WorldPacket &recvData)
 
void HandleArenaTeamRosterOpcode (WorldPacket &recvData)
 
void HandleArenaTeamInviteOpcode (WorldPacket &recvData)
 
void HandleArenaTeamAcceptOpcode (WorldPacket &recvData)
 
void HandleArenaTeamDeclineOpcode (WorldPacket &recvData)
 
void HandleArenaTeamLeaveOpcode (WorldPacket &recvData)
 
void HandleArenaTeamRemoveOpcode (WorldPacket &recvData)
 
void HandleArenaTeamDisbandOpcode (WorldPacket &recvData)
 
void HandleArenaTeamLeaderOpcode (WorldPacket &recvData)
 
void HandleAreaSpiritHealerQueryOpcode (WorldPacket &recvData)
 
void HandleAreaSpiritHealerQueueOpcode (WorldPacket &recvData)
 
void HandleCancelMountAuraOpcode (WorldPacket &recvData)
 
void HandleSelfResOpcode (WorldPacket &recvData)
 
void HandleComplainOpcode (WorldPackets::Misc::Complain &packet)
 
void HandleRequestPetInfo (WorldPackets::Pet::RequestPetInfo &packet)
 
void HandleSocketOpcode (WorldPackets::Item::SocketGems &packet)
 
void HandleCancelTempEnchantmentOpcode (WorldPackets::Item::CancelTempEnchantment &packet)
 
void HandleItemRefundInfoRequest (WorldPackets::Item::ItemRefundInfo &packet)
 
void HandleItemRefund (WorldPackets::Item::ItemRefund &packet)
 
void HandleChannelVoiceOnOpcode (WorldPacket &recvData)
 
void HandleVoiceSessionEnableOpcode (WorldPacket &recvData)
 
void HandleSetActiveVoiceChannel (WorldPacket &recvData)
 
void HandleSetTaxiBenchmarkOpcode (WorldPacket &recvData)
 
void HandleGuildPermissions (WorldPackets::Guild::GuildPermissionsQuery &packet)
 
void HandleGuildBankMoneyWithdrawn (WorldPackets::Guild::GuildBankRemainingWithdrawMoneyQuery &packet)
 
void HandleGuildBankerActivate (WorldPackets::Guild::GuildBankActivate &packet)
 
void HandleGuildBankQueryTab (WorldPackets::Guild::GuildBankQueryTab &packet)
 
void HandleGuildBankLogQuery (WorldPackets::Guild::GuildBankLogQuery &packet)
 
void HandleGuildBankDepositMoney (WorldPackets::Guild::GuildBankDepositMoney &packet)
 
void HandleGuildBankWithdrawMoney (WorldPackets::Guild::GuildBankWithdrawMoney &packet)
 
void HandleGuildBankSwapItems (WorldPackets::Guild::GuildBankSwapItems &packet)
 
void HandleGuildBankUpdateTab (WorldPackets::Guild::GuildBankUpdateTab &packet)
 
void HandleGuildBankBuyTab (WorldPackets::Guild::GuildBankBuyTab &packet)
 
void HandleQueryGuildBankTabText (WorldPackets::Guild::GuildBankTextQuery &packet)
 
void HandleSetGuildBankTabText (WorldPackets::Guild::GuildBankSetTabText &packet)
 
void HandleGrantLevel (WorldPacket &recvData)
 
void HandleAcceptGrantLevel (WorldPacket &recvData)
 
void HandleCalendarGetCalendar (WorldPacket &recvData)
 
void HandleCalendarGetEvent (WorldPackets::Calendar::GetEvent &packet)
 
void HandleCalendarGuildFilter (WorldPackets::Calendar::GuildFilter &packet)
 
void HandleCalendarArenaTeam (WorldPackets::Calendar::ArenaTeam &packet)
 
void HandleCalendarAddEvent (WorldPacket &recvData)
 
void HandleCalendarUpdateEvent (WorldPacket &recvData)
 
void HandleCalendarRemoveEvent (WorldPacket &recvData)
 
void HandleCalendarCopyEvent (WorldPacket &recvData)
 
void HandleCalendarEventInvite (WorldPacket &recvData)
 
void HandleCalendarEventRsvp (WorldPacket &recvData)
 
void HandleCalendarEventRemoveInvite (WorldPacket &recvData)
 
void HandleCalendarEventStatus (WorldPacket &recvData)
 
void HandleCalendarEventModeratorStatus (WorldPacket &recvData)
 
void HandleCalendarComplain (WorldPackets::Calendar::CalendarComplain &packet)
 
void HandleCalendarGetNumPending (WorldPacket &recvData)
 
void HandleCalendarEventSignup (WorldPacket &recvData)
 
void SendCalendarRaidLockout (InstanceSave const *save, bool add)
 
void SendCalendarRaidLockoutUpdated (InstanceSave const *save, bool isExtended)
 
void HandleSetSavedInstanceExtend (WorldPacket &recvData)
 
void HandleSpellClick (WorldPacket &recvData)
 
void HandleMirrorImageDataRequest (WorldPacket &recvData)
 
void HandleAlterAppearance (WorldPacket &recvData)
 
void HandleRemoveGlyph (WorldPacket &recvData)
 
void HandleCharCustomize (WorldPacket &recvData)
 
void HandleCharCustomizeCallback (std::shared_ptr< CharacterCustomizeInfo > customizeInfo, PreparedQueryResult result)
 
void HandleQueryInspectAchievements (WorldPacket &recvData)
 
void HandleEquipmentSetSave (WorldPacket &recvData)
 
void HandleEquipmentSetDelete (WorldPacket &recvData)
 
void HandleEquipmentSetUse (WorldPacket &recvData)
 
void HandleWorldStateUITimerUpdate (WorldPacket &recvData)
 
void HandleReadyForAccountDataTimes (WorldPacket &recvData)
 
void HandleQueryQuestsCompleted (WorldPacket &recvData)
 
void HandleQuestPOIQuery (WorldPacket &recvData)
 
void HandleEjectPassenger (WorldPacket &data)
 
void HandleEnterPlayerVehicle (WorldPacket &data)
 
void HandleUpdateProjectilePosition (WorldPacket &recvPacket)
 
void HandleTeleportTimeout (bool updateInSessions)
 
bool HandleSocketClosed ()
 
void SetOfflineTime (uint32 time)
 
uint32 GetOfflineTime () const
 
bool IsKicked () const
 
void SetKicked (bool val)
 
bool IsSocketClosed () const
 
QueryCallbackProcessorGetQueryProcessor ()
 
TransactionCallbackAddTransactionCallback (TransactionCallback &&callback)
 
SQLQueryHolderCallbackAddQueryHolderCallback (SQLQueryHolderCallback &&callback)
 
void InitializeSession ()
 
void InitializeSessionCallback (CharacterDatabaseQueryHolder const &realmHolder, uint32 clientCacheVersion)
 
void SetPacketLogging (bool state)
 

Public Attributes

time_t m_muteTime
 
std::atomic< time_t > m_timeOutTime
 

Protected Attributes

class WorldSession::DosProtection AntiDOS
 

Private Types

typedef std::list< AddonInfoAddonsList
 

Private Member Functions

void ProcessQueryCallbacks ()
 
void moveItems (Item *myItems[], Item *hisItems[])
 
bool CanUseBank (ObjectGuid bankerGUID=ObjectGuid::Empty) const
 
bool recoveryItem (Item *pItem)
 
void LogUnexpectedOpcode (WorldPacket *packet, char const *status, const char *reason)
 Logging helper for unexpected opcodes.
 
void LogUnprocessedTail (WorldPacket *packet)
 Logging helper for unexpected opcodes.
 
bool IsLegitCharacterForAccount (ObjectGuid guid)
 
void ComputeNewClockDelta ()
 
 WorldSession (WorldSession const &right)=delete
 
WorldSessionoperator= (WorldSession const &right)=delete
 

Private Attributes

QueryCallbackProcessor _queryProcessor
 
AsyncCallbackProcessor< TransactionCallback_transactionCallbacks
 
AsyncCallbackProcessor< SQLQueryHolderCallback_queryHolderProcessor
 
GuidSet _legitCharacters
 
ObjectGuid::LowType m_GUIDLow
 
Player_player
 
std::shared_ptr< WorldSocketm_Socket
 
std::string m_Address
 
AccountTypes _security
 
bool _skipQueue
 
uint32 _accountId
 
std::string _accountName
 
uint32 _accountFlags
 
uint8 m_expansion
 
uint32 m_total_time
 
std::unique_ptr< Warden_warden
 
time_t _logoutTime
 
bool m_inQueue
 
bool m_playerLoading
 
bool m_playerLogout
 
bool m_playerRecentlyLogout
 
bool m_playerSave
 
LocaleConstant m_sessionDbcLocale
 
LocaleConstant m_sessionDbLocaleIndex
 
std::atomic< uint32m_latency
 
AccountData m_accountData [NUM_ACCOUNT_DATA_TYPES]
 
uint32 m_Tutorials [MAX_ACCOUNT_TUTORIAL_VALUES]
 
bool m_TutorialsChanged
 
AddonsList m_addonsList
 
uint32 recruiterId
 
bool isRecruiter
 
LockedQueue< WorldPacket * > _recvQueue
 
uint32 m_currentVendorEntry
 
ObjectGuid m_currentBankerGUID
 
uint32 _offlineTime
 
bool _kicked
 
time_t _calendarEventCreationCooldown
 
std::atomic< uint32_addonMessageReceiveCount
 
CircularBuffer< std::pair< int64, uint32 > > _timeSyncClockDeltaQueue
 
int64 _timeSyncClockDelta
 
std::map< uint32, uint32_pendingTimeSyncRequests
 
uint32 _timeSyncNextCounter
 
uint32 _timeSyncTimer
 
uint32 _orderCounter
 

Friends

class World
 

Detailed Description

Player session in the World.

Member Typedef Documentation

◆ AddonsList

typedef std::list<AddonInfo> WorldSession::AddonsList
private

Constructor & Destructor Documentation

◆ WorldSession() [1/2]

WorldSession::WorldSession ( uint32  id,
std::string &&  name,
uint32  accountFlags,
std::shared_ptr< WorldSocket sock,
AccountTypes  sec,
uint8  expansion,
time_t  mute_time,
LocaleConstant  locale,
uint32  recruiter,
bool  isARecruiter,
bool  skipQueue,
uint32  TotalTime 
)

WorldSession constructor.

108 :
109 m_muteTime(mute_time),
110 m_timeOutTime(0),
111 AntiDOS(this),
112 m_GUIDLow(0),
113 _player(nullptr),
114 m_Socket(sock),
115 _security(sec),
116 _skipQueue(skipQueue),
117 _accountId(id),
118 _accountName(std::move(name)),
119 _accountFlags(accountFlags),
120 m_expansion(expansion),
121 m_total_time(TotalTime),
122 _logoutTime(0),
123 m_inQueue(false),
124 m_playerLoading(false),
125 m_playerLogout(false),
127 m_playerSave(false),
128 m_sessionDbcLocale(sWorld->GetAvailableDbcLocale(locale)),
130 m_latency(0),
131 m_TutorialsChanged(false),
132 recruiterId(recruiter),
133 isRecruiter(isARecruiter),
141{
142 memset(m_Tutorials, 0, sizeof(m_Tutorials));
143
144 _offlineTime = 0;
145 _kicked = false;
146
148 _timeSyncTimer = 0;
149
150 if (sock)
151 {
152 m_Address = sock->GetRemoteIpAddress().to_string();
153 ResetTimeOutTime(false);
154 LoginDatabase.Execute("UPDATE account SET online = 1 WHERE id = {};", GetAccountId()); // One-time query
155 }
156}
DatabaseWorkerPool< LoginDatabaseConnection > LoginDatabase
Accessor to the realm/login database.
Definition DatabaseEnv.cpp:22
bool m_playerRecentlyLogout
Definition WorldSession.h:1223
bool isRecruiter
Definition WorldSession.h:1233
std::string m_Address
Definition WorldSession.h:1204
uint32 _offlineTime
Definition WorldSession.h:1237
bool m_playerSave
Definition WorldSession.h:1224
LocaleConstant m_sessionDbLocaleIndex
Definition WorldSession.h:1226
bool _skipQueue
Definition WorldSession.h:1207
CircularBuffer< std::pair< int64, uint32 > > _timeSyncClockDeltaQueue
Definition WorldSession.h:1245
bool m_TutorialsChanged
Definition WorldSession.h:1230
time_t _logoutTime
Definition WorldSession.h:1219
uint32 m_currentVendorEntry
Definition WorldSession.h:1235
int64 _timeSyncClockDelta
Definition WorldSession.h:1246
std::atomic< uint32 > _addonMessageReceiveCount
Definition WorldSession.h:1243
bool m_playerLoading
Definition WorldSession.h:1221
std::shared_ptr< WorldSocket > m_Socket
Definition WorldSession.h:1203
std::map< uint32, uint32 > _pendingTimeSyncRequests
Definition WorldSession.h:1249
time_t _calendarEventCreationCooldown
Definition WorldSession.h:1240
class WorldSession::DosProtection AntiDOS
std::atomic< time_t > m_timeOutTime
Definition WorldSession.h:567
uint32 _timeSyncTimer
Definition WorldSession.h:1251
uint32 _accountFlags
Definition WorldSession.h:1210
uint32 m_total_time
Definition WorldSession.h:1212
std::string _accountName
Definition WorldSession.h:1209
uint32 _timeSyncNextCounter
Definition WorldSession.h:1250
uint32 recruiterId
Definition WorldSession.h:1232
bool m_playerLogout
Definition WorldSession.h:1222
uint32 _accountId
Definition WorldSession.h:1208
ObjectGuid::LowType m_GUIDLow
Definition WorldSession.h:1201
uint32 GetAccountId() const
Definition WorldSession.h:423
Player * _player
Definition WorldSession.h:1202
AccountTypes _security
Definition WorldSession.h:1206
bool m_inQueue
Definition WorldSession.h:1220
LocaleConstant m_sessionDbcLocale
Definition WorldSession.h:1225
time_t m_muteTime
Definition WorldSession.h:556
std::atomic< uint32 > m_latency
Definition WorldSession.h:1227
void ResetTimeOutTime(bool onlyActive)
Definition WorldSession.h:575
uint32 m_Tutorials[MAX_ACCOUNT_TUTORIAL_VALUES]
Definition WorldSession.h:1229
uint32 _orderCounter
Definition WorldSession.h:1253
uint8 m_expansion
Definition WorldSession.h:1211
bool _kicked
Definition WorldSession.h:1238
#define sWorld
Definition World.h:316

References _kicked, _offlineTime, _timeSyncNextCounter, _timeSyncTimer, GetAccountId(), LoginDatabase, m_Address, m_Tutorials, and ResetTimeOutTime().

◆ ~WorldSession()

WorldSession::~WorldSession ( )

WorldSession destructor.

  • unload player if not unloaded
  • If have unclosed socket, close it
  • empty incoming packet queue
160{
161 LoginDatabase.Execute("UPDATE account SET totaltime = {} WHERE id = {}", GetTotalTime(), GetAccountId());
162
164 if (_player)
165 LogoutPlayer(true);
166
168 if (m_Socket)
169 {
170 m_Socket->CloseSocket();
171 m_Socket = nullptr;
172 }
173
175 WorldPacket* packet = nullptr;
176 while (_recvQueue.next(packet))
177 delete packet;
178
179 LoginDatabase.Execute("UPDATE account SET online = 0 WHERE id = {};", GetAccountId()); // One-time query
180}
bool next(T &result)
Gets the next item in the queue and removes it.
Definition LockedQueue.h:77
Definition WorldPacket.h:26
void LogoutPlayer(bool save)
Log the player out
Definition WorldSession.cpp:611
uint32 GetTotalTime() const
Definition WorldSession.h:438
LockedQueue< WorldPacket * > _recvQueue
Definition WorldSession.h:1234

References _player, _recvQueue, GetAccountId(), GetTotalTime(), LoginDatabase, LogoutPlayer(), m_Socket, and LockedQueue< T, StorageType >::next().

◆ WorldSession() [2/2]

WorldSession::WorldSession ( WorldSession const &  right)
privatedelete

Member Function Documentation

◆ AddQueryHolderCallback()

SQLQueryHolderCallback & WorldSession::AddQueryHolderCallback ( SQLQueryHolderCallback &&  callback)
1330{
1331 return _queryHolderProcessor.AddCallback(std::move(callback));
1332}
T & AddCallback(T &&query)
Definition AsyncCallbackProcessor.h:34
AsyncCallbackProcessor< SQLQueryHolderCallback > _queryHolderProcessor
Definition WorldSession.h:1148

References _queryHolderProcessor, and AsyncCallbackProcessor< T >::AddCallback().

Referenced by HandlePlayerLoginOpcode(), InitializeSession(), and Pet::LoadPetFromDB().

◆ AddTransactionCallback()

TransactionCallback & WorldSession::AddTransactionCallback ( TransactionCallback &&  callback)
1325{
1326 return _transactionCallbacks.AddCallback(std::move(callback));
1327}
AsyncCallbackProcessor< TransactionCallback > _transactionCallbacks
Definition WorldSession.h:1147

References _transactionCallbacks, and AsyncCallbackProcessor< T >::AddCallback().

◆ BuildPartyMemberStatsChangedPacket()

void WorldSession::BuildPartyMemberStatsChangedPacket ( Player player,
WorldPacket data 
)
760{
761 uint32 mask = player->GetGroupUpdateFlag();
762
763 if (mask == GROUP_UPDATE_FLAG_NONE)
764 return;
765
766 if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also
768
769 if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets
771
772 uint32 byteCount = 0;
773 for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i)
774 if (mask & (1 << i))
775 byteCount += GroupUpdateLength[i];
776
777 data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount);
778 *data << player->GetPackGUID();
779 *data << uint32(mask);
780
781 if (mask & GROUP_UPDATE_FLAG_STATUS)
782 {
783 uint16 playerStatus = MEMBER_STATUS_ONLINE;
784 if (player->IsPvP())
785 playerStatus |= MEMBER_STATUS_PVP;
786
787 if (!player->IsAlive())
788 {
790 playerStatus |= MEMBER_STATUS_GHOST;
791 else
792 playerStatus |= MEMBER_STATUS_DEAD;
793 }
794
795 if (player->IsFFAPvP())
796 playerStatus |= MEMBER_STATUS_PVP_FFA;
797
798 if (player->isAFK())
799 playerStatus |= MEMBER_STATUS_AFK;
800
801 if (player->isDND())
802 playerStatus |= MEMBER_STATUS_DND;
803
804 *data << uint16(playerStatus);
805 }
806
807 if (mask & GROUP_UPDATE_FLAG_CUR_HP)
808 *data << uint32(player->GetHealth());
809
810 if (mask & GROUP_UPDATE_FLAG_MAX_HP)
811 *data << uint32(player->GetMaxHealth());
812
813 Powers powerType = player->getPowerType();
815 *data << uint8(powerType);
816
818 *data << uint16(player->GetPower(powerType));
819
821 *data << uint16(player->GetMaxPower(powerType));
822
823 if (mask & GROUP_UPDATE_FLAG_LEVEL)
824 *data << uint16(player->GetLevel());
825
826 if (mask & GROUP_UPDATE_FLAG_ZONE)
827 *data << uint16(player->GetZoneId());
828
830 {
831 *data << uint16(player->GetPositionX());
832 *data << uint16(player->GetPositionY());
833 }
834
835 if (mask & GROUP_UPDATE_FLAG_AURAS)
836 {
837 uint64 auramask = player->GetAuraUpdateMaskForRaid();
838 *data << uint64(auramask);
839 for (uint32 i = 0; i < MAX_AURAS_GROUP_UPDATE; ++i)
840 {
841 if (auramask & (uint64(1) << i))
842 {
843 AuraApplication const* aurApp = player->GetVisibleAura(i);
844 *data << uint32(aurApp ? aurApp->GetBase()->GetId() : 0);
845 *data << uint8(1);
846 }
847 }
848 }
849
850 Pet* pet = player->GetPet();
852 {
853 if (pet)
854 *data << pet->GetGUID();
855 else
856 *data << (uint64) 0;
857 }
858
860 {
861 if (pet)
862 *data << pet->GetName();
863 else
864 *data << uint8(0);
865 }
866
868 {
869 if (pet)
870 *data << uint16(pet->GetDisplayId());
871 else
872 *data << uint16(0);
873 }
874
876 {
877 if (pet)
878 *data << uint32(pet->GetHealth());
879 else
880 *data << uint32(0);
881 }
882
884 {
885 if (pet)
886 *data << uint32(pet->GetMaxHealth());
887 else
888 *data << uint32(0);
889 }
890
892 {
893 if (pet)
894 *data << uint8(pet->getPowerType());
895 else
896 *data << uint8(0);
897 }
898
900 {
901 if (pet)
902 *data << uint16(pet->GetPower(pet->getPowerType()));
903 else
904 *data << uint16(0);
905 }
906
908 {
909 if (pet)
910 *data << uint16(pet->GetMaxPower(pet->getPowerType()));
911 else
912 *data << uint16(0);
913 }
914
916 {
917 if (pet)
918 {
919 uint64 auramask = pet->GetAuraUpdateMaskForRaid();
920 *data << uint64(auramask);
921 for (uint32 i = 0; i < MAX_AURAS_GROUP_UPDATE; ++i)
922 {
923 if (auramask & (uint64(1) << i))
924 {
925 AuraApplication const* aurApp = pet->GetVisibleAura(i);
926 *data << uint32(aurApp ? aurApp->GetBase()->GetId() : 0);
927 *data << uint8(aurApp ? aurApp->GetFlags() : 0);
928 }
929 }
930 }
931 else
932 *data << uint64(0);
933 }
934
936 {
937 if (Vehicle* veh = player->GetVehicle())
938 * data << uint32(veh->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]);
939 else
940 *data << uint32(0);
941 }
942}
std::uint8_t uint8
Definition Define.h:109
std::uint32_t uint32
Definition Define.h:107
std::uint64_t uint64
Definition Define.h:106
std::uint16_t uint16
Definition Define.h:108
@ MEMBER_STATUS_AFK
Definition Group.h:67
@ MEMBER_STATUS_PVP
Definition Group.h:62
@ MEMBER_STATUS_ONLINE
Definition Group.h:61
@ MEMBER_STATUS_DEAD
Definition Group.h:63
@ MEMBER_STATUS_GHOST
Definition Group.h:64
@ MEMBER_STATUS_DND
Definition Group.h:68
@ MEMBER_STATUS_PVP_FFA
Definition Group.h:65
static const uint8 GroupUpdateLength[GROUP_UPDATE_FLAGS_COUNT]
Definition Group.h:140
@ GROUP_UPDATE_FLAG_CUR_HP
Definition Group.h:101
@ GROUP_UPDATE_FLAG_PET_CUR_HP
Definition Group.h:113
@ GROUP_UPDATE_FLAG_POWER_TYPE
Definition Group.h:103
@ GROUP_UPDATE_FLAG_PET_CUR_POWER
Definition Group.h:116
@ GROUP_UPDATE_FLAG_PET_MAX_POWER
Definition Group.h:117
@ GROUP_UPDATE_FLAG_MAX_HP
Definition Group.h:102
@ GROUP_UPDATE_FLAG_VEHICLE_SEAT
Definition Group.h:119
@ GROUP_UPDATE_FLAG_STATUS
Definition Group.h:100
@ GROUP_UPDATE_FLAG_PET_POWER_TYPE
Definition Group.h:115
@ GROUP_UPDATE_FLAG_MAX_POWER
Definition Group.h:105
@ GROUP_UPDATE_FLAG_ZONE
Definition Group.h:107
@ GROUP_UPDATE_FLAG_NONE
Definition Group.h:99
@ GROUP_UPDATE_FLAG_POSITION
Definition Group.h:108
@ GROUP_UPDATE_FLAG_PET_MODEL_ID
Definition Group.h:112
@ GROUP_UPDATE_FLAG_PET_NAME
Definition Group.h:111
@ GROUP_UPDATE_FLAG_PET_AURAS
Definition Group.h:118
@ GROUP_UPDATE_FLAG_AURAS
Definition Group.h:109
@ GROUP_UPDATE_FLAG_LEVEL
Definition Group.h:106
@ GROUP_UPDATE_FLAG_PET_GUID
Definition Group.h:110
@ GROUP_UPDATE_FLAG_PET_MAX_HP
Definition Group.h:114
@ GROUP_UPDATE_FLAG_CUR_POWER
Definition Group.h:104
#define GROUP_UPDATE_FLAGS_COUNT
Definition Group.h:138
@ PLAYER_FLAGS_GHOST
Definition Player.h:472
Powers
Definition SharedDefines.h:279
#define MAX_AURAS_GROUP_UPDATE
Definition SpellAuraDefines.h:22
Definition SpellAuras.h:37
uint8 GetFlags() const
Definition SpellAuras.h:65
Aura * GetBase() const
Definition SpellAuras.h:62
uint32 GetId() const
Definition SpellAuras.cpp:405
PackedGuid const & GetPackGUID() const
Definition Object.h:115
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:113
Definition Pet.h:41
uint64 GetAuraUpdateMaskForRaid() const
Definition Pet.h:136
uint64 GetAuraUpdateMaskForRaid() const
Definition Player.h:2489
Pet * GetPet() const
Definition Player.cpp:8997
bool IsFFAPvP()
Definition Player.cpp:16227
bool isDND() const
Definition Player.h:1137
uint32 GetGroupUpdateFlag() const
Definition Player.h:2487
bool HasPlayerFlag(PlayerFlags flags) const
Definition Player.h:1110
bool isAFK() const
Definition Player.h:1136
bool IsPvP()
Definition Player.cpp:16236
Vehicle * GetVehicle() const
Definition Unit.h:1905
AuraApplication * GetVisibleAura(uint8 slot)
Definition Unit.h:1525
uint32 GetMaxHealth() const
Definition Unit.h:1094
bool IsAlive() const
Definition Unit.h:1773
uint32 GetDisplayId() const
Definition Unit.h:1953
uint32 GetMaxPower(Powers power) const
Definition Unit.h:1121
uint32 GetHealth() const
Definition Unit.h:1093
Powers getPowerType() const
Definition Unit.h:1116
uint32 GetPower(Powers power) const
Definition Unit.h:1120
uint8 GetLevel() const
Definition Unit.h:1088
Definition Vehicle.h:28
std::string const & GetName() const
Definition Object.h:524
uint32 GetZoneId() const
Definition Object.cpp:3056
MovementInfo m_movementInfo
Definition Object.h:692
void Initialize(uint16 opcode, std::size_t newres=200)
Definition WorldPacket.h:68
@ SMSG_PARTY_MEMBER_STATS
Definition Opcodes.h:156
int8 seat
Definition Object.h:309
struct MovementInfo::TransportInfo transport
float GetPositionX() const
Definition Position.h:121
float GetPositionY() const
Definition Position.h:122

References Pet::GetAuraUpdateMaskForRaid(), Player::GetAuraUpdateMaskForRaid(), AuraApplication::GetBase(), Unit::GetDisplayId(), AuraApplication::GetFlags(), Player::GetGroupUpdateFlag(), Object::GetGUID(), Unit::GetHealth(), Aura::GetId(), Unit::GetLevel(), Unit::GetMaxHealth(), Unit::GetMaxPower(), WorldObject::GetName(), Object::GetPackGUID(), Player::GetPet(), Position::GetPositionX(), Position::GetPositionY(), Unit::GetPower(), Unit::getPowerType(), Unit::GetVehicle(), Unit::GetVisibleAura(), WorldObject::GetZoneId(), GROUP_UPDATE_FLAG_AURAS, GROUP_UPDATE_FLAG_CUR_HP, GROUP_UPDATE_FLAG_CUR_POWER, GROUP_UPDATE_FLAG_LEVEL, GROUP_UPDATE_FLAG_MAX_HP, GROUP_UPDATE_FLAG_MAX_POWER, GROUP_UPDATE_FLAG_NONE, GROUP_UPDATE_FLAG_PET_AURAS, GROUP_UPDATE_FLAG_PET_CUR_HP, GROUP_UPDATE_FLAG_PET_CUR_POWER, GROUP_UPDATE_FLAG_PET_GUID, GROUP_UPDATE_FLAG_PET_MAX_HP, GROUP_UPDATE_FLAG_PET_MAX_POWER, GROUP_UPDATE_FLAG_PET_MODEL_ID, GROUP_UPDATE_FLAG_PET_NAME, GROUP_UPDATE_FLAG_PET_POWER_TYPE, GROUP_UPDATE_FLAG_POSITION, GROUP_UPDATE_FLAG_POWER_TYPE, GROUP_UPDATE_FLAG_STATUS, GROUP_UPDATE_FLAG_VEHICLE_SEAT, GROUP_UPDATE_FLAG_ZONE, GROUP_UPDATE_FLAGS_COUNT, GroupUpdateLength, Player::HasPlayerFlag(), WorldPacket::Initialize(), Player::isAFK(), Unit::IsAlive(), Player::isDND(), Player::IsFFAPvP(), Player::IsPvP(), WorldObject::m_movementInfo, MAX_AURAS_GROUP_UPDATE, MEMBER_STATUS_AFK, MEMBER_STATUS_DEAD, MEMBER_STATUS_DND, MEMBER_STATUS_GHOST, MEMBER_STATUS_ONLINE, MEMBER_STATUS_PVP, MEMBER_STATUS_PVP_FFA, PLAYER_FLAGS_GHOST, MovementInfo::TransportInfo::seat, SMSG_PARTY_MEMBER_STATS, and MovementInfo::transport.

Referenced by Group::UpdatePlayerOutOfRange().

◆ CanOpenMailBox()

bool WorldSession::CanOpenMailBox ( ObjectGuid  guid)
38{
39 if (guid == _player->GetGUID())
40 {
42 {
43 LOG_ERROR("network.opcode", "{} attempt open mailbox in cheating way.", _player->GetName());
44 return false;
45 }
46 }
47 else if (guid.IsGameObject())
48 {
50 return false;
51 }
52 else if (guid.IsAnyTypeCreature())
53 {
55 return false;
56 }
57 else
58 return false;
59
60 return true;
61}
@ SEC_MODERATOR
Definition Common.h:58
#define LOG_ERROR(filterType__,...)
Definition Log.h:158
@ GAMEOBJECT_TYPE_MAILBOX
Definition SharedDefines.h:1590
@ UNIT_NPC_FLAG_MAILBOX
Definition UnitDefines.h:345
bool IsGameObject() const
Definition ObjectGuid.h:171
bool IsAnyTypeCreature() const
Definition ObjectGuid.h:167
Creature * GetNPCIfCanInteractWith(ObjectGuid const &guid, uint32 npcflagmask)
Definition Player.cpp:2069
WorldSession * GetSession() const
Definition Player.h:1998
GameObject * GetGameObjectIfCanInteractWith(ObjectGuid const &guid, GameobjectTypes type) const
Definition Player.cpp:2126
AccountTypes GetSecurity() const
Definition WorldSession.h:421

References _player, GAMEOBJECT_TYPE_MAILBOX, Player::GetGameObjectIfCanInteractWith(), Object::GetGUID(), WorldObject::GetName(), Player::GetNPCIfCanInteractWith(), GetSecurity(), Player::GetSession(), ObjectGuid::IsAnyTypeCreature(), ObjectGuid::IsGameObject(), LOG_ERROR, SEC_MODERATOR, and UNIT_NPC_FLAG_MAILBOX.

Referenced by HandleGetMailList(), HandleMailCreateTextItem(), HandleMailDelete(), HandleMailMarkAsRead(), HandleMailReturnToSender(), HandleMailTakeItem(), HandleMailTakeMoney(), and HandleSendMail().

◆ CanSkipQueue()

bool WorldSession::CanSkipQueue ( ) const
inline
422{ return _skipQueue; }

References _skipQueue.

Referenced by WorldSessionMgr::AddSession_().

◆ CanUseBank()

bool WorldSession::CanUseBank ( ObjectGuid  bankerGUID = ObjectGuid::Empty) const
private
27{
28 // bankerGUID parameter is optional, set to 0 by default.
29 if (!bankerGUID)
30 bankerGUID = m_currentBankerGUID;
31
32 bool isUsingBankCommand = (bankerGUID == GetPlayer()->GetGUID() && bankerGUID == m_currentBankerGUID);
33
34 if (!isUsingBankCommand)
35 {
37 if (!creature)
38 return false;
39 }
40
41 return true;
42}
@ UNIT_NPC_FLAG_BANKER
Definition UnitDefines.h:336
Definition Creature.h:47
Player * GetPlayer() const
Definition WorldSession.h:424
ObjectGuid m_currentBankerGUID
Definition WorldSession.h:1236

References Object::GetGUID(), Player::GetNPCIfCanInteractWith(), GetPlayer(), m_currentBankerGUID, and UNIT_NPC_FLAG_BANKER.

Referenced by HandleAutoBankItemOpcode(), HandleAutoStoreBankItemOpcode(), HandleBuyBankSlotOpcode(), HandleSwapInvItemOpcode(), and HandleSwapItem().

◆ CheckStableMaster()

bool WorldSession::CheckStableMaster ( ObjectGuid  guid)
664{
665 // spell case or GM
666 if (guid == GetPlayer()->GetGUID())
667 {
668 if (!GetPlayer()->IsGameMaster() && !GetPlayer()->HasOpenStableAura())
669 {
670 LOG_DEBUG("network.opcode", "Player ({}) attempt open stable in cheating way.", guid.ToString());
671 return false;
672 }
673 }
674 // stable master case
675 else
676 {
677 if (!GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_STABLEMASTER))
678 {
679 LOG_DEBUG("network.opcode", "Stablemaster ({}) not found or you can't interact with him.", guid.ToString());
680 return false;
681 }
682 }
683 return true;
684}
#define LOG_DEBUG(filterType__,...)
Definition Log.h:170
@ UNIT_NPC_FLAG_STABLEMASTER
Definition UnitDefines.h:341
std::string ToString() const
Definition ObjectGuid.cpp:47

References GetPlayer(), LOG_DEBUG, ObjectGuid::ToString(), and UNIT_NPC_FLAG_STABLEMASTER.

Referenced by HandleBuyStableSlot(), HandleListStabledPetsOpcode(), HandleStablePet(), HandleStableSwapPet(), and HandleUnstablePet().

◆ ComputeNewClockDelta()

void WorldSession::ComputeNewClockDelta ( )
private
937{
938 // implementation of the technique described here: https://web.archive.org/web/20180430214420/http://www.mine-control.com/zack/timesync/timesync.html
939 // to reduce the skew induced by dropped TCP packets that get resent.
940
941 std::vector<uint32> latencies;
942 std::vector<int64> clockDeltasAfterFiltering;
943
944 for (auto& pair : _timeSyncClockDeltaQueue.content())
945 latencies.push_back(pair.second);
946
947 uint32 latencyMedian = median(latencies);
948 uint32 latencyStandardDeviation = standard_deviation(latencies);
949
950 uint32 sampleSizeAfterFiltering = 0;
951 for (auto& pair : _timeSyncClockDeltaQueue.content())
952 {
953 if (pair.second <= latencyMedian + latencyStandardDeviation)
954 {
955 clockDeltasAfterFiltering.push_back(pair.first);
956 sampleSizeAfterFiltering++;
957 }
958 }
959
960 if (sampleSizeAfterFiltering != 0)
961 {
962 int64 meanClockDelta = static_cast<int64>(mean(clockDeltasAfterFiltering));
963 if (std::abs(meanClockDelta - _timeSyncClockDelta) > 25)
964 _timeSyncClockDelta = meanClockDelta;
965 }
966 else if (_timeSyncClockDelta == 0)
967 {
968 std::pair<int64, uint32> back = _timeSyncClockDeltaQueue.peak_back();
969 _timeSyncClockDelta = back.first;
970 }
971}
std::int64_t int64
Definition Define.h:102
T median(std::vector< T > a)
Definition MathUtil.h:59
T standard_deviation(Container &&c)
Definition MathUtil.h:28
T mean(Container &&c)
Definition MathUtil.h:49
T peak_back()
Definition CircularBuffer.h:88

References _timeSyncClockDelta, _timeSyncClockDeltaQueue, CircularBuffer< T >::content(), mean(), median(), CircularBuffer< T >::peak_back(), and standard_deviation().

Referenced by HandleTimeSyncResp().

◆ DisallowHyperlinksAndMaybeKick()

bool WorldSession::DisallowHyperlinksAndMaybeKick ( std::string_view  str)
820{
821 if (str.find('|') == std::string_view::npos)
822 return true;
823
824 LOG_ERROR("network", "Player {} {} sent a message which illegally contained a hyperlink:\n{}", GetPlayer()->GetName(),
825 GetPlayer()->GetGUID().ToString(), str);
826
828 KickPlayer("WorldSession::DisallowHyperlinksAndMaybeKick Illegal chat link");
829
830 return false;
831}
@ CONFIG_CHAT_STRICT_LINK_CHECKING_KICK
Definition WorldConfig.h:243
void KickPlayer(bool setKicked=true)
Definition WorldSession.h:462
bool GetName(uint32 accountId, std::string &name)
Definition AccountMgr.cpp:264
std::string ToString(Type &&val, Params &&... params)
Definition StringConvert.h:250

References CONFIG_CHAT_STRICT_LINK_CHECKING_KICK, GetPlayer(), KickPlayer(), LOG_ERROR, and sWorld.

Referenced by HandleJoinChannel().

◆ DoLootRelease()

void WorldSession::DoLootRelease ( ObjectGuid  lguid)
271{
272 Player* player = GetPlayer();
273 Loot* loot;
274
276 player->SendLootRelease(lguid);
277
279
280 if (!player->IsInWorld())
281 return;
282
283 if (lguid.IsGameObject())
284 {
285 GameObject* go = GetPlayer()->GetMap()->GetGameObject(lguid);
286
287 // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO
288 if (!go || ((go->GetOwnerGUID() != _player->GetGUID() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player)))
289 {
290 return;
291 }
292
293 loot = &go->loot;
294
295 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR)
296 {
297 // locked doors are opened with spelleffect openlock, prevent remove its as looted
298 go->UseDoorOrButton();
299 }
300 else if (loot->isLooted() || go->GetGoType() == GAMEOBJECT_TYPE_FISHINGNODE)
301 {
303 {
304 // The fishing hole used once more
305 go->AddUse(); // if the max usage is reached, will be despawned in next tick
306 if (go->GetUseCount() >= go->GetGOValue()->FishingHole.MaxOpens)
308 else
310 }
311 else
312 {
314
315 // Xinef: moved event execution to loot release (after everything is looted)
316 // Xinef: 99% sure that this worked like this on blizz
317 // Xinef: prevents exploits with just opening GO and spawning bilions of npcs, which can crash core if you know what you're doin ;)
319 {
320 LOG_DEBUG("spells.aura", "Chest ScriptStart id {} for GO {}", go->GetGOInfo()->chest.eventId, go->GetSpawnId());
321 player->GetMap()->ScriptsStart(sEventScripts, go->GetGOInfo()->chest.eventId, player, go);
322 }
323 }
324
325 loot->clear();
326 }
327 else
328 {
329 // not fully looted object
330 go->SetLootState(GO_ACTIVATED, player);
331
332 // if the round robin player release, reset it.
333 if (player->GetGUID() == loot->roundRobinPlayer)
334 loot->roundRobinPlayer.Clear();
335 }
336 }
337 else if (lguid.IsCorpse()) // ONLY remove insignia at BG
338 {
339 Corpse* corpse = ObjectAccessor::GetCorpse(*player, lguid);
340 if (!corpse || !corpse->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
341 return;
342
343 loot = &corpse->loot;
344
345 // Xinef: Buggs client? (Opening loot after closing)
346 //if (loot->isLooted())
347 {
348 loot->clear();
350 }
351 }
352 else if (lguid.IsItem())
353 {
354 Item* pItem = player->GetItemByGuid(lguid);
355 if (!pItem)
356 return;
357
358 loot = &pItem->loot;
359 ItemTemplate const* proto = pItem->GetTemplate();
360
361 // destroy only 5 items from stack in case prospecting and milling
363 {
364 pItem->m_lootGenerated = false;
365 pItem->loot.clear();
366
367 uint32 count = pItem->GetCount();
368
369 // >=5 checked in spell code, but will work for cheating cases also with removing from another stacks.
370 if (count > 5)
371 count = 5;
372
373 player->DestroyItemCount(pItem, count, true);
374 }
375 else if (pItem->loot.isLooted() || !proto->HasFlag(ITEM_FLAG_HAS_LOOT))
376 {
377 player->DestroyItem(pItem->GetBagSlot(), pItem->GetSlot(), true);
378 return;
379 }
380 }
381 else
382 {
383 Creature* creature = GetPlayer()->GetMap()->GetCreature(lguid);
384
385 bool lootAllowed = creature && creature->IsAlive() == (player->IsClass(CLASS_ROGUE, CLASS_CONTEXT_ABILITY) && creature->loot.loot_type == LOOT_PICKPOCKETING);
386 if (!lootAllowed || !creature->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
387 return;
388
389 loot = &creature->loot;
390 if (loot->isLooted())
391 {
392 // skip pickpocketing loot for speed, skinning timer reduction is no-op in fact
393 if (!creature->IsAlive())
394 creature->AllLootRemovedFromCorpse();
395
397 loot->clear();
398 }
399 else
400 {
401 // if the round robin player release, reset it.
402 if (player->GetGUID() == loot->roundRobinPlayer)
403 {
404 loot->roundRobinPlayer.Clear();
405
406 if (Group* group = player->GetGroup())
407 group->SendLooter(creature, nullptr);
408 }
409 // force dynflag update to update looter and lootable info
411 }
412 }
413
414 //Player is not looking at loot list, he doesn't need to see updates on the loot list
415 if (!lguid.IsItem())
416 {
417 loot->RemoveLooter(player->GetGUID());
418 }
419}
@ GO_ACTIVATED
Definition GameObject.h:112
@ GO_READY
Definition GameObject.h:111
@ GO_JUST_DEACTIVATED
Definition GameObject.h:113
@ ITEM_FLAG_IS_MILLABLE
Definition ItemTemplate.h:176
@ ITEM_FLAG_IS_PROSPECTABLE
Definition ItemTemplate.h:165
@ ITEM_FLAG_HAS_LOOT
Definition ItemTemplate.h:149
@ LOOT_PICKPOCKETING
Definition LootMgr.h:81
#define INTERACTION_DISTANCE
Definition ObjectDefines.h:24
ScriptMapMap sEventScripts
Definition ObjectMgr.cpp:60
@ GAMEOBJECT_TYPE_CHEST
Definition SharedDefines.h:1574
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition SharedDefines.h:1596
@ GAMEOBJECT_TYPE_FISHINGNODE
Definition SharedDefines.h:1588
@ GAMEOBJECT_TYPE_DOOR
Definition SharedDefines.h:1571
@ CORPSE_DYNFLAG_LOOTABLE
Definition SharedDefines.h:3383
@ UNIT_DYNFLAG_LOOTABLE
Definition SharedDefines.h:3371
@ CLASS_ROGUE
Definition SharedDefines.h:144
@ CLASS_CONTEXT_ABILITY
Definition UnitDefines.h:238
@ UNIT_FLAG_LOOTING
Definition UnitDefines.h:264
@ CORPSE_FIELD_DYNAMIC_FLAGS
Definition UpdateFields.h:428
@ UNIT_DYNAMIC_FLAGS
Definition UpdateFields.h:136
Definition Corpse.h:49
Loot loot
Definition Corpse.h:77
Loot loot
Definition Creature.h:229
void AllLootRemovedFromCorpse()
Definition Creature.cpp:3002
Definition GameObject.h:120
bool IsWithinDistInMap(Player const *player) const
Definition GameObject.cpp:2995
Loot loot
Definition GameObject.h:246
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
Definition GameObject.cpp:1410
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:136
void AddUse()
Definition GameObject.h:238
GameObjectValue const * GetGOValue() const
Definition GameObject.h:139
void SetLootState(LootState s, Unit *unit=nullptr)
Definition GameObject.cpp:2434
ObjectGuid GetOwnerGUID() const
Definition GameObject.h:173
GameobjectTypes GetGoType() const
Definition GameObject.h:202
ObjectGuid::LowType GetSpawnId() const
Definition GameObject.h:144
uint32 GetUseCount() const
Definition GameObject.h:240
Definition Group.h:169
Definition Item.h:220
uint8 GetSlot() const
Definition Item.h:281
ItemTemplate const * GetTemplate() const
Definition Item.cpp:544
bool m_lootGenerated
Definition Item.h:321
uint32 GetCount() const
Definition Item.h:272
Loot loot
Definition Item.h:320
uint8 GetBagSlot() const
Definition Item.cpp:784
void ScriptsStart(std::map< uint32, std::multimap< uint32, ScriptInfo > > const &scripts, uint32 id, Object *source, Object *target)
Put scripts in the execution queue.
Definition MapScripts.cpp:31
GameObject * GetGameObject(ObjectGuid const &guid)
Definition Map.cpp:2362
Creature * GetCreature(ObjectGuid const &guid)
Definition Map.cpp:2357
static ObjectGuid const Empty
Definition ObjectGuid.h:120
bool IsCorpse() const
Definition ObjectGuid.h:173
bool IsItem() const
Definition ObjectGuid.h:170
void Clear()
Definition ObjectGuid.h:138
virtual void RemoveDynamicFlag(uint32 flag)
Definition Object.h:125
bool IsInWorld() const
Definition Object.h:108
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition Object.cpp:842
void ForceValuesUpdateAtIndex(uint32)
Definition Object.cpp:2070
Definition Player.h:1071
void SendLootRelease(ObjectGuid guid)
Definition Player.cpp:7842
void SetLootGUID(ObjectGuid guid)
Definition Player.h:1994
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition PlayerStorage.cpp:3024
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition Player.cpp:1301
Group * GetGroup()
Definition Player.h:2482
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition PlayerStorage.cpp:3117
Item * GetItemByGuid(ObjectGuid guid) const
Definition PlayerStorage.cpp:409
void RemoveUnitFlag(UnitFlags flags)
UnitFlags available in UnitDefines.h.
Definition Unit.h:739
Map * GetMap() const
Definition Object.h:620
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1347
Corpse * GetCorpse(WorldObject const &u, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:179
uint32 eventId
Definition GameObjectData.h:89
struct GameObjectTemplate::@233::@238 chest
Definition ItemTemplate.h:619
bool HasFlag(ItemFlags flag) const
Definition ItemTemplate.h:825
ItemFlags Flags
Definition ItemTemplate.h:627
Definition LootMgr.h:313
bool isLooted() const
Definition LootMgr.h:368
void clear()
Definition LootMgr.h:343
ObjectGuid roundRobinPlayer
Definition LootMgr.h:324
void RemoveLooter(ObjectGuid GUID)
Definition LootMgr.h:374
LootType loot_type
Definition LootMgr.h:326
uint32 MaxOpens
Definition GameObject.h:60
struct GameObjectValue::@230 FishingHole

References _player, GameObject::AddUse(), Creature::AllLootRemovedFromCorpse(), GameObjectTemplate::chest, CLASS_CONTEXT_ABILITY, CLASS_ROGUE, ObjectGuid::Clear(), Loot::clear(), CORPSE_DYNFLAG_LOOTABLE, CORPSE_FIELD_DYNAMIC_FLAGS, Player::DestroyItem(), Player::DestroyItemCount(), ObjectGuid::Empty, GameObjectTemplate::eventId, GameObjectValue::FishingHole, ItemTemplate::Flags, Object::ForceValuesUpdateAtIndex(), GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_FISHINGHOLE, GAMEOBJECT_TYPE_FISHINGNODE, Item::GetBagSlot(), ObjectAccessor::GetCorpse(), Item::GetCount(), Map::GetCreature(), Map::GetGameObject(), GameObject::GetGOInfo(), GameObject::GetGoType(), GameObject::GetGOValue(), Player::GetGroup(), Object::GetGUID(), Player::GetItemByGuid(), WorldObject::GetMap(), GameObject::GetOwnerGUID(), GetPlayer(), Item::GetSlot(), GameObject::GetSpawnId(), Item::GetTemplate(), GameObject::GetUseCount(), GO_ACTIVATED, GO_JUST_DEACTIVATED, GO_READY, ItemTemplate::HasFlag(), INTERACTION_DISTANCE, Unit::IsAlive(), Player::IsClass(), ObjectGuid::IsCorpse(), ObjectGuid::IsGameObject(), Object::IsInWorld(), ObjectGuid::IsItem(), Loot::isLooted(), GameObject::IsWithinDistInMap(), WorldObject::IsWithinDistInMap(), ITEM_FLAG_HAS_LOOT, ITEM_FLAG_IS_MILLABLE, ITEM_FLAG_IS_PROSPECTABLE, LOG_DEBUG, Corpse::loot, Creature::loot, GameObject::loot, Item::loot, LOOT_PICKPOCKETING, Loot::loot_type, Item::m_lootGenerated, GameObjectValue::MaxOpens, Object::RemoveDynamicFlag(), Object::RemoveFlag(), Loot::RemoveLooter(), Unit::RemoveUnitFlag(), Loot::roundRobinPlayer, Map::ScriptsStart(), Player::SendLootRelease(), Player::SetLootGUID(), GameObject::SetLootState(), sEventScripts, UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE, UNIT_FLAG_LOOTING, and GameObject::UseDoorOrButton().

Referenced by HandleAutostoreLootItemOpcode(), HandleLogoutRequestOpcode(), HandleLootMoneyOpcode(), HandleLootReleaseOpcode(), LogoutPlayer(), Player::RemoveFromWorld(), Player::SendLoot(), and Player::SwapItem().

◆ Expansion()

◆ GetAccountData()

AccountData * WorldSession::GetAccountData ( AccountDataType  type)
inline
512{ return &m_accountData[type]; }
AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES]
Definition WorldSession.h:1228

References m_accountData.

Referenced by HandleRequestAccountData(), and SendAccountDataTimes().

◆ GetAccountFlags()

uint32 WorldSession::GetAccountFlags ( ) const
inline
374{ return _accountFlags; }

References _accountFlags.

Referenced by misc_commandscript::HandlePInfoCommand().

◆ GetAccountId()

uint32 WorldSession::GetAccountId ( ) const
inline
423{ return _accountId; }

References _accountId.

Referenced by Player::_SaveInstanceTimeRestrictions(), WorldSessionMgr::AddSession_(), Warden::ApplyPenalty(), CharacterActionIpLogger::CharacterIPLogAction(), Spell::CheckCast(), Spell::CheckEffectTarget(), WorldSession::DosProtection::EvaluateOpcode(), GetPlayerInfo(), Player::GetsRecruitAFriendBonus(), HandleAcceptGrantLevel(), HandleAcceptTradeOpcode(), account_commandscript::HandleAccount2FARemoveCommand(), account_commandscript::HandleAccount2FASetupCommand(), account_commandscript::HandleAccountAddonCommand(), account_commandscript::HandleAccountCreateCommand(), account_commandscript::HandleAccountLockCountryCommand(), account_commandscript::HandleAccountLockIpCommand(), account_commandscript::HandleAccountPasswordCommand(), account_commandscript::HandleAccountSetAddonCommand(), account_commandscript::HandleAccountSetGmLevelCommand(), HandleAuctionPlaceBid(), HandleCharCreateOpcode(), HandleCharCustomize(), HandleCharCustomizeCallback(), HandleCharDeleteOpcode(), HandleCharEnum(), HandleCharEnumOpcode(), HandleCharFactionOrRaceChange(), HandleCharFactionOrRaceChangeCallback(), HandleCharRenameCallBack(), HandleCharRenameOpcode(), WardenWin::HandleData(), HandleDismissCritter(), HandleForceSpeedChangeAck(), HandleGrantLevel(), HandleMailReturnToSender(), HandleMailTakeItem(), Guild::HandleMemberDepositMoney(), Guild::HandleMemberWithdrawMoney(), misc_commandscript::HandleMuteCommand(), HandlePetitionSignOpcode(), misc_commandscript::HandlePInfoCommand(), HandlePlayerLoginFromDB(), HandlePlayerLoginOpcode(), HandleSendMail(), misc_commandscript::HandleUnmuteCommand(), HandleWhoisOpcode(), WorldSessionMgr::HasRecentlyDisconnected(), WardenMac::Init(), WardenWin::Init(), InitializeSession(), BattlegroundQueue::InviteGroupToBG(), Channel::JoinChannel(), Channel::KickOrBan(), KickPlayer(), Player::LoadFromDB(), LogCommandUsage(), LogoutPlayer(), go_ulduar_pure_saronite_deposit::OnGossipHello(), SaveTutorialsData(), AuctionHouseMgr::SendAuctionWonMail(), SetAccountData(), Channel::SetMode(), Channel::SetOwner(), Guild::Member::SetStats(), Channel::UnBan(), Update(), UpdateAccountFlag(), WorldSessionMgr::UpdateSessions(), WorldSession(), and ~WorldSession().

◆ GetAcoreString()

std::string WorldSession::GetAcoreString ( uint32  entry) const

◆ GetCalendarEventCreationCooldown()

time_t WorldSession::GetCalendarEventCreationCooldown ( ) const
inline

◆ GetCurrentVendor()

◆ GetGuidLow()

ObjectGuid::LowType WorldSession::GetGuidLow ( ) const

Get player guid if available. Use for logging purposes only.

247{
248 return GetPlayer() ? GetPlayer()->GetGUID().GetCounter() : 0;
249}
LowType GetCounter() const
Definition ObjectGuid.h:145

References ObjectGuid::GetCounter(), Object::GetGUID(), and GetPlayer().

◆ GetLatency()

◆ GetModuleString()

std::string const * WorldSession::GetModuleString ( std::string  module,
uint32  id 
) const
839{
840 return sObjectMgr->GetModuleString(module, id, GetSessionDbLocaleIndex());
841}

References GetSessionDbLocaleIndex(), and sObjectMgr.

Referenced by ChatHandler::GetModuleString().

◆ GetOfflineTime()

uint32 WorldSession::GetOfflineTime ( ) const
inline
1125{ return _offlineTime; }

References _offlineTime.

Referenced by WorldSessionMgr::UpdateSessions().

◆ GetOrderCounter()

◆ GetPlayer()

Player * WorldSession::GetPlayer ( ) const
inline
424{ return _player; }

References _player.

Referenced by Guild::_SendBankContent(), Guild::_SendBankList(), Warden::ApplyPenalty(), Guild::BroadcastToGuild(), CanUseBank(), CheckStableMaster(), DisallowHyperlinksAndMaybeKick(), DoLootRelease(), go_commandscript::DoTeleport(), ChatHandler::GetCreatureFromPlayerMapByDbGuid(), GetGuidLow(), ChatHandler::GetNearbyGameObject(), ChatHandler::GetObjectFromPlayerMapByDbGuid(), ChatHandler::GetPlayer(), ChatHandler::GetPlayerGroupAndGUIDByName(), ChatHandler::getSelectedCreature(), ChatHandler::getSelectedObject(), ChatHandler::getSelectedPlayer(), ChatHandler::getSelectedPlayerOrSelf(), ChatHandler::getSelectedUnit(), Guild::HandleAcceptMember(), account_commandscript::HandleAccountCreateCommand(), HandleActivateTaxiExpressOpcode(), HandleActivateTaxiOpcode(), HandleAddFriendOpcode(), HandleAddIgnoreOpcode(), misc_commandscript::HandleAddItemCommand(), misc_commandscript::HandleAddItemSetCommand(), Guild::HandleAddNewRank(), misc_commandscript::HandleAppearCommand(), HandleAreaSpiritHealerQueryOpcode(), HandleAreaSpiritHealerQueueOpcode(), HandleAreaTriggerOpcode(), HandleArenaTeamInviteOpcode(), HandleAttackStopOpcode(), HandleAuctionHelloOpcode(), HandleAuctionListBidderItems(), HandleAuctionListItems(), HandleAuctionListOwnerItems(), HandleAuctionPlaceBid(), HandleAuctionRemoveItem(), HandleAuctionSellItem(), HandleAutostoreLootItemOpcode(), bg_commandscript::HandleBagsClearCommand(), HandleBankerActivateOpcode(), HandleBattlemasterHelloOpcode(), HandleBattlemasterJoinArena(), HandleBattlemasterJoinOpcode(), HandleBinderActivateOpcode(), misc_commandscript::HandleBindSightCommand(), misc_commandscript::HandleBMCommand(), HandleBuybackItem(), Guild::HandleBuyBankTab(), HandleBuyItemInSlotOpcode(), HandleBuyItemOpcode(), HandleBuyStableSlot(), HandleCancelTempEnchantmentOpcode(), cast_commandscript::HandleCastBackCommand(), cast_commandscript::HandleCastCommand(), cast_commandscript::HandleCastDistCommand(), cheat_commandscript::HandleCasttimeCheatCommand(), HandleChangeSeatsOnControlledVehicle(), misc_commandscript::HandleChangeWeather(), HandleChannelAnnouncements(), HandleChannelBan(), HandleChannelInvite(), HandleChannelKick(), HandleChannelList(), HandleChannelModerateOpcode(), HandleChannelModerator(), HandleChannelMute(), HandleChannelOwner(), HandleChannelPassword(), HandleChannelSetOwner(), HandleChannelUnban(), HandleChannelUnmoderator(), HandleChannelUnmute(), HandleCharacterAuraFrozen(), character_commandscript::HandleCharacterCheckBankCommand(), character_commandscript::HandleCharacterLevelCommand(), HandleChatIgnoredOpcode(), cheat_commandscript::HandleCheatStatusCommand(), HandleClearChannelWatch(), misc_commandscript::HandleComeToMeCommand(), misc_commandscript::HandleCommentatorCommand(), HandleCompleteCinematic(), cheat_commandscript::HandleCoolDownCheatCommand(), misc_commandscript::HandleCooldownCommand(), HandleCorpseQueryOpcode(), misc_commandscript::HandleDamageCommand(), debug_commandscript::HandleDebugAreaTriggersCommand(), debug_commandscript::HandleDebugHostileRefListCommand(), debug_commandscript::HandleDebugLoSCommand(), debug_commandscript::HandleDebugSendOpcodeCommand(), debug_commandscript::HandleDebugSpawnVehicleCommand(), debug_commandscript::HandleDebugUnitStateCommand(), HandleDelFriendOpcode(), HandleDelIgnoreOpcode(), misc_commandscript::HandleDevCommand(), misc_commandscript::HandleDieCommand(), Guild::HandleDisband(), HandleDismissCritter(), misc_commandscript::HandleDismountCommand(), HandleDuelAcceptedOpcode(), HandleDuelCancelledOpcode(), HandleEjectPassenger(), HandleEmoteOpcode(), cheat_commandscript::HandleExploreCheatCommand(), HandleFarSightOpcode(), gobject_commandscript::HandleGameObjectActivateCommand(), gobject_commandscript::HandleGameObjectAddCommand(), gobject_commandscript::HandleGameObjectAddTempCommand(), gobject_commandscript::HandleGameObjectDeleteCommand(), gobject_commandscript::HandleGameObjectMoveCommand(), gobject_commandscript::HandleGameObjectNearCommand(), HandleGameobjectReportUse(), gobject_commandscript::HandleGameObjectTargetCommand(), gobject_commandscript::HandleGameObjectTurnCommand(), HandleGameObjectUseOpcode(), HandleGetChannelMemberCount(), misc_commandscript::HandleGetDistanceCommand(), gm_commandscript::HandleGMFlyCommand(), gm_commandscript::HandleGMListIngameCommand(), HandleGMResponseResolve(), gm_commandscript::HandleGMSpectatorCommand(), HandleGMSurveySubmit(), ticket_commandscript::HandleGMTicketAssignToCommand(), ticket_commandscript::HandleGMTicketCloseByIdCommand(), ticket_commandscript::HandleGMTicketCommentCommand(), ticket_commandscript::HandleGMTicketCompleteCommand(), HandleGMTicketCreateOpcode(), ticket_commandscript::HandleGMTicketDeleteByIdCommand(), HandleGMTicketDeleteOpcode(), HandleGMTicketGetTicketOpcode(), ticket_commandscript::HandleGMTicketResponseDeleteCommand(), ticket_commandscript::HandleGMTicketUnAssignCommand(), HandleGMTicketUpdateOpcode(), gm_commandscript::HandleGMVisibleCommand(), cheat_commandscript::HandleGodModeCheatCommand(), go_commandscript::HandleGoGraveyardCommand(), go_commandscript::HandleGoGridCommand(), HandleGossipHelloOpcode(), HandleGossipSelectOptionOpcode(), go_commandscript::HandleGoTicketCommand(), go_commandscript::HandleGoXYZCommand(), go_commandscript::HandleGoZoneXYCommand(), misc_commandscript::HandleGPSCommand(), HandleGroupAcceptOpcode(), HandleGroupAssistantLeaderOpcode(), HandleGroupChangeSubGroupOpcode(), HandleGroupDeclineOpcode(), HandleGroupDisbandOpcode(), HandleGroupInviteOpcode(), HandleGroupRaidConvertOpcode(), HandleGroupSetLeaderOpcode(), misc_commandscript::HandleGroupSummonCommand(), HandleGroupSwapSubGroupOpcode(), HandleGroupUninviteGuidOpcode(), HandleGroupUninviteOpcode(), misc_commandscript::HandleGUIDCommand(), HandleGuildAcceptOpcode(), HandleGuildAddRankOpcode(), HandleGuildBankBuyTab(), HandleGuildBankDepositMoney(), HandleGuildBankerActivate(), HandleGuildBankLogQuery(), HandleGuildBankMoneyWithdrawn(), HandleGuildBankQueryTab(), HandleGuildBankSwapItems(), HandleGuildBankUpdateTab(), HandleGuildBankWithdrawMoney(), HandleGuildChangeInfoTextOpcode(), HandleGuildDeclineOpcode(), HandleGuildDelRankOpcode(), HandleGuildDemoteOpcode(), HandleGuildDisbandOpcode(), HandleGuildEventLogQueryOpcode(), HandleGuildInfoOpcode(), HandleGuildInviteOpcode(), HandleGuildLeaderOpcode(), HandleGuildLeaveOpcode(), HandleGuildMOTDOpcode(), HandleGuildPermissions(), HandleGuildPromoteOpcode(), HandleGuildRankOpcode(), HandleGuildRemoveOpcode(), HandleGuildRosterOpcode(), HandleGuildSetOfficerNoteOpcode(), HandleGuildSetPublicNoteOpcode(), honor_commandscript::HandleHonorAddKillCommand(), HandleInitiateTradeOpcode(), HandleInspectArenaTeamsOpcode(), HandleInspectHonorStatsOpcode(), HandleInspectOpcode(), instance_commandscript::HandleInstanceListBindsCommand(), instance_commandscript::HandleInstanceSaveDataCommand(), instance_commandscript::HandleInstanceUnbindCommand(), Guild::HandleInviteMember(), item_commandscript::HandleItemMoveCommand(), HandleItemRefund(), HandleItemRefundInfoRequest(), HandleJoinChannel(), misc_commandscript::HandleKickPlayerCommand(), learn_commandscript::HandleLearnAllCraftsCommand(), learn_commandscript::HandleLearnAllGMCommand(), learn_commandscript::HandleLearnAllMyPetTalentsCommand(), learn_commandscript::HandleLearnAllMySpellsCommand(), learn_commandscript::HandleLearnAllMyTalentsCommand(), HandleLeaveChannel(), Guild::HandleLeaveMember(), character_commandscript::HandleLevelUpCommand(), HandleLfgGetStatus(), HandleLfgJoinOpcode(), HandleLfgLeaveOpcode(), HandleLfgPartyLockInfoRequestOpcode(), HandleLfgPlayerLockInfoRequestOpcode(), HandleLfgProposalResultOpcode(), HandleLfgSetBootVoteOpcode(), HandleLfgSetCommentOpcode(), HandleLfgSetRolesOpcode(), HandleLfgTeleportOpcode(), HandleLfrSearchJoinOpcode(), HandleLfrSearchLeaveOpcode(), misc_commandscript::HandleLinkGraveCommand(), list_commandscript::HandleListCreatureCommand(), HandleListInventoryOpcode(), list_commandscript::HandleListObjectCommand(), HandleListStabledPetsOpcode(), HandleLoadActionsSwitchSpec(), HandleLogoutCancelOpcode(), HandleLogoutRequestOpcode(), lookup_commandscript::HandleLookupPlayerIpCommand(), HandleLootMasterGiveOpcode(), HandleLootMethodOpcode(), HandleLootMoneyOpcode(), HandleLootOpcode(), HandleLootReleaseOpcode(), HandleLootRoll(), misc_commandscript::HandleMailBoxCommand(), Guild::HandleMemberDepositMoney(), Guild::HandleMemberLogout(), Guild::HandleMemberWithdrawMoney(), HandleMessagechatOpcode(), HandleMinimapPingOpcode(), mmaps_commandscript::HandleMmapLoadedTilesCommand(), mmaps_commandscript::HandleMmapLocCommand(), mmaps_commandscript::HandleMmapPathCommand(), mmaps_commandscript::HandleMmapStatsCommand(), mmaps_commandscript::HandleMmapTestArea(), modify_commandscript::HandleModifyPhaseCommand(), modify_commandscript::HandleModifyStandStateCommand(), modify_commandscript::HandleMorphResetCommand(), modify_commandscript::HandleMorphTargetCommand(), HandleMountSpecialAnimOpcode(), HandleMoverRelocation(), HandleMoveSplineDoneOpcode(), HandleMoveTeleportAck(), HandleMoveTimeSkippedOpcode(), HandleMoveWorldportAck(), misc_commandscript::HandleNearGraveCommand(), HandleNextCinematicCamera(), npc_commandscript::HandleNpcAddCommand(), npc_commandscript::HandleNpcAddFormationCommand(), npc_commandscript::HandleNpcAddTempSpawnCommand(), npc_commandscript::HandleNpcAddVendorItemCommand(), npc_commandscript::HandleNpcFollowCommand(), npc_commandscript::HandleNpcMoveCommand(), npc_commandscript::HandleNpcNearCommand(), npc_commandscript::HandleNpcSetFactionTempIdCommand(), npc_commandscript::HandleNpcSetOriginalFaction(), npc_commandscript::HandleNpcTameCommand(), npc_commandscript::HandleNpcUnFollowCommand(), HandleOfferPetitionOpcode(), HandleOpenWrappedItemCallback(), HandleOptOutOfLootOpcode(), HandlePartyAssignmentOpcode(), HandlePetAction(), HandlePetActionHelper(), HandlePetCancelAuraOpcode(), HandlePetCastSpellOpcode(), pet_commandscript::HandlePetCreateCommand(), HandlePetitionBuyOpcode(), HandlePetitionSignOpcode(), pet_commandscript::HandlePetLearnCommand(), HandlePetSetAction(), HandlePetSpellAutocastOpcode(), HandlePetStopAttack(), pet_commandscript::HandlePetUnlearnCommand(), HandlePlayerLoginOpcode(), HandlePlayerLoginToCharInWorld(), misc_commandscript::HandlePossessCommand(), cheat_commandscript::HandlePowerCheatCommand(), HandleQueryGuildBankTabText(), HandleQueryInspectAchievements(), HandleQuestgiverAcceptQuestOpcode(), HandleQuestgiverHelloOpcode(), HandleQuestLogSwapQuest(), HandleRaidReadyCheckFinishedOpcode(), HandleRaidReadyCheckOpcode(), HandleRaidTargetUpdateOpcode(), HandleRandomRollOpcode(), Guild::HandleRemoveMember(), Guild::HandleRemoveRank(), HandleRepairItemOpcode(), HandleRepopRequestOpcode(), HandleReportLag(), HandleRequestVehicleExit(), reset_commandscript::HandleResetSpellsCommand(), reset_commandscript::HandleResetTalentsCommand(), misc_commandscript::HandleRespawnAllCommand(), misc_commandscript::HandleRespawnCommand(), HandleResurrectResponseOpcode(), Guild::HandleRoster(), misc_commandscript::HandleSaveCommand(), HandleSaveGuildEmblemOpcode(), HandleSellItemOpcode(), send_commandscript::HandleSendItemsCommand(), HandleSendMail(), send_commandscript::HandleSendMailCommand(), send_commandscript::HandleSendMoneyCommand(), HandleSetActionBarToggles(), HandleSetActionButtonOpcode(), HandleSetActiveMoverOpcode(), HandleSetChannelWatch(), Guild::HandleSetEmblem(), HandleSetFactionAtWar(), HandleSetFactionCheat(), HandleSetGuildBankTabText(), Guild::HandleSetInfo(), Guild::HandleSetLeader(), Guild::HandleSetMemberNote(), Guild::HandleSetMOTD(), Guild::HandleSetRankInfo(), HandleSetSavedInstanceExtend(), HandleSetTitleOpcode(), HandleSetWatchedFactionOpcode(), HandleSocketClosed(), spectator_commandscript::HandleSpectatorLeaveCommand(), spectator_commandscript::HandleSpectatorResetCommand(), ArenaSpectator::HandleSpectatorSpectateCommand(), spectator_commandscript::HandleSpectatorVersionCommand(), ArenaSpectator::HandleSpectatorWatchCommand(), HandleSpiritHealerActivateOpcode(), HandleStablePet(), HandleStableSwapPet(), misc_commandscript::HandleSummonCommand(), HandleTabardVendorActivateOpcode(), HandleTalentWipeConfirmOpcode(), cheat_commandscript::HandleTaxiCheatCommand(), HandleTaxiQueryAvailableNodes(), tele_commandscript::HandleTeleAddCommand(), tele_commandscript::HandleTeleCommand(), HandleTeleportTimeout(), HandleTextEmoteOpcode(), HandleTogglePvP(), HandleTotemDestroyed(), HandleTrainerBuySpellOpcode(), misc_commandscript::HandleUnbindSightCommand(), HandleUnlearnSkillOpcode(), misc_commandscript::HandleUnPossessCommand(), HandleUnstablePet(), misc_commandscript::HandleUnstuckCommand(), Guild::HandleUpdateMemberRank(), cheat_commandscript::HandleWaterWalkCheatCommand(), message_commandscript::HandleWhispersCommand(), HandleWhoisOpcode(), HandleWorldTeleportOpcode(), wp_commandscript::HandleWpAddCommand(), debug_commandscript::HandleWPGPSCommand(), wp_commandscript::HandleWpModifyCommand(), wp_commandscript::HandleWpShowCommand(), HandleZoneUpdateOpcode(), LogCommandUsage(), ArenaTeam::MassInviteToEvent(), Guild::MassInviteToEvent(), ChatHandler::needReportToTarget(), ServerMailReward::OnPlayerLogin(), MapSessionFilter::Process(), WorldSessionFilter::Process(), ReadMovementInfo(), ResetTimeOutTime(), SendActivateTaxiReply(), SendAttackStop(), SendAuctionHello(), Guild::SendBankTabsInfo(), SendBindPoint(), SendDiscoverNewTaxiNode(), SendDoFlight(), SendEnchantmentLog(), SendLearnNewTaxiNode(), SendLfgBootProposalUpdate(), SendLfgDisabled(), SendLfgJoinResult(), SendLfgLfrList(), SendLfgOfferContinue(), SendLfgPlayerReward(), SendLfgQueueStatus(), SendLfgRoleCheckUpdate(), SendLfgRoleChosen(), SendLfgTeleportError(), SendLfgUpdateProposal(), SendListInventory(), Guild::SendLoginInfo(), Guild::SendMoneyInfo(), Guild::SendPermissions(), SendPetitionShowList(), PlayerMenu::SendQuestGiverOfferReward(), PlayerMenu::SendQuestGiverQuestDetails(), PlayerMenu::SendQuestGiverRequestItems(), PlayerMenu::SendQuestQueryResponse(), SendStablePet(), SendTaxiMenu(), SendTaxiStatus(), SendTrainerList(), ChatHandler::SendWorldTextOptional(), ticket_commandscript::TicketResponseAppend(), Update(), WorldSessionMgr::UpdateSessions(), and ValidateHyperlinksAndMaybeKick().

◆ GetPlayerInfo()

std::string WorldSession::GetPlayerInfo ( ) const
217{
218 std::ostringstream ss;
219
220 ss << "[Player: ";
221
222 if (!m_playerLoading && _player)
223 {
224 ss << _player->GetName() << ' ' << _player->GetGUID().ToString() << ", ";
225 }
226
227 ss << "Account: " << GetAccountId() << "]";
228
229 return ss.str();
230}

References _player, GetAccountId(), Object::GetGUID(), WorldObject::GetName(), m_playerLoading, and ObjectGuid::ToString().

Referenced by Guild::_SendBankList(), Handle_Deprecated(), Handle_EarlyProccess(), Handle_NULL(), Handle_ServerSide(), HandleBattleFieldPortOpcode(), HandleChannelAnnouncements(), HandleChannelBan(), HandleChannelInvite(), HandleChannelKick(), HandleChannelList(), HandleChannelModerateOpcode(), HandleChannelModerator(), HandleChannelMute(), HandleChannelOwner(), HandleChannelPassword(), HandleChannelSetOwner(), HandleChannelUnban(), HandleChannelUnmoderator(), HandleChannelUnmute(), HandleCharFactionOrRaceChangeCallback(), HandleGetChannelMemberCount(), HandleGuildAddRankOpcode(), HandleGuildBankBuyTab(), HandleGuildBankDepositMoney(), HandleGuildBankerActivate(), HandleGuildBankLogQuery(), HandleGuildBankMoneyWithdrawn(), HandleGuildBankQueryTab(), HandleGuildBankUpdateTab(), HandleGuildBankWithdrawMoney(), HandleGuildChangeInfoTextOpcode(), HandleGuildCreateOpcode(), HandleGuildDeclineOpcode(), HandleGuildDelRankOpcode(), HandleGuildDemoteOpcode(), HandleGuildDisbandOpcode(), HandleGuildEventLogQueryOpcode(), HandleGuildInfoOpcode(), HandleGuildInviteOpcode(), HandleGuildLeaderOpcode(), HandleGuildLeaveOpcode(), HandleGuildMOTDOpcode(), HandleGuildPromoteOpcode(), HandleGuildQueryOpcode(), HandleGuildRankOpcode(), HandleGuildRemoveOpcode(), HandleGuildRosterOpcode(), HandleGuildSetOfficerNoteOpcode(), HandleGuildSetPublicNoteOpcode(), HandleJoinChannel(), HandleLeaveChannel(), HandleLfgGetStatus(), HandleLfgJoinOpcode(), HandleMessagechatOpcode(), WorldSocket::HandlePing(), Guild::HandleQuery(), HandleQueryGuildBankTabText(), Guild::HandleRoster(), HandleSaveGuildEmblemOpcode(), Guild::HandleSetBankTabInfo(), HandleSetGuildBankTabText(), Channel::List(), WorldSocket::LogOpcodeText(), LogUnexpectedOpcode(), LogUnprocessedTail(), WorldSocket::ReadDataHandler(), Guild::SendBankLog(), Guild::SendCommandResult(), Guild::SendEventLog(), Guild::SendInfo(), SendLfgPlayerReward(), SendLfgUpdateParty(), SendLfgUpdatePlayer(), Guild::SendLoginInfo(), Guild::SendMoneyInfo(), Guild::SendPermissions(), Guild::SendSaveEmblemResult(), Guild::BankTab::SendText(), Pet::Update(), and Update().

◆ GetPlayerName()

◆ GetQueryProcessor()

QueryCallbackProcessor & WorldSession::GetQueryProcessor ( )
inline
1134{ return _queryProcessor; }
QueryCallbackProcessor _queryProcessor
Definition WorldSession.h:1146

References _queryProcessor.

Referenced by Player::ActivateSpec(), and ServerMailReward::OnPlayerLogin().

◆ GetRecruiterId()

◆ GetRemoteAddress()

◆ GetSecurity()

AccountTypes WorldSession::GetSecurity ( ) const
inline

◆ GetSessionDbcLocale()

◆ GetSessionDbLocaleIndex()

◆ GetTotalTime()

uint32 WorldSession::GetTotalTime ( ) const
inline
438{ return m_total_time; }

References m_total_time.

Referenced by ~WorldSession().

◆ GetTutorialInt()

uint32 WorldSession::GetTutorialInt ( uint8  index) const
inline
520{ return m_Tutorials[index]; }

References m_Tutorials.

Referenced by HandleTutorialFlag().

◆ GetWarden()

Warden * WorldSession::GetWarden ( )
1350{
1351 return &(*_warden);
1352}

◆ Handle_Deprecated()

void WorldSession::Handle_Deprecated ( WorldPacket recvPacket)
862{
863 LOG_ERROR("network.opcode", "Received deprecated opcode {} from {}",
864 GetOpcodeNameForLogging(static_cast<OpcodeClient>(recvPacket.GetOpcode())), GetPlayerInfo());
865}
uint16 GetOpcode() const
Definition WorldPacket.h:75
std::string GetPlayerInfo() const
Definition WorldSession.cpp:216
Opcodes
List of Opcodes.
Definition Opcodes.h:30
std::string GetOpcodeNameForLogging(Opcodes opcode)
Lookup opcode name for human understandable logging.
Definition Opcodes.cpp:1468

References WorldPacket::GetOpcode(), GetOpcodeNameForLogging(), GetPlayerInfo(), and LOG_ERROR.

◆ Handle_EarlyProccess()

void WorldSession::Handle_EarlyProccess ( WorldPacket recvPacket)
850{
851 LOG_ERROR("network.opcode", "Received opcode {} that must be processed in WorldSocket::ReadDataHandler from {}",
852 GetOpcodeNameForLogging(static_cast<OpcodeClient>(recvPacket.GetOpcode())), GetPlayerInfo());
853}

References WorldPacket::GetOpcode(), GetOpcodeNameForLogging(), GetPlayerInfo(), and LOG_ERROR.

Referenced by OpcodeTable::Initialize().

◆ Handle_NULL()

void WorldSession::Handle_NULL ( WorldPacket null)
844{
845 LOG_ERROR("network.opcode", "Received unhandled opcode {} from {}",
847}

References WorldPacket::GetOpcode(), GetOpcodeNameForLogging(), GetPlayerInfo(), and LOG_ERROR.

Referenced by OpcodeTable::Initialize().

◆ Handle_ServerSide()

void WorldSession::Handle_ServerSide ( WorldPacket recvPacket)
856{
857 LOG_ERROR("network.opcode", "Received server-side opcode {} from {}",
858 GetOpcodeNameForLogging(static_cast<OpcodeServer>(recvPacket.GetOpcode())), GetPlayerInfo());
859}

References WorldPacket::GetOpcode(), GetOpcodeNameForLogging(), GetPlayerInfo(), and LOG_ERROR.

◆ HandleAcceptGrantLevel()

void WorldSession::HandleAcceptGrantLevel ( WorldPacket recvData)
67{
68 LOG_DEBUG("network", "WORLD: CMSG_ACCEPT_LEVEL_GRANT");
69
70 ObjectGuid guid;
71 recvData >> guid.ReadAsPacked();
72
74 if (!other)
75 return;
76
77 if (GetAccountId() != other->GetSession()->GetRecruiterId())
78 return;
79
80 if (other->GetGrantableLevels())
81 other->SetGrantableLevels(other->GetGrantableLevels() - 1);
82 else
83 return;
84
86}
Definition ObjectGuid.h:118
PackedGuidReader ReadAsPacked()
Definition ObjectGuid.h:135
void GiveLevel(uint8 level)
Definition Player.cpp:2440
void SetGrantableLevels(uint8 val)
Definition Player.h:2121
uint8 GetGrantableLevels()
Definition Player.h:2120
uint32 GetRecruiterId() const
Definition WorldSession.h:588
Player * GetPlayer(Map const *, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:220

References _player, GetAccountId(), Player::GetGrantableLevels(), Unit::GetLevel(), ObjectAccessor::GetPlayer(), GetRecruiterId(), Player::GetSession(), Player::GiveLevel(), LOG_DEBUG, ObjectGuid::ReadAsPacked(), and Player::SetGrantableLevels().

Referenced by OpcodeTable::Initialize().

◆ HandleAcceptTradeOpcode()

void WorldSession::HandleAcceptTradeOpcode ( WorldPacket recvPacket)
245{
246 TradeData* my_trade = _player->m_trade;
247 if (!my_trade)
248 return;
249
250 Player* trader = my_trade->GetTrader();
251
252 TradeData* his_trade = trader->m_trade;
253 if (!his_trade)
254 return;
255
256 Item* myItems[TRADE_SLOT_TRADED_COUNT] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
257 Item* hisItems[TRADE_SLOT_TRADED_COUNT] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
258 bool myCanCompleteTrade = true, hisCanCompleteTrade = true;
259
260 // set before checks for propertly undo at problems (it already set in to client)
261 my_trade->SetAccepted(true);
262
263 // not accept case incorrect money amount
264 if (!_player->HasEnoughMoney(my_trade->GetMoney()))
265 {
267 my_trade->SetAccepted(false, true);
268 return;
269 }
270
271 // not accept case incorrect money amount
272 if (!trader->HasEnoughMoney(his_trade->GetMoney()))
273 {
275 his_trade->SetAccepted(false, true);
276 return;
277 }
278
279 if (_player->GetMoney() >= uint32(MAX_MONEY_AMOUNT) - his_trade->GetMoney())
280 {
282 my_trade->SetAccepted(false, true);
283 return;
284 }
285
286 if (trader->GetMoney() >= uint32(MAX_MONEY_AMOUNT) - my_trade->GetMoney())
287 {
288 trader->SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, nullptr, nullptr);
289 his_trade->SetAccepted(false, true);
290 return;
291 }
292
293 // not accept if some items now can't be trade (cheating)
294 for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i)
295 {
296 if (Item* item = my_trade->GetItem(TradeSlots(i)))
297 {
298 if (!item->CanBeTraded(false, true))
299 {
301 return;
302 }
303
304 if (item->IsBindedNotWith(trader))
305 {
307 SendTradeStatus(TRADE_STATUS_CLOSE_WINDOW/*TRADE_STATUS_TRADE_CANCELED*/);
308 return;
309 }
310 }
311
312 if (Item* item = his_trade->GetItem(TradeSlots(i)))
313 {
314 if (!item->CanBeTraded(false, true))
315 {
317 return;
318 }
319 //if (item->IsBindedNotWith(_player)) // dont mark as invalid when his item isnt good (not exploitable because if item is invalid trade will fail anyway later on the same check)
320 //{
321 // SendTradeStatus(TRADE_STATUS_NOT_ELIGIBLE);
322 // his_trade->SetAccepted(false, true);
323 // return;
324 //}
325 }
326 }
327
328 if (his_trade->IsAccepted())
329 {
330 setAcceptTradeMode(my_trade, his_trade, myItems, hisItems);
331
332 Spell* my_spell = nullptr;
333 SpellCastTargets my_targets;
334
335 Spell* his_spell = nullptr;
336 SpellCastTargets his_targets;
337
338 // not accept if spell can't be casted now (cheating)
339 if (uint32 my_spell_id = my_trade->GetSpell())
340 {
341 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(my_spell_id);
342 Item* castItem = my_trade->GetSpellCastItem();
343
344 if (!spellInfo || !his_trade->GetItem(TRADE_SLOT_NONTRADED) ||
345 (my_trade->HasSpellCastItem() && !castItem))
346 {
347 clearAcceptTradeMode(my_trade, his_trade);
348 clearAcceptTradeMode(myItems, hisItems);
349
350 my_trade->SetSpell(0);
351 return;
352 }
353
354 my_spell = new Spell(_player, spellInfo, TRIGGERED_FULL_MASK);
355 my_spell->m_CastItem = castItem;
356 my_targets.SetTradeItemTarget(_player);
357 my_spell->m_targets = my_targets;
358
359 SpellCastResult res = my_spell->CheckCast(true);
360 if (res != SPELL_CAST_OK)
361 {
362 my_spell->SendCastResult(res);
363
364 clearAcceptTradeMode(my_trade, his_trade);
365 clearAcceptTradeMode(myItems, hisItems);
366
367 delete my_spell;
368 my_trade->SetSpell(0);
369 return;
370 }
371 }
372
373 // not accept if spell can't be casted now (cheating)
374 if (uint32 his_spell_id = his_trade->GetSpell())
375 {
376 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(his_spell_id);
377 Item* castItem = his_trade->GetSpellCastItem();
378
379 if (!spellInfo || !my_trade->GetItem(TRADE_SLOT_NONTRADED) || (his_trade->HasSpellCastItem() && !castItem))
380 {
381 delete my_spell;
382 his_trade->SetSpell(0);
383
384 clearAcceptTradeMode(my_trade, his_trade);
385 clearAcceptTradeMode(myItems, hisItems);
386 return;
387 }
388
389 his_spell = new Spell(trader, spellInfo, TRIGGERED_FULL_MASK);
390 his_spell->m_CastItem = castItem;
391 his_targets.SetTradeItemTarget(trader);
392 his_spell->m_targets = his_targets;
393
394 SpellCastResult res = his_spell->CheckCast(true);
395 if (res != SPELL_CAST_OK)
396 {
397 his_spell->SendCastResult(res);
398
399 clearAcceptTradeMode(my_trade, his_trade);
400 clearAcceptTradeMode(myItems, hisItems);
401
402 delete my_spell;
403 delete his_spell;
404
405 his_trade->SetSpell(0);
406 return;
407 }
408 }
409
410 // inform partner client
412
413 // test if item will fit in each inventory
414 hisCanCompleteTrade = (trader->CanStoreItems(myItems, TRADE_SLOT_TRADED_COUNT) == EQUIP_ERR_OK);
415 myCanCompleteTrade = (_player->CanStoreItems(hisItems, TRADE_SLOT_TRADED_COUNT) == EQUIP_ERR_OK);
416
417 clearAcceptTradeMode(myItems, hisItems);
418
419 // in case of missing space report error
420 if (!myCanCompleteTrade)
421 {
422 clearAcceptTradeMode(my_trade, his_trade);
423
426 my_trade->SetAccepted(false);
427 his_trade->SetAccepted(false);
428 delete my_spell;
429 delete his_spell;
430 return;
431 }
432 else if (!hisCanCompleteTrade)
433 {
434 clearAcceptTradeMode(my_trade, his_trade);
435
438 my_trade->SetAccepted(false);
439 his_trade->SetAccepted(false);
440 delete my_spell;
441 delete his_spell;
442 return;
443 }
444
445 // execute trade: 1. remove
446 for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i)
447 {
448 if (myItems[i])
449 {
451 _player->MoveItemFromInventory(myItems[i]->GetBagSlot(), myItems[i]->GetSlot(), true);
452 }
453 if (hisItems[i])
454 {
455 hisItems[i]->SetGuidValue(ITEM_FIELD_GIFTCREATOR, trader->GetGUID());
456 trader->MoveItemFromInventory(hisItems[i]->GetBagSlot(), hisItems[i]->GetSlot(), true);
457 }
458 }
459
460 // execute trade: 2. store
461 moveItems(myItems, hisItems);
462
463 if (my_trade->GetMoney() >= 10 * GOLD )
464 {
465 CharacterDatabase.Execute("INSERT INTO log_money VALUES({}, {}, \"{}\", \"{}\", {}, \"{}\", {}, \"goods\", NOW(), {})",
466 GetAccountId(), _player->GetGUID().GetCounter(), _player->GetName(), GetRemoteAddress(), trader->GetSession()->GetAccountId(), trader->GetName(), my_trade->GetMoney(), 6);
467 }
468 if (his_trade->GetMoney() >= 10 * GOLD )
469 {
470 CharacterDatabase.Execute("INSERT INTO log_money VALUES({}, {}, \"{}\", \"{}\", {}, \"{}\", {}, \"goods\", NOW(), {})",
471 trader->GetSession()->GetAccountId(), trader->GetGUID().GetCounter(), trader->GetName(), trader->GetSession()->GetRemoteAddress(), GetAccountId(), _player->GetName(), his_trade->GetMoney(), 6);
472 }
473
474 // update money
475 _player->ModifyMoney(-int32(my_trade->GetMoney()));
476 _player->ModifyMoney(his_trade->GetMoney());
477 trader->ModifyMoney(-int32(his_trade->GetMoney()));
478 trader->ModifyMoney(my_trade->GetMoney());
479
480 if (my_spell)
481 my_spell->prepare(&my_targets);
482
483 if (his_spell)
484 his_spell->prepare(&his_targets);
485
486 // cleanup
487 clearAcceptTradeMode(my_trade, his_trade);
488 delete _player->m_trade;
489 _player->m_trade = nullptr;
490 delete trader->m_trade;
491 trader->m_trade = nullptr;
492
493 // desynchronized with the other saves here (SaveInventoryAndGoldToDB() not have own transaction guards)
494 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
496 trader->SaveInventoryAndGoldToDB(trans);
497 CharacterDatabase.CommitTransaction(trans);
498
501 }
502 else
503 {
505 }
506}
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
Definition DatabaseEnvFwd.h:69
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition DatabaseEnv.cpp:21
std::int32_t int32
Definition Define.h:103
@ EQUIP_ERR_TOO_MUCH_GOLD
Definition Item.h:123
@ EQUIP_ERR_OK
Definition Item.h:47
@ LANG_NOT_PARTNER_FREE_TRADE_SLOTS
Definition Language.h:746
@ LANG_NOT_FREE_TRADE_SLOTS
Definition Language.h:745
@ LANG_NOT_ENOUGH_GOLD
Definition Language.h:744
#define MAX_MONEY_AMOUNT
Definition Player.h:925
@ TRADE_STATUS_TRADE_COMPLETE
Definition SharedDefines.h:3824
@ TRADE_STATUS_TRADE_ACCEPT
Definition SharedDefines.h:3820
@ TRADE_STATUS_TRADE_CANCELED
Definition SharedDefines.h:3819
@ TRADE_STATUS_NOT_ELIGIBLE
Definition SharedDefines.h:3839
@ TRADE_STATUS_CLOSE_WINDOW
Definition SharedDefines.h:3828
@ GOLD
Definition SharedDefines.h:264
SpellCastResult
Definition SharedDefines.h:959
@ SPELL_CAST_OK
Definition SharedDefines.h:1149
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
Definition SpellDefines.h:150
#define sSpellMgr
Definition SpellMgr.h:825
TradeSlots
Definition TradeData.h:28
@ TRADE_SLOT_TRADED_COUNT
Definition TradeData.h:30
@ TRADE_SLOT_NONTRADED
Definition TradeData.h:31
static void setAcceptTradeMode(TradeData *myTrade, TradeData *hisTrade, Item **myItems, Item **hisItems)
Definition TradeHandler.cpp:201
static void clearAcceptTradeMode(TradeData *myTrade, TradeData *hisTrade)
Definition TradeHandler.cpp:226
@ ITEM_FIELD_GIFTCREATOR
Definition UpdateFields.h:38
Definition Chat.h:37
void SendNotification(std::string_view str)
Definition Chat.cpp:105
void SetGuidValue(uint16 index, ObjectGuid value)
Definition Object.cpp:712
void SaveInventoryAndGoldToDB(CharacterDatabaseTransaction trans)
Definition PlayerStorage.cpp:7125
bool ModifyMoney(int32 amount, bool sendError=true)
Definition Player.cpp:11529
TradeData * m_trade
Definition Player.h:2876
bool HasEnoughMoney(uint32 amount) const
Definition Player.h:1605
void MoveItemFromInventory(uint8 bag, uint8 slot, bool update)
Definition PlayerStorage.cpp:2979
uint32 GetMoney() const
Definition Player.h:1603
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition PlayerStorage.cpp:4023
InventoryResult CanStoreItems(Item **pItem, int32 count) const
Definition PlayerStorage.cpp:1541
Definition Spell.h:119
void SetTradeItemTarget(Player *caster)
Definition Spell.cpp:338
Definition SpellInfo.h:316
Definition Spell.h:295
SpellCastTargets m_targets
Definition Spell.h:538
SpellCastResult prepare(SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
Definition Spell.cpp:3403
SpellCastResult CheckCast(bool strict)
Definition Spell.cpp:5604
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition Spell.cpp:4619
Item * m_CastItem
Definition Spell.h:532
Definition TradeData.h:36
Item * GetSpellCastItem() const
Definition TradeData.cpp:49
bool HasSpellCastItem() const
Definition TradeData.h:53
void SetSpell(uint32 spell_id, Item *castItem=nullptr)
Definition TradeData.cpp:76
Player * GetTrader() const
Definition TradeData.h:41
uint32 GetMoney() const
Definition TradeData.h:55
Item * GetItem(TradeSlots slot) const
Definition TradeData.cpp:26
bool IsAccepted() const
Definition TradeData.h:58
uint32 GetSpell() const
Definition TradeData.h:49
void SetAccepted(bool state, bool crosssend=false)
Definition TradeData.cpp:120
void moveItems(Item *myItems[], Item *hisItems[])
Definition TradeHandler.cpp:132
std::string const & GetRemoteAddress()
Definition WorldSession.h:433
void SendTradeStatus(TradeStatus status)
Definition TradeHandler.cpp:33

References _player, Player::CanStoreItems(), CharacterDatabase, Spell::CheckCast(), clearAcceptTradeMode(), EQUIP_ERR_OK, EQUIP_ERR_TOO_MUCH_GOLD, GetAccountId(), ObjectGuid::GetCounter(), Object::GetGUID(), TradeData::GetItem(), Player::GetMoney(), TradeData::GetMoney(), WorldObject::GetName(), GetRemoteAddress(), Player::GetSession(), TradeData::GetSpell(), TradeData::GetSpellCastItem(), TradeData::GetTrader(), GOLD, Player::HasEnoughMoney(), TradeData::HasSpellCastItem(), TradeData::IsAccepted(), ITEM_FIELD_GIFTCREATOR, LANG_NOT_ENOUGH_GOLD, LANG_NOT_FREE_TRADE_SLOTS, LANG_NOT_PARTNER_FREE_TRADE_SLOTS, Spell::m_CastItem, Spell::m_targets, Player::m_trade, MAX_MONEY_AMOUNT, Player::ModifyMoney(), Player::MoveItemFromInventory(), moveItems(), Spell::prepare(), Player::SaveInventoryAndGoldToDB(), Spell::SendCastResult(), Player::SendEquipError(), ChatHandler::SendNotification(), SendTradeStatus(), TradeData::SetAccepted(), setAcceptTradeMode(), Object::SetGuidValue(), TradeData::SetSpell(), SpellCastTargets::SetTradeItemTarget(), SPELL_CAST_OK, sSpellMgr, TRADE_SLOT_NONTRADED, TRADE_SLOT_TRADED_COUNT, TRADE_STATUS_CLOSE_WINDOW, TRADE_STATUS_NOT_ELIGIBLE, TRADE_STATUS_TRADE_ACCEPT, TRADE_STATUS_TRADE_CANCELED, TRADE_STATUS_TRADE_COMPLETE, and TRIGGERED_FULL_MASK.

Referenced by OpcodeTable::Initialize().

◆ HandleActivateTaxiExpressOpcode()

void WorldSession::HandleActivateTaxiExpressOpcode ( WorldPacket recvPacket)
161{
162 ObjectGuid guid;
163 uint32 node_count;
164
165 recvData >> guid >> node_count;
166
168 if (!npc)
169 {
170 LOG_DEBUG("network", "WORLD: HandleActivateTaxiExpressOpcode - Unit ({}) not found or you can't interact with it.", guid.ToString());
172 return;
173 }
174 std::vector<uint32> nodes;
175
176 for (uint32 i = 0; i < node_count; ++i)
177 {
178 uint32 node;
179 recvData >> node;
180
181 if (!GetPlayer()->m_taxi.IsTaximaskNodeKnown(node) && !GetPlayer()->isTaxiCheater())
182 {
184 recvData.rfinish();
185 return;
186 }
187
188 nodes.push_back(node);
189 }
190
191 if (nodes.empty())
192 return;
193
194 LOG_DEBUG("network", "WORLD: Received CMSG_ACTIVATETAXIEXPRESS from {} to {}", nodes.front(), nodes.back());
195
196 GetPlayer()->ActivateTaxiPathTo(nodes, npc, 0);
197}
npc
Definition BattlegroundSA.h:47
@ ERR_TAXINOTVISITED
Definition SharedDefines.h:3867
@ ERR_TAXITOOFARAWAY
Definition SharedDefines.h:3865
@ UNIT_NPC_FLAG_FLIGHTMASTER
Definition UnitDefines.h:332
bool ActivateTaxiPathTo(std::vector< uint32 > const &nodes, Creature *npc=nullptr, uint32 spellid=1)
Definition Player.cpp:10267
void SendActivateTaxiReply(ActivateTaxiReply reply)
Definition TaxiHandler.cpp:295

References Player::ActivateTaxiPathTo(), ERR_TAXINOTVISITED, ERR_TAXITOOFARAWAY, Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, ByteBuffer::rfinish(), SendActivateTaxiReply(), ObjectGuid::ToString(), and UNIT_NPC_FLAG_FLIGHTMASTER.

Referenced by OpcodeTable::Initialize().

◆ HandleActivateTaxiOpcode()

void WorldSession::HandleActivateTaxiOpcode ( WorldPacket recvPacket)
268{
269 ObjectGuid guid;
270 std::vector<uint32> nodes;
271 nodes.resize(2);
272 GetPlayer()->SetCanTeleport(true);
273 recvData >> guid >> nodes[0] >> nodes[1];
274 LOG_DEBUG("network", "WORLD: Received CMSG_ACTIVATETAXI from {} to {}", nodes[0], nodes[1]);
276 if (!npc)
277 {
278 LOG_DEBUG("network", "WORLD: HandleActivateTaxiOpcode - Unit ({}) not found or you can't interact with it.", guid.ToString());
280 return;
281 }
282
283 if (!GetPlayer()->isTaxiCheater())
284 {
285 if (!GetPlayer()->m_taxi.IsTaximaskNodeKnown(nodes[0]) || !GetPlayer()->m_taxi.IsTaximaskNodeKnown(nodes[1]))
286 {
288 return;
289 }
290 }
291
292 GetPlayer()->ActivateTaxiPathTo(nodes, npc, 0);
293}
void SetCanTeleport(bool value)
Definition Player.h:2512

References Player::ActivateTaxiPathTo(), ERR_TAXINOTVISITED, ERR_TAXITOOFARAWAY, Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, SendActivateTaxiReply(), Player::SetCanTeleport(), ObjectGuid::ToString(), and UNIT_NPC_FLAG_FLIGHTMASTER.

Referenced by OpcodeTable::Initialize().

◆ HandleAddFriendOpcode()

void WorldSession::HandleAddFriendOpcode ( WorldPacket recvPacket)
38{
39 std::string friendName = GetAcoreString(LANG_FRIEND_IGNORE_UNKNOWN);
40 std::string friendNote;
41
42 recv_data >> friendName;
43 recv_data >> friendNote;
44
45 if (!normalizePlayerName(friendName))
46 return;
47
48 ObjectGuid friendGuid = sCharacterCache->GetCharacterGuidByName(friendName);
49 if (!friendGuid)
50 return;
51
52 CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(friendGuid);
53 if (!playerData)
54 return;
55
56 uint32 friendAccountId = playerData->AccountId;
57 TeamId teamId = Player::TeamIdForRace(playerData->Race);
58 FriendsResult friendResult = FRIEND_NOT_FOUND;
59
61 {
62 if (friendGuid)
63 {
64 if (friendGuid == GetPlayer()->GetGUID())
65 friendResult = FRIEND_SELF;
67 friendResult = FRIEND_ENEMY;
68 else if (GetPlayer()->GetSocial()->HasFriend(friendGuid))
69 friendResult = FRIEND_ALREADY;
70 else
71 {
72 Player* pFriend = ObjectAccessor::FindConnectedPlayer(friendGuid);
73 if (pFriend && pFriend->IsVisibleGloballyFor(GetPlayer()) && !pFriend->GetSession()->IsGMAccount())
74 friendResult = FRIEND_ADDED_ONLINE;
75 else
76 friendResult = FRIEND_ADDED_OFFLINE;
77 if (GetPlayer()->GetSocial()->AddToSocialList(friendGuid, SOCIAL_FLAG_FRIEND))
78 GetPlayer()->GetSocial()->SetFriendNote(friendGuid, friendNote);
79 else
80 friendResult = FRIEND_LIST_FULL;
81 }
82 GetPlayer()->GetSocial()->SetFriendNote(friendGuid, friendNote);
83 }
84 }
85
86 sSocialMgr->SendFriendStatus(GetPlayer(), friendResult, friendGuid, false);
87
88 LOG_DEBUG("network", "WORLD: Sent (SMSG_FRIEND_STATUS)");
89}
#define sCharacterCache
Definition CharacterCache.h:83
@ LANG_FRIEND_IGNORE_UNKNOWN
Definition Language.h:80
bool normalizePlayerName(std::string &name)
Definition ObjectMgr.cpp:208
TeamId GetTeamId(PvPTeamId teamId)
Definition SharedDefines.h:3728
TeamId
Definition SharedDefines.h:770
FriendsResult
Results of friend related commands.
Definition SocialMgr.h:65
@ FRIEND_ENEMY
Definition SocialMgr.h:76
@ FRIEND_ALREADY
Definition SocialMgr.h:74
@ FRIEND_ADDED_OFFLINE
Definition SocialMgr.h:73
@ FRIEND_NOT_FOUND
Definition SocialMgr.h:70
@ FRIEND_ADDED_ONLINE
Definition SocialMgr.h:72
@ FRIEND_SELF
Definition SocialMgr.h:75
@ FRIEND_LIST_FULL
Definition SocialMgr.h:67
#define sSocialMgr
Definition SocialMgr.h:147
@ SOCIAL_FLAG_FRIEND
Definition SocialMgr.h:39
@ CONFIG_ALLOW_GM_FRIEND
Definition WorldConfig.h:48
@ CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND
Definition WorldConfig.h:40
void SetFriendNote(ObjectGuid const &friendGuid, std::string note)
Definition SocialMgr.cpp:105
static TeamId TeamIdForRace(uint8 race)
Definition Player.cpp:5900
bool IsVisibleGloballyFor(Player const *player) const
Definition Player.cpp:11500
PlayerSocial * GetSocial()
Definition Player.h:1143
bool IsGMAccount() const
Definition WorldSession.cpp:206
std::string GetAcoreString(uint32 entry) const
Definition WorldSession.cpp:833
Realm realm
Definition World.cpp:111
bool IsPlayerAccount(uint32 gmlevel)
Definition AccountMgr.cpp:312
uint32 GetSecurity(uint32 accountId)
Definition AccountMgr.cpp:245
Player * FindConnectedPlayer(ObjectGuid const guid)
Definition ObjectAccessor.cpp:257
Definition CharacterCache.h:28
uint8 Race
Definition CharacterCache.h:33
uint32 AccountId
Definition CharacterCache.h:31
uint32 Realm
Definition Realm.h:43
RealmHandle Id
Definition Realm.h:69

References CharacterCacheEntry::AccountId, CONFIG_ALLOW_GM_FRIEND, CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND, ObjectAccessor::FindConnectedPlayer(), FRIEND_ADDED_OFFLINE, FRIEND_ADDED_ONLINE, FRIEND_ALREADY, FRIEND_ENEMY, FRIEND_LIST_FULL, FRIEND_NOT_FOUND, FRIEND_SELF, GetAcoreString(), GetPlayer(), GetSecurity(), AccountMgr::GetSecurity(), Player::GetSession(), Player::GetSocial(), GetTeamId(), Realm::Id, IsGMAccount(), AccountMgr::IsPlayerAccount(), Player::IsVisibleGloballyFor(), LANG_FRIEND_IGNORE_UNKNOWN, LOG_DEBUG, normalizePlayerName(), CharacterCacheEntry::Race, realm, RealmHandle::Realm, sCharacterCache, PlayerSocial::SetFriendNote(), SOCIAL_FLAG_FRIEND, sSocialMgr, sWorld, and Player::TeamIdForRace().

Referenced by OpcodeTable::Initialize().

◆ HandleAddIgnoreOpcode()

void WorldSession::HandleAddIgnoreOpcode ( WorldPacket recvPacket)
104{
105 std::string ignoreName = GetAcoreString(LANG_FRIEND_IGNORE_UNKNOWN);
106
107 recv_data >> ignoreName;
108
109 if (!normalizePlayerName(ignoreName))
110 return;
111
112 LOG_DEBUG("network", "WORLD: {} asked to Ignore: '{}'", GetPlayer()->GetName(), ignoreName);
113
114 ObjectGuid ignoreGuid = sCharacterCache->GetCharacterGuidByName(ignoreName);
115 if (!ignoreGuid)
116 return;
117
118 FriendsResult ignoreResult;
119
120 if (ignoreGuid == GetPlayer()->GetGUID()) //not add yourself
121 ignoreResult = FRIEND_IGNORE_SELF;
122 else if (GetPlayer()->GetSocial()->HasIgnore(ignoreGuid))
123 ignoreResult = FRIEND_IGNORE_ALREADY;
124 else
125 {
126 ignoreResult = FRIEND_IGNORE_ADDED;
127
128 // ignore list full
129 if (!GetPlayer()->GetSocial()->AddToSocialList(ignoreGuid, SOCIAL_FLAG_IGNORED))
130 ignoreResult = FRIEND_IGNORE_FULL;
131 }
132
133 sSocialMgr->SendFriendStatus(GetPlayer(), ignoreResult, ignoreGuid, false);
134
135 LOG_DEBUG("network", "WORLD: Sent (SMSG_FRIEND_STATUS)");
136}
@ FRIEND_IGNORE_FULL
Definition SocialMgr.h:77
@ FRIEND_IGNORE_ADDED
Definition SocialMgr.h:81
@ FRIEND_IGNORE_SELF
Definition SocialMgr.h:78
@ FRIEND_IGNORE_ALREADY
Definition SocialMgr.h:80
@ SOCIAL_FLAG_IGNORED
Definition SocialMgr.h:40

References FRIEND_IGNORE_ADDED, FRIEND_IGNORE_ALREADY, FRIEND_IGNORE_FULL, FRIEND_IGNORE_SELF, GetAcoreString(), GetPlayer(), LANG_FRIEND_IGNORE_UNKNOWN, LOG_DEBUG, normalizePlayerName(), sCharacterCache, SOCIAL_FLAG_IGNORED, and sSocialMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleAlterAppearance()

void WorldSession::HandleAlterAppearance ( WorldPacket recvData)
1508{
1509 LOG_DEBUG("network", "CMSG_ALTER_APPEARANCE");
1510
1511 uint32 Hair, Color, FacialHair, SkinColor;
1512 recvData >> Hair >> Color >> FacialHair >> SkinColor;
1513
1514 BarberShopStyleEntry const* bs_hair = sBarberShopStyleStore.LookupEntry(Hair);
1515
1516 if (!bs_hair || bs_hair->type != 0 || bs_hair->race != _player->getRace() || bs_hair->gender != _player->getGender())
1517 return;
1518
1519 BarberShopStyleEntry const* bs_facialHair = sBarberShopStyleStore.LookupEntry(FacialHair);
1520
1521 if (!bs_facialHair || bs_facialHair->type != 2 || bs_facialHair->race != _player->getRace() || bs_facialHair->gender != _player->getGender())
1522 return;
1523
1524 BarberShopStyleEntry const* bs_skinColor = sBarberShopStyleStore.LookupEntry(SkinColor);
1525
1526 if (bs_skinColor && (bs_skinColor->type != 3 || bs_skinColor->race != _player->getRace() || bs_skinColor->gender != _player->getGender()))
1527 return;
1528
1530 if (!go)
1531 {
1533 data << uint32(2);
1534 SendPacket(&data);
1535 return;
1536 }
1537
1539 {
1541 data << uint32(2);
1542 SendPacket(&data);
1543 return;
1544 }
1545
1546 uint32 cost = _player->GetBarberShopCost(bs_hair->hair_id, Color, bs_facialHair->hair_id, bs_skinColor);
1547
1548 // 0 - ok
1549 // 1, 3 - not enough money
1550 // 2 - you have to seat on barber chair
1551 if (!_player->HasEnoughMoney(cost))
1552 {
1554 data << uint32(1); // no money
1555 SendPacket(&data);
1556 return;
1557 }
1558 else
1559 {
1561 data << uint32(0); // ok
1562 SendPacket(&data);
1563 }
1564
1565 _player->ModifyMoney(-int32(cost)); // it isn't free
1567
1570 _player->SetByteValue(PLAYER_BYTES_2, 0, uint8(bs_facialHair->hair_id));
1571 if (bs_skinColor)
1572 _player->SetByteValue(PLAYER_BYTES, 0, uint8(bs_skinColor->hair_id));
1573
1575
1576 _player->SetStandState(0); // stand up
1577}
@ ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP
Definition DBCEnums.h:162
@ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER
Definition DBCEnums.h:177
DBCStorage< BarberShopStyleEntry > sBarberShopStyleStore(BarberShopStyleEntryfmt)
@ GAMEOBJECT_TYPE_BARBER_CHAIR
Definition SharedDefines.h:1603
@ UNIT_STAND_STATE_SIT_LOW_CHAIR
Definition UnitDefines.h:36
@ PLAYER_BYTES_2
Definition UpdateFields.h:182
@ PLAYER_BYTES
Definition UpdateFields.h:181
void SetByteValue(uint16 index, uint8 offset, uint8 value)
Definition Object.cpp:739
uint32 GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair, BarberShopStyleEntry const *newSkin=nullptr)
Definition Player.cpp:13288
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition PlayerUpdates.cpp:2163
uint8 getGender() const
Definition Unit.h:838
uint8 getRace(bool original=false) const
Definition Unit.cpp:21098
uint8 getStandState() const
Definition Unit.h:1760
void SetStandState(uint8 state)
Definition Unit.cpp:16958
GameObject * FindNearestGameObjectOfType(GameobjectTypes type, float range) const
Definition Object.cpp:2461
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
Definition WorldSession.cpp:252
@ SMSG_BARBER_SHOP_RESULT
Definition Opcodes.h:1094
Definition DBCStructure.h:590
uint32 type
Definition DBCStructure.h:592
uint32 race
Definition DBCStructure.h:598
uint32 gender
Definition DBCStructure.h:599
uint32 hair_id
Definition DBCStructure.h:600
uint32 chairheight
Definition GameObjectData.h:345
struct GameObjectTemplate::@233::@260 barberChair

References _player, ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER, ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP, GameObjectTemplate::barberChair, GameObjectTemplate::chairheight, WorldObject::FindNearestGameObjectOfType(), GAMEOBJECT_TYPE_BARBER_CHAIR, BarberShopStyleEntry::gender, Player::GetBarberShopCost(), Unit::getGender(), GameObject::GetGOInfo(), Unit::getRace(), Unit::getStandState(), BarberShopStyleEntry::hair_id, Player::HasEnoughMoney(), LOG_DEBUG, Player::ModifyMoney(), PLAYER_BYTES, PLAYER_BYTES_2, BarberShopStyleEntry::race, sBarberShopStyleStore, SendPacket(), Object::SetByteValue(), Unit::SetStandState(), SMSG_BARBER_SHOP_RESULT, BarberShopStyleEntry::type, UNIT_STAND_STATE_SIT_LOW_CHAIR, and Player::UpdateAchievementCriteria().

Referenced by OpcodeTable::Initialize().

◆ HandleAreaSpiritHealerQueryOpcode()

void WorldSession::HandleAreaSpiritHealerQueryOpcode ( WorldPacket recvData)
1628{
1629 LOG_DEBUG("network", "WORLD: CMSG_AREA_SPIRIT_HEALER_QUERY");
1630
1632
1633 ObjectGuid guid;
1634 recv_data >> guid;
1635
1636 Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
1637 if (!unit)
1638 return;
1639
1640 if (!unit->IsSpiritService()) // it's not spirit service
1641 return;
1642
1643 if (bg)
1644 sBattlegroundMgr->SendAreaSpiritHealerQueryOpcode(_player, bg, guid);
1645
1646 if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
1647 bf->SendAreaSpiritHealerQueryOpcode(_player, guid);
1648}
#define sBattlefieldMgr
Definition BattlefieldMgr.h:77
#define sBattlegroundMgr
Definition BattlegroundMgr.h:187
Definition Battlefield.h:205
Definition Battleground.h:294
Battleground * GetBattleground(bool create=false) const
Definition Player.cpp:12238
bool IsSpiritService() const
Definition Unit.h:814

References _player, Player::GetBattleground(), Map::GetCreature(), WorldObject::GetMap(), GetPlayer(), WorldObject::GetZoneId(), Unit::IsSpiritService(), LOG_DEBUG, sBattlefieldMgr, and sBattlegroundMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleAreaSpiritHealerQueueOpcode()

void WorldSession::HandleAreaSpiritHealerQueueOpcode ( WorldPacket recvData)
1651{
1652 LOG_DEBUG("network", "WORLD: CMSG_AREA_SPIRIT_HEALER_QUEUE");
1653
1655
1656 ObjectGuid guid;
1657 recv_data >> guid;
1658
1659 Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
1660 if (!unit)
1661 return;
1662
1663 if (!unit->IsSpiritService()) // it's not spirit service
1664 return;
1665
1666 if (bg)
1668
1669 if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
1670 bf->AddPlayerToResurrectQueue(guid, _player->GetGUID());
1671}
void AddPlayerToResurrectQueue(ObjectGuid npc_guid, ObjectGuid player_guid)
Definition Battleground.cpp:1434

References _player, Battleground::AddPlayerToResurrectQueue(), Player::GetBattleground(), Map::GetCreature(), Object::GetGUID(), WorldObject::GetMap(), GetPlayer(), WorldObject::GetZoneId(), Unit::IsSpiritService(), LOG_DEBUG, and sBattlefieldMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleAreaTriggerOpcode()

void WorldSession::HandleAreaTriggerOpcode ( WorldPacket recvPacket)
694{
695 uint32 triggerId;
696 recv_data >> triggerId;
697
698 LOG_DEBUG("network", "CMSG_AREATRIGGER. Trigger ID: {}", triggerId);
699
700 Player* player = GetPlayer();
701 if (player->IsInFlight())
702 {
703 LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player '{}' ({}) in flight, ignore Area Trigger ID:{}",
704 player->GetName(), player->GetGUID().ToString(), triggerId);
705 return;
706 }
707
708 AreaTrigger const* atEntry = sObjectMgr->GetAreaTrigger(triggerId);
709 if (!atEntry)
710 {
711 LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player '{}' ({}) send unknown (by DBC) Area Trigger ID:{}",
712 player->GetName(), player->GetGUID().ToString(), triggerId);
713 return;
714 }
715
716 uint32 teamFaction = player->GetTeamId(true) == TEAM_ALLIANCE ? FACTION_MASK_ALLIANCE : FACTION_MASK_HORDE;
717 bool isTavernAreatrigger = sObjectMgr->IsTavernAreaTrigger(triggerId, teamFaction);
718 if (!player->IsInAreaTriggerRadius(atEntry, isTavernAreatrigger ? 5.f : 0.f))
719 {
720 LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player {} ({}) too far (trigger map: {} player map: {}), ignore Area Trigger ID: {}",
721 player->GetName(), player->GetGUID().ToString(), atEntry->map, player->GetMapId(), triggerId);
722 return;
723 }
724
725 if (player->isDebugAreaTriggers)
727
728 if (sScriptMgr->OnAreaTrigger(player, atEntry))
729 return;
730
731 if (player->IsAlive())
732 if (uint32 questId = sObjectMgr->GetQuestForAreaTrigger(triggerId))
733 if (player->GetQuestStatus(questId) == QUEST_STATUS_INCOMPLETE)
734 player->AreaExploredOrEventHappens(questId);
735
736 if (isTavernAreatrigger)
737 {
738 // set resting flag we are in the inn
739 player->SetRestFlag(REST_FLAG_IN_TAVERN, atEntry->entry);
740
741 if (sWorld->IsFFAPvPRealm())
742 {
744 {
746 sScriptMgr->OnPlayerFfaPvpStateUpdate(player, false);
747
748 }
749 }
750 return;
751 }
752
753 if (Battleground* bg = player->GetBattleground())
754 if (bg->GetStatus() == STATUS_IN_PROGRESS)
755 {
756 bg->HandleAreaTrigger(player, triggerId);
757 return;
758 }
759
760 if (OutdoorPvP* pvp = player->GetOutdoorPvP())
761 if (pvp->HandleAreaTrigger(_player, triggerId))
762 return;
763
764 AreaTriggerTeleport const* at = sObjectMgr->GetAreaTriggerTeleport(triggerId);
765 if (!at)
766 return;
767
768 bool teleported = false;
769 if (player->GetMapId() != at->target_mapId)
770 {
771 if (Map::EnterState denyReason = sMapMgr->PlayerCannotEnter(at->target_mapId, player, false))
772 {
773 bool reviveAtTrigger = false; // should we revive the player if he is trying to enter the correct instance?
774 switch (denyReason)
775 {
781 reviveAtTrigger = true;
782 break;
783 default:
784 break;
785 }
786
787 if (reviveAtTrigger) // check if the player is touching the areatrigger leading to the map his corpse is on
788 {
789 if (!player->IsAlive() && player->HasCorpse())
790 {
791 if (player->GetCorpseLocation().GetMapId() == at->target_mapId)
792 {
793 player->ResurrectPlayer(0.5f);
794 player->SpawnCorpseBones();
795 }
796 }
797 }
798
799 return;
800 }
801
802 if (Group* group = player->GetGroup())
803 if (group->isLFGGroup() && player->GetMap()->IsDungeon())
804 teleported = player->TeleportToEntryPoint();
805 }
806
807 if (!teleported)
809}
@ STATUS_IN_PROGRESS
Definition Battleground.h:193
@ FACTION_MASK_ALLIANCE
Definition DBCEnums.h:338
@ FACTION_MASK_HORDE
Definition DBCEnums.h:339
@ LANG_DEBUG_AREATRIGGER_REACHED
Definition Language.h:990
#define sMapMgr
Definition MapMgr.h:220
@ TELE_TO_NOT_LEAVE_TRANSPORT
Definition Player.h:817
@ REST_FLAG_IN_TAVERN
Definition Player.h:809
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:103
#define sScriptMgr
Definition ScriptMgr.h:719
@ TEAM_ALLIANCE
Definition SharedDefines.h:771
@ UNIT_BYTE2_FLAG_FFA_PVP
Definition UnitDefines.h:138
@ UNIT_FIELD_BYTES_2
Definition UpdateFields.h:161
void PSendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition Chat.cpp:211
bool IsDungeon() const
Definition Map.h:295
EnterState
Definition Map.h:270
@ CANNOT_ENTER_TOO_MANY_INSTANCES
Definition Map.h:279
@ CANNOT_ENTER_MAX_PLAYERS
Definition Map.h:280
@ CANNOT_ENTER_ZONE_IN_COMBAT
Definition Map.h:281
@ CANNOT_ENTER_INSTANCE_BIND_MISMATCH
Definition Map.h:278
@ CANNOT_ENTER_NOT_IN_RAID
Definition Map.h:276
void RemoveByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition Object.cpp:912
bool HasByteFlag(uint16 index, uint8 offset, uint8 flag) const
Definition Object.cpp:931
Definition OutdoorPvP.h:186
void SetRestFlag(RestFlag restFlag, uint32 triggerId=0)
Definition Player.cpp:16157
TeamId GetTeamId(bool original=false) const
Definition Player.h:2106
void SpawnCorpseBones(bool triggerSave=true)
Definition Player.cpp:4677
bool HasCorpse() const
Definition Player.h:2037
bool TeleportToEntryPoint()
Definition Player.cpp:1599
OutdoorPvP * GetOutdoorPvP() const
Definition Player.cpp:12555
WorldLocation GetCorpseLocation() const
Definition Player.h:2038
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0, Unit *target=nullptr, bool newInstance=false)
Definition Player.cpp:1352
void AreaExploredOrEventHappens(uint32 questId)
Definition PlayerQuest.cpp:1789
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition PlayerQuest.cpp:1428
bool isDebugAreaTriggers
Definition Player.h:2572
bool IsInAreaTriggerRadius(AreaTrigger const *trigger, float delta=0.f) const
Definition Player.cpp:2177
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition Player.cpp:4459
bool IsInFlight() const
Definition Unit.h:1685
uint32 GetMapId() const
Definition Position.h:281
Definition ObjectMgr.h:411
float target_Z
Definition ObjectMgr.h:415
float target_X
Definition ObjectMgr.h:413
float target_Orientation
Definition ObjectMgr.h:416
float target_Y
Definition ObjectMgr.h:414
uint32 target_mapId
Definition ObjectMgr.h:412
Definition ObjectMgr.h:420
uint32 entry
Definition ObjectMgr.h:421
uint32 map
Definition ObjectMgr.h:422

References _player, Player::AreaExploredOrEventHappens(), Map::CANNOT_ENTER_INSTANCE_BIND_MISMATCH, Map::CANNOT_ENTER_MAX_PLAYERS, Map::CANNOT_ENTER_NOT_IN_RAID, Map::CANNOT_ENTER_TOO_MANY_INSTANCES, Map::CANNOT_ENTER_ZONE_IN_COMBAT, AreaTrigger::entry, FACTION_MASK_ALLIANCE, FACTION_MASK_HORDE, Player::GetBattleground(), Player::GetCorpseLocation(), Player::GetGroup(), Object::GetGUID(), WorldObject::GetMap(), WorldLocation::GetMapId(), WorldObject::GetName(), Player::GetOutdoorPvP(), GetPlayer(), Player::GetQuestStatus(), Player::GetTeamId(), Object::HasByteFlag(), Player::HasCorpse(), Unit::IsAlive(), Player::isDebugAreaTriggers, Map::IsDungeon(), Player::IsInAreaTriggerRadius(), Unit::IsInFlight(), LANG_DEBUG_AREATRIGGER_REACHED, LOG_DEBUG, AreaTrigger::map, ChatHandler::PSendSysMessage(), QUEST_STATUS_INCOMPLETE, Object::RemoveByteFlag(), REST_FLAG_IN_TAVERN, Player::ResurrectPlayer(), Player::SetRestFlag(), sMapMgr, sObjectMgr, Player::SpawnCorpseBones(), sScriptMgr, STATUS_IN_PROGRESS, sWorld, AreaTriggerTeleport::target_mapId, AreaTriggerTeleport::target_Orientation, AreaTriggerTeleport::target_X, AreaTriggerTeleport::target_Y, AreaTriggerTeleport::target_Z, TEAM_ALLIANCE, TELE_TO_NOT_LEAVE_TRANSPORT, Player::TeleportTo(), Player::TeleportToEntryPoint(), ObjectGuid::ToString(), UNIT_BYTE2_FLAG_FFA_PVP, and UNIT_FIELD_BYTES_2.

Referenced by OpcodeTable::Initialize().

◆ HandleArenaTeamAcceptOpcode()

void WorldSession::HandleArenaTeamAcceptOpcode ( WorldPacket recvData)
169{
170 LOG_DEBUG("network", "CMSG_ARENA_TEAM_ACCEPT"); // empty opcode
171
172 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(_player->GetArenaTeamIdInvited());
173 if (!arenaTeam)
174 return;
175
176 // Check if player is already in another team of the same size
177 if (_player->GetArenaTeamId(arenaTeam->GetSlot()))
178 {
180 return;
181 }
182
183 // Only allow members of the other faction to join the team if cross faction interaction is enabled
184 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA) && _player->GetTeamId() != sCharacterCache->GetCharacterTeamByGuid(arenaTeam->GetCaptain()))
185 {
187 return;
188 }
189
190 // Add player to team
191 if (!arenaTeam->AddMember(_player->GetGUID()))
192 {
194 return;
195 }
196
197 // Broadcast event
198 arenaTeam->BroadcastEvent(ERR_ARENA_TEAM_JOIN_SS, _player->GetGUID(), 2, _player->GetName().c_str(), arenaTeam->GetName(), "");
199}
#define sArenaTeamMgr
Definition ArenaTeamMgr.h:69
@ ERR_ARENA_TEAM_CREATE_S
Definition ArenaTeam.h:32
@ ERR_ARENA_TEAM_INTERNAL
Definition ArenaTeam.h:40
@ ERR_ALREADY_IN_ARENA_TEAM
Definition ArenaTeam.h:41
@ ERR_ARENA_TEAM_NOT_ALLIED
Definition ArenaTeam.h:52
@ ERR_ARENA_TEAM_JOIN_SS
Definition ArenaTeam.h:63
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA
Definition WorldConfig.h:36
Definition ArenaTeam.h:137
ObjectGuid GetCaptain() const
Definition ArenaTeam.h:153
uint8 GetSlot() const
Definition ArenaTeam.h:150
void BroadcastEvent(ArenaTeamEvents event, ObjectGuid guid, uint8 strCount, std::string const &str1, std::string const &str2, std::string const &str3)
Definition ArenaTeam.cpp:573
bool AddMember(ObjectGuid playerGuid)
Definition ArenaTeam.cpp:92
std::string const & GetName() const
Definition ArenaTeam.h:154
uint32 GetArenaTeamId(uint8 slot) const
Definition Player.cpp:16218
uint32 GetArenaTeamIdInvited()
Definition Player.h:1913
void SendArenaTeamCommandResult(uint32 team_action, std::string const &team, std::string const &player, uint32 error_id=0)
Definition ArenaTeamHandler.cpp:406

References _player, ArenaTeam::AddMember(), ArenaTeam::BroadcastEvent(), CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA, ERR_ALREADY_IN_ARENA_TEAM, ERR_ARENA_TEAM_CREATE_S, ERR_ARENA_TEAM_INTERNAL, ERR_ARENA_TEAM_JOIN_SS, ERR_ARENA_TEAM_NOT_ALLIED, Player::GetArenaTeamId(), Player::GetArenaTeamIdInvited(), ArenaTeam::GetCaptain(), Object::GetGUID(), ArenaTeam::GetName(), WorldObject::GetName(), ArenaTeam::GetSlot(), Player::GetTeamId(), LOG_DEBUG, sArenaTeamMgr, sCharacterCache, SendArenaTeamCommandResult(), and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleArenaTeamDeclineOpcode()

void WorldSession::HandleArenaTeamDeclineOpcode ( WorldPacket recvData)
202{
203 LOG_DEBUG("network", "CMSG_ARENA_TEAM_DECLINE"); // empty opcode
204
205 // Remove invite from player
207}
void SetArenaTeamIdInvited(uint32 ArenaTeamId)
Definition Player.h:1912

References _player, LOG_DEBUG, and Player::SetArenaTeamIdInvited().

Referenced by OpcodeTable::Initialize().

◆ HandleArenaTeamDisbandOpcode()

void WorldSession::HandleArenaTeamDisbandOpcode ( WorldPacket recvData)
267{
268 LOG_DEBUG("network", "CMSG_ARENA_TEAM_DISBAND");
269
270 uint32 arenaTeamId;
271 recvData >> arenaTeamId;
272
273 if (ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId))
274 {
275 // Only captain can disband the team
276 if (arenaTeam->GetCaptain() != _player->GetGUID())
277 return;
278
279 // Teams cannot be disbanded during queues
281 {
282 GroupQueueInfo ginfo;
283 BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueue);
284 if (queue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
286 return;
287 }
288
289 // Teams cannot be disbanded during fights
290 if (arenaTeam->IsFighting())
291 return;
292
293 arenaTeam->Disband(this);
294 delete arenaTeam;
295 }
296}
@ BATTLEGROUND_AA
Definition SharedDefines.h:3752
BattlegroundQueueTypeId
Definition SharedDefines.h:3885
static BattlegroundQueueTypeId BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 arenaType)
Definition BattlegroundMgr.cpp:686
Definition BattlegroundQueue.h:64
bool GetPlayerGroupInfoData(ObjectGuid guid, GroupQueueInfo *ginfo)
Definition BattlegroundQueue.cpp:385
Definition BattlegroundQueue.h:31
uint32 IsInvitedToBGInstanceGUID
Definition BattlegroundQueue.h:41

References _player, BATTLEGROUND_AA, BattlegroundMgr::BGQueueTypeId(), Object::GetGUID(), BattlegroundQueue::GetPlayerGroupInfoData(), GroupQueueInfo::IsInvitedToBGInstanceGUID, LOG_DEBUG, sArenaTeamMgr, and sBattlegroundMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleArenaTeamInviteOpcode()

void WorldSession::HandleArenaTeamInviteOpcode ( WorldPacket recvData)
85{
86 LOG_DEBUG("network", "CMSG_ARENA_TEAM_INVITE");
87
88 uint32 arenaTeamId; // arena team id
89 std::string invitedName;
90
91 Player* player = nullptr;
92
93 recvData >> arenaTeamId >> invitedName;
94
95 if (!invitedName.empty())
96 {
97 if (!normalizePlayerName(invitedName))
98 return;
99
100 player = ObjectAccessor::FindPlayerByName(invitedName, false);
101 }
102
103 if (!player)
104 {
106 return;
107 }
108
109 if (player->GetLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
110 {
112 return;
113 }
114
115 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
116 if (!arenaTeam)
117 {
119 return;
120 }
121
122 if (GetPlayer()->GetArenaTeamId(arenaTeam->GetSlot()) != arenaTeamId)
123 {
125 return;
126 }
127
128 // OK result but don't send invite
129 if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUID()))
130 return;
131
132 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA) && player->GetTeamId() != GetPlayer()->GetTeamId())
133 {
135 return;
136 }
137
138 if (player->GetArenaTeamId(arenaTeam->GetSlot()))
139 {
141 return;
142 }
143
144 if (player->GetArenaTeamIdInvited())
145 {
147 return;
148 }
149
150 if (arenaTeam->GetMembersSize() >= arenaTeam->GetType() * 2)
151 {
153 return;
154 }
155
156 LOG_DEBUG("bg.battleground", "Player {} Invited {} to Join his ArenaTeam", GetPlayer()->GetName(), invitedName);
157
158 player->SetArenaTeamIdInvited(arenaTeam->GetId());
159
160 WorldPacket data(SMSG_ARENA_TEAM_INVITE, (8 + 10));
161 data << GetPlayer()->GetName();
162 data << arenaTeam->GetName();
163 player->SendDirectMessage(&data);
164
165 LOG_DEBUG("network", "WORLD: Sent SMSG_ARENA_TEAM_INVITE");
166}
@ ERR_ARENA_TEAM_INVITE_SS
Definition ArenaTeam.h:33
@ ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S
Definition ArenaTeam.h:56
@ ERR_ALREADY_IN_ARENA_TEAM_S
Definition ArenaTeam.h:42
@ ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM
Definition ArenaTeam.h:49
@ ERR_ARENA_TEAM_PERMISSIONS
Definition ArenaTeam.h:48
@ ERR_ARENA_TEAM_TARGET_TOO_LOW_S
Definition ArenaTeam.h:54
@ ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S
Definition ArenaTeam.h:51
@ ERR_ALREADY_INVITED_TO_ARENA_TEAM_S
Definition ArenaTeam.h:44
@ CONFIG_MAX_PLAYER_LEVEL
Definition WorldConfig.h:190
std::size_t GetMembersSize() const
Definition ArenaTeam.h:169
uint32 GetType() const
Definition ArenaTeam.h:149
uint32 GetId() const
Definition ArenaTeam.h:148
bool HasIgnore(ObjectGuid const &ignore_guid) const
Definition SocialMgr.cpp:193
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:5762
@ SMSG_ARENA_TEAM_INVITE
Definition Opcodes.h:878
Player * FindPlayerByName(std::string const &name, bool checkInWorld=true)
Definition ObjectAccessor.cpp:271

References CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA, CONFIG_MAX_PLAYER_LEVEL, ERR_ALREADY_IN_ARENA_TEAM_S, ERR_ALREADY_INVITED_TO_ARENA_TEAM_S, ERR_ARENA_TEAM_CREATE_S, ERR_ARENA_TEAM_INVITE_SS, ERR_ARENA_TEAM_NOT_ALLIED, ERR_ARENA_TEAM_PERMISSIONS, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S, ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM, ERR_ARENA_TEAM_TARGET_TOO_LOW_S, ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S, ObjectAccessor::FindPlayerByName(), Player::GetArenaTeamId(), Player::GetArenaTeamIdInvited(), ArenaTeam::GetId(), Unit::GetLevel(), ArenaTeam::GetMembersSize(), ArenaTeam::GetName(), WorldObject::GetName(), GetPlayer(), ArenaTeam::GetSlot(), Player::GetSocial(), Player::GetTeamId(), GetTeamId(), ArenaTeam::GetType(), PlayerSocial::HasIgnore(), LOG_DEBUG, normalizePlayerName(), sArenaTeamMgr, SendArenaTeamCommandResult(), Player::SendDirectMessage(), Player::SetArenaTeamIdInvited(), SMSG_ARENA_TEAM_INVITE, and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleArenaTeamLeaderOpcode()

void WorldSession::HandleArenaTeamLeaderOpcode ( WorldPacket recvData)
364{
365 LOG_DEBUG("network", "CMSG_ARENA_TEAM_LEADER");
366
367 uint32 arenaTeamId;
368 std::string name;
369
370 recvData >> arenaTeamId;
371 recvData >> name;
372
373 // Check for valid arena team
374 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
375 if (!arenaTeam)
376 return;
377
378 // Only captain can pass leadership
379 if (arenaTeam->GetCaptain() != _player->GetGUID())
380 {
382 return;
383 }
384
385 if (!normalizePlayerName(name))
386 return;
387
388 // Check if team member exists
389 ArenaTeamMember* member = arenaTeam->GetMember(name);
390 if (!member)
391 {
393 return;
394 }
395
396 // Check if the target is already team captain
397 if (arenaTeam->GetCaptain() == member->Guid)
398 return;
399
400 arenaTeam->SetCaptain(member->Guid);
401
402 // Broadcast event
403 arenaTeam->BroadcastEvent(ERR_ARENA_TEAM_LEADER_CHANGED_SSS, ObjectGuid::Empty, 3, _player->GetName().c_str(), name, arenaTeam->GetName());
404}
@ ERR_ARENA_TEAM_LEADER_CHANGED_SSS
Definition ArenaTeam.h:67
void SetCaptain(ObjectGuid guid)
Definition ArenaTeam.cpp:298
ArenaTeamMember * GetMember(ObjectGuid guid)
Definition ArenaTeam.cpp:1015
Definition ArenaTeam.h:108
ObjectGuid Guid
Definition ArenaTeam.h:109

References _player, ArenaTeam::BroadcastEvent(), ObjectGuid::Empty, ERR_ARENA_TEAM_CREATE_S, ERR_ARENA_TEAM_LEADER_CHANGED_SSS, ERR_ARENA_TEAM_PERMISSIONS, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S, ArenaTeam::GetCaptain(), Object::GetGUID(), ArenaTeam::GetMember(), ArenaTeam::GetName(), WorldObject::GetName(), ArenaTeamMember::Guid, LOG_DEBUG, normalizePlayerName(), sArenaTeamMgr, SendArenaTeamCommandResult(), and ArenaTeam::SetCaptain().

Referenced by OpcodeTable::Initialize().

◆ HandleArenaTeamLeaveOpcode()

void WorldSession::HandleArenaTeamLeaveOpcode ( WorldPacket recvData)
210{
211 LOG_DEBUG("network", "CMSG_ARENA_TEAM_LEAVE");
212
213 uint32 arenaTeamId;
214 recvData >> arenaTeamId;
215
216 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
217 if (!arenaTeam)
218 return;
219
220 // Disallow leave team while in arena
221 if (arenaTeam->IsFighting())
222 {
224 return;
225 }
226
227 // Team captain can't leave the team if other members are still present
228 if (_player->GetGUID() == arenaTeam->GetCaptain() && arenaTeam->GetMembersSize() > 1)
229 {
231 return;
232 }
233
234 // Player cannot be removed during queues
236 {
237 GroupQueueInfo ginfo;
238 BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueue);
239 if (queue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
240 {
242 {
244 return;
245 }
246 }
247 }
248
249 // If team consists only of the captain, disband the team
250 if (_player->GetGUID() == arenaTeam->GetCaptain())
251 {
252 arenaTeam->Disband(this);
253 delete arenaTeam;
254 return;
255 }
256 else
257 arenaTeam->DelMember(_player->GetGUID(), true);
258
259 // Broadcast event
260 arenaTeam->BroadcastEvent(ERR_ARENA_TEAM_LEAVE_SS, _player->GetGUID(), 2, _player->GetName().c_str(), arenaTeam->GetName(), "");
261
262 // Inform player who left
264}
@ ERR_ARENA_TEAM_QUIT_S
Definition ArenaTeam.h:34
@ ERR_ARENA_TEAMS_LOCKED
Definition ArenaTeam.h:58
@ ERR_ARENA_TEAM_LEADER_LEAVE_S
Definition ArenaTeam.h:47
@ ERR_ARENA_TEAM_LEAVE_SS
Definition ArenaTeam.h:64
void Disband(WorldSession *session)
Definition ArenaTeam.cpp:386
void DelMember(ObjectGuid guid, bool cleanDb)
Definition ArenaTeam.cpp:327
bool IsFighting() const
Definition ArenaTeam.cpp:1000

References _player, BATTLEGROUND_AA, BattlegroundMgr::BGQueueTypeId(), ArenaTeam::BroadcastEvent(), ArenaTeam::DelMember(), ArenaTeam::Disband(), ERR_ARENA_TEAM_LEADER_LEAVE_S, ERR_ARENA_TEAM_LEAVE_SS, ERR_ARENA_TEAM_QUIT_S, ERR_ARENA_TEAMS_LOCKED, ArenaTeam::GetCaptain(), Object::GetGUID(), ArenaTeam::GetMembersSize(), ArenaTeam::GetName(), WorldObject::GetName(), BattlegroundQueue::GetPlayerGroupInfoData(), ArenaTeam::GetType(), ArenaTeam::IsFighting(), GroupQueueInfo::IsInvitedToBGInstanceGUID, LOG_DEBUG, sArenaTeamMgr, sBattlegroundMgr, and SendArenaTeamCommandResult().

Referenced by OpcodeTable::Initialize().

◆ HandleArenaTeamQueryOpcode()

void WorldSession::HandleArenaTeamQueryOpcode ( WorldPacket recvData)
64{
65 uint32 arenaTeamId;
66 recvData >> arenaTeamId;
67
68 if (ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId))
69 {
70 arenaTeam->Query(this);
71 arenaTeam->SendStats(this);
72 }
73}

References sArenaTeamMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleArenaTeamRemoveOpcode()

void WorldSession::HandleArenaTeamRemoveOpcode ( WorldPacket recvData)
299{
300 LOG_DEBUG("network", "CMSG_ARENA_TEAM_REMOVE");
301
302 uint32 arenaTeamId;
303 std::string name;
304
305 recvData >> arenaTeamId;
306 recvData >> name;
307
308 // Check for valid arena team
309 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
310 if (!arenaTeam)
311 return;
312
313 // Only captain can remove members
314 if (arenaTeam->GetCaptain() != _player->GetGUID())
315 {
317 return;
318 }
319
320 if (!normalizePlayerName(name))
321 return;
322
323 // Check if team member exists
324 ArenaTeamMember* member = arenaTeam->GetMember(name);
325 if (!member)
326 {
328 return;
329 }
330
331 // Captain cannot be removed
332 if (arenaTeam->GetCaptain() == member->Guid)
333 {
335 return;
336 }
337
338 // Team member cannot be removed during queues
340 {
341 GroupQueueInfo ginfo;
342 BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueue);
343 if (queue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
344 {
346 {
348 return;
349 }
350 }
351 }
352
353 // Player cannot be removed during fights
354 if (arenaTeam->IsFighting())
355 return;
356
357 arenaTeam->DelMember(member->Guid, true);
358
359 // Broadcast event
361}
@ ERR_ARENA_TEAM_REMOVE_SSS
Definition ArenaTeam.h:65

References _player, BATTLEGROUND_AA, BattlegroundMgr::BGQueueTypeId(), ArenaTeam::BroadcastEvent(), ArenaTeam::DelMember(), ObjectGuid::Empty, ERR_ARENA_TEAM_CREATE_S, ERR_ARENA_TEAM_LEADER_LEAVE_S, ERR_ARENA_TEAM_PERMISSIONS, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S, ERR_ARENA_TEAM_QUIT_S, ERR_ARENA_TEAM_REMOVE_SSS, ERR_ARENA_TEAMS_LOCKED, ArenaTeam::GetCaptain(), Object::GetGUID(), ArenaTeam::GetMember(), ArenaTeam::GetName(), WorldObject::GetName(), BattlegroundQueue::GetPlayerGroupInfoData(), ArenaTeam::GetType(), ArenaTeamMember::Guid, ArenaTeam::IsFighting(), GroupQueueInfo::IsInvitedToBGInstanceGUID, LOG_DEBUG, normalizePlayerName(), sArenaTeamMgr, sBattlegroundMgr, and SendArenaTeamCommandResult().

Referenced by OpcodeTable::Initialize().

◆ HandleArenaTeamRosterOpcode()

void WorldSession::HandleArenaTeamRosterOpcode ( WorldPacket recvData)
76{
77 uint32 arenaTeamId; // arena team id
78 recvData >> arenaTeamId;
79
80 if (ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId))
81 arenaTeam->Roster(this);
82}

References sArenaTeamMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleAttackStopOpcode()

void WorldSession::HandleAttackStopOpcode ( WorldPacket recvPacket)
69{
71}
bool AttackStop()
Force the unit to stop attacking. This will clear UNIT_STATE_MELEE_ATTACKING, Interrupt current spell...
Definition Unit.cpp:10607

References Unit::AttackStop(), and GetPlayer().

Referenced by OpcodeTable::Initialize().

◆ HandleAttackSwingOpcode()

void WorldSession::HandleAttackSwingOpcode ( WorldPacket recvPacket)

Client explicitly checks the following before sending CMSG_ATTACKSWING packet, so we'll place the same check here. Note that it might be possible to reuse this snippet in other places as well.

29{
30 ObjectGuid guid;
31 recvData >> guid;
32
33 LOG_DEBUG("network", "WORLD: Recvd CMSG_ATTACKSWING: {}", guid.ToString());
34
35 Unit* pEnemy = ObjectAccessor::GetUnit(*_player, guid);
36
37 if (!pEnemy)
38 {
39 // stop attack state at client
40 SendAttackStop(nullptr);
41 return;
42 }
43
44 if (!_player->IsValidAttackTarget(pEnemy))
45 {
46 // stop attack state at client
47 SendAttackStop(pEnemy);
48 return;
49 }
50
54 if (Vehicle* vehicle = _player->GetVehicle())
55 {
56 VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(_player);
57 ASSERT(seat);
59 {
60 SendAttackStop(pEnemy);
61 return;
62 }
63 }
64
65 _player->Attack(pEnemy, true);
66}
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition DBCEnums.h:458
#define ASSERT
Definition Errors.h:68
Definition Unit.h:655
bool Attack(Unit *victim, bool meleeAttack)
Definition Unit.cpp:10451
bool IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell=nullptr) const
Definition Unit.cpp:14029
void SendAttackStop(Unit const *enemy)
Definition CombatHandler.cpp:84
Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:199
Definition DBCStructure.h:2062
uint32 m_flags
Definition DBCStructure.h:2064

References _player, ASSERT, Unit::Attack(), ObjectAccessor::GetUnit(), Unit::GetVehicle(), Unit::IsValidAttackTarget(), LOG_DEBUG, VehicleSeatEntry::m_flags, SendAttackStop(), ObjectGuid::ToString(), and VEHICLE_SEAT_FLAG_CAN_ATTACK.

Referenced by OpcodeTable::Initialize().

◆ HandleAuctionHelloOpcode()

void WorldSession::HandleAuctionHelloOpcode ( WorldPacket recvPacket)
34{
35 ObjectGuid guid; //NPC guid
36 recvData >> guid;
37
39 if (!unit)
40 {
41 LOG_DEBUG("network", "WORLD: HandleAuctionHelloOpcode - Unit ({}) not found or you can't interact with him.", guid.ToString());
42 return;
43 }
44
45 // remove fake death
46 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
48
49 SendAuctionHello(guid, unit);
50}
@ SPELL_AURA_FEIGN_DEATH
Definition SpellAuraDefines.h:129
@ UNIT_NPC_FLAG_AUCTIONEER
Definition UnitDefines.h:340
@ UNIT_STATE_DIED
Definition UnitDefines.h:170
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition Unit.cpp:5229
void SendAuctionHello(ObjectGuid guid, Creature *unit)
Definition AuctionHouseHandler.cpp:53

References Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, Unit::RemoveAurasByType(), SendAuctionHello(), SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_AUCTIONEER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleAuctionListBidderItems()

void WorldSession::HandleAuctionListBidderItems ( WorldPacket recvData)
595{
596 ObjectGuid guid; //NPC guid
597 uint32 listfrom; //page of auctions
598 uint32 outbiddedCount; //count of outbidded auctions
599
600 recvData >> guid;
601 recvData >> listfrom; // not used in fact (this list not have page control in client)
602 recvData >> outbiddedCount;
603 if (recvData.size() != (16 + outbiddedCount * 4))
604 {
605 LOG_ERROR("network.opcode", "Client sent bad opcode!!! with count: {} and size : {} (must be: {})", outbiddedCount, (unsigned long)recvData.size(), (16 + outbiddedCount * 4));
606 outbiddedCount = 0;
607 }
608
610 if (!creature)
611 {
612 LOG_DEBUG("network", "WORLD: HandleAuctionListBidderItems - Unit ({}) not found or you can't interact with him.", guid.ToString());
613 recvData.rfinish();
614 return;
615 }
616
617 // Arbitrary cap, can be adjusted if needed
618 if (outbiddedCount > 1000)
619 return;
620
621 // remove fake death
622 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
624
626 if (!ahEntry)
627 return;
628
630
631 // Client sends this list, which I'm honestly not entirely sure why?
632 std::vector<uint32> auctionIds;
633 auctionIds.reserve(outbiddedCount);
634 while (outbiddedCount > 0) // add all data, which client requires
635 {
636 --outbiddedCount;
637 uint32 outbiddedAuctionId;
638 recvData >> outbiddedAuctionId;
639 auctionIds.push_back(outbiddedAuctionId);
640 }
641
642 sAuctionMgr->GetAuctionHouseSearcher()->QueueSearchRequest(new AuctionSearchBidderListRequest(auctionHouseFaction, std::move(auctionIds), GetPlayer()->GetGUID()));
643}
AuctionHouseId
Definition AuctionHouseMgr.h:88
#define sAuctionMgr
Definition AuctionHouseMgr.h:224
AuctionHouseFaction
Definition AuctionHouseMgr.h:81
static AuctionHouseEntry const * GetAuctionHouseEntryFromFactionTemplate(uint32 factionTemplateId)
Definition AuctionHouseMgr.cpp:457
static AuctionHouseFaction GetAuctionHouseFactionFromHouseId(AuctionHouseId ahHouseId)
Definition AuctionHouseMgr.cpp:443
std::size_t size() const
Definition ByteBuffer.h:444
void rfinish()
Definition ByteBuffer.h:325
uint32 GetFaction() const
Definition Unit.h:841
Definition DBCStructure.h:574
uint32 houseId
Definition DBCStructure.h:575
Definition AuctionHouseSearcher.h:173

References AuctionHouseMgr::GetAuctionHouseEntryFromFactionTemplate(), AuctionHouseMgr::GetAuctionHouseFactionFromHouseId(), Unit::GetFaction(), Player::GetNPCIfCanInteractWith(), GetPlayer(), AuctionHouseEntry::houseId, LOG_DEBUG, LOG_ERROR, Unit::RemoveAurasByType(), ByteBuffer::rfinish(), sAuctionMgr, ByteBuffer::size(), SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_AUCTIONEER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleAuctionListItems()

void WorldSession::HandleAuctionListItems ( WorldPacket recvData)
673{
674 std::string searchedname;
675 uint8 levelmin, levelmax, usable;
676 uint32 listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality;
677 ObjectGuid guid;
678
679 recvData >> guid;
680 recvData >> listfrom; // start, used for page control listing by 50 elements
681 recvData >> searchedname;
682
683 recvData >> levelmin >> levelmax;
684 recvData >> auctionSlotID >> auctionMainCategory >> auctionSubCategory;
685 recvData >> quality >> usable;
686
687 uint8 getAll;
688 recvData >> getAll;
689
690 // Read sort block
691 uint8 sortOrderCount;
692 recvData >> sortOrderCount;
693
694 if (sortOrderCount > AUCTION_SORT_MAX)
695 return;
696
697 AuctionSortOrderVector sortOrder;
698 for (uint8 i = 0; i < sortOrderCount; i++)
699 {
700 uint8 sortMode;
701 uint8 isDesc;
702 recvData >> sortMode;
703 recvData >> isDesc;
704 AuctionSortInfo sortInfo;
705 sortInfo.isDesc = (isDesc == 1);
706 sortInfo.sortOrder = static_cast<AuctionSortOrder>(sortMode);
707 sortOrder.push_back(std::move(sortInfo));
708 }
709
710 // converting string that we try to find to lower case
711 std::wstring wsearchedname;
712 if (!Utf8toWStr(searchedname, wsearchedname))
713 return;
714
715 wstrToLower(wsearchedname);
716
718 if (!creature)
719 return;
720
721 // remove fake death
724
726 if (!ahEntry)
727 return;
728
730
731 AuctionHouseSearchInfo ahSearchInfo;
732 ahSearchInfo.wsearchedname = wsearchedname;
733 ahSearchInfo.listfrom = listfrom;
734 ahSearchInfo.levelmin = levelmin;
735 ahSearchInfo.levelmax = levelmax;
736 ahSearchInfo.usable = usable;
737 ahSearchInfo.inventoryType = auctionSlotID;
738 ahSearchInfo.itemClass = auctionMainCategory;
739 ahSearchInfo.itemSubClass = auctionSubCategory;
740 ahSearchInfo.quality = quality;
741 ahSearchInfo.getAll = getAll;
742 ahSearchInfo.sorting = std::move(sortOrder);
743
744 AuctionHousePlayerInfo ahPlayerInfo;
745 ahPlayerInfo.playerGuid = GetPlayer()->GetGUID();
746 ahPlayerInfo.faction = GetPlayer()->GetFaction();
748 ahPlayerInfo.locdbc_idx = GetPlayer()->GetSession()->GetSessionDbcLocale();
749 if (usable)
750 {
751 AuctionHouseUsablePlayerInfo usablePlayerInfo;
752 usablePlayerInfo.classMask = GetPlayer()->getClassMask();
753 usablePlayerInfo.raceMask = GetPlayer()->getRaceMask();
754 usablePlayerInfo.level = GetPlayer()->GetLevel();
755
756 SkillStatusMap const& skillMap = GetPlayer()->GetSkillStatusMap();
757 for (auto const& pair : skillMap)
758 usablePlayerInfo.skills.insert(std::make_pair(pair.first, GetPlayer()->GetSkillValue(pair.first)));
759
760 PlayerSpellMap const& spellMap = GetPlayer()->GetSpellMap();
761 for (auto const& pair : spellMap)
762 {
763 if (pair.second->State != PLAYERSPELL_REMOVED && pair.second->IsInSpec(GetPlayer()->GetActiveSpec()))
764 usablePlayerInfo.spells.insert(pair.first);
765 }
766 ahPlayerInfo.usablePlayerInfo = std::move(usablePlayerInfo);
767 }
768
769 sAuctionMgr->GetAuctionHouseSearcher()->QueueSearchRequest(new AuctionSearchListRequest(auctionHouseFaction, std::move(ahSearchInfo), std::move(ahPlayerInfo)));
770}
AuctionSortOrder
Definition AuctionHouseSearcher.h:35
@ AUCTION_SORT_MAX
Definition AuctionHouseSearcher.h:48
std::vector< AuctionSortInfo > AuctionSortOrderVector
Definition AuctionHouseSearcher.h:97
std::unordered_map< uint32, PlayerSpell * > PlayerSpellMap
Definition Player.h:195
std::unordered_map< uint32, SkillStatusData > SkillStatusMap
Definition Player.h:649
@ PLAYERSPELL_REMOVED
Definition Player.h:123
bool Utf8toWStr(char const *utf8str, std::size_t csize, wchar_t *wstr, std::size_t &wsize)
Definition Util.cpp:281
void wstrToLower(std::wstring &str)
Definition Util.cpp:382
PlayerSpellMap const & GetSpellMap() const
Definition Player.h:1768
SkillStatusMap const & GetSkillStatusMap() const
Definition Player.h:1774
uint32 getRaceMask() const
Definition Unit.h:828
bool HasUnitState(const uint32 f) const
Definition Unit.h:726
uint32 getClassMask() const
Definition Unit.h:835
LocaleConstant GetSessionDbcLocale() const
Definition WorldSession.h:559
STL namespace.
Definition AuctionHouseSearcher.h:131
std::optional< AuctionHouseUsablePlayerInfo > usablePlayerInfo
Definition AuctionHouseSearcher.h:136
int locdbc_idx
Definition AuctionHouseSearcher.h:135
ObjectGuid playerGuid
Definition AuctionHouseSearcher.h:132
int loc_idx
Definition AuctionHouseSearcher.h:134
uint32 faction
Definition AuctionHouseSearcher.h:133
Definition AuctionHouseSearcher.h:100
std::wstring wsearchedname
Definition AuctionHouseSearcher.h:101
uint32 quality
Definition AuctionHouseSearcher.h:109
uint32 listfrom
Definition AuctionHouseSearcher.h:102
uint32 inventoryType
Definition AuctionHouseSearcher.h:106
AuctionSortOrderVector sorting
Definition AuctionHouseSearcher.h:111
bool getAll
Definition AuctionHouseSearcher.h:110
uint8 levelmax
Definition AuctionHouseSearcher.h:104
uint32 itemClass
Definition AuctionHouseSearcher.h:107
uint8 levelmin
Definition AuctionHouseSearcher.h:103
uint32 itemSubClass
Definition AuctionHouseSearcher.h:108
bool usable
Definition AuctionHouseSearcher.h:105
Definition AuctionHouseSearcher.h:118
uint32 classMask
Definition AuctionHouseSearcher.h:119
uint8 level
Definition AuctionHouseSearcher.h:121
uint32 raceMask
Definition AuctionHouseSearcher.h:120
AuctionPlayerSpells spells
Definition AuctionHouseSearcher.h:123
Definition AuctionHouseSearcher.h:156
Definition AuctionHouseSearcher.h:52
bool isDesc
Definition AuctionHouseSearcher.h:56
AuctionSortOrder sortOrder
Definition AuctionHouseSearcher.h:55

References _player, AUCTION_SORT_MAX, AuctionHouseUsablePlayerInfo::classMask, AuctionHousePlayerInfo::faction, AuctionHouseSearchInfo::getAll, AuctionHouseMgr::GetAuctionHouseEntryFromFactionTemplate(), AuctionHouseMgr::GetAuctionHouseFactionFromHouseId(), Unit::getClassMask(), Unit::GetFaction(), Object::GetGUID(), Unit::GetLevel(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Unit::getRaceMask(), Player::GetSession(), GetSessionDbcLocale(), GetSessionDbLocaleIndex(), Player::GetSkillStatusMap(), Player::GetSpellMap(), Unit::HasUnitState(), AuctionHouseEntry::houseId, AuctionHouseSearchInfo::inventoryType, AuctionSortInfo::isDesc, AuctionHouseSearchInfo::itemClass, AuctionHouseSearchInfo::itemSubClass, AuctionHouseUsablePlayerInfo::level, AuctionHouseSearchInfo::levelmax, AuctionHouseSearchInfo::levelmin, AuctionHouseSearchInfo::listfrom, AuctionHousePlayerInfo::loc_idx, AuctionHousePlayerInfo::locdbc_idx, AuctionHousePlayerInfo::playerGuid, PLAYERSPELL_REMOVED, AuctionHouseSearchInfo::quality, AuctionHouseUsablePlayerInfo::raceMask, Unit::RemoveAurasByType(), sAuctionMgr, AuctionHouseUsablePlayerInfo::skills, AuctionHouseSearchInfo::sorting, AuctionSortInfo::sortOrder, SPELL_AURA_FEIGN_DEATH, AuctionHouseUsablePlayerInfo::spells, UNIT_NPC_FLAG_AUCTIONEER, UNIT_STATE_DIED, AuctionHouseSearchInfo::usable, AuctionHousePlayerInfo::usablePlayerInfo, Utf8toWStr(), AuctionHouseSearchInfo::wsearchedname, and wstrToLower().

Referenced by OpcodeTable::Initialize().

◆ HandleAuctionListOwnerItems()

void WorldSession::HandleAuctionListOwnerItems ( WorldPacket recvData)
647{
648 ObjectGuid guid;
649 uint32 listfrom;
650
651 recvData >> guid;
652 recvData >> listfrom; // not used in fact (this list does not have page control in client)
653
655 if (!creature)
656 return;
657
658 // remove fake death
659 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
661
663 if (!ahEntry)
664 return;
665
667
668 sAuctionMgr->GetAuctionHouseSearcher()->QueueSearchRequest(new AuctionSearchOwnerListRequest(auctionHouseFaction, GetPlayer()->GetGUID()));
669}
Definition AuctionHouseSearcher.h:165

References AuctionHouseMgr::GetAuctionHouseEntryFromFactionTemplate(), AuctionHouseMgr::GetAuctionHouseFactionFromHouseId(), Unit::GetFaction(), Player::GetNPCIfCanInteractWith(), GetPlayer(), AuctionHouseEntry::houseId, Unit::RemoveAurasByType(), sAuctionMgr, SPELL_AURA_FEIGN_DEATH, UNIT_NPC_FLAG_AUCTIONEER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleAuctionListPendingSales()

void WorldSession::HandleAuctionListPendingSales ( WorldPacket recvData)
773{
774 recvData.read_skip<uint64>();
775
776 uint32 count = 0;
777
779 data << uint32(count); // count
780 /*for (uint32 i = 0; i < count; ++i)
781 {
782 data << ""; // string
783 data << ""; // string
784 data << uint32(0);
785 data << uint32(0);
786 data << float(0);
787 }*/
788 SendPacket(&data);
789}
void read_skip()
Definition ByteBuffer.h:339
@ SMSG_AUCTION_LIST_PENDING_SALES
Definition Opcodes.h:1198

References ByteBuffer::read_skip(), SendPacket(), and SMSG_AUCTION_LIST_PENDING_SALES.

Referenced by OpcodeTable::Initialize().

◆ HandleAuctionPlaceBid()

void WorldSession::HandleAuctionPlaceBid ( WorldPacket recvData)
394{
395 ObjectGuid auctioneer;
396 uint32 auctionId;
397 uint32 price;
398 recvData >> auctioneer;
399 recvData >> auctionId >> price;
400
401 if (!auctionId || !price)
402 return; //check for cheaters
403
405 if (!creature)
406 {
407 LOG_DEBUG("network", "WORLD: HandleAuctionPlaceBid - Unit ({}) not found or you can't interact with him.", auctioneer.ToString());
408 return;
409 }
410
411 // remove fake death
412 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
414
415 AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->GetFaction());
416
417 AuctionEntry* auction = auctionHouse->GetAuction(auctionId);
418 Player* player = GetPlayer();
419
420 if (!sScriptMgr->OnPlayerCanPlaceAuctionBid(player, auction))
421 {
423 return;
424 }
425
426 if (!auction || auction->owner == player->GetGUID())
427 {
428 //you cannot bid your own auction:
430 return;
431 }
432
433 // impossible have online own another character (use this for speedup check in case online owner)
434 Player* auction_owner = ObjectAccessor::FindConnectedPlayer(auction->owner);
435 if (!auction_owner && sCharacterCache->GetCharacterAccountIdByGuid(auction->owner) == GetAccountId())
436 {
437 //you cannot bid your another character auction:
439 return;
440 }
441
442 // cheating
443 if (price <= auction->bid || price < auction->startbid)
444 return;
445
446 // price too low for next bid if not buyout
447 if ((price < auction->buyout || auction->buyout == 0) &&
448 price < auction->bid + AuctionEntry::CalculateAuctionOutBid(auction->bid))
449 {
450 //auction has already higher bid, client tests it!
451 return;
452 }
453
454 if (!player->HasEnoughMoney(price))
455 {
456 //you don't have enought money!, client tests!
457 //SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???);
458 return;
459 }
460
461 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
462
463 if (price < auction->buyout || auction->buyout == 0)
464 {
465 if (auction->bidder)
466 {
467 if (auction->bidder == player->GetGUID())
468 player->ModifyMoney(-int32(price - auction->bid));
469 else
470 {
471 // mail to last bidder and return money
472 sAuctionMgr->SendAuctionOutbiddedMail(auction, price, GetPlayer(), trans);
473 player->ModifyMoney(-int32(price));
474 }
475 }
476 else
477 player->ModifyMoney(-int32(price));
478
479 auction->bidder = player->GetGUID();
480 auction->bid = price;
481
482 sAuctionMgr->GetAuctionHouseSearcher()->UpdateBid(auction);
483
485
487 stmt->SetData(0, auction->bidder.GetCounter());
488 stmt->SetData(1, auction->bid);
489 stmt->SetData(2, auction->Id);
490 trans->Append(stmt);
491
493 }
494 else
495 {
496 //buyout:
497 if (player->GetGUID() == auction->bidder)
498 player->ModifyMoney(-int32(auction->buyout - auction->bid));
499 else
500 {
501 player->ModifyMoney(-int32(auction->buyout));
502 if (auction->bidder) //buyout for bidded auction ..
503 sAuctionMgr->SendAuctionOutbiddedMail(auction, auction->buyout, GetPlayer(), trans);
504 }
505 auction->bidder = player->GetGUID();
506 auction->bid = auction->buyout;
508
509 //- Mails must be under transaction control too to prevent data loss
510 sAuctionMgr->SendAuctionSalePendingMail(auction, trans);
511 sAuctionMgr->SendAuctionSuccessfulMail(auction, trans);
512 sAuctionMgr->SendAuctionWonMail(auction, trans);
513 sScriptMgr->OnAuctionSuccessful(auctionHouse, auction);
514
516
517 auction->DeleteFromDB(trans);
518
519 sAuctionMgr->RemoveAItem(auction->item_guid);
520 auctionHouse->RemoveAuction(auction);
521 }
522 player->SaveInventoryAndGoldToDB(trans);
523 CharacterDatabase.CommitTransaction(trans);
524}
@ AUCTION_PLACE_BID
Definition AuctionHouseMgr.h:66
@ ERR_AUCTION_OK
Definition AuctionHouseMgr.h:51
@ ERR_AUCTION_RESTRICTED_ACCOUNT
Definition AuctionHouseMgr.h:59
@ ERR_AUCTION_BID_OWN
Definition AuctionHouseMgr.h:58
@ CHAR_UPD_AUCTION_BID
Definition CharacterDatabase.h:107
@ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID
Definition DBCEnums.h:191
Definition AuctionHouseMgr.h:127
AuctionEntry * GetAuction(uint32 id) const
Definition AuctionHouseMgr.h:145
bool RemoveAuction(AuctionEntry *auction)
Definition AuctionHouseMgr.cpp:489
Acore::Types::is_default< T > SetData(const uint8 index, T value)
Definition PreparedStatement.h:77
Definition PreparedStatement.h:157
void SendAuctionCommandResult(uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError=0)
Definition AuctionHouseHandler.cpp:76
Definition AuctionHouseMgr.h:97
uint32 bid
Definition AuctionHouseMgr.h:105
void DeleteFromDB(CharacterDatabaseTransaction trans) const
Definition AuctionHouseMgr.cpp:571
ObjectGuid bidder
Definition AuctionHouseMgr.h:108
ObjectGuid item_guid
Definition AuctionHouseMgr.h:100
uint32 Id
Definition AuctionHouseMgr.h:98
static uint32 CalculateAuctionOutBid(uint32 bid)
the sum of outbid is (1% from current bid)*5, if bid is very small, it is 1c
Definition AuctionHouseMgr.cpp:565
uint32 buyout
Definition AuctionHouseMgr.h:106
ObjectGuid owner
Definition AuctionHouseMgr.h:103

References ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, AUCTION_PLACE_BID, AuctionEntry::bid, AuctionEntry::bidder, AuctionEntry::buyout, AuctionEntry::CalculateAuctionOutBid(), CHAR_UPD_AUCTION_BID, CharacterDatabase, AuctionEntry::DeleteFromDB(), ERR_AUCTION_BID_OWN, ERR_AUCTION_OK, ERR_AUCTION_RESTRICTED_ACCOUNT, ObjectAccessor::FindConnectedPlayer(), GetAccountId(), AuctionHouseObject::GetAuction(), ObjectGuid::GetCounter(), Unit::GetFaction(), Object::GetGUID(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Player::HasEnoughMoney(), AuctionEntry::Id, AuctionEntry::item_guid, LOG_DEBUG, Player::ModifyMoney(), AuctionEntry::owner, AuctionHouseObject::RemoveAuction(), Unit::RemoveAurasByType(), sAuctionMgr, Player::SaveInventoryAndGoldToDB(), sCharacterCache, SendAuctionCommandResult(), PreparedStatementBase::SetData(), SPELL_AURA_FEIGN_DEATH, sScriptMgr, ObjectGuid::ToString(), UNIT_NPC_FLAG_AUCTIONEER, UNIT_STATE_DIED, and Player::UpdateAchievementCriteria().

Referenced by OpcodeTable::Initialize().

◆ HandleAuctionRemoveItem()

void WorldSession::HandleAuctionRemoveItem ( WorldPacket recvData)
528{
529 ObjectGuid auctioneer;
530 uint32 auctionId;
531 recvData >> auctioneer;
532 recvData >> auctionId;
533
535 if (!creature)
536 {
537 LOG_DEBUG("network", "WORLD: HandleAuctionRemoveItem - Unit ({}) not found or you can't interact with him.", auctioneer.ToString());
538 return;
539 }
540
541 // remove fake death
542 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
544
545 AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->GetFaction());
546
547 AuctionEntry* auction = auctionHouse->GetAuction(auctionId);
548 Player* player = GetPlayer();
549
550 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
551 if (auction && auction->owner == player->GetGUID())
552 {
553 Item* pItem = sAuctionMgr->GetAItem(auction->item_guid);
554 if (!pItem)
555 return;
556
557 if (auction->bidder) // If we have a bidder, we have to send him the money he paid
558 {
559 uint32 auctionCut = auction->GetAuctionCut();
560 if (!player->HasEnoughMoney(auctionCut)) //player doesn't have enough money, maybe message needed
561 return;
562 //some auctionBidderNotification would be needed, but don't know that parts..
563 sAuctionMgr->SendAuctionCancelledToBidderMail(auction, trans);
564 player->ModifyMoney(-int32(auctionCut));
565 }
566
567 // item will deleted or added to received mail list
569 .AddItem(pItem)
570 .SendMailTo(trans, player, auction, MAIL_CHECK_MASK_COPIED);
571 }
572 else
573 {
575 //this code isn't possible ... maybe there should be assert
576 LOG_ERROR("network.opcode", "CHEATER : {}, he tried to cancel auction (id: {}) of another player, or auction is nullptr", player->GetGUID().ToString(), auctionId);
577 return;
578 }
579
580 //inform player, that auction is removed
582
583 // Now remove the auction
584
585 player->SaveInventoryAndGoldToDB(trans);
586 auction->DeleteFromDB(trans);
587 CharacterDatabase.CommitTransaction(trans);
588
589 sAuctionMgr->RemoveAItem(auction->item_guid);
590 auctionHouse->RemoveAuction(auction);
591}
@ AUCTION_CANCELED
Definition AuctionHouseMgr.h:76
@ AUCTION_CANCEL
Definition AuctionHouseMgr.h:65
@ ERR_AUCTION_DATABASE_ERROR
Definition AuctionHouseMgr.h:53
@ MAIL_CHECK_MASK_COPIED
This mail was returned. Do not allow returning mail back again.
Definition Mail.h:49
Definition Mail.h:119
void SendMailTo(CharacterDatabaseTransaction trans, MailReceiver const &receiver, MailSender const &sender, MailCheckMask checked=MAIL_CHECK_MASK_NONE, uint32 deliver_delay=0, uint32 custom_expiration=0, bool deleteMailItemsFromDB=false, bool sendMail=true)
Definition Mail.cpp:185
MailDraft & AddItem(Item *item)
Definition Mail.cpp:93
static std::string BuildAuctionMailBody(ObjectGuid guid, uint32 bid, uint32 buyout, uint32 deposit=0, uint32 cut=0, uint32 moneyDelay=0, uint32 eta=0)
Definition AuctionHouseMgr.cpp:633
std::string BuildAuctionMailSubject(MailAuctionAnswers response) const
Definition AuctionHouseMgr.cpp:626
uint32 deposit
Definition AuctionHouseMgr.h:109
uint32 GetAuctionCut() const
Definition AuctionHouseMgr.cpp:553

References MailDraft::AddItem(), AUCTION_CANCEL, AUCTION_CANCELED, AuctionEntry::bidder, AuctionEntry::BuildAuctionMailBody(), AuctionEntry::BuildAuctionMailSubject(), AuctionEntry::buyout, CharacterDatabase, AuctionEntry::DeleteFromDB(), AuctionEntry::deposit, ObjectGuid::Empty, ERR_AUCTION_DATABASE_ERROR, ERR_AUCTION_OK, AuctionHouseObject::GetAuction(), AuctionEntry::GetAuctionCut(), Unit::GetFaction(), Object::GetGUID(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Player::HasEnoughMoney(), AuctionEntry::Id, AuctionEntry::item_guid, LOG_DEBUG, LOG_ERROR, MAIL_CHECK_MASK_COPIED, Player::ModifyMoney(), AuctionEntry::owner, AuctionHouseObject::RemoveAuction(), Unit::RemoveAurasByType(), sAuctionMgr, Player::SaveInventoryAndGoldToDB(), SendAuctionCommandResult(), MailDraft::SendMailTo(), SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_AUCTIONEER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleAuctionSellItem()

void WorldSession::HandleAuctionSellItem ( WorldPacket recvData)
117{
118 ObjectGuid auctioneer;
119 uint32 itemsCount, etime, bid, buyout;
120 recvData >> auctioneer;
121 recvData >> itemsCount;
122
123 ObjectGuid itemGUIDs[MAX_AUCTION_ITEMS]; // 160 slot = 4x 36 slot bag + backpack 16 slot
125 memset(count, 0, sizeof(count));
126
127 if (itemsCount > MAX_AUCTION_ITEMS)
128 {
130 recvData.rfinish();
131 return;
132 }
133
134 for (uint32 i = 0; i < itemsCount; ++i)
135 {
136 recvData >> itemGUIDs[i];
137 recvData >> count[i];
138
139 if (!itemGUIDs[i] || !count[i] || count[i] > 1000)
140 {
141 recvData.rfinish();
142 return;
143 }
144 }
145
146 recvData >> bid;
147 recvData >> buyout;
148 recvData >> etime;
149
150 if (!bid || !etime)
151 return;
152
153 if (bid > MAX_MONEY_AMOUNT || buyout > MAX_MONEY_AMOUNT)
154 {
155 LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Player {} ({}) attempted to sell item with higher price than max gold amount.",
158 return;
159 }
160
162 if (!creature)
163 {
164 LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Unit ({}) not found or you can't interact with him.", auctioneer.ToString());
165 return;
166 }
167
169 if (!auctionHouseEntry)
170 {
171 LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Unit ({}) has wrong faction.", auctioneer.ToString());
172 return;
173 }
174
175 etime *= MINUTE;
176
177 switch (etime)
178 {
179 case 1*MIN_AUCTION_TIME:
180 case 2*MIN_AUCTION_TIME:
181 case 4*MIN_AUCTION_TIME:
182 break;
183 default:
184 return;
185 }
186
187 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
189
190 Item* items[MAX_AUCTION_ITEMS];
191
192 uint32 finalCount = 0;
193 uint32 itemEntry = 0;
194
195 for (uint32 i = 0; i < itemsCount; ++i)
196 {
197 Item* item = _player->GetItemByGuid(itemGUIDs[i]);
198
199 if (!item)
200 {
202 return;
203 }
204
205 if (itemEntry == 0)
206 itemEntry = item->GetTemplate()->ItemId;
207
208 if (sAuctionMgr->GetAItem(item->GetGUID()) || !item->CanBeTraded() || item->IsNotEmptyBag() ||
210 item->GetCount() < count[i] || itemEntry != item->GetTemplate()->ItemId)
211 {
213 return;
214 }
215
216 items[i] = item;
217 finalCount += count[i];
218 }
219
220 if (!finalCount)
221 {
223 return;
224 }
225
226 // check if there are 2 identical guids, in this case user is most likely cheating
227 for (uint32 i = 0; i < itemsCount - 1; ++i)
228 {
229 for (uint32 j = i + 1; j < itemsCount; ++j)
230 {
231 if (itemGUIDs[i] == itemGUIDs[j])
232 {
234 return;
235 }
236 }
237 }
238
239 for (uint32 i = 0; i < itemsCount; ++i)
240 {
241 Item* item = items[i];
242
243 if (item->GetMaxStackCount() < finalCount)
244 {
246 return;
247 }
248 }
249
250 for (uint32 i = 0; i < itemsCount; ++i)
251 {
252 Item* item = items[i];
253
254 uint32 auctionTime = uint32(etime * sWorld->getRate(RATE_AUCTION_TIME));
255 AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->GetFaction());
256
257 uint32 deposit = sAuctionMgr->GetAuctionDeposit(auctionHouseEntry, etime, item, finalCount);
258 if (!_player->HasEnoughMoney(deposit))
259 {
261 return;
262 }
263
264 _player->ModifyMoney(-int32(deposit));
265
266 AuctionEntry* AH = new AuctionEntry;
267 AH->Id = sObjectMgr->GenerateAuctionID();
268
271 else
272 {
273 CreatureData const* auctioneerData = sObjectMgr->GetCreatureData(creature->GetSpawnId());
274 if (!auctioneerData)
275 {
276 LOG_ERROR("network.opcode", "Data for auctioneer not found ({})", auctioneer.ToString());
277 delete AH;
278 return;
279 }
280
281 CreatureTemplate const* auctioneerInfo = sObjectMgr->GetCreatureTemplate(auctioneerData->id1);
282 if (!auctioneerInfo)
283 {
284 LOG_ERROR("network.opcode", "Non existing auctioneer ({})", auctioneer.ToString());
285 delete AH;
286 return;
287 }
288
289 const AuctionHouseEntry* AHEntry = sAuctionMgr->GetAuctionHouseEntryFromFactionTemplate(auctioneerInfo->faction);
290 AH->houseId = AuctionHouseId(AHEntry->houseId);
291 }
292
293 // Required stack size of auction matches to current item stack size, just move item to auctionhouse
294 if (itemsCount == 1 && item->GetCount() == count[i])
295 {
296 AH->item_guid = item->GetGUID();
297 AH->item_template = item->GetEntry();
298 AH->itemCount = item->GetCount();
299 AH->owner = _player->GetGUID();
300 AH->startbid = bid;
302 AH->bid = 0;
303 AH->buyout = buyout;
304 AH->expire_time = GameTime::GetGameTime().count() + auctionTime;
305 AH->deposit = deposit;
306 AH->auctionHouseEntry = auctionHouseEntry;
307
308 LOG_DEBUG("network.opcode", "CMSG_AUCTION_SELL_ITEM: Player {} ({}) is selling item {} entry {} ({}) with count {} with initial bid {} with buyout {} and with time {} (in sec) in auctionhouse {}",
309 _player->GetName(), _player->GetGUID().ToString(), item->GetTemplate()->Name1, item->GetEntry(), item->GetGUID().ToString(), item->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
310 sAuctionMgr->AddAItem(item);
311 auctionHouse->AddAuction(AH);
312
313 _player->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true);
314
315 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
316 item->DeleteFromInventoryDB(trans);
317 item->SaveToDB(trans);
318 AH->SaveToDB(trans);
320 CharacterDatabase.CommitTransaction(trans);
321
323
325 return;
326 }
327 else // Required stack size of auction does not match to current item stack size, clone item and set correct stack size
328 {
329 Item* newItem = item->CloneItem(finalCount, _player);
330 if (!newItem)
331 {
332 LOG_ERROR("network.opcode", "CMSG_AUCTION_SELL_ITEM: Could not create clone of item {}", item->GetEntry());
334 return;
335 }
336
337 AH->item_guid = newItem->GetGUID();
338 AH->item_template = newItem->GetEntry();
339 AH->itemCount = newItem->GetCount();
340 AH->owner = _player->GetGUID();
341 AH->startbid = bid;
343 AH->bid = 0;
344 AH->buyout = buyout;
345 AH->expire_time = GameTime::GetGameTime().count() + auctionTime;
346 AH->deposit = deposit;
347 AH->auctionHouseEntry = auctionHouseEntry;
348
349 LOG_DEBUG("network.opcode", "CMSG_AUCTION_SELL_ITEM: Player {} ({}) is selling item {} entry {} ({}) with count {} with initial bid {} with buyout {} and with time {} (in sec) in auctionhouse {}",
350 _player->GetName(), _player->GetGUID().ToString(), newItem->GetTemplate()->Name1, newItem->GetEntry(), newItem->GetGUID().ToString(), newItem->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
351 sAuctionMgr->AddAItem(newItem);
352 auctionHouse->AddAuction(AH);
353
354 for (uint32 j = 0; j < itemsCount; ++j)
355 {
356 Item* item2 = items[j];
357
358 // Item stack count equals required count, ready to delete item - cloned item will be used for auction
359 if (item2->GetCount() == count[j])
360 {
361 _player->MoveItemFromInventory(item2->GetBagSlot(), item2->GetSlot(), true);
362
363 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
364 item2->DeleteFromInventoryDB(trans);
365 item2->DeleteFromDB(trans);
366 CharacterDatabase.CommitTransaction(trans);
367 delete item2;
368 }
369 else // Item stack count is bigger than required count, update item stack count and save to database - cloned item will be used for auction
370 {
371 item2->SetCount(item2->GetCount() - count[j]);
373 _player->ItemRemovedQuestCheck(item2->GetEntry(), count[j]);
375 }
376 }
377
378 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
379 newItem->SaveToDB(trans);
380 AH->SaveToDB(trans);
382 CharacterDatabase.CommitTransaction(trans);
383
385
387 return;
388 }
389 }
390}
#define MIN_AUCTION_TIME
Definition AuctionHouseMgr.h:34
@ AUCTION_SELL_ITEM
Definition AuctionHouseMgr.h:64
#define MAX_AUCTION_ITEMS
Definition AuctionHouseMgr.h:35
@ ERR_AUCTION_NOT_ENOUGHT_MONEY
Definition AuctionHouseMgr.h:54
@ ERR_AUCTION_ITEM_NOT_FOUND
Definition AuctionHouseMgr.h:55
constexpr auto MINUTE
Definition Common.h:47
@ ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION
Definition DBCEnums.h:190
@ ITEM_FLAG_CONJURED
Definition ItemTemplate.h:148
@ ITEM_CHANGED
Definition Item.h:210
@ ITEM_FIELD_DURATION
Definition UpdateFields.h:40
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION
Definition WorldConfig.h:37
@ RATE_AUCTION_TIME
Definition WorldConfig.h:468
void AddAuction(AuctionEntry *auction)
Definition AuctionHouseMgr.cpp:479
ObjectGuid::LowType GetSpawnId() const
Definition Creature.h:69
static void DeleteFromInventoryDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid)
Definition Item.cpp:532
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition Item.cpp:714
virtual void SaveToDB(CharacterDatabaseTransaction trans)
Definition Item.cpp:336
Item * CloneItem(uint32 count, Player const *player=nullptr) const
Definition Item.cpp:1118
bool CanBeTraded(bool mail=false, bool trade=false) const
Definition Item.cpp:794
void SetCount(uint32 value)
Definition Item.h:273
bool IsNotEmptyBag() const
Definition Item.cpp:311
uint32 GetMaxStackCount() const
Definition Item.h:274
static void DeleteFromDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid)
Definition Item.cpp:518
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:294
uint32 GetEntry() const
Definition Object.h:116
void SendUpdateToPlayer(Player *player)
Definition Object.cpp:235
void ItemRemovedQuestCheck(uint32 entry, uint32 count)
Definition PlayerQuest.cpp:1872
Seconds GetGameTime()
Definition GameTime.cpp:38
AuctionHouseId houseId
Definition AuctionHouseMgr.h:99
AuctionHouseId GetHouseId() const
Definition AuctionHouseMgr.h:113
AuctionHouseEntry const * auctionHouseEntry
Definition AuctionHouseMgr.h:110
void SaveToDB(CharacterDatabaseTransaction trans) const
Definition AuctionHouseMgr.cpp:578
time_t expire_time
Definition AuctionHouseMgr.h:107
uint32 startbid
Definition AuctionHouseMgr.h:104
uint32 itemCount
Definition AuctionHouseMgr.h:102
uint32 item_template
Definition AuctionHouseMgr.h:101
Definition CreatureData.h:370
uint32 id1
Definition CreatureData.h:372
Definition CreatureData.h:186
uint32 faction
Definition CreatureData.h:198
std::string Name1
Definition ItemTemplate.h:624
uint32 ItemId
Definition ItemTemplate.h:620

References _player, ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, AuctionHouseObject::AddAuction(), AUCTION_SELL_ITEM, AuctionEntry::auctionHouseEntry, AuctionEntry::bid, AuctionEntry::bidder, AuctionEntry::buyout, Item::CanBeTraded(), CharacterDatabase, Item::CloneItem(), CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION, Item::DeleteFromDB(), Item::DeleteFromInventoryDB(), AuctionEntry::deposit, ObjectGuid::Empty, ERR_AUCTION_DATABASE_ERROR, ERR_AUCTION_ITEM_NOT_FOUND, ERR_AUCTION_NOT_ENOUGHT_MONEY, ERR_AUCTION_OK, AuctionEntry::expire_time, CreatureTemplate::faction, AuctionHouseMgr::GetAuctionHouseEntryFromFactionTemplate(), Item::GetBagSlot(), Item::GetCount(), Object::GetEntry(), Unit::GetFaction(), GameTime::GetGameTime(), Object::GetGUID(), AuctionEntry::GetHouseId(), Player::GetItemByGuid(), Item::GetMaxStackCount(), WorldObject::GetName(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Item::GetSlot(), Creature::GetSpawnId(), Item::GetTemplate(), Object::GetUInt32Value(), Player::HasEnoughMoney(), ItemTemplate::HasFlag(), AuctionEntry::houseId, AuctionHouseEntry::houseId, AuctionEntry::Id, CreatureData::id1, Item::IsNotEmptyBag(), ITEM_CHANGED, ITEM_FIELD_DURATION, ITEM_FLAG_CONJURED, AuctionEntry::item_guid, AuctionEntry::item_template, AuctionEntry::itemCount, ItemTemplate::ItemId, Player::ItemRemovedQuestCheck(), LOG_DEBUG, LOG_ERROR, MAX_AUCTION_ITEMS, MAX_MONEY_AMOUNT, MIN_AUCTION_TIME, MINUTE, Player::ModifyMoney(), Player::MoveItemFromInventory(), ItemTemplate::Name1, Neutral, AuctionEntry::owner, RATE_AUCTION_TIME, Unit::RemoveAurasByType(), ByteBuffer::rfinish(), sAuctionMgr, Player::SaveInventoryAndGoldToDB(), Item::SaveToDB(), AuctionEntry::SaveToDB(), SendAuctionCommandResult(), Object::SendUpdateToPlayer(), Item::SetCount(), Item::SetState(), sObjectMgr, SPELL_AURA_FEIGN_DEATH, AuctionEntry::startbid, sWorld, ObjectGuid::ToString(), UNIT_NPC_FLAG_AUCTIONEER, UNIT_STATE_DIED, and Player::UpdateAchievementCriteria().

Referenced by OpcodeTable::Initialize().

◆ HandleAutoBankItemOpcode()

void WorldSession::HandleAutoBankItemOpcode ( WorldPackets::Bank::AutoBankItem packet)
65{
66 LOG_DEBUG("network", "STORAGE: receive bag = {}, slot = {}", packet.Bag, packet.Slot);
67
68 if (!CanUseBank())
69 {
70 LOG_DEBUG("network", "WORLD: HandleAutoBankItemOpcode - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
71 return;
72 }
73
74 Item* item = _player->GetItemByPos(packet.Bag, packet.Slot);
75 if (!item)
76 return;
77
78 ItemPosCountVec dest;
79 InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, item, false);
80 if (msg != EQUIP_ERR_OK)
81 {
82 _player->SendEquipError(msg, item, nullptr);
83 return;
84 }
85
86 if (dest.size() == 1 && dest[0].pos == item->GetPos())
87 {
88 _player->SendEquipError(EQUIP_ERR_NONE, item, nullptr);
89 return;
90 }
91
92 _player->RemoveItem(packet.Bag, packet.Slot, true);
94 _player->BankItem(dest, item, true);
96}
InventoryResult
Definition Item.h:46
@ EQUIP_ERR_NONE
Definition Item.h:106
@ NULL_BAG
Definition Item.h:40
@ NULL_SLOT
Definition Item.h:41
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:766
uint16 GetPos() const
Definition Item.h:285
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition Player.h:1333
Item * GetItemByPos(uint16 pos) const
Definition PlayerStorage.cpp:443
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition PlayerStorage.cpp:2039
void RemoveItem(uint8 bag, uint8 slot, bool update)
Definition PlayerStorage.cpp:2905
void UpdateTitansGrip()
Definition PlayerUpdates.cpp:1833
uint8 Bag
Definition BankPackets.h:35
uint8 Slot
Definition BankPackets.h:36
bool CanUseBank(ObjectGuid bankerGUID=ObjectGuid::Empty) const
Definition BankHandler.cpp:26

References _player, WorldPackets::Bank::AutoBankItem::Bag, Player::BankItem(), Player::CanBankItem(), CanUseBank(), EQUIP_ERR_NONE, EQUIP_ERR_OK, Item::GetCount(), Object::GetEntry(), Player::GetItemByPos(), Item::GetPos(), Player::ItemRemovedQuestCheck(), LOG_DEBUG, m_currentBankerGUID, NULL_BAG, NULL_SLOT, Player::RemoveItem(), Player::SendEquipError(), WorldPackets::Bank::AutoBankItem::Slot, ObjectGuid::ToString(), and Player::UpdateTitansGrip().

Referenced by OpcodeTable::Initialize().

◆ HandleAutoEquipItemOpcode()

void WorldSession::HandleAutoEquipItemOpcode ( WorldPackets::Item::AutoEquipItem packet)
154{
155 //LOG_DEBUG("network.opcode", "WORLD: CMSG_AUTOEQUIP_ITEM");
156
157 Item* pSrcItem = _player->GetItemByPos(packet.SourceBag, packet.SourceSlot);
158 if (!pSrcItem)
159 return; // only at cheat
160
161 ItemTemplate const* pProto = pSrcItem->GetTemplate();
162 if (!pProto)
163 {
165 return;
166 }
167
168 uint8 eslot = _player->FindEquipSlot(pProto, NULL_SLOT, !pSrcItem->IsBag());
169 if (eslot == NULL_SLOT)
170 {
172 return;
173 }
174
175 uint16 src = pSrcItem->GetPos();
176 uint16 dest = ((INVENTORY_SLOT_BAG_0 << 8) | eslot);
177 if (dest == src) // prevent equip in same slot, only at cheat
178 {
180 return;
181 }
182
183 Item* pDstItem = _player->GetItemByPos(dest);
184
185 // Remove item enchantments for now and restore it later
186 // Needed for swap sanity checks
187 if (pDstItem)
188 {
189 _player->ApplyEnchantment(pDstItem, false);
190 }
191
192 InventoryResult msg = _player->CanEquipItem(NULL_SLOT, dest, pSrcItem, !pSrcItem->IsBag());
193 if (msg != EQUIP_ERR_OK)
194 {
195 // Restore enchantments
196 if (pDstItem)
197 {
198 _player->ApplyEnchantment(pDstItem, true);
199 }
200
201 _player->SendEquipError(msg, pSrcItem, nullptr);
202 return;
203 }
204
205 if (!pDstItem) // empty slot, simple case
206 {
207 _player->RemoveItem(packet.SourceBag, packet.SourceSlot, true);
208 _player->EquipItem(dest, pSrcItem, true);
210 }
211 else // have currently equipped item, not simple case
212 {
213 // Restore enchantments
214 _player->ApplyEnchantment(pDstItem, true);
215
216 uint8 dstbag = pDstItem->GetBagSlot();
217 uint8 dstslot = pDstItem->GetSlot();
218
219 msg = _player->CanUnequipItem(dest, !pSrcItem->IsBag());
220 if (msg != EQUIP_ERR_OK)
221 {
222 _player->SendEquipError(msg, pDstItem, nullptr);
223 return;
224 }
225
226 // check dest->src move possibility
227 ItemPosCountVec sSrc;
228 uint16 eSrc = 0;
229 if (_player->IsInventoryPos(src))
230 {
231 msg = _player->CanStoreItem(packet.SourceBag, packet.SourceSlot, sSrc, pDstItem, true);
232 if (msg != EQUIP_ERR_OK)
233 msg = _player->CanStoreItem(packet.SourceBag, NULL_SLOT, sSrc, pDstItem, true);
234 if (msg != EQUIP_ERR_OK)
235 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, sSrc, pDstItem, true);
236 }
237 else if (_player->IsBankPos(src))
238 {
239 msg = _player->CanBankItem(packet.SourceBag, packet.SourceSlot, sSrc, pDstItem, true);
240 if (msg != EQUIP_ERR_OK)
241 msg = _player->CanBankItem(packet.SourceBag, NULL_SLOT, sSrc, pDstItem, true);
242 if (msg != EQUIP_ERR_OK)
243 msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, sSrc, pDstItem, true);
244 }
245 else if (_player->IsEquipmentPos(src))
246 {
247 msg = _player->CanEquipItem(packet.SourceSlot, eSrc, pDstItem, true);
248 if (msg == EQUIP_ERR_OK)
249 msg = _player->CanUnequipItem(eSrc, true);
250 }
251
252 if (msg != EQUIP_ERR_OK)
253 {
254 _player->SendEquipError(msg, pDstItem, pSrcItem);
255 return;
256 }
257
258 // now do moves, remove...
259 _player->RemoveItem(dstbag, dstslot, true);
260 _player->RemoveItem(packet.SourceBag, packet.SourceSlot, true);
261
262 // add to dest
263 _player->EquipItem(dest, pSrcItem, true);
264
265 // add to src
266 if (_player->IsInventoryPos(src))
267 _player->StoreItem(sSrc, pDstItem, true);
268 else if (_player->IsBankPos(src))
269 _player->BankItem(sSrc, pDstItem, true);
270 else if (_player->IsEquipmentPos(src))
271 _player->EquipItem(eSrc, pDstItem, true);
272
274
275 // Xinef: Call this here after all needed items are equipped
277 }
278}
@ EQUIP_ERR_ITEM_CANT_BE_EQUIPPED
Definition Item.h:67
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition Item.h:70
@ EQUIP_ERR_ITEMS_CANT_BE_SWAPPED
Definition Item.h:68
#define INVENTORY_SLOT_BAG_0
Definition Player.h:665
bool IsBag() const
Definition Item.h:254
static bool IsEquipmentPos(uint16 pos)
Definition Player.h:1264
InventoryResult CanUnequipItem(uint16 src, bool swap) const
Definition PlayerStorage.cpp:1991
void RemoveItemDependentAurasAndCasts(Item *pItem)
Definition Player.cpp:12622
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition PlayerStorage.cpp:1807
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition Player.h:1284
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition PlayerStorage.cpp:4306
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition PlayerStorage.cpp:2586
static bool IsInventoryPos(uint16 pos)
Definition Player.h:1262
uint8 FindEquipSlot(ItemTemplate const *proto, uint32 slot, bool swap) const
Definition PlayerStorage.cpp:127
void AutoUnequipOffhandIfNeed(bool force=false)
Definition Player.cpp:12505
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition PlayerStorage.cpp:2733
static bool IsBankPos(uint16 pos)
Definition Player.h:1267
uint8 SourceBag
Definition ItemPackets.h:85
uint8 SourceSlot
Definition ItemPackets.h:86

References _player, Player::ApplyEnchantment(), Player::AutoUnequipOffhandIfNeed(), Player::BankItem(), Player::CanBankItem(), Player::CanEquipItem(), Player::CanStoreItem(), Player::CanUnequipItem(), EQUIP_ERR_ITEM_CANT_BE_EQUIPPED, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_ITEMS_CANT_BE_SWAPPED, EQUIP_ERR_OK, Player::EquipItem(), Player::FindEquipSlot(), Item::GetBagSlot(), Player::GetItemByPos(), Item::GetPos(), Item::GetSlot(), Item::GetTemplate(), INVENTORY_SLOT_BAG_0, Item::IsBag(), Player::IsBankPos(), Player::IsEquipmentPos(), Player::IsInventoryPos(), NULL_BAG, NULL_SLOT, Player::RemoveItem(), Player::RemoveItemDependentAurasAndCasts(), Player::SendEquipError(), WorldPackets::Item::AutoEquipItem::SourceBag, WorldPackets::Item::AutoEquipItem::SourceSlot, and Player::StoreItem().

Referenced by OpcodeTable::Initialize().

◆ HandleAutoEquipItemSlotOpcode()

void WorldSession::HandleAutoEquipItemSlotOpcode ( WorldPackets::Item::AutoEquipItemSlot packet)
101{
102 // cheating attempt, client should never send opcode in that case
104 return;
105
106 Item* item = _player->GetItemByGuid(packet.ItemGuid);
107 uint16 dstpos = packet.DestinationSlot | (INVENTORY_SLOT_BAG_0 << 8);
108
109 if (!item || item->GetPos() == dstpos)
110 return;
111
112 _player->SwapItem(item->GetPos(), dstpos);
113}
void SwapItem(uint16 src, uint16 dst)
Definition PlayerStorage.cpp:3532
uint8 DestinationSlot
Definition ItemPackets.h:62
ObjectGuid ItemGuid
Definition ItemPackets.h:61

References _player, WorldPackets::Item::AutoEquipItemSlot::DestinationSlot, Player::GetItemByGuid(), Item::GetPos(), INVENTORY_SLOT_BAG_0, Player::IsEquipmentPos(), WorldPackets::Item::AutoEquipItemSlot::ItemGuid, and Player::SwapItem().

Referenced by OpcodeTable::Initialize().

◆ HandleAutoStoreBagItemOpcode()

void WorldSession::HandleAutoStoreBagItemOpcode ( WorldPackets::Item::AutoStoreBagItem packet)
963{
964 //LOG_DEBUG("network.opcode", "WORLD: CMSG_AUTOSTORE_BAG_ITEM");
965 Item* pItem = _player->GetItemByPos(packet.SourceBag, packet.SourceSlot);
966 if (!pItem)
967 return;
968
969 if (!_player->IsValidPos(packet.DestinationBag, NULL_SLOT, false)) // can be autostore pos
970 {
972 return;
973 }
974
975 uint16 src = pItem->GetPos();
976
977 // check unequip potability for equipped items and bank bags
978 if (_player->IsEquipmentPos (src) || _player->IsBagPos (src))
979 {
981 if (msg != EQUIP_ERR_OK)
982 {
983 _player->SendEquipError(msg, pItem, nullptr);
984 return;
985 }
986 }
987
988 ItemPosCountVec dest;
989 InventoryResult msg = _player->CanStoreItem(packet.DestinationBag, NULL_SLOT, dest, pItem, false);
990 if (msg != EQUIP_ERR_OK)
991 {
992 _player->SendEquipError(msg, pItem, nullptr);
993 return;
994 }
995
996 // no-op: placed in same slot
997 if (dest.size() == 1 && dest[0].pos == src)
998 {
999 // just remove grey item state
1000 _player->SendEquipError(EQUIP_ERR_NONE, pItem, nullptr);
1001 return;
1002 }
1003
1004 _player->RemoveItem(packet.SourceBag, packet.SourceSlot, true);
1005 _player->StoreItem(dest, pItem, true);
1007}
@ EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT
Definition Item.h:50
static bool IsBagPos(uint16 pos)
Definition PlayerStorage.cpp:592
bool IsValidPos(uint16 pos, bool explicit_pos)
Definition Player.h:1269
uint8 SourceBag
Definition ItemPackets.h:184
uint8 SourceSlot
Definition ItemPackets.h:185
uint8 DestinationBag
Definition ItemPackets.h:186

References _player, Player::CanStoreItem(), Player::CanUnequipItem(), WorldPackets::Item::AutoStoreBagItem::DestinationBag, EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, EQUIP_ERR_NONE, EQUIP_ERR_OK, Player::GetItemByPos(), Item::GetPos(), Player::IsBagPos(), Player::IsEquipmentPos(), Player::IsValidPos(), NULL_SLOT, Player::RemoveItem(), Player::SendEquipError(), WorldPackets::Item::AutoStoreBagItem::SourceBag, WorldPackets::Item::AutoStoreBagItem::SourceSlot, Player::StoreItem(), and Player::UpdateTitansGrip().

Referenced by OpcodeTable::Initialize().

◆ HandleAutoStoreBankItemOpcode()

void WorldSession::HandleAutoStoreBankItemOpcode ( WorldPackets::Bank::AutoStoreBankItem packet)
99{
100 LOG_DEBUG("network", "STORAGE: receive bag = {}, slot = {}", packet.Bag, packet.Slot);
101
102 if (!CanUseBank())
103 {
104 LOG_DEBUG("network", "WORLD: HandleAutoStoreBankItemOpcode - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
105 return;
106 }
107
108 Item* item = _player->GetItemByPos(packet.Bag, packet.Slot);
109 if (!item)
110 return;
111
112 if (_player->IsBankPos(packet.Bag, packet.Slot)) // moving from bank to inventory
113 {
114 ItemPosCountVec dest;
115 InventoryResult msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, item, false);
116 if (msg != EQUIP_ERR_OK)
117 {
118 _player->SendEquipError(msg, item, nullptr);
119 return;
120 }
121
122 _player->RemoveItem(packet.Bag, packet.Slot, true);
123 if (Item const* storedItem = _player->StoreItem(dest, item, true))
124 _player->ItemAddedQuestCheck(storedItem->GetEntry(), storedItem->GetCount());
125 }
126 else // moving from inventory to bank
127 {
128 ItemPosCountVec dest;
129 InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, item, false);
130 if (msg != EQUIP_ERR_OK)
131 {
132 _player->SendEquipError(msg, item, nullptr);
133 return;
134 }
135
136 _player->RemoveItem(packet.Bag, packet.Slot, true);
138 _player->BankItem(dest, item, true);
140 }
141}
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition PlayerQuest.cpp:1833
uint8 Bag
Definition BankPackets.h:46
uint8 Slot
Definition BankPackets.h:47

References _player, WorldPackets::Bank::AutoStoreBankItem::Bag, Player::BankItem(), Player::CanBankItem(), Player::CanStoreItem(), CanUseBank(), EQUIP_ERR_OK, Item::GetCount(), Object::GetEntry(), Player::GetItemByPos(), Player::IsBankPos(), Player::ItemAddedQuestCheck(), Player::ItemRemovedQuestCheck(), LOG_DEBUG, m_currentBankerGUID, NULL_BAG, NULL_SLOT, Player::RemoveItem(), Player::SendEquipError(), WorldPackets::Bank::AutoStoreBankItem::Slot, Player::StoreItem(), ObjectGuid::ToString(), and Player::UpdateTitansGrip().

Referenced by OpcodeTable::Initialize().

◆ HandleAutostoreLootItemOpcode()

void WorldSession::HandleAutostoreLootItemOpcode ( WorldPacket recvPacket)
34{
35 LOG_DEBUG("network", "WORLD: CMSG_AUTOSTORE_LOOT_ITEM");
36 Player* player = GetPlayer();
37 ObjectGuid lguid = player->GetLootGUID();
38 Loot* loot = nullptr;
39 uint8 lootSlot = 0;
40
41 recvData >> lootSlot;
42
43 if (lguid.IsGameObject())
44 {
45 GameObject* go = player->GetMap()->GetGameObject(lguid);
46 // xinef: cheating protection
47 //if (player->GetGroup() && player->GetGroup()->GetLootMethod() == MASTER_LOOT && player->GetGUID() != player->GetGroup()->GetMasterLooterGuid())
48 // go = nullptr;
49
50 // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO
51 if (!go || ((go->GetOwnerGUID() != _player->GetGUID() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player)))
52 {
53 player->SendLootRelease(lguid);
54 return;
55 }
56
57 loot = &go->loot;
58 }
59 else if (lguid.IsItem())
60 {
61 Item* pItem = player->GetItemByGuid(lguid);
62
63 if (!pItem)
64 {
65 player->SendLootRelease(lguid);
66 return;
67 }
68
69 loot = &pItem->loot;
70 }
71 else if (lguid.IsCorpse())
72 {
73 Corpse* bones = ObjectAccessor::GetCorpse(*player, lguid);
74 if (!bones)
75 {
76 player->SendLootRelease(lguid);
77 return;
78 }
79
80 loot = &bones->loot;
81 }
82 else
83 {
84 Creature* creature = GetPlayer()->GetMap()->GetCreature(lguid);
85
86 bool lootAllowed = creature && creature->IsAlive() == (player->IsClass(CLASS_ROGUE, CLASS_CONTEXT_ABILITY) && creature->loot.loot_type == LOOT_PICKPOCKETING);
87 if (!lootAllowed || !creature->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
88 {
89 player->SendLootError(lguid, lootAllowed ? LOOT_ERROR_TOO_FAR : LOOT_ERROR_DIDNT_KILL);
90 return;
91 }
92
93 loot = &creature->loot;
94 }
95
96 sScriptMgr->OnPlayerAfterCreatureLoot(player);
97
99 LootItem* lootItem = player->StoreLootItem(lootSlot, loot, msg);
100 if (msg != EQUIP_ERR_OK && lguid.IsItem() && loot->loot_type != LOOT_CORPSE)
101 {
102 lootItem->is_looted = true;
103 loot->NotifyItemRemoved(lootItem->itemIndex);
104 loot->unlootedCount--;
105
106 player->SendItemRetrievalMail(lootItem->itemid, lootItem->count);
107 }
108
109 // If player is removing the last LootItem, delete the empty container.
110 if (loot->isLooted() && lguid.IsItem())
111 DoLootRelease(lguid);
112}
@ LOOT_ERROR_TOO_FAR
Definition LootMgr.h:97
@ LOOT_ERROR_DIDNT_KILL
Definition LootMgr.h:96
@ LOOT_CORPSE
Definition LootMgr.h:80
void SendItemRetrievalMail(uint32 itemEntry, uint32 count)
Definition PlayerMisc.cpp:439
ObjectGuid GetLootGUID() const
Definition Player.h:1993
void SendLootError(ObjectGuid guid, LootError error)
Definition Player.cpp:8242
LootItem * StoreLootItem(uint8 lootSlot, Loot *loot, InventoryResult &msg)
Definition Player.cpp:13555
void DoLootRelease(ObjectGuid lguid)
Definition LootHandler.cpp:270
Definition LootMgr.h:154
uint32 itemid
Definition LootMgr.h:155
uint32 itemIndex
Definition LootMgr.h:156
uint8 count
Definition LootMgr.h:162
bool is_looted
Definition LootMgr.h:163
uint8 unlootedCount
Definition LootMgr.h:323
void NotifyItemRemoved(uint8 lootIndex)
Definition LootMgr.cpp:773

References _player, CLASS_CONTEXT_ABILITY, CLASS_ROGUE, LootItem::count, DoLootRelease(), EQUIP_ERR_OK, GAMEOBJECT_TYPE_FISHINGHOLE, ObjectAccessor::GetCorpse(), Map::GetCreature(), Map::GetGameObject(), GameObject::GetGoType(), Object::GetGUID(), Player::GetItemByGuid(), Player::GetLootGUID(), WorldObject::GetMap(), GameObject::GetOwnerGUID(), GetPlayer(), INTERACTION_DISTANCE, LootItem::is_looted, Unit::IsAlive(), Player::IsClass(), ObjectGuid::IsCorpse(), ObjectGuid::IsGameObject(), ObjectGuid::IsItem(), Loot::isLooted(), GameObject::IsWithinDistInMap(), WorldObject::IsWithinDistInMap(), LootItem::itemid, LootItem::itemIndex, LOG_DEBUG, Corpse::loot, Creature::loot, GameObject::loot, Item::loot, LOOT_CORPSE, LOOT_ERROR_DIDNT_KILL, LOOT_ERROR_TOO_FAR, LOOT_PICKPOCKETING, Loot::loot_type, Loot::NotifyItemRemoved(), Player::SendItemRetrievalMail(), Player::SendLootError(), Player::SendLootRelease(), sScriptMgr, Player::StoreLootItem(), and Loot::unlootedCount.

Referenced by OpcodeTable::Initialize().

◆ HandleBankerActivateOpcode()

void WorldSession::HandleBankerActivateOpcode ( WorldPacket recvData)
45{
46 ObjectGuid guid;
47
48 recvData >> guid;
49
51 if (!unit)
52 {
53 LOG_DEBUG("network", "WORLD: HandleBankerActivateOpcode - Unit ({}) not found or you can not interact with him.", guid.ToString());
54 return;
55 }
56
57 // remove fake death
58 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
60
61 SendShowBank(guid);
62}
void SendShowBank(ObjectGuid guid)
Definition BankHandler.cpp:188

References Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, Unit::RemoveAurasByType(), SendShowBank(), SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_BANKER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleBattlefieldLeaveOpcode()

void WorldSession::HandleBattlefieldLeaveOpcode ( WorldPacket recvData)
592{
593 LOG_DEBUG("network", "WORLD: Recvd CMSG_LEAVE_BATTLEFIELD Message");
594
595 recvData.read_skip<uint8>(); // unk1
596 recvData.read_skip<uint8>(); // unk2
597 recvData.read_skip<uint32>(); // BattlegroundTypeId
598 recvData.read_skip<uint16>(); // unk3
599
600 // not allow leave battleground in combat
601 if (_player->IsInCombat())
603 if (bg->GetStatus() != STATUS_WAIT_LEAVE)
604 return;
605
607}
@ STATUS_WAIT_LEAVE
Definition Battleground.h:194
void LeaveBattleground(Battleground *bg=nullptr)
Definition Player.cpp:11344
bool IsInCombat() const
Definition Unit.h:924

References _player, Player::GetBattleground(), Unit::IsInCombat(), Player::LeaveBattleground(), LOG_DEBUG, ByteBuffer::read_skip(), and STATUS_WAIT_LEAVE.

Referenced by OpcodeTable::Initialize().

◆ HandleBattlefieldListOpcode()

void WorldSession::HandleBattlefieldListOpcode ( WorldPacket recvData)
369{
370 LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEFIELD_LIST Message");
371
372 uint32 bgTypeId;
373 recvData >> bgTypeId; // id from DBC
374
375 uint8 fromWhere;
376 recvData >> fromWhere; // 0 - battlemaster (lua: ShowBattlefieldList), 1 - UI (lua: RequestBattlegroundInstanceInfo)
377
378 uint8 canGainXP;
379 recvData >> canGainXP; // players with locked xp have their own bg queue on retail
380
381 BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId);
382 if (!bl)
383 {
384 LOG_DEBUG("bg.battleground", "BattlegroundHandler: invalid bgtype ({}) with player (Name: {}, {}) received.", bgTypeId, _player->GetName(), _player->GetGUID().ToString());
385 return;
386 }
387
388 WorldPacket data;
389 sBattlegroundMgr->BuildBattlegroundListPacket(&data, ObjectGuid::Empty, _player, BattlegroundTypeId(bgTypeId), fromWhere);
390 SendPacket(&data);
391}
DBCStorage< BattlemasterListEntry > sBattlemasterListStore(BattlemasterListEntryfmt)
BattlegroundTypeId
Definition SharedDefines.h:3745
Definition DBCStructure.h:604

References _player, ObjectGuid::Empty, Object::GetGUID(), WorldObject::GetName(), LOG_DEBUG, sBattlegroundMgr, sBattlemasterListStore, SendPacket(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleBattleFieldPortOpcode()

void WorldSession::HandleBattleFieldPortOpcode ( WorldPacket recvData)
394{
395 uint8 arenaType; // arenatype if arena
396 uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1
397 uint32 bgTypeId_; // type id from dbc
398 uint16 unk; // 0x1F90 constant?
399 uint8 action; // enter battle 0x1, leave queue 0x0
400
401 recvData >> arenaType >> unk2 >> bgTypeId_ >> unk >> action;
402
403 // bgTypeId not valid
404 if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
405 {
406 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Invalid BgType!", GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
407 return;
408 }
409
410 // player not in any queue, so can't really answer
412 {
413 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Player not in queue!", GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
414 return;
415 }
416
418 {
420 return;
421 }
422
423 // get BattlegroundQueue for received
424 BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_);
425 BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenaType);
426 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
427
428 if (!sScriptMgr->OnPlayerCanBattleFieldPort(_player, arenaType, bgTypeId, action))
429 return;
430
431 // get group info from queue
432 GroupQueueInfo ginfo;
433 if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
434 {
435 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Player not in queue (No player Group Info)!",
436 GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
437 return;
438 }
439
440 // to accept, player must be invited to particular battleground id
441 if (!ginfo.IsInvitedToBGInstanceGUID && action == 1)
442 {
443 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Player is not invited to any bg!",
444 GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
445 return;
446 }
447
448 Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
449 if (!bg)
450 {
451 if (action)
452 {
453 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Cant find BG with id {}!",
454 GetPlayerInfo(), arenaType, unk2, bgTypeId_, action, ginfo.IsInvitedToBGInstanceGUID);
455 return;
456 }
457
458 bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
459 if (!bg)
460 {
461 LOG_ERROR("network", "BattlegroundHandler: bg_template not found for type id {}.", bgTypeId);
462 return;
463 }
464 }
465
466 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}.",
467 GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
468
469 // expected bracket entry
471 if (!bracketEntry)
472 return;
473
474 // safety checks
475 if (action == 1 && ginfo.ArenaType == 0)
476 {
477 // can't join with deserter, check it here right before joining to be sure
479 {
480 WorldPacket data;
481 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS);
482 SendPacket(&data);
483 action = 0;
484 LOG_DEBUG("bg.battleground", "Player {} {} has a deserter debuff, do not port him to battleground!", _player->GetName(), _player->GetGUID().ToString());
485 }
486
487 if (_player->GetLevel() > bg->GetMaxLevel())
488 {
489 LOG_ERROR("network", "Player {} {} has level ({}) higher than maxlevel ({}) of battleground ({})! Do not port him to battleground!",
491 action = 0;
492 }
493 }
494
495 // get player queue slot index for this bg (can be in up to 2 queues at the same time)
496 uint32 queueSlot = _player->GetBattlegroundQueueIndex(bgQueueTypeId);
497 WorldPacket data;
498
499 if (action) // accept
500 {
501 // check Freeze debuff
502 if (_player->HasAura(9454))
503 return;
504
505 if (!_player->IsInvitedForBattlegroundQueueType(bgQueueTypeId))
506 return; // cheating?
507
508 // set entry point if not in battleground
509 if (!_player->InBattleground())
511
512 // resurrect the player
513 if (!_player->IsAlive())
514 {
517 }
518
519 TeamId teamId = ginfo.teamId;
520
521 // send status packet
522 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType(), teamId);
523 SendPacket(&data);
524
525 // remove battleground queue status from BGmgr
526 bgQueue.RemovePlayer(_player->GetGUID(), false);
527
528 // this is still needed here if battleground "jumping" shouldn't add deserter debuff
529 // also this is required to prevent stuck at old battleground after SetBattlegroundId set to new
530 if (Battleground* currentBg = _player->GetBattleground())
531 currentBg->RemovePlayerAtLeave(_player);
532
533 for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
534 {
535 auto playerBgQueueTypeId = _player->GetBattlegroundQueueTypeId(i);
536 if (playerBgQueueTypeId != BATTLEGROUND_QUEUE_NONE && playerBgQueueTypeId != bgQueueTypeId)
537 {
538 _player->RemoveBattlegroundQueueId(playerBgQueueTypeId);
539 sBattlegroundMgr->GetBattlegroundQueue(playerBgQueueTypeId).RemovePlayer(_player->GetGUID(), true);
540 }
541 }
542
543 // Remove from LFG queues
544 sLFGMgr->LeaveAllLfgQueues(_player->GetGUID(), false);
545
546 _player->SetBattlegroundId(bg->GetInstanceID(), bg->GetBgTypeID(), queueSlot, true, bgTypeId == BATTLEGROUND_RB, teamId);
547 sBattlegroundMgr->SendToBattleground(_player, ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
548
549 LOG_DEBUG("bg.battleground", "Battleground: player {} {} joined battle for bg {}, bgtype {}, queue type {}.", _player->GetName(), _player->GetGUID().ToString(), bg->GetInstanceID(), bg->GetBgTypeID(), bgQueueTypeId);
550 }
551 else // leave queue
552 {
553 for (auto const& playerGuid : ginfo.Players)
554 {
555 auto player = ObjectAccessor::FindConnectedPlayer(playerGuid);
556 if (!player)
557 continue;
558
559 bgQueue.RemovePlayer(playerGuid, true);
560 player->RemoveBattlegroundQueueId(bgQueueTypeId);
561
562 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0, TEAM_NEUTRAL);
563 player->SendDirectMessage(&data);
564
565 LOG_DEBUG("bg.battleground", "Battleground: player {} {} left queue for bgtype {}, queue type {}.", player->GetName(), playerGuid.ToString(), bg->GetBgTypeID(), bgQueueTypeId);
566 }
567
568 // player left queue, we should update it - do not update Arena Queue
569 if (!ginfo.ArenaType)
570 sBattlegroundMgr->ScheduleQueueUpdate(ginfo.ArenaMatchmakerRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
571
572 // track if player refuses to join the BG after being invited
573 if (bg->isBattleground() && (bg->GetStatus() == STATUS_IN_PROGRESS || bg->GetStatus() == STATUS_WAIT_JOIN))
574 {
576 {
578 stmt->SetData(0, _player->GetGUID().GetCounter());
580 CharacterDatabase.Execute(stmt);
581 }
582
583 sScriptMgr->OnPlayerBattlegroundDesertion(_player, BG_DESERTION_TYPE_LEAVE_QUEUE);
584 }
585
586 if (bg->isArena() && (bg->GetStatus() == STATUS_IN_PROGRESS || bg->GetStatus() == STATUS_WAIT_JOIN))
587 sScriptMgr->OnPlayerBattlegroundDesertion(_player, ARENA_DESERTION_TYPE_LEAVE_QUEUE);
588 }
589}
@ ARENA_DESERTION_TYPE_LEAVE_QUEUE
Definition Battleground.h:58
@ BG_DESERTION_TYPE_LEAVE_QUEUE
Definition Battleground.h:54
@ STATUS_NONE
Definition Battleground.h:190
@ STATUS_WAIT_JOIN
Definition Battleground.h:192
@ CHAR_INS_DESERTER_TRACK
Definition CharacterDatabase.h:501
PvPDifficultyEntry const * GetBattlegroundBracketByLevel(uint32 mapid, uint32 level)
Definition DBCStores.cpp:793
#define sLFGMgr
Definition LFGMgr.h:643
@ LANG_YOU_IN_COMBAT
Definition Language.h:55
@ ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS
Definition SharedDefines.h:3905
@ BATTLEGROUND_RB
Definition SharedDefines.h:3759
@ BATTLEGROUND_QUEUE_NONE
Definition SharedDefines.h:3886
@ TEAM_NEUTRAL
Definition SharedDefines.h:773
#define PLAYER_MAX_BATTLEGROUND_QUEUES
Definition SharedDefines.h:176
@ CONFIG_BATTLEGROUND_TRACK_DESERTERS
Definition WorldConfig.h:75
void RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
Definition BattlegroundQueue.cpp:261
uint32 GetMapId() const
Definition Battleground.h:436
uint8 GetArenaType() const
Definition Battleground.h:348
uint32 GetInstanceID() const
Definition Battleground.h:322
bool isArena() const
Definition Battleground.h:404
uint32 GetStartTime() const
Definition Battleground.h:325
bool isBattleground() const
Definition Battleground.h:405
BattlegroundStatus GetStatus() const
Definition Battleground.h:323
uint32 GetMaxLevel() const
Definition Battleground.h:330
BattlegroundTypeId GetBgTypeID(bool GetRandom=false) const
Definition Battleground.h:320
bool IsInvitedForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
Definition Player.cpp:12272
void SetEntryPoint()
Definition Player.cpp:11307
bool InBattleground() const
Definition Player.h:2266
bool InBattlegroundQueue(bool ignoreArena=false) const
Definition Player.cpp:12247
void SetBattlegroundId(uint32 id, BattlegroundTypeId bgTypeId, uint32 queueSlot, bool invited, bool isRandom, TeamId teamId)
Definition Player.cpp:12348
void RemoveBattlegroundQueueId(BattlegroundQueueTypeId val)
Definition Player.cpp:12310
bool CanJoinToBattleground() const
Definition Player.cpp:11382
uint32 GetBattlegroundQueueIndex(BattlegroundQueueTypeId bgQueueTypeId) const
Definition Player.cpp:12263
BattlegroundQueueTypeId GetBattlegroundQueueTypeId(uint32 index) const
Definition Player.cpp:12258
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:5840
ObjectGuid GetCharmGUID() const
Definition Unit.h:711
TeamId teamId
Definition BattlegroundQueue.h:33
uint8 ArenaType
Definition BattlegroundQueue.h:37
uint32 ArenaMatchmakerRating
Definition BattlegroundQueue.h:43
Definition DBCStructure.h:1429
BattlegroundBracketId GetBracketId() const
Definition DBCStructure.h:1439

References _player, ARENA_DESERTION_TYPE_LEAVE_QUEUE, GroupQueueInfo::ArenaMatchmakerRating, GroupQueueInfo::ArenaType, BATTLEGROUND_QUEUE_NONE, BATTLEGROUND_RB, BG_DESERTION_TYPE_LEAVE_QUEUE, BattlegroundMgr::BGQueueTypeId(), Player::CanJoinToBattleground(), CHAR_INS_DESERTER_TRACK, CharacterDatabase, CONFIG_BATTLEGROUND_TRACK_DESERTERS, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS, ObjectAccessor::FindConnectedPlayer(), Battleground::GetArenaType(), Player::GetBattleground(), GetBattlegroundBracketByLevel(), Player::GetBattlegroundQueueIndex(), Player::GetBattlegroundQueueTypeId(), Battleground::GetBgTypeID(), PvPDifficultyEntry::GetBracketId(), Unit::GetCharmGUID(), ObjectGuid::GetCounter(), Object::GetGUID(), Battleground::GetInstanceID(), Unit::GetLevel(), Battleground::GetMapId(), Battleground::GetMaxLevel(), WorldObject::GetName(), BattlegroundQueue::GetPlayerGroupInfoData(), GetPlayerInfo(), Player::GetSession(), Battleground::GetStartTime(), Battleground::GetStatus(), Unit::HasAura(), Player::InBattleground(), Player::InBattlegroundQueue(), Unit::IsAlive(), Battleground::isArena(), Battleground::isBattleground(), Unit::IsInCombat(), Player::IsInvitedForBattlegroundQueueType(), GroupQueueInfo::IsInvitedToBGInstanceGUID, LANG_YOU_IN_COMBAT, LOG_DEBUG, LOG_ERROR, PLAYER_MAX_BATTLEGROUND_QUEUES, GroupQueueInfo::Players, Player::RemoveBattlegroundQueueId(), BattlegroundQueue::RemovePlayer(), Player::ResurrectPlayer(), sBattlegroundMgr, sBattlemasterListStore, ChatHandler::SendNotification(), SendPacket(), Player::SetBattlegroundId(), PreparedStatementBase::SetData(), Player::SetEntryPoint(), sLFGMgr, Player::SpawnCorpseBones(), sScriptMgr, STATUS_IN_PROGRESS, STATUS_NONE, STATUS_WAIT_JOIN, sWorld, TEAM_NEUTRAL, GroupQueueInfo::teamId, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleBattlefieldStatusOpcode()

void WorldSession::HandleBattlefieldStatusOpcode ( WorldPacket recvData)
610{
611 // requested at login and on map change
612 // send status for current queues and current bg
613
614 WorldPacket data;
615
616 // for current bg send STATUS_IN_PROGRESS
618 if (bg->GetPlayers().count(_player->GetGUID()))
619 {
620 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player->GetCurrentBattlegroundQueueSlot(), STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), bg->GetArenaType(), _player->GetBgTeamId());
621 SendPacket(&data);
622 }
623
624 // for queued bgs send STATUS_WAIT_JOIN or STATUS_WAIT_QUEUE
625 for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
626 {
627 // check if in queue
629 if (!bgQueueTypeId)
630 continue;
631
632 // get group info from queue
633 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
634 GroupQueueInfo ginfo;
635 if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
636 continue;
637
638 BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(bgQueueTypeId);
639
640 // if invited - send STATUS_WAIT_JOIN
642 {
643 Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
644 if (!bg)
645 continue;
646
647 uint32 remainingTime = (GameTime::GetGameTimeMS().count() < ginfo.RemoveInviteTime ? getMSTimeDiff(GameTime::GetGameTimeMS().count(), ginfo.RemoveInviteTime) : 1);
648 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_WAIT_JOIN, remainingTime, 0, ginfo.ArenaType, TEAM_NEUTRAL, bg->isRated(), ginfo.BgTypeId);
649 SendPacket(&data);
650 }
651 // if not invited - send STATUS_WAIT_QUEUE
652 else
653 {
654 Battleground* bgt = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
655 if (!bgt)
656 continue;
657
658 // expected bracket entry
660 if (!bracketEntry)
661 continue;
662
663 uint32 avgWaitTime = bgQueue.GetAverageQueueWaitTime(&ginfo);
664 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, i, STATUS_WAIT_QUEUE, avgWaitTime, getMSTimeDiff(ginfo.JoinTime, GameTime::GetGameTimeMS().count()), ginfo.ArenaType, TEAM_NEUTRAL, ginfo.IsRated);
665 SendPacket(&data);
666 }
667 }
668}
@ STATUS_WAIT_QUEUE
Definition Battleground.h:191
uint32 getMSTimeDiff(uint32 oldMSTime, uint32 newMSTime)
Definition Timer.h:110
static BattlegroundTypeId BGTemplateId(BattlegroundQueueTypeId bgQueueTypeId)
Definition BattlegroundMgr.cpp:710
uint32 GetAverageQueueWaitTime(GroupQueueInfo *ginfo) const
Definition BattlegroundQueue.cpp:235
bool isRated() const
Definition Battleground.h:406
uint32 GetCurrentBattlegroundQueueSlot() const
Definition Player.h:2270
TeamId GetBgTeamId() const
Definition Player.h:2292
Milliseconds GetGameTimeMS()
Definition GameTime.cpp:43
uint32 JoinTime
Definition BattlegroundQueue.h:39
BattlegroundTypeId BgTypeId
Definition BattlegroundQueue.h:35
uint32 RemoveInviteTime
Definition BattlegroundQueue.h:40
bool IsRated
Definition BattlegroundQueue.h:36

References _player, GroupQueueInfo::ArenaType, BattlegroundMgr::BGTemplateId(), GroupQueueInfo::BgTypeId, BattlegroundQueue::GetAverageQueueWaitTime(), Player::GetBattleground(), GetBattlegroundBracketByLevel(), Player::GetBattlegroundQueueTypeId(), Player::GetBgTeamId(), Player::GetCurrentBattlegroundQueueSlot(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::GetLevel(), Battleground::GetMapId(), getMSTimeDiff(), BattlegroundQueue::GetPlayerGroupInfoData(), GroupQueueInfo::IsInvitedToBGInstanceGUID, Battleground::isRated(), GroupQueueInfo::IsRated, GroupQueueInfo::JoinTime, PLAYER_MAX_BATTLEGROUND_QUEUES, GroupQueueInfo::RemoveInviteTime, sBattlegroundMgr, SendPacket(), STATUS_IN_PROGRESS, STATUS_WAIT_JOIN, STATUS_WAIT_QUEUE, and TEAM_NEUTRAL.

Referenced by OpcodeTable::Initialize().

◆ HandleBattlegroundPlayerPositionsOpcode()

void WorldSession::HandleBattlegroundPlayerPositionsOpcode ( WorldPacket recvData)
299{
300 LOG_DEBUG("network", "WORLD: Recvd MSG_BATTLEGROUND_PLAYER_POSITIONS Message");
301
303 if (!bg) // can't be received if player not in battleground
304 return;
305
306 uint32 flagCarrierCount = 0;
307 Player* allianceFlagCarrier = nullptr;
308 Player* hordeFlagCarrier = nullptr;
309
311 {
312 allianceFlagCarrier = ObjectAccessor::FindPlayer(guid);
313 if (allianceFlagCarrier)
314 ++flagCarrierCount;
315 }
316
318 {
319 hordeFlagCarrier = ObjectAccessor::FindPlayer(guid);
320 if (hordeFlagCarrier)
321 ++flagCarrierCount;
322 }
323
324 WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, 4 + 4 + 16 * flagCarrierCount);
325 // Used to send several player positions (found used in AV)
326 data << 0; // CGBattlefieldInfo__m_numPlayerPositions
327 /*
328 for (CGBattlefieldInfo__m_numPlayerPositions)
329 data << guid << posx << posy;
330 */
331 data << flagCarrierCount;
332 if (allianceFlagCarrier)
333 {
334 data << allianceFlagCarrier->GetGUID();
335 data << float(allianceFlagCarrier->GetPositionX());
336 data << float(allianceFlagCarrier->GetPositionY());
337 }
338
339 if (hordeFlagCarrier)
340 {
341 data << hordeFlagCarrier->GetGUID();
342 data << float(hordeFlagCarrier->GetPositionX());
343 data << float(hordeFlagCarrier->GetPositionY());
344 }
345
346 SendPacket(&data);
347}
@ TEAM_HORDE
Definition SharedDefines.h:772
virtual ObjectGuid GetFlagPickerGUID(TeamId=TEAM_NEUTRAL) const
Definition Battleground.h:564
@ MSG_BATTLEGROUND_PLAYER_POSITIONS
Definition Opcodes.h:775
Player * FindPlayer(ObjectGuid const guid)
Definition ObjectAccessor.cpp:245

References _player, ObjectAccessor::FindPlayer(), Player::GetBattleground(), Battleground::GetFlagPickerGUID(), Object::GetGUID(), Position::GetPositionX(), Position::GetPositionY(), LOG_DEBUG, MSG_BATTLEGROUND_PLAYER_POSITIONS, SendPacket(), TEAM_ALLIANCE, and TEAM_HORDE.

Referenced by OpcodeTable::Initialize().

◆ HandleBattlemasterHelloOpcode()

void WorldSession::HandleBattlemasterHelloOpcode ( WorldPacket recvData)
38{
39 ObjectGuid guid;
40 recvData >> guid;
41 LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEMASTER_HELLO Message from ({})", guid.ToString());
42
43 Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
44 if (!unit)
45 return;
46
47 if (!unit->IsBattleMaster()) // it's not battlemaster
48 return;
49
50 // Stop the npc if moving
52 unit->PauseMovement(pause);
53 unit->SetHomePosition(unit->GetPosition());
54
55 BattlegroundTypeId bgTypeId = sBattlegroundMgr->GetBattleMasterBG(unit->GetEntry());
56
57 if (!_player->GetBGAccessByLevel(bgTypeId))
58 {
59 // temp, must be gossip message...
61 return;
62 }
63
64 SendBattleGroundList(guid, bgTypeId);
65}
@ LANG_YOUR_BG_LEVEL_REQ_ERROR
Definition Language.h:692
void SetHomePosition(float x, float y, float z, float o)
Definition Creature.h:339
CreatureMovementData const & GetMovementTemplate() const
Definition Creature.cpp:2994
bool GetBGAccessByLevel(BattlegroundTypeId bgTypeId) const
Definition Player.cpp:12360
bool IsBattleMaster() const
Definition Unit.h:799
virtual void PauseMovement(uint32 timer=0, uint8 slot=0)
Disable the unit movement by clearing UNIT_STATE_MOVING and stopping the spline.
Definition Unit.cpp:16885
void SendBattleGroundList(ObjectGuid guid, BattlegroundTypeId bgTypeId=BATTLEGROUND_RB)
Definition BattleGroundHandler.cpp:67
uint32 GetInteractionPauseTimer() const
Definition CreatureData.h:160
void GetPosition(float &x, float &y) const
Definition Position.h:126

References _player, Player::GetBGAccessByLevel(), Map::GetCreature(), Object::GetEntry(), CreatureMovementData::GetInteractionPauseTimer(), WorldObject::GetMap(), Creature::GetMovementTemplate(), GetPlayer(), Position::GetPosition(), Unit::IsBattleMaster(), LANG_YOUR_BG_LEVEL_REQ_ERROR, LOG_DEBUG, Unit::PauseMovement(), sBattlegroundMgr, SendBattleGroundList(), ChatHandler::SendNotification(), Creature::SetHomePosition(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleBattlemasterJoinArena()

void WorldSession::HandleBattlemasterJoinArena ( WorldPacket recvData)
671{
672 LOG_DEBUG("network", "WORLD: CMSG_BATTLEMASTER_JOIN_ARENA");
673
674 ObjectGuid guid; // arena Battlemaster guid
675 uint8 arenaslot; // 2v2, 3v3 or 5v5
676 uint8 asGroup; // asGroup
677 uint8 isRated; // isRated
678
679 recvData >> guid >> arenaslot >> asGroup >> isRated;
680
681 // can't queue for rated without a group
682 if (isRated && !asGroup)
683 return;
684
685 // ignore if we already in BG or BG queue
686 if (_player->InBattleground())
687 return;
688
689 // find creature by guid
690 Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
691 if (!unit || !unit->IsBattleMaster())
692 return;
693
694 // get arena type
695 uint8 arenatype = 0;
696 uint32 ateamId = 0;
697 uint32 arenaRating = 0;
698 uint32 matchmakerRating = 0;
699 uint32 previousOpponents = 0;
700
701 switch (arenaslot)
702 {
703 case 0:
704 arenatype = ARENA_TYPE_2v2;
705 break;
706 case 1:
707 arenatype = ARENA_TYPE_3v3;
708 break;
709 case 2:
710 arenatype = ARENA_TYPE_5v5;
711 break;
712 default:
713 LOG_ERROR("network", "Unknown arena slot {} at HandleBattlemasterJoinArena()", arenaslot);
714 return;
715 }
716
717 // get template for all arenas
718 Battleground* bgt = sBattlegroundMgr->GetBattlegroundTemplate(BATTLEGROUND_AA);
719 if (!bgt)
720 {
721 LOG_ERROR("network", "Battleground: template bg (all arenas) not found");
722 return;
723 }
724
725 // arenas disabled
726 if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, BATTLEGROUND_AA, nullptr))
727 {
729 return;
730 }
731
732 BattlegroundTypeId bgTypeId = bgt->GetBgTypeID();
733
734 // expected bracket entry
736 if (!bracketEntry)
737 return;
738
739 // must have free queue slot
740 // pussywizard: allow being queued only in one arena queue, and it even cannot be together with bg queues
742 {
743 WorldPacket data;
744 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_CANNOT_QUEUE_FOR_RATED);
745 SendPacket(&data);
746 return;
747 }
748
749 // queue result (default ok)
751
752 if (!sScriptMgr->OnPlayerCanJoinInArenaQueue(_player, guid, arenaslot, bgTypeId, asGroup, isRated, err) && err <= 0)
753 {
754 WorldPacket data;
755 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
756 SendPacket(&data);
757 return;
758 }
759
760 BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenatype);
761 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
762
763 // check if player can queue:
764 if (!asGroup)
765 {
766 lfg::LfgState lfgState = sLFGMgr->GetState(GetPlayer()->GetGUID());
767 if (GetPlayer()->InBattleground()) // currently in battleground
768 {
770 }
771 else if (lfgState > lfg::LFG_STATE_NONE && (lfgState != lfg::LFG_STATE_QUEUED || !sWorld->getBoolConfig(CONFIG_ALLOW_JOIN_BG_AND_LFG))) // using lfg system
772 {
774 }
775
776 if (err <= 0)
777 {
778 WorldPacket data;
779 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
780 SendPacket(&data);
781 return;
782 }
783
784 // check if already in queue
786 //player is already in this queue
787 return;
788
789 // check if has free queue slots
791 return;
792
793 GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bgTypeId, bracketEntry, arenatype, isRated != 0, false, arenaRating, matchmakerRating, ateamId, previousOpponents);
794 uint32 avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo);
795 uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId);
796
797 WorldPacket data;
798 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, arenatype, TEAM_NEUTRAL);
799 SendPacket(&data);
800
801 LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena, skirmish, bg queue type {} bg type {}: {}, NAME {}", bgQueueTypeId, bgTypeId, _player->GetGUID().ToString(), _player->GetName());
802
803 sScriptMgr->OnPlayerJoinArena(_player);
804 }
805 // check if group can queue:
806 else
807 {
808 Group* grp = _player->GetGroup();
809 // no group or not a leader
810 if (!grp || grp->GetLeaderGUID() != _player->GetGUID())
811 return;
812
813 // additional checks for rated arenas
814 if (isRated)
815 {
816 // pussywizard: for rated matches check if season is in progress!
817 if (sArenaSeasonMgr->GetSeasonState() == ARENA_SEASON_STATE_DISABLED)
818 return;
819
820 ateamId = _player->GetArenaTeamId(arenaslot);
821
822 // check team existence
823 ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(ateamId);
824 if (!at)
825 {
826 SendNotInArenaTeamPacket(arenatype);
827 return;
828 }
829
830 // get team rating for queueing
831 arenaRating = at->GetRating();
832 matchmakerRating = at->GetAverageMMR(grp);
833 if (arenaRating <= 0)
834 arenaRating = 1;
835
836 previousOpponents = at->GetPreviousOpponents();
837 }
838
839 err = grp->CanJoinBattlegroundQueue(bgt, bgQueueTypeId, arenatype, arenatype, (bool)isRated, arenaslot);
840
841 // Check queue group members
842 if (err)
843 {
844 grp->DoForAllMembers([&bgQueue, &err](Player* member)
845 {
846 if (bgQueue.IsPlayerInvitedToRatedArena(member->GetGUID()))
847 {
848 err = ERR_BATTLEGROUND_JOIN_FAILED;
849 }
850 });
851 }
852
853 uint32 avgWaitTime = 0;
854 if (err > 0)
855 {
856 LOG_DEBUG("bg.battleground", "Battleground: arena join as group start");
857
858 if (isRated)
859 {
860 LOG_DEBUG("bg.battleground", "Battleground: arena team id {}, leader {} queued with matchmaker rating {} for type {}", _player->GetArenaTeamId(arenaslot), _player->GetName(), matchmakerRating, arenatype);
861 bgt->SetRated(true);
862 }
863 else
864 {
865 bgt->SetRated(false);
866 }
867
868 GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, arenatype, isRated != 0, false, arenaRating, matchmakerRating, ateamId, previousOpponents);
869 avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo);
870 }
871
872 WorldPacket data;
873 for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next())
874 {
875 Player* member = itr->GetSource();
876 if (!member)
877 continue;
878
879 if (err <= 0)
880 {
881 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
882 member->SendDirectMessage(&data);
883 continue;
884 }
885
886 uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId);
887
888 // send status packet
889 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, arenatype, TEAM_NEUTRAL, isRated);
890 member->SendDirectMessage(&data);
891
892 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
893 member->SendDirectMessage(&data);
894
895 LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena as group bg queue type {} bg type {}: {}, NAME {}", bgQueueTypeId, bgTypeId, member->GetGUID().ToString(), member->GetName());
896
897 sScriptMgr->OnPlayerJoinArena(member);
898 }
899 }
900
901 sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
902}
@ ARENA_SEASON_STATE_DISABLED
Definition ArenaSeasonMgr.h:28
#define sArenaSeasonMgr
Definition ArenaSeasonMgr.h:124
@ ARENA_TYPE_5v5
Definition Battleground.h:210
@ ARENA_TYPE_3v3
Definition Battleground.h:209
@ ARENA_TYPE_2v2
Definition Battleground.h:208
#define sDisableMgr
Definition DisableMgr.h:88
@ DISABLE_TYPE_BATTLEGROUND
Definition DisableMgr.h:31
@ LANG_ARENA_DISABLED
Definition Language.h:725
GroupJoinBattlegroundResult
Definition SharedDefines.h:3901
@ ERR_BATTLEGROUND_CANNOT_QUEUE_FOR_RATED
Definition SharedDefines.h:3908
@ ERR_LFG_CANT_USE_BATTLEGROUND
Definition SharedDefines.h:3916
@ ERR_BATTLEGROUND_NOT_IN_BATTLEGROUND
Definition SharedDefines.h:3911
@ CONFIG_ALLOW_JOIN_BG_AND_LFG
Definition WorldConfig.h:131
uint32 GetPreviousOpponents()
Definition ArenaTeam.h:212
uint32 GetRating() const
Definition ArenaTeam.h:158
uint32 GetAverageMMR(Group *group) const
Definition ArenaTeam.cpp:685
bool IsPlayerInvitedToRatedArena(ObjectGuid pl_guid)
Definition BattlegroundQueue.cpp:372
GroupQueueInfo * AddGroup(Player *leader, Group *group, BattlegroundTypeId bgTypeId, PvPDifficultyEntry const *bracketEntry, uint8 arenaType, bool isRated, bool isPremade, uint32 arenaRating, uint32 matchmakerRating, uint32 arenaTeamId=0, uint32 opponentsArenaTeamId=0)
Definition BattlegroundQueue.cpp:134
void SetRated(bool state)
Definition Battleground.h:370
Definition GroupReference.h:27
GroupJoinBattlegroundResult CanJoinBattlegroundQueue(Battleground const *bgTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot)
Definition Group.cpp:1930
GroupReference * GetFirstMember()
Definition Group.h:243
void DoForAllMembers(std::function< void(Player *)> const &worker)
Definition Group.cpp:2553
ObjectGuid GetLeaderGUID() const
Definition Group.cpp:2306
bool HasFreeBattlegroundQueueId() const
Definition Player.cpp:12301
uint32 AddBattlegroundQueueId(BattlegroundQueueTypeId val)
Definition Player.cpp:12286
void SendNotInArenaTeamPacket(uint8 type)
Definition ArenaTeamHandler.cpp:416
LfgState
Definition LFG.h:67
@ LFG_STATE_NONE
Definition LFG.h:68
@ LFG_STATE_QUEUED
Definition LFG.h:70

References _player, Player::AddBattlegroundQueueId(), BattlegroundQueue::AddGroup(), ARENA_SEASON_STATE_DISABLED, ARENA_TYPE_2v2, ARENA_TYPE_3v3, ARENA_TYPE_5v5, BATTLEGROUND_AA, BattlegroundMgr::BGQueueTypeId(), Group::CanJoinBattlegroundQueue(), CONFIG_ALLOW_JOIN_BG_AND_LFG, DISABLE_TYPE_BATTLEGROUND, Group::DoForAllMembers(), ERR_BATTLEGROUND_CANNOT_QUEUE_FOR_RATED, ERR_BATTLEGROUND_NOT_IN_BATTLEGROUND, ERR_LFG_CANT_USE_BATTLEGROUND, Player::GetArenaTeamId(), ArenaTeam::GetAverageMMR(), BattlegroundQueue::GetAverageQueueWaitTime(), GetBattlegroundBracketByLevel(), Player::GetBattlegroundQueueIndex(), Battleground::GetBgTypeID(), PvPDifficultyEntry::GetBracketId(), Map::GetCreature(), Group::GetFirstMember(), Player::GetGroup(), Object::GetGUID(), Group::GetLeaderGUID(), Unit::GetLevel(), WorldObject::GetMap(), Battleground::GetMapId(), WorldObject::GetName(), GetPlayer(), ArenaTeam::GetPreviousOpponents(), ArenaTeam::GetRating(), Player::HasFreeBattlegroundQueueId(), Player::InBattleground(), Player::InBattlegroundQueue(), Unit::IsBattleMaster(), BattlegroundQueue::IsPlayerInvitedToRatedArena(), LANG_ARENA_DISABLED, lfg::LFG_STATE_NONE, lfg::LFG_STATE_QUEUED, LOG_DEBUG, LOG_ERROR, PLAYER_MAX_BATTLEGROUND_QUEUES, ChatHandler::PSendSysMessage(), sArenaSeasonMgr, sArenaTeamMgr, sBattlegroundMgr, sDisableMgr, Player::SendDirectMessage(), SendNotInArenaTeamPacket(), SendPacket(), Battleground::SetRated(), sLFGMgr, sScriptMgr, STATUS_WAIT_QUEUE, sWorld, TEAM_NEUTRAL, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleBattlemasterJoinOpcode()

void WorldSession::HandleBattlemasterJoinOpcode ( WorldPacket recvData)
75{
76 ObjectGuid guid;
77 uint32 bgTypeId_;
78 uint32 instanceId;
79 uint8 joinAsGroup;
80 bool isPremade = false;
81
82 recvData >> guid; // battlemaster guid
83 recvData >> bgTypeId_; // battleground type id (DBC id)
84 recvData >> instanceId; // instance id, 0 if First Available selected
85 recvData >> joinAsGroup; // join as group
86
87 // entry not found
88 if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
89 {
90 LOG_ERROR("network", "Battleground: invalid bgtype ({}) received. possible cheater? player {}", bgTypeId_, _player->GetGUID().ToString());
91 return;
92 }
93
94 // chosen battleground type is disabled
95 if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId_, nullptr))
96 {
98 return;
99 }
100
101 LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from {}", guid.ToString());
102
103 // get queue typeid and random typeid to check if already queued for them
104 BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_);
105 BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, 0);
107
108 // safety check - bgQueueTypeId == BATTLEGROUND_QUEUE_NONE if tried to queue for arena using this function
109 if (bgQueueTypeId == BATTLEGROUND_QUEUE_NONE)
110 return;
111
112 // ignore if player is already in BG
113 if (_player->InBattleground())
114 return;
115
116 // get bg instance or bg template if instance not found
117 Battleground* bg = nullptr;
118 if (instanceId)
119 bg = sBattlegroundMgr->GetBattlegroundThroughClientInstance(instanceId, bgTypeId);
120
121 if (!bg)
122 bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
123
124 if (!bg)
125 return;
126
127 // expected bracket entry
129 if (!bracketEntry)
130 return;
131
132 // must have free queue slot
134 {
135 WorldPacket data;
136 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_TOO_MANY_QUEUES);
137 SendPacket(&data);
138 return;
139 }
140
141 // queue result (default ok)
143
144 if (!sScriptMgr->OnPlayerCanJoinInBattlegroundQueue(_player, guid, bgTypeId, joinAsGroup, err) && err <= 0)
145 {
146 WorldPacket data;
147 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
148 SendPacket(&data);
149 return;
150 }
151
152 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
153
154 // check if player can queue:
155 if (!joinAsGroup)
156 {
157 lfg::LfgState lfgState = sLFGMgr->GetState(GetPlayer()->GetGUID());
158 if (GetPlayer()->InBattleground()) // currently in battleground
159 {
161 }
162 else if (lfgState > lfg::LFG_STATE_NONE && (lfgState != lfg::LFG_STATE_QUEUED || !sWorld->getBoolConfig(CONFIG_ALLOW_JOIN_BG_AND_LFG))) // using lfg system
163 {
165 }
166 else if (!_player->CanJoinToBattleground()) // has deserter debuff
167 {
169 }
170 else if (_player->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeIdRandom)) // queued for random bg, so can't queue for anything else
171 {
172 err = ERR_IN_RANDOM_BG;
173 }
174 else if (_player->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeId)) // queued for this bg
175 {
177 }
178 else if (_player->InBattlegroundQueue() && bgTypeId == BATTLEGROUND_RB) // already in queue, so can't queue for random
179 {
181 }
184 _player->InBattlegroundQueueForBattlegroundQueueType(BATTLEGROUND_QUEUE_5v5)) // can't be already queued for arenas
185 {
187 }
188 // don't let Death Knights join BG queues when they are not allowed to be teleported yet
190 {
192 }
193 else if (!_player->GetBGAccessByLevel(bgTypeId))
194 {
196 }
197
198 if (err <= 0)
199 {
200 WorldPacket data;
201 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
202 SendPacket(&data);
203 return;
204 }
205
206 GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0);
207 uint32 avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo);
208 uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId);
209
210 // send status packet
211 WorldPacket data;
212 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, 0, TEAM_NEUTRAL);
213 SendPacket(&data);
214
215 sScriptMgr->OnPlayerJoinBG(_player);
216 }
217 // check if group can queue:
218 else
219 {
220 Group* grp = _player->GetGroup();
221
222 // no group or not a leader
223 if (!grp || grp->GetLeaderGUID() != _player->GetGUID())
224 return;
225
226 grp->DoForAllMembers([&err, bgQueueTypeId, bgQueueTypeIdRandom, bgTypeId](Player* member)
227 {
228 if (member->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeIdRandom)) // queued for random bg, so can't queue for anything else
229 {
230 err = ERR_IN_RANDOM_BG;
231 }
232 else if (member->InBattlegroundQueue() && bgTypeId == BATTLEGROUND_RB) // already in queue, so can't queue for random
233 {
234 err = ERR_IN_NON_RANDOM_BG;
235 }
238 member->InBattlegroundQueueForBattlegroundQueueType(BATTLEGROUND_QUEUE_5v5)) // can't be already queued for arenas
239 {
240 err = ERR_BATTLEGROUND_QUEUED_FOR_RATED;
241 }
242 else if (member->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeId)) // queued for this bg
243 {
244 err = ERR_BATTLEGROUND_NONE;
245 }
246 else if (!member->GetBGAccessByLevel(bgTypeId))
247 {
248 err = ERR_BATTLEGROUND_JOIN_TIMED_OUT;
249 }
250
251 if (err < 0)
252 {
253 return;
254 }
255 });
256
257 if (err)
258 {
259 err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0);
260 }
261
262 if (err <= 0)
263 {
264 grp->DoForAllMembers([err](Player* member)
265 {
266 WorldPacket data;
267 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
268 member->SendDirectMessage(&data);
269 });
270
271 return;
272 }
273
274 isPremade = (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam() && bgTypeId != BATTLEGROUND_RB);
275 uint32 avgWaitTime = 0;
276
277 GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0);
278 avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo);
279
280 grp->DoForAllMembers([bg, err, bgQueueTypeId, avgWaitTime](Player* member)
281 {
282 WorldPacket data;
283
284 // send status packet
285 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, member->AddBattlegroundQueueId(bgQueueTypeId), STATUS_WAIT_QUEUE, avgWaitTime, 0, 0, TEAM_NEUTRAL);
286 member->SendDirectMessage(&data);
287
288 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
289 member->SendDirectMessage(&data);
290
291 sScriptMgr->OnPlayerJoinBG(member);
292 });
293 }
294
295 sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
296}
@ MAP_EBON_HOLD
Definition AreaDefines.h:259
@ LANG_BG_DISABLED
Definition Language.h:724
@ ERR_IN_NON_RANDOM_BG
Definition SharedDefines.h:3918
@ ERR_BATTLEGROUND_NONE
Definition SharedDefines.h:3904
@ ERR_BATTLEGROUND_TOO_MANY_QUEUES
Definition SharedDefines.h:3907
@ ERR_IN_RANDOM_BG
Definition SharedDefines.h:3917
@ ERR_BATTLEGROUND_QUEUED_FOR_RATED
Definition SharedDefines.h:3909
@ CLASS_DEATH_KNIGHT
Definition SharedDefines.h:146
@ BATTLEGROUND_QUEUE_2v2
Definition SharedDefines.h:3894
@ BATTLEGROUND_QUEUE_5v5
Definition SharedDefines.h:3896
@ BATTLEGROUND_QUEUE_3v3
Definition SharedDefines.h:3895
@ CLASS_CONTEXT_TELEPORT
Definition UnitDefines.h:232
uint32 GetMinPlayersPerTeam() const
Definition Battleground.h:341
uint32 GetMaxPlayersPerTeam() const
Definition Battleground.h:340
uint32 GetMembersCount() const
Definition Group.h:245
bool InBattlegroundQueueForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
Definition Player.cpp:12281
bool IsGameMaster() const
Definition Player.h:1161
bool HasSpell(uint32 spell) const override
Definition Player.cpp:3886

References _player, Player::AddBattlegroundQueueId(), BattlegroundQueue::AddGroup(), BATTLEGROUND_QUEUE_2v2, BATTLEGROUND_QUEUE_3v3, BATTLEGROUND_QUEUE_5v5, BATTLEGROUND_QUEUE_NONE, BATTLEGROUND_RB, BattlegroundMgr::BGQueueTypeId(), Group::CanJoinBattlegroundQueue(), Player::CanJoinToBattleground(), CLASS_CONTEXT_TELEPORT, CLASS_DEATH_KNIGHT, CONFIG_ALLOW_JOIN_BG_AND_LFG, DISABLE_TYPE_BATTLEGROUND, Group::DoForAllMembers(), ERR_BATTLEGROUND_NONE, ERR_BATTLEGROUND_NOT_IN_BATTLEGROUND, ERR_BATTLEGROUND_QUEUED_FOR_RATED, ERR_BATTLEGROUND_TOO_MANY_QUEUES, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS, ERR_IN_NON_RANDOM_BG, ERR_IN_RANDOM_BG, ERR_LFG_CANT_USE_BATTLEGROUND, BattlegroundQueue::GetAverageQueueWaitTime(), GetBattlegroundBracketByLevel(), Player::GetBGAccessByLevel(), Battleground::GetBgTypeID(), PvPDifficultyEntry::GetBracketId(), Player::GetGroup(), Object::GetGUID(), Group::GetLeaderGUID(), Unit::GetLevel(), Battleground::GetMapId(), WorldLocation::GetMapId(), Battleground::GetMaxPlayersPerTeam(), Group::GetMembersCount(), Battleground::GetMinPlayersPerTeam(), GetPlayer(), Player::HasFreeBattlegroundQueueId(), Player::HasSpell(), Player::InBattleground(), Player::InBattlegroundQueue(), Player::InBattlegroundQueueForBattlegroundQueueType(), Player::IsClass(), Player::IsGameMaster(), LANG_BG_DISABLED, lfg::LFG_STATE_NONE, lfg::LFG_STATE_QUEUED, LOG_DEBUG, LOG_ERROR, MAP_EBON_HOLD, ChatHandler::PSendSysMessage(), sBattlegroundMgr, sBattlemasterListStore, sDisableMgr, Player::SendDirectMessage(), SendPacket(), sLFGMgr, sScriptMgr, STATUS_WAIT_QUEUE, sWorld, TEAM_NEUTRAL, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleBeginTradeOpcode()

void WorldSession::HandleBeginTradeOpcode ( WorldPacket recvPacket)
518{
519 TradeData* my_trade = _player->m_trade;
520 if (!my_trade)
521 return;
522
525}
@ TRADE_STATUS_OPEN_WINDOW
Definition SharedDefines.h:3818

References _player, Player::GetSession(), TradeData::GetTrader(), Player::m_trade, SendTradeStatus(), and TRADE_STATUS_OPEN_WINDOW.

Referenced by OpcodeTable::Initialize().

◆ HandleBfEntryInviteResponse()

void WorldSession::HandleBfEntryInviteResponse ( WorldPacket recvData)
115{
116 uint32 BattleId;
117 uint8 Accepted;
118
119 recvData >> BattleId >> Accepted;
120
121 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldByBattleId(BattleId);
122 if (!Bf)
123 return;
124
125 //If player accept invitation
126 if (Accepted)
127 {
129 }
130 else
131 {
132 if (_player->GetZoneId() == Bf->GetZoneId())
134 }
135}
void KickPlayerFromBattlefield(ObjectGuid guid)
Kick player from battlefield and teleport him to kick-point location.
Definition Battlefield.cpp:328
void PlayerAcceptInviteToWar(Player *player)
Definition Battlefield.cpp:422
uint32 GetZoneId()
Definition Battlefield.h:243

References _player, Object::GetGUID(), Battlefield::GetZoneId(), WorldObject::GetZoneId(), Battlefield::KickPlayerFromBattlefield(), Battlefield::PlayerAcceptInviteToWar(), and sBattlefieldMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleBfExitRequest()

void WorldSession::HandleBfExitRequest ( WorldPacket recvData)
138{
139 uint32 BattleId;
140
141 recvData >> BattleId;
142
143 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldByBattleId(BattleId);
144 if (!Bf)
145 return;
146
148}
void AskToLeaveQueue(Player *player)
Definition Battlefield.cpp:406

References _player, Battlefield::AskToLeaveQueue(), and sBattlefieldMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleBfQueueInviteResponse()

void WorldSession::HandleBfQueueInviteResponse ( WorldPacket recvData)
97{
98 uint32 BattleId;
99 uint8 Accepted;
100
101 recvData >> BattleId >> Accepted;
102
103 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldByBattleId(BattleId);
104 if (!Bf)
105 return;
106
107 if (Accepted)
108 {
110 }
111}
void PlayerAcceptInviteToQueue(Player *player)
Definition Battlefield.cpp:397

References _player, Battlefield::PlayerAcceptInviteToQueue(), and sBattlefieldMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleBinderActivateOpcode()

void WorldSession::HandleBinderActivateOpcode ( WorldPacket recvPacket)
419{
420 ObjectGuid npcGUID;
421 recvData >> npcGUID;
422
423 if (!GetPlayer()->IsInWorld() || !GetPlayer()->IsAlive())
424 return;
425
427 if (!unit)
428 {
429 LOG_DEBUG("network", "WORLD: HandleBinderActivateOpcode - Unit ({}) not found or you can not interact with him.", npcGUID.ToString());
430 return;
431 }
432
433 // remove fake death
434 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
436
437 SendBindPoint(unit);
438}
@ UNIT_NPC_FLAG_INNKEEPER
Definition UnitDefines.h:335
void SendBindPoint(Creature *npc)
Definition NPCHandler.cpp:440

References Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, Unit::RemoveAurasByType(), SendBindPoint(), SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_INNKEEPER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleBugOpcode()

void WorldSession::HandleBugOpcode ( WorldPacket recvPacket)
619{
620 uint32 suggestion, contentlen, typelen;
621 std::string content, type;
622
623 recv_data >> suggestion >> contentlen >> content;
624
625 recv_data >> typelen >> type;
626
628
629 stmt->SetData(0, type);
630 stmt->SetData(1, content);
631
632 CharacterDatabase.Execute(stmt);
633}
@ CHAR_INS_BUG_REPORT
Definition CharacterDatabase.h:279

References CHAR_INS_BUG_REPORT, CharacterDatabase, and PreparedStatementBase::SetData().

Referenced by OpcodeTable::Initialize().

◆ HandleBusyTradeOpcode()

void WorldSession::HandleBusyTradeOpcode ( WorldPacket recvPacket)
77{
79}
@ TRADE_STATUS_BUSY
Definition SharedDefines.h:3816
void TradeCancel(bool sendback, TradeStatus status=TRADE_STATUS_TRADE_CANCELED)
Definition PlayerStorage.cpp:4090

References _player, TRADE_STATUS_BUSY, and Player::TradeCancel().

Referenced by OpcodeTable::Initialize().

◆ HandleBuybackItem()

void WorldSession::HandleBuybackItem ( WorldPackets::Item::BuybackItem packet)
746{
748 if (!creature)
749 {
750 LOG_DEBUG("network", "WORLD: HandleBuybackItem - Unit ({}) not found or you can not interact with him.", packet.VendorGuid.ToString());
752 return;
753 }
754
755 // remove fake death
756 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
758
759 Item* pItem = _player->GetItemFromBuyBackSlot(packet.Slot);
760 if (pItem)
761 {
763 if (!_player->HasEnoughMoney(price))
764 {
766 return;
767 }
768
769 ItemPosCountVec dest;
770 InventoryResult msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, pItem, false);
771 if (msg == EQUIP_ERR_OK)
772 {
773 if (sWorld->getBoolConfig(CONFIG_ITEMDELETE_VENDOR))
774 {
776 stmt->SetData(0, _player->GetGUID().GetCounter());
777 stmt->SetData(1, pItem->GetEntry());
778 stmt->SetData(2, pItem->GetCount());
779 CharacterDatabase.Execute(stmt);
780 }
781
782 _player->ModifyMoney(-(int32)price);
783 _player->RemoveItemFromBuyBackSlot(packet.Slot, false);
784 _player->ItemAddedQuestCheck(pItem->GetEntry(), pItem->GetCount());
785 _player->StoreItem(dest, pItem, true);
786 }
787 else
788 _player->SendEquipError(msg, pItem, nullptr);
789 return;
790 }
791 else
793}
@ CHAR_DEL_RECOVERY_ITEM
Definition CharacterDatabase.h:511
@ BUY_ERR_CANT_FIND_ITEM
Definition Item.h:141
@ BUY_ERR_NOT_ENOUGHT_MONEY
Definition Item.h:143
@ SELL_ERR_CANT_FIND_VENDOR
Definition Item.h:157
@ BUYBACK_SLOT_START
Definition Player.h:719
@ UNIT_NPC_FLAG_VENDOR
Definition UnitDefines.h:326
@ PLAYER_FIELD_BUYBACK_PRICE_1
Definition UpdateFields.h:372
@ CONFIG_ITEMDELETE_VENDOR
Definition WorldConfig.h:121
void RemoveItemFromBuyBackSlot(uint32 slot, bool del)
Definition PlayerStorage.cpp:3997
void SendSellError(SellResult msg, Creature *creature, ObjectGuid guid, uint32 param)
Definition PlayerStorage.cpp:4078
Item * GetItemFromBuyBackSlot(uint32 slot)
Definition PlayerStorage.cpp:3989
void SendBuyError(BuyResult msg, Creature *creature, uint32 item, uint32 param)
Definition PlayerStorage.cpp:4066
ObjectGuid VendorGuid
Definition ItemPackets.h:134
uint32 Slot
Definition ItemPackets.h:135

References _player, BUY_ERR_CANT_FIND_ITEM, BUY_ERR_NOT_ENOUGHT_MONEY, BUYBACK_SLOT_START, Player::CanStoreItem(), CHAR_DEL_RECOVERY_ITEM, CharacterDatabase, CONFIG_ITEMDELETE_VENDOR, ObjectGuid::Empty, EQUIP_ERR_OK, Item::GetCount(), ObjectGuid::GetCounter(), Object::GetEntry(), Object::GetGUID(), Player::GetItemFromBuyBackSlot(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Object::GetUInt32Value(), Player::HasEnoughMoney(), Player::ItemAddedQuestCheck(), LOG_DEBUG, Player::ModifyMoney(), NULL_BAG, NULL_SLOT, PLAYER_FIELD_BUYBACK_PRICE_1, Unit::RemoveAurasByType(), Player::RemoveItemFromBuyBackSlot(), SELL_ERR_CANT_FIND_VENDOR, Player::SendBuyError(), Player::SendEquipError(), Player::SendSellError(), PreparedStatementBase::SetData(), WorldPackets::Item::BuybackItem::Slot, SPELL_AURA_FEIGN_DEATH, Player::StoreItem(), sWorld, ObjectGuid::ToString(), UNIT_NPC_FLAG_VENDOR, UNIT_STATE_DIED, and WorldPackets::Item::BuybackItem::VendorGuid.

Referenced by OpcodeTable::Initialize().

◆ HandleBuyBankSlotOpcode()

void WorldSession::HandleBuyBankSlotOpcode ( WorldPackets::Bank::BuyBankSlot buyBankSlot)
144{
146 if (!CanUseBank(buyBankSlot.Banker))
147 {
149 SendPacket(packet.Write());
150 LOG_DEBUG("network", "WORLD: HandleBuyBankSlotOpcode - {} not found or you can't interact with him.", buyBankSlot.Banker.ToString());
151 return;
152 }
153
155
156 // next slot
157 ++slot;
158
159 LOG_INFO("network", "PLAYER: Buy bank bag slot, slot number = {}", slot);
160
161 BankBagSlotPricesEntry const* slotEntry = sBankBagSlotPricesStore.LookupEntry(slot);
162
163 if (!slotEntry)
164 {
166 SendPacket(packet.Write());
167 return;
168 }
169
170 uint32 price = slotEntry->price;
171
172 if (!_player->HasEnoughMoney(price))
173 {
175 SendPacket(packet.Write());
176 return;
177 }
178
180 _player->ModifyMoney(-int32(price));
181
182 packet.Result = ERR_BANKSLOT_OK;
183 SendPacket(packet.Write());
184
186}
@ ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT
Definition DBCEnums.h:159
DBCStorage< BankBagSlotPricesEntry > sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt)
#define LOG_INFO(filterType__,...)
Definition Log.h:166
@ ERR_BANKSLOT_NOTBANKER
Definition Player.h:114
@ ERR_BANKSLOT_FAILED_TOO_MANY
Definition Player.h:112
@ ERR_BANKSLOT_OK
Definition Player.h:115
@ ERR_BANKSLOT_INSUFFICIENT_FUNDS
Definition Player.h:113
uint8 GetBankBagSlotCount() const
Definition Player.h:1271
void SetBankBagSlotCount(uint8 count)
Definition Player.h:1272
Definition BankPackets.h:61
WorldPacket const * Write() override
Definition BankPackets.cpp:37
uint32 Result
Definition BankPackets.h:67
ObjectGuid Banker
Definition BankPackets.h:57
Definition DBCStructure.h:584
uint32 price
Definition DBCStructure.h:586

References _player, ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT, WorldPackets::Bank::BuyBankSlot::Banker, CanUseBank(), ERR_BANKSLOT_FAILED_TOO_MANY, ERR_BANKSLOT_INSUFFICIENT_FUNDS, ERR_BANKSLOT_NOTBANKER, ERR_BANKSLOT_OK, Player::GetBankBagSlotCount(), Player::HasEnoughMoney(), LOG_DEBUG, LOG_INFO, Player::ModifyMoney(), BankBagSlotPricesEntry::price, WorldPackets::Bank::BuyBankSlotResult::Result, sBankBagSlotPricesStore, SendPacket(), Player::SetBankBagSlotCount(), ObjectGuid::ToString(), Player::UpdateAchievementCriteria(), and WorldPackets::Bank::BuyBankSlotResult::Write().

Referenced by OpcodeTable::Initialize().

◆ HandleBuyItemInSlotOpcode()

void WorldSession::HandleBuyItemInSlotOpcode ( WorldPackets::Item::BuyItemInSlot packet)
796{
797 // client expects count starting at 1, and we send vendorslot+1 to client already
798 if (packet.Slot > 0)
799 --packet.Slot;
800 else
801 return; // cheating
802
803 uint8 bag = NULL_BAG; // init for case invalid bagGUID
804
805 // find bag slot by bag guid
806 if (packet.BagGuid == _player->GetGUID())
808 else
809 {
811 {
812 if (Bag* pBag = _player->GetBagByPos(i))
813 {
814 if (packet.BagGuid == pBag->GetGUID())
815 {
816 bag = i;
817 break;
818 }
819 }
820 }
821 }
822
823 // bag not found, cheating?
824 if (bag == NULL_BAG)
825 return;
826
827 GetPlayer()->BuyItemFromVendorSlot(packet.VendorGuid, packet.Slot, packet.Item, packet.Count, bag, packet.BagSlot);
828}
@ INVENTORY_SLOT_BAG_START
Definition Player.h:694
@ INVENTORY_SLOT_BAG_END
Definition Player.h:695
Definition Bag.h:28
Bag * GetBagByPos(uint8 slot) const
Definition PlayerStorage.cpp:459
bool BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot)
Definition Player.cpp:10734
uint32 Item
Definition ItemPackets.h:146
uint32 Count
Definition ItemPackets.h:150
uint32 Slot
Definition ItemPackets.h:147
ObjectGuid BagGuid
Definition ItemPackets.h:148
uint8 BagSlot
Definition ItemPackets.h:149
ObjectGuid VendorGuid
Definition ItemPackets.h:145

References _player, WorldPackets::Item::BuyItemInSlot::BagGuid, WorldPackets::Item::BuyItemInSlot::BagSlot, Player::BuyItemFromVendorSlot(), WorldPackets::Item::BuyItemInSlot::Count, Player::GetBagByPos(), Object::GetGUID(), GetPlayer(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, INVENTORY_SLOT_BAG_START, WorldPackets::Item::BuyItemInSlot::Item, NULL_BAG, WorldPackets::Item::BuyItemInSlot::Slot, and WorldPackets::Item::BuyItemInSlot::VendorGuid.

Referenced by OpcodeTable::Initialize().

◆ HandleBuyItemOpcode()

void WorldSession::HandleBuyItemOpcode ( WorldPackets::Item::BuyItem packet)
831{
832 // client expects count starting at 1, and we send vendorslot+1 to client already
833 if (packet.Slot > 0)
834 --packet.Slot;
835 else
836 return; // cheating
837
838 GetPlayer()->BuyItemFromVendorSlot(packet.VendorGuid, packet.Slot, packet.Item, packet.Count, NULL_BAG, NULL_SLOT);
839}
uint32 Item
Definition ItemPackets.h:161
uint32 Count
Definition ItemPackets.h:163
uint32 Slot
Definition ItemPackets.h:162
ObjectGuid VendorGuid
Definition ItemPackets.h:160

References Player::BuyItemFromVendorSlot(), WorldPackets::Item::BuyItem::Count, GetPlayer(), WorldPackets::Item::BuyItem::Item, NULL_BAG, NULL_SLOT, WorldPackets::Item::BuyItem::Slot, and WorldPackets::Item::BuyItem::VendorGuid.

Referenced by OpcodeTable::Initialize().

◆ HandleBuyStableSlot()

void WorldSession::HandleBuyStableSlot ( WorldPacket recvPacket)
733{
734 LOG_DEBUG("network", "WORLD: Recv CMSG_BUY_STABLE_SLOT.");
735 ObjectGuid npcGUID;
736
737 recvData >> npcGUID;
738
739 if (!CheckStableMaster(npcGUID))
740 {
742 return;
743 }
744
745 // remove fake death
746 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
748
749 PetStable& petStable = GetPlayer()->GetOrInitPetStable();
750 if (petStable.MaxStabledPets < MAX_PET_STABLES)
751 {
752 StableSlotPricesEntry const* SlotPrice = sStableSlotPricesStore.LookupEntry(petStable.MaxStabledPets + 1);
753 if (_player->HasEnoughMoney(SlotPrice->Price))
754 {
755 ++petStable.MaxStabledPets;
756 _player->ModifyMoney(-int32(SlotPrice->Price));
758 }
759 else
761 }
762 else
764}
DBCStorage< StableSlotPricesEntry > sStableSlotPricesStore(StableSlotPricesfmt)
@ STABLE_ERR_MONEY
Definition NPCHandler.cpp:38
@ STABLE_SUCCESS_BUY_SLOT
Definition NPCHandler.cpp:42
@ STABLE_ERR_STABLE
Definition NPCHandler.cpp:39
constexpr auto MAX_PET_STABLES
Definition PetDefines.h:37
Definition PetDefines.h:212
uint32 MaxStabledPets
Definition PetDefines.h:237
PetStable & GetOrInitPetStable()
Definition Player.cpp:15692
bool CheckStableMaster(ObjectGuid guid)
Definition PetHandler.cpp:663
void SendStableResult(uint8 guid)
Definition NPCHandler.cpp:543
Definition DBCStructure.h:1901
uint32 Price
Definition DBCStructure.h:1903

References _player, CheckStableMaster(), Player::GetOrInitPetStable(), GetPlayer(), Player::HasEnoughMoney(), LOG_DEBUG, MAX_PET_STABLES, PetStable::MaxStabledPets, Player::ModifyMoney(), StableSlotPricesEntry::Price, Unit::RemoveAurasByType(), SendStableResult(), SPELL_AURA_FEIGN_DEATH, sStableSlotPricesStore, STABLE_ERR_MONEY, STABLE_ERR_STABLE, STABLE_SUCCESS_BUY_SLOT, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarAddEvent()

void WorldSession::HandleCalendarAddEvent ( WorldPacket recvData)
229{
230 ObjectGuid guid = _player->GetGUID();
231
232 std::string title;
233 std::string description;
234 uint8 type;
235 uint8 repeatable;
236 uint32 maxInvites;
237 int32 dungeonId;
238 uint32 eventPackedTime;
239 uint32 unkPackedTime;
240 uint32 flags;
241
242 recvData >> title >> description >> type >> repeatable >> maxInvites >> dungeonId;
243 recvData.ReadPackedTime(eventPackedTime);
244 recvData.ReadPackedTime(unkPackedTime);
245 recvData >> flags;
246
247 // prevent attacks with non-utf8 chars -> with multiple packets it will hang up the db due to errors.
248 if (!validUtf8String(recvData, title, "create", guid) || title.size() > 31 || !validUtf8String(recvData, description, "create", guid) || description.size() > 255)
249 return;
250
251 // prevent events in the past
252 // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
253 if (time_t(eventPackedTime) < (GameTime::GetGameTime().count() - time_t(86400L)))
254 {
255 recvData.rfinish();
256 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_PASSED);
257 return;
258 }
259
260 // If the event is a guild event, check if the player is in a guild
262 {
263 if (!_player->GetGuildId())
264 {
265 recvData.rfinish();
266 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD);
267 return;
268 }
269 }
270
271 // Check if the player reached the max number of events allowed to create
273 {
274 if (sCalendarMgr->GetGuildEvents(_player->GetGuildId()).size() >= CALENDAR_MAX_GUILD_EVENTS)
275 {
276 recvData.rfinish();
277 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED);
278 return;
279 }
280 }
281 else
282 {
283 if (sCalendarMgr->GetEventsCreatedBy(guid).size() >= CALENDAR_MAX_EVENTS)
284 {
285 recvData.rfinish();
286 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENTS_EXCEEDED);
287 return;
288 }
289 }
290
292 {
293 recvData.rfinish();
294 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_INTERNAL);
295 return;
296 }
298
299 CalendarEvent* calendarEvent = new CalendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(type), dungeonId,
300 time_t(eventPackedTime), flags, time_t(unkPackedTime), title, description);
301
302 if (calendarEvent->IsGuildEvent() || calendarEvent->IsGuildAnnouncement())
303 if (Player* creator = ObjectAccessor::FindConnectedPlayer(guid))
304 calendarEvent->SetGuildId(creator->GetGuildId());
305
306 if (calendarEvent->IsGuildAnnouncement())
307 {
308 // 946684800 is 01/01/2000 00:00:00 - default response time
309 CalendarInvite* invite = new CalendarInvite(0, calendarEvent->GetEventId(), ObjectGuid::Empty, guid, 946684800, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, "");
310 sCalendarMgr->AddInvite(calendarEvent, invite);
311 }
312 else
313 {
314 uint32 inviteCount;
318
319 memset(status, 0, sizeof(status));
320 memset(rank, 0, sizeof(rank));
321
322 try
323 {
324 recvData >> inviteCount;
325
326 for (uint32 i = 0; i < inviteCount && i < CALENDAR_MAX_INVITES; ++i)
327 {
328 recvData >> invitee[i].ReadAsPacked();
329 recvData >> status[i] >> rank[i];
330 }
331 }
332 catch (ByteBufferException const&)
333 {
334 delete calendarEvent;
335 calendarEvent = nullptr;
336 throw;
337 }
338
340 if (inviteCount > 1)
341 trans = CharacterDatabase.BeginTransaction();
342
343 for (uint32 i = 0; i < inviteCount && i < CALENDAR_MAX_INVITES; ++i)
344 {
345 // 946684800 is 01/01/2000 00:00:00 - default response time
346 CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent->GetEventId(), invitee[i], guid, 946684800, CalendarInviteStatus(status[i]), CalendarModerationRank(rank[i]), "");
347 sCalendarMgr->AddInvite(calendarEvent, invite, trans);
348 }
349
350 if (inviteCount > 1)
351 CharacterDatabase.CommitTransaction(trans);
352 }
353
354 sCalendarMgr->AddEvent(calendarEvent, CALENDAR_SENDTYPE_ADD);
355}
bool validUtf8String(WorldPacket &recvData, std::string &s, std::string action, ObjectGuid playerGUID)
Definition CalendarHandler.cpp:216
#define sCalendarMgr
Definition CalendarMgr.h:344
@ CALENDAR_ERROR_INTERNAL
Definition CalendarMgr.h:98
@ CALENDAR_ERROR_EVENT_PASSED
Definition CalendarMgr.h:109
@ CALENDAR_ERROR_EVENTS_EXCEEDED
Definition CalendarMgr.h:92
@ CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED
Definition CalendarMgr.h:91
@ CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD
Definition CalendarMgr.h:99
CalendarModerationRank
Definition CalendarMgr.h:44
@ CALENDAR_RANK_PLAYER
Definition CalendarMgr.h:45
@ CALENDAR_SENDTYPE_ADD
Definition CalendarMgr.h:53
CalendarEventType
Definition CalendarMgr.h:58
CalendarInviteStatus
Definition CalendarMgr.h:75
@ CALENDAR_STATUS_NOT_SIGNED_UP
Definition CalendarMgr.h:83
@ CALENDAR_MAX_EVENTS
Definition CalendarMgr.h:128
@ CALENDAR_MAX_INVITES
Definition CalendarMgr.h:130
@ CALENDAR_MAX_GUILD_EVENTS
Definition CalendarMgr.h:129
@ CALENDAR_CREATE_EVENT_COOLDOWN
Definition CalendarMgr.h:131
Definition ByteBuffer.h:32
uint32 ReadPackedTime()
Definition ByteBuffer.cpp:95
uint32 GetGuildId() const
Definition Player.h:1896
time_t GetCalendarEventCreationCooldown() const
Definition WorldSession.h:592
void SetCalendarEventCreationCooldown(time_t cooldown)
Definition WorldSession.h:593
Definition CalendarMgr.h:195
bool IsGuildAnnouncement() const
Definition CalendarMgr.h:253
void SetGuildId(uint32 guildId)
Definition CalendarMgr.h:228
bool IsGuildEvent() const
Definition CalendarMgr.h:252
uint64 GetEventId() const
Definition CalendarMgr.h:223
Definition CalendarMgr.h:136

References _player, CALENDAR_CREATE_EVENT_COOLDOWN, CALENDAR_ERROR_EVENT_PASSED, CALENDAR_ERROR_EVENTS_EXCEEDED, CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED, CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD, CALENDAR_ERROR_INTERNAL, CALENDAR_MAX_EVENTS, CALENDAR_MAX_GUILD_EVENTS, CALENDAR_MAX_INVITES, CALENDAR_RANK_PLAYER, CALENDAR_SENDTYPE_ADD, CALENDAR_STATUS_NOT_SIGNED_UP, CharacterDatabase, ObjectGuid::Empty, ObjectAccessor::FindConnectedPlayer(), GetCalendarEventCreationCooldown(), CalendarEvent::GetEventId(), GameTime::GetGameTime(), Object::GetGUID(), Player::GetGuildId(), CalendarEvent::IsGuildAnnouncement(), CalendarEvent::IsGuildEvent(), ObjectGuid::ReadAsPacked(), ByteBuffer::ReadPackedTime(), ByteBuffer::rfinish(), sCalendarMgr, SetCalendarEventCreationCooldown(), CalendarEvent::SetGuildId(), and validUtf8String().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarArenaTeam()

void WorldSession::HandleCalendarArenaTeam ( WorldPackets::Calendar::ArenaTeam packet)
209{
210 LOG_DEBUG("network", "CMSG_CALENDAR_ARENA_TEAM [{}]", _player->GetGUID().ToString());
211
212 if (ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(packet.ArenaTeamId))
213 team->MassInviteToEvent(this);
214}
uint32 ArenaTeamId
Definition CalendarPackets.h:57

References _player, WorldPackets::Calendar::ArenaTeam::ArenaTeamId, Object::GetGUID(), LOG_DEBUG, sArenaTeamMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarComplain()

void WorldSession::HandleCalendarComplain ( WorldPackets::Calendar::CalendarComplain packet)
756{
757 ObjectGuid guid = _player->GetGUID();
758
759 LOG_DEBUG("network", "CMSG_CALENDAR_COMPLAIN [{}] EventId [{}] guid [{}]", guid.ToString(), packet.EventId, packet.ComplainGuid.ToString());
760
761 // what to do with complains?
762}
ObjectGuid ComplainGuid
Definition CalendarPackets.h:68
uint64 EventId
Definition CalendarPackets.h:67

References _player, WorldPackets::Calendar::CalendarComplain::ComplainGuid, WorldPackets::Calendar::CalendarComplain::EventId, Object::GetGUID(), LOG_DEBUG, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarCopyEvent()

void WorldSession::HandleCalendarCopyEvent ( WorldPacket recvData)
426{
427 ObjectGuid guid = _player->GetGUID();
428 uint64 eventId;
429 uint64 inviteId;
430 uint32 eventTime;
431
432 recvData >> eventId >> inviteId;
433 recvData.ReadPackedTime(eventTime);
434 LOG_DEBUG("network", "CMSG_CALENDAR_COPY_EVENT [{}], EventId [{}] inviteId [{}] Time: {}", guid.ToString(), eventId, inviteId, eventTime);
435
436 // prevent events in the past
437 // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
438 if (time_t(eventTime) < (GameTime::GetGameTime().count() - time_t(86400L)))
439 {
440 recvData.rfinish();
441 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_PASSED);
442 return;
443 }
444
445 if (CalendarEvent* oldEvent = sCalendarMgr->GetEvent(eventId))
446 {
447 // Ensure that the player has access to the event
448 if (oldEvent->IsGuildEvent() || oldEvent->IsGuildAnnouncement())
449 {
450 if (oldEvent->GetGuildId() != _player->GetGuildId())
451 {
452 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
453 return;
454 }
455 }
456 else
457 {
458 if (oldEvent->GetCreatorGUID() != guid)
459 {
460 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
461 return;
462 }
463 }
464
465 // Check if the player reached the max number of events allowed to create
466 if (oldEvent->IsGuildEvent() || oldEvent->IsGuildAnnouncement())
467 {
468 if (sCalendarMgr->GetGuildEvents(_player->GetGuildId()).size() >= CALENDAR_MAX_GUILD_EVENTS)
469 {
470 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED);
471 return;
472 }
473 }
474 else
475 {
476 if (sCalendarMgr->GetEventsCreatedBy(guid).size() >= CALENDAR_MAX_EVENTS)
477 {
478 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENTS_EXCEEDED);
479 return;
480 }
481 }
482
484 {
485 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_INTERNAL);
486 return;
487 }
489
490 CalendarEvent* newEvent = new CalendarEvent(*oldEvent, sCalendarMgr->GetFreeEventId());
491 newEvent->SetEventTime(time_t(eventTime));
492 sCalendarMgr->AddEvent(newEvent, CALENDAR_SENDTYPE_COPY);
493
494 CalendarInviteStore invites = sCalendarMgr->GetEventInvites(eventId);
496 if (invites.size() > 1)
497 trans = CharacterDatabase.BeginTransaction();
498
499 for (CalendarInviteStore::const_iterator itr = invites.begin(); itr != invites.end(); ++itr)
500 sCalendarMgr->AddInvite(newEvent, new CalendarInvite(**itr, sCalendarMgr->GetFreeInviteId(), newEvent->GetEventId()), trans);
501
502 if (invites.size() > 1)
503 CharacterDatabase.CommitTransaction(trans);
504 // should we change owner when somebody makes a copy of event owned by another person?
505 }
506 else
507 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
508}
@ CALENDAR_ERROR_EVENT_INVALID
Definition CalendarMgr.h:96
std::vector< CalendarInvite * > CalendarInviteStore
Definition CalendarMgr.h:273
@ CALENDAR_SENDTYPE_COPY
Definition CalendarMgr.h:54
void SetEventTime(time_t eventTime)
Definition CalendarMgr.h:243

References _player, CALENDAR_CREATE_EVENT_COOLDOWN, CALENDAR_ERROR_EVENT_INVALID, CALENDAR_ERROR_EVENT_PASSED, CALENDAR_ERROR_EVENTS_EXCEEDED, CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED, CALENDAR_ERROR_INTERNAL, CALENDAR_MAX_EVENTS, CALENDAR_MAX_GUILD_EVENTS, CALENDAR_SENDTYPE_COPY, CharacterDatabase, GetCalendarEventCreationCooldown(), CalendarEvent::GetEventId(), GameTime::GetGameTime(), Object::GetGUID(), Player::GetGuildId(), LOG_DEBUG, ByteBuffer::ReadPackedTime(), ByteBuffer::rfinish(), sCalendarMgr, SetCalendarEventCreationCooldown(), CalendarEvent::SetEventTime(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarEventInvite()

void WorldSession::HandleCalendarEventInvite ( WorldPacket recvData)
511{
512 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_INVITE");
513
514 ObjectGuid playerGuid = _player->GetGUID();
515
516 uint64 eventId;
517 uint64 inviteId;
518 std::string name;
519 bool isPreInvite;
520 bool isGuildEvent;
521
522 ObjectGuid inviteeGuid;
523 uint32 inviteeTeamId = TEAM_NEUTRAL;
524 uint32 inviteeGuildId = 0;
525
526 recvData >> eventId >> inviteId >> name >> isPreInvite >> isGuildEvent;
527
528 if (Player* player = ObjectAccessor::FindPlayerByName(name.c_str(), false))
529 {
530 // Invitee is online
531 inviteeGuid = player->GetGUID();
532 inviteeTeamId = player->GetTeamId();
533 inviteeGuildId = player->GetGuildId();
534 }
535 else
536 {
537 // xinef: Get Data From global storage
538 if (ObjectGuid guid = sCharacterCache->GetCharacterGuidByName(name))
539 {
540 if (CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(guid))
541 {
542 inviteeGuid = guid;
543 inviteeTeamId = Player::TeamIdForRace(playerData->Race);
544 inviteeGuildId = playerData->GuildId;
545 }
546 }
547 }
548
549 if (!inviteeGuid)
550 {
551 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_PLAYER_NOT_FOUND);
552 return;
553 }
554
555 if (_player->GetTeamId() != inviteeTeamId && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR))
556 {
557 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NOT_ALLIED);
558 return;
559 }
560
561 // xinef: sync query
562 if (QueryResult result = CharacterDatabase.Query("SELECT flags FROM character_social WHERE guid = {} AND friend = {}", inviteeGuid.GetCounter(), playerGuid.GetCounter()))
563 {
564 Field* fields = result->Fetch();
565 if (fields[0].Get<uint8>() & SOCIAL_FLAG_IGNORED)
566 {
567 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_IGNORING_YOU_S, name.c_str());
568 return;
569 }
570 }
571
572 if (!isPreInvite)
573 {
574 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
575 {
576 if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() == inviteeGuildId)
577 {
578 // we can't invite guild members to guild events
579 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NO_GUILD_INVITES);
580 return;
581 }
582
583 // 946684800 is 01/01/2000 00:00:00 - default response time
584 CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), eventId, inviteeGuid, playerGuid, 946684800, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, "");
585 sCalendarMgr->AddInvite(calendarEvent, invite);
586 }
587 else
588 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_EVENT_INVALID);
589 }
590 else
591 {
592 if (isGuildEvent && inviteeGuildId == _player->GetGuildId())
593 {
594 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NO_GUILD_INVITES);
595 return;
596 }
597
598 // 946684800 is 01/01/2000 00:00:00 - default response time
599 CalendarInvite* invite = new CalendarInvite(inviteId, 0, inviteeGuid, playerGuid, 946684800, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, "");
600 sCalendarMgr->SendCalendarEventInvite(*invite);
601 }
602}
@ CALENDAR_ERROR_NOT_ALLIED
Definition CalendarMgr.h:102
@ CALENDAR_ERROR_NO_GUILD_INVITES
Definition CalendarMgr.h:121
@ CALENDAR_ERROR_IGNORING_YOU_S
Definition CalendarMgr.h:103
@ CALENDAR_ERROR_PLAYER_NOT_FOUND
Definition CalendarMgr.h:101
@ CALENDAR_STATUS_INVITED
Definition CalendarMgr.h:76
std::shared_ptr< ResultSet > QueryResult
Definition DatabaseEnvFwd.h:27
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR
Definition WorldConfig.h:31
Class used to access individual fields of database query result.
Definition Field.h:98

References _player, CALENDAR_ERROR_EVENT_INVALID, CALENDAR_ERROR_IGNORING_YOU_S, CALENDAR_ERROR_NO_GUILD_INVITES, CALENDAR_ERROR_NOT_ALLIED, CALENDAR_ERROR_PLAYER_NOT_FOUND, CALENDAR_RANK_PLAYER, CALENDAR_STATUS_INVITED, CharacterDatabase, CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR, ObjectAccessor::FindPlayerByName(), ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetGuildId(), Player::GetTeamId(), LOG_DEBUG, sCalendarMgr, sCharacterCache, SOCIAL_FLAG_IGNORED, sWorld, TEAM_NEUTRAL, and Player::TeamIdForRace().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarEventModeratorStatus()

void WorldSession::HandleCalendarEventModeratorStatus ( WorldPacket recvData)
727{
728 ObjectGuid guid = _player->GetGUID();
729 ObjectGuid invitee;
730 uint64 eventId;
731 uint64 inviteId;
732 uint64 ownerInviteId; // isn't it sender's inviteId?
733 uint8 rank;
734
735 recvData>> invitee.ReadAsPacked();
736 recvData >> eventId >> inviteId >> ownerInviteId >> rank;
737 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_MODERATOR_STATUS [{}] EventId [{}] ownerInviteId [{}], Invitee ([{}] id: [{}], rank {}",
738 guid.ToString(), eventId, ownerInviteId, invitee.ToString(), inviteId, rank);
739
740 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
741 {
742 if (CalendarInvite* invite = sCalendarMgr->GetInvite(inviteId))
743 {
744 invite->SetRank(CalendarModerationRank(rank));
745 sCalendarMgr->UpdateInvite(invite);
746 sCalendarMgr->SendCalendarEventModeratorStatusAlert(*calendarEvent, *invite);
747 }
748 else
749 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); // correct?
750 }
751 else
752 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
753}
@ CALENDAR_ERROR_NO_INVITE
Definition CalendarMgr.h:117

References _player, CALENDAR_ERROR_EVENT_INVALID, CALENDAR_ERROR_NO_INVITE, Object::GetGUID(), LOG_DEBUG, ObjectGuid::ReadAsPacked(), sCalendarMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarEventRemoveInvite()

void WorldSession::HandleCalendarEventRemoveInvite ( WorldPacket recvData)
667{
668 ObjectGuid guid = _player->GetGUID();
669 ObjectGuid invitee;
670 uint64 eventId;
671 uint64 ownerInviteId; // isn't it sender's inviteId?
672 uint64 inviteId;
673
674 recvData>> invitee.ReadAsPacked();
675 recvData >> inviteId >> ownerInviteId >> eventId;
676
677 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_REMOVE_INVITE [{}] EventId [{}], ownerInviteId [{}], Invitee ([{}] id: [{}])",
678 guid.ToString(), eventId, ownerInviteId, invitee.ToString(), inviteId);
679
680 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
681 {
682 if (calendarEvent->GetCreatorGUID() == invitee)
683 {
684 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_DELETE_CREATOR_FAILED);
685 return;
686 }
687
688 sCalendarMgr->RemoveInvite(inviteId, eventId, guid);
689 }
690 else
691 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE);
692}
@ CALENDAR_ERROR_DELETE_CREATOR_FAILED
Definition CalendarMgr.h:111

References _player, CALENDAR_ERROR_DELETE_CREATOR_FAILED, CALENDAR_ERROR_NO_INVITE, Object::GetGUID(), LOG_DEBUG, ObjectGuid::ReadAsPacked(), sCalendarMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarEventRsvp()

void WorldSession::HandleCalendarEventRsvp ( WorldPacket recvData)
631{
632 ObjectGuid guid = _player->GetGUID();
633 uint64 eventId;
634 uint64 inviteId;
635 uint32 status;
636
637 recvData >> eventId >> inviteId >> status;
638 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_RSVP [{}] EventId [{}], InviteId [{}], status {}",
639 guid.ToString(), eventId, inviteId, status);
640
641 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
642 {
643 // i think we still should be able to remove self from locked events
644 if (status != CALENDAR_STATUS_REMOVED && calendarEvent->GetFlags() & CALENDAR_FLAG_INVITES_LOCKED)
645 {
646 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_LOCKED);
647 return;
648 }
649
650 if (CalendarInvite* invite = sCalendarMgr->GetInvite(inviteId))
651 {
652 invite->SetStatus(CalendarInviteStatus(status));
653 invite->SetStatusTime(GameTime::GetGameTime().count());
654
655 sCalendarMgr->UpdateInvite(invite);
656 sCalendarMgr->SendCalendarEventStatus(*calendarEvent, *invite);
657 sCalendarMgr->SendCalendarClearPendingAction(guid);
658 }
659 else
660 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); // correct?
661 }
662 else
663 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
664}
@ CALENDAR_ERROR_EVENT_LOCKED
Definition CalendarMgr.h:110
@ CALENDAR_FLAG_INVITES_LOCKED
Definition CalendarMgr.h:38
@ CALENDAR_STATUS_REMOVED
Definition CalendarMgr.h:85

References _player, CALENDAR_ERROR_EVENT_INVALID, CALENDAR_ERROR_EVENT_LOCKED, CALENDAR_ERROR_NO_INVITE, CALENDAR_FLAG_INVITES_LOCKED, CALENDAR_STATUS_REMOVED, GameTime::GetGameTime(), Object::GetGUID(), LOG_DEBUG, sCalendarMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarEventSignup()

void WorldSession::HandleCalendarEventSignup ( WorldPacket recvData)
605{
606 ObjectGuid guid = _player->GetGUID();
607 uint64 eventId;
608 bool tentative;
609
610 recvData >> eventId >> tentative;
611 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_SIGNUP [{}] EventId [{}] Tentative {}", guid.ToString(), eventId, tentative);
612
613 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
614 {
615 if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() != _player->GetGuildId())
616 {
617 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD);
618 return;
619 }
620
622 CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), eventId, guid, guid, GameTime::GetGameTime().count(), status, CALENDAR_RANK_PLAYER, "");
623 sCalendarMgr->AddInvite(calendarEvent, invite);
624 sCalendarMgr->SendCalendarClearPendingAction(guid);
625 }
626 else
627 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
628}
@ CALENDAR_STATUS_TENTATIVE
Definition CalendarMgr.h:84
@ CALENDAR_STATUS_SIGNED_UP
Definition CalendarMgr.h:82

References _player, CALENDAR_ERROR_EVENT_INVALID, CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD, CALENDAR_RANK_PLAYER, CALENDAR_STATUS_SIGNED_UP, CALENDAR_STATUS_TENTATIVE, GameTime::GetGameTime(), Object::GetGUID(), Player::GetGuildId(), LOG_DEBUG, sCalendarMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarEventStatus()

void WorldSession::HandleCalendarEventStatus ( WorldPacket recvData)
695{
696 ObjectGuid guid = _player->GetGUID();
697 ObjectGuid invitee;
698 uint64 eventId;
699 uint64 inviteId;
700 uint64 ownerInviteId; // isn't it sender's inviteId?
701 uint8 status;
702
703 recvData >> invitee.ReadAsPacked();
704 recvData >> eventId >> inviteId >> ownerInviteId >> status;
705 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_STATUS [{}] EventId [{}] ownerInviteId [{}], Invitee ({}) id: [{}], status {}",
706 guid.ToString(), eventId, ownerInviteId, invitee.ToString(), inviteId, status);
707
708 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
709 {
710 if (CalendarInvite* invite = sCalendarMgr->GetInvite(inviteId))
711 {
712 invite->SetStatus((CalendarInviteStatus)status);
713 invite->SetStatusTime(GameTime::GetGameTime().count());
714
715 sCalendarMgr->UpdateInvite(invite);
716 sCalendarMgr->SendCalendarEventStatus(*calendarEvent, *invite);
717 sCalendarMgr->SendCalendarClearPendingAction(invitee);
718 }
719 else
720 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); // correct?
721 }
722 else
723 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
724}

References _player, CALENDAR_ERROR_EVENT_INVALID, CALENDAR_ERROR_NO_INVITE, GameTime::GetGameTime(), Object::GetGUID(), LOG_DEBUG, ObjectGuid::ReadAsPacked(), sCalendarMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarGetCalendar()

void WorldSession::HandleCalendarGetCalendar ( WorldPacket recvData)
Todo:
: Fix this, how we do know how many and what holidays to send?
54{
55 ObjectGuid guid = _player->GetGUID();
56 LOG_DEBUG("network", "CMSG_CALENDAR_GET_CALENDAR [{}]", guid.ToString());
57
58 time_t currTime = GameTime::GetGameTime().count();
59
60 WorldPacket data(SMSG_CALENDAR_SEND_CALENDAR, 1000); // Average size if no instance
61
62 CalendarInviteStore invites = sCalendarMgr->GetPlayerInvites(guid);
63 data << uint32(invites.size());
64 for (CalendarInviteStore::const_iterator itr = invites.begin(); itr != invites.end(); ++itr)
65 {
66 data << uint64((*itr)->GetEventId());
67 data << uint64((*itr)->GetInviteId());
68 data << uint8((*itr)->GetStatus());
69 data << uint8((*itr)->GetRank());
70
71 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent((*itr)->GetEventId()))
72 {
73 data << uint8(calendarEvent->IsGuildEvent());
74 data << calendarEvent->GetCreatorGUID().WriteAsPacked();
75 }
76 else
77 {
78 data << uint8(0);
79 data << (*itr)->GetSenderGUID().WriteAsPacked();
80 }
81 }
82
83 CalendarEventStore playerEvents = sCalendarMgr->GetPlayerEvents(guid);
84 data << uint32(playerEvents.size());
85 for (CalendarEventStore::const_iterator itr = playerEvents.begin(); itr != playerEvents.end(); ++itr)
86 {
87 CalendarEvent* calendarEvent = *itr;
88
89 data << uint64(calendarEvent->GetEventId());
90 data << calendarEvent->GetTitle();
91 data << uint32(calendarEvent->GetType());
92 data.AppendPackedTime(calendarEvent->GetEventTime());
93 data << uint32(calendarEvent->GetFlags());
94 data << int32(calendarEvent->GetDungeonId());
95 data << calendarEvent->GetCreatorGUID().WriteAsPacked();
96 }
97
98 data << uint32(currTime); // server time
99 data.AppendPackedTime(currTime); // zone time
100
101 ByteBuffer dataBuffer;
102 uint32 boundCounter = 0;
103 for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
104 {
105 BoundInstancesMap const& m_boundInstances = sInstanceSaveMgr->PlayerGetBoundInstances(_player->GetGUID(), Difficulty(i));
106 for (BoundInstancesMap::const_iterator itr = m_boundInstances.begin(); itr != m_boundInstances.end(); ++itr)
107 {
108 if (itr->second.perm)
109 {
110 InstanceSave const* save = itr->second.save;
111 time_t resetTime = itr->second.extended ? save->GetExtendedResetTime() : save->GetResetTime();
112 dataBuffer << uint32(save->GetMapId());
113 dataBuffer << uint32(save->GetDifficulty());
114 dataBuffer << uint32(resetTime >= currTime ? resetTime - currTime : 0);
115 dataBuffer << ObjectGuid::Create<HighGuid::Instance>(save->GetInstanceId()); // instance save id as unique instance copy id
116 ++boundCounter;
117 }
118 }
119 }
120
121 data << uint32(boundCounter);
122 data.append(dataBuffer);
123
124 // pussywizard
125 uint32 relationTime = sWorld->getIntConfig(CONFIG_INSTANCE_RESET_TIME_RELATIVE_TIMESTAMP) + sWorld->getIntConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR; // set point in time (default 29.12.2005) + X hours
126 data << uint32(relationTime);
127
128 // Reuse variables
129 boundCounter = 0;
130 std::set<uint32> sentMaps;
131 dataBuffer.clear();
132
133 ResetTimeByMapDifficultyMap const& resets = sInstanceSaveMgr->GetResetTimeMap();
134 for (ResetTimeByMapDifficultyMap::const_iterator itr = resets.begin(); itr != resets.end(); ++itr)
135 {
136 uint32 mapId = PAIR32_LOPART(itr->first);
137 if (sentMaps.find(mapId) != sentMaps.end())
138 continue;
139
140 MapEntry const* mapEntry = sMapStore.LookupEntry(mapId);
141 if (!mapEntry || !mapEntry->IsRaid())
142 continue;
143
144 sentMaps.insert(mapId);
145
146 dataBuffer << int32(mapId);
147 time_t period = sInstanceSaveMgr->GetExtendedResetTimeFor(mapId, (Difficulty)PAIR32_HIPART(itr->first)) - itr->second;
148 dataBuffer << int32(period); // pussywizard: reset time period
149 dataBuffer << int32(0); // pussywizard: reset time offset, needed for other than 7-day periods if not aligned with relationTime
150 ++boundCounter;
151 }
152
153 data << uint32(boundCounter);
154 data.append(dataBuffer);
155
157 data << uint32(sGameEventMgr->ModifiedHolidays.size());
158 for (uint32 entry : sGameEventMgr->ModifiedHolidays)
159 {
160 HolidaysEntry const* holiday = sHolidaysStore.LookupEntry(entry);
161
162 if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_GAME_EVENT, sGameEventMgr->GetHolidayEventId(holiday->Id), nullptr))
163 {
164 continue;
165 }
166
167 data << uint32(holiday->Id); // m_ID
168 data << uint32(holiday->Region); // m_region, might be looping
169 data << uint32(holiday->Looping); // m_looping, might be region
170 data << uint32(holiday->Priority); // m_priority
171 data << uint32(holiday->CalendarFilterType); // m_calendarFilterType
172
173 for (uint8 j = 0; j < MAX_HOLIDAY_DATES; ++j)
174 data << uint32(holiday->Date[j]); // 26 * m_date -- WritePackedTime ?
175
176 for (uint8 j = 0; j < MAX_HOLIDAY_DURATIONS; ++j)
177 data << uint32(holiday->Duration[j]); // 10 * m_duration
178
179 for (uint8 j = 0; j < MAX_HOLIDAY_FLAGS; ++j)
180 data << uint32(holiday->CalendarFlags[j]); // 10 * m_calendarFlags
181
182 data << holiday->TextureFilename; // m_textureFilename (holiday name)
183 }
184
185 SendPacket(&data);
186}
std::unordered_set< CalendarEvent * > CalendarEventStore
Definition CalendarMgr.h:274
constexpr auto HOUR
Definition Common.h:48
Difficulty
Definition DBCEnums.h:266
#define MAX_DIFFICULTY
Definition DBCEnums.h:283
DBCStorage< HolidaysEntry > sHolidaysStore(Holidaysfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
#define MAX_HOLIDAY_FLAGS
Definition DBCStructure.h:1122
#define MAX_HOLIDAY_DURATIONS
Definition DBCStructure.h:1120
#define MAX_HOLIDAY_DATES
Definition DBCStructure.h:1121
@ DISABLE_TYPE_GAME_EVENT
Definition DisableMgr.h:37
#define sGameEventMgr
Definition GameEventMgr.h:201
std::unordered_map< uint32, InstancePlayerBind > BoundInstancesMap
Definition InstanceSaveMgr.h:46
#define sInstanceSaveMgr
Definition InstanceSaveMgr.h:202
std::unordered_map< uint32, time_t > ResetTimeByMapDifficultyMap
Definition InstanceSaveMgr.h:104
uint16 PAIR32_HIPART(uint32 x)
Definition ObjectDefines.h:93
uint16 PAIR32_LOPART(uint32 x)
Definition ObjectDefines.h:98
@ CONFIG_INSTANCE_RESET_TIME_RELATIVE_TIMESTAMP
Definition WorldConfig.h:204
@ CONFIG_INSTANCE_RESET_TIME_HOUR
Definition WorldConfig.h:203
Definition ByteBuffer.h:70
void clear()
Definition ByteBuffer.h:122
Definition InstanceSaveMgr.h:56
time_t GetExtendedResetTime() const
Definition InstanceSaveMgr.h:76
uint32 GetInstanceId() const
Definition InstanceSaveMgr.h:61
uint32 GetMapId() const
Definition InstanceSaveMgr.h:62
Difficulty GetDifficulty() const
Definition InstanceSaveMgr.h:63
time_t GetResetTime() const
Definition InstanceSaveMgr.h:75
PackedGuid WriteAsPacked() const
Definition ObjectGuid.h:316
@ SMSG_CALENDAR_SEND_CALENDAR
Definition Opcodes.h:1108
ObjectGuid GetCreatorGUID() const
Definition CalendarMgr.h:226
CalendarEventType GetType() const
Definition CalendarMgr.h:238
int32 GetDungeonId() const
Definition CalendarMgr.h:241
std::string GetTitle() const
Definition CalendarMgr.h:232
time_t GetEventTime() const
Definition CalendarMgr.h:244
uint32 GetFlags() const
Definition CalendarMgr.h:247
Definition DBCStructure.h:1125
int32 CalendarFilterType
Definition DBCStructure.h:1136
uint32 Duration[MAX_HOLIDAY_DURATIONS]
Definition DBCStructure.h:1127
uint32 Id
Definition DBCStructure.h:1126
char const * TextureFilename
Definition DBCStructure.h:1134
uint32 Priority
Definition DBCStructure.h:1135
uint32 CalendarFlags[MAX_HOLIDAY_FLAGS]
Definition DBCStructure.h:1131
uint32 Region
Definition DBCStructure.h:1129
uint32 Date[MAX_HOLIDAY_DATES]
Definition DBCStructure.h:1128
uint32 Looping
Definition DBCStructure.h:1130
Definition DBCStructure.h:1323
bool IsRaid() const
Definition DBCStructure.h:1352

References _player, ByteBuffer::append(), ByteBuffer::AppendPackedTime(), HolidaysEntry::CalendarFilterType, HolidaysEntry::CalendarFlags, ByteBuffer::clear(), CONFIG_INSTANCE_RESET_TIME_HOUR, CONFIG_INSTANCE_RESET_TIME_RELATIVE_TIMESTAMP, HolidaysEntry::Date, DISABLE_TYPE_GAME_EVENT, HolidaysEntry::Duration, CalendarEvent::GetCreatorGUID(), InstanceSave::GetDifficulty(), CalendarEvent::GetDungeonId(), CalendarEvent::GetEventId(), CalendarEvent::GetEventTime(), InstanceSave::GetExtendedResetTime(), CalendarEvent::GetFlags(), GameTime::GetGameTime(), Object::GetGUID(), InstanceSave::GetInstanceId(), InstanceSave::GetMapId(), InstanceSave::GetResetTime(), CalendarEvent::GetTitle(), CalendarEvent::GetType(), HOUR, HolidaysEntry::Id, MapEntry::IsRaid(), LOG_DEBUG, HolidaysEntry::Looping, MAX_DIFFICULTY, MAX_HOLIDAY_DATES, MAX_HOLIDAY_DURATIONS, MAX_HOLIDAY_FLAGS, PAIR32_HIPART(), PAIR32_LOPART(), HolidaysEntry::Priority, HolidaysEntry::Region, sCalendarMgr, sDisableMgr, SendPacket(), sGameEventMgr, sHolidaysStore, sInstanceSaveMgr, sMapStore, SMSG_CALENDAR_SEND_CALENDAR, sWorld, HolidaysEntry::TextureFilename, ObjectGuid::ToString(), and ObjectGuid::WriteAsPacked().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarGetEvent()

void WorldSession::HandleCalendarGetEvent ( WorldPackets::Calendar::GetEvent packet)
189{
190 LOG_DEBUG("network", "CMSG_CALENDAR_GET_EVENT. Player [{}] Event [{}]", _player->GetGUID().ToString(), packet.EventId);
191
192 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(packet.EventId))
193 sCalendarMgr->SendCalendarEvent(_player->GetGUID(), *calendarEvent, CALENDAR_SENDTYPE_GET);
194 else
195 sCalendarMgr->SendCalendarCommandResult(_player->GetGUID(), CALENDAR_ERROR_EVENT_INVALID);
196}
@ CALENDAR_SENDTYPE_GET
Definition CalendarMgr.h:52
uint64 EventId
Definition CalendarPackets.h:35

References _player, CALENDAR_ERROR_EVENT_INVALID, CALENDAR_SENDTYPE_GET, WorldPackets::Calendar::GetEvent::EventId, Object::GetGUID(), LOG_DEBUG, sCalendarMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarGetNumPending()

void WorldSession::HandleCalendarGetNumPending ( WorldPacket recvData)
765{
766 ObjectGuid guid = _player->GetGUID();
767 uint32 pending = sCalendarMgr->GetPlayerNumPending(guid);
768
769 LOG_DEBUG("network", "CMSG_CALENDAR_GET_NUM_PENDING: [{}] Pending: {}", guid.ToString(), pending);
770
772 data << uint32(pending);
773 SendPacket(&data);
774}
@ SMSG_CALENDAR_SEND_NUM_PENDING
Definition Opcodes.h:1126

References _player, Object::GetGUID(), LOG_DEBUG, sCalendarMgr, SendPacket(), SMSG_CALENDAR_SEND_NUM_PENDING, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarGuildFilter()

void WorldSession::HandleCalendarGuildFilter ( WorldPackets::Calendar::GuildFilter packet)
199{
200 LOG_DEBUG("network", "CMSG_CALENDAR_GUILD_FILTER [{}]", _player->GetGUID().ToString());
201
202 if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
203 guild->MassInviteToEvent(this, packet.MinimumLevel, packet.MaximumLevel, packet.MinimumRank);
204
205 LOG_DEBUG("network", "CMSG_CALENDAR_GUILD_FILTER: Min level [{}], Max level [{}], Min rank [{}]", packet.MinimumLevel, packet.MaximumLevel, packet.MinimumRank);
206}
#define sGuildMgr
Definition GuildMgr.h:51
Definition Guild.h:292
uint32 MinimumLevel
Definition CalendarPackets.h:45
uint32 MinimumRank
Definition CalendarPackets.h:47
uint32 MaximumLevel
Definition CalendarPackets.h:46

References _player, Object::GetGUID(), Player::GetGuildId(), LOG_DEBUG, WorldPackets::Calendar::GuildFilter::MaximumLevel, WorldPackets::Calendar::GuildFilter::MinimumLevel, WorldPackets::Calendar::GuildFilter::MinimumRank, sGuildMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarRemoveEvent()

void WorldSession::HandleCalendarRemoveEvent ( WorldPacket recvData)
415{
416 ObjectGuid guid = _player->GetGUID();
417 uint64 eventId;
418
419 recvData >> eventId;
420 recvData.rfinish(); // Skip flags & invite ID, we don't use them
421
422 sCalendarMgr->RemoveEvent(eventId, guid);
423}

References _player, Object::GetGUID(), ByteBuffer::rfinish(), and sCalendarMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarUpdateEvent()

void WorldSession::HandleCalendarUpdateEvent ( WorldPacket recvData)
358{
359 ObjectGuid guid = _player->GetGUID();
360 time_t oldEventTime;
361
362 uint64 eventId;
363 uint64 inviteId;
364 std::string title;
365 std::string description;
366 uint8 type;
367 uint8 repetitionType;
368 uint32 maxInvites;
369 int32 dungeonId;
370 uint32 eventPackedTime;
371 uint32 timeZoneTime;
372 uint32 flags;
373
374 recvData >> eventId >> inviteId >> title >> description >> type >> repetitionType >> maxInvites >> dungeonId;
375 recvData.ReadPackedTime(eventPackedTime);
376 recvData.ReadPackedTime(timeZoneTime);
377 recvData >> flags;
378
379 // prevent attacks with non-utf8 chars -> with multiple packets it will hang up the db due to errors.
380 if (!validUtf8String(recvData, title, "update", guid) || title.size() > 31 || !validUtf8String(recvData, description, "update", guid) || description.size() > 255)
381 return;
382
383 // prevent events in the past
384 // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
385 if (time_t(eventPackedTime) < (GameTime::GetGameTime().count() - time_t(86400L)))
386 {
387 recvData.rfinish();
388 return;
389 }
390
391 LOG_DEBUG("network", "CMSG_CALENDAR_UPDATE_EVENT [{}] EventId [{}], InviteId [{}] Title {}, Description {}, type {} "
392 "Repeatable {}, MaxInvites {}, Dungeon ID {}, Time {} Time2 {}, Flags {}",
393 guid.ToString(), eventId, inviteId, title, description, type, repetitionType, maxInvites, dungeonId, eventPackedTime, timeZoneTime, flags);
394
395 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
396 {
397 oldEventTime = calendarEvent->GetEventTime();
398
399 calendarEvent->SetType(CalendarEventType(type));
400 calendarEvent->SetFlags(flags);
401 calendarEvent->SetEventTime(time_t(eventPackedTime));
402 calendarEvent->SetTimeZoneTime(time_t(timeZoneTime)); // Not sure, seems constant from the little sniffs we have
403 calendarEvent->SetDungeonId(dungeonId);
404 calendarEvent->SetTitle(title);
405 calendarEvent->SetDescription(description);
406
407 sCalendarMgr->UpdateEvent(calendarEvent);
408 sCalendarMgr->SendCalendarEventUpdateAlert(*calendarEvent, oldEventTime);
409 }
410 else
411 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
412}

References _player, CALENDAR_ERROR_EVENT_INVALID, GameTime::GetGameTime(), Object::GetGUID(), LOG_DEBUG, ByteBuffer::ReadPackedTime(), ByteBuffer::rfinish(), sCalendarMgr, ObjectGuid::ToString(), and validUtf8String().

Referenced by OpcodeTable::Initialize().

◆ HandleCancelAuraOpcode()

void WorldSession::HandleCancelAuraOpcode ( WorldPacket recvPacket)
565{
566 uint32 spellId;
567 recvPacket >> spellId;
568
569 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
570 if (!spellInfo)
571 return;
572
573 // not allow remove spells with attr SPELL_ATTR0_NO_AURA_CANCEL
575 {
576 return;
577 }
578
579 // channeled spell case (it currently casted then)
580 if (spellInfo->IsChanneled())
581 {
583 if (curSpell->m_spellInfo->Id == spellId)
585 return;
586 }
587
588 // non channeled case:
589 // don't allow remove non positive spells
590 // don't allow cancelling passive auras (some of them are visible)
591 if (!spellInfo->IsPositive() || spellInfo->IsPassive())
592 {
593 return;
594 }
595
596 // maybe should only remove one buff when there are multiple?
598}
@ SPELL_ATTR0_NO_AURA_CANCEL
Definition SharedDefines.h:424
@ AURA_REMOVE_BY_CANCEL
Definition SpellAuraDefines.h:393
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:546
bool IsPassive() const
Definition SpellInfo.cpp:1098
bool IsChanneled() const
Definition SpellInfo.cpp:1256
bool HasAttribute(SpellAttr0 attribute) const
Definition SpellInfo.h:415
bool IsPositive() const
Definition SpellInfo.cpp:1237
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4824
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition Unit.cpp:4104
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition Unit.h:1561

References _player, AURA_REMOVE_BY_CANCEL, CURRENT_CHANNELED_SPELL, ObjectGuid::Empty, Unit::GetCurrentSpell(), SpellInfo::HasAttribute(), Unit::InterruptSpell(), SpellInfo::IsChanneled(), SpellInfo::IsPassive(), SpellInfo::IsPositive(), Unit::RemoveOwnedAura(), SPELL_ATTR0_NO_AURA_CANCEL, and sSpellMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleCancelAutoRepeatSpellOpcode()

void WorldSession::HandleCancelAutoRepeatSpellOpcode ( WorldPacket recvPacket)
643{
644 // may be better send SMSG_CANCEL_AUTO_REPEAT?
645 // cancel and prepare for deleting
647}
@ CURRENT_AUTOREPEAT_SPELL
Definition Unit.h:547

References _player, CURRENT_AUTOREPEAT_SPELL, and Unit::InterruptSpell().

Referenced by OpcodeTable::Initialize().

◆ HandleCancelCastOpcode()

void WorldSession::HandleCancelCastOpcode ( WorldPacket recvPacket)
551{
552 uint32 spellId;
553
554 recvPacket.read_skip<uint8>(); // counter, increments with every CANCEL packet, don't use for now
555 recvPacket >> spellId;
556
557 _player->SpellQueue.clear();
558
560 if (_player->IsNonMeleeSpellCast(false))
561 _player->InterruptNonMeleeSpells(false, spellId, false, true);
562}
@ CURRENT_MELEE_SPELL
Definition Unit.h:544
std::deque< PendingSpellCastRequest > SpellQueue
Definition Player.h:2663
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true, bool bySelf=false)
Definition Unit.cpp:4176
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition Unit.cpp:4146

References _player, CURRENT_MELEE_SPELL, Unit::InterruptNonMeleeSpells(), Unit::InterruptSpell(), Unit::IsNonMeleeSpellCast(), ByteBuffer::read_skip(), and Player::SpellQueue.

Referenced by OpcodeTable::Initialize().

◆ HandleCancelChanneling()

void WorldSession::HandleCancelChanneling ( WorldPacket recvData)
650{
651 uint32 spellID = 0;
652 recvData >> spellID;
653
654 // ignore for remote control state (for player case)
655 Unit* mover = _player->m_mover;
656 if (!mover)
657 {
658 return;
659 }
660
661 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID);
662 if (!spellInfo)
663 {
664 return;
665 }
666
667 // not allow remove spells with attr SPELL_ATTR0_NO_AURA_CANCEL
669 {
670 return;
671 }
672
674 if (!spell || spell->GetSpellInfo()->Id != spellInfo->Id)
675 {
676 return;
677 }
678
680}
SafeUnitPointer m_mover
Definition Player.h:2347
uint32 Id
Definition SpellInfo.h:320
SpellInfo const * GetSpellInfo() const
Definition Spell.h:587

References _player, CURRENT_CHANNELED_SPELL, Unit::GetCurrentSpell(), Spell::GetSpellInfo(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::InterruptSpell(), Player::m_mover, SPELL_ATTR0_NO_AURA_CANCEL, and sSpellMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleCancelGrowthAuraOpcode()

void WorldSession::HandleCancelGrowthAuraOpcode ( WorldPacket recvPacket)
639{
640}

Referenced by OpcodeTable::Initialize().

◆ HandleCancelMountAuraOpcode()

void WorldSession::HandleCancelMountAuraOpcode ( WorldPacket recvData)
1470{
1471 LOG_DEBUG("network", "WORLD: CMSG_CANCEL_MOUNT_AURA");
1472
1473 //If player is not mounted, so go out :)
1474 if (!_player->IsMounted()) // not blizz like; no any messages on blizz
1475 {
1477 return;
1478 }
1479
1480 if (_player->IsInFlight()) // not blizz like; no any messages on blizz
1481 {
1483 return;
1484 }
1485
1486 _player->Dismount();
1488}
@ LANG_CHAR_NON_MOUNTED
Definition Language.h:54
@ LANG_YOU_IN_FLIGHT
Definition Language.h:50
@ SPELL_AURA_MOUNTED
Definition SpellAuraDefines.h:141
virtual void SendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition Chat.cpp:160
void Dismount()
Definition Unit.cpp:13674
bool IsMounted() const
Definition Unit.h:1866

References _player, Unit::Dismount(), Unit::IsInFlight(), Unit::IsMounted(), LANG_CHAR_NON_MOUNTED, LANG_YOU_IN_FLIGHT, LOG_DEBUG, Unit::RemoveAurasByType(), ChatHandler::SendSysMessage(), and SPELL_AURA_MOUNTED.

Referenced by OpcodeTable::Initialize().

◆ HandleCancelTempEnchantmentOpcode()

void WorldSession::HandleCancelTempEnchantmentOpcode ( WorldPackets::Item::CancelTempEnchantment packet)
1400{
1401 LOG_DEBUG("network", "WORLD: CMSG_CANCEL_TEMP_ENCHANTMENT");
1402
1403 // apply only to equipped item
1405 return;
1406
1408
1409 if (!item)
1410 return;
1411
1413 return;
1414
1417}
@ TEMP_ENCHANTMENT_SLOT
Definition Item.h:170
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition Item.h:304
void ClearEnchantment(EnchantmentSlot slot)
Definition Item.cpp:960
uint32 EquipmentSlot
Definition ItemPackets.h:247

References Player::ApplyEnchantment(), Item::ClearEnchantment(), WorldPackets::Item::CancelTempEnchantment::EquipmentSlot, Item::GetEnchantmentId(), Player::GetItemByPos(), GetPlayer(), INVENTORY_SLOT_BAG_0, Player::IsEquipmentPos(), LOG_DEBUG, and TEMP_ENCHANTMENT_SLOT.

Referenced by OpcodeTable::Initialize().

◆ HandleCancelTradeOpcode()

void WorldSession::HandleCancelTradeOpcode ( WorldPacket recvPacket)
536{
537 // sended also after LOGOUT COMPLETE
538 if (_player) // needed because STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT
539 _player->TradeCancel(true);
540}

References _player, and Player::TradeCancel().

Referenced by OpcodeTable::Initialize().

◆ HandleCastSpellOpcode()

void WorldSession::HandleCastSpellOpcode ( WorldPacket recvPacket)
Todo:
: Preparation for #23204
377{
378 uint32 spellId;
379 uint8 castCount, castFlags;
380
381 if (recvPacket.empty())
382 return;
383
384 recvPacket >> castCount >> spellId >> castFlags;
385 TriggerCastFlags triggerFlag = TRIGGERED_NONE;
386
387 uint32 oldSpellId = spellId;
388
389 LOG_DEBUG("network", "WORLD: got cast spell packet, castCount: {}, spellId: {}, castFlags: {}, data length = {}", castCount, spellId, castFlags, (uint32)recvPacket.size());
390
391 // ignore for remote control state (for player case)
392 Unit* mover = _player->m_mover;
393 if (mover != _player && mover->IsPlayer())
394 {
395 recvPacket.rfinish(); // prevent spam at ignore packet
396 return;
397 }
398
399 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
400
401 if (!spellInfo)
402 {
403 LOG_ERROR("network.opcode", "WORLD: unknown spell id {}", spellId);
404 recvPacket.rfinish(); // prevent spam at ignore packet
405 return;
406 }
407
408 // fail if we are cancelling pending request
409 if (!_player->SpellQueue.empty())
410 {
411 PendingSpellCastRequest& request = _player->SpellQueue.front(); // Peek at the first spell
412 if (request.cancelInProgress)
413 {
414 Spell* spell = new Spell(_player, spellInfo, TRIGGERED_NONE);
415 spell->m_cast_count = castCount;
417 spell->finish(false);
418 recvPacket.rfinish(); // prevent spam at ignore packet
419 return;
420 }
421 }
422
423 // try queue spell if it can't be executed right now
425 {
426 if (_player->CanRequestSpellCast(spellInfo))
427 {
428 WorldPacket packetCopy(recvPacket); // Copy the packet
429 packetCopy.rpos(0); // Reset read position to the start of the buffer.
430 _player->SpellQueue.emplace_back(
431 spellId,
432 spellInfo->GetCategory(),
433 std::move(packetCopy) // Move ownership of copied packet
434 );
435 return;
436 }
437 }
438
439 // client provided targets
440 SpellCastTargets targets;
441 targets.Read(recvPacket, mover);
442 HandleClientCastFlags(recvPacket, castFlags, targets);
443
444 // not have spell in spellbook
445 if (mover->IsPlayer())
446 {
447 // not have spell in spellbook or spell passive and not casted by client
448 if (!(spellInfo->Targets & TARGET_FLAG_GAMEOBJECT_ITEM) && (!mover->ToPlayer()->HasActiveSpell(spellId) || spellInfo->IsPassive()))
449 {
450 bool allow = false;
451
452 // allow casting of unknown spells for special lock cases
453 if (GameObject* go = targets.GetGOTarget())
454 {
455 if (go->GetSpellForLock(mover->ToPlayer()) == spellInfo)
456 {
457 allow = true;
458 }
459 }
460
462 // allow casting of spells triggered by clientside periodic trigger auras
463 /*
464 if (caster->HasAuraTypeWithTriggerSpell(SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT, spellId))
465 {
466 allow = true;
467 triggerFlag = TRIGGERED_FULL_MASK;
468 }
469 */
470
471 if (!allow)
472 return;
473 }
474 }
475 else
476 {
477 // pussywizard: casting player's spells from vehicle when seat allows it
478 // if ANYTHING CHANGES in this function, INFORM ME BEFORE applying!!!
479 if (Vehicle* veh = mover->GetVehicleKit())
480 if (const VehicleSeatEntry* seat = veh->GetSeatForPassenger(_player))
481 if (seat->m_flags & VEHICLE_SEAT_FLAG_CAN_ATTACK || spellInfo->Effects[EFFECT_0].Effect == SPELL_EFFECT_OPEN_LOCK /*allow looting from vehicle, but only if player has required spell (all necessary opening spells are in playercreateinfo_spell)*/)
482 if ((mover->IsCreature() && !mover->ToCreature()->HasSpell(spellId)) || spellInfo->IsPassive()) // the creature can't cast that spell, check player instead
483 {
484 if (!(spellInfo->Targets & TARGET_FLAG_GAMEOBJECT_ITEM) && (!_player->HasActiveSpell (spellId) || spellInfo->IsPassive()))
485 {
486 //cheater? kick? ban?
487 recvPacket.rfinish(); // prevent spam at ignore packet
488 return;
489 }
490
491 // at this point, player is a valid caster
492 // swapping the mover will stop the check below at IsUnit, so everything works fine
493 mover = _player;
494 }
495
496 // not have spell in spellbook or spell passive and not casted by client
497 if ((mover->IsCreature() && !mover->ToCreature()->HasSpell(spellId)) || spellInfo->IsPassive())
498 {
499 //cheater? kick? ban?
500 recvPacket.rfinish(); // prevent spam at ignore packet
501 return;
502 }
503 }
504
505 sScriptMgr->ValidateSpellAtCastSpell(_player, oldSpellId, spellId, castCount, castFlags);
506
507 if (oldSpellId != spellId)
508 spellInfo = sSpellMgr->GetSpellInfo(spellId);
509
510 // Client is resending autoshot cast opcode when other spell is casted during shoot rotation
511 // Skip it to prevent "interrupt" message
514 {
515 recvPacket.rfinish();
516 return;
517 }
518
519 // can't use our own spells when we're in possession of another unit,
520 if (_player->isPossessing())
521 {
522 return;
523 }
524
525 // pussywizard: HandleClientCastFlags calls HandleMovementOpcodes, which can result in pretty much anything. Caster not in map will crash at GetMap() for spell difficulty in Spell constructor.
526 if (!mover->FindMap())
527 {
528 recvPacket.rfinish(); // prevent spam at ignore packet
529 return;
530 }
531
532 // auto-selection buff level base at target level (in spellInfo)
533 if (targets.GetUnitTarget())
534 {
535 SpellInfo const* actualSpellInfo = spellInfo->GetAuraRankForLevel(targets.GetUnitTarget()->GetLevel());
536
537 // if rank not found then function return nullptr but in explicit cast case original spell can be casted and later failed with appropriate error message
538 if (actualSpellInfo)
539 spellInfo = actualSpellInfo;
540 }
541
542 Spell* spell = new Spell(mover, spellInfo, triggerFlag, ObjectGuid::Empty, false);
543
544 sScriptMgr->ValidateSpellAtCastSpellResult(_player, mover, spell, oldSpellId, spellId);
545
546 spell->m_cast_count = castCount; // set count of casts
547 spell->prepare(&targets);
548}
@ EFFECT_0
Definition SharedDefines.h:31
@ SPELL_EFFECT_OPEN_LOCK
Definition SharedDefines.h:822
@ SPELL_FAILED_DONT_REPORT
Definition SharedDefines.h:987
TriggerCastFlags
Definition SpellDefines.h:132
@ TRIGGERED_NONE
Definition SpellDefines.h:133
@ TARGET_FLAG_GAMEOBJECT_ITEM
Definition SpellInfo.h:60
bool empty() const
Definition ByteBuffer.h:445
bool HasSpell(uint32 spellID) const override
Definition Creature.cpp:2935
bool IsPlayer() const
Definition Object.h:200
Player * ToPlayer()
Definition Object.h:201
bool IsCreature() const
Definition Object.h:204
Creature * ToCreature()
Definition Object.h:205
bool CanExecutePendingSpellCastRequest(SpellInfo const *spellInfo)
Definition PlayerUpdates.cpp:2297
bool HasActiveSpell(uint32 spell) const
Definition Player.cpp:3898
bool CanRequestSpellCast(SpellInfo const *spellInfo)
Definition PlayerUpdates.cpp:2323
GameObject * GetGOTarget() const
Definition Spell.cpp:263
void Read(ByteBuffer &data, Unit *caster)
Definition Spell.cpp:125
Unit * GetUnitTarget() const
Definition Spell.cpp:231
uint32 GetCategory() const
Definition SpellInfo.cpp:871
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition SpellInfo.cpp:2422
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition SpellInfo.h:393
uint32 Targets
Definition SpellInfo.h:335
bool IsAutoRepeatRangedSpell() const
Definition SpellInfo.cpp:1283
uint8 m_cast_count
Definition Spell.h:535
void finish(bool ok=true)
Definition Spell.cpp:4427
SpellInfo const *const m_spellInfo
Definition Spell.h:531
bool isPossessing() const
Definition Unit.h:1298
Vehicle * GetVehicleKit() const
Definition Unit.h:1904
Map * FindMap() const
Definition Object.h:621
void HandleClientCastFlags(WorldPacket &recvPacket, uint8 castFlags, SpellCastTargets &targets)
Definition SpellHandler.cpp:35
Definition Player.h:1059
bool cancelInProgress
Definition Player.h:1064

References _player, PendingSpellCastRequest::cancelInProgress, Player::CanExecutePendingSpellCastRequest(), Player::CanRequestSpellCast(), CURRENT_AUTOREPEAT_SPELL, EFFECT_0, SpellInfo::Effects, ObjectGuid::Empty, ByteBuffer::empty(), WorldObject::FindMap(), Spell::finish(), SpellInfo::GetAuraRankForLevel(), SpellInfo::GetCategory(), Unit::GetCurrentSpell(), SpellCastTargets::GetGOTarget(), Unit::GetLevel(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicleKit(), HandleClientCastFlags(), Player::HasActiveSpell(), Creature::HasSpell(), SpellInfo::IsAutoRepeatRangedSpell(), Object::IsCreature(), SpellInfo::IsPassive(), Object::IsPlayer(), Unit::isPossessing(), LOG_DEBUG, LOG_ERROR, Spell::m_cast_count, Player::m_mover, Spell::m_spellInfo, Spell::prepare(), SpellCastTargets::Read(), ByteBuffer::rfinish(), ByteBuffer::rpos(), Spell::SendCastResult(), ByteBuffer::size(), SPELL_EFFECT_OPEN_LOCK, SPELL_FAILED_DONT_REPORT, Player::SpellQueue, sScriptMgr, sSpellMgr, TARGET_FLAG_GAMEOBJECT_ITEM, SpellInfo::Targets, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_NONE, and VEHICLE_SEAT_FLAG_CAN_ATTACK.

Referenced by OpcodeTable::Initialize().

◆ HandleChangeSeatsOnControlledVehicle()

void WorldSession::HandleChangeSeatsOnControlledVehicle ( WorldPacket recvData)
62{
63 LOG_DEBUG("network", "WORLD: Recvd CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE");
64
65 Unit* vehicle_base = GetPlayer()->GetVehicleBase();
66 if (!vehicle_base)
67 {
68 recvData.rfinish(); // prevent warnings spam
69 return;
70 }
71
73 if (!seat->CanSwitchFromSeat())
74 {
75 recvData.rfinish(); // prevent warnings spam
76 LOG_ERROR("network.opcode", "HandleChangeSeatsOnControlledVehicle, Opcode: {}, Player {} tried to switch seats but current seatflags {} don't permit that.",
77 recvData.GetOpcode(), GetPlayer()->GetGUID().ToString(), seat->m_flags);
78 return;
79 }
80
81 switch (recvData.GetOpcode())
82 {
84 GetPlayer()->ChangeSeat(-1, false);
85 break;
87 GetPlayer()->ChangeSeat(-1, true);
88 break;
90 {
91 ObjectGuid guid; // current vehicle guid
92 recvData >> guid.ReadAsPacked();
93
94 // pussywizard:
95 if (vehicle_base->GetGUID() != guid)
96 {
97 recvData.rfinish(); // prevent warnings spam
98 return;
99 }
100
101 MovementInfo movementInfo;
102 movementInfo.guid = guid;
103 ReadMovementInfo(recvData, &movementInfo);
104 vehicle_base->m_movementInfo = movementInfo;
105
106 ObjectGuid accessory; // accessory guid
107 recvData >> accessory.ReadAsPacked();
108
109 int8 seatId;
110 recvData >> seatId;
111
112 if (!accessory)
113 GetPlayer()->ChangeSeat(-1, seatId > 0); // prev/next
114 else if (Unit* vehUnit = ObjectAccessor::GetUnit(*GetPlayer(), accessory))
115 {
116 if (Vehicle* vehicle = vehUnit->GetVehicleKit())
117 if (vehicle->HasEmptySeat(seatId))
118 vehUnit->HandleSpellClick(GetPlayer(), seatId);
119 }
120 break;
121 }
123 {
124 ObjectGuid guid; // current vehicle guid
125 recvData >> guid.ReadAsPacked();
126
127 int8 seatId;
128 recvData >> seatId;
129
130 if (vehicle_base->GetGUID() == guid)
131 GetPlayer()->ChangeSeat(seatId);
132 else if (Unit* vehUnit = ObjectAccessor::GetUnit(*GetPlayer(), guid))
133 if (Vehicle* vehicle = vehUnit->GetVehicleKit())
134 if (vehicle->HasEmptySeat(seatId))
135 vehUnit->HandleSpellClick(GetPlayer(), seatId);
136 break;
137 }
138 default:
139 break;
140 }
141}
std::int8_t int8
Definition Define.h:105
Unit * GetVehicleBase() const
Definition Unit.cpp:18989
void ChangeSeat(int8 seatId, bool next=true)
Definition Unit.cpp:19694
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition Vehicle.cpp:600
void ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
Definition WorldSession.cpp:999
@ CMSG_REQUEST_VEHICLE_SWITCH_SEAT
Definition Opcodes.h:1175
@ CMSG_REQUEST_VEHICLE_NEXT_SEAT
Definition Opcodes.h:1174
@ CMSG_REQUEST_VEHICLE_PREV_SEAT
Definition Opcodes.h:1173
@ CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE
Definition Opcodes.h:1209
Definition Object.h:287
ObjectGuid guid
Definition Object.h:289
bool CanSwitchFromSeat() const
Definition DBCStructure.h:2117

References VehicleSeatEntry::CanSwitchFromSeat(), Unit::ChangeSeat(), CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE, CMSG_REQUEST_VEHICLE_NEXT_SEAT, CMSG_REQUEST_VEHICLE_PREV_SEAT, CMSG_REQUEST_VEHICLE_SWITCH_SEAT, Object::GetGUID(), WorldPacket::GetOpcode(), GetPlayer(), Vehicle::GetSeatForPassenger(), ObjectAccessor::GetUnit(), Unit::GetVehicle(), Unit::GetVehicleBase(), MovementInfo::guid, LOG_DEBUG, LOG_ERROR, VehicleSeatEntry::m_flags, WorldObject::m_movementInfo, ObjectGuid::ReadAsPacked(), ReadMovementInfo(), and ByteBuffer::rfinish().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelAnnouncements()

void WorldSession::HandleChannelAnnouncements ( WorldPacket recvPacket)
249{
250 std::string channelName;
251 recvPacket >> channelName;
252
253 LOG_DEBUG("chat.system", "CMSG_CHANNEL_ANNOUNCEMENTS {} Channel: {}",
254 GetPlayerInfo(), channelName);
256 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
257 channel->Announce(GetPlayer());
258}
Definition ChannelMgr.h:29
static ChannelMgr * forTeam(TeamId teamId)
Definition ChannelMgr.cpp:33
Definition Channel.h:144

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleChannelBan()

void WorldSession::HandleChannelBan ( WorldPacket recvPacket)
219{
220 std::string channelName, targetName;
221 recvPacket >> channelName >> targetName;
222
223 LOG_DEBUG("chat.system", "CMSG_CHANNEL_BAN {} Channel: {}, Target: {}",
224 GetPlayerInfo(), channelName, targetName);
225 if (!normalizePlayerName(targetName))
226 return;
227
229 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
230 channel->Ban(GetPlayer(), targetName);
231}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelDeclineInvite()

void WorldSession::HandleChannelDeclineInvite ( WorldPacket recvPacket)
766{
767 // used only with EXTRA_LOGS
768 (void)recvPacket;
769
770 LOG_DEBUG("network", "Opcode {}", recvPacket.GetOpcode());
771}

References WorldPacket::GetOpcode(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleChannelDisplayListQuery()

void WorldSession::HandleChannelDisplayListQuery ( WorldPacket recvPacket)
274{
275 // this should be OK because the 2 function _were_ the same
276 HandleChannelList(recvPacket);
277}
void HandleChannelList(WorldPacket &recvPacket)
Definition ChannelHandler.cpp:73

References HandleChannelList().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelInvite()

void WorldSession::HandleChannelInvite ( WorldPacket recvPacket)
189{
190 std::string channelName, targetName;
191 recvPacket >> channelName >> targetName;
192
193 LOG_DEBUG("chat.system", "CMSG_CHANNEL_INVITE {} Channel: {}, Target: {}",
194 GetPlayerInfo(), channelName, targetName);
195 if (!normalizePlayerName(targetName))
196 return;
197
199 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
200 channel->Invite(GetPlayer(), targetName);
201}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelKick()

void WorldSession::HandleChannelKick ( WorldPacket recvPacket)
204{
205 std::string channelName, targetName;
206 recvPacket >> channelName >> targetName;
207
208 LOG_DEBUG("chat.system", "CMSG_CHANNEL_KICK {} Channel: {}, Target: {}",
209 GetPlayerInfo(), channelName, targetName);
210 if (!normalizePlayerName(targetName))
211 return;
212
214 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
215 channel->Kick(GetPlayer(), targetName);
216}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelList()

void WorldSession::HandleChannelList ( WorldPacket recvPacket)
74{
75 std::string channelName;
76 recvPacket >> channelName;
77
78 LOG_DEBUG("chat.system", "{} {} Channel: {}",
79 recvPacket.GetOpcode() == CMSG_CHANNEL_DISPLAY_LIST ? "CMSG_CHANNEL_DISPLAY_LIST" : "CMSG_CHANNEL_LIST",
80 GetPlayerInfo(), channelName);
82 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
83 channel->List(GetPlayer());
84}
@ CMSG_CHANNEL_DISPLAY_LIST
Definition Opcodes.h:1008

References CMSG_CHANNEL_DISPLAY_LIST, ChannelMgr::forTeam(), WorldPacket::GetOpcode(), GetPlayer(), GetPlayerInfo(), GetTeamId(), and LOG_DEBUG.

Referenced by HandleChannelDisplayListQuery(), and OpcodeTable::Initialize().

◆ HandleChannelModerateOpcode()

void WorldSession::HandleChannelModerateOpcode ( WorldPacket recvPacket)
261{
262 std::string channelName;
263 recvPacket >> channelName;
264
265 LOG_DEBUG("chat.system", "CMSG_CHANNEL_MODERATE {} Channel: {}",
266 GetPlayerInfo(), channelName);
267
269 if (Channel* chn = cMgr->GetChannel(channelName, GetPlayer()))
270 chn->ToggleModeration(GetPlayer());
271}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleChannelModerator()

void WorldSession::HandleChannelModerator ( WorldPacket recvPacket)
129{
130 std::string channelName, targetName;
131 recvPacket >> channelName >> targetName;
132
133 LOG_DEBUG("chat.system", "CMSG_CHANNEL_MODERATOR {} Channel: {}, Target: {}",
134 GetPlayerInfo(), channelName, targetName);
135 if (!normalizePlayerName(targetName))
136 return;
137
139 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
140 channel->SetModerator(GetPlayer(), targetName);
141}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelMute()

void WorldSession::HandleChannelMute ( WorldPacket recvPacket)
159{
160 std::string channelName, targetName;
161 recvPacket >> channelName >> targetName;
162
163 LOG_DEBUG("chat.system", "CMSG_CHANNEL_MUTE {} Channel: {}, Target: {}",
164 GetPlayerInfo(), channelName, targetName);
165 if (!normalizePlayerName(targetName))
166 return;
167
169 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
170 channel->SetMute(GetPlayer(), targetName);
171}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelOwner()

void WorldSession::HandleChannelOwner ( WorldPacket recvPacket)
117{
118 std::string channelName;
119 recvPacket >> channelName;
120
121 LOG_DEBUG("chat.system", "CMSG_CHANNEL_OWNER {} Channel: {}",
122 GetPlayerInfo(), channelName);
124 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
125 channel->SendWhoOwner(GetPlayer()->GetGUID());
126}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleChannelPassword()

void WorldSession::HandleChannelPassword ( WorldPacket recvPacket)
87{
88 std::string channelName, password;
89 recvPacket >> channelName >> password;
90
91 LOG_DEBUG("chat.system", "CMSG_CHANNEL_PASSWORD {} Channel: {}, Password: {}",
92 GetPlayerInfo(), channelName, password);
93 if (password.length() > MAX_CHANNEL_PASS_STR)
94 return;
95
97 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
98 channel->Password(GetPlayer(), password);
99}
#define MAX_CHANNEL_PASS_STR
Definition ChannelMgr.h:26

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and MAX_CHANNEL_PASS_STR.

Referenced by OpcodeTable::Initialize().

◆ HandleChannelSetOwner()

void WorldSession::HandleChannelSetOwner ( WorldPacket recvPacket)
102{
103 std::string channelName, targetName;
104 recvPacket >> channelName >> targetName;
105
106 LOG_DEBUG("chat.system", "CMSG_CHANNEL_SET_OWNER {} Channel: {}, Target: {}",
107 GetPlayerInfo(), channelName, targetName);
108 if (!normalizePlayerName(targetName))
109 return;
110
112 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
113 channel->SetOwner(GetPlayer(), targetName);
114}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelUnban()

void WorldSession::HandleChannelUnban ( WorldPacket recvPacket)
234{
235 std::string channelName, targetName;
236 recvPacket >> channelName >> targetName;
237
238 LOG_DEBUG("chat.system", "CMSG_CHANNEL_UNBAN {} Channel: {}, Target: {}",
239 GetPlayerInfo(), channelName, targetName);
240 if (!normalizePlayerName(targetName))
241 return;
242
244 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
245 channel->UnBan(GetPlayer(), targetName);
246}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelUnmoderator()

void WorldSession::HandleChannelUnmoderator ( WorldPacket recvPacket)
144{
145 std::string channelName, targetName;
146 recvPacket >> channelName >> targetName;
147
148 LOG_DEBUG("chat.system", "CMSG_CHANNEL_UNMODERATOR {} Channel: {}, Target: {}",
149 GetPlayerInfo(), channelName, targetName);
150 if (!normalizePlayerName(targetName))
151 return;
152
154 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
155 channel->UnsetModerator(GetPlayer(), targetName);
156}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelUnmute()

void WorldSession::HandleChannelUnmute ( WorldPacket recvPacket)
174{
175 std::string channelName, targetName;
176 recvPacket >> channelName >> targetName;
177
178 LOG_DEBUG("chat.system", "CMSG_CHANNEL_UNMUTE {} Channel: {}, Target: {}",
179 GetPlayerInfo(), channelName, targetName);
180 if (!normalizePlayerName(targetName))
181 return;
182
184 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
185 channel->UnsetMute(GetPlayer(), targetName);
186}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelVoiceOnOpcode()

void WorldSession::HandleChannelVoiceOnOpcode ( WorldPacket recvData)
32{
33 LOG_DEBUG("network", "WORLD: CMSG_CHANNEL_VOICE_ON");
34 // Enable Voice button in channel context menu
35}

References LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleCharacterAuraFrozen()

void WorldSession::HandleCharacterAuraFrozen ( PreparedQueryResult  result)
593{
594 if (!GetPlayer())
595 return;
596
597 ChatHandler handler = ChatHandler(this);
598
599 // Select
600 if (!result)
601 {
603 return;
604 }
605
606 // Header of the names
608
609 // Output of the results
610 do
611 {
612 Field* fields = result->Fetch();
613 std::string player = fields[0].Get<std::string>();
615 } while (result->NextRow());
616}
@ LANG_COMMAND_LIST_FREEZE
Definition Language.h:1060
@ LANG_COMMAND_NO_FROZEN_PLAYERS
Definition Language.h:1059
@ LANG_COMMAND_FROZEN_PLAYERS
Definition Language.h:1061
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition Field.h:112

References Field::Get(), GetPlayer(), LANG_COMMAND_FROZEN_PLAYERS, LANG_COMMAND_LIST_FREEZE, LANG_COMMAND_NO_FROZEN_PLAYERS, ChatHandler::PSendSysMessage(), and ChatHandler::SendSysMessage().

◆ HandleCharCreateOpcode()

void WorldSession::HandleCharCreateOpcode ( WorldPacket recvPacket)
Todo:
what to if account already has characters of both races?
Todo:
check if cinematic already shown? (already logged in?; cinematic field)
273{
274 std::shared_ptr<CharacterCreateInfo> createInfo = std::make_shared<CharacterCreateInfo>();
275
276 recvData >> createInfo->Name
277 >> createInfo->Race
278 >> createInfo->Class
279 >> createInfo->Gender
280 >> createInfo->Skin
281 >> createInfo->Face
282 >> createInfo->HairStyle
283 >> createInfo->HairColor
284 >> createInfo->FacialHair
285 >> createInfo->OutfitId;
286
288 {
289 if (uint32 mask = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED))
290 {
291 if (mask & (1 << Player::TeamIdForRace(createInfo->Race)))
292 {
294 return;
295 }
296 }
297 }
298
299 ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(createInfo->Class);
300 if (!classEntry)
301 {
303 LOG_ERROR("network.opcode", "Class ({}) not found in DBC while creating new char for account (ID: {}): wrong DBC files or cheater?", createInfo->Class, GetAccountId());
304 return;
305 }
306
307 ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(createInfo->Race);
308 if (!raceEntry)
309 {
311 LOG_ERROR("network.opcode", "Race ({}) not found in DBC while creating new char for account (ID: {}): wrong DBC files or cheater?", createInfo->Race, GetAccountId());
312 return;
313 }
314
315 // prevent character creating Expansion race without Expansion account
316 if (raceEntry->expansion > Expansion())
317 {
319 LOG_ERROR("network.opcode", "Expansion {} account:[{}] tried to Create character with expansion {} race ({})", Expansion(), GetAccountId(), raceEntry->expansion, createInfo->Race);
320 return;
321 }
322
323 // prevent character creating Expansion class without Expansion account
324 if (classEntry->expansion > Expansion())
325 {
327 LOG_ERROR("network.opcode", "Expansion {} account:[{}] tried to Create character with expansion {} class ({})", Expansion(), GetAccountId(), classEntry->expansion, createInfo->Class);
328 return;
329 }
330
332 {
333 uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK);
334 if ((1 << (createInfo->Race - 1)) & raceMaskDisabled)
335 {
337 return;
338 }
339
340 uint32 classMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK);
341 if ((1 << (createInfo->Class - 1)) & classMaskDisabled)
342 {
344 return;
345 }
346 }
347
348 // prevent character creating with invalid name
349 if (!normalizePlayerName(createInfo->Name))
350 {
352 LOG_ERROR("network.opcode", "Account:[{}] but tried to Create character with empty [name] ", GetAccountId());
353 return;
354 }
355
356 // check name limitations
357 uint8 res = ObjectMgr::CheckPlayerName(createInfo->Name, true);
358 if (res != CHAR_NAME_SUCCESS)
359 {
361 return;
362 }
363
364 // speedup check for heroic class disabled case
365 uint32 heroic_free_slots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM);
366 if (heroic_free_slots == 0 && AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT)
367 {
369 return;
370 }
371
372 // speedup check for heroic class disabled case
373 uint32 req_level_for_heroic = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER);
374 if (AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT && req_level_for_heroic > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
375 {
377 return;
378 }
379
381 stmt->SetData(0, createInfo->Name);
382
384 .WithChainingPreparedCallback([this](QueryCallback& queryCallback, PreparedQueryResult result)
385 {
386 if (result)
387 {
388 SendCharCreate(CHAR_CREATE_NAME_IN_USE);
389 return;
390 }
391
393 stmt->SetData(0, GetAccountId());
394 queryCallback.SetNextQuery(LoginDatabase.AsyncQuery(stmt));
395 })
396 .WithChainingPreparedCallback([this](QueryCallback& queryCallback, PreparedQueryResult result)
397 {
398 uint64 acctCharCount = 0;
399 if (result)
400 {
401 Field* fields = result->Fetch();
402 acctCharCount = uint64(fields[0].Get<double>());
403 }
404
405 if (acctCharCount >= static_cast<uint64>(sWorld->getIntConfig(CONFIG_CHARACTERS_PER_ACCOUNT)))
406 {
408 return;
409 }
410
412 stmt->SetData(0, GetAccountId());
413 queryCallback.SetNextQuery(CharacterDatabase.AsyncQuery(stmt));
414 })
415 .WithChainingPreparedCallback([this, createInfo](QueryCallback& queryCallback, PreparedQueryResult result)
416 {
417 if (result)
418 {
419 Field* fields = result->Fetch();
420 createInfo->CharCount = uint8(fields[0].Get<uint64>()); // SQL's COUNT() returns uint64 but it will always be less than uint8.Max
421
422 if (createInfo->CharCount >= sWorld->getIntConfig(CONFIG_CHARACTERS_PER_REALM))
423 {
425 return;
426 }
427 }
428
429 bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity());
430 uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
431
432 std::function<void(PreparedQueryResult)> finalizeCharacterCreation = [this, createInfo](PreparedQueryResult result)
433 {
434 if (!sScriptMgr->CanAccountCreateCharacter(GetAccountId(), createInfo->Race, createInfo->Class))
435 {
437 return;
438 }
439 bool haveSameRace = false;
441 bool hasHeroicReqLevel = (heroicReqLevel == 0);
442 bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity());
443 uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
444 bool checkDeathKnightReqs = AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT;
445
446 if (result)
447 {
448 TeamId teamId = Player::TeamIdForRace(createInfo->Race);
449 uint32 freeDeathKnightSlots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM);
450
451 Field* field = result->Fetch();
452 uint8 accRace = field[1].Get<uint8>();
453
454 if (checkDeathKnightReqs)
455 {
456 uint8 accClass = field[2].Get<uint8>();
457 if (accClass == CLASS_DEATH_KNIGHT)
458 {
459 if (freeDeathKnightSlots > 0)
460 --freeDeathKnightSlots;
461
462 if (freeDeathKnightSlots == 0)
463 {
465 return;
466 }
467 }
468
469 if (!hasHeroicReqLevel)
470 {
471 uint8 accLevel = field[0].Get<uint8>();
472 if (accLevel >= heroicReqLevel)
473 hasHeroicReqLevel = true;
474 }
475 }
476
477 // need to check team only for first character
479 if (!allowTwoSideAccounts)
480 {
481 uint32 accTeam = 0;
482 if (accRace > 0)
483 accTeam = Player::TeamIdForRace(accRace);
484
485 if (accTeam != teamId)
486 {
488 return;
489 }
490 }
491
492 // search same race for cinematic or same class if need
494 while ((skipCinematics == 1 && !haveSameRace) || createInfo->Class == CLASS_DEATH_KNIGHT)
495 {
496 if (!result->NextRow())
497 break;
498
499 field = result->Fetch();
500 accRace = field[1].Get<uint8>();
501
502 if (!haveSameRace)
503 haveSameRace = createInfo->Race == accRace;
504
505 if (checkDeathKnightReqs)
506 {
507 uint8 acc_class = field[2].Get<uint8>();
508 if (acc_class == CLASS_DEATH_KNIGHT)
509 {
510 if (freeDeathKnightSlots > 0)
511 --freeDeathKnightSlots;
512
513 if (freeDeathKnightSlots == 0)
514 {
516 return;
517 }
518 }
519
520 if (!hasHeroicReqLevel)
521 {
522 uint8 acc_level = field[0].Get<uint8>();
523 if (acc_level >= heroicReqLevel)
524 hasHeroicReqLevel = true;
525 }
526 }
527 }
528 }
529
530 if (checkDeathKnightReqs && !hasHeroicReqLevel)
531 {
533 return;
534 }
535
536 // Check name uniqueness in the same step as saving to database
537 if (sCharacterCache->GetCharacterGuidByName(createInfo->Name))
538 {
540 return;
541 }
542
543 std::shared_ptr<Player> newChar(new Player(this), [](Player* ptr)
544 {
545 // Only when player is created correctly do clean
547 {
548 ptr->CleanupsBeforeDelete();
549 }
550 delete ptr;
551 });
552
553 newChar->GetMotionMaster()->Initialize();
554 if (!newChar->Create(sObjectMgr->GetGenerator<HighGuid::Player>().Generate(), createInfo.get()))
555 {
556 // Player not create (race/class/etc problem?)
558 return;
559 }
560
561 if ((haveSameRace && skipCinematics == 1) || skipCinematics == 2)
562 newChar->setCinematic(1); // not show intro
563
564 newChar->SetAtLoginFlag(AT_LOGIN_FIRST); // First login
565
566 CharacterDatabaseTransaction characterTransaction = CharacterDatabase.BeginTransaction();
567 LoginDatabaseTransaction trans = LoginDatabase.BeginTransaction();
568
569 // Player created, save it now
570 newChar->SaveToDB(characterTransaction, true, false);
571 createInfo->CharCount++;
572
574 stmt->SetData(0, createInfo->CharCount);
575 stmt->SetData(1, GetAccountId());
576 stmt->SetData(2, realm.Id.Realm);
577 trans->Append(stmt);
578
579 LoginDatabase.CommitTransaction(trans);
580
581 AddTransactionCallback(CharacterDatabase.AsyncCommitTransaction(characterTransaction)).AfterComplete([this, newChar = std::move(newChar)](bool success)
582 {
583 if (success)
584 {
585 LOG_INFO("entities.player.character", "Account: {} (IP: {}) Create Character: {} {}", GetAccountId(), GetRemoteAddress(), newChar->GetName(), newChar->GetGUID().ToString());
586 sScriptMgr->OnPlayerCreate(newChar.get());
587 sCharacterCache->AddCharacterCacheEntry(newChar->GetGUID(), GetAccountId(), newChar->GetName(), newChar->getGender(), newChar->getRace(), newChar->getClass(), newChar->GetLevel());
589 }
590 else
592 });
593 };
594
595 if (allowTwoSideAccounts && !skipCinematics && createInfo->Class != CLASS_DEATH_KNIGHT)
596 {
597 finalizeCharacterCreation(PreparedQueryResult(nullptr));
598 return;
599 }
600
602 stmt->SetData(0, GetAccountId());
603 stmt->SetData(1, (skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT) ? 10 : 1);
604 queryCallback.WithPreparedCallback(std::move(finalizeCharacterCreation)).SetNextQuery(CharacterDatabase.AsyncQuery(stmt));
605 }));
606}
@ CHAR_SEL_CHECK_NAME
Definition CharacterDatabase.h:37
@ CHAR_SEL_SUM_CHARS
Definition CharacterDatabase.h:39
@ CHAR_SEL_CHAR_CREATE_INFO
Definition CharacterDatabase.h:40
DBCStorage< ChrRacesEntry > sChrRacesStore(ChrRacesEntryfmt)
DBCStorage< ChrClassesEntry > sChrClassesStore(ChrClassesEntryfmt)
SQLTransaction< LoginDatabaseConnection > LoginDatabaseTransaction
Definition DatabaseEnvFwd.h:70
std::shared_ptr< PreparedResultSet > PreparedQueryResult
Definition DatabaseEnvFwd.h:45
@ LOGIN_REP_REALM_CHARACTERS
Definition LoginDatabase.h:63
@ LOGIN_SEL_SUM_REALM_CHARACTERS
Definition LoginDatabase.h:64
@ AT_LOGIN_FIRST
Definition Player.h:600
ResponseCodes
Definition SharedDefines.h:3586
@ CHAR_CREATE_EXPANSION
Definition SharedDefines.h:3650
@ CHAR_NAME_NO_NAME
Definition SharedDefines.h:3687
@ CHAR_CREATE_DISABLED
Definition SharedDefines.h:3644
@ CHAR_CREATE_LEVEL_REQUIREMENT
Definition SharedDefines.h:3652
@ CHAR_CREATE_FAILED
Definition SharedDefines.h:3642
@ CHAR_CREATE_ERROR
Definition SharedDefines.h:3641
@ CHAR_CREATE_NAME_IN_USE
Definition SharedDefines.h:3643
@ CHAR_CREATE_SERVER_LIMIT
Definition SharedDefines.h:3646
@ CHAR_CREATE_EXPANSION_CLASS
Definition SharedDefines.h:3651
@ CHAR_CREATE_SUCCESS
Definition SharedDefines.h:3640
@ CHAR_CREATE_PVP_TEAMS_VIOLATION
Definition SharedDefines.h:3645
@ CHAR_CREATE_ACCOUNT_LIMIT
Definition SharedDefines.h:3647
@ CHAR_CREATE_UNIQUE_CLASS_LIMIT
Definition SharedDefines.h:3653
@ CHAR_NAME_SUCCESS
Definition SharedDefines.h:3685
@ CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK
Definition WorldConfig.h:183
@ CONFIG_CHARACTER_CREATING_DISABLED
Definition WorldConfig.h:181
@ CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK
Definition WorldConfig.h:182
@ CONFIG_CHARACTERS_PER_ACCOUNT
Definition WorldConfig.h:184
@ CONFIG_HEROIC_CHARACTERS_PER_REALM
Definition WorldConfig.h:187
@ CONFIG_ALLOW_TWO_SIDE_ACCOUNTS
Definition WorldConfig.h:30
@ CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER
Definition WorldConfig.h:188
@ CONFIG_SKIP_CINEMATICS
Definition WorldConfig.h:189
@ CONFIG_CHARACTERS_PER_REALM
Definition WorldConfig.h:185
static uint8 CheckPlayerName(std::string_view name, bool create=false)
Definition ObjectMgr.cpp:8652
bool HasAtLoginFlag(AtLoginFlags f) const
Definition Player.h:2416
Definition QueryCallback.h:29
void SetNextQuery(QueryCallback &&next)
Definition QueryCallback.cpp:181
QueryCallback && WithPreparedCallback(std::function< void(PreparedQueryResult)> &&callback)
Definition QueryCallback.cpp:162
void AfterComplete(std::function< void(bool)> callback) &
Definition Transaction.h:116
uint8 Expansion() const
Definition WorldSession.h:435
TransactionCallback & AddTransactionCallback(TransactionCallback &&callback)
Definition WorldSession.cpp:1324
void SendCharCreate(ResponseCodes result)
Definition CharacterHandler.cpp:2577
Definition DBCStructure.h:653
uint32 expansion
Definition DBCStructure.h:668
Definition DBCStructure.h:679
uint32 expansion
Definition DBCStructure.h:698

References _queryProcessor, AsyncCallbackProcessor< T >::AddCallback(), CHAR_CREATE_DISABLED, CHAR_CREATE_EXPANSION, CHAR_CREATE_EXPANSION_CLASS, CHAR_CREATE_FAILED, CHAR_CREATE_LEVEL_REQUIREMENT, CHAR_CREATE_UNIQUE_CLASS_LIMIT, CHAR_NAME_NO_NAME, CHAR_NAME_SUCCESS, CHAR_SEL_CHECK_NAME, CharacterDatabase, ObjectMgr::CheckPlayerName(), CLASS_DEATH_KNIGHT, CONFIG_CHARACTER_CREATING_DISABLED, CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK, CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK, CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER, CONFIG_HEROIC_CHARACTERS_PER_REALM, CONFIG_MAX_PLAYER_LEVEL, Expansion(), ChrClassesEntry::expansion, ChrRacesEntry::expansion, GetAccountId(), GetSecurity(), AccountMgr::IsPlayerAccount(), LOG_ERROR, LOGIN_SEL_SUM_REALM_CHARACTERS, LoginDatabase, normalizePlayerName(), sChrClassesStore, sChrRacesStore, SendCharCreate(), PreparedStatementBase::SetData(), QueryCallback::SetNextQuery(), sWorld, and Player::TeamIdForRace().

Referenced by OpcodeTable::Initialize().

◆ HandleCharCustomize()

void WorldSession::HandleCharCustomize ( WorldPacket recvData)
1620{
1621 std::shared_ptr<CharacterCustomizeInfo> customizeInfo = std::make_shared<CharacterCustomizeInfo>();
1622
1623 recvData >> customizeInfo->Guid;
1624
1625 if (!IsLegitCharacterForAccount(customizeInfo->Guid))
1626 {
1627 LOG_ERROR("entities.player.cheat", "Account {}, IP: {} tried to customise {}, but it does not belong to their account!",
1628 GetAccountId(), GetRemoteAddress(), customizeInfo->Guid.ToString());
1629 recvData.rfinish();
1630 KickPlayer("WorldSession::HandleCharCustomize Trying to customise character of another account");
1631 return;
1632 }
1633
1634 // pussywizard:
1635 if (ObjectAccessor::FindConnectedPlayer(customizeInfo->Guid) || sWorldSessionMgr->FindOfflineSessionForCharacterGUID(customizeInfo->Guid.GetCounter()))
1636 {
1637 recvData.rfinish();
1639 data << uint8(CHAR_CREATE_ERROR);
1640 SendPacket(&data);
1641 return;
1642 }
1643
1644 recvData >> customizeInfo->Name
1645 >> customizeInfo->Gender
1646 >> customizeInfo->Skin
1647 >> customizeInfo->HairColor
1648 >> customizeInfo->HairStyle
1649 >> customizeInfo->FacialHair
1650 >> customizeInfo->Face;
1651
1653 stmt->SetData(0, customizeInfo->Guid.GetCounter());
1654
1656 .WithPreparedCallback(std::bind(&WorldSession::HandleCharCustomizeCallback, this, customizeInfo, std::placeholders::_1)));
1657}
@ CHAR_SEL_CHAR_CUSTOMIZE_INFO
Definition CharacterDatabase.h:346
#define sWorldSessionMgr
Definition WorldSessionMgr.h:108
void HandleCharCustomizeCallback(std::shared_ptr< CharacterCustomizeInfo > customizeInfo, PreparedQueryResult result)
Definition CharacterHandler.cpp:1659
bool IsLegitCharacterForAccount(ObjectGuid guid)
Definition WorldSession.h:1192
@ SMSG_CHAR_CUSTOMIZE
Definition Opcodes.h:1170

References _queryProcessor, AsyncCallbackProcessor< T >::AddCallback(), CHAR_CREATE_ERROR, CHAR_SEL_CHAR_CUSTOMIZE_INFO, CharacterDatabase, ObjectAccessor::FindConnectedPlayer(), GetAccountId(), GetRemoteAddress(), HandleCharCustomizeCallback(), IsLegitCharacterForAccount(), KickPlayer(), LOG_ERROR, ByteBuffer::rfinish(), SendPacket(), PreparedStatementBase::SetData(), SMSG_CHAR_CUSTOMIZE, and sWorldSessionMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleCharCustomizeCallback()

void WorldSession::HandleCharCustomizeCallback ( std::shared_ptr< CharacterCustomizeInfo customizeInfo,
PreparedQueryResult  result 
)

Customize

Name Change and update atLogin flags

1660{
1661 if (!result)
1662 {
1663 SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo.get());
1664 return;
1665 }
1666
1667 // get the players old (at this moment current) race
1668 CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(customizeInfo->Guid);
1669 if (!playerData)
1670 {
1671 SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo.get());
1672 return;
1673 }
1674
1675 Field* fields = result->Fetch();
1676 std::string oldName = fields[0].Get<std::string>();
1677 //uint8 plrRace = fields[1].Get<uint8>();
1678 //uint8 plrClass = fields[2].Get<uint8>();
1679 //uint8 plrGender = fields[3].Get<uint8>();
1680 uint32 atLoginFlags = fields[4].Get<uint16>();
1681
1682 if (!(atLoginFlags & AT_LOGIN_CUSTOMIZE))
1683 {
1684 SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo.get());
1685 return;
1686 }
1687
1688 atLoginFlags &= ~AT_LOGIN_CUSTOMIZE;
1689
1690 // prevent character rename to invalid name
1691 if (!normalizePlayerName(customizeInfo->Name))
1692 {
1693 SendCharCustomize(CHAR_NAME_NO_NAME, customizeInfo.get());
1694 return;
1695 }
1696
1697 ResponseCodes res = static_cast<ResponseCodes>(ObjectMgr::CheckPlayerName(customizeInfo->Name, true));
1698 if (res != CHAR_NAME_SUCCESS)
1699 {
1700 SendCharCustomize(res, customizeInfo.get());
1701 return;
1702 }
1703
1704 // character with this name already exist
1705 if (ObjectGuid newguid = sCharacterCache->GetCharacterGuidByName(customizeInfo->Name))
1706 {
1707 if (newguid != customizeInfo->Guid)
1708 {
1709 SendCharCustomize(CHAR_CREATE_NAME_IN_USE, customizeInfo.get());
1710 return;
1711 }
1712 }
1713
1714 CharacterDatabasePreparedStatement* stmt = nullptr;
1715 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
1716
1717 ObjectGuid::LowType lowGuid = customizeInfo->Guid.GetCounter();
1718
1720 Player::Customize(customizeInfo.get(), trans);
1721
1723 {
1724 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN);
1725 stmt->SetData(0, customizeInfo->Name);
1726 stmt->SetData(1, atLoginFlags);
1727 stmt->SetData(2, lowGuid);
1728
1729 trans->Append(stmt);
1730
1731 if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
1732 {
1733 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME);
1734 stmt->SetData(0, lowGuid);
1735
1736 trans->Append(stmt);
1737 }
1738 }
1739
1740 CharacterDatabase.CommitTransaction(trans);
1741
1742 sCharacterCache->UpdateCharacterData(customizeInfo->Guid, customizeInfo->Name, customizeInfo->Gender);
1743
1744 SendCharCustomize(RESPONSE_SUCCESS, customizeInfo.get());
1745
1746 LOG_INFO("entities.player.character", "Account: {} (IP: {}), Character[{}] ({}) Customized to: {}",
1747 GetAccountId(), GetRemoteAddress(), oldName, customizeInfo->Guid.ToString(), customizeInfo->Name);
1748}
@ CHAR_DEL_DECLINED_NAME
Definition CharacterDatabase.h:138
@ CHAR_UPD_CHAR_NAME_AT_LOGIN
Definition CharacterDatabase.h:305
@ AT_LOGIN_CUSTOMIZE
Definition Player.h:598
@ RESPONSE_SUCCESS
Definition SharedDefines.h:3587
@ CONFIG_DECLINED_NAMES_USED
Definition WorldConfig.h:67
uint32 LowType
Definition ObjectGuid.h:122
static void Customize(CharacterCustomizeInfo const *customizeInfo, CharacterDatabaseTransaction trans)
Definition PlayerMisc.cpp:114
void SendCharCustomize(ResponseCodes result, CharacterCustomizeInfo const *customizeInfo)
Definition CharacterHandler.cpp:2629

References AT_LOGIN_CUSTOMIZE, CHAR_CREATE_ERROR, CHAR_CREATE_NAME_IN_USE, CHAR_DEL_DECLINED_NAME, CHAR_NAME_NO_NAME, CHAR_NAME_SUCCESS, CHAR_UPD_CHAR_NAME_AT_LOGIN, CharacterDatabase, ObjectMgr::CheckPlayerName(), CONFIG_DECLINED_NAMES_USED, Player::Customize(), Field::Get(), GetAccountId(), GetRemoteAddress(), LOG_INFO, normalizePlayerName(), RESPONSE_SUCCESS, sCharacterCache, SendCharCustomize(), PreparedStatementBase::SetData(), and sWorld.

Referenced by HandleCharCustomize().

◆ HandleCharDeleteOpcode()

void WorldSession::HandleCharDeleteOpcode ( WorldPacket recvPacket)
609{
610 ObjectGuid guid;
611 recvData >> guid;
612
613 // Initiating
614 uint32 initAccountId = GetAccountId();
615
616 // can't delete loaded character
617 if (ObjectAccessor::FindConnectedPlayer(guid) || sWorldSessionMgr->FindOfflineSessionForCharacterGUID(guid.GetCounter()))
618 {
619 sScriptMgr->OnPlayerFailedDelete(guid, initAccountId);
620 return;
621 }
622
623 uint32 accountId = 0;
624 uint8 level = 0;
625 std::string name;
626
627 // is guild leader
628 if (sGuildMgr->GetGuildByLeader(guid))
629 {
630 sScriptMgr->OnPlayerFailedDelete(guid, initAccountId);
632 return;
633 }
634
635 // is arena team captain
636 if (sArenaTeamMgr->GetArenaTeamByCaptain(guid))
637 {
638 sScriptMgr->OnPlayerFailedDelete(guid, initAccountId);
640 return;
641 }
642
643 if (CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(guid))
644 {
645 accountId = playerData->AccountId;
646 name = playerData->Name;
647 level = playerData->Level;
648 }
649
650 // prevent deleting other players' characters using cheating tools
651 if (accountId != initAccountId)
652 {
653 sScriptMgr->OnPlayerFailedDelete(guid, initAccountId);
654 return;
655 }
656
657 LOG_INFO("entities.player.character", "Account: {}, IP: {} deleted character: {}, {}, Level: {}", accountId, GetRemoteAddress(), name, guid.ToString(), level);
658
659 // To prevent hook failure, place hook before removing reference from DB
660 sScriptMgr->OnPlayerDelete(guid, initAccountId); // To prevent race conditioning, but as it also makes sense, we hand the accountId over for successful delete.
661 sCalendarMgr->RemoveAllPlayerEventsAndInvites(guid);
662 Player::DeleteFromDB(guid.GetCounter(), GetAccountId(), true, false);
663
664 sWorld->UpdateRealmCharCount(GetAccountId());
665
667}
@ CHAR_DELETE_SUCCESS
Definition SharedDefines.h:3667
@ CHAR_DELETE_FAILED_GUILD_LEADER
Definition SharedDefines.h:3670
@ CHAR_DELETE_FAILED_ARENA_CAPTAIN
Definition SharedDefines.h:3671
static void DeleteFromDB(ObjectGuid::LowType lowGuid, uint32 accountId, bool updateRealmChars, bool deleteFinally)
Definition Player.cpp:3982
void SendCharDelete(ResponseCodes result)
Definition CharacterHandler.cpp:2584

References CHAR_DELETE_FAILED_ARENA_CAPTAIN, CHAR_DELETE_FAILED_GUILD_LEADER, CHAR_DELETE_SUCCESS, Player::DeleteFromDB(), ObjectAccessor::FindConnectedPlayer(), GetAccountId(), ObjectGuid::GetCounter(), GetRemoteAddress(), LOG_INFO, sArenaTeamMgr, sCalendarMgr, sCharacterCache, SendCharDelete(), sGuildMgr, sScriptMgr, sWorld, sWorldSessionMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCharEnum()

void WorldSession::HandleCharEnum ( PreparedQueryResult  result)
228{
229 WorldPacket data(SMSG_CHAR_ENUM, 100); // we guess size
230
231 uint8 num = 0;
232
233 data << num;
234
235 _legitCharacters.clear();
236 if (result)
237 {
238 do
239 {
240 ObjectGuid guid = ObjectGuid::Create<HighGuid::Player>((*result)[0].Get<uint32>());
241 LOG_DEBUG("network.opcode", "Loading char {} from account {}.", guid.ToString(), GetAccountId());
242 if (Player::BuildEnumData(result, &data))
243 {
244 _legitCharacters.insert(guid);
245 ++num;
246 }
247 } while (result->NextRow());
248 }
249
250 data.put<uint8>(0, num);
251
252 SendPacket(&data);
253}
static bool BuildEnumData(PreparedQueryResult result, WorldPacket *data)
Definition Player.cpp:1105
GuidSet _legitCharacters
Definition WorldSession.h:1199
@ SMSG_CHAR_ENUM
Definition Opcodes.h:89

References _legitCharacters, Player::BuildEnumData(), ByteBuffer::clear(), GetAccountId(), LOG_DEBUG, ByteBuffer::put(), SendPacket(), SMSG_CHAR_ENUM, and ObjectGuid::ToString().

Referenced by HandleCharEnumOpcode().

◆ HandleCharEnumOpcode()

void WorldSession::HandleCharEnumOpcode ( WorldPacket recvPacket)

get all the data necessary for loading all characters (along with their pets) on the account

256{
258
260
261 if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
262 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ENUM_DECLINED_NAME);
263 else
264 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ENUM);
265
267 stmt->SetData(1, GetAccountId());
268
269 _queryProcessor.AddCallback(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSession::HandleCharEnum, this, std::placeholders::_1)));
270}
@ CHAR_SEL_ENUM
Definition CharacterDatabase.h:48
@ CHAR_SEL_ENUM_DECLINED_NAME
Definition CharacterDatabase.h:49
@ PET_SAVE_AS_CURRENT
Definition PetDefines.h:43
void HandleCharEnum(PreparedQueryResult result)
Definition CharacterHandler.cpp:227

References _queryProcessor, AsyncCallbackProcessor< T >::AddCallback(), CHAR_SEL_ENUM, CHAR_SEL_ENUM_DECLINED_NAME, CharacterDatabase, CONFIG_DECLINED_NAMES_USED, GetAccountId(), HandleCharEnum(), PET_SAVE_AS_CURRENT, PreparedStatementBase::SetData(), and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleCharFactionOrRaceChange()

void WorldSession::HandleCharFactionOrRaceChange ( WorldPacket recvData)
1925{
1926 std::shared_ptr<CharacterFactionChangeInfo> factionChangeInfo = std::make_shared<CharacterFactionChangeInfo>();
1927
1928 recvData >> factionChangeInfo->Guid;
1929
1930 if (!IsLegitCharacterForAccount(factionChangeInfo->Guid))
1931 {
1932 LOG_ERROR("entities.player.cheat", "Account {}, IP: {} tried to factionchange character {}, but it does not belong to their account!",
1933 GetAccountId(), GetRemoteAddress(), factionChangeInfo->Guid.ToString());
1934 recvData.rfinish();
1935 KickPlayer("WorldSession::HandleCharFactionOrRaceChange Trying to change faction of character of another account");
1936 return;
1937 }
1938
1939 recvData >> factionChangeInfo->Name
1940 >> factionChangeInfo->Gender
1941 >> factionChangeInfo->Skin
1942 >> factionChangeInfo->HairColor
1943 >> factionChangeInfo->HairStyle
1944 >> factionChangeInfo->FacialHair
1945 >> factionChangeInfo->Face
1946 >> factionChangeInfo->Race;
1947
1948 // pussywizard:
1949 if (ObjectAccessor::FindConnectedPlayer(factionChangeInfo->Guid) || sWorldSessionMgr->FindOfflineSessionForCharacterGUID(factionChangeInfo->Guid.GetCounter()))
1950 {
1951 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
1952 return;
1953 }
1954
1955 factionChangeInfo->FactionChange = (recvData.GetOpcode() == CMSG_CHAR_FACTION_CHANGE);
1956
1958 stmt->SetData(0, factionChangeInfo->Guid.GetCounter());
1959
1961 .WithPreparedCallback(std::bind(&WorldSession::HandleCharFactionOrRaceChangeCallback, this, factionChangeInfo, std::placeholders::_1)));
1962}
@ CHAR_SEL_CHAR_RACE_OR_FACTION_CHANGE_INFOS
Definition CharacterDatabase.h:347
void HandleCharFactionOrRaceChangeCallback(std::shared_ptr< CharacterFactionChangeInfo > factionChangeInfo, PreparedQueryResult result)
Definition CharacterHandler.cpp:1964
void SendCharFactionChange(ResponseCodes result, CharacterFactionChangeInfo const *factionChangeInfo)
Definition CharacterHandler.cpp:2610
@ CMSG_CHAR_FACTION_CHANGE
Definition Opcodes.h:1271

References _queryProcessor, AsyncCallbackProcessor< T >::AddCallback(), CHAR_CREATE_ERROR, CHAR_SEL_CHAR_RACE_OR_FACTION_CHANGE_INFOS, CharacterDatabase, CMSG_CHAR_FACTION_CHANGE, ObjectAccessor::FindConnectedPlayer(), GetAccountId(), WorldPacket::GetOpcode(), GetRemoteAddress(), HandleCharFactionOrRaceChangeCallback(), IsLegitCharacterForAccount(), KickPlayer(), LOG_ERROR, ByteBuffer::rfinish(), SendCharFactionChange(), PreparedStatementBase::SetData(), and sWorldSessionMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleCharFactionOrRaceChangeCallback()

void WorldSession::HandleCharFactionOrRaceChangeCallback ( std::shared_ptr< CharacterFactionChangeInfo factionChangeInfo,
PreparedQueryResult  result 
)
1965{
1966 if (!result)
1967 {
1968 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
1969 return;
1970 }
1971
1972 ObjectGuid::LowType lowGuid = factionChangeInfo->Guid.GetCounter();
1973
1974 // get the players old (at this moment current) race
1975 CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(factionChangeInfo->Guid);
1976 if (!playerData)
1977 {
1978 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
1979 return;
1980 }
1981
1982 uint8 oldRace = playerData->Race;
1983 uint8 playerClass = playerData->Class;
1984 uint8 level = playerData->Level;
1985
1986 if (!sObjectMgr->GetPlayerInfo(factionChangeInfo->Race, playerClass))
1987 {
1988 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
1989 return;
1990 }
1991
1992 Field* fields = result->Fetch();
1993 uint32 atLoginFlags = fields[0].Get<uint16>();
1994 std::string knownTitlesStr = fields[1].Get<std::string>();
1995 uint32 money = fields[2].Get<uint32>();
1996
1997 uint32 usedLoginFlag = (factionChangeInfo->FactionChange ? AT_LOGIN_CHANGE_FACTION : AT_LOGIN_CHANGE_RACE);
1998 if (!(atLoginFlags & usedLoginFlag))
1999 {
2000 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
2001 return;
2002 }
2003
2004 // xinef: add some safety checks
2005 if (factionChangeInfo->FactionChange)
2006 {
2007 // if player is in a guild
2008 if (playerData->GuildId && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD))
2009 {
2010 SendCharFactionChange(CHAR_CREATE_CHARACTER_IN_GUILD, factionChangeInfo.get());
2011 return;
2012 }
2013
2014 // is arena team captain
2015 if (sArenaTeamMgr->GetArenaTeamByCaptain(factionChangeInfo->Guid))
2016 {
2018 return;
2019 }
2020
2021 // check mailbox
2022 if (playerData->MailCount)
2023 {
2025 return;
2026 }
2027
2028 // check auctions, current packet is processed single-threaded way, so not a problem
2029 bool has_auctions = false;
2030
2031 for (uint8 i = 0; i < 2; ++i) // check both neutral and faction-specific AH
2032 {
2033 AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(i == 0 ? 0 : (((1 << (playerData->Race - 1)) & RACEMASK_ALLIANCE) ? 12 : 29));
2034
2035 for (auto const& [auID, Aentry] : auctionHouse->GetAuctions())
2036 {
2037 if (Aentry && (Aentry->owner == factionChangeInfo->Guid || Aentry->bidder == factionChangeInfo->Guid))
2038 {
2039 has_auctions = true;
2040 break;
2041 }
2042 }
2043
2044 if (has_auctions)
2045 break;
2046 }
2047
2048 if (has_auctions)
2049 {
2050 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
2051 return;
2052 }
2053 }
2054
2055 TeamId newTeam = Player::TeamIdForRace(factionChangeInfo->Race);
2056 if (factionChangeInfo->FactionChange == (Player::TeamIdForRace(oldRace) == newTeam))
2057 {
2058 SendCharFactionChange(factionChangeInfo->FactionChange ? CHAR_CREATE_CHARACTER_SWAP_FACTION : CHAR_CREATE_CHARACTER_RACE_ONLY, factionChangeInfo.get());
2059 return;
2060 }
2061
2062 uint32 maxMoney = sWorld->getIntConfig(CONFIG_CHANGE_FACTION_MAX_MONEY);
2063 if (maxMoney && money > maxMoney)
2064 {
2066 return;
2067 }
2068
2069 // pussywizard: check titles here to prevent return while building queries
2070 const uint32 ktcount = KNOWN_TITLES_SIZE * 2;
2071 std::vector<std::string_view> tokens = Acore::Tokenize(knownTitlesStr, ' ', false);
2072
2073 if (factionChangeInfo->FactionChange && tokens.size() != ktcount)
2074 {
2075 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
2076 return;
2077 }
2078
2080 {
2081 uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK);
2082 if ((1 << (factionChangeInfo->Race - 1)) & raceMaskDisabled)
2083 {
2084 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
2085 return;
2086 }
2087 }
2088
2089 // prevent character rename to invalid name
2090 if (!normalizePlayerName(factionChangeInfo->Name))
2091 {
2092 SendCharFactionChange(CHAR_NAME_NO_NAME, factionChangeInfo.get());
2093 return;
2094 }
2095
2096 ResponseCodes res = static_cast<ResponseCodes>(ObjectMgr::CheckPlayerName(factionChangeInfo->Name, true));
2097 if (res != CHAR_NAME_SUCCESS)
2098 {
2099 SendCharFactionChange(res, factionChangeInfo.get());
2100 return;
2101 }
2102
2103 // character with this name already exist
2104 if (ObjectGuid newguid = sCharacterCache->GetCharacterGuidByName(factionChangeInfo->Name))
2105 {
2106 if (newguid != factionChangeInfo->Guid)
2107 {
2108 SendCharFactionChange(CHAR_CREATE_NAME_IN_USE, factionChangeInfo.get());
2109 return;
2110 }
2111 }
2112
2113 CharacterDatabasePreparedStatement* stmt = nullptr;
2114 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
2115
2116 // resurrect the character in case he's dead
2117 Player::OfflineResurrect(factionChangeInfo->Guid, trans);
2118
2119 // Name Change and update atLogin flags
2120 {
2121 CharacterDatabase.EscapeString(factionChangeInfo->Name);
2122
2123 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN);
2124 stmt->SetData(0, factionChangeInfo->Name);
2125 stmt->SetData(1, uint16((atLoginFlags | AT_LOGIN_RESURRECT) & ~usedLoginFlag));
2126 stmt->SetData(2, lowGuid);
2127 trans->Append(stmt);
2128
2129 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_DECLINED_NAME);
2130 stmt->SetData(0, lowGuid);
2131 trans->Append(stmt);
2132 }
2133
2134 // Customize
2135 Player::Customize(factionChangeInfo.get(), trans);
2136
2137 // Race Change
2138 {
2139 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_RACE);
2140 stmt->SetData(0, factionChangeInfo->Race);
2141 stmt->SetData(1, lowGuid);
2142 trans->Append(stmt);
2143 }
2144
2145 LOG_INFO("entities.player.character", "Account: {} (IP: {}), Character [{}] (guid: {}) Changed Race/Faction to: {}",
2146 GetAccountId(), GetRemoteAddress(), playerData->Name, lowGuid, factionChangeInfo->Name);
2147
2148 // xinef: update global data
2149 sCharacterCache->UpdateCharacterData(factionChangeInfo->Guid, factionChangeInfo->Name, factionChangeInfo->Gender, factionChangeInfo->Race);
2150
2151 if (oldRace != factionChangeInfo->Race)
2152 {
2153 // Switch Languages
2154 // delete all languages first
2155 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SKILL_LANGUAGES);
2156 stmt->SetData(0, lowGuid);
2157 trans->Append(stmt);
2158
2159 // Now add them back
2160 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_SKILL_LANGUAGE);
2161 stmt->SetData(0, lowGuid);
2162
2163 // Faction specific languages
2164 if (newTeam == TEAM_HORDE)
2165 stmt->SetData(1, 109);
2166 else
2167 stmt->SetData(1, 98);
2168
2169 trans->Append(stmt);
2170
2171 // Race specific languages
2172 if (factionChangeInfo->Race != RACE_ORC && factionChangeInfo->Race != RACE_HUMAN)
2173 {
2174 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_SKILL_LANGUAGE);
2175 stmt->SetData(0, lowGuid);
2176
2177 switch (factionChangeInfo->Race)
2178 {
2179 case RACE_DWARF:
2180 stmt->SetData(1, 111);
2181 break;
2182 case RACE_DRAENEI:
2183 stmt->SetData(1, 759);
2184 break;
2185 case RACE_GNOME:
2186 stmt->SetData(1, 313);
2187 break;
2188 case RACE_NIGHTELF:
2189 stmt->SetData(1, 113);
2190 break;
2191 case RACE_UNDEAD_PLAYER:
2192 stmt->SetData(1, 673);
2193 break;
2194 case RACE_TAUREN:
2195 stmt->SetData(1, 115);
2196 break;
2197 case RACE_TROLL:
2198 stmt->SetData(1, 315);
2199 break;
2200 case RACE_BLOODELF:
2201 stmt->SetData(1, 137);
2202 break;
2203 }
2204
2205 trans->Append(stmt);
2206 }
2207
2208 if (factionChangeInfo->FactionChange)
2209 {
2210 {
2211 // Delete all Flypaths
2212 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXI_PATH);
2213 stmt->SetData(0, lowGuid);
2214 trans->Append(stmt);
2215
2216 // Update Taxi path
2217 TaxiMask newTaxiMask;
2218 newTaxiMask.fill(0);
2219
2220 TaxiMask const& factionMask = newTeam == TEAM_HORDE ? sHordeTaxiNodesMask : sAllianceTaxiNodesMask;
2221 for (auto const& itr : sTaxiPathSetBySource)
2222 {
2223 auto FillTaxiMask = [&](uint8 field, uint32 mask)
2224 {
2225 if (playerClass == CLASS_DEATH_KNIGHT)
2226 {
2227 newTaxiMask[field] |= uint32(mask | (sDeathKnightTaxiNodesMask[field] & mask));
2228 }
2229 else
2230 {
2231 newTaxiMask[field] |= mask;
2232 }
2233 };
2234
2235 uint32 nodeId = itr.first;
2236 uint8 field = (uint8)((nodeId - 1) / 32);
2237 uint32 submask = 1 << ((nodeId - 1) % 32);
2238
2239 if ((factionMask[field] & submask) == 0)
2240 {
2241 FillTaxiMask(field, 0);
2242 continue;
2243 }
2244
2245 TaxiPathSetForSource const& taxiPaths = itr.second;
2246 if (taxiPaths.empty())
2247 {
2248 FillTaxiMask(field, 0);
2249 continue;
2250 }
2251
2252 TaxiPathEntry const* taxiPath = taxiPaths.begin()->second;
2253 if (!taxiPath)
2254 {
2255 FillTaxiMask(field, 0);
2256 continue;
2257 }
2258
2259 TaxiPathNodeList const& taxiNodePaths = sTaxiPathNodesByPath[taxiPath->ID];
2260 if (taxiNodePaths.empty())
2261 {
2262 FillTaxiMask(field, 0);
2263 continue;
2264 }
2265
2266 TaxiPathNodeEntry const* pathNode = taxiNodePaths.front();
2267 if (!pathNode)
2268 {
2269 FillTaxiMask(field, 0);
2270 continue;
2271 }
2272
2273 AreaTableEntry const* zone = sAreaTableStore.LookupEntry(sMapMgr->GetZoneId(PHASEMASK_NORMAL, pathNode->mapid, pathNode->x, pathNode->y, pathNode->z));
2274 if (!zone)
2275 {
2276 FillTaxiMask(field, 0);
2277 continue;
2278 }
2279
2281 if (!lfgDungeon)
2282 {
2283 FillTaxiMask(field, 0);
2284 continue;
2285 }
2286
2287 // Get level from LFGDungeonEntry because the one from AreaTableEntry is not valid
2288 // If area level is too big, do not add new taxi
2289 if (lfgDungeon->MinLevel > level)
2290 {
2291 FillTaxiMask(field, 0);
2292 continue;
2293 }
2294
2295 FillTaxiMask(field, submask);
2296 }
2297
2298 std::ostringstream taximaskstream;
2299 for (uint8 i = 0; i < TaxiMaskSize; ++i)
2300 taximaskstream << uint32(newTaxiMask[i]) << ' ';
2301
2302 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXIMASK);
2303 stmt->SetData(0, taximaskstream.str());
2304 stmt->SetData(1, lowGuid);
2305 trans->Append(stmt);
2306 }
2307
2308 // Reset guild
2310 {
2311 if (uint32 guildId = playerData->GuildId)
2312 if (Guild* guild = sGuildMgr->GetGuildById(guildId))
2313 guild->DeleteMember(factionChangeInfo->Guid, false, false, true);
2314 }
2315
2316 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND))
2317 {
2318 // Delete Friend List
2319 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SOCIAL_BY_GUID);
2320 stmt->SetData(0, lowGuid);
2321 trans->Append(stmt);
2322
2323 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SOCIAL_BY_FRIEND);
2324 stmt->SetData(0, lowGuid);
2325 trans->Append(stmt);
2326 }
2327
2328 // Leave Arena Teams
2329 Player::LeaveAllArenaTeams(factionChangeInfo->Guid);
2330
2331 // Reset homebind and position
2332 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_HOMEBIND);
2333 stmt->SetData(0, lowGuid);
2334 trans->Append(stmt);
2335
2336 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PLAYER_HOMEBIND);
2337 stmt->SetData(0, lowGuid);
2338
2339 WorldLocation loc;
2340 uint16 zoneId = 0;
2341
2342 if (newTeam == TEAM_ALLIANCE)
2343 {
2344 loc.WorldRelocate(MAP_EASTERN_KINGDOMS, -8867.68f, 673.373f, 97.9034f, 0.0f);
2345 zoneId = AREA_STORMWIND_CITY;
2346 }
2347 else
2348 {
2349 loc.WorldRelocate(MAP_KALIMDOR, 1633.33f, -4439.11f, 15.7588f, 0.0f);
2350 zoneId = AREA_ORGRIMMAR;
2351 }
2352
2353 stmt->SetData(1, loc.GetMapId());
2354 stmt->SetData(2, zoneId);
2355 stmt->SetData(3, loc.GetPositionX());
2356 stmt->SetData(4, loc.GetPositionY());
2357 stmt->SetData(5, loc.GetPositionZ());
2358 trans->Append(stmt);
2359
2360 Player::SavePositionInDB(loc, zoneId, factionChangeInfo->Guid, trans);
2361
2362 // Achievement conversion
2363 for (auto const& [achiev_alliance, achiev_horde] : sObjectMgr->FactionChangeAchievements)
2364 {
2366 stmt->SetData(0, uint16(newTeam == TEAM_ALLIANCE ? achiev_alliance : achiev_horde));
2367 stmt->SetData(1, lowGuid);
2368 trans->Append(stmt);
2369
2370 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ACHIEVEMENT);
2371 stmt->SetData(0, uint16(newTeam == TEAM_ALLIANCE ? achiev_alliance : achiev_horde));
2372 stmt->SetData(1, uint16(newTeam == TEAM_ALLIANCE ? achiev_horde : achiev_alliance));
2373 stmt->SetData(2, lowGuid);
2374 trans->Append(stmt);
2375 }
2376
2377 // Item conversion
2378 for (auto const& [item_alliance, item_horde] : sObjectMgr->FactionChangeItems)
2379 {
2380 uint32 new_entry = (newTeam == TEAM_ALLIANCE ? item_alliance : item_horde);
2381 uint32 old_entry = (newTeam == TEAM_ALLIANCE ? item_horde : item_alliance);
2382
2383 if (old_entry == 45978 /*Solid Gold Coin*/ || old_entry == 2589 /*Linen Cloth*/ || old_entry == 5976 /*Guild Tabard*/)
2384 continue;
2385
2386 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE);
2387 stmt->SetData(0, new_entry);
2388 stmt->SetData(1, old_entry);
2389 stmt->SetData(2, lowGuid);
2390 trans->Append(stmt);
2391 }
2392
2393 // Delete all current quests
2394 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS);
2395 stmt->SetData(0, lowGuid);
2396 trans->Append(stmt);
2397
2398 // Quest conversion
2399 for (auto const& [quest_alliance, quest_horde] : sObjectMgr->FactionChangeQuests)
2400 {
2402 stmt->SetData(0, lowGuid);
2403 stmt->SetData(1, (newTeam == TEAM_ALLIANCE ? quest_alliance : quest_horde));
2404 trans->Append(stmt);
2405
2407 stmt->SetData(0, (newTeam == TEAM_ALLIANCE ? quest_alliance : quest_horde));
2408 stmt->SetData(1, (newTeam == TEAM_ALLIANCE ? quest_horde : quest_alliance));
2409 stmt->SetData(2, lowGuid);
2410 trans->Append(stmt);
2411 }
2412
2413 // Mark all rewarded quests as "active" (will count for completed quests achievements)
2415 stmt->SetData(0, lowGuid);
2416 trans->Append(stmt);
2417
2418 // Disable all old-faction specific quests
2419 for (auto const& [questID, quest] : sObjectMgr->GetQuestTemplates())
2420 {
2421 uint32 newRaceMask = (newTeam == TEAM_ALLIANCE) ? RACEMASK_ALLIANCE : RACEMASK_HORDE;
2422
2423 if (quest->GetAllowableRaces() && !(quest->GetAllowableRaces() & newRaceMask))
2424 {
2426 stmt->SetData(0, quest->GetQuestId());
2427 stmt->SetData(1, lowGuid);
2428 trans->Append(stmt);
2429 }
2430 }
2431
2432 // Spell conversion
2433 for (auto const& [spell_alliance, spell_horde] : sObjectMgr->FactionChangeSpells)
2434 {
2435 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SPELL_BY_SPELL);
2436 stmt->SetData(0, lowGuid);
2437 stmt->SetData(1, (newTeam == TEAM_ALLIANCE ? spell_alliance : spell_horde));
2438 trans->Append(stmt);
2439
2440 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_SPELL_FACTION_CHANGE);
2441 stmt->SetData(0, (newTeam == TEAM_ALLIANCE ? spell_alliance : spell_horde));
2442 stmt->SetData(1, (newTeam == TEAM_ALLIANCE ? spell_horde : spell_alliance));
2443 stmt->SetData(2, lowGuid);
2444 trans->Append(stmt);
2445 }
2446
2447 // Reputation conversion
2448 for (auto const& [reputation_alliance, reputation_horde] : sObjectMgr->FactionChangeReputation)
2449 {
2450 uint32 newReputation = (newTeam == TEAM_ALLIANCE) ? reputation_alliance : reputation_horde;
2451 uint32 oldReputation = (newTeam == TEAM_ALLIANCE) ? reputation_horde : reputation_alliance;
2452
2453 // select old standing set in db
2454 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_REP_BY_FACTION);
2455 stmt->SetData(0, oldReputation);
2456 stmt->SetData(1, lowGuid);
2457
2458 PreparedQueryResult result = CharacterDatabase.Query(stmt);
2459 if (!result)
2460 continue;
2461
2462 fields = result->Fetch();
2463 int32 oldDBRep = fields[0].Get<int32>();
2464 FactionEntry const* factionEntry = sFactionStore.LookupEntry(oldReputation);
2465
2466 // old base reputation
2467 int32 oldBaseRep = sObjectMgr->GetBaseReputationOf(factionEntry, oldRace, playerClass);
2468
2469 // new base reputation
2470 int32 newBaseRep = sObjectMgr->GetBaseReputationOf(sFactionStore.LookupEntry(newReputation), factionChangeInfo->Race, playerClass);
2471
2472 // final reputation shouldnt change
2473 int32 FinalRep = oldDBRep + oldBaseRep;
2474 int32 newDBRep = FinalRep - newBaseRep;
2475
2476 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_REP_BY_FACTION);
2477 stmt->SetData(0, newReputation);
2478 stmt->SetData(1, lowGuid);
2479 trans->Append(stmt);
2480
2481 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_REP_FACTION_CHANGE);
2482 stmt->SetData(0, uint16(newReputation));
2483 stmt->SetData(1, newDBRep);
2484 stmt->SetData(2, uint16(oldReputation));
2485 stmt->SetData(3, lowGuid);
2486 trans->Append(stmt);
2487 }
2488
2489 // Title conversion
2490 if (!knownTitlesStr.empty())
2491 {
2492 std::array<uint32, KNOWN_TITLES_SIZE * 2> knownTitles;
2493
2494 for (uint32 index = 0; index < knownTitles.size(); ++index)
2495 {
2496 Optional<uint32> thisMask;
2497 if (index < tokens.size())
2498 thisMask = Acore::StringTo<uint32>(tokens[index]);
2499
2500 if (thisMask)
2501 knownTitles[index] = *thisMask;
2502 else
2503 {
2504 LOG_WARN("entities.player", "{} has invalid title data '{}' at index {} - skipped, this may result in titles being lost",
2505 GetPlayerInfo(), (index < tokens.size()) ? std::string(tokens[index]) : "<none>", index);
2506
2507 knownTitles[index] = 0;
2508 }
2509 }
2510
2511 for (auto const& [title_alliance, title_horde] : sObjectMgr->FactionChangeTitles)
2512 {
2513 CharTitlesEntry const* atitleInfo = sCharTitlesStore.LookupEntry(title_alliance);
2514 CharTitlesEntry const* htitleInfo = sCharTitlesStore.LookupEntry(title_horde);
2515
2516 // new team
2517 if (newTeam == TEAM_ALLIANCE)
2518 {
2519 uint32 bitIndex = htitleInfo->bit_index;
2520 uint32 index = bitIndex / 32;
2521 uint32 old_flag = 1 << (bitIndex % 32);
2522 uint32 new_flag = 1 << (atitleInfo->bit_index % 32);
2523
2524 if (knownTitles[index] & old_flag)
2525 {
2526 knownTitles[index] &= ~old_flag;
2527 // use index of the new title
2528 knownTitles[atitleInfo->bit_index / 32] |= new_flag;
2529 }
2530 }
2531 else
2532 {
2533 uint32 bitIndex = atitleInfo->bit_index;
2534 uint32 index = bitIndex / 32;
2535 uint32 old_flag = 1 << (bitIndex % 32);
2536 uint32 new_flag = 1 << (htitleInfo->bit_index % 32);
2537
2538 if (knownTitles[index] & old_flag)
2539 {
2540 knownTitles[index] &= ~old_flag;
2541 // use index of the new title
2542 knownTitles[htitleInfo->bit_index / 32] |= new_flag;
2543 }
2544 }
2545
2546 std::ostringstream ss;
2547 for (uint32 mask : knownTitles)
2548 ss << mask << ' ';
2549
2550 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TITLES_FACTION_CHANGE);
2551 stmt->SetData(0, ss.str().c_str());
2552 stmt->SetData(1, lowGuid);
2553 trans->Append(stmt);
2554
2555 // unset any currently chosen title
2556 stmt = CharacterDatabase.GetPreparedStatement(CHAR_RES_CHAR_TITLES_FACTION_CHANGE);
2557 stmt->SetData(0, lowGuid);
2558 trans->Append(stmt);
2559 }
2560 }
2561 }
2562 }
2563
2564 // Re-check all achievement criterias
2565 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
2567 stmt->SetData(1, lowGuid);
2568 trans->Append(stmt);
2569
2570 CharacterDatabase.CommitTransaction(trans);
2571
2572 LOG_DEBUG("entities.player", "{} (IP: {}) changed race from {} to {}", GetPlayerInfo(), GetRemoteAddress(), oldRace, factionChangeInfo->Race);
2573
2574 SendCharFactionChange(RESPONSE_SUCCESS, factionChangeInfo.get());
2575}
@ MAP_KALIMDOR
Definition AreaDefines.h:187
@ MAP_EASTERN_KINGDOMS
Definition AreaDefines.h:186
@ AREA_STORMWIND_CITY
Definition AreaDefines.h:81
@ AREA_ORGRIMMAR
Definition AreaDefines.h:83
@ CHAR_DEL_CHAR_SOCIAL_BY_FRIEND
Definition CharacterDatabase.h:395
@ CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE
Definition CharacterDatabase.h:398
@ CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST
Definition CharacterDatabase.h:441
@ CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_FACTION_CHANGE
Definition CharacterDatabase.h:442
@ CHAR_DEL_CHAR_SKILL_LANGUAGES
Definition CharacterDatabase.h:389
@ CHAR_UPD_CHAR_ACHIEVEMENT
Definition CharacterDatabase.h:397
@ CHAR_DEL_CHAR_DECLINED_NAME
Definition CharacterDatabase.h:386
@ CHAR_INS_PLAYER_HOMEBIND
Definition CharacterDatabase.h:242
@ CHAR_INS_CHAR_SKILL_LANGUAGE
Definition CharacterDatabase.h:390
@ CHAR_UPD_CHAR_SPELL_FACTION_CHANGE
Definition CharacterDatabase.h:400
@ CHAR_UPD_CHAR_TAXI_PATH
Definition CharacterDatabase.h:391
@ CHAR_UPD_CHAR_TAXIMASK
Definition CharacterDatabase.h:392
@ CHAR_DEL_PLAYER_HOMEBIND
Definition CharacterDatabase.h:244
@ CHAR_SEL_CHAR_REP_BY_FACTION
Definition CharacterDatabase.h:401
@ CHAR_DEL_CHAR_SPELL_BY_SPELL
Definition CharacterDatabase.h:399
@ CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST
Definition CharacterDatabase.h:444
@ CHAR_DEL_CHAR_ACHIEVEMENT_BY_ACHIEVEMENT
Definition CharacterDatabase.h:396
@ CHAR_DEL_CHAR_QUESTSTATUS
Definition CharacterDatabase.h:393
@ CHAR_UPD_CHAR_REP_FACTION_CHANGE
Definition CharacterDatabase.h:403
@ CHAR_UPD_CHAR_RACE
Definition CharacterDatabase.h:388
@ CHAR_UPD_CHAR_TITLES_FACTION_CHANGE
Definition CharacterDatabase.h:404
@ CHAR_DEL_CHAR_REP_BY_FACTION
Definition CharacterDatabase.h:402
@ CHAR_UPD_ADD_AT_LOGIN_FLAG
Definition CharacterDatabase.h:276
@ CHAR_RES_CHAR_TITLES_FACTION_CHANGE
Definition CharacterDatabase.h:405
@ CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE
Definition CharacterDatabase.h:443
@ CHAR_DEL_CHAR_SOCIAL_BY_GUID
Definition CharacterDatabase.h:394
DBCStorage< CharTitlesEntry > sCharTitlesStore(CharTitlesEntryfmt)
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
TaxiMask sAllianceTaxiNodesMask
Definition DBCStores.cpp:179
LFGDungeonEntry const * GetZoneLFGDungeonEntry(std::string const &zoneName, LocaleConstant locale)
Definition DBCStores.cpp:867
TaxiPathSetBySource sTaxiPathSetBySource
Definition DBCStores.cpp:183
TaxiPathNodesByPath sTaxiPathNodesByPath
Definition DBCStores.cpp:187
TaxiMask sDeathKnightTaxiNodesMask
Definition DBCStores.cpp:180
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
TaxiMask sHordeTaxiNodesMask
Definition DBCStores.cpp:178
std::array< uint32, TaxiMaskSize > TaxiMask
Definition DBCStructure.h:2247
std::vector< TaxiPathNodeEntry const * > TaxiPathNodeList
Definition DBCStructure.h:2243
std::map< uint32, TaxiPathEntry const * > TaxiPathSetForSource
Definition DBCStructure.h:2240
static constexpr std::size_t TaxiMaskSize
Definition DBCStructure.h:2246
#define LOG_WARN(filterType__,...)
Definition Log.h:162
@ PHASEMASK_NORMAL
Definition Object.h:62
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:24
#define KNOWN_TITLES_SIZE
Definition Player.h:547
@ AT_LOGIN_RESURRECT
Definition Player.h:606
@ AT_LOGIN_CHANGE_RACE
Definition Player.h:602
@ AT_LOGIN_CHECK_ACHIEVS
Definition Player.h:605
@ AT_LOGIN_CHANGE_FACTION
Definition Player.h:601
@ Race
Requires the player to be a specific race.
@ CHAR_CREATE_CHARACTER_IN_GUILD
Definition SharedDefines.h:3654
@ CHAR_CREATE_CHARACTER_DELETE_MAIL
Definition SharedDefines.h:3658
@ CHAR_CREATE_CHARACTER_GOLD_LIMIT
Definition SharedDefines.h:3662
@ CHAR_CREATE_CHARACTER_ARENA_LEADER
Definition SharedDefines.h:3657
@ CHAR_CREATE_CHARACTER_SWAP_FACTION
Definition SharedDefines.h:3659
@ CHAR_CREATE_CHARACTER_RACE_ONLY
Definition SharedDefines.h:3660
#define RACEMASK_HORDE
Definition SharedDefines.h:107
@ RACE_TROLL
Definition SharedDefines.h:78
@ RACE_UNDEAD_PLAYER
Definition SharedDefines.h:75
@ RACE_ORC
Definition SharedDefines.h:72
@ RACE_DRAENEI
Definition SharedDefines.h:81
@ RACE_NIGHTELF
Definition SharedDefines.h:74
@ RACE_BLOODELF
Definition SharedDefines.h:80
@ RACE_DWARF
Definition SharedDefines.h:73
@ RACE_GNOME
Definition SharedDefines.h:77
@ RACE_HUMAN
Definition SharedDefines.h:71
@ RACE_TAUREN
Definition SharedDefines.h:76
#define RACEMASK_ALLIANCE
Definition SharedDefines.h:103
@ CONFIG_CHANGE_FACTION_MAX_MONEY
Definition WorldConfig.h:378
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD
Definition WorldConfig.h:35
static void OfflineResurrect(ObjectGuid const &guid, CharacterDatabaseTransaction trans)
Definition Player.cpp:4573
static void LeaveAllArenaTeams(ObjectGuid guid)
Definition Player.cpp:10210
static void SavePositionInDB(uint32 mapid, float x, float y, float z, float o, uint32 zone, ObjectGuid guid)
Definition PlayerMisc.cpp:84
Definition Position.h:256
void WorldRelocate(const WorldLocation &loc)
Definition Position.h:264
std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition Tokenize.cpp:20
Definition DBCStructure.h:519
char const * area_name[16]
Definition DBCStructure.h:527
Definition DBCStructure.h:632
uint32 bit_index
Definition DBCStructure.h:639
uint8 Class
Definition CharacterCache.h:32
uint8 Level
Definition CharacterCache.h:35
ObjectGuid::LowType GuildId
Definition CharacterCache.h:37
std::string Name
Definition CharacterCache.h:30
uint8 MailCount
Definition CharacterCache.h:36
Definition DBCStructure.h:907
Definition DBCStructure.h:1243
uint32 MinLevel
Definition DBCStructure.h:1247
float GetPositionZ() const
Definition Position.h:123
Definition DBCStructure.h:1963
uint32 ID
Definition DBCStructure.h:1964
Definition DBCStructure.h:1971
float y
Definition DBCStructure.h:1977
float x
Definition DBCStructure.h:1976
uint32 mapid
Definition DBCStructure.h:1975
float z
Definition DBCStructure.h:1978

References AreaTableEntry::area_name, AREA_ORGRIMMAR, AREA_STORMWIND_CITY, AT_LOGIN_CHANGE_FACTION, AT_LOGIN_CHANGE_RACE, AT_LOGIN_CHECK_ACHIEVS, AT_LOGIN_RESURRECT, CharTitlesEntry::bit_index, CHAR_CREATE_CHARACTER_ARENA_LEADER, CHAR_CREATE_CHARACTER_DELETE_MAIL, CHAR_CREATE_CHARACTER_GOLD_LIMIT, CHAR_CREATE_CHARACTER_IN_GUILD, CHAR_CREATE_CHARACTER_RACE_ONLY, CHAR_CREATE_CHARACTER_SWAP_FACTION, CHAR_CREATE_ERROR, CHAR_CREATE_NAME_IN_USE, CHAR_DEL_CHAR_ACHIEVEMENT_BY_ACHIEVEMENT, CHAR_DEL_CHAR_DECLINED_NAME, CHAR_DEL_CHAR_QUESTSTATUS, CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST, CHAR_DEL_CHAR_REP_BY_FACTION, CHAR_DEL_CHAR_SKILL_LANGUAGES, CHAR_DEL_CHAR_SOCIAL_BY_FRIEND, CHAR_DEL_CHAR_SOCIAL_BY_GUID, CHAR_DEL_CHAR_SPELL_BY_SPELL, CHAR_DEL_PLAYER_HOMEBIND, CHAR_INS_CHAR_SKILL_LANGUAGE, CHAR_INS_PLAYER_HOMEBIND, CHAR_NAME_NO_NAME, CHAR_NAME_SUCCESS, CHAR_RES_CHAR_TITLES_FACTION_CHANGE, CHAR_SEL_CHAR_REP_BY_FACTION, CHAR_UPD_ADD_AT_LOGIN_FLAG, CHAR_UPD_CHAR_ACHIEVEMENT, CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE, CHAR_UPD_CHAR_NAME_AT_LOGIN, CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE, CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST, CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_FACTION_CHANGE, CHAR_UPD_CHAR_RACE, CHAR_UPD_CHAR_REP_FACTION_CHANGE, CHAR_UPD_CHAR_SPELL_FACTION_CHANGE, CHAR_UPD_CHAR_TAXI_PATH, CHAR_UPD_CHAR_TAXIMASK, CHAR_UPD_CHAR_TITLES_FACTION_CHANGE, CharacterDatabase, ObjectMgr::CheckPlayerName(), CharacterCacheEntry::Class, CLASS_DEATH_KNIGHT, CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND, CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD, CONFIG_CHANGE_FACTION_MAX_MONEY, CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK, Player::Customize(), Field::Get(), GetAccountId(), AuctionHouseObject::GetAuctions(), WorldLocation::GetMapId(), GetPlayerInfo(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), GetRemoteAddress(), GetSecurity(), GetSessionDbLocaleIndex(), GetZoneLFGDungeonEntry(), CharacterCacheEntry::GuildId, TaxiPathEntry::ID, AccountMgr::IsPlayerAccount(), KNOWN_TITLES_SIZE, Player::LeaveAllArenaTeams(), CharacterCacheEntry::Level, LOG_DEBUG, LOG_INFO, LOG_WARN, CharacterCacheEntry::MailCount, MAP_EASTERN_KINGDOMS, MAP_KALIMDOR, TaxiPathNodeEntry::mapid, LFGDungeonEntry::MinLevel, CharacterCacheEntry::Name, normalizePlayerName(), Player::OfflineResurrect(), PHASEMASK_NORMAL, CharacterCacheEntry::Race, RACE_BLOODELF, RACE_DRAENEI, RACE_DWARF, RACE_GNOME, RACE_HUMAN, RACE_NIGHTELF, RACE_ORC, RACE_TAUREN, RACE_TROLL, RACE_UNDEAD_PLAYER, RACEMASK_ALLIANCE, RACEMASK_HORDE, RESPONSE_SUCCESS, sAllianceTaxiNodesMask, sAreaTableStore, sArenaTeamMgr, sAuctionMgr, Player::SavePositionInDB(), sCharacterCache, sCharTitlesStore, sDeathKnightTaxiNodesMask, SendCharFactionChange(), PreparedStatementBase::SetData(), sFactionStore, sGuildMgr, sHordeTaxiNodesMask, sMapMgr, sObjectMgr, sTaxiPathNodesByPath, sTaxiPathSetBySource, sWorld, TaxiMaskSize, TEAM_ALLIANCE, TEAM_HORDE, Player::TeamIdForRace(), Acore::Tokenize(), WorldLocation::WorldRelocate(), TaxiPathNodeEntry::x, TaxiPathNodeEntry::y, and TaxiPathNodeEntry::z.

Referenced by HandleCharFactionOrRaceChange().

◆ HandleCharRenameCallBack()

void WorldSession::HandleCharRenameCallBack ( std::shared_ptr< CharacterRenameInfo renameInfo,
PreparedQueryResult  result 
)
1377{
1378 if (!result)
1379 {
1380 SendCharRename(CHAR_CREATE_ERROR, renameInfo.get());
1381 return;
1382 }
1383
1384 Field* fields = result->Fetch();
1385
1386 ObjectGuid::LowType guidLow = fields[0].Get<uint32>();
1387 std::string oldName = fields[1].Get<std::string>();
1388 uint16 atLoginFlags = fields[2].Get<uint16>();
1389
1390 if (!(atLoginFlags & AT_LOGIN_RENAME))
1391 {
1392 SendCharRename(CHAR_CREATE_ERROR, renameInfo.get());
1393 return;
1394 }
1395
1396 atLoginFlags &= ~AT_LOGIN_RENAME;
1397
1398 // pussywizard:
1399 if (ObjectAccessor::FindConnectedPlayer(ObjectGuid::Create<HighGuid::Player>(guidLow)) || sWorldSessionMgr->FindOfflineSessionForCharacterGUID(guidLow))
1400 {
1401 SendCharRename(CHAR_CREATE_ERROR, renameInfo.get());
1402 return;
1403 }
1404
1405 // Update name and at_login flag in the db
1407 stmt->SetData(0, renameInfo->Name);
1408 stmt->SetData(1, atLoginFlags);
1409 stmt->SetData(2, guidLow);
1410 CharacterDatabase.Execute(stmt);
1411
1412 // Removed declined name from db
1413 if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
1414 {
1415 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME);
1416 stmt->SetData(0, guidLow);
1417 CharacterDatabase.Execute(stmt);
1418 }
1419
1420 LOG_INFO("entities.player.character", "Account: {} (IP: {}), Character [{}] (guid: {}) Changed name to: {}", GetAccountId(), GetRemoteAddress(), oldName, guidLow, renameInfo->Name);
1421
1422 SendCharRename(RESPONSE_SUCCESS, renameInfo.get());
1423
1424 // xinef: update global data
1425 sCharacterCache->UpdateCharacterData(renameInfo->Guid, renameInfo->Name);
1426}
@ AT_LOGIN_RENAME
Definition Player.h:595
void SendCharRename(ResponseCodes result, CharacterRenameInfo const *renameInfo)
Definition CharacterHandler.cpp:2598

References AT_LOGIN_RENAME, CHAR_CREATE_ERROR, CHAR_DEL_DECLINED_NAME, CHAR_UPD_CHAR_NAME_AT_LOGIN, CharacterDatabase, CONFIG_DECLINED_NAMES_USED, ObjectAccessor::FindConnectedPlayer(), Field::Get(), GetAccountId(), GetRemoteAddress(), LOG_INFO, RESPONSE_SUCCESS, sCharacterCache, SendCharRename(), PreparedStatementBase::SetData(), sWorld, and sWorldSessionMgr.

Referenced by HandleCharRenameOpcode().

◆ HandleCharRenameOpcode()

void WorldSession::HandleCharRenameOpcode ( WorldPacket recvData)
1344{
1345 std::shared_ptr<CharacterRenameInfo> renameInfo = std::make_shared<CharacterRenameInfo>();
1346
1347 recvData >> renameInfo->Guid
1348 >> renameInfo->Name;
1349
1350 // prevent character rename to invalid name
1351 if (!normalizePlayerName(renameInfo->Name))
1352 {
1353 SendCharRename(CHAR_NAME_NO_NAME, renameInfo.get());
1354 return;
1355 }
1356
1357 uint8 res = ObjectMgr::CheckPlayerName(renameInfo->Name, true);
1358 if (res != CHAR_NAME_SUCCESS)
1359 {
1360 SendCharRename(ResponseCodes(res), renameInfo.get());
1361 return;
1362 }
1363
1364 // Ensure that the character belongs to the current account, that rename at login is enabled
1365 // and that there is no character with the desired new name
1367
1368 stmt->SetData(0, renameInfo->Guid.GetCounter());
1369 stmt->SetData(1, GetAccountId());
1370 stmt->SetData(2, renameInfo->Name);
1371
1373 .WithPreparedCallback(std::bind(&WorldSession::HandleCharRenameCallBack, this, renameInfo, std::placeholders::_1)));
1374}
@ CHAR_SEL_FREE_NAME
Definition CharacterDatabase.h:50
void HandleCharRenameCallBack(std::shared_ptr< CharacterRenameInfo > renameInfo, PreparedQueryResult result)
Definition CharacterHandler.cpp:1376

References _queryProcessor, AsyncCallbackProcessor< T >::AddCallback(), CHAR_NAME_NO_NAME, CHAR_NAME_SUCCESS, CHAR_SEL_FREE_NAME, CharacterDatabase, ObjectMgr::CheckPlayerName(), GetAccountId(), HandleCharRenameCallBack(), normalizePlayerName(), SendCharRename(), and PreparedStatementBase::SetData().

Referenced by OpcodeTable::Initialize().

◆ HandleChatIgnoredOpcode()

void WorldSession::HandleChatIgnoredOpcode ( WorldPacket recvPacket)
749{
750 ObjectGuid iguid;
751 uint8 unk;
752
753 recvData >> iguid;
754 recvData >> unk; // probably related to spam reporting
755
757 if (!player)
758 return;
759
760 WorldPacket data;
762 player->SendDirectMessage(&data);
763}
@ CHAT_MSG_IGNORED
Definition SharedDefines.h:3427
@ LANG_UNIVERSAL
Definition SharedDefines.h:746
static std::size_t BuildChatPacket(WorldPacket &data, ChatMsg chatType, Language language, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string_view message, uint8 chatTag, std::string const &senderName="", std::string const &receiverName="", uint32 achievementId=0, bool gmMessage=false, std::string const &channelName="")
Definition Chat.cpp:265

References _player, ChatHandler::BuildChatPacket(), CHAT_MSG_IGNORED, ObjectAccessor::FindConnectedPlayer(), GetPlayer(), LANG_UNIVERSAL, and Player::SendDirectMessage().

Referenced by OpcodeTable::Initialize().

◆ HandleClearChannelWatch()

void WorldSession::HandleClearChannelWatch ( WorldPacket recvPacket)
318{
319 std::string channelName;
320 recvPacket >> channelName;
321
322 if (channelName.empty())
323 return;
324
326 if (Channel* channel = cMgr->GetChannel(channelName, nullptr, false))
327 channel->RemoveWatching(GetPlayer());
328}

References ChannelMgr::forTeam(), GetPlayer(), and GetTeamId().

Referenced by OpcodeTable::Initialize().

◆ HandleClearTradeItemOpcode()

void WorldSession::HandleClearTradeItemOpcode ( WorldPacket recvPacket)
717{
718 uint8 tradeSlot;
719 recvPacket >> tradeSlot;
720
721 TradeData* my_trade = _player->m_trade;
722 if (!my_trade)
723 return;
724
725 // invalid slot number
726 if (tradeSlot >= TRADE_SLOT_COUNT)
727 return;
728
729 my_trade->SetItem(TradeSlots(tradeSlot), nullptr);
730}
@ TRADE_SLOT_COUNT
Definition TradeData.h:29
void SetItem(TradeSlots slot, Item *item)
Definition TradeData.cpp:54

References _player, Player::m_trade, TradeData::SetItem(), and TRADE_SLOT_COUNT.

Referenced by OpcodeTable::Initialize().

◆ HandleClientCastFlags()

void WorldSession::HandleClientCastFlags ( WorldPacket recvPacket,
uint8  castFlags,
SpellCastTargets targets 
)
36{
37 // some spell cast packet including more data (for projectiles?)
38 if (castFlags & 0x02)
39 {
40 // not sure about these two
41 float elevation, speed;
42 recvPacket >> elevation;
43 recvPacket >> speed;
44
45 targets.SetElevation(elevation);
46 targets.SetSpeed(speed);
47
48 uint8 hasMovementData;
49 recvPacket >> hasMovementData;
50 if (hasMovementData)
51 {
52 recvPacket.SetOpcode(recvPacket.read<uint32>());
53 HandleMovementOpcodes(recvPacket);
54 }
55 }
56}
T read()
Definition ByteBuffer.h:351
void SetSpeed(float speed)
Definition Spell.h:181
void SetElevation(float elevation)
Definition Spell.h:179
void SetOpcode(uint16 opcode)
Definition WorldPacket.h:76
void HandleMovementOpcodes(WorldPacket &recvPacket)
Definition MovementHandler.cpp:343

References HandleMovementOpcodes(), ByteBuffer::read(), SpellCastTargets::SetElevation(), WorldPacket::SetOpcode(), and SpellCastTargets::SetSpeed().

Referenced by HandleCastSpellOpcode(), HandlePetCastSpellOpcode(), and HandleUseItemOpcode().

◆ HandleComplainOpcode()

void WorldSession::HandleComplainOpcode ( WorldPackets::Misc::Complain packet)
1143{
1144 LOG_DEBUG("network", "WORLD: CMSG_COMPLAIN");
1145
1146 // NOTE: all chat messages from this spammer automatically ignored by spam reporter until logout in case chat spam.
1147 // if it's mail spam - ALL mails from this spammer automatically removed by client
1148
1149 // Complaint Received message
1151
1152 LOG_DEBUG("network", "REPORT SPAM: type {}, {}, unk1 {}, unk2 {}, unk3 {}, unk4 {}, message {}",
1153 packet.SpamType, packet.SpammerGuid.ToString(), packet.Unk1, packet.Unk2, packet.Unk3, packet.Unk4, packet.Description);
1154}
Definition MiscPackets.h:231
uint32 Unk2
Definition MiscPackets.h:224
ObjectGuid SpammerGuid
Definition MiscPackets.h:222
std::string Description
Definition MiscPackets.h:227
uint32 Unk3
Definition MiscPackets.h:225
uint32 Unk1
Definition MiscPackets.h:223
uint32 Unk4
Definition MiscPackets.h:226
uint8 SpamType
Definition MiscPackets.h:221

References WorldPackets::Misc::Complain::Description, LOG_DEBUG, SendPacket(), WorldPackets::Misc::Complain::SpammerGuid, WorldPackets::Misc::Complain::SpamType, ObjectGuid::ToString(), WorldPackets::Misc::Complain::Unk1, WorldPackets::Misc::Complain::Unk2, WorldPackets::Misc::Complain::Unk3, and WorldPackets::Misc::Complain::Unk4.

Referenced by OpcodeTable::Initialize().

◆ HandleCompleteCinematic()

void WorldSession::HandleCompleteCinematic ( WorldPacket recvPacket)
942{
943 // If player has sight bound to visual waypoint NPC we should remove it
945}
void EndCinematic()
Definition CinematicMgr.cpp:74
CinematicMgr * GetCinematicMgr() const
Definition Player.h:1378

References CinematicMgr::EndCinematic(), Player::GetCinematicMgr(), and GetPlayer().

Referenced by OpcodeTable::Initialize().

◆ HandleContactListOpcode()

void WorldSession::HandleContactListOpcode ( WorldPacket recvPacket)
30{
31 uint32 flags;
32 recv_data >> flags;
33
35}
void SendSocialList(Player *player, uint32 flags)
Definition SocialMgr.cpp:124

References _player, Player::GetSocial(), and PlayerSocial::SendSocialList().

Referenced by OpcodeTable::Initialize().

◆ HandleCorpseMapPositionQuery()

void WorldSession::HandleCorpseMapPositionQuery ( WorldPackets::Query::CorpseMapPositionQuery packet)
400{
401 LOG_DEBUG("network", "WORLD: Recv CMSG_CORPSE_MAP_POSITION_QUERY");
402
404 data << float(0);
405 data << float(0);
406 data << float(0);
407 data << float(0);
408 SendPacket(&data);
409}
@ SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE
Definition Opcodes.h:1237

References LOG_DEBUG, SendPacket(), and SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE.

Referenced by OpcodeTable::Initialize().

◆ HandleCorpseQueryOpcode()

void WorldSession::HandleCorpseQueryOpcode ( WorldPacket recvPacket)
227{
228 if (!_player->HasCorpse())
229 {
231 data << uint8(0); // corpse not found
232 SendPacket(&data);
233 return;
234 }
235
236 WorldLocation corpseLocation = _player->GetCorpseLocation();
237 uint32 corpseMapID = corpseLocation.GetMapId();
238 uint32 mapID = corpseLocation.GetMapId();
239 float x = corpseLocation.GetPositionX();
240 float y = corpseLocation.GetPositionY();
241 float z = corpseLocation.GetPositionZ();
242
243 // if corpse at different map
244 if (mapID != _player->GetMapId())
245 {
246 // search entrance map for proper show entrance
247 if (MapEntry const* corpseMapEntry = sMapStore.LookupEntry(mapID))
248 {
249 if (corpseMapEntry->IsDungeon() && corpseMapEntry->entrance_map >= 0)
250 {
251 // if corpse map have entrance
252 if (Map const* entranceMap = sMapMgr->CreateBaseMap(corpseMapEntry->entrance_map))
253 {
254 mapID = corpseMapEntry->entrance_map;
255 x = corpseMapEntry->entrance_x;
256 y = corpseMapEntry->entrance_y;
257 z = entranceMap->GetHeight(GetPlayer()->GetPhaseMask(), x, y, MAX_HEIGHT);
258 }
259 }
260 }
261 }
262
263 WorldPacket data(MSG_CORPSE_QUERY, 1 + (6 * 4));
264 data << uint8(1); // corpse found
265 data << int32(mapID);
266 data << float(x);
267 data << float(y);
268 data << float(z);
269 data << int32(corpseMapID);
270 data << uint32(0); // unknown
271 SendPacket(&data);
272}
#define MAX_HEIGHT
Definition GridTerrainData.h:26
Definition Map.h:163
@ MSG_CORPSE_QUERY
Definition Opcodes.h:564

References _player, Player::GetCorpseLocation(), WorldLocation::GetMapId(), GetPlayer(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::HasCorpse(), MAX_HEIGHT, MSG_CORPSE_QUERY, SendPacket(), sMapMgr, and sMapStore.

Referenced by OpcodeTable::Initialize().

◆ HandleCreatureQueryOpcode()

void WorldSession::HandleCreatureQueryOpcode ( WorldPacket recvPacket)

Only static data is sent in this packet !!!

89{
90 uint32 entry;
91 recvData >> entry;
92 ObjectGuid guid;
93 recvData >> guid;
94
95 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(entry);
96 if (ci)
97 {
98 std::string Name, Title;
99 Name = ci->Name;
100 Title = ci->SubName;
101
103 if (loc_idx >= 0)
104 {
105 if (CreatureLocale const* cl = sObjectMgr->GetCreatureLocale(entry))
106 {
107 ObjectMgr::GetLocaleString(cl->Name, loc_idx, Name);
108 ObjectMgr::GetLocaleString(cl->Title, loc_idx, Title);
109 }
110 }
111 // guess size
113 data << uint32(entry); // creature entry
114 data << Name;
115 data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty
116 data << Title;
117 data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0
118 data << uint32(ci->type_flags); // flags
119 data << uint32(ci->type); // CreatureType.dbc
120 data << uint32(ci->family); // CreatureFamily.dbc
121 data << uint32(ci->rank); // Creature Rank (elite, boss, etc)
122 data << uint32(ci->KillCredit[0]); // new in 3.1, kill credit
123 data << uint32(ci->KillCredit[1]); // new in 3.1, kill credit
124 if (ci->GetModelByIdx(0))
125 data << uint32(ci->GetModelByIdx(0)->CreatureDisplayID); // Modelid1
126 else
127 data << uint32(0); // Modelid1
128 if (ci->GetModelByIdx(1))
129 data << uint32(ci->GetModelByIdx(1)->CreatureDisplayID); // Modelid2
130 else
131 data << uint32(0); // Modelid2
132 if (ci->GetModelByIdx(2))
133 data << uint32(ci->GetModelByIdx(2)->CreatureDisplayID); // Modelid3
134 else
135 data << uint32(0); // Modelid3
136 if (ci->GetModelByIdx(3))
137 data << uint32(ci->GetModelByIdx(3)->CreatureDisplayID); // Modelid4
138 else
139 data << uint32(0); // Modelid4
140 data << float(ci->ModHealth); // dmg/hp modifier
141 data << float(ci->ModMana); // dmg/mana modifier
142 data << uint8(ci->RacialLeader);
143
144 CreatureQuestItemList const* items = sObjectMgr->GetCreatureQuestItemList(entry);
145 if (items)
146 for (std::size_t i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
147 data << (i < items->size() ? uint32((*items)[i]) : uint32(0));
148 else
149 for (std::size_t i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
150 data << uint32(0);
151
152 data << uint32(ci->movementId); // CreatureMovementInfo.dbc
153 SendPacket(&data);
154 }
155 else
156 {
157 LOG_DEBUG("network", "WORLD: CMSG_CREATURE_QUERY - NO CREATURE INFO! ({})", guid.ToString());
159 data << uint32(entry | 0x80000000);
160 SendPacket(&data);
161 LOG_DEBUG("network", "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE");
162 }
163}
LocaleConstant
Definition Common.h:117
std::vector< uint32 > CreatureQuestItemList
Definition CreatureData.h:288
#define MAX_CREATURE_QUEST_ITEMS
Definition CreatureData.h:33
static std::string_view GetLocaleString(std::vector< std::string > const &data, std::size_t locale)
Definition ObjectMgr.h:1419
@ SMSG_CREATURE_QUERY_RESPONSE
Definition Opcodes.h:127
Definition CreatureData.h:343
uint32 CreatureDisplayID
Definition CreatureData.h:179
CreatureModel const * GetModelByIdx(uint32 idx) const
Definition Creature.cpp:123
float ModHealth
Definition CreatureData.h:237
float ModMana
Definition CreatureData.h:238
uint32 type
Definition CreatureData.h:222
uint32 rank
Definition CreatureData.h:206
std::string SubName
Definition CreatureData.h:192
std::string Name
Definition CreatureData.h:191
uint32 KillCredit[MAX_KILL_CREDIT]
Definition CreatureData.h:189
bool RacialLeader
Definition CreatureData.h:241
uint32 type_flags
Definition CreatureData.h:223
uint32 family
Definition CreatureData.h:217
uint32 movementId
Definition CreatureData.h:242
std::string IconName
Definition CreatureData.h:193

References CreatureModel::CreatureDisplayID, CreatureTemplate::family, ObjectMgr::GetLocaleString(), CreatureTemplate::GetModelByIdx(), GetSessionDbLocaleIndex(), CreatureTemplate::IconName, CreatureTemplate::KillCredit, LOG_DEBUG, MAX_CREATURE_QUEST_ITEMS, CreatureTemplate::ModHealth, CreatureTemplate::ModMana, CreatureTemplate::movementId, CreatureTemplate::Name, CreatureTemplate::RacialLeader, CreatureTemplate::rank, SendPacket(), SMSG_CREATURE_QUERY_RESPONSE, sObjectMgr, CreatureTemplate::SubName, ObjectGuid::ToString(), CreatureTemplate::type, and CreatureTemplate::type_flags.

Referenced by OpcodeTable::Initialize().

◆ HandleDelFriendOpcode()

void WorldSession::HandleDelFriendOpcode ( WorldPacket recvPacket)
92{
93 ObjectGuid FriendGUID;
94 recv_data >> FriendGUID;
95
97
98 sSocialMgr->SendFriendStatus(GetPlayer(), FRIEND_REMOVED, FriendGUID, false);
99
100 LOG_DEBUG("network", "WORLD: Sent motd (SMSG_FRIEND_STATUS)");
101}
@ FRIEND_REMOVED
Definition SocialMgr.h:71
void RemoveFromSocialList(ObjectGuid const &friend_guid, SocialFlag flag)
Definition SocialMgr.cpp:74

References _player, FRIEND_REMOVED, GetPlayer(), Player::GetSocial(), LOG_DEBUG, PlayerSocial::RemoveFromSocialList(), SOCIAL_FLAG_FRIEND, and sSocialMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleDelIgnoreOpcode()

void WorldSession::HandleDelIgnoreOpcode ( WorldPacket recvPacket)
139{
140 ObjectGuid IgnoreGUID;
141 recv_data >> IgnoreGUID;
142
144 sSocialMgr->SendFriendStatus(GetPlayer(), FRIEND_IGNORE_REMOVED, IgnoreGUID, false);
145}
@ FRIEND_IGNORE_REMOVED
Definition SocialMgr.h:82

References _player, FRIEND_IGNORE_REMOVED, GetPlayer(), Player::GetSocial(), PlayerSocial::RemoveFromSocialList(), SOCIAL_FLAG_IGNORED, and sSocialMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleDestroyItemOpcode()

void WorldSession::HandleDestroyItemOpcode ( WorldPackets::Item::DestroyItem packet)
281{
282 //LOG_DEBUG("network.opcode", "WORLD: CMSG_DESTROYITEM");
283
284 uint16 pos = (packet.Bag << 8) | packet.Slot;
285
286 // prevent drop unequipable items (in combat, for example) and non-empty bags
287 if (_player->IsEquipmentPos(pos) || _player->IsBagPos(pos))
288 {
289 InventoryResult msg = _player->CanUnequipItem(pos, false);
290 if (msg != EQUIP_ERR_OK)
291 {
292 _player->SendEquipError(msg, _player->GetItemByPos(pos), nullptr);
293 return;
294 }
295 }
296
297 Item* pItem = _player->GetItemByPos(packet.Bag, packet.Slot);
298 if (!pItem)
299 {
301 return;
302 }
303
305 {
307 return;
308 }
309
310 recoveryItem(pItem);
311
312 if (packet.Count)
313 {
314 uint32 i_count = packet.Count;
315 _player->DestroyItemCount(pItem, i_count, true);
316 }
317 else
318 {
319 _player->DestroyItem(packet.Bag, packet.Slot, true);
320 }
322}
@ ITEM_FLAG_NO_USER_DESTROY
Definition ItemTemplate.h:152
@ EQUIP_ERR_CANT_DROP_SOULBOUND
Definition Item.h:71
void SendQuestGiverStatusMultiple()
Definition Player.cpp:7761
uint8 Bag
Definition ItemPackets.h:96
uint8 Count
Definition ItemPackets.h:98
uint8 Slot
Definition ItemPackets.h:97
bool recoveryItem(Item *pItem)
Definition ItemHandler.cpp:1479

References _player, WorldPackets::Item::DestroyItem::Bag, Player::CanUnequipItem(), WorldPackets::Item::DestroyItem::Count, Player::DestroyItem(), Player::DestroyItemCount(), EQUIP_ERR_CANT_DROP_SOULBOUND, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_OK, Player::GetItemByPos(), Item::GetTemplate(), ItemTemplate::HasFlag(), Player::IsBagPos(), Player::IsEquipmentPos(), ITEM_FLAG_NO_USER_DESTROY, recoveryItem(), Player::SendEquipError(), Player::SendQuestGiverStatusMultiple(), and WorldPackets::Item::DestroyItem::Slot.

Referenced by OpcodeTable::Initialize().

◆ HandleDismissControlledVehicle()

void WorldSession::HandleDismissControlledVehicle ( WorldPacket recvData)
27{
28 LOG_DEBUG("network", "WORLD: Recvd CMSG_DISMISS_CONTROLLED_VEHICLE");
29
30 ObjectGuid vehicleGUID = _player->GetCharmGUID();
31
32 if (!vehicleGUID) // something wrong here...
33 {
34 recvData.rfinish(); // prevent warnings spam
35 return;
36 }
37
38 ObjectGuid guid;
39 recvData >> guid.ReadAsPacked();
40
41 // pussywizard: typical check for incomming movement packets
43 {
44 recvData.rfinish(); // prevent warnings spam
46 return;
47 }
48
49 MovementInfo mi;
50 mi.guid = guid;
51 ReadMovementInfo(recvData, &mi);
52
53 if (_player->m_mover->IsRooted()) // for some reason client sends it without it even if rooted
55
57
59}
@ MOVEMENTFLAG_ROOT
Definition UnitDefines.h:380
bool IsDuringRemoveFromWorld() const
Definition Unit.h:693
bool IsRooted() const
Definition Unit.h:1695
void ExitVehicle(Position const *exitPosition=nullptr)
Definition Unit.cpp:19713
bool ProcessMovementInfo(MovementInfo &movementInfo, Unit *mover, Player *plrMover, WorldPacket &recvData)
Definition MovementHandler.cpp:596
void AddMovementFlag(uint32 flag)
Definition Object.h:343

References _player, MovementInfo::AddMovementFlag(), Unit::ExitVehicle(), Unit::GetCharmGUID(), Object::GetGUID(), MovementInfo::guid, Unit::IsDuringRemoveFromWorld(), Object::IsInWorld(), Unit::IsRooted(), LOG_DEBUG, Player::m_mover, MOVEMENTFLAG_ROOT, ProcessMovementInfo(), ObjectGuid::ReadAsPacked(), ReadMovementInfo(), ByteBuffer::rfinish(), and Object::ToPlayer().

Referenced by OpcodeTable::Initialize().

◆ HandleDismissCritter()

void WorldSession::HandleDismissCritter ( WorldPackets::Pet::DismissCritter dismissCritter)
40{
41 Unit* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, packet.CritterGUID);
42
43 if (!pet)
44 {
45 LOG_DEBUG("network", "Vanitypet ({}) does not exist - player {} ({} / account: {}) attempted to dismiss it (possibly lagged out)",
46 packet.CritterGUID.ToString(), GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString(), GetAccountId());
47 return;
48 }
49
50 if (_player->GetCritterGUID() == pet->GetGUID())
51 {
52 if (pet->IsCreature() && pet->ToCreature()->IsSummon())
53 pet->ToTempSummon()->UnSummon();
54 }
55}
virtual void UnSummon(Milliseconds msTime=0ms)
Definition TemporarySummon.cpp:287
TempSummon * ToTempSummon()
Definition Unit.h:721
bool IsSummon() const
Definition Unit.h:784
ObjectGuid GetCritterGUID() const
Definition Unit.h:715
Creature * GetCreatureOrPetOrVehicle(WorldObject const &, ObjectGuid const &)
Definition ObjectAccessor.cpp:234

References _player, WorldPackets::Pet::DismissCritter::CritterGUID, GetAccountId(), ObjectAccessor::GetCreatureOrPetOrVehicle(), Unit::GetCritterGUID(), Object::GetGUID(), GetPlayer(), Object::IsCreature(), Unit::IsSummon(), LOG_DEBUG, Object::ToCreature(), ObjectGuid::ToString(), Unit::ToTempSummon(), and TempSummon::UnSummon().

Referenced by OpcodeTable::Initialize().

◆ HandleDuelAcceptedOpcode()

void WorldSession::HandleDuelAcceptedOpcode ( WorldPacket recvPacket)
26{
27 Player* player = GetPlayer();
28 if (!player->duel || player == player->duel->Initiator || player->duel->State != DUEL_STATE_CHALLENGED)
29 return;
30
31 ObjectGuid guid;
32 recvPacket >> guid;
33
34 Player* target = player->duel->Opponent;
35 if (target->GetGuidValue(PLAYER_DUEL_ARBITER) != guid)
36 return;
37
38 LOG_DEBUG("network.opcode", "Player 1 is: {} ({})", player->GetGUID().ToString(), player->GetName());
39 LOG_DEBUG("network.opcode", "Player 2 is: {} ({})", target->GetGUID().ToString(), target->GetName());
40
41 time_t now = GameTime::GetGameTime().count();
42 player->duel->StartTime = now + 3;
43 target->duel->StartTime = now + 3;
44
45 player->duel->State = DUEL_STATE_COUNTDOWN;
46 target->duel->State = DUEL_STATE_COUNTDOWN;
47
48 player->SendDuelCountdown(3000);
49 target->SendDuelCountdown(3000);
50}
@ DUEL_STATE_CHALLENGED
Definition Player.h:366
@ DUEL_STATE_COUNTDOWN
Definition Player.h:367
@ PLAYER_DUEL_ARBITER
Definition UpdateFields.h:177
ObjectGuid GetGuidValue(uint16 index) const
Definition Object.cpp:326
void SendDuelCountdown(uint32 counter)
Definition Player.cpp:15458
std::unique_ptr< DuelInfo > duel
Definition Player.h:1873

References Player::duel, DUEL_STATE_CHALLENGED, DUEL_STATE_COUNTDOWN, GameTime::GetGameTime(), Object::GetGUID(), Object::GetGuidValue(), WorldObject::GetName(), GetPlayer(), LOG_DEBUG, PLAYER_DUEL_ARBITER, Player::SendDuelCountdown(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleDuelCancelledOpcode()

void WorldSession::HandleDuelCancelledOpcode ( WorldPacket recvPacket)
53{
54 Player* player = GetPlayer();
55
56 ObjectGuid guid;
57 recvPacket >> guid;
58
59 // no duel requested
60 if (!player->duel || player->duel->State == DUEL_STATE_COMPLETED)
61 return;
62
63 // player surrendered in a duel using /forfeit
64 if (GetPlayer()->duel->State == DUEL_STATE_IN_PROGRESS)
65 {
67 GetPlayer()->duel->Opponent->CombatStopWithPets(true);
68
69 GetPlayer()->CastSpell(GetPlayer(), 7267, true); // beg
71 return;
72 }
73
75}
@ DUEL_STATE_COMPLETED
Definition Player.h:369
@ DUEL_STATE_IN_PROGRESS
Definition Player.h:368
@ DUEL_WON
Definition SharedDefines.h:3879
@ DUEL_INTERRUPTED
Definition SharedDefines.h:3878
void DuelComplete(DuelCompleteType type)
Definition Player.cpp:6470
SpellCastResult CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition Unit.cpp:1194
void CombatStopWithPets(bool includingCast=false)
Definition Unit.cpp:10658

References Unit::CastSpell(), Unit::CombatStopWithPets(), Player::duel, DUEL_INTERRUPTED, DUEL_STATE_COMPLETED, DUEL_STATE_IN_PROGRESS, DUEL_WON, Player::DuelComplete(), and GetPlayer().

Referenced by OpcodeTable::Initialize().

◆ HandleEjectPassenger()

void WorldSession::HandleEjectPassenger ( WorldPacket data)
166{
167 Vehicle* vehicle = _player->GetVehicleKit();
168 if (!vehicle)
169 {
170 data.rfinish(); // prevent warnings spam
171 LOG_ERROR("network.opcode", "HandleEjectPassenger: Player {} is not in a vehicle!", GetPlayer()->GetGUID().ToString());
172 return;
173 }
174
175 ObjectGuid guid;
176 data >> guid;
177
178 if (guid.IsPlayer())
179 {
180 Player* player = ObjectAccessor::GetPlayer(*_player, guid);
181 if (!player)
182 {
183 LOG_ERROR("network.opcode", "Player {} tried to eject player {} from vehicle, but the latter was not found in world!", GetPlayer()->GetGUID().ToString(), guid.ToString());
184 return;
185 }
186
187 if (!player->IsOnVehicle(vehicle->GetBase()))
188 {
189 LOG_ERROR("network.opcode", "Player {} tried to eject player {}, but they are not in the same vehicle", GetPlayer()->GetGUID().ToString(), guid.ToString());
190 return;
191 }
192
193 VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(player);
194 ASSERT(seat);
195 if (seat->IsEjectable())
196 player->ExitVehicle();
197 else
198 LOG_ERROR("network.opcode", "Player {} attempted to eject player {} from non-ejectable seat.", GetPlayer()->GetGUID().ToString(), guid.ToString());
199 }
200 else if (guid.IsCreature())
201 {
202 Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
203 if (!unit) // creatures can be ejected too from player mounts
204 {
205 LOG_ERROR("network.opcode", "Player {} tried to eject creature guid {} from vehicle, but the latter was not found in world!", GetPlayer()->GetGUID().ToString(), guid.ToString());
206 return;
207 }
208
209 if (!unit->IsOnVehicle(vehicle->GetBase()))
210 {
211 LOG_ERROR("network.opcode", "Player {} tried to eject unit {}, but they are not in the same vehicle", GetPlayer()->GetGUID().ToString(), guid.ToString());
212 return;
213 }
214
215 VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(unit);
216 ASSERT(seat);
217 if (seat->IsEjectable())
218 {
219 ASSERT(GetPlayer() == vehicle->GetBase());
220 unit->ExitVehicle();
221 }
222 else
223 LOG_ERROR("network.opcode", "Player {} attempted to eject creature {} from non-ejectable seat.", GetPlayer()->GetGUID().ToString(), guid.ToString());
224 }
225 else
226 LOG_ERROR("network.opcode", "HandleEjectPassenger: Player {} tried to eject invalid {}", GetPlayer()->GetGUID().ToString(), guid.ToString());
227}
bool IsPlayer() const
Definition ObjectGuid.h:168
bool IsCreature() const
Definition ObjectGuid.h:162
bool IsOnVehicle(Unit const *vehicle) const
Definition Unit.h:1906
Unit * GetBase() const
May be called from scripts.
Definition Vehicle.h:37
bool IsEjectable() const
Definition DBCStructure.h:2124

References _player, ASSERT, Unit::ExitVehicle(), Vehicle::GetBase(), GetPlayer(), ObjectAccessor::GetPlayer(), Vehicle::GetSeatForPassenger(), ObjectAccessor::GetUnit(), Unit::GetVehicleKit(), ObjectGuid::IsCreature(), VehicleSeatEntry::IsEjectable(), Unit::IsOnVehicle(), ObjectGuid::IsPlayer(), LOG_ERROR, ByteBuffer::rfinish(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleEmoteOpcode()

void WorldSession::HandleEmoteOpcode ( WorldPackets::Chat::EmoteClient packet)
635{
636 if (GetPlayer()->IsSpectator())
637 return;
638
639 uint32 emoteId = packet.EmoteID;
640
641 // restrict to the only emotes hardcoded in client
642 if (emoteId != EMOTE_ONESHOT_NONE && emoteId != EMOTE_ONESHOT_WAVE)
643 return;
644
646 return;
647
648 sScriptMgr->OnPlayerEmote(_player, emoteId);
649 _player->HandleEmoteCommand(emoteId);
650}
@ EMOTE_ONESHOT_NONE
Definition SharedDefines.h:1905
@ EMOTE_ONESHOT_WAVE
Definition SharedDefines.h:1908
void HandleEmoteCommand(uint32 emoteId)
Definition Unit.cpp:2036
uint32 EmoteID
Definition ChatPackets.h:46

References _player, EMOTE_ONESHOT_NONE, EMOTE_ONESHOT_WAVE, WorldPackets::Chat::EmoteClient::EmoteID, GetPlayer(), Unit::HandleEmoteCommand(), Unit::HasUnitState(), Unit::IsAlive(), sScriptMgr, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleEnterPlayerVehicle()

void WorldSession::HandleEnterPlayerVehicle ( WorldPacket data)
144{
145 // Read guid
146 ObjectGuid guid;
147 data >> guid;
148
149 if (Player* player = ObjectAccessor::GetPlayer(*_player, guid))
150 {
151 if (!player->GetVehicleKit())
152 return;
153 if (!player->IsInRaidWith(_player))
154 return;
155 if (!player->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
156 return;
157 // Xinef:
159 return;
160
161 _player->EnterVehicle(player);
162 }
163}
bool IsBattleArena() const
Definition Map.h:302
void EnterVehicle(Unit *base, int8 seatId=-1)
Definition Unit.cpp:19617

References _player, Unit::EnterVehicle(), WorldObject::FindMap(), ObjectAccessor::GetPlayer(), INTERACTION_DISTANCE, and Map::IsBattleArena().

Referenced by OpcodeTable::Initialize().

◆ HandleEquipmentSetDelete()

void WorldSession::HandleEquipmentSetDelete ( WorldPacket recvData)
1822{
1823 LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_DELETE");
1824
1825 uint64 setGuid;
1826 recvData.readPackGUID(setGuid);
1827
1828 _player->DeleteEquipmentSet(setGuid);
1829}
void readPackGUID(uint64 &guid)
Definition ByteBuffer.h:387
void DeleteEquipmentSet(uint64 setGuid)
Definition Player.cpp:14732

References _player, Player::DeleteEquipmentSet(), LOG_DEBUG, and ByteBuffer::readPackGUID().

Referenced by OpcodeTable::Initialize().

◆ HandleEquipmentSetSave()

void WorldSession::HandleEquipmentSetSave ( WorldPacket recvData)
1751{
1752 LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_SAVE");
1753
1754 uint64 setGuid;
1755 recvData.readPackGUID(setGuid);
1756
1757 uint32 index;
1758 recvData >> index;
1759 if (index >= MAX_EQUIPMENT_SET_INDEX) // client set slots amount
1760 return;
1761
1762 std::string name;
1763 recvData >> name;
1764
1765 if (name.length() > 16) // Client limitation
1766 {
1767 LOG_ERROR("entities.player.cheat", "Character GUID {} tried to create equipment set {} with too long a name!", _player->GetGUID().ToString(), setGuid);
1768 return;
1769 }
1770
1771 std::string iconName;
1772 recvData >> iconName;
1773
1774 if (iconName.length() > 100) // DB limitation
1775 {
1776 LOG_ERROR("entities.player.cheat", "Character GUID {} tried to create equipment set {} with too long an icon name!", _player->GetGUID().ToString(), setGuid);
1777 return;
1778 }
1779
1780 EquipmentSet eqSet;
1781
1782 eqSet.Guid = setGuid;
1783 eqSet.Name = name;
1784 eqSet.IconName = iconName;
1785 eqSet.state = EQUIPMENT_SET_NEW;
1786
1787 for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
1788 {
1789 ObjectGuid itemGuid;
1790 recvData >> itemGuid.ReadAsPacked();
1791
1792 // xinef: if client sends 0, it means empty slot
1793 if (!itemGuid)
1794 {
1795 eqSet.Items[i].Clear();
1796 continue;
1797 }
1798
1799 // equipment manager sends "1" (as raw GUID) for slots set to "ignore" (don't touch slot at equip set)
1800 if (itemGuid.GetRawValue() == 1)
1801 {
1802 // ignored slots saved as bit mask because we have no free special values for Items[i]
1803 eqSet.IgnoreMask |= 1 << i;
1804 continue;
1805 }
1806
1807 // xinef: some cheating checks
1809 if (!item || item->GetGUID() != itemGuid)
1810 {
1811 eqSet.Items[i].Clear();
1812 continue;
1813 }
1814
1815 eqSet.Items[i] = itemGuid;
1816 }
1817
1818 _player->SetEquipmentSet(index, eqSet);
1819}
@ EQUIPMENT_SET_NEW
Definition Player.h:739
#define MAX_EQUIPMENT_SET_INDEX
Definition Player.h:755
@ EQUIPMENT_SLOT_END
Definition Player.h:689
uint64 GetRawValue() const
Definition ObjectGuid.h:142
void SetEquipmentSet(uint32 index, EquipmentSet eqset)
Definition Player.cpp:14616
Definition Player.h:744
ObjectGuid Items[EQUIPMENT_SLOT_END]
Definition Player.h:751
std::string Name
Definition Player.h:748
std::string IconName
Definition Player.h:749
EquipmentSetUpdateState state
Definition Player.h:752
uint64 Guid
Definition Player.h:747
uint32 IgnoreMask
Definition Player.h:750

References _player, ObjectGuid::Clear(), EQUIPMENT_SET_NEW, EQUIPMENT_SLOT_END, Object::GetGUID(), Player::GetItemByPos(), ObjectGuid::GetRawValue(), EquipmentSet::Guid, EquipmentSet::IconName, EquipmentSet::IgnoreMask, INVENTORY_SLOT_BAG_0, EquipmentSet::Items, LOG_DEBUG, LOG_ERROR, MAX_EQUIPMENT_SET_INDEX, EquipmentSet::Name, ObjectGuid::ReadAsPacked(), ByteBuffer::readPackGUID(), Player::SetEquipmentSet(), EquipmentSet::state, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleEquipmentSetUse()

void WorldSession::HandleEquipmentSetUse ( WorldPacket recvData)
1832{
1833 LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_USE");
1834
1835 std::vector<std::unique_ptr<SavedItem>> savedItems;
1836 uint8 errorId = 0;
1837 for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
1838 {
1839 ObjectGuid itemGuid;
1840 recvData >> itemGuid.ReadAsPacked();
1841
1842 uint8 srcbag, srcslot;
1843 recvData >> srcbag >> srcslot;
1844
1845 LOG_DEBUG("entities.player.items", "Item {}: srcbag {}, srcslot {}", itemGuid.ToString(), srcbag, srcslot);
1846
1847 // check if item slot is set to "ignored" (raw value == 1), must not be unequipped then
1848 if (itemGuid.GetRawValue() == 1)
1849 continue;
1850
1851 // Only equip weapons in combat
1853 continue;
1854
1855 Item* item = nullptr;
1856 if (itemGuid)
1857 item = _player->GetItemByGuid(itemGuid);
1858
1859 uint16 dstpos = i | (INVENTORY_SLOT_BAG_0 << 8);
1860
1861 InventoryResult msg;
1863 if (uItem)
1864 {
1865 if (uItem->IsEquipped())
1866 {
1867 msg = _player->CanUnequipItem(dstpos, true);
1868 if (msg != EQUIP_ERR_OK)
1869 {
1870 _player->SendEquipError(msg, uItem, nullptr);
1871 continue;
1872 }
1873 }
1874
1875 if (!item)
1876 {
1877 ItemPosCountVec sDest;
1878 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, sDest, uItem, false);
1879 if (msg == EQUIP_ERR_OK)
1880 {
1881 savedItems.emplace_back(std::make_unique<SavedItem>(uItem, dstpos));
1883 _player->StoreItem(sDest, uItem, true);
1884 }
1885 else
1886 {
1887 errorId = 4;
1888 for (uint8_t j = 0; j < savedItems.size(); ++j)
1889 {
1890 _player->SwapItem(savedItems[j].get()->item->GetPos(), savedItems[j].get()->dstpos);
1891 }
1892 break;
1893 }
1894
1895 continue;
1896 }
1897 }
1898
1899 if (item)
1900 {
1901 if (item->GetPos() == dstpos)
1902 continue;
1903
1904 if (!item->IsEquipped())
1905 {
1906 uint16 _candidatePos;
1907 msg = _player->CanEquipItem(NULL_SLOT, _candidatePos, item, true);
1908 if (msg != EQUIP_ERR_OK)
1909 {
1910 _player->SendEquipError(msg, item, nullptr);
1911 continue;
1912 }
1913 }
1914
1915 _player->SwapItem(item->GetPos(), dstpos);
1916 }
1917 }
1918
1920 data << uint8(errorId); // 4 - equipment swap failed - inventory is full
1921 SendPacket(&data);
1922}
@ EQUIPMENT_SLOT_MAINHAND
Definition Player.h:685
@ EQUIPMENT_SLOT_OFFHAND
Definition Player.h:686
@ EQUIPMENT_SLOT_RANGED
Definition Player.h:687
bool IsEquipped() const
Definition Item.cpp:789
@ SMSG_EQUIPMENT_SET_USE_RESULT
Definition Opcodes.h:1268

References _player, Player::CanEquipItem(), Player::CanStoreItem(), Player::CanUnequipItem(), EQUIP_ERR_OK, EQUIPMENT_SLOT_END, EQUIPMENT_SLOT_MAINHAND, EQUIPMENT_SLOT_OFFHAND, EQUIPMENT_SLOT_RANGED, Player::GetItemByGuid(), Player::GetItemByPos(), Item::GetPos(), ObjectGuid::GetRawValue(), INVENTORY_SLOT_BAG_0, Item::IsEquipped(), Unit::IsInCombat(), LOG_DEBUG, NULL_BAG, NULL_SLOT, ObjectGuid::ReadAsPacked(), Player::RemoveItem(), Player::SendEquipError(), SendPacket(), SMSG_EQUIPMENT_SET_USE_RESULT, Player::StoreItem(), Player::SwapItem(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleFarSightOpcode()

void WorldSession::HandleFarSightOpcode ( WorldPacket recvData)
1176{
1177 LOG_DEBUG("network", "WORLD: CMSG_FAR_SIGHT");
1178
1179 bool apply;
1180 recvData >> apply;
1181
1182 if (apply)
1183 {
1184 LOG_DEBUG("network", "Added FarSight {} to player {}", _player->GetGuidValue(PLAYER_FARSIGHT).ToString(), _player->GetGUID().ToString());
1185 if (WorldObject* target = _player->GetViewpoint())
1186 _player->SetSeer(target);
1187 else
1188 LOG_DEBUG("network.opcode", "Player {} requests non-existing seer {}", _player->GetName(), _player->GetGuidValue(PLAYER_FARSIGHT).ToString());
1189 }
1190 else
1191 {
1192 WorldObject* newFarsightobject = nullptr;
1193 if (WorldObject* viewpoint = _player->GetViewpoint())
1194 {
1195 if (DynamicObject* viewpointDynamicObject = viewpoint->ToDynObject())
1196 {
1197 newFarsightobject = ObjectAccessor::GetUnit(*viewpointDynamicObject, viewpointDynamicObject->GetOldFarsightGUID());
1198 }
1199 else if (DynamicObject* viewpointDynamicObject = _player->GetDynObject(_player->GetUInt32Value(UNIT_CHANNEL_SPELL)))
1200 {
1201 if (viewpointDynamicObject->IsViewpoint() && viewpointDynamicObject->GetCasterGUID() == _player->GetGUID())
1202 {
1203 newFarsightobject = viewpointDynamicObject;
1204 }
1205 }
1206 }
1207
1208 if (newFarsightobject)
1209 {
1210 LOG_DEBUG("network", "Player {} set vision to old farsight {}", _player->GetGUID().ToString(), newFarsightobject->GetGUID().ToString());
1212 _player->SetViewpoint(newFarsightobject, true);
1213 }
1214 else
1215 {
1216 LOG_DEBUG("network", "Player {} set vision to self", _player->GetGUID().ToString());
1218 }
1219 }
1220
1222}
@ PLAYER_FARSIGHT
Definition UpdateFields.h:334
@ UNIT_CHANNEL_SPELL
Definition UpdateFields.h:94
Definition DynamicObject.h:35
DynamicObject * ToDynObject()
Definition Object.h:221
void SetSeer(WorldObject *target)
Definition Player.h:2363
void UpdateVisibilityForPlayer(bool mapChange=false)
Definition PlayerUpdates.cpp:1591
void SetViewpoint(WorldObject *target, bool apply)
Definition Player.cpp:13208
WorldObject * GetViewpoint() const
Definition Player.cpp:13251
DynamicObject * GetDynObject(uint32 spellId)
Definition Unit.cpp:6355
Definition Object.h:471
void apply(T *val)
Definition ByteConverter.h:40

References _player, Unit::GetDynObject(), Object::GetGUID(), Object::GetGuidValue(), WorldObject::GetName(), GetPlayer(), Object::GetUInt32Value(), ObjectAccessor::GetUnit(), Player::GetViewpoint(), LOG_DEBUG, PLAYER_FARSIGHT, Player::SetSeer(), Player::SetViewpoint(), Object::ToDynObject(), ObjectGuid::ToString(), UNIT_CHANNEL_SPELL, and Player::UpdateVisibilityForPlayer().

Referenced by OpcodeTable::Initialize().

◆ HandleForceSpeedChangeAck()

void WorldSession::HandleForceSpeedChangeAck ( WorldPacket recvData)
661{
662 uint32 opcode = recvData.GetOpcode();
663 LOG_DEBUG("network", "WORLD: Recvd {} ({}, 0x{:X}) opcode", GetOpcodeNameForLogging(static_cast<OpcodeClient>(opcode)), opcode, opcode);
664
665 /* extract packet */
666 ObjectGuid guid;
667 uint32 counter;
668 MovementInfo movementInfo;
669 float newspeed;
670
671 recvData >> guid.ReadAsPacked();
672 recvData >> counter; // counter or moveEvent
673 movementInfo.guid = guid;
674 ReadMovementInfo(recvData, &movementInfo);
675 recvData >> newspeed;
676
677 Unit* mover = _player->m_mover;
678
679 // pussywizard: special check, only player mover allowed here
680 if (guid != mover->GetGUID() || guid != _player->GetGUID())
681 {
682 recvData.rfinish(); // prevent warnings spam
683 return;
684 }
685
686 // old map - async processing, ignore
687 if (counter <= _player->GetMapChangeOrderCounter())
688 return;
689
690 if (!ProcessMovementInfo(movementInfo, mover, _player, recvData))
691 {
692 recvData.rfinish(); // prevent warnings spam
693 return;
694 }
695
697 {
699 WriteMovementInfo(&data, &movementInfo);
700 data << newspeed; // new collision height
701 mover->SendMessageToSet(&data, _player);
702 return;
703 }
704
705 // client ACK send one packet for mounted/run case and need skip all except last from its
706 // in other cases anti-cheat check can be fail in false case
707 UnitMoveType move_type;
708 UnitMoveType force_move_type;
709
710 static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack", "PitchRate" };
711
712 switch (opcode)
713 {
714 case CMSG_FORCE_WALK_SPEED_CHANGE_ACK: move_type = MOVE_WALK; force_move_type = MOVE_WALK; break;
715 case CMSG_FORCE_RUN_SPEED_CHANGE_ACK: move_type = MOVE_RUN; force_move_type = MOVE_RUN; break;
716 case CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK: move_type = MOVE_RUN_BACK; force_move_type = MOVE_RUN_BACK; break;
717 case CMSG_FORCE_SWIM_SPEED_CHANGE_ACK: move_type = MOVE_SWIM; force_move_type = MOVE_SWIM; break;
718 case CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK: move_type = MOVE_SWIM_BACK; force_move_type = MOVE_SWIM_BACK; break;
719 case CMSG_FORCE_TURN_RATE_CHANGE_ACK: move_type = MOVE_TURN_RATE; force_move_type = MOVE_TURN_RATE; break;
720 case CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT; force_move_type = MOVE_FLIGHT; break;
721 case CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT_BACK; force_move_type = MOVE_FLIGHT_BACK; break;
722 case CMSG_FORCE_PITCH_RATE_CHANGE_ACK: move_type = MOVE_PITCH_RATE; force_move_type = MOVE_PITCH_RATE; break;
723 default:
724 LOG_ERROR("network.opcode", "WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: {}", opcode);
725 return;
726 }
727
728 sScriptMgr->AnticheatSetUnderACKmount(_player);
729
730 SpeedOpcodePair const& speedOpcodes = SetSpeed2Opc_table[move_type];
731 WorldPacket data(speedOpcodes[static_cast<size_t>(SpeedOpcodeIndex::ACK_RESPONSE)], 18);
732 WriteMovementInfo(&data, &movementInfo);
733 data << newspeed;
734 mover->SendMessageToSet(&data, _player);
735
736 // skip all forced speed changes except last and unexpected
737 // in run/mounted case used one ACK and it must be skipped.m_forced_speed_changes[MOVE_RUN} store both.
738 if (_player->m_forced_speed_changes[force_move_type] > 0)
739 {
740 --_player->m_forced_speed_changes[force_move_type];
741 if (_player->m_forced_speed_changes[force_move_type] > 0)
742 return;
743 }
744
745 if (!_player->GetTransport() && std::fabs(_player->GetSpeed(move_type) - newspeed) > 0.01f)
746 {
747 if (_player->GetSpeed(move_type) > newspeed) // must be greater - just correct
748 {
749 LOG_ERROR("network.opcode", "{}SpeedChange player {} is NOT correct (must be {} instead {}), force set to correct value",
750 move_type_name[move_type], _player->GetName(), _player->GetSpeed(move_type), newspeed);
751 _player->SetSpeed(move_type, _player->GetSpeedRate(move_type), true);
752 }
753 else // must be lesser - cheating
754 {
755 LOG_INFO("network.opcode", "Player {} from account id {} kicked for incorrect speed (must be {} instead {})",
756 _player->GetName(), GetAccountId(), _player->GetSpeed(move_type), newspeed);
757 KickPlayer("Incorrect speed");
758 }
759 }
760}
#define MAX_MOVE_TYPE
Definition UnitDefines.h:364
UnitMoveType
Definition UnitDefines.h:352
@ MOVE_FLIGHT
Definition UnitDefines.h:359
@ MOVE_SWIM
Definition UnitDefines.h:356
@ MOVE_TURN_RATE
Definition UnitDefines.h:358
@ MOVE_FLIGHT_BACK
Definition UnitDefines.h:360
@ MOVE_SWIM_BACK
Definition UnitDefines.h:357
@ MOVE_RUN
Definition UnitDefines.h:354
@ MOVE_PITCH_RATE
Definition UnitDefines.h:361
@ MOVE_RUN_BACK
Definition UnitDefines.h:355
@ MOVE_WALK
Definition UnitDefines.h:353
const Opcodes SpeedOpcodePair[static_cast< size_t >(SpeedOpcodeIndex::MAX)]
Definition Unit.h:640
SpeedOpcodePair SetSpeed2Opc_table[MAX_MOVE_TYPE]
Definition Unit.h:641
uint8 m_forced_speed_changes[MAX_MOVE_TYPE]
Definition Player.h:2414
float GetSpeed(UnitMoveType mtype) const
Definition Unit.cpp:14588
float GetSpeedRate(UnitMoveType mtype) const
Definition Unit.h:1721
void SetSpeed(UnitMoveType mtype, float rate, bool forced=false)
Definition Unit.cpp:14593
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:2083
Transport * GetTransport() const
Definition Object.h:682
void WriteMovementInfo(WorldPacket *data, MovementInfo *mi)
Definition WorldSession.cpp:1113
@ CMSG_FORCE_PITCH_RATE_CHANGE_ACK
Definition Opcodes.h:1147
@ CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK
Definition Opcodes.h:259
@ CMSG_FORCE_TURN_RATE_CHANGE_ACK
Definition Opcodes.h:765
@ MSG_MOVE_SET_COLLISION_HGT
Definition Opcodes.h:1334
@ CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK
Definition Opcodes.h:930
@ CMSG_FORCE_SWIM_SPEED_CHANGE_ACK
Definition Opcodes.h:261
@ CMSG_MOVE_SET_COLLISION_HGT_ACK
Definition Opcodes.h:1333
@ CMSG_FORCE_RUN_SPEED_CHANGE_ACK
Definition Opcodes.h:257
@ CMSG_FORCE_WALK_SPEED_CHANGE_ACK
Definition Opcodes.h:761
@ CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK
Definition Opcodes.h:928
@ CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK
Definition Opcodes.h:763

References _player, ACK_RESPONSE, CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK, CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK, CMSG_FORCE_PITCH_RATE_CHANGE_ACK, CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK, CMSG_FORCE_RUN_SPEED_CHANGE_ACK, CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK, CMSG_FORCE_SWIM_SPEED_CHANGE_ACK, CMSG_FORCE_TURN_RATE_CHANGE_ACK, CMSG_FORCE_WALK_SPEED_CHANGE_ACK, CMSG_MOVE_SET_COLLISION_HGT_ACK, GetAccountId(), Object::GetGUID(), WorldObject::GetName(), WorldPacket::GetOpcode(), GetOpcodeNameForLogging(), Unit::GetSpeed(), Unit::GetSpeedRate(), WorldObject::GetTransport(), MovementInfo::guid, KickPlayer(), LOG_DEBUG, LOG_ERROR, LOG_INFO, Player::m_forced_speed_changes, Player::m_mover, MAX_MOVE_TYPE, MOVE_FLIGHT, MOVE_FLIGHT_BACK, MOVE_PITCH_RATE, MOVE_RUN, MOVE_RUN_BACK, MOVE_SWIM, MOVE_SWIM_BACK, MOVE_TURN_RATE, MOVE_WALK, MSG_MOVE_SET_COLLISION_HGT, ProcessMovementInfo(), ObjectGuid::ReadAsPacked(), ReadMovementInfo(), ByteBuffer::rfinish(), WorldObject::SendMessageToSet(), Unit::SetSpeed(), SetSpeed2Opc_table, sScriptMgr, and WriteMovementInfo().

Referenced by OpcodeTable::Initialize().

◆ HandleGameObjectQueryOpcode()

void WorldSession::HandleGameObjectQueryOpcode ( WorldPacket recvPacket)

Only static data is sent in this packet !!!

167{
168 uint32 entry;
169 recvData >> entry;
170 ObjectGuid guid;
171 recvData >> guid;
172
173 const GameObjectTemplate* info = sObjectMgr->GetGameObjectTemplate(entry);
174 if (info)
175 {
176 std::string Name;
177 std::string IconName;
178 std::string CastBarCaption;
179
180 Name = info->name;
181 IconName = info->IconName;
182 CastBarCaption = info->castBarCaption;
183
184 LocaleConstant localeConstant = GetSessionDbLocaleIndex();
185 if (localeConstant >= LOCALE_enUS)
186 if (GameObjectLocale const* gameObjectLocale = sObjectMgr->GetGameObjectLocale(entry))
187 {
188 ObjectMgr::GetLocaleString(gameObjectLocale->Name, localeConstant, Name);
189 ObjectMgr::GetLocaleString(gameObjectLocale->CastBarCaption, localeConstant, CastBarCaption);
190 }
191
192 LOG_DEBUG("network", "WORLD: CMSG_GAMEOBJECT_QUERY '{}' - Entry: {}. ", info->name, entry);
194 data << uint32(entry);
195 data << uint32(info->type);
196 data << uint32(info->displayId);
197 data << Name;
198 data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4
199 data << IconName; // 2.0.3, string. Icon name to use instead of default icon for go's (ex: "Attack" makes sword)
200 data << CastBarCaption; // 2.0.3, string. Text will appear in Cast Bar when using GO (ex: "Collecting")
201 data << info->unk1; // 2.0.3, string
202 data.append(info->raw.data, MAX_GAMEOBJECT_DATA);
203 data << float(info->size); // go size
204
205 GameObjectQuestItemList const* items = sObjectMgr->GetGameObjectQuestItemList(entry);
206 if (items)
207 for (std::size_t i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i)
208 data << (i < items->size() ? uint32((*items)[i]) : uint32(0));
209 else
210 for (std::size_t i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i)
211 data << uint32(0);
212
213 SendPacket(&data);
214 LOG_DEBUG("network", "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE");
215 }
216 else
217 {
218 LOG_DEBUG("network", "WORLD: CMSG_GAMEOBJECT_QUERY - Missing gameobject info for ({})", guid.ToString());
220 data << uint32(entry | 0x80000000);
221 SendPacket(&data);
222 LOG_DEBUG("network", "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE");
223 }
224}
@ LOCALE_enUS
Definition Common.h:118
#define MAX_GAMEOBJECT_QUEST_ITEMS
Definition GameObjectData.h:26
std::vector< uint32 > GameObjectQuestItemList
Definition GameObject.h:46
#define MAX_GAMEOBJECT_DATA
Definition SharedDefines.h:1610
@ SMSG_GAMEOBJECT_QUERY_RESPONSE
Definition Opcodes.h:125
Definition GameObjectData.h:676
Definition GameObjectData.h:31
uint32 data[MAX_GAMEOBJECT_DATA]
Definition GameObjectData.h:388
uint32 type
Definition GameObjectData.h:33
std::string unk1
Definition GameObjectData.h:38
std::string name
Definition GameObjectData.h:35
struct GameObjectTemplate::@233::@263 raw
std::string castBarCaption
Definition GameObjectData.h:37
float size
Definition GameObjectData.h:39
uint32 displayId
Definition GameObjectData.h:34
std::string IconName
Definition GameObjectData.h:36

References ByteBuffer::append(), GameObjectTemplate::castBarCaption, GameObjectTemplate::data, GameObjectTemplate::displayId, ObjectMgr::GetLocaleString(), GetSessionDbLocaleIndex(), GameObjectTemplate::IconName, LOCALE_enUS, LOG_DEBUG, MAX_GAMEOBJECT_DATA, MAX_GAMEOBJECT_QUEST_ITEMS, GameObjectTemplate::name, GameObjectTemplate::raw, SendPacket(), GameObjectTemplate::size, SMSG_GAMEOBJECT_QUERY_RESPONSE, sObjectMgr, ObjectGuid::ToString(), GameObjectTemplate::type, and GameObjectTemplate::unk1.

Referenced by OpcodeTable::Initialize().

◆ HandleGameobjectReportUse()

void WorldSession::HandleGameobjectReportUse ( WorldPacket recvPacket)
349{
350 ObjectGuid guid;
351 recvPacket >> guid;
352
353 LOG_DEBUG("network", "WORLD: Recvd CMSG_GAMEOBJ_REPORT_USE Message [{}]", guid.ToString());
354
355 // ignore for remote control state
356 if (_player->m_mover != _player)
357 return;
358
359 GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid);
360 if (!go)
361 return;
362
363 // Prevent use of GameObject if it is not selectable. Fixes hack.
365 return;
366
368 return;
369
370 if (go->AI()->GossipHello(_player, true))
371 return;
372
374}
@ ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT
Definition DBCEnums.h:180
@ GO_FLAG_NOT_SELECTABLE
Definition SharedDefines.h:1618
virtual bool GossipHello(Player *, bool)
Definition GameObjectAI.h:54
GameObjectAI * AI() const
Definition GameObject.h:305
bool HasGameObjectFlag(GameObjectFlags flags) const
Definition GameObject.h:216

References _player, ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, GameObject::AI(), Object::GetEntry(), Map::GetGameObject(), WorldObject::GetMap(), GetPlayer(), GO_FLAG_NOT_SELECTABLE, GameObjectAI::GossipHello(), GameObject::HasGameObjectFlag(), INTERACTION_DISTANCE, GameObject::IsWithinDistInMap(), LOG_DEBUG, Player::m_mover, ObjectGuid::ToString(), and Player::UpdateAchievementCriteria().

Referenced by OpcodeTable::Initialize().

◆ HandleGameObjectUseOpcode()

void WorldSession::HandleGameObjectUseOpcode ( WorldPacket recPacket)
328{
329 ObjectGuid guid;
330 recvData >> guid;
331
332 LOG_DEBUG("network", "WORLD: Recvd CMSG_GAMEOBJ_USE Message [{}]", guid.ToString());
333
334 if (GameObject* obj = GetPlayer()->GetMap()->GetGameObject(guid))
335 {
336 if (!obj->IsWithinDistInMap(GetPlayer(), obj->GetInteractionDistance()))
337 return;
338
339 // ignore for remote control state
340 if (GetPlayer()->m_mover != GetPlayer())
341 if (!(GetPlayer()->IsOnVehicle(GetPlayer()->m_mover) || GetPlayer()->IsMounted()) && !obj->GetGOInfo()->IsUsableMounted())
342 return;
343
344 obj->Use(GetPlayer());
345 }
346}
GameObject * GetGameObject(WorldObject const &u, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:184

References GetPlayer(), LOG_DEBUG, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleGetChannelMemberCount()

void WorldSession::HandleGetChannelMemberCount ( WorldPacket recvPacket)
280{
281 std::string channelName;
282 recvPacket >> channelName;
283
284 LOG_DEBUG("chat.system", "CMSG_GET_CHANNEL_MEMBER_COUNT {} Channel: {}",
285 GetPlayerInfo(), channelName);
287 {
288 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
289 {
290 LOG_DEBUG("chat.system", "SMSG_CHANNEL_MEMBER_COUNT {} Channel: {} Count: {}",
291 GetPlayerInfo(), channelName, channel->GetNumPlayers());
292
293 WorldPacket data(SMSG_CHANNEL_MEMBER_COUNT, channel->GetName().size() + 1 + 4);
294 data << channel->GetName();
295 data << uint8(channel->GetFlags());
296 data << uint32(channel->GetNumPlayers());
297 SendPacket(&data);
298 }
299 }
300}
@ SMSG_CHANNEL_MEMBER_COUNT
Definition Opcodes.h:1011

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, SendPacket(), and SMSG_CHANNEL_MEMBER_COUNT.

Referenced by OpcodeTable::Initialize().

◆ HandleGetMailList()

void WorldSession::HandleGetMailList ( WorldPacket recvData)
630{
631 ObjectGuid mailbox;
632 recvData >> mailbox;
633
634 if (!CanOpenMailBox(mailbox))
635 return;
636
637 Player* player = _player;
638
639 uint8 mailsCount = 0;
640 uint32 realCount = 0;
641
642 WorldPacket data(SMSG_MAIL_LIST_RESULT, (200)); // guess size
643 data << uint32(0); // real mail's count
644 data << uint8(0); // mail's count
645 time_t cur_time = GameTime::GetGameTime().count();
646
647 for (Mail const* mail : player->GetMails())
648 {
649 // prevent client storage overflow
650 if (mailsCount >= MAX_INBOX_CLIENT_CAPACITY)
651 {
652 ++realCount;
653 continue;
654 }
655
656 // skip deleted or not delivered (deliver delay not expired) mails
657 if (mail->state == MAIL_STATE_DELETED || cur_time < mail->deliver_time || cur_time > mail->expire_time)
658 {
659 continue;
660 }
661
662 uint8 item_count = uint8(mail->items.size()); // max count is MAX_MAIL_ITEMS (12)
663
664 std::size_t next_mail_size = 2 + 4 + 1 + (mail->messageType == MAIL_NORMAL ? 8 : 4) + 4 * 8 + (mail->subject.size() + 1) + (mail->body.size() + 1) + 1 + item_count * (1 + 4 + 4 + MAX_INSPECTED_ENCHANTMENT_SLOT * 3 * 4 + 4 + 4 + 4 + 4 + 4 + 4 + 1);
665
666 if (data.wpos() + next_mail_size > MAX_NETCLIENT_PACKET_SIZE)
667 {
668 ++realCount;
669 continue;
670 }
671
672 data << uint16(next_mail_size); // Message size
673 data << uint32(mail->messageID); // Message ID
674 data << uint8(mail->messageType); // Message Type
675
676 switch (mail->messageType)
677 {
678 case MAIL_NORMAL: // sender guid
679 data << ObjectGuid::Create<HighGuid::Player>(mail->sender);
680 break;
681 case MAIL_CREATURE:
682 case MAIL_GAMEOBJECT:
683 case MAIL_AUCTION:
684 case MAIL_CALENDAR:
685 data << uint32(mail->sender); // creature/gameobject entry, auction id, calendar event id?
686 break;
687 }
688
689 // prevent client crash
690 std::string subject = mail->subject;
691 std::string body = mail->body;
692
693 if (subject.find("| |") != std::string::npos)
694 {
695 subject = "";
696 }
697 if (body.find("| |") != std::string::npos)
698 {
699 body = "";
700 }
701
702 data << uint32(mail->COD); // COD
703 data << uint32(0); // probably changed in 3.3.3
704 data << uint32(mail->stationery); // stationery (Stationery.dbc)
705 data << uint32(mail->money); // Gold
706 data << uint32(mail->checked); // flags
707 data << float(float(mail->expire_time - GameTime::GetGameTime().count()) / DAY); // Time
708 data << uint32(mail->mailTemplateId); // mail template (MailTemplate.dbc)
709 data << subject; // Subject string - once 00, when mail type = 3, max 256
710 data << body; // message? max 8000
711 data << uint8(item_count); // client limit is 0x10
712
713 for (uint8 i = 0; i < item_count; ++i)
714 {
715 Item* item = player->GetMItem(mail->items[i].item_guid);
716 // item index (0-6?)
717 data << uint8(i);
718 // item guid low?
719 data << uint32((item ? item->GetGUID().GetCounter() : 0));
720 // entry
721 data << uint32((item ? item->GetEntry() : 0));
722 for (uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j)
723 {
724 data << uint32(item ? item->GetEnchantmentId(EnchantmentSlot(j)) : 0);
725 data << uint32(item ? item->GetEnchantmentDuration(EnchantmentSlot(j)) : 0);
726 data << uint32(item ? item->GetEnchantmentCharges(EnchantmentSlot(j)) : 0);
727 }
728 // can be negative
729 data << int32((item ? item->GetItemRandomPropertyId() : 0));
730 // unk
731 data << uint32((item ? item->GetItemSuffixFactor() : 0));
732 // stack count
733 data << uint32((item ? item->GetCount() : 0));
734 // charges
735 data << uint32((item ? item->GetSpellCharges() : 0));
736 // durability
737 data << uint32((item ? item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY) : 0));
738 // durability
739 data << uint32((item ? item->GetUInt32Value(ITEM_FIELD_DURABILITY) : 0));
740 // unknown wotlk
741 data << uint8(0);
742 }
743
744 ++realCount;
745 ++mailsCount;
746 }
747
748 data.put<uint32>(0, realCount); // this will display warning about undelivered mail to player if realCount > mailsCount
749 data.put<uint8>(4, mailsCount); // set real send mails to client
750 SendPacket(&data);
751
752 // recalculate m_nextMailDelivereTime and unReadMails
754}
constexpr auto DAY
Definition Common.h:49
#define MAX_NETCLIENT_PACKET_SIZE
Definition Common.h:43
EnchantmentSlot
Definition Item.h:168
@ MAX_INSPECTED_ENCHANTMENT_SLOT
Definition Item.h:176
#define MAX_INBOX_CLIENT_CAPACITY
Definition MailHandler.cpp:35
@ MAIL_STATE_DELETED
Definition Mail.h:70
@ MAIL_AUCTION
Definition Mail.h:38
@ MAIL_GAMEOBJECT
Definition Mail.h:40
@ MAIL_CREATURE
Definition Mail.h:39
@ MAIL_CALENDAR
Definition Mail.h:41
@ MAIL_NORMAL
Definition Mail.h:37
@ ITEM_FIELD_DURABILITY
Definition UpdateFields.h:69
@ ITEM_FIELD_MAXDURABILITY
Definition UpdateFields.h:70
int32 GetSpellCharges(uint8 index=0) const
Definition Item.h:317
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition Item.h:305
int32 GetItemRandomPropertyId() const
Definition Item.h:295
uint32 GetItemSuffixFactor() const
Definition Item.h:296
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition Item.h:306
void UpdateNextMailTimeAndUnreads()
Definition PlayerUpdates.cpp:436
Item * GetMItem(ObjectGuid::LowType itemLowGuid)
Definition Player.h:1662
bool CanOpenMailBox(ObjectGuid guid)
Definition MailHandler.cpp:37
@ SMSG_MAIL_LIST_RESULT
Definition Opcodes.h:601
Definition Mail.h:167

References _player, CanOpenMailBox(), DAY, Item::GetCount(), ObjectGuid::GetCounter(), Item::GetEnchantmentCharges(), Item::GetEnchantmentDuration(), Item::GetEnchantmentId(), Object::GetEntry(), GameTime::GetGameTime(), Object::GetGUID(), Item::GetItemRandomPropertyId(), Item::GetItemSuffixFactor(), Player::GetMails(), Player::GetMItem(), Item::GetSpellCharges(), Object::GetUInt32Value(), ITEM_FIELD_DURABILITY, ITEM_FIELD_MAXDURABILITY, MAIL_AUCTION, MAIL_CALENDAR, MAIL_CREATURE, MAIL_GAMEOBJECT, MAIL_NORMAL, MAIL_STATE_DELETED, MAX_INBOX_CLIENT_CAPACITY, MAX_INSPECTED_ENCHANTMENT_SLOT, MAX_NETCLIENT_PACKET_SIZE, ByteBuffer::put(), SendPacket(), SMSG_MAIL_LIST_RESULT, Player::UpdateNextMailTimeAndUnreads(), and ByteBuffer::wpos().

Referenced by OpcodeTable::Initialize().

◆ HandleGMResponseResolve()

void WorldSession::HandleGMResponseResolve ( WorldPacket recvPacket)
281{
282 // empty packet
283 if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
284 {
285 uint8 getSurvey = 0;
286 if (float(rand_chance()) < sWorld->getFloatConfig(CONFIG_CHANCE_OF_GM_SURVEY))
287 getSurvey = 1;
288
290 data << uint8(getSurvey);
291 SendPacket(&data);
292
295 SendPacket(&data2);
296
297 sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID());
298 sTicketMgr->SendTicket(this, nullptr);
299 }
300}
double rand_chance()
Definition Random.cpp:91
#define sTicketMgr
Definition TicketMgr.h:260
@ GMTICKET_RESPONSE_TICKET_DELETED
Definition TicketMgr.h:47
@ CONFIG_CHANCE_OF_GM_SURVEY
Definition WorldConfig.h:157
Definition TicketMgr.h:88
@ SMSG_GMRESPONSE_STATUS_UPDATE
Definition Opcodes.h:1295
@ SMSG_GMTICKET_DELETETICKET
Definition Opcodes.h:566

References CONFIG_CHANCE_OF_GM_SURVEY, GetPlayer(), GMTICKET_RESPONSE_TICKET_DELETED, rand_chance(), SendPacket(), SMSG_GMRESPONSE_STATUS_UPDATE, SMSG_GMTICKET_DELETETICKET, sTicketMgr, and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleGMSurveySubmit()

void WorldSession::HandleGMSurveySubmit ( WorldPacket recvPacket)
198{
199 uint32 nextSurveyID = sTicketMgr->GetNextSurveyID();
200 // just put the survey into the database
201 uint32 mainSurvey; // GMSurveyCurrentSurvey.dbc, column 1 (all 9) ref to GMSurveySurveys.dbc
202 recv_data >> mainSurvey;
203
204 std::unordered_set<uint32> surveyIds;
205 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
206
207 // sub_survey1, r1, comment1, sub_survey2, r2, comment2, sub_survey3, r3, comment3, sub_survey4, r4, comment4, sub_survey5, r5, comment5, sub_survey6, r6, comment6, sub_survey7, r7, comment7, sub_survey8, r8, comment8, sub_survey9, r9, comment9, sub_survey10, r10, comment10,
208 for (uint8 i = 0; i < 10; i++)
209 {
210 uint32 subSurveyId; // ref to i'th GMSurveySurveys.dbc field (all fields in that dbc point to fields in GMSurveyQuestions.dbc)
211 recv_data >> subSurveyId;
212 if (!subSurveyId)
213 break;
214
215 uint8 rank; // probably some sort of ref to GMSurveyAnswers.dbc
216 recv_data >> rank;
217 std::string comment; // comment ("Usage: GMSurveyAnswerSubmit(question, rank, comment)")
218 recv_data >> comment;
219
220 if (!ValidateHyperlinksAndMaybeKick(comment))
221 {
222 return;
223 }
224
225 // make sure the same sub survey is not added to DB twice
226 if (!surveyIds.insert(subSurveyId).second)
227 continue;
228
230 stmt->SetData(0, nextSurveyID);
231 stmt->SetData(1, subSurveyId);
232 stmt->SetData(2, rank);
233 stmt->SetData(3, comment);
234 trans->Append(stmt);
235 }
236
237 std::string comment; // just a guess
238 recv_data >> comment;
239
240 if (!ValidateHyperlinksAndMaybeKick(comment))
241 {
242 return;
243 }
244
246 stmt->SetData(0, GetPlayer()->GetGUID().GetCounter());
247 stmt->SetData(1, nextSurveyID);
248 stmt->SetData(2, mainSurvey);
249 stmt->SetData(3, comment);
250
251 trans->Append(stmt);
252
253 CharacterDatabase.CommitTransaction(trans);
254}
@ CHAR_INS_GM_SURVEY
Definition CharacterDatabase.h:269
@ CHAR_INS_GM_SUBSURVEY
Definition CharacterDatabase.h:270
bool ValidateHyperlinksAndMaybeKick(std::string_view str)
Definition WorldSession.cpp:805

References CHAR_INS_GM_SUBSURVEY, CHAR_INS_GM_SURVEY, CharacterDatabase, GetPlayer(), PreparedStatementBase::SetData(), sTicketMgr, and ValidateHyperlinksAndMaybeKick().

Referenced by OpcodeTable::Initialize().

◆ HandleGMTicketCreateOpcode()

void WorldSession::HandleGMTicketCreateOpcode ( WorldPacket recvPacket)
31{
32 // Don't accept tickets if the ticket queue is disabled. (Ticket UI is greyed out but not fully dependable)
34 return;
35
36 if (GetPlayer()->GetLevel() < sWorld->getIntConfig(CONFIG_TICKET_LEVEL_REQ))
37 {
39 return;
40 }
41
43 GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID());
44
45 if (ticket && ticket->IsCompleted())
46 sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID());
47
48 // Player must not have ticket
49 if (!ticket || ticket->IsClosed())
50 {
51 uint32 mapId;
52 float x, y, z;
53 std::string message;
54 uint32 needResponse;
55 bool needMoreHelp;
56 uint32 count;
57 std::list<uint32> times;
58 uint32 decompressedSize;
59 std::string chatLog;
60
61 recvData >> mapId;
62 recvData >> x >> y >> z;
63 recvData >> message;
64
66 {
67 return;
68 }
69
70 recvData >> needResponse;
71 recvData >> needMoreHelp;
72
73 recvData >> count;
74
75 for (uint32 i = 0; i < count; i++)
76 {
77 uint32 time;
78 recvData >> time;
79 times.push_back(time);
80 }
81
82 recvData >> decompressedSize;
83
84 if (count && decompressedSize && decompressedSize < 0xFFFF)
85 {
86 uint32 pos = recvData.rpos();
87 ByteBuffer dest;
88 dest.resize(decompressedSize);
89
90 uLongf realSize = decompressedSize;
91 if (uncompress(dest.contents(), &realSize, recvData.contents() + pos, recvData.size() - pos) == Z_OK)
92 {
93 dest >> chatLog;
94 }
95 else
96 {
97 LOG_ERROR("network.opcode", "CMSG_GMTICKET_CREATE possibly corrupt. Uncompression failed.");
98 recvData.rfinish();
99 return;
100 }
101
102 recvData.rfinish(); // Will still have compressed data in buffer.
103 }
104
105 if (!chatLog.empty() && !ValidateHyperlinksAndMaybeKick(chatLog))
106 {
107 return;
108 }
109
110 ticket = new GmTicket(GetPlayer());
111 ticket->SetPosition(mapId, x, y, z);
112 ticket->SetMessage(message);
113 ticket->SetGmAction(needResponse, needMoreHelp);
114
115 if (!chatLog.empty())
116 ticket->SetChatLog(times, chatLog);
117
118 sTicketMgr->AddTicket(ticket);
119 sTicketMgr->UpdateLastChange(ticket);
120
122
124 }
125
127 data << uint32(response);
128 SendPacket(&data);
129}
@ LANG_TICKET_REQ
Definition Language.h:1170
@ LANG_COMMAND_TICKETNEW
Definition Language.h:1020
@ GMTICKET_QUEUE_STATUS_DISABLED
Definition TicketMgr.h:30
GMTicketResponse
Definition TicketMgr.h:41
@ GMTICKET_RESPONSE_CREATE_ERROR
Definition TicketMgr.h:44
@ GMTICKET_RESPONSE_CREATE_SUCCESS
Definition TicketMgr.h:43
@ CONFIG_TICKET_LEVEL_REQ
Definition WorldConfig.h:250
void resize(std::size_t newsize)
Definition ByteBuffer.h:447
uint8 * contents()
Definition ByteBuffer.h:424
void SendGMText(std::string_view str)
Definition Chat.cpp:116
bool IsClosed() const
Definition TicketMgr.h:94
void SetPosition(uint32 mapId, float x, float y, float z)
Definition TicketMgr.cpp:224
void SetMessage(std::string const &message)
Definition TicketMgr.cpp:257
void SetGmAction(uint32 needResponse, bool needMoreHelp)
Definition TicketMgr.cpp:232
bool IsCompleted() const
Definition TicketMgr.h:95
uint32 GetId() const
Definition TicketMgr.h:101
void SetChatLog(std::list< uint32 > time, std::string const &log)
Definition TicketMgr.cpp:243
@ SMSG_GMTICKET_CREATE
Definition Opcodes.h:548

References CONFIG_TICKET_LEVEL_REQ, ByteBuffer::contents(), GmTicket::GetId(), GetPlayer(), GMTICKET_QUEUE_STATUS_DISABLED, GMTICKET_RESPONSE_CREATE_ERROR, GMTICKET_RESPONSE_CREATE_SUCCESS, GmTicket::IsClosed(), GmTicket::IsCompleted(), LANG_COMMAND_TICKETNEW, LANG_TICKET_REQ, LOG_ERROR, ByteBuffer::resize(), ByteBuffer::rfinish(), ByteBuffer::rpos(), ChatHandler::SendGMText(), ChatHandler::SendNotification(), SendPacket(), GmTicket::SetChatLog(), GmTicket::SetGmAction(), GmTicket::SetMessage(), GmTicket::SetPosition(), ByteBuffer::size(), SMSG_GMTICKET_CREATE, sTicketMgr, sWorld, and ValidateHyperlinksAndMaybeKick().

Referenced by OpcodeTable::Initialize().

◆ HandleGMTicketDeleteOpcode()

void WorldSession::HandleGMTicketDeleteOpcode ( WorldPacket recvPacket)
159{
160 if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
161 {
164 SendPacket(&data);
165
167
168 sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID());
169 sTicketMgr->SendTicket(this, nullptr);
170 }
171}
@ LANG_COMMAND_TICKETPLAYERABANDON
Definition Language.h:1022

References GetPlayer(), GMTICKET_RESPONSE_TICKET_DELETED, LANG_COMMAND_TICKETPLAYERABANDON, ChatHandler::SendGMText(), SendPacket(), SMSG_GMTICKET_DELETETICKET, and sTicketMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleGMTicketGetTicketOpcode()

void WorldSession::HandleGMTicketGetTicketOpcode ( WorldPacket recvPacket)
174{
176
177 if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
178 {
179 if (ticket->IsCompleted())
180 ticket->SendResponse(this);
181 else
182 sTicketMgr->SendTicket(this, ticket);
183 }
184 else
185 sTicketMgr->SendTicket(this, nullptr);
186}
void SendTimeQueryResponse()
Definition QueryHandler.cpp:77

References GetPlayer(), SendTimeQueryResponse(), and sTicketMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleGMTicketSystemStatusOpcode()

void WorldSession::HandleGMTicketSystemStatusOpcode ( WorldPacket recvPacket)
189{
190 // Note: This only disables the ticket UI at client side and is not fully reliable
191 // are we sure this is a uint32? Should ask Zor
194 SendPacket(&data);
195}
@ GMTICKET_QUEUE_STATUS_ENABLED
Definition TicketMgr.h:31
@ SMSG_GMTICKET_SYSTEMSTATUS
Definition Opcodes.h:569

References GMTICKET_QUEUE_STATUS_DISABLED, GMTICKET_QUEUE_STATUS_ENABLED, SendPacket(), SMSG_GMTICKET_SYSTEMSTATUS, and sTicketMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleGMTicketUpdateOpcode()

void WorldSession::HandleGMTicketUpdateOpcode ( WorldPacket recvPacket)
132{
133 std::string message;
134 recv_data >> message;
135
136 if (!ValidateHyperlinksAndMaybeKick(message))
137 {
138 return;
139 }
140
142 if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
143 {
145 ticket->SetMessage(message);
146 ticket->SaveToDB(trans);
147
148 ChatHandler(nullptr).SendGMText(LANG_COMMAND_TICKETUPDATED, GetPlayer()->GetName(), ticket->GetId());
149
151 }
152
154 data << uint32(response);
155 SendPacket(&data);
156}
@ LANG_COMMAND_TICKETUPDATED
Definition Language.h:1021
@ GMTICKET_RESPONSE_UPDATE_SUCCESS
Definition TicketMgr.h:45
@ GMTICKET_RESPONSE_UPDATE_ERROR
Definition TicketMgr.h:46
@ SMSG_GMTICKET_UPDATETEXT
Definition Opcodes.h:550

References GetPlayer(), GMTICKET_RESPONSE_UPDATE_ERROR, GMTICKET_RESPONSE_UPDATE_SUCCESS, LANG_COMMAND_TICKETUPDATED, ChatHandler::SendGMText(), SendPacket(), SMSG_GMTICKET_UPDATETEXT, sTicketMgr, and ValidateHyperlinksAndMaybeKick().

Referenced by OpcodeTable::Initialize().

◆ HandleGossipHelloOpcode()

void WorldSession::HandleGossipHelloOpcode ( WorldPacket recvPacket)
274{
275 ObjectGuid guid;
276 recvData >> guid;
277
279 if (!unit)
280 {
281 LOG_DEBUG("network", "WORLD: HandleGossipHelloOpcode - Unit ({}) not found or you can not interact with him.", guid.ToString());
282 return;
283 }
284
285 // xinef: check if we have ANY npc flags
286 if (unit->GetNpcFlags() == UNIT_NPC_FLAG_NONE)
287 return;
288
289 // set faction visible if needed
290 if (FactionTemplateEntry const* factionTemplateEntry = sFactionTemplateStore.LookupEntry(unit->GetFaction()))
291 _player->GetReputationMgr().SetVisible(factionTemplateEntry);
292
294 // remove fake death
295 //if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
296 // GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
297
298 // Stop the npc if moving
300 unit->PauseMovement(pause);
301 unit->SetHomePosition(unit->GetPosition());
302
303 // If spiritguide, no need for gossip menu, just put player into resurrect queue
304 if (unit->IsSpiritGuide())
305 {
307 if (bg)
308 {
310 sBattlegroundMgr->SendAreaSpiritHealerQueryOpcode(_player, bg, unit->GetGUID());
311 return;
312 }
313 }
314
315 if (!sScriptMgr->OnGossipHello(_player, unit))
316 {
317 // _player->TalkedToCreature(unit->GetEntry(), unit->GetGUID());
320 }
321 unit->AI()->sGossipHello(_player);
322}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
@ AURA_INTERRUPT_FLAG_TALK
Definition SpellDefines.h:53
@ UNIT_NPC_FLAG_NONE
Definition UnitDefines.h:318
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:208
CreatureAI * AI() const
Definition Creature.h:145
void SendPreparedGossip(WorldObject *source)
Definition PlayerGossip.cpp:209
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition PlayerGossip.cpp:32
ReputationMgr & GetReputationMgr()
Definition Player.h:2123
void SetVisible(FactionTemplateEntry const *factionTemplateEntry)
Definition ReputationMgr.cpp:461
virtual void sGossipHello(Player *)
Definition UnitAI.h:412
NPCFlags GetNpcFlags() const
Clears emote state (looping emote)
Definition Unit.h:752
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition Unit.cpp:5300
bool IsSpiritGuide() const
Definition Unit.h:803
uint32 GossipMenuId
Definition CreatureData.h:194
Definition DBCStructure.h:939

References _player, Battleground::AddPlayerToResurrectQueue(), Creature::AI(), AURA_INTERRUPT_FLAG_TALK, Player::GetBattleground(), Creature::GetCreatureTemplate(), Unit::GetFaction(), Object::GetGUID(), CreatureMovementData::GetInteractionPauseTimer(), Creature::GetMovementTemplate(), Unit::GetNpcFlags(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Position::GetPosition(), Player::GetReputationMgr(), CreatureTemplate::GossipMenuId, Unit::IsSpiritGuide(), LOG_DEBUG, Unit::PauseMovement(), Player::PrepareGossipMenu(), Unit::RemoveAurasWithInterruptFlags(), sBattlegroundMgr, Player::SendPreparedGossip(), Creature::SetHomePosition(), ReputationMgr::SetVisible(), sFactionTemplateStore, UnitAI::sGossipHello(), sScriptMgr, ObjectGuid::ToString(), and UNIT_NPC_FLAG_NONE.

Referenced by OpcodeTable::Initialize().

◆ HandleGossipSelectOptionOpcode()

void WorldSession::HandleGossipSelectOptionOpcode ( WorldPacket recvPacket)
88{
89 LOG_DEBUG("network", "WORLD: CMSG_GOSSIP_SELECT_OPTION");
90
91 uint32 gossipListId;
92 uint32 menuId;
93 ObjectGuid guid;
94 std::string code = "";
95
96 recv_data >> guid >> menuId >> gossipListId;
97
99 recv_data >> code;
100
101 // Prevent cheating on C++ scripted menus
103 {
104 return;
105 }
106
107 Creature* unit = nullptr;
108 GameObject* go = nullptr;
109 Item* item = nullptr;
110 if (guid.IsCreatureOrVehicle())
111 {
113 if (!unit)
114 {
115 LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - Unit ({}) not found or you can't interact with him.", guid.ToString());
116 return;
117 }
118 }
119 else if (guid.IsGameObject())
120 {
121 go = _player->GetMap()->GetGameObject(guid);
122 if (!go)
123 {
124 LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - GameObject ({}) not found.", guid.ToString());
125 return;
126 }
127 }
128 else if (guid.IsItem())
129 {
130 item = _player->GetItemByGuid(guid);
131 if (!item || _player->IsBankPos(item->GetPos()))
132 {
133 //LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - {} not found.", guid.ToString());
134 return;
135 }
136 }
137 else if (guid.IsPlayer())
138 {
139 if (guid != _player->GetGUID() || menuId != _player->PlayerTalkClass->GetGossipMenu().GetMenuId())
140 {
141 //LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - {} not found.", guid.ToString());
142 return;
143 }
144 }
145 else
146 {
147 LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - unsupported GUID type for {}.", guid.ToString());
148 return;
149 }
150
151 // remove fake death
152 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
154
155 if ((unit && unit->GetScriptId() != unit->LastUsedScriptID) || (go && go->GetScriptId() != go->LastUsedScriptID))
156 {
157 LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - Script reloaded while in use, ignoring and set new scipt id");
158 if (unit)
159 unit->LastUsedScriptID = unit->GetScriptId();
160 if (go)
161 go->LastUsedScriptID = go->GetScriptId();
163 return;
164 }
165 if (!code.empty())
166 {
167 if (unit)
168 {
169 unit->AI()->sGossipSelectCode(_player, menuId, gossipListId, code.c_str());
170 if (!sScriptMgr->OnGossipSelectCode(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str()))
171 _player->OnGossipSelect(unit, gossipListId, menuId);
172 }
173 else if (go)
174 {
175 go->AI()->GossipSelectCode(_player, menuId, gossipListId, code.c_str());
176 sScriptMgr->OnGossipSelectCode(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str());
177 }
178 else if (item)
179 {
180 sScriptMgr->OnGossipSelectCode(_player, item, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str());
181 }
182 else
183 {
184 sScriptMgr->OnPlayerGossipSelectCode(_player, menuId, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str());
185 }
186 }
187 else
188 {
189 if (unit)
190 {
191 unit->AI()->sGossipSelect(_player, menuId, gossipListId);
192 if (!sScriptMgr->OnGossipSelect(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId)))
193 _player->OnGossipSelect(unit, gossipListId, menuId);
194 }
195 else if (go)
196 {
197 go->AI()->GossipSelect(_player, menuId, gossipListId);
198 if (!sScriptMgr->OnGossipSelect(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId)))
199 _player->OnGossipSelect(go, gossipListId, menuId);
200 }
201 else if (item)
202 {
203 sScriptMgr->OnGossipSelect(_player, item, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId));
204 }
205 else
206 {
207 sScriptMgr->OnPlayerGossipSelect(_player, menuId, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId));
208 }
209 }
210}
uint32 GetScriptId() const
Definition Creature.cpp:3057
virtual bool GossipSelectCode(Player *, uint32, uint32, char const *)
Definition GameObjectAI.h:56
virtual bool GossipSelect(Player *, uint32, uint32)
Definition GameObjectAI.h:55
virtual uint32 GetScriptId() const
Definition GameObject.cpp:2189
uint32 GetMenuId() const
Definition GossipDef.h:172
ObjectGuid GetSenderGUID() const
Definition GossipDef.h:218
bool IsCreatureOrVehicle() const
Definition ObjectGuid.h:166
void SendCloseGossip()
Definition GossipDef.cpp:239
bool IsGossipOptionCoded(uint32 selection) const
Definition GossipDef.h:272
uint32 GetGossipOptionSender(uint32 selection) const
Definition GossipDef.h:270
GossipMenu & GetGossipMenu()
Definition GossipDef.h:264
uint32 GetGossipOptionAction(uint32 selection) const
Definition GossipDef.h:271
void OnGossipSelect(WorldObject *source, uint32 gossipListId, uint32 menuId)
Definition PlayerGossip.cpp:244
PlayerMenu * PlayerTalkClass
Definition Player.h:2253
virtual void sGossipSelectCode(Player *, uint32, uint32, char const *)
Definition UnitAI.h:414
virtual void sGossipSelect(Player *, uint32, uint32)
Definition UnitAI.h:413
uint32 LastUsedScriptID
Definition Object.h:679

References _player, Creature::AI(), GameObject::AI(), Map::GetGameObject(), PlayerMenu::GetGossipMenu(), PlayerMenu::GetGossipOptionAction(), PlayerMenu::GetGossipOptionSender(), Object::GetGUID(), Player::GetItemByGuid(), WorldObject::GetMap(), GossipMenu::GetMenuId(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Item::GetPos(), Creature::GetScriptId(), GameObject::GetScriptId(), GossipMenu::GetSenderGUID(), GameObjectAI::GossipSelect(), GameObjectAI::GossipSelectCode(), Player::IsBankPos(), ObjectGuid::IsCreatureOrVehicle(), ObjectGuid::IsGameObject(), PlayerMenu::IsGossipOptionCoded(), ObjectGuid::IsItem(), ObjectGuid::IsPlayer(), WorldObject::LastUsedScriptID, LOG_DEBUG, Player::OnGossipSelect(), Player::PlayerTalkClass, Unit::RemoveAurasByType(), PlayerMenu::SendCloseGossip(), UnitAI::sGossipSelect(), UnitAI::sGossipSelectCode(), SPELL_AURA_FEIGN_DEATH, sScriptMgr, ObjectGuid::ToString(), UNIT_NPC_FLAG_NONE, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleGrantLevel()

void WorldSession::HandleGrantLevel ( WorldPacket recvData)
24{
25 LOG_DEBUG("network", "WORLD: CMSG_GRANT_LEVEL");
26
27 ObjectGuid guid;
28 recvData >> guid.ReadAsPacked();
29
31
32 // check cheating
34 uint8 error = 0;
35 if (!target)
37 else if (levels == 0)
39 else if (GetRecruiterId() != target->GetSession()->GetAccountId())
41 else if (target->GetTeamId() != _player->GetTeamId())
43 else if (target->GetLevel() >= _player->GetLevel())
45 else if (target->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
47 else if (target->GetGroup() != _player->GetGroup())
49
50 if (error)
51 {
53 data << uint32(error);
55 data << target->GetName();
56
57 SendPacket(&data);
58 return;
59 }
60
62 data2 << _player->GetPackGUID();
63 target->SendDirectMessage(&data2);
64}
@ ERR_REFER_A_FRIEND_TARGET_TOO_HIGH
Definition Player.h:963
@ ERR_REFER_A_FRIEND_DIFFERENT_FACTION
Definition Player.h:966
@ ERR_REFER_A_FRIEND_NO_TARGET
Definition Player.h:969
@ ERR_REFER_A_FRIEND_INSUFFICIENT_GRANTABLE_LEVELS
Definition Player.h:964
@ ERR_REFER_A_FRIEND_NOT_REFERRED_BY
Definition Player.h:962
@ ERR_REFER_A_FRIEND_NOT_IN_GROUP
Definition Player.h:970
@ ERR_REFER_A_FRIEND_GRANT_LEVEL_MAX_I
Definition Player.h:968
@ CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL
Definition WorldConfig.h:201
@ SMSG_REFER_A_FRIEND_FAILURE
Definition Opcodes.h:1087
@ SMSG_PROPOSE_LEVEL_GRANT
Definition Opcodes.h:1085

References _player, CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL, ERR_REFER_A_FRIEND_DIFFERENT_FACTION, ERR_REFER_A_FRIEND_GRANT_LEVEL_MAX_I, ERR_REFER_A_FRIEND_INSUFFICIENT_GRANTABLE_LEVELS, ERR_REFER_A_FRIEND_NO_TARGET, ERR_REFER_A_FRIEND_NOT_IN_GROUP, ERR_REFER_A_FRIEND_NOT_REFERRED_BY, ERR_REFER_A_FRIEND_TARGET_TOO_HIGH, GetAccountId(), Player::GetGrantableLevels(), Player::GetGroup(), Unit::GetLevel(), WorldObject::GetName(), Object::GetPackGUID(), ObjectAccessor::GetPlayer(), GetRecruiterId(), Player::GetSession(), Player::GetTeamId(), LOG_DEBUG, ObjectGuid::ReadAsPacked(), Player::SendDirectMessage(), SendPacket(), SMSG_PROPOSE_LEVEL_GRANT, SMSG_REFER_A_FRIEND_FAILURE, and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleGroupAcceptOpcode()

void WorldSession::HandleGroupAcceptOpcode ( WorldPacket recvPacket)
218{
219 recvData.read_skip<uint32>();
220 Group* group = GetPlayer()->GetGroupInvite();
221
222 if (!group)
223 return;
224
225 // Remove player from invitees in any case
226 group->RemoveInvite(GetPlayer());
227
228 if (GetPlayer()->IsSpectator())
229 {
231 return;
232 }
233
234 if (!sScriptMgr->OnPlayerCanGroupAccept(GetPlayer(), group))
235 return;
236
237 if (group->GetLeaderGUID() == GetPlayer()->GetGUID())
238 {
239 LOG_ERROR("network.opcode", "HandleGroupAcceptOpcode: player {} ({}) tried to accept an invite to his own group",
240 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
241 return;
242 }
243
244 // Group is full
245 if (group->IsFull())
246 {
248 return;
249 }
250
251 Player* leader = ObjectAccessor::FindConnectedPlayer(group->GetLeaderGUID());
252
253 // Forming a new group, create it
254 if (!group->IsCreated())
255 {
256 // This can happen if the leader is zoning. To be removed once delayed actions for zoning are implemented
257 if (!leader || leader->IsSpectator())
258 {
259 group->RemoveAllInvites();
260 return;
261 }
262
263 // If we're about to create a group there really should be a leader present
264 ASSERT(leader);
265 group->RemoveInvite(leader);
266 group->Create(leader);
267 sGroupMgr->AddGroup(group);
268 }
269
270 // Everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!!
271 if (!group->AddMember(GetPlayer()))
272 return;
273
274 group->BroadcastGroupUpdate();
275}
#define sGroupMgr
Definition GroupMgr.h:51
@ ERR_INVITE_RESTRICTED
Definition SharedDefines.h:3982
@ ERR_GROUP_FULL
Definition SharedDefines.h:3975
void RemoveInvite(Player *player)
Definition Group.cpp:351
bool IsSpectator() const
Definition Player.h:2586
Group * GetGroupInvite()
Definition Player.h:2480
void SendPartyResult(PartyOperation operation, std::string const &member, PartyResult res, uint32 val=0)
Definition GroupHandler.cpp:53
@ PARTY_OP_INVITE
Definition WorldSession.h:230

References ASSERT, ERR_GROUP_FULL, ERR_INVITE_RESTRICTED, ObjectAccessor::FindConnectedPlayer(), Player::GetGroupInvite(), GetPlayer(), Player::IsSpectator(), LOG_ERROR, PARTY_OP_INVITE, ByteBuffer::read_skip(), Group::RemoveInvite(), SendPartyResult(), sGroupMgr, and sScriptMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleGroupAssistantLeaderOpcode()

void WorldSession::HandleGroupAssistantLeaderOpcode ( WorldPacket recvData)
652{
653 Group* group = GetPlayer()->GetGroup();
654 if (!group)
655 return;
656
657 if (!group->IsLeader(GetPlayer()->GetGUID()))
658 return;
659
660 ObjectGuid guid;
661 bool apply;
662 recvData >> guid;
663 recvData >> apply;
664
665 group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_ASSISTANT);
666
667 group->SendUpdate();
668}
@ MEMBER_FLAG_ASSISTANT
Definition Group.h:73
bool IsLeader(ObjectGuid guid) const
Definition Group.cpp:2351
void SendUpdate()
Definition Group.cpp:1665
void SetGroupMemberFlag(ObjectGuid guid, bool apply, GroupMemberFlags flag)
Definition Group.cpp:2412

References Player::GetGroup(), GetPlayer(), Group::IsLeader(), MEMBER_FLAG_ASSISTANT, Group::SendUpdate(), and Group::SetGroupMemberFlag().

Referenced by OpcodeTable::Initialize().

◆ HandleGroupChangeSubGroupOpcode()

void WorldSession::HandleGroupChangeSubGroupOpcode ( WorldPacket recvData)
615{
616 // we will get correct pointer for group here, so we don't have to check if group is BG raid
617 Group* group = GetPlayer()->GetGroup();
618 if (!group)
619 return;
620
621 std::string name;
622 uint8 groupNr;
623 recvData >> name;
624 recvData >> groupNr;
625
626 if (groupNr >= MAX_RAID_SUBGROUPS)
627 return;
628
629 ObjectGuid senderGuid = GetPlayer()->GetGUID();
630 if (!group->IsLeader(senderGuid) && !group->IsAssistant(senderGuid))
631 return;
632
633 if (!group->HasFreeSlotSubGroup(groupNr))
634 return;
635
636 Player* movedPlayer = ObjectAccessor::FindPlayerByName(name, false);
637 ObjectGuid guid;
638 if (movedPlayer)
639 {
640 guid = movedPlayer->GetGUID();
641 }
642 else
643 {
644 CharacterDatabase.EscapeString(name);
645 guid = sCharacterCache->GetCharacterGuidByName(name);
646 }
647
648 group->ChangeMembersGroup(guid, groupNr);
649}
#define MAX_RAID_SUBGROUPS
Definition Group.h:45
void ChangeMembersGroup(ObjectGuid guid, uint8 group)
Definition Group.cpp:1808
bool IsAssistant(ObjectGuid guid) const
Definition Group.cpp:2365
bool HasFreeSlotSubGroup(uint8 subgroup) const
Definition Group.cpp:2389

References Group::ChangeMembersGroup(), CharacterDatabase, ObjectAccessor::FindPlayerByName(), Player::GetGroup(), Object::GetGUID(), GetPlayer(), Group::HasFreeSlotSubGroup(), Group::IsAssistant(), Group::IsLeader(), MAX_RAID_SUBGROUPS, and sCharacterCache.

Referenced by OpcodeTable::Initialize().

◆ HandleGroupDeclineOpcode()

void WorldSession::HandleGroupDeclineOpcode ( WorldPacket recvPacket)
278{
279 Group* group = GetPlayer()->GetGroupInvite();
280 if (!group)
281 return;
282
283 // Remember leader if online (group pointer will be invalid if group gets disbanded)
285
286 // uninvite, group can be deleted
288
289 if (!leader)
290 return;
291
292 // report
293 WorldPacket data(SMSG_GROUP_DECLINE, GetPlayer()->GetName().length());
294 data << GetPlayer()->GetName();
295 leader->SendDirectMessage(&data);
296}
void UninviteFromGroup()
Definition Player.cpp:2310
@ SMSG_GROUP_DECLINE
Definition Opcodes.h:146

References ObjectAccessor::FindConnectedPlayer(), Player::GetGroupInvite(), Group::GetLeaderGUID(), WorldObject::GetName(), GetPlayer(), Player::SendDirectMessage(), SMSG_GROUP_DECLINE, and Player::UninviteFromGroup().

Referenced by OpcodeTable::Initialize().

◆ HandleGroupDisbandOpcode()

void WorldSession::HandleGroupDisbandOpcode ( WorldPacket recvPacket)

error handling

436{
437 Group* grp = GetPlayer()->GetGroup();
438 Group* grpInvite = GetPlayer()->GetGroupInvite();
439 if (!grp && !grpInvite)
440 return;
441
442 if (_player->InBattleground())
443 {
445 return;
446 }
447
449 /********************/
450
451 // everything's fine, do it
452 if (grp)
453 {
456 }
457 else if (grpInvite && grpInvite->GetLeaderGUID() == GetPlayer()->GetGUID())
458 { // pending group creation being cancelled
460 grpInvite->Disband();
461 }
462}
@ GROUP_REMOVEMETHOD_LEAVE
Definition SharedDefines.h:3855
@ ERR_PARTY_RESULT_OK
Definition SharedDefines.h:3971
void Disband(bool hideDestroy=false)
Definition Group.cpp:753
static void RemoveFromGroup(Group *group, ObjectGuid guid, RemoveMethod method=GROUP_REMOVEMETHOD_DEFAULT, ObjectGuid kicker=ObjectGuid::Empty, const char *reason=nullptr)
Definition Player.cpp:2337
@ PARTY_OP_LEAVE
Definition WorldSession.h:232

References _player, Group::Disband(), ERR_INVITE_RESTRICTED, ERR_PARTY_RESULT_OK, Player::GetGroup(), Player::GetGroupInvite(), Group::GetLeaderGUID(), GetPlayer(), GROUP_REMOVEMETHOD_LEAVE, Player::InBattleground(), PARTY_OP_INVITE, PARTY_OP_LEAVE, Player::RemoveFromGroup(), and SendPartyResult().

Referenced by OpcodeTable::Initialize().

◆ HandleGroupInviteOpcode()

void WorldSession::HandleGroupInviteOpcode ( WorldPacket recvPacket)
65{
66 std::string membername;
67 recvData >> membername;
68 recvData.read_skip<uint32>();
69
70 // attempt add selected player
71
72 // cheating
73 if (!normalizePlayerName(membername))
74 {
76 return;
77 }
78
79 Player* invitingPlayer = GetPlayer();
80 Player* invitedPlayer = ObjectAccessor::FindPlayerByName(membername, false);
81
82 // no player or cheat self-invite
83 if (!invitedPlayer || invitedPlayer == invitingPlayer)
84 {
86 return;
87 }
88
89 if (!sScriptMgr->OnPlayerCanGroupInvite(invitingPlayer, membername))
90 return;
91
92 if (invitingPlayer->IsSpectator() || invitedPlayer->IsSpectator())
93 {
95 return;
96 }
97
98 // restrict invite to GMs
99 if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !invitingPlayer->IsGameMaster() && invitedPlayer->IsGameMaster())
100 {
102 return;
103 }
104
105 // can't group with
106 if (!invitingPlayer->IsGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && invitingPlayer->GetTeamId() != invitedPlayer->GetTeamId())
107 {
109 return;
110 }
111 if (invitingPlayer->GetInstanceId() != 0 && invitedPlayer->GetInstanceId() != 0 && invitingPlayer->GetInstanceId() != invitedPlayer->GetInstanceId() && invitingPlayer->GetMapId() == invitedPlayer->GetMapId())
112 {
114 return;
115 }
116
117 if (invitedPlayer->GetSocial()->HasIgnore(invitingPlayer->GetGUID()))
118 {
120 return;
121 }
122
123 if (!invitedPlayer->GetSocial()->HasFriend(invitingPlayer->GetGUID()) && invitingPlayer->GetLevel() < sWorld->getIntConfig(CONFIG_PARTY_LEVEL_REQ))
124 {
126 return;
127 }
128
129 Group* group = invitingPlayer->GetGroup();
130 if (group && group->isBGGroup())
131 group = invitingPlayer->GetOriginalGroup();
132 if (!group)
133 group = invitingPlayer->GetGroupInvite();
134
135 Group* group2 = invitedPlayer->GetGroup();
136 if (group2 && group2->isBGGroup())
137 group2 = invitedPlayer->GetOriginalGroup();
138 // player already in another group or invited
139 if (group2 || invitedPlayer->GetGroupInvite())
140 {
142
143 if (group2)
144 {
145 // tell the player that they were invited but it failed as they were already in a group
146 WorldPacket data(SMSG_GROUP_INVITE, 25); // guess size
147 data << uint8(0); // invited/already in group flag
148 data << invitingPlayer->GetName(); // max len 48
149 data << uint32(0); // unk
150 data << uint8(0); // count
151 data << uint32(0); // unk
152 invitedPlayer->SendDirectMessage(&data);
153 }
154
155 return;
156 }
157
158 if (group)
159 {
160 // not have permissions for invite
161 if (!group->IsLeader(invitingPlayer->GetGUID()) && !group->IsAssistant(invitingPlayer->GetGUID()))
162 {
164 return;
165 }
166 // not have place
167 if (group->IsFull())
168 {
170 return;
171 }
172 }
173
174 // xinef: if player has no group, check group invite
175 if (!group && invitingPlayer->GetGroupInvite() && invitingPlayer->GetGroupInvite()->GetLeaderGUID() == invitingPlayer->GetGUID())
176 group = invitingPlayer->GetGroupInvite();
177
178 // ok, but group not exist, start a new group
179 // but don't create and save the group to the DB until
180 // at least one person joins
181 if (!group)
182 {
183 group = new Group();
184 // new group: if can't add then delete
185 if (!group->AddLeaderInvite(invitingPlayer))
186 {
187 delete group;
188 return;
189 }
190 if (!group->AddInvite(invitedPlayer))
191 {
192 delete group;
193 return;
194 }
195 }
196 else
197 {
198 // already existed group: if can't add then just leave
199 if (!group->AddInvite(invitedPlayer))
200 {
201 return;
202 }
203 }
204
205 // ok, we do it
206 WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size
207 data << uint8(1); // invited/already in group flag
208 data << invitingPlayer->GetName(); // max len 48
209 data << uint32(0); // unk
210 data << uint8(0); // count
211 data << uint32(0); // unk
212 invitedPlayer->SendDirectMessage(&data);
213
215}
@ ERR_ALREADY_IN_GROUP_S
Definition SharedDefines.h:3976
@ ERR_TARGET_NOT_IN_INSTANCE_S
Definition SharedDefines.h:3974
@ ERR_IGNORING_YOU_S
Definition SharedDefines.h:3980
@ ERR_NOT_LEADER
Definition SharedDefines.h:3978
@ ERR_PLAYER_WRONG_FACTION
Definition SharedDefines.h:3979
@ ERR_BAD_PLAYER_NAME_S
Definition SharedDefines.h:3972
@ CONFIG_ALLOW_GM_GROUP
Definition WorldConfig.h:47
@ CONFIG_PARTY_LEVEL_REQ
Definition WorldConfig.h:247
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP
Definition WorldConfig.h:34
bool AddLeaderInvite(Player *player)
Definition Group.cpp:341
bool isBGGroup() const
Definition Group.cpp:2286
bool AddInvite(Player *player)
Definition Group.cpp:320
bool IsFull() const
Definition Group.cpp:2270
bool HasFriend(ObjectGuid const &friend_guid) const
Definition SocialMgr.cpp:188
Group * GetOriginalGroup()
Definition Player.h:2497
uint32 GetInstanceId() const
Definition Object.h:509
@ SMSG_GROUP_INVITE
Definition Opcodes.h:141

References Group::AddInvite(), Group::AddLeaderInvite(), CONFIG_ALLOW_GM_GROUP, CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP, CONFIG_PARTY_LEVEL_REQ, ERR_ALREADY_IN_GROUP_S, ERR_BAD_PLAYER_NAME_S, ERR_GROUP_FULL, ERR_IGNORING_YOU_S, ERR_INVITE_RESTRICTED, ERR_NOT_LEADER, ERR_PARTY_RESULT_OK, ERR_PLAYER_WRONG_FACTION, ERR_TARGET_NOT_IN_INSTANCE_S, ObjectAccessor::FindPlayerByName(), Player::GetGroup(), Player::GetGroupInvite(), Object::GetGUID(), WorldObject::GetInstanceId(), Group::GetLeaderGUID(), Unit::GetLevel(), WorldLocation::GetMapId(), WorldObject::GetName(), Player::GetOriginalGroup(), GetPlayer(), Player::GetSocial(), Player::GetTeamId(), PlayerSocial::HasFriend(), PlayerSocial::HasIgnore(), Group::IsAssistant(), Group::isBGGroup(), Group::IsFull(), Player::IsGameMaster(), Group::IsLeader(), Player::IsSpectator(), normalizePlayerName(), PARTY_OP_INVITE, ByteBuffer::read_skip(), Player::SendDirectMessage(), SendPartyResult(), SMSG_GROUP_INVITE, sScriptMgr, and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleGroupRaidConvertOpcode()

void WorldSession::HandleGroupRaidConvertOpcode ( WorldPacket recvData)

error handling

590{
591 Group* group = GetPlayer()->GetGroup();
592 if (!group)
593 return;
594
595 if (_player->InBattleground())
596 return;
597
599 if (group->CheckLevelForRaid())
600 {
602 return;
603 }
604
605 if (!group->IsLeader(GetPlayer()->GetGUID()) || group->GetMembersCount() < 2 || group->isLFGGroup()) // pussywizard: not allowed for lfg groups, it is either raid from the beginning or not!
606 return;
607 /********************/
608
609 // everything's fine, do it (is it 0 (PARTY_OP_INVITE) correct code)
611 group->ConvertToRaid();
612}
@ ERR_RAID_DISALLOWED_BY_LEVEL
Definition SharedDefines.h:3994
bool CheckLevelForRaid()
Definition Group.cpp:282
bool isLFGGroup(bool restricted=false) const
Definition Group.cpp:2275
void ConvertToRaid()
Definition Group.cpp:292

References _player, Group::CheckLevelForRaid(), Group::ConvertToRaid(), ERR_PARTY_RESULT_OK, ERR_RAID_DISALLOWED_BY_LEVEL, Player::GetGroup(), Group::GetMembersCount(), GetPlayer(), Player::InBattleground(), Group::IsLeader(), Group::isLFGGroup(), PARTY_OP_INVITE, and SendPartyResult().

Referenced by OpcodeTable::Initialize().

◆ HandleGroupSetLeaderOpcode()

void WorldSession::HandleGroupSetLeaderOpcode ( WorldPacket recvPacket)
417{
418 ObjectGuid guid;
419 recvData >> guid;
420
422 Group* group = GetPlayer()->GetGroup();
423
424 if (!group || !player)
425 return;
426
427 if (!group->IsLeader(GetPlayer()->GetGUID()) || player->GetGroup() != group || guid == GetPlayer()->GetGUID())
428 return;
429
430 // Everything's fine, accepted.
431 group->ChangeLeader(guid);
432 group->SendUpdate();
433}
void ChangeLeader(ObjectGuid guid)
Definition Group.cpp:712

References Group::ChangeLeader(), ObjectAccessor::FindConnectedPlayer(), Player::GetGroup(), GetPlayer(), Group::IsLeader(), and Group::SendUpdate().

Referenced by OpcodeTable::Initialize().

◆ HandleGroupSwapSubGroupOpcode()

void WorldSession::HandleGroupSwapSubGroupOpcode ( WorldPacket recvData)
1097{
1098 std::string playerName1, playerName2;
1099
1100 // first = moved from, second = moved to
1101 recv_data >> playerName1;
1102 recv_data >> playerName2;
1103
1104 if (!normalizePlayerName(playerName1))
1105 {
1107 return;
1108 }
1109 if (!normalizePlayerName(playerName2))
1110 {
1112 return;
1113 }
1114
1115 Group* group = GetPlayer()->GetGroup();
1116 if (!group || !group->isRaidGroup())
1117 {
1118 return;
1119 }
1120
1121 if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
1122 {
1123 return;
1124 }
1125
1126 //get guid, member may be offline
1127 auto getGuid = [&group](std::string const& playerName)
1128 {
1129 // no player, cheating?
1130 if (!group->GetMemberGUID(playerName))
1131 {
1132 return ObjectGuid::Empty;
1133 }
1134
1135 if (Player* player = ObjectAccessor::FindPlayerByName(playerName.c_str()))
1136 {
1137 return player->GetGUID();
1138 }
1139 else
1140 {
1141 if (ObjectGuid guid = sCharacterCache->GetCharacterGuidByName(playerName))
1142 {
1143 return guid;
1144 }
1145 else
1146 {
1147 return ObjectGuid::Empty; // no player - again, cheating?
1148 }
1149 }
1150 };
1151
1152 ObjectGuid guid1 = getGuid(playerName1);
1153 ObjectGuid guid2 = getGuid(playerName2);
1154
1155 if (!guid1 || !guid2)
1156 {
1158 return;
1159 }
1160
1161 uint8 groupId1 = group->GetMemberGroup(guid1);
1162 uint8 groupId2 = group->GetMemberGroup(guid2);
1163
1164 if (groupId1 == MAX_RAID_SUBGROUPS + 1 || groupId2 == MAX_RAID_SUBGROUPS + 1)
1165 {
1166 return;
1167 }
1168
1169 if (groupId1 == groupId2)
1170 {
1171 return;
1172 }
1173
1174 group->ChangeMembersGroup(guid1, groupId2);
1175 group->ChangeMembersGroup(guid2, groupId1);
1176}
@ ERR_GROUP_SWAP_FAILED
Definition SharedDefines.h:3983
uint8 GetMemberGroup(ObjectGuid guid) const
Definition Group.cpp:2394
ObjectGuid GetMemberGUID(const std::string &name)
Definition Group.cpp:2356
bool isRaidGroup() const
Definition Group.cpp:2281
@ PARTY_OP_SWAP
Definition WorldSession.h:233

References Group::ChangeMembersGroup(), ObjectGuid::Empty, ERR_GROUP_SWAP_FAILED, ObjectAccessor::FindPlayerByName(), Player::GetGroup(), Group::GetMemberGroup(), Group::GetMemberGUID(), GetPlayer(), Group::IsAssistant(), Group::IsLeader(), Group::isRaidGroup(), MAX_RAID_SUBGROUPS, normalizePlayerName(), PARTY_OP_SWAP, sCharacterCache, and SendPartyResult().

Referenced by OpcodeTable::Initialize().

◆ HandleGroupUninviteGuidOpcode()

void WorldSession::HandleGroupUninviteGuidOpcode ( WorldPacket recvPacket)
299{
300 ObjectGuid guid;
301 std::string reason, name;
302 recvData >> guid;
303 recvData >> reason;
304
305 //can't uninvite yourself
306 if (guid == GetPlayer()->GetGUID())
307 {
308 LOG_ERROR("network.opcode", "WorldSession::HandleGroupUninviteGuidOpcode: leader {} ({}) tried to uninvite himself from the group.",
309 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
310 return;
311 }
312
313 sCharacterCache->GetCharacterNameByGuid(guid, name);
314
316 if (res != ERR_PARTY_RESULT_OK)
317 {
319 {
320 if (Player* kickTarget = ObjectAccessor::FindConnectedPlayer(guid))
321 {
322 if (Aura* dungeonCooldownAura = kickTarget->GetAura(lfg::LFG_SPELL_DUNGEON_COOLDOWN))
323 {
324 int32 elapsedTime = dungeonCooldownAura->GetMaxDuration() - dungeonCooldownAura->GetDuration();
325 if (static_cast<int32>(sWorld->getIntConfig(CONFIG_LFG_KICK_PREVENTION_TIMER)) > elapsedTime)
326 {
327 SendPartyResult(PARTY_OP_UNINVITE, name, res, (sWorld->getIntConfig(CONFIG_LFG_KICK_PREVENTION_TIMER) - elapsedTime) / 1000);
328 }
329 }
330 }
331 } else
332 {
334 }
335
336 return;
337 }
338
339 Group* grp = GetPlayer()->GetGroup();
340 if (!grp)
341 return;
342
343 // Xinef: do not allow to kick with empty reason, this will resend packet with given reason
344 if (grp->isLFGGroup(true) && reason.empty())
345 {
347 return;
348 }
349
350 if (grp->IsLeader(guid) && !grp->isLFGGroup(true))
351 {
353 return;
354 }
355
356 if (grp->IsMember(guid))
357 {
358 Player::RemoveFromGroup(grp, guid, GROUP_REMOVEMETHOD_KICK, GetPlayer()->GetGUID(), reason.c_str());
359 return;
360 }
361
362 if (Player* player = grp->GetInvited(guid))
363 {
364 player->UninviteFromGroup();
365 return;
366 }
367
369}
@ GROUP_REMOVEMETHOD_KICK
Definition SharedDefines.h:3854
PartyResult
Definition SharedDefines.h:3970
@ ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S
Definition SharedDefines.h:3993
@ ERR_VOTE_KICK_REASON_NEEDED
Definition SharedDefines.h:3996
@ ERR_TARGET_NOT_IN_GROUP_S
Definition SharedDefines.h:3973
@ CONFIG_LFG_KICK_PREVENTION_TIMER
Definition WorldConfig.h:377
Definition SpellAuras.h:87
Player * GetInvited(ObjectGuid guid) const
Definition Group.cpp:370
bool IsMember(ObjectGuid guid) const
Definition Group.cpp:2346
PartyResult CanUninviteFromGroup(ObjectGuid targetPlayerGUID=ObjectGuid::Empty) const
Definition Player.cpp:13049
@ PARTY_OP_UNINVITE
Definition WorldSession.h:231
@ LFG_SPELL_DUNGEON_COOLDOWN
Definition LFGMgr.h:52

References Player::CanUninviteFromGroup(), CONFIG_LFG_KICK_PREVENTION_TIMER, ERR_NOT_LEADER, ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S, ERR_PARTY_RESULT_OK, ERR_TARGET_NOT_IN_GROUP_S, ERR_VOTE_KICK_REASON_NEEDED, ObjectAccessor::FindConnectedPlayer(), Player::GetGroup(), Group::GetInvited(), GetPlayer(), GROUP_REMOVEMETHOD_KICK, Group::IsLeader(), Group::isLFGGroup(), Group::IsMember(), lfg::LFG_SPELL_DUNGEON_COOLDOWN, LOG_ERROR, PARTY_OP_UNINVITE, Player::RemoveFromGroup(), sCharacterCache, SendPartyResult(), and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleGroupUninviteOpcode()

void WorldSession::HandleGroupUninviteOpcode ( WorldPacket recvPacket)
372{
373 std::string membername;
374 recvData >> membername;
375
376 // player not found
377 if (!normalizePlayerName(membername))
378 return;
379
380 // can't uninvite yourself
381 if (GetPlayer()->GetName() == membername)
382 {
383 LOG_ERROR("network.opcode", "WorldSession::HandleGroupUninviteOpcode: leader {} ({}) tried to uninvite himself from the group.",
384 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
385 return;
386 }
387
388 Group* grp = GetPlayer()->GetGroup();
389 if (!grp)
390 {
391 return;
392 }
393
394 PartyResult res = GetPlayer()->CanUninviteFromGroup(grp->GetMemberGUID(membername));
395 if (res != ERR_PARTY_RESULT_OK)
396 {
398 return;
399 }
400
401 if (ObjectGuid guid = grp->GetMemberGUID(membername))
402 {
404 return;
405 }
406
407 if (Player* player = grp->GetInvited(membername))
408 {
409 player->UninviteFromGroup();
410 return;
411 }
412
414}

References Player::CanUninviteFromGroup(), ERR_PARTY_RESULT_OK, ERR_TARGET_NOT_IN_GROUP_S, Player::GetGroup(), Group::GetInvited(), Group::GetMemberGUID(), GetPlayer(), GROUP_REMOVEMETHOD_KICK, LOG_ERROR, normalizePlayerName(), PARTY_OP_UNINVITE, Player::RemoveFromGroup(), and SendPartyResult().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildAcceptOpcode()

void WorldSession::HandleGuildAcceptOpcode ( WorldPackets::Guild::AcceptGuildInvite invite)
59{
60 LOG_DEBUG("guild", "CMSG_GUILD_ACCEPT [{}]", GetPlayer()->GetName());
61
62 if (!GetPlayer()->GetGuildId())
63 if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildIdInvited()))
64 guild->HandleAcceptMember(this);
65}

References GetPlayer(), LOG_DEBUG, and sGuildMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildAddRankOpcode()

void WorldSession::HandleGuildAddRankOpcode ( WorldPackets::Guild::GuildAddRank packet)
201{
202 LOG_DEBUG("guild", "CMSG_GUILD_ADD_RANK [{}]: Rank: {}", GetPlayerInfo(), packet.Name);
203
204 if (Guild* guild = GetPlayer()->GetGuild())
205 guild->HandleAddNewRank(this, packet.Name);
206}
String< 15, Strings::NoHyperlinks > Name
Definition GuildPackets.h:291

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, and WorldPackets::Guild::GuildAddRank::Name.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildBankBuyTab()

void WorldSession::HandleGuildBankBuyTab ( WorldPackets::Guild::GuildBankBuyTab packet)
361{
362 LOG_DEBUG("guild", "CMSG_GUILD_BANK_BUY_TAB [{}]: [{}[, TabId: {}", GetPlayerInfo(), packet.Banker .ToString(), packet.BankTab);
363
364 if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
365 if (Guild* guild = GetPlayer()->GetGuild())
366 guild->HandleBuyBankTab(this, packet.BankTab);
367}
@ GAMEOBJECT_TYPE_GUILD_BANK
Definition SharedDefines.h:1605
ObjectGuid Banker
Definition GuildPackets.h:387
uint8 BankTab
Definition GuildPackets.h:388

References WorldPackets::Guild::GuildBankBuyTab::Banker, WorldPackets::Guild::GuildBankBuyTab::BankTab, GAMEOBJECT_TYPE_GUILD_BANK, GetPlayer(), GetPlayerInfo(), LOG_DEBUG, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildBankDepositMoney()

void WorldSession::HandleGuildBankDepositMoney ( WorldPackets::Guild::GuildBankDepositMoney packet)
302{
303 LOG_DEBUG("guild", "CMSG_GUILD_BANK_DEPOSIT_MONEY [{}]: Go: [{}], money: {}",
304 GetPlayerInfo(), packet.Banker.ToString(), packet.Money);
305
306 if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
307 if (packet.Money && GetPlayer()->HasEnoughMoney(packet.Money))
308 if (Guild* guild = GetPlayer()->GetGuild())
309 guild->HandleMemberDepositMoney(this, packet.Money);
310}
uint32 Money
Definition GuildPackets.h:412
ObjectGuid Banker
Definition GuildPackets.h:411

References WorldPackets::Guild::GuildBankDepositMoney::Banker, GAMEOBJECT_TYPE_GUILD_BANK, GetPlayer(), GetPlayerInfo(), LOG_DEBUG, WorldPackets::Guild::GuildBankDepositMoney::Money, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildBankerActivate()

void WorldSession::HandleGuildBankerActivate ( WorldPackets::Guild::GuildBankActivate packet)
272{
273 LOG_DEBUG("guild", "CMSG_GUILD_BANKER_ACTIVATE [{}]: Go: [{}] AllSlots: {}"
274 , GetPlayerInfo(), packet.Banker.ToString(), packet.FullUpdate);
275
277 if (!go)
278 return;
279
280 Guild* const guild = GetPlayer()->GetGuild();
281 if (!guild)
282 {
284 return;
285 }
286
287 guild->SendBankTabsInfo(this, packet.FullUpdate);
288}
@ GUILD_COMMAND_VIEW_TAB
Definition Guild.h:112
@ ERR_GUILD_PLAYER_NOT_IN_GUILD
Definition Guild.h:129
void SendBankTabsInfo(WorldSession *session, bool showTabs=false)
Definition Guild.cpp:1820
static void SendCommandResult(WorldSession *session, GuildCommandType type, GuildCommandError errCode, std::string_view param={})
Definition Guild.cpp:114
Guild * GetGuild() const
Definition Player.cpp:16012
bool FullUpdate
Definition GuildPackets.h:377
ObjectGuid Banker
Definition GuildPackets.h:376

References WorldPackets::Guild::GuildBankActivate::Banker, ERR_GUILD_PLAYER_NOT_IN_GUILD, WorldPackets::Guild::GuildBankActivate::FullUpdate, GAMEOBJECT_TYPE_GUILD_BANK, Player::GetGameObjectIfCanInteractWith(), Player::GetGuild(), GetPlayer(), GetPlayerInfo(), GUILD_COMMAND_VIEW_TAB, LOG_DEBUG, Guild::SendBankTabsInfo(), Guild::SendCommandResult(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildBankLogQuery()

void WorldSession::HandleGuildBankLogQuery ( WorldPackets::Guild::GuildBankLogQuery packet)
381{
382 LOG_DEBUG("guild", "MSG_GUILD_BANK_LOG_QUERY [{}]: TabId: {}", GetPlayerInfo(), packet.Tab);
383
384 if (Guild* guild = GetPlayer()->GetGuild())
385 guild->SendBankLog(this, packet.Tab);
386}
uint8 Tab
Definition GuildPackets.h:531

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, and WorldPackets::Guild::GuildBankLogQuery::Tab.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildBankMoneyWithdrawn()

void WorldSession::HandleGuildBankMoneyWithdrawn ( WorldPackets::Guild::GuildBankRemainingWithdrawMoneyQuery packet)
257{
258 LOG_DEBUG("guild", "MSG_GUILD_BANK_MONEY_WITHDRAWN [{}]", GetPlayerInfo());
259
260 if (Guild* guild = GetPlayer()->GetGuild())
261 guild->SendMoneyInfo(this);
262}

References GetPlayer(), GetPlayerInfo(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildBankQueryTab()

void WorldSession::HandleGuildBankQueryTab ( WorldPackets::Guild::GuildBankQueryTab packet)
292{
293 LOG_DEBUG("guild", "CMSG_GUILD_BANK_QUERY_TAB [{}]: Go: [{}], TabId: {}, ShowTabs: {}"
294 , GetPlayerInfo(), packet.Banker.ToString(), packet.Tab, packet.FullUpdate);
295
296 if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
297 if (Guild* guild = GetPlayer()->GetGuild())
298 guild->SendBankTabData(this, packet.Tab, packet.FullUpdate);
299}
bool FullUpdate
Definition GuildPackets.h:424
uint8 Tab
Definition GuildPackets.h:423
ObjectGuid Banker
Definition GuildPackets.h:422

References WorldPackets::Guild::GuildBankQueryTab::Banker, WorldPackets::Guild::GuildBankQueryTab::FullUpdate, GAMEOBJECT_TYPE_GUILD_BANK, GetPlayer(), GetPlayerInfo(), LOG_DEBUG, WorldPackets::Guild::GuildBankQueryTab::Tab, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildBankSwapItems()

void WorldSession::HandleGuildBankSwapItems ( WorldPackets::Guild::GuildBankSwapItems packet)
322{
323 if (!GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
324 {
325 return;
326 }
327
328 Guild* guild = GetPlayer()->GetGuild();
329 if (!guild)
330 {
331 return;
332 }
333
334 if (packet.BankOnly)
335 guild->SwapItems(GetPlayer(), packet.BankTab1, packet.BankSlot1, packet.BankTab, packet.BankSlot, packet.BankItemCount);
336 else
337 {
338 uint8 playerBag = NULL_BAG;
339 uint8 playerSlotId = NULL_SLOT;
340 uint8 toChar = 1;
341 uint32 splitedAmount = 0;
342
343 if (!packet.AutoStore)
344 {
345 playerBag = packet.ContainerSlot;
346 playerSlotId = packet.ContainerItemSlot;
347 toChar = packet.ToSlot;
348 splitedAmount = packet.StackCount;
349 }
350
351 // Player <-> Bank
352 // Allow to work with inventory only
353 if (!Player::IsInventoryPos(playerBag, playerSlotId) && !(playerBag == NULL_BAG && playerSlotId == NULL_SLOT))
355 else
356 guild->SwapItemsWithInventory(GetPlayer(), toChar != 0, packet.BankTab, packet.BankSlot, playerBag, playerSlotId, splitedAmount);
357 }
358}
void SwapItemsWithInventory(Player *player, bool toChar, uint8 tabId, uint8 slotId, uint8 playerBag, uint8 playerSlotId, uint32 splitedAmount)
Definition Guild.cpp:2360
void SwapItems(Player *player, uint8 tabId, uint8 slotId, uint8 destTabId, uint8 destSlotId, uint32 splitedAmount)
Definition Guild.cpp:2346
uint8 ContainerSlot
Definition GuildPackets.h:518
uint8 ToSlot
Definition GuildPackets.h:513
bool BankOnly
Definition GuildPackets.h:521
uint8 ContainerItemSlot
Definition GuildPackets.h:519
uint8 BankTab
Definition GuildPackets.h:516
ObjectGuid Banker
Definition GuildPackets.h:508
uint8 BankTab1
Definition GuildPackets.h:517
uint8 BankSlot
Definition GuildPackets.h:514
bool AutoStore
Definition GuildPackets.h:520
uint8 BankSlot1
Definition GuildPackets.h:515
int32 BankItemCount
Definition GuildPackets.h:510
int32 StackCount
Definition GuildPackets.h:509

References WorldPackets::Guild::GuildBankSwapItems::AutoStore, WorldPackets::Guild::GuildBankSwapItems::Banker, WorldPackets::Guild::GuildBankSwapItems::BankItemCount, WorldPackets::Guild::GuildBankSwapItems::BankOnly, WorldPackets::Guild::GuildBankSwapItems::BankSlot, WorldPackets::Guild::GuildBankSwapItems::BankSlot1, WorldPackets::Guild::GuildBankSwapItems::BankTab, WorldPackets::Guild::GuildBankSwapItems::BankTab1, WorldPackets::Guild::GuildBankSwapItems::ContainerItemSlot, WorldPackets::Guild::GuildBankSwapItems::ContainerSlot, EQUIP_ERR_NONE, GAMEOBJECT_TYPE_GUILD_BANK, Player::GetGuild(), GetPlayer(), Player::IsInventoryPos(), NULL_BAG, NULL_SLOT, Player::SendEquipError(), WorldPackets::Guild::GuildBankSwapItems::StackCount, Guild::SwapItems(), Guild::SwapItemsWithInventory(), and WorldPackets::Guild::GuildBankSwapItems::ToSlot.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildBankUpdateTab()

void WorldSession::HandleGuildBankUpdateTab ( WorldPackets::Guild::GuildBankUpdateTab packet)
370{
371 LOG_DEBUG("guild", "CMSG_GUILD_BANK_UPDATE_TAB [{}]: Go: [{}], TabId: {}, Name: {}, Icon: {}"
372 , GetPlayerInfo(), packet.Banker.ToString(), packet.BankTab, packet.Name, packet.Icon);
373
374 if (!packet.Name.empty() && !packet.Icon.empty())
375 if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
376 if (Guild* guild = GetPlayer()->GetGuild())
377 guild->HandleSetBankTabInfo(this, packet.BankTab, packet.Name, packet.Icon);
378}
String< 16, Strings::NoHyperlinks > Name
Definition GuildPackets.h:400
uint8 BankTab
Definition GuildPackets.h:399
String< 100 > Icon
Definition GuildPackets.h:401
ObjectGuid Banker
Definition GuildPackets.h:398
bool empty() const
Definition PacketUtilities.h:78

References WorldPackets::Guild::GuildBankUpdateTab::Banker, WorldPackets::Guild::GuildBankUpdateTab::BankTab, WorldPackets::String< MaxBytesWithoutNullTerminator, Validators >::empty(), GAMEOBJECT_TYPE_GUILD_BANK, GetPlayer(), GetPlayerInfo(), WorldPackets::Guild::GuildBankUpdateTab::Icon, LOG_DEBUG, WorldPackets::Guild::GuildBankUpdateTab::Name, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildBankWithdrawMoney()

void WorldSession::HandleGuildBankWithdrawMoney ( WorldPackets::Guild::GuildBankWithdrawMoney packet)
313{
314 LOG_DEBUG("guild", "CMSG_GUILD_BANK_WITHDRAW_MONEY [{}]: Go: [{}], money: {}",
315 GetPlayerInfo(), packet.Banker.ToString(), packet.Money);
316 if (packet.Money && GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
317 if (Guild* guild = GetPlayer()->GetGuild())
318 guild->HandleMemberWithdrawMoney(this, packet.Money);
319}
uint32 Money
Definition GuildPackets.h:453
ObjectGuid Banker
Definition GuildPackets.h:452

References WorldPackets::Guild::GuildBankWithdrawMoney::Banker, GAMEOBJECT_TYPE_GUILD_BANK, GetPlayer(), GetPlayerInfo(), LOG_DEBUG, WorldPackets::Guild::GuildBankWithdrawMoney::Money, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildChangeInfoTextOpcode()

void WorldSession::HandleGuildChangeInfoTextOpcode ( WorldPackets::Guild::GuildUpdateInfoText packet)
217{
218 LOG_DEBUG("guild", "CMSG_GUILD_INFO_TEXT [{}]: {}", GetPlayerInfo(), packet.InfoText);
219
220 if (Guild* guild = GetPlayer()->GetGuild())
221 guild->HandleSetInfo(this, packet.InfoText);
222}
String< 500, Strings::NoHyperlinks > InfoText
Definition GuildPackets.h:309

References GetPlayer(), GetPlayerInfo(), WorldPackets::Guild::GuildUpdateInfoText::InfoText, and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildCreateOpcode()

void WorldSession::HandleGuildCreateOpcode ( WorldPackets::Guild::GuildCreate packet)
37{
38 LOG_ERROR("network.opcode", "CMSG_GUILD_CREATE: Possible hacking-attempt: {} tried to create a guild [Name: {}] using cheats", GetPlayerInfo(), packet.GuildName);
39}
std::string GuildName
Definition GuildPackets.h:73

References GetPlayerInfo(), WorldPackets::Guild::GuildCreate::GuildName, and LOG_ERROR.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildDeclineOpcode()

void WorldSession::HandleGuildDeclineOpcode ( WorldPackets::Guild::GuildDeclineInvitation decline)
68{
69 LOG_DEBUG("guild", "CMSG_GUILD_DECLINE [{}]", GetPlayerInfo());
70
71 if (GetPlayer()->GetGuild())
72 {
73 return;
74 }
75
78}
void SetGuildIdInvited(uint32 GuildId)
Definition Player.h:1895
void SetInGuild(uint32 GuildId)
Definition Player.h:1887

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, Player::SetGuildIdInvited(), and Player::SetInGuild().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildDelRankOpcode()

void WorldSession::HandleGuildDelRankOpcode ( WorldPackets::Guild::GuildDeleteRank packet)
209{
210 LOG_DEBUG("guild", "CMSG_GUILD_DEL_RANK [{}]", GetPlayerInfo());
211
212 if (Guild* guild = GetPlayer()->GetGuild())
213 guild->HandleRemoveLowestRank(this);
214}

References GetPlayer(), GetPlayerInfo(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildDemoteOpcode()

void WorldSession::HandleGuildDemoteOpcode ( WorldPackets::Guild::GuildDemoteMember demote)
108{
109 LOG_DEBUG("guild", "CMSG_GUILD_DEMOTE [{}]: Target: {}", GetPlayerInfo(), demote.Demotee);
110
111 if (normalizePlayerName(demote.Demotee))
112 if (Guild* guild = GetPlayer()->GetGuild())
113 guild->HandleUpdateMemberRank(this, demote.Demotee, true);
114}
std::string Demotee
Definition GuildPackets.h:338

References WorldPackets::Guild::GuildDemoteMember::Demotee, GetPlayer(), GetPlayerInfo(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildDisbandOpcode()

void WorldSession::HandleGuildDisbandOpcode ( WorldPackets::Guild::GuildDelete packet)
125{
126 LOG_DEBUG("guild", "CMSG_GUILD_DISBAND [{}]", GetPlayerInfo());
127
128 if (Guild* guild = GetPlayer()->GetGuild())
129 guild->HandleDisband(this);
130}

References GetPlayer(), GetPlayerInfo(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildEventLogQueryOpcode()

void WorldSession::HandleGuildEventLogQueryOpcode ( WorldPackets::Guild::GuildEventLogQuery packet)
249{
250 LOG_DEBUG("guild", "MSG_GUILD_EVENT_LOG_QUERY [{}]", GetPlayerInfo());
251
252 if (Guild* guild = GetPlayer()->GetGuild())
253 guild->SendEventLog(this);
254}

References GetPlayer(), GetPlayerInfo(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildInfoOpcode()

void WorldSession::HandleGuildInfoOpcode ( WorldPackets::Guild::GuildGetInfo packet)
81{
82 LOG_DEBUG("guild", "CMSG_GUILD_INFO [{}]", GetPlayerInfo());
83
84 if (Guild* guild = GetPlayer()->GetGuild())
85 guild->SendInfo(this);
86}

References GetPlayer(), GetPlayerInfo(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildInviteOpcode()

void WorldSession::HandleGuildInviteOpcode ( WorldPackets::Guild::GuildInviteByName packet)
42{
43 LOG_DEBUG("guild", "CMSG_GUILD_INVITE [{}]: Invited: {}", GetPlayerInfo(), packet.Name);
44 if (normalizePlayerName(packet.Name))
45 if (Guild* guild = GetPlayer()->GetGuild())
46 guild->HandleInviteMember(this, packet.Name);
47}
String< 48 > Name
Definition GuildPackets.h:188

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, WorldPackets::Guild::GuildInviteByName::Name, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildLeaderOpcode()

void WorldSession::HandleGuildLeaderOpcode ( WorldPackets::Guild::GuildSetGuildMaster packet)
133{
134 LOG_DEBUG("guild", "CMSG_GUILD_LEADER [{}]: Target: {}", GetPlayerInfo(), packet.NewMasterName);
135
137 if (Guild* guild = GetPlayer()->GetGuild())
138 guild->HandleSetLeader(this, packet.NewMasterName);
139}
std::string NewMasterName
Definition GuildPackets.h:595

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, WorldPackets::Guild::GuildSetGuildMaster::NewMasterName, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildLeaveOpcode()

void WorldSession::HandleGuildLeaveOpcode ( WorldPackets::Guild::GuildLeave leave)
117{
118 LOG_DEBUG("guild", "CMSG_GUILD_LEAVE [{}]", GetPlayerInfo());
119
120 if (Guild* guild = GetPlayer()->GetGuild())
121 guild->HandleLeaveMember(this);
122}

References GetPlayer(), GetPlayerInfo(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildMOTDOpcode()

void WorldSession::HandleGuildMOTDOpcode ( WorldPackets::Guild::GuildUpdateMotdText packet)
142{
143 LOG_DEBUG("guild", "CMSG_GUILD_MOTD [{}]: MOTD: {}", GetPlayerInfo(), packet.MotdText);
144
145 if (Guild* guild = GetPlayer()->GetGuild())
146 guild->HandleSetMOTD(this, packet.MotdText);
147}
String< 128, Strings::NoHyperlinks > MotdText
Definition GuildPackets.h:150

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, and WorldPackets::Guild::GuildUpdateMotdText::MotdText.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildPermissions()

void WorldSession::HandleGuildPermissions ( WorldPackets::Guild::GuildPermissionsQuery packet)
265{
266 if (Guild* guild = GetPlayer()->GetGuild())
267 guild->SendPermissions(this);
268}

References GetPlayer().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildPromoteOpcode()

void WorldSession::HandleGuildPromoteOpcode ( WorldPackets::Guild::GuildPromoteMember promote)
99{
100 LOG_DEBUG("guild", "CMSG_GUILD_PROMOTE [{}]: Target: {}", GetPlayerInfo(), promote.Promotee);
101
102 if (normalizePlayerName(promote.Promotee))
103 if (Guild* guild = GetPlayer()->GetGuild())
104 guild->HandleUpdateMemberRank(this, promote.Promotee, false);
105}
std::string Promotee
Definition GuildPackets.h:348

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, normalizePlayerName(), and WorldPackets::Guild::GuildPromoteMember::Promotee.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildQueryOpcode()

void WorldSession::HandleGuildQueryOpcode ( WorldPackets::Guild::QueryGuildInfo query)
27{
28 LOG_DEBUG("guild", "CMSG_GUILD_QUERY [{}]: Guild: {}", GetPlayerInfo(), query.GuildId);
29 if (!query.GuildId)
30 return;
31
32 if (Guild* guild = sGuildMgr->GetGuildById(query.GuildId))
33 guild->HandleQuery(this);
34}
uint32 GuildId
Definition GuildPackets.h:38

References GetPlayerInfo(), WorldPackets::Guild::QueryGuildInfo::GuildId, LOG_DEBUG, and sGuildMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildRankOpcode()

void WorldSession::HandleGuildRankOpcode ( WorldPackets::Guild::GuildSetRankPermissions packet)
169{
170 Guild* guild = GetPlayer()->GetGuild();
171 if (!guild)
172 {
173 return;
174 }
175
176 std::array<GuildBankRightsAndSlots, GUILD_BANK_MAX_TABS> rightsAndSlots;
177
178 for (uint8 tabId = 0; tabId < GUILD_BANK_MAX_TABS; ++tabId)
179 {
180 // For some reason the client is sending - 1 for guildmaster tab withdraw item limit, that's ilegal for us because we expect unsigned int.
181 // Probably core handling for this should be changed.
182 if (packet.TabWithdrawItemLimit[tabId] <= 0)
183 {
185 }
186 rightsAndSlots[tabId] = GuildBankRightsAndSlots(tabId, uint8(packet.TabFlags[tabId]), packet.TabWithdrawItemLimit[tabId]);
187 }
188
189 LOG_DEBUG("guild", "CMSG_GUILD_RANK [{}]: Rank: {} ({})", GetPlayerInfo(), packet.RankName, packet.RankID);
190
191 // Same as the issue above but this time with rights.
192 if (packet.Flags <= 0)
193 {
195 }
196
197 guild->HandleSetRankInfo(this, packet.RankID, packet.RankName, packet.Flags, packet.WithdrawGoldLimit, rightsAndSlots);
198}
@ GUILD_WITHDRAW_SLOT_UNLIMITED
Definition Guild.h:49
@ GUILD_BANK_MAX_TABS
Definition Guild.h:42
@ GUILD_BANK_RIGHT_FULL
Definition Guild.h:192
Definition Guild.h:263
void HandleSetRankInfo(WorldSession *session, uint8 rankId, std::string_view name, uint32 rights, uint32 moneyPerDay, std::array< GuildBankRightsAndSlots, GUILD_BANK_MAX_TABS > const &rightsAndSlots)
Definition Guild.cpp:1383
uint32 RankID
Definition GuildPackets.h:276
uint32 WithdrawGoldLimit
Definition GuildPackets.h:277
String< 15, Strings::NoHyperlinks > RankName
Definition GuildPackets.h:281
uint32 TabWithdrawItemLimit[GUILD_BANK_MAX_TABS]
Definition GuildPackets.h:280
uint32 Flags
Definition GuildPackets.h:278
uint32 TabFlags[GUILD_BANK_MAX_TABS]
Definition GuildPackets.h:279

References WorldPackets::Guild::GuildSetRankPermissions::Flags, Player::GetGuild(), GetPlayer(), GetPlayerInfo(), GUILD_BANK_MAX_TABS, GUILD_BANK_RIGHT_FULL, GUILD_WITHDRAW_SLOT_UNLIMITED, Guild::HandleSetRankInfo(), LOG_DEBUG, WorldPackets::Guild::GuildSetRankPermissions::RankID, WorldPackets::Guild::GuildSetRankPermissions::RankName, WorldPackets::Guild::GuildSetRankPermissions::TabFlags, WorldPackets::Guild::GuildSetRankPermissions::TabWithdrawItemLimit, and WorldPackets::Guild::GuildSetRankPermissions::WithdrawGoldLimit.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildRemoveOpcode()

void WorldSession::HandleGuildRemoveOpcode ( WorldPackets::Guild::GuildOfficerRemoveMember packet)
50{
51 LOG_DEBUG("guild", "CMSG_GUILD_REMOVE [{}]: Target: {}", GetPlayerInfo(), packet.Removee);
52
53 if (normalizePlayerName(packet.Removee))
54 if (Guild* guild = GetPlayer()->GetGuild())
55 guild->HandleRemoveMember(this, packet.Removee);
56}
std::string Removee
Definition GuildPackets.h:358

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, normalizePlayerName(), and WorldPackets::Guild::GuildOfficerRemoveMember::Removee.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildRosterOpcode()

void WorldSession::HandleGuildRosterOpcode ( WorldPackets::Guild::GuildGetRoster packet)
89{
90 LOG_DEBUG("guild", "CMSG_GUILD_ROSTER [{}]", GetPlayerInfo());
91
92 if (Guild* guild = GetPlayer()->GetGuild())
93 guild->HandleRoster(this);
94 else
96}
@ GUILD_COMMAND_ROSTER
Definition Guild.h:102

References ERR_GUILD_PLAYER_NOT_IN_GUILD, GetPlayer(), GetPlayerInfo(), GUILD_COMMAND_ROSTER, LOG_DEBUG, and Guild::SendCommandResult().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildSetOfficerNoteOpcode()

void WorldSession::HandleGuildSetOfficerNoteOpcode ( WorldPackets::Guild::GuildSetMemberNote packet)
159{
160 LOG_DEBUG("guild", "CMSG_GUILD_SET_OFFICER_NOTE [{}]: Target: {}, Note: {}",
161 GetPlayerInfo(), packet.NoteeName, packet.Note);
162
163 if (normalizePlayerName(packet.NoteeName))
164 if (Guild* guild = GetPlayer()->GetGuild())
165 guild->HandleSetMemberNote(this, packet.NoteeName, packet.Note, false);
166}
String< 31, Strings::NoHyperlinks > Note
Definition GuildPackets.h:320
std::string NoteeName
Definition GuildPackets.h:319

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, normalizePlayerName(), WorldPackets::Guild::GuildSetMemberNote::Note, and WorldPackets::Guild::GuildSetMemberNote::NoteeName.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildSetPublicNoteOpcode()

void WorldSession::HandleGuildSetPublicNoteOpcode ( WorldPackets::Guild::GuildSetMemberNote packet)
150{
151 LOG_DEBUG("guild", "CMSG_GUILD_SET_PUBLIC_NOTE [{}]: Target: {}, Note: {}", GetPlayerInfo(), packet.NoteeName, packet.Note);
152
153 if (normalizePlayerName(packet.NoteeName))
154 if (Guild* guild = GetPlayer()->GetGuild())
155 guild->HandleSetMemberNote(this, packet.NoteeName, packet.Note, true);
156}

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, normalizePlayerName(), WorldPackets::Guild::GuildSetMemberNote::Note, and WorldPackets::Guild::GuildSetMemberNote::NoteeName.

Referenced by OpcodeTable::Initialize().

◆ HandleHearthAndResurrect()

void WorldSession::HandleHearthAndResurrect ( WorldPacket recvData)
1674{
1675 if (_player->IsInFlight())
1676 return;
1677
1678 if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
1679 {
1680 bf->PlayerAskToLeave(_player);
1681 return;
1682 }
1683
1684 AreaTableEntry const* atEntry = sAreaTableStore.LookupEntry(_player->GetAreaId());
1685 if (!atEntry || !(atEntry->flags & AREA_FLAG_WINTERGRASP_2))
1686 return;
1687
1689 _player->ResurrectPlayer(1.0f);
1692}
@ AREA_FLAG_WINTERGRASP_2
Definition DBCEnums.h:261
float m_homebindZ
Definition Player.h:2388
uint32 m_homebindMapId
Definition Player.h:2384
float m_homebindY
Definition Player.h:2387
void BuildPlayerRepop()
Definition Player.cpp:4411
float m_homebindX
Definition Player.h:2386
uint32 GetAreaId() const
Definition Object.cpp:3064
uint32 flags
Definition DBCStructure.h:524
float GetOrientation() const
Definition Position.h:124

References _player, AREA_FLAG_WINTERGRASP_2, Player::BuildPlayerRepop(), AreaTableEntry::flags, WorldObject::GetAreaId(), Position::GetOrientation(), WorldObject::GetZoneId(), Unit::IsInFlight(), Player::m_homebindMapId, Player::m_homebindX, Player::m_homebindY, Player::m_homebindZ, Player::ResurrectPlayer(), sAreaTableStore, sBattlefieldMgr, Player::SpawnCorpseBones(), and Player::TeleportTo().

Referenced by OpcodeTable::Initialize().

◆ HandleIgnoreTradeOpcode()

void WorldSession::HandleIgnoreTradeOpcode ( WorldPacket recvPacket)
72{
74}
@ TRADE_STATUS_IGNORE_YOU
Definition SharedDefines.h:3830

References _player, TRADE_STATUS_IGNORE_YOU, and Player::TradeCancel().

Referenced by OpcodeTable::Initialize().

◆ HandleInitiateTradeOpcode()

void WorldSession::HandleInitiateTradeOpcode ( WorldPacket recvPacket)
543{
544 ObjectGuid ID;
545 recvPacket >> ID;
546
547 if (GetPlayer()->m_trade)
548 return;
549
550 if (!GetPlayer()->IsAlive())
551 {
553 return;
554 }
555
556 if (GetPlayer()->HasUnitState(UNIT_STATE_STUNNED))
557 {
559 return;
560 }
561
562 if (isLogingOut())
563 {
565 return;
566 }
567
568 if (GetPlayer()->IsInFlight())
569 {
571 return;
572 }
573
574 if (GetPlayer()->GetLevel() < sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ))
575 {
577 return;
578 }
579
580 if (GetPlayer()->IsSpectator())
581 return;
582
584
585 if (!pOther)
586 {
588 return;
589 }
590
591 if (pOther == GetPlayer() || pOther->m_trade)
592 {
594 return;
595 }
596
597 if (!pOther->IsAlive())
598 {
600 return;
601 }
602
603 if (pOther->IsInFlight())
604 {
606 return;
607 }
608
609 if (pOther->HasUnitState(UNIT_STATE_STUNNED))
610 {
612 return;
613 }
614
615 if (pOther->GetSession()->isLogingOut())
616 {
618 return;
619 }
620
621 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_TRADE) && pOther->GetTeamId() != _player->GetTeamId())
622 {
624 return;
625 }
626
627 if (!pOther->IsWithinDistInMap(_player, 10.0f, false))
628 {
630 return;
631 }
632
633 if (pOther->GetLevel() < sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ))
634 {
636 return;
637 }
638
639 if (!sScriptMgr->OnPlayerCanInitTrade(_player, pOther))
640 return;
641
642 // OK start trade
643 _player->m_trade = new TradeData(_player, pOther);
644 pOther->m_trade = new TradeData(pOther, _player);
645
648 data << _player->GetGUID();
649 pOther->SendDirectMessage(&data);
650}
@ LANG_TRADE_OTHER_REQ
Definition Language.h:1172
@ LANG_TRADE_REQ
Definition Language.h:1171
@ TRADE_STATUS_YOU_STUNNED
Definition SharedDefines.h:3831
@ TRADE_STATUS_YOU_DEAD
Definition SharedDefines.h:3833
@ TRADE_STATUS_YOU_LOGOUT
Definition SharedDefines.h:3835
@ TRADE_STATUS_TARGET_DEAD
Definition SharedDefines.h:3834
@ TRADE_STATUS_NO_TARGET
Definition SharedDefines.h:3822
@ TRADE_STATUS_BEGIN_TRADE
Definition SharedDefines.h:3817
@ TRADE_STATUS_TARGET_LOGOUT
Definition SharedDefines.h:3836
@ TRADE_STATUS_TARGET_STUNNED
Definition SharedDefines.h:3832
@ TRADE_STATUS_TARGET_TO_FAR
Definition SharedDefines.h:3826
@ TRADE_STATUS_WRONG_FACTION
Definition SharedDefines.h:3827
@ UNIT_STATE_STUNNED
Definition UnitDefines.h:173
@ CONFIG_ALLOW_TWO_SIDE_TRADE
Definition WorldConfig.h:41
@ CONFIG_TRADE_LEVEL_REQ
Definition WorldConfig.h:249
bool isLogingOut() const
Is the user engaged in a log out process?
Definition WorldSession.h:447
@ SMSG_TRADE_STATUS
Definition Opcodes.h:318

References _player, CONFIG_ALLOW_TWO_SIDE_TRADE, CONFIG_TRADE_LEVEL_REQ, ObjectAccessor::FindPlayer(), Object::GetGUID(), Unit::GetLevel(), GetPlayer(), Player::GetSession(), Player::GetTeamId(), Unit::HasUnitState(), Unit::IsAlive(), Unit::IsInFlight(), isLogingOut(), WorldObject::IsWithinDistInMap(), LANG_TRADE_OTHER_REQ, LANG_TRADE_REQ, Player::m_trade, Player::SendDirectMessage(), ChatHandler::SendNotification(), SendTradeStatus(), SMSG_TRADE_STATUS, sScriptMgr, sWorld, TRADE_STATUS_BEGIN_TRADE, TRADE_STATUS_BUSY, TRADE_STATUS_NO_TARGET, TRADE_STATUS_TARGET_DEAD, TRADE_STATUS_TARGET_LOGOUT, TRADE_STATUS_TARGET_STUNNED, TRADE_STATUS_TARGET_TO_FAR, TRADE_STATUS_WRONG_FACTION, TRADE_STATUS_YOU_DEAD, TRADE_STATUS_YOU_LOGOUT, TRADE_STATUS_YOU_STUNNED, and UNIT_STATE_STUNNED.

Referenced by OpcodeTable::Initialize().

◆ HandleInspectArenaTeamsOpcode()

void WorldSession::HandleInspectArenaTeamsOpcode ( WorldPacket recvData)
30{
31 LOG_DEBUG("network", "MSG_INSPECT_ARENA_TEAMS");
32
33 ObjectGuid guid;
34 recvData >> guid;
35 LOG_DEBUG("network", "Inspect Arena stats ({})", guid.ToString());
36
37 Player* player = ObjectAccessor::FindPlayer(guid);
38 if (!player)
39 {
40 return;
41 }
42
43 if (!GetPlayer()->IsWithinDistInMap(player, INSPECT_DISTANCE, false))
44 {
45 return;
46 }
47
48 if (GetPlayer()->IsValidAttackTarget(player))
49 {
50 return;
51 }
52
53 for (uint8 i = 0; i < MAX_ARENA_SLOT; ++i)
54 {
55 if (uint32 a_id = player->GetArenaTeamId(i))
56 {
57 if (ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(a_id))
58 arenaTeam->Inspect(this, player->GetGUID());
59 }
60 }
61}
#define MAX_ARENA_SLOT
Definition ArenaTeam.h:134
#define INSPECT_DISTANCE
Definition ObjectDefines.h:27

References ObjectAccessor::FindPlayer(), Player::GetArenaTeamId(), Object::GetGUID(), GetPlayer(), INSPECT_DISTANCE, LOG_DEBUG, MAX_ARENA_SLOT, sArenaTeamMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleInspectHonorStatsOpcode()

void WorldSession::HandleInspectHonorStatsOpcode ( WorldPacket recvPacket)
1021{
1022 ObjectGuid guid;
1023 recv_data >> guid;
1024
1025 Player* player = ObjectAccessor::GetPlayer(*_player, guid);
1026 if (!player)
1027 {
1028 LOG_DEBUG("network", "MSG_INSPECT_HONOR_STATS: No player found from {}", guid.ToString());
1029 return;
1030 }
1031
1032 if (!GetPlayer()->IsWithinDistInMap(player, INSPECT_DISTANCE, false))
1033 {
1034 return;
1035 }
1036
1037 if (GetPlayer()->IsValidAttackTarget(player))
1038 {
1039 return;
1040 }
1041
1042 WorldPacket data(MSG_INSPECT_HONOR_STATS, 8 + 1 + 4 * 4);
1043 data << player->GetGUID();
1044 data << uint8(player->GetHonorPoints());
1045 data << uint32(player->GetUInt32Value(PLAYER_FIELD_KILLS));
1049 SendPacket(&data);
1050}
@ PLAYER_FIELD_TODAY_CONTRIBUTION
Definition UpdateFields.h:375
@ PLAYER_FIELD_KILLS
Definition UpdateFields.h:374
@ PLAYER_FIELD_YESTERDAY_CONTRIBUTION
Definition UpdateFields.h:376
@ PLAYER_FIELD_LIFETIME_HONORABLE_KILLS
Definition UpdateFields.h:377
uint32 GetHonorPoints() const
Definition Player.h:2150
@ MSG_INSPECT_HONOR_STATS
Definition Opcodes.h:756

References _player, Object::GetGUID(), Player::GetHonorPoints(), GetPlayer(), ObjectAccessor::GetPlayer(), Object::GetUInt32Value(), INSPECT_DISTANCE, LOG_DEBUG, MSG_INSPECT_HONOR_STATS, PLAYER_FIELD_KILLS, PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, PLAYER_FIELD_TODAY_CONTRIBUTION, PLAYER_FIELD_YESTERDAY_CONTRIBUTION, SendPacket(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleInspectOpcode()

void WorldSession::HandleInspectOpcode ( WorldPacket recvPacket)
979{
980 ObjectGuid guid;
981 recv_data >> guid;
982
983 Player* player = ObjectAccessor::GetPlayer(*_player, guid);
984 if (!player)
985 {
986 LOG_DEBUG("network", "CMSG_INSPECT: No player found from {}", guid.ToString());
987 return;
988 }
989
990 if (!GetPlayer()->IsWithinDistInMap(player, INSPECT_DISTANCE, false))
991 {
992 return;
993 }
994
995 if (GetPlayer()->IsValidAttackTarget(player))
996 {
997 return;
998 }
999
1000 uint32 talent_points = 0x47;
1001 uint32 guid_size = player->GetPackGUID().size();
1002 WorldPacket data(SMSG_INSPECT_TALENT, guid_size + 4 + talent_points);
1003 data << player->GetPackGUID();
1004
1005 if (sWorld->getBoolConfig(CONFIG_TALENTS_INSPECTING) || _player->IsGameMaster())
1006 {
1007 player->BuildPlayerTalentsInfoData(&data);
1008 }
1009 else
1010 {
1011 data << uint32(0); // unspentTalentPoints
1012 data << uint8(0); // talentGroupCount
1013 data << uint8(0); // talentGroupIndex
1014 }
1015
1016 player->BuildEnchantmentsInfoData(&data);
1017 SendPacket(&data);
1018}
@ CONFIG_TALENTS_INSPECTING
Definition WorldConfig.h:59
std::size_t size() const
Definition ObjectGuid.h:274
void BuildEnchantmentsInfoData(WorldPacket *data)
Definition Player.cpp:14543
void BuildPlayerTalentsInfoData(WorldPacket *data)
Definition Player.cpp:14426
@ SMSG_INSPECT_TALENT
Definition Opcodes.h:1042

References _player, Player::BuildEnchantmentsInfoData(), Player::BuildPlayerTalentsInfoData(), CONFIG_TALENTS_INSPECTING, Object::GetPackGUID(), GetPlayer(), ObjectAccessor::GetPlayer(), INSPECT_DISTANCE, Player::IsGameMaster(), LOG_DEBUG, SendPacket(), PackedGuid::size(), SMSG_INSPECT_TALENT, sWorld, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleInstanceLockResponse()

void WorldSession::HandleInstanceLockResponse ( WorldPacket recvPacket)
1695{
1696 uint8 accept;
1697 recvPacket >> accept;
1698
1700 {
1701 LOG_DEBUG("network.opcode", "InstanceLockResponse: Player {} ({}) tried to bind himself/teleport to graveyard without a pending bind!",
1703 return;
1704 }
1705
1706 if (accept)
1708 else
1710
1711 _player->SetPendingBind(0, 0);
1712}
bool IsLfgRandomInstance() const
Definition Group.h:316
uint32 GetPendingBind() const
Definition Player.h:2454
bool HasPendingBind() const
Definition Player.h:2453
void RepopAtGraveyard()
Definition Player.cpp:4909
void SetPendingBind(uint32 instanceId, uint32 bindTimer)
Definition Player.h:2452
void BindToInstance()
Definition PlayerStorage.cpp:6512

References _player, Player::BindToInstance(), Player::GetGroup(), Object::GetGUID(), WorldObject::GetInstanceId(), WorldObject::GetName(), Player::GetPendingBind(), Player::HasPendingBind(), Group::isLFGGroup(), Group::IsLfgRandomInstance(), LOG_DEBUG, Player::RepopAtGraveyard(), Player::SetPendingBind(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleItemNameQueryOpcode()

void WorldSession::HandleItemNameQueryOpcode ( WorldPacket recvPacket)
1057{
1058 uint32 itemid;
1059 recvData >> itemid;
1060 recvData.read_skip<uint64>(); // guid
1061
1062 LOG_DEBUG("network", "WORLD: CMSG_ITEM_NAME_QUERY {}", itemid);
1063 ItemSetNameEntry const* pName = sObjectMgr->GetItemSetNameEntry(itemid);
1064 if (pName)
1065 {
1066 std::string Name = pName->name;
1068 if (loc_idx >= 0)
1069 if (ItemSetNameLocale const* isnl = sObjectMgr->GetItemSetNameLocale(itemid))
1070 ObjectMgr::GetLocaleString(isnl->Name, loc_idx, Name);
1071
1072 WorldPacket data(SMSG_ITEM_NAME_QUERY_RESPONSE, (4 + Name.size() + 1 + 4));
1073 data << uint32(itemid);
1074 data << Name;
1075 data << uint32(pName->InventoryType);
1076 SendPacket(&data);
1077 }
1078}
@ SMSG_ITEM_NAME_QUERY_RESPONSE
Definition Opcodes.h:739
Definition ItemTemplate.h:840
uint32 InventoryType
Definition ItemTemplate.h:842
std::string name
Definition ItemTemplate.h:841
Definition ItemTemplate.h:846

References ObjectMgr::GetLocaleString(), GetSessionDbLocaleIndex(), ItemSetNameEntry::InventoryType, LOG_DEBUG, ItemSetNameEntry::name, ByteBuffer::read_skip(), SendPacket(), SMSG_ITEM_NAME_QUERY_RESPONSE, and sObjectMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleItemQuerySingleOpcode()

void WorldSession::HandleItemQuerySingleOpcode ( WorldPacket recvPacket)
390{
391 //LOG_DEBUG("network.opcode", "WORLD: CMSG_ITEM_QUERY_SINGLE");
392 uint32 item;
393 recvData >> item;
394
395 LOG_DEBUG("network.opcode", "STORAGE: Item Query = {}", item);
396
397 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item);
398 if (pProto)
399 {
400 std::string Name = pProto->Name1;
401 std::string Description = pProto->Description;
402
403 int loc_idx = GetSessionDbLocaleIndex();
404 if (loc_idx >= 0)
405 {
406 if (ItemLocale const* il = sObjectMgr->GetItemLocale(pProto->ItemId))
407 {
408 ObjectMgr::GetLocaleString(il->Name, loc_idx, Name);
409 ObjectMgr::GetLocaleString(il->Description, loc_idx, Description);
410 }
411 }
412 // guess size
414 queryData << pProto->ItemId;
415 queryData << pProto->Class;
416 queryData << pProto->SubClass;
417 queryData << pProto->SoundOverrideSubclass;
418 queryData << Name;
419 queryData << uint8(0x00); //pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name...
420 queryData << uint8(0x00); //pProto->Name3; // blizz not send name there, just uint8(0x00);
421 queryData << uint8(0x00); //pProto->Name4; // blizz not send name there, just uint8(0x00);
422 queryData << pProto->DisplayInfoID;
423 queryData << pProto->Quality;
424 queryData << pProto->Flags;
425 queryData << pProto->Flags2;
426 queryData << pProto->BuyPrice;
427 queryData << pProto->SellPrice;
428 queryData << pProto->InventoryType;
429 queryData << pProto->AllowableClass;
430 queryData << pProto->AllowableRace;
431 queryData << pProto->ItemLevel;
432 queryData << pProto->RequiredLevel;
433 queryData << pProto->RequiredSkill;
434 queryData << pProto->RequiredSkillRank;
435 queryData << pProto->RequiredSpell;
436 queryData << pProto->RequiredHonorRank;
437 queryData << pProto->RequiredCityRank;
438 queryData << pProto->RequiredReputationFaction;
439 queryData << pProto->RequiredReputationRank;
440 queryData << int32(pProto->MaxCount);
441 queryData << int32(pProto->Stackable);
442 queryData << pProto->ContainerSlots;
443 queryData << pProto->StatsCount; // item stats count
444 for (uint32 i = 0; i < pProto->StatsCount; ++i)
445 {
446 queryData << pProto->ItemStat[i].ItemStatType;
447 queryData << pProto->ItemStat[i].ItemStatValue;
448 }
449 queryData << pProto->ScalingStatDistribution; // scaling stats distribution
450 queryData << pProto->ScalingStatValue; // some kind of flags used to determine stat values column
451 for (int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
452 {
453 queryData << pProto->Damage[i].DamageMin;
454 queryData << pProto->Damage[i].DamageMax;
455 queryData << pProto->Damage[i].DamageType;
456 }
457
458 // resistances (7)
459 queryData << pProto->Armor;
460 queryData << pProto->HolyRes;
461 queryData << pProto->FireRes;
462 queryData << pProto->NatureRes;
463 queryData << pProto->FrostRes;
464 queryData << pProto->ShadowRes;
465 queryData << pProto->ArcaneRes;
466
467 queryData << pProto->Delay;
468 queryData << pProto->AmmoType;
469 queryData << pProto->RangedModRange;
470
471 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
472 {
473 // send DBC data for cooldowns in same way as it used in Spell::SendSpellCooldown
474 // use `item_template` or if not set then only use spell cooldowns
475 SpellInfo const* spell = sSpellMgr->GetSpellInfo(pProto->Spells[s].SpellId);
476 if (spell)
477 {
478 bool db_data = pProto->Spells[s].SpellCooldown >= 0 || pProto->Spells[s].SpellCategoryCooldown >= 0;
479
480 queryData << pProto->Spells[s].SpellId;
481 queryData << pProto->Spells[s].SpellTrigger;
482 queryData << int32(pProto->Spells[s].SpellCharges);
483
484 if (db_data)
485 {
486 queryData << uint32(pProto->Spells[s].SpellCooldown);
487 queryData << uint32(pProto->Spells[s].SpellCategory);
488 queryData << uint32(pProto->Spells[s].SpellCategoryCooldown);
489 }
490 else
491 {
492 queryData << uint32(spell->RecoveryTime);
493 queryData << uint32(spell->GetCategory());
494 queryData << uint32(spell->CategoryRecoveryTime);
495 }
496 }
497 else
498 {
499 queryData << uint32(0);
500 queryData << uint32(0);
501 queryData << uint32(0);
502 queryData << uint32(-1);
503 queryData << uint32(0);
504 queryData << uint32(-1);
505 }
506 }
507 queryData << pProto->Bonding;
508 queryData << Description;
509 queryData << pProto->PageText;
510 queryData << pProto->LanguageID;
511 queryData << pProto->PageMaterial;
512 queryData << pProto->StartQuest;
513 queryData << pProto->LockID;
514 queryData << int32(pProto->Material);
515 queryData << pProto->Sheath;
516 queryData << pProto->RandomProperty;
517 queryData << pProto->RandomSuffix;
518 queryData << pProto->Block;
519 queryData << pProto->ItemSet;
520 queryData << pProto->MaxDurability;
521 queryData << pProto->Area;
522 queryData << pProto->Map; // Added in 1.12.x & 2.0.1 client branch
523 queryData << pProto->BagFamily;
524 queryData << pProto->TotemCategory;
525 for (int s = 0; s < MAX_ITEM_PROTO_SOCKETS; ++s)
526 {
527 queryData << pProto->Socket[s].Color;
528 queryData << pProto->Socket[s].Content;
529 }
530 queryData << pProto->socketBonus;
531 queryData << pProto->GemProperties;
532 queryData << pProto->RequiredDisenchantSkill;
533 queryData << pProto->ArmorDamageModifier;
534 queryData << pProto->Duration; // added in 2.4.2.8209, duration (seconds)
535 queryData << pProto->ItemLimitCategory; // WotLK, ItemLimitCategory
536 queryData << pProto->HolidayId; // Holiday.dbc?
537 SendPacket(&queryData);
538 }
539 else
540 {
541 LOG_DEBUG("network", "WORLD: CMSG_ITEM_QUERY_SINGLE - NO item INFO! (ENTRY: {})", item);
543 queryData << uint32(item | 0x80000000);
544 SendPacket(&queryData);
545 }
546}
#define MAX_ITEM_PROTO_SOCKETS
Definition ItemTemplate.h:614
#define MAX_ITEM_PROTO_DAMAGES
Definition ItemTemplate.h:613
#define MAX_ITEM_PROTO_SPELLS
Definition ItemTemplate.h:615
uint32 RecoveryTime
Definition SpellInfo.h:348
uint32 CategoryRecoveryTime
Definition SpellInfo.h:349
@ SMSG_ITEM_QUERY_SINGLE_RESPONSE
Definition Opcodes.h:118
Definition ItemTemplate.h:834
int32 RandomProperty
Definition ItemTemplate.h:672
int32 FrostRes
Definition ItemTemplate.h:656
ItemFlags2 Flags2
Definition ItemTemplate.h:628
uint32 Map
Definition ItemTemplate.h:678
uint32 Block
Definition ItemTemplate.h:674
uint32 Quality
Definition ItemTemplate.h:626
uint32 ItemLevel
Definition ItemTemplate.h:635
int32 ArcaneRes
Definition ItemTemplate.h:658
uint32 RequiredCityRank
Definition ItemTemplate.h:641
uint32 RequiredSkill
Definition ItemTemplate.h:637
int32 ShadowRes
Definition ItemTemplate.h:657
uint32 RequiredSpell
Definition ItemTemplate.h:639
int32 MaxCount
Definition ItemTemplate.h:644
uint32 ScalingStatValue
Definition ItemTemplate.h:650
std::string Description
Definition ItemTemplate.h:664
uint32 AllowableClass
Definition ItemTemplate.h:633
uint32 RequiredSkillRank
Definition ItemTemplate.h:638
_Damage Damage[MAX_ITEM_PROTO_DAMAGES]
Definition ItemTemplate.h:651
uint32 RequiredHonorRank
Definition ItemTemplate.h:640
int32 HolyRes
Definition ItemTemplate.h:653
float RangedModRange
Definition ItemTemplate.h:661
uint32 Sheath
Definition ItemTemplate.h:671
float ArmorDamageModifier
Definition ItemTemplate.h:685
int32 Material
Definition ItemTemplate.h:670
_Spell Spells[MAX_ITEM_PROTO_SPELLS]
Definition ItemTemplate.h:662
uint32 Area
Definition ItemTemplate.h:677
int32 BuyPrice
Definition ItemTemplate.h:630
uint32 socketBonus
Definition ItemTemplate.h:682
uint32 RequiredDisenchantSkill
Definition ItemTemplate.h:684
uint32 TotemCategory
Definition ItemTemplate.h:680
uint32 PageMaterial
Definition ItemTemplate.h:667
uint32 RequiredLevel
Definition ItemTemplate.h:636
uint32 LockID
Definition ItemTemplate.h:669
uint32 ItemSet
Definition ItemTemplate.h:675
uint32 HolidayId
Definition ItemTemplate.h:688
uint32 GemProperties
Definition ItemTemplate.h:683
uint32 RequiredReputationRank
Definition ItemTemplate.h:643
uint32 ContainerSlots
Definition ItemTemplate.h:646
uint32 DisplayInfoID
Definition ItemTemplate.h:625
uint32 AllowableRace
Definition ItemTemplate.h:634
uint32 RequiredReputationFaction
Definition ItemTemplate.h:642
uint32 Class
Definition ItemTemplate.h:621
uint32 ItemLimitCategory
Definition ItemTemplate.h:687
uint32 PageText
Definition ItemTemplate.h:665
uint32 ScalingStatDistribution
Definition ItemTemplate.h:649
int32 NatureRes
Definition ItemTemplate.h:655
_ItemStat ItemStat[MAX_ITEM_PROTO_STATS]
Definition ItemTemplate.h:648
uint32 MaxDurability
Definition ItemTemplate.h:676
uint32 BagFamily
Definition ItemTemplate.h:679
uint32 InventoryType
Definition ItemTemplate.h:632
uint32 LanguageID
Definition ItemTemplate.h:666
uint32 AmmoType
Definition ItemTemplate.h:660
uint32 Delay
Definition ItemTemplate.h:659
int32 RandomSuffix
Definition ItemTemplate.h:673
uint32 Duration
Definition ItemTemplate.h:686
uint32 SubClass
Definition ItemTemplate.h:622
uint32 Armor
Definition ItemTemplate.h:652
int32 Stackable
Definition ItemTemplate.h:645
uint32 StartQuest
Definition ItemTemplate.h:668
int32 SoundOverrideSubclass
Definition ItemTemplate.h:623
_Socket Socket[MAX_ITEM_PROTO_SOCKETS]
Definition ItemTemplate.h:681
uint32 StatsCount
Definition ItemTemplate.h:647
int32 FireRes
Definition ItemTemplate.h:654
uint32 Bonding
Definition ItemTemplate.h:663
uint32 SellPrice
Definition ItemTemplate.h:631
float DamageMin
Definition ItemTemplate.h:579
uint32 DamageType
Definition ItemTemplate.h:581
float DamageMax
Definition ItemTemplate.h:580
int32 ItemStatValue
Definition ItemTemplate.h:587
uint32 ItemStatType
Definition ItemTemplate.h:586
uint32 Content
Definition ItemTemplate.h:603
uint32 Color
Definition ItemTemplate.h:602
int32 SpellCharges
Definition ItemTemplate.h:593
uint32 SpellTrigger
Definition ItemTemplate.h:592
int32 SpellCategoryCooldown
Definition ItemTemplate.h:597
int32 SpellCooldown
Definition ItemTemplate.h:595
uint32 SpellCategory
Definition ItemTemplate.h:596
int32 SpellId
Definition ItemTemplate.h:591

References ItemTemplate::AllowableClass, ItemTemplate::AllowableRace, ItemTemplate::AmmoType, ItemTemplate::ArcaneRes, ItemTemplate::Area, ItemTemplate::Armor, ItemTemplate::ArmorDamageModifier, ItemTemplate::BagFamily, ItemTemplate::Block, ItemTemplate::Bonding, ItemTemplate::BuyPrice, SpellInfo::CategoryRecoveryTime, ItemTemplate::Class, _Socket::Color, ItemTemplate::ContainerSlots, _Socket::Content, ItemTemplate::Damage, _Damage::DamageMax, _Damage::DamageMin, _Damage::DamageType, ItemTemplate::Delay, ItemTemplate::Description, ItemTemplate::DisplayInfoID, ItemTemplate::Duration, ItemTemplate::FireRes, ItemTemplate::Flags, ItemTemplate::Flags2, ItemTemplate::FrostRes, ItemTemplate::GemProperties, SpellInfo::GetCategory(), ObjectMgr::GetLocaleString(), GetSessionDbLocaleIndex(), ItemTemplate::HolidayId, ItemTemplate::HolyRes, ItemTemplate::InventoryType, ItemTemplate::ItemId, ItemTemplate::ItemLevel, ItemTemplate::ItemLimitCategory, ItemTemplate::ItemSet, ItemTemplate::ItemStat, _ItemStat::ItemStatType, _ItemStat::ItemStatValue, ItemTemplate::LanguageID, ItemTemplate::LockID, LOG_DEBUG, ItemTemplate::Map, ItemTemplate::Material, MAX_ITEM_PROTO_DAMAGES, MAX_ITEM_PROTO_SOCKETS, MAX_ITEM_PROTO_SPELLS, ItemTemplate::MaxCount, ItemTemplate::MaxDurability, ItemTemplate::Name1, ItemTemplate::NatureRes, ItemTemplate::PageMaterial, ItemTemplate::PageText, ItemTemplate::Quality, ItemTemplate::RandomProperty, ItemTemplate::RandomSuffix, ItemTemplate::RangedModRange, SpellInfo::RecoveryTime, ItemTemplate::RequiredCityRank, ItemTemplate::RequiredDisenchantSkill, ItemTemplate::RequiredHonorRank, ItemTemplate::RequiredLevel, ItemTemplate::RequiredReputationFaction, ItemTemplate::RequiredReputationRank, ItemTemplate::RequiredSkill, ItemTemplate::RequiredSkillRank, ItemTemplate::RequiredSpell, ItemTemplate::ScalingStatDistribution, ItemTemplate::ScalingStatValue, ItemTemplate::SellPrice, SendPacket(), ItemTemplate::ShadowRes, ItemTemplate::Sheath, SMSG_ITEM_QUERY_SINGLE_RESPONSE, sObjectMgr, ItemTemplate::Socket, ItemTemplate::socketBonus, ItemTemplate::SoundOverrideSubclass, _Spell::SpellCategory, _Spell::SpellCategoryCooldown, _Spell::SpellCharges, _Spell::SpellCooldown, _Spell::SpellId, ItemTemplate::Spells, _Spell::SpellTrigger, sSpellMgr, ItemTemplate::Stackable, ItemTemplate::StartQuest, ItemTemplate::StatsCount, ItemTemplate::SubClass, and ItemTemplate::TotemCategory.

Referenced by OpcodeTable::Initialize().

◆ HandleItemRefund()

void WorldSession::HandleItemRefund ( WorldPackets::Item::ItemRefund packet)
1434{
1435 LOG_DEBUG("network", "WORLD: CMSG_ITEM_REFUND");
1436
1437 Item* item = _player->GetItemByGuid(packet.ItemGuid);
1438 if (!item)
1439 {
1440 LOG_DEBUG("network", "Item refund: item not found!");
1441 return;
1442 }
1443
1444 // Don't try to refund item currently being disenchanted
1445 if (_player->GetLootGUID() == packet.ItemGuid)
1446 return;
1447
1448 GetPlayer()->RefundItem(item);
1449}
void RefundItem(Item *item)
Definition Player.cpp:15700
ObjectGuid ItemGuid
Definition ItemPackets.h:267

References _player, Player::GetItemByGuid(), Player::GetLootGUID(), GetPlayer(), WorldPackets::Item::ItemRefund::ItemGuid, LOG_DEBUG, and Player::RefundItem().

Referenced by OpcodeTable::Initialize().

◆ HandleItemRefundInfoRequest()

void WorldSession::HandleItemRefundInfoRequest ( WorldPackets::Item::ItemRefundInfo packet)
1420{
1421 LOG_DEBUG("network", "WORLD: CMSG_ITEM_REFUND_INFO");
1422
1423 Item* item = _player->GetItemByGuid(packet.ItemGuid);
1424 if (!item)
1425 {
1426 LOG_DEBUG("network", "Item refund: item not found!");
1427 return;
1428 }
1429
1430 GetPlayer()->SendRefundInfo(item);
1431}
void SendRefundInfo(Item *item)
Definition Player.cpp:15629
ObjectGuid ItemGuid
Definition ItemPackets.h:257

References _player, Player::GetItemByGuid(), GetPlayer(), WorldPackets::Item::ItemRefundInfo::ItemGuid, LOG_DEBUG, and Player::SendRefundInfo().

Referenced by OpcodeTable::Initialize().

◆ HandleItemTextQuery()

void WorldSession::HandleItemTextQuery ( WorldPacket recvData)

Handles the packet sent by the client when requesting information about item text.

This function is called when player clicks on item which has some flag set

1457{
1458 ObjectGuid itemGuid;
1459 recvData >> itemGuid;
1460
1461 LOG_DEBUG("network", "CMSG_ITEM_TEXT_QUERY item: {}", itemGuid.ToString());
1462
1463 WorldPacket data(SMSG_ITEM_TEXT_QUERY_RESPONSE, 50); // guess size
1464
1465 if (Item* item = _player->GetItemByGuid(itemGuid))
1466 {
1467 data << uint8(0); // has text
1468 data << itemGuid; // item guid
1469 data << item->GetText();
1470 }
1471 else
1472 {
1473 data << uint8(1); // no text
1474 }
1475
1476 SendPacket(&data);
1477}
@ SMSG_ITEM_TEXT_QUERY_RESPONSE
Definition Opcodes.h:610

References _player, Player::GetItemByGuid(), LOG_DEBUG, SendPacket(), SMSG_ITEM_TEXT_QUERY_RESPONSE, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleJoinChannel()

void WorldSession::HandleJoinChannel ( WorldPacket recvPacket)
24{
25 uint32 channelId;
26 uint8 unknown1, unknown2;
27 std::string channelName, password;
28
29 recvPacket >> channelId >> unknown1 >> unknown2 >> channelName >> password;
30
31 LOG_DEBUG("chat.system", "CMSG_JOIN_CHANNEL {} Channel: {}, unk1: {}, unk2: {}, channel: {}, password: {}", GetPlayerInfo(), channelId, unknown1, unknown2, channelName, password);
32 if (channelId)
33 {
34 ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(channelId);
35 if (!channel)
36 return;
37
38 AreaTableEntry const* zone = sAreaTableStore.LookupEntry(GetPlayer()->GetZoneId());
39 if (!zone || !GetPlayer()->CanJoinConstantChannelInZone(channel, zone))
40 return;
41 }
42
43 if (channelName.empty())
44 return;
45
46 if (isdigit(channelName[0]))
47 return;
48
49 if (channelName.size() >= 100 || !DisallowHyperlinksAndMaybeKick(channelName))
50 return;
51
53 if (Channel* channel = cMgr->GetJoinChannel(channelName, channelId))
54 channel->JoinChannel(GetPlayer(), password);
55}
DBCStorage< ChatChannelsEntry > sChatChannelsStore(ChatChannelsEntryfmt)
bool DisallowHyperlinksAndMaybeKick(std::string_view str)
Definition WorldSession.cpp:819
Definition DBCStructure.h:643

References DisallowHyperlinksAndMaybeKick(), ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, sAreaTableStore, and sChatChannelsStore.

Referenced by OpcodeTable::Initialize().

◆ HandleLearnPreviewTalents()

void WorldSession::HandleLearnPreviewTalents ( WorldPacket recvPacket)
35{
36 LOG_DEBUG("network", "CMSG_LEARN_PREVIEW_TALENTS");
37
38 uint32 talentsCount;
39 recvPacket >> talentsCount;
40
41 uint32 talentId, talentRank;
42
43 // Client has max 44 talents for tree for 3 trees, rounded up : 150
44 uint32 const MaxTalentsCount = 150;
45
46 for (uint32 i = 0; i < talentsCount && i < MaxTalentsCount; ++i)
47 {
48 recvPacket >> talentId >> talentRank;
49
50 _player->LearnTalent(talentId, talentRank);
51 }
52
54
55 recvPacket.rfinish();
56}
void SendTalentsInfoData(bool pet)
Definition Player.cpp:14532
void LearnTalent(uint32 talentId, uint32 talentRank, bool command=false)
Definition Player.cpp:13985

References _player, Player::LearnTalent(), LOG_DEBUG, ByteBuffer::rfinish(), and Player::SendTalentsInfoData().

Referenced by OpcodeTable::Initialize().

◆ HandleLearnPreviewTalentsPet()

void WorldSession::HandleLearnPreviewTalentsPet ( WorldPacket recvPacket)
1131{
1132 LOG_DEBUG("network", "CMSG_LEARN_PREVIEW_TALENTS_PET");
1133
1134 ObjectGuid guid;
1135 recvData >> guid;
1136
1137 uint32 talentsCount;
1138 recvData >> talentsCount;
1139
1140 uint32 talentId, talentRank;
1141
1142 // Client has max 24 talents, rounded up : 30
1143 uint32 const MaxTalentsCount = 30;
1144
1145 for (uint32 i = 0; i < talentsCount && i < MaxTalentsCount; ++i)
1146 {
1147 recvData >> talentId >> talentRank;
1148
1149 _player->LearnPetTalent(guid, talentId, talentRank);
1150 }
1151
1153
1154 recvData.rfinish();
1155}
void LearnPetTalent(ObjectGuid petGuid, uint32 talentId, uint32 talentRank)
Definition Player.cpp:14118

References _player, Player::LearnPetTalent(), LOG_DEBUG, ByteBuffer::rfinish(), and Player::SendTalentsInfoData().

Referenced by OpcodeTable::Initialize().

◆ HandleLearnTalentOpcode()

void WorldSession::HandleLearnTalentOpcode ( WorldPacket recvPacket)
26{
27 uint32 talent_id, requested_rank;
28 recvData >> talent_id >> requested_rank;
29
30 _player->LearnTalent(talent_id, requested_rank);
32}

References _player, Player::LearnTalent(), and Player::SendTalentsInfoData().

Referenced by OpcodeTable::Initialize().

◆ HandleLeaveChannel()

void WorldSession::HandleLeaveChannel ( WorldPacket recvPacket)
58{
59 uint32 unk;
60 std::string channelName;
61 recvPacket >> unk >> channelName;
62
63 LOG_DEBUG("chat.system", "CMSG_LEAVE_CHANNEL {} Channel: {}, unk1: {}",
64 GetPlayerInfo(), channelName, unk);
65 if (channelName.empty())
66 return;
67
69 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
70 channel->LeaveChannel(GetPlayer(), true);
71}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleLfgGetStatus()

void WorldSession::HandleLfgGetStatus ( WorldPacket recvData)
278{
279 LOG_DEBUG("lfg", "CMSG_LFG_GET_STATUS {}", GetPlayerInfo());
280
281 ObjectGuid guid = GetPlayer()->GetGUID();
282 lfg::LfgUpdateData updateData = sLFGMgr->GetLfgStatus(guid);
283
284 if (GetPlayer()->GetGroup())
285 {
286 SendLfgUpdateParty(updateData);
287 updateData.dungeons.clear();
288 SendLfgUpdatePlayer(updateData);
289 }
290 else
291 {
292 SendLfgUpdatePlayer(updateData);
293 updateData.dungeons.clear();
294 SendLfgUpdateParty(updateData);
295 }
296}
void SendLfgUpdatePlayer(lfg::LfgUpdateData const &updateData)
Definition LFGHandler.cpp:298
void SendLfgUpdateParty(lfg::LfgUpdateData const &updateData)
Definition LFGHandler.cpp:335
Definition LFGMgr.h:290
LfgDungeonSet dungeons
Definition LFGMgr.h:299

References lfg::LfgUpdateData::dungeons, Object::GetGUID(), GetPlayer(), GetPlayerInfo(), LOG_DEBUG, SendLfgUpdateParty(), SendLfgUpdatePlayer(), and sLFGMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleLfgJoinOpcode()

void WorldSession::HandleLfgJoinOpcode ( WorldPackets::LFG::LFGJoin lfgJoin)
50{
52 (GetPlayer()->GetGroup() && GetPlayer()->GetGroup()->GetLeaderGUID() != GetPlayer()->GetGUID() &&
53 (GetPlayer()->GetGroup()->GetMembersCount() == MAXGROUPSIZE || !GetPlayer()->GetGroup()->isLFGGroup())))
54 return;
55
56 if (packet.Slots.empty())
57 {
58 LOG_DEBUG("lfg", "CMSG_LFG_JOIN {} no dungeons selected", GetPlayerInfo());
59 return;
60 }
61
62 lfg::LfgDungeonSet newDungeons;
63 for (uint32 slot : packet.Slots)
64 {
65 uint32 dungeon = slot & 0x00FFFFFF; // remove the type from the dungeon entry
66 if (sLFGDungeonStore.LookupEntry(dungeon))
67 newDungeons.insert(dungeon);
68 }
69
70 LOG_DEBUG("network", "CMSG_LFG_JOIN [{}] roles: {}, Dungeons: {}, Comment: {}",
71 GetPlayerInfo(), packet.Roles, newDungeons.size(), packet.Comment);
72
73 sLFGMgr->JoinLfg(GetPlayer(), uint8(packet.Roles), newDungeons, packet.Comment);
75}
DBCStorage< LFGDungeonEntry > sLFGDungeonStore(LFGDungeonEntryfmt)
#define MAXGROUPSIZE
Definition Group.h:43
void UpdateLFGChannel()
Definition PlayerUpdates.cpp:464
@ LFG_OPTION_ENABLE_SEASONAL_BOSSES
Definition LFGMgr.h:43
@ LFG_OPTION_ENABLE_DUNGEON_FINDER
Definition LFGMgr.h:41
@ LFG_OPTION_ENABLE_RAID_BROWSER
Definition LFGMgr.h:42
std::set< uint32 > LfgDungeonSet
Definition LFG.h:114

References WorldPackets::LFG::LFGJoin::Comment, WorldPackets::Array< T, N >::empty(), GetPlayer(), GetPlayerInfo(), lfg::LFG_OPTION_ENABLE_DUNGEON_FINDER, lfg::LFG_OPTION_ENABLE_RAID_BROWSER, lfg::LFG_OPTION_ENABLE_SEASONAL_BOSSES, LOG_DEBUG, MAXGROUPSIZE, WorldPackets::LFG::LFGJoin::Roles, sLFGDungeonStore, sLFGMgr, WorldPackets::LFG::LFGJoin::Slots, and Player::UpdateLFGChannel().

Referenced by OpcodeTable::Initialize().

◆ HandleLfgLeaveOpcode()

void WorldSession::HandleLfgLeaveOpcode ( WorldPackets::LFG::LFGLeave lfgleave)
78{
79 Group* group = GetPlayer()->GetGroup();
80 ObjectGuid guid = GetPlayer()->GetGUID();
81 ObjectGuid gguid = group ? group->GetGUID() : guid;
82
83 LOG_DEBUG("network", "CMSG_LFG_LEAVE [{}] in group: {}", guid.ToString(), group ? 1 : 0);
84
85 // Check cheating - only leader can leave the queue
86 if (!group || group->GetLeaderGUID() == guid)
87 {
88 sLFGMgr->LeaveLfg(sLFGMgr->GetState(guid) == lfg::LFG_STATE_RAIDBROWSER ? guid : gguid);
89 sLFGMgr->LeaveAllLfgQueues(guid, true, group ? group->GetGUID() : ObjectGuid::Empty);
90 }
92}
ObjectGuid GetGUID() const
Definition Group.cpp:2316
@ LFG_STATE_RAIDBROWSER
Definition LFG.h:75

References ObjectGuid::Empty, Player::GetGroup(), Group::GetGUID(), Object::GetGUID(), Group::GetLeaderGUID(), GetPlayer(), lfg::LFG_STATE_RAIDBROWSER, LOG_DEBUG, sLFGMgr, ObjectGuid::ToString(), and Player::UpdateLFGChannel().

Referenced by OpcodeTable::Initialize().

◆ HandleLfgPartyLockInfoRequestOpcode()

void WorldSession::HandleLfgPartyLockInfoRequestOpcode ( WorldPacket recvData)
227{
228 ObjectGuid guid = GetPlayer()->GetGUID();
229 LOG_DEBUG("network", "CMSG_LFG_PARTY_LOCK_INFO_REQUEST [{}]", guid.ToString());
230
231 Group* group = GetPlayer()->GetGroup();
232 if (!group)
233 return;
234
235 // Get the locked dungeons of the other party members
236 lfg::LfgLockPartyMap lockMap;
237 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
238 {
239 Player* plrg = itr->GetSource();
240 if (!plrg)
241 continue;
242
243 ObjectGuid pguid = plrg->GetGUID();
244 if (pguid == guid)
245 continue;
246
247 sLFGMgr->InitializeLockedDungeons(plrg, group); // pussywizard
248 lockMap[pguid] = sLFGMgr->GetLockedDungeons(pguid);
249 }
250
251 uint32 size = 0;
252 for (lfg::LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it)
253 size += 8 + 4 + uint32(it->second.size()) * (4 + 4);
254
255 LOG_DEBUG("network", "SMSG_LFG_PARTY_INFO [{}]", guid.ToString());
256 WorldPacket data(SMSG_LFG_PARTY_INFO, 1 + size);
257 BuildPartyLockDungeonBlock(data, lockMap);
258 SendPacket(&data);
259}
void BuildPartyLockDungeonBlock(WorldPacket &data, const lfg::LfgLockPartyMap &lockMap)
Definition LFGHandler.cpp:39
@ SMSG_LFG_PARTY_INFO
Definition Opcodes.h:912
std::map< ObjectGuid, LfgLockMap > LfgLockPartyMap
Definition LFG.h:116

References BuildPartyLockDungeonBlock(), Group::GetFirstMember(), Player::GetGroup(), Object::GetGUID(), GetPlayer(), LOG_DEBUG, SendPacket(), sLFGMgr, SMSG_LFG_PARTY_INFO, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleLfgPlayerLockInfoRequestOpcode()

void WorldSession::HandleLfgPlayerLockInfoRequestOpcode ( WorldPacket recvData)
152{
153 ObjectGuid guid = GetPlayer()->GetGUID();
154 LOG_DEBUG("network", "CMSG_LFG_PLAYER_LOCK_INFO_REQUEST [{}]", guid.ToString());
155
156 // Get Random dungeons that can be done at a certain level and expansion
157 uint8 level = GetPlayer()->GetLevel();
158 lfg::LfgDungeonSet const& randomDungeons =
159 sLFGMgr->GetRandomAndSeasonalDungeons(level, GetPlayer()->GetSession()->Expansion());
160
161 // Get player locked Dungeons
162 sLFGMgr->InitializeLockedDungeons(GetPlayer(), GetPlayer()->GetGroup()); // pussywizard
163 lfg::LfgLockMap const& lock = sLFGMgr->GetLockedDungeons(guid);
164 uint32 rsize = uint32(randomDungeons.size());
165 uint32 lsize = uint32(lock.size());
166
167 LOG_DEBUG("network", "SMSG_LFG_PLAYER_INFO [{}]", guid.ToString());
168 WorldPacket data(SMSG_LFG_PLAYER_INFO, 1 + rsize * (4 + 1 + 4 + 4 + 4 + 4 + 1 + 4 + 4 + 4) + 4 + lsize * (1 + 4 + 4 + 4 + 4 + 1 + 4 + 4 + 4));
169
170 data << uint8(randomDungeons.size()); // Random Dungeon count
171 for (lfg::LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it)
172 {
173 data << uint32(*it); // Dungeon Entry (id + type)
174 lfg::LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level);
175 Quest const* quest = nullptr;
176 bool done = false;
177 if (reward)
178 {
179 quest = sObjectMgr->GetQuestTemplate(reward->firstQuest);
180 if (quest)
181 {
182 done = !GetPlayer()->CanRewardQuest(quest, false);
183 if (done)
184 quest = sObjectMgr->GetQuestTemplate(reward->otherQuest);
185 }
186 }
187
188 if (quest)
189 {
190 uint8 playerLevel = GetPlayer() ? GetPlayer()->GetLevel() : 0;
191 data << uint8(done);
192 data << uint32(quest->GetRewOrReqMoney(playerLevel));
193 if (!GetPlayer()->IsMaxLevel())
194 data << uint32(quest->XPValue(playerLevel));
195 else
196 data << uint32(0);
197 data << uint32(0);
198 data << uint32(0);
199 data << uint8(quest->GetRewItemsCount());
200 if (quest->GetRewItemsCount())
201 {
202 for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
203 if (uint32 itemId = quest->RewardItemId[i])
204 {
205 ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId);
206 data << uint32(itemId);
207 data << uint32(item ? item->DisplayInfoID : 0);
208 data << uint32(quest->RewardItemIdCount[i]);
209 }
210 }
211 }
212 else
213 {
214 data << uint8(0);
215 data << uint32(0);
216 data << uint32(0);
217 data << uint32(0);
218 data << uint32(0);
219 data << uint8(0);
220 }
221 }
222 BuildPlayerLockDungeonBlock(data, lock);
223 SendPacket(&data);
224}
void BuildPlayerLockDungeonBlock(WorldPacket &data, lfg::LfgLockMap const &lock)
Definition LFGHandler.cpp:29
#define QUEST_REWARDS_COUNT
Definition QuestDef.h:39
bool CanRewardQuest(Quest const *quest, bool msg)
Definition PlayerQuest.cpp:385
Definition QuestDef.h:210
uint32 RewardItemIdCount[QUEST_REWARDS_COUNT]
Definition QuestDef.h:309
uint32 GetRewItemsCount() const
Definition QuestDef.h:321
uint32 XPValue(uint8 playerLevel=0) const
Definition QuestDef.cpp:198
int32 GetRewOrReqMoney(uint8 playerLevel=0) const
Definition QuestDef.cpp:238
uint32 RewardItemId[QUEST_REWARDS_COUNT]
Definition QuestDef.h:308
@ SMSG_LFG_PLAYER_INFO
Definition Opcodes.h:909
std::map< uint32, uint32 > LfgLockMap
Definition LFG.h:115
Definition LFGMgr.h:335
uint32 firstQuest
Definition LFGMgr.h:340
uint32 otherQuest
Definition LFGMgr.h:341

References BuildPlayerLockDungeonBlock(), Player::CanRewardQuest(), ItemTemplate::DisplayInfoID, Expansion(), lfg::LfgReward::firstQuest, Object::GetGUID(), Unit::GetLevel(), GetPlayer(), Quest::GetRewItemsCount(), Quest::GetRewOrReqMoney(), LOG_DEBUG, lfg::LfgReward::otherQuest, QUEST_REWARDS_COUNT, Quest::RewardItemId, Quest::RewardItemIdCount, SendPacket(), sLFGMgr, SMSG_LFG_PLAYER_INFO, sObjectMgr, ObjectGuid::ToString(), and Quest::XPValue().

Referenced by OpcodeTable::Initialize().

◆ HandleLfgProposalResultOpcode()

void WorldSession::HandleLfgProposalResultOpcode ( WorldPacket recvData)
95{
96 uint32 proposalID; // Internal lfgGroupID
97 bool accept; // Accept to join?
98 recvData >> proposalID;
99 recvData >> accept;
100
101 LOG_DEBUG("network", "CMSG_LFG_PROPOSAL_RESULT [{}] proposal: {} accept: {}", GetPlayer()->GetGUID().ToString(), proposalID, accept ? 1 : 0);
102 sLFGMgr->UpdateProposal(proposalID, GetPlayer()->GetGUID(), accept);
103}

References Object::GetGUID(), GetPlayer(), LOG_DEBUG, and sLFGMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleLfgSetBootVoteOpcode()

void WorldSession::HandleLfgSetBootVoteOpcode ( WorldPacket recvData)
133{
134 bool agree; // Agree to kick player
135 recvData >> agree;
136
137 ObjectGuid guid = GetPlayer()->GetGUID();
138 LOG_DEBUG("network", "CMSG_LFG_SET_BOOT_VOTE [{}] agree: {}", guid.ToString(), agree ? 1 : 0);
139 sLFGMgr->UpdateBoot(guid, agree);
140}

References Object::GetGUID(), GetPlayer(), LOG_DEBUG, sLFGMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleLfgSetCommentOpcode()

void WorldSession::HandleLfgSetCommentOpcode ( WorldPacket recvData)
122{
123 std::string comment;
124 recvData >> comment;
125 ObjectGuid guid = GetPlayer()->GetGUID();
126 LOG_DEBUG("network", "CMSG_LFG_SET_COMMENT [{}] comment: {}", guid.ToString(), comment);
127
128 sLFGMgr->SetComment(GetPlayer()->GetGUID(), comment);
129 sLFGMgr->LfrSetComment(GetPlayer(), comment);
130}

References Object::GetGUID(), GetPlayer(), LOG_DEBUG, sLFGMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleLfgSetRolesOpcode()

void WorldSession::HandleLfgSetRolesOpcode ( WorldPacket recvData)
106{
107 uint8 roles;
108 recvData >> roles; // Player Group Roles
109 ObjectGuid guid = GetPlayer()->GetGUID();
110 Group* group = GetPlayer()->GetGroup();
111 if (!group)
112 {
113 LOG_DEBUG("network", "CMSG_LFG_SET_ROLES [{}] Not in group", guid.ToString());
114 return;
115 }
116 ObjectGuid gguid = group->GetGUID();
117 LOG_DEBUG("network", "CMSG_LFG_SET_ROLES: Group [{}], Player [{}], Roles: {}", gguid.ToString(), guid.ToString(), roles);
118 sLFGMgr->UpdateRoleCheck(gguid, guid, roles);
119}

References Player::GetGroup(), Group::GetGUID(), Object::GetGUID(), GetPlayer(), LOG_DEBUG, sLFGMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleLfgTeleportOpcode()

void WorldSession::HandleLfgTeleportOpcode ( WorldPacket recvData)
143{
144 bool out;
145 recvData >> out;
146
147 LOG_DEBUG("network", "CMSG_LFG_TELEPORT [{}] out: {}", GetPlayer()->GetGUID().ToString(), out ? 1 : 0);
148 sLFGMgr->TeleportPlayer(GetPlayer(), out);
149}

References GetPlayer(), LOG_DEBUG, and sLFGMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleLfrSearchJoinOpcode()

void WorldSession::HandleLfrSearchJoinOpcode ( WorldPacket recvData)
262{
263 uint32 dungeonId;
264 recvData >> dungeonId;
265 dungeonId = (dungeonId & 0x00FFFFFF); // remove the type from the dungeon entry
266 sLFGMgr->LfrSearchAdd(GetPlayer(), dungeonId);
267 sLFGMgr->SendRaidBrowserCachedList(GetPlayer(), dungeonId);
268}

References GetPlayer(), and sLFGMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleLfrSearchLeaveOpcode()

void WorldSession::HandleLfrSearchLeaveOpcode ( WorldPacket recvData)
271{
272 uint32 dungeonId;
273 recvData >> dungeonId;
274 sLFGMgr->LfrSearchRemove(GetPlayer());
275}

References GetPlayer(), and sLFGMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleListInventoryOpcode()

void WorldSession::HandleListInventoryOpcode ( WorldPackets::Item::ListInventory packet)
842{
843 if (!GetPlayer()->IsAlive())
844 return;
845
846 LOG_DEBUG("network", "WORLD: Recvd CMSG_LIST_INVENTORY");
847
849}
ObjectGuid VendorGuid
Definition ItemPackets.h:174
void SendListInventory(ObjectGuid guid, uint32 vendorEntry=0)
Definition ItemHandler.cpp:851

References GetPlayer(), LOG_DEBUG, SendListInventory(), and WorldPackets::Item::ListInventory::VendorGuid.

Referenced by OpcodeTable::Initialize().

◆ HandleListStabledPetsOpcode()

void WorldSession::HandleListStabledPetsOpcode ( WorldPacket recvPacket)
460{
461 LOG_DEBUG("network", "WORLD: Recv MSG_LIST_STABLED_PETS");
462 ObjectGuid npcGUID;
463
464 recvData >> npcGUID;
465
466 if (!CheckStableMaster(npcGUID))
467 return;
468
469 // remove fake death
470 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
472
473 // remove mounts this fix bug where getting pet from stable while mounted deletes pet.
474 if (GetPlayer()->IsMounted())
476
477 SendStablePet(npcGUID);
478}
void SendStablePet(ObjectGuid guid)
Definition NPCHandler.cpp:480

References CheckStableMaster(), GetPlayer(), LOG_DEBUG, Unit::RemoveAurasByType(), SendStablePet(), SPELL_AURA_FEIGN_DEATH, SPELL_AURA_MOUNTED, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleLoadActionsSwitchSpec()

void WorldSession::HandleLoadActionsSwitchSpec ( PreparedQueryResult  result)
582{
583 if (!GetPlayer())
584 return;
585
586 if (result)
587 GetPlayer()->_LoadActions(result);
588
590}
void _LoadActions(PreparedQueryResult result)
Definition PlayerStorage.cpp:5670
void SendActionButtons(uint32 state) const
Definition Player.cpp:5621

References Player::_LoadActions(), GetPlayer(), and Player::SendActionButtons().

◆ HandleLogoutCancelOpcode()

void WorldSession::HandleLogoutCancelOpcode ( WorldPackets::Character::LogoutCancel logoutCancel)
483{
484 // Player have already logged out serverside, too late to cancel
485 if (!GetPlayer())
486 return;
487
489
491
492 // not remove flags if can't free move - its not set in Logout request code.
493 if (GetPlayer()->CanFreeMove())
494 {
495 GetPlayer()->SetRooted(false, true, true);
496
499 }
500}
@ UNIT_STAND_STATE_STAND
Definition UnitDefines.h:32
@ UNIT_FLAG_STUNNED
Definition UnitDefines.h:272
void SetRooted(bool apply, bool stun=false, bool logout=false)
Definition Unit.cpp:18460
Definition CharacterPackets.h:83
void SetLogoutStartTime(time_t requestTime)
Engage the logout process for the user.
Definition WorldSession.h:450

References GetPlayer(), Unit::RemoveUnitFlag(), SendPacket(), SetLogoutStartTime(), Unit::SetRooted(), Unit::SetStandState(), UNIT_FLAG_STUNNED, and UNIT_STAND_STATE_STAND.

Referenced by OpcodeTable::Initialize().

◆ HandleLogoutRequestOpcode()

void WorldSession::HandleLogoutRequestOpcode ( WorldPackets::Character::LogoutRequest logoutRequest)
Todo:
: Possibly add RBAC permission to log out in combat
419{
420 LOG_DEBUG("network", "WORLD: Recvd CMSG_LOGOUT_REQUEST Message, security - {}", GetSecurity());
421
422 if (ObjectGuid lguid = GetPlayer()->GetLootGUID())
423 DoLootRelease(lguid);
424
425 bool instantLogout = ((GetSecurity() >= 0 && uint32(GetSecurity()) >= sWorld->getIntConfig(CONFIG_INSTANT_LOGOUT))
427
428 bool preventAfkSanctuaryLogout = sWorld->getIntConfig(CONFIG_AFK_PREVENT_LOGOUT) == 1
429 && GetPlayer()->isAFK() && sAreaTableStore.LookupEntry(GetPlayer()->GetAreaId())->IsSanctuary();
430
431 bool preventAfkLogout = sWorld->getIntConfig(CONFIG_AFK_PREVENT_LOGOUT) == 2
432 && GetPlayer()->isAFK();
433
435 bool canLogoutInCombat = GetPlayer()->HasPlayerFlag(PLAYER_FLAGS_RESTING);
436
437 uint32 reason = 0;
438 if (GetPlayer()->IsInCombat() && !canLogoutInCombat)
439 reason = 1;
440 else if (GetPlayer()->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR))
441 reason = 3; // is jumping or falling
442 else if (preventAfkSanctuaryLogout || preventAfkLogout || GetPlayer()->duel || GetPlayer()->HasAura(9454)) // is dueling or frozen by GM via freeze command
443 reason = 2; // FIXME - Need the correct value
444
446 logoutResponse.LogoutResult = reason;
447 logoutResponse.Instant = instantLogout;
448 SendPacket(logoutResponse.Write());
449
450 if (reason)
451 {
453 return;
454 }
455
456 //instant logout in taverns/cities or on taxi or for admins, gm's, mod's if its enabled in worldserver.conf
457 if (instantLogout)
458 {
459 LogoutPlayer(true);
460 return;
461 }
462
463 // not set flags if player can't free move to prevent lost state at logout cancel
464 if (GetPlayer()->CanFreeMove())
465 {
466 if (GetPlayer()->getStandState() == UNIT_STAND_STATE_STAND)
467 {
469 }
470
471 GetPlayer()->SetRooted(true, true, true);
473 }
474
476}
@ PLAYER_FLAGS_RESTING
Definition Player.h:473
@ MOVEMENTFLAG_FALLING
Definition UnitDefines.h:381
@ MOVEMENTFLAG_FALLING_FAR
Definition UnitDefines.h:382
@ UNIT_STAND_STATE_SIT
Definition UnitDefines.h:33
@ CONFIG_INSTANT_LOGOUT
Definition WorldConfig.h:259
@ CONFIG_AFK_PREVENT_LOGOUT
Definition WorldConfig.h:342
void SetUnitFlag(UnitFlags flags)
UnitFlags available in UnitDefines.h.
Definition Unit.h:738
Definition CharacterPackets.h:56
WorldPacket const * Write() override
Definition CharacterPackets.cpp:30
uint32 LogoutResult
Definition CharacterPackets.h:62
bool Instant
Definition CharacterPackets.h:63

References CONFIG_AFK_PREVENT_LOGOUT, CONFIG_INSTANT_LOGOUT, DoLootRelease(), GameTime::GetGameTime(), GetPlayer(), GetSecurity(), Player::HasPlayerFlag(), WorldPackets::Character::LogoutResponse::Instant, Player::isAFK(), Unit::IsInCombat(), Unit::IsInFlight(), LOG_DEBUG, LogoutPlayer(), WorldPackets::Character::LogoutResponse::LogoutResult, MOVEMENTFLAG_FALLING, MOVEMENTFLAG_FALLING_FAR, PLAYER_FLAGS_RESTING, sAreaTableStore, SendPacket(), SetLogoutStartTime(), Unit::SetRooted(), Unit::SetStandState(), Unit::SetUnitFlag(), sWorld, UNIT_FLAG_STUNNED, UNIT_STAND_STATE_SIT, UNIT_STAND_STATE_STAND, and WorldPackets::Character::LogoutResponse::Write().

Referenced by OpcodeTable::Initialize().

◆ HandleLootMasterGiveOpcode()

void WorldSession::HandleLootMasterGiveOpcode ( WorldPacket recvPacket)
422{
423 uint8 slotid;
424 ObjectGuid lootguid, target_playerguid;
425
426 recvData >> lootguid >> slotid >> target_playerguid;
427
429 {
431 return;
432 }
433
434 Player* target = ObjectAccessor::GetPlayer(*_player, target_playerguid);
435 if (!target)
436 {
438 return;
439 }
440
441 LOG_DEBUG("network", "WorldSession::HandleLootMasterGiveOpcode (CMSG_LOOT_MASTER_GIVE, 0x02A3) Target = [{}].", target->GetName());
442
443 if (_player->GetLootGUID() != lootguid)
444 {
446 return;
447 }
448
449 if (!_player->IsInRaidWith(target))
450 {
452 //LOG_DEBUG("network", "MasterLootItem: Player {} tried to give an item to ineligible player {} !", GetPlayer()->GetName(), target->GetName());
453 return;
454 }
455
456 Loot* loot = nullptr;
457
458 if (GetPlayer()->GetLootGUID().IsCreatureOrVehicle())
459 {
460 Creature* creature = GetPlayer()->GetMap()->GetCreature(lootguid);
461 if (!creature)
462 return;
463
464 loot = &creature->loot;
465 }
466 else if (GetPlayer()->GetLootGUID().IsGameObject())
467 {
468 GameObject* pGO = GetPlayer()->GetMap()->GetGameObject(lootguid);
469 if (!pGO)
470 return;
471
472 loot = &pGO->loot;
473 }
474
475 if (!loot)
476 return;
477
478 if (slotid >= loot->items.size() + loot->quest_items.size())
479 {
480 LOG_DEBUG("loot", "MasterLootItem: Player {} might be using a hack! (slot {}, size {})", GetPlayer()->GetName(), slotid, (unsigned long)loot->items.size());
481 return;
482 }
483
484 LootItem& item = slotid >= loot->items.size() ? loot->quest_items[slotid - loot->items.size()] : loot->items[slotid];
485
486 ItemPosCountVec dest;
487 InventoryResult msg = target->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, item.itemid, item.count);
488 if (!item.AllowedForPlayer(target, loot->sourceWorldObjectGUID))
490 if (msg != EQUIP_ERR_OK)
491 {
494 else if (msg == EQUIP_ERR_INVENTORY_FULL)
496 else
498
499 return;
500 }
501
502 // list of players allowed to receive this item in trade
503 AllowedLooterSet looters = item.GetAllowedLooters();
504
505 // not move item from loot to target inventory
506 Item* newitem = target->StoreNewItem(dest, item.itemid, true, item.randomPropertyId, looters);
507 target->SendNewItem(newitem, uint32(item.count), false, false, true);
508 target->UpdateLootAchievements(&item, loot);
509
510 // mark as looted
511 item.count = 0;
512 item.is_looted = true;
513
514 loot->NotifyItemRemoved(slotid);
515 --loot->unlootedCount;
516}
@ EQUIP_ERR_CANT_CARRY_MORE_OF_THIS
Definition Item.h:64
@ EQUIP_ERR_INVENTORY_FULL
Definition Item.h:97
@ EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM
Definition Item.h:57
GuidSet AllowedLooterSet
Definition LootMgr.h:151
@ MASTER_LOOT
Definition LootMgr.h:60
@ LOOT_ERROR_MASTER_OTHER
Definition LootMgr.h:106
@ LOOT_ERROR_MASTER_INV_FULL
Definition LootMgr.h:104
@ LOOT_ERROR_MASTER_UNIQUE_ITEM
Definition LootMgr.h:105
@ LOOT_ERROR_PLAYER_NOT_FOUND
Definition LootMgr.h:102
ObjectGuid GetMasterLooterGuid() const
Definition Group.cpp:2336
LootMethod GetLootMethod() const
Definition Group.cpp:2326
void UpdateLootAchievements(LootItem *item, Loot *loot)
Definition PlayerUpdates.cpp:2153
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition PlayerStorage.cpp:4747
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0, bool refund=false)
Definition PlayerStorage.cpp:2531
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition Player.h:1280
bool IsInRaidWith(Unit const *unit) const
Definition Unit.cpp:19044
bool AllowedForPlayer(Player const *player, ObjectGuid source) const
Definition LootMgr.cpp:417
int32 randomPropertyId
Definition LootMgr.h:158
const AllowedLooterSet & GetAllowedLooters() const
Definition LootMgr.h:181
ObjectGuid sourceWorldObjectGUID
Definition LootMgr.h:330
std::vector< LootItem > items
Definition LootMgr.h:320
std::vector< LootItem > quest_items
Definition LootMgr.h:321

References _player, LootItem::AllowedForPlayer(), Player::CanStoreNewItem(), LootItem::count, EQUIP_ERR_CANT_CARRY_MORE_OF_THIS, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_OK, EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM, LootItem::GetAllowedLooters(), Map::GetCreature(), Map::GetGameObject(), Player::GetGroup(), Object::GetGUID(), Player::GetLootGUID(), Group::GetLootMethod(), WorldObject::GetMap(), Group::GetMasterLooterGuid(), WorldObject::GetName(), GetPlayer(), ObjectAccessor::GetPlayer(), LootItem::is_looted, Unit::IsInRaidWith(), LootItem::itemid, Loot::items, LOG_DEBUG, Creature::loot, GameObject::loot, LOOT_ERROR_DIDNT_KILL, LOOT_ERROR_MASTER_INV_FULL, LOOT_ERROR_MASTER_OTHER, LOOT_ERROR_MASTER_UNIQUE_ITEM, LOOT_ERROR_PLAYER_NOT_FOUND, MASTER_LOOT, Loot::NotifyItemRemoved(), NULL_BAG, NULL_SLOT, Loot::quest_items, LootItem::randomPropertyId, Player::SendLootError(), Player::SendNewItem(), Loot::sourceWorldObjectGUID, Player::StoreNewItem(), Loot::unlootedCount, and Player::UpdateLootAchievements().

Referenced by OpcodeTable::Initialize().

◆ HandleLootMethodOpcode()

void WorldSession::HandleLootMethodOpcode ( WorldPacket recvPacket)

error handling

465{
466 uint32 lootMethod;
467 ObjectGuid lootMaster;
468 uint32 lootThreshold;
469 recvData >> lootMethod >> lootMaster >> lootThreshold;
470
471 Group* group = GetPlayer()->GetGroup();
472 if (!group)
473 return;
474
476 // Xinef: Check if group is LFG
477 if (!group->IsLeader(GetPlayer()->GetGUID()) || group->isLFGGroup(true))
478 return;
479
480 if (lootMethod > NEED_BEFORE_GREED)
481 return;
482
483 if (lootThreshold < ITEM_QUALITY_UNCOMMON || lootThreshold > ITEM_QUALITY_ARTIFACT)
484 return;
485
486 if (lootMethod == MASTER_LOOT && !group->IsMember(lootMaster))
487 return;
488 /********************/
489
490 // everything's fine, do it
491 group->SetLootMethod((LootMethod)lootMethod);
492 group->SetMasterLooterGuid(lootMaster);
493 group->SetLootThreshold((ItemQualities)lootThreshold);
494 group->SendUpdate();
495}
LootMethod
Definition LootMgr.h:57
@ NEED_BEFORE_GREED
Definition LootMgr.h:62
ItemQualities
Definition SharedDefines.h:339
@ ITEM_QUALITY_ARTIFACT
Definition SharedDefines.h:346
void SetLootMethod(LootMethod method)
Definition Group.cpp:2240
void SetLootThreshold(ItemQualities threshold)
Definition Group.cpp:2255
void SetMasterLooterGuid(ObjectGuid guid)
Definition Group.cpp:2250

References Player::GetGroup(), GetPlayer(), Group::IsLeader(), Group::isLFGGroup(), Group::IsMember(), ITEM_QUALITY_ARTIFACT, MASTER_LOOT, NEED_BEFORE_GREED, Group::SendUpdate(), Group::SetLootMethod(), Group::SetLootThreshold(), and Group::SetMasterLooterGuid().

Referenced by OpcodeTable::Initialize().

◆ HandleLootMoneyOpcode()

void WorldSession::HandleLootMoneyOpcode ( WorldPacket recvPacket)
115{
116 LOG_DEBUG("network", "WORLD: CMSG_LOOT_MONEY");
117
118 Player* player = GetPlayer();
119 ObjectGuid guid = player->GetLootGUID();
120 if (!guid)
121 return;
122
123 Loot* loot = nullptr;
124 bool shareMoney = true;
125
126 switch (guid.GetHigh())
127 {
129 {
130 GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid);
131
132 // do not check distance for GO if player is the owner of it (ex. fishing bobber)
133 if (go && ((go->GetOwnerGUID() == player->GetGUID() || go->IsWithinDistInMap(player))))
134 {
135 loot = &go->loot;
136 }
137
138 break;
139 }
140 case HighGuid::Corpse: // remove insignia ONLY in BG
141 {
142 Corpse* bones = ObjectAccessor::GetCorpse(*player, guid);
143
144 if (bones && bones->IsWithinDistInMap(player, INTERACTION_DISTANCE))
145 {
146 loot = &bones->loot;
147 shareMoney = false;
148 }
149
150 break;
151 }
152 case HighGuid::Item:
153 {
154 if (Item* item = player->GetItemByGuid(guid))
155 {
156 loot = &item->loot;
157 shareMoney = false;
158 }
159 break;
160 }
161 case HighGuid::Unit:
163 {
164 Creature* creature = player->GetMap()->GetCreature(guid);
165 bool lootAllowed = creature && creature->IsAlive() == (player->IsClass(CLASS_ROGUE, CLASS_CONTEXT_ABILITY) && creature->loot.loot_type == LOOT_PICKPOCKETING);
166 if (lootAllowed && creature->IsWithinDistInMap(player, INTERACTION_DISTANCE))
167 {
168 loot = &creature->loot;
169 if (creature->IsAlive())
170 shareMoney = false;
171 }
172 else
173 player->SendLootError(guid, lootAllowed ? LOOT_ERROR_TOO_FAR : LOOT_ERROR_DIDNT_KILL);
174 break;
175 }
176 default:
177 return; // unlootable type
178 }
179
180 if (loot)
181 {
182 sScriptMgr->OnPlayerBeforeLootMoney(player, loot);
183 loot->NotifyMoneyRemoved();
184 if (shareMoney && player->GetGroup()) //item, pickpocket and players can be looted only single player
185 {
186 Group* group = player->GetGroup();
187
188 std::vector<Player*> playersNear;
189 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
190 {
191 Player* member = itr->GetSource();
192 if (!member)
193 continue;
194
195 if (player->IsAtLootRewardDistance(member))
196 playersNear.push_back(member);
197 }
198
199 uint32 goldPerPlayer = uint32((loot->gold) / (playersNear.size()));
200
201 for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i)
202 {
203 (*i)->ModifyMoney(goldPerPlayer);
204 (*i)->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, goldPerPlayer);
205
207 data << uint32(goldPerPlayer);
208 data << uint8(playersNear.size() > 1 ? 0 : 1); // Controls the text displayed in chat. 0 is "Your share is..." and 1 is "You loot..."
209 (*i)->SendDirectMessage(&data);
210 }
211 }
212 else
213 {
214 sScriptMgr->OnPlayerAfterCreatureLootMoney(player);
215 player->ModifyMoney(loot->gold);
217
219 data << uint32(loot->gold);
220 data << uint8(1); // "You loot..."
221 SendPacket(&data);
222 }
223
224 sScriptMgr->OnLootMoney(player, loot->gold);
225
226 loot->gold = 0;
227
228 // Delete the money loot record from the DB
229 if (loot->containerGUID)
230 sLootItemStorage->RemoveStoredLootMoney(loot->containerGUID, loot);
231
232 // Delete container if empty
233 if (loot->isLooted() && guid.IsItem())
234 DoLootRelease(guid);
235 }
236}
@ ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY
Definition DBCEnums.h:179
#define sLootItemStorage
Definition LootItemStorage.h:73
HighGuid GetHigh() const
Definition ObjectGuid.h:143
bool IsAtLootRewardDistance(WorldObject const *pRewardSource) const
Definition Player.cpp:12822
@ SMSG_LOOT_MONEY_NOTIFY
Definition Opcodes.h:385
ObjectGuid containerGUID
Definition LootMgr.h:329
void NotifyMoneyRemoved()
Definition LootMgr.cpp:789
uint32 gold
Definition LootMgr.h:322

References ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, CLASS_CONTEXT_ABILITY, CLASS_ROGUE, Loot::containerGUID, Corpse, DoLootRelease(), GameObject, ObjectAccessor::GetCorpse(), Map::GetCreature(), Group::GetFirstMember(), Map::GetGameObject(), Player::GetGroup(), Object::GetGUID(), ObjectGuid::GetHigh(), Player::GetItemByGuid(), Player::GetLootGUID(), WorldObject::GetMap(), GameObject::GetOwnerGUID(), GetPlayer(), Loot::gold, INTERACTION_DISTANCE, Unit::IsAlive(), Player::IsAtLootRewardDistance(), Player::IsClass(), ObjectGuid::IsItem(), Loot::isLooted(), GameObject::IsWithinDistInMap(), WorldObject::IsWithinDistInMap(), Item, LOG_DEBUG, Corpse::loot, Creature::loot, GameObject::loot, LOOT_ERROR_DIDNT_KILL, LOOT_ERROR_TOO_FAR, LOOT_PICKPOCKETING, Loot::loot_type, Player::ModifyMoney(), GroupReference::next(), Loot::NotifyMoneyRemoved(), Player::SendLootError(), SendPacket(), sLootItemStorage, SMSG_LOOT_MONEY_NOTIFY, sScriptMgr, Unit, Player::UpdateAchievementCriteria(), and Vehicle.

Referenced by OpcodeTable::Initialize().

◆ HandleLootOpcode()

void WorldSession::HandleLootOpcode ( WorldPacket recvPacket)
239{
240 LOG_DEBUG("network", "WORLD: CMSG_LOOT");
241
242 ObjectGuid guid;
243 recvData >> guid;
244
245 // Check possible cheat
246 if (!GetPlayer()->IsAlive() || !guid.IsCreatureOrVehicle())
247 return;
248
249 // interrupt cast
250 if (GetPlayer()->IsNonMeleeSpellCast(false))
252
254}
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition Player.cpp:7849

References GetPlayer(), Unit::InterruptNonMeleeSpells(), ObjectGuid::IsCreatureOrVehicle(), LOG_DEBUG, LOOT_CORPSE, and Player::SendLoot().

Referenced by OpcodeTable::Initialize().

◆ HandleLootReleaseOpcode()

void WorldSession::HandleLootReleaseOpcode ( WorldPacket recvPacket)
257{
258 LOG_DEBUG("network", "WORLD: CMSG_LOOT_RELEASE");
259
260 // cheaters can modify lguid to prevent correct apply loot release code and re-loot
261 // use internal stored guid
262 ObjectGuid guid;
263 recvData >> guid;
264
265 if (ObjectGuid lguid = GetPlayer()->GetLootGUID())
266 if (lguid == guid)
267 DoLootRelease(lguid);
268}

References DoLootRelease(), GetPlayer(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleLootRoll()

void WorldSession::HandleLootRoll ( WorldPacket recvData)
498{
499 ObjectGuid guid;
500 uint32 itemSlot;
501 uint8 rollType;
502 recvData >> guid; // guid of the item rolled
503 recvData >> itemSlot;
504 recvData >> rollType; // 0: pass, 1: need, 2: greed
505
506 Group* group = GetPlayer()->GetGroup();
507 if (!group)
508 return;
509
510 group->CountRollVote(GetPlayer()->GetGUID(), guid, rollType);
511
512 switch (rollType)
513 {
514 case ROLL_NEED:
516 break;
517 case ROLL_GREED:
519 break;
520 case ROLL_DISENCHANT:
522 break;
523 }
524}
@ ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED
Definition DBCEnums.h:201
@ ACHIEVEMENT_CRITERIA_TYPE_ROLL_DISENCHANT
Definition DBCEnums.h:222
@ ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED
Definition DBCEnums.h:200
@ ROLL_GREED
Definition LootMgr.h:35
@ ROLL_NEED
Definition LootMgr.h:34
@ ROLL_DISENCHANT
Definition LootMgr.h:36
bool CountRollVote(ObjectGuid playerGUID, ObjectGuid Guid, uint8 Choise)
Definition Group.cpp:1360

References ACHIEVEMENT_CRITERIA_TYPE_ROLL_DISENCHANT, ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED, ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED, Group::CountRollVote(), Player::GetGroup(), GetPlayer(), ROLL_DISENCHANT, ROLL_GREED, ROLL_NEED, and Player::UpdateAchievementCriteria().

Referenced by OpcodeTable::Initialize().

◆ HandleMailCreateTextItem()

void WorldSession::HandleMailCreateTextItem ( WorldPacket recvData)
758{
759 ObjectGuid mailbox;
760 uint32 mailId;
761
762 recvData >> mailbox;
763 recvData >> mailId;
764
765 if (!CanOpenMailBox(mailbox))
766 return;
767
768 Player* player = _player;
769
770 Mail* m = player->GetMail(mailId);
771 if (!m || (m->body.empty() && !m->mailTemplateId) || m->state == MAIL_STATE_DELETED || m->deliver_time > GameTime::GetGameTime().count() || (m->checked & MAIL_CHECK_MASK_COPIED))
772 {
774 return;
775 }
776
777 Item* bodyItem = new Item; // This is not bag and then can be used new Item.
778 if (!bodyItem->Create(sObjectMgr->GetGenerator<HighGuid::Item>().Generate(), MAIL_BODY_ITEM_TEMPLATE, player))
779 {
780 delete bodyItem;
781 return;
782 }
783
784 // in mail template case we need create new item text
785 if (m->mailTemplateId)
786 {
787 MailTemplateEntry const* mailTemplateEntry = sMailTemplateStore.LookupEntry(m->mailTemplateId);
788 if (!mailTemplateEntry)
789 {
791 delete bodyItem;
792 return;
793 }
794
795 bodyItem->SetText(mailTemplateEntry->content[GetSessionDbcLocale()]);
796 }
797 else
798 bodyItem->SetText(m->body);
799
802
803 LOG_DEBUG("network.opcode", "HandleMailCreateTextItem mailid={}", mailId);
804
805 ItemPosCountVec dest;
806 uint8 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, bodyItem, false);
807 if (msg == EQUIP_ERR_OK)
808 {
811 player->m_mailsUpdated = true;
812
813 player->StoreItem(dest, bodyItem, true);
815 }
816 else
817 {
819 delete bodyItem;
820 }
821}
DBCStorage< MailTemplateEntry > sMailTemplateStore(MailTemplateEntryfmt)
@ ITEM_FLAG_MAIL_TEXT_MASK
Definition ItemTemplate.h:142
@ MAIL_STATE_CHANGED
Definition Mail.h:69
#define MAIL_BODY_ITEM_TEMPLATE
Definition Mail.h:32
@ MAIL_MADE_PERMANENT
Definition SharedDefines.h:3771
@ MAIL_ERR_EQUIP_ERROR
Definition SharedDefines.h:3777
@ MAIL_OK
Definition SharedDefines.h:3776
@ MAIL_ERR_INTERNAL_ERROR
Definition SharedDefines.h:3782
@ ITEM_FIELD_FLAGS
Definition UpdateFields.h:42
@ ITEM_FIELD_CREATOR
Definition UpdateFields.h:37
virtual bool Create(ObjectGuid::LowType guidlow, uint32 itemid, Player const *owner)
Definition Item.cpp:282
void SetText(std::string const &text)
Definition Item.h:309
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:827
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:639
void SendMailResult(uint32 mailId, MailResponseType mailAction, MailResponseResult mailError, uint32 equipError=0, ObjectGuid::LowType item_guid=0, uint32 item_count=0)
Definition Player.cpp:2855
bool m_mailsUpdated
Definition Player.h:1592
Mail * GetMail(uint32 id)
Definition Player.cpp:3812
Definition DBCStructure.h:1315
char const * content[16]
Definition DBCStructure.h:1319
uint32 sender
Definition Mail.h:172
std::string body
Definition Mail.h:175
time_t deliver_time
Definition Mail.h:179
uint32 checked
Definition Mail.h:182
MailState state
Definition Mail.h:183
uint16 mailTemplateId
Definition Mail.h:171

References _player, Mail::body, CanOpenMailBox(), Player::CanStoreItem(), Mail::checked, MailTemplateEntry::content, Item::Create(), Mail::deliver_time, EQUIP_ERR_OK, GameTime::GetGameTime(), Player::GetMail(), GetSessionDbcLocale(), Item, ITEM_FIELD_CREATOR, ITEM_FIELD_FLAGS, ITEM_FLAG_MAIL_TEXT_MASK, LOG_DEBUG, Player::m_mailsUpdated, MAIL_BODY_ITEM_TEMPLATE, MAIL_CHECK_MASK_COPIED, MAIL_ERR_EQUIP_ERROR, MAIL_ERR_INTERNAL_ERROR, MAIL_MADE_PERMANENT, MAIL_OK, MAIL_STATE_CHANGED, MAIL_STATE_DELETED, Mail::mailTemplateId, NULL_BAG, NULL_SLOT, Mail::sender, Player::SendMailResult(), Object::SetFlag(), Item::SetText(), Object::SetUInt32Value(), sMailTemplateStore, sObjectMgr, Mail::state, and Player::StoreItem().

Referenced by OpcodeTable::Initialize().

◆ HandleMailDelete()

void WorldSession::HandleMailDelete ( WorldPacket recvData)
372{
373 ObjectGuid mailbox;
374 uint32 mailId;
375 recvData >> mailbox;
376 recvData >> mailId;
377 recvData.read_skip<uint32>(); // mailTemplateId
378
379 if (!CanOpenMailBox(mailbox))
380 return;
381
382 Mail* m = _player->GetMail(mailId);
383 Player* player = _player;
384 player->m_mailsUpdated = true;
385 if (m)
386 {
387 // delete shouldn't show up for COD mails
388 if (m->COD)
389 {
391 return;
392 }
393
395
396 sCharacterCache->DecreaseCharacterMailCount(player->GetGUID());
397 }
398 player->SendMailResult(mailId, MAIL_DELETED, MAIL_OK);
399}
@ MAIL_DELETED
Definition SharedDefines.h:3770
uint32 COD
Definition Mail.h:181

References _player, CanOpenMailBox(), Mail::COD, Object::GetGUID(), Player::GetMail(), Player::m_mailsUpdated, MAIL_DELETED, MAIL_ERR_INTERNAL_ERROR, MAIL_OK, MAIL_STATE_DELETED, ByteBuffer::read_skip(), sCharacterCache, Player::SendMailResult(), and Mail::state.

Referenced by OpcodeTable::Initialize().

◆ HandleMailMarkAsRead()

void WorldSession::HandleMailMarkAsRead ( WorldPacket recvData)
349{
350 ObjectGuid mailbox;
351 uint32 mailId;
352 recvData >> mailbox;
353 recvData >> mailId;
354
355 if (!CanOpenMailBox(mailbox))
356 return;
357
358 Player* player = _player;
359 Mail* m = player->GetMail(mailId);
360 if (m && m->state != MAIL_STATE_DELETED)
361 {
362 if (player->unReadMails)
363 --player->unReadMails;
365 player->m_mailsUpdated = true;
367 }
368}
@ MAIL_CHECK_MASK_READ
Definition Mail.h:47
uint8 unReadMails
Definition Player.h:1655

References _player, CanOpenMailBox(), Mail::checked, Player::GetMail(), Player::m_mailsUpdated, MAIL_CHECK_MASK_READ, MAIL_STATE_CHANGED, MAIL_STATE_DELETED, Mail::state, and Player::unReadMails.

Referenced by OpcodeTable::Initialize().

◆ HandleMailReturnToSender()

void WorldSession::HandleMailReturnToSender ( WorldPacket recvData)
402{
403 ObjectGuid mailbox;
404 uint32 mailId;
405 recvData >> mailbox;
406 recvData >> mailId;
407 recvData.read_skip<uint64>(); // original sender GUID for return to, not used
408
409 if (!CanOpenMailBox(mailbox))
410 return;
411
412 Player* player = _player;
413 Mail* m = player->GetMail(mailId);
414 if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > GameTime::GetGameTime().count())
415 {
417 return;
418 }
419
420 if (m->HasItems())
421 {
422 for (MailItemInfoVec::iterator itr = m->items.begin(); itr != m->items.end(); ++itr)
423 {
424 Item* item = player->GetMItem(itr->item_guid);
425 if (item && !sScriptMgr->OnPlayerCanSendMail(player, ObjectGuid(HighGuid::Player, m->sender), mailbox, m->subject, m->body, m->money, m->COD, item))
426 {
428 return;
429 }
430 }
431 }
432 else if (!sScriptMgr->OnPlayerCanSendMail(player, ObjectGuid(HighGuid::Player, m->sender), mailbox, m->subject, m->body, m->money, m->COD, nullptr))
433 {
435 return;
436 }
437
438 //we can return mail now
439 //so firstly delete the old one
440 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
441
443 stmt->SetData(0, mailId);
444 trans->Append(stmt);
445
446 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM_BY_ID);
447 stmt->SetData(0, mailId);
448 trans->Append(stmt);
449
450 player->RemoveMail(mailId);
451
452 // only return mail if the player exists (and delete if not existing)
453 if (m->messageType == MAIL_NORMAL && m->sender)
454 {
455 MailDraft draft(m->subject, m->body);
456 if (m->mailTemplateId)
457 draft = MailDraft(m->mailTemplateId, false); // items already included
458
459 if (m->HasItems())
460 {
461 for (MailItemInfoVec::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
462 {
463 Item* item = player->GetMItem(itr2->item_guid);
464 if (item)
465 draft.AddItem(item);
466
467 player->RemoveMItem(itr2->item_guid);
468 }
469 }
470 draft.AddMoney(m->money).SendReturnToSender(GetAccountId(), m->receiver, m->sender, trans);
471 }
472
473 CharacterDatabase.CommitTransaction(trans);
474
475 delete m; //we can deallocate old mail
477
478 sCharacterCache->DecreaseCharacterMailCount(player->GetGUID());
479}
@ CHAR_DEL_MAIL_BY_ID
Definition CharacterDatabase.h:110
@ CHAR_DEL_MAIL_ITEM_BY_ID
Definition CharacterDatabase.h:382
@ MAIL_RETURNED_TO_SENDER
Definition SharedDefines.h:3769
void RemoveMail(uint32 id)
Definition Player.cpp:2842
bool RemoveMItem(ObjectGuid::LowType itemLowGuid)
Definition Player.h:1675
bool HasItems() const
Definition Mail.h:206
ObjectGuid::LowType receiver
Definition Mail.h:173
uint8 messageType
Definition Mail.h:169
std::string subject
Definition Mail.h:174
std::vector< MailItemInfo > items
Definition Mail.h:176
uint32 money
Definition Mail.h:180

References _player, MailDraft::AddItem(), MailDraft::AddMoney(), Mail::body, CanOpenMailBox(), CHAR_DEL_MAIL_BY_ID, CHAR_DEL_MAIL_ITEM_BY_ID, CharacterDatabase, Mail::COD, Mail::deliver_time, GetAccountId(), GameTime::GetGameTime(), Object::GetGUID(), Player::GetMail(), Player::GetMItem(), Mail::HasItems(), Mail::items, MAIL_ERR_INTERNAL_ERROR, MAIL_NORMAL, MAIL_OK, MAIL_RETURNED_TO_SENDER, MAIL_STATE_DELETED, Mail::mailTemplateId, Mail::messageType, Mail::money, Player, ByteBuffer::read_skip(), Mail::receiver, Player::RemoveMail(), Player::RemoveMItem(), sCharacterCache, Mail::sender, Player::SendMailResult(), MailDraft::SendReturnToSender(), PreparedStatementBase::SetData(), sScriptMgr, Mail::state, and Mail::subject.

Referenced by OpcodeTable::Initialize().

◆ HandleMailTakeItem()

void WorldSession::HandleMailTakeItem ( WorldPacket recvData)
483{
484 ObjectGuid mailbox;
485 uint32 mailId;
486 uint32 itemLowGuid;
487 recvData >> mailbox;
488 recvData >> mailId;
489 recvData >> itemLowGuid; // item guid low
490
491 if (!CanOpenMailBox(mailbox))
492 return;
493
494 Player* player = _player;
495
496 Mail* m = player->GetMail(mailId);
497 if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > GameTime::GetGameTime().count())
498 {
500 return;
501 }
502
503 // verify that the mail has the item to avoid cheaters taking COD items without paying
504 bool foundItem = false;
505 for (std::vector<MailItemInfo>::const_iterator itr = m->items.begin(); itr != m->items.end(); ++itr)
506 if (itr->item_guid == itemLowGuid)
507 {
508 foundItem = true;
509 break;
510 }
511 if (!foundItem)
512 {
514 return;
515 }
516
517 // prevent cheating with skip client money check
518 if (!player->HasEnoughMoney(m->COD))
519 {
521 return;
522 }
523
524 Item* it = player->GetMItem(itemLowGuid);
525
526 ItemPosCountVec dest;
527 uint8 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, it, false);
528 if (msg == EQUIP_ERR_OK)
529 {
530 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
531 m->RemoveItem(itemLowGuid);
532 m->removedItems.push_back(itemLowGuid);
533
534 if (m->COD > 0) // if there is COD, take COD money from player and send them to sender by mail
535 {
536 uint32 sender_accId = 0;
538 if (sender)
539 {
540 sender_accId = sender->GetSession()->GetAccountId();
541 }
542 else
543 {
544 sender_accId = sCharacterCache->GetCharacterAccountIdByGuid(ObjectGuid(HighGuid::Player, m->sender));
545 }
546
547 // check player existence
548 if (sender || sender_accId)
549 {
550 MailDraft(m->subject, "")
551 .AddMoney(m->COD)
553
554 if (m->COD >= 10 * GOLD)
555 {
556 std::string senderName;
557 if (!sCharacterCache->GetCharacterNameByGuid(ObjectGuid(HighGuid::Player, m->sender), senderName))
558 {
559 senderName = sObjectMgr->GetAcoreStringForDBCLocale(LANG_UNKNOWN);
560 }
561 std::string subj = m->subject;
563 CharacterDatabase.Execute("INSERT INTO log_money VALUES({}, {}, \"{}\", \"{}\", {}, \"{}\", {}, \"{}\", NOW(), {})",
564 GetAccountId(), player->GetGUID().GetCounter(), player->GetName(), player->GetSession()->GetRemoteAddress(), sender_accId, senderName, m->COD, subj, 1);
565 }
566 }
567
568 player->ModifyMoney(-int32(m->COD));
569 }
570
571 m->COD = 0;
573 player->m_mailsUpdated = true;
574 player->RemoveMItem(it->GetGUID().GetCounter());
575
576 uint32 count = it->GetCount(); // save counts before store and possible merge with deleting
577 it->SetState(ITEM_UNCHANGED); // need to set this state, otherwise item cannot be removed later, if neccessary
578 player->MoveItemToInventory(dest, it, true);
579
580 player->SaveInventoryAndGoldToDB(trans);
581 player->_SaveMail(trans);
582 CharacterDatabase.CommitTransaction(trans);
583
584 player->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_OK, 0, itemLowGuid, count);
585 }
586 else
588}
void CleanStringForMysqlQuery(std::string &str)
Definition Common.cpp:61
@ ITEM_UNCHANGED
Definition Item.h:209
@ LANG_UNKNOWN
Definition Language.h:77
@ MAIL_CHECK_MASK_COD_PAYMENT
This mail was copied. Do not allow making a copy of items in mail.
Definition Mail.h:50
@ MAIL_ITEM_TAKEN
Definition SharedDefines.h:3768
@ MAIL_ERR_NOT_ENOUGH_MONEY
Definition SharedDefines.h:3779
MailDraft & AddMoney(uint32 money)
Definition Mail.h:137
Definition Mail.h:105
Definition Mail.h:83
void MoveItemToInventory(ItemPosCountVec const &dest, Item *pItem, bool update, bool in_characterInventoryDB=false)
Definition PlayerStorage.cpp:2999
void _SaveMail(CharacterDatabaseTransaction trans)
Definition PlayerStorage.cpp:7383
Player * FindPlayerByLowGUID(ObjectGuid::LowType lowguid)
Definition ObjectAccessor.cpp:251
std::vector< uint32 > removedItems
Definition Mail.h:177
bool RemoveItem(ObjectGuid::LowType item_guid)
Definition Mail.h:193

References _player, Player::_SaveMail(), MailDraft::AddMoney(), CanOpenMailBox(), Player::CanStoreItem(), CharacterDatabase, CleanStringForMysqlQuery(), Mail::COD, Mail::deliver_time, EQUIP_ERR_OK, ObjectAccessor::FindPlayerByLowGUID(), GetAccountId(), Item::GetCount(), ObjectGuid::GetCounter(), GameTime::GetGameTime(), Object::GetGUID(), Player::GetMail(), Player::GetMItem(), WorldObject::GetName(), GetRemoteAddress(), Player::GetSession(), GOLD, Player::HasEnoughMoney(), ITEM_UNCHANGED, Mail::items, LANG_UNKNOWN, Player::m_mailsUpdated, MAIL_CHECK_MASK_COD_PAYMENT, MAIL_ERR_EQUIP_ERROR, MAIL_ERR_INTERNAL_ERROR, MAIL_ERR_NOT_ENOUGH_MONEY, MAIL_ITEM_TAKEN, MAIL_NORMAL, MAIL_OK, MAIL_STATE_CHANGED, MAIL_STATE_DELETED, Player::ModifyMoney(), Player::MoveItemToInventory(), NULL_BAG, NULL_SLOT, Player, Mail::receiver, Mail::removedItems, Mail::RemoveItem(), Player::RemoveMItem(), Player::SaveInventoryAndGoldToDB(), sCharacterCache, Mail::sender, Player::SendMailResult(), MailDraft::SendMailTo(), Item::SetState(), sObjectMgr, Mail::state, and Mail::subject.

Referenced by OpcodeTable::Initialize().

◆ HandleMailTakeMoney()

void WorldSession::HandleMailTakeMoney ( WorldPacket recvData)
591{
592 ObjectGuid mailbox;
593 uint32 mailId;
594 recvData >> mailbox;
595 recvData >> mailId;
596
597 if (!CanOpenMailBox(mailbox))
598 return;
599
600 Player* player = _player;
601
602 Mail* m = player->GetMail(mailId);
603 if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > GameTime::GetGameTime().count())
604 {
606 return;
607 }
608
609 if (!player->ModifyMoney(m->money, false))
610 {
612 return;
613 }
614
615 m->money = 0;
617 player->m_mailsUpdated = true;
618
619 player->SendMailResult(mailId, MAIL_MONEY_TAKEN, MAIL_OK);
620
621 // save money and mail to prevent cheating
622 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
623 player->SaveGoldToDB(trans);
624 player->_SaveMail(trans);
625 CharacterDatabase.CommitTransaction(trans);
626}
@ MAIL_MONEY_TAKEN
Definition SharedDefines.h:3767
void SaveGoldToDB(CharacterDatabaseTransaction trans)
Definition PlayerStorage.cpp:7131

References _player, Player::_SaveMail(), CanOpenMailBox(), CharacterDatabase, Mail::deliver_time, EQUIP_ERR_TOO_MUCH_GOLD, GameTime::GetGameTime(), Player::GetMail(), Player::m_mailsUpdated, MAIL_ERR_EQUIP_ERROR, MAIL_ERR_INTERNAL_ERROR, MAIL_MONEY_TAKEN, MAIL_OK, MAIL_STATE_CHANGED, MAIL_STATE_DELETED, Player::ModifyMoney(), Mail::money, Player::SaveGoldToDB(), Player::SendMailResult(), and Mail::state.

Referenced by OpcodeTable::Initialize().

◆ HandleMessagechatOpcode()

void WorldSession::HandleMessagechatOpcode ( WorldPacket recvPacket)
60{
61 uint32 type;
62 uint32 lang;
63
64 recvData >> type;
65 recvData >> lang;
66
67 if (type >= MAX_CHAT_MSG_TYPE)
68 {
69 LOG_ERROR("network.opcode", "CHAT: Wrong message type received: {}", type);
70 recvData.rfinish();
71 return;
72 }
73
74 if (lang == LANG_UNIVERSAL && type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
75 {
76 LOG_ERROR("entities.player.cheat", "CMSG_MESSAGECHAT: Possible hacking-attempt: {} tried to send a message in universal language", GetPlayerInfo());
78 recvData.rfinish();
79 return;
80 }
81
82 Player* sender = GetPlayer();
83
84 // prevent talking at unknown language (cheating)
85 LanguageDesc const* langDesc = GetLanguageDescByID(lang);
86 if (!langDesc)
87 {
89 recvData.rfinish();
90 return;
91 }
92
93 if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id))
94 {
95 // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language)
96 bool foundAura = false;
97 for (auto const& auraEff : sender->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE))
98 {
99 if (auraEff->GetMiscValue() == int32(lang))
100 {
101 foundAura = true;
102 break;
103 }
104 }
105
106 if (!foundAura)
107 {
109 recvData.rfinish();
110 return;
111 }
112 }
113
114 // pussywizard: chatting on most chat types requires 2 hours played to prevent spam/abuse
116 {
117 switch (type)
118 {
119 case CHAT_MSG_ADDON:
120 case CHAT_MSG_PARTY:
121 case CHAT_MSG_RAID:
122 case CHAT_MSG_GUILD:
123 case CHAT_MSG_OFFICER:
124 case CHAT_MSG_AFK:
125 case CHAT_MSG_DND:
131 break;
132 default:
133 {
134 if (sWorld->getBoolConfig(CONFIG_CHAT_MUTE_FIRST_LOGIN) && lang != LANG_ADDON)
135 {
136 uint32 minutes = sWorld->getIntConfig(CONFIG_CHAT_TIME_MUTE_FIRST_LOGIN);
137
138 if (sender->GetTotalPlayedTime() < minutes * MINUTE)
139 {
141 recvData.rfinish();
142 return;
143 }
144 }
145 }
146 }
147 }
148
149 // pussywizard:
150 switch (type)
151 {
152 case CHAT_MSG_SAY:
153 case CHAT_MSG_YELL:
154 case CHAT_MSG_EMOTE:
156 case CHAT_MSG_AFK:
157 case CHAT_MSG_DND:
158 if (sender->IsSpectator())
159 {
160 recvData.rfinish();
161 return;
162 }
163 }
164
165 if (sender->HasAura(1852) && type != CHAT_MSG_WHISPER)
166 {
168 recvData.rfinish();
169 return;
170 }
171
172 if (lang == LANG_ADDON)
173 {
174 // LANG_ADDON is only valid for the following message types
175 switch (type)
176 {
177 case CHAT_MSG_PARTY:
178 case CHAT_MSG_RAID:
179 case CHAT_MSG_GUILD:
181 case CHAT_MSG_WHISPER:
182 // check if addon messages are disabled
183 if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL))
184 {
185 recvData.rfinish();
186 return;
187 }
188 break;
189 default:
190 LOG_ERROR("network", "Player {} ({}) sent a chatmessage with an invalid language/message type combination",
191 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
192
193 recvData.rfinish();
194 return;
195 }
196 }
197 else
198 {
199 // send in universal language if player in .gmon mode (ignore spell effects)
200 if (sender->IsGameMaster())
201 lang = LANG_UNIVERSAL;
202 else
203 {
204 // send in universal language in two side iteration allowed mode
206 lang = LANG_UNIVERSAL;
207 else
208 {
209 switch (type)
210 {
211 case CHAT_MSG_PARTY:
213 case CHAT_MSG_RAID:
216 // allow two side chat at group channel if two side group allowed
218 lang = LANG_UNIVERSAL;
219 break;
220 case CHAT_MSG_GUILD:
221 case CHAT_MSG_OFFICER:
222 // allow two side chat at guild channel if two side guild allowed
224 lang = LANG_UNIVERSAL;
225 break;
226 }
227 }
228 // Overwritten by SPELL_AURA_MOD_LANGUAGE auras (Affects only Say and Yell)
230 if (!ModLangAuras.empty() && (type == CHAT_MSG_SAY || type == CHAT_MSG_YELL))
231 lang = ModLangAuras.front()->GetMiscValue();
232 }
233
234 if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
235 sender->UpdateSpeakTime(lang == LANG_ADDON ? Player::ChatFloodThrottle::ADDON : Player::ChatFloodThrottle::REGULAR);
236 }
237
238 std::string to, channel, msg;
239 bool ignoreChecks = false;
240 switch (type)
241 {
242 case CHAT_MSG_SAY:
243 case CHAT_MSG_EMOTE:
244 case CHAT_MSG_YELL:
245 case CHAT_MSG_PARTY:
247 case CHAT_MSG_GUILD:
248 case CHAT_MSG_OFFICER:
249 case CHAT_MSG_RAID:
254 msg = recvData.ReadCString(lang != LANG_ADDON);
255 break;
256 case CHAT_MSG_WHISPER:
257 recvData >> to;
258 msg = recvData.ReadCString(lang != LANG_ADDON);
259 break;
260 case CHAT_MSG_CHANNEL:
261 recvData >> channel;
262 msg = recvData.ReadCString(lang != LANG_ADDON);
263 break;
264 case CHAT_MSG_AFK:
265 case CHAT_MSG_DND:
266 msg = recvData.ReadCString(lang != LANG_ADDON);
267 ignoreChecks = true;
268 break;
269 }
270
271 // Our Warden module also uses SendAddonMessage as a way to communicate Lua check results to the server, see if this is that
272 if (type == CHAT_MSG_GUILD && lang == LANG_ADDON && _warden && _warden->ProcessLuaCheckResponse(msg))
273 {
274 return;
275 }
276
277 // pussywizard:
278 if (msg.length() > 255 || (lang != LANG_ADDON && msg.find("|0") != std::string::npos))
279 return;
280
281 if (!ignoreChecks)
282 {
283 if (msg.empty())
284 return;
285
286 if (lang == LANG_ADDON)
287 {
288 if (AddonChannelCommandHandler(this).ParseCommands(msg.c_str()))
289 return;
290 }
291 else
292 {
293 if (ChatHandler(this).ParseCommands(msg.c_str()))
294 return;
295
296 if (!_player->CanSpeak())
297 {
298 std::string timeStr = secsToTimeString(m_muteTime - GameTime::GetGameTime().count());
300 return;
301 }
302 }
303 }
304
305 // do message validity checks
306 if (lang != LANG_ADDON)
307 {
308 // cut at the first newline or carriage return
309 std::string::size_type pos = msg.find_first_of("\n\r");
310
311 if (pos == 0)
312 {
313 return;
314 }
315 else if (pos != std::string::npos)
316 {
317 msg.erase(pos);
318 }
319
320 // abort on any sort of nasty character
321 for (uint8 c : msg)
322 {
323 if (isNasty(c))
324 {
325 LOG_ERROR("network", "Player {} {} sent a message containing invalid character {} - blocked", GetPlayer()->GetName(),
326 GetPlayer()->GetGUID().ToString(), uint8(c));
327 return;
328 }
329 }
330
331 // collapse multiple spaces into one
333 {
334 auto end = std::unique(msg.begin(), msg.end(), [](char c1, char c2) { return (c1 == ' ') && (c2 == ' '); });
335 msg.erase(end, msg.end());
336 }
337
338 // Validate hyperlinks
340 {
341 return;
342 }
343 }
344
345 else
346 {
348 }
349
350 sScriptMgr->OnPlayerBeforeSendChatMessage(_player, type, lang, msg);
351
352 switch (type)
353 {
354 case CHAT_MSG_SAY:
355 case CHAT_MSG_EMOTE:
356 case CHAT_MSG_YELL:
357 {
358 // Prevent cheating
359 if (!sender->IsAlive())
360 return;
361
362 if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ))
363 {
365 return;
366 }
367
368 if (type == CHAT_MSG_SAY)
369 sender->Say(msg, Language(lang));
370 else if (type == CHAT_MSG_EMOTE)
371 sender->TextEmote(msg);
372 else if (type == CHAT_MSG_YELL)
373 sender->Yell(msg, Language(lang));
374 }
375 break;
376 case CHAT_MSG_WHISPER:
377 {
378 if (!normalizePlayerName(to))
379 {
381 break;
382 }
383
384 Player* receiver = ObjectAccessor::FindPlayerByName(to, false);
385 bool senderIsPlayer = AccountMgr::IsPlayerAccount(GetSecurity());
386 bool receiverIsPlayer = AccountMgr::IsPlayerAccount(receiver ? receiver->GetSession()->GetSecurity() : SEC_PLAYER);
387
388 if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) && receiver != sender && receiver && !receiver->IsGameMaster())
389 {
391 return;
392 }
393
394 if (!receiver || (senderIsPlayer && !receiverIsPlayer && !receiver->isAcceptWhispers() && !receiver->IsInWhisperWhiteList(sender->GetGUID())))
395 {
397 return;
398 }
399
400 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) && senderIsPlayer && receiverIsPlayer)
401 if (GetPlayer()->GetTeamId() != receiver->GetTeamId())
402 {
404 return;
405 }
406
407 // pussywizard: optimization
408 if (GetPlayer()->HasAura(1852) && !receiver->IsGameMaster())
409 {
411 return;
412 }
413
414 // If player is a Gamemaster and doesn't accept whisper, we auto-whitelist every player that the Gamemaster is talking to
415 if (!senderIsPlayer && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID()))
416 sender->AddWhisperWhiteList(receiver->GetGUID());
417
418 GetPlayer()->Whisper(msg, Language(lang), receiver);
419 }
420 break;
421 case CHAT_MSG_PARTY:
423 {
424 // if player is in battleground, he cannot say to battleground members by /p
425 Group* group = GetPlayer()->GetOriginalGroup();
426 if (!group)
427 {
428 group = sender->GetGroup();
429 if (!group || group->isBGGroup())
430 return;
431 }
432
433 if (type == CHAT_MSG_PARTY_LEADER && !group->IsLeader(sender->GetGUID()))
434 return;
435
436 if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
437 return;
438
439 WorldPacket data;
440 ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, nullptr, msg);
441 group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID()));
442 }
443 break;
444 case CHAT_MSG_GUILD:
445 {
446 if (GetPlayer()->GetGuildId())
447 {
448 if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
449 {
450 if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, guild))
451 return;
452
453 guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
454 }
455 }
456 }
457 break;
458 case CHAT_MSG_OFFICER:
459 {
460 if (GetPlayer()->GetGuildId())
461 {
462 if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
463 {
464 if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, guild))
465 return;
466
467 guild->BroadcastToGuild(this, true, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
468 }
469 }
470 }
471 break;
472 case CHAT_MSG_RAID:
473 {
474 // if player is in battleground, he cannot say to battleground members by /ra
475 Group* group = GetPlayer()->GetOriginalGroup();
476 if (!group)
477 {
478 group = GetPlayer()->GetGroup();
479 if (!group || group->isBGGroup() || !group->isRaidGroup())
480 return;
481 }
482
483 if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
484 return;
485
486 WorldPacket data;
487 ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), sender, nullptr, msg);
488 group->BroadcastPacket(&data, false);
489 }
490 break;
492 {
493 // if player is in battleground, he cannot say to battleground members by /ra
494 Group* group = GetPlayer()->GetOriginalGroup();
495 if (!group)
496 {
497 group = GetPlayer()->GetGroup();
498 if (!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(sender->GetGUID()))
499 return;
500 }
501
502 if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
503 return;
504
505 WorldPacket data;
506 ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), sender, nullptr, msg);
507 group->BroadcastPacket(&data, false);
508 }
509 break;
511 {
512 Group* group = GetPlayer()->GetGroup();
513 if (!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())) || group->isBGGroup())
514 return;
515
516 if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
517 return;
518
519 // In battleground, raid warning is sent only to players in battleground - code is ok
520 WorldPacket data;
521 ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_WARNING, Language(lang), sender, nullptr, msg);
522 group->BroadcastPacket(&data, false);
523 }
524 break;
526 {
527 //battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
528 Group* group = GetPlayer()->GetGroup();
529 if (!group || !group->isBGGroup())
530 return;
531
532 if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
533 return;
534
535 WorldPacket data;
536 ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), sender, nullptr, msg);
537 group->BroadcastPacket(&data, false);
538 }
539 break;
541 {
542 // battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
543 Group* group = GetPlayer()->GetGroup();
544 if (!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID()))
545 return;
546
547 if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
548 return;
549
550 WorldPacket data;
551 ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), sender, nullptr, msg);
552 group->BroadcastPacket(&data, false);
553 }
554 break;
555 case CHAT_MSG_CHANNEL:
556 {
558 {
559 if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ))
560 {
562 return;
563 }
564 }
565
566 if (ChannelMgr* cMgr = ChannelMgr::forTeam(sender->GetTeamId()))
567 {
568 if (Channel* chn = cMgr->GetChannel(channel, sender))
569 {
570 if (!sScriptMgr->OnPlayerCanUseChat(sender, type, lang, msg, chn))
571 return;
572
573 chn->Say(sender->GetGUID(), msg.c_str(), lang);
574 }
575 }
576 }
577 break;
578 case CHAT_MSG_AFK:
579 {
580 if (!sender->IsInCombat())
581 {
582 if (sender->isAFK()) // Already AFK
583 {
584 if (msg.empty())
585 sender->ToggleAFK(); // Remove AFK
586 else
587 sender->autoReplyMsg = msg; // Update message
588 }
589 else // New AFK mode
590 {
591 sender->autoReplyMsg = msg.empty() ? GetAcoreString(LANG_PLAYER_AFK_DEFAULT) : msg;
592
593 if (sender->isDND())
594 sender->ToggleDND();
595
596 sender->ToggleAFK();
597 }
598
599 if (!sScriptMgr->OnPlayerCanUseChat(sender, type, lang, msg))
600 return;
601 }
602 break;
603 }
604 case CHAT_MSG_DND:
605 {
606 if (sender->isDND()) // Already DND
607 {
608 if (msg.empty())
609 sender->ToggleDND(); // Remove DND
610 else
611 sender->autoReplyMsg = msg; // Update message
612 }
613 else // New DND mode
614 {
615 sender->autoReplyMsg = msg.empty() ? GetAcoreString(LANG_PLAYER_DND_DEFAULT) : msg;
616
617 if (sender->isAFK())
618 sender->ToggleAFK();
619
620 sender->ToggleDND();
621 }
622
623 if (!sScriptMgr->OnPlayerCanUseChat(sender, type, lang, msg))
624 return;
625
626 break;
627 }
628 default:
629 LOG_ERROR("network.opcode", "CHAT: unknown message type {}, lang: {}", type, lang);
630 break;
631 }
632}
bool isNasty(uint8 c)
Definition ChatHandler.cpp:44
@ SEC_PLAYER
Definition Common.h:57
@ LANG_SAY_REQ
Definition Language.h:1166
@ LANG_GM_SILENCE
Definition Language.h:1181
@ LANG_UNKNOWN_LANGUAGE
Definition Language.h:748
@ LANG_NOT_LEARNED_LANGUAGE
Definition Language.h:749
@ LANG_WHISPER_REQ
Definition Language.h:1167
@ LANG_WAIT_BEFORE_SPEAKING
Definition Language.h:676
@ LANG_PLAYER_AFK_DEFAULT
Definition Language.h:681
@ LANG_MUTED_PLAYER
Definition Language.h:1327
@ LANG_PLAYER_DND_DEFAULT
Definition Language.h:680
@ LANG_CHANNEL_REQ
Definition Language.h:1168
LanguageDesc const * GetLanguageDescByID(uint32 lang)
Definition ObjectMgr.cpp:253
ChatMsg
Definition SharedDefines.h:3400
@ CHAT_MSG_RAID_WARNING
Definition SharedDefines.h:3442
@ CHAT_MSG_RAID
Definition SharedDefines.h:3405
@ CHAT_MSG_TEXT_EMOTE
Definition SharedDefines.h:3413
@ CHAT_MSG_SAY
Definition SharedDefines.h:3403
@ CHAT_MSG_PARTY_LEADER
Definition SharedDefines.h:3453
@ CHAT_MSG_RAID_LEADER
Definition SharedDefines.h:3441
@ CHAT_MSG_DND
Definition SharedDefines.h:3426
@ CHAT_MSG_YELL
Definition SharedDefines.h:3408
@ CHAT_MSG_PARTY
Definition SharedDefines.h:3404
@ CHAT_MSG_WHISPER
Definition SharedDefines.h:3409
@ CHAT_MSG_EMOTE
Definition SharedDefines.h:3412
@ CHAT_MSG_GUILD
Definition SharedDefines.h:3406
@ CHAT_MSG_OFFICER
Definition SharedDefines.h:3407
@ CHAT_MSG_AFK
Definition SharedDefines.h:3425
@ CHAT_MSG_ADDON
Definition SharedDefines.h:3401
@ CHAT_MSG_BATTLEGROUND
Definition SharedDefines.h:3446
@ CHAT_MSG_BATTLEGROUND_LEADER
Definition SharedDefines.h:3447
@ CHAT_MSG_CHANNEL
Definition SharedDefines.h:3419
Language
Definition SharedDefines.h:745
@ LANG_ADDON
Definition SharedDefines.h:764
#define MAX_CHAT_MSG_TYPE
Definition SharedDefines.h:3456
@ SPELL_AURA_COMPREHEND_LANGUAGE
Definition SpellAuraDefines.h:307
@ SPELL_AURA_MOD_LANGUAGE
Definition SpellAuraDefines.h:138
std::string secsToTimeString(uint64 timeInSecs, bool shortText)
Definition Util.cpp:73
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT
Definition WorldConfig.h:32
@ CONFIG_CHAT_MUTE_FIRST_LOGIN
Definition WorldConfig.h:61
@ CONFIG_CHAT_FAKE_MESSAGE_PREVENTING
Definition WorldConfig.h:60
@ CONFIG_ADDON_CHANNEL
Definition WorldConfig.h:26
@ CONFIG_CHAT_CHANNEL_LEVEL_REQ
Definition WorldConfig.h:244
@ CONFIG_CHAT_WHISPER_LEVEL_REQ
Definition WorldConfig.h:245
@ CONFIG_CHAT_TIME_MUTE_FIRST_LOGIN
Definition WorldConfig.h:248
@ CONFIG_CHAT_SAY_LEVEL_REQ
Definition WorldConfig.h:246
Definition Chat.h:278
void BroadcastPacket(WorldPacket const *packet, bool ignorePlayersInBGRaid, int group=-1, ObjectGuid ignore=ObjectGuid::Empty)
Definition Group.cpp:1757
bool CanSpeak() const
Definition PlayerMisc.cpp:69
bool IsInWhisperWhiteList(ObjectGuid guid)
Definition Player.cpp:15999
std::string autoReplyMsg
Definition Player.h:1139
uint32 GetTotalPlayedTime()
Definition Player.h:1192
bool HasSkill(uint32 skill) const
Definition Player.cpp:5499
void ToggleAFK()
Definition Player.cpp:1310
void UpdateSpeakTime(ChatFloodThrottle::Index index)
Definition PlayerMisc.cpp:29
void AddWhisperWhiteList(ObjectGuid guid)
Definition Player.h:2575
bool isAcceptWhispers() const
Definition Player.h:1159
void Yell(std::string_view text, Language language, WorldObject const *=nullptr) override
Handles yelled message in regular chat based on declared language and in config pre-defined Range.
Definition Player.cpp:9449
void Say(std::string_view text, Language language, WorldObject const *=nullptr) override
Handles said message in regular chat based on declared language and in config pre-defined Range.
Definition Player.cpp:9428
void TextEmote(std::string_view text, WorldObject const *=nullptr, bool=false) override
Outputs an universal text which is supposed to be an action.
Definition Player.cpp:9471
void Whisper(std::string_view text, Language language, Player *receiver, bool=false) override
Handles whispers from Addons and players based on sender, receiver's guid and language.
Definition Player.cpp:9493
void ToggleDND()
Definition Player.cpp:1319
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1413
std::vector< AuraEffect * > AuraEffectList
Definition Unit.h:671
void SendPlayerNotFoundNotice(std::string const &name)
Definition ChatHandler.cpp:773
void SendWrongFactionNotice()
Definition ChatHandler.cpp:787
std::unique_ptr< Warden > _warden
Definition WorldSession.h:1217
Definition ObjectMgr.h:691
uint32 skill_id
Definition ObjectMgr.h:694
@ ADDON
Definition Player.h:2332

References _addonMessageReceiveCount, _player, _warden, Player::ChatFloodThrottle::ADDON, Player::AddWhisperWhiteList(), Player::autoReplyMsg, Group::BroadcastPacket(), ChatHandler::BuildChatPacket(), Player::CanSpeak(), CHAT_MSG_ADDON, CHAT_MSG_AFK, CHAT_MSG_BATTLEGROUND, CHAT_MSG_BATTLEGROUND_LEADER, CHAT_MSG_CHANNEL, CHAT_MSG_DND, CHAT_MSG_EMOTE, CHAT_MSG_GUILD, CHAT_MSG_OFFICER, CHAT_MSG_PARTY, CHAT_MSG_PARTY_LEADER, CHAT_MSG_RAID, CHAT_MSG_RAID_LEADER, CHAT_MSG_RAID_WARNING, CHAT_MSG_SAY, CHAT_MSG_TEXT_EMOTE, CHAT_MSG_WHISPER, CHAT_MSG_YELL, CONFIG_ADDON_CHANNEL, CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT, CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP, CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD, CONFIG_CHAT_CHANNEL_LEVEL_REQ, CONFIG_CHAT_FAKE_MESSAGE_PREVENTING, CONFIG_CHAT_MUTE_FIRST_LOGIN, CONFIG_CHAT_SAY_LEVEL_REQ, CONFIG_CHAT_TIME_MUTE_FIRST_LOGIN, CONFIG_CHAT_WHISPER_LEVEL_REQ, ObjectAccessor::FindPlayerByName(), ChannelMgr::forTeam(), GetAcoreString(), Unit::GetAuraEffectsByType(), GameTime::GetGameTime(), Player::GetGroup(), Object::GetGUID(), Player::GetGuildId(), GetLanguageDescByID(), Unit::GetLevel(), Group::GetMemberGroup(), WorldObject::GetName(), Player::GetOriginalGroup(), GetPlayer(), GetPlayerInfo(), GetSecurity(), Player::GetSession(), Player::GetTeamId(), GetTeamId(), Player::GetTotalPlayedTime(), Unit::HasAura(), Player::HasSkill(), Player::isAcceptWhispers(), Player::isAFK(), Unit::IsAlive(), Group::IsAssistant(), Group::isBGGroup(), Player::isDND(), Player::IsGameMaster(), Unit::IsInCombat(), Player::IsInWhisperWhiteList(), Group::IsLeader(), isNasty(), AccountMgr::IsPlayerAccount(), Group::isRaidGroup(), Player::IsSpectator(), LANG_ADDON, LANG_CHANNEL_REQ, LANG_GM_SILENCE, LANG_MUTED_PLAYER, LANG_NOT_LEARNED_LANGUAGE, LANG_PLAYER_AFK_DEFAULT, LANG_PLAYER_DND_DEFAULT, LANG_SAY_REQ, LANG_UNIVERSAL, LANG_UNKNOWN_LANGUAGE, LANG_WAIT_BEFORE_SPEAKING, LANG_WHISPER_REQ, LOG_ERROR, m_muteTime, MAX_CHAT_MSG_TYPE, MINUTE, normalizePlayerName(), AddonChannelCommandHandler::ParseCommands(), ChatHandler::ParseCommands(), ByteBuffer::ReadCString(), Player::ChatFloodThrottle::REGULAR, ByteBuffer::rfinish(), Player::Say(), SEC_PLAYER, secsToTimeString(), ChatHandler::SendNotification(), SendPlayerNotFoundNotice(), SendWrongFactionNotice(), sGuildMgr, LanguageDesc::skill_id, SPELL_AURA_COMPREHEND_LANGUAGE, SPELL_AURA_MOD_LANGUAGE, sScriptMgr, sWorld, Player::TextEmote(), Player::ToggleAFK(), Player::ToggleDND(), Player::UpdateSpeakTime(), ValidateHyperlinksAndMaybeKick(), Player::Whisper(), and Player::Yell().

Referenced by OpcodeTable::Initialize().

◆ HandleMinimapPingOpcode()

void WorldSession::HandleMinimapPingOpcode ( WorldPackets::Misc::MinimapPingClient packet)
527{
528 if (!sMapMgr->IsValidMapCoord(GetPlayer()->GetMap()->GetId(), packet.MapX, packet.MapY))
529 return;
530
531 Group* group = GetPlayer()->GetGroup();
532
533 if (!group)
534 return;
535
536 group->DoMinimapPing(GetPlayer()->GetGUID(), packet.MapX, packet.MapY);
537}
void DoMinimapPing(ObjectGuid sourceGuid, float mapX, float mapY)
Definition Group.cpp:2063
float MapY
Definition MiscPackets.h:104
float MapX
Definition MiscPackets.h:103
uint32 GetId(std::string const &username)
Definition AccountMgr.cpp:236

References Group::DoMinimapPing(), Player::GetGroup(), GetPlayer(), WorldPackets::Misc::MinimapPingClient::MapX, WorldPackets::Misc::MinimapPingClient::MapY, and sMapMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleMirrorImageDataRequest()

void WorldSession::HandleMirrorImageDataRequest ( WorldPacket recvData)
738{
739 LOG_DEBUG("network", "WORLD: CMSG_GET_MIRRORIMAGE_DATA");
740 ObjectGuid guid;
741 recvData >> guid;
742
743 // Get unit for which data is needed by client
744 Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
745 if (!unit)
746 return;
747
748 if (!unit->HasCloneCasterAura())
749 return;
750
751 // Get creator of the unit (SPELL_AURA_CLONE_CASTER does not stack)
752 Unit* creator = unit->GetAuraEffectsByType(SPELL_AURA_CLONE_CASTER).front()->GetCaster();
753 if (!creator)
754 return;
755
757 data << guid;
758 data << uint32(creator->GetDisplayId());
759 data << uint8(creator->getRace());
760 data << uint8(creator->getGender());
761 data << uint8(creator->getClass());
762
763 if (creator->IsPlayer())
764 {
765 Player* player = creator->ToPlayer();
766 data << uint8(player->GetByteValue(PLAYER_BYTES, 0)); // skin
767 data << uint8(player->GetByteValue(PLAYER_BYTES, 1)); // face
768 data << uint8(player->GetByteValue(PLAYER_BYTES, 2)); // hair
769 data << uint8(player->GetByteValue(PLAYER_BYTES, 3)); // haircolor
770 data << uint8(player->GetByteValue(PLAYER_BYTES_2, 0)); // facialhair
771 data << uint32(player->GetGuildId()); // unk
772
773 static EquipmentSlots const itemSlots[] =
774 {
787 };
788
789 // Display items in visible slots
790 for (EquipmentSlots const* itr = &itemSlots[0]; *itr != EQUIPMENT_SLOT_END; ++itr)
791 {
793 data << uint32(0);
794 else if (*itr == EQUIPMENT_SLOT_BACK && player->HasPlayerFlag(PLAYER_FLAGS_HIDE_CLOAK))
795 data << uint32(0);
796 else if (Item const* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, *itr))
797 {
798 uint32 displayInfoId = item->GetTemplate()->DisplayInfoID;
799
800 sScriptMgr->OnGlobalMirrorImageDisplayItem(item, displayInfoId);
801
802 data << uint32(displayInfoId);
803 }
804 else
805 data << uint32(0);
806 }
807 }
808 else
809 {
810 // Skip player data for creatures
811 data << uint8(0);
812 data << uint32(0);
813 data << uint32(0);
814 data << uint32(0);
815 data << uint32(0);
816 data << uint32(0);
817 data << uint32(0);
818 data << uint32(0);
819 data << uint32(0);
820 data << uint32(0);
821 data << uint32(0);
822 data << uint32(0);
823 data << uint32(0);
824 data << uint32(0);
825 }
826
827 SendPacket(&data);
828}
@ PLAYER_FLAGS_HIDE_CLOAK
Definition Player.h:479
@ PLAYER_FLAGS_HIDE_HELM
Definition Player.h:478
EquipmentSlots
Definition Player.h:668
@ EQUIPMENT_SLOT_SHOULDERS
Definition Player.h:672
@ EQUIPMENT_SLOT_BODY
Definition Player.h:673
@ EQUIPMENT_SLOT_HANDS
Definition Player.h:679
@ EQUIPMENT_SLOT_TABARD
Definition Player.h:688
@ EQUIPMENT_SLOT_HEAD
Definition Player.h:670
@ EQUIPMENT_SLOT_LEGS
Definition Player.h:676
@ EQUIPMENT_SLOT_BACK
Definition Player.h:684
@ EQUIPMENT_SLOT_WAIST
Definition Player.h:675
@ EQUIPMENT_SLOT_FEET
Definition Player.h:677
@ EQUIPMENT_SLOT_CHEST
Definition Player.h:674
@ EQUIPMENT_SLOT_WRISTS
Definition Player.h:678
@ SPELL_AURA_CLONE_CASTER
Definition SpellAuraDefines.h:310
uint8 GetByteValue(uint16 index, uint8 offset) const
Definition Object.cpp:312
uint8 getClass() const
Definition Unit.h:833
bool HasCloneCasterAura() const
Definition Unit.h:1795
@ SMSG_MIRRORIMAGE_DATA
Definition Opcodes.h:1056

References _player, EQUIPMENT_SLOT_BACK, EQUIPMENT_SLOT_BODY, EQUIPMENT_SLOT_CHEST, EQUIPMENT_SLOT_END, EQUIPMENT_SLOT_FEET, EQUIPMENT_SLOT_HANDS, EQUIPMENT_SLOT_HEAD, EQUIPMENT_SLOT_LEGS, EQUIPMENT_SLOT_SHOULDERS, EQUIPMENT_SLOT_TABARD, EQUIPMENT_SLOT_WAIST, EQUIPMENT_SLOT_WRISTS, Unit::GetAuraEffectsByType(), Object::GetByteValue(), Unit::getClass(), Unit::GetDisplayId(), Unit::getGender(), Player::GetGuildId(), Player::GetItemByPos(), Unit::getRace(), ObjectAccessor::GetUnit(), Unit::HasCloneCasterAura(), Player::HasPlayerFlag(), INVENTORY_SLOT_BAG_0, Object::IsPlayer(), LOG_DEBUG, PLAYER_BYTES, PLAYER_BYTES_2, PLAYER_FLAGS_HIDE_CLOAK, PLAYER_FLAGS_HIDE_HELM, SendPacket(), SMSG_MIRRORIMAGE_DATA, SPELL_AURA_CLONE_CASTER, sScriptMgr, and Object::ToPlayer().

Referenced by OpcodeTable::Initialize().

◆ HandleMountSpecialAnimOpcode()

void WorldSession::HandleMountSpecialAnimOpcode ( WorldPacket recvdata)
799{
801 data << GetPlayer()->GetGUID();
802
803 GetPlayer()->SendMessageToSet(&data, false);
804}
void SendMessageToSet(WorldPacket const *data, bool self) const override
Definition Player.cpp:5739
@ SMSG_MOUNTSPECIAL_ANIM
Definition Opcodes.h:400

References Object::GetGUID(), GetPlayer(), Player::SendMessageToSet(), and SMSG_MOUNTSPECIAL_ANIM.

Referenced by OpcodeTable::Initialize().

◆ HandleMoveFlagChangeOpcode()

void WorldSession::HandleMoveFlagChangeOpcode ( WorldPacket recvData)
1491{
1492 LOG_DEBUG("network", "WORLD: {}", GetOpcodeNameForLogging((Opcodes)recv_data.GetOpcode()));
1493
1494 Opcodes opcode = (Opcodes)recv_data.GetOpcode();
1495
1496 ObjectGuid guid;
1497 uint32 counter;
1498 uint32 isApplied;
1499 recv_data >> guid.ReadAsPacked();
1500
1501 if (!_player)
1502 {
1503 recv_data.rfinish(); // prevent warnings spam
1504 return;
1505 }
1506
1507 recv_data >> counter;
1508
1509 MovementInfo movementInfo;
1510 movementInfo.guid = guid;
1511 ReadMovementInfo(recv_data, &movementInfo);
1512
1514 recv_data >> isApplied;
1515
1516 sScriptMgr->AnticheatSetCanFlybyServer(_player, movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY));
1517
1518 Unit* mover = _player->m_mover;
1519 Player* plrMover = mover->ToPlayer();
1520
1521 mover->m_movementInfo.flags = movementInfo.GetMovementFlags();
1522
1523 // old map - async processing, ignore
1524 if (counter <= _player->GetMapChangeOrderCounter())
1525 return;
1526
1527 if (!ProcessMovementInfo(movementInfo, mover, plrMover, recv_data))
1528 {
1529 recv_data.rfinish(); // prevent warnings spam
1530 return;
1531 }
1532
1533 if (_player->GetPendingFlightChange() == counter && opcode == CMSG_MOVE_SET_CAN_FLY_ACK)
1535
1536 Opcodes response;
1537
1538 switch (recv_data.GetOpcode())
1539 {
1540 case CMSG_MOVE_HOVER_ACK: response = MSG_MOVE_HOVER; break;
1541 case CMSG_MOVE_FEATHER_FALL_ACK: response = MSG_MOVE_FEATHER_FALL; break;
1542 case CMSG_MOVE_WATER_WALK_ACK: response = MSG_MOVE_WATER_WALK; break;
1543 case CMSG_MOVE_SET_CAN_FLY_ACK: response = MSG_MOVE_UPDATE_CAN_FLY; break;
1546 default: return;
1547 }
1548
1549 WorldPacket data(response, 8);
1550 WriteMovementInfo(&data, &movementInfo);
1552}
@ MOVEMENTFLAG_CAN_FLY
Definition UnitDefines.h:393
void SetPendingFlightChange(uint32 counter)
Definition Player.h:2650
uint32 GetPendingFlightChange() const
Definition Player.h:2649
@ MSG_MOVE_HOVER
Definition Opcodes.h:277
@ CMSG_MOVE_GRAVITY_ENABLE_ACK
Definition Opcodes.h:1263
@ CMSG_MOVE_SET_CAN_FLY_ACK
Definition Opcodes.h:867
@ MSG_MOVE_UPDATE_CAN_FLY
Definition Opcodes.h:971
@ MSG_MOVE_WATER_WALK
Definition Opcodes.h:719
@ CMSG_MOVE_FEATHER_FALL_ACK
Definition Opcodes.h:749
@ CMSG_MOVE_WATER_WALK_ACK
Definition Opcodes.h:750
@ CMSG_MOVE_HOVER_ACK
Definition Opcodes.h:276
@ MSG_MOVE_FEATHER_FALL
Definition Opcodes.h:718
@ CMSG_MOVE_GRAVITY_DISABLE_ACK
Definition Opcodes.h:1261
@ MSG_MOVE_GRAVITY_CHNG
Definition Opcodes.h:1264
uint32 flags
Definition Object.h:290
bool HasMovementFlag(uint32 flag) const
Definition Object.h:345
uint32 GetMovementFlags() const
Definition Object.h:341

References _player, CMSG_MOVE_FEATHER_FALL_ACK, CMSG_MOVE_GRAVITY_DISABLE_ACK, CMSG_MOVE_GRAVITY_ENABLE_ACK, CMSG_MOVE_HOVER_ACK, CMSG_MOVE_SET_CAN_FLY_ACK, CMSG_MOVE_WATER_WALK_ACK, MovementInfo::flags, MovementInfo::GetMovementFlags(), WorldPacket::GetOpcode(), GetOpcodeNameForLogging(), Player::GetPendingFlightChange(), MovementInfo::guid, MovementInfo::HasMovementFlag(), LOG_DEBUG, WorldObject::m_movementInfo, Player::m_mover, MOVEMENTFLAG_CAN_FLY, MSG_MOVE_FEATHER_FALL, MSG_MOVE_GRAVITY_CHNG, MSG_MOVE_HOVER, MSG_MOVE_UPDATE_CAN_FLY, MSG_MOVE_WATER_WALK, ProcessMovementInfo(), ObjectGuid::ReadAsPacked(), ReadMovementInfo(), ByteBuffer::rfinish(), WorldObject::SendMessageToSet(), Player::SetPendingFlightChange(), sScriptMgr, Object::ToPlayer(), and WriteMovementInfo().

Referenced by OpcodeTable::Initialize().

◆ HandleMoveKnockBackAck()

void WorldSession::HandleMoveKnockBackAck ( WorldPacket recvPacket)
807{
808 LOG_DEBUG("network", "CMSG_MOVE_KNOCK_BACK_ACK");
809
810 Unit* mover = _player->m_mover;
811
812 ObjectGuid guid;
813 recvData >> guid.ReadAsPacked();
814
815 // pussywizard: typical check for incomming movement packets
816 if (!mover || !mover->IsInWorld() || mover->IsDuringRemoveFromWorld() || guid != mover->GetGUID())
817 {
818 recvData.rfinish(); // prevent warnings spam
819 return;
820 }
821
822 recvData.read_skip<uint32>(); // unk
823
824 MovementInfo movementInfo;
825 movementInfo.guid = guid;
826 ReadMovementInfo(recvData, &movementInfo);
827
828 mover->m_movementInfo = movementInfo;
829
830 if (mover->IsPlayer() && static_cast<Player*>(mover)->IsFreeFlying())
831 mover->SetCanFly(true);
832
834 data << guid.WriteAsPacked();
836 _player->SetCanTeleport(true);
837 // knockback specific info
838 data << movementInfo.jump.sinAngle;
839 data << movementInfo.jump.cosAngle;
840 data << movementInfo.jump.xyspeed;
841 data << movementInfo.jump.zspeed;
842
843 _player->SendMessageToSet(&data, false);
844}
bool IsFreeFlying() const
Definition Player.h:2581
void SetCanFly(bool enable)
Add the movement flag: MOVEMENTFLAGCAN_FLY. Generaly only use by players, allowing them to fly by pre...
Definition Unit.cpp:20607
void BuildMovementPacket(ByteBuffer *data) const
Definition Unit.cpp:19875
@ MSG_MOVE_KNOCK_BACK
Definition Opcodes.h:271

References _player, Unit::BuildMovementPacket(), Object::GetGUID(), MovementInfo::guid, Unit::IsDuringRemoveFromWorld(), Player::IsFreeFlying(), Object::IsInWorld(), Object::IsPlayer(), LOG_DEBUG, WorldObject::m_movementInfo, Player::m_mover, MSG_MOVE_KNOCK_BACK, ByteBuffer::read_skip(), ObjectGuid::ReadAsPacked(), ReadMovementInfo(), ByteBuffer::rfinish(), Player::SendMessageToSet(), Unit::SetCanFly(), Player::SetCanTeleport(), and ObjectGuid::WriteAsPacked().

Referenced by OpcodeTable::Initialize().

◆ HandleMovementOpcodes()

void WorldSession::HandleMovementOpcodes ( WorldPacket recvPacket)
344{
345 uint16 opcode = recvData.GetOpcode();
346
347 Unit* mover = _player->m_mover;
348
349 ASSERT(mover); // there must always be a mover
350
351 Player* plrMover = mover->ToPlayer();
352
353 // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck
354 if (plrMover && plrMover->IsBeingTeleported())
355 {
356 recvData.rfinish(); // prevent warnings spam
357 return;
358 }
359
360 /* extract packet */
361 ObjectGuid guid;
362 recvData >> guid.ReadAsPacked();
363
364 // prevent tampered movement data
365 if (!guid || guid != mover->GetGUID())
366 {
367 recvData.rfinish(); // prevent warnings spam
368 return;
369 }
370
371 // pussywizard: typical check for incomming movement packets | prevent tampered movement data
372 if (!mover || !(mover->IsInWorld()) || mover->IsDuringRemoveFromWorld() || guid != mover->GetGUID())
373 {
374 recvData.rfinish(); // prevent warnings spam
375 return;
376 }
377
378 MovementInfo movementInfo;
379 movementInfo.guid = guid;
380 ReadMovementInfo(recvData, &movementInfo);
381
382 if (!ProcessMovementInfo(movementInfo, mover, plrMover, recvData))
383 {
384 recvData.rfinish(); // prevent warnings spam
385 return;
386 }
387
388 if (opcode == CMSG_MOVE_FALL_RESET || opcode == CMSG_MOVE_CHNG_TRANSPORT)
389 return;
390
391 /* process position-change */
392 WorldPacket data(opcode, recvData.size());
393 WriteMovementInfo(&data, &movementInfo);
394 mover->SendMessageToSet(&data, _player);
395}
bool IsBeingTeleported() const
Definition Player.h:2088
@ CMSG_MOVE_FALL_RESET
Definition Opcodes.h:744
@ CMSG_MOVE_CHNG_TRANSPORT
Definition Opcodes.h:939

References _player, ASSERT, CMSG_MOVE_CHNG_TRANSPORT, CMSG_MOVE_FALL_RESET, Object::GetGUID(), WorldPacket::GetOpcode(), MovementInfo::guid, Player::IsBeingTeleported(), Unit::IsDuringRemoveFromWorld(), Object::IsInWorld(), Player::m_mover, ProcessMovementInfo(), ObjectGuid::ReadAsPacked(), ReadMovementInfo(), ByteBuffer::rfinish(), WorldObject::SendMessageToSet(), ByteBuffer::size(), Object::ToPlayer(), and WriteMovementInfo().

Referenced by HandleClientCastFlags(), HandleUpdateMissileTrajectory(), and OpcodeTable::Initialize().

◆ HandleMoveNotActiveMover()

void WorldSession::HandleMoveNotActiveMover ( WorldPacket recvData)
778{
779 LOG_DEBUG("network", "WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER");
780
781 ObjectGuid old_mover_guid;
782 recvData >> old_mover_guid.ReadAsPacked();
783
784 // pussywizard: typical check for incomming movement packets
786 {
787 recvData.rfinish(); // prevent warnings spam
788 return;
789 }
790
791 MovementInfo mi;
792 mi.guid = old_mover_guid;
793 ReadMovementInfo(recvData, &mi);
794
796}

References _player, Object::GetGUID(), MovementInfo::guid, Unit::IsDuringRemoveFromWorld(), Object::IsInWorld(), LOG_DEBUG, WorldObject::m_movementInfo, Player::m_mover, ObjectGuid::ReadAsPacked(), ReadMovementInfo(), and ByteBuffer::rfinish().

Referenced by OpcodeTable::Initialize().

◆ HandleMoveRootAck()

void WorldSession::HandleMoveRootAck ( WorldPacket recvPacket)
974{
975 Opcodes opcode = (Opcodes)recvData.GetOpcode();
976 LOG_DEBUG("network", "WORLD: {}", GetOpcodeNameForLogging(opcode));
977
978 ObjectGuid guid;
979 uint32 counter;
980 MovementInfo movementInfo;
981 recvData >> guid.ReadAsPacked();
982 recvData >> counter;
983 movementInfo.guid = guid;
984 ReadMovementInfo(recvData, &movementInfo);
985
986 Unit* mover = _player->m_mover;
987
988 if (mover->GetGUID() != guid)
989 return;
990
991 if (opcode == CMSG_FORCE_MOVE_UNROOT_ACK) // unroot case
992 {
994 return;
995 }
996 else // root case
997 {
999 return;
1000 }
1001
1002 // old map - async processing, ignore
1003 if (counter <= _player->GetMapChangeOrderCounter())
1004 return;
1005
1006 if (!ProcessMovementInfo(movementInfo, mover, _player, recvData))
1007 return;
1008
1010 return;
1011
1013 WriteMovementInfo(&data, &movementInfo);
1014 mover->SendMessageToSet(&data, _player);
1015}
bool IsExpectingChangeTransport() const
Definition Player.h:2646
@ MSG_MOVE_ROOT
Definition Opcodes.h:266
@ CMSG_FORCE_MOVE_UNROOT_ACK
Definition Opcodes.h:265
@ MSG_MOVE_UNROOT
Definition Opcodes.h:267

References _player, CMSG_FORCE_MOVE_UNROOT_ACK, Object::GetGUID(), WorldPacket::GetOpcode(), GetOpcodeNameForLogging(), MovementInfo::guid, MovementInfo::HasMovementFlag(), Player::IsExpectingChangeTransport(), LOG_DEBUG, WorldObject::m_movementInfo, Player::m_mover, MOVEMENTFLAG_ROOT, MSG_MOVE_ROOT, MSG_MOVE_UNROOT, ProcessMovementInfo(), ObjectGuid::ReadAsPacked(), ReadMovementInfo(), WorldObject::SendMessageToSet(), and WriteMovementInfo().

Referenced by OpcodeTable::Initialize().

◆ HandleMoverRelocation()

void WorldSession::HandleMoverRelocation ( MovementInfo movementInfo,
Unit mover 
)
412{
413 SynchronizeMovement(movementInfo);
414
415 mover->UpdatePosition(movementInfo.pos);
416 mover->m_movementInfo = movementInfo;
417
419 {
420 // if we boarded a transport, add us to it (generalized for both players and creatures)
421 if (!mover->GetTransport())
422 {
423 if (Transport* transport = mover->GetMap()->GetTransport(movementInfo.transport.guid))
424 {
425 mover->SetTransport(transport);
426 transport->AddPassenger(mover);
427 }
428 }
429 else if (mover->GetTransport()->GetGUID() != movementInfo.transport.guid)
430 {
431 // Switching transports
432 bool foundNewTransport = false;
433 mover->GetTransport()->RemovePassenger(mover);
434 if (Transport* transport = mover->GetMap()->GetTransport(movementInfo.transport.guid))
435 {
436 foundNewTransport = true;
437 mover->SetTransport(transport);
438 transport->AddPassenger(mover);
439 }
440
441 if (!foundNewTransport)
442 {
443 mover->SetTransport(nullptr);
444 movementInfo.transport.Reset();
445 }
446 }
447
448 if (!mover->GetTransport() && !mover->GetVehicle())
449 {
450 GameObject* go = mover->GetMap()->GetGameObject(movementInfo.transport.guid);
451 if (!go || go->GetGoType() != GAMEOBJECT_TYPE_TRANSPORT)
453 }
454 }
455 else
456 {
457 // if we were on a transport, leave (handles both players and creatures)
458 if (Transport* transport = mover->GetTransport())
459 {
460 if (mover->IsPlayer())
461 sScriptMgr->AnticheatSetUnderACKmount(mover->ToPlayer()); // just for safe
462
463 transport->RemovePassenger(mover);
464 mover->SetTransport(nullptr);
465 movementInfo.transport.Reset();
466 }
467 }
468
469 // Some vehicles allow the passenger to turn by himself
470 if (Vehicle* vehicle = mover->GetVehicle())
471 {
472 if (VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(mover))
473 {
474 if (seat->m_flags & VEHICLE_SEAT_FLAG_ALLOW_TURNING && movementInfo.pos.GetOrientation() != mover->GetOrientation())
475 {
476 mover->SetOrientation(movementInfo.pos.GetOrientation());
478 }
479 }
480 }
481
482 if (Player* plrMover = mover->ToPlayer()) // nothing is charmed, or player charmed
483 {
484 if (plrMover->IsSitState() && (movementInfo.flags & (MOVEMENTFLAG_MASK_MOVING | MOVEMENTFLAG_MASK_TURNING)))
485 plrMover->SetStandState(UNIT_STAND_STATE_STAND);
486
487 if (movementInfo.pos.GetPositionZ() < plrMover->GetMap()->GetMinHeight(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY()))
488 {
489 if (!plrMover->GetBattleground() || !plrMover->GetBattleground()->HandlePlayerUnderMap(_player))
490 {
491 if (plrMover->IsAlive())
492 {
493 plrMover->SetPlayerFlag(PLAYER_FLAGS_IS_OUT_OF_BOUNDS);
494 plrMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
495 // player can be alive if GM
496 if (plrMover->IsAlive())
497 plrMover->KillPlayer();
498 }
499 else if (!plrMover->HasPlayerFlag(PLAYER_FLAGS_IS_OUT_OF_BOUNDS))
500 {
501 GraveyardStruct const* grave = sGraveyard->GetClosestGraveyard(plrMover, plrMover->GetTeamId());
502 if (grave)
503 {
504 plrMover->TeleportTo(grave->Map, grave->x, grave->y, grave->z, plrMover->GetOrientation());
505 plrMover->Relocate(grave->x, grave->y, grave->z, plrMover->GetOrientation());
506 }
507 }
508 }
509 }
510 }
511}
@ VEHICLE_SEAT_FLAG_ALLOW_TURNING
Definition DBCEnums.h:454
#define sGraveyard
Definition GameGraveyard.h:74
@ DAMAGE_FALL_TO_VOID
Definition Player.h:835
@ PLAYER_FLAGS_IS_OUT_OF_BOUNDS
Definition Player.h:482
@ GAMEOBJECT_TYPE_TRANSPORT
Definition SharedDefines.h:1582
@ AURA_INTERRUPT_FLAG_TURNING
Definition SpellDefines.h:47
@ MOVEMENTFLAG_ONTRANSPORT
Definition UnitDefines.h:378
@ MOVEMENTFLAG_MASK_MOVING
Definition UnitDefines.h:402
@ MOVEMENTFLAG_MASK_TURNING
Definition UnitDefines.h:407
Transport * GetTransport(ObjectGuid const &guid)
Definition Map.cpp:2372
Definition Transport.h:30
virtual void RemovePassenger(WorldObject *passenger, bool withAll=false)=0
virtual bool UpdatePosition(float x, float y, float z, float ang, bool teleport=false)
Definition Unit.cpp:20000
void SetTransport(Transport *t)
Definition Object.h:690
void SynchronizeMovement(MovementInfo &movementInfo)
Definition MovementHandler.cpp:397
Definition GameGraveyard.h:27
float z
Definition GameGraveyard.h:32
float x
Definition GameGraveyard.h:30
float y
Definition GameGraveyard.h:31
uint32 Map
Definition GameGraveyard.h:29
void Reset()
Definition Object.h:298
ObjectGuid guid
Definition Object.h:307
void RemoveMovementFlag(uint32 flag)
Definition Object.h:344
Position pos
Definition Object.h:292
void SetOrientation(float orientation)
Definition Position.h:116

References _player, AURA_INTERRUPT_FLAG_TURNING, DAMAGE_FALL_TO_VOID, MovementInfo::flags, GAMEOBJECT_TYPE_TRANSPORT, Map::GetGameObject(), GameObject::GetGoType(), Object::GetGUID(), WorldObject::GetMap(), Position::GetOrientation(), GetPlayer(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldObject::GetTransport(), Map::GetTransport(), Unit::GetVehicle(), MovementInfo::TransportInfo::guid, MovementInfo::HasMovementFlag(), Object::IsPlayer(), WorldObject::m_movementInfo, GraveyardStruct::Map, MOVEMENTFLAG_MASK_MOVING, MOVEMENTFLAG_MASK_TURNING, MOVEMENTFLAG_ONTRANSPORT, PLAYER_FLAGS_IS_OUT_OF_BOUNDS, MovementInfo::pos, Unit::RemoveAurasWithInterruptFlags(), MovementInfo::RemoveMovementFlag(), Transport::RemovePassenger(), MovementInfo::TransportInfo::Reset(), Position::SetOrientation(), WorldObject::SetTransport(), sGraveyard, sScriptMgr, SynchronizeMovement(), Object::ToPlayer(), MovementInfo::transport, UNIT_STAND_STATE_STAND, Unit::UpdatePosition(), VEHICLE_SEAT_FLAG_ALLOW_TURNING, GraveyardStruct::x, GraveyardStruct::y, and GraveyardStruct::z.

Referenced by ProcessMovementInfo().

◆ HandleMoveSplineDoneOpcode()

void WorldSession::HandleMoveSplineDoneOpcode ( WorldPacket recvPacket)
200{
201 ObjectGuid guid; // used only for proper packet read
202 MovementInfo movementInfo; // used only for proper packet read
203 uint32 movementCounter; // spline counter
204
205 Unit* mover = _player->m_mover;
206
207 recvData >> guid.ReadAsPacked();
208 ReadMovementInfo(recvData, &movementInfo);
209 recvData >> movementCounter;
210
211 if (_player->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_TAXI_FLIGHT)) // taxi spline case
212 {
213 // in taxi flight packet received in 2 case:
214 // 1) end taxi path in far (multi-node) flight
215 // 2) switch from one map to other in case multim-map taxi path
216 // we need process only (1)
217
219 if (curDest)
220 {
221 TaxiNodesEntry const* curDestNode = sTaxiNodesStore.LookupEntry(curDest);
222
223 // far teleport case
224 if (curDestNode && curDestNode->map_id != GetPlayer()->GetMapId() && GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE)
225 {
226 if (FlightPathMovementGenerator* flight = dynamic_cast<FlightPathMovementGenerator*>(GetPlayer()->GetMotionMaster()->top()))
227 {
228 // short preparations to continue flight
229 flight->SetCurrentNodeAfterTeleport();
230 TaxiPathNodeEntry const* node = flight->GetPath()[flight->GetCurrentNode()];
231 flight->SkipCurrentNode();
232
233 GetPlayer()->TeleportTo(curDestNode->map_id, node->x, node->y, node->z, GetPlayer()->GetOrientation(), TELE_TO_NOT_LEAVE_TAXI);
234 }
235 }
236
237 return;
238 }
239
240 // at this point only 1 node is expected (final destination)
241 if (GetPlayer()->m_taxi.GetPath().size() != 1)
242 {
243 return;
244 }
245
247 GetPlayer()->SetFallInformation(GameTime::GetGameTime().count(), GetPlayer()->GetPositionZ());
248 if (GetPlayer()->pvpInfo.IsHostile)
249 {
250 GetPlayer()->CastSpell(GetPlayer(), 2479, true);
251 }
252 return;
253 }
254
255 if (mover->GetGUID() != guid)
256 return;
257
258 if (!_player->IsExpectingChangeTransport() || !mover->movespline || mover->movespline->GetId() != movementCounter)
259 return;
260
263 WriteMovementInfo(&data, &movementInfo);
264 mover->SendMessageToSet(&data, _player);
265}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
@ FLIGHT_MOTION_TYPE
Definition MotionMaster.h:47
@ TELE_TO_NOT_LEAVE_TAXI
Definition Player.h:823
@ UNIT_FLAG_TAXI_FLIGHT
Definition UnitDefines.h:274
@ UNIT_FIELD_FLAGS
Definition UpdateFields.h:117
Definition WaypointMovementGenerator.h:107
uint32 GetId() const
Definition MoveSpline.h:115
bool HasFlag(uint16 index, uint32 flag) const
Definition Object.cpp:871
uint32 GetTaxiDestination() const
Definition PlayerTaxi.h:64
void SetFallInformation(uint32 time, float z)
Definition Player.h:2350
PlayerTaxi m_taxi
Definition Player.h:1145
void SetExpectingChangeTransport(bool state)
Definition Player.h:2647
void CleanupAfterTaxiFlight()
Definition Player.cpp:10464
Movement::MoveSpline * movespline
Definition Unit.h:2096
Definition DBCStructure.h:1951
uint32 map_id
Definition DBCStructure.h:1953

References _player, Unit::CastSpell(), Player::CleanupAfterTaxiFlight(), FLIGHT_MOTION_TYPE, GameTime::GetGameTime(), Object::GetGUID(), Movement::MoveSpline::GetId(), GetPlayer(), PlayerTaxi::GetTaxiDestination(), Object::HasFlag(), MovementInfo::HasMovementFlag(), Player::IsExpectingChangeTransport(), WorldObject::m_movementInfo, Player::m_mover, Player::m_taxi, TaxiNodesEntry::map_id, MOVEMENTFLAG_ROOT, Unit::movespline, MSG_MOVE_ROOT, MSG_MOVE_UNROOT, ObjectGuid::ReadAsPacked(), ReadMovementInfo(), WorldObject::SendMessageToSet(), Player::SetExpectingChangeTransport(), Player::SetFallInformation(), ByteBuffer::size(), sTaxiNodesStore, TELE_TO_NOT_LEAVE_TAXI, Player::TeleportTo(), UNIT_FIELD_FLAGS, UNIT_FLAG_TAXI_FLIGHT, WriteMovementInfo(), TaxiPathNodeEntry::x, TaxiPathNodeEntry::y, and TaxiPathNodeEntry::z.

Referenced by OpcodeTable::Initialize().

◆ HandleMoveTeleportAck()

void WorldSession::HandleMoveTeleportAck ( WorldPacket recvPacket)
274{
275 LOG_DEBUG("network", "MSG_MOVE_TELEPORT_ACK");
276
277 ObjectGuid guid;
278 recvData >> guid.ReadAsPacked();
279
280 uint32 flags, time;
281 recvData >> flags >> time; // unused
282 LOG_DEBUG("network.opcode", "Guid {}", guid.ToString());
283 LOG_DEBUG("network.opcode", "Flags {}, time {}", flags, time / IN_MILLISECONDS);
284
285 Player* plMover = _player->m_mover->ToPlayer();
286
287 if (!plMover || !plMover->IsBeingTeleportedNear())
288 return;
289
290 if (guid != plMover->GetGUID())
291 return;
292
293 plMover->SetSemaphoreTeleportNear(0);
294
295 uint32 old_zone = plMover->GetZoneId();
296
297 WorldLocation const& dest = plMover->GetTeleportDest();
298 Position oldPos(*plMover);
299
300 plMover->UpdatePosition(dest, true);
301
302 plMover->SetFallInformation(GameTime::GetGameTime().count(), dest.GetPositionZ());
303
304 // xinef: teleport pets if they are not unsummoned
305 if (Pet* pet = plMover->GetPet())
306 {
307 if (!pet->IsWithinDist3d(plMover, plMover->GetMap()->GetVisibilityRange() - 5.0f))
308 pet->NearTeleportTo(plMover->GetPositionX(), plMover->GetPositionY(), plMover->GetPositionZ(), pet->GetOrientation());
309 }
310
311 if (oldPos.GetExactDist2d(plMover) > 100.0f)
312 {
313 uint32 newzone, newarea;
314 plMover->GetZoneAndAreaId(newzone, newarea);
315 plMover->UpdateZone(newzone, newarea);
316
317 // new zone
318 if (old_zone != newzone)
319 {
320 // honorless target
321 if (plMover->pvpInfo.IsHostile)
322 plMover->CastSpell(plMover, 2479, true);
323
324 // in friendly area
325 else if (plMover->IsPvP() && !plMover->HasPlayerFlag(PLAYER_FLAGS_IN_PVP))
326 plMover->UpdatePvP(false, false);
327 }
328 }
329
330 // resummon pet
332
333 //lets process all delayed operations on successful teleport
335
337
338 // pussywizard: client forgets about losing control, resend it
339 if (plMover->HasUnitState(UNIT_STATE_FLEEING | UNIT_STATE_CONFUSED) || plMover->IsCharmed()) // only in such cases SetClientControl(self, false) is sent
340 plMover->SetClientControl(plMover, false, true);
341}
constexpr auto IN_MILLISECONDS
Definition Common.h:53
@ PLAYER_FLAGS_IN_PVP
Definition Player.h:477
@ UNIT_STATE_CONFUSED
Definition UnitDefines.h:181
@ UNIT_STATE_FLEEING
Definition UnitDefines.h:177
float GetVisibilityRange() const
Definition Map.h:195
void ReinitializeMovement()
Definition MotionMaster.cpp:940
WorldLocation & GetTeleportDest()
Definition Player.h:2087
void UpdatePvP(bool state, bool _override=false)
Definition PlayerUpdates.cpp:1529
void UpdateZone(uint32 newZone, uint32 newArea, bool force=false)
Definition PlayerUpdates.cpp:1252
void ProcessDelayedOperations()
Definition Player.cpp:1616
bool UpdatePosition(float x, float y, float z, float orientation, bool teleport=false) override
Definition PlayerUpdates.cpp:1156
void SetSemaphoreTeleportNear(time_t tm)
Definition Player.h:2091
PvPInfo pvpInfo
Definition Player.h:1842
bool IsBeingTeleportedNear() const
Definition Player.h:2089
void SetClientControl(Unit *target, bool allowMove, bool packetOnly=false)
Definition Player.cpp:12894
void ResummonPetTemporaryUnSummonedIfAny()
Definition Player.cpp:14274
bool IsCharmed() const
Definition Unit.h:1295
MotionMaster * GetMotionMaster()
Definition Unit.h:1738
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition Object.cpp:3072
Definition Position.h:27
bool IsHostile
Definition Player.h:356

References _player, Unit::CastSpell(), Position::GetExactDist2d(), GameTime::GetGameTime(), Object::GetGUID(), WorldObject::GetMap(), Unit::GetMotionMaster(), Player::GetPet(), GetPlayer(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetTeleportDest(), Map::GetVisibilityRange(), WorldObject::GetZoneAndAreaId(), WorldObject::GetZoneId(), Player::HasPlayerFlag(), Unit::HasUnitState(), IN_MILLISECONDS, Player::IsBeingTeleportedNear(), Unit::IsCharmed(), PvPInfo::IsHostile, Player::IsPvP(), LOG_DEBUG, Player::m_mover, PLAYER_FLAGS_IN_PVP, Player::ProcessDelayedOperations(), Player::pvpInfo, ObjectGuid::ReadAsPacked(), MotionMaster::ReinitializeMovement(), Player::ResummonPetTemporaryUnSummonedIfAny(), Player::SetClientControl(), Player::SetFallInformation(), Player::SetSemaphoreTeleportNear(), Object::ToPlayer(), ObjectGuid::ToString(), UNIT_STATE_CONFUSED, UNIT_STATE_FLEEING, Player::UpdatePosition(), Player::UpdatePvP(), and Player::UpdateZone().

Referenced by HandleTeleportTimeout(), and OpcodeTable::Initialize().

◆ HandleMoveTimeSkippedOpcode()

void WorldSession::HandleMoveTimeSkippedOpcode ( WorldPacket recvData)
871{
872 LOG_DEBUG("network", "WORLD: Recvd CMSG_MOVE_TIME_SKIPPED");
873
874 ObjectGuid guid;
875 uint32 timeSkipped;
876 recvData >> guid.ReadAsPacked();
877 recvData >> timeSkipped;
878
879 Unit* mover = GetPlayer()->m_mover;
880
881 if (!mover)
882 {
883 LOG_ERROR("network.opcode", "WorldSession::HandleMoveTimeSkippedOpcode wrong mover state from the unit moved by the player [{}]", GetPlayer()->GetGUID().ToString());
884 return;
885 }
886
887 // prevent tampered movement data
888 if (guid != mover->GetGUID())
889 {
890 LOG_ERROR("network.opcode", "WorldSession::HandleMoveTimeSkippedOpcode wrong guid from the unit moved by the player [{}]", GetPlayer()->GetGUID().ToString());
891 return;
892 }
893
894 mover->m_movementInfo.time += timeSkipped;
895
896 WorldPacket data(MSG_MOVE_TIME_SKIPPED, recvData.size());
897 data << guid.WriteAsPacked();
898 data << timeSkipped;
899 GetPlayer()->SendMessageToSet(&data, false);
900}
@ MSG_MOVE_TIME_SKIPPED
Definition Opcodes.h:823
uint32 time
Definition Object.h:293

References Object::GetGUID(), GetPlayer(), LOG_DEBUG, LOG_ERROR, WorldObject::m_movementInfo, Player::m_mover, MSG_MOVE_TIME_SKIPPED, ObjectGuid::ReadAsPacked(), Player::SendMessageToSet(), ByteBuffer::size(), MovementInfo::time, and ObjectGuid::WriteAsPacked().

Referenced by OpcodeTable::Initialize().

◆ HandleMoveWorldportAck()

void WorldSession::HandleMoveWorldportAck ( )
51{
52 // ignore unexpected far teleports
53 if (!GetPlayer()->IsBeingTeleportedFar())
54 return;
55
57
58 // get the teleport destination
59 WorldLocation const& loc = GetPlayer()->GetTeleportDest();
60
61 // possible errors in the coordinate validity check
63 {
64 KickPlayer("!MapMgr::IsValidMapCoord(loc)");
65 return;
66 }
67
68 // get the destination map entry, not the current one, this will fix homebind and reset greeting
69 MapEntry const* mEntry = sMapStore.LookupEntry(loc.GetMapId());
70 InstanceTemplate const* mInstance = sObjectMgr->GetInstanceTemplate(loc.GetMapId());
71
72 Map* oldMap = GetPlayer()->GetMap();
73 if (GetPlayer()->IsInWorld())
74 {
75 LOG_ERROR("network.opcode", "Player (Name {}) is still in world when teleported from map {} to new map {}", GetPlayer()->GetName(), oldMap->GetId(), loc.GetMapId());
76 oldMap->RemovePlayerFromMap(GetPlayer(), false);
77 }
78
79 // reset instance validity, except if going to an instance inside an instance
80 if (!GetPlayer()->m_InstanceValid && !mInstance)
81 {
82 GetPlayer()->m_InstanceValid = true;
83 // pussywizard: m_InstanceValid can be false only by leaving a group in an instance => so remove temp binds that could not be removed because player was still on the map!
84 if (!sInstanceSaveMgr->PlayerIsPermBoundToInstance(GetPlayer()->GetGUID(), oldMap->GetId(), oldMap->GetDifficulty()))
85 sInstanceSaveMgr->PlayerUnbindInstance(GetPlayer()->GetGUID(), oldMap->GetId(), oldMap->GetDifficulty(), true);
86 }
87
88 // relocate the player to the teleport destination
89 Map* newMap = sMapMgr->CreateMap(loc.GetMapId(), GetPlayer());
90 // the CanEnter checks are done in TeleporTo but conditions may change
91 // while the player is in transit, for example the map may get full
92 if (!newMap || newMap->CannotEnter(GetPlayer(), false))
93 {
94 LOG_ERROR("network.opcode", "Map {} could not be created for player {}, porting player to homebind", loc.GetMapId(), GetPlayer()->GetGUID().ToString());
95 GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation());
96 return;
97 }
98
99 float z = loc.GetPositionZ() + GetPlayer()->GetHoverHeight();
100 GetPlayer()->Relocate(loc.GetPositionX(), loc.GetPositionY(), z, loc.GetOrientation());
101
102 GetPlayer()->ResetMap();
103 GetPlayer()->SetMap(newMap);
104
106
108
109 if (GetPlayer()->GetPendingFlightChange() <= GetPlayer()->GetMapChangeOrderCounter())
110 {
111 if (!GetPlayer()->HasIncreaseMountedFlightSpeedAura() && !GetPlayer()->HasFlyAura())
113 }
114
115 if (!GetPlayer()->GetMap()->AddPlayerToMap(GetPlayer()))
116 {
117 LOG_ERROR("network.opcode", "WORLD: failed to teleport player {} ({}) to map {} because of unknown reason!",
118 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString(), loc.GetMapId());
119 GetPlayer()->ResetMap();
120 GetPlayer()->SetMap(oldMap);
121 GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation());
122 return;
123 }
124
125 oldMap->AfterPlayerUnlinkFromMap();
126
127 // pussywizard: transport teleport couldn't teleport us to the same map (some other teleport pending, reqs not met, etc.), but we still have transport set until player moves! clear it if map differs (crashfix)
128 if (Transport* t = _player->GetTransport())
129 if (!t->IsInMap(_player))
130 {
131 t->RemovePassenger(_player);
132 _player->m_transport = nullptr;
135 }
136
138 _player->getHostileRefMgr().deleteReferences(true); // pussywizard: multithreading crashfix
139
140 CellCoord pair(Acore::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY()));
141 Cell cell(pair);
142 if (!GridCoord(cell.GridX(), cell.GridY()).IsCoordValid())
143 {
144 KickPlayer("!GridCoord(cell.GridX(), cell.GridY()).IsCoordValid()");
145 return;
146 }
147 newMap->LoadGrid(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
148
149 // pussywizard: player supposed to enter bg map
150 if (_player->InBattleground())
151 {
152 // but landed on another map, cleanup data
153 if (!mEntry->IsBattlegroundOrArena())
155 // everything ok
156 else if (Battleground* bg = _player->GetBattleground())
157 {
158 if (_player->IsInvitedForBattlegroundInstance()) // GMs are not invited, so they are not added to participants
159 bg->AddPlayer(_player);
160 }
161 }
162
163 // pussywizard: arena spectator stuff
164 {
165 if (newMap->IsBattleArena() && ((BattlegroundMap*)newMap)->GetBG() && _player->HasPendingSpectatorForBG(((BattlegroundMap*)newMap)->GetInstanceId()))
166 {
168 _player->SetIsSpectator(true);
170 ((BattlegroundMap*)newMap)->GetBG()->AddSpectator(_player);
172 }
173 else
174 _player->SetIsSpectator(false);
175
177
178 if (uint32 inviteInstanceId = _player->GetPendingSpectatorInviteInstanceId())
179 {
180 if (Battleground* tbg = sBattlegroundMgr->GetBattleground(inviteInstanceId, BATTLEGROUND_TYPE_NONE))
181 tbg->RemoveToBeTeleported(_player->GetGUID());
183 }
184 }
185
186 // xinef: do this again, player can be teleported inside bg->AddPlayer(_player)!!!!
187 CellCoord pair2(Acore::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY()));
188 Cell cell2(pair2);
189 if (!GridCoord(cell2.GridX(), cell2.GridY()).IsCoordValid())
190 {
191 KickPlayer("!GridCoord(cell2.GridX(), cell2.GridY()).IsCoordValid()");
192 return;
193 }
194 newMap->LoadGrid(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
195
197
198 // flight fast teleport case
199 if (GetPlayer()->IsInFlight())
200 {
201 if (!GetPlayer()->InBattleground())
202 {
203 // short preparations to continue flight
204 MovementGenerator* movementGenerator = GetPlayer()->GetMotionMaster()->top();
205 movementGenerator->Initialize(GetPlayer());
206 return;
207 }
208
209 // battleground state prepare, stop flight
212 }
213
214 // resurrect character at enter into instance where his corpse exist after add to map
215 Corpse* corpse = GetPlayer()->GetMap()->GetCorpseByPlayer(GetPlayer()->GetGUID());
216 if (corpse && corpse->GetType() != CORPSE_BONES)
217 {
218 if (mEntry->IsDungeon())
219 {
220 GetPlayer()->ResurrectPlayer(0.5f);
222 }
223 }
224
225 if (!corpse && mEntry->IsDungeon())
226 {
227 // resurrect character upon entering instance when the corpse is not available anymore
228 if (GetPlayer()->GetCorpseLocation().GetMapId() == mEntry->MapID)
229 {
230 GetPlayer()->ResurrectPlayer(0.5f);
232 }
233 }
234
235 bool allowMount = !mEntry->IsDungeon() || mEntry->IsBattlegroundOrArena();
236 if (mInstance)
237 {
238 Difficulty diff = GetPlayer()->GetDifficulty(mEntry->IsRaid());
239 if (MapDifficulty const* mapDiff = GetMapDifficultyData(mEntry->MapID, diff))
240 if (mapDiff->resetTime)
241 if (time_t timeReset = sInstanceSaveMgr->GetResetTimeFor(mEntry->MapID, diff))
242 {
243 uint32 timeleft = uint32(timeReset - GameTime::GetGameTime().count());
244 GetPlayer()->SendInstanceResetWarning(mEntry->MapID, diff, timeleft, true);
245 }
246 allowMount = mInstance->AllowMount;
247 }
248
249 // mount allow check
250 if (!allowMount)
252
253 // update zone immediately, otherwise leave channel will cause crash in mtmap
254 uint32 newzone, newarea;
255 GetPlayer()->GetZoneAndAreaId(newzone, newarea);
256 GetPlayer()->UpdateZone(newzone, newarea);
257
258 // honorless target
259 if (GetPlayer()->pvpInfo.IsHostile)
260 GetPlayer()->CastSpell(GetPlayer(), 2479, true);
261
262 // in friendly area
263 else if (GetPlayer()->IsPvP() && !GetPlayer()->HasPlayerFlag(PLAYER_FLAGS_IN_PVP))
264 GetPlayer()->UpdatePvP(false, false);
265
266 // resummon pet
268
269 //lets process all delayed operations on successful teleport
271}
#define SPECTATOR_ADDON_PREFIX
Definition ArenaSpectator.h:35
@ CORPSE_BONES
Definition Corpse.h:28
MapDifficulty const * GetMapDifficultyData(uint32 mapId, Difficulty difficulty)
Definition DBCStores.cpp:761
CoordPair< MAX_NUMBER_OF_GRIDS > GridCoord
Definition GridDefines.h:171
@ BATTLEGROUND_TYPE_NONE
Definition SharedDefines.h:3746
Definition Map.h:680
CorpseType GetType() const
Definition Corpse.h:72
void deleteReferences(bool removeFromMap=false)
Definition HostileRefMgr.cpp:125
bool IsEmpty() const
Definition LinkedList.h:97
static bool IsValidMapCoord(uint32 mapid, Position const &pos)
Definition MapMgr.h:90
virtual void RemovePlayerFromMap(Player *, bool)
Definition Map.cpp:701
void LoadGrid(float x, float y)
Definition Map.cpp:214
virtual void AfterPlayerUnlinkFromMap()
Definition Map.cpp:722
virtual EnterState CannotEnter(Player *, bool)
Definition Map.h:285
uint32 GetId() const
Definition Map.h:229
Corpse * GetCorpseByPlayer(ObjectGuid const &ownerGuid) const
Definition Map.h:365
Difficulty GetDifficulty() const
Definition Map.h:290
_Ty top() const
Definition MotionMaster.h:175
void MovementExpired(bool reset=true)
Definition MotionMaster.h:205
Definition MovementGenerator.h:28
virtual void Initialize(Unit *)=0
bool HasPendingSpectatorForBG(uint32 bgInstanceId) const
Definition Player.h:2590
void SendInitialPacketsAfterAddToMap()
Definition Player.cpp:11649
bool m_InstanceValid
Definition Player.h:2450
void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time, bool onEnterMap)
Definition Player.cpp:11790
bool IsInvitedForBattlegroundInstance() const
Definition Player.h:2271
Difficulty GetDifficulty(bool isRaid) const
Definition Player.h:1915
void SendInitialPacketsBeforeAddToMap()
Definition Player.cpp:11592
void ResetMap() override
Definition Player.cpp:14773
void RemoveCorpse()
Definition Player.cpp:4663
void ClearReceivedSpectatorResetFor()
Definition Player.h:2594
void SetPendingSpectatorInviteInstanceId(uint32 bgInstanceId)
Definition Player.h:2591
void SetIsSpectator(bool on)
Definition Player.cpp:15465
void SetSemaphoreTeleportFar(time_t tm)
Definition Player.h:2092
void SetMap(Map *map) override
Definition Player.cpp:14785
void SetPendingSpectatorForBG(uint32 bgInstanceId)
Definition Player.h:2589
uint32 GetPendingSpectatorInviteInstanceId() const
Definition Player.h:2592
HostileRefMgr & getHostileRefMgr()
Definition Unit.h:947
float GetHoverHeight() const
Definition Unit.h:1697
void UpdatePositionData()
Definition Object.cpp:1155
Transport * m_transport
Definition Object.h:747
CellCoord ComputeCellCoord(float x, float y)
Definition GridDefines.h:197
AC_GAME_API void HandleResetCommand(Player *player)
Definition ArenaSpectator.cpp:227
void SendCommand(T *o, Format &&fmt, Args &&... args)
Definition ArenaSpectator.h:47
Definition Cell.h:45
Definition Map.h:121
bool AllowMount
Definition Map.h:124
Definition DBCStructure.h:2220
uint32 MapID
Definition DBCStructure.h:1324
bool IsBattlegroundOrArena() const
Definition DBCStructure.h:1355
bool IsDungeon() const
Definition DBCStructure.h:1349
void Relocate(float x, float y)
Definition Position.h:77

References _player, Map::AfterPlayerUnlinkFromMap(), InstanceTemplate::AllowMount, BATTLEGROUND_TYPE_NONE, Map::CannotEnter(), Unit::CastSpell(), Player::CleanupAfterTaxiFlight(), Player::ClearReceivedSpectatorResetFor(), Acore::ComputeCellCoord(), CORPSE_BONES, HostileRefMgr::deleteReferences(), Player::GetBattleground(), Map::GetCorpseByPlayer(), Map::GetDifficulty(), Player::GetDifficulty(), GameTime::GetGameTime(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetHoverHeight(), Map::GetId(), WorldObject::GetMap(), GetMapDifficultyData(), WorldLocation::GetMapId(), Unit::GetMotionMaster(), Position::GetOrientation(), Player::GetPendingSpectatorInviteInstanceId(), GetPlayer(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetTeleportDest(), WorldObject::GetTransport(), Corpse::GetType(), WorldObject::GetZoneAndAreaId(), Cell::GridX(), Cell::GridY(), ArenaSpectator::HandleResetCommand(), Player::HasPendingSpectatorForBG(), Player::InBattleground(), MovementGenerator::Initialize(), Map::IsBattleArena(), MapEntry::IsBattlegroundOrArena(), MapEntry::IsDungeon(), LinkedListHead::IsEmpty(), Player::IsInvitedForBattlegroundInstance(), MapEntry::IsRaid(), MapMgr::IsValidMapCoord(), KickPlayer(), Map::LoadGrid(), LOG_ERROR, Player::m_InstanceValid, WorldObject::m_movementInfo, WorldObject::m_transport, MapEntry::MapID, MotionMaster::MovementExpired(), MOVEMENTFLAG_CAN_FLY, MOVEMENTFLAG_ONTRANSPORT, PLAYER_FLAGS_IN_PVP, PLAYER_MAX_BATTLEGROUND_QUEUES, Player::ProcessDelayedOperations(), Position::Relocate(), Unit::RemoveAurasByType(), Player::RemoveCorpse(), MovementInfo::RemoveMovementFlag(), Map::RemovePlayerFromMap(), MovementInfo::TransportInfo::Reset(), Player::ResetMap(), Player::ResummonPetTemporaryUnSummonedIfAny(), Player::ResurrectPlayer(), sBattlegroundMgr, ArenaSpectator::SendCommand(), Player::SendInitialPacketsAfterAddToMap(), Player::SendInitialPacketsBeforeAddToMap(), Player::SendInstanceResetWarning(), Player::SetBattlegroundId(), Player::SetIsSpectator(), Player::SetMap(), Player::SetPendingSpectatorForBG(), Player::SetPendingSpectatorInviteInstanceId(), Player::SetSemaphoreTeleportFar(), sInstanceSaveMgr, sMapMgr, sMapStore, sObjectMgr, Player::SpawnCorpseBones(), SPECTATOR_ADDON_PREFIX, SPELL_AURA_MOUNTED, TEAM_NEUTRAL, Player::TeleportTo(), MotionMaster::top(), MovementInfo::transport, WorldObject::UpdatePositionData(), Player::UpdatePvP(), and Player::UpdateZone().

Referenced by HandleMoveWorldportAckOpcode(), HandleTeleportTimeout(), and LogoutPlayer().

◆ HandleMoveWorldportAckOpcode()

void WorldSession::HandleMoveWorldportAckOpcode ( WorldPacket recvPacket)
45{
46 LOG_DEBUG("network", "WORLD: got MSG_MOVE_WORLDPORT_ACK.");
48}
void HandleMoveWorldportAck()
Definition MovementHandler.cpp:50

References HandleMoveWorldportAck(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleNameQueryOpcode()

void WorldSession::HandleNameQueryOpcode ( WorldPackets::Query::NameQuery packet)
65{
66 // This is disable by default to prevent lots of console spam
67 // LOG_INFO("network.opcode", "HandleNameQueryOpcode {}", guid);
68
70}
ObjectGuid Guid
Definition QueryPackets.h:35
void SendNameQueryOpcode(ObjectGuid guid)
Definition QueryHandler.cpp:32

References WorldPackets::Query::NameQuery::Guid, and SendNameQueryOpcode().

Referenced by OpcodeTable::Initialize().

◆ HandleNextCinematicCamera()

void WorldSession::HandleNextCinematicCamera ( WorldPacket recvPacket)
948{
949 // Sent by client when cinematic actually begun. So we begin the server side process
951}
void BeginCinematic()
Definition CinematicMgr.cpp:41

References CinematicMgr::BeginCinematic(), Player::GetCinematicMgr(), and GetPlayer().

Referenced by OpcodeTable::Initialize().

◆ HandleNpcTextQueryOpcode()

void WorldSession::HandleNpcTextQueryOpcode ( WorldPacket recvPacket)
275{
276 uint32 textID;
277 ObjectGuid guid;
278
279 recvData >> textID;
280 LOG_DEBUG("network", "WORLD: CMSG_NPC_TEXT_QUERY TextId: {}", textID);
281
282 recvData >> guid;
283
284 GossipText const* gossip = sObjectMgr->GetGossipText(textID);
285
286 WorldPacket data(SMSG_NPC_TEXT_UPDATE, 100); // guess size
287 data << textID;
288
289 if (!gossip)
290 {
291 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
292 {
293 data << float(0);
294 data << "Greetings $N";
295 data << "Greetings $N";
296 data << uint32(0);
297 data << uint32(0);
298 data << uint32(0);
299 data << uint32(0);
300 data << uint32(0);
301 data << uint32(0);
302 data << uint32(0);
303 }
304 }
305 else
306 {
307 std::string text0[MAX_GOSSIP_TEXT_OPTIONS], text1[MAX_GOSSIP_TEXT_OPTIONS];
309
310 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
311 {
312 BroadcastText const* bct = sObjectMgr->GetBroadcastText(gossip->Options[i].BroadcastTextID);
313 if (bct)
314 {
315 text0[i] = bct->GetText(locale, GENDER_MALE, true);
316 text1[i] = bct->GetText(locale, GENDER_FEMALE, true);
317 }
318 else
319 {
320 text0[i] = gossip->Options[i].Text_0;
321 text1[i] = gossip->Options[i].Text_1;
322 }
323
324 if (locale != DEFAULT_LOCALE && !bct)
325 {
326 if (NpcTextLocale const* npcTextLocale = sObjectMgr->GetNpcTextLocale(textID))
327 {
328 ObjectMgr::GetLocaleString(npcTextLocale->Text_0[i], locale, text0[i]);
329 ObjectMgr::GetLocaleString(npcTextLocale->Text_1[i], locale, text1[i]);
330 }
331 }
332
333 data << gossip->Options[i].Probability;
334
335 if (text0[i].empty())
336 data << text1[i];
337 else
338 data << text0[i];
339
340 if (text1[i].empty())
341 data << text0[i];
342 else
343 data << text1[i];
344
345 data << gossip->Options[i].Language;
346
347 for (uint8 j = 0; j < MAX_GOSSIP_TEXT_EMOTES; ++j)
348 {
349 data << gossip->Options[i].Emotes[j]._Delay;
350 data << gossip->Options[i].Emotes[j]._Emote;
351 }
352 }
353 }
354
355 SendPacket(&data);
356
357 LOG_DEBUG("network", "WORLD: Sent SMSG_NPC_TEXT_UPDATE");
358}
#define DEFAULT_LOCALE
Definition Common.h:131
#define MAX_GOSSIP_TEXT_OPTIONS
Definition NPCHandler.h:42
#define MAX_GOSSIP_TEXT_EMOTES
Definition NPCHandler.h:30
@ GENDER_MALE
Definition SharedDefines.h:61
@ GENDER_FEMALE
Definition SharedDefines.h:62
@ SMSG_NPC_TEXT_UPDATE
Definition Opcodes.h:414
Definition ObjectMgr.h:434
std::string const & GetText(LocaleConstant locale=DEFAULT_LOCALE, uint8 gender=GENDER_MALE, bool forceGender=false) const
Definition ObjectMgr.h:456
std::string Text_0
Definition NPCHandler.h:34
QEmote Emotes[MAX_GOSSIP_TEXT_EMOTES]
Definition NPCHandler.h:39
uint32 Language
Definition NPCHandler.h:37
float Probability
Definition NPCHandler.h:38
uint32 BroadcastTextID
Definition NPCHandler.h:36
std::string Text_1
Definition NPCHandler.h:35
Definition NPCHandler.h:45
GossipTextOption Options[MAX_GOSSIP_TEXT_OPTIONS]
Definition NPCHandler.h:46
Definition NPCHandler.h:55
uint32 _Emote
Definition NPCHandler.h:26
uint32 _Delay
Definition NPCHandler.h:27

References QEmote::_Delay, QEmote::_Emote, GossipTextOption::BroadcastTextID, DEFAULT_LOCALE, GossipTextOption::Emotes, GENDER_FEMALE, GENDER_MALE, ObjectMgr::GetLocaleString(), GetSessionDbLocaleIndex(), BroadcastText::GetText(), GossipTextOption::Language, LOG_DEBUG, MAX_GOSSIP_TEXT_EMOTES, MAX_GOSSIP_TEXT_OPTIONS, GossipText::Options, GossipTextOption::Probability, SendPacket(), SMSG_NPC_TEXT_UPDATE, sObjectMgr, GossipTextOption::Text_0, and GossipTextOption::Text_1.

Referenced by OpcodeTable::Initialize().

◆ HandleOfferPetitionOpcode()

void WorldSession::HandleOfferPetitionOpcode ( WorldPacket recvData)
555{
556 LOG_DEBUG("network", "Received opcode CMSG_OFFER_PETITION"); // ok
557
558 ObjectGuid petitionguid, plguid;
559 uint32 junk;
560 Player* player;
561 recvData >> junk; // this is not petition type!
562 recvData >> petitionguid; // petition guid
563 recvData >> plguid; // player guid
564
566 if (!player)
567 return;
568
569 Petition const* petition = sPetitionMgr->GetPetition(petitionguid);
570 if (!petition)
571 return;
572
573 if (petition->petitionType != GUILD_CHARTER_TYPE)
574 {
575 if (GetPlayer()->GetTeamId() != player->GetTeamId() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA))
576 {
578 return;
579 }
580
581 if (player->GetLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
582 {
583 // player is too low level to join an arena team
585 return;
586 }
587
589 if (slot >= MAX_ARENA_SLOT)
590 return;
591
592 if (player->GetArenaTeamId(slot))
593 {
594 // player is already in an arena team
596 return;
597 }
598
599 if (player->GetArenaTeamIdInvited())
600 {
602 return;
603 }
604 }
605 else
606 {
607 if (GetPlayer()->GetTeamId() != player->GetTeamId() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD))
608 {
610 return;
611 }
612
613 if (player->GetGuildId())
614 {
616 return;
617 }
618
619 if (player->GetGuildIdInvited())
620 {
622 return;
623 }
624 }
625
626 Signatures const* signatures = sPetitionMgr->GetSignature(petitionguid);
627 uint8 signs = signatures ? signatures->signatureMap.size() : 0;
628
629 WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8 + 8 + 4 + signs + signs * 12));
630 data << petitionguid; // petition guid
631 data << _player->GetGUID(); // owner guid
632 data << uint32(petition->petitionId); // guild/team id (31-bit safe)
633 data << uint8(signs); // sign's count
634
635 if (signs)
636 for (SignatureMap::const_iterator itr = signatures->signatureMap.begin(); itr != signatures->signatureMap.end(); ++itr)
637 {
638 data << itr->first; // Player GUID
639 data << uint32(0); // there 0 ...
640 }
641
642 player->SendDirectMessage(&data);
643}
@ GUILD_COMMAND_INVITE
Definition Guild.h:100
@ GUILD_COMMAND_CREATE
Definition Guild.h:99
@ ERR_ALREADY_IN_GUILD_S
Definition Guild.h:122
@ ERR_GUILD_NOT_ALLIED
Definition Guild.h:132
@ ERR_ALREADY_INVITED_TO_GUILD_S
Definition Guild.h:124
#define sPetitionMgr
Definition PetitionMgr.h:104
static uint8 GetSlotByType(uint32 type)
Definition ArenaTeam.cpp:621
uint32 GetGuildIdInvited()
Definition Player.h:1898
@ SMSG_PETITION_SHOW_SIGNATURES
Definition Opcodes.h:477
@ GUILD_CHARTER_TYPE
Definition WorldSession.h:261
Definition PetitionMgr.h:40
uint8 petitionType
Definition PetitionMgr.h:48
uint32 petitionId
Definition PetitionMgr.h:44
Definition PetitionMgr.h:54
SignatureMap signatureMap
Definition PetitionMgr.h:57

References _player, CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA, CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD, CONFIG_MAX_PLAYER_LEVEL, ERR_ALREADY_IN_ARENA_TEAM_S, ERR_ALREADY_IN_GUILD_S, ERR_ALREADY_INVITED_TO_ARENA_TEAM_S, ERR_ALREADY_INVITED_TO_GUILD_S, ERR_ARENA_TEAM_CREATE_S, ERR_ARENA_TEAM_INVITE_SS, ERR_ARENA_TEAM_NOT_ALLIED, ERR_ARENA_TEAM_TARGET_TOO_LOW_S, ERR_GUILD_NOT_ALLIED, ObjectAccessor::FindConnectedPlayer(), Player::GetArenaTeamId(), Player::GetArenaTeamIdInvited(), Object::GetGUID(), Player::GetGuildId(), Player::GetGuildIdInvited(), Unit::GetLevel(), WorldObject::GetName(), GetPlayer(), ArenaTeam::GetSlotByType(), Player::GetTeamId(), GetTeamId(), GUILD_CHARTER_TYPE, GUILD_COMMAND_CREATE, GUILD_COMMAND_INVITE, LOG_DEBUG, MAX_ARENA_SLOT, Petition::petitionId, Petition::petitionType, SendArenaTeamCommandResult(), Guild::SendCommandResult(), Player::SendDirectMessage(), Signatures::signatureMap, SMSG_PETITION_SHOW_SIGNATURES, sPetitionMgr, and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleOpenItemOpcode()

void WorldSession::HandleOpenItemOpcode ( WorldPacket recvPacket)
205{
206 LOG_DEBUG("network", "WORLD: CMSG_OPEN_ITEM packet, data length = {}", (uint32)recvPacket.size());
207
208 Player* pUser = _player;
209
210 // ignore for remote control state
211 if (pUser->m_mover != pUser)
212 return;
213
214 // xinef: additional check, client outputs message on its own
215 if (!pUser->IsAlive())
216 {
217 pUser->SendEquipError(EQUIP_ERR_YOU_ARE_DEAD, nullptr, nullptr);
218 return;
219 }
220
221 uint8 bagIndex, slot;
222
223 recvPacket >> bagIndex >> slot;
224
225 LOG_DEBUG("network.opcode", "bagIndex: {}, slot: {}", bagIndex, slot);
226
227 Item* item = pUser->GetItemByPos(bagIndex, slot);
228 if (!item)
229 {
230 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
231 return;
232 }
233
234 ItemTemplate const* proto = item->GetTemplate();
235 if (!proto)
236 {
237 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, nullptr);
238 return;
239 }
240
241 // Verify that the bag is an actual bag or wrapped item that can be used "normally"
242 if (!proto->HasFlag(ITEM_FLAG_HAS_LOOT) && !item->IsWrapped())
243 {
244 pUser->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, nullptr);
245 LOG_ERROR("network.opcode", "Possible hacking attempt: Player {} [{}] tried to open item [{}, entry: {}] which is not openable!",
246 pUser->GetName(), pUser->GetGUID().ToString(), item->GetGUID().ToString(), proto->ItemId);
247 return;
248 }
249
250 // locked item
251 uint32 lockId = proto->LockID;
252 if (lockId)
253 {
254 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
255
256 if (!lockInfo)
257 {
258 pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, nullptr);
259 LOG_ERROR("network.opcode", "WORLD::OpenItem: item [{}] has an unknown lockId: {}!", item->GetGUID().ToString(), lockId);
260 return;
261 }
262
263 // was not unlocked yet
264 if (item->IsLocked())
265 {
266 pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, nullptr);
267 return;
268 }
269 }
270
271 if (sScriptMgr->OnPlayerBeforeOpenItem(pUser, item))
272 {
273 if (item->IsWrapped())// wrapped?
274 {
276 stmt->SetData(0, item->GetGUID().GetCounter());
278 .WithPreparedCallback(std::bind(&WorldSession::HandleOpenWrappedItemCallback, this, bagIndex, slot, item->GetGUID().GetCounter(), std::placeholders::_1)));
279 }
280 else
281 {
282 pUser->SendLoot(item->GetGUID(), LOOT_CORPSE);
283 }
284 }
285}
@ CHAR_SEL_CHARACTER_GIFT_BY_ITEM
Definition CharacterDatabase.h:131
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
@ EQUIP_ERR_ITEM_LOCKED
Definition Item.h:83
@ EQUIP_ERR_YOU_ARE_DEAD
Definition Item.h:85
@ EQUIP_ERR_CANT_DO_RIGHT_NOW
Definition Item.h:86
bool IsWrapped() const
Definition Item.h:263
bool IsLocked() const
Definition Item.h:253
void HandleOpenWrappedItemCallback(uint8 bagIndex, uint8 slot, ObjectGuid::LowType itemLowGUID, PreparedQueryResult result)
Definition SpellHandler.cpp:287
Definition DBCStructure.h:1306

References _player, _queryProcessor, AsyncCallbackProcessor< T >::AddCallback(), CHAR_SEL_CHARACTER_GIFT_BY_ITEM, CharacterDatabase, EQUIP_ERR_CANT_DO_RIGHT_NOW, EQUIP_ERR_ITEM_LOCKED, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_YOU_ARE_DEAD, ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetItemByPos(), WorldObject::GetName(), Item::GetTemplate(), HandleOpenWrappedItemCallback(), ItemTemplate::HasFlag(), Unit::IsAlive(), Item::IsLocked(), Item::IsWrapped(), ITEM_FLAG_HAS_LOOT, ItemTemplate::ItemId, ItemTemplate::LockID, LOG_DEBUG, LOG_ERROR, LOOT_CORPSE, Player::m_mover, Player::SendEquipError(), Player::SendLoot(), PreparedStatementBase::SetData(), ByteBuffer::size(), sLockStore, sScriptMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleOpenWrappedItemCallback()

void WorldSession::HandleOpenWrappedItemCallback ( uint8  bagIndex,
uint8  slot,
ObjectGuid::LowType  itemLowGUID,
PreparedQueryResult  result 
)
288{
289 if (!GetPlayer())
290 return;
291
292 Item* item = GetPlayer()->GetItemByPos(bagIndex, slot);
293 if (!item)
294 return;
295
296 if (item->GetGUID().GetCounter() != itemLowGUID || !item->IsWrapped()) // during getting result, gift was swapped with another item
297 return;
298
299 if (!result)
300 {
301 LOG_ERROR("network", "Wrapped item {} don't have record in character_gifts table and will deleted", item->GetGUID().ToString());
302 GetPlayer()->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
303 return;
304 }
305
306 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
307
308 Field* fields = result->Fetch();
309 uint32 entry = fields[0].Get<uint32>();
310 uint32 flags = fields[1].Get<uint32>();
311
313 item->SetEntry(entry);
314 item->SetUInt32Value(ITEM_FIELD_FLAGS, flags);
316
319
321 stmt->SetData(0, item->GetGUID().GetCounter());
322 trans->Append(stmt);
323
324 CharacterDatabase.CommitTransaction(trans);
325}
@ CHAR_DEL_GIFT
Definition CharacterDatabase.h:130
void SetEntry(uint32 entry)
Definition Object.h:117

References CHAR_DEL_GIFT, CharacterDatabase, Player::DestroyItem(), ObjectGuid::Empty, Field::Get(), Item::GetBagSlot(), ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetItemByPos(), GetPlayer(), Item::GetSlot(), Item::GetTemplate(), Item::IsWrapped(), ITEM_CHANGED, ITEM_FIELD_FLAGS, ITEM_FIELD_GIFTCREATOR, ITEM_FIELD_MAXDURABILITY, LOG_ERROR, ItemTemplate::MaxDurability, Player::SaveInventoryAndGoldToDB(), PreparedStatementBase::SetData(), Object::SetEntry(), Object::SetGuidValue(), Item::SetState(), Object::SetUInt32Value(), and ObjectGuid::ToString().

Referenced by HandleOpenItemOpcode().

◆ HandleOptOutOfLootOpcode()

void WorldSession::HandleOptOutOfLootOpcode ( WorldPacket recvData)
1086{
1087 uint32 passOnLoot;
1088 recvData >> passOnLoot; // 1 always pass, 0 do not pass
1089
1090 if (!GetPlayer())
1091 return;
1092
1093 GetPlayer()->SetPassOnGroupLoot(passOnLoot);
1094}
void SetPassOnGroupLoot(bool bPassOnGroupLoot)
Definition Player.h:2502

References GetPlayer(), and Player::SetPassOnGroupLoot().

Referenced by OpcodeTable::Initialize().

◆ HandlePageTextQueryOpcode()

void WorldSession::HandlePageTextQueryOpcode ( WorldPacket recvPacket)

Only static data is sent in this packet !!!

362{
363 uint32 pageID;
364 recvData >> pageID;
365 recvData.read_skip<uint64>(); // guid
366
367 while (pageID)
368 {
369 PageText const* pageText = sObjectMgr->GetPageText(pageID);
370 // guess size
372 data << pageID;
373
374 if (!pageText)
375 {
376 data << "Item page missing.";
377 data << uint32(0);
378 pageID = 0;
379 }
380 else
381 {
382 std::string Text = pageText->Text;
383
384 int loc_idx = GetSessionDbLocaleIndex();
385 if (loc_idx >= 0)
386 if (PageTextLocale const* player = sObjectMgr->GetPageTextLocale(pageID))
387 ObjectMgr::GetLocaleString(player->Text, loc_idx, Text);
388
389 data << Text;
390 data << pageText->NextPage;
391 pageID = pageText->NextPage;
392 }
393 SendPacket(&data);
394
395 LOG_DEBUG("network", "WORLD: Sent SMSG_PAGE_TEXT_QUERY_RESPONSE");
396 }
397}
Text
Definition boss_pyroguard_emberseer.cpp:26
@ SMSG_PAGE_TEXT_QUERY_RESPONSE
Definition Opcodes.h:121
Definition NPCHandler.h:50
Definition ObjectMgr.h:57
std::string Text
Definition ObjectMgr.h:58
uint32 NextPage
Definition ObjectMgr.h:59

References ObjectMgr::GetLocaleString(), GetSessionDbLocaleIndex(), LOG_DEBUG, PageText::NextPage, ByteBuffer::read_skip(), SendPacket(), SMSG_PAGE_TEXT_QUERY_RESPONSE, sObjectMgr, and PageText::Text.

Referenced by OpcodeTable::Initialize().

◆ HandlePartyAssignmentOpcode()

void WorldSession::HandlePartyAssignmentOpcode ( WorldPacket recvData)
671{
672 Group* group = GetPlayer()->GetGroup();
673 if (!group)
674 return;
675
676 ObjectGuid senderGuid = GetPlayer()->GetGUID();
677 if (!group->IsLeader(senderGuid) && !group->IsAssistant(senderGuid))
678 return;
679
680 uint8 assignment;
681 bool apply;
682 ObjectGuid guid;
683 recvData >> assignment >> apply;
684 recvData >> guid;
685
686 switch (assignment)
687 {
690 group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_MAINASSIST);
691 break;
693 group->RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINTANK); // Remove main assist flag from current if any.
694 group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_MAINTANK);
695 default:
696 break;
697 }
698
699 group->SendUpdate();
700}
@ GROUP_ASSIGN_MAINASSIST
Definition Group.h:81
@ GROUP_ASSIGN_MAINTANK
Definition Group.h:80
@ MEMBER_FLAG_MAINASSIST
Definition Group.h:75
@ MEMBER_FLAG_MAINTANK
Definition Group.h:74
void RemoveUniqueGroupMemberFlag(GroupMemberFlags flag)
Definition Group.cpp:2527

References Player::GetGroup(), Object::GetGUID(), GetPlayer(), GROUP_ASSIGN_MAINASSIST, GROUP_ASSIGN_MAINTANK, Group::IsAssistant(), Group::IsLeader(), MEMBER_FLAG_MAINASSIST, MEMBER_FLAG_MAINTANK, Group::RemoveUniqueGroupMemberFlag(), Group::SendUpdate(), and Group::SetGroupMemberFlag().

Referenced by OpcodeTable::Initialize().

◆ HandlePetAbandon()

void WorldSession::HandlePetAbandon ( WorldPackets::Pet::PetAbandon packet)
922{
923 if (!_player->IsInWorld())
924 return;
925
926 // pet/charmed
928 if (pet && pet->ToPet() && pet->ToPet()->getPetType() == HUNTER_PET)
929 {
930 if (pet->IsPet())
931 {
932 if (pet->GetGUID() == _player->GetPetGUID())
933 {
934 uint32 feelty = pet->GetPower(POWER_HAPPINESS);
935 pet->SetPower(POWER_HAPPINESS, feelty > 50000 ? (feelty - 50000) : 0);
936 }
937
939 }
940 else if (pet->GetGUID() == _player->GetCharmGUID())
942 }
943}
@ PET_SAVE_AS_DELETED
Definition PetDefines.h:42
@ HUNTER_PET
Definition PetDefines.h:33
@ POWER_HAPPINESS
Definition SharedDefines.h:284
PetType getPetType() const
Definition Pet.h:52
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition Player.cpp:9147
void StopCastingCharm(Aura *except=nullptr)
Definition Player.cpp:9384
Pet * ToPet()
Definition Unit.h:719
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool fromRegenerate=false)
Definition Unit.cpp:15801
bool IsPet() const
Definition Unit.h:787
ObjectGuid GetPetGUID() const
Definition Unit.h:713
ObjectGuid PetGUID
Definition PetPackets.h:46

References _player, Unit::GetCharmGUID(), ObjectAccessor::GetCreatureOrPetOrVehicle(), Object::GetGUID(), Unit::GetPetGUID(), Pet::getPetType(), Unit::GetPower(), HUNTER_PET, Object::IsInWorld(), Unit::IsPet(), PET_SAVE_AS_DELETED, WorldPackets::Pet::PetAbandon::PetGUID, POWER_HAPPINESS, Player::RemovePet(), Unit::SetPower(), Player::StopCastingCharm(), and Unit::ToPet().

Referenced by OpcodeTable::Initialize().

◆ HandlePetAction()

void WorldSession::HandlePetAction ( WorldPacket recvData)
58{
59 ObjectGuid guid1;
60 uint32 data;
61 ObjectGuid guid2;
62 recvData >> guid1; //pet guid
63 recvData >> data;
64 recvData >> guid2; //tag guid
65
66 uint32 spellId = UNIT_ACTION_BUTTON_ACTION(data);
67 uint8 flag = UNIT_ACTION_BUTTON_TYPE(data); //delete = 0x07 CastSpell = C1
68
69 // used also for charmed creature
70 Unit* pet = ObjectAccessor::GetUnit(*_player, guid1);
71 LOG_DEBUG("network.opcode", "HandlePetAction: Pet {} - flag: {}, spellId: {}, target: {}.", guid1.ToString(), uint32(flag), spellId, guid2.ToString());
72
73 if (!pet)
74 {
75 LOG_ERROR("network.opcode", "HandlePetAction: Pet ({}) doesn't exist for player {}", guid1.ToString(), GetPlayer()->GetName());
76 return;
77 }
78
79 if (pet != GetPlayer()->GetFirstControlled())
80 {
81 LOG_ERROR("network.opcode", "HandlePetAction: Pet ({}) does not belong to player {}", guid1.ToString(), GetPlayer()->GetName());
82 return;
83 }
84
85 if (!pet->IsAlive())
86 {
87 // xinef: allow dissmis dead pets
88 SpellInfo const* spell = (flag == ACT_ENABLED || flag == ACT_PASSIVE) ? sSpellMgr->GetSpellInfo(spellId) : nullptr;
89 if ((flag != ACT_COMMAND || spellId != COMMAND_ABANDON) && (!spell || !spell->HasAttribute(SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD)))
90 return;
91 }
92
93 // Xinef: allow to controll players
94 if (pet->IsPlayer() && flag != ACT_COMMAND && flag != ACT_REACTION)
95 return;
96
97 // Do not follow itself vehicle
98 if (spellId == COMMAND_FOLLOW && _player->IsOnVehicle(pet))
99 {
100 return;
101 }
102
103 if (GetPlayer()->m_Controlled.size() == 1)
104 HandlePetActionHelper(pet, guid1, spellId, flag, guid2);
105 else
106 {
107 //If a pet is dismissed, m_Controlled will change
108 std::vector<Unit*> controlled;
109 for (Unit::ControlSet::iterator itr = GetPlayer()->m_Controlled.begin(); itr != GetPlayer()->m_Controlled.end(); ++itr)
110 {
111 // xinef: allow to dissmis dead pets
112 if ((*itr)->GetEntry() == pet->GetEntry() && ((*itr)->IsAlive() || (flag == ACT_COMMAND && spellId == COMMAND_ABANDON)))
113 controlled.push_back(*itr);
114 // xinef: mirror image blizzard
115 else if ((*itr)->GetEntry() == NPC_MIRROR_IMAGE && flag == ACT_COMMAND && spellId == COMMAND_FOLLOW)
116 {
117 (*itr)->InterruptNonMeleeSpells(false);
118 }
119 }
120
121 for (Unit* pet : controlled)
122 if (pet && pet->IsInWorld() && pet->GetMap() == _player->GetMap())
123 HandlePetActionHelper(pet, guid1, spellId, flag, guid2);
124 }
125}
#define UNIT_ACTION_BUTTON_ACTION(X)
Definition CharmInfo.h:31
@ ACT_REACTION
Definition CharmInfo.h:65
@ ACT_COMMAND
Definition CharmInfo.h:64
@ ACT_ENABLED
Definition CharmInfo.h:63
@ ACT_PASSIVE
Definition CharmInfo.h:61
#define UNIT_ACTION_BUTTON_TYPE(X)
Definition CharmInfo.h:32
@ NPC_MIRROR_IMAGE
Definition PetDefines.h:106
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
Definition SharedDefines.h:416
@ COMMAND_ABANDON
Definition Unit.h:565
@ COMMAND_FOLLOW
Definition Unit.h:563
ControlSet m_Controlled
Definition Unit.h:2057
void HandlePetActionHelper(Unit *pet, ObjectGuid guid1, uint32 spellid, uint16 flag, ObjectGuid guid2)
Definition PetHandler.cpp:150

References _player, ACT_COMMAND, ACT_ENABLED, ACT_PASSIVE, ACT_REACTION, COMMAND_ABANDON, COMMAND_FOLLOW, Object::GetEntry(), WorldObject::GetMap(), GetPlayer(), ObjectAccessor::GetUnit(), HandlePetActionHelper(), SpellInfo::HasAttribute(), Unit::IsAlive(), Object::IsInWorld(), Unit::IsOnVehicle(), Object::IsPlayer(), LOG_DEBUG, LOG_ERROR, Unit::m_Controlled, NPC_MIRROR_IMAGE, SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD, sSpellMgr, ObjectGuid::ToString(), UNIT_ACTION_BUTTON_ACTION, and UNIT_ACTION_BUTTON_TYPE.

Referenced by OpcodeTable::Initialize().

◆ HandlePetActionHelper()

void WorldSession::HandlePetActionHelper ( Unit pet,
ObjectGuid  guid1,
uint32  spellid,
uint16  flag,
ObjectGuid  guid2 
)
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
151{
152 CharmInfo* charmInfo = pet->GetCharmInfo();
153 if (!charmInfo)
154 {
155 LOG_ERROR("network.opcode", "WorldSession::HandlePetAction(petGuid: {}, tagGuid: {}, spellId: {}, flag: {}): object ({}) is considered pet-like but doesn't have a charminfo!",
156 guid1.ToString(), guid2.ToString(), spellId, flag, pet->GetGUID().ToString());
157 return;
158 }
159
160 switch (flag)
161 {
162 case ACT_COMMAND: //0x07
163 switch (spellId)
164 {
165 case COMMAND_STAY: //flat=1792 //STAY
166 {
168 if (!controlledMotion)
169 {
171 pet->GetMotionMaster()->Clear(false);
172 pet->GetMotionMaster()->MoveIdle();
173 }
174
175 charmInfo->SetCommandState(COMMAND_STAY);
176 charmInfo->SetIsCommandAttack(false);
177 charmInfo->SetIsCommandFollow(false);
178 charmInfo->SetIsFollowing(false);
179 charmInfo->SetIsReturning(false);
180 charmInfo->SetIsAtStay(!controlledMotion);
181 charmInfo->SaveStayPosition(controlledMotion);
182 if (pet->ToPet())
184
185 charmInfo->SetForcedSpell(0);
186 charmInfo->SetForcedTargetGUID();
187 break;
188 }
189 case COMMAND_FOLLOW: //spellId=1792 //FOLLOW
190 {
191 pet->AttackStop();
192 pet->InterruptNonMeleeSpells(false);
193 pet->ClearInPetCombat();
195 if (pet->ToPet())
198
199 charmInfo->SetIsCommandAttack(false);
200 charmInfo->SetIsAtStay(false);
201 charmInfo->SetIsReturning(true);
202 charmInfo->SetIsCommandFollow(true);
203 charmInfo->SetIsFollowing(false);
204 charmInfo->RemoveStayPosition();
205 charmInfo->SetForcedSpell(0);
206 charmInfo->SetForcedTargetGUID();
207 break;
208 }
209 case COMMAND_ATTACK: //spellId=1792 //ATTACK
210 {
211 // Can't attack if owner is pacified
212 if (_player->HasPacifyAura())
213 {
214 //pet->SendPetCastFail(spellId, SPELL_FAILED_PACIFIED);
215 //TODO: Send proper error message to client
216 return;
217 }
218
219 // only place where pet can be player
220 Unit* TargetUnit = ObjectAccessor::GetUnit(*_player, guid2);
221 if (!TargetUnit)
222 return;
223
224 if (Unit* owner = pet->GetOwner())
225 if (!owner->IsValidAttackTarget(TargetUnit))
226 return;
227
228 // pussywizard (excluded charmed)
229 if (!pet->IsCharmed())
230 if (Creature* creaturePet = pet->ToCreature())
231 if (!creaturePet->CanCreatureAttack(TargetUnit))
232 return;
233
234 // Not let attack through obstructions
235 bool checkLos = !sDisableMgr->IsPathfindingEnabled(pet->GetMap()) ||
236 (TargetUnit->IsCreature() && (TargetUnit->ToCreature()->isWorldBoss() || TargetUnit->ToCreature()->IsDungeonBoss()));
237
238 if (checkLos && !pet->IsWithinLOSInMap(TargetUnit))
239 {
240 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
241 data << uint8(0);
242 data << uint32(7389);
244 SendPacket(&data);
245 return;
246 }
247
249 // This is true if pet has no target or has target but targets differs.
250 if (pet->GetVictim() != TargetUnit || (pet->GetVictim() == TargetUnit && !pet->GetCharmInfo()->IsCommandAttack()))
251 {
252 pet->AttackStop();
253
254 if (!pet->IsPlayer() && pet->ToCreature()->IsAIEnabled)
255 {
256 charmInfo->SetIsCommandAttack(true);
257 charmInfo->SetIsAtStay(false);
258 charmInfo->SetIsFollowing(false);
259 charmInfo->SetIsCommandFollow(false);
260 charmInfo->SetIsReturning(false);
261
262 pet->ToCreature()->AI()->AttackStart(TargetUnit);
263
264 //10% chance to play special pet attack talk, else growl
265 if (pet->IsPet() && pet->ToPet()->getPetType() == SUMMON_PET && pet != TargetUnit && roll_chance_i(10))
267 else
268 {
269 // 90% chance for pet and 100% chance for charmed creature
270 pet->SendPetAIReaction(guid1);
271 }
272 }
273 else // charmed player
274 {
275 charmInfo->SetIsCommandAttack(true);
276 charmInfo->SetIsAtStay(false);
277 charmInfo->SetIsFollowing(false);
278 charmInfo->SetIsCommandFollow(false);
279 charmInfo->SetIsReturning(false);
280
281 pet->Attack(TargetUnit, true);
282 pet->SendPetAIReaction(guid1);
283 }
284 }
285 break;
286 }
287 case COMMAND_ABANDON: // abandon (hunter pet) or dismiss (summoned pet)
288 if (pet->GetCharmerGUID() == GetPlayer()->GetGUID())
289 {
291 }
292 else if (pet->GetOwnerGUID() == GetPlayer()->GetGUID())
293 {
294 ASSERT(pet->IsCreature());
295 if (pet->IsPet())
296 {
297 if (pet->ToPet()->getPetType() == HUNTER_PET)
299 else
300 {
301 pet->SendPetDismissSound();
302 //dismissing a summoned pet is like killing them (this prevents returning a soulshard...)
304 }
305 }
307 {
308 pet->ToTempSummon()->UnSummon();
309 }
310 }
311 break;
312 default:
313 LOG_ERROR("network.opcode", "WORLD: unknown PET flag Action {} and spellId {}.", uint32(flag), spellId);
314 }
315 break;
316 case ACT_REACTION: // 0x6
317 switch (spellId)
318 {
319 case REACT_PASSIVE: //passive
320 pet->AttackStop();
321 if (pet->ToPet())
323 pet->ClearInPetCombat();
324 [[fallthrough]];
325
326 case REACT_DEFENSIVE: //recovery
327 case REACT_AGGRESSIVE: //activete
328 if (pet->IsCreature())
329 pet->ToCreature()->SetReactState(ReactStates(spellId));
330 else
331 charmInfo->SetPlayerReactState(ReactStates(spellId));
332 break;
333 }
334 break;
335 case ACT_DISABLED: // 0x81 spell (disabled), ignore
336 case ACT_PASSIVE: // 0x01
337 case ACT_ENABLED: // 0xC1 spell
338 {
339 Unit* unit_target = nullptr;
340
341 // do not cast unknown spells
342 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
343 if (!spellInfo)
344 {
345 LOG_ERROR("network.opcode", "WORLD: unknown PET spell id {}", spellId);
346 return;
347 }
348
349 if (guid2)
350 unit_target = ObjectAccessor::GetUnit(*_player, guid2);
351 else if (!spellInfo->IsPositive())
352 return;
353
354 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
355 {
356 if (spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_SRC_AREA_ENEMY || spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_DEST_AREA_ENEMY || spellInfo->Effects[i].TargetA.GetTarget() == TARGET_DEST_DYNOBJ_ENEMY)
357 return;
358 }
359
360 TriggerCastFlags triggerCastFlags = TRIGGERED_NONE;
361
362 if (spellInfo->IsPassive())
363 return;
364
365 // cast only learned spells
366 if (!pet->HasSpell(spellId))
367 {
368 bool allow = false;
369
370 // allow casting of spells triggered by clientside periodic trigger auras
372 {
373 allow = true;
374 triggerCastFlags = TRIGGERED_FULL_MASK;
375 }
376
377 if (!allow)
378 return;
379 }
380
381 Spell* spell = new Spell(pet, spellInfo, triggerCastFlags);
382 spell->LoadScripts(); // xinef: load for CheckPetCast
383
384 SpellCastResult result = spell->CheckPetCast(unit_target);
385
386 //auto turn to target unless possessed
387 if (result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->isPossessed() && !pet->IsVehicle())
388 {
389 if (unit_target)
390 {
391 pet->SetInFront(unit_target);
392 if (unit_target->IsPlayer())
393 pet->SendUpdateToPlayer(unit_target->ToPlayer());
394 }
395 else if (Unit* unit_target2 = spell->m_targets.GetUnitTarget())
396 {
397 pet->SetInFront(unit_target2);
398 if (unit_target2->IsPlayer())
399 pet->SendUpdateToPlayer(unit_target2->ToPlayer());
400 }
401 if (Unit* powner = pet->GetCharmerOrOwner())
402 if (powner->IsPlayer())
403 pet->SendUpdateToPlayer(powner->ToPlayer());
404
405 result = SPELL_CAST_OK;
406 }
407
408 if (result == SPELL_CAST_OK)
409 {
410 if (!spellInfo->IsCooldownStartedOnEvent())
411 {
412 pet->ToCreature()->AddSpellCooldown(spellId, 0, 0);
413 }
414
415 unit_target = spell->m_targets.GetUnitTarget();
416
417 //10% chance to play special pet attack talk, else growl
418 //actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
419 if (pet->IsPet() && (pet->ToPet()->getPetType() == SUMMON_PET) && (pet != unit_target) && roll_chance_i(10))
421 else
422 {
423 pet->SendPetAIReaction(guid1);
424 }
425
426 if (unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->isPossessed() && !pet->IsVehicle())
427 {
428 // This is true if pet has no target or has target but targets differs.
429 if (pet->GetVictim() != unit_target)
430 {
431 if (pet->ToCreature()->IsAIEnabled)
432 pet->ToCreature()->AI()->AttackStart(unit_target);
433 }
434 }
435
436 spell->prepare(&(spell->m_targets));
437
438 // spell->prepare() can delete charm info.
439 // Let's refresh the pointer.
440 charmInfo = pet->GetCharmInfo();
441 if (charmInfo)
442 {
443 charmInfo->SetForcedSpell(0);
444 charmInfo->SetForcedTargetGUID();
445 }
446 }
447 else if (pet->ToPet() && (result == SPELL_FAILED_LINE_OF_SIGHT || result == SPELL_FAILED_OUT_OF_RANGE))
448 {
449 unit_target = spell->m_targets.GetUnitTarget();
450 bool haspositiveeffect = false;
451
452 if (!unit_target)
453 {
454 delete spell;
455 return;
456 }
457
458 // search positive effects for spell
459 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
460 {
461 if (spellInfo->_IsPositiveEffect(i, true))
462 {
463 haspositiveeffect = true;
464 break;
465 }
466 }
467
468 if (pet->isPossessed() || pet->IsVehicle())
469 Spell::SendCastResult(GetPlayer(), spellInfo, 0, result);
470 else if (GetPlayer()->IsFriendlyTo(unit_target) && !haspositiveeffect)
472 else
474
475 if (!pet->HasSpellCooldown(spellId))
476 if (pet->ToPet())
477 pet->ToPet()->RemoveSpellCooldown(spellId, true);
478
479 spell->finish(false);
480 delete spell;
481
482 if (_player->HasPacifyAura())
483 return;
484
485 bool tempspellIsPositive = false;
486
487 if (!GetPlayer()->IsFriendlyTo(unit_target))
488 {
489 // only place where pet can be player
490 Unit* TargetUnit = ObjectAccessor::GetUnit(*_player, guid2);
491 if (!TargetUnit)
492 return;
493
494 if (Unit* owner = pet->GetOwner())
495 if (!owner->IsValidAttackTarget(TargetUnit))
496 return;
497
499 // This is true if pet has no target or has target but targets differs.
500 if (pet->GetVictim() != TargetUnit || (pet->GetVictim() == TargetUnit && !pet->GetCharmInfo()->IsCommandAttack()))
501 {
502 if (pet->GetVictim())
503 pet->AttackStop();
504
505 if (!pet->IsPlayer() && pet->ToCreature() && pet->ToCreature()->IsAIEnabled)
506 {
507 charmInfo->SetIsCommandAttack(true);
508 charmInfo->SetIsAtStay(false);
509 charmInfo->SetIsFollowing(false);
510 charmInfo->SetIsCommandFollow(false);
511 charmInfo->SetIsReturning(false);
512
513 pet->ToCreature()->AI()->AttackStart(TargetUnit);
514
515 if (pet->IsPet() && pet->ToPet()->getPetType() == SUMMON_PET && pet != TargetUnit && roll_chance_i(10))
517 else
518 pet->SendPetAIReaction(guid1);
519 }
520 else // charmed player
521 {
522 if (pet->GetVictim() && pet->GetVictim() != TargetUnit)
523 pet->AttackStop();
524
525 charmInfo->SetIsCommandAttack(true);
526 charmInfo->SetIsAtStay(false);
527 charmInfo->SetIsFollowing(false);
528 charmInfo->SetIsCommandFollow(false);
529 charmInfo->SetIsReturning(false);
530
531 pet->Attack(TargetUnit, true);
532 pet->SendPetAIReaction(guid1);
533 }
534
535 pet->ToPet()->CastWhenWillAvailable(spellId, unit_target, ObjectGuid::Empty, tempspellIsPositive);
536 }
537 }
538 else if (haspositiveeffect)
539 {
540 bool tmpSpellIsPositive = true;
542 // This is true if pet has no target or has target but targets differs.
543 Unit* victim = pet->GetVictim();
544 if (victim)
545 {
546 pet->AttackStop();
547 }
548 else
549 victim = nullptr;
550
551 if (!pet->IsPlayer() && pet->ToCreature() && pet->ToCreature()->IsAIEnabled)
552 {
553 pet->StopMoving();
554 pet->GetMotionMaster()->Clear();
555
556 charmInfo->SetIsCommandAttack(false);
557 charmInfo->SetIsAtStay(false);
558 charmInfo->SetIsFollowing(false);
559 charmInfo->SetIsCommandFollow(false);
560 charmInfo->SetIsReturning(false);
561
562 pet->GetMotionMaster()->MoveFollow(unit_target, PET_FOLLOW_DIST, rand_norm() * 2 * M_PI);
563
564 if (pet->IsPet() && pet->ToPet()->getPetType() == SUMMON_PET && pet != unit_target && roll_chance_i(10))
566 else
567 {
568 pet->SendPetAIReaction(guid1);
569 }
570
571 ObjectGuid oldTarget = ObjectGuid::Empty;
572 if (victim)
573 oldTarget = victim->GetGUID();
574
575 pet->ToPet()->CastWhenWillAvailable(spellId, unit_target, oldTarget, tmpSpellIsPositive);
576 }
577 }
578 }
579 else
580 {
581 // dont spam alerts
582 if (!charmInfo->GetForcedSpell())
583 {
584 if (pet->isPossessed() || pet->IsVehicle())
585 Spell::SendCastResult(GetPlayer(), spellInfo, 0, result);
586 else
587 spell->SendPetCastResult(result);
588 }
589
590 if (!pet->ToCreature()->HasSpellCooldown(spellId))
591 GetPlayer()->SendClearCooldown(spellId, pet);
592
593 spell->finish(false);
594 delete spell;
595
596 // reset specific flags in case of spell fail. AI will reset other flags
597 pet->PetSpellFail(spellInfo, unit_target, result);
598 }
599 break;
600 }
601 default:
602 LOG_ERROR("network.opcode", "WORLD: unknown PET flag Action {} and spellId {}.", uint32(flag), spellId);
603 }
604}
@ ACT_DISABLED
Definition CharmInfo.h:62
#define MAX_SPELL_EFFECTS
Definition DBCStructure.h:1635
@ MOTION_SLOT_CONTROLLED
Definition MotionMaster.h:65
@ NULL_MOTION_TYPE
Definition MotionMaster.h:58
constexpr float PET_FOLLOW_DIST
Definition PetDefines.h:206
@ PET_ACTION_ATTACK
Definition PetDefines.h:82
@ PET_ACTION_SPECIAL_SPELL
Definition PetDefines.h:81
@ SUMMON_PET
Definition PetDefines.h:32
double rand_norm()
Definition Random.cpp:85
bool roll_chance_i(int chance)
Definition Random.h:63
@ TARGET_DEST_DYNOBJ_ENEMY
Definition SharedDefines.h:1443
@ TARGET_UNIT_DEST_AREA_ENEMY
Definition SharedDefines.h:1432
@ TARGET_UNIT_SRC_AREA_ENEMY
Definition SharedDefines.h:1431
@ SPELL_FAILED_UNIT_NOT_INFRONT
Definition SharedDefines.h:1094
@ SPELL_FAILED_OUT_OF_RANGE
Definition SharedDefines.h:1057
@ SPELL_FAILED_LINE_OF_SIGHT
Definition SharedDefines.h:1007
@ SPELL_FAILED_TARGET_FRIENDLY
Definition SharedDefines.h:1075
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT
Definition SpellAuraDefines.h:111
@ UNIT_MASK_SUMMON
Definition UnitDefines.h:156
@ UNIT_MASK_CONTROLLABLE_GUARDIAN
Definition UnitDefines.h:164
@ UNIT_MASK_GUARDIAN
Definition UnitDefines.h:158
@ UNIT_MASK_MINION
Definition UnitDefines.h:157
@ UNIT_STATE_FOLLOW
Definition UnitDefines.h:179
ReactStates
Definition Unit.h:554
@ REACT_DEFENSIVE
Definition Unit.h:556
@ REACT_PASSIVE
Definition Unit.h:555
@ REACT_AGGRESSIVE
Definition Unit.h:557
@ COMMAND_ATTACK
Definition Unit.h:564
@ COMMAND_STAY
Definition Unit.h:562
bool IsDungeonBoss() const
Definition Creature.cpp:3176
bool isWorldBoss() const
Definition Creature.h:125
bool HasSpellCooldown(uint32 spell_id) const override
Definition Creature.cpp:2929
void AddSpellCooldown(uint32 spell_id, uint32, uint32 end_time, bool needSendToClient=false, bool forceSendToSpectator=false) override
Definition Creature.cpp:2874
void SetReactState(ReactStates state)
A creature can have 3 ReactStates : Agressive, Passive, Neutral.
Definition Creature.h:99
MovementGeneratorType GetMotionSlotType(int slot) const
Definition MotionMaster.cpp:957
void MoveIdle()
Definition MotionMaster.cpp:233
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE, bool inheritWalkState=true, bool inheritSpeed=true)
The unit will follow this target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition MotionMaster.cpp:446
void Clear(bool reset=true)
Definition MotionMaster.h:192
void ClearCastWhenWillAvailable()
Definition Pet.cpp:2435
void RemoveSpellCooldown(uint32 spell_id, bool update)
Definition Pet.cpp:2443
void CastWhenWillAvailable(uint32 spellid, Unit *spellTarget, ObjectGuid oldTarget, bool spellIsPositive=false)
Definition Pet.cpp:2419
void SendClearCooldown(uint32 spell_id, Unit *target)
Definition Player.cpp:14762
bool IsCooldownStartedOnEvent() const
Definition SpellInfo.cpp:1212
bool _IsPositiveEffect(uint8 effIndex, bool deep) const
Definition SpellInfo.cpp:2520
void LoadScripts()
Definition Spell.cpp:8500
void SendPetCastResult(SpellCastResult result)
Definition Spell.cpp:4648
SpellCastResult CheckPetCast(Unit *target)
Definition Spell.cpp:6784
virtual void AttackStart(Unit *)
Definition UnitAI.cpp:27
void ClearUnitState(uint32 f)
Definition Unit.h:727
bool IsVehicle() const
Definition Unit.h:790
virtual void setDeathState(DeathState s, bool despawn=false)
Definition Unit.cpp:14658
Unit * GetOwner() const
Definition Unit.cpp:10804
virtual bool HasSpellCooldown(uint32) const
Definition Unit.h:1320
void SendPetAIReaction(ObjectGuid guid) const
Definition Unit.cpp:16847
void PetSpellFail(SpellInfo const *spellInfo, Unit *target, uint32 result)
Definition Unit.cpp:20319
void StopMoving()
Definition Unit.cpp:16866
CharmInfo * GetCharmInfo()
Definition Unit.h:1266
virtual bool HasSpell(uint32) const
Definition Unit.h:1567
Unit * GetCharmerOrOwner() const
Definition Unit.h:1271
void ClearInPetCombat()
Definition Unit.cpp:14002
bool isPossessed() const
Definition Unit.h:1296
void SendPetActionSound(PetAction action) const
Definition Unit.cpp:16836
virtual float GetFollowAngle() const
Definition Unit.h:1875
Unit * GetVictim() const
Definition Unit.h:893
void StopMovingOnCurrentPos()
Definition Unit.cpp:16905
bool IsAIEnabled
Definition Unit.h:2079
ObjectGuid GetOwnerGUID() const
Definition Unit.h:703
uint32 HasUnitTypeMask(uint32 mask) const
Definition Unit.h:731
ObjectGuid GetCharmerGUID() const
Definition Unit.h:709
bool HasAuraTypeWithTriggerSpell(AuraType auratype, uint32 triggerSpell) const
Definition Unit.cpp:5898
void SetInFront(WorldObject const *target)
Definition Unit.cpp:20490
bool HasPacifyAura() const
Definition Unit.h:1807
void SendPetDismissSound() const
Definition Unit.cpp:16841
bool IsWithinLOSInMap(WorldObject const *obj, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, Optional< float > collisionHeight={ }, Optional< float > combatReach={ }) const
Definition Object.cpp:1373
@ SMSG_CAST_FAILED
Definition Opcodes.h:334
Definition CharmInfo.h:127
void RemoveStayPosition()
Definition CharmInfo.cpp:353
int32 GetForcedSpell()
Definition CharmInfo.h:178
void SetIsCommandFollow(bool val)
Definition CharmInfo.cpp:313
bool IsCommandAttack()
Definition CharmInfo.cpp:308
void SetIsAtStay(bool val)
Definition CharmInfo.cpp:365
void SetIsFollowing(bool val)
Definition CharmInfo.cpp:375
void SetIsReturning(bool val)
Definition CharmInfo.cpp:385
void SaveStayPosition(bool atCurrentPos)
Definition CharmInfo.cpp:323
void SetForcedSpell(uint32 id)
Definition CharmInfo.h:177
void SetPlayerReactState(ReactStates s)
Definition CharmInfo.h:183
void SetForcedTargetGUID(ObjectGuid guid=ObjectGuid::Empty)
Definition CharmInfo.h:179
void SetCommandState(CommandStates st)
Definition CharmInfo.h:135
void SetIsCommandAttack(bool val)
Definition CharmInfo.cpp:303

References SpellInfo::_IsPositiveEffect(), _player, ACT_COMMAND, ACT_DISABLED, ACT_ENABLED, ACT_PASSIVE, ACT_REACTION, Creature::AddSpellCooldown(), Creature::AI(), ASSERT, Unit::Attack(), UnitAI::AttackStart(), Unit::AttackStop(), Pet::CastWhenWillAvailable(), Spell::CheckPetCast(), MotionMaster::Clear(), Pet::ClearCastWhenWillAvailable(), Unit::ClearInPetCombat(), Unit::ClearUnitState(), COMMAND_ABANDON, COMMAND_ATTACK, COMMAND_FOLLOW, COMMAND_STAY, Corpse, SpellInfo::Effects, ObjectGuid::Empty, Spell::finish(), Unit::GetCharmerGUID(), Unit::GetCharmerOrOwner(), Unit::GetCharmInfo(), Unit::GetFollowAngle(), CharmInfo::GetForcedSpell(), Object::GetGUID(), WorldObject::GetMap(), Unit::GetMotionMaster(), MotionMaster::GetMotionSlotType(), Unit::GetOwner(), Unit::GetOwnerGUID(), Pet::getPetType(), GetPlayer(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTarget(), Unit::GetVictim(), Unit::HasAuraTypeWithTriggerSpell(), Unit::HasPacifyAura(), Unit::HasSpell(), Creature::HasSpellCooldown(), Unit::HasSpellCooldown(), Unit::HasUnitTypeMask(), HUNTER_PET, Unit::InterruptNonMeleeSpells(), Unit::IsAIEnabled, Unit::IsCharmed(), CharmInfo::IsCommandAttack(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), Creature::IsDungeonBoss(), SpellInfo::IsPassive(), Unit::IsPet(), Object::IsPlayer(), SpellInfo::IsPositive(), Unit::isPossessed(), Unit::IsVehicle(), WorldObject::IsWithinLOSInMap(), Creature::isWorldBoss(), Spell::LoadScripts(), LOG_ERROR, Spell::m_targets, MAX_SPELL_EFFECTS, MOTION_SLOT_CONTROLLED, MotionMaster::MoveFollow(), MotionMaster::MoveIdle(), NULL_MOTION_TYPE, PET_ACTION_ATTACK, PET_ACTION_SPECIAL_SPELL, PET_FOLLOW_DIST, PET_SAVE_AS_DELETED, Unit::PetSpellFail(), Spell::prepare(), rand_norm(), REACT_AGGRESSIVE, REACT_DEFENSIVE, REACT_PASSIVE, Player::RemovePet(), Pet::RemoveSpellCooldown(), CharmInfo::RemoveStayPosition(), roll_chance_i(), CharmInfo::SaveStayPosition(), sDisableMgr, Spell::SendCastResult(), Player::SendClearCooldown(), SendPacket(), Unit::SendPetActionSound(), Unit::SendPetAIReaction(), Spell::SendPetCastResult(), Unit::SendPetDismissSound(), Object::SendUpdateToPlayer(), CharmInfo::SetCommandState(), Unit::setDeathState(), CharmInfo::SetForcedSpell(), CharmInfo::SetForcedTargetGUID(), Unit::SetInFront(), CharmInfo::SetIsAtStay(), CharmInfo::SetIsCommandAttack(), CharmInfo::SetIsCommandFollow(), CharmInfo::SetIsFollowing(), CharmInfo::SetIsReturning(), CharmInfo::SetPlayerReactState(), Creature::SetReactState(), SMSG_CAST_FAILED, SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT, SPELL_CAST_OK, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_TARGET_FRIENDLY, SPELL_FAILED_UNIT_NOT_INFRONT, sSpellMgr, Player::StopCastingCharm(), Unit::StopMoving(), Unit::StopMovingOnCurrentPos(), SUMMON_PET, TARGET_DEST_DYNOBJ_ENEMY, TARGET_UNIT_DEST_AREA_ENEMY, TARGET_UNIT_SRC_AREA_ENEMY, Object::ToCreature(), Unit::ToPet(), Object::ToPlayer(), ObjectGuid::ToString(), Unit::ToTempSummon(), TRIGGERED_FULL_MASK, TRIGGERED_NONE, UNIT_MASK_CONTROLLABLE_GUARDIAN, UNIT_MASK_GUARDIAN, UNIT_MASK_MINION, UNIT_MASK_SUMMON, UNIT_STATE_FOLLOW, and TempSummon::UnSummon().

Referenced by HandlePetAction(), and PetAI::UpdateAI().

◆ HandlePetCancelAuraOpcode()

void WorldSession::HandlePetCancelAuraOpcode ( WorldPacket recvPacket)
601{
602 ObjectGuid guid;
603 uint32 spellId;
604
605 recvPacket >> guid;
606 recvPacket >> spellId;
607
608 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
609 if (!spellInfo)
610 {
611 LOG_ERROR("network.opcode", "WORLD: unknown PET spell id {}", spellId);
612 return;
613 }
614
616
617 if (!pet)
618 {
619 LOG_ERROR("network.opcode", "HandlePetCancelAura: Attempt to cancel an aura for non-existant pet {} by player {}", guid.ToString(), GetPlayer()->GetName());
620 return;
621 }
622
623 if (pet != GetPlayer()->GetGuardianPet() && pet != GetPlayer()->GetCharm())
624 {
625 LOG_ERROR("network.opcode", "HandlePetCancelAura: Pet {} is not a pet of player {}", guid.ToString(), GetPlayer()->GetName());
626 return;
627 }
628
629 if (!pet->IsAlive())
630 {
632 return;
633 }
634
636}
@ FEEDBACK_PET_DEAD
Definition PetDefines.h:74
void SendPetActionFeedback(uint8 msg) const
-------—Pet responses methods--------------—
Definition Unit.cpp:16825

References _player, AURA_REMOVE_BY_CANCEL, ObjectGuid::Empty, FEEDBACK_PET_DEAD, ObjectAccessor::GetCreatureOrPetOrVehicle(), GetPlayer(), Unit::IsAlive(), LOG_ERROR, Unit::RemoveOwnedAura(), Unit::SendPetActionFeedback(), sSpellMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandlePetCastSpellOpcode()

void WorldSession::HandlePetCastSpellOpcode ( WorldPacket recvPacket)
1002{
1003 LOG_DEBUG("network", "WORLD: CMSG_PET_CAST_SPELL");
1004
1005 ObjectGuid guid;
1006 uint8 castCount;
1007 uint32 spellId;
1008 uint8 castFlags;
1009
1010 recvPacket >> guid >> castCount >> spellId >> castFlags;
1011
1012 LOG_DEBUG("network", "WORLD: CMSG_PET_CAST_SPELL, guid: {}, castCount: {}, spellId {}, castFlags {}", guid.ToString(), castCount, spellId, castFlags);
1013
1014 // This opcode is also sent from charmed and possessed units (players and creatures)
1015 if (!_player->GetGuardianPet() && !_player->GetCharm())
1016 return;
1017
1018 Unit* caster = ObjectAccessor::GetUnit(*_player, guid);
1019
1020 if (!caster || (caster != _player->GetGuardianPet() && caster != _player->GetCharm()))
1021 {
1022 LOG_ERROR("network.opcode", "HandlePetCastSpellOpcode: Pet {} isn't pet of player {} .", guid.ToString(), GetPlayer()->GetName());
1023 return;
1024 }
1025
1026 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
1027 if (!spellInfo)
1028 {
1029 LOG_ERROR("network.opcode", "WORLD: unknown PET spell id {}", spellId);
1030 return;
1031 }
1032
1033 // do not cast not learned spells
1034 if (!caster->HasSpell(spellId) || spellInfo->IsPassive())
1035 return;
1036
1037 SpellCastTargets targets;
1038 targets.Read(recvPacket, caster);
1039 HandleClientCastFlags(recvPacket, castFlags, targets);
1040
1041 bool SetFollow = caster->HasUnitState(UNIT_STATE_FOLLOW);
1043
1044 Spell* spell = new Spell(caster, spellInfo, TRIGGERED_NONE);
1045 spell->m_cast_count = castCount; // probably pending spell cast
1046 spell->m_targets = targets;
1047 spell->LoadScripts();
1048
1049 // Xinef: Send default target, fixes return on NeedExplicitUnitTarget
1050 Unit* target = targets.GetUnitTarget();
1051 if (!target && spell->m_spellInfo->NeedsExplicitUnitTarget())
1052 target = _player->GetSelectedUnit();
1053
1054 SpellCastResult result = spell->CheckPetCast(target);
1055
1056 if (result == SPELL_CAST_OK)
1057 {
1058 if (Creature* creature = caster->ToCreature())
1059 {
1060 creature->AddSpellCooldown(spellId, 0, 0);
1061 if (Pet* pet = creature->ToPet())
1062 {
1063 // 10% chance to play special pet attack talk, else growl
1064 // actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
1065 if (pet->getPetType() == SUMMON_PET && roll_chance_i(10))
1066 pet->SendPetActionSound(PET_ACTION_SPECIAL_SPELL);
1067 else
1068 pet->SendPetAIReaction(guid);
1069 }
1070 }
1071
1072 spell->prepare(&(spell->m_targets));
1073 }
1074 else
1075 {
1076 if (!caster->GetCharmInfo() || !caster->GetCharmInfo()->GetForcedSpell())
1077 spell->SendPetCastResult(result);
1078
1079 if (caster->IsPlayer())
1080 {
1081 if (!caster->ToPlayer()->HasSpellCooldown(spellId))
1082 GetPlayer()->SendClearCooldown(spellId, caster);
1083 }
1084 else
1085 {
1086 if (!caster->ToCreature()->HasSpellCooldown(spellId))
1087 GetPlayer()->SendClearCooldown(spellId, caster);
1088
1089 // reset specific flags in case of spell fail. AI will reset other flags
1090 if (caster->IsPet())
1091 caster->PetSpellFail(spellInfo, targets.GetUnitTarget(), result);
1092 }
1093
1094 spell->finish(false);
1095 delete spell;
1096 }
1097
1098 if (SetFollow && !caster->IsInCombat())
1100}
bool HasSpellCooldown(uint32 spell_id) const override
Definition Player.cpp:16352
Unit * GetSelectedUnit() const
Definition Player.cpp:11553
bool NeedsExplicitUnitTarget() const
Definition SpellInfo.cpp:1033
Unit * GetCharm() const
Definition Unit.cpp:10875
void AddUnitState(uint32 f)
Definition Unit.h:725
Guardian * GetGuardianPet() const
Definition Unit.cpp:10855

References _player, Unit::AddUnitState(), Spell::CheckPetCast(), Unit::ClearUnitState(), Spell::finish(), Unit::GetCharm(), Unit::GetCharmInfo(), CharmInfo::GetForcedSpell(), Unit::GetGuardianPet(), GetPlayer(), Player::GetSelectedUnit(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTarget(), HandleClientCastFlags(), Unit::HasSpell(), Creature::HasSpellCooldown(), Player::HasSpellCooldown(), Unit::HasUnitState(), Unit::IsInCombat(), SpellInfo::IsPassive(), Unit::IsPet(), Object::IsPlayer(), Spell::LoadScripts(), LOG_DEBUG, LOG_ERROR, Spell::m_cast_count, Spell::m_spellInfo, Spell::m_targets, SpellInfo::NeedsExplicitUnitTarget(), PET_ACTION_SPECIAL_SPELL, Unit::PetSpellFail(), Spell::prepare(), SpellCastTargets::Read(), roll_chance_i(), Player::SendClearCooldown(), Spell::SendPetCastResult(), SPELL_CAST_OK, sSpellMgr, SUMMON_PET, Object::ToCreature(), Unit::ToPet(), Object::ToPlayer(), ObjectGuid::ToString(), TRIGGERED_NONE, and UNIT_STATE_FOLLOW.

Referenced by OpcodeTable::Initialize().

◆ HandlePetitionBuyOpcode()

void WorldSession::HandlePetitionBuyOpcode ( WorldPacket recvData)
Todo:
: find correct opcode
33{
34 LOG_DEBUG("network", "Received opcode CMSG_PETITION_BUY");
35
36 ObjectGuid guidNPC;
37 uint32 clientIndex; // 1 for guild and arenaslot+1 for arenas in client
38 std::string name;
39
40 recvData >> guidNPC; // NPC GUID
41 recvData.read_skip<uint32>(); // 0
42 recvData.read_skip<uint64>(); // 0
43 recvData >> name; // name
44 recvData.read_skip<std::string>(); // some string
45 recvData.read_skip<uint32>(); // 0
46 recvData.read_skip<uint32>(); // 0
47 recvData.read_skip<uint32>(); // 0
48 recvData.read_skip<uint32>(); // 0
49 recvData.read_skip<uint32>(); // 0
50 recvData.read_skip<uint32>(); // 0
51 recvData.read_skip<uint32>(); // 0
52 recvData.read_skip<uint16>(); // 0
53 recvData.read_skip<uint32>(); // 0
54 recvData.read_skip<uint32>(); // 0
55 recvData.read_skip<uint32>(); // 0
56
57 for (int i = 0; i < 10; ++i)
58 recvData.read_skip<std::string>();
59
60 recvData >> clientIndex; // index
61 recvData.read_skip<uint32>(); // 0
62
63 LOG_DEBUG("network", "Petitioner ({}) tried sell petition: name {}", guidNPC.ToString(), name);
64
65 // prevent cheating
67 if (!creature)
68 {
69 LOG_DEBUG("network", "WORLD: HandlePetitionBuyOpcode - Unit ({}) not found or you can't interact with him.", guidNPC.ToString());
70 return;
71 }
72
73 // remove fake death
74 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
76
77 uint32 charterid = 0;
78 uint32 cost = 0;
79 uint32 type = 0;
80 if (creature->IsTabardDesigner())
81 {
82 // if tabard designer, then trying to buy a guild charter.
83 // do not let if already in guild.
84 if (_player->GetGuildId())
85 return;
86
87 charterid = GUILD_CHARTER;
88 cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD);
89 type = GUILD_CHARTER_TYPE;
90 }
91 else
92 {
94 if (_player->GetLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
95 {
97 return;
98 }
99
100 switch (clientIndex) // arenaSlot+1 as received from client (1 from 3 case)
101 {
102 case 1:
103 charterid = ARENA_TEAM_CHARTER_2v2;
104 cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_2v2);
106 break;
107 case 2:
108 charterid = ARENA_TEAM_CHARTER_3v3;
109 cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_3v3);
111 break;
112 case 3:
113 charterid = ARENA_TEAM_CHARTER_5v5;
114 cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_5v5);
116 break;
117 default:
118 LOG_DEBUG("network", "unknown selection at buy arena petition: {}", clientIndex);
119 return;
120 }
121
122 if (_player->GetArenaTeamId(clientIndex - 1)) // arenaSlot+1 as received from client
123 {
125 return;
126 }
127 }
128
129 sScriptMgr->OnPlayerPetitionBuy(_player, creature, charterid, cost, type);
130
131 if (type == GUILD_CHARTER_TYPE)
132 {
133 if (sGuildMgr->GetGuildByName(name))
134 {
136 return;
137 }
138
140 {
142 return;
143 }
144 }
145 else
146 {
147 if (sArenaTeamMgr->GetArenaTeamByName(name))
148 {
150 return;
151 }
153 {
155 return;
156 }
157 }
158
159 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(charterid);
160 if (!pProto)
161 {
162 _player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, nullptr, charterid, 0);
163 return;
164 }
165
166 if (!_player->HasEnoughMoney(cost))
167 {
168 //player hasn't got enough money
169 _player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, creature, charterid, 0);
170 return;
171 }
172
173 ItemPosCountVec dest;
174 InventoryResult msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, charterid, pProto->BuyCount);
175 if (msg != EQUIP_ERR_OK)
176 {
177 _player->SendEquipError(msg, nullptr, nullptr, charterid);
178 return;
179 }
180
181 _player->ModifyMoney(-(int32)cost);
182 Item* charter = _player->StoreNewItem(dest, charterid, true);
183 if (!charter)
184 return;
185
186 // Use a 31-bit safe petition id instead of the raw item guid
187 uint32 petitionId = sPetitionMgr->GeneratePetitionId();
188 charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1, petitionId);
189 // ITEM_FIELD_ENCHANTMENT_1_1 is guild/arenateam id
190 // ITEM_FIELD_ENCHANTMENT_1_1+1 is current signatures count (showed on item)
191 charter->SetState(ITEM_CHANGED, _player);
192 _player->SendNewItem(charter, 1, true, false);
193
194 // a petition is invalid, if both the owner and the type matches
195 // we checked above, if this player is in an arenateam, so this must be
196 // datacorruption
197 Petition const* petition = sPetitionMgr->GetPetitionByOwnerWithType(_player->GetGUID(), type);
198
199 CharacterDatabase.EscapeString(name);
200 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
201
202 if (petition)
203 {
204 LOG_DEBUG("network", "Invalid petition: {}", petition->petitionGuid.ToString());
205
206 trans->Append("DELETE FROM petition WHERE petitionguid = {}", petition->petitionGuid.GetCounter());
207 trans->Append("DELETE FROM petition_sign WHERE petitionguid = {}", petition->petitionGuid.GetCounter());
208
209 // xinef: clear petition store
210 sPetitionMgr->RemovePetition(petition->petitionGuid);
211 }
212
213 // xinef: petition pointer is invalid from now on
214
216 // petition_id, ownerguid, petitionguid(item guid), name, type
217 stmt->SetData(0, petitionId);
218 stmt->SetData(1, _player->GetGUID().GetCounter());
219 stmt->SetData(2, charter->GetGUID().GetCounter());
220 stmt->SetData(3, name);
221 stmt->SetData(4, uint8(type));
222 trans->Append(stmt);
223
224 CharacterDatabase.CommitTransaction(trans);
225
226 // xinef: fill petition store (include petitionId)
227 sPetitionMgr->AddPetition(charter->GetGUID(), _player->GetGUID(), name, uint8(type), petitionId);
228}
@ ERR_ARENA_TEAM_NAME_INVALID
Definition ArenaTeam.h:45
@ ERR_ARENA_TEAM_NAME_EXISTS_S
Definition ArenaTeam.h:46
@ CHAR_INS_PETITION
Definition CharacterDatabase.h:383
@ ERR_GUILD_NAME_EXISTS_S
Definition Guild.h:126
@ ERR_GUILD_NAME_INVALID
Definition Guild.h:125
@ GUILD_CHARTER
Definition PetitionMgr.h:31
@ ARENA_TEAM_CHARTER_2v2
Definition PetitionMgr.h:32
@ ARENA_TEAM_CHARTER_5v5
Definition PetitionMgr.h:34
@ ARENA_TEAM_CHARTER_3v3
Definition PetitionMgr.h:33
@ UNIT_NPC_FLAG_PETITIONER
Definition UnitDefines.h:337
@ ITEM_FIELD_ENCHANTMENT_1_1
Definition UpdateFields.h:43
@ CONFIG_CHARTER_COST_GUILD
Definition WorldConfig.h:354
@ CONFIG_CHARTER_COST_ARENA_5v5
Definition WorldConfig.h:357
@ CONFIG_CHARTER_COST_ARENA_2v2
Definition WorldConfig.h:355
@ CONFIG_CHARTER_COST_ARENA_3v3
Definition WorldConfig.h:356
static bool IsValidCharterName(std::string_view name)
Definition ObjectMgr.cpp:8691
bool IsTabardDesigner() const
Definition Unit.h:804
@ ARENA_TEAM_CHARTER_2v2_TYPE
Definition WorldSession.h:262
@ ARENA_TEAM_CHARTER_3v3_TYPE
Definition WorldSession.h:263
@ ARENA_TEAM_CHARTER_5v5_TYPE
Definition WorldSession.h:264
uint32 BuyCount
Definition ItemTemplate.h:629
ObjectGuid petitionGuid
Definition PetitionMgr.h:42

References _player, ARENA_TEAM_CHARTER_2v2, ARENA_TEAM_CHARTER_2v2_TYPE, ARENA_TEAM_CHARTER_3v3, ARENA_TEAM_CHARTER_3v3_TYPE, ARENA_TEAM_CHARTER_5v5, ARENA_TEAM_CHARTER_5v5_TYPE, BUY_ERR_CANT_FIND_ITEM, BUY_ERR_NOT_ENOUGHT_MONEY, ItemTemplate::BuyCount, Player::CanStoreNewItem(), CHAR_INS_PETITION, CharacterDatabase, CONFIG_CHARTER_COST_ARENA_2v2, CONFIG_CHARTER_COST_ARENA_3v3, CONFIG_CHARTER_COST_ARENA_5v5, CONFIG_CHARTER_COST_GUILD, CONFIG_MAX_PLAYER_LEVEL, EQUIP_ERR_OK, ERR_ALREADY_IN_ARENA_TEAM, ERR_ARENA_TEAM_CREATE_S, ERR_ARENA_TEAM_NAME_EXISTS_S, ERR_ARENA_TEAM_NAME_INVALID, ERR_ARENA_TEAM_TARGET_TOO_LOW_S, ERR_GUILD_NAME_EXISTS_S, ERR_GUILD_NAME_INVALID, Player::GetArenaTeamId(), ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetGuildId(), Unit::GetLevel(), WorldObject::GetName(), Player::GetNPCIfCanInteractWith(), GetPlayer(), GUILD_CHARTER, GUILD_CHARTER_TYPE, GUILD_COMMAND_CREATE, Player::HasEnoughMoney(), Unit::IsTabardDesigner(), ObjectMgr::IsValidCharterName(), ITEM_CHANGED, ITEM_FIELD_ENCHANTMENT_1_1, LOG_DEBUG, Player::ModifyMoney(), NULL_BAG, NULL_SLOT, Petition::petitionGuid, ByteBuffer::read_skip(), Unit::RemoveAurasByType(), sArenaTeamMgr, SendArenaTeamCommandResult(), Player::SendBuyError(), Guild::SendCommandResult(), Player::SendEquipError(), Player::SendNewItem(), PreparedStatementBase::SetData(), Item::SetState(), Object::SetUInt32Value(), sGuildMgr, sObjectMgr, SPELL_AURA_FEIGN_DEATH, sPetitionMgr, sScriptMgr, Player::StoreNewItem(), sWorld, ObjectGuid::ToString(), UNIT_NPC_FLAG_PETITIONER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandlePetitionDeclineOpcode()

void WorldSession::HandlePetitionDeclineOpcode ( WorldPacket recvData)
534{
535 LOG_DEBUG("network", "Received opcode MSG_PETITION_DECLINE"); // ok
536
537 ObjectGuid petitionguid;
538 ObjectGuid ownerguid;
539 recvData >> petitionguid; // petition guid
540 LOG_DEBUG("network", "Petition {} declined by {}", petitionguid.ToString(), _player->GetGUID().ToString());
541
542 Petition const* petition = sPetitionMgr->GetPetition(petitionguid);
543 if (!petition)
544 return;
545
546 if (Player* owner = ObjectAccessor::FindConnectedPlayer(ownerguid)) // petition owner online
547 {
549 data << _player->GetGUID();
550 owner->SendDirectMessage(&data);
551 }
552}
@ MSG_PETITION_DECLINE
Definition Opcodes.h:480

References _player, ObjectAccessor::FindConnectedPlayer(), Object::GetGUID(), LOG_DEBUG, MSG_PETITION_DECLINE, sPetitionMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandlePetitionQueryOpcode()

void WorldSession::HandlePetitionQueryOpcode ( WorldPacket recvData)
270{
271 LOG_DEBUG("network", "Received opcode CMSG_PETITION_QUERY"); // ok
272
273 ObjectGuid::LowType guildguid;
274 ObjectGuid petitionguid;
275 recvData >> guildguid; // in Trinity always same as petition low guid
276 recvData >> petitionguid; // petition guid
277 LOG_DEBUG("network", "CMSG_PETITION_QUERY Petition ({}) Guild GUID {}", petitionguid.ToString(), guildguid);
278
279 SendPetitionQueryOpcode(petitionguid);
280}
void SendPetitionQueryOpcode(ObjectGuid petitionguid)
Definition PetitionsHandler.cpp:282

References LOG_DEBUG, SendPetitionQueryOpcode(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandlePetitionRenameOpcode()

void WorldSession::HandlePetitionRenameOpcode ( WorldPacket recvData)
330{
331 LOG_DEBUG("network", "Received opcode MSG_PETITION_RENAME"); // ok
332
333 ObjectGuid petitionGuid;
334 std::string newName;
335
336 recvData >> petitionGuid; // guid
337 recvData >> newName; // new name
338
339 Item* item = _player->GetItemByGuid(petitionGuid);
340 if (!item)
341 return;
342
343 Petition const* petition = sPetitionMgr->GetPetition(petitionGuid);
344 if (!petition)
345 {
346 LOG_DEBUG("network", "CMSG_PETITION_QUERY failed for petition ({})", petitionGuid.ToString());
347 return;
348 }
349
350 if (petition->petitionType == GUILD_CHARTER_TYPE)
351 {
352 if (sGuildMgr->GetGuildByName(newName))
353 {
355 return;
356 }
357 if (!ObjectMgr::IsValidCharterName(newName))
358 {
360 return;
361 }
362 }
363 else
364 {
365 if (sArenaTeamMgr->GetArenaTeamByName(newName))
366 {
368 return;
369 }
370 if (!ObjectMgr::IsValidCharterName(newName))
371 {
373 return;
374 }
375 }
376
378
379 stmt->SetData(0, newName);
380 stmt->SetData(1, petition->petitionId);
381
382 CharacterDatabase.Execute(stmt);
383
384 // xinef: update petition container
385 const_cast<Petition*>(petition)->petitionName = newName;
386
387 LOG_DEBUG("network", "Petition ({}) renamed to {}", petitionGuid.ToString(), newName);
388 WorldPacket data(MSG_PETITION_RENAME, (8 + newName.size() + 1));
389 data << petitionGuid;
390 data << newName;
391 SendPacket(&data);
392}
@ CHAR_UPD_PETITION_NAME
Definition CharacterDatabase.h:280
@ MSG_PETITION_RENAME
Definition Opcodes.h:735

References _player, CHAR_UPD_PETITION_NAME, CharacterDatabase, ERR_ARENA_TEAM_CREATE_S, ERR_ARENA_TEAM_NAME_EXISTS_S, ERR_ARENA_TEAM_NAME_INVALID, ERR_GUILD_NAME_EXISTS_S, ERR_GUILD_NAME_INVALID, Player::GetItemByGuid(), GUILD_CHARTER_TYPE, GUILD_COMMAND_CREATE, ObjectMgr::IsValidCharterName(), LOG_DEBUG, MSG_PETITION_RENAME, Petition::petitionId, Petition::petitionType, sArenaTeamMgr, SendArenaTeamCommandResult(), Guild::SendCommandResult(), SendPacket(), PreparedStatementBase::SetData(), sGuildMgr, sPetitionMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandlePetitionShowListOpcode()

void WorldSession::HandlePetitionShowListOpcode ( WorldPacket recvPacket)
819{
820 LOG_DEBUG("network", "Received CMSG_PETITION_SHOWLIST");
821
822 ObjectGuid guid;
823 recvData >> guid;
824
826}
void SendPetitionShowList(ObjectGuid guid)
Definition PetitionsHandler.cpp:828

References LOG_DEBUG, and SendPetitionShowList().

Referenced by OpcodeTable::Initialize().

◆ HandlePetitionShowSignOpcode()

void WorldSession::HandlePetitionShowSignOpcode ( WorldPacket recvData)
231{
232 LOG_DEBUG("network", "Received opcode CMSG_PETITION_SHOW_SIGNATURES");
233
234 ObjectGuid petitionguid;
235 recvData >> petitionguid; // petition guid
236
237 // solve (possible) some strange compile problems with explicit use petition low guid at some GCC versions (wrong code optimization in compiler?)
238 Petition const* petition = sPetitionMgr->GetPetition(petitionguid);
239 if (!petition)
240 return;
241
242 uint32 type = petition->petitionType;
243
244 // if guild petition and has guild => error, return;
245 if (type == GUILD_CHARTER_TYPE && _player->GetGuildId())
246 return;
247
248 Signatures const* signatures = sPetitionMgr->GetSignature(petitionguid);
249 uint8 signs = signatures ? signatures->signatureMap.size() : 0;
250
251 LOG_DEBUG("network", "CMSG_PETITION_SHOW_SIGNATURES petition {}", petitionguid.ToString());
252
253 WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8 + 8 + 4 + 1 + signs * 12));
254 data << petitionguid; // petition guid
255 data << _player->GetGUID(); // owner guid
256 data << uint32(petition->petitionId); // guild/team id (31-bit safe)
257 data << uint8(signs); // sign's count
258
259 if (signs)
260 for (SignatureMap::const_iterator itr = signatures->signatureMap.begin(); itr != signatures->signatureMap.end(); ++itr)
261 {
262 data << itr->first; // Player GUID
263 data << uint32(0); // there 0 ...
264 }
265
266 SendPacket(&data);
267}

References _player, Object::GetGUID(), Player::GetGuildId(), GUILD_CHARTER_TYPE, LOG_DEBUG, Petition::petitionId, Petition::petitionType, SendPacket(), Signatures::signatureMap, SMSG_PETITION_SHOW_SIGNATURES, sPetitionMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandlePetitionSignOpcode()

void WorldSession::HandlePetitionSignOpcode ( WorldPacket recvData)
395{
396 LOG_DEBUG("network", "Received opcode CMSG_PETITION_SIGN"); // ok
397
398 ObjectGuid petitionGuid;
399 uint8 unk;
400 recvData >> petitionGuid; // petition guid
401 recvData >> unk;
402
403 Petition const* petition = sPetitionMgr->GetPetition(petitionGuid);
404 if (!petition)
405 {
406 LOG_ERROR("network.opcode", "Petition {} is not found for player {} (Name: {})", petitionGuid.ToString(), GetPlayer()->GetGUID().ToString(), GetPlayer()->GetName());
407 return;
408 }
409
410 uint8 type = petition->petitionType;
411
412 ObjectGuid playerGuid = _player->GetGUID();
413 if (petition->ownerGuid == playerGuid)
414 return;
415
416 Signatures const* signatures = sPetitionMgr->GetSignature(petitionGuid);
417 if (!signatures)
418 return;
419
420 if (type != GUILD_CHARTER_TYPE)
421 {
422 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA) && GetPlayer()->GetTeamId() != sCharacterCache->GetCharacterTeamByGuid(petition->ownerGuid))
423 {
425 return;
426 }
427
428 if (_player->GetLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
429 {
431 return;
432 }
433
434 uint8 slot = ArenaTeam::GetSlotByType(type);
435 if (slot >= MAX_ARENA_SLOT)
436 return;
437
438 if (_player->GetArenaTeamId(slot))
439 {
441 return;
442 }
443
445 {
447 return;
448 }
449 }
450 else
451 {
452 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeamId() != sCharacterCache->GetCharacterTeamByGuid(petition->ownerGuid))
453 {
455 return;
456 }
457
458 if (_player->GetGuildId())
459 {
461 return;
462 }
464 {
466 return;
467 }
468 }
469
470 uint32 signs = signatures->signatureMap.size();
471 if (++signs > type) // client signs maximum
472 return;
473
474 // Client doesn't allow to sign petition two times by one character, but not check sign by another character from same account
475 // not allow sign another player from already sign player account
476
477 bool found = false;
478 for (SignatureMap::const_iterator itr = signatures->signatureMap.begin(); itr != signatures->signatureMap.end(); ++itr)
479 if (itr->second == GetAccountId())
480 {
481 found = true;
482 break;
483 }
484
485 if (found)
486 {
487 WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8 + 8 + 4));
488 data << petitionGuid;
489 data << playerGuid;
491
492 // close at signer side
493 SendPacket(&data);
494
495 // update for owner if online
497 owner->SendDirectMessage(&data);
498 return;
499 }
500
502
503 stmt->SetData(0, petition->ownerGuid.GetCounter());
504 stmt->SetData(1, petition->petitionId);
505 stmt->SetData(2, playerGuid.GetCounter());
506 stmt->SetData(3, GetAccountId());
507
508 CharacterDatabase.Execute(stmt);
509
510 // xinef: fill petition store
511 sPetitionMgr->AddSignature(petitionGuid, GetAccountId(), playerGuid);
512
513 LOG_DEBUG("network", "PETITION SIGN: {} by player: {} ({}, Account: {})", petitionGuid.ToString(), _player->GetName(), playerGuid.ToString(), GetAccountId());
514
515 WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8 + 8 + 4));
516 data << petitionGuid;
517 data << playerGuid;
518 data << uint32(PETITION_SIGN_OK);
519
520 // close at signer side
521 SendPacket(&data);
522
523 // update signs count on charter, required testing...
524 //Item* item = _player->GetItemByGuid(petitionguid));
525 //if (item)
526 // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1+1, signs);
527
528 // update for owner if online
530 owner->SendDirectMessage(&data);
531}
@ CHAR_INS_PETITION_SIGNATURE
Definition CharacterDatabase.h:281
@ PETITION_SIGN_ALREADY_SIGNED
Definition Guild.h:179
@ PETITION_SIGN_OK
Definition Guild.h:178
@ SMSG_PETITION_SIGN_RESULTS
Definition Opcodes.h:479
ObjectGuid ownerGuid
Definition PetitionMgr.h:46

References _player, CHAR_INS_PETITION_SIGNATURE, CharacterDatabase, CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA, CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD, CONFIG_MAX_PLAYER_LEVEL, ERR_ALREADY_IN_ARENA_TEAM_S, ERR_ALREADY_IN_GUILD_S, ERR_ALREADY_INVITED_TO_ARENA_TEAM_S, ERR_ALREADY_INVITED_TO_GUILD_S, ERR_ARENA_TEAM_CREATE_S, ERR_ARENA_TEAM_INVITE_SS, ERR_ARENA_TEAM_NOT_ALLIED, ERR_ARENA_TEAM_TARGET_TOO_LOW_S, ERR_GUILD_NOT_ALLIED, ObjectAccessor::FindConnectedPlayer(), GetAccountId(), Player::GetArenaTeamId(), Player::GetArenaTeamIdInvited(), ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetGuildId(), Player::GetGuildIdInvited(), Unit::GetLevel(), WorldObject::GetName(), GetPlayer(), ArenaTeam::GetSlotByType(), GetTeamId(), GUILD_CHARTER_TYPE, GUILD_COMMAND_CREATE, GUILD_COMMAND_INVITE, LOG_DEBUG, LOG_ERROR, MAX_ARENA_SLOT, Petition::ownerGuid, PETITION_SIGN_ALREADY_SIGNED, PETITION_SIGN_OK, Petition::petitionId, Petition::petitionType, sCharacterCache, SendArenaTeamCommandResult(), Guild::SendCommandResult(), SendPacket(), PreparedStatementBase::SetData(), Signatures::signatureMap, SMSG_PETITION_SIGN_RESULTS, sPetitionMgr, sWorld, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandlePetLearnTalent()

void WorldSession::HandlePetLearnTalent ( WorldPacket recvPacket)
1119{
1120 LOG_DEBUG("network", "WORLD: CMSG_PET_LEARN_TALENT");
1121
1122 ObjectGuid guid;
1123 uint32 talent_id, requested_rank;
1124 recvData >> guid >> talent_id >> requested_rank;
1125
1126 _player->LearnPetTalent(guid, talent_id, requested_rank);
1128}

References _player, Player::LearnPetTalent(), LOG_DEBUG, and Player::SendTalentsInfoData().

Referenced by OpcodeTable::Initialize().

◆ HandlePetNameQuery()

void WorldSession::HandlePetNameQuery ( WorldPacket recvData)
607{
608 LOG_DEBUG("network.opcode", "HandlePetNameQuery. CMSG_PET_NAME_QUERY");
609
610 uint32 petnumber;
611 ObjectGuid petguid;
612
613 recvData >> petnumber;
614 recvData >> petguid;
615
616 SendPetNameQuery(petguid, petnumber);
617}
void SendPetNameQuery(ObjectGuid guid, uint32 petnumber)
Definition PetHandler.cpp:619

References LOG_DEBUG, and SendPetNameQuery().

Referenced by OpcodeTable::Initialize().

◆ HandlePetRename()

void WorldSession::HandlePetRename ( WorldPacket recvData)
831{
832 LOG_DEBUG("network.opcode", "HandlePetRename. CMSG_PET_RENAME");
833
834 ObjectGuid petguid;
835 uint8 isdeclined;
836
837 std::string name;
838 DeclinedName declinedname;
839
840 recvData >> petguid;
841 recvData >> name;
842 recvData >> isdeclined;
843
844 PetStable* petStable = _player->GetPetStable();
845
846 Pet* pet = ObjectAccessor::GetPet(*_player, petguid);
847
848 // check it!
849 if (!pet || !pet->IsPet() || ((Pet*)pet)->getPetType() != HUNTER_PET ||
851 pet->GetOwnerGUID() != _player->GetGUID() || !pet->GetCharmInfo() ||
852 !petStable || !petStable->CurrentPet || petStable->CurrentPet->PetNumber != pet->GetCharmInfo()->GetPetNumber())
853 {
854 return;
855 }
856
858 if (res != PET_NAME_SUCCESS)
859 {
860 SendPetNameInvalid(res, name, nullptr);
861 return;
862 }
863
864 pet->SetName(name);
865
866 Unit* owner = pet->GetOwner();
867 if (owner && (owner->IsPlayer()) && owner->ToPlayer()->GetGroup())
869
871
872 petStable->CurrentPet->Name = name;
873 petStable->CurrentPet->WasRenamed = true;
874
875 if (isdeclined)
876 {
877 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
878 {
879 recvData >> declinedname.name[i];
880 }
881
882 std::wstring wname;
883 Utf8toWStr(name, wname);
884 if (!ObjectMgr::CheckDeclinedNames(wname, declinedname))
885 {
887 return;
888 }
889 }
890
891 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
892 if (isdeclined)
893 {
894 if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
895 {
897 stmt->SetData(0, pet->GetCharmInfo()->GetPetNumber());
898 trans->Append(stmt);
899
900 stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_CHAR_PET_DECLINEDNAME);
901 stmt->SetData(0, _player->GetGUID().GetCounter());
902
903 for (uint8 i = 0; i < 5; i++)
904 stmt->SetData(i + 1, declinedname.name[i]);
905
906 trans->Append(stmt);
907 }
908 }
909
911 stmt->SetData(0, name);
912 stmt->SetData(1, _player->GetGUID().GetCounter());
913 stmt->SetData(2, pet->GetCharmInfo()->GetPetNumber());
914 trans->Append(stmt);
915
916 CharacterDatabase.CommitTransaction(trans);
917
918 pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(GameTime::GetGameTime().count())); // cast can't be helped
919}
@ CHAR_ADD_CHAR_PET_DECLINEDNAME
Definition CharacterDatabase.h:482
@ CHAR_UPD_CHAR_PET_NAME
Definition CharacterDatabase.h:484
@ CHAR_DEL_CHAR_PET_DECLINEDNAME
Definition CharacterDatabase.h:481
PetNameInvalidReason
Definition SharedDefines.h:3922
@ PET_NAME_SUCCESS
Definition SharedDefines.h:3924
@ PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME
Definition SharedDefines.h:3938
@ UNIT_CAN_BE_RENAMED
Definition UnitDefines.h:149
#define MAX_DECLINED_NAME_CASES
Definition Unit.h:535
@ UNIT_FIELD_PET_NAME_TIMESTAMP
Definition UpdateFields.h:133
static PetNameInvalidReason CheckPetName(std::string_view name)
Definition ObjectMgr.cpp:8731
static bool CheckDeclinedNames(std::wstring w_ownname, DeclinedName const &names)
Definition ObjectMgr.cpp:9026
Optional< PetInfo > CurrentPet
Definition PetDefines.h:235
Player * GetOwner() const
Definition Pet.cpp:2478
void SetGroupUpdateFlag(uint32 flag)
Definition Player.h:2488
PetStable * GetPetStable()
Definition Player.h:1208
void SetUInt32Value(uint16 index, uint32 value)
Definition Unit.cpp:21414
void SetName(std::string const &newname)
Definition Object.h:525
void SendPetNameInvalid(uint32 error, std::string const &name, DeclinedName *declinedName)
Definition PetHandler.cpp:1102
Pet * GetPet(WorldObject const &, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:215
uint32 GetPetNumber() const
Definition CharmInfo.h:132
Definition Unit.h:538
std::string name[MAX_DECLINED_NAME_CASES]
Definition Unit.h:539

References _player, CHAR_ADD_CHAR_PET_DECLINEDNAME, CHAR_DEL_CHAR_PET_DECLINEDNAME, CHAR_UPD_CHAR_PET_NAME, CharacterDatabase, ObjectMgr::CheckDeclinedNames(), ObjectMgr::CheckPetName(), CONFIG_DECLINED_NAMES_USED, PetStable::CurrentPet, Unit::GetCharmInfo(), ObjectGuid::GetCounter(), GameTime::GetGameTime(), Player::GetGroup(), Object::GetGUID(), Pet::GetOwner(), Unit::GetOwnerGUID(), ObjectAccessor::GetPet(), CharmInfo::GetPetNumber(), Player::GetPetStable(), GROUP_UPDATE_FLAG_PET_NAME, Object::HasByteFlag(), HUNTER_PET, Unit::IsPet(), Object::IsPlayer(), LOG_DEBUG, MAX_DECLINED_NAME_CASES, DeclinedName::name, PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME, PET_NAME_SUCCESS, Object::RemoveByteFlag(), SendPetNameInvalid(), PreparedStatementBase::SetData(), Player::SetGroupUpdateFlag(), WorldObject::SetName(), Unit::SetUInt32Value(), sWorld, Object::ToPlayer(), UNIT_CAN_BE_RENAMED, UNIT_FIELD_BYTES_2, UNIT_FIELD_PET_NAME_TIMESTAMP, and Utf8toWStr().

Referenced by OpcodeTable::Initialize().

◆ HandlePetSetAction()

void WorldSession::HandlePetSetAction ( WorldPacket recvData)
687{
688 LOG_DEBUG("network.opcode", "HandlePetSetAction. CMSG_PET_SET_ACTION");
689
690 ObjectGuid petguid;
691 uint8 count;
692
693 recvData >> petguid;
694
695 Unit* checkPet = ObjectAccessor::GetUnit(*_player, petguid);
696 if (!checkPet || checkPet != _player->GetFirstControlled())
697 {
698 LOG_ERROR("network.opcode", "HandlePetSetAction: Unknown pet ({}) or pet owner ({})", petguid.ToString(), _player->GetGUID().ToString());
699 return;
700 }
701
702 count = (recvData.size() == 24) ? 2 : 1;
703
704 uint32 position[2];
705 uint32 data[2];
706 bool move_command = false;
707
708 for (uint8 i = 0; i < count; ++i)
709 {
710 recvData >> position[i];
711 recvData >> data[i];
712
713 uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data[i]);
714
715 //ignore invalid position
716 if (position[i] >= MAX_UNIT_ACTION_BAR_INDEX)
717 return;
718
719 // in the normal case, command and reaction buttons can only be moved, not removed
720 // at moving count == 2, at removing count == 1
721 // ignore attempt to remove command|reaction buttons (not possible at normal case)
722 if (act_state == ACT_COMMAND || act_state == ACT_REACTION)
723 {
724 if (count == 1)
725 return;
726
727 move_command = true;
728 }
729 }
730
731 Unit::ControlSet petsSet;
732 if (checkPet->GetEntry() != petguid.GetEntry())
733 petsSet.insert(checkPet);
734 else
735 petsSet = _player->m_Controlled;
736
737 // Xinef: loop all pets with same entry (fixes partial state change for feral spirits)
738 for (Unit::ControlSet::const_iterator itr = petsSet.begin(); itr != petsSet.end(); ++itr)
739 {
740 Unit* pet = *itr;
741 if (checkPet->GetEntry() == petguid.GetEntry() && pet->GetEntry() != petguid.GetEntry())
742 continue;
743
744 CharmInfo* charmInfo = pet->GetCharmInfo();
745 if (!charmInfo)
746 {
747 LOG_ERROR("network.opcode", "WorldSession::HandlePetSetAction: object ({} TypeId: {}) is considered pet-like but doesn't have a charminfo!",
748 pet->GetGUID().ToString(), pet->GetTypeId());
749 continue;
750 }
751
752 // check swap (at command->spell swap client remove spell first in another packet, so check only command move correctness)
753 if (move_command)
754 {
755 uint8 act_state_0 = UNIT_ACTION_BUTTON_TYPE(data[0]);
756 if (act_state_0 == ACT_COMMAND || act_state_0 == ACT_REACTION)
757 {
758 uint32 spell_id_0 = UNIT_ACTION_BUTTON_ACTION(data[0]);
759 UnitActionBarEntry const* actionEntry_1 = charmInfo->GetActionBarEntry(position[1]);
760 if (!actionEntry_1 || spell_id_0 != actionEntry_1->GetAction() ||
761 act_state_0 != actionEntry_1->GetType())
762 continue;
763 }
764
765 uint8 act_state_1 = UNIT_ACTION_BUTTON_TYPE(data[1]);
766 if (act_state_1 == ACT_COMMAND || act_state_1 == ACT_REACTION)
767 {
768 uint32 spell_id_1 = UNIT_ACTION_BUTTON_ACTION(data[1]);
769 UnitActionBarEntry const* actionEntry_0 = charmInfo->GetActionBarEntry(position[0]);
770 if (!actionEntry_0 || spell_id_1 != actionEntry_0->GetAction() ||
771 act_state_1 != actionEntry_0->GetType())
772 continue;
773 }
774 }
775
776 for (uint8 i = 0; i < count; ++i)
777 {
778 uint32 spell_id = UNIT_ACTION_BUTTON_ACTION(data[i]);
779 uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data[i]);
780
781 //if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add
782 if (!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && !pet->HasSpell(spell_id)))
783 {
784 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id))
785 {
786 //sign for autocast
787 if (act_state == ACT_ENABLED)
788 {
789 if (pet->IsCreature() && pet->IsPet())
790 {
791 ((Pet*)pet)->ToggleAutocast(spellInfo, true);
792 }
793 else
794 {
795 for (auto iterator = GetPlayer()->m_Controlled.begin(); iterator != GetPlayer()->m_Controlled.end(); ++iterator)
796 {
797 if ((*iterator)->GetEntry() == pet->GetEntry())
798 {
799 (*iterator)->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, true);
800 }
801 }
802 }
803 }
804 //sign for no/turn off autocast
805 else if (act_state == ACT_DISABLED)
806 {
807 if (pet->IsCreature() && pet->IsPet())
808 {
809 ((Pet*)pet)->ToggleAutocast(spellInfo, false);
810 }
811 else
812 {
813 for (auto iterator = GetPlayer()->m_Controlled.begin(); iterator != GetPlayer()->m_Controlled.end(); ++iterator)
814 {
815 if ((*iterator)->GetEntry() == pet->GetEntry())
816 {
817 (*iterator)->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, false);
818 }
819 }
820 }
821 }
822 }
823
824 charmInfo->SetActionBar(position[i], spell_id, ActiveStates(act_state));
825 }
826 }
827 }
828}
#define MAX_UNIT_ACTION_BAR_INDEX
Definition CharmInfo.h:29
ActiveStates
Definition CharmInfo.h:60
uint32 GetEntry() const
Definition ObjectGuid.h:144
TypeID GetTypeId() const
Definition Object.h:128
std::set< Unit * > ControlSet
Definition Unit.h:658
Unit * GetFirstControlled() const
Definition Unit.cpp:11283
void SetActionBar(uint8 index, uint32 spellOrAction, ActiveStates type)
Definition CharmInfo.h:150
UnitActionBarEntry const * GetActionBarEntry(uint8 index) const
Definition CharmInfo.h:154
Definition CharmInfo.h:95
ActiveStates GetType() const
Definition CharmInfo.h:101
uint32 GetAction() const
Definition CharmInfo.h:102

References _player, ACT_COMMAND, ACT_DISABLED, ACT_ENABLED, ACT_PASSIVE, ACT_REACTION, UnitActionBarEntry::GetAction(), CharmInfo::GetActionBarEntry(), Unit::GetCharmInfo(), Object::GetEntry(), ObjectGuid::GetEntry(), Unit::GetFirstControlled(), Object::GetGUID(), GetPlayer(), UnitActionBarEntry::GetType(), Object::GetTypeId(), ObjectAccessor::GetUnit(), Unit::HasSpell(), Object::IsCreature(), Unit::IsPet(), LOG_DEBUG, LOG_ERROR, Unit::m_Controlled, MAX_UNIT_ACTION_BAR_INDEX, CharmInfo::SetActionBar(), ByteBuffer::size(), sSpellMgr, ObjectGuid::ToString(), UNIT_ACTION_BUTTON_ACTION, and UNIT_ACTION_BUTTON_TYPE.

Referenced by OpcodeTable::Initialize().

◆ HandlePetSpellAutocastOpcode()

void WorldSession::HandlePetSpellAutocastOpcode ( WorldPackets::Pet::PetSpellAutocast packet)
946{
948 if (!checkPet)
949 {
950 LOG_ERROR("entities.pet", "WorldSession::HandlePetSpellAutocastOpcode: Pet {} not found.", packet.PetGUID.ToString());
951 return;
952 }
953
954 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(packet.SpellID);
955 if (!spellInfo)
956 {
957 LOG_ERROR("spells.pet", "WorldSession::HandlePetSpellAutocastOpcode: Unknown spell id {} used by {}.", packet.SpellID, packet.PetGUID.ToString());
958 return;
959 }
960
961 if (checkPet != _player->GetGuardianPet() && checkPet != _player->GetCharm())
962 {
963 LOG_ERROR("entities.pet", "WorldSession::HandlePetSpellAutocastOpcode: {} isn't pet of player {} ({}).",
964 packet.PetGUID.ToString(), GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
965 return;
966 }
967
968 Unit::ControlSet petsSet;
969 if (checkPet->GetEntry() != packet.PetGUID.GetEntry())
970 petsSet.insert(checkPet);
971 else
972 petsSet = _player->m_Controlled;
973
974 // Xinef: loop all pets with same entry (fixes partial state change for feral spirits)
975 for (Unit* pet : petsSet)
976 {
977 if (checkPet->GetEntry() == packet.PetGUID.GetEntry() && pet->GetEntry() != packet.PetGUID.GetEntry())
978 continue;
979
980 // do not add not learned spells/ passive spells
981 if (!pet->HasSpell(packet.SpellID) || !spellInfo->IsAutocastable())
982 continue;
983
984 CharmInfo* charmInfo = pet->GetCharmInfo();
985 if (!charmInfo)
986 {
987 LOG_ERROR("network.opcode", "WorldSession::HandlePetSpellAutocastOpcode: object ({} TypeId: {}) is considered pet-like but doesn't have a charminfo!",
988 pet->GetGUID().ToString(), pet->GetTypeId());
989 continue;
990 }
991
992 if (Pet* summon = pet->ToPet())
993 summon->ToggleAutocast(spellInfo, packet.AutocastEnabled);
994 else
995 charmInfo->ToggleCreatureAutocast(spellInfo, packet.AutocastEnabled);
996
997 charmInfo->SetSpellAutocast(spellInfo, packet.AutocastEnabled);
998 }
999}
bool IsAutocastable() const
Definition SpellInfo.cpp:1103
bool AutocastEnabled
Definition PetPackets.h:68
uint32 SpellID
Definition PetPackets.h:67
ObjectGuid PetGUID
Definition PetPackets.h:66
void SetSpellAutocast(SpellInfo const *spellInfo, bool state)
Definition CharmInfo.cpp:291
void ToggleCreatureAutocast(SpellInfo const *spellInfo, bool apply)
Definition CharmInfo.cpp:230

References _player, WorldPackets::Pet::PetSpellAutocast::AutocastEnabled, Unit::GetCharm(), ObjectAccessor::GetCreatureOrPetOrVehicle(), Object::GetEntry(), ObjectGuid::GetEntry(), Unit::GetGuardianPet(), GetPlayer(), SpellInfo::IsAutocastable(), LOG_ERROR, Unit::m_Controlled, WorldPackets::Pet::PetSpellAutocast::PetGUID, CharmInfo::SetSpellAutocast(), WorldPackets::Pet::PetSpellAutocast::SpellID, sSpellMgr, CharmInfo::ToggleCreatureAutocast(), Unit::ToPet(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandlePetStopAttack()

void WorldSession::HandlePetStopAttack ( WorldPackets::Pet::PetStopAttack packet)
128{
130
131 if (!pet)
132 {
133 LOG_ERROR("network.opcode", "HandlePetStopAttack: Pet {} does not exist", packet.PetGUID.ToString());
134 return;
135 }
136
137 if (pet != GetPlayer()->GetPet() && pet != GetPlayer()->GetCharm())
138 {
139 LOG_ERROR("network.opcode", "HandlePetStopAttack: Pet {} isn't a pet or charmed creature of player {}", packet.PetGUID.ToString(), GetPlayer()->GetName());
140 return;
141 }
142
143 if (!pet->IsAlive())
144 return;
145
146 pet->AttackStop();
147 pet->ClearInPetCombat();
148}
ObjectGuid PetGUID
Definition PetPackets.h:56

References _player, Unit::AttackStop(), Unit::ClearInPetCombat(), ObjectAccessor::GetCreatureOrPetOrVehicle(), GetPlayer(), Unit::IsAlive(), LOG_ERROR, WorldPackets::Pet::PetStopAttack::PetGUID, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandlePlayedTime()

void WorldSession::HandlePlayedTime ( WorldPackets::Character::PlayedTimeClient packet)
970{
972 playedTime.TotalTime = _player->GetTotalPlayedTime();
973 playedTime.LevelTime = _player->GetLevelPlayedTime();
974 playedTime.TriggerScriptEvent = packet.TriggerScriptEvent; // 0-1 - will not show in chat frame
975 SendPacket(playedTime.Write());
976}
uint32 GetLevelPlayedTime()
Definition Player.h:1193
bool TriggerScriptEvent
Definition CharacterPackets.h:105
Definition CharacterPackets.h:109
WorldPacket const * Write() override
Definition CharacterPackets.cpp:42
uint32 LevelTime
Definition CharacterPackets.h:116
bool TriggerScriptEvent
Definition CharacterPackets.h:117
uint32 TotalTime
Definition CharacterPackets.h:115

References _player, Player::GetLevelPlayedTime(), Player::GetTotalPlayedTime(), WorldPackets::Character::PlayedTime::LevelTime, SendPacket(), WorldPackets::Character::PlayedTime::TotalTime, WorldPackets::Character::PlayedTimeClient::TriggerScriptEvent, WorldPackets::Character::PlayedTime::TriggerScriptEvent, and WorldPackets::Character::PlayedTime::Write().

Referenced by OpcodeTable::Initialize().

◆ HandlePlayerLoginFromDB()

void WorldSession::HandlePlayerLoginFromDB ( LoginQueryHolder const &  holder)
789{
790 ObjectGuid playerGuid = holder.GetGuid();
791
792 Player* pCurrChar = new Player(this);
793 // for send server info and strings (config)
794 ChatHandler chH = ChatHandler(pCurrChar->GetSession());
795
796 // "GetAccountId() == db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools)
797 if (!pCurrChar->LoadFromDB(playerGuid, holder))
798 {
799 SetPlayer(nullptr);
800 KickPlayer("WorldSession::HandlePlayerLogin Player::LoadFromDB failed"); // disconnect client, player no set to session and it will not deleted or saved at kick
801 delete pCurrChar; // delete it manually
802 m_playerLoading = false;
803 return;
804 }
805
806 pCurrChar->GetMotionMaster()->Initialize();
807 pCurrChar->SendDungeonDifficulty(false);
808
810 data << pCurrChar->GetMapId();
811 data << pCurrChar->GetPositionX();
812 data << pCurrChar->GetPositionY();
813 data << pCurrChar->GetPositionZ();
814 data << pCurrChar->GetOrientation();
815 SendPacket(&data);
816
817 // load player specific part before send times
820
821 data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0
822 data << uint8(2); // 2 - COMPLAINT_ENABLED_WITH_AUTO_IGNORE
823 data << uint8(0); // enable(1)/disable(0) voice chat interface in client
824 SendPacket(&data);
825
826 // Send MOTD
827 {
828 SendPacket(sMotdMgr->GetMotdPacket(pCurrChar->GetSession()->GetSessionDbLocaleIndex()));
829
830 // send server info
831 if (sWorld->getIntConfig(CONFIG_ENABLE_SINFO_LOGIN) == 1)
833 }
834
835 if (uint32 guildId = sCharacterCache->GetCharacterGuildIdByGuid(pCurrChar->GetGUID()))
836 {
837 Guild* guild = sGuildMgr->GetGuildById(guildId);
838 Guild::Member const* member = guild ? guild->GetMember(pCurrChar->GetGUID()) : nullptr;
839 if (member)
840 {
841 pCurrChar->SetInGuild(guildId);
842 pCurrChar->SetRank(member->GetRankId());
843 guild->SendLoginInfo(this);
844 }
845 else
846 {
847 LOG_ERROR("network.opcode", "Player {} ({}) marked as member of not existing guild (id: {}), removing guild membership for player.",
848 pCurrChar->GetName(), pCurrChar->GetGUID().ToString(), guildId);
849 pCurrChar->SetInGuild(0);
850 pCurrChar->SetRank(0);
851 }
852 }
853 else
854 {
855 pCurrChar->SetInGuild(0);
856 pCurrChar->SetRank(0);
857 }
858
859 data.Initialize(SMSG_LEARNED_DANCE_MOVES, 4 + 4);
860 data << uint32(0);
861 data << uint32(0);
862 SendPacket(&data);
863
865
866 //Show cinematic at the first time that player login
867 if (!pCurrChar->getCinematic())
868 {
869 pCurrChar->setCinematic(1);
870
871 if (ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(pCurrChar->getClass()))
872 {
873 if (cEntry->CinematicSequence)
874 pCurrChar->SendCinematicStart(cEntry->CinematicSequence);
875 else if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace()))
876 pCurrChar->SendCinematicStart(rEntry->CinematicSequence);
877
878 // send new char string if not empty
879 std::string_view newCharString = sWorld->getStringConfig(CONFIG_NEW_CHAR_STRING);
880 if (!newCharString.empty())
881 chH.PSendSysMessage("{}", newCharString);
882 }
883 }
884
885 // Xinef: moved this from below
886 ObjectAccessor::AddObject(pCurrChar);
887
888 if (!pCurrChar->GetMap()->AddPlayerToMap(pCurrChar) || !pCurrChar->CheckInstanceLoginValid())
889 {
890 AreaTriggerTeleport const* at = sObjectMgr->GetGoBackTrigger(pCurrChar->GetMapId());
891 if (at)
892 pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation());
893 else
894 pCurrChar->TeleportTo(pCurrChar->m_homebindMapId, pCurrChar->m_homebindX, pCurrChar->m_homebindY, pCurrChar->m_homebindZ, pCurrChar->GetOrientation());
895
896 // Probably a hackfix, but currently the best workaround to prevent character names showing as Unknown after teleport out from instances at login.
897 pCurrChar->GetSession()->SendNameQueryOpcode(pCurrChar->GetGUID());
898 }
899
901
903 stmt->SetData(0, pCurrChar->GetGUID().GetCounter());
904 CharacterDatabase.Execute(stmt);
905
907 loginStmt->SetData(0, realm.Id.Realm);
908 loginStmt->SetData(1, GetAccountId());
909 LoginDatabase.Execute(loginStmt);
910
911 pCurrChar->SetInGameTime(GameTime::GetGameTimeMS().count());
912
913 // announce group about member online (must be after add to player list to receive announce to self)
914 if (Group* group = pCurrChar->GetGroup())
915 {
916 group->SendUpdate();
917 group->ResetMaxEnchantingLevel();
918 }
919
920 // pussywizard: send instance welcome message as when entering the instance through a portal
921 if (MapDifficulty const* mapDiff = GetMapDifficultyData(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty()))
922 if (mapDiff->resetTime)
923 if (time_t timeReset = sInstanceSaveMgr->GetResetTimeFor(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty()))
924 {
925 uint32 timeleft = uint32(timeReset - GameTime::GetGameTime().count());
926 pCurrChar->SendInstanceResetWarning(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty(), timeleft, true);
927 }
928
929 // pussywizard: ensure that we end up on map with our loaded transport:
930 if (Transport* t = pCurrChar->GetTransport())
931 if (!t->IsInMap(pCurrChar))
932 {
933 t->RemovePassenger(pCurrChar);
934 pCurrChar->m_transport = nullptr;
935 pCurrChar->m_movementInfo.transport.Reset();
937 }
938
939 // friend status
940 sSocialMgr->SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUID(), true);
941
942 // Place character in world (and load zone) before some object loading
943 pCurrChar->LoadCorpse(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION));
944
945 // setting Ghost+speed if dead
946 if (pCurrChar->m_deathState != DeathState::Alive)
947 {
948 // not blizz like, we must correctly save and load player instead...
949 if (pCurrChar->getRace() == RACE_NIGHTELF)
950 pCurrChar->CastSpell(pCurrChar, 20584, true, 0); // auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form)
951
952 pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
953 }
954
955 // Set FFA PvP for non GM in non-rest mode
956 if (sWorld->IsFFAPvPRealm() && !pCurrChar->IsGameMaster() && !pCurrChar->HasPlayerFlag(PLAYER_FLAGS_RESTING))
958 {
959 sScriptMgr->OnPlayerFfaPvpStateUpdate(pCurrChar,true);
961 }
962
964 {
965 pCurrChar->SetContestedPvP(nullptr, false);
966 }
967
968 // Apply at_login requests
970 {
971 pCurrChar->resetSpells();
973 }
974
976 {
977 pCurrChar->resetTalents(true);
978 pCurrChar->SendTalentsInfoData(false); // original talents send already in to SendInitialPacketsBeforeAddToMap, resend reset state
980 }
981
983 {
984 // If we process the check while players are loading they won't be notified of the changes.
985 pCurrChar->m_Events.AddEventAtOffset([pCurrChar]
986 {
988 pCurrChar->CheckAllAchievementCriteria();
989 }, 1s);
990 }
991
992 bool firstLogin = pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST);
993 if (firstLogin)
994 {
995 PlayerInfo const* info = sObjectMgr->GetPlayerInfo(pCurrChar->getRace(), pCurrChar->getClass());
996 for (uint32 spellId : info->castSpells)
997 {
998 pCurrChar->CastSpell(pCurrChar, spellId, true);
999 }
1000
1001 // start with every map explored
1002 if (sWorld->getBoolConfig(CONFIG_START_ALL_EXPLORED))
1003 {
1004 for (uint8 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; i++)
1005 {
1006 pCurrChar->SetFlag(PLAYER_EXPLORED_ZONES_1 + i, 0xFFFFFFFF);
1007 }
1008 }
1009
1010 // Reputations if "StartAllReputation" is enabled, -- TODO: Fix this in a better way
1011 if (sWorld->getBoolConfig(CONFIG_START_ALL_REP))
1012 {
1013 ReputationMgr& repMgr = pCurrChar->GetReputationMgr();
1014
1015 auto SendFullReputation = [&repMgr](std::initializer_list<uint32> factionsList)
1016 {
1017 for (auto const& itr : factionsList)
1018 {
1019 repMgr.SetOneFactionReputation(sFactionStore.LookupEntry(itr), 42999.f, false);
1020 }
1021 };
1022
1023 SendFullReputation({ 942, 935, 936, 1011, 970, 967, 989, 932, 934, 1038, 1077, 1106, 1104, 1090, 1098, 1156, 1073, 1105, 1119, 1091 });
1024
1025 switch (pCurrChar->GetFaction())
1026 {
1027 case ALLIANCE:
1028 SendFullReputation({ 72, 47, 69, 930, 730, 978, 54, 946, 1037, 1068, 1126, 1094, 1050 });
1029 break;
1030 case HORDE:
1031 SendFullReputation({ 76, 68, 81, 911, 729, 941, 530, 947, 1052, 1067, 1124, 1064, 1085 });
1032 break;
1033 default:
1034 break;
1035 }
1036
1037 repMgr.SendStates();
1038 }
1039 }
1040
1041 // show time before shutdown if shutdown planned.
1042 if (sWorld->IsShuttingDown())
1043 sWorld->ShutdownMsg(true, pCurrChar);
1044
1045 if (sWorld->getBoolConfig(CONFIG_ALL_TAXI_PATHS))
1046 pCurrChar->SetTaxiCheater(true);
1047
1048 if (pCurrChar->IsGameMaster())
1050
1051 std::string IP_str = GetRemoteAddress();
1052 LOG_INFO("entities.player", "Account: {} (IP: {}) Login Character:[{}] ({}) Level: {}",
1053 GetAccountId(), IP_str, pCurrChar->GetName(), pCurrChar->GetGUID().ToString(), pCurrChar->GetLevel());
1054
1055 if (!pCurrChar->IsStandState() && !pCurrChar->HasUnitState(UNIT_STATE_STUNNED))
1057
1058 m_playerLoading = false;
1059
1060 // Handle Login-Achievements (should be handled after loading)
1062
1063 // Xinef: fix vendors falling of player vehicle, due to isBeingLoaded checks
1064 if (pCurrChar->IsInWorld())
1065 {
1066 if (pCurrChar->GetMountBlockId() && !pCurrChar->HasMountedAura())
1067 {
1068 pCurrChar->CastSpell(pCurrChar, pCurrChar->GetMountBlockId(), true);
1069 pCurrChar->SetMountBlockId(0);
1070
1071 // Xinef: refresh this in case mount aura changes anything (eg no fly zone)
1072 pCurrChar->UpdateAreaDependentAuras(pCurrChar->GetAreaId());
1073 pCurrChar->UpdateZoneDependentAuras(pCurrChar->GetZoneId());
1074 }
1075 }
1076
1077 // pussywizard: pvp mode
1079 if (pCurrChar->HasPlayerFlag(PLAYER_FLAGS_IN_PVP))
1080 pCurrChar->UpdatePvP(true, true);
1081
1082 // pussywizard: on login it's not possible to go back to arena as a spectator, HandleMoveWorldportAckOpcode is not sent, so call it here
1083 pCurrChar->SetIsSpectator(false);
1084
1085 // xinef: do this after everything is loaded
1086 pCurrChar->ContinueTaxiFlight();
1087
1088 // reset for all pets before pet loading
1091
1092 // Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned)
1093 pCurrChar->LoadPet();
1094
1095 if (pCurrChar->GetSession()->GetRecruiterId() != 0 || pCurrChar->GetSession()->IsARecruiter())
1096 {
1097 bool isReferrer = pCurrChar->GetSession()->IsARecruiter();
1098
1099 for (auto const& [accID, session] : sWorldSessionMgr->GetAllSessions())
1100 {
1101 if (!session->GetRecruiterId() && !session->IsARecruiter())
1102 continue;
1103
1104 if ((isReferrer && pCurrChar->GetSession()->GetAccountId() == session->GetRecruiterId()) || (!isReferrer && pCurrChar->GetSession()->GetRecruiterId() == session->GetAccountId()))
1105 {
1106 Player* rf = session->GetPlayer();
1107 if (rf)
1108 {
1109 pCurrChar->SendUpdateToPlayer(rf);
1110 rf->SendUpdateToPlayer(pCurrChar);
1111 }
1112 }
1113 }
1114 }
1115
1116 sScriptMgr->OnPlayerLogin(pCurrChar);
1117
1118 if (pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST))
1119 {
1121 sScriptMgr->OnPlayerFirstLogin(pCurrChar);
1122 }
1123
1124 METRIC_EVENT("player_events", "Login", pCurrChar->GetName());
1125}
@ CHAR_UPD_CHAR_ONLINE
Definition CharacterDatabase.h:304
@ ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN
Definition DBCEnums.h:184
@ LANG_RESET_SPELLS
Definition Language.h:259
@ LANG_RESET_TALENTS
Definition Language.h:260
@ LANG_GM_ON
Definition Language.h:379
@ LOGIN_UPD_ACCOUNT_ONLINE
Definition LoginDatabase.h:76
#define METRIC_EVENT(category, title, description)
Definition Metric.h:189
#define sMotdMgr
Definition MotdMgr.h:52
@ PLAYER_FLAGS_CONTESTED_PVP
Definition Player.h:476
@ PLAYER_FLAGS_PVP_TIMER
Definition Player.h:486
@ AT_LOGIN_RESET_TALENTS
Definition Player.h:597
@ AT_LOGIN_RESET_SPELLS
Definition Player.h:596
@ AT_LOGIN_RESET_PET_TALENTS
Definition Player.h:599
#define PLAYER_EXPLORED_ZONES_SIZE
Definition Player.h:73
@ PLAYER_LOGIN_QUERY_LOAD_ACCOUNT_DATA
Definition Player.h:879
@ PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION
Definition Player.h:889
@ ALLIANCE
Definition SharedDefines.h:779
@ HORDE
Definition SharedDefines.h:778
@ FRIEND_ONLINE
Definition SocialMgr.h:68
@ PLAYER_EXPLORED_ZONES_1
Definition UpdateFields.h:357
@ CONFIG_ALL_TAXI_PATHS
Definition WorldConfig.h:42
@ CONFIG_ENABLE_SINFO_LOGIN
Definition WorldConfig.h:298
@ CONFIG_START_ALL_REP
Definition WorldConfig.h:86
@ CONFIG_START_ALL_EXPLORED
Definition WorldConfig.h:85
@ CONFIG_NEW_CHAR_STRING
Definition WorldConfig.h:486
void AddEventAtOffset(BasicEvent *event, Milliseconds offset, uint8 eventGroup=0)
Definition EventProcessor.h:108
Definition Guild.h:296
uint8 GetRankId() const
Definition Guild.h:330
void SendLoginInfo(WorldSession *session)
Definition Guild.cpp:1881
const Member * GetMember(ObjectGuid guid) const
Definition Guild.h:381
virtual bool AddPlayerToMap(Player *)
Definition Map.cpp:256
void Initialize()
Definition MotionMaster.cpp:74
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition Object.cpp:893
static void resetTalentsForAllPetsOf(Player *owner, Pet *online_pet=nullptr)
Definition Pet.cpp:2123
void RemoveAtLoginFlag(AtLoginFlags flags, bool persist=false)
Definition Player.cpp:14747
void RemovePlayerFlag(PlayerFlags flags)
Definition Player.h:1112
uint32 GetMountBlockId()
Definition Player.h:2614
void ContinueTaxiFlight()
Definition Player.cpp:10478
void SendDungeonDifficulty(bool IsInGroup)
Definition PlayerMisc.cpp:167
void UpdateAreaDependentAuras(uint32 area_id)
Definition PlayerUpdates.cpp:1856
void SetMountBlockId(uint32 mount)
Definition Player.h:2615
bool resetTalents(bool noResetCost=false)
Definition Player.cpp:3711
void LoadCorpse(PreparedQueryResult result)
Definition PlayerStorage.cpp:5812
void SendCinematicStart(uint32 CinematicSequenceId) const
Definition Player.cpp:5767
void LoadPet()
Definition PlayerStorage.cpp:6213
uint8 getCinematic() const
Definition Player.h:1826
void SetRank(uint8 rankId)
Definition Player.h:1893
bool LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const &holder)
Definition PlayerStorage.cpp:4915
void UpdateZoneDependentAuras(uint32 zone_id)
Definition PlayerUpdates.cpp:1842
void SetTaxiCheater(bool on)
Definition Player.h:1169
void SetInGameTime(uint32 time)
Definition Player.h:1551
void CheckAllAchievementCriteria()
Definition Player.cpp:13945
void setCinematic(uint8 cine)
Definition Player.h:1830
bool CheckInstanceLoginValid()
Definition PlayerStorage.cpp:6956
void resetSpells()
Definition Player.cpp:11873
Definition ReputationMgr.h:57
bool SetOneFactionReputation(FactionEntry const *factionEntry, float standing, bool incremental, Optional< ReputationRank > repMaxCap={ })
Public for chat command needs.
Definition ReputationMgr.cpp:378
void SendStates()
Definition ReputationMgr.cpp:246
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition Unit.cpp:17492
bool HasMountedAura() const
Definition Unit.h:1779
DeathState m_deathState
Definition Unit.h:2135
bool IsStandState() const
Definition Unit.cpp:16943
EventProcessor m_Events
Definition Object.h:730
void SetPlayer(Player *player)
Definition WorldSession.cpp:1308
void LoadAccountData(PreparedQueryResult result, uint32 mask)
Definition WorldSession.cpp:885
bool IsARecruiter() const
Definition WorldSession.h:589
void SendAccountDataTimes(uint32 mask)
Definition WorldSession.cpp:945
#define PER_CHARACTER_CACHE_MASK
Definition WorldSession.h:218
@ SMSG_LEARNED_DANCE_MOVES
Definition Opcodes.h:1139
@ SMSG_LOGIN_VERIFY_WORLD
Definition Opcodes.h:596
@ SMSG_FEATURE_SYSTEM_STATUS
Definition Opcodes.h:999
AC_COMMON_API char const * GetFullVersion()
Definition GitRevision.cpp:82
void AddObject(T *object)
Definition ObjectAccessor.h:89
Definition Player.h:331

References _player, ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN, EventProcessor::AddEventAtOffset(), ObjectAccessor::AddObject(), Map::AddPlayerToMap(), Alive, ALLIANCE, AT_LOGIN_CHECK_ACHIEVS, AT_LOGIN_FIRST, AT_LOGIN_RESET_PET_TALENTS, AT_LOGIN_RESET_SPELLS, AT_LOGIN_RESET_TALENTS, Unit::CastSpell(), PlayerInfo::castSpells, CHAR_UPD_CHAR_ONLINE, CharacterDatabase, Player::CheckAllAchievementCriteria(), Player::CheckInstanceLoginValid(), CONFIG_ALL_TAXI_PATHS, CONFIG_ENABLE_SINFO_LOGIN, CONFIG_NEW_CHAR_STRING, CONFIG_START_ALL_EXPLORED, CONFIG_START_ALL_REP, Player::ContinueTaxiFlight(), FRIEND_ONLINE, GetAccountId(), WorldObject::GetAreaId(), Player::getCinematic(), Unit::getClass(), ObjectGuid::GetCounter(), Map::GetDifficulty(), Unit::GetFaction(), GitRevision::GetFullVersion(), GameTime::GetGameTime(), GameTime::GetGameTimeMS(), Player::GetGroup(), LoginQueryHolder::GetGuid(), Object::GetGUID(), Map::GetId(), Unit::GetLevel(), WorldObject::GetMap(), GetMapDifficultyData(), WorldLocation::GetMapId(), Guild::GetMember(), Unit::GetMotionMaster(), Player::GetMountBlockId(), WorldObject::GetName(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SQLQueryHolderBase::GetPreparedResult(), Unit::getRace(), Guild::Member::GetRankId(), GetRecruiterId(), GetRemoteAddress(), Player::GetReputationMgr(), Player::GetSession(), GetSessionDbLocaleIndex(), WorldObject::GetTransport(), WorldObject::GetZoneId(), Player::HasAtLoginFlag(), Object::HasByteFlag(), Unit::HasMountedAura(), Player::HasPlayerFlag(), Unit::HasUnitState(), HORDE, Realm::Id, MotionMaster::Initialize(), WorldPacket::Initialize(), IsARecruiter(), Player::IsGameMaster(), Object::IsInWorld(), Unit::IsStandState(), KickPlayer(), LANG_GM_ON, LANG_RESET_SPELLS, LANG_RESET_TALENTS, LoadAccountData(), Player::LoadCorpse(), Player::LoadFromDB(), Player::LoadPet(), LOG_ERROR, LOG_INFO, LOGIN_UPD_ACCOUNT_ONLINE, LoginDatabase, Unit::m_deathState, WorldObject::m_Events, Player::m_homebindMapId, Player::m_homebindX, Player::m_homebindY, Player::m_homebindZ, WorldObject::m_movementInfo, m_playerLoading, WorldObject::m_transport, METRIC_EVENT, MOVEMENTFLAG_ONTRANSPORT, PER_CHARACTER_CACHE_MASK, PLAYER_EXPLORED_ZONES_1, PLAYER_EXPLORED_ZONES_SIZE, PLAYER_FLAGS_CONTESTED_PVP, PLAYER_FLAGS_IN_PVP, PLAYER_FLAGS_PVP_TIMER, PLAYER_FLAGS_RESTING, PLAYER_LOGIN_QUERY_LOAD_ACCOUNT_DATA, PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION, ChatHandler::PSendSysMessage(), RACE_NIGHTELF, realm, RealmHandle::Realm, Player::RemoveAtLoginFlag(), MovementInfo::RemoveMovementFlag(), Player::RemovePlayerFlag(), MovementInfo::TransportInfo::Reset(), Player::resetSpells(), Player::resetTalents(), Pet::resetTalentsForAllPetsOf(), sCharacterCache, sChrClassesStore, sChrRacesStore, SendAccountDataTimes(), Player::SendCinematicStart(), Player::SendDungeonDifficulty(), Player::SendInitialPacketsAfterAddToMap(), Player::SendInitialPacketsBeforeAddToMap(), Player::SendInstanceResetWarning(), Guild::SendLoginInfo(), SendNameQueryOpcode(), ChatHandler::SendNotification(), SendPacket(), ReputationMgr::SendStates(), Player::SendTalentsInfoData(), Object::SendUpdateToPlayer(), Object::SetByteFlag(), Player::setCinematic(), Unit::SetContestedPvP(), PreparedStatementBase::SetData(), Object::SetFlag(), Player::SetInGameTime(), Player::SetInGuild(), Player::SetIsSpectator(), Player::SetMountBlockId(), ReputationMgr::SetOneFactionReputation(), SetPlayer(), Player::SetRank(), Unit::SetStandState(), Player::SetTaxiCheater(), sFactionStore, sGuildMgr, sInstanceSaveMgr, sMotdMgr, SMSG_FEATURE_SYSTEM_STATUS, SMSG_LEARNED_DANCE_MOVES, SMSG_LOGIN_VERIFY_WORLD, sObjectMgr, sScriptMgr, sSocialMgr, sWorld, sWorldSessionMgr, AreaTriggerTeleport::target_mapId, AreaTriggerTeleport::target_X, AreaTriggerTeleport::target_Y, AreaTriggerTeleport::target_Z, Player::TeleportTo(), ObjectGuid::ToString(), MovementInfo::transport, UNIT_BYTE2_FLAG_FFA_PVP, UNIT_FIELD_BYTES_2, UNIT_STAND_STATE_STAND, UNIT_STATE_STUNNED, Player::UpdateAchievementCriteria(), Player::UpdateAreaDependentAuras(), Player::UpdatePvP(), and Player::UpdateZoneDependentAuras().

Referenced by HandlePlayerLoginOpcode().

◆ HandlePlayerLoginOpcode()

void WorldSession::HandlePlayerLoginOpcode ( WorldPacket recvPacket)
670{
671 if (!sWorld->getBoolConfig(CONFIG_REALM_LOGIN_ENABLED))
672 {
674 return;
675 }
676
677 if (PlayerLoading() || GetPlayer() != nullptr)
678 {
679 LOG_ERROR("network", "Player tried to login again, AccountId = {}", GetAccountId());
680 KickPlayer("WorldSession::HandlePlayerLoginOpcode Another client logging in");
681 return;
682 }
683
684 ObjectGuid playerGuid;
685 recvData >> playerGuid;
686
687 if (!IsLegitCharacterForAccount(playerGuid))
688 {
689 LOG_ERROR("network", "Account ({}) can't login with that character ({}).", GetAccountId(), playerGuid.ToString());
690 KickPlayer("Account can't login with this character");
691 return;
692 }
693
694 // pussywizard:
695 if (WorldSession* sess = sWorldSessionMgr->FindOfflineSessionForCharacterGUID(playerGuid.GetCounter()))
696 {
697 if (sess->GetAccountId() != GetAccountId())
698 {
700 return;
701 }
702 }
703
704 // pussywizard:
705 if (WorldSession* sess = sWorldSessionMgr->FindOfflineSession(GetAccountId()))
706 {
707 Player* p = sess->GetPlayer();
708 if (!p || sess->IsKicked())
709 {
711 return;
712 }
713
714 if (p->GetGUID() != playerGuid)
715 sess->KickPlayer("No return, go to normal loading"); // no return, go to normal loading
716 else
717 {
718 // pussywizard: players stay ingame no matter what (prevent abuse), but allow to turn it off to stop crashing
719 if (!sWorld->getBoolConfig(CONFIG_ENABLE_LOGIN_AFTER_DC))
720 {
722 return;
723 }
724
725 uint8 limitA = 10, limitB = 10, limitC = 10; // pussywizard: this somehow froze (probably, ahh crash logs ...), and while (far) have never frozen in LogoutPlayer o_O maybe it's the combination of while(far); while(near);
726 while (sess->GetPlayer() && (sess->GetPlayer()->IsBeingTeleportedFar() || (sess->GetPlayer()->IsInWorld() && sess->GetPlayer()->IsBeingTeleportedNear())))
727 {
728 if (limitA == 0 || --limitA == 0)
729 {
730 LOG_INFO("misc", "HandlePlayerLoginOpcode A");
731 break;
732 }
733 while (sess->GetPlayer() && sess->GetPlayer()->IsBeingTeleportedFar())
734 {
735 if (limitB == 0 || --limitB == 0)
736 {
737 LOG_INFO("misc", "HandlePlayerLoginOpcode B");
738 break;
739 }
740 sess->HandleMoveWorldportAck();
741 }
742 while (sess->GetPlayer() && sess->GetPlayer()->IsInWorld() && sess->GetPlayer()->IsBeingTeleportedNear())
743 {
744 if (limitC == 0 || --limitC == 0)
745 {
746 LOG_INFO("misc", "HandlePlayerLoginOpcode C");
747 break;
748 }
749
750 Player* plMover = sess->GetPlayer()->m_mover->ToPlayer();
751 if (!plMover)
752 break;
753
755 pkt << plMover->GetPackGUID();
756 pkt << uint32(0); // flags
757 pkt << uint32(0); // time
758 sess->HandleMoveTeleportAck(pkt);
759 }
760 }
761 if (!p->FindMap() || !p->IsInWorld() || sess->IsKicked())
762 {
764 return;
765 }
766
767 sess->SetPlayer(nullptr);
768 SetPlayer(p);
769 p->SetSession(this);
770 delete p->PlayerTalkClass;
773 return;
774 }
775 }
776
777 std::shared_ptr<LoginQueryHolder> holder = std::make_shared<LoginQueryHolder>(GetAccountId(), playerGuid);
778 if (!holder->Initialize())
779 return;
780
781 m_playerLoading = true;
782 AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase const& holder)
783 {
784 HandlePlayerLoginFromDB(static_cast<LoginQueryHolder const&>(holder));
785 });
786}
@ CONFIG_ENABLE_LOGIN_AFTER_DC
Definition WorldConfig.h:103
@ CONFIG_REALM_LOGIN_ENABLED
Definition WorldConfig.h:129
Definition CharacterHandler.cpp:64
Definition GossipDef.h:259
void SetSession(WorldSession *sess)
Definition Player.h:1999
Definition QueryHolder.h:25
void AfterComplete(std::function< void(SQLQueryHolderBase const &)> callback) &
Definition QueryHolder.h:77
Player session in the World.
Definition WorldSession.h:369
void SendCharLoginFailed(LoginFailureReason reason)
Definition CharacterHandler.cpp:2591
bool PlayerLoading() const
Definition WorldSession.h:381
void HandlePlayerLoginToCharInWorld(Player *pCurrChar)
Definition CharacterHandler.cpp:1127
SQLQueryHolderCallback & AddQueryHolderCallback(SQLQueryHolderCallback &&callback)
Definition WorldSession.cpp:1329
void HandlePlayerLoginFromDB(LoginQueryHolder const &holder)
Definition CharacterHandler.cpp:788
@ MSG_MOVE_TELEPORT_ACK
Definition Opcodes.h:229

References AddQueryHolderCallback(), SQLQueryHolderCallback::AfterComplete(), CharacterDatabase, CONFIG_ENABLE_LOGIN_AFTER_DC, CONFIG_REALM_LOGIN_ENABLED, DuplicateCharacter, WorldObject::FindMap(), GetAccountId(), ObjectGuid::GetCounter(), Object::GetGUID(), Object::GetPackGUID(), GetPlayer(), Player::GetSession(), HandlePlayerLoginFromDB(), HandlePlayerLoginToCharInWorld(), Object::IsInWorld(), IsLegitCharacterForAccount(), KickPlayer(), LOG_ERROR, LOG_INFO, Player::m_mover, m_playerLoading, MSG_MOVE_TELEPORT_ACK, NoWorld, PlayerLoading(), Player::PlayerTalkClass, SendCharLoginFailed(), SetPlayer(), Player::SetSession(), sWorld, sWorldSessionMgr, Object::ToPlayer(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandlePlayerLoginToCharInWorld()

void WorldSession::HandlePlayerLoginToCharInWorld ( Player pCurrChar)
1128{
1129 ChatHandler chH = ChatHandler(this);
1130 m_playerLoading = true;
1131
1132 pCurrChar->SendDungeonDifficulty(false);
1133
1135 data << pCurrChar->GetMapId();
1136 data << pCurrChar->GetPositionX();
1137 data << pCurrChar->GetPositionY();
1138 data << pCurrChar->GetPositionZ();
1139 data << pCurrChar->GetOrientation();
1140 SendPacket(&data);
1141
1143
1144 data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0
1145 data << uint8(2); // unknown value
1146 data << uint8(0); // enable(1)/disable(0) voice chat interface in client
1147 SendPacket(&data);
1148
1149 // Send MOTD
1150 {
1151 SendPacket(sMotdMgr->GetMotdPacket(pCurrChar->GetSession()->GetSessionDbLocaleIndex()));
1152
1153 // send server info
1154 if (sWorld->getIntConfig(CONFIG_ENABLE_SINFO_LOGIN) == 1)
1156
1157 LOG_DEBUG("network.opcode", "WORLD: Sent server info");
1158 }
1159
1160 data.Initialize(SMSG_LEARNED_DANCE_MOVES, 4 + 4);
1161 data << uint32(0);
1162 data << uint32(0);
1163 SendPacket(&data);
1164
1165 // Xinef: fix possible problem with flag UNIT_FLAG_STUNNED added during logout
1166 if (pCurrChar->HasUnitState(UNIT_STATE_LOGOUT_TIMER))
1167 {
1168 pCurrChar->SetRooted(false, true, true);
1170 }
1171
1172 if (pCurrChar->GetPendingFlightChange() <= pCurrChar->GetMapChangeOrderCounter())
1173 {
1174 if (!pCurrChar->HasIncreaseMountedFlightSpeedAura() && !pCurrChar->HasFlyAura())
1176 }
1177
1179
1180 // necessary actions from AddPlayerToMap:
1181 pCurrChar->GetMap()->SendInitTransports(pCurrChar);
1182 pCurrChar->GetMap()->SendInitSelf(pCurrChar);
1183
1184 // If we are logging into an existing player, simply clear visibility references
1185 // so player will receive a fresh list of new objects on the next vis update.
1187 pCurrChar->UpdateObjectVisibility(false);
1188
1189 pCurrChar->CleanupChannels();
1191 uint32 currZone, currArea;
1192 pCurrChar->GetZoneAndAreaId(currZone, currArea);
1193 pCurrChar->SendInitWorldStates(currZone, currArea);
1194 pCurrChar->SetInGameTime(GameTime::GetGameTimeMS().count());
1195
1196 // Xinef: we need to resend all spell mods
1197 for (uint16 Opcode = SMSG_SET_FLAT_SPELL_MODIFIER; Opcode <= SMSG_SET_PCT_SPELL_MODIFIER; ++Opcode) // PCT = FLAT+1
1198 {
1200 for (uint32 opType = SPELLMOD_DAMAGE; opType < MAX_SPELLMOD; ++opType)
1201 {
1202 int32 i = 0;
1203 flag96 _mask = 0;
1204 SpellModList const& spellMods = pCurrChar->GetSpellModList(opType);
1205 if (spellMods.empty())
1206 continue;
1207
1208 for (int32 eff = 0; eff < 96; ++eff)
1209 {
1210 if (eff != 0 && eff % 32 == 0)
1211 _mask[i++] = 0;
1212
1213 _mask[i] = uint32(1) << (eff - (32 * i));
1214 int32 val = 0;
1215 for (auto const& spellMod : spellMods)
1216 if (spellMod->type == modType && spellMod->mask & _mask)
1217 val += spellMod->value;
1218
1219 if (val == 0)
1220 continue;
1221
1222 WorldPacket data(Opcode, (1 + 1 + 4));
1223 data << uint8(eff);
1224 data << uint8(opType);
1225 data << int32(val);
1226 SendPacket(&data);
1227 }
1228 }
1229 }
1230
1231 if (Group* group = pCurrChar->GetGroup())
1232 group->SendUpdate();
1233
1234 // pussywizard: send instance welcome message as when entering the instance through a portal
1235 if (MapDifficulty const* mapDiff = GetMapDifficultyData(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty()))
1236 if (mapDiff->resetTime)
1237 if (time_t timeReset = sInstanceSaveMgr->GetResetTimeFor(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty()))
1238 {
1239 uint32 timeleft = uint32(timeReset - GameTime::GetGameTime().count());
1240 GetPlayer()->SendInstanceResetWarning(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty(), timeleft, true);
1241 }
1242
1243 // this shouldn't do anything, becaues offline can't be on taxi, but just in case
1244 pCurrChar->ContinueTaxiFlight();
1245
1246 // send pet data, action bar, talents, etc.
1247 pCurrChar->PetSpellInitialize();
1248 pCurrChar->SendTalentsInfoData(true);
1249
1250 // show time before shutdown if shutdown planned.
1251 if (sWorld->IsShuttingDown())
1252 sWorld->ShutdownMsg(true, pCurrChar);
1253
1254 if (pCurrChar->IsGameMaster())
1256
1257 m_playerLoading = false;
1258}
std::list< SpellModifier * > SpellModList
Definition Player.h:196
@ SPELLMOD_FLAT
Definition Player.h:94
@ SPELLMOD_PCT
Definition Player.h:95
@ SPELLMOD_DAMAGE
Definition SpellDefines.h:76
#define MAX_SPELLMOD
Definition SpellDefines.h:109
@ UNIT_STATE_LOGOUT_TIMER
Definition UnitDefines.h:202
void SendInitSelf(Player *player)
Definition Map.cpp:1625
void SendInitTransports(Player *player)
Definition Map.cpp:1671
void CleanVisibilityReferences()
Definition ObjectVisibilityContainer.cpp:47
void CleanupChannels()
Definition Player.cpp:4992
SpellModList const & GetSpellModList(uint32 type) const
Definition Player.h:2622
void PetSpellInitialize()
Definition Player.cpp:9556
void SendInitWorldStates(uint32 zoneId, uint32 areaId)
Definition Player.cpp:8266
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
Definition PlayerUpdates.cpp:1607
uint32 GetMapChangeOrderCounter()
Definition Player.h:2653
bool HasFlyAura() const
Definition Unit.h:1783
bool HasIncreaseMountedFlightSpeedAura() const
Definition Unit.h:1810
ObjectVisibilityContainer & GetObjectVisibilityContainer()
Definition Object.h:725
Definition Util.h:442
@ SMSG_SET_FLAT_SPELL_MODIFIER
Definition Opcodes.h:644
@ SMSG_SET_PCT_SPELL_MODIFIER
Definition Opcodes.h:645

References Player::CleanupChannels(), ObjectVisibilityContainer::CleanVisibilityReferences(), CONFIG_ENABLE_SINFO_LOGIN, Player::ContinueTaxiFlight(), Map::GetDifficulty(), GitRevision::GetFullVersion(), GameTime::GetGameTime(), GameTime::GetGameTimeMS(), Player::GetGroup(), Map::GetId(), WorldObject::GetMap(), Player::GetMapChangeOrderCounter(), GetMapDifficultyData(), WorldLocation::GetMapId(), WorldObject::GetObjectVisibilityContainer(), Position::GetOrientation(), Player::GetPendingFlightChange(), GetPlayer(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetSession(), GetSessionDbLocaleIndex(), Player::GetSpellModList(), WorldObject::GetZoneAndAreaId(), Unit::HasFlyAura(), Unit::HasIncreaseMountedFlightSpeedAura(), Unit::HasUnitState(), WorldPacket::Initialize(), Player::IsGameMaster(), LANG_GM_ON, LOG_DEBUG, WorldObject::m_movementInfo, m_playerLoading, MAX_SPELLMOD, MOVEMENTFLAG_CAN_FLY, PER_CHARACTER_CACHE_MASK, Player::PetSpellInitialize(), ChatHandler::PSendSysMessage(), MovementInfo::RemoveMovementFlag(), Unit::RemoveUnitFlag(), SendAccountDataTimes(), Player::SendDungeonDifficulty(), Player::SendInitialPacketsAfterAddToMap(), Player::SendInitialPacketsBeforeAddToMap(), Map::SendInitSelf(), Map::SendInitTransports(), Player::SendInitWorldStates(), Player::SendInstanceResetWarning(), ChatHandler::SendNotification(), SendPacket(), Player::SendTalentsInfoData(), Player::SetInGameTime(), Unit::SetRooted(), sInstanceSaveMgr, sMotdMgr, SMSG_FEATURE_SYSTEM_STATUS, SMSG_LEARNED_DANCE_MOVES, SMSG_LOGIN_VERIFY_WORLD, SMSG_SET_FLAT_SPELL_MODIFIER, SMSG_SET_PCT_SPELL_MODIFIER, SPELLMOD_DAMAGE, SPELLMOD_FLAT, SPELLMOD_PCT, sWorld, UNIT_FLAG_STUNNED, UNIT_STATE_LOGOUT_TIMER, and Player::UpdateObjectVisibility().

Referenced by HandlePlayerLoginOpcode().

◆ HandlePlayerLoginToCharOutOfWorld()

void WorldSession::HandlePlayerLoginToCharOutOfWorld ( Player pCurrChar)
1261{
1262 ABORT();
1263}
#define ABORT
Definition Errors.h:76

References ABORT.

◆ HandlePlayerLogoutOpcode()

void WorldSession::HandlePlayerLogoutOpcode ( WorldPackets::Character::PlayerLogout playerLogout)
479{
480}

Referenced by OpcodeTable::Initialize().

◆ HandlePushQuestToParty()

void WorldSession::HandlePushQuestToParty ( WorldPacket recvPacket)
536{
537 uint32 questId;
538 recvPacket >> questId;
539
540 if (!_player->CanShareQuest(questId))
541 return;
542
543 LOG_DEBUG("network", "WORLD: Received CMSG_PUSHQUESTTOPARTY quest = {}", questId);
544
545 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
546 {
547 if (Group* group = _player->GetGroup())
548 {
549 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
550 {
551 Player* player = itr->GetSource();
552
553 if (!player || player == _player || !player->IsInMap(_player)) // skip self
554 continue;
555
556 if (!player->SatisfyQuestStatus(quest, false))
557 {
559 continue;
560 }
561
562 if (player->GetQuestStatus(questId) == QUEST_STATUS_COMPLETE)
563 {
565 continue;
566 }
567
568 if (!player->CanTakeQuest(quest, false))
569 {
571 continue;
572 }
573
574 if (!player->SatisfyQuestLog(false))
575 {
577 continue;
578 }
579
580 // Check if Quest Share in BG is enabled
582 {
583 // Check if player is in BG
584 if (_player->InBattleground())
585 {
587 continue;
588 }
589 }
590
591 if (player->GetDivider())
592 {
594 continue;
595 }
596
598
599 if (quest->IsAutoAccept() && player->CanAddQuest(quest, true) && player->CanTakeQuest(quest, true))
600 player->AddQuestAndCheckCompletion(quest, _player);
601
602 if (quest->IsAutoComplete() || !quest->GetQuestMethod())
604 else
605 {
606 player->SetDivider(_player->GetGUID());
607 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
608 }
609 }
610 }
611 }
612}
@ LANG_BG_SHARE_QUEST_ERROR
Definition Language.h:1339
@ QUEST_STATUS_COMPLETE
Definition QuestDef.h:101
@ QUEST_PARTY_MSG_FINISH_QUEST
Definition QuestDef.h:73
@ QUEST_PARTY_MSG_CANT_TAKE_QUEST
Definition QuestDef.h:67
@ QUEST_PARTY_MSG_BUSY
Definition QuestDef.h:70
@ QUEST_PARTY_MSG_HAVE_QUEST
Definition QuestDef.h:72
@ QUEST_PARTY_MSG_SHARING_QUEST
Definition QuestDef.h:66
@ QUEST_PARTY_MSG_LOG_FULL
Definition QuestDef.h:71
@ CONFIG_BATTLEGROUND_DISABLE_QUEST_SHARE_IN_BG
Definition WorldConfig.h:68
void SendQuestGiverQuestDetails(Quest const *quest, ObjectGuid npcGUID, bool activateAccept) const
Definition GossipDef.cpp:388
void SendQuestGiverRequestItems(Quest const *quest, ObjectGuid npcGUID, bool canComplete, bool closeOnCancel) const
Definition GossipDef.cpp:752
bool CanTakeQuest(Quest const *quest, bool msg)
Definition PlayerQuest.cpp:251
bool CanAddQuest(Quest const *quest, bool msg)
Definition PlayerQuest.cpp:264
ObjectGuid GetDivider()
Definition Player.h:1546
void SendPushToPartyResponse(Player const *player, uint8 msg) const
Definition PlayerQuest.cpp:2433
bool SatisfyQuestLog(bool msg)
Definition PlayerQuest.cpp:984
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition PlayerQuest.cpp:421
bool CanCompleteRepeatableQuest(Quest const *quest)
Definition PlayerQuest.cpp:366
bool CanShareQuest(uint32 quest_id) const
Definition PlayerQuest.cpp:1456
void SetDivider(ObjectGuid guid=ObjectGuid::Empty)
Definition Player.h:1547
bool SatisfyQuestStatus(Quest const *qInfo, bool msg) const
Definition PlayerQuest.cpp:1148
bool IsInMap(WorldObject const *obj) const
Definition Object.cpp:1311

References _player, Player::AddQuestAndCheckCompletion(), Player::CanAddQuest(), Player::CanCompleteRepeatableQuest(), Player::CanShareQuest(), Player::CanTakeQuest(), CONFIG_BATTLEGROUND_DISABLE_QUEST_SHARE_IN_BG, Player::GetDivider(), Player::GetGroup(), Object::GetGUID(), Player::GetQuestStatus(), Player::GetSession(), Player::InBattleground(), WorldObject::IsInMap(), LANG_BG_SHARE_QUEST_ERROR, LOG_DEBUG, Player::PlayerTalkClass, QUEST_PARTY_MSG_BUSY, QUEST_PARTY_MSG_CANT_TAKE_QUEST, QUEST_PARTY_MSG_FINISH_QUEST, QUEST_PARTY_MSG_HAVE_QUEST, QUEST_PARTY_MSG_LOG_FULL, QUEST_PARTY_MSG_SHARING_QUEST, QUEST_STATUS_COMPLETE, Player::SatisfyQuestLog(), Player::SatisfyQuestStatus(), ChatHandler::SendNotification(), Player::SendPushToPartyResponse(), PlayerMenu::SendQuestGiverQuestDetails(), PlayerMenu::SendQuestGiverRequestItems(), Player::SetDivider(), sObjectMgr, and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandlePVPLogDataOpcode()

void WorldSession::HandlePVPLogDataOpcode ( WorldPacket recvData)
350{
351 LOG_DEBUG("network", "WORLD: Recvd MSG_PVP_LOG_DATA Message");
352
354 if (!bg)
355 return;
356
357 // Prevent players from sending BuildPvpLogDataPacket in an arena except for when sent in BattleGround::EndBattleGround.
358 if (bg->isArena())
359 return;
360
361 WorldPacket data;
362 bg->BuildPvPLogDataPacket(data);
363 SendPacket(&data);
364
365 LOG_DEBUG("network", "WORLD: Sent MSG_PVP_LOG_DATA Message");
366}
void BuildPvPLogDataPacket(WorldPacket &data)
Definition Battleground.cpp:1390

References _player, Battleground::BuildPvPLogDataPacket(), Player::GetBattleground(), Battleground::isArena(), LOG_DEBUG, and SendPacket().

Referenced by OpcodeTable::Initialize().

◆ HandleQueryGuildBankTabText()

void WorldSession::HandleQueryGuildBankTabText ( WorldPackets::Guild::GuildBankTextQuery packet)
389{
390 LOG_DEBUG("guild", "MSG_QUERY_GUILD_BANK_TEXT [{}]: TabId: {}", GetPlayerInfo(), packet.Tab);
391
392 if (Guild* guild = GetPlayer()->GetGuild())
393 guild->SendBankTabText(this, packet.Tab);
394}
uint8 Tab
Definition GuildPackets.h:563

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, and WorldPackets::Guild::GuildBankTextQuery::Tab.

Referenced by OpcodeTable::Initialize().

◆ HandleQueryInspectAchievements()

void WorldSession::HandleQueryInspectAchievements ( WorldPacket recvData)
1578{
1579 ObjectGuid guid;
1580 recv_data >> guid.ReadAsPacked();
1581
1582 Player* player = ObjectAccessor::GetPlayer(*_player, guid);
1583 if (!player)
1584 {
1585 return;
1586 }
1587
1588 if (!GetPlayer()->IsWithinDistInMap(player, INSPECT_DISTANCE, false))
1589 {
1590 return;
1591 }
1592
1593 if (GetPlayer()->IsValidAttackTarget(player))
1594 {
1595 return;
1596 }
1597
1599}
void SendRespondInspectAchievements(Player *player) const
Definition Player.cpp:13955

References _player, GetPlayer(), ObjectAccessor::GetPlayer(), INSPECT_DISTANCE, ObjectGuid::ReadAsPacked(), and Player::SendRespondInspectAchievements().

Referenced by OpcodeTable::Initialize().

◆ HandleQueryNextMailTime()

void WorldSession::HandleQueryNextMailTime ( WorldPacket recvData)
825{
827
828 if (_player->unReadMails > 0)
829 {
830 data << float(0); // float
831 data << uint32(0); // count
832
833 uint32 count = 0;
834 time_t now = GameTime::GetGameTime().count();
835 std::set<uint32> sentSenders;
836 for (Mail const* mail : _player->GetMails())
837 {
838 // must be not checked yet
839 if (mail->checked & MAIL_CHECK_MASK_READ)
840 continue;
841
842 // and already delivered or expired
843 if (now < mail->deliver_time || now > mail->expire_time)
844 continue;
845
846 // only send each mail sender once
847 if (sentSenders.count(mail->sender))
848 continue;
849
850 data << (mail->messageType == MAIL_NORMAL ? ObjectGuid::Create<HighGuid::Player>(mail->sender) : ObjectGuid::Empty); // player guid
851 data << uint32(mail->messageType != MAIL_NORMAL ? mail->sender : 0); // non-player entries
852 data << uint32(mail->messageType);
853 data << uint32(mail->stationery);
854 data << float(mail->deliver_time - now);
855
856 sentSenders.insert(mail->sender);
857 ++count;
858 if (count == 2) // do not display more than 2 mails
859 break;
860 }
861
862 data.put<uint32>(4, count);
863 }
864 else
865 {
866 data << float(-DAY);
867 data << uint32(0);
868 }
869
870 SendPacket(&data);
871}
@ MSG_QUERY_NEXT_MAIL_TIME
Definition Opcodes.h:674

References _player, DAY, ObjectGuid::Empty, GameTime::GetGameTime(), Player::GetMails(), MAIL_CHECK_MASK_READ, MAIL_NORMAL, MSG_QUERY_NEXT_MAIL_TIME, ByteBuffer::put(), SendPacket(), and Player::unReadMails.

Referenced by OpcodeTable::Initialize().

◆ HandleQueryQuestsCompleted()

void WorldSession::HandleQueryQuestsCompleted ( WorldPacket recvData)
640{
641 std::size_t rew_count = _player->GetRewardedQuestCount();
642
643 WorldPacket data(SMSG_QUERY_QUESTS_COMPLETED_RESPONSE, 4 + 4 * rew_count);
644 data << uint32(rew_count);
645
646 const RewardedQuestSet& rewQuests = _player->getRewardedQuests();
647 for (RewardedQuestSet::const_iterator itr = rewQuests.begin(); itr != rewQuests.end(); ++itr)
648 data << uint32(*itr);
649
650 SendPacket(&data);
651}
std::unordered_set< uint32 > RewardedQuestSet
Definition Player.h:610
std::size_t GetRewardedQuestCount() const
Definition Player.h:1624
RewardedQuestSet const & getRewardedQuests() const
Definition Player.h:1620
@ SMSG_QUERY_QUESTS_COMPLETED_RESPONSE
Definition Opcodes.h:1311

References _player, Player::GetRewardedQuestCount(), Player::getRewardedQuests(), SendPacket(), and SMSG_QUERY_QUESTS_COMPLETED_RESPONSE.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestConfirmAccept()

void WorldSession::HandleQuestConfirmAccept ( WorldPacket recvData)
450{
451 uint32 questId;
452 recvData >> questId;
453
454 LOG_DEBUG("network", "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = {}", questId);
455
456 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
457 {
458 if (!quest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT))
459 return;
460
462 if (!originalPlayer)
463 return;
464
465 if (!_player->IsInSameRaidWith(originalPlayer) || !_player->IsAtGroupRewardDistance(originalPlayer))
466 return;
467
468 if (!_player->CanTakeQuest(quest, true) || _player->HasPendingBind())
469 return;
470
471 // pussywizard: exploit fix, can't share quests that give items to be sold
472 if (uint32 itemId = quest->GetSrcItemId())
473 if (ItemTemplate const* srcItem = sObjectMgr->GetItemTemplate(itemId))
474 if (srcItem->SellPrice > 0)
475 return;
476
477 if (_player->CanAddQuest(quest, true))
478 _player->AddQuestAndCheckCompletion(quest, nullptr); // nullptr, this prevent DB script from duplicate running
479
481 }
482}
@ QUEST_FLAGS_PARTY_ACCEPT
Definition QuestDef.h:133
bool IsInSameRaidWith(Player const *p) const
Definition Player.h:1881
bool IsAtGroupRewardDistance(WorldObject const *pRewardSource) const
Definition Player.cpp:12801

References _player, Player::AddQuestAndCheckCompletion(), Player::CanAddQuest(), Player::CanTakeQuest(), Player::GetDivider(), ObjectAccessor::GetPlayer(), Player::HasPendingBind(), Player::IsAtGroupRewardDistance(), Player::IsInSameRaidWith(), LOG_DEBUG, QUEST_FLAGS_PARTY_ACCEPT, Player::SetDivider(), and sObjectMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestgiverAcceptQuestOpcode()

void WorldSession::HandleQuestgiverAcceptQuestOpcode ( WorldPacket recvPacket)
111{
112 ObjectGuid guid;
113 uint32 questId;
114 uint32 unk1;
115 recvData >> guid >> questId >> unk1;
116
117 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc {}, quest = {}, unk1 = {}", guid.ToString(), questId, unk1);
118
120
121 // no or incorrect quest giver
122 if (!object || object == _player || (!object->IsPlayer() && !object->hasQuest(questId)) ||
123 (object->IsPlayer() && !object->ToPlayer()->CanShareQuest(questId)))
124 {
127 return;
128 }
129
130 // some kind of WPE protection
132 return;
133
134 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
135 {
136 // pussywizard: exploit fix, can't share quests that give items to be sold
137 if (object->IsPlayer())
138 if (uint32 itemId = quest->GetSrcItemId())
139 if (ItemTemplate const* srcItem = sObjectMgr->GetItemTemplate(itemId))
140 if (srcItem->SellPrice > 0)
141 return;
142
143 // prevent cheating
144 if (!GetPlayer()->CanTakeQuest(quest, true))
145 {
148 return;
149 }
150
151 if (_player->GetDivider())
152 {
154 if (player)
155 {
158 }
159 }
160
161 if (_player->CanAddQuest(quest, true))
162 {
163 _player->AddQuestAndCheckCompletion(quest, object);
164
165 if (quest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT))
166 {
167 if (Group* group = _player->GetGroup())
168 {
169 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
170 {
171 Player* itrPlayer = itr->GetSource();
172 if (!itrPlayer || itrPlayer == _player || !itrPlayer->IsAtGroupRewardDistance(_player) || itrPlayer->HasPendingBind()) // xinef: check range
173 continue;
174
175 if (itrPlayer->CanTakeQuest(quest, false))
176 {
177 itrPlayer->SetDivider(_player->GetGUID());
178
179 // need confirmation that any gossip window will close
180 itrPlayer->PlayerTalkClass->SendCloseGossip();
181
182 _player->SendQuestConfirmAccept(quest, itrPlayer);
183 }
184 }
185 }
186 }
187
189
190 if (quest->GetSrcSpell() > 0)
191 _player->CastSpell(_player, quest->GetSrcSpell(), true);
192
193 return;
194 }
195 }
196
198}
@ TYPEMASK_ITEM
Definition ObjectGuid.h:47
@ TYPEMASK_UNIT
Definition ObjectGuid.h:49
@ TYPEMASK_GAMEOBJECT
Definition ObjectGuid.h:51
@ TYPEMASK_PLAYER
Definition ObjectGuid.h:50
@ QUEST_PARTY_MSG_ACCEPT_QUEST
Definition QuestDef.h:68
Definition Object.h:104
virtual bool hasQuest(uint32) const
Definition Object.h:189
void SendQuestConfirmAccept(Quest const *quest, Player *pReceiver)
Definition PlayerQuest.cpp:2411
bool CanInteractWithQuestGiver(Object *questGiver)
Definition Player.cpp:2051
Object * GetObjectByTypeMask(WorldObject const &, ObjectGuid const &guid, uint32 typemask)
Definition ObjectAccessor.cpp:141

References _player, Player::AddQuestAndCheckCompletion(), Player::CanAddQuest(), Player::CanInteractWithQuestGiver(), Player::CanShareQuest(), Player::CanTakeQuest(), Unit::CastSpell(), Player::GetDivider(), Player::GetGroup(), Object::GetGUID(), ObjectAccessor::GetObjectByTypeMask(), GetPlayer(), ObjectAccessor::GetPlayer(), Player::HasPendingBind(), Object::hasQuest(), Player::IsAtGroupRewardDistance(), Object::IsPlayer(), LOG_DEBUG, Player::PlayerTalkClass, QUEST_FLAGS_PARTY_ACCEPT, QUEST_PARTY_MSG_ACCEPT_QUEST, PlayerMenu::SendCloseGossip(), Player::SendPushToPartyResponse(), Player::SendQuestConfirmAccept(), Player::SetDivider(), sObjectMgr, Object::ToPlayer(), ObjectGuid::ToString(), TYPEMASK_GAMEOBJECT, TYPEMASK_ITEM, TYPEMASK_PLAYER, and TYPEMASK_UNIT.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestgiverCancel()

void WorldSession::HandleQuestgiverCancel ( WorldPacket recvData)

◆ HandleQuestgiverChooseRewardOpcode()

void WorldSession::HandleQuestgiverChooseRewardOpcode ( WorldPacket recvPacket)
248{
249 uint32 questId, reward;
250 ObjectGuid guid;
251 recvData >> guid >> questId >> reward;
252
253 if (reward >= QUEST_REWARD_CHOICES_COUNT)
254 {
255 LOG_ERROR("network.opcode", "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player {} ({}) tried to get invalid reward ({}) (probably packet hacking)",
256 _player->GetName(), _player->GetGUID().ToString(), reward);
257 return;
258 }
259
260 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc {}, quest = {}, reward = {}", guid.ToString(), questId, reward);
261
263 if (!object || !object->hasInvolvedQuest(questId))
264 return;
265
266 // some kind of WPE protection
268 return;
269
270 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
271 {
272 if ((!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId) == QUEST_STATUS_NONE) ||
273 (_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE && !quest->IsAutoComplete() && quest->GetQuestMethod()))
274 {
275 LOG_ERROR("network.opcode", "HACK ALERT: Player {} ({}) is trying to complete quest (id: {}) but he has no right to do it!",
276 _player->GetName(), _player->GetGUID().ToString(), questId);
277 return;
278 }
279 if (_player->CanRewardQuest(quest, reward, true))
280 {
281 _player->RewardQuest(quest, reward, object);
282
283 // Special dialog status update (client does not query this)
284 if (!quest->GetQuestMethod())
285 {
287 }
288
289 switch (object->GetTypeId())
290 {
291 case TYPEID_UNIT:
292 {
293 Creature* questgiver = object->ToCreature();
294 if (!sScriptMgr->OnQuestReward(_player, questgiver, quest, reward))
295 {
296 // Send next quest
297 if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
298 {
299 if (_player->CanTakeQuest(nextQuest, false))
300 {
301 if (nextQuest->IsAutoAccept())
302 {
303 // QUEST_FLAGS_AUTO_ACCEPT was not used by Blizzard.
304 if (_player->CanAddQuest(nextQuest, false))
305 {
306 _player->AddQuestAndCheckCompletion(nextQuest, object);
307 }
308 else
309 {
310 // Auto accept is set for a custom quest and there is no inventory space
312 break;
313 }
314 }
315 _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
316 }
317 }
318
319 questgiver->AI()->sQuestReward(_player, quest, reward);
320 }
321 break;
322 }
324 {
325 GameObject* questGiver = object->ToGameObject();
326 if (!sScriptMgr->OnQuestReward(_player, questGiver, quest, reward))
327 {
328 // Send next quest
329 if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
330 {
331 if (_player->CanAddQuest(nextQuest, false) && _player->CanTakeQuest(nextQuest, false))
332 {
333 if (nextQuest->IsAutoAccept())
334 _player->AddQuestAndCheckCompletion(nextQuest, object);
335 _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
336 }
337 }
338
339 questGiver->AI()->QuestReward(_player, quest, reward);
340 }
341 break;
342 }
343 default:
344 break;
345 }
346 }
347 else
349 }
350}
@ TYPEID_GAMEOBJECT
Definition ObjectGuid.h:37
@ TYPEID_UNIT
Definition ObjectGuid.h:35
@ QUEST_STATUS_NONE
Definition QuestDef.h:100
#define QUEST_REWARD_CHOICES_COUNT
Definition QuestDef.h:38
virtual bool QuestReward(Player *, Quest const *, uint32)
Definition GameObjectAI.h:58
GameObject * ToGameObject()
Definition Object.h:213
virtual bool hasInvolvedQuest(uint32) const
Definition Object.h:190
void SendQuestGiverStatus(uint8 questStatus, ObjectGuid npcGUID) const
Definition GossipDef.cpp:378
void SendQuestGiverOfferReward(Quest const *quest, ObjectGuid npcGUID, bool enableNext) const
Definition GossipDef.cpp:647
QuestGiverStatus GetQuestDialogStatus(Object *questGiver)
Definition PlayerQuest.cpp:1593
bool CanSeeStartQuest(Quest const *quest)
Definition PlayerQuest.cpp:237
Quest const * GetNextQuest(ObjectGuid guid, Quest const *quest)
Definition PlayerQuest.cpp:207
void RewardQuest(Quest const *quest, uint32 reward, Object *questGiver, bool announce=true, bool isLFGReward=false)
Definition PlayerQuest.cpp:659
virtual void sQuestReward(Player *, Quest const *, uint32)
Definition UnitAI.h:418

References _player, Player::AddQuestAndCheckCompletion(), Creature::AI(), GameObject::AI(), Player::CanAddQuest(), Player::CanInteractWithQuestGiver(), Player::CanRewardQuest(), Player::CanSeeStartQuest(), Player::CanTakeQuest(), Object::GetGUID(), WorldObject::GetName(), Player::GetNextQuest(), ObjectAccessor::GetObjectByTypeMask(), Player::GetQuestDialogStatus(), Player::GetQuestStatus(), Object::GetTypeId(), Object::hasInvolvedQuest(), LOG_DEBUG, LOG_ERROR, Player::PlayerTalkClass, QUEST_REWARD_CHOICES_COUNT, QUEST_STATUS_COMPLETE, QUEST_STATUS_NONE, GameObjectAI::QuestReward(), Player::RewardQuest(), PlayerMenu::SendCloseGossip(), PlayerMenu::SendQuestGiverOfferReward(), PlayerMenu::SendQuestGiverQuestDetails(), PlayerMenu::SendQuestGiverStatus(), sObjectMgr, UnitAI::sQuestReward(), sScriptMgr, Object::ToCreature(), Object::ToGameObject(), ObjectGuid::ToString(), TYPEID_GAMEOBJECT, TYPEID_UNIT, TYPEMASK_GAMEOBJECT, and TYPEMASK_UNIT.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestgiverCompleteQuest()

void WorldSession::HandleQuestgiverCompleteQuest ( WorldPacket recvData)
485{
486 uint32 questId;
487 ObjectGuid guid;
488
489 recvData >> guid >> questId;
490
491 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST npc {}, quest = {}", guid.ToString(), questId);
492
494 if (!object || !object->hasInvolvedQuest(questId))
495 return;
496
497 // some kind of WPE protection
499 return;
500
501 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
502 {
504 {
505 LOG_ERROR("network.opcode", "Possible hacking attempt: Player {} [{}] tried to complete quest [entry: {}] without being in possession of the quest!",
506 _player->GetName(), _player->GetGUID().ToString(), questId);
507 return;
508 }
509
511 if (bg->GetBgTypeID(true) == BATTLEGROUND_AV)
512 bg->ToBattlegroundAV()->HandleQuestComplete(questId, _player);
513
515 {
516 if (quest->IsRepeatable())
518 else
519 _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, _player->CanRewardQuest(quest, false), false);
520 }
521 else
522 {
523 if (quest->GetReqItemsCount()) // some items required
524 _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, _player->CanRewardQuest(quest, false), false);
525 else // no items required
527 }
528 }
529}
@ BATTLEGROUND_AV
Definition SharedDefines.h:3747

References _player, BATTLEGROUND_AV, Player::CanCompleteRepeatableQuest(), Player::CanInteractWithQuestGiver(), Player::CanRewardQuest(), Player::CanSeeStartQuest(), Player::GetBattleground(), Object::GetGUID(), WorldObject::GetName(), ObjectAccessor::GetObjectByTypeMask(), Player::GetQuestStatus(), Object::hasInvolvedQuest(), LOG_DEBUG, LOG_ERROR, Player::PlayerTalkClass, QUEST_STATUS_COMPLETE, QUEST_STATUS_NONE, PlayerMenu::SendQuestGiverOfferReward(), PlayerMenu::SendQuestGiverRequestItems(), sObjectMgr, ObjectGuid::ToString(), TYPEMASK_GAMEOBJECT, and TYPEMASK_UNIT.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestgiverHelloOpcode()

void WorldSession::HandleQuestgiverHelloOpcode ( WorldPacket recvPacket)
79{
80 ObjectGuid guid;
81 recvData >> guid;
82
83 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_HELLO npc {}", guid.ToString());
84
86 if (!creature)
87 {
88 LOG_DEBUG("network", "WORLD: HandleQuestgiverHelloOpcode - Unit ({}) not found or you can't interact with him.", guid.ToString());
89 return;
90 }
91
92 // remove fake death
93 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
95
96 // Stop the npc if moving
97 if (uint32 pause = creature->GetMovementTemplate().GetInteractionPauseTimer())
98 creature->PauseMovement(pause);
99 creature->SetHomePosition(creature->GetPosition());
100
101 if (sScriptMgr->OnGossipHello(_player, creature))
102 return;
103
104 _player->PrepareGossipMenu(creature, creature->GetCreatureTemplate()->GossipMenuId, true);
105 _player->SendPreparedGossip(creature);
106
107 creature->AI()->sGossipHello(_player);
108}

References _player, Creature::AI(), Creature::GetCreatureTemplate(), CreatureMovementData::GetInteractionPauseTimer(), Creature::GetMovementTemplate(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Position::GetPosition(), CreatureTemplate::GossipMenuId, LOG_DEBUG, Unit::PauseMovement(), Player::PrepareGossipMenu(), Unit::RemoveAurasByType(), Player::SendPreparedGossip(), Creature::SetHomePosition(), UnitAI::sGossipHello(), SPELL_AURA_FEIGN_DEATH, sScriptMgr, ObjectGuid::ToString(), UNIT_NPC_FLAG_NONE, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestgiverQueryQuestOpcode()

void WorldSession::HandleQuestgiverQueryQuestOpcode ( WorldPacket recvPacket)
201{
202 ObjectGuid guid;
203 uint32 questId;
204 uint8 unk1;
205 recvData >> guid >> questId >> unk1;
206 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_QUERY_QUEST npc {}, quest = {}, unk1 = {}", guid.ToString(), questId, unk1);
207
208 // Verify that the guid is valid and is a questgiver or involved in the requested quest
210 if (!object || (!object->hasQuest(questId) && !object->hasInvolvedQuest(questId)))
211 {
213 return;
214 }
215
216 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
217 {
218 // not sure here what should happen to quests with QUEST_FLAGS_AUTOCOMPLETE
219 // if this breaks them, add && object->IsItem() to this check
220 // item-started quests never have that flag
221 if (!_player->CanTakeQuest(quest, true))
222 return;
223
224 if (quest->IsAutoAccept() && _player->CanAddQuest(quest, true))
225 _player->AddQuestAndCheckCompletion(quest, object);
226
227 if (quest->IsAutoComplete() || !quest->GetQuestMethod())
228 _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, object->GetGUID(), _player->CanCompleteQuest(quest->GetQuestId()), true);
229 else
231 }
232}
bool CanCompleteQuest(uint32 quest_id, const QuestStatusData *q_savedStatus=nullptr)
Definition PlayerQuest.cpp:289

References _player, Player::AddQuestAndCheckCompletion(), Player::CanAddQuest(), Player::CanCompleteQuest(), Player::CanTakeQuest(), Object::GetGUID(), ObjectAccessor::GetObjectByTypeMask(), Object::hasInvolvedQuest(), Object::hasQuest(), LOG_DEBUG, Player::PlayerTalkClass, PlayerMenu::SendCloseGossip(), PlayerMenu::SendQuestGiverQuestDetails(), PlayerMenu::SendQuestGiverRequestItems(), sObjectMgr, ObjectGuid::ToString(), TYPEMASK_GAMEOBJECT, TYPEMASK_ITEM, and TYPEMASK_UNIT.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestgiverQuestAutoLaunch()

void WorldSession::HandleQuestgiverQuestAutoLaunch ( WorldPacket recvPacket)
532{
533}

Referenced by OpcodeTable::Initialize().

◆ HandleQuestgiverRequestRewardOpcode()

void WorldSession::HandleQuestgiverRequestRewardOpcode ( WorldPacket recvPacket)
353{
354 uint32 questId;
355 ObjectGuid guid;
356 recvData >> guid >> questId;
357
358 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_REQUEST_REWARD npc {}, quest = {}", guid.ToString(), questId);
359
361 if (!object || !object->hasInvolvedQuest(questId))
362 return;
363
364 // some kind of WPE protection
366 return;
367
368 if (_player->CanCompleteQuest(questId))
369 _player->CompleteQuest(questId);
370
372 return;
373
374 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
376}
void CompleteQuest(uint32 quest_id)
Definition PlayerQuest.cpp:598

References _player, Player::CanCompleteQuest(), Player::CanInteractWithQuestGiver(), Player::CompleteQuest(), ObjectAccessor::GetObjectByTypeMask(), Player::GetQuestStatus(), Object::hasInvolvedQuest(), LOG_DEBUG, Player::PlayerTalkClass, QUEST_STATUS_COMPLETE, PlayerMenu::SendQuestGiverOfferReward(), sObjectMgr, ObjectGuid::ToString(), TYPEMASK_GAMEOBJECT, and TYPEMASK_UNIT.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestgiverStatusMultipleQuery()

void WorldSession::HandleQuestgiverStatusMultipleQuery ( WorldPacket recvPacket)

◆ HandleQuestgiverStatusQueryOpcode()

void WorldSession::HandleQuestgiverStatusQueryOpcode ( WorldPacket recvPacket)
36{
37 ObjectGuid guid;
38 recvData >> guid;
39 uint32 questStatus = DIALOG_STATUS_NONE;
40
42
43 if (!questGiver)
44 {
45 LOG_DEBUG("network.opcode", "Error in CMSG_QUESTGIVER_STATUS_QUERY, called for not found questgiver ({})", guid.ToString());
46 return;
47 }
48
49 switch (questGiver->GetTypeId())
50 {
51 case TYPEID_UNIT:
52 {
53 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for npc {}", guid.ToString());
54 if (!questGiver->ToCreature()->IsHostileTo(_player)) // do not show quest status to enemies
55 questStatus = _player->GetQuestDialogStatus(questGiver);
56 break;
57 }
58
60 {
61 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for GameObject {}", guid.ToString());
62 if (sWorld->getBoolConfig(CONFIG_OBJECT_QUEST_MARKERS))
63 {
64 questStatus = _player->GetQuestDialogStatus(questGiver);
65 }
66 break;
67 }
68
69 default:
70 LOG_ERROR("network.opcode", "QuestGiver called for unexpected type {}", questGiver->GetTypeId());
71 break;
72 }
73
74 // inform client about status of quest
76}
@ DIALOG_STATUS_NONE
Definition QuestDef.h:112
@ CONFIG_OBJECT_QUEST_MARKERS
Definition WorldConfig.h:140
bool IsHostileTo(Unit const *unit) const
Definition Unit.cpp:10415

References _player, CONFIG_OBJECT_QUEST_MARKERS, DIALOG_STATUS_NONE, ObjectAccessor::GetObjectByTypeMask(), Player::GetQuestDialogStatus(), Object::GetTypeId(), Unit::IsHostileTo(), LOG_DEBUG, LOG_ERROR, Player::PlayerTalkClass, PlayerMenu::SendQuestGiverStatus(), sWorld, Object::ToCreature(), ObjectGuid::ToString(), TYPEID_GAMEOBJECT, TYPEID_UNIT, TYPEMASK_GAMEOBJECT, and TYPEMASK_UNIT.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestLogRemoveQuest()

void WorldSession::HandleQuestLogRemoveQuest ( WorldPacket recvData)
397{
398 uint8 slot;
399 recvData >> slot;
400
401 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTLOG_REMOVE_QUEST slot = {}", slot);
402
403 if (slot < MAX_QUEST_LOG_SIZE)
404 {
405 if (uint32 questId = _player->GetQuestSlotQuestId(slot))
406 {
407 if (!_player->TakeQuestSourceItem(questId, true))
408 return; // can't un-equip some items, reject quest cancel
409
410 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
411 {
412 if (quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED))
413 _player->RemoveTimedQuest(questId);
414
415 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
416 {
419 }
420 }
421
422 _player->TakeQuestSourceItem(questId, true); // remove quest src item from player
423 _player->AbandonQuest(questId); // remove all quest items player received before abandoning quest.
424 _player->RemoveActiveQuest(questId);
426
427 sScriptMgr->OnPlayerQuestAbandon(_player, questId);
428
429 LOG_DEBUG("network.opcode", "Player {} abandoned quest {}", _player->GetGUID().ToString(), questId);
430 // check if Quest Tracker is enabled
431 if (sWorld->getBoolConfig(CONFIG_QUEST_ENABLE_QUEST_TRACKER))
432 {
433 // prepare Quest Tracker datas
434 auto stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_QUEST_TRACK_ABANDON_TIME);
435 stmt->SetData(0, questId);
436 stmt->SetData(1, _player->GetGUID().GetCounter());
437
438 // add to Quest Tracker
439 CharacterDatabase.Execute(stmt);
440 }
441 }
442
443 _player->SetQuestSlot(slot, 0);
444
446 }
447}
@ CHAR_UPD_QUEST_TRACK_ABANDON_TIME
Definition CharacterDatabase.h:506
@ ACHIEVEMENT_TIMED_TYPE_QUEST
Definition DBCEnums.h:111
@ ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED
Definition DBCEnums.h:214
@ QUEST_FLAGS_FLAGS_PVP
Definition QuestDef.h:145
#define MAX_QUEST_LOG_SIZE
Definition QuestDef.h:33
@ QUEST_SPECIAL_FLAGS_TIMED
Definition QuestDef.h:178
@ CONFIG_QUEST_ENABLE_QUEST_TRACKER
Definition WorldConfig.h:107
bool HasPvPForcingQuest() const
Definition PlayerQuest.cpp:2493
void UpdatePvPState()
Definition PlayerUpdates.cpp:1436
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition Player.h:1482
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition Player.h:1486
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition PlayerQuest.cpp:1363
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition PlayerQuest.cpp:1493
void RemoveTimedQuest(uint32 quest_id)
Definition Player.h:1554
void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry)
Definition Player.cpp:13970
void AbandonQuest(uint32 quest_id)
Definition PlayerQuest.cpp:930
bool IsInHostileArea
Definition Player.h:357

References _player, Player::AbandonQuest(), ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED, ACHIEVEMENT_TIMED_TYPE_QUEST, CHAR_UPD_QUEST_TRACK_ABANDON_TIME, CharacterDatabase, CONFIG_QUEST_ENABLE_QUEST_TRACKER, ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetQuestSlotQuestId(), Player::HasPvPForcingQuest(), PvPInfo::IsHostile, PvPInfo::IsInHostileArea, LOG_DEBUG, MAX_QUEST_LOG_SIZE, Player::pvpInfo, QUEST_FLAGS_FLAGS_PVP, QUEST_SPECIAL_FLAGS_TIMED, Player::RemoveActiveQuest(), Player::RemoveTimedAchievement(), Player::RemoveTimedQuest(), Player::SetQuestSlot(), sObjectMgr, sScriptMgr, sWorld, Player::TakeQuestSourceItem(), ObjectGuid::ToString(), Player::UpdateAchievementCriteria(), and Player::UpdatePvPState().

Referenced by OpcodeTable::Initialize().

◆ HandleQuestLogSwapQuest()

void WorldSession::HandleQuestLogSwapQuest ( WorldPacket recvData)
384{
385 uint8 slot1, slot2;
386 recvData >> slot1 >> slot2;
387
388 if (slot1 == slot2 || slot1 >= MAX_QUEST_LOG_SIZE || slot2 >= MAX_QUEST_LOG_SIZE)
389 return;
390
391 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTLOG_SWAP_QUEST slot 1 = {}, slot 2 = {}", slot1, slot2);
392
393 GetPlayer()->SwapQuestSlot(slot1, slot2);
394}
void SwapQuestSlot(uint16 slot1, uint16 slot2)
Definition Player.h:1504

References GetPlayer(), LOG_DEBUG, MAX_QUEST_LOG_SIZE, and Player::SwapQuestSlot().

Referenced by OpcodeTable::Initialize().

◆ HandleQuestPOIQuery()

void WorldSession::HandleQuestPOIQuery ( WorldPacket recvData)
412{
413 uint32 count;
414 recvData >> count; // quest count, max=25
415
416 if (count > MAX_QUEST_LOG_SIZE)
417 {
418 recvData.rfinish();
419 return;
420 }
421
422 // Read quest ids and add the in a unordered_set so we don't send POIs for the same quest multiple times
423 std::unordered_set<uint32> questIds;
424 for (uint32 i = 0; i < count; ++i)
425 questIds.insert(recvData.read<uint32>()); // quest id
426
427 WorldPacket data(SMSG_QUEST_POI_QUERY_RESPONSE, 4 + (4 + 4)*questIds.size());
428 data << uint32(questIds.size()); // count
429
430 for (std::unordered_set<uint32>::const_iterator itr = questIds.begin(); itr != questIds.end(); ++itr)
431 {
432 uint32 questId = *itr;
433 bool questOk = false;
434
435 uint16 questSlot = _player->FindQuestSlot(questId);
436
437 if (questSlot != MAX_QUEST_LOG_SIZE)
438 questOk = _player->GetQuestSlotQuestId(questSlot) == questId;
439
440 if (questOk)
441 {
442 QuestPOIVector const* POI = sObjectMgr->GetQuestPOIVector(questId);
443
444 if (POI)
445 {
446 data << uint32(questId); // quest ID
447 data << uint32(POI->size()); // POI count
448
449 for (QuestPOIVector::const_iterator itr = POI->begin(); itr != POI->end(); ++itr)
450 {
451 data << uint32(itr->Id); // POI index
452 data << int32(itr->ObjectiveIndex); // objective index
453 data << uint32(itr->MapId); // mapid
454 data << uint32(itr->AreaId); // areaid
455 data << uint32(itr->FloorId); // floorid
456 data << uint32(itr->Unk3); // unknown
457 data << uint32(itr->Unk4); // unknown
458 data << uint32(itr->points.size()); // POI points count
459
460 for (std::vector<QuestPOIPoint>::const_iterator itr2 = itr->points.begin(); itr2 != itr->points.end(); ++itr2)
461 {
462 data << int32(itr2->x); // POI point x
463 data << int32(itr2->y); // POI point y
464 }
465 }
466 }
467 else
468 {
469 data << uint32(questId); // quest ID
470 data << uint32(0); // POI count
471 }
472 }
473 else
474 {
475 data << uint32(questId); // quest ID
476 data << uint32(0); // POI count
477 }
478 }
479
480 SendPacket(&data);
481}
std::vector< QuestPOI > QuestPOIVector
Definition ObjectMgr.h:661
uint16 FindQuestSlot(uint32 quest_id) const
Definition PlayerQuest.cpp:1780
@ SMSG_QUEST_POI_QUERY_RESPONSE
Definition Opcodes.h:514

References _player, Player::FindQuestSlot(), Player::GetQuestSlotQuestId(), MAX_QUEST_LOG_SIZE, ByteBuffer::read(), ByteBuffer::rfinish(), SendPacket(), SMSG_QUEST_POI_QUERY_RESPONSE, and sObjectMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestPushResult()

void WorldSession::HandleQuestPushResult ( WorldPacket recvPacket)
615{
616 ObjectGuid guid;
617 uint32 questId;
618 uint8 msg;
619 recvPacket >> guid >> questId >> msg;
620
621 if (_player->GetDivider() && _player->GetDivider() == guid)
622 {
624 {
625 WorldPacket data(MSG_QUEST_PUSH_RESULT, 8 + 4 + 1);
626 data << _player->GetGUID();
627 data << uint8(msg); // valid values: 0-8
628 player->SendDirectMessage(&data);
630 }
631 }
632}
@ MSG_QUEST_PUSH_RESULT
Definition Opcodes.h:660

References _player, Player::GetDivider(), Object::GetGUID(), ObjectAccessor::GetPlayer(), MSG_QUEST_PUSH_RESULT, and Player::SetDivider().

Referenced by OpcodeTable::Initialize().

◆ HandleQuestQueryOpcode()

void WorldSession::HandleQuestQueryOpcode ( WorldPacket recvPacket)
235{
236 if (!_player)
237 return;
238
239 uint32 questId;
240 recvData >> questId;
241 LOG_DEBUG("network", "WORLD: Received CMSG_QUEST_QUERY quest = {}", questId);
242
243 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
245}
void SendQuestQueryResponse(Quest const *quest) const
Definition GossipDef.cpp:507

References _player, LOG_DEBUG, Player::PlayerTalkClass, PlayerMenu::SendQuestQueryResponse(), and sObjectMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleRaidReadyCheckFinishedOpcode()

void WorldSession::HandleRaidReadyCheckFinishedOpcode ( WorldPacket recvData)
747{
748 Group* group = GetPlayer()->GetGroup();
749 if (!group)
750 return;
751
752 if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
753 return;
754
756 group->BroadcastPacket(&data, true, -1);
757}
@ MSG_RAID_READY_CHECK_FINISHED
Definition Opcodes.h:996

References Group::BroadcastPacket(), Player::GetGroup(), GetPlayer(), Group::IsAssistant(), Group::IsLeader(), and MSG_RAID_READY_CHECK_FINISHED.

Referenced by OpcodeTable::Initialize().

◆ HandleRaidReadyCheckOpcode()

void WorldSession::HandleRaidReadyCheckOpcode ( WorldPacket recvData)

error handling

703{
704 Group* group = GetPlayer()->GetGroup();
705 if (!group)
706 return;
707
708 if (recvData.empty()) // request
709 {
711 if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
712 return;
713 /********************/
714
715 // Check if Ready Check in BG is enabled
717 {
718 // Check if player is in BG
719 if (_player->InBattleground())
720 {
722 return;
723 }
724 }
725
726 // everything's fine, do it
728 data << GetPlayer()->GetGUID();
729 group->BroadcastPacket(&data, false, -1);
730
731 group->OfflineReadyCheck();
732 }
733 else // answer
734 {
735 uint8 state;
736 recvData >> state;
737
738 // everything's fine, do it
740 data << GetPlayer()->GetGUID();
741 data << uint8(state);
742 group->BroadcastReadyCheck(&data);
743 }
744}
@ LANG_BG_READY_CHECK_ERROR
Definition Language.h:1340
@ CONFIG_BATTLEGROUND_DISABLE_READY_CHECK_IN_BG
Definition WorldConfig.h:69
void BroadcastReadyCheck(WorldPacket const *packet)
Definition Group.cpp:1770
void OfflineReadyCheck()
Definition Group.cpp:1781
@ MSG_RAID_READY_CHECK
Definition Opcodes.h:832
@ MSG_RAID_READY_CHECK_CONFIRM
Definition Opcodes.h:972

References _player, Group::BroadcastPacket(), Group::BroadcastReadyCheck(), CONFIG_BATTLEGROUND_DISABLE_READY_CHECK_IN_BG, ByteBuffer::empty(), Player::GetGroup(), Object::GetGUID(), GetPlayer(), Player::GetSession(), Player::InBattleground(), Group::IsAssistant(), Group::IsLeader(), LANG_BG_READY_CHECK_ERROR, MSG_RAID_READY_CHECK, MSG_RAID_READY_CHECK_CONFIRM, Group::OfflineReadyCheck(), ChatHandler::SendNotification(), and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleRaidTargetUpdateOpcode()

void WorldSession::HandleRaidTargetUpdateOpcode ( WorldPacket recvData)

error handling

553{
554 Group* group = GetPlayer()->GetGroup();
555 if (!group)
556 return;
557
558 uint8 x;
559 recvData >> x;
560
562 /********************/
563
564 // everything's fine, do it
565 if (x == 0xFF) // target icon request
566 {
567 group->SendTargetIconList(this);
568 }
569 else // target icon update
570 {
571 if (group->isRaidGroup() && !group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
572 return;
573
574 ObjectGuid guid;
575 recvData >> guid;
576
577 if (guid.IsPlayer())
578 {
580
581 if (!target || target->IsHostileTo(GetPlayer()))
582 return;
583 }
584
585 group->SetTargetIcon(x, _player->GetGUID(), guid);
586 }
587}
void SendTargetIconList(WorldSession *session)
Definition Group.cpp:1645
void SetTargetIcon(uint8 id, ObjectGuid whoGuid, ObjectGuid targetGuid)
Definition Group.cpp:1624

References _player, ObjectAccessor::FindConnectedPlayer(), Player::GetGroup(), Object::GetGUID(), GetPlayer(), Group::IsAssistant(), Unit::IsHostileTo(), Group::IsLeader(), ObjectGuid::IsPlayer(), Group::isRaidGroup(), Group::SendTargetIconList(), and Group::SetTargetIcon().

Referenced by OpcodeTable::Initialize().

◆ HandleRandomRollOpcode()

void WorldSession::HandleRandomRollOpcode ( WorldPackets::Misc::RandomRollClient packet)

error handling

540{
541 uint32 minimum, maximum;
542 minimum = packet.Min;
543 maximum = packet.Max;
544
546 if (minimum > maximum || maximum > sWorld->getIntConfig(CONFIG_RANDOM_ROLL_MAXIMUM))
547 return;
548
549 GetPlayer()->DoRandomRoll(minimum, maximum);
550}
@ CONFIG_RANDOM_ROLL_MAXIMUM
Definition WorldConfig.h:134
uint32 DoRandomRoll(uint32 minimum, uint32 maximum)
Definition Player.cpp:16184
uint32 Min
Definition MiscPackets.h:126
uint32 Max
Definition MiscPackets.h:127

References CONFIG_RANDOM_ROLL_MAXIMUM, Player::DoRandomRoll(), GetPlayer(), WorldPackets::Misc::RandomRollClient::Max, WorldPackets::Misc::RandomRollClient::Min, and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleReadItem()

void WorldSession::HandleReadItem ( WorldPackets::Item::ReadItem packet)
549{
550 //LOG_DEBUG("network.opcode", "WORLD: CMSG_READ_ITEM");
551
552 //LOG_DEBUG("network.opcode", "STORAGE: Read bag = {}, slot = {}", bag, slot);
553 Item* pItem = _player->GetItemByPos(packet.Bag, packet.Slot);
554
555 if (pItem && pItem->GetTemplate()->PageText)
556 {
557 WorldPacket data;
558
559 InventoryResult msg = _player->CanUseItem(pItem);
560 if (msg == EQUIP_ERR_OK)
561 {
563 LOG_DEBUG("network.opcode", "STORAGE: Item page sent");
564 }
565 else
566 {
568 LOG_DEBUG("network.opcode", "STORAGE: Unable to read item");
569 _player->SendEquipError(msg, pItem, nullptr);
570 }
571 data << pItem->GetGUID();
572 SendPacket(&data);
573 }
574 else
576}
InventoryResult CanUseItem(Item *pItem, bool not_loading=true) const
Definition PlayerStorage.cpp:2226
uint8 Bag
Definition ItemPackets.h:111
uint8 Slot
Definition ItemPackets.h:112
@ SMSG_READ_ITEM_FAILED
Definition Opcodes.h:205
@ SMSG_READ_ITEM_OK
Definition Opcodes.h:204

References _player, WorldPackets::Item::ReadItem::Bag, Player::CanUseItem(), EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_OK, Object::GetGUID(), Player::GetItemByPos(), Item::GetTemplate(), WorldPacket::Initialize(), LOG_DEBUG, ItemTemplate::PageText, Player::SendEquipError(), SendPacket(), WorldPackets::Item::ReadItem::Slot, SMSG_READ_ITEM_FAILED, and SMSG_READ_ITEM_OK.

Referenced by OpcodeTable::Initialize().

◆ HandleReadyForAccountDataTimes()

void WorldSession::HandleReadyForAccountDataTimes ( WorldPacket recvData)
1612{
1613 // empty opcode
1614 LOG_DEBUG("network", "WORLD: CMSG_READY_FOR_ACCOUNT_DATA_TIMES");
1615
1617}
#define GLOBAL_CACHE_MASK
Definition WorldSession.h:217

References GLOBAL_CACHE_MASK, LOG_DEBUG, and SendAccountDataTimes().

Referenced by OpcodeTable::Initialize().

◆ HandleRealmSplitOpcode()

void WorldSession::HandleRealmSplitOpcode ( WorldPacket recvData)
1157{
1158 LOG_DEBUG("network", "CMSG_REALM_SPLIT");
1159
1160 uint32 unk;
1161 std::string split_date = "01/01/01";
1162 recv_data >> unk;
1163
1164 WorldPacket data(SMSG_REALM_SPLIT, 4 + 4 + split_date.size() + 1);
1165 data << unk;
1166 data << uint32(0x00000000); // realm split state
1167 // split states:
1168 // 0x0 realm normal
1169 // 0x1 realm split
1170 // 0x2 realm split pending
1171 data << split_date;
1172 SendPacket(&data);
1173}
@ SMSG_REALM_SPLIT
Definition Opcodes.h:937

References LOG_DEBUG, SendPacket(), and SMSG_REALM_SPLIT.

Referenced by OpcodeTable::Initialize().

◆ HandleReclaimCorpseOpcode()

void WorldSession::HandleReclaimCorpseOpcode ( WorldPacket recvPacket)
636{
637 ObjectGuid guid;
638 recv_data >> guid;
639
640 if (_player->IsAlive())
641 return;
642
643 // do not allow corpse reclaim in arena
644 if (_player->InArena())
645 return;
646
647 // body not released yet
649 return;
650
651 Corpse* corpse = _player->GetCorpse();
652 if (!corpse)
653 return;
654
655 // prevent resurrect before 30-sec delay after body release not finished
656 if (time_t(corpse->GetGhostTime() + _player->GetCorpseReclaimDelay(corpse->GetType() == CORPSE_RESURRECTABLE_PVP)) > time_t(GameTime::GetGameTime().count()))
657 return;
658
659 // skip phase check
660 if (!corpse->IsInMap(_player) || !corpse->IsWithinDist(_player, CORPSE_RECLAIM_RADIUS, true))
661 return;
662
663 // resurrect
665
666 // spawn bones
668}
#define CORPSE_RECLAIM_RADIUS
Definition Corpse.h:35
@ CORPSE_RESURRECTABLE_PVP
Definition Corpse.h:30
time_t const & GetGhostTime() const
Definition Corpse.h:70
Corpse * GetCorpse() const
Definition Player.cpp:4697
uint32 GetCorpseReclaimDelay(bool pvp) const
Definition Player.cpp:12958
bool InArena() const
Definition Player.cpp:12339
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1342

References _player, CORPSE_RECLAIM_RADIUS, CORPSE_RESURRECTABLE_PVP, Player::GetCorpse(), Player::GetCorpseReclaimDelay(), GameTime::GetGameTime(), Corpse::GetGhostTime(), Corpse::GetType(), Player::HasPlayerFlag(), Player::InArena(), Player::InBattleground(), Unit::IsAlive(), WorldObject::IsInMap(), WorldObject::IsWithinDist(), PLAYER_FLAGS_GHOST, Player::ResurrectPlayer(), and Player::SpawnCorpseBones().

Referenced by OpcodeTable::Initialize().

◆ HandleRemoveGlyph()

void WorldSession::HandleRemoveGlyph ( WorldPacket recvData)
1580{
1581 uint32 slot;
1582 recvData >> slot;
1583
1584 if (slot >= MAX_GLYPH_SLOT_INDEX)
1585 {
1586 LOG_DEBUG("network", "Client sent wrong glyph slot number in opcode CMSG_REMOVE_GLYPH {}", slot);
1587 return;
1588 }
1589
1590 if (uint32 glyph = _player->GetGlyph(slot))
1591 {
1592 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
1593 {
1594 _player->RemoveAurasDueToSpell(glyphEntry->SpellId);
1595
1596 // Removed any triggered auras
1597 Unit::AuraMap& ownedAuras = _player->GetOwnedAuras();
1598 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
1599 {
1600 Aura* aura = iter->second;
1601 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
1602 {
1603 if (triggeredByAuraSpellInfo->Id == glyphEntry->SpellId)
1604 {
1605 _player->RemoveOwnedAura(iter);
1606 continue;
1607 }
1608 }
1609 ++iter;
1610 }
1611
1612 _player->SendLearnPacket(glyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
1613 _player->SetGlyph(slot, 0, true);
1615 }
1616 }
1617}
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
#define MAX_GLYPH_SLOT_INDEX
Definition SharedDefines.h:687
SpellInfo const * GetTriggeredByAuraSpellInfo() const
Definition SpellAuras.cpp:2685
void SendLearnPacket(uint32 spellId, bool learn)
Definition Player.cpp:3027
uint32 GetGlyph(uint8 slot) const
Definition Player.h:1762
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition Player.h:1754
std::multimap< uint32, Aura * > AuraMap
Definition Unit.h:660
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:5028
AuraMap & GetOwnedAuras()
Definition Unit.h:1358
Definition DBCStructure.h:1022

References _player, Player::GetGlyph(), Unit::GetOwnedAuras(), Aura::GetTriggeredByAuraSpellInfo(), LOG_DEBUG, MAX_GLYPH_SLOT_INDEX, Unit::RemoveAurasDueToSpell(), Unit::RemoveOwnedAura(), Player::SendLearnPacket(), Player::SendTalentsInfoData(), Player::SetGlyph(), and sGlyphPropertiesStore.

Referenced by OpcodeTable::Initialize().

◆ HandleRepairItemOpcode()

void WorldSession::HandleRepairItemOpcode ( WorldPacket recvPacket)
885{
886 LOG_DEBUG("network", "WORLD: CMSG_REPAIR_ITEM");
887
888 ObjectGuid npcGUID, itemGUID;
889 uint8 guildBank; // new in 2.3.2, bool that means from guild bank money
890
891 recvData >> npcGUID >> itemGUID >> guildBank;
892
894 if (!unit)
895 {
896 LOG_DEBUG("network", "WORLD: HandleRepairItemOpcode - Unit ({}) not found or you can not interact with him.", npcGUID.ToString());
897 return;
898 }
899
900 // remove fake death
901 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
903
904 // reputation discount
905 float discountMod = _player->GetReputationPriceDiscount(unit);
906
907 sScriptMgr->OnPlayerBeforeDurabilityRepair(_player, npcGUID, itemGUID, discountMod, guildBank);
908
909 if (itemGUID)
910 {
911 LOG_DEBUG("network", "ITEM: Repair item, item {}, npc {}", itemGUID.ToString(), npcGUID.ToString());
912
913 Item* item = _player->GetItemByGuid(itemGUID);
914 if (item)
915 _player->DurabilityRepair(item->GetPos(), true, discountMod, guildBank);
916 }
917 else
918 {
919 LOG_DEBUG("network", "ITEM: Repair all items, npc {}", npcGUID.ToString());
920 _player->DurabilityRepairAll(true, discountMod, guildBank);
921 }
922}
@ UNIT_NPC_FLAG_REPAIR
Definition UnitDefines.h:331
float GetReputationPriceDiscount(Creature const *creature) const
Definition Player.cpp:12378
uint32 DurabilityRepairAll(bool cost, float discountMod, bool guildBank)
Definition Player.cpp:4813
uint32 DurabilityRepair(uint16 pos, bool cost, float discountMod, bool guildBank)
Definition Player.cpp:4829

References _player, Player::DurabilityRepair(), Player::DurabilityRepairAll(), Player::GetItemByGuid(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Item::GetPos(), Player::GetReputationPriceDiscount(), LOG_DEBUG, Unit::RemoveAurasByType(), SPELL_AURA_FEIGN_DEATH, sScriptMgr, ObjectGuid::ToString(), UNIT_NPC_FLAG_REPAIR, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleRepopRequestOpcode()

void WorldSession::HandleRepopRequestOpcode ( WorldPacket recvPacket)
58{
59 LOG_DEBUG("network", "WORLD: Recvd CMSG_REPOP_REQUEST Message");
60
61 recv_data.read_skip<uint8>();
62
64 return;
65
67 return; // silently return, client should display the error by itself
68
69 // the world update order is sessions, players, creatures
70 // the netcode runs in parallel with all of these
71 // creatures can kill players
72 // so if the server is lagging enough the player can
73 // release spirit after he's killed but before he is updated
75 {
76 LOG_DEBUG("network", "HandleRepopRequestOpcode: got request after player {} ({}) was killed and before he was updated",
77 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
79 }
80
81 //this is spirit release confirm?
82 GetPlayer()->RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT, true);
85}
@ PET_SAVE_NOT_IN_SLOT
Definition PetDefines.h:46
void KillPlayer()
Definition Player.cpp:4541
DeathState getDeathState()
Definition Unit.h:1770
bool HasPreventResurectionAura() const
Definition Unit.h:1787

References Player::BuildPlayerRepop(), Unit::getDeathState(), GetPlayer(), Player::HasPlayerFlag(), Unit::HasPreventResurectionAura(), Unit::IsAlive(), JustDied, Player::KillPlayer(), LOG_DEBUG, PET_SAVE_NOT_IN_SLOT, PLAYER_FLAGS_GHOST, ByteBuffer::read_skip(), Player::RemovePet(), and Player::RepopAtGraveyard().

Referenced by OpcodeTable::Initialize().

◆ HandleReportLag()

void WorldSession::HandleReportLag ( WorldPacket recvPacket)
257{
258 // just put the lag report into the database...
259 // can't think of anything else to do with it
260 uint32 lagType, mapId;
261 recv_data >> lagType;
262 recv_data >> mapId;
263 float x, y, z;
264 recv_data >> x;
265 recv_data >> y;
266 recv_data >> z;
267
269 stmt->SetData(0, GetPlayer()->GetGUID().GetCounter());
270 stmt->SetData (1, lagType);
271 stmt->SetData(2, mapId);
272 stmt->SetData (3, x);
273 stmt->SetData (4, y);
274 stmt->SetData (5, z);
275 stmt->SetData(6, GetLatency());
276 stmt->SetData(7, GameTime::GetGameTime().count());
277 CharacterDatabase.Execute(stmt);
278}
@ CHAR_INS_LAG_REPORT
Definition CharacterDatabase.h:271
uint32 GetLatency() const
Definition WorldSession.h:564

References CHAR_INS_LAG_REPORT, CharacterDatabase, GameTime::GetGameTime(), GetLatency(), GetPlayer(), and PreparedStatementBase::SetData().

Referenced by OpcodeTable::Initialize().

◆ HandleReportPvPAFK()

void WorldSession::HandleReportPvPAFK ( WorldPacket recvData)
905{
906 ObjectGuid playerGuid;
907 recvData >> playerGuid;
908 Player* reportedPlayer = ObjectAccessor::FindPlayer(playerGuid);
909
910 if (!reportedPlayer)
911 {
912 LOG_DEBUG("bg.battleground", "WorldSession::HandleReportPvPAFK: player not found");
913 return;
914 }
915
916 LOG_DEBUG("bg.battleground", "WorldSession::HandleReportPvPAFK: {} reported {}", _player->GetName(), reportedPlayer->GetName());
917
918 reportedPlayer->ReportedAfkBy(_player);
919}
void ReportedAfkBy(Player *reporter)
This player has been blamed to be inactive in a battleground.
Definition Player.cpp:11401

References _player, ObjectAccessor::FindPlayer(), WorldObject::GetName(), LOG_DEBUG, and Player::ReportedAfkBy().

Referenced by OpcodeTable::Initialize().

◆ HandleRequestAccountData()

void WorldSession::HandleRequestAccountData ( WorldPacket recvPacket)
865{
866 uint32 type;
867 recv_data >> type;
868
869 LOG_DEBUG("network", "RAD: type {}", type);
870
871 if (type >= NUM_ACCOUNT_DATA_TYPES)
872 return;
873
875
876 uint32 size = adata->Data.size();
877
878 uLongf destSize = compressBound(size);
879
880 ByteBuffer dest;
881 dest.resize(destSize);
882
883 if (size && compress(dest.contents(), &destSize, (uint8 const*)adata->Data.c_str(), size) != Z_OK)
884 {
885 LOG_DEBUG("network", "RAD: Failed to compress account data");
886 return;
887 }
888
889 dest.resize(destSize);
890
891 WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA, 8 + 4 + 4 + 4 + destSize);
892 data << (_player ? _player->GetGUID() : ObjectGuid::Empty); // player guid
893 data << uint32(type); // type (0-7)
894 data << uint32(adata->Time); // unix time
895 data << uint32(size); // decompressed length
896 data.append(dest); // compressed data
897 SendPacket(&data);
898}
AccountData * GetAccountData(AccountDataType type)
Definition WorldSession.h:512
AccountDataType
Definition WorldSession.h:204
#define NUM_ACCOUNT_DATA_TYPES
Definition WorldSession.h:215
@ SMSG_UPDATE_ACCOUNT_DATA
Definition Opcodes.h:554
Definition WorldSession.h:221
time_t Time
Definition WorldSession.h:224
std::string Data
Definition WorldSession.h:225

References _player, ByteBuffer::append(), ByteBuffer::contents(), AccountData::Data, ObjectGuid::Empty, GetAccountData(), Object::GetGUID(), LOG_DEBUG, NUM_ACCOUNT_DATA_TYPES, ByteBuffer::resize(), SendPacket(), SMSG_UPDATE_ACCOUNT_DATA, and AccountData::Time.

Referenced by OpcodeTable::Initialize().

◆ HandleRequestPartyMemberStatsOpcode()

void WorldSession::HandleRequestPartyMemberStatsOpcode ( WorldPacket recvData)
946{
947 ObjectGuid Guid;
948 recvData >> Guid;
949
950 Player* player = HashMapHolder<Player>::Find(Guid);
951 if (!player || !player->IsInSameRaidWith(_player))
952 {
954 data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
955 data << Guid.WriteAsPacked();
958 SendPacket(&data);
959 return;
960 }
961
962 Pet* pet = player->GetPet();
963 Powers powerType = player->getPowerType();
964
965 WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4 + 2 + 2 + 2 + 1 + 2 * 6 + 8 + 1 + 8);
966 data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
967 data << player->GetPackGUID();
968
973
974 if (powerType != POWER_MANA)
975 updateFlags |= GROUP_UPDATE_FLAG_POWER_TYPE;
976
977 if (pet)
980
981 if (player->GetVehicle())
982 updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT;
983
984 uint16 playerStatus = MEMBER_STATUS_ONLINE;
985 if (player->IsPvP())
986 playerStatus |= MEMBER_STATUS_PVP;
987
988 if (!player->IsAlive())
989 {
991 playerStatus |= MEMBER_STATUS_GHOST;
992 else
993 playerStatus |= MEMBER_STATUS_DEAD;
994 }
995
996 if (player->IsFFAPvP())
997 playerStatus |= MEMBER_STATUS_PVP_FFA;
998
999 if (player->isAFK())
1000 playerStatus |= MEMBER_STATUS_AFK;
1001
1002 if (player->isDND())
1003 playerStatus |= MEMBER_STATUS_DND;
1004
1005 data << uint32(updateFlags);
1006 data << uint16(playerStatus); // GROUP_UPDATE_FLAG_STATUS
1007 data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP
1008 data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP
1009 if (updateFlags & GROUP_UPDATE_FLAG_POWER_TYPE)
1010 data << uint8(powerType);
1011
1012 data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER
1013 data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER
1014 data << uint16(player->GetLevel()); // GROUP_UPDATE_FLAG_LEVEL
1015 data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE
1016 data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION
1017 data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION
1018
1019 uint64 auraMask = 0;
1020 std::size_t maskPos = data.wpos();
1021 data << uint64(auraMask); // placeholder
1022 for (uint8 i = 0; i < MAX_AURAS_GROUP_UPDATE; ++i)
1023 {
1024 if (AuraApplication const* aurApp = player->GetVisibleAura(i))
1025 {
1026 auraMask |= uint64(1) << i;
1027 data << uint32(aurApp->GetBase()->GetId());
1028 data << uint8(aurApp->GetFlags());
1029 }
1030 }
1031
1032 data.put<uint64>(maskPos, auraMask); // GROUP_UPDATE_FLAG_AURAS
1033
1034 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_GUID))
1035 data << pet->GetGUID();
1036
1037 data << std::string(pet ? pet->GetName() : ""); // GROUP_UPDATE_FLAG_PET_NAME
1038 data << uint16(pet ? pet->GetDisplayId() : 0); // GROUP_UPDATE_FLAG_PET_MODEL_ID
1039
1040 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_HP))
1041 data << uint32(pet->GetHealth());
1042
1043 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_HP))
1044 data << uint32(pet->GetMaxHealth());
1045
1046 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_POWER_TYPE))
1047 data << (uint8)pet->getPowerType();
1048
1049 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_POWER))
1050 data << uint16(pet->GetPower(pet->getPowerType()));
1051
1052 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_POWER))
1053 data << uint16(pet->GetMaxPower(pet->getPowerType()));
1054
1055 uint64 petAuraMask = 0;
1056 maskPos = data.wpos();
1057 data << uint64(petAuraMask); // placeholder
1058 if (pet)
1059 {
1060 for (uint8 i = 0; i < MAX_AURAS_GROUP_UPDATE; ++i)
1061 {
1062 if (AuraApplication const* aurApp = pet->GetVisibleAura(i))
1063 {
1064 petAuraMask |= uint64(1) << i;
1065 data << uint32(aurApp->GetBase()->GetId());
1066 data << uint8(aurApp->GetFlags());
1067 }
1068 }
1069 }
1070
1071 data.put<uint64>(maskPos, petAuraMask); // GROUP_UPDATE_FLAG_PET_AURAS
1072
1073 if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
1074 data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]);
1075
1076 SendPacket(&data);
1077}
@ MEMBER_STATUS_OFFLINE
Definition Group.h:60
@ POWER_MANA
Definition SharedDefines.h:280
static T * Find(ObjectGuid guid)
Definition ObjectAccessor.cpp:53
VehicleEntry const * GetVehicleInfo() const
Definition Vehicle.h:38
@ SMSG_PARTY_MEMBER_STATS_FULL
Definition Opcodes.h:784
uint32 m_seatID[MAX_VEHICLE_SEATS]
Definition DBCStructure.h:2032

References _player, HashMapHolder< T >::Find(), Unit::GetDisplayId(), Object::GetGUID(), Unit::GetHealth(), Unit::GetLevel(), Unit::GetMaxHealth(), Unit::GetMaxPower(), WorldObject::GetName(), Object::GetPackGUID(), Player::GetPet(), Position::GetPositionX(), Position::GetPositionY(), Unit::GetPower(), Unit::getPowerType(), Unit::GetVehicle(), Vehicle::GetVehicleInfo(), Unit::GetVisibleAura(), WorldObject::GetZoneId(), GROUP_UPDATE_FLAG_AURAS, GROUP_UPDATE_FLAG_CUR_HP, GROUP_UPDATE_FLAG_CUR_POWER, GROUP_UPDATE_FLAG_LEVEL, GROUP_UPDATE_FLAG_MAX_HP, GROUP_UPDATE_FLAG_MAX_POWER, GROUP_UPDATE_FLAG_PET_AURAS, GROUP_UPDATE_FLAG_PET_CUR_HP, GROUP_UPDATE_FLAG_PET_CUR_POWER, GROUP_UPDATE_FLAG_PET_GUID, GROUP_UPDATE_FLAG_PET_MAX_HP, GROUP_UPDATE_FLAG_PET_MAX_POWER, GROUP_UPDATE_FLAG_PET_MODEL_ID, GROUP_UPDATE_FLAG_PET_NAME, GROUP_UPDATE_FLAG_PET_POWER_TYPE, GROUP_UPDATE_FLAG_POSITION, GROUP_UPDATE_FLAG_POWER_TYPE, GROUP_UPDATE_FLAG_STATUS, GROUP_UPDATE_FLAG_VEHICLE_SEAT, GROUP_UPDATE_FLAG_ZONE, Player::HasPlayerFlag(), Player::isAFK(), Unit::IsAlive(), Player::isDND(), Player::IsFFAPvP(), Player::IsInSameRaidWith(), Player::IsPvP(), WorldObject::m_movementInfo, VehicleEntry::m_seatID, MAX_AURAS_GROUP_UPDATE, MEMBER_STATUS_AFK, MEMBER_STATUS_DEAD, MEMBER_STATUS_DND, MEMBER_STATUS_GHOST, MEMBER_STATUS_OFFLINE, MEMBER_STATUS_ONLINE, MEMBER_STATUS_PVP, MEMBER_STATUS_PVP_FFA, PLAYER_FLAGS_GHOST, POWER_MANA, ByteBuffer::put(), MovementInfo::TransportInfo::seat, SendPacket(), SMSG_PARTY_MEMBER_STATS_FULL, MovementInfo::transport, ByteBuffer::wpos(), and ObjectGuid::WriteAsPacked().

Referenced by OpcodeTable::Initialize().

◆ HandleRequestPetInfo()

void WorldSession::HandleRequestPetInfo ( WorldPackets::Pet::RequestPetInfo packet)
1555{
1556 /*
1557 LOG_DEBUG("network.opcode", "WORLD: CMSG_REQUEST_PET_INFO");
1558 recv_data.hexlike();
1559 */
1560
1561 if (_player->GetPet())
1563 else if (_player->GetCharm())
1565}
void CharmSpellInitialize()
Definition Player.cpp:9731

References _player, Player::CharmSpellInitialize(), Unit::GetCharm(), Player::GetPet(), and Player::PetSpellInitialize().

Referenced by OpcodeTable::Initialize().

◆ HandleRequestRaidInfoOpcode()

void WorldSession::HandleRequestRaidInfoOpcode ( WorldPacket recvData)
1080{
1081 // every time the player checks the character screen
1083}
void SendRaidInfo()
Definition PlayerStorage.cpp:6524

References _player, and Player::SendRaidInfo().

Referenced by OpcodeTable::Initialize().

◆ HandleRequestVehicleExit()

void WorldSession::HandleRequestVehicleExit ( WorldPacket recvData)
230{
231 LOG_DEBUG("network", "WORLD: Recvd CMSG_REQUEST_VEHICLE_EXIT");
232
233 if (Vehicle* vehicle = GetPlayer()->GetVehicle())
234 {
235 if (VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(GetPlayer()))
236 {
237 if (seat->CanEnterOrExit())
239 else
240 LOG_ERROR("network.opcode", "Player {} tried to exit vehicle, but seatflags {} (ID: {}) don't permit that.",
241 GetPlayer()->GetGUID().ToString(), seat->m_ID, seat->m_flags);
242 }
243 }
244}

References Unit::ExitVehicle(), GetPlayer(), LOG_DEBUG, and LOG_ERROR.

Referenced by OpcodeTable::Initialize().

◆ HandleResetInstancesOpcode()

void WorldSession::HandleResetInstancesOpcode ( WorldPacket recvData)
1244{
1245 LOG_DEBUG("network", "WORLD: CMSG_RESET_INSTANCES");
1246
1247 if (Group* group = _player->GetGroup())
1248 {
1249 if (group->IsLeader(_player->GetGUID()))
1250 group->ResetInstances(INSTANCE_RESET_ALL, false, _player);
1251 }
1252 else
1254}
@ INSTANCE_RESET_ALL
Definition Map.h:638
static void ResetInstances(ObjectGuid guid, uint8 method, bool isRaid)
Reset all solo instances and optionally send a message on success for each.
Definition PlayerMisc.cpp:195

References _player, Player::GetGroup(), Object::GetGUID(), INSTANCE_RESET_ALL, LOG_DEBUG, and Player::ResetInstances().

Referenced by OpcodeTable::Initialize().

◆ HandleResurrectResponseOpcode()

void WorldSession::HandleResurrectResponseOpcode ( WorldPacket recvPacket)
671{
672 ObjectGuid guid;
673 uint8 status;
674 recv_data >> guid;
675 recv_data >> status;
676
677 // Xinef: Prevent resurrect with prevent resurrection aura
678 if (GetPlayer()->IsAlive() || GetPlayer()->HasPreventResurectionAura())
679 return;
680
681 if (status == 0)
682 {
684 return;
685 }
686
687 if (!GetPlayer()->isResurrectRequestedBy(guid))
688 return;
689
691}
void ResurectUsingRequestData()
Definition Player.cpp:12864
void clearResurrectRequestData()
Definition Player.h:1821

References Player::clearResurrectRequestData(), GetPlayer(), and Player::ResurectUsingRequestData().

Referenced by OpcodeTable::Initialize().

◆ HandleSaveGuildEmblemOpcode()

void WorldSession::HandleSaveGuildEmblemOpcode ( WorldPackets::Guild::SaveGuildEmblem packet)
225{
226 EmblemInfo emblemInfo;
227 emblemInfo.ReadPacket(packet);
228
229 LOG_DEBUG("guild", "MSG_SAVE_GUILD_EMBLEM [{}]: Guid: [{}] Style: {}, Color: {}, BorderStyle: {}, BorderColor: {}, BackgroundColor: {}"
230 , GetPlayerInfo(), packet.Vendor.ToString(), emblemInfo.GetStyle()
231 , emblemInfo.GetColor(), emblemInfo.GetBorderStyle()
232 , emblemInfo.GetBorderColor(), emblemInfo.GetBackgroundColor());
233 if (GetPlayer()->GetNPCIfCanInteractWith(packet.Vendor, UNIT_NPC_FLAG_TABARDDESIGNER))
234 {
235 // Remove fake death
236 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
238
239 if (Guild* guild = GetPlayer()->GetGuild())
240 guild->HandleSetEmblem(this, emblemInfo);
241 else
242 Guild::SendSaveEmblemResult(this, ERR_GUILDEMBLEM_NOGUILD); // "You are not part of a guild!";
243 }
244 else
245 Guild::SendSaveEmblemResult(this, ERR_GUILDEMBLEM_INVALIDVENDOR); // "That's not an emblem vendor!"
246}
@ ERR_GUILDEMBLEM_INVALIDVENDOR
Definition Guild.h:225
@ ERR_GUILDEMBLEM_NOGUILD
Definition Guild.h:222
@ UNIT_NPC_FLAG_TABARDDESIGNER
Definition UnitDefines.h:338
Definition Guild.h:239
uint32 GetStyle() const
Definition Guild.h:247
uint32 GetColor() const
Definition Guild.h:248
uint32 GetBackgroundColor() const
Definition Guild.h:251
uint32 GetBorderStyle() const
Definition Guild.h:249
void ReadPacket(WorldPackets::Guild::SaveGuildEmblem &packet)
Definition Guild.cpp:683
uint32 GetBorderColor() const
Definition Guild.h:250
static void SendSaveEmblemResult(WorldSession *session, GuildEmblemError errCode)
Definition Guild.cpp:125
ObjectGuid Vendor
Definition GuildPackets.h:605

References ERR_GUILDEMBLEM_INVALIDVENDOR, ERR_GUILDEMBLEM_NOGUILD, EmblemInfo::GetBackgroundColor(), EmblemInfo::GetBorderColor(), EmblemInfo::GetBorderStyle(), EmblemInfo::GetColor(), GetPlayer(), GetPlayerInfo(), EmblemInfo::GetStyle(), LOG_DEBUG, EmblemInfo::ReadPacket(), Unit::RemoveAurasByType(), Guild::SendSaveEmblemResult(), SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_TABARDDESIGNER, UNIT_STATE_DIED, and WorldPackets::Guild::SaveGuildEmblem::Vendor.

Referenced by OpcodeTable::Initialize().

◆ HandleSelfResOpcode()

void WorldSession::HandleSelfResOpcode ( WorldPacket recvData)
704{
705 LOG_DEBUG("network", "WORLD: CMSG_SELF_RES"); // empty opcode
706
707 if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(_player->GetUInt32Value(PLAYER_SELF_RES_SPELL)))
708 {
710 {
711 return; // silent return, client should display error by itself and not send this opcode
712 }
713
714 _player->CastSpell(_player, spell->Id);
716 }
717}
@ SPELL_ATTR7_BYPASS_NO_RESURRECTION_AURA
Definition SharedDefines.h:679
@ PLAYER_SELF_RES_SPELL
Definition UpdateFields.h:370

References _player, Unit::CastSpell(), Object::GetUInt32Value(), Unit::HasPreventResurectionAura(), LOG_DEBUG, PLAYER_SELF_RES_SPELL, Unit::SetUInt32Value(), SPELL_ATTR7_BYPASS_NO_RESURRECTION_AURA, and sSpellMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleSellItemOpcode()

void WorldSession::HandleSellItemOpcode ( WorldPackets::Item::SellItem packet)
579{
580 if (!packet.ItemGuid)
581 return;
582
584 if (!creature)
585 {
586 LOG_DEBUG("network", "WORLD: HandleSellItemOpcode - Unit ({}) not found or you can not interact with him.", packet.VendorGuid.ToString());
588 return;
589 }
590
592 {
594 return;
595 }
596
597 // remove fake death
598 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
600
601 Item* pItem = _player->GetItemByGuid(packet.ItemGuid);
602 if (pItem)
603 {
604 if (!sScriptMgr->OnPlayerCanSellItem(_player, pItem, creature))
605 return;
606
607 // prevent sell not owner item
608 if (_player->GetGUID() != pItem->GetOwnerGUID())
609 {
611 return;
612 }
613
614 // prevent sell non empty bag by drag-and-drop at vendor's item list
615 if (pItem->IsNotEmptyBag())
616 {
618 return;
619 }
620
621 // prevent sell currently looted item
622 if (_player->GetLootGUID() == pItem->GetGUID())
623 {
625 return;
626 }
627
628 // prevent selling item for sellprice when the item is still refundable
629 // this probably happens when right clicking a refundable item, the client sends both
630 // CMSG_SELL_ITEM and CMSG_REFUND_ITEM (unverified)
631 if (pItem->IsRefundable())
632 return; // Therefore, no feedback to client
633
634 // special case at auto sell (sell all)
635 if (packet.Count == 0)
636 packet.Count = pItem->GetCount();
637 else
638 {
639 // prevent sell more items that exist in stack (possible only not from client)
640 if (packet.Count > pItem->GetCount())
641 {
643 return;
644 }
645 }
646
647 ItemTemplate const* pProto = pItem->GetTemplate();
648 if (pProto)
649 {
650 if (pProto->SellPrice > 0)
651 {
652 uint32 money = pProto->SellPrice * packet.Count;
653 if (_player->GetMoney() >= MAX_MONEY_AMOUNT - money) // prevent exceeding gold limit
654 {
656 _player->SendSellError(SELL_ERR_UNK, creature, packet.ItemGuid, 0);
657 return;
658 }
659
660 if (sWorld->getBoolConfig(CONFIG_ITEMDELETE_VENDOR))
661 recoveryItem(pItem);
662
663 uint32 maxDurability = pItem->GetUInt32Value(ITEM_FIELD_MAXDURABILITY);
664 if (maxDurability)
665 {
666 uint32 curDurability = pItem->GetUInt32Value(ITEM_FIELD_DURABILITY);
667 uint32 LostDurability = maxDurability - curDurability;
668
669 if (LostDurability > 0)
670 {
671 DurabilityCostsEntry const* dcost = sDurabilityCostsStore.LookupEntry(pProto->ItemLevel);
672 if (!dcost)
673 {
675 LOG_ERROR("network.opcode", "WORLD: HandleSellItemOpcode - Wrong item lvl {} for item {} count = {}", pProto->ItemLevel, pItem->GetEntry(), packet.Count);
676 return;
677 }
678
679 uint32 dQualitymodEntryId = (pProto->Quality + 1) * 2;
680 DurabilityQualityEntry const* dQualitymodEntry = sDurabilityQualityStore.LookupEntry(dQualitymodEntryId);
681 if (!dQualitymodEntry)
682 {
684 LOG_ERROR("network.opcode", "WORLD: HandleSellItemOpcode - Wrong dQualityModEntry {} for item {} count = {}", dQualitymodEntryId, pItem->GetEntry(), packet.Count);
685 return;
686 }
687
688 uint32 dmultiplier = dcost->multiplier[ItemSubClassToDurabilityMultiplierId(pProto->Class, pProto->SubClass)];
689 uint32 refund = uint32(std::ceil(LostDurability * dmultiplier * double(dQualitymodEntry->quality_mod)));
690
691 if (!refund)
692 refund = 1;
693
694 //starter items can cost more to refund than vendorprice
695 if (refund > money)
696 money = 1;
697 else
698 money -= refund;
699 }
700 }
701
702 if (packet.Count < pItem->GetCount()) // need split items
703 {
704 Item* pNewItem = pItem->CloneItem(packet.Count, _player);
705 if (!pNewItem)
706 {
707 LOG_ERROR("network.opcode", "WORLD: HandleSellItemOpcode - could not create clone of item {}; count = {}", pItem->GetEntry(), packet.Count);
709 return;
710 }
711
713
714 pItem->SetCount(pItem->GetCount() - packet.Count);
715 _player->ItemRemovedQuestCheck(pItem->GetEntry(), packet.Count);
716 if (_player->IsInWorld())
719
720 _player->AddItemToBuyBackSlot(pNewItem, money);
721 if (_player->IsInWorld())
722 pNewItem->SendUpdateToPlayer(_player);
723 }
724 else
725 {
726 _player->ItemRemovedQuestCheck(pItem->GetEntry(), pItem->GetCount());
727 _player->RemoveItem(pItem->GetBagSlot(), pItem->GetSlot(), true);
729 _player->AddItemToBuyBackSlot(pItem, money);
731 }
732
733 _player->ModifyMoney(money);
735 }
736 else
738 return;
739 }
740 }
742 return;
743}
@ CREATURE_FLAG_EXTRA_NO_SELL_VENDOR
Definition CreatureData.h:57
@ ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS
Definition DBCEnums.h:172
DBCStorage< DurabilityQualityEntry > sDurabilityQualityStore(DurabilityQualityfmt)
DBCStorage< DurabilityCostsEntry > sDurabilityCostsStore(DurabilityCostsfmt)
uint8 ItemSubClassToDurabilityMultiplierId(uint32 ItemClass, uint32 ItemSubClass)
Definition ItemTemplate.h:557
@ SELL_ERR_UNK
Definition Item.h:159
@ SELL_ERR_CANT_SELL_TO_THIS_MERCHANT
Definition Item.h:161
@ SELL_ERR_CANT_FIND_ITEM
Definition Item.h:155
@ SELL_ERR_CANT_SELL_ITEM
Definition Item.h:156
bool HasFlagsExtra(uint32 flag) const
Definition Creature.h:77
void RemoveFromUpdateQueueOf(Player *player)
Definition Item.cpp:764
ObjectGuid GetOwnerGUID() const
Definition Item.h:231
bool IsRefundable() const
Definition Item.h:261
void AddItemToBuyBackSlot(Item *pItem, uint32 money)
Definition PlayerStorage.cpp:3938
uint32 Count
Definition ItemPackets.h:124
ObjectGuid VendorGuid
Definition ItemPackets.h:122
ObjectGuid ItemGuid
Definition ItemPackets.h:123
Definition DBCStructure.h:878
uint32 multiplier[29]
Definition DBCStructure.h:880
Definition DBCStructure.h:884
float quality_mod
Definition DBCStructure.h:886

References _player, ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS, Player::AddItemToBuyBackSlot(), ItemTemplate::Class, Item::CloneItem(), CONFIG_ITEMDELETE_VENDOR, WorldPackets::Item::SellItem::Count, CREATURE_FLAG_EXTRA_NO_SELL_VENDOR, EQUIP_ERR_TOO_MUCH_GOLD, Item::GetBagSlot(), Item::GetCount(), Object::GetEntry(), Object::GetGUID(), Player::GetItemByGuid(), Player::GetLootGUID(), Player::GetMoney(), Player::GetNPCIfCanInteractWith(), Item::GetOwnerGUID(), GetPlayer(), Item::GetSlot(), Item::GetTemplate(), Object::GetUInt32Value(), Creature::HasFlagsExtra(), Object::IsInWorld(), Item::IsNotEmptyBag(), Item::IsRefundable(), ITEM_CHANGED, ITEM_FIELD_DURABILITY, ITEM_FIELD_MAXDURABILITY, WorldPackets::Item::SellItem::ItemGuid, ItemTemplate::ItemLevel, Player::ItemRemovedQuestCheck(), ItemSubClassToDurabilityMultiplierId(), LOG_DEBUG, LOG_ERROR, MAX_MONEY_AMOUNT, Player::ModifyMoney(), DurabilityCostsEntry::multiplier, ItemTemplate::Quality, DurabilityQualityEntry::quality_mod, recoveryItem(), Unit::RemoveAurasByType(), Item::RemoveFromUpdateQueueOf(), Player::RemoveItem(), sDurabilityCostsStore, sDurabilityQualityStore, SELL_ERR_CANT_FIND_ITEM, SELL_ERR_CANT_FIND_VENDOR, SELL_ERR_CANT_SELL_ITEM, SELL_ERR_CANT_SELL_TO_THIS_MERCHANT, SELL_ERR_UNK, ItemTemplate::SellPrice, Player::SendEquipError(), Player::SendSellError(), Object::SendUpdateToPlayer(), Item::SetCount(), Item::SetState(), Object::SetUInt32Value(), SPELL_AURA_FEIGN_DEATH, sScriptMgr, ItemTemplate::SubClass, sWorld, ObjectGuid::ToString(), UNIT_NPC_FLAG_VENDOR, UNIT_STATE_DIED, Player::UpdateAchievementCriteria(), Player::UpdateTitansGrip(), and WorldPackets::Item::SellItem::VendorGuid.

Referenced by OpcodeTable::Initialize().

◆ HandleSendMail()

void WorldSession::HandleSendMail ( WorldPacket recvData)

accountBound

64{
65 ObjectGuid mailbox;
66 uint64 unk3;
67 std::string receiver, subject, body;
68 uint32 unk1, unk2, money, COD;
69 uint8 unk4;
70
71 recvData >> mailbox;
72 recvData >> receiver;
73
74 recvData >> subject;
75
76 // prevent client crash
77 if (subject.find("| |") != std::string::npos || body.find("| |") != std::string::npos)
78 {
79 return;
80 }
81
82 recvData >> body;
83
84 recvData >> unk1; // stationery?
85 recvData >> unk2; // 0x00000000
86
87 uint8 items_count;
88 recvData >> items_count; // attached items count
89
90 if (items_count > MAX_MAIL_ITEMS) // client limit
91 {
93 recvData.rfinish(); // set to end to avoid warnings spam
94 return;
95 }
96
97 ObjectGuid itemGUIDs[MAX_MAIL_ITEMS];
98
99 for (uint8 i = 0; i < items_count; ++i)
100 {
101 recvData.read_skip<uint8>(); // item slot in mail, not used
102 recvData >> itemGUIDs[i];
103 }
104
105 recvData >> money >> COD; // money and cod
106 recvData >> unk3; // const 0
107 recvData >> unk4; // const 0
108
109 // packet read complete, now do check
110
111 if (!CanOpenMailBox(mailbox))
112 return;
113
114 if (receiver.empty())
115 return;
116
117 Player* player = _player;
118
119 if (player->GetLevel() < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ))
120 {
122 return;
123 }
124
125 ObjectGuid receiverGuid;
126 if (normalizePlayerName(receiver))
127 {
128 receiverGuid = sCharacterCache->GetCharacterGuidByName(receiver);
129 }
130
131 if (!receiverGuid)
132 {
133 LOG_DEBUG("network.opcode", "Player {} is sending mail to {} (GUID: not existed!) with subject {} and body {} includes {} items, {} copper and {} COD copper with unk1 = {}, unk2 = {}",
134 player->GetGUID().ToString(), receiver, subject, body, items_count, money, COD, unk1, unk2);
136 return;
137 }
138
139 LOG_DEBUG("network.opcode", "Player {} is sending mail to {} ({}) with subject {} and body {} includes {} items, {} copper and {} COD copper with unk1 = {}, unk2 = {}",
140 player->GetGUID().ToString(), receiver, receiverGuid.ToString(), subject, body, items_count, money, COD, unk1, unk2);
141
142 if (player->GetGUID() == receiverGuid)
143 {
145 return;
146 }
147
148 if (money && COD) // cannot send money in a COD mail
149 {
150 LOG_ERROR("network.opcode", "{} attempt to dupe money!!!.", receiver);
152 return;
153 }
154
155 uint32 cost = items_count ? 30 * items_count : 30; // price hardcoded in client
156
157 uint32 reqmoney = cost + money;
158
159 // Check for overflow
160 if (reqmoney < money)
161 {
163 return;
164 }
165
166 if (!player->HasEnoughMoney(reqmoney))
167 {
169 return;
170 }
171
172 Player* receive = ObjectAccessor::FindConnectedPlayer(receiverGuid);
173
174 uint32 rc_teamId = TEAM_NEUTRAL;
175 uint16 mails_count = 0; //do not allow to send to one player more than 100 mails
176
177 if (receive)
178 {
179 rc_teamId = receive->GetTeamId();
180 mails_count = receive->GetMailSize();
181 }
182 else
183 {
184 // xinef: get data from global storage
185 if (CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(receiverGuid))
186 {
187 rc_teamId = Player::TeamIdForRace(playerData->Race);
188 mails_count = playerData->MailCount;
189 }
190 }
191 //do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255..
192 if (mails_count > 100)
193 {
195 return;
196 }
197 // test the receiver's Faction... or all items are account bound
198 // Xinef: check for boa items, not used currently
199 /*bool accountBound = items_count && !money && !COD ? true : false;
200 for (uint8 i = 0; i < items_count; ++i)
201 {
202 Item* item = player->GetItemByGuid(itemGUIDs[i]);
203 if (item)
204 {
205 ItemTemplate const* itemProto = item->GetTemplate();
206 if (!itemProto || !itemProto->HasFlag(ITEM_FLAG_IS_BOUND_TO_ACCOUNT))
207 {
208 accountBound = false;
209 break;
210 }
211 }
212 }*/
213
214 uint32 rc_account = receive ? receive->GetSession()->GetAccountId() : sCharacterCache->GetCharacterAccountIdByGuid(receiverGuid);
215
216 if ( GetAccountId() != rc_account && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) && player->GetTeamId() != rc_teamId && AccountMgr::IsPlayerAccount(GetSecurity()))
217 {
219 return;
220 }
221
222 Item* items[MAX_MAIL_ITEMS];
223
224 for (uint8 i = 0; i < items_count; ++i)
225 {
226 if (!itemGUIDs[i])
227 {
229 return;
230 }
231
232 Item* item = player->GetItemByGuid(itemGUIDs[i]);
233
234 // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail)
235 if (!item)
236 {
238 return;
239 }
240
241 // handle empty bag before CanBeTraded, since that func already has that check
242 if (item->IsNotEmptyBag())
243 {
245 return;
246 }
247
248 if (!item->CanBeTraded(true))
249 {
251 return;
252 }
253
254 if (item->IsBoundAccountWide() && item->IsSoulBound() && GetAccountId() != rc_account)
255 {
257 return;
258 }
259
261 {
263 return;
264 }
265
266 if (COD && item->IsWrapped())
267 {
269 return;
270 }
271
272 if (!sScriptMgr->OnPlayerCanSendMail(player, receiverGuid, mailbox, subject, body, money, COD, item))
273 {
275 return;
276 }
277
278 items[i] = item;
279 }
280
281 if (!items_count && !sScriptMgr->OnPlayerCanSendMail(player, receiverGuid, mailbox, subject, body, money, COD, nullptr))
282 {
284 return;
285 }
286
287 player->SendMailResult(0, MAIL_SEND, MAIL_OK);
288
289 player->ModifyMoney(-int32(reqmoney));
291
292 bool needItemDelay = false;
293
294 MailDraft draft(subject, body);
295
296 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
297
298 if (items_count > 0 || money > 0)
299 {
300 if (items_count > 0)
301 {
302 for (uint8 i = 0; i < items_count; ++i)
303 {
304 Item* item = items[i];
305
306 item->SetNotRefundable(GetPlayer()); // makes the item no longer refundable
307 player->MoveItemFromInventory(items[i]->GetBagSlot(), item->GetSlot(), true);
308
309 item->DeleteFromInventoryDB(trans); // deletes item from character's inventory
310 if (item->GetState() == ITEM_UNCHANGED)
311 item->FSetState(ITEM_CHANGED); // pussywizard: so the item will be saved and owner will be updated in database
312 item->SetOwnerGUID(receiverGuid);
313 item->SaveToDB(trans); // recursive and not have transaction guard into self, item not in inventory and can be save standalone
314
315 draft.AddItem(item);
316 }
317
318 // if item send to character at another account, then apply item delivery delay
319 needItemDelay = GetAccountId() != rc_account;
320 }
321
322 if (money >= 10 * GOLD)
323 {
325 CharacterDatabase.Execute("INSERT INTO log_money VALUES({}, {}, \"{}\", \"{}\", {}, \"{}\", {}, \"{}\", NOW(), {})",
326 GetAccountId(), player->GetGUID().GetCounter(), player->GetName(), player->GetSession()->GetRemoteAddress(), rc_account, receiver, money, subject, 5);
327 }
328 }
329
330 // If theres is an item, there is a one hour delivery delay if sent to another account's character.
331 uint32 deliver_delay = needItemDelay ? sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0;
332
333 // don't ask for COD if there are no items
334 if (items_count == 0)
335 COD = 0;
336
337 // will delete item or place to receiver mail list
338 draft
339 .AddMoney(money)
340 .AddCOD(COD)
341 .SendMailTo(trans, MailReceiver(receive, receiverGuid.GetCounter()), MailSender(player), body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay);
342
343 player->SaveInventoryAndGoldToDB(trans);
344 CharacterDatabase.CommitTransaction(trans);
345}
@ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL
Definition DBCEnums.h:178
@ EQUIP_ERR_MAIL_BOUND_ITEM
Definition Item.h:119
@ EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS
Definition Item.h:78
@ EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS
Definition Item.h:128
@ LANG_MAIL_SENDER_REQ
Definition Language.h:1173
#define MAX_MAIL_ITEMS
Definition Mail.h:33
@ MAIL_CHECK_MASK_HAS_BODY
Definition Mail.h:51
@ MAIL_SEND
Definition SharedDefines.h:3766
@ MAIL_ERR_NOT_YOUR_TEAM
Definition SharedDefines.h:3781
@ MAIL_ERR_CANT_SEND_WRAPPED_COD
Definition SharedDefines.h:3785
@ MAIL_ERR_RECIPIENT_CAP_REACHED
Definition SharedDefines.h:3784
@ MAIL_ERR_RECIPIENT_NOT_FOUND
Definition SharedDefines.h:3780
@ MAIL_ERR_TOO_MANY_ATTACHMENTS
Definition SharedDefines.h:3787
@ MAIL_ERR_MAIL_ATTACHMENT_INVALID
Definition SharedDefines.h:3788
@ MAIL_ERR_CANNOT_SEND_TO_SELF
Definition SharedDefines.h:3778
@ CONFIG_MAIL_LEVEL_REQ
Definition WorldConfig.h:252
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL
Definition WorldConfig.h:38
@ CONFIG_MAIL_DELIVERY_DELAY
Definition WorldConfig.h:216
bool IsBoundAccountWide() const
Definition Item.h:237
bool IsSoulBound() const
Definition Item.h:236
ItemUpdateState GetState() const
Definition Item.h:324
void SetNotRefundable(Player *owner, bool changestate=true, CharacterDatabaseTransaction *trans=nullptr)
Definition Item.cpp:1200
void FSetState(ItemUpdateState state)
Definition Item.h:330
void SetOwnerGUID(ObjectGuid guid)
Definition Item.h:232
uint32 GetMailSize()
Definition Player.h:1644

References _player, ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, MailDraft::AddCOD(), MailDraft::AddItem(), MailDraft::AddMoney(), Item::CanBeTraded(), CanOpenMailBox(), CharacterDatabase, CleanStringForMysqlQuery(), CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL, CONFIG_MAIL_DELIVERY_DELAY, CONFIG_MAIL_LEVEL_REQ, Item::DeleteFromInventoryDB(), EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS, EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS, EQUIP_ERR_MAIL_BOUND_ITEM, ObjectAccessor::FindConnectedPlayer(), Item::FSetState(), GetAccountId(), ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetItemByGuid(), Unit::GetLevel(), Player::GetMailSize(), WorldObject::GetName(), GetPlayer(), GetRemoteAddress(), GetSecurity(), Player::GetSession(), Item::GetSlot(), Item::GetState(), Player::GetTeamId(), Item::GetTemplate(), Object::GetUInt32Value(), GOLD, Player::HasEnoughMoney(), ItemTemplate::HasFlag(), Item::IsBoundAccountWide(), Item::IsNotEmptyBag(), AccountMgr::IsPlayerAccount(), Item::IsSoulBound(), Item::IsWrapped(), ITEM_CHANGED, ITEM_FIELD_DURATION, ITEM_FLAG_CONJURED, ITEM_UNCHANGED, LANG_MAIL_SENDER_REQ, LOG_DEBUG, LOG_ERROR, MAIL_CHECK_MASK_COPIED, MAIL_CHECK_MASK_HAS_BODY, MAIL_ERR_CANNOT_SEND_TO_SELF, MAIL_ERR_CANT_SEND_WRAPPED_COD, MAIL_ERR_EQUIP_ERROR, MAIL_ERR_INTERNAL_ERROR, MAIL_ERR_MAIL_ATTACHMENT_INVALID, MAIL_ERR_NOT_ENOUGH_MONEY, MAIL_ERR_NOT_YOUR_TEAM, MAIL_ERR_RECIPIENT_CAP_REACHED, MAIL_ERR_RECIPIENT_NOT_FOUND, MAIL_ERR_TOO_MANY_ATTACHMENTS, MAIL_OK, MAIL_SEND, MAX_MAIL_ITEMS, Player::ModifyMoney(), Player::MoveItemFromInventory(), normalizePlayerName(), ByteBuffer::read_skip(), ByteBuffer::rfinish(), Player::SaveInventoryAndGoldToDB(), Item::SaveToDB(), sCharacterCache, Player::SendMailResult(), MailDraft::SendMailTo(), ChatHandler::SendNotification(), Item::SetNotRefundable(), Item::SetOwnerGUID(), sScriptMgr, sWorld, TEAM_NEUTRAL, Player::TeamIdForRace(), ObjectGuid::ToString(), and Player::UpdateAchievementCriteria().

Referenced by OpcodeTable::Initialize().

◆ HandleSetActionBarToggles()

void WorldSession::HandleSetActionBarToggles ( WorldPacket recvData)
954{
955 uint8 ActionBar;
956
957 recv_data >> ActionBar;
958
959 if (!GetPlayer()) // ignore until not logged (check needed because STATUS_AUTHED)
960 {
961 if (ActionBar != 0)
962 LOG_ERROR("network.opcode", "WorldSession::HandleSetActionBarToggles in not logged state with value: {}, ignored", uint32(ActionBar));
963 return;
964 }
965
966 GetPlayer()->SetByteValue(PLAYER_FIELD_BYTES, 2, ActionBar);
967}
@ PLAYER_FIELD_BYTES
Definition UpdateFields.h:368

References GetPlayer(), LOG_ERROR, PLAYER_FIELD_BYTES, and Object::SetByteValue().

Referenced by OpcodeTable::Initialize().

◆ HandleSetActionButtonOpcode()

void WorldSession::HandleSetActionButtonOpcode ( WorldPacket recvPacket)
901{
902 uint8 button;
903 uint32 packetData;
904 recv_data >> button >> packetData;
905
906 uint32 action = ACTION_BUTTON_ACTION(packetData);
907 uint8 type = ACTION_BUTTON_TYPE(packetData);
908
909 LOG_DEBUG("network.opcode", "BUTTON: {} ACTION: {} TYPE: {}", button, action, type);
910 if (!packetData)
911 {
912 LOG_DEBUG("network.opcode", "MISC: Remove action from button {}", button);
913 GetPlayer()->removeActionButton(button);
914 }
915 else
916 {
917 switch (type)
918 {
921 LOG_DEBUG("network.opcode", "MISC: Added Macro {} into button {}", action, button);
922 break;
924 LOG_DEBUG("network.opcode", "MISC: Added EquipmentSet {} into button {}", action, button);
925 break;
927 LOG_DEBUG("network.opcode", "MISC: Added Spell {} into button {}", action, button);
928 break;
930 LOG_DEBUG("network.opcode", "MISC: Added Item {} into button {}", action, button);
931 break;
932 default:
933 LOG_ERROR("network.opcode", "MISC: Unknown action button type {} for action {} into button {} for player {} ({})",
934 type, action, button, _player->GetName(), _player->GetGUID().ToString());
935 return;
936 }
937 GetPlayer()->addActionButton(button, action, type);
938 }
939}
@ ACTION_BUTTON_EQSET
Definition Player.h:233
@ ACTION_BUTTON_MACRO
Definition Player.h:234
@ ACTION_BUTTON_ITEM
Definition Player.h:236
@ ACTION_BUTTON_CMACRO
Definition Player.h:235
@ ACTION_BUTTON_SPELL
Definition Player.h:231
#define ACTION_BUTTON_TYPE(X)
Definition Player.h:245
#define ACTION_BUTTON_ACTION(X)
Definition Player.h:244
ActionButton * addActionButton(uint8 button, uint32 action, uint8 type)
Definition Player.cpp:5692
void removeActionButton(uint8 button)
Definition Player.cpp:5707

References _player, ACTION_BUTTON_ACTION, ACTION_BUTTON_CMACRO, ACTION_BUTTON_EQSET, ACTION_BUTTON_ITEM, ACTION_BUTTON_MACRO, ACTION_BUTTON_SPELL, ACTION_BUTTON_TYPE, Player::addActionButton(), Object::GetGUID(), WorldObject::GetName(), GetPlayer(), LOG_DEBUG, LOG_ERROR, Player::removeActionButton(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleSetActiveMoverOpcode()

void WorldSession::HandleSetActiveMoverOpcode ( WorldPacket recvData)
763{
764 LOG_DEBUG("network", "WORLD: Recvd CMSG_SET_ACTIVE_MOVER");
765
766 ObjectGuid guid;
767 recvData >> guid;
768
769 if (GetPlayer()->IsInWorld() && _player->m_mover && _player->m_mover->IsInWorld())
770 {
771 if (_player->m_mover->GetGUID() != guid)
772 LOG_ERROR("network.opcode", "HandleSetActiveMoverOpcode: incorrect mover guid: mover is {} and should be {}",
773 guid.ToString(), _player->m_mover->GetGUID().ToString());
774 }
775}

References _player, Object::GetGUID(), GetPlayer(), Object::IsInWorld(), LOG_DEBUG, LOG_ERROR, Player::m_mover, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleSetActiveVoiceChannel()

void WorldSession::HandleSetActiveVoiceChannel ( WorldPacket recvData)
38{
39 LOG_DEBUG("network", "WORLD: CMSG_SET_ACTIVE_VOICE_CHANNEL");
40 recvData.read_skip<uint32>();
41 recvData.read_skip<char*>();
42}

References LOG_DEBUG, and ByteBuffer::read_skip().

Referenced by OpcodeTable::Initialize().

◆ HandleSetAmmoOpcode()

void WorldSession::HandleSetAmmoOpcode ( WorldPacket recvPacket)
1010{
1011 if (!_player->IsAlive())
1012 {
1013 _player->SendEquipError(EQUIP_ERR_YOU_ARE_DEAD, nullptr, nullptr);
1014 return;
1015 }
1016
1017 LOG_DEBUG("network", "WORLD: CMSG_SET_AMMO");
1018 uint32 item;
1019
1020 recvData >> item;
1021
1022 if (item)
1023 {
1024 if (!_player->GetItemCount(item))
1025 {
1027 return;
1028 }
1029
1030 _player->SetAmmo(item);
1031 }
1032 else
1034}
uint32 GetItemCount(uint32 item, bool inBankAlso=false, Item *skipItem=nullptr) const
Definition PlayerStorage.cpp:329
void RemoveAmmo()
Definition PlayerStorage.cpp:2521
void SetAmmo(uint32 item)
Definition PlayerStorage.cpp:2499

References _player, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_YOU_ARE_DEAD, Player::GetItemCount(), Unit::IsAlive(), LOG_DEBUG, Player::RemoveAmmo(), Player::SendEquipError(), and Player::SetAmmo().

Referenced by OpcodeTable::Initialize().

◆ HandleSetChannelWatch()

void WorldSession::HandleSetChannelWatch ( WorldPacket recvPacket)
303{
304 std::string channelName;
305 recvPacket >> channelName;
306
308
309 if (channelName.empty())
310 return;
311
313 if (Channel* channel = cMgr->GetChannel(channelName, nullptr, false))
314 channel->AddWatching(GetPlayer());
315}
void ClearChannelWatch()
Definition Player.cpp:5002

References Player::ClearChannelWatch(), ChannelMgr::forTeam(), GetPlayer(), and GetTeamId().

Referenced by OpcodeTable::Initialize().

◆ HandleSetContactNotesOpcode()

void WorldSession::HandleSetContactNotesOpcode ( WorldPacket recvPacket)
148{
149 ObjectGuid guid;
150 std::string note;
151 recv_data >> guid >> note;
152 _player->GetSocial()->SetFriendNote(guid, note);
153}

References _player, Player::GetSocial(), and PlayerSocial::SetFriendNote().

Referenced by OpcodeTable::Initialize().

◆ HandleSetDungeonDifficultyOpcode()

void WorldSession::HandleSetDungeonDifficultyOpcode ( WorldPacket recvData)
1257{
1258 LOG_DEBUG("network", "MSG_SET_DUNGEON_DIFFICULTY");
1259
1260 uint32 mode;
1261 recv_data >> mode;
1262
1263 if (mode >= MAX_DUNGEON_DIFFICULTY)
1264 return;
1265
1266 if (Difficulty(mode) == _player->GetDungeonDifficulty())
1267 return;
1268
1269 Group* group = _player->GetGroup();
1270 if (group)
1271 {
1272 if (group->IsLeader(_player->GetGUID()))
1273 {
1274 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
1275 {
1276 Player* groupGuy = itr->GetSource();
1277 if (!groupGuy)
1278 continue;
1279
1280 if (!groupGuy->IsInWorld())
1281 {
1282 _player->SendDungeonDifficulty(group != nullptr);
1283 return;
1284 }
1285
1286 if (groupGuy->GetGUID() == _player->GetGUID() ? groupGuy->GetMap()->IsDungeon() : groupGuy->GetMap()->IsNonRaidDungeon())
1287 {
1288 _player->SendDungeonDifficulty(group != nullptr);
1289 return;
1290 }
1291 }
1292
1294 group->SetDungeonDifficulty(Difficulty(mode));
1295 }
1296 }
1297 else
1298 {
1299 if (_player->FindMap() && _player->FindMap()->IsDungeon())
1300 {
1301 _player->SendDungeonDifficulty(group != nullptr);
1302 return;
1303 }
1306 }
1307}
#define MAX_DUNGEON_DIFFICULTY
Definition DBCEnums.h:281
@ INSTANCE_RESET_CHANGE_DIFFICULTY
Definition Map.h:639
void SetDungeonDifficulty(Difficulty difficulty)
Definition Group.cpp:2083
void ResetInstances(uint8 method, bool isRaid, Player *leader)
Definition Group.cpp:2125
bool IsNonRaidDungeon() const
Definition Map.h:296
void SetDungeonDifficulty(Difficulty dungeon_difficulty)
Definition Player.h:1919
Difficulty GetDungeonDifficulty() const
Definition Player.h:1916

References _player, WorldObject::FindMap(), Player::GetDungeonDifficulty(), Group::GetFirstMember(), Player::GetGroup(), Object::GetGUID(), WorldObject::GetMap(), INSTANCE_RESET_CHANGE_DIFFICULTY, Map::IsDungeon(), Object::IsInWorld(), Group::IsLeader(), Map::IsNonRaidDungeon(), LOG_DEBUG, MAX_DUNGEON_DIFFICULTY, Player::ResetInstances(), Group::ResetInstances(), Player::SendDungeonDifficulty(), Group::SetDungeonDifficulty(), and Player::SetDungeonDifficulty().

Referenced by OpcodeTable::Initialize().

◆ HandleSetFactionAtWar()

void WorldSession::HandleSetFactionAtWar ( WorldPacket recvData)
1266{
1267 uint32 repListID;
1268 uint8 flag;
1269
1270 recvData >> repListID;
1271 recvData >> flag;
1272
1273 GetPlayer()->GetReputationMgr().SetAtWar(repListID, flag);
1274}
void SetAtWar(RepListID repListID, bool on)
Definition ReputationMgr.cpp:504

References GetPlayer(), Player::GetReputationMgr(), and ReputationMgr::SetAtWar().

Referenced by OpcodeTable::Initialize().

◆ HandleSetFactionCheat()

void WorldSession::HandleSetFactionCheat ( WorldPacket recvData)
1278{
1279 LOG_ERROR("network.opcode", "WORLD SESSION: HandleSetFactionCheat, not expected call, please report.");
1281}

References GetPlayer(), Player::GetReputationMgr(), LOG_ERROR, and ReputationMgr::SendStates().

Referenced by OpcodeTable::Initialize().

◆ HandleSetFactionInactiveOpcode()

void WorldSession::HandleSetFactionInactiveOpcode ( WorldPacket recvData)
1319{
1320 uint32 replistid;
1321 uint8 inactive;
1322 recvData >> replistid >> inactive;
1323
1324 _player->GetReputationMgr().SetInactive(replistid, inactive);
1325}
void SetInactive(RepListID repListID, bool on)
Definition ReputationMgr.cpp:536

References _player, Player::GetReputationMgr(), and ReputationMgr::SetInactive().

Referenced by OpcodeTable::Initialize().

◆ HandleSetGuildBankTabText()

void WorldSession::HandleSetGuildBankTabText ( WorldPackets::Guild::GuildBankSetTabText packet)
397{
398 LOG_DEBUG("guild", "CMSG_SET_GUILD_BANK_TEXT [{}]: TabId: {}, Text: {}", GetPlayerInfo(), packet.Tab, packet.TabText);
399
400 if (Guild* guild = GetPlayer()->GetGuild())
401 guild->SetBankTabText(packet.Tab, packet.TabText);
402}
String< 500, Strings::NoHyperlinks > TabText
Definition GuildPackets.h:585
uint8 Tab
Definition GuildPackets.h:584

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, WorldPackets::Guild::GuildBankSetTabText::Tab, and WorldPackets::Guild::GuildBankSetTabText::TabText.

Referenced by OpcodeTable::Initialize().

◆ HandleSetPlayerDeclinedNames()

void WorldSession::HandleSetPlayerDeclinedNames ( WorldPacket recvData)
1429{
1430 // pussywizard:
1431 if (!sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
1432 return;
1433
1434 ObjectGuid guid;
1435 recvData >> guid;
1436
1437 // not accept declined names for unsupported languages
1438 std::string name;
1439 if (!sCharacterCache->GetCharacterNameByGuid(guid, name))
1440 {
1442 return;
1443 }
1444
1445 std::wstring wname;
1446 if (!Utf8toWStr(name, wname))
1447 {
1449 return;
1450 }
1451
1452 if (!isCyrillicCharacter(wname[0])) // name already stored as only single alphabet using
1453 {
1455 return;
1456 }
1457
1458 std::string name2;
1459 DeclinedName declinedname;
1460
1461 recvData >> name2;
1462
1463 if (name2 != name) // character have different name
1464 {
1466 return;
1467 }
1468
1469 for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
1470 {
1471 recvData >> declinedname.name[i];
1472 if (!normalizePlayerName(declinedname.name[i]))
1473 {
1475 return;
1476 }
1477 }
1478
1479 if (!ObjectMgr::CheckDeclinedNames(wname, declinedname))
1480 {
1482 return;
1483 }
1484
1485 for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
1486 CharacterDatabase.EscapeString(declinedname.name[i]);
1487
1488 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
1489
1491 stmt->SetData(0, guid.GetCounter());
1492 trans->Append(stmt);
1493
1494 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_DECLINED_NAME);
1495 stmt->SetData(0, guid.GetCounter());
1496
1497 for (uint8 i = 0; i < 5; i++)
1498 stmt->SetData(i + 1, declinedname.name[i]);
1499
1500 trans->Append(stmt);
1501
1502 CharacterDatabase.CommitTransaction(trans);
1503
1505}
@ CHAR_INS_CHAR_DECLINED_NAME
Definition CharacterDatabase.h:387
bool isCyrillicCharacter(wchar_t wchar)
Definition Util.h:145
void SendSetPlayerDeclinedNamesResult(DeclinedNameResult result, ObjectGuid guid)
Definition CharacterHandler.cpp:2647
@ DECLINED_NAMES_RESULT_SUCCESS
Definition WorldSession.h:255
@ DECLINED_NAMES_RESULT_ERROR
Definition WorldSession.h:256

References CHAR_DEL_CHAR_DECLINED_NAME, CHAR_INS_CHAR_DECLINED_NAME, CharacterDatabase, ObjectMgr::CheckDeclinedNames(), CONFIG_DECLINED_NAMES_USED, DECLINED_NAMES_RESULT_ERROR, DECLINED_NAMES_RESULT_SUCCESS, ObjectGuid::GetCounter(), isCyrillicCharacter(), MAX_DECLINED_NAME_CASES, DeclinedName::name, normalizePlayerName(), sCharacterCache, SendSetPlayerDeclinedNamesResult(), PreparedStatementBase::SetData(), sWorld, and Utf8toWStr().

Referenced by OpcodeTable::Initialize().

◆ HandleSetRaidDifficultyOpcode()

void WorldSession::HandleSetRaidDifficultyOpcode ( WorldPacket recvData)
1310{
1311 LOG_DEBUG("network", "MSG_SET_RAID_DIFFICULTY");
1312
1313 uint32 mode;
1314 recv_data >> mode;
1315
1316 if (mode >= MAX_RAID_DIFFICULTY)
1317 return;
1318
1319 if (Difficulty(mode) == _player->GetRaidDifficulty())
1320 return;
1321
1322 Group* group = _player->GetGroup();
1323 if (group)
1324 {
1325 if (group->IsLeader(_player->GetGUID()))
1326 {
1327 std::set<uint32> foundMaps;
1328 std::set<Map*> foundMapsPtr;
1329 Map* currMap = nullptr;
1330
1331 if (uint32 preventionTime = group->GetDifficultyChangePreventionTime())
1332 {
1333 switch (group->GetDifficultyChangePreventionReason())
1334 {
1336 ChatHandler(this).PSendSysMessage("Raid was in combat recently and may not change difficulty again for {} sec.", preventionTime);
1337 break;
1339 default:
1340 ChatHandler(this).PSendSysMessage("Raid difficulty has changed recently, and may not change again for {} sec.", preventionTime);
1341 break;
1342 }
1343
1344 _player->SendRaidDifficulty(group != nullptr);
1345 return;
1346 }
1347
1348 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
1349 {
1350 Player* groupGuy = itr->GetSource();
1351 if (!groupGuy)
1352 continue;
1353
1354 if (!groupGuy->IsInWorld())
1355 {
1356 _player->SendRaidDifficulty(group != nullptr);
1357 return;
1358 }
1359
1360 if (IsSharedDifficultyMap(groupGuy->GetMap()->GetId()) && (uint32(mode % 2) == uint32(_player->GetRaidDifficulty() % 2)) && group->isRaidGroup())
1361 {
1362 if (!currMap)
1363 currMap = groupGuy->GetMap();
1364 foundMaps.insert(groupGuy->GetMap()->GetId());
1365 foundMapsPtr.insert(groupGuy->GetMap());
1366 if (foundMaps.size() > 1 || foundMapsPtr.size() > 1)
1367 {
1368 _player->SendRaidDifficulty(group != nullptr);
1369 return;
1370 }
1371
1372 if (!groupGuy->IsAlive() || groupGuy->IsInCombat() || groupGuy->GetVictim() || groupGuy->m_mover != groupGuy || groupGuy->IsNonMeleeSpellCast(true) || (!groupGuy->GetMotionMaster()->empty() && groupGuy->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE)
1373 || !groupGuy->movespline->Finalized() || !groupGuy->GetMap()->ToInstanceMap() || !groupGuy->GetMap()->ToInstanceMap()->GetInstanceScript() || groupGuy->GetMap()->ToInstanceMap()->GetInstanceScript()->IsEncounterInProgress()
1374 || !groupGuy->Satisfy(sObjectMgr->GetAccessRequirement(groupGuy->GetMap()->GetId(), Difficulty(mode)), groupGuy->GetMap()->GetId(), false))
1375 {
1376 _player->SendRaidDifficulty(group != nullptr);
1377 return;
1378 }
1379 }
1380 else if (groupGuy->GetGUID() == _player->GetGUID() ? groupGuy->GetMap()->IsDungeon() : groupGuy->GetMap()->IsRaid())
1381 {
1382 _player->SendRaidDifficulty(group != nullptr);
1383 return;
1384 }
1385 }
1386
1387 Map* homeMap571 = sMapMgr->CreateMap(MAP_NORTHREND, nullptr);
1388 Map* homeMap0 = sMapMgr->CreateMap(MAP_EASTERN_KINGDOMS, nullptr);
1389 ASSERT(homeMap0 && homeMap571);
1390
1391 std::map<Player*, Position> playerTeleport;
1392 // handle here all players in the instance that are not in the group
1393 if (currMap)
1394 for (Map::PlayerList::const_iterator itr = currMap->GetPlayers().begin(); itr != currMap->GetPlayers().end(); ++itr)
1395 if (Player* p = itr->GetSource())
1396 if (p->GetGroup() != group)
1397 {
1398 if (!p->IsInWorld() || !p->IsAlive() || p->IsInCombat() || p->GetVictim() || p->m_mover != p || p->IsNonMeleeSpellCast(true) || (!p->GetMotionMaster()->empty() && p->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE)
1399 || !p->movespline->Finalized() || !p->GetMap()->ToInstanceMap() || !p->GetMap()->ToInstanceMap()->GetInstanceScript() || p->GetMap()->ToInstanceMap()->GetInstanceScript()->IsEncounterInProgress())
1400 {
1401 _player->SendRaidDifficulty(group != nullptr);
1402 return;
1403 }
1404 playerTeleport[p];
1405 }
1406 for (std::map<Player*, Position>::iterator itr = playerTeleport.begin(); itr != playerTeleport.end(); ++itr)
1407 {
1408 Player* p = itr->first;
1409 Map* oldMap = p->GetMap();
1410 oldMap->RemovePlayerFromMap(p, false);
1411 p->ResetMap();
1412 oldMap->AfterPlayerUnlinkFromMap();
1413 p->SetMap(homeMap0);
1414 p->Relocate(0.0f, 0.0f, 0.0f, 0.0f);
1415 if (!p->TeleportTo(MAP_NORTHREND, 5790.20f, 2071.36f, 636.07f, 3.60f))
1416 p->GetSession()->KickPlayer("HandleSetRaidDifficultyOpcode 1");
1417 }
1418
1419 bool anyoneInside = false;
1420 playerTeleport.clear();
1421 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
1422 {
1423 Player* groupGuy = itr->GetSource();
1424 if (!groupGuy)
1425 continue;
1426
1427 if (IsSharedDifficultyMap(groupGuy->GetMap()->GetId()))
1428 {
1429 anyoneInside = true;
1430
1431 float x, y, z, o;
1432 groupGuy->GetPosition(x, y, z, o);
1433 Map* oldMap = groupGuy->GetMap();
1434 oldMap->RemovePlayerFromMap(groupGuy, false);
1435 groupGuy->ResetMap();
1436 oldMap->AfterPlayerUnlinkFromMap();
1437 groupGuy->SetMap(homeMap571);
1438 groupGuy->Relocate(5790.20f, 2071.36f, 636.07f, 3.60f);
1439 Position dest = {x, y, z + 0.1f, o};
1440 playerTeleport[groupGuy] = dest;
1441 }
1442 }
1443
1444 if (!anyoneInside) // pussywizard: don't reset if changing ICC/RS difficulty while inside
1446 group->SetRaidDifficulty(Difficulty(mode));
1448
1449 for (std::map<Player*, Position>::iterator itr = playerTeleport.begin(); itr != playerTeleport.end(); ++itr)
1450 {
1451 itr->first->SetRaidDifficulty(Difficulty(mode)); // needed for teleport not to fail
1452 if (!itr->first->TeleportTo(*(foundMaps.begin()), itr->second.GetPositionX(), itr->second.GetPositionY(), itr->second.GetPositionZ(), itr->second.GetOrientation()))
1453 itr->first->GetSession()->KickPlayer("HandleSetRaidDifficultyOpcode 2");
1454 }
1455 }
1456 }
1457 else
1458 {
1459 if (_player->FindMap() && _player->FindMap()->IsDungeon())
1460 {
1461 _player->SendRaidDifficulty(group != nullptr);
1462 return;
1463 }
1466 }
1467}
@ MAP_NORTHREND
Definition AreaDefines.h:243
#define MAX_RAID_DIFFICULTY
Definition DBCEnums.h:282
bool IsSharedDifficultyMap(uint32 mapid)
Definition DBCStores.cpp:829
@ DIFFICULTY_PREVENTION_CHANGE_RECENTLY_CHANGED
Definition Group.h:134
@ DIFFICULTY_PREVENTION_CHANGE_BOSS_KILLED
Definition Group.h:135
@ IDLE_MOTION_TYPE
Definition MotionMaster.h:39
GroupReference * next()
Definition GroupReference.h:36
void SetRaidDifficulty(Difficulty difficulty)
Definition Group.cpp:2104
DifficultyPreventionChangeType GetDifficultyChangePreventionReason() const
Definition Group.h:321
void SetDifficultyChangePrevention(DifficultyPreventionChangeType type)
Definition Group.cpp:2547
uint32 GetDifficultyChangePreventionTime() const
Definition Group.cpp:2542
InstanceScript * GetInstanceScript()
Definition Map.h:658
virtual bool IsEncounterInProgress() const
Definition InstanceScript.cpp:137
Definition LinkedList.h:139
iterator begin()
Definition MapRefMgr.h:36
iterator end()
Definition MapRefMgr.h:37
bool IsRaid() const
Definition Map.h:297
InstanceMap * ToInstanceMap()
Definition Map.h:377
PlayerList const & GetPlayers() const
Definition Map.h:326
MovementGeneratorType GetCurrentMovementGeneratorType() const
Definition MotionMaster.cpp:949
bool empty() const
Definition MotionMaster.h:173
bool Finalized() const
Definition MoveSpline.h:116
Difficulty GetRaidDifficulty() const
Definition Player.h:1917
void SetRaidDifficulty(Difficulty raid_difficulty)
Definition Player.h:1920
bool Satisfy(DungeonProgressionRequirements const *ar, uint32 target_map, bool report=false)
Definition PlayerStorage.cpp:6710
void SendRaidDifficulty(bool IsInGroup, int32 forcedDifficulty=-1)
Definition PlayerMisc.cpp:177

References _player, Map::AfterPlayerUnlinkFromMap(), ASSERT, MapRefMgr::begin(), DIFFICULTY_PREVENTION_CHANGE_BOSS_KILLED, DIFFICULTY_PREVENTION_CHANGE_RECENTLY_CHANGED, MotionMaster::empty(), MapRefMgr::end(), Movement::MoveSpline::Finalized(), WorldObject::FindMap(), MotionMaster::GetCurrentMovementGeneratorType(), Group::GetDifficultyChangePreventionReason(), Group::GetDifficultyChangePreventionTime(), Group::GetFirstMember(), Player::GetGroup(), Object::GetGUID(), Map::GetId(), InstanceMap::GetInstanceScript(), WorldObject::GetMap(), Unit::GetMotionMaster(), Map::GetPlayers(), Position::GetPosition(), Player::GetRaidDifficulty(), Player::GetSession(), Unit::GetVictim(), IDLE_MOTION_TYPE, INSTANCE_RESET_CHANGE_DIFFICULTY, Unit::IsAlive(), Map::IsDungeon(), InstanceScript::IsEncounterInProgress(), Unit::IsInCombat(), Object::IsInWorld(), Group::IsLeader(), Unit::IsNonMeleeSpellCast(), Map::IsRaid(), Group::isRaidGroup(), IsSharedDifficultyMap(), KickPlayer(), LOG_DEBUG, Player::m_mover, MAP_EASTERN_KINGDOMS, MAP_NORTHREND, MAX_RAID_DIFFICULTY, Unit::movespline, GroupReference::next(), ChatHandler::PSendSysMessage(), Position::Relocate(), Map::RemovePlayerFromMap(), Player::ResetInstances(), Group::ResetInstances(), Player::ResetMap(), Player::Satisfy(), Player::SendRaidDifficulty(), Group::SetDifficultyChangePrevention(), Player::SetMap(), Group::SetRaidDifficulty(), Player::SetRaidDifficulty(), sMapMgr, sObjectMgr, Player::TeleportTo(), and Map::ToInstanceMap().

Referenced by OpcodeTable::Initialize().

◆ HandleSetSavedInstanceExtend()

void WorldSession::HandleSetSavedInstanceExtend ( WorldPacket recvData)
777{
778 uint32 mapId, difficulty;
779 uint8 toggleExtendOn;
780 recvData >> mapId >> difficulty >> toggleExtendOn;
781
782 MapEntry const* entry = sMapStore.LookupEntry(mapId);
783 if (!entry || !entry->IsRaid())
784 return;
785
786 InstancePlayerBind* instanceBind = sInstanceSaveMgr->PlayerGetBoundInstance(GetPlayer()->GetGUID(), mapId, Difficulty(difficulty));
787 if (!instanceBind || !instanceBind->perm || (bool)toggleExtendOn == instanceBind->extended)
788 return;
789
790 instanceBind->extended = (bool)toggleExtendOn;
791
792 // update in db
794 stmt->SetData(0, toggleExtendOn ? 1 : 0);
795 stmt->SetData(1, GetPlayer()->GetGUID().GetCounter());
796 stmt->SetData(2, instanceBind->save->GetInstanceId());
797 CharacterDatabase.Execute(stmt);
798
799 SendCalendarRaidLockoutUpdated(instanceBind->save, (bool)toggleExtendOn);
800}
@ CHAR_UPD_CHAR_INSTANCE_EXTENDED
Definition CharacterDatabase.h:313
void SendCalendarRaidLockoutUpdated(InstanceSave const *save, bool isExtended)
Definition CalendarHandler.cpp:823
Definition InstanceSaveMgr.h:39
InstanceSave * save
Definition InstanceSaveMgr.h:40
bool extended
Definition InstanceSaveMgr.h:42
bool perm
Definition InstanceSaveMgr.h:41

References CHAR_UPD_CHAR_INSTANCE_EXTENDED, CharacterDatabase, InstancePlayerBind::extended, ObjectGuid::GetCounter(), Object::GetGUID(), InstanceSave::GetInstanceId(), GetPlayer(), MapEntry::IsRaid(), InstancePlayerBind::perm, InstancePlayerBind::save, SendCalendarRaidLockoutUpdated(), PreparedStatementBase::SetData(), sInstanceSaveMgr, and sMapStore.

Referenced by OpcodeTable::Initialize().

◆ HandleSetSelectionOpcode()

void WorldSession::HandleSetSelectionOpcode ( WorldPacket recvPacket)
537{
538 ObjectGuid guid;
539 recv_data >> guid;
540
541 _player->SetSelection(guid);
542
543 // Change target of current autoshoot spell
544 if (guid)
545 {
546 if (Spell* autoReapeatSpell = _player->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL))
547 {
548 if (autoReapeatSpell->m_targets.GetUnitTargetGUID() != guid)
549 {
550 if (Unit* unit = ObjectAccessor::GetUnit(*_player, guid))
551 {
552 if (unit->IsAlive() && !_player->IsFriendlyTo(unit) && unit->isTargetableForAttack(true, _player))
553 {
554 autoReapeatSpell->m_targets.SetUnitTarget(unit);
555 }
556 }
557 }
558 }
559 }
560}
void SetSelection(ObjectGuid guid)
Used for serverside target changes, does not apply to players.
Definition Player.cpp:11569
bool IsFriendlyTo(Unit const *unit) const
Definition Unit.cpp:10420

References _player, CURRENT_AUTOREPEAT_SPELL, Unit::GetCurrentSpell(), ObjectAccessor::GetUnit(), Unit::IsFriendlyTo(), and Player::SetSelection().

Referenced by OpcodeTable::Initialize().

◆ HandleSetSheathedOpcode()

void WorldSession::HandleSetSheathedOpcode ( WorldPackets::Combat::SetSheathed packet)
74{
76 {
77 LOG_ERROR("network.opcode", "Unknown sheath state {} ??", packet.CurrentSheathState);
78 return;
79 }
80
82}
SheathState
Definition UnitDefines.h:125
#define MAX_SHEATH_STATE
Definition UnitDefines.h:131
void SetSheath(SheathState sheathed) override
Definition PlayerStorage.cpp:99
uint32 CurrentSheathState
Definition CombatPackets.h:35

References _player, WorldPackets::Combat::SetSheathed::CurrentSheathState, LOG_ERROR, MAX_SHEATH_STATE, and Player::SetSheath().

Referenced by OpcodeTable::Initialize().

◆ HandleSetTaxiBenchmarkOpcode()

void WorldSession::HandleSetTaxiBenchmarkOpcode ( WorldPacket recvData)
1568{
1569 uint8 mode;
1570 recv_data >> mode;
1571
1573
1574 LOG_DEBUG("network", "Client used \"/timetest {}\" command", mode);
1575}
@ PLAYER_FLAGS_TAXI_BENCHMARK
Definition Player.h:485
void SetPlayerFlag(PlayerFlags flags)
Definition Player.h:1111

References _player, LOG_DEBUG, PLAYER_FLAGS_TAXI_BENCHMARK, Player::RemovePlayerFlag(), and Player::SetPlayerFlag().

Referenced by OpcodeTable::Initialize().

◆ HandleSetTitleOpcode()

void WorldSession::HandleSetTitleOpcode ( WorldPacket recvData)
1225{
1226 LOG_DEBUG("network", "CMSG_SET_TITLE");
1227
1228 int32 title;
1229 recv_data >> title;
1230
1231 // -1 at none
1232 if (title > 0 && title < MAX_TITLE_INDEX)
1233 {
1234 if (!GetPlayer()->HasTitle(title))
1235 return;
1236 }
1237 else
1238 title = 0;
1239
1241}
#define MAX_TITLE_INDEX
Definition Player.h:548
@ PLAYER_CHOSEN_TITLE
Definition UpdateFields.h:324

References GetPlayer(), LOG_DEBUG, MAX_TITLE_INDEX, PLAYER_CHOSEN_TITLE, and Unit::SetUInt32Value().

Referenced by OpcodeTable::Initialize().

◆ HandleSetTradeGoldOpcode()

void WorldSession::HandleSetTradeGoldOpcode ( WorldPacket recvPacket)
653{
654 uint32 gold;
655 recvPacket >> gold;
656
657 TradeData* my_trade = _player->GetTradeData();
658 if (!my_trade)
659 return;
660
661 my_trade->SetMoney(gold);
662}
TradeData * GetTradeData() const
Definition Player.h:1375
void SetMoney(uint32 money)
Definition TradeData.cpp:93

References _player, Player::GetTradeData(), and TradeData::SetMoney().

Referenced by OpcodeTable::Initialize().

◆ HandleSetTradeItemOpcode()

void WorldSession::HandleSetTradeItemOpcode ( WorldPacket recvPacket)
665{
666 // send update
667 uint8 tradeSlot;
668 uint8 bag;
669 uint8 slot;
670
671 recvPacket >> tradeSlot;
672 recvPacket >> bag;
673 recvPacket >> slot;
674
675 TradeData* my_trade = _player->GetTradeData();
676 if (!my_trade)
677 return;
678
679 // invalid slot number
680 if (tradeSlot >= TRADE_SLOT_COUNT)
681 {
683 return;
684 }
685
686 // check cheating, can't fail with correct client operations
687 Item* item = _player->GetItemByPos(bag, slot);
688 if (!item || (tradeSlot != TRADE_SLOT_NONTRADED && !item->CanBeTraded(false, true)))
689 {
691 return;
692 }
693
694 ObjectGuid iGUID = item->GetGUID();
695
696 // prevent place single item into many trade slots using cheating and client bugs
697 if (my_trade->HasItem(iGUID))
698 {
699 // cheating attempt
701 return;
702 }
703
704 // PlayerScript Hook for checking traded items if we want to filter them in a custom module
705 if (!sScriptMgr->OnPlayerCanSetTradeItem(_player, item, tradeSlot))
706 {
707 // Do not send TRADE_STATUS_TRADE_CANCELED because it will cause double display of "Transaction canceled" notification
708 // On the trade initiator screen
710 return;
711 }
712
713 my_trade->SetItem(TradeSlots(tradeSlot), item);
714}
bool HasItem(ObjectGuid itemGuid) const
Definition TradeData.cpp:31

References _player, Item::CanBeTraded(), Object::GetGUID(), Player::GetItemByPos(), Player::GetTradeData(), TradeData::HasItem(), SendTradeStatus(), TradeData::SetItem(), sScriptMgr, TRADE_SLOT_COUNT, TRADE_SLOT_NONTRADED, TRADE_STATUS_CLOSE_WINDOW, and TRADE_STATUS_TRADE_CANCELED.

Referenced by OpcodeTable::Initialize().

◆ HandleSetWatchedFactionOpcode()

void WorldSession::HandleSetWatchedFactionOpcode ( WorldPacket recvData)
1312{
1313 uint32 fact;
1314 recvData >> fact;
1316}
@ PLAYER_FIELD_WATCHED_FACTION_INDEX
Definition UpdateFields.h:379

References GetPlayer(), PLAYER_FIELD_WATCHED_FACTION_INDEX, and Unit::SetUInt32Value().

Referenced by OpcodeTable::Initialize().

◆ HandleShowingCloakOpcode()

◆ HandleShowingHelmOpcode()

◆ HandleSocketClosed()

bool WorldSession::HandleSocketClosed ( )
564{
565 if (m_Socket && !m_Socket->IsOpen() && !IsKicked() && GetPlayer() && !PlayerLogout() && GetPlayer()->m_taxi.empty() && GetPlayer()->IsInWorld() && !World::IsStopped())
566 {
567 m_Socket = nullptr;
568 GetPlayer()->TradeCancel(false);
569 return true;
570 }
571
572 return false;
573}
bool PlayerLogout() const
Definition WorldSession.h:382
bool IsKicked() const
Definition WorldSession.h:1126
static bool IsStopped()
Definition World.h:189

References GetPlayer(), IsKicked(), World::IsStopped(), m_Socket, PlayerLogout(), and Player::TradeCancel().

Referenced by WorldSessionMgr::AddSession_(), and WorldSessionMgr::UpdateSessions().

◆ HandleSocketOpcode()

void WorldSession::HandleSocketOpcode ( WorldPackets::Item::SocketGems packet)
1209{
1210 LOG_DEBUG("network", "WORLD: CMSG_SOCKET_GEMS");
1211
1212 if (!packet.ItemGuid)
1213 return;
1214
1215 //cheat -> tried to socket same gem multiple times
1216 if ((packet.GemGuids[0] && (packet.GemGuids[0] == packet.GemGuids[1] || packet.GemGuids[0] == packet.GemGuids[2])) ||
1217 (packet.GemGuids[1] && (packet.GemGuids[1] == packet.GemGuids[2])))
1218 return;
1219
1220 Item* itemTarget = _player->GetItemByGuid(packet.ItemGuid);
1221 if (!itemTarget) //missing item to socket
1222 return;
1223
1224 ItemTemplate const* itemProto = itemTarget->GetTemplate();
1225 if (!itemProto)
1226 return;
1227
1228 //this slot is excepted when applying / removing meta gem bonus
1229 uint8 slot = itemTarget->IsEquipped() ? itemTarget->GetSlot() : uint8(NULL_SLOT);
1230
1231 Item* Gems[MAX_GEM_SOCKETS];
1232 for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
1233 Gems[i] = packet.GemGuids[i] ? _player->GetItemByGuid(packet.GemGuids[i]) : nullptr;
1234
1235 GemPropertiesEntry const* GemProps[MAX_GEM_SOCKETS];
1236 for (int i = 0; i < MAX_GEM_SOCKETS; ++i) //get geminfo from dbc storage
1237 GemProps[i] = (Gems[i]) ? sGemPropertiesStore.LookupEntry(Gems[i]->GetTemplate()->GemProperties) : nullptr;
1238
1239 // Find first prismatic socket
1240 int32 firstPrismatic = 0;
1241 while (firstPrismatic < MAX_GEM_SOCKETS && itemProto->Socket[firstPrismatic].Color)
1242 ++firstPrismatic;
1243
1244 for (int i = 0; i < MAX_GEM_SOCKETS; ++i) //check for hack maybe
1245 {
1246 if (!GemProps[i])
1247 continue;
1248
1249 // tried to put gem in socket where no socket exists (take care about prismatic sockets)
1250 if (!itemProto->Socket[i].Color)
1251 {
1252 // no prismatic socket
1254 return;
1255
1256 if (i != firstPrismatic)
1257 return;
1258 }
1259
1260 // tried to put normal gem in meta socket
1261 if (itemProto->Socket[i].Color == SOCKET_COLOR_META && GemProps[i]->color != SOCKET_COLOR_META)
1262 return;
1263
1264 // tried to put meta gem in normal socket
1265 if (itemProto->Socket[i].Color != SOCKET_COLOR_META && GemProps[i]->color == SOCKET_COLOR_META)
1266 return;
1267 }
1268
1269 uint32 GemEnchants[MAX_GEM_SOCKETS];
1270 uint32 OldEnchants[MAX_GEM_SOCKETS];
1271 for (int i = 0; i < MAX_GEM_SOCKETS; ++i) //get new and old enchantments
1272 {
1273 GemEnchants[i] = (GemProps[i]) ? GemProps[i]->spellitemenchantement : 0;
1274 OldEnchants[i] = itemTarget->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT + i));
1275 }
1276
1277 // check unique-equipped conditions
1278 for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
1279 {
1280 if (!Gems[i])
1281 continue;
1282
1283 // continue check for case when attempt add 2 similar unique equipped gems in one item.
1284 ItemTemplate const* iGemProto = Gems[i]->GetTemplate();
1285
1286 // unique item (for new and already placed bit removed enchantments
1287 if (iGemProto->HasFlag(ITEM_FLAG_UNIQUE_EQUIPPABLE))
1288 {
1289 for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
1290 {
1291 if (i == j) // skip self
1292 continue;
1293
1294 if (Gems[j])
1295 {
1296 if (iGemProto->ItemId == Gems[j]->GetEntry())
1297 {
1299 return;
1300 }
1301 }
1302 else if (OldEnchants[j])
1303 {
1304 if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]))
1305 {
1306 if (iGemProto->ItemId == enchantEntry->GemID)
1307 {
1309 return;
1310 }
1311 }
1312 }
1313 }
1314 }
1315
1316 // unique limit type item
1317 int32 limit_newcount = 0;
1318 if (iGemProto->ItemLimitCategory)
1319 {
1320 if (ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(iGemProto->ItemLimitCategory))
1321 {
1322 // NOTE: limitEntry->mode is not checked because if item has limit then it is applied in equip case
1323 for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
1324 {
1325 if (Gems[j])
1326 {
1327 // new gem
1328 if (iGemProto->ItemLimitCategory == Gems[j]->GetTemplate()->ItemLimitCategory)
1329 ++limit_newcount;
1330 }
1331 else if (OldEnchants[j])
1332 {
1333 // existing gem
1334 if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]))
1335 if (ItemTemplate const* jProto = sObjectMgr->GetItemTemplate(enchantEntry->GemID))
1336 if (iGemProto->ItemLimitCategory == jProto->ItemLimitCategory)
1337 ++limit_newcount;
1338 }
1339 }
1340
1341 if (limit_newcount > 0 && uint32(limit_newcount) > limitEntry->maxCount)
1342 {
1344 return;
1345 }
1346 }
1347 }
1348
1349 // for equipped item check all equipment for duplicate equipped gems
1350 if (itemTarget->IsEquipped())
1351 {
1352 if (InventoryResult res = _player->CanEquipUniqueItem(Gems[i], slot, std::max(limit_newcount, 0)))
1353 {
1354 _player->SendEquipError(res, itemTarget, nullptr);
1355 return;
1356 }
1357 }
1358 }
1359
1360 bool SocketBonusActivated = itemTarget->GemsFitSockets(); //save state of socketbonus
1361 _player->ToggleMetaGemsActive(slot, false); //turn off all metagems (except for the target item)
1362
1363 //if a meta gem is being equipped, all information has to be written to the item before testing if the conditions for the gem are met
1364
1365 //remove ALL enchants
1366 for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS; ++enchant_slot)
1367 _player->ApplyEnchantment(itemTarget, EnchantmentSlot(enchant_slot), false);
1368
1369 for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
1370 {
1371 if (GemEnchants[i])
1372 {
1373 itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT + i), GemEnchants[i], 0, 0, _player->GetGUID());
1374 if (Item* guidItem = _player->GetItemByGuid(packet.GemGuids[i]))
1375 _player->DestroyItem(guidItem->GetBagSlot(), guidItem->GetSlot(), true);
1376 }
1377 }
1378
1379 for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS; ++enchant_slot)
1380 _player->ApplyEnchantment(itemTarget, EnchantmentSlot(enchant_slot), true);
1381
1382 bool SocketBonusToBeActivated = itemTarget->GemsFitSockets();//current socketbonus state
1383 if (SocketBonusActivated ^ SocketBonusToBeActivated) //if there was a change...
1384 {
1385 _player->ApplyEnchantment(itemTarget, BONUS_ENCHANTMENT_SLOT, false);
1386 itemTarget->SetEnchantment(BONUS_ENCHANTMENT_SLOT, (SocketBonusToBeActivated ? itemTarget->GetTemplate()->socketBonus : 0), 0, 0, _player->GetGUID());
1388 //it is not displayed, client has an inbuilt system to determine if the bonus is activated
1389 }
1390
1391 _player->ToggleMetaGemsActive(slot, true); //turn on all metagems (except for target item)
1392
1393 _player->RemoveTradeableItem(itemTarget);
1394 itemTarget->ClearSoulboundTradeable(_player); // clear tradeable flag
1395
1396 itemTarget->SendUpdateSockets();
1397}
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
DBCStorage< ItemLimitCategoryEntry > sItemLimitCategoryStore(ItemLimitCategoryEntryfmt)
DBCStorage< GemPropertiesEntry > sGemPropertiesStore(GemPropertiesEntryfmt)
@ ITEM_FLAG_UNIQUE_EQUIPPABLE
Definition ItemTemplate.h:166
@ SOCKET_COLOR_META
Definition ItemTemplate.h:246
@ EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED
Definition Item.h:122
#define MAX_GEM_SOCKETS
Definition Item.h:188
@ PRISMATIC_ENCHANTMENT_SLOT
Definition Item.h:175
@ SOCK_ENCHANTMENT_SLOT
Definition Item.h:171
@ BONUS_ENCHANTMENT_SLOT
Definition Item.h:174
bool GemsFitSockets() const
Definition Item.cpp:970
void SendUpdateSockets()
Definition Item.cpp:1062
void ClearSoulboundTradeable(Player *currentOwner)
Definition Item.cpp:1264
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition Item.cpp:920
void ToggleMetaGemsActive(uint8 exceptslot, bool apply)
Definition Player.cpp:11274
InventoryResult CanEquipUniqueItem(Item *pItem, uint8 except_slot=NULL_SLOT, uint32 limit_count=1) const
Definition Player.cpp:13829
void RemoveTradeableItem(Item *item)
Definition PlayerStorage.cpp:4141
Definition Socket.h:52
ObjectGuid ItemGuid
Definition ItemPackets.h:236
ObjectGuid GemGuids[MAX_GEM_SOCKETS]
Definition ItemPackets.h:237
Definition DBCStructure.h:1015
Definition DBCStructure.h:1197
Definition DBCStructure.h:1839

References _player, Player::ApplyEnchantment(), BONUS_ENCHANTMENT_SLOT, Player::CanEquipUniqueItem(), Item::ClearSoulboundTradeable(), _Socket::Color, GemPropertiesEntry::color, Player::DestroyItem(), EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, WorldPackets::Item::SocketGems::GemGuids, Item::GemsFitSockets(), Item::GetEnchantmentId(), Object::GetEntry(), Object::GetGUID(), Player::GetItemByGuid(), Item::GetSlot(), Item::GetTemplate(), ItemTemplate::HasFlag(), Item::IsEquipped(), ITEM_FLAG_UNIQUE_EQUIPPABLE, WorldPackets::Item::SocketGems::ItemGuid, ItemTemplate::ItemId, ItemTemplate::ItemLimitCategory, LOG_DEBUG, MAX_GEM_SOCKETS, NULL_SLOT, PRISMATIC_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Player::SendEquipError(), Item::SendUpdateSockets(), Item::SetEnchantment(), sGemPropertiesStore, sItemLimitCategoryStore, sObjectMgr, SOCK_ENCHANTMENT_SLOT, ItemTemplate::Socket, SOCKET_COLOR_META, ItemTemplate::socketBonus, sSpellItemEnchantmentStore, and Player::ToggleMetaGemsActive().

Referenced by OpcodeTable::Initialize().

◆ HandleSpellClick()

void WorldSession::HandleSpellClick ( WorldPacket recvData)
Todo:
: Unit::SetCharmedBy: 28782 is not in world but 0 is trying to charm it! -> crash
720{
721 ObjectGuid guid;
722 recvData >> guid;
723
724 // this will get something not in world. crash
726
727 if (!unit)
728 return;
729
731 if (!unit->IsInWorld())
732 return;
733
735}
bool HandleSpellClick(Unit *clicker, int8 seatId=-1)
Definition Unit.cpp:19532

References _player, ObjectAccessor::GetCreatureOrPetOrVehicle(), Unit::HandleSpellClick(), and Object::IsInWorld().

Referenced by OpcodeTable::Initialize().

◆ HandleSpiritHealerActivateOpcode()

void WorldSession::HandleSpiritHealerActivateOpcode ( WorldPacket recvPacket)
366{
367 LOG_DEBUG("network", "WORLD: CMSG_SPIRIT_HEALER_ACTIVATE");
368
369 ObjectGuid guid;
370
371 recvData >> guid;
372
374 if (!unit)
375 {
376 LOG_DEBUG("network", "WORLD: HandleSpiritHealerActivateOpcode - Unit ({}) not found or you can not interact with him.", guid.ToString());
377 return;
378 }
379
380 // remove fake death
381 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
383
385}
@ UNIT_NPC_FLAG_SPIRITHEALER
Definition UnitDefines.h:333
void SendSpiritResurrect()
Definition NPCHandler.cpp:387

References Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, Unit::RemoveAurasByType(), SendSpiritResurrect(), SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_SPIRITHEALER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleSplitItemOpcode()

void WorldSession::HandleSplitItemOpcode ( WorldPackets::Item::SplitItem packet)
35{
36 //LOG_DEBUG("network.opcode", "WORLD: CMSG_SPLIT_ITEM");
37
38 uint16 src = ((packet.SourceBag << 8) | packet.SourceSlot);
39 uint16 dst = ((packet.DestinationBag << 8) | packet.DestinationSlot);
40
41 if (src == dst)
42 return;
43
44 if (packet.Count == 0)
45 return; //check count - if zero it's fake packet
46
47 if (!_player->IsValidPos(packet.SourceBag, packet.SourceSlot, true))
48 {
50 return;
51 }
52
53 if (!_player->IsValidPos(packet.DestinationBag, packet.DestinationSlot, false)) // can be autostore pos
54 {
56 return;
57 }
58
59 _player->SplitItem(src, dst, packet.Count);
60}
void SplitItem(uint16 src, uint16 dst, uint32 count)
Definition PlayerStorage.cpp:3417
uint32 Count
Definition ItemPackets.h:40
uint8 SourceSlot
Definition ItemPackets.h:37
uint8 SourceBag
Definition ItemPackets.h:36
uint8 DestinationSlot
Definition ItemPackets.h:39
uint8 DestinationBag
Definition ItemPackets.h:38

References _player, WorldPackets::Item::SplitItem::Count, WorldPackets::Item::SplitItem::DestinationBag, WorldPackets::Item::SplitItem::DestinationSlot, EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, EQUIP_ERR_ITEM_NOT_FOUND, Player::IsValidPos(), Player::SendEquipError(), WorldPackets::Item::SplitItem::SourceBag, WorldPackets::Item::SplitItem::SourceSlot, and Player::SplitItem().

Referenced by OpcodeTable::Initialize().

◆ HandleStablePet()

void WorldSession::HandleStablePet ( WorldPacket recvPacket)
551{
552 LOG_DEBUG("network", "WORLD: Recv CMSG_STABLE_PET");
553 ObjectGuid npcGUID;
554
555 recvData >> npcGUID;
556
557 if (!GetPlayer()->IsAlive())
558 {
560 return;
561 }
562
563 if (!CheckStableMaster(npcGUID))
564 {
566 return;
567 }
568
569 // remove fake death
570 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
572
573 PetStable* petStable = GetPlayer()->GetPetStable();
574 if (!petStable)
575 return;
576
577 Pet* pet = _player->GetPet();
578
579 // can't place in stable dead pet
580 if ((pet && (!pet->IsAlive() || pet->getPetType() != HUNTER_PET))
581 || (!pet && (petStable->UnslottedPets.size() != 1 || !petStable->UnslottedPets[0].Health || petStable->UnslottedPets[0].Type != HUNTER_PET)))
582 {
584 return;
585 }
586
587 for (uint32 freeSlot = 0; freeSlot < petStable->MaxStabledPets; ++freeSlot)
588 {
589 if (!petStable->StabledPets[freeSlot])
590 {
591 if (pet)
592 {
593 // stable summoned pet
595 std::swap(petStable->StabledPets[freeSlot], petStable->CurrentPet);
597 return;
598 }
599
601 stmt->SetData(0, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + freeSlot));
602 stmt->SetData(1, _player->GetGUID().GetCounter());
603 stmt->SetData(2, petStable->UnslottedPets[0].PetNumber);
604 CharacterDatabase.Execute(stmt);
605
606 // stable unsummoned pet
607 petStable->StabledPets[freeSlot] = std::move(petStable->UnslottedPets.back());
608 petStable->UnslottedPets.pop_back();
610 return;
611 }
612 }
613
614 // not free stable slot
616}
@ CHAR_UPD_CHAR_PET_SLOT_BY_ID
Definition CharacterDatabase.h:485
@ STABLE_SUCCESS_STABLE
Definition NPCHandler.cpp:40
PetSaveMode
Definition PetDefines.h:41
@ PET_SAVE_FIRST_STABLE_SLOT
Definition PetDefines.h:44
std::array< Optional< PetInfo >, MAX_PET_STABLES > StabledPets
Definition PetDefines.h:236
std::vector< PetInfo > UnslottedPets
Definition PetDefines.h:238

References _player, CHAR_UPD_CHAR_PET_SLOT_BY_ID, CharacterDatabase, CheckStableMaster(), PetStable::CurrentPet, ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetPet(), Player::GetPetStable(), Pet::getPetType(), GetPlayer(), HUNTER_PET, Unit::IsAlive(), LOG_DEBUG, PetStable::MaxStabledPets, PET_SAVE_FIRST_STABLE_SLOT, Unit::RemoveAurasByType(), Player::RemovePet(), SendStableResult(), PreparedStatementBase::SetData(), SPELL_AURA_FEIGN_DEATH, STABLE_ERR_STABLE, STABLE_SUCCESS_STABLE, PetStable::StabledPets, UNIT_STATE_DIED, and PetStable::UnslottedPets.

Referenced by OpcodeTable::Initialize().

◆ HandleStableRevivePet()

void WorldSession::HandleStableRevivePet ( WorldPacket recvPacket)
767{
768 LOG_DEBUG("network", "HandleStableRevivePet: Not implemented");
769}

References LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleStableSwapPet()

void WorldSession::HandleStableSwapPet ( WorldPacket recvPacket)
772{
773 LOG_DEBUG("network", "WORLD: Recv CMSG_STABLE_SWAP_PET.");
774 ObjectGuid npcGUID;
775 uint32 petId;
776
777 recvData >> npcGUID >> petId;
778
779 if (!CheckStableMaster(npcGUID))
780 {
782 return;
783 }
784
785 // remove fake death
786 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
788
789 PetStable* petStable = GetPlayer()->GetPetStable();
790 if (!petStable)
791 {
793 return;
794 }
795
796 // Find swapped pet slot in stable
797 auto stabledPet = std::find_if(petStable->StabledPets.begin(), petStable->StabledPets.end(), [petId](Optional<PetStable::PetInfo> const& pet)
798 {
799 return pet && pet->PetNumber == petId;
800 });
801
802 if (stabledPet == petStable->StabledPets.end())
803 {
805 return;
806 }
807
808 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate((*stabledPet)->CreatureId);
809 if (!creatureInfo || !creatureInfo->IsTameable(_player->CanTameExoticPets()))
810 {
811 // if problem in exotic pet
812 if (creatureInfo && creatureInfo->IsTameable(true))
814 else
816 return;
817 }
818
819 Pet* oldPet = _player->GetPet();
820 if (oldPet)
821 {
822 if (!oldPet->IsAlive() || !oldPet->IsHunterPet())
823 {
825 return;
826 }
827
828 _player->RemovePet(oldPet, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + std::distance(petStable->StabledPets.begin(), stabledPet)));
829 }
830 else if (petStable->UnslottedPets.size() == 1)
831 {
832 if (petStable->CurrentPet || !petStable->UnslottedPets[0].Health || petStable->UnslottedPets[0].Type != HUNTER_PET)
833 {
835 return;
836 }
837
839 stmt->SetData(0, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + std::distance(petStable->StabledPets.begin(), stabledPet)));
840 stmt->SetData(1, _player->GetGUID().GetCounter());
841 stmt->SetData(2, petStable->UnslottedPets[0].PetNumber);
842 CharacterDatabase.Execute(stmt);
843
844 // move unsummoned pet into CurrentPet slot so that it gets moved into stable slot later
845 petStable->CurrentPet = std::move(petStable->UnslottedPets.back());
846 petStable->UnslottedPets.pop_back();
847 }
848 else if (petStable->CurrentPet || !petStable->UnslottedPets.empty())
849 {
851 return;
852 }
853
854 // summon unstabled pet
855 Pet* newPet = new Pet(_player, HUNTER_PET);
856 if (!newPet->LoadPetFromDB(_player, 0, petId, false))
857 {
858 delete newPet;
860
861 petStable->UnslottedPets.push_back(std::move(*petStable->CurrentPet));
862 petStable->CurrentPet.reset();
863
864 // update current pet slot in db immediately to maintain slot consistency, dismissed pet was already saved
867 stmt->SetData(1, _player->GetGUID().GetCounter());
868 stmt->SetData(2, petId);
869 CharacterDatabase.Execute(stmt);
870 }
871 else
872 {
873 // update current pet slot in db immediately to maintain slot consistency, dismissed pet was already saved
876 stmt->SetData(1, _player->GetGUID().GetCounter());
877 stmt->SetData(2, petId);
878 CharacterDatabase.Execute(stmt);
879
881 }
882}
@ STABLE_ERR_EXOTIC
Definition NPCHandler.cpp:43
@ STABLE_SUCCESS_UNSTABLE
Definition NPCHandler.cpp:41
bool LoadPetFromDB(Player *owner, uint32 petEntry, uint32 petnumber, bool current, uint32 healthPct=0, bool fullMana=false)
Definition Pet.cpp:216
bool CanTameExoticPets() const
Definition Player.h:2187
bool IsHunterPet() const
Definition Unit.h:788
bool IsTameable(bool exotic) const
Definition CreatureData.h:274

References _player, Player::CanTameExoticPets(), CHAR_UPD_CHAR_PET_SLOT_BY_ID, CharacterDatabase, CheckStableMaster(), PetStable::CurrentPet, ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetPet(), Player::GetPetStable(), GetPlayer(), HUNTER_PET, Unit::IsAlive(), Unit::IsHunterPet(), CreatureTemplate::IsTameable(), Pet::LoadPetFromDB(), LOG_DEBUG, PET_SAVE_AS_CURRENT, PET_SAVE_FIRST_STABLE_SLOT, PET_SAVE_NOT_IN_SLOT, Unit::RemoveAurasByType(), Player::RemovePet(), SendStableResult(), PreparedStatementBase::SetData(), sObjectMgr, SPELL_AURA_FEIGN_DEATH, STABLE_ERR_EXOTIC, STABLE_ERR_STABLE, STABLE_SUCCESS_UNSTABLE, PetStable::StabledPets, UNIT_STATE_DIED, and PetStable::UnslottedPets.

Referenced by OpcodeTable::Initialize().

◆ HandleStandStateChangeOpcode()

void WorldSession::HandleStandStateChangeOpcode ( WorldPacket recvPacket)
563{
564 uint32 animstate;
565 recv_data >> animstate;
566
567 switch (animstate)
568 {
573 break;
574 default:
575 return;
576 }
577
578 _player->SetStandState(animstate);
579}
@ UNIT_STAND_STATE_SLEEP
Definition UnitDefines.h:35
@ UNIT_STAND_STATE_KNEEL
Definition UnitDefines.h:40

References _player, Unit::SetStandState(), UNIT_STAND_STATE_KNEEL, UNIT_STAND_STATE_SIT, UNIT_STAND_STATE_SLEEP, and UNIT_STAND_STATE_STAND.

Referenced by OpcodeTable::Initialize().

◆ HandleSummonResponseOpcode()

void WorldSession::HandleSummonResponseOpcode ( WorldPacket recvData)
847{
848 if (!_player->IsAlive() || _player->IsInCombat())
849 return;
850
851 ObjectGuid summoner_guid;
852 bool agree;
853 recvData >> summoner_guid;
854 recvData >> agree;
855
856 if (agree && _player->IsSummonAsSpectator())
857 {
858 ChatHandler chc(this);
859 if (Player* summoner = ObjectAccessor::FindPlayer(summoner_guid))
860 ArenaSpectator::HandleSpectatorSpectateCommand(&chc, summoner->GetName().c_str());
861 else
862 chc.PSendSysMessage("Requested player not found.");
863
864 agree = false;
865 }
867 _player->SummonIfPossible(agree, summoner_guid);
868}
void SetSummonAsSpectator(bool on)
Definition Player.h:1101
void SummonIfPossible(bool agree, ObjectGuid summoner_guid)
Definition Player.cpp:12460
bool IsSummonAsSpectator() const
Definition Player.cpp:16347
AC_GAME_API bool HandleSpectatorSpectateCommand(ChatHandler *handler, std::string const &name)
Definition ArenaSpectator.cpp:29

References _player, ObjectAccessor::FindPlayer(), ArenaSpectator::HandleSpectatorSpectateCommand(), Unit::IsAlive(), Unit::IsInCombat(), Player::IsSummonAsSpectator(), ChatHandler::PSendSysMessage(), Player::SetSummonAsSpectator(), and Player::SummonIfPossible().

Referenced by OpcodeTable::Initialize().

◆ HandleSwapInvItemOpcode()

void WorldSession::HandleSwapInvItemOpcode ( WorldPackets::Item::SwapInventoryItem packet)
63{
64 //LOG_DEBUG("network.opcode", "WORLD: CMSG_SWAP_INV_ITEM");
65
66 // prevent attempt swap same item to current position generated by client at special cheating sequence
67 if (packet.SourceSlot == packet.DestinationSlot)
68 return;
69
71 {
73 return;
74 }
75
77 {
79 return;
80 }
81
83 {
84 //LOG_DEBUG("network", "WORLD: HandleSwapInvItemOpcode - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
85 return;
86 }
87
89 {
90 //LOG_DEBUG("network", "WORLD: HandleSwapInvItemOpcode - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
91 return;
92 }
93
94 uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | packet.SourceSlot);
95 uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | packet.DestinationSlot);
96
97 _player->SwapItem(src, dst);
98}
uint8 SourceSlot
Definition ItemPackets.h:51
uint8 DestinationSlot
Definition ItemPackets.h:50

References _player, CanUseBank(), WorldPackets::Item::SwapInventoryItem::DestinationSlot, EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, EQUIP_ERR_ITEM_NOT_FOUND, INVENTORY_SLOT_BAG_0, Player::IsBankPos(), Player::IsValidPos(), Player::SendEquipError(), WorldPackets::Item::SwapInventoryItem::SourceSlot, and Player::SwapItem().

Referenced by OpcodeTable::Initialize().

◆ HandleSwapItem()

void WorldSession::HandleSwapItem ( WorldPackets::Item::SwapItem packet)
116{
117 //LOG_DEBUG("network.opcode", "WORLD: CMSG_SWAP_ITEM");
118
119 uint16 src = ((packet.SourceBag << 8) | packet.SourceSlot);
120 uint16 dst = ((packet.DestinationBag << 8) | packet.DestinationSlot);
121
122 // prevent attempt swap same item to current position generated by client at special cheating sequence
123 if (src == dst)
124 return;
125
126 if (!_player->IsValidPos(packet.SourceBag, packet.SourceSlot, true))
127 {
129 return;
130 }
131
132 if (!_player->IsValidPos(packet.DestinationBag, packet.DestinationSlot, true))
133 {
135 return;
136 }
137
138 if (_player->IsBankPos(packet.SourceBag, packet.SourceSlot) && !CanUseBank())
139 {
140 //LOG_DEBUG("network", "WORLD: HandleSwapItem - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
141 return;
142 }
143
144 if (_player->IsBankPos(packet.DestinationBag, packet.DestinationSlot) && !CanUseBank())
145 {
146 //LOG_DEBUG("network", "WORLD: HandleSwapItem - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
147 return;
148 }
149
150 _player->SwapItem(src, dst);
151}
uint8 DestinationSlot
Definition ItemPackets.h:73
uint8 SourceBag
Definition ItemPackets.h:74
uint8 DestinationBag
Definition ItemPackets.h:72
uint8 SourceSlot
Definition ItemPackets.h:75

References _player, CanUseBank(), WorldPackets::Item::SwapItem::DestinationBag, WorldPackets::Item::SwapItem::DestinationSlot, EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, EQUIP_ERR_ITEM_NOT_FOUND, Player::IsBankPos(), Player::IsValidPos(), Player::SendEquipError(), WorldPackets::Item::SwapItem::SourceBag, WorldPackets::Item::SwapItem::SourceSlot, and Player::SwapItem().

Referenced by OpcodeTable::Initialize().

◆ HandleTabardVendorActivateOpcode()

void WorldSession::HandleTabardVendorActivateOpcode ( WorldPacket recvPacket)
47{
48 ObjectGuid guid;
49 recvData >> guid;
50
52 if (!unit)
53 {
54 LOG_DEBUG("network", "WORLD: HandleTabardVendorActivateOpcode - Unit ({}) not found or you can not interact with him.", guid.ToString());
55 return;
56 }
57
58 // remove fake death
59 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
61
63}
void SendTabardVendorActivate(ObjectGuid guid)
Definition NPCHandler.cpp:65

References Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, Unit::RemoveAurasByType(), SendTabardVendorActivate(), SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_TABARDDESIGNER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleTalentWipeConfirmOpcode()

void WorldSession::HandleTalentWipeConfirmOpcode ( WorldPacket recvPacket)
59{
60 LOG_DEBUG("network", "MSG_TALENT_WIPE_CONFIRM");
61 ObjectGuid guid;
62 recvData >> guid;
63
65 if (!unit)
66 {
67 LOG_DEBUG("network", "WORLD: HandleTalentWipeConfirmOpcode - Unit ({}) not found or you can't interact with him.", guid.ToString());
68 return;
69 }
70
72 return;
73
74 // remove fake death
75 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
77
78 if (!(_player->resetTalents()))
79 {
80 WorldPacket data(MSG_TALENT_WIPE_CONFIRM, 8 + 4); //you have not any talent
81 data << uint64(0);
82 data << uint32(0);
83 SendPacket(&data);
84 return;
85 }
86
88 unit->CastSpell(_player, 14867, true); //spell: "Untalent Visual Effect"
89}
@ UNIT_NPC_FLAG_TRAINER
Definition UnitDefines.h:323
bool isCanTrainingAndResetTalentsOf(Player *player) const
Definition Creature.cpp:1267
@ MSG_TALENT_WIPE_CONFIRM
Definition Opcodes.h:712

References _player, Unit::CastSpell(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Creature::isCanTrainingAndResetTalentsOf(), LOG_DEBUG, MSG_TALENT_WIPE_CONFIRM, Unit::RemoveAurasByType(), Player::resetTalents(), SendPacket(), Player::SendTalentsInfoData(), SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_TRAINER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleTaxiNodeStatusQueryOpcode()

void WorldSession::HandleTaxiNodeStatusQueryOpcode ( WorldPacket recvPacket)
28{
29 ObjectGuid guid;
30
31 recvData >> guid;
32 SendTaxiStatus(guid);
33}
void SendTaxiStatus(ObjectGuid guid)
Definition TaxiHandler.cpp:35

References SendTaxiStatus().

Referenced by OpcodeTable::Initialize().

◆ HandleTaxiQueryAvailableNodes()

void WorldSession::HandleTaxiQueryAvailableNodes ( WorldPacket recvPacket)
60{
61 ObjectGuid guid;
62 recvData >> guid;
63
64 // cheating checks
66 if (!unit)
67 {
68 LOG_DEBUG("network", "WORLD: HandleTaxiQueryAvailableNodes - Unit ({}) not found or you can't interact with him.", guid.ToString());
69 return;
70 }
71
72 // remove fake death
73 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
75
76 // unknown taxi node case
77 if (SendLearnNewTaxiNode(unit))
78 return;
79
80 // known taxi node case
81 SendTaxiMenu(unit);
82}
bool SendLearnNewTaxiNode(Creature *unit)
Definition TaxiHandler.cpp:127
void SendTaxiMenu(Creature *unit)
Definition TaxiHandler.cpp:84

References Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, Unit::RemoveAurasByType(), SendLearnNewTaxiNode(), SendTaxiMenu(), SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_FLIGHTMASTER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleTeleportTimeout()

void WorldSession::HandleTeleportTimeout ( bool  updateInSessions)
581{
582 // pussywizard: handle teleport ack timeout
583 if (m_Socket && m_Socket->IsOpen() && GetPlayer() && GetPlayer()->IsBeingTeleported())
584 {
585 time_t currTime = GameTime::GetGameTime().count();
586 if (updateInSessions) // session update from World::UpdateSessions
587 {
588 if (GetPlayer()->IsBeingTeleportedFar() && GetPlayer()->GetSemaphoreTeleportFar() + sWorld->getIntConfig(CONFIG_TELEPORT_TIMEOUT_FAR) < currTime)
589 while (GetPlayer() && GetPlayer()->IsBeingTeleportedFar())
591 }
592 else // session update from Map::Update
593 {
594 if (GetPlayer()->IsBeingTeleportedNear() && GetPlayer()->GetSemaphoreTeleportNear() + sWorld->getIntConfig(CONFIG_TELEPORT_TIMEOUT_NEAR) < currTime)
595 while (GetPlayer() && GetPlayer()->IsInWorld() && GetPlayer()->IsBeingTeleportedNear())
596 {
597 Player* plMover = GetPlayer()->m_mover->ToPlayer();
598 if (!plMover)
599 break;
601 pkt << plMover->GetPackGUID();
602 pkt << uint32(0); // flags
603 pkt << uint32(0); // time
605 }
606 }
607 }
608}
@ CONFIG_TELEPORT_TIMEOUT_FAR
Definition WorldConfig.h:303
@ CONFIG_TELEPORT_TIMEOUT_NEAR
Definition WorldConfig.h:302
void HandleMoveTeleportAck(WorldPacket &recvPacket)
Definition MovementHandler.cpp:273

References CONFIG_TELEPORT_TIMEOUT_FAR, CONFIG_TELEPORT_TIMEOUT_NEAR, GameTime::GetGameTime(), Object::GetPackGUID(), GetPlayer(), HandleMoveTeleportAck(), HandleMoveWorldportAck(), Player::m_mover, m_Socket, MSG_MOVE_TELEPORT_ACK, sWorld, and Object::ToPlayer().

Referenced by Update().

◆ HandleTextEmoteOpcode()

void WorldSession::HandleTextEmoteOpcode ( WorldPacket recvPacket)
685{
686 if (!GetPlayer()->IsAlive())
687 return;
688
690
691 if (!GetPlayer()->CanSpeak())
692 {
693 std::string timeStr = secsToTimeString(m_muteTime - GameTime::GetGameTime().count());
695 return;
696 }
697
698 if (GetPlayer()->IsSpectator())
699 return;
700
701 uint32 text_emote, emoteNum;
702 ObjectGuid guid;
703
704 recvData >> text_emote;
705 recvData >> emoteNum;
706 recvData >> guid;
707
708 sScriptMgr->OnPlayerTextEmote(GetPlayer(), text_emote, emoteNum, guid);
709
710 EmotesTextEntry const* em = sEmotesTextStore.LookupEntry(text_emote);
711 if (!em)
712 return;
713
714 uint32 emote_anim = em->textid;
715
716 switch (emote_anim)
717 {
719 case EMOTE_STATE_SIT:
722 break;
725 break;
726 default:
727 // Only allow text-emotes for "dead" entities (feign death included)
728 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
729 break;
730 GetPlayer()->HandleEmoteCommand(emote_anim);
731 break;
732 }
733
734 Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
735
736 Acore::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit);
739 Cell::VisitObjects(GetPlayer(), emote_worker, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
740
742
743 //Send scripted event call
744 if (unit && unit->IsCreature() && ((Creature*)unit)->AI())
745 ((Creature*)unit)->AI()->ReceiveEmote(GetPlayer(), text_emote);
746}
@ ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE
Definition DBCEnums.h:168
DBCStorage< EmotesTextEntry > sEmotesTextStore(EmotesTextEntryfmt)
@ EMOTE_STATE_SLEEP
Definition SharedDefines.h:1915
@ EMOTE_STATE_SIT
Definition SharedDefines.h:1916
@ EMOTE_STATE_KNEEL
Definition SharedDefines.h:1954
@ EMOTE_STATE_DANCE
Definition SharedDefines.h:1913
@ UNIT_NPC_EMOTESTATE
Definition UpdateFields.h:140
@ CONFIG_LISTEN_RANGE_TEXTEMOTE
Definition WorldConfig.h:152
Definition ChatHandler.cpp:655
Definition GridNotifiers.h:1737
Definition GridNotifiers.h:583
static void VisitObjects(WorldObject const *obj, T &visitor, float radius)
Definition CellImpl.h:165
Definition DBCStructure.h:901
uint32 textid
Definition DBCStructure.h:903
@ REGULAR
Definition Player.h:2331

References _player, ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, CONFIG_LISTEN_RANGE_TEXTEMOTE, EMOTE_ONESHOT_NONE, EMOTE_STATE_DANCE, EMOTE_STATE_KNEEL, EMOTE_STATE_SIT, EMOTE_STATE_SLEEP, GameTime::GetGameTime(), GetPlayer(), ObjectAccessor::GetUnit(), Unit::HandleEmoteCommand(), Object::IsCreature(), LANG_WAIT_BEFORE_SPEAKING, m_muteTime, Player::ChatFloodThrottle::REGULAR, secsToTimeString(), sEmotesTextStore, ChatHandler::SendNotification(), Unit::SetUInt32Value(), sScriptMgr, sWorld, EmotesTextEntry::textid, UNIT_NPC_EMOTESTATE, UNIT_STATE_DIED, Player::UpdateAchievementCriteria(), Player::UpdateSpeakTime(), and Cell::VisitObjects().

Referenced by OpcodeTable::Initialize().

◆ HandleTimeQueryOpcode()

void WorldSession::HandleTimeQueryOpcode ( WorldPackets::Query::TimeQuery packet)

◆ HandleTimeSyncResp()

void WorldSession::HandleTimeSyncResp ( WorldPacket recvData)
903{
904 LOG_DEBUG("network", "CMSG_TIME_SYNC_RESP");
905
906 uint32 counter, clientTimestamp;
907 recvData >> counter >> clientTimestamp;
908
909 if (_pendingTimeSyncRequests.count(counter) == 0)
910 return;
911
912 uint32 serverTimeAtSent = _pendingTimeSyncRequests.at(counter);
913 _pendingTimeSyncRequests.erase(counter);
914
915 // time it took for the request to travel to the client, for the client to process it and reply and for response to travel back to the server.
916 // we are going to make 2 assumptions:
917 // 1) we assume that the request processing time equals 0.
918 // 2) we assume that the packet took as much time to travel from server to client than it took to travel from client to server.
919 uint32 roundTripDuration = getMSTimeDiff(serverTimeAtSent, recvData.GetReceivedTime());
920 uint32 lagDelay = roundTripDuration / 2;
921
922 // clockDelta = serverTime - clientTime
923 // where
924 // serverTime: time that was displayed on the clock of the SERVER at the moment when the client processed the SMSG_TIME_SYNC_REQUEST packet.
925 // clientTime: time that was displayed on the clock of the CLIENT at the moment when the client processed the SMSG_TIME_SYNC_REQUEST packet.
926
927 // Once clockDelta has been computed, we can compute the time of an event on server clock when we know the time of that same event on the client clock,
928 // using the following relation:
929 // serverTime = clockDelta + clientTime
930
931 int64 clockDelta = (int64)serverTimeAtSent + (int64)lagDelay - (int64)clientTimestamp;
932 _timeSyncClockDeltaQueue.put(std::pair<int64, uint32>(clockDelta, roundTripDuration));
934}
void put(T item)
Definition CircularBuffer.h:27
TimePoint GetReceivedTime() const
Definition WorldPacket.h:78
void ComputeNewClockDelta()
Definition MovementHandler.cpp:936

References _pendingTimeSyncRequests, _timeSyncClockDeltaQueue, ComputeNewClockDelta(), getMSTimeDiff(), WorldPacket::GetReceivedTime(), LOG_DEBUG, and CircularBuffer< T >::put().

Referenced by OpcodeTable::Initialize().

◆ HandleTogglePvP()

void WorldSession::HandleTogglePvP ( WorldPacket recvPacket)
503{
504 // this opcode can be used in two ways: Either set explicit new status or toggle old status
505 if (recv_data.size() == 1)
506 {
507 bool newPvPStatus;
508 recv_data >> newPvPStatus;
510 }
511 else
513
514 if (GetPlayer()->HasPlayerFlag(PLAYER_FLAGS_IN_PVP))
515 GetPlayer()->UpdatePvP(true, true);
516 else if (!GetPlayer()->pvpInfo.IsHostile && GetPlayer()->IsPvP()) // pussywizard: in pvp mode, but doesn't want to be and not in hostile territory, so start timer
517 GetPlayer()->UpdatePvP(true, false);
518
519 //if (OutdoorPvP* pvp = _player->GetOutdoorPvP())
520 // pvp->HandlePlayerActivityChanged(_player);
521}
@ PLAYER_FLAGS
Definition UpdateFields.h:178
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition Object.cpp:881
void ToggleFlag(uint16 index, uint32 flag)
Definition Object.cpp:859

References Object::ApplyModFlag(), GetPlayer(), PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP, ByteBuffer::size(), Object::ToggleFlag(), and Player::UpdatePvP().

Referenced by OpcodeTable::Initialize().

◆ HandleTotemDestroyed()

void WorldSession::HandleTotemDestroyed ( WorldPackets::Totem::TotemDestroyed totemDestroyed)
683{
684 // ignore for remote control state
685 if (_player->m_mover != _player)
686 return;
687
688 uint8 slotId = totemDestroyed.Slot;
689 slotId += SUMMON_SLOT_TOTEM_FIRE;
690
691 if (slotId >= MAX_TOTEM_SLOT)
692 return;
693
694 if (!_player->m_SummonSlot[slotId])
695 return;
696
697 Creature* totem = GetPlayer()->GetMap()->GetCreature(_player->m_SummonSlot[slotId]);
698 // Don't unsummon sentry totem
699 if (totem && totem->IsTotem())
700 totem->ToTotem()->UnSummon();
701}
#define MAX_TOTEM_SLOT
Definition SharedDefines.h:3572
@ SUMMON_SLOT_TOTEM_FIRE
Definition SharedDefines.h:3562
void UnSummon(Milliseconds msTime=0ms) override
Definition Totem.cpp:122
Totem * ToTotem()
Definition Unit.h:720
bool IsTotem() const
Definition Unit.h:789
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition Unit.h:2061
uint8 Slot
Definition TotemPackets.h:35

References _player, Map::GetCreature(), WorldObject::GetMap(), GetPlayer(), Unit::IsTotem(), Player::m_mover, Unit::m_SummonSlot, MAX_TOTEM_SLOT, WorldPackets::Totem::TotemDestroyed::Slot, SUMMON_SLOT_TOTEM_FIRE, Unit::ToTotem(), and Totem::UnSummon().

Referenced by OpcodeTable::Initialize().

◆ HandleTrainerBuySpellOpcode()

void WorldSession::HandleTrainerBuySpellOpcode ( WorldPacket recvPacket)
213{
214 ObjectGuid guid;
215 uint32 spellId = 0;
216
217 recvData >> guid >> spellId;
218
220 if (!unit)
221 {
222 LOG_DEBUG("network", "WORLD: HandleTrainerBuySpellOpcode - Unit ({}) not found or you can not interact with him.", guid.ToString());
223 return;
224 }
225
226 // remove fake death
227 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
229
230 // check present spell in trainer spell list
231 TrainerSpellData const* trainer_spells = unit->GetTrainerSpells();
232 if (!trainer_spells)
233 return;
234
235 // not found, cheat?
236 TrainerSpell const* trainer_spell = trainer_spells->Find(spellId);
237 if (!trainer_spell)
238 return;
239
240 if (trainer_spell->reqSpell && !_player->HasSpell(trainer_spell->reqSpell))
241 {
242 return;
243 }
244
245 // can't be learn, cheat? Or double learn with lags...
246 if (_player->GetTrainerSpellState(trainer_spell) != TRAINER_SPELL_GREEN)
247 return;
248
249 // apply reputation discount
250 uint32 nSpellCost = uint32(std::floor(trainer_spell->spellCost * _player->GetReputationPriceDiscount(unit)));
251
252 // check money requirement
253 if (!_player->HasEnoughMoney(nSpellCost))
254 return;
255
256 _player->ModifyMoney(-int32(nSpellCost));
257
258 unit->SendPlaySpellVisual(179); // 53 SpellCastDirected
259 unit->SendPlaySpellImpact(_player->GetGUID(), 362); // 113 EmoteSalute
260
261 // learn explicitly or cast explicitly
262 if (trainer_spell->IsCastable())
263 _player->CastSpell(_player, trainer_spell->spell, true);
264 else
265 _player->learnSpell(spellId);
266
268 data << guid;
269 data << uint32(spellId); // should be same as in packet from client
270 SendPacket(&data);
271}
@ TRAINER_SPELL_GREEN
Definition Player.h:215
TrainerSpellData const * GetTrainerSpells() const
Definition Creature.cpp:3146
void learnSpell(uint32 spellId, bool temporary=false, bool learnFromSkill=false)
Definition Player.cpp:3298
TrainerSpellState GetTrainerSpellState(TrainerSpell const *trainer_spell) const
Definition Player.cpp:3904
void SendPlaySpellVisual(uint32 id)
Definition Unit.cpp:19158
void SendPlaySpellImpact(ObjectGuid guid, uint32 id)
Definition Unit.cpp:19166
@ SMSG_TRAINER_BUY_SUCCEEDED
Definition Opcodes.h:465
Definition CreatureData.h:529
TrainerSpell const * Find(uint32 spell_id) const
Definition Creature.cpp:84
Definition CreatureData.h:507
bool IsCastable() const
Definition CreatureData.h:523
uint32 reqSpell
Definition CreatureData.h:520
uint32 spellCost
Definition CreatureData.h:515
uint32 spell
Definition CreatureData.h:514

References _player, Unit::CastSpell(), TrainerSpellData::Find(), Object::GetGUID(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Player::GetReputationPriceDiscount(), Creature::GetTrainerSpells(), Player::GetTrainerSpellState(), Player::HasEnoughMoney(), Player::HasSpell(), TrainerSpell::IsCastable(), Player::learnSpell(), LOG_DEBUG, Player::ModifyMoney(), Unit::RemoveAurasByType(), TrainerSpell::reqSpell, SendPacket(), Unit::SendPlaySpellImpact(), Unit::SendPlaySpellVisual(), SMSG_TRAINER_BUY_SUCCEEDED, TrainerSpell::spell, SPELL_AURA_FEIGN_DEATH, TrainerSpell::spellCost, ObjectGuid::ToString(), TRAINER_SPELL_GREEN, UNIT_NPC_FLAG_TRAINER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleTrainerListOpcode()

void WorldSession::HandleTrainerListOpcode ( WorldPacket recvPacket)
80{
81 ObjectGuid guid;
82
83 recvData >> guid;
84 SendTrainerList(guid);
85}
void SendTrainerList(ObjectGuid guid)
Definition NPCHandler.cpp:87

References SendTrainerList().

Referenced by OpcodeTable::Initialize().

◆ HandleTurnInPetitionOpcode()

void WorldSession::HandleTurnInPetitionOpcode ( WorldPacket recvData)
646{
647 LOG_DEBUG("network", "Received opcode CMSG_TURN_IN_PETITION");
648
649 // Get petition guid from packet
650 WorldPacket data;
651 ObjectGuid petitionGuid;
652
653 recvData >> petitionGuid;
654
655 // Check if player really has the required petition charter
656 Item* item = _player->GetItemByGuid(petitionGuid);
657 if (!item)
658 return;
659
660 LOG_DEBUG("network", "Petition {} turned in by {}", petitionGuid.ToString(), _player->GetGUID().ToString());
661
662 Petition const* petition = sPetitionMgr->GetPetition(petitionGuid);
663 if (!petition)
664 {
665 LOG_ERROR("network.opcode", "Player {} ({}) tried to turn in petition ({}) that is not present in the database",
666 _player->GetName(), _player->GetGUID().ToString(), petitionGuid.ToString());
667 return;
668 }
669
670 ObjectGuid ownerGuid = petition->ownerGuid;
671 uint8 type = petition->petitionType;
672 std::string name = petition->petitionName;
673
674 // Only the petition owner can turn in the petition
675 if (_player->GetGUID() != ownerGuid)
676 return;
677
678 // Petition type (guild/arena) specific checks
679 if (type == GUILD_CHARTER_TYPE)
680 {
681 // Check if player is already in a guild
682 if (_player->GetGuildId())
683 {
686 SendPacket(&data);
687 return;
688 }
689
690 // Check if guild name is already taken
691 if (sGuildMgr->GetGuildByName(name))
692 {
694 return;
695 }
696 }
697 else
698 {
699 // Check for valid arena bracket (2v2, 3v3, 5v5)
700 uint8 slot = ArenaTeam::GetSlotByType(type);
701 if (slot >= MAX_ARENA_SLOT)
702 return;
703
704 // Check if player is already in an arena team
705 if (_player->GetArenaTeamId(slot))
706 {
708 return;
709 }
710
711 // Check if arena team name is already taken
712 if (sArenaTeamMgr->GetArenaTeamByName(name))
713 {
715 return;
716 }
717 }
718
719 // Get petition signatures from db
720 Signatures const* signatures = sPetitionMgr->GetSignature(petitionGuid);
721 uint8 signs = signatures ? signatures->signatureMap.size() : 0;
722 SignatureMap signatureCopy;
723 if (signs)
724 signatureCopy = signatures->signatureMap;
725
726 uint32 requiredSignatures;
727 if (type == GUILD_CHARTER_TYPE)
728 requiredSignatures = sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS);
729 else
730 requiredSignatures = type - 1;
731
732 // Notify player if signatures are missing
733 if (signs < requiredSignatures)
734 {
737 SendPacket(&data);
738 return;
739 }
740
741 // Proceed with guild/arena team creation
742
743 // Delete charter item
744 _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
745
746 if (type == GUILD_CHARTER_TYPE)
747 {
748 // Create guild
749 Guild* guild = new Guild;
750
751 if (!guild->Create(_player, name))
752 {
753 delete guild;
754 return;
755 }
756
757 // Register guild and add guild master
758 sGuildMgr->AddGuild(guild);
759
761
762 // Add members from signatures
763 if (signs)
764 for (SignatureMap::const_iterator itr = signatureCopy.begin(); itr != signatureCopy.end(); ++itr)
765 guild->AddMember(itr->first);
766 }
767 else
768 {
769 // Receive the rest of the packet in arena team creation case
770 uint32 background, icon, iconcolor, border, bordercolor;
771 recvData >> background >> icon >> iconcolor >> border >> bordercolor;
772
773 // Create arena team
774 ArenaTeam* arenaTeam = new ArenaTeam();
775
776 if (!arenaTeam->Create(_player->GetGUID(), type, name, background, icon, iconcolor, border, bordercolor))
777 {
778 delete arenaTeam;
779 return;
780 }
781
782 // Register arena team
783 sArenaTeamMgr->AddArenaTeam(arenaTeam);
784 LOG_DEBUG("network", "PetitonsHandler: Arena team (guid: {}) added to ObjectMgr", arenaTeam->GetId());
785
786 // Add members
787 if (signs)
788 for (SignatureMap::const_iterator itr = signatureCopy.begin(); itr != signatureCopy.end(); ++itr)
789 {
790 LOG_DEBUG("network", "PetitionsHandler: Adding arena team (guid: {}) member {}", arenaTeam->GetId(), itr->first.ToString());
791 arenaTeam->AddMember(itr->first);
792 }
793 }
794
795 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
796
798 stmt->SetData(0, petition->petitionId);
799 trans->Append(stmt);
800
801 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_SIGNATURE_BY_ID);
802 stmt->SetData(0, petition->petitionId);
803 trans->Append(stmt);
804
805 CharacterDatabase.CommitTransaction(trans);
806
807 // xinef: clear petition store (petition and signatures)
808 sPetitionMgr->RemovePetition(petitionGuid);
809
810 // created
811 LOG_DEBUG("network", "TURN IN PETITION {}", petitionGuid.ToString());
812
814 data << (uint32)PETITION_TURN_OK;
815 SendPacket(&data);
816}
@ CHAR_DEL_PETITION_BY_ID
Definition CharacterDatabase.h:384
@ CHAR_DEL_PETITION_SIGNATURE_BY_ID
Definition CharacterDatabase.h:385
@ ERR_GUILD_COMMAND_SUCCESS
Definition Guild.h:119
@ PETITION_TURN_NEED_MORE_SIGNATURES
Definition Guild.h:173
@ PETITION_TURN_ALREADY_IN_GUILD
Definition Guild.h:172
@ PETITION_TURN_OK
Definition Guild.h:171
std::map< ObjectGuid, uint32 > SignatureMap
Definition PetitionMgr.h:37
@ CONFIG_MIN_PETITION_SIGNS
Definition WorldConfig.h:207
bool Create(ObjectGuid captainGuid, uint8 type, std::string const &teamName, uint32 backgroundColor, uint8 emblemStyle, uint32 emblemColor, uint8 borderStyle, uint32 borderColor)
Definition ArenaTeam.cpp:50
bool Create(Player *pLeader, std::string_view name)
Definition Guild.cpp:1049
bool AddMember(ObjectGuid guid, uint8 rankId=GUILD_RANK_NONE)
Definition Guild.cpp:2178
@ SMSG_TURN_IN_PETITION_RESULTS
Definition Opcodes.h:483
std::string petitionName
Definition PetitionMgr.h:50

References _player, Guild::AddMember(), ArenaTeam::AddMember(), CHAR_DEL_PETITION_BY_ID, CHAR_DEL_PETITION_SIGNATURE_BY_ID, CharacterDatabase, CONFIG_MIN_PETITION_SIGNS, ArenaTeam::Create(), Guild::Create(), Player::DestroyItem(), ERR_ALREADY_IN_ARENA_TEAM, ERR_ARENA_TEAM_CREATE_S, ERR_ARENA_TEAM_NAME_EXISTS_S, ERR_GUILD_COMMAND_SUCCESS, ERR_GUILD_NAME_EXISTS_S, Player::GetArenaTeamId(), Item::GetBagSlot(), Object::GetGUID(), Player::GetGuildId(), ArenaTeam::GetId(), Player::GetItemByGuid(), WorldObject::GetName(), Item::GetSlot(), ArenaTeam::GetSlotByType(), GUILD_CHARTER_TYPE, GUILD_COMMAND_CREATE, WorldPacket::Initialize(), LOG_DEBUG, LOG_ERROR, MAX_ARENA_SLOT, Petition::ownerGuid, PETITION_TURN_ALREADY_IN_GUILD, PETITION_TURN_NEED_MORE_SIGNATURES, PETITION_TURN_OK, Petition::petitionId, Petition::petitionName, Petition::petitionType, sArenaTeamMgr, SendArenaTeamCommandResult(), Guild::SendCommandResult(), SendPacket(), PreparedStatementBase::SetData(), sGuildMgr, Signatures::signatureMap, SMSG_TURN_IN_PETITION_RESULTS, sPetitionMgr, sWorld, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleTutorialClear()

void WorldSession::HandleTutorialClear ( WorldPacket recvData)
1300{
1301 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
1302 SetTutorialInt(i, 0xFFFFFFFF);
1303}
#define MAX_ACCOUNT_TUTORIAL_VALUES
Definition Common.h:134
void SetTutorialInt(uint8 index, uint32 value)
Definition WorldSession.h:521

References MAX_ACCOUNT_TUTORIAL_VALUES, and SetTutorialInt().

Referenced by OpcodeTable::Initialize().

◆ HandleTutorialFlag()

void WorldSession::HandleTutorialFlag ( WorldPacket recvData)
1284{
1285 uint32 data;
1286 recvData >> data;
1287
1288 uint8 index = uint8(data / 32);
1289 if (index >= MAX_ACCOUNT_TUTORIAL_VALUES)
1290 return;
1291
1292 uint32 value = (data % 32);
1293
1294 uint32 flag = GetTutorialInt(index);
1295 flag |= (1 << value);
1296 SetTutorialInt(index, flag);
1297}
uint32 GetTutorialInt(uint8 index) const
Definition WorldSession.h:520

References GetTutorialInt(), MAX_ACCOUNT_TUTORIAL_VALUES, and SetTutorialInt().

Referenced by OpcodeTable::Initialize().

◆ HandleTutorialReset()

void WorldSession::HandleTutorialReset ( WorldPacket recvData)
1306{
1307 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
1308 SetTutorialInt(i, 0x00000000);
1309}

References MAX_ACCOUNT_TUTORIAL_VALUES, and SetTutorialInt().

Referenced by OpcodeTable::Initialize().

◆ HandleUnacceptTradeOpcode()

void WorldSession::HandleUnacceptTradeOpcode ( WorldPacket recvPacket)
509{
510 TradeData* my_trade = _player->GetTradeData();
511 if (!my_trade)
512 return;
513
514 my_trade->SetAccepted(false, true);
515}

References _player, Player::GetTradeData(), and TradeData::SetAccepted().

Referenced by OpcodeTable::Initialize().

◆ HandleUnlearnSkillOpcode()

void WorldSession::HandleUnlearnSkillOpcode ( WorldPacket recvPacket)
92{
93 uint32 skillId;
94 recvData >> skillId;
95
96 if (!IsPrimaryProfessionSkill(skillId))
97 return;
98
99 GetPlayer()->SetSkill(skillId, 0, 0, 0);
100}
bool IsPrimaryProfessionSkill(uint32 skill)
Definition SpellMgr.cpp:33
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition Player.cpp:5399

References GetPlayer(), IsPrimaryProfessionSkill(), and Player::SetSkill().

Referenced by OpcodeTable::Initialize().

◆ HandleUnstablePet()

void WorldSession::HandleUnstablePet ( WorldPacket recvPacket)
619{
620 LOG_DEBUG("network", "WORLD: Recv CMSG_UNSTABLE_PET.");
621 ObjectGuid npcGUID;
622 uint32 petnumber;
623
624 recvData >> npcGUID >> petnumber;
625
626 if (!CheckStableMaster(npcGUID))
627 {
629 return;
630 }
631
632 // remove fake death
633 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
635
636 PetStable* petStable = GetPlayer()->GetPetStable();
637 if (!petStable)
638 {
640 return;
641 }
642
643 auto stabledPet = std::find_if(petStable->StabledPets.begin(), petStable->StabledPets.end(), [petnumber](Optional<PetStable::PetInfo> const& pet)
644 {
645 return pet && pet->PetNumber == petnumber;
646 });
647
648 if (stabledPet == petStable->StabledPets.end())
649 {
651 return;
652 }
653
654 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate((*stabledPet)->CreatureId);
655 if (!creatureInfo || !creatureInfo->IsTameable(_player->CanTameExoticPets()))
656 {
657 // if problem in exotic pet
658 if (creatureInfo && creatureInfo->IsTameable(true))
660 else
662
663 return;
664 }
665
666 Pet* oldPet = _player->GetPet();
667 if (oldPet)
668 {
669 // try performing a swap, client sends this packet instead of swap when starting from stabled slot
670 if (!oldPet->IsAlive() || !oldPet->IsHunterPet())
671 {
673 return;
674 }
675
676 _player->RemovePet(oldPet, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + std::distance(petStable->StabledPets.begin(), stabledPet)));
677 }
678 else if (petStable->UnslottedPets.size() == 1)
679 {
680 if (petStable->CurrentPet || !petStable->UnslottedPets[0].Health || petStable->UnslottedPets[0].Type != HUNTER_PET)
681 {
683 return;
684 }
685
687 stmt->SetData(0, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + std::distance(petStable->StabledPets.begin(), stabledPet)));
688 stmt->SetData(1, _player->GetGUID().GetCounter());
689 stmt->SetData(2, petStable->UnslottedPets[0].PetNumber);
690 CharacterDatabase.Execute(stmt);
691
692 // move unsummoned pet into CurrentPet slot so that it gets moved into stable slot later
693 petStable->CurrentPet = std::move(petStable->UnslottedPets.back());
694 petStable->UnslottedPets.pop_back();
695 }
696 else if (petStable->CurrentPet || !petStable->UnslottedPets.empty())
697 {
699 return;
700 }
701
702 Pet* newPet = new Pet(_player, HUNTER_PET);
703 if (!newPet->LoadPetFromDB(_player, 0, petnumber, false))
704 {
705 delete newPet;
706
707 petStable->UnslottedPets.push_back(std::move(*petStable->CurrentPet));
708 petStable->CurrentPet.reset();
709
710 // update current pet slot in db immediately to maintain slot consistency, dismissed pet was already saved
713 stmt->SetData(1, _player->GetGUID().GetCounter());
714 stmt->SetData(2, petnumber);
715 CharacterDatabase.Execute(stmt);
716
718 }
719 else
720 {
721 // update current pet slot in db immediately to maintain slot consistency, dismissed pet was already saved
724 stmt->SetData(1, _player->GetGUID().GetCounter());
725 stmt->SetData(2, petnumber);
726 CharacterDatabase.Execute(stmt);
727
729 }
730}

References _player, Player::CanTameExoticPets(), CHAR_UPD_CHAR_PET_SLOT_BY_ID, CharacterDatabase, CheckStableMaster(), PetStable::CurrentPet, ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetPet(), Player::GetPetStable(), GetPlayer(), HUNTER_PET, Unit::IsAlive(), Unit::IsHunterPet(), CreatureTemplate::IsTameable(), Pet::LoadPetFromDB(), LOG_DEBUG, PET_SAVE_AS_CURRENT, PET_SAVE_FIRST_STABLE_SLOT, PET_SAVE_NOT_IN_SLOT, Unit::RemoveAurasByType(), Player::RemovePet(), SendStableResult(), PreparedStatementBase::SetData(), sObjectMgr, SPELL_AURA_FEIGN_DEATH, STABLE_ERR_EXOTIC, STABLE_ERR_STABLE, STABLE_SUCCESS_UNSTABLE, PetStable::StabledPets, UNIT_STATE_DIED, and PetStable::UnslottedPets.

Referenced by OpcodeTable::Initialize().

◆ HandleUpdateAccountData()

void WorldSession::HandleUpdateAccountData ( WorldPacket recvPacket)
812{
813 uint32 type, timestamp, decompressedSize;
814 recv_data >> type >> timestamp >> decompressedSize;
815
816 LOG_DEBUG("network", "UAD: type {}, time {}, decompressedSize {}", type, timestamp, decompressedSize);
817
818 if (type >= NUM_ACCOUNT_DATA_TYPES)
819 return;
820
821 if (decompressedSize == 0) // erase
822 {
823 SetAccountData(AccountDataType(type), 0, "");
824
826 data << uint32(type);
827 data << uint32(0);
828 SendPacket(&data);
829
830 return;
831 }
832
833 if (decompressedSize > 0xFFFF)
834 {
835 recv_data.rfinish(); // unnneded warning spam in this case
836 LOG_ERROR("network.opcode", "UAD: Account data packet too big, size {}", decompressedSize);
837 return;
838 }
839
840 ByteBuffer dest;
841 dest.resize(decompressedSize);
842
843 uLongf realSize = decompressedSize;
844 if (uncompress(dest.contents(), &realSize, recv_data.contents() + recv_data.rpos(), recv_data.size() - recv_data.rpos()) != Z_OK)
845 {
846 recv_data.rfinish(); // unnneded warning spam in this case
847 LOG_ERROR("network.opcode", "UAD: Failed to decompress account data");
848 return;
849 }
850
851 recv_data.rfinish(); // uncompress read (recv_data.size() - recv_data.rpos())
852
853 std::string adata;
854 dest >> adata;
855
856 SetAccountData(AccountDataType(type), timestamp, adata);
857
859 data << uint32(type);
860 data << uint32(0);
861 SendPacket(&data);
862}
void SetAccountData(AccountDataType type, time_t tm, std::string const &data)
Definition WorldSession.cpp:915
@ SMSG_UPDATE_ACCOUNT_DATA_COMPLETE
Definition Opcodes.h:1153

References ByteBuffer::contents(), LOG_DEBUG, LOG_ERROR, NUM_ACCOUNT_DATA_TYPES, ByteBuffer::resize(), ByteBuffer::rfinish(), ByteBuffer::rpos(), SendPacket(), SetAccountData(), ByteBuffer::size(), and SMSG_UPDATE_ACCOUNT_DATA_COMPLETE.

Referenced by OpcodeTable::Initialize().

◆ HandleUpdateMissileTrajectory()

void WorldSession::HandleUpdateMissileTrajectory ( WorldPacket recvPacket)
1715{
1716 LOG_DEBUG("network", "WORLD: CMSG_UPDATE_MISSILE_TRAJECTORY");
1717
1718 ObjectGuid guid;
1719 uint32 spellId;
1720 float elevation, speed;
1721 float curX, curY, curZ;
1722 float targetX, targetY, targetZ;
1723 uint8 moveStop;
1724
1725 recvPacket >> guid >> spellId >> elevation >> speed;
1726 recvPacket >> curX >> curY >> curZ;
1727 recvPacket >> targetX >> targetY >> targetZ;
1728 recvPacket >> moveStop;
1729
1730 Unit* caster = ObjectAccessor::GetUnit(*_player, guid);
1731 Spell* spell = caster ? caster->GetCurrentSpell(CURRENT_GENERIC_SPELL) : nullptr;
1732 if (!spell || spell->m_spellInfo->Id != spellId || !spell->m_targets.HasDst() || !spell->m_targets.HasSrc())
1733 {
1734 recvPacket.rfinish();
1735 return;
1736 }
1737
1738 Position pos = *spell->m_targets.GetSrcPos();
1739 pos.Relocate(curX, curY, curZ);
1740 spell->m_targets.ModSrc(pos);
1741
1742 pos = *spell->m_targets.GetDstPos();
1743 pos.Relocate(targetX, targetY, targetZ);
1744 spell->m_targets.ModDst(pos);
1745
1746 spell->m_targets.SetElevation(elevation);
1747 spell->m_targets.SetSpeed(speed);
1748
1749 if (moveStop)
1750 {
1751 uint32 opcode;
1752 recvPacket >> opcode;
1753 recvPacket.SetOpcode(opcode);
1754 HandleMovementOpcodes(recvPacket);
1755 }
1756}
@ CURRENT_GENERIC_SPELL
Definition Unit.h:545
void ModDst(Position const &pos)
Definition Spell.cpp:435
bool HasSrc() const
Definition Spell.h:174
bool HasDst() const
Definition Spell.h:175
void ModSrc(Position const &pos)
Definition Spell.cpp:384
Position const * GetSrcPos() const
Definition Spell.cpp:361
WorldLocation const * GetDstPos() const
Definition Spell.cpp:400

References _player, CURRENT_GENERIC_SPELL, Unit::GetCurrentSpell(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetSrcPos(), ObjectAccessor::GetUnit(), HandleMovementOpcodes(), SpellCastTargets::HasDst(), SpellCastTargets::HasSrc(), SpellInfo::Id, LOG_DEBUG, Spell::m_spellInfo, Spell::m_targets, SpellCastTargets::ModDst(), SpellCastTargets::ModSrc(), Position::Relocate(), ByteBuffer::rfinish(), SpellCastTargets::SetElevation(), WorldPacket::SetOpcode(), and SpellCastTargets::SetSpeed().

Referenced by OpcodeTable::Initialize().

◆ HandleUpdateProjectilePosition()

void WorldSession::HandleUpdateProjectilePosition ( WorldPacket recvPacket)
831{
832 LOG_DEBUG("network", "WORLD: CMSG_UPDATE_PROJECTILE_POSITION");
833
834 ObjectGuid casterGuid;
835 uint32 spellId;
836 uint8 castCount;
837 float x, y, z; // Position of missile hit
838
839 recvPacket >> casterGuid;
840 recvPacket >> spellId;
841 recvPacket >> castCount;
842 recvPacket >> x;
843 recvPacket >> y;
844 recvPacket >> z;
845
846 Unit* caster = ObjectAccessor::GetUnit(*_player, casterGuid);
847 if (!caster)
848 return;
849
850 Spell* spell = caster->FindCurrentSpellBySpellId(spellId);
851 if (!spell || !spell->m_targets.HasDst())
852 return;
853
854 Position pos = *spell->m_targets.GetDstPos();
855 pos.Relocate(x, y, z);
856 spell->m_targets.ModDst(pos);
857
858 // we changed dest, recalculate flight time
860
862 data << casterGuid;
863 data << uint8(castCount);
864 data << float(x);
865 data << float(y);
866 data << float(z);
867 caster->SendMessageToSet(&data, true);
868}
void RecalculateDelayMomentForDst()
Definition Spell.cpp:921
Spell * FindCurrentSpellBySpellId(uint32 spell_id) const
Definition Unit.cpp:4200
@ SMSG_SET_PROJECTILE_POSITION
Definition Opcodes.h:1245

References _player, Unit::FindCurrentSpellBySpellId(), SpellCastTargets::GetDstPos(), ObjectAccessor::GetUnit(), SpellCastTargets::HasDst(), LOG_DEBUG, Spell::m_targets, SpellCastTargets::ModDst(), Spell::RecalculateDelayMomentForDst(), Position::Relocate(), WorldObject::SendMessageToSet(), and SMSG_SET_PROJECTILE_POSITION.

Referenced by OpcodeTable::Initialize().

◆ HandleUseItemOpcode()

void WorldSession::HandleUseItemOpcode ( WorldPacket recvPacket)
Todo:
: add targets.read() check
59{
61 Player* pUser = _player;
62
63 // ignore for remote control state
64 if (pUser->m_mover != pUser)
65 return;
66
67 uint8 bagIndex, slot, castFlags;
68 uint8 castCount; // next cast if exists (single or not)
69 ObjectGuid itemGUID;
70 uint32 glyphIndex; // something to do with glyphs?
71 uint32 spellId; // casted spell id
72
73 recvPacket >> bagIndex >> slot >> castCount >> spellId >> itemGUID >> glyphIndex >> castFlags;
74
75 if (glyphIndex >= MAX_GLYPH_SLOT_INDEX)
76 {
77 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
78 return;
79 }
80
81 Item* pItem = pUser->GetUseableItemByPos(bagIndex, slot);
82 if (!pItem)
83 {
84 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
85 return;
86 }
87
88 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
89
90 if (!spellInfo)
91 {
92 LOG_ERROR("network.opcode", "WORLD: unknown spell id {}", spellId);
93 recvPacket.rfinish(); // prevent spam at ignore packet
94 return;
95 }
96
97 // fail if we are cancelling pending request
98 if (!_player->SpellQueue.empty())
99 {
100 PendingSpellCastRequest& request = _player->SpellQueue.front(); // Peek at the first spell
101 if (request.cancelInProgress)
102 {
103 pUser->SendEquipError(EQUIP_ERR_NONE, pItem, nullptr);
104 recvPacket.rfinish(); // prevent spam at ignore packet
105 return;
106 }
107 }
108
109 // try queue spell if it can't be executed right now
111 if (_player->CanRequestSpellCast(spellInfo))
112 {
113 WorldPacket packetCopy(recvPacket); // Copy the packet
114 packetCopy.rpos(0); // Reset read position to the start of the buffer.
115 _player->SpellQueue.emplace_back(
116 spellId,
117 spellInfo->GetCategory(),
118 std::move(packetCopy), // Move ownership of copied packet
119 true // itemCast
120 );
121 return;
122 }
123
124 if (pItem->GetGUID() != itemGUID)
125 {
126 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
127 return;
128 }
129
130 LOG_DEBUG("network", "WORLD: CMSG_USE_ITEM packet, bagIndex: {}, slot: {}, castCount: {}, spellId: {}, Item: {}, glyphIndex: {}, data length = {}", bagIndex, slot, castCount, spellId, pItem->GetEntry(), glyphIndex, (uint32)recvPacket.size());
131
132 ItemTemplate const* proto = pItem->GetTemplate();
133 if (!proto)
134 {
135 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, nullptr);
136 return;
137 }
138
139 // some item classes can be used only in equipped state
140 if (proto->InventoryType != INVTYPE_NON_EQUIP && !pItem->IsEquipped())
141 {
142 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, nullptr);
143 return;
144 }
145
146 InventoryResult msg = pUser->CanUseItem(pItem);
147 if (msg != EQUIP_ERR_OK)
148 {
149 pUser->SendEquipError(msg, pItem, nullptr);
150 return;
151 }
152
153 // only allow conjured consumable, bandage, poisons (all should have the 2^21 item flag set in DB)
155 {
156 pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, nullptr);
157 return;
158 }
159
160 // don't allow items banned in arena
161 if (proto->HasFlag(ITEM_FLAG_NOT_USEABLE_IN_ARENA) && pUser->InArena())
162 {
163 pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, nullptr);
164 return;
165 }
166
167 if (pUser->IsInCombat())
168 {
169 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
170 {
171 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(proto->Spells[i].SpellId))
172 {
173 if (!spellInfo->CanBeUsedInCombat())
174 {
175 pUser->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT, pItem, nullptr);
176 return;
177 }
178 }
179 }
180 }
181
182 // check also BIND_WHEN_PICKED_UP and BIND_QUEST_ITEM for .additem or .additemset case by GM (not binded at adding to inventory)
184 {
185 if (!pItem->IsSoulBound())
186 {
187 pItem->SetState(ITEM_CHANGED, pUser);
188 pItem->SetBinding(true);
189 }
190 }
191
192 SpellCastTargets targets;
193 targets.Read(recvPacket, pUser);
194 HandleClientCastFlags(recvPacket, castFlags, targets);
195
196 // Note: If script stop casting it must send appropriate data to client to prevent stuck item in gray state.
197 if (!sScriptMgr->OnItemUse(pUser, pItem, targets))
198 {
199 // no script or script not process request by self
200 pUser->CastItemUseSpell(pItem, targets, castCount, glyphIndex);
201 }
202}
@ INVTYPE_NON_EQUIP
Definition ItemTemplate.h:256
@ ITEM_FLAG_IGNORE_DEFAULT_ARENA_RESTRICTIONS
Definition ItemTemplate.h:168
@ ITEM_FLAG_NOT_USEABLE_IN_ARENA
Definition ItemTemplate.h:173
@ BIND_WHEN_USE
Definition ItemTemplate.h:98
@ BIND_QUEST_ITEM
Definition ItemTemplate.h:99
@ BIND_WHEN_PICKED_UP
Definition ItemTemplate.h:96
@ ITEM_CLASS_CONSUMABLE
Definition ItemTemplate.h:291
@ EQUIP_ERR_NOT_DURING_ARENA_MATCH
Definition Item.h:124
@ EQUIP_ERR_NOT_IN_COMBAT
Definition Item.h:107
void SetBinding(bool val)
Definition Item.h:235
Item * GetUseableItemByPos(uint8 bag, uint8 slot) const
Definition Player.h:1250
void CastItemUseSpell(Item *item, SpellCastTargets const &targets, uint8 cast_count, uint32 glyphIndex)
Definition Player.cpp:7458
bool CanBeUsedInCombat() const
Definition SpellInfo.cpp:1232

References _player, BIND_QUEST_ITEM, BIND_WHEN_PICKED_UP, BIND_WHEN_USE, ItemTemplate::Bonding, SpellInfo::CanBeUsedInCombat(), PendingSpellCastRequest::cancelInProgress, Player::CanExecutePendingSpellCastRequest(), Player::CanRequestSpellCast(), Player::CanUseItem(), Player::CastItemUseSpell(), ItemTemplate::Class, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_NONE, EQUIP_ERR_NOT_DURING_ARENA_MATCH, EQUIP_ERR_NOT_IN_COMBAT, EQUIP_ERR_OK, SpellInfo::GetCategory(), Object::GetEntry(), Object::GetGUID(), Item::GetTemplate(), Player::GetUseableItemByPos(), HandleClientCastFlags(), ItemTemplate::HasFlag(), Player::InArena(), ItemTemplate::InventoryType, INVTYPE_NON_EQUIP, Item::IsEquipped(), Unit::IsInCombat(), Item::IsSoulBound(), ITEM_CHANGED, ITEM_CLASS_CONSUMABLE, ITEM_FLAG_IGNORE_DEFAULT_ARENA_RESTRICTIONS, ITEM_FLAG_NOT_USEABLE_IN_ARENA, LOG_DEBUG, LOG_ERROR, Player::m_mover, MAX_GLYPH_SLOT_INDEX, MAX_ITEM_PROTO_SPELLS, SpellCastTargets::Read(), ByteBuffer::rfinish(), ByteBuffer::rpos(), Player::SendEquipError(), Item::SetBinding(), Item::SetState(), ByteBuffer::size(), _Spell::SpellId, Player::SpellQueue, ItemTemplate::Spells, sScriptMgr, and sSpellMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleVoiceSessionEnableOpcode()

void WorldSession::HandleVoiceSessionEnableOpcode ( WorldPacket recvData)
24{
25 LOG_DEBUG("network", "WORLD: CMSG_VOICE_SESSION_ENABLE");
26 // uint8 isVoiceEnabled, uint8 isMicrophoneEnabled
27 recvData.read_skip<uint8>();
28 recvData.read_skip<uint8>();
29}

References LOG_DEBUG, and ByteBuffer::read_skip().

Referenced by OpcodeTable::Initialize().

◆ HandleWardenDataOpcode()

void WorldSession::HandleWardenDataOpcode ( WorldPacket recvData)
318{
319 if (!_warden || recvData.empty())
320 return;
321
322 _warden->DecryptData(recvData.contents(), recvData.size());
323 uint8 opcode;
324 recvData >> opcode;
325 LOG_DEBUG("warden", "Got packet, opcode {:02X}, size {}", opcode, uint32(recvData.size()));
326 recvData.hexlike();
327
328 switch (opcode)
329 {
331 _warden->SendModuleToClient();
332 break;
334 _warden->RequestHash();
335 break;
337 _warden->HandleData(recvData);
338 break;
340 LOG_DEBUG("warden", "NYI WARDEN_CMSG_MEM_CHECKS_RESULT received!");
341 break;
343 _warden->HandleHashResult(recvData);
344 _warden->InitializeModule();
345 break;
347 LOG_DEBUG("warden", "NYI WARDEN_CMSG_MODULE_FAILED received!");
348 break;
349 default:
350 LOG_DEBUG("warden", "Got unknown warden opcode {:02X} of size {}.", opcode, uint32(recvData.size() - 1));
351 break;
352 }
353}
@ WARDEN_CMSG_MODULE_MISSING
Definition Warden.h:30
@ WARDEN_CMSG_HASH_RESULT
Definition Warden.h:34
@ WARDEN_CMSG_MODULE_FAILED
Definition Warden.h:35
@ WARDEN_CMSG_CHEAT_CHECKS_RESULT
Definition Warden.h:32
@ WARDEN_CMSG_MODULE_OK
Definition Warden.h:31
@ WARDEN_CMSG_MEM_CHECKS_RESULT
Definition Warden.h:33
void hexlike() const
Definition ByteBuffer.cpp:188

References _warden, ByteBuffer::contents(), ByteBuffer::empty(), ByteBuffer::hexlike(), LOG_DEBUG, ByteBuffer::size(), WARDEN_CMSG_CHEAT_CHECKS_RESULT, WARDEN_CMSG_HASH_RESULT, WARDEN_CMSG_MEM_CHECKS_RESULT, WARDEN_CMSG_MODULE_FAILED, WARDEN_CMSG_MODULE_MISSING, and WARDEN_CMSG_MODULE_OK.

Referenced by OpcodeTable::Initialize().

◆ HandleWhoisOpcode()

void WorldSession::HandleWhoisOpcode ( WorldPacket recvData)
1083{
1084 LOG_DEBUG("network", "Received opcode CMSG_WHOIS");
1085 std::string charname;
1086 recv_data >> charname;
1087
1089 {
1091 return;
1092 }
1093
1094 if (charname.empty() || !normalizePlayerName (charname))
1095 {
1097 return;
1098 }
1099
1100 Player* player = ObjectAccessor::FindPlayerByName(charname, false);
1101
1102 if (!player)
1103 {
1105 return;
1106 }
1107
1108 uint32 accid = player->GetSession()->GetAccountId();
1109
1111
1112 stmt->SetData(0, accid);
1113
1114 PreparedQueryResult result = LoginDatabase.Query(stmt);
1115
1116 if (!result)
1117 {
1119 return;
1120 }
1121
1122 Field* fields = result->Fetch();
1123 std::string acc = fields[0].Get<std::string>();
1124 if (acc.empty())
1125 acc = "Unknown";
1126 std::string email = fields[1].Get<std::string>();
1127 if (email.empty())
1128 email = "Unknown";
1129 std::string lastip = fields[2].Get<std::string>();
1130 if (lastip.empty())
1131 lastip = "Unknown";
1132
1133 std::string msg = charname + "'s " + "account is " + acc + ", e-mail: " + email + ", last ip: " + lastip;
1134
1135 WorldPacket data(SMSG_WHOIS, msg.size() + 1);
1136 data << msg;
1137 SendPacket(&data);
1138
1139 LOG_DEBUG("network", "Received whois command from player {} for character {}", GetPlayer()->GetName(), charname);
1140}
@ LANG_PLAYER_NOT_EXIST_OR_OFFLINE
Definition Language.h:751
@ LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND
Definition Language.h:752
@ LANG_PERMISSION_DENIED
Definition Language.h:747
@ LANG_NEED_CHARACTER_NAME
Definition Language.h:750
@ LOGIN_SEL_ACCOUNT_WHOIS
Definition LoginDatabase.h:98
@ SMSG_WHOIS
Definition Opcodes.h:131
bool IsAdminAccount(uint32 gmlevel)
Definition AccountMgr.cpp:322

References ObjectAccessor::FindPlayerByName(), Field::Get(), GetAccountId(), GetPlayer(), GetSecurity(), Player::GetSession(), AccountMgr::IsAdminAccount(), LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND, LANG_NEED_CHARACTER_NAME, LANG_PERMISSION_DENIED, LANG_PLAYER_NOT_EXIST_OR_OFFLINE, LOG_DEBUG, LOGIN_SEL_ACCOUNT_WHOIS, LoginDatabase, normalizePlayerName(), ChatHandler::SendNotification(), SendPacket(), PreparedStatementBase::SetData(), and SMSG_WHOIS.

Referenced by OpcodeTable::Initialize().

◆ HandleWhoOpcode()

void WorldSession::HandleWhoOpcode ( WorldPacket recvPacket)
213{
214 LOG_DEBUG("network", "WORLD: Recvd CMSG_WHO Message");
215
216 uint32 matchCount = 0;
217
218 uint32 levelMin, levelMax, racemask, classmask, zonesCount, strCount;
219 std::array<uint32, 10> zoneids = {}; // 10 is client limit
220 std::string packetPlayerName, packetGuildName;
221
222 recvData >> levelMin; // maximal player level, default 0
223 recvData >> levelMax; // minimal player level, default 100 (MAX_LEVEL)
224 recvData >> packetPlayerName; // player name, case sensitive...
225
226 recvData >> packetGuildName; // guild name, case sensitive...
227
228 recvData >> racemask; // race mask
229 recvData >> classmask; // class mask
230 recvData >> zonesCount; // zones count, client limit = 10 (2.0.10)
231
232 if (zonesCount > 10)
233 return; // can't be received from real client or broken packet
234
235 for (uint32 i = 0; i < zonesCount; ++i)
236 {
237 uint32 temp;
238 recvData >> temp; // zone id, 0 if zone is unknown...
239 zoneids[i] = temp;
240 LOG_DEBUG("network.who", "Zone {}: {}", i, zoneids[i]);
241 }
242
243 recvData >> strCount; // user entered strings count, client limit=4 (checked on 2.0.10)
244
245 if (strCount > 4)
246 return; // can't be received from real client or broken packet
247
248 LOG_DEBUG("network.who", "Minlvl {}, maxlvl {}, name {}, guild {}, racemask {}, classmask {}, zones {}, strings {}",
249 levelMin, levelMax, packetPlayerName, packetGuildName, racemask, classmask, zonesCount, strCount);
250
251 std::wstring str[4]; // 4 is client limit
252 for (uint32 i = 0; i < strCount; ++i)
253 {
254 std::string temp;
255 recvData >> temp; // user entered string, it used as universal search pattern(guild+player name)?
256
257 if (!Utf8toWStr(temp, str[i]))
258 continue;
259
260 wstrToLower(str[i]);
261
262 LOG_DEBUG("network.who", "String {}: {}", i, temp);
263 }
264
265 std::wstring wpacketPlayerName;
266 std::wstring wpacketGuildName;
267 if (!(Utf8toWStr(packetPlayerName, wpacketPlayerName) && Utf8toWStr(packetGuildName, wpacketGuildName)))
268 return;
269
270 wstrToLower(wpacketPlayerName);
271 wstrToLower(wpacketGuildName);
272
273 // client send in case not set max level value 100 but Acore supports 255 max level,
274 // update it to show GMs with characters after 100 level
275 if (levelMax >= MAX_LEVEL)
276 levelMax = STRONG_MAX_LEVEL;
277
278 uint32 team = _player->GetTeamId();
279 uint32 security = GetSecurity();
280 bool allowTwoSideWhoList = sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
281 uint32 gmLevelInWhoList = sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST);
282 uint32 displaycount = 0;
283
284 WorldPacket data(SMSG_WHO, 50); // guess size
285 data << uint32(matchCount); // placeholder, count of players matching criteria
286 data << uint32(displaycount); // placeholder, count of players displayed
287
288 for (auto const& target : sWhoListCacheMgr->GetWhoList())
289 {
290 if (AccountMgr::IsPlayerAccount(security))
291 {
292 // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST
293 if (target.GetTeamId() != team && !allowTwoSideWhoList)
294 {
295 continue;
296 }
297
298 // player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if CONFIG_GM_IN_WHO_LIST
299 if (target.GetSecurity() > AccountTypes(gmLevelInWhoList))
300 {
301 continue;
302 }
303 }
304
305 // check if target is globally visible for player
306 if ((_player->GetGUID() != target.GetGuid() && !target.IsVisible()) &&
308 {
309 continue;
310 }
311
312 // check if target's level is in level range
313 uint8 lvl = target.GetLevel();
314 if (lvl < levelMin || lvl > levelMax)
315 {
316 continue;
317 }
318
319 // check if class matches classmask
320 uint8 class_ = target.GetClass();
321 if (!(classmask & (1 << class_)))
322 {
323 continue;
324 }
325
326 // check if race matches racemask
327 uint32 race = target.GetRace();
328 if (!(racemask & (1 << race)))
329 {
330 continue;
331 }
332
333 uint32 playerZoneId = target.GetZoneId();
334 uint8 gender = target.GetGender();
335
336 bool showZones = true;
337 for (uint32 i = 0; i < zonesCount; ++i)
338 {
339 if (zoneids[i] == playerZoneId)
340 {
341 showZones = true;
342 break;
343 }
344
345 showZones = false;
346 }
347
348 if (!showZones)
349 {
350 continue;
351 }
352
353 std::wstring const& wideplayername = target.GetWidePlayerName();
354 if (!(wpacketPlayerName.empty() || wideplayername.find(wpacketPlayerName) != std::wstring::npos))
355 {
356 continue;
357 }
358
359 std::wstring const& wideguildname = target.GetWideGuildName();
360 if (!(wpacketGuildName.empty() || wideguildname.find(wpacketGuildName) != std::wstring::npos))
361 {
362 continue;
363 }
364
365 std::string aname;
366 if (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(playerZoneId))
367 {
368 aname = areaEntry->area_name[GetSessionDbcLocale()];
369 }
370
371 bool s_show = true;
372 for (uint32 i = 0; i < strCount; ++i)
373 {
374 if (!str[i].empty())
375 {
376 if (wideguildname.find(str[i]) != std::wstring::npos ||
377 wideplayername.find(str[i]) != std::wstring::npos ||
378 Utf8FitTo(aname, str[i]))
379 {
380 s_show = true;
381 break;
382 }
383
384 s_show = false;
385 }
386 }
387
388 if (!s_show)
389 {
390 continue;
391 }
392
393 // 49 is maximum player count sent to client - can be overridden
394 // through config, but is unstable
395 if ((matchCount++) >= sWorld->getIntConfig(CONFIG_MAX_WHO_LIST_RETURN))
396 {
397 continue;
398 }
399
400 data << target.GetPlayerName(); // player name
401 data << target.GetGuildName(); // guild name
402 data << uint32(lvl); // player level
403 data << uint32(class_); // player class
404 data << uint32(race); // player race
405 data << uint8(gender); // player gender
406 data << uint32(playerZoneId); // player zone id
407
408 ++displaycount;
409 }
410
411 data.put(0, displaycount); // insert right count, count displayed
412 data.put(4, matchCount); // insert right count, count of matches
413
414 SendPacket(&data);
415 LOG_DEBUG("network", "WORLD: Send SMSG_WHO Message");
416}
AccountTypes
Definition Common.h:56
#define MAX_LEVEL
Definition DBCEnums.h:39
#define STRONG_MAX_LEVEL
Definition DBCEnums.h:43
bool Utf8FitTo(std::string_view str, std::wstring_view search)
Definition Util.cpp:481
#define sWhoListCacheMgr
Definition WhoListCacheMgr.h:96
@ CONFIG_ALLOW_TWO_SIDE_WHO_LIST
Definition WorldConfig.h:39
@ CONFIG_MAX_WHO_LIST_RETURN
Definition WorldConfig.h:358
@ CONFIG_GM_LEVEL_IN_WHO_LIST
Definition WorldConfig.h:213
@ SMSG_WHO
Definition Opcodes.h:129

References _player, CONFIG_ALLOW_TWO_SIDE_WHO_LIST, CONFIG_GM_LEVEL_IN_WHO_LIST, CONFIG_MAX_WHO_LIST_RETURN, Object::GetGUID(), GetSecurity(), Player::GetSession(), GetSessionDbcLocale(), Player::GetTeamId(), AccountMgr::IsPlayerAccount(), LOG_DEBUG, MAX_LEVEL, ByteBuffer::put(), sAreaTableStore, SendPacket(), SMSG_WHO, STRONG_MAX_LEVEL, sWhoListCacheMgr, sWorld, Utf8FitTo(), Utf8toWStr(), and wstrToLower().

Referenced by OpcodeTable::Initialize().

◆ HandleWorldStateUITimerUpdate()

void WorldSession::HandleWorldStateUITimerUpdate ( WorldPacket recvData)
1602{
1603 // empty opcode
1604 LOG_DEBUG("network", "WORLD: CMSG_WORLD_STATE_UI_TIMER_UPDATE");
1605
1607 response.Time = GameTime::GetGameTime().count();
1608 SendPacket(response.Write());
1609}
Definition MiscPackets.h:205
WorldPacket const * Write() override
Definition MiscPackets.cpp:137
uint32 Time
Definition MiscPackets.h:211

References GameTime::GetGameTime(), LOG_DEBUG, SendPacket(), WorldPackets::Misc::UITime::Time, and WorldPackets::Misc::UITime::Write().

Referenced by OpcodeTable::Initialize().

◆ HandleWorldTeleportOpcode()

void WorldSession::HandleWorldTeleportOpcode ( WorldPacket recvData)
1053{
1054 uint32 time;
1055 uint32 mapid;
1056 float PositionX;
1057 float PositionY;
1058 float PositionZ;
1059 float Orientation;
1060
1061 recv_data >> time; // time in m.sec.
1062 recv_data >> mapid;
1063 recv_data >> PositionX;
1064 recv_data >> PositionY;
1065 recv_data >> PositionZ;
1066 recv_data >> Orientation; // o (3.141593 = 180 degrees)
1067
1068 if (GetPlayer()->IsInFlight())
1069 {
1070 LOG_DEBUG("network", "Player '{}' ({}) in flight, ignore worldport command.", GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
1071 return;
1072 }
1073
1074 LOG_DEBUG("network", "CMSG_WORLD_TELEPORT: Player = {}, Time = {}, map = {}, x = {}, y = {}, z = {}, o = {}", GetPlayer()->GetName(), time, mapid, PositionX, PositionY, PositionZ, Orientation);
1075
1077 GetPlayer()->TeleportTo(mapid, PositionX, PositionY, PositionZ, Orientation);
1078 else
1080}

References GetPlayer(), GetSecurity(), AccountMgr::IsAdminAccount(), LANG_PERMISSION_DENIED, LOG_DEBUG, ChatHandler::SendNotification(), and Player::TeleportTo().

Referenced by OpcodeTable::Initialize().

◆ HandleWrapItemOpcode()

void WorldSession::HandleWrapItemOpcode ( WorldPackets::Item::WrapItem packet)
1081{
1082 LOG_DEBUG("network", "Received opcode CMSG_WRAP_ITEM");
1083
1084 LOG_DEBUG("network", "WRAP: receive GiftBag = {}, GiftSlot = {}, ItemBag = {}, ItemSlot = {}", packet.GiftBag, packet.GiftSlot, packet.ItemBag, packet.ItemSlot);
1085
1086 Item* gift = _player->GetItemByPos(packet.GiftBag, packet.GiftSlot);
1087 if (!gift)
1088 {
1090 return;
1091 }
1092
1093 if (!(gift->GetTemplate()->HasFlag(ITEM_FLAG_IS_WRAPPER))) // cheating: non-wrapper wrapper
1094 {
1096 return;
1097 }
1098
1099 Item* item = _player->GetItemByPos(packet.ItemBag, packet.ItemSlot);
1100
1101 if (!item)
1102 {
1104 return;
1105 }
1106
1107 // xinef: do not allow to wrap removed items, just in case
1108 if (item->GetState() == ITEM_REMOVED)
1109 {
1111 return;
1112 }
1113
1114 if (item == gift) // not possible with packet from real client
1115 {
1117 return;
1118 }
1119
1120 if (item->IsEquipped())
1121 {
1123 return;
1124 }
1125
1126 if (item->GetGuidValue(ITEM_FIELD_GIFTCREATOR)) // HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED);
1127 {
1129 return;
1130 }
1131
1132 if (item->IsBag())
1133 {
1135 return;
1136 }
1137
1138 if (item->IsSoulBound())
1139 {
1141 return;
1142 }
1143
1144 if (item->GetMaxStackCount() != 1)
1145 {
1147 return;
1148 }
1149
1150 // maybe not correct check (it is better than nothing)
1151 if (item->GetTemplate()->MaxCount > 0)
1152 {
1154 return;
1155 }
1156
1157 if (item->GetTemplate()->Duration > 0)
1158 {
1160 return;
1161 }
1162
1163 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
1164
1166 stmt->SetData(0, item->GetOwnerGUID().GetCounter());
1167 stmt->SetData(1, item->GetGUID().GetCounter());
1168 stmt->SetData(2, item->GetEntry());
1169 stmt->SetData(3, item->GetUInt32Value(ITEM_FIELD_FLAGS));
1170 trans->Append(stmt);
1171
1172 item->SetEntry(gift->GetEntry());
1173
1174 switch (item->GetEntry())
1175 {
1176 case 5042:
1177 item->SetEntry(5043);
1178 break;
1179 case 5048:
1180 item->SetEntry(5044);
1181 break;
1182 case 17303:
1183 item->SetEntry(17302);
1184 break;
1185 case 17304:
1186 item->SetEntry(17305);
1187 break;
1188 case 17307:
1189 item->SetEntry(17308);
1190 break;
1191 case 21830:
1192 item->SetEntry(21831);
1193 break;
1194 }
1198
1199 // after save it will be impossible to remove the item from the queue
1201
1202 CharacterDatabase.CommitTransaction(trans);
1203
1204 uint32 count = 1;
1205 _player->DestroyItemCount(gift, count, true);
1206}
@ CHAR_INS_CHAR_GIFT
Definition CharacterDatabase.h:380
@ ITEM_FIELD_FLAG_WRAPPED
Definition ItemTemplate.h:112
@ ITEM_FLAG_IS_WRAPPER
Definition ItemTemplate.h:156
@ EQUIP_ERR_BAGS_CANT_BE_WRAPPED
Definition Item.h:95
@ EQUIP_ERR_STACKABLE_CANT_BE_WRAPPED
Definition Item.h:90
@ EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED
Definition Item.h:94
@ EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED
Definition Item.h:92
@ EQUIP_ERR_BOUND_CANT_BE_WRAPPED
Definition Item.h:93
@ EQUIP_ERR_EQUIPPED_CANT_BE_WRAPPED
Definition Item.h:91
@ ITEM_REMOVED
Definition Item.h:212
uint8 GiftBag
Definition ItemPackets.h:223
uint8 ItemBag
Definition ItemPackets.h:225
uint8 ItemSlot
Definition ItemPackets.h:226
uint8 GiftSlot
Definition ItemPackets.h:224

References _player, CHAR_INS_CHAR_GIFT, CharacterDatabase, Player::DestroyItemCount(), ItemTemplate::Duration, EQUIP_ERR_BAGS_CANT_BE_WRAPPED, EQUIP_ERR_BOUND_CANT_BE_WRAPPED, EQUIP_ERR_EQUIPPED_CANT_BE_WRAPPED, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_STACKABLE_CANT_BE_WRAPPED, EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED, EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED, ObjectGuid::GetCounter(), Object::GetEntry(), Object::GetGUID(), Object::GetGuidValue(), Player::GetItemByPos(), Item::GetMaxStackCount(), Item::GetOwnerGUID(), Item::GetState(), Item::GetTemplate(), Object::GetUInt32Value(), WorldPackets::Item::WrapItem::GiftBag, WorldPackets::Item::WrapItem::GiftSlot, ItemTemplate::HasFlag(), Item::IsBag(), Item::IsEquipped(), Item::IsSoulBound(), ITEM_CHANGED, ITEM_FIELD_FLAG_WRAPPED, ITEM_FIELD_FLAGS, ITEM_FIELD_GIFTCREATOR, ITEM_FLAG_IS_WRAPPER, ITEM_REMOVED, WorldPackets::Item::WrapItem::ItemBag, WorldPackets::Item::WrapItem::ItemSlot, LOG_DEBUG, ItemTemplate::MaxCount, Player::SaveInventoryAndGoldToDB(), Player::SendEquipError(), PreparedStatementBase::SetData(), Object::SetEntry(), Object::SetGuidValue(), Item::SetState(), and Object::SetUInt32Value().

Referenced by OpcodeTable::Initialize().

◆ HandleZoneUpdateOpcode()

void WorldSession::HandleZoneUpdateOpcode ( WorldPacket recvPacket)
524{
525 uint32 newZone;
526 recv_data >> newZone;
527
528 LOG_DEBUG("network", "WORLD: Recvd ZONE_UPDATE: {}", newZone);
529
530 // use server side data, but only after update the player position. See Player::UpdatePosition().
532
533 //GetPlayer()->SendInitWorldStates(true, newZone);
534}
void SetNeedZoneUpdate(bool needUpdate)
Definition Player.h:1855

References GetPlayer(), LOG_DEBUG, and Player::SetNeedZoneUpdate().

Referenced by OpcodeTable::Initialize().

◆ HasAccountFlag()

bool WorldSession::HasAccountFlag ( uint32  flag) const
inline
375{ return (_accountFlags & flag) != 0; }

References _accountFlags.

Referenced by ServerMailCondition::CheckCondition(), and ValidateAccountFlags().

◆ IncrementOrderCounter()

void WorldSession::IncrementOrderCounter ( )
inline

◆ InitializeSession()

void WorldSession::InitializeSession ( )
1475{
1476 uint32 cacheVersion = sWorld->getIntConfig(CONFIG_CLIENTCACHE_VERSION);
1477 sScriptMgr->OnBeforeFinalizePlayerWorldSession(cacheVersion);
1478
1479 std::shared_ptr<AccountInfoQueryHolderPerRealm> realmHolder = std::make_shared<AccountInfoQueryHolderPerRealm>();
1480 if (!realmHolder->Initialize(GetAccountId()))
1481 {
1483 return;
1484 }
1485
1486 AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(realmHolder)).AfterComplete([this, cacheVersion](SQLQueryHolderBase const& holder)
1487 {
1488 InitializeSessionCallback(static_cast<AccountInfoQueryHolderPerRealm const&>(holder), cacheVersion);
1489 });
1490}
@ AUTH_SYSTEM_ERROR
Definition SharedDefines.h:3606
@ CONFIG_CLIENTCACHE_VERSION
Definition WorldConfig.h:305
Definition WorldSession.cpp:1446
void InitializeSessionCallback(CharacterDatabaseQueryHolder const &realmHolder, uint32 clientCacheVersion)
Definition WorldSession.cpp:1492
void SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos=0)
Definition AuthHandler.cpp:22

References AddQueryHolderCallback(), SQLQueryHolderCallback::AfterComplete(), AUTH_SYSTEM_ERROR, CharacterDatabase, CONFIG_CLIENTCACHE_VERSION, GetAccountId(), InitializeSessionCallback(), SendAuthResponse(), sScriptMgr, and sWorld.

Referenced by WorldSessionMgr::AddSession_(), and WorldSessionMgr::RemoveQueuedPlayer().

◆ InitializeSessionCallback()

void WorldSession::InitializeSessionCallback ( CharacterDatabaseQueryHolder const &  realmHolder,
uint32  clientCacheVersion 
)
1493{
1495 LoadTutorialsData(realmHolder.GetPreparedResult(AccountInfoQueryHolderPerRealm::TUTORIALS));
1496
1497 if (!m_inQueue)
1498 {
1500 }
1501 else
1502 {
1504 }
1505
1506 SetInQueue(false);
1507 ResetTimeOutTime(false);
1508
1510 SendClientCacheVersion(clientCacheVersion);
1512}
@ AUTH_OK
Definition SharedDefines.h:3601
@ TUTORIALS
Definition WorldSession.cpp:1451
@ GLOBAL_ACCOUNT_DATA
Definition WorldSession.cpp:1450
void LoadTutorialsData(PreparedQueryResult result)
Definition WorldSession.cpp:957
void SendClientCacheVersion(uint32 version)
Definition AuthHandler.cpp:45
void SendAuthWaitQueue(uint32 position)
Handle the authentication waiting queue (to be completed)
Definition WorldSession.cpp:867
void SendAddonsInfo()
Definition WorldSession.cpp:1240
void SetInQueue(bool state)
Session in auth.queue currently.
Definition WorldSession.h:444
void SendTutorialsData()
Definition WorldSession.cpp:972

References AUTH_OK, SQLQueryHolderBase::GetPreparedResult(), AccountInfoQueryHolderPerRealm::GLOBAL_ACCOUNT_DATA, GLOBAL_CACHE_MASK, LoadAccountData(), LoadTutorialsData(), m_inQueue, ResetTimeOutTime(), SendAddonsInfo(), SendAuthResponse(), SendAuthWaitQueue(), SendClientCacheVersion(), SendTutorialsData(), SetInQueue(), and AccountInfoQueryHolderPerRealm::TUTORIALS.

Referenced by InitializeSession().

◆ InitWarden()

void WorldSession::InitWarden ( SessionKey const &  k,
std::string const &  os 
)
1335{
1336 if (os == "Win")
1337 {
1338 _warden = std::make_unique<WardenWin>();
1339 _warden->Init(this, k);
1340 }
1341 else if (os == "OSX")
1342 {
1343 // Disabled as it is causing the client to crash
1344 // _warden = new WardenMac();
1345 // _warden->Init(this, k);
1346 }
1347}

References _warden.

Referenced by WorldSocket::HandleAuthSessionCallback().

◆ IsARecruiter()

bool WorldSession::IsARecruiter ( ) const
inline

◆ IsConnectionIdle()

bool WorldSession::IsConnectionIdle ( ) const
inline
583 {
584 return (m_timeOutTime <= 0 && !m_inQueue);
585 }

References m_inQueue, and m_timeOutTime.

Referenced by Update().

◆ IsGMAccount()

◆ IsKicked()

bool WorldSession::IsKicked ( ) const
inline
1126{ return _kicked; }

References _kicked.

Referenced by HandleSocketClosed(), and WorldSessionMgr::UpdateSessions().

◆ IsLegitCharacterForAccount()

bool WorldSession::IsLegitCharacterForAccount ( ObjectGuid  guid)
inlineprivate
1193 {
1194 return _legitCharacters.find(guid) != _legitCharacters.end();
1195 }

References _legitCharacters.

Referenced by HandleCharCustomize(), HandleCharFactionOrRaceChange(), and HandlePlayerLoginOpcode().

◆ isLogingOut()

bool WorldSession::isLogingOut ( ) const
inline

Is the user engaged in a log out process?

447{ return _logoutTime || m_playerLogout; }

References _logoutTime, and m_playerLogout.

Referenced by HandleInitiateTradeOpcode(), and Player::SaveToDB().

◆ IsSocketClosed()

bool WorldSession::IsSocketClosed ( ) const
576{
577 return !m_Socket || !m_Socket->IsOpen();
578}

References m_Socket.

Referenced by Group::ResetMaxEnchantingLevel().

◆ KickPlayer() [1/2]

◆ KickPlayer() [2/2]

void WorldSession::KickPlayer ( std::string const &  reason,
bool  setKicked = true 
)

Kick a player out of the World.

792{
793 if (m_Socket)
794 {
795 LOG_INFO("network.kick", "Account: {} Character: '{}' {} kicked with reason: {}", GetAccountId(), _player ? _player->GetName() : "<none>",
796 _player ? _player->GetGUID().ToString() : "", reason);
797
798 m_Socket->CloseSocket();
799 }
800
801 if (setKicked)
802 SetKicked(true); // pussywizard: the session won't be left ingame for 60 seconds and to also kick offline session
803}
void SetKicked(bool val)
Definition WorldSession.h:1127

References _player, GetAccountId(), Object::GetGUID(), WorldObject::GetName(), LOG_INFO, m_Socket, SetKicked(), and ObjectGuid::ToString().

◆ LoadAccountData()

void WorldSession::LoadAccountData ( PreparedQueryResult  result,
uint32  mask 
)
886{
887 for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
888 if (mask & (1 << i))
890
891 if (!result)
892 return;
893
894 do
895 {
896 Field* fields = result->Fetch();
897 uint32 type = fields[0].Get<uint8>();
898 if (type >= NUM_ACCOUNT_DATA_TYPES)
899 {
900 LOG_ERROR("network", "Table `{}` have invalid account data type ({}), ignore.", mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
901 continue;
902 }
903
904 if ((mask & (1 << type)) == 0)
905 {
906 LOG_ERROR("network", "Table `{}` have non appropriate for table account data type ({}), ignore.", mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
907 continue;
908 }
909
910 m_accountData[type].Time = time_t(fields[1].Get<uint32>());
911 m_accountData[type].Data = fields[2].Get<std::string>();
912 } while (result->NextRow());
913}

References AccountData::Data, Field::Get(), GLOBAL_CACHE_MASK, LOG_ERROR, m_accountData, NUM_ACCOUNT_DATA_TYPES, and AccountData::Time.

Referenced by HandlePlayerLoginFromDB(), and InitializeSessionCallback().

◆ LoadTutorialsData()

void WorldSession::LoadTutorialsData ( PreparedQueryResult  result)
958{
959 memset(m_Tutorials, 0, sizeof(uint32) * MAX_ACCOUNT_TUTORIAL_VALUES);
960
961 if (result)
962 {
963 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
964 {
965 m_Tutorials[i] = (*result)[i].Get<uint32>();
966 }
967 }
968
969 m_TutorialsChanged = false;
970}

References m_Tutorials, m_TutorialsChanged, and MAX_ACCOUNT_TUTORIAL_VALUES.

Referenced by InitializeSessionCallback().

◆ LogoutPlayer()

void WorldSession::LogoutPlayer ( bool  save)

Log the player out

Call script hook before other logout events

  • If the player just died before logging out, make him appear as a ghost
  • If the player is in a guild, update the guild roster and broadcast a logout message to other guild members
  • Remove pet
  • empty buyback items and save the player in the database
  • Leave all channels before player delete...

Send update to group and reset stored max enchanting level

Broadcast a logout message to the player's friends

Call script hook before deletion

Remove the player from the world

Send the 'logout complete' packet to the client Client will respond by sending 3x CMSG_CANCEL_TRADE, which we currently dont handle

Since each account can only have one online character at any given time, ensure all characters for active account are marked as offline

612{
613 // finish pending transfers before starting the logout
616
617 m_playerLogout = true;
618 m_playerSave = save;
619
620 if (_player)
621 {
623 sScriptMgr->OnPlayerBeforeLogout(_player);
624
625 if (ObjectGuid lguid = _player->GetLootGUID())
626 DoLootRelease(lguid);
627
629 //FIXME: logout must be delayed in case lost connection with client in time of combat
630 if (_player->GetDeathTimer())
631 {
635 }
637 {
638 // this will kill character by SPELL_AURA_SPIRIT_OF_REDEMPTION
643 }
644 else if (_player->HasPendingBind())
645 {
647 _player->SetPendingBind(0, 0);
648 }
649
650 // pussywizard: leave whole bg on logout (character stays ingame when necessary)
651 // pussywizard: GetBattleground() checked inside
653
654 // pussywizard: checked first time
657
658 sOutdoorPvPMgr->HandlePlayerLeaveZone(_player, _player->GetZoneId());
659 sWorldState->HandlePlayerLeaveZone(_player, static_cast<AreaTableIDs>(_player->GetZoneId()));
660
661 // pussywizard: remove from battleground queues on logout
662 for (int i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
664 {
665 // track if player logs out after invited to join BG
667 {
669 {
671 stmt->SetData(0, _player->GetGUID().GetCounter());
673 CharacterDatabase.Execute(stmt);
674 }
675
676 sScriptMgr->OnPlayerBattlegroundDesertion(_player, BG_DESERTION_TYPE_INVITE_LOGOUT);
677 }
678
679 if (bgQueueTypeId >= BATTLEGROUND_QUEUE_2v2 && bgQueueTypeId < MAX_BATTLEGROUND_QUEUE_TYPES && _player->IsInvitedForBattlegroundQueueType(bgQueueTypeId))
680 sScriptMgr->OnPlayerBattlegroundDesertion(_player, ARENA_DESERTION_TYPE_INVITE_LOGOUT);
681
682 _player->RemoveBattlegroundQueueId(bgQueueTypeId);
683 sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId).RemovePlayer(_player->GetGUID(), true);
684 }
685
687 if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
688 guild->HandleMemberLogout(this);
689
692
693 // pussywizard: on logout remove auras that are removed at map change (before saving to db)
694 // there are some positive auras from boss encounters that can be kept by logging out and logging in after boss is dead, and may be used on next bosses
696
697 if (Group *group = _player->GetGroupInvite())
699 ? _player->UninviteFromGroup() // Can disband group.
700 : group->RemoveInvite(_player); // Just removes invite.
701
702 // remove player from the group if he is:
703 // a) in group; b) not in raid group; c) logging out normally (not being kicked or disconnected) d) LeaveGroupOnLogout is enabled
706
707 // pussywizard: checked second time after being removed from a group
710
711 // Repop at Graveyard or other player far teleport will prevent saving player because of not present map
712 // Teleport player immediately for correct player save
715
717 // some save parts only correctly work in case player present in map/player_lists (pets, etc)
718 if (save)
719 {
720 uint32 eslot;
721 for (int j = BUYBACK_SLOT_START; j < BUYBACK_SLOT_END; ++j)
722 {
723 eslot = j - BUYBACK_SLOT_START;
727 }
728 _player->SaveToDB(false, true);
729 }
730
733
735 if (_player->GetGroup())
736 {
739
741 {
742 Map::PlayerList const &playerList = _player->GetMap()->GetPlayers();
743 if (playerList.IsEmpty())
745 }
746 }
747
749 sSocialMgr->SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUID(), true);
750 sSocialMgr->RemovePlayerSocial(_player->GetGUID());
751
753 sScriptMgr->OnPlayerLogout(_player);
754
755 METRIC_EVENT("player_events", "Logout", _player->GetName());
756
757 LOG_INFO("entities.player", "Account: {} (IP: {}) Logout Character:[{}] ({}) Level: {}",
759
761 // the player may not be in the world when logging out
762 // e.g if he got disconnected during a transfer to another map
763 // calls to GetMap in this case may cause crashes
765 if (Map* _map = _player->FindMap())
766 {
767 _map->RemovePlayerFromMap(_player, true);
768 _map->AfterPlayerUnlinkFromMap();
769 }
770
771 SetPlayer(nullptr); // pointer already deleted
772
776 LOG_DEBUG("network", "SESSION: Sent SMSG_LOGOUT_COMPLETE Message");
777
780 stmt->SetData(0, GetAccountId());
781 CharacterDatabase.Execute(stmt);
782 }
783
784 m_playerLogout = false;
785 m_playerSave = false;
788}
AreaTableIDs
Definition AreaDefines.h:24
@ ARENA_DESERTION_TYPE_INVITE_LOGOUT
Definition Battleground.h:60
@ BG_DESERTION_TYPE_INVITE_LOGOUT
Definition Battleground.h:56
@ CHAR_UPD_ACCOUNT_ONLINE
Definition CharacterDatabase.h:282
#define sOutdoorPvPMgr
Definition OutdoorPvPMgr.h:102
@ BUYBACK_SLOT_END
Definition Player.h:720
@ FRIEND_OFFLINE
Definition SocialMgr.h:69
@ SPELL_AURA_MOD_SHAPESHIFT
Definition SpellAuraDefines.h:99
@ AURA_INTERRUPT_FLAG_CHANGE_MAP
Definition SpellDefines.h:62
@ PLAYER_FIELD_VENDORBUYBACK_SLOT_1
Definition UpdateFields.h:331
@ PLAYER_FIELD_BUYBACK_TIMESTAMP_1
Definition UpdateFields.h:373
@ CONFIG_LEAVE_GROUP_ON_LOGOUT
Definition WorldConfig.h:133
#define sWorldState
Definition WorldState.h:377
void ResetMaxEnchantingLevel()
Definition Group.cpp:2225
Definition MapRefMgr.h:26
bool IsRaidOrHeroicDungeon() const
Definition Map.h:298
void SaveToDB(bool create, bool logout)
Definition PlayerStorage.cpp:7054
bool IsBeingTeleportedFar() const
Definition Player.h:2090
void CleanupsBeforeDelete(bool finalCleanup=true) override
Definition Player.cpp:478
uint32 GetDeathTimer() const
Definition Player.h:2174
bool HasSpiritOfRedemptionAura() const
Definition Unit.h:1784
Definition CharacterPackets.h:67

References _player, ARENA_DESERTION_TYPE_INVITE_LOGOUT, AURA_INTERRUPT_FLAG_CHANGE_MAP, BATTLEGROUND_QUEUE_2v2, BG_DESERTION_TYPE_INVITE_LOGOUT, Player::BuildPlayerRepop(), BUYBACK_SLOT_END, BUYBACK_SLOT_START, CHAR_INS_DESERTER_TRACK, CHAR_UPD_ACCOUNT_ONLINE, CharacterDatabase, Player::CleanupChannels(), Player::CleanupsBeforeDelete(), CONFIG_BATTLEGROUND_TRACK_DESERTERS, CONFIG_LEAVE_GROUP_ON_LOGOUT, HostileRefMgr::deleteReferences(), DoLootRelease(), ObjectGuid::Empty, WorldObject::FindMap(), FRIEND_OFFLINE, GetAccountId(), Player::GetBattlegroundQueueTypeId(), ObjectGuid::GetCounter(), Player::GetDeathTimer(), Player::GetGroup(), Player::GetGroupInvite(), Object::GetGUID(), Player::GetGuildId(), Unit::getHostileRefMgr(), Unit::GetLevel(), Player::GetLootGUID(), WorldObject::GetMap(), WorldObject::GetName(), Map::GetPlayers(), GetRemoteAddress(), WorldObject::GetZoneId(), HandleMoveWorldportAck(), Player::HasPendingBind(), Unit::HasSpiritOfRedemptionAura(), Player::IsBeingTeleportedFar(), Map::IsDungeon(), LinkedListHead::IsEmpty(), Player::IsGameMaster(), Player::IsInvitedForBattlegroundInstance(), Group::isLFGGroup(), Group::isRaidGroup(), Map::IsRaidOrHeroicDungeon(), Player::KillPlayer(), Player::LeaveBattleground(), LOG_DEBUG, LOG_INFO, Player::m_InstanceValid, m_playerLogout, m_playerRecentlyLogout, m_playerSave, m_Socket, METRIC_EVENT, PET_SAVE_AS_CURRENT, PLAYER_FIELD_BUYBACK_PRICE_1, PLAYER_FIELD_BUYBACK_TIMESTAMP_1, PLAYER_FIELD_VENDORBUYBACK_SLOT_1, PLAYER_MAX_BATTLEGROUND_QUEUES, Unit::RemoveAurasByType(), Unit::RemoveAurasWithInterruptFlags(), Player::RemoveBattlegroundQueueId(), Player::RemoveFromGroup(), Player::RemovePet(), Player::RepopAtGraveyard(), Group::ResetMaxEnchantingLevel(), Player::SaveToDB(), sBattlegroundMgr, SendPacket(), Group::SendUpdate(), PreparedStatementBase::SetData(), Object::SetGuidValue(), SetLogoutStartTime(), Player::SetPendingBind(), SetPlayer(), Unit::SetUInt32Value(), sGuildMgr, sOutdoorPvPMgr, SPELL_AURA_MOD_SHAPESHIFT, sScriptMgr, sSocialMgr, sWorld, sWorldState, Player::TeleportToEntryPoint(), ObjectGuid::ToString(), and Player::UninviteFromGroup().

Referenced by AccountMgr::DeleteAccount(), HandleLogoutRequestOpcode(), Update(), and ~WorldSession().

◆ LogUnexpectedOpcode()

void WorldSession::LogUnexpectedOpcode ( WorldPacket packet,
char const *  status,
const char *  reason 
)
private

Logging helper for unexpected opcodes.

309{
310 LOG_ERROR("network.opcode", "Received unexpected opcode {} Status: {} Reason: {} from {}",
311 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), status, reason, GetPlayerInfo());
312}

References WorldPacket::GetOpcode(), GetOpcodeNameForLogging(), GetPlayerInfo(), and LOG_ERROR.

Referenced by Update().

◆ LogUnprocessedTail()

void WorldSession::LogUnprocessedTail ( WorldPacket packet)
private

Logging helper for unexpected opcodes.

316{
317 if (!sLog->ShouldLog("network.opcode", LogLevel::LOG_LEVEL_TRACE) || packet->rpos() >= packet->wpos())
318 return;
319
320 LOG_TRACE("network.opcode", "Unprocessed tail data (read stop at {} from {}) Opcode {} from {}",
321 uint32(packet->rpos()), uint32(packet->wpos()), GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
322
323 packet->print_storage();
324}
@ LOG_LEVEL_TRACE
Definition LogCommon.h:32
#define sLog
Definition Log.h:127
#define LOG_TRACE(filterType__,...)
Definition Log.h:174
void print_storage() const
Definition ByteBuffer.cpp:152
std::size_t wpos() const
Definition ByteBuffer.h:330
std::size_t rpos() const
Definition ByteBuffer.h:317

References WorldPacket::GetOpcode(), GetOpcodeNameForLogging(), GetPlayerInfo(), LOG_LEVEL_TRACE, LOG_TRACE, ByteBuffer::print_storage(), ByteBuffer::rpos(), sLog, and ByteBuffer::wpos().

Referenced by Update().

◆ moveItems()

void WorldSession::moveItems ( Item myItems[],
Item hisItems[] 
)
private
133{
134 Player* trader = _player->GetTrader();
135 if (!trader)
136 return;
137
138 for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i)
139 {
140 ItemPosCountVec traderDst;
141 ItemPosCountVec playerDst;
142 bool traderCanTrade = (!myItems[i] || trader->CanStoreItem(NULL_BAG, NULL_SLOT, traderDst, myItems[i], false) == EQUIP_ERR_OK);
143 bool playerCanTrade = (!hisItems[i] || _player->CanStoreItem(NULL_BAG, NULL_SLOT, playerDst, hisItems[i], false) == EQUIP_ERR_OK);
144 if (traderCanTrade && playerCanTrade)
145 {
146 // Ok, if trade item exists and can be stored
147 // If we trade in both directions we had to check, if the trade will work before we actually do it
148 // A roll back is not possible after we stored it
149 if (myItems[i])
150 {
151 // logging
152 LOG_DEBUG("network", "partner storing: {}", myItems[i]->GetGUID().ToString());
153
154 // adjust time (depends on /played)
155 if (myItems[i]->IsBOPTradable())
157 // store
158 trader->MoveItemToInventory(traderDst, myItems[i], true, true);
159 }
160 if (hisItems[i])
161 {
162 // logging
163 LOG_DEBUG("network", "player storing: {}", hisItems[i]->GetGUID().ToString());
164
165 // adjust time (depends on /played)
166 if (hisItems[i]->IsBOPTradable())
168 // store
169 _player->MoveItemToInventory(playerDst, hisItems[i], true, true);
170 }
171 }
172 else
173 {
174 // in case of fatal error log error message
175 // return the already removed items to the original owner
176 if (myItems[i])
177 {
178 if (!traderCanTrade)
179 LOG_ERROR("network.opcode", "trader can't store item: {}", myItems[i]->GetGUID().ToString());
180 if (_player->CanStoreItem(NULL_BAG, NULL_SLOT, playerDst, myItems[i], false) == EQUIP_ERR_OK)
181 _player->MoveItemToInventory(playerDst, myItems[i], true, true);
182 else
183 LOG_ERROR("network.opcode", "player can't take item back: {}", myItems[i]->GetGUID().ToString());
184 }
185 // return the already removed items to the original owner
186 if (hisItems[i])
187 {
188 if (!playerCanTrade)
189 LOG_ERROR("network.opcode", "player can't store item: {}", hisItems[i]->GetGUID().ToString());
190 if (trader->CanStoreItem(NULL_BAG, NULL_SLOT, traderDst, hisItems[i], false) == EQUIP_ERR_OK)
191 trader->MoveItemToInventory(traderDst, hisItems[i], true, true);
192 else
193 LOG_ERROR("network.opcode", "trader can't take item back: {}", hisItems[i]->GetGUID().ToString());
194 }
195 }
196 }
197}
@ ITEM_FIELD_CREATE_PLAYED_TIME
Definition UpdateFields.h:71
Player * GetTrader() const
Definition Player.h:1374

References _player, Player::CanStoreItem(), EQUIP_ERR_OK, Player::GetTotalPlayedTime(), Player::GetTrader(), Object::GetUInt32Value(), ITEM_FIELD_CREATE_PLAYED_TIME, LOG_DEBUG, LOG_ERROR, Player::MoveItemToInventory(), NULL_BAG, NULL_SLOT, Object::SetUInt32Value(), and TRADE_SLOT_TRADED_COUNT.

Referenced by HandleAcceptTradeOpcode().

◆ operator=()

WorldSession & WorldSession::operator= ( WorldSession const &  right)
privatedelete

◆ PlayerLoading()

◆ PlayerLogout()

◆ PlayerLogoutWithSave()

bool WorldSession::PlayerLogoutWithSave ( ) const
inline
384{ return m_playerLogout && m_playerSave; }

References m_playerLogout, and m_playerSave.

◆ PlayerRecentlyLoggedOut()

bool WorldSession::PlayerRecentlyLoggedOut ( ) const
inline
383{ return m_playerRecentlyLogout; }

References m_playerRecentlyLogout.

Referenced by SendCancelTrade().

◆ ProcessMovementInfo()

bool WorldSession::ProcessMovementInfo ( MovementInfo movementInfo,
Unit mover,
Player plrMover,
WorldPacket recvData 
)
597{
598 Opcodes opcode = (Opcodes)recvData.GetOpcode();
599 if (!VerifyMovementInfo(movementInfo, plrMover, mover, opcode))
600 return false;
601
603 {
604 movementInfo.pos.Relocate(mover->GetPositionX(), mover->GetPositionY(), mover->GetPositionZ());
605
606 if (mover->IsCreature())
607 {
608 movementInfo.transport.guid = mover->m_movementInfo.transport.guid;
610 movementInfo.transport.seat = mover->m_movementInfo.transport.seat;
611 }
612 }
613
614 // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
615 if (opcode == MSG_MOVE_FALL_LAND && plrMover && !plrMover->IsInFlight())
616 {
617 plrMover->HandleFall(movementInfo);
618
619 sScriptMgr->AnticheatSetJumpingbyOpcode(plrMover, false);
620 }
621
622 // interrupt parachutes upon falling or landing in water
623 if (opcode == MSG_MOVE_FALL_LAND || opcode == MSG_MOVE_START_SWIM)
624 {
626
627 if (plrMover)
628 {
629 sScriptMgr->AnticheatSetJumpingbyOpcode(plrMover, false);
630 }
631 }
632
633 if (plrMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plrMover->IsInWater())
634 {
635 // now client not include swimming flag in case jumping under water
636 plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetMap()->IsUnderWater(plrMover->GetPhaseMask(), movementInfo.pos.GetPositionX(),
637 movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ(), plrMover->GetCollisionHeight()));
638 }
639
640 if (plrMover)//Hook for OnPlayerMove
641 {
642 sScriptMgr->OnPlayerMove(plrMover, movementInfo, opcode);
643 }
644
646 {
647 if (mover->IsStandState())
650 }
651
652 HandleMoverRelocation(movementInfo, mover);
653
654 if (plrMover && opcode != CMSG_MOVE_KNOCK_BACK_ACK)
655 plrMover->UpdateFallInformationIfNeed(movementInfo, opcode);
656
657 return true;
658}
@ AURA_INTERRUPT_FLAG_LANDING
Definition SpellDefines.h:68
@ MOVEMENTFLAG_MASK_MOVING_OR_TURN
Definition UnitDefines.h:417
@ MOVEMENTFLAG_SWIMMING
Definition UnitDefines.h:390
@ UNIT_FLAG_DISABLE_MOVE
Definition UnitDefines.h:256
bool IsUnderWater(uint32 phaseMask, float x, float y, float z, float collisionHeight) const
Definition Map.cpp:1600
void HandleFall(MovementInfo const &movementInfo)
Definition Player.cpp:13892
void SetInWater(bool apply)
Definition Player.cpp:2156
bool IsInWater() const override
Definition Player.h:1121
void UpdateFallInformationIfNeed(MovementInfo const &minfo, uint16 opcode)
Definition PlayerUpdates.cpp:2172
float GetCollisionHeight() const override
Return collision height sent to client.
Definition Unit.cpp:21198
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:737
uint32 GetPhaseMask() const
Definition Object.h:512
void HandleMoverRelocation(MovementInfo &movementInfo, Unit *mover)
Definition MovementHandler.cpp:411
bool VerifyMovementInfo(MovementInfo const &movementInfo, Player *plrMover, Unit *mover, Opcodes opcode) const
Definition MovementHandler.cpp:513
@ MSG_MOVE_START_SWIM
Definition Opcodes.h:232
@ CMSG_MOVE_KNOCK_BACK_ACK
Definition Opcodes.h:270
@ MSG_MOVE_FALL_LAND
Definition Opcodes.h:231
Position pos
Definition Object.h:308

References AURA_INTERRUPT_FLAG_LANDING, CMSG_MOVE_KNOCK_BACK_ACK, EMOTE_ONESHOT_NONE, MovementInfo::flags, Unit::GetCollisionHeight(), WorldObject::GetMap(), MovementInfo::GetMovementFlags(), WorldPacket::GetOpcode(), WorldObject::GetPhaseMask(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), MovementInfo::TransportInfo::guid, Player::HandleFall(), HandleMoverRelocation(), Unit::HasUnitFlag(), Object::IsCreature(), Unit::IsInFlight(), Player::IsInWater(), Unit::IsStandState(), Map::IsUnderWater(), WorldObject::m_movementInfo, MOVEMENTFLAG_MASK_MOVING_OR_TURN, MOVEMENTFLAG_SWIMMING, MSG_MOVE_FALL_LAND, MSG_MOVE_START_SWIM, MovementInfo::pos, MovementInfo::TransportInfo::pos, Position::Relocate(), Unit::RemoveAurasWithInterruptFlags(), MovementInfo::TransportInfo::seat, Player::SetInWater(), Unit::SetStandState(), Unit::SetUInt32Value(), sScriptMgr, MovementInfo::transport, UNIT_FLAG_DISABLE_MOVE, UNIT_NPC_EMOTESTATE, UNIT_STAND_STATE_STAND, Player::UpdateFallInformationIfNeed(), and VerifyMovementInfo().

Referenced by HandleDismissControlledVehicle(), HandleForceSpeedChangeAck(), HandleMoveFlagChangeOpcode(), HandleMovementOpcodes(), and HandleMoveRootAck().

◆ ProcessQueryCallbacks()

void WorldSession::ProcessQueryCallbacks ( )
private

◆ QueuePacket()

void WorldSession::QueuePacket ( WorldPacket new_packet)

Add an incoming packet to the queue.

303{
304 _recvQueue.add(new_packet);
305}
void add(const T &item)
Adds an item to the back of the queue.
Definition LockedQueue.h:52

References _recvQueue, and LockedQueue< T, StorageType >::add().

Referenced by WorldSocket::ReadDataHandler().

◆ ReadAddonsInfo()

void WorldSession::ReadAddonsInfo ( ByteBuffer data)
Todo:
: Find out when to not use CRC/pubkey, and other possible states.
1152{
1153 if (data.rpos() + 4 > data.size())
1154 return;
1155
1156 uint32 size;
1157 data >> size;
1158
1159 if (!size)
1160 return;
1161
1162 if (size > 0xFFFFF)
1163 {
1164 LOG_ERROR("network", "WorldSession::ReadAddonsInfo addon info too big, size {}", size);
1165 return;
1166 }
1167
1168 uLongf uSize = size;
1169
1170 uint32 pos = data.rpos();
1171
1172 ByteBuffer addonInfo;
1173 addonInfo.resize(size);
1174
1175 if (uncompress(addonInfo.contents(), &uSize, data.contents() + pos, data.size() - pos) == Z_OK)
1176 {
1177 try
1178 {
1179 uint32 addonsCount;
1180 addonInfo >> addonsCount; // addons count
1181
1182 for (uint32 i = 0; i < addonsCount; ++i)
1183 {
1184 std::string addonName;
1185 uint8 enabled;
1186 uint32 crc, unk1;
1187
1188 // check next addon data format correctness
1189 if (addonInfo.rpos() + 1 > addonInfo.size())
1190 return;
1191
1192 addonInfo >> addonName;
1193
1194 addonInfo >> enabled >> crc >> unk1;
1195
1196 LOG_DEBUG("network", "ADDON: Name: {}, Enabled: 0x{:x}, CRC: 0x{:x}, Unknown2: 0x{:x}", addonName, enabled, crc, unk1);
1197
1198 AddonInfo addon(addonName, enabled, crc, 2, true);
1199
1200 SavedAddon const* savedAddon = AddonMgr::GetAddonInfo(addonName);
1201 if (savedAddon)
1202 {
1203 bool match = true;
1204
1205 if (addon.CRC != savedAddon->CRC)
1206 match = false;
1207
1208 if (!match)
1209 LOG_DEBUG("network", "ADDON: {} was known, but didn't match known CRC (0x{:x})!", addon.Name, savedAddon->CRC);
1210 else
1211 LOG_DEBUG("network", "ADDON: {} was known, CRC is correct (0x{:x})", addon.Name, savedAddon->CRC);
1212 }
1213 else
1214 {
1215 AddonMgr::SaveAddon(addon);
1216
1217 LOG_DEBUG("network", "ADDON: {} (0x{:x}) was not known, saving...", addon.Name, addon.CRC);
1218 }
1219
1221 m_addonsList.push_back(addon);
1222 }
1223
1224 uint32 currentTime;
1225 addonInfo >> currentTime;
1226 LOG_DEBUG("network", "ADDON: CurrentTime: {}", currentTime);
1227
1228 if (addonInfo.rpos() != addonInfo.size())
1229 LOG_DEBUG("network", "packet under-read!");
1230 }
1231 catch (ByteBufferException const& e)
1232 {
1233 LOG_ERROR("network", "Addon packet read error! {}", e.what());
1234 }
1235 }
1236 else
1237 LOG_ERROR("network", "Addon packet uncompress error!");
1238}
char const * what() const noexcept override
Definition ByteBuffer.h:36
AddonsList m_addonsList
Definition WorldSession.h:1231
SavedAddon const * GetAddonInfo(const std::string &name)
Definition AddonMgr.cpp:107
void SaveAddon(AddonInfo const &addon)
Definition AddonMgr.cpp:95
Definition AddonMgr.h:27
Definition AddonMgr.h:39
uint32 CRC
Definition AddonMgr.h:43

References ByteBuffer::contents(), AddonInfo::CRC, SavedAddon::CRC, AddonMgr::GetAddonInfo(), LOG_DEBUG, LOG_ERROR, m_addonsList, AddonInfo::Name, ByteBuffer::resize(), ByteBuffer::rpos(), AddonMgr::SaveAddon(), ByteBuffer::size(), and ByteBufferException::what().

Referenced by WorldSocket::HandleAuthSessionCallback().

◆ ReadMovementInfo()

void WorldSession::ReadMovementInfo ( WorldPacket data,
MovementInfo mi 
)

Anti-cheat checks. Please keep them in seperate if () blocks to maintain a clear overview. Might be subject to latency, so just remove improper flags.

This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid in conjunction with any of the moving movement flags such as MOVEMENTFLAG_FORWARD. It will freeze clients that receive this player's movement info.

Cannot hover without SPELL_AURA_HOVER

Cannot ascend and descend at the same time

Cannot move left and right at the same time

Cannot strafe left and right at the same time

Cannot pitch up and down at the same time

Cannot move forwards and backwards at the same time

Cannot walk on water without SPELL_AURA_WATER_WALK

Cannot feather fall without SPELL_AURA_FEATHER_FALL

Cannot fly if no fly auras present. Exception is being a GM. Note that we check for account level instead of Player::IsGameMaster() because in some situations it may be feasable to use .gm fly on as a GM without having .gm on, e.g. aerial combat.

Cannot fly and fall at the same time

1000{
1001 data >> mi->flags;
1002 data >> mi->flags2;
1003 data >> mi->time;
1004 data >> mi->pos.PositionXYZOStream();
1005
1007 {
1008 data >> mi->transport.guid.ReadAsPacked();
1009
1010 data >> mi->transport.pos.PositionXYZOStream();
1011 data >> mi->transport.time;
1012 data >> mi->transport.seat;
1013
1015 data >> mi->transport.time2;
1016 }
1017
1019 data >> mi->pitch;
1020
1021 data >> mi->fallTime;
1022
1024 {
1025 data >> mi->jump.zspeed;
1026 data >> mi->jump.sinAngle;
1027 data >> mi->jump.cosAngle;
1028 data >> mi->jump.xyspeed;
1029 }
1030
1032 data >> mi->splineElevation;
1033
1036#ifdef ACORE_DEBUG
1037#define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
1038 { \
1039 if (check) \
1040 { \
1041 LOG_DEBUG("entities.unit", "WorldSession::ReadMovementInfo: Violation of MovementFlags found ({}). " \
1042 "MovementFlags: {}, MovementFlags2: {} for player {}. Mask {} will be removed.", \
1043 STRINGIZE(check), mi->GetMovementFlags(), mi->GetExtraMovementFlags(), GetPlayer()->GetGUID().ToString(), maskToRemove); \
1044 mi->RemoveMovementFlag((maskToRemove)); \
1045 } \
1046 }
1047#else
1048#define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
1049 if (check) \
1050 mi->RemoveMovementFlag((maskToRemove));
1051#endif
1052
1059
1063
1067
1071
1075
1079
1083
1086 !GetPlayer()->HasWaterWalkAura() &&
1087 !GetPlayer()->HasGhostAura(),
1089
1093
1102
1106
1108 (!GetPlayer()->movespline->Initialized() || GetPlayer()->movespline->Finalized()), MOVEMENTFLAG_SPLINE_ENABLED);
1109
1110#undef REMOVE_VIOLATING_FLAGS
1111}
MovementFlags
Definition UnitDefines.h:367
@ MOVEMENTFLAG_DESCENDING
Definition UnitDefines.h:392
@ MOVEMENTFLAG_PITCH_DOWN
Definition UnitDefines.h:376
@ MOVEMENTFLAG_PITCH_UP
Definition UnitDefines.h:375
@ MOVEMENTFLAG_RIGHT
Definition UnitDefines.h:374
@ MOVEMENTFLAG_SPLINE_ENABLED
Definition UnitDefines.h:396
@ MOVEMENTFLAG_FORWARD
Definition UnitDefines.h:369
@ MOVEMENTFLAG_STRAFE_LEFT
Definition UnitDefines.h:371
@ MOVEMENTFLAG_BACKWARD
Definition UnitDefines.h:370
@ MOVEMENTFLAG_WATERWALKING
Definition UnitDefines.h:397
@ MOVEMENTFLAG_DISABLE_GRAVITY
Definition UnitDefines.h:379
@ MOVEMENTFLAG_FLYING
Definition UnitDefines.h:394
@ MOVEMENTFLAG_FALLING_SLOW
Definition UnitDefines.h:398
@ MOVEMENTFLAG_LEFT
Definition UnitDefines.h:373
@ MOVEMENTFLAG_STRAFE_RIGHT
Definition UnitDefines.h:372
@ MOVEMENTFLAG_ASCENDING
Definition UnitDefines.h:391
@ MOVEMENTFLAG_HOVER
Definition UnitDefines.h:399
@ MOVEMENTFLAG_SPLINE_ELEVATION
Definition UnitDefines.h:395
@ MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING
Definition UnitDefines.h:432
@ MOVEMENTFLAG2_INTERPOLATED_MOVEMENT
Definition UnitDefines.h:437
#define REMOVE_VIOLATING_FLAGS(check, maskToRemove)
float cosAngle
Definition Object.h:328
float xyspeed
Definition Object.h:328
float zspeed
Definition Object.h:328
float sinAngle
Definition Object.h:328
uint32 time2
Definition Object.h:311
uint32 time
Definition Object.h:310
struct MovementInfo::JumpInfo jump
uint16 flags2
Definition Object.h:291
uint32 fallTime
Definition Object.h:318
float splineElevation
Definition Object.h:332
float pitch
Definition Object.h:315
bool HasExtraMovementFlag(uint16 flag) const
Definition Object.h:349
Position::PositionXYZOStreamer PositionXYZOStream()
Definition Position.h:154

References MovementInfo::JumpInfo::cosAngle, MovementInfo::fallTime, MovementInfo::flags, MovementInfo::flags2, GetPlayer(), GetSecurity(), MovementInfo::TransportInfo::guid, MovementInfo::HasExtraMovementFlag(), Unit::HasFlyAura(), Unit::HasIncreaseMountedFlightSpeedAura(), MovementInfo::HasMovementFlag(), MovementInfo::jump, MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING, MOVEMENTFLAG2_INTERPOLATED_MOVEMENT, MOVEMENTFLAG_ASCENDING, MOVEMENTFLAG_BACKWARD, MOVEMENTFLAG_CAN_FLY, MOVEMENTFLAG_DESCENDING, MOVEMENTFLAG_DISABLE_GRAVITY, MOVEMENTFLAG_FALLING, MOVEMENTFLAG_FALLING_SLOW, MOVEMENTFLAG_FLYING, MOVEMENTFLAG_FORWARD, MOVEMENTFLAG_HOVER, MOVEMENTFLAG_LEFT, MOVEMENTFLAG_ONTRANSPORT, MOVEMENTFLAG_PITCH_DOWN, MOVEMENTFLAG_PITCH_UP, MOVEMENTFLAG_RIGHT, MOVEMENTFLAG_ROOT, MOVEMENTFLAG_SPLINE_ELEVATION, MOVEMENTFLAG_SPLINE_ENABLED, MOVEMENTFLAG_STRAFE_LEFT, MOVEMENTFLAG_STRAFE_RIGHT, MOVEMENTFLAG_SWIMMING, MOVEMENTFLAG_WATERWALKING, MovementInfo::pitch, MovementInfo::pos, MovementInfo::TransportInfo::pos, Position::PositionXYZOStream(), ObjectGuid::ReadAsPacked(), REMOVE_VIOLATING_FLAGS, MovementInfo::TransportInfo::seat, SEC_PLAYER, MovementInfo::JumpInfo::sinAngle, MovementInfo::splineElevation, MovementInfo::time, MovementInfo::TransportInfo::time, MovementInfo::TransportInfo::time2, MovementInfo::transport, MovementInfo::JumpInfo::xyspeed, and MovementInfo::JumpInfo::zspeed.

Referenced by HandleChangeSeatsOnControlledVehicle(), HandleDismissControlledVehicle(), HandleForceSpeedChangeAck(), HandleMoveFlagChangeOpcode(), HandleMoveKnockBackAck(), HandleMovementOpcodes(), HandleMoveNotActiveMover(), HandleMoveRootAck(), and HandleMoveSplineDoneOpcode().

◆ recoveryItem()

bool WorldSession::recoveryItem ( Item pItem)
private
1480{
1481 if (sWorld->getBoolConfig(CONFIG_ITEMDELETE_METHOD)
1482 && pItem->GetTemplate()->Quality >= sWorld->getIntConfig(CONFIG_ITEMDELETE_QUALITY)
1483 && pItem->GetTemplate()->ItemLevel >= sWorld->getIntConfig(CONFIG_ITEMDELETE_ITEM_LEVEL))
1484 {
1486
1487 stmt->SetData(0, pItem->GetOwnerGUID().GetCounter());
1488 stmt->SetData(1, pItem->GetTemplate()->ItemId);
1489 stmt->SetData(2, pItem->GetCount());
1490
1491 CharacterDatabase.Query(stmt);
1492
1493 return true;
1494 }
1495
1496 return false;
1497}
@ CHAR_INS_RECOVERY_ITEM
Definition CharacterDatabase.h:508
@ CONFIG_ITEMDELETE_METHOD
Definition WorldConfig.h:120
@ CONFIG_ITEMDELETE_QUALITY
Definition WorldConfig.h:345
@ CONFIG_ITEMDELETE_ITEM_LEVEL
Definition WorldConfig.h:346

References CHAR_INS_RECOVERY_ITEM, CharacterDatabase, CONFIG_ITEMDELETE_ITEM_LEVEL, CONFIG_ITEMDELETE_METHOD, CONFIG_ITEMDELETE_QUALITY, Item::GetCount(), ObjectGuid::GetCounter(), Item::GetOwnerGUID(), Item::GetTemplate(), ItemTemplate::ItemId, ItemTemplate::ItemLevel, ItemTemplate::Quality, PreparedStatementBase::SetData(), and sWorld.

Referenced by HandleDestroyItemOpcode(), and HandleSellItemOpcode().

◆ ResetTimeOutTime()

void WorldSession::ResetTimeOutTime ( bool  onlyActive)
inline
576 {
577 if (GetPlayer())
579 else if (!onlyActive)
581 }
@ CONFIG_SOCKET_TIMEOUTTIME
Definition WorldConfig.h:170
@ CONFIG_SOCKET_TIMEOUTTIME_ACTIVE
Definition WorldConfig.h:340

References CONFIG_SOCKET_TIMEOUTTIME, CONFIG_SOCKET_TIMEOUTTIME_ACTIVE, GetPlayer(), m_timeOutTime, and sWorld.

Referenced by InitializeSessionCallback(), WorldSocket::ReadDataHandler(), WorldSessionMgr::RemoveQueuedPlayer(), and WorldSession().

◆ ResetTimeSync()

void WorldSession::ResetTimeSync ( )

◆ SaveTutorialsData()

void WorldSession::SaveTutorialsData ( CharacterDatabaseTransaction  trans)
981{
983 return;
984
986 stmt->SetData(0, GetAccountId());
987 bool hasTutorials = bool(CharacterDatabase.Query(stmt));
988
989 stmt = CharacterDatabase.GetPreparedStatement(hasTutorials ? CHAR_UPD_TUTORIALS : CHAR_INS_TUTORIALS);
990
991 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
992 stmt->SetData(i, m_Tutorials[i]);
994 trans->Append(stmt);
995
996 m_TutorialsChanged = false;
997}
@ CHAR_INS_TUTORIALS
Definition CharacterDatabase.h:207
@ CHAR_UPD_TUTORIALS
Definition CharacterDatabase.h:208
@ CHAR_SEL_HAS_TUTORIALS
Definition CharacterDatabase.h:206

References CHAR_INS_TUTORIALS, CHAR_SEL_HAS_TUTORIALS, CHAR_UPD_TUTORIALS, CharacterDatabase, GetAccountId(), m_Tutorials, m_TutorialsChanged, MAX_ACCOUNT_TUTORIAL_VALUES, and PreparedStatementBase::SetData().

Referenced by Player::SaveToDB().

◆ SendAccountDataTimes()

void WorldSession::SendAccountDataTimes ( uint32  mask)
946{
947 WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4 + 1 + 4 + 8 * 4); // changed in WotLK
948 data << uint32(GameTime::GetGameTime().count()); // unix time of something
949 data << uint8(1);
950 data << uint32(mask); // type mask
951 for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
952 if (mask & (1 << i))
953 data << uint32(GetAccountData(AccountDataType(i))->Time);// also unix time
954 SendPacket(&data);
955}
@ SMSG_ACCOUNT_DATA_TIMES
Definition Opcodes.h:551

References GetAccountData(), GameTime::GetGameTime(), NUM_ACCOUNT_DATA_TYPES, SendPacket(), and SMSG_ACCOUNT_DATA_TIMES.

Referenced by HandlePlayerLoginFromDB(), HandlePlayerLoginToCharInWorld(), and HandleReadyForAccountDataTimes().

◆ SendActivateTaxiReply()

void WorldSession::SendActivateTaxiReply ( ActivateTaxiReply  reply)
296{
297 GetPlayer()->SetCanTeleport(true);
299 data << uint32(reply);
300 SendPacket(&data);
301
302 LOG_DEBUG("network", "WORLD: Sent SMSG_ACTIVATETAXIREPLY");
303}
@ SMSG_ACTIVATETAXIREPLY
Definition Opcodes.h:460

References GetPlayer(), LOG_DEBUG, SendPacket(), Player::SetCanTeleport(), and SMSG_ACTIVATETAXIREPLY.

Referenced by Player::ActivateTaxiPathTo(), HandleActivateTaxiExpressOpcode(), and HandleActivateTaxiOpcode().

◆ SendAddonsInfo()

void WorldSession::SendAddonsInfo ( )
Todo:
: Find out the meaning of this.
1241{
1242 uint8 addonPublicKey[256] =
1243 {
1244 0xC3, 0x5B, 0x50, 0x84, 0xB9, 0x3E, 0x32, 0x42, 0x8C, 0xD0, 0xC7, 0x48, 0xFA, 0x0E, 0x5D, 0x54,
1245 0x5A, 0xA3, 0x0E, 0x14, 0xBA, 0x9E, 0x0D, 0xB9, 0x5D, 0x8B, 0xEE, 0xB6, 0x84, 0x93, 0x45, 0x75,
1246 0xFF, 0x31, 0xFE, 0x2F, 0x64, 0x3F, 0x3D, 0x6D, 0x07, 0xD9, 0x44, 0x9B, 0x40, 0x85, 0x59, 0x34,
1247 0x4E, 0x10, 0xE1, 0xE7, 0x43, 0x69, 0xEF, 0x7C, 0x16, 0xFC, 0xB4, 0xED, 0x1B, 0x95, 0x28, 0xA8,
1248 0x23, 0x76, 0x51, 0x31, 0x57, 0x30, 0x2B, 0x79, 0x08, 0x50, 0x10, 0x1C, 0x4A, 0x1A, 0x2C, 0xC8,
1249 0x8B, 0x8F, 0x05, 0x2D, 0x22, 0x3D, 0xDB, 0x5A, 0x24, 0x7A, 0x0F, 0x13, 0x50, 0x37, 0x8F, 0x5A,
1250 0xCC, 0x9E, 0x04, 0x44, 0x0E, 0x87, 0x01, 0xD4, 0xA3, 0x15, 0x94, 0x16, 0x34, 0xC6, 0xC2, 0xC3,
1251 0xFB, 0x49, 0xFE, 0xE1, 0xF9, 0xDA, 0x8C, 0x50, 0x3C, 0xBE, 0x2C, 0xBB, 0x57, 0xED, 0x46, 0xB9,
1252 0xAD, 0x8B, 0xC6, 0xDF, 0x0E, 0xD6, 0x0F, 0xBE, 0x80, 0xB3, 0x8B, 0x1E, 0x77, 0xCF, 0xAD, 0x22,
1253 0xCF, 0xB7, 0x4B, 0xCF, 0xFB, 0xF0, 0x6B, 0x11, 0x45, 0x2D, 0x7A, 0x81, 0x18, 0xF2, 0x92, 0x7E,
1254 0x98, 0x56, 0x5D, 0x5E, 0x69, 0x72, 0x0A, 0x0D, 0x03, 0x0A, 0x85, 0xA2, 0x85, 0x9C, 0xCB, 0xFB,
1255 0x56, 0x6E, 0x8F, 0x44, 0xBB, 0x8F, 0x02, 0x22, 0x68, 0x63, 0x97, 0xBC, 0x85, 0xBA, 0xA8, 0xF7,
1256 0xB5, 0x40, 0x68, 0x3C, 0x77, 0x86, 0x6F, 0x4B, 0xD7, 0x88, 0xCA, 0x8A, 0xD7, 0xCE, 0x36, 0xF0,
1257 0x45, 0x6E, 0xD5, 0x64, 0x79, 0x0F, 0x17, 0xFC, 0x64, 0xDD, 0x10, 0x6F, 0xF3, 0xF5, 0xE0, 0xA6,
1258 0xC3, 0xFB, 0x1B, 0x8C, 0x29, 0xEF, 0x8E, 0xE5, 0x34, 0xCB, 0xD1, 0x2A, 0xCE, 0x79, 0xC3, 0x9A,
1259 0x0D, 0x36, 0xEA, 0x01, 0xE0, 0xAA, 0x91, 0x20, 0x54, 0xF0, 0x72, 0xD8, 0x1E, 0xC7, 0x89, 0xD2
1260 };
1261
1263
1264 for (AddonsList::iterator itr = m_addonsList.begin(); itr != m_addonsList.end(); ++itr)
1265 {
1266 data << uint8(itr->State);
1267
1268 uint8 crcpub = itr->UsePublicKeyOrCRC;
1269 data << uint8(crcpub);
1270 if (crcpub)
1271 {
1272 uint8 usepk = (itr->CRC != STANDARD_ADDON_CRC); // If addon is Standard addon CRC
1273 data << uint8(usepk);
1274 if (usepk) // if CRC is wrong, add public key (client need it)
1275 {
1276 LOG_DEBUG("network", "ADDON: CRC (0x{:x}) for addon {} is wrong (does not match expected 0x{:x}), sending pubkey", itr->CRC, itr->Name, STANDARD_ADDON_CRC);
1277 data.append(addonPublicKey, sizeof(addonPublicKey));
1278 }
1279
1280 data << uint32(0);
1281 }
1282
1283 uint8 unk3 = 0; // 0 is sent here
1284 data << uint8(unk3);
1285 if (unk3)
1286 {
1287 // String, length 256 (null terminated)
1288 data << uint8(0);
1289 }
1290 }
1291
1292 m_addonsList.clear();
1293
1295 data << uint32(bannedAddons->size());
1296 for (AddonMgr::BannedAddonList::const_iterator itr = bannedAddons->begin(); itr != bannedAddons->end(); ++itr)
1297 {
1298 data << uint32(itr->Id);
1299 data.append(itr->NameMD5);
1300 data.append(itr->VersionMD5);
1301 data << uint32(itr->Timestamp);
1302 data << uint32(1); // IsBanned
1303 }
1304
1305 SendPacket(&data);
1306}
#define STANDARD_ADDON_CRC
Definition AddonMgr.h:57
@ SMSG_ADDON_INFO
Definition Opcodes.h:781
std::list< BannedAddon > BannedAddonList
Definition AddonMgr.h:65
BannedAddonList const * GetBannedAddons()
Definition AddonMgr.cpp:120

References ByteBuffer::append(), AddonMgr::GetBannedAddons(), LOG_DEBUG, m_addonsList, SendPacket(), SMSG_ADDON_INFO, and STANDARD_ADDON_CRC.

Referenced by InitializeSessionCallback().

◆ SendAreaTriggerMessage() [1/3]

template<typename... Args>
void WorldSession::SendAreaTriggerMessage ( char const *  fmt,
Args &&...  args 
)
inline
404 {
405 if (!m_playerLoading)
406 SendAreaTriggerMessage(Acore::StringFormat(fmt, std::forward<Args>(args)...));
407 }
void SendAreaTriggerMessage(std::string_view str)
Definition WorldSession.cpp:232
std::string StringFormat(FormatString< Args... > fmt, Args &&... args)
Default AC string format function.
Definition StringFormat.h:34

References m_playerLoading, SendAreaTriggerMessage(), and Acore::StringFormat().

◆ SendAreaTriggerMessage() [2/3]

void WorldSession::SendAreaTriggerMessage ( std::string_view  str)
233{
234 std::vector<std::string_view> lines = Acore::Tokenize(str, '\n', true);
235 for (std::string_view line : lines)
236 {
237 uint32 length = line.size() + 1;
238 WorldPacket data(SMSG_AREA_TRIGGER_MESSAGE, 4 + length);
239 data << length;
240 data << line.data();
241 SendPacket(&data);
242 }
243}
@ SMSG_AREA_TRIGGER_MESSAGE
Definition Opcodes.h:726

References SendPacket(), SMSG_AREA_TRIGGER_MESSAGE, and Acore::Tokenize().

Referenced by BattlegroundAB::HandleAreaTrigger(), BattlegroundAV::HandleAreaTrigger(), send_commandscript::HandleSendMessageCommand(), MapMgr::PlayerCannotEnter(), Player::Satisfy(), SendAreaTriggerMessage(), and SendAreaTriggerMessage().

◆ SendAreaTriggerMessage() [3/3]

template<typename... Args>
void WorldSession::SendAreaTriggerMessage ( uint32  strId,
Args &&...  args 
)
inline

◆ SendArenaTeamCommandResult()

void WorldSession::SendArenaTeamCommandResult ( uint32  team_action,
std::string const &  team,
std::string const &  player,
uint32  error_id = 0 
)

◆ SendAttackStop()

void WorldSession::SendAttackStop ( Unit const *  enemy)
85{
86 WorldPacket data(SMSG_ATTACKSTOP, (8 + 8 + 4)); // we guess size
87 data << GetPlayer()->GetPackGUID();
88
89 if (enemy)
90 {
91 data << enemy->GetPackGUID(); // must be packed guid
92 data << (uint32)enemy->isDead();
93 }
94 SendPacket(&data);
95}
@ SMSG_ATTACKSTOP
Definition Opcodes.h:354

References Object::GetPackGUID(), GetPlayer(), Unit::isDead(), SendPacket(), and SMSG_ATTACKSTOP.

Referenced by HandleAttackSwingOpcode().

◆ SendAuctionBidderNotification()

void WorldSession::SendAuctionBidderNotification ( uint32  location,
uint32  auctionId,
ObjectGuid  bidder,
uint32  bidSum,
uint32  diff,
uint32  item_template 
)
89{
91 data << uint32(location);
92 data << uint32(auctionId);
93 data << bidder;
94 data << uint32(bidSum);
95 data << uint32(diff);
96 data << uint32(item_template);
97 data << uint32(0);
98 SendPacket(&data);
99}
@ SMSG_AUCTION_BIDDER_NOTIFICATION
Definition Opcodes.h:636

References SendPacket(), and SMSG_AUCTION_BIDDER_NOTIFICATION.

Referenced by AuctionHouseMgr::SendAuctionOutbiddedMail(), and AuctionHouseMgr::SendAuctionWonMail().

◆ SendAuctionCommandResult()

void WorldSession::SendAuctionCommandResult ( uint32  auctionId,
uint32  Action,
uint32  ErrorCode,
uint32  bidError = 0 
)
77{
79 data << auctionId;
80 data << Action;
81 data << ErrorCode;
82 if (!ErrorCode && Action)
83 data << bidError; //when bid, then send 0, once...
84 SendPacket(&data);
85}
Action
Definition boss_mandokir.cpp:72
@ SMSG_AUCTION_COMMAND_RESULT
Definition Opcodes.h:633

References SendPacket(), and SMSG_AUCTION_COMMAND_RESULT.

Referenced by HandleAuctionPlaceBid(), HandleAuctionRemoveItem(), and HandleAuctionSellItem().

◆ SendAuctionHello()

void WorldSession::SendAuctionHello ( ObjectGuid  guid,
Creature unit 
)
54{
55 if (GetPlayer()->GetLevel() < sWorld->getIntConfig(CONFIG_AUCTION_LEVEL_REQ))
56 {
58 return;
59 }
60
61 if (!sScriptMgr->CanSendAuctionHello(this, guid, unit))
62 return;
63
65 if (!ahEntry)
66 return;
67
69 data << guid;
70 data << uint32(ahEntry->houseId);
71 data << uint8(1); // 3.3.3: 1 - AH enabled, 0 - AH disabled
72 SendPacket(&data);
73}
@ LANG_AUCTION_REQ
Definition Language.h:1169
@ CONFIG_AUCTION_LEVEL_REQ
Definition WorldConfig.h:251
@ MSG_AUCTION_HELLO
Definition Opcodes.h:627

References CONFIG_AUCTION_LEVEL_REQ, AuctionHouseMgr::GetAuctionHouseEntryFromFactionTemplate(), Unit::GetFaction(), GetPlayer(), AuctionHouseEntry::houseId, LANG_AUCTION_REQ, MSG_AUCTION_HELLO, ChatHandler::SendNotification(), SendPacket(), sScriptMgr, and sWorld.

Referenced by HandleAuctionHelloOpcode(), and Player::OnGossipSelect().

◆ SendAuctionOwnerNotification()

void WorldSession::SendAuctionOwnerNotification ( AuctionEntry auction)
103{
105 data << uint32(auction->Id);
106 data << uint32(auction->bid);
107 data << uint32(0); //unk
108 data << uint64(0); //unk (bidder guid?)
109 data << uint32(auction->item_template);
110 data << uint32(0); //unk
111 data << float(0); //unk (time?)
112 SendPacket(&data);
113}
@ SMSG_AUCTION_OWNER_NOTIFICATION
Definition Opcodes.h:637

References AuctionEntry::bid, AuctionEntry::Id, AuctionEntry::item_template, SendPacket(), and SMSG_AUCTION_OWNER_NOTIFICATION.

Referenced by AuctionHouseMgr::SendAuctionExpiredMail(), and AuctionHouseMgr::SendAuctionSuccessfulMail().

◆ SendAuthResponse()

void WorldSession::SendAuthResponse ( uint8  code,
bool  shortForm,
uint32  queuePos = 0 
)
23{
24 WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1 + (shortForm ? 0 : (4 + 1)));
25 packet << uint8(code);
26 packet << uint32(0); // BillingTimeRemaining
27 packet << uint8(0); // BillingPlanFlags
28 packet << uint32(0); // BillingTimeRested
29 uint8 exp = Expansion(); // 0 - normal, 1 - TBC, 2 - WOTLK, must be set in database manually for each account
30
31 if (exp >= MAX_EXPANSIONS)
32 exp = MAX_EXPANSIONS - 1;
33
34 packet << uint8(exp);
35
36 if (!shortForm)
37 {
38 packet << uint32(queuePos); // Queue position
39 packet << uint8(0); // Realm has a free character migration - bool
40 }
41
42 SendPacket(&packet);
43}
@ MAX_EXPANSIONS
Definition SharedDefines.h:56
@ SMSG_AUTH_RESPONSE
Definition Opcodes.h:524

References Expansion(), MAX_EXPANSIONS, SendPacket(), and SMSG_AUTH_RESPONSE.

Referenced by WorldSessionMgr::AddQueuedPlayer(), InitializeSession(), and InitializeSessionCallback().

◆ SendAuthWaitQueue()

void WorldSession::SendAuthWaitQueue ( uint32  position)

Handle the authentication waiting queue (to be completed)

868{
869 if (position == 0)
870 {
872 packet << uint8(AUTH_OK);
873 SendPacket(&packet);
874 }
875 else
876 {
878 packet << uint8(AUTH_WAIT_QUEUE);
879 packet << uint32(position);
880 packet << uint8(0); // unk
881 SendPacket(&packet);
882 }
883}
@ AUTH_WAIT_QUEUE
Definition SharedDefines.h:3616

References AUTH_OK, AUTH_WAIT_QUEUE, SendPacket(), and SMSG_AUTH_RESPONSE.

Referenced by InitializeSessionCallback().

◆ SendBattleGroundList()

void WorldSession::SendBattleGroundList ( ObjectGuid  guid,
BattlegroundTypeId  bgTypeId = BATTLEGROUND_RB 
)
68{
69 WorldPacket data;
70 sBattlegroundMgr->BuildBattlegroundListPacket(&data, guid, _player, bgTypeId, 0);
71 SendPacket(&data);
72}

References _player, sBattlegroundMgr, and SendPacket().

Referenced by HandleBattlemasterHelloOpcode(), and Player::OnGossipSelect().

◆ SendBfEntered()

void WorldSession::SendBfEntered ( uint32  battleId)
75{
76 // m_PlayerInWar[player->GetTeamId()].insert(player->GetGUID());
78 data << uint32(BattleId);
79 data << uint8(1); //unk
80 data << uint8(1); //unk
81 data << uint8(_player->isAFK() ? 1 : 0); //Clear AFK
82 SendPacket(&data);
83}
@ SMSG_BATTLEFIELD_MGR_ENTERED
Definition Opcodes.h:1278

References _player, Player::isAFK(), SendPacket(), and SMSG_BATTLEFIELD_MGR_ENTERED.

Referenced by Battlefield::PlayerAcceptInviteToWar().

◆ SendBfInvitePlayerToQueue()

void WorldSession::SendBfInvitePlayerToQueue ( uint32  battleId)
46{
48
49 data << uint32(BattleId);
50 data << uint8(1); //warmup ? used ?
51
52 //Sending packet to player
53 SendPacket(&data);
54}
@ SMSG_BATTLEFIELD_MGR_QUEUE_INVITE
Definition Opcodes.h:1279

References SendPacket(), and SMSG_BATTLEFIELD_MGR_QUEUE_INVITE.

Referenced by Battlefield::InvitePlayerToQueue().

◆ SendBfInvitePlayerToWar()

void WorldSession::SendBfInvitePlayerToWar ( uint32  battleId,
uint32  zoneId,
uint32  time 
)
32{
33 //Send packet
35 data << uint32(BattleId);
36 data << uint32(ZoneId);
37 data << uint32((GameTime::GetGameTime().count() + p_time));
38
39 //Sending the packet to player
40 SendPacket(&data);
41}
@ SMSG_BATTLEFIELD_MGR_ENTRY_INVITE
Definition Opcodes.h:1276

References GameTime::GetGameTime(), SendPacket(), and SMSG_BATTLEFIELD_MGR_ENTRY_INVITE.

Referenced by Battlefield::InvitePlayerToWar().

◆ SendBfLeaveMessage()

void WorldSession::SendBfLeaveMessage ( uint32  battleId,
BFLeaveReason  reason = BF_LEAVE_REASON_EXITED 
)
86{
88 data << uint32(BattleId);
89 data << uint8(reason);//byte Reason
90 data << uint8(2);//byte BattleStatus
91 data << uint8(0);//bool Relocated
92 SendPacket(&data);
93}
@ SMSG_BATTLEFIELD_MGR_EJECTED
Definition Opcodes.h:1284

References SendPacket(), and SMSG_BATTLEFIELD_MGR_EJECTED.

Referenced by Battlefield::AskToLeaveQueue(), and Battlefield::HandlePlayerLeaveZone().

◆ SendBfQueueInviteResponse()

void WorldSession::SendBfQueueInviteResponse ( uint32  battleId,
uint32  zoneId,
bool  canQueue = true,
bool  full = false 
)
62{
64 data << uint32(BattleId);
65 data << uint32(ZoneId);
66 data << uint8((CanQueue ? 1 : 0)); //Accepted //0 you cannot queue wg //1 you are queued
67 data << uint8((Full ? 0 : 1)); //Logging In //0 wg full //1 queue for upcoming
68 data << uint8(1); //Warmup
69 SendPacket(&data);
70}
@ SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE
Definition Opcodes.h:1282

References SendPacket(), and SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE.

Referenced by Battlefield::PlayerAcceptInviteToQueue().

◆ SendBindPoint()

void WorldSession::SendBindPoint ( Creature npc)
441{
442 // prevent set homebind to instances in any case
443 if (GetPlayer()->GetMap()->Instanceable())
444 return;
445
446 uint32 bindspell = 3286;
447
448 // send spell for homebinding (3286)
449 npc->CastSpell(_player, bindspell, true);
450
452 data << npc->GetGUID();
453 data << uint32(bindspell);
454 SendPacket(&data);
455
457}

References _player, GetPlayer(), Player::PlayerTalkClass, PlayerMenu::SendCloseGossip(), SendPacket(), and SMSG_TRAINER_BUY_SUCCEEDED.

Referenced by HandleBinderActivateOpcode().

◆ SendCalendarRaidLockout()

void WorldSession::SendCalendarRaidLockout ( InstanceSave const *  save,
bool  add 
)
805{
806 LOG_DEBUG("network", "{}", add ? "SMSG_CALENDAR_RAID_LOCKOUT_ADDED" : "SMSG_CALENDAR_RAID_LOCKOUT_REMOVED");
807 time_t currTime = GameTime::GetGameTime().count();
808
809 WorldPacket data(SMSG_CALENDAR_RAID_LOCKOUT_REMOVED, (add ? 4 : 0) + 4 + 4 + 4 + 8);
810 if (add)
811 {
813 data.AppendPackedTime(currTime);
814 }
815
816 data << uint32(save->GetMapId());
817 data << uint32(save->GetDifficulty());
818 data << uint32(save->GetResetTime() >= currTime ? save->GetResetTime() - currTime : 0);
819 data << ObjectGuid::Create<HighGuid::Instance>(save->GetInstanceId());
820 SendPacket(&data);
821}
void AppendPackedTime(time_t time)
Definition ByteBuffer.cpp:137
@ SMSG_CALENDAR_RAID_LOCKOUT_ADDED
Definition Opcodes.h:1116
@ SMSG_CALENDAR_RAID_LOCKOUT_REMOVED
Definition Opcodes.h:1117

References ByteBuffer::AppendPackedTime(), InstanceSave::GetDifficulty(), GameTime::GetGameTime(), InstanceSave::GetInstanceId(), InstanceSave::GetMapId(), InstanceSave::GetResetTime(), LOG_DEBUG, SendPacket(), WorldPacket::SetOpcode(), SMSG_CALENDAR_RAID_LOCKOUT_ADDED, and SMSG_CALENDAR_RAID_LOCKOUT_REMOVED.

Referenced by InstanceSaveMgr::PlayerBindToInstance(), InstanceSaveMgr::PlayerUnbindInstance(), and InstanceSaveMgr::PlayerUnbindInstanceNotExtended().

◆ SendCalendarRaidLockoutUpdated()

void WorldSession::SendCalendarRaidLockoutUpdated ( InstanceSave const *  save,
bool  isExtended 
)
824{
825 time_t currTime = GameTime::GetGameTime().count();
826 time_t resetTime = isExtended ? save->GetExtendedResetTime() : save->GetResetTime();
827 time_t resetTimeOp = isExtended ? save->GetResetTime() : save->GetExtendedResetTime();
828 WorldPacket data(SMSG_CALENDAR_RAID_LOCKOUT_UPDATED, 4 + 4 + 4 + 4 + 8);
829 data.AppendPackedTime(currTime);
830 data << uint32(save->GetMapId());
831 data << uint32(save->GetDifficulty());
832 data << uint32(resetTimeOp >= currTime ? resetTimeOp - currTime : resetTimeOp); // pussywizard: old time in secs to reset
833 data << uint32(resetTime >= currTime ? resetTime - currTime : 0); // pussywizard: new time in secs to reset
834 SendPacket(&data);
835}
@ SMSG_CALENDAR_RAID_LOCKOUT_UPDATED
Definition Opcodes.h:1167

References ByteBuffer::AppendPackedTime(), InstanceSave::GetDifficulty(), InstanceSave::GetExtendedResetTime(), GameTime::GetGameTime(), InstanceSave::GetMapId(), InstanceSave::GetResetTime(), SendPacket(), and SMSG_CALENDAR_RAID_LOCKOUT_UPDATED.

Referenced by HandleSetSavedInstanceExtend().

◆ SendCancelTrade()

void WorldSession::SendCancelTrade ( TradeStatus  status)
528{
530 return;
531
532 SendTradeStatus(status);
533}
bool PlayerRecentlyLoggedOut() const
Definition WorldSession.h:383

References PlayerLogout(), PlayerRecentlyLoggedOut(), and SendTradeStatus().

Referenced by Player::TradeCancel(), and Player::UpdatePosition().

◆ SendCharCreate()

void WorldSession::SendCharCreate ( ResponseCodes  result)
2578{
2580 data << uint8(result);
2581 SendPacket(&data);
2582}
@ SMSG_CHAR_CREATE
Definition Opcodes.h:88

References SendPacket(), and SMSG_CHAR_CREATE.

Referenced by HandleCharCreateOpcode().

◆ SendCharCustomize()

void WorldSession::SendCharCustomize ( ResponseCodes  result,
CharacterCustomizeInfo const *  customizeInfo 
)
2630{
2631 WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1 + 8 + customizeInfo->Name.size() + 1 + 6);
2632 data << uint8(result);
2633 if (result == RESPONSE_SUCCESS)
2634 {
2635 data << customizeInfo->Guid;
2636 data << customizeInfo->Name;
2637 data << uint8(customizeInfo->Gender);
2638 data << uint8(customizeInfo->Skin);
2639 data << uint8(customizeInfo->Face);
2640 data << uint8(customizeInfo->HairStyle);
2641 data << uint8(customizeInfo->HairColor);
2642 data << uint8(customizeInfo->FacialHair);
2643 }
2644 SendPacket(&data);
2645}

References CharacterCustomizeInfo::Face, CharacterCustomizeInfo::FacialHair, CharacterCustomizeInfo::Gender, CharacterRenameInfo::Guid, CharacterCustomizeInfo::HairColor, CharacterCustomizeInfo::HairStyle, CharacterRenameInfo::Name, RESPONSE_SUCCESS, SendPacket(), CharacterCustomizeInfo::Skin, and SMSG_CHAR_CUSTOMIZE.

Referenced by HandleCharCustomizeCallback().

◆ SendCharDelete()

void WorldSession::SendCharDelete ( ResponseCodes  result)
2585{
2587 data << uint8(result);
2588 SendPacket(&data);
2589}
@ SMSG_CHAR_DELETE
Definition Opcodes.h:90

References SendPacket(), and SMSG_CHAR_DELETE.

Referenced by HandleCharDeleteOpcode().

◆ SendCharFactionChange()

void WorldSession::SendCharFactionChange ( ResponseCodes  result,
CharacterFactionChangeInfo const *  factionChangeInfo 
)
2611{
2612 WorldPacket data(SMSG_CHAR_FACTION_CHANGE, 1 + 8 + factionChangeInfo->Name.size() + 1 + 7);
2613 data << uint8(result);
2614 if (result == RESPONSE_SUCCESS)
2615 {
2616 data << factionChangeInfo->Guid;
2617 data << factionChangeInfo->Name;
2618 data << uint8(factionChangeInfo->Gender);
2619 data << uint8(factionChangeInfo->Skin);
2620 data << uint8(factionChangeInfo->Face);
2621 data << uint8(factionChangeInfo->HairStyle);
2622 data << uint8(factionChangeInfo->HairColor);
2623 data << uint8(factionChangeInfo->FacialHair);
2624 data << uint8(factionChangeInfo->Race);
2625 }
2626 SendPacket(&data);
2627}
@ SMSG_CHAR_FACTION_CHANGE
Definition Opcodes.h:1272

References CharacterCustomizeInfo::Face, CharacterCustomizeInfo::FacialHair, CharacterCustomizeInfo::Gender, CharacterRenameInfo::Guid, CharacterCustomizeInfo::HairColor, CharacterCustomizeInfo::HairStyle, CharacterRenameInfo::Name, CharacterFactionChangeInfo::Race, RESPONSE_SUCCESS, SendPacket(), CharacterCustomizeInfo::Skin, and SMSG_CHAR_FACTION_CHANGE.

Referenced by HandleCharFactionOrRaceChange(), and HandleCharFactionOrRaceChangeCallback().

◆ SendCharLoginFailed()

void WorldSession::SendCharLoginFailed ( LoginFailureReason  reason)
2592{
2594 data << uint8(reason);
2595 SendPacket(&data);
2596};
@ SMSG_CHARACTER_LOGIN_FAILED
Definition Opcodes.h:95

References SendPacket(), and SMSG_CHARACTER_LOGIN_FAILED.

Referenced by HandlePlayerLoginOpcode().

◆ SendCharRename()

void WorldSession::SendCharRename ( ResponseCodes  result,
CharacterRenameInfo const *  renameInfo 
)
2599{
2600 WorldPacket data(SMSG_CHAR_RENAME, 1 + 8 + renameInfo->Name.size() + 1);
2601 data << uint8(result);
2602 if (result == RESPONSE_SUCCESS)
2603 {
2604 data << renameInfo->Guid;
2605 data << renameInfo->Name;
2606 }
2607 SendPacket(&data);
2608}
@ SMSG_CHAR_RENAME
Definition Opcodes.h:742

References CharacterRenameInfo::Guid, CharacterRenameInfo::Name, RESPONSE_SUCCESS, SendPacket(), and SMSG_CHAR_RENAME.

Referenced by HandleCharRenameCallBack(), and HandleCharRenameOpcode().

◆ SendChatRestrictedNotice()

void WorldSession::SendChatRestrictedNotice ( ChatRestrictionType  restriction)
794{
796 data << uint8(restriction);
797 SendPacket(&data);
798}
@ SMSG_CHAT_RESTRICTED
Definition Opcodes.h:795

References SendPacket(), and SMSG_CHAT_RESTRICTED.

◆ SendClientCacheVersion()

void WorldSession::SendClientCacheVersion ( uint32  version)
46{
48 data << uint32(version);
49 SendPacket(&data);
50}
@ SMSG_CLIENTCACHE_VERSION
Definition Opcodes.h:1225

References SendPacket(), and SMSG_CLIENTCACHE_VERSION.

Referenced by InitializeSessionCallback().

◆ SendDiscoverNewTaxiNode()

void WorldSession::SendDiscoverNewTaxiNode ( uint32  nodeid)
152{
153 if (GetPlayer()->m_taxi.SetTaximaskNode(nodeid))
154 {
156 SendPacket(&msg);
157 }
158}
@ SMSG_NEW_TAXI_PATH
Definition Opcodes.h:461

References GetPlayer(), SendPacket(), and SMSG_NEW_TAXI_PATH.

Referenced by Spell::EffectDiscoverTaxi().

◆ SendDoFlight()

void WorldSession::SendDoFlight ( uint32  mountDisplayId,
uint32  path,
uint32  pathNode = 0 
)
110{
111 // remove fake death
112 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
114
115 while (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE)
117
118 if (mountDisplayId)
119 GetPlayer()->Mount(mountDisplayId);
120
121 if (Creature* critter = ObjectAccessor::GetCreature(*GetPlayer(), GetPlayer()->GetCritterGUID()))
122 critter->DespawnOrUnsummon();
123
124 GetPlayer()->GetMotionMaster()->MoveTaxiFlight(path, pathNode);
125}
void MoveTaxiFlight(uint32 path, uint32 pathnode)
Definition MotionMaster.cpp:820
void Mount(uint32 mount, uint32 vehicleId=0, uint32 creatureEntry=0)
Definition Unit.cpp:13614
Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:210

References FLIGHT_MOTION_TYPE, ObjectAccessor::GetCreature(), Unit::GetMotionMaster(), GetPlayer(), Unit::Mount(), MotionMaster::MovementExpired(), MotionMaster::MoveTaxiFlight(), Unit::RemoveAurasByType(), SPELL_AURA_FEIGN_DEATH, and UNIT_STATE_DIED.

Referenced by Player::ActivateTaxiPathTo(), and Player::ContinueTaxiFlight().

◆ SendEnchantmentLog()

void WorldSession::SendEnchantmentLog ( ObjectGuid  target,
ObjectGuid  caster,
uint32  itemId,
uint32  enchantId 
)
1037{
1039 enchantmentLog.Target = target.WriteAsPacked();
1040 enchantmentLog.Caster = caster.WriteAsPacked();
1041 enchantmentLog.ItemId = itemId;
1042 enchantmentLog.EnchantId = enchantId;
1043 GetPlayer()->SendMessageToSet(enchantmentLog.Write(), true);
1044}
Definition ItemPackets.h:190
WorldPacket const * Write() override
Definition ItemPackets.cpp:115
uint32 EnchantId
Definition ItemPackets.h:199
PackedGuid Target
Definition ItemPackets.h:196
uint32 ItemId
Definition ItemPackets.h:198
PackedGuid Caster
Definition ItemPackets.h:197

References WorldPackets::Item::EnchantmentLog::Caster, WorldPackets::Item::EnchantmentLog::EnchantId, GetPlayer(), WorldPackets::Item::EnchantmentLog::ItemId, Player::SendMessageToSet(), WorldPackets::Item::EnchantmentLog::Target, WorldPackets::Item::EnchantmentLog::Write(), and ObjectGuid::WriteAsPacked().

Referenced by Item::SetEnchantment().

◆ SendItemEnchantTimeUpdate()

void WorldSession::SendItemEnchantTimeUpdate ( ObjectGuid  Playerguid,
ObjectGuid  Itemguid,
uint32  slot,
uint32  Duration 
)
1047{
1048 WorldPackets::Item::ItemEnchantTimeUpdate itemEnchantTimeUpdate;
1049 itemEnchantTimeUpdate.ItemGuid = Itemguid;
1050 itemEnchantTimeUpdate.Slot = slot;
1051 itemEnchantTimeUpdate.Duration = Duration;
1052 itemEnchantTimeUpdate.PlayerGuid = Playerguid;
1053 SendPacket(itemEnchantTimeUpdate.Write());
1054}
Definition ItemPackets.h:203
ObjectGuid PlayerGuid
Definition ItemPackets.h:213
uint32 Duration
Definition ItemPackets.h:212
uint32 Slot
Definition ItemPackets.h:211
WorldPacket const * Write() override
Definition ItemPackets.cpp:125
ObjectGuid ItemGuid
Definition ItemPackets.h:210

References WorldPackets::Item::ItemEnchantTimeUpdate::Duration, WorldPackets::Item::ItemEnchantTimeUpdate::ItemGuid, WorldPackets::Item::ItemEnchantTimeUpdate::PlayerGuid, SendPacket(), WorldPackets::Item::ItemEnchantTimeUpdate::Slot, and WorldPackets::Item::ItemEnchantTimeUpdate::Write().

Referenced by Player::AddEnchantmentDuration(), and Player::SendEnchantmentDurations().

◆ SendLearnNewTaxiNode()

bool WorldSession::SendLearnNewTaxiNode ( Creature unit)
128{
129 // find current node
130 uint32 curloc = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), GetPlayer()->GetTeamId());
131
132 if (curloc == 0)
133 return true; // `true` send to avoid WorldSession::SendTaxiMenu call with one more curlock seartch with same false result.
134
135 if (GetPlayer()->m_taxi.SetTaximaskNode(curloc))
136 {
138 SendPacket(&msg);
139
141 update << unit->GetGUID();
142 update << uint8(1);
143 SendPacket(&update);
144
145 return true;
146 }
147 else
148 return false;
149}
@ SMSG_TAXINODE_STATUS
Definition Opcodes.h:457

References Object::GetGUID(), WorldLocation::GetMapId(), GetPlayer(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), GetTeamId(), SendPacket(), SMSG_NEW_TAXI_PATH, SMSG_TAXINODE_STATUS, and sObjectMgr.

Referenced by HandleTaxiQueryAvailableNodes().

◆ SendLfgBootProposalUpdate()

void WorldSession::SendLfgBootProposalUpdate ( lfg::LfgPlayerBoot const &  boot)
508{
509 ObjectGuid guid = GetPlayer()->GetGUID();
510 lfg::LfgAnswer playerVote = boot.votes.find(guid)->second;
511 uint8 votesNum = 0;
512 uint8 agreeNum = 0;
513 uint32 secsleft = boot.cancelTime - GameTime::GetGameTime().count();
514 for (lfg::LfgAnswerContainer::const_iterator it = boot.votes.begin(); it != boot.votes.end(); ++it)
515 {
516 if (it->second != lfg::LFG_ANSWER_PENDING)
517 {
518 ++votesNum;
519 if (it->second == lfg::LFG_ANSWER_AGREE)
520 ++agreeNum;
521 }
522 }
523 LOG_DEBUG("network", "SMSG_LFG_BOOT_PROPOSAL_UPDATE [{}] inProgress: {} - didVote: {} - agree: {} - victim: [{}] votes: {} - agrees: {} - left: {} - needed: {} - reason {}",
524 guid.ToString(), uint8(boot.inProgress), uint8(playerVote != lfg::LFG_ANSWER_PENDING), uint8(playerVote == lfg::LFG_ANSWER_AGREE),
525 boot.victim.ToString(), votesNum, agreeNum, secsleft, lfg::LFG_GROUP_KICK_VOTES_NEEDED, boot.reason);
526 WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + boot.reason.length());
527 data << uint8(boot.inProgress); // Vote in progress
528 data << uint8(playerVote != lfg::LFG_ANSWER_PENDING); // Did Vote
529 data << uint8(playerVote == lfg::LFG_ANSWER_AGREE); // Agree
530 data << boot.victim; // Victim GUID
531 data << uint32(votesNum); // Total Votes
532 data << uint32(agreeNum); // Agree Count
533 data << uint32(secsleft); // Time Left
534 data << uint32(lfg::LFG_GROUP_KICK_VOTES_NEEDED); // Needed Votes
535 data << boot.reason.c_str(); // Kick reason
536 SendPacket(&data);
537}
@ SMSG_LFG_BOOT_PROPOSAL_UPDATE
Definition Opcodes.h:907
@ LFG_GROUP_KICK_VOTES_NEEDED
Definition LFGMgr.h:55
LfgAnswer
Answer state (Also used to check compatibilites)
Definition LFG.h:97
@ LFG_ANSWER_AGREE
Definition LFG.h:100
@ LFG_ANSWER_PENDING
Definition LFG.h:98

References lfg::LfgPlayerBoot::cancelTime, GameTime::GetGameTime(), Object::GetGUID(), GetPlayer(), lfg::LfgPlayerBoot::inProgress, lfg::LFG_ANSWER_AGREE, lfg::LFG_ANSWER_PENDING, lfg::LFG_GROUP_KICK_VOTES_NEEDED, LOG_DEBUG, lfg::LfgPlayerBoot::reason, SendPacket(), SMSG_LFG_BOOT_PROPOSAL_UPDATE, ObjectGuid::ToString(), lfg::LfgPlayerBoot::victim, and lfg::LfgPlayerBoot::votes.

◆ SendLfgDisabled()

void WorldSession::SendLfgDisabled ( )
596{
597 LOG_DEBUG("network", "SMSG_LFG_DISABLED [{}]", GetPlayer()->GetGUID().ToString());
599 SendPacket(&data);
600}
@ SMSG_LFG_DISABLED
Definition Opcodes.h:950

References GetPlayer(), LOG_DEBUG, SendPacket(), and SMSG_LFG_DISABLED.

◆ SendLfgJoinResult()

void WorldSession::SendLfgJoinResult ( lfg::LfgJoinResultData const &  joinData)
438{
439 uint32 size = 0;
440 for (lfg::LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it)
441 size += 8 + 4 + uint32(it->second.size()) * (4 + 4);
442
443 LOG_DEBUG("network", "SMSG_LFG_JOIN_RESULT [{}] checkResult: {} checkValue: {}", GetPlayer()->GetGUID().ToString(), joinData.result, joinData.state);
444 WorldPacket data(SMSG_LFG_JOIN_RESULT, 4 + 4 + size);
445 data << uint32(joinData.result); // Check Result
446 data << uint32(joinData.state); // Check Value
447 if (!joinData.lockmap.empty())
448 BuildPartyLockDungeonBlock(data, joinData.lockmap);
449 SendPacket(&data);
450}
@ SMSG_LFG_JOIN_RESULT
Definition Opcodes.h:898

References BuildPartyLockDungeonBlock(), GetPlayer(), lfg::LfgJoinResultData::lockmap, LOG_DEBUG, lfg::LfgJoinResultData::result, SendPacket(), SMSG_LFG_JOIN_RESULT, and lfg::LfgJoinResultData::state.

Referenced by lfg::LFGMgr::JoinLfg(), and lfg::LFGMgr::SendRaidBrowserJoinedPacket().

◆ SendLfgLfrList()

void WorldSession::SendLfgLfrList ( bool  update)
588{
589 LOG_DEBUG("network", "SMSG_LFG_LFR_LIST [{}] update: {}", GetPlayer()->GetGUID().ToString(), update ? 1 : 0);
591 data << uint8(update); // In Lfg Queue?
592 SendPacket(&data);
593}
@ SMSG_LFG_UPDATE_SEARCH
Definition Opcodes.h:903

References GetPlayer(), LOG_DEBUG, SendPacket(), and SMSG_LFG_UPDATE_SEARCH.

Referenced by lfg::LFGPlayerScript::OnPlayerLogout().

◆ SendLfgOfferContinue()

void WorldSession::SendLfgOfferContinue ( uint32  dungeonEntry)
603{
604 LOG_DEBUG("network", "SMSG_LFG_OFFER_CONTINUE [{}] dungeon entry: {}", GetPlayer()->GetGUID().ToString(), dungeonEntry);
606 data << uint32(dungeonEntry);
607 SendPacket(&data);
608}
@ SMSG_LFG_OFFER_CONTINUE
Definition Opcodes.h:689

References GetPlayer(), LOG_DEBUG, SendPacket(), and SMSG_LFG_OFFER_CONTINUE.

◆ SendLfgPlayerReward()

void WorldSession::SendLfgPlayerReward ( lfg::LfgPlayerRewardData const &  lfgPlayerRewardData)
472{
473 if (!rewardData.rdungeonEntry || !rewardData.sdungeonEntry || !rewardData.quest)
474 return;
475
476 LOG_DEBUG("lfg", "SMSG_LFG_PLAYER_REWARD {} rdungeonEntry: {}, sdungeonEntry: {}, done: {}",
477 GetPlayerInfo(), rewardData.rdungeonEntry, rewardData.sdungeonEntry, rewardData.done);
478
479 uint8 itemNum = rewardData.quest->GetRewItemsCount();
480
481 uint8 playerLevel = GetPlayer() ? GetPlayer()->GetLevel() : 0;
482
483 WorldPacket data(SMSG_LFG_PLAYER_REWARD, 4 + 4 + 1 + 4 + 4 + 4 + 4 + 4 + 1 + itemNum * (4 + 4 + 4));
484 data << uint32(rewardData.rdungeonEntry); // Random Dungeon Finished
485 data << uint32(rewardData.sdungeonEntry); // Dungeon Finished
486 data << uint8(rewardData.done);
487 data << uint32(1);
488 data << uint32(rewardData.quest->GetRewOrReqMoney(playerLevel));
489 data << uint32(rewardData.quest->XPValue(playerLevel));
490 data << uint32(0);
491 data << uint32(0);
492 data << uint8(itemNum);
493 if (itemNum)
494 {
495 for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
496 if (uint32 itemId = rewardData.quest->RewardItemId[i])
497 {
498 ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId);
499 data << uint32(itemId);
500 data << uint32(item ? item->DisplayInfoID : 0);
501 data << uint32(rewardData.quest->RewardItemIdCount[i]);
502 }
503 }
504 SendPacket(&data);
505}
@ SMSG_LFG_PLAYER_REWARD
Definition Opcodes.h:541

References ItemTemplate::DisplayInfoID, lfg::LfgPlayerRewardData::done, Unit::GetLevel(), GetPlayer(), GetPlayerInfo(), Quest::GetRewItemsCount(), Quest::GetRewOrReqMoney(), LOG_DEBUG, lfg::LfgPlayerRewardData::quest, QUEST_REWARDS_COUNT, lfg::LfgPlayerRewardData::rdungeonEntry, Quest::RewardItemId, Quest::RewardItemIdCount, lfg::LfgPlayerRewardData::sdungeonEntry, SendPacket(), SMSG_LFG_PLAYER_REWARD, sObjectMgr, and Quest::XPValue().

Referenced by lfg::LFGMgr::FinishDungeon().

◆ SendLfgQueueStatus()

void WorldSession::SendLfgQueueStatus ( lfg::LfgQueueStatusData const &  queueData)
453{
454 LOG_DEBUG("network", "SMSG_LFG_QUEUE_STATUS [{}] dungeon: {} - waitTime: {} - avgWaitTime: {} - waitTimeTanks: {} - waitTimeHealer: {} - waitTimeDps: {} - queuedTime: {} - tanks: {} - healers: {} - dps: {}",
455 GetPlayer()->GetGUID().ToString(), queueData.dungeonId, queueData.waitTime, queueData.waitTimeAvg, queueData.waitTimeTank,
456 queueData.waitTimeHealer, queueData.waitTimeDps, queueData.queuedTime, queueData.tanks, queueData.healers, queueData.dps);
457 WorldPacket data(SMSG_LFG_QUEUE_STATUS, 4 + 4 + 4 + 4 + 4 + 4 + 1 + 1 + 1 + 4);
458 data << uint32(queueData.dungeonId); // Dungeon
459 data << int32(queueData.waitTimeAvg); // Average Wait time
460 data << int32(queueData.waitTime); // Wait Time
461 data << int32(queueData.waitTimeTank); // Wait Tanks
462 data << int32(queueData.waitTimeHealer); // Wait Healers
463 data << int32(queueData.waitTimeDps); // Wait Dps
464 data << uint8(queueData.tanks); // Tanks needed
465 data << uint8(queueData.healers); // Healers needed
466 data << uint8(queueData.dps); // Dps needed
467 data << uint32(queueData.queuedTime); // Player wait time in queue
468 SendPacket(&data);
469}
@ SMSG_LFG_QUEUE_STATUS
Definition Opcodes.h:899

References lfg::LfgQueueStatusData::dps, lfg::LfgQueueStatusData::dungeonId, GetPlayer(), lfg::LfgQueueStatusData::healers, LOG_DEBUG, lfg::LfgQueueStatusData::queuedTime, SendPacket(), SMSG_LFG_QUEUE_STATUS, lfg::LfgQueueStatusData::tanks, lfg::LfgQueueStatusData::waitTime, lfg::LfgQueueStatusData::waitTimeAvg, lfg::LfgQueueStatusData::waitTimeDps, lfg::LfgQueueStatusData::waitTimeHealer, and lfg::LfgQueueStatusData::waitTimeTank.

◆ SendLfgRoleCheckUpdate()

void WorldSession::SendLfgRoleCheckUpdate ( lfg::LfgRoleCheck const &  pRoleCheck)
391{
392 lfg::LfgDungeonSet dungeons;
393 if (roleCheck.rDungeonId)
394 dungeons.insert(roleCheck.rDungeonId);
395 else
396 dungeons = roleCheck.dungeons;
397
398 LOG_DEBUG("network", "SMSG_LFG_ROLE_CHECK_UPDATE [{}]", GetPlayer()->GetGUID().ToString());
399 WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + dungeons.size() * 4 + 1 + roleCheck.roles.size() * (8 + 1 + 4 + 1));
400
401 data << uint32(roleCheck.state); // Check result
402 data << uint8(roleCheck.state == lfg::LFG_ROLECHECK_INITIALITING);
403 data << uint8(dungeons.size()); // Number of dungeons
404 if (!dungeons.empty())
405 for (lfg::LfgDungeonSet::iterator it = dungeons.begin(); it != dungeons.end(); ++it)
406 data << uint32(sLFGMgr->GetLFGDungeonEntry(*it)); // Dungeon
407
408 data << uint8(roleCheck.roles.size()); // Players in group
409 if (!roleCheck.roles.empty())
410 {
411 // Leader info MUST be sent 1st :S
412 ObjectGuid guid = roleCheck.leader;
413 uint8 roles = roleCheck.roles.find(guid)->second;
414 data << guid; // Guid
415 data << uint8(roles > 0); // Ready
416 data << uint32(roles); // Roles
418 data << uint8(player ? player->GetLevel() : 0); // Level
419
420 for (lfg::LfgRolesMap::const_iterator it = roleCheck.roles.begin(); it != roleCheck.roles.end(); ++it)
421 {
422 if (it->first == roleCheck.leader)
423 continue;
424
425 guid = it->first;
426 roles = it->second;
427 data << guid; // Guid
428 data << uint8(roles > 0); // Ready
429 data << uint32(roles); // Roles
431 data << uint8(player ? player->GetLevel() : 0);// Level
432 }
433 }
434 SendPacket(&data);
435}
@ SMSG_LFG_ROLE_CHECK_UPDATE
Definition Opcodes.h:897
@ LFG_ROLECHECK_INITIALITING
Definition LFGMgr.h:126

References lfg::LfgRoleCheck::dungeons, ObjectAccessor::FindConnectedPlayer(), Unit::GetLevel(), GetPlayer(), lfg::LfgRoleCheck::leader, lfg::LFG_ROLECHECK_INITIALITING, LOG_DEBUG, lfg::LfgRoleCheck::rDungeonId, lfg::LfgRoleCheck::roles, SendPacket(), sLFGMgr, SMSG_LFG_ROLE_CHECK_UPDATE, and lfg::LfgRoleCheck::state.

◆ SendLfgRoleChosen()

void WorldSession::SendLfgRoleChosen ( ObjectGuid  guid,
uint8  roles 
)
380{
381 LOG_DEBUG("network", "SMSG_LFG_ROLE_CHOSEN [{}] guid: [{}] roles: {}", GetPlayer()->GetGUID().ToString(), guid.ToString(), roles);
382
383 WorldPacket data(SMSG_LFG_ROLE_CHOSEN, 8 + 1 + 4);
384 data << guid; // Guid
385 data << uint8(roles > 0); // Ready
386 data << uint32(roles); // Roles
387 SendPacket(&data);
388}
@ SMSG_LFG_ROLE_CHOSEN
Definition Opcodes.h:729

References GetPlayer(), LOG_DEBUG, SendPacket(), SMSG_LFG_ROLE_CHOSEN, and ObjectGuid::ToString().

Referenced by lfg::LFGMgr::SendLfgRoleChosen().

◆ SendLfgTeleportError()

void WorldSession::SendLfgTeleportError ( uint8  err)
611{
612 LOG_DEBUG("network", "SMSG_LFG_TELEPORT_DENIED [{}] reason: {}", GetPlayer()->GetGUID().ToString(), err);
614 data << uint32(err); // Error
615 SendPacket(&data);
616}
@ SMSG_LFG_TELEPORT_DENIED
Definition Opcodes.h:542

References GetPlayer(), LOG_DEBUG, SendPacket(), and SMSG_LFG_TELEPORT_DENIED.

Referenced by lfg::LFGMgr::TeleportPlayer().

◆ SendLfgUpdateParty()

void WorldSession::SendLfgUpdateParty ( lfg::LfgUpdateData const &  updateData)
336{
337 bool join = false;
338 bool queued = false;
339 uint8 size = uint8(updateData.dungeons.size());
340
341 switch (updateData.updateType)
342 {
343 case lfg::LFG_UPDATETYPE_ADDED_TO_QUEUE: // Rolecheck Success
344 queued = true;
345 [[fallthrough]];
347 join = true;
348 break;
350 join = updateData.state != lfg::LFG_STATE_ROLECHECK && updateData.state != lfg::LFG_STATE_NONE;
351 queued = updateData.state == lfg::LFG_STATE_QUEUED;
352 break;
353 default:
354 break;
355 }
356
357 LOG_DEBUG("lfg", "SMSG_LFG_UPDATE_PARTY {} updatetype: {}",
358 GetPlayerInfo(), updateData.updateType);
359 WorldPacket data(SMSG_LFG_UPDATE_PARTY, 1 + 1 + (size > 0 ? 1 : 0) * (1 + 1 + 1 + 1 + 1 + size * 4 + updateData.comment.length()));
360 data << uint8(updateData.updateType); // Lfg Update type
361 data << uint8(size > 0); // Extra info
362 if (size)
363 {
364 data << uint8(join); // LFG Join
365 data << uint8(queued); // Join the queue
366 data << uint8(0); // unk - Always 0
367 data << uint8(0); // unk - Always 0
368 for (uint8 i = 0; i < 3; ++i)
369 data << uint8(0); // unk - Always 0
370
371 data << uint8(size);
372 for (lfg::LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it)
373 data << uint32(*it);
374 data << updateData.comment;
375 }
376 SendPacket(&data);
377}
@ SMSG_LFG_UPDATE_PARTY
Definition Opcodes.h:902
@ LFG_STATE_ROLECHECK
Definition LFG.h:69
@ LFG_UPDATETYPE_ADDED_TO_QUEUE
Definition LFG.h:59
@ LFG_UPDATETYPE_UPDATE_STATUS
Definition LFG.h:61
@ LFG_UPDATETYPE_PROPOSAL_BEGIN
Definition LFG.h:60

References lfg::LfgUpdateData::comment, lfg::LfgUpdateData::dungeons, GetPlayerInfo(), lfg::LFG_STATE_NONE, lfg::LFG_STATE_QUEUED, lfg::LFG_STATE_ROLECHECK, lfg::LFG_UPDATETYPE_ADDED_TO_QUEUE, lfg::LFG_UPDATETYPE_PROPOSAL_BEGIN, lfg::LFG_UPDATETYPE_UPDATE_STATUS, LOG_DEBUG, SendPacket(), SMSG_LFG_UPDATE_PARTY, lfg::LfgUpdateData::state, and lfg::LfgUpdateData::updateType.

Referenced by HandleLfgGetStatus(), and lfg::LFGMgr::SendRaidBrowserJoinedPacket().

◆ SendLfgUpdatePlayer()

void WorldSession::SendLfgUpdatePlayer ( lfg::LfgUpdateData const &  updateData)
299{
300 bool queued = false;
301 uint8 size = uint8(updateData.dungeons.size());
302
303 switch (updateData.updateType)
304 {
307 queued = true;
308 break;
310 queued = updateData.state == lfg::LFG_STATE_QUEUED;
311 break;
312 default:
313 break;
314 }
315
316 LOG_DEBUG("lfg", "SMSG_LFG_UPDATE_PLAYER {} updatetype: {}",
317 GetPlayerInfo(), updateData.updateType);
318 WorldPacket data(SMSG_LFG_UPDATE_PLAYER, 1 + 1 + (size > 0 ? 1 : 0) * (1 + 1 + 1 + 1 + size * 4 + updateData.comment.length()));
319 data << uint8(updateData.updateType); // Lfg Update type
320 data << uint8(size > 0); // Extra info
321 if (size)
322 {
323 data << uint8(queued); // Join the queue
324 data << uint8(0); // unk - Always 0
325 data << uint8(0); // unk - Always 0
326
327 data << uint8(size);
328 for (lfg::LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it)
329 data << uint32(*it);
330 data << updateData.comment;
331 }
332 SendPacket(&data);
333}
@ SMSG_LFG_UPDATE_PLAYER
Definition Opcodes.h:901
@ LFG_UPDATETYPE_JOIN_QUEUE
Definition LFG.h:53

References lfg::LfgUpdateData::comment, lfg::LfgUpdateData::dungeons, GetPlayerInfo(), lfg::LFG_STATE_QUEUED, lfg::LFG_UPDATETYPE_ADDED_TO_QUEUE, lfg::LFG_UPDATETYPE_JOIN_QUEUE, lfg::LFG_UPDATETYPE_UPDATE_STATUS, LOG_DEBUG, SendPacket(), SMSG_LFG_UPDATE_PLAYER, lfg::LfgUpdateData::state, and lfg::LfgUpdateData::updateType.

Referenced by HandleLfgGetStatus(), lfg::LFGMgr::JoinLfg(), and lfg::LFGMgr::SendRaidBrowserJoinedPacket().

◆ SendLfgUpdateProposal()

void WorldSession::SendLfgUpdateProposal ( lfg::LfgProposal const &  proposal)
540{
541 ObjectGuid guid = GetPlayer()->GetGUID();
542 ObjectGuid gguid = proposal.players.find(guid)->second.group;
543 bool silent = !proposal.isNew && gguid == proposal.group;
544 uint32 dungeonEntry = proposal.dungeonId;
545
546 LOG_DEBUG("network", "SMSG_LFG_PROPOSAL_UPDATE [{} state: {}", guid.ToString(), proposal.state);
547
548 // show random dungeon if player selected random dungeon and it's not lfg group
549 if (!silent)
550 {
551 lfg::LfgDungeonSet const& playerDungeons = sLFGMgr->GetSelectedDungeons(guid);
552 if (playerDungeons.find(proposal.dungeonId) == playerDungeons.end())
553 dungeonEntry = (*playerDungeons.begin());
554 }
555
556 dungeonEntry = sLFGMgr->GetLFGDungeonEntry(dungeonEntry);
557
558 WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + proposal.players.size() * (4 + 1 + 1 + 1 + 1 + 1));
559 data << uint32(dungeonEntry); // Dungeon
560 data << uint8(proposal.state); // Proposal state
561 data << uint32(proposal.id); // Proposal ID
562 data << uint32(proposal.encounters); // encounters done
563 data << uint8(silent); // Show proposal window
564 data << uint8(proposal.players.size()); // Group size
565
566 for (lfg::LfgProposalPlayerContainer::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it)
567 {
568 lfg::LfgProposalPlayer const& player = it->second;
569 data << uint32(player.role); // Role
570 data << uint8(it->first == guid); // Self player
571 if (!player.group) // Player not it a group
572 {
573 data << uint8(0); // Not in dungeon
574 data << uint8(0); // Not same group
575 }
576 else
577 {
578 data << uint8(player.group == proposal.group); // In dungeon (silent)
579 data << uint8(player.group == gguid); // Same Group than player
580 }
581 data << uint8(player.accept != lfg::LFG_ANSWER_PENDING);// Answered
582 data << uint8(player.accept == lfg::LFG_ANSWER_AGREE); // Accepted
583 }
584 SendPacket(&data);
585}
@ SMSG_LFG_PROPOSAL_UPDATE
Definition Opcodes.h:895
Definition LFGMgr.h:346
uint8 role
Proposed role.
Definition LFGMgr.h:348
ObjectGuid group
Original group guid. 0 if no original group.
Definition LFGMgr.h:350
LfgAnswer accept
Accept status (-1 not answer | 0 Not agree | 1 agree)
Definition LFGMgr.h:349

References lfg::LfgProposalPlayer::accept, lfg::LfgProposal::dungeonId, lfg::LfgProposal::encounters, Object::GetGUID(), GetPlayer(), lfg::LfgProposalPlayer::group, lfg::LfgProposal::group, lfg::LfgProposal::id, lfg::LfgProposal::isNew, lfg::LFG_ANSWER_AGREE, lfg::LFG_ANSWER_PENDING, LOG_DEBUG, lfg::LfgProposal::players, lfg::LfgProposalPlayer::role, SendPacket(), sLFGMgr, SMSG_LFG_PROPOSAL_UPDATE, lfg::LfgProposal::state, and ObjectGuid::ToString().

◆ SendListInventory()

void WorldSession::SendListInventory ( ObjectGuid  guid,
uint32  vendorEntry = 0 
)
852{
853 LOG_DEBUG("network", "WORLD: Sent SMSG_LIST_INVENTORY");
854
855 sScriptMgr->OnPlayerSendListInventory(GetPlayer(), vendorGuid, vendorEntry);
856
858 if (!vendor)
859 {
860 LOG_DEBUG("network", "WORLD: SendListInventory - Unit ({}) not found or you can not interact with him.", vendorGuid.ToString());
862 return;
863 }
864
865 // remove fake death
866 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
867 {
869 }
870
871 // Stop the npc if moving
873 vendor->PauseMovement(pause);
874 vendor->SetHomePosition(vendor->GetPosition());
875
876 SetCurrentVendor(vendorEntry);
877
878 VendorItemData const* items = vendorEntry ? sObjectMgr->GetNpcVendorItemList(vendorEntry) : vendor->GetVendorItems();
879 if (!items)
880 {
881 WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + 1);
882 data << vendorGuid;
883 data << uint8(0); // count == 0, next will be error code
884 data << uint8(0); // "Vendor has no inventory"
885 SendPacket(&data);
886 return;
887 }
888
889 uint8 itemCount = items->GetItemCount();
890 uint8 count = 0;
891
892 WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + itemCount * 8 * 4);
893 data << vendorGuid;
894
895 std::size_t countPos = data.wpos();
896 data << uint8(count);
897
898 float discountMod = _player->GetReputationPriceDiscount(vendor);
899
900 for (uint8 slot = 0; slot < itemCount; ++slot)
901 {
902 if (VendorItem const* item = items->GetItem(slot))
903 {
904 if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(item->item))
905 {
906 if (!(itemTemplate->AllowableClass & _player->getClassMask()) && itemTemplate->Bonding == BIND_WHEN_PICKED_UP && !_player->IsGameMaster())
907 {
908 continue;
909 }
910 // Only display items in vendor lists for the team the
911 // player is on. If GM on, display all items.
912 if (!_player->IsGameMaster() && ((itemTemplate->HasFlag2(ITEM_FLAG2_FACTION_HORDE) && _player->GetTeamId() == TEAM_ALLIANCE) || (itemTemplate->HasFlag2(ITEM_FLAG2_FACTION_ALLIANCE) && _player->GetTeamId() == TEAM_HORDE)))
913 {
914 continue;
915 }
916
917 // Items sold out are not displayed in list
918 uint32 leftInStock = !item->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(item);
919 if (!_player->IsGameMaster() && !leftInStock)
920 {
921 continue;
922 }
923
924 ConditionList conditions = sConditionMgr->GetConditionsForNpcVendorEvent(vendor->GetEntry(), item->item);
925 if (!sConditionMgr->IsObjectMeetToConditions(_player, vendor, conditions))
926 {
927 LOG_DEBUG("network", "SendListInventory: conditions not met for creature entry {} item {}", vendor->GetEntry(), item->item);
928 continue;
929 }
930
931 // reputation discount
932 int32 price = item->IsGoldRequired(itemTemplate) ? uint32(std::floor(itemTemplate->BuyPrice * discountMod)) : 0;
933
934 data << uint32(slot + 1); // client expects counting to start at 1
935 data << uint32(item->item);
936 data << uint32(itemTemplate->DisplayInfoID);
937 data << int32(leftInStock);
938 data << uint32(price);
939 data << uint32(itemTemplate->MaxDurability);
940 data << uint32(itemTemplate->BuyCount);
941 data << uint32(item->ExtendedCost);
942
943 if (++count >= MAX_VENDOR_ITEMS)
944 {
945 break;
946 }
947 }
948 }
949 }
950
951 if (count == 0)
952 {
953 data << uint8(0);
954 SendPacket(&data);
955 return;
956 }
957
958 data.put<uint8>(countPos, count);
959 SendPacket(&data);
960}
#define sConditionMgr
Definition ConditionMgr.h:291
std::list< Condition * > ConditionList
Definition ConditionMgr.h:238
#define MAX_VENDOR_ITEMS
Definition Creature.h:40
@ ITEM_FLAG2_FACTION_HORDE
Definition ItemTemplate.h:183
@ ITEM_FLAG2_FACTION_ALLIANCE
Definition ItemTemplate.h:184
VendorItemData const * GetVendorItems() const
Definition Creature.cpp:3069
uint32 GetVendorItemCurrentCount(VendorItem const *vItem)
Definition Creature.cpp:3074
void SetCurrentVendor(uint32 vendorEntry)
Definition WorldSession.h:429
@ SMSG_LIST_INVENTORY
Definition Opcodes.h:445
Definition CreatureData.h:469
VendorItem * GetItem(uint32 slot) const
Definition CreatureData.h:472
uint8 GetItemCount() const
Definition CreatureData.h:480
Definition CreatureData.h:454

References _player, BIND_WHEN_PICKED_UP, ObjectGuid::Empty, Unit::getClassMask(), Object::GetEntry(), CreatureMovementData::GetInteractionPauseTimer(), VendorItemData::GetItem(), VendorItemData::GetItemCount(), Creature::GetMovementTemplate(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Position::GetPosition(), Player::GetReputationPriceDiscount(), Player::GetTeamId(), Creature::GetVendorItemCurrentCount(), Creature::GetVendorItems(), Player::IsGameMaster(), ITEM_FLAG2_FACTION_ALLIANCE, ITEM_FLAG2_FACTION_HORDE, LOG_DEBUG, MAX_VENDOR_ITEMS, Unit::PauseMovement(), ByteBuffer::put(), Unit::RemoveAurasByType(), sConditionMgr, SELL_ERR_CANT_FIND_VENDOR, SendPacket(), Player::SendSellError(), SetCurrentVendor(), Creature::SetHomePosition(), SMSG_LIST_INVENTORY, sObjectMgr, SPELL_AURA_FEIGN_DEATH, sScriptMgr, TEAM_ALLIANCE, TEAM_HORDE, ObjectGuid::ToString(), UNIT_NPC_FLAG_VENDOR, UNIT_STATE_DIED, and ByteBuffer::wpos().

Referenced by HandleListInventoryOpcode(), npc_pet_gen_argent_pony_bridle::OnGossipSelect(), npc_lokhtos_darkbargainer::OnGossipSelect(), npc_augustus_the_touched::OnGossipSelect(), npc_rivern_frostwind::OnGossipSelect(), npc_roxi_ramrocket::OnGossipSelect(), npc_wg_quest_giver::OnGossipSelect(), npc_drake_dealer_hurlunk::OnGossipSelect(), npc_shattrathflaskvendors::OnGossipSelect(), npc_slim::OnGossipSelect(), npc_innkeeper::OnGossipSelect(), Player::OnGossipSelect(), npc_prof_alchemy::SendActionMenu(), npc_prof_blacksmith::SendActionMenu(), and npc_prof_tailor::SendActionMenu().

◆ SendNameQueryOpcode()

void WorldSession::SendNameQueryOpcode ( ObjectGuid  guid)
33{
34 CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(guid);
35
37 nameQueryResponse.Guid = guid.WriteAsPacked();
38 if (!playerData)
39 {
40 nameQueryResponse.NameUnknown = true;
41 SendPacket(nameQueryResponse.Write());
42 return;
43 }
44
46
47 nameQueryResponse.NameUnknown = false;
48 nameQueryResponse.Name = playerData->Name;
49 nameQueryResponse.Race = player ? player->getRace() : playerData->Race;
50 nameQueryResponse.Sex = player ? player->getGender() : playerData->Sex;
51 nameQueryResponse.Class = player ? player->getClass() : playerData->Class;
52
53 if (DeclinedName const* names = (player ? player->GetDeclinedNames() : nullptr))
54 {
55 nameQueryResponse.Declined = true;
56 nameQueryResponse.DeclinedNames = *names;
57 }
58 else
59 nameQueryResponse.Declined = false;
60
61 SendPacket(nameQueryResponse.Write());
62}
DeclinedName const * GetDeclinedNames() const
Definition Player.h:2518
Definition QueryPackets.h:39
DeclinedName DeclinedNames
Definition QueryPackets.h:53
uint8 Race
Definition QueryPackets.h:49
WorldPacket const * Write() override
Definition QueryPackets.cpp:25
uint8 NameUnknown
Definition QueryPackets.h:46
uint8 Declined
Definition QueryPackets.h:52
uint8 Class
Definition QueryPackets.h:51
std::string_view Name
Definition QueryPackets.h:47
uint8 Sex
Definition QueryPackets.h:50
PackedGuid Guid
Definition QueryPackets.h:45
uint8 Sex
Definition CharacterCache.h:34

References CharacterCacheEntry::Class, WorldPackets::Query::NameQueryResponse::Class, WorldPackets::Query::NameQueryResponse::Declined, WorldPackets::Query::NameQueryResponse::DeclinedNames, ObjectAccessor::FindConnectedPlayer(), Unit::getClass(), Player::GetDeclinedNames(), Unit::getGender(), Unit::getRace(), WorldPackets::Query::NameQueryResponse::Guid, CharacterCacheEntry::Name, WorldPackets::Query::NameQueryResponse::Name, WorldPackets::Query::NameQueryResponse::NameUnknown, CharacterCacheEntry::Race, WorldPackets::Query::NameQueryResponse::Race, sCharacterCache, SendPacket(), CharacterCacheEntry::Sex, WorldPackets::Query::NameQueryResponse::Sex, WorldPackets::Query::NameQueryResponse::Write(), and ObjectGuid::WriteAsPacked().

Referenced by HandleNameQueryOpcode(), HandlePlayerLoginFromDB(), and lfg::LFGPlayerScript::OnPlayerMapChanged().

◆ SendNotInArenaTeamPacket()

void WorldSession::SendNotInArenaTeamPacket ( uint8  type)
417{
418 WorldPacket data(SMSG_ARENA_ERROR, 4 + 1); // 886 - You are not in a %uv%u arena team
419 uint32 unk = 0;
420 data << uint32(unk); // unk(0)
421 if (!unk)
422 data << uint8(type); // team type (2=2v2, 3=3v3, 5=5v5), can be used for custom types...
423 SendPacket(&data);
424}
@ SMSG_ARENA_ERROR
Definition Opcodes.h:916

References SendPacket(), and SMSG_ARENA_ERROR.

Referenced by HandleBattlemasterJoinArena().

◆ SendPacket()

void WorldSession::SendPacket ( WorldPacket const *  packet)

Send a packet to the client.

253{
254 if (!m_Socket)
255 return;
256
257#if defined(ACORE_DEBUG)
258 // Code for network use statistic
259 static uint64 sendPacketCount = 0;
260 static uint64 sendPacketBytes = 0;
261
262 static time_t firstTime = GameTime::GetGameTime().count();
263 static time_t lastTime = firstTime; // next 60 secs start time
264
265 static uint64 sendLastPacketCount = 0;
266 static uint64 sendLastPacketBytes = 0;
267
268 time_t cur_time = GameTime::GetGameTime().count();
269
270 if ((cur_time - lastTime) < 60)
271 {
272 sendPacketCount += 1;
273 sendPacketBytes += packet->size();
274
275 sendLastPacketCount += 1;
276 sendLastPacketBytes += packet->size();
277 }
278 else
279 {
280 uint64 minTime = uint64(cur_time - lastTime);
281 uint64 fullTime = uint64(lastTime - firstTime);
282
283 LOG_DEBUG("network", "Send all time packets count: {} bytes: {} avr.count/sec: {} avr.bytes/sec: {} time: {}", sendPacketCount, sendPacketBytes, float(sendPacketCount) / fullTime, float(sendPacketBytes) / fullTime, uint32(fullTime));
284
285 LOG_DEBUG("network", "Send last min packets count: {} bytes: {} avr.count/sec: {} avr.bytes/sec: {}", sendLastPacketCount, sendLastPacketBytes, float(sendLastPacketCount) / minTime, float(sendLastPacketBytes) / minTime);
286
287 lastTime = cur_time;
288 sendLastPacketCount = 1;
289 sendLastPacketBytes = packet->wpos(); // wpos is real written size
290 }
291#endif // !ACORE_DEBUG
292
293 if (!sScriptMgr->CanPacketSend(this, *packet))
294 {
295 return;
296 }
297
298 m_Socket->SendPacket(*packet);
299}

References GameTime::GetGameTime(), LOG_DEBUG, m_Socket, ByteBuffer::size(), sScriptMgr, and ByteBuffer::wpos().

Referenced by Guild::_SendBankList(), HandleAlterAppearance(), HandleAuctionListPendingSales(), HandleBattlefieldListOpcode(), HandleBattleFieldPortOpcode(), HandleBattlefieldStatusOpcode(), HandleBattlegroundPlayerPositionsOpcode(), HandleBattlemasterJoinArena(), HandleBattlemasterJoinOpcode(), HandleBuyBankSlotOpcode(), HandleCalendarGetCalendar(), HandleCalendarGetNumPending(), HandleCharCustomize(), HandleCharEnum(), HandleComplainOpcode(), HandleCorpseMapPositionQuery(), HandleCorpseQueryOpcode(), HandleCreatureQueryOpcode(), debug_commandscript::HandleDebugSendChannelNotifyCommand(), debug_commandscript::HandleDebugSendChatMsgCommand(), debug_commandscript::HandleDebugSendSpellFailCommand(), HandleEquipmentSetUse(), HandleGameObjectQueryOpcode(), HandleGetChannelMemberCount(), HandleGetMailList(), HandleGMResponseResolve(), HandleGMTicketCreateOpcode(), HandleGMTicketDeleteOpcode(), HandleGMTicketSystemStatusOpcode(), HandleGMTicketUpdateOpcode(), HandleGrantLevel(), HandleInspectHonorStatsOpcode(), HandleInspectOpcode(), HandleItemNameQueryOpcode(), HandleItemQuerySingleOpcode(), HandleItemTextQuery(), HandleLfgPartyLockInfoRequestOpcode(), HandleLfgPlayerLockInfoRequestOpcode(), HandleLogoutCancelOpcode(), HandleLogoutRequestOpcode(), HandleLootMoneyOpcode(), HandleMirrorImageDataRequest(), HandleNpcTextQueryOpcode(), HandlePageTextQueryOpcode(), HandlePetActionHelper(), HandlePetitionRenameOpcode(), HandlePetitionShowSignOpcode(), HandlePetitionSignOpcode(), HandlePlayedTime(), HandlePlayerLoginFromDB(), HandlePlayerLoginToCharInWorld(), HandlePVPLogDataOpcode(), Guild::HandleQuery(), HandleQueryNextMailTime(), HandleQueryQuestsCompleted(), HandleQuestPOIQuery(), HandleReadItem(), HandleRealmSplitOpcode(), HandleRequestAccountData(), HandleRequestPartyMemberStatsOpcode(), Guild::HandleRoster(), HandleTalentWipeConfirmOpcode(), HandleTrainerBuySpellOpcode(), HandleTurnInPetitionOpcode(), HandleUpdateAccountData(), HandleWhoisOpcode(), HandleWhoOpcode(), HandleWorldStateUITimerUpdate(), WardenWin::InitializeModule(), ArenaTeam::Inspect(), LogoutPlayer(), ArenaTeam::MassInviteToEvent(), Guild::MassInviteToEvent(), ArenaTeam::Query(), WardenMac::RequestChecks(), WardenWin::RequestChecks(), WardenMac::RequestHash(), WardenWin::RequestHash(), Warden::RequestModule(), ArenaTeam::Roster(), AddonChannelCommandHandler::Send(), SendAccountDataTimes(), SendActivateTaxiReply(), SendAddonsInfo(), SendAreaTriggerMessage(), SendArenaTeamCommandResult(), SendAttackStop(), SendAuctionBidderNotification(), SendAuctionCommandResult(), SendAuctionHello(), SendAuctionOwnerNotification(), SendAuthResponse(), SendAuthWaitQueue(), Guild::SendBankLog(), SendBattleGroundList(), SendBfEntered(), SendBfInvitePlayerToQueue(), SendBfInvitePlayerToWar(), SendBfLeaveMessage(), SendBfQueueInviteResponse(), SendBindPoint(), SendCalendarRaidLockout(), SendCalendarRaidLockoutUpdated(), SendCharCreate(), SendCharCustomize(), SendCharDelete(), SendCharFactionChange(), SendCharLoginFailed(), SendCharRename(), SendChatRestrictedNotice(), SendClientCacheVersion(), PlayerMenu::SendCloseGossip(), Guild::SendCommandResult(), Player::SendDirectMessage(), SendDiscoverNewTaxiNode(), Guild::SendEventLog(), ChatHandler::SendGMText(), PlayerMenu::SendGossipMenu(), Guild::SendInfo(), SendItemEnchantTimeUpdate(), SendLearnNewTaxiNode(), SendLfgBootProposalUpdate(), SendLfgDisabled(), SendLfgJoinResult(), SendLfgLfrList(), SendLfgOfferContinue(), SendLfgPlayerReward(), SendLfgQueueStatus(), SendLfgRoleCheckUpdate(), SendLfgRoleChosen(), SendLfgTeleportError(), SendLfgUpdateParty(), SendLfgUpdatePlayer(), SendLfgUpdateProposal(), SendListInventory(), Guild::SendLoginInfo(), Warden::SendModuleToClient(), Guild::SendMoneyInfo(), Unit::SendMoveRoot(), SendNameQueryOpcode(), ChatHandler::SendNotification(), SendNotInArenaTeamPacket(), SendPartyResult(), Guild::SendPermissions(), SendPetitionQueryOpcode(), SendPetitionShowList(), SendPetNameInvalid(), SendPetNameQuery(), SendPlayerAmbiguousNotice(), SendPlayerNotFoundNotice(), PlayerMenu::SendPointOfInterest(), PlayerMenu::SendQuestGiverOfferReward(), PlayerMenu::SendQuestGiverQuestDetails(), PlayerMenu::SendQuestGiverQuestList(), PlayerMenu::SendQuestGiverRequestItems(), PlayerMenu::SendQuestGiverStatus(), PlayerMenu::SendQuestQueryResponse(), GmTicket::SendResponse(), Guild::SendSaveEmblemResult(), SendSetPhaseShift(), SendSetPlayerDeclinedNamesResult(), SendShowBank(), SendShowMailBox(), SendStablePet(), SendStableResult(), ArenaTeam::SendStats(), ChatHandler::SendSysMessage(), AddonChannelCommandHandler::SendSysMessage(), SendTabardVendorActivate(), Group::SendTargetIconList(), SendTaxiMenu(), SendTaxiStatus(), Guild::BankTab::SendText(), TicketMgr::SendTicket(), SendTimeQueryResponse(), SendTimeSync(), SendTradeStatus(), SendTrainerList(), SendTutorialsData(), SendUpdateTrade(), SendWrongFactionNotice(), and Unit::SetSpeed().

◆ SendPartyResult()

void WorldSession::SendPartyResult ( PartyOperation  operation,
std::string const &  member,
PartyResult  res,
uint32  val = 0 
)
54{
55 WorldPacket data(SMSG_PARTY_COMMAND_RESULT, 4 + member.size() + 1 + 4 + 4);
56 data << uint32(operation);
57 data << member;
58 data << uint32(res);
59 data << uint32(val); // LFD cooldown related (used with ERR_PARTY_LFG_BOOT_COOLDOWN_S and ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S)
60
61 SendPacket(&data);
62}
@ SMSG_PARTY_COMMAND_RESULT
Definition Opcodes.h:157

References SendPacket(), and SMSG_PARTY_COMMAND_RESULT.

Referenced by HandleGroupAcceptOpcode(), HandleGroupDisbandOpcode(), HandleGroupInviteOpcode(), HandleGroupRaidConvertOpcode(), HandleGroupSwapSubGroupOpcode(), HandleGroupUninviteGuidOpcode(), and HandleGroupUninviteOpcode().

◆ SendPetitionQueryOpcode()

void WorldSession::SendPetitionQueryOpcode ( ObjectGuid  petitionguid)
283{
284 Petition const* petition = sPetitionMgr->GetPetition(petitionguid);
285 if (!petition)
286 {
287 LOG_DEBUG("network", "CMSG_PETITION_QUERY failed for petition ({})", petitionguid.ToString());
288 return;
289 }
290
291 uint8 type = petition->petitionType;
292 WorldPacket data(SMSG_PETITION_QUERY_RESPONSE, (4 + 8 + petition->petitionName.size() + 1 + 1 + 4 * 12 + 2 + 10));
293 data << uint32(petition->petitionId); // guild/team id (was item low guid)
294 data << petition->ownerGuid; // charter owner guid
295 data << petition->petitionName; // name (guild/arena team)
296 data << uint8(0); // some string
297 if (type == GUILD_CHARTER_TYPE)
298 {
299 uint32 needed = sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS);
300 data << uint32(needed);
301 data << uint32(needed);
302 data << uint32(0); // bypass client - side limitation, a different value is needed here for each petition
303 }
304 else
305 {
306 data << uint32(type - 1);
307 data << uint32(type - 1);
308 data << uint32(type); // bypass client - side limitation, a different value is needed here for each petition
309 }
310 data << uint32(0); // 5
311 data << uint32(0); // 6
312 data << uint32(0); // 7
313 data << uint32(0); // 8
314 data << uint16(0); // 9 2 bytes field
315 data << uint32(0); // 10
316 data << uint32(0); // 11
317 data << uint32(0); // 13 count of next strings?
318
319 for (int i = 0; i < 10; ++i)
320 data << uint8(0); // some string
321
322 data << uint32(0); // 14
323
324 data << uint32(type != GUILD_CHARTER_TYPE); // 15 0 - guild, 1 - arena team
325
326 SendPacket(&data);
327}
@ SMSG_PETITION_QUERY_RESPONSE
Definition Opcodes.h:485

References CONFIG_MIN_PETITION_SIGNS, GUILD_CHARTER_TYPE, LOG_DEBUG, Petition::ownerGuid, Petition::petitionId, Petition::petitionName, Petition::petitionType, SendPacket(), SMSG_PETITION_QUERY_RESPONSE, sPetitionMgr, sWorld, and ObjectGuid::ToString().

Referenced by HandlePetitionQueryOpcode(), and Player::RemovePetitionsAndSigns().

◆ SendPetitionShowList()

void WorldSession::SendPetitionShowList ( ObjectGuid  guid)
829{
831 if (!creature)
832 {
833 LOG_DEBUG("network", "WORLD: HandlePetitionShowListOpcode - Unit ({}) not found or you can't interact with him.", guid.ToString());
834 return;
835 }
836
837 WorldPacket data(SMSG_PETITION_SHOWLIST, 8 + 1 + 4 * 6);
838 data << guid; // npc guid
839
840 // For guild default
841 uint32 CharterEntry = GUILD_CHARTER;
842 uint32 CharterDispayID = CHARTER_DISPLAY_ID;
843 uint32 CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD);
844
845 if (creature->IsTabardDesigner())
846 {
847 sScriptMgr->OnPlayerPetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
848
849 data << uint8(1); // count
850 data << uint32(1); // index
851 data << CharterEntry; // charter entry
852 data << CharterDispayID; // charter display id
853 data << CharterCost; // charter cost
854 data << uint32(0); // unknown
855 data << uint32(sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS)); // required signs
856 }
857 else
858 {
859 // For 2v2 default
860 CharterEntry = ARENA_TEAM_CHARTER_2v2;
861 CharterDispayID = CHARTER_DISPLAY_ID;
862 CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_2v2);
863
864 // 2v2
865 data << uint8(3); // count
866 sScriptMgr->OnPlayerPetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
867 data << uint32(1); // index
868 data << CharterEntry; // charter entry
869 data << CharterDispayID; // charter display id
870 data << CharterCost; // charter cost
871 data << uint32(2); // unknown
872 data << uint32(2); // required signs?
873
874 // For 3v3 default
875 CharterEntry = ARENA_TEAM_CHARTER_3v3;
876 CharterDispayID = CHARTER_DISPLAY_ID;
877 CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_3v3);
878
879 // 3v3
880 sScriptMgr->OnPlayerPetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
881 data << uint32(2); // index
882 data << CharterEntry; // charter entry
883 data << CharterDispayID; // charter display id
884 data << CharterCost; // charter cost
885 data << uint32(3); // unknown
886 data << uint32(3); // required signs?
887
888 // For 3v3 default
889 CharterEntry = ARENA_TEAM_CHARTER_5v5;
890 CharterDispayID = CHARTER_DISPLAY_ID;
891 CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_5v5);
892
893 // 5v5
894 sScriptMgr->OnPlayerPetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
895 data << uint32(3); // index
896 data << CharterEntry; // charter entry
897 data << CharterDispayID; // charter display id
898 data << CharterCost; // charter cost
899 data << uint32(5); // unknown
900 data << uint32(5); // required signs?
901 }
902
903 SendPacket(&data);
904 LOG_DEBUG("network", "Sent SMSG_PETITION_SHOWLIST");
905}
#define CHARTER_DISPLAY_ID
Definition PetitionMgr.h:26
@ SMSG_PETITION_SHOWLIST
Definition Opcodes.h:474

References _player, ARENA_TEAM_CHARTER_2v2, ARENA_TEAM_CHARTER_3v3, ARENA_TEAM_CHARTER_5v5, CHARTER_DISPLAY_ID, CONFIG_CHARTER_COST_ARENA_2v2, CONFIG_CHARTER_COST_ARENA_3v3, CONFIG_CHARTER_COST_ARENA_5v5, CONFIG_CHARTER_COST_GUILD, CONFIG_MIN_PETITION_SIGNS, Player::GetNPCIfCanInteractWith(), GetPlayer(), GUILD_CHARTER, Unit::IsTabardDesigner(), LOG_DEBUG, SendPacket(), SMSG_PETITION_SHOWLIST, sScriptMgr, sWorld, ObjectGuid::ToString(), and UNIT_NPC_FLAG_PETITIONER.

Referenced by HandlePetitionShowListOpcode(), and Player::OnGossipSelect().

◆ SendPetNameInvalid()

void WorldSession::SendPetNameInvalid ( uint32  error,
std::string const &  name,
DeclinedName declinedName 
)
1103{
1104 WorldPacket data(SMSG_PET_NAME_INVALID, 4 + name.size() + 1 + 1);
1105 data << uint32(error);
1106 data << name;
1107 if (declinedName)
1108 {
1109 data << uint8(1);
1110 for (uint32 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
1111 data << declinedName->name[i];
1112 }
1113 else
1114 data << uint8(0);
1115 SendPacket(&data);
1116}
@ SMSG_PET_NAME_INVALID
Definition Opcodes.h:406

References MAX_DECLINED_NAME_CASES, DeclinedName::name, SendPacket(), and SMSG_PET_NAME_INVALID.

Referenced by HandlePetRename().

◆ SendPetNameQuery()

void WorldSession::SendPetNameQuery ( ObjectGuid  guid,
uint32  petnumber 
)
620{
622 if (!pet)
623 {
624 WorldPacket data(SMSG_PET_NAME_QUERY_RESPONSE, (4 + 1 + 4 + 1));
625 data << uint32(petnumber);
626 data << uint8(0);
627 data << uint32(0);
628 data << uint8(0);
629 SendPacket(&data);
630 return;
631 }
632
633 std::string name;
635 {
636 // Use localized creature name for the mage pet
638 if (loc_idx != DEFAULT_LOCALE)
639 name = pet->GetNameForLocaleIdx(loc_idx);
640 else
641 name = pet->GetCreatureTemplate()->Name;
642 }
643 else
644 name = pet->GetName();
645
646 WorldPacket data(SMSG_PET_NAME_QUERY_RESPONSE, (4 + 4 + name.size() + 1));
647 data << uint32(petnumber);
648 data << name.c_str();
650
651 if (pet->IsPet() && ((Pet*)pet)->GetDeclinedNames())
652 {
653 data << uint8(1);
654 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
655 data << ((Pet*)pet)->GetDeclinedNames()->name[i];
656 }
657 else
658 data << uint8(0);
659
660 SendPacket(&data);
661}
@ NPC_WATER_ELEMENTAL_PERM
Definition PetDefines.h:107
std::string const & GetNameForLocaleIdx(LocaleConstant locale_idx) const override
Definition Creature.cpp:3152
@ SMSG_PET_NAME_QUERY_RESPONSE
Definition Opcodes.h:113

References _player, DEFAULT_LOCALE, ObjectAccessor::GetCreatureOrPetOrVehicle(), Creature::GetCreatureTemplate(), Object::GetEntry(), WorldObject::GetName(), Creature::GetNameForLocaleIdx(), GetSessionDbLocaleIndex(), Object::GetUInt32Value(), Unit::IsPet(), MAX_DECLINED_NAME_CASES, CreatureTemplate::Name, NPC_WATER_ELEMENTAL_PERM, SendPacket(), SMSG_PET_NAME_QUERY_RESPONSE, and UNIT_FIELD_PET_NAME_TIMESTAMP.

Referenced by HandlePetNameQuery().

◆ SendPlayerAmbiguousNotice()

void WorldSession::SendPlayerAmbiguousNotice ( std::string const &  name)
781{
782 WorldPacket data(SMSG_CHAT_PLAYER_AMBIGUOUS, name.size() + 1);
783 data << name;
784 SendPacket(&data);
785}
@ SMSG_CHAT_PLAYER_AMBIGUOUS
Definition Opcodes.h:843

References SendPacket(), and SMSG_CHAT_PLAYER_AMBIGUOUS.

◆ SendPlayerNotFoundNotice()

void WorldSession::SendPlayerNotFoundNotice ( std::string const &  name)
774{
775 WorldPacket data(SMSG_CHAT_PLAYER_NOT_FOUND, name.size() + 1);
776 data << name;
777 SendPacket(&data);
778}
@ SMSG_CHAT_PLAYER_NOT_FOUND
Definition Opcodes.h:711

References SendPacket(), and SMSG_CHAT_PLAYER_NOT_FOUND.

Referenced by HandleMessagechatOpcode().

◆ SendSetPhaseShift()

void WorldSession::SendSetPhaseShift ( uint32  phaseShift)
1620{
1622 data << uint32(PhaseShift);
1623 SendPacket(&data);
1624}
@ SMSG_SET_PHASE_SHIFT
Definition Opcodes.h:1178

References SendPacket(), and SMSG_SET_PHASE_SHIFT.

Referenced by debug_commandscript::HandleDebugSendSetPhaseShiftCommand().

◆ SendSetPlayerDeclinedNamesResult()

void WorldSession::SendSetPlayerDeclinedNamesResult ( DeclinedNameResult  result,
ObjectGuid  guid 
)
2648{
2650 data << uint32(result);
2651 data << guid;
2652 SendPacket(&data);
2653}
@ SMSG_SET_PLAYER_DECLINED_NAMES_RESULT
Definition Opcodes.h:1080

References SendPacket(), and SMSG_SET_PLAYER_DECLINED_NAMES_RESULT.

Referenced by HandleSetPlayerDeclinedNames().

◆ SendShowBank()

void WorldSession::SendShowBank ( ObjectGuid  guid)

◆ SendShowMailBox()

void WorldSession::SendShowMailBox ( ObjectGuid  guid)
73{
75 data << guid;
76 SendPacket(&data);
77}
@ SMSG_SHOW_MAILBOX
Definition Opcodes.h:693

References SendPacket(), and SMSG_SHOW_MAILBOX.

Referenced by misc_commandscript::HandleMailBoxCommand(), and npc_pet_gen_argent_pony_bridle::OnGossipSelect().

◆ SendSpiritResurrect()

void WorldSession::SendSpiritResurrect ( )
388{
389 _player->ResurrectPlayer(0.5f, true);
390
391 _player->DurabilityLossAll(0.25f, true);
392
393 // get corpse nearest graveyard
394 GraveyardStruct const* corpseGrave = nullptr;
395
396 // Search for any graveyards near the player's corpse.
397 corpseGrave = sGraveyard->GetClosestGraveyard(_player, _player->GetTeamId(), _player->HasCorpse());
398
399 // now can spawn bones
401
402 // teleport to nearest from corpse graveyard, if different from nearest to player ghost
403 if (corpseGrave)
404 {
405 GraveyardStruct const* ghostGrave = sGraveyard->GetClosestGraveyard(_player, _player->GetTeamId());
406
407 if (corpseGrave != ghostGrave)
408 _player->TeleportTo(corpseGrave->Map, corpseGrave->x, corpseGrave->y, corpseGrave->z, _player->GetOrientation());
409 // or update at original position
410 //else
411 // _player->UpdateObjectVisibility(); // xinef: not needed, called in ResurrectPlayer
412 }
413 // or update at original position
414 //else
415 // _player->UpdateObjectVisibility(); // xinef: not needed, called in ResurrectPlayer
416}
void DurabilityLossAll(double percent, bool inventory)
Definition Player.cpp:4707

References _player, Player::DurabilityLossAll(), Position::GetOrientation(), Player::GetTeamId(), Player::HasCorpse(), GraveyardStruct::Map, Player::ResurrectPlayer(), sGraveyard, Player::SpawnCorpseBones(), Player::TeleportTo(), GraveyardStruct::x, GraveyardStruct::y, and GraveyardStruct::z.

Referenced by HandleSpiritHealerActivateOpcode().

◆ SendStablePet()

void WorldSession::SendStablePet ( ObjectGuid  guid)
481{
482 LOG_DEBUG("network", "WORLD: Recv MSG_LIST_STABLED_PETS Send.");
483
484 WorldPacket data(MSG_LIST_STABLED_PETS, 200); // guess size
485 data << guid;
486 std::size_t wpos = data.wpos();
487 data << uint8(0); // place holder for slot show number
488
489 PetStable* petStable = GetPlayer()->GetPetStable();
490 if (!petStable)
491 {
492 data << uint8(0); // stable slots
493 SendPacket(&data);
494 return;
495 }
496
497 data << uint8(petStable->MaxStabledPets);
498
499 uint8 num = 0; // counter for place holder
500
501 // not let move dead pet in slot
502 if (petStable->CurrentPet)
503 {
504 PetStable::PetInfo const& pet = *petStable->CurrentPet;
505 data << uint32(pet.PetNumber);
506 data << uint32(pet.CreatureId);
507 data << uint32(pet.Level);
508 data << pet.Name; // petname
509 data << uint8(1); // flags: 1 active, 2 inactive
510 ++num;
511 }
512 else
513 {
514 if (PetStable::PetInfo const* pet = petStable->GetUnslottedHunterPet())
515 {
516 data << uint32(pet->PetNumber);
517 data << uint32(pet->CreatureId);
518 data << uint32(pet->Level);
519 data << pet->Name; // petname
520 data << uint8(1); // flags: 1 active, 2 inactive
521 ++num;
522 }
523 }
524
525 for (Optional<PetStable::PetInfo> const& stabledSlot : petStable->StabledPets)
526 {
527 if (stabledSlot)
528 {
529 PetStable::PetInfo const& pet = *stabledSlot;
530 data << uint32(pet.PetNumber);
531 data << uint32(pet.CreatureId);
532 data << uint32(pet.Level);
533 data << pet.Name; // petname
534 data << uint8(2); // flags: 1 active, 2 inactive
535 ++num;
536 }
537 }
538
539 data.put<uint8>(wpos, num); // set real data to placeholder
540 SendPacket(&data);
541}
PetInfo const * GetUnslottedHunterPet() const
Definition PetDefines.h:240
@ MSG_LIST_STABLED_PETS
Definition Opcodes.h:653
Definition PetDefines.h:215
uint32 CreatureId
Definition PetDefines.h:221
uint8 Level
Definition PetDefines.h:229
std::string Name
Definition PetDefines.h:218
uint32 PetNumber
Definition PetDefines.h:220

References PetStable::PetInfo::CreatureId, PetStable::CurrentPet, Player::GetPetStable(), GetPlayer(), PetStable::GetUnslottedHunterPet(), PetStable::PetInfo::Level, LOG_DEBUG, PetStable::MaxStabledPets, MSG_LIST_STABLED_PETS, PetStable::PetInfo::Name, PetStable::PetInfo::PetNumber, ByteBuffer::put(), SendPacket(), PetStable::StabledPets, and ByteBuffer::wpos().

Referenced by AuraEffect::HandleAuraOpenStable(), HandleListStabledPetsOpcode(), and Player::OnGossipSelect().

◆ SendStablePetCallback()

void WorldSession::SendStablePetCallback ( ObjectGuid  guid,
PreparedQueryResult  result 
)

◆ SendStableResult()

void WorldSession::SendStableResult ( uint8  guid)
544{
546 data << uint8(res);
547 SendPacket(&data);
548}
@ SMSG_STABLE_RESULT
Definition Opcodes.h:657

References SendPacket(), and SMSG_STABLE_RESULT.

Referenced by HandleBuyStableSlot(), HandleStablePet(), HandleStableSwapPet(), and HandleUnstablePet().

◆ SendTabardVendorActivate()

void WorldSession::SendTabardVendorActivate ( ObjectGuid  guid)
66{
68 data << guid;
69 SendPacket(&data);
70}
@ MSG_TABARDVENDOR_ACTIVATE
Definition Opcodes.h:528

References MSG_TABARDVENDOR_ACTIVATE, and SendPacket().

Referenced by HandleTabardVendorActivateOpcode(), and Player::OnGossipSelect().

◆ SendTaxiMenu()

void WorldSession::SendTaxiMenu ( Creature unit)
85{
86 // find current node
87 uint32 curloc = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), GetPlayer()->GetTeamId());
88
89 if (curloc == 0)
90 return;
91
92 bool lastTaxiCheaterState = GetPlayer()->isTaxiCheater();
93 if (unit->GetEntry() == 29480) GetPlayer()->SetTaxiCheater(true); // Grimwing in Ebon Hold, special case. NOTE: Not perfect, Zul'Aman should not be included according to WoWhead, and I think taxicheat includes it.
94
95 LOG_DEBUG("network", "WORLD: CMSG_TAXINODE_STATUS_QUERY {} ", curloc);
96
97 WorldPacket data(SMSG_SHOWTAXINODES, (4 + 8 + 4 + 8 * 4));
98 data << uint32(1);
99 data << unit->GetGUID();
100 data << uint32(curloc);
101 GetPlayer()->m_taxi.AppendTaximaskTo(data, GetPlayer()->isTaxiCheater());
102 SendPacket(&data);
103
104 LOG_DEBUG("network", "WORLD: Sent SMSG_SHOWTAXINODES");
105
106 GetPlayer()->SetTaxiCheater(lastTaxiCheaterState);
107}
void AppendTaximaskTo(ByteBuffer &data, bool all)
Definition PlayerTaxi.cpp:116
bool isTaxiCheater() const
Definition Player.h:1168
@ SMSG_SHOWTAXINODES
Definition Opcodes.h:455

References PlayerTaxi::AppendTaximaskTo(), Object::GetEntry(), Object::GetGUID(), WorldLocation::GetMapId(), GetPlayer(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), GetTeamId(), Player::isTaxiCheater(), LOG_DEBUG, Player::m_taxi, SendPacket(), Player::SetTaxiCheater(), SMSG_SHOWTAXINODES, and sObjectMgr.

Referenced by HandleTaxiQueryAvailableNodes(), and Player::OnGossipSelect().

◆ SendTaxiStatus()

void WorldSession::SendTaxiStatus ( ObjectGuid  guid)
36{
37 Player* const player = GetPlayer();
38 Creature* unit = ObjectAccessor::GetCreature(*player, guid);
39 if (!unit || unit->IsHostileTo(player) || !unit->HasNpcFlag(UNIT_NPC_FLAG_FLIGHTMASTER))
40 {
41 LOG_DEBUG("network", "WorldSession::SendTaxiStatus - Unit ({}) not found.", guid.ToString());
42 return;
43 }
44
45 // find taxi node
46 uint32 nearest = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), player->GetTeamId());
47 if (!nearest)
48 {
49 return;
50 }
51
53 data << guid;
54 data << uint8(player->m_taxi.IsTaximaskNodeKnown(nearest) ? 1 : 0);
55 SendPacket(&data);
56 LOG_DEBUG("network", "WORLD: Sent SMSG_TAXINODE_STATUS");
57}
bool IsTaximaskNodeKnown(uint32 nodeidx) const
Definition PlayerTaxi.h:35
bool HasNpcFlag(NPCFlags flags) const
Definition Unit.h:753

References ObjectAccessor::GetCreature(), WorldLocation::GetMapId(), GetPlayer(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetTeamId(), Unit::HasNpcFlag(), Unit::IsHostileTo(), PlayerTaxi::IsTaximaskNodeKnown(), LOG_DEBUG, Player::m_taxi, SendPacket(), SMSG_TAXINODE_STATUS, sObjectMgr, ObjectGuid::ToString(), and UNIT_NPC_FLAG_FLIGHTMASTER.

Referenced by HandleTaxiNodeStatusQueryOpcode().

◆ SendTimeQueryResponse()

void WorldSession::SendTimeQueryResponse ( )
78{
79 auto timeResponse = sWorld->GetNextDailyQuestsResetTime() - GameTime::GetGameTime();
80
82 timeQueryResponse.ServerTime = GameTime::GetGameTime().count();
83 timeQueryResponse.TimeResponse = timeResponse.count();
84 SendPacket(timeQueryResponse.Write());
85}
Definition QueryPackets.h:65
uint32 TimeResponse
Definition QueryPackets.h:72
WorldPacket const * Write() override
Definition QueryPackets.cpp:47
uint32 ServerTime
Definition QueryPackets.h:71

References GameTime::GetGameTime(), SendPacket(), WorldPackets::Query::TimeQueryResponse::ServerTime, sWorld, WorldPackets::Query::TimeQueryResponse::TimeResponse, and WorldPackets::Query::TimeQueryResponse::Write().

Referenced by HandleGMTicketGetTicketOpcode(), and HandleTimeQueryOpcode().

◆ SendTimeSync()

void WorldSession::SendTimeSync ( )
1433{
1436 SendPacket(&data);
1437
1439
1440 // Schedule next sync in 10 sec (except for the 2 first packets, which are spaced by only 5s)
1441 _timeSyncTimer = _timeSyncNextCounter == 0 ? 5000 : 10000;
1443}
uint32 getMSTime()
Definition Timer.h:103
@ SMSG_TIME_SYNC_REQ
Definition Opcodes.h:942

References _pendingTimeSyncRequests, _timeSyncNextCounter, _timeSyncTimer, getMSTime(), SendPacket(), and SMSG_TIME_SYNC_REQ.

Referenced by Player::SendInitialPacketsAfterAddToMap(), and Update().

◆ SendTradeStatus()

void WorldSession::SendTradeStatus ( TradeStatus  status)
34{
35 WorldPacket data;
36
37 switch (status)
38 {
40 data.Initialize(SMSG_TRADE_STATUS, 4 + 8);
41 data << uint32(status);
42 data << uint64(0);
43 break;
45 data.Initialize(SMSG_TRADE_STATUS, 4 + 4);
46 data << uint32(status);
47 data << uint32(0); // added in 2.4.0
48 break;
50 data.Initialize(SMSG_TRADE_STATUS, 4 + 4 + 1 + 4);
51 data << uint32(status);
52 data << uint32(0);
53 data << uint8(0);
54 data << uint32(0);
55 break;
58 data.Initialize(SMSG_TRADE_STATUS, 4 + 1);
59 data << uint32(status);
60 data << uint8(0);
61 break;
62 default:
64 data << uint32(status);
65 break;
66 }
67
68 SendPacket(&data);
69}
@ TRADE_STATUS_ONLY_CONJURED
Definition SharedDefines.h:3838

References WorldPacket::Initialize(), SendPacket(), SMSG_TRADE_STATUS, TRADE_STATUS_BEGIN_TRADE, TRADE_STATUS_CLOSE_WINDOW, TRADE_STATUS_NOT_ELIGIBLE, TRADE_STATUS_ONLY_CONJURED, and TRADE_STATUS_OPEN_WINDOW.

Referenced by HandleAcceptTradeOpcode(), HandleBeginTradeOpcode(), HandleInitiateTradeOpcode(), HandleSetTradeItemOpcode(), SendCancelTrade(), TradeData::SetAccepted(), and TradeData::SetMoney().

◆ SendTrainerList() [1/2]

◆ SendTrainerList() [2/2]

void WorldSession::SendTrainerList ( ObjectGuid  guid,
std::string const &  strTitle 
)
94{
95 LOG_DEBUG("network", "WORLD: SendTrainerList");
96
98 if (!unit)
99 {
100 LOG_DEBUG("network", "WORLD: SendTrainerList - Unit ({}) not found or you can not interact with him.", guid.ToString());
101 return;
102 }
103
104 // remove fake death
105 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
107
108 CreatureTemplate const* ci = unit->GetCreatureTemplate();
109
110 if (!ci)
111 {
112 LOG_DEBUG("network", "WORLD: SendTrainerList - ({}) NO CREATUREINFO!", guid.ToString());
113 return;
114 }
115
116 TrainerSpellData const* trainer_spells = unit->GetTrainerSpells();
117 if (!trainer_spells)
118 {
119 LOG_DEBUG("network", "WORLD: SendTrainerList - Training spells not found for creature ({})", guid.ToString());
120 return;
121 }
122
123 WorldPacket data(SMSG_TRAINER_LIST, 8 + 4 + 4 + trainer_spells->spellList.size() * 38 + strTitle.size() + 1);
124 data << guid;
125 data << uint32(trainer_spells->trainerType);
126
127 std::size_t count_pos = data.wpos();
128 data << uint32(trainer_spells->spellList.size());
129
130 // reputation discount
131 float fDiscountMod = _player->GetReputationPriceDiscount(unit);
132 bool can_learn_primary_prof = GetPlayer()->GetFreePrimaryProfessionPoints() > 0;
133
134 uint32 count = 0;
135 for (TrainerSpellMap::const_iterator itr = trainer_spells->spellList.begin(); itr != trainer_spells->spellList.end(); ++itr)
136 {
137 TrainerSpell const* tSpell = &itr->second;
138
139 bool valid = true;
140 bool primary_prof_first_rank = false;
141 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
142 {
143 if (!tSpell->learnedSpell[i])
144 continue;
146 {
147 valid = false;
148 break;
149 }
150 SpellInfo const* learnedSpellInfo = sSpellMgr->GetSpellInfo(tSpell->learnedSpell[i]);
151 if (learnedSpellInfo && learnedSpellInfo->IsPrimaryProfessionFirstRank())
152 primary_prof_first_rank = true;
153 }
154
155 if (!valid)
156 continue;
157
158 if (tSpell->reqSpell && !_player->HasSpell(tSpell->reqSpell))
159 {
160 continue;
161 }
162
164
165 data << uint32(tSpell->spell); // learned spell (or cast-spell in profession case)
166 data << uint8(state == TRAINER_SPELL_GREEN_DISABLED ? TRAINER_SPELL_GREEN : state);
167 data << uint32(std::floor(tSpell->spellCost * fDiscountMod));
168
169 data << uint32(primary_prof_first_rank && can_learn_primary_prof ? 1 : 0);
170 // primary prof. learn confirmation dialog
171 data << uint32(primary_prof_first_rank ? 1 : 0); // must be equal prev. field to have learn button in enabled state
172 data << uint8(tSpell->reqLevel);
173 data << uint32(tSpell->reqSkill);
174 data << uint32(tSpell->reqSkillValue);
175 //prev + req or req + 0
176 uint8 maxReq = 0;
177 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
178 {
179 if (!tSpell->learnedSpell[i])
180 continue;
181 if (uint32 prevSpellId = sSpellMgr->GetPrevSpellInChain(tSpell->learnedSpell[i]))
182 {
183 data << uint32(prevSpellId);
184 ++maxReq;
185 }
186 if (maxReq == 3)
187 break;
188 SpellsRequiringSpellMapBounds spellsRequired = sSpellMgr->GetSpellsRequiredForSpellBounds(tSpell->learnedSpell[i]);
189 for (SpellsRequiringSpellMap::const_iterator itr2 = spellsRequired.first; itr2 != spellsRequired.second && maxReq < 3; ++itr2)
190 {
191 data << uint32(itr2->second);
192 ++maxReq;
193 }
194 if (maxReq == 3)
195 break;
196 }
197 while (maxReq < 3)
198 {
199 data << uint32(0);
200 ++maxReq;
201 }
202
203 ++count;
204 }
205
206 data << strTitle;
207
208 data.put<uint32>(count_pos, count);
209 SendPacket(&data);
210}
TrainerSpellState
Definition Player.h:214
@ TRAINER_SPELL_GREEN_DISABLED
Definition Player.h:218
std::pair< SpellsRequiringSpellMap::const_iterator, SpellsRequiringSpellMap::const_iterator > SpellsRequiringSpellMapBounds
Definition SpellMgr.h:562
bool IsSpellFitByClassAndRace(uint32 spell_id) const
Definition Player.cpp:12399
uint32 GetFreePrimaryProfessionPoints() const
Definition Player.h:1764
bool IsPrimaryProfessionFirstRank() const
Definition SpellInfo.cpp:983
@ SMSG_TRAINER_LIST
Definition Opcodes.h:463
TrainerSpellMap spellList
Definition CreatureData.h:533
uint32 trainerType
Definition CreatureData.h:534
uint32 reqSkillValue
Definition CreatureData.h:517
uint32 learnedSpell[3]
Definition CreatureData.h:519
uint32 reqSkill
Definition CreatureData.h:516
uint32 reqLevel
Definition CreatureData.h:518

References _player, Creature::GetCreatureTemplate(), Player::GetFreePrimaryProfessionPoints(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Player::GetReputationPriceDiscount(), Creature::GetTrainerSpells(), Player::GetTrainerSpellState(), Player::HasSpell(), SpellInfo::IsPrimaryProfessionFirstRank(), Player::IsSpellFitByClassAndRace(), TrainerSpell::learnedSpell, LOG_DEBUG, MAX_SPELL_EFFECTS, ByteBuffer::put(), Unit::RemoveAurasByType(), TrainerSpell::reqLevel, TrainerSpell::reqSkill, TrainerSpell::reqSkillValue, TrainerSpell::reqSpell, SendPacket(), SMSG_TRAINER_LIST, TrainerSpell::spell, SPELL_AURA_FEIGN_DEATH, TrainerSpell::spellCost, TrainerSpellData::spellList, sSpellMgr, ObjectGuid::ToString(), TRAINER_SPELL_GREEN, TRAINER_SPELL_GREEN_DISABLED, TrainerSpellData::trainerType, UNIT_NPC_FLAG_TRAINER, UNIT_STATE_DIED, and ByteBuffer::wpos().

◆ SendTutorialsData()

void WorldSession::SendTutorialsData ( )
973{
975 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
976 data << m_Tutorials[i];
977 SendPacket(&data);
978}
@ SMSG_TUTORIAL_FLAGS
Definition Opcodes.h:283

References m_Tutorials, MAX_ACCOUNT_TUTORIAL_VALUES, SendPacket(), and SMSG_TUTORIAL_FLAGS.

Referenced by InitializeSessionCallback().

◆ SendUpdateTrade()

void WorldSession::SendUpdateTrade ( bool  trader_data = true)
82{
83 TradeData* view_trade = trader_data ? _player->GetTradeData()->GetTraderData() : _player->GetTradeData();
84
85 WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, 1 + 4 + 4 + 4 + 4 + 4 + 7 * (1 + 4 + 4 + 4 + 4 + 8 + 4 + 4 + 4 + 4 + 8 + 4 + 4 + 4 + 4 + 4 + 4));
86 data << uint8(trader_data); // 1 means traders data, 0 means own
87 data << uint32(0); // added in 2.4.0, this value must be equal to value from TRADE_STATUS_OPEN_WINDOW status packet (different value for different players to block multiple trades?)
88 data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = next field in most cases
89 data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = prev field in most cases
90 data << uint32(view_trade->GetMoney()); // trader gold
91 data << uint32(view_trade->GetSpell()); // spell casted on lowest slot item
92
93 for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
94 {
95 data << uint8(i); // trade slot number, if not specified, then end of packet
96
97 if (Item* item = view_trade->GetItem(TradeSlots(i)))
98 {
99 data << uint32(item->GetTemplate()->ItemId); // entry
100 data << uint32(item->GetTemplate()->DisplayInfoID);// display id
101 data << uint32(item->GetCount()); // stack count
102 // wrapped: hide stats but show giftcreator name
103 data << uint32(item->IsWrapped() ? 1 : 0);
104 data << item->GetGuidValue(ITEM_FIELD_GIFTCREATOR);
105 // perm. enchantment and gems
106 data << uint32(item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT));
107 for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS; ++enchant_slot)
108 data << uint32(item->GetEnchantmentId(EnchantmentSlot(enchant_slot)));
109 // creator
110 data << item->GetGuidValue(ITEM_FIELD_CREATOR);
111 data << uint32(item->GetSpellCharges()); // charges
112 data << uint32(item->GetItemSuffixFactor()); // SuffixFactor
113 data << int32(item->GetItemRandomPropertyId()); // random properties id
114 data << uint32(item->GetTemplate()->LockID); // lock id
115 // max durability
116 data << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY));
117 // durability
118 data << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY));
119 }
120 else
121 {
122 for (uint8 j = 0; j < 18; ++j)
123 data << uint32(0);
124 }
125 }
126 SendPacket(&data);
127}
@ PERM_ENCHANTMENT_SLOT
Definition Item.h:169
TradeData * GetTraderData() const
Definition TradeData.cpp:21
@ SMSG_TRADE_STATUS_EXTENDED
Definition Opcodes.h:319

References _player, TradeData::GetItem(), TradeData::GetMoney(), TradeData::GetSpell(), Player::GetTradeData(), TradeData::GetTraderData(), ITEM_FIELD_CREATOR, ITEM_FIELD_DURABILITY, ITEM_FIELD_GIFTCREATOR, ITEM_FIELD_MAXDURABILITY, MAX_GEM_SOCKETS, PERM_ENCHANTMENT_SLOT, SendPacket(), SMSG_TRADE_STATUS_EXTENDED, SOCK_ENCHANTMENT_SLOT, and TRADE_SLOT_COUNT.

Referenced by TradeData::Update().

◆ SendWrongFactionNotice()

void WorldSession::SendWrongFactionNotice ( )
788{
790 SendPacket(&data);
791}
@ SMSG_CHAT_WRONG_FACTION
Definition Opcodes.h:567

References SendPacket(), and SMSG_CHAT_WRONG_FACTION.

Referenced by HandleMessagechatOpcode().

◆ SetAccountData()

void WorldSession::SetAccountData ( AccountDataType  type,
time_t  tm,
std::string const &  data 
)
916{
917 uint32 id = 0;
919 if ((1 << type) & GLOBAL_CACHE_MASK)
920 {
921 id = GetAccountId();
922 index = CHAR_REP_ACCOUNT_DATA;
923 }
924 else
925 {
926 // _player can be nullptr and packet received after logout but m_GUID still store correct guid
927 if (!m_GUIDLow)
928 return;
929
930 id = m_GUIDLow;
932 }
933
934 CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(index);
935 stmt->SetData(0, id);
936 stmt->SetData(1, type);
937 stmt->SetData(2, uint32(tm));
938 stmt->SetData(3, data);
939 CharacterDatabase.Execute(stmt);
940
941 m_accountData[type].Time = tm;
942 m_accountData[type].Data = data;
943}
CharacterDatabaseStatements
Definition CharacterDatabase.h:24
@ CHAR_REP_PLAYER_ACCOUNT_DATA
Definition CharacterDatabase.h:202
@ CHAR_REP_ACCOUNT_DATA
Definition CharacterDatabase.h:199

References CHAR_REP_ACCOUNT_DATA, CHAR_REP_PLAYER_ACCOUNT_DATA, CharacterDatabase, AccountData::Data, GetAccountId(), GLOBAL_CACHE_MASK, m_accountData, m_GUIDLow, PreparedStatementBase::SetData(), and AccountData::Time.

Referenced by HandleUpdateAccountData().

◆ SetCalendarEventCreationCooldown()

void WorldSession::SetCalendarEventCreationCooldown ( time_t  cooldown)
inline

◆ SetCurrentVendor()

void WorldSession::SetCurrentVendor ( uint32  vendorEntry)
inline
429{ m_currentVendorEntry = vendorEntry; }

References m_currentVendorEntry.

Referenced by SendListInventory().

◆ SetInQueue()

void WorldSession::SetInQueue ( bool  state)
inline

Session in auth.queue currently.

444{ m_inQueue = state; }

References m_inQueue.

Referenced by WorldSessionMgr::AddQueuedPlayer(), InitializeSessionCallback(), and WorldSessionMgr::RemoveQueuedPlayer().

◆ SetKicked()

void WorldSession::SetKicked ( bool  val)
inline
1127{ _kicked = val; }

References _kicked.

Referenced by KickPlayer().

◆ SetLatency()

void WorldSession::SetLatency ( uint32  latency)
inline
565{ m_latency = latency; }

References m_latency.

Referenced by WorldSocket::HandlePing().

◆ SetLogoutStartTime()

void WorldSession::SetLogoutStartTime ( time_t  requestTime)
inline

Engage the logout process for the user.

451 {
452 _logoutTime = requestTime;
453 }

References _logoutTime.

Referenced by HandleLogoutCancelOpcode(), HandleLogoutRequestOpcode(), and LogoutPlayer().

◆ SetOfflineTime()

void WorldSession::SetOfflineTime ( uint32  time)
inline

◆ SetPacketLogging()

void WorldSession::SetPacketLogging ( bool  state)
1515{
1516 if (m_Socket)
1517 m_Socket->SetPacketLogging(state);
1518}

References m_Socket.

Referenced by misc_commandscript::HandlePacketLog().

◆ SetPlayer()

void WorldSession::SetPlayer ( Player player)
1309{
1310 _player = player;
1311
1312 // set m_GUID that can be used while player loggined and later until m_playerRecentlyLogout not reset
1313 if (_player)
1315}

References _player, ObjectGuid::GetCounter(), Object::GetGUID(), and m_GUIDLow.

Referenced by HandlePlayerLoginFromDB(), HandlePlayerLoginOpcode(), Player::LoadFromDB(), and LogoutPlayer().

◆ SetSecurity()

void WorldSession::SetSecurity ( AccountTypes  security)
inline
432{ _security = security; }

References _security.

◆ SetTotalTime()

void WorldSession::SetTotalTime ( uint32  TotalTime)
inline
437{ m_total_time = TotalTime; }

References m_total_time.

Referenced by Player::Update().

◆ SetTutorialInt()

void WorldSession::SetTutorialInt ( uint8  index,
uint32  value 
)
inline
522 {
523 if (m_Tutorials[index] != value)
524 {
525 m_Tutorials[index] = value;
526 m_TutorialsChanged = true;
527 }
528 }

References m_Tutorials, and m_TutorialsChanged.

Referenced by HandleTutorialClear(), HandleTutorialFlag(), and HandleTutorialReset().

◆ ShouldLogOut()

bool WorldSession::ShouldLogOut ( time_t  currTime) const
inline

Is logout cooldown expired?

457 {
458 return (_logoutTime > 0 && currTime >= _logoutTime + 20);
459 }

References _logoutTime.

Referenced by Update().

◆ SynchronizeMovement()

void WorldSession::SynchronizeMovement ( MovementInfo movementInfo)
398{
399 int64 movementTime = (int64)movementInfo.time + _timeSyncClockDelta;
400 if (_timeSyncClockDelta == 0 || movementTime < 0 || movementTime > 0xFFFFFFFF)
401 {
402 LOG_INFO("misc", "The computed movement time using clockDelta is erronous. Using fallback instead");
403 movementInfo.time = getMSTime();
404 }
405 else
406 {
407 movementInfo.time = (uint32)movementTime;
408 }
409}

References _timeSyncClockDelta, getMSTime(), LOG_INFO, and MovementInfo::time.

Referenced by HandleMoverRelocation().

◆ Update()

bool WorldSession::Update ( uint32  diff,
PacketFilter updater 
)

Update the WorldSession (triggered by World update)

  • Before we process anything: If necessary, kick the player because the client didn't send anything for too long (or they've been idling in character select)
  • Retrieve packets from the receive queue and call the appropriate handlers not process packets if socket already closed

Delete packet after processing by default

If player didn't log out a while ago, it means packets are being sent while the server does not recognize the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later.

328{
333 m_Socket->CloseSocket();
334
335 if (updater.ProcessUnsafe())
336 UpdateTimeOutTime(diff);
337
339
342 WorldPacket* packet = nullptr;
343
345 bool deletePacket = true;
346 std::vector<WorldPacket*> requeuePackets;
347 uint32 processedPackets = 0;
348 time_t currentTime = GameTime::GetGameTime().count();
349
350 constexpr uint32 MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE = 150;
351
352 while (m_Socket && _recvQueue.next(packet, updater))
353 {
354 OpcodeClient opcode = static_cast<OpcodeClient>(packet->GetOpcode());
355 ClientOpcodeHandler const* opHandle = opcodeTable[opcode];
356
357 METRIC_DETAILED_TIMER("worldsession_update_opcode_time", METRIC_TAG("opcode", opHandle->Name));
358 LOG_DEBUG("network", "message id {} ({}) under READ", opcode, opHandle->Name);
359
360 WorldSession::DosProtection::Policy const evaluationPolicy = AntiDOS.EvaluateOpcode(*packet, currentTime);
361 switch (evaluationPolicy)
362 {
365 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE;
366 break;
368 requeuePackets.push_back(packet);
369 deletePacket = false;
370 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE;
371 break;
372 default:
373 break;
374 }
375
377 || evaluationPolicy == WorldSession::DosProtection::Policy::Log)
378 {
379 try
380 {
381 switch (opHandle->Status)
382 {
383 case STATUS_LOGGEDIN:
384 if (!_player)
385 {
386 // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
390 {
391 //requeuePackets.push_back(packet);
392 //deletePacket = false;
393
394 LOG_DEBUG("network", "Delaying processing of message with status STATUS_LOGGEDIN: No players in the world for account id {}", GetAccountId());
395 }
396 }
397 else if (_player->IsInWorld())
398 {
399 if (!sScriptMgr->CanPacketReceive(this, *packet))
400 break;
401
402 opHandle->Call(this, *packet);
403 LogUnprocessedTail(packet);
404 }
405
406 // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
407 break;
409 if (!_player && !m_playerRecentlyLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout
410 {
411 LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT",
412 "the player has not logged in yet and not recently logout");
413 }
414 else
415 {
416 // not expected _player or must checked in packet hanlder
417 if (!sScriptMgr->CanPacketReceive(this, *packet))
418 break;
419
420 opHandle->Call(this, *packet);
421 LogUnprocessedTail(packet);
422 }
423 break;
424 case STATUS_TRANSFER:
425 if (_player && !_player->IsInWorld())
426 {
427 if (!sScriptMgr->CanPacketReceive(this, *packet))
428 break;
429
430 opHandle->Call(this, *packet);
431 LogUnprocessedTail(packet);
432 }
433 break;
434 case STATUS_AUTHED:
435 if (m_inQueue) // prevent cheating
436 break;
437
438 // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes
439 // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process.
440 if (packet->GetOpcode() == CMSG_CHAR_ENUM)
442
443 if (!sScriptMgr->CanPacketReceive(this, *packet))
444 break;
445
446 opHandle->Call(this, *packet);
447 LogUnprocessedTail(packet);
448 break;
449 case STATUS_NEVER:
450 LOG_ERROR("network.opcode", "Received not allowed opcode {} from {}",
451 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
452 break;
453 case STATUS_UNHANDLED:
454 LOG_DEBUG("network.opcode", "Received not handled opcode {} from {}",
455 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
456 break;
457 }
458 }
460 {
461 LOG_ERROR("network", "{} sent {} with an invalid link:\n{}", GetPlayerInfo(),
462 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), ihe.GetInvalidValue());
463
465 {
466 KickPlayer("WorldSession::Update Invalid chat link");
467 }
468 }
470 {
471 LOG_ERROR("network", "{} sent {} which illegally contained a hyperlink:\n{}", GetPlayerInfo(),
472 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), ihe.GetInvalidValue());
473
475 {
476 KickPlayer("WorldSession::Update Illegal chat link");
477 }
478 }
480 {
481 LOG_ERROR("network", "PacketArrayMaxCapacityException: {} while parsing {} from {}.",
482 pamce.what(), GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
483 }
484 catch (ByteBufferException const&)
485 {
486 LOG_ERROR("network", "WorldSession::Update ByteBufferException occured while parsing a packet (opcode: {}) from client {}, accountid={}. Skipped packet.", packet->GetOpcode(), GetRemoteAddress(), GetAccountId());
487 if (sLog->ShouldLog("network", LogLevel::LOG_LEVEL_DEBUG))
488 {
489 LOG_DEBUG("network", "Dumping error causing packet:");
490 packet->hexlike();
491 }
492 }
493 }
494
495 if (deletePacket)
496 delete packet;
497
498 deletePacket = true;
499
500 processedPackets++;
501
502 //process only a max amout of packets in 1 Update() call.
503 //Any leftover will be processed in next update
504 if (processedPackets > MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE)
505 break;
506 }
507
508 _recvQueue.readd(requeuePackets.begin(), requeuePackets.end());
509
510 METRIC_VALUE("processed_packets", processedPackets);
511 METRIC_VALUE("addon_messages", _addonMessageReceiveCount.load());
513
514 if (!updater.ProcessUnsafe()) // <=> updater is of type MapSessionFilter
515 {
516 // Send time sync packet every 10s.
517 if (_timeSyncTimer > 0)
518 {
519 if (diff >= _timeSyncTimer)
520 {
521 SendTimeSync();
522 }
523 else
524 {
525 _timeSyncTimer -= diff;
526 }
527 }
528 }
529
531
532 //check if we are safe to proceed with logout
533 //logout procedure should happen only in World::UpdateSessions() method!!!
534 if (updater.ProcessUnsafe())
535 {
536 if (m_Socket && m_Socket->IsOpen() && _warden)
537 {
538 _warden->Update(diff);
539 }
540
541 if (ShouldLogOut(currentTime) && !m_playerLoading)
542 {
543 LogoutPlayer(true);
544 }
545
546 if (m_Socket && !m_Socket->IsOpen())
547 {
548 if (GetPlayer() && _warden)
549 _warden->Update(diff);
550
551 m_Socket = nullptr;
552 }
553
554 if (!m_Socket)
555 {
556 return false; //Will remove this session from the world session map
557 }
558 }
559
560 return true;
561}
@ STATUS_AUTHED
Definition AuthSession.h:42
@ LOG_LEVEL_DEBUG
Definition LogCommon.h:31
#define METRIC_DETAILED_TIMER(category,...)
Definition Metric.h:223
#define METRIC_VALUE(category, value,...)
Definition Metric.h:197
#define METRIC_TAG(name, value)
Definition Metric.h:163
@ CONFIG_CLOSE_IDLE_CONNECTIONS
Definition WorldConfig.h:116
Definition Opcodes.h:1385
void readd(Iterator begin, Iterator end)
Adds a range of items to the front of the queue.
Definition LockedQueue.h:65
virtual bool ProcessUnsafe() const
Definition WorldSession.h:276
Definition PacketUtilities.h:52
Definition PacketUtilities.h:46
std::string const & GetInvalidValue() const
Definition PacketUtilities.h:33
Definition PacketUtilities.h:110
Policy EvaluateOpcode(WorldPacket const &p, time_t const time) const
Definition WorldSession.cpp:1354
Policy
Definition WorldSession.h:1157
void SendTimeSync()
Definition WorldSession.cpp:1432
void UpdateTimeOutTime(uint32 diff)
Definition WorldSession.h:568
void LogUnexpectedOpcode(WorldPacket *packet, char const *status, const char *reason)
Logging helper for unexpected opcodes.
Definition WorldSession.cpp:308
void LogUnprocessedTail(WorldPacket *packet)
Logging helper for unexpected opcodes.
Definition WorldSession.cpp:315
void ProcessQueryCallbacks()
Definition WorldSession.cpp:1317
void HandleTeleportTimeout(bool updateInSessions)
Definition WorldSession.cpp:580
bool ShouldLogOut(time_t currTime) const
Is logout cooldown expired?
Definition WorldSession.h:456
bool IsConnectionIdle() const
Definition WorldSession.h:582
char const * Name
Definition Opcodes.h:1380
OpcodeTable opcodeTable
Definition Opcodes.cpp:51
SessionStatus Status
Definition Opcodes.h:1381
virtual void Call(WorldSession *session, WorldPacket &packet) const =0
@ CMSG_CHAR_ENUM
Definition Opcodes.h:85
@ STATUS_LOGGEDIN
Definition Opcodes.h:1357
@ STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT
Definition Opcodes.h:1359
@ STATUS_TRANSFER
Definition Opcodes.h:1358
@ STATUS_NEVER
Definition Opcodes.h:1360
@ STATUS_UNHANDLED
Definition Opcodes.h:1361

References _addonMessageReceiveCount, _player, _recvQueue, _timeSyncTimer, _warden, AntiDOS, WorldSession::DosProtection::Ban, WorldSession::DosProtection::BlockingThrottle, ClientOpcodeHandler::Call(), CMSG_CHAR_ENUM, CONFIG_CHAT_STRICT_LINK_CHECKING_KICK, CONFIG_CLOSE_IDLE_CONNECTIONS, WorldSession::DosProtection::EvaluateOpcode(), GetAccountId(), GameTime::GetGameTime(), WorldPackets::InvalidStringValueException::GetInvalidValue(), WorldPacket::GetOpcode(), GetOpcodeNameForLogging(), GetPlayer(), GetPlayerInfo(), GetRemoteAddress(), HandleTeleportTimeout(), ByteBuffer::hexlike(), IsConnectionIdle(), Object::IsInWorld(), WorldSession::DosProtection::Kick, KickPlayer(), WorldSession::DosProtection::Log, LOG_DEBUG, LOG_ERROR, LOG_LEVEL_DEBUG, LogoutPlayer(), LogUnexpectedOpcode(), LogUnprocessedTail(), m_inQueue, m_playerLoading, m_playerRecentlyLogout, m_Socket, METRIC_DETAILED_TIMER, METRIC_TAG, METRIC_VALUE, OpcodeHandler::Name, LockedQueue< T, StorageType >::next(), opcodeTable, WorldSession::DosProtection::Process, ProcessQueryCallbacks(), PacketFilter::ProcessUnsafe(), LockedQueue< T, StorageType >::readd(), SendTimeSync(), ShouldLogOut(), sLog, sScriptMgr, OpcodeHandler::Status, STATUS_AUTHED, STATUS_LOGGEDIN, STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, STATUS_NEVER, STATUS_TRANSFER, STATUS_UNHANDLED, sWorld, UpdateTimeOutTime(), and ByteBufferException::what().

Referenced by Map::Update(), and WorldSessionMgr::UpdateSessions().

◆ UpdateAccountFlag()

void WorldSession::UpdateAccountFlag ( uint32  flag,
bool  remove = false 
)
183{
184 if (remove)
185 _accountFlags &= ~flag;
186 else
187 _accountFlags |= flag;
188
189 // Async update
191 stmt->SetData(0, _accountFlags);
192 stmt->SetData(1, GetAccountId());
193 LoginDatabase.Execute(stmt);
194}
@ LOGIN_UPD_SET_ACCOUNT_FLAG
Definition LoginDatabase.h:89

References _accountFlags, GetAccountId(), LOGIN_UPD_SET_ACCOUNT_FLAG, LoginDatabase, and PreparedStatementBase::SetData().

Referenced by ValidateAccountFlags().

◆ UpdateTimeOutTime()

void WorldSession::UpdateTimeOutTime ( uint32  diff)
inline
569 {
570 if (time_t(diff) > m_timeOutTime)
571 m_timeOutTime = 0;
572 else
573 m_timeOutTime -= diff;
574 }

References m_timeOutTime.

Referenced by Update().

◆ ValidateAccountFlags()

void WorldSession::ValidateAccountFlags ( )
197{
198 bool hasGMFlag = HasAccountFlag(ACCOUNT_FLAG_GM);
199
200 if (IsGMAccount() && !hasGMFlag)
202 else if (hasGMFlag && !IsGMAccount())
204}
@ ACCOUNT_FLAG_GM
Definition Common.h:67
bool HasAccountFlag(uint32 flag) const
Definition WorldSession.h:375
void UpdateAccountFlag(uint32 flag, bool remove=false)
Definition WorldSession.cpp:182

References ACCOUNT_FLAG_GM, HasAccountFlag(), IsGMAccount(), and UpdateAccountFlag().

Referenced by WorldSocket::HandleAuthSessionCallback().

◆ ValidateHyperlinksAndMaybeKick()

bool WorldSession::ValidateHyperlinksAndMaybeKick ( std::string_view  str)
806{
808 return true;
809
810 LOG_ERROR("network", "Player {} {} sent a message with an invalid link:\n{}", GetPlayer()->GetName(),
811 GetPlayer()->GetGUID().ToString(), str);
812
814 KickPlayer("WorldSession::ValidateHyperlinksAndMaybeKick Invalid chat link");
815
816 return false;
817}

References Acore::Hyperlinks::CheckAllLinks(), CONFIG_CHAT_STRICT_LINK_CHECKING_KICK, GetPlayer(), KickPlayer(), LOG_ERROR, and sWorld.

Referenced by HandleGMSurveySubmit(), HandleGMTicketCreateOpcode(), HandleGMTicketUpdateOpcode(), and HandleMessagechatOpcode().

◆ VerifyMovementInfo()

bool WorldSession::VerifyMovementInfo ( MovementInfo const &  movementInfo,
Player plrMover,
Unit mover,
Opcodes  opcode 
) const
514{
515 if (!movementInfo.pos.IsPositionValid())
516 {
517 if (plrMover)
518 {
519 sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
520 }
521
522 return false;
523 }
524
525 if (!mover->movespline->Finalized())
526 {
527 if (!mover->movespline->isBoarding() || (opcode != CMSG_FORCE_MOVE_UNROOT_ACK && opcode != CMSG_FORCE_MOVE_ROOT_ACK))
528 return false;
529 }
530
531 // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE
533 {
534 // Xinef: skip moving packets
535 if (movementInfo.HasMovementFlag(MOVEMENTFLAG_MASK_MOVING))
536 {
537 if (plrMover)
538 {
539 sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
540 }
541 return false;
542 }
543 }
544
545 bool jumpopcode = false;
546 if (opcode == MSG_MOVE_JUMP)
547 {
548 jumpopcode = true;
549 if (plrMover && !sScriptMgr->AnticheatHandleDoubleJump(plrMover, mover))
550 {
551 plrMover->GetSession()->KickPlayer();
552 return false;
553 }
554 }
555
556 /* start some hack detection */
557 if (plrMover && !sScriptMgr->AnticheatCheckMovementInfo(plrMover, movementInfo, mover, jumpopcode))
558 {
559 plrMover->GetSession()->KickPlayer();
560 return false;
561 }
562
563 if (movementInfo.HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
564 {
565 // We were teleported, skip packets that were broadcast before teleport
566 if (movementInfo.pos.GetExactDist2d(mover) > SIZE_OF_GRIDS)
567 {
568 if (plrMover)
569 {
570 sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
571 //LOG_INFO("anticheat", "MovementHandler:: 2 We were teleported, skip packets that were broadcast before teleport");
572 }
573 return false;
574 }
575
576 if (!Acore::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.transport.pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.transport.pos.GetPositionY(),
577 movementInfo.pos.GetPositionZ() + movementInfo.transport.pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.transport.pos.GetOrientation()))
578 {
579 if (plrMover)
580 {
581 sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
582 }
583
584 return false;
585 }
586 }
587
588 // rooted mover sent packet without root or moving AND root - ignore, due to client crash possibility
589 if (opcode != CMSG_FORCE_MOVE_UNROOT_ACK)
590 if (mover->IsRooted() && (!movementInfo.HasMovementFlag(MOVEMENTFLAG_ROOT) || movementInfo.HasMovementFlag(MOVEMENTFLAG_MASK_MOVING)))
591 return false;
592
593 return true;
594}
#define SIZE_OF_GRIDS
Definition MapDefines.h:26
bool isBoarding() const
Definition MoveSpline.h:120
@ MSG_MOVE_JUMP
Definition Opcodes.h:217
@ CMSG_FORCE_MOVE_ROOT_ACK
Definition Opcodes.h:263
bool IsValidMapCoord(float c)
Definition GridDefines.h:210

References CMSG_FORCE_MOVE_ROOT_ACK, CMSG_FORCE_MOVE_UNROOT_ACK, Movement::MoveSpline::Finalized(), Position::GetExactDist2d(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetSession(), MovementInfo::HasMovementFlag(), Unit::HasUnitFlag(), Movement::MoveSpline::isBoarding(), Position::IsPositionValid(), Unit::IsRooted(), Acore::IsValidMapCoord(), KickPlayer(), MOVEMENTFLAG_MASK_MOVING, MOVEMENTFLAG_ONTRANSPORT, MOVEMENTFLAG_ROOT, Unit::movespline, MSG_MOVE_JUMP, MovementInfo::pos, MovementInfo::TransportInfo::pos, SIZE_OF_GRIDS, sScriptMgr, MovementInfo::transport, and UNIT_FLAG_DISABLE_MOVE.

Referenced by ProcessMovementInfo().

◆ WriteMovementInfo()

void WorldSession::WriteMovementInfo ( WorldPacket data,
MovementInfo mi 
)
1114{
1115 *data << mi->guid.WriteAsPacked();
1116
1117 *data << mi->flags;
1118 *data << mi->flags2;
1119 *data << mi->time;
1120 *data << mi->pos.PositionXYZOStream();
1121
1123 {
1124 *data << mi->transport.guid.WriteAsPacked();
1125
1126 *data << mi->transport.pos.PositionXYZOStream();
1127 *data << mi->transport.time;
1128 *data << mi->transport.seat;
1129
1131 *data << mi->transport.time2;
1132 }
1133
1135 *data << mi->pitch;
1136
1137 *data << mi->fallTime;
1138
1140 {
1141 *data << mi->jump.zspeed;
1142 *data << mi->jump.sinAngle;
1143 *data << mi->jump.cosAngle;
1144 *data << mi->jump.xyspeed;
1145 }
1146
1148 *data << mi->splineElevation;
1149}

References MovementInfo::JumpInfo::cosAngle, MovementInfo::fallTime, MovementInfo::flags, MovementInfo::flags2, MovementInfo::guid, MovementInfo::TransportInfo::guid, MovementInfo::HasExtraMovementFlag(), MovementInfo::HasMovementFlag(), MovementInfo::jump, MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING, MOVEMENTFLAG2_INTERPOLATED_MOVEMENT, MOVEMENTFLAG_FALLING, MOVEMENTFLAG_FLYING, MOVEMENTFLAG_ONTRANSPORT, MOVEMENTFLAG_SPLINE_ELEVATION, MOVEMENTFLAG_SWIMMING, MovementInfo::pitch, MovementInfo::pos, MovementInfo::TransportInfo::pos, Position::PositionXYZOStream(), MovementInfo::TransportInfo::seat, MovementInfo::JumpInfo::sinAngle, MovementInfo::splineElevation, MovementInfo::time, MovementInfo::TransportInfo::time, MovementInfo::TransportInfo::time2, MovementInfo::transport, ObjectGuid::WriteAsPacked(), MovementInfo::JumpInfo::xyspeed, and MovementInfo::JumpInfo::zspeed.

Referenced by HandleForceSpeedChangeAck(), HandleMoveFlagChangeOpcode(), HandleMovementOpcodes(), HandleMoveRootAck(), and HandleMoveSplineDoneOpcode().

Friends And Related Symbol Documentation

◆ World

friend class World
friend

Member Data Documentation

◆ _accountFlags

uint32 WorldSession::_accountFlags
private

◆ _accountId

uint32 WorldSession::_accountId
private

Referenced by GetAccountId().

◆ _accountName

std::string WorldSession::_accountName
private

◆ _addonMessageReceiveCount

std::atomic<uint32> WorldSession::_addonMessageReceiveCount
private

Referenced by HandleMessagechatOpcode(), and Update().

◆ _calendarEventCreationCooldown

time_t WorldSession::_calendarEventCreationCooldown
private

◆ _kicked

bool WorldSession::_kicked
private

Referenced by IsKicked(), SetKicked(), and WorldSession().

◆ _legitCharacters

GuidSet WorldSession::_legitCharacters
private

◆ _logoutTime

time_t WorldSession::_logoutTime
private

◆ _offlineTime

uint32 WorldSession::_offlineTime
private

◆ _orderCounter

uint32 WorldSession::_orderCounter
private

◆ _pendingTimeSyncRequests

std::map<uint32, uint32> WorldSession::_pendingTimeSyncRequests
private

◆ _player

Player* WorldSession::_player
private

Referenced by CanOpenMailBox(), DoLootRelease(), GetPlayer(), GetPlayerInfo(), GetPlayerName(), HandleAcceptGrantLevel(), HandleAcceptTradeOpcode(), HandleAlterAppearance(), HandleAreaSpiritHealerQueryOpcode(), HandleAreaSpiritHealerQueueOpcode(), HandleAreaTriggerOpcode(), HandleArenaTeamAcceptOpcode(), HandleArenaTeamDeclineOpcode(), HandleArenaTeamDisbandOpcode(), HandleArenaTeamLeaderOpcode(), HandleArenaTeamLeaveOpcode(), HandleArenaTeamRemoveOpcode(), HandleAttackSwingOpcode(), HandleAuctionListItems(), HandleAuctionSellItem(), HandleAutoBankItemOpcode(), HandleAutoEquipItemOpcode(), HandleAutoEquipItemSlotOpcode(), HandleAutoStoreBagItemOpcode(), HandleAutoStoreBankItemOpcode(), HandleAutostoreLootItemOpcode(), HandleBattlefieldLeaveOpcode(), HandleBattlefieldListOpcode(), HandleBattleFieldPortOpcode(), HandleBattlefieldStatusOpcode(), HandleBattlegroundPlayerPositionsOpcode(), HandleBattlemasterHelloOpcode(), HandleBattlemasterJoinArena(), HandleBattlemasterJoinOpcode(), HandleBeginTradeOpcode(), HandleBfEntryInviteResponse(), HandleBfExitRequest(), HandleBfQueueInviteResponse(), HandleBusyTradeOpcode(), HandleBuybackItem(), HandleBuyBankSlotOpcode(), HandleBuyItemInSlotOpcode(), HandleBuyStableSlot(), HandleCalendarAddEvent(), HandleCalendarArenaTeam(), HandleCalendarComplain(), HandleCalendarCopyEvent(), HandleCalendarEventInvite(), HandleCalendarEventModeratorStatus(), HandleCalendarEventRemoveInvite(), HandleCalendarEventRsvp(), HandleCalendarEventSignup(), HandleCalendarEventStatus(), HandleCalendarGetCalendar(), HandleCalendarGetEvent(), HandleCalendarGetNumPending(), HandleCalendarGuildFilter(), HandleCalendarRemoveEvent(), HandleCalendarUpdateEvent(), HandleCancelAuraOpcode(), HandleCancelAutoRepeatSpellOpcode(), HandleCancelCastOpcode(), HandleCancelChanneling(), HandleCancelMountAuraOpcode(), HandleCancelTradeOpcode(), HandleCastSpellOpcode(), HandleChatIgnoredOpcode(), HandleClearTradeItemOpcode(), HandleContactListOpcode(), HandleCorpseQueryOpcode(), HandleDelFriendOpcode(), HandleDelIgnoreOpcode(), HandleDestroyItemOpcode(), HandleDismissControlledVehicle(), HandleDismissCritter(), HandleEjectPassenger(), HandleEmoteOpcode(), HandleEnterPlayerVehicle(), HandleEquipmentSetDelete(), HandleEquipmentSetSave(), HandleEquipmentSetUse(), HandleFarSightOpcode(), HandleForceSpeedChangeAck(), HandleGameobjectReportUse(), HandleGetMailList(), HandleGossipHelloOpcode(), HandleGossipSelectOptionOpcode(), HandleGrantLevel(), HandleGroupDisbandOpcode(), HandleGroupRaidConvertOpcode(), HandleHearthAndResurrect(), HandleIgnoreTradeOpcode(), HandleInitiateTradeOpcode(), HandleInspectHonorStatsOpcode(), HandleInspectOpcode(), HandleInstanceLockResponse(), HandleItemRefund(), HandleItemRefundInfoRequest(), HandleItemTextQuery(), HandleLearnPreviewTalents(), HandleLearnPreviewTalentsPet(), HandleLearnTalentOpcode(), HandleLootMasterGiveOpcode(), HandleMailCreateTextItem(), HandleMailDelete(), HandleMailMarkAsRead(), HandleMailReturnToSender(), HandleMailTakeItem(), HandleMailTakeMoney(), HandleMessagechatOpcode(), HandleMirrorImageDataRequest(), HandleMoveFlagChangeOpcode(), HandleMoveKnockBackAck(), HandleMovementOpcodes(), HandleMoveNotActiveMover(), HandleMoveRootAck(), HandleMoverRelocation(), HandleMoveSplineDoneOpcode(), HandleMoveTeleportAck(), HandleMoveWorldportAck(), HandleOfferPetitionOpcode(), HandleOpenItemOpcode(), HandlePetAbandon(), HandlePetAction(), HandlePetActionHelper(), HandlePetCancelAuraOpcode(), HandlePetCastSpellOpcode(), HandlePetitionBuyOpcode(), HandlePetitionDeclineOpcode(), HandlePetitionRenameOpcode(), HandlePetitionShowSignOpcode(), HandlePetitionSignOpcode(), HandlePetLearnTalent(), HandlePetRename(), HandlePetSetAction(), HandlePetSpellAutocastOpcode(), HandlePetStopAttack(), HandlePlayedTime(), HandlePlayerLoginFromDB(), HandlePushQuestToParty(), HandlePVPLogDataOpcode(), HandleQueryInspectAchievements(), HandleQueryNextMailTime(), HandleQueryQuestsCompleted(), HandleQuestConfirmAccept(), HandleQuestgiverAcceptQuestOpcode(), HandleQuestgiverCancel(), HandleQuestgiverChooseRewardOpcode(), HandleQuestgiverCompleteQuest(), HandleQuestgiverHelloOpcode(), HandleQuestgiverQueryQuestOpcode(), HandleQuestgiverRequestRewardOpcode(), HandleQuestgiverStatusMultipleQuery(), HandleQuestgiverStatusQueryOpcode(), HandleQuestLogRemoveQuest(), HandleQuestPOIQuery(), HandleQuestPushResult(), HandleQuestQueryOpcode(), HandleRaidReadyCheckOpcode(), HandleRaidTargetUpdateOpcode(), HandleReadItem(), HandleReclaimCorpseOpcode(), HandleRemoveGlyph(), HandleRepairItemOpcode(), HandleReportPvPAFK(), HandleRequestAccountData(), HandleRequestPartyMemberStatsOpcode(), HandleRequestPetInfo(), HandleRequestRaidInfoOpcode(), HandleResetInstancesOpcode(), HandleSelfResOpcode(), HandleSellItemOpcode(), HandleSendMail(), HandleSetActionButtonOpcode(), HandleSetActiveMoverOpcode(), HandleSetAmmoOpcode(), HandleSetContactNotesOpcode(), HandleSetDungeonDifficultyOpcode(), HandleSetFactionInactiveOpcode(), HandleSetRaidDifficultyOpcode(), HandleSetSelectionOpcode(), HandleSetSheathedOpcode(), HandleSetTaxiBenchmarkOpcode(), HandleSetTradeGoldOpcode(), HandleSetTradeItemOpcode(), HandleShowingCloakOpcode(), HandleShowingHelmOpcode(), HandleSocketOpcode(), HandleSpellClick(), HandleSplitItemOpcode(), HandleStablePet(), HandleStableSwapPet(), HandleStandStateChangeOpcode(), HandleSummonResponseOpcode(), HandleSwapInvItemOpcode(), HandleSwapItem(), HandleTalentWipeConfirmOpcode(), HandleTextEmoteOpcode(), HandleTotemDestroyed(), HandleTrainerBuySpellOpcode(), HandleTurnInPetitionOpcode(), HandleUnacceptTradeOpcode(), HandleUnstablePet(), HandleUpdateMissileTrajectory(), HandleUpdateProjectilePosition(), HandleUseItemOpcode(), HandleWhoOpcode(), HandleWrapItemOpcode(), KickPlayer(), LogoutPlayer(), moveItems(), SendBattleGroundList(), SendBfEntered(), SendBindPoint(), SendListInventory(), SendPetitionShowList(), SendPetNameQuery(), SendSpiritResurrect(), SendTrainerList(), SendUpdateTrade(), SetPlayer(), Update(), and ~WorldSession().

◆ _queryHolderProcessor

AsyncCallbackProcessor<SQLQueryHolderCallback> WorldSession::_queryHolderProcessor
private

◆ _queryProcessor

◆ _recvQueue

LockedQueue<WorldPacket*> WorldSession::_recvQueue
private

Referenced by QueuePacket(), Update(), and ~WorldSession().

◆ _security

AccountTypes WorldSession::_security
private

Referenced by GetSecurity(), and SetSecurity().

◆ _skipQueue

bool WorldSession::_skipQueue
private

Referenced by CanSkipQueue().

◆ _timeSyncClockDelta

int64 WorldSession::_timeSyncClockDelta
private

◆ _timeSyncClockDeltaQueue

CircularBuffer<std::pair<int64, uint32> > WorldSession::_timeSyncClockDeltaQueue
private

◆ _timeSyncNextCounter

uint32 WorldSession::_timeSyncNextCounter
private

◆ _timeSyncTimer

uint32 WorldSession::_timeSyncTimer
private

Referenced by SendTimeSync(), Update(), and WorldSession().

◆ _transactionCallbacks

AsyncCallbackProcessor<TransactionCallback> WorldSession::_transactionCallbacks
private

◆ _warden

std::unique_ptr<Warden> WorldSession::_warden
private

◆ AntiDOS

class WorldSession::DosProtection WorldSession::AntiDOS
protected

Referenced by Update().

◆ isRecruiter

bool WorldSession::isRecruiter
private

Referenced by IsARecruiter().

◆ m_accountData

AccountData WorldSession::m_accountData[NUM_ACCOUNT_DATA_TYPES]
private

◆ m_addonsList

AddonsList WorldSession::m_addonsList
private

Referenced by ReadAddonsInfo(), and SendAddonsInfo().

◆ m_Address

std::string WorldSession::m_Address
private

Referenced by GetRemoteAddress(), and WorldSession().

◆ m_currentBankerGUID

ObjectGuid WorldSession::m_currentBankerGUID
private

◆ m_currentVendorEntry

uint32 WorldSession::m_currentVendorEntry
private

◆ m_expansion

uint8 WorldSession::m_expansion
private

Referenced by Expansion().

◆ m_GUIDLow

ObjectGuid::LowType WorldSession::m_GUIDLow
private

Referenced by SetAccountData(), and SetPlayer().

◆ m_inQueue

bool WorldSession::m_inQueue
private

◆ m_latency

std::atomic<uint32> WorldSession::m_latency
private

Referenced by GetLatency(), and SetLatency().

◆ m_muteTime

◆ m_playerLoading

◆ m_playerLogout

bool WorldSession::m_playerLogout
private

◆ m_playerRecentlyLogout

bool WorldSession::m_playerRecentlyLogout
private

◆ m_playerSave

bool WorldSession::m_playerSave
private

◆ m_sessionDbcLocale

LocaleConstant WorldSession::m_sessionDbcLocale
private

Referenced by GetSessionDbcLocale().

◆ m_sessionDbLocaleIndex

LocaleConstant WorldSession::m_sessionDbLocaleIndex
private

Referenced by GetSessionDbLocaleIndex().

◆ m_Socket

◆ m_timeOutTime

std::atomic<time_t> WorldSession::m_timeOutTime

◆ m_total_time

uint32 WorldSession::m_total_time
private

Referenced by GetTotalTime(), and SetTotalTime().

◆ m_Tutorials

◆ m_TutorialsChanged

bool WorldSession::m_TutorialsChanged
private

◆ recruiterId

uint32 WorldSession::recruiterId
private

Referenced by GetRecruiterId().


The documentation for this class was generated from the following files: