Quest Template több nyelven.

Indította NevemSenki, 2013 március 23, 10:22:19 DÉLELŐTT

Előző téma - Következő téma

kagebunshin

Üdv mindenkinek!

Picit utánaolvastam és elgondolkodtam a témán. Tehát ha jól értem. Regisztrációnál vagy esetleg az után is a játékos kiválasztja milyen nyelven szeretné látni a küldetéseket és az az ő felhasználónevével úgy jelenik meg a játékban. Kicsit.... pontosabban nagyon régi tc2 emum van. Nézzétek el hogy ezen próbáltam ki de lusta voltam leszedni egy frissebbet. Egy kis módosítás kell csak hozzá és feltételezem nem változott meg annyira, hogy ne működjön esetleg egy újabb emun.

Innentől minden amit állítok a saját feltételezésem ha valamit hibásan állítok jelezzétek és javítom.

Amire szükségünk van:
-world adatbázisban a Locales quest tc2 tábla
-auth adatbázisban a DB_Auth_account tábla
-src/server/game/Server/WorldSession.cpp

Először nézzük a Locales quest tc2 táblát. Azt a célt szolgálja, hogy miután a szerver felismerte a klienst a megadott quest adott fordítását továbbítja a kliensnek. Nem részletezem pontosan mi mire jó benne. Feltételezem mindenki ismeri vagy utána tud nézni. A lényeg, hogy id-nek egy quest id-t kell megadni majd a title, details, objectives fordításait. Azt tapasztaltam, hogy ha egy quest-nek csak pl a címét fordítjuk le a többit üresen hagyjuk akkor azok maradnak a Quest template tc2 beállításai szerint, tehát az eredeti angol szöveg marad az üres helyett. Bizonyos szempontból ez logikus is, de gondoltam leírom. Persze gondolom a tábla nem pont a magyar fordításra lett kitalálva, de mivel teljesen üres talán nem köveznek meg ha felhasználjuk.

Tehát ez a tábla majdnem arra jó ami nekünk kell. Adott kliens-nek, adott nyelvű questeket küld. Ha jól értelmezem a szerver bejelentkezéskor azonosítja a kliens nyelvét. Az most nem fontos ezt hogyan dönti el. Ami most fontos, hogy ezt hol tárolja. Ez pedig a WorldSession. Konstruktorban kapja meg és a m_sessionDbLocaleIndex változóban tárolja.

Megoldás:

A DB_Auth_account táblában már szerepel egy locale mező. Megfigyeléseim alapján ez is minden belépésnél frissül, de ennek a mintájára létre lehet hozni egy hasonló mezőt pl.: req_locale. Itt tárolhatjuk, hogy a játékos milyen nyelven szeretné látni a questeket. Értéke 0-8-ig terjedhet. Esetleg egy plusz érték amivel kikapcsolhatjuk.

Így néz ki jelenleg a konstruktor.
Idéz
WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter):
    m_muteTime(mute_time),
    m_timeOutTime(0),
    _player(NULL),
    m_Socket(sock),
    _security(sec),
    _accountId(id),
    m_expansion(expansion),
    _warden(NULL),
    _logoutTime(0),
    m_inQueue(false),
    m_playerLoading(false),
    m_playerLogout(false),
    m_playerRecentlyLogout(false),
    m_playerSave(false),
    m_sessionDbcLocale(sWorld->GetAvailableDbcLocale(locale)),
    m_sessionDbLocaleIndex(locale),
    m_latency(0),
    m_TutorialsChanged(false),
    recruiterId(recruiter),
    isRecruiter(isARecruiter),
    timeLastWhoCommand(0),
    _RBACData(NULL)
{
    if (sock)
    {
        m_Address = sock->GetRemoteAddress();
        sock->AddReference();
        ResetTimeOutTime();
        LoginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = %u;", GetAccountId()); // One-time query
    }

    InitializeQueryCallbackParameters();
}

Ki kell bővíteni egy lekérdezéssel.
Lekérjük az adott accounthoz tartozó req_locale értékét.
És ha az nem egyenlő az általunk megadott tiltó értékkel, akkor felülírjuk vele a régit. A példámban ez a szám 9, de talán elegánsabb lenne valami mást használni erre.

Idéz
   QueryResult banResult = LoginDatabase.PQuery("SELECT req_locale FROM account WHERE id = %u", GetAccountId());
    if (banResult)
   {
      Field* fields = banResult->Fetch();
      uInt nyelv = fields[0].GetUInt16();

      if(nyelv != 9)
         m_sessionDbLocaleIndex = (LocaleConstant)fields[0].GetUInt16();
   }

    if (sock)
    {
        m_Address = sock->GetRemoteAddress();
        sock->AddReference();
        ResetTimeOutTime();
        LoginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = %u;", GetAccountId()); // One-time query
    }

Ezek után már csak a Locales quest tc2 táblát kell megfelelően kitölteni. Továbbá valahányszor a játékos módosítja a nyelvet szükséges a cache mappa törlése, hogy a változtatás érvényes legyen.

Összefoglalva:
Egy plusz mező az account táblába és egy egyszerű lekérdezés. Saját gépen teszteltem és működik is. Ha pedig a sejtésem nem csal ez a worldsession konstruktor loginoláskor fut le, ami azért jó esetben nem olyan gyakori, hogy megakassza a szervert, de ehhez már nem értek annyira. Gyorsan átfutottam csak a többi locales táblát biztos azokra is hatással van, de ezt már nem teszteltem.

Biztos lehetne még szépíteni a kódon, de siettem a megoldással és a poszt írásával is. Ha másra nem is, kiindulási alapnak remélem jó lesz.

Ha esetleg valami nem világos vagy rosszul írtam volna jelezzétek és javítom.

Aki pedig megtisztelt a posztom elolvasásával annak pedig köszönöm a figyelmet!
Aki nem annak is. :)

Üdv:
Kagebunshin
"-Egy dolgot viszont elárulhatnál nekem. Ki találta ki, hogy a fák őreinek erejével szálljatok szembe velem, mert nem te ugye? Te nem tudtad!
-Nem... de azért vagyunk többen, hogy valaki tudja."

Armin

Na oké, ez mind szép, és jó, viszont az npc-k dumáit nem igazán lehetne több nyelvűre megcsinálni.

NevemSenki

Szerintem ha ezt meg lehet oldani, akkor azt is. Valahogy biztosan.
kagebunshin örülök neki hogy volt aki érdemben utánanézett a dolognak.
Szerintem mások nevében is mondhatom hogy köszönjük.

Ebből már bőven el lehet indulni.

Üdv.: Senki
Csak a Puffin ad neked erőt, és mindent lebíró akaratot!

EroniX

Idézetet írta: Armin Dátum 2013 március 23, 08:21:52 DÉLUTÁN
Na oké, ez mind szép, és jó, viszont az npc-k dumáit nem igazán lehetne több nyelvűre megcsinálni.
Ha jól látom npc_text táblában már van is rá támogatás.
http://collab.kpsn.org/display/tc/Locales+npc+text+tc2
Azuregos Delta Force

NevemSenki

EroniX, pont ezt néztem én is, csak beelőztél.


  • locales_achievement_reward [R]
  • locales_creature [R]
  • locales_gameobject [R]
  • locales_item [R]
  • locales_gossip_menu_option [R]
  • locales_item_set_names [R]
  • locales_npc_text [R]
  • locales_page_text [R]
  • locales_points_of_interest [R]
  • locales_quest [R]

És még ide tartozik a http://archive.trinitycore.info/Localization_lang, maguk az ID-k.

Tehát akkor eredetileg a Kliens-től függ hogy milyen Locale-be tartozik. ( enUS, ruRU ) és azáltal frissül a LocaleId, ami majd szabályozza a megjelenített szöveget? Lehet rosszul értelmeztem valamit.

Üdv.: Senki
Csak a Puffin ad neked erőt, és mindent lebíró akaratot!

Armin

#20
Na akkó talán olvasgatom kellett volna, mielőtt írok  ;D
Ha a kliens oldalról nézi, akkor ez már nem az én asztalom  ;D

Amúgy valóban köszi. Ment is a +1  :)

Ő, ez nem hiszen, hogy az EnUS, stb.-re vonatkozna, ugyanis kétlem, hogy van francia, spanyol, stb. kliens. De ezeket dbc-ből olvassa, szóval vagy módosítani kell kicsit, vagy valamelyiket felhasználni magyarnak.

NevemSenki

Ha kliens, akkor én megpróbálok utánanézni. Úgyis régi vágyam egy Magyar kliens!  ;)

Üdv.: Senki
Csak a Puffin ad neked erőt, és mindent lebíró akaratot!

kagebunshin

Igen. Alap esetben a klienstől függ.

https://github.com/TrinityCore/TrinityCore/blob/master/src/server/shared/Common.cpp

Itt is van a függvény ami elvégzi az átalakítást. A LocaleConstant amit visszaad egy enum tipus. Bővítéséhez gondolom több helyen is át kell írni, meg ugye a local táblákba mindenhova egy kilencedik oszlop. Egy meglévő felhasználása lehet, hogy jobb ötlet.

Pluszokat köszönöm és sok sikert a magyar klienshez.
"-Egy dolgot viszont elárulhatnál nekem. Ki találta ki, hogy a fák őreinek erejével szálljatok szembe velem, mert nem te ugye? Te nem tudtad!
-Nem... de azért vagyunk többen, hogy valaki tudja."

Powered by EzPortal