import os import struct import codecs import json from ibunroku_settings import load_encoding_table, commands, russian, hex_from_str def from_hex_str(s): """Converts a hex string to an integer.""" bin_ = ''.join(hex_from_str[v] for v in s) bin_ = bin_[8:] + bin_[:8] return int(bin_, 2) def inject_event_strings(bin_file_path, json_file_path, tbl_path): """ Injects event strings from a JSON file into a binary file. Args: bin_file_path (str): Path to the original binary file. json_file_path (str): Path to the JSON file containing parsed strings. tbl_path (str): Path to the encoding table file. """ encoding_table = load_encoding_table(tbl_path) with open(bin_file_path, 'rb') as binfile: binfile_data = binfile.read() with codecs.open(json_file_path, 'r', encoding='utf_8') as jsonfile: json_data = json.load(jsonfile) # Extract header information header_size = json_data["Header"]["Header Size"] file_size = json_data["Header"]["File Size"] music = json_data["Header"]["Music"] end_text_table = json_data["Header"]["End of Text Table"] unk_pointer1 = json_data["Header"]["Unknown Pointer 1"] - end_text_table unk_pointer2 = json_data["Header"]["Unknown Pointer 2"] - end_text_table unk_pointer3 = json_data["Header"]["Unknown Pointer 3"] - end_text_table script_table_pointer = json_data["Header"]["Script Table Pointer"] text_table_pointer = json_data["Header"]["Text Table Pointer"] data_after = json_data["Other Data"] # Prepare kanji dictionary kanji = {v: k for k, v in encoding_table.items()} # Convert strings and update pointers textblock = b'' new_pointers = [text_table_pointer] text_pointer = text_table_pointer for s in json_data["Parsed strings"]: converted_s = b'' i = 0 while i < len(json_data["Parsed strings"][s]): char_s = json_data["Parsed strings"][s][i] if char_s in russian: converted_s += struct.pack('B', russian.index(char_s)) i += 1 elif char_s in encoding_table.values(): char_hex_code = [k for k, v in encoding_table.items() if v == char_s][0] converted_s += struct.pack('B', int(char_hex_code, 16)) i += 1 elif char_s == "|": kanji_hex_code = json_data["Parsed strings"][s][i+1:i+5] converted_s += struct.pack('H', from_hex_str(kanji_hex_code)) i += 5 elif char_s == '[': command = '' j = 1 while ']' not in command: command += json_data["Parsed strings"][s][i+j] j += 1 if '=' in command: command = command.split('=') command_index = commands.index(f'[{command[0]}]') if command[0] == "WAIT": converted_s += b'\xFF' + struct.pack('B', command_index) + struct.pack('B', int(command[1].rstrip(']'))) + b'\x00' else: converted_s += b'\xFF' + struct.pack('B', command_index) + struct.pack('B', int(command[1].rstrip(']'))) else: converted_s += b'\xFF' + struct.pack('B', commands.index(f'[{command}]')) i += j else: kanji_hex_code = kanji[char_s] converted_s += struct.pack('>H', from_hex_str(kanji_hex_code)) i += 1 text_pointer += len(converted_s) new_pointers.append(text_pointer) textblock += converted_s # Update file size and pointers file_size = text_table_pointer + len(textblock) + len(data_after) end_text_table = text_table_pointer + len(textblock) unk_pointer1 += end_text_table unk_pointer2 += end_text_table unk_pointer3 += end_text_table # Update text pointers in the binary file new_table = binfile_data[:text_table_pointer+8] for i, s in enumerate(json_data["Parsed strings"]): new_table = new_table[:int(s)+8] + struct.pack('