|
| 1 | +#!/usr/bin/env python |
| 2 | + |
| 3 | +import os, sys, io, collections, struct, unix_ar |
| 4 | +LuaObject = collections.namedtuple('LuaObject', ['info', 'contents']) |
| 5 | + |
| 6 | +if input("Have you made sure you verified that FileUtils::CFileToLua is compatible with the new lua51.lib file? (y/n) ") != 'y': |
| 7 | + exit() |
| 8 | + |
| 9 | +# Open lua lib in read mode |
| 10 | +lua_lib = unix_ar.open(sys.argv[1], mode = "r") |
| 11 | + |
| 12 | +# Get contents of io library |
| 13 | +lua_objects = [] |
| 14 | +for entry in lua_lib.infolist(): |
| 15 | + current_index = len(lua_objects) |
| 16 | + lua_objects.append(LuaObject(entry, lua_lib.extract(entry, path=io.BytesIO()).read())) |
| 17 | + if entry.name.strip(b"/").decode('iso-8859-1') == "lib_io.obj": |
| 18 | + io_lib_index = current_index |
| 19 | + |
| 20 | +# Close lua lib |
| 21 | +lua_lib.close() |
| 22 | + |
| 23 | +# Get io object file |
| 24 | +io_lib = bytearray(lua_objects[io_lib_index].contents) |
| 25 | + |
| 26 | +# Get address of string table |
| 27 | +symbolTableAddr, = struct.unpack_from("<I", io_lib, 8) |
| 28 | +numberOfSymbols, = struct.unpack_from("<I", io_lib, 12) |
| 29 | +stringTableAddr = symbolTableAddr + numberOfSymbols * 18 |
| 30 | + |
| 31 | +# Find function name offset relative to the string table |
| 32 | +functionStringAddr = io_lib.find(b"_io_std_new", stringTableAddr) |
| 33 | +assert functionStringAddr >= 0, 'String "_io_std_new" was not found' |
| 34 | +functionStringOffset = functionStringAddr - stringTableAddr |
| 35 | +assert functionStringOffset >= 0, 'String "_io_std_new" is outside of the string table' |
| 36 | + |
| 37 | +# Search address of symbol table entry |
| 38 | +for symbolIndex in range(numberOfSymbols): |
| 39 | + symbolAddr = symbolTableAddr + symbolIndex * 18 |
| 40 | + mustBeZero, = struct.unpack_from("<I", io_lib, symbolAddr) |
| 41 | + symbolNameOffset, = struct.unpack_from("<I", io_lib, symbolAddr + 4) |
| 42 | + if mustBeZero == 0 and symbolNameOffset == functionStringOffset: |
| 43 | + functionSymbolAddr = symbolAddr |
| 44 | + break |
| 45 | + |
| 46 | +else: |
| 47 | + assert False, "Symbol _io_std_new was not found" |
| 48 | + |
| 49 | +# Make symbol global |
| 50 | +io_lib[functionSymbolAddr + 16] = 0x2 |
| 51 | + |
| 52 | +# Update contents |
| 53 | +lua_objects[io_lib_index] = LuaObject(lua_objects[io_lib_index].info, bytes(io_lib)) |
| 54 | + |
| 55 | +# Backup old lua lib |
| 56 | +os.rename(sys.argv[1], sys.argv[1] + ".old") |
| 57 | + |
| 58 | +# Open lua lib in write mode |
| 59 | +lua_lib = unix_ar.open(sys.argv[1], mode = "w") |
| 60 | + |
| 61 | +# Add all files to archive |
| 62 | +for entry in lua_objects: |
| 63 | + lua_lib.addfile(entry.info, io.BytesIO(entry.contents)) |
| 64 | + |
| 65 | +# Close new lua lib |
| 66 | +lua_lib.close() |
| 67 | + |
| 68 | +print("Done!") |
| 69 | + |
| 70 | + |
| 71 | + |
0 commit comments