Files
UltraChat/clannad_parser/parser.py
2026-03-17 00:16:49 +05:00

121 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import sys
import os
def parse_text_command(data, pos):
# Читаем параметры в Little Endian
text_id = int.from_bytes(data[pos:pos+2], 'little')
voice_id = int.from_bytes(data[pos+2:pos+6], 'little')
pos += 6
# Собираем текст до 0000
text_bytes = bytearray()
while pos + 2 <= len(data):
char_bytes = data[pos:pos+2]
if char_bytes == b'\x00\x00':
break
text_bytes.extend(char_bytes)
pos += 2
# Декодируем UTF-16LE текст
text = text_bytes.decode('utf-16le', errors='replace')
total_size = 8 + len(text_bytes) # 8 байт заголовка + текст + 0000
return f"TextID: {text_id}, VoiceID: {voice_id}, Text: {text}", total_size
# База команд (идентификаторы в Big Endian)
command_db = {
0x0001: {
"name": "Sprite",
"size": 14,
"handler": lambda data, pos: (f"ID: {int.from_bytes(data[pos+2:pos+4], 'little')} | " \
+ f"MODE: {int.from_bytes(data[pos+4:pos+6], 'little')} | " \
+ f"X: {int.from_bytes(data[pos+6:pos+8], 'big')} | " \
+ f"Y: {int.from_bytes(data[pos+8:pos+10], 'big')} | " \
+ f"fade: {int.from_bytes(data[pos+10:pos+12], 'big')}ms" \
, 12)
},
0x1401: {
"name": "BGM",
"size": 2,
"handler": lambda data, pos: (f"BGM Track: {int.from_bytes(data[pos:pos+2], 'little')}", 2)
},
0x1600: {
"name": "Pause",
"size": 2,
"handler": lambda data, pos: (f"{int.from_bytes(data[pos:pos+2], 'little')}ms", 2)
},
0x0A00: {
"name": "Text",
"size": 8,
"handler": parse_text_command
}
}
def parse_script(file_path):
with open(file_path, 'rb') as f:
data = f.read()
pos = 0
output = []
while pos + 2 <= len(data):
# Определяем команду в Big Endian
cmd = int.from_bytes(data[pos:pos+2], 'big')
if cmd in command_db:
cmd_info = command_db[cmd]
result, size = cmd_info["handler"](data, pos + 2)
output.append(f"[0x{pos:08X}][0x{cmd:04X}] {cmd_info['name']}: {result}")
pos += 2 + size # 2 байта команды + размер данных
# Выравнивание по 4 байтам
while pos % 4 != 0:
pos += 1
else:
output.append(f"[0x{pos:08X}][0x{cmd:04X}] UNKNOWN COMMAND")
pos += 2
# Сохраняем в файл
output_file = file_path + ".txt"
with open(output_file, "w", encoding="utf-8") as f:
f.write("\n".join(output))
print(f"Обработан: {file_path} -> {output_file}")
return output
def batch_process_scr_files():
# Получаем текущий каталог
current_dir = os.getcwd()
# Ищем все файлы с расширением .scr
scr_files = []
for file_name in os.listdir(current_dir):
if file_name.lower().endswith('.scr'):
scr_files.append(file_name)
if not scr_files:
print("Файлы с расширением .scr не найдены в текущем каталоге.")
return []
print(f"Найдено {len(scr_files)} файлов .scr для обработки:")
for file_name in scr_files:
print(f" - {file_name}")
results = []
for file_name in scr_files:
try:
file_results = parse_script(file_name)
results.extend(file_results)
except Exception as e:
print(f"Ошибка при обработке файла {file_name}: {e}")
return results
if __name__ == "__main__":
if len(sys.argv) > 1:
# Если указан аргумент командной строки, обрабатываем указанный файл
results = parse_script(sys.argv[1])
for line in results:
print(line)
else:
# Если аргументов нет, сканируем текущий каталог
batch_process_scr_files()