void WorldSession::HandleOfferPetitionOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode CMSG_OFFER_PETITION"); ObjectGuid petitionGuid, playerGuid; uint32 type, junk; Player* player; ObjectGuid guid1; ObjectGuid guid2; recvData >> junk; // this is not petition type! guid1[3] = recvData.ReadBit(); guid1[2] = recvData.ReadBit(); guid1[5] = recvData.ReadBit(); guid2[4] = recvData.ReadBit(); guid1[7] = recvData.ReadBit(); guid1[6] = recvData.ReadBit(); guid2[3] = recvData.ReadBit(); guid2[7] = recvData.ReadBit(); guid2[0] = recvData.ReadBit(); guid1[4] = recvData.ReadBit(); guid2[1] = recvData.ReadBit(); guid2[6] = recvData.ReadBit(); guid2[2] = recvData.ReadBit(); guid1[1] = recvData.ReadBit(); guid2[5] = recvData.ReadBit(); guid1[0] = recvData.ReadBit(); recvData.FlushBits(); recvData.ReadByteSeq(guid2[2]); recvData.ReadByteSeq(guid2[3]); recvData.ReadByteSeq(guid2[1]); recvData.ReadByteSeq(guid2[5]); recvData.ReadByteSeq(guid2[4]); recvData.ReadByteSeq(guid1[7]); recvData.ReadByteSeq(guid2[0]); recvData.ReadByteSeq(guid1[2]); recvData.ReadByteSeq(guid1[0]); recvData.ReadByteSeq(guid1[6]); recvData.ReadByteSeq(guid2[7]); recvData.ReadByteSeq(guid1[1]); recvData.ReadByteSeq(guid1[4]); recvData.ReadByteSeq(guid1[3]); recvData.ReadByteSeq(guid1[5]); recvData.ReadByteSeq(guid2[6]); petitionGuid = guid1; playerGuid = guid2; player = ObjectAccessor::FindPlayer(playerGuid); if (!player) return; type = GUILD_CHARTER_TYPE; uint32 petitionGuidLow = GUID_LOPART(petitionGuid); sLog->outDebug(LOG_FILTER_NETWORKIO, "OFFER PETITION: type %u, GUID1 %u, to player id: %u", type, petitionGuidLow, GUID_LOPART(playerGuid)); if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != player->GetTeam()) { if (type == GUILD_CHARTER_TYPE) Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NOT_ALLIED); return; } if (type == GUILD_CHARTER_TYPE) { if (player->GetGuildIdInvited()) { SendPetitionSignResult(_player->GetGUID(), MAKE_NEW_GUID(petitionGuidLow, 0, HIGHGUID_ITEM), PETITION_SIGN_ALREADY_SIGNED_OTHER); return; } if (player->GetGuildId()) { SendPetitionSignResult(_player->GetGUID(), MAKE_NEW_GUID(petitionGuidLow, 0, HIGHGUID_ITEM), PETITION_SIGN_ALREADY_IN_GUILD); return; } } auto stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIGNATURE); stmt->setUInt32(0, petitionGuidLow); auto result = CharacterDatabase.Query(stmt); typedef std::vector<uint32> storage; storage loParts; // result == NULL also correct charter without signs if (result) { loParts.reserve(uint32(result->GetRowCount())); do { auto fields = result->Fetch(); auto loPart = fields[0].GetUInt32(); if (GUID_LOPART(playerGuid) == loPart) { player->GetSession()->SendAlreadySigned(playerGuid); return; } loParts.push_back(loPart); } while (result->NextRow()); } WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES); ByteBuffer signsBuffer; guid2 = _player->GetGUID(); //ObjectGuid guid1 = petitionGuid; data.WriteBit(guid2[4]); data.WriteBit(guid1[4]); data.WriteBit(guid2[5]); data.WriteBit(guid2[0]); data.WriteBit(guid2[6]); data.WriteBit(guid1[7]); data.WriteBit(guid2[7]); data.WriteBit(guid1[0]); data.WriteBit(guid2[2]); data.WriteBit(guid2[3]); data.WriteBits(loParts.size(), 21); for (auto lowGuid : loParts) { ObjectGuid signerGuid = MAKE_NEW_GUID(lowGuid, 0, HIGHGUID_PLAYER); uint8 bitsSendOrder[8] = { 6, 2, 4, 5, 3, 0, 7, 1 }; data.WriteBitInOrder(signerGuid, bitsSendOrder); signsBuffer.WriteByteSeq(signerGuid[4]); signsBuffer.WriteByteSeq(signerGuid[7]); signsBuffer.WriteByteSeq(signerGuid[5]); signsBuffer.WriteByteSeq(signerGuid[3]); signsBuffer.WriteByteSeq(signerGuid[2]); signsBuffer << uint32(0); signsBuffer.WriteByteSeq(signerGuid[6]); signsBuffer.WriteByteSeq(signerGuid[1]); signsBuffer.WriteByteSeq(signerGuid[0]); } data.WriteBit(guid1[5]); data.WriteBit(guid1[6]); data.WriteBit(guid1[1]); data.WriteBit(guid1[3]); data.WriteBit(guid2[1]); data.WriteBit(guid1[2]); data.FlushBits(); data << uint32(petitionGuidLow); if (signsBuffer.size()) data.append(signsBuffer); data.WriteByteSeq(guid1[2]); data.WriteByteSeq(guid2[1]); data.WriteByteSeq(guid2[6]); data.WriteByteSeq(guid1[3]); data.WriteByteSeq(guid2[7]); data.WriteByteSeq(guid1[0]); data.WriteByteSeq(guid2[0]); data.WriteByteSeq(guid2[2]); data.WriteByteSeq(guid1[4]); data.WriteByteSeq(guid1[7]); data.WriteByteSeq(guid1[6]); data.WriteByteSeq(guid2[4]); data.WriteByteSeq(guid2[3]); data.WriteByteSeq(guid2[5]); data.WriteByteSeq(guid1[5]); data.WriteByteSeq(guid1[1]); player->GetSession()->SendPacket(&data); }
void WorldSession::HandleVoidStorageQuery(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_VOID_STORAGE_QUERY"); Player* player = GetPlayer(); ObjectGuid npcGuid; npcGuid[4] = recvData.ReadBit(); npcGuid[0] = recvData.ReadBit(); npcGuid[5] = recvData.ReadBit(); npcGuid[7] = recvData.ReadBit(); npcGuid[6] = recvData.ReadBit(); npcGuid[3] = recvData.ReadBit(); npcGuid[1] = recvData.ReadBit(); npcGuid[2] = recvData.ReadBit(); recvData.ReadByteSeq(npcGuid[5]); recvData.ReadByteSeq(npcGuid[6]); recvData.ReadByteSeq(npcGuid[3]); recvData.ReadByteSeq(npcGuid[7]); recvData.ReadByteSeq(npcGuid[1]); recvData.ReadByteSeq(npcGuid[0]); recvData.ReadByteSeq(npcGuid[4]); recvData.ReadByteSeq(npcGuid[2]); Creature* unit = player->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_VAULTKEEPER); if (!unit) { TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageQuery - Unit (GUID: %u) not found or player can't interact with it.", GUID_LOPART(npcGuid)); return; } if (!player->IsVoidStorageUnlocked()) { TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageQuery - Player (GUID: %u, name: %s) queried void storage without unlocking it.", player->GetGUIDLow(), player->GetName().c_str()); return; } uint8 count = 0; for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i) if (player->GetVoidStorageItem(i)) ++count; WorldPacket data(SMSG_VOID_STORAGE_CONTENTS, 2 * count + (14 + 4 + 4 + 4 + 4) * count); data.WriteBits(count, 8); ByteBuffer itemData((14 + 4 + 4 + 4 + 4) * count); for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i) { VoidStorageItem* item = player->GetVoidStorageItem(i); if (!item) continue; ObjectGuid itemId = item->ItemId; ObjectGuid creatorGuid = item->CreatorGuid; data.WriteBit(creatorGuid[3]); data.WriteBit(itemId[5]); data.WriteBit(creatorGuid[6]); data.WriteBit(creatorGuid[1]); data.WriteBit(itemId[1]); data.WriteBit(itemId[3]); data.WriteBit(itemId[6]); data.WriteBit(creatorGuid[5]); data.WriteBit(creatorGuid[2]); data.WriteBit(itemId[2]); data.WriteBit(creatorGuid[4]); data.WriteBit(itemId[0]); data.WriteBit(itemId[4]); data.WriteBit(itemId[7]); data.WriteBit(creatorGuid[0]); data.WriteBit(creatorGuid[7]); itemData.WriteByteSeq(creatorGuid[3]); itemData << uint32(item->ItemSuffixFactor); itemData.WriteByteSeq(creatorGuid[4]); itemData << uint32(i); itemData.WriteByteSeq(itemId[0]); itemData.WriteByteSeq(itemId[6]); itemData.WriteByteSeq(creatorGuid[0]); itemData.WriteByteSeq(creatorGuid[1]); itemData << uint32(item->ItemRandomPropertyId); itemData.WriteByteSeq(itemId[4]); itemData.WriteByteSeq(itemId[5]); itemData.WriteByteSeq(itemId[2]); itemData.WriteByteSeq(creatorGuid[2]); itemData.WriteByteSeq(creatorGuid[6]); itemData.WriteByteSeq(itemId[1]); itemData.WriteByteSeq(itemId[3]); itemData.WriteByteSeq(creatorGuid[5]); itemData.WriteByteSeq(creatorGuid[7]); itemData << uint32(item->ItemEntry); itemData.WriteByteSeq(itemId[7]); } data.FlushBits(); data.append(itemData); SendPacket(&data); }
void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvData) { ObjectGuid guid; uint32 spellId; uint32 trainerId; recvData >> spellId >> trainerId; guid[1] = recvData.ReadBit(); guid[4] = recvData.ReadBit(); guid[0] = recvData.ReadBit(); guid[6] = recvData.ReadBit(); guid[3] = recvData.ReadBit(); guid[2] = recvData.ReadBit(); guid[5] = recvData.ReadBit(); guid[7] = recvData.ReadBit(); recvData.ReadByteSeq(guid[3]); recvData.ReadByteSeq(guid[1]); recvData.ReadByteSeq(guid[4]); recvData.ReadByteSeq(guid[7]); recvData.ReadByteSeq(guid[0]); recvData.ReadByteSeq(guid[5]); recvData.ReadByteSeq(guid[6]); recvData.ReadByteSeq(guid[2]); TC_LOG_DEBUG("network", "WORLD: Received CMSG_TRAINER_BUY_SPELL NpcGUID=%u, learn spell id is: %u", uint32(GUID_LOPART(guid)), spellId); Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_TRAINER); if (!unit) { TC_LOG_DEBUG("network", "WORLD: HandleTrainerBuySpellOpcode - Unit (GUID: %u) not found or you can not interact with him.", uint32(GUID_LOPART(guid))); return; } // remove fake death if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); // check present spell in trainer spell list TrainerSpellData const* trainer_spells = unit->GetTrainerSpells(); if (!trainer_spells) { SendTrainerBuyFailed(guid, spellId, 0); return; } // not found, cheat? TrainerSpell const* trainer_spell = trainer_spells->Find(spellId); if (!trainer_spell) { SendTrainerBuyFailed(guid, spellId, 0); return; } // can't be learn, cheat? Or double learn with lags... //if (_player->GetTrainerSpellState(trainer_spell) != TRAINER_SPELL_GREEN) // SendTrainerBuyFailed(guid, spellId, 0); // return; //} // apply reputation discount uint32 nSpellCost = uint32(floor(trainer_spell->spellCost * _player->GetReputationPriceDiscount(unit))); // check money requirement if (!_player->HasEnoughMoney(uint64(nSpellCost))) { SendTrainerBuyFailed(guid, spellId, 1); return; } _player->ModifyMoney(-int64(nSpellCost)); unit->SendPlaySpellVisualKit(179, 0, 0); // 53 SpellCastDirected _player->SendPlaySpellVisualKit(362, 1, 0); // 113 EmoteSalute // learn explicitly or cast explicitly if (trainer_spell->IsCastable()) _player->CastSpell(_player, trainer_spell->spell, true); else _player->learnSpell(spellId, false); }
void WorldSession::HandleGroupSetRolesOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_SET_ROLES"); uint32 newRole = 0; ObjectGuid targetGuid; recvData.read_skip<uint8>(); recvData >> newRole; targetGuid[2] = recvData.ReadBit(); targetGuid[0] = recvData.ReadBit(); targetGuid[7] = recvData.ReadBit(); targetGuid[4] = recvData.ReadBit(); targetGuid[1] = recvData.ReadBit(); targetGuid[3] = recvData.ReadBit(); targetGuid[6] = recvData.ReadBit(); targetGuid[5] = recvData.ReadBit(); recvData.ReadByteSeq(targetGuid[1]); recvData.ReadByteSeq(targetGuid[5]); recvData.ReadByteSeq(targetGuid[2]); recvData.ReadByteSeq(targetGuid[6]); recvData.ReadByteSeq(targetGuid[7]); recvData.ReadByteSeq(targetGuid[0]); recvData.ReadByteSeq(targetGuid[4]); recvData.ReadByteSeq(targetGuid[3]); Player* tPlayer = ObjectAccessor::FindPlayer(targetGuid); Group* group = GetPlayer()->GetGroup(); if (!tPlayer || !group) return; if (group != tPlayer->GetGroup()) return; ObjectGuid assignerGuid = GetPlayer()->GetGUID(); WorldPacket data(SMSG_ROLE_CHANGED_INFORM, 1 + 8 + 1 + 8 + 4 + 1 + 4); data.WriteBit(assignerGuid[1]); data.WriteBit(targetGuid[7]); data.WriteBit(targetGuid[6]); data.WriteBit(targetGuid[4]); data.WriteBit(targetGuid[1]); data.WriteBit(targetGuid[0]); data.WriteBit(assignerGuid[0]); data.WriteBit(assignerGuid[7]); data.WriteBit(targetGuid[3]); data.WriteBit(assignerGuid[6]); data.WriteBit(targetGuid[2]); data.WriteBit(assignerGuid[4]); data.WriteBit(assignerGuid[5]); data.WriteBit(assignerGuid[2]); data.WriteBit(targetGuid[5]); data.WriteBit(assignerGuid[3]); data.WriteByteSeq(assignerGuid[1]); data.WriteByteSeq(assignerGuid[6]); data.WriteByteSeq(assignerGuid[2]); data.WriteByteSeq(targetGuid[3]); data << uint32(group->GetMemberRole(targetGuid)); data.WriteByteSeq(assignerGuid[7]); data.WriteByteSeq(targetGuid[5]); data.WriteByteSeq(assignerGuid[3]); data.WriteByteSeq(targetGuid[4]); data.WriteByteSeq(targetGuid[7]); data.WriteByteSeq(assignerGuid[5]); data.WriteByteSeq(targetGuid[6]); data.WriteByteSeq(targetGuid[2]); data.WriteByteSeq(targetGuid[1]); data.WriteByteSeq(targetGuid[0]); data.WriteByteSeq(assignerGuid[4]); data << uint8(0); // unknown data.WriteByteSeq(assignerGuid[0]); data << uint32(newRole); if (group) { group->setGroupMemberRole(targetGuid, newRole); group->SendUpdate(); group->BroadcastPacket(&data, false); } else SendPacket(&data); }
void WorldSession::HandleVoidStorageTransfer(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_VOID_STORAGE_TRANSFER"); Player* player = GetPlayer(); // Read everything ObjectGuid npcGuid; npcGuid[1] = recvData.ReadBit(); uint32 countDeposit = recvData.ReadBits(26); if (countDeposit > 9) { TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) wants to deposit more than 9 items (%u).", player->GetGUIDLow(), player->GetName().c_str(), countDeposit); return; } std::vector<ObjectGuid> itemGuids(countDeposit); for (uint32 i = 0; i < countDeposit; ++i) { itemGuids[i][4] = recvData.ReadBit(); itemGuids[i][6] = recvData.ReadBit(); itemGuids[i][7] = recvData.ReadBit(); itemGuids[i][0] = recvData.ReadBit(); itemGuids[i][1] = recvData.ReadBit(); itemGuids[i][5] = recvData.ReadBit(); itemGuids[i][3] = recvData.ReadBit(); itemGuids[i][2] = recvData.ReadBit(); } npcGuid[2] = recvData.ReadBit(); npcGuid[0] = recvData.ReadBit(); npcGuid[3] = recvData.ReadBit(); npcGuid[5] = recvData.ReadBit(); npcGuid[6] = recvData.ReadBit(); npcGuid[4] = recvData.ReadBit(); uint32 countWithdraw = recvData.ReadBits(26); if (countWithdraw > 9) { TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) wants to withdraw more than 9 items (%u).", player->GetGUIDLow(), player->GetName().c_str(), countWithdraw); return; } std::vector<ObjectGuid> itemIds(countWithdraw); for (uint32 i = 0; i < countWithdraw; ++i) { itemIds[i][4] = recvData.ReadBit(); itemIds[i][7] = recvData.ReadBit(); itemIds[i][1] = recvData.ReadBit(); itemIds[i][0] = recvData.ReadBit(); itemIds[i][2] = recvData.ReadBit(); itemIds[i][3] = recvData.ReadBit(); itemIds[i][5] = recvData.ReadBit(); itemIds[i][6] = recvData.ReadBit(); } npcGuid[7] = recvData.ReadBit(); for (uint32 i = 0; i < countDeposit; ++i) { recvData.ReadByteSeq(itemGuids[i][6]); recvData.ReadByteSeq(itemGuids[i][1]); recvData.ReadByteSeq(itemGuids[i][0]); recvData.ReadByteSeq(itemGuids[i][2]); recvData.ReadByteSeq(itemGuids[i][4]); recvData.ReadByteSeq(itemGuids[i][5]); recvData.ReadByteSeq(itemGuids[i][3]); recvData.ReadByteSeq(itemGuids[i][7]); } recvData.ReadByteSeq(npcGuid[5]); recvData.ReadByteSeq(npcGuid[6]); for (uint32 i = 0; i < countWithdraw; ++i) { recvData.ReadByteSeq(itemIds[i][3]); recvData.ReadByteSeq(itemIds[i][0]); recvData.ReadByteSeq(itemIds[i][1]); recvData.ReadByteSeq(itemIds[i][6]); recvData.ReadByteSeq(itemIds[i][2]); recvData.ReadByteSeq(itemIds[i][7]); recvData.ReadByteSeq(itemIds[i][5]); recvData.ReadByteSeq(itemIds[i][4]); } recvData.ReadByteSeq(npcGuid[1]); recvData.ReadByteSeq(npcGuid[4]); recvData.ReadByteSeq(npcGuid[7]); recvData.ReadByteSeq(npcGuid[3]); recvData.ReadByteSeq(npcGuid[2]); recvData.ReadByteSeq(npcGuid[0]); Creature* unit = player->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_VAULTKEEPER); if (!unit) { TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Unit (GUID: %u) not found or player can't interact with it.", GUID_LOPART(npcGuid)); return; } if (!player->IsVoidStorageUnlocked()) { TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) queried void storage without unlocking it.", player->GetGUIDLow(), player->GetName().c_str()); return; } if (itemGuids.size() > player->GetNumOfVoidStorageFreeSlots()) { SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_FULL); return; } uint32 freeBagSlots = 0; if (itemIds.size() != 0) { // make this a Player function for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) if (Bag* bag = player->GetBagByPos(i)) freeBagSlots += bag->GetFreeSlots(); for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) if (!player->GetItemByPos(INVENTORY_SLOT_BAG_0, i)) ++freeBagSlots; } if (itemIds.size() > freeBagSlots) { SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INVENTORY_FULL); return; } if (!player->HasEnoughMoney(uint64(itemGuids.size() * VOID_STORAGE_STORE_ITEM))) { SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_NOT_ENOUGH_MONEY); return; } std::pair<VoidStorageItem, uint8> depositItems[VOID_STORAGE_MAX_DEPOSIT]; uint8 depositCount = 0; for (std::vector<ObjectGuid>::iterator itr = itemGuids.begin(); itr != itemGuids.end(); ++itr) { Item* item = player->GetItemByGuid(*itr); if (!item) { TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) wants to deposit an invalid item (item guid: " UI64FMTD ").", player->GetGUIDLow(), player->GetName().c_str(), uint64(*itr)); continue; } VoidStorageItem itemVS(sObjectMgr->GenerateVoidStorageItemId(), item->GetEntry(), item->GetUInt64Value(ITEM_FIELD_CREATOR), item->GetItemRandomPropertyId(), item->GetItemSuffixFactor()); uint8 slot = player->AddVoidStorageItem(itemVS); depositItems[depositCount++] = std::make_pair(itemVS, slot); player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); } int64 cost = depositCount * VOID_STORAGE_STORE_ITEM; player->ModifyMoney(-cost); VoidStorageItem withdrawItems[VOID_STORAGE_MAX_WITHDRAW]; uint8 withdrawCount = 0; for (std::vector<ObjectGuid>::iterator itr = itemIds.begin(); itr != itemIds.end(); ++itr) { uint8 slot; VoidStorageItem* itemVS = player->GetVoidStorageItem(*itr, slot); if (!itemVS) { TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) tried to withdraw an invalid item (id: " UI64FMTD ")", player->GetGUIDLow(), player->GetName().c_str(), uint64(*itr)); continue; } ItemPosCountVec dest; InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemVS->ItemEntry, 1); if (msg != EQUIP_ERR_OK) { SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INVENTORY_FULL); TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) couldn't withdraw item id " UI64FMTD " because inventory was full.", player->GetGUIDLow(), player->GetName().c_str(), uint64(*itr)); return; } Item* item = player->StoreNewItem(dest, itemVS->ItemEntry, true, itemVS->ItemRandomPropertyId); item->SetUInt64Value(ITEM_FIELD_CREATOR, uint64(itemVS->CreatorGuid)); item->SetBinding(true); player->SendNewItem(item, 1, false, false, false); withdrawItems[withdrawCount++] = *itemVS; player->DeleteVoidStorageItem(slot); } WorldPacket data(SMSG_VOID_STORAGE_TRANSFER_CHANGES, ((5 + 5 + (7 + 7) * depositCount + 7 * withdrawCount) / 8) + 7 * withdrawCount + (7 + 7 + 4 * 4) * depositCount); data.WriteBits(depositCount, 5); data.WriteBits(withdrawCount, 5); for (uint8 i = 0; i < depositCount; ++i) { ObjectGuid itemId = depositItems[i].first.ItemId; ObjectGuid creatorGuid = depositItems[i].first.CreatorGuid; data.WriteBit(creatorGuid[7]); data.WriteBit(itemId[7]); data.WriteBit(itemId[4]); data.WriteBit(creatorGuid[6]); data.WriteBit(creatorGuid[5]); data.WriteBit(itemId[3]); data.WriteBit(itemId[5]); data.WriteBit(creatorGuid[4]); data.WriteBit(creatorGuid[2]); data.WriteBit(creatorGuid[0]); data.WriteBit(creatorGuid[3]); data.WriteBit(creatorGuid[1]); data.WriteBit(itemId[2]); data.WriteBit(itemId[0]); data.WriteBit(itemId[1]); data.WriteBit(itemId[6]); } for (uint8 i = 0; i < withdrawCount; ++i) { ObjectGuid itemId = withdrawItems[i].ItemId; data.WriteBit(itemId[1]); data.WriteBit(itemId[7]); data.WriteBit(itemId[3]); data.WriteBit(itemId[5]); data.WriteBit(itemId[6]); data.WriteBit(itemId[2]); data.WriteBit(itemId[4]); data.WriteBit(itemId[0]); } data.FlushBits(); for (uint8 i = 0; i < withdrawCount; ++i) { ObjectGuid itemId = withdrawItems[i].ItemId; data.WriteByteSeq(itemId[3]); data.WriteByteSeq(itemId[1]); data.WriteByteSeq(itemId[0]); data.WriteByteSeq(itemId[2]); data.WriteByteSeq(itemId[7]); data.WriteByteSeq(itemId[5]); data.WriteByteSeq(itemId[6]); data.WriteByteSeq(itemId[4]); } for (uint8 i = 0; i < depositCount; ++i) { ObjectGuid itemId = depositItems[i].first.ItemId; ObjectGuid creatorGuid = depositItems[i].first.CreatorGuid; data << uint32(depositItems[i].first.ItemSuffixFactor); data.WriteByteSeq(itemId[6]); data.WriteByteSeq(itemId[4]); data.WriteByteSeq(creatorGuid[4]); data.WriteByteSeq(itemId[2]); data.WriteByteSeq(creatorGuid[1]); data.WriteByteSeq(creatorGuid[3]); data.WriteByteSeq(itemId[3]); data.WriteByteSeq(creatorGuid[0]); data.WriteByteSeq(itemId[0]); data.WriteByteSeq(creatorGuid[6]); data.WriteByteSeq(itemId[5]); data.WriteByteSeq(creatorGuid[5]); data.WriteByteSeq(creatorGuid[7]); data << uint32(depositItems[i].first.ItemEntry); data.WriteByteSeq(itemId[1]); data << uint32(depositItems[i].second); // slot data.WriteByteSeq(creatorGuid[2]); data.WriteByteSeq(itemId[7]); data << uint32(depositItems[i].first.ItemRandomPropertyId); } SendPacket(&data); SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_NO_ERROR); }
void WorldSession::HandleGrantLevel(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: CMSG_GRANT_LEVEL"); ObjectGuid guid; guid[2] = recvData.ReadBit(); // 18 guid[1] = recvData.ReadBit(); // 17 guid[5] = recvData.ReadBit(); // 21 guid[3] = recvData.ReadBit(); // 19 guid[7] = recvData.ReadBit(); // 23 guid[4] = recvData.ReadBit(); // 20 guid[0] = recvData.ReadBit(); // 16 guid[6] = recvData.ReadBit(); // 22 recvData.ReadByteSeq(guid[1]); // 17 recvData.ReadByteSeq(guid[4]); // 20 recvData.ReadByteSeq(guid[2]); // 18 recvData.ReadByteSeq(guid[7]); // 23 recvData.ReadByteSeq(guid[5]); // 21 recvData.ReadByteSeq(guid[3]); // 19 recvData.ReadByteSeq(guid[6]); // 22 recvData.ReadByteSeq(guid[0]); // 16 Player* target = ObjectAccessor::GetObjectInWorld(guid, _player); // check cheating uint8 levels = _player->GetGrantableLevels(); uint8 error = 0; if (!target) error = ERR_REFER_A_FRIEND_NO_TARGET; else if (levels == 0) error = ERR_REFER_A_FRIEND_INSUFFICIENT_GRANTABLE_LEVELS; else if (GetRecruiterId() != target->GetSession()->GetAccountId()) error = ERR_REFER_A_FRIEND_NOT_REFERRED_BY; else if (target->GetTeamId() != _player->GetTeamId()) error = ERR_REFER_A_FRIEND_DIFFERENT_FACTION; else if (target->getLevel() >= _player->getLevel()) error = ERR_REFER_A_FRIEND_TARGET_TOO_HIGH; else if (target->getLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL)) error = ERR_REFER_A_FRIEND_GRANT_LEVEL_MAX_I; else if (target->GetGroup() != _player->GetGroup()) error = ERR_REFER_A_FRIEND_NOT_IN_GROUP; if (error) { WorldPacket data(SMSG_REFER_A_FRIEND_FAILURE, 24); data << uint32(error); if (error == ERR_REFER_A_FRIEND_NOT_IN_GROUP) data << target->GetName(); SendPacket(&data); return; } ObjectGuid oGUID = _player->GetGUID(); WorldPacket data2(SMSG_PROPOSE_LEVEL_GRANT, 8); data2.WriteBit(oGUID[6]); // 22 data2.WriteBit(oGUID[7]); // 23 data2.WriteBit(oGUID[2]); // 18 data2.WriteBit(oGUID[5]); // 21 data2.WriteBit(oGUID[3]); // 19 data2.WriteBit(oGUID[0]); // 16 data2.WriteBit(oGUID[1]); // 17 data2.WriteBit(oGUID[4]); // 20 data2.WriteByteSeq(oGUID[2]); // 18 data2.WriteByteSeq(oGUID[5]); // 21 data2.WriteByteSeq(oGUID[6]); // 22 data2.WriteByteSeq(oGUID[7]); // 23 data2.WriteByteSeq(oGUID[1]); // 17 data2.WriteByteSeq(oGUID[4]); // 20 data2.WriteByteSeq(oGUID[3]); // 19 data2.WriteByteSeq(oGUID[0]); // 16 target->GetSession()->SendPacket(&data2); }
void WorldSession::HandleRaidConfirmReadyCheck(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_RAID_CONFIRM_READY_CHECK"); ObjectGuid guid; // currently unused Group* group = GetPlayer()->GetGroup(); if (!group) return; recvData.read_skip<uint8>(); guid[2] = recvData.ReadBit(); guid[1] = recvData.ReadBit(); guid[0] = recvData.ReadBit(); guid[3] = recvData.ReadBit(); guid[6] = recvData.ReadBit(); bool status = recvData.ReadBit(); guid[7] = recvData.ReadBit(); guid[4] = recvData.ReadBit(); guid[5] = recvData.ReadBit(); recvData.ReadByteSeq(guid[1]); recvData.ReadByteSeq(guid[0]); recvData.ReadByteSeq(guid[3]); recvData.ReadByteSeq(guid[2]); recvData.ReadByteSeq(guid[4]); recvData.ReadByteSeq(guid[5]); recvData.ReadByteSeq(guid[7]); recvData.ReadByteSeq(guid[6]); ObjectGuid playerGuid = GetPlayer()->GetGUID(); ObjectGuid groupGuid = group->GetGUID(); group->SetReadyCheckCount(group->GetReadyCheckCount() + 1); WorldPacket data(SMSG_RAID_READY_CHECK_CONFIRM, 1 + 1 + 8 + 1 + 8); data.WriteBit(groupGuid[4]); data.WriteBit(playerGuid[5]); data.WriteBit(playerGuid[3]); data.WriteBit(status); data.WriteBit(groupGuid[2]); data.WriteBit(playerGuid[6]); data.WriteBit(groupGuid[3]); data.WriteBit(playerGuid[0]); data.WriteBit(playerGuid[1]); data.WriteBit(groupGuid[1]); data.WriteBit(groupGuid[5]); data.WriteBit(playerGuid[7]); data.WriteBit(playerGuid[4]); data.WriteBit(groupGuid[6]); data.WriteBit(playerGuid[2]); data.WriteBit(groupGuid[0]); data.WriteBit(groupGuid[7]); data.FlushBits(); data.WriteByteSeq(playerGuid[4]); data.WriteByteSeq(playerGuid[2]); data.WriteByteSeq(playerGuid[1]); data.WriteByteSeq(groupGuid[4]); data.WriteByteSeq(groupGuid[2]); data.WriteByteSeq(playerGuid[0]); data.WriteByteSeq(groupGuid[5]); data.WriteByteSeq(groupGuid[3]); data.WriteByteSeq(playerGuid[7]); data.WriteByteSeq(groupGuid[6]); data.WriteByteSeq(groupGuid[1]); data.WriteByteSeq(playerGuid[6]); data.WriteByteSeq(playerGuid[3]); data.WriteByteSeq(playerGuid[5]); data.WriteByteSeq(groupGuid[0]); data.WriteByteSeq(groupGuid[7]); group->BroadcastPacket(&data, true); // Send SMSG_RAID_READY_CHECK_COMPLETED if (group->GetReadyCheckCount() >= group->GetMembersCount()) { ObjectGuid grpGUID = group->GetGUID(); data.Initialize(SMSG_RAID_READY_CHECK_COMPLETED, 1 + 8 + 1); uint8 bitOrder[8] = { 4, 2, 5, 7, 1, 0, 3, 6 }; data.WriteBitInOrder(grpGUID, bitOrder); data.WriteByteSeq(grpGUID[6]); data.WriteByteSeq(grpGUID[0]); data.WriteByteSeq(grpGUID[3]); data.WriteByteSeq(grpGUID[1]); data.WriteByteSeq(grpGUID[5]); data << uint8(1); // or 0 data.WriteByteSeq(grpGUID[7]); data.WriteByteSeq(grpGUID[2]); data.WriteByteSeq(grpGUID[4]); group->BroadcastPacket(&data, true); } }
//Todo Database Support void WorldSession::HandleSubmitComplainOpcode(WorldPacket & recvData) { float posX, posY, posZ, posO; uint32 mapID; ObjectGuid guid; guid[5] = recvData.ReadBit(); guid[0] = recvData.ReadBit(); guid[1] = recvData.ReadBit(); uint32 length = recvData.ReadBits(12); guid[3] = recvData.ReadBit(); guid[2] = recvData.ReadBit(); guid[4] = recvData.ReadBit(); guid[7] = recvData.ReadBit(); //guid:4 options:0 length :0;posY:648.581055 ,posX:-8851.486328 ,posZ:96.454063 ,MAP:0 ,poso:2.151366 , unk:0 text: //SPAM //guid:4 options:10 length :0;posY:648.581055 ,posX:-8851.486328 ,posZ:96.454063 ,MAP:0 ,poso:2.151366 , unk:0 text: //Ausdrucksweise uint32 options = recvData.ReadBits(4); // ## guid[6] = recvData.ReadBit(); recvData.ReadByteSeq(guid[3]); recvData.ReadByteSeq(guid[5]); recvData.ReadByteSeq(guid[1]); recvData.ReadByteSeq(guid[2]); recvData.ReadByteSeq(guid[6]); recvData.ReadByteSeq(guid[0]); std::string text = recvData.ReadString(length); recvData.ReadByteSeq(guid[7]); recvData.ReadByteSeq(guid[4]); recvData >> posY; recvData >> posZ; recvData >> posX; recvData >> mapID; recvData >> posO; recvData.ReadBit(); uint32 count = recvData.ReadBits(22); uint32* strLength = new uint32[count]; // sLog->outInfo(LOG_FILTER_SERVER_LOADING,"CMSG_SUBMIT_COMPLAIN:: count:%u guid:%u option:%u length :%u;posY:%f ,posX:%f ,posZ:%f ,MAP:%u ,poso:%f text:%s",count,guid,options,length,posY,posX,posZ,mapID,posO,text.c_str()); switch(options) { case COMPLAIN_CHEATER: case COMPLAIN_PLAYER_NAME: case COMPLAIN_GUILD_NAME: case COMPLAIN_ARENA_NAME: break; case COMPLAIN_SPAM: case COMPLAIN_BAD_LANG: for (uint32 i = 0; i < count; ++i) strLength[i] = recvData.ReadBits(13); for (uint32 i = 0; i < count; ++i) { sLog->outInfo(LOG_FILTER_SERVER_LOADING,"time : %u",recvData.ReadPackedTime()); sLog->outInfo(LOG_FILTER_SERVER_LOADING,"Text : %s",recvData.ReadString(strLength[i]).c_str()); } break; default: sLog->outInfo(LOG_FILTER_SERVER_LOADING,"CMSG_SUBMIT_COMPLAIN::UNKNOW option:%u",options); } }
void WorldSession::HandleRaidReadyCheckConfirmOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_RAID_READY_CHECK_CONFIRM"); ObjectGuid guid; // currently unused Group* group = GetPlayer()->GetGroup(); if (!group) return; if (!group->ReadyCheckInProgress()) return; recvData.read_skip<uint8>(); guid[2] = recvData.ReadBit(); guid[1] = recvData.ReadBit(); guid[0] = recvData.ReadBit(); guid[3] = recvData.ReadBit(); guid[6] = recvData.ReadBit(); bool status = recvData.ReadBit(); guid[7] = recvData.ReadBit(); guid[4] = recvData.ReadBit(); guid[5] = recvData.ReadBit(); recvData.ReadByteSeq(guid[1]); recvData.ReadByteSeq(guid[0]); recvData.ReadByteSeq(guid[3]); recvData.ReadByteSeq(guid[2]); recvData.ReadByteSeq(guid[4]); recvData.ReadByteSeq(guid[5]); recvData.ReadByteSeq(guid[7]); recvData.ReadByteSeq(guid[6]); ObjectGuid groupGuid = group->GetGUID(); ObjectGuid playerGuid = GetPlayer()->GetGUID(); WorldPacket data(SMSG_RAID_READY_CHECK_CONFIRM, 1 + 1 + 8 + 1 + 8); data.WriteBit(groupGuid[4]); data.WriteBit(playerGuid[5]); data.WriteBit(playerGuid[3]); data.WriteBit(status); data.WriteBit(groupGuid[2]); data.WriteBit(playerGuid[6]); data.WriteBit(groupGuid[3]); data.WriteBit(playerGuid[0]); data.WriteBit(playerGuid[1]); data.WriteBit(groupGuid[1]); data.WriteBit(groupGuid[5]); data.WriteBit(playerGuid[7]); data.WriteBit(playerGuid[4]); data.WriteBit(groupGuid[6]); data.WriteBit(playerGuid[2]); data.WriteBit(groupGuid[0]); data.WriteBit(groupGuid[7]); data.FlushBits(); data.WriteByteSeq(playerGuid[4]); data.WriteByteSeq(playerGuid[2]); data.WriteByteSeq(playerGuid[1]); data.WriteByteSeq(groupGuid[4]); data.WriteByteSeq(groupGuid[2]); data.WriteByteSeq(playerGuid[0]); data.WriteByteSeq(groupGuid[5]); data.WriteByteSeq(groupGuid[3]); data.WriteByteSeq(playerGuid[7]); data.WriteByteSeq(groupGuid[6]); data.WriteByteSeq(groupGuid[1]); data.WriteByteSeq(playerGuid[6]); data.WriteByteSeq(playerGuid[3]); data.WriteByteSeq(playerGuid[5]); data.WriteByteSeq(groupGuid[0]); data.WriteByteSeq(groupGuid[7]); group->BroadcastPacket(&data, false); group->ReadyCheckMemberHasResponded(playerGuid); if (group->ReadyCheckAllResponded()) { Player* leader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()); if (leader) leader->SetReadyCheckTimer(0); group->ReadyCheck(false); group->ReadyCheckResetResponded(); group->SendReadyCheckCompleted(); } }
void WorldSession::HandleSendMail(WorldPacket& recv_data) { CHECK_INWORLD_RETURN MailMessage msg; ObjectGuid mailbox; uint32 unk1, unk2; uint64 money, COD; uint32 bodyLength, subjectLength, receiverLength; std::string receiver, subject, body; std::vector< Item* > items; std::vector< Item* >::iterator itr; Item* pItem; recv_data >> unk1; recv_data >> unk2; recv_data >> COD; recv_data >> money; bodyLength = recv_data.readBits(12); subjectLength = recv_data.readBits(9); uint8 items_count = recv_data.readBits(5); // attached items count if (items_count > MAIL_MAX_ITEM_SLOT) { SendMailError(MAIL_ERR_TOO_MANY_ATTACHMENTS); return; } mailbox[0] = recv_data.readBit(); ObjectGuid itemGUIDs[MAIL_MAX_ITEM_SLOT]; for (uint8 i = 0; i < items_count; ++i) { itemGUIDs[i][2] = recv_data.readBit(); itemGUIDs[i][6] = recv_data.readBit(); itemGUIDs[i][3] = recv_data.readBit(); itemGUIDs[i][7] = recv_data.readBit(); itemGUIDs[i][1] = recv_data.readBit(); itemGUIDs[i][0] = recv_data.readBit(); itemGUIDs[i][4] = recv_data.readBit(); itemGUIDs[i][5] = recv_data.readBit(); } mailbox[3] = recv_data.readBit(); mailbox[4] = recv_data.readBit(); receiverLength = recv_data.readBits(7); mailbox[2] = recv_data.readBit(); mailbox[6] = recv_data.readBit(); mailbox[1] = recv_data.readBit(); mailbox[7] = recv_data.readBit(); mailbox[5] = recv_data.readBit(); recv_data.ReadByteSeq(mailbox[4]); for (uint8 i = 0; i < items_count; ++i) { recv_data.ReadByteSeq(itemGUIDs[i][6]); recv_data.ReadByteSeq(itemGUIDs[i][1]); recv_data.ReadByteSeq(itemGUIDs[i][7]); recv_data.ReadByteSeq(itemGUIDs[i][2]); recv_data.read_skip<uint8>(); // item slot in mail, not used recv_data.ReadByteSeq(itemGUIDs[i][3]); recv_data.ReadByteSeq(itemGUIDs[i][0]); recv_data.ReadByteSeq(itemGUIDs[i][4]); recv_data.ReadByteSeq(itemGUIDs[i][5]); } recv_data.ReadByteSeq(mailbox[7]); recv_data.ReadByteSeq(mailbox[3]); recv_data.ReadByteSeq(mailbox[6]); recv_data.ReadByteSeq(mailbox[5]); subject = recv_data.ReadString(subjectLength); receiver = recv_data.ReadString(receiverLength); recv_data.ReadByteSeq(mailbox[2]); recv_data.ReadByteSeq(mailbox[0]); body = recv_data.ReadString(bodyLength); recv_data.ReadByteSeq(mailbox[1]); // packet read complete, now do check // Search for the recipient PlayerInfo* player = ObjectMgr::getSingleton().GetPlayerInfoByName(receiver.c_str()); if (player == NULL) { SendMailError(MAIL_ERR_RECIPIENT_NOT_FOUND); return; } for (uint8 i = 0; i < items_count; ++i) { pItem = _player->GetItemInterface()->GetItemByGUID(itemGUIDs[i]); if (pItem == NULL || pItem->IsSoulbound() || pItem->IsConjured()) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } if (pItem->IsAccountbound() && GetAccountId() != player->acct) // don't mail account-bound items to another account { WorldPacket data(SMSG_SEND_MAIL_RESULT, 16); data << uint32(0); data << uint32(0); data << uint32(MAIL_ERR_BAG_FULL); data << uint32(INV_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS); SendPacket(&data); return; } items.push_back(pItem); } if (receiver.empty()) return; bool interfaction = false; if (sMailSystem.MailOption(MAIL_FLAG_CAN_SEND_TO_OPPOSITE_FACTION) || (HasGMPermissions() && sMailSystem.MailOption(MAIL_FLAG_CAN_SEND_TO_OPPOSITE_FACTION_GM))) { interfaction = true; } // Check we're sending to the same faction (disable this for testing) if (player->team != _player->GetTeam() && !interfaction) { SendMailError(MAIL_ERR_NOT_YOUR_ALLIANCE); return; } // Check if we're sending mail to ourselves if (strcmp(player->name, _player->GetName()) == 0 && !GetPermissionCount()) { SendMailError(MAIL_ERR_CANNOT_SEND_TO_SELF); return; } if (msg.stationery == MAIL_STATIONERY_GM && !HasGMPermissions()) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } // Instant delivery time by default. msg.delivery_time = (uint32)UNIXTIME; // Set up the cost uint32 cost = items_count ? 30 * items_count : 30; // price hardcoded in client uint64 reqmoney = cost + money; if (!sMailSystem.MailOption(MAIL_FLAG_DISABLE_POSTAGE_COSTS) && !(GetPermissionCount() && sMailSystem.MailOption(MAIL_FLAG_NO_COST_FOR_GM))) { cost += 30; } // check that we have enough in our backpack if (!_player->HasGold(cost)) { SendMailError(MAIL_ERR_NOT_ENOUGH_MONEY); return; } // Check for the item, and required item. if (!items.empty()) { for (itr = items.begin(); itr != items.end(); ++itr) { pItem = *itr; if (_player->GetItemInterface()->SafeRemoveAndRetreiveItemByGuid(pItem->GetGUID(), false) != pItem) continue; // should never be hit. pItem->RemoveFromWorld(); pItem->SetOwner(NULL); pItem->SaveToDB(INVENTORY_SLOT_NOT_SET, 0, true, NULL); msg.items.push_back(pItem->GetLowGUID()); if (GetPermissionCount() > 0) { /* log the message */ sGMLog.writefromsession(this, "sent mail with item entry %u to %s, with gold %u.", pItem->GetEntry(), player->name, money); } pItem->DeleteMe(); } } if (money != 0 || COD != 0 || (!items.size() && player->acct != _player->GetSession()->GetAccountId())) { if (!sMailSystem.MailOption(MAIL_FLAG_DISABLE_HOUR_DELAY_FOR_ITEMS)) msg.delivery_time += 3600; // 1hr } // take the money _player->ModGold(-cost); // Fill in the rest of the info msg.player_guid = player->guid; msg.sender_guid = _player->GetGUID(); msg.money = money; msg.cod = COD; msg.subject = subject; msg.body = body; // 30 day expiry time for unread mail if (!sMailSystem.MailOption(MAIL_FLAG_NO_EXPIRY)) msg.expire_time = (uint32)UNIXTIME + (TIME_DAY * MAIL_DEFAULT_EXPIRATION_TIME); else msg.expire_time = 0; msg.deleted_flag = false; msg.message_type = 0; msg.checked_flag = msg.body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY; // Great, all our info is filled in. Now we can add it to the other players mailbox. sMailSystem.DeliverMessage(player->guid, &msg); // Save/Update character's gold if they've received gold that is. This prevents a rollback. CharacterDatabase.Execute("UPDATE characters SET gold = %u WHERE guid = %u", _player->GetGold(), _player->m_playerInfo->guid); // Success packet :) SendMailError(MAIL_OK); }
void WorldSession::HandleMoveTeleportAck(WorldPacket& recvPacket) { TC_LOG_DEBUG("network", "MSG_MOVE_TELEPORT_ACK"); ObjectGuid guid; uint32 flags, time; recvPacket >> flags >> time; guid[5] = recvPacket.ReadBit(); guid[0] = recvPacket.ReadBit(); guid[1] = recvPacket.ReadBit(); guid[6] = recvPacket.ReadBit(); guid[3] = recvPacket.ReadBit(); guid[7] = recvPacket.ReadBit(); guid[2] = recvPacket.ReadBit(); guid[4] = recvPacket.ReadBit(); recvPacket.ReadByteSeq(guid[4]); recvPacket.ReadByteSeq(guid[2]); recvPacket.ReadByteSeq(guid[7]); recvPacket.ReadByteSeq(guid[6]); recvPacket.ReadByteSeq(guid[5]); recvPacket.ReadByteSeq(guid[1]); recvPacket.ReadByteSeq(guid[3]); recvPacket.ReadByteSeq(guid[0]); TC_LOG_DEBUG("network", "Guid " UI64FMTD, uint64(guid)); TC_LOG_DEBUG("network", "Flags %u, time %u", flags, time/IN_MILLISECONDS); Player* plMover = _player->m_mover->ToPlayer(); if (!plMover || !plMover->IsBeingTeleportedNear()) return; if (guid != plMover->GetGUID()) return; plMover->SetSemaphoreTeleportNear(false); uint32 old_zone = plMover->GetZoneId(); WorldLocation const& dest = plMover->GetTeleportDest(); plMover->UpdatePosition(dest, true); uint32 newzone, newarea; plMover->GetZoneAndAreaId(newzone, newarea); plMover->UpdateZone(newzone, newarea); // new zone if (old_zone != newzone) { // honorless target if (plMover->pvpInfo.IsHostile) plMover->CastSpell(plMover, 2479, true); // in friendly area else if (plMover->IsPvP() && !plMover->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP)) plMover->UpdatePvP(false, false); } // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); //lets process all delayed operations on successful teleport GetPlayer()->ProcessDelayedOperations(); }
void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_INVITE"); ObjectGuid crossRealmGuid; // unused recvData.read_skip<uint32>(); // Non-zero in cross realm invites recvData.read_skip<uint32>(); // Always 0 crossRealmGuid[2] = recvData.ReadBit(); crossRealmGuid[7] = recvData.ReadBit(); uint8 realmLen = recvData.ReadBits(9); crossRealmGuid[3] = recvData.ReadBit(); uint8 nameLen = recvData.ReadBits(10); crossRealmGuid[5] = recvData.ReadBit(); crossRealmGuid[4] = recvData.ReadBit(); crossRealmGuid[6] = recvData.ReadBit(); crossRealmGuid[0] = recvData.ReadBit(); crossRealmGuid[1] = recvData.ReadBit(); recvData.ReadByteSeq(crossRealmGuid[4]); recvData.ReadByteSeq(crossRealmGuid[7]); recvData.ReadByteSeq(crossRealmGuid[6]); std::string memberName, realmName; memberName = recvData.ReadString(nameLen); realmName = recvData.ReadString(realmLen); // unused recvData.ReadByteSeq(crossRealmGuid[1]); recvData.ReadByteSeq(crossRealmGuid[0]); recvData.ReadByteSeq(crossRealmGuid[5]); recvData.ReadByteSeq(crossRealmGuid[3]); recvData.ReadByteSeq(crossRealmGuid[2]); // attempt add selected player // cheating if (!normalizePlayerName(memberName)) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); return; } Player* player = ObjectAccessor::FindPlayerByName(memberName); // no player if (!player) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); return; } // restrict invite to GMs if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !GetPlayer()->IsGameMaster() && player->IsGameMaster()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); return; } // can't group with if (!GetPlayer()->IsGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PLAYER_WRONG_FACTION); return; } if (GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_TARGET_NOT_IN_INSTANCE_S); return; } // just ignore us if (player->GetInstanceId() != 0 && player->GetDungeonDifficulty() != GetPlayer()->GetDungeonDifficulty()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S); return; } if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S); return; } ObjectGuid invitedGuid = player->GetGUID(); Group* group = GetPlayer()->GetGroup(); if (group && group->isBGGroup()) group = GetPlayer()->GetOriginalGroup(); Group* group2 = player->GetGroup(); if (group2 && group2->isBGGroup()) group2 = player->GetOriginalGroup(); // player already in another group or invited if (group2 || player->GetGroupInvite()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_ALREADY_IN_GROUP_S); if (group2) { // tell the player that they were invited but it failed as they were already in a group WorldPacket data(SMSG_GROUP_INVITE, 45); data.WriteBit(0); data.WriteBit(invitedGuid[0]); data.WriteBit(invitedGuid[3]); data.WriteBit(invitedGuid[2]); data.WriteBit(0); // Inverse already in group data.WriteBit(invitedGuid[6]); data.WriteBit(invitedGuid[5]); data.WriteBits(0, 9); // Realm name data.WriteBit(invitedGuid[4]); data.WriteBits(GetPlayer()->GetName().size(), 7); // Inviter name length data.WriteBits(0, 24); // Count 2 data.WriteBit(0); data.WriteBit(invitedGuid[1]); data.WriteBit(invitedGuid[7]); data.FlushBits(); data.WriteByteSeq(invitedGuid[1]); data.WriteByteSeq(invitedGuid[4]); data << int32(getMSTime()); data << int32(0); data << int32(0); data.WriteByteSeq(invitedGuid[6]); data.WriteByteSeq(invitedGuid[0]); data.WriteByteSeq(invitedGuid[2]); data.WriteByteSeq(invitedGuid[3]); // for count2 { int32(0) } data.WriteByteSeq(invitedGuid[5]); // data.append(realm name); data.WriteByteSeq(invitedGuid[7]); data.WriteString(GetPlayer()->GetName()); // inviter name data << int32(0); player->GetSession()->SendPacket(&data); } return; } if (group) { // not have permissions for invite if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) { SendPartyResult(PARTY_OP_INVITE, "", ERR_NOT_LEADER); return; } // not have place if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } } // ok, but group not exist, start a new group // but don't create and save the group to the DB until // at least one person joins if (!group) { group = new Group; // new group: if can't add then delete if (!group->AddLeaderInvite(GetPlayer())) { delete group; return; } if (!group->AddInvite(player)) { delete group; return; } } else { // already existed group: if can't add then just leave if (!group->AddInvite(player)) { return; } } // ok, we do it WorldPacket data(SMSG_GROUP_INVITE, 45); data.WriteBit(0); data.WriteBit(invitedGuid[0]); data.WriteBit(invitedGuid[3]); data.WriteBit(invitedGuid[2]); data.WriteBit(1); // Inverse already in group data.WriteBit(invitedGuid[6]); data.WriteBit(invitedGuid[5]); data.WriteBits(0, 9); // Realm name data.WriteBit(invitedGuid[4]); data.WriteBits(GetPlayer()->GetName().size(), 7); // Inviter name length data.WriteBits(0, 24); // Count 2 data.WriteBit(0); data.WriteBit(invitedGuid[1]); data.WriteBit(invitedGuid[7]); data.FlushBits(); data.WriteByteSeq(invitedGuid[1]); data.WriteByteSeq(invitedGuid[4]); data << int32(getMSTime()); data << int32(0); data << int32(0); data.WriteByteSeq(invitedGuid[6]); data.WriteByteSeq(invitedGuid[0]); data.WriteByteSeq(invitedGuid[2]); data.WriteByteSeq(invitedGuid[3]); // for count2 { int32(0) } data.WriteByteSeq(invitedGuid[5]); // data.append(realm name); data.WriteByteSeq(invitedGuid[7]); data.WriteString(GetPlayer()->GetName()); data << int32(0); player->GetSession()->SendPacket(&data); SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PARTY_RESULT_OK); }
void WorldSession::HandleGroupSetRolesOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_SET_ROLES"); uint32 newRole; ObjectGuid guid1; // Assigner GUID ObjectGuid guid2; // Target GUID guid1 = GetPlayer()->GetGUID(); recvData >> newRole; guid2[2] = recvData.ReadBit(); guid2[6] = recvData.ReadBit(); guid2[3] = recvData.ReadBit(); guid2[7] = recvData.ReadBit(); guid2[5] = recvData.ReadBit(); guid2[1] = recvData.ReadBit(); guid2[0] = recvData.ReadBit(); guid2[4] = recvData.ReadBit(); recvData.ReadByteSeq(guid2[6]); recvData.ReadByteSeq(guid2[4]); recvData.ReadByteSeq(guid2[1]); recvData.ReadByteSeq(guid2[3]); recvData.ReadByteSeq(guid2[0]); recvData.ReadByteSeq(guid2[5]); recvData.ReadByteSeq(guid2[2]); recvData.ReadByteSeq(guid2[7]); WorldPacket data(SMSG_GROUP_SET_ROLE, 24); data.WriteBit(guid1[1]); data.WriteBit(guid2[0]); data.WriteBit(guid2[2]); data.WriteBit(guid2[4]); data.WriteBit(guid2[7]); data.WriteBit(guid2[3]); data.WriteBit(guid1[7]); data.WriteBit(guid2[5]); data.WriteBit(guid1[5]); data.WriteBit(guid1[4]); data.WriteBit(guid1[3]); data.WriteBit(guid2[6]); data.WriteBit(guid1[2]); data.WriteBit(guid1[6]); data.WriteBit(guid2[1]); data.WriteBit(guid1[0]); data.WriteByteSeq(guid1[7]); data.WriteByteSeq(guid2[3]); data.WriteByteSeq(guid1[6]); data.WriteByteSeq(guid2[4]); data.WriteByteSeq(guid2[0]); data << uint32(newRole); // New Role data.WriteByteSeq(guid2[6]); data.WriteByteSeq(guid2[2]); data.WriteByteSeq(guid1[0]); data.WriteByteSeq(guid1[4]); data.WriteByteSeq(guid2[1]); data.WriteByteSeq(guid1[3]); data.WriteByteSeq(guid1[5]); data.WriteByteSeq(guid1[2]); data.WriteByteSeq(guid2[5]); data.WriteByteSeq(guid2[7]); data.WriteByteSeq(guid1[1]); data << uint32(0); // Old Role if (Group* group = GetPlayer()->GetGroup()) { /// @todo probably should be sent only if (oldRole != newRole) group->BroadcastPacket(&data, false); group->SetLfgRoles(guid2, newRole); } else SendPacket(&data); }
void WorldSession::HandleGroupSetRolesOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_SET_ROLES"); uint32 newRole; ObjectGuid guid1; // Assigner GUID ObjectGuid guid2; // Target GUID guid1 = GetPlayer()->GetGUID(); recvData >> newRole; guid2[2] = recvData.ReadBit(); guid2[6] = recvData.ReadBit(); guid2[3] = recvData.ReadBit(); guid2[7] = recvData.ReadBit(); guid2[5] = recvData.ReadBit(); guid2[1] = recvData.ReadBit(); guid2[0] = recvData.ReadBit(); guid2[4] = recvData.ReadBit(); recvData.ReadByteSeq(guid2[6]); recvData.ReadByteSeq(guid2[4]); recvData.ReadByteSeq(guid2[1]); recvData.ReadByteSeq(guid2[3]); recvData.ReadByteSeq(guid2[0]); recvData.ReadByteSeq(guid2[5]); recvData.ReadByteSeq(guid2[2]); recvData.ReadByteSeq(guid2[7]); WorldPacket data(SMSG_GROUP_SET_ROLE, 24); data.WriteBit(guid1[1]); data.WriteBit(guid2[0]); data.WriteBit(guid2[2]); data.WriteBit(guid2[4]); data.WriteBit(guid2[7]); data.WriteBit(guid2[3]); data.WriteBit(guid1[7]); data.WriteBit(guid2[5]); data.WriteBit(guid1[5]); data.WriteBit(guid1[4]); data.WriteBit(guid1[3]); data.WriteBit(guid2[6]); data.WriteBit(guid1[2]); data.WriteBit(guid1[6]); data.WriteBit(guid2[1]); data.WriteBit(guid1[0]); data.WriteByteSeq(guid1[7]); data.WriteByteSeq(guid2[3]); data.WriteByteSeq(guid1[6]); data.WriteByteSeq(guid2[4]); data.WriteByteSeq(guid2[0]); data << uint32(newRole); // New Role data.WriteByteSeq(guid2[6]); data.WriteByteSeq(guid2[2]); data.WriteByteSeq(guid1[0]); data.WriteByteSeq(guid1[4]); data.WriteByteSeq(guid2[1]); data.WriteByteSeq(guid1[3]); data.WriteByteSeq(guid1[5]); data.WriteByteSeq(guid1[2]); data.WriteByteSeq(guid2[5]); data.WriteByteSeq(guid2[7]); data.WriteByteSeq(guid1[1]); data << uint32(0); // Old Role if (GetPlayer()->GetGroup()) GetPlayer()->GetGroup()->BroadcastPacket(&data, false); else SendPacket(&data); }
void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_BATTLEFIELD_PORT Message"); uint32 time; uint32 queueSlot; uint32 unk; uint8 action; // enter battle 0x1, leave queue 0x0 ObjectGuid guid; recvData >> time; recvData >> queueSlot; recvData >> unk; guid[0] = recvData.ReadBit(); guid[1] = recvData.ReadBit(); guid[5] = recvData.ReadBit(); guid[6] = recvData.ReadBit(); guid[7] = recvData.ReadBit(); guid[4] = recvData.ReadBit(); guid[3] = recvData.ReadBit(); guid[2] = recvData.ReadBit(); action = recvData.ReadBit(); recvData.ReadByteSeq(guid[1]); recvData.ReadByteSeq(guid[3]); recvData.ReadByteSeq(guid[5]); recvData.ReadByteSeq(guid[7]); recvData.ReadByteSeq(guid[0]); recvData.ReadByteSeq(guid[2]); recvData.ReadByteSeq(guid[6]); recvData.ReadByteSeq(guid[4]); if (!_player->InBattlegroundQueue()) { sLog->outDebug(LOG_FILTER_BATTLEGROUND, "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Player not in queue!", GetPlayerInfo().c_str(), queueSlot, unk, time, action); return; } BattlegroundQueueTypeId bgQueueTypeId = _player->GetBattlegroundQueueTypeId(queueSlot); if (bgQueueTypeId == BATTLEGROUND_QUEUE_NONE) { sLog->outDebug(LOG_FILTER_BATTLEGROUND, "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Invalid queueSlot!", GetPlayerInfo().c_str(), queueSlot, unk, time, action); return; } BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); //we must use temporary variable, because GroupQueueInfo pointer can be deleted in BattlegroundQueue::RemovePlayer() function GroupQueueInfo ginfo; if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo)) { sLog->outDebug(LOG_FILTER_BATTLEGROUND, "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Player not in queue (No player Group Info)!", GetPlayerInfo().c_str(), queueSlot, unk, time, action); return; } // if action == 1, then instanceId is required if (!ginfo.IsInvitedToBGInstanceGUID && action == 1) { sLog->outDebug(LOG_FILTER_BATTLEGROUND, "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Player is not invited to any bg!", GetPlayerInfo().c_str(), queueSlot, unk, time, action); return; } BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(bgQueueTypeId); // BGTemplateId returns BATTLEGROUND_AA when it is arena queue. // Do instance id search as there is no AA bg instances. Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId == BATTLEGROUND_AA ? BATTLEGROUND_TYPE_NONE : bgTypeId); if (!bg) { if (action) { sLog->outDebug(LOG_FILTER_BATTLEGROUND, "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Cant find BG with id %u!", GetPlayerInfo().c_str(), queueSlot, unk, time, action, ginfo.IsInvitedToBGInstanceGUID); return; } bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId); if (!bg) { sLog->outError(LOG_FILTER_NETWORKIO, "BattlegroundHandler: bg_template not found for type id %u.", bgTypeId); return; } } sLog->outDebug(LOG_FILTER_BATTLEGROUND, "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u.", GetPlayerInfo().c_str(), queueSlot, unk, time, action); // get real bg type bgTypeId = bg->GetTypeID(); // expected bracket entry PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel()); if (!bracketEntry) return; //some checks if player isn't cheating - it is not exactly cheating, but we cannot allow it if (action == 1 && ginfo.ArenaType == 0) { //if player is trying to enter battleground (not arena!) and he has deserter debuff, we must just remove him from queue if (!_player->CanJoinToBattleground(bg)) { //send bg command result to show nice message WorldPacket data2; sBattlegroundMgr->BuildStatusFailedPacket(&data2, bg, _player, 0, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS); _player->GetSession()->SendPacket(&data2); action = 0; sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Player %s (%u) has a deserter debuff, do not port him to battleground!", _player->GetName().c_str(), _player->GetGUIDLow()); } //if player don't match battleground max level, then do not allow him to enter! (this might happen when player leveled up during his waiting in queue if (_player->getLevel() > bg->GetMaxLevel()) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Player %s (%u) has level (%u) higher than maxlevel (%u) of battleground (%u)! Do not port him to battleground!", _player->GetName().c_str(), _player->GetGUIDLow(), _player->getLevel(), bg->GetMaxLevel(), bg->GetTypeID()); action = 0; } } WorldPacket data; switch (action) { case 1: // port to battleground if (!_player->IsInvitedForBattlegroundQueueType(bgQueueTypeId)) return; // cheating? if (!_player->InBattleground()) _player->SetBattlegroundEntryPoint(); // resurrect the player if (!_player->isAlive()) { _player->ResurrectPlayer(1.0f); _player->SpawnCorpseBones(); } // stop taxi flight at port if (_player->isInFlight()) { _player->GetMotionMaster()->MovementExpired(); _player->CleanupAfterTaxiFlight(); } sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player, queueSlot, STATUS_IN_PROGRESS, _player->GetBattlegroundQueueJoinTime(bgTypeId), bg->GetElapsedTime(), bg->GetArenaType()); _player->GetSession()->SendPacket(&data); // remove battleground queue status from BGmgr bgQueue.RemovePlayer(_player->GetGUID(), false); // this is still needed here if battleground "jumping" shouldn't add deserter debuff // also this is required to prevent stuck at old battleground after SetBattlegroundId set to new if (Battleground* currentBg = _player->GetBattleground()) currentBg->RemovePlayerAtLeave(_player->GetGUID(), false, true); // set the destination instance id _player->SetBattlegroundId(bg->GetInstanceID(), bgTypeId); // set the destination team _player->SetBGTeam(ginfo.Team); // bg->HandleBeforeTeleportToBattleground(_player); sBattlegroundMgr->SendToBattleground(_player, ginfo.IsInvitedToBGInstanceGUID, bgTypeId); // add only in HandleMoveWorldPortAck() // bg->AddPlayer(_player, team); sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player %s (%u) joined battle for bg %u, bgtype %u, queue type %u.", _player->GetName().c_str(), _player->GetGUIDLow(), bg->GetInstanceID(), bg->GetTypeID(), bgQueueTypeId); break; case 0: // leave queue if (bg->isArena() && bg->GetStatus() > STATUS_WAIT_QUEUE) return; // if player leaves rated arena match before match start, it is counted as he played but he lost if (ginfo.IsRated && ginfo.IsInvitedToBGInstanceGUID) { ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(ginfo.Team); if (at) { sLog->outDebug(LOG_FILTER_BATTLEGROUND, "UPDATING memberLost's personal arena rating for %u by opponents rating: %u, because he has left queue!", GUID_LOPART(_player->GetGUID()), ginfo.OpponentsTeamRating); at->MemberLost(_player, ginfo.OpponentsMatchmakerRating); at->SaveToDB(); } } _player->RemoveBattlegroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player, queueSlot, STATUS_NONE, _player->GetBattlegroundQueueJoinTime(bgTypeId), 0, 0); bgQueue.RemovePlayer(_player->GetGUID(), true); // player left queue, we should update it - do not update Arena Queue if (!ginfo.ArenaType) sBattlegroundMgr->ScheduleQueueUpdate(ginfo.ArenaMatchmakerRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); SendPacket(&data); sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player %s (%u) left queue for bgtype %u, queue type %u.", _player->GetName().c_str(), _player->GetGUIDLow(), bg->GetTypeID(), bgQueueTypeId); break; default: sLog->outError(LOG_FILTER_NETWORKIO, "Battleground port: unknown action %u", action); break; } }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); ObjectGuid guid; recvData.read_skip<uint8>(); // flags guid[7] = recvData.ReadBit(); guid[4] = recvData.ReadBit(); guid[0] = recvData.ReadBit(); guid[1] = recvData.ReadBit(); guid[3] = recvData.ReadBit(); guid[6] = recvData.ReadBit(); guid[2] = recvData.ReadBit(); guid[5] = recvData.ReadBit(); recvData.ReadByteSeq(guid[3]); recvData.ReadByteSeq(guid[6]); recvData.ReadByteSeq(guid[5]); recvData.ReadByteSeq(guid[2]); recvData.ReadByteSeq(guid[1]); recvData.ReadByteSeq(guid[4]); recvData.ReadByteSeq(guid[0]); recvData.ReadByteSeq(guid[7]); Player* player = HashMapHolder<Player>::Find(guid); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.appendPackGUID(guid); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Pet* pet = player->GetPet(); Powers powerType = player->getPowerType(); std::set<uint32> phases; player->GetPhaseMgr().GetActivePhases(phases); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.append(player->GetPackGUID()); uint32 updateFlags = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_AURAS | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | GROUP_UPDATE_FLAG_PET_AURAS; if (powerType != POWER_MANA) updateFlags |= GROUP_UPDATE_FLAG_POWER_TYPE; if (pet) updateFlags |= GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP | GROUP_UPDATE_FLAG_PET_POWER_TYPE | GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER; if (player->GetVehicle()) updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT; if (!phases.empty()) updateFlags |= GROUP_UPDATE_FLAG_PHASE; uint16 playerStatus = MEMBER_STATUS_ONLINE; if (player->IsPvP()) playerStatus |= MEMBER_STATUS_PVP; if (!player->IsAlive()) { if (player->HasFlag(PLAYER_FIELD_PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) playerStatus |= MEMBER_STATUS_GHOST; else playerStatus |= MEMBER_STATUS_DEAD; } if (player->HasByteFlag(UNIT_FIELD_SHAPESHIFT_FORM, 1, UNIT_BYTE2_FLAG_FFA_PVP)) playerStatus |= MEMBER_STATUS_PVP_FFA; if (player->isAFK()) playerStatus |= MEMBER_STATUS_AFK; if (player->isDND()) playerStatus |= MEMBER_STATUS_DND; data << uint32(updateFlags); data << uint16(playerStatus); // GROUP_UPDATE_FLAG_STATUS data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP if (updateFlags & GROUP_UPDATE_FLAG_POWER_TYPE) data << uint8(powerType); data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionZ()); // GROUP_UPDATE_FLAG_POSITION // GROUP_UPDATE_FLAG_AURAS data << uint8(1); uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder data << uint32(MAX_AURAS); // count for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(aurApp->GetBase()->GetId()); data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) data << int32(eff->GetAmount()); else data << int32(0); } } } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if (updateFlags & GROUP_UPDATE_FLAG_PET_GUID) data << uint64(pet->GetGUID()); data << std::string(pet ? pet->GetName() : ""); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet ? pet->GetDisplayId() : 0); // GROUP_UPDATE_FLAG_PET_MODEL_ID if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_HP) data << uint32(pet->GetHealth()); if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_HP) data << uint32(pet->GetMaxHealth()); if (updateFlags & GROUP_UPDATE_FLAG_PET_POWER_TYPE) data << (uint8)pet->getPowerType(); if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_POWER) data << uint16(pet->GetPower(pet->getPowerType())); if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_POWER) data << uint16(pet->GetMaxPower(pet->getPowerType())); // GROUP_UPDATE_FLAG_PET_AURAS uint64 petAuraMask = 0; data << uint8(1); maskPos = data.wpos(); data << uint64(petAuraMask); // placeholder data << uint32(MAX_AURAS); // count if (pet) { for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = pet->GetVisibleAura(i)) { petAuraMask |= (uint64(1) << i); data << uint32(aurApp->GetBase()->GetId()); data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) data << int32(eff->GetAmount()); else data << int32(0); } } } } } data.put<uint64>(maskPos, petAuraMask); // GROUP_UPDATE_FLAG_PET_AURAS if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT) data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]); if (updateFlags & GROUP_UPDATE_FLAG_PHASE) { data << uint32(phases.empty() ? 8 : 0); data << uint32(phases.size()); for (std::set<uint32>::const_iterator itr = phases.begin(); itr != phases.end(); ++itr) data << uint16(*itr); } SendPacket(&data); }
void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) { uint32 bgTypeId_; uint32 instanceId; uint8 asGroup; bool isPremade = false; Group* grp = NULL; ObjectGuid guid; recvData >> instanceId; // Instance Id guid[2] = recvData.ReadBit(); guid[0] = recvData.ReadBit(); guid[3] = recvData.ReadBit(); guid[1] = recvData.ReadBit(); guid[5] = recvData.ReadBit(); asGroup = recvData.ReadBit(); // As Group guid[4] = recvData.ReadBit(); guid[6] = recvData.ReadBit(); guid[7] = recvData.ReadBit(); recvData.ReadByteSeq(guid[2]); recvData.ReadByteSeq(guid[6]); recvData.ReadByteSeq(guid[4]); recvData.ReadByteSeq(guid[3]); recvData.ReadByteSeq(guid[7]); recvData.ReadByteSeq(guid[0]); recvData.ReadByteSeq(guid[5]); recvData.ReadByteSeq(guid[1]); //extract from guid bgTypeId_ = GUID_LOPART(guid); if (!sBattlemasterListStore.LookupEntry(bgTypeId_)) { sLog->outError(LOG_FILTER_NETWORKIO, "Battleground: invalid bgtype (%u) received. possible cheater? player guid %u", bgTypeId_, _player->GetGUIDLow()); return; } if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId_, NULL)) { ChatHandler(this).PSendSysMessage(LANG_BG_DISABLED); return; } BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_); //sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from (GUID:"UI64FMTD" TypeId:%u)", guid, bgTypeId_); // can do this, since it's battleground, not arena BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, 0); BattlegroundQueueTypeId bgQueueTypeIdRandom = BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_RB, 0); // ignore if player is already in BG if (_player->InBattleground()) return; // get bg instance or bg template if instance not found Battleground* bg = NULL; if (instanceId) bg = sBattlegroundMgr->GetBattlegroundThroughClientInstance(instanceId, bgTypeId); if (!bg) bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId); if (!bg) return; // expected bracket entry PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel()); if (!bracketEntry) return; GroupJoinBattlegroundResult err = ERR_BATTLEGROUND_NONE; // check queue conditions if (!asGroup) { if (GetPlayer()->isUsingLfg()) { WorldPacket data; sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_LFG_CANT_USE_BATTLEGROUND); GetPlayer()->GetSession()->SendPacket(&data); return; } // check Deserter debuff if (!_player->CanJoinToBattleground(bg)) { WorldPacket data; sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS); _player->GetSession()->SendPacket(&data); return; } if (_player->GetBattlegroundQueueIndex(bgQueueTypeIdRandom) < PLAYER_MAX_BATTLEGROUND_QUEUES) { // player is already in random queue WorldPacket data; sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_IN_RANDOM_BG); _player->GetSession()->SendPacket(&data); return; } if (_player->InBattlegroundQueue() && bgTypeId == BATTLEGROUND_RB) { // player is already in queue, can't start random queue WorldPacket data; sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_IN_NON_RANDOM_BG); _player->GetSession()->SendPacket(&data); return; } // check if already in queue if (_player->GetBattlegroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is already in this queue return; // check if has free queue slots if (!_player->HasFreeBattlegroundQueueId()) { WorldPacket data; sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_BATTLEGROUND_TOO_MANY_QUEUES); _player->GetSession()->SendPacket(&data); return; } BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId); // add joined time data _player->AddBattlegroundQueueJoinTime(bgTypeId, ginfo->JoinTime); WorldPacket data; // send status packet (in queue) sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player, queueSlot, STATUS_WAIT_QUEUE, avgTime, ginfo->JoinTime, ginfo->ArenaType); SendPacket(&data); sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, _player->GetGUIDLow(), _player->GetName().c_str()); } else { grp = _player->GetGroup(); if (!grp) return; if (grp->GetLeaderGUID() != _player->GetGUID()) return; err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0); isPremade = (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam()); BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo* ginfo = NULL; uint32 avgTime = 0; if (!err) { sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: the following players are joining as group:"); ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); } for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->getSource(); if (!member) continue; // this should never happen if (err) { WorldPacket data; sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, err); member->GetSession()->SendPacket(&data); continue; } // add to queue uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId); // add joined time data member->AddBattlegroundQueueJoinTime(bgTypeId, ginfo->JoinTime); WorldPacket data; // send status packet (in queue) sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, member, queueSlot, STATUS_WAIT_QUEUE, avgTime, ginfo->JoinTime, ginfo->ArenaType); member->GetSession()->SendPacket(&data); sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName().c_str()); } sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: group end"); } sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); }
void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_UNINVITE_GUID"); ObjectGuid guid; recvData.read_skip<uint8>(); guid[6] = recvData.ReadBit(); guid[4] = recvData.ReadBit(); guid[3] = recvData.ReadBit(); guid[2] = recvData.ReadBit(); guid[0] = recvData.ReadBit(); guid[1] = recvData.ReadBit(); guid[7] = recvData.ReadBit(); guid[5] = recvData.ReadBit(); uint8 reasonLen = recvData.ReadBits(8); std::string reason = recvData.ReadString(reasonLen); recvData.ReadByteSeq(guid[5]); recvData.ReadByteSeq(guid[6]); recvData.ReadByteSeq(guid[1]); recvData.ReadByteSeq(guid[4]); recvData.ReadByteSeq(guid[3]); recvData.ReadByteSeq(guid[2]); recvData.ReadByteSeq(guid[7]); recvData.ReadByteSeq(guid[0]); //can't uninvite yourself if (guid == GetPlayer()->GetGUID()) { TC_LOG_ERROR("network", "WorldSession::HandleGroupUninviteGuidOpcode: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow()); return; } PartyResult res = GetPlayer()->CanUninviteFromGroup(); if (res != ERR_PARTY_RESULT_OK) { SendPartyResult(PARTY_OP_UNINVITE, "", res); return; } Group* grp = GetPlayer()->GetGroup(); if (!grp) return; if (grp->IsLeader(guid)) { SendPartyResult(PARTY_OP_UNINVITE, "", ERR_NOT_LEADER); return; } if (grp->IsMember(guid)) { Player::RemoveFromGroup(grp, guid, GROUP_REMOVEMETHOD_KICK, GetPlayer()->GetGUID(), reason.c_str()); return; } if (Player* player = grp->GetInvited(guid)) { player->UninviteFromGroup(); return; } SendPartyResult(PARTY_OP_UNINVITE, "", ERR_TARGET_NOT_IN_GROUP_S); }
void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) { sLog->outInfo(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_INVITE"); time_t now = time(NULL); if (now - timeLastGroupInviteCommand < 5) return; else timeLastGroupInviteCommand = now; ObjectGuid crossRealmGuid; // unused recvData.read_skip<uint32>(); // Non-zero in cross realm invites recvData.read_skip<uint8>(); recvData.read_skip<uint32>(); // Always 0 crossRealmGuid[7] = recvData.ReadBit(); uint8 realmLen = recvData.ReadBits(9); crossRealmGuid[3] = recvData.ReadBit(); uint8 nameLen = recvData.ReadBits(9); crossRealmGuid[2] = recvData.ReadBit(); crossRealmGuid[5] = recvData.ReadBit(); crossRealmGuid[4] = recvData.ReadBit(); crossRealmGuid[0] = recvData.ReadBit(); crossRealmGuid[1] = recvData.ReadBit(); crossRealmGuid[6] = recvData.ReadBit(); recvData.ReadByteSeq(crossRealmGuid[7]); recvData.ReadByteSeq(crossRealmGuid[6]); recvData.ReadByteSeq(crossRealmGuid[0]); recvData.ReadByteSeq(crossRealmGuid[4]); std::string realmName = recvData.ReadString(realmLen); // unused recvData.ReadByteSeq(crossRealmGuid[1]); recvData.ReadByteSeq(crossRealmGuid[2]); recvData.ReadByteSeq(crossRealmGuid[3]); std::string memberName = recvData.ReadString(nameLen); recvData.ReadByteSeq(crossRealmGuid[5]); // attempt add selected player // cheating if (!normalizePlayerName(memberName)) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); return; } Player* player = sObjectAccessor->FindPlayerByName(memberName.c_str()); // no player if (!player) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); return; } // restrict invite to GMs if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !GetPlayer()->isGameMaster() && player->isGameMaster()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); return; } // can't group with if (!GetPlayer()->isGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PLAYER_WRONG_FACTION); return; } if (GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_TARGET_NOT_IN_INSTANCE_S); return; } // just ignore us if (player->GetInstanceId() != 0 && player->GetDungeonDifficulty() != GetPlayer()->GetDungeonDifficulty()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S); return; } if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S); return; } Group* group = GetPlayer()->GetGroup(); if (group && group->isBGGroup()) group = GetPlayer()->GetOriginalGroup(); Group* group2 = player->GetGroup(); if (group2 && group2->isBGGroup()) group2 = player->GetOriginalGroup(); // player already in another group or invited if (group2 || player->GetGroupInvite()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_ALREADY_IN_GROUP_S); if (group2) { // tell the player that they were invited but it failed as they were already in a group player->GetSession()->SendGroupInviteNotification(GetPlayer()->GetName(), true); } return; } if (group) { // not have permissions for invite if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) { SendPartyResult(PARTY_OP_INVITE, "", ERR_NOT_LEADER); return; } // not have place if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } } // ok, but group not exist, start a new group // but don't create and save the group to the DB until // at least one person joins if (!group) { group = new Group; // new group: if can't add then delete if (!group->AddLeaderInvite(GetPlayer())) { delete group; return; } if (!group->AddInvite(player)) { delete group; return; } } else { // already existed group: if can't add then just leave if (!group->AddInvite(player)) { return; } } // ok, we do it player->GetSession()->SendGroupInviteNotification(GetPlayer()->GetName(), false); SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PARTY_RESULT_OK); }
void WorldSession::HandleSendMail(WorldPacket& recvData) { ObjectGuid mailbox; uint64 money, COD; std::string receiverName, subject, body; uint32 bodyLength, subjectLength, receiverLength; uint32 unk1, unk2; uint8 itemCount; recvData >> unk1 >> unk2; // both unknown recvData >> COD >> money; // money and cod mailbox[0] = recvData.ReadBit(); mailbox[6] = recvData.ReadBit(); mailbox[4] = recvData.ReadBit(); mailbox[1] = recvData.ReadBit(); bodyLength = recvData.ReadBits(11); mailbox[3] = recvData.ReadBit(); receiverLength = recvData.ReadBits(9); mailbox[7] = recvData.ReadBit(); mailbox[5] = recvData.ReadBit(); itemCount = recvData.ReadBits(5); // attached items count if (itemCount > MAX_MAIL_ITEMS) // client limit { GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS); recvData.rfinish(); // set to end to avoid warnings spam return; } ObjectGuid itemGuids[MAX_MAIL_ITEMS]; for (uint8 i = 0; i < itemCount; ++i) { itemGuids[i][1] = recvData.ReadBit(); itemGuids[i][7] = recvData.ReadBit(); itemGuids[i][2] = recvData.ReadBit(); itemGuids[i][5] = recvData.ReadBit(); itemGuids[i][0] = recvData.ReadBit(); itemGuids[i][6] = recvData.ReadBit(); itemGuids[i][3] = recvData.ReadBit(); itemGuids[i][4] = recvData.ReadBit(); } subjectLength = recvData.ReadBits(9); mailbox[2] = recvData.ReadBit(); for (uint8 i = 0; i < itemCount; ++i) { recvData.read_skip<uint8>(); // item slot in mail, not used recvData.ReadByteSeq(itemGuids[i][3]); recvData.ReadByteSeq(itemGuids[i][0]); recvData.ReadByteSeq(itemGuids[i][2]); recvData.ReadByteSeq(itemGuids[i][1]); recvData.ReadByteSeq(itemGuids[i][6]); recvData.ReadByteSeq(itemGuids[i][5]); recvData.ReadByteSeq(itemGuids[i][7]); recvData.ReadByteSeq(itemGuids[i][4]); } recvData.ReadByteSeq(mailbox[1]); body = recvData.ReadString(bodyLength); recvData.ReadByteSeq(mailbox[0]); subject = recvData.ReadString(subjectLength); recvData.ReadByteSeq(mailbox[2]); recvData.ReadByteSeq(mailbox[6]); recvData.ReadByteSeq(mailbox[5]); recvData.ReadByteSeq(mailbox[7]); recvData.ReadByteSeq(mailbox[3]); recvData.ReadByteSeq(mailbox[4]); receiverName = recvData.ReadString(receiverLength); // packet read complete, now do check if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; if (receiverName.empty()) return; Player* player = _player; if (player->getLevel() < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_MAIL_SENDER_REQ), sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)); return; } uint64 receiverGuid = 0; if (normalizePlayerName(receiverName)) receiverGuid = sObjectMgr->GetPlayerGUIDByName(receiverName); if (!receiverGuid) { TC_LOG_INFO("network", "Player %u is sending mail to %s (GUID: not existed!) with subject %s " "and body %s includes %u items, " UI64FMTD " copper and " UI64FMTD " COD copper with unk1 = %u, unk2 = %u", player->GetGUIDLow(), receiverName.c_str(), subject.c_str(), body.c_str(), itemCount, money, COD, unk1, unk2); player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND); return; } TC_LOG_INFO("network", "Player %u is sending mail to %s (GUID: %u) with subject %s and body %s " "includes %u items, " UI64FMTD " copper and " UI64FMTD " COD copper with unk1 = %u, unk2 = %u", player->GetGUIDLow(), receiverName.c_str(), GUID_LOPART(receiverGuid), subject.c_str(), body.c_str(), itemCount, money, COD, unk1, unk2); if (player->GetGUID() == receiverGuid) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANNOT_SEND_TO_SELF); return; } uint32 cost = itemCount ? 30 * itemCount : 30; // price hardcoded in client uint64 reqmoney = cost + money; if (!player->HasEnoughMoney(reqmoney) && !player->IsGameMaster()) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY); return; } Player* receiver = ObjectAccessor::FindPlayer(receiverGuid); uint32 receiverTeam = 0; uint8 mailsCount = 0; //do not allow to send to one player more than 100 mails uint8 receiverLevel = 0; uint32 receiverAccountId = 0; if (receiver) { receiverTeam = receiver->GetTeam(); mailsCount = receiver->GetMailSize(); receiverLevel = receiver->getLevel(); receiverAccountId = receiver->GetSession()->GetAccountId(); } else { receiverTeam = sObjectMgr->GetPlayerTeamByGUID(receiverGuid); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT); stmt->setUInt32(0, GUID_LOPART(receiverGuid)); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { Field* fields = result->Fetch(); mailsCount = fields[0].GetUInt64(); } stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_LEVEL); stmt->setUInt32(0, GUID_LOPART(receiverGuid)); result = CharacterDatabase.Query(stmt); if (result) { Field* fields = result->Fetch(); receiverLevel = fields[0].GetUInt8(); } receiverAccountId = sObjectMgr->GetPlayerAccountIdByGUID(receiverGuid); } // do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255.. if (mailsCount > 100) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_CAP_REACHED); return; } // test the receiver's Faction... or all items are account bound bool accountBound = itemCount ? true : false; for (uint8 i = 0; i < itemCount; ++i) { if (Item* item = player->GetItemByGuid(itemGuids[i])) { ItemTemplate const* itemProto = item->GetTemplate(); if (!itemProto || !(itemProto->Flags & ITEM_PROTO_FLAG_BIND_TO_ACCOUNT)) { accountBound = false; break; } } } if (!accountBound && player->GetTeam() != receiverTeam && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_MAIL)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_YOUR_TEAM); return; } if (receiverLevel < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_MAIL_RECEIVER_REQ), sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)); return; } Item* items[MAX_MAIL_ITEMS]; for (uint8 i = 0; i < itemCount; ++i) { if (!itemGuids[i]) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } Item* item = player->GetItemByGuid(itemGuids[i]); // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail) if (!item) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } if (!item->CanBeTraded(true)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM); return; } if (item->IsBoundAccountWide() && item->IsSoulBound() && player->GetSession()->GetAccountId() != receiverAccountId) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_NOT_SAME_ACCOUNT); return; } if (item->GetTemplate()->Flags & ITEM_PROTO_FLAG_CONJURED || item->GetUInt32Value(ITEM_FIELD_EXPIRATION)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM); return; } if (COD && item->HasFlag(ITEM_FIELD_DYNAMIC_FLAGS, ITEM_FLAG_WRAPPED)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANT_SEND_WRAPPED_COD); return; } if (item->IsNotEmptyBag()) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_DESTROY_NONEMPTY_BAG); return; } items[i] = item; } player->SendMailResult(0, MAIL_SEND, MAIL_OK); player->ModifyMoney(-int64(reqmoney)); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost); bool needItemDelay = false; MailDraft draft(subject, body); SQLTransaction trans = CharacterDatabase.BeginTransaction(); if (itemCount > 0 || money > 0) { bool log = HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE); if (itemCount > 0) { for (uint8 i = 0; i < itemCount; ++i) { Item* item = items[i]; if (log) { sLog->outCommand(GetAccountId(), "GM %s (GUID: %u) (Account: %u) mail item: %s (Entry: %u Count: %u) " "to player: %s (GUID: %u) (Account: %u)", GetPlayerName().c_str(), GetGuidLow(), GetAccountId(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount(), receiverName.c_str(), GUID_LOPART(receiverGuid), receiverAccountId); } item->SetNotRefundable(GetPlayer()); // makes the item no longer refundable player->MoveItemFromInventory(items[i]->GetBagSlot(), item->GetSlot(), true); item->DeleteFromInventoryDB(trans); // deletes item from character's inventory item->SetOwnerGUID(receiverGuid); item->SaveToDB(trans); // recursive and not have transaction guard into self, item not in inventory and can be save standalone draft.AddItem(item); } // if item send to character at another account, then apply item delivery delay needItemDelay = player->GetSession()->GetAccountId() != receiverAccountId; } if (log && money > 0) { sLog->outCommand(GetAccountId(), "GM %s (GUID: %u) (Account: %u) mail money: " UI64FMTD " to player: %s (GUID: %u) (Account: %u)", GetPlayerName().c_str(), GetGuidLow(), GetAccountId(), money, receiverName.c_str(), GUID_LOPART(receiverGuid), receiverAccountId); } } // If theres is an item, there is a one hour delivery delay if sent to another account's character. uint32 deliver_delay = needItemDelay ? sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0; // Mail sent between guild members arrives instantly if they have the guild perk "Guild Mail" if (Guild* guild = sGuildMgr->GetGuildById(player->GetGuildId())) if (guild->GetLevel() >= 17 && guild->IsMember(receiverGuid)) deliver_delay = 0; // will delete item or place to receiver mail list draft .AddMoney(money) .AddCOD(COD) .SendMailTo(trans, MailReceiver(receiver, GUID_LOPART(receiverGuid)), MailSender(player), body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay); player->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); }
void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_UNINVITE_GUID"); ObjectGuid guid; std::string unkstring; recvData.read_skip<uint8>(); // unk 0x00 guid[6] = recvData.ReadBit(); guid[4] = recvData.ReadBit(); guid[3] = recvData.ReadBit(); guid[2] = recvData.ReadBit(); guid[0] = recvData.ReadBit(); guid[1] = recvData.ReadBit(); guid[7] = recvData.ReadBit(); guid[5] = recvData.ReadBit(); uint8 stringSize = recvData.ReadBits(8); unkstring = recvData.ReadString(stringSize); recvData.ReadByteSeq(guid[5]); recvData.ReadByteSeq(guid[6]); recvData.ReadByteSeq(guid[1]); recvData.ReadByteSeq(guid[4]); recvData.ReadByteSeq(guid[3]); recvData.ReadByteSeq(guid[2]); recvData.ReadByteSeq(guid[7]); recvData.ReadByteSeq(guid[0]); // Can't uninvite yourself if (guid == GetPlayer()->GetGUID()) { sLog->outError(LOG_FILTER_NETWORKIO, "WorldSession::HandleGroupUninviteGuidOpcode: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow()); return; } PartyResult res = GetPlayer()->CanUninviteFromGroup(); if (res != ERR_PARTY_RESULT_OK) { SendPartyResult(PARTY_OP_UNINVITE, "", res); return; } Group* grp = GetPlayer()->GetGroup(); if (!grp) return; if (grp->IsLeader(guid)) { SendPartyResult(PARTY_OP_UNINVITE, "", ERR_NOT_LEADER); return; } if (grp->IsMember(guid)) { Player::RemoveFromGroup(grp, guid, GROUP_REMOVEMETHOD_KICK, GetPlayer()->GetGUID(), unkstring.c_str()); return; } if (Player* player = grp->GetInvited(guid)) { player->UninviteFromGroup(); return; } SendPartyResult(PARTY_OP_UNINVITE, "", ERR_TARGET_NOT_IN_GROUP_S); }
void WorldSession::HandleMailReturnToSender(WorldPacket& recvData) { ObjectGuid mailbox; uint32 mailId; recvData >> mailId; mailbox[2] = recvData.ReadBit(); mailbox[0] = recvData.ReadBit(); mailbox[4] = recvData.ReadBit(); mailbox[6] = recvData.ReadBit(); mailbox[3] = recvData.ReadBit(); mailbox[1] = recvData.ReadBit(); mailbox[7] = recvData.ReadBit(); mailbox[5] = recvData.ReadBit(); recvData.ReadByteSeq(mailbox[5]); recvData.ReadByteSeq(mailbox[6]); recvData.ReadByteSeq(mailbox[2]); recvData.ReadByteSeq(mailbox[0]); recvData.ReadByteSeq(mailbox[3]); recvData.ReadByteSeq(mailbox[1]); recvData.ReadByteSeq(mailbox[4]); recvData.ReadByteSeq(mailbox[7]); if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; Player* player = _player; Mail* m = player->GetMail(mailId); if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL)) { player->SendMailResult(mailId, MAIL_RETURNED_TO_SENDER, MAIL_ERR_INTERNAL_ERROR); return; } //we can return mail now, so firstly delete the old one SQLTransaction trans = CharacterDatabase.BeginTransaction(); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_BY_ID); stmt->setUInt32(0, mailId); trans->Append(stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM_BY_ID); stmt->setUInt32(0, mailId); trans->Append(stmt); player->RemoveMail(mailId); // only return mail if the player exists (and delete if not existing) if (m->messageType == MAIL_NORMAL && m->sender) { MailDraft draft(m->subject, m->body); if (m->mailTemplateId) draft = MailDraft(m->mailTemplateId, false); // items already included if (m->HasItems()) { for (MailItemInfoVec::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2) { if (Item* const item = player->GetMItem(itr2->item_guid)) draft.AddItem(item); player->RemoveMItem(itr2->item_guid); } } draft.AddMoney(m->money).SendReturnToSender(GetAccountId(), m->receiver, m->sender, trans); } CharacterDatabase.CommitTransaction(trans); delete m; //we can deallocate old mail player->SendMailResult(mailId, MAIL_RETURNED_TO_SENDER, MAIL_OK); }
void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) { ObjectGuid guid; guid[0] = recvPacket.ReadBit(); guid[3] = recvPacket.ReadBit(); guid[5] = recvPacket.ReadBit(); guid[1] = recvPacket.ReadBit(); guid[4] = recvPacket.ReadBit(); guid[6] = recvPacket.ReadBit(); guid[7] = recvPacket.ReadBit(); guid[2] = recvPacket.ReadBit(); recvPacket.ReadByteSeq(guid[7]); recvPacket.ReadByteSeq(guid[4]); recvPacket.ReadByteSeq(guid[3]); recvPacket.ReadByteSeq(guid[5]); recvPacket.ReadByteSeq(guid[1]); recvPacket.ReadByteSeq(guid[2]); recvPacket.ReadByteSeq(guid[6]); recvPacket.ReadByteSeq(guid[0]); if (GetPlayer()->m_trade) return; TradeStatusInfo info; if (!GetPlayer()->IsAlive()) { info.Status = TRADE_STATUS_YOU_DEAD; SendTradeStatus(info); return; } if (GetPlayer()->HasUnitState(UNIT_STATE_STUNNED)) { info.Status = TRADE_STATUS_YOU_STUNNED; SendTradeStatus(info); return; } if (isLogingOut()) { info.Status = TRADE_STATUS_YOU_LOGOUT; SendTradeStatus(info); return; } if (GetPlayer()->IsInFlight()) { info.Status = TRADE_STATUS_TARGET_TO_FAR; SendTradeStatus(info); return; } if (GetPlayer()->getLevel() < sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_TRADE_REQ), sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ)); return; } Player* pOther = ObjectAccessor::FindPlayer(guid); if (!pOther) { info.Status = TRADE_STATUS_NO_TARGET; SendTradeStatus(info); return; } if (pOther == GetPlayer() || pOther->m_trade) { info.Status = TRADE_STATUS_BUSY; SendTradeStatus(info); return; } if (!pOther->IsAlive()) { info.Status = TRADE_STATUS_TARGET_DEAD; SendTradeStatus(info); return; } if (pOther->IsInFlight()) { info.Status = TRADE_STATUS_TARGET_TO_FAR; SendTradeStatus(info); return; } if (pOther->HasUnitState(UNIT_STATE_STUNNED)) { info.Status = TRADE_STATUS_TARGET_STUNNED; SendTradeStatus(info); return; } if (pOther->GetSession()->isLogingOut()) { info.Status = TRADE_STATUS_TARGET_LOGOUT; SendTradeStatus(info); return; } if (pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) { info.Status = TRADE_STATUS_IGNORE_YOU; SendTradeStatus(info); return; } if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_TRADE) && pOther->GetTeam() !=_player->GetTeam()) { info.Status = TRADE_STATUS_WRONG_FACTION; SendTradeStatus(info); return; } if (!pOther->IsWithinDistInMap(_player, TRADE_DISTANCE, false)) { info.Status = TRADE_STATUS_TARGET_TO_FAR; SendTradeStatus(info); return; } if (pOther->getLevel() < sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_TRADE_OTHER_REQ), sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ)); return; } // OK start trade _player->m_trade = new TradeData(_player, pOther); pOther->m_trade = new TradeData(pOther, _player); info.Status = TRADE_STATUS_BEGIN_TRADE; info.TraderGuid = _player->GetGUID(); pOther->GetSession()->SendTradeStatus(info); }
//called when player takes item attached in mail void WorldSession::HandleMailTakeItem(WorldPacket& recvData) { ObjectGuid mailbox; uint32 mailId; uint32 itemId; recvData >> mailId; recvData >> itemId; mailbox[6] = recvData.ReadBit(); mailbox[5] = recvData.ReadBit(); mailbox[2] = recvData.ReadBit(); mailbox[3] = recvData.ReadBit(); mailbox[0] = recvData.ReadBit(); mailbox[1] = recvData.ReadBit(); mailbox[4] = recvData.ReadBit(); mailbox[7] = recvData.ReadBit(); recvData.ReadByteSeq(mailbox[0]); recvData.ReadByteSeq(mailbox[1]); recvData.ReadByteSeq(mailbox[4]); recvData.ReadByteSeq(mailbox[2]); recvData.ReadByteSeq(mailbox[5]); recvData.ReadByteSeq(mailbox[6]); recvData.ReadByteSeq(mailbox[3]); recvData.ReadByteSeq(mailbox[7]); if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; Player* player = _player; Mail* m = player->GetMail(mailId); if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL)) { player->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_ERR_INTERNAL_ERROR); return; } // prevent cheating with skip client money check if (!player->HasEnoughMoney(uint64(m->COD))) { player->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_ERR_NOT_ENOUGH_MONEY); return; } Item* it = player->GetMItem(itemId); ItemPosCountVec dest; uint8 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, it, false); if (msg == EQUIP_ERR_OK) { SQLTransaction trans = CharacterDatabase.BeginTransaction(); m->RemoveItem(itemId); m->removedItems.push_back(itemId); if (m->COD > 0) //if there is COD, take COD money from player and send them to sender by mail { uint64 sender_guid = MAKE_NEW_GUID(m->sender, 0, HIGHGUID_PLAYER); Player* receiver = ObjectAccessor::FindPlayer(sender_guid); uint32 sender_accId = 0; if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { std::string sender_name; if (receiver) { sender_accId = receiver->GetSession()->GetAccountId(); sender_name = receiver->GetName(); } else { // can be calculated early sender_accId = sObjectMgr->GetPlayerAccountIdByGUID(sender_guid); if (!sObjectMgr->GetPlayerNameByGUID(sender_guid, sender_name)) sender_name = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN); } sLog->outCommand(GetAccountId(), "GM %s (Account: %u) receiver mail item: %s (Entry: %u Count: %u) and send COD money: " UI64FMTD " to player: %s (Account: %u)", GetPlayerName().c_str(), GetAccountId(), it->GetTemplate()->Name1.c_str(), it->GetEntry(), it->GetCount(), m->COD, sender_name.c_str(), sender_accId); } else if (!receiver) sender_accId = sObjectMgr->GetPlayerAccountIdByGUID(sender_guid); // check player existence if (receiver || sender_accId) { MailDraft(m->subject, "") .AddMoney(m->COD) .SendMailTo(trans, MailReceiver(receiver, m->sender), MailSender(MAIL_NORMAL, m->receiver), MAIL_CHECK_MASK_COD_PAYMENT); } player->ModifyMoney(-int32(m->COD)); } m->COD = 0; m->state = MAIL_STATE_CHANGED; player->m_mailsUpdated = true; player->RemoveMItem(it->GetGUIDLow()); uint32 count = it->GetCount(); // save counts before store and possible merge with deleting it->SetState(ITEM_UNCHANGED); // need to set this state, otherwise item cannot be removed later, if neccessary player->MoveItemToInventory(dest, it, true); player->SaveInventoryAndGoldToDB(trans); player->_SaveMail(trans); CharacterDatabase.CommitTransaction(trans); player->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_OK, 0, itemId, count); } else player->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_ERR_EQUIP_ERROR, msg); }
void WorldSession::HandleVoidSwapItem(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_VOID_SWAP_ITEM"); Player* player = GetPlayer(); uint32 newSlot; ObjectGuid npcGuid; ObjectGuid itemId; recvData >> newSlot; npcGuid[2] = recvData.ReadBit(); npcGuid[4] = recvData.ReadBit(); npcGuid[0] = recvData.ReadBit(); itemId[2] = recvData.ReadBit(); itemId[6] = recvData.ReadBit(); itemId[5] = recvData.ReadBit(); npcGuid[1] = recvData.ReadBit(); npcGuid[7] = recvData.ReadBit(); itemId[3] = recvData.ReadBit(); itemId[7] = recvData.ReadBit(); itemId[0] = recvData.ReadBit(); npcGuid[6] = recvData.ReadBit(); npcGuid[5] = recvData.ReadBit(); npcGuid[3] = recvData.ReadBit(); itemId[1] = recvData.ReadBit(); itemId[4] = recvData.ReadBit(); recvData.ReadByteSeq(npcGuid[1]); recvData.ReadByteSeq(itemId[3]); recvData.ReadByteSeq(itemId[2]); recvData.ReadByteSeq(itemId[4]); recvData.ReadByteSeq(npcGuid[3]); recvData.ReadByteSeq(npcGuid[0]); recvData.ReadByteSeq(itemId[6]); recvData.ReadByteSeq(itemId[1]); recvData.ReadByteSeq(npcGuid[5]); recvData.ReadByteSeq(itemId[5]); recvData.ReadByteSeq(npcGuid[6]); recvData.ReadByteSeq(itemId[0]); recvData.ReadByteSeq(npcGuid[2]); recvData.ReadByteSeq(npcGuid[7]); recvData.ReadByteSeq(npcGuid[4]); recvData.ReadByteSeq(itemId[7]); Creature* unit = player->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_VAULTKEEPER); if (!unit) { TC_LOG_DEBUG("network", "WORLD: HandleVoidSwapItem - Unit (GUID: %u) not found or player can't interact with it.", GUID_LOPART(npcGuid)); return; } if (!player->IsVoidStorageUnlocked()) { TC_LOG_DEBUG("network", "WORLD: HandleVoidSwapItem - Player (GUID: %u, name: %s) queried void storage without unlocking it.", player->GetGUIDLow(), player->GetName().c_str()); return; } uint8 oldSlot; if (!player->GetVoidStorageItem(itemId, oldSlot)) { TC_LOG_DEBUG("network", "WORLD: HandleVoidSwapItem - Player (GUID: %u, name: %s) requested swapping an invalid item (slot: %u, itemid: " UI64FMTD ").", player->GetGUIDLow(), player->GetName().c_str(), newSlot, uint64(itemId)); return; } bool usedSrcSlot = player->GetVoidStorageItem(oldSlot) != NULL; // should be always true bool usedDestSlot = player->GetVoidStorageItem(newSlot) != NULL; ObjectGuid itemIdDest; if (usedDestSlot) itemIdDest = player->GetVoidStorageItem(newSlot)->ItemId; if (!player->SwapVoidStorageItem(oldSlot, newSlot)) { SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INTERNAL_ERROR_1); return; } WorldPacket data(SMSG_VOID_ITEM_SWAP_RESPONSE, 1 + (usedSrcSlot + usedDestSlot) * (1 + 7 + 4)); data.WriteBit(!usedDestSlot); data.WriteBit(!usedSrcSlot); if (usedSrcSlot) { data.WriteBit(itemId[5]); data.WriteBit(itemId[2]); data.WriteBit(itemId[1]); data.WriteBit(itemId[4]); data.WriteBit(itemId[0]); data.WriteBit(itemId[6]); data.WriteBit(itemId[7]); data.WriteBit(itemId[3]); } data.WriteBit(!usedDestSlot); // unk if (usedDestSlot) { data.WriteBit(itemIdDest[7]); data.WriteBit(itemIdDest[3]); data.WriteBit(itemIdDest[4]); data.WriteBit(itemIdDest[0]); data.WriteBit(itemIdDest[5]); data.WriteBit(itemIdDest[1]); data.WriteBit(itemIdDest[2]); data.WriteBit(itemIdDest[6]); } data.WriteBit(!usedSrcSlot); // unk data.FlushBits(); if (usedDestSlot) { data.WriteByteSeq(itemIdDest[4]); data.WriteByteSeq(itemIdDest[6]); data.WriteByteSeq(itemIdDest[5]); data.WriteByteSeq(itemIdDest[2]); data.WriteByteSeq(itemIdDest[3]); data.WriteByteSeq(itemIdDest[1]); data.WriteByteSeq(itemIdDest[7]); data.WriteByteSeq(itemIdDest[0]); } if (usedSrcSlot) { data.WriteByteSeq(itemId[6]); data.WriteByteSeq(itemId[3]); data.WriteByteSeq(itemId[5]); data.WriteByteSeq(itemId[0]); data.WriteByteSeq(itemId[1]); data.WriteByteSeq(itemId[2]); data.WriteByteSeq(itemId[4]); data.WriteByteSeq(itemId[7]); } if (usedDestSlot) data << uint32(oldSlot); if (usedSrcSlot) data << uint32(newSlot); SendPacket(&data); }
//called when player lists his received mails void WorldSession::HandleGetMailList(WorldPacket& recvData) { ObjectGuid mailbox; mailbox[6] = recvData.ReadBit(); mailbox[3] = recvData.ReadBit(); mailbox[7] = recvData.ReadBit(); mailbox[5] = recvData.ReadBit(); mailbox[4] = recvData.ReadBit(); mailbox[1] = recvData.ReadBit(); mailbox[2] = recvData.ReadBit(); mailbox[0] = recvData.ReadBit(); recvData.ReadByteSeq(mailbox[7]); recvData.ReadByteSeq(mailbox[1]); recvData.ReadByteSeq(mailbox[6]); recvData.ReadByteSeq(mailbox[5]); recvData.ReadByteSeq(mailbox[4]); recvData.ReadByteSeq(mailbox[2]); recvData.ReadByteSeq(mailbox[3]); recvData.ReadByteSeq(mailbox[0]); if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; Player* player = _player; //load players mails, and mailed items if (!player->m_mailsLoaded) player->_LoadMail(); // client can't work with packets > max int16 value const uint32 maxPacketSize = 32767; uint32 mailCount = 0; uint32 realCount = 0; // true mail count (includes any skipped mail) time_t cur_time = time(NULL); ByteBuffer mailData; WorldPacket data(SMSG_MAIL_LIST_RESULT, 200); // guess size data << uint32(0); // placeholder size_t mailCountPos = data.bitwpos(); data.WriteBits(0, 18); // placeholder for (PlayerMails::iterator itr = player->GetMailBegin(); itr != player->GetMailEnd(); ++itr) { Mail* mail = *itr; // Only first 50 mails are displayed if (mailCount >= 50) { realCount += 1; continue; } // skip deleted or not delivered (deliver delay not expired) mails if (mail->state == MAIL_STATE_DELETED || cur_time < mail->deliver_time) continue; // skip mail with more than MAX_MAIL_ITEMS items (should not occur) uint8 itemCount = mail->items.size(); if (itemCount > MAX_MAIL_ITEMS) { realCount += 1; continue; } // skip mail if the packet has become too large (should not occur) size_t nextMailSize = 6 + 1 + 8 + itemCount * (4 + 4 + 4 + 4 + 4 + MAX_INSPECTED_ENCHANTMENT_SLOT * (4 + 4 + 4) + 4 + 4 + 4 + 4 + 1 + 4) + mail->body.size() + mail->subject.size() + 4 + 4 + 8 + 4 + 8 + 4 + 4 + 1 + 4; if (data.wpos() + nextMailSize > maxPacketSize) { realCount += 1; continue; } data.WriteBit(mail->messageType != MAIL_NORMAL ? 1 : 0); data.WriteBits(mail->subject.size(), 8); data.WriteBits(mail->body.size(), 13); data.WriteBit(0); data.WriteBit(0); size_t itemCountPos = data.bitwpos(); data.WriteBits(0, 17); // placeholder data.WriteBit(1); // has guid ObjectGuid guid = mail->messageType == MAIL_NORMAL ? MAKE_NEW_GUID(mail->sender, 0, HIGHGUID_PLAYER) : 0; data.WriteBit(guid[2]); data.WriteBit(guid[6]); data.WriteBit(guid[7]); data.WriteBit(guid[0]); data.WriteBit(guid[5]); data.WriteBit(guid[3]); data.WriteBit(guid[1]); data.WriteBit(guid[4]); uint8 trueItemCount = 0; for (uint8 i = 0; i < itemCount; i++) { Item* item = player->GetMItem(mail->items[i].item_guid); if (!item) continue; data.WriteBit(0); mailData << uint32(item->GetGUIDLow()); mailData << uint32(4); // unknown mailData << uint32(item->GetSpellCharges()); mailData << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY)); mailData << uint32(0); // unknown for (uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; j++) { mailData << uint32(item->GetEnchantmentCharges((EnchantmentSlot)j)); mailData << uint32(item->GetEnchantmentDuration((EnchantmentSlot)j)); mailData << uint32(item->GetEnchantmentId((EnchantmentSlot)j)); } mailData << uint32(item->GetItemSuffixFactor()); mailData << int32(item->GetItemRandomPropertyId()); mailData << uint32(item->GetUInt32Value(ITEM_FIELD_MAX_DURABILITY)); mailData << uint32(item->GetCount()); mailData << uint8(i); mailData << uint32(item->GetEntry()); trueItemCount++; } data.PutBits(itemCountPos, trueItemCount, 17); mailData.WriteString(mail->body); mailData << uint32(mail->messageID); mailData.WriteByteSeq(guid[4]); mailData.WriteByteSeq(guid[0]); mailData.WriteByteSeq(guid[5]); mailData.WriteByteSeq(guid[3]); mailData.WriteByteSeq(guid[1]); mailData.WriteByteSeq(guid[7]); mailData.WriteByteSeq(guid[2]); mailData.WriteByteSeq(guid[6]); mailData << uint32(mail->mailTemplateId); mailData << uint64(mail->COD); mailData.WriteString(mail->subject); mailData << uint32(mail->stationery); mailData << float(float(mail->expire_time - time(NULL)) / DAY); mailData << uint64(mail->money); mailData << uint32(mail->checked); if (mail->messageType != MAIL_NORMAL) mailData << uint32(mail->sender); mailData << uint8(mail->messageType); mailData << uint32(0); // unknown realCount++; mailCount++; } data.FlushBits(); data.append(mailData); data.put<uint32>(0, realCount); data.PutBits(mailCountPos, mailCount, 18); SendPacket(&data); // recalculate m_nextMailDelivereTime and unReadMails _player->UpdateNextMailTimeAndUnreads(); }
void WorldSession::HandleRepairItemOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: CMSG_REPAIR_ITEM"); ObjectGuid npcGuid, itemGuid; bool guildBank; // new in 2.3.2, bool that means from guild bank money itemGuid[2] = recvData.ReadBit(); itemGuid[5] = recvData.ReadBit(); npcGuid[3] = recvData.ReadBit(); guildBank = recvData.ReadBit(); npcGuid[7] = recvData.ReadBit(); itemGuid[4] = recvData.ReadBit(); npcGuid[2] = recvData.ReadBit(); itemGuid[0] = recvData.ReadBit(); itemGuid[3] = recvData.ReadBit(); npcGuid[6] = recvData.ReadBit(); npcGuid[1] = recvData.ReadBit(); npcGuid[4] = recvData.ReadBit(); itemGuid[6] = recvData.ReadBit(); npcGuid[5] = recvData.ReadBit(); npcGuid[0] = recvData.ReadBit(); itemGuid[7] = recvData.ReadBit(); itemGuid[1] = recvData.ReadBit(); recvData.ReadByteSeq(itemGuid[2]); recvData.ReadByteSeq(npcGuid[1]); recvData.ReadByteSeq(itemGuid[1]); recvData.ReadByteSeq(npcGuid[4]); recvData.ReadByteSeq(npcGuid[7]); recvData.ReadByteSeq(npcGuid[3]); recvData.ReadByteSeq(npcGuid[2]); recvData.ReadByteSeq(itemGuid[7]); recvData.ReadByteSeq(npcGuid[5]); recvData.ReadByteSeq(npcGuid[0]); recvData.ReadByteSeq(itemGuid[5]); recvData.ReadByteSeq(itemGuid[3]); recvData.ReadByteSeq(itemGuid[4]); recvData.ReadByteSeq(itemGuid[6]); recvData.ReadByteSeq(npcGuid[6]); recvData.ReadByteSeq(itemGuid[0]); Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_REPAIR); if (!unit) { TC_LOG_DEBUG("network", "WORLD: HandleRepairItemOpcode - Unit (GUID: %u) not found or you can not interact with him.", uint32(GUID_LOPART(npcGuid))); return; } // remove fake death if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); // reputation discount float discountMod = _player->GetReputationPriceDiscount(unit); if (itemGuid) { TC_LOG_DEBUG("network", "ITEM: Repair item, itemGUID = %u, npcGUID = %u", GUID_LOPART(itemGuid), GUID_LOPART(npcGuid)); Item* item = _player->GetItemByGuid(itemGuid); if (item) _player->DurabilityRepair(item->GetPos(), true, discountMod, guildBank); } else { TC_LOG_DEBUG("network", "ITEM: Repair all items, npcGUID = %u", GUID_LOPART(npcGuid)); _player->DurabilityRepairAll(true, discountMod, guildBank); } }
//used when player copies mail body to his inventory void WorldSession::HandleMailCreateTextItem(WorldPacket& recvData) { ObjectGuid mailbox; uint32 mailId; recvData >> mailId; mailbox[4] = recvData.ReadBit(); mailbox[1] = recvData.ReadBit(); mailbox[6] = recvData.ReadBit(); mailbox[2] = recvData.ReadBit(); mailbox[5] = recvData.ReadBit(); mailbox[3] = recvData.ReadBit(); mailbox[0] = recvData.ReadBit(); mailbox[7] = recvData.ReadBit(); recvData.ReadByteSeq(mailbox[6]); recvData.ReadByteSeq(mailbox[5]); recvData.ReadByteSeq(mailbox[4]); recvData.ReadByteSeq(mailbox[3]); recvData.ReadByteSeq(mailbox[0]); recvData.ReadByteSeq(mailbox[7]); recvData.ReadByteSeq(mailbox[2]); recvData.ReadByteSeq(mailbox[1]); if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; Player* player = _player; Mail* m = player->GetMail(mailId); if (!m || (m->body.empty() && !m->mailTemplateId) || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL)) { player->SendMailResult(mailId, MAIL_MADE_PERMANENT, MAIL_ERR_INTERNAL_ERROR); return; } Item* bodyItem = new Item; // This is not bag and then can be used new Item. if (!bodyItem->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_ITEM), MAIL_BODY_ITEM_TEMPLATE, player)) { delete bodyItem; return; } // in mail template case we need create new item text if (m->mailTemplateId) { MailTemplateEntry const* mailTemplateEntry = sMailTemplateStore.LookupEntry(m->mailTemplateId); if (!mailTemplateEntry) { player->SendMailResult(mailId, MAIL_MADE_PERMANENT, MAIL_ERR_INTERNAL_ERROR); return; } bodyItem->SetText(mailTemplateEntry->content); } else bodyItem->SetText(m->body); bodyItem->SetUInt32Value(ITEM_FIELD_CREATOR, m->sender); bodyItem->SetFlag(ITEM_FIELD_DYNAMIC_FLAGS, ITEM_FLAG_MAIL_TEXT_MASK); TC_LOG_INFO("network", "HandleMailCreateTextItem mailid=%u", mailId); ItemPosCountVec dest; uint8 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, bodyItem, false); if (msg == EQUIP_ERR_OK) { m->checked = m->checked | MAIL_CHECK_MASK_COPIED; m->state = MAIL_STATE_CHANGED; player->m_mailsUpdated = true; player->StoreItem(dest, bodyItem, true); player->SendMailResult(mailId, MAIL_MADE_PERMANENT, MAIL_OK); } else { player->SendMailResult(mailId, MAIL_MADE_PERMANENT, MAIL_ERR_EQUIP_ERROR, msg); delete bodyItem; } }
void WorldSession::HandleGossipHelloOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_GOSSIP_HELLO"); ObjectGuid guid; guid[2] = recvData.ReadBit(); guid[4] = recvData.ReadBit(); guid[0] = recvData.ReadBit(); guid[3] = recvData.ReadBit(); guid[6] = recvData.ReadBit(); guid[7] = recvData.ReadBit(); guid[5] = recvData.ReadBit(); guid[1] = recvData.ReadBit(); recvData.ReadByteSeq(guid[4]); recvData.ReadByteSeq(guid[7]); recvData.ReadByteSeq(guid[1]); recvData.ReadByteSeq(guid[0]); recvData.ReadByteSeq(guid[5]); recvData.ReadByteSeq(guid[3]); recvData.ReadByteSeq(guid[6]); recvData.ReadByteSeq(guid[2]); Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE); if (!unit) { TC_LOG_DEBUG("network", "WORLD: HandleGossipHelloOpcode - Unit (GUID: %u) not found or you can not interact with him.", uint32(GUID_LOPART(guid))); return; } // set faction visible if needed if (FactionTemplateEntry const* factionTemplateEntry = sFactionTemplateStore.LookupEntry(unit->getFaction())) _player->GetReputationMgr().SetVisible(factionTemplateEntry); GetPlayer()->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK); // remove fake death //if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) // GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); if (unit->IsArmorer() || unit->IsCivilian() || unit->IsQuestGiver() || unit->IsServiceProvider() || unit->IsGuard()) unit->StopMoving(); // If spiritguide, no need for gossip menu, just put player into resurrect queue if (unit->IsSpiritGuide()) { Battleground* bg = _player->GetBattleground(); if (bg) { bg->AddPlayerToResurrectQueue(unit->GetGUID(), _player->GetGUID()); sBattlegroundMgr->SendAreaSpiritHealerQueryOpcode(_player, bg, unit->GetGUID()); return; } } if (!sScriptMgr->OnGossipHello(_player, unit)) { // _player->TalkedToCreature(unit->GetEntry(), unit->GetGUID()); _player->PrepareGossipMenu(unit, unit->GetCreatureTemplate()->GossipMenuId, true); _player->SendPreparedGossip(unit); } unit->AI()->sGossipHello(_player); }
void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode CMSG_PETITION_BUY"); ObjectGuid npcGuid; uint32 nameLen = 0; std::string name; npcGuid[6] = recvData.ReadBit(); npcGuid[1] = recvData.ReadBit(); npcGuid[4] = recvData.ReadBit(); npcGuid[2] = recvData.ReadBit(); npcGuid[5] = recvData.ReadBit(); npcGuid[7] = recvData.ReadBit(); npcGuid[3] = recvData.ReadBit(); nameLen = recvData.ReadBits(7); npcGuid[0] = recvData.ReadBit(); recvData.FlushBits(); recvData.ReadByteSeq(npcGuid[0]); recvData.ReadByteSeq(npcGuid[2]); recvData.ReadByteSeq(npcGuid[4]); recvData.ReadByteSeq(npcGuid[6]); recvData.ReadByteSeq(npcGuid[7]); recvData.ReadByteSeq(npcGuid[5]); recvData.ReadByteSeq(npcGuid[3]); recvData.ReadByteSeq(npcGuid[1]); name = recvData.ReadString(nameLen); sLog->outDebug(LOG_FILTER_NETWORKIO, "Petitioner with GUID %u tried sell petition: name %s", GUID_LOPART(npcGuid), name.c_str()); // prevent cheating Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_PETITIONER); if (!creature) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandlePetitionBuyOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(npcGuid)); return; } // remove fake death if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); uint32 charterid = 0; uint32 cost = 0; uint32 type = 0; if (creature->isTabardDesigner()) { // if tabard designer, then trying to buy a guild charter. // do not let if already in guild. if (_player->GetGuildId()) return; charterid = GUILD_CHARTER; cost = GUILD_CHARTER_COST; type = GUILD_CHARTER_TYPE; } if (type == GUILD_CHARTER_TYPE) { if (sGuildMgr->GetGuildByName(name)) { Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_EXISTS_S, name); return; } if (sObjectMgr->IsReservedName(name) || !ObjectMgr::IsValidCharterName(name)) { Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_INVALID, name); return; } } ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(charterid); if (!pProto) { _player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, charterid, 0); return; } if (!_player->HasEnoughMoney(uint64(cost))) { //player hasn't got enough money _player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, creature, charterid, 0); return; } ItemPosCountVec dest; InventoryResult msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, charterid, pProto->BuyCount); if (msg != EQUIP_ERR_OK) { _player->SendEquipError(msg, NULL, NULL, charterid); return; } _player->ModifyMoney(-(int32)cost); Item* charter = _player->StoreNewItem(dest, charterid, true); if (!charter) return; charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1, charter->GetGUIDLow()); // ITEM_FIELD_ENCHANTMENT_1_1 is guild/arenateam id // ITEM_FIELD_ENCHANTMENT_1_1+1 is current signatures count (showed on item) charter->SetState(ITEM_CHANGED, _player); _player->SendNewItem(charter, 1, true, false); // a petition is invalid, if both the owner and the type matches // we checked above, if this player is in an arenateam, so this must be // datacorruption PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_BY_OWNER); stmt->setUInt32(0, _player->GetGUIDLow()); stmt->setUInt8(1, type); PreparedQueryResult result = CharacterDatabase.Query(stmt); std::ostringstream ssInvalidPetitionGUIDs; if (result) { do { Field* fields = result->Fetch(); ssInvalidPetitionGUIDs << '\'' << fields[0].GetUInt32() << "', "; } while (result->NextRow()); } // delete petitions with the same guid as this one ssInvalidPetitionGUIDs << '\'' << charter->GetGUIDLow() << '\''; sLog->outDebug(LOG_FILTER_NETWORKIO, "Invalid petition GUIDs: %s", ssInvalidPetitionGUIDs.str().c_str()); CharacterDatabase.EscapeString(name); SQLTransaction trans = CharacterDatabase.BeginTransaction(); trans->PAppend("DELETE FROM petition WHERE petitionguid IN (%s)", ssInvalidPetitionGUIDs.str().c_str()); trans->PAppend("DELETE FROM petition_sign WHERE petitionguid IN (%s)", ssInvalidPetitionGUIDs.str().c_str()); stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PETITION); stmt->setUInt32(0, _player->GetGUIDLow()); stmt->setUInt32(1, charter->GetGUIDLow()); stmt->setString(2, name); stmt->setUInt8(3, uint8(type)); trans->Append(stmt); CharacterDatabase.CommitTransaction(trans); }