Jump to content
Maintenance : Final step ×

Multi Language System


Recommended Posts

  • Contributor

M2 Download Center

This is the hidden content, please
( Internal )

This is the hidden content, please
( GitHub )

Everything works fine, just add a part of "python" client, so that users change language with a button, i was lazy to do it.
 
 
- The system saves one language per account.
- It's capable of translating quest, client, etc.
- The system takes the language from the client's mylang.cfg file and save on DB of this account in the client.
 
The guide simply focuses on looking for DEFINE:

ENABLE_MULTILANGUAGE
 
So you can see how I placed it.
Edited by Metin2 Dev
Core X - External 2 Internal
  • Metin2 Dev 308
  • kekw 8
  • Eyes 5
  • Dislove 2
  • Angry 4
  • Not Good 1
  • Sad 2
  • Think 4
  • Confused 3
  • Scream 1
  • Lmao 1
  • Good 125
  • muscle 2
  • Love 23
  • Love 220
Link to comment
Share on other sites

  • 1 year later...
  • 7 months later...
  • Active Member

IJR9yaj.png

I've reviewed the codes a few times, but I couldn't get the chat to work, does anyone have any idea what might be happening, or know how I can fix it?

Obs.: In the "locale_game.txt" messages it is as if there are no spaces between the words, I don't know if this has something to do with the main problem.

In advance, I am grateful for your attention.

FIX: 

This is the hidden content, please

Obs.: Working perfectly, with the exception of the accents in chat all, but in normal chat it works, in case anyone has a fix.

Edited by Metin2 Dev
Core X - External 2 Internal
  • Metin2 Dev 86
  • kekw 1
  • Flame 1
  • Confused 1
  • Good 28
  • Love 2
  • Love 31
Link to comment
Share on other sites

  • 4 weeks later...
  • 8 months later...
  • Active Member
On 4/12/2022 at 11:17 PM, Klaus said:

IJR9yaj.png

I've reviewed the codes a few times, but I couldn't get the chat to work, does anyone have any idea what might be happening, or know how I can fix it?

Obs.: In the "locale_game.txt" messages it is as if there are no spaces between the words, I don't know if this has something to do with the main problem.

In advance, I am grateful for your attention.

FIX: 

This is the hidden content, please

Obs.: Working perfectly, with the exception of the accents in chat all, but in normal chat it works, in case anyone has a fix.

Thank you for the fix, in addition you should mention, that the class std::size will only work with c++17 and higher. 

I would like to contribute with the gui for changing the language:

Download Center

This is the hidden content, please

 

 

Spoiler

intrologin.py
 

under
	def __init__(self, stream):
add
		self.languageBoard = 0
under
	def Close(self):
add
		self.languageBoard				= None
under 
	def __LoadScript(self, fileName):
		import dbg
		try:
			pyScrLoader = ui.PythonScriptLoader()
			pyScrLoader.LoadScriptFile(self, fileName)
		except:
			import exception
			exception.Abort("LoginWindow.__LoadScript.LoadObject")
		try:
			GetObject=self.GetChild
			self.serverBoard			= GetObject("ServerBoard")
add this
			self.languageBoard			= GetObject("LanguageBoard")
			self.OnClickChangeEn		= GetObject("ChangeLanguageEn")
			self.OnClickChangeEs		= GetObject("ChangeLanguageEs")
			self.OnClickChangeHu		= GetObject("ChangeLanguageHu")
			self.OnClickChangeRo		= GetObject("ChangeLanguageRo")
			self.OnClickChangeTr		= GetObject("ChangeLanguageTr")
			self.OnClickChangeDe		= GetObject("ChangeLanguageDe")
under this 
		except:
			import exception
			exception.Abort("LoginWindow.__LoadScript.BindObject")

		self.selectConnectButton.SetEvent(ui.__mem_func__(self.__OnClickSelectConnectButton))

		self.serverBoard.OnKeyUp = ui.__mem_func__(self.__ServerBoard_OnKeyUp)
		self.xServerBoard, self.yServerBoard = self.serverBoard.GetLocalPosition()

		self.serverSelectButton.SetEvent(ui.__mem_func__(self.__OnClickSelectServerButton))
		self.serverExitButton.SetEvent(ui.__mem_func__(self.__OnClickExitButton))

		self.loginButton.SetEvent(ui.__mem_func__(self.__OnClickLoginButton))
		self.loginExitButton.SetEvent(ui.__mem_func__(self.__OnClickExitButton))

		self.serverList.SetEvent(ui.__mem_func__(self.__OnSelectServer))
		
		self.idEditLine.SetReturnEvent(ui.__mem_func__(self.pwdEditLine.SetFocus))
		self.idEditLine.SetTabEvent(ui.__mem_func__(self.pwdEditLine.SetFocus))

		self.pwdEditLine.SetReturnEvent(ui.__mem_func__(self.__OnClickLoginButton))
		self.pwdEditLine.SetTabEvent(ui.__mem_func__(self.idEditLine.SetFocus))
add this
		self.OnClickChangeEn.SetEvent(ui.__mem_func__(self.__OnClickChangeLanguage), "en")
		self.OnClickChangeEs.SetEvent(ui.__mem_func__(self.__OnClickChangeLanguage), "es")
		self.OnClickChangeHu.SetEvent(ui.__mem_func__(self.__OnClickChangeLanguage), "hu")
		self.OnClickChangeRo.SetEvent(ui.__mem_func__(self.__OnClickChangeLanguage), "ro")
		self.OnClickChangeTr.SetEvent(ui.__mem_func__(self.__OnClickChangeLanguage), "tr")
		self.OnClickChangeDe.SetEvent(ui.__mem_func__(self.__OnClickChangeLanguage), "de")

before this:
	def __OnClickLoginButton(self):
add this function
	def __OnClickChangeLanguage(self, language):
		self.Languages = { "en" : "0", "es" : "1", "hu" : "2", "ro" : "3", "tr" : "4", "de" : "5"}
		file = open("mylang.cfg", "w")
		file.write(self.Languages[str(language)])
		file.close()
		dbg.LogBox("The laguage of client was changed.")
		dbg.LogBox("Please start your game again.")
		app.Exit()

 

loginwindow.py
 

	{
			"name" : "LanguageBoard",
			"type" : "window",
			"x" : 530,
			"y" :SCREEN_HEIGHT - SERVER_BOARD_HEIGHT - 122,
			"width" : 375,
			"height" : 50,
			"children" :
			(
				{
					"name" : "ChangeLanguageEn",
					"type" : "radio_button",

					"x": 0,
					"y": 0,

					"default_image": "d:/ymir work/ui/game/language/login/flag_en_norm.tga",
					"over_image": "d:/ymir work/ui/game/language/login/flag_en_over.tga",
					"down_image": "d:/ymir work/ui/game/language/login/flag_en_norm.tga",
				},
				{
					"name" : "ChangeLanguageEs",
					"type" : "radio_button",

					"x": 40,
					"y": 0,

					"default_image": "d:/ymir work/ui/game/language/login/flag_es_norm.tga",
					"over_image": "d:/ymir work/ui/game/language/login/flag_es_over.tga",
					"down_image": "d:/ymir work/ui/game/language/login/flag_es_norm.tga",
				},
				{
					"name" : "ChangeLanguageHu",
					"type" : "radio_button",

					"x": 40*2,
					"y": 0,

					"default_image": "d:/ymir work/ui/game/language/login/flag_hu_norm.tga",
					"over_image": "d:/ymir work/ui/game/language/login/flag_hu_over.tga",
					"down_image": "d:/ymir work/ui/game/language/login/flag_hu_norm.tga",
				},
				{
					"name" : "ChangeLanguageRo",
					"type" : "radio_button",

					"x": 40*3,
					"y": 0,

					"default_image": "d:/ymir work/ui/game/language/login/flag_ro_norm.tga",
					"over_image": "d:/ymir work/ui/game/language/login/flag_ro_over.tga",
					"down_image": "d:/ymir work/ui/game/language/login/flag_ro_norm.tga",
				},
				{
					"name" : "ChangeLanguageTr",
					"type" : "radio_button",

					"x": 40*4,
					"y": 0,
					"default_image": "d:/ymir work/ui/game/language/login/flag_tr_norm.tga",
					"over_image": "d:/ymir work/ui/game/language/login/flag_tr_over.tga",
					"down_image": "d:/ymir work/ui/game/language/login/flag_tr_norm.tga",
				},
				{
					"name" : "ChangeLanguageDe",
					"type" : "radio_button",

					"x": 40*5,
					"y": 0,

					"default_image": "d:/ymir work/ui/game/language/login/flag_de_norm.tga",
					"over_image": "d:/ymir work/ui/game/language/login/flag_de_over.tga",
					"down_image": "d:/ymir work/ui/game/language/login/flag_de_norm.tga",
				},
			)
		},
 
  • Metin2 Dev 34
  • Good 15
  • Love 3
  • Love 24

spacer.png

Link to comment
Share on other sites

  • 2 months later...
  • 1 month later...
  • 2 months later...

image.png

Edited by Metin2 Dev International
Core X - External 2 Internal
  • Good 1

“To be humble with superiors is duty, with equals is courtesy, with inferiors is nobility.”
Benjamin Franklin

 

Por favor, desative seu AdBlock quando usar meus links de download.

Please, disable your 
AdBlock when use my download links.

Me

AdBlock 
On:   


699691-icon-20-sad-face-eyebrows-48.png

 

Adblock Off:  



Streamline-65-48.png

 

 

Angry One Piece GIF by Toei Animation

Link to comment
Share on other sites

  • 7 months later...
  • Contributor
Posted (edited)

First of all thanks for the release.

If anyone try to use this multilang system, here's some tip for the quests because making different quest states for each language as in the example will be a nightmare.

translate.lua:

--Default arrays
gameforge.blacksmith = {}
gameforge.blacksmith._10_npcChat = {}
gameforge.blacksmith._20_sayTitle = {}
gameforge.blacksmith._30_say = {}
gameforge.blacksmith._40_sayTitle = {}
gameforge.blacksmith._50_sayReward = {}

--EN
gameforge.blacksmith._10_npcChat["en"] = "I want to upgrade something. "
gameforge.blacksmith._20_sayTitle["en"] = "Blacksmith "
gameforge.blacksmith._30_say["en"] = "Greetings![ENTER]I am responsible for upgrading items. If you want[ENTER]to upgrade an item, just bring it to me. "
gameforge.blacksmith._40_sayTitle["en"] = "Information: "
gameforge.blacksmith._50_sayReward["en"] = "Drag an item from your inventory onto the[ENTER]Blacksmith. "

--HU
gameforge.blacksmith._10_npcChat["hu"] = "Szeretnék valamit feljavíttatni. "
gameforge.blacksmith._20_sayTitle["hu"] = "Kovács "
gameforge.blacksmith._30_say["hu"] = "Üdvözöllek![ENTER]Én felelek a tárgyak feljavításáért. Ha fel[ENTER]szeretnél javíttatni egy tárgyat, hozd csak ide[ENTER]nekem. "
gameforge.blacksmith._40_sayTitle["hu"] = "Információ: "
gameforge.blacksmith._50_sayReward["hu"] = "Húzz rá egy tárgyat a leltáradból a Kovácsra. "

questlib.lua:

function get_lang_name()
	if get_lang() == 1 then
		return "hu"
	end
	return "en"
end

blacksmith.quest:

quest blacksmith begin
	state start begin
		when blacksmith.chat.gameforge.blacksmith._10_npcChat[get_lang_name()] begin
			say_title(gameforge.blacksmith._20_sayTitle[get_lang_name()])
			say(gameforge.blacksmith._30_say[get_lang_name()])
			wait()
			say_title(gameforge.blacksmith._40_sayTitle[get_lang_name()])
			say_reward(gameforge.blacksmith._50_sayReward[get_lang_name()])
		end
	end
end

Some caching mechanism to the get_lang_name() would be nice too.
Also do not use this in notice_all because it will notice all in the player's language... Maybe use ["en"] to display notice_alls in english for everyone or code some translating mechanism for the client (e.g. replace chars when displaying the messages depending on the current lang).

+1 note: the default qc did not like the [get_lang_name()] in the when statement but a friend gave me a "fixed" qc which you can download 

This is the hidden content, please
.

Edited by TMP4
  • Metin2 Dev 6
  • Love 4
Link to comment
Share on other sites

  • Contributor
Posted (edited)
On 4/12/2022 at 11:17 PM, Klaus said:

Obs.: Working perfectly, with the exception of the accents in chat all, but in normal chat it works, in case anyone has a fix.

char.cpp in void CHARACTER::ChatPacket

this:

#ifdef ENABLE_MULTILANGUAGE
    std::string sTranslateText;
    if (type != CHAT_TYPE_COMMAND)
    {    
        if (GetLang() > MAX_LANGUAGES)
            sTranslateText = LC_TEXT(DEFAULT_LANGUAGE, format);
        else
            sTranslateText = LC_TEXT(GetLang(), format);
    }
#endif

and this a little under:

#ifdef ENABLE_MULTILANGUAGE
	int len = vsnprintf(chatbuf, sizeof(chatbuf), format, args);

	if (type != CHAT_TYPE_COMMAND)
		len = vsnprintf(chatbuf, sizeof(chatbuf), sTranslateText.c_str(), args);
#else

Is just not needed at all and makes this problem. Every shout, party, info etc chat would go to LC_TEXT what adds a "@0949" to the message if translation not found in  in locale.cpp's locale_find (it's hidden but you can see in /n for example or if you write messages to console) and that "@0949" makes accents bad plus you get a syserr each time somebody shout or party or guild chat etc.

So you can delete this 2 ifdef if you already set every LC_TEXT(DEFAULT_LANGUAGE.. / LC_TEXT(ch->GetLang().. and I'm sure you did because LC_TEXT's new first attribute is mandatory so if you didn't then you couldn't compile the game. So that's why I said this is just not needed at all and can be removed.

Edit: LC_TEXT(TRANSLATE_LANGUAGE will not work. Use LC_TEXT(ch->GetLang()..

(Sorry for bumping old topic but I wanted to share the fix)

Edited by TMP4
  • Love 1
Link to comment
Share on other sites

  • Contributor

Make NPC names load from clientside mob_proto:

Look for CPythonNetworkStream::__RecvCharacterAppendPacket in PythonNetworkStreamPhaseGameActor.cpp

Add this to the begginning of the function:

#ifdef ENABLE_MULTILANGUAGE
	if (pkNetActorData->m_bType == CActorInstance::TYPE_NPC && !(pkNetActorData->m_dwRace >= 20101 && pkNetActorData->m_dwRace <= 20109) && !(pkNetActorData->m_dwRace >= 34001 && pkNetActorData->m_dwRace <= 34099)) // load npc names from clientside
	{
		const char* c_szName;
		CPythonNonPlayer& rkNonPlayer = CPythonNonPlayer::Instance();
		if (rkNonPlayer.GetName(pkNetActorData->m_dwRace, &c_szName))
			pkNetActorData->m_stName = c_szName;
	}
#endif
  • Metin2 Dev 1
  • Not Good 1
Link to comment
Share on other sites

  • 3 weeks later...

is that possible 

		if (LC_IsEurope())
		{
			char translateFileName[256];
			snprintf(translateFileName, sizeof(translateFileName), "%s/translate.lua", LocaleService_GetBasePath().c_str());

			int translateLoadingResult = lua_dofile(L, translateFileName);
			sys_log(0, "LoadTranslate(%s), returns %d", translateFileName, translateLoadingResult);
			if (translateLoadingResult != 0)
			{
				sys_err("LOAD_TRANSLATE_ERROR(%s)", translateFileName);
				return false;
			}
		}

		{
			char questLocaleFileName[256];
			if (LC_IsEurope())
			{
				snprintf(questLocaleFileName, sizeof(questLocaleFileName), "%s/locale.lua", g_stQuestDir.c_str());
			}
			else
			{
				snprintf(questLocaleFileName, sizeof(questLocaleFileName), "%s/locale_%s.lua", g_stQuestDir.c_str(), g_stLocale.c_str());
			}

			int questLocaleLoadingResult = lua_dofile(L, questLocaleFileName);
			sys_log(0, "LoadQuestLocale(%s), returns %d", questLocaleFileName, questLocaleLoadingResult);
			if (questLocaleLoadingResult != 0)
			{
				sys_err("LoadQuestLocale(%s) FAILURE", questLocaleFileName);
				return false;
			}
		}

questlua.cpp update this automatic like if lang is english then it load translate_en.lua if german language then translate_de.lua

 

and i got this error 

 

locale_service.cpp:427:18: compile matrix_card.cpp
error: use of undeclared identifier 'SQLMsg'
  427 |         std::unique_ptcompile messenger_manager.cpp
r<SQLMsg> pMsg(DBManager::Instance().DirectQuery("SELECT lang FROM common.lang"));
      |                         ^
locale_service.cpp:427:31: error: use of undeclared identifier 'DBManager'
  427 |         std::unique_ptr<SQLMsg> pMsg(DBManager::Incompile mining.cpp
stance().DirectQuery("SELECT lang FROM common.lang"));
      compile mob_manager.cpp
|                                      ^
locale_service.cpp:430:2: error: unknown type name 'MYSQL_ROW'
  430 |         MYSQL_ROW row;
      |         ^
locale_service.cpp:454:6: error: redefinition of 'LocaleService_LoadLocaleStringFile'

 

Link to comment
Share on other sites

  • 3 weeks later...
  • Active Member
On 4/16/2024 at 8:56 PM, TMP4 said:

First of all thanks for the release.

If anyone try to use this multilang system, here's some tip for the quests because making different quest states for each language as in the example will be a nightmare.

translate.lua:

--Default arrays
gameforge.blacksmith = {}
gameforge.blacksmith._10_npcChat = {}
gameforge.blacksmith._20_sayTitle = {}
gameforge.blacksmith._30_say = {}
gameforge.blacksmith._40_sayTitle = {}
gameforge.blacksmith._50_sayReward = {}

--EN
gameforge.blacksmith._10_npcChat["en"] = "I want to upgrade something. "
gameforge.blacksmith._20_sayTitle["en"] = "Blacksmith "
gameforge.blacksmith._30_say["en"] = "Greetings![ENTER]I am responsible for upgrading items. If you want[ENTER]to upgrade an item, just bring it to me. "
gameforge.blacksmith._40_sayTitle["en"] = "Information: "
gameforge.blacksmith._50_sayReward["en"] = "Drag an item from your inventory onto the[ENTER]Blacksmith. "

--HU
gameforge.blacksmith._10_npcChat["hu"] = "Szeretnék valamit feljavíttatni. "
gameforge.blacksmith._20_sayTitle["hu"] = "Kovács "
gameforge.blacksmith._30_say["hu"] = "Üdvözöllek![ENTER]Én felelek a tárgyak feljavításáért. Ha fel[ENTER]szeretnél javíttatni egy tárgyat, hozd csak ide[ENTER]nekem. "
gameforge.blacksmith._40_sayTitle["hu"] = "Információ: "
gameforge.blacksmith._50_sayReward["hu"] = "Húzz rá egy tárgyat a leltáradból a Kovácsra. "

questlib.lua:

function get_lang_name()
	if get_lang() == 1 then
		return "hu"
	end
	return "en"
end

blacksmith.quest:

quest blacksmith begin
	state start begin
		when blacksmith.chat.gameforge.blacksmith._10_npcChat[get_lang_name()] begin
			say_title(gameforge.blacksmith._20_sayTitle[get_lang_name()])
			say(gameforge.blacksmith._30_say[get_lang_name()])
			wait()
			say_title(gameforge.blacksmith._40_sayTitle[get_lang_name()])
			say_reward(gameforge.blacksmith._50_sayReward[get_lang_name()])
		end
	end
end

Some caching mechanism to the get_lang_name() would be nice too.
Also do not use this in notice_all because it will notice all in the player's language... Maybe use ["en"] to display notice_alls in english for everyone or code some translating mechanism for the client (e.g. replace chars when displaying the messages depending on the current lang).

+1 note: the default qc did not like the [get_lang_name()] in the when statement but a friend gave me a "fixed" qc which you can download 

Hidden Content

  • Give reaction to this post to see the hidden content.

.

 

Did you also managed to fix the locale.lua part for the npc chats? If I start the server and login with an german client after that starting a second client with romanian for example, both clients get the german language for the npc chats.

spacer.png

Link to comment
Share on other sites

×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.