74 lines
2.3 KiB
Python
74 lines
2.3 KiB
Python
import sys
|
|
|
|
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) + 2 # 8 байт заголовка + текст + 0000
|
|
return f"TextID: {text_id}, VoiceID: {voice_id}, Text: {text}", total_size
|
|
|
|
# База команд (идентификаторы в Big Endian)
|
|
command_db = {
|
|
0x1401: {
|
|
"name": "PlayBGM",
|
|
"size": 2,
|
|
"handler": lambda data, pos: (f"BGM Track: {int.from_bytes(data[pos:pos+2], 'little')}", 2)
|
|
},
|
|
0x0A00: {
|
|
"name": "ShowText",
|
|
"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
|
|
|
|
# Сохраняем в файл
|
|
with open("script" + file_path + ".txt", "w", encoding="utf-8") as f:
|
|
f.write("\n".join(output))
|
|
|
|
return output
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) < 2:
|
|
print("Usage: python parser.py <script.bin>")
|
|
sys.exit(1)
|
|
|
|
results = parse_script(sys.argv[1])
|
|
for line in results:
|
|
print(line) |