Author Topic: Reading Infinity files in Python  (Read 6733 times)

Offline Riklaunim

  • b'ahlach
  • Planewalker
  • *****
  • Posts: 38
  • Gender: Male
    • Riklaunims cRPG Library
Reading Infinity files in Python
« on: March 03, 2006, 09:59:41 AM »
To read a binary file in python we need a basic code:
Code: [Select]
import struct
binfile = open('FILENAME', 'rb')
try:
        bin = binfile.read()
finally:
        binfile.close()
Where bin variable contains content of the whole file. On IESDP we have IE File Formats where each file type has full description. We can read part of the file using given OFFSET - print bin[OFFSET:OFFSET+SIZE]

IF the data is binary - we have to convert it.
- resref, char array - direct acces, non binary
- dword, strref - convert with struct
Code: [Select]
print struct.unpack('i', bin[0x0014:0x0014+4])- word - convert with struct
Code: [Select]
print struct.unpack('h', bin[0x0080:0x0080+2])- byte, unsigned byte, char - convert with struct
Code: [Select]
print struct.unpack('b', bin[0x000b:0x000b+1])
note 1: To write binary data from a given text data use struct.pack with the same format (i, h, b).
note 2: struct.unpack returns a tuple. To acces a value:
Code: [Select]
a = struct.unpack('i', tekst[0x0014:0x0014+4])
print a[0]
Each tuple element has a number (from zero). This code will work everywhere python works. Should also work on jython (python in java) and IronPython (python in .NET). If someone wants to make a GUI app - on windows py2exe can help make an *exe from the Application, and for GUI libs: python tkinter is good for Mac and Windows, looks terible on Linux/Unix. pyGTK+ - good for all 3 OS. pyQT - easy, good for Unix/Linux and Mac, on Windows - from PyQT4 (in development) ;)
For compressed biffs there is zlib module :)


CRE example:
Code: [Select]
import struct
plik = open('beheld01.cre', 'rb')
try:
        tekst = plik.read()
finally:
        plik.close()

print 'File Signature: ' + tekst[0x0000:0x0000+4]
print 'Version: ' + tekst[0x0004:0x0004+4]
print 'Long Creature name: ' + str(struct.unpack('i', tekst[0x0008:0x0008+4])[0])
print 'Short Creature name: ' + str(struct.unpack('i', tekst[0x000c:0x000c+4])[0])
print 'Creature flags: ' + str(struct.unpack('i', tekst[0x0010:0x0010+4])[0])
print 'XP for killing: ' + str(struct.unpack('i', tekst[0x0014:0x0014+4])[0])
print 'CRE Level: ' + str(struct.unpack('i', tekst[0x0018:0x0018+4])[0])
print 'Current HP: ' + str(struct.unpack('h', tekst[0x0024:0x0024+2])[0])

Offline Riklaunim

  • b'ahlach
  • Planewalker
  • *****
  • Posts: 38
  • Gender: Male
    • Riklaunims cRPG Library
Re: Reading Infinity files in Python
« Reply #1 on: March 06, 2006, 10:31:58 AM »
Zlib compressed data
SAV and BIFC files have data compressed with zlib. In Python we have zlib module so we can decompress the data. This code decompress everything from a sav file and save it to files:
Code: [Select]
import struct
import zlib
# we need a SAV file in the same dir
plik = open('baldur.sav', 'rb')
try:
        tekst = plik.read()
finally:
        plik.close()

a = 0x0004 + 4
# decompress everything until end of file
while a < len(tekst):
lenght = struct.unpack('i', tekst[a:a+4])[0]
print 'Lenght of filename: ' + str(lenght)
# get the filename - it has various lenght
filename = str(tekst[a+4:a+16])
# split into 2 parts using dot as splitter
file_name = filename.split('.')
#get the extension+rubbish
ext = file_name[1]
# kill the rubbish, read only 3 chars :)
file_name = file_name[0] +'.'+ ext[0:3]
print 'Filename: ' + file_name
decomp_size = struct.unpack('i', tekst[a+0x0004+lenght:a+0x0004+lenght+4])[0]
print 'Decompressed size: ' + str(decomp_size)
comp_size = struct.unpack('i', tekst[a+0x0008+lenght:a+0x0008+lenght+4])[0]
print 'Compressed size: ' + str(comp_size)
if decomp_size != 0:
code = tekst[a+0x000c+lenght:a+0x000c+lenght+comp_size]
open(file_name, 'wb').write(zlib.decompress(code))
print 'Saved Raw data as ' + file_name
a = a+0x000c+lenght+comp_size
print "----------------------------"

« Last Edit: March 06, 2006, 11:57:12 AM by Riklaunim »

Offline jcompton

  • Niche Exploiter
  • Administrator
  • Planewalker
  • *****
  • Posts: 7232
Re: Reading Infinity files in Python
« Reply #2 on: March 09, 2006, 02:52:51 PM »
Okay, I'll give in and ask. What are you developing in python that's led you to work all this out?
Cespenar says, "Kelsey and friends be at the Pocket Plane? Ohhh yesssss!" http://www.pocketplane.net

Offline Riklaunim

  • b'ahlach
  • Planewalker
  • *****
  • Posts: 38
  • Gender: Male
    • Riklaunims cRPG Library
Re: Reading Infinity files in Python
« Reply #3 on: March 10, 2006, 10:40:48 AM »
just learning python ;) and maybe I'll make a pyQT based Infinity browser/editor in the near future.
Using cherryPy or Zope or other Python servers some IE "tools" could become online web based tools :)

Offline Riklaunim

  • b'ahlach
  • Planewalker
  • *****
  • Posts: 38
  • Gender: Male
    • Riklaunims cRPG Library
Re: Reading Infinity files in Python
« Reply #4 on: August 18, 2006, 05:29:49 PM »
If someone is interested: Reading Infinity Engine files in Django - a python web framework

 

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

Name: Email:
Verification:
Type the letters shown in the picture
Listen to the letters / Request another image
Type the letters shown in the picture:
What color are clouds?:
What is the fourth word in this sentence?: