121 lines
4.2 KiB
Python
121 lines
4.2 KiB
Python
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() |