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 IsTrialAccount () const
 
bool IsInternetGameRoomAccount () const
 
bool IsRecurringBillingAccount () const
 
bool IsAffectedByCAIS () const
 
uint8 GetBillingPlanFlags () 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
 
rbac::RBACData * GetRBACData () const
 
bool HasPermission (uint32 permissionId)
 
void LoadPermissions ()
 
QueryCallback LoadPermissionsAsync ()
 
void InvalidateRBACData ()
 
void InitRBACDataForTest ()
 For unit testing - initializes RBAC data without database access.
 
uint32 GetAccountId () const
 
Player * GetPlayer () 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)
 
Warden * GetWarden ()
 
void SetInQueue (bool state)
 Session in auth.queue currently.
 
Seconds GetCreateTime () const
 
Seconds GetConsecutivePlayTime (Seconds now) const
 
Seconds GetPreviousPlayedTime () const
 
void SetPreviousPlayedTime (Seconds playedTime)
 
void CheckPlayedTimeLimit (Seconds now)
 
void SendPlayTimeWarning (PlayTimeFlag flag, int32 playTimeRemaining)
 
bool IsLoggingOut () 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, bool redirecting=false)
 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 (Creature *npc)
 
void SendListInventory (ObjectGuid guid, uint32 vendorEntry=0)
 
void SendShowBank (ObjectGuid guid)
 
bool CanOpenMailBox (ObjectGuid guid)
 
void SendShowMailBox (ObjectGuid guid)
 
void SendMailList ()
 
void SendTabardVendorActivate (ObjectGuid guid)
 
void SendSpiritResurrect ()
 
void SendBindPoint (Creature *npc)
 
void SendBattleGroundList (ObjectGuid guid, BattlegroundTypeId bgTypeId=BATTLEGROUND_RB)
 
void SendTradeStatus (TradeStatusInfo const &info)
 
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)
 
AccountData * GetAccountData (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 HandleTC9PrepareForRedirect (WorldPacket &recvData)
 
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 (WorldPackets::NPC::Hello &packet)
 
void HandleTrainerBuySpellOpcode (WorldPackets::NPC::TrainerBuySpell &packet)
 
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 (WorldPackets::Quest::QuestLogSwapQuest &packet)
 
void HandleQuestLogRemoveQuest (WorldPackets::Quest::QuestLogRemoveQuest &packet)
 
void HandleQuestConfirmAccept (WorldPackets::Quest::QuestConfirmAcceptClient &packet)
 
void HandleQuestgiverCompleteQuest (WorldPacket &recvData)
 
void HandleQuestgiverQuestAutoLaunch (WorldPackets::Quest::QuestGiverQuestAutoLaunch &packet)
 
void HandlePushQuestToParty (WorldPackets::Quest::PushQuestToParty &packet)
 
void HandleQuestPushResult (WorldPackets::Quest::QuestPushResultClient &packet)
 
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 (WorldPackets::Instance::SetDungeonDifficultyClient &packet)
 
void HandleSetRaidDifficultyOpcode (WorldPackets::Instance::SetRaidDifficultyClient &packet)
 
void HandleMoveFlagChangeOpcode (WorldPacket &recvData)
 
void HandleSetTitleOpcode (WorldPacket &recvData)
 
void HandleRealmSplitOpcode (WorldPacket &recvData)
 
void HandleTimeSyncResp (WorldPacket &recvData)
 
void HandleWhoisOpcode (WorldPacket &recvData)
 
void HandleResetInstancesOpcode (WorldPackets::Instance::ResetInstances &packet)
 
void HandleHearthAndResurrect (WorldPacket &recvData)
 
void HandleInstanceLockResponse (WorldPackets::Instance::InstanceLockResponse &packet)
 
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)
 
bool HandleSocketClosed ()
 
void SetOfflineTime (uint32 time)
 
uint32 GetOfflineTime () const
 
bool IsKicked () const
 
void SetKicked (bool val)
 
bool IsSocketClosed () const
 
QueryCallbackProcessor & GetQueryProcessor ()
 
TransactionCallback & AddTransactionCallback (TransactionCallback &&callback)
 
SQLQueryHolderCallback & AddQueryHolderCallback (SQLQueryHolderCallback &&callback)
 
void ProcessQueryCallbacks ()
 
void InitializeSession ()
 
void InitializeSessionCallback (CharacterDatabaseQueryHolder const &realmHolder, uint32 clientCacheVersion)
 
void SetPacketLogging (bool state)
 
std::unique_ptr< WorldPacket > NextQueuedPacket ()
 
bool IsHeadless () const
 

Public Attributes

time_t m_muteTime
 
std::atomic< time_t > m_timeOutTime
 

Protected Attributes

class WorldSession::DosProtection AntiDOS
 

Private Types

typedef std::list< AddonInfo > AddonsList
 

Private Member Functions

void moveItems (Item *myItems[], Item *hisItems[])
 
bool CanUseBank (ObjectGuid bankerGUID=ObjectGuid::Empty) const
 
bool recoveryItem (Item *pItem)
 
void LogUnexpectedOpcode (WorldPacket *packet, char const *status, char const *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
 
WorldSession & operator= (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< WorldSocket > m_Socket
 
std::string m_Address
 
AccountTypes _security
 
bool _skipQueue
 
uint32 _accountId
 
rbac::RBACData * _RBACData
 
std::string _accountName
 
uint32 _accountFlags
 
uint8 m_expansion
 
uint32 m_total_time
 
std::unique_ptr< Warden > _warden
 
Seconds _lastUpdateTime
 
Seconds _createTime
 
Seconds _previousPlayTime
 
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< uint32 > m_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
 
bool const _headless
 

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.

111 :
112 m_muteTime(mute_time),
113 m_timeOutTime(0),
114 AntiDOS(this),
115 m_GUIDLow(0),
116 _player(nullptr),
117 m_Socket(sock),
118 _security(sec),
119 _skipQueue(skipQueue),
120 _accountId(id),
121 _RBACData(nullptr),
122 _accountName(std::move(name)),
123 _accountFlags(accountFlags),
124 m_expansion(expansion),
125 m_total_time(TotalTime),
129 _logoutTime(0),
130 m_inQueue(false),
131 m_playerLoading(false),
132 m_playerLogout(false),
134 m_playerSave(false),
135 m_sessionDbcLocale(sWorld->GetAvailableDbcLocale(locale)),
137 m_latency(0),
138 m_TutorialsChanged(false),
139 recruiterId(recruiter),
140 isRecruiter(isARecruiter),
147 _orderCounter(0),
148 _headless(!sock)
149{
150 memset(m_Tutorials, 0, sizeof(m_Tutorials));
151
152 _offlineTime = 0;
153 _kicked = false;
154
156 _timeSyncTimer = 0;
157
158 if (sock)
159 {
160 m_Address = sock->GetRemoteIpAddress().to_string();
161 ResetTimeOutTime(false);
162 LoginDatabase.Execute("UPDATE account SET online = 1 WHERE id = {};", GetAccountId()); // One-time query
163 }
164 else
165 m_Address = "headless";
166}
DatabaseWorkerPool< LoginDatabaseConnection > LoginDatabase
Accessor to the realm/login database.
Definition DatabaseEnv.cpp:22
bool m_playerRecentlyLogout
Definition WorldSession.h:1318
bool isRecruiter
Definition WorldSession.h:1328
std::string m_Address
Definition WorldSession.h:1295
uint32 _offlineTime
Definition WorldSession.h:1332
bool m_playerSave
Definition WorldSession.h:1319
LocaleConstant m_sessionDbLocaleIndex
Definition WorldSession.h:1321
bool _skipQueue
Definition WorldSession.h:1298
CircularBuffer< std::pair< int64, uint32 > > _timeSyncClockDeltaQueue
Definition WorldSession.h:1340
bool m_TutorialsChanged
Definition WorldSession.h:1325
time_t _logoutTime
Definition WorldSession.h:1314
uint32 m_currentVendorEntry
Definition WorldSession.h:1330
bool const _headless
Definition WorldSession.h:1350
int64 _timeSyncClockDelta
Definition WorldSession.h:1341
std::atomic< uint32 > _addonMessageReceiveCount
Definition WorldSession.h:1338
bool m_playerLoading
Definition WorldSession.h:1316
std::shared_ptr< WorldSocket > m_Socket
Definition WorldSession.h:1294
std::map< uint32, uint32 > _pendingTimeSyncRequests
Definition WorldSession.h:1344
time_t _calendarEventCreationCooldown
Definition WorldSession.h:1335
class WorldSession::DosProtection AntiDOS
std::atomic< time_t > m_timeOutTime
Definition WorldSession.h:654
uint32 _timeSyncTimer
Definition WorldSession.h:1346
Seconds _createTime
Definition WorldSession.h:1312
uint32 _accountFlags
Definition WorldSession.h:1302
rbac::RBACData * _RBACData
Definition WorldSession.h:1300
uint32 m_total_time
Definition WorldSession.h:1304
std::string _accountName
Definition WorldSession.h:1301
uint32 _timeSyncNextCounter
Definition WorldSession.h:1345
uint32 recruiterId
Definition WorldSession.h:1327
bool m_playerLogout
Definition WorldSession.h:1317
uint32 _accountId
Definition WorldSession.h:1299
ObjectGuid::LowType m_GUIDLow
Definition WorldSession.h:1292
uint32 GetAccountId() const
Definition WorldSession.h:502
Player * _player
Definition WorldSession.h:1293
AccountTypes _security
Definition WorldSession.h:1297
Seconds _previousPlayTime
Definition WorldSession.h:1313
bool m_inQueue
Definition WorldSession.h:1315
LocaleConstant m_sessionDbcLocale
Definition WorldSession.h:1320
time_t m_muteTime
Definition WorldSession.h:643
std::atomic< uint32 > m_latency
Definition WorldSession.h:1322
void ResetTimeOutTime(bool onlyActive)
Definition WorldSession.h:662
Seconds _lastUpdateTime
Definition WorldSession.h:1311
uint32 m_Tutorials[MAX_ACCOUNT_TUTORIAL_VALUES]
Definition WorldSession.h:1324
uint32 _orderCounter
Definition WorldSession.h:1348
uint8 m_expansion
Definition WorldSession.h:1303
bool _kicked
Definition WorldSession.h:1333
#define sWorld
Definition World.h:318
Seconds GetGameTime()
Definition GameTime.cpp:38

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
170{
171 if (!_headless)
172 LoginDatabase.Execute("UPDATE account SET totaltime = {} WHERE id = {}", GetTotalTime(), GetAccountId());
173
175 if (_player)
176 LogoutPlayer(true);
177
179 if (m_Socket)
180 {
181 m_Socket->CloseSocket();
182 m_Socket = nullptr;
183 }
184
185 delete _RBACData;
186
188 WorldPacket* packet = nullptr;
189 while (_recvQueue.next(packet))
190 delete packet;
191
192 if (!_headless)
193 LoginDatabase.Execute("UPDATE account SET online = 0 WHERE id = {};", GetAccountId()); // One-time query
194}
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, bool redirecting=false)
Log the player out
Definition WorldSession.cpp:686
uint32 GetTotalTime() const
Definition WorldSession.h:517
LockedQueue< WorldPacket * > _recvQueue
Definition WorldSession.h:1329

References _headless, _player, _RBACData, _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)
1420{
1421 return _queryHolderProcessor.AddCallback(std::move(callback));
1422}
T & AddCallback(T &&query)
Definition AsyncCallbackProcessor.h:34
AsyncCallbackProcessor< SQLQueryHolderCallback > _queryHolderProcessor
Definition WorldSession.h:1239

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

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

◆ AddTransactionCallback()

TransactionCallback & WorldSession::AddTransactionCallback ( TransactionCallback &&  callback)
1415{
1416 return _transactionCallbacks.AddCallback(std::move(callback));
1417}
AsyncCallbackProcessor< TransactionCallback > _transactionCallbacks
Definition WorldSession.h:1238

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

Referenced by HandleTC9PrepareForRedirect().

◆ BuildPartyMemberStatsChangedPacket()

void WorldSession::BuildPartyMemberStatsChangedPacket ( Player *  player,
WorldPacket *  data 
)
818{
819 uint32 mask = player->GetGroupUpdateFlag();
820
821 if (mask == GROUP_UPDATE_FLAG_NONE)
822 return;
823
824 if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also
826
827 if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets
829
830 uint32 byteCount = 0;
831 for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i)
832 if (mask & (1 << i))
833 byteCount += GroupUpdateLength[i];
834
835 data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount);
836 *data << player->GetPackGUID();
837 *data << uint32(mask);
838
839 if (mask & GROUP_UPDATE_FLAG_STATUS)
840 {
841 uint16 playerStatus = MEMBER_STATUS_ONLINE;
842 if (player->IsPvP())
843 playerStatus |= MEMBER_STATUS_PVP;
844
845 if (!player->IsAlive())
846 {
848 playerStatus |= MEMBER_STATUS_GHOST;
849 else
850 playerStatus |= MEMBER_STATUS_DEAD;
851 }
852
853 if (player->IsFFAPvP())
854 playerStatus |= MEMBER_STATUS_PVP_FFA;
855
856 if (player->isAFK())
857 playerStatus |= MEMBER_STATUS_AFK;
858
859 if (player->isDND())
860 playerStatus |= MEMBER_STATUS_DND;
861
862 *data << uint16(playerStatus);
863 }
864
865 if (mask & GROUP_UPDATE_FLAG_CUR_HP)
866 *data << uint32(player->GetHealth());
867
868 if (mask & GROUP_UPDATE_FLAG_MAX_HP)
869 *data << uint32(player->GetMaxHealth());
870
871 Powers powerType = player->getPowerType();
873 *data << uint8(powerType);
874
876 *data << uint16(player->GetPower(powerType));
877
879 *data << uint16(player->GetMaxPower(powerType));
880
881 if (mask & GROUP_UPDATE_FLAG_LEVEL)
882 *data << uint16(player->GetLevel());
883
884 if (mask & GROUP_UPDATE_FLAG_ZONE)
885 *data << uint16(player->GetZoneId());
886
888 {
889 *data << uint16(player->GetPositionX());
890 *data << uint16(player->GetPositionY());
891 }
892
893 if (mask & GROUP_UPDATE_FLAG_AURAS)
894 {
895 uint64 auramask = player->GetAuraUpdateMaskForRaid();
896 *data << uint64(auramask);
897 for (uint32 i = 0; i < MAX_AURAS_GROUP_UPDATE; ++i)
898 {
899 if (auramask & (uint64(1) << i))
900 {
901 AuraApplication const* aurApp = player->GetVisibleAura(i);
902 *data << uint32(aurApp ? aurApp->GetBase()->GetId() : 0);
903 *data << uint8(1);
904 }
905 }
906 }
907
908 Pet* pet = player->GetPet();
910 {
911 if (pet)
912 *data << pet->GetGUID();
913 else
914 *data << (uint64) 0;
915 }
916
918 {
919 if (pet)
920 *data << pet->GetName();
921 else
922 *data << uint8(0);
923 }
924
926 {
927 if (pet)
928 *data << uint16(pet->GetDisplayId());
929 else
930 *data << uint16(0);
931 }
932
934 {
935 if (pet)
936 *data << uint32(pet->GetHealth());
937 else
938 *data << uint32(0);
939 }
940
942 {
943 if (pet)
944 *data << uint32(pet->GetMaxHealth());
945 else
946 *data << uint32(0);
947 }
948
950 {
951 if (pet)
952 *data << uint8(pet->getPowerType());
953 else
954 *data << uint8(0);
955 }
956
958 {
959 if (pet)
960 *data << uint16(pet->GetPower(pet->getPowerType()));
961 else
962 *data << uint16(0);
963 }
964
966 {
967 if (pet)
968 *data << uint16(pet->GetMaxPower(pet->getPowerType()));
969 else
970 *data << uint16(0);
971 }
972
974 {
975 if (pet)
976 {
977 uint64 auramask = pet->GetAuraUpdateMaskForRaid();
978 *data << uint64(auramask);
979 for (uint32 i = 0; i < MAX_AURAS_GROUP_UPDATE; ++i)
980 {
981 if (auramask & (uint64(1) << i))
982 {
983 AuraApplication const* aurApp = pet->GetVisibleAura(i);
984 *data << uint32(aurApp ? aurApp->GetBase()->GetId() : 0);
985 *data << uint8(aurApp ? aurApp->GetFlags() : 0);
986 }
987 }
988 }
989 else
990 *data << uint64(0);
991 }
992
994 {
995 if (Vehicle* veh = player->GetVehicle())
996 * data << uint32(veh->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]);
997 else
998 *data << uint32(0);
999 }
1000}
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:68
@ MEMBER_STATUS_PVP
Definition Group.h:63
@ MEMBER_STATUS_ONLINE
Definition Group.h:62
@ MEMBER_STATUS_DEAD
Definition Group.h:64
@ MEMBER_STATUS_GHOST
Definition Group.h:65
@ MEMBER_STATUS_DND
Definition Group.h:69
@ MEMBER_STATUS_PVP_FFA
Definition Group.h:66
static const uint8 GroupUpdateLength[GROUP_UPDATE_FLAGS_COUNT]
Definition Group.h:148
@ GROUP_UPDATE_FLAG_CUR_HP
Definition Group.h:102
@ GROUP_UPDATE_FLAG_PET_CUR_HP
Definition Group.h:114
@ GROUP_UPDATE_FLAG_POWER_TYPE
Definition Group.h:104
@ GROUP_UPDATE_FLAG_PET_CUR_POWER
Definition Group.h:117
@ GROUP_UPDATE_FLAG_PET_MAX_POWER
Definition Group.h:118
@ GROUP_UPDATE_FLAG_MAX_HP
Definition Group.h:103
@ GROUP_UPDATE_FLAG_VEHICLE_SEAT
Definition Group.h:120
@ GROUP_UPDATE_FLAG_STATUS
Definition Group.h:101
@ GROUP_UPDATE_FLAG_PET_POWER_TYPE
Definition Group.h:116
@ GROUP_UPDATE_FLAG_MAX_POWER
Definition Group.h:106
@ GROUP_UPDATE_FLAG_ZONE
Definition Group.h:108
@ GROUP_UPDATE_FLAG_NONE
Definition Group.h:100
@ GROUP_UPDATE_FLAG_POSITION
Definition Group.h:109
@ GROUP_UPDATE_FLAG_PET_MODEL_ID
Definition Group.h:113
@ GROUP_UPDATE_FLAG_PET_NAME
Definition Group.h:112
@ GROUP_UPDATE_FLAG_PET_AURAS
Definition Group.h:119
@ GROUP_UPDATE_FLAG_AURAS
Definition Group.h:110
@ GROUP_UPDATE_FLAG_LEVEL
Definition Group.h:107
@ GROUP_UPDATE_FLAG_PET_GUID
Definition Group.h:111
@ GROUP_UPDATE_FLAG_PET_MAX_HP
Definition Group.h:115
@ GROUP_UPDATE_FLAG_CUR_POWER
Definition Group.h:105
#define GROUP_UPDATE_FLAGS_COUNT
Definition Group.h:146
@ PLAYER_FLAGS_GHOST
Definition Player.h:463
Powers
Definition SharedDefines.h:256
#define MAX_AURAS_GROUP_UPDATE
Definition SpellAuraDefines.h:22
Definition SpellAuras.h:37
uint8 GetFlags() const
Definition SpellAuras.h:66
Aura * GetBase() const
Definition SpellAuras.h:63
uint32 GetId() const
Definition SpellAuras.cpp:410
PackedGuid const & GetPackGUID() const
Definition Object.h:122
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:120
Definition Pet.h:41
uint64 GetAuraUpdateMaskForRaid() const
Definition Pet.h:136
uint64 GetAuraUpdateMaskForRaid() const
Definition Player.h:2524
Pet * GetPet() const
Definition Player.cpp:9149
bool IsFFAPvP()
Definition Player.cpp:16598
bool isDND() const
Definition Player.h:1152
uint32 GetGroupUpdateFlag() const
Definition Player.h:2522
bool HasPlayerFlag(PlayerFlags flags) const
Definition Player.h:1125
bool isAFK() const
Definition Player.h:1151
bool IsPvP()
Definition Player.cpp:16607
Vehicle * GetVehicle() const
Definition Unit.h:1932
AuraApplication * GetVisibleAura(uint8 slot)
Definition Unit.h:1545
uint32 GetMaxHealth() const
Definition Unit.h:1115
bool IsAlive() const
Definition Unit.h:1796
uint32 GetDisplayId() const
Definition Unit.h:1980
uint32 GetMaxPower(Powers power) const
Definition Unit.h:1142
uint32 GetHealth() const
Definition Unit.h:1114
Powers getPowerType() const
Definition Unit.h:1137
uint32 GetPower(Powers power) const
Definition Unit.h:1141
uint8 GetLevel() const
Definition Unit.h:1109
Definition Vehicle.h:28
std::string const & GetName() const
Definition Object.h:535
uint32 GetZoneId() const
Definition Object.cpp:3171
MovementInfo m_movementInfo
Definition Object.h:711
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:317
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)
40{
41 if (guid == _player->GetGUID())
42 {
44 {
45 LOG_WARN("cheat", "{} attempted to open mailbox by using a cheat.", _player->GetName());
46 return false;
47 }
48 }
49 else if (guid.IsGameObject())
50 {
52 return false;
53 }
54 else if (guid.IsAnyTypeCreature())
55 {
57 return false;
58 }
59 else
60 return false;
61
62 return true;
63}
#define LOG_WARN(filterType__,...)
Definition Log.h:149
@ GAMEOBJECT_TYPE_MAILBOX
Definition SharedDefines.h:1583
@ UNIT_NPC_FLAG_MAILBOX
Definition UnitDefines.h:348
bool IsGameObject() const
Definition ObjectGuid.h:175
bool IsAnyTypeCreature() const
Definition ObjectGuid.h:171
Creature * GetNPCIfCanInteractWith(ObjectGuid const &guid, uint32 npcflagmask)
Definition Player.cpp:2115
GameObject * GetGameObjectIfCanInteractWith(ObjectGuid const &guid, GameobjectTypes type) const
Definition Player.cpp:2167
bool HasPermission(uint32 permissionId)
Definition WorldSession.cpp:1691
@ RBAC_PERM_COMMAND_MAILBOX
Definition RBAC.h:600

References _player, GAMEOBJECT_TYPE_MAILBOX, Player::GetGameObjectIfCanInteractWith(), Object::GetGUID(), WorldObject::GetName(), Player::GetNPCIfCanInteractWith(), HasPermission(), ObjectGuid::IsAnyTypeCreature(), ObjectGuid::IsGameObject(), LOG_WARN, rbac::RBAC_PERM_COMMAND_MAILBOX, and UNIT_NPC_FLAG_MAILBOX.

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

◆ CanSkipQueue()

bool WorldSession::CanSkipQueue ( ) const
inline
491{ 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:339
Definition Creature.h:47
Player * GetPlayer() const
Definition WorldSession.h:503
ObjectGuid m_currentBankerGUID
Definition WorldSession.h:1331

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

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

◆ CheckPlayedTimeLimit()

void WorldSession::CheckPlayedTimeLimit ( Seconds  now)
645{
646 Seconds const previousPlayed = GetConsecutivePlayTime(_lastUpdateTime);
647 Seconds const currentPlayed = GetConsecutivePlayTime(now);
648
649 if ((previousPlayed < PLAY_TIME_LIMIT_FULL) &&
650 (currentPlayed >= PLAY_TIME_LIMIT_FULL))
651 {
655 }
656 else if ((previousPlayed < PLAY_TIME_LIMIT_APPROACHING_FULL) &&
657 (currentPlayed >= PLAY_TIME_LIMIT_APPROACHING_FULL))
658 {
662 }
663 else if ((previousPlayed < PLAY_TIME_LIMIT_PARTIAL) &&
664 (currentPlayed >= PLAY_TIME_LIMIT_PARTIAL))
665 {
669 }
670 else if ((previousPlayed < PLAY_TIME_LIMIT_APPROACHING_PARTIAL) &&
671 (currentPlayed >= PLAY_TIME_LIMIT_APPROACHING_PARTIAL))
672 {
674 }
675}
std::int32_t int32
Definition Define.h:103
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition Duration.h:30
@ PLAYER_FLAGS_PARTIAL_PLAY_TIME
Definition Player.h:471
@ PLAYER_FLAGS_NO_PLAY_TIME
Definition Player.h:472
void SetPlayerFlag(PlayerFlags flags)
Definition Player.h:1126
void RemovePlayerFlag(PlayerFlags flags)
Definition Player.h:1127
Seconds GetConsecutivePlayTime(Seconds now) const
Definition WorldSession.h:529
void SendPlayTimeWarning(PlayTimeFlag flag, int32 playTimeRemaining)
Definition WorldSession.cpp:677
constexpr Seconds PLAY_TIME_LIMIT_APPROACHING_PARTIAL
Definition WorldSession.h:307
constexpr Seconds PLAY_TIME_LIMIT_PARTIAL
Definition WorldSession.h:308
constexpr Seconds PLAY_TIME_LIMIT_FULL
Definition WorldSession.h:310
constexpr Seconds PLAY_TIME_LIMIT_APPROACHING_FULL
Definition WorldSession.h:309
@ PTF_APPROACHING_NO_PLAY_TIME
Definition WorldSession.h:315
@ PTF_UNHEALTHY_TIME
Definition WorldSession.h:318
@ PTF_APPROACHING_PARTIAL_PLAY_TIME
Definition WorldSession.h:314

References _lastUpdateTime, GetConsecutivePlayTime(), GetPlayer(), PLAY_TIME_LIMIT_APPROACHING_FULL, PLAY_TIME_LIMIT_APPROACHING_PARTIAL, PLAY_TIME_LIMIT_FULL, PLAY_TIME_LIMIT_PARTIAL, PLAYER_FLAGS_NO_PLAY_TIME, PLAYER_FLAGS_PARTIAL_PLAY_TIME, PTF_APPROACHING_NO_PLAY_TIME, PTF_APPROACHING_PARTIAL_PLAY_TIME, PTF_UNHEALTHY_TIME, Player::RemovePlayerFlag(), SendPlayTimeWarning(), and Player::SetPlayerFlag().

Referenced by Update().

◆ CheckStableMaster()

bool WorldSession::CheckStableMaster ( ObjectGuid  guid)
674{
675 // spell case or GM
676 if (guid == GetPlayer()->GetGUID())
677 {
678 if (!GetPlayer()->IsGameMaster() && !GetPlayer()->HasOpenStableAura())
679 {
680 LOG_DEBUG("network.opcode", "Player ({}) attempt open stable in cheating way.", guid.ToString());
681 return false;
682 }
683 }
684 // stable master case
685 else
686 {
687 if (!GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_STABLEMASTER))
688 {
689 LOG_DEBUG("network.opcode", "Stablemaster ({}) not found or you can't interact with him.", guid.ToString());
690 return false;
691 }
692 }
693 return true;
694}
#define LOG_DEBUG(filterType__,...)
Definition Log.h:157
@ UNIT_NPC_FLAG_STABLEMASTER
Definition UnitDefines.h:344
std::string ToString() const
Definition ObjectGuid.cpp:48

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

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

◆ ComputeNewClockDelta()

void WorldSession::ComputeNewClockDelta ( )
private
961{
962 // implementation of the technique described here: https://web.archive.org/web/20180430214420/http://www.mine-control.com/zack/timesync/timesync.html
963 // to reduce the skew induced by dropped TCP packets that get resent.
964
965 std::vector<uint32> latencies;
966 std::vector<int64> clockDeltasAfterFiltering;
967
968 for (auto& pair : _timeSyncClockDeltaQueue.content())
969 latencies.push_back(pair.second);
970
971 uint32 latencyMedian = median(latencies);
972 uint32 latencyStandardDeviation = standard_deviation(latencies);
973
974 uint32 sampleSizeAfterFiltering = 0;
975 for (auto& pair : _timeSyncClockDeltaQueue.content())
976 {
977 if (pair.second <= latencyMedian + latencyStandardDeviation)
978 {
979 clockDeltasAfterFiltering.push_back(pair.first);
980 sampleSizeAfterFiltering++;
981 }
982 }
983
984 if (sampleSizeAfterFiltering != 0)
985 {
986 int64 meanClockDelta = static_cast<int64>(mean(clockDeltasAfterFiltering));
987 if (std::abs(meanClockDelta - _timeSyncClockDelta) > 25)
988 _timeSyncClockDelta = meanClockDelta;
989 }
990 else if (_timeSyncClockDelta == 0)
991 {
992 std::pair<int64, uint32> back = _timeSyncClockDeltaQueue.peak_back();
993 _timeSyncClockDelta = back.first;
994 }
995}
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)
910{
911 if (str.find('|') == std::string_view::npos)
912 return true;
913
914 LOG_ERROR("network", "Player {} {} sent a message which illegally contained a hyperlink:\n{}", GetPlayer()->GetName(),
915 GetPlayer()->GetGUID().ToString(), str);
916
918 KickPlayer("WorldSession::DisallowHyperlinksAndMaybeKick Illegal chat link");
919
920 return false;
921}
#define LOG_ERROR(filterType__,...)
Definition Log.h:145
@ CONFIG_CHAT_STRICT_LINK_CHECKING_KICK
Definition WorldConfig.h:248
void KickPlayer(bool setKicked=true)
Definition WorldSession.h:551
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)
328{
329 Player* player = GetPlayer();
330 Loot* loot;
331
333 player->SendLootRelease(lguid);
334
336
337 if (!player->IsInWorld())
338 return;
339
340 if (lguid.IsGameObject())
341 {
342 GameObject* go = GetPlayer()->GetMap()->GetGameObject(lguid);
343
344 // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO
345 if (!go || ((go->GetOwnerGUID() != _player->GetGUID() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player)))
346 {
347 return;
348 }
349
350 loot = &go->loot;
351
352 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR)
353 {
354 // locked doors are opened with spelleffect openlock, prevent remove its as looted
355 go->UseDoorOrButton();
356 }
357 else if (loot->isLooted() || go->GetGoType() == GAMEOBJECT_TYPE_FISHINGNODE)
358 {
360 {
361 // The fishing hole used once more
362 go->AddUse(); // if the max usage is reached, will be despawned in next tick
363 if (go->GetUseCount() >= go->GetGOValue()->FishingHole.MaxOpens)
365 else
367 }
368 else
369 {
371
372 // Xinef: moved event execution to loot release (after everything is looted)
373 // Xinef: 99% sure that this worked like this on blizz
374 // Xinef: prevents exploits with just opening GO and spawning bilions of npcs, which can crash core if you know what you're doin ;)
376 {
377 LOG_DEBUG("spells.aura", "Chest ScriptStart id {} for GO {}", go->GetGOInfo()->chest.eventId, go->GetSpawnId());
378 player->GetMap()->ScriptsStart(sEventScripts, go->GetGOInfo()->chest.eventId, player, go);
379 }
380 }
381
382 loot->clear();
383 }
384 else
385 {
386 // not fully looted object
387 go->SetLootState(GO_ACTIVATED, player);
388
389 // if the round robin player release, reset it.
390 if (player->GetGUID() == loot->roundRobinPlayer)
391 loot->roundRobinPlayer.Clear();
392 }
393 }
394 else if (lguid.IsCorpse()) // ONLY remove insignia at BG
395 {
396 Corpse* corpse = ObjectAccessor::GetCorpse(*player, lguid);
397 if (!corpse || !corpse->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
398 return;
399
400 loot = &corpse->loot;
401
402 // Xinef: Buggs client? (Opening loot after closing)
403 //if (loot->isLooted())
404 {
405 loot->clear();
407 }
408 }
409 else if (lguid.IsItem())
410 {
411 Item* pItem = player->GetItemByGuid(lguid);
412 if (!pItem)
413 return;
414
415 loot = &pItem->loot;
416 ItemTemplate const* proto = pItem->GetTemplate();
417
418 // destroy only 5 items from stack in case prospecting and milling
420 {
421 pItem->m_lootGenerated = false;
422 pItem->loot.clear();
423
424 uint32 count = pItem->GetCount();
425
426 // >=5 checked in spell code, but will work for cheating cases also with removing from another stacks.
427 if (count > 5)
428 count = 5;
429
430 player->DestroyItemCount(pItem, count, true);
431 }
432 else if (pItem->loot.isLooted() || !proto->HasFlag(ITEM_FLAG_HAS_LOOT))
433 {
434 player->DestroyItem(pItem->GetBagSlot(), pItem->GetSlot(), true);
435 return;
436 }
437 }
438 else
439 {
440 Creature* creature = GetPlayer()->GetMap()->GetCreature(lguid);
441
442 bool lootAllowed = creature && creature->IsAlive() == (player->IsClass(CLASS_ROGUE, CLASS_CONTEXT_ABILITY) && creature->loot.loot_type == LOOT_PICKPOCKETING);
443 if (!lootAllowed || !creature->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
444 return;
445
446 loot = &creature->loot;
447 if (loot->isLooted())
448 {
449 // skip pickpocketing loot for speed, skinning timer reduction is no-op in fact
450 if (!creature->IsAlive())
451 creature->AllLootRemovedFromCorpse();
452
454 loot->clear();
455 }
456 else
457 {
458 // if the round robin player release, reset it.
459 if (player->GetGUID() == loot->roundRobinPlayer)
460 {
461 loot->roundRobinPlayer.Clear();
462
463 if (Group* group = player->GetGroup())
464 group->SendLooter(creature, nullptr);
465 }
466 // force dynflag update to update looter and lootable info
468 }
469 }
470
471 //Player is not looking at loot list, he doesn't need to see updates on the loot list
472 if (!lguid.IsItem())
473 {
474 loot->RemoveLooter(player->GetGUID());
475 }
476}
@ 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:61
@ GAMEOBJECT_TYPE_CHEST
Definition SharedDefines.h:1567
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition SharedDefines.h:1589
@ GAMEOBJECT_TYPE_FISHINGNODE
Definition SharedDefines.h:1581
@ GAMEOBJECT_TYPE_DOOR
Definition SharedDefines.h:1564
@ CORPSE_DYNFLAG_LOOTABLE
Definition SharedDefines.h:3366
@ UNIT_DYNFLAG_LOOTABLE
Definition SharedDefines.h:3354
@ CLASS_ROGUE
Definition SharedDefines.h:129
@ CLASS_CONTEXT_ABILITY
Definition UnitDefines.h:241
@ UNIT_FLAG_LOOTING
Definition UnitDefines.h:267
@ CORPSE_FIELD_DYNAMIC_FLAGS
Definition UpdateFields.h:428
@ UNIT_DYNAMIC_FLAGS
Definition UpdateFields.h:136
Definition Corpse.h:49
Loot loot
Definition Corpse.h:78
Loot loot
Definition Creature.h:231
void AllLootRemovedFromCorpse()
Definition Creature.cpp:3171
Definition GameObject.h:120
ObjectGuid GetOwnerGUID() const override
Definition GameObject.h:174
bool IsWithinDistInMap(Player const *player) const
Definition GameObject.cpp:3046
Loot loot
Definition GameObject.h:248
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
Definition GameObject.cpp:1429
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:136
void AddUse()
Definition GameObject.h:240
GameObjectValue const * GetGOValue() const
Definition GameObject.h:139
void SetLootState(LootState s, Unit *unit=nullptr)
Definition GameObject.cpp:2484
GameobjectTypes GetGoType() const
Definition GameObject.h:204
ObjectGuid::LowType GetSpawnId() const
Definition GameObject.h:144
uint32 GetUseCount() const
Definition GameObject.h:242
Definition Group.h:177
Definition Item.h:220
uint8 GetSlot() const
Definition Item.h:281
ItemTemplate const * GetTemplate() const
Definition Item.cpp:545
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:785
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:2447
Creature * GetCreature(ObjectGuid const &guid)
Definition Map.cpp:2442
static ObjectGuid const Empty
Definition ObjectGuid.h:123
bool IsCorpse() const
Definition ObjectGuid.h:177
bool IsItem() const
Definition ObjectGuid.h:174
void Clear()
Definition ObjectGuid.h:141
virtual void RemoveDynamicFlag(uint32 flag)
Definition Object.h:132
bool IsInWorld() const
Definition Object.h:115
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition Object.cpp:851
void ForceValuesUpdateAtIndex(uint32)
Definition Object.cpp:2158
Definition Player.h:1086
void SendLootRelease(ObjectGuid guid)
Definition Player.cpp:7978
void SetLootGUID(ObjectGuid guid)
Definition Player.h:2027
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition PlayerStorage.cpp:3132
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition Player.cpp:1350
Group * GetGroup()
Definition Player.h:2517
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition PlayerStorage.cpp:3225
Item * GetItemByGuid(ObjectGuid guid) const
Definition PlayerStorage.cpp:411
void RemoveUnitFlag(UnitFlags flags)
UnitFlags available in UnitDefines.h.
Definition Unit.h:750
Map * GetMap() const
Definition Object.h:637
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1386
Corpse * GetCorpse(WorldObject const &u, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:203
uint32 eventId
Definition GameObjectData.h:90
struct GameObjectTemplate::@236::@241 chest
Definition ItemTemplate.h:619
bool HasFlag(ItemFlags flag) const
Definition ItemTemplate.h:827
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::@233 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
599{ return &m_accountData[type]; }
AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES]
Definition WorldSession.h:1323

References m_accountData.

Referenced by HandleRequestAccountData(), and SendAccountDataTimes().

◆ GetAccountFlags()

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

References _accountFlags.

Referenced by misc_commandscript::HandlePInfoCommand().

◆ GetAccountId()

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

References _accountId.

Referenced by Player::_SaveInstanceTimeRestrictions(), WorldSessionMgr::AddSession_(), Warden::ApplyPenalty(), CharacterActionIpLogger::CharacterIPLogAction(), Spell::CheckCast(), Spell::CheckEffectTarget(), Spell::EffectEnchantItemPerm(), Spell::EffectEnchantItemPrismatic(), Spell::EffectEnchantItemTmp(), WorldSession::DosProtection::EvaluateOpcode(), GetPlayerInfo(), Player::GetsRecruitAFriendBonus(), HandleAcceptGrantLevel(), HandleAcceptTradeOpcode(), account_commandscript::HandleAccount2FARemoveCommand(), account_commandscript::HandleAccount2FASetupCommand(), account_commandscript::HandleAccountAddonCommand(), account_commandscript::HandleAccountCommand(), account_commandscript::HandleAccountCreateCommand(), account_commandscript::HandleAccountInfoCommand(), account_commandscript::HandleAccountLockCountryCommand(), account_commandscript::HandleAccountLockIpCommand(), account_commandscript::HandleAccountPasswordCommand(), account_commandscript::HandleAccountSetAddonCommand(), account_commandscript::HandleAccountSetGmLevelCommand(), HandleAuctionPlaceBid(), HandleAuctionRemoveItem(), HandleAuctionSellItem(), HandleCharCreateOpcode(), HandleCharCustomize(), HandleCharCustomizeCallback(), HandleCharDeleteOpcode(), HandleCharEnum(), HandleCharEnumOpcode(), HandleCharFactionOrRaceChange(), HandleCharFactionOrRaceChangeCallback(), HandleCharRenameCallBack(), HandleCharRenameOpcode(), WardenWin::HandleData(), HandleDismissCritter(), HandleForceSpeedChangeAck(), HandleGrantLevel(), HandleMailReturnToSender(), HandleMailTakeItem(), HandleMailTakeMoney(), Guild::HandleMemberDepositMoney(), Guild::HandleMemberWithdrawMoney(), misc_commandscript::HandleMuteCommand(), HandlePetitionSignOpcode(), misc_commandscript::HandlePInfoCommand(), HandlePlayerLoginFromDB(), HandlePlayerLoginOpcode(), HandleSendMail(), HandleTC9PrepareForRedirect(), misc_commandscript::HandleUnmuteCommand(), HandleWhoisOpcode(), WorldSessionMgr::HasRecentlyDisconnected(), WardenMac::Init(), WardenWin::Init(), InitializeSession(), BattlegroundQueue::InviteGroupToBG(), Channel::JoinChannel(), Channel::KickOrBan(), KickPlayer(), Player::LoadFromDB(), LoadPermissions(), LoadPermissionsAsync(), LogCommandUsage(), LogoutPlayer(), 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
924{
925 return sObjectMgr->GetAcoreString(entry, GetSessionDbLocaleIndex());
926}
#define sObjectMgr
Definition ObjectMgr.h:1731
LocaleConstant GetSessionDbLocaleIndex() const
Definition WorldSession.h:647

References GetSessionDbLocaleIndex(), and sObjectMgr.

Referenced by Player::_LoadInventory(), Player::AutoUnequipOffhandIfNeed(), ChatHandler::GetAcoreString(), HandleAddFriendOpcode(), HandleAddIgnoreOpcode(), HandleMessagechatOpcode(), Player::PrepareGossipMenu(), Player::Satisfy(), and SendAreaTriggerMessage().

◆ GetBillingPlanFlags()

uint8 WorldSession::GetBillingPlanFlags ( ) const
249{
250 uint8 flags = SESSION_NONE;
251
253 flags |= SESSION_RECURRING_BILL;
254
255 if (IsTrialAccount())
256 flags |= SESSION_FREE_TRIAL;
257
259 flags |= SESSION_IGR;
260
261 if (IsAffectedByCAIS())
262 flags |= SESSION_ENABLE_CAIS;
263
264 return flags;
265}
bool IsInternetGameRoomAccount() const
Definition WorldSession.cpp:230
bool IsRecurringBillingAccount() const
Definition WorldSession.cpp:235
bool IsAffectedByCAIS() const
Definition WorldSession.cpp:240
bool IsTrialAccount() const
Definition WorldSession.cpp:225
@ SESSION_NONE
Definition World.h:75
@ SESSION_RECURRING_BILL
Definition World.h:77
@ SESSION_ENABLE_CAIS
Definition World.h:83
@ SESSION_FREE_TRIAL
Definition World.h:78
@ SESSION_IGR
Definition World.h:79

References IsAffectedByCAIS(), IsInternetGameRoomAccount(), IsRecurringBillingAccount(), IsTrialAccount(), SESSION_ENABLE_CAIS, SESSION_FREE_TRIAL, SESSION_IGR, SESSION_NONE, and SESSION_RECURRING_BILL.

Referenced by SendAuthResponse().

◆ GetCalendarEventCreationCooldown()

time_t WorldSession::GetCalendarEventCreationCooldown ( ) const
inline

◆ GetConsecutivePlayTime()

Seconds WorldSession::GetConsecutivePlayTime ( Seconds  now) const
inline

◆ GetCreateTime()

Seconds WorldSession::GetCreateTime ( ) const
inline
526{ return _createTime; }

References _createTime.

◆ GetCurrentVendor()

◆ GetGuidLow()

ObjectGuid::LowType WorldSession::GetGuidLow ( ) const

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

303{
304 return GetPlayer() ? GetPlayer()->GetGUID().GetCounter() : 0;
305}
LowType GetCounter() const
Definition ObjectGuid.h:149

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

◆ GetLatency()

◆ GetModuleString()

std::string const * WorldSession::GetModuleString ( std::string  module,
uint32  id 
) const
929{
930 return sObjectMgr->GetModuleString(module, id, GetSessionDbLocaleIndex());
931}

References GetSessionDbLocaleIndex(), and sObjectMgr.

Referenced by ChatHandler::GetModuleString().

◆ GetOfflineTime()

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

References _offlineTime.

Referenced by WorldSessionMgr::UpdateSessions().

◆ GetOrderCounter()

◆ GetPlayer()

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

References _player.

Referenced by Guild::_SendBankContent(), Guild::_SendBankList(), Warden::ApplyPenalty(), Guild::BroadcastToGuild(), CanUseBank(), CheckPlayedTimeLimit(), CheckStableMaster(), DisallowHyperlinksAndMaybeKick(), DoLootRelease(), go_commandscript::DoTeleport(), go_commandscript::DoTeleportToTransport(), 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::HandleGameObjectDespawnGroupCommand(), gobject_commandscript::HandleGameObjectMoveCommand(), gobject_commandscript::HandleGameObjectNearCommand(), HandleGameobjectReportUse(), gobject_commandscript::HandleGameObjectSpawnGroupCommand(), 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(), group_commandscript::HandleGroupInvitesCommand(), 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::HandleLearnAllMyTalentsCommand(), learn_commandscript::HandleLearnAllMyTrainerSpellsCommand(), 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(), list_commandscript::HandleListRespawnsCommand(), 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::HandleNpcDespawnGroupCommand(), npc_commandscript::HandleNpcFollowCommand(), npc_commandscript::HandleNpcMoveCommand(), npc_commandscript::HandleNpcNearCommand(), npc_commandscript::HandleNpcSetFactionTempIdCommand(), npc_commandscript::HandleNpcSetOriginalFaction(), npc_commandscript::HandleNpcSpawnGroupCommand(), 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(), pool_commandscript::HandlePoolLookupCommand(), 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(), misc_commandscript::HandleRespawnCreatureByEntryCommand(), misc_commandscript::HandleRespawnCreatureByGuidCommand(), misc_commandscript::HandleRespawnGameObjectByEntryCommand(), misc_commandscript::HandleRespawnGameObjectByGuidCommand(), 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(), HandleTC9PrepareForRedirect(), tele_commandscript::HandleTeleAddCommand(), tele_commandscript::HandleTeleCommand(), HandleTextEmoteOpcode(), HandleTogglePvP(), HandleTotemDestroyed(), HandleTrainerBuySpellOpcode(), HandleTrainerListOpcode(), 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(), 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
273{
274 std::ostringstream ss;
275
276 ss << "[Player: ";
277
278 if (!m_playerLoading && _player)
279 {
280 ss << _player->GetName() << ' ' << _player->GetGUID().ToString() << ", ";
281 }
282
283 ss << "Account: " << GetAccountId() << "]";
284
285 return ss.str();
286}

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(), SendTrainerList(), Pet::Update(), and Update().

◆ GetPlayerName()

◆ GetPreviousPlayedTime()

Seconds WorldSession::GetPreviousPlayedTime ( ) const
inline
530{ return _previousPlayTime; }

References _previousPlayTime.

◆ GetQueryProcessor()

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

References _queryProcessor.

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

◆ GetRBACData()

rbac::RBACData * WorldSession::GetRBACData ( ) const
inline
494{ return _RBACData; }

References _RBACData.

◆ GetRecruiterId()

◆ GetRemoteAddress()

◆ GetSecurity()

◆ GetSessionDbcLocale()

◆ GetSessionDbLocaleIndex()

LocaleConstant WorldSession::GetSessionDbLocaleIndex ( ) const
inline

◆ GetTotalTime()

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

References m_total_time.

Referenced by ~WorldSession().

◆ GetTutorialInt()

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

References m_Tutorials.

Referenced by HandleTutorialFlag().

◆ GetWarden()

Warden * WorldSession::GetWarden ( )
1440{
1441 return &(*_warden);
1442}

◆ Handle_Deprecated()

void WorldSession::Handle_Deprecated ( WorldPacket &  recvPacket)
952{
953 LOG_ERROR("network.opcode", "Received deprecated opcode {} from {}",
954 GetOpcodeNameForLogging(static_cast<OpcodeClient>(recvPacket.GetOpcode())), GetPlayerInfo());
955}
uint16 GetOpcode() const
Definition WorldPacket.h:75
std::string GetPlayerInfo() const
Definition WorldSession.cpp:272
Opcodes
List of Opcodes.
Definition Opcodes.h:30
std::string GetOpcodeNameForLogging(Opcodes opcode)
Lookup opcode name for human understandable logging.
Definition Opcodes.cpp:1470

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

◆ Handle_EarlyProccess()

void WorldSession::Handle_EarlyProccess ( WorldPacket &  recvPacket)
940{
941 LOG_ERROR("network.opcode", "Received opcode {} that must be processed in WorldSocket::ReadDataHandler from {}",
942 GetOpcodeNameForLogging(static_cast<OpcodeClient>(recvPacket.GetOpcode())), GetPlayerInfo());
943}

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

Referenced by OpcodeTable::Initialize().

◆ Handle_NULL()

void WorldSession::Handle_NULL ( WorldPacket &  null)
934{
935 LOG_ERROR("network.opcode", "Received unhandled opcode {} from {}",
937}

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

Referenced by OpcodeTable::Initialize().

◆ Handle_ServerSide()

void WorldSession::Handle_ServerSide ( WorldPacket &  recvPacket)
946{
947 LOG_ERROR("network.opcode", "Received server-side opcode {} from {}",
948 GetOpcodeNameForLogging(static_cast<OpcodeServer>(recvPacket.GetOpcode())), GetPlayerInfo());
949}

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:121
PackedGuidReader ReadAsPacked()
Definition ObjectGuid.h:138
void GiveLevel(uint8 level)
Definition Player.cpp:2480
void SetGrantableLevels(uint8 val)
Definition Player.h:2154
WorldSession * GetSession() const
Definition Player.h:2031
uint8 GetGrantableLevels()
Definition Player.h:2153
uint32 GetRecruiterId() const
Definition WorldSession.h:675
Player * GetPlayer(Map const *, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:244

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)
238{
239 TradeData* my_trade = _player->m_trade;
240 if (!my_trade)
241 return;
242
243 Player* trader = my_trade->GetTrader();
244
245 TradeData* his_trade = trader->m_trade;
246 if (!his_trade)
247 return;
248
249 Item* myItems[TRADE_SLOT_TRADED_COUNT] = { };
250 Item* hisItems[TRADE_SLOT_TRADED_COUNT] = { };
251
252 // set before checks for propertly undo at problems (it already set in to client)
253 my_trade->SetAccepted(true);
254
255 TradeStatusInfo info;
256 if (!_player->IsWithinDistInMap(trader, TRADE_DISTANCE, false))
257 {
259 SendTradeStatus(info);
260 my_trade->SetAccepted(false);
261 return;
262 }
263
264 // not accept case incorrect money amount
265 if (!_player->HasEnoughMoney(my_trade->GetMoney()))
266 {
269 SendTradeStatus(info);
270 my_trade->SetAccepted(false, true);
271 return;
272 }
273
274 // not accept case incorrect money amount
275 if (!trader->HasEnoughMoney(his_trade->GetMoney()))
276 {
279 trader->GetSession()->SendTradeStatus(info);
280 his_trade->SetAccepted(false, true);
281 return;
282 }
283
284 if (_player->GetMoney() >= MAX_MONEY_AMOUNT - his_trade->GetMoney())
285 {
288 SendTradeStatus(info);
289 my_trade->SetAccepted(false, true);
290 return;
291 }
292
293 if (trader->GetMoney() >= MAX_MONEY_AMOUNT - my_trade->GetMoney())
294 {
297 trader->GetSession()->SendTradeStatus(info);
298 his_trade->SetAccepted(false, true);
299 return;
300 }
301
302 // not accept if some items now can't be trade (cheating)
303 for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i)
304 {
305 if (Item* item = my_trade->GetItem(TradeSlots(i)))
306 {
307 if (!item->CanBeTraded(false, true))
308 {
310 SendTradeStatus(info);
311 return;
312 }
313
314 if (item->IsBindedNotWith(trader))
315 {
318 SendTradeStatus(info);
319 return;
320 }
321 }
322
323 if (Item* item = his_trade->GetItem(TradeSlots(i)))
324 {
325 if (!item->CanBeTraded(false, true))
326 {
328 SendTradeStatus(info);
329 return;
330 }
331 //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)
332 //{
333 // SendTradeStatus(TRADE_STATUS_NOT_ELIGIBLE);
334 // his_trade->SetAccepted(false, true);
335 // return;
336 //}
337 }
338 }
339
340 if (his_trade->IsAccepted())
341 {
342 setAcceptTradeMode(my_trade, his_trade, myItems, hisItems);
343
344 Spell* my_spell = nullptr;
345 SpellCastTargets my_targets;
346
347 Spell* his_spell = nullptr;
348 SpellCastTargets his_targets;
349
350 // not accept if spell can't be casted now (cheating)
351 if (uint32 my_spell_id = my_trade->GetSpell())
352 {
353 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(my_spell_id);
354 Item* castItem = my_trade->GetSpellCastItem();
355
356 if (!spellInfo || !his_trade->GetItem(TRADE_SLOT_NONTRADED) ||
357 (my_trade->HasSpellCastItem() && !castItem))
358 {
359 clearAcceptTradeMode(my_trade, his_trade);
360 clearAcceptTradeMode(myItems, hisItems);
361
362 my_trade->SetSpell(0);
363 return;
364 }
365
366 my_spell = new Spell(_player, spellInfo, TRIGGERED_FULL_MASK);
367 my_spell->m_CastItem = castItem;
368 my_targets.SetTradeItemTarget(_player);
369 my_spell->m_targets = my_targets;
370
371 SpellCastResult res = my_spell->CheckCast(true);
372 if (res != SPELL_CAST_OK)
373 {
374 my_spell->SendCastResult(res);
375
376 clearAcceptTradeMode(my_trade, his_trade);
377 clearAcceptTradeMode(myItems, hisItems);
378
379 delete my_spell;
380 my_trade->SetSpell(0);
381 return;
382 }
383 }
384
385 // not accept if spell can't be casted now (cheating)
386 if (uint32 his_spell_id = his_trade->GetSpell())
387 {
388 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(his_spell_id);
389 Item* castItem = his_trade->GetSpellCastItem();
390
391 if (!spellInfo || !my_trade->GetItem(TRADE_SLOT_NONTRADED) || (his_trade->HasSpellCastItem() && !castItem))
392 {
393 delete my_spell;
394 his_trade->SetSpell(0);
395
396 clearAcceptTradeMode(my_trade, his_trade);
397 clearAcceptTradeMode(myItems, hisItems);
398 return;
399 }
400
401 his_spell = new Spell(trader, spellInfo, TRIGGERED_FULL_MASK);
402 his_spell->m_CastItem = castItem;
403 his_targets.SetTradeItemTarget(trader);
404 his_spell->m_targets = his_targets;
405
406 SpellCastResult res = his_spell->CheckCast(true);
407 if (res != SPELL_CAST_OK)
408 {
409 his_spell->SendCastResult(res);
410
411 clearAcceptTradeMode(my_trade, his_trade);
412 clearAcceptTradeMode(myItems, hisItems);
413
414 delete my_spell;
415 delete his_spell;
416
417 his_trade->SetSpell(0);
418 return;
419 }
420 }
421
422 // inform partner client
424 trader->GetSession()->SendTradeStatus(info);
425
426 // test if item will fit in each inventory
427 TradeStatusInfo myCanCompleteInfo, hisCanCompleteInfo;
428 hisCanCompleteInfo.Result = trader->CanStoreItems(myItems, TRADE_SLOT_TRADED_COUNT, &hisCanCompleteInfo.ItemLimitedByLimitCategory);
429 myCanCompleteInfo.Result = _player->CanStoreItems(hisItems, TRADE_SLOT_TRADED_COUNT, &myCanCompleteInfo.ItemLimitedByLimitCategory);
430
431 clearAcceptTradeMode(myItems, hisItems);
432
433 // in case of missing space report error
434 if (myCanCompleteInfo.Result != EQUIP_ERR_OK)
435 {
436 clearAcceptTradeMode(my_trade, his_trade);
437
438 myCanCompleteInfo.Status = TRADE_STATUS_CLOSE_WINDOW;
439 trader->GetSession()->SendTradeStatus(myCanCompleteInfo);
440 myCanCompleteInfo.IsTargetResult = true;
441 SendTradeStatus(myCanCompleteInfo);
442 my_trade->SetAccepted(false);
443 his_trade->SetAccepted(false);
444 delete my_spell;
445 delete his_spell;
446 return;
447 }
448 else if (hisCanCompleteInfo.Result != EQUIP_ERR_OK)
449 {
450 clearAcceptTradeMode(my_trade, his_trade);
451
452 hisCanCompleteInfo.Status = TRADE_STATUS_CLOSE_WINDOW;
453 SendTradeStatus(hisCanCompleteInfo);
454 hisCanCompleteInfo.IsTargetResult = true;
455 trader->GetSession()->SendTradeStatus(hisCanCompleteInfo);
456 my_trade->SetAccepted(false);
457 his_trade->SetAccepted(false);
458 delete my_spell;
459 delete his_spell;
460 return;
461 }
462
463 // cache traded item info before moving (pointers become invalid after moveItems if items merge into existing stacks)
464 struct TradedItemInfo
465 {
466 bool present = false;
467 std::string name;
468 uint32 entry = 0;
469 uint32 count = 0;
470 };
471 TradedItemInfo myItemsInfo[TRADE_SLOT_TRADED_COUNT];
472 TradedItemInfo hisItemsInfo[TRADE_SLOT_TRADED_COUNT];
473 std::string myItemsStr, hisItemsStr;
474 for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i)
475 {
476 if (myItems[i])
477 {
478 myItemsInfo[i].present = true;
479 myItemsInfo[i].name = myItems[i]->GetTemplate()->Name1;
480 myItemsInfo[i].entry = myItems[i]->GetEntry();
481 myItemsInfo[i].count = myItems[i]->GetCount();
482 myItemsStr += Acore::StringFormat("{} (Entry:{}) x{}, ", myItemsInfo[i].name, myItemsInfo[i].entry, myItemsInfo[i].count);
483 }
484 if (hisItems[i])
485 {
486 hisItemsInfo[i].present = true;
487 hisItemsInfo[i].name = hisItems[i]->GetTemplate()->Name1;
488 hisItemsInfo[i].entry = hisItems[i]->GetEntry();
489 hisItemsInfo[i].count = hisItems[i]->GetCount();
490 hisItemsStr += Acore::StringFormat("{} (Entry:{}) x{}, ", hisItemsInfo[i].name, hisItemsInfo[i].entry, hisItemsInfo[i].count);
491 }
492 }
493
494 // execute trade: 1. remove
495 for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i)
496 {
497 if (myItems[i])
498 {
500 _player->MoveItemFromInventory(myItems[i]->GetBagSlot(), myItems[i]->GetSlot(), true);
501 }
502 if (hisItems[i])
503 {
504 hisItems[i]->SetGuidValue(ITEM_FIELD_GIFTCREATOR, trader->GetGUID());
505 trader->MoveItemFromInventory(hisItems[i]->GetBagSlot(), hisItems[i]->GetSlot(), true);
506 }
507 }
508
509 bool needsCrossrealmHandling = sToCloud9Sidecar->IsCrossrealm() && _player->GetGUID().GetRealmID() != trader->GetGUID().GetRealmID();
510
511 // Create new items for crossrealm usage.
512 if (needsCrossrealmHandling)
513 {
515 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
516 stmt = CharacterDatabase.GetPreparedStatement(CHAR_NO_OP_PROVIDE_REALM_CONTEXT);
517 stmt->SetData(0, _player->GetGUID().GetRealmID());
518 trans->Append(stmt);
519
520 for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; i++)
521 {
522 if (myItems[i])
523 {
524 Item* newItem = myItems[i]->CloneItem(myItems[i]->GetCount(), trader);
525 if (!newItem)
526 {
527 ItemPosCountVec playerDst;
528 if (_player->CanStoreItem(NULL_BAG, NULL_SLOT, playerDst, myItems[i], false) == EQUIP_ERR_OK)
529 _player->MoveItemToInventory(playerDst, myItems[i], true, true);
530
531 // Should we handle else statement here?
532
533 continue;
534 }
535
536 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE);
537 stmt->SetData(0, myItems[i]->GetGUID().GetCounter());
538 trans->Append(stmt);
539
540 delete myItems[i];
541
542 myItems[i] = newItem;
543 }
544 }
545 CharacterDatabase.CommitTransaction(trans);
546
547 trans = CharacterDatabase.BeginTransaction();
548
549 stmt = CharacterDatabase.GetPreparedStatement(CHAR_NO_OP_PROVIDE_REALM_CONTEXT);
550 stmt->SetData(0, trader->GetGUID().GetRealmID());
551 trans->Append(stmt);
552
553 for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; i++)
554 {
555 if (hisItems[i])
556 {
557 Item* newItem = hisItems[i]->CloneItem(hisItems[i]->GetCount(), _player);
558 if (!newItem)
559 {
560 ItemPosCountVec playerDst;
561 if (trader->CanStoreItem(NULL_BAG, NULL_SLOT, playerDst, hisItems[i], false) == EQUIP_ERR_OK)
562 trader->MoveItemToInventory(playerDst, hisItems[i], true, true);
563
564 // Should we handle else statement here?
565
566 continue;
567 }
568
569 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE);
570 stmt->SetData(0, hisItems[i]->GetGUID().GetCounter());
571 trans->Append(stmt);
572
573 delete hisItems[i];
574
575 hisItems[i] = newItem;
576 }
577 }
578 CharacterDatabase.CommitTransaction(trans);
579
580 }
581
582 // execute trade: 2. store
583 moveItems(myItems, hisItems);
584
585 // logging money
586 if (my_trade->GetMoney() >= 10 * GOLD )
587 {
588 CharacterDatabase.Execute("INSERT INTO log_money VALUES({}, {}, \"{}\", \"{}\", {}, \"{}\", {}, \"goods\", NOW(), {})",
589 GetAccountId(), _player->GetGUID().GetCounter(), _player->GetName(), GetRemoteAddress(), trader->GetSession()->GetAccountId(), trader->GetName(), my_trade->GetMoney(), 6);
590 }
591 if (his_trade->GetMoney() >= 10 * GOLD )
592 {
593 CharacterDatabase.Execute("INSERT INTO log_money VALUES({}, {}, \"{}\", \"{}\", {}, \"{}\", {}, \"goods\", NOW(), {})",
594 trader->GetSession()->GetAccountId(), trader->GetGUID().GetCounter(), trader->GetName(), trader->GetSession()->GetRemoteAddress(), GetAccountId(), _player->GetName(), his_trade->GetMoney(), 6);
595 }
596
597 // update money
598 _player->ModifyMoney(-int32(my_trade->GetMoney()));
599 _player->ModifyMoney(his_trade->GetMoney());
600 trader->ModifyMoney(-int32(his_trade->GetMoney()));
601 trader->ModifyMoney(my_trade->GetMoney());
602
604 {
605 for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i)
606 {
607 if (myItemsInfo[i].present)
608 LOG_GM(GetAccountId(), "GM {} (Account: {}) traded item: {} (Entry: {} Count: {}) to {}",
610 myItemsInfo[i].name, myItemsInfo[i].entry, myItemsInfo[i].count,
611 trader->GetName());
612 }
613 if (my_trade->GetMoney() > 0)
614 LOG_GM(GetAccountId(), "GM {} (Account: {}) traded money: {} to {}",
615 _player->GetName(), GetAccountId(), my_trade->GetMoney(), trader->GetName());
616 }
618 {
619 for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i)
620 {
621 if (hisItemsInfo[i].present)
622 LOG_GM(trader->GetSession()->GetAccountId(), "GM {} (Account: {}) traded item: {} (Entry: {} Count: {}) to {}",
623 trader->GetName(), trader->GetSession()->GetAccountId(),
624 hisItemsInfo[i].name, hisItemsInfo[i].entry, hisItemsInfo[i].count,
625 _player->GetName());
626 }
627 if (his_trade->GetMoney() > 0)
628 LOG_GM(trader->GetSession()->GetAccountId(), "GM {} (Account: {}) traded money: {} to {}",
629 trader->GetName(), trader->GetSession()->GetAccountId(), his_trade->GetMoney(), _player->GetName());
630 }
631
632 // log completed trade
633 LOG_INFO("entities.player.trade", "Trade: Account: {} (IP: {}), Player [{}] ({}) traded with Player [{}] ({}): gave {} copper, received {} copper, gave item(s) [{}], received item(s) [{}]",
635 trader->GetName(), trader->GetGUID().GetCounter(),
636 my_trade->GetMoney(), his_trade->GetMoney(),
637 myItemsStr, hisItemsStr);
638
639 if (my_spell)
640 my_spell->prepare(&my_targets);
641
642 if (his_spell)
643 his_spell->prepare(&his_targets);
644
645 // cleanup
646 clearAcceptTradeMode(my_trade, his_trade);
647 delete _player->m_trade;
648 _player->m_trade = nullptr;
649 delete trader->m_trade;
650 trader->m_trade = nullptr;
651
652 // We can't use single transaction with different databases.
653 if (needsCrossrealmHandling)
654 {
655 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
657 CharacterDatabase.CommitTransaction(trans);
658
659 trans = CharacterDatabase.BeginTransaction();
660 trader->SaveInventoryAndGoldToDB(trans);
661 CharacterDatabase.CommitTransaction(trans);
662 }
663 else
664 {
665 // desynchronized with the other saves here (SaveInventoryAndGoldToDB() not have own transaction guards)
666 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
668 trader->SaveInventoryAndGoldToDB(trans);
669 CharacterDatabase.CommitTransaction(trans);
670 }
671
673 trader->GetSession()->SendTradeStatus(info);
674 SendTradeStatus(info);
675 }
676 else
677 {
679 trader->GetSession()->SendTradeStatus(info);
680 }
681}
@ CHAR_NO_OP_PROVIDE_REALM_CONTEXT
Definition CharacterDatabase.h:549
@ CHAR_DEL_ITEM_INSTANCE
Definition CharacterDatabase.h:128
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
Definition DatabaseEnvFwd.h:69
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition DatabaseEnv.cpp:21
@ EQUIP_ERR_TOO_MUCH_GOLD
Definition Item.h:123
@ EQUIP_ERR_CANNOT_TRADE_THAT
Definition Item.h:125
@ EQUIP_ERR_OK
Definition Item.h:47
@ EQUIP_ERR_NOT_ENOUGH_MONEY
Definition Item.h:76
@ NULL_BAG
Definition Item.h:40
@ NULL_SLOT
Definition Item.h:41
#define LOG_INFO(filterType__,...)
Definition Log.h:153
#define LOG_GM(accountId__,...)
Definition Log.h:164
#define TRADE_DISTANCE
Definition ObjectDefines.h:29
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:758
#define MAX_MONEY_AMOUNT
Definition Player.h:924
@ TRADE_STATUS_TRADE_COMPLETE
Definition SharedDefines.h:3814
@ TRADE_STATUS_TRADE_ACCEPT
Definition SharedDefines.h:3810
@ TRADE_STATUS_TRADE_CANCELED
Definition SharedDefines.h:3809
@ TRADE_STATUS_TARGET_TO_FAR
Definition SharedDefines.h:3816
@ TRADE_STATUS_CLOSE_WINDOW
Definition SharedDefines.h:3818
@ GOLD
Definition SharedDefines.h:241
SpellCastResult
Definition SharedDefines.h:936
@ SPELL_CAST_OK
Definition SharedDefines.h:1126
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
Definition SpellDefines.h:158
#define sSpellMgr
Definition SpellMgr.h:847
#define sToCloud9Sidecar
Definition TC9Sidecar.h:81
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:194
static void clearAcceptTradeMode(TradeData *myTrade, TradeData *hisTrade)
Definition TradeHandler.cpp:219
@ ITEM_FIELD_GIFTCREATOR
Definition UpdateFields.h:38
Item * CloneItem(uint32 count, Player const *player=nullptr) const
Definition Item.cpp:1128
uint16 GetRealmID() const
Definition ObjectGuid.h:148
void SetGuidValue(uint16 index, ObjectGuid value)
Definition Object.cpp:721
uint32 GetEntry() const
Definition Object.h:123
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition Player.h:1309
void SaveInventoryAndGoldToDB(CharacterDatabaseTransaction trans)
Definition PlayerStorage.cpp:7314
bool ModifyMoney(int32 amount, bool sendError=true)
Definition Player.cpp:11689
TradeData * m_trade
Definition Player.h:2918
InventoryResult CanStoreItems(Item **items, int count, uint32 *itemLimitedByLimitCategory) const
Definition PlayerStorage.cpp:1548
Item * MoveItemToInventory(ItemPosCountVec const &dest, Item *pItem, bool update, bool in_characterInventoryDB=false)
Definition PlayerStorage.cpp:3103
bool HasEnoughMoney(uint32 amount) const
Definition Player.h:1633
void MoveItemFromInventory(uint8 bag, uint8 slot, bool update)
Definition PlayerStorage.cpp:3083
uint32 GetMoney() const
Definition Player.h:1631
Acore::Types::is_default< T > SetData(const uint8 index, T value)
Definition PreparedStatement.h:77
Definition PreparedStatement.h:157
Definition Spell.h:121
void SetTradeItemTarget(Player *caster)
Definition Spell.cpp:376
Definition SpellInfo.h:340
Definition Spell.h:298
SpellCastTargets m_targets
Definition Spell.h:542
SpellCastResult prepare(SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
Definition Spell.cpp:3556
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition Spell.cpp:4809
Item * m_CastItem
Definition Spell.h:536
SpellCastResult CheckCast(bool strict, uint32 *param1=nullptr, uint32 *param2=nullptr)
Definition Spell.cpp:5849
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
void SetAccepted(bool state, bool forTrader=false)
Definition TradeData.cpp:123
Item * GetItem(TradeSlots slot) const
Definition TradeData.cpp:26
bool IsAccepted() const
Definition TradeData.h:58
uint32 GetSpell() const
Definition TradeData.h:49
void moveItems(Item *myItems[], Item *hisItems[])
Definition TradeHandler.cpp:125
std::string const & GetRemoteAddress()
Definition WorldSession.h:512
void SendTradeStatus(TradeStatusInfo const &info)
Definition TradeHandler.cpp:35
std::string StringFormat(FormatStringView fmt, Args &&... args)
Default AC string format function.
Definition StringFormat.h:44
@ RBAC_PERM_LOG_GM_TRADE
Definition RBAC.h:62
std::string Name1
Definition ItemTemplate.h:624
Definition Player.h:1062
bool IsTargetResult
Definition Player.h:1068
TradeStatus Status
Definition Player.h:1065
InventoryResult Result
Definition Player.h:1067
uint32 ItemLimitedByLimitCategory
Definition Player.h:1069

References _player, Player::CanStoreItem(), Player::CanStoreItems(), CHAR_DEL_ITEM_INSTANCE, CHAR_NO_OP_PROVIDE_REALM_CONTEXT, CharacterDatabase, Spell::CheckCast(), clearAcceptTradeMode(), Item::CloneItem(), EQUIP_ERR_CANNOT_TRADE_THAT, EQUIP_ERR_NOT_ENOUGH_MONEY, EQUIP_ERR_OK, EQUIP_ERR_TOO_MUCH_GOLD, GetAccountId(), Item::GetCount(), ObjectGuid::GetCounter(), Object::GetEntry(), Object::GetGUID(), TradeData::GetItem(), Player::GetMoney(), TradeData::GetMoney(), WorldObject::GetName(), ObjectGuid::GetRealmID(), GetRemoteAddress(), Player::GetSession(), TradeData::GetSpell(), TradeData::GetSpellCastItem(), Item::GetTemplate(), TradeData::GetTrader(), GOLD, Player::HasEnoughMoney(), HasPermission(), TradeData::HasSpellCastItem(), TradeData::IsAccepted(), TradeStatusInfo::IsTargetResult, WorldObject::IsWithinDistInMap(), ITEM_FIELD_GIFTCREATOR, TradeStatusInfo::ItemLimitedByLimitCategory, LOG_GM, LOG_INFO, Spell::m_CastItem, Spell::m_targets, Player::m_trade, MAX_MONEY_AMOUNT, Player::ModifyMoney(), Player::MoveItemFromInventory(), moveItems(), Player::MoveItemToInventory(), ItemTemplate::Name1, NULL_BAG, NULL_SLOT, Spell::prepare(), rbac::RBAC_PERM_LOG_GM_TRADE, TradeStatusInfo::Result, Player::SaveInventoryAndGoldToDB(), Spell::SendCastResult(), SendTradeStatus(), TradeData::SetAccepted(), setAcceptTradeMode(), PreparedStatementBase::SetData(), Object::SetGuidValue(), TradeData::SetSpell(), SpellCastTargets::SetTradeItemTarget(), SPELL_CAST_OK, sSpellMgr, TradeStatusInfo::Status, sToCloud9Sidecar, Acore::StringFormat(), TRADE_DISTANCE, TRADE_SLOT_NONTRADED, TRADE_SLOT_TRADED_COUNT, TRADE_STATUS_CLOSE_WINDOW, TRADE_STATUS_TARGET_TO_FAR, 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)
166{
167 ObjectGuid guid;
168 uint32 node_count;
169
170 recvData >> guid >> node_count;
171
173 if (!npc)
174 {
175 LOG_DEBUG("network", "WORLD: HandleActivateTaxiExpressOpcode - Unit ({}) not found or you can't interact with it.", guid.ToString());
177 return;
178 }
179 std::vector<uint32> nodes;
180
181 for (uint32 i = 0; i < node_count; ++i)
182 {
183 uint32 node;
184 recvData >> node;
185
186 if (!GetPlayer()->m_taxi.IsTaximaskNodeKnown(node) && !GetPlayer()->isTaxiCheater())
187 {
189 recvData.rfinish();
190 return;
191 }
192
193 nodes.push_back(node);
194 }
195
196 if (nodes.empty())
197 return;
198
199 LOG_DEBUG("network", "WORLD: Received CMSG_ACTIVATETAXIEXPRESS from {} to {}", nodes.front(), nodes.back());
200
201 GetPlayer()->ActivateTaxiPathTo(nodes, npc, 0);
202}
npc
Definition BattlegroundSA.h:47
@ ERR_TAXINOTVISITED
Definition SharedDefines.h:3857
@ ERR_TAXITOOFARAWAY
Definition SharedDefines.h:3855
@ UNIT_NPC_FLAG_FLIGHTMASTER
Definition UnitDefines.h:335
bool ActivateTaxiPathTo(std::vector< uint32 > const &nodes, Creature *npc=nullptr, uint32 spellid=1)
Definition Player.cpp:10408
void SendActivateTaxiReply(ActivateTaxiReply reply)
Definition TaxiHandler.cpp:300

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)
273{
274 ObjectGuid guid;
275 std::vector<uint32> nodes;
276 nodes.resize(2);
277 GetPlayer()->SetCanTeleport(true);
278 recvData >> guid >> nodes[0] >> nodes[1];
279 LOG_DEBUG("network", "WORLD: Received CMSG_ACTIVATETAXI from {} to {}", nodes[0], nodes[1]);
281 if (!npc)
282 {
283 LOG_DEBUG("network", "WORLD: HandleActivateTaxiOpcode - Unit ({}) not found or you can't interact with it.", guid.ToString());
285 return;
286 }
287
288 if (!GetPlayer()->isTaxiCheater())
289 {
290 if (!GetPlayer()->m_taxi.IsTaximaskNodeKnown(nodes[0]) || !GetPlayer()->m_taxi.IsTaximaskNodeKnown(nodes[1]))
291 {
293 return;
294 }
295 }
296
297 GetPlayer()->ActivateTaxiPathTo(nodes, npc, 0);
298}
void SetCanTeleport(bool value)
Definition Player.h:2547

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)
39{
40 std::string friendName = GetAcoreString(LANG_FRIEND_IGNORE_UNKNOWN);
41 std::string friendNote;
42
43 recv_data >> friendName;
44 recv_data >> friendNote;
45
46 if (!normalizePlayerName(friendName))
47 return;
48
49 ObjectGuid friendGuid = sCharacterCache->GetCharacterGuidByName(friendName);
50 if (!friendGuid)
51 return;
52
53 CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(friendGuid);
54 if (!playerData)
55 return;
56
57 uint32 friendAccountId = playerData->AccountId;
58 TeamId teamId = Player::TeamIdForRace(playerData->Race);
59 FriendsResult friendResult = FRIEND_NOT_FOUND;
60
62 {
63 if (friendGuid)
64 {
65 if (friendGuid == GetPlayer()->GetGUID())
66 friendResult = FRIEND_SELF;
68 friendResult = FRIEND_ENEMY;
69 else if (GetPlayer()->GetSocial()->HasFriend(friendGuid))
70 friendResult = FRIEND_ALREADY;
71 else
72 {
73 Player* pFriend = ObjectAccessor::FindConnectedPlayer(friendGuid);
74 if (pFriend && pFriend->IsVisibleGloballyFor(GetPlayer()) && !pFriend->GetSession()->IsGMAccount())
75 friendResult = FRIEND_ADDED_ONLINE;
76 else
77 friendResult = FRIEND_ADDED_OFFLINE;
78 if (GetPlayer()->GetSocial()->AddToSocialList(friendGuid, SOCIAL_FLAG_FRIEND))
79 GetPlayer()->GetSocial()->SetFriendNote(friendGuid, friendNote);
80 else
81 friendResult = FRIEND_LIST_FULL;
82 }
83 GetPlayer()->GetSocial()->SetFriendNote(friendGuid, friendNote);
84 }
85 }
86
87 sSocialMgr->SendFriendStatus(GetPlayer(), friendResult, friendGuid, false);
88
89 LOG_DEBUG("network", "WORLD: Sent (SMSG_FRIEND_STATUS)");
90}
#define sCharacterCache
Definition CharacterCache.h:88
@ LANG_FRIEND_IGNORE_UNKNOWN
Definition Language.h:80
bool normalizePlayerName(std::string &name)
Definition ObjectMgr.cpp:209
TeamId GetTeamId(PvPTeamId teamId)
Definition SharedDefines.h:3718
TeamId
Definition SharedDefines.h:747
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:46
static bool IsPlayerAccount(uint32 gmlevel)
Definition AccountMgr.cpp:324
static uint32 GetSecurity(uint32 accountId)
Definition AccountMgr.cpp:257
void SetFriendNote(ObjectGuid const &friendGuid, std::string note)
Definition SocialMgr.cpp:106
static TeamId TeamIdForRace(uint8 race)
Definition Player.cpp:6001
bool IsVisibleGloballyFor(Player const *player) const
Definition Player.cpp:11660
PlayerSocial * GetSocial()
Definition Player.h:1158
bool IsGMAccount() const
Definition WorldSession.cpp:220
std::string GetAcoreString(uint32 entry) const
Definition WorldSession.cpp:923
Realm realm
Definition World.cpp:115
Player * FindConnectedPlayer(ObjectGuid const guid)
Definition ObjectAccessor.cpp:281
@ RBAC_PERM_ALLOW_GM_FRIEND
Definition RBAC.h:91
@ RBAC_PERM_TWO_SIDE_ADD_FRIEND
Definition RBAC.h:80
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, ObjectAccessor::FindConnectedPlayer(), FRIEND_ADDED_OFFLINE, FRIEND_ADDED_ONLINE, FRIEND_ALREADY, FRIEND_ENEMY, FRIEND_LIST_FULL, FRIEND_NOT_FOUND, FRIEND_SELF, GetAcoreString(), GetPlayer(), AccountMgr::GetSecurity(), Player::GetSession(), Player::GetSocial(), GetTeamId(), HasPermission(), Realm::Id, IsGMAccount(), AccountMgr::IsPlayerAccount(), Player::IsVisibleGloballyFor(), LANG_FRIEND_IGNORE_UNKNOWN, LOG_DEBUG, normalizePlayerName(), CharacterCacheEntry::Race, rbac::RBAC_PERM_ALLOW_GM_FRIEND, rbac::RBAC_PERM_TWO_SIDE_ADD_FRIEND, realm, RealmHandle::Realm, sCharacterCache, PlayerSocial::SetFriendNote(), SOCIAL_FLAG_FRIEND, sSocialMgr, sWorld, and Player::TeamIdForRace().

Referenced by OpcodeTable::Initialize().

◆ HandleAddIgnoreOpcode()

void WorldSession::HandleAddIgnoreOpcode ( WorldPacket &  recvPacket)
105{
106 std::string ignoreName = GetAcoreString(LANG_FRIEND_IGNORE_UNKNOWN);
107
108 recv_data >> ignoreName;
109
110 if (!normalizePlayerName(ignoreName))
111 return;
112
113 LOG_DEBUG("network", "WORLD: {} asked to Ignore: '{}'", GetPlayer()->GetName(), ignoreName);
114
115 ObjectGuid ignoreGuid = sCharacterCache->GetCharacterGuidByName(ignoreName);
116 if (!ignoreGuid)
117 return;
118
119 FriendsResult ignoreResult;
120
121 if (ignoreGuid == GetPlayer()->GetGUID()) //not add yourself
122 ignoreResult = FRIEND_IGNORE_SELF;
123 else if (GetPlayer()->GetSocial()->HasIgnore(ignoreGuid))
124 ignoreResult = FRIEND_IGNORE_ALREADY;
125 else
126 {
127 ignoreResult = FRIEND_IGNORE_ADDED;
128
129 // ignore list full
130 if (!GetPlayer()->GetSocial()->AddToSocialList(ignoreGuid, SOCIAL_FLAG_IGNORED))
131 ignoreResult = FRIEND_IGNORE_FULL;
132 }
133
134 sSocialMgr->SendFriendStatus(GetPlayer(), ignoreResult, ignoreGuid, false);
135
136 LOG_DEBUG("network", "WORLD: Sent (SMSG_FRIEND_STATUS)");
137}
@ 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)
1528{
1529 LOG_DEBUG("network", "CMSG_ALTER_APPEARANCE");
1530
1531 uint32 Hair, Color, FacialHair, SkinColor;
1532 recvData >> Hair >> Color >> FacialHair >> SkinColor;
1533
1534 BarberShopStyleEntry const* bs_hair = sBarberShopStyleStore.LookupEntry(Hair);
1535
1536 if (!bs_hair || bs_hair->type != 0 || bs_hair->race != _player->getRace() || bs_hair->gender != _player->getGender())
1537 return;
1538
1539 BarberShopStyleEntry const* bs_facialHair = sBarberShopStyleStore.LookupEntry(FacialHair);
1540
1541 if (!bs_facialHair || bs_facialHair->type != 2 || bs_facialHair->race != _player->getRace() || bs_facialHair->gender != _player->getGender())
1542 return;
1543
1544 BarberShopStyleEntry const* bs_skinColor = sBarberShopStyleStore.LookupEntry(SkinColor);
1545
1546 if (bs_skinColor && (bs_skinColor->type != 3 || bs_skinColor->race != _player->getRace() || bs_skinColor->gender != _player->getGender()))
1547 return;
1548
1550 if (!go)
1551 {
1553 data << uint32(2);
1554 SendPacket(&data);
1555 return;
1556 }
1557
1559 {
1561 data << uint32(2);
1562 SendPacket(&data);
1563 return;
1564 }
1565
1566 uint32 cost = _player->GetBarberShopCost(bs_hair->hair_id, Color, bs_facialHair->hair_id, bs_skinColor);
1567
1568 // 0 - ok
1569 // 1, 3 - not enough money
1570 // 2 - you have to seat on barber chair
1571 if (!_player->HasEnoughMoney(cost))
1572 {
1574 data << uint32(1); // no money
1575 SendPacket(&data);
1576 return;
1577 }
1578 else
1579 {
1581 data << uint32(0); // ok
1582 SendPacket(&data);
1583 }
1584
1585 _player->ModifyMoney(-int32(cost)); // it isn't free
1587
1590 _player->SetByteValue(PLAYER_BYTES_2, 0, uint8(bs_facialHair->hair_id));
1591 if (bs_skinColor)
1592 _player->SetByteValue(PLAYER_BYTES, 0, uint8(bs_skinColor->hair_id));
1593
1595
1596 _player->SetStandState(0); // stand up
1597}
@ 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:1596
@ UNIT_STAND_STATE_SIT_LOW_CHAIR
Definition UnitDefines.h:39
@ PLAYER_BYTES_2
Definition UpdateFields.h:182
@ PLAYER_BYTES
Definition UpdateFields.h:181
void SetByteValue(uint16 index, uint8 offset, uint8 value)
Definition Object.cpp:748
uint32 GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair, BarberShopStyleEntry const *newSkin=nullptr)
Definition Player.cpp:13586
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition PlayerUpdates.cpp:2236
uint8 getGender() const
Definition Unit.h:849
uint8 getRace(bool original=false) const
Definition Unit.cpp:16670
uint8 getStandState() const
Definition Unit.h:1783
void SetStandState(uint8 state)
Definition Unit.cpp:12731
GameObject * FindNearestGameObjectOfType(GameobjectTypes type, float range) const
Definition Object.cpp:2576
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
Definition WorldSession.cpp:308
@ 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
struct GameObjectTemplate::@236::@263 barberChair
uint32 chairheight
Definition GameObjectData.h:346

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)
1641{
1642 LOG_DEBUG("network", "WORLD: CMSG_AREA_SPIRIT_HEALER_QUERY");
1643
1645
1646 ObjectGuid guid;
1647 recv_data >> guid;
1648
1649 Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
1650 if (!unit)
1651 return;
1652
1653 if (!unit->IsSpiritService()) // it's not spirit service
1654 return;
1655
1656 if (bg)
1657 sBattlegroundMgr->SendAreaSpiritHealerQueryOpcode(_player, bg, guid);
1658
1659 if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
1660 bf->SendAreaSpiritHealerQueryOpcode(_player, guid);
1661}
#define sBattlefieldMgr
Definition BattlefieldMgr.h:79
#define sBattlegroundMgr
Definition BattlegroundMgr.h:190
Definition Battlefield.h:196
Definition Battleground.h:304
Battleground * GetBattleground(bool create=false) const
Definition Player.cpp:12461
bool IsSpiritService() const
Definition Unit.h:825

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)
1664{
1665 LOG_DEBUG("network", "WORLD: CMSG_AREA_SPIRIT_HEALER_QUEUE");
1666
1668
1669 ObjectGuid guid;
1670 recv_data >> guid;
1671
1672 Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
1673 if (!unit)
1674 return;
1675
1676 if (!unit->IsSpiritService()) // it's not spirit service
1677 return;
1678
1679 if (bg)
1681
1682 if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
1683 bf->AddPlayerToResurrectQueue(guid, _player->GetGUID());
1684}
void AddPlayerToResurrectQueue(ObjectGuid npc_guid, ObjectGuid player_guid)
Definition Battleground.cpp:1417

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)
692{
693 uint32 triggerId;
694 recv_data >> triggerId;
695
696 LOG_DEBUG("network", "CMSG_AREATRIGGER. Trigger ID: {}", triggerId);
697
698 Player* player = GetPlayer();
699 if (player->IsInFlight())
700 {
701 LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player '{}' ({}) in flight, ignore Area Trigger ID:{}",
702 player->GetName(), player->GetGUID().ToString(), triggerId);
703 return;
704 }
705
706 AreaTrigger const* atEntry = sObjectMgr->GetAreaTrigger(triggerId);
707 if (!atEntry)
708 {
709 LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player '{}' ({}) send unknown (by DBC) Area Trigger ID:{}",
710 player->GetName(), player->GetGUID().ToString(), triggerId);
711 return;
712 }
713
714 uint32 teamFaction = player->GetTeamId(true) == TEAM_ALLIANCE ? FACTION_MASK_ALLIANCE : FACTION_MASK_HORDE;
715 bool isTavernAreatrigger = sObjectMgr->IsTavernAreaTrigger(triggerId, teamFaction);
716 if (!player->IsInAreaTriggerRadius(atEntry, isTavernAreatrigger ? 5.f : 0.f))
717 {
718 LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player {} ({}) too far (trigger map: {} player map: {}), ignore Area Trigger ID: {}",
719 player->GetName(), player->GetGUID().ToString(), atEntry->map, player->GetMapId(), triggerId);
720 return;
721 }
722
723 if (player->isDebugAreaTriggers)
725
726 // Skip areatrigger scripts for GMs unless debug areatriggers is enabled
727 if ((!player->IsGameMaster() || player->isDebugAreaTriggers) && sScriptMgr->OnAreaTrigger(player, atEntry))
728 return;
729
730 if (player->IsAlive())
731 if (uint32 questId = sObjectMgr->GetQuestForAreaTrigger(triggerId))
732 if (player->GetQuestStatus(questId) == QUEST_STATUS_INCOMPLETE)
733 player->AreaExploredOrEventHappens(questId);
734
735 if (isTavernAreatrigger)
736 {
737 // set resting flag we are in the inn
738 player->SetRestFlag(REST_FLAG_IN_TAVERN, atEntry->entry);
739
740 if (sWorld->IsFFAPvPRealm())
741 {
743 {
745 sScriptMgr->OnPlayerFfaPvpStateUpdate(player, false);
746
747 }
748 }
749 return;
750 }
751
752 if (Battleground* bg = player->GetBattleground())
753 if (bg->GetStatus() == STATUS_IN_PROGRESS)
754 {
755 bg->HandleAreaTrigger(player, triggerId);
756 return;
757 }
758
759 if (OutdoorPvP* pvp = player->GetOutdoorPvP())
760 if (pvp->HandleAreaTrigger(_player, triggerId))
761 return;
762
763 AreaTriggerTeleport const* at = sObjectMgr->GetAreaTriggerTeleport(triggerId);
764 if (!at)
765 return;
766
767 bool teleported = false;
768 if (player->GetMapId() != at->target_mapId)
769 {
770 if (Map::EnterState denyReason = sMapMgr->PlayerCannotEnter(at->target_mapId, player, false))
771 {
772 bool reviveAtTrigger = false; // should we revive the player if he is trying to enter the correct instance?
773 switch (denyReason)
774 {
780 reviveAtTrigger = true;
781 break;
782 default:
783 break;
784 }
785
786 if (reviveAtTrigger) // check if the player is touching the areatrigger leading to the map his corpse is on
787 {
788 if (!player->IsAlive() && player->HasCorpse())
789 {
790 if (player->GetCorpseLocation().GetMapId() == at->target_mapId)
791 {
792 player->ResurrectPlayer(0.5f);
793 player->SpawnCorpseBones();
794 }
795 }
796 }
797
798 return;
799 }
800
801 if (Group* group = player->GetGroup())
802 if (group->isLFGGroup() && player->GetMap()->IsDungeon())
803 teleported = player->TeleportToEntryPoint();
804 }
805
806 if (!teleported)
808}
@ 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:996
#define sMapMgr
Definition MapMgr.h:220
@ TELE_TO_NOT_LEAVE_TRANSPORT
Definition Player.h:816
@ REST_FLAG_IN_TAVERN
Definition Player.h:808
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:103
#define sScriptMgr
Definition ScriptMgr.h:766
@ TEAM_ALLIANCE
Definition SharedDefines.h:748
@ UNIT_BYTE2_FLAG_FFA_PVP
Definition UnitDefines.h:141
@ UNIT_FIELD_BYTES_2
Definition UpdateFields.h:161
Definition Chat.h:37
void PSendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition Chat.cpp:219
bool IsDungeon() const
Definition Map.h:299
EnterState
Definition Map.h:274
@ CANNOT_ENTER_TOO_MANY_INSTANCES
Definition Map.h:283
@ CANNOT_ENTER_MAX_PLAYERS
Definition Map.h:284
@ CANNOT_ENTER_ZONE_IN_COMBAT
Definition Map.h:285
@ CANNOT_ENTER_INSTANCE_BIND_MISMATCH
Definition Map.h:282
@ CANNOT_ENTER_NOT_IN_RAID
Definition Map.h:280
void RemoveByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition Object.cpp:921
bool HasByteFlag(uint16 index, uint8 offset, uint8 flag) const
Definition Object.cpp:940
Definition OutdoorPvP.h:188
void SetRestFlag(RestFlag restFlag, uint32 triggerId=0)
Definition Player.cpp:16528
TeamId GetTeamId(bool original=false) const
Definition Player.h:2139
void SpawnCorpseBones(bool triggerSave=true)
Definition Player.cpp:4774
bool HasCorpse() const
Definition Player.h:2070
bool TeleportToEntryPoint()
Definition Player.cpp:1648
OutdoorPvP * GetOutdoorPvP() const
Definition Player.cpp:12798
WorldLocation GetCorpseLocation() const
Definition Player.h:2071
bool IsGameMaster() const
Definition Player.h:1178
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0, Unit *target=nullptr, bool newInstance=false)
Definition Player.cpp:1401
void AreaExploredOrEventHappens(uint32 questId)
Definition PlayerQuest.cpp:1865
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition PlayerQuest.cpp:1504
bool isDebugAreaTriggers
Definition Player.h:2611
bool IsInAreaTriggerRadius(AreaTrigger const *trigger, float delta=0.f) const
Definition Player.cpp:2218
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition Player.cpp:4556
bool IsInFlight() const
Definition Unit.h:1712
uint32 GetMapId() const
Definition Position.h:281
Definition ObjectMgr.h:414
float target_Z
Definition ObjectMgr.h:418
float target_X
Definition ObjectMgr.h:416
float target_Orientation
Definition ObjectMgr.h:419
float target_Y
Definition ObjectMgr.h:417
uint32 target_mapId
Definition ObjectMgr.h:415
Definition ObjectMgr.h:423
uint32 entry
Definition ObjectMgr.h:424
uint32 map
Definition ObjectMgr.h:425

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::IsGameMaster(), 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:37
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:582
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:16589
uint32 GetArenaTeamIdInvited()
Definition Player.h:1946
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:1945

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:3742
BattlegroundQueueTypeId
Definition SharedDefines.h:3875
static BattlegroundQueueTypeId BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 arenaType)
Definition BattlegroundMgr.cpp:685
Definition BattlegroundQueue.h:68
bool GetPlayerGroupInfoData(ObjectGuid guid, GroupQueueInfo *ginfo)
Definition BattlegroundQueue.cpp:400
Definition BattlegroundQueue.h:35
uint32 IsInvitedToBGInstanceGUID
Definition BattlegroundQueue.h:45

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:194
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:194
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:5864
@ SMSG_ARENA_TEAM_INVITE
Definition Opcodes.h:878
Player * FindPlayerByName(std::string const &name, bool checkInWorld=true)
Definition ObjectAccessor.cpp:295

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:307
ArenaTeamMember * GetMember(ObjectGuid guid)
Definition ArenaTeam.cpp:1027
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:395
void DelMember(ObjectGuid guid, bool cleanDb)
Definition ArenaTeam.cpp:336
bool IsFighting() const
Definition ArenaTeam.cpp:1012

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:7240

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
41 return;
42 }
43
44 if (!_player->IsValidAttackTarget(pEnemy))
45 {
46 // stop attack state at client
48 return;
49 }
50
54 if (Vehicle* vehicle = _player->GetVehicle())
55 {
56 VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(_player);
57 ASSERT(seat);
59 {
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:665
bool Attack(Unit *victim, bool meleeAttack)
Definition Unit.cpp:7074
bool IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell=nullptr) const
Definition Unit.cpp:10487
void SendMeleeAttackStop(Unit const *victim=nullptr) const
Send to the client SMSG_ATTACKSTOP but doesn't clear UNIT_STATE_MELEE_ATTACKING on server side or int...
Definition Unit.cpp:3267
Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:223
Definition DBCStructure.h:2100
uint32 m_flags
Definition DBCStructure.h:2102

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

Referenced by OpcodeTable::Initialize().

◆ HandleAuctionHelloOpcode()

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

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)
672{
673 ObjectGuid guid; //NPC guid
674 uint32 listfrom; //page of auctions
675 uint32 outbiddedCount; //count of outbidded auctions
676
677 recvData >> guid;
678 recvData >> listfrom; // not used in fact (this list not have page control in client)
679 recvData >> outbiddedCount;
680 if (recvData.size() != (16 + outbiddedCount * 4))
681 {
682 LOG_ERROR("network.opcode", "Client sent bad opcode!!! with count: {} and size : {} (must be: {})", outbiddedCount, (unsigned long)recvData.size(), (16 + outbiddedCount * 4));
683 outbiddedCount = 0;
684 }
685
687 if (!creature)
688 {
689 LOG_DEBUG("network", "WORLD: HandleAuctionListBidderItems - Unit ({}) not found or you can't interact with him.", guid.ToString());
690 recvData.rfinish();
691 return;
692 }
693
694 // Arbitrary cap, can be adjusted if needed
695 if (outbiddedCount > 1000)
696 return;
697
698 // remove fake death
699 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
701
703 if (!ahEntry)
704 return;
705
707
708 // Client sends this list, which I'm honestly not entirely sure why?
709 std::vector<uint32> auctionIds;
710 auctionIds.reserve(outbiddedCount);
711 while (outbiddedCount > 0) // add all data, which client requires
712 {
713 --outbiddedCount;
714 uint32 outbiddedAuctionId;
715 recvData >> outbiddedAuctionId;
716 auctionIds.push_back(outbiddedAuctionId);
717 }
718
719 sAuctionMgr->GetAuctionHouseSearcher()->QueueSearchRequest(new AuctionSearchBidderListRequest(auctionHouseFaction, std::move(auctionIds), GetPlayer()->GetGUID()));
720}
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:472
static AuctionHouseFaction GetAuctionHouseFactionFromHouseId(AuctionHouseId ahHouseId)
Definition AuctionHouseMgr.cpp:458
std::size_t size() const
Definition ByteBuffer.h:444
void rfinish()
Definition ByteBuffer.h:325
uint32 GetFaction() const override
Definition Unit.h:852
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)
750{
751 std::string searchedname;
752 uint8 levelmin, levelmax, usable;
753 uint32 listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality;
754 ObjectGuid guid;
755
756 recvData >> guid;
757 recvData >> listfrom; // start, used for page control listing by 50 elements
758 recvData >> searchedname;
759
760 recvData >> levelmin >> levelmax;
761 recvData >> auctionSlotID >> auctionMainCategory >> auctionSubCategory;
762 recvData >> quality >> usable;
763
764 uint8 getAll;
765 recvData >> getAll;
766
767 // Read sort block
768 uint8 sortOrderCount;
769 recvData >> sortOrderCount;
770
771 if (sortOrderCount > AUCTION_SORT_MAX)
772 return;
773
774 AuctionSortOrderVector sortOrder;
775 for (uint8 i = 0; i < sortOrderCount; i++)
776 {
777 uint8 sortMode;
778 uint8 isDesc;
779 recvData >> sortMode;
780 recvData >> isDesc;
781 AuctionSortInfo sortInfo;
782 sortInfo.isDesc = (isDesc == 1);
783 sortInfo.sortOrder = static_cast<AuctionSortOrder>(sortMode);
784 sortOrder.push_back(std::move(sortInfo));
785 }
786
787 // converting string that we try to find to lower case
788 std::wstring wsearchedname;
789 if (!Utf8toWStr(searchedname, wsearchedname))
790 return;
791
792 wstrToLower(wsearchedname);
793
795 if (!creature)
796 return;
797
798 // remove fake death
801
803 if (!ahEntry)
804 return;
805
807
808 AuctionHouseSearchInfo ahSearchInfo;
809 ahSearchInfo.wsearchedname = wsearchedname;
810 ahSearchInfo.listfrom = listfrom;
811 ahSearchInfo.levelmin = levelmin;
812 ahSearchInfo.levelmax = levelmax;
813 ahSearchInfo.usable = usable;
814 ahSearchInfo.inventoryType = auctionSlotID;
815 ahSearchInfo.itemClass = auctionMainCategory;
816 ahSearchInfo.itemSubClass = auctionSubCategory;
817 ahSearchInfo.quality = quality;
818 ahSearchInfo.getAll = getAll;
819 ahSearchInfo.sorting = std::move(sortOrder);
820
821 AuctionHousePlayerInfo ahPlayerInfo;
822 ahPlayerInfo.playerGuid = GetPlayer()->GetGUID();
823 ahPlayerInfo.faction = GetPlayer()->GetFaction();
825 ahPlayerInfo.locdbc_idx = GetPlayer()->GetSession()->GetSessionDbcLocale();
826 if (usable)
827 {
828 AuctionHouseUsablePlayerInfo usablePlayerInfo;
829 usablePlayerInfo.classMask = GetPlayer()->getClassMask();
830 usablePlayerInfo.raceMask = GetPlayer()->getRaceMask();
831 usablePlayerInfo.level = GetPlayer()->GetLevel();
832
833 SkillStatusMap const& skillMap = GetPlayer()->GetSkillStatusMap();
834 for (auto const& pair : skillMap)
835 usablePlayerInfo.skills.insert(std::make_pair(pair.first, GetPlayer()->GetSkillValue(pair.first)));
836
837 PlayerSpellMap const& spellMap = GetPlayer()->GetSpellMap();
838 for (auto const& pair : spellMap)
839 {
840 if (pair.second->State != PLAYERSPELL_REMOVED && pair.second->IsInSpec(GetPlayer()->GetActiveSpec()))
841 usablePlayerInfo.spells.insert(pair.first);
842 }
843 ahPlayerInfo.usablePlayerInfo = std::move(usablePlayerInfo);
844 }
845
846 sAuctionMgr->GetAuctionHouseSearcher()->QueueSearchRequest(new AuctionSearchListRequest(auctionHouseFaction, std::move(ahSearchInfo), std::move(ahPlayerInfo)));
847}
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:194
std::unordered_map< uint32, SkillStatusData > SkillStatusMap
Definition Player.h:641
@ 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:1799
SkillStatusMap const & GetSkillStatusMap() const
Definition Player.h:1805
uint32 getRaceMask() const
Definition Unit.h:839
bool HasUnitState(const uint32 f) const
Definition Unit.h:737
uint32 getClassMask() const
Definition Unit.h:846
LocaleConstant GetSessionDbcLocale() const
Definition WorldSession.h:646
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)
724{
725 ObjectGuid guid;
726 uint32 listfrom;
727
728 recvData >> guid;
729 recvData >> listfrom; // not used in fact (this list does not have page control in client)
730
732 if (!creature)
733 return;
734
735 // remove fake death
736 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
738
740 if (!ahEntry)
741 return;
742
744
745 sAuctionMgr->GetAuctionHouseSearcher()->QueueSearchRequest(new AuctionSearchOwnerListRequest(auctionHouseFaction, GetPlayer()->GetGUID()));
746}
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)
850{
851 recvData.read_skip<uint64>();
852
853 uint32 count = 0;
854
856 data << uint32(count); // count
857 /*for (uint32 i = 0; i < count; ++i)
858 {
859 data << ""; // string
860 data << ""; // string
861 data << uint32(0);
862 data << uint32(0);
863 data << float(0);
864 }*/
865 SendPacket(&data);
866}
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)
426{
427 ObjectGuid auctioneer;
428 uint32 auctionId;
429 uint32 price;
430 recvData >> auctioneer;
431 recvData >> auctionId >> price;
432
433 if (!auctionId || !price)
434 return; //check for cheaters
435
437 {
439 return;
440 }
441
443 if (!creature)
444 {
445 LOG_DEBUG("network", "WORLD: HandleAuctionPlaceBid - Unit ({}) not found or you can't interact with him.", auctioneer.ToString());
446 return;
447 }
448
449 // remove fake death
450 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
452
453 AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->GetFaction());
454
455 AuctionEntry* auction = auctionHouse->GetAuction(auctionId);
456 Player* player = GetPlayer();
457
458 if (!sScriptMgr->OnPlayerCanPlaceAuctionBid(player, auction))
459 {
461 return;
462 }
463
464 if (!auction)
465 {
466 // auction was cancelled or already bought by someone else
468 return;
469 }
470
471 if (auction->owner == player->GetGUID())
472 {
473 //you cannot bid your own auction:
475 return;
476 }
477
478 // impossible have online own another character (use this for speedup check in case online owner)
479 Player* auction_owner = ObjectAccessor::FindConnectedPlayer(auction->owner);
480 if (!auction_owner && sCharacterCache->GetCharacterAccountIdByGuid(auction->owner) == GetAccountId())
481 {
482 //you cannot bid your another character auction:
484 return;
485 }
486
487 // cheating
488 if (price <= auction->bid || price < auction->startbid)
489 return;
490
491 // price too low for next bid if not buyout
492 if ((price < auction->buyout || auction->buyout == 0) &&
493 price < auction->bid + AuctionEntry::CalculateAuctionOutBid(auction->bid))
494 {
495 //auction has already higher bid, client tests it!
496 return;
497 }
498
499 if (!player->HasEnoughMoney(price))
500 {
501 //you don't have enought money!, client tests!
502 //SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???);
503 return;
504 }
505
506 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
507
508 if (price < auction->buyout || auction->buyout == 0)
509 {
510 if (auction->bidder)
511 {
512 if (auction->bidder == player->GetGUID())
513 player->ModifyMoney(-int32(price - auction->bid));
514 else
515 {
516 // mail to last bidder and return money
517 sAuctionMgr->SendAuctionOutbiddedMail(auction, price, GetPlayer(), trans);
518 player->ModifyMoney(-int32(price));
519 }
520 }
521 else
522 player->ModifyMoney(-int32(price));
523
524 auction->bidder = player->GetGUID();
525 auction->bid = price;
526
527 sAuctionMgr->GetAuctionHouseSearcher()->UpdateBid(auction);
528
530
532 stmt->SetData(0, auction->bidder.GetCounter());
533 stmt->SetData(1, auction->bid);
534 stmt->SetData(2, auction->Id);
535 trans->Append(stmt);
536
538
540 {
541 LOG_GM(GetAccountId(), "GM {} (Account: {}) bid on auction: {} (Item: {} Count: {}) Bid: {}",
542 player->GetName(), GetAccountId(), auction->Id,
543 auction->item_template, auction->itemCount, price);
544 }
545
546 LOG_INFO("entities.player.auctionhouse", "AuctionHouse: Account: {} (IP: {}), Player [{}] (GUID: {}) placed bid on auction #{}: Item (Entry: {}) x{}, Bid: {} copper, Owner: {} (GUID: {})",
547 GetAccountId(), GetRemoteAddress(), player->GetName(), player->GetGUID().GetCounter(),
548 auction->Id, auction->item_template, auction->itemCount, price, auction->owner.GetCounter(), auction->owner.GetCounter());
549 }
550 else
551 {
552 //buyout:
553 if (player->GetGUID() == auction->bidder)
554 player->ModifyMoney(-int32(auction->buyout - auction->bid));
555 else
556 {
557 player->ModifyMoney(-int32(auction->buyout));
558 if (auction->bidder) //buyout for bidded auction ..
559 sAuctionMgr->SendAuctionOutbiddedMail(auction, auction->buyout, GetPlayer(), trans);
560 }
561 auction->bidder = player->GetGUID();
562 auction->bid = auction->buyout;
564
565 //- Mails must be under transaction control too to prevent data loss
566 sAuctionMgr->SendAuctionSalePendingMail(auction, trans);
567 sAuctionMgr->SendAuctionSuccessfulMail(auction, trans);
568 sAuctionMgr->SendAuctionWonMail(auction, trans);
569 sScriptMgr->OnAuctionSuccessful(auctionHouse, auction);
570
572
574 {
575 LOG_GM(GetAccountId(), "GM {} (Account: {}) bought out auction: {} (Item: {} Count: {}) Buyout: {}",
576 player->GetName(), GetAccountId(), auction->Id,
577 auction->item_template, auction->itemCount, auction->buyout);
578 }
579
580 LOG_INFO("entities.player.auctionhouse", "AuctionHouse: Account: {} (IP: {}), Player [{}] (GUID: {}) bought out auction #{}: Item (Entry: {}) x{}, Buyout: {} copper, Owner: {} (GUID: {})",
581 GetAccountId(), GetRemoteAddress(), player->GetName(), player->GetGUID().GetCounter(),
582 auction->Id, auction->item_template, auction->itemCount, auction->buyout, auction->owner.GetCounter(), auction->owner.GetCounter());
583
584 auction->DeleteFromDB(trans);
585
586 sAuctionMgr->RemoveAItem(auction->item_guid);
587 auctionHouse->RemoveAuction(auction);
588 }
589 player->SaveInventoryAndGoldToDB(trans);
590 CharacterDatabase.CommitTransaction(trans);
591}
@ 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
@ ERR_AUCTION_ITEM_NOT_FOUND
Definition AuctionHouseMgr.h:55
@ CHAR_UPD_AUCTION_BID
Definition CharacterDatabase.h:107
@ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID
Definition DBCEnums.h:191
@ CONFIG_TRIAL_RESTRICTION_AUCTION
Definition WorldConfig.h:512
Definition AuctionHouseMgr.h:127
AuctionEntry * GetAuction(uint32 id) const
Definition AuctionHouseMgr.h:145
bool RemoveAuction(AuctionEntry *auction)
Definition AuctionHouseMgr.cpp:504
void SendAuctionCommandResult(uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError=0)
Definition AuctionHouseHandler.cpp:77
Definition AuctionHouseMgr.h:97
uint32 bid
Definition AuctionHouseMgr.h:105
void DeleteFromDB(CharacterDatabaseTransaction trans) const
Definition AuctionHouseMgr.cpp:586
ObjectGuid bidder
Definition AuctionHouseMgr.h:108
ObjectGuid item_guid
Definition AuctionHouseMgr.h:100
uint32 Id
Definition AuctionHouseMgr.h:98
uint32 itemCount
Definition AuctionHouseMgr.h:102
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:580
uint32 buyout
Definition AuctionHouseMgr.h:106
uint32 item_template
Definition AuctionHouseMgr.h:101
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, CONFIG_TRIAL_RESTRICTION_AUCTION, AuctionEntry::DeleteFromDB(), ERR_AUCTION_BID_OWN, ERR_AUCTION_ITEM_NOT_FOUND, ERR_AUCTION_OK, ERR_AUCTION_RESTRICTED_ACCOUNT, ObjectAccessor::FindConnectedPlayer(), GetAccountId(), AuctionHouseObject::GetAuction(), ObjectGuid::GetCounter(), Unit::GetFaction(), Object::GetGUID(), WorldObject::GetName(), Player::GetNPCIfCanInteractWith(), GetPlayer(), GetRemoteAddress(), Player::HasEnoughMoney(), HasPermission(), AuctionEntry::Id, IsTrialAccount(), AuctionEntry::item_guid, AuctionEntry::item_template, AuctionEntry::itemCount, LOG_DEBUG, LOG_GM, LOG_INFO, Player::ModifyMoney(), AuctionEntry::owner, rbac::RBAC_PERM_LOG_GM_TRADE, AuctionHouseObject::RemoveAuction(), Unit::RemoveAurasByType(), sAuctionMgr, Player::SaveInventoryAndGoldToDB(), sCharacterCache, SendAuctionCommandResult(), PreparedStatementBase::SetData(), SPELL_AURA_FEIGN_DEATH, sScriptMgr, sWorld, ObjectGuid::ToString(), UNIT_NPC_FLAG_AUCTIONEER, UNIT_STATE_DIED, and Player::UpdateAchievementCriteria().

Referenced by OpcodeTable::Initialize().

◆ HandleAuctionRemoveItem()

void WorldSession::HandleAuctionRemoveItem ( WorldPacket &  recvData)
595{
596 ObjectGuid auctioneer;
597 uint32 auctionId;
598 recvData >> auctioneer;
599 recvData >> auctionId;
600
602 {
604 return;
605 }
606
608 if (!creature)
609 {
610 LOG_DEBUG("network", "WORLD: HandleAuctionRemoveItem - Unit ({}) not found or you can't interact with him.", auctioneer.ToString());
611 return;
612 }
613
614 // remove fake death
615 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
617
618 AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->GetFaction());
619
620 AuctionEntry* auction = auctionHouse->GetAuction(auctionId);
621 Player* player = GetPlayer();
622
623 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
624 if (auction && auction->owner == player->GetGUID())
625 {
626 Item* pItem = sAuctionMgr->GetAItem(auction->item_guid);
627 if (!pItem)
628 return;
629
630 if (auction->bidder) // If we have a bidder, we have to send him the money he paid
631 {
632 uint32 auctionCut = auction->GetAuctionCut();
633 if (!player->HasEnoughMoney(auctionCut)) //player doesn't have enough money, maybe message needed
634 return;
635 //some auctionBidderNotification would be needed, but don't know that parts..
636 sAuctionMgr->SendAuctionCancelledToBidderMail(auction, trans);
637 player->ModifyMoney(-int32(auctionCut));
638 }
639
640 // item will deleted or added to received mail list
642 .AddItem(pItem)
643 .SendMailTo(trans, player, auction, MAIL_CHECK_MASK_COPIED);
644 }
645 else
646 {
648 //this code isn't possible ... maybe there should be assert
649 LOG_ERROR("network.opcode", "CHEATER : {}, he tried to cancel auction (id: {}) of another player, or auction is nullptr", player->GetGUID().ToString(), auctionId);
650 return;
651 }
652
653 //inform player, that auction is removed
655
656 LOG_INFO("entities.player.auctionhouse", "AuctionHouse: Account: {} (IP: {}), Player [{}] (GUID: {}) cancelled auction #{}: Item (Entry: {}) x{}, Buyout: {} copper",
657 GetAccountId(), GetRemoteAddress(), player->GetName(), player->GetGUID().GetCounter(),
658 auction->Id, auction->item_template, auction->itemCount, auction->buyout);
659
660 // Now remove the auction
661
662 player->SaveInventoryAndGoldToDB(trans);
663 auction->DeleteFromDB(trans);
664 CharacterDatabase.CommitTransaction(trans);
665
666 sAuctionMgr->RemoveAItem(auction->item_guid);
667 auctionHouse->RemoveAuction(auction);
668}
@ 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:187
MailDraft & AddItem(Item *item)
Definition Mail.cpp:95
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:648
std::string BuildAuctionMailSubject(MailAuctionAnswers response) const
Definition AuctionHouseMgr.cpp:641
uint32 deposit
Definition AuctionHouseMgr.h:109
uint32 GetAuctionCut() const
Definition AuctionHouseMgr.cpp:568

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

Referenced by OpcodeTable::Initialize().

◆ HandleAuctionSellItem()

void WorldSession::HandleAuctionSellItem ( WorldPacket &  recvData)
118{
119 ObjectGuid auctioneer;
120 uint32 itemsCount, etime, bid, buyout;
121 recvData >> auctioneer;
122 recvData >> itemsCount;
123
124 ObjectGuid itemGUIDs[MAX_AUCTION_ITEMS]; // 160 slot = 4x 36 slot bag + backpack 16 slot
126 memset(count, 0, sizeof(count));
127
128 if (itemsCount > MAX_AUCTION_ITEMS)
129 {
131 recvData.rfinish();
132 return;
133 }
134
136 {
138 recvData.rfinish();
139 return;
140 }
141
142 for (uint32 i = 0; i < itemsCount; ++i)
143 {
144 recvData >> itemGUIDs[i];
145 recvData >> count[i];
146
147 if (!itemGUIDs[i] || !count[i] || count[i] > 1000)
148 {
149 recvData.rfinish();
150 return;
151 }
152 }
153
154 recvData >> bid;
155 recvData >> buyout;
156 recvData >> etime;
157
158 if (!bid || !etime)
159 return;
160
161 if (bid > MAX_MONEY_AMOUNT || buyout > MAX_MONEY_AMOUNT)
162 {
163 LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Player {} ({}) attempted to sell item with higher price than max gold amount.",
166 return;
167 }
168
170 if (!creature)
171 {
172 LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Unit ({}) not found or you can't interact with him.", auctioneer.ToString());
173 return;
174 }
175
177 if (!auctionHouseEntry)
178 {
179 LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Unit ({}) has wrong faction.", auctioneer.ToString());
180 return;
181 }
182
183 etime *= MINUTE;
184
185 switch (etime)
186 {
187 case 1*MIN_AUCTION_TIME:
188 case 2*MIN_AUCTION_TIME:
189 case 4*MIN_AUCTION_TIME:
190 break;
191 default:
192 return;
193 }
194
195 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
197
198 Item* items[MAX_AUCTION_ITEMS];
199
200 uint32 finalCount = 0;
201 uint32 itemEntry = 0;
202
203 for (uint32 i = 0; i < itemsCount; ++i)
204 {
205 Item* item = _player->GetItemByGuid(itemGUIDs[i]);
206
207 if (!item)
208 {
210 return;
211 }
212
213 if (itemEntry == 0)
214 itemEntry = item->GetTemplate()->ItemId;
215
216 if (sAuctionMgr->GetAItem(item->GetGUID()) || !item->CanBeTraded() || item->IsNotEmptyBag() ||
218 item->GetCount() < count[i] || itemEntry != item->GetTemplate()->ItemId)
219 {
221 return;
222 }
223
224 items[i] = item;
225 finalCount += count[i];
226 }
227
228 if (!finalCount)
229 {
231 return;
232 }
233
234 // check if there are 2 identical guids, in this case user is most likely cheating
235 for (uint32 i = 0; i < itemsCount - 1; ++i)
236 {
237 for (uint32 j = i + 1; j < itemsCount; ++j)
238 {
239 if (itemGUIDs[i] == itemGUIDs[j])
240 {
242 return;
243 }
244 }
245 }
246
247 for (uint32 i = 0; i < itemsCount; ++i)
248 {
249 Item* item = items[i];
250
251 if (item->GetMaxStackCount() < finalCount)
252 {
254 return;
255 }
256 }
257
258 for (uint32 i = 0; i < itemsCount; ++i)
259 {
260 Item* item = items[i];
261
262 uint32 auctionTime = uint32(etime * sWorld->getRate(RATE_AUCTION_TIME));
263 AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->GetFaction());
264
265 uint32 deposit = sAuctionMgr->GetAuctionDeposit(auctionHouseEntry, etime, item, finalCount);
266 if (!_player->HasEnoughMoney(deposit))
267 {
269 return;
270 }
271
272 _player->ModifyMoney(-int32(deposit));
273
274 AuctionEntry* AH = new AuctionEntry;
275 AH->Id = sObjectMgr->GenerateAuctionID();
276
279 else
280 {
281 CreatureData const* auctioneerData = sObjectMgr->GetCreatureData(creature->GetSpawnId());
282 if (!auctioneerData)
283 {
284 LOG_ERROR("network.opcode", "Data for auctioneer not found ({})", auctioneer.ToString());
285 delete AH;
286 return;
287 }
288
289 CreatureTemplate const* auctioneerInfo = sObjectMgr->GetCreatureTemplate(auctioneerData->id);
290 if (!auctioneerInfo)
291 {
292 LOG_ERROR("network.opcode", "Non existing auctioneer ({})", auctioneer.ToString());
293 delete AH;
294 return;
295 }
296
297 AuctionHouseEntry const* AHEntry = sAuctionMgr->GetAuctionHouseEntryFromFactionTemplate(auctioneerInfo->faction);
298 AH->houseId = AuctionHouseId(AHEntry->houseId);
299 }
300
301 // Required stack size of auction matches to current item stack size, just move item to auctionhouse
302 if (itemsCount == 1 && item->GetCount() == count[i])
303 {
304 AH->item_guid = item->GetGUID();
305 AH->item_template = item->GetEntry();
306 AH->itemCount = item->GetCount();
307 AH->owner = _player->GetGUID();
308 AH->startbid = bid;
310 AH->bid = 0;
311 AH->buyout = buyout;
312 AH->expire_time = GameTime::GetGameTime().count() + auctionTime;
313 AH->deposit = deposit;
314 AH->auctionHouseEntry = auctionHouseEntry;
315
316 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 {}",
317 _player->GetName(), _player->GetGUID().ToString(), item->GetTemplate()->Name1, item->GetEntry(), item->GetGUID().ToString(), item->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
318 sAuctionMgr->AddAItem(item);
319 auctionHouse->AddAuction(AH);
320
321 _player->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true);
322
323 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
324 item->DeleteFromInventoryDB(trans);
325 item->SaveToDB(trans);
326 AH->SaveToDB(trans);
328 CharacterDatabase.CommitTransaction(trans);
329
331
333 {
334 LOG_GM(GetAccountId(), "GM {} (Account: {}) created auction: {} (Item: {} Count: {}) Bid: {} Buyout: {}",
335 _player->GetName(), GetAccountId(), AH->Id,
336 item->GetTemplate()->Name1, item->GetCount(), bid, buyout);
337 }
338
340
341 LOG_INFO("entities.player.auctionhouse", "AuctionHouse: Account: {} (IP: {}), Player [{}] (GUID: {}) created auction #{}: Item '{}' (Entry: {}) x{}, StartBid: {} copper, Buyout: {} copper, Deposit: {} copper",
343 item->GetTemplate()->Name1, item->GetEntry(), item->GetCount(), bid, buyout, deposit);
344
345 return;
346 }
347 else // Required stack size of auction does not match to current item stack size, clone item and set correct stack size
348 {
349 Item* newItem = item->CloneItem(finalCount, _player);
350 if (!newItem)
351 {
352 LOG_ERROR("network.opcode", "CMSG_AUCTION_SELL_ITEM: Could not create clone of item {}", item->GetEntry());
354 return;
355 }
356
357 AH->item_guid = newItem->GetGUID();
358 AH->item_template = newItem->GetEntry();
359 AH->itemCount = newItem->GetCount();
360 AH->owner = _player->GetGUID();
361 AH->startbid = bid;
363 AH->bid = 0;
364 AH->buyout = buyout;
365 AH->expire_time = GameTime::GetGameTime().count() + auctionTime;
366 AH->deposit = deposit;
367 AH->auctionHouseEntry = auctionHouseEntry;
368
369 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 {}",
370 _player->GetName(), _player->GetGUID().ToString(), newItem->GetTemplate()->Name1, newItem->GetEntry(), newItem->GetGUID().ToString(), newItem->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
371 sAuctionMgr->AddAItem(newItem);
372 auctionHouse->AddAuction(AH);
373
374 for (uint32 j = 0; j < itemsCount; ++j)
375 {
376 Item* item2 = items[j];
377
378 // Item stack count equals required count, ready to delete item - cloned item will be used for auction
379 if (item2->GetCount() == count[j])
380 {
381 _player->MoveItemFromInventory(item2->GetBagSlot(), item2->GetSlot(), true);
382
383 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
384 item2->DeleteFromInventoryDB(trans);
385 item2->DeleteFromDB(trans);
386 CharacterDatabase.CommitTransaction(trans);
387 delete item2;
388 }
389 else // Item stack count is bigger than required count, update item stack count and save to database - cloned item will be used for auction
390 {
391 item2->SetCount(item2->GetCount() - count[j]);
393 _player->ItemRemovedQuestCheck(item2->GetEntry(), count[j]);
395 }
396 }
397
398 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
399 newItem->SaveToDB(trans);
400 AH->SaveToDB(trans);
402 CharacterDatabase.CommitTransaction(trans);
403
405
407 {
408 LOG_GM(GetAccountId(), "GM {} (Account: {}) created auction: {} (Item: {} Count: {}) Bid: {} Buyout: {}",
409 _player->GetName(), GetAccountId(), AH->Id,
410 newItem->GetTemplate()->Name1, newItem->GetCount(), bid, buyout);
411 }
412
414
415 LOG_INFO("entities.player.auctionhouse", "AuctionHouse: Account: {} (IP: {}), Player [{}] (GUID: {}) created auction #{}: Item '{}' (Entry: {}) x{}, StartBid: {} copper, Buyout: {} copper, Deposit: {} copper",
417 newItem->GetTemplate()->Name1, newItem->GetEntry(), newItem->GetCount(), bid, buyout, deposit);
418
419 return;
420 }
421 }
422}
#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
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:38
@ RATE_AUCTION_TIME
Definition WorldConfig.h:483
void AddAuction(AuctionEntry *auction)
Definition AuctionHouseMgr.cpp:494
ObjectGuid::LowType GetSpawnId() const
Definition Creature.h:69
static void DeleteFromInventoryDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid)
Definition Item.cpp:533
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition Item.cpp:715
virtual void SaveToDB(CharacterDatabaseTransaction trans)
Definition Item.cpp:337
bool CanBeTraded(bool mail=false, bool trade=false) const
Definition Item.cpp:795
void SetCount(uint32 value)
Definition Item.h:273
bool IsNotEmptyBag() const
Definition Item.cpp:312
uint32 GetMaxStackCount() const
Definition Item.h:274
static void DeleteFromDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid)
Definition Item.cpp:519
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:303
void SendUpdateToPlayer(Player *player)
Definition Object.cpp:244
void ItemRemovedQuestCheck(uint32 entry, uint32 count)
Definition PlayerQuest.cpp:1948
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:593
time_t expire_time
Definition AuctionHouseMgr.h:107
uint32 startbid
Definition AuctionHouseMgr.h:104
Definition CreatureData.h:370
uint32 id
Definition CreatureData.h:372
Definition CreatureData.h:187
uint32 faction
Definition CreatureData.h:199
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, CONFIG_TRIAL_RESTRICTION_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, ERR_AUCTION_RESTRICTED_ACCOUNT, AuctionEntry::expire_time, CreatureTemplate::faction, GetAccountId(), AuctionHouseMgr::GetAuctionHouseEntryFromFactionTemplate(), Item::GetBagSlot(), Item::GetCount(), ObjectGuid::GetCounter(), Object::GetEntry(), Unit::GetFaction(), GameTime::GetGameTime(), Object::GetGUID(), AuctionEntry::GetHouseId(), Player::GetItemByGuid(), Item::GetMaxStackCount(), WorldObject::GetName(), Player::GetNPCIfCanInteractWith(), GetPlayer(), GetRemoteAddress(), Item::GetSlot(), Creature::GetSpawnId(), Item::GetTemplate(), Object::GetUInt32Value(), Player::HasEnoughMoney(), ItemTemplate::HasFlag(), HasPermission(), AuctionEntry::houseId, AuctionHouseEntry::houseId, AuctionEntry::Id, CreatureData::id, Item::IsNotEmptyBag(), IsTrialAccount(), ITEM_CHANGED, ITEM_FIELD_DURATION, ITEM_FLAG_CONJURED, AuctionEntry::item_guid, AuctionEntry::item_template, AuctionEntry::itemCount, ItemTemplate::ItemId, Player::ItemRemovedQuestCheck(), LOG_DEBUG, LOG_ERROR, LOG_GM, LOG_INFO, MAX_AUCTION_ITEMS, MAX_MONEY_AMOUNT, MIN_AUCTION_TIME, MINUTE, Player::ModifyMoney(), Player::MoveItemFromInventory(), ItemTemplate::Name1, Neutral, AuctionEntry::owner, RATE_AUCTION_TIME, rbac::RBAC_PERM_LOG_GM_TRADE, 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
uint16 GetPos() const
Definition Item.h:285
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition Player.h:1358
Item * GetItemByPos(uint16 pos) const
Definition PlayerStorage.cpp:445
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition PlayerStorage.cpp:2110
void RemoveItem(uint8 bag, uint8 slot, bool update)
Definition PlayerStorage.cpp:3009
void UpdateTitansGrip()
Definition PlayerUpdates.cpp:1871
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition PlayerStorage.cpp:4131
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:657
bool IsBag() const
Definition Item.h:254
static bool IsEquipmentPos(uint16 pos)
Definition Player.h:1284
InventoryResult CanUnequipItem(uint16 src, bool swap) const
Definition PlayerStorage.cpp:2062
void RemoveItemDependentAurasAndCasts(Item *pItem)
Definition Player.cpp:12895
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition PlayerStorage.cpp:1878
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition PlayerStorage.cpp:4414
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition PlayerStorage.cpp:2690
static bool IsInventoryPos(uint16 pos)
Definition Player.h:1282
uint8 FindEquipSlot(ItemTemplate const *proto, uint32 slot, bool swap) const
Definition PlayerStorage.cpp:129
void AutoUnequipOffhandIfNeed(bool force=false)
Definition Player.cpp:12748
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition PlayerStorage.cpp:2837
static bool IsBankPos(uint16 pos)
Definition Player.h:1287
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:3640
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)
968{
969 //LOG_DEBUG("network.opcode", "WORLD: CMSG_AUTOSTORE_BAG_ITEM");
970 Item* pItem = _player->GetItemByPos(packet.SourceBag, packet.SourceSlot);
971 if (!pItem)
972 return;
973
974 if (!_player->IsValidPos(packet.DestinationBag, NULL_SLOT, false)) // can be autostore pos
975 {
977 return;
978 }
979
980 uint16 src = pItem->GetPos();
981
982 // check unequip potability for equipped items and bank bags
983 if (_player->IsEquipmentPos (src) || _player->IsBagPos (src))
984 {
986 if (msg != EQUIP_ERR_OK)
987 {
988 _player->SendEquipError(msg, pItem, nullptr);
989 return;
990 }
991 }
992
993 ItemPosCountVec dest;
994 InventoryResult msg = _player->CanStoreItem(packet.DestinationBag, NULL_SLOT, dest, pItem, false);
995 if (msg != EQUIP_ERR_OK)
996 {
997 _player->SendEquipError(msg, pItem, nullptr);
998 return;
999 }
1000
1001 // no-op: placed in same slot
1002 if (dest.size() == 1 && dest[0].pos == src)
1003 {
1004 // just remove grey item state
1005 _player->SendEquipError(EQUIP_ERR_NONE, pItem, nullptr);
1006 return;
1007 }
1008
1009 _player->RemoveItem(packet.SourceBag, packet.SourceSlot, true);
1010 _player->StoreItem(dest, pItem, true);
1012}
@ EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT
Definition Item.h:50
static bool IsBagPos(uint16 pos)
Definition PlayerStorage.cpp:594
bool IsValidPos(uint16 pos, bool explicit_pos)
Definition Player.h:1289
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:1909
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 // full CAIS restriction blocks item pickup from every loot source (GO/gather/item/corpse),
44 // not just the creature-corpse window guarded in HandleLootOpcode
46 {
48 return;
49 }
50
51 if (lguid.IsGameObject())
52 {
53 GameObject* go = player->GetMap()->GetGameObject(lguid);
54 // xinef: cheating protection
55 //if (player->GetGroup() && player->GetGroup()->GetLootMethod() == MASTER_LOOT && player->GetGUID() != player->GetGroup()->GetMasterLooterGuid())
56 // go = nullptr;
57
58 // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO
59 if (!go || ((go->GetOwnerGUID() != _player->GetGUID() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player)))
60 {
61 player->SendLootRelease(lguid);
62 return;
63 }
64
65 loot = &go->loot;
66 }
67 else if (lguid.IsItem())
68 {
69 Item* pItem = player->GetItemByGuid(lguid);
70
71 if (!pItem)
72 {
73 player->SendLootRelease(lguid);
74 return;
75 }
76
77 loot = &pItem->loot;
78 }
79 else if (lguid.IsCorpse())
80 {
81 Corpse* bones = ObjectAccessor::GetCorpse(*player, lguid);
82 if (!bones)
83 {
84 player->SendLootRelease(lguid);
85 return;
86 }
87
88 loot = &bones->loot;
89 }
90 else
91 {
92 Creature* creature = GetPlayer()->GetMap()->GetCreature(lguid);
93
94 bool lootAllowed = creature && creature->IsAlive() == (player->IsClass(CLASS_ROGUE, CLASS_CONTEXT_ABILITY) && creature->loot.loot_type == LOOT_PICKPOCKETING);
95 if (!lootAllowed || !creature->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
96 {
97 player->SendLootError(lguid, lootAllowed ? LOOT_ERROR_TOO_FAR : LOOT_ERROR_DIDNT_KILL);
98 return;
99 }
100
101 loot = &creature->loot;
102 }
103
104 sScriptMgr->OnPlayerAfterCreatureLoot(player);
105
106 InventoryResult msg;
107 LootItem* lootItem = player->StoreLootItem(lootSlot, loot, msg);
108 if (msg != EQUIP_ERR_OK && lguid.IsItem() && loot->loot_type != LOOT_CORPSE)
109 {
110 lootItem->is_looted = true;
111 loot->NotifyItemRemoved(lootItem->itemIndex);
112 loot->unlootedCount--;
113
114 player->SendItemRetrievalMail(lootItem->itemid, lootItem->count);
115 }
116
117 // If player is removing the last LootItem, delete the empty container.
118 if (loot->isLooted() && lguid.IsItem())
119 DoLootRelease(lguid);
120}
@ LOOT_ERROR_TOO_FAR
Definition LootMgr.h:97
@ LOOT_ERROR_DIDNT_KILL
Definition LootMgr.h:96
@ LOOT_ERROR_PLAY_TIME_EXCEEDED
Definition LootMgr.h:103
@ LOOT_CORPSE
Definition LootMgr.h:80
void SendItemRetrievalMail(uint32 itemEntry, uint32 count)
Definition PlayerMisc.cpp:432
ObjectGuid GetLootGUID() const
Definition Player.h:2026
void SendLootError(ObjectGuid guid, LootError error)
Definition Player.cpp:8394
LootItem * StoreLootItem(uint8 lootSlot, Loot *loot, InventoryResult &msg)
Definition Player.cpp:13853
void DoLootRelease(ObjectGuid lguid)
Definition LootHandler.cpp:327
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:743

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(), Player::HasPlayerFlag(), 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_PLAY_TIME_EXCEEDED, LOOT_ERROR_TOO_FAR, LOOT_PICKPOCKETING, Loot::loot_type, Loot::NotifyItemRemoved(), PLAYER_FLAGS_NO_PLAY_TIME, 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:186

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)
620{
621 LOG_DEBUG("network", "WORLD: Recvd CMSG_LEAVE_BATTLEFIELD Message");
622
623 recvData.read_skip<uint8>(); // unk1
624 recvData.read_skip<uint8>(); // unk2
625 recvData.read_skip<uint32>(); // BattlegroundTypeId
626 recvData.read_skip<uint16>(); // unk3
627
628 // not allow leave battleground in combat
629 if (_player->IsInCombat())
631 if (bg->GetStatus() != STATUS_WAIT_LEAVE)
632 return;
633
635}
@ STATUS_WAIT_LEAVE
Definition Battleground.h:194
void LeaveBattleground(Battleground *bg=nullptr)
Definition Player.cpp:11500
bool IsInCombat() const
Definition Unit.h:941

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:3735
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
417 // GetCharm() validates the charmed unit still exists and clears a stale reference,
418 // unlike GetCharmGUID(); a despawned vehicle must not permanently block BG entry.
419 if (_player->GetCharm() || _player->IsInCombat())
420 {
422 return;
423 }
424
425 // get BattlegroundQueue for received
426 BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_);
427 BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenaType);
428 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
429
430 if (!sScriptMgr->OnPlayerCanBattleFieldPort(_player, arenaType, bgTypeId, action))
431 return;
432
433 // get group info from queue
434 GroupQueueInfo ginfo;
435 if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
436 {
437 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Player not in queue (No player Group Info)!",
438 GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
439 return;
440 }
441
442 // to accept, player must be invited to particular battleground id
443 if (!ginfo.IsInvitedToBGInstanceGUID && action == 1)
444 {
445 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Player is not invited to any bg!",
446 GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
447 return;
448 }
449
450 Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
451 if (!bg)
452 {
453 if (action)
454 {
455 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Cant find BG with id {}!",
456 GetPlayerInfo(), arenaType, unk2, bgTypeId_, action, ginfo.IsInvitedToBGInstanceGUID);
457 return;
458 }
459
460 bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
461 if (!bg)
462 {
463 LOG_ERROR("network", "BattlegroundHandler: bg_template not found for type id {}.", bgTypeId);
464 return;
465 }
466 }
467
468 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}.",
469 GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
470
471 // expected bracket entry
473 if (!bracketEntry)
474 return;
475
476 // safety checks
477 if (action == 1 && ginfo.ArenaType == 0)
478 {
479 // can't join with deserter, check it here right before joining to be sure
481 {
482 WorldPacket data;
483 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS);
484 SendPacket(&data);
485 action = 0;
486 LOG_DEBUG("bg.battleground", "Player {} {} has a deserter debuff, do not port him to battleground!", _player->GetName(), _player->GetGUID().ToString());
487 }
488
489 if (_player->GetLevel() > bg->GetMaxLevel())
490 {
491 LOG_ERROR("network", "Player {} {} has level ({}) higher than maxlevel ({}) of battleground ({})! Do not port him to battleground!",
493 action = 0;
494 }
495 }
496
497 // get player queue slot index for this bg (can be in up to 2 queues at the same time)
498 uint32 queueSlot = _player->GetBattlegroundQueueIndex(bgQueueTypeId);
499 WorldPacket data;
500
501 if (action) // accept
502 {
503 // check Freeze debuff
504 if (_player->HasAura(9454))
505 return;
506
507 if (!_player->IsInvitedForBattlegroundQueueType(bgQueueTypeId))
508 return; // cheating?
509
510 // set entry point if not in battleground
511 if (!_player->InBattleground())
513
514 // resurrect the player
515 if (!_player->IsAlive())
516 {
519 }
520
521 TeamId teamId = ginfo.teamId;
522
523 // send status packet
524 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType(), teamId);
525 SendPacket(&data);
526
527 // remove battleground queue status from BGmgr
528 bgQueue.RemovePlayer(_player->GetGUID(), false);
529
530 // this is still needed here if battleground "jumping" shouldn't add deserter debuff
531 // also this is required to prevent stuck at old battleground after SetBattlegroundId set to new
532 if (Battleground* currentBg = _player->GetBattleground())
533 currentBg->RemovePlayerAtLeave(_player);
534
535 for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
536 {
537 auto playerBgQueueTypeId = _player->GetBattlegroundQueueTypeId(i);
538 if (playerBgQueueTypeId != BATTLEGROUND_QUEUE_NONE && playerBgQueueTypeId != bgQueueTypeId)
539 {
540 _player->RemoveBattlegroundQueueId(playerBgQueueTypeId);
541 sBattlegroundMgr->GetBattlegroundQueue(playerBgQueueTypeId).RemovePlayer(_player->GetGUID(), true);
542 }
543 }
544
545 // Remove from LFG queues
546 sLFGMgr->LeaveAllLfgQueues(_player->GetGUID(), false);
547
548 _player->SetBattlegroundId(bg->GetInstanceID(), bg->GetBgTypeID(), queueSlot, true, bgTypeId == BATTLEGROUND_RB, teamId);
549
550 if (!sBattlegroundMgr->SendToBattleground(_player, ginfo.IsInvitedToBGInstanceGUID, bgTypeId))
551 {
552 // The teleport never started (instance gone, or a synchronous
553 // TeleportTo veto such as a DK still locked to Ebon Hold). The accept
554 // already pulled the player out of the queue and he can't decline
555 // now, so undo the accept here -- otherwise the invited reservation
556 // leaks forever, permanently skewing team selection and blocking the
557 // empty instance's cleanup.
558 bg->DecreaseInvitedCount(teamId);
559 if (bg->HasFreeSlots())
561 _player->RemoveBattlegroundQueueId(bgQueueTypeId);
563
564 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0, TEAM_NEUTRAL);
565 SendPacket(&data);
566
567 // Free slot -> let the queue refill it. BG only, like the sibling
568 // leave-queue path: an arena update needs its own type/rating.
569 if (!ginfo.ArenaType)
570 sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
571
572 LOG_ERROR("bg.battleground", "Battleground: player {} {} failed to teleport into bg {}, bgtype {}; released the invited reservation.",
574 return;
575 }
576
577 LOG_DEBUG("bg.battleground", "Battleground: player {} {} joined battle for bg {}, bgtype {}, queue type {}.", _player->GetName(), _player->GetGUID().ToString(), bg->GetInstanceID(), bg->GetBgTypeID(), bgQueueTypeId);
578 }
579 else // leave queue
580 {
581 for (auto const& playerGuid : ginfo.Players)
582 {
583 auto player = ObjectAccessor::FindConnectedPlayer(playerGuid);
584 if (!player)
585 continue;
586
587 bgQueue.RemovePlayer(playerGuid, true);
588 player->RemoveBattlegroundQueueId(bgQueueTypeId);
589
590 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0, TEAM_NEUTRAL);
591 player->SendDirectMessage(&data);
592
593 LOG_DEBUG("bg.battleground", "Battleground: player {} {} left queue for bgtype {}, queue type {}.", player->GetName(), playerGuid.ToString(), bg->GetBgTypeID(), bgQueueTypeId);
594 }
595
596 // player left queue, we should update it - do not update Arena Queue
597 if (!ginfo.ArenaType)
598 sBattlegroundMgr->ScheduleQueueUpdate(ginfo.ArenaMatchmakerRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
599
600 // track if player refuses to join the BG after being invited
601 if (bg->isBattleground() && (bg->GetStatus() == STATUS_IN_PROGRESS || bg->GetStatus() == STATUS_WAIT_JOIN))
602 {
604 {
606 stmt->SetData(0, _player->GetGUID().GetCounter());
608 CharacterDatabase.Execute(stmt);
609 }
610
611 sScriptMgr->OnPlayerBattlegroundDesertion(_player, BG_DESERTION_TYPE_LEAVE_QUEUE);
612 }
613
614 if (bg->isArena() && (bg->GetStatus() == STATUS_IN_PROGRESS || bg->GetStatus() == STATUS_WAIT_JOIN))
615 sScriptMgr->OnPlayerBattlegroundDesertion(_player, ARENA_DESERTION_TYPE_LEAVE_QUEUE);
616 }
617}
@ 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:511
PvPDifficultyEntry const * GetBattlegroundBracketByLevel(uint32 mapid, uint32 level)
Definition DBCStores.cpp:805
#define sLFGMgr
Definition LFGMgr.h:665
@ LANG_YOU_IN_COMBAT
Definition Language.h:55
@ ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS
Definition SharedDefines.h:3895
@ BATTLEGROUND_TYPE_NONE
Definition SharedDefines.h:3736
@ BATTLEGROUND_RB
Definition SharedDefines.h:3749
@ BATTLEGROUND_QUEUE_NONE
Definition SharedDefines.h:3876
@ TEAM_NEUTRAL
Definition SharedDefines.h:750
#define PLAYER_MAX_BATTLEGROUND_QUEUES
Definition SharedDefines.h:153
@ CONFIG_BATTLEGROUND_TRACK_DESERTERS
Definition WorldConfig.h:73
void RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
Definition BattlegroundQueue.cpp:261
uint32 GetMapId() const
Definition Battleground.h:442
void DecreaseInvitedCount(TeamId teamId)
Definition Battleground.h:395
uint8 GetArenaType() const
Definition Battleground.h:354
void AddToBGFreeSlotQueue()
Definition Battleground.cpp:1286
uint32 GetInstanceID() const
Definition Battleground.h:332
bool isArena() const
Definition Battleground.h:413
uint32 GetStartTime() const
Definition Battleground.h:335
bool isBattleground() const
Definition Battleground.h:414
BattlegroundStatus GetStatus() const
Definition Battleground.h:333
bool HasFreeSlots() const
Definition Battleground.cpp:1357
uint32 GetMaxLevel() const
Definition Battleground.h:340
BattlegroundTypeId GetBgTypeID(bool GetRandom=false) const
Definition Battleground.h:330
void SendNotification(std::string_view str)
Definition Chat.cpp:113
bool IsInvitedForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
Definition Player.cpp:12501
void SetEntryPoint()
Definition Player.cpp:11463
bool InBattleground() const
Definition Player.h:2299
bool InBattlegroundQueue(bool ignoreArena=false) const
Definition Player.cpp:12476
void SetBattlegroundId(uint32 id, BattlegroundTypeId bgTypeId, uint32 queueSlot, bool invited, bool isRandom, TeamId teamId)
Definition Player.cpp:12577
void RemoveBattlegroundQueueId(BattlegroundQueueTypeId val)
Definition Player.cpp:12539
bool CanJoinToBattleground(Battleground const *bg) const
Definition Player.cpp:11538
uint32 GetBattlegroundQueueIndex(BattlegroundQueueTypeId bgQueueTypeId) const
Definition Player.cpp:12492
BattlegroundQueueTypeId GetBattlegroundQueueTypeId(uint32 index) const
Definition Player.cpp:12487
Unit * GetCharm() const
Definition Unit.cpp:7558
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:5764
TeamId teamId
Definition BattlegroundQueue.h:37
uint8 ArenaType
Definition BattlegroundQueue.h:41
uint32 ArenaMatchmakerRating
Definition BattlegroundQueue.h:47
Definition DBCStructure.h:1467
BattlegroundBracketId GetBracketId() const
Definition DBCStructure.h:1477

References _player, Battleground::AddToBGFreeSlotQueue(), ARENA_DESERTION_TYPE_LEAVE_QUEUE, GroupQueueInfo::ArenaMatchmakerRating, GroupQueueInfo::ArenaType, BATTLEGROUND_QUEUE_NONE, BATTLEGROUND_RB, BATTLEGROUND_TYPE_NONE, BG_DESERTION_TYPE_LEAVE_QUEUE, BattlegroundMgr::BGQueueTypeId(), Player::CanJoinToBattleground(), CHAR_INS_DESERTER_TRACK, CharacterDatabase, CONFIG_BATTLEGROUND_TRACK_DESERTERS, Battleground::DecreaseInvitedCount(), ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS, ObjectAccessor::FindConnectedPlayer(), Battleground::GetArenaType(), Player::GetBattleground(), GetBattlegroundBracketByLevel(), Player::GetBattlegroundQueueIndex(), Player::GetBattlegroundQueueTypeId(), Battleground::GetBgTypeID(), PvPDifficultyEntry::GetBracketId(), Unit::GetCharm(), 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(), Battleground::HasFreeSlots(), 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)
638{
639 // requested at login and on map change
640 // send status for current queues and current bg
641
642 WorldPacket data;
643
644 // for current bg send STATUS_IN_PROGRESS
646 if (bg->GetPlayers().count(_player->GetGUID()))
647 {
648 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player->GetCurrentBattlegroundQueueSlot(), STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), bg->GetArenaType(), _player->GetBgTeamId());
649 SendPacket(&data);
650 }
651
652 // for queued bgs send STATUS_WAIT_JOIN or STATUS_WAIT_QUEUE
653 for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
654 {
655 // check if in queue
657 if (!bgQueueTypeId)
658 continue;
659
660 // get group info from queue
661 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
662 GroupQueueInfo ginfo;
663 if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
664 continue;
665
666 BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(bgQueueTypeId);
667
668 // if invited - send STATUS_WAIT_JOIN
670 {
671 Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
672 if (!bg)
673 continue;
674
675 uint32 remainingTime = (GameTime::GetGameTimeMS().count() < ginfo.RemoveInviteTime ? getMSTimeDiff(GameTime::GetGameTimeMS().count(), ginfo.RemoveInviteTime) : 1);
676 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_WAIT_JOIN, remainingTime, 0, ginfo.ArenaType, TEAM_NEUTRAL, bg->isRated(), ginfo.BgTypeId);
677 SendPacket(&data);
678 }
679 // if not invited - send STATUS_WAIT_QUEUE
680 else
681 {
682 Battleground* bgt = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
683 if (!bgt)
684 continue;
685
686 // expected bracket entry
688 if (!bracketEntry)
689 continue;
690
691 uint32 avgWaitTime = bgQueue.GetAverageQueueWaitTime(&ginfo);
692 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, i, STATUS_WAIT_QUEUE, avgWaitTime, getMSTimeDiff(ginfo.JoinTime, GameTime::GetGameTimeMS().count()), ginfo.ArenaType, TEAM_NEUTRAL, ginfo.IsRated);
693 SendPacket(&data);
694 }
695 }
696}
@ 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:709
uint32 GetAverageQueueWaitTime(GroupQueueInfo *ginfo) const
Definition BattlegroundQueue.cpp:235
bool isRated() const
Definition Battleground.h:415
uint32 GetCurrentBattlegroundQueueSlot() const
Definition Player.h:2304
TeamId GetBgTeamId() const
Definition Player.h:2326
Milliseconds GetGameTimeMS()
Definition GameTime.cpp:43
uint32 JoinTime
Definition BattlegroundQueue.h:43
BattlegroundTypeId BgTypeId
Definition BattlegroundQueue.h:39
uint32 RemoveInviteTime
Definition BattlegroundQueue.h:44
bool IsRated
Definition BattlegroundQueue.h:40

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:749
virtual ObjectGuid GetFlagPickerGUID(TeamId=TEAM_NEUTRAL) const
Definition Battleground.h:570
@ MSG_BATTLEGROUND_PLAYER_POSITIONS
Definition Opcodes.h:775
Player * FindPlayer(ObjectGuid const guid)
Definition ObjectAccessor.cpp:269

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
51 unit->SetHomePosition(unit->GetPosition());
52
53 BattlegroundTypeId bgTypeId = sBattlegroundMgr->GetBattleMasterBG(unit->GetEntry());
54
55 if (!_player->GetBGAccessByLevel(bgTypeId))
56 {
57 // temp, must be gossip message...
59 return;
60 }
61
62 SendBattleGroundList(guid, bgTypeId);
63}
@ LANG_YOUR_BG_LEVEL_REQ_ERROR
Definition Language.h:697
void SetHomePosition(float x, float y, float z, float o)
Definition Creature.h:347
void PauseMovementForInteraction()
Definition Creature.cpp:3156
bool GetBGAccessByLevel(BattlegroundTypeId bgTypeId) const
Definition Player.cpp:12589
bool IsBattleMaster() const
Definition Unit.h:810
void SendBattleGroundList(ObjectGuid guid, BattlegroundTypeId bgTypeId=BATTLEGROUND_RB)
Definition BattleGroundHandler.cpp:65
void GetPosition(float &x, float &y) const
Definition Position.h:126

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

Referenced by OpcodeTable::Initialize().

◆ HandleBattlemasterJoinArena()

void WorldSession::HandleBattlemasterJoinArena ( WorldPacket &  recvData)
699{
700 LOG_DEBUG("network", "WORLD: CMSG_BATTLEMASTER_JOIN_ARENA");
701
702 ObjectGuid guid; // arena Battlemaster guid
703 uint8 arenaslot; // 2v2, 3v3 or 5v5
704 uint8 asGroup; // asGroup
705 uint8 isRated; // isRated
706
707 recvData >> guid >> arenaslot >> asGroup >> isRated;
708
709 // can't queue for rated without a group
710 if (isRated && !asGroup)
711 return;
712
713 // ignore if we already in BG or BG queue
714 if (_player->InBattleground())
715 return;
716
717 // find creature by guid
718 Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
719 if (!unit || !unit->IsBattleMaster())
720 return;
721
722 // get arena type
723 uint8 arenatype = 0;
724 uint32 ateamId = 0;
725 uint32 arenaRating = 0;
726 uint32 matchmakerRating = 0;
727 uint32 previousOpponents = 0;
728
729 switch (arenaslot)
730 {
731 case 0:
732 arenatype = ARENA_TYPE_2v2;
733 break;
734 case 1:
735 arenatype = ARENA_TYPE_3v3;
736 break;
737 case 2:
738 arenatype = ARENA_TYPE_5v5;
739 break;
740 default:
741 LOG_ERROR("network", "Unknown arena slot {} at HandleBattlemasterJoinArena()", arenaslot);
742 return;
743 }
744
745 // get template for all arenas
746 Battleground* bgt = sBattlegroundMgr->GetBattlegroundTemplate(BATTLEGROUND_AA);
747 if (!bgt)
748 {
749 LOG_ERROR("network", "Battleground: template bg (all arenas) not found");
750 return;
751 }
752
753 // arenas disabled
754 if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, BATTLEGROUND_AA, nullptr))
755 {
757 return;
758 }
759
760 BattlegroundTypeId bgTypeId = bgt->GetBgTypeID();
761
762 // expected bracket entry
764 if (!bracketEntry)
765 return;
766
767 // must have free queue slot
768 // pussywizard: allow being queued only in one arena queue, and it even cannot be together with bg queues
770 {
771 WorldPacket data;
772 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_CANNOT_QUEUE_FOR_RATED);
773 SendPacket(&data);
774 return;
775 }
776
777 // queue result (default ok)
779
780 if (!sScriptMgr->OnPlayerCanJoinInArenaQueue(_player, guid, arenaslot, bgTypeId, asGroup, isRated, err) && err <= 0)
781 {
782 WorldPacket data;
783 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
784 SendPacket(&data);
785 return;
786 }
787
788 BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenatype);
789 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
790
791 // check if player can queue:
792 if (!asGroup)
793 {
794 lfg::LfgState lfgState = sLFGMgr->GetState(GetPlayer()->GetGUID());
795 if (GetPlayer()->InBattleground()) // currently in battleground
797 else if (lfgState > lfg::LFG_STATE_NONE && (lfgState != lfg::LFG_STATE_QUEUED || !sWorld->getBoolConfig(CONFIG_ALLOW_JOIN_BG_AND_LFG))) // using lfg system
799 else if (GetPlayer()->HasPlayerFlag(PLAYER_FLAGS_NO_PLAY_TIME)) // Assumed to only apply to full restriction rather than partial
800 err = ERR_GROUP_JOIN_BATTLEGROUND_FAIL; // ERR_ARENA_EXPIRED_CAIS does not seem to be a result, so using this error instead
801
802 if (err <= 0)
803 {
804 WorldPacket data;
805 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
806 SendPacket(&data);
807 return;
808 }
809
810 // check if already in queue
812 //player is already in this queue
813 return;
814
815 // check if has free queue slots
817 return;
818
819 GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bgTypeId, bracketEntry, arenatype, isRated != 0, false, arenaRating, matchmakerRating, ateamId, previousOpponents);
820 uint32 avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo);
821 uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId);
822
823 WorldPacket data;
824 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, arenatype, TEAM_NEUTRAL);
825 SendPacket(&data);
826
827 LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena, skirmish, bg queue type {} bg type {}: {}, NAME {}", bgQueueTypeId, bgTypeId, _player->GetGUID().ToString(), _player->GetName());
828
829 sScriptMgr->OnPlayerJoinArena(_player);
830 }
831 // check if group can queue:
832 else
833 {
834 Group* grp = _player->GetGroup();
835 // no group or not a leader
836 if (!grp || grp->GetLeaderGUID() != _player->GetGUID())
837 return;
838
839 // additional checks for rated arenas
840 if (isRated)
841 {
842 // pussywizard: for rated matches check if season is in progress!
843 if (sArenaSeasonMgr->GetSeasonState() == ARENA_SEASON_STATE_DISABLED)
844 return;
845
846 ateamId = _player->GetArenaTeamId(arenaslot);
847
848 // check team existence
849 ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(ateamId);
850 if (!at)
851 {
852 SendNotInArenaTeamPacket(arenatype);
853 return;
854 }
855
856 // get team rating for queueing
857 arenaRating = at->GetRating();
858 matchmakerRating = at->GetAverageMMR(grp);
859 if (arenaRating <= 0)
860 arenaRating = 1;
861
862 previousOpponents = at->GetPreviousOpponents();
863 }
864
865 err = grp->CanJoinBattlegroundQueue(bgt, bgQueueTypeId, arenatype, arenatype, (bool)isRated, arenaslot);
866
867 // Check queue group members
868 if (err)
869 {
870 grp->DoForAllMembers([&bgQueue, &err](Player* member)
871 {
872 if (bgQueue.IsPlayerInvitedToRatedArena(member->GetGUID()))
874 });
875 }
876
877 uint32 avgWaitTime = 0;
878 if (err > 0)
879 {
880 LOG_DEBUG("bg.battleground", "Battleground: arena join as group start");
881
882 if (isRated)
883 {
884 LOG_DEBUG("bg.battleground", "Battleground: arena team id {}, leader {} queued with matchmaker rating {} for type {}", _player->GetArenaTeamId(arenaslot), _player->GetName(), matchmakerRating, arenatype);
885 bgt->SetRated(true);
886 }
887 else
888 {
889 bgt->SetRated(false);
890 }
891
892 GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, arenatype, isRated != 0, false, arenaRating, matchmakerRating, ateamId, previousOpponents);
893 avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo);
894 }
895
896 WorldPacket data;
897 for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next())
898 {
899 Player* member = itr->GetSource();
900 if (!member)
901 continue;
902
903 if (err <= 0)
904 {
905 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
906 member->SendDirectMessage(&data);
907 continue;
908 }
909
910 uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId);
911
912 // send status packet
913 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, arenatype, TEAM_NEUTRAL, isRated);
914 member->SendDirectMessage(&data);
915
916 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
917 member->SendDirectMessage(&data);
918
919 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());
920
921 sScriptMgr->OnPlayerJoinArena(member);
922 }
923 }
924
925 sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
926}
@ ARENA_SEASON_STATE_DISABLED
Definition ArenaSeasonMgr.h:28
#define sArenaSeasonMgr
Definition ArenaSeasonMgr.h:124
@ ARENA_TYPE_5v5
Definition Battleground.h:211
@ ARENA_TYPE_3v3
Definition Battleground.h:210
@ ARENA_TYPE_2v2
Definition Battleground.h:209
#define sDisableMgr
Definition DisableMgr.h:88
@ DISABLE_TYPE_BATTLEGROUND
Definition DisableMgr.h:31
@ LANG_ARENA_DISABLED
Definition Language.h:730
GroupJoinBattlegroundResult
Definition SharedDefines.h:3891
@ ERR_BATTLEGROUND_JOIN_FAILED
Definition SharedDefines.h:3905
@ ERR_BATTLEGROUND_CANNOT_QUEUE_FOR_RATED
Definition SharedDefines.h:3898
@ ERR_LFG_CANT_USE_BATTLEGROUND
Definition SharedDefines.h:3906
@ ERR_BATTLEGROUND_NOT_IN_BATTLEGROUND
Definition SharedDefines.h:3901
@ ERR_GROUP_JOIN_BATTLEGROUND_FAIL
Definition SharedDefines.h:3893
@ CONFIG_ALLOW_JOIN_BG_AND_LFG
Definition WorldConfig.h:132
uint32 GetPreviousOpponents()
Definition ArenaTeam.h:212
uint32 GetRating() const
Definition ArenaTeam.h:158
uint32 GetAverageMMR(Group *group) const
Definition ArenaTeam.cpp:694
bool IsPlayerInvitedToRatedArena(ObjectGuid pl_guid)
Definition BattlegroundQueue.cpp:387
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:376
Definition GroupReference.h:27
GroupJoinBattlegroundResult CanJoinBattlegroundQueue(Battleground const *bgTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot)
Definition Group.cpp:2142
GroupReference * GetFirstMember()
Definition Group.h:252
void DoForAllMembers(std::function< void(Player *)> const &worker)
Definition Group.cpp:2762
ObjectGuid GetLeaderGUID() const
Definition Group.cpp:2515
bool HasFreeBattlegroundQueueId() const
Definition Player.cpp:12530
uint32 AddBattlegroundQueueId(BattlegroundQueueTypeId val)
Definition Player.cpp:12515
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_JOIN_FAILED, ERR_BATTLEGROUND_NOT_IN_BATTLEGROUND, ERR_GROUP_JOIN_BATTLEGROUND_FAIL, 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_FLAGS_NO_PLAY_TIME, 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)
73{
74 ObjectGuid guid;
75 uint32 bgTypeId_;
76 uint32 instanceId;
77 uint8 joinAsGroup;
78 bool isPremade = false;
79
80 recvData >> guid; // battlemaster guid
81 recvData >> bgTypeId_; // battleground type id (DBC id)
82 recvData >> instanceId; // instance id, 0 if First Available selected
83 recvData >> joinAsGroup; // join as group
84
85 // entry not found
86 if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
87 {
88 LOG_ERROR("network", "Battleground: invalid bgtype ({}) received. possible cheater? player {}", bgTypeId_, _player->GetGUID().ToString());
89 return;
90 }
91
92 // chosen battleground type is disabled
93 if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId_, nullptr))
94 {
96 return;
97 }
98
99 LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from {}", guid.ToString());
100
101 // get queue typeid and random typeid to check if already queued for them
102 BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_);
103 BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, 0);
105
106 // safety check - bgQueueTypeId == BATTLEGROUND_QUEUE_NONE if tried to queue for arena using this function
107 if (bgQueueTypeId == BATTLEGROUND_QUEUE_NONE)
108 return;
109
110 // ignore if player is already in BG
111 if (_player->InBattleground())
112 return;
113
114 // get bg instance or bg template if instance not found
115 Battleground* bg = nullptr;
116 if (instanceId)
117 bg = sBattlegroundMgr->GetBattlegroundThroughClientInstance(instanceId, bgTypeId);
118
119 if (!bg)
120 bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
121
122 if (!bg)
123 return;
124
125 // expected bracket entry
127 if (!bracketEntry)
128 return;
129
130 // must have free queue slot
132 {
133 WorldPacket data;
134 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_TOO_MANY_QUEUES);
135 SendPacket(&data);
136 return;
137 }
138
139 // queue result (default ok)
141
142 if (!sScriptMgr->OnPlayerCanJoinInBattlegroundQueue(_player, guid, bgTypeId, joinAsGroup, err) && err <= 0)
143 {
144 WorldPacket data;
145 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
146 SendPacket(&data);
147 return;
148 }
149
150 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
151
152 // check if player can queue:
153 if (!joinAsGroup)
154 {
155 lfg::LfgState lfgState = sLFGMgr->GetState(GetPlayer()->GetGUID());
156 if (GetPlayer()->InBattleground()) // currently in battleground
157 {
159 }
160 else if (lfgState > lfg::LFG_STATE_NONE && (lfgState != lfg::LFG_STATE_QUEUED || !sWorld->getBoolConfig(CONFIG_ALLOW_JOIN_BG_AND_LFG))) // using lfg system
161 {
163 }
164 else if (!_player->CanJoinToBattleground(bg)) // has deserter debuff
165 {
167 }
168 else if (_player->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeIdRandom)) // queued for random bg, so can't queue for anything else
169 {
170 err = ERR_IN_RANDOM_BG;
171 }
172 else if (_player->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeId)) // queued for this bg
173 {
175 }
176 else if (_player->InBattlegroundQueue() && bgTypeId == BATTLEGROUND_RB) // already in queue, so can't queue for random
177 {
179 }
182 _player->InBattlegroundQueueForBattlegroundQueueType(BATTLEGROUND_QUEUE_5v5)) // can't be already queued for arenas
183 {
185 }
186 // don't let Death Knights join BG queues when they are not allowed to be teleported yet
188 {
190 }
191 else if (!_player->GetBGAccessByLevel(bgTypeId))
192 {
194 }
195 else if (_player->HasPlayerFlag(PLAYER_FLAGS_NO_PLAY_TIME)) // Assumed to only apply to full restriction rather than partial
196 err = ERR_GROUP_JOIN_BATTLEGROUND_FAIL; // ERR_ARENA_EXPIRED_CAIS does not seem to be a result, so using this error instead
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 > 0)
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:262
@ LANG_BG_DISABLED
Definition Language.h:729
@ ERR_IN_NON_RANDOM_BG
Definition SharedDefines.h:3908
@ ERR_BATTLEGROUND_NONE
Definition SharedDefines.h:3894
@ ERR_BATTLEGROUND_TOO_MANY_QUEUES
Definition SharedDefines.h:3897
@ ERR_IN_RANDOM_BG
Definition SharedDefines.h:3907
@ ERR_BATTLEGROUND_QUEUED_FOR_RATED
Definition SharedDefines.h:3899
@ CLASS_DEATH_KNIGHT
Definition SharedDefines.h:131
@ BATTLEGROUND_QUEUE_2v2
Definition SharedDefines.h:3884
@ BATTLEGROUND_QUEUE_5v5
Definition SharedDefines.h:3886
@ BATTLEGROUND_QUEUE_3v3
Definition SharedDefines.h:3885
@ CLASS_CONTEXT_TELEPORT
Definition UnitDefines.h:235
uint32 GetMinPlayersPerTeam() const
Definition Battleground.cpp:248
uint32 GetMaxPlayersPerTeam() const
Definition Battleground.h:350
uint32 GetMembersCount() const
Definition Group.h:254
bool InBattlegroundQueueForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
Definition Player.cpp:12510
bool HasSpell(uint32 spell) const override
Definition Player.cpp:4051

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_GROUP_JOIN_BATTLEGROUND_FAIL, 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::HasPlayerFlag(), 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, PLAYER_FLAGS_NO_PLAY_TIME, 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)
693{
694 TradeData* my_trade = _player->GetTradeData();
695 if (!my_trade)
696 return;
697
698 TradeStatusInfo info;
700 my_trade->GetTrader()->GetSession()->SendTradeStatus(info);
701 SendTradeStatus(info);
702}
@ TRADE_STATUS_OPEN_WINDOW
Definition SharedDefines.h:3808
TradeData * GetTradeData() const
Definition Player.h:1400

References _player, Player::GetSession(), Player::GetTradeData(), TradeData::GetTrader(), SendTradeStatus(), TradeStatusInfo::Status, and TRADE_STATUS_OPEN_WINDOW.

Referenced by OpcodeTable::Initialize().

◆ HandleBfEntryInviteResponse()

void WorldSession::HandleBfEntryInviteResponse ( WorldPacket &  recvData)
106{
107 uint32 battleId;
108 uint8 accepted;
109
110 recvData >> battleId >> accepted;
111
112 Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleId);
113 if (!bf)
114 return;
115
116 if (accepted)
118 else
119 {
120 if (_player->GetZoneId() == bf->GetZoneId())
122 }
123}
uint32 GetZoneId() const
Definition Battlefield.h:234
void KickPlayerFromBattlefield(ObjectGuid guid)
Kick player from battlefield and teleport him to kick-point location.
Definition Battlefield.cpp:333
void PlayerAcceptInviteToWar(Player *player)
Definition Battlefield.cpp:489

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

Referenced by OpcodeTable::Initialize().

◆ HandleBfExitRequest()

void WorldSession::HandleBfExitRequest ( WorldPacket &  recvData)
126{
127 uint32 battleId;
128
129 recvData >> battleId;
130
131 Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleId);
132 if (!bf)
133 return;
134
136}
void AskToLeaveQueue(Player *player)
Definition Battlefield.cpp:473

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

Referenced by OpcodeTable::Initialize().

◆ HandleBfQueueInviteResponse()

void WorldSession::HandleBfQueueInviteResponse ( WorldPacket &  recvData)
90{
91 uint32 battleId;
92 uint8 accepted;
93
94 recvData >> battleId >> accepted;
95
96 Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleId);
97 if (!bf)
98 return;
99
100 if (accepted)
102}
void PlayerAcceptInviteToQueue(Player *player)
Definition Battlefield.cpp:464

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

Referenced by OpcodeTable::Initialize().

◆ HandleBinderActivateOpcode()

void WorldSession::HandleBinderActivateOpcode ( WorldPacket &  recvPacket)
294{
295 ObjectGuid npcGUID;
296 recvData >> npcGUID;
297
298 if (!GetPlayer()->IsInWorld() || !GetPlayer()->IsAlive())
299 return;
300
302 if (!unit)
303 {
304 LOG_DEBUG("network", "WORLD: HandleBinderActivateOpcode - Unit ({}) not found or you can not interact with him.", npcGUID.ToString());
305 return;
306 }
307
308 // remove fake death
309 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
311
312 SendBindPoint(unit);
313}
@ UNIT_NPC_FLAG_INNKEEPER
Definition UnitDefines.h:338
void SendBindPoint(Creature *npc)
Definition NPCHandler.cpp:315

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)
617{
618 uint32 suggestion, contentlen, typelen;
619 std::string content, type;
620
621 recv_data >> suggestion >> contentlen >> content;
622
623 recv_data >> typelen >> type;
624
626
627 stmt->SetData(0, type);
628 stmt->SetData(1, content);
629
630 CharacterDatabase.Execute(stmt);
631}
@ CHAR_INS_BUG_REPORT
Definition CharacterDatabase.h:281

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

Referenced by OpcodeTable::Initialize().

◆ HandleBusyTradeOpcode()

void WorldSession::HandleBusyTradeOpcode ( WorldPacket &  recvPacket)
70{
72}
@ TRADE_STATUS_BUSY
Definition SharedDefines.h:3806
void TradeCancel(bool sendback, TradeStatus status=TRADE_STATUS_TRADE_CANCELED)
Definition PlayerStorage.cpp:4198

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

Referenced by OpcodeTable::Initialize().

◆ HandleBuybackItem()

void WorldSession::HandleBuybackItem ( WorldPackets::Item::BuybackItem &  packet)
749{
751 if (!creature)
752 {
753 LOG_DEBUG("network", "WORLD: HandleBuybackItem - Unit ({}) not found or you can not interact with him.", packet.VendorGuid.ToString());
755 return;
756 }
757
758 // remove fake death
759 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
761
762 Item* pItem = _player->GetItemFromBuyBackSlot(packet.Slot);
763 if (pItem)
764 {
766 if (!_player->HasEnoughMoney(price))
767 {
769 return;
770 }
771
772 ItemPosCountVec dest;
773 InventoryResult msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, pItem, false);
774 if (msg == EQUIP_ERR_OK)
775 {
776 if (sWorld->getBoolConfig(CONFIG_ITEMDELETE_VENDOR))
777 {
779 stmt->SetData(0, _player->GetGUID().GetCounter());
780 stmt->SetData(1, pItem->GetEntry());
781 stmt->SetData(2, pItem->GetCount());
782 CharacterDatabase.Execute(stmt);
783 }
784
785 _player->ModifyMoney(-(int32)price);
786 _player->RemoveItemFromBuyBackSlot(packet.Slot, false);
787 _player->ItemAddedQuestCheck(pItem->GetEntry(), pItem->GetCount());
788 _player->StoreItem(dest, pItem, true);
789 }
790 else
791 _player->SendEquipError(msg, pItem, nullptr);
792 return;
793 }
794 else
796}
@ CHAR_DEL_RECOVERY_ITEM
Definition CharacterDatabase.h:521
@ 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:711
@ UNIT_NPC_FLAG_VENDOR
Definition UnitDefines.h:329
@ 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:4105
void SendSellError(SellResult msg, Creature *creature, ObjectGuid guid, uint32 param)
Definition PlayerStorage.cpp:4186
Item * GetItemFromBuyBackSlot(uint32 slot)
Definition PlayerStorage.cpp:4097
void SendBuyError(BuyResult msg, Creature *creature, uint32 item, uint32 param)
Definition PlayerStorage.cpp:4174
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 BankBagSlotPricesEntry const* slotEntry = sBankBagSlotPricesStore.LookupEntry(slot);
160
161 if (!slotEntry)
162 {
164 SendPacket(packet.Write());
165 return;
166 }
167
168 uint32 price = slotEntry->price;
169
170 if (!_player->HasEnoughMoney(price))
171 {
173 SendPacket(packet.Write());
174 return;
175 }
176
178 _player->ModifyMoney(-int32(price));
179
180 packet.Result = ERR_BANKSLOT_OK;
181 SendPacket(packet.Write());
182
184}
@ ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT
Definition DBCEnums.h:159
DBCStorage< BankBagSlotPricesEntry > sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt)
@ 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:1291
void SetBankBagSlotCount(uint8 count)
Definition Player.h:1292
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, 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)
799{
800 // client expects count starting at 1, and we send vendorslot+1 to client already
801 if (packet.Slot > 0)
802 --packet.Slot;
803 else
804 return; // cheating
805
806 uint8 bag = NULL_BAG; // init for case invalid bagGUID
807
808 // find bag slot by bag guid
809 if (packet.BagGuid == _player->GetGUID())
811 else
812 {
814 {
815 if (Bag* pBag = _player->GetBagByPos(i))
816 {
817 if (packet.BagGuid == pBag->GetGUID())
818 {
819 bag = i;
820 break;
821 }
822 }
823 }
824 }
825
826 // bag not found, cheating?
827 if (bag == NULL_BAG)
828 return;
829
830 GetPlayer()->BuyItemFromVendorSlot(packet.VendorGuid, packet.Slot, packet.Item, packet.Count, bag, packet.BagSlot);
831}
@ INVENTORY_SLOT_BAG_START
Definition Player.h:686
@ INVENTORY_SLOT_BAG_END
Definition Player.h:687
Definition Bag.h:28
Bag * GetBagByPos(uint8 slot) const
Definition PlayerStorage.cpp:461
bool BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot)
Definition Player.cpp:10890
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)
834{
835 // client expects count starting at 1, and we send vendorslot+1 to client already
836 if (packet.Slot > 0)
837 --packet.Slot;
838 else
839 return; // cheating
840
841 GetPlayer()->BuyItemFromVendorSlot(packet.VendorGuid, packet.Slot, packet.Item, packet.Count, NULL_BAG, NULL_SLOT);
842}
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)
608{
609 LOG_DEBUG("network", "WORLD: Recv CMSG_BUY_STABLE_SLOT.");
610 ObjectGuid npcGUID;
611
612 recvData >> npcGUID;
613
614 if (!CheckStableMaster(npcGUID))
615 {
617 return;
618 }
619
620 // remove fake death
621 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
623
624 PetStable& petStable = GetPlayer()->GetOrInitPetStable();
625 if (petStable.MaxStabledPets < MAX_PET_STABLES)
626 {
627 StableSlotPricesEntry const* SlotPrice = sStableSlotPricesStore.LookupEntry(petStable.MaxStabledPets + 1);
628 if (_player->HasEnoughMoney(SlotPrice->Price))
629 {
630 ++petStable.MaxStabledPets;
631 _player->ModifyMoney(-int32(SlotPrice->Price));
633 }
634 else
636 }
637 else
639}
DBCStorage< StableSlotPricesEntry > sStableSlotPricesStore(StableSlotPricesfmt)
@ STABLE_ERR_MONEY
Definition NPCHandler.cpp:40
@ STABLE_SUCCESS_BUY_SLOT
Definition NPCHandler.cpp:44
@ STABLE_ERR_STABLE
Definition NPCHandler.cpp:41
constexpr auto MAX_PET_STABLES
Definition PetDefines.h:37
Definition PetDefines.h:212
uint32 MaxStabledPets
Definition PetDefines.h:237
PetStable & GetOrInitPetStable()
Definition Player.cpp:16045
bool CheckStableMaster(ObjectGuid guid)
Definition PetHandler.cpp:673
void SendStableResult(uint8 guid)
Definition NPCHandler.cpp:418
Definition DBCStructure.h:1939
uint32 Price
Definition DBCStructure.h:1941

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)
236{
237 ObjectGuid guid = _player->GetGUID();
238
239 std::string title;
240 std::string description;
241 uint8 type;
242 uint8 repeatable;
243 uint32 maxInvites;
244 int32 dungeonId;
245 uint32 eventPackedTime;
246 uint32 unkPackedTime;
247 uint32 flags;
248
249 recvData >> title >> description >> type >> repeatable >> maxInvites >> dungeonId;
250 recvData.ReadPackedTime(eventPackedTime);
251 recvData.ReadPackedTime(unkPackedTime);
252 recvData >> flags;
253
254 // prevent attacks with non-utf8 chars -> with multiple packets it will hang up the db due to errors.
255 if (!validUtf8String(recvData, title, "create", guid) || title.size() > 31 || !validUtf8String(recvData, description, "create", guid) || description.size() > 255)
256 return;
257
258 // prevent events in the past
259 // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
260 if (time_t(eventPackedTime) < (GameTime::GetGameTime().count() - time_t(86400L)))
261 {
262 recvData.rfinish();
263 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_PASSED);
264 return;
265 }
266
267 // If the event is a guild event, check if the player is in a guild
269 {
270 if (!_player->GetGuildId())
271 {
272 recvData.rfinish();
273 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD);
274 return;
275 }
276 }
277
278 // Check if the player reached the max number of events allowed to create
280 {
281 if (sCalendarMgr->GetGuildEvents(_player->GetGuildId()).size() >= CALENDAR_MAX_GUILD_EVENTS)
282 {
283 recvData.rfinish();
284 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED);
285 return;
286 }
287 }
288 else
289 {
290 if (sCalendarMgr->GetEventsCreatedBy(guid).size() >= CALENDAR_MAX_EVENTS)
291 {
292 recvData.rfinish();
293 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENTS_EXCEEDED);
294 return;
295 }
296 }
297
299 {
300 recvData.rfinish();
301 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_INTERNAL);
302 return;
303 }
305
306 CalendarEvent* calendarEvent = new CalendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(type), dungeonId,
307 time_t(eventPackedTime), flags, time_t(unkPackedTime), title, description);
308
309 if (calendarEvent->IsGuildEvent() || calendarEvent->IsGuildAnnouncement())
310 if (Player* creator = ObjectAccessor::FindConnectedPlayer(guid))
311 calendarEvent->SetGuildId(creator->GetGuildId());
312
313 if (calendarEvent->IsGuildAnnouncement())
314 {
315 // 946684800 is 01/01/2000 00:00:00 - default response time
316 CalendarInvite* invite = new CalendarInvite(0, calendarEvent->GetEventId(), ObjectGuid::Empty, guid, 946684800, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, "");
317 sCalendarMgr->AddInvite(calendarEvent, invite);
318 }
319 else
320 {
321 uint32 inviteCount;
325
326 memset(status, 0, sizeof(status));
327 memset(rank, 0, sizeof(rank));
328
329 try
330 {
331 recvData >> inviteCount;
332
333 for (uint32 i = 0; i < inviteCount && i < CALENDAR_MAX_INVITES; ++i)
334 {
335 recvData >> invitee[i].ReadAsPacked();
336 recvData >> status[i] >> rank[i];
337 }
338 }
339 catch (ByteBufferException const&)
340 {
341 delete calendarEvent;
342 calendarEvent = nullptr;
343 throw;
344 }
345
347 if (inviteCount > 1)
348 trans = CharacterDatabase.BeginTransaction();
349
350 for (uint32 i = 0; i < inviteCount && i < CALENDAR_MAX_INVITES; ++i)
351 {
352 // 946684800 is 01/01/2000 00:00:00 - default response time
353 CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent->GetEventId(), invitee[i], guid, 946684800, CalendarInviteStatus(status[i]), CalendarModerationRank(rank[i]), "");
354 sCalendarMgr->AddInvite(calendarEvent, invite, trans);
355 }
356
357 if (inviteCount > 1)
358 CharacterDatabase.CommitTransaction(trans);
359 }
360
361 sCalendarMgr->AddEvent(calendarEvent, CALENDAR_SENDTYPE_ADD);
362}
bool validUtf8String(WorldPacket &recvData, std::string &s, std::string action, ObjectGuid playerGUID)
Definition CalendarHandler.cpp:223
#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:1929
time_t GetCalendarEventCreationCooldown() const
Definition WorldSession.h:679
void SetCalendarEventCreationCooldown(time_t cooldown)
Definition WorldSession.h:680
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)
216{
217 LOG_DEBUG("network", "CMSG_CALENDAR_ARENA_TEAM [{}]", _player->GetGUID().ToString());
218
219 if (ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(packet.ArenaTeamId))
220 team->MassInviteToEvent(this);
221}
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)
763{
764 if (sWorld->getBoolConfig(CONFIG_LOGSPAMREPORTS))
765 {
767
768 stmt->SetData(0, 2); // SpamType 2 = Calendar
769 stmt->SetData(1, packet.ComplainGuid.GetCounter());
770 stmt->SetData(2, 0);
771 stmt->SetData(3, 0);
772 stmt->SetData(4, 0);
773 stmt->SetData(5, 0);
774 stmt->SetData(6, "EventId: " + std::to_string(packet.EventId));
775 stmt->SetData(7, GameTime::GetGameTime().count());
776
777 CharacterDatabase.Execute(stmt);
778 }
779}
@ CHAR_INS_SPAM_REPORT
Definition CharacterDatabase.h:282
@ CONFIG_LOGSPAMREPORTS
Definition WorldConfig.h:114
ObjectGuid ComplainGuid
Definition CalendarPackets.h:68
uint64 EventId
Definition CalendarPackets.h:67

References CHAR_INS_SPAM_REPORT, CharacterDatabase, WorldPackets::Calendar::CalendarComplain::ComplainGuid, CONFIG_LOGSPAMREPORTS, WorldPackets::Calendar::CalendarComplain::EventId, ObjectGuid::GetCounter(), GameTime::GetGameTime(), PreparedStatementBase::SetData(), and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarCopyEvent()

void WorldSession::HandleCalendarCopyEvent ( WorldPacket &  recvData)
433{
434 ObjectGuid guid = _player->GetGUID();
435 uint64 eventId;
436 uint64 inviteId;
437 uint32 eventTime;
438
439 recvData >> eventId >> inviteId;
440 recvData.ReadPackedTime(eventTime);
441 LOG_DEBUG("network", "CMSG_CALENDAR_COPY_EVENT [{}], EventId [{}] inviteId [{}] Time: {}", guid.ToString(), eventId, inviteId, eventTime);
442
443 // prevent events in the past
444 // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
445 if (time_t(eventTime) < (GameTime::GetGameTime().count() - time_t(86400L)))
446 {
447 recvData.rfinish();
448 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_PASSED);
449 return;
450 }
451
452 if (CalendarEvent* oldEvent = sCalendarMgr->GetEvent(eventId))
453 {
454 // Ensure that the player has access to the event
455 if (oldEvent->IsGuildEvent() || oldEvent->IsGuildAnnouncement())
456 {
457 if (oldEvent->GetGuildId() != _player->GetGuildId())
458 {
459 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
460 return;
461 }
462 }
463 else
464 {
465 if (oldEvent->GetCreatorGUID() != guid)
466 {
467 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
468 return;
469 }
470 }
471
472 // Check if the player reached the max number of events allowed to create
473 if (oldEvent->IsGuildEvent() || oldEvent->IsGuildAnnouncement())
474 {
475 if (sCalendarMgr->GetGuildEvents(_player->GetGuildId()).size() >= CALENDAR_MAX_GUILD_EVENTS)
476 {
477 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED);
478 return;
479 }
480 }
481 else
482 {
483 if (sCalendarMgr->GetEventsCreatedBy(guid).size() >= CALENDAR_MAX_EVENTS)
484 {
485 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENTS_EXCEEDED);
486 return;
487 }
488 }
489
491 {
492 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_INTERNAL);
493 return;
494 }
496
497 CalendarEvent* newEvent = new CalendarEvent(*oldEvent, sCalendarMgr->GetFreeEventId());
498 newEvent->SetEventTime(time_t(eventTime));
499 sCalendarMgr->AddEvent(newEvent, CALENDAR_SENDTYPE_COPY);
500
501 CalendarInviteStore invites = sCalendarMgr->GetEventInvites(eventId);
503 if (invites.size() > 1)
504 trans = CharacterDatabase.BeginTransaction();
505
506 for (CalendarInviteStore::const_iterator itr = invites.begin(); itr != invites.end(); ++itr)
507 sCalendarMgr->AddInvite(newEvent, new CalendarInvite(**itr, sCalendarMgr->GetFreeInviteId(), newEvent->GetEventId()), trans);
508
509 if (invites.size() > 1)
510 CharacterDatabase.CommitTransaction(trans);
511 // should we change owner when somebody makes a copy of event owned by another person?
512 }
513 else
514 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
515}
@ 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)
518{
519 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_INVITE");
520
521 ObjectGuid playerGuid = _player->GetGUID();
522
523 uint64 eventId;
524 uint64 inviteId;
525 std::string name;
526 bool isPreInvite;
527 bool isGuildEvent;
528
529 ObjectGuid inviteeGuid;
530 uint32 inviteeTeamId = TEAM_NEUTRAL;
531 uint32 inviteeGuildId = 0;
532
533 recvData >> eventId >> inviteId >> name >> isPreInvite >> isGuildEvent;
534
535 if (Player* player = ObjectAccessor::FindPlayerByName(name.c_str(), false))
536 {
537 // Invitee is online
538 inviteeGuid = player->GetGUID();
539 inviteeTeamId = player->GetTeamId();
540 inviteeGuildId = player->GetGuildId();
541 }
542 else
543 {
544 // xinef: Get Data From global storage
545 if (ObjectGuid guid = sCharacterCache->GetCharacterGuidByName(name))
546 {
547 if (CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(guid))
548 {
549 inviteeGuid = guid;
550 inviteeTeamId = Player::TeamIdForRace(playerData->Race);
551 inviteeGuildId = playerData->GuildId;
552 }
553 }
554 }
555
556 if (!inviteeGuid)
557 {
558 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_PLAYER_NOT_FOUND);
559 return;
560 }
561
562 if (_player->GetTeamId() != inviteeTeamId && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR))
563 {
564 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NOT_ALLIED);
565 return;
566 }
567
568 // xinef: sync query
569 if (QueryResult result = CharacterDatabase.Query("SELECT flags FROM character_social WHERE guid = {} AND friend = {}", inviteeGuid.GetCounter(), playerGuid.GetCounter()))
570 {
571 Field* fields = result->Fetch();
572 if (fields[0].Get<uint8>() & SOCIAL_FLAG_IGNORED)
573 {
574 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_IGNORING_YOU_S, name.c_str());
575 return;
576 }
577 }
578
579 if (!isPreInvite)
580 {
581 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
582 {
583 if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() == inviteeGuildId)
584 {
585 // we can't invite guild members to guild events
586 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NO_GUILD_INVITES);
587 return;
588 }
589
590 // 946684800 is 01/01/2000 00:00:00 - default response time
591 CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), eventId, inviteeGuid, playerGuid, 946684800, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, "");
592 sCalendarMgr->AddInvite(calendarEvent, invite);
593 }
594 else
595 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_EVENT_INVALID);
596 }
597 else
598 {
599 if (isGuildEvent && inviteeGuildId == _player->GetGuildId())
600 {
601 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NO_GUILD_INVITES);
602 return;
603 }
604
605 // 946684800 is 01/01/2000 00:00:00 - default response time
606 CalendarInvite* invite = new CalendarInvite(inviteId, 0, inviteeGuid, playerGuid, 946684800, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, "");
607 sCalendarMgr->SendCalendarEventInvite(*invite);
608 }
609}
@ 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:32
Class used to access individual fields of database query result.
Definition Field.h:99

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)
734{
735 ObjectGuid guid = _player->GetGUID();
736 ObjectGuid invitee;
737 uint64 eventId;
738 uint64 inviteId;
739 uint64 ownerInviteId; // isn't it sender's inviteId?
740 uint8 rank;
741
742 recvData>> invitee.ReadAsPacked();
743 recvData >> eventId >> inviteId >> ownerInviteId >> rank;
744 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_MODERATOR_STATUS [{}] EventId [{}] ownerInviteId [{}], Invitee ([{}] id: [{}], rank {}",
745 guid.ToString(), eventId, ownerInviteId, invitee.ToString(), inviteId, rank);
746
747 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
748 {
749 if (CalendarInvite* invite = sCalendarMgr->GetInvite(inviteId))
750 {
751 invite->SetRank(CalendarModerationRank(rank));
752 sCalendarMgr->UpdateInvite(invite);
753 sCalendarMgr->SendCalendarEventModeratorStatusAlert(*calendarEvent, *invite);
754 }
755 else
756 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); // correct?
757 }
758 else
759 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
760}
@ 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)
674{
675 ObjectGuid guid = _player->GetGUID();
676 ObjectGuid invitee;
677 uint64 eventId;
678 uint64 ownerInviteId; // isn't it sender's inviteId?
679 uint64 inviteId;
680
681 recvData>> invitee.ReadAsPacked();
682 recvData >> inviteId >> ownerInviteId >> eventId;
683
684 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_REMOVE_INVITE [{}] EventId [{}], ownerInviteId [{}], Invitee ([{}] id: [{}])",
685 guid.ToString(), eventId, ownerInviteId, invitee.ToString(), inviteId);
686
687 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
688 {
689 if (calendarEvent->GetCreatorGUID() == invitee)
690 {
691 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_DELETE_CREATOR_FAILED);
692 return;
693 }
694
695 sCalendarMgr->RemoveInvite(inviteId, eventId, guid);
696 }
697 else
698 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE);
699}
@ 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)
638{
639 ObjectGuid guid = _player->GetGUID();
640 uint64 eventId;
641 uint64 inviteId;
642 uint32 status;
643
644 recvData >> eventId >> inviteId >> status;
645 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_RSVP [{}] EventId [{}], InviteId [{}], status {}",
646 guid.ToString(), eventId, inviteId, status);
647
648 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
649 {
650 // i think we still should be able to remove self from locked events
651 if (status != CALENDAR_STATUS_REMOVED && calendarEvent->GetFlags() & CALENDAR_FLAG_INVITES_LOCKED)
652 {
653 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_LOCKED);
654 return;
655 }
656
657 if (CalendarInvite* invite = sCalendarMgr->GetInvite(inviteId))
658 {
659 invite->SetStatus(CalendarInviteStatus(status));
660 invite->SetStatusTime(GameTime::GetGameTime().count());
661
662 sCalendarMgr->UpdateInvite(invite);
663 sCalendarMgr->SendCalendarEventStatus(*calendarEvent, *invite);
664 sCalendarMgr->SendCalendarClearPendingAction(guid);
665 }
666 else
667 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); // correct?
668 }
669 else
670 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
671}
@ 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)
612{
613 ObjectGuid guid = _player->GetGUID();
614 uint64 eventId;
615 bool tentative;
616
617 recvData >> eventId >> tentative;
618 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_SIGNUP [{}] EventId [{}] Tentative {}", guid.ToString(), eventId, tentative);
619
620 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
621 {
622 if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() != _player->GetGuildId())
623 {
624 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD);
625 return;
626 }
627
629 CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), eventId, guid, guid, GameTime::GetGameTime().count(), status, CALENDAR_RANK_PLAYER, "");
630 sCalendarMgr->AddInvite(calendarEvent, invite);
631 sCalendarMgr->SendCalendarClearPendingAction(guid);
632 }
633 else
634 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
635}
@ 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)
702{
703 ObjectGuid guid = _player->GetGUID();
704 ObjectGuid invitee;
705 uint64 eventId;
706 uint64 inviteId;
707 uint64 ownerInviteId; // isn't it sender's inviteId?
708 uint8 status;
709
710 recvData >> invitee.ReadAsPacked();
711 recvData >> eventId >> inviteId >> ownerInviteId >> status;
712 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_STATUS [{}] EventId [{}] ownerInviteId [{}], Invitee ({}) id: [{}], status {}",
713 guid.ToString(), eventId, ownerInviteId, invitee.ToString(), inviteId, status);
714
715 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
716 {
717 if (CalendarInvite* invite = sCalendarMgr->GetInvite(inviteId))
718 {
719 invite->SetStatus((CalendarInviteStatus)status);
720 invite->SetStatusTime(GameTime::GetGameTime().count());
721
722 sCalendarMgr->UpdateInvite(invite);
723 sCalendarMgr->SendCalendarEventStatus(*calendarEvent, *invite);
724 sCalendarMgr->SendCalendarClearPendingAction(invitee);
725 }
726 else
727 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); // correct?
728 }
729 else
730 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
731}

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 uint32 holidayCounter = 0;
158 dataBuffer.clear();
159
160 for (uint32 entry : sGameEventMgr->ModifiedHolidays)
161 {
162 HolidaysEntry const* holiday = sHolidaysStore.LookupEntry(entry);
163
164 if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_GAME_EVENT, sGameEventMgr->GetHolidayEventId(holiday->Id), nullptr))
165 {
166 continue;
167 }
168
169 dataBuffer << uint32(holiday->Id); // m_ID
170 dataBuffer << uint32(holiday->Region); // m_region, might be looping
171 dataBuffer << uint32(holiday->Looping); // m_looping, might be region
172 dataBuffer << uint32(holiday->Priority); // m_priority
173 dataBuffer << uint32(holiday->CalendarFilterType); // m_calendarFilterType
174
175 for (uint8 j = 0; j < MAX_HOLIDAY_DATES; ++j)
176 dataBuffer << uint32(holiday->Date[j]); // 26 * m_date -- WritePackedTime ?
177
178 for (uint8 j = 0; j < MAX_HOLIDAY_DURATIONS; ++j)
179 dataBuffer << uint32(holiday->Duration[j]); // 10 * m_duration
180
181 for (uint8 j = 0; j < MAX_HOLIDAY_FLAGS; ++j)
182 dataBuffer << uint32(holiday->CalendarFlags[j]); // 10 * m_calendarFlags
183
184 dataBuffer << holiday->TextureFilename; // m_textureFilename (holiday name)
185
186 ++holidayCounter;
187 }
188
189 data << uint32(holidayCounter);
190 data.append(dataBuffer);
191
192 SendPacket(&data);
193}
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:1160
#define MAX_HOLIDAY_DURATIONS
Definition DBCStructure.h:1158
#define MAX_HOLIDAY_DATES
Definition DBCStructure.h:1159
@ DISABLE_TYPE_GAME_EVENT
Definition DisableMgr.h:37
#define sGameEventMgr
Definition GameEventMgr.h:204
std::unordered_map< uint32, InstancePlayerBind > BoundInstancesMap
Definition InstanceSaveMgr.h:47
#define sInstanceSaveMgr
Definition InstanceSaveMgr.h:233
std::unordered_map< uint32, time_t > ResetTimeByMapDifficultyMap
Definition InstanceSaveMgr.h:105
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:208
@ CONFIG_INSTANCE_RESET_TIME_HOUR
Definition WorldConfig.h:207
Definition ByteBuffer.h:70
void clear()
Definition ByteBuffer.h:122
Definition InstanceSaveMgr.h:57
time_t GetExtendedResetTime() const
Definition InstanceSaveMgr.h:77
uint32 GetInstanceId() const
Definition InstanceSaveMgr.h:62
uint32 GetMapId() const
Definition InstanceSaveMgr.h:63
Difficulty GetDifficulty() const
Definition InstanceSaveMgr.h:64
time_t GetResetTime() const
Definition InstanceSaveMgr.h:76
PackedGuid WriteAsPacked() const
Definition ObjectGuid.h:325
@ 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:1163
int32 CalendarFilterType
Definition DBCStructure.h:1174
uint32 Duration[MAX_HOLIDAY_DURATIONS]
Definition DBCStructure.h:1165
uint32 Id
Definition DBCStructure.h:1164
char const * TextureFilename
Definition DBCStructure.h:1172
uint32 Priority
Definition DBCStructure.h:1173
uint32 CalendarFlags[MAX_HOLIDAY_FLAGS]
Definition DBCStructure.h:1169
uint32 Region
Definition DBCStructure.h:1167
uint32 Date[MAX_HOLIDAY_DATES]
Definition DBCStructure.h:1166
uint32 Looping
Definition DBCStructure.h:1168
Definition DBCStructure.h:1361
bool IsRaid() const
Definition DBCStructure.h:1390

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)
196{
197 LOG_DEBUG("network", "CMSG_CALENDAR_GET_EVENT. Player [{}] Event [{}]", _player->GetGUID().ToString(), packet.EventId);
198
199 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(packet.EventId))
200 sCalendarMgr->SendCalendarEvent(_player->GetGUID(), *calendarEvent, CALENDAR_SENDTYPE_GET);
201 else
202 sCalendarMgr->SendCalendarCommandResult(_player->GetGUID(), CALENDAR_ERROR_EVENT_INVALID);
203}
@ 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)
782{
783 ObjectGuid guid = _player->GetGUID();
784 uint32 pending = sCalendarMgr->GetPlayerNumPending(guid);
785
786 LOG_DEBUG("network", "CMSG_CALENDAR_GET_NUM_PENDING: [{}] Pending: {}", guid.ToString(), pending);
787
789 data << uint32(pending);
790 SendPacket(&data);
791}
@ 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)
206{
207 LOG_DEBUG("network", "CMSG_CALENDAR_GUILD_FILTER [{}]", _player->GetGUID().ToString());
208
209 if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
210 guild->MassInviteToEvent(this, packet.MinimumLevel, packet.MaximumLevel, packet.MinimumRank);
211
212 LOG_DEBUG("network", "CMSG_CALENDAR_GUILD_FILTER: Min level [{}], Max level [{}], Min rank [{}]", packet.MinimumLevel, packet.MaximumLevel, packet.MinimumRank);
213}
#define sGuildMgr
Definition GuildMgr.h:51
Definition Guild.h:295
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)
422{
423 ObjectGuid guid = _player->GetGUID();
424 uint64 eventId;
425
426 recvData >> eventId;
427 recvData.rfinish(); // Skip flags & invite ID, we don't use them
428
429 sCalendarMgr->RemoveEvent(eventId, guid);
430}

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

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarUpdateEvent()

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

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)
569{
570 uint32 spellId;
571 recvPacket >> spellId;
572
573 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
574 if (!spellInfo)
575 return;
576
577 // not allow remove spells with attr SPELL_ATTR0_NO_AURA_CANCEL
579 {
580 return;
581 }
582
583 // channeled spell case (it currently casted then)
584 if (spellInfo->IsChanneled())
585 {
587 if (curSpell->m_spellInfo->Id == spellId)
589 return;
590 }
591
592 // non channeled case:
593 // don't allow remove non positive spells
594 // don't allow cancelling passive auras (some of them are visible)
595 if (!spellInfo->IsPositive() || spellInfo->IsPassive())
596 {
597 return;
598 }
599
600 // maybe should only remove one buff when there are multiple?
602}
@ SPELL_ATTR0_NO_AURA_CANCEL
Definition SharedDefines.h:401
@ AURA_REMOVE_BY_CANCEL
Definition SpellAuraDefines.h:393
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:558
bool IsPassive() const
Definition SpellInfo.cpp:1143
bool IsChanneled() const
Definition SpellInfo.cpp:1301
bool HasAttribute(SpellAttr0 attribute) const
Definition SpellInfo.h:441
bool IsPositive() const
Definition SpellInfo.cpp:1282
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4730
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition Unit.cpp:3975
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition Unit.h:1581

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)
647{
648 // may be better send SMSG_CANCEL_AUTO_REPEAT?
649 // cancel and prepare for deleting
651}
@ CURRENT_AUTOREPEAT_SPELL
Definition Unit.h:559

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

Referenced by OpcodeTable::Initialize().

◆ HandleCancelCastOpcode()

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

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)
654{
655 uint32 spellID = 0;
656 recvData >> spellID;
657
658 // ignore for remote control state (for player case)
659 Unit* mover = _player->m_mover;
660 if (!mover)
661 {
662 return;
663 }
664
665 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID);
666 if (!spellInfo)
667 {
668 return;
669 }
670
671 // not allow remove spells with attr SPELL_ATTR0_NO_AURA_CANCEL
673 {
674 return;
675 }
676
678 if (!spell || spell->GetSpellInfo()->Id != spellInfo->Id)
679 {
680 return;
681 }
682
684}
SafeUnitPointer m_mover
Definition Player.h:2381
uint32 Id
Definition SpellInfo.h:344
SpellInfo const * GetSpellInfo() const
Definition Spell.h:596

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)
643{
644}

Referenced by OpcodeTable::Initialize().

◆ HandleCancelMountAuraOpcode()

void WorldSession::HandleCancelMountAuraOpcode ( WorldPacket &  recvData)
1476{
1477 LOG_DEBUG("network", "WORLD: CMSG_CANCEL_MOUNT_AURA");
1478
1479 //If player is not mounted, so go out :)
1480 if (!_player->IsMounted()) // not blizz like; no any messages on blizz
1481 {
1483 return;
1484 }
1485
1486 if (_player->IsInFlight()) // not blizz like; no any messages on blizz
1487 {
1489 return;
1490 }
1491
1492 _player->Dismount();
1494}
@ 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:168
void Dismount()
Definition Unit.cpp:10319
bool IsMounted() const
Definition Unit.h:1892

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)
1405{
1406 LOG_DEBUG("network", "WORLD: CMSG_CANCEL_TEMP_ENCHANTMENT");
1407
1408 // apply only to equipped item
1410 return;
1411
1413
1414 if (!item)
1415 return;
1416
1418 return;
1419
1422}
@ TEMP_ENCHANTMENT_SLOT
Definition Item.h:170
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition Item.h:304
void ClearEnchantment(EnchantmentSlot slot)
Definition Item.cpp:961
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)
715{
716 // sended also after LOGOUT COMPLETE
717 if (_player) // needed because STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT
718 _player->TradeCancel(true);
719}

References _player, and Player::TradeCancel().

Referenced by OpcodeTable::Initialize().

◆ HandleCastSpellOpcode()

void WorldSession::HandleCastSpellOpcode ( WorldPacket &  recvPacket)
Todo:
: Preparation for #23204
379{
380 uint32 spellId;
381 uint8 castCount, castFlags;
382
383 if (recvPacket.empty())
384 return;
385
386 recvPacket >> castCount >> spellId >> castFlags;
387 TriggerCastFlags triggerFlag = TRIGGERED_NONE;
388
389 uint32 oldSpellId = spellId;
390
391 LOG_DEBUG("network", "WORLD: got cast spell packet, castCount: {}, spellId: {}, castFlags: {}, data length = {}", castCount, spellId, castFlags, (uint32)recvPacket.size());
392
393 // ignore for remote control state (for player case)
394 Unit* mover = _player->m_mover;
395 if (mover != _player && mover->IsPlayer())
396 {
397 recvPacket.rfinish(); // prevent spam at ignore packet
398 return;
399 }
400
401 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
402
403 if (!spellInfo)
404 {
405 LOG_ERROR("network.opcode", "WORLD: unknown spell id {}", spellId);
406 recvPacket.rfinish(); // prevent spam at ignore packet
407 return;
408 }
409
410 // fail if we are cancelling pending request
411 if (!_player->SpellQueue.empty())
412 {
413 PendingSpellCastRequest& request = _player->SpellQueue.front(); // Peek at the first spell
414 if (request.cancelInProgress)
415 {
416 Spell* spell = new Spell(_player, spellInfo, TRIGGERED_NONE);
417 spell->m_cast_count = castCount;
419 spell->finish(false);
420 recvPacket.rfinish(); // prevent spam at ignore packet
421 return;
422 }
423 }
424
425 // try queue spell if it can't be executed right now
427 {
428 if (_player->CanRequestSpellCast(spellInfo))
429 {
430 WorldPacket packetCopy(recvPacket); // Copy the packet
431 packetCopy.rpos(0); // Reset read position to the start of the buffer.
432 _player->SpellQueue.emplace_back(
433 spellId,
434 spellInfo->GetCategory(),
435 std::move(packetCopy) // Move ownership of copied packet
436 );
437 return;
438 }
439 }
440
441 // client provided targets
442 SpellCastTargets targets;
443 targets.Read(recvPacket, mover);
444 HandleClientCastFlags(recvPacket, castFlags, targets);
445
446 // not have spell in spellbook
447 if (mover->IsPlayer())
448 {
449 // not have spell in spellbook or spell passive and not casted by client
450 if (!(spellInfo->Targets & TARGET_FLAG_GAMEOBJECT_ITEM) && (!mover->ToPlayer()->HasActiveSpell(spellId) || spellInfo->IsPassive()))
451 {
452 bool allow = false;
453
454 // allow casting of unknown spells for special lock cases
455 if (GameObject* go = targets.GetGOTarget())
456 {
457 if (go->GetSpellForLock(mover->ToPlayer()) == spellInfo)
458 {
459 allow = true;
460 }
461 }
462
464 // allow casting of spells triggered by clientside periodic trigger auras
465 /*
466 if (caster->HasAuraTypeWithTriggerSpell(SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT, spellId))
467 {
468 allow = true;
469 triggerFlag = TRIGGERED_FULL_MASK;
470 }
471 */
472
473 if (!allow)
474 return;
475 }
476 }
477 else
478 {
479 // pussywizard: casting player's spells from vehicle when seat allows it
480 // if ANYTHING CHANGES in this function, INFORM ME BEFORE applying!!!
481 if (Vehicle* veh = mover->GetVehicleKit())
482 if (VehicleSeatEntry const* seat = veh->GetSeatForPassenger(_player))
483 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)*/)
484 if ((mover->IsCreature() && !mover->ToCreature()->HasSpell(spellId)) || spellInfo->IsPassive()) // the creature can't cast that spell, check player instead
485 {
486 if (!(spellInfo->Targets & TARGET_FLAG_GAMEOBJECT_ITEM) && (!_player->HasActiveSpell (spellId) || spellInfo->IsPassive()))
487 {
488 //cheater? kick? ban?
489 recvPacket.rfinish(); // prevent spam at ignore packet
490 return;
491 }
492
493 // at this point, player is a valid caster
494 // swapping the mover will stop the check below at IsUnit, so everything works fine
495 mover = _player;
496 }
497
498 // not have spell in spellbook or spell passive and not casted by client
499 if ((mover->IsCreature() && !mover->ToCreature()->HasSpell(spellId)) || spellInfo->IsPassive())
500 {
501 //cheater? kick? ban?
502 recvPacket.rfinish(); // prevent spam at ignore packet
503 return;
504 }
505 }
506
507 sScriptMgr->ValidateSpellAtCastSpell(_player, oldSpellId, spellId, castCount, castFlags);
508
509 if (oldSpellId != spellId)
510 spellInfo = sSpellMgr->GetSpellInfo(spellId);
511
512 // Client is resending autoshot cast opcode when other spell is casted during shoot rotation
513 // Skip it to prevent "interrupt" message
516 {
517 recvPacket.rfinish();
518 return;
519 }
520
521 // can't use our own spells when we're in possession of another unit,
522 if (_player->isPossessing())
523 {
524 return;
525 }
526
527 // 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.
528 if (!mover->FindMap())
529 {
530 recvPacket.rfinish(); // prevent spam at ignore packet
531 return;
532 }
533
534 // auto-selection buff level base at target level (in spellInfo)
535 if (spellInfo->IsPositive())
536 if (Unit* target = targets.GetUnitTarget())
537 if (mover->IsFriendlyTo(target))
538 {
539 SpellInfo const* actualSpellInfo = spellInfo->GetAuraRankForLevel(target->GetLevel());
540
541 // 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
542 if (actualSpellInfo)
543 spellInfo = actualSpellInfo;
544 }
545
546 Spell* spell = new Spell(mover, spellInfo, triggerFlag, ObjectGuid::Empty, false);
547
548 sScriptMgr->ValidateSpellAtCastSpellResult(_player, mover, spell, oldSpellId, spellId);
549
550 spell->m_cast_count = castCount; // set count of casts
551 spell->prepare(&targets);
552}
@ EFFECT_0
Definition SharedDefines.h:31
@ SPELL_EFFECT_OPEN_LOCK
Definition SharedDefines.h:799
@ SPELL_FAILED_DONT_REPORT
Definition SharedDefines.h:964
TriggerCastFlags
Definition SpellDefines.h:140
@ TRIGGERED_NONE
Definition SpellDefines.h:141
@ TARGET_FLAG_GAMEOBJECT_ITEM
Definition SpellInfo.h:61
bool empty() const
Definition ByteBuffer.h:445
bool HasSpell(uint32 spellID) const override
Definition Creature.cpp:3089
bool IsPlayer() const
Definition Object.h:207
Player * ToPlayer()
Definition Object.h:208
bool IsCreature() const
Definition Object.h:211
Creature * ToCreature()
Definition Object.h:212
bool CanExecutePendingSpellCastRequest(SpellInfo const *spellInfo)
Definition PlayerUpdates.cpp:2370
bool HasActiveSpell(uint32 spell) const
Definition Player.cpp:4063
bool CanRequestSpellCast(SpellInfo const *spellInfo)
Definition PlayerUpdates.cpp:2396
GameObject * GetGOTarget() const
Definition Spell.cpp:301
void Read(ByteBuffer &data, WorldObject *caster)
Definition Spell.cpp:163
Unit * GetUnitTarget() const
Definition Spell.cpp:269
uint32 GetCategory() const
Definition SpellInfo.cpp:884
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition SpellInfo.cpp:2959
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition SpellInfo.h:417
uint32 Targets
Definition SpellInfo.h:359
bool IsAutoRepeatRangedSpell() const
Definition SpellInfo.cpp:1328
uint8 m_cast_count
Definition Spell.h:539
void finish(bool ok=true)
Definition Spell.cpp:4612
SpellInfo const *const m_spellInfo
Definition Spell.h:535
bool isPossessing() const
Definition Unit.h:1318
bool IsFriendlyTo(Unit const *unit) const
Definition Unit.cpp:7043
Vehicle * GetVehicleKit() const
Definition Unit.h:1931
Map * FindMap() const
Definition Object.h:638
void HandleClientCastFlags(WorldPacket &recvPacket, uint8 castFlags, SpellCastTargets &targets)
Definition SpellHandler.cpp:35
Definition Player.h:1074
bool cancelInProgress
Definition Player.h:1079

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(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicleKit(), HandleClientCastFlags(), Player::HasActiveSpell(), Creature::HasSpell(), SpellInfo::IsAutoRepeatRangedSpell(), Object::IsCreature(), Unit::IsFriendlyTo(), SpellInfo::IsPassive(), Object::IsPlayer(), SpellInfo::IsPositive(), 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:14626
void ChangeSeat(int8 seatId, bool next=true)
Definition Unit.cpp:15296
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition Vehicle.cpp:656
void ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
Definition WorldSession.cpp:1089
@ 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:295
ObjectGuid guid
Definition Object.h:297
bool CanSwitchFromSeat() const
Definition DBCStructure.h:2155

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)
268{
269 std::string channelName;
270 recvPacket >> channelName;
271
272 LOG_DEBUG("chat.system", "CMSG_CHANNEL_ANNOUNCEMENTS {} Channel: {}",
273 GetPlayerInfo(), channelName);
275 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
276 channel->Announce(GetPlayer());
277}
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)
238{
239 std::string channelName, targetName;
240 recvPacket >> channelName >> targetName;
241
242 LOG_DEBUG("chat.system", "CMSG_CHANNEL_BAN {} Channel: {}, Target: {}",
243 GetPlayerInfo(), channelName, targetName);
244 if (!normalizePlayerName(targetName))
245 return;
246
248 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
249 channel->Ban(GetPlayer(), targetName);
250}

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

Referenced by OpcodeTable::Initialize().

◆ HandleChannelDeclineInvite()

void WorldSession::HandleChannelDeclineInvite ( WorldPacket &  recvPacket)
807{
808 // used only with EXTRA_LOGS
809 (void)recvPacket;
810
811 LOG_DEBUG("network", "Opcode {}", recvPacket.GetOpcode());
812}

References WorldPacket::GetOpcode(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleChannelDisplayListQuery()

void WorldSession::HandleChannelDisplayListQuery ( WorldPacket &  recvPacket)
293{
294 // this should be OK because the 2 function _were_ the same
295 HandleChannelList(recvPacket);
296}
void HandleChannelList(WorldPacket &recvPacket)
Definition ChannelHandler.cpp:92

References HandleChannelList().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelInvite()

void WorldSession::HandleChannelInvite ( WorldPacket &  recvPacket)
208{
209 std::string channelName, targetName;
210 recvPacket >> channelName >> targetName;
211
212 LOG_DEBUG("chat.system", "CMSG_CHANNEL_INVITE {} Channel: {}, Target: {}",
213 GetPlayerInfo(), channelName, targetName);
214 if (!normalizePlayerName(targetName))
215 return;
216
218 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
219 channel->Invite(GetPlayer(), targetName);
220}

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

Referenced by OpcodeTable::Initialize().

◆ HandleChannelKick()

void WorldSession::HandleChannelKick ( WorldPacket &  recvPacket)
223{
224 std::string channelName, targetName;
225 recvPacket >> channelName >> targetName;
226
227 LOG_DEBUG("chat.system", "CMSG_CHANNEL_KICK {} Channel: {}, Target: {}",
228 GetPlayerInfo(), channelName, targetName);
229 if (!normalizePlayerName(targetName))
230 return;
231
233 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
234 channel->Kick(GetPlayer(), targetName);
235}

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

Referenced by OpcodeTable::Initialize().

◆ HandleChannelList()

void WorldSession::HandleChannelList ( WorldPacket &  recvPacket)
93{
94 std::string channelName;
95 recvPacket >> channelName;
96
97 LOG_DEBUG("chat.system", "{} {} Channel: {}",
98 recvPacket.GetOpcode() == CMSG_CHANNEL_DISPLAY_LIST ? "CMSG_CHANNEL_DISPLAY_LIST" : "CMSG_CHANNEL_LIST",
99 GetPlayerInfo(), channelName);
101 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
102 channel->List(GetPlayer());
103}
@ 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)
280{
281 std::string channelName;
282 recvPacket >> channelName;
283
284 LOG_DEBUG("chat.system", "CMSG_CHANNEL_MODERATE {} Channel: {}",
285 GetPlayerInfo(), channelName);
286
288 if (Channel* chn = cMgr->GetChannel(channelName, GetPlayer()))
289 chn->ToggleModeration(GetPlayer());
290}

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

Referenced by OpcodeTable::Initialize().

◆ HandleChannelModerator()

void WorldSession::HandleChannelModerator ( WorldPacket &  recvPacket)
148{
149 std::string channelName, targetName;
150 recvPacket >> channelName >> targetName;
151
152 LOG_DEBUG("chat.system", "CMSG_CHANNEL_MODERATOR {} Channel: {}, Target: {}",
153 GetPlayerInfo(), channelName, targetName);
154 if (!normalizePlayerName(targetName))
155 return;
156
158 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
159 channel->SetModerator(GetPlayer(), targetName);
160}

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

Referenced by OpcodeTable::Initialize().

◆ HandleChannelMute()

void WorldSession::HandleChannelMute ( WorldPacket &  recvPacket)
178{
179 std::string channelName, targetName;
180 recvPacket >> channelName >> targetName;
181
182 LOG_DEBUG("chat.system", "CMSG_CHANNEL_MUTE {} Channel: {}, Target: {}",
183 GetPlayerInfo(), channelName, targetName);
184 if (!normalizePlayerName(targetName))
185 return;
186
188 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
189 channel->SetMute(GetPlayer(), targetName);
190}

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

Referenced by OpcodeTable::Initialize().

◆ HandleChannelOwner()

void WorldSession::HandleChannelOwner ( WorldPacket &  recvPacket)
136{
137 std::string channelName;
138 recvPacket >> channelName;
139
140 LOG_DEBUG("chat.system", "CMSG_CHANNEL_OWNER {} Channel: {}",
141 GetPlayerInfo(), channelName);
143 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
144 channel->SendWhoOwner(GetPlayer()->GetGUID());
145}

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

Referenced by OpcodeTable::Initialize().

◆ HandleChannelPassword()

void WorldSession::HandleChannelPassword ( WorldPacket &  recvPacket)
106{
107 std::string channelName, password;
108 recvPacket >> channelName >> password;
109
110 LOG_DEBUG("chat.system", "CMSG_CHANNEL_PASSWORD {} Channel: {}, Password: {}",
111 GetPlayerInfo(), channelName, password);
112 if (password.length() > MAX_CHANNEL_PASS_STR)
113 return;
114
116 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
117 channel->Password(GetPlayer(), password);
118}
#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)
121{
122 std::string channelName, targetName;
123 recvPacket >> channelName >> targetName;
124
125 LOG_DEBUG("chat.system", "CMSG_CHANNEL_SET_OWNER {} Channel: {}, Target: {}",
126 GetPlayerInfo(), channelName, targetName);
127 if (!normalizePlayerName(targetName))
128 return;
129
131 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
132 channel->SetOwner(GetPlayer(), targetName);
133}

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

Referenced by OpcodeTable::Initialize().

◆ HandleChannelUnban()

void WorldSession::HandleChannelUnban ( WorldPacket &  recvPacket)
253{
254 std::string channelName, targetName;
255 recvPacket >> channelName >> targetName;
256
257 LOG_DEBUG("chat.system", "CMSG_CHANNEL_UNBAN {} Channel: {}, Target: {}",
258 GetPlayerInfo(), channelName, targetName);
259 if (!normalizePlayerName(targetName))
260 return;
261
263 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
264 channel->UnBan(GetPlayer(), targetName);
265}

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

Referenced by OpcodeTable::Initialize().

◆ HandleChannelUnmoderator()

void WorldSession::HandleChannelUnmoderator ( WorldPacket &  recvPacket)
163{
164 std::string channelName, targetName;
165 recvPacket >> channelName >> targetName;
166
167 LOG_DEBUG("chat.system", "CMSG_CHANNEL_UNMODERATOR {} Channel: {}, Target: {}",
168 GetPlayerInfo(), channelName, targetName);
169 if (!normalizePlayerName(targetName))
170 return;
171
173 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
174 channel->UnsetModerator(GetPlayer(), targetName);
175}

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

Referenced by OpcodeTable::Initialize().

◆ HandleChannelUnmute()

void WorldSession::HandleChannelUnmute ( WorldPacket &  recvPacket)
193{
194 std::string channelName, targetName;
195 recvPacket >> channelName >> targetName;
196
197 LOG_DEBUG("chat.system", "CMSG_CHANNEL_UNMUTE {} Channel: {}, Target: {}",
198 GetPlayerInfo(), channelName, targetName);
199 if (!normalizePlayerName(targetName))
200 return;
201
203 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
204 channel->UnsetMute(GetPlayer(), targetName);
205}

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)
591{
592 if (!GetPlayer())
593 return;
594
595 ChatHandler handler = ChatHandler(this);
596
597 // Select
598 if (!result)
599 {
601 return;
602 }
603
604 // Header of the names
606
607 // Output of the results
608 do
609 {
610 Field* fields = result->Fetch();
611 std::string player = fields[0].Get<std::string>();
613 } while (result->NextRow());
614}
@ LANG_COMMAND_LIST_FREEZE
Definition Language.h:1066
@ LANG_COMMAND_NO_FROZEN_PLAYERS
Definition Language.h:1065
@ LANG_COMMAND_FROZEN_PLAYERS
Definition Language.h:1067
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition Field.h:113

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)
265{
266 std::shared_ptr<CharacterCreateInfo> createInfo = std::make_shared<CharacterCreateInfo>();
267
268 recvData >> createInfo->Name
269 >> createInfo->Race
270 >> createInfo->Class
271 >> createInfo->Gender
272 >> createInfo->Skin
273 >> createInfo->Face
274 >> createInfo->HairStyle
275 >> createInfo->HairColor
276 >> createInfo->FacialHair
277 >> createInfo->OutfitId;
278
280 {
281 if (uint32 mask = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED))
282 {
283 if (mask & (1 << Player::TeamIdForRace(createInfo->Race)))
284 {
286 return;
287 }
288 }
289 }
290
291 ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(createInfo->Class);
292 if (!classEntry)
293 {
295 LOG_ERROR("network.opcode", "Class ({}) not found in DBC while creating new char for account (ID: {}): wrong DBC files or cheater?", createInfo->Class, GetAccountId());
296 return;
297 }
298
299 ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(createInfo->Race);
300 if (!raceEntry)
301 {
303 LOG_ERROR("network.opcode", "Race ({}) not found in DBC while creating new char for account (ID: {}): wrong DBC files or cheater?", createInfo->Race, GetAccountId());
304 return;
305 }
306
307 // prevent character creating Expansion race without Expansion account
308 if (raceEntry->expansion > Expansion())
309 {
311 LOG_ERROR("network.opcode", "Expansion {} account:[{}] tried to Create character with expansion {} race ({})", Expansion(), GetAccountId(), raceEntry->expansion, createInfo->Race);
312 return;
313 }
314
315 // prevent character creating Expansion class without Expansion account
316 if (classEntry->expansion > Expansion())
317 {
319 LOG_ERROR("network.opcode", "Expansion {} account:[{}] tried to Create character with expansion {} class ({})", Expansion(), GetAccountId(), classEntry->expansion, createInfo->Class);
320 return;
321 }
322
324 {
325 uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK);
326 if ((1 << (createInfo->Race - 1)) & raceMaskDisabled)
327 {
329 return;
330 }
331 }
332
334 {
335 uint32 classMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK);
336 if ((1 << (createInfo->Class - 1)) & classMaskDisabled)
337 {
339 return;
340 }
341 }
342
343 // prevent character creating with invalid name
344 if (!normalizePlayerName(createInfo->Name))
345 {
347 LOG_ERROR("network.opcode", "Account:[{}] but tried to Create character with empty [name] ", GetAccountId());
348 return;
349 }
350
351 // check name limitations
352 uint8 res = ObjectMgr::CheckPlayerName(createInfo->Name, true);
353 if (res != CHAR_NAME_SUCCESS)
354 {
356 {
358 return;
359 }
360 }
361
362 // speedup check for heroic class disabled case
363 uint32 heroic_free_slots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM);
364 if (heroic_free_slots == 0 && !HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_DEATH_KNIGHT) && createInfo->Class == CLASS_DEATH_KNIGHT)
365 {
367 return;
368 }
369
370 // speedup check for heroic class disabled case
371 uint32 req_level_for_heroic = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER);
373 && req_level_for_heroic > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) && !HasAccountFlag(ACCOUNT_FLAG_DEATH_KNIGHT_OK))
374 {
376 return;
377 }
378
380 stmt->SetData(0, createInfo->Name);
381
383 .WithChainingPreparedCallback([this](QueryCallback& queryCallback, PreparedQueryResult result)
384 {
385 if (result)
386 {
387 SendCharCreate(CHAR_CREATE_NAME_IN_USE);
388 return;
389 }
390
392 stmt->SetData(0, GetAccountId());
393 queryCallback.SetNextQuery(LoginDatabase.AsyncQuery(stmt));
394 })
395 .WithChainingPreparedCallback([this](QueryCallback& queryCallback, PreparedQueryResult result)
396 {
397 uint64 acctCharCount = 0;
398 if (result)
399 {
400 Field* fields = result->Fetch();
401 acctCharCount = uint64(fields[0].Get<double>());
402 }
403
404 if (acctCharCount >= static_cast<uint64>(sWorld->getIntConfig(CONFIG_CHARACTERS_PER_ACCOUNT)))
405 {
407 return;
408 }
409
411 stmt->SetData(0, GetAccountId());
412 queryCallback.SetNextQuery(CharacterDatabase.AsyncQuery(stmt));
413 })
414 .WithChainingPreparedCallback([this, createInfo](QueryCallback& queryCallback, PreparedQueryResult result)
415 {
416 if (result)
417 {
418 Field* fields = result->Fetch();
419 createInfo->CharCount = uint8(fields[0].Get<uint64>()); // SQL's COUNT() returns uint64 but it will always be less than uint8.Max
420
421 if (createInfo->CharCount >= sWorld->getIntConfig(CONFIG_CHARACTERS_PER_REALM))
422 {
424 return;
425 }
426 }
427
428 bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || HasPermission(rbac::RBAC_PERM_TWO_SIDE_CHARACTER_CREATION);
429 uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
430
431 std::function<void(PreparedQueryResult)> finalizeCharacterCreation = [this, createInfo](PreparedQueryResult result)
432 {
433 if (!sScriptMgr->CanAccountCreateCharacter(GetAccountId(), createInfo->Race, createInfo->Class))
434 {
436 return;
437 }
438 bool haveSameRace = false;
440 bool const deathKnightFlagAlreadySet = HasAccountFlag(ACCOUNT_FLAG_DEATH_KNIGHT_OK); // Account flag is superior to level requirement.
441 bool hasHeroicReqLevel = (heroicReqLevel == 0) || deathKnightFlagAlreadySet;
442 bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || HasPermission(rbac::RBAC_PERM_TWO_SIDE_CHARACTER_CREATION);
443 uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
444 bool checkDeathKnightReqs = !HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_DEATH_KNIGHT) && 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)
531 {
532 if (!deathKnightFlagAlreadySet && hasHeroicReqLevel)
534
535 if (!hasHeroicReqLevel)
536 {
538 return;
539 }
540 }
541
542 // Check name uniqueness in the same step as saving to database
543 if (sCharacterCache->GetCharacterGuidByName(createInfo->Name))
544 {
546 return;
547 }
548
549 std::shared_ptr<Player> newChar(new Player(this), [](Player* ptr)
550 {
551 // Only when player is created correctly do clean
553 {
554 ptr->CleanupsBeforeDelete();
555 }
556 delete ptr;
557 });
558
559 newChar->GetMotionMaster()->Initialize();
560 if (!newChar->Create(sObjectMgr->GetGenerator<HighGuid::Player>().Generate(), createInfo.get()))
561 {
562 // Player not create (race/class/etc problem?)
564 return;
565 }
566
567 if ((haveSameRace && skipCinematics == 1) || skipCinematics == 2)
568 newChar->setCinematic(1); // not show intro
569
570 newChar->SetAtLoginFlag(AT_LOGIN_FIRST); // First login
571
572 CharacterDatabaseTransaction characterTransaction = CharacterDatabase.BeginTransaction();
573 LoginDatabaseTransaction trans = LoginDatabase.BeginTransaction();
574
575 // Player created, save it now
576 newChar->SaveToDB(characterTransaction, true, false);
577 createInfo->CharCount++;
578
580 stmt->SetData(0, createInfo->CharCount);
581 stmt->SetData(1, GetAccountId());
582 stmt->SetData(2, realm.Id.Realm);
583 trans->Append(stmt);
584
585 LoginDatabase.CommitTransaction(trans);
586
587 AddTransactionCallback(CharacterDatabase.AsyncCommitTransaction(characterTransaction)).AfterComplete([this, newChar = std::move(newChar)](bool success)
588 {
589 if (success)
590 {
591 LOG_INFO("entities.player.character", "Account: {} (IP: {}) Create Character: {} {}", GetAccountId(), GetRemoteAddress(), newChar->GetName(), newChar->GetGUID().ToString());
592 sScriptMgr->OnPlayerCreate(newChar.get());
593 sCharacterCache->AddCharacterCacheEntry(newChar->GetGUID(), GetAccountId(), newChar->GetName(), newChar->getGender(), newChar->getRace(), newChar->getClass(), newChar->GetLevel());
595 }
596 else
598 });
599 };
600
601 if (allowTwoSideAccounts && !skipCinematics && createInfo->Class != CLASS_DEATH_KNIGHT)
602 {
603 finalizeCharacterCreation(PreparedQueryResult(nullptr));
604 return;
605 }
606
608 stmt->SetData(0, GetAccountId());
609 stmt->SetData(1, (skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT) ? 10 : 1);
610 queryCallback.WithPreparedCallback(std::move(finalizeCharacterCreation)).SetNextQuery(CharacterDatabase.AsyncQuery(stmt));
611 }));
612}
@ 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
@ ACCOUNT_FLAG_DEATH_KNIGHT_OK
Definition Common.h:96
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:592
ResponseCodes
Definition SharedDefines.h:3569
@ CHAR_CREATE_EXPANSION
Definition SharedDefines.h:3633
@ CHAR_NAME_NO_NAME
Definition SharedDefines.h:3670
@ CHAR_CREATE_DISABLED
Definition SharedDefines.h:3627
@ CHAR_CREATE_LEVEL_REQUIREMENT
Definition SharedDefines.h:3635
@ CHAR_CREATE_FAILED
Definition SharedDefines.h:3625
@ CHAR_NAME_RESERVED
Definition SharedDefines.h:3676
@ CHAR_CREATE_ERROR
Definition SharedDefines.h:3624
@ CHAR_CREATE_NAME_IN_USE
Definition SharedDefines.h:3626
@ CHAR_CREATE_SERVER_LIMIT
Definition SharedDefines.h:3629
@ CHAR_CREATE_EXPANSION_CLASS
Definition SharedDefines.h:3634
@ CHAR_CREATE_SUCCESS
Definition SharedDefines.h:3623
@ CHAR_CREATE_PVP_TEAMS_VIOLATION
Definition SharedDefines.h:3628
@ CHAR_CREATE_ACCOUNT_LIMIT
Definition SharedDefines.h:3630
@ CHAR_CREATE_UNIQUE_CLASS_LIMIT
Definition SharedDefines.h:3636
@ CHAR_NAME_SUCCESS
Definition SharedDefines.h:3668
@ CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK
Definition WorldConfig.h:187
@ CONFIG_CHARACTER_CREATING_DISABLED
Definition WorldConfig.h:185
@ CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK
Definition WorldConfig.h:186
@ CONFIG_CHARACTERS_PER_ACCOUNT
Definition WorldConfig.h:188
@ CONFIG_HEROIC_CHARACTERS_PER_REALM
Definition WorldConfig.h:191
@ CONFIG_ALLOW_TWO_SIDE_ACCOUNTS
Definition WorldConfig.h:31
@ CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER
Definition WorldConfig.h:192
@ CONFIG_SKIP_CINEMATICS
Definition WorldConfig.h:193
@ CONFIG_CHARACTERS_PER_REALM
Definition WorldConfig.h:189
static uint8 CheckPlayerName(std::string_view name, bool create=false)
Definition ObjectMgr.cpp:9280
bool HasAtLoginFlag(AtLoginFlags f) const
Definition Player.h:2451
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:117
uint8 Expansion() const
Definition WorldSession.h:514
bool HasAccountFlag(uint32 flag) const
Definition WorldSession.h:438
TransactionCallback & AddTransactionCallback(TransactionCallback &&callback)
Definition WorldSession.cpp:1414
void UpdateAccountFlag(uint32 flag, bool remove=false)
Definition WorldSession.cpp:196
void SendCharCreate(ResponseCodes result)
Definition CharacterHandler.cpp:2603
@ RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_TEAMMASK
Definition RBAC.h:65
@ RBAC_PERM_TWO_SIDE_CHARACTER_CREATION
Definition RBAC.h:75
@ RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME
Definition RBAC.h:68
@ RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK
Definition RBAC.h:67
@ RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_DEATH_KNIGHT
Definition RBAC.h:69
@ RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_CLASSMASK
Definition RBAC.h:66
Definition DBCStructure.h:680
uint32 expansion
Definition DBCStructure.h:695
Definition DBCStructure.h:706
uint32 expansion
Definition DBCStructure.h:725

References _queryProcessor, ACCOUNT_FLAG_DEATH_KNIGHT_OK, 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_RESERVED, 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(), HasAccountFlag(), HasPermission(), LOG_ERROR, LOGIN_SEL_SUM_REALM_CHARACTERS, LoginDatabase, normalizePlayerName(), rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_CLASSMASK, rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_DEATH_KNIGHT, rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK, rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME, rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_TEAMMASK, sChrClassesStore, sChrRacesStore, SendCharCreate(), PreparedStatementBase::SetData(), QueryCallback::SetNextQuery(), sWorld, and Player::TeamIdForRace().

Referenced by OpcodeTable::Initialize().

◆ HandleCharCustomize()

void WorldSession::HandleCharCustomize ( WorldPacket &  recvData)
1640{
1641 std::shared_ptr<CharacterCustomizeInfo> customizeInfo = std::make_shared<CharacterCustomizeInfo>();
1642
1643 recvData >> customizeInfo->Guid;
1644
1645 if (!IsLegitCharacterForAccount(customizeInfo->Guid))
1646 {
1647 LOG_ERROR("entities.player.cheat", "Account {}, IP: {} tried to customise {}, but it does not belong to their account!",
1648 GetAccountId(), GetRemoteAddress(), customizeInfo->Guid.ToString());
1649 recvData.rfinish();
1650 KickPlayer("WorldSession::HandleCharCustomize Trying to customise character of another account");
1651 return;
1652 }
1653
1654 // pussywizard:
1655 if (ObjectAccessor::FindConnectedPlayer(customizeInfo->Guid) || sWorldSessionMgr->FindOfflineSessionForCharacterGUID(customizeInfo->Guid.GetCounter()))
1656 {
1657 recvData.rfinish();
1659 data << uint8(CHAR_CREATE_ERROR);
1660 SendPacket(&data);
1661 return;
1662 }
1663
1664 recvData >> customizeInfo->Name
1665 >> customizeInfo->Gender
1666 >> customizeInfo->Skin
1667 >> customizeInfo->HairColor
1668 >> customizeInfo->HairStyle
1669 >> customizeInfo->FacialHair
1670 >> customizeInfo->Face;
1671
1673 stmt->SetData(0, customizeInfo->Guid.GetCounter());
1674
1676 .WithPreparedCallback(std::bind(&WorldSession::HandleCharCustomizeCallback, this, customizeInfo, std::placeholders::_1)));
1677}
@ CHAR_SEL_CHAR_CUSTOMIZE_INFO
Definition CharacterDatabase.h:351
#define sWorldSessionMgr
Definition WorldSessionMgr.h:118
void HandleCharCustomizeCallback(std::shared_ptr< CharacterCustomizeInfo > customizeInfo, PreparedQueryResult result)
Definition CharacterHandler.cpp:1679
bool IsLegitCharacterForAccount(ObjectGuid guid)
Definition WorldSession.h:1283
@ 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

1680{
1681 if (!result)
1682 {
1683 SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo.get());
1684 return;
1685 }
1686
1687 // get the players old (at this moment current) race
1688 CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(customizeInfo->Guid);
1689 if (!playerData)
1690 {
1691 SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo.get());
1692 return;
1693 }
1694
1695 Field* fields = result->Fetch();
1696 std::string oldName = fields[0].Get<std::string>();
1697 //uint8 plrRace = fields[1].Get<uint8>();
1698 //uint8 plrClass = fields[2].Get<uint8>();
1699 //uint8 plrGender = fields[3].Get<uint8>();
1700 uint32 atLoginFlags = fields[4].Get<uint16>();
1701
1702 if (!(atLoginFlags & AT_LOGIN_CUSTOMIZE))
1703 {
1704 SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo.get());
1705 return;
1706 }
1707
1708 atLoginFlags &= ~AT_LOGIN_CUSTOMIZE;
1709
1710 // prevent character rename to invalid name
1711 if (!normalizePlayerName(customizeInfo->Name))
1712 {
1713 SendCharCustomize(CHAR_NAME_NO_NAME, customizeInfo.get());
1714 return;
1715 }
1716
1717 ResponseCodes res = static_cast<ResponseCodes>(ObjectMgr::CheckPlayerName(customizeInfo->Name, true));
1718 if (res != CHAR_NAME_SUCCESS)
1719 {
1721 {
1722 SendCharCustomize(res, customizeInfo.get());
1723 return;
1724 }
1725 }
1726
1727 // character with this name already exist
1728 if (ObjectGuid newguid = sCharacterCache->GetCharacterGuidByName(customizeInfo->Name))
1729 {
1730 if (newguid != customizeInfo->Guid)
1731 {
1732 SendCharCustomize(CHAR_CREATE_NAME_IN_USE, customizeInfo.get());
1733 return;
1734 }
1735 }
1736
1737 CharacterDatabasePreparedStatement* stmt = nullptr;
1738 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
1739
1740 ObjectGuid::LowType lowGuid = customizeInfo->Guid.GetCounter();
1741
1743 Player::Customize(customizeInfo.get(), trans);
1744
1746 {
1747 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN);
1748 stmt->SetData(0, customizeInfo->Name);
1749 stmt->SetData(1, atLoginFlags);
1750 stmt->SetData(2, lowGuid);
1751
1752 trans->Append(stmt);
1753
1754 if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
1755 {
1756 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME);
1757 stmt->SetData(0, lowGuid);
1758
1759 trans->Append(stmt);
1760 }
1761 }
1762
1763 CharacterDatabase.CommitTransaction(trans);
1764
1765 sCharacterCache->UpdateCharacterData(customizeInfo->Guid, customizeInfo->Name, customizeInfo->Gender);
1766
1767 SendCharCustomize(RESPONSE_SUCCESS, customizeInfo.get());
1768
1769 LOG_INFO("entities.player.character", "Account: {} (IP: {}), Character[{}] ({}) Customized to: {}",
1770 GetAccountId(), GetRemoteAddress(), oldName, customizeInfo->Guid.ToString(), customizeInfo->Name);
1771}
@ CHAR_DEL_DECLINED_NAME
Definition CharacterDatabase.h:139
@ CHAR_UPD_CHAR_NAME_AT_LOGIN
Definition CharacterDatabase.h:308
@ AT_LOGIN_CUSTOMIZE
Definition Player.h:590
@ RESPONSE_SUCCESS
Definition SharedDefines.h:3570
@ CONFIG_DECLINED_NAMES_USED
Definition WorldConfig.h:65
uint32 LowType
Definition ObjectGuid.h:125
static void Customize(CharacterCustomizeInfo const *customizeInfo, CharacterDatabaseTransaction trans)
Definition PlayerMisc.cpp:116
void SendCharCustomize(ResponseCodes result, CharacterCustomizeInfo const *customizeInfo)
Definition CharacterHandler.cpp:2655

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

Referenced by HandleCharCustomize().

◆ HandleCharDeleteOpcode()

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

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)
220{
221 WorldPacket data(SMSG_CHAR_ENUM, 100); // we guess size
222
223 uint8 num = 0;
224
225 data << num;
226
227 _legitCharacters.clear();
228 if (result)
229 {
230 do
231 {
232 ObjectGuid guid = ObjectGuid::Create<HighGuid::Player>((*result)[0].Get<uint32>());
233 LOG_DEBUG("network.opcode", "Loading char {} from account {}.", guid.ToString(), GetAccountId());
234 if (Player::BuildEnumData(result, &data))
235 {
236 _legitCharacters.insert(guid);
237 ++num;
238 }
239 } while (result->NextRow());
240 }
241
242 data.put<uint8>(0, num);
243
244 SendPacket(&data);
245}
static bool BuildEnumData(PreparedQueryResult result, WorldPacket *data)
Definition Player.cpp:1154
GuidSet _legitCharacters
Definition WorldSession.h:1290
@ 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

248{
250
252
253 if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
254 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ENUM_DECLINED_NAME);
255 else
256 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ENUM);
257
259 stmt->SetData(1, GetAccountId());
260
261 _queryProcessor.AddCallback(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSession::HandleCharEnum, this, std::placeholders::_1)));
262}
@ 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:219

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

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_RESERVED, 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_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(), GetSessionDbLocaleIndex(), GetZoneLFGDungeonEntry(), CharacterCacheEntry::GuildId, HasPermission(), TaxiPathEntry::ID, 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, rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK, rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME, rbac::RBAC_PERM_TWO_SIDE_ADD_FRIEND, RESPONSE_SUCCESS, sAllianceTaxiNodesMask, sAreaTableStore, sArenaTeamMgr, sAuctionMgr, Player::SavePositionInDB(), sCharacterCache, sCharTitlesStore, sDeathKnightTaxiNodesMask, SendCharFactionChange(), PreparedStatementBase::SetData(), sFactionStore, sGuildMgr, sHordeTaxiNodesMask, sMapMgr, sObjectMgr, sRaceMgr, 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 
)
1397{
1398 if (!result)
1399 {
1400 SendCharRename(CHAR_CREATE_ERROR, renameInfo.get());
1401 return;
1402 }
1403
1404 Field* fields = result->Fetch();
1405
1406 ObjectGuid::LowType guidLow = fields[0].Get<uint32>();
1407 std::string oldName = fields[1].Get<std::string>();
1408 uint16 atLoginFlags = fields[2].Get<uint16>();
1409
1410 if (!(atLoginFlags & AT_LOGIN_RENAME))
1411 {
1412 SendCharRename(CHAR_CREATE_ERROR, renameInfo.get());
1413 return;
1414 }
1415
1416 atLoginFlags &= ~AT_LOGIN_RENAME;
1417
1418 // pussywizard:
1419 if (ObjectAccessor::FindConnectedPlayer(ObjectGuid::Create<HighGuid::Player>(guidLow)) || sWorldSessionMgr->FindOfflineSessionForCharacterGUID(guidLow))
1420 {
1421 SendCharRename(CHAR_CREATE_ERROR, renameInfo.get());
1422 return;
1423 }
1424
1425 // Update name and at_login flag in the db
1427 stmt->SetData(0, renameInfo->Name);
1428 stmt->SetData(1, atLoginFlags);
1429 stmt->SetData(2, guidLow);
1430 CharacterDatabase.Execute(stmt);
1431
1432 // Removed declined name from db
1433 if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
1434 {
1435 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME);
1436 stmt->SetData(0, guidLow);
1437 CharacterDatabase.Execute(stmt);
1438 }
1439
1440 LOG_INFO("entities.player.character", "Account: {} (IP: {}), Character [{}] (guid: {}) Changed name to: {}", GetAccountId(), GetRemoteAddress(), oldName, guidLow, renameInfo->Name);
1441
1442 SendCharRename(RESPONSE_SUCCESS, renameInfo.get());
1443
1444 // xinef: update global data
1445 sCharacterCache->UpdateCharacterData(renameInfo->Guid, renameInfo->Name);
1446}
@ AT_LOGIN_RENAME
Definition Player.h:587
void SendCharRename(ResponseCodes result, CharacterRenameInfo const *renameInfo)
Definition CharacterHandler.cpp:2624

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)
1361{
1362 std::shared_ptr<CharacterRenameInfo> renameInfo = std::make_shared<CharacterRenameInfo>();
1363
1364 recvData >> renameInfo->Guid
1365 >> renameInfo->Name;
1366
1367 // prevent character rename to invalid name
1368 if (!normalizePlayerName(renameInfo->Name))
1369 {
1370 SendCharRename(CHAR_NAME_NO_NAME, renameInfo.get());
1371 return;
1372 }
1373
1374 uint8 res = ObjectMgr::CheckPlayerName(renameInfo->Name, true);
1375 if (res != CHAR_NAME_SUCCESS)
1376 {
1378 {
1379 SendCharRename(ResponseCodes(res), renameInfo.get());
1380 return;
1381 }
1382 }
1383
1384 // Ensure that the character belongs to the current account, that rename at login is enabled
1385 // and that there is no character with the desired new name
1387
1388 stmt->SetData(0, renameInfo->Guid.GetCounter());
1389 stmt->SetData(1, GetAccountId());
1390 stmt->SetData(2, renameInfo->Name);
1391
1393 .WithPreparedCallback(std::bind(&WorldSession::HandleCharRenameCallBack, this, renameInfo, std::placeholders::_1)));
1394}
@ CHAR_SEL_FREE_NAME
Definition CharacterDatabase.h:50
void HandleCharRenameCallBack(std::shared_ptr< CharacterRenameInfo > renameInfo, PreparedQueryResult result)
Definition CharacterHandler.cpp:1396

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

Referenced by OpcodeTable::Initialize().

◆ HandleChatIgnoredOpcode()

void WorldSession::HandleChatIgnoredOpcode ( WorldPacket &  recvPacket)
790{
791 ObjectGuid iguid;
792 uint8 unk;
793
794 recvData >> iguid;
795 recvData >> unk; // probably related to spam reporting
796
798 if (!player)
799 return;
800
801 WorldPacket data;
803 player->SendDirectMessage(&data);
804}
@ CHAT_MSG_IGNORED
Definition SharedDefines.h:3410
@ LANG_UNIVERSAL
Definition SharedDefines.h:723
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:273

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)
337{
338 std::string channelName;
339 recvPacket >> channelName;
340
341 if (channelName.empty())
342 return;
343
345 if (Channel* channel = cMgr->GetChannel(channelName, nullptr, false))
346 channel->RemoveWatching(GetPlayer());
347}

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

Referenced by OpcodeTable::Initialize().

◆ HandleClearTradeItemOpcode()

void WorldSession::HandleClearTradeItemOpcode ( WorldPacket &  recvPacket)
936{
937 uint8 tradeSlot;
938 recvPacket >> tradeSlot;
939
940 TradeData* my_trade = _player->m_trade;
941 if (!my_trade)
942 return;
943
944 // invalid slot number
945 if (tradeSlot >= TRADE_SLOT_COUNT)
946 return;
947
948 my_trade->SetItem(TradeSlots(tradeSlot), nullptr);
949}
@ 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:183
void SetElevation(float elevation)
Definition Spell.h:181
void SetOpcode(uint16 opcode)
Definition WorldPacket.h:76
void HandleMovementOpcodes(WorldPacket &recvPacket)
Definition MovementHandler.cpp:362

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)
1142{
1143 LOG_DEBUG("network", "WORLD: CMSG_COMPLAIN");
1144
1145 // NOTE: all chat messages from this spammer automatically ignored by spam reporter until logout in case chat spam.
1146 // if it's mail spam - ALL mails from this spammer automatically removed by client
1147
1148 // Complaint Received message
1150
1151 if (sWorld->getBoolConfig(CONFIG_LOGSPAMREPORTS))
1152 {
1154
1155 stmt->SetData(0, packet.SpamType);
1156 stmt->SetData(1, packet.SpammerGuid.GetCounter());
1157 stmt->SetData(2, packet.Unk1);
1158 stmt->SetData(3, packet.MailIdOrMessageType);
1159 stmt->SetData(4, packet.ChannelId);
1160 stmt->SetData(5, packet.SecondsSinceMessage);
1161 stmt->SetData(6, packet.Description);
1162 stmt->SetData(7, GameTime::GetGameTime().count());
1163
1164 CharacterDatabase.Execute(stmt);
1165 }
1166}
Definition MiscPackets.h:231
uint32 ChannelId
Definition MiscPackets.h:225
uint32 MailIdOrMessageType
Definition MiscPackets.h:224
ObjectGuid SpammerGuid
Definition MiscPackets.h:222
std::string Description
Definition MiscPackets.h:227
uint32 Unk1
Definition MiscPackets.h:223
uint32 SecondsSinceMessage
Definition MiscPackets.h:226
uint8 SpamType
Definition MiscPackets.h:221

References WorldPackets::Misc::Complain::ChannelId, CHAR_INS_SPAM_REPORT, CharacterDatabase, CONFIG_LOGSPAMREPORTS, WorldPackets::Misc::Complain::Description, ObjectGuid::GetCounter(), GameTime::GetGameTime(), LOG_DEBUG, WorldPackets::Misc::Complain::MailIdOrMessageType, WorldPackets::Misc::Complain::SecondsSinceMessage, SendPacket(), PreparedStatementBase::SetData(), WorldPackets::Misc::Complain::SpammerGuid, WorldPackets::Misc::Complain::SpamType, sWorld, and WorldPackets::Misc::Complain::Unk1.

Referenced by OpcodeTable::Initialize().

◆ HandleCompleteCinematic()

void WorldSession::HandleCompleteCinematic ( WorldPacket &  recvPacket)
941{
942 // End the current cinematic and restore the normal player view
944}
void EndCinematic()
Definition CinematicMgr.cpp:65
CinematicMgr & GetCinematicMgr()
Definition Player.h:1403

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

Referenced by OpcodeTable::Initialize().

◆ HandleContactListOpcode()

void WorldSession::HandleContactListOpcode ( WorldPacket &  recvPacket)
31{
32 uint32 flags;
33 recv_data >> flags;
34
36}
void SendSocialList(Player *player, uint32 flags)
Definition SocialMgr.cpp:125

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:168
@ 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:125
std::vector< uint32 > CreatureQuestItemList
Definition CreatureData.h:283
#define MAX_CREATURE_QUEST_ITEMS
Definition CreatureData.h:34
static std::string_view GetLocaleString(std::vector< std::string > const &data, std::size_t locale)
Definition ObjectMgr.h:1491
@ SMSG_CREATURE_QUERY_RESPONSE
Definition Opcodes.h:127
Definition CreatureData.h:343
uint32 CreatureDisplayID
Definition CreatureData.h:180
CreatureModel const * GetModelByIdx(uint32 idx) const
Definition Creature.cpp:120
float ModHealth
Definition CreatureData.h:233
float ModMana
Definition CreatureData.h:234
uint32 type
Definition CreatureData.h:218
uint32 rank
Definition CreatureData.h:206
std::string SubName
Definition CreatureData.h:193
std::string Name
Definition CreatureData.h:192
uint32 KillCredit[MAX_KILL_CREDIT]
Definition CreatureData.h:190
bool RacialLeader
Definition CreatureData.h:237
uint32 type_flags
Definition CreatureData.h:219
uint32 family
Definition CreatureData.h:217
uint32 movementId
Definition CreatureData.h:238
std::string IconName
Definition CreatureData.h:194

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)
93{
94 ObjectGuid FriendGUID;
95 recv_data >> FriendGUID;
96
98
99 sSocialMgr->SendFriendStatus(GetPlayer(), FRIEND_REMOVED, FriendGUID, false);
100
101 LOG_DEBUG("network", "WORLD: Sent motd (SMSG_FRIEND_STATUS)");
102}
@ FRIEND_REMOVED
Definition SocialMgr.h:71
void RemoveFromSocialList(ObjectGuid const &friend_guid, SocialFlag flag)
Definition SocialMgr.cpp:75

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)
140{
141 ObjectGuid IgnoreGUID;
142 recv_data >> IgnoreGUID;
143
145 sSocialMgr->SendFriendStatus(GetPlayer(), FRIEND_IGNORE_REMOVED, IgnoreGUID, false);
146}
@ 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:7897
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:1484

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:383
bool IsDuringRemoveFromWorld() const
Definition Unit.h:704
ObjectGuid GetCharmGUID() const
Definition Unit.h:722
bool IsRooted() const
Definition Unit.h:1722
void ExitVehicle(Position const *exitPosition=nullptr)
Definition Unit.cpp:15315
bool ProcessMovementInfo(MovementInfo &movementInfo, Unit *mover, Player *plrMover, WorldPacket &recvData)
Definition MovementHandler.cpp:614
void AddMovementFlag(uint32 flag)
Definition Object.h:351

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:292
TempSummon * ToTempSummon()
Definition Unit.h:732
bool IsSummon() const
Definition Unit.h:795
ObjectGuid GetCritterGUID() const
Definition Unit.h:726
Creature * GetCreatureOrPetOrVehicle(WorldObject const &, ObjectGuid const &)
Definition ObjectAccessor.cpp:258

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:357
@ DUEL_STATE_COUNTDOWN
Definition Player.h:358
@ PLAYER_DUEL_ARBITER
Definition UpdateFields.h:177
ObjectGuid GetGuidValue(uint16 index) const
Definition Object.cpp:335
void SendDuelCountdown(uint32 counter)
Definition Player.cpp:15793
std::unique_ptr< DuelInfo > duel
Definition Player.h:1906

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:360
@ DUEL_STATE_IN_PROGRESS
Definition Player.h:359
@ DUEL_WON
Definition SharedDefines.h:3869
@ DUEL_INTERRUPTED
Definition SharedDefines.h:3868
void DuelComplete(DuelCompleteType type)
Definition Player.cpp:6598
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:1372
void CombatStopWithPets(bool includingCast=false)
Definition Unit.cpp:7298

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:172
bool IsCreature() const
Definition ObjectGuid.h:166
bool IsOnVehicle(Unit const *vehicle) const
Definition Unit.h:1933
Unit * GetBase() const
May be called from scripts.
Definition Vehicle.h:37
bool IsEjectable() const
Definition DBCStructure.h:2162

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)
665{
666 if (GetPlayer()->IsSpectator())
667 return;
668
669 uint32 emoteId = packet.EmoteID;
670
671 // restrict to the only emotes hardcoded in client
672 if (emoteId != EMOTE_ONESHOT_NONE && emoteId != EMOTE_ONESHOT_WAVE)
673 return;
674
676 return;
677
678 sScriptMgr->OnPlayerEmote(_player, emoteId);
679 _player->HandleEmoteCommand(emoteId);
680}
@ EMOTE_ONESHOT_NONE
Definition SharedDefines.h:1898
@ EMOTE_ONESHOT_WAVE
Definition SharedDefines.h:1901
void HandleEmoteCommand(uint32 emoteId)
Definition Unit.cpp:2198
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:306
void EnterVehicle(Unit *base, int8 seatId=-1)
Definition Unit.cpp:15219

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

Referenced by OpcodeTable::Initialize().

◆ HandleEquipmentSetDelete()

void WorldSession::HandleEquipmentSetDelete ( WorldPacket &  recvData)
1845{
1846 LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_DELETE");
1847
1848 uint64 setGuid;
1849 recvData.readPackGUID(setGuid);
1850
1851 _player->DeleteEquipmentSet(setGuid);
1852}
void readPackGUID(uint64 &guid)
Definition ByteBuffer.h:387
void DeleteEquipmentSet(uint64 setGuid)
Definition Player.cpp:15058

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

Referenced by OpcodeTable::Initialize().

◆ HandleEquipmentSetSave()

void WorldSession::HandleEquipmentSetSave ( WorldPacket &  recvData)
1774{
1775 LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_SAVE");
1776
1777 uint64 setGuid;
1778 recvData.readPackGUID(setGuid);
1779
1780 uint32 index;
1781 recvData >> index;
1782 if (index >= MAX_EQUIPMENT_SET_INDEX) // client set slots amount
1783 return;
1784
1785 std::string name;
1786 recvData >> name;
1787
1788 if (name.length() > 16) // Client limitation
1789 {
1790 LOG_ERROR("entities.player.cheat", "Character GUID {} tried to create equipment set {} with too long a name!", _player->GetGUID().ToString(), setGuid);
1791 return;
1792 }
1793
1794 std::string iconName;
1795 recvData >> iconName;
1796
1797 if (iconName.length() > 100) // DB limitation
1798 {
1799 LOG_ERROR("entities.player.cheat", "Character GUID {} tried to create equipment set {} with too long an icon name!", _player->GetGUID().ToString(), setGuid);
1800 return;
1801 }
1802
1803 EquipmentSet eqSet;
1804
1805 eqSet.Guid = setGuid;
1806 eqSet.Name = name;
1807 eqSet.IconName = iconName;
1808 eqSet.state = EQUIPMENT_SET_NEW;
1809
1810 for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
1811 {
1812 ObjectGuid itemGuid;
1813 recvData >> itemGuid.ReadAsPacked();
1814
1815 // xinef: if client sends 0, it means empty slot
1816 if (!itemGuid)
1817 {
1818 eqSet.Items[i].Clear();
1819 continue;
1820 }
1821
1822 // equipment manager sends "1" (as raw GUID) for slots set to "ignore" (don't touch slot at equip set)
1823 if (itemGuid.GetRawValue() == 1)
1824 {
1825 // ignored slots saved as bit mask because we have no free special values for Items[i]
1826 eqSet.IgnoreMask |= 1 << i;
1827 continue;
1828 }
1829
1830 // xinef: some cheating checks
1832 if (!item || item->GetGUID() != itemGuid)
1833 {
1834 eqSet.Items[i].Clear();
1835 continue;
1836 }
1837
1838 eqSet.Items[i] = itemGuid;
1839 }
1840
1841 _player->SetEquipmentSet(index, eqSet);
1842}
@ EQUIPMENT_SET_NEW
Definition Player.h:731
#define MAX_EQUIPMENT_SET_INDEX
Definition Player.h:747
@ EQUIPMENT_SLOT_END
Definition Player.h:681
uint64 GetRawValue() const
Definition ObjectGuid.h:145
void SetEquipmentSet(uint32 index, EquipmentSet eqset)
Definition Player.cpp:14942
Definition Player.h:736
ObjectGuid Items[EQUIPMENT_SLOT_END]
Definition Player.h:743
std::string Name
Definition Player.h:740
std::string IconName
Definition Player.h:741
EquipmentSetUpdateState state
Definition Player.h:744
uint64 Guid
Definition Player.h:739
uint32 IgnoreMask
Definition Player.h:742

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)
1855{
1856 LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_USE");
1857
1858 std::vector<std::unique_ptr<SavedItem>> savedItems;
1859 uint8 errorId = 0;
1860 for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
1861 {
1862 ObjectGuid itemGuid;
1863 recvData >> itemGuid.ReadAsPacked();
1864
1865 uint8 srcbag, srcslot;
1866 recvData >> srcbag >> srcslot;
1867
1868 LOG_DEBUG("entities.player.items", "Item {}: srcbag {}, srcslot {}", itemGuid.ToString(), srcbag, srcslot);
1869
1870 // check if item slot is set to "ignored" (raw value == 1), must not be unequipped then
1871 if (itemGuid.GetRawValue() == 1)
1872 continue;
1873
1874 // Only equip weapons in combat
1876 continue;
1877
1878 Item* item = nullptr;
1879 if (itemGuid)
1880 item = _player->GetItemByGuid(itemGuid);
1881
1882 uint16 dstpos = i | (INVENTORY_SLOT_BAG_0 << 8);
1883
1884 InventoryResult msg;
1886 if (uItem)
1887 {
1888 if (uItem->IsEquipped())
1889 {
1890 msg = _player->CanUnequipItem(dstpos, true);
1891 if (msg != EQUIP_ERR_OK)
1892 {
1893 _player->SendEquipError(msg, uItem, nullptr);
1894 continue;
1895 }
1896 }
1897
1898 if (!item)
1899 {
1900 ItemPosCountVec sDest;
1901 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, sDest, uItem, false);
1902 if (msg == EQUIP_ERR_OK)
1903 {
1904 savedItems.emplace_back(std::make_unique<SavedItem>(uItem, dstpos));
1906 _player->StoreItem(sDest, uItem, true);
1907 }
1908 else
1909 {
1910 errorId = 4;
1911 for (uint8_t j = 0; j < savedItems.size(); ++j)
1912 {
1913 _player->SwapItem(savedItems[j].get()->item->GetPos(), savedItems[j].get()->dstpos);
1914 }
1915 break;
1916 }
1917
1918 continue;
1919 }
1920 }
1921
1922 if (item)
1923 {
1924 if (item->GetPos() == dstpos)
1925 continue;
1926
1927 if (!item->IsEquipped())
1928 {
1929 uint16 _candidatePos;
1930 msg = _player->CanEquipItem(NULL_SLOT, _candidatePos, item, true);
1931 if (msg != EQUIP_ERR_OK)
1932 {
1933 _player->SendEquipError(msg, item, nullptr);
1934 continue;
1935 }
1936 }
1937
1938 _player->SwapItem(item->GetPos(), dstpos);
1939 }
1940 }
1941
1943 data << uint8(errorId); // 4 - equipment swap failed - inventory is full
1944 SendPacket(&data);
1945}
@ EQUIPMENT_SLOT_MAINHAND
Definition Player.h:677
@ EQUIPMENT_SLOT_OFFHAND
Definition Player.h:678
@ EQUIPMENT_SLOT_RANGED
Definition Player.h:679
bool IsEquipped() const
Definition Item.cpp:790
@ 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)
1188{
1189 LOG_DEBUG("network", "WORLD: CMSG_FAR_SIGHT");
1190
1191 bool apply;
1192 recvData >> apply;
1193
1194 if (apply)
1195 {
1196 LOG_DEBUG("network", "Added FarSight {} to player {}", _player->GetGuidValue(PLAYER_FARSIGHT).ToString(), _player->GetGUID().ToString());
1197 if (WorldObject* target = _player->GetViewpoint())
1198 _player->SetSeer(target);
1199 else
1200 LOG_DEBUG("network.opcode", "Player {} requests non-existing seer {}", _player->GetName(), _player->GetGuidValue(PLAYER_FARSIGHT).ToString());
1201 }
1202 else
1203 {
1204 WorldObject* newFarsightobject = nullptr;
1205 if (WorldObject* viewpoint = _player->GetViewpoint())
1206 {
1207 if (DynamicObject* viewpointDynamicObject = viewpoint->ToDynObject())
1208 {
1209 newFarsightobject = ObjectAccessor::GetUnit(*viewpointDynamicObject, viewpointDynamicObject->GetOldFarsightGUID());
1210 }
1211 else if (DynamicObject* viewpointDynamicObject = _player->GetDynObject(_player->GetUInt32Value(UNIT_CHANNEL_SPELL)))
1212 {
1213 if (viewpointDynamicObject->IsViewpoint() && viewpointDynamicObject->GetCasterGUID() == _player->GetGUID())
1214 {
1215 newFarsightobject = viewpointDynamicObject;
1216 }
1217 }
1218 }
1219
1220 if (newFarsightobject)
1221 {
1222 LOG_DEBUG("network", "Player {} set vision to old farsight {}", _player->GetGUID().ToString(), newFarsightobject->GetGUID().ToString());
1224 _player->SetViewpoint(newFarsightobject, true);
1225 }
1226 else
1227 {
1228 LOG_DEBUG("network", "Player {} set vision to self", _player->GetGUID().ToString());
1230 }
1231 }
1232
1234}
@ PLAYER_FARSIGHT
Definition UpdateFields.h:334
@ UNIT_CHANNEL_SPELL
Definition UpdateFields.h:94
Definition DynamicObject.h:35
DynamicObject * ToDynObject()
Definition Object.h:228
void SetSeer(WorldObject *target)
Definition Player.h:2397
void UpdateVisibilityForPlayer(bool mapChange=false)
Definition PlayerUpdates.cpp:1629
void SetViewpoint(WorldObject *target, bool apply)
Definition Player.cpp:13498
WorldObject * GetViewpoint() const
Definition Player.cpp:13541
DynamicObject * GetDynObject(uint32 spellId)
Definition Unit.cpp:6279
Definition Object.h:482
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)
679{
680 uint32 opcode = recvData.GetOpcode();
681 LOG_DEBUG("network", "WORLD: Recvd {} ({}, 0x{:X}) opcode", GetOpcodeNameForLogging(static_cast<OpcodeClient>(opcode)), opcode, opcode);
682
683 /* extract packet */
684 ObjectGuid guid;
685 uint32 counter;
686 MovementInfo movementInfo;
687 float newspeed;
688
689 recvData >> guid.ReadAsPacked();
690 recvData >> counter; // counter or moveEvent
691 movementInfo.guid = guid;
692 ReadMovementInfo(recvData, &movementInfo);
693 recvData >> newspeed;
694
695 Unit* mover = _player->m_mover;
696
697 // pussywizard: special check, only player mover allowed here
698 if (guid != mover->GetGUID() || guid != _player->GetGUID())
699 {
700 recvData.rfinish(); // prevent warnings spam
701 return;
702 }
703
704 // old map - async processing, ignore
705 if (counter <= _player->GetMapChangeOrderCounter())
706 return;
707
708 if (!ProcessMovementInfo(movementInfo, mover, _player, recvData))
709 {
710 recvData.rfinish(); // prevent warnings spam
711 return;
712 }
713
715 {
717 WriteMovementInfo(&data, &movementInfo);
718 data << newspeed; // new collision height
719 mover->SendMessageToSet(&data, _player);
720 return;
721 }
722
723 // client ACK send one packet for mounted/run case and need skip all except last from its
724 // in other cases anti-cheat check can be fail in false case
725 UnitMoveType move_type;
726 UnitMoveType force_move_type;
727
728 static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack", "PitchRate" };
729
730 switch (opcode)
731 {
732 case CMSG_FORCE_WALK_SPEED_CHANGE_ACK: move_type = MOVE_WALK; force_move_type = MOVE_WALK; break;
733 case CMSG_FORCE_RUN_SPEED_CHANGE_ACK: move_type = MOVE_RUN; force_move_type = MOVE_RUN; break;
734 case CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK: move_type = MOVE_RUN_BACK; force_move_type = MOVE_RUN_BACK; break;
735 case CMSG_FORCE_SWIM_SPEED_CHANGE_ACK: move_type = MOVE_SWIM; force_move_type = MOVE_SWIM; break;
736 case CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK: move_type = MOVE_SWIM_BACK; force_move_type = MOVE_SWIM_BACK; break;
737 case CMSG_FORCE_TURN_RATE_CHANGE_ACK: move_type = MOVE_TURN_RATE; force_move_type = MOVE_TURN_RATE; break;
738 case CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT; force_move_type = MOVE_FLIGHT; break;
739 case CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT_BACK; force_move_type = MOVE_FLIGHT_BACK; break;
740 case CMSG_FORCE_PITCH_RATE_CHANGE_ACK: move_type = MOVE_PITCH_RATE; force_move_type = MOVE_PITCH_RATE; break;
741 default:
742 LOG_ERROR("network.opcode", "WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: {}", opcode);
743 return;
744 }
745
746 sScriptMgr->AnticheatSetUnderACKmount(_player);
747
748 SpeedOpcodePair const& speedOpcodes = SetSpeed2Opc_table[move_type];
749 WorldPacket data(speedOpcodes[static_cast<size_t>(SpeedOpcodeIndex::ACK_RESPONSE)], 18);
750 WriteMovementInfo(&data, &movementInfo);
751 data << newspeed;
752 mover->SendMessageToSet(&data, _player);
753
754 // skip all forced speed changes except last and unexpected
755 // in run/mounted case used one ACK and it must be skipped.m_forced_speed_changes[MOVE_RUN} store both.
756 if (_player->m_forced_speed_changes[force_move_type] > 0)
757 {
758 --_player->m_forced_speed_changes[force_move_type];
759 if (_player->m_forced_speed_changes[force_move_type] > 0)
760 return;
761 }
762
763 if (!_player->GetTransport() && std::fabs(_player->GetSpeed(move_type) - newspeed) > 0.01f)
764 {
765 if (_player->GetSpeed(move_type) > newspeed) // must be greater - just correct
766 {
767 LOG_ERROR("network.opcode", "{}SpeedChange player {} is NOT correct (must be {} instead {}), force set to correct value",
768 move_type_name[move_type], _player->GetName(), _player->GetSpeed(move_type), newspeed);
769 _player->SetSpeed(move_type, _player->GetSpeedRate(move_type), true);
770 }
771 else // must be lesser - cheating
772 {
773 LOG_INFO("network.opcode", "Player {} from account id {} kicked for incorrect speed (must be {} instead {})",
774 _player->GetName(), GetAccountId(), _player->GetSpeed(move_type), newspeed);
775 KickPlayer("Incorrect speed");
776 }
777 }
778}
#define MAX_MOVE_TYPE
Definition UnitDefines.h:367
UnitMoveType
Definition UnitDefines.h:355
@ MOVE_FLIGHT
Definition UnitDefines.h:362
@ MOVE_SWIM
Definition UnitDefines.h:359
@ MOVE_TURN_RATE
Definition UnitDefines.h:361
@ MOVE_FLIGHT_BACK
Definition UnitDefines.h:363
@ MOVE_SWIM_BACK
Definition UnitDefines.h:360
@ MOVE_RUN
Definition UnitDefines.h:357
@ MOVE_PITCH_RATE
Definition UnitDefines.h:364
@ MOVE_RUN_BACK
Definition UnitDefines.h:358
@ MOVE_WALK
Definition UnitDefines.h:356
const Opcodes SpeedOpcodePair[static_cast< size_t >(SpeedOpcodeIndex::MAX)]
Definition Unit.h:650
SpeedOpcodePair SetSpeed2Opc_table[MAX_MOVE_TYPE]
Definition Unit.h:651
uint8 m_forced_speed_changes[MAX_MOVE_TYPE]
Definition Player.h:2449
float GetSpeed(UnitMoveType mtype) const
Definition Unit.cpp:11047
float GetSpeedRate(UnitMoveType mtype) const
Definition Unit.h:1743
void SetSpeed(UnitMoveType mtype, float rate, bool forced=false)
Definition Unit.cpp:11052
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:2171
Transport * GetTransport() const
Definition Object.h:701
void WriteMovementInfo(WorldPacket *data, MovementInfo *mi)
Definition WorldSession.cpp:1203
@ 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 GameObjectTemplate const* 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:126
#define MAX_GAMEOBJECT_QUEST_ITEMS
Definition GameObjectData.h:27
std::vector< uint32 > GameObjectQuestItemList
Definition GameObject.h:46
#define MAX_GAMEOBJECT_DATA
Definition SharedDefines.h:1603
@ SMSG_GAMEOBJECT_QUERY_RESPONSE
Definition Opcodes.h:125
Definition GameObjectData.h:677
Definition GameObjectData.h:32
uint32 data[MAX_GAMEOBJECT_DATA]
Definition GameObjectData.h:389
uint32 type
Definition GameObjectData.h:34
std::string unk1
Definition GameObjectData.h:39
struct GameObjectTemplate::@236::@266 raw
std::string name
Definition GameObjectData.h:36
std::string castBarCaption
Definition GameObjectData.h:38
float size
Definition GameObjectData.h:40
uint32 displayId
Definition GameObjectData.h:35
std::string IconName
Definition GameObjectData.h:37

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)
351{
352 ObjectGuid guid;
353 recvPacket >> guid;
354
355 LOG_DEBUG("network", "WORLD: Recvd CMSG_GAMEOBJ_REPORT_USE Message [{}]", guid.ToString());
356
357 // ignore for remote control state
358 if (_player->m_mover != _player)
359 return;
360
361 GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid);
362 if (!go)
363 return;
364
365 // Prevent use of GameObject if it is not selectable. Fixes hack.
367 return;
368
370 return;
371
372 if (go->AI()->GossipHello(_player, true))
373 return;
374
376}
@ ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT
Definition DBCEnums.h:180
@ GO_FLAG_NOT_SELECTABLE
Definition SharedDefines.h:1611
virtual bool GossipHello(Player *, bool)
Definition GameObjectAI.h:54
GameObjectAI * AI() const
Definition GameObject.h:308
bool HasGameObjectFlag(GameObjectFlags flags) const
Definition GameObject.h:218

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

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

Referenced by OpcodeTable::Initialize().

◆ HandleGetChannelMemberCount()

void WorldSession::HandleGetChannelMemberCount ( WorldPacket &  recvPacket)
299{
300 std::string channelName;
301 recvPacket >> channelName;
302
303 LOG_DEBUG("chat.system", "CMSG_GET_CHANNEL_MEMBER_COUNT {} Channel: {}",
304 GetPlayerInfo(), channelName);
306 {
307 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
308 {
309 LOG_DEBUG("chat.system", "SMSG_CHANNEL_MEMBER_COUNT {} Channel: {} Count: {}",
310 GetPlayerInfo(), channelName, channel->GetNumPlayers());
311
312 WorldPacket data(SMSG_CHANNEL_MEMBER_COUNT, channel->GetName().size() + 1 + 4);
313 data << channel->GetName();
314 data << uint8(channel->GetFlags());
315 data << uint32(channel->GetNumPlayers());
316 SendPacket(&data);
317 }
318 }
319}
@ 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)
682{
683 ObjectGuid mailbox;
684 recvData >> mailbox;
685
686 if (!CanOpenMailBox(mailbox))
687 return;
688
689 SendMailList();
690
691 // recalculate m_nextMailDelivereTime and unReadMails
693}
void UpdateNextMailTimeAndUnreads()
Definition PlayerUpdates.cpp:441
bool CanOpenMailBox(ObjectGuid guid)
Definition MailHandler.cpp:39
void SendMailList()
Definition MailHandler.cpp:698

References _player, CanOpenMailBox(), SendMailList(), and Player::UpdateNextMailTimeAndUnreads().

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:162
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:271
@ CHAR_INS_GM_SUBSURVEY
Definition CharacterDatabase.h:272
bool ValidateHyperlinksAndMaybeKick(std::string_view str)
Definition WorldSession.cpp:895

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
121 ChatHandler(nullptr).SendGMText(LANG_COMMAND_TICKETNEW, GetPlayer()->GetName(), ticket->GetId());
122
124 }
125
127 data << uint32(response);
128 SendPacket(&data);
129}
@ LANG_TICKET_REQ
Definition Language.h:1244
@ LANG_COMMAND_TICKETNEW
Definition Language.h:1026
@ 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:255
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:124
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
166 ChatHandler(nullptr).SendGMText(LANG_COMMAND_TICKETPLAYERABANDON, GetPlayer()->GetName(), ticket->GetId());
167
168 sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID());
169 sTicketMgr->SendTicket(this, nullptr);
170 }
171}
@ LANG_COMMAND_TICKETPLAYERABANDON
Definition Language.h:1028

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:1027
@ 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)
140{
141 ObjectGuid guid;
142 recvData >> guid;
143
145 if (!unit)
146 {
147 LOG_DEBUG("network", "WORLD: HandleGossipHelloOpcode - Unit ({}) not found or you can not interact with him.", guid.ToString());
148 return;
149 }
150
151 // xinef: check if we have ANY npc flags
152 if (unit->GetNpcFlags() == UNIT_NPC_FLAG_NONE)
153 return;
154
155 // Check GossipHello conditions - block gossip opening if conditions not met
156 ConditionList gossipConditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_GOSSIP_HELLO, unit->GetEntry());
157 if (!sConditionMgr->IsObjectMeetToConditions(_player, unit, gossipConditions))
158 return;
159
160 // set faction visible if needed
161 if (FactionTemplateEntry const* factionTemplateEntry = sFactionTemplateStore.LookupEntry(unit->GetFaction()))
162 _player->GetReputationMgr().SetVisible(factionTemplateEntry);
163
165 // remove fake death
166 //if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
167 // GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
168
170
171 // Update home position for patrolling NPCs only (prevents drift for stationary NPCs)
174 unit->SetHomePosition(unit->GetPosition());
175
176 // If spiritguide, no need for gossip menu, just put player into resurrect queue
177 if (unit->IsSpiritGuide())
178 {
180 if (bg)
181 {
183 sBattlegroundMgr->SendAreaSpiritHealerQueryOpcode(_player, bg, unit->GetGUID());
184 return;
185 }
186 }
187
188 if (!sScriptMgr->OnGossipHello(_player, unit))
189 {
190 // _player->TalkedToCreature(unit->GetEntry(), unit->GetGUID());
191 _player->PrepareGossipMenu(unit, unit->GetGossipMenuId(), true);
193 }
194 unit->AI()->sGossipHello(_player);
195}
#define sConditionMgr
Definition ConditionMgr.h:296
@ CONDITION_SOURCE_TYPE_GOSSIP_HELLO
Definition ConditionMgr.h:146
std::list< Condition * > ConditionList
Definition ConditionMgr.h:240
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
@ WAYPOINT_MOTION_TYPE
Definition MotionMaster.h:41
@ AURA_INTERRUPT_FLAG_TALK
Definition SpellDefines.h:61
@ UNIT_NPC_FLAG_NONE
Definition UnitDefines.h:321
MovementGeneratorType GetDefaultMovementType() const override
-------—End of Pet responses methods-------—
Definition Creature.h:91
CreatureAI * AI() const
Definition Creature.h:144
uint32 GetGossipMenuId() const
Definition Creature.h:209
MovementGeneratorType GetCurrentMovementGeneratorType() const
Definition MotionMaster.cpp:1085
void SendPreparedGossip(WorldObject *source)
Definition PlayerGossip.cpp:214
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition PlayerGossip.cpp:32
ReputationMgr & GetReputationMgr()
Definition Player.h:2156
void SetVisible(FactionTemplateEntry const *factionTemplateEntry)
Definition ReputationMgr.cpp:461
virtual void sGossipHello(Player *)
Definition UnitAI.h:421
NPCFlags GetNpcFlags() const
Clears emote state (looping emote)
Definition Unit.h:763
MotionMaster * GetMotionMaster()
Definition Unit.h:1761
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition Unit.cpp:5215
bool IsSpiritGuide() const
Definition Unit.h:814
Definition DBCStructure.h:975

References _player, Battleground::AddPlayerToResurrectQueue(), Creature::AI(), AURA_INTERRUPT_FLAG_TALK, CONDITION_SOURCE_TYPE_GOSSIP_HELLO, Player::GetBattleground(), MotionMaster::GetCurrentMovementGeneratorType(), Creature::GetDefaultMovementType(), Object::GetEntry(), Unit::GetFaction(), Creature::GetGossipMenuId(), Object::GetGUID(), Unit::GetMotionMaster(), Unit::GetNpcFlags(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Position::GetPosition(), Player::GetReputationMgr(), Unit::IsSpiritGuide(), LOG_DEBUG, Creature::PauseMovementForInteraction(), Player::PrepareGossipMenu(), Unit::RemoveAurasWithInterruptFlags(), sBattlegroundMgr, sConditionMgr, Player::SendPreparedGossip(), Creature::SetHomePosition(), ReputationMgr::SetVisible(), sFactionTemplateStore, UnitAI::sGossipHello(), sScriptMgr, ObjectGuid::ToString(), UNIT_NPC_FLAG_NONE, and WAYPOINT_MOTION_TYPE.

Referenced by OpcodeTable::Initialize().

◆ HandleGossipSelectOptionOpcode()

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

References _player, Creature::AI(), GameObject::AI(), Map::GetGameObject(), PlayerMenu::GetGossipMenu(), PlayerMenu::GetGossipOptionAction(), PlayerMenu::GetGossipOptionSender(), Object::GetGUID(), GossipMenu::GetItem(), 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(), ByteBuffer::rfinish(), 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:962
@ ERR_REFER_A_FRIEND_DIFFERENT_FACTION
Definition Player.h:965
@ ERR_REFER_A_FRIEND_NO_TARGET
Definition Player.h:968
@ ERR_REFER_A_FRIEND_INSUFFICIENT_GRANTABLE_LEVELS
Definition Player.h:963
@ ERR_REFER_A_FRIEND_NOT_REFERRED_BY
Definition Player.h:961
@ ERR_REFER_A_FRIEND_NOT_IN_GROUP
Definition Player.h:969
@ ERR_REFER_A_FRIEND_GRANT_LEVEL_MAX_I
Definition Player.h:967
@ CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL
Definition WorldConfig.h:205
@ 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)
241{
242 recvData.read_skip<uint32>();
243 Group* group = GetPlayer()->GetGroupInvite();
244
245 if (!group)
246 return;
247
248 // Remove player from invitees in any case
249 group->RemoveInvite(GetPlayer());
250
251 if (GetPlayer()->IsSpectator())
252 {
254 return;
255 }
256
257 if (!sScriptMgr->OnPlayerCanGroupAccept(GetPlayer(), group))
258 return;
259
260 Player* leader = ObjectAccessor::FindConnectedPlayer(group->GetLeaderGUID());
261
262 // Trial accounts cannot join a group whose existing members are above the trial level cap.
264 {
265 if (uint32 trialLevelCap = sWorld->getIntConfig(CONFIG_TRIAL_LEVEL_CAP))
266 {
267 uint8 leaderLevel = leader ? leader->GetLevel() : sCharacterCache->GetCharacterLevelByGuid(group->GetLeaderGUID());
268 if (leaderLevel > trialLevelCap)
269 {
271 return;
272 }
273
274 for (auto const& slot : group->GetMemberSlots())
275 {
276 if (slot.guid == GetPlayer()->GetGUID())
277 continue;
278
279 uint8 memberLevel = 0;
280 if (Player* member = ObjectAccessor::FindConnectedPlayer(slot.guid))
281 memberLevel = member->GetLevel();
282 else
283 memberLevel = sCharacterCache->GetCharacterLevelByGuid(slot.guid);
284
285 if (memberLevel > trialLevelCap)
286 {
288 return;
289 }
290 }
291 }
292 }
293
294 if (group->GetLeaderGUID() == GetPlayer()->GetGUID())
295 {
296 LOG_ERROR("network.opcode", "HandleGroupAcceptOpcode: player {} ({}) tried to accept an invite to his own group",
297 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
298 return;
299 }
300
301 // Group is full
302 if (group->IsFull())
303 {
305 return;
306 }
307
308 // Forming a new group, create it
309 if (!group->IsCreated())
310 {
311 // This can happen if the leader is zoning. To be removed once delayed actions for zoning are implemented
312 if (!leader || leader->IsSpectator())
313 {
314 group->RemoveAllInvites();
315 return;
316 }
317
318 // If we're about to create a group there really should be a leader present
319 ASSERT(leader);
320 group->RemoveInvite(leader);
321 group->Create(leader);
322 sGroupMgr->AddGroup(group);
323 }
324
325 // Everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!!
326 if (!group->AddMember(GetPlayer()))
327 return;
328
329 group->BroadcastGroupUpdate();
330}
#define sGroupMgr
Definition GroupMgr.h:51
@ ERR_INVITE_RESTRICTED
Definition SharedDefines.h:3972
@ ERR_GROUP_FULL
Definition SharedDefines.h:3965
@ CONFIG_TRIAL_LEVEL_CAP
Definition WorldConfig.h:516
@ CONFIG_TRIAL_RESTRICTION_PARTY
Definition WorldConfig.h:513
void RemoveInvite(Player *player)
Definition Group.cpp:386
bool IsSpectator() const
Definition Player.h:2625
Group * GetGroupInvite()
Definition Player.h:2515
void SendPartyResult(PartyOperation operation, std::string const &member, PartyResult res, uint32 val=0)
Definition GroupHandler.cpp:53
@ PARTY_OP_INVITE
Definition WorldSession.h:256

References ASSERT, CONFIG_TRIAL_LEVEL_CAP, CONFIG_TRIAL_RESTRICTION_PARTY, ERR_GROUP_FULL, ERR_INVITE_RESTRICTED, ObjectAccessor::FindConnectedPlayer(), Player::GetGroupInvite(), Object::GetGUID(), Unit::GetLevel(), GetPlayer(), Player::IsSpectator(), IsTrialAccount(), LOG_ERROR, PARTY_OP_INVITE, ByteBuffer::read_skip(), Group::RemoveInvite(), sCharacterCache, SendPartyResult(), sGroupMgr, sScriptMgr, and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleGroupAssistantLeaderOpcode()

void WorldSession::HandleGroupAssistantLeaderOpcode ( WorldPacket &  recvData)
710{
711 Group* group = GetPlayer()->GetGroup();
712 if (!group)
713 return;
714
715 if (!group->IsLeader(GetPlayer()->GetGUID()))
716 return;
717
718 ObjectGuid guid;
719 bool apply;
720 recvData >> guid;
721 recvData >> apply;
722
723 group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_ASSISTANT);
724
725 group->SendUpdate();
726}
@ MEMBER_FLAG_ASSISTANT
Definition Group.h:74
bool IsLeader(ObjectGuid guid) const
Definition Group.cpp:2560
void SendUpdate()
Definition Group.cpp:1871
void SetGroupMemberFlag(ObjectGuid guid, bool apply, GroupMemberFlags flag)
Definition Group.cpp:2621

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

Referenced by OpcodeTable::Initialize().

◆ HandleGroupChangeSubGroupOpcode()

void WorldSession::HandleGroupChangeSubGroupOpcode ( WorldPacket &  recvData)
673{
674 // we will get correct pointer for group here, so we don't have to check if group is BG raid
675 Group* group = GetPlayer()->GetGroup();
676 if (!group)
677 return;
678
679 std::string name;
680 uint8 groupNr;
681 recvData >> name;
682 recvData >> groupNr;
683
684 if (groupNr >= MAX_RAID_SUBGROUPS)
685 return;
686
687 ObjectGuid senderGuid = GetPlayer()->GetGUID();
688 if (!group->IsLeader(senderGuid) && !group->IsAssistant(senderGuid))
689 return;
690
691 if (!group->HasFreeSlotSubGroup(groupNr))
692 return;
693
694 Player* movedPlayer = ObjectAccessor::FindPlayerByName(name, false);
695 ObjectGuid guid;
696 if (movedPlayer)
697 {
698 guid = movedPlayer->GetGUID();
699 }
700 else
701 {
702 CharacterDatabase.EscapeString(name);
703 guid = sCharacterCache->GetCharacterGuidByName(name);
704 }
705
706 group->ChangeMembersGroup(guid, groupNr);
707}
#define MAX_RAID_SUBGROUPS
Definition Group.h:46
void ChangeMembersGroup(ObjectGuid guid, uint8 group)
Definition Group.cpp:2020
bool IsAssistant(ObjectGuid guid) const
Definition Group.cpp:2574
bool HasFreeSlotSubGroup(uint8 subgroup) const
Definition Group.cpp:2598

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)
333{
334 Group* group = GetPlayer()->GetGroupInvite();
335 if (!group)
336 return;
337
338 // Remember leader if online (group pointer will be invalid if group gets disbanded)
340
341 // uninvite, group can be deleted
343
344 if (!leader)
345 return;
346
347 // report
348 WorldPacket data(SMSG_GROUP_DECLINE, GetPlayer()->GetName().length());
349 data << GetPlayer()->GetName();
350 leader->SendDirectMessage(&data);
351}
void UninviteFromGroup()
Definition Player.cpp:2349
@ 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

491{
492 Group* grp = GetPlayer()->GetGroup();
493 Group* grpInvite = GetPlayer()->GetGroupInvite();
494 if (!grp && !grpInvite)
495 return;
496
497 if (_player->InBattleground()) // Do not leave group, give no error. Verified on TBC Classic
498 return;
499
501 /********************/
502
503 // everything's fine, do it
504 if (grp)
505 {
508 }
509 else if (grpInvite && grpInvite->GetLeaderGUID() == GetPlayer()->GetGUID())
510 { // pending group creation being cancelled
512 grpInvite->Disband();
513 }
514}
@ GROUP_REMOVEMETHOD_LEAVE
Definition SharedDefines.h:3845
@ ERR_PARTY_RESULT_OK
Definition SharedDefines.h:3961
void Disband(bool hideDestroy=false)
Definition Group.cpp:915
static void RemoveFromGroup(Group *group, ObjectGuid guid, RemoveMethod method=GROUP_REMOVEMETHOD_DEFAULT, ObjectGuid kicker=ObjectGuid::Empty, char const *reason=nullptr)
Definition Player.cpp:2376
@ PARTY_OP_LEAVE
Definition WorldSession.h:258

References _player, Group::Disband(), ERR_PARTY_RESULT_OK, Player::GetGroup(), Player::GetGroupInvite(), Group::GetLeaderGUID(), GetPlayer(), GROUP_REMOVEMETHOD_LEAVE, Player::InBattleground(), 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
93 {
95 return;
96 }
97
98 if (invitingPlayer->IsSpectator() || invitedPlayer->IsSpectator())
99 {
101 return;
102 }
103
104 // restrict invite to GMs
105 if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !invitingPlayer->IsGameMaster() && invitedPlayer->IsGameMaster())
106 {
108 return;
109 }
110
111 // target has opted out of receiving group invites
112 if (!invitedPlayer->IsAcceptGroupInvites())
113 {
115 return;
116 }
117
118 // can't group with
119 if (!invitingPlayer->IsGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && invitingPlayer->GetTeamId() != invitedPlayer->GetTeamId())
120 {
122 return;
123 }
124 if (invitingPlayer->GetInstanceId() != 0 && invitedPlayer->GetInstanceId() != 0 && invitingPlayer->GetInstanceId() != invitedPlayer->GetInstanceId() && invitingPlayer->GetMapId() == invitedPlayer->GetMapId())
125 {
127 return;
128 }
129
130 if (invitedPlayer->GetSocial()->HasIgnore(invitingPlayer->GetGUID()))
131 {
133 return;
134 }
135
136 if (!invitedPlayer->GetSocial()->HasFriend(invitingPlayer->GetGUID()) && invitingPlayer->GetLevel() < sWorld->getIntConfig(CONFIG_PARTY_LEVEL_REQ))
137 {
139 return;
140 }
141
142 // Battlefield raids (e.g. Wintergrasp) have their composition managed by the BF
143 // system based on queue and team balance. Letting raid members recruit outsiders
144 // bypasses Battlefield::AddOrSetPlayerToCorrectBfGroup, which on WG entry then
145 // refuses to add the invitee because they are already in a BF group.
146 if (Group* invitingGroup = invitingPlayer->GetGroup(); invitingGroup && invitingGroup->isBFGroup())
147 {
149 return;
150 }
151
152 Group* group = invitingPlayer->GetGroup();
153 if (group && group->isBGGroup())
154 group = invitingPlayer->GetOriginalGroup();
155 if (!group)
156 group = invitingPlayer->GetGroupInvite();
157
158 Group* group2 = invitedPlayer->GetGroup();
159 if (group2 && group2->isBGGroup())
160 group2 = invitedPlayer->GetOriginalGroup();
161 // player already in another group or invited
162 if (group2 || invitedPlayer->GetGroupInvite())
163 {
165
166 if (group2)
167 {
168 // tell the player that they were invited but it failed as they were already in a group
169 WorldPacket data(SMSG_GROUP_INVITE, 25); // guess size
170 data << uint8(0); // invited/already in group flag
171 data << invitingPlayer->GetName(); // max len 48
172 data << uint32(0); // unk
173 data << uint8(0); // count
174 data << uint32(0); // unk
175 invitedPlayer->SendDirectMessage(&data);
176 }
177
178 return;
179 }
180
181 if (group)
182 {
183 // not have permissions for invite
184 if (!group->IsLeader(invitingPlayer->GetGUID()) && !group->IsAssistant(invitingPlayer->GetGUID()))
185 {
187 return;
188 }
189 // not have place
190 if (group->IsFull())
191 {
193 return;
194 }
195 }
196
197 // xinef: if player has no group, check group invite
198 if (!group && invitingPlayer->GetGroupInvite() && invitingPlayer->GetGroupInvite()->GetLeaderGUID() == invitingPlayer->GetGUID())
199 group = invitingPlayer->GetGroupInvite();
200
201 // ok, but group not exist, start a new group
202 // but don't create and save the group to the DB until
203 // at least one person joins
204 if (!group)
205 {
206 group = new Group();
207 // new group: if can't add then delete
208 if (!group->AddLeaderInvite(invitingPlayer))
209 {
210 delete group;
211 return;
212 }
213 if (!group->AddInvite(invitedPlayer))
214 {
215 delete group;
216 return;
217 }
218 }
219 else
220 {
221 // already existed group: if can't add then just leave
222 if (!group->AddInvite(invitedPlayer))
223 {
224 return;
225 }
226 }
227
228 // ok, we do it
229 WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size
230 data << uint8(1); // invited/already in group flag
231 data << invitingPlayer->GetName(); // max len 48
232 data << uint32(0); // unk
233 data << uint8(0); // count
234 data << uint32(0); // unk
235 invitedPlayer->SendDirectMessage(&data);
236
238}
@ ERR_ALREADY_IN_GROUP_S
Definition SharedDefines.h:3966
@ ERR_TARGET_NOT_IN_INSTANCE_S
Definition SharedDefines.h:3964
@ ERR_IGNORING_YOU_S
Definition SharedDefines.h:3970
@ ERR_NOT_LEADER
Definition SharedDefines.h:3968
@ ERR_PLAYER_WRONG_FACTION
Definition SharedDefines.h:3969
@ ERR_BAD_PLAYER_NAME_S
Definition SharedDefines.h:3962
@ CONFIG_ALLOW_GM_GROUP
Definition WorldConfig.h:45
@ CONFIG_PARTY_LEVEL_REQ
Definition WorldConfig.h:252
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP
Definition WorldConfig.h:35
bool AddLeaderInvite(Player *player)
Definition Group.cpp:376
bool isBGGroup() const
Definition Group.cpp:2495
bool AddInvite(Player *player)
Definition Group.cpp:355
bool IsFull() const
Definition Group.cpp:2479
bool HasFriend(ObjectGuid const &friend_guid) const
Definition SocialMgr.cpp:189
bool IsAcceptGroupInvites() const
Definition Player.h:1176
Group * GetOriginalGroup()
Definition Player.h:2532
uint32 GetInstanceId() const
Definition Object.h:520
@ 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, CONFIG_TRIAL_RESTRICTION_PARTY, 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(), Player::IsAcceptGroupInvites(), Group::IsAssistant(), Group::isBGGroup(), Group::IsFull(), Player::IsGameMaster(), Group::IsLeader(), Player::IsSpectator(), IsTrialAccount(), 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

648{
649 Group* group = GetPlayer()->GetGroup();
650 if (!group)
651 return;
652
653 if (_player->InBattleground())
654 return;
655
657 if (group->CheckLevelForRaid())
658 {
660 return;
661 }
662
663 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!
664 return;
665 /********************/
666
667 // everything's fine, do it (is it 0 (PARTY_OP_INVITE) correct code)
669 group->ConvertToRaid();
670}
@ ERR_RAID_DISALLOWED_BY_LEVEL
Definition SharedDefines.h:3984
bool CheckLevelForRaid()
Definition Group.cpp:317
bool isLFGGroup(bool restricted=false) const
Definition Group.cpp:2484
void ConvertToRaid()
Definition Group.cpp:327

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)
472{
473 ObjectGuid guid;
474 recvData >> guid;
475
477 Group* group = GetPlayer()->GetGroup();
478
479 if (!group || !player)
480 return;
481
482 if (!group->IsLeader(GetPlayer()->GetGUID()) || player->GetGroup() != group || guid == GetPlayer()->GetGUID())
483 return;
484
485 // Everything's fine, accepted.
486 group->ChangeLeader(guid);
487 group->SendUpdate();
488}
void ChangeLeader(ObjectGuid guid)
Definition Group.cpp:778

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

Referenced by OpcodeTable::Initialize().

◆ HandleGroupSwapSubGroupOpcode()

void WorldSession::HandleGroupSwapSubGroupOpcode ( WorldPacket &  recvData)
1155{
1156 std::string playerName1, playerName2;
1157
1158 // first = moved from, second = moved to
1159 recv_data >> playerName1;
1160 recv_data >> playerName2;
1161
1162 if (!normalizePlayerName(playerName1))
1163 {
1165 return;
1166 }
1167 if (!normalizePlayerName(playerName2))
1168 {
1170 return;
1171 }
1172
1173 Group* group = GetPlayer()->GetGroup();
1174 if (!group || !group->isRaidGroup())
1175 {
1176 return;
1177 }
1178
1179 if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
1180 {
1181 return;
1182 }
1183
1184 //get guid, member may be offline
1185 auto getGuid = [&group](std::string const& playerName)
1186 {
1187 // no player, cheating?
1188 if (!group->GetMemberGUID(playerName))
1189 {
1190 return ObjectGuid::Empty;
1191 }
1192
1193 if (Player* player = ObjectAccessor::FindPlayerByName(playerName.c_str()))
1194 {
1195 return player->GetGUID();
1196 }
1197 else
1198 {
1199 if (ObjectGuid guid = sCharacterCache->GetCharacterGuidByName(playerName))
1200 {
1201 return guid;
1202 }
1203 else
1204 {
1205 return ObjectGuid::Empty; // no player - again, cheating?
1206 }
1207 }
1208 };
1209
1210 ObjectGuid guid1 = getGuid(playerName1);
1211 ObjectGuid guid2 = getGuid(playerName2);
1212
1213 if (!guid1 || !guid2)
1214 {
1216 return;
1217 }
1218
1219 uint8 groupId1 = group->GetMemberGroup(guid1);
1220 uint8 groupId2 = group->GetMemberGroup(guid2);
1221
1222 if (groupId1 == MAX_RAID_SUBGROUPS + 1 || groupId2 == MAX_RAID_SUBGROUPS + 1)
1223 {
1224 return;
1225 }
1226
1227 if (groupId1 == groupId2)
1228 {
1229 return;
1230 }
1231
1232 group->ChangeMembersGroup(guid1, groupId2);
1233 group->ChangeMembersGroup(guid2, groupId1);
1234}
@ ERR_GROUP_SWAP_FAILED
Definition SharedDefines.h:3973
uint8 GetMemberGroup(ObjectGuid guid) const
Definition Group.cpp:2603
ObjectGuid GetMemberGUID(std::string const &name)
Definition Group.cpp:2565
bool isRaidGroup() const
Definition Group.cpp:2490
@ PARTY_OP_SWAP
Definition WorldSession.h:259

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)
354{
355 ObjectGuid guid;
356 std::string reason, name;
357 recvData >> guid;
358 recvData >> reason;
359
360 //can't uninvite yourself
361 if (guid == GetPlayer()->GetGUID())
362 {
363 LOG_ERROR("network.opcode", "WorldSession::HandleGroupUninviteGuidOpcode: leader {} ({}) tried to uninvite himself from the group.",
364 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
365 return;
366 }
367
368 sCharacterCache->GetCharacterNameByGuid(guid, name);
369
371 if (res != ERR_PARTY_RESULT_OK)
372 {
374 {
375 if (Player* kickTarget = ObjectAccessor::FindConnectedPlayer(guid))
376 {
377 if (Aura* dungeonCooldownAura = kickTarget->GetAura(lfg::LFG_SPELL_DUNGEON_COOLDOWN))
378 {
379 int32 elapsedTime = dungeonCooldownAura->GetMaxDuration() - dungeonCooldownAura->GetDuration();
380 if (static_cast<int32>(sWorld->getIntConfig(CONFIG_LFG_KICK_PREVENTION_TIMER)) > elapsedTime)
381 {
382 SendPartyResult(PARTY_OP_UNINVITE, name, res, (sWorld->getIntConfig(CONFIG_LFG_KICK_PREVENTION_TIMER) - elapsedTime) / 1000);
383 }
384 }
385 }
386 } else
387 {
389 }
390
391 return;
392 }
393
394 Group* grp = GetPlayer()->GetGroup();
395 if (!grp)
396 return;
397
398 // Xinef: do not allow to kick with empty reason, this will resend packet with given reason
399 if (grp->isLFGGroup(true) && reason.empty())
400 {
402 return;
403 }
404
405 if (grp->IsLeader(guid) && !grp->isLFGGroup(true))
406 {
408 return;
409 }
410
411 if (grp->IsMember(guid))
412 {
413 Player::RemoveFromGroup(grp, guid, GROUP_REMOVEMETHOD_KICK, GetPlayer()->GetGUID(), reason.c_str());
414 return;
415 }
416
417 if (Player* player = grp->GetInvited(guid))
418 {
419 player->UninviteFromGroup();
420 return;
421 }
422
424}
@ GROUP_REMOVEMETHOD_KICK
Definition SharedDefines.h:3844
PartyResult
Definition SharedDefines.h:3960
@ ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S
Definition SharedDefines.h:3983
@ ERR_VOTE_KICK_REASON_NEEDED
Definition SharedDefines.h:3986
@ ERR_TARGET_NOT_IN_GROUP_S
Definition SharedDefines.h:3963
@ CONFIG_LFG_KICK_PREVENTION_TIMER
Definition WorldConfig.h:388
Definition SpellAuras.h:88
Player * GetInvited(ObjectGuid guid) const
Definition Group.cpp:407
bool IsMember(ObjectGuid guid) const
Definition Group.cpp:2555
PartyResult CanUninviteFromGroup(ObjectGuid targetPlayerGUID=ObjectGuid::Empty) const
Definition Player.cpp:13334
@ PARTY_OP_UNINVITE
Definition WorldSession.h:257
@ LFG_SPELL_DUNGEON_COOLDOWN
Definition LFGMgr.h:53

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)
427{
428 std::string membername;
429 recvData >> membername;
430
431 // player not found
432 if (!normalizePlayerName(membername))
433 return;
434
435 // can't uninvite yourself
436 if (GetPlayer()->GetName() == membername)
437 {
438 LOG_ERROR("network.opcode", "WorldSession::HandleGroupUninviteOpcode: leader {} ({}) tried to uninvite himself from the group.",
439 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
440 return;
441 }
442
443 Group* grp = GetPlayer()->GetGroup();
444 if (!grp)
445 {
446 return;
447 }
448
449 PartyResult res = GetPlayer()->CanUninviteFromGroup(grp->GetMemberGUID(membername));
450 if (res != ERR_PARTY_RESULT_OK)
451 {
453 return;
454 }
455
456 if (ObjectGuid guid = grp->GetMemberGUID(membername))
457 {
459 return;
460 }
461
462 if (Player* player = grp->GetInvited(membername))
463 {
464 player->UninviteFromGroup();
465 return;
466 }
467
469}

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)
60{
61 LOG_DEBUG("guild", "CMSG_GUILD_ACCEPT [{}]", GetPlayer()->GetName());
62
64 {
68 return;
69 }
70
71 if (!GetPlayer()->GetGuildId())
72 if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildIdInvited()))
73 guild->HandleAcceptMember(this);
74}
@ GUILD_COMMAND_INVITE
Definition Guild.h:100
@ ERR_GUILD_PERMISSIONS
Definition Guild.h:128
@ CONFIG_TRIAL_RESTRICTION_GUILD
Definition WorldConfig.h:514
static void SendCommandResult(WorldSession *session, GuildCommandType type, GuildCommandError errCode, std::string_view param={})
Definition Guild.cpp:115
void SetGuildIdInvited(uint32 GuildId)
Definition Player.h:1928
void SetInGuild(uint32 GuildId)
Definition Player.h:1920

References CONFIG_TRIAL_RESTRICTION_GUILD, ERR_GUILD_PERMISSIONS, GetPlayer(), GUILD_COMMAND_INVITE, IsTrialAccount(), LOG_DEBUG, Guild::SendCommandResult(), Player::SetGuildIdInvited(), Player::SetInGuild(), sGuildMgr, and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildAddRankOpcode()

void WorldSession::HandleGuildAddRankOpcode ( WorldPackets::Guild::GuildAddRank &  packet)
210{
211 LOG_DEBUG("guild", "CMSG_GUILD_ADD_RANK [{}]: Rank: {}", GetPlayerInfo(), packet.Name);
212
213 if (Guild* guild = GetPlayer()->GetGuild())
214 guild->HandleAddNewRank(this, packet.Name);
215}
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)
370{
371 LOG_DEBUG("guild", "CMSG_GUILD_BANK_BUY_TAB [{}]: [{}[, TabId: {}", GetPlayerInfo(), packet.Banker .ToString(), packet.BankTab);
372
373 if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
374 if (Guild* guild = GetPlayer()->GetGuild())
375 guild->HandleBuyBankTab(this, packet.BankTab);
376}
@ GAMEOBJECT_TYPE_GUILD_BANK
Definition SharedDefines.h:1598
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)
311{
312 LOG_DEBUG("guild", "CMSG_GUILD_BANK_DEPOSIT_MONEY [{}]: Go: [{}], money: {}",
313 GetPlayerInfo(), packet.Banker.ToString(), packet.Money);
314
315 if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
316 if (packet.Money && GetPlayer()->HasEnoughMoney(packet.Money))
317 if (Guild* guild = GetPlayer()->GetGuild())
318 guild->HandleMemberDepositMoney(this, packet.Money);
319}
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)
281{
282 LOG_DEBUG("guild", "CMSG_GUILD_BANKER_ACTIVATE [{}]: Go: [{}] AllSlots: {}"
283 , GetPlayerInfo(), packet.Banker.ToString(), packet.FullUpdate);
284
286 if (!go)
287 return;
288
289 Guild* const guild = GetPlayer()->GetGuild();
290 if (!guild)
291 {
293 return;
294 }
295
296 guild->SendBankTabsInfo(this, packet.FullUpdate);
297}
@ 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:1872
Guild * GetGuild() const
Definition Player.cpp:16383
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)
390{
391 LOG_DEBUG("guild", "MSG_GUILD_BANK_LOG_QUERY [{}]: TabId: {}", GetPlayerInfo(), packet.Tab);
392
393 if (Guild* guild = GetPlayer()->GetGuild())
394 guild->SendBankLog(this, packet.Tab);
395}
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)
266{
267 LOG_DEBUG("guild", "MSG_GUILD_BANK_MONEY_WITHDRAWN [{}]", GetPlayerInfo());
268
269 if (Guild* guild = GetPlayer()->GetGuild())
270 guild->SendMoneyInfo(this);
271}

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

Referenced by OpcodeTable::Initialize().

◆ HandleGuildBankQueryTab()

void WorldSession::HandleGuildBankQueryTab ( WorldPackets::Guild::GuildBankQueryTab &  packet)
301{
302 LOG_DEBUG("guild", "CMSG_GUILD_BANK_QUERY_TAB [{}]: Go: [{}], TabId: {}, ShowTabs: {}"
303 , GetPlayerInfo(), packet.Banker.ToString(), packet.Tab, packet.FullUpdate);
304
305 if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
306 if (Guild* guild = GetPlayer()->GetGuild())
307 guild->SendBankTabData(this, packet.Tab, packet.FullUpdate);
308}
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)
331{
332 if (!GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
333 {
334 return;
335 }
336
337 Guild* guild = GetPlayer()->GetGuild();
338 if (!guild)
339 {
340 return;
341 }
342
343 if (packet.BankOnly)
344 guild->SwapItems(GetPlayer(), packet.BankTab1, packet.BankSlot1, packet.BankTab, packet.BankSlot, packet.BankItemCount);
345 else
346 {
347 uint8 playerBag = NULL_BAG;
348 uint8 playerSlotId = NULL_SLOT;
349 uint8 toChar = 1;
350 uint32 splitedAmount = 0;
351
352 if (!packet.AutoStore)
353 {
354 playerBag = packet.ContainerSlot;
355 playerSlotId = packet.ContainerItemSlot;
356 toChar = packet.ToSlot;
357 splitedAmount = packet.StackCount;
358 }
359
360 // Player <-> Bank
361 // Allow to work with inventory only
362 if (!Player::IsInventoryPos(playerBag, playerSlotId) && !(playerBag == NULL_BAG && playerSlotId == NULL_SLOT))
364 else
365 guild->SwapItemsWithInventory(GetPlayer(), toChar != 0, packet.BankTab, packet.BankSlot, playerBag, playerSlotId, splitedAmount);
366 }
367}
void SwapItemsWithInventory(Player *player, bool toChar, uint8 tabId, uint8 slotId, uint8 playerBag, uint8 playerSlotId, uint32 splitedAmount)
Definition Guild.cpp:2412
void SwapItems(Player *player, uint8 tabId, uint8 slotId, uint8 destTabId, uint8 destSlotId, uint32 splitedAmount)
Definition Guild.cpp:2398
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)
379{
380 LOG_DEBUG("guild", "CMSG_GUILD_BANK_UPDATE_TAB [{}]: Go: [{}], TabId: {}, Name: {}, Icon: {}"
381 , GetPlayerInfo(), packet.Banker.ToString(), packet.BankTab, packet.Name, packet.Icon);
382
383 if (!packet.Name.empty() && !packet.Icon.empty())
384 if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
385 if (Guild* guild = GetPlayer()->GetGuild())
386 guild->HandleSetBankTabInfo(this, packet.BankTab, packet.Name, packet.Icon);
387}
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)
322{
323 LOG_DEBUG("guild", "CMSG_GUILD_BANK_WITHDRAW_MONEY [{}]: Go: [{}], money: {}",
324 GetPlayerInfo(), packet.Banker.ToString(), packet.Money);
325 if (packet.Money && GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
326 if (Guild* guild = GetPlayer()->GetGuild())
327 guild->HandleMemberWithdrawMoney(this, packet.Money);
328}
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)
226{
227 LOG_DEBUG("guild", "CMSG_GUILD_INFO_TEXT [{}]: {}", GetPlayerInfo(), packet.InfoText);
228
229 if (Guild* guild = GetPlayer()->GetGuild())
230 guild->HandleSetInfo(this, packet.InfoText);
231}
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)
38{
39 LOG_ERROR("network.opcode", "CMSG_GUILD_CREATE: Possible hacking-attempt: {} tried to create a guild [Name: {}] using cheats", GetPlayerInfo(), packet.GuildName);
40}
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)
77{
78 LOG_DEBUG("guild", "CMSG_GUILD_DECLINE [{}]", GetPlayerInfo());
79
80 if (GetPlayer()->GetGuild())
81 {
82 return;
83 }
84
87}

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

Referenced by OpcodeTable::Initialize().

◆ HandleGuildDelRankOpcode()

void WorldSession::HandleGuildDelRankOpcode ( WorldPackets::Guild::GuildDeleteRank &  packet)
218{
219 LOG_DEBUG("guild", "CMSG_GUILD_DEL_RANK [{}]", GetPlayerInfo());
220
221 if (Guild* guild = GetPlayer()->GetGuild())
222 guild->HandleRemoveLowestRank(this);
223}

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

Referenced by OpcodeTable::Initialize().

◆ HandleGuildDemoteOpcode()

void WorldSession::HandleGuildDemoteOpcode ( WorldPackets::Guild::GuildDemoteMember &  demote)
117{
118 LOG_DEBUG("guild", "CMSG_GUILD_DEMOTE [{}]: Target: {}", GetPlayerInfo(), demote.Demotee);
119
120 if (normalizePlayerName(demote.Demotee))
121 if (Guild* guild = GetPlayer()->GetGuild())
122 guild->HandleUpdateMemberRank(this, demote.Demotee, true);
123}
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)
134{
135 LOG_DEBUG("guild", "CMSG_GUILD_DISBAND [{}]", GetPlayerInfo());
136
137 if (Guild* guild = GetPlayer()->GetGuild())
138 guild->HandleDisband(this);
139}

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

Referenced by OpcodeTable::Initialize().

◆ HandleGuildEventLogQueryOpcode()

void WorldSession::HandleGuildEventLogQueryOpcode ( WorldPackets::Guild::GuildEventLogQuery &  packet)
258{
259 LOG_DEBUG("guild", "MSG_GUILD_EVENT_LOG_QUERY [{}]", GetPlayerInfo());
260
261 if (Guild* guild = GetPlayer()->GetGuild())
262 guild->SendEventLog(this);
263}

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

Referenced by OpcodeTable::Initialize().

◆ HandleGuildInfoOpcode()

void WorldSession::HandleGuildInfoOpcode ( WorldPackets::Guild::GuildGetInfo &  packet)
90{
91 LOG_DEBUG("guild", "CMSG_GUILD_INFO [{}]", GetPlayerInfo());
92
93 if (Guild* guild = GetPlayer()->GetGuild())
94 guild->SendInfo(this);
95}

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

Referenced by OpcodeTable::Initialize().

◆ HandleGuildInviteOpcode()

void WorldSession::HandleGuildInviteOpcode ( WorldPackets::Guild::GuildInviteByName &  packet)
43{
44 LOG_DEBUG("guild", "CMSG_GUILD_INVITE [{}]: Invited: {}", GetPlayerInfo(), packet.Name);
45 if (normalizePlayerName(packet.Name))
46 if (Guild* guild = GetPlayer()->GetGuild())
47 guild->HandleInviteMember(this, packet.Name);
48}
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)
142{
143 LOG_DEBUG("guild", "CMSG_GUILD_LEADER [{}]: Target: {}", GetPlayerInfo(), packet.NewMasterName);
144
146 if (Guild* guild = GetPlayer()->GetGuild())
147 guild->HandleSetLeader(this, packet.NewMasterName);
148}
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)
126{
127 LOG_DEBUG("guild", "CMSG_GUILD_LEAVE [{}]", GetPlayerInfo());
128
129 if (Guild* guild = GetPlayer()->GetGuild())
130 guild->HandleLeaveMember(this);
131}

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

Referenced by OpcodeTable::Initialize().

◆ HandleGuildMOTDOpcode()

void WorldSession::HandleGuildMOTDOpcode ( WorldPackets::Guild::GuildUpdateMotdText &  packet)
151{
152 LOG_DEBUG("guild", "CMSG_GUILD_MOTD [{}]: MOTD: {}", GetPlayerInfo(), packet.MotdText);
153
154 if (Guild* guild = GetPlayer()->GetGuild())
155 guild->HandleSetMOTD(this, packet.MotdText);
156}
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)
274{
275 if (Guild* guild = GetPlayer()->GetGuild())
276 guild->SendPermissions(this);
277}

References GetPlayer().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildPromoteOpcode()

void WorldSession::HandleGuildPromoteOpcode ( WorldPackets::Guild::GuildPromoteMember &  promote)
108{
109 LOG_DEBUG("guild", "CMSG_GUILD_PROMOTE [{}]: Target: {}", GetPlayerInfo(), promote.Promotee);
110
111 if (normalizePlayerName(promote.Promotee))
112 if (Guild* guild = GetPlayer()->GetGuild())
113 guild->HandleUpdateMemberRank(this, promote.Promotee, false);
114}
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)
28{
29 LOG_DEBUG("guild", "CMSG_GUILD_QUERY [{}]: Guild: {}", GetPlayerInfo(), query.GuildId);
30 if (!query.GuildId)
31 return;
32
33 if (Guild* guild = sGuildMgr->GetGuildById(query.GuildId))
34 guild->HandleQuery(this);
35}
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)
178{
179 Guild* guild = GetPlayer()->GetGuild();
180 if (!guild)
181 {
182 return;
183 }
184
185 std::array<GuildBankRightsAndSlots, GUILD_BANK_MAX_TABS> rightsAndSlots;
186
187 for (uint8 tabId = 0; tabId < GUILD_BANK_MAX_TABS; ++tabId)
188 {
189 // For some reason the client is sending - 1 for guildmaster tab withdraw item limit, that's ilegal for us because we expect unsigned int.
190 // Probably core handling for this should be changed.
191 if (packet.TabWithdrawItemLimit[tabId] <= 0)
192 {
194 }
195 rightsAndSlots[tabId] = GuildBankRightsAndSlots(tabId, uint8(packet.TabFlags[tabId]), packet.TabWithdrawItemLimit[tabId]);
196 }
197
198 LOG_DEBUG("guild", "CMSG_GUILD_RANK [{}]: Rank: {} ({})", GetPlayerInfo(), packet.RankName, packet.RankID);
199
200 // Same as the issue above but this time with rights.
201 if (packet.Flags <= 0)
202 {
204 }
205
206 guild->HandleSetRankInfo(this, packet.RankID, packet.RankName, packet.Flags, packet.WithdrawGoldLimit, rightsAndSlots);
207}
@ 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:266
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:1396
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)
51{
52 LOG_DEBUG("guild", "CMSG_GUILD_REMOVE [{}]: Target: {}", GetPlayerInfo(), packet.Removee);
53
54 if (normalizePlayerName(packet.Removee))
55 if (Guild* guild = GetPlayer()->GetGuild())
56 guild->HandleRemoveMember(this, packet.Removee);
57}
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)
98{
99 LOG_DEBUG("guild", "CMSG_GUILD_ROSTER [{}]", GetPlayerInfo());
100
101 if (Guild* guild = GetPlayer()->GetGuild())
102 guild->HandleRoster(this);
103 else
105}
@ 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)
168{
169 LOG_DEBUG("guild", "CMSG_GUILD_SET_OFFICER_NOTE [{}]: Target: {}, Note: {}",
170 GetPlayerInfo(), packet.NoteeName, packet.Note);
171
172 if (normalizePlayerName(packet.NoteeName))
173 if (Guild* guild = GetPlayer()->GetGuild())
174 guild->HandleSetMemberNote(this, packet.NoteeName, packet.Note, false);
175}
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)
159{
160 LOG_DEBUG("guild", "CMSG_GUILD_SET_PUBLIC_NOTE [{}]: Target: {}, Note: {}", GetPlayerInfo(), packet.NoteeName, packet.Note);
161
162 if (normalizePlayerName(packet.NoteeName))
163 if (Guild* guild = GetPlayer()->GetGuild())
164 guild->HandleSetMemberNote(this, packet.NoteeName, packet.Note, true);
165}

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)
1687{
1688 if (_player->IsInFlight())
1689 return;
1690
1691 if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
1692 {
1693 bf->PlayerAskToLeave(_player);
1694 return;
1695 }
1696
1697 AreaTableEntry const* atEntry = sAreaTableStore.LookupEntry(_player->GetAreaId());
1698 if (!atEntry || !(atEntry->flags & AREA_FLAG_WINTERGRASP_2))
1699 return;
1700
1702 _player->ResurrectPlayer(1.0f);
1705}
@ AREA_FLAG_WINTERGRASP_2
Definition DBCEnums.h:261
float m_homebindZ
Definition Player.h:2423
uint32 m_homebindMapId
Definition Player.h:2419
float m_homebindY
Definition Player.h:2422
void BuildPlayerRepop()
Definition Player.cpp:4508
float m_homebindX
Definition Player.h:2421
uint32 GetAreaId() const
Definition Object.cpp:3179
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)
65{
67}
@ TRADE_STATUS_IGNORE_YOU
Definition SharedDefines.h:3820

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

Referenced by OpcodeTable::Initialize().

◆ HandleInitiateTradeOpcode()

void WorldSession::HandleInitiateTradeOpcode ( WorldPacket &  recvPacket)
722{
723 ObjectGuid ID;
724 recvPacket >> ID;
725
726 if (GetPlayer()->GetTradeData())
727 return;
728
729 TradeStatusInfo info;
730 if (!GetPlayer()->IsAlive())
731 {
733 SendTradeStatus(info);
734 return;
735 }
736
737 if (GetPlayer()->HasUnitState(UNIT_STATE_STUNNED))
738 {
740 SendTradeStatus(info);
741 return;
742 }
743
744 if (IsLoggingOut())
745 {
747 SendTradeStatus(info);
748 return;
749 }
750
751 if (GetPlayer()->IsInFlight())
752 {
754 SendTradeStatus(info);
755 return;
756 }
757
758 if (GetPlayer()->GetLevel() < sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ))
759 {
762 SendTradeStatus(info);
763 return;
764 }
765
767 {
769 SendTradeStatus(info);
770 return;
771 }
772
773 if (GetPlayer()->IsSpectator())
774 return;
775
777
778 if (!pOther)
779 {
781 SendTradeStatus(info);
782 return;
783 }
784
785 if (pOther == GetPlayer() || pOther->m_trade)
786 {
788 SendTradeStatus(info);
789 return;
790 }
791
792 if (!pOther->IsAlive())
793 {
795 SendTradeStatus(info);
796 return;
797 }
798
799 if (pOther->IsInFlight())
800 {
802 SendTradeStatus(info);
803 return;
804 }
805
806 if (pOther->HasUnitState(UNIT_STATE_STUNNED))
807 {
809 SendTradeStatus(info);
810 return;
811 }
812
813 if (pOther->GetSession()->IsLoggingOut())
814 {
816 SendTradeStatus(info);
817 return;
818 }
819
820 if (sWorld->getBoolConfig(CONFIG_TRIAL_RESTRICTION_TRADE) && pOther->GetSession()->IsTrialAccount())
821 {
823 SendTradeStatus(info);
824 return;
825 }
826
827 if (pOther->GetTeamId() != _player->GetTeamId() &&
829 {
831 SendTradeStatus(info);
832 return;
833 }
834
835 if (!pOther->IsWithinDistInMap(_player, TRADE_DISTANCE, false))
836 {
838 SendTradeStatus(info);
839 return;
840 }
841
842 if (!sScriptMgr->OnPlayerCanInitTrade(_player, pOther))
843 return;
844
845 // OK start trade
846 _player->m_trade = new TradeData(_player, pOther);
847 pOther->m_trade = new TradeData(pOther, _player);
848
849 // WorldPacket data(SMSG_TRADE_STATUS, 12);
850 // data << uint32(TRADE_STATUS_BEGIN_TRADE);
851 // data << _player->GetGUID();
852 // pOther->SendDirectMessage(&data);
854 info.TraderGuid = _player->GetGUID();
855 pOther->GetSession()->SendTradeStatus(info);
856}
@ LANG_TRADE_REQ
Definition Language.h:1245
@ TRADE_STATUS_YOU_STUNNED
Definition SharedDefines.h:3821
@ TRADE_STATUS_YOU_DEAD
Definition SharedDefines.h:3823
@ TRADE_STATUS_YOU_LOGOUT
Definition SharedDefines.h:3825
@ TRADE_STATUS_TARGET_DEAD
Definition SharedDefines.h:3824
@ TRADE_STATUS_NO_TARGET
Definition SharedDefines.h:3812
@ TRADE_STATUS_TRIAL_ACCOUNT
Definition SharedDefines.h:3827
@ TRADE_STATUS_BEGIN_TRADE
Definition SharedDefines.h:3807
@ TRADE_STATUS_TARGET_LOGOUT
Definition SharedDefines.h:3826
@ TRADE_STATUS_TARGET_STUNNED
Definition SharedDefines.h:3822
@ TRADE_STATUS_WRONG_FACTION
Definition SharedDefines.h:3817
@ UNIT_STATE_STUNNED
Definition UnitDefines.h:176
@ CONFIG_TRADE_LEVEL_REQ
Definition WorldConfig.h:254
@ CONFIG_TRIAL_RESTRICTION_TRADE
Definition WorldConfig.h:511
bool IsLoggingOut() const
Is the user engaged in a log out process?
Definition WorldSession.h:536
@ RBAC_PERM_ALLOW_TWO_SIDE_TRADE
Definition RBAC.h:102
ObjectGuid TraderGuid
Definition Player.h:1066

References _player, CONFIG_TRADE_LEVEL_REQ, CONFIG_TRIAL_RESTRICTION_TRADE, ObjectAccessor::FindPlayer(), Object::GetGUID(), GetPlayer(), Player::GetSession(), Player::GetTeamId(), HasPermission(), Unit::HasUnitState(), Unit::IsAlive(), Unit::IsInFlight(), IsLoggingOut(), IsTrialAccount(), WorldObject::IsWithinDistInMap(), LANG_TRADE_REQ, Player::m_trade, rbac::RBAC_PERM_ALLOW_TWO_SIDE_TRADE, ChatHandler::SendNotification(), SendTradeStatus(), sScriptMgr, TradeStatusInfo::Status, sWorld, TRADE_DISTANCE, TRADE_STATUS_BEGIN_TRADE, TRADE_STATUS_BUSY, TRADE_STATUS_CLOSE_WINDOW, TRADE_STATUS_NO_TARGET, TRADE_STATUS_TARGET_DEAD, TRADE_STATUS_TARGET_LOGOUT, TRADE_STATUS_TARGET_STUNNED, TRADE_STATUS_TARGET_TO_FAR, TRADE_STATUS_TRIAL_ACCOUNT, TRADE_STATUS_WRONG_FACTION, TRADE_STATUS_YOU_DEAD, TRADE_STATUS_YOU_LOGOUT, TRADE_STATUS_YOU_STUNNED, TradeStatusInfo::TraderGuid, 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)
1020{
1021 ObjectGuid guid;
1022 recv_data >> guid;
1023
1024 Player* player = ObjectAccessor::GetPlayer(*_player, guid);
1025 if (!player)
1026 {
1027 LOG_DEBUG("network", "MSG_INSPECT_HONOR_STATS: No player found from {}", guid.ToString());
1028 return;
1029 }
1030
1031 if (!GetPlayer()->IsWithinDistInMap(player, INSPECT_DISTANCE, false))
1032 {
1033 return;
1034 }
1035
1036 if (GetPlayer()->IsValidAttackTarget(player))
1037 {
1038 return;
1039 }
1040
1041 WorldPacket data(MSG_INSPECT_HONOR_STATS, 8 + 1 + 4 * 4);
1042 data << player->GetGUID();
1043 data << uint8(player->GetHonorPoints());
1044 data << uint32(player->GetUInt32Value(PLAYER_FIELD_KILLS));
1048 SendPacket(&data);
1049}
@ 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:2183
@ 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)
978{
979 ObjectGuid guid;
980 recv_data >> guid;
981
982 Player* player = ObjectAccessor::GetPlayer(*_player, guid);
983 if (!player)
984 {
985 LOG_DEBUG("network", "CMSG_INSPECT: No player found from {}", guid.ToString());
986 return;
987 }
988
989 if (!GetPlayer()->IsWithinDistInMap(player, INSPECT_DISTANCE, false))
990 {
991 return;
992 }
993
994 if (GetPlayer()->IsValidAttackTarget(player))
995 {
996 return;
997 }
998
999 uint32 talent_points = 0x47;
1000 uint32 guid_size = player->GetPackGUID().size();
1001 WorldPacket data(SMSG_INSPECT_TALENT, guid_size + 4 + talent_points);
1002 data << player->GetPackGUID();
1003
1004 if (sWorld->getBoolConfig(CONFIG_TALENTS_INSPECTING) || _player->CanBeGameMaster())
1005 {
1006 player->BuildPlayerTalentsInfoData(&data);
1007 }
1008 else
1009 {
1010 data << uint32(0); // unspentTalentPoints
1011 data << uint8(0); // talentGroupCount
1012 data << uint8(0); // talentGroupIndex
1013 }
1014
1015 player->BuildEnchantmentsInfoData(&data);
1016 SendPacket(&data);
1017}
@ CONFIG_TALENTS_INSPECTING
Definition WorldConfig.h:57
std::size_t size() const
Definition ObjectGuid.h:278
void BuildEnchantmentsInfoData(WorldPacket *data)
Definition Player.cpp:14869
bool CanBeGameMaster() const
Definition Player.cpp:2240
void BuildPlayerTalentsInfoData(WorldPacket *data)
Definition Player.cpp:14752
@ SMSG_INSPECT_TALENT
Definition Opcodes.h:1042

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

Referenced by OpcodeTable::Initialize().

◆ HandleInstanceLockResponse()

void WorldSession::HandleInstanceLockResponse ( WorldPackets::Instance::InstanceLockResponse &  packet)
1708{
1710 {
1711 LOG_DEBUG("network.opcode", "InstanceLockResponse: Player {} ({}) tried to bind himself/teleport to graveyard without a pending bind!",
1713 return;
1714 }
1715
1716 if (packet.Accept)
1718 else
1720
1721 _player->SetPendingBind(0, 0);
1722}
bool IsLfgRandomInstance() const
Definition Group.h:331
uint32 GetPendingBind() const
Definition Player.h:2489
bool HasPendingBind() const
Definition Player.h:2488
void RepopAtGraveyard()
Definition Player.cpp:5006
void SetPendingBind(uint32 instanceId, uint32 bindTimer)
Definition Player.h:2487
void BindToInstance()
Definition PlayerStorage.cpp:6689
uint8 Accept
Definition InstancePackets.h:118

References _player, WorldPackets::Instance::InstanceLockResponse::Accept, 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)
1062{
1063 uint32 itemid;
1064 recvData >> itemid;
1065 recvData.read_skip<uint64>(); // guid
1066
1067 LOG_DEBUG("network", "WORLD: CMSG_ITEM_NAME_QUERY {}", itemid);
1068 ItemSetNameEntry const* pName = sObjectMgr->GetItemSetNameEntry(itemid);
1069 if (pName)
1070 {
1071 std::string Name = pName->name;
1073 if (loc_idx >= 0)
1074 if (ItemSetNameLocale const* isnl = sObjectMgr->GetItemSetNameLocale(itemid))
1075 ObjectMgr::GetLocaleString(isnl->Name, loc_idx, Name);
1076
1077 WorldPacket data(SMSG_ITEM_NAME_QUERY_RESPONSE, (4 + Name.size() + 1 + 4));
1078 data << uint32(itemid);
1079 data << Name;
1080 data << uint32(pName->InventoryType);
1081 SendPacket(&data);
1082 }
1083}
@ SMSG_ITEM_NAME_QUERY_RESPONSE
Definition Opcodes.h:739
Definition ItemTemplate.h:842
uint32 InventoryType
Definition ItemTemplate.h:844
std::string name
Definition ItemTemplate.h:843
Definition ItemTemplate.h:848

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:372
uint32 CategoryRecoveryTime
Definition SpellInfo.h:373
@ SMSG_ITEM_QUERY_SINGLE_RESPONSE
Definition Opcodes.h:118
Definition ItemTemplate.h:836
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)
1439{
1440 LOG_DEBUG("network", "WORLD: CMSG_ITEM_REFUND");
1441
1442 Item* item = _player->GetItemByGuid(packet.ItemGuid);
1443 if (!item)
1444 {
1445 LOG_DEBUG("network", "Item refund: item not found!");
1446 return;
1447 }
1448
1449 // Don't try to refund item currently being disenchanted
1450 if (_player->GetLootGUID() == packet.ItemGuid)
1451 return;
1452
1453 GetPlayer()->RefundItem(item);
1454}
void RefundItem(Item *item)
Definition Player.cpp:16053
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)
1425{
1426 LOG_DEBUG("network", "WORLD: CMSG_ITEM_REFUND_INFO");
1427
1428 Item* item = _player->GetItemByGuid(packet.ItemGuid);
1429 if (!item)
1430 {
1431 LOG_DEBUG("network", "Item refund: item not found!");
1432 return;
1433 }
1434
1435 GetPlayer()->SendRefundInfo(item);
1436}
void SendRefundInfo(Item *item)
Definition Player.cpp:15982
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

1462{
1463 ObjectGuid itemGuid;
1464 recvData >> itemGuid;
1465
1466 LOG_DEBUG("network", "CMSG_ITEM_TEXT_QUERY item: {}", itemGuid.ToString());
1467
1468 WorldPacket data(SMSG_ITEM_TEXT_QUERY_RESPONSE, 50); // guess size
1469
1470 if (Item* item = _player->GetItemByGuid(itemGuid))
1471 {
1472 data << uint8(0); // has text
1473 data << itemGuid; // item guid
1474 data << item->GetText();
1475 }
1476 else
1477 {
1478 data << uint8(1); // no text
1479 }
1480
1481 SendPacket(&data);
1482}
@ 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)
26{
27 uint32 channelId;
28 uint8 unknown1, unknown2;
29 std::string channelName, password;
30
31 recvPacket >> channelId >> unknown1 >> unknown2 >> channelName >> password;
32
33 LOG_DEBUG("chat.system", "CMSG_JOIN_CHANNEL {} Channel: {}, unk1: {}, unk2: {}, channel: {}, password: {}", GetPlayerInfo(), channelId, unknown1, unknown2, channelName, password);
34 if (channelId)
35 {
36 ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(channelId);
37 if (!channel)
38 return;
39
40 AreaTableEntry const* zone = sAreaTableStore.LookupEntry(GetPlayer()->GetZoneId());
41 if (!zone || !GetPlayer()->CanJoinConstantChannelInZone(channel, zone))
42 return;
43
44 // Cluster mode rebuilds the localized channel name so nodes agree on it;
45 // stock servers keep the client-supplied name.
46 if (sToCloud9Sidecar->ClusterModeEnabled())
47 {
48 auto const locale = GetSessionDbcLocale();
49 std::string const& zoneName = zone->area_name[locale];
50 std::string const cityName = sObjectMgr->GetAcoreStringForDBCLocale(LANG_CHANNEL_CITY);
51 char const* nameExt = (channel->flags & CHANNEL_DBC_FLAG_CITY_ONLY) ? cityName.c_str() : zoneName.c_str();
52
53 std::array<char, 128> buffer{};
54 if (char const* pattern = channel->pattern[locale])
55 {
56 std::snprintf(buffer.data(), buffer.size(), pattern, nameExt);
57 channelName = buffer.data();
58 }
59 }
60 }
61
62 if (channelName.empty())
63 return;
64
65 if (isdigit(channelName[0]))
66 return;
67
68 if (channelName.size() >= 100 || !DisallowHyperlinksAndMaybeKick(channelName))
69 return;
70
72 if (Channel* channel = cMgr->GetJoinChannel(channelName, channelId))
73 channel->JoinChannel(GetPlayer(), password);
74}
@ CHANNEL_DBC_FLAG_CITY_ONLY
Definition Channel.h:97
DBCStorage< ChatChannelsEntry > sChatChannelsStore(ChatChannelsEntryfmt)
@ LANG_CHANNEL_CITY
Definition Language.h:769
bool DisallowHyperlinksAndMaybeKick(std::string_view str)
Definition WorldSession.cpp:909
Definition DBCStructure.h:670
uint32 flags
Definition DBCStructure.h:672
char const * pattern[16]
Definition DBCStructure.h:673

References AreaTableEntry::area_name, CHANNEL_DBC_FLAG_CITY_ONLY, DisallowHyperlinksAndMaybeKick(), ChatChannelsEntry::flags, ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetSessionDbcLocale(), GetTeamId(), LANG_CHANNEL_CITY, LOG_DEBUG, ChatChannelsEntry::pattern, sAreaTableStore, sChatChannelsStore, sObjectMgr, and sToCloud9Sidecar.

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:14858
void LearnTalent(uint32 talentId, uint32 talentRank, bool command=false)
Definition Player.cpp:14286

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

Referenced by OpcodeTable::Initialize().

◆ HandleLearnPreviewTalentsPet()

void WorldSession::HandleLearnPreviewTalentsPet ( WorldPacket &  recvPacket)
1141{
1142 LOG_DEBUG("network", "CMSG_LEARN_PREVIEW_TALENTS_PET");
1143
1144 ObjectGuid guid;
1145 recvData >> guid;
1146
1147 uint32 talentsCount;
1148 recvData >> talentsCount;
1149
1150 uint32 talentId, talentRank;
1151
1152 // Client has max 24 talents, rounded up : 30
1153 uint32 const MaxTalentsCount = 30;
1154
1155 for (uint32 i = 0; i < talentsCount && i < MaxTalentsCount; ++i)
1156 {
1157 recvData >> talentId >> talentRank;
1158
1159 _player->LearnPetTalent(guid, talentId, talentRank);
1160 }
1161
1163
1164 recvData.rfinish();
1165}
void LearnPetTalent(ObjectGuid petGuid, uint32 talentId, uint32 talentRank)
Definition Player.cpp:14422

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)
77{
78 uint32 unk;
79 std::string channelName;
80 recvPacket >> unk >> channelName;
81
82 LOG_DEBUG("chat.system", "CMSG_LEAVE_CHANNEL {} Channel: {}, unk1: {}",
83 GetPlayerInfo(), channelName, unk);
84 if (channelName.empty())
85 return;
86
88 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
89 channel->LeaveChannel(GetPlayer(), true);
90}

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

Referenced by OpcodeTable::Initialize().

◆ HandleLfgGetStatus()

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

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)
51{
53 (GetPlayer()->GetGroup() && GetPlayer()->GetGroup()->GetLeaderGUID() != GetPlayer()->GetGUID() &&
54 (GetPlayer()->GetGroup()->GetMembersCount() == MAXGROUPSIZE || !GetPlayer()->GetGroup()->isLFGGroup())))
55 return;
56
57 if (packet.Slots.empty())
58 {
59 LOG_DEBUG("lfg", "CMSG_LFG_JOIN {} no dungeons selected", GetPlayerInfo());
60 return;
61 }
62
63 lfg::LfgDungeonSet newDungeons;
64 for (uint32 slot : packet.Slots)
65 {
66 uint32 dungeon = slot & 0x00FFFFFF; // remove the type from the dungeon entry
67 if (sLFGDungeonStore.LookupEntry(dungeon))
68 newDungeons.insert(dungeon);
69 }
70
71 LOG_DEBUG("network", "CMSG_LFG_JOIN [{}] roles: {}, Dungeons: {}, Comment: {}",
72 GetPlayerInfo(), packet.Roles, newDungeons.size(), packet.Comment);
73
74 sLFGMgr->JoinLfg(GetPlayer(), uint8(packet.Roles), newDungeons, packet.Comment);
76}
DBCStorage< LFGDungeonEntry > sLFGDungeonStore(LFGDungeonEntryfmt)
#define MAXGROUPSIZE
Definition Group.h:44
void UpdateLFGChannel()
Definition PlayerUpdates.cpp:469
@ LFG_OPTION_ENABLE_SEASONAL_BOSSES
Definition LFGMgr.h:44
@ LFG_OPTION_ENABLE_DUNGEON_FINDER
Definition LFGMgr.h:42
@ LFG_OPTION_ENABLE_RAID_BROWSER
Definition LFGMgr.h:43
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)
79{
80 Group* group = GetPlayer()->GetGroup();
81 ObjectGuid guid = GetPlayer()->GetGUID();
82 ObjectGuid gguid = group ? group->GetGUID() : guid;
83
84 LOG_DEBUG("network", "CMSG_LFG_LEAVE [{}] in group: {}", guid.ToString(), group ? 1 : 0);
85
86 // Check cheating - only leader can leave the queue
87 if (!group || group->GetLeaderGUID() == guid)
88 {
89 sLFGMgr->LeaveLfg(sLFGMgr->GetState(guid) == lfg::LFG_STATE_RAIDBROWSER ? guid : gguid);
90 sLFGMgr->LeaveAllLfgQueues(guid, true, group ? group->GetGUID() : ObjectGuid::Empty);
91 }
93}
ObjectGuid GetGUID() const
Definition Group.cpp:2525
@ 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)
231{
232 ObjectGuid guid = GetPlayer()->GetGUID();
233 LOG_DEBUG("network", "CMSG_LFG_PARTY_LOCK_INFO_REQUEST [{}]", guid.ToString());
234
235 Group* group = GetPlayer()->GetGroup();
236 if (!group)
237 return;
238
239 // Get the locked dungeons of the other party members
240 lfg::LfgLockPartyMap lockMap;
241 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
242 {
243 Player* plrg = itr->GetSource();
244 if (!plrg)
245 continue;
246
247 ObjectGuid pguid = plrg->GetGUID();
248 if (pguid == guid)
249 continue;
250
251 sLFGMgr->InitializeLockedDungeons(plrg, group); // pussywizard
252 lockMap[pguid] = sLFGMgr->GetLockedDungeons(pguid);
253 }
254
255 uint32 size = 0;
256 for (lfg::LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it)
257 size += 8 + 4 + uint32(it->second.size()) * (4 + 4);
258
259 LOG_DEBUG("network", "SMSG_LFG_PARTY_INFO [{}]", guid.ToString());
260 WorldPacket data(SMSG_LFG_PARTY_INFO, 1 + size);
261 BuildPartyLockDungeonBlock(data, lockMap);
262 SendPacket(&data);
263}
void BuildPartyLockDungeonBlock(WorldPacket &data, lfg::LfgLockPartyMap const &lockMap)
Definition LFGHandler.cpp:40
@ 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)
153{
154 ObjectGuid guid = GetPlayer()->GetGUID();
155 LOG_DEBUG("network", "CMSG_LFG_PLAYER_LOCK_INFO_REQUEST [{}]", guid.ToString());
156
157 // Get Random dungeons that can be done at a certain level and expansion
158 uint8 level = GetPlayer()->GetLevel();
159 lfg::LfgDungeonSet const& randomDungeons =
160 sLFGMgr->GetRandomAndSeasonalDungeons(level, GetPlayer()->GetSession()->Expansion());
161
162 // Get player locked Dungeons
163 sLFGMgr->InitializeLockedDungeons(GetPlayer(), GetPlayer()->GetGroup()); // pussywizard
164 lfg::LfgLockMap const& lock = sLFGMgr->GetLockedDungeons(guid);
165 uint32 rsize = uint32(randomDungeons.size());
166 uint32 lsize = uint32(lock.size());
167
168 LOG_DEBUG("network", "SMSG_LFG_PLAYER_INFO [{}]", guid.ToString());
169 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));
170
171 data << uint8(randomDungeons.size()); // Random Dungeon count
172 for (lfg::LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it)
173 {
174 data << uint32(*it); // Dungeon Entry (id + type)
175 lfg::LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level);
176 Quest const* quest = nullptr;
177 bool done = false;
178 if (reward)
179 {
180 quest = sObjectMgr->GetQuestTemplate(reward->firstQuest);
181 if (quest)
182 {
183 done = !GetPlayer()->CanRewardQuest(quest, false);
184 if (done)
185 quest = sObjectMgr->GetQuestTemplate(reward->otherQuest);
186 }
187 }
188
189 if (quest)
190 {
191 uint8 playerLevel = GetPlayer() ? GetPlayer()->GetLevel() : 0;
192 uint8 playerLevelForXP = playerLevel;
193 sScriptMgr->OnPlayerBeforeGetLevelForXPGain(GetPlayer(), playerLevelForXP);
194
195 data << uint8(done);
196 data << uint32(quest->GetRewOrReqMoney(playerLevel));
197 if (playerLevelForXP < GetPlayer()->GetUInt32Value(PLAYER_FIELD_MAX_LEVEL))
198 data << uint32(quest->XPValue(playerLevelForXP));
199 else
200 data << uint32(0);
201 data << uint32(0);
202 data << uint32(0);
203 data << uint8(quest->GetRewItemsCount());
204 if (quest->GetRewItemsCount())
205 {
206 for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
207 if (uint32 itemId = quest->RewardItemId[i])
208 {
209 ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId);
210 data << uint32(itemId);
211 data << uint32(item ? item->DisplayInfoID : 0);
212 data << uint32(quest->RewardItemIdCount[i]);
213 }
214 }
215 }
216 else
217 {
218 data << uint8(0);
219 data << uint32(0);
220 data << uint32(0);
221 data << uint32(0);
222 data << uint32(0);
223 data << uint8(0);
224 }
225 }
226 BuildPlayerLockDungeonBlock(data, lock);
227 SendPacket(&data);
228}
void BuildPlayerLockDungeonBlock(WorldPacket &data, lfg::LfgLockMap const &lock)
Definition LFGHandler.cpp:30
#define QUEST_REWARDS_COUNT
Definition QuestDef.h:39
@ PLAYER_FIELD_MAX_LEVEL
Definition UpdateFields.h:384
bool CanRewardQuest(Quest const *quest, bool msg)
Definition PlayerQuest.cpp:387
Definition QuestDef.h:210
uint32 RewardItemIdCount[QUEST_REWARDS_COUNT]
Definition QuestDef.h:310
uint32 GetRewItemsCount() const
Definition QuestDef.h:322
uint32 XPValue(uint8 playerLevel=0) const
Definition QuestDef.cpp:199
int32 GetRewOrReqMoney(uint8 playerLevel=0) const
Definition QuestDef.cpp:239
uint32 RewardItemId[QUEST_REWARDS_COUNT]
Definition QuestDef.h:309
@ SMSG_LFG_PLAYER_INFO
Definition Opcodes.h:909
std::map< uint32, uint32 > LfgLockMap
Definition LFG.h:115
Definition LFGMgr.h:336
uint32 firstQuest
Definition LFGMgr.h:341
uint32 otherQuest
Definition LFGMgr.h:342

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

Referenced by OpcodeTable::Initialize().

◆ HandleLfgProposalResultOpcode()

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

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

Referenced by OpcodeTable::Initialize().

◆ HandleLfgSetBootVoteOpcode()

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

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

Referenced by OpcodeTable::Initialize().

◆ HandleLfgSetCommentOpcode()

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

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

Referenced by OpcodeTable::Initialize().

◆ HandleLfgSetRolesOpcode()

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

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

Referenced by OpcodeTable::Initialize().

◆ HandleLfgTeleportOpcode()

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

References GetPlayer(), LOG_DEBUG, and sLFGMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleLfrSearchJoinOpcode()

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

References GetPlayer(), and sLFGMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleLfrSearchLeaveOpcode()

void WorldSession::HandleLfrSearchLeaveOpcode ( WorldPacket &  recvData)
275{
276 uint32 dungeonId;
277 recvData >> dungeonId;
278 sLFGMgr->LfrSearchRemove(GetPlayer());
279}

References GetPlayer(), and sLFGMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleListInventoryOpcode()

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

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

Referenced by OpcodeTable::Initialize().

◆ HandleListStabledPetsOpcode()

void WorldSession::HandleListStabledPetsOpcode ( WorldPacket &  recvPacket)
335{
336 LOG_DEBUG("network", "WORLD: Recv MSG_LIST_STABLED_PETS");
337 ObjectGuid npcGUID;
338
339 recvData >> npcGUID;
340
341 if (!CheckStableMaster(npcGUID))
342 return;
343
344 // remove fake death
345 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
347
348 // remove mounts this fix bug where getting pet from stable while mounted deletes pet.
349 if (GetPlayer()->IsMounted())
351
352 SendStablePet(npcGUID);
353}
void SendStablePet(ObjectGuid guid)
Definition NPCHandler.cpp:355

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)
580{
581 if (!GetPlayer())
582 return;
583
584 if (result)
585 GetPlayer()->_LoadActions(result);
586
588}
void _LoadActions(PreparedQueryResult result)
Definition PlayerStorage.cpp:5799
void SendActionButtons(uint32 state) const
Definition Player.cpp:5723

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

◆ HandleLogoutCancelOpcode()

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

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
417{
418 LOG_DEBUG("network", "WORLD: Recvd CMSG_LOGOUT_REQUEST Message, security - {}", GetSecurity());
419
420 if (ObjectGuid lguid = GetPlayer()->GetLootGUID())
421 DoLootRelease(lguid);
422
423 bool instantLogout = (HasPermission(rbac::RBAC_PERM_INSTANT_LOGOUT)
425
426 bool preventAfkSanctuaryLogout = sWorld->getIntConfig(CONFIG_AFK_PREVENT_LOGOUT) == 1
427 && GetPlayer()->isAFK() && sAreaTableStore.LookupEntry(GetPlayer()->GetAreaId())->IsSanctuary();
428
429 bool preventAfkLogout = ((sWorld->getIntConfig(CONFIG_AFK_PREVENT_LOGOUT) == 2) || HasAccountFlag(ACCOUNT_FLAG_NOKICK))
430 && GetPlayer()->isAFK();
431
433 bool canLogoutInCombat = GetPlayer()->HasPlayerFlag(PLAYER_FLAGS_RESTING);
434
435 uint32 reason = 0;
436 if (GetPlayer()->IsInCombat() && !canLogoutInCombat)
437 reason = 1;
438 else if (GetPlayer()->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR))
439 reason = 3; // is jumping or falling
440 else if (preventAfkSanctuaryLogout || preventAfkLogout || GetPlayer()->duel || GetPlayer()->HasAura(9454)) // is dueling or frozen by GM via freeze command
441 reason = 2; // FIXME - Need the correct value
442
444 logoutResponse.LogoutResult = reason;
445 logoutResponse.Instant = instantLogout;
446 SendPacket(logoutResponse.Write());
447
448 if (reason)
449 {
451 return;
452 }
453
454 //instant logout in taverns/cities or on taxi or for admins, gm's, mod's if its enabled in worldserver.conf
455 if (instantLogout)
456 {
457 LogoutPlayer(true);
458 return;
459 }
460
461 // not set flags if player can't free move to prevent lost state at logout cancel
462 if (GetPlayer()->CanFreeMove())
463 {
464 if (GetPlayer()->getStandState() == UNIT_STAND_STATE_STAND)
465 {
467 }
468
469 GetPlayer()->SetRooted(true, true, true);
471 }
472
474}
@ ACCOUNT_FLAG_NOKICK
Definition Common.h:68
@ PLAYER_FLAGS_RESTING
Definition Player.h:464
@ MOVEMENTFLAG_FALLING
Definition UnitDefines.h:384
@ MOVEMENTFLAG_FALLING_FAR
Definition UnitDefines.h:385
@ UNIT_STAND_STATE_SIT
Definition UnitDefines.h:36
@ CONFIG_AFK_PREVENT_LOGOUT
Definition WorldConfig.h:355
void SetUnitFlag(UnitFlags flags)
UnitFlags available in UnitDefines.h.
Definition Unit.h:749
Definition CharacterPackets.h:56
WorldPacket const * Write() override
Definition CharacterPackets.cpp:30
uint32 LogoutResult
Definition CharacterPackets.h:62
bool Instant
Definition CharacterPackets.h:63
AccountTypes GetSecurity() const
Definition WorldSession.h:490
@ RBAC_PERM_INSTANT_LOGOUT
Definition RBAC.h:52

References ACCOUNT_FLAG_NOKICK, CONFIG_AFK_PREVENT_LOGOUT, DoLootRelease(), GameTime::GetGameTime(), GetPlayer(), GetSecurity(), HasAccountFlag(), HasPermission(), 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, rbac::RBAC_PERM_INSTANT_LOGOUT, 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)
479{
480 uint8 slotid;
481 ObjectGuid lootguid, target_playerguid;
482
483 recvData >> lootguid >> slotid >> target_playerguid;
484
486 {
488 return;
489 }
490
491 Player* target = ObjectAccessor::GetPlayer(*_player, target_playerguid);
492 if (!target)
493 {
495 return;
496 }
497
498 LOG_DEBUG("network", "WorldSession::HandleLootMasterGiveOpcode (CMSG_LOOT_MASTER_GIVE, 0x02A3) Target = [{}].", target->GetName());
499
500 if (_player->GetLootGUID() != lootguid)
501 {
503 return;
504 }
505
507 {
509 //LOG_DEBUG("network", "MasterLootItem: Player {} tried to give an item to ineligible player {} !", GetPlayer()->GetName(), target->GetName());
510 return;
511 }
512
513 Loot* loot = nullptr;
514
515 if (GetPlayer()->GetLootGUID().IsCreatureOrVehicle())
516 {
517 Creature* creature = GetPlayer()->GetMap()->GetCreature(lootguid);
518 if (!creature)
519 return;
520
521 loot = &creature->loot;
522 }
523 else if (GetPlayer()->GetLootGUID().IsGameObject())
524 {
525 GameObject* pGO = GetPlayer()->GetMap()->GetGameObject(lootguid);
526 if (!pGO)
527 return;
528
529 loot = &pGO->loot;
530 }
531
532 if (!loot)
533 return;
534
535 if (slotid >= loot->items.size() + loot->quest_items.size())
536 {
537 LOG_DEBUG("loot", "MasterLootItem: Player {} might be using a hack! (slot {}, size {})", GetPlayer()->GetName(), slotid, (unsigned long)loot->items.size());
538 return;
539 }
540
541 LootItem& item = slotid >= loot->items.size() ? loot->quest_items[slotid - loot->items.size()] : loot->items[slotid];
542
543 ItemPosCountVec dest;
544 InventoryResult msg = target->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, item.itemid, item.count);
545 if (!item.AllowedForPlayer(target, loot->sourceWorldObjectGUID))
547 if (msg != EQUIP_ERR_OK)
548 {
551 else if (msg == EQUIP_ERR_INVENTORY_FULL)
553 else
555
556 return;
557 }
558
559 // list of players allowed to receive this item in trade
560 AllowedLooterSet looters = item.GetAllowedLooters();
561
562 // not move item from loot to target inventory
563 Item* newitem = target->StoreNewItem(dest, item.itemid, true, item.randomPropertyId, looters);
564 target->SendNewItem(newitem, uint32(item.count), false, false, true);
565 target->UpdateLootAchievements(&item, loot);
566
567 // mark as looted
568 item.count = 0;
569 item.is_looted = true;
570
571 loot->NotifyItemRemoved(slotid);
572 --loot->unlootedCount;
573}
@ 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:2545
LootMethod GetLootMethod() const
Definition Group.cpp:2535
void UpdateLootAchievements(LootItem *item, Loot *loot)
Definition PlayerUpdates.cpp:2226
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition PlayerStorage.cpp:4855
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0, bool refund=false)
Definition PlayerStorage.cpp:2635
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition Player.h:1304
bool IsInRaidWith(Unit const *unit) const
Definition Unit.cpp:14681
AllowedLooterSet const & GetAllowedLooters() const
Definition LootMgr.h:181
bool AllowedForPlayer(Player const *player, ObjectGuid source) const
Definition LootMgr.cpp:417
int32 randomPropertyId
Definition LootMgr.h:158
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(), Player::HasPlayerFlag(), 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, PLAYER_FLAGS_NO_PLAY_TIME, 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

517{
518 uint32 lootMethod;
519 ObjectGuid lootMaster;
520 uint32 lootThreshold;
521 recvData >> lootMethod >> lootMaster >> lootThreshold;
522
523 Group* group = GetPlayer()->GetGroup();
524 if (!group)
525 return;
526
528 // Xinef: Check if group is LFG
529 if (!group->IsLeader(GetPlayer()->GetGUID()) || group->isLFGGroup(true))
530 return;
531
532 if (lootMethod > NEED_BEFORE_GREED)
533 return;
534
535 if (lootThreshold < ITEM_QUALITY_UNCOMMON || lootThreshold > ITEM_QUALITY_ARTIFACT)
536 return;
537
538 if (lootMethod == MASTER_LOOT && !group->IsMember(lootMaster))
539 return;
540 /********************/
541
542 // everything's fine, do it
543 group->SetLootMethod((LootMethod)lootMethod);
544 group->SetMasterLooterGuid(lootMaster);
545 group->SetLootThreshold((ItemQualities)lootThreshold);
546 group->SendUpdate();
547}
LootMethod
Definition LootMgr.h:57
@ NEED_BEFORE_GREED
Definition LootMgr.h:62
ItemQualities
Definition SharedDefines.h:316
@ ITEM_QUALITY_ARTIFACT
Definition SharedDefines.h:323
void SetLootMethod(LootMethod method)
Definition Group.cpp:2449
void SetLootThreshold(ItemQualities threshold)
Definition Group.cpp:2464
void SetMasterLooterGuid(ObjectGuid guid)
Definition Group.cpp:2459

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)
123{
124 LOG_DEBUG("network", "WORLD: CMSG_LOOT_MONEY");
125
126 Player* player = GetPlayer();
127 ObjectGuid guid = player->GetLootGUID();
128 if (!guid)
129 return;
130
131 Loot* loot = nullptr;
132 bool shareMoney = true;
133
134 switch (guid.GetHigh())
135 {
137 {
138 GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid);
139
140 // do not check distance for GO if player is the owner of it (ex. fishing bobber)
141 if (go && ((go->GetOwnerGUID() == player->GetGUID() || go->IsWithinDistInMap(player))))
142 {
143 loot = &go->loot;
144 }
145
146 break;
147 }
148 case HighGuid::Corpse: // remove insignia ONLY in BG
149 {
150 Corpse* bones = ObjectAccessor::GetCorpse(*player, guid);
151
152 if (bones && bones->IsWithinDistInMap(player, INTERACTION_DISTANCE))
153 {
154 loot = &bones->loot;
155 shareMoney = false;
156 }
157
158 break;
159 }
160 case HighGuid::Item:
161 {
162 if (Item* item = player->GetItemByGuid(guid))
163 {
164 loot = &item->loot;
165 shareMoney = false;
166 }
167 break;
168 }
169 case HighGuid::Unit:
171 {
172 Creature* creature = player->GetMap()->GetCreature(guid);
173 bool lootAllowed = creature && creature->IsAlive() == (player->IsClass(CLASS_ROGUE, CLASS_CONTEXT_ABILITY) && creature->loot.loot_type == LOOT_PICKPOCKETING);
174 if (lootAllowed && creature->IsWithinDistInMap(player, INTERACTION_DISTANCE))
175 {
176 loot = &creature->loot;
177 if (creature->IsAlive())
178 shareMoney = false;
179 }
180 else
181 player->SendLootError(guid, lootAllowed ? LOOT_ERROR_TOO_FAR : LOOT_ERROR_DIDNT_KILL);
182 break;
183 }
184 default:
185 return; // unlootable type
186 }
187
188 if (loot)
189 {
190 // the money is zeroed and dropped from storage below no matter who is paid, so a fully
191 // restricted looter would destroy it rather than receive it. Bail before that teardown;
192 // reachable for windows not opened through HandleLootOpcode, e.g. chests and lockboxes.
194 {
196 return;
197 }
198
199 sScriptMgr->OnPlayerBeforeLootMoney(player, loot);
200 loot->NotifyMoneyRemoved();
201 if (shareMoney && player->GetGroup()) //item, pickpocket and players can be looted only single player
202 {
203 Group* group = player->GetGroup();
204
205 std::vector<Player*> playersNear;
206 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
207 {
208 Player* member = itr->GetSource();
209 if (!member)
210 continue;
211
212 if (player->IsAtLootRewardDistance(member))
213 playersNear.push_back(member);
214 }
215
216 uint32 goldPerPlayer = uint32((loot->gold) / (playersNear.size()));
217
218 for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i)
219 {
220 uint32 finalGold = goldPerPlayer;
221
222 if ((*i)->HasPlayerFlag(PLAYER_FLAGS_NO_PLAY_TIME))
223 continue;
224
225 if ((*i)->HasPlayerFlag(PLAYER_FLAGS_PARTIAL_PLAY_TIME))
226 {
227 finalGold /= 2;
228
229 // a halved share that rounds down to nothing is not worth announcing
230 if (!finalGold)
231 continue;
232 }
233
234 (*i)->ModifyMoney(finalGold);
235 (*i)->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, finalGold);
236
238 data << uint32(finalGold);
239 data << uint8(playersNear.size() > 1 ? 0 : 1); // Controls the text displayed in chat. 0 is "Your share is..." and 1 is "You loot..."
240 (*i)->SendDirectMessage(&data);
241 }
242 }
243 else
244 {
245 uint32 finalGold = loot->gold;
246 bool award = true; // full restriction already returned above
247
249 {
250 finalGold /= 2;
251
252 // a halved amount that rounds down to nothing is not worth announcing
253 award = finalGold != 0;
254 }
255
256 // fire the hook regardless of the CAIS reduction, matching OnLootMoney below
257 sScriptMgr->OnPlayerAfterCreatureLootMoney(player);
258
259 if (award)
260 {
261 player->ModifyMoney(finalGold);
263
265 data << uint32(finalGold);
266 data << uint8(1); // "You loot..."
267 SendPacket(&data);
268 }
269 }
270
271 // reports the amount that dropped, not the CAIS-reduced amount actually awarded;
272 // a script that grants money from this hook bypasses the play time restriction
273 sScriptMgr->OnLootMoney(player, loot->gold);
274
275 loot->gold = 0;
276
277 // Delete the money loot record from the DB
278 if (loot->containerGUID)
279 sLootItemStorage->RemoveStoredLootMoney(loot->containerGUID, loot);
280
281 // Delete container if empty
282 if (loot->isLooted() && guid.IsItem())
283 DoLootRelease(guid);
284 }
285}
@ ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY
Definition DBCEnums.h:179
#define sLootItemStorage
Definition LootItemStorage.h:73
HighGuid GetHigh() const
Definition ObjectGuid.h:146
bool IsAtLootRewardDistance(WorldObject const *pRewardSource) const
Definition Player.cpp:13097
@ SMSG_LOOT_MONEY_NOTIFY
Definition Opcodes.h:385
ObjectGuid containerGUID
Definition LootMgr.h:329
void NotifyMoneyRemoved()
Definition LootMgr.cpp:759
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, Player::HasPlayerFlag(), 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_PLAY_TIME_EXCEEDED, LOOT_ERROR_TOO_FAR, LOOT_PICKPOCKETING, Loot::loot_type, Player::ModifyMoney(), GroupReference::next(), Loot::NotifyMoneyRemoved(), PLAYER_FLAGS_NO_PLAY_TIME, PLAYER_FLAGS_PARTIAL_PLAY_TIME, Player::SendLootError(), SendPacket(), sLootItemStorage, SMSG_LOOT_MONEY_NOTIFY, sScriptMgr, Unit, Player::UpdateAchievementCriteria(), and Vehicle.

Referenced by OpcodeTable::Initialize().

◆ HandleLootOpcode()

void WorldSession::HandleLootOpcode ( WorldPacket &  recvPacket)
288{
289 LOG_DEBUG("network", "WORLD: CMSG_LOOT");
290
291 ObjectGuid guid;
292 recvData >> guid;
293
294 Player* player = GetPlayer();
295
296 // Check possible cheat
297 if (!player->IsAlive() || !guid.IsCreatureOrVehicle())
298 return;
299
301 {
303 return;
304 }
305
306 // interrupt cast
307 if (player->IsNonMeleeSpellCast(false))
308 player->InterruptNonMeleeSpells(false);
309
310 player->SendLoot(guid, LOOT_CORPSE);
311}
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition Player.cpp:7985

References GetPlayer(), Player::HasPlayerFlag(), Unit::InterruptNonMeleeSpells(), Unit::IsAlive(), ObjectGuid::IsCreatureOrVehicle(), Unit::IsNonMeleeSpellCast(), LOG_DEBUG, LOOT_CORPSE, LOOT_ERROR_PLAY_TIME_EXCEEDED, PLAYER_FLAGS_NO_PLAY_TIME, Player::SendLoot(), and Player::SendLootError().

Referenced by OpcodeTable::Initialize().

◆ HandleLootReleaseOpcode()

void WorldSession::HandleLootReleaseOpcode ( WorldPacket &  recvPacket)
314{
315 LOG_DEBUG("network", "WORLD: CMSG_LOOT_RELEASE");
316
317 // cheaters can modify lguid to prevent correct apply loot release code and re-loot
318 // use internal stored guid
319 ObjectGuid guid;
320 recvData >> guid;
321
322 if (ObjectGuid lguid = GetPlayer()->GetLootGUID())
323 if (lguid == guid)
324 DoLootRelease(lguid);
325}

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

Referenced by OpcodeTable::Initialize().

◆ HandleLootRoll()

void WorldSession::HandleLootRoll ( WorldPacket &  recvData)
550{
551 ObjectGuid guid;
552 uint32 itemSlot;
553 uint8 rollType;
554 recvData >> guid; // guid of the item rolled
555 recvData >> itemSlot;
556 recvData >> rollType; // 0: pass, 1: need, 2: greed
557
558 Group* group = GetPlayer()->GetGroup();
559 if (!group)
560 return;
561
562 if (GetPlayer()->HasPlayerFlag(PLAYER_FLAGS_NO_PLAY_TIME))
563 {
565 rollType = ROLL_PASS;
566 }
567
568 group->CountRollVote(GetPlayer()->GetGUID(), guid, rollType);
569
570 switch (rollType)
571 {
572 case ROLL_NEED:
574 break;
575 case ROLL_GREED:
577 break;
578 case ROLL_DISENCHANT:
580 break;
581 }
582}
@ 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_PASS
Definition LootMgr.h:33
@ 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:1496

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

Referenced by OpcodeTable::Initialize().

◆ HandleMailCreateTextItem()

void WorldSession::HandleMailCreateTextItem ( WorldPacket &  recvData)
825{
826 ObjectGuid mailbox;
827 uint32 mailId;
828
829 recvData >> mailbox;
830 recvData >> mailId;
831
832 if (!CanOpenMailBox(mailbox))
833 return;
834
835 Player* player = _player;
836
837 Mail* m = player->GetMail(mailId);
838 if (!m || (m->body.empty() && !m->mailTemplateId) || m->state == MAIL_STATE_DELETED || m->deliver_time > GameTime::GetGameTime().count() || (m->checked & MAIL_CHECK_MASK_COPIED))
839 {
841 return;
842 }
843
844 Item* bodyItem = new Item; // This is not bag and then can be used new Item.
845 if (!bodyItem->Create(sObjectMgr->GetGenerator<HighGuid::Item>().Generate(), MAIL_BODY_ITEM_TEMPLATE, player))
846 {
847 delete bodyItem;
848 return;
849 }
850
851 // in mail template case we need create new item text
852 if (m->mailTemplateId)
853 {
854 MailTemplateEntry const* mailTemplateEntry = sMailTemplateStore.LookupEntry(m->mailTemplateId);
855 if (!mailTemplateEntry)
856 {
858 delete bodyItem;
859 return;
860 }
861
862 bodyItem->SetText(mailTemplateEntry->content[GetSessionDbcLocale()]);
863 }
864 else
865 bodyItem->SetText(m->body);
866
869
870 LOG_DEBUG("network.opcode", "HandleMailCreateTextItem mailid={}", mailId);
871
872 ItemPosCountVec dest;
873 uint8 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, bodyItem, false);
874 if (msg == EQUIP_ERR_OK)
875 {
878 player->m_mailsUpdated = true;
879
880 player->StoreItem(dest, bodyItem, true);
882 }
883 else
884 {
886 delete bodyItem;
887 }
888}
DBCStorage< MailTemplateEntry > sMailTemplateStore(MailTemplateEntryfmt)
@ ITEM_FLAG_MAIL_TEXT_MASK
Definition ItemTemplate.h:142
@ MAIL_STATE_DELETED
Definition Mail.h:70
@ MAIL_STATE_CHANGED
Definition Mail.h:69
#define MAIL_BODY_ITEM_TEMPLATE
Definition Mail.h:32
@ MAIL_MADE_PERMANENT
Definition SharedDefines.h:3761
@ MAIL_ERR_EQUIP_ERROR
Definition SharedDefines.h:3767
@ MAIL_OK
Definition SharedDefines.h:3766
@ MAIL_ERR_INTERNAL_ERROR
Definition SharedDefines.h:3772
@ 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:283
void SetText(std::string const &text)
Definition Item.h:309
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:836
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:648
void SendMailResult(uint32 mailId, MailResponseType mailAction, MailResponseResult mailError, uint32 equipError=0, ObjectGuid::LowType item_guid=0, uint32 item_count=0)
Definition Player.cpp:2958
bool m_mailsUpdated
Definition Player.h:1620
Mail * GetMail(uint32 id)
Definition Player.cpp:3977
Definition DBCStructure.h:1353
char const * content[16]
Definition DBCStructure.h:1357
Definition Mail.h:167
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)
407{
408 ObjectGuid mailbox;
409 uint32 mailId;
410 recvData >> mailbox;
411 recvData >> mailId;
412 recvData.read_skip<uint32>(); // mailTemplateId
413
414 if (!CanOpenMailBox(mailbox))
415 return;
416
417 Mail* m = _player->GetMail(mailId);
418 Player* player = _player;
419 player->m_mailsUpdated = true;
420 if (m && m->state != MAIL_STATE_DELETED)
421 {
422 // delete shouldn't show up for COD mails
423 if (m->COD)
424 {
426 return;
427 }
428
430
431 sMailMgr->OnMailDeleted(player->GetGUID().GetCounter());
432 }
433 player->SendMailResult(mailId, MAIL_DELETED, MAIL_OK);
434}
#define sMailMgr
Definition MailMgr.h:85
@ MAIL_DELETED
Definition SharedDefines.h:3760
uint32 COD
Definition Mail.h:181

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

Referenced by OpcodeTable::Initialize().

◆ HandleMailMarkAsRead()

void WorldSession::HandleMailMarkAsRead ( WorldPacket &  recvData)
384{
385 ObjectGuid mailbox;
386 uint32 mailId;
387 recvData >> mailbox;
388 recvData >> mailId;
389
390 if (!CanOpenMailBox(mailbox))
391 return;
392
393 Player* player = _player;
394 Mail* m = player->GetMail(mailId);
395 if (m && m->state != MAIL_STATE_DELETED)
396 {
397 if (player->unReadMails)
398 --player->unReadMails;
400 player->m_mailsUpdated = true;
402 }
403}
@ MAIL_CHECK_MASK_READ
Definition Mail.h:47
uint8 unReadMails
Definition Player.h:1687

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)
437{
438 ObjectGuid mailbox;
439 uint32 mailId;
440 recvData >> mailbox;
441 recvData >> mailId;
442 recvData.read_skip<uint64>(); // original sender GUID for return to, not used
443
444 if (!CanOpenMailBox(mailbox))
445 return;
446
447 Player* player = _player;
448 Mail* m = player->GetMail(mailId);
449 if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > GameTime::GetGameTime().count())
450 {
452 return;
453 }
454
455 if (m->HasItems())
456 {
457 for (MailItemInfoVec::iterator itr = m->items.begin(); itr != m->items.end(); ++itr)
458 {
459 Item* item = player->GetMItem(itr->item_guid);
460 if (item && !sScriptMgr->OnPlayerCanSendMail(player, ObjectGuid(HighGuid::Player, m->sender), mailbox, m->subject, m->body, m->money, m->COD, item))
461 {
463 return;
464 }
465 }
466 }
467 else if (!sScriptMgr->OnPlayerCanSendMail(player, ObjectGuid(HighGuid::Player, m->sender), mailbox, m->subject, m->body, m->money, m->COD, nullptr))
468 {
470 return;
471 }
472
473 //we can return mail now
474 //so firstly delete the old one
475 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
476
478 stmt->SetData(0, mailId);
479 trans->Append(stmt);
480
481 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM_BY_ID);
482 stmt->SetData(0, mailId);
483 trans->Append(stmt);
484
485 player->RemoveMail(mailId);
486
487 // only return mail if the player exists (and delete if not existing)
488 if (m->messageType == MAIL_NORMAL && m->sender)
489 {
490 MailDraft draft(m->subject, m->body);
491 if (m->mailTemplateId)
492 draft = MailDraft(m->mailTemplateId, false); // items already included
493
494 if (m->HasItems())
495 {
496 for (MailItemInfoVec::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
497 {
498 Item* item = player->GetMItem(itr2->item_guid);
499 if (item)
500 draft.AddItem(item);
501
502 player->RemoveMItem(itr2->item_guid);
503 }
504 }
505 draft.AddMoney(m->money).SendReturnToSender(GetAccountId(), m->receiver, m->sender, trans);
506 }
507
508 CharacterDatabase.CommitTransaction(trans);
509
510 delete m; //we can deallocate old mail
512
513 sMailMgr->OnMailDeleted(player->GetGUID().GetCounter());
514}
@ CHAR_DEL_MAIL_BY_ID
Definition CharacterDatabase.h:110
@ CHAR_DEL_MAIL_ITEM_BY_ID
Definition CharacterDatabase.h:388
@ MAIL_NORMAL
Definition Mail.h:37
@ MAIL_RETURNED_TO_SENDER
Definition SharedDefines.h:3759
void RemoveMail(uint32 id)
Definition Player.cpp:2945
bool RemoveMItem(ObjectGuid::LowType itemLowGuid)
Definition Player.h:1707
Item * GetMItem(ObjectGuid::LowType itemLowGuid)
Definition Player.h:1694
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(), ObjectGuid::GetCounter(), 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(), Mail::sender, Player::SendMailResult(), MailDraft::SendReturnToSender(), PreparedStatementBase::SetData(), sMailMgr, sScriptMgr, Mail::state, and Mail::subject.

Referenced by OpcodeTable::Initialize().

◆ HandleMailTakeItem()

void WorldSession::HandleMailTakeItem ( WorldPacket &  recvData)
518{
519 ObjectGuid mailbox;
520 uint32 mailId;
521 uint32 itemLowGuid;
522 recvData >> mailbox;
523 recvData >> mailId;
524 recvData >> itemLowGuid; // item guid low
525
526 if (!CanOpenMailBox(mailbox))
527 return;
528
529 Player* player = _player;
530
531 Mail* m = player->GetMail(mailId);
532 if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > GameTime::GetGameTime().count())
533 {
535 return;
536 }
537
538 // verify that the mail has the item to avoid cheaters taking COD items without paying
539 bool foundItem = false;
540 for (std::vector<MailItemInfo>::const_iterator itr = m->items.begin(); itr != m->items.end(); ++itr)
541 if (itr->item_guid == itemLowGuid)
542 {
543 foundItem = true;
544 break;
545 }
546 if (!foundItem)
547 {
549 return;
550 }
551
552 // prevent cheating with skip client money check
553 if (!player->HasEnoughMoney(m->COD))
554 {
556 return;
557 }
558
559 Item* it = player->GetMItem(itemLowGuid);
560
561 ItemPosCountVec dest;
562 uint8 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, it, false);
563 if (msg == EQUIP_ERR_OK)
564 {
565 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
566 m->RemoveItem(itemLowGuid);
567 m->removedItems.push_back(itemLowGuid);
568
569 if (m->COD > 0) // if there is COD, take COD money from player and send them to sender by mail
570 {
571 uint32 sender_accId = 0;
573 if (sender)
574 {
575 sender_accId = sender->GetSession()->GetAccountId();
576 }
577 else
578 {
579 sender_accId = sCharacterCache->GetCharacterAccountIdByGuid(ObjectGuid(HighGuid::Player, m->sender));
580 }
581
582 // check player existence
583 if (sender || sender_accId)
584 {
585 MailDraft(m->subject, "")
586 .AddMoney(m->COD)
588
589 if (m->COD >= 10 * GOLD)
590 {
591 std::string senderName;
592 if (!sCharacterCache->GetCharacterNameByGuid(ObjectGuid(HighGuid::Player, m->sender), senderName))
593 {
594 senderName = sObjectMgr->GetAcoreStringForDBCLocale(LANG_UNKNOWN);
595 }
596 std::string subj = m->subject;
598 CharacterDatabase.Execute("INSERT INTO log_money VALUES({}, {}, \"{}\", \"{}\", {}, \"{}\", {}, \"{}\", NOW(), {})",
599 GetAccountId(), player->GetGUID().GetCounter(), player->GetName(), player->GetSession()->GetRemoteAddress(), sender_accId, senderName, m->COD, subj, 1);
600 }
601 }
602
603 player->ModifyMoney(-int32(m->COD));
604 }
605
606 m->COD = 0;
608 player->m_mailsUpdated = true;
609 player->RemoveMItem(it->GetGUID().GetCounter());
610
611 uint32 count = it->GetCount(); // save counts before store and possible merge with deleting
612 it->SetState(ITEM_UNCHANGED); // need to set this state, otherwise item cannot be removed later, if neccessary
613
614 // `stored` is the stack the character ends up holding. On a full stack merge, `it` is marked for removal
615 // and `SaveInventoryAndGoldToDB` below deletes it, so we pass `stored` instead of `it` to downstream hooks.
616 Item* stored = player->MoveItemToInventory(dest, it, true);
617
619 {
620 LOG_GM(GetAccountId(), "GM {} (Account: {}) took mail item: {} (Entry: {} Count: {}) from mailbox",
621 player->GetName(), GetAccountId(), it->GetTemplate()->Name1, it->GetEntry(), count);
622 }
623
624 player->SaveInventoryAndGoldToDB(trans);
625 player->_SaveMail(trans);
626 CharacterDatabase.CommitTransaction(trans);
627
628 player->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_OK, 0, itemLowGuid, count);
629
630 sScriptMgr->OnPlayerAfterTakeItemFromMail(player, stored, count);
631 }
632 else
634}
void CleanStringForMysqlQuery(std::string &str)
Definition Common.cpp:97
@ 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:3758
@ MAIL_ERR_NOT_ENOUGH_MONEY
Definition SharedDefines.h:3769
MailDraft & AddMoney(uint32 money)
Definition Mail.h:137
Definition Mail.h:105
Definition Mail.h:83
void _SaveMail(CharacterDatabaseTransaction trans)
Definition PlayerStorage.cpp:7572
Player * FindPlayerByLowGUID(ObjectGuid::LowType lowguid)
Definition ObjectAccessor.cpp:275
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(), Object::GetEntry(), GameTime::GetGameTime(), Object::GetGUID(), Player::GetMail(), Player::GetMItem(), WorldObject::GetName(), GetRemoteAddress(), Player::GetSession(), Item::GetTemplate(), GOLD, Player::HasEnoughMoney(), HasPermission(), ITEM_UNCHANGED, Mail::items, LANG_UNKNOWN, LOG_GM, 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(), ItemTemplate::Name1, NULL_BAG, NULL_SLOT, Player, rbac::RBAC_PERM_LOG_GM_TRADE, Mail::receiver, Mail::removedItems, Mail::RemoveItem(), Player::RemoveMItem(), Player::SaveInventoryAndGoldToDB(), sCharacterCache, Mail::sender, Player::SendMailResult(), MailDraft::SendMailTo(), Item::SetState(), sObjectMgr, sScriptMgr, Mail::state, and Mail::subject.

Referenced by OpcodeTable::Initialize().

◆ HandleMailTakeMoney()

void WorldSession::HandleMailTakeMoney ( WorldPacket &  recvData)
637{
638 ObjectGuid mailbox;
639 uint32 mailId;
640 recvData >> mailbox;
641 recvData >> mailId;
642
643 if (!CanOpenMailBox(mailbox))
644 return;
645
646 Player* player = _player;
647
648 Mail* m = player->GetMail(mailId);
649 if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > GameTime::GetGameTime().count())
650 {
652 return;
653 }
654
655 if (!player->ModifyMoney(m->money, false))
656 {
658 return;
659 }
660
662 {
663 LOG_GM(GetAccountId(), "GM {} (Account: {}) took mail money: {} from mailbox",
664 player->GetName(), GetAccountId(), m->money);
665 }
666
667 m->money = 0;
669 player->m_mailsUpdated = true;
670
671 player->SendMailResult(mailId, MAIL_MONEY_TAKEN, MAIL_OK);
672
673 // save money and mail to prevent cheating
674 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
675 player->SaveGoldToDB(trans);
676 player->_SaveMail(trans);
677 CharacterDatabase.CommitTransaction(trans);
678}
@ MAIL_MONEY_TAKEN
Definition SharedDefines.h:3757
void SaveGoldToDB(CharacterDatabaseTransaction trans)
Definition PlayerStorage.cpp:7320

References _player, Player::_SaveMail(), CanOpenMailBox(), CharacterDatabase, Mail::deliver_time, EQUIP_ERR_TOO_MUCH_GOLD, GetAccountId(), GameTime::GetGameTime(), Player::GetMail(), WorldObject::GetName(), HasPermission(), LOG_GM, 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, rbac::RBAC_PERM_LOG_GM_TRADE, Player::SaveGoldToDB(), Player::SendMailResult(), and Mail::state.

Referenced by OpcodeTable::Initialize().

◆ HandleMessagechatOpcode()

void WorldSession::HandleMessagechatOpcode ( WorldPacket &  recvPacket)
62{
63 uint32 type;
64 uint32 lang;
65
66 recvData >> type;
67 recvData >> lang;
68
69 if (type >= MAX_CHAT_MSG_TYPE)
70 {
71 LOG_ERROR("network.opcode", "CHAT: Wrong message type received: {}", type);
72 recvData.rfinish();
73 return;
74 }
75
76 if (lang == LANG_UNIVERSAL && type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
77 {
78 LOG_ERROR("entities.player.cheat", "CMSG_MESSAGECHAT: Possible hacking-attempt: {} tried to send a message in universal language", GetPlayerInfo());
80 recvData.rfinish();
81 return;
82 }
83
84 Player* sender = GetPlayer();
85
86 // prevent talking at unknown language (cheating)
87 LanguageDesc const* langDesc = GetLanguageDescByID(lang);
88 if (!langDesc)
89 {
91 recvData.rfinish();
92 return;
93 }
94
95 if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id))
96 {
97 // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language)
98 bool foundAura = false;
99 for (auto const& auraEff : sender->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE))
100 {
101 if (auraEff->GetMiscValue() == int32(lang))
102 {
103 foundAura = true;
104 break;
105 }
106 }
107
108 if (!foundAura)
109 {
111 recvData.rfinish();
112 return;
113 }
114 }
115
116 // Trial accounts cannot speak in chat channels or guild/officer chat. Whisper is handled later.
117 // Addon traffic (LANG_ADDON) is excluded; it carries the Warden Lua check response over guild chat.
118 if (sWorld->getBoolConfig(CONFIG_TRIAL_RESTRICTION_CHAT) && IsTrialAccount() && lang != LANG_ADDON
119 && (type == CHAT_MSG_CHANNEL || type == CHAT_MSG_GUILD || type == CHAT_MSG_OFFICER))
120 {
121 WorldPacket data;
123 SendPacket(&data);
124 recvData.rfinish();
125 return;
126 }
127
128 // pussywizard: chatting on most chat types requires 2 hours played to prevent spam/abuse
130 {
131 switch (type)
132 {
133 case CHAT_MSG_ADDON:
134 case CHAT_MSG_PARTY:
135 case CHAT_MSG_RAID:
136 case CHAT_MSG_GUILD:
137 case CHAT_MSG_OFFICER:
138 case CHAT_MSG_AFK:
139 case CHAT_MSG_DND:
145 break;
146 default:
147 {
148 if (sWorld->getBoolConfig(CONFIG_CHAT_MUTE_FIRST_LOGIN) && lang != LANG_ADDON)
149 {
150 uint32 minutes = sWorld->getIntConfig(CONFIG_CHAT_TIME_MUTE_FIRST_LOGIN);
151
152 if (sender->GetTotalPlayedTime() < minutes * MINUTE)
153 {
155 recvData.rfinish();
156 return;
157 }
158 }
159 }
160 }
161 }
162
163 // pussywizard:
164 switch (type)
165 {
166 case CHAT_MSG_SAY:
167 case CHAT_MSG_YELL:
168 case CHAT_MSG_EMOTE:
170 case CHAT_MSG_AFK:
171 case CHAT_MSG_DND:
172 if (sender->IsSpectator())
173 {
174 recvData.rfinish();
175 return;
176 }
177 }
178
179 if (sender->HasAura(1852) && type != CHAT_MSG_WHISPER)
180 {
182 recvData.rfinish();
183 return;
184 }
185
186 if (lang == LANG_ADDON)
187 {
188 // LANG_ADDON is only valid for the following message types
189 switch (type)
190 {
191 case CHAT_MSG_PARTY:
192 case CHAT_MSG_RAID:
193 case CHAT_MSG_GUILD:
195 case CHAT_MSG_WHISPER:
196 // check if addon messages are disabled
197 if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL))
198 {
199 recvData.rfinish();
200 return;
201 }
202 break;
203 default:
204 LOG_ERROR("network", "Player {} ({}) sent a chatmessage with an invalid language/message type combination",
205 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
206
207 recvData.rfinish();
208 return;
209 }
210 }
211 else
212 {
213 // send in universal language if player in .gmon mode (ignore spell effects)
214 if (sender->IsGameMaster())
215 lang = LANG_UNIVERSAL;
216 else
217 {
218 // send in universal language in two side iteration allowed mode
220 lang = LANG_UNIVERSAL;
221 else
222 {
223 switch (type)
224 {
225 case CHAT_MSG_PARTY:
227 case CHAT_MSG_RAID:
230 // allow two side chat at group channel if two side group allowed
232 lang = LANG_UNIVERSAL;
233 break;
234 case CHAT_MSG_GUILD:
235 case CHAT_MSG_OFFICER:
236 // allow two side chat at guild channel if two side guild allowed
238 lang = LANG_UNIVERSAL;
239 break;
240 }
241 }
242 // Overwritten by SPELL_AURA_MOD_LANGUAGE auras (Affects only Say and Yell)
244 if (!ModLangAuras.empty() && (type == CHAT_MSG_SAY || type == CHAT_MSG_YELL))
245 lang = ModLangAuras.front()->GetMiscValue();
246 }
247
248 if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
249 sender->UpdateSpeakTime(lang == LANG_ADDON ? Player::ChatFloodThrottle::ADDON : Player::ChatFloodThrottle::REGULAR);
250 }
251
252 std::string to, channel, msg;
253 bool ignoreChecks = false;
254 switch (type)
255 {
256 case CHAT_MSG_SAY:
257 case CHAT_MSG_EMOTE:
258 case CHAT_MSG_YELL:
259 case CHAT_MSG_PARTY:
261 case CHAT_MSG_GUILD:
262 case CHAT_MSG_OFFICER:
263 case CHAT_MSG_RAID:
268 msg = recvData.ReadCString(lang != LANG_ADDON);
269 break;
270 case CHAT_MSG_WHISPER:
271 recvData >> to;
272 msg = recvData.ReadCString(lang != LANG_ADDON);
273 break;
274 case CHAT_MSG_CHANNEL:
275 recvData >> channel;
276 msg = recvData.ReadCString(lang != LANG_ADDON);
277 break;
278 case CHAT_MSG_AFK:
279 case CHAT_MSG_DND:
280 msg = recvData.ReadCString(lang != LANG_ADDON);
281 ignoreChecks = true;
282 break;
283 }
284
285 // Our Warden module also uses SendAddonMessage as a way to communicate Lua check results to the server, see if this is that
286 if (type == CHAT_MSG_GUILD && lang == LANG_ADDON && _warden && _warden->ProcessLuaCheckResponse(msg))
287 {
288 return;
289 }
290
291 // pussywizard:
292 if (msg.length() > 255 || (lang != LANG_ADDON && msg.find("|0") != std::string::npos))
293 return;
294
295 if (!ignoreChecks)
296 {
297 if (msg.empty())
298 return;
299
300 if (lang == LANG_ADDON)
301 {
302 if (AddonChannelCommandHandler(this).ParseCommands(msg.c_str()))
303 return;
304 }
305 else
306 {
307 if (ChatHandler(this).ParseCommands(msg.c_str()))
308 return;
309
310 if (!_player->CanSpeak())
311 {
312 std::string timeStr = secsToTimeString(m_muteTime - GameTime::GetGameTime().count());
314 return;
315 }
316 }
317 }
318
319 // do message validity checks
320 if (lang != LANG_ADDON)
321 {
322 // cut at the first newline or carriage return
323 std::string::size_type pos = msg.find_first_of("\n\r");
324
325 if (pos == 0)
326 {
327 return;
328 }
329 else if (pos != std::string::npos)
330 {
331 msg.erase(pos);
332 }
333
334 // abort on any sort of nasty character
335 for (uint8 c : msg)
336 {
337 if (isNasty(c))
338 {
339 LOG_ERROR("network", "Player {} {} sent a message containing invalid character {} - blocked", GetPlayer()->GetName(),
340 GetPlayer()->GetGUID().ToString(), uint8(c));
341 return;
342 }
343 }
344
345 // collapse multiple spaces into one
347 {
348 auto end = std::unique(msg.begin(), msg.end(), [](char c1, char c2) { return (c1 == ' ') && (c2 == ' '); });
349 msg.erase(end, msg.end());
350 }
351
352 // Validate hyperlinks
354 {
355 return;
356 }
357 }
358
359 else
360 {
362 }
363
364 sScriptMgr->OnPlayerBeforeSendChatMessage(_player, type, lang, msg);
365
366 switch (type)
367 {
368 case CHAT_MSG_SAY:
369 case CHAT_MSG_EMOTE:
370 case CHAT_MSG_YELL:
371 {
372 // Prevent cheating
373 if (!sender->IsAlive())
374 return;
375
376 if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ))
377 {
379 return;
380 }
381
382 if (type == CHAT_MSG_SAY)
383 sender->Say(msg, Language(lang));
384 else if (type == CHAT_MSG_EMOTE)
385 sender->TextEmote(msg);
386 else if (type == CHAT_MSG_YELL)
387 sender->Yell(msg, Language(lang));
388 }
389 break;
390 case CHAT_MSG_WHISPER:
391 {
392 if (!normalizePlayerName(to))
393 {
395 break;
396 }
397
398 Player* receiver = ObjectAccessor::FindPlayerByName(to, false);
400 bool receiverIsPlayer = receiver ? !receiver->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT) : true;
401
402 if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) && receiver != sender && receiver && !receiver->IsGameMaster())
403 {
405 return;
406 }
407
408 if (!receiver || (lang != LANG_ADDON && !receiver->isAcceptWhispers() && receiver->GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !receiver->IsInWhisperWhiteList(sender->GetGUID())))
409 {
411 return;
412 }
413
414 // Trial accounts can only whisper players who have them on their friend list, or players who whispered them first.
415 if (sWorld->getBoolConfig(CONFIG_TRIAL_RESTRICTION_CHAT) && IsTrialAccount() && receiver != sender
416 && !receiver->GetSocial()->HasFriend(sender->GetGUID())
417 && !sender->IsInWhisperWhiteList(receiver->GetGUID()))
418 {
419 WorldPacket data;
421 SendPacket(&data);
422 return;
423 }
424
425 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) && senderIsPlayer && receiverIsPlayer)
426 if (GetPlayer()->GetTeamId() != receiver->GetTeamId())
427 {
429 return;
430 }
431
432 if (GetPlayer()->HasAura(1852) && !receiver->IsGameMaster())
433 {
435 return;
436 }
437
438 // If player is a Gamemaster and doesn't accept whisper, we auto-whitelist every player that the Gamemaster is talking to
439 // We also do that if a player is under the required level for whispers.
440 if (receiver->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) ||
442 sender->AddWhisperWhiteList(receiver->GetGUID());
443
444 // Allow a trial-account recipient to whisper back without being on the sender's friend list.
445 if (receiver->GetSession()->IsTrialAccount() && !receiver->IsInWhisperWhiteList(sender->GetGUID()))
446 receiver->AddWhisperWhiteList(sender->GetGUID());
447
448 GetPlayer()->Whisper(msg, Language(lang), receiver);
449 }
450 break;
451 case CHAT_MSG_PARTY:
453 {
454 // if player is in battleground, he cannot say to battleground members by /p
455 Group* group = GetPlayer()->GetOriginalGroup();
456 if (!group)
457 {
458 group = sender->GetGroup();
459 if (!group || group->isBGGroup())
460 return;
461 }
462
463 if (type == CHAT_MSG_PARTY_LEADER && !group->IsLeader(sender->GetGUID()))
464 return;
465
466 if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
467 return;
468
469 WorldPacket data;
470 ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, nullptr, msg);
471 group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID()));
472 }
473 break;
474 case CHAT_MSG_GUILD:
475 {
476 if (GetPlayer()->GetGuildId())
477 {
478 if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
479 {
480 if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, guild))
481 return;
482
483 guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
484 }
485 }
486 }
487 break;
488 case CHAT_MSG_OFFICER:
489 {
490 if (GetPlayer()->GetGuildId())
491 {
492 if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
493 {
494 if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, guild))
495 return;
496
497 guild->BroadcastToGuild(this, true, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
498 }
499 }
500 }
501 break;
502 case CHAT_MSG_RAID:
503 {
504 // if player is in battleground, he cannot say to battleground members by /ra
505 Group* group = GetPlayer()->GetOriginalGroup();
506 if (!group)
507 {
508 group = GetPlayer()->GetGroup();
509 if (!group || group->isBGGroup() || !group->isRaidGroup())
510 return;
511 }
512
513 if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
514 return;
515
516 WorldPacket data;
517 ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), sender, nullptr, msg);
518 group->BroadcastPacket(&data, false);
519 }
520 break;
522 {
523 // if player is in battleground, he cannot say to battleground members by /ra
524 Group* group = GetPlayer()->GetOriginalGroup();
525 if (!group)
526 {
527 group = GetPlayer()->GetGroup();
528 if (!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(sender->GetGUID()))
529 return;
530 }
531
532 if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
533 return;
534
535 WorldPacket data;
536 ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), sender, nullptr, msg);
537 group->BroadcastPacket(&data, false);
538 }
539 break;
541 {
542 Group* group = GetPlayer()->GetGroup();
543 if (!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())) || group->isBGGroup())
544 return;
545
546 if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
547 return;
548
549 // In battleground, raid warning is sent only to players in battleground - code is ok
550 WorldPacket data;
551 ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_WARNING, Language(lang), sender, nullptr, msg);
552 group->BroadcastPacket(&data, false);
553 }
554 break;
556 {
557 //battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
558 Group* group = GetPlayer()->GetGroup();
559 if (!group || !group->isBGGroup())
560 return;
561
562 if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
563 return;
564
565 WorldPacket data;
566 ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), sender, nullptr, msg);
567 group->BroadcastPacket(&data, false);
568 }
569 break;
571 {
572 // battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
573 Group* group = GetPlayer()->GetGroup();
574 if (!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID()))
575 return;
576
577 if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
578 return;
579
580 WorldPacket data;
581 ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), sender, nullptr, msg);
582 group->BroadcastPacket(&data, false);
583 }
584 break;
585 case CHAT_MSG_CHANNEL:
586 {
588 {
589 if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ))
590 {
592 return;
593 }
594 }
595
596 if (ChannelMgr* cMgr = ChannelMgr::forTeam(sender->GetTeamId()))
597 {
598 if (Channel* chn = cMgr->GetChannel(channel, sender))
599 {
600 if (!sScriptMgr->OnPlayerCanUseChat(sender, type, lang, msg, chn))
601 return;
602
603 chn->Say(sender->GetGUID(), msg.c_str(), lang);
604 }
605 }
606 }
607 break;
608 case CHAT_MSG_AFK:
609 {
610 if (!sender->IsInCombat())
611 {
612 if (sender->isAFK()) // Already AFK
613 {
614 if (msg.empty())
615 sender->ToggleAFK(); // Remove AFK
616 else
617 sender->autoReplyMsg = msg; // Update message
618 }
619 else // New AFK mode
620 {
621 sender->autoReplyMsg = msg.empty() ? GetAcoreString(LANG_PLAYER_AFK_DEFAULT) : msg;
622
623 if (sender->isDND())
624 sender->ToggleDND();
625
626 sender->ToggleAFK();
627 }
628
629 if (!sScriptMgr->OnPlayerCanUseChat(sender, type, lang, msg))
630 return;
631 }
632 break;
633 }
634 case CHAT_MSG_DND:
635 {
636 if (sender->isDND()) // Already DND
637 {
638 if (msg.empty())
639 sender->ToggleDND(); // Remove DND
640 else
641 sender->autoReplyMsg = msg; // Update message
642 }
643 else // New DND mode
644 {
645 sender->autoReplyMsg = msg.empty() ? GetAcoreString(LANG_PLAYER_DND_DEFAULT) : msg;
646
647 if (sender->isAFK())
648 sender->ToggleAFK();
649
650 sender->ToggleDND();
651 }
652
653 if (!sScriptMgr->OnPlayerCanUseChat(sender, type, lang, msg))
654 return;
655
656 break;
657 }
658 default:
659 LOG_ERROR("network.opcode", "CHAT: unknown message type {}, lang: {}", type, lang);
660 break;
661 }
662}
bool isNasty(uint8 c)
Definition ChatHandler.cpp:46
@ LANG_SAY_REQ
Definition Language.h:1240
@ LANG_GM_SILENCE
Definition Language.h:1255
@ LANG_UNKNOWN_LANGUAGE
Definition Language.h:753
@ LANG_NOT_LEARNED_LANGUAGE
Definition Language.h:754
@ LANG_WHISPER_REQ
Definition Language.h:1241
@ LANG_WAIT_BEFORE_SPEAKING
Definition Language.h:681
@ LANG_PLAYER_AFK_DEFAULT
Definition Language.h:686
@ LANG_MUTED_PLAYER
Definition Language.h:1407
@ LANG_PLAYER_DND_DEFAULT
Definition Language.h:685
@ LANG_CHANNEL_REQ
Definition Language.h:1242
LanguageDesc const * GetLanguageDescByID(uint32 lang)
Definition ObjectMgr.cpp:254
ChatMsg
Definition SharedDefines.h:3383
@ CHAT_MSG_RAID_WARNING
Definition SharedDefines.h:3425
@ CHAT_MSG_RAID
Definition SharedDefines.h:3388
@ CHAT_MSG_TEXT_EMOTE
Definition SharedDefines.h:3396
@ CHAT_MSG_SAY
Definition SharedDefines.h:3386
@ CHAT_MSG_PARTY_LEADER
Definition SharedDefines.h:3436
@ CHAT_MSG_RAID_LEADER
Definition SharedDefines.h:3424
@ CHAT_MSG_DND
Definition SharedDefines.h:3409
@ CHAT_MSG_YELL
Definition SharedDefines.h:3391
@ CHAT_MSG_PARTY
Definition SharedDefines.h:3387
@ CHAT_MSG_WHISPER
Definition SharedDefines.h:3392
@ CHAT_MSG_EMOTE
Definition SharedDefines.h:3395
@ CHAT_MSG_GUILD
Definition SharedDefines.h:3389
@ CHAT_MSG_OFFICER
Definition SharedDefines.h:3390
@ CHAT_MSG_RESTRICTED
Definition SharedDefines.h:3431
@ CHAT_MSG_AFK
Definition SharedDefines.h:3408
@ CHAT_MSG_ADDON
Definition SharedDefines.h:3384
@ CHAT_MSG_BATTLEGROUND
Definition SharedDefines.h:3429
@ CHAT_MSG_BATTLEGROUND_LEADER
Definition SharedDefines.h:3430
@ CHAT_MSG_CHANNEL
Definition SharedDefines.h:3402
Language
Definition SharedDefines.h:722
@ LANG_ADDON
Definition SharedDefines.h:741
#define MAX_CHAT_MSG_TYPE
Definition SharedDefines.h:3439
@ 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:33
@ CONFIG_CHAT_MUTE_FIRST_LOGIN
Definition WorldConfig.h:59
@ CONFIG_CHAT_FAKE_MESSAGE_PREVENTING
Definition WorldConfig.h:58
@ CONFIG_TRIAL_RESTRICTION_CHAT
Definition WorldConfig.h:509
@ CONFIG_ADDON_CHANNEL
Definition WorldConfig.h:26
@ CONFIG_CHAT_CHANNEL_LEVEL_REQ
Definition WorldConfig.h:249
@ CONFIG_CHAT_WHISPER_LEVEL_REQ
Definition WorldConfig.h:250
@ CONFIG_CHAT_TIME_MUTE_FIRST_LOGIN
Definition WorldConfig.h:253
@ CONFIG_CHAT_SAY_LEVEL_REQ
Definition WorldConfig.h:251
Definition Chat.h:280
void BroadcastPacket(WorldPacket const *packet, bool ignorePlayersInBGRaid, int group=-1, ObjectGuid ignore=ObjectGuid::Empty)
Definition Group.cpp:1969
bool CanSpeak() const
Definition PlayerMisc.cpp:71
bool IsInWhisperWhiteList(ObjectGuid guid)
Definition Player.cpp:16370
std::string autoReplyMsg
Definition Player.h:1154
uint32 GetTotalPlayedTime()
Definition Player.h:1210
bool HasSkill(uint32 skill) const
Definition Player.cpp:5601
void ToggleAFK()
Definition Player.cpp:1359
void UpdateSpeakTime(ChatFloodThrottle::Index index)
Definition PlayerMisc.cpp:31
void AddWhisperWhiteList(ObjectGuid guid)
Definition Player.h:2614
bool isAcceptWhispers() const
Definition Player.h:1174
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:9600
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:9573
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:9628
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:9675
void ToggleDND()
Definition Player.cpp:1368
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1433
std::vector< AuraEffect * > AuraEffectList
Definition Unit.h:681
void SendPlayerNotFoundNotice(std::string const &name)
Definition ChatHandler.cpp:814
void SendWrongFactionNotice()
Definition ChatHandler.cpp:828
std::unique_ptr< Warden > _warden
Definition WorldSession.h:1309
@ RBAC_PERM_TWO_SIDE_INTERACTION_CHAT
Definition RBAC.h:76
@ RBAC_PERM_CAN_FILTER_WHISPERS
Definition RBAC.h:87
@ RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ
Definition RBAC.h:70
Definition ObjectMgr.h:696
uint32 skill_id
Definition ObjectMgr.h:699
@ ADDON
Definition Player.h:2366

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_RESTRICTED, 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, CONFIG_TRIAL_RESTRICTION_CHAT, 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(), Player::GetSession(), Player::GetSocial(), Player::GetTeamId(), GetTeamId(), Player::GetTotalPlayedTime(), Unit::HasAura(), PlayerSocial::HasFriend(), HasPermission(), Player::HasSkill(), Player::isAcceptWhispers(), Player::isAFK(), Unit::IsAlive(), Group::IsAssistant(), Group::isBGGroup(), Player::isDND(), Player::IsGameMaster(), Unit::IsInCombat(), Player::IsInWhisperWhiteList(), Group::IsLeader(), isNasty(), Group::isRaidGroup(), Player::IsSpectator(), IsTrialAccount(), 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(), rbac::RBAC_PERM_CAN_FILTER_WHISPERS, rbac::RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ, rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT, ByteBuffer::ReadCString(), Player::ChatFloodThrottle::REGULAR, ByteBuffer::rfinish(), Player::Say(), secsToTimeString(), ChatHandler::SendNotification(), SendPacket(), 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)
585{
586 if (!sMapMgr->IsValidMapCoord(GetPlayer()->GetMap()->GetId(), packet.MapX, packet.MapY))
587 return;
588
589 Group* group = GetPlayer()->GetGroup();
590
591 if (!group)
592 return;
593
594 group->DoMinimapPing(GetPlayer()->GetGUID(), packet.MapX, packet.MapY);
595}
void DoMinimapPing(ObjectGuid sourceGuid, float mapX, float mapY)
Definition Group.cpp:2272
float MapY
Definition MiscPackets.h:104
float MapX
Definition MiscPackets.h:103

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)
742{
743 LOG_DEBUG("network", "WORLD: CMSG_GET_MIRRORIMAGE_DATA");
744 ObjectGuid guid;
745 recvData >> guid;
746
747 // Get unit for which data is needed by client
748 Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
749 if (!unit)
750 return;
751
752 if (!unit->HasCloneCasterAura())
753 return;
754
755 // Get creator of the unit (SPELL_AURA_CLONE_CASTER does not stack)
756 Unit* creator = unit->GetAuraEffectsByType(SPELL_AURA_CLONE_CASTER).front()->GetCaster();
757 if (!creator)
758 return;
759
761 data << guid;
762 data << uint32(creator->GetDisplayId());
763 data << uint8(creator->getRace());
764 data << uint8(creator->getGender());
765 data << uint8(creator->getClass());
766
767 if (creator->IsPlayer())
768 {
769 Player* player = creator->ToPlayer();
770 data << uint8(player->GetByteValue(PLAYER_BYTES, 0)); // skin
771 data << uint8(player->GetByteValue(PLAYER_BYTES, 1)); // face
772 data << uint8(player->GetByteValue(PLAYER_BYTES, 2)); // hair
773 data << uint8(player->GetByteValue(PLAYER_BYTES, 3)); // haircolor
774 data << uint8(player->GetByteValue(PLAYER_BYTES_2, 0)); // facialhair
775 data << uint32(player->GetGuildId()); // unk
776
777 static EquipmentSlots const itemSlots[] =
778 {
791 };
792
793 // Display items in visible slots
794 for (EquipmentSlots const* itr = &itemSlots[0]; *itr != EQUIPMENT_SLOT_END; ++itr)
795 {
797 data << uint32(0);
798 else if (*itr == EQUIPMENT_SLOT_BACK && player->HasPlayerFlag(PLAYER_FLAGS_HIDE_CLOAK))
799 data << uint32(0);
800 else if (Item const* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, *itr))
801 {
802 uint32 displayInfoId = item->GetTemplate()->DisplayInfoID;
803
804 sScriptMgr->OnGlobalMirrorImageDisplayItem(item, displayInfoId);
805
806 data << uint32(displayInfoId);
807 }
808 else
809 data << uint32(0);
810 }
811 }
812 else
813 {
814 // Skip player data for creatures
815 data << uint8(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 data << uint32(0);
826 data << uint32(0);
827 data << uint32(0);
828 data << uint32(0);
829 }
830
831 SendPacket(&data);
832}
@ PLAYER_FLAGS_HIDE_CLOAK
Definition Player.h:470
@ PLAYER_FLAGS_HIDE_HELM
Definition Player.h:469
EquipmentSlots
Definition Player.h:660
@ EQUIPMENT_SLOT_SHOULDERS
Definition Player.h:664
@ EQUIPMENT_SLOT_BODY
Definition Player.h:665
@ EQUIPMENT_SLOT_HANDS
Definition Player.h:671
@ EQUIPMENT_SLOT_TABARD
Definition Player.h:680
@ EQUIPMENT_SLOT_HEAD
Definition Player.h:662
@ EQUIPMENT_SLOT_LEGS
Definition Player.h:668
@ EQUIPMENT_SLOT_BACK
Definition Player.h:676
@ EQUIPMENT_SLOT_WAIST
Definition Player.h:667
@ EQUIPMENT_SLOT_FEET
Definition Player.h:669
@ EQUIPMENT_SLOT_CHEST
Definition Player.h:666
@ EQUIPMENT_SLOT_WRISTS
Definition Player.h:670
@ SPELL_AURA_CLONE_CASTER
Definition SpellAuraDefines.h:310
uint8 GetByteValue(uint16 index, uint8 offset) const
Definition Object.cpp:321
uint8 getClass() const
Definition Unit.h:844
bool HasCloneCasterAura() const
Definition Unit.h:1818
@ 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)
817{
819 data << GetPlayer()->GetGUID();
820
821 GetPlayer()->SendMessageToSet(&data, false);
822}
void SendMessageToSet(WorldPacket const *data, bool self) const override
Definition Player.cpp:5841
@ 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)
1497{
1498 LOG_DEBUG("network", "WORLD: {}", GetOpcodeNameForLogging((Opcodes)recv_data.GetOpcode()));
1499
1500 Opcodes opcode = (Opcodes)recv_data.GetOpcode();
1501
1502 ObjectGuid guid;
1503 uint32 counter;
1504 uint32 isApplied;
1505 recv_data >> guid.ReadAsPacked();
1506
1507 if (!_player)
1508 {
1509 recv_data.rfinish(); // prevent warnings spam
1510 return;
1511 }
1512
1513 recv_data >> counter;
1514
1515 MovementInfo movementInfo;
1516 movementInfo.guid = guid;
1517 ReadMovementInfo(recv_data, &movementInfo);
1518
1520 recv_data >> isApplied;
1521
1522 sScriptMgr->AnticheatSetCanFlybyServer(_player, movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY));
1523
1524 Unit* mover = _player->m_mover;
1525 Player* plrMover = mover->ToPlayer();
1526
1527 mover->m_movementInfo.flags = movementInfo.GetMovementFlags();
1528
1529 // old map - async processing, ignore
1530 if (counter <= _player->GetMapChangeOrderCounter())
1531 return;
1532
1533 if (!ProcessMovementInfo(movementInfo, mover, plrMover, recv_data))
1534 {
1535 recv_data.rfinish(); // prevent warnings spam
1536 return;
1537 }
1538
1539 if (_player->GetPendingFlightChange() == counter && opcode == CMSG_MOVE_SET_CAN_FLY_ACK)
1541
1542 Opcodes response;
1543
1544 switch (recv_data.GetOpcode())
1545 {
1546 case CMSG_MOVE_HOVER_ACK: response = MSG_MOVE_HOVER; break;
1547 case CMSG_MOVE_FEATHER_FALL_ACK: response = MSG_MOVE_FEATHER_FALL; break;
1548 case CMSG_MOVE_WATER_WALK_ACK: response = MSG_MOVE_WATER_WALK; break;
1549 case CMSG_MOVE_SET_CAN_FLY_ACK: response = MSG_MOVE_UPDATE_CAN_FLY; break;
1552 default: return;
1553 }
1554
1555 WorldPacket data(response, 8);
1556 WriteMovementInfo(&data, &movementInfo);
1558}
@ MOVEMENTFLAG_CAN_FLY
Definition UnitDefines.h:396
void SetPendingFlightChange(uint32 counter)
Definition Player.h:2689
uint32 GetPendingFlightChange() const
Definition Player.h:2688
@ 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:298
bool HasMovementFlag(uint32 flag) const
Definition Object.h:353
uint32 GetMovementFlags() const
Definition Object.h:349

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)
825{
826 LOG_DEBUG("network", "CMSG_MOVE_KNOCK_BACK_ACK");
827
828 Unit* mover = _player->m_mover;
829
830 ObjectGuid guid;
831 recvData >> guid.ReadAsPacked();
832
833 // pussywizard: typical check for incomming movement packets
834 if (!mover || !mover->IsInWorld() || mover->IsDuringRemoveFromWorld() || guid != mover->GetGUID())
835 {
836 recvData.rfinish(); // prevent warnings spam
837 return;
838 }
839
840 recvData.read_skip<uint32>(); // unk
841
842 MovementInfo movementInfo;
843 movementInfo.guid = guid;
844 ReadMovementInfo(recvData, &movementInfo);
845
846 // Relocate the mover to the acknowledged position. Otherwise the server (and the
847 // MSG_MOVE_KNOCK_BACK broadcast below) keeps using the pre-knockback position until
848 // the next regular movement packet arrives, desyncing the unit for nearby clients
849 if (!ProcessMovementInfo(movementInfo, mover, mover->ToPlayer(), recvData))
850 {
851 recvData.rfinish(); // prevent warnings spam
852 return;
853 }
854
855 if (mover->IsPlayer() && static_cast<Player*>(mover)->IsFreeFlying())
856 mover->SetCanFly(true);
857
859 WriteMovementInfo(&data, &movementInfo);
860 _player->SetCanTeleport(true);
861 // knockback specific info
862 data << movementInfo.jump.sinAngle;
863 data << movementInfo.jump.cosAngle;
864 data << movementInfo.jump.xyspeed;
865 data << movementInfo.jump.zspeed;
866
867 _player->SendMessageToSet(&data, false);
868}
bool IsFreeFlying() const
Definition Player.h:2620
void SetCanFly(bool enable)
Add the movement flag: MOVEMENTFLAGCAN_FLY. Generaly only use by players, allowing them to fly by pre...
Definition Unit.cpp:16179
@ MSG_MOVE_KNOCK_BACK
Definition Opcodes.h:271

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

Referenced by OpcodeTable::Initialize().

◆ HandleMovementOpcodes()

void WorldSession::HandleMovementOpcodes ( WorldPacket &  recvPacket)
363{
364 uint16 opcode = recvData.GetOpcode();
365
366 Unit* mover = _player->m_mover;
367
368 ASSERT(mover); // there must always be a mover
369
370 Player* plrMover = mover->ToPlayer();
371
372 // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck
373 if (plrMover && plrMover->IsBeingTeleported())
374 {
375 recvData.rfinish(); // prevent warnings spam
376 return;
377 }
378
379 /* extract packet */
380 ObjectGuid guid;
381 recvData >> guid.ReadAsPacked();
382
383 // prevent tampered movement data
384 if (!guid || guid != mover->GetGUID())
385 {
386 recvData.rfinish(); // prevent warnings spam
387 return;
388 }
389
390 // pussywizard: typical check for incomming movement packets | prevent tampered movement data
391 if (!mover || !(mover->IsInWorld()) || mover->IsDuringRemoveFromWorld() || guid != mover->GetGUID())
392 {
393 recvData.rfinish(); // prevent warnings spam
394 return;
395 }
396
397 MovementInfo movementInfo;
398 movementInfo.guid = guid;
399 ReadMovementInfo(recvData, &movementInfo);
400
401 if (!ProcessMovementInfo(movementInfo, mover, plrMover, recvData))
402 {
403 recvData.rfinish(); // prevent warnings spam
404 return;
405 }
406
407 if (opcode == CMSG_MOVE_FALL_RESET || opcode == CMSG_MOVE_CHNG_TRANSPORT)
408 return;
409
410 /* process position-change */
411 WorldPacket data(opcode, recvData.size());
412 WriteMovementInfo(&data, &movementInfo);
413 mover->SendMessageToSet(&data, _player);
414}
bool IsBeingTeleported() const
Definition Player.h:2121
@ 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)
796{
797 LOG_DEBUG("network", "WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER");
798
799 ObjectGuid old_mover_guid;
800 recvData >> old_mover_guid.ReadAsPacked();
801
802 // pussywizard: typical check for incomming movement packets
804 {
805 recvData.rfinish(); // prevent warnings spam
806 return;
807 }
808
809 MovementInfo mi;
810 mi.guid = old_mover_guid;
811 ReadMovementInfo(recvData, &mi);
812
814}

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)
998{
999 Opcodes opcode = (Opcodes)recvData.GetOpcode();
1000 LOG_DEBUG("network", "WORLD: {}", GetOpcodeNameForLogging(opcode));
1001
1002 ObjectGuid guid;
1003 uint32 counter;
1004 MovementInfo movementInfo;
1005 recvData >> guid.ReadAsPacked();
1006 recvData >> counter;
1007 movementInfo.guid = guid;
1008 ReadMovementInfo(recvData, &movementInfo);
1009
1010 Unit* mover = _player->m_mover;
1011
1012 if (mover->GetGUID() != guid)
1013 return;
1014
1015 if (opcode == CMSG_FORCE_MOVE_UNROOT_ACK) // unroot case
1016 {
1018 return;
1019
1020 // Legit unroots clear the state first, so a still immobilized mover was never sent one.
1021 // This ack bypasses VerifyMovementInfo()'s root check, so accepting it clears
1022 // MOVEMENTFLAG_ROOT permanently. Creatures only: ResurrectPlayer() unroots packet-only.
1023 if (mover->IsCreature() && mover->IsImmobilizedState())
1024 return;
1025 }
1026 else // root case
1027 {
1029 return;
1030 }
1031
1032 // old map - async processing, ignore
1033 if (counter <= _player->GetMapChangeOrderCounter())
1034 return;
1035
1036 if (!ProcessMovementInfo(movementInfo, mover, _player, recvData))
1037 return;
1038
1040 return;
1041
1043 WriteMovementInfo(&data, &movementInfo);
1044 mover->SendMessageToSet(&data, _player);
1045}
bool IsExpectingChangeTransport() const
Definition Player.h:2685
bool IsImmobilizedState() const
Definition Unit.h:786
@ 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(), Object::IsCreature(), Player::IsExpectingChangeTransport(), Unit::IsImmobilizedState(), 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 
)
431{
432 SynchronizeMovement(movementInfo);
433
434 mover->UpdatePosition(movementInfo.pos);
435 mover->m_movementInfo = movementInfo;
436
438 {
439 // if we boarded a transport, add us to it (generalized for both players and creatures)
440 if (!mover->GetTransport())
441 {
442 if (Transport* transport = mover->GetMap()->GetTransport(movementInfo.transport.guid))
443 {
444 mover->SetTransport(transport);
445 transport->AddPassenger(mover);
446 }
447 }
448 else if (mover->GetTransport()->GetGUID() != movementInfo.transport.guid)
449 {
450 // Switching transports
451 bool foundNewTransport = false;
452 mover->GetTransport()->RemovePassenger(mover);
453 if (Transport* transport = mover->GetMap()->GetTransport(movementInfo.transport.guid))
454 {
455 foundNewTransport = true;
456 mover->SetTransport(transport);
457 transport->AddPassenger(mover);
458 }
459
460 if (!foundNewTransport)
461 {
462 mover->SetTransport(nullptr);
463 movementInfo.transport.Reset();
464 }
465 }
466
467 if (!mover->GetTransport() && !mover->GetVehicle())
468 {
469 GameObject* go = mover->GetMap()->GetGameObject(movementInfo.transport.guid);
470 if (!go || go->GetGoType() != GAMEOBJECT_TYPE_TRANSPORT)
472 }
473 }
474 else
475 {
476 // if we were on a transport, leave (handles both players and creatures)
477 if (Transport* transport = mover->GetTransport())
478 {
479 if (mover->IsPlayer())
480 sScriptMgr->AnticheatSetUnderACKmount(mover->ToPlayer()); // just for safe
481
482 transport->RemovePassenger(mover);
483 mover->SetTransport(nullptr);
484 movementInfo.transport.Reset();
485 }
486 }
487
488 // Some vehicles allow the passenger to turn by himself
489 if (Vehicle* vehicle = mover->GetVehicle())
490 {
491 if (VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(mover))
492 {
493 if (seat->m_flags & VEHICLE_SEAT_FLAG_ALLOW_TURNING && movementInfo.pos.GetOrientation() != mover->GetOrientation())
494 {
495 mover->SetOrientation(movementInfo.pos.GetOrientation());
497 }
498 }
499 }
500
501 if (Player* plrMover = mover->ToPlayer()) // nothing is charmed, or player charmed
502 {
503 if (plrMover->IsSitState() && (movementInfo.flags & (MOVEMENTFLAG_MASK_MOVING | MOVEMENTFLAG_MASK_TURNING)))
504 plrMover->SetStandState(UNIT_STAND_STATE_STAND);
505
506 if (movementInfo.pos.GetPositionZ() < plrMover->GetMap()->GetMinHeight(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY()))
507 {
508 if (!plrMover->GetBattleground() || !plrMover->GetBattleground()->HandlePlayerUnderMap(_player))
509 {
510 if (plrMover->IsAlive())
511 {
512 // The Oculus under map case is handled by areatrigger (5001) and should not kill the player
513 if (plrMover->GetMapId() == MAP_THE_OCULUS)
514 return;
515
516 plrMover->SetPlayerFlag(PLAYER_FLAGS_IS_OUT_OF_BOUNDS);
517 plrMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
518 // player can be alive if GM
519 if (plrMover->IsAlive())
520 plrMover->KillPlayer();
521 }
522 // Rescue only released ghosts: teleporting an unreleased body would move the corpse
523 // out of instances (e.g. Eye of Eternity platform destruction, issue #25757).
524 else if (plrMover->HasPlayerFlag(PLAYER_FLAGS_GHOST) && !plrMover->HasPlayerFlag(PLAYER_FLAGS_IS_OUT_OF_BOUNDS))
525 plrMover->RepopAtGraveyard();
526 }
527 }
528 }
529}
@ MAP_THE_OCULUS
Definition AreaDefines.h:250
@ VEHICLE_SEAT_FLAG_ALLOW_TURNING
Definition DBCEnums.h:454
@ DAMAGE_FALL_TO_VOID
Definition Player.h:834
@ PLAYER_FLAGS_IS_OUT_OF_BOUNDS
Definition Player.h:473
@ GAMEOBJECT_TYPE_TRANSPORT
Definition SharedDefines.h:1575
@ AURA_INTERRUPT_FLAG_TURNING
Definition SpellDefines.h:55
@ MOVEMENTFLAG_ONTRANSPORT
Definition UnitDefines.h:381
@ MOVEMENTFLAG_MASK_MOVING
Definition UnitDefines.h:405
@ MOVEMENTFLAG_MASK_TURNING
Definition UnitDefines.h:410
Transport * GetTransport(ObjectGuid const &guid)
Definition Map.cpp:2457
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:15618
void SetTransport(Transport *t)
Definition Object.h:709
void SynchronizeMovement(MovementInfo &movementInfo)
Definition MovementHandler.cpp:416
void Reset()
Definition Object.h:306
ObjectGuid guid
Definition Object.h:315
void RemoveMovementFlag(uint32 flag)
Definition Object.h:352
Position pos
Definition Object.h:300
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, MAP_THE_OCULUS, MOVEMENTFLAG_MASK_MOVING, MOVEMENTFLAG_MASK_TURNING, MOVEMENTFLAG_ONTRANSPORT, PLAYER_FLAGS_GHOST, PLAYER_FLAGS_IS_OUT_OF_BOUNDS, MovementInfo::pos, Unit::RemoveAurasWithInterruptFlags(), MovementInfo::RemoveMovementFlag(), Transport::RemovePassenger(), MovementInfo::TransportInfo::Reset(), Position::SetOrientation(), WorldObject::SetTransport(), sScriptMgr, SynchronizeMovement(), Object::ToPlayer(), MovementInfo::transport, UNIT_STAND_STATE_STAND, Unit::UpdatePosition(), and VEHICLE_SEAT_FLAG_ALLOW_TURNING.

Referenced by ProcessMovementInfo().

◆ HandleMoveSplineDoneOpcode()

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

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)
293{
294 LOG_DEBUG("network", "MSG_MOVE_TELEPORT_ACK");
295
296 ObjectGuid guid;
297 recvData >> guid.ReadAsPacked();
298
299 uint32 flags, time;
300 recvData >> flags >> time; // unused
301 LOG_DEBUG("network.opcode", "Guid {}", guid.ToString());
302 LOG_DEBUG("network.opcode", "Flags {}, time {}", flags, time / IN_MILLISECONDS);
303
304 Player* plMover = _player->m_mover->ToPlayer();
305
306 if (!plMover || !plMover->IsBeingTeleportedNear())
307 return;
308
309 if (guid != plMover->GetGUID())
310 return;
311
312 plMover->SetSemaphoreTeleportNear(0);
313
314 uint32 old_zone = plMover->GetZoneId();
315
316 WorldLocation const& dest = plMover->GetTeleportDest();
317 Position oldPos(*plMover);
318
319 plMover->UpdatePosition(dest, true);
320
321 plMover->SetFallInformation(GameTime::GetGameTime().count(), dest.GetPositionZ());
322
323 // xinef: teleport pets if they are not unsummoned
324 if (Pet* pet = plMover->GetPet())
325 {
326 if (!pet->IsWithinDist3d(plMover, plMover->GetMap()->GetVisibilityRange() - 5.0f))
327 pet->NearTeleportTo(plMover->GetPositionX(), plMover->GetPositionY(), plMover->GetPositionZ(), pet->GetOrientation());
328 }
329
330 if (oldPos.GetExactDist2d(plMover) > 100.0f)
331 {
332 uint32 newzone, newarea;
333 plMover->GetZoneAndAreaId(newzone, newarea);
334 plMover->UpdateZone(newzone, newarea);
335
336 // new zone
337 if (old_zone != newzone)
338 {
339 // honorless target
340 if (plMover->pvpInfo.IsHostile)
341 plMover->CastSpell(plMover, 2479, true);
342
343 // in friendly area
344 else if (plMover->IsPvP() && !plMover->HasPlayerFlag(PLAYER_FLAGS_IN_PVP))
345 plMover->UpdatePvP(false, false);
346 }
347 }
348
349 // resummon pet
351
352 //lets process all delayed operations on successful teleport
354
356
357 // pussywizard: client forgets about losing control, resend it
358 if (plMover->HasUnitState(UNIT_STATE_FLEEING | UNIT_STATE_CONFUSED) || plMover->IsCharmed()) // only in such cases SetClientControl(self, false) is sent
359 plMover->SetClientControl(plMover, false, true);
360}
constexpr auto IN_MILLISECONDS
Definition Common.h:53
@ PLAYER_FLAGS_IN_PVP
Definition Player.h:468
@ UNIT_STATE_CONFUSED
Definition UnitDefines.h:184
@ UNIT_STATE_FLEEING
Definition UnitDefines.h:180
float GetVisibilityRange() const
Definition Map.h:200
void ReinitializeMovement()
Definition MotionMaster.cpp:1076
WorldLocation & GetTeleportDest()
Definition Player.h:2120
void UpdatePvP(bool state, bool _override=false)
Definition PlayerUpdates.cpp:1557
void UpdateZone(uint32 newZone, uint32 newArea, bool force=false)
Definition PlayerUpdates.cpp:1279
void ProcessDelayedOperations()
Definition Player.cpp:1665
bool UpdatePosition(float x, float y, float z, float orientation, bool teleport=false) override
Definition PlayerUpdates.cpp:1185
void SetSemaphoreTeleportNear(time_t tm)
Definition Player.h:2124
PvPInfo pvpInfo
Definition Player.h:1875
bool IsBeingTeleportedNear() const
Definition Player.h:2122
void SetClientControl(Unit *target, bool allowMove, bool packetOnly=false)
Definition Player.cpp:13169
void ResummonPetTemporaryUnSummonedIfAny()
Definition Player.cpp:14578
bool IsCharmed() const
Definition Unit.h:1315
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition Object.cpp:3187
Definition Position.h:27
bool IsHostile
Definition Player.h:347

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 OpcodeTable::Initialize().

◆ HandleMoveTimeSkippedOpcode()

void WorldSession::HandleMoveTimeSkippedOpcode ( WorldPacket &  recvData)
895{
896 LOG_DEBUG("network", "WORLD: Recvd CMSG_MOVE_TIME_SKIPPED");
897
898 ObjectGuid guid;
899 uint32 timeSkipped;
900 recvData >> guid.ReadAsPacked();
901 recvData >> timeSkipped;
902
903 Unit* mover = GetPlayer()->m_mover;
904
905 if (!mover)
906 {
907 LOG_ERROR("network.opcode", "WorldSession::HandleMoveTimeSkippedOpcode wrong mover state from the unit moved by the player [{}]", GetPlayer()->GetGUID().ToString());
908 return;
909 }
910
911 // prevent tampered movement data
912 if (guid != mover->GetGUID())
913 {
914 LOG_ERROR("network.opcode", "WorldSession::HandleMoveTimeSkippedOpcode wrong guid from the unit moved by the player [{}]", GetPlayer()->GetGUID().ToString());
915 return;
916 }
917
918 mover->m_movementInfo.time += timeSkipped;
919
920 WorldPacket data(MSG_MOVE_TIME_SKIPPED, recvData.size());
921 data << guid.WriteAsPacked();
922 data << timeSkipped;
923 GetPlayer()->SendMessageToSet(&data, false);
924}
@ MSG_MOVE_TIME_SKIPPED
Definition Opcodes.h:823
uint32 time
Definition Object.h:301

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 ( )
52{
53 // ignore unexpected far teleports
54 if (!GetPlayer()->IsBeingTeleportedFar())
55 return;
56
58
59 // get the teleport destination
60 WorldLocation const& loc = GetPlayer()->GetTeleportDest();
61
62 // possible errors in the coordinate validity check
64 {
65 KickPlayer("!MapMgr::IsValidMapCoord(loc)");
66 return;
67 }
68
69 // get the destination map entry, not the current one, this will fix homebind and reset greeting
70 MapEntry const* mEntry = sMapStore.LookupEntry(loc.GetMapId());
71 InstanceTemplate const* mInstance = sObjectMgr->GetInstanceTemplate(loc.GetMapId());
72
73 Map* oldMap = GetPlayer()->GetMap();
74 if (GetPlayer()->IsInWorld())
75 {
76 LOG_ERROR("network.opcode", "Player (Name {}) is still in world when teleported from map {} to new map {}", GetPlayer()->GetName(), oldMap->GetId(), loc.GetMapId());
77 oldMap->RemovePlayerFromMap(GetPlayer(), false);
78 }
79
80 // reset instance validity, except if going to an instance inside an instance
81 if (!GetPlayer()->m_InstanceValid && !mInstance)
82 {
83 GetPlayer()->m_InstanceValid = true;
84 // 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!
85 if (!sInstanceSaveMgr->PlayerIsPermBoundToInstance(GetPlayer()->GetGUID(), oldMap->GetId(), oldMap->GetDifficulty()))
86 sInstanceSaveMgr->PlayerUnbindInstance(GetPlayer()->GetGUID(), oldMap->GetId(), oldMap->GetDifficulty(), true);
87 }
88
89 // relocate the player to the teleport destination
90 Map* newMap = sMapMgr->CreateMap(loc.GetMapId(), GetPlayer());
91 // the CanEnter checks are done in TeleporTo but conditions may change
92 // while the player is in transit, for example the map may get full
93 if (!newMap || newMap->CannotEnter(GetPlayer(), false))
94 {
95 LOG_ERROR("network.opcode", "Map {} could not be created for player {}, porting player to homebind", loc.GetMapId(), GetPlayer()->GetGUID().ToString());
96 GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation());
97 return;
98 }
99
100 float z = loc.GetPositionZ() + GetPlayer()->GetHoverHeight();
101 GetPlayer()->Relocate(loc.GetPositionX(), loc.GetPositionY(), z, loc.GetOrientation());
102
103 GetPlayer()->ResetMap();
104 GetPlayer()->SetMap(newMap);
105
107
109
110 if (GetPlayer()->GetPendingFlightChange() <= GetPlayer()->GetMapChangeOrderCounter())
111 {
112 if (!GetPlayer()->HasIncreaseMountedFlightSpeedAura() && !GetPlayer()->HasFlyAura())
114 }
115
116 if (!GetPlayer()->GetMap()->AddPlayerToMap(GetPlayer()))
117 {
118 LOG_ERROR("network.opcode", "WORLD: failed to teleport player {} ({}) to map {} because of unknown reason!",
119 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString(), loc.GetMapId());
120 GetPlayer()->ResetMap();
121 GetPlayer()->SetMap(oldMap);
122 GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation());
123 return;
124 }
125
126 oldMap->AfterPlayerUnlinkFromMap();
127
128 // 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)
129 if (Transport* t = _player->GetTransport())
130 if (!t->IsInMap(_player))
131 {
132 // Client was never told to destroy its own transport
133 // Destroy it now or it keeps a phantom copy of the transport on the new map
134 UpdateData transData;
135 t->BuildOutOfRangeUpdateBlock(&transData);
136 WorldPacket packet;
137 transData.BuildPacket(packet);
138 _player->SendDirectMessage(&packet);
139
140 t->RemovePassenger(_player);
141 _player->m_transport = nullptr;
144 }
145
147 _player->GetThreatMgr().RemoveMeFromThreatLists(); // pussywizard: multithreading crashfix
148
149 CellCoord pair(Acore::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY()));
150 Cell cell(pair);
151 if (!GridCoord(cell.GridX(), cell.GridY()).IsCoordValid())
152 {
153 KickPlayer("!GridCoord(cell.GridX(), cell.GridY()).IsCoordValid()");
154 return;
155 }
156 newMap->LoadGrid(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
157
158 // pussywizard: player supposed to enter bg map
159 if (_player->InBattleground())
160 {
161 // but landed on another map, cleanup data
162 if (!mEntry->IsBattlegroundOrArena())
163 {
164 // release the unconsumed invite, otherwise the BG never satisfies its empty + uninvited deletion gate
165 if (Battleground* bg = _player->GetBattleground(true))
166 if (_player->IsInvitedForBattlegroundInstance(bg->GetInstanceID()))
167 {
168 bg->DecreaseInvitedCount(_player->GetBgTeamId());
169 _player->RemoveBattlegroundQueueId(BattlegroundMgr::BGQueueTypeId(bg->GetBgTypeID(), bg->GetArenaType()));
170 }
171
173 }
174 // everything ok
175 else if (Battleground* bg = _player->GetBattleground())
176 {
177 if (_player->IsInvitedForBattlegroundInstance()) // GMs are not invited, so they are not added to participants
178 bg->AddPlayer(_player);
179 }
180 }
181
182 // pussywizard: arena spectator stuff
183 {
184 if (newMap->IsBattleArena() && ((BattlegroundMap*)newMap)->GetBG() && _player->HasPendingSpectatorForBG(((BattlegroundMap*)newMap)->GetInstanceId()))
185 {
187 _player->SetIsSpectator(true);
189 ((BattlegroundMap*)newMap)->GetBG()->AddSpectator(_player);
191 }
192 else
193 _player->SetIsSpectator(false);
194
196
197 if (uint32 inviteInstanceId = _player->GetPendingSpectatorInviteInstanceId())
198 {
199 if (Battleground* tbg = sBattlegroundMgr->GetBattleground(inviteInstanceId, BATTLEGROUND_TYPE_NONE))
200 tbg->RemoveToBeTeleported(_player->GetGUID());
202 }
203 }
204
205 // xinef: do this again, player can be teleported inside bg->AddPlayer(_player)!!!!
206 CellCoord pair2(Acore::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY()));
207 Cell cell2(pair2);
208 if (!GridCoord(cell2.GridX(), cell2.GridY()).IsCoordValid())
209 {
210 KickPlayer("!GridCoord(cell2.GridX(), cell2.GridY()).IsCoordValid()");
211 return;
212 }
213 newMap->LoadGrid(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
214
216
217 // flight fast teleport case
218 if (GetPlayer()->IsInFlight())
219 {
220 if (!GetPlayer()->InBattleground())
221 {
222 // short preparations to continue flight
223 MovementGenerator* movementGenerator = GetPlayer()->GetMotionMaster()->top();
224 movementGenerator->Initialize(GetPlayer());
225 return;
226 }
227
228 // battleground state prepare, stop flight
231 }
232
233 // resurrect character at enter into instance where his corpse exist after add to map
234 Corpse* corpse = GetPlayer()->GetMap()->GetCorpseByPlayer(GetPlayer()->GetGUID());
235 if (corpse && corpse->GetType() != CORPSE_BONES)
236 {
237 if (mEntry->IsDungeon())
238 {
239 GetPlayer()->ResurrectPlayer(0.5f);
241 }
242 }
243
244 if (!corpse && mEntry->IsDungeon())
245 {
246 // resurrect character upon entering instance when the corpse is not available anymore
247 if (GetPlayer()->GetCorpseLocation().GetMapId() == mEntry->MapID)
248 {
249 GetPlayer()->ResurrectPlayer(0.5f);
251 }
252 }
253
254 bool allowMount = !mEntry->IsDungeon() || mEntry->IsBattlegroundOrArena();
255 if (mInstance)
256 {
257 Difficulty diff = GetPlayer()->GetDifficulty(mEntry->IsRaid());
258 if (MapDifficulty const* mapDiff = GetMapDifficultyData(mEntry->MapID, diff))
259 if (mapDiff->resetTime)
260 if (time_t timeReset = sInstanceSaveMgr->GetResetTimeFor(mEntry->MapID, diff))
261 {
262 uint32 timeleft = uint32(timeReset - GameTime::GetGameTime().count());
263 GetPlayer()->SendInstanceResetWarning(mEntry->MapID, diff, timeleft, true);
264 }
265 allowMount = mInstance->AllowMount;
266 }
267
268 // mount allow check
269 if (!allowMount)
271
272 // update zone immediately, otherwise leave channel will cause crash in mtmap
273 uint32 newzone, newarea;
274 GetPlayer()->GetZoneAndAreaId(newzone, newarea);
275 GetPlayer()->UpdateZone(newzone, newarea);
276
277 // honorless target
278 if (GetPlayer()->pvpInfo.IsHostile)
279 GetPlayer()->CastSpell(GetPlayer(), 2479, true);
280
281 // in friendly area
282 else if (GetPlayer()->IsPvP() && !GetPlayer()->HasPlayerFlag(PLAYER_FLAGS_IN_PVP))
283 GetPlayer()->UpdatePvP(false, false);
284
285 // resummon pet
287
288 //lets process all delayed operations on successful teleport
290}
#define SPECTATOR_ADDON_PREFIX
Definition ArenaSpectator.h:35
@ CORPSE_BONES
Definition Corpse.h:28
MapDifficulty const * GetMapDifficultyData(uint32 mapId, Difficulty difficulty)
Definition DBCStores.cpp:773
CoordPair< MAX_NUMBER_OF_GRIDS > GridCoord
Definition GridDefines.h:171
Definition Map.h:758
CorpseType GetType() const
Definition Corpse.h:73
static bool IsValidMapCoord(uint32 mapid, Position const &pos)
Definition MapMgr.h:90
virtual void RemovePlayerFromMap(Player *, bool)
Definition Map.cpp:719
void LoadGrid(float x, float y)
Definition Map.cpp:216
virtual void AfterPlayerUnlinkFromMap()
Definition Map.cpp:740
virtual EnterState CannotEnter(Player *, bool)
Definition Map.h:289
uint32 GetId() const
Definition Map.h:234
Corpse * GetCorpseByPlayer(ObjectGuid const &ownerGuid) const
Definition Map.h:375
Difficulty GetDifficulty() const
Definition Map.h:294
_Ty top() const
Definition MotionMaster.h:177
void MovementExpired(bool reset=true)
Definition MotionMaster.h:207
Definition MovementGenerator.h:28
virtual void Initialize(Unit *)=0
bool HasPendingSpectatorForBG(uint32 bgInstanceId) const
Definition Player.h:2629
void SendInitialPacketsAfterAddToMap()
Definition Player.cpp:11817
bool m_InstanceValid
Definition Player.h:2485
void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time, bool onEnterMap)
Definition Player.cpp:11971
bool IsInvitedForBattlegroundInstance() const
Definition Player.h:2305
Difficulty GetDifficulty(bool isRaid) const
Definition Player.h:1948
void SendInitialPacketsBeforeAddToMap()
Definition Player.cpp:11763
void ResetMap() override
Definition Player.cpp:15099
void RemoveCorpse()
Definition Player.cpp:4760
void ClearReceivedSpectatorResetFor()
Definition Player.h:2633
void SetPendingSpectatorInviteInstanceId(uint32 bgInstanceId)
Definition Player.h:2630
void SetIsSpectator(bool on)
Definition Player.cpp:15800
void SetSemaphoreTeleportFar(time_t tm)
Definition Player.h:2125
void SetMap(Map *map) override
Definition Player.cpp:15111
void SetPendingSpectatorForBG(uint32 bgInstanceId)
Definition Player.h:2628
uint32 GetPendingSpectatorInviteInstanceId() const
Definition Player.h:2631
void RemoveMeFromThreatLists()
Definition ThreatManager.cpp:798
bool IsThreateningAnyone(bool includeOffline=false) const
Definition ThreatManager.cpp:355
float GetHoverHeight() const
Definition Unit.h:1724
ThreatManager & GetThreatMgr()
Definition Unit.h:957
Definition UpdateData.h:52
bool BuildPacket(WorldPacket &packet)
Definition UpdateData.cpp:48
void UpdatePositionData()
Definition Object.cpp:1188
Transport * m_transport
Definition Object.h:813
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:126
bool AllowMount
Definition Map.h:129
Definition DBCStructure.h:2258
uint32 MapID
Definition DBCStructure.h:1362
bool IsBattlegroundOrArena() const
Definition DBCStructure.h:1393
bool IsDungeon() const
Definition DBCStructure.h:1387
void Relocate(float x, float y)
Definition Position.h:77

References _player, Map::AfterPlayerUnlinkFromMap(), InstanceTemplate::AllowMount, BATTLEGROUND_TYPE_NONE, BattlegroundMgr::BGQueueTypeId(), UpdateData::BuildPacket(), Map::CannotEnter(), Unit::CastSpell(), Player::CleanupAfterTaxiFlight(), Player::ClearReceivedSpectatorResetFor(), Acore::ComputeCellCoord(), CORPSE_BONES, Player::GetBattleground(), Player::GetBgTeamId(), Map::GetCorpseByPlayer(), Map::GetDifficulty(), Player::GetDifficulty(), GameTime::GetGameTime(), Object::GetGUID(), Unit::GetHoverHeight(), Map::GetId(), WorldObject::GetMap(), GetMapDifficultyData(), WorldLocation::GetMapId(), Unit::GetMotionMaster(), Position::GetOrientation(), Player::GetPendingSpectatorInviteInstanceId(), GetPlayer(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetTeleportDest(), Unit::GetThreatMgr(), WorldObject::GetTransport(), Corpse::GetType(), WorldObject::GetZoneAndAreaId(), Cell::GridX(), Cell::GridY(), ArenaSpectator::HandleResetCommand(), Player::HasPendingSpectatorForBG(), Player::InBattleground(), MovementGenerator::Initialize(), Map::IsBattleArena(), MapEntry::IsBattlegroundOrArena(), MapEntry::IsDungeon(), Player::IsInvitedForBattlegroundInstance(), MapEntry::IsRaid(), ThreatManager::IsThreateningAnyone(), 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::RemoveBattlegroundQueueId(), Player::RemoveCorpse(), ThreatManager::RemoveMeFromThreatLists(), MovementInfo::RemoveMovementFlag(), Map::RemovePlayerFromMap(), MovementInfo::TransportInfo::Reset(), Player::ResetMap(), Player::ResummonPetTemporaryUnSummonedIfAny(), Player::ResurrectPlayer(), sBattlegroundMgr, ArenaSpectator::SendCommand(), Player::SendDirectMessage(), 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(), and LogoutPlayer().

◆ HandleMoveWorldportAckOpcode()

void WorldSession::HandleMoveWorldportAckOpcode ( WorldPacket &  recvPacket)
46{
47 LOG_DEBUG("network", "WORLD: got MSG_MOVE_WORLDPORT_ACK.");
49}
void HandleMoveWorldportAck()
Definition MovementHandler.cpp:51

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)
947{
948 // Sent by client when cinematic actually begun. So we begin the server side process
950}
void StartCinematicCamera()
Definition CinematicMgr.cpp:38

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

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:139
#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:437
std::string const & GetText(LocaleConstant locale=DEFAULT_LOCALE, uint8 gender=GENDER_MALE, bool forceGender=false) const
Definition ObjectMgr.h:459
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)
569{
570 LOG_DEBUG("network", "Received opcode CMSG_OFFER_PETITION"); // ok
571
572 ObjectGuid petitionguid, plguid;
573 uint32 junk;
574 Player* player;
575 recvData >> junk; // this is not petition type!
576 recvData >> petitionguid; // petition guid
577 recvData >> plguid; // player guid
578
580 if (!player)
581 return;
582
583 Petition const* petition = sPetitionMgr->GetPetition(petitionguid);
584 if (!petition)
585 return;
586
587 if (petition->petitionType != GUILD_CHARTER_TYPE)
588 {
589 if (GetPlayer()->GetTeamId() != player->GetTeamId() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA))
590 {
592 return;
593 }
594
595 if (player->GetLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
596 {
597 // player is too low level to join an arena team
599 return;
600 }
601
603 if (slot >= MAX_ARENA_SLOT)
604 return;
605
606 if (player->GetArenaTeamId(slot))
607 {
608 // player is already in an arena team
610 return;
611 }
612
613 if (player->GetArenaTeamIdInvited())
614 {
616 return;
617 }
618 }
619 else
620 {
621 if (GetPlayer()->GetTeamId() != player->GetTeamId() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD))
622 {
624 return;
625 }
626
627 if (player->GetGuildId())
628 {
630 return;
631 }
632
633 if (player->GetGuildIdInvited())
634 {
636 return;
637 }
638 }
639
640 Signatures const* signatures = sPetitionMgr->GetSignature(petitionguid);
641 uint8 signs = signatures ? signatures->signatureMap.size() : 0;
642
643 WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8 + 8 + 4 + signs + signs * 12));
644 data << petitionguid; // petition guid
645 data << _player->GetGUID(); // owner guid
646 data << uint32(petition->petitionId); // guild/team id (31-bit safe)
647 data << uint8(signs); // sign's count
648
649 if (signs)
650 for (SignatureMap::const_iterator itr = signatures->signatureMap.begin(); itr != signatures->signatureMap.end(); ++itr)
651 {
652 data << itr->first; // Player GUID
653 data << uint32(0); // there 0 ...
654 }
655
656 player->SendDirectMessage(&data);
657}
@ 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:630
uint32 GetGuildIdInvited()
Definition Player.h:1931
@ SMSG_PETITION_SHOW_SIGNATURES
Definition Opcodes.h:477
@ GUILD_CHARTER_TYPE
Definition WorldSession.h:287
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 uint8 bagIndex, slot;
215
216 recvPacket >> bagIndex >> slot;
217
218 LOG_DEBUG("network.opcode", "bagIndex: {}, slot: {}", bagIndex, slot);
219
220 Item* item = pUser->GetItemByPos(bagIndex, slot);
221 if (!item)
222 {
223 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
224 return;
225 }
226
227 // The client locks the item when it sends CMSG_OPEN_ITEM and only unlocks it on a loot
228 // response for that item's guid, so a plain equip error would leave it grayed out until /reload.
229 if (!pUser->IsAlive())
230 {
231 pUser->SendEquipError(EQUIP_ERR_YOU_ARE_DEAD, item, nullptr);
232 pUser->SendLootRelease(item->GetGUID());
233 return;
234 }
235
236 ItemTemplate const* proto = item->GetTemplate();
237 if (!proto)
238 {
239 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, nullptr);
240 return;
241 }
242
243 // Verify that the bag is an actual bag or wrapped item that can be used "normally"
244 if (!proto->HasFlag(ITEM_FLAG_HAS_LOOT) && !item->IsWrapped())
245 {
246 pUser->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, nullptr);
247 LOG_ERROR("network.opcode", "Possible hacking attempt: Player {} [{}] tried to open item [{}, entry: {}] which is not openable!",
248 pUser->GetName(), pUser->GetGUID().ToString(), item->GetGUID().ToString(), proto->ItemId);
249 return;
250 }
251
252 // locked item
253 uint32 lockId = proto->LockID;
254 if (lockId)
255 {
256 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
257
258 if (!lockInfo)
259 {
260 pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, nullptr);
261 LOG_ERROR("network.opcode", "WORLD::OpenItem: item [{}] has an unknown lockId: {}!", item->GetGUID().ToString(), lockId);
262 return;
263 }
264
265 // was not unlocked yet
266 if (item->IsLocked())
267 {
268 pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, nullptr);
269 return;
270 }
271 }
272
273 if (sScriptMgr->OnPlayerBeforeOpenItem(pUser, item))
274 {
275 if (item->IsWrapped())// wrapped?
276 {
278 stmt->SetData(0, item->GetGUID().GetCounter());
280 .WithPreparedCallback(std::bind(&WorldSession::HandleOpenWrappedItemCallback, this, bagIndex, slot, item->GetGUID().GetCounter(), std::placeholders::_1)));
281 }
282 else
283 {
284 pUser->SendLoot(item->GetGUID(), LOOT_CORPSE);
285 }
286 }
287}
@ CHAR_SEL_CHARACTER_GIFT_BY_ITEM
Definition CharacterDatabase.h:132
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:289
Definition DBCStructure.h:1344

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(), Player::SendLootRelease(), 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 
)
290{
291 if (!GetPlayer())
292 return;
293
294 Item* item = GetPlayer()->GetItemByPos(bagIndex, slot);
295 if (!item)
296 return;
297
298 if (item->GetGUID().GetCounter() != itemLowGUID || !item->IsWrapped()) // during getting result, gift was swapped with another item
299 return;
300
301 if (!result)
302 {
303 LOG_ERROR("network", "Wrapped item {} don't have record in character_gifts table and will deleted", item->GetGUID().ToString());
304 GetPlayer()->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
305 return;
306 }
307
308 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
309
310 Field* fields = result->Fetch();
311 uint32 entry = fields[0].Get<uint32>();
312 uint32 flags = fields[1].Get<uint32>();
313
315 item->SetEntry(entry);
316 item->SetUInt32Value(ITEM_FIELD_FLAGS, flags);
318
321
323 stmt->SetData(0, item->GetGUID().GetCounter());
324 trans->Append(stmt);
325
326 CharacterDatabase.CommitTransaction(trans);
327}
@ CHAR_DEL_GIFT
Definition CharacterDatabase.h:131
@ ITEM_FIELD_MAXDURABILITY
Definition UpdateFields.h:70
void SetEntry(uint32 entry)
Definition Object.h:124

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)
1144{
1145 uint32 passOnLoot;
1146 recvData >> passOnLoot; // 1 always pass, 0 do not pass
1147
1148 if (!GetPlayer())
1149 return;
1150
1151 GetPlayer()->SetPassOnGroupLoot(passOnLoot);
1152}
void SetPassOnGroupLoot(bool bPassOnGroupLoot)
Definition Player.h:2537

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:60
std::string Text
Definition ObjectMgr.h:61
uint32 NextPage
Definition ObjectMgr.h:62

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)
729{
730 Group* group = GetPlayer()->GetGroup();
731 if (!group)
732 return;
733
734 ObjectGuid senderGuid = GetPlayer()->GetGUID();
735 if (!group->IsLeader(senderGuid) && !group->IsAssistant(senderGuid))
736 return;
737
738 uint8 assignment;
739 bool apply;
740 ObjectGuid guid;
741 recvData >> assignment >> apply;
742 recvData >> guid;
743
744 switch (assignment)
745 {
748 group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_MAINASSIST);
749 break;
751 group->RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINTANK); // Remove main assist flag from current if any.
752 group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_MAINTANK);
753 default:
754 break;
755 }
756
757 group->SendUpdate();
758}
@ GROUP_ASSIGN_MAINASSIST
Definition Group.h:82
@ GROUP_ASSIGN_MAINTANK
Definition Group.h:81
@ MEMBER_FLAG_MAINASSIST
Definition Group.h:76
@ MEMBER_FLAG_MAINTANK
Definition Group.h:75
void RemoveUniqueGroupMemberFlag(GroupMemberFlags flag)
Definition Group.cpp:2736

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)
932{
933 if (!_player->IsInWorld())
934 return;
935
936 // pet/charmed
938 if (pet && pet->ToPet() && pet->ToPet()->getPetType() == HUNTER_PET)
939 {
940 if (pet->IsPet())
941 {
942 if (pet->GetGUID() == _player->GetPetGUID())
943 {
944 uint32 feelty = pet->GetPower(POWER_HAPPINESS);
945 pet->SetPower(POWER_HAPPINESS, feelty > 50000 ? (feelty - 50000) : 0);
946 }
947
949 }
950 else if (pet->GetGUID() == _player->GetCharmGUID())
952 }
953}
@ PET_SAVE_AS_DELETED
Definition PetDefines.h:42
@ HUNTER_PET
Definition PetDefines.h:33
@ POWER_HAPPINESS
Definition SharedDefines.h:261
PetType getPetType() const
Definition Pet.h:52
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition Player.cpp:9299
void StopCastingCharm(Aura *except=nullptr)
Definition Player.cpp:9529
Pet * ToPet()
Definition Unit.h:730
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool fromRegenerate=false)
Definition Unit.cpp:12038
bool IsPet() const
Definition Unit.h:798
ObjectGuid GetPetGUID() const
Definition Unit.h:724
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:393
@ COMMAND_ABANDON
Definition Unit.h:577
@ COMMAND_FOLLOW
Definition Unit.h:575
ControlSet m_Controlled
Definition Unit.h:2079
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 // Don't bother if pet is already attacking target
235 if (pet->GetVictim() == TargetUnit && pet->GetCharmInfo()->IsCommandAttack())
236 return;
237
239 // This is true if pet has no target or has target but targets differs.
240 if (pet->GetVictim() != TargetUnit || (pet->GetVictim() == TargetUnit && !pet->GetCharmInfo()->IsCommandAttack()))
241 {
242 pet->AttackStop();
243
244 if (!pet->IsPlayer() && pet->ToCreature()->IsAIEnabled)
245 {
246 charmInfo->SetIsCommandAttack(true);
247 charmInfo->SetIsAtStay(false);
248 charmInfo->SetIsFollowing(false);
249 charmInfo->SetIsCommandFollow(false);
250 charmInfo->SetIsReturning(false);
251
252 pet->ToCreature()->AI()->AttackStart(TargetUnit);
253
254 //10% chance to play special pet attack talk, else growl
255 if (pet->IsPet() && pet->ToPet()->getPetType() == SUMMON_PET && pet != TargetUnit && roll_chance_i(10))
257 else
258 {
259 // 90% chance for pet and 100% chance for charmed creature
260 pet->SendPetAIReaction(guid1);
261 }
262 }
263 else // charmed player
264 {
265 charmInfo->SetIsCommandAttack(true);
266 charmInfo->SetIsAtStay(false);
267 charmInfo->SetIsFollowing(false);
268 charmInfo->SetIsCommandFollow(false);
269 charmInfo->SetIsReturning(false);
270
271 pet->Attack(TargetUnit, true);
272 pet->SendPetAIReaction(guid1);
273 }
274 }
275 break;
276 }
277 case COMMAND_ABANDON: // abandon (hunter pet) or dismiss (summoned pet)
278 if (pet->GetCharmerGUID() == GetPlayer()->GetGUID())
279 {
281 }
282 else if (pet->GetOwnerGUID() == GetPlayer()->GetGUID())
283 {
284 ASSERT(pet->IsCreature());
285 if (pet->IsPet())
286 {
287 if (pet->ToPet()->getPetType() == HUNTER_PET)
289 else
290 {
291 pet->SendPetDismissSound();
292 //dismissing a summoned pet is like killing them (this prevents returning a soulshard...)
294 }
295 }
297 {
298 pet->ToTempSummon()->UnSummon();
299 }
300 }
301 break;
302 default:
303 LOG_ERROR("network.opcode", "WORLD: unknown PET flag Action {} and spellId {}.", uint32(flag), spellId);
304 }
305 break;
306 case ACT_REACTION: // 0x6
307 switch (spellId)
308 {
309 case REACT_PASSIVE: //passive
310 pet->AttackStop();
311 if (pet->ToPet())
313 pet->ClearInPetCombat();
314 [[fallthrough]];
315
316 case REACT_DEFENSIVE: //recovery
317 case REACT_AGGRESSIVE: //activete
318 if (pet->IsCreature())
319 pet->ToCreature()->SetReactState(ReactStates(spellId));
320 else
321 charmInfo->SetPlayerReactState(ReactStates(spellId));
322 break;
323 }
324 break;
325 case ACT_DISABLED: // 0x81 spell (disabled), ignore
326 case ACT_PASSIVE: // 0x01
327 case ACT_ENABLED: // 0xC1 spell
328 {
329 Unit* unit_target = nullptr;
330
331 // do not cast unknown spells
332 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
333 if (!spellInfo)
334 {
335 LOG_ERROR("network.opcode", "WORLD: unknown PET spell id {}", spellId);
336 return;
337 }
338
339 if (guid2)
340 unit_target = ObjectAccessor::GetUnit(*_player, guid2);
341 else if (!spellInfo->IsPositive())
342 return;
343
344 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
345 {
346 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)
347 return;
348 }
349
350 TriggerCastFlags triggerCastFlags = TRIGGERED_NONE;
351
352 if (spellInfo->IsPassive())
353 return;
354
355 // cast only learned spells
356 if (!pet->HasSpell(spellId))
357 {
358 bool allow = false;
359
360 // allow casting of spells triggered by clientside periodic trigger auras
362 {
363 allow = true;
364 triggerCastFlags = TRIGGERED_FULL_MASK;
365 }
366
367 if (!allow)
368 return;
369 }
370
371 Spell* spell = new Spell(pet, spellInfo, triggerCastFlags);
372 spell->LoadScripts(); // xinef: load for CheckPetCast
373
374 SpellCastResult result = spell->CheckPetCast(unit_target);
375
376 //auto turn to target unless possessed
377 if (result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->isPossessed() && !pet->IsVehicle())
378 {
379 if (unit_target)
380 {
381 pet->SetInFront(unit_target);
382 if (unit_target->IsPlayer())
383 pet->SendUpdateToPlayer(unit_target->ToPlayer());
384 }
385 else if (Unit* unit_target2 = spell->m_targets.GetUnitTarget())
386 {
387 pet->SetInFront(unit_target2);
388 if (unit_target2->IsPlayer())
389 pet->SendUpdateToPlayer(unit_target2->ToPlayer());
390 }
391 if (Unit* powner = pet->GetCharmerOrOwner())
392 if (powner->IsPlayer())
393 pet->SendUpdateToPlayer(powner->ToPlayer());
394
395 result = SPELL_CAST_OK;
396 }
397
398 if (result == SPELL_CAST_OK)
399 {
400 if (!spellInfo->IsCooldownStartedOnEvent())
401 {
402 pet->ToCreature()->AddSpellCooldown(spellId, 0, 0);
403 }
404
405 unit_target = spell->m_targets.GetUnitTarget();
406
407 //10% chance to play special pet attack talk, else growl
408 //actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
409 if (pet->IsPet() && (pet->ToPet()->getPetType() == SUMMON_PET) && (pet != unit_target) && roll_chance_i(10))
411 else
412 {
413 pet->SendPetAIReaction(guid1);
414 }
415
416 if (unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->isPossessed() && !pet->IsVehicle())
417 {
418 // This is true if pet has no target or has target but targets differs.
419 if (pet->GetVictim() != unit_target)
420 {
421 pet->ToCreature()->AI()->AttackStart(unit_target);
422 }
423 }
424
425 spell->prepare(&(spell->m_targets));
426
427 // Stop the current spline before the next movement update can interrupt a stationary channel.
428 if (Pet* controlledPet = pet->ToPet())
429 if (spellInfo->IsChanneled() && !spellInfo->IsActionAllowedChannel()
430 && controlledPet->IsMovementPreventedByCasting())
431 controlledPet->StopMoving();
432
433 // spell->prepare() can delete charm info.
434 // Let's refresh the pointer.
435 charmInfo = pet->GetCharmInfo();
436 if (charmInfo)
437 {
438 charmInfo->SetForcedSpell(0);
439 charmInfo->SetForcedTargetGUID();
440 }
441 }
442 else if (pet->ToPet() && (result == SPELL_FAILED_LINE_OF_SIGHT || result == SPELL_FAILED_OUT_OF_RANGE))
443 {
444 unit_target = spell->m_targets.GetUnitTarget();
445 bool haspositiveeffect = false;
446
447 if (!unit_target)
448 {
449 delete spell;
450 return;
451 }
452
453 // search positive effects for spell
454 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
455 {
456 if (spellInfo->_IsPositiveEffect(i, true))
457 {
458 haspositiveeffect = true;
459 break;
460 }
461 }
462
463 if (pet->isPossessed() || pet->IsVehicle())
464 Spell::SendCastResult(GetPlayer(), spellInfo, 0, result);
465 else if (charmInfo->HasCommandState(COMMAND_STAY))
466 spell->SendPetCastResult(result);
467 else if (GetPlayer()->IsFriendlyTo(unit_target) && !haspositiveeffect)
469 else
471
472 if (!pet->HasSpellCooldown(spellId))
473 if (pet->ToPet())
474 pet->ToPet()->RemoveSpellCooldown(spellId, true);
475
476 spell->finish(false);
477 delete spell;
478
479 if (_player->HasPacifyAura())
480 return;
481
482 if (charmInfo->HasCommandState(COMMAND_STAY))
483 {
484 charmInfo->SetForcedSpell(0);
485 charmInfo->SetForcedTargetGUID();
486 return;
487 }
488
489 bool tempspellIsPositive = false;
490
491 if (!GetPlayer()->IsFriendlyTo(unit_target))
492 {
493 // only place where pet can be player
494 Unit* TargetUnit = ObjectAccessor::GetUnit(*_player, guid2);
495 if (!TargetUnit)
496 return;
497
498 if (Unit* owner = pet->GetOwner())
499 if (!owner->IsValidAttackTarget(TargetUnit))
500 return;
501
503 // This is true if pet has no target or has target but targets differs.
504 if (pet->GetVictim() != TargetUnit || (pet->GetVictim() == TargetUnit && !pet->GetCharmInfo()->IsCommandAttack()))
505 {
506 if (pet->GetVictim())
507 pet->AttackStop();
508
509 if (!pet->IsPlayer() && pet->ToCreature() && pet->ToCreature()->IsAIEnabled)
510 {
511 charmInfo->SetIsCommandAttack(true);
512 charmInfo->SetIsAtStay(false);
513 charmInfo->SetIsFollowing(false);
514 charmInfo->SetIsCommandFollow(false);
515 charmInfo->SetIsReturning(false);
516
517 pet->ToCreature()->AI()->AttackStart(TargetUnit);
518
519 if (pet->IsPet() && pet->ToPet()->getPetType() == SUMMON_PET && pet != TargetUnit && roll_chance_i(10))
521 else
522 pet->SendPetAIReaction(guid1);
523 }
524 else // charmed player
525 {
526 if (pet->GetVictim() && pet->GetVictim() != TargetUnit)
527 pet->AttackStop();
528
529 charmInfo->SetIsCommandAttack(true);
530 charmInfo->SetIsAtStay(false);
531 charmInfo->SetIsFollowing(false);
532 charmInfo->SetIsCommandFollow(false);
533 charmInfo->SetIsReturning(false);
534
535 pet->Attack(TargetUnit, true);
536 pet->SendPetAIReaction(guid1);
537 }
538
539 pet->ToPet()->CastWhenWillAvailable(spellId, unit_target, ObjectGuid::Empty, tempspellIsPositive);
540 }
541 }
542 else if (haspositiveeffect)
543 {
544 bool tmpSpellIsPositive = true;
546 // This is true if pet has no target or has target but targets differs.
547 Unit* victim = pet->GetVictim();
548 if (victim)
549 {
550 pet->AttackStop();
551 }
552 else
553 victim = nullptr;
554
555 if (!pet->IsPlayer() && pet->ToCreature() && pet->ToCreature()->IsAIEnabled)
556 {
557 pet->StopMoving();
558 pet->GetMotionMaster()->Clear();
559
560 charmInfo->SetIsCommandAttack(false);
561 charmInfo->SetIsAtStay(false);
562 charmInfo->SetIsFollowing(false);
563 charmInfo->SetIsCommandFollow(false);
564 charmInfo->SetIsReturning(false);
565
566 pet->GetMotionMaster()->MoveFollow(unit_target, PET_FOLLOW_DIST, rand_norm() * 2 * M_PI);
567
568 if (pet->IsPet() && pet->ToPet()->getPetType() == SUMMON_PET && pet != unit_target && roll_chance_i(10))
570 else
571 {
572 pet->SendPetAIReaction(guid1);
573 }
574
575 ObjectGuid oldTarget = ObjectGuid::Empty;
576 if (victim)
577 oldTarget = victim->GetGUID();
578
579 pet->ToPet()->CastWhenWillAvailable(spellId, unit_target, oldTarget, tmpSpellIsPositive);
580 }
581 }
582 }
583 else
584 {
585 // dont spam alerts
586 if (charmInfo->HasCommandState(COMMAND_STAY) || !charmInfo->GetForcedSpell())
587 {
588 if (pet->isPossessed() || pet->IsVehicle())
589 Spell::SendCastResult(GetPlayer(), spellInfo, 0, result);
590 else
591 spell->SendPetCastResult(result);
592 }
593
594 if (!pet->ToCreature()->HasSpellCooldown(spellId))
595 GetPlayer()->SendClearCooldown(spellId, pet);
596
597 spell->finish(false);
598 delete spell;
599
600 // reset specific flags in case of spell fail. AI will reset other flags
601 if (charmInfo->HasCommandState(COMMAND_STAY))
602 {
603 charmInfo->SetForcedSpell(0);
604 charmInfo->SetForcedTargetGUID();
605 }
606 else
607 pet->PetSpellFail(spellInfo, unit_target, result);
608 }
609 break;
610 }
611 default:
612 LOG_ERROR("network.opcode", "WORLD: unknown PET flag Action {} and spellId {}.", uint32(flag), spellId);
613 }
614}
@ ACT_DISABLED
Definition CharmInfo.h:62
#define MAX_SPELL_EFFECTS
Definition DBCStructure.h:1673
@ MOTION_SLOT_CONTROLLED
Definition MotionMaster.h:66
@ NULL_MOTION_TYPE
Definition MotionMaster.h:59
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:1436
@ TARGET_UNIT_DEST_AREA_ENEMY
Definition SharedDefines.h:1425
@ TARGET_UNIT_SRC_AREA_ENEMY
Definition SharedDefines.h:1424
@ SPELL_FAILED_UNIT_NOT_INFRONT
Definition SharedDefines.h:1071
@ SPELL_FAILED_OUT_OF_RANGE
Definition SharedDefines.h:1034
@ SPELL_FAILED_LINE_OF_SIGHT
Definition SharedDefines.h:984
@ SPELL_FAILED_TARGET_FRIENDLY
Definition SharedDefines.h:1052
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT
Definition SpellAuraDefines.h:111
@ UNIT_MASK_SUMMON
Definition UnitDefines.h:159
@ UNIT_MASK_CONTROLLABLE_GUARDIAN
Definition UnitDefines.h:167
@ UNIT_MASK_GUARDIAN
Definition UnitDefines.h:161
@ UNIT_MASK_MINION
Definition UnitDefines.h:160
@ UNIT_STATE_FOLLOW
Definition UnitDefines.h:182
ReactStates
Definition Unit.h:566
@ REACT_DEFENSIVE
Definition Unit.h:568
@ REACT_PASSIVE
Definition Unit.h:567
@ REACT_AGGRESSIVE
Definition Unit.h:569
@ COMMAND_ATTACK
Definition Unit.h:576
@ COMMAND_STAY
Definition Unit.h:574
bool HasSpellCooldown(uint32 spell_id) const override
Definition Creature.cpp:3083
void AddSpellCooldown(uint32 spell_id, uint32, uint32 end_time, bool needSendToClient=false, bool forceSendToSpectator=false) override
Definition Creature.cpp:3008
void SetReactState(ReactStates state)
A creature can have 3 ReactStates : Agressive, Passive, Neutral.
Definition Creature.h:100
MovementGeneratorType GetMotionSlotType(int slot) const
Definition MotionMaster.cpp:1093
void MoveIdle()
Definition MotionMaster.cpp:235
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:448
void Clear(bool reset=true)
Definition MotionMaster.h:194
void ClearCastWhenWillAvailable()
Definition Pet.cpp:2442
void RemoveSpellCooldown(uint32 spell_id, bool update)
Definition Pet.cpp:2450
void CastWhenWillAvailable(uint32 spellid, Unit *spellTarget, ObjectGuid oldTarget, bool spellIsPositive=false)
Definition Pet.cpp:2426
void SendClearCooldown(uint32 spell_id, Unit *target)
Definition Player.cpp:15088
bool IsCooldownStartedOnEvent() const
Definition SpellInfo.cpp:1257
bool IsActionAllowedChannel() const
Definition SpellInfo.cpp:1306
bool _IsPositiveEffect(uint8 effIndex, bool deep) const
Definition SpellInfo.cpp:3057
void LoadScripts()
Definition Spell.cpp:8876
void SendPetCastResult(SpellCastResult result)
Definition Spell.cpp:4842
SpellCastResult CheckPetCast(Unit *target)
Definition Spell.cpp:7085
virtual void AttackStart(Unit *)
Definition UnitAI.cpp:29
void ClearUnitState(uint32 f)
Definition Unit.h:738
bool IsVehicle() const
Definition Unit.h:801
virtual void setDeathState(DeathState s, bool despawn=false)
Definition Unit.cpp:11120
Unit * GetOwner() const
Definition Unit.cpp:7487
virtual bool HasSpellCooldown(uint32) const
Definition Unit.h:1340
void SendPetAIReaction(ObjectGuid guid) const
Definition Unit.cpp:12620
ObjectGuid GetOwnerGUID() const override
Definition Unit.h:714
void PetSpellFail(SpellInfo const *spellInfo, Unit *target, uint32 result)
Definition Unit.cpp:15891
void StopMoving()
Definition Unit.cpp:12639
CharmInfo * GetCharmInfo()
Definition Unit.h:1286
virtual bool HasSpell(uint32) const
Definition Unit.h:1587
Unit * GetCharmerOrOwner() const
Definition Unit.h:1291
void ClearInPetCombat()
Definition Unit.cpp:10460
bool isPossessed() const
Definition Unit.h:1316
void SendPetActionSound(PetAction action) const
Definition Unit.cpp:12609
virtual float GetFollowAngle() const
Definition Unit.h:1901
Unit * GetVictim() const
Definition Unit.h:904
void StopMovingOnCurrentPos()
Definition Unit.cpp:12678
bool IsAIEnabled
Definition Unit.h:2102
uint32 HasUnitTypeMask(uint32 mask) const
Definition Unit.h:742
ObjectGuid GetCharmerGUID() const
Definition Unit.h:720
bool HasAuraTypeWithTriggerSpell(AuraType auratype, uint32 triggerSpell) const
Definition Unit.cpp:5822
void SetInFront(WorldObject const *target)
Definition Unit.cpp:16062
bool HasPacifyAura() const
Definition Unit.h:1830
void SendPetDismissSound() const
Definition Unit.cpp:12614
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
bool HasCommandState(CommandStates state) const
Definition CharmInfo.h:137
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(), Unit::GetMotionMaster(), MotionMaster::GetMotionSlotType(), Unit::GetOwner(), Unit::GetOwnerGUID(), Pet::getPetType(), GetPlayer(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTarget(), Unit::GetVictim(), Unit::HasAuraTypeWithTriggerSpell(), CharmInfo::HasCommandState(), Unit::HasPacifyAura(), Unit::HasSpell(), Creature::HasSpellCooldown(), Unit::HasSpellCooldown(), Unit::HasUnitTypeMask(), HUNTER_PET, Unit::InterruptNonMeleeSpells(), SpellInfo::IsActionAllowedChannel(), Unit::IsAIEnabled, SpellInfo::IsChanneled(), Unit::IsCharmed(), CharmInfo::IsCommandAttack(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), SpellInfo::IsPassive(), Unit::IsPet(), Object::IsPlayer(), SpellInfo::IsPositive(), Unit::isPossessed(), Unit::IsVehicle(), 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(), Spell::SendCastResult(), Player::SendClearCooldown(), 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(), 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)
605{
606 ObjectGuid guid;
607 uint32 spellId;
608
609 recvPacket >> guid;
610 recvPacket >> spellId;
611
612 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
613 if (!spellInfo)
614 {
615 LOG_ERROR("network.opcode", "WORLD: unknown PET spell id {}", spellId);
616 return;
617 }
618
620
621 if (!pet)
622 {
623 LOG_ERROR("network.opcode", "HandlePetCancelAura: Attempt to cancel an aura for non-existant pet {} by player {}", guid.ToString(), GetPlayer()->GetName());
624 return;
625 }
626
627 if (pet != GetPlayer()->GetGuardianPet() && pet != GetPlayer()->GetCharm())
628 {
629 LOG_ERROR("network.opcode", "HandlePetCancelAura: Pet {} is not a pet of player {}", guid.ToString(), GetPlayer()->GetName());
630 return;
631 }
632
633 if (!pet->IsAlive())
634 {
636 return;
637 }
638
640}
@ FEEDBACK_PET_DEAD
Definition PetDefines.h:74
void SendPetActionFeedback(uint8 msg) const
-------—Pet responses methods--------------—
Definition Unit.cpp:12598

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

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
88 {
90 return;
91 }
92
93 charterid = GUILD_CHARTER;
94 cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD);
95 type = GUILD_CHARTER_TYPE;
96 }
97 else
98 {
100 if (_player->GetLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
101 {
103 return;
104 }
105
106 switch (clientIndex) // arenaSlot+1 as received from client (1 from 3 case)
107 {
108 case 1:
109 charterid = ARENA_TEAM_CHARTER_2v2;
110 cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_2v2);
112 break;
113 case 2:
114 charterid = ARENA_TEAM_CHARTER_3v3;
115 cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_3v3);
117 break;
118 case 3:
119 charterid = ARENA_TEAM_CHARTER_5v5;
120 cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_5v5);
122 break;
123 default:
124 LOG_DEBUG("network", "unknown selection at buy arena petition: {}", clientIndex);
125 return;
126 }
127
128 if (_player->GetArenaTeamId(clientIndex - 1)) // arenaSlot+1 as received from client
129 {
131 return;
132 }
133 }
134
135 sScriptMgr->OnPlayerPetitionBuy(_player, creature, charterid, cost, type);
136
137 if (type == GUILD_CHARTER_TYPE)
138 {
139 if (sGuildMgr->GetGuildByName(name))
140 {
142 return;
143 }
144
146 {
148 return;
149 }
150 }
151 else
152 {
153 if (sArenaTeamMgr->GetArenaTeamByName(name))
154 {
156 return;
157 }
159 {
161 return;
162 }
163 }
164
165 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(charterid);
166 if (!pProto)
167 {
168 _player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, nullptr, charterid, 0);
169 return;
170 }
171
172 if (!_player->HasEnoughMoney(cost))
173 {
174 //player hasn't got enough money
175 _player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, creature, charterid, 0);
176 return;
177 }
178
179 ItemPosCountVec dest;
180 InventoryResult msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, charterid, pProto->BuyCount);
181 if (msg != EQUIP_ERR_OK)
182 {
183 _player->SendEquipError(msg, nullptr, nullptr, charterid);
184 return;
185 }
186
187 _player->ModifyMoney(-(int32)cost);
188 Item* charter = _player->StoreNewItem(dest, charterid, true);
189 if (!charter)
190 return;
191
192 // Use a 31-bit safe petition id instead of the raw item guid
193 uint32 petitionId = sPetitionMgr->GeneratePetitionId();
194 charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1, petitionId);
195 // ITEM_FIELD_ENCHANTMENT_1_1 is guild/arenateam id
196 // ITEM_FIELD_ENCHANTMENT_1_1+1 is current signatures count (showed on item)
197 charter->SetState(ITEM_CHANGED, _player);
198 _player->SendNewItem(charter, 1, true, false);
199
200 // a petition is invalid, if both the owner and the type matches
201 // we checked above, if this player is in an arenateam, so this must be
202 // datacorruption
203 Petition const* petition = sPetitionMgr->GetPetitionByOwnerWithType(_player->GetGUID(), type);
204
205 CharacterDatabase.EscapeString(name);
206 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
207
208 if (petition)
209 {
210 LOG_DEBUG("network", "Invalid petition: {}", petition->petitionGuid.ToString());
211
212 trans->Append("DELETE FROM petition WHERE petitionguid = {}", petition->petitionGuid.GetCounter());
213 trans->Append("DELETE FROM petition_sign WHERE petitionguid = {}", petition->petitionGuid.GetCounter());
214
215 // xinef: clear petition store
216 sPetitionMgr->RemovePetition(petition->petitionGuid);
217 }
218
219 // xinef: petition pointer is invalid from now on
220
222 // petition_id, ownerguid, petitionguid(item guid), name, type
223 stmt->SetData(0, petitionId);
224 stmt->SetData(1, _player->GetGUID().GetCounter());
225 stmt->SetData(2, charter->GetGUID().GetCounter());
226 stmt->SetData(3, name);
227 stmt->SetData(4, uint8(type));
228 trans->Append(stmt);
229
230 CharacterDatabase.CommitTransaction(trans);
231
232 // xinef: fill petition store (include petitionId)
233 sPetitionMgr->AddPetition(charter->GetGUID(), _player->GetGUID(), name, uint8(type), petitionId);
234}
@ 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:389
@ 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:340
@ ITEM_FIELD_ENCHANTMENT_1_1
Definition UpdateFields.h:43
@ CONFIG_CHARTER_COST_GUILD
Definition WorldConfig.h:367
@ CONFIG_CHARTER_COST_ARENA_5v5
Definition WorldConfig.h:370
@ CONFIG_CHARTER_COST_ARENA_2v2
Definition WorldConfig.h:368
@ CONFIG_CHARTER_COST_ARENA_3v3
Definition WorldConfig.h:369
static bool IsValidCharterName(std::string_view name)
Definition ObjectMgr.cpp:9319
bool IsTabardDesigner() const
Definition Unit.h:815
@ ARENA_TEAM_CHARTER_2v2_TYPE
Definition WorldSession.h:288
@ ARENA_TEAM_CHARTER_3v3_TYPE
Definition WorldSession.h:289
@ ARENA_TEAM_CHARTER_5v5_TYPE
Definition WorldSession.h:290
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, CONFIG_TRIAL_RESTRICTION_GUILD, 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, ERR_GUILD_PERMISSIONS, 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(), IsTrialAccount(), 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)
548{
549 LOG_DEBUG("network", "Received opcode MSG_PETITION_DECLINE"); // ok
550
551 ObjectGuid petitionguid;
552 ObjectGuid ownerguid;
553 recvData >> petitionguid; // petition guid
554 LOG_DEBUG("network", "Petition {} declined by {}", petitionguid.ToString(), _player->GetGUID().ToString());
555
556 Petition const* petition = sPetitionMgr->GetPetition(petitionguid);
557 if (!petition)
558 return;
559
560 if (Player* owner = ObjectAccessor::FindConnectedPlayer(ownerguid)) // petition owner online
561 {
563 data << _player->GetGUID();
564 owner->SendDirectMessage(&data);
565 }
566}
@ 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)
276{
277 LOG_DEBUG("network", "Received opcode CMSG_PETITION_QUERY"); // ok
278
279 ObjectGuid::LowType guildguid;
280 ObjectGuid petitionguid;
281 recvData >> guildguid; // in Trinity always same as petition low guid
282 recvData >> petitionguid; // petition guid
283 LOG_DEBUG("network", "CMSG_PETITION_QUERY Petition ({}) Guild GUID {}", petitionguid.ToString(), guildguid);
284
285 SendPetitionQueryOpcode(petitionguid);
286}
void SendPetitionQueryOpcode(ObjectGuid petitionguid)
Definition PetitionsHandler.cpp:288

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

Referenced by OpcodeTable::Initialize().

◆ HandlePetitionRenameOpcode()

void WorldSession::HandlePetitionRenameOpcode ( WorldPacket &  recvData)
336{
337 LOG_DEBUG("network", "Received opcode MSG_PETITION_RENAME"); // ok
338
339 ObjectGuid petitionGuid;
340 std::string newName;
341
342 recvData >> petitionGuid; // guid
343 recvData >> newName; // new name
344
345 Item* item = _player->GetItemByGuid(petitionGuid);
346 if (!item)
347 return;
348
349 Petition const* petition = sPetitionMgr->GetPetition(petitionGuid);
350 if (!petition)
351 {
352 LOG_DEBUG("network", "CMSG_PETITION_QUERY failed for petition ({})", petitionGuid.ToString());
353 return;
354 }
355
356 if (petition->petitionType == GUILD_CHARTER_TYPE)
357 {
358 if (sGuildMgr->GetGuildByName(newName))
359 {
361 return;
362 }
363 if (!ObjectMgr::IsValidCharterName(newName))
364 {
366 return;
367 }
368 }
369 else
370 {
371 if (sArenaTeamMgr->GetArenaTeamByName(newName))
372 {
374 return;
375 }
376 if (!ObjectMgr::IsValidCharterName(newName))
377 {
379 return;
380 }
381 }
382
384
385 stmt->SetData(0, newName);
386 stmt->SetData(1, petition->petitionId);
387
388 CharacterDatabase.Execute(stmt);
389
390 // xinef: update petition container
391 const_cast<Petition*>(petition)->petitionName = newName;
392
393 LOG_DEBUG("network", "Petition ({}) renamed to {}", petitionGuid.ToString(), newName);
394 WorldPacket data(MSG_PETITION_RENAME, (8 + newName.size() + 1));
395 data << petitionGuid;
396 data << newName;
397 SendPacket(&data);
398}
@ CHAR_UPD_PETITION_NAME
Definition CharacterDatabase.h:283
@ 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)
839{
840 LOG_DEBUG("network", "Received CMSG_PETITION_SHOWLIST");
841
842 ObjectGuid guid;
843 recvData >> guid;
844
846}
void SendPetitionShowList(ObjectGuid guid)
Definition PetitionsHandler.cpp:848

References LOG_DEBUG, and SendPetitionShowList().

Referenced by OpcodeTable::Initialize().

◆ HandlePetitionShowSignOpcode()

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

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

Referenced by OpcodeTable::Initialize().

◆ HandlePetLearnTalent()

void WorldSession::HandlePetLearnTalent ( WorldPacket &  recvPacket)
1129{
1130 LOG_DEBUG("network", "WORLD: CMSG_PET_LEARN_TALENT");
1131
1132 ObjectGuid guid;
1133 uint32 talent_id, requested_rank;
1134 recvData >> guid >> talent_id >> requested_rank;
1135
1136 _player->LearnPetTalent(guid, talent_id, requested_rank);
1138}

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

Referenced by OpcodeTable::Initialize().

◆ HandlePetNameQuery()

void WorldSession::HandlePetNameQuery ( WorldPacket &  recvData)
617{
618 LOG_DEBUG("network.opcode", "HandlePetNameQuery. CMSG_PET_NAME_QUERY");
619
620 uint32 petnumber;
621 ObjectGuid petguid;
622
623 recvData >> petnumber;
624 recvData >> petguid;
625
626 SendPetNameQuery(petguid, petnumber);
627}
void SendPetNameQuery(ObjectGuid guid, uint32 petnumber)
Definition PetHandler.cpp:629

References LOG_DEBUG, and SendPetNameQuery().

Referenced by OpcodeTable::Initialize().

◆ HandlePetRename()

void WorldSession::HandlePetRename ( WorldPacket &  recvData)
841{
842 LOG_DEBUG("network.opcode", "HandlePetRename. CMSG_PET_RENAME");
843
844 ObjectGuid petguid;
845 uint8 isdeclined;
846
847 std::string name;
848 DeclinedName declinedname;
849
850 recvData >> petguid;
851 recvData >> name;
852 recvData >> isdeclined;
853
854 PetStable* petStable = _player->GetPetStable();
855
856 Pet* pet = ObjectAccessor::GetPet(*_player, petguid);
857
858 // check it!
859 if (!pet || !pet->IsPet() || ((Pet*)pet)->getPetType() != HUNTER_PET ||
861 pet->GetOwnerGUID() != _player->GetGUID() || !pet->GetCharmInfo() ||
862 !petStable || !petStable->CurrentPet || petStable->CurrentPet->PetNumber != pet->GetCharmInfo()->GetPetNumber())
863 {
864 return;
865 }
866
868 if (res != PET_NAME_SUCCESS)
869 {
870 SendPetNameInvalid(res, name, nullptr);
871 return;
872 }
873
874 pet->SetName(name);
875
876 Unit* owner = pet->GetOwner();
877 if (owner && (owner->IsPlayer()) && owner->ToPlayer()->GetGroup())
879
881
882 petStable->CurrentPet->Name = name;
883 petStable->CurrentPet->WasRenamed = true;
884
885 if (isdeclined)
886 {
887 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
888 {
889 recvData >> declinedname.name[i];
890 }
891
892 std::wstring wname;
893 Utf8toWStr(name, wname);
894 if (!ObjectMgr::CheckDeclinedNames(wname, declinedname))
895 {
897 return;
898 }
899 }
900
901 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
902 if (isdeclined)
903 {
904 if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
905 {
907 stmt->SetData(0, pet->GetCharmInfo()->GetPetNumber());
908 trans->Append(stmt);
909
910 stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_CHAR_PET_DECLINEDNAME);
911 stmt->SetData(0, _player->GetGUID().GetCounter());
912
913 for (uint8 i = 0; i < 5; i++)
914 stmt->SetData(i + 1, declinedname.name[i]);
915
916 trans->Append(stmt);
917 }
918 }
919
921 stmt->SetData(0, name);
922 stmt->SetData(1, _player->GetGUID().GetCounter());
923 stmt->SetData(2, pet->GetCharmInfo()->GetPetNumber());
924 trans->Append(stmt);
925
926 CharacterDatabase.CommitTransaction(trans);
927
928 pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(GameTime::GetGameTime().count())); // cast can't be helped
929}
@ CHAR_ADD_CHAR_PET_DECLINEDNAME
Definition CharacterDatabase.h:492
@ CHAR_UPD_CHAR_PET_NAME
Definition CharacterDatabase.h:494
@ CHAR_DEL_CHAR_PET_DECLINEDNAME
Definition CharacterDatabase.h:491
PetNameInvalidReason
Definition SharedDefines.h:3912
@ PET_NAME_SUCCESS
Definition SharedDefines.h:3914
@ PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME
Definition SharedDefines.h:3928
@ UNIT_CAN_BE_RENAMED
Definition UnitDefines.h:152
#define MAX_DECLINED_NAME_CASES
Definition Unit.h:547
@ UNIT_FIELD_PET_NAME_TIMESTAMP
Definition UpdateFields.h:133
static PetNameInvalidReason CheckPetName(std::string_view name)
Definition ObjectMgr.cpp:9359
static bool CheckDeclinedNames(std::wstring w_ownname, DeclinedName const &names)
Definition ObjectMgr.cpp:9654
Optional< PetInfo > CurrentPet
Definition PetDefines.h:235
Player * GetOwner() const
Definition Pet.cpp:2485
void SetGroupUpdateFlag(uint32 flag)
Definition Player.h:2523
PetStable * GetPetStable()
Definition Player.h:1226
void SetUInt32Value(uint16 index, uint32 value)
Definition Unit.cpp:16980
void SetName(std::string const &newname)
Definition Object.h:536
void SendPetNameInvalid(uint32 error, std::string const &name, DeclinedName *declinedName)
Definition PetHandler.cpp:1112
Pet * GetPet(WorldObject const &, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:239
uint32 GetPetNumber() const
Definition CharmInfo.h:132
Definition Unit.h:550
std::string name[MAX_DECLINED_NAME_CASES]
Definition Unit.h:551

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)
697{
698 LOG_DEBUG("network.opcode", "HandlePetSetAction. CMSG_PET_SET_ACTION");
699
700 ObjectGuid petguid;
701 uint8 count;
702
703 recvData >> petguid;
704
705 Unit* checkPet = ObjectAccessor::GetUnit(*_player, petguid);
706 if (!checkPet || checkPet != _player->GetFirstControlled())
707 {
708 LOG_ERROR("network.opcode", "HandlePetSetAction: Unknown pet ({}) or pet owner ({})", petguid.ToString(), _player->GetGUID().ToString());
709 return;
710 }
711
712 count = (recvData.size() == 24) ? 2 : 1;
713
714 uint32 position[2];
715 uint32 data[2];
716 bool move_command = false;
717
718 for (uint8 i = 0; i < count; ++i)
719 {
720 recvData >> position[i];
721 recvData >> data[i];
722
723 uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data[i]);
724
725 //ignore invalid position
726 if (position[i] >= MAX_UNIT_ACTION_BAR_INDEX)
727 return;
728
729 // in the normal case, command and reaction buttons can only be moved, not removed
730 // at moving count == 2, at removing count == 1
731 // ignore attempt to remove command|reaction buttons (not possible at normal case)
732 if (act_state == ACT_COMMAND || act_state == ACT_REACTION)
733 {
734 if (count == 1)
735 return;
736
737 move_command = true;
738 }
739 }
740
741 Unit::ControlSet petsSet;
742 if (checkPet->GetEntry() != petguid.GetEntry())
743 petsSet.insert(checkPet);
744 else
745 petsSet = _player->m_Controlled;
746
747 // Xinef: loop all pets with same entry (fixes partial state change for feral spirits)
748 for (Unit::ControlSet::const_iterator itr = petsSet.begin(); itr != petsSet.end(); ++itr)
749 {
750 Unit* pet = *itr;
751 if (checkPet->GetEntry() == petguid.GetEntry() && pet->GetEntry() != petguid.GetEntry())
752 continue;
753
754 CharmInfo* charmInfo = pet->GetCharmInfo();
755 if (!charmInfo)
756 {
757 LOG_ERROR("network.opcode", "WorldSession::HandlePetSetAction: object ({} TypeId: {}) is considered pet-like but doesn't have a charminfo!",
758 pet->GetGUID().ToString(), pet->GetTypeId());
759 continue;
760 }
761
762 // check swap (at command->spell swap client remove spell first in another packet, so check only command move correctness)
763 if (move_command)
764 {
765 uint8 act_state_0 = UNIT_ACTION_BUTTON_TYPE(data[0]);
766 if (act_state_0 == ACT_COMMAND || act_state_0 == ACT_REACTION)
767 {
768 uint32 spell_id_0 = UNIT_ACTION_BUTTON_ACTION(data[0]);
769 UnitActionBarEntry const* actionEntry_1 = charmInfo->GetActionBarEntry(position[1]);
770 if (!actionEntry_1 || spell_id_0 != actionEntry_1->GetAction() ||
771 act_state_0 != actionEntry_1->GetType())
772 continue;
773 }
774
775 uint8 act_state_1 = UNIT_ACTION_BUTTON_TYPE(data[1]);
776 if (act_state_1 == ACT_COMMAND || act_state_1 == ACT_REACTION)
777 {
778 uint32 spell_id_1 = UNIT_ACTION_BUTTON_ACTION(data[1]);
779 UnitActionBarEntry const* actionEntry_0 = charmInfo->GetActionBarEntry(position[0]);
780 if (!actionEntry_0 || spell_id_1 != actionEntry_0->GetAction() ||
781 act_state_1 != actionEntry_0->GetType())
782 continue;
783 }
784 }
785
786 for (uint8 i = 0; i < count; ++i)
787 {
788 uint32 spell_id = UNIT_ACTION_BUTTON_ACTION(data[i]);
789 uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data[i]);
790
791 //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
792 if (!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && !pet->HasSpell(spell_id)))
793 {
794 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id))
795 {
796 //sign for autocast
797 if (act_state == ACT_ENABLED)
798 {
799 if (pet->IsCreature() && pet->IsPet())
800 {
801 ((Pet*)pet)->ToggleAutocast(spellInfo, true);
802 }
803 else
804 {
805 for (auto iterator = GetPlayer()->m_Controlled.begin(); iterator != GetPlayer()->m_Controlled.end(); ++iterator)
806 {
807 if ((*iterator)->GetEntry() == pet->GetEntry())
808 {
809 (*iterator)->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, true);
810 }
811 }
812 }
813 }
814 //sign for no/turn off autocast
815 else if (act_state == ACT_DISABLED)
816 {
817 if (pet->IsCreature() && pet->IsPet())
818 {
819 ((Pet*)pet)->ToggleAutocast(spellInfo, false);
820 }
821 else
822 {
823 for (auto iterator = GetPlayer()->m_Controlled.begin(); iterator != GetPlayer()->m_Controlled.end(); ++iterator)
824 {
825 if ((*iterator)->GetEntry() == pet->GetEntry())
826 {
827 (*iterator)->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, false);
828 }
829 }
830 }
831 }
832 }
833
834 charmInfo->SetActionBar(position[i], spell_id, ActiveStates(act_state));
835 }
836 }
837 }
838}
#define MAX_UNIT_ACTION_BAR_INDEX
Definition CharmInfo.h:29
ActiveStates
Definition CharmInfo.h:60
uint32 GetEntry() const
Definition ObjectGuid.h:147
TypeID GetTypeId() const
Definition Object.h:135
std::set< Unit * > ControlSet
Definition Unit.h:668
Unit * GetFirstControlled() const
Definition Unit.cpp:7967
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)
956{
958 if (!checkPet)
959 {
960 LOG_ERROR("entities.pet", "WorldSession::HandlePetSpellAutocastOpcode: Pet {} not found.", packet.PetGUID.ToString());
961 return;
962 }
963
964 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(packet.SpellID);
965 if (!spellInfo)
966 {
967 LOG_ERROR("spells.pet", "WorldSession::HandlePetSpellAutocastOpcode: Unknown spell id {} used by {}.", packet.SpellID, packet.PetGUID.ToString());
968 return;
969 }
970
971 if (checkPet != _player->GetGuardianPet() && checkPet != _player->GetCharm())
972 {
973 LOG_ERROR("entities.pet", "WorldSession::HandlePetSpellAutocastOpcode: {} isn't pet of player {} ({}).",
974 packet.PetGUID.ToString(), GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
975 return;
976 }
977
978 Unit::ControlSet petsSet;
979 if (checkPet->GetEntry() != packet.PetGUID.GetEntry())
980 petsSet.insert(checkPet);
981 else
982 petsSet = _player->m_Controlled;
983
984 // Xinef: loop all pets with same entry (fixes partial state change for feral spirits)
985 for (Unit* pet : petsSet)
986 {
987 if (checkPet->GetEntry() == packet.PetGUID.GetEntry() && pet->GetEntry() != packet.PetGUID.GetEntry())
988 continue;
989
990 // do not add not learned spells/ passive spells
991 if (!pet->HasSpell(packet.SpellID) || !spellInfo->IsAutocastable())
992 continue;
993
994 CharmInfo* charmInfo = pet->GetCharmInfo();
995 if (!charmInfo)
996 {
997 LOG_ERROR("network.opcode", "WorldSession::HandlePetSpellAutocastOpcode: object ({} TypeId: {}) is considered pet-like but doesn't have a charminfo!",
998 pet->GetGUID().ToString(), pet->GetTypeId());
999 continue;
1000 }
1001
1002 if (Pet* summon = pet->ToPet())
1003 summon->ToggleAutocast(spellInfo, packet.AutocastEnabled);
1004 else
1005 charmInfo->ToggleCreatureAutocast(spellInfo, packet.AutocastEnabled);
1006
1007 charmInfo->SetSpellAutocast(spellInfo, packet.AutocastEnabled);
1008 }
1009}
bool IsAutocastable() const
Definition SpellInfo.cpp:1148
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)
969{
971 playedTime.TotalTime = _player->GetTotalPlayedTime();
972 playedTime.LevelTime = _player->GetLevelPlayedTime();
973 playedTime.TriggerScriptEvent = packet.TriggerScriptEvent; // 0-1 - will not show in chat frame
974 SendPacket(playedTime.Write());
975}
uint32 GetLevelPlayedTime()
Definition Player.h:1211
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)
797{
798 m_playerLoading = true; // Set here for direct callers.
799 ObjectGuid playerGuid = holder.GetGuid();
800
801 Player* pCurrChar = new Player(this);
802 // for send server info and strings (config)
803 ChatHandler chH = ChatHandler(pCurrChar->GetSession());
804
805 // "GetAccountId() == db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools)
806 if (!pCurrChar->LoadFromDB(playerGuid, holder))
807 {
808 SetPlayer(nullptr);
809 KickPlayer("WorldSession::HandlePlayerLogin Player::LoadFromDB failed"); // disconnect client, player no set to session and it will not deleted or saved at kick
810 delete pCurrChar; // delete it manually
811 m_playerLoading = false;
812 return;
813 }
814
815 pCurrChar->GetMotionMaster()->Initialize();
816 pCurrChar->SendDungeonDifficulty(false);
817
819 data << pCurrChar->GetMapId();
820 data << pCurrChar->GetPositionX();
821 data << pCurrChar->GetPositionY();
822 data << pCurrChar->GetPositionZ();
823 data << pCurrChar->GetOrientation();
824 SendPacket(&data);
825
826 // load player specific part before send times
829
830 data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0
831 data << uint8(2); // 2 - COMPLAINT_ENABLED_WITH_AUTO_IGNORE
832 data << uint8(0); // enable(1)/disable(0) voice chat interface in client
833 SendPacket(&data);
834
835 // Send MOTD
836 {
837 SendPacket(sMotdMgr->GetMotdPacket(pCurrChar->GetSession()->GetSessionDbLocaleIndex()));
838
839 // send server info
840 if (sWorld->getIntConfig(CONFIG_ENABLE_SINFO_LOGIN) == 1)
842 }
843
844 if (!sToCloud9Sidecar->ClusterModeEnabled())
845 {
846 if (uint32 guildId = sCharacterCache->GetCharacterGuildIdByGuid(pCurrChar->GetGUID()))
847 {
848 Guild* guild = sGuildMgr->GetGuildById(guildId);
849 Guild::Member const* member = guild ? guild->GetMember(pCurrChar->GetGUID()) : nullptr;
850 if (member)
851 {
852 pCurrChar->SetInGuild(guildId);
853 pCurrChar->SetRank(member->GetRankId());
854 guild->SendLoginInfo(this);
855 }
856 else
857 {
858 LOG_ERROR("network.opcode", "Player {} ({}) marked as member of not existing guild (id: {}), removing guild membership for player.",
859 pCurrChar->GetName(), pCurrChar->GetGUID().ToString(), guildId);
860 pCurrChar->SetInGuild(0);
861 pCurrChar->SetRank(0);
862 }
863 }
864 else
865 {
866 pCurrChar->SetInGuild(0);
867 pCurrChar->SetRank(0);
868 }
869 }
870 else
871 {
872 pCurrChar->SetInGuild(0);
873 pCurrChar->SetRank(0);
874 }
875
876 data.Initialize(SMSG_LEARNED_DANCE_MOVES, 4 + 4);
877 data << uint32(0);
878 data << uint32(0);
879 SendPacket(&data);
880
882
883 //Show cinematic at the first time that player login
884 if (!pCurrChar->getCinematic())
885 {
886 pCurrChar->setCinematic(1);
887
888 if (ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(pCurrChar->getClass()))
889 {
890 if (cEntry->CinematicSequence)
891 pCurrChar->GetCinematicMgr().StartCinematic(cEntry->CinematicSequence);
892 else if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace()))
893 pCurrChar->GetCinematicMgr().StartCinematic(rEntry->CinematicSequence);
894
895 // send new char string if not empty
896 std::string_view newCharString = sWorld->getStringConfig(CONFIG_NEW_CHAR_STRING);
897 if (!newCharString.empty())
898 chH.PSendSysMessage("{}", newCharString);
899 }
900 }
901
902 // Xinef: moved this from below
903 ObjectAccessor::AddObject(pCurrChar);
904
905 if (!pCurrChar->GetMap()->AddPlayerToMap(pCurrChar) || !pCurrChar->CheckInstanceLoginValid())
906 {
907 AreaTriggerTeleport const* at = sObjectMgr->GetGoBackTrigger(pCurrChar->GetMapId());
908 if (at)
909 pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation());
910 else
911 pCurrChar->TeleportTo(pCurrChar->m_homebindMapId, pCurrChar->m_homebindX, pCurrChar->m_homebindY, pCurrChar->m_homebindZ, pCurrChar->GetOrientation());
912
913 // Probably a hackfix, but currently the best workaround to prevent character names showing as Unknown after teleport out from instances at login.
914 pCurrChar->GetSession()->SendNameQueryOpcode(pCurrChar->GetGUID());
915 }
916
918
919 if (!sToCloud9Sidecar->ClusterModeEnabled())
920 {
922 stmt->SetData(0, pCurrChar->GetGUID().GetCounter());
923 CharacterDatabase.Execute(stmt);
924 }
925
927 loginStmt->SetData(0, realm.Id.Realm);
928 loginStmt->SetData(1, GetAccountId());
929 LoginDatabase.Execute(loginStmt);
930
931 pCurrChar->SetInGameTime(GameTime::GetGameTimeMS().count());
932
933 // announce group about member online (must be after add to player list to receive announce to self)
934 if (Group* group = pCurrChar->GetGroup())
935 {
936 group->SendUpdate();
937 group->ResetMaxEnchantingLevel();
938 }
939
940 // pussywizard: send instance welcome message as when entering the instance through a portal
941 if (MapDifficulty const* mapDiff = GetMapDifficultyData(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty()))
942 if (mapDiff->resetTime)
943 if (time_t timeReset = sInstanceSaveMgr->GetResetTimeFor(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty()))
944 {
945 uint32 timeleft = uint32(timeReset - GameTime::GetGameTime().count());
946 pCurrChar->SendInstanceResetWarning(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty(), timeleft, true);
947 }
948
949 // pussywizard: ensure that we end up on map with our loaded transport:
950 if (Transport* t = pCurrChar->GetTransport())
951 if (!t->IsInMap(pCurrChar))
952 {
953 t->RemovePassenger(pCurrChar);
954 pCurrChar->m_transport = nullptr;
955 pCurrChar->m_movementInfo.transport.Reset();
957 }
958
959 // friend status
960 sSocialMgr->SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUID(), true);
961
962 // Place character in world (and load zone) before some object loading
963 pCurrChar->LoadCorpse(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION));
964
965 // Set FFA PvP for non GM in non-rest mode
966 if (sWorld->IsFFAPvPRealm() && !pCurrChar->IsGameMaster() && !pCurrChar->HasPlayerFlag(PLAYER_FLAGS_RESTING))
968 {
969 sScriptMgr->OnPlayerFfaPvpStateUpdate(pCurrChar,true);
971 }
972
974 {
975 pCurrChar->SetContestedPvP(nullptr, false);
976 }
977
978 // Apply at_login requests
980 {
981 pCurrChar->resetSpells();
983 }
984
986 {
987 pCurrChar->resetTalents(true);
988 pCurrChar->SendTalentsInfoData(false); // original talents send already in to SendInitialPacketsBeforeAddToMap, resend reset state
990 }
991
993 {
994 // If we process the check while players are loading they won't be notified of the changes.
995 pCurrChar->m_Events.AddEventAtOffset([pCurrChar]
996 {
998 pCurrChar->CheckAllAchievementCriteria();
999 }, 1s);
1000 }
1001
1002 bool firstLogin = pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST);
1003 if (firstLogin)
1004 {
1005 PlayerInfo const* info = sObjectMgr->GetPlayerInfo(pCurrChar->getRace(), pCurrChar->getClass());
1006 for (uint32 spellId : info->castSpells)
1007 {
1008 pCurrChar->CastSpell(pCurrChar, spellId, true);
1009 }
1010
1011 // start with every map explored
1012 if (sWorld->getBoolConfig(CONFIG_START_ALL_EXPLORED))
1013 {
1014 for (uint8 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; i++)
1015 {
1016 pCurrChar->SetFlag(PLAYER_EXPLORED_ZONES_1 + i, 0xFFFFFFFF);
1017 }
1018 }
1019
1020 // Reputations if "StartAllReputation" is enabled, -- TODO: Fix this in a better way
1021 if (sWorld->getBoolConfig(CONFIG_START_ALL_REP))
1022 {
1023 ReputationMgr& repMgr = pCurrChar->GetReputationMgr();
1024
1025 auto SendFullReputation = [&repMgr](std::initializer_list<uint32> factionsList)
1026 {
1027 for (auto const& itr : factionsList)
1028 {
1029 repMgr.SetOneFactionReputation(sFactionStore.LookupEntry(itr), 42999.f, false);
1030 }
1031 };
1032
1033 SendFullReputation({ 942, 935, 936, 1011, 970, 967, 989, 932, 934, 1038, 1077, 1106, 1104, 1090, 1098, 1156, 1073, 1105, 1119, 1091 });
1034
1035 switch (pCurrChar->GetFaction())
1036 {
1037 case ALLIANCE:
1038 SendFullReputation({ 72, 47, 69, 930, 730, 978, 54, 946, 1037, 1068, 1126, 1094, 1050 });
1039 break;
1040 case HORDE:
1041 SendFullReputation({ 76, 68, 81, 911, 729, 941, 530, 947, 1052, 1067, 1124, 1064, 1085 });
1042 break;
1043 default:
1044 break;
1045 }
1046
1047 repMgr.SendStates();
1048 }
1049 }
1050
1051 // show time before shutdown if shutdown planned.
1052 if (sWorld->IsShuttingDown())
1053 sWorld->ShutdownMsg(true, pCurrChar);
1054
1055 if (sWorld->getBoolConfig(CONFIG_ALL_TAXI_PATHS))
1056 pCurrChar->SetTaxiCheater(true);
1057
1058 if (pCurrChar->IsGameMaster())
1060
1061 std::string IP_str = GetRemoteAddress();
1062 LOG_INFO("entities.player", "Account: {} (IP: {}) Login Character:[{}] ({}) Level: {}",
1063 GetAccountId(), IP_str, pCurrChar->GetName(), pCurrChar->GetGUID().ToString(), pCurrChar->GetLevel());
1064
1065 if (!pCurrChar->IsStandState() && !pCurrChar->HasUnitState(UNIT_STATE_STUNNED))
1067
1068 m_playerLoading = false;
1069
1070 // Handle Login-Achievements (should be handled after loading)
1072
1073 // Xinef: fix vendors falling of player vehicle, due to isBeingLoaded checks
1074 if (pCurrChar->IsInWorld())
1075 {
1076 if (pCurrChar->GetMountBlockId() && !pCurrChar->HasMountedAura())
1077 {
1078 pCurrChar->CastSpell(pCurrChar, pCurrChar->GetMountBlockId(), true);
1079 pCurrChar->SetMountBlockId(0);
1080
1081 // Xinef: refresh this in case mount aura changes anything (eg no fly zone)
1082 pCurrChar->UpdateAreaDependentAuras(pCurrChar->GetAreaId());
1083 pCurrChar->UpdateZoneDependentAuras(pCurrChar->GetZoneId());
1084 }
1085 }
1086
1087 // pussywizard: pvp mode
1089 if (pCurrChar->HasPlayerFlag(PLAYER_FLAGS_IN_PVP))
1090 pCurrChar->UpdatePvP(true, true);
1091
1092 // pussywizard: on login it's not possible to go back to arena as a spectator, HandleMoveWorldportAckOpcode is not sent, so call it here
1093 pCurrChar->SetIsSpectator(false);
1094
1095 // xinef: do this after everything is loaded
1096 pCurrChar->ContinueTaxiFlight();
1097
1098 // reset for all pets before pet loading
1101
1102 // Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned)
1103 pCurrChar->LoadPet();
1104
1105 if (pCurrChar->GetSession()->GetRecruiterId() != 0 || pCurrChar->GetSession()->IsARecruiter())
1106 {
1107 bool isReferrer = pCurrChar->GetSession()->IsARecruiter();
1108
1109 for (auto const& [accID, session] : sWorldSessionMgr->GetAllSessions())
1110 {
1111 if (!session->GetRecruiterId() && !session->IsARecruiter())
1112 continue;
1113
1114 if ((isReferrer && pCurrChar->GetSession()->GetAccountId() == session->GetRecruiterId()) || (!isReferrer && pCurrChar->GetSession()->GetRecruiterId() == session->GetAccountId()))
1115 {
1116 Player* rf = session->GetPlayer();
1117 if (rf)
1118 {
1119 pCurrChar->SendUpdateToPlayer(rf);
1120 rf->SendUpdateToPlayer(pCurrChar);
1121 }
1122 }
1123 }
1124 }
1125
1126 sScriptMgr->OnPlayerLogin(pCurrChar);
1127
1128 if (pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST))
1129 {
1131 sScriptMgr->OnPlayerFirstLogin(pCurrChar);
1132 }
1133
1134 METRIC_EVENT("player_events", "Login", pCurrChar->GetName());
1135}
@ CHAR_UPD_CHAR_ONLINE
Definition CharacterDatabase.h:307
@ ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN
Definition DBCEnums.h:184
@ LANG_RESET_SPELLS
Definition Language.h:262
@ LANG_RESET_TALENTS
Definition Language.h:263
@ LANG_GM_ON
Definition Language.h:382
@ 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:467
@ PLAYER_FLAGS_PVP_TIMER
Definition Player.h:477
@ AT_LOGIN_RESET_TALENTS
Definition Player.h:589
@ AT_LOGIN_RESET_SPELLS
Definition Player.h:588
@ AT_LOGIN_RESET_PET_TALENTS
Definition Player.h:591
#define PLAYER_EXPLORED_ZONES_SIZE
Definition Player.h:73
@ PLAYER_LOGIN_QUERY_LOAD_ACCOUNT_DATA
Definition Player.h:878
@ PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION
Definition Player.h:888
@ ALLIANCE
Definition SharedDefines.h:756
@ HORDE
Definition SharedDefines.h:755
@ FRIEND_ONLINE
Definition SocialMgr.h:68
@ PLAYER_EXPLORED_ZONES_1
Definition UpdateFields.h:357
@ CONFIG_ALL_TAXI_PATHS
Definition WorldConfig.h:39
@ CONFIG_ENABLE_SINFO_LOGIN
Definition WorldConfig.h:308
@ CONFIG_START_ALL_REP
Definition WorldConfig.h:87
@ CONFIG_START_ALL_EXPLORED
Definition WorldConfig.h:86
@ CONFIG_NEW_CHAR_STRING
Definition WorldConfig.h:504
void StartCinematic(uint32 const cinematicSequenceId)
Definition CinematicMgr.cpp:31
void AddEventAtOffset(BasicEvent *event, Milliseconds offset, uint8 eventGroup=0)
Definition EventProcessor.h:108
Definition Guild.h:299
uint8 GetRankId() const
Definition Guild.h:333
void SendLoginInfo(WorldSession *session)
Definition Guild.cpp:1933
Member const * GetMember(ObjectGuid guid) const
Definition Guild.h:384
virtual bool AddPlayerToMap(Player *)
Definition Map.cpp:258
void Initialize()
Definition MotionMaster.cpp:76
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition Object.cpp:902
static void resetTalentsForAllPetsOf(Player *owner, Pet *online_pet=nullptr)
Definition Pet.cpp:2129
void RemoveAtLoginFlag(AtLoginFlags flags, bool persist=false)
Definition Player.cpp:15073
uint32 GetMountBlockId()
Definition Player.h:2653
void ContinueTaxiFlight()
Definition Player.cpp:10618
void SendDungeonDifficulty(bool IsInGroup)
Definition PlayerMisc.cpp:169
void UpdateAreaDependentAuras(uint32 area_id)
Definition PlayerUpdates.cpp:1894
void SetMountBlockId(uint32 mount)
Definition Player.h:2654
bool resetTalents(bool noResetCost=false)
Definition Player.cpp:3876
void LoadCorpse(PreparedQueryResult result)
Definition PlayerStorage.cpp:5941
void LoadPet()
Definition PlayerStorage.cpp:6381
uint8 getCinematic() const
Definition Player.h:1859
void SetRank(uint8 rankId)
Definition Player.h:1926
bool LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const &holder)
Definition PlayerStorage.cpp:5023
void UpdateZoneDependentAuras(uint32 zone_id)
Definition PlayerUpdates.cpp:1880
void SetTaxiCheater(bool on)
Definition Player.h:1187
void SetInGameTime(uint32 time)
Definition Player.h:1579
void CheckAllAchievementCriteria()
Definition Player.cpp:14246
void setCinematic(uint8 cine)
Definition Player.h:1863
bool CheckInstanceLoginValid()
Definition PlayerStorage.cpp:7133
void resetSpells()
Definition Player.cpp:12083
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:13265
bool HasMountedAura() const
Definition Unit.h:1802
bool IsStandState() const
Definition Unit.cpp:12716
EventProcessor m_Events
Definition Object.h:749
void SetPlayer(Player *player)
Definition WorldSession.cpp:1398
void LoadAccountData(PreparedQueryResult result, uint32 mask)
Definition WorldSession.cpp:975
bool IsARecruiter() const
Definition WorldSession.h:676
void SendAccountDataTimes(uint32 mask)
Definition WorldSession.cpp:1035
#define PER_CHARACTER_CACHE_MASK
Definition WorldSession.h:244
@ 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:322

References _player, ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN, EventProcessor::AddEventAtOffset(), ObjectAccessor::AddObject(), Map::AddPlayerToMap(), 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(), Player::GetCinematicMgr(), 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, 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(), realm, RealmHandle::Realm, Player::RemoveAtLoginFlag(), MovementInfo::RemoveMovementFlag(), Player::RemovePlayerFlag(), MovementInfo::TransportInfo::Reset(), Player::resetSpells(), Player::resetTalents(), Pet::resetTalentsForAllPetsOf(), sCharacterCache, sChrClassesStore, sChrRacesStore, SendAccountDataTimes(), 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, CinematicMgr::StartCinematic(), sToCloud9Sidecar, 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)
676{
677 if (!sWorld->getBoolConfig(CONFIG_REALM_LOGIN_ENABLED))
678 {
680 return;
681 }
682
683 if (PlayerLoading() || GetPlayer() != nullptr)
684 {
685 LOG_ERROR("network", "Player tried to login again, AccountId = {}", GetAccountId());
686 KickPlayer("WorldSession::HandlePlayerLoginOpcode Another client logging in");
687 return;
688 }
689
690 ObjectGuid playerGuid;
691 recvData >> playerGuid;
692
693 // The ownership check is delegated to the gateway in cluster mode, but a
694 // non-player GUID is invalid regardless of who authenticated the session.
695 if (!playerGuid.IsPlayer() || (!sToCloud9Sidecar->ClusterModeEnabled() && !IsLegitCharacterForAccount(playerGuid)))
696 {
697 LOG_ERROR("network", "Account ({}) can't login with that character ({}).", GetAccountId(), playerGuid.ToString());
698 KickPlayer("Account can't login with this character");
699 return;
700 }
701
702 // pussywizard:
703 if (WorldSession* sess = sWorldSessionMgr->FindOfflineSessionForCharacterGUID(playerGuid.GetCounter()))
704 {
705 if (sess->GetAccountId() != GetAccountId())
706 {
708 return;
709 }
710 }
711
712 // pussywizard:
713 if (WorldSession* sess = sWorldSessionMgr->FindOfflineSession(GetAccountId()))
714 {
715 Player* p = sess->GetPlayer();
716 if (!p || sess->IsKicked())
717 {
719 return;
720 }
721
722 if (p->GetGUID() != playerGuid)
723 sess->KickPlayer("No return, go to normal loading"); // no return, go to normal loading
724 else
725 {
726 // pussywizard: players stay ingame no matter what (prevent abuse), but allow to turn it off to stop crashing
727 if (!sWorld->getBoolConfig(CONFIG_ENABLE_LOGIN_AFTER_DC))
728 {
730 return;
731 }
732
733 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);
734 while (sess->GetPlayer() && (sess->GetPlayer()->IsBeingTeleportedFar() || (sess->GetPlayer()->IsInWorld() && sess->GetPlayer()->IsBeingTeleportedNear())))
735 {
736 if (limitA == 0 || --limitA == 0)
737 {
738 LOG_INFO("misc", "HandlePlayerLoginOpcode A");
739 break;
740 }
741 while (sess->GetPlayer() && sess->GetPlayer()->IsBeingTeleportedFar())
742 {
743 if (limitB == 0 || --limitB == 0)
744 {
745 LOG_INFO("misc", "HandlePlayerLoginOpcode B");
746 break;
747 }
748 sess->HandleMoveWorldportAck();
749 }
750 while (sess->GetPlayer() && sess->GetPlayer()->IsInWorld() && sess->GetPlayer()->IsBeingTeleportedNear())
751 {
752 if (limitC == 0 || --limitC == 0)
753 {
754 LOG_INFO("misc", "HandlePlayerLoginOpcode C");
755 break;
756 }
757
758 Player* plMover = sess->GetPlayer()->m_mover->ToPlayer();
759 if (!plMover)
760 break;
761
763 pkt << plMover->GetPackGUID();
764 pkt << uint32(0); // flags
765 pkt << uint32(0); // time
766 sess->HandleMoveTeleportAck(pkt);
767 }
768 }
769 if (!p->FindMap() || !p->IsInWorld() || sess->IsKicked())
770 {
772 return;
773 }
774
775 sess->SetPlayer(nullptr);
776 SetPlayer(p);
777 p->SetSession(this);
778 delete p->PlayerTalkClass;
781 return;
782 }
783 }
784
785 std::shared_ptr<LoginQueryHolder> holder = std::make_shared<LoginQueryHolder>(GetAccountId(), playerGuid);
786 if (!holder->Initialize())
787 return;
788
789 m_playerLoading = true;
790 AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase const& holder)
791 {
792 HandlePlayerLoginFromDB(static_cast<LoginQueryHolder const&>(holder));
793 });
794}
@ CONFIG_ENABLE_LOGIN_AFTER_DC
Definition WorldConfig.h:104
@ CONFIG_REALM_LOGIN_ENABLED
Definition WorldConfig.h:130
Definition WorldSession.h:294
Definition GossipDef.h:259
void SetSession(WorldSession *sess)
Definition Player.h:2032
Definition QueryHolder.h:25
void AfterComplete(std::function< void(SQLQueryHolderBase const &)> callback) &
Definition QueryHolder.h:77
Player session in the World.
Definition WorldSession.h:430
void SendCharLoginFailed(LoginFailureReason reason)
Definition CharacterHandler.cpp:2617
bool PlayerLoading() const
Definition WorldSession.h:450
void HandlePlayerLoginToCharInWorld(Player *pCurrChar)
Definition CharacterHandler.cpp:1137
SQLQueryHolderCallback & AddQueryHolderCallback(SQLQueryHolderCallback &&callback)
Definition WorldSession.cpp:1419
void HandlePlayerLoginFromDB(LoginQueryHolder const &holder)
Definition CharacterHandler.cpp:796
@ 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(), ObjectGuid::IsPlayer(), KickPlayer(), LOG_ERROR, LOG_INFO, Player::m_mover, m_playerLoading, MSG_MOVE_TELEPORT_ACK, NoWorld, PlayerLoading(), Player::PlayerTalkClass, SendCharLoginFailed(), SetPlayer(), Player::SetSession(), sToCloud9Sidecar, sWorld, sWorldSessionMgr, Object::ToPlayer(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandlePlayerLoginToCharInWorld()

void WorldSession::HandlePlayerLoginToCharInWorld ( Player *  pCurrChar)
1138{
1139 ChatHandler chH = ChatHandler(this);
1140 m_playerLoading = true;
1141
1142 // Exit vehicle on reconnect - the client has fully reset so
1143 // the player can no longer control the vehicle. Without this
1144 // the player is stuck: server-side still seated, but the
1145 // client has no vehicle UI or movement control.
1146 if (pCurrChar->GetVehicle())
1147 pCurrChar->ExitVehicle();
1148
1149 pCurrChar->SendDungeonDifficulty(false);
1150
1152 data << pCurrChar->GetMapId();
1153 data << pCurrChar->GetPositionX();
1154 data << pCurrChar->GetPositionY();
1155 data << pCurrChar->GetPositionZ();
1156 data << pCurrChar->GetOrientation();
1157 SendPacket(&data);
1158
1160
1161 data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0
1162 data << uint8(2); // unknown value
1163 data << uint8(0); // enable(1)/disable(0) voice chat interface in client
1164 SendPacket(&data);
1165
1166 // Send MOTD
1167 {
1168 SendPacket(sMotdMgr->GetMotdPacket(pCurrChar->GetSession()->GetSessionDbLocaleIndex()));
1169
1170 // send server info
1171 if (sWorld->getIntConfig(CONFIG_ENABLE_SINFO_LOGIN) == 1)
1173
1174 LOG_DEBUG("network.opcode", "WORLD: Sent server info");
1175 }
1176
1177 data.Initialize(SMSG_LEARNED_DANCE_MOVES, 4 + 4);
1178 data << uint32(0);
1179 data << uint32(0);
1180 SendPacket(&data);
1181
1182 // Xinef: fix possible problem with flag UNIT_FLAG_STUNNED added during logout
1183 if (pCurrChar->HasUnitState(UNIT_STATE_LOGOUT_TIMER))
1184 {
1185 pCurrChar->SetRooted(false, true, true);
1187 }
1188
1189 if (pCurrChar->GetPendingFlightChange() <= pCurrChar->GetMapChangeOrderCounter())
1190 {
1191 if (!pCurrChar->HasIncreaseMountedFlightSpeedAura() && !pCurrChar->HasFlyAura())
1193 }
1194
1196
1197 // necessary actions from AddPlayerToMap:
1198 pCurrChar->GetMap()->SendInitTransports(pCurrChar);
1199 pCurrChar->GetMap()->SendInitSelf(pCurrChar);
1200
1201 // If we are logging into an existing player, simply clear visibility references
1202 // so player will receive a fresh list of new objects on the next vis update.
1204 pCurrChar->UpdateObjectVisibility(false);
1205
1206 pCurrChar->CleanupChannels();
1208 uint32 currZone, currArea;
1209 pCurrChar->GetZoneAndAreaId(currZone, currArea);
1210 pCurrChar->SendInitWorldStates(currZone, currArea);
1211 pCurrChar->SetInGameTime(GameTime::GetGameTimeMS().count());
1212
1213 // Xinef: we need to resend all spell mods
1214 for (uint16 Opcode = SMSG_SET_FLAT_SPELL_MODIFIER; Opcode <= SMSG_SET_PCT_SPELL_MODIFIER; ++Opcode) // PCT = FLAT+1
1215 {
1217 for (uint32 opType = SPELLMOD_DAMAGE; opType < MAX_SPELLMOD; ++opType)
1218 {
1219 int32 i = 0;
1220 flag96 _mask = 0;
1221 SpellModContainer const& spellMods = pCurrChar->GetSpellModList(opType);
1222 if (spellMods.empty())
1223 continue;
1224
1225 for (int32 eff = 0; eff < 96; ++eff)
1226 {
1227 if (eff != 0 && eff % 32 == 0)
1228 _mask[i++] = 0;
1229
1230 _mask[i] = uint32(1) << (eff - (32 * i));
1231 int32 val = 0;
1232 for (auto const& spellMod : spellMods)
1233 if (spellMod->type == modType && spellMod->mask & _mask)
1234 val += spellMod->value;
1235
1236 if (val == 0)
1237 continue;
1238
1239 WorldPacket data(Opcode, (1 + 1 + 4));
1240 data << uint8(eff);
1241 data << uint8(opType);
1242 data << int32(val);
1243 SendPacket(&data);
1244 }
1245 }
1246 }
1247
1248 if (Group* group = pCurrChar->GetGroup())
1249 group->SendUpdate();
1250
1251 // pussywizard: send instance welcome message as when entering the instance through a portal
1252 if (MapDifficulty const* mapDiff = GetMapDifficultyData(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty()))
1253 if (mapDiff->resetTime)
1254 if (time_t timeReset = sInstanceSaveMgr->GetResetTimeFor(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty()))
1255 {
1256 uint32 timeleft = uint32(timeReset - GameTime::GetGameTime().count());
1257 GetPlayer()->SendInstanceResetWarning(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty(), timeleft, true);
1258 }
1259
1260 // this shouldn't do anything, becaues offline can't be on taxi, but just in case
1261 pCurrChar->ContinueTaxiFlight();
1262
1263 // send pet data, action bar, talents, etc.
1264 pCurrChar->PetSpellInitialize();
1265 pCurrChar->SendTalentsInfoData(true);
1266
1267 // show time before shutdown if shutdown planned.
1268 if (sWorld->IsShuttingDown())
1269 sWorld->ShutdownMsg(true, pCurrChar);
1270
1271 if (pCurrChar->IsGameMaster())
1273
1274 m_playerLoading = false;
1275}
std::unordered_set< SpellModifier * > SpellModContainer
Definition Player.h:195
@ SPELLMOD_FLAT
Definition Player.h:94
@ SPELLMOD_PCT
Definition Player.h:95
@ SPELLMOD_DAMAGE
Definition SpellDefines.h:84
#define MAX_SPELLMOD
Definition SpellDefines.h:117
@ UNIT_STATE_LOGOUT_TIMER
Definition UnitDefines.h:205
void SendInitSelf(Player *player)
Definition Map.cpp:1646
void SendInitTransports(Player *player)
Definition Map.cpp:1692
void CleanVisibilityReferences()
Definition ObjectVisibilityContainer.cpp:47
void CleanupChannels()
Definition Player.cpp:5089
void PetSpellInitialize()
Definition Player.cpp:9752
void SendInitWorldStates(uint32 zoneId, uint32 areaId)
Definition Player.cpp:8418
SpellModContainer const & GetSpellModList(uint32 type) const
Definition Player.h:2661
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
Definition PlayerUpdates.cpp:1645
uint32 GetMapChangeOrderCounter()
Definition Player.h:2692
bool HasFlyAura() const
Definition Unit.h:1806
bool HasIncreaseMountedFlightSpeedAura() const
Definition Unit.h:1833
ObjectVisibilityContainer & GetObjectVisibilityContainer()
Definition Object.h:744
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(), Unit::ExitVehicle(), 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(), Unit::GetVehicle(), 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)
1278{
1279 ABORT();
1280}
#define ABORT
Definition Errors.h:76

References ABORT.

◆ HandlePlayerLogoutOpcode()

void WorldSession::HandlePlayerLogoutOpcode ( WorldPackets::Character::PlayerLogout &  playerLogout)
477{
478}

Referenced by OpcodeTable::Initialize().

◆ HandlePushQuestToParty()

void WorldSession::HandlePushQuestToParty ( WorldPackets::Quest::PushQuestToParty &  packet)
530{
531 if (!_player->CanShareQuest(packet.QuestId))
532 return;
533
534 LOG_DEBUG("network", "WORLD: Received CMSG_PUSHQUESTTOPARTY quest = {}", packet.QuestId);
535
536 if (Quest const* quest = sObjectMgr->GetQuestTemplate(packet.QuestId))
537 {
538 if (Group* group = _player->GetGroup())
539 {
540 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
541 {
542 Player* player = itr->GetSource();
543
544 if (!player || player == _player || !player->IsInMap(_player)) // skip self
545 continue;
546
547 if (!player->SatisfyQuestStatus(quest, false))
548 {
550 continue;
551 }
552
553 if (player->GetQuestStatus(packet.QuestId) == QUEST_STATUS_COMPLETE)
554 {
556 continue;
557 }
558
559 if (!player->CanTakeQuest(quest, false))
560 {
562 continue;
563 }
564
565 if (!player->SatisfyQuestLog(false))
566 {
568 continue;
569 }
570
571 // Check if Quest Share in BG is enabled
573 {
574 // Check if player is in BG
575 if (_player->InBattleground())
576 {
578 continue;
579 }
580 }
581
582 if (player->GetDivider())
583 {
585 continue;
586 }
587
589
590 if (quest->IsAutoAccept() && player->CanAddQuest(quest, true) && player->CanTakeQuest(quest, true))
591 player->AddQuestAndCheckCompletion(quest, _player);
592
593 if (quest->IsAutoComplete() || !quest->GetQuestMethod())
595 else
596 {
597 player->SetDivider(_player->GetGUID());
598 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
599 }
600 }
601 }
602 }
603}
@ LANG_BG_SHARE_QUEST_ERROR
Definition Language.h:1419
@ 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:66
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:252
bool CanAddQuest(Quest const *quest, bool msg)
Definition PlayerQuest.cpp:266
ObjectGuid GetDivider()
Definition Player.h:1574
bool SatisfyQuestLog(bool msg)
Definition PlayerQuest.cpp:1025
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition PlayerQuest.cpp:423
void SendPushToPartyResponse(Player const *player, QuestShareMessages msg) const
Definition PlayerQuest.cpp:2505
bool CanCompleteRepeatableQuest(Quest const *quest)
Definition PlayerQuest.cpp:368
bool CanShareQuest(uint32 quest_id) const
Definition PlayerQuest.cpp:1532
void SetDivider(ObjectGuid guid=ObjectGuid::Empty)
Definition Player.h:1575
bool SatisfyQuestStatus(Quest const *qInfo, bool msg) const
Definition PlayerQuest.cpp:1188
bool IsInMap(WorldObject const *obj) const
Definition Object.cpp:1344
uint32 QuestId
Definition QuestPackets.h:209

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, WorldPackets::Quest::PushQuestToParty::QuestId, 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:1373

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

Referenced by OpcodeTable::Initialize().

◆ HandleQueryGuildBankTabText()

void WorldSession::HandleQueryGuildBankTabText ( WorldPackets::Guild::GuildBankTextQuery &  packet)
398{
399 LOG_DEBUG("guild", "MSG_QUERY_GUILD_BANK_TEXT [{}]: TabId: {}", GetPlayerInfo(), packet.Tab);
400
401 if (Guild* guild = GetPlayer()->GetGuild())
402 guild->SendBankTabText(this, packet.Tab);
403}
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)
1591{
1592 ObjectGuid guid;
1593 recv_data >> guid.ReadAsPacked();
1594
1595 Player* player = ObjectAccessor::GetPlayer(*_player, guid);
1596 if (!player)
1597 {
1598 return;
1599 }
1600
1601 if (!GetPlayer()->IsWithinDistInMap(player, INSPECT_DISTANCE, false))
1602 {
1603 return;
1604 }
1605
1606 if (GetPlayer()->IsValidAttackTarget(player))
1607 {
1608 return;
1609 }
1610
1612}
void SendRespondInspectAchievements(Player *player) const
Definition Player.cpp:14256

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

Referenced by OpcodeTable::Initialize().

◆ HandleQueryNextMailTime()

void WorldSession::HandleQueryNextMailTime ( WorldPacket &  recvData)
892{
894
895 if (_player->unReadMails > 0)
896 {
897 data << float(0); // float
898 data << uint32(0); // count
899
900 uint32 count = 0;
901 time_t now = GameTime::GetGameTime().count();
902 std::set<uint32> sentSenders;
903 for (Mail const* mail : _player->GetMails())
904 {
905 // must be not checked yet
906 if (mail->checked & MAIL_CHECK_MASK_READ)
907 continue;
908
909 // and already delivered or expired
910 if (now < mail->deliver_time || now > mail->expire_time)
911 continue;
912
913 // only send each mail sender once
914 if (sentSenders.count(mail->sender))
915 continue;
916
917 data << (mail->messageType == MAIL_NORMAL ? ObjectGuid::Create<HighGuid::Player>(mail->sender) : ObjectGuid::Empty); // player guid
918 data << uint32(mail->messageType != MAIL_NORMAL ? mail->sender : 0); // non-player entries
919 data << uint32(mail->messageType);
920 data << uint32(mail->stationery);
921 data << float(mail->deliver_time - now);
922
923 sentSenders.insert(mail->sender);
924 ++count;
925 if (count == 2) // do not display more than 2 mails
926 break;
927 }
928
929 data.put<uint32>(4, count);
930 }
931 else
932 {
933 data << float(-DAY);
934 data << uint32(0);
935 }
936
937 SendPacket(&data);
938}
constexpr auto DAY
Definition Common.h:49
@ 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)
626{
627 std::size_t rew_count = _player->GetRewardedQuestCount();
628
629 WorldPacket data(SMSG_QUERY_QUESTS_COMPLETED_RESPONSE, 4 + 4 * rew_count);
630 data << uint32(rew_count);
631
632 RewardedQuestSet const& rewQuests = _player->getRewardedQuests();
633 for (RewardedQuestSet::const_iterator itr = rewQuests.begin(); itr != rewQuests.end(); ++itr)
634 data << uint32(*itr);
635
636 SendPacket(&data);
637}
std::unordered_set< uint32 > RewardedQuestSet
Definition Player.h:602
std::size_t GetRewardedQuestCount() const
Definition Player.h:1652
RewardedQuestSet const & getRewardedQuests() const
Definition Player.h:1648
@ 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 ( WorldPackets::Quest::QuestConfirmAcceptClient &  packet)
447{
448 LOG_DEBUG("network", "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = {}", packet.QuestId);
449
450 if (Quest const* quest = sObjectMgr->GetQuestTemplate(packet.QuestId))
451 {
452 if (!quest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT))
453 return;
454
456 if (!originalPlayer)
457 return;
458
459 if (!_player->IsInSameRaidWith(originalPlayer) || !_player->IsAtGroupRewardDistance(originalPlayer))
460 return;
461
462 if (!_player->CanTakeQuest(quest, true) || _player->HasPendingBind())
463 return;
464
465 // pussywizard: exploit fix, can't share quests that give items to be sold
466 if (uint32 itemId = quest->GetSrcItemId())
467 if (ItemTemplate const* srcItem = sObjectMgr->GetItemTemplate(itemId))
468 if (srcItem->SellPrice > 0)
469 return;
470
471 if (_player->CanAddQuest(quest, true))
472 _player->AddQuestAndCheckCompletion(quest, nullptr); // nullptr, this prevent DB script from duplicate running
473
475 }
476}
@ QUEST_FLAGS_PARTY_ACCEPT
Definition QuestDef.h:133
bool IsInSameRaidWith(Player const *p) const
Definition Player.h:1914
bool IsAtGroupRewardDistance(WorldObject const *pRewardSource) const
Definition Player.cpp:13076
uint32 QuestId
Definition QuestPackets.h:199

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

Referenced by OpcodeTable::Initialize().

◆ HandleQuestgiverAcceptQuestOpcode()

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

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

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)
479{
480 uint32 questId;
481 ObjectGuid guid;
482
483 recvData >> guid >> questId;
484
485 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST npc {}, quest = {}", guid.ToString(), questId);
486
488 if (!object || !object->hasInvolvedQuest(questId))
489 return;
490
491 // some kind of WPE protection
493 return;
494
495 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
496 {
498 {
499 LOG_ERROR("network.opcode", "Possible hacking attempt: Player {} [{}] tried to complete quest [entry: {}] without being in possession of the quest!",
500 _player->GetName(), _player->GetGUID().ToString(), questId);
501 return;
502 }
503
505 if (bg->GetBgTypeID(true) == BATTLEGROUND_AV)
506 bg->ToBattlegroundAV()->HandleQuestComplete(questId, _player);
507
509 {
510 if (quest->IsRepeatable())
512 else
513 _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, _player->CanRewardQuest(quest, false), false);
514 }
515 else
516 {
517 if (quest->GetReqItemsCount()) // some items required
518 _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, _player->CanRewardQuest(quest, false), false);
519 else // no items required
521 }
522 }
523}
@ BATTLEGROUND_AV
Definition SharedDefines.h:3737

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)
80{
81 ObjectGuid guid;
82 recvData >> guid;
83
84 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_HELLO npc {}", guid.ToString());
85
87 if (!creature)
88 {
89 LOG_DEBUG("network", "WORLD: HandleQuestgiverHelloOpcode - Unit ({}) not found or you can't interact with him.", guid.ToString());
90 return;
91 }
92
93 // remove fake death
94 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
96
98
99 // Update home position for patrolling NPCs only (prevents drift for stationary NPCs)
100 if (creature->GetDefaultMovementType() == WAYPOINT_MOTION_TYPE ||
102 creature->SetHomePosition(creature->GetPosition());
103
104 if (sScriptMgr->OnGossipHello(_player, creature))
105 return;
106
107 _player->PrepareGossipMenu(creature, creature->GetGossipMenuId(), true);
108 _player->SendPreparedGossip(creature);
109
110 creature->AI()->sGossipHello(_player);
111}

References _player, Creature::AI(), MotionMaster::GetCurrentMovementGeneratorType(), Creature::GetDefaultMovementType(), Creature::GetGossipMenuId(), Unit::GetMotionMaster(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Position::GetPosition(), LOG_DEBUG, Creature::PauseMovementForInteraction(), Player::PrepareGossipMenu(), Unit::RemoveAurasByType(), Player::SendPreparedGossip(), Creature::SetHomePosition(), UnitAI::sGossipHello(), SPELL_AURA_FEIGN_DEATH, sScriptMgr, ObjectGuid::ToString(), UNIT_NPC_FLAG_NONE, UNIT_STATE_DIED, and WAYPOINT_MOTION_TYPE.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestgiverQueryQuestOpcode()

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

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 ( WorldPackets::Quest::QuestGiverQuestAutoLaunch &  packet)
526{
527}

Referenced by OpcodeTable::Initialize().

◆ HandleQuestgiverRequestRewardOpcode()

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

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

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 ( WorldPackets::Quest::QuestLogRemoveQuest &  packet)
397{
398 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTLOG_REMOVE_QUEST slot = {}", packet.Slot);
399
400 if (packet.Slot < MAX_QUEST_LOG_SIZE)
401 {
402 if (uint32 questId = _player->GetQuestSlotQuestId(packet.Slot))
403 {
404 if (!_player->TakeQuestSourceItem(questId, true))
405 return; // can't un-equip some items, reject quest cancel
406
407 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
408 {
409 if (quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED))
410 _player->RemoveTimedQuest(questId);
411
412 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
413 {
416 }
417 }
418
419 _player->TakeQuestSourceItem(questId, true); // remove quest src item from player
420 _player->AbandonQuest(questId); // remove all quest items player received before abandoning quest.
421 _player->RemoveActiveQuest(questId);
423
424 sScriptMgr->OnPlayerQuestAbandon(_player, questId);
425
426 LOG_DEBUG("network.opcode", "Player {} abandoned quest {}", _player->GetGUID().ToString(), questId);
427 // check if Quest Tracker is enabled
428 if (sWorld->getBoolConfig(CONFIG_QUEST_ENABLE_QUEST_TRACKER))
429 {
430 // prepare Quest Tracker datas
431 auto stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_QUEST_TRACK_ABANDON_TIME);
432 stmt->SetData(0, questId);
433 stmt->SetData(1, _player->GetGUID().GetCounter());
434
435 // add to Quest Tracker
436 CharacterDatabase.Execute(stmt);
437 }
438 }
439
440 _player->SetQuestSlot(packet.Slot, 0);
441
443 }
444}
@ CHAR_UPD_QUEST_TRACK_ABANDON_TIME
Definition CharacterDatabase.h:516
@ 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:108
bool HasPvPForcingQuest() const
Definition PlayerQuest.cpp:2566
void UpdatePvPState()
Definition PlayerUpdates.cpp:1464
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition Player.h:1510
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition Player.h:1514
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition PlayerQuest.cpp:1436
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition PlayerQuest.cpp:1569
void RemoveTimedQuest(uint32 quest_id)
Definition Player.h:1582
void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry)
Definition Player.cpp:14271
void AbandonQuest(uint32 quest_id)
Definition PlayerQuest.cpp:971
uint8 Slot
Definition QuestPackets.h:189
bool IsInHostileArea
Definition Player.h:348

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(), WorldPackets::Quest::QuestLogRemoveQuest::Slot, sObjectMgr, sScriptMgr, sWorld, Player::TakeQuestSourceItem(), ObjectGuid::ToString(), Player::UpdateAchievementCriteria(), and Player::UpdatePvPState().

Referenced by OpcodeTable::Initialize().

◆ HandleQuestLogSwapQuest()

void WorldSession::HandleQuestLogSwapQuest ( WorldPackets::Quest::QuestLogSwapQuest &  packet)
387{
388 if (packet.Slot1 == packet.Slot2 || packet.Slot1 >= MAX_QUEST_LOG_SIZE || packet.Slot2 >= MAX_QUEST_LOG_SIZE)
389 return;
390
391 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTLOG_SWAP_QUEST slot 1 = {}, slot 2 = {}", packet.Slot1, packet.Slot2);
392
393 GetPlayer()->SwapQuestSlot(packet.Slot1, packet.Slot2);
394}
void SwapQuestSlot(uint16 slot1, uint16 slot2)
Definition Player.h:1532
uint8 Slot1
Definition QuestPackets.h:178
uint8 Slot2
Definition QuestPackets.h:179

References GetPlayer(), LOG_DEBUG, MAX_QUEST_LOG_SIZE, WorldPackets::Quest::QuestLogSwapQuest::Slot1, WorldPackets::Quest::QuestLogSwapQuest::Slot2, 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:667
uint16 FindQuestSlot(uint32 quest_id) const
Definition PlayerQuest.cpp:1856
@ 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 ( WorldPackets::Quest::QuestPushResultClient &  packet)
606{
607 if (_player->GetDivider() && _player->GetDivider() == packet.PlayerGuid)
608 {
610 {
612 questPushResult.PlayerGuid = _player->GetGUID();
613 questPushResult.QuestShareMessage = packet.QuestShareMessage;
614 player->SendDirectMessage(questPushResult.Write());
616 }
617 }
618}
QuestShareMessages QuestShareMessage
Definition QuestPackets.h:160
ObjectGuid PlayerGuid
Definition QuestPackets.h:158
Definition QuestPackets.h:107
ObjectGuid PlayerGuid
Definition QuestPackets.h:113
WorldPacket const * Write() override
Definition QuestPackets.cpp:70
QuestShareMessages QuestShareMessage
Definition QuestPackets.h:114

References _player, Player::GetDivider(), Object::GetGUID(), ObjectAccessor::GetPlayer(), WorldPackets::Quest::QuestPushResult::PlayerGuid, WorldPackets::Quest::QuestPushResultClient::PlayerGuid, WorldPackets::Quest::QuestPushResult::QuestShareMessage, WorldPackets::Quest::QuestPushResultClient::QuestShareMessage, Player::SetDivider(), and WorldPackets::Quest::QuestPushResult::Write().

Referenced by OpcodeTable::Initialize().

◆ HandleQuestQueryOpcode()

void WorldSession::HandleQuestQueryOpcode ( WorldPacket &  recvPacket)
238{
239 if (!_player)
240 return;
241
242 uint32 questId;
243 recvData >> questId;
244 LOG_DEBUG("network", "WORLD: Received CMSG_QUEST_QUERY quest = {}", questId);
245
246 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
248}
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)
805{
806 Group* group = GetPlayer()->GetGroup();
807 if (!group)
808 return;
809
810 if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
811 return;
812
814 group->BroadcastPacket(&data, true, -1);
815}
@ 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

761{
762 Group* group = GetPlayer()->GetGroup();
763 if (!group)
764 return;
765
766 if (recvData.empty()) // request
767 {
769 if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
770 return;
771 /********************/
772
773 // Check if Ready Check in BG is enabled
775 {
776 // Check if player is in BG
777 if (_player->InBattleground())
778 {
780 return;
781 }
782 }
783
784 // everything's fine, do it
786 data << GetPlayer()->GetGUID();
787 group->BroadcastPacket(&data, false, -1);
788
789 group->OfflineReadyCheck();
790 }
791 else // answer
792 {
793 uint8 state;
794 recvData >> state;
795
796 // everything's fine, do it
798 data << GetPlayer()->GetGUID();
799 data << uint8(state);
800 group->BroadcastReadyCheck(&data);
801 }
802}
@ LANG_BG_READY_CHECK_ERROR
Definition Language.h:1420
@ CONFIG_BATTLEGROUND_DISABLE_READY_CHECK_IN_BG
Definition WorldConfig.h:67
void BroadcastReadyCheck(WorldPacket const *packet)
Definition Group.cpp:1982
void OfflineReadyCheck()
Definition Group.cpp:1993
@ 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

611{
612 Group* group = GetPlayer()->GetGroup();
613 if (!group)
614 return;
615
616 uint8 x;
617 recvData >> x;
618
620 /********************/
621
622 // everything's fine, do it
623 if (x == 0xFF) // target icon request
624 {
625 group->SendTargetIconList(this);
626 }
627 else // target icon update
628 {
629 if (group->isRaidGroup() && !group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
630 return;
631
632 ObjectGuid guid;
633 recvData >> guid;
634
635 if (guid.IsPlayer())
636 {
638
639 if (!target || target->IsHostileTo(GetPlayer()))
640 return;
641 }
642
643 group->SetTargetIcon(x, _player->GetGUID(), guid);
644 }
645}
void SendTargetIconList(WorldSession *session)
Definition Group.cpp:1851
void SetTargetIcon(uint8 id, ObjectGuid whoGuid, ObjectGuid targetGuid)
Definition Group.cpp:1830

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

598{
599 uint32 minimum, maximum;
600 minimum = packet.Min;
601 maximum = packet.Max;
602
604 if (minimum > maximum || maximum > sWorld->getIntConfig(CONFIG_RANDOM_ROLL_MAXIMUM))
605 return;
606
607 GetPlayer()->DoRandomRoll(minimum, maximum);
608}
@ CONFIG_RANDOM_ROLL_MAXIMUM
Definition WorldConfig.h:135
uint32 DoRandomRoll(uint32 minimum, uint32 maximum)
Definition Player.cpp:16555
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:2297
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)
1625{
1626 // empty opcode
1627 LOG_DEBUG("network", "WORLD: CMSG_READY_FOR_ACCOUNT_DATA_TIMES");
1628
1630}
#define GLOBAL_CACHE_MASK
Definition WorldSession.h:243

References GLOBAL_CACHE_MASK, LOG_DEBUG, and SendAccountDataTimes().

Referenced by OpcodeTable::Initialize().

◆ HandleRealmSplitOpcode()

void WorldSession::HandleRealmSplitOpcode ( WorldPacket &  recvData)
1169{
1170 LOG_DEBUG("network", "CMSG_REALM_SPLIT");
1171
1172 uint32 unk;
1173 std::string split_date = "01/01/01";
1174 recv_data >> unk;
1175
1176 WorldPacket data(SMSG_REALM_SPLIT, 4 + 4 + split_date.size() + 1);
1177 data << unk;
1178 data << uint32(0x00000000); // realm split state
1179 // split states:
1180 // 0x0 realm normal
1181 // 0x1 realm split
1182 // 0x2 realm split pending
1183 data << split_date;
1184 SendPacket(&data);
1185}
@ 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)
634{
635 ObjectGuid guid;
636 recv_data >> guid;
637
638 if (_player->IsAlive())
639 return;
640
641 // do not allow corpse reclaim in arena
642 if (_player->InArena())
643 return;
644
645 // body not released yet
647 return;
648
649 Corpse* corpse = _player->GetCorpse();
650 if (!corpse)
651 return;
652
653 // prevent resurrect before 30-sec delay after body release not finished
654 if (time_t(corpse->GetGhostTime() + _player->GetCorpseReclaimDelay(corpse->GetType() == CORPSE_RESURRECTABLE_PVP)) > time_t(GameTime::GetGameTime().count()))
655 return;
656
657 // skip phase check
658 if (!corpse->IsInMap(_player) || !corpse->IsWithinDist(_player, CORPSE_RECLAIM_RADIUS, true))
659 return;
660
661 // resurrect
663
664 // spawn bones
666}
#define CORPSE_RECLAIM_RADIUS
Definition Corpse.h:35
@ CORPSE_RESURRECTABLE_PVP
Definition Corpse.h:30
time_t const & GetGhostTime() const
Definition Corpse.h:71
Corpse * GetCorpse() const
Definition Player.cpp:4794
uint32 GetCorpseReclaimDelay(bool pvp) const
Definition Player.cpp:13243
bool InArena() const
Definition Player.cpp:12568
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1381

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)
1600{
1601 uint32 slot;
1602 recvData >> slot;
1603
1604 if (slot >= MAX_GLYPH_SLOT_INDEX)
1605 {
1606 LOG_DEBUG("network", "Client sent wrong glyph slot number in opcode CMSG_REMOVE_GLYPH {}", slot);
1607 return;
1608 }
1609
1610 if (uint32 glyph = _player->GetGlyph(slot))
1611 {
1612 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
1613 {
1614 _player->RemoveAurasDueToSpell(glyphEntry->SpellId);
1615
1616 // Removed any triggered auras
1617 Unit::AuraMap& ownedAuras = _player->GetOwnedAuras();
1618 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
1619 {
1620 Aura* aura = iter->second;
1621 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
1622 {
1623 if (triggeredByAuraSpellInfo->Id == glyphEntry->SpellId)
1624 {
1625 _player->RemoveOwnedAura(iter);
1626 continue;
1627 }
1628 }
1629 ++iter;
1630 }
1631
1632 _player->SendLearnPacket(glyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
1633 _player->SetGlyph(slot, 0, true);
1635 }
1636 }
1637}
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
#define MAX_GLYPH_SLOT_INDEX
Definition SharedDefines.h:664
SpellInfo const * GetTriggeredByAuraSpellInfo() const
Definition SpellAuras.cpp:2870
void SendLearnPacket(uint32 spellId, bool learn)
Definition Player.cpp:3137
uint32 GetGlyph(uint8 slot) const
Definition Player.h:1793
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition Player.h:1785
boost::container::flat_multimap< uint32, Aura * > AuraMap
Definition Unit.h:670
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4936
AuraMap & GetOwnedAuras()
Definition Unit.h:1378
Definition DBCStructure.h:1060

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)
760{
761 LOG_DEBUG("network", "WORLD: CMSG_REPAIR_ITEM");
762
763 ObjectGuid npcGUID, itemGUID;
764 uint8 guildBank; // new in 2.3.2, bool that means from guild bank money
765
766 recvData >> npcGUID >> itemGUID >> guildBank;
767
769 if (!unit)
770 {
771 LOG_DEBUG("network", "WORLD: HandleRepairItemOpcode - Unit ({}) not found or you can not interact with him.", npcGUID.ToString());
772 return;
773 }
774
775 // remove fake death
776 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
778
779 // reputation discount
780 float discountMod = _player->GetReputationPriceDiscount(unit);
781
782 sScriptMgr->OnPlayerBeforeDurabilityRepair(_player, npcGUID, itemGUID, discountMod, guildBank);
783
784 if (itemGUID)
785 {
786 LOG_DEBUG("network", "ITEM: Repair item, item {}, npc {}", itemGUID.ToString(), npcGUID.ToString());
787
788 Item* item = _player->GetItemByGuid(itemGUID);
789 if (item)
790 _player->DurabilityRepair(item->GetPos(), true, discountMod, guildBank);
791 }
792 else
793 {
794 LOG_DEBUG("network", "ITEM: Repair all items, npc {}", npcGUID.ToString());
795 _player->DurabilityRepairAll(true, discountMod, guildBank);
796 }
797}
@ UNIT_NPC_FLAG_REPAIR
Definition UnitDefines.h:334
float GetReputationPriceDiscount(Creature const *creature) const
Definition Player.cpp:12607
uint32 DurabilityRepairAll(bool cost, float discountMod, bool guildBank)
Definition Player.cpp:4910
uint32 DurabilityRepair(uint16 pos, bool cost, float discountMod, bool guildBank)
Definition Player.cpp:4926

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)
60{
61 LOG_DEBUG("network", "WORLD: Recvd CMSG_REPOP_REQUEST Message");
62
63 recv_data.read_skip<uint8>();
64
66 return;
67
69 return; // silently return, client should display the error by itself
70
71 // the world update order is sessions, players, creatures
72 // the netcode runs in parallel with all of these
73 // creatures can kill players
74 // so if the server is lagging enough the player can
75 // release spirit after he's killed but before he is updated
77 {
78 LOG_DEBUG("network", "HandleRepopRequestOpcode: got request after player {} ({}) was killed and before he was updated",
79 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
81 }
82
83 //this is spirit release confirm?
84 GetPlayer()->RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT, true);
87}
@ PET_SAVE_NOT_IN_SLOT
Definition PetDefines.h:46
void KillPlayer()
Definition Player.cpp:4638
DeathState getDeathState()
Definition Unit.h:1793
bool HasPreventResurectionAura() const
Definition Unit.h:1810

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:273
uint32 GetLatency() const
Definition WorldSession.h:651

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

Referenced by OpcodeTable::Initialize().

◆ HandleReportPvPAFK()

void WorldSession::HandleReportPvPAFK ( WorldPacket &  recvData)
929{
930 ObjectGuid playerGuid;
931 recvData >> playerGuid;
932 Player* reportedPlayer = ObjectAccessor::FindPlayer(playerGuid);
933
934 if (!reportedPlayer)
935 {
936 LOG_DEBUG("bg.battleground", "WorldSession::HandleReportPvPAFK: player not found");
937 return;
938 }
939
940 LOG_DEBUG("bg.battleground", "WorldSession::HandleReportPvPAFK: {} reported {}", _player->GetName(), reportedPlayer->GetName());
941
942 reportedPlayer->ReportedAfkBy(_player);
943}
void ReportedAfkBy(Player *reporter)
This player has been blamed to be inactive in a battleground.
Definition Player.cpp:11561

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

Referenced by OpcodeTable::Initialize().

◆ HandleRequestAccountData()

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

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)
1004{
1005 ObjectGuid Guid;
1006 recvData >> Guid;
1007
1008 Player* player = HashMapHolder<Player>::Find(Guid);
1009 if (!player || !player->IsInSameRaidWith(_player))
1010 {
1012 data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
1013 data << Guid.WriteAsPacked();
1016 SendPacket(&data);
1017 return;
1018 }
1019
1020 Pet* pet = player->GetPet();
1021 Powers powerType = player->getPowerType();
1022
1023 WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4 + 2 + 2 + 2 + 1 + 2 * 6 + 8 + 1 + 8);
1024 data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
1025 data << player->GetPackGUID();
1026
1031
1032 if (powerType != POWER_MANA)
1033 updateFlags |= GROUP_UPDATE_FLAG_POWER_TYPE;
1034
1035 if (pet)
1038
1039 if (player->GetVehicle())
1040 updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT;
1041
1042 uint16 playerStatus = MEMBER_STATUS_ONLINE;
1043 if (player->IsPvP())
1044 playerStatus |= MEMBER_STATUS_PVP;
1045
1046 if (!player->IsAlive())
1047 {
1048 if (player->HasPlayerFlag(PLAYER_FLAGS_GHOST))
1049 playerStatus |= MEMBER_STATUS_GHOST;
1050 else
1051 playerStatus |= MEMBER_STATUS_DEAD;
1052 }
1053
1054 if (player->IsFFAPvP())
1055 playerStatus |= MEMBER_STATUS_PVP_FFA;
1056
1057 if (player->isAFK())
1058 playerStatus |= MEMBER_STATUS_AFK;
1059
1060 if (player->isDND())
1061 playerStatus |= MEMBER_STATUS_DND;
1062
1063 data << uint32(updateFlags);
1064 data << uint16(playerStatus); // GROUP_UPDATE_FLAG_STATUS
1065 data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP
1066 data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP
1067 if (updateFlags & GROUP_UPDATE_FLAG_POWER_TYPE)
1068 data << uint8(powerType);
1069
1070 data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER
1071 data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER
1072 data << uint16(player->GetLevel()); // GROUP_UPDATE_FLAG_LEVEL
1073 data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE
1074 data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION
1075 data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION
1076
1077 uint64 auraMask = 0;
1078 std::size_t maskPos = data.wpos();
1079 data << uint64(auraMask); // placeholder
1080 for (uint8 i = 0; i < MAX_AURAS_GROUP_UPDATE; ++i)
1081 {
1082 if (AuraApplication const* aurApp = player->GetVisibleAura(i))
1083 {
1084 auraMask |= uint64(1) << i;
1085 data << uint32(aurApp->GetBase()->GetId());
1086 data << uint8(aurApp->GetFlags());
1087 }
1088 }
1089
1090 data.put<uint64>(maskPos, auraMask); // GROUP_UPDATE_FLAG_AURAS
1091
1092 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_GUID))
1093 data << pet->GetGUID();
1094
1095 data << std::string(pet ? pet->GetName() : ""); // GROUP_UPDATE_FLAG_PET_NAME
1096 data << uint16(pet ? pet->GetDisplayId() : 0); // GROUP_UPDATE_FLAG_PET_MODEL_ID
1097
1098 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_HP))
1099 data << uint32(pet->GetHealth());
1100
1101 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_HP))
1102 data << uint32(pet->GetMaxHealth());
1103
1104 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_POWER_TYPE))
1105 data << (uint8)pet->getPowerType();
1106
1107 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_POWER))
1108 data << uint16(pet->GetPower(pet->getPowerType()));
1109
1110 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_POWER))
1111 data << uint16(pet->GetMaxPower(pet->getPowerType()));
1112
1113 uint64 petAuraMask = 0;
1114 maskPos = data.wpos();
1115 data << uint64(petAuraMask); // placeholder
1116 if (pet)
1117 {
1118 for (uint8 i = 0; i < MAX_AURAS_GROUP_UPDATE; ++i)
1119 {
1120 if (AuraApplication const* aurApp = pet->GetVisibleAura(i))
1121 {
1122 petAuraMask |= uint64(1) << i;
1123 data << uint32(aurApp->GetBase()->GetId());
1124 data << uint8(aurApp->GetFlags());
1125 }
1126 }
1127 }
1128
1129 data.put<uint64>(maskPos, petAuraMask); // GROUP_UPDATE_FLAG_PET_AURAS
1130
1131 if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
1132 data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]);
1133
1134 SendPacket(&data);
1135}
@ MEMBER_STATUS_OFFLINE
Definition Group.h:61
@ POWER_MANA
Definition SharedDefines.h:257
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:2070

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)
1561{
1562 /*
1563 LOG_DEBUG("network.opcode", "WORLD: CMSG_REQUEST_PET_INFO");
1564 recv_data.hexlike();
1565 */
1566
1567 if (_player->GetPet())
1569 else if (Unit* charm = _player->GetCharm())
1570 {
1571 if (charm->HasUnitState(UNIT_STATE_POSSESSED))
1573 else if (charm->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED) && charm->HasUnitFlag(UNIT_FLAG_POSSESSED))
1575 else
1577 }
1578}
@ UNIT_STATE_POSSESSED
Definition UnitDefines.h:189
@ UNIT_FLAG_POSSESSED
Definition UnitDefines.h:281
@ UNIT_FLAG_PLAYER_CONTROLLED
Definition UnitDefines.h:260
void CharmSpellInitialize()
Definition Player.cpp:9927
void PossessSpellInitialize()
Definition Player.cpp:9824
void VehicleSpellInitialize()
Definition Player.cpp:9852

References _player, Player::CharmSpellInitialize(), Unit::GetCharm(), Player::GetPet(), Player::PetSpellInitialize(), Player::PossessSpellInitialize(), UNIT_FLAG_PLAYER_CONTROLLED, UNIT_FLAG_POSSESSED, UNIT_STATE_POSSESSED, and Player::VehicleSpellInitialize().

Referenced by OpcodeTable::Initialize().

◆ HandleRequestRaidInfoOpcode()

void WorldSession::HandleRequestRaidInfoOpcode ( WorldPacket &  recvData)
1138{
1139 // every time the player checks the character screen
1141}
void SendRaidInfo()
Definition PlayerStorage.cpp:6701

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 ( WorldPackets::Instance::ResetInstances &  packet)
1256{
1257 LOG_DEBUG("network", "WORLD: CMSG_RESET_INSTANCES");
1258
1259 if (Group* group = _player->GetGroup())
1260 {
1261 if (group->IsLeader(_player->GetGUID()))
1262 group->ResetInstances(INSTANCE_RESET_ALL, false, _player);
1263 }
1264 else
1266}
@ INSTANCE_RESET_ALL
Definition Map.h:716
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:193

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

Referenced by OpcodeTable::Initialize().

◆ HandleResurrectResponseOpcode()

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

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

Referenced by OpcodeTable::Initialize().

◆ HandleSaveGuildEmblemOpcode()

void WorldSession::HandleSaveGuildEmblemOpcode ( WorldPackets::Guild::SaveGuildEmblem &  packet)
234{
235 EmblemInfo emblemInfo;
236 emblemInfo.ReadPacket(packet);
237
238 LOG_DEBUG("guild", "MSG_SAVE_GUILD_EMBLEM [{}]: Guid: [{}] Style: {}, Color: {}, BorderStyle: {}, BorderColor: {}, BackgroundColor: {}"
239 , GetPlayerInfo(), packet.Vendor.ToString(), emblemInfo.GetStyle()
240 , emblemInfo.GetColor(), emblemInfo.GetBorderStyle()
241 , emblemInfo.GetBorderColor(), emblemInfo.GetBackgroundColor());
242 if (GetPlayer()->GetNPCIfCanInteractWith(packet.Vendor, UNIT_NPC_FLAG_TABARDDESIGNER))
243 {
244 // Remove fake death
245 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
247
248 if (Guild* guild = GetPlayer()->GetGuild())
249 guild->HandleSetEmblem(this, emblemInfo);
250 else
251 Guild::SendSaveEmblemResult(this, ERR_GUILDEMBLEM_NOGUILD); // "You are not part of a guild!";
252 }
253 else
254 Guild::SendSaveEmblemResult(this, ERR_GUILDEMBLEM_INVALIDVENDOR); // "That's not an emblem vendor!"
255}
@ ERR_GUILDEMBLEM_INVALIDVENDOR
Definition Guild.h:225
@ ERR_GUILDEMBLEM_NOGUILD
Definition Guild.h:222
@ UNIT_NPC_FLAG_TABARDDESIGNER
Definition UnitDefines.h:341
Definition Guild.h:239
uint32 GetStyle() const
Definition Guild.h:250
uint32 GetColor() const
Definition Guild.h:251
uint32 GetBackgroundColor() const
Definition Guild.h:254
uint32 GetBorderStyle() const
Definition Guild.h:252
void ReadPacket(WorldPackets::Guild::SaveGuildEmblem &packet)
Definition Guild.cpp:684
uint32 GetBorderColor() const
Definition Guild.h:253
static void SendSaveEmblemResult(WorldSession *session, GuildEmblemError errCode)
Definition Guild.cpp:126
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)
708{
709 LOG_DEBUG("network", "WORLD: CMSG_SELF_RES"); // empty opcode
710
711 if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(_player->GetUInt32Value(PLAYER_SELF_RES_SPELL)))
712 {
714 {
715 return; // silent return, client should display error by itself and not send this opcode
716 }
717
718 _player->CastSpell(_player, spell->Id);
720 }
721}
@ SPELL_ATTR7_BYPASS_NO_RESURRECTION_AURA
Definition SharedDefines.h:656
@ 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 {
607 return;
608 }
609
610 // prevent sell not owner item
611 if (_player->GetGUID() != pItem->GetOwnerGUID())
612 {
614 return;
615 }
616
617 // prevent sell non empty bag by drag-and-drop at vendor's item list
618 if (pItem->IsNotEmptyBag())
619 {
621 return;
622 }
623
624 // prevent sell currently looted item
625 if (_player->GetLootGUID() == pItem->GetGUID())
626 {
628 return;
629 }
630
631 // prevent selling item for sellprice when the item is still refundable
632 // this probably happens when right clicking a refundable item, the client sends both
633 // CMSG_SELL_ITEM and CMSG_REFUND_ITEM (unverified)
634 if (pItem->IsRefundable())
635 return; // Therefore, no feedback to client
636
637 // special case at auto sell (sell all)
638 if (packet.Count == 0)
639 packet.Count = pItem->GetCount();
640 else
641 {
642 // prevent sell more items that exist in stack (possible only not from client)
643 if (packet.Count > pItem->GetCount())
644 {
646 return;
647 }
648 }
649
650 ItemTemplate const* pProto = pItem->GetTemplate();
651 if (pProto)
652 {
653 if (pProto->SellPrice > 0)
654 {
655 uint32 money = pProto->SellPrice * packet.Count;
656 if (_player->GetMoney() >= MAX_MONEY_AMOUNT - money) // prevent exceeding gold limit
657 {
659 _player->SendSellError(SELL_ERR_UNK, creature, packet.ItemGuid, 0);
660 return;
661 }
662
663 if (sWorld->getBoolConfig(CONFIG_ITEMDELETE_VENDOR))
664 recoveryItem(pItem);
665
666 uint32 maxDurability = pItem->GetUInt32Value(ITEM_FIELD_MAXDURABILITY);
667 if (maxDurability)
668 {
669 uint32 curDurability = pItem->GetUInt32Value(ITEM_FIELD_DURABILITY);
670 uint32 LostDurability = maxDurability - curDurability;
671
672 if (LostDurability > 0)
673 {
674 DurabilityCostsEntry const* dcost = sDurabilityCostsStore.LookupEntry(pProto->ItemLevel);
675 if (!dcost)
676 {
678 LOG_ERROR("network.opcode", "WORLD: HandleSellItemOpcode - Wrong item lvl {} for item {} count = {}", pProto->ItemLevel, pItem->GetEntry(), packet.Count);
679 return;
680 }
681
682 uint32 dQualitymodEntryId = (pProto->Quality + 1) * 2;
683 DurabilityQualityEntry const* dQualitymodEntry = sDurabilityQualityStore.LookupEntry(dQualitymodEntryId);
684 if (!dQualitymodEntry)
685 {
687 LOG_ERROR("network.opcode", "WORLD: HandleSellItemOpcode - Wrong dQualityModEntry {} for item {} count = {}", dQualitymodEntryId, pItem->GetEntry(), packet.Count);
688 return;
689 }
690
691 uint32 dmultiplier = dcost->multiplier[ItemSubClassToDurabilityMultiplierId(pProto->Class, pProto->SubClass)];
692 uint32 refund = uint32(std::ceil(LostDurability * dmultiplier * double(dQualitymodEntry->quality_mod)));
693
694 if (!refund)
695 refund = 1;
696
697 //starter items can cost more to refund than vendorprice
698 if (refund > money)
699 money = 1;
700 else
701 money -= refund;
702 }
703 }
704
705 if (packet.Count < pItem->GetCount()) // need split items
706 {
707 Item* pNewItem = pItem->CloneItem(packet.Count, _player);
708 if (!pNewItem)
709 {
710 LOG_ERROR("network.opcode", "WORLD: HandleSellItemOpcode - could not create clone of item {}; count = {}", pItem->GetEntry(), packet.Count);
712 return;
713 }
714
716
717 pItem->SetCount(pItem->GetCount() - packet.Count);
718 _player->ItemRemovedQuestCheck(pItem->GetEntry(), packet.Count);
719 if (_player->IsInWorld())
722
723 _player->AddItemToBuyBackSlot(pNewItem, money);
724 if (_player->IsInWorld())
725 pNewItem->SendUpdateToPlayer(_player);
726 }
727 else
728 {
729 _player->ItemRemovedQuestCheck(pItem->GetEntry(), pItem->GetCount());
730 _player->RemoveItem(pItem->GetBagSlot(), pItem->GetSlot(), true);
732 _player->AddItemToBuyBackSlot(pItem, money);
734 }
735
736 _player->ModifyMoney(money);
738 }
739 else
741 return;
742 }
743 }
745 return;
746}
@ CREATURE_FLAG_EXTRA_NO_SELL_VENDOR
Definition CreatureData.h:58
@ 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
@ ITEM_FIELD_DURABILITY
Definition UpdateFields.h:69
bool HasFlagsExtra(uint32 flag) const
Definition Creature.h:77
void RemoveFromUpdateQueueOf(Player *player)
Definition Item.cpp:765
ObjectGuid GetOwnerGUID() const
Definition Item.h:231
bool IsRefundable() const
Definition Item.h:261
void AddItemToBuyBackSlot(Item *pItem, uint32 money)
Definition PlayerStorage.cpp:4046
uint32 Count
Definition ItemPackets.h:124
ObjectGuid VendorGuid
Definition ItemPackets.h:122
ObjectGuid ItemGuid
Definition ItemPackets.h:123
Definition DBCStructure.h:905
uint32 multiplier[29]
Definition DBCStructure.h:907
Definition DBCStructure.h:911
float quality_mod
Definition DBCStructure.h:913

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

66{
67 ObjectGuid mailbox;
68 uint64 unk3;
69 std::string receiver, subject, body;
70 uint32 unk1, unk2, money, COD;
71 uint8 unk4;
72
73 recvData >> mailbox;
74 recvData >> receiver;
75
76 recvData >> subject;
77
78 // prevent client crash
79 if (subject.find("| |") != std::string::npos || body.find("| |") != std::string::npos)
80 {
81 return;
82 }
83
84 recvData >> body;
85
86 recvData >> unk1; // stationery?
87 recvData >> unk2; // 0x00000000
88
89 uint8 items_count;
90 recvData >> items_count; // attached items count
91
92 if (items_count > MAX_MAIL_ITEMS) // client limit
93 {
95 recvData.rfinish(); // set to end to avoid warnings spam
96 return;
97 }
98
99 ObjectGuid itemGUIDs[MAX_MAIL_ITEMS];
100
101 for (uint8 i = 0; i < items_count; ++i)
102 {
103 recvData.read_skip<uint8>(); // item slot in mail, not used
104 recvData >> itemGUIDs[i];
105 }
106
107 recvData >> money >> COD; // money and cod
108 recvData >> unk3; // const 0
109 recvData >> unk4; // const 0
110
111 // packet read complete, now do check
112
113 if (!CanOpenMailBox(mailbox))
114 return;
115
116 if (receiver.empty())
117 return;
118
119 Player* player = _player;
120
121 if (sWorld->getBoolConfig(CONFIG_TRIAL_RESTRICTION_MAIL) && IsTrialAccount())
122 {
124 return;
125 }
126
127 if (player->GetLevel() < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ))
128 {
130 return;
131 }
132
133 ObjectGuid receiverGuid;
134 if (normalizePlayerName(receiver))
135 {
136 receiverGuid = sCharacterCache->GetCharacterGuidByName(receiver);
137 }
138
139 if (!receiverGuid)
140 {
141 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 = {}",
142 player->GetGUID().ToString(), receiver, subject, body, items_count, money, COD, unk1, unk2);
144 return;
145 }
146
147 LOG_DEBUG("network.opcode", "Player {} is sending mail to {} ({}) with subject {} and body {} includes {} items, {} copper and {} COD copper with unk1 = {}, unk2 = {}",
148 player->GetGUID().ToString(), receiver, receiverGuid.ToString(), subject, body, items_count, money, COD, unk1, unk2);
149
150 if (player->GetGUID() == receiverGuid)
151 {
153 return;
154 }
155
156 if (money && COD) // cannot send money in a COD mail
157 {
158 LOG_ERROR("network.opcode", "{} attempt to dupe money!!!.", receiver);
160 return;
161 }
162
163 uint32 cost = items_count ? 30 * items_count : 30; // price hardcoded in client
164
165 uint32 reqmoney = cost + money;
166
167 // Check for overflow
168 if (reqmoney < money)
169 {
171 return;
172 }
173
174 if (!player->HasEnoughMoney(reqmoney))
175 {
177 return;
178 }
179
180 Player* receive = ObjectAccessor::FindConnectedPlayer(receiverGuid);
181
182 uint32 rc_teamId = TEAM_NEUTRAL;
183 uint16 mails_count = 0; //do not allow to send to one player more than 100 mails
184
185 if (receive)
186 {
187 rc_teamId = receive->GetTeamId();
188 mails_count = receive->GetMailSize();
189 }
190 else
191 {
192 // xinef: get data from global storage
193 if (CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(receiverGuid))
194 {
195 rc_teamId = Player::TeamIdForRace(playerData->Race);
196 mails_count = playerData->MailCount;
197 }
198 }
199 //do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255..
200 if (mails_count > 100)
201 {
203 return;
204 }
205 // test the receiver's Faction... or all items are account bound
206 // Xinef: check for boa items, not used currently
207 /*bool accountBound = items_count && !money && !COD ? true : false;
208 for (uint8 i = 0; i < items_count; ++i)
209 {
210 Item* item = player->GetItemByGuid(itemGUIDs[i]);
211 if (item)
212 {
213 ItemTemplate const* itemProto = item->GetTemplate();
214 if (!itemProto || !itemProto->HasFlag(ITEM_FLAG_IS_BOUND_TO_ACCOUNT))
215 {
216 accountBound = false;
217 break;
218 }
219 }
220 }*/
221
222 uint32 rc_account = receive ? receive->GetSession()->GetAccountId() : sCharacterCache->GetCharacterAccountIdByGuid(receiverGuid);
223
224 if ( GetAccountId() != rc_account && player->GetTeamId() != rc_teamId && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_MAIL))
225 {
227 return;
228 }
229
230 Item* items[MAX_MAIL_ITEMS];
231
232 for (uint8 i = 0; i < items_count; ++i)
233 {
234 if (!itemGUIDs[i])
235 {
237 return;
238 }
239
240 Item* item = player->GetItemByGuid(itemGUIDs[i]);
241
242 // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail)
243 if (!item)
244 {
246 return;
247 }
248
249 // handle empty bag before CanBeTraded, since that func already has that check
250 if (item->IsNotEmptyBag())
251 {
253 return;
254 }
255
256 if (!item->CanBeTraded(true))
257 {
259 return;
260 }
261
262 if (item->IsBoundAccountWide() && item->IsSoulBound() && GetAccountId() != rc_account)
263 {
265 return;
266 }
267
269 {
271 return;
272 }
273
274 if (COD && item->IsWrapped())
275 {
277 return;
278 }
279
280 if (!sScriptMgr->OnPlayerCanSendMail(player, receiverGuid, mailbox, subject, body, money, COD, item))
281 {
283 return;
284 }
285
286 items[i] = item;
287 }
288
289 if (!items_count && !sScriptMgr->OnPlayerCanSendMail(player, receiverGuid, mailbox, subject, body, money, COD, nullptr))
290 {
292 return;
293 }
294
295 player->SendMailResult(0, MAIL_SEND, MAIL_OK);
296
298 {
299 if (items_count > 0)
300 {
301 for (uint8 i = 0; i < items_count; ++i)
302 {
303 Item* item = items[i];
304 LOG_GM(GetAccountId(), "GM {} (Account: {}) sent mail to {} (Account: {}) with item: {} (Entry: {} Count: {})",
305 player->GetName(), GetAccountId(), receiver, rc_account,
306 item->GetTemplate()->Name1, item->GetEntry(), item->GetCount());
307 }
308 }
309 if (money > 0)
310 {
311 LOG_GM(GetAccountId(), "GM {} (Account: {}) sent mail to {} (Account: {}) with money: {}",
312 player->GetName(), GetAccountId(), receiver, rc_account, money);
313 }
314 }
315
316 player->ModifyMoney(-int32(reqmoney));
318
319 bool needItemDelay = false;
320
321 MailDraft draft(subject, body);
322
323 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
324
325 std::string itemLogStr = "";
326 if (items_count > 0 || money > 0)
327 {
328 if (items_count > 0)
329 {
330 for (uint8 i = 0; i < items_count; ++i)
331 {
332 // log item
333 itemLogStr += Acore::StringFormat("{} (Entry: {}) x{}, ", items[i]->GetTemplate()->Name1, items[i]->GetEntry(), items[i]->GetCount());
334
335 Item* item = items[i];
336
337 item->SetNotRefundable(GetPlayer()); // makes the item no longer refundable
338 player->MoveItemFromInventory(items[i]->GetBagSlot(), item->GetSlot(), true);
339
340 item->DeleteFromInventoryDB(trans); // deletes item from character's inventory
341 if (item->GetState() == ITEM_UNCHANGED)
342 item->FSetState(ITEM_CHANGED); // pussywizard: so the item will be saved and owner will be updated in database
343 item->SetOwnerGUID(receiverGuid);
344 item->SaveToDB(trans); // recursive and not have transaction guard into self, item not in inventory and can be save standalone
345
346 draft.AddItem(item);
347 }
348
349 // if item send to character at another account, then apply item delivery delay
350 needItemDelay = GetAccountId() != rc_account;
351 }
352
353 if (money >= 10 * GOLD)
354 {
356 CharacterDatabase.Execute("INSERT INTO log_money VALUES({}, {}, \"{}\", \"{}\", {}, \"{}\", {}, \"{}\", NOW(), {})",
357 GetAccountId(), player->GetGUID().GetCounter(), player->GetName(), player->GetSession()->GetRemoteAddress(), rc_account, receiver, money, subject, 5);
358 }
359 }
360
361 // If theres is an item, there is a one hour delivery delay if sent to another account's character.
362 uint32 deliver_delay = needItemDelay ? sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0;
363
364 // don't ask for COD if there are no items
365 if (items_count == 0)
366 COD = 0;
367
368 // will delete item or place to receiver mail list
369 draft
370 .AddMoney(money)
371 .AddCOD(COD)
372 .SendMailTo(trans, MailReceiver(receive, receiverGuid.GetCounter()), MailSender(player), body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay);
373
374 player->SaveInventoryAndGoldToDB(trans);
375 CharacterDatabase.CommitTransaction(trans);
376
377 LOG_INFO("entities.player.mail", "Mail: Account: {} (IP: {}), Player [{}] ({}) sent mail to Player [{}] ({}): subject='{}', body='{}', {} copper, {} COD copper, sent item(s) [{}]",
378 GetAccountId(), GetRemoteAddress(), player->GetName(), player->GetGUID().GetCounter(),
379 receiver, receiverGuid.GetCounter(), subject, body, money, COD, itemLogStr);
380}
@ 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:1247
#define MAX_MAIL_ITEMS
Definition Mail.h:33
@ MAIL_CHECK_MASK_HAS_BODY
Definition Mail.h:51
@ MAIL_SEND
Definition SharedDefines.h:3756
@ MAIL_ERR_NOT_YOUR_TEAM
Definition SharedDefines.h:3771
@ MAIL_ERR_CANT_SEND_WRAPPED_COD
Definition SharedDefines.h:3775
@ MAIL_ERR_RECIPIENT_CAP_REACHED
Definition SharedDefines.h:3774
@ MAIL_ERR_RECIPIENT_NOT_FOUND
Definition SharedDefines.h:3770
@ MAIL_ERR_TOO_MANY_ATTACHMENTS
Definition SharedDefines.h:3777
@ MAIL_ERR_DISABLED_FOR_TRIAL_ACC
Definition SharedDefines.h:3773
@ MAIL_ERR_MAIL_ATTACHMENT_INVALID
Definition SharedDefines.h:3778
@ MAIL_ERR_CANNOT_SEND_TO_SELF
Definition SharedDefines.h:3768
@ CONFIG_MAIL_LEVEL_REQ
Definition WorldConfig.h:257
@ CONFIG_MAIL_DELIVERY_DELAY
Definition WorldConfig.h:220
@ CONFIG_TRIAL_RESTRICTION_MAIL
Definition WorldConfig.h:510
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:1210
void FSetState(ItemUpdateState state)
Definition Item.h:330
void SetOwnerGUID(ObjectGuid guid)
Definition Item.h:232
uint32 GetMailSize()
Definition Player.h:1675
@ RBAC_PERM_TWO_SIDE_INTERACTION_MAIL
Definition RBAC.h:78

References _player, ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, MailDraft::AddCOD(), MailDraft::AddItem(), MailDraft::AddMoney(), Item::CanBeTraded(), CanOpenMailBox(), CharacterDatabase, CleanStringForMysqlQuery(), CONFIG_MAIL_DELIVERY_DELAY, CONFIG_MAIL_LEVEL_REQ, CONFIG_TRIAL_RESTRICTION_MAIL, 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(), Item::GetCount(), ObjectGuid::GetCounter(), Object::GetEntry(), Object::GetGUID(), Player::GetItemByGuid(), Unit::GetLevel(), Player::GetMailSize(), WorldObject::GetName(), GetPlayer(), GetRemoteAddress(), Player::GetSession(), Item::GetSlot(), Item::GetState(), Player::GetTeamId(), Item::GetTemplate(), Object::GetUInt32Value(), GOLD, Player::HasEnoughMoney(), ItemTemplate::HasFlag(), HasPermission(), Item::IsBoundAccountWide(), Item::IsNotEmptyBag(), Item::IsSoulBound(), IsTrialAccount(), Item::IsWrapped(), ITEM_CHANGED, ITEM_FIELD_DURATION, ITEM_FLAG_CONJURED, ITEM_UNCHANGED, LANG_MAIL_SENDER_REQ, LOG_DEBUG, LOG_ERROR, LOG_GM, LOG_INFO, MAIL_CHECK_MASK_COPIED, MAIL_CHECK_MASK_HAS_BODY, MAIL_ERR_CANNOT_SEND_TO_SELF, MAIL_ERR_CANT_SEND_WRAPPED_COD, MAIL_ERR_DISABLED_FOR_TRIAL_ACC, 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(), ItemTemplate::Name1, normalizePlayerName(), rbac::RBAC_PERM_LOG_GM_TRADE, rbac::RBAC_PERM_TWO_SIDE_INTERACTION_MAIL, ByteBuffer::read_skip(), ByteBuffer::rfinish(), Player::SaveInventoryAndGoldToDB(), Item::SaveToDB(), sCharacterCache, Player::SendMailResult(), MailDraft::SendMailTo(), ChatHandler::SendNotification(), Item::SetNotRefundable(), Item::SetOwnerGUID(), sScriptMgr, Acore::StringFormat(), sWorld, TEAM_NEUTRAL, Player::TeamIdForRace(), ObjectGuid::ToString(), and Player::UpdateAchievementCriteria().

Referenced by OpcodeTable::Initialize().

◆ HandleSetActionBarToggles()

void WorldSession::HandleSetActionBarToggles ( WorldPacket &  recvData)
953{
954 uint8 ActionBar;
955
956 recv_data >> ActionBar;
957
958 if (!GetPlayer()) // ignore until not logged (check needed because STATUS_AUTHED)
959 {
960 if (ActionBar != 0)
961 LOG_ERROR("network.opcode", "WorldSession::HandleSetActionBarToggles in not logged state with value: {}, ignored", uint32(ActionBar));
962 return;
963 }
964
965 GetPlayer()->SetByteValue(PLAYER_FIELD_BYTES, 2, ActionBar);
966}
@ 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)
900{
901 uint8 button;
902 uint32 packetData;
903 recv_data >> button >> packetData;
904
905 uint32 action = ACTION_BUTTON_ACTION(packetData);
906 uint8 type = ACTION_BUTTON_TYPE(packetData);
907
908 LOG_DEBUG("network.opcode", "BUTTON: {} ACTION: {} TYPE: {}", button, action, type);
909 if (!packetData)
910 {
911 LOG_DEBUG("network.opcode", "MISC: Remove action from button {}", button);
912 GetPlayer()->removeActionButton(button);
913 }
914 else
915 {
916 switch (type)
917 {
920 LOG_DEBUG("network.opcode", "MISC: Added Macro {} into button {}", action, button);
921 break;
923 LOG_DEBUG("network.opcode", "MISC: Added EquipmentSet {} into button {}", action, button);
924 break;
926 LOG_DEBUG("network.opcode", "MISC: Added Spell {} into button {}", action, button);
927 break;
929 LOG_DEBUG("network.opcode", "MISC: Added Item {} into button {}", action, button);
930 break;
931 default:
932 LOG_ERROR("network.opcode", "MISC: Unknown action button type {} for action {} into button {} for player {} ({})",
933 type, action, button, _player->GetName(), _player->GetGUID().ToString());
934 return;
935 }
936 GetPlayer()->addActionButton(button, action, type);
937 }
938}
@ ACTION_BUTTON_EQSET
Definition Player.h:224
@ ACTION_BUTTON_MACRO
Definition Player.h:225
@ ACTION_BUTTON_ITEM
Definition Player.h:227
@ ACTION_BUTTON_CMACRO
Definition Player.h:226
@ ACTION_BUTTON_SPELL
Definition Player.h:222
#define ACTION_BUTTON_TYPE(X)
Definition Player.h:236
#define ACTION_BUTTON_ACTION(X)
Definition Player.h:235
ActionButton * addActionButton(uint8 button, uint32 action, uint8 type)
Definition Player.cpp:5794
void removeActionButton(uint8 button)
Definition Player.cpp:5809

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)
781{
782 LOG_DEBUG("network", "WORLD: Recvd CMSG_SET_ACTIVE_MOVER");
783
784 ObjectGuid guid;
785 recvData >> guid;
786
787 if (GetPlayer()->IsInWorld() && _player->m_mover && _player->m_mover->IsInWorld())
788 {
789 if (_player->m_mover->GetGUID() != guid)
790 LOG_ERROR("network.opcode", "HandleSetActiveMoverOpcode: incorrect mover guid: mover is {} and should be {}",
791 guid.ToString(), _player->m_mover->GetGUID().ToString());
792 }
793}

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)
1015{
1016 if (!_player->IsAlive())
1017 {
1018 _player->SendEquipError(EQUIP_ERR_YOU_ARE_DEAD, nullptr, nullptr);
1019 return;
1020 }
1021
1022 LOG_DEBUG("network", "WORLD: CMSG_SET_AMMO");
1023 uint32 item;
1024
1025 recvData >> item;
1026
1027 if (item)
1028 {
1029 if (!_player->GetItemCount(item))
1030 {
1032 return;
1033 }
1034
1035 _player->SetAmmo(item);
1036 }
1037 else
1039}
uint32 GetItemCount(uint32 item, bool inBankAlso=false, Item *skipItem=nullptr) const
Definition PlayerStorage.cpp:331
void RemoveAmmo()
Definition PlayerStorage.cpp:2625
void SetAmmo(uint32 item)
Definition PlayerStorage.cpp:2603

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)
322{
323 std::string channelName;
324 recvPacket >> channelName;
325
327
328 if (channelName.empty())
329 return;
330
332 if (Channel* channel = cMgr->GetChannel(channelName, nullptr, false))
333 channel->AddWatching(GetPlayer());
334}
void ClearChannelWatch()
Definition Player.cpp:5099

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

Referenced by OpcodeTable::Initialize().

◆ HandleSetContactNotesOpcode()

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

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

Referenced by OpcodeTable::Initialize().

◆ HandleSetDungeonDifficultyOpcode()

void WorldSession::HandleSetDungeonDifficultyOpcode ( WorldPackets::Instance::SetDungeonDifficultyClient &  packet)
1269{
1270 LOG_DEBUG("network", "MSG_SET_DUNGEON_DIFFICULTY");
1271
1272 if (packet.Mode >= MAX_DUNGEON_DIFFICULTY)
1273 return;
1274
1275 if (Difficulty(packet.Mode) == _player->GetDungeonDifficulty())
1276 return;
1277
1278 Group* group = _player->GetGroup();
1279 if (group)
1280 {
1281 if (group->IsLeader(_player->GetGUID()))
1282 {
1283 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
1284 {
1285 Player* groupGuy = itr->GetSource();
1286 if (!groupGuy)
1287 continue;
1288
1289 if (!groupGuy->IsInWorld())
1290 {
1291 _player->SendDungeonDifficulty(group != nullptr);
1292 return;
1293 }
1294
1295 if (groupGuy->GetGUID() == _player->GetGUID() ? groupGuy->GetMap()->IsDungeon() : groupGuy->GetMap()->IsNonRaidDungeon())
1296 {
1297 _player->SendDungeonDifficulty(group != nullptr);
1298 return;
1299 }
1300 }
1301
1303 group->SetDungeonDifficulty(Difficulty(packet.Mode));
1304 }
1305 }
1306 else
1307 {
1308 if (_player->FindMap() && _player->FindMap()->IsDungeon())
1309 {
1310 _player->SendDungeonDifficulty(group != nullptr);
1311 return;
1312 }
1315 }
1316}
#define MAX_DUNGEON_DIFFICULTY
Definition DBCEnums.h:281
@ INSTANCE_RESET_CHANGE_DIFFICULTY
Definition Map.h:717
void SetDungeonDifficulty(Difficulty difficulty)
Definition Group.cpp:2292
void ResetInstances(uint8 method, bool isRaid, Player *leader)
Definition Group.cpp:2334
bool IsNonRaidDungeon() const
Definition Map.h:300
void SetDungeonDifficulty(Difficulty dungeon_difficulty)
Definition Player.h:1952
Difficulty GetDungeonDifficulty() const
Definition Player.h:1949
uint32 Mode
Definition InstancePackets.h:68

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, WorldPackets::Instance::SetDungeonDifficultyClient::Mode, Player::ResetInstances(), Group::ResetInstances(), Player::SendDungeonDifficulty(), Group::SetDungeonDifficulty(), and Player::SetDungeonDifficulty().

Referenced by OpcodeTable::Initialize().

◆ HandleSetFactionAtWar()

void WorldSession::HandleSetFactionAtWar ( WorldPacket &  recvData)
1283{
1284 uint32 repListID;
1285 uint8 flag;
1286
1287 recvData >> repListID;
1288 recvData >> flag;
1289
1290 GetPlayer()->GetReputationMgr().SetAtWar(repListID, flag);
1291}
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)
1295{
1296 LOG_ERROR("network.opcode", "WORLD SESSION: HandleSetFactionCheat, not expected call, please report.");
1298}

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

Referenced by OpcodeTable::Initialize().

◆ HandleSetFactionInactiveOpcode()

void WorldSession::HandleSetFactionInactiveOpcode ( WorldPacket &  recvData)
1336{
1337 uint32 replistid;
1338 uint8 inactive;
1339 recvData >> replistid >> inactive;
1340
1341 _player->GetReputationMgr().SetInactive(replistid, inactive);
1342}
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)
406{
407 LOG_DEBUG("guild", "CMSG_SET_GUILD_BANK_TEXT [{}]: TabId: {}, Text: {}", GetPlayerInfo(), packet.Tab, packet.TabText);
408
409 if (Guild* guild = GetPlayer()->GetGuild())
410 guild->SetBankTabText(packet.Tab, packet.TabText);
411}
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)
1449{
1450 // pussywizard:
1451 if (!sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
1452 return;
1453
1454 ObjectGuid guid;
1455 recvData >> guid;
1456
1457 // not accept declined names for unsupported languages
1458 std::string name;
1459 if (!sCharacterCache->GetCharacterNameByGuid(guid, name))
1460 {
1462 return;
1463 }
1464
1465 std::wstring wname;
1466 if (!Utf8toWStr(name, wname))
1467 {
1469 return;
1470 }
1471
1472 if (!isCyrillicCharacter(wname[0])) // name already stored as only single alphabet using
1473 {
1475 return;
1476 }
1477
1478 std::string name2;
1479 DeclinedName declinedname;
1480
1481 recvData >> name2;
1482
1483 if (name2 != name) // character have different name
1484 {
1486 return;
1487 }
1488
1489 for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
1490 {
1491 recvData >> declinedname.name[i];
1492 if (!normalizePlayerName(declinedname.name[i]))
1493 {
1495 return;
1496 }
1497 }
1498
1499 if (!ObjectMgr::CheckDeclinedNames(wname, declinedname))
1500 {
1502 return;
1503 }
1504
1505 for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
1506 CharacterDatabase.EscapeString(declinedname.name[i]);
1507
1508 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
1509
1511 stmt->SetData(0, guid.GetCounter());
1512 trans->Append(stmt);
1513
1514 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_DECLINED_NAME);
1515 stmt->SetData(0, guid.GetCounter());
1516
1517 for (uint8 i = 0; i < 5; i++)
1518 stmt->SetData(i + 1, declinedname.name[i]);
1519
1520 trans->Append(stmt);
1521
1522 CharacterDatabase.CommitTransaction(trans);
1523
1525}
@ CHAR_INS_CHAR_DECLINED_NAME
Definition CharacterDatabase.h:393
bool isCyrillicCharacter(wchar_t wchar)
Definition Util.h:145
void SendSetPlayerDeclinedNamesResult(DeclinedNameResult result, ObjectGuid guid)
Definition CharacterHandler.cpp:2673
@ DECLINED_NAMES_RESULT_SUCCESS
Definition WorldSession.h:281
@ DECLINED_NAMES_RESULT_ERROR
Definition WorldSession.h:282

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

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, WorldPackets::Instance::SetRaidDifficultyClient::Mode, 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)
794{
795 uint32 mapId, difficulty;
796 uint8 toggleExtendOn;
797 recvData >> mapId >> difficulty >> toggleExtendOn;
798
799 MapEntry const* entry = sMapStore.LookupEntry(mapId);
800 if (!entry || !entry->IsRaid())
801 return;
802
803 InstancePlayerBind* instanceBind = sInstanceSaveMgr->PlayerGetBoundInstance(GetPlayer()->GetGUID(), mapId, Difficulty(difficulty));
804 if (!instanceBind || !instanceBind->perm || (bool)toggleExtendOn == instanceBind->extended)
805 return;
806
807 instanceBind->extended = (bool)toggleExtendOn;
808
809 // update in db
811 stmt->SetData(0, toggleExtendOn ? 1 : 0);
812 stmt->SetData(1, GetPlayer()->GetGUID().GetCounter());
813 stmt->SetData(2, instanceBind->save->GetInstanceId());
814 CharacterDatabase.Execute(stmt);
815
816 SendCalendarRaidLockoutUpdated(instanceBind->save, (bool)toggleExtendOn);
817}
@ CHAR_UPD_CHAR_INSTANCE_EXTENDED
Definition CharacterDatabase.h:316
void SendCalendarRaidLockoutUpdated(InstanceSave const *save, bool isExtended)
Definition CalendarHandler.cpp:840
Definition InstanceSaveMgr.h:40
InstanceSave * save
Definition InstanceSaveMgr.h:41
bool extended
Definition InstanceSaveMgr.h:43
bool perm
Definition InstanceSaveMgr.h:42

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

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:128
#define MAX_SHEATH_STATE
Definition UnitDefines.h:134
void SetSheath(SheathState sheathed) override
Definition PlayerStorage.cpp:101
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)
1581{
1582 uint8 mode;
1583 recv_data >> mode;
1584
1586
1587 LOG_DEBUG("network", "Client used \"/timetest {}\" command", mode);
1588}
@ PLAYER_FLAGS_TAXI_BENCHMARK
Definition Player.h:476

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

Referenced by OpcodeTable::Initialize().

◆ HandleSetTitleOpcode()

void WorldSession::HandleSetTitleOpcode ( WorldPacket &  recvData)
1237{
1238 LOG_DEBUG("network", "CMSG_SET_TITLE");
1239
1240 int32 title;
1241 recv_data >> title;
1242
1243 // -1 at none
1244 if (title > 0 && title < MAX_TITLE_INDEX)
1245 {
1246 if (!GetPlayer()->HasTitle(title))
1247 return;
1248 }
1249 else
1250 title = 0;
1251
1253}
#define MAX_TITLE_INDEX
Definition Player.h:539
@ 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)
859{
860 uint32 gold;
861 recvPacket >> gold;
862
863 TradeData* my_trade = _player->GetTradeData();
864 if (!my_trade)
865 return;
866
867 my_trade->SetMoney(gold);
868}
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)
871{
872 // send update
873 uint8 tradeSlot;
874 uint8 bag;
875 uint8 slot;
876
877 recvPacket >> tradeSlot;
878 recvPacket >> bag;
879 recvPacket >> slot;
880
881 TradeData* my_trade = _player->GetTradeData();
882 if (!my_trade)
883 return;
884
885 TradeStatusInfo info;
886 // invalid slot number
887 if (tradeSlot >= TRADE_SLOT_COUNT)
888 {
890 SendTradeStatus(info);
891 return;
892 }
893
894 // check cheating, can't fail with correct client operations
895 Item* item = _player->GetItemByPos(bag, slot);
896 if (!item || (tradeSlot != TRADE_SLOT_NONTRADED && !item->CanBeTraded(false, true)))
897 {
899 SendTradeStatus(info);
900 return;
901 }
902
903 ObjectGuid iGUID = item->GetGUID();
904
905 // prevent place single item into many trade slots using cheating and client bugs
906 if (my_trade->HasItem(iGUID))
907 {
908 // cheating attempt
910 SendTradeStatus(info);
911 return;
912 }
913
914 // PlayerScript Hook for checking traded items if we want to filter them in a custom module
915 if (!sScriptMgr->OnPlayerCanSetTradeItem(_player, item, tradeSlot))
916 {
917 // Do not send TRADE_STATUS_TRADE_CANCELED because it will cause double display of "Transaction canceled" notification
918 // On the trade initiator screen
920 SendTradeStatus(info);
921 return;
922 }
923
924 if (tradeSlot != TRADE_SLOT_NONTRADED && item->IsBindedNotWith(my_trade->GetTrader()))
925 {
927 info.Slot = tradeSlot;
928 SendTradeStatus(info);
929 return;
930 }
931
932 my_trade->SetItem(TradeSlots(tradeSlot), item);
933}
@ TRADE_STATUS_NOT_ON_TAPLIST
Definition SharedDefines.h:3829
bool IsBindedNotWith(Player const *player) const
Definition Item.cpp:1142
bool HasItem(ObjectGuid itemGuid) const
Definition TradeData.cpp:31
uint8 Slot
Definition Player.h:1070

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

Referenced by OpcodeTable::Initialize().

◆ HandleSetWatchedFactionOpcode()

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

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
724{
725 ObjectGuid guid;
726 recvData >> guid;
727
728 // this will get something not in world. crash
730
731 if (!unit)
732 return;
733
735 if (!unit->IsInWorld())
736 return;
737
739}
bool HandleSpellClick(Unit *clicker, int8 seatId=-1)
Definition Unit.cpp:15134

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

Referenced by OpcodeTable::Initialize().

◆ HandleSpiritHealerActivateOpcode()

void WorldSession::HandleSpiritHealerActivateOpcode ( WorldPacket &  recvPacket)
239{
240 LOG_DEBUG("network", "WORLD: CMSG_SPIRIT_HEALER_ACTIVATE");
241
242 ObjectGuid guid;
243
244 recvData >> guid;
245
247 if (!unit)
248 {
249 LOG_DEBUG("network", "WORLD: HandleSpiritHealerActivateOpcode - Unit ({}) not found or you can not interact with him.", guid.ToString());
250 return;
251 }
252
253 // remove fake death
254 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
256
258}
@ UNIT_NPC_FLAG_SPIRITHEALER
Definition UnitDefines.h:336
void SendSpiritResurrect()
Definition NPCHandler.cpp:260

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:3525
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)
426{
427 LOG_DEBUG("network", "WORLD: Recv CMSG_STABLE_PET");
428 ObjectGuid npcGUID;
429
430 recvData >> npcGUID;
431
432 if (!GetPlayer()->IsAlive())
433 {
435 return;
436 }
437
438 if (!CheckStableMaster(npcGUID))
439 {
441 return;
442 }
443
444 // remove fake death
445 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
447
448 PetStable* petStable = GetPlayer()->GetPetStable();
449 if (!petStable)
450 return;
451
452 Pet* pet = _player->GetPet();
453
454 // can't place in stable dead pet
455 if ((pet && (!pet->IsAlive() || pet->getPetType() != HUNTER_PET))
456 || (!pet && (petStable->UnslottedPets.size() != 1 || !petStable->UnslottedPets[0].Health || petStable->UnslottedPets[0].Type != HUNTER_PET)))
457 {
459 return;
460 }
461
462 for (uint32 freeSlot = 0; freeSlot < petStable->MaxStabledPets; ++freeSlot)
463 {
464 if (!petStable->StabledPets[freeSlot])
465 {
466 if (pet)
467 {
468 // stable summoned pet
470 std::swap(petStable->StabledPets[freeSlot], petStable->CurrentPet);
472 return;
473 }
474
476 stmt->SetData(0, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + freeSlot));
477 stmt->SetData(1, _player->GetGUID().GetCounter());
478 stmt->SetData(2, petStable->UnslottedPets[0].PetNumber);
479 CharacterDatabase.Execute(stmt);
480
481 // stable unsummoned pet
482 petStable->StabledPets[freeSlot] = std::move(petStable->UnslottedPets.back());
483 petStable->UnslottedPets.pop_back();
485 return;
486 }
487 }
488
489 // not free stable slot
491}
@ CHAR_UPD_CHAR_PET_SLOT_BY_ID
Definition CharacterDatabase.h:495
@ STABLE_SUCCESS_STABLE
Definition NPCHandler.cpp:42
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)
642{
643 LOG_DEBUG("network", "HandleStableRevivePet: Not implemented");
644}

References LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleStableSwapPet()

void WorldSession::HandleStableSwapPet ( WorldPacket &  recvPacket)
647{
648 LOG_DEBUG("network", "WORLD: Recv CMSG_STABLE_SWAP_PET.");
649 ObjectGuid npcGUID;
650 uint32 petId;
651
652 recvData >> npcGUID >> petId;
653
654 if (!CheckStableMaster(npcGUID))
655 {
657 return;
658 }
659
660 // remove fake death
661 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
663
664 PetStable* petStable = GetPlayer()->GetPetStable();
665 if (!petStable)
666 {
668 return;
669 }
670
671 // Find swapped pet slot in stable
672 auto stabledPet = std::find_if(petStable->StabledPets.begin(), petStable->StabledPets.end(), [petId](Optional<PetStable::PetInfo> const& pet)
673 {
674 return pet && pet->PetNumber == petId;
675 });
676
677 if (stabledPet == petStable->StabledPets.end())
678 {
680 return;
681 }
682
683 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate((*stabledPet)->CreatureId);
684 if (!creatureInfo || !creatureInfo->IsTameable(_player->CanTameExoticPets()))
685 {
686 // if problem in exotic pet
687 if (creatureInfo && creatureInfo->IsTameable(true))
689 else
691 return;
692 }
693
694 Pet* oldPet = _player->GetPet();
695 if (oldPet)
696 {
697 if (!oldPet->IsAlive() || !oldPet->IsHunterPet())
698 {
700 return;
701 }
702
703 _player->RemovePet(oldPet, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + std::distance(petStable->StabledPets.begin(), stabledPet)));
704 }
705 else if (petStable->UnslottedPets.size() == 1)
706 {
707 if (petStable->CurrentPet || !petStable->UnslottedPets[0].Health || petStable->UnslottedPets[0].Type != HUNTER_PET)
708 {
710 return;
711 }
712
714 stmt->SetData(0, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + std::distance(petStable->StabledPets.begin(), stabledPet)));
715 stmt->SetData(1, _player->GetGUID().GetCounter());
716 stmt->SetData(2, petStable->UnslottedPets[0].PetNumber);
717 CharacterDatabase.Execute(stmt);
718
719 // move unsummoned pet into CurrentPet slot so that it gets moved into stable slot later
720 petStable->CurrentPet = std::move(petStable->UnslottedPets.back());
721 petStable->UnslottedPets.pop_back();
722 }
723 else if (petStable->CurrentPet || !petStable->UnslottedPets.empty())
724 {
726 return;
727 }
728
729 // summon unstabled pet
730 Pet* newPet = new Pet(_player, HUNTER_PET);
731 if (!newPet->LoadPetFromDB(_player, 0, petId, false))
732 {
733 delete newPet;
735
736 petStable->UnslottedPets.push_back(std::move(*petStable->CurrentPet));
737 petStable->CurrentPet.reset();
738
739 // update current pet slot in db immediately to maintain slot consistency, dismissed pet was already saved
742 stmt->SetData(1, _player->GetGUID().GetCounter());
743 stmt->SetData(2, petId);
744 CharacterDatabase.Execute(stmt);
745 }
746 else
747 {
748 // update current pet slot in db immediately to maintain slot consistency, dismissed pet was already saved
751 stmt->SetData(1, _player->GetGUID().GetCounter());
752 stmt->SetData(2, petId);
753 CharacterDatabase.Execute(stmt);
754
756 }
757}
@ STABLE_ERR_EXOTIC
Definition NPCHandler.cpp:45
@ STABLE_SUCCESS_UNSTABLE
Definition NPCHandler.cpp:43
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:2220
bool IsHunterPet() const
Definition Unit.h:799
bool IsTameable(bool exotic) const
Definition CreatureData.h:269

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)
561{
562 uint32 animstate;
563 recv_data >> animstate;
564
565 switch (animstate)
566 {
571 break;
572 default:
573 return;
574 }
575
576 _player->SetStandState(animstate);
577}
@ UNIT_STAND_STATE_SLEEP
Definition UnitDefines.h:38
@ UNIT_STAND_STATE_KNEEL
Definition UnitDefines.h:43

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)
871{
872 if (!_player->IsAlive() || _player->IsInCombat())
873 return;
874
875 ObjectGuid summoner_guid;
876 bool agree;
877 recvData >> summoner_guid;
878 recvData >> agree;
879
880 if (agree && _player->IsSummonAsSpectator())
881 {
882 ChatHandler chc(this);
883 if (Player* summoner = ObjectAccessor::FindPlayer(summoner_guid))
884 ArenaSpectator::HandleSpectatorSpectateCommand(&chc, summoner->GetName().c_str());
885 else
886 chc.PSendSysMessage("Requested player not found.");
887
888 agree = false;
889 }
891 _player->SummonIfPossible(agree, summoner_guid);
892}
void SetSummonAsSpectator(bool on)
Definition Player.h:1116
void SummonIfPossible(bool agree, ObjectGuid summoner_guid)
Definition Player.cpp:12703
bool IsSummonAsSpectator() const
Definition Player.cpp:16721
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)
49{
50 ObjectGuid guid;
51 recvData >> guid;
52
54 if (!unit)
55 {
56 LOG_DEBUG("network", "WORLD: HandleTabardVendorActivateOpcode - Unit ({}) not found or you can not interact with him.", guid.ToString());
57 return;
58 }
59
60 // remove fake death
61 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
63
65}
void SendTabardVendorActivate(ObjectGuid guid)
Definition NPCHandler.cpp:67

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
71 if (!unit->CanResetTalents(_player))
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:326
bool CanResetTalents(Player *player) const
Definition Creature.cpp:1301
@ MSG_TALENT_WIPE_CONFIRM
Definition Opcodes.h:712

References _player, Creature::CanResetTalents(), Unit::CastSpell(), Player::GetNPCIfCanInteractWith(), GetPlayer(), 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)
61{
62 ObjectGuid guid;
63 recvData >> guid;
64
65 // cheating checks
67 if (!unit)
68 {
69 LOG_DEBUG("network", "WORLD: HandleTaxiQueryAvailableNodes - Unit ({}) not found or you can't interact with him.", guid.ToString());
70 return;
71 }
72
73 // remove fake death
74 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
76
77 // unknown taxi node case
78 if (SendLearnNewTaxiNode(unit))
79 return;
80
81 // known taxi node case
82 SendTaxiMenu(unit);
83}
bool SendLearnNewTaxiNode(Creature *unit)
Definition TaxiHandler.cpp:128
void SendTaxiMenu(Creature *unit)
Definition TaxiHandler.cpp:85

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().

◆ HandleTC9PrepareForRedirect()

void WorldSession::HandleTC9PrepareForRedirect ( WorldPacket &  recvData)
1611{
1612 if (!sToCloud9Sidecar->ClusterModeEnabled())
1613 return;
1614
1615 Player* player = this->GetPlayer();
1616 if (player == nullptr)
1617 {
1619 data << uint8(1); // 1 - Failed.
1620 SendPacket(&data);
1621 return;
1622 }
1623
1624 LOG_DEBUG("network", "Starting saving, AccountId = {}", GetAccountId());
1625
1626 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
1627 player->SaveToDB(trans, false, true);
1628 AddTransactionCallback(CharacterDatabase.AsyncCommitTransaction(trans)).AfterComplete([this](bool success)
1629 {
1631 data << uint8(!success); // 0 - Success, 1 - Failed.
1632 SendPacket(&data);
1633
1634 if (!success)
1635 {
1636 LOG_ERROR("network", "Failed to save player, AccountId = {}", GetAccountId());
1637 return;
1638 }
1639
1640 LOG_DEBUG("network", "Saved, AccountId = {}", GetAccountId());
1641
1642 Player* player = GetPlayer();
1643 if (!player)
1644 return;
1645
1646 player->m_Events.AddEventAtOffset([this](){
1647 KickPlayer("HandlePrepareForRedirect client redirected");
1648 }, 100ms);
1649 });
1650}
void SaveToDB(bool create, bool logout)
Definition PlayerStorage.cpp:7231
@ TC9_SMSG_READY_FOR_REDIRECT
Definition Opcodes.h:1342

References EventProcessor::AddEventAtOffset(), AddTransactionCallback(), TransactionCallback::AfterComplete(), CharacterDatabase, GetAccountId(), GetPlayer(), KickPlayer(), LOG_DEBUG, LOG_ERROR, WorldObject::m_Events, Player::SaveToDB(), SendPacket(), sToCloud9Sidecar, and TC9_SMSG_READY_FOR_REDIRECT.

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

◆ HandleTextEmoteOpcode()

void WorldSession::HandleTextEmoteOpcode ( WorldPacket &  recvPacket)
715{
716 uint32 text_emote;
717 recvData >> text_emote;
718
719 constexpr uint32 readyEmote = 126;
720
721 // Handle confirmation redirect when the player types "/ready" after the new node becomes available for redirection.
722 if (text_emote == readyEmote && GetPlayer()->GetMap()->IsPlayerRedirectKickTimerActive())
723 {
725 return;
726 }
727
728 if (!GetPlayer()->IsAlive())
729 return;
730
732
733 if (!GetPlayer()->CanSpeak())
734 {
735 std::string timeStr = secsToTimeString(m_muteTime - GameTime::GetGameTime().count());
737 return;
738 }
739
740 if (GetPlayer()->IsSpectator())
741 return;
742
743 uint32 emoteNum;
744 ObjectGuid guid;
745
746 recvData >> emoteNum;
747 recvData >> guid;
748
749 sScriptMgr->OnPlayerTextEmote(GetPlayer(), text_emote, emoteNum, guid);
750
751 EmotesTextEntry const* em = sEmotesTextStore.LookupEntry(text_emote);
752 if (!em)
753 return;
754
755 uint32 emote_anim = em->textid;
756
757 switch (emote_anim)
758 {
760 case EMOTE_STATE_SIT:
763 break;
766 break;
767 default:
768 // Only allow text-emotes for "dead" entities (feign death included)
769 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
770 break;
771 GetPlayer()->HandleEmoteCommand(emote_anim);
772 break;
773 }
774
775 Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
776
777 Acore::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit);
780 Cell::VisitObjects(GetPlayer(), emote_worker, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
781
783
784 //Send scripted event call
785 if (unit && unit->IsCreature() && ((Creature*)unit)->AI())
786 ((Creature*)unit)->AI()->ReceiveEmote(GetPlayer(), text_emote);
787}
@ ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE
Definition DBCEnums.h:168
DBCStorage< EmotesTextEntry > sEmotesTextStore(EmotesTextEntryfmt)
@ EMOTE_STATE_SLEEP
Definition SharedDefines.h:1908
@ EMOTE_STATE_SIT
Definition SharedDefines.h:1909
@ EMOTE_STATE_KNEEL
Definition SharedDefines.h:1947
@ EMOTE_STATE_DANCE
Definition SharedDefines.h:1906
@ UNIT_NPC_EMOTESTATE
Definition UpdateFields.h:140
@ CONFIG_LISTEN_RANGE_TEXTEMOTE
Definition WorldConfig.h:157
Definition ChatHandler.cpp:685
Definition GridNotifiers.h:1769
void HandleTC9PrepareForRedirect(WorldPacket &recvData)
Definition WorldSession.cpp:1610
Definition GridNotifiers.h:615
static void VisitObjects(WorldObject const *obj, T &visitor, float radius)
Definition CellImpl.h:165
Definition DBCStructure.h:928
uint32 textid
Definition DBCStructure.h:930
@ REGULAR
Definition Player.h:2365

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(), HandleTC9PrepareForRedirect(), 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)
927{
928 LOG_DEBUG("network", "CMSG_TIME_SYNC_RESP");
929
930 uint32 counter, clientTimestamp;
931 recvData >> counter >> clientTimestamp;
932
933 if (_pendingTimeSyncRequests.count(counter) == 0)
934 return;
935
936 uint32 serverTimeAtSent = _pendingTimeSyncRequests.at(counter);
937 _pendingTimeSyncRequests.erase(counter);
938
939 // 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.
940 // we are going to make 2 assumptions:
941 // 1) we assume that the request processing time equals 0.
942 // 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.
943 uint32 roundTripDuration = getMSTimeDiff(serverTimeAtSent, recvData.GetReceivedTime());
944 uint32 lagDelay = roundTripDuration / 2;
945
946 // clockDelta = serverTime - clientTime
947 // where
948 // serverTime: time that was displayed on the clock of the SERVER at the moment when the client processed the SMSG_TIME_SYNC_REQUEST packet.
949 // clientTime: time that was displayed on the clock of the CLIENT at the moment when the client processed the SMSG_TIME_SYNC_REQUEST packet.
950
951 // 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,
952 // using the following relation:
953 // serverTime = clockDelta + clientTime
954
955 int64 clockDelta = (int64)serverTimeAtSent + (int64)lagDelay - (int64)clientTimestamp;
956 _timeSyncClockDeltaQueue.put(std::pair<int64, uint32>(clockDelta, roundTripDuration));
958}
void put(T item)
Definition CircularBuffer.h:27
TimePoint GetReceivedTime() const
Definition WorldPacket.h:78
void ComputeNewClockDelta()
Definition MovementHandler.cpp:960

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

Referenced by OpcodeTable::Initialize().

◆ HandleTogglePvP()

void WorldSession::HandleTogglePvP ( WorldPacket &  recvPacket)
501{
502 // this opcode can be used in two ways: Either set explicit new status or toggle old status
503 if (recv_data.size() == 1)
504 {
505 bool newPvPStatus;
506 recv_data >> newPvPStatus;
508 }
509 else
511
512 if (GetPlayer()->HasPlayerFlag(PLAYER_FLAGS_IN_PVP))
513 GetPlayer()->UpdatePvP(true, true);
514 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
515 GetPlayer()->UpdatePvP(true, false);
516
517 //if (OutdoorPvP* pvp = _player->GetOutdoorPvP())
518 // pvp->HandlePlayerActivityChanged(_player);
519}
@ PLAYER_FLAGS
Definition UpdateFields.h:178
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition Object.cpp:890
void ToggleFlag(uint16 index, uint32 flag)
Definition Object.cpp:868

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)
687{
688 // ignore for remote control state
689 if (_player->m_mover != _player)
690 return;
691
692 uint8 slotId = totemDestroyed.Slot;
693 slotId += SUMMON_SLOT_TOTEM_FIRE;
694
695 if (slotId >= MAX_TOTEM_SLOT)
696 return;
697
698 if (!_player->m_SummonSlot[slotId])
699 return;
700
701 Creature* totem = GetPlayer()->GetMap()->GetCreature(_player->m_SummonSlot[slotId]);
702 // Don't unsummon sentry totem
703 if (totem && totem->IsTotem())
704 totem->ToTotem()->UnSummon();
705}
#define MAX_TOTEM_SLOT
Definition SharedDefines.h:3555
@ SUMMON_SLOT_TOTEM_FIRE
Definition SharedDefines.h:3545
void UnSummon(Milliseconds msTime=0ms) override
Definition Totem.cpp:130
Totem * ToTotem()
Definition Unit.h:731
bool IsTotem() const
Definition Unit.h:800
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition Unit.h:2083
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 ( WorldPackets::NPC::TrainerBuySpell &  packet)
118{
119 LOG_DEBUG("network", "WORLD: Received CMSG_TRAINER_BUY_SPELL {}, learn spell id is: {}", packet.TrainerGUID.ToString().c_str(), packet.SpellID);
120
122 if (!npc)
123 {
124 LOG_DEBUG("network", "WORLD: HandleTrainerBuySpellOpcode - {} not found or you can not interact with him.", packet.TrainerGUID.ToString().c_str());
125 return;
126 }
127
128 // remove fake death
129 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
131
132 Trainer::Trainer* trainer = sObjectMgr->GetTrainer(npc->GetEntry());
133 if (!trainer)
134 return;
135
136 trainer->TeachSpell(npc, _player, packet.SpellID);
137}
Definition Trainer.h:66
void TeachSpell(Creature *npc, Player *player, uint32 spellId)
Definition Trainer.cpp:83
ObjectGuid TrainerGUID
Definition NPCPackets.h:75
int32 SpellID
Definition NPCPackets.h:76

References _player, Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, Unit::RemoveAurasByType(), sObjectMgr, SPELL_AURA_FEIGN_DEATH, WorldPackets::NPC::TrainerBuySpell::SpellID, Trainer::Trainer::TeachSpell(), ObjectGuid::ToString(), WorldPackets::NPC::TrainerBuySpell::TrainerGUID, UNIT_NPC_FLAG_TRAINER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleTrainerListOpcode()

void WorldSession::HandleTrainerListOpcode ( WorldPackets::NPC::Hello &  packet)
82{
84 if (!npc)
85 {
86 LOG_DEBUG("network", "WorldSession: SendTrainerList - {} not found or you can not interact with him.", packet.Unit.ToString().c_str());
87 return;
88 }
89
91}
ObjectGuid Unit
Definition NPCPackets.h:40
void SendTrainerList(Creature *npc)
Definition NPCHandler.cpp:93

References Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, SendTrainerList(), ObjectGuid::ToString(), WorldPackets::NPC::Hello::Unit, and UNIT_NPC_FLAG_TRAINER.

Referenced by OpcodeTable::Initialize().

◆ HandleTurnInPetitionOpcode()

void WorldSession::HandleTurnInPetitionOpcode ( WorldPacket &  recvData)
660{
661 LOG_DEBUG("network", "Received opcode CMSG_TURN_IN_PETITION");
662
663 // Get petition guid from packet
664 WorldPacket data;
665 ObjectGuid petitionGuid;
666
667 recvData >> petitionGuid;
668
669 // Check if player really has the required petition charter
670 Item* item = _player->GetItemByGuid(petitionGuid);
671 if (!item)
672 return;
673
674 LOG_DEBUG("network", "Petition {} turned in by {}", petitionGuid.ToString(), _player->GetGUID().ToString());
675
676 Petition const* petition = sPetitionMgr->GetPetition(petitionGuid);
677 if (!petition)
678 {
679 LOG_ERROR("network.opcode", "Player {} ({}) tried to turn in petition ({}) that is not present in the database",
680 _player->GetName(), _player->GetGUID().ToString(), petitionGuid.ToString());
681 return;
682 }
683
684 ObjectGuid ownerGuid = petition->ownerGuid;
685 uint8 type = petition->petitionType;
686 std::string name = petition->petitionName;
687
688 // Only the petition owner can turn in the petition
689 if (_player->GetGUID() != ownerGuid)
690 return;
691
692 // Petition type (guild/arena) specific checks
693 if (type == GUILD_CHARTER_TYPE)
694 {
696 {
698 return;
699 }
700
701 // Check if player is already in a guild
702 if (_player->GetGuildId())
703 {
706 SendPacket(&data);
707 return;
708 }
709
710 // Check if guild name is already taken
711 if (sGuildMgr->GetGuildByName(name))
712 {
714 return;
715 }
716 }
717 else
718 {
719 // Check for valid arena bracket (2v2, 3v3, 5v5)
720 uint8 slot = ArenaTeam::GetSlotByType(type);
721 if (slot >= MAX_ARENA_SLOT)
722 return;
723
724 // Check if player is already in an arena team
725 if (_player->GetArenaTeamId(slot))
726 {
728 return;
729 }
730
731 // Check if arena team name is already taken
732 if (sArenaTeamMgr->GetArenaTeamByName(name))
733 {
735 return;
736 }
737 }
738
739 // Get petition signatures from db
740 Signatures const* signatures = sPetitionMgr->GetSignature(petitionGuid);
741 uint8 signs = signatures ? signatures->signatureMap.size() : 0;
742 SignatureMap signatureCopy;
743 if (signs)
744 signatureCopy = signatures->signatureMap;
745
746 uint32 requiredSignatures;
747 if (type == GUILD_CHARTER_TYPE)
748 requiredSignatures = sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS);
749 else
750 requiredSignatures = type - 1;
751
752 // Notify player if signatures are missing
753 if (signs < requiredSignatures)
754 {
757 SendPacket(&data);
758 return;
759 }
760
761 // Proceed with guild/arena team creation
762
763 // Delete charter item
764 _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
765
766 if (type == GUILD_CHARTER_TYPE)
767 {
768 // Create guild
769 Guild* guild = new Guild;
770
771 if (!guild->Create(_player, name))
772 {
773 delete guild;
774 return;
775 }
776
777 // Register guild and add guild master
778 sGuildMgr->AddGuild(guild);
779
781
782 // Add members from signatures
783 if (signs)
784 for (SignatureMap::const_iterator itr = signatureCopy.begin(); itr != signatureCopy.end(); ++itr)
785 guild->AddMember(itr->first);
786 }
787 else
788 {
789 // Receive the rest of the packet in arena team creation case
790 uint32 background, icon, iconcolor, border, bordercolor;
791 recvData >> background >> icon >> iconcolor >> border >> bordercolor;
792
793 // Create arena team
794 ArenaTeam* arenaTeam = new ArenaTeam();
795
796 if (!arenaTeam->Create(_player->GetGUID(), type, name, background, icon, iconcolor, border, bordercolor))
797 {
798 delete arenaTeam;
799 return;
800 }
801
802 // Register arena team
803 sArenaTeamMgr->AddArenaTeam(arenaTeam);
804 LOG_DEBUG("network", "PetitonsHandler: Arena team (guid: {}) added to ObjectMgr", arenaTeam->GetId());
805
806 // Add members
807 if (signs)
808 for (SignatureMap::const_iterator itr = signatureCopy.begin(); itr != signatureCopy.end(); ++itr)
809 {
810 LOG_DEBUG("network", "PetitionsHandler: Adding arena team (guid: {}) member {}", arenaTeam->GetId(), itr->first.ToString());
811 arenaTeam->AddMember(itr->first);
812 }
813 }
814
815 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
816
818 stmt->SetData(0, petition->petitionId);
819 trans->Append(stmt);
820
821 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_SIGNATURE_BY_ID);
822 stmt->SetData(0, petition->petitionId);
823 trans->Append(stmt);
824
825 CharacterDatabase.CommitTransaction(trans);
826
827 // xinef: clear petition store (petition and signatures)
828 sPetitionMgr->RemovePetition(petitionGuid);
829
830 // created
831 LOG_DEBUG("network", "TURN IN PETITION {}", petitionGuid.ToString());
832
834 data << (uint32)PETITION_TURN_OK;
835 SendPacket(&data);
836}
@ CHAR_DEL_PETITION_BY_ID
Definition CharacterDatabase.h:390
@ CHAR_DEL_PETITION_SIGNATURE_BY_ID
Definition CharacterDatabase.h:391
@ 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:211
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:1057
bool AddMember(ObjectGuid guid, uint8 rankId=GUILD_RANK_NONE)
Definition Guild.cpp:2230
@ 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, CONFIG_TRIAL_RESTRICTION_GUILD, 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, ERR_GUILD_PERMISSIONS, 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(), IsTrialAccount(), 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)
1317{
1318 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
1319 SetTutorialInt(i, 0xFFFFFFFF);
1320}
#define MAX_ACCOUNT_TUTORIAL_VALUES
Definition Common.h:142
void SetTutorialInt(uint8 index, uint32 value)
Definition WorldSession.h:608

References MAX_ACCOUNT_TUTORIAL_VALUES, and SetTutorialInt().

Referenced by OpcodeTable::Initialize().

◆ HandleTutorialFlag()

void WorldSession::HandleTutorialFlag ( WorldPacket &  recvData)
1301{
1302 uint32 data;
1303 recvData >> data;
1304
1305 uint8 index = uint8(data / 32);
1306 if (index >= MAX_ACCOUNT_TUTORIAL_VALUES)
1307 return;
1308
1309 uint32 value = (data % 32);
1310
1311 uint32 flag = GetTutorialInt(index);
1312 flag |= (1 << value);
1313 SetTutorialInt(index, flag);
1314}
uint32 GetTutorialInt(uint8 index) const
Definition WorldSession.h:607

References GetTutorialInt(), MAX_ACCOUNT_TUTORIAL_VALUES, and SetTutorialInt().

Referenced by OpcodeTable::Initialize().

◆ HandleTutorialReset()

void WorldSession::HandleTutorialReset ( WorldPacket &  recvData)
1323{
1324 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
1325 SetTutorialInt(i, 0x00000000);
1326}

References MAX_ACCOUNT_TUTORIAL_VALUES, and SetTutorialInt().

Referenced by OpcodeTable::Initialize().

◆ HandleUnacceptTradeOpcode()

void WorldSession::HandleUnacceptTradeOpcode ( WorldPacket &  recvPacket)
684{
685 TradeData* my_trade = _player->GetTradeData();
686 if (!my_trade)
687 return;
688
689 my_trade->SetAccepted(false, true);
690}

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:38
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition Player.cpp:5496

References GetPlayer(), IsPrimaryProfessionSkill(), and Player::SetSkill().

Referenced by OpcodeTable::Initialize().

◆ HandleUnstablePet()

void WorldSession::HandleUnstablePet ( WorldPacket &  recvPacket)
494{
495 LOG_DEBUG("network", "WORLD: Recv CMSG_UNSTABLE_PET.");
496 ObjectGuid npcGUID;
497 uint32 petnumber;
498
499 recvData >> npcGUID >> petnumber;
500
501 if (!CheckStableMaster(npcGUID))
502 {
504 return;
505 }
506
507 // remove fake death
508 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
510
511 PetStable* petStable = GetPlayer()->GetPetStable();
512 if (!petStable)
513 {
515 return;
516 }
517
518 auto stabledPet = std::find_if(petStable->StabledPets.begin(), petStable->StabledPets.end(), [petnumber](Optional<PetStable::PetInfo> const& pet)
519 {
520 return pet && pet->PetNumber == petnumber;
521 });
522
523 if (stabledPet == petStable->StabledPets.end())
524 {
526 return;
527 }
528
529 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate((*stabledPet)->CreatureId);
530 if (!creatureInfo || !creatureInfo->IsTameable(_player->CanTameExoticPets()))
531 {
532 // if problem in exotic pet
533 if (creatureInfo && creatureInfo->IsTameable(true))
535 else
537
538 return;
539 }
540
541 Pet* oldPet = _player->GetPet();
542 if (oldPet)
543 {
544 // try performing a swap, client sends this packet instead of swap when starting from stabled slot
545 if (!oldPet->IsAlive() || !oldPet->IsHunterPet())
546 {
548 return;
549 }
550
551 _player->RemovePet(oldPet, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + std::distance(petStable->StabledPets.begin(), stabledPet)));
552 }
553 else if (petStable->UnslottedPets.size() == 1)
554 {
555 if (petStable->CurrentPet || !petStable->UnslottedPets[0].Health || petStable->UnslottedPets[0].Type != HUNTER_PET)
556 {
558 return;
559 }
560
562 stmt->SetData(0, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + std::distance(petStable->StabledPets.begin(), stabledPet)));
563 stmt->SetData(1, _player->GetGUID().GetCounter());
564 stmt->SetData(2, petStable->UnslottedPets[0].PetNumber);
565 CharacterDatabase.Execute(stmt);
566
567 // move unsummoned pet into CurrentPet slot so that it gets moved into stable slot later
568 petStable->CurrentPet = std::move(petStable->UnslottedPets.back());
569 petStable->UnslottedPets.pop_back();
570 }
571 else if (petStable->CurrentPet || !petStable->UnslottedPets.empty())
572 {
574 return;
575 }
576
577 Pet* newPet = new Pet(_player, HUNTER_PET);
578 if (!newPet->LoadPetFromDB(_player, 0, petnumber, false))
579 {
580 delete newPet;
581
582 petStable->UnslottedPets.push_back(std::move(*petStable->CurrentPet));
583 petStable->CurrentPet.reset();
584
585 // update current pet slot in db immediately to maintain slot consistency, dismissed pet was already saved
588 stmt->SetData(1, _player->GetGUID().GetCounter());
589 stmt->SetData(2, petnumber);
590 CharacterDatabase.Execute(stmt);
591
593 }
594 else
595 {
596 // update current pet slot in db immediately to maintain slot consistency, dismissed pet was already saved
599 stmt->SetData(1, _player->GetGUID().GetCounter());
600 stmt->SetData(2, petnumber);
601 CharacterDatabase.Execute(stmt);
602
604 }
605}

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)
811{
812 uint32 type, timestamp, decompressedSize;
813 recv_data >> type >> timestamp >> decompressedSize;
814
815 LOG_DEBUG("network", "UAD: type {}, time {}, decompressedSize {}", type, timestamp, decompressedSize);
816
817 if (type >= NUM_ACCOUNT_DATA_TYPES)
818 return;
819
820 if (decompressedSize == 0) // erase
821 {
822 SetAccountData(AccountDataType(type), 0, "");
823
825 data << uint32(type);
826 data << uint32(0);
827 SendPacket(&data);
828
829 return;
830 }
831
832 if (decompressedSize > 0xFFFF)
833 {
834 recv_data.rfinish(); // unnneded warning spam in this case
835 LOG_ERROR("network.opcode", "UAD: Account data packet too big, size {}", decompressedSize);
836 return;
837 }
838
839 ByteBuffer dest;
840 dest.resize(decompressedSize);
841
842 uLongf realSize = decompressedSize;
843 if (uncompress(dest.contents(), &realSize, recv_data.contents() + recv_data.rpos(), recv_data.size() - recv_data.rpos()) != Z_OK)
844 {
845 recv_data.rfinish(); // unnneded warning spam in this case
846 LOG_ERROR("network.opcode", "UAD: Failed to decompress account data");
847 return;
848 }
849
850 recv_data.rfinish(); // uncompress read (recv_data.size() - recv_data.rpos())
851
852 std::string adata;
853 dest >> adata;
854
855 SetAccountData(AccountDataType(type), timestamp, adata);
856
858 data << uint32(type);
859 data << uint32(0);
860 SendPacket(&data);
861}
void SetAccountData(AccountDataType type, time_t tm, std::string const &data)
Definition WorldSession.cpp:1005
@ 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)
1725{
1726 LOG_DEBUG("network", "WORLD: CMSG_UPDATE_MISSILE_TRAJECTORY");
1727
1728 ObjectGuid guid;
1729 uint32 spellId;
1730 float elevation, speed;
1731 float curX, curY, curZ;
1732 float targetX, targetY, targetZ;
1733 uint8 moveStop;
1734
1735 recvPacket >> guid >> spellId >> elevation >> speed;
1736 recvPacket >> curX >> curY >> curZ;
1737 recvPacket >> targetX >> targetY >> targetZ;
1738 recvPacket >> moveStop;
1739
1740 Unit* caster = ObjectAccessor::GetUnit(*_player, guid);
1741 Spell* spell = caster ? caster->GetCurrentSpell(CURRENT_GENERIC_SPELL) : nullptr;
1742 if (!spell || spell->m_spellInfo->Id != spellId || !spell->m_targets.HasDst() || !spell->m_targets.HasSrc())
1743 {
1744 recvPacket.rfinish();
1745 return;
1746 }
1747
1748 Position pos = *spell->m_targets.GetSrcPos();
1749 pos.Relocate(curX, curY, curZ);
1750 spell->m_targets.ModSrc(pos);
1751
1752 pos = *spell->m_targets.GetDstPos();
1753 pos.Relocate(targetX, targetY, targetZ);
1754 spell->m_targets.ModDst(pos);
1755
1756 spell->m_targets.SetElevation(elevation);
1757 spell->m_targets.SetSpeed(speed);
1758
1759 if (moveStop)
1760 {
1761 uint32 opcode;
1762 recvPacket >> opcode;
1763 recvPacket.SetOpcode(opcode);
1764 HandleMovementOpcodes(recvPacket);
1765 }
1766}
@ CURRENT_GENERIC_SPELL
Definition Unit.h:557
void ModDst(Position const &pos)
Definition Spell.cpp:473
bool HasSrc() const
Definition Spell.h:176
bool HasDst() const
Definition Spell.h:177
void ModSrc(Position const &pos)
Definition Spell.cpp:422
Position const * GetSrcPos() const
Definition Spell.cpp:399
WorldLocation const * GetDstPos() const
Definition Spell.cpp:438

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)
835{
836 LOG_DEBUG("network", "WORLD: CMSG_UPDATE_PROJECTILE_POSITION");
837
838 ObjectGuid casterGuid;
839 uint32 spellId;
840 uint8 castCount;
841 float x, y, z; // Position of missile hit
842
843 recvPacket >> casterGuid;
844 recvPacket >> spellId;
845 recvPacket >> castCount;
846 recvPacket >> x;
847 recvPacket >> y;
848 recvPacket >> z;
849
850 Unit* caster = ObjectAccessor::GetUnit(*_player, casterGuid);
851 if (!caster)
852 return;
853
854 Spell* spell = caster->FindCurrentSpellBySpellId(spellId);
855 if (!spell || !spell->m_targets.HasDst())
856 return;
857
858 Position pos = *spell->m_targets.GetDstPos();
859 pos.Relocate(x, y, z);
860 spell->m_targets.ModDst(pos);
861
862 // we changed dest, recalculate flight time
864
866 data << casterGuid;
867 data << uint8(castCount);
868 data << float(x);
869 data << float(y);
870 data << float(z);
871 caster->SendMessageToSet(&data, true);
872}
void RecalculateDelayMomentForDst()
Definition Spell.cpp:970
Spell * FindCurrentSpellBySpellId(uint32 spell_id) const
Definition Unit.cpp:4071
@ 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:1270
void CastItemUseSpell(Item *item, SpellCastTargets const &targets, uint8 cast_count, uint32 glyphIndex)
Definition Player.cpp:7586
bool CanBeUsedInCombat() const
Definition SpellInfo.cpp:1277

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)
321{
322 if (!_warden || recvData.empty())
323 return;
324
325 _warden->DecryptData(recvData.contents(), recvData.size());
326 uint8 opcode;
327 recvData >> opcode;
328 LOG_DEBUG("warden", "Got packet, opcode {:02X}, size {}", opcode, uint32(recvData.size()));
329 recvData.hexlike();
330
331 switch (opcode)
332 {
334 _warden->SendModuleToClient();
335 break;
337 _warden->RequestHash();
338 break;
340 _warden->HandleData(recvData);
341 break;
343 LOG_DEBUG("warden", "NYI WARDEN_CMSG_MEM_CHECKS_RESULT received!");
344 break;
346 _warden->HandleHashResult(recvData);
347 _warden->InitializeModule();
348 break;
350 LOG_DEBUG("warden", "NYI WARDEN_CMSG_MODULE_FAILED received!");
351 break;
352 default:
353 LOG_DEBUG("warden", "Got unknown warden opcode {:02X} of size {}.", opcode, uint32(recvData.size() - 1));
354 break;
355 }
356}
@ 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)
1082{
1083 LOG_DEBUG("network", "Received opcode CMSG_WHOIS");
1084 std::string charname;
1085 recv_data >> charname;
1086
1088 {
1090 return;
1091 }
1092
1093 if (charname.empty() || !normalizePlayerName (charname))
1094 {
1096 return;
1097 }
1098
1099 Player* player = ObjectAccessor::FindPlayerByName(charname, false);
1100
1101 if (!player)
1102 {
1104 return;
1105 }
1106
1107 uint32 accid = player->GetSession()->GetAccountId();
1108
1110
1111 stmt->SetData(0, accid);
1112
1113 PreparedQueryResult result = LoginDatabase.Query(stmt);
1114
1115 if (!result)
1116 {
1118 return;
1119 }
1120
1121 Field* fields = result->Fetch();
1122 std::string acc = fields[0].Get<std::string>();
1123 if (acc.empty())
1124 acc = "Unknown";
1125 std::string email = fields[1].Get<std::string>();
1126 if (email.empty())
1127 email = "Unknown";
1128 std::string lastip = fields[2].Get<std::string>();
1129 if (lastip.empty())
1130 lastip = "Unknown";
1131
1132 std::string msg = charname + "'s " + "account is " + acc + ", e-mail: " + email + ", last ip: " + lastip;
1133
1134 WorldPacket data(SMSG_WHOIS, msg.size() + 1);
1135 data << msg;
1136 SendPacket(&data);
1137
1138 LOG_DEBUG("network", "Received whois command from player {} for character {}", GetPlayer()->GetName(), charname);
1139}
@ LANG_PLAYER_NOT_EXIST_OR_OFFLINE
Definition Language.h:756
@ LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND
Definition Language.h:757
@ LANG_PERMISSION_DENIED
Definition Language.h:752
@ LANG_NEED_CHARACTER_NAME
Definition Language.h:755
@ LOGIN_SEL_ACCOUNT_WHOIS
Definition LoginDatabase.h:100
@ SMSG_WHOIS
Definition Opcodes.h:131
@ RBAC_PERM_OPCODE_WHOIS
Definition RBAC.h:94

References ObjectAccessor::FindPlayerByName(), Field::Get(), GetAccountId(), GetPlayer(), Player::GetSession(), HasPermission(), 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(), rbac::RBAC_PERM_OPCODE_WHOIS, ChatHandler::SendNotification(), SendPacket(), PreparedStatementBase::SetData(), and SMSG_WHOIS.

Referenced by OpcodeTable::Initialize().

◆ HandleWhoOpcode()

void WorldSession::HandleWhoOpcode ( WorldPacket &  recvPacket)
221{
222 LOG_DEBUG("network", "WORLD: Recvd CMSG_WHO Message");
223
224 uint32 matchCount = 0;
225
226 uint32 levelMin, levelMax, racemask, classmask, zonesCount, strCount;
227 std::array<uint32, 10> zoneids = {}; // 10 is client limit
228 std::string packetPlayerName, packetGuildName;
229
230 recvData >> levelMin; // maximal player level, default 0
231 recvData >> levelMax; // minimal player level, default 100 (MAX_LEVEL)
232 recvData >> packetPlayerName; // player name, case sensitive...
233
234 recvData >> packetGuildName; // guild name, case sensitive...
235
236 recvData >> racemask; // race mask
237 recvData >> classmask; // class mask
238 recvData >> zonesCount; // zones count, client limit = 10 (2.0.10)
239
240 if (zonesCount > 10)
241 return; // can't be received from real client or broken packet
242
243 for (uint32 i = 0; i < zonesCount; ++i)
244 {
245 uint32 temp;
246 recvData >> temp; // zone id, 0 if zone is unknown...
247 zoneids[i] = temp;
248 LOG_DEBUG("network.who", "Zone {}: {}", i, zoneids[i]);
249 }
250
251 recvData >> strCount; // user entered strings count, client limit=4 (checked on 2.0.10)
252
253 if (strCount > 4)
254 return; // can't be received from real client or broken packet
255
256 LOG_DEBUG("network.who", "Minlvl {}, maxlvl {}, name {}, guild {}, racemask {}, classmask {}, zones {}, strings {}",
257 levelMin, levelMax, packetPlayerName, packetGuildName, racemask, classmask, zonesCount, strCount);
258
259 std::wstring str[4]; // 4 is client limit
260 for (uint32 i = 0; i < strCount; ++i)
261 {
262 std::string temp;
263 recvData >> temp; // user entered string, it used as universal search pattern(guild+player name)?
264
265 if (!Utf8toWStr(temp, str[i]))
266 continue;
267
268 wstrToLower(str[i]);
269
270 LOG_DEBUG("network.who", "String {}: {}", i, temp);
271 }
272
273 std::wstring wpacketPlayerName;
274 std::wstring wpacketGuildName;
275 if (!(Utf8toWStr(packetPlayerName, wpacketPlayerName) && Utf8toWStr(packetGuildName, wpacketGuildName)))
276 return;
277
278 wstrToLower(wpacketPlayerName);
279 wstrToLower(wpacketGuildName);
280
281 // client send in case not set max level value 100 but Acore supports 255 max level,
282 // update it to show GMs with characters after 100 level
283 if (levelMax >= MAX_LEVEL)
284 levelMax = STRONG_MAX_LEVEL;
285
286 uint32 team = _player->GetTeamId();
287 uint32 gmLevelInWhoList = sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST);
288 uint32 displaycount = 0;
289
290 WorldPacket data(SMSG_WHO, 50); // guess size
291 data << uint32(matchCount); // placeholder, count of players matching criteria
292 data << uint32(displaycount); // placeholder, count of players displayed
293
294 for (auto const& target : sWhoListCacheMgr->GetWhoList())
295 {
296 if (target.GetTeamId() != team && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_WHO_LIST))
297 continue;
298
299 // player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if CONFIG_GM_IN_WHO_LIST
300 if (!HasPermission(rbac::RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) && target.GetSecurity() > AccountTypes(gmLevelInWhoList))
301 continue;
302
303 // check if target is globally visible for player
304 if ((_player->GetGUID() != target.GetGuid() && !target.IsVisible()) &&
306 {
307 continue;
308 }
309
310 // check if target's level is in level range
311 uint8 lvl = target.GetLevel();
312 if (lvl < levelMin || lvl > levelMax)
313 {
314 continue;
315 }
316
317 // check if class matches classmask
318 uint8 class_ = target.GetClass();
319 if (!(classmask & (1 << class_)))
320 {
321 continue;
322 }
323
324 // check if race matches racemask
325 uint32 race = target.GetRace();
326 if (!(racemask & (1 << race)))
327 {
328 continue;
329 }
330
331 uint32 playerZoneId = target.GetZoneId();
332 uint8 gender = target.GetGender();
333
334 bool showZones = true;
335 for (uint32 i = 0; i < zonesCount; ++i)
336 {
337 if (zoneids[i] == playerZoneId)
338 {
339 showZones = true;
340 break;
341 }
342
343 showZones = false;
344 }
345
346 if (!showZones)
347 {
348 continue;
349 }
350
351 std::wstring const& wideplayername = target.GetWidePlayerName();
352 if (!(wpacketPlayerName.empty() || wideplayername.find(wpacketPlayerName) != std::wstring::npos))
353 {
354 continue;
355 }
356
357 std::wstring const& wideguildname = target.GetWideGuildName();
358 if (!(wpacketGuildName.empty() || wideguildname.find(wpacketGuildName) != std::wstring::npos))
359 {
360 continue;
361 }
362
363 std::string aname;
364 if (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(playerZoneId))
365 {
366 aname = areaEntry->area_name[GetSessionDbcLocale()];
367 }
368
369 bool s_show = true;
370 for (uint32 i = 0; i < strCount; ++i)
371 {
372 if (!str[i].empty())
373 {
374 if (wideguildname.find(str[i]) != std::wstring::npos ||
375 wideplayername.find(str[i]) != std::wstring::npos ||
376 Utf8FitTo(aname, str[i]))
377 {
378 s_show = true;
379 break;
380 }
381
382 s_show = false;
383 }
384 }
385
386 if (!s_show)
387 {
388 continue;
389 }
390
391 // 49 is maximum player count sent to client - can be overridden
392 // through config, but is unstable
393 if ((matchCount++) >= sWorld->getIntConfig(CONFIG_MAX_WHO_LIST_RETURN))
394 {
395 continue;
396 }
397
398 data << target.GetPlayerName(); // player name
399 data << target.GetGuildName(); // guild name
400 data << uint32(lvl); // player level
401 data << uint32(class_); // player class
402 data << uint32(race); // player race
403 data << uint8(gender); // player gender
404 data << uint32(playerZoneId); // player zone id
405
406 ++displaycount;
407 }
408
409 data.put(0, displaycount); // insert right count, count displayed
410 data.put(4, matchCount); // insert right count, count of matches
411
412 SendPacket(&data);
413 LOG_DEBUG("network", "WORLD: Send SMSG_WHO Message");
414}
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_MAX_WHO_LIST_RETURN
Definition WorldConfig.h:371
@ CONFIG_GM_LEVEL_IN_WHO_LIST
Definition WorldConfig.h:217
@ SMSG_WHO
Definition Opcodes.h:129
@ RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS
Definition RBAC.h:86
@ RBAC_PERM_TWO_SIDE_WHO_LIST
Definition RBAC.h:79

References _player, CONFIG_GM_LEVEL_IN_WHO_LIST, CONFIG_MAX_WHO_LIST_RETURN, Object::GetGUID(), GetSecurity(), Player::GetSession(), GetSessionDbcLocale(), Player::GetTeamId(), HasPermission(), AccountMgr::IsPlayerAccount(), LOG_DEBUG, MAX_LEVEL, ByteBuffer::put(), rbac::RBAC_PERM_TWO_SIDE_WHO_LIST, rbac::RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS, sAreaTableStore, SendPacket(), SMSG_WHO, STRONG_MAX_LEVEL, sWhoListCacheMgr, sWorld, Utf8FitTo(), Utf8toWStr(), and wstrToLower().

Referenced by OpcodeTable::Initialize().

◆ HandleWorldStateUITimerUpdate()

void WorldSession::HandleWorldStateUITimerUpdate ( WorldPacket &  recvData)
1615{
1616 // empty opcode
1617 LOG_DEBUG("network", "WORLD: CMSG_WORLD_STATE_UI_TIMER_UPDATE");
1618
1620 response.Time = GameTime::GetGameTime().count();
1621 SendPacket(response.Write());
1622}
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)
1052{
1053 uint32 time;
1054 uint32 mapid;
1055 float PositionX;
1056 float PositionY;
1057 float PositionZ;
1058 float Orientation;
1059
1060 recv_data >> time; // time in m.sec.
1061 recv_data >> mapid;
1062 recv_data >> PositionX;
1063 recv_data >> PositionY;
1064 recv_data >> PositionZ;
1065 recv_data >> Orientation; // o (3.141593 = 180 degrees)
1066
1067 if (GetPlayer()->IsInFlight())
1068 {
1069 LOG_DEBUG("network", "Player '{}' ({}) in flight, ignore worldport command.", GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
1070 return;
1071 }
1072
1073 LOG_DEBUG("network", "CMSG_WORLD_TELEPORT: Player = {}, Time = {}, map = {}, x = {}, y = {}, z = {}, o = {}", GetPlayer()->GetName(), time, mapid, PositionX, PositionY, PositionZ, Orientation);
1074
1076 GetPlayer()->TeleportTo(mapid, PositionX, PositionY, PositionZ, Orientation);
1077 else
1079}
@ RBAC_PERM_OPCODE_WORLD_TELEPORT
Definition RBAC.h:93

References GetPlayer(), HasPermission(), LANG_PERMISSION_DENIED, LOG_DEBUG, rbac::RBAC_PERM_OPCODE_WORLD_TELEPORT, ChatHandler::SendNotification(), and Player::TeleportTo().

Referenced by OpcodeTable::Initialize().

◆ HandleWrapItemOpcode()

void WorldSession::HandleWrapItemOpcode ( WorldPackets::Item::WrapItem &  packet)
1086{
1087 LOG_DEBUG("network", "Received opcode CMSG_WRAP_ITEM");
1088
1089 LOG_DEBUG("network", "WRAP: receive GiftBag = {}, GiftSlot = {}, ItemBag = {}, ItemSlot = {}", packet.GiftBag, packet.GiftSlot, packet.ItemBag, packet.ItemSlot);
1090
1091 Item* gift = _player->GetItemByPos(packet.GiftBag, packet.GiftSlot);
1092 if (!gift)
1093 {
1095 return;
1096 }
1097
1098 if (!(gift->GetTemplate()->HasFlag(ITEM_FLAG_IS_WRAPPER))) // cheating: non-wrapper wrapper
1099 {
1101 return;
1102 }
1103
1104 Item* item = _player->GetItemByPos(packet.ItemBag, packet.ItemSlot);
1105
1106 if (!item)
1107 {
1109 return;
1110 }
1111
1112 // xinef: do not allow to wrap removed items, just in case
1113 if (item->GetState() == ITEM_REMOVED)
1114 {
1116 return;
1117 }
1118
1119 if (item == gift) // not possible with packet from real client
1120 {
1122 return;
1123 }
1124
1125 if (item->IsEquipped())
1126 {
1128 return;
1129 }
1130
1131 if (item->GetGuidValue(ITEM_FIELD_GIFTCREATOR)) // HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED);
1132 {
1134 return;
1135 }
1136
1137 if (item->IsBag())
1138 {
1140 return;
1141 }
1142
1143 if (item->IsSoulBound())
1144 {
1146 return;
1147 }
1148
1149 if (item->GetMaxStackCount() != 1)
1150 {
1152 return;
1153 }
1154
1155 // maybe not correct check (it is better than nothing)
1156 if (item->GetTemplate()->MaxCount > 0)
1157 {
1159 return;
1160 }
1161
1162 if (item->GetTemplate()->Duration > 0)
1163 {
1165 return;
1166 }
1167
1168 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
1169
1171 stmt->SetData(0, item->GetOwnerGUID().GetCounter());
1172 stmt->SetData(1, item->GetGUID().GetCounter());
1173 stmt->SetData(2, item->GetEntry());
1174 stmt->SetData(3, item->GetUInt32Value(ITEM_FIELD_FLAGS));
1175 trans->Append(stmt);
1176
1177 item->SetEntry(gift->GetEntry());
1178
1179 switch (item->GetEntry())
1180 {
1181 case 5042:
1182 item->SetEntry(5043);
1183 break;
1184 case 5048:
1185 item->SetEntry(5044);
1186 break;
1187 case 17303:
1188 item->SetEntry(17302);
1189 break;
1190 case 17304:
1191 item->SetEntry(17305);
1192 break;
1193 case 17307:
1194 item->SetEntry(17308);
1195 break;
1196 case 21830:
1197 item->SetEntry(21831);
1198 break;
1199 }
1203
1204 // after save it will be impossible to remove the item from the queue
1206
1207 CharacterDatabase.CommitTransaction(trans);
1208
1209 uint32 count = 1;
1210 _player->DestroyItemCount(gift, count, true);
1211}
@ CHAR_INS_CHAR_GIFT
Definition CharacterDatabase.h:386
@ 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)
522{
523 uint32 newZone;
524 recv_data >> newZone;
525
526 LOG_DEBUG("network", "WORLD: Recvd ZONE_UPDATE: {}", newZone);
527
528 // use server side data, but only after update the player position. See Player::UpdatePosition().
530
531 //GetPlayer()->SendInitWorldStates(true, newZone);
532}
void SetNeedZoneUpdate(bool needUpdate)
Definition Player.h:1888

References GetPlayer(), LOG_DEBUG, and Player::SetNeedZoneUpdate().

Referenced by OpcodeTable::Initialize().

◆ HasAccountFlag()

◆ HasPermission()

bool WorldSession::HasPermission ( uint32  permissionId)
1692{
1693 if (!_RBACData)
1695
1696 bool hasPermission = _RBACData->HasPermission(permission);
1697 LOG_DEBUG("rbac", "WorldSession::HasPermission [AccountId: {}, Name: {}, realmId: {}]",
1699
1700 return hasPermission;
1701}
void LoadPermissions()
Definition WorldSession.cpp:1667
uint32 GetId() const
Gets the Id of the Object.
Definition RBAC.h:771
std::string const & GetName() const
Gets the Name of the Object.
Definition RBAC.h:769
bool HasPermission(uint32 permission) const
Definition RBAC.h:779

References _RBACData, rbac::RBACData::GetId(), rbac::RBACData::GetName(), rbac::RBACData::HasPermission(), Realm::Id, LoadPermissions(), LOG_DEBUG, realm, and RealmHandle::Realm.

Referenced by ChatHandler::_ParseCommands(), InstanceScript::_SkipCheckRequiredBosses(), WorldSessionMgr::AddSession_(), Channel::Announce(), SocialMgr::BroadcastToFriendListers(), Player::CanBeGameMaster(), Player::CanJoinToBattleground(), CanOpenMailBox(), AchievementMgr::CompletedAchievement(), Spell::EffectEnchantItemPerm(), Spell::EffectEnchantItemPrismatic(), Spell::EffectEnchantItemTmp(), Channel::FlagsNotify(), SocialMgr::GetFriendInfo(), HandleAcceptTradeOpcode(), account_commandscript::HandleAccountCommand(), HandleAddFriendOpcode(), HandleAuctionPlaceBid(), HandleAuctionSellItem(), HandleCharCreateOpcode(), HandleCharCustomizeCallback(), HandleCharFactionOrRaceChangeCallback(), HandleCharRenameOpcode(), HandleInitiateTradeOpcode(), HandleLogoutRequestOpcode(), HandleMailTakeItem(), HandleMailTakeMoney(), Guild::HandleMemberDepositMoney(), Guild::HandleMemberWithdrawMoney(), HandleMessagechatOpcode(), WorldSocket::HandlePing(), misc_commandscript::HandleSaveCommand(), HandleSendMail(), HandleWhoisOpcode(), HandleWhoOpcode(), HandleWorldTeleportOpcode(), ChatHandler::HasLowerSecurityAccount(), ChatHandler::HasPermission(), lfg::LFGMgr::InitializeLockedDungeons(), Channel::JoinChannel(), lfg::LFGMgr::JoinLfg(), Channel::JoinNotify(), Channel::KickOrBan(), Channel::LeaveNotify(), Channel::List(), Channel::Password(), Battleground::RemovePlayerAtLeave(), AchievementMgr::ResetAchievementCriteria(), WorldSessionMgr::SendGlobalGMMessage(), ChatHandler::SendGMText(), Channel::SetMode(), Channel::SetOwner(), Channel::ShouldAnnouncePlayer(), Channel::ToggleModeration(), Channel::UnBan(), Update(), and AchievementMgr::UpdateAchievementCriteria().

◆ IncrementOrderCounter()

◆ InitializeSession()

void WorldSession::InitializeSession ( )
1565{
1566 uint32 cacheVersion = sWorld->getIntConfig(CONFIG_CLIENTCACHE_VERSION);
1567 sScriptMgr->OnBeforeFinalizePlayerWorldSession(cacheVersion);
1568
1569 std::shared_ptr<AccountInfoQueryHolderPerRealm> realmHolder = std::make_shared<AccountInfoQueryHolderPerRealm>();
1570 if (!realmHolder->Initialize(GetAccountId()))
1571 {
1573 return;
1574 }
1575
1576 AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(realmHolder)).AfterComplete([this, cacheVersion](SQLQueryHolderBase const& holder)
1577 {
1578 InitializeSessionCallback(static_cast<AccountInfoQueryHolderPerRealm const&>(holder), cacheVersion);
1579 });
1580}
@ AUTH_SYSTEM_ERROR
Definition SharedDefines.h:3589
@ CONFIG_CLIENTCACHE_VERSION
Definition WorldConfig.h:313
Definition WorldSession.cpp:1536
void InitializeSessionCallback(CharacterDatabaseQueryHolder const &realmHolder, uint32 clientCacheVersion)
Definition WorldSession.cpp:1582
void SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos=0)
Definition AuthHandler.cpp:23

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 
)
1583{
1585 LoadTutorialsData(realmHolder.GetPreparedResult(AccountInfoQueryHolderPerRealm::TUTORIALS));
1586
1587 if (!sToCloud9Sidecar->ClusterModeEnabled())
1588 {
1589 if (!m_inQueue)
1590 {
1592 }
1593 else
1594 {
1596 }
1597 }
1598
1599 SetInQueue(false);
1600 ResetTimeOutTime(false);
1601
1602 if (!sToCloud9Sidecar->ClusterModeEnabled())
1603 {
1605 SendClientCacheVersion(clientCacheVersion);
1607 }
1608}
@ AUTH_OK
Definition SharedDefines.h:3584
@ TUTORIALS
Definition WorldSession.cpp:1541
@ GLOBAL_ACCOUNT_DATA
Definition WorldSession.cpp:1540
void LoadTutorialsData(PreparedQueryResult result)
Definition WorldSession.cpp:1047
void SendClientCacheVersion(uint32 version)
Definition AuthHandler.cpp:56
void SendAuthWaitQueue(uint32 position)
Handle the authentication waiting queue (to be completed)
Definition WorldSession.cpp:957
void SendAddonsInfo()
Definition WorldSession.cpp:1330
void SetInQueue(bool state)
Session in auth.queue currently.
Definition WorldSession.h:523
void SendTutorialsData()
Definition WorldSession.cpp:1062

References AUTH_OK, SQLQueryHolderBase::GetPreparedResult(), AccountInfoQueryHolderPerRealm::GLOBAL_ACCOUNT_DATA, GLOBAL_CACHE_MASK, LoadAccountData(), LoadTutorialsData(), m_inQueue, ResetTimeOutTime(), SendAddonsInfo(), SendAuthResponse(), SendAuthWaitQueue(), SendClientCacheVersion(), SendTutorialsData(), SetInQueue(), sToCloud9Sidecar, and AccountInfoQueryHolderPerRealm::TUTORIALS.

Referenced by InitializeSession().

◆ InitRBACDataForTest()

void WorldSession::InitRBACDataForTest ( )

For unit testing - initializes RBAC data without database access.

1712{
1713 delete _RBACData;
1715 _RBACData->LoadFromDBCallback(nullptr);
1716}
Definition RBAC.h:762
void LoadFromDBCallback(PreparedQueryResult result)
Definition RBAC.cpp:201

References _accountId, _accountName, _RBACData, _security, Realm::Id, rbac::RBACData::LoadFromDBCallback(), realm, and RealmHandle::Realm.

◆ InitWarden()

void WorldSession::InitWarden ( SessionKey const &  k,
std::string const &  os 
)
1425{
1426 if (os == "Win")
1427 {
1428 _warden = std::make_unique<WardenWin>();
1429 _warden->Init(this, k);
1430 }
1431 else if (os == "OSX")
1432 {
1433 // Disabled as it is causing the client to crash
1434 // _warden = new WardenMac();
1435 // _warden->Init(this, k);
1436 }
1437}

References _warden.

Referenced by WorldSocket::HandleAuthSessionCallback().

◆ InvalidateRBACData()

void WorldSession::InvalidateRBACData ( )
1704{
1705 LOG_DEBUG("rbac", "WorldSession::InvalidateRBACData [AccountId: {}, Name: {}, realmId: {}]",
1707 delete _RBACData;
1708 _RBACData = nullptr;
1709}

References _RBACData, rbac::RBACData::GetId(), rbac::RBACData::GetName(), Realm::Id, LOG_DEBUG, realm, and RealmHandle::Realm.

◆ IsAffectedByCAIS()

bool WorldSession::IsAffectedByCAIS ( ) const
241{
242 // China realm system for restricting consecutive play time (anti-addiction).
243 // There is no known per-account flag for it, so a realm-wide config gate is used;
244 // swap this out if a per-account/realm-region source is found later.
245 return sWorld->getBoolConfig(CONFIG_CAIS_ENABLED);
246}
@ CONFIG_CAIS_ENABLED
Definition WorldConfig.h:520

References CONFIG_CAIS_ENABLED, and sWorld.

Referenced by GetBillingPlanFlags(), SendAuthResponse(), Update(), and WorldSessionMgr::UpdateSessions().

◆ IsARecruiter()

bool WorldSession::IsARecruiter ( ) const
inline

◆ IsConnectionIdle()

bool WorldSession::IsConnectionIdle ( ) const
inline
670 {
671 return (m_timeOutTime <= 0 && !m_inQueue);
672 }

References m_inQueue, and m_timeOutTime.

Referenced by Update().

◆ IsGMAccount()

bool WorldSession::IsGMAccount ( ) const

◆ IsHeadless()

bool WorldSession::IsHeadless ( ) const
inline
1234{ return _headless; }

References _headless.

◆ IsInternetGameRoomAccount()

bool WorldSession::IsInternetGameRoomAccount ( ) const
231{
233}
@ ACCOUNT_FLAG_IGR
Definition Common.h:72

References ACCOUNT_FLAG_IGR, and HasAccountFlag().

Referenced by GetBillingPlanFlags().

◆ IsKicked()

bool WorldSession::IsKicked ( ) const
inline
1214{ return _kicked; }

References _kicked.

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

◆ IsLegitCharacterForAccount()

bool WorldSession::IsLegitCharacterForAccount ( ObjectGuid  guid)
inlineprivate
1284 {
1285 return _legitCharacters.find(guid) != _legitCharacters.end();
1286 }

References _legitCharacters.

Referenced by HandleCharCustomize(), HandleCharFactionOrRaceChange(), and HandlePlayerLoginOpcode().

◆ IsLoggingOut()

bool WorldSession::IsLoggingOut ( ) const
inline

Is the user engaged in a log out process?

536{ return _logoutTime || m_playerLogout; }

References _logoutTime, and m_playerLogout.

Referenced by HandleInitiateTradeOpcode(), and Player::SaveToDB().

◆ IsRecurringBillingAccount()

bool WorldSession::IsRecurringBillingAccount ( ) const
236{
238}
@ ACCOUNT_FLAG_RECURRING_BILLING
Definition Common.h:80

References ACCOUNT_FLAG_RECURRING_BILLING, and HasAccountFlag().

Referenced by GetBillingPlanFlags().

◆ IsSocketClosed()

bool WorldSession::IsSocketClosed ( ) const
640{
641 return !m_Socket || !m_Socket->IsOpen();
642}

References m_Socket.

Referenced by Group::ResetMaxEnchantingLevel().

◆ IsTrialAccount()

◆ KickPlayer() [1/2]

◆ KickPlayer() [2/2]

void WorldSession::KickPlayer ( std::string const &  reason,
bool  setKicked = true 
)

Kick a player out of the World.

882{
883 if (m_Socket)
884 {
885 LOG_INFO("network.kick", "Account: {} Character: '{}' {} kicked with reason: {}", GetAccountId(), _player ? _player->GetName() : "<none>",
886 _player ? _player->GetGUID().ToString() : "", reason);
887
888 m_Socket->CloseSocket();
889 }
890
891 if (setKicked)
892 SetKicked(true); // pussywizard: the session won't be left ingame for 60 seconds and to also kick offline session
893}
void SetKicked(bool val)
Definition WorldSession.h:1215

References _player, GetAccountId(), Object::GetGUID(), WorldObject::GetName(), LOG_INFO, m_Socket, SetKicked(), and ObjectGuid::ToString().

◆ LoadAccountData()

void WorldSession::LoadAccountData ( PreparedQueryResult  result,
uint32  mask 
)
976{
977 for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
978 if (mask & (1 << i))
980
981 if (!result)
982 return;
983
984 do
985 {
986 Field* fields = result->Fetch();
987 uint32 type = fields[0].Get<uint8>();
988 if (type >= NUM_ACCOUNT_DATA_TYPES)
989 {
990 LOG_ERROR("network", "Table `{}` have invalid account data type ({}), ignore.", mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
991 continue;
992 }
993
994 if ((mask & (1 << type)) == 0)
995 {
996 LOG_ERROR("network", "Table `{}` have non appropriate for table account data type ({}), ignore.", mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
997 continue;
998 }
999
1000 m_accountData[type].Time = time_t(fields[1].Get<uint32>());
1001 m_accountData[type].Data = fields[2].Get<std::string>();
1002 } while (result->NextRow());
1003}

References AccountData::Data, Field::Get(), GLOBAL_CACHE_MASK, LOG_ERROR, m_accountData, NUM_ACCOUNT_DATA_TYPES, and AccountData::Time.

Referenced by HandlePlayerLoginFromDB(), and InitializeSessionCallback().

◆ LoadPermissions()

void WorldSession::LoadPermissions ( )
1668{
1669 uint32 id = GetAccountId();
1670 uint8 secLevel = GetSecurity();
1671
1672 LOG_DEBUG("rbac", "WorldSession::LoadPermissions [AccountId: {}, Name: {}, realmId: {}, secLevel: {}]",
1673 id, _accountName, realm.Id.Realm, secLevel);
1674
1675 _RBACData = new rbac::RBACData(id, _accountName, realm.Id.Realm, secLevel);
1677}
void LoadFromDB()
Loads all permissions assigned to current account.
Definition RBAC.cpp:175

References _accountName, _RBACData, GetAccountId(), GetSecurity(), Realm::Id, rbac::RBACData::LoadFromDB(), LOG_DEBUG, realm, and RealmHandle::Realm.

Referenced by HasPermission().

◆ LoadPermissionsAsync()

QueryCallback WorldSession::LoadPermissionsAsync ( )
1680{
1681 uint32 id = GetAccountId();
1682 uint8 secLevel = GetSecurity();
1683
1684 LOG_DEBUG("rbac", "WorldSession::LoadPermissions [AccountId: {}, Name: {}, realmId: {}, secLevel: {}]",
1685 id, _accountName, realm.Id.Realm, secLevel);
1686
1687 _RBACData = new rbac::RBACData(id, _accountName, realm.Id.Realm, secLevel);
1688 return _RBACData->LoadFromDBAsync();
1689}
QueryCallback LoadFromDBAsync()
Definition RBAC.cpp:188

References _accountName, _RBACData, GetAccountId(), GetSecurity(), Realm::Id, rbac::RBACData::LoadFromDBAsync(), LOG_DEBUG, realm, and RealmHandle::Realm.

◆ LoadTutorialsData()

void WorldSession::LoadTutorialsData ( PreparedQueryResult  result)
1048{
1049 memset(m_Tutorials, 0, sizeof(uint32) * MAX_ACCOUNT_TUTORIAL_VALUES);
1050
1051 if (result)
1052 {
1053 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
1054 {
1055 m_Tutorials[i] = (*result)[i].Get<uint32>();
1056 }
1057 }
1058
1059 m_TutorialsChanged = false;
1060}

References m_Tutorials, m_TutorialsChanged, and MAX_ACCOUNT_TUTORIAL_VALUES.

Referenced by InitializeSessionCallback().

◆ LogoutPlayer()

void WorldSession::LogoutPlayer ( bool  save,
bool  redirecting = false 
)

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

Mark all characters of the account offline, unless a script running several per account handles it instead

687{
688 // finish pending transfers before starting the logout
691
692 m_playerLogout = true;
693 m_playerSave = save;
694
695 if (_player)
696 {
698 sScriptMgr->OnPlayerBeforeLogout(_player);
699
700 if (ObjectGuid lguid = _player->GetLootGUID())
701 DoLootRelease(lguid);
702
704 //FIXME: logout must be delayed in case lost connection with client in time of combat
705 if (_player->GetDeathTimer())
706 {
710 }
712 {
713 // this will kill character by SPELL_AURA_SPIRIT_OF_REDEMPTION
718 }
719 else if (_player->HasPendingBind())
720 {
722 _player->SetPendingBind(0, 0);
723 }
724
725 // pussywizard: leave whole bg on logout (character stays ingame when necessary)
726 // pussywizard: GetBattleground() checked inside
728
729 // pussywizard: checked first time
732
733 sOutdoorPvPMgr->HandlePlayerLeaveZone(_player, _player->GetZoneId());
734 sWorldState->HandlePlayerLeaveZone(_player, static_cast<AreaTableIDs>(_player->GetZoneId()));
735
736 // pussywizard: remove from battleground queues on logout
737 for (int i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
739 {
740 // track if player logs out after invited to join BG
742 {
744 {
746 stmt->SetData(0, _player->GetGUID().GetCounter());
748 CharacterDatabase.Execute(stmt);
749 }
750
751 sScriptMgr->OnPlayerBattlegroundDesertion(_player, BG_DESERTION_TYPE_INVITE_LOGOUT);
752 }
753
754 if (bgQueueTypeId >= BATTLEGROUND_QUEUE_2v2 && bgQueueTypeId < MAX_BATTLEGROUND_QUEUE_TYPES && _player->IsInvitedForBattlegroundQueueType(bgQueueTypeId))
755 sScriptMgr->OnPlayerBattlegroundDesertion(_player, ARENA_DESERTION_TYPE_INVITE_LOGOUT);
756
757 _player->RemoveBattlegroundQueueId(bgQueueTypeId);
758 sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId).RemovePlayer(_player->GetGUID(), true);
759 }
760
762 if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
763 guild->HandleMemberLogout(this);
764
767
768 // pussywizard: on logout remove auras that are removed at map change (before saving to db)
769 // 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
771
772 if (!redirecting)
773 {
774 if (Group *group = _player->GetGroupInvite())
776 ? _player->UninviteFromGroup() // Can disband group.
777 : group->RemoveInvite(_player); // Just removes invite.
778
779 // remove player from the group if he is:
780 // a) in group; b) not in raid group; c) logging out normally (not being kicked or disconnected) d) LeaveGroupOnLogout is enabled
781 if (!sToCloud9Sidecar->ClusterModeEnabled() && _player->GetGroup() && !_player->GetGroup()->isRaidGroup() && !_player->GetGroup()->isLFGGroup() && m_Socket && sWorld->getBoolConfig(CONFIG_LEAVE_GROUP_ON_LOGOUT))
783 // Remove player from active loot rolls in LFG groups (player stays in group but should not block rolls)
784 else if (Group* group = _player->GetGroup())
785 if (group->isLFGGroup())
786 group->RemovePlayerFromRolls(_player->GetGUID());
787
788 // pussywizard: checked second time after being removed from a group
791 }
792
793 // Repop at Graveyard or other player far teleport will prevent saving player because of not present map
794 // Teleport player immediately for correct player save
797
799 // some save parts only correctly work in case player present in map/player_lists (pets, etc)
800 if (save)
801 {
802 uint32 eslot;
803 for (int j = BUYBACK_SLOT_START; j < BUYBACK_SLOT_END; ++j)
804 {
805 eslot = j - BUYBACK_SLOT_START;
809 }
810 _player->SaveToDB(false, true);
811 }
812
815
817 if (_player->GetGroup())
818 {
821
823 {
824 Map::PlayerList const &playerList = _player->GetMap()->GetPlayers();
825 if (playerList.IsEmpty())
827 }
828 }
829
830 if (!redirecting)
831 {
833 sSocialMgr->SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUID(), true);
834 sSocialMgr->RemovePlayerSocial(_player->GetGUID());
835
837 sScriptMgr->OnPlayerLogout(_player);
838 }
839
840 METRIC_EVENT("player_events", "Logout", _player->GetName());
841
842 LOG_INFO("entities.player", "Account: {} (IP: {}) Logout Character:[{}] ({}) Level: {}",
844
845 ObjectGuid const playerGuid = _player->GetGUID();
846
848 // the player may not be in the world when logging out
849 // e.g if he got disconnected during a transfer to another map
850 // calls to GetMap in this case may cause crashes
852 if (Map* _map = _player->FindMap())
853 {
854 _map->RemovePlayerFromMap(_player, true);
855 _map->AfterPlayerUnlinkFromMap();
856 }
857
858 SetPlayer(nullptr); // pointer already deleted
859
863 LOG_DEBUG("network", "SESSION: Sent SMSG_LOGOUT_COMPLETE Message");
864
866 if (!redirecting && sScriptMgr->OnPlayerCanMarkAccountOffline(playerGuid, GetAccountId()))
867 {
869 stmt->SetData(0, GetAccountId());
870 CharacterDatabase.Execute(stmt);
871 }
872 }
873
874 m_playerLogout = false;
875 m_playerSave = false;
878}
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:285
#define sOutdoorPvPMgr
Definition OutdoorPvPMgr.h:102
@ BUYBACK_SLOT_END
Definition Player.h:712
@ FRIEND_OFFLINE
Definition SocialMgr.h:69
@ SPELL_AURA_MOD_SHAPESHIFT
Definition SpellAuraDefines.h:99
@ AURA_INTERRUPT_FLAG_CHANGE_MAP
Definition SpellDefines.h:70
@ 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:134
#define sWorldState
Definition WorldState.h:377
void ResetMaxEnchantingLevel()
Definition Group.cpp:2434
bool IsEmpty() const
Definition LinkedList.h:97
Definition MapRefMgr.h:26
bool IsRaidOrHeroicDungeon() const
Definition Map.h:302
bool IsBeingTeleportedFar() const
Definition Player.h:2123
void CleanupsBeforeDelete(bool finalCleanup=true) override
Definition Player.cpp:477
uint32 GetDeathTimer() const
Definition Player.h:2207
bool HasSpiritOfRedemptionAura() const
Definition Unit.h:1807
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, DoLootRelease(), ObjectGuid::Empty, WorldObject::FindMap(), FRIEND_OFFLINE, GetAccountId(), Player::GetBattlegroundQueueTypeId(), ObjectGuid::GetCounter(), Player::GetDeathTimer(), Player::GetGroup(), Player::GetGroupInvite(), Object::GetGUID(), Player::GetGuildId(), Unit::GetLevel(), Player::GetLootGUID(), WorldObject::GetMap(), WorldObject::GetName(), Map::GetPlayers(), GetRemoteAddress(), Unit::GetThreatMgr(), 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(), ThreatManager::RemoveMeFromThreatLists(), 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, sToCloud9Sidecar, 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,
char const *  reason 
)
private

Logging helper for unexpected opcodes.

367{
368 LOG_ERROR("network.opcode", "Received unexpected opcode {} Status: {} Reason: {} from {}",
369 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), status, reason, GetPlayerInfo());
370}

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

Referenced by Update().

◆ LogUnprocessedTail()

void WorldSession::LogUnprocessedTail ( WorldPacket *  packet)
private

Logging helper for unexpected opcodes.

374{
375 if (!sLog->ShouldLog("network.opcode", LogLevel::LOG_LEVEL_TRACE) || packet->rpos() >= packet->wpos())
376 return;
377
378 LOG_TRACE("network.opcode", "Unprocessed tail data (read stop at {} from {}) Opcode {} from {}",
379 uint32(packet->rpos()), uint32(packet->wpos()), GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
380
381 packet->print_storage();
382}
@ LOG_LEVEL_TRACE
Definition LogCommon.h:32
#define sLog
Definition Log.h:127
#define LOG_TRACE(filterType__,...)
Definition Log.h:161
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
126{
127 Player* trader = _player->GetTrader();
128 if (!trader)
129 return;
130
131 for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i)
132 {
133 ItemPosCountVec traderDst;
134 ItemPosCountVec playerDst;
135 bool traderCanTrade = (!myItems[i] || trader->CanStoreItem(NULL_BAG, NULL_SLOT, traderDst, myItems[i], false) == EQUIP_ERR_OK);
136 bool playerCanTrade = (!hisItems[i] || _player->CanStoreItem(NULL_BAG, NULL_SLOT, playerDst, hisItems[i], false) == EQUIP_ERR_OK);
137 if (traderCanTrade && playerCanTrade)
138 {
139 // Ok, if trade item exists and can be stored
140 // If we trade in both directions we had to check, if the trade will work before we actually do it
141 // A roll back is not possible after we stored it
142 if (myItems[i])
143 {
144 // logging
145 LOG_DEBUG("network", "partner storing: {}", myItems[i]->GetGUID().ToString());
146
147 // adjust time (depends on /played)
148 if (myItems[i]->IsBOPTradable())
150 // store
151 trader->MoveItemToInventory(traderDst, myItems[i], true, true);
152 }
153 if (hisItems[i])
154 {
155 // logging
156 LOG_DEBUG("network", "player storing: {}", hisItems[i]->GetGUID().ToString());
157
158 // adjust time (depends on /played)
159 if (hisItems[i]->IsBOPTradable())
161 // store
162 _player->MoveItemToInventory(playerDst, hisItems[i], true, true);
163 }
164 }
165 else
166 {
167 // in case of fatal error log error message
168 // return the already removed items to the original owner
169 if (myItems[i])
170 {
171 if (!traderCanTrade)
172 LOG_ERROR("network.opcode", "trader can't store item: {}", myItems[i]->GetGUID().ToString());
173 if (_player->CanStoreItem(NULL_BAG, NULL_SLOT, playerDst, myItems[i], false) == EQUIP_ERR_OK)
174 _player->MoveItemToInventory(playerDst, myItems[i], true, true);
175 else
176 LOG_ERROR("network.opcode", "player can't take item back: {}", myItems[i]->GetGUID().ToString());
177 }
178 // return the already removed items to the original owner
179 if (hisItems[i])
180 {
181 if (!playerCanTrade)
182 LOG_ERROR("network.opcode", "player can't store item: {}", hisItems[i]->GetGUID().ToString());
183 if (trader->CanStoreItem(NULL_BAG, NULL_SLOT, traderDst, hisItems[i], false) == EQUIP_ERR_OK)
184 trader->MoveItemToInventory(traderDst, hisItems[i], true, true);
185 else
186 LOG_ERROR("network.opcode", "trader can't take item back: {}", hisItems[i]->GetGUID().ToString());
187 }
188 }
189 }
190}
@ ITEM_FIELD_CREATE_PLAYED_TIME
Definition UpdateFields.h:71
Player * GetTrader() const
Definition Player.h:1399

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().

◆ NextQueuedPacket()

std::unique_ptr< WorldPacket > WorldSession::NextQueuedPacket ( )
1659{
1660 WorldPacket* packet = nullptr;
1661 if (!_recvQueue.next(packet))
1662 return nullptr;
1663
1664 return std::unique_ptr<WorldPacket>(packet);
1665}

References _recvQueue, and LockedQueue< T, StorageType >::next().

◆ operator=()

WorldSession & WorldSession::operator= ( WorldSession const &  right)
privatedelete

◆ PlayerLoading()

◆ PlayerLogout()

◆ PlayerLogoutWithSave()

bool WorldSession::PlayerLogoutWithSave ( ) const
inline
453{ return m_playerLogout && m_playerSave; }

References m_playerLogout, and m_playerSave.

◆ PlayerRecentlyLoggedOut()

bool WorldSession::PlayerRecentlyLoggedOut ( ) const
inline
452{ return m_playerRecentlyLogout; }

References m_playerRecentlyLogout.

Referenced by SendCancelTrade().

◆ ProcessMovementInfo()

bool WorldSession::ProcessMovementInfo ( MovementInfo &  movementInfo,
Unit *  mover,
Player *  plrMover,
WorldPacket &  recvData 
)
615{
616 Opcodes opcode = (Opcodes)recvData.GetOpcode();
617 if (!VerifyMovementInfo(movementInfo, plrMover, mover, opcode))
618 return false;
619
620 if (mover->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE) || (mover->IsCreature() && mover->IsImmobilizedState()))
621 {
622 movementInfo.pos.Relocate(mover->GetPositionX(), mover->GetPositionY(), mover->GetPositionZ());
623
624 if (mover->IsCreature())
625 {
626 movementInfo.transport.guid = mover->m_movementInfo.transport.guid;
628 movementInfo.transport.seat = mover->m_movementInfo.transport.seat;
629 }
630 }
631
632 // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
633 if (opcode == MSG_MOVE_FALL_LAND && plrMover && !plrMover->IsInFlight())
634 {
635 plrMover->HandleFall(movementInfo);
636
637 sScriptMgr->AnticheatSetJumpingbyOpcode(plrMover, false);
638 }
639
640 // interrupt parachutes upon falling or landing in water
641 if (opcode == MSG_MOVE_FALL_LAND || opcode == MSG_MOVE_START_SWIM)
642 {
644
645 if (plrMover)
646 {
647 sScriptMgr->AnticheatSetJumpingbyOpcode(plrMover, false);
648 }
649 }
650
651 if (plrMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plrMover->IsInWater())
652 {
653 // now client not include swimming flag in case jumping under water
654 plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetMap()->IsUnderWater(plrMover->GetPhaseMask(), movementInfo.pos.GetPositionX(),
655 movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ(), plrMover->GetCollisionHeight()));
656 }
657
658 if (plrMover)//Hook for OnPlayerMove
659 {
660 sScriptMgr->OnPlayerMove(plrMover, movementInfo, opcode);
661 }
662
664 {
665 if (mover->IsStandState())
668 }
669
670 HandleMoverRelocation(movementInfo, mover);
671
672 if (plrMover && opcode != CMSG_MOVE_KNOCK_BACK_ACK)
673 plrMover->UpdateFallInformationIfNeed(movementInfo, opcode);
674
675 return true;
676}
@ AURA_INTERRUPT_FLAG_LANDING
Definition SpellDefines.h:76
@ MOVEMENTFLAG_MASK_MOVING_OR_TURN
Definition UnitDefines.h:420
@ MOVEMENTFLAG_SWIMMING
Definition UnitDefines.h:393
@ UNIT_FLAG_DISABLE_MOVE
Definition UnitDefines.h:259
bool IsUnderWater(uint32 phaseMask, float x, float y, float z, float collisionHeight) const
Definition Map.cpp:1621
void HandleFall(MovementInfo const &movementInfo)
Definition Player.cpp:14201
void SetInWater(bool apply)
Definition Player.cpp:2197
bool IsInWater() const override
Definition Player.h:1136
void UpdateFallInformationIfNeed(MovementInfo const &minfo, uint16 opcode)
Definition PlayerUpdates.cpp:2245
float GetCollisionHeight() const override
Return collision height sent to client.
Definition Unit.cpp:16764
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:748
uint32 GetPhaseMask() const
Definition Object.h:523
void HandleMoverRelocation(MovementInfo &movementInfo, Unit *mover)
Definition MovementHandler.cpp:430
bool VerifyMovementInfo(MovementInfo const &movementInfo, Player *plrMover, Unit *mover, Opcodes opcode) const
Definition MovementHandler.cpp:531
@ 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:316

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::IsImmobilizedState(), 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(), HandleMoveKnockBackAck(), HandleMovementOpcodes(), and HandleMoveRootAck().

◆ ProcessQueryCallbacks()

void WorldSession::ProcessQueryCallbacks ( )

◆ QueuePacket()

void WorldSession::QueuePacket ( WorldPacket *  new_packet)

Add an incoming packet to the queue.

361{
362 _recvQueue.add(new_packet);
363}
void add(T const &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.
1242{
1243 if (data.rpos() + 4 > data.size())
1244 return;
1245
1246 uint32 size;
1247 data >> size;
1248
1249 if (!size)
1250 return;
1251
1252 if (size > 0xFFFFF)
1253 {
1254 LOG_ERROR("network", "WorldSession::ReadAddonsInfo addon info too big, size {}", size);
1255 return;
1256 }
1257
1258 uLongf uSize = size;
1259
1260 uint32 pos = data.rpos();
1261
1262 ByteBuffer addonInfo;
1263 addonInfo.resize(size);
1264
1265 if (uncompress(addonInfo.contents(), &uSize, data.contents() + pos, data.size() - pos) == Z_OK)
1266 {
1267 try
1268 {
1269 uint32 addonsCount;
1270 addonInfo >> addonsCount; // addons count
1271
1272 for (uint32 i = 0; i < addonsCount; ++i)
1273 {
1274 std::string addonName;
1275 uint8 enabled;
1276 uint32 crc, unk1;
1277
1278 // check next addon data format correctness
1279 if (addonInfo.rpos() + 1 > addonInfo.size())
1280 return;
1281
1282 addonInfo >> addonName;
1283
1284 addonInfo >> enabled >> crc >> unk1;
1285
1286 LOG_DEBUG("network", "ADDON: Name: {}, Enabled: 0x{:x}, CRC: 0x{:x}, Unknown2: 0x{:x}", addonName, enabled, crc, unk1);
1287
1288 AddonInfo addon(addonName, enabled, crc, 2, true);
1289
1290 SavedAddon const* savedAddon = AddonMgr::GetAddonInfo(addonName);
1291 if (savedAddon)
1292 {
1293 bool match = true;
1294
1295 if (addon.CRC != savedAddon->CRC)
1296 match = false;
1297
1298 if (!match)
1299 LOG_DEBUG("network", "ADDON: {} was known, but didn't match known CRC (0x{:x})!", addon.Name, savedAddon->CRC);
1300 else
1301 LOG_DEBUG("network", "ADDON: {} was known, CRC is correct (0x{:x})", addon.Name, savedAddon->CRC);
1302 }
1303 else
1304 {
1305 AddonMgr::SaveAddon(addon);
1306
1307 LOG_DEBUG("network", "ADDON: {} (0x{:x}) was not known, saving...", addon.Name, addon.CRC);
1308 }
1309
1311 m_addonsList.push_back(addon);
1312 }
1313
1314 uint32 currentTime;
1315 addonInfo >> currentTime;
1316 LOG_DEBUG("network", "ADDON: CurrentTime: {}", currentTime);
1317
1318 if (addonInfo.rpos() != addonInfo.size())
1319 LOG_DEBUG("network", "packet under-read!");
1320 }
1321 catch (ByteBufferException const& e)
1322 {
1323 LOG_ERROR("network", "Addon packet read error! {}", e.what());
1324 }
1325 }
1326 else
1327 LOG_ERROR("network", "Addon packet uncompress error!");
1328}
char const * what() const noexcept override
Definition ByteBuffer.h:36
AddonsList m_addonsList
Definition WorldSession.h:1326
SavedAddon const * GetAddonInfo(std::string const &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

1090{
1091 data >> mi->flags;
1092 data >> mi->flags2;
1093 data >> mi->time;
1094 data >> mi->pos.PositionXYZOStream();
1095
1097 {
1098 data >> mi->transport.guid.ReadAsPacked();
1099
1100 data >> mi->transport.pos.PositionXYZOStream();
1101 data >> mi->transport.time;
1102 data >> mi->transport.seat;
1103
1105 data >> mi->transport.time2;
1106 }
1107
1109 data >> mi->pitch;
1110
1111 data >> mi->fallTime;
1112
1114 {
1115 data >> mi->jump.zspeed;
1116 data >> mi->jump.sinAngle;
1117 data >> mi->jump.cosAngle;
1118 data >> mi->jump.xyspeed;
1119 }
1120
1122 data >> mi->splineElevation;
1123
1126#ifdef ACORE_DEBUG
1127#define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
1128 { \
1129 if (check) \
1130 { \
1131 LOG_DEBUG("entities.unit", "WorldSession::ReadMovementInfo: Violation of MovementFlags found ({}). " \
1132 "MovementFlags: {}, MovementFlags2: {} for player {}. Mask {} will be removed.", \
1133 STRINGIZE(check), mi->GetMovementFlags(), mi->GetExtraMovementFlags(), GetPlayer()->GetGUID().ToString(), maskToRemove); \
1134 mi->RemoveMovementFlag((maskToRemove)); \
1135 } \
1136 }
1137#else
1138#define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
1139 if (check) \
1140 mi->RemoveMovementFlag((maskToRemove));
1141#endif
1142
1149
1153
1157
1161
1165
1169
1173
1176 !GetPlayer()->HasWaterWalkAura() &&
1177 !GetPlayer()->HasGhostAura(),
1179
1183
1192
1196
1198 (!GetPlayer()->movespline->Initialized() || GetPlayer()->movespline->Finalized()), MOVEMENTFLAG_SPLINE_ENABLED);
1199
1200#undef REMOVE_VIOLATING_FLAGS
1201}
@ SEC_PLAYER
Definition Common.h:57
MovementFlags
Definition UnitDefines.h:370
@ MOVEMENTFLAG_DESCENDING
Definition UnitDefines.h:395
@ MOVEMENTFLAG_PITCH_DOWN
Definition UnitDefines.h:379
@ MOVEMENTFLAG_PITCH_UP
Definition UnitDefines.h:378
@ MOVEMENTFLAG_RIGHT
Definition UnitDefines.h:377
@ MOVEMENTFLAG_SPLINE_ENABLED
Definition UnitDefines.h:399
@ MOVEMENTFLAG_FORWARD
Definition UnitDefines.h:372
@ MOVEMENTFLAG_STRAFE_LEFT
Definition UnitDefines.h:374
@ MOVEMENTFLAG_BACKWARD
Definition UnitDefines.h:373
@ MOVEMENTFLAG_WATERWALKING
Definition UnitDefines.h:400
@ MOVEMENTFLAG_DISABLE_GRAVITY
Definition UnitDefines.h:382
@ MOVEMENTFLAG_FLYING
Definition UnitDefines.h:397
@ MOVEMENTFLAG_FALLING_SLOW
Definition UnitDefines.h:401
@ MOVEMENTFLAG_LEFT
Definition UnitDefines.h:376
@ MOVEMENTFLAG_STRAFE_RIGHT
Definition UnitDefines.h:375
@ MOVEMENTFLAG_ASCENDING
Definition UnitDefines.h:394
@ MOVEMENTFLAG_HOVER
Definition UnitDefines.h:402
@ MOVEMENTFLAG_SPLINE_ELEVATION
Definition UnitDefines.h:398
@ MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING
Definition UnitDefines.h:435
@ MOVEMENTFLAG2_INTERPOLATED_MOVEMENT
Definition UnitDefines.h:440
#define REMOVE_VIOLATING_FLAGS(check, maskToRemove)
float cosAngle
Definition Object.h:336
float xyspeed
Definition Object.h:336
float zspeed
Definition Object.h:336
float sinAngle
Definition Object.h:336
uint32 time2
Definition Object.h:319
uint32 time
Definition Object.h:318
struct MovementInfo::JumpInfo jump
uint16 flags2
Definition Object.h:299
uint32 fallTime
Definition Object.h:326
float splineElevation
Definition Object.h:340
float pitch
Definition Object.h:323
bool HasExtraMovementFlag(uint16 flag) const
Definition Object.h:360
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
1485{
1486 if (sWorld->getBoolConfig(CONFIG_ITEMDELETE_METHOD)
1487 && pItem->GetTemplate()->Quality >= sWorld->getIntConfig(CONFIG_ITEMDELETE_QUALITY)
1488 && pItem->GetTemplate()->ItemLevel >= sWorld->getIntConfig(CONFIG_ITEMDELETE_ITEM_LEVEL))
1489 {
1491
1492 stmt->SetData(0, pItem->GetOwnerGUID().GetCounter());
1493 stmt->SetData(1, pItem->GetTemplate()->ItemId);
1494 stmt->SetData(2, pItem->GetCount());
1495
1496 CharacterDatabase.Query(stmt);
1497
1498 return true;
1499 }
1500
1501 return false;
1502}
@ CHAR_INS_RECOVERY_ITEM
Definition CharacterDatabase.h:518
@ CONFIG_ITEMDELETE_METHOD
Definition WorldConfig.h:120
@ CONFIG_ITEMDELETE_QUALITY
Definition WorldConfig.h:358
@ CONFIG_ITEMDELETE_ITEM_LEVEL
Definition WorldConfig.h:359

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
663 {
664 if (GetPlayer())
666 else if (!onlyActive)
668 }
@ CONFIG_SOCKET_TIMEOUTTIME
Definition WorldConfig.h:175
@ CONFIG_SOCKET_TIMEOUTTIME_ACTIVE
Definition WorldConfig.h:353

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)
1071{
1072 if (!m_TutorialsChanged)
1073 return;
1074
1076 stmt->SetData(0, GetAccountId());
1077 bool hasTutorials = bool(CharacterDatabase.Query(stmt));
1078
1079 stmt = CharacterDatabase.GetPreparedStatement(hasTutorials ? CHAR_UPD_TUTORIALS : CHAR_INS_TUTORIALS);
1080
1081 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
1082 stmt->SetData(i, m_Tutorials[i]);
1084 trans->Append(stmt);
1085
1086 m_TutorialsChanged = false;
1087}
@ CHAR_INS_TUTORIALS
Definition CharacterDatabase.h:208
@ CHAR_UPD_TUTORIALS
Definition CharacterDatabase.h:209
@ CHAR_SEL_HAS_TUTORIALS
Definition CharacterDatabase.h:207

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)
1036{
1037 WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4 + 1 + 4 + 8 * 4); // changed in WotLK
1038 data << uint32(GameTime::GetGameTime().count()); // unix time of something
1039 data << uint8(1);
1040 data << uint32(mask); // type mask
1041 for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
1042 if (mask & (1 << i))
1043 data << uint32(GetAccountData(AccountDataType(i))->Time);// also unix time
1044 SendPacket(&data);
1045}
@ 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)
301{
302 GetPlayer()->SetCanTeleport(true);
304 data << uint32(reply);
305 SendPacket(&data);
306
307 LOG_DEBUG("network", "WORLD: Sent SMSG_ACTIVATETAXIREPLY");
308}
@ 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.
1331{
1332 uint8 addonPublicKey[256] =
1333 {
1334 0xC3, 0x5B, 0x50, 0x84, 0xB9, 0x3E, 0x32, 0x42, 0x8C, 0xD0, 0xC7, 0x48, 0xFA, 0x0E, 0x5D, 0x54,
1335 0x5A, 0xA3, 0x0E, 0x14, 0xBA, 0x9E, 0x0D, 0xB9, 0x5D, 0x8B, 0xEE, 0xB6, 0x84, 0x93, 0x45, 0x75,
1336 0xFF, 0x31, 0xFE, 0x2F, 0x64, 0x3F, 0x3D, 0x6D, 0x07, 0xD9, 0x44, 0x9B, 0x40, 0x85, 0x59, 0x34,
1337 0x4E, 0x10, 0xE1, 0xE7, 0x43, 0x69, 0xEF, 0x7C, 0x16, 0xFC, 0xB4, 0xED, 0x1B, 0x95, 0x28, 0xA8,
1338 0x23, 0x76, 0x51, 0x31, 0x57, 0x30, 0x2B, 0x79, 0x08, 0x50, 0x10, 0x1C, 0x4A, 0x1A, 0x2C, 0xC8,
1339 0x8B, 0x8F, 0x05, 0x2D, 0x22, 0x3D, 0xDB, 0x5A, 0x24, 0x7A, 0x0F, 0x13, 0x50, 0x37, 0x8F, 0x5A,
1340 0xCC, 0x9E, 0x04, 0x44, 0x0E, 0x87, 0x01, 0xD4, 0xA3, 0x15, 0x94, 0x16, 0x34, 0xC6, 0xC2, 0xC3,
1341 0xFB, 0x49, 0xFE, 0xE1, 0xF9, 0xDA, 0x8C, 0x50, 0x3C, 0xBE, 0x2C, 0xBB, 0x57, 0xED, 0x46, 0xB9,
1342 0xAD, 0x8B, 0xC6, 0xDF, 0x0E, 0xD6, 0x0F, 0xBE, 0x80, 0xB3, 0x8B, 0x1E, 0x77, 0xCF, 0xAD, 0x22,
1343 0xCF, 0xB7, 0x4B, 0xCF, 0xFB, 0xF0, 0x6B, 0x11, 0x45, 0x2D, 0x7A, 0x81, 0x18, 0xF2, 0x92, 0x7E,
1344 0x98, 0x56, 0x5D, 0x5E, 0x69, 0x72, 0x0A, 0x0D, 0x03, 0x0A, 0x85, 0xA2, 0x85, 0x9C, 0xCB, 0xFB,
1345 0x56, 0x6E, 0x8F, 0x44, 0xBB, 0x8F, 0x02, 0x22, 0x68, 0x63, 0x97, 0xBC, 0x85, 0xBA, 0xA8, 0xF7,
1346 0xB5, 0x40, 0x68, 0x3C, 0x77, 0x86, 0x6F, 0x4B, 0xD7, 0x88, 0xCA, 0x8A, 0xD7, 0xCE, 0x36, 0xF0,
1347 0x45, 0x6E, 0xD5, 0x64, 0x79, 0x0F, 0x17, 0xFC, 0x64, 0xDD, 0x10, 0x6F, 0xF3, 0xF5, 0xE0, 0xA6,
1348 0xC3, 0xFB, 0x1B, 0x8C, 0x29, 0xEF, 0x8E, 0xE5, 0x34, 0xCB, 0xD1, 0x2A, 0xCE, 0x79, 0xC3, 0x9A,
1349 0x0D, 0x36, 0xEA, 0x01, 0xE0, 0xAA, 0x91, 0x20, 0x54, 0xF0, 0x72, 0xD8, 0x1E, 0xC7, 0x89, 0xD2
1350 };
1351
1353
1354 for (AddonsList::iterator itr = m_addonsList.begin(); itr != m_addonsList.end(); ++itr)
1355 {
1356 data << uint8(itr->State);
1357
1358 uint8 crcpub = itr->UsePublicKeyOrCRC;
1359 data << uint8(crcpub);
1360 if (crcpub)
1361 {
1362 uint8 usepk = (itr->CRC != STANDARD_ADDON_CRC); // If addon is Standard addon CRC
1363 data << uint8(usepk);
1364 if (usepk) // if CRC is wrong, add public key (client need it)
1365 {
1366 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);
1367 data.append(addonPublicKey, sizeof(addonPublicKey));
1368 }
1369
1370 data << uint32(0);
1371 }
1372
1373 uint8 unk3 = 0; // 0 is sent here
1374 data << uint8(unk3);
1375 if (unk3)
1376 {
1377 // String, length 256 (null terminated)
1378 data << uint8(0);
1379 }
1380 }
1381
1382 m_addonsList.clear();
1383
1385 data << uint32(bannedAddons->size());
1386 for (AddonMgr::BannedAddonList::const_iterator itr = bannedAddons->begin(); itr != bannedAddons->end(); ++itr)
1387 {
1388 data << uint32(itr->Id);
1389 data.append(itr->NameMD5);
1390 data.append(itr->VersionMD5);
1391 data << uint32(itr->Timestamp);
1392 data << uint32(1); // IsBanned
1393 }
1394
1395 SendPacket(&data);
1396}
#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
473 {
474 if (!m_playerLoading)
475 SendAreaTriggerMessage(Acore::StringFormat(fmt, std::forward<Args>(args)...));
476 }
void SendAreaTriggerMessage(std::string_view str)
Definition WorldSession.cpp:288

References m_playerLoading, SendAreaTriggerMessage(), and Acore::StringFormat().

◆ SendAreaTriggerMessage() [2/3]

void WorldSession::SendAreaTriggerMessage ( std::string_view  str)
289{
290 std::vector<std::string_view> lines = Acore::Tokenize(str, '\n', true);
291 for (std::string_view line : lines)
292 {
293 uint32 length = line.size() + 1;
294 WorldPacket data(SMSG_AREA_TRIGGER_MESSAGE, 4 + length);
295 data << length;
296 data << line.data();
297 SendPacket(&data);
298 }
299}
@ 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 
)

◆ SendAuctionBidderNotification()

void WorldSession::SendAuctionBidderNotification ( uint32  location,
uint32  auctionId,
ObjectGuid  bidder,
uint32  bidSum,
uint32  diff,
uint32  item_template 
)
90{
92 data << uint32(location);
93 data << uint32(auctionId);
94 data << bidder;
95 data << uint32(bidSum);
96 data << uint32(diff);
97 data << uint32(item_template);
98 data << uint32(0);
99 SendPacket(&data);
100}
@ 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 
)
78{
80 data << auctionId;
81 data << Action;
82 data << ErrorCode;
83 if (!ErrorCode && Action)
84 data << bidError; //when bid, then send 0, once...
85 SendPacket(&data);
86}
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 
)
55{
56 if (GetPlayer()->GetLevel() < sWorld->getIntConfig(CONFIG_AUCTION_LEVEL_REQ))
57 {
59 return;
60 }
61
62 if (!sScriptMgr->CanSendAuctionHello(this, guid, unit))
63 return;
64
66 if (!ahEntry)
67 return;
68
70 data << guid;
71 data << uint32(ahEntry->houseId);
72 data << uint8(1); // 3.3.3: 1 - AH enabled, 0 - AH disabled
73 SendPacket(&data);
74}
@ LANG_AUCTION_REQ
Definition Language.h:1243
@ CONFIG_AUCTION_LEVEL_REQ
Definition WorldConfig.h:256
@ 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)
104{
106 data << uint32(auction->Id);
107 data << uint32(auction->bid);
108 data << uint32(0); //unk
109 data << uint64(0); //unk (bidder guid?)
110 data << uint32(auction->item_template);
111 data << uint32(0); //unk
112 data << float(0); //unk (time?)
113 SendPacket(&data);
114}
@ 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 
)
24{
25 // BillingTimeRested: seconds of "healthy" play left before CAIS halves XP/loot from creatures
26 // and quests (read by the client's GetBillingTimeRested()); 0 unless the CAIS flag is set.
27 uint32 billingTimeRested = 0;
28 if (IsAffectedByCAIS())
29 {
31 if (played < PLAY_TIME_LIMIT_PARTIAL)
32 billingTimeRested = uint32((PLAY_TIME_LIMIT_PARTIAL - played).count());
33 }
34
35 WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1 + (shortForm ? 0 : (4 + 1)));
36 packet << uint8(code);
37 packet << uint32(0); // BillingTimeRemaining
38 packet << GetBillingPlanFlags();
39 packet << billingTimeRested;
40 uint8 exp = Expansion(); // 0 - normal, 1 - TBC, 2 - WotLK, must be set in database manually for each account
41
42 if (exp >= MAX_EXPANSIONS)
43 exp = MAX_EXPANSIONS - 1;
44
45 packet << uint8(exp);
46
47 if (!shortForm)
48 {
49 packet << uint32(queuePos); // Queue position
50 packet << uint8(0); // Realm has a free character migration - bool
51 }
52
53 SendPacket(&packet);
54}
@ MAX_EXPANSIONS
Definition SharedDefines.h:56
uint8 GetBillingPlanFlags() const
Definition WorldSession.cpp:248
@ SMSG_AUTH_RESPONSE
Definition Opcodes.h:524

References Expansion(), GetBillingPlanFlags(), GetConsecutivePlayTime(), GameTime::GetGameTime(), IsAffectedByCAIS(), MAX_EXPANSIONS, PLAY_TIME_LIMIT_PARTIAL, 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)

958{
959 if (position == 0)
960 {
962 packet << uint8(AUTH_OK);
963 SendPacket(&packet);
964 }
965 else
966 {
968 packet << uint8(AUTH_WAIT_QUEUE);
969 packet << uint32(position);
970 packet << uint8(0); // unk
971 SendPacket(&packet);
972 }
973}
@ AUTH_WAIT_QUEUE
Definition SharedDefines.h:3599

References AUTH_OK, AUTH_WAIT_QUEUE, SendPacket(), and SMSG_AUTH_RESPONSE.

Referenced by InitializeSessionCallback().

◆ SendBattleGroundList()

void WorldSession::SendBattleGroundList ( ObjectGuid  guid,
BattlegroundTypeId  bgTypeId = BATTLEGROUND_RB 
)
66{
67 WorldPacket data;
68 sBattlegroundMgr->BuildBattlegroundListPacket(&data, guid, _player, bgTypeId, 0);
69 SendPacket(&data);
70}

References _player, sBattlegroundMgr, and SendPacket().

Referenced by HandleBattlemasterHelloOpcode(), and Player::OnGossipSelect().

◆ SendBfEntered()

void WorldSession::SendBfEntered ( uint32  battleId)
69{
71 data << uint32(battleId);
72 data << uint8(1); // unk
73 data << uint8(1); // unk
74 data << uint8(_player->isAFK() ? 1 : 0); // Clear AFK
75 SendPacket(&data);
76}
@ SMSG_BATTLEFIELD_MGR_ENTERED
Definition Opcodes.h:1278

References _player, Player::isAFK(), SendPacket(), and SMSG_BATTLEFIELD_MGR_ENTERED.

Referenced by Battlefield::PlayerAcceptInviteToWar(), and Battlefield::TryRejoinAfterLogout().

◆ SendBfInvitePlayerToQueue()

void WorldSession::SendBfInvitePlayerToQueue ( uint32  battleId)
43{
45 data << uint32(battleId);
46 data << uint8(1); // warmup ? used ?
47 SendPacket(&data);
48}
@ 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{
34 data << uint32(battleId);
35 data << uint32(zoneId);
36 data << uint32(GameTime::GetGameTime().count() + time);
37 SendPacket(&data);
38}
@ 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 
)
79{
81 data << uint32(battleId);
82 data << uint8(reason); // byte Reason
83 data << uint8(2); // byte BattleStatus
84 data << uint8(0); // bool Relocated
85 SendPacket(&data);
86}
@ 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 
)
56{
58 data << uint32(battleId);
59 data << uint32(zoneId);
60 data << uint8((canQueue ? 1 : 0)); //Accepted //0 you cannot queue wg //1 you are queued
61 data << uint8((full ? 0 : 1)); //Logging In //0 wg full //1 queue for upcoming
62 data << uint8(1); //Warmup
63 SendPacket(&data);
64}
@ 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)
316{
317 // prevent set homebind to instances in any case
318 if (GetPlayer()->GetMap()->Instanceable())
319 return;
320
321 uint32 bindspell = 3286;
322
323 // send spell for homebinding (3286)
324 npc->CastSpell(_player, bindspell, true);
325
327 data << npc->GetGUID();
328 data << uint32(bindspell);
329 SendPacket(&data);
330
332}
@ SMSG_TRAINER_BUY_SUCCEEDED
Definition Opcodes.h:465

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 
)
822{
823 LOG_DEBUG("network", "{}", add ? "SMSG_CALENDAR_RAID_LOCKOUT_ADDED" : "SMSG_CALENDAR_RAID_LOCKOUT_REMOVED");
824 time_t currTime = GameTime::GetGameTime().count();
825
826 WorldPacket data(SMSG_CALENDAR_RAID_LOCKOUT_REMOVED, (add ? 4 : 0) + 4 + 4 + 4 + 8);
827 if (add)
828 {
830 data.AppendPackedTime(currTime);
831 }
832
833 data << uint32(save->GetMapId());
834 data << uint32(save->GetDifficulty());
835 data << uint32(save->GetResetTime() >= currTime ? save->GetResetTime() - currTime : 0);
836 data << ObjectGuid::Create<HighGuid::Instance>(save->GetInstanceId());
837 SendPacket(&data);
838}
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 
)
841{
842 time_t currTime = GameTime::GetGameTime().count();
843 time_t resetTime = isExtended ? save->GetExtendedResetTime() : save->GetResetTime();
844 time_t resetTimeOp = isExtended ? save->GetResetTime() : save->GetExtendedResetTime();
845 WorldPacket data(SMSG_CALENDAR_RAID_LOCKOUT_UPDATED, 4 + 4 + 4 + 4 + 8);
846 data.AppendPackedTime(currTime);
847 data << uint32(save->GetMapId());
848 data << uint32(save->GetDifficulty());
849 data << uint32(resetTimeOp >= currTime ? resetTimeOp - currTime : resetTimeOp); // pussywizard: old time in secs to reset
850 data << uint32(resetTime >= currTime ? resetTime - currTime : 0); // pussywizard: new time in secs to reset
851 SendPacket(&data);
852}
@ 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)
705{
707 return;
708
709 TradeStatusInfo info;
710 info.Status = status;
711 SendTradeStatus(info);
712}
bool PlayerRecentlyLoggedOut() const
Definition WorldSession.h:452

References PlayerLogout(), PlayerRecentlyLoggedOut(), SendTradeStatus(), and TradeStatusInfo::Status.

Referenced by Player::TradeCancel().

◆ SendCharCreate()

void WorldSession::SendCharCreate ( ResponseCodes  result)
2604{
2606 data << uint8(result);
2607 SendPacket(&data);
2608}
@ 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 
)
2656{
2657 WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1 + 8 + customizeInfo->Name.size() + 1 + 6);
2658 data << uint8(result);
2659 if (result == RESPONSE_SUCCESS)
2660 {
2661 data << customizeInfo->Guid;
2662 data << customizeInfo->Name;
2663 data << uint8(customizeInfo->Gender);
2664 data << uint8(customizeInfo->Skin);
2665 data << uint8(customizeInfo->Face);
2666 data << uint8(customizeInfo->HairStyle);
2667 data << uint8(customizeInfo->HairColor);
2668 data << uint8(customizeInfo->FacialHair);
2669 }
2670 SendPacket(&data);
2671}

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)
2611{
2613 data << uint8(result);
2614 SendPacket(&data);
2615}
@ 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 
)
2637{
2638 WorldPacket data(SMSG_CHAR_FACTION_CHANGE, 1 + 8 + factionChangeInfo->Name.size() + 1 + 7);
2639 data << uint8(result);
2640 if (result == RESPONSE_SUCCESS)
2641 {
2642 data << factionChangeInfo->Guid;
2643 data << factionChangeInfo->Name;
2644 data << uint8(factionChangeInfo->Gender);
2645 data << uint8(factionChangeInfo->Skin);
2646 data << uint8(factionChangeInfo->Face);
2647 data << uint8(factionChangeInfo->HairStyle);
2648 data << uint8(factionChangeInfo->HairColor);
2649 data << uint8(factionChangeInfo->FacialHair);
2650 data << uint8(factionChangeInfo->Race);
2651 }
2652 SendPacket(&data);
2653}
@ 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)
2618{
2620 data << uint8(reason);
2621 SendPacket(&data);
2622};
@ 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 
)
2625{
2626 WorldPacket data(SMSG_CHAR_RENAME, 1 + 8 + renameInfo->Name.size() + 1);
2627 data << uint8(result);
2628 if (result == RESPONSE_SUCCESS)
2629 {
2630 data << renameInfo->Guid;
2631 data << renameInfo->Name;
2632 }
2633 SendPacket(&data);
2634}
@ 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)
835{
837 data << uint8(restriction);
838 SendPacket(&data);
839}
@ SMSG_CHAT_RESTRICTED
Definition Opcodes.h:795

References SendPacket(), and SMSG_CHAT_RESTRICTED.

◆ SendClientCacheVersion()

void WorldSession::SendClientCacheVersion ( uint32  version)
57{
59 data << uint32(version);
60 SendPacket(&data);
61}
@ SMSG_CLIENTCACHE_VERSION
Definition Opcodes.h:1225

References SendPacket(), and SMSG_CLIENTCACHE_VERSION.

Referenced by InitializeSessionCallback().

◆ SendDiscoverNewTaxiNode()

void WorldSession::SendDiscoverNewTaxiNode ( uint32  nodeid)
155{
156 if (GetPlayer()->m_taxi.SetTaximaskNode(nodeid))
157 {
159 SendPacket(&msg);
160
161 sScriptMgr->OnPlayerLearnTaxiNode(GetPlayer(), nodeid);
162 }
163}
@ SMSG_NEW_TAXI_PATH
Definition Opcodes.h:461

References GetPlayer(), SendPacket(), SMSG_NEW_TAXI_PATH, and sScriptMgr.

Referenced by Spell::EffectDiscoverTaxi().

◆ SendDoFlight()

void WorldSession::SendDoFlight ( uint32  mountDisplayId,
uint32  path,
uint32  pathNode = 0 
)
111{
112 // remove fake death
113 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
115
116 while (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE)
118
119 if (mountDisplayId)
120 GetPlayer()->Mount(mountDisplayId);
121
122 if (Creature* critter = ObjectAccessor::GetCreature(*GetPlayer(), GetPlayer()->GetCritterGUID()))
123 critter->DespawnOrUnsummon();
124
125 GetPlayer()->GetMotionMaster()->MoveTaxiFlight(path, pathNode);
126}
void MoveTaxiFlight(uint32 path, uint32 pathnode)
Definition MotionMaster.cpp:923
void Mount(uint32 mount, uint32 vehicleId=0, uint32 creatureEntry=0)
Definition Unit.cpp:10259
Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:234

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 
)
1042{
1044 enchantmentLog.Target = target.WriteAsPacked();
1045 enchantmentLog.Caster = caster.WriteAsPacked();
1046 enchantmentLog.ItemId = itemId;
1047 enchantmentLog.EnchantId = enchantId;
1048 GetPlayer()->SendMessageToSet(enchantmentLog.Write(), true);
1049}
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 
)
1052{
1053 WorldPackets::Item::ItemEnchantTimeUpdate itemEnchantTimeUpdate;
1054 itemEnchantTimeUpdate.ItemGuid = Itemguid;
1055 itemEnchantTimeUpdate.Slot = slot;
1056 itemEnchantTimeUpdate.Duration = Duration;
1057 itemEnchantTimeUpdate.PlayerGuid = Playerguid;
1058 SendPacket(itemEnchantTimeUpdate.Write());
1059}
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)
129{
130 // find current node
131 uint32 curloc = sObjectMgr->GetNearestTaxiNode(*unit, GetPlayer()->GetTeamId(true));
132
133 if (curloc == 0)
134 return true; // `true` send to avoid WorldSession::SendTaxiMenu call with one more curlock seartch with same false result.
135
136 if (GetPlayer()->m_taxi.SetTaximaskNode(curloc))
137 {
139 SendPacket(&msg);
140
142 update << unit->GetGUID();
143 update << uint8(1);
144 SendPacket(&update);
145
146 sScriptMgr->OnPlayerLearnTaxiNode(GetPlayer(), curloc);
147
148 return true;
149 }
150 else
151 return false;
152}
@ SMSG_TAXINODE_STATUS
Definition Opcodes.h:457

References Object::GetGUID(), GetPlayer(), GetTeamId(), SendPacket(), SMSG_NEW_TAXI_PATH, SMSG_TAXINODE_STATUS, sObjectMgr, and sScriptMgr.

Referenced by HandleTaxiQueryAvailableNodes().

◆ SendLfgBootProposalUpdate()

void WorldSession::SendLfgBootProposalUpdate ( lfg::LfgPlayerBoot const &  boot)
514{
515 ObjectGuid guid = GetPlayer()->GetGUID();
516 lfg::LfgAnswer playerVote = boot.votes.find(guid)->second;
517 uint8 votesNum = 0;
518 uint8 agreeNum = 0;
519 uint32 secsleft = boot.cancelTime - GameTime::GetGameTime().count();
520 for (lfg::LfgAnswerContainer::const_iterator it = boot.votes.begin(); it != boot.votes.end(); ++it)
521 {
522 if (it->second != lfg::LFG_ANSWER_PENDING)
523 {
524 ++votesNum;
525 if (it->second == lfg::LFG_ANSWER_AGREE)
526 ++agreeNum;
527 }
528 }
529 LOG_DEBUG("network", "SMSG_LFG_BOOT_PROPOSAL_UPDATE [{}] inProgress: {} - didVote: {} - agree: {} - victim: [{}] votes: {} - agrees: {} - left: {} - needed: {} - reason {}",
530 guid.ToString(), uint8(boot.inProgress), uint8(playerVote != lfg::LFG_ANSWER_PENDING), uint8(playerVote == lfg::LFG_ANSWER_AGREE),
531 boot.victim.ToString(), votesNum, agreeNum, secsleft, lfg::LFG_GROUP_KICK_VOTES_NEEDED, boot.reason);
532 WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + boot.reason.length());
533 data << uint8(boot.inProgress); // Vote in progress
534 data << uint8(playerVote != lfg::LFG_ANSWER_PENDING); // Did Vote
535 data << uint8(playerVote == lfg::LFG_ANSWER_AGREE); // Agree
536 data << boot.victim; // Victim GUID
537 data << uint32(votesNum); // Total Votes
538 data << uint32(agreeNum); // Agree Count
539 data << uint32(secsleft); // Time Left
540 data << uint32(lfg::LFG_GROUP_KICK_VOTES_NEEDED); // Needed Votes
541 data << boot.reason.c_str(); // Kick reason
542 SendPacket(&data);
543}
@ SMSG_LFG_BOOT_PROPOSAL_UPDATE
Definition Opcodes.h:907
@ LFG_GROUP_KICK_VOTES_NEEDED
Definition LFGMgr.h:56
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 ( )
622{
623 LOG_DEBUG("network", "SMSG_LFG_DISABLED [{}]", GetPlayer()->GetGUID().ToString());
625 SendPacket(&data);
626}
@ SMSG_LFG_DISABLED
Definition Opcodes.h:950

References GetPlayer(), LOG_DEBUG, SendPacket(), and SMSG_LFG_DISABLED.

◆ SendLfgJoinResult()

void WorldSession::SendLfgJoinResult ( lfg::LfgJoinResultData const &  joinData)
442{
443 uint32 size = 0;
444 for (lfg::LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it)
445 size += 8 + 4 + uint32(it->second.size()) * (4 + 4);
446
447 LOG_DEBUG("network", "SMSG_LFG_JOIN_RESULT [{}] checkResult: {} checkValue: {}", GetPlayer()->GetGUID().ToString(), joinData.result, joinData.state);
448 WorldPacket data(SMSG_LFG_JOIN_RESULT, 4 + 4 + size);
449 data << uint32(joinData.result); // Check Result
450 data << uint32(joinData.state); // Check Value
451 if (!joinData.lockmap.empty())
452 BuildPartyLockDungeonBlock(data, joinData.lockmap);
453 SendPacket(&data);
454}
@ 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)
614{
615 LOG_DEBUG("network", "SMSG_LFG_LFR_LIST [{}] update: {}", GetPlayer()->GetGUID().ToString(), update ? 1 : 0);
617 data << uint8(update); // In Lfg Queue?
618 SendPacket(&data);
619}
@ 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)
629{
630 LOG_DEBUG("network", "SMSG_LFG_OFFER_CONTINUE [{}] dungeon entry: {}", GetPlayer()->GetGUID().ToString(), dungeonEntry);
632 data << uint32(dungeonEntry);
633 SendPacket(&data);
634}
@ 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)
476{
477 if (!rewardData.rdungeonEntry || !rewardData.sdungeonEntry || !rewardData.quest)
478 return;
479
480 LOG_DEBUG("lfg", "SMSG_LFG_PLAYER_REWARD {} rdungeonEntry: {}, sdungeonEntry: {}, done: {}",
481 GetPlayerInfo(), rewardData.rdungeonEntry, rewardData.sdungeonEntry, rewardData.done);
482
483 uint8 itemNum = rewardData.quest->GetRewItemsCount();
484
485 uint8 playerLevel = GetPlayer() ? GetPlayer()->GetLevel() : 0;
486 uint8 playerLevelForXP = playerLevel;
487 sScriptMgr->OnPlayerBeforeGetLevelForXPGain(GetPlayer(), playerLevelForXP);
488
489 WorldPacket data(SMSG_LFG_PLAYER_REWARD, 4 + 4 + 1 + 4 + 4 + 4 + 4 + 4 + 1 + itemNum * (4 + 4 + 4));
490 data << uint32(rewardData.rdungeonEntry); // Random Dungeon Finished
491 data << uint32(rewardData.sdungeonEntry); // Dungeon Finished
492 data << uint8(rewardData.done);
493 data << uint32(1);
494 data << uint32(rewardData.quest->GetRewOrReqMoney(playerLevel));
495 data << uint32(rewardData.quest->XPValue(playerLevelForXP));
496 data << uint32(0);
497 data << uint32(0);
498 data << uint8(itemNum);
499 if (itemNum)
500 {
501 for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
502 if (uint32 itemId = rewardData.quest->RewardItemId[i])
503 {
504 ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId);
505 data << uint32(itemId);
506 data << uint32(item ? item->DisplayInfoID : 0);
507 data << uint32(rewardData.quest->RewardItemIdCount[i]);
508 }
509 }
510 SendPacket(&data);
511}
@ 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, sScriptMgr, and Quest::XPValue().

Referenced by lfg::LFGMgr::FinishDungeon().

◆ SendLfgQueueStatus()

void WorldSession::SendLfgQueueStatus ( lfg::LfgQueueStatusData const &  queueData)
457{
458 LOG_DEBUG("network", "SMSG_LFG_QUEUE_STATUS [{}] dungeon: {} - waitTime: {} - avgWaitTime: {} - waitTimeTanks: {} - waitTimeHealer: {} - waitTimeDps: {} - queuedTime: {} - tanks: {} - healers: {} - dps: {}",
459 GetPlayer()->GetGUID().ToString(), queueData.dungeonId, queueData.waitTime, queueData.waitTimeAvg, queueData.waitTimeTank,
460 queueData.waitTimeHealer, queueData.waitTimeDps, queueData.queuedTime, queueData.tanks, queueData.healers, queueData.dps);
461 WorldPacket data(SMSG_LFG_QUEUE_STATUS, 4 + 4 + 4 + 4 + 4 + 4 + 1 + 1 + 1 + 4);
462 data << uint32(queueData.dungeonId); // Dungeon
463 data << int32(queueData.waitTimeAvg); // Average Wait time
464 data << int32(queueData.waitTime); // Wait Time
465 data << int32(queueData.waitTimeTank); // Wait Tanks
466 data << int32(queueData.waitTimeHealer); // Wait Healers
467 data << int32(queueData.waitTimeDps); // Wait Dps
468 data << uint8(queueData.tanks); // Tanks needed
469 data << uint8(queueData.healers); // Healers needed
470 data << uint8(queueData.dps); // Dps needed
471 data << uint32(queueData.queuedTime); // Player wait time in queue
472 SendPacket(&data);
473}
@ 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)
395{
396 lfg::LfgDungeonSet dungeons;
397 if (roleCheck.rDungeonId)
398 dungeons.insert(roleCheck.rDungeonId);
399 else
400 dungeons = roleCheck.dungeons;
401
402 LOG_DEBUG("network", "SMSG_LFG_ROLE_CHECK_UPDATE [{}]", GetPlayer()->GetGUID().ToString());
403 WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + dungeons.size() * 4 + 1 + roleCheck.roles.size() * (8 + 1 + 4 + 1));
404
405 data << uint32(roleCheck.state); // Check result
406 data << uint8(roleCheck.state == lfg::LFG_ROLECHECK_INITIALITING);
407 data << uint8(dungeons.size()); // Number of dungeons
408 if (!dungeons.empty())
409 for (lfg::LfgDungeonSet::iterator it = dungeons.begin(); it != dungeons.end(); ++it)
410 data << uint32(sLFGMgr->GetLFGDungeonEntry(*it)); // Dungeon
411
412 data << uint8(roleCheck.roles.size()); // Players in group
413 if (!roleCheck.roles.empty())
414 {
415 // Leader info MUST be sent 1st :S
416 ObjectGuid guid = roleCheck.leader;
417 uint8 roles = roleCheck.roles.find(guid)->second;
418 data << guid; // Guid
419 data << uint8(roles > 0); // Ready
420 data << uint32(roles); // Roles
422 data << uint8(player ? player->GetLevel() : 0); // Level
423
424 for (lfg::LfgRolesMap::const_iterator it = roleCheck.roles.begin(); it != roleCheck.roles.end(); ++it)
425 {
426 if (it->first == roleCheck.leader)
427 continue;
428
429 guid = it->first;
430 roles = it->second;
431 data << guid; // Guid
432 data << uint8(roles > 0); // Ready
433 data << uint32(roles); // Roles
435 data << uint8(player ? player->GetLevel() : 0);// Level
436 }
437 }
438 SendPacket(&data);
439}
@ SMSG_LFG_ROLE_CHECK_UPDATE
Definition Opcodes.h:897
@ LFG_ROLECHECK_INITIALITING
Definition LFGMgr.h:127

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 
)
384{
385 LOG_DEBUG("network", "SMSG_LFG_ROLE_CHOSEN [{}] guid: [{}] roles: {}", GetPlayer()->GetGUID().ToString(), guid.ToString(), roles);
386
387 WorldPacket data(SMSG_LFG_ROLE_CHOSEN, 8 + 1 + 4);
388 data << guid; // Guid
389 data << uint8(roles > 0); // Ready
390 data << uint32(roles); // Roles
391 SendPacket(&data);
392}
@ 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)
637{
638 LOG_DEBUG("network", "SMSG_LFG_TELEPORT_DENIED [{}] reason: {}", GetPlayer()->GetGUID().ToString(), err);
640 data << uint32(err); // Error
641 SendPacket(&data);
642}
@ 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)
340{
341 bool join = false;
342 bool queued = false;
343 uint8 size = uint8(updateData.dungeons.size());
344
345 switch (updateData.updateType)
346 {
347 case lfg::LFG_UPDATETYPE_ADDED_TO_QUEUE: // Rolecheck Success
348 queued = true;
349 [[fallthrough]];
351 join = true;
352 break;
354 join = updateData.state != lfg::LFG_STATE_ROLECHECK && updateData.state != lfg::LFG_STATE_NONE;
355 queued = updateData.state == lfg::LFG_STATE_QUEUED;
356 break;
357 default:
358 break;
359 }
360
361 LOG_DEBUG("lfg", "SMSG_LFG_UPDATE_PARTY {} updatetype: {}",
362 GetPlayerInfo(), updateData.updateType);
363 WorldPacket data(SMSG_LFG_UPDATE_PARTY, 1 + 1 + (size > 0 ? 1 : 0) * (1 + 1 + 1 + 1 + 1 + size * 4 + updateData.comment.length()));
364 data << uint8(updateData.updateType); // Lfg Update type
365 data << uint8(size > 0); // Extra info
366 if (size)
367 {
368 data << uint8(join); // LFG Join
369 data << uint8(queued); // Join the queue
370 data << uint8(0); // unk - Always 0
371 data << uint8(0); // unk - Always 0
372 for (uint8 i = 0; i < 3; ++i)
373 data << uint8(0); // unk - Always 0
374
375 data << uint8(size);
376 for (lfg::LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it)
377 data << uint32(*it);
378 data << updateData.comment;
379 }
380 SendPacket(&data);
381}
@ 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)
303{
304 bool queued = false;
305 uint8 size = uint8(updateData.dungeons.size());
306
307 switch (updateData.updateType)
308 {
311 queued = true;
312 break;
314 queued = updateData.state == lfg::LFG_STATE_QUEUED;
315 break;
316 default:
317 break;
318 }
319
320 LOG_DEBUG("lfg", "SMSG_LFG_UPDATE_PLAYER {} updatetype: {}",
321 GetPlayerInfo(), updateData.updateType);
322 WorldPacket data(SMSG_LFG_UPDATE_PLAYER, 1 + 1 + (size > 0 ? 1 : 0) * (1 + 1 + 1 + 1 + size * 4 + updateData.comment.length()));
323 data << uint8(updateData.updateType); // Lfg Update type
324 data << uint8(size > 0); // Extra info
325 if (size)
326 {
327 data << uint8(queued); // Join the queue
328 data << uint8(0); // unk - Always 0
329 data << uint8(0); // unk - Always 0
330
331 data << uint8(size);
332 for (lfg::LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it)
333 data << uint32(*it);
334 data << updateData.comment;
335 }
336 SendPacket(&data);
337}
@ 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)
546{
547 ObjectGuid guid = GetPlayer()->GetGUID();
548 ObjectGuid gguid = proposal.players.find(guid)->second.group;
549 bool silent = !proposal.isNew && gguid == proposal.group;
550 uint32 dungeonEntry = proposal.dungeonId;
551
552 LOG_DEBUG("network", "SMSG_LFG_PROPOSAL_UPDATE [{} state: {}", guid.ToString(), proposal.state);
553
554 // show random dungeon if player selected random dungeon and it's not lfg group
555 if (!silent)
556 {
557 lfg::LfgDungeonSet const& playerDungeons = sLFGMgr->GetSelectedDungeons(guid);
558 if (playerDungeons.find(proposal.dungeonId) == playerDungeons.end())
559 dungeonEntry = (*playerDungeons.begin());
560 }
561
562 dungeonEntry = sLFGMgr->GetLFGDungeonEntry(dungeonEntry);
563
564 WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + proposal.players.size() * (4 + 1 + 1 + 1 + 1 + 1));
565 data << uint32(dungeonEntry); // Dungeon
566 data << uint8(proposal.state); // Proposal state
567 data << uint32(proposal.id); // Proposal ID
568 data << uint32(proposal.encounters); // encounters done
569 data << uint8(silent); // Show proposal window
570 data << uint8(proposal.players.size()); // Group size
571
572 // Sort by roles: tank, healer, dps
573 std::vector<ObjectGuid> ordered;
574 ordered.reserve(proposal.players.size());
575
576 std::vector<ObjectGuid> tanks, healers, dps;
577
578 for (auto const& [pguid, player] : proposal.players)
579 {
580 if (player.role & lfg::PLAYER_ROLE_TANK)
581 tanks.push_back(pguid);
582 else if (player.role & lfg::PLAYER_ROLE_HEALER)
583 healers.push_back(pguid);
584 else
585 dps.push_back(pguid);
586 }
587
588 ordered.insert(ordered.end(), tanks.begin(), tanks.end());
589 ordered.insert(ordered.end(), healers.begin(), healers.end());
590 ordered.insert(ordered.end(), dps.begin(), dps.end());
591
592 for (auto const& pguid : ordered)
593 {
594 lfg::LfgProposalPlayer const& player = proposal.players.find(pguid)->second;
595 data << uint32(player.role); // Role
596 data << uint8(pguid == guid); // Self player
597 if (!player.group) // Player not in a group
598 {
599 data << uint8(0); // Not in dungeon
600 data << uint8(0); // Not same group
601 }
602 else
603 {
604 data << uint8(player.group == proposal.group); // In dungeon (silent)
605 data << uint8(player.group == gguid); // Same Group than player
606 }
607 data << uint8(player.accept != lfg::LFG_ANSWER_PENDING);// Answered
608 data << uint8(player.accept == lfg::LFG_ANSWER_AGREE); // Accepted
609 }
610 SendPacket(&data);
611}
@ SMSG_LFG_PROPOSAL_UPDATE
Definition Opcodes.h:895
@ PLAYER_ROLE_TANK
Definition LFG.h:41
@ PLAYER_ROLE_HEALER
Definition LFG.h:42
Definition LFGMgr.h:347
uint8 role
Proposed role.
Definition LFGMgr.h:349
ObjectGuid group
Original group guid. 0 if no original group.
Definition LFGMgr.h:351
LfgAnswer accept
Accept status (-1 not answer | 0 Not agree | 1 agree)
Definition LFGMgr.h:350

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::PLAYER_ROLE_HEALER, lfg::PLAYER_ROLE_TANK, 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 
)
855{
856 LOG_DEBUG("network", "WORLD: Sent SMSG_LIST_INVENTORY");
857
858 sScriptMgr->OnPlayerSendListInventory(GetPlayer(), vendorGuid, vendorEntry);
859
861 if (!vendor)
862 {
863 LOG_DEBUG("network", "WORLD: SendListInventory - Unit ({}) not found or you can not interact with him.", vendorGuid.ToString());
865 return;
866 }
867
868 // remove fake death
869 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
870 {
872 }
873
875
876 // Update home position for patrolling NPCs only (prevents drift for stationary NPCs)
879 vendor->SetHomePosition(vendor->GetPosition());
880
881 SetCurrentVendor(vendorEntry);
882
883 VendorItemData const* items = vendorEntry ? sObjectMgr->GetNpcVendorItemList(vendorEntry) : vendor->GetVendorItems();
884 if (!items)
885 {
886 WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + 1);
887 data << vendorGuid;
888 data << uint8(0); // count == 0, next will be error code
889 data << uint8(0); // "Vendor has no inventory"
890 SendPacket(&data);
891 return;
892 }
893
894 uint8 itemCount = items->GetItemCount();
895 uint8 count = 0;
896
897 WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + itemCount * 8 * 4);
898 data << vendorGuid;
899
900 std::size_t countPos = data.wpos();
901 data << uint8(count);
902
903 float discountMod = _player->GetReputationPriceDiscount(vendor);
904
905 for (uint8 slot = 0; slot < itemCount; ++slot)
906 {
907 if (VendorItem const* item = items->GetItem(slot))
908 {
909 if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(item->item))
910 {
911 if (!(itemTemplate->AllowableClass & _player->getClassMask()) && itemTemplate->Bonding == BIND_WHEN_PICKED_UP && !_player->IsGameMaster())
912 {
913 continue;
914 }
915 // Only display items in vendor lists for the team the
916 // player is on. If GM on, display all items.
917 if (!_player->IsGameMaster() && ((itemTemplate->HasFlag2(ITEM_FLAG2_FACTION_HORDE) && _player->GetTeamId() == TEAM_ALLIANCE) || (itemTemplate->HasFlag2(ITEM_FLAG2_FACTION_ALLIANCE) && _player->GetTeamId() == TEAM_HORDE)))
918 {
919 continue;
920 }
921
922 // Items sold out are not displayed in list
923 uint32 leftInStock = !item->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(item);
924 if (!_player->IsGameMaster() && !leftInStock)
925 {
926 continue;
927 }
928
929 ConditionList conditions = sConditionMgr->GetConditionsForNpcVendorEvent(vendor->GetEntry(), item->item);
930 if (!sConditionMgr->IsObjectMeetToConditions(_player, vendor, conditions))
931 {
932 LOG_DEBUG("network", "SendListInventory: conditions not met for creature entry {} item {}", vendor->GetEntry(), item->item);
933 continue;
934 }
935
936 // reputation discount
937 int32 price = item->IsGoldRequired(itemTemplate) ? uint32(std::floor(itemTemplate->BuyPrice * discountMod)) : 0;
938
939 data << uint32(slot + 1); // client expects counting to start at 1
940 data << uint32(item->item);
941 data << uint32(itemTemplate->DisplayInfoID);
942 data << int32(leftInStock);
943 data << uint32(price);
944 data << uint32(itemTemplate->MaxDurability);
945 data << uint32(itemTemplate->BuyCount);
946 data << uint32(item->ExtendedCost);
947
948 if (++count >= MAX_VENDOR_ITEMS)
949 {
950 break;
951 }
952 }
953 }
954 }
955
956 if (count == 0)
957 {
958 data << uint8(0);
959 SendPacket(&data);
960 return;
961 }
962
963 data.put<uint8>(countPos, count);
964 SendPacket(&data);
965}
#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:3249
uint32 GetVendorItemCurrentCount(VendorItem const *vItem)
Definition Creature.cpp:3254
void SetCurrentVendor(uint32 vendorEntry)
Definition WorldSession.h:508
@ SMSG_LIST_INVENTORY
Definition Opcodes.h:445
Definition CreatureData.h:460
VendorItem * GetItem(uint32 slot) const
Definition CreatureData.h:463
uint8 GetItemCount() const
Definition CreatureData.h:471
Definition CreatureData.h:445

References _player, BIND_WHEN_PICKED_UP, ObjectGuid::Empty, Unit::getClassMask(), MotionMaster::GetCurrentMovementGeneratorType(), Creature::GetDefaultMovementType(), Object::GetEntry(), VendorItemData::GetItem(), VendorItemData::GetItemCount(), Unit::GetMotionMaster(), 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, Creature::PauseMovementForInteraction(), 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, WAYPOINT_MOTION_TYPE, and ByteBuffer::wpos().

Referenced by HandleListInventoryOpcode(), npc_pet_gen_argent_pony_bridle::OnGossipSelect(), npc_wg_quest_giver::OnGossipSelect(), npc_innkeeper::OnGossipSelect(), Player::OnGossipSelect(), npc_prof_alchemy::SendActionMenu(), npc_prof_blacksmith::SendActionMenu(), and npc_prof_tailor::SendActionMenu().

◆ SendMailList()

void WorldSession::SendMailList ( )
699{
700 Player* player = _player;
701
702 uint8 mailsCount = 0;
703 uint32 realCount = 0;
704
705 WorldPacket data(SMSG_MAIL_LIST_RESULT, (200)); // guess size
706 data << uint32(0); // real mail's count
707 data << uint8(0); // mail's count
708 time_t cur_time = GameTime::GetGameTime().count();
709
710 for (Mail const* mail : player->GetMails())
711 {
712 // prevent client storage overflow
713 if (mailsCount >= MAX_INBOX_CLIENT_CAPACITY)
714 {
715 ++realCount;
716 continue;
717 }
718
719 // skip deleted or not delivered (deliver delay not expired) mails
720 if (mail->state == MAIL_STATE_DELETED || cur_time < mail->deliver_time || cur_time > mail->expire_time)
721 {
722 continue;
723 }
724
725 uint8 item_count = uint8(mail->items.size()); // max count is MAX_MAIL_ITEMS (12)
726
727 // prevent client crash
728 std::string subject = mail->subject;
729 std::string body = mail->body;
730
731 if (subject.find("| |") != std::string::npos)
732 {
733 subject = "";
734 }
735 if (body.find("| |") != std::string::npos)
736 {
737 body = "";
738 }
739
740 // Declared length of this entry. Must match the bytes written below: the uint16 size itself,
741 // uint32 id, uint8 type, the sender as a guid or an entry, six uint32 fields and one float,
742 // both null terminated strings, the uint8 item count and the items. The strings are measured
743 // after sanitisation, because the sanitised ones are what gets written
744 std::size_t const sender_size = mail->messageType == MAIL_NORMAL ? 8 : 4;
745 std::size_t const item_size = 1 + 4 + 4 + MAX_INSPECTED_ENCHANTMENT_SLOT * 3 * 4 + 4 + 4 + 4 + 4 + 4 + 4 + 1;
746 std::size_t next_mail_size = 2 + 4 + 1 + sender_size + 7 * 4
747 + (subject.size() + 1) + (body.size() + 1) + 1 + item_count * item_size;
748
749 if (data.wpos() + next_mail_size > MAX_NETCLIENT_PACKET_SIZE)
750 {
751 ++realCount;
752 continue;
753 }
754
755 data << uint16(next_mail_size); // Message size
756 data << uint32(mail->messageID); // Message ID
757 data << uint8(mail->messageType); // Message Type
758
759 switch (mail->messageType)
760 {
761 case MAIL_NORMAL: // sender guid
762 data << ObjectGuid::Create<HighGuid::Player>(mail->sender);
763 break;
764 case MAIL_CREATURE:
765 case MAIL_GAMEOBJECT:
766 case MAIL_AUCTION:
767 case MAIL_CALENDAR:
768 data << uint32(mail->sender); // creature/gameobject entry, auction id, calendar event id?
769 break;
770 }
771
772 data << uint32(mail->COD); // COD
773 data << uint32(0); // probably changed in 3.3.3
774 data << uint32(mail->stationery); // stationery (Stationery.dbc)
775 data << uint32(mail->money); // Gold
776 data << uint32(mail->checked); // flags
777 data << float(float(mail->expire_time - GameTime::GetGameTime().count()) / DAY); // Time
778 data << uint32(mail->mailTemplateId); // mail template (MailTemplate.dbc)
779 data << subject; // Subject string - once 00, when mail type = 3, max 256
780 data << body; // message? max 8000
781 data << uint8(item_count); // client limit is 0x10
782
783 for (uint8 i = 0; i < item_count; ++i)
784 {
785 Item* item = player->GetMItem(mail->items[i].item_guid);
786 // item index (0-6?)
787 data << uint8(i);
788 // item guid low?
789 data << uint32((item ? item->GetGUID().GetCounter() : 0));
790 // entry
791 data << uint32((item ? item->GetEntry() : 0));
792 for (uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j)
793 {
794 data << uint32(item ? item->GetEnchantmentId(EnchantmentSlot(j)) : 0);
795 data << uint32(item ? item->GetEnchantmentDuration(EnchantmentSlot(j)) : 0);
796 data << uint32(item ? item->GetEnchantmentCharges(EnchantmentSlot(j)) : 0);
797 }
798 // can be negative
799 data << int32((item ? item->GetItemRandomPropertyId() : 0));
800 // unk
801 data << uint32((item ? item->GetItemSuffixFactor() : 0));
802 // stack count
803 data << uint32((item ? item->GetCount() : 0));
804 // charges
805 data << uint32((item ? item->GetSpellCharges() : 0));
806 // durability
807 data << uint32((item ? item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY) : 0));
808 // durability
809 data << uint32((item ? item->GetUInt32Value(ITEM_FIELD_DURABILITY) : 0));
810 // unknown wotlk
811 data << uint8(0);
812 }
813
814 ++realCount;
815 ++mailsCount;
816 }
817
818 data.put<uint32>(0, realCount); // this will display warning about undelivered mail to player if realCount > mailsCount
819 data.put<uint8>(4, mailsCount); // set real send mails to client
820 SendPacket(&data);
821}
#define MAX_NETCLIENT_PACKET_SIZE
Definition Common.h:43
@ MAX_INSPECTED_ENCHANTMENT_SLOT
Definition Item.h:176
#define MAX_INBOX_CLIENT_CAPACITY
Definition MailHandler.cpp:37
@ MAIL_AUCTION
Definition Mail.h:38
@ MAIL_GAMEOBJECT
Definition Mail.h:40
@ MAIL_CREATURE
Definition Mail.h:39
@ MAIL_CALENDAR
Definition Mail.h:41
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
@ SMSG_MAIL_LIST_RESULT
Definition Opcodes.h:601

References _player, 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, and ByteBuffer::wpos().

Referenced by HandleGetMailList(), and Player::SendNewMail().

◆ 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:2553
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.

309{
310 sScriptMgr->OnPacketSent(this, *packet);
311
312 if (!m_Socket)
313 return;
314
315#if defined(ACORE_DEBUG)
316 // Code for network use statistic
317 static uint64 sendPacketCount = 0;
318 static uint64 sendPacketBytes = 0;
319
320 static time_t firstTime = GameTime::GetGameTime().count();
321 static time_t lastTime = firstTime; // next 60 secs start time
322
323 static uint64 sendLastPacketCount = 0;
324 static uint64 sendLastPacketBytes = 0;
325
326 time_t cur_time = GameTime::GetGameTime().count();
327
328 if ((cur_time - lastTime) < 60)
329 {
330 sendPacketCount += 1;
331 sendPacketBytes += packet->size();
332
333 sendLastPacketCount += 1;
334 sendLastPacketBytes += packet->size();
335 }
336 else
337 {
338 uint64 minTime = uint64(cur_time - lastTime);
339 uint64 fullTime = uint64(lastTime - firstTime);
340
341 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));
342
343 LOG_DEBUG("network", "Send last min packets count: {} bytes: {} avr.count/sec: {} avr.bytes/sec: {}", sendLastPacketCount, sendLastPacketBytes, float(sendLastPacketCount) / minTime, float(sendLastPacketBytes) / minTime);
344
345 lastTime = cur_time;
346 sendLastPacketCount = 1;
347 sendLastPacketBytes = packet->wpos(); // wpos is real written size
348 }
349#endif // !ACORE_DEBUG
350
351 if (!sScriptMgr->CanPacketSend(this, *packet))
352 {
353 return;
354 }
355
356 m_Socket->SendPacket(*packet);
357}

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(), HandleGMResponseResolve(), HandleGMTicketCreateOpcode(), HandleGMTicketDeleteOpcode(), HandleGMTicketSystemStatusOpcode(), HandleGMTicketUpdateOpcode(), HandleGrantLevel(), HandleInspectHonorStatsOpcode(), HandleInspectOpcode(), HandleItemNameQueryOpcode(), HandleItemQuerySingleOpcode(), HandleItemTextQuery(), HandleLfgPartyLockInfoRequestOpcode(), HandleLfgPlayerLockInfoRequestOpcode(), HandleLogoutCancelOpcode(), HandleLogoutRequestOpcode(), HandleLootMoneyOpcode(), HandleMessagechatOpcode(), HandleMirrorImageDataRequest(), HandleNpcTextQueryOpcode(), HandlePageTextQueryOpcode(), HandlePetitionRenameOpcode(), HandlePetitionShowSignOpcode(), HandlePetitionSignOpcode(), HandlePlayedTime(), HandlePlayerLoginFromDB(), HandlePlayerLoginToCharInWorld(), HandlePVPLogDataOpcode(), Guild::HandleQuery(), HandleQueryNextMailTime(), HandleQueryQuestsCompleted(), HandleQuestPOIQuery(), HandleReadItem(), HandleRealmSplitOpcode(), HandleRequestAccountData(), HandleRequestPartyMemberStatsOpcode(), Guild::HandleRoster(), HandleTalentWipeConfirmOpcode(), HandleTC9PrepareForRedirect(), HandleTurnInPetitionOpcode(), HandleUpdateAccountData(), HandleWhoisOpcode(), HandleWhoOpcode(), HandleWorldStateUITimerUpdate(), WardenWin::InitializeModule(), ArenaTeam::Inspect(), LogoutPlayer(), ArenaTeam::MassInviteToEvent(), Guild::MassInviteToEvent(), ArenaTeam::Query(), Group::RemoveMember(), WardenMac::RequestChecks(), WardenWin::RequestChecks(), WardenMac::RequestHash(), WardenWin::RequestHash(), Warden::RequestModule(), ArenaTeam::Roster(), AddonChannelCommandHandler::Send(), SendAccountDataTimes(), SendActivateTaxiReply(), SendAddonsInfo(), SendAreaTriggerMessage(), SendArenaTeamCommandResult(), 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(), PlayerMenu::SendGossipMenu(), Guild::SendInfo(), SendItemEnchantTimeUpdate(), SendLearnNewTaxiNode(), SendLfgBootProposalUpdate(), SendLfgDisabled(), SendLfgJoinResult(), SendLfgLfrList(), SendLfgOfferContinue(), SendLfgPlayerReward(), SendLfgQueueStatus(), SendLfgRoleCheckUpdate(), SendLfgRoleChosen(), SendLfgTeleportError(), SendLfgUpdateParty(), SendLfgUpdatePlayer(), SendLfgUpdateProposal(), SendListInventory(), Guild::SendLoginInfo(), SendMailList(), Warden::SendModuleToClient(), Guild::SendMoneyInfo(), Unit::SendMoveRoot(), SendNameQueryOpcode(), ChatHandler::SendNotification(), SendNotInArenaTeamPacket(), SendPartyResult(), Guild::SendPermissions(), SendPetitionQueryOpcode(), SendPetitionShowList(), SendPetNameInvalid(), SendPetNameQuery(), SendPlayerAmbiguousNotice(), SendPlayerNotFoundNotice(), SendPlayTimeWarning(), PlayerMenu::SendPointOfInterest(), PlayerMenu::SendQuestGiverOfferReward(), PlayerMenu::SendQuestGiverQuestDetails(), PlayerMenu::SendQuestGiverQuestList(), PlayerMenu::SendQuestGiverRequestItems(), PlayerMenu::SendQuestGiverStatus(), PlayerMenu::SendQuestQueryResponse(), GmTicket::SendResponse(), Guild::SendSaveEmblemResult(), SendSetPhaseShift(), SendSetPlayerDeclinedNamesResult(), SendShowBank(), SendShowMailBox(), Unit::SendSpeedToController(), SendStablePet(), SendStableResult(), ArenaTeam::SendStats(), ChatHandler::SendSysMessage(), SendTabardVendorActivate(), Group::SendTargetIconList(), SendTaxiMenu(), SendTaxiStatus(), Guild::BankTab::SendText(), TicketMgr::SendTicket(), SendTimeQueryResponse(), SendTimeSync(), SendTradeStatus(), SendTutorialsData(), SendUpdateTrade(), ChatHandler::SendWorldText(), and SendWrongFactionNotice().

◆ 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)
289{
290 Petition const* petition = sPetitionMgr->GetPetition(petitionguid);
291 if (!petition)
292 {
293 LOG_DEBUG("network", "CMSG_PETITION_QUERY failed for petition ({})", petitionguid.ToString());
294 return;
295 }
296
297 uint8 type = petition->petitionType;
298 WorldPacket data(SMSG_PETITION_QUERY_RESPONSE, (4 + 8 + petition->petitionName.size() + 1 + 1 + 4 * 12 + 2 + 10));
299 data << uint32(petition->petitionId); // guild/team id (was item low guid)
300 data << petition->ownerGuid; // charter owner guid
301 data << petition->petitionName; // name (guild/arena team)
302 data << uint8(0); // some string
303 if (type == GUILD_CHARTER_TYPE)
304 {
305 uint32 needed = sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS);
306 data << uint32(needed);
307 data << uint32(needed);
308 data << uint32(0); // bypass client - side limitation, a different value is needed here for each petition
309 }
310 else
311 {
312 data << uint32(type - 1);
313 data << uint32(type - 1);
314 data << uint32(type); // bypass client - side limitation, a different value is needed here for each petition
315 }
316 data << uint32(0); // 5
317 data << uint32(0); // 6
318 data << uint32(0); // 7
319 data << uint32(0); // 8
320 data << uint16(0); // 9 2 bytes field
321 data << uint32(0); // 10
322 data << uint32(0); // 11
323 data << uint32(0); // 13 count of next strings?
324
325 for (int i = 0; i < 10; ++i)
326 data << uint8(0); // some string
327
328 data << uint32(0); // 14
329
330 data << uint32(type != GUILD_CHARTER_TYPE); // 15 0 - guild, 1 - arena team
331
332 SendPacket(&data);
333}
@ 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)
849{
851 if (!creature)
852 {
853 LOG_DEBUG("network", "WORLD: HandlePetitionShowListOpcode - Unit ({}) not found or you can't interact with him.", guid.ToString());
854 return;
855 }
856
857 WorldPacket data(SMSG_PETITION_SHOWLIST, 8 + 1 + 4 * 6);
858 data << guid; // npc guid
859
860 // For guild default
861 uint32 CharterEntry = GUILD_CHARTER;
862 uint32 CharterDispayID = CHARTER_DISPLAY_ID;
863 uint32 CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD);
864
865 if (creature->IsTabardDesigner())
866 {
867 sScriptMgr->OnPlayerPetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
868
869 data << uint8(1); // count
870 data << uint32(1); // index
871 data << CharterEntry; // charter entry
872 data << CharterDispayID; // charter display id
873 data << CharterCost; // charter cost
874 data << uint32(0); // unknown
875 data << uint32(sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS)); // required signs
876 }
877 else
878 {
879 // For 2v2 default
880 CharterEntry = ARENA_TEAM_CHARTER_2v2;
881 CharterDispayID = CHARTER_DISPLAY_ID;
882 CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_2v2);
883
884 // 2v2
885 data << uint8(3); // count
886 sScriptMgr->OnPlayerPetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
887 data << uint32(1); // index
888 data << CharterEntry; // charter entry
889 data << CharterDispayID; // charter display id
890 data << CharterCost; // charter cost
891 data << uint32(2); // unknown
892 data << uint32(2); // required signs?
893
894 // For 3v3 default
895 CharterEntry = ARENA_TEAM_CHARTER_3v3;
896 CharterDispayID = CHARTER_DISPLAY_ID;
897 CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_3v3);
898
899 // 3v3
900 sScriptMgr->OnPlayerPetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
901 data << uint32(2); // index
902 data << CharterEntry; // charter entry
903 data << CharterDispayID; // charter display id
904 data << CharterCost; // charter cost
905 data << uint32(3); // unknown
906 data << uint32(3); // required signs?
907
908 // For 3v3 default
909 CharterEntry = ARENA_TEAM_CHARTER_5v5;
910 CharterDispayID = CHARTER_DISPLAY_ID;
911 CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_5v5);
912
913 // 5v5
914 sScriptMgr->OnPlayerPetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
915 data << uint32(3); // index
916 data << CharterEntry; // charter entry
917 data << CharterDispayID; // charter display id
918 data << CharterCost; // charter cost
919 data << uint32(5); // unknown
920 data << uint32(5); // required signs?
921 }
922
923 SendPacket(&data);
924 LOG_DEBUG("network", "Sent SMSG_PETITION_SHOWLIST");
925}
#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 
)
1113{
1114 WorldPacket data(SMSG_PET_NAME_INVALID, 4 + name.size() + 1 + 1);
1115 data << uint32(error);
1116 data << name;
1117 if (declinedName)
1118 {
1119 data << uint8(1);
1120 for (uint32 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
1121 data << declinedName->name[i];
1122 }
1123 else
1124 data << uint8(0);
1125 SendPacket(&data);
1126}
@ 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 
)
630{
632 if (!pet)
633 {
634 WorldPacket data(SMSG_PET_NAME_QUERY_RESPONSE, (4 + 1 + 4 + 1));
635 data << uint32(petnumber);
636 data << uint8(0);
637 data << uint32(0);
638 data << uint8(0);
639 SendPacket(&data);
640 return;
641 }
642
643 std::string name;
645 {
646 // Use localized creature name for the mage pet
648 if (loc_idx != DEFAULT_LOCALE)
649 name = pet->GetNameForLocaleIdx(loc_idx);
650 else
651 name = pet->GetCreatureTemplate()->Name;
652 }
653 else
654 name = pet->GetName();
655
656 WorldPacket data(SMSG_PET_NAME_QUERY_RESPONSE, (4 + 4 + name.size() + 1));
657 data << uint32(petnumber);
658 data << name.c_str();
660
661 if (pet->IsPet() && ((Pet*)pet)->GetDeclinedNames())
662 {
663 data << uint8(1);
664 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
665 data << ((Pet*)pet)->GetDeclinedNames()->name[i];
666 }
667 else
668 data << uint8(0);
669
670 SendPacket(&data);
671}
@ NPC_WATER_ELEMENTAL_PERM
Definition PetDefines.h:107
std::string const & GetNameForLocaleIdx(LocaleConstant locale_idx) const override
Definition Creature.cpp:3327
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:207
@ 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)
822{
823 WorldPacket data(SMSG_CHAT_PLAYER_AMBIGUOUS, name.size() + 1);
824 data << name;
825 SendPacket(&data);
826}
@ SMSG_CHAT_PLAYER_AMBIGUOUS
Definition Opcodes.h:843

References SendPacket(), and SMSG_CHAT_PLAYER_AMBIGUOUS.

◆ SendPlayerNotFoundNotice()

void WorldSession::SendPlayerNotFoundNotice ( std::string const &  name)
815{
816 WorldPacket data(SMSG_CHAT_PLAYER_NOT_FOUND, name.size() + 1);
817 data << name;
818 SendPacket(&data);
819}
@ SMSG_CHAT_PLAYER_NOT_FOUND
Definition Opcodes.h:711

References SendPacket(), and SMSG_CHAT_PLAYER_NOT_FOUND.

Referenced by HandleMessagechatOpcode().

◆ SendPlayTimeWarning()

void WorldSession::SendPlayTimeWarning ( PlayTimeFlag  flag,
int32  playTimeRemaining 
)
678{
680 playTimeWarning.Flag = flag;
681 playTimeWarning.PlayTimeRemaining = playTimeRemaining;
682 SendPacket(playTimeWarning.Write());
683}
Definition MiscPackets.h:241
int32 PlayTimeRemaining
Definition MiscPackets.h:248
uint32 Flag
Definition MiscPackets.h:247
WorldPacket const * Write() override
Definition MiscPackets.cpp:172

References WorldPackets::Misc::PlayTimeWarning::Flag, WorldPackets::Misc::PlayTimeWarning::PlayTimeRemaining, SendPacket(), and WorldPackets::Misc::PlayTimeWarning::Write().

Referenced by Player::CanRewardQuest(), CheckPlayedTimeLimit(), and HandleLootRoll().

◆ SendSetPhaseShift()

void WorldSession::SendSetPhaseShift ( uint32  phaseShift)
1633{
1635 data << uint32(PhaseShift);
1636 SendPacket(&data);
1637}
@ 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 
)
2674{
2676 data << uint32(result);
2677 data << guid;
2678 SendPacket(&data);
2679}
@ 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)
75{
77 data << guid;
78 SendPacket(&data);
79}
@ 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 ( )
261{
262 _player->ResurrectPlayer(0.5f, true);
263
264 float durabilityLossOnSpiritResurrect = sWorld->getRate(RATE_DURABILITY_LOSS_ON_SPIRIT_RESURRECT) / 100.0f;
265 if (durabilityLossOnSpiritResurrect)
266 _player->DurabilityLossAll(durabilityLossOnSpiritResurrect, true);
267
268 // get corpse nearest graveyard
269 GraveyardStruct const* corpseGrave = nullptr;
270
271 // Search for any graveyards near the player's corpse.
272 corpseGrave = sGraveyard->GetClosestGraveyard(_player, _player->GetTeamId(), _player->HasCorpse());
273
274 // now can spawn bones
276
277 // teleport to nearest from corpse graveyard, if different from nearest to player ghost
278 if (corpseGrave)
279 {
280 GraveyardStruct const* ghostGrave = sGraveyard->GetClosestGraveyard(_player, _player->GetTeamId());
281
282 if (corpseGrave != ghostGrave)
283 _player->TeleportTo(corpseGrave->Map, corpseGrave->x, corpseGrave->y, corpseGrave->z, _player->GetOrientation());
284 // or update at original position
285 //else
286 // _player->UpdateObjectVisibility(); // xinef: not needed, called in ResurrectPlayer
287 }
288 // or update at original position
289 //else
290 // _player->UpdateObjectVisibility(); // xinef: not needed, called in ResurrectPlayer
291}
#define sGraveyard
Definition GameGraveyard.h:76
@ RATE_DURABILITY_LOSS_ON_SPIRIT_RESURRECT
Definition WorldConfig.h:495
void DurabilityLossAll(double percent, bool inventory)
Definition Player.cpp:4804
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

References _player, Player::DurabilityLossAll(), Position::GetOrientation(), Player::GetTeamId(), Player::HasCorpse(), GraveyardStruct::Map, RATE_DURABILITY_LOSS_ON_SPIRIT_RESURRECT, Player::ResurrectPlayer(), sGraveyard, Player::SpawnCorpseBones(), sWorld, Player::TeleportTo(), GraveyardStruct::x, GraveyardStruct::y, and GraveyardStruct::z.

Referenced by HandleSpiritHealerActivateOpcode().

◆ SendStablePet()

void WorldSession::SendStablePet ( ObjectGuid  guid)
356{
357 LOG_DEBUG("network", "WORLD: Recv MSG_LIST_STABLED_PETS Send.");
358
359 WorldPacket data(MSG_LIST_STABLED_PETS, 200); // guess size
360 data << guid;
361 std::size_t wpos = data.wpos();
362 data << uint8(0); // place holder for slot show number
363
364 PetStable* petStable = GetPlayer()->GetPetStable();
365 if (!petStable)
366 {
367 data << uint8(0); // stable slots
368 SendPacket(&data);
369 return;
370 }
371
372 data << uint8(petStable->MaxStabledPets);
373
374 uint8 num = 0; // counter for place holder
375
376 // not let move dead pet in slot
377 if (petStable->CurrentPet)
378 {
379 PetStable::PetInfo const& pet = *petStable->CurrentPet;
380 data << uint32(pet.PetNumber);
381 data << uint32(pet.CreatureId);
382 data << uint32(pet.Level);
383 data << pet.Name; // petname
384 data << uint8(1); // flags: 1 active, 2 inactive
385 ++num;
386 }
387 else
388 {
389 if (PetStable::PetInfo const* pet = petStable->GetUnslottedHunterPet())
390 {
391 data << uint32(pet->PetNumber);
392 data << uint32(pet->CreatureId);
393 data << uint32(pet->Level);
394 data << pet->Name; // petname
395 data << uint8(1); // flags: 1 active, 2 inactive
396 ++num;
397 }
398 }
399
400 for (Optional<PetStable::PetInfo> const& stabledSlot : petStable->StabledPets)
401 {
402 if (stabledSlot)
403 {
404 PetStable::PetInfo const& pet = *stabledSlot;
405 data << uint32(pet.PetNumber);
406 data << uint32(pet.CreatureId);
407 data << uint32(pet.Level);
408 data << pet.Name; // petname
409 data << uint8(2); // flags: 1 active, 2 inactive
410 ++num;
411 }
412 }
413
414 data.put<uint8>(wpos, num); // set real data to placeholder
415 SendPacket(&data);
416}
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)
419{
421 data << uint8(res);
422 SendPacket(&data);
423}
@ 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)
68{
70 data << guid;
71 SendPacket(&data);
72}
@ 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)
86{
87 // find current node
88 uint32 curloc = sObjectMgr->GetNearestTaxiNode(*unit, GetPlayer()->GetTeamId(true));
89
90 if (curloc == 0)
91 return;
92
93 bool lastTaxiCheaterState = GetPlayer()->isTaxiCheater();
94 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.
95
96 LOG_DEBUG("network", "WORLD: CMSG_TAXINODE_STATUS_QUERY {} ", curloc);
97
98 WorldPacket data(SMSG_SHOWTAXINODES, (4 + 8 + 4 + 8 * 4));
99 data << uint32(1);
100 data << unit->GetGUID();
101 data << uint32(curloc);
102 GetPlayer()->m_taxi.AppendTaximaskTo(data, GetPlayer()->isTaxiCheater());
103 SendPacket(&data);
104
105 LOG_DEBUG("network", "WORLD: Sent SMSG_SHOWTAXINODES");
106
107 GetPlayer()->SetTaxiCheater(lastTaxiCheaterState);
108}
void AppendTaximaskTo(ByteBuffer &data, bool all)
Definition PlayerTaxi.cpp:116
bool isTaxiCheater() const
Definition Player.h:1186
@ SMSG_SHOWTAXINODES
Definition Opcodes.h:455

References PlayerTaxi::AppendTaximaskTo(), Object::GetEntry(), Object::GetGUID(), GetPlayer(), 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 // reaction must be checked both ways: the Dark Portal flight masters are neutral toward opposite-faction players, while players are hostile toward them
40 if (!unit || unit->GetReactionTo(player) <= REP_UNFRIENDLY || player->IsHostileTo(unit) || !unit->HasNpcFlag(UNIT_NPC_FLAG_FLIGHTMASTER))
41 {
42 LOG_DEBUG("network", "WorldSession::SendTaxiStatus - Unit ({}) not found.", guid.ToString());
43 return;
44 }
45
46 // find taxi node
47 uint32 nearest = sObjectMgr->GetNearestTaxiNode(*unit, player->GetTeamId(true));
48 if (!nearest)
49 {
50 return;
51 }
52
54 data << guid;
55 data << uint8(player->m_taxi.IsTaximaskNodeKnown(nearest) ? 1 : 0);
56 SendPacket(&data);
57 LOG_DEBUG("network", "WORLD: Sent SMSG_TAXINODE_STATUS");
58}
@ REP_UNFRIENDLY
Definition SharedDefines.h:159
bool IsTaximaskNodeKnown(uint32 nodeidx) const
Definition PlayerTaxi.h:35
ReputationRank GetReactionTo(Unit const *target, bool checkOriginalFaction=false) const
Definition Unit.cpp:6858
bool HasNpcFlag(NPCFlags flags) const
Definition Unit.h:764

References ObjectAccessor::GetCreature(), GetPlayer(), Unit::GetReactionTo(), Player::GetTeamId(), Unit::HasNpcFlag(), Unit::IsHostileTo(), PlayerTaxi::IsTaximaskNodeKnown(), LOG_DEBUG, Player::m_taxi, REP_UNFRIENDLY, 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 ( )
1523{
1526 SendPacket(&data);
1527
1529
1530 // Schedule next sync in 10 sec (except for the 2 first packets, which are spaced by only 5s)
1531 _timeSyncTimer = _timeSyncNextCounter == 0 ? 5000 : 10000;
1533}
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 ( TradeStatusInfo const &  info)
36{
38 data << uint32(info.Status);
39
40 switch (info.Status)
41 {
43 data << info.TraderGuid; // CGTradeInfo::m_tradingPlayer
44 break;
46 data << uint32(0); // CGTradeInfo::m_tradeID
47 break;
49 data << uint32(info.Result); // InventoryResult
50 data << uint8(info.IsTargetResult); // bool isTargetError; used for: EQUIP_ERR_BAG_FULL, EQUIP_ERR_CANT_CARRY_MORE_OF_THIS, EQUIP_ERR_MISSING_REAGENT, EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED
51 data << uint32(info.ItemLimitedByLimitCategory);// when result 84 - Item Id that was limited by ItemLimitCategory.dbc
52 break;
55 data << uint8(info.Slot); // Trade slot; -1 here clears CGTradeInfo::m_tradeMoney
56 break;
57 default:
58 break;
59 }
60
61 SendPacket(&data);
62}
@ TRADE_STATUS_WRONG_REALM
Definition SharedDefines.h:3828
@ SMSG_TRADE_STATUS
Definition Opcodes.h:318

References TradeStatusInfo::IsTargetResult, TradeStatusInfo::ItemLimitedByLimitCategory, TradeStatusInfo::Result, SendPacket(), TradeStatusInfo::Slot, SMSG_TRADE_STATUS, TradeStatusInfo::Status, TRADE_STATUS_BEGIN_TRADE, TRADE_STATUS_CLOSE_WINDOW, TRADE_STATUS_NOT_ON_TAPLIST, TRADE_STATUS_OPEN_WINDOW, TRADE_STATUS_WRONG_REALM, and TradeStatusInfo::TraderGuid.

Referenced by HandleAcceptTradeOpcode(), HandleBeginTradeOpcode(), HandleInitiateTradeOpcode(), HandleSetTradeItemOpcode(), SendCancelTrade(), TradeData::SetAccepted(), and TradeData::SetMoney().

◆ SendTrainerList()

void WorldSession::SendTrainerList ( Creature *  npc)
94{
95 // remove fake death
96 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
98
99 Trainer::Trainer const* trainer = sObjectMgr->GetTrainer(npc->GetEntry());
100 if (!trainer)
101 {
102 LOG_DEBUG("network", "WorldSession: SendTrainerList - trainer spells not found for {}", npc->GetGUID().ToString().c_str());
103 return;
104 }
105
106 if (!trainer->IsTrainerValidForPlayer(_player))
107 {
108 LOG_DEBUG("network", "WorldSession: SendTrainerList - trainer {} not valid for player {}", npc->GetGUID().ToString().c_str(), GetPlayerInfo().c_str());
109 return;
110 }
111
112 npc->PauseMovementForInteraction();
113
115}
bool IsTrainerValidForPlayer(Player const *player) const
Definition Trainer.cpp:223
void SendSpells(Creature *npc, Player *player, LocaleConstant locale) const
Definition Trainer.cpp:38

References _player, GetPlayer(), GetPlayerInfo(), GetSessionDbLocaleIndex(), Trainer::Trainer::IsTrainerValidForPlayer(), LOG_DEBUG, Unit::RemoveAurasByType(), Trainer::Trainer::SendSpells(), sObjectMgr, SPELL_AURA_FEIGN_DEATH, and UNIT_STATE_DIED.

Referenced by HandleTrainerListOpcode(), npc_prof_leather::OnGossipSelect(), Player::OnGossipSelect(), npc_prof_alchemy::SendActionMenu(), npc_prof_blacksmith::SendActionMenu(), and npc_prof_tailor::SendActionMenu().

◆ SendTutorialsData()

void WorldSession::SendTutorialsData ( )
1063{
1065 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
1066 data << m_Tutorials[i];
1067 SendPacket(&data);
1068}
@ 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)
75{
76 TradeData* view_trade = trader_data ? _player->GetTradeData()->GetTraderData() : _player->GetTradeData();
77
78 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));
79 data << uint8(trader_data); // 1 means traders data, 0 means own
80 data << uint32(0); // CGTradeInfo::m_tradeID
81 data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = next field in most cases
82 data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = prev field in most cases
83 data << uint32(view_trade->GetMoney()); // trader gold
84 data << uint32(view_trade->GetSpell()); // spell casted on lowest slot item
85
86 for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
87 {
88 data << uint8(i); // trade slot number, if not specified, then end of packet
89
90 if (Item* item = view_trade->GetItem(TradeSlots(i)))
91 {
92 data << uint32(item->GetTemplate()->ItemId); // entry
93 data << uint32(item->GetTemplate()->DisplayInfoID);// display id
94 data << uint32(item->GetCount()); // stack count
95 // wrapped: hide stats but show giftcreator name
96 data << uint32(item->IsWrapped() ? 1 : 0);
97 data << item->GetGuidValue(ITEM_FIELD_GIFTCREATOR);
98 // perm. enchantment and gems
99 data << uint32(item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT));
100 for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS; ++enchant_slot)
101 data << uint32(item->GetEnchantmentId(EnchantmentSlot(enchant_slot)));
102 // creator
103 data << item->GetGuidValue(ITEM_FIELD_CREATOR);
104 data << uint32(item->GetSpellCharges()); // charges
105 data << uint32(item->GetItemSuffixFactor()); // SuffixFactor
106 data << int32(item->GetItemRandomPropertyId()); // random properties id
107 data << uint32(item->GetTemplate()->LockID); // lock id
108 // max durability
109 data << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY));
110 // durability
111 data << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY));
112 }
113 else
114 {
115 for (uint8 j = 0; j < 18; ++j)
116 data << uint32(0);
117 }
118 }
119 SendPacket(&data);
120}
@ 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 ( )
829{
831 SendPacket(&data);
832}
@ 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 
)
1006{
1007 uint32 id = 0;
1009 if ((1 << type) & GLOBAL_CACHE_MASK)
1010 {
1011 id = GetAccountId();
1012 index = CHAR_REP_ACCOUNT_DATA;
1013 }
1014 else
1015 {
1016 // _player can be nullptr and packet received after logout but m_GUID still store correct guid
1017 if (!m_GUIDLow)
1018 return;
1019
1020 id = m_GUIDLow;
1022 }
1023
1024 CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(index);
1025 stmt->SetData(0, id);
1026 stmt->SetData(1, type);
1027 stmt->SetData(2, uint32(tm));
1028 stmt->SetData(3, data);
1029 CharacterDatabase.Execute(stmt);
1030
1031 m_accountData[type].Time = tm;
1032 m_accountData[type].Data = data;
1033}
CharacterDatabaseStatements
Definition CharacterDatabase.h:24
@ CHAR_REP_PLAYER_ACCOUNT_DATA
Definition CharacterDatabase.h:203
@ CHAR_REP_ACCOUNT_DATA
Definition CharacterDatabase.h:200

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
508{ m_currentVendorEntry = vendorEntry; }

References m_currentVendorEntry.

Referenced by SendListInventory().

◆ SetInQueue()

void WorldSession::SetInQueue ( bool  state)
inline

Session in auth.queue currently.

523{ m_inQueue = state; }

References m_inQueue.

Referenced by WorldSessionMgr::AddQueuedPlayer(), InitializeSessionCallback(), and WorldSessionMgr::RemoveQueuedPlayer().

◆ SetKicked()

void WorldSession::SetKicked ( bool  val)
inline
1215{ _kicked = val; }

References _kicked.

Referenced by KickPlayer().

◆ SetLatency()

void WorldSession::SetLatency ( uint32  latency)
inline
652{ 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.

540 {
541 _logoutTime = requestTime;
542 }

References _logoutTime.

Referenced by HandleLogoutCancelOpcode(), HandleLogoutRequestOpcode(), and LogoutPlayer().

◆ SetOfflineTime()

void WorldSession::SetOfflineTime ( uint32  time)
inline

◆ SetPacketLogging()

void WorldSession::SetPacketLogging ( bool  state)
1653{
1654 if (m_Socket)
1655 m_Socket->SetPacketLogging(state);
1656}

References m_Socket.

Referenced by misc_commandscript::HandlePacketLog().

◆ SetPlayer()

void WorldSession::SetPlayer ( Player *  player)
1399{
1400 _player = player;
1401
1402 // set m_GUID that can be used while player loggined and later until m_playerRecentlyLogout not reset
1403 if (_player)
1405}

References _player, ObjectGuid::GetCounter(), Object::GetGUID(), and m_GUIDLow.

Referenced by HandlePlayerLoginFromDB(), HandlePlayerLoginOpcode(), Player::LoadFromDB(), and LogoutPlayer().

◆ SetPreviousPlayedTime()

void WorldSession::SetPreviousPlayedTime ( Seconds  playedTime)
inline
531{ _previousPlayTime = playedTime; }

References _previousPlayTime.

Referenced by WorldSessionMgr::AddSession_().

◆ SetSecurity()

void WorldSession::SetSecurity ( AccountTypes  security)
inline
511{ _security = security; }

References _security.

◆ SetTotalTime()

void WorldSession::SetTotalTime ( uint32  TotalTime)
inline
516{ m_total_time = TotalTime; }

References m_total_time.

Referenced by Player::Update().

◆ SetTutorialInt()

void WorldSession::SetTutorialInt ( uint8  index,
uint32  value 
)
inline
609 {
610 if (m_Tutorials[index] != value)
611 {
612 m_Tutorials[index] = value;
613 m_TutorialsChanged = true;
614 }
615 }

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?

546 {
547 return (_logoutTime > 0 && currTime >= _logoutTime + 20);
548 }

References _logoutTime.

Referenced by Update().

◆ SynchronizeMovement()

void WorldSession::SynchronizeMovement ( MovementInfo &  movementInfo)
417{
418 int64 movementTime = (int64)movementInfo.time + _timeSyncClockDelta;
419 if (_timeSyncClockDelta == 0 || movementTime < 0 || movementTime > 0xFFFFFFFF)
420 {
421 LOG_INFO("misc", "The computed movement time using clockDelta is erronous. Using fallback instead");
422 movementInfo.time = getMSTime();
423 }
424 else
425 {
426 movementInfo.time = (uint32)movementTime;
427 }
428}

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.

386{
391 m_Socket->CloseSocket();
392
393 if (updater.ProcessUnsafe())
394 UpdateTimeOutTime(diff);
395
398 WorldPacket* packet = nullptr;
399
401 bool deletePacket = true;
402 std::vector<WorldPacket*> requeuePackets;
403 uint32 processedPackets = 0;
404 time_t currentTime = GameTime::GetGameTime().count();
405
406 if (GetPlayer() && GetPlayer()->IsInWorld() && IsAffectedByCAIS())
407 {
408 CheckPlayedTimeLimit(Seconds(currentTime));
409 _lastUpdateTime = Seconds(currentTime);
410 }
411
412 constexpr uint32 MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE = 150;
413
414 while (m_Socket && _recvQueue.next(packet, updater))
415 {
416 OpcodeClient opcode = static_cast<OpcodeClient>(packet->GetOpcode());
417 ClientOpcodeHandler const* opHandle = opcodeTable[opcode];
418
419 METRIC_DETAILED_TIMER("worldsession_update_opcode_time", METRIC_TAG("opcode", opHandle->Name));
420 LOG_DEBUG("network", "message id {} ({}) under READ", opcode, opHandle->Name);
421
422 WorldSession::DosProtection::Policy const evaluationPolicy = AntiDOS.EvaluateOpcode(*packet, currentTime);
423 switch (evaluationPolicy)
424 {
427 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE;
428 break;
430 requeuePackets.push_back(packet);
431 deletePacket = false;
432 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE;
433 break;
434 default:
435 break;
436 }
437
439 || evaluationPolicy == WorldSession::DosProtection::Policy::Log)
440 {
441 try
442 {
443 switch (opHandle->Status)
444 {
445 case STATUS_LOGGEDIN:
446 if (!_player)
447 {
448 // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
452 {
453 //requeuePackets.push_back(packet);
454 //deletePacket = false;
455
456 LOG_DEBUG("network", "Delaying processing of message with status STATUS_LOGGEDIN: No players in the world for account id {}", GetAccountId());
457 }
458 }
459 else if (_player->IsInWorld())
460 {
461 if (!sScriptMgr->CanPacketReceive(this, *packet))
462 break;
463
464 opHandle->Call(this, *packet);
465 LogUnprocessedTail(packet);
466 }
467
468 // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
469 break;
471 if (!_player && !m_playerRecentlyLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout
472 {
473 LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT",
474 "the player has not logged in yet and not recently logout");
475 }
476 else
477 {
478 // not expected _player or must checked in packet hanlder
479 if (!sScriptMgr->CanPacketReceive(this, *packet))
480 break;
481
482 opHandle->Call(this, *packet);
483 LogUnprocessedTail(packet);
484 }
485 break;
486 case STATUS_TRANSFER:
487 if (_player && !_player->IsInWorld())
488 {
489 if (!sScriptMgr->CanPacketReceive(this, *packet))
490 break;
491
492 opHandle->Call(this, *packet);
493 LogUnprocessedTail(packet);
494 }
495 break;
496 case STATUS_AUTHED:
497 if (m_inQueue) // prevent cheating
498 break;
499
500 // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes
501 // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process.
502 if (packet->GetOpcode() == CMSG_CHAR_ENUM)
504
505 if (!sScriptMgr->CanPacketReceive(this, *packet))
506 break;
507
508 opHandle->Call(this, *packet);
509 LogUnprocessedTail(packet);
510 break;
511 case STATUS_NEVER:
512 LOG_ERROR("network.opcode", "Received not allowed opcode {} from {}",
513 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
514 break;
515 case STATUS_UNHANDLED:
516 LOG_DEBUG("network.opcode", "Received not handled opcode {} from {}",
517 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
518 break;
519 }
520 }
522 {
523 LOG_ERROR("network", "{} sent {} with an invalid link:\n{}", GetPlayerInfo(),
524 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), ihe.GetInvalidValue());
525
527 {
528 KickPlayer("WorldSession::Update Invalid chat link");
529 }
530 }
532 {
533 LOG_ERROR("network", "{} sent {} which illegally contained a hyperlink:\n{}", GetPlayerInfo(),
534 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), ihe.GetInvalidValue());
535
537 {
538 KickPlayer("WorldSession::Update Illegal chat link");
539 }
540 }
542 {
543 LOG_ERROR("network", "PacketArrayMaxCapacityException: {} while parsing {} from {}.",
544 pamce.what(), GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
545 }
546 catch (ByteBufferException const&)
547 {
548 LOG_ERROR("network", "WorldSession::Update ByteBufferException occured while parsing a packet (opcode: {}) from client {}, accountid={}. Skipped packet.", packet->GetOpcode(), GetRemoteAddress(), GetAccountId());
549 if (sLog->ShouldLog("network", LogLevel::LOG_LEVEL_DEBUG))
550 {
551 LOG_DEBUG("network", "Dumping error causing packet:");
552 packet->hexlike();
553 }
554 }
555 }
556
557 if (deletePacket)
558 delete packet;
559
560 deletePacket = true;
561
562 processedPackets++;
563
564 //process only a max amout of packets in 1 Update() call.
565 //Any leftover will be processed in next update
566 if (processedPackets > MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE)
567 break;
568 }
569
570 _recvQueue.readd(requeuePackets.begin(), requeuePackets.end());
571
572 METRIC_VALUE("processed_packets", processedPackets);
573 METRIC_VALUE("addon_messages", _addonMessageReceiveCount.load());
575
576 if (!updater.ProcessUnsafe()) // <=> updater is of type MapSessionFilter
577 {
578 // Send time sync packet every 10s.
579 if (_timeSyncTimer > 0)
580 {
581 if (diff >= _timeSyncTimer)
582 {
583 SendTimeSync();
584 }
585 else
586 {
587 _timeSyncTimer -= diff;
588 }
589 }
590 }
591
593
594 //check if we are safe to proceed with logout
595 //logout procedure should happen only in World::UpdateSessions() method!!!
596 if (updater.ProcessUnsafe())
597 {
598 sScriptMgr->OnSessionUpdate(this, diff);
599
600 if (m_Socket && m_Socket->IsOpen() && _warden)
601 {
602 _warden->Update(diff);
603 }
604
605 if (ShouldLogOut(currentTime) && !m_playerLoading)
606 {
607 LogoutPlayer(true);
608 }
609
610 if (m_Socket && !m_Socket->IsOpen())
611 {
612 if (GetPlayer() && _warden)
613 _warden->Update(diff);
614
615 m_Socket = nullptr;
616 }
617
618 if (!m_Socket)
619 {
620 return false; //Will remove this session from the world session map
621 }
622 }
623
624 return true;
625}
@ 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
Definition Opcodes.h:1387
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:330
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:1444
Policy
Definition WorldSession.h:1248
void SendTimeSync()
Definition WorldSession.cpp:1522
void UpdateTimeOutTime(uint32 diff)
Definition WorldSession.h:655
void LogUnexpectedOpcode(WorldPacket *packet, char const *status, char const *reason)
Logging helper for unexpected opcodes.
Definition WorldSession.cpp:366
void LogUnprocessedTail(WorldPacket *packet)
Logging helper for unexpected opcodes.
Definition WorldSession.cpp:373
void ProcessQueryCallbacks()
Definition WorldSession.cpp:1407
void CheckPlayedTimeLimit(Seconds now)
Definition WorldSession.cpp:644
bool ShouldLogOut(time_t currTime) const
Is logout cooldown expired?
Definition WorldSession.h:545
bool IsConnectionIdle() const
Definition WorldSession.h:669
char const * Name
Definition Opcodes.h:1382
OpcodeTable opcodeTable
Definition Opcodes.cpp:51
SessionStatus Status
Definition Opcodes.h:1383
virtual void Call(WorldSession *session, WorldPacket &packet) const =0
@ CMSG_CHAR_ENUM
Definition Opcodes.h:85
@ STATUS_LOGGEDIN
Definition Opcodes.h:1359
@ STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT
Definition Opcodes.h:1361
@ STATUS_TRANSFER
Definition Opcodes.h:1360
@ STATUS_NEVER
Definition Opcodes.h:1362
@ STATUS_UNHANDLED
Definition Opcodes.h:1363
@ RBAC_PERM_IGNORE_IDLE_CONNECTION
Definition RBAC.h:58

References _addonMessageReceiveCount, _lastUpdateTime, _player, _recvQueue, _timeSyncTimer, _warden, AntiDOS, WorldSession::DosProtection::Ban, WorldSession::DosProtection::BlockingThrottle, ClientOpcodeHandler::Call(), CheckPlayedTimeLimit(), CMSG_CHAR_ENUM, CONFIG_CHAT_STRICT_LINK_CHECKING_KICK, WorldSession::DosProtection::EvaluateOpcode(), GetAccountId(), GameTime::GetGameTime(), WorldPackets::InvalidStringValueException::GetInvalidValue(), WorldPacket::GetOpcode(), GetOpcodeNameForLogging(), GetPlayer(), GetPlayerInfo(), GetRemoteAddress(), HasPermission(), ByteBuffer::hexlike(), IsAffectedByCAIS(), 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(), rbac::RBAC_PERM_IGNORE_IDLE_CONNECTION, 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 
)
197{
198 if (remove)
199 _accountFlags &= ~flag;
200 else
201 _accountFlags |= flag;
202
203 // Async update
205 stmt->SetData(0, _accountFlags);
206 stmt->SetData(1, GetAccountId());
207 LoginDatabase.Execute(stmt);
208}
@ LOGIN_UPD_SET_ACCOUNT_FLAG
Definition LoginDatabase.h:90

References _accountFlags, GetAccountId(), LOGIN_UPD_SET_ACCOUNT_FLAG, LoginDatabase, and PreparedStatementBase::SetData().

Referenced by ValidateAccountFlags().

◆ UpdateTimeOutTime()

void WorldSession::UpdateTimeOutTime ( uint32  diff)
inline
656 {
657 if (time_t(diff) > m_timeOutTime)
658 m_timeOutTime = 0;
659 else
660 m_timeOutTime -= diff;
661 }

References m_timeOutTime.

Referenced by Update().

◆ ValidateAccountFlags()

void WorldSession::ValidateAccountFlags ( )
211{
212 bool hasGMFlag = HasAccountFlag(ACCOUNT_FLAG_GM);
213
214 if (IsGMAccount() && !hasGMFlag)
216 else if (hasGMFlag && !IsGMAccount())
218}
@ ACCOUNT_FLAG_GM
Definition Common.h:67

References ACCOUNT_FLAG_GM, HasAccountFlag(), IsGMAccount(), and UpdateAccountFlag().

Referenced by WorldSocket::HandleAuthSessionCallback().

◆ ValidateHyperlinksAndMaybeKick()

bool WorldSession::ValidateHyperlinksAndMaybeKick ( std::string_view  str)
896{
898 return true;
899
900 LOG_ERROR("network", "Player {} {} sent a message with an invalid link:\n{}", GetPlayer()->GetName(),
901 GetPlayer()->GetGUID().ToString(), str);
902
904 KickPlayer("WorldSession::ValidateHyperlinksAndMaybeKick Invalid chat link");
905
906 return false;
907}

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
532{
533 if (!movementInfo.pos.IsPositionValid())
534 {
535 if (plrMover)
536 {
537 sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
538 }
539
540 return false;
541 }
542
543 if (!mover->movespline->Finalized())
544 {
545 if (!mover->movespline->isBoarding() || (opcode != CMSG_FORCE_MOVE_UNROOT_ACK && opcode != CMSG_FORCE_MOVE_ROOT_ACK))
546 return false;
547 }
548
549 // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE
551 {
552 // Xinef: skip moving packets
553 if (movementInfo.HasMovementFlag(MOVEMENTFLAG_MASK_MOVING))
554 {
555 if (plrMover)
556 {
557 sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
558 }
559 return false;
560 }
561 }
562
563 bool jumpopcode = false;
564 if (opcode == MSG_MOVE_JUMP)
565 {
566 jumpopcode = true;
567 if (plrMover && !sScriptMgr->AnticheatHandleDoubleJump(plrMover, mover))
568 {
569 plrMover->GetSession()->KickPlayer();
570 return false;
571 }
572 }
573
574 /* start some hack detection */
575 if (plrMover && !sScriptMgr->AnticheatCheckMovementInfo(plrMover, movementInfo, mover, jumpopcode))
576 {
577 plrMover->GetSession()->KickPlayer();
578 return false;
579 }
580
581 if (movementInfo.HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
582 {
583 // We were teleported, skip packets that were broadcast before teleport
584 if (movementInfo.pos.GetExactDist2d(mover) > SIZE_OF_GRIDS)
585 {
586 if (plrMover)
587 {
588 sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
589 //LOG_INFO("anticheat", "MovementHandler:: 2 We were teleported, skip packets that were broadcast before teleport");
590 }
591 return false;
592 }
593
594 if (!Acore::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.transport.pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.transport.pos.GetPositionY(),
595 movementInfo.pos.GetPositionZ() + movementInfo.transport.pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.transport.pos.GetOrientation()))
596 {
597 if (plrMover)
598 {
599 sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
600 }
601
602 return false;
603 }
604 }
605
606 // rooted mover sent packet without root or moving AND root - ignore, due to client crash possibility
607 if (opcode != CMSG_FORCE_MOVE_UNROOT_ACK)
608 if (mover->IsRooted() && (!movementInfo.HasMovementFlag(MOVEMENTFLAG_ROOT) || movementInfo.HasMovementFlag(MOVEMENTFLAG_MASK_MOVING)))
609 return false;
610
611 return true;
612}
#define SIZE_OF_GRIDS
Definition MapDefines.h:26
bool isBoarding() const
Definition MoveSpline.h:121
@ 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 
)
1204{
1205 *data << mi->guid.WriteAsPacked();
1206
1207 *data << mi->flags;
1208 *data << mi->flags2;
1209 *data << mi->time;
1210 *data << mi->pos.PositionXYZOStream();
1211
1213 {
1214 *data << mi->transport.guid.WriteAsPacked();
1215
1216 *data << mi->transport.pos.PositionXYZOStream();
1217 *data << mi->transport.time;
1218 *data << mi->transport.seat;
1219
1221 *data << mi->transport.time2;
1222 }
1223
1225 *data << mi->pitch;
1226
1227 *data << mi->fallTime;
1228
1230 {
1231 *data << mi->jump.zspeed;
1232 *data << mi->jump.sinAngle;
1233 *data << mi->jump.cosAngle;
1234 *data << mi->jump.xyspeed;
1235 }
1236
1238 *data << mi->splineElevation;
1239}

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(), HandleMoveKnockBackAck(), 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

◆ _accountName

std::string WorldSession::_accountName
private

◆ _addonMessageReceiveCount

std::atomic<uint32> WorldSession::_addonMessageReceiveCount
private

Referenced by HandleMessagechatOpcode(), and Update().

◆ _calendarEventCreationCooldown

time_t WorldSession::_calendarEventCreationCooldown
private

◆ _createTime

Seconds WorldSession::_createTime
private

◆ _headless

bool const WorldSession::_headless
private

Referenced by IsHeadless(), and ~WorldSession().

◆ _kicked

bool WorldSession::_kicked
private

Referenced by IsKicked(), SetKicked(), and WorldSession().

◆ _lastUpdateTime

Seconds WorldSession::_lastUpdateTime
private

Referenced by CheckPlayedTimeLimit(), and Update().

◆ _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(), 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(), SendMailList(), SendPetitionShowList(), SendPetNameQuery(), SendSpiritResurrect(), SendTrainerList(), SendUpdateTrade(), SetPlayer(), Update(), and ~WorldSession().

◆ _previousPlayTime

Seconds WorldSession::_previousPlayTime
private

◆ _queryHolderProcessor

AsyncCallbackProcessor<SQLQueryHolderCallback> WorldSession::_queryHolderProcessor
private

◆ _queryProcessor

◆ _RBACData

◆ _recvQueue

LockedQueue<WorldPacket*> WorldSession::_recvQueue
private

◆ _security

AccountTypes WorldSession::_security
private

◆ _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

std::shared_ptr<WorldSocket> WorldSession::m_Socket
private

◆ 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: