Odczytywanie danych z plików silnika Infinity

Większość plików gier opartych o silnik infinity (Baldurs Gate, Icewind Dale) to pliki binarne. Python jest prostym i przenośnym skryptowym językiem programistycznym. Bardzo łatwo odczytać z jego poziomu dane z owych binarnych plików. Podstawą będzie dokumentacja IESDP (IE File Formats). By odczytać plik binarny w pythonie wystarczy skrypt
import struct
plik = open('NAZWA_PLIKU', 'rb')
try:
        tekst = plik.read()
finally:
        plik.close()
Zmienna tekst przetrzymuje zawartość pliku podanego w funkcji open (w przykładzie: camb2su.eff). W IESDP mamy podany Offset i jego rozmiar (size). By odczytać określony obszar z pliku w pythonie wystarczy: print tekst[OFFSET:OFFSET+ROZMIAR] np. print tekst[0x0014:0x0014+4].

Typy Danych i sposób ich odczytywania

- resref, char array - odczyt bezpośredni
- dword, strref - odczyt z wykorzystaniem modułu struct
print struct.unpack('i', tekst[0x0014:0x0014+4])
- word - odczyt z wykorzystaniem modułu struct
print struct.unpack('h', tekst[0x0080:0x0080+2])
- byte, unsigned byte, char - odczyt z wykorzystaniem modułu struct
print struct.unpack('b', tekst[0x000b:0x000b+1])
By zapisać binarne dane (odczytywane przez struct.unpack) trzeba zwykłe dane przetworzyć na binarne za pomocą struct.pack z tym samym formatem (i, h, b).
Notka: struct.unpack zwraca tuplę. By dostać się do wyniku trzeba przypisać wynik do zmiennej i odwołać się do danego elementu (numerowane od zera) np.:
a = struct.unpack('i', tekst[0x0014:0x0014+4])
print a[0]

Podany kod zadziała pod dowolnych systemem operacyjnym pod którym działa python :)

Przykład dla pliku CRE:
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])
RkBlog

Tworzenie gier w Pythonie, 14 July 2008

Comment article
Comment article RkBlog main page Search RSS Contact