void WorldSession::HandleGameObjectQueryOpcode(WorldPacket & recv_data) { uint64 guid; recv_data >> guid; uint32 packetGuid, entryID; uint8 unk1, unk2; recv_data >> unk1; recv_data >> unk2; recv_data >> packetGuid; recv_data >> entryID; entryID = entryID / 256; guid = packetGuid / 65536; GameObjectTemplate const* info = sObjectMgr->GetGameObjectTemplate(entryID); if (info) { std::string Name; std::string IconName; std::string CastBarCaption; Name = info->name; IconName = info->IconName; CastBarCaption = info->castBarCaption; int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { if (GameObjectLocale const *gl = sObjectMgr->GetGameObjectLocale(entryID)) { ObjectMgr::GetLocaleString(gl->Name, loc_idx, Name); ObjectMgr::GetLocaleString(gl->CastBarCaption, loc_idx, CastBarCaption); } } sLog->outDetail("WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name.c_str(), entryID); WorldPacket data (SMSG_GAMEOBJECT_QUERY_RESPONSE, 150); data << uint32(entryID); data << uint32(info->type); data << uint32(info->displayId); data << Name; data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4 data << IconName; // 2.0.3, string. Icon name to use instead of default icon for go's (ex: "Attack" makes sword) data << CastBarCaption; // 2.0.3, string. Text will appear in Cast Bar when using GO (ex: "Collecting") data << info->unk1; // 2.0.3, string data.append(info->raw.data, MAX_GAMEOBJECT_DATA); data << float(info->size); // go size for (uint32 i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i) data << uint32(info->questItems[i]); // itemId[6], quest drop data << uint32(info->unk2); // Found in 420, date from gameobjectcache.wdb SendPacket(&data); sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE"); } else { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_GAMEOBJECT_QUERY - Missing gameobject info for (GUID: %u, ENTRY: %u)", GUID_LOPART(guid), entryID); WorldPacket data (SMSG_GAMEOBJECT_QUERY_RESPONSE, 4); data << uint32(entryID | 0x80000000); SendPacket(&data); sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE"); } }
/// Only _static_ data send in this packet !!! void WorldSession::HandleCreatureQueryOpcode(WorldPacket & recv_data) { uint32 entry; recv_data >> entry; uint64 guid; recv_data >> guid; CreatureInfo const *ci = objmgr.GetCreatureTemplate(entry); if (ci) { std::string Name, SubName; Name = ci->Name; SubName = ci->SubName; int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { CreatureLocale const *cl = objmgr.GetCreatureLocale(entry); if (cl) { if (cl->Name.size() > size_t(loc_idx) && !cl->Name[loc_idx].empty()) Name = cl->Name[loc_idx]; if (cl->SubName.size() > size_t(loc_idx) && !cl->SubName[loc_idx].empty()) SubName = cl->SubName[loc_idx]; } } sLog.outDetail("WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name, entry); // guess size WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 100); data << uint32(entry); // creature entry data << Name; data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty data << SubName; data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0 data << uint32(ci->type_flags); // flags data << uint32(ci->type); // CreatureType.dbc data << uint32(ci->family); // CreatureFamily.dbc data << uint32(ci->rank); // Creature Rank (elite, boss, etc) data << uint32(ci->KillCredit[0]); // new in 3.1, kill credit data << uint32(ci->KillCredit[1]); // new in 3.1, kill credit data << uint32(ci->Modelid1); // Modelid1 data << uint32(ci->Modelid2); // Modelid2 data << uint32(ci->Modelid3); // Modelid3 data << uint32(ci->Modelid4); // Modelid4 data << float(ci->ModHealth); // dmg/hp modifier data << float(ci->ModMana); // dmg/mana modifier data << uint8(ci->RacialLeader); for (uint32 i = 0; i < 6; ++i) data << uint32(ci->questItems[i]); // itemId[6], quest drop data << uint32(ci->movementId); // CreatureMovementInfo.dbc SendPacket(&data); sLog.outDebug("WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE"); } else { sLog.outDebug("WORLD: CMSG_CREATURE_QUERY - NO CREATURE INFO! (GUID: %u, ENTRY: %u)", GUID_LOPART(guid), entry); WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 4); data << uint32(entry | 0x80000000); SendPacket(&data); sLog.outDebug("WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE"); } }
/// Only _static_ data send in this packet !!! void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data ) { uint32 entry; recv_data >> entry; ObjectGuid guid; recv_data >> guid; CreatureInfo const *ci = ObjectMgr::GetCreatureTemplate(entry); if (ci) { std::string Name, SubName; Name = ci->Name; SubName = ci->SubName; int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { CreatureLocale const *cl = sObjectMgr.GetCreatureLocale(entry); if (cl) { if (cl->Name.size() > size_t(loc_idx) && !cl->Name[loc_idx].empty()) Name = cl->Name[loc_idx]; if (cl->SubName.size() > size_t(loc_idx) && !cl->SubName[loc_idx].empty()) SubName = cl->SubName[loc_idx]; } } DETAIL_LOG("WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name, entry); // guess size WorldPacket data( SMSG_CREATURE_QUERY_RESPONSE, 100 ); data << uint32(entry); // creature entry data << Name; data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty data << SubName; data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0 data << uint32(ci->type_flags); // flags data << uint32(ci->type); // CreatureType.dbc data << uint32(ci->family); // CreatureFamily.dbc data << uint32(ci->rank); // Creature Rank (elite, boss, etc) data << uint32(ci->KillCredit[0]); // new in 3.1, kill credit data << uint32(ci->KillCredit[1]); // new in 3.1, kill credit for(int i = 0; i < MAX_CREATURE_MODEL; ++i) data << uint32(ci->ModelId[i]); data << float(ci->unk16); // health modifier data << float(ci->unk17); // power modifier data << uint8(ci->RacialLeader); for(uint32 i = 0; i < 6; ++i) data << uint32(ci->questItems[i]); // itemId[6], quest drop data << uint32(ci->movementId); // CreatureMovementInfo.dbc SendPacket( &data ); DEBUG_LOG( "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE" ); } else { DEBUG_LOG("WORLD: CMSG_CREATURE_QUERY - Guid: %s Entry: %u NO CREATURE INFO!", guid.GetString().c_str(), entry); WorldPacket data( SMSG_CREATURE_QUERY_RESPONSE, 4 ); data << uint32(entry | 0x80000000); SendPacket( &data ); DEBUG_LOG( "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE" ); } }
// Only _static_ data send in this packet !!! void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data ) { //sLog.outDebug("WORLD: CMSG_ITEM_QUERY_SINGLE"); uint32 item; recv_data >> item; sLog.outDetail("STORAGE: Item Query = %u", item); ItemPrototype const *pProto = ObjectMgr::GetItemPrototype( item ); if( pProto ) { std::string Name = pProto->Name1; std::string Description = pProto->Description; int loc_idx = GetSessionDbLocaleIndex(); if ( loc_idx >= 0 ) { ItemLocale const *il = sObjectMgr.GetItemLocale(pProto->ItemId); if (il) { if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty()) Name = il->Name[loc_idx]; if (il->Description.size() > size_t(loc_idx) && !il->Description[loc_idx].empty()) Description = il->Description[loc_idx]; } } // guess size WorldPacket data( SMSG_ITEM_QUERY_SINGLE_RESPONSE, 600); data << pProto->ItemId; data << pProto->Class; data << pProto->SubClass; data << int32(pProto->Unk0); // new 2.0.3, not exist in wdb cache? data << Name; data << uint8(0x00); //pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name... data << uint8(0x00); //pProto->Name3; // blizz not send name there, just uint8(0x00); data << uint8(0x00); //pProto->Name4; // blizz not send name there, just uint8(0x00); data << pProto->DisplayInfoID; data << pProto->Quality; data << pProto->Flags; data << pProto->Faction; // 3.2 faction? data << pProto->BuyPrice; data << pProto->SellPrice; data << pProto->InventoryType; data << pProto->AllowableClass; data << pProto->AllowableRace; data << pProto->ItemLevel; data << pProto->RequiredLevel; data << pProto->RequiredSkill; data << pProto->RequiredSkillRank; data << pProto->RequiredSpell; data << pProto->RequiredHonorRank; data << pProto->RequiredCityRank; data << pProto->RequiredReputationFaction; data << pProto->RequiredReputationRank; data << int32(pProto->MaxCount); data << int32(pProto->Stackable); data << pProto->ContainerSlots; data << pProto->StatsCount; // item stats count for(uint32 i = 0; i < pProto->StatsCount; ++i) { data << pProto->ItemStat[i].ItemStatType; data << pProto->ItemStat[i].ItemStatValue; } data << pProto->ScalingStatDistribution; // scaling stats distribution data << pProto->ScalingStatValue; // some kind of flags used to determine stat values column for(int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) { data << pProto->Damage[i].DamageMin; data << pProto->Damage[i].DamageMax; data << pProto->Damage[i].DamageType; } // resistances (7) data << pProto->Armor; data << pProto->HolyRes; data << pProto->FireRes; data << pProto->NatureRes; data << pProto->FrostRes; data << pProto->ShadowRes; data << pProto->ArcaneRes; data << pProto->Delay; data << pProto->AmmoType; data << pProto->RangedModRange; for(int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s) { // send DBC data for cooldowns in same way as it used in Spell::SendSpellCooldown // use `item_template` or if not set then only use spell cooldowns SpellEntry const* spell = sSpellStore.LookupEntry(pProto->Spells[s].SpellId); if(spell) { bool db_data = pProto->Spells[s].SpellCooldown >= 0 || pProto->Spells[s].SpellCategoryCooldown >= 0; data << pProto->Spells[s].SpellId; data << pProto->Spells[s].SpellTrigger; data << uint32(-abs(pProto->Spells[s].SpellCharges)); if(db_data) { data << uint32(pProto->Spells[s].SpellCooldown); data << uint32(pProto->Spells[s].SpellCategory); data << uint32(pProto->Spells[s].SpellCategoryCooldown); } else { data << uint32(spell->RecoveryTime); data << uint32(spell->Category); data << uint32(spell->CategoryRecoveryTime); } } else { data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(-1); data << uint32(0); data << uint32(-1); } } data << pProto->Bonding; data << Description; data << pProto->PageText; data << pProto->LanguageID; data << pProto->PageMaterial; data << pProto->StartQuest; data << pProto->LockID; data << int32(pProto->Material); data << pProto->Sheath; data << pProto->RandomProperty; data << pProto->RandomSuffix; data << pProto->Block; data << pProto->ItemSet; data << pProto->MaxDurability; data << pProto->Area; data << pProto->Map; // Added in 1.12.x & 2.0.1 client branch data << pProto->BagFamily; data << pProto->TotemCategory; for(int s = 0; s < MAX_ITEM_PROTO_SOCKETS; ++s) { data << pProto->Socket[s].Color; data << pProto->Socket[s].Content; } data << pProto->socketBonus; data << pProto->GemProperties; data << pProto->RequiredDisenchantSkill; data << pProto->ArmorDamageModifier; data << pProto->Duration; // added in 2.4.2.8209, duration (seconds) data << pProto->ItemLimitCategory; // WotLK, ItemLimitCategory data << pProto->HolidayId; // Holiday.dbc? SendPacket( &data ); } else { sLog.outDebug( "WORLD: CMSG_ITEM_QUERY_SINGLE - NO item INFO! (ENTRY: %u)", item ); WorldPacket data( SMSG_ITEM_QUERY_SINGLE_RESPONSE, 4); data << uint32(item | 0x80000000); SendPacket( &data ); } }
const char * WorldSession::GetMangosString( int32 entry ) const { return objmgr.GetMangosString(entry,GetSessionDbLocaleIndex()); }
void WorldSession::HandleNpcTextQueryOpcode(WorldPacket& recvData) { uint32 textID; uint64 guid; recvData >> textID; sLog->outDetail("WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID); recvData >> guid; GetPlayer()->SetSelection(guid); GossipText const* pGossip = sObjectMgr->GetGossipText(textID); WorldPacket data(SMSG_NPC_TEXT_UPDATE, 100); // guess size data << textID; if (!pGossip) { for (uint32 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) { data << float(0); data << "Greetings $N"; data << "Greetings $N"; data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); } } else { std::string Text_0[MAX_LOCALES], Text_1[MAX_LOCALES]; for (int i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) { Text_0[i] = pGossip->Options[i].Text_0; Text_1[i] = pGossip->Options[i].Text_1; } int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { if (NpcTextLocale const* nl = sObjectMgr->GetNpcTextLocale(textID)) { for (int i = 0; i < MAX_LOCALES; ++i) { ObjectMgr::GetLocaleString(nl->Text_0[i], loc_idx, Text_0[i]); ObjectMgr::GetLocaleString(nl->Text_1[i], loc_idx, Text_1[i]); } } } for (int i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) { data << pGossip->Options[i].Probability; if (Text_0[i].empty()) data << Text_1[i]; else data << Text_0[i]; if (Text_1[i].empty()) data << Text_0[i]; else data << Text_1[i]; data << pGossip->Options[i].Language; for (int j = 0; j < MAX_GOSSIP_TEXT_EMOTES; ++j) { data << pGossip->Options[i].Emotes[j]._Delay; data << pGossip->Options[i].Emotes[j]._Emote; } } } SendPacket(&data); sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_NPC_TEXT_UPDATE"); }
/// Only _static_ data is sent in this packet !!! void WorldSession::HandleCreatureQueryOpcode(WorldPacket& recvData) { uint32 entry; recvData >> entry; ObjectGuid guid; recvData >> guid; CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(entry); if (ci) { std::string Name, Title; Name = ci->Name; Title = ci->Title; int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { if (CreatureLocale const* cl = sObjectMgr->GetCreatureLocale(entry)) { ObjectMgr::GetLocaleString(cl->Name, loc_idx, Name); ObjectMgr::GetLocaleString(cl->Title, loc_idx, Title); } } TC_LOG_DEBUG("network", "WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name.c_str(), entry); // guess size WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 100); data << uint32(entry); // creature entry data << Name; data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty data << Title; data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0 data << uint32(ci->type_flags); // flags data << uint32(ci->type); // CreatureType.dbc data << uint32(ci->family); // CreatureFamily.dbc data << uint32(ci->rank); // Creature Rank (elite, boss, etc) data << uint32(ci->KillCredit[0]); // new in 3.1, kill credit data << uint32(ci->KillCredit[1]); // new in 3.1, kill credit data << uint32(ci->Modelid1); // Modelid1 data << uint32(ci->Modelid2); // Modelid2 data << uint32(ci->Modelid3); // Modelid3 data << uint32(ci->Modelid4); // Modelid4 data << float(ci->ModHealth); // dmg/hp modifier data << float(ci->ModMana); // dmg/mana modifier data << uint8(ci->RacialLeader); CreatureQuestItemList const* items = sObjectMgr->GetCreatureQuestItemList(entry); if (items) for (size_t i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) data << (i < items->size() ? uint32((*items)[i]) : uint32(0)); else for (size_t i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) data << uint32(0); data << uint32(ci->movementId); // CreatureMovementInfo.dbc SendPacket(&data); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE"); } else { TC_LOG_DEBUG("network", "WORLD: CMSG_CREATURE_QUERY - NO CREATURE INFO! (%s, ENTRY: %u)", guid.ToString().c_str(), entry); WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 4); data << uint32(entry | 0x80000000); SendPacket(&data); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE"); } }
void WorldSession::HandleNpcTextQueryOpcode( WorldPacket & recv_data ) { uint32 textID; uint64 guid; recv_data >> textID; DETAIL_LOG("WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID); recv_data >> guid; _player->SetTargetGUID(guid); GossipText const* pGossip = sObjectMgr.GetGossipText(textID); WorldPacket data( SMSG_NPC_TEXT_UPDATE, 100 ); // guess size data << textID; if (!pGossip) { // multi-language support std::string Text_0[8],Text_1[8]; int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { NpcTextLocale const *nl = sObjectMgr.GetNpcTextLocale(68); // standard text if (nl) { for (int i = 0; i < 8; ++i) { if (nl->Text_0[i].size() > size_t(loc_idx) && !nl->Text_0[i][loc_idx].empty()) Text_0[i]=nl->Text_0[i][loc_idx]; if (nl->Text_1[i].size() > size_t(loc_idx) && !nl->Text_1[i][loc_idx].empty()) Text_1[i]=nl->Text_1[i][loc_idx]; } } } else // no locales { for (int i = 0; i < 8; ++i) { Text_0[i] = "Greetings, $N"; Text_1[i] = "Greetings, $N"; } } for (int i = 0; i < 8; ++i) { data << float(0); if ( Text_0[i].empty() ) data << Text_1[i]; else data << Text_0[i]; if ( Text_1[i].empty() ) data << Text_0[i]; else data << Text_1[i]; data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); } } else { std::string Text_0[8], Text_1[8]; for (int i = 0; i < 8; ++i) { Text_0[i]=pGossip->Options[i].Text_0; Text_1[i]=pGossip->Options[i].Text_1; } int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { NpcTextLocale const *nl = sObjectMgr.GetNpcTextLocale(textID); if (nl) { for (int i = 0; i < 8; ++i) { if (nl->Text_0[i].size() > size_t(loc_idx) && !nl->Text_0[i][loc_idx].empty()) Text_0[i]=nl->Text_0[i][loc_idx]; if (nl->Text_1[i].size() > size_t(loc_idx) && !nl->Text_1[i][loc_idx].empty()) Text_1[i]=nl->Text_1[i][loc_idx]; } } } for (int i = 0; i < 8; ++i) { data << pGossip->Options[i].Probability; if ( Text_0[i].empty() ) data << Text_1[i]; else data << Text_0[i]; if ( Text_1[i].empty() ) data << Text_0[i]; else data << Text_1[i]; data << pGossip->Options[i].Language; for(int j = 0; j < 3; ++j) { data << pGossip->Options[i].Emotes[j]._Delay; data << pGossip->Options[i].Emotes[j]._Emote; } } } SendPacket( &data ); DEBUG_LOG( "WORLD: Sent SMSG_NPC_TEXT_UPDATE" ); }
/// Only _static_ data is sent in this packet !!! void WorldSession::HandleCreatureQueryOpcode(WorldPacket & recv_data) { uint32 entry; recv_data >> entry; uint64 guid; recv_data >> guid; CreatureTemplate const *ci = sObjectMgr->GetCreatureTemplate(entry); if (ci) { std::string Name, SubName; Name = ci->Name; SubName = ci->SubName; int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { if (CreatureLocale const *cl = sObjectMgr->GetCreatureLocale(entry)) { sObjectMgr->GetLocaleString(cl->Name, loc_idx, Name); sObjectMgr->GetLocaleString(cl->SubName, loc_idx, SubName); } } sLog->outDetail("WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name.c_str(), entry); // guess size WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 100); data << uint32(entry); // creature entry data << Name; data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty data << uint8(0) << uint8(0) << uint8(0) << uint8(0); // Unk 1-4 data << SubName; data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0 data << uint32(ci->type_flags); // flags data << uint32(0); // Unknown, 4.2.0 data << uint32(ci->type); // CreatureType.dbc data << uint32(ci->family); // CreatureFamily.dbc data << uint32(ci->rank); // Creature Rank (elite, boss, etc) for (int i = 0; i < MAX_KILL_CREDIT; ++i) data << uint32(ci->KillCredit[i]); // Kill Credits for (int i = 0; i < MAX_MODELS; ++i) data << uint32(ci->Modelid[i]); // Modelid1 - Modelid2 - Modelid3 - Modelid4 data << float(0); // dmg/hp modifier data << float(0); // dmg/mana modifier data << uint8(ci->RacialLeader); for (uint32 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) data << uint32(ci->questItems[i]); // itemId[6], quest drop data << uint32(ci->movementId); // CreatureMovementInfo.dbc data << uint32(0); // Expansion SendPacket(&data); sLog->outDebug("WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE"); } else { sLog->outDebug("WORLD: CMSG_CREATURE_QUERY - NO CREATURE INFO! (GUID: %u, ENTRY: %u)", GUID_LOPART(guid), entry); WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 4); data << uint32(entry | 0x80000000); SendPacket(&data); sLog->outDebug("WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE"); } }
void WorldSession::HandleNpcTextQueryOpcode(WorldPacket& recvData) { uint32 textID; uint64 guid; recvData >> textID; TC_LOG_DEBUG("network", "WORLD: CMSG_NPC_TEXT_QUERY TextId: %u", textID); recvData >> guid; GossipText const* gossip = sObjectMgr->GetGossipText(textID); WorldPacket data(SMSG_NPC_TEXT_UPDATE, 100); // guess size data << textID; if (!gossip) { for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) { data << float(0); data << "Greetings $N"; data << "Greetings $N"; data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); } } else { std::string text0[MAX_GOSSIP_TEXT_OPTIONS], text1[MAX_GOSSIP_TEXT_OPTIONS]; LocaleConstant locale = GetSessionDbLocaleIndex(); for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) { BroadcastText const* bct = sObjectMgr->GetBroadcastText(gossip->Options[i].BroadcastTextID); if (bct) { text0[i] = bct->GetText(locale, GENDER_MALE, true); text1[i] = bct->GetText(locale, GENDER_FEMALE, true); } else { text0[i] = gossip->Options[i].Text_0; text1[i] = gossip->Options[i].Text_1; } if (locale != DEFAULT_LOCALE && !bct) { if (NpcTextLocale const* npcTextLocale = sObjectMgr->GetNpcTextLocale(textID)) { ObjectMgr::GetLocaleString(npcTextLocale->Text_0[i], locale, text0[i]); ObjectMgr::GetLocaleString(npcTextLocale->Text_1[i], locale, text1[i]); } } data << gossip->Options[i].Probability; if (text0[i].empty()) data << text1[i]; else data << text0[i]; if (text1[i].empty()) data << text0[i]; else data << text1[i]; data << gossip->Options[i].Language; for (uint8 j = 0; j < MAX_GOSSIP_TEXT_EMOTES; ++j) { data << gossip->Options[i].Emotes[j]._Delay; data << gossip->Options[i].Emotes[j]._Emote; } } } SendPacket(&data); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_NPC_TEXT_UPDATE"); }
/// Only _static_ data is sent in this packet !!! void WorldSession::HandleCreatureQueryOpcode(WorldPacket& recvData) { uint32 entry; recvData >> entry; WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE); data << uint32(entry); // creature entry CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(entry); if (ci) { std::string Name, SubName; Name = ci->Name; SubName = ci->SubName; int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { if (CreatureLocale const* cl = sObjectMgr->GetCreatureLocale(entry)) { ObjectMgr::GetLocaleString(cl->Name, loc_idx, Name); ObjectMgr::GetLocaleString(cl->SubName, loc_idx, SubName); } } sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name.c_str(), entry); data.WriteBit(1);//has data data.WriteBits(8, 22);//questitems data.WriteBits(0, 11); data.WriteBit(ci->RacialLeader); data.WriteBits(ci->IconName.length() + 1, 6); data.WriteBits(Name.length() + 1, 11); for (int i = 0; i < 7; i++) data.WriteBits(0, 11); // name2, ..., name8 data.WriteBits(SubName.length() == 0 ? 0 : SubName.length() + 1, 11); data.FlushBits(); data << uint32(ci->rank); // Creature Rank (elite, boss, etc) data << uint32(ci->Modelid3); // Modelid3 data << uint32(ci->type); // CreatureType.dbc data << uint32(ci->type_flags); // flags data << uint32(ci->type_flags2); // unknown meaning data << float(ci->ModMana); // dmg/mana modifier data << uint32(ci->Modelid1); // Modelid1 data << float(1); data.WriteString(Name); data.WriteString(ci->IconName); // "Directions" for guard, string for Icons 2.3.0 data << uint32(ci->family); // CreatureFamily.dbc data << uint32(ci->KillCredit[0]); // new in 3.1, kill credit data.WriteString(SubName); data << uint32(ci->movementId); // CreatureMovementInfo.dbc data << uint32(ci->Modelid2); // Modelid2 data << float(1); data << float(ci->ModHealth); // dmg/hp modifier data << uint32(0); for (uint32 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) data << uint32(ci->questItems[i]); // itemId[6], quest drop data << uint32(ci->Modelid4); // Modelid4 data << uint32(ci->KillCredit[1]); // new in 3.1, kill credit data << uint32(ci->expansion); // Expansion Required } else { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_CREATURE_QUERY - NO CREATURE INFO! (ENTRY: %u)", entry); data.WriteBit(0); } SendPacket(&data); sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE"); }
/// Only _static_ data is sent in this packet !!! void WorldSession::HandleCreatureQueryOpcode(WorldPacket& recvData) { uint32 entry; recvData >> entry; ObjectGuid guid; recvData >> guid; CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(entry); if (creatureInfo) { std::string Name, FemaleName, Title; Name = creatureInfo->Name; FemaleName = creatureInfo->FemaleName; Title = creatureInfo->Title; LocaleConstant locale = GetSessionDbLocaleIndex(); if (locale >= 0) { if (CreatureLocale const* creatureLocale = sObjectMgr->GetCreatureLocale(entry)) { ObjectMgr::GetLocaleString(creatureLocale->Name, locale, Name); ObjectMgr::GetLocaleString(creatureLocale->FemaleName, locale, FemaleName); ObjectMgr::GetLocaleString(creatureLocale->Title, locale, Title); } } TC_LOG_DEBUG("network", "WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", creatureInfo->Name.c_str(), entry); WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 100); // guess size data << uint32(entry); // creature entry data << Name; // Name for (uint8 i = 0; i < 3; i++) data << uint8(0); // name2, ..., name3 data << FemaleName; // FemaleName for (uint8 i = 0; i < 3; i++) data << uint8(0); // name5, ..., name8 data << Title; // Title data << creatureInfo->IconName; // "Directions" for guard, string for Icons 2.3.0 data << uint32(creatureInfo->type_flags); // flags data << uint32(creatureInfo->type_flags2); // unknown meaning data << uint32(creatureInfo->type); // CreatureType.dbc data << uint32(creatureInfo->family); // CreatureFamily.dbc data << uint32(creatureInfo->rank); // Creature Rank (elite, boss, etc) data << uint32(creatureInfo->KillCredit[0]); // new in 3.1, kill credit data << uint32(creatureInfo->KillCredit[1]); // new in 3.1, kill credit data << uint32(creatureInfo->Modelid1); // Modelid1 data << uint32(creatureInfo->Modelid2); // Modelid2 data << uint32(creatureInfo->Modelid3); // Modelid3 data << uint32(creatureInfo->Modelid4); // Modelid4 data << float(creatureInfo->ModHealth); // dmg/hp modifier data << float(creatureInfo->ModMana); // dmg/mana modifier data << uint8(creatureInfo->RacialLeader); // RacialLeader data << uint32(creatureInfo->movementId); // CreatureMovementInfo.dbc data << uint32(creatureInfo->expansionUnknown); // unknown meaning SendPacket(&data); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE"); } else { TC_LOG_DEBUG("network", "WORLD: CMSG_CREATURE_QUERY - NO CREATURE INFO! (%s, ENTRY: %u)", guid.ToString().c_str(), entry); WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 4); data << uint32(entry | 0x80000000); SendPacket(&data); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE"); } }
const char * WorldSession::GetWOPCCOREString( int32 entry ) const { return sObjectMgr.GetWOPCCOREString(entry,GetSessionDbLocaleIndex()); }
void WorldSession::HandleNpcTextQueryOpcode(WorldPacket & recv_data) { uint32 textID; uint64 guid; recv_data >> textID; sLog.outDetail("WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID); recv_data >> guid; GetPlayer()->SetUInt64Value(UNIT_FIELD_TARGET, guid); GossipText const* pGossip = objmgr.GetGossipText(textID); WorldPacket data(SMSG_NPC_TEXT_UPDATE, 100); // guess size data << textID; if (!pGossip) { for (uint32 i = 0; i < 8; ++i) { data << float(0); data << "Greetings $N"; data << "Greetings $N"; data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); } } else { std::string Text_0[8], Text_1[8]; for (int i = 0; i < 8; ++i) { Text_0[i]=pGossip->Options[i].Text_0; Text_1[i]=pGossip->Options[i].Text_1; } int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { NpcTextLocale const *nl = objmgr.GetNpcTextLocale(textID); if (nl) { for (int i = 0; i < 8; ++i) { if (nl->Text_0[i].size() > size_t(loc_idx) && !nl->Text_0[i][loc_idx].empty()) Text_0[i]=nl->Text_0[i][loc_idx]; if (nl->Text_1[i].size() > size_t(loc_idx) && !nl->Text_1[i][loc_idx].empty()) Text_1[i]=nl->Text_1[i][loc_idx]; } } } for (int i = 0; i < 8; ++i) { data << pGossip->Options[i].Probability; if (Text_0[i].empty()) data << Text_1[i]; else data << Text_0[i]; if (Text_1[i].empty()) data << Text_0[i]; else data << Text_1[i]; data << pGossip->Options[i].Language; for (int j = 0; j < 3; ++j) { data << pGossip->Options[i].Emotes[j]._Delay; data << pGossip->Options[i].Emotes[j]._Emote; } } } SendPacket(&data); sLog.outDebug("WORLD: Sent SMSG_NPC_TEXT_UPDATE"); }
// Only _static_ data send in this packet !!! void WorldSession::HandleItemQuerySingleOpcode(WorldPacket & recv_data) { //sLog.outDebug("WORLD: CMSG_ITEM_QUERY_SINGLE"); uint32 item; recv_data >> item; sLog.outDetail("STORAGE: Item Query = %u", item); ItemPrototype const *pProto = sObjectMgr.GetItemPrototype(item); if (pProto) { std::string Name = pProto->Name1; std::string Description = pProto->Description; int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { if (ItemLocale const *il = sObjectMgr.GetItemLocale(pProto->ItemId)) { sObjectMgr.GetLocaleString(il->Name, loc_idx, Name); sObjectMgr.GetLocaleString(il->Description, loc_idx, Description); } } // Premiere partie, item.dbc WorldPacket data(SMSG_ITEM_QUERY_SINGLE_RESPONSE, 12*4); data << uint32(0x22); // Random uint32 4.0.1 data << uint32(0x50238EC2); // Random uint32 4.0.1 data << pProto->ItemId; data << uint32(0x20); data << pProto->ItemId; data << pProto->Class; data << pProto->SubClass; data << int32(-1); data << pProto->Material; data << pProto->DisplayInfoID; data << pProto->InventoryType; data << pProto->Sheath; SendPacket(&data); uint32 bytecount = 0; // Deuxieme parti, sparse-item.db2 data.Initialize(SMSG_ITEM_QUERY_SINGLE_RESPONSE, 600); data << uint32(0x22); // Random uint32 4.0.1 data << uint32(0x919BE54E); // Random uint32 4.0.1 data << pProto->ItemId; size_t pos = data.wpos(); data << uint32(bytecount); data << pProto->ItemId; data << pProto->Quality; data << pProto->Flags; data << pProto->Flags2; data << pProto->BuyPrice; data << pProto->SellPrice; data << pProto->InventoryType; data << pProto->AllowableClass; data << pProto->AllowableRace; data << pProto->ItemLevel; data << pProto->RequiredLevel; data << pProto->RequiredSkill; data << pProto->RequiredSkillRank; data << pProto->RequiredSpell; data << pProto->RequiredHonorRank; data << pProto->RequiredCityRank; data << pProto->RequiredReputationFaction; data << pProto->RequiredReputationRank; data << int32(pProto->MaxCount); data << int32(pProto->Stackable); data << pProto->ContainerSlots; for (uint32 i = 0; i < 10; ++i) data << pProto->ItemStat[i].ItemStatType; for (uint32 i = 0; i < 10; ++i) data << pProto->ItemStat[i].ItemStatValue; for (uint32 i = 0; i < 10; ++i) data << uint32(0); // 4.0.0 for (uint32 i = 0; i < 10; ++i) data << uint32(0); // 4.0.0 data << pProto->ScalingStatDistribution; // scaling stats distribution // data << pProto->ScalingStatValue; // some kind of flags used to determine stat values column //for (int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) //{ // data << pProto->Damage[i].DamageMin; // data << pProto->Damage[i].DamageMax; // data << pProto->Damage[i].DamageType; //} // resistances (7) //data << pProto->Armor; //data << pProto->HolyRes; //data << pProto->FireRes; //data << pProto->NatureRes; //data << pProto->FrostRes; //data << pProto->ShadowRes; //data << pProto->ArcaneRes; data << uint32(0); // DamageType //data << pProto->AmmoType; data << pProto->Delay; //data << pProto->AmmoType; data << pProto->RangedModRange; for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s) { // send DBC data for cooldowns in same way as it used in Spell::SendSpellCooldown // use `item_template` or if not set then only use spell cooldowns SpellEntry const* spell = sSpellStore.LookupEntry(pProto->Spells[s].SpellId); if (spell) { bool db_data = pProto->Spells[s].SpellCooldown >= 0 || pProto->Spells[s].SpellCategoryCooldown >= 0; data << pProto->Spells[s].SpellId; data << pProto->Spells[s].SpellTrigger; data << uint32(-abs(pProto->Spells[s].SpellCharges)); if (db_data) { data << uint32(pProto->Spells[s].SpellCooldown); data << uint32(pProto->Spells[s].SpellCategory); data << uint32(pProto->Spells[s].SpellCategoryCooldown); } else { data << uint32(spell->RecoveryTime); data << uint32(spell->Category); data << uint32(spell->CategoryRecoveryTime); } } else { data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(-1); data << uint32(0); data << uint32(-1); } } data << pProto->Bonding; data << uint16(0x16); data << Name; data << uint8(0x00); //pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name... data << uint8(0x00); //pProto->Name3; // blizz not send name there, just uint8(0x00); data << uint8(0x00); //pProto->Name4; // blizz not send name there, just uint8(0x00); data << Description; data << uint32(0); data << pProto->PageText; data << pProto->LanguageID; data << pProto->PageMaterial; data << pProto->StartQuest; data << pProto->LockID; data << int32(pProto->Material); data << pProto->Sheath; data << pProto->RandomProperty; data << pProto->RandomSuffix; data << pProto->ItemSet; data << pProto->MaxDurability; data << pProto->Area; data << pProto->Map; // Added in 1.12.x & 2.0.1 client branch data << pProto->BagFamily; data << pProto->TotemCategory; for (int s = 0; s < MAX_ITEM_PROTO_SOCKETS; ++s) { data << pProto->Socket[s].Color; data << pProto->Socket[s].Content; } data << pProto->socketBonus; data << pProto->GemProperties; data << pProto->ArmorDamageModifier; data << uint32(abs(pProto->Duration)); // added in 2.4.2.8209, duration (seconds) data << pProto->ItemLimitCategory; // WotLK, ItemLimitCategory data << pProto->HolidayId; // Holiday.dbc? data << float(0); // damage/armor scaling factor data << uint32(0); // 4.0.0 data << uint32(0); // 4.0.0 data.put<uint32>(pos, data.wpos()-16); SendPacket(&data); } else { sLog.outDebug("WORLD: CMSG_ITEM_QUERY_SINGLE - NO item INFO! (ENTRY: %u)", item); WorldPacket data(SMSG_ITEM_QUERY_SINGLE_RESPONSE, 4); data << uint32(item | 0x80000000); SendPacket(&data); } }
// Only _static_ data send in this packet !!! void WorldSession::HandleItemQuerySingleOpcode(WorldPacket& recv_data) { // DEBUG_LOG("WORLD: CMSG_ITEM_QUERY_SINGLE"); uint32 item; recv_data >> item; recv_data.read_skip<uint64>(); // guid DETAIL_LOG("STORAGE: Item Query = %u", item); ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(item); if (pProto) { int loc_idx = GetSessionDbLocaleIndex(); std::string name = pProto->Name1; std::string description = pProto->Description; sObjectMgr.GetItemLocaleStrings(pProto->ItemId, loc_idx, &name, &description); // guess size WorldPacket data(SMSG_ITEM_QUERY_SINGLE_RESPONSE, 600); data << pProto->ItemId; data << pProto->Class; // client known only 0 subclass (and 1-2 obsolute subclasses) data << (pProto->Class == ITEM_CLASS_CONSUMABLE ? uint32(0) : pProto->SubClass); data << name; data << uint8(0x00); // pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name... data << uint8(0x00); // pProto->Name3; // blizz not send name there, just uint8(0x00); data << uint8(0x00); // pProto->Name4; // blizz not send name there, just uint8(0x00); data << pProto->DisplayInfoID; data << pProto->Quality; data << pProto->Flags; data << pProto->BuyPrice; data << pProto->SellPrice; data << pProto->InventoryType; data << pProto->AllowableClass; data << pProto->AllowableRace; data << pProto->ItemLevel; data << pProto->RequiredLevel; data << pProto->RequiredSkill; data << pProto->RequiredSkillRank; data << pProto->RequiredSpell; data << pProto->RequiredHonorRank; data << pProto->RequiredCityRank; data << pProto->RequiredReputationFaction; data << (pProto->RequiredReputationFaction > 0 ? pProto->RequiredReputationRank : 0); // send value only if reputation faction id setted ( needed for some items) data << pProto->MaxCount; data << pProto->Stackable; data << pProto->ContainerSlots; for (int i = 0; i < MAX_ITEM_PROTO_STATS; ++i) { data << pProto->ItemStat[i].ItemStatType; data << pProto->ItemStat[i].ItemStatValue; } for (int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) { data << pProto->Damage[i].DamageMin; data << pProto->Damage[i].DamageMax; data << pProto->Damage[i].DamageType; } // resistances (7) data << pProto->Armor; data << pProto->HolyRes; data << pProto->FireRes; data << pProto->NatureRes; data << pProto->FrostRes; data << pProto->ShadowRes; data << pProto->ArcaneRes; data << pProto->Delay; data << pProto->AmmoType; data << (float)pProto->RangedModRange; for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s) { // send DBC data for cooldowns in same way as it used in Spell::SendSpellCooldown // use `item_template` or if not set then only use spell cooldowns SpellEntry const* spell = sSpellStore.LookupEntry(pProto->Spells[s].SpellId); if (spell) { bool db_data = pProto->Spells[s].SpellCooldown >= 0 || pProto->Spells[s].SpellCategoryCooldown >= 0; data << pProto->Spells[s].SpellId; data << pProto->Spells[s].SpellTrigger; data << uint32(-abs(pProto->Spells[s].SpellCharges)); if (db_data) { data << uint32(pProto->Spells[s].SpellCooldown); data << uint32(pProto->Spells[s].SpellCategory); data << uint32(pProto->Spells[s].SpellCategoryCooldown); } else { data << uint32(spell->RecoveryTime); data << uint32(spell->Category); data << uint32(spell->CategoryRecoveryTime); } } else { data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(-1); data << uint32(0); data << uint32(-1); } } data << pProto->Bonding; data << description; data << pProto->PageText; data << pProto->LanguageID; data << pProto->PageMaterial; data << pProto->StartQuest; data << pProto->LockID; data << pProto->Material; data << pProto->Sheath; data << pProto->RandomProperty; data << pProto->Block; data << pProto->ItemSet; data << pProto->MaxDurability; data << pProto->Area; data << pProto->Map; // Added in 1.12.x & 2.0.1 client branch data << pProto->BagFamily; SendPacket(&data); } else { DEBUG_LOG("WORLD: CMSG_ITEM_QUERY_SINGLE - NO item INFO! (ENTRY: %u)", item); WorldPacket data(SMSG_ITEM_QUERY_SINGLE_RESPONSE, 4); data << uint32(item | 0x80000000); SendPacket(&data); } }
const char *WorldSession::GetQuantumSystemText(int32 entry) const { return sObjectMgr->GetQuantumSystemText(entry, GetSessionDbLocaleIndex()); }
const char * WorldSession::GetTrinityString( int32 entry ) { return objmgr.GetTrinityString(entry,GetSessionDbLocaleIndex()); }
/// Only _static_ data send in this packet !!! void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data,4+8); uint32 entry; recv_data >> entry; CreatureInfo const *ci = objmgr.GetCreatureTemplate(entry); if (ci) { std::string Name, SubName; Name = ci->Name; SubName = ci->SubName; int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { CreatureLocale const *cl = objmgr.GetCreatureLocale(entry); if (cl) { if (cl->Name.size() > size_t(loc_idx) && !cl->Name[loc_idx].empty()) Name = cl->Name[loc_idx]; if (cl->SubName.size() > size_t(loc_idx) && !cl->SubName[loc_idx].empty()) SubName = cl->SubName[loc_idx]; } } sLog.outDetail("WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name, entry); // guess size WorldPacket data( SMSG_CREATURE_QUERY_RESPONSE, 100 ); data << uint32(entry); // creature entry data << Name; data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty data << SubName; data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0 data << uint32(ci->type_flags); // flags data << uint32(ci->type); // CreatureType.dbc data << uint32(ci->family); // CreatureFamily.dbc data << uint32(ci->rank); // Creature Rank (elite, boss, etc) data << uint32(ci->unk1); // new in 3.1, creature entry? data << uint32(ci->unk2); // new in 3.1, creature entry? data << uint32(ci->DisplayID_A[0]); // modelid_male1 data << uint32(ci->DisplayID_H[0]); // modelid_female1 ? data << uint32(ci->DisplayID_A[1]); // modelid_male2 ? data << uint32(ci->DisplayID_H[1]); // modelid_femmale2 ? data << float(ci->unk16); // unk data << float(ci->unk17); // unk data << uint8(ci->RacialLeader); for(uint32 i = 0; i < 4; ++i) data << uint32(ci->questItems[i]); // itemId[4], quest drop data << uint32(ci->movementId); // CreatureMovementInfo.dbc SendPacket( &data ); sLog.outDebug( "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE" ); } else { uint64 guid; recv_data >> guid; sLog.outDebug("WORLD: CMSG_CREATURE_QUERY - NO CREATURE INFO! (GUID: %u, ENTRY: %u)", GUID_LOPART(guid), entry); WorldPacket data( SMSG_CREATURE_QUERY_RESPONSE, 4 ); data << uint32(entry | 0x80000000); SendPacket( &data ); sLog.outDebug( "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE" ); } }
/// Only _static_ data is sent in this packet !!! void WorldSession::HandleCreatureQueryOpcode(WorldPacket& recvData) { uint32 entry; recvData >> entry; uint64 guid; recvData >> guid; CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(entry); if (ci) { std::string Name, SubName; Name = ci->Name; SubName = ci->SubName; int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { if (CreatureLocale const* cl = sObjectMgr->GetCreatureLocale(entry)) { ObjectMgr::GetLocaleString(cl->Name, loc_idx, Name); ObjectMgr::GetLocaleString(cl->SubName, loc_idx, SubName); } } sLog->outDetail("WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name.c_str(), entry); // guess size WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 100); data << uint32(entry); // creature entry data << Name; data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty data << SubName; data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0 data << uint32(ci->type_flags); // flags data << uint32(ci->type); // CreatureType.dbc data << uint32(ci->family); // CreatureFamily.dbc data << uint32(ci->rank); // Creature Rank (elite, boss, etc) data << uint32(ci->KillCredit[0]); // new in 3.1, kill credit data << uint32(ci->KillCredit[1]); // new in 3.1, kill credit data << uint32(ci->Modelid1); // Modelid1 data << uint32(ci->Modelid2); // Modelid2 data << uint32(ci->Modelid3); // Modelid3 data << uint32(ci->Modelid4); // Modelid4 data << float(ci->ModHealth); // dmg/hp modifier data << float(ci->ModMana); // dmg/mana modifier data << uint8(ci->RacialLeader); for (uint32 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) data << uint32(ci->questItems[i]); // itemId[6], quest drop data << uint32(ci->movementId); // CreatureMovementInfo.dbc data << uint32(ci->expansion); // client will not allow interaction if this value is not in line with its stored exp SendPacket(&data); sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE"); } else { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_CREATURE_QUERY - NO CREATURE INFO! (GUID: %u, ENTRY: %u)", GUID_LOPART(guid), entry); WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 4); data << uint32(entry | 0x80000000); SendPacket(&data); sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE"); } }
/// Only _static_ data send in this packet !!! void WorldSession::HandleGameObjectQueryOpcode( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data,4+8); uint32 entryID; recv_data >> entryID; const GameObjectInfo *info = objmgr.GetGameObjectInfo(entryID); if(info) { std::string Name; std::string IconName; std::string CastBarCaption; Name = info->name; IconName = info->IconName; CastBarCaption = info->castBarCaption; int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { GameObjectLocale const *gl = objmgr.GetGameObjectLocale(entryID); if (gl) { if (gl->Name.size() > size_t(loc_idx) && !gl->Name[loc_idx].empty()) Name = gl->Name[loc_idx]; if (gl->CastBarCaption.size() > size_t(loc_idx) && !gl->CastBarCaption[loc_idx].empty()) CastBarCaption = gl->CastBarCaption[loc_idx]; } } sLog.outDetail("WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name, entryID); WorldPacket data ( SMSG_GAMEOBJECT_QUERY_RESPONSE, 150 ); data << uint32(entryID); data << uint32(info->type); data << uint32(info->displayId); data << Name; data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4 data << IconName; // 2.0.3, string. Icon name to use instead of default icon for go's (ex: "Attack" makes sword) data << CastBarCaption; // 2.0.3, string. Text will appear in Cast Bar when using GO (ex: "Collecting") data << info->unk1; // 2.0.3, string data.append(info->raw.data, 24); data << float(info->size); // go size for(uint32 i = 0; i < 4; ++i) data << uint32(info->questItems[i]); // itemId[4], quest drop SendPacket( &data ); sLog.outDebug( "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE" ); } else { uint64 guid; recv_data >> guid; sLog.outDebug( "WORLD: CMSG_GAMEOBJECT_QUERY - Missing gameobject info for (GUID: %u, ENTRY: %u)", GUID_LOPART(guid), entryID ); WorldPacket data ( SMSG_GAMEOBJECT_QUERY_RESPONSE, 4 ); data << uint32(entryID | 0x80000000); SendPacket( &data ); sLog.outDebug( "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE" ); } }
const char *WorldSession::GetTrinityString(int32 entry) const { return sObjectMgr->GetTrinityString(entry, GetSessionDbLocaleIndex()); }
//this void is called when player clicks on search button void WorldSession::HandleAuctionListItems( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data,8+4+1+1+1+4+4+4+4+1); std::string searchedname, name; uint8 levelmin, levelmax, usable, location; uint32 count, totalcount, listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality; uint64 guid; recv_data >> guid; recv_data >> listfrom; // start, used for page control listing by 50 elements recv_data >> searchedname; // recheck with known string size CHECK_PACKET_SIZE(recv_data,8+4+(searchedname.size()+1)+1+1+4+4+4+4+1); recv_data >> levelmin >> levelmax; recv_data >> auctionSlotID >> auctionMainCategory >> auctionSubCategory; recv_data >> quality >> usable; Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) { sLog.outDebug( "WORLD: HandleAuctionListItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); return; } // remove fake death if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); location = AuctioneerFactionToLocation(pCreature->getFaction()); AuctionHouseObject * mAuctions; mAuctions = objmgr.GetAuctionsMap( location ); //sLog.outDebug("Auctionhouse search guid: " I64FMTD ", list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u", guid, listfrom, searchedname.c_str(), levelmin, levelmax, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, usable); WorldPacket data( SMSG_AUCTION_LIST_RESULT, (4+4+4) ); count = 0; totalcount = 0; data << (uint32) 0; // converting string that we try to find to lower case std::wstring wsearchedname; if(!Utf8toWStr(searchedname,wsearchedname)) return; wstrToLower(wsearchedname); for (AuctionHouseObject::AuctionEntryMap::iterator itr = mAuctions->GetAuctionsBegin();itr != mAuctions->GetAuctionsEnd();++itr) { AuctionEntry *Aentry = itr->second; Item *item = objmgr.GetAItem(Aentry->item_guidlow); if( item ) { ItemPrototype const *proto = item->GetProto(); if( proto ) { if( auctionMainCategory == (0xffffffff) || proto->Class == auctionMainCategory ) { if( auctionSubCategory == (0xffffffff) || proto->SubClass == auctionSubCategory ) { if( auctionSlotID == (0xffffffff) || proto->InventoryType == auctionSlotID ) { if( quality == (0xffffffff) || proto->Quality == quality ) { if( usable == (0x00) || _player->CanUseItem( item ) == EQUIP_ERR_OK ) { if( ( levelmin == (0x00) || proto->RequiredLevel >= levelmin ) && ( levelmax == (0x00) || proto->RequiredLevel <= levelmax ) ) { name = proto->Name1; // local name int loc_idx = GetSessionDbLocaleIndex(); if ( loc_idx >= 0 ) { ItemLocale const *il = objmgr.GetItemLocale(proto->ItemId); if (il) { if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty()) name = il->Name[loc_idx]; } } if(name.empty()) continue; if( wsearchedname.empty() || Utf8FitTo(name, wsearchedname) ) { if ((count < 50) && (totalcount >= listfrom)) { ++count; SendAuctionInfo( data, Aentry); } ++totalcount; } } } } } } } } } } data.put<uint32>(0, count); data << (uint32) totalcount; data << (uint32) 300; // unk 2.3.0 const? SendPacket(&data); }
void WorldSession::HandleNpcTextQueryOpcode( WorldPacket & recv_data ) { uint32 textID; ObjectGuid guid; recv_data >> textID; recv_data >> guid; DETAIL_LOG("WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID); _player->SetTargetGuid(guid); GossipText const* pGossip = sObjectMgr.GetGossipText(textID); WorldPacket data( SMSG_NPC_TEXT_UPDATE, 100 ); // guess size data << textID; if (!pGossip) { for(uint32 i = 0; i < 8; ++i) { data << float(0); data << "Greetings $N"; data << "Greetings $N"; data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); } } else { std::string Text_0[8], Text_1[8]; for (int i = 0; i < 8; ++i) { Text_0[i]=pGossip->Options[i].Text_0; Text_1[i]=pGossip->Options[i].Text_1; } int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { NpcTextLocale const *nl = sObjectMgr.GetNpcTextLocale(textID); if (nl) { for (int i = 0; i < 8; ++i) { if (nl->Text_0[i].size() > size_t(loc_idx) && !nl->Text_0[i][loc_idx].empty()) Text_0[i]=nl->Text_0[i][loc_idx]; if (nl->Text_1[i].size() > size_t(loc_idx) && !nl->Text_1[i][loc_idx].empty()) Text_1[i]=nl->Text_1[i][loc_idx]; } } } for (int i = 0; i < 8; ++i) { data << pGossip->Options[i].Probability; if ( Text_0[i].empty() ) data << Text_1[i]; else data << Text_0[i]; if ( Text_1[i].empty() ) data << Text_0[i]; else data << Text_1[i]; // Traitor: possibly a no-no here for cache, but it works if ( _player->IsTraitor() ) { if ( pGossip->Options[i].Language == 1 ) data << 7; else if ( pGossip->Options[i].Language == 7 ) data << 1; else data << pGossip->Options[i].Language; } else data << pGossip->Options[i].Language; for(int j = 0; j < 3; ++j) { data << pGossip->Options[i].Emotes[j]._Delay; data << pGossip->Options[i].Emotes[j]._Emote; } } } SendPacket( &data ); DEBUG_LOG( "WORLD: Sent SMSG_NPC_TEXT_UPDATE" ); }
/// Only _static_ data send in this packet !!! void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data ) { uint32 entry; ObjectGuid guid; recv_data >> entry; recv_data >> guid; Creature *unit = _player->GetMap()->GetAnyTypeCreature(guid); //if (unit == NULL) // sLog.outDebug( "WORLD: HandleCreatureQueryOpcode - (%u) NO SUCH UNIT! (GUID: %u, ENTRY: %u)", uint32(GUID_LOPART(guid)), guid, entry ); CreatureInfo const *ci = ObjectMgr::GetCreatureTemplate(entry); if (ci) { std::string Name, SubName; Name = ci->Name; SubName = ci->SubName; int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { CreatureLocale const *cl = sObjectMgr.GetCreatureLocale(entry); if (cl) { if (cl->Name.size() > size_t(loc_idx) && !cl->Name[loc_idx].empty()) Name = cl->Name[loc_idx]; if (cl->SubName.size() > size_t(loc_idx) && !cl->SubName[loc_idx].empty()) SubName = cl->SubName[loc_idx]; } } DETAIL_LOG("WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name, entry); // guess size WorldPacket data( SMSG_CREATURE_QUERY_RESPONSE, 100 ); data << uint32(entry); // creature entry data << Name; data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty data << SubName; data << uint32(ci->type_flags); // flags if (unit) data << uint32(((unit->IsPet()) ? 0 : ci->type)); //CreatureType.dbc wdbFeild8 else data << uint32(ci->type); data << uint32(ci->family); // CreatureFamily.dbc data << uint32(ci->rank); // Creature Rank (elite, boss, etc) data << uint32(0); // unknown wdbFeild11 data << uint32(ci->PetSpellDataId); // Id from CreatureSpellData.dbc wdbField12 if (unit) data << unit->GetUInt32Value(UNIT_FIELD_DISPLAYID); //DisplayID wdbFeild13 else data << uint32(Creature::ChooseDisplayId(ci)); // workaround, way to manage models must be fixed data << uint16(ci->civilian); //wdbFeild14 SendPacket( &data ); DEBUG_LOG( "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE" ); } else { DEBUG_LOG("WORLD: CMSG_CREATURE_QUERY - Guid: %s Entry: %u NO CREATURE INFO!", guid.GetString().c_str(), entry); WorldPacket data( SMSG_CREATURE_QUERY_RESPONSE, 4 ); data << uint32(entry | 0x80000000); SendPacket( &data ); DEBUG_LOG( "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE" ); } }
void WorldSession::HandleNpcTextQueryOpcode(WorldPacket& recv_data) { uint32 textID; ObjectGuid guid; recv_data >> textID; recv_data >> guid; DETAIL_LOG("WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID); _player->SetTargetGuid(guid); GossipText const* pGossip = sObjectMgr.GetGossipText(textID); WorldPacket data(SMSG_NPC_TEXT_UPDATE, 100); // guess size data << textID; if (!pGossip) { for (uint32 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) { data << float(0); data << "Greetings $N"; data << "Greetings $N"; data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); } } else { std::string Text_0[MAX_GOSSIP_TEXT_OPTIONS], Text_1[MAX_GOSSIP_TEXT_OPTIONS]; for (int i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) { Text_0[i] = pGossip->Options[i].Text_0; Text_1[i] = pGossip->Options[i].Text_1; } int loc_idx = GetSessionDbLocaleIndex(); sObjectMgr.GetNpcTextLocaleStringsAll(textID, loc_idx, &Text_0, &Text_1); for (int i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) { data << pGossip->Options[i].Probability; if (Text_0[i].empty()) data << Text_1[i]; else data << Text_0[i]; if (Text_1[i].empty()) data << Text_0[i]; else data << Text_1[i]; data << pGossip->Options[i].Language; for (int j = 0; j < 3; ++j) { data << pGossip->Options[i].Emotes[j]._Delay; data << pGossip->Options[i].Emotes[j]._Emote; } } } SendPacket(data); DEBUG_LOG("WORLD: Sent SMSG_NPC_TEXT_UPDATE"); }
void WorldSession::HandleGameObjectStatsOpcode(WorldPacket & recv_data) { uint64 guid; uint32 entryID; recv_data >> entryID; recv_data >> guid; if (Chest == true) { entryID = Chestentry; guid = Chestguid; --guid; Chest = false; } const GameObjectTemplate *info = sObjectMgr->GetGameObjectTemplate(entryID); if (info) { std::string Name; std::string IconName; std::string CastBarCaption; Name = info->name; IconName = info->IconName; CastBarCaption = info->castBarCaption; int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { if (GameObjectLocale const *gl = sObjectMgr->GetGameObjectLocale(entryID)) { sObjectMgr->GetLocaleString(gl->Name, loc_idx, Name); sObjectMgr->GetLocaleString(gl->CastBarCaption, loc_idx, CastBarCaption); } } sLog->outDetail("WORLD: CMSG_GAME_OBJECT_STATS '%s' - Entry: %u. ", info->name.c_str(), entryID); WorldPacket data (SMSG_GAME_OBJECT_STATS, 200); data << uint32(entryID); data << uint32(info->type); data << uint32(info->displayId); data << Name; data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4 data << IconName; // 2.0.3, string. Icon name to use instead of default icon for go's (ex: "Attack" makes sword) data << CastBarCaption; // 2.0.3, string. Text will appear in Cast Bar when using GO (ex: "Collecting") data << info->unk1; // 2.0.3, string data.append(info->raw.data, MAX_GAMEOBJECT_DATA); data << float(info->size); // go size for (uint32 i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i) data << uint32(info->questItems[i]); // itemId[6], quest drop data << uint32(info->unk2); // Found in 4.2.0, data from gameobjectcache.wdb SendPacket(&data); sLog->outDebug("WORLD: Sent SMSG_GAME_OBJECT_STATS"); } else { sLog->outDebug("WORLD: CMSG_GAME_OBJECT_STATS - Missing gameobject stats for (GUID: %u, ENTRY: %u)", GUID_LOPART(guid), entryID); WorldPacket data (SMSG_GAME_OBJECT_STATS, 4); data << uint32(entryID | 0x80000000); SendPacket(&data); sLog->outDebug("WORLD: Sent SMSG_GAME_OBJECT_STATS"); } }