[11743] Fixed auction crash in case missing localization for only some items

Source crash in missing locale strings array size check before access
to it in locale structure.

Also move repeating code for access to wide used localization string arrays to ObjectMgr functions.
This commit is contained in:
VladimirMangos 2011-07-19 00:35:16 +04:00
parent bc171d5f97
commit 3e0cacbdaf
15 changed files with 203 additions and 315 deletions

View file

@ -697,22 +697,18 @@ int AuctionEntry::CompareAuctionEntry(uint32 column, const AuctionEntry *auc, Pl
break; break;
case 5: // name = 5 case 5: // name = 5
{ {
ItemPrototype const* itemProto1 = ObjectMgr::GetItemPrototype(itemTemplate);
ItemPrototype const* itemProto2 = ObjectMgr::GetItemPrototype(auc->itemTemplate);
if (!itemProto2 || !itemProto1)
return 0;
int32 loc_idx = viewPlayer->GetSession()->GetSessionDbLocaleIndex(); int32 loc_idx = viewPlayer->GetSession()->GetSessionDbLocaleIndex();
std::string name1, name2; std::string name1 = itemProto1->Name1;
if (loc_idx >= 0) sObjectMgr.GetItemLocaleStrings(itemProto1->ItemId, loc_idx, &name1);
{
if(ItemLocale const *il = sObjectMgr.GetItemLocale(itemTemplate)) std::string name2 = itemProto2->Name1;
name1 = il->Name[loc_idx]; sObjectMgr.GetItemLocaleStrings(itemProto2->ItemId, loc_idx, &name2);
if(ItemLocale const *il = sObjectMgr.GetItemLocale(auc->itemTemplate))
name2 = il->Name[loc_idx];
}
if (name1.empty())
if (ItemPrototype const* proto = ObjectMgr::GetItemPrototype(itemTemplate))
name1 = proto->Name1;
if (name2.empty())
if (ItemPrototype const* proto = ObjectMgr::GetItemPrototype(auc->itemTemplate))
name2 = proto->Name1;
std::wstring wname1, wname2; std::wstring wname1, wname2;
Utf8toWStr(name1, wname1); Utf8toWStr(name1, wname1);
@ -845,19 +841,7 @@ void WorldSession::BuildListAuctionItems(std::vector<AuctionEntry*> const& aucti
continue; continue;
std::string name = proto->Name1; std::string name = proto->Name1;
if (name.empty()) sObjectMgr.GetItemLocaleStrings(proto->ItemId, loc_idx, &name);
continue;
// local name
if (loc_idx >= 0)
{
ItemLocale const *il = sObjectMgr.GetItemLocale(proto->ItemId);
if (il)
{
if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty())
name = il->Name[loc_idx];
}
}
if (!wsearchedname.empty() && !Utf8FitTo(name, wsearchedname)) if (!wsearchedname.empty() && !Utf8FitTo(name, wsearchedname))
continue; continue;

View file

@ -940,13 +940,11 @@ void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count)
// save new item before send // save new item before send
markItem->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted markItem->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
int loc_idx = plr->GetSession()->GetSessionDbLocaleIndex();
// subject: item name // subject: item name
std::string subject = markProto->Name1; std::string subject = markProto->Name1;
int loc_idx = plr->GetSession()->GetSessionDbLocaleIndex(); sObjectMgr.GetItemLocaleStrings(markProto->ItemId, loc_idx, &subject);
if (loc_idx >= 0 )
if (ItemLocale const *il = sObjectMgr.GetItemLocale(markProto->ItemId))
if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty())
subject = il->Name[loc_idx];
// text // text
std::string textFormat = plr->GetSession()->GetMangosString(LANG_BG_MARK_BY_MAIL); std::string textFormat = plr->GetSession()->GetMangosString(LANG_BG_MARK_BY_MAIL);

View file

@ -1896,7 +1896,7 @@ valid examples:
return false; return false;
} }
for(uint8 i=0; i<MAX_LOCALE; ++i) for(uint8 i=0; i < MAX_LOCALE; ++i)
{ {
uint32 skillLineNameLength = strlen(skillLine->name[i]); uint32 skillLineNameLength = strlen(skillLine->name[i]);
if (skillLineNameLength > 0 && strncmp(skillLine->name[i], buffer, skillLineNameLength) == 0) if (skillLineNameLength > 0 && strncmp(skillLine->name[i], buffer, skillLineNameLength) == 0)
@ -1933,7 +1933,7 @@ valid examples:
} }
bool foundName = false; bool foundName = false;
for(uint8 i=0; i<ql->Title.size(); i++) for(uint8 i=0; i < ql->Title.size(); ++i)
{ {
if (ql->Title[i] == buffer) if (ql->Title[i] == buffer)
{ {

View file

@ -2330,17 +2330,9 @@ TrainerSpellData const* Creature::GetTrainerSpells() const
// overwrite WorldObject function for proper name localization // overwrite WorldObject function for proper name localization
const char* Creature::GetNameForLocaleIdx(int32 loc_idx) const const char* Creature::GetNameForLocaleIdx(int32 loc_idx) const
{ {
if (loc_idx >= 0) char const* name = GetName();
{ sObjectMgr.GetCreatureLocaleStrings(GetEntry(), loc_idx, &name);
CreatureLocale const *cl = sObjectMgr.GetCreatureLocale(GetEntry()); return name;
if (cl)
{
if (cl->Name.size() > (size_t)loc_idx && !cl->Name[loc_idx].empty())
return cl->Name[loc_idx].c_str();
}
}
return GetName();
} }
void Creature::SetFactionTemporary(uint32 factionId, uint32 tempFactionFlags) void Creature::SetFactionTemporary(uint32 factionId, uint32 tempFactionFlags)

View file

@ -181,14 +181,12 @@ void PlayerMenu::SendGossipMenu(uint32 TitleTextId, ObjectGuid objectGuid)
data << int32(pQuest->GetQuestLevel()); data << int32(pQuest->GetQuestLevel());
data << uint32(pQuest->GetQuestFlags()); // 3.3.3 quest flags data << uint32(pQuest->GetQuestFlags()); // 3.3.3 quest flags
data << uint8(0); // 3.3.3 changes icon: blue question or yellow exclamation data << uint8(0); // 3.3.3 changes icon: blue question or yellow exclamation
std::string Title = pQuest->GetTitle();
int loc_idx = GetMenuSession()->GetSessionDbLocaleIndex(); int loc_idx = GetMenuSession()->GetSessionDbLocaleIndex();
if (loc_idx >= 0) std::string title = pQuest->GetTitle();
if (QuestLocale const *ql = sObjectMgr.GetQuestLocale(questID)) sObjectMgr.GetQuestLocaleStrings(questID, loc_idx, &title);
if (ql->Title.size() > (size_t)loc_idx && !ql->Title[loc_idx].empty())
Title = ql->Title[loc_idx]; data << title; // max 0x200
data << Title; // max 0x200
} }
GetMenuSession()->SendPacket( &data ); GetMenuSession()->SendPacket( &data );
@ -272,36 +270,27 @@ void PlayerMenu::SendTalking( uint32 textID )
} }
else else
{ {
std::string Text_0[8], Text_1[8]; std::string Text_0[MAX_GOSSIP_TEXT_OPTIONS], Text_1[MAX_GOSSIP_TEXT_OPTIONS];
for (int i = 0; i < 8; ++i) for (int i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
{ {
Text_0[i] = pGossip->Options[i].Text_0; Text_0[i] = pGossip->Options[i].Text_0;
Text_1[i] = pGossip->Options[i].Text_1; Text_1[i] = pGossip->Options[i].Text_1;
} }
int loc_idx = GetMenuSession()->GetSessionDbLocaleIndex(); int loc_idx = GetMenuSession()->GetSessionDbLocaleIndex();
if (loc_idx >= 0)
{ sObjectMgr.GetNpcTextLocaleStringsAll(textID, loc_idx, &Text_0, &Text_1);
if (NpcTextLocale const *nl = sObjectMgr.GetNpcTextLocale(textID))
{ for (int i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
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; data << pGossip->Options[i].Probability;
if ( Text_0[i].empty() ) if (Text_0[i].empty())
data << Text_1[i]; data << Text_1[i];
else else
data << Text_0[i]; data << Text_0[i];
if ( Text_1[i].empty() ) if (Text_1[i].empty())
data << Text_0[i]; data << Text_0[i];
else else
data << Text_1[i]; data << Text_1[i];
@ -405,17 +394,9 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote eEmote, const std::string& Title
if(Quest const *pQuest = sObjectMgr.GetQuestTemplate(questID)) if(Quest const *pQuest = sObjectMgr.GetQuestTemplate(questID))
{ {
std::string title = pQuest->GetTitle();
int loc_idx = GetMenuSession()->GetSessionDbLocaleIndex(); int loc_idx = GetMenuSession()->GetSessionDbLocaleIndex();
if (loc_idx >= 0) std::string title = pQuest->GetTitle();
{ sObjectMgr.GetQuestLocaleStrings(questID, loc_idx, &title);
if(QuestLocale const *ql = sObjectMgr.GetQuestLocale(questID))
{
if (ql->Title.size() > (size_t)loc_idx && !ql->Title[loc_idx].empty())
title = ql->Title[loc_idx];
}
}
data << uint32(questID); data << uint32(questID);
data << uint32(qmi.m_qIcon); data << uint32(qmi.m_qIcon);

View file

@ -286,31 +286,22 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
DETAIL_LOG("STORAGE: Item Query = %u", item); DETAIL_LOG("STORAGE: Item Query = %u", item);
ItemPrototype const *pProto = ObjectMgr::GetItemPrototype( item ); ItemPrototype const *pProto = ObjectMgr::GetItemPrototype(item);
if( pProto ) if (pProto)
{ {
std::string Name = pProto->Name1;
std::string Description = pProto->Description;
int loc_idx = GetSessionDbLocaleIndex(); int loc_idx = GetSessionDbLocaleIndex();
if ( loc_idx >= 0 )
{ std::string name = pProto->Name1;
ItemLocale const *il = sObjectMgr.GetItemLocale(pProto->ItemId); std::string description = pProto->Description;
if (il) sObjectMgr.GetItemLocaleStrings(pProto->ItemId, loc_idx, &name, &description);
{
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 // guess size
WorldPacket data( SMSG_ITEM_QUERY_SINGLE_RESPONSE, 600); WorldPacket data( SMSG_ITEM_QUERY_SINGLE_RESPONSE, 600);
data << pProto->ItemId; data << pProto->ItemId;
data << pProto->Class; data << pProto->Class;
data << pProto->SubClass; data << pProto->SubClass;
data << int32(pProto->Unk0); // new 2.0.3, not exist in wdb cache? data << int32(pProto->Unk0); // new 2.0.3, not exist in wdb cache?
data << Name; data << name;
data << uint8(0x00); //pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty 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->Name3; // blizz not send name there, just uint8(0x00);
data << uint8(0x00); //pProto->Name4; // blizz not send name there, just uint8(0x00); data << uint8(0x00); //pProto->Name4; // blizz not send name there, just uint8(0x00);
@ -400,7 +391,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
} }
} }
data << pProto->Bonding; data << pProto->Bonding;
data << Description; data << description;
data << pProto->PageText; data << pProto->PageText;
data << pProto->LanguageID; data << pProto->LanguageID;
data << pProto->PageMaterial; data << pProto->PageMaterial;
@ -1078,26 +1069,16 @@ void WorldSession::HandleItemNameQueryOpcode(WorldPacket & recv_data)
recv_data.read_skip<uint64>(); // guid recv_data.read_skip<uint64>(); // guid
DEBUG_LOG("WORLD: CMSG_ITEM_NAME_QUERY %u", itemid); DEBUG_LOG("WORLD: CMSG_ITEM_NAME_QUERY %u", itemid);
ItemPrototype const *pProto = ObjectMgr::GetItemPrototype( itemid ); if (ItemPrototype const *pProto = ObjectMgr::GetItemPrototype(itemid))
if( pProto )
{ {
std::string Name;
Name = pProto->Name1;
int loc_idx = GetSessionDbLocaleIndex(); int loc_idx = GetSessionDbLocaleIndex();
if (loc_idx >= 0)
{ std::string name = pProto->Name1;
ItemLocale const *il = sObjectMgr.GetItemLocale(pProto->ItemId); sObjectMgr.GetItemLocaleStrings(pProto->ItemId, loc_idx, &name);
if (il)
{
if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty())
Name = il->Name[loc_idx];
}
}
// guess size // guess size
WorldPacket data(SMSG_ITEM_NAME_QUERY_RESPONSE, (4+10)); WorldPacket data(SMSG_ITEM_NAME_QUERY_RESPONSE, (4+10));
data << uint32(pProto->ItemId); data << uint32(pProto->ItemId);
data << Name; data << name;
data << uint32(pProto->InventoryType); data << uint32(pProto->InventoryType);
SendPacket(&data); SendPacket(&data);
return; return;

View file

@ -3078,13 +3078,8 @@ void ChatHandler::ShowItemListHelper( uint32 itemId, int loc_idx, Player* target
if(!itemProto) if(!itemProto)
return; return;
std::string name; std::string name = itemProto->Name1;
sObjectMgr.GetItemLocaleStrings(itemProto->ItemId, loc_idx, &name);
if(ItemLocale const *il = loc_idx >= 0 ? sObjectMgr.GetItemLocale(itemProto->ItemId) : NULL)
name = il->Name[loc_idx];
if (name.empty())
name = itemProto->Name1;
char const* usableStr = ""; char const* usableStr = "";
@ -3119,41 +3114,21 @@ bool ChatHandler::HandleLookupItemCommand(char* args)
uint32 counter = 0; uint32 counter = 0;
// Search in `item_template` // Search in `item_template`
for (uint32 id = 0; id < sItemStorage.MaxEntry; id++) for (uint32 id = 0; id < sItemStorage.MaxEntry; ++id)
{ {
ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype >(id); ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype >(id);
if(!pProto) if(!pProto)
continue; continue;
int loc_idx = GetSessionDbLocaleIndex(); int loc_idx = GetSessionDbLocaleIndex();
if ( loc_idx >= 0 )
{
ItemLocale const *il = sObjectMgr.GetItemLocale(pProto->ItemId);
if (il)
{
if ((int32)il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
{
std::string name = il->Name[loc_idx];
if (Utf8FitTo(name, wnamepart)) std::string name; // "" for let later only single time check default locale name directly
{ sObjectMgr.GetItemLocaleStrings(id, loc_idx, &name);
ShowItemListHelper(pProto->ItemId, loc_idx, pl); if ((name.empty() || !Utf8FitTo(name, wnamepart)) && !Utf8FitTo(pProto->Name1, wnamepart))
++counter;
continue;
}
}
}
}
std::string name = pProto->Name1;
if(name.empty())
continue; continue;
if (Utf8FitTo(name, wnamepart)) ShowItemListHelper(id, loc_idx, pl);
{ ++counter;
ShowItemListHelper(pProto->ItemId, -1, pl);
++counter;
}
} }
if (counter==0) if (counter==0)
@ -3413,13 +3388,8 @@ void ChatHandler::ShowQuestListHelper( uint32 questId, int32 loc_idx, Player* ta
if (!qinfo) if (!qinfo)
return; return;
std::string title; std::string title = qinfo->GetTitle();
sObjectMgr.GetQuestLocaleStrings(questId, loc_idx, &title);
if (QuestLocale const *il = loc_idx >= 0 ? sObjectMgr.GetQuestLocale(qinfo->GetQuestId()) : NULL)
title = il->Title[loc_idx];
if (title.empty())
title = qinfo->GetTitle();
char const* statusStr = ""; char const* statusStr = "";
@ -3463,40 +3433,21 @@ bool ChatHandler::HandleLookupQuestCommand(char* args)
uint32 counter = 0 ; uint32 counter = 0 ;
int loc_idx = GetSessionDbLocaleIndex();
ObjectMgr::QuestMap const& qTemplates = sObjectMgr.GetQuestTemplates(); ObjectMgr::QuestMap const& qTemplates = sObjectMgr.GetQuestTemplates();
for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter) for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter)
{ {
Quest * qinfo = iter->second; Quest * qinfo = iter->second;
int loc_idx = GetSessionDbLocaleIndex(); std::string title; // "" for avoid repeating check default locale
if ( loc_idx >= 0 ) sObjectMgr.GetQuestLocaleStrings(qinfo->GetQuestId(), loc_idx, &title);
{
QuestLocale const *il = sObjectMgr.GetQuestLocale(qinfo->GetQuestId());
if (il)
{
if ((int32)il->Title.size() > loc_idx && !il->Title[loc_idx].empty())
{
std::string title = il->Title[loc_idx];
if (Utf8FitTo(title, wnamepart)) if ((title.empty() || !Utf8FitTo(title, wnamepart)) && !Utf8FitTo(qinfo->GetTitle(), wnamepart))
{
ShowQuestListHelper(qinfo->GetQuestId(), loc_idx, target);
++counter;
continue;
}
}
}
}
std::string title = qinfo->GetTitle();
if(title.empty())
continue; continue;
if (Utf8FitTo(title, wnamepart)) ShowQuestListHelper(qinfo->GetQuestId(), loc_idx, target);
{ ++counter;
ShowQuestListHelper(qinfo->GetQuestId(), -1, target);
++counter;
}
} }
if (counter==0) if (counter==0)
@ -3528,40 +3479,22 @@ bool ChatHandler::HandleLookupCreatureCommand(char* args)
continue; continue;
int loc_idx = GetSessionDbLocaleIndex(); int loc_idx = GetSessionDbLocaleIndex();
if (loc_idx >= 0)
{
CreatureLocale const *cl = sObjectMgr.GetCreatureLocale (id);
if (cl)
{
if ((int32)cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty ())
{
std::string name = cl->Name[loc_idx];
if (Utf8FitTo (name, wnamepart)) char const* name = ""; // "" for avoid repeating check for default locale
{ sObjectMgr.GetCreatureLocaleStrings(id, loc_idx, &name);
if (m_session) if (!*name || !Utf8FitTo(name, wnamepart))
PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ()); {
else name = cInfo->Name;
PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ()); if (!Utf8FitTo(name, wnamepart))
++counter; continue;
continue;
}
}
}
} }
std::string name = cInfo->Name; if (m_session)
if (name.empty ()) PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name);
continue; else
PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name);
if (Utf8FitTo(name, wnamepart)) ++counter;
{
if (m_session)
PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
else
PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
++counter;
}
} }
if (counter==0) if (counter==0)

View file

@ -3160,23 +3160,12 @@ class StaticMonsterChatBuilder
} }
void operator()(WorldPacket& data, int32 loc_idx) void operator()(WorldPacket& data, int32 loc_idx)
{ {
char const* text = sObjectMgr.GetMangosString(i_textId,loc_idx); char const* text = sObjectMgr.GetMangosString(i_textId, loc_idx);
std::string nameForLocale = ""; char const* nameForLocale = i_cInfo->Name;
if (loc_idx >= 0) sObjectMgr.GetCreatureLocaleStrings(i_cInfo->Entry, loc_idx, &nameForLocale);
{
CreatureLocale const *cl = sObjectMgr.GetCreatureLocale(i_cInfo->Entry);
if (cl)
{
if (cl->Name.size() > (size_t)loc_idx && !cl->Name[loc_idx].empty())
nameForLocale = cl->Name[loc_idx];
}
}
if (nameForLocale.empty()) WorldObject::BuildMonsterChat(&data, i_senderGuid, i_msgtype, text, i_language, nameForLocale, i_target ? i_target->GetObjectGuid() : ObjectGuid(), i_target ? i_target->GetNameForLocaleIdx(loc_idx) : "");
nameForLocale = i_cInfo->Name;
WorldObject::BuildMonsterChat(&data, i_senderGuid, i_msgtype, text, i_language, nameForLocale.c_str(), i_target ? i_target->GetObjectGuid() : ObjectGuid(), i_target ? i_target->GetNameForLocaleIdx(loc_idx) : "");
} }
private: private:

View file

@ -69,9 +69,11 @@ struct GossipTextOption
QEmote Emotes[3]; QEmote Emotes[3];
}; };
#define MAX_GOSSIP_TEXT_OPTIONS 8
struct GossipText struct GossipText
{ {
GossipTextOption Options[8]; GossipTextOption Options[MAX_GOSSIP_TEXT_OPTIONS];
}; };
#endif #endif

View file

@ -4692,7 +4692,7 @@ void ObjectMgr::LoadGossipText()
GossipText& gText = mGossipText[Text_ID]; GossipText& gText = mGossipText[Text_ID];
for (int i = 0; i < 8; ++i) for (int i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
{ {
gText.Options[i].Text_0 = fields[cic++].GetCppString(); gText.Options[i].Text_0 = fields[cic++].GetCppString();
gText.Options[i].Text_1 = fields[cic++].GetCppString(); gText.Options[i].Text_1 = fields[cic++].GetCppString();
@ -8843,6 +8843,85 @@ void ObjectMgr::RemoveArenaTeam( uint32 Id )
mArenaTeamMap.erase(Id); mArenaTeamMap.erase(Id);
} }
void ObjectMgr::GetCreatureLocaleStrings(uint32 entry, int32 loc_idx, char const** namePtr, char const** subnamePtr) const
{
if (loc_idx >= 0)
{
if (CreatureLocale const *il = GetCreatureLocale(entry))
{
if (namePtr && il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty())
*namePtr = il->Name[loc_idx].c_str();
if (subnamePtr && il->SubName.size() > size_t(loc_idx) && !il->SubName[loc_idx].empty())
*subnamePtr = il->SubName[loc_idx].c_str();
}
}
}
void ObjectMgr::GetItemLocaleStrings(uint32 entry, int32 loc_idx, std::string* namePtr, std::string* descriptionPtr) const
{
if (loc_idx >= 0)
{
if(ItemLocale const *il = GetItemLocale(entry))
{
if (namePtr && il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty())
*namePtr = il->Name[loc_idx];
if (descriptionPtr && il->Description.size() > size_t(loc_idx) && !il->Description[loc_idx].empty())
*descriptionPtr = il->Description[loc_idx];
}
}
}
void ObjectMgr::GetQuestLocaleStrings(uint32 entry, int32 loc_idx, std::string* titlePtr) const
{
if (loc_idx >= 0)
{
if(QuestLocale const *il = GetQuestLocale(entry))
{
if (titlePtr && il->Title.size() > size_t(loc_idx) && !il->Title[loc_idx].empty())
*titlePtr = il->Title[loc_idx];
}
}
}
void ObjectMgr::GetNpcTextLocaleStringsAll(uint32 entry, int32 loc_idx, ObjectMgr::NpcTextArray* text0_Ptr, ObjectMgr::NpcTextArray* text1_Ptr) const
{
if (loc_idx >= 0)
{
if (NpcTextLocale const *nl = GetNpcTextLocale(entry))
{
if (text0_Ptr)
for (int i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
if (nl->Text_0[i].size() > (size_t)loc_idx && !nl->Text_0[i][loc_idx].empty())
(*text0_Ptr)[i] = nl->Text_0[i][loc_idx];
if (text1_Ptr)
for (int i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
if (nl->Text_1[i].size() > (size_t)loc_idx && !nl->Text_1[i][loc_idx].empty())
(*text1_Ptr)[i] = nl->Text_1[i][loc_idx];
}
}
}
void ObjectMgr::GetNpcTextLocaleStrings0(uint32 entry, int32 loc_idx, std::string* text0_0_Ptr, std::string* text1_0_Ptr) const
{
if (loc_idx >= 0)
{
if (NpcTextLocale const *nl = GetNpcTextLocale(entry))
{
if (text0_0_Ptr)
if (nl->Text_0[0].size() > (size_t)loc_idx && !nl->Text_0[0][loc_idx].empty())
*text0_0_Ptr = nl->Text_0[0][loc_idx];
if (text1_0_Ptr)
if (nl->Text_1[0].size() > (size_t)loc_idx && !nl->Text_1[0][loc_idx].empty())
*text1_0_Ptr = nl->Text_1[0][loc_idx];
}
}
}
// Functions for scripting access // Functions for scripting access
bool LoadMangosStrings(DatabaseType& db, char const* table,int32 start_value, int32 end_value) bool LoadMangosStrings(DatabaseType& db, char const* table,int32 start_value, int32 end_value)
{ {

View file

@ -785,6 +785,8 @@ class ObjectMgr
return &itr->second; return &itr->second;
} }
void GetCreatureLocaleStrings(uint32 entry, int32 loc_idx, char const** namePtr, char const** subnamePtr = NULL) const;
GameObjectLocale const* GetGameObjectLocale(uint32 entry) const GameObjectLocale const* GetGameObjectLocale(uint32 entry) const
{ {
GameObjectLocaleMap::const_iterator itr = mGameObjectLocaleMap.find(entry); GameObjectLocaleMap::const_iterator itr = mGameObjectLocaleMap.find(entry);
@ -799,6 +801,8 @@ class ObjectMgr
return &itr->second; return &itr->second;
} }
void GetItemLocaleStrings(uint32 entry, int32 loc_idx, std::string* namePtr, std::string* descriptionPtr = NULL) const;
QuestLocale const* GetQuestLocale(uint32 entry) const QuestLocale const* GetQuestLocale(uint32 entry) const
{ {
QuestLocaleMap::const_iterator itr = mQuestLocaleMap.find(entry); QuestLocaleMap::const_iterator itr = mQuestLocaleMap.find(entry);
@ -806,6 +810,8 @@ class ObjectMgr
return &itr->second; return &itr->second;
} }
void GetQuestLocaleStrings(uint32 entry, int32 loc_idx, std::string* titlePtr) const;
NpcTextLocale const* GetNpcTextLocale(uint32 entry) const NpcTextLocale const* GetNpcTextLocale(uint32 entry) const
{ {
NpcTextLocaleMap::const_iterator itr = mNpcTextLocaleMap.find(entry); NpcTextLocaleMap::const_iterator itr = mNpcTextLocaleMap.find(entry);
@ -813,6 +819,10 @@ class ObjectMgr
return &itr->second; return &itr->second;
} }
typedef std::string NpcTextArray[MAX_GOSSIP_TEXT_OPTIONS];
void GetNpcTextLocaleStringsAll(uint32 entry, int32 loc_idx, NpcTextArray *text0_Ptr, NpcTextArray* text1_Ptr) const;
void GetNpcTextLocaleStrings0(uint32 entry, int32 loc_idx, std::string* text0_0_Ptr, std::string* text1_0_Ptr) const;
PageTextLocale const* GetPageTextLocale(uint32 entry) const PageTextLocale const* GetPageTextLocale(uint32 entry) const
{ {
PageTextLocaleMap::const_iterator itr = mPageTextLocaleMap.find(entry); PageTextLocaleMap::const_iterator itr = mPageTextLocaleMap.find(entry);

View file

@ -324,25 +324,18 @@ void WorldSession::SendPetNameQuery(ObjectGuid petguid, uint32 petnumber)
return; return;
} }
std::string name = pet->GetName(); char const* name = pet->GetName();
// creature pets have localization like other creatures // creature pets have localization like other creatures
if (!pet->GetOwnerGuid().IsPlayer()) if (!pet->GetOwnerGuid().IsPlayer())
{ {
int loc_idx = GetSessionDbLocaleIndex(); int loc_idx = GetSessionDbLocaleIndex();
if (loc_idx >= 0) sObjectMgr.GetCreatureLocaleStrings(pet->GetEntry(), loc_idx, &name);
{
if (CreatureLocale const *cl = sObjectMgr.GetCreatureLocale(pet->GetEntry()))
{
if (cl->Name.size() > size_t(loc_idx) && !cl->Name[loc_idx].empty())
name = cl->Name[loc_idx];
}
}
} }
WorldPacket data(SMSG_PET_NAME_QUERY_RESPONSE, (4+4+name.size()+1)); WorldPacket data(SMSG_PET_NAME_QUERY_RESPONSE, (4+4+strlen(name)+1));
data << uint32(petnumber); data << uint32(petnumber);
data << name.c_str(); data << name;
data << uint32(pet->GetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP)); data << uint32(pet->GetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP));
if (pet->IsPet() && ((Pet*)pet)->GetDeclinedNames()) if (pet->IsPet() && ((Pet*)pet)->GetDeclinedNames())

View file

@ -13528,36 +13528,13 @@ void Player::SendPreparedQuest(ObjectGuid guid)
{ {
qe = gossiptext->Options[0].Emotes[0]; qe = gossiptext->Options[0].Emotes[0];
if(!gossiptext->Options[0].Text_0.empty()) int loc_idx = GetSession()->GetSessionDbLocaleIndex();
{
title = gossiptext->Options[0].Text_0;
int loc_idx = GetSession()->GetSessionDbLocaleIndex(); std::string title0 = gossiptext->Options[0].Text_0;
if (loc_idx >= 0) std::string title1 = gossiptext->Options[0].Text_1;
{ sObjectMgr.GetNpcTextLocaleStrings0(textid, loc_idx, &title0, &title1);
NpcTextLocale const *nl = sObjectMgr.GetNpcTextLocale(textid);
if (nl)
{
if ((int32)nl->Text_0[0].size() > loc_idx && !nl->Text_0[0][loc_idx].empty())
title = nl->Text_0[0][loc_idx];
}
}
}
else
{
title = gossiptext->Options[0].Text_1;
int loc_idx = GetSession()->GetSessionDbLocaleIndex(); title = !title0.empty() ? title0 : title1;
if (loc_idx >= 0)
{
NpcTextLocale const *nl = sObjectMgr.GetNpcTextLocale(textid);
if (nl)
{
if ((int32)nl->Text_1[0].size() > loc_idx && !nl->Text_1[0][loc_idx].empty())
title = nl->Text_1[0][loc_idx];
}
}
}
} }
} }
PlayerTalkClass->SendQuestGiverQuestList(qe, title, guid); PlayerTalkClass->SendQuestGiverQuestList(qe, title, guid);
@ -15223,22 +15200,13 @@ void Player::SendQuestConfirmAccept(const Quest* pQuest, Player* pReceiver)
{ {
if (pReceiver) if (pReceiver)
{ {
std::string strTitle = pQuest->GetTitle();
int loc_idx = pReceiver->GetSession()->GetSessionDbLocaleIndex(); int loc_idx = pReceiver->GetSession()->GetSessionDbLocaleIndex();
std::string title = pQuest->GetTitle();
sObjectMgr.GetQuestLocaleStrings(pQuest->GetQuestId(), loc_idx, &title);
if (loc_idx >= 0) WorldPacket data(SMSG_QUEST_CONFIRM_ACCEPT, (4 + title.size() + 8));
{
if (const QuestLocale* pLocale = sObjectMgr.GetQuestLocale(pQuest->GetQuestId()))
{
if ((int32)pLocale->Title.size() > loc_idx && !pLocale->Title[loc_idx].empty())
strTitle = pLocale->Title[loc_idx];
}
}
WorldPacket data(SMSG_QUEST_CONFIRM_ACCEPT, (4 + strTitle.size() + 8));
data << uint32(pQuest->GetQuestId()); data << uint32(pQuest->GetQuestId());
data << strTitle; data << title;
data << GetObjectGuid(); data << GetObjectGuid();
pReceiver->GetSession()->SendPacket(&data); pReceiver->GetSession()->SendPacket(&data);

View file

@ -154,29 +154,19 @@ void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data )
CreatureInfo const *ci = ObjectMgr::GetCreatureTemplate(entry); CreatureInfo const *ci = ObjectMgr::GetCreatureTemplate(entry);
if (ci) if (ci)
{ {
std::string Name, SubName;
Name = ci->Name;
SubName = ci->SubName;
int loc_idx = GetSessionDbLocaleIndex(); int loc_idx = GetSessionDbLocaleIndex();
if (loc_idx >= 0)
{ char const* name = ci->Name;
CreatureLocale const *cl = sObjectMgr.GetCreatureLocale(entry); char const* subName = ci->SubName;
if (cl) sObjectMgr.GetCreatureLocaleStrings(entry, loc_idx, &name, &subName);
{
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); DETAIL_LOG("WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name, entry);
// guess size // guess size
WorldPacket data( SMSG_CREATURE_QUERY_RESPONSE, 100 ); WorldPacket data( SMSG_CREATURE_QUERY_RESPONSE, 100 );
data << uint32(entry); // creature entry data << uint32(entry); // creature entry
data << Name; data << name;
data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty
data << SubName; data << subName;
data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0 data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0
data << uint32(ci->type_flags); // flags data << uint32(ci->type_flags); // flags
data << uint32(ci->type); // CreatureType.dbc data << uint32(ci->type); // CreatureType.dbc
@ -337,7 +327,7 @@ void WorldSession::HandleNpcTextQueryOpcode( WorldPacket & recv_data )
if (!pGossip) if (!pGossip)
{ {
for(uint32 i = 0; i < 8; ++i) for(uint32 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
{ {
data << float(0); data << float(0);
data << "Greetings $N"; data << "Greetings $N";
@ -353,39 +343,27 @@ void WorldSession::HandleNpcTextQueryOpcode( WorldPacket & recv_data )
} }
else else
{ {
std::string Text_0[8], Text_1[8]; std::string Text_0[MAX_GOSSIP_TEXT_OPTIONS], Text_1[MAX_GOSSIP_TEXT_OPTIONS];
for (int i = 0; i < 8; ++i) for (int i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
{ {
Text_0[i]=pGossip->Options[i].Text_0; Text_0[i]=pGossip->Options[i].Text_0;
Text_1[i]=pGossip->Options[i].Text_1; Text_1[i]=pGossip->Options[i].Text_1;
} }
int loc_idx = GetSessionDbLocaleIndex(); 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) sObjectMgr.GetNpcTextLocaleStringsAll(textID, loc_idx, &Text_0, &Text_1);
for (int i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
{ {
data << pGossip->Options[i].Probability; data << pGossip->Options[i].Probability;
if ( Text_0[i].empty() ) if (Text_0[i].empty())
data << Text_1[i]; data << Text_1[i];
else else
data << Text_0[i]; data << Text_0[i];
if ( Text_1[i].empty() ) if (Text_1[i].empty())
data << Text_0[i]; data << Text_0[i];
else else
data << Text_1[i]; data << Text_1[i];

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "11742" #define REVISION_NR "11743"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__