// hacky way for the mark of the faceless, needs core support // PLEASE REMOVE FOR REVISION! void CheckForMark(ObjectGuid m_uiTargetGUID) { if(m_uiTargetGUID.GetRawValue() == 0) return; m_bHasSimphon = false; Map *map = m_creature->GetMap(); Unit* pTarget = m_creature->GetMap()->GetUnit( m_uiTargetGUID); if (map->IsDungeon()) { Map::PlayerList const &PlayerList = map->GetPlayers(); if (PlayerList.isEmpty()) return; for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if(pTarget && pTarget->isAlive() && !m_bHasSimphon && m_uiTargetGUID.GetRawValue() != i->getSource()->GetObjectGuid().GetRawValue()) { if (i->getSource()->isAlive() && pTarget->GetDistance2d(i->getSource()) < 10.0f) { DoCast(pTarget, SPELL_MARK_SIMPHON); m_bHasSimphon = true; } } } } }
void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket ) { DETAIL_LOG("CMSG_PET_SPELL_AUTOCAST"); ObjectGuid guid; uint32 spellid; uint8 state; //1 for on, 0 for off recvPacket >> guid >> spellid >> state; Creature* pet = _player->GetMap()->GetAnyTypeCreature(guid); if (!pet || (guid.GetRawValue() != _player->GetPetGUID() && guid.GetRawValue() != _player->GetCharmGUID())) { sLog.outError("HandlePetSpellAutocastOpcode. %s isn't pet of %s .", guid.GetString().c_str(), GetPlayer()->GetObjectGuid().GetString().c_str()); return; } // do not add not learned spells/ passive spells if (!pet->HasSpell(spellid) || IsPassiveSpell(spellid)) return; CharmInfo *charmInfo = pet->GetCharmInfo(); if (!charmInfo) { sLog.outError("WorldSession::HandlePetSpellAutocastOpcod: %s is considered pet-like but doesn't have a charminfo!", guid.GetString().c_str()); return; } if (pet->isCharmed()) //state can be used as boolean pet->GetCharmInfo()->ToggleCreatureAutocast(spellid, state); else ((Pet*)pet)->ToggleAutocast(spellid, state); charmInfo->SetSpellAutocast(spellid,state); }
void PacketWorker::BuildSendPlayVisual(WorldPacket* data, ObjectGuid guid, uint32 value, bool impact) { *data << uint32(0); // unk, seems always 0 *data << uint32(value); *data << uint32(impact ? 1 : 0); uint8 guidMask[8] = { 4, 7, 5, 3, 1, 2, 0, 6 }; uint8 byteOrder[8] = { 0, 4, 1, 6, 7, 2, 3, 5 }; data->WriteGuidMask(guid.GetRawValue(), guidMask, 8); data->WriteGuidBytes(guid.GetRawValue(), byteOrder, 8, 0); }
void WorldSession::HandleEquipmentSetSaveOpcode(WorldPacket& recv_data) { DEBUG_LOG("CMSG_EQUIPMENT_SET_SAVE"); ObjectGuid setGuid; uint32 index; std::string name; std::string iconName; recv_data >> setGuid.ReadAsPacked(); recv_data >> index; recv_data >> name; recv_data >> iconName; if (index >= MAX_EQUIPMENT_SET_INDEX) // client set slots amount return; EquipmentSet eqSet; eqSet.Guid = setGuid.GetRawValue(); eqSet.Name = name; eqSet.IconName = iconName; eqSet.state = EQUIPMENT_SET_NEW; for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) { ObjectGuid itemGuid; recv_data >> itemGuid.ReadAsPacked(); // equipment manager sends "1" (as raw GUID) for slots set to "ignore" (not touch slot at equip set) if (itemGuid.GetRawValue() == 1) { // ignored slots saved as bit mask because we have no free special values for Items[i] eqSet.IgnoreMask |= 1 << i; continue; } Item* item = _player->GetItemByPos(INVENTORY_SLOT_BAG_0, i); if (!item && itemGuid) // cheating check 1 return; if (item && item->GetObjectGuid() != itemGuid) // cheating check 2 return; eqSet.Items[i] = itemGuid.GetCounter(); } _player->SetEquipmentSet(index, eqSet); }
void WorldSession::SendLfgRoleCheckUpdate(LFGRoleCheck const& roleCheck) { WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE); data << uint32(roleCheck.state); data << uint8(roleCheck.state == LFG_ROLECHECK_INITIALITING); std::set<uint32> dungeons; if (roleCheck.randomDungeonID) dungeons.insert(roleCheck.randomDungeonID); else dungeons = roleCheck.dungeonList; data << uint8(dungeons.size()); if (!dungeons.empty()) for (std::set<uint32>::iterator it = dungeons.begin(); it != dungeons.end(); ++it) data << uint32(sLFGMgr.GetDungeonEntry(*it)); data << uint8(roleCheck.currentRoles.size()); if (!roleCheck.currentRoles.empty()) { ObjectGuid leaderGuid = ObjectGuid(roleCheck.leaderGuidRaw); uint8 leaderRoles = roleCheck.currentRoles.find(leaderGuid)->second; Player* pLeader = ObjectAccessor::FindPlayer(leaderGuid); data << uint64(leaderGuid.GetRawValue()); data << uint8(leaderRoles > 0); data << uint32(leaderRoles); data << uint8(pLeader->getLevel()); for (roleMap::const_iterator rItr = roleCheck.currentRoles.begin(); rItr != roleCheck.currentRoles.end(); ++rItr) { if (rItr->first == leaderGuid) continue; // exclude the leader ObjectGuid plrGuid = rItr->first; Player* pPlayer = ObjectAccessor::FindPlayer(plrGuid); data << uint64(plrGuid.GetRawValue()); data << uint8(rItr->second > 0); data << uint32(rItr->second); data << uint8(pPlayer->getLevel()); } } SendPacket(&data); }
string WhoAction::QuerySkill(string text) { ostringstream out; InitSkills(); for (map<uint32, string>::iterator i = skills.begin(); i != skills.end(); ++i) { string name = i->second; uint16 skill = i->first; if (!strcmpi(text.c_str(), name.c_str()) && bot->HasSkill(skill)) { string skillName = i->second; uint32 spellId = AI_VALUE2(uint32, "spell id", skillName); uint16 value = bot->GetSkillValue(skill); uint16 maxSkill = bot->GetMaxSkillValue(skill); ObjectGuid guid = bot->GetObjectGuid(); string data = "0"; out << "|cFFFFFF00|Htrade:" << spellId << ":" << value << ":" << maxSkill << ":" << std::hex << std::uppercase << guid.GetRawValue() << std::nouppercase << std::dec << ":" << data << "|h[" << skills[skill] << "]|h|r" << " |h|cff00ff00" << value << "|h|cffffffff/" << "|h|cff00ff00" << maxSkill << "|h|cffffffff "; } } return out.str(); }
void LFGQueue::RemoveFromQueue(ObjectGuid guid) { RemoveFromNewQueue(guid); RemoveFromCurrentQueue(guid); RemoveFromCompatibles(guid); std::ostringstream o; o << guid.GetRawValue(); std::string sguid = o.str(); LfgQueueDataContainer::iterator itDelete = QueueDataStore.end(); for (LfgQueueDataContainer::iterator itr = QueueDataStore.begin(); itr != QueueDataStore.end(); ++itr) if (itr->first != guid) { if (std::string::npos != itr->second.bestCompatible.find(sguid)) { itr->second.bestCompatible.clear(); FindBestCompatibleInQueue(itr); } } else itDelete = itr; if (itDelete != QueueDataStore.end()) QueueDataStore.erase(itDelete); }
void WorldSession::HandleAttackSwingOpcode(WorldPacket & recv_data) { ObjectGuid guid; recv_data >> guid; DEBUG_LOG("WORLD: Recvd CMSG_ATTACKSWING Message %s", guid.GetString().c_str()); Unit *pEnemy = ObjectAccessor::GetUnit(*_player, guid.GetRawValue()); if (!pEnemy) { if (!guid.IsUnit()) sLog.outError("WORLD: %s isn't player, pet or creature", guid.GetString().c_str()); else sLog.outError("WORLD: Enemy %s not found", guid.GetString().c_str()); // stop attack state at client SendAttackStop(NULL); return; } if (!_player->canAttack(pEnemy)) { sLog.outError("WORLD: Enemy %s is friendly",guid.GetString().c_str()); // stop attack state at client SendAttackStop(pEnemy); return; } _player->Attack(pEnemy,true); }
void BattleGround::AddPlayer(Player *plr) { // remove afk from player if (plr->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK)) plr->ToggleAFK(); // score struct must be created in inherited class ObjectGuid guid = plr->GetObjectGuid(); uint32 team = plr->GetBGTeam(); BattleGroundPlayer bp; bp.LastOnlineTime = 0; bp.Team = team; // Add to list/maps m_Players[guid.GetRawValue()] = bp; UpdatePlayersCountByTeam(team, false); // +1 player WorldPacket data; sBattleGroundMgr.BuildPlayerJoinedBattleGroundPacket(&data, plr); SendPacketToTeam(team, &data, plr, false); // Log DETAIL_LOG("BATTLEGROUND: Player %s joined the battle.", plr->GetName()); }
uint64 BSWScriptedInstance::GetInstanceObjectGUID(uint32 entry) { ObjectGuid guid = GetInstanceObjectGuid(entry); if (guid.IsEmpty()) return 0; else return guid.GetRawValue(); }
bool ArenaTeam::HaveMember(ObjectGuid guid) const { for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) if(itr->guid == guid.GetRawValue()) return true; return false; }
void WorldSession::HandleEquipmentSetDelete(WorldPacket &recv_data) { sLog.outDebug("CMSG_EQUIPMENT_SET_DELETE"); ObjectGuid setGuid; recv_data >> setGuid.ReadAsPacked(); _player->DeleteEquipmentSet(setGuid.GetRawValue()); }
void WorldSession::HandleRequestVehicleSwitchSeat(WorldPacket &recv_data) { sLog.outDebug("WORLD: Recvd CMSG_REQUEST_VEHICLE_SWITCH_SEAT"); recv_data.hexlike(); uint64 vehicleGUID = _player->GetVehicleGUID(); if(!vehicleGUID) // something wrong here... return; if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID)) { ObjectGuid guid; recv_data >> guid.ReadAsPacked(); int8 seatId = 0; recv_data >> seatId; if(!guid.IsEmpty()) { if(vehicleGUID != guid.GetRawValue()) { if(Vehicle *veh = ObjectAccessor::GetVehicle(guid.GetRawValue())) { if(!_player->IsWithinDistInMap(veh, 10)) return; if(Vehicle *v = veh->FindFreeSeat(&seatId, false)) { vehicle->RemovePassenger(_player); _player->EnterVehicle(v, seatId, false); } } return; } } if(Vehicle *v = vehicle->FindFreeSeat(&seatId, false)) { vehicle->RemovePassenger(_player); _player->EnterVehicle(v, seatId, false); } }
void WorldSession::HandleForceSpeedChangeAck(WorldPacket& recv_data) { DEBUG_LOG("WORLD: Recvd CMSG_SPEED_CHANGE_ACK"); /* extract packet */ ObjectGuid guid; uint32 unk1; MovementInfo movementInfo; float newspeed; recv_data >> guid; recv_data >> unk1; // counter or moveEvent recv_data >> movementInfo; recv_data >> newspeed; // now can skip not our packet if (GetPlayer()->GetGUID() != guid.GetRawValue()) return; /*----------------*/ // Save movement flags GetPlayer()->SetUnitMovementFlags(movementInfo.GetMovementFlags()); // client ACK send one packet for mounted/run case and need skip all except last from its // in other cases anti-cheat check can be fail in false case UnitMoveType move_type; UnitMoveType force_move_type; //static char const* move_type_name[MAX_MOVE_TYPE] = {"Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack"}; uint16 opcode = recv_data.GetOpcode(); switch (opcode) { case CMSG_FORCE_WALK_SPEED_CHANGE_ACK: move_type = MOVE_WALK; force_move_type = MOVE_WALK; break; case CMSG_FORCE_RUN_SPEED_CHANGE_ACK: move_type = MOVE_RUN; force_move_type = MOVE_RUN; break; case CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK: move_type = MOVE_RUN_BACK; force_move_type = MOVE_RUN_BACK; break; case CMSG_FORCE_SWIM_SPEED_CHANGE_ACK: move_type = MOVE_SWIM; force_move_type = MOVE_SWIM; break; case CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK: move_type = MOVE_SWIM_BACK; force_move_type = MOVE_SWIM_BACK; break; case CMSG_FORCE_TURN_RATE_CHANGE_ACK: move_type = MOVE_TURN_RATE; force_move_type = MOVE_TURN_RATE; break; case CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT; force_move_type = MOVE_FLIGHT; break; case CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT_BACK; force_move_type = MOVE_FLIGHT_BACK; break; default: sLog.outError("WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: %u", opcode); return; } // skip all forced speed changes except last and unexpected // in run/mounted case used one ACK and it must be skipped.m_forced_speed_changes[MOVE_RUN] store both. if (GetPlayer()->m_forced_speed_changes[force_move_type] > 0) { --GetPlayer()->m_forced_speed_changes[force_move_type]; if (GetPlayer()->m_forced_speed_changes[force_move_type] > 0) return; } }
void PacketWorker::BuildSetMovementPacket(Opcodes op, WorldPacket* data, ObjectGuid guid, uint32 value) { switch(op) { case SMSG_FORCE_MOVE_ROOT: { uint8 guidMask[8] = { 2, 7, 6, 0, 5, 4, 1, 3 }; uint8 byteOrder[8] = { 1, 0, 2, 5, 3, 4, 7, 6 }; data->WriteGuidMask(guid.GetRawValue(), guidMask, 8); data->WriteGuidBytes(guid.GetRawValue(), byteOrder, 4, 0); *data << uint32(value); data->WriteGuidBytes(guid.GetRawValue(), byteOrder, 4, 4); data->FlushBits(); break; } case SMSG_FORCE_MOVE_UNROOT: { uint8 guidMask[8] = { 0, 1, 3, 7, 5, 2, 4, 6 }; uint8 byteOrder[8] = { 3, 6, 1, 2, 0, 7, 4, 5 }; data->WriteGuidMask(guid.GetRawValue(), guidMask, 8); data->WriteGuidBytes(guid.GetRawValue(), byteOrder, 3, 0); *data << uint32(value); data->WriteGuidBytes(guid.GetRawValue(), byteOrder, 5, 3); break; } default: { sLog.outError("Called PacketWorker::BuildSetMovementPacket for unknown opcode %u", op); break; } } }
void WorldSession::HandleEquipmentSetUseOpcode(WorldPacket& recv_data) { DEBUG_LOG("CMSG_EQUIPMENT_SET_USE"); recv_data.hexlike(); for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) { ObjectGuid itemGuid; uint8 srcbag, srcslot; recv_data >> itemGuid.ReadAsPacked(); recv_data >> srcbag >> srcslot; DEBUG_LOG("Item (%s): srcbag %u, srcslot %u", itemGuid.GetString().c_str(), srcbag, srcslot); // check if item slot is set to "ignored" (raw value == 1), must not be unequipped then if (itemGuid.GetRawValue() == 1) continue; Item* item = _player->GetItemByGuid(itemGuid); uint16 dstpos = i | (INVENTORY_SLOT_BAG_0 << 8); if (!item) { Item* uItem = _player->GetItemByPos(INVENTORY_SLOT_BAG_0, i); if (!uItem) continue; ItemPosCountVec sDest; InventoryResult msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, sDest, uItem, false); if (msg == EQUIP_ERR_OK) { _player->RemoveItem(INVENTORY_SLOT_BAG_0, i, true); _player->StoreItem(sDest, uItem, true); } else _player->SendEquipError(msg, uItem, NULL); continue; } if (item->GetPos() == dstpos) continue; _player->SwapItem(item->GetPos(), dstpos); } WorldPacket data(SMSG_USE_EQUIPMENT_SET_RESULT, 1); data << uint8(0); // 4 - equipment swap failed - inventory is full SendPacket(&data); }
/** Remove from cached compatible dungeons any entry that contains the given guid @param[in] guid Guid to remove from compatible cache */ void LFGQueue::RemoveFromCompatibles(ObjectGuid guid) { std::stringstream out; out << guid.GetRawValue(); std::string strGuid = out.str(); TC_LOG_DEBUG("lfg.queue.data.compatibles.remove", "Removing %s", guid.ToString().c_str()); for (LfgCompatibleContainer::iterator itNext = CompatibleMapStore.begin(); itNext != CompatibleMapStore.end();) { LfgCompatibleContainer::iterator it = itNext++; if (std::string::npos != it->first.find(strGuid)) CompatibleMapStore.erase(it); } }
void WorldSession::HandleLfgGetPartyInfo(WorldPacket& recv_data) { DEBUG_LOG("CMSG_LFG_GET_PARTY_INFO"); Player* pPlayer = GetPlayer(); uint64 guid = pPlayer->GetObjectGuid().GetRawValue(); // send later in packet Group* pGroup = pPlayer->GetGroup(); if (!pGroup) return; partyForbidden groupMap; for (GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* pGroupPlayer = itr->getSource(); if (!pGroupPlayer) continue; ObjectGuid pPlayerGuid = pGroupPlayer->GetObjectGuid(); if (pPlayerGuid.GetRawValue() != guid) groupMap[pPlayerGuid] = sLFGMgr.FindRandomDungeonsNotForPlayer(pGroupPlayer); } uint32 packetSize = 0; for (partyForbidden::iterator it = groupMap.begin(); it != groupMap.end(); ++it) packetSize += 12 + uint32(it->second.size()) * 8; DEBUG_LOG("Sending SMSG_LFG_PARTY_INFO..."); WorldPacket data(SMSG_LFG_PARTY_INFO, packetSize); data << uint8(groupMap.size()); for (partyForbidden::iterator it = groupMap.begin(); it != groupMap.end(); ++it) { dungeonForbidden dungeonInfo = it->second; data << uint64(it->first); // object guid of player data << uint32(dungeonInfo.size()); // amount of their locked dungeons for (dungeonForbidden::iterator itr = dungeonInfo.begin(); itr != dungeonInfo.end(); ++itr) { data << uint32(itr->first); // dungeon entry data << uint32(itr->second); // reason for dungeon being forbidden/locked } } SendPacket(&data); }
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 WorldSession::HandleEquipmentSetSave(WorldPacket &recv_data) { sLog.outDebug("CMSG_EQUIPMENT_SET_SAVE"); ObjectGuid setGuid; uint32 index; std::string name; std::string iconName; recv_data >> setGuid.ReadAsPacked(); recv_data >> index; recv_data >> name; recv_data >> iconName; if(index >= MAX_EQUIPMENT_SET_INDEX) // client set slots amount return; EquipmentSet eqSet; eqSet.Guid = setGuid.GetRawValue(); eqSet.Name = name; eqSet.IconName = iconName; eqSet.state = EQUIPMENT_SET_NEW; for(uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) { ObjectGuid itemGuid; recv_data >> itemGuid.ReadAsPacked(); Item *item = _player->GetItemByPos(INVENTORY_SLOT_BAG_0, i); if(!item && !itemGuid.IsEmpty()) // cheating check 1 return; if(item && item->GetObjectGuid() != itemGuid) // cheating check 2 return; eqSet.Items[i] = itemGuid.GetCounter(); } _player->SetEquipmentSet(index, eqSet); }
std::string CalendarEvent::BuildCalendarMailSubject(ObjectGuid remover) const { std::ostringstream strm; strm << remover.GetRawValue() << ':' << _title; return strm.str(); }
void HandleDummyLaunchTarget(SpellEffIndex /*effIndex*/) { ObjectGuid targetGUID; if (Unit* unitTarget = GetHitUnit()) targetGUID = unitTarget->GetGUID(); // we're handling SPELL_EFFECT_DUMMY in effIndex 0 here TC_LOG_INFO("misc", "Spell %u with SPELL_EFFECT_DUMMY is just launched at it's target: " UI64FMTD "!", GetSpellInfo()->Id, targetGUID.GetRawValue()); }
void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket ) { DETAIL_LOG("WORLD: CMSG_PET_CAST_SPELL"); ObjectGuid guid; uint32 spellid; uint8 cast_count; uint8 unk_flags; // flags (if 0x02 - some additional data are received) recvPacket >> guid >> cast_count >> spellid >> unk_flags; DEBUG_LOG("WORLD: CMSG_PET_CAST_SPELL, %s, cast_count: %u, spellid %u, unk_flags %u", guid.GetString().c_str(), cast_count, spellid, unk_flags); Creature* pet = _player->GetMap()->GetAnyTypeCreature(guid); if (!pet || (guid.GetRawValue() != _player->GetPetGUID() && guid.GetRawValue() != _player->GetCharmGUID())) { sLog.outError("HandlePetCastSpellOpcode: %s isn't pet of %s .", guid.GetString().c_str(), GetPlayer()->GetObjectGuid().GetString().c_str()); return; } SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid); if (!spellInfo) { sLog.outError("WORLD: unknown PET spell id %i", spellid); return; } if (pet->GetCharmInfo() && pet->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo)) return; // do not cast not learned spells if (!pet->HasSpell(spellid) || IsPassiveSpell(spellInfo)) return; SpellCastTargets targets; recvPacket >> targets.ReadForCaster(pet); pet->clearUnitState(UNIT_STAT_MOVING); Spell *spell = new Spell(pet, spellInfo, false); spell->m_cast_count = cast_count; // probably pending spell cast spell->m_targets = targets; SpellCastResult result = spell->CheckPetCast(NULL); if (result == SPELL_CAST_OK) { pet->AddCreatureSpellCooldown(spellid); if (pet->IsPet()) { //10% chance to play special pet attack talk, else growl //actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell if(((Pet*)pet)->getPetType() == SUMMON_PET && (urand(0, 100) < 10)) pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL); else pet->SendPetAIReaction(); } spell->prepare(&(spell->m_targets)); } else { pet->SendPetCastFail(spellid, result); if (!pet->HasSpellCooldown(spellid)) GetPlayer()->SendClearCooldown(spellid, pet); spell->finish(false); delete spell; } }
bool GossipHelloAction::Execute(Event event) { ObjectGuid guid; WorldPacket &p = event.getPacket(); if (p.empty()) { Player* master = GetMaster(); if (master && master->GetSelectedUnit()) guid = master->GetSelectedUnit()->GetGUID(); } else { p.rpos(0); p >> guid; } if (!guid) return false; Creature *pCreature = bot->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE); if (!pCreature) { sLog->outMessage("playerbot", LOG_LEVEL_DEBUG, "[PlayerbotMgr]: HandleMasterIncomingPacket - Received CMSG_GOSSIP_HELLO %d not found or you can't interact with him.", guid.GetRawValue()); return false; } GossipMenuItemsMapBounds pMenuItemBounds = sObjectMgr->GetGossipMenuItemsMapBounds(pCreature->GetCreatureTemplate()->GossipMenuId); if (pMenuItemBounds.first == pMenuItemBounds.second) return false; WorldPacket p1; p1 << guid; bot->GetSession()->HandleGossipHelloOpcode(p1); bot->SetFacingToObject(pCreature); ostringstream out; out << "--- " << pCreature->GetName() << " ---"; ai->TellMasterNoFacing(out.str()); GossipMenu& menu = bot->PlayerTalkClass->GetGossipMenu(); int i = 0, loops = 0; set<uint32> alreadyTalked; while (i < menu.GetMenuItemCount() && loops++ < 100) { GossipMenuItem const* item = menu.GetItem(i); ai->TellMasterNoFacing(item->Message); if (item->OptionType < 1000 && item->OptionType != GOSSIP_OPTION_GOSSIP) { i++; continue; } WorldPacket p1; std::string code; p1 << guid << menu.GetMenuId() << i << code; bot->GetSession()->HandleGossipSelectOptionOpcode(p1); i = 0; } bot->TalkedToCreature(pCreature->GetEntry(), pCreature->GetGUID()); return true; }
/** * 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) { sLog.outError("WORLD: CMSG_SEND_MAIL"); ObjectGuid mailboxGuid; uint64 money, COD; std::string receiver, subject, body; uint8 receiverLen, subjectLen, bodyLen; uint32 unk1, unk2; recv_data >> unk1; // stationery? recv_data >> unk2; // 0x00000000 recv_data >> money >> COD; // money and cod bodyLen = recv_data.ReadBits(12); subjectLen = recv_data.ReadBits(9); uint8 items_count = recv_data.ReadBits(5); // attached items count if (items_count > MAX_MAIL_ITEMS) // client limit { GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS); recv_data.rfinish(); // set to end to avoid warnings spam return; } recv_data.ReadGuidMask<0>(mailboxGuid); ObjectGuid itemGuids[MAX_MAIL_ITEMS]; for (uint8 i = 0; i < items_count; ++i) recv_data.ReadGuidMask<2, 6, 3, 7, 1, 0, 4, 5>(itemGuids[i]); recv_data.ReadGuidMask<3, 4>(mailboxGuid); receiverLen = recv_data.ReadBits(7); recv_data.ReadGuidMask<2, 6, 1, 7, 5>(mailboxGuid); recv_data.ReadGuidBytes<4>(mailboxGuid); for (uint8 i = 0; i < items_count; ++i) { recv_data.ReadGuidBytes<6, 1, 7, 2>(itemGuids[i]); recv_data.read_skip<uint8>(); // item slot in mail, not used recv_data.ReadGuidBytes<3, 0, 4, 5>(itemGuids[i]); } recv_data.ReadGuidBytes<7, 3, 6, 5>(mailboxGuid); subject = recv_data.ReadString(subjectLen); receiver = recv_data.ReadString(receiverLen); recv_data.ReadGuidBytes<2, 0>(mailboxGuid); body = recv_data.ReadString(bodyLen); recv_data.ReadGuidBytes<1>(mailboxGuid); DEBUG_LOG("WORLD: CMSG_SEND_MAIL receiver '%s' subject '%s' body '%s' mailbox " UI64FMTD " money " UI64FMTD " COD " UI64FMTD " unkt1 %u unk2 %u", receiver.c_str(), subject.c_str(), body.c_str(), mailboxGuid.GetRawValue(), money, COD, unk1, unk2); // packet read complete, now do check if (!CheckMailBox(mailboxGuid)) return; if (receiver.empty()) return; Player* pl = _player; ObjectGuid rc; if (normalizePlayerName(receiver)) rc = sAccountMgr.GetPlayerGuidByName(receiver); if (!rc) { DEBUG_LOG("%s is sending mail to %s (GUID: nonexistent!) with subject %s and body %s includes %u items, " UI64FMTD " copper and " UI64FMTD " COD copper with unk1 = %u, unk2 = %u", pl->GetGuidStr().c_str(), receiver.c_str(), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2); pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND); return; } DEBUG_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(), items_count, money, COD, unk1, unk2); if (pl->GetObjectGuid() == rc) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANNOT_SEND_TO_SELF); return; } uint32 cost = items_count ? 30 * items_count : 30; // price hardcoded in client uint64 reqmoney = cost + money; 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 = sAccountMgr.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() : sAccountMgr.GetPlayerAccountIdByGUID(rc); Item* items[MAX_MAIL_ITEMS]; for (uint8 i = 0; i < items_count; ++i) { if (!itemGuids[i].IsItem()) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } Item* item = pl->GetItemByGuid(itemGuids[i]); // 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(true)) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM); return; } if (item->IsBoundAccountWide() && item->IsSoulBound() && pl->GetSession()->GetAccountId() != rc_account) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS); return; } if ((item->GetProto()->Flags & ITEM_FLAG_CONJURED) || item->GetUInt32Value(ITEM_FIELD_DURATION)) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM); return; } if (COD && item->HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED)) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANT_SEND_WRAPPED_COD); return; } items[i] = item; } pl->SendMailResult(0, MAIL_SEND, MAIL_OK); pl->ModifyMoney(-int64(reqmoney)); pl->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost); bool needItemDelay = false; MailDraft draft(subject, body); if (items_count > 0 || money > 0) { if (items_count > 0) { for (uint8 i = 0; i < items_count; ++i) { Item* item = items[i]; 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); } item->SetNotRefundable(GetPlayer()); // makes the item no longer refundable pl->MoveItemFromInventory(items[i]->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: " UI64FMTD " 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(); }
void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) { /* extract packet */ ObjectGuid guid; MovementInfo movementInfo; float newspeed; recv_data >> guid; recv_data >> Unused<uint32>(); // counter or moveEvent recv_data >> movementInfo; recv_data >> newspeed; // now can skip not our packet if (_player->GetGUID() != guid.GetRawValue()) return; // continue parse packet /*----------------*/ // client ACK send one packet for mounted/run case and need skip all except last from its // in other cases anti-cheat check can be fail in false case UnitMoveType move_type; UnitMoveType force_move_type; static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack" }; uint16 opcode = recv_data.GetOpcode(); switch (opcode) { case CMSG_FORCE_WALK_SPEED_CHANGE_ACK: move_type = MOVE_WALK; force_move_type = MOVE_WALK; break; case CMSG_FORCE_RUN_SPEED_CHANGE_ACK: move_type = MOVE_RUN; force_move_type = MOVE_RUN; break; case CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK: move_type = MOVE_RUN_BACK; force_move_type = MOVE_RUN_BACK; break; case CMSG_FORCE_SWIM_SPEED_CHANGE_ACK: move_type = MOVE_SWIM; force_move_type = MOVE_SWIM; break; case CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK: move_type = MOVE_SWIM_BACK; force_move_type = MOVE_SWIM_BACK; break; case CMSG_FORCE_TURN_RATE_CHANGE_ACK: move_type = MOVE_TURN_RATE; force_move_type = MOVE_TURN_RATE; break; case CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT; force_move_type = MOVE_FLIGHT; break; case CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT_BACK; force_move_type = MOVE_FLIGHT_BACK; break; default: sLog.outLog(LOG_DEFAULT, "ERROR: WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: %u", opcode); return; } // skip all forced speed changes except last and unexpected // in run/mounted case used one ACK and it must be skipped.m_forced_speed_changes[MOVE_RUN} store both. if (_player->m_forced_speed_changes[force_move_type] > 0) { --_player->m_forced_speed_changes[force_move_type]; if (_player->m_forced_speed_changes[force_move_type] > 0) return; } if (!_player->GetTransport() && fabs(_player->GetSpeed(move_type) - newspeed) > 0.01f) { if (_player->GetSpeed(move_type) > newspeed) // must be greater - just correct { sLog.outLog(LOG_DEFAULT, "ERROR: %sSpeedChange player %s is NOT correct (must be %f instead %f), force set to correct value", move_type_name[move_type], _player->GetName(), _player->GetSpeed(move_type), newspeed); _player->SetSpeed(move_type,_player->GetSpeedRate(move_type),true); } else // must be lesser - cheating { sLog.outLog(LOG_DEFAULT, "ERROR: Player %s from account id %u kicked for incorrect speed (must be %f instead %f)", _player->GetName(),_player->GetSession()->GetAccountId(),_player->GetSpeed(move_type), newspeed); _player->GetSession()->KickPlayer(); } } }
bool ChatHandler::HandlePlayerbotCommand(char* args) { if (sWorld.getConfig(CONFIG_BOOL_PLAYERBOT_DISABLE)) { PSendSysMessage("|cffff0000Playerbot system is currently disabled!"); SetSentErrorMessage(true); return false; } if (!m_session) { PSendSysMessage("|cffff0000You may only add bots from an active session"); SetSentErrorMessage(true); return false; } if (!*args) { PSendSysMessage("|cffff0000usage: add PLAYERNAME or remove PLAYERNAME"); SetSentErrorMessage(true); return false; } char *cmd = strtok ((char *) args, " "); char *charname = strtok (NULL, " "); if (!cmd || !charname) { PSendSysMessage("|cffff0000usage: add PLAYERNAME or remove PLAYERNAME"); SetSentErrorMessage(true); return false; } std::string cmdStr = cmd; std::string charnameStr = charname; if (!normalizePlayerName(charnameStr)) return false; ObjectGuid guid = sAccountMgr.GetPlayerGuidByName(charnameStr.c_str()); if (guid == ObjectGuid() || (guid == m_session->GetPlayer()->GetObjectGuid())) { SendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } uint32 accountId = sAccountMgr.GetPlayerAccountIdByGUID(guid); if (accountId != m_session->GetAccountId()) { if (!sWorld.getConfig(CONFIG_BOOL_PLAYERBOT_SHAREDBOTS)) { PSendSysMessage("|cffff0000You may only add bots from the same account."); SetSentErrorMessage(true); return false; } QueryResult *resultsocial = CharacterDatabase.PQuery("SELECT COUNT(*) FROM character_social s, characters c WHERE s.guid=c.guid AND c.online = 0 AND flags & 1 AND s.note " _LIKE_ " " _CONCAT3_ ("'%%'","'shared'","'%%'")" AND s.friend = '%u' AND s.guid = '%llu'", m_session->GetPlayer()->GetGUIDLow(), guid.GetRawValue()); if (resultsocial) { Field *fields = resultsocial->Fetch(); if (fields[0].GetUInt32() == 0 && (cmdStr == "add" || cmdStr == "login")) { PSendSysMessage("|cffff0000You may only add bots from the same account or a friend's character that contains 'shared' in the notes on their friend list while not online."); SetSentErrorMessage(true); delete resultsocial; return false; } } delete resultsocial; } // create the playerbot manager if it doesn't already exist PlayerbotMgr* mgr = m_session->GetPlayer()->GetPlayerbotMgr(); if (!mgr) { mgr = new PlayerbotMgr(m_session->GetPlayer()); m_session->GetPlayer()->SetPlayerbotMgr(mgr); } if (!(m_session->GetSecurity() > SEC_PLAYER)) { int maxnum = sWorld.getConfig(CONFIG_UINT32_PLAYERBOT_MAXBOTS); int charcount = m_session->GetPlayer()->GetPlayerbotMgr()->GetBotCount(); if (charcount >= maxnum && (cmdStr == "add" || cmdStr == "login")) { PSendSysMessage("|cffff0000You cannot summon anymore bots.(Current Max: |cffffffff%u)",maxnum); SetSentErrorMessage(true); return false; } } QueryResult *resultlvl = CharacterDatabase.PQuery("SELECT level, name, race FROM characters WHERE guid = '%u'", guid.GetCounter()); if (resultlvl) { Field *fields = resultlvl->Fetch(); int charlvl = fields[0].GetUInt32(); uint32 race = fields[2].GetUInt32(); Team master_team = m_session->GetPlayer()->GetTeam(); Team bot_team = HORDE; if (RACEMASK_ALLIANCE & (1 << (race-1))) bot_team = ALLIANCE; int maxlvl = sWorld.getConfig(CONFIG_UINT32_PLAYERBOT_RESTRICTLEVEL); int minlvl = sWorld.getConfig(CONFIG_UINT32_PLAYERBOT_MINBOTLEVEL); if (!(m_session->GetSecurity() > SEC_PLAYER)) { if (charlvl > maxlvl) { PSendSysMessage("|cffff0000You cannot summon |cffffffff[%s]|cffff0000, it's level is too high.(Current Max:lvl |cffffffff%u)", fields[1].GetString(), maxlvl); SetSentErrorMessage(true); delete resultlvl; return false; } if (charlvl < minlvl) { PSendSysMessage("|cffff0000You cannot summon |cffffffff[%s]|cffff0000, it's level is too low.(Current Min:lvl |cffffffff%u)", fields[1].GetString(), minlvl); SetSentErrorMessage(true); delete resultlvl; return false; } if (!sWorld.getConfig(CONFIG_BOOL_PLAYERBOT_ALLOW_SUMMON_OPPOSITE_FACTION) && bot_team != master_team) { PSendSysMessage("|cffff0000You cannot summon |cffffffff[%s]|cffff0000, it is from opposite faction.", fields[1].GetString()); SetSentErrorMessage(true); delete resultlvl; return false; } } delete resultlvl; } // end of gmconfig patch if (cmdStr == "add" || cmdStr == "login") { if (mgr->GetPlayerBot(guid) || sObjectMgr.GetPlayer(guid)) { PSendSysMessage("Bot already exists in world."); SetSentErrorMessage(true); return false; } CharacterDatabase.DirectPExecute("UPDATE characters SET online = 1 WHERE guid = '%u'", guid.GetCounter()); mgr->AddPlayerBot(guid); PSendSysMessage("Bot added successfully."); ++mgr->m_botCount; } else if (cmdStr == "remove" || cmdStr == "logout") { if (!mgr->GetPlayerBot(guid)) { PSendSysMessage("|cffff0000Bot can not be removed because bot does not exist in world."); SetSentErrorMessage(true); return false; } CharacterDatabase.DirectPExecute("UPDATE characters SET online = 0 WHERE guid = '%u'", guid.GetCounter()); mgr->LogoutPlayerBot(guid); PSendSysMessage("Bot removed successfully."); --mgr->m_botCount; } else if (cmdStr == "co" || cmdStr == "combatorder") { Unit *target = NULL; char *orderChar = strtok(NULL, " "); if (!orderChar) { PSendSysMessage("|cffff0000Syntax error:|cffffffff .bot co <botName> <order=reset|tank|assist|heal|protect> [targetPlayer]"); SetSentErrorMessage(true); return false; } std::string orderStr = orderChar; if (orderStr == "protect" || orderStr == "assist") { char *targetChar = strtok(NULL, " "); ObjectGuid targetGuid = m_session->GetPlayer()->GetSelectionGuid(); if (!targetChar && targetGuid.IsEmpty()) { PSendSysMessage("|cffff0000Combat orders protect and assist expect a target either by selection or by giving target player in command string!"); SetSentErrorMessage(true); return false; } if (targetChar) { std::string targetStr = targetChar; ObjectGuid targ_guid = sAccountMgr.GetPlayerGuidByName(targetStr.c_str()); targetGuid.Set(targ_guid.GetRawValue()); } target = ObjectAccessor::GetUnit(*m_session->GetPlayer(), targetGuid); if (!target) { PSendSysMessage("|cffff0000Invalid target for combat order protect or assist!"); SetSentErrorMessage(true); return false; } } if (mgr->GetPlayerBot(guid) == NULL) { PSendSysMessage("|cffff0000Bot can not receive combat order because bot does not exist in world."); SetSentErrorMessage(true); return false; } mgr->GetPlayerBot(guid)->GetPlayerbotAI()->SetCombatOrderByStr(orderStr, target); } return true; }
void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data ) { uint8 slotid; ObjectGuid lootguid; ObjectGuid target_playerguid; recv_data >> lootguid >> slotid >> target_playerguid; if (!_player->GetGroup() || _player->GetGroup()->GetLooterGuid() != _player->GetObjectGuid()) { _player->SendLootRelease(GetPlayer()->GetLootGUID()); return; } Player *target = ObjectAccessor::FindPlayer(target_playerguid); if (!target) return; DEBUG_LOG("WorldSession::HandleLootMasterGiveOpcode (CMSG_LOOT_MASTER_GIVE, 0x02A3) Target = %s [%s].", target_playerguid.GetString().c_str(), target->GetName()); if (_player->GetLootGUID() != lootguid.GetRawValue()) return; Loot *pLoot = NULL; if(lootguid.IsCreature()) { Creature *pCreature = GetPlayer()->GetMap()->GetCreature(lootguid); if(!pCreature) return; pLoot = &pCreature->loot; } else if(lootguid.IsGameobject()) { GameObject *pGO = GetPlayer()->GetMap()->GetGameObject(lootguid); if(!pGO) return; pLoot = &pGO->loot; } else return; if (slotid > pLoot->items.size()) { DEBUG_LOG("AutoLootItem: Player %s might be using a hack! (slot %d, size %lu)",GetPlayer()->GetName(), slotid, (unsigned long)pLoot->items.size()); return; } LootItem& item = pLoot->items[slotid]; ItemPosCountVec dest; uint8 msg = target->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, item.itemid, item.count ); if ( msg != EQUIP_ERR_OK ) { target->SendEquipError( msg, NULL, NULL, item.itemid ); // send duplicate of error massage to master looter _player->SendEquipError( msg, NULL, NULL, item.itemid ); return; } // now move item from loot to target inventory Item * newitem = target->StoreNewItem( dest, item.itemid, true, item.randomPropertyId ); target->SendNewItem(newitem, uint32(item.count), false, false, true ); target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item.itemid, item.count); target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, pLoot->loot_type, item.count); target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item.itemid, item.count); // mark as looted item.count=0; item.is_looted=true; pLoot->NotifyItemRemoved(slotid); --pLoot->unlootedCount; }
bool GuildTaskMgr::HandleConsoleCommand(ChatHandler* handler, char const* args) { if (!sPlayerbotAIConfig.guildTaskEnabled) { sLog->outMessage("gtask", LOG_LEVEL_ERROR, "Guild task system is currently disabled!"); return false; } if (!args || !*args) { sLog->outMessage("gtask", LOG_LEVEL_ERROR, "Usage: gtask stats/reset"); return false; } string cmd = args; if (cmd == "reset") { CharacterDatabase.PExecute("delete from ai_playerbot_guild_tasks"); sLog->outMessage("gtask", LOG_LEVEL_INFO, "Guild tasks were reset for all players"); return true; } if (cmd == "stats") { sLog->outMessage("gtask", LOG_LEVEL_INFO, "Usage: gtask stats <player name>"); return true; } if (cmd.find("stats ") != string::npos) { string charName = cmd.substr(cmd.find("stats ") + 6); ObjectGuid guid = sObjectMgr->GetPlayerGUIDByName(charName); if (!guid) { sLog->outMessage("gtask", LOG_LEVEL_ERROR, "Player %s not found", charName.c_str()); return false; } uint32 owner = (uint32)guid.GetRawValue(); QueryResult result = CharacterDatabase.PQuery( "select `value`, `time`, validIn, guildid, `type` from ai_playerbot_guild_tasks where owner = '%u' order by guildid, `type`", owner); if (result) { do { Field* fields = result->Fetch(); uint32 value = fields[0].GetUInt32(); uint32 lastChangeTime = fields[1].GetUInt32(); uint32 validIn = fields[2].GetUInt32(); if ((time(0) - lastChangeTime) >= validIn) value = 0; uint32 guildId = fields[3].GetUInt32(); string type = fields[4].GetString(); Guild *guild = sGuildMgr->GetGuildById(guildId); if (!guild) continue; sLog->outMessage("gtask", LOG_LEVEL_INFO, "Player '%s' Guild '%s' %s=%u (%u secs)", charName.c_str(), guild->GetName().c_str(), type.c_str(), value, validIn); } while (result->NextRow()); Field* fields = result->Fetch(); } return true; } if (cmd == "reward") { sLog->outMessage("gtask", LOG_LEVEL_INFO, "Usage: gtask reward <player name>"); return true; } if (cmd.find("reward ") != string::npos) { string charName = cmd.substr(cmd.find("reward ") + 7); ObjectGuid guid = sObjectMgr->GetPlayerGUIDByName(charName); if (!guid) { sLog->outMessage("gtask", LOG_LEVEL_ERROR, "Player %s not found", charName.c_str()); return false; } uint32 owner = (uint32)guid.GetRawValue(); QueryResult result = CharacterDatabase.PQuery( "select distinct guildid from ai_playerbot_guild_tasks where owner = '%u'", owner); if (result) { do { Field* fields = result->Fetch(); uint32 guildId = fields[0].GetUInt32(); Guild *guild = sGuildMgr->GetGuildById(guildId); if (!guild) continue; sGuildTaskMgr.Reward(owner, guildId); } while (result->NextRow()); Field* fields = result->Fetch(); return true; } } return false; }