Elma 2/Code

From Elma Wiki
Jump to navigation Jump to search

Python: .mif parser

Unzip .mif

import os
import struct

offset=0

def output(msg):
    print('%4X: %s'%(offset,msg))
        
def Loop():
    if not(os.path.exists("out")):
        os.makedirs("out")
    for file in os.listdir():
        if(file.lower()=="default.mif"):
            output(file)
            with open(file,'rb') as f:
                offset=0
                data = iter(f.read())

                def munch(n):
                    global offset
                    offset+=n
                    return b''.join([bytes(chr(next(data)), 'latin1') for _ in range(n)])
                    
                assert struct.unpack('I', munch(4))[0]==100
                headerLength=struct.unpack('I', munch(4))[0]
                assert headerLength==0x2BF20
                number_of_files=struct.unpack('I', munch(4))[0]
                i=0
                files=0
                fileset_data=[None]*number_of_files
                while i<headerLength and files<number_of_files:
                    filename=munch(0x5C)
                    filename=filename[:filename.find(b'\0')].decode('latin1')
                    seekspot=struct.unpack('I', munch(4))[0]
                    filelength=struct.unpack('I', munch(4))[0]
                    fileset_data[files]=[filename,seekspot,filelength]
                    output("%s - %s: %X - %X"%(files,filename,seekspot,filelength))
                    files+=1
                    i+=0x5C+4+4
                for j in fileset_data:
                    f.seek(j[1],0)
                    with open("out\%s"%j[0],'wb') as g:
                        g.write(f.read(j[2]))
Loop()

Zip .mif

import os
import struct
import shutil
import time

headerlength=180000
        
def Loop():
    if not(os.path.exists("out")):
        print("No out/ directory found - aborting")
        return
    
    if not(os.path.exists("backup")):
        print("ok")
        os.mkdir("backup")
        print("Made backup/ directory")
        
    for file in os.listdir():
        if(file.lower()=="default.mif"):
            shutil.copy2(file,"backup/%s.mif"%time.strftime("%Y%m%d%H%M%S",time.gmtime()))
            print("Backup created in backup directory")
            break
    
    filelist=os.listdir("out")
    #filelist=sorted(filelist,key=lambda s:s.lower())
    n_files=len(filelist)
    file_pos=[None]*n_files
    file_len=[None]*n_files
    
    with open('default.mif','wb') as f:
        f.write(struct.pack('I', 100))
        f.write(struct.pack('I', headerlength))
        assert(n_files>0 and n_files<=1800)
        f.write(struct.pack('I', n_files))
        
        for i in range(headerlength):
            f.write(b'\xCD')
        f.write(struct.pack('I',0x5B7AAB9E))
        
        for i in range(n_files):
            #print(filelist[i])
            with open('out/%s'%filelist[i],'rb') as g:
                file_pos[i]=f.tell()
                f.write(g.read())
                file_len[i]=g.tell()
        f.write(struct.pack('I',0x5B7AAB9E))
        
        for i in range(n_files):
            f.seek(12+100*i)
            f.write(bytes(filelist[i], 'latin1'))
            f.write(b'\0')
            f.seek(12+100*i+92)
            f.write(struct.pack('I', file_pos[i]))
            f.write(struct.pack('I', file_len[i]))
    return
    
Loop()