void Group::BroadcastPacket(WorldPacket& packet, bool ignorePlayersInBGRaid, int group, ObjectGuid ignore) { for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* pl = itr->getSource(); if (!pl || (ignore && pl->GetObjectGuid() == ignore) || (ignorePlayersInBGRaid && pl->GetGroup() != this)) continue; if (pl->GetSession() && (group == -1 || itr->getSubGroup() == group)) pl->GetSession()->SendPacket(packet); } }
void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data) { DEBUG_LOG("MSG_MOVE_TELEPORT_ACK"); ObjectGuid guid; recv_data >> guid.ReadAsPacked(); uint32 flags, time; recv_data >> flags >> time; DEBUG_LOG("Guid: %s", guid.GetString().c_str()); DEBUG_LOG("Flags %u, time %u", flags, time/IN_MILLISECONDS); Unit *mover = _player->m_mover; Player *plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL; if(!plMover || !plMover->IsBeingTeleportedNear()) return; if(guid != plMover->GetObjectGuid()) return; plMover->SetSemaphoreTeleportNear(false); uint32 old_zone = plMover->GetZoneId(); WorldLocation const& dest = plMover->GetTeleportDest(); plMover->SetPosition(dest.coord_x, dest.coord_y, dest.coord_z, dest.orientation, true); uint32 newzone, newarea; plMover->GetZoneAndAreaId(newzone, newarea); plMover->UpdateZone(newzone, newarea); // new zone if(old_zone != newzone) { // honorless target if(plMover->pvpInfo.inHostileArea) plMover->CastSpell(plMover, 2479, true); } // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); if(plMover) { plMover->Anti__SetLastTeleTime(::time(NULL)); plMover->m_anti_BeginFallZ=INVALID_HEIGHT; } //lets process all delayed operations on successful teleport GetPlayer()->ProcessDelayedOperations(); }
/// Add control and such modifiers to a passenger if required void VehicleInfo::ApplySeatMods(Unit* passenger, uint32 seatFlags) { Unit* pVehicle = (Unit*)m_owner; // Vehicles are alawys Unit if (passenger->GetTypeId() == TYPEID_PLAYER) { Player* pPlayer = (Player*)passenger; if (seatFlags & SEAT_FLAG_CAN_CONTROL) { pPlayer->GetCamera().SetView(pVehicle); pPlayer->SetCharm(pVehicle); pVehicle->SetCharmerGuid(pPlayer->GetObjectGuid()); pVehicle->addUnitState(UNIT_STAT_CONTROLLED); pVehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); pPlayer->SetClientControl(pVehicle, 1); pPlayer->SetMover(pVehicle); // Unconfirmed - default speed handling if (pVehicle->GetTypeId() == TYPEID_UNIT) { if (!pPlayer->IsWalking() && pVehicle->IsWalking()) { ((Creature*)pVehicle)->SetWalk(false); } else if (pPlayer->IsWalking() && !pVehicle->IsWalking()) { ((Creature*)pVehicle)->SetWalk(true); } } } if (seatFlags & (SEAT_FLAG_USABLE | SEAT_FLAG_CAN_CAST)) { CharmInfo* charmInfo = pVehicle->InitCharmInfo(pVehicle); // ToDo: Send vehicle actionbar spells charmInfo->InitEmptyActionBar(); pPlayer->PossessSpellInitialize(); } } else if (passenger->GetTypeId() == TYPEID_UNIT) { if (seatFlags & SEAT_FLAG_CAN_CONTROL) { passenger->SetCharm(pVehicle); pVehicle->SetCharmerGuid(passenger->GetObjectGuid()); } } }
void PetAI::UpdateAllies() { Unit* owner = m_creature->GetCharmerOrOwner(); Group *group = NULL; m_updateAlliesTimer = 10 * IN_MILLISECONDS; //update friendly targets every 10 seconds, lesser checks increase performance if (!owner) return; else if (owner->GetTypeId() == TYPEID_PLAYER) group = ((Player*)owner)->GetGroup(); //only pet and owner/not in group->ok if (m_AllySet.size() == 2 && !group) return; //owner is in group; group members filled in already (no raid -> subgroupcount = whole count) if (group && !group->isRaidGroup() && m_AllySet.size() == (group->GetMembersCount() + 2)) return; m_AllySet.clear(); m_AllySet.insert(m_creature->GetObjectGuid()); if (group) //add group { for (GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* target = itr->getSource(); if (!target || !group->SameSubGroup((Player*)owner, target)) continue; if (target->GetObjectGuid() == owner->GetObjectGuid()) continue; m_AllySet.insert(target->GetObjectGuid()); } } else //remove group m_AllySet.insert(owner->GetObjectGuid()); }
void PetAI::UpdateAllies() { Unit* owner = m_creature->GetCharmerOrOwner(); if (!owner) return; Group* pGroup = NULL; if (owner->GetTypeId() == TYPEID_PLAYER) pGroup = ((Player*)owner)->GetGroup(); // only pet and owner/not in group->ok if (m_AllySet.size() == 2 && !pGroup) return; // owner is in group; group members filled in already (no raid -> subgroupcount = whole count) if (pGroup && !pGroup->isRaidGroup() && m_AllySet.size() == (pGroup->GetMembersCount() + 2)) return; m_AllySet.clear(); m_AllySet.insert(m_creature->GetObjectGuid()); if (pGroup) // add group { for (GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* target = itr->getSource(); if (!target || !pGroup->SameSubGroup((Player*)owner, target)) continue; if (target->GetObjectGuid() == owner->GetObjectGuid()) continue; m_AllySet.insert(target->GetObjectGuid()); } } else // remove group m_AllySet.insert(owner->GetObjectGuid()); }
void Channel::UnBan(ObjectGuid good, const char* badname) { uint32 sec = 0; Player* gplr = sObjectMgr.GetPlayer(good); if (gplr) sec = gplr->GetSession()->GetSecurity(); if (!IsOn(good)) { WorldPacket data; MakeNotMember(&data); SendToOne(&data, good); } else if (!m_players[good].IsModerator() && sec < SEC_GAMEMASTER) { WorldPacket data; MakeNotModerator(&data); SendToOne(&data, good); } else { Player* bad = sObjectMgr.GetPlayer(badname); if (bad == NULL || !IsBanned(bad->GetObjectGuid())) { WorldPacket data; MakePlayerNotFound(&data, badname); SendToOne(&data, good); } else { m_banned.erase(bad->GetObjectGuid()); WorldPacket data; MakePlayerUnbanned(&data, bad->GetObjectGuid(), good); SendToAll(&data); } } }
void Channel::SetOwner(Player* player, const char* targetName) { ObjectGuid guid = player->GetObjectGuid(); if (!IsOn(guid)) { WorldPacket data; MakeNotMember(&data); SendToOne(&data, guid); return; } if (player->GetSession()->GetSecurity() < SEC_GAMEMASTER && guid != m_ownerGuid) { WorldPacket data; MakeNotOwner(&data); SendToOne(&data, guid); return; } Player* target = sObjectMgr.GetPlayer(targetName); if (!target) { WorldPacket data; MakePlayerNotFound(&data, targetName); SendToOne(&data, guid); return; } ObjectGuid targetGuid = target->GetObjectGuid(); if (!IsOn(targetGuid)) { WorldPacket data; MakePlayerNotFound(&data, targetName); SendToOne(&data, guid); return; } if (target->GetTeam() != player->GetTeam() && !sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_CHANNEL)) { WorldPacket data; MakePlayerNotFound(&data, targetName); SendToOne(&data, guid); return; } // set channel owner m_players[targetGuid].SetModerator(true); SetOwner(targetGuid); }
void UpdateAI(const uint32 diff) { if (FlyBackTimer <= diff) { ObjectGuid m_uiCreatorGuid = m_creature->GetCreatorGuid(); Player* player = m_creature->GetMap()->GetPlayer(m_uiCreatorGuid); if (!player) phase = 3; switch(phase) { case 0: m_creature->SetWalk(false); m_creature->HandleEmoteCommand(EMOTE_STATE_FLYGRABCLOSED); FlyBackTimer = 500; break; case 1: player->GetClosePoint(x, y, z, m_creature->GetObjectBoundingRadius(), 0, 0, m_creature); z += 2.5; x -= 2; y -= 1.5; m_creature->GetMotionMaster()->MovePoint(0, x, y, z); m_creature->SetTargetGuid(player->GetObjectGuid()); m_creature->SetVisibility(VISIBILITY_ON); FlyBackTimer = 4500; break; case 2: if (!player->isRessurectRequested()) { m_creature->HandleEmoteCommand(EMOTE_ONESHOT_CUSTOMSPELL01); DoCast(player, SPELL_REVIVE, true); int sex = (player->getGender()) == GENDER_MALE ? 0 : 1; DoScriptText(VALK_WHISPER_M - sex, m_creature, player); } FlyBackTimer = 5000; break; case 3: m_creature->SetVisibility(VISIBILITY_OFF); FlyBackTimer = 3000; break; case 4: m_creature->ForcedDespawn(); break; default: //Nothing To DO break; } ++phase; } else FlyBackTimer-=diff; }
bool ChatHandler::HandleCharacterAutodumpCommand(char *args) { char* cname = strtok (args, " "); if (!cname || !*cname) return false; ObjectGuid guid64; uint32 accid = 0; Player *target = sObjectMgr.GetPlayer(cname); std::string normalName; if(target) { // player online guid64 = target->GetObjectGuid(); accid = target->GetSession()->GetAccountId(); normalName = target->GetName(); } else { // player offline, ask DB guid64 = sObjectMgr.GetPlayerGuidByName(cname); accid = sObjectMgr.GetPlayerAccountIdByGUID(guid64); if(guid64 && accid) { normalName = cname; normalizePlayerName(normalName); } else // nothing found or wrong data { PSendSysMessage(LANG_NO_PLAYER, cname); SetSentErrorMessage(true); return false; } } ObjectGuid guid; guid.Set(guid64); std::string dump = PlayerDumpWriter().GetDump(guid.GetCounter()); std::string outfile; bool result = sLog.outCharDumpExtra(dump.c_str(),accid,guid.GetCounter(),normalName.c_str(),&outfile); if(!result) { PSendSysMessage(LANG_FILE_OPEN_FAIL, outfile.c_str()); SetSentErrorMessage(true); return false; } PSendSysMessage("Dump of '%s' saved to: %s", normalName.c_str(), outfile.c_str()); return true; }
void WorldSession::HandleMoveTeleportAckOpcode(WorldPacket& recv_data) { DEBUG_LOG("CMSG_MOVE_TELEPORT_ACK"); ObjectGuid guid; uint32 counter, time; recv_data >> counter >> time; recv_data.ReadGuidMask<5, 0, 1, 6, 3, 7, 2, 4>(guid); recv_data.ReadGuidBytes<4, 2, 7, 6, 5, 1, 3, 0>(guid); DEBUG_LOG("Guid: %s", guid.GetString().c_str()); DEBUG_LOG("Counter %u, time %u", counter, time / IN_MILLISECONDS); Unit* mover = _player->GetMover(); Player* plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL; if (!plMover || !plMover->IsBeingTeleportedNear()) return; if (guid != plMover->GetObjectGuid()) return; plMover->SetSemaphoreTeleportNear(false); uint32 old_zone = plMover->GetZoneId(); WorldLocation const& dest = plMover->GetTeleportDest(); plMover->SetPosition(dest.coord_x, dest.coord_y, dest.coord_z, dest.orientation, true); uint32 newzone, newarea; plMover->GetZoneAndAreaId(newzone, newarea); plMover->UpdateZone(newzone, newarea); // new zone if (old_zone != newzone) { // honorless target if (plMover->pvpInfo.inHostileArea) plMover->CastSpell(plMover, 2479, true); } // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); // lets process all delayed operations on successful teleport GetPlayer()->ProcessDelayedOperations(); }
bool PlayerbotAI::TellMasterNoFacing(string text, PlayerbotSecurityLevel securityLevel) { Player* master = GetMaster(); if (!master) return false; if (!GetSecurity()->CheckLevelFor(securityLevel, true, master)) return false; if (sPlayerbotAIConfig.whisperDistance && !bot->GetGroup() && sRandomPlayerbotMgr.IsRandomBot(bot) && master->GetSession()->GetSecurity() < SEC_GAMEMASTER && (bot->GetMapId() != master->GetMapId() || bot->GetDistance(master) > sPlayerbotAIConfig.whisperDistance)) return false; bot->Whisper(text, LANG_UNIVERSAL, master->GetObjectGuid()); return true; }
void WorldSession::HandleLfgLeaveOpcode(WorldPacket& /*recv_data*/) { DEBUG_LOG("CMSG_LFG_LEAVE"); Player* pPlayer = GetPlayer(); ObjectGuid guid = pPlayer->GetObjectGuid(); Group* pGroup = pPlayer->GetGroup(); // If it's just one player they can leave, otherwise just the group leader if (!pGroup) sLFGMgr.LeaveLFG(pPlayer, false); else if (pGroup && pGroup->IsLeader(guid)) sLFGMgr.LeaveLFG(pPlayer, true); // SendLfgUpdate(false, LFG_UPDATE_LEAVE, 0); }
void Channel::UnBan(Player* player, const char* targetName) { ObjectGuid guid = player->GetObjectGuid(); if (!IsOn(guid)) { WorldPacket data; MakeNotMember(&data); SendToOne(&data, guid); return; } if (!m_players[guid].IsModerator() && player->GetSession()->GetSecurity() < SEC_GAMEMASTER) { WorldPacket data; MakeNotModerator(&data); SendToOne(&data, guid); return; } Player* target = sObjectMgr.GetPlayer(targetName); if (!target) { WorldPacket data; MakePlayerNotFound(&data, targetName); SendToOne(&data, guid); return; } ObjectGuid targetGuid = target->GetObjectGuid(); if (!IsBanned(targetGuid)) { WorldPacket data; MakePlayerNotBanned(&data, targetName); SendToOne(&data, guid); return; } // unban player m_banned.erase(targetGuid); WorldPacket data; MakePlayerUnbanned(&data, targetGuid, guid); SendToAll(&data); }
void instance_sunwell_plateau::DoEjectSpectralRealmPlayers() { if (m_lSpectralRealmList.empty()) return; Map::PlayerList const& players = instance->GetPlayers(); for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { Player* pPlayer = itr->getSource(); if (pPlayer && !pPlayer->HasAura(SPELL_SPECTRAL_REALM)) { m_lSpectralRealmList.remove(pPlayer->GetObjectGuid()); pPlayer->CastSpell(pPlayer, SPELL_SPECTRAL_REALM_RETURN, true); } } }
void WorldSession::SendLfgProposalUpdate(LFGProposal const& proposal) { Player* pPlayer = GetPlayer(); ObjectGuid plrGuid = pPlayer->GetObjectGuid(); ObjectGuid plrGroupGuid = proposal.groups.find(plrGuid)->second; uint32 dungeonEntry = sLFGMgr.GetDungeonEntry(proposal.dungeonID); bool showProposal = !proposal.isNew && proposal.groupRawGuid == plrGroupGuid.GetRawValue(); WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 15+(9*proposal.currentRoles.size())); data << uint32(dungeonEntry); // Dungeon Entry data << uint8(proposal.state); // Proposal state data << uint32(proposal.id); // ID of proposal data << uint32(proposal.encounters); // Encounters done data << uint8(showProposal); // Show or hide proposal window [todo-this] data << uint8(proposal.currentRoles.size()); // Size of group for (playerGroupMap::const_iterator it = proposal.groups.begin(); it != proposal.groups.end(); ++it) { ObjectGuid grpPlrGuid = it->first; uint8 grpPlrRole = proposal.currentRoles.find(grpPlrGuid)->second; LFGProposalAnswer grpPlrAnswer = proposal.answers.find(grpPlrGuid)->second; data << uint32(grpPlrRole); // Player's role data << uint8(grpPlrGuid == plrGuid); // Is this player me? if (it->second != 0) { data << uint8(it->second == ObjectGuid(proposal.groupRawGuid)); // Is player in the proposed group? data << uint8(it->second == plrGroupGuid); // Is player in the same group as myself? } else { data << uint8(0); data << uint8(0); } data << uint8(grpPlrAnswer != LFG_ANSWER_PENDING); // Has the player selected an answer? data << uint8(grpPlrAnswer == LFG_ANSWER_AGREE); // Has the player agreed to do the dungeon? } SendPacket(&data); }
void PlayerbotMgr::OnBotLogin(Player* const bot) { // simulate client taking control WorldPacket* const pCMSG_SET_ACTIVE_MOVER = new WorldPacket(CMSG_SET_ACTIVE_MOVER, 8); *pCMSG_SET_ACTIVE_MOVER << bot->GetObjectGuid(); bot->GetSession()->QueuePacket(std::move(std::unique_ptr<WorldPacket>(pCMSG_SET_ACTIVE_MOVER))); WorldPacket* const pMSG_MOVE_FALL_LAND = new WorldPacket(MSG_MOVE_FALL_LAND, 28); *pMSG_MOVE_FALL_LAND << bot->GetMover()->m_movementInfo; bot->GetSession()->QueuePacket(std::move(std::unique_ptr<WorldPacket>(pMSG_MOVE_FALL_LAND))); // give the bot some AI, object is owned by the player class PlayerbotAI* ai = new PlayerbotAI(this, bot); bot->SetPlayerbotAI(ai); // tell the world session that they now manage this new bot m_playerBots[bot->GetObjectGuid()] = bot; // if bot is in a group and master is not in group then // have bot leave their group if (bot->GetGroup() && (m_master->GetGroup() == nullptr || m_master->GetGroup()->IsMember(bot->GetObjectGuid()) == false)) bot->RemoveFromGroup(); // sometimes master can lose leadership, pass leadership to master check const ObjectGuid masterGuid = m_master->GetObjectGuid(); if (m_master->GetGroup() && !m_master->GetGroup()->IsLeader(masterGuid)) { // But only do so if one of the master's bots is leader for (PlayerBotMap::const_iterator itr = GetPlayerBotsBegin(); itr != GetPlayerBotsEnd(); itr++) { Player* bot = itr->second; if (m_master->GetGroup()->IsLeader(bot->GetObjectGuid())) { m_master->GetGroup()->ChangeLeader(masterGuid); break; } } } }
void instance_sunwell_plateau::EjectPlayers() { if (SpectralRealmList.empty()) return; Map::PlayerList const& players = instance->GetPlayers(); for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { Player* plr = itr->getSource(); if (plr && !plr->HasAura(SPELL_SPECTRAL_REALM)) { SpectralRealmList.remove(plr->GetObjectGuid()); EjectPlayer(plr); } } //SpectralRealmList.clear(); }
LFGQueueSet LFGMgr::GetDungeonPlayerQueue(LFGDungeonEntry const* dungeon, Team team) { LFGQueueSet tmpSet; tmpSet.clear(); LFGType type = LFG_TYPE_NONE; uint32 dungeonID = 0; uint8 searchEnd = LFG_TYPE_MAX; if (dungeon) { type = LFGType(dungeon->type); dungeonID = dungeon->ID; searchEnd = type+1; } for (uint8 i = type; i < searchEnd; ++i) { for (LFGQueueInfoMap::iterator itr = m_queueInfoMap[i].begin(); itr != m_queueInfoMap[i].end(); ++itr) { ObjectGuid guid = itr->first; if (!guid.IsPlayer()) continue; Player* player = sObjectMgr.GetPlayer(guid); if (!player) continue; if (team && player->GetTeam() != team) continue; if (player->GetLFGState()->GetState() < LFG_STATE_LFR || player->GetLFGState()->GetState() > LFG_STATE_PROPOSAL) continue; if (player->GetLFGState()->GetDungeons()->find(dungeon) == player->GetLFGState()->GetDungeons()->end()) continue; tmpSet.insert(player->GetObjectGuid()); } } return tmpSet; }
void WorldSession::HandleMoveTeleportAckOpcode(WorldPacket& recv_data) { DEBUG_LOG("MSG_MOVE_TELEPORT_ACK"); ObjectGuid guid; recv_data >> guid; uint32 counter, time; recv_data >> counter >> time; DEBUG_LOG("Guid: %s", guid.GetString().c_str()); DEBUG_LOG("Counter %u, time %u", counter, time / IN_MILLISECONDS); Unit *mover = _player->GetMover(); Player *plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL; if (!plMover || !plMover->IsBeingTeleportedNear()) return; if (guid != plMover->GetObjectGuid()) return; plMover->SetSemaphoreTeleportNear(false); WorldLocation const& dest = plMover->GetTeleportDest(); plMover->TeleportPositionRelocation(dest.coord_x, dest.coord_y, dest.coord_z, dest.orientation); // resummon pet plMover->ResummonPetTemporaryUnSummonedIfAny(); //lets process all delayed operations on successful teleport plMover->ProcessDelayedOperations(); // Si le joueur est stun, il ne pourra pas envoyer sa position -> Fix desynchro ici. if (plMover->hasUnitState(UNIT_STAT_NO_FREE_MOVE)) { plMover->m_movementInfo.moveFlags &= ~MOVEFLAG_MASK_MOVING_OR_TURN; plMover->SendHeartBeat(false); } }
void WorldSession::HandleLfgGetStatus(WorldPacket& recv_data) { DEBUG_LOG("CMSG_LFG_GET_STATUS"); Player* pPlayer = GetPlayer(); ObjectGuid guid = pPlayer->GetObjectGuid(); LFGPlayerStatus currentStatus = sLFGMgr.GetPlayerStatus(guid); if (pPlayer->GetGroup()) { SendLfgUpdate(true, currentStatus); currentStatus.dungeonList.clear(); SendLfgUpdate(false, currentStatus); } else { // reverse order SendLfgUpdate(false, currentStatus); currentStatus.dungeonList.clear(); SendLfgUpdate(true, currentStatus); } }
void Test() override { switch (GetTestStep()) { case 0: SpawnPlayer(0, CLASS_WARLOCK, RACE_UNDEAD, 10.0f); SpawnPlayer(1, CLASS_MAGE, RACE_GNOME, 0, 1); SpawnPlayer(2, CLASS_MAGE, RACE_GNOME, 0, -1); WaitPlayerSummon(); break; case 1: { Player* warlock = GetTestPlayer(0, TESTPLAYER_PVP_ON); Player* mage1 = GetTestPlayer(1, TESTPLAYER_PVP_ON | TESTPLAYER_MAXLEVEL); Player* mage2 = GetTestPlayer(2, TESTPLAYER_PVP_ON | TESTPLAYER_MAXLEVEL); mage1->SetSelectionGuid(warlock->GetObjectGuid()); mage2->SetSelectionGuid(warlock->GetObjectGuid()); mage1->SetFacingToObject(warlock); mage2->SetFacingToObject(warlock); mage1->CastSpell(warlock, SPELL_ARCANE_MISSILE, false); TEST_ASSERT(mage1->IsNonMeleeSpellCasted(false) && "First cast"); mage2->CastSpell(warlock, SPELL_ARCANE_MISSILE, false); TEST_ASSERT(mage1->IsNonMeleeSpellCasted(false)); TEST_ASSERT(mage2->IsNonMeleeSpellCasted(false)); Wait(3000); break; } case 2: { Player* mage1 = GetTestPlayer(1); Player* mage2 = GetTestPlayer(2); TEST_ASSERT(mage1->IsNonMeleeSpellCasted(false)); TEST_ASSERT(mage2->IsNonMeleeSpellCasted(false)); Finish(true); break; } } NextStep(); }
void WorldSession::HandleGuildAcceptOpcode(WorldPacket& /*recvPacket*/) { Guild* guild; Player* player = GetPlayer(); DEBUG_LOG("WORLD: Received opcode CMSG_GUILD_ACCEPT"); guild = sGuildMgr.GetGuildById(player->GetGuildIdInvited()); if (!guild || player->GetGuildId()) { return; } // not let enemies sign guild charter if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != sObjectMgr.GetPlayerTeamByGUID(guild->GetLeaderGuid())) { return; } if (!guild->AddMember(GetPlayer()->GetObjectGuid(), guild->GetLowestRank())) { return; } // Put record into guild log guild->LogGuildEvent(GUILD_EVENT_LOG_JOIN_GUILD, GetPlayer()->GetObjectGuid()); guild->BroadcastEvent(GE_JOINED, player->GetObjectGuid(), player->GetName()); }
void BattleGroundAV::CheckPlayerSize() { //weltklasse Map* pMap = GetBgMap(); if (!pMap || !pMap->IsBattleGround()) return; Map::PlayerList const &PlayerList = pMap->GetPlayers(); if (PlayerList.getSize() > 80) { SetMaxPlayers(80); SetMaxPlayersPerTeam(40); Map::PlayerList::const_iterator itr = PlayerList.getFirst(); Player* pPlayer = itr->getSource(); RemovePlayerAtLeave(pPlayer->GetObjectGuid(), true, true); std::ofstream logFile("bg-removed-players.txt", std::ios::app); if (logFile) logFile << pPlayer->GetName() << "\n"; } }
void WorldSession::DoLootRelease(ObjectGuid lguid) { Player *player = GetPlayer(); Loot *loot; player->SetLootGUID(ObjectGuid()); player->SendLootRelease(lguid); player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_LOOTING); if(!player->IsInWorld()) return; switch(lguid.GetHigh()) { case HIGHGUID_GAMEOBJECT: { GameObject *go = GetPlayer()->GetMap()->GetGameObject(lguid); // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO if (!go || ((go->GetOwnerGUID() != _player->GetGUID() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player,INTERACTION_DISTANCE))) return; loot = &go->loot; if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR) { // locked doors are opened with spelleffect openlock, prevent remove its as looted go->UseDoorOrButton(); } else if (loot->isLooted() || go->GetGoType() == GAMEOBJECT_TYPE_FISHINGNODE) { // GO is mineral vein? so it is not removed after its looted if(go->GetGoType() == GAMEOBJECT_TYPE_CHEST) { uint32 go_min = go->GetGOInfo()->chest.minSuccessOpens; uint32 go_max = go->GetGOInfo()->chest.maxSuccessOpens; if (player->GetInstanceId()) { Map *map = go->GetMap(); if (map->IsDungeon()) { if (map->IsRaidOrHeroicDungeon()) { ((InstanceMap *)map)->PermBindAllPlayers(player); } else { // the reset time is set but not added to the scheduler // until the players leave the instance time_t resettime = go->GetRespawnTimeEx() + 2 * HOUR; if(InstanceSave *save = player->GetMap()->GetInstanceSave()) if(save->GetResetTime() < resettime) save->SetResetTime(resettime); } } } // only vein pass this check if(go_min != 0 && go_max > go_min) { float amount_rate = sWorld.getConfig(CONFIG_FLOAT_RATE_MINING_AMOUNT); float min_amount = go_min*amount_rate; float max_amount = go_max*amount_rate; go->AddUse(); float uses = float(go->GetUseCount()); if(uses < max_amount) { if(uses >= min_amount) { float chance_rate = sWorld.getConfig(CONFIG_FLOAT_RATE_MINING_NEXT); int32 ReqValue = 175; LockEntry const *lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->chest.lockId); if(lockInfo) ReqValue = lockInfo->Skill[0]; float skill = float(player->GetSkillValue(SKILL_MINING))/(ReqValue+25); double chance = pow(0.8*chance_rate,4*(1/double(max_amount))*double(uses)); if(roll_chance_f(float(100.0f*chance+skill))) { go->SetLootState(GO_READY); } else // not have more uses go->SetLootState(GO_JUST_DEACTIVATED); } else // 100% chance until min uses go->SetLootState(GO_READY); } else // max uses already go->SetLootState(GO_JUST_DEACTIVATED); } else // not vein go->SetLootState(GO_JUST_DEACTIVATED); } else if (go->GetGoType() == GAMEOBJECT_TYPE_FISHINGHOLE) { // The fishing hole used once more go->AddUse(); // if the max usage is reached, will be despawned at next tick if (go->GetUseCount() >= urand(go->GetGOInfo()->fishinghole.minSuccessOpens,go->GetGOInfo()->fishinghole.maxSuccessOpens)) { go->SetLootState(GO_JUST_DEACTIVATED); } else go->SetLootState(GO_READY); } else // not chest (or vein/herb/etc) go->SetLootState(GO_JUST_DEACTIVATED); loot->clear(); } else // not fully looted object go->SetLootState(GO_ACTIVATED); if (player->GetInstanceId()) { Map *map = go->GetMap(); if (map->IsDungeon()) { if (map->IsRaidOrHeroicDungeon()) { ((InstanceMap *)map)->PermBindAllPlayers(player); } else { // the reset time is set but not added to the scheduler // until the players leave the instance time_t resettime = go->GetRespawnTimeEx() + 2 * HOUR; if(InstanceSave *save = player->GetMap()->GetInstanceSave()) if(save->GetResetTime() < resettime) save->SetResetTime(resettime); } } } break; } case HIGHGUID_CORPSE: // ONLY remove insignia at BG { Corpse *corpse = _player->GetMap()->GetCorpse(lguid); if (!corpse || !corpse->IsWithinDistInMap(_player,INTERACTION_DISTANCE) ) return; loot = &corpse->loot; if (loot->isLooted()) { loot->clear(); corpse->RemoveFlag(CORPSE_FIELD_DYNAMIC_FLAGS, CORPSE_DYNFLAG_LOOTABLE); } break; } case HIGHGUID_ITEM: { Item *pItem = player->GetItemByGuid(lguid ); if(!pItem) return; ItemPrototype const* proto = pItem->GetProto(); // destroy only 5 items from stack in case prospecting and milling if( (proto->BagFamily & (BAG_FAMILY_MASK_MINING_SUPP|BAG_FAMILY_MASK_HERBS)) && proto->Class == ITEM_CLASS_TRADE_GOODS) { pItem->m_lootGenerated = false; pItem->loot.clear(); uint32 count = pItem->GetCount(); // >=5 checked in spell code, but will work for cheating cases also with removing from another stacks. if(count > 5) count = 5; player->DestroyItemCount(pItem, count, true); } else // FIXME: item don't must be deleted in case not fully looted state. But this pre-request implement loot saving in DB at item save. Or checting possible. player->DestroyItem( pItem->GetBagSlot(),pItem->GetSlot(), true); return; // item can be looted only single player } case HIGHGUID_UNIT: { Creature* pCreature = GetPlayer()->GetMap()->GetCreature(lguid); bool ok_loot = pCreature && pCreature->isAlive() == (player->getClass()==CLASS_ROGUE && pCreature->lootForPickPocketed); if ( !ok_loot || !pCreature->IsWithinDistInMap(_player,INTERACTION_DISTANCE) ) return; loot = &pCreature->loot; // update next looter if(Group* group = pCreature->GetGroupLootRecipient()) if (group->GetLooterGuid() == player->GetObjectGuid()) group->UpdateLooterGuid(pCreature); if (loot->isLooted()) { // for example skinning after normal loot pCreature->PrepareBodyLootState(); if(!pCreature->isAlive()) pCreature->AllLootRemovedFromCorpse(); } break; } default: { sLog.outError("%s is unsupported for looting.", lguid.GetString().c_str()); return; } } //Player is not looking at loot list, he doesn't need to see updates on the loot list loot->RemoveLooter(player->GetGUID()); }
void Guild::BroadcastToOfficers(WorldSession* session, const std::string& msg, uint32 language) { if (!session) { return; } Player* player = session->GetPlayer(); if (!player || !HasRankRight(player->GetRank(), GR_RIGHT_OFFCHATSPEAK)) { return; } for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr) { WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_OFFICER, msg.c_str(), Language(language), player->GetChatTag(), player->GetObjectGuid(), player->GetName()); Player* pl = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first)); if (pl && pl->GetSession() && HasRankRight(pl->GetRank(), GR_RIGHT_OFFCHATLISTEN) && !pl->GetSocial()->HasIgnore(player->GetObjectGuid())) { pl->GetSession()->SendPacket(&data); } } }
void WorldSession::DoLootRelease(ObjectGuid lguid) { Player *player = GetPlayer(); Loot *loot; player->SetLootGUID(ObjectGuid()); player->SendLootRelease(lguid); player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_LOOTING); if(!player->IsInWorld()) return; switch(lguid.GetHigh()) { case HIGHGUID_GAMEOBJECT: { GameObject *go = GetPlayer()->GetMap()->GetGameObject(lguid); // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO if (!go || ((go->GetOwnerGUID() != _player->GetGUID() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player,INTERACTION_DISTANCE))) return; loot = &go->loot; if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR) { // locked doors are opened with spelleffect openlock, prevent remove its as looted go->UseDoorOrButton(); } else if (loot->isLooted() || go->GetGoType() == GAMEOBJECT_TYPE_FISHINGNODE) { // GO is mineral vein? so it is not removed after its looted if(go->GetGoType() == GAMEOBJECT_TYPE_CHEST) { uint32 go_min = go->GetGOInfo()->chest.minSuccessOpens; uint32 go_max = go->GetGOInfo()->chest.maxSuccessOpens; // only vein pass this check if(go_min != 0 && go_max > go_min) { float amount_rate = sWorld.getConfig(CONFIG_FLOAT_RATE_MINING_AMOUNT); float min_amount = go_min*amount_rate; float max_amount = go_max*amount_rate; go->AddUse(); float uses = float(go->GetUseCount()); if(uses < max_amount) { if(uses >= min_amount) { float chance_rate = sWorld.getConfig(CONFIG_FLOAT_RATE_MINING_NEXT); int32 ReqValue = 175; LockEntry const *lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->chest.lockId); if(lockInfo) ReqValue = lockInfo->Skill[0]; float skill = float(player->GetSkillValue(SKILL_MINING))/(ReqValue+25); double chance = pow(0.8*chance_rate,4*(1/double(max_amount))*double(uses)); if(roll_chance_f(float(100.0f*chance+skill))) { go->SetLootState(GO_READY); } else // not have more uses go->SetLootState(GO_JUST_DEACTIVATED); } else // 100% chance until min uses go->SetLootState(GO_READY); } else // max uses already go->SetLootState(GO_JUST_DEACTIVATED); } else // not vein go->SetLootState(GO_JUST_DEACTIVATED); } else if (go->GetGoType() == GAMEOBJECT_TYPE_FISHINGHOLE) { // The fishing hole used once more go->AddUse(); // if the max usage is reached, will be despawned at next tick if (go->GetUseCount() >= urand(go->GetGOInfo()->fishinghole.minSuccessOpens,go->GetGOInfo()->fishinghole.maxSuccessOpens)) { go->SetLootState(GO_JUST_DEACTIVATED); } else go->SetLootState(GO_READY); } else // not chest (or vein/herb/etc) go->SetLootState(GO_JUST_DEACTIVATED); loot->clear(); } else // not fully looted object go->SetLootState(GO_ACTIVATED); break; } case HIGHGUID_CORPSE: // ONLY remove insignia at BG { Corpse *corpse = _player->GetMap()->GetCorpse(lguid); if (!corpse || !corpse->IsWithinDistInMap(_player,INTERACTION_DISTANCE) ) return; loot = &corpse->loot; if (loot->isLooted()) { loot->clear(); corpse->RemoveFlag(CORPSE_FIELD_DYNAMIC_FLAGS, CORPSE_DYNFLAG_LOOTABLE); } break; } case HIGHGUID_ITEM: { Item *pItem = player->GetItemByGuid(lguid ); if (!pItem) return; switch (pItem->loot.loot_type) { // temporary loot in stacking items, clear loot state, no auto loot move case LOOT_MILLING: case LOOT_PROSPECTING: { uint32 count = pItem->GetCount(); // >=5 checked in spell code, but will work for cheating cases also with removing from another stacks. if(count > 5) count = 5; // reset loot for allow repeat looting if stack > 5 pItem->loot.clear(); pItem->SetLootState(ITEM_LOOT_REMOVED); player->DestroyItemCount(pItem, count, true); break; } // temporary loot, auto loot move case LOOT_DISENCHANTING: { if (!pItem->loot.isLooted()) player->AutoStoreLoot(pItem->loot); // can be lost if no space pItem->loot.clear(); pItem->SetLootState(ITEM_LOOT_REMOVED); player->DestroyItem( pItem->GetBagSlot(),pItem->GetSlot(), true); break; } // normal persistence loot default: { // must be destroyed only if no loot if (pItem->loot.isLooted()) { pItem->SetLootState(ITEM_LOOT_REMOVED); player->DestroyItem( pItem->GetBagSlot(),pItem->GetSlot(), true); } break; } } return; // item can be looted only single player } case HIGHGUID_UNIT: case HIGHGUID_VEHICLE: { Creature* pCreature = GetPlayer()->GetMap()->GetCreature(lguid); bool ok_loot = pCreature && pCreature->isAlive() == (player->getClass()==CLASS_ROGUE && pCreature->lootForPickPocketed); if ( !ok_loot || !pCreature->IsWithinDistInMap(_player,INTERACTION_DISTANCE) ) return; loot = &pCreature->loot; // update next looter if(Group* group = pCreature->GetGroupLootRecipient()) if (group->GetLooterGuid() == player->GetObjectGuid()) group->UpdateLooterGuid(pCreature); if (loot->isLooted()) { // for example skinning after normal loot pCreature->PrepareBodyLootState(); if(!pCreature->isAlive()) pCreature->AllLootRemovedFromCorpse(); } break; } default: { sLog.outError("%s is unsupported for looting.", lguid.GetString().c_str()); return; } } //Player is not looking at loot list, he doesn't need to see updates on the loot list loot->RemoveLooter(player->GetGUID()); }
void WorldSession::HandleBattleGroundPlayerPositionsOpcode(WorldPacket& /*recv_data*/) { // empty opcode DEBUG_LOG("WORLD: Received opcode CMSG_BATTLEGROUND_PLAYER_POSITIONS"); BattleGround* bg = _player->GetBattleGround(); if (!bg) // can't be received if player not in battleground return; Player* flagCarrierA = NULL; Player* flagCarrierH = NULL; uint32 flagCarrierCountA = 0; // obsolete uint32 flagCarrierCountH = 0; switch (bg->GetTypeID()) { case BATTLEGROUND_WS: { if (flagCarrierA = sObjectMgr.GetPlayer(((BattleGroundWS*)bg)->GetAllianceFlagCarrierGuid())) ++flagCarrierCountH; if (flagCarrierH = sObjectMgr.GetPlayer(((BattleGroundWS*)bg)->GetHordeFlagCarrierGuid())) ++flagCarrierCountH; break; } case BATTLEGROUND_EY: { if (flagCarrierH = sObjectMgr.GetPlayer(((BattleGroundEY*)bg)->GetFlagCarrierGuid())) ++flagCarrierCountH; break; } case BATTLEGROUND_AB: case BATTLEGROUND_AV: // for other BG types - send default break; default: // maybe it is sent also in arena - do nothing break; } WorldPacket data(SMSG_BATTLEGROUND_PLAYER_POSITIONS, (3 + 1) * 2 + (8 + 4 + 4) * 2); data.WriteBits(flagCarrierCountA, 22); data.WriteBits(flagCarrierCountH, 22); if (flagCarrierA) data.WriteGuidMask<6, 5, 4, 7, 2, 1, 0, 3>(flagCarrierA->GetObjectGuid()); if (flagCarrierH) data.WriteGuidMask<6, 5, 4, 7, 2, 1, 0, 3>(flagCarrierH->GetObjectGuid()); if (flagCarrierA) { data.WriteGuidBytes<2, 1>(flagCarrierA->GetObjectGuid()); data << float(flagCarrierA->GetPositionY()); data.WriteGuidBytes<5, 4, 7, 0, 6, 3>(flagCarrierA->GetObjectGuid()); data << float(flagCarrierA->GetPositionX()); } if (flagCarrierH) { data.WriteGuidBytes<2, 1>(flagCarrierH->GetObjectGuid()); data << float(flagCarrierH->GetPositionY()); data.WriteGuidBytes<5, 4, 7, 0, 6, 3>(flagCarrierH->GetObjectGuid()); data << float(flagCarrierH->GetPositionX()); } SendPacket(&data); }
void WorldSession::HandleMessagechatOpcode(WorldPacket& recv_data) { uint32 type; uint32 lang; recv_data >> type; recv_data >> lang; if (type >= MAX_CHAT_MSG_TYPE) { sLog.outError("CHAT: Wrong message type received: %u", type); return; } DEBUG_LOG("CHAT: packet received. type %u, lang %u", type, lang); // prevent talking at unknown language (cheating) LanguageDesc const* langDesc = GetLanguageDescByID(lang); if (!langDesc) { SendNotification(LANG_UNKNOWN_LANGUAGE); return; } if (langDesc->skill_id != 0 && !_player->HasSkill(langDesc->skill_id)) { // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language) Unit::AuraList const& langAuras = _player->GetAurasByType(SPELL_AURA_COMPREHEND_LANGUAGE); bool foundAura = false; for (Unit::AuraList::const_iterator i = langAuras.begin(); i != langAuras.end(); ++i) { if ((*i)->GetModifier()->m_miscvalue == int32(lang)) { foundAura = true; break; } } if (!foundAura) { SendNotification(LANG_NOT_LEARNED_LANGUAGE); return; } } if (lang == LANG_ADDON) { // Disabled addon channel? if (!sWorld.getConfig(CONFIG_BOOL_ADDON_CHANNEL)) return; } // LANG_ADDON should not be changed nor be affected by flood control else { // send in universal language if player in .gmon mode (ignore spell effects) if (_player->isGameMaster()) lang = LANG_UNIVERSAL; else { // send in universal language in two side iteration allowed mode if (sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_CHAT)) lang = LANG_UNIVERSAL; else { switch (type) { case CHAT_MSG_PARTY: case CHAT_MSG_RAID: case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: // allow two side chat at group channel if two side group allowed if (sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GROUP)) lang = LANG_UNIVERSAL; break; case CHAT_MSG_GUILD: case CHAT_MSG_OFFICER: // allow two side chat at guild channel if two side guild allowed if (sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GUILD)) lang = LANG_UNIVERSAL; break; } } // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used) Unit::AuraList const& ModLangAuras = _player->GetAurasByType(SPELL_AURA_MOD_LANGUAGE); if (!ModLangAuras.empty()) lang = ModLangAuras.front()->GetModifier()->m_miscvalue; } if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND) { if (!_player->CanSpeak()) { std::string timeStr = secsToTimeString(m_muteTime - time(NULL)); SendNotification(GetMangosString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str()); return; } GetPlayer()->UpdateSpeakTime(); } } switch (type) { case CHAT_MSG_SAY: case CHAT_MSG_EMOTE: case CHAT_MSG_YELL: { std::string msg; recv_data >> msg; if (msg.empty()) break; if (ChatHandler(this).ParseCommands(msg.c_str())) break; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; if (type == CHAT_MSG_SAY) GetPlayer()->Say(msg, lang); else if (type == CHAT_MSG_EMOTE) GetPlayer()->TextEmote(msg); else if (type == CHAT_MSG_YELL) GetPlayer()->Yell(msg, lang); } break; case CHAT_MSG_WHISPER: { std::string to, msg; recv_data >> to; recv_data >> msg; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; if (!normalizePlayerName(to)) { SendPlayerNotFoundNotice(to); break; } Player* player = sObjectMgr.GetPlayer(to.c_str()); uint32 tSecurity = GetSecurity(); uint32 pSecurity = player ? player->GetSession()->GetSecurity() : SEC_PLAYER; if (!player || (tSecurity == SEC_PLAYER && pSecurity > SEC_PLAYER && !player->isAcceptWhispers())) { SendPlayerNotFoundNotice(to); return; } if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_CHAT) && tSecurity == SEC_PLAYER && pSecurity == SEC_PLAYER) { if (GetPlayer()->GetTeam() != player->GetTeam()) { SendWrongFactionNotice(); return; } } // Playerbot mod: handle whispered command to bot if (player->GetPlayerbotAI()) { player->GetPlayerbotAI()->HandleCommand(msg, *GetPlayer()); GetPlayer()->m_speakTime = 0; GetPlayer()->m_speakCount = 0; } else GetPlayer()->Whisper(msg, lang, player->GetObjectGuid()); } break; case CHAT_MSG_PARTY: { std::string msg; recv_data >> msg; if (msg.empty()) break; if (ChatHandler(this).ParseCommands(msg.c_str())) break; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; // if player is in battleground, he cannot say to battleground members by /p Group* group = GetPlayer()->GetOriginalGroup(); if (!group) { group = _player->GetGroup(); if (!group || group->isBGGroup()) return; } // Playerbot mod: broadcast message to bot members for(GroupReference* itr = group->GetFirstMember(); itr != NULL; itr=itr->next()) { Player* player = itr->getSource(); if (player && player->GetPlayerbotAI()) { player->GetPlayerbotAI()->HandleCommand(msg, *GetPlayer()); GetPlayer()->m_speakTime = 0; GetPlayer()->m_speakCount = 0; } } // END Playerbot mod WorldPacket data; ChatHandler::FillMessageData(&data, this, type, lang, msg.c_str()); group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetObjectGuid())); break; } case CHAT_MSG_GUILD: { std::string msg; recv_data >> msg; if (msg.empty()) break; if (ChatHandler(this).ParseCommands(msg.c_str())) break; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; if (GetPlayer()->GetGuildId()) if (Guild* guild = sGuildMgr.GetGuildById(GetPlayer()->GetGuildId())) guild->BroadcastToGuild(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); break; } case CHAT_MSG_OFFICER: { std::string msg; recv_data >> msg; if (msg.empty()) break; if (ChatHandler(this).ParseCommands(msg.c_str())) break; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; if (GetPlayer()->GetGuildId()) if (Guild* guild = sGuildMgr.GetGuildById(GetPlayer()->GetGuildId())) guild->BroadcastToOfficers(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); break; } case CHAT_MSG_RAID: { std::string msg; recv_data >> msg; if (msg.empty()) break; if (ChatHandler(this).ParseCommands(msg.c_str())) break; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; // if player is in battleground, he cannot say to battleground members by /ra Group* group = GetPlayer()->GetOriginalGroup(); if (!group) { group = GetPlayer()->GetGroup(); if (!group || group->isBGGroup() || !group->isRaidGroup()) return; } WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID, lang, msg.c_str()); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_RAID_LEADER: { std::string msg; recv_data >> msg; if (msg.empty()) break; if (ChatHandler(this).ParseCommands(msg.c_str())) break; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; // if player is in battleground, he cannot say to battleground members by /ra Group* group = GetPlayer()->GetOriginalGroup(); if (!group) { group = GetPlayer()->GetGroup(); if (!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(_player->GetObjectGuid())) return; } WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_LEADER, lang, msg.c_str()); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_RAID_WARNING: { std::string msg; recv_data >> msg; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; Group* group = GetPlayer()->GetGroup(); if (!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetObjectGuid()) || group->IsAssistant(GetPlayer()->GetObjectGuid()))) return; WorldPacket data; // in battleground, raid warning is sent only to players in battleground - code is ok ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_WARNING, lang, msg.c_str()); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_BATTLEGROUND: { std::string msg; recv_data >> msg; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; // battleground raid is always in Player->GetGroup(), never in GetOriginalGroup() Group* group = GetPlayer()->GetGroup(); if (!group || !group->isBGGroup()) return; WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND, lang, msg.c_str()); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_BATTLEGROUND_LEADER: { std::string msg; recv_data >> msg; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; // battleground raid is always in Player->GetGroup(), never in GetOriginalGroup() Group* group = GetPlayer()->GetGroup(); if (!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetObjectGuid())) return; WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND_LEADER, lang, msg.c_str()); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_CHANNEL: { std::string channel, msg; recv_data >> channel; recv_data >> msg; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; if (ChannelMgr* cMgr = channelMgr(_player->GetTeam())) if (Channel* chn = cMgr->GetChannel(channel, _player)) chn->Say(_player->GetObjectGuid(), msg.c_str(), lang); } break; case CHAT_MSG_AFK: { std::string msg; recv_data >> msg; if (!_player->isInCombat()) { if (_player->isAFK()) // Already AFK { if (msg.empty()) _player->ToggleAFK(); // Remove AFK else _player->autoReplyMsg = msg; // Update message } else // New AFK mode { _player->autoReplyMsg = msg.empty() ? GetMangosString(LANG_PLAYER_AFK_DEFAULT) : msg; if (_player->isDND()) _player->ToggleDND(); _player->ToggleAFK(); } } break; } case CHAT_MSG_DND: { std::string msg; recv_data >> msg; if (_player->isDND()) // Already DND { if (msg.empty()) _player->ToggleDND(); // Remove DND else _player->autoReplyMsg = msg; // Update message } else // New DND mode { _player->autoReplyMsg = msg.empty() ? GetMangosString(LANG_PLAYER_DND_DEFAULT) : msg; if (_player->isAFK()) _player->ToggleAFK(); _player->ToggleDND(); } break; } default: sLog.outError("CHAT: unknown message type %u, lang: %u", type, lang); break; } }
void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) { ObjectGuid playerGuid = holder->GetGuid(); Player* pCurrChar = new Player(this); pCurrChar->GetMotionMaster()->Initialize(); SetPlayer(pCurrChar); m_playerLoading = true; SetOnline(); // "GetAccountId()==db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) if (!pCurrChar->LoadFromDB(playerGuid, holder)) { KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick delete pCurrChar; // delete it manually delete holder; // delete all unprocessed queries m_playerLoading = false; sLog.outError("HandlePlayerLogin> LoadFromDB failed to load %s, AccountId = %u", pCurrChar->GetGuidStr().c_str(), GetAccountId()); WorldPacket data(SMSG_CHARACTER_LOGIN_FAILED, 1); data << (uint8)CHAR_LOGIN_NO_CHARACTER; SendPacket(data, true); return; } WorldPacket data(SMSG_LOGIN_VERIFY_WORLD, 20); data << pCurrChar->GetMapId(); data << pCurrChar->GetPositionX(); data << pCurrChar->GetPositionY(); data << pCurrChar->GetPositionZ(); data << pCurrChar->GetOrientation(); SendPacket(data); data.Initialize(SMSG_ACCOUNT_DATA_TIMES, 128); for (int i = 0; i < 32; ++i) data << uint32(0); SendPacket(data); // Send Spam records SendExpectedSpamRecords(); SendMotd(pCurrChar); // QueryResult *result = CharacterDatabase.PQuery("SELECT guildid,rank FROM guild_member WHERE guid = '%u'",pCurrChar->GetGUIDLow()); QueryResult* resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD); if (resultGuild) { Field* fields = resultGuild->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt32()); delete resultGuild; } else if (pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about nonexistent membership { pCurrChar->SetInGuild(0); pCurrChar->SetRank(0); } if (pCurrChar->GetGuildId() != 0) { Guild* guild = sGuildMgr.GetGuildById(pCurrChar->GetGuildId()); if (guild) { data.Initialize(SMSG_GUILD_EVENT, (1 + 1 + guild->GetMOTD().size() + 1)); data << uint8(GE_MOTD); data << uint8(1); data << guild->GetMOTD(); SendPacket(data); DEBUG_LOG("WORLD: Sent guild-motd (SMSG_GUILD_EVENT)"); guild->BroadcastEvent(GE_SIGNED_ON, pCurrChar->GetObjectGuid(), pCurrChar->GetName()); } else { // remove wrong guild data sLog.outError("Player %s (GUID: %u) marked as member of nonexistent guild (id: %u), removing guild membership for player.", pCurrChar->GetName(), pCurrChar->GetGUIDLow(), pCurrChar->GetGuildId()); pCurrChar->SetInGuild(0); } } if (!pCurrChar->isAlive()) pCurrChar->SendCorpseReclaimDelay(true); pCurrChar->SendInitialPacketsBeforeAddToMap(); // Show cinematic at the first time that player login if (!pCurrChar->getCinematic()) { pCurrChar->setCinematic(1); if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace())) pCurrChar->SendCinematicStart(rEntry->CinematicSequence); } uint32 miscRequirement = 0; AreaLockStatus lockStatus = AREA_LOCKSTATUS_OK; if (AreaTrigger const* at = sObjectMgr.GetMapEntranceTrigger(pCurrChar->GetMapId())) lockStatus = pCurrChar->GetAreaTriggerLockStatus(at, miscRequirement); else { // Some basic checks in case of a map without areatrigger MapEntry const* mapEntry = sMapStore.LookupEntry(pCurrChar->GetMapId()); if (!mapEntry) lockStatus = AREA_LOCKSTATUS_UNKNOWN_ERROR; } if (lockStatus != AREA_LOCKSTATUS_OK || !pCurrChar->GetMap()->Add(pCurrChar)) { // normal delayed teleport protection not applied (and this correct) for this case (Player object just created) AreaTrigger const* at = sObjectMgr.GetGoBackTrigger(pCurrChar->GetMapId()); if (at) lockStatus = pCurrChar->GetAreaTriggerLockStatus(at, miscRequirement); if (!at || lockStatus != AREA_LOCKSTATUS_OK || !pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation())) pCurrChar->TeleportToHomebind(); } sObjectAccessor.AddObject(pCurrChar); // DEBUG_LOG("Player %s added to Map.",pCurrChar->GetName()); pCurrChar->GetSocial()->SendFriendList(); pCurrChar->GetSocial()->SendIgnoreList(); pCurrChar->SendInitialPacketsAfterAddToMap(); static SqlStatementID updChars; static SqlStatementID updAccount; SqlStatement stmt = CharacterDatabase.CreateStatement(updChars, "UPDATE characters SET online = 1 WHERE guid = ?"); stmt.PExecute(pCurrChar->GetGUIDLow()); stmt = LoginDatabase.CreateStatement(updAccount, "UPDATE account SET active_realm_id = ? WHERE id = ?"); stmt.PExecute(realmID, GetAccountId()); pCurrChar->SetInGameTime(WorldTimer::getMSTime()); // announce group about member online (must be after add to player list to receive announce to self) if (Group* group = pCurrChar->GetGroup()) group->UpdatePlayerOnlineStatus(pCurrChar); // friend status sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetObjectGuid(), true); // Place character in world (and load zone) before some object loading pCurrChar->LoadCorpse(); // setting Ghost+speed if dead if (pCurrChar->m_deathState != ALIVE) { // not blizz like, we must correctly save and load player instead... if (pCurrChar->getRace() == RACE_NIGHTELF) pCurrChar->CastSpell(pCurrChar, 20584, TRIGGERED_OLD_TRIGGERED); // auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) pCurrChar->CastSpell(pCurrChar, 8326, TRIGGERED_OLD_TRIGGERED); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) pCurrChar->SetWaterWalk(true); } pCurrChar->TaxiFlightResume(); // Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned) pCurrChar->LoadPet(); // Set FFA PvP for non GM in non-rest mode if (sWorld.IsFFAPvPRealm() && !pCurrChar->isGameMaster() && !pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING)) pCurrChar->SetPvPFreeForAll(true); if (pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP)) pCurrChar->UpdatePvPContested(true); // Apply at_login requests if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_SPELLS)) { pCurrChar->resetSpells(); SendNotification(LANG_RESET_SPELLS); } if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS)) { pCurrChar->resetTalents(true); SendNotification(LANG_RESET_TALENTS); // we can use SMSG_TALENTS_INVOLUNTARILY_RESET here } if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TAXINODES)) { pCurrChar->InitTaxiNodes(); pCurrChar->RemoveAtLoginFlag(AT_LOGIN_RESET_TAXINODES, true); SendNotification("Your taxi nodes have been reset."); } if (pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST)) pCurrChar->RemoveAtLoginFlag(AT_LOGIN_FIRST); // show time before shutdown if shutdown planned. if (sWorld.IsShutdowning()) sWorld.ShutdownMsg(true, pCurrChar); if (sWorld.getConfig(CONFIG_BOOL_ALL_TAXI_PATHS)) pCurrChar->SetTaxiCheater(true); if (pCurrChar->isGameMaster()) SendNotification(LANG_GM_ON); if (!pCurrChar->isGMVisible()) { SendNotification(LANG_INVISIBLE_INVISIBLE); SpellEntry const* invisibleAuraInfo = sSpellTemplate.LookupEntry<SpellEntry>(sWorld.getConfig(CONFIG_UINT32_GM_INVISIBLE_AURA)); if (invisibleAuraInfo && IsSpellAppliesAura(invisibleAuraInfo)) pCurrChar->CastSpell(pCurrChar, invisibleAuraInfo, TRIGGERED_OLD_TRIGGERED); } std::string IP_str = GetRemoteAddress(); sLog.outChar("Account: %d (IP: %s) Login Character:[%s] (guid: %u)", GetAccountId(), IP_str.c_str(), pCurrChar->GetName(), pCurrChar->GetGUIDLow()); if (!pCurrChar->IsStandState() && !pCurrChar->hasUnitState(UNIT_STAT_STUNNED)) pCurrChar->SetStandState(UNIT_STAND_STATE_STAND); m_playerLoading = false; delete holder; }
/** * Handles the Packet sent by the client when sending a mail. * * This methods takes the packet sent by the client and performs the following actions: * - Checks whether the mail is valid: i.e. can he send the selected items, * does he have enough money, etc. * - Creates a MailDraft and adds the needed items, money, cost data. * - Sends the mail. * * Depending on the outcome of the checks performed the player will recieve a different * MailResponseResult. * * @see MailResponseResult * @see SendMailResult() * * @param recv_data the WorldPacket containing the data sent by the client. */ void WorldSession::HandleSendMail(WorldPacket& recv_data) { ObjectGuid mailboxGuid; ObjectGuid itemGuid; uint64 unk3; std::string receiver, subject, body; uint32 unk1, unk2, money, COD; uint8 unk4; recv_data >> mailboxGuid; recv_data >> receiver; recv_data >> subject; recv_data >> body; recv_data >> unk1; // stationery? recv_data >> unk2; // 0x00000000 recv_data >> itemGuid; recv_data >> money >> COD; // money and cod recv_data >> unk3; // const 0 recv_data >> unk4; // const 0 // packet read complete, now do check if (!CheckMailBox(mailboxGuid)) return; if (receiver.empty()) return; Player* pl = _player; ObjectGuid rc; if (normalizePlayerName(receiver)) rc = sObjectMgr.GetPlayerGuidByName(receiver); if (!rc) { DETAIL_LOG("%s is sending mail to %s (GUID: nonexistent!) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", pl->GetGuidStr().c_str(), receiver.c_str(), subject.c_str(), body.c_str(), itemGuid ? 1 : 0, money, COD, unk1, unk2); pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND); return; } DETAIL_LOG("%s is sending mail to %s with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", pl->GetGuidStr().c_str(), rc.GetString().c_str(), subject.c_str(), body.c_str(), itemGuid ? 1 : 0, money, COD, unk1, unk2); if (pl->GetObjectGuid() == rc) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANNOT_SEND_TO_SELF); return; } uint32 reqmoney = money + 30; if (pl->GetMoney() < reqmoney) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY); return; } Player* receive = sObjectMgr.GetPlayer(rc); Team rc_team; uint8 mails_count = 0; // do not allow to send to one player more than 100 mails if (receive) { rc_team = receive->GetTeam(); mails_count = receive->GetMailSize(); } else { rc_team = sObjectMgr.GetPlayerTeamByGUID(rc); if (QueryResult* result = CharacterDatabase.PQuery("SELECT COUNT(*) FROM mail WHERE receiver = '%u'", rc.GetCounter())) { Field* fields = result->Fetch(); mails_count = fields[0].GetUInt32(); delete result; } } // do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255.. if (mails_count > 100) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_CAP_REACHED); return; } // check the receiver's Faction... if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_MAIL) && pl->GetTeam() != rc_team && GetSecurity() == SEC_PLAYER) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_YOUR_TEAM); return; } uint32 rc_account = receive ? receive->GetSession()->GetAccountId() : sObjectMgr.GetPlayerAccountIdByGUID(rc); Item* item = NULL; if (itemGuid) { item = pl->GetItemByGuid(itemGuid); // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail) if (!item) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } if (!item->CanBeTraded()) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } if ((item->GetProto()->Flags & ITEM_FLAG_CONJURED) || item->GetUInt32Value(ITEM_FIELD_DURATION)) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } if (COD && item->HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED)) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANT_SEND_WRAPPED_COD); return; } } pl->SendMailResult(0, MAIL_SEND, MAIL_OK); // pl->ModifyMoney(-int32(reqmoney)); bool needItemDelay = false; MailDraft draft(subject, body); if (itemGuid || money > 0) { uint32 rc_account = 0; if (receive) rc_account = receive->GetSession()->GetAccountId(); else rc_account = sObjectMgr.GetPlayerAccountIdByGUID(rc); if (item) { if (GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE)) { sLog.outCommand(GetAccountId(), "GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) to player: %s (Account: %u)", GetPlayerName(), GetAccountId(), item->GetProto()->Name1, item->GetEntry(), item->GetCount(), receiver.c_str(), rc_account); } pl->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true); CharacterDatabase.BeginTransaction(); item->DeleteFromInventoryDB(); // deletes item from character's inventory item->SaveToDB(); // recursive and not have transaction guard into self, item not in inventory and can be save standalone // owner in data will set at mail receive and item extracting CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", rc.GetCounter(), item->GetGUIDLow()); CharacterDatabase.CommitTransaction(); draft.AddItem(item); // if item send to character at another account, then apply item delivery delay needItemDelay = pl->GetSession()->GetAccountId() != rc_account; } if (money > 0 && GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE)) { sLog.outCommand(GetAccountId(), "GM %s (Account: %u) mail money: %u to player: %s (Account: %u)", GetPlayerName(), GetAccountId(), money, receiver.c_str(), rc_account); } } // If theres is an item, there is a one hour delivery delay if sent to another account's character. uint32 deliver_delay = needItemDelay ? sWorld.getConfig(CONFIG_UINT32_MAIL_DELIVERY_DELAY) : 0; // will delete item or place to receiver mail list draft .SetMoney(money) .SetCOD(COD) .SendMailTo(MailReceiver(receive, rc), pl, body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay); CharacterDatabase.BeginTransaction(); pl->SaveInventoryAndGoldToDB(); CharacterDatabase.CommitTransaction(); }