Jump to content

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 452
  • kekw 8
  • Eyes 9
  • Dislove 2
  • Angry 3
  • Not Good 1
  • Sad 2
  • Think 5
  • Confused 3
  • Scream 1
  • Lmao 1
  • Good 159
  • muscle 4
  • Love 33
  • Love 303
Link to comment
https://metin2.dev/topic/22779-multi-language-system/
Share on other sites

  • 1 year later...
  • 7 months later...

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 106
  • kekw 1
  • Flame 1
  • Confused 1
  • Good 32
  • muscle 1
  • Love 5
  • Love 39
Link to comment
https://metin2.dev/topic/22779-multi-language-system/#findComment-148722
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 48
  • Good 16
  • Love 4
  • Love 29

spacer.png

Link to comment
https://metin2.dev/topic/22779-multi-language-system/#findComment-154730
Share on other sites

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

I place the server side the source build and strip game file but syserr is:
SYSERR: Jun 11 15:41:35 :: Process: SEQUENCE 212bb700 mismatch 0xaf != 0x0 header 111
SYSERR: Jun 11 15:41:35 :: Process: SEQUENCE_LOG [UNKNOWN]-------------
    [111 : 0xaf]

 

help me please

Link to comment
https://metin2.dev/topic/22779-multi-language-system/#findComment-158130
Share on other sites

  • 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
https://metin2.dev/topic/22779-multi-language-system/#findComment-159490
Share on other sites

  • 7 months later...
  • Contributor

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 11
  • Love 10
Link to comment
https://metin2.dev/topic/22779-multi-language-system/#findComment-164642
Share on other sites

  • Contributor
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
https://metin2.dev/topic/22779-multi-language-system/#findComment-164706
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
https://metin2.dev/topic/22779-multi-language-system/#findComment-164739
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
https://metin2.dev/topic/22779-multi-language-system/#findComment-165190
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
https://metin2.dev/topic/22779-multi-language-system/#findComment-165516
Share on other sites

  • 1 year later...

Hey, I didn’t want to create a new topic for this, but I thought it might be useful to share. Here’s a small function that detects the user's Windows language and returns it as a short code like "en", "ro", "de" — perfect for multi-language systems.

You can use it to automatically set the default language in your client based on the user's OS settings, instead of asking them to choose manually on first launch.

 

This is the hidden content, please

Usage:

const std::string& lang = GetUserLanguageCode();
TraceError("%s", lang.c_str());

 

Edited by mmorse3399
  • Metin2 Dev 12
  • Good 3
  • Love 5
Link to comment
https://metin2.dev/topic/22779-multi-language-system/#findComment-171325
Share on other sites

Don't use any images from : imgur, turkmmop, freakgamers, inforge, hizliresim... Or your content will be deleted without notice...
Use : https://metin2.download/media/add/

Please use https://metin2.download/ when uploading files smaller than 100MB, otherwise the approval will take longer due to manual upload.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • 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.