Jump to content

Server Side Korean Strings to Locale Translation And EUC-KR to UTF-8 Change


Recommended Posts

  • Active+ Member

So, one of the most common problems i've seen in metin2 development, is people using text editors without configuring them for the euc-kr encoding which causes translation issues when editing server side files and also when programming its easier to check for a english text than some korean string, so i created a simple python script that takes the translated strings from server side locale_string and changes every korean string to their english translation while also changing the file encoding from euc-kr to utf-8, it will also create a new locale string file.

This is a small script and i think there's no need for a tutorial, but always take backups as safety measure

import re
import sys
import os

mainPath = 'path\\to\\server\\source'

textFound = []
rawStrings = []
rawStringsPT = []
translations = []
translationsPT = []

blacklistFiles = [
	'empire_text_convert.cpp'
]

def openFile(file_path):
	pattern = r'LC_TEXT.*?"(.*?)"'

	print("Opening file: %s" % file_path)

	with open(file_path, 'r', encoding="latin-1") as file:
		for line in file:
			match = re.search(pattern, line)
			if match:
				if not match.group(1) in textFound:
					textFound.append(match.group(1))

def saveFoundedTexts():
	with open('textFound.txt', 'w', encoding="latin-1") as f:
		for i in textFound:
			f.write(i)
			f.write("\n")

def loadLocaleStringEN():
	pattern = r'"(.*?)"'

	with open('locale_string_en.txt', 'r', encoding='latin-1') as file:
		lines = file.readlines()
	raw_line = None

	for line_number, line in enumerate(lines):
		line = line.strip()
		if not line:
			continue

		match = re.search(pattern, line)
		if match:
			extracted_text = match.group(1)
			if raw_line is None:
				raw_line = extracted_text
			else:
				rawStrings.append(raw_line)
				translations.append(extracted_text)
				raw_line = None

def updateLocale(file):
	raw_to_translations_map = dict(zip(rawStrings, translations))

	updated_lines = []
	new_file = "new_" + str(file)

	with open(file, 'r', encoding='latin-1') as file:
		lines = file.readlines()

	for line in lines:
		line = line.strip()
		if not line:
			updated_lines.append(line)
			continue

		match = re.search(r'"(.*?)"', line)
		if match:
			raw_string = match.group(1)
			if raw_string in raw_to_translations_map:
				updated_line = line.replace(f'"{raw_string}"', f'"{raw_to_translations_map[raw_string]}"')
				updated_lines.append(updated_line)
			else:
				updated_lines.append(line)
		else:
			updated_lines.append(line)

	

	with open(new_file, 'w', encoding='latin-1') as file:
		file.write('\n'.join(updated_lines))

def replaceTexts(file_path):
	pattern = r'LC_TEXT.*?"(.*?)"'

	print("Replacing text in file: %s" % file_path)

	with open(file_path, 'r', encoding="latin-1") as file:
		content = file.read()

	for raw, translated in zip(rawStrings, translations):
		content = re.sub(
			f'LC_TEXT.*?"{re.escape(raw)}"', 
			f'LC_TEXT("{translated}"', 
			content
		)

	with open(file_path, 'w', encoding="utf-8") as file:
		file.write(content)

def scan(path, replace=False):
	for root, dirs, files in os.walk(path):
		for file in files:
			if file.endswith('.cpp'):
				path = os.path.join(root, file)
				if not file in blacklistFiles:
					if replace:
						replaceTexts(path)
					else:
						openFile(path)

def main():
	loadLocaleStringEN()
	updateLocale('locale_string_en.txt')
	# updateLocale('locale_string_pt.txt')
	scan(mainPath)
	scan(mainPath, True)
	saveFoundedTexts()

if __name__ == '__main__':
	main()

 

  • Active+ Member
import re
import os

# Directory containing the source files
SOURCE_PATH = "path/to/server/source"
BLACKLIST_FILES = ["empire_text_convert.cpp"]

# Globals to store translations and results
translations = {}
untranslated_texts = []
success_count = 0
failure_count = 0


def list_locale_files():
    """Lists all locale_string_x.txt files in the current directory."""
    return [f for f in os.listdir() if f.startswith("locale_string_") and f.endswith(".txt")]


def load_translations(file_path):
    """Loads translations from the selected locale string file."""
    global translations
    print(f"Loading translations from: {file_path}")

    pattern = r'"(.*?)"'
    raw_key = None

    with open(file_path, "r", encoding="utf-8") as file:
        for line in file:
            line = line.strip()
            if not line:
                continue
            match = re.search(pattern, line)
            if match:
                extracted = match.group(1)
                if raw_key is None:
                    raw_key = extracted
                else:
                    translations[raw_key] = extracted
                    raw_key = None


def process_file(file_path):
    """Processes a .cpp file, replacing texts with translations."""
    global success_count, failure_count

    print(f"Processing file: {file_path}")
    pattern = r'LC_TEXT.*?"(.*?)"'
    updated_lines = []

    with open(file_path, "r", encoding="utf-8") as file:
        lines = file.readlines()

    for line in lines:
        match = re.search(pattern, line)
        if match:
            original_text = match.group(1)
            if original_text in translations:
                translated_text = translations[original_text]
                updated_lines.append(line.replace(f'"{original_text}"', f'"{translated_text}"'))
                success_count += 1
            else:
                untranslated_texts.append(original_text)
                updated_lines.append(line)
                failure_count += 1
        else:
            updated_lines.append(line)

    # Write updated content back to the file
    with open(file_path, "w", encoding="utf-8") as file:
        file.writelines(updated_lines)


def scan_source_directory():
    """Scans the source directory for .cpp files and processes them."""
    for root, dirs, files in os.walk(SOURCE_PATH):
        for file in files:
            if file.endswith(".cpp") and file not in BLACKLIST_FILES:
                process_file(os.path.join(root, file))


def save_untranslated_texts():
    """Saves untranslated texts to a file."""
    if untranslated_texts:
        with open("untranslated_texts.txt", "w", encoding="utf-8") as file:
            for text in set(untranslated_texts):  # Remove duplicates
                file.write(f"{text}\n")
        print(f"Untranslated texts saved to 'untranslated_texts.txt'")


def main():
    # Step 1: List available locale string files
    locale_files = list_locale_files()
    if not locale_files:
        print("No locale string files found.")
        return

    print("Available locale string files:")
    for i, file in enumerate(locale_files, start=1):
        print(f"{i}. {file}")

    # Step 2: User selects a locale string file
    try:
        choice = int(input("Select a file by number: "))
        if choice < 1 or choice > len(locale_files):
            print("Invalid selection.")
            return
        selected_file = locale_files[choice - 1]
    except ValueError:
        print("Invalid input.")
        return

    # Step 3: Load translations
    load_translations(selected_file)

    # Step 4: Process source files
    scan_source_directory()

    # Step 5: Save untranslated texts and show stats
    save_untranslated_texts()

    print(f"\nTranslation completed!")
    print(f"  Successfully translated: {success_count}")
    print(f"  Failed to translate: {failure_count}")


if __name__ == "__main__":
    main()

Here is a revised version with minor improvements.

  • Love 2

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.