All pastes #730525 Raw Edit

Full localization by Neo2003 rev

public diff v1 · immutable
·published 2007-10-09 09:09 UTC
rendered paste body
Index: src/game/Creature.h===================================================================--- src/game/Creature.h	(revision 4577)+++ src/game/Creature.h	(working copy)@@ -203,6 +203,13 @@     char const* ScriptName; }; +struct CreatureLocale+{+    uint32 Entry;+    std::string Name[8];+    std::string SubName[8];+};+ struct EquipmentInfo {     uint32  entry;Index: src/game/GameObject.h===================================================================--- src/game/GameObject.h	(revision 4577)+++ src/game/GameObject.h	(working copy)@@ -68,6 +68,12 @@     char   *ScriptName; }; +struct GameObjectLocale+{+    uint32 Entry;+    std::string Name[8];+};+ // from `ganeobject` struct GameObjectData {Index: src/game/GossipDef.cpp===================================================================--- src/game/GossipDef.cpp	(revision 4577)+++ src/game/GossipDef.cpp	(working copy)@@ -135,7 +135,17 @@         data << questID;         data << uint32( pQuestMenu->GetItem(iI).m_qIcon );         data << uint32( pQuest ? pQuest->GetQuestLevel() : 0 );-        data << (pQuest ? pQuest->GetTitle() : "");+        std::string Title = pQuest->GetTitle();+        if (pSession->GetSessionLanguage()>0)+        {+            QuestLocale const *ql = objmgr.GetQuestLocale(questID);+            if (ql)+            {+                if (ql->Title[pSession->GetSessionLanguage()]!="")+                    Title=ql->Title[pSession->GetSessionLanguage()];+            }+        }+        data << Title;     }      pSession->SendPacket( &data );@@ -178,34 +188,54 @@         data << uint32( 0 );         data << "Greetings $N";         data << "Greetings $N";-    } else+    } 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;+        } -    for (int i=0; i<8; i++)-    {-        data << pGossip->Options[i].Probability;+        if (pSession->GetSessionLanguage()>0)+        {+            NpcTextLocale const *nl = objmgr.GetNpcTextLocale(textID);+            if (nl)+            {+                for (int i=0;i<8;i++)+                {+                    if (nl->Text_0[i][pSession->GetSessionLanguage()]!="")+                        Text_0[i]=nl->Text_0[i][pSession->GetSessionLanguage()];+                    if (nl->Text_1[i][pSession->GetSessionLanguage()]!="")+                        Text_1[i]=nl->Text_1[i][pSession->GetSessionLanguage()];+                }+            }+        }+        for (int i=0; i<8; i++)+        {+            data << pGossip->Options[i].Probability; -        if ( pGossip->Options[i].Text_0 == "" )-            data << pGossip->Options[i].Text_1;-        else-            data << pGossip->Options[i].Text_0;+            if ( Text_0[i] == "" )+                data << Text_1[i];+            else+                data << Text_0[i]; -        if ( pGossip->Options[i].Text_1 == "" )-            data << pGossip->Options[i].Text_0; -        else-            data << pGossip->Options[i].Text_1;+            if ( Text_1[i] == "" )+                data << Text_0[i]; +            else+                data << Text_1[i]; -        data << pGossip->Options[i].Language;+            data << pGossip->Options[i].Language; -        data << pGossip->Options[i].Emotes[0]._Delay;-        data << pGossip->Options[i].Emotes[0]._Emote;+            data << pGossip->Options[i].Emotes[0]._Delay;+            data << pGossip->Options[i].Emotes[0]._Emote; -        data << pGossip->Options[i].Emotes[1]._Delay;-        data << pGossip->Options[i].Emotes[1]._Emote;+            data << pGossip->Options[i].Emotes[1]._Delay;+            data << pGossip->Options[i].Emotes[1]._Emote; -        data << pGossip->Options[i].Emotes[2]._Delay;-        data << pGossip->Options[i].Emotes[2]._Emote;+            data << pGossip->Options[i].Emotes[2]._Delay;+            data << pGossip->Options[i].Emotes[2]._Emote;+        }     }-     pSession->SendPacket( &data );      sLog.outDetail( "WORLD: Sent SMSG_NPC_TEXT_UPDATE " );@@ -308,9 +338,28 @@ {     WorldPacket data(SMSG_QUESTGIVER_QUEST_DETAILS, 100);   // guess size +    std::string Title,Details,Objectives,EndText;+    Title = pQuest->GetTitle();+    Details = pQuest->GetDetails();+    Objectives = pQuest->GetObjectives();+    EndText = pQuest->GetEndText();+    if (pSession->GetSessionLanguage()>0)+    {+        QuestLocale const *ql = objmgr.GetQuestLocale(pQuest->GetQuestId());+        if (ql)+        {+            if (ql->Title[pSession->GetSessionLanguage()]!="")+                Title=ql->Title[pSession->GetSessionLanguage()];+            if (ql->Details[pSession->GetSessionLanguage()]!="")+                Details=ql->Details[pSession->GetSessionLanguage()];+            if (ql->Objectives[pSession->GetSessionLanguage()]!="")+                Objectives=ql->Objectives[pSession->GetSessionLanguage()];+        }+    }+     data << npcGUID;-    data << pQuest->GetQuestId() << pQuest->GetTitle() << pQuest->GetDetails();-    data << pQuest->GetObjectives();+    data << pQuest->GetQuestId() << Title << Details;+    data << Objectives;     data << (uint32)ActivateAccept;     data << pQuest->GetSuggestedPlayers(); @@ -379,6 +428,31 @@  void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest ) {+    std::string Title,Details,Objectives,EndText;+    std::string ObjectiveText[QUEST_OBJECTIVES_COUNT];+    Title = pQuest->GetTitle();+    Details = pQuest->GetDetails();+    Objectives = pQuest->GetObjectives();+    EndText = pQuest->GetEndText();+    for (int i=0;i<QUEST_OBJECTIVES_COUNT;i++)+        ObjectiveText[i]=pQuest->ObjectiveText[i];+    if (pSession->GetSessionLanguage()>0)+    {+        QuestLocale const *ql = objmgr.GetQuestLocale(pQuest->GetQuestId());+        if (ql)+        {+            if (ql->Title[pSession->GetSessionLanguage()]!="")+                Title=ql->Title[pSession->GetSessionLanguage()];+            if (ql->Details[pSession->GetSessionLanguage()]!="")+                Details=ql->Details[pSession->GetSessionLanguage()];+            if (ql->Objectives[pSession->GetSessionLanguage()]!="")+                Objectives=ql->Objectives[pSession->GetSessionLanguage()];+            for (int i=0;i<QUEST_OBJECTIVES_COUNT;i++)+                if (ql->ObjectiveText[i][pSession->GetSessionLanguage()]!="")+                    ObjectiveText[i]=ql->ObjectiveText[i][pSession->GetSessionLanguage()];+        }+    }+     WorldPacket data( SMSG_QUEST_QUERY_RESPONSE, 100 );     // guess size      data << uint32(pQuest->GetQuestId());@@ -439,10 +513,10 @@     data << pQuest->GetPointY();     data << pQuest->GetPointOpt(); -    data << pQuest->GetTitle();-    data << pQuest->GetObjectives();-    data << pQuest->GetDetails();-    data << pQuest->GetEndText();+    data << Title;+    data << Objectives;+    data << Details;+    data << EndText;      for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; iI++)     {@@ -461,7 +535,7 @@     }      for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; iI++)-        data << pQuest->ObjectiveText[iI];+        data << ObjectiveText[iI];      pSession->SendPacket( &data );     //sLog.outDebug( "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u",pQuest->GetQuestId() );@@ -473,12 +547,27 @@     if(!qInfo)         return; +    std::string Title,OfferRewardText;+    Title = qInfo->GetTitle();+    OfferRewardText = qInfo->GetOfferRewardText();+    if (pSession->GetSessionLanguage()>0)+    {+        QuestLocale const *ql = objmgr.GetQuestLocale(quest_id);+        if (ql)+        {+            if (ql->Title[pSession->GetSessionLanguage()]!="")+                Title=ql->Title[pSession->GetSessionLanguage()];+            if (ql->OfferRewardText[pSession->GetSessionLanguage()]!="")+                OfferRewardText=ql->OfferRewardText[pSession->GetSessionLanguage()];+        }+    }+     WorldPacket data( SMSG_QUESTGIVER_OFFER_REWARD, 50 );   // guess size      data << npcGUID;     data << quest_id;-    data << qInfo->GetTitle();-    data << qInfo->GetOfferRewardText();+    data << Title;+    data << OfferRewardText;      data << uint32( EnbleNext ); @@ -563,18 +652,33 @@     // items.  Otherwise, we'll skip straight to the OfferReward      // We may wish a better check, perhaps checking the real quest requirements-    if (strlen(pQuest->GetRequestItemsText()) == 0)+    if (pQuest->GetRequestItemsText().size() == 0)     {         SendQuestGiverOfferReward(pQuest->GetQuestId(), npcGUID, true);         return;     } +    std::string Title,RequestItemsText;+    Title = pQuest->GetTitle();+    RequestItemsText = pQuest->GetRequestItemsText();+    if (pSession->GetSessionLanguage()>0)+    {+        QuestLocale const *ql = objmgr.GetQuestLocale(pQuest->GetQuestId());+        if (ql)+        {+            if (ql->Title[pSession->GetSessionLanguage()]!="")+                Title=ql->Title[pSession->GetSessionLanguage()];+            if (ql->RequestItemsText[pSession->GetSessionLanguage()]!="")+                RequestItemsText=ql->RequestItemsText[pSession->GetSessionLanguage()];+        }+    }+     WorldPacket data( SMSG_QUESTGIVER_REQUEST_ITEMS, 50 );  // guess size     data << npcGUID;     data << pQuest->GetQuestId();-    data << pQuest->GetTitle();+    data << Title; -    data << pQuest->GetRequestItemsText();+    data << RequestItemsText;      data << uint32(0x00);                                   // unk Index: src/game/ItemHandler.cpp===================================================================--- src/game/ItemHandler.cpp	(revision 4577)+++ src/game/ItemHandler.cpp	(working copy)@@ -203,6 +203,20 @@      if( pProto )     {+        std::string Name, Description;+        Name = pProto->Name1;+        Description = pProto->Description;+        if (GetSessionLanguage()>0)+        {+            ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);+            if (il)+            {+                if (il->Name[GetSessionLanguage()]!="") // default to english+                    Name = il->Name[GetSessionLanguage()];+                if (il->Description[GetSessionLanguage()]!="") // default to english+                    Description = il->Description[GetSessionLanguage()];+            }+        }         data << pProto->ItemId;         data << pProto->Class; @@ -210,7 +224,7 @@         data << uint32(pProto->Class==ITEM_CLASS_CONSUMABLE ? 0 : pProto->SubClass);          data << uint32(-1);                                 // new 2.0.3, not exist in wdb cache?-        data << pProto->Name1;+        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);@@ -308,7 +322,7 @@             }         }         data << pProto->Bonding;-        data << pProto->Description;+        data << Description;         data << pProto->PageText;         data << pProto->LanguageID;         data << pProto->PageMaterial;@@ -812,10 +826,21 @@     ItemPrototype const *pProto = objmgr.GetItemPrototype( itemid );     if( pProto )     {+        std::string Name;+        Name = pProto->Name1;+        if (GetSessionLanguage()>0)+        {+            ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);+            if (il)+            {+                if (il->Name[GetSessionLanguage()]!="") // default to english+                    Name = il->Name[GetSessionLanguage()];+            }+        }                                                             // guess size         WorldPacket data(SMSG_ITEM_NAME_QUERY_RESPONSE, (4+10));         data << pProto->ItemId;-        data << pProto->Name1;+        data << Name;         SendPacket(&data);         return;     }Index: src/game/ItemPrototype.h===================================================================--- src/game/ItemPrototype.h	(revision 4577)+++ src/game/ItemPrototype.h	(working copy)@@ -523,6 +523,13 @@     uint32 FoodType; }; +struct ItemLocale+{+    uint32 Entry;+    std::string Name[8];+    std::string Description[8];+};+ // GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some paltform #if defined( __GNUC__ ) #pragma pack()Index: src/game/NPCHandler.h===================================================================--- src/game/NPCHandler.h	(revision 4577)+++ src/game/NPCHandler.h	(working copy)@@ -34,6 +34,12 @@     uint32 Next_Page; }; +struct PageTextLocale+{+    uint32 Entry;+    std::string Text[8];+};+ // GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some paltform #if defined( __GNUC__ ) #pragma pack()@@ -61,4 +67,12 @@     uint32 Text_ID;     GossipTextOption Options[8]; };++struct NpcTextLocale+{+    uint32 Entry;+    std::string Text_0[8][8];+    std::string Text_1[8][8];+};+ #endifIndex: src/game/ObjectMgr.cpp===================================================================--- src/game/ObjectMgr.cpp	(revision 4577)+++ src/game/ObjectMgr.cpp	(working copy)@@ -386,6 +386,59 @@     return sCreatureStorage.LookupEntry<CreatureInfo>(id); } +void ObjectMgr::LoadCreatureLocales()+{+    const World::LocalizationMap *Locales = sWorld.GetSupportedLocals();++    World::LocalizationMap::const_iterator itr = Locales->begin();+    std::ostringstream ostr;+    ostr << "`name_loc" << (int)*itr << "`,`subname_loc" << (int)*itr << "`";+    itr++;+    while (itr != Locales->end())+    { +        ostr << ",`name_loc" << (int)*itr << "`,`subname_loc" << (int)*itr << "`";+        itr++;+    }++    QueryResult *result = sDatabase.PQuery("SELECT `entry`,%s FROM `locales_creature`",ostr.str().c_str());++    if(!result)+    {+        barGoLink bar(1);++        bar.step();++        sLog.outString("");+        sLog.outErrorDb(">> Loaded 0 creature locale strings. DB table `locales_creature` is empty.");+        return;+    }++    barGoLink bar(result->GetRowCount());++    do+    {+        Field *fields = result->Fetch();+        bar.step();++        uint32 entry = fields[0].GetUInt32();++        CreatureLocale& data = mCreatureLocaleMap[entry];+        uint16 currentIndex=0;+        for (itr = Locales->begin(); itr != Locales->end(); ++itr)+        {+            data.Name[*itr]   = fields[currentIndex*2+1].GetCppString();+            data.SubName[*itr]= fields[currentIndex*2+2].GetCppString();+            currentIndex++;+        }++    } while (result->NextRow());++    delete result;++    sLog.outString();+    sLog.outString( ">> Loaded %u creature locale strings", mCreatureLocaleMap.size() );+}+ void ObjectMgr::LoadCreatureTemplates() {     sCreatureStorage.Load();@@ -913,6 +966,58 @@     sLog.outString(); } +void ObjectMgr::LoadItemLocales()+{+    const World::LocalizationMap *Locales = sWorld.GetSupportedLocals();++    World::LocalizationMap::const_iterator itr = Locales->begin();+    std::ostringstream ostr;+    ostr << "`name_loc" << (int)*itr << "`,`description_loc" << (int)*itr << "`";+    itr++;+    while (itr != Locales->end())+    { +        ostr << ",`name_loc" << (int)*itr << "`,`description_loc" << (int)*itr << "`";+        itr++;+    }++    QueryResult *result = sDatabase.PQuery("SELECT `entry`,%s FROM `locales_item`",ostr.str().c_str());++    if(!result)+    {+        barGoLink bar(1);++        bar.step();++        sLog.outString("");+        sLog.outErrorDb(">> Loaded 0 Item locale strings. DB table `locales_item` is empty.");+        return;+    }++    barGoLink bar(result->GetRowCount());++    do+    {+        Field *fields = result->Fetch();+        bar.step();++        uint32 entry = fields[0].GetUInt32();++        ItemLocale& data = mItemLocaleMap[entry];+        uint16 currentIndex=0;+        for (itr = Locales->begin(); itr != Locales->end(); ++itr)+        {+            data.Name[*itr]   = fields[currentIndex*2+1].GetCppString();+            data.Description[*itr]= fields[currentIndex*2+2].GetCppString();+            currentIndex++;+        }+    } while (result->NextRow());++    delete result;++    sLog.outString();+    sLog.outString( ">> Loaded %u Item locale strings", mItemLocaleMap.size() );+}+ void ObjectMgr::LoadItemPrototypes() {     sItemStorage.Load ();@@ -2133,6 +2238,69 @@     sLog.outString( ">> Loaded %u quests definitions", mQuestTemplates.size() ); } +void ObjectMgr::LoadQuestLocales()+{+    const World::LocalizationMap *Locales = sWorld.GetSupportedLocals();++    World::LocalizationMap::const_iterator itr = Locales->begin();+    std::ostringstream ostr;+    ostr << "`Title_loc" << (int)*itr << "`,`Details_loc" << (int)*itr << "`,`Objectives_loc" << (int)*itr;+    ostr << "`,`OfferRewardText_loc" << (int)*itr << "`,`RequestItemsText_loc" << (int)*itr << "`,`EndText_loc" << (int)*itr;+    ostr << "`,`ObjectiveText1_loc" << (int)*itr <<  "`,`ObjectiveText2_loc" << (int)*itr <<  "`,`ObjectiveText3_loc" << (int)*itr <<  "`,`ObjectiveText4_loc" << (int)*itr << "`";+    +    itr++;+    while (itr != Locales->end())+    { +        ostr << ",`Title_loc" << (int)*itr << "`,`Details_loc" << (int)*itr << "`,`Objectives_loc" << (int)*itr;+        ostr << "`,`OfferRewardText_loc" << (int)*itr << "`,`RequestItemsText_loc" << (int)*itr << "`,`EndText_loc" << (int)*itr;+        ostr << "`,`ObjectiveText1_loc" << (int)*itr <<  "`,`ObjectiveText2_loc" << (int)*itr <<  "`,`ObjectiveText3_loc" << (int)*itr <<  "`,`ObjectiveText4_loc" << (int)*itr << "`";+        itr++;+    }++    QueryResult *result = sDatabase.PQuery("SELECT `entry`,%s FROM `locales_quest`",ostr.str().c_str());++    if(!result)+    {+        barGoLink bar(1);++        bar.step();++        sLog.outString("");+        sLog.outErrorDb(">> Loaded 0 Quest locale strings. DB table `locales_quest` is empty.");+        return;+    }++    barGoLink bar(result->GetRowCount());++    do+    {+        Field *fields = result->Fetch();+        bar.step();++        uint32 entry = fields[0].GetUInt32();++        QuestLocale& data = mQuestLocaleMap[entry];+        uint16 currentIndex=0;+        for (itr = Locales->begin(); itr != Locales->end(); ++itr)+        {+            data.Title[*itr]            = fields[currentIndex*10+1].GetCppString();+            data.Details[*itr]          = fields[currentIndex*10+2].GetCppString();+            data.Objectives[*itr]       = fields[currentIndex*10+3].GetCppString();+            data.OfferRewardText[*itr]  = fields[currentIndex*10+4].GetCppString();+            data.RequestItemsText[*itr] = fields[currentIndex*10+5].GetCppString();+            data.EndText[*itr]          = fields[currentIndex*10+2].GetCppString();+            for (int i=0;i<4;i++)+                data.ObjectiveText[i][*itr] = fields[currentIndex*10+6+i].GetCppString();+            currentIndex++;+        }+    } while (result->NextRow());++    delete result;++    sLog.outString();+    sLog.outString( ">> Loaded %u Quest locale strings", mQuestLocaleMap.size() );+}+ void ObjectMgr::LoadSpellChains() {     mSpellChains.clear();                                   // need for reload case@@ -2716,6 +2884,58 @@     sLog.outString(); } +void ObjectMgr::LoadPageTextLocales()+{+    const World::LocalizationMap *Locales = sWorld.GetSupportedLocals();++    World::LocalizationMap::const_iterator itr = Locales->begin();+    std::ostringstream ostr;+    ostr << "`text_loc" << (int)*itr << "`";+    itr++;+    while (itr != Locales->end())+    { +        ostr << ",`text_loc" << (int)*itr << "`";+        itr++;+    }++    QueryResult *result = sDatabase.PQuery("SELECT `entry`,%s FROM `locales_page_text`",ostr.str().c_str());++    if(!result)+    {+        barGoLink bar(1);++        bar.step();++        sLog.outString("");+        sLog.outErrorDb(">> Loaded 0 PageText locale strings. DB table `locales_page_text` is empty.");+        return;+    }++    barGoLink bar(result->GetRowCount());++    do+    {+        Field *fields = result->Fetch();+        bar.step();++        uint32 entry = fields[0].GetUInt32();++        PageTextLocale& data = mPageTextLocaleMap[entry];+        uint16 currentIndex=0;+        for (itr = Locales->begin(); itr != Locales->end(); ++itr)+        {+            data.Text[*itr]   = fields[currentIndex+1].GetCppString();+            currentIndex++;+        }++    } while (result->NextRow());++    delete result;++    sLog.outString();+    sLog.outString( ">> Loaded %u PageText locale strings", mPageTextLocaleMap.size() );+}+ void ObjectMgr::AddGossipText(GossipText *pGText) {     ASSERT( pGText->Text_ID );@@ -2794,6 +3014,64 @@     delete result; } +void ObjectMgr::LoadNpcTextLocales()+{+    const World::LocalizationMap *Locales = sWorld.GetSupportedLocals();++    World::LocalizationMap::const_iterator itr = Locales->begin();+    std::ostringstream ostr;+    ostr << "`Text0_0_loc" << (int)*itr << "`,`Text0_1_loc" << (int)*itr << "`";+    for (int i=1;i<8;i++)+        ostr << ",`Text" << i << "_0_loc" << (int)*itr << "`,`Text" << i << "_1_loc" << (int)*itr << "`";+    itr++;+    while (itr != Locales->end())+    {+        for (int i=0;i<8;i++)+            ostr << ",`Text" << i << "_0_loc" << (int)*itr << "`,`Text" << i << "_1_loc" << (int)*itr << "`";+        itr++;+    }++    QueryResult *result = sDatabase.PQuery("SELECT `entry`,%s FROM `locales_npc_text`",ostr.str().c_str());++    if(!result)+    {+        barGoLink bar(1);++        bar.step();++        sLog.outString("");+        sLog.outErrorDb(">> Loaded 0 Quest locale strings. DB table `locales_npc_text` is empty.");+        return;+    }++    barGoLink bar(result->GetRowCount());++    do+    {+        Field *fields = result->Fetch();+        bar.step();++        uint32 entry = fields[0].GetUInt32();++        NpcTextLocale& data = mNpcTextLocaleMap[entry];+        uint16 currentIndex=0;+        for (itr = Locales->begin(); itr != Locales->end(); ++itr)+        {+            for (int i=0;i<8;i++)+            {+                data.Text_0[i][*itr]         = fields[currentIndex*16+1+i*2].GetCppString();+                data.Text_1[i][*itr]         = fields[currentIndex*16+2+i*2].GetCppString();+            }+            currentIndex++;+        }+    } while (result->NextRow());++    delete result;++    sLog.outString();+    sLog.outString( ">> Loaded %u NpcText locale strings", mNpcTextLocaleMap.size() );+}+ //not very fast function but it is called only once a day, or on starting-up void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp) {@@ -3513,6 +3791,58 @@     return 0; } +void ObjectMgr::LoadGameObjectLocales()+{+    const World::LocalizationMap *Locales = sWorld.GetSupportedLocals();++    World::LocalizationMap::const_iterator itr = Locales->begin();+    std::ostringstream ostr;+    ostr << "`name_loc" << (int)*itr << "`";+    itr++;+    while (itr != Locales->end())+    { +        ostr << ",`name_loc" << (int)*itr << "`";+        itr++;+    }++    QueryResult *result = sDatabase.PQuery("SELECT `entry`,%s FROM `locales_gameobject`",ostr.str().c_str());++    if(!result)+    {+        barGoLink bar(1);++        bar.step();++        sLog.outString("");+        sLog.outErrorDb(">> Loaded 0 gameobject locale strings. DB table `locales_gameobject` is empty.");+        return;+    }++    barGoLink bar(result->GetRowCount());++    do+    {+        Field *fields = result->Fetch();+        bar.step();++        uint32 entry = fields[0].GetUInt32();++        GameObjectLocale& data = mGameObjectLocaleMap[entry];+        uint16 currentIndex=0;+        for (itr = Locales->begin(); itr != Locales->end(); ++itr)+        {+            data.Name[*itr]   = fields[currentIndex+1].GetCppString();+            currentIndex++;+        }++    } while (result->NextRow());++    delete result;++    sLog.outString();+    sLog.outString( ">> Loaded %u gameobject locale strings", mGameObjectLocaleMap.size() );+}+ void ObjectMgr::LoadGameobjectInfo() {     sGOStorage.Load();Index: src/game/ObjectMgr.h===================================================================--- src/game/ObjectMgr.h	(revision 4577)+++ src/game/ObjectMgr.h	(working copy)@@ -112,6 +112,12 @@  typedef HM_NAMESPACE::hash_map<uint32,CreatureData> CreatureDataMap; typedef HM_NAMESPACE::hash_map<uint32,GameObjectData> GameObjectDataMap;+typedef HM_NAMESPACE::hash_map<uint32,CreatureLocale> CreatureLocaleMap;+typedef HM_NAMESPACE::hash_map<uint32,GameObjectLocale> GameObjectLocaleMap;+typedef HM_NAMESPACE::hash_map<uint32,ItemLocale> ItemLocaleMap;+typedef HM_NAMESPACE::hash_map<uint32,QuestLocale> QuestLocaleMap;+typedef HM_NAMESPACE::hash_map<uint32,NpcTextLocale> NpcTextLocaleMap;+typedef HM_NAMESPACE::hash_map<uint32,PageTextLocale> PageTextLocaleMap;  typedef std::multimap<uint32,uint32> QuestRelations; @@ -415,17 +421,23 @@         void LoadSpellScriptTarget();          void LoadPetCreateSpells();+        void LoadCreatureLocales();         void LoadCreatureTemplates();         void LoadCreatures();         void LoadCreatureRespawnTimes();         void LoadCreatureAddons();         void LoadCreatureModelInfo();         void LoadEquipmentTemplates();+        void LoadGameObjectLocales();         void LoadGameobjects();         void LoadGameobjectRespawnTimes();         void LoadSpellProcEvents();         void LoadSpellThreats();         void LoadItemPrototypes();+        void LoadItemLocales();+        void LoadQuestLocales();+        void LoadNpcTextLocales();+        void LoadPageTextLocales();          void LoadGossipText(); @@ -617,6 +629,43 @@         CreatureData& NewCreatureData(uint32 guid) { return mCreatureDataMap[guid]; }         void DeleteCreatureData(uint32 guid); +        CreatureLocale const* GetCreatureLocale(uint32 entry) const+        {+            CreatureLocaleMap::const_iterator itr = mCreatureLocaleMap.find(entry);+            if(itr==mCreatureLocaleMap.end()) return NULL;+            return &itr->second;+        }+        GameObjectLocale const* GetGameObjectLocale(uint32 entry) const+        {+            GameObjectLocaleMap::const_iterator itr = mGameObjectLocaleMap.find(entry);+            if(itr==mGameObjectLocaleMap.end()) return NULL;+            return &itr->second;+        }+        ItemLocale const* GetItemLocale(uint32 entry) const+        {+            ItemLocaleMap::const_iterator itr = mItemLocaleMap.find(entry);+            if(itr==mItemLocaleMap.end()) return NULL;+            return &itr->second;+        }+        QuestLocale const* GetQuestLocale(uint32 entry) const+        {+            QuestLocaleMap::const_iterator itr = mQuestLocaleMap.find(entry);+            if(itr==mQuestLocaleMap.end()) return NULL;+            return &itr->second;+        }+        NpcTextLocale const* GetNpcTextLocale(uint32 entry) const+        {+            NpcTextLocaleMap::const_iterator itr = mNpcTextLocaleMap.find(entry);+            if(itr==mNpcTextLocaleMap.end()) return NULL;+            return &itr->second;+        }+        PageTextLocale const* GetPageTextLocale(uint32 entry) const+        {+            PageTextLocaleMap::const_iterator itr = mPageTextLocaleMap.find(entry);+            if(itr==mPageTextLocaleMap.end()) return NULL;+            return &itr->second;+        }+         GameObjectData const* GetGOData(uint32 guid) const         {             GameObjectDataMap::const_iterator itr = mGameObjectDataMap.find(guid);@@ -721,7 +770,13 @@          MapObjectGuids mMapObjectGuids;         CreatureDataMap mCreatureDataMap;+        CreatureLocaleMap mCreatureLocaleMap;         GameObjectDataMap mGameObjectDataMap;+        GameObjectLocaleMap mGameObjectLocaleMap;+        ItemLocaleMap mItemLocaleMap;+        QuestLocaleMap mQuestLocaleMap;+        NpcTextLocaleMap mNpcTextLocaleMap;+        PageTextLocaleMap mPageTextLocaleMap;         RespawnTimes mCreatureRespawnTimes;         RespawnTimes mGORespawnTimes; Index: src/game/Player.cpp===================================================================--- src/game/Player.cpp	(revision 4577)+++ src/game/Player.cpp	(working copy)@@ -10447,6 +10447,15 @@                 title = gossiptext->Options[0].Text_0 == "" ? gossiptext->Options[0].Text_1 : gossiptext->Options[0].Text_0;                 if( &title == NULL )                     title = "";+                if (GetSession()->GetSessionLanguage()>0)+                {+                    NpcTextLocale const *nl = objmgr.GetNpcTextLocale(textid);+                    if (nl)+                    {+                        if (nl->Text_0[0][GetSession()->GetSessionLanguage()]!="" || nl->Text_1[0][GetSession()->GetSessionLanguage()]!="")+                            title = nl->Text_0[0][GetSession()->GetSessionLanguage()]=="" ? nl->Text_1[0][GetSession()->GetSessionLanguage()] : nl->Text_0[0][GetSession()->GetSessionLanguage()];+                    }+                }             }         }         PlayerTalkClass->SendQuestGiverQuestList( qe, title, guid );Index: src/game/QueryHandler.cpp===================================================================--- src/game/QueryHandler.cpp	(revision 4577)+++ src/game/QueryHandler.cpp	(working copy)@@ -114,8 +114,6 @@         //    return;     } -    //CreatureInfo const *ci = unit->GetCreatureInfo();-     CreatureInfo const *ci = objmgr.GetCreatureTemplate(entry);      if (!ci)@@ -124,18 +122,38 @@         return;     } +    std::string Name, SubName;+    //CreatureInfo const *ci = unit->GetCreatureInfo();+    Name = ci->Name;+    SubName = ci->SubName;++    if (GetSessionLanguage()>0)+    {+        CreatureLocale const *cl = objmgr.GetCreatureLocale(entry);+        if (cl)+        {+            if (cl->Name[GetSessionLanguage()]!="") // default to english+                Name = cl->Name[GetSessionLanguage()];+            if (cl->SubName[GetSessionLanguage()]!="") // same+                SubName = cl->SubName[GetSessionLanguage()];+        }+    }+     sLog.outDetail("WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u - GUID: %u.", ci->Name, entry, guid);      WorldPacket data( SMSG_CREATURE_QUERY_RESPONSE, 100 );  // guess size     data << (uint32)entry;                                  // creature entry-    data << (unit ? unit->GetName() : ci->Name);            // creature name+    if (unit)+        data << ((unit->isPet()) ? unit->GetName() : Name); // creature name+    else+        data << Name;      data << uint8(0) << uint8(0) << uint8(0);               // name2, name3, name4, always empty      if (unit)-        data << ((unit->isPet()) ? "Pet" : ci->SubName);    // subname+        data << ((unit->isPet()) ? "Pet" : SubName);        // subname     else-        data << ci->SubName;+        data << SubName;      data << ci->flag1;                                      // flags          wdbFeild7=wad flags1 @@ -157,7 +175,7 @@     data << (float)1;                                       // unk     data << (float)1;                                       // unk     data << uint8(ci->civilian);-    data << uint8(0);                                       // boss flag?+    data << uint8(ci->RacialLeader);     SendPacket( &data ); } @@ -171,6 +189,7 @@     recv_data >> entryID;     recv_data >> guid; +    std::string Name;     const GameObjectInfo *info = objmgr.GetGameObjectInfo(entryID);                                                             // guess size     WorldPacket data ( SMSG_GAMEOBJECT_QUERY_RESPONSE, 150 );@@ -181,11 +200,21 @@     }     else     {+        Name = info->name;+        if (GetSessionLanguage()>0)+        {+            GameObjectLocale const *gl = objmgr.GetGameObjectLocale(entryID);+            if (gl)+            {+                if (gl->Name[GetSessionLanguage()]!="") // default to english+                    Name = gl->Name[GetSessionLanguage()];+            }+        }         sLog.outDetail("WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u - GUID: %u.", info->name, entryID, guid);         data << entryID;         data << (uint32)info->type;         data << (uint32)info->displayId;-        data << info->name;+        data << Name;         data << uint8(0) << uint8(0) << uint8(0);           // name2, name3, name4         data << uint8(0);                                   // 2.0.3, string         data << uint8(0);                                   // 2.0.3, string@@ -266,32 +295,54 @@         data << uint32( 0 );         data << "Greetings $N";         data << "Greetings $N";-    } else+    } 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;+        } -    for (int i=0; i<8; i++)-    {-        data << pGossip->Options[i].Probability;+        if (GetSessionLanguage()>0)+        {+            NpcTextLocale const *nl = objmgr.GetNpcTextLocale(textID);+            if (nl)+            {+                for (int i=0;i<8;i++)+                {+                    if (nl->Text_0[i][GetSessionLanguage()]!="")+                        Text_0[i]=nl->Text_0[i][GetSessionLanguage()];+                    if (nl->Text_1[i][GetSessionLanguage()]!="")+                        Text_1[i]=nl->Text_1[i][GetSessionLanguage()];+                }+            }+        } -        if ( pGossip->Options[i].Text_0 == "" )-            data << pGossip->Options[i].Text_1;-        else-            data << pGossip->Options[i].Text_0;+        for (int i=0; i<8; i++)+        {+            data << pGossip->Options[i].Probability; -        if ( pGossip->Options[i].Text_1 == "" )-            data << pGossip->Options[i].Text_0; -        else-            data << pGossip->Options[i].Text_1;+            if ( Text_0[i] == "" )+                data << Text_1[i];+            else+                data << Text_0[i]; -        data << pGossip->Options[i].Language;+            if ( Text_1[i] == "" )+                data << Text_0[i];+            else+                data << Text_1[i]; -        data << pGossip->Options[i].Emotes[0]._Delay;-        data << pGossip->Options[i].Emotes[0]._Emote;+            data << pGossip->Options[i].Language; -        data << pGossip->Options[i].Emotes[1]._Delay;-        data << pGossip->Options[i].Emotes[1]._Emote;+            data << pGossip->Options[i].Emotes[0]._Delay;+            data << pGossip->Options[i].Emotes[0]._Emote; -        data << pGossip->Options[i].Emotes[2]._Delay;-        data << pGossip->Options[i].Emotes[2]._Emote;+            data << pGossip->Options[i].Emotes[1]._Delay;+            data << pGossip->Options[i].Emotes[1]._Emote;++            data << pGossip->Options[i].Emotes[2]._Delay;+            data << pGossip->Options[i].Emotes[2]._Emote;+        }     }      SendPacket( &data );@@ -323,7 +374,17 @@         }         else         {-            data << pPage->Text;+            std::string Text = pPage->Text;+            if (GetSessionLanguage()>0)+            {+                PageTextLocale const *pl = objmgr.GetPageTextLocale(pageID);+                if (pl)+                {+                    if (pl->Text[GetSessionLanguage()]!="")+                        Text = pl->Text[GetSessionLanguage()];+                }+            }+            data << Text;             data << uint32(pPage->Next_Page);             pageID = pPage->Next_Page;         }Index: src/game/QuestDef.h===================================================================--- src/game/QuestDef.h	(revision 4577)+++ src/game/QuestDef.h	(working copy)@@ -126,6 +126,18 @@     //QUEST_SPECIAL_FLAGS_UNK5          = 2048,             // unknown tbc }; +struct QuestLocale+{+    uint32 Entry;+    std::string Title[8];+    std::string Details[8];+    std::string Objectives[8];+    std::string OfferRewardText[8];+    std::string RequestItemsText[8];+    std::string EndText[8];+    std::string ObjectiveText[QUEST_OBJECTIVES_COUNT][8];+};+  // This Quest class provides a convenient way to access a few pretotaled (cached) quest details, // all base quest information, and any utility functions such as generating the amount of // xp to give@@ -147,9 +159,9 @@         uint32 GetRequiredRaces() const { return RequiredRaces; }         uint32 GetRequiredSkillValue() const { return RequiredSkillValue; }         uint32 GetRequiredMinRepFaction() const { return RequiredMinRepFaction; }-         int32 GetRequiredMinRepValue() const { return RequiredMinRepValue; }+        int32  GetRequiredMinRepValue() const { return RequiredMinRepValue; }         uint32 GetRequiredMaxRepFaction() const { return RequiredMaxRepFaction; }-         int32 GetRequiredMaxRepValue() const { return RequiredMaxRepValue; }+        int32  GetRequiredMaxRepValue() const { return RequiredMaxRepValue; }         uint32 GetSuggestedPlayers() const { return SuggestedPlayers; }         uint32 GetLimitTime() const { return LimitTime; }         int32  GetNextQuestId() const { return NextQuestId; }@@ -158,12 +170,12 @@         uint32 GetSrcItemId() const { return SrcItemId; }         uint32 GetSrcItemCount() const { return SrcItemCount; }         uint32 GetSrcSpell() const { return SrcSpell; }-        const char* GetTitle() const { return Title.c_str(); }-        const char* GetDetails() const { return Details.c_str(); }-        const char* GetObjectives() const { return Objectives.c_str(); }-        const char* GetOfferRewardText() const { return OfferRewardText.c_str(); }-        const char* GetRequestItemsText() const { return RequestItemsText.c_str(); }-        const char* GetEndText() const { return EndText.c_str(); }+        std::string GetTitle() const { return Title; }+        std::string GetDetails() const { return Details; }+        std::string GetObjectives() const { return Objectives; }+        std::string GetOfferRewardText() const { return OfferRewardText; }+        std::string GetRequestItemsText() const { return RequestItemsText; }+        std::string GetEndText() const { return EndText; }         int32  GetRewOrReqMoney() const { return RewOrReqMoney; }         uint32 GetRewXpOrMoney() const { return RewXpOrMoney; }         uint32 GetRewSpell() const { return RewSpell; }Index: src/game/World.cpp===================================================================--- src/game/World.cpp	(revision 4577)+++ src/game/World.cpp	(working copy)@@ -475,6 +475,9 @@         exit(1);     } +    std::string localization = sConfig.GetStringDefault("StringLocalize", "");+    FillSupportedLocals(localization);+     ///- Update the realm entry in the database with the realm type from the config file     //No SQL injection as values are treated as integers     loginDatabase.PExecute("UPDATE `realmlist` SET `icon` = %u WHERE `id` = '%d'", m_configs[CONFIG_GAME_TYPE],realmID);@@ -495,6 +498,17 @@     objmgr.PackInstances();      ///- Load static data tables from the database+    if (m_SupportedLocals.size()>0)+    {+        sLog.outString( "Loading Localization strings..." );+        objmgr.LoadCreatureLocales();+        objmgr.LoadGameObjectLocales();+        objmgr.LoadItemLocales();+        objmgr.LoadQuestLocales();+        objmgr.LoadNpcTextLocales();+        objmgr.LoadPageTextLocales();+    }+     sLog.outString( "Loading Game Object Templates..." );     objmgr.LoadGameobjectInfo(); @@ -1647,3 +1661,29 @@         loginDatabase.PExecute("INSERT INTO `realmcharacters` (`numchars`, `acctid`, `realmid`) VALUES (%u, %u, %u) ON DUPLICATE KEY UPDATE `numchars` = '%u'", charCount, accountId, realmID, charCount);     } }++void World::FillSupportedLocals(std::string str)+{+    if(str=="")+    {+        return; // English by default if none selected+    }+    int local;+    std::istringstream ss(str);+    for(int i = 0; i < 8; ++i)+    {+        ss >> local;+        if (local > 0 && local <8)+            SetSupportedLocals((uint8) local);+        if(!ss)+            break;+    }+    if (m_SupportedLocals.empty())+    {+        sLog.outError("Unable to determine your Locales!!");+        exit(1);+    }+    LocalizationMap::const_iterator itr;+    for (itr = m_SupportedLocals.begin(); itr != m_SupportedLocals.end(); ++itr)+        sLog.outString("Support for local %u will be used",*itr);+}Index: src/game/World.h===================================================================--- src/game/World.h	(revision 4577)+++ src/game/World.h	(working copy)@@ -349,11 +349,16 @@          void UpdateRealmCharCount(uint32 accid); +        typedef std::set<uint8> LocalizationMap;+        LocalizationMap const* GetSupportedLocals() const { return &m_SupportedLocals; }+     protected:         void _UpdateGameTime();         void ScriptsProcess();         // callback for UpdateRealmCharacters         void _UpdateRealmCharCount(QueryResult *resultCharCount, uint32 accountId);+        void SetSupportedLocals(uint8 local) { m_SupportedLocals.insert(local); }+        void FillSupportedLocals(std::string str);      private:         time_t m_startTime;@@ -394,6 +399,9 @@         // CLI command holder to be thread safe         ZThread::LockedQueue<CliCommandHolder*, ZThread::FastMutex> cliCmdQueue;         SqlResultQueue *m_resultQueue;++        // Localization+        LocalizationMap m_SupportedLocals; };  extern uint32 realmID;Index: src/game/WorldSession.cpp===================================================================--- src/game/WorldSession.cpp	(revision 4577)+++ src/game/WorldSession.cpp	(working copy)@@ -40,9 +40,9 @@ #include "Chat.h"  /// WorldSession constructor-WorldSession::WorldSession(uint32 id, WorldSocket *sock, uint32 sec, bool tbc, time_t mute_time) :+WorldSession::WorldSession(uint32 id, WorldSocket *sock, uint32 sec, bool tbc, time_t mute_time, uint8 locale) : LookingForGroup_auto_join(false), LookingForGroup_auto_add(false), m_muteTime(mute_time),-_player(NULL), _socket(sock),_security(sec), _accountId(id), m_isTBC(tbc),+_player(NULL), _socket(sock),_security(sec), _accountId(id), m_isTBC(tbc), m_sessionLanguage(locale), _logoutTime(0), m_playerLoading(false), m_playerLogout(false), m_playerRecentlyLogout(false) {     FillOpcodeHandlerHashTable();Index: src/game/WorldSession.h===================================================================--- src/game/WorldSession.h	(revision 4577)+++ src/game/WorldSession.h	(working copy)@@ -64,7 +64,7 @@ {     friend class CharacterHandler;     public:-        WorldSession(uint32 id, WorldSocket *sock, uint32 sec, bool tbc, time_t mute_time);+        WorldSession(uint32 id, WorldSocket *sock, uint32 sec, bool tbc, time_t mute_time, uint8 locale);         ~WorldSession();          bool PlayerLoading() { return m_playerLoading; }@@ -170,6 +170,9 @@          // Account mute time         time_t m_muteTime;++        // Locales+        uint8 GetSessionLanguage() { return m_sessionLanguage; }     protected:          void HandleCharEnumOpcode(WorldPacket& recvPacket);@@ -556,6 +559,7 @@         bool m_playerLoading;                               // code processed in LoginPlayer         bool m_playerLogout;                                // code processed in LogoutPlayer         bool m_playerRecentlyLogout;+        uint8 m_sessionLanguage;          void FillOpcodeHandlerHashTable(); Index: src/game/WorldSocket.cpp===================================================================--- src/game/WorldSocket.cpp	(revision 4577)+++ src/game/WorldSocket.cpp	(working copy)@@ -221,6 +221,7 @@     uint32 unk2;     uint32 BuiltNumberClient;     uint32 id, security;+    uint8  locale;     bool tbc = false;     std::string account;     Sha1Hash sha1;@@ -248,8 +249,8 @@     std::string safe_account=account;                       // Duplicate, else will screw the SHA hash verification below     loginDatabase.escape_string(safe_account);     //No SQL injection, username escaped.-    //                                                 0    1         2            3         4         5           6    7    8     9-    QueryResult *result = loginDatabase.PQuery("SELECT `id`,`gmlevel`,`sessionkey`,`last_ip`,`locked`, `I`, `v`, `s`, `tbc`,`mutetime` FROM `account` WHERE `username` = '%s'", safe_account.c_str());+    //                                                 0    1         2            3         4         5           6    7    8     9   10+    QueryResult *result = loginDatabase.PQuery("SELECT `id`,`gmlevel`,`sessionkey`,`last_ip`,`locked`, `I`, `v`, `s`, `tbc`,`mutetime`,`locale` FROM `account` WHERE `username` = '%s'", safe_account.c_str());      ///- Stop if the account is not found     if ( !result )@@ -321,7 +322,7 @@     security = fields[1].GetUInt16();     K.SetHexStr(fields[2].GetString());     time_t mutetime = time_t(fields[9].GetUInt64());-+    locale = fields[10].GetUInt8();     delete result;      ///- Re-check account ban (same check as in realmd) /// TO DO: why on earth do 2 checks for same thing?@@ -395,7 +396,7 @@     SendPacket(&packet);      ///- Create a new WorldSession for the player and add it to the World-    _session = new WorldSession(id, this,security,tbc,mutetime);+    _session = new WorldSession(id, this,security,tbc,mutetime,locale);     sWorld.AddSession(_session);      if(sLog.IsOutDebug())                                   // optimize disabled debug outputIndex: src/mangosd/mangosd.conf.in===================================================================--- src/mangosd/mangosd.conf.in	(revision 4577)+++ src/mangosd/mangosd.conf.in	(working copy)@@ -54,6 +54,14 @@ # 255 = Auto Detect (Default) DBC.Locale = 255 +# Full localization support activation+# use the same codes as for DBC language to enable localization support in this language+# Be informed that activating it consumes some memory (around 57MB per language activated)+# ex: StringLocalize = "2" will activate French on top of default English+# You can activate several languages like StringLocalize = "2 3" for French and German+# StringLocalize = "" (Default = Disabled)+StringLocalize = ""+ # Enable logging of GM commands - all SQL code will be written to a log file # All commands are written to a file: YYYY-MM-DD_logSQL.sql # If a new day starts (00:00:00) then a new file is created - the oldIndex: src/realmd/AuthSocket.cpp===================================================================--- src/realmd/AuthSocket.cpp	(revision 4577)+++ src/realmd/AuthSocket.cpp	(working copy)@@ -448,6 +448,14 @@                         pkt.append(s.AsByteArray(), s.GetNumBytes());                         pkt.append(unk3.AsByteArray(), 16);                         pkt << (uint8)0;                    // Added in 1.12.x client branch++                        QueryResult *localeresult = dbRealmServer.PQuery("SELECT `locale` FROM `localization` WHERE `string` = '%c%c'",ch->country[3],ch->country[2]);+                        if( localeresult )+                            _localization=(*localeresult)[0].GetUInt8();+                        else+                            _localization=0; ++                        sLog.outBasic("[AuthChallenge] acount %s is using '%c%c' locale (%u)", _login.c_str (), ch->country[3],ch->country[2], _localization);                     }                 }                 delete result;@@ -595,7 +603,7 @@          ///- Update the sessionkey, last_ip and last login time in the account table for this account         // No SQL injection (escaped user name) and IP address as received by socket-        dbRealmServer.PExecute("UPDATE `account` SET `sessionkey` = '%s', `last_ip` = '%s', `last_login` = NOW() WHERE `username` = '%s'",K.AsHexStr(), GetRemoteAddress().c_str(), _safelogin.c_str() );+        dbRealmServer.PExecute("UPDATE `account` SET `sessionkey` = '%s', `last_ip` = '%s', `last_login` = NOW(), `locale` = '%u' WHERE `username` = '%s'",K.AsHexStr(), GetRemoteAddress().c_str(),  _localization, _safelogin.c_str() );          ///- Finish SRP6 and send the final result to the client         sha.Initialize();Index: src/realmd/AuthSocket.h===================================================================--- src/realmd/AuthSocket.h	(revision 4577)+++ src/realmd/AuthSocket.h	(working copy)@@ -68,6 +68,7 @@          std::string _login;         std::string _safelogin;+        uint8 _localization; }; #endif /// @}