View Single Post
  #35  
Old 04-11-2008, 07:22 PM
Derision
Developer
 
Join Date: Feb 2004
Location: UK
Posts: 1,540
Default

Quote:
Originally Posted by KLS View Post
Should probably look for a more general solution, for version 2 EQGs but it's frustrating..
I don't know whether the Dev's worked out the formula for calculating the offsets for version 2 EQGs, but I searched and couldn't find anything relevant after this thread.

I've been messing about trying to get OpenEQ to load version 2 EQGs, and came across this old thread:

http://www.eqemulator.net/forums/arc...p/t-21615.html

Based on that, I knocked together the following bit of Python to calculate the offsets (excuse my Python, but I'm new at it ):

Code:
import struct, posixfile, socket, zlib, pdb, sys



for eqgfilename in ["broodlands", "guildhall", "guildlobby", "harbingers", "stillmoona", "stillmoonb", "thenest", "thundercrest"]:
    filenames = []
    files = []
 
    eqgfile = file(eqgfilename + '.eqg', 'rb')

    block = eqgfile.read(12)
    (offset, magic, unknown) = struct.unpack('L4sL', block)


    eqgfile.seek(offset, posixfile.SEEK_SET)

    block = eqgfile.read(4)

    dir_count = struct.unpack('I', block)



    for i in range(0, dir_count[0]):
        block = eqgfile.read(12)
        (crc, fileoffset, filesize) = struct.unpack('LLL', block)


        if crc == 0x61580AC9:

            CurrentPos = eqgfile.tell()
	    eqgfile.seek(fileoffset, posixfile.SEEK_SET)
	    InflatedLength = 0
	    uncompressed = ''
   	    while InflatedLength < filesize:
	        block = eqgfile.read(8)
	        (deflen, inflen) = struct.unpack('LL', block)

	        block = eqgfile.read(deflen)
	        uncompressed = uncompressed + zlib.decompress(block)
	        InflatedLength = InflatedLength + inflen

	    eqgfile.seek(CurrentPos, posixfile.SEEK_SET)
            fncount = struct.unpack('L', uncompressed[0:4])	

	    pos = 4
	    for j in range(0, fncount[0]):
	        fnlen = struct.unpack('L', uncompressed[pos:pos+4])

	        fmt = str(fnlen[0]) + 's'
	        fname = struct.unpack(fmt, uncompressed[pos+4:pos+4+fnlen[0]])
                fname = fname[0].strip('\x00')

                if fname[len(fname)-4:len(fname)] == '.ter':
                    wantedfile = fname

	        filenames.append(fname)
	        pos = pos + 4 + fnlen[0]
        else:
            files.append((eqgfile.tell() - 12, fileoffset))


    for i in range(dir_count[0] - 2, 0, -1):
        for j in range(0, i):

            if files[j][1] > files[j+1][1]:
                tmp = files[j]
                files[j] = files[j+1]
                files[j+1] = tmp



    for a in range(0, dir_count[0]-1):
        if filenames[a] == wantedfile:

	    eqgfile.seek(files[a][0], posixfile.SEEK_SET)
            block = eqgfile.read(12)
            (crc, fileoffset, filesize) = struct.unpack('LLL', block)

	    eqgfile.seek(files[a][1], posixfile.SEEK_SET)
	    break

    uncompressed = ''
    inf = 0

    while inf < filesize:
        block = eqgfile.read(8)
        (deflen, inflen) = struct.unpack('LL', block)

        block = eqgfile.read(deflen)
        uncompressed = uncompressed + zlib.decompress(block)
        inf = inf + inflen

    (magic, version, list_len, obj_count, vert_count, tri_count) = struct.unpack('4sLLLLL', uncompressed[0:24])


    ter_tmp = list_len
    pos = 24
    while pos < ter_tmp:
        strlen = 0 
        while uncompressed[pos+strlen] != chr(0):
            strlen = strlen + 1
        fmt = str(strlen) + 's'
        (strvar) = struct.unpack(fmt, uncompressed[pos:pos+strlen])
        pos = pos + strlen+1

        strlen = 0 
        while uncompressed[pos+strlen] != chr(0):
            strlen = strlen + 1
        fmt = str(strlen) + 's'
        (strval) = struct.unpack(fmt, uncompressed[pos:pos+strlen])
        pos = pos + strlen+1



    pos = 24 + list_len
  
    for b in range(0, obj_count):

        (index, name_offset, another_name_offset, property_count) = struct.unpack('LLLL', uncompressed[pos: pos+16])

        pos = pos + 16
        for a in range(0, property_count):
            pos = pos + 12

    print "Offset for EQG Zone %-20s (TER: %-22s) is %8X" % (eqgfilename, wantedfile, pos)
For the EQG zones hardcoded in the currently downloadable version of azone, it spits out the same offsets:

Code:
Offset for EQG Zone broodlands           (TER: ter_broodlands.ter    ) is    382B7
Offset for EQG Zone guildhall            (TER: ter_guildhall.ter     ) is     307E
Offset for EQG Zone guildlobby           (TER: ter_guildlobby.ter    ) is     41A3
Offset for EQG Zone harbingers           (TER: ter_harbingers.ter    ) is     1178
Offset for EQG Zone stillmoona           (TER: ter_main.ter          ) is    71948
Offset for EQG Zone stillmoonb           (TER: ter_easterntemple.ter ) is     E33E
Offset for EQG Zone thenest              (TER: ter_abyss01.ter       ) is    CA244
Offset for EQG Zone thundercrest         (TER: ter_stormtower01.ter  ) is    6222C
Reply With Quote