import os
import struct
# Папка, куда скрипт сохранит готовые русские файлы игры
OUTPUT_FOLDER = "STCM2L_RUSSIAN"
os.makedirs(OUTPUT_FOLDER, exist_ok=True)
def pack_stcm2l(orig_bin_path, translated_txt_path, output_bin_path):
if not os.path.exists(orig_bin_path) or not os.path.exists(translated_txt_path):
return False
with open(orig_bin_path, "rb") as f:
data = bytearray(f.read())
# Считываем переведенные строки
translations = []
with open(translated_txt_path, "r", encoding="utf-8") as t:
for line in t:
line = line.strip()
if line.startswith("[0x") and "]" in line:
parts = line.split("]", 1)
offset_hex = parts[0].replace("[", "")
offset = int(offset_hex, 16)
text = parts[1].strip()
translations.append((offset, text))
# Сортируем изменения с конца файла к началу, чтобы сдвиги байт не ломали адреса
translations.sort(key=lambda x: x[0], reverse=True)
for offset, text in translations:
# Переводим русский текст в байты (игра обычно требует UTF-8 или Shift-JIS)
# Если игра со Switch/PC, оставляем utf-8. Если с Vita - смените на shift_jis
new_bytes = text.encode('utf-8') + b'\x00'
# Определяем длину оригинальной строки в байтах до нулевого терминатора
orig_len = 0
while data[offset + orig_len] != 0:
orig_len += 1
orig_len += 1 # Включая нулевой байт
# Заменяем старые байты на новые (размер файла изменится, это нормально)
data[offset : offset + orig_len] = new_bytes
# Автоматический пересчет указателей (Pointers) для движка Otomate
# Скрипт ищет ссылки на этот текст во всем файле и обновляет их смещение
diff = len(new_bytes) - orig_len
if diff != 0:
# Движок использует 4-байтовые указатели (LE)
for i in range(0, len(data) - 4, 4):
val = struct.unpack("<I", data[i:i+4])[0]
if val > offset:
# Если указатель вел на данные после нашей строки, сдвигаем его
data[i:i+4] = struct.pack("<I", val + diff)
with open(output_bin_path, "wb") as out:
out.write(data)
return True
# Массовый перебор всей вашей тысячи файлов
total_built = 0
for file_name in os.listdir("."):
if file_name.endswith(".stcm2l") or file_name.endswith(".DAT"):
# Ищем текстовый файл с переводом для текущего файла сценария
txt_name = file_name + ".txt"
if not os.path.exists(txt_name):
txt_name = file_name.replace(".stcm2l", ".txt").replace(".DAT", ".txt")
if os.path.exists(txt_name):
out_name = os.path.join(OUTPUT_FOLDER, file_name)
if pack_stcm2l(file_name, txt_name, out_name):
total_built += 1
print(f"[{total_built}] Успешно собран: {file_name}")
print(f"\nРабота завершена! Собрано файлов: {total_built}. Все они лежат в папке '{OUTPUT_FOLDER}'")