Пример #1
0
def parsegtc(folder, secondary, missing, nobackup, names, f, parent):
    try:
        doingtrain = doinghighway = False
        h = file(join(folder, f), 'rU')
        for passtype in [
                'route', 'train'
        ]:  # have to do two passes since train may be defined after route
            h.seek(0)
            for line in h:
                line = line.strip()
                if not line:
                    doingtrain = doinghighway = False
                    continue
                line = line.split('#')[0].strip()
                if not line: continue
                cmd = line.split()[0]
                if cmd == passtype == 'route' or doingtrain or doinghighway:
                    line = line.split(None, (doinghighway and 2)
                                      or (doingtrain and 3) or 4)
                    if doinghighway:
                        if len(line) != 3:
                            doinghighway = False  # on to waypoints
                            continue
                    else:
                        if len(line) != (doingtrain and 4 or 5):
                            continue  # syntax error
                    obj = unicodeify(line[-1].replace(':', '/'))
                    obj2 = casepath(folder, obj)
                    if exists(join(folder, obj2)):
                        if obj not in secondary:
                            parseobj(folder, secondary, missing, nobackup,
                                     names, obj2, f)
                        elif f not in secondary[obj2]:
                            secondary[obj2].append(f)
                    elif obj in names:  # library obj
                        if names[obj]:
                            if obj not in nobackup:
                                nobackup[obj] = [f]
                            elif f not in nobackup[obj]:
                                nobackup[obj].append(f)
                    elif obj not in missing:
                        missing[obj] = [f]
                    elif f not in missing[obj]:
                        missing[obj].append(f)
                elif cmd == passtype == 'train':
                    doingtrain = True
                    obj = line.split(None, 1)[-1].replace(':', '/')
                    if obj in missing:
                        missing[obj].remove(f)
                        if not missing[obj]:
                            missing.pop(obj)
                elif cmd == 'highway' and passtype == 'route':
                    doinghighway = True
        h.close()
    except:
        if __debug__:
            print f
            print_exc()
        die("Can't read %s" % f)
Пример #2
0
def parselib(folder, secondary, missing, nobackup, names, f, parent):
    try:
        h = file(join(folder, f), 'rU')
        if not h.readline().strip(' \t\xef\xbb\xbf')[0] in [
                'I', 'A'
        ]:  # Also strip UTF-8 BOM
            raise IOError
        if not h.readline().split()[0] == '800':
            raise IOError
        if not h.readline().split()[0] == 'LIBRARY':
            raise IOError
        for line in h:
            line = line.split('#')[0].strip()
            if not line: continue
            cmd = line.split()[0]
            line = line[len(cmd):].strip()
            if cmd in [
                    'EXPORT', 'EXPORT_RATIO', 'EXPORT_EXTEND', 'EXPORT_BACKUP'
            ]:
                if cmd == 'EXPORT_RATIO':
                    line = line[len(line.split()[0]):].strip()
                elif cmd == 'EXPORT_BACKUP':
                    names[line.split()[0]] = None  # Override exported name
                line = line[len(line.split()[0]):].strip()
                obj = casepath(
                    folder,
                    unicodeify(line.replace(':', '/').replace('\\', '/')))
                if obj not in secondary:
                    if not obj[-4:].lower() in textypes:
                        # eg A0 LHA Scenery System exports textures!
                        parseobj(folder, secondary, missing, nobackup, names,
                                 obj, f)
                    else:
                        secondary[obj] = [f]
                elif f not in secondary[obj]:
                    secondary[obj].append(f)
        h.close()
    except:
        if __debug__:
            print f
            print_exc()
        die("Can't read %s" % f)
Пример #3
0
def parsedsf(folder, secondary, missing, nobackup, names, f, parent):
    try:
        h = file(join(folder, f), 'rb')
        if h.read(8) != 'XPLNEDSF' or unpack(
                '<I', h.read(4)) != (1, ) or h.read(4) != 'DAEH':
            raise IOError
        (l, ) = unpack('<I', h.read(4))
        headend = h.tell() + l - 8
        if h.read(4) != 'PORP':
            raise IOError
        h.seek(headend)

        # Definitions Atom
        if h.read(4) != 'NFED':
            raise IOError
        (l, ) = unpack('<I', h.read(4))
        defnend = h.tell() + l - 8
        while h.tell() < defnend:
            c = h.read(4)
            (l, ) = unpack('<I', h.read(4))
            if l == 8:
                pass  # empty
            elif c in ['TRET', 'TJBO', 'YLOP', 'WTEN']:
                objs = h.read(l - 9).split('\0')
                for o in objs:
                    obj = unicodeify(o.replace(':', '/').replace('\\', '/'))
                    if c == 'TJBO':
                        seq = ['', 'custom objects']  # v7 style for objs only
                    else:
                        seq = ['']
                    for d in seq:
                        obj2 = casepath(folder, join(d, obj))
                        if exists(join(folder, obj2)):
                            if obj2 not in secondary:
                                parseobj(folder, secondary, missing, nobackup,
                                         names, obj2, f)
                            elif f not in secondary[obj2]:
                                secondary[obj2].append(f)
                            break
                    else:
                        if obj in names:  # terrain_Water or library obj
                            if names[obj]:
                                if obj not in nobackup:
                                    nobackup[obj] = [f]
                                elif f not in nobackup[obj]:
                                    nobackup[obj].append(f)
                        elif obj not in missing:
                            missing[obj] = [f]
                        elif f not in missing[obj]:
                            missing[obj].append(f)

                h.read(1)
            else:
                h.seek(l - 8, 1)

        h.close()
    except:
        if __debug__:
            print f
            print_exc()
        die("Can't read %s" % f)
Пример #4
0
def liverytex(folder, secondary, missing, nobackup, tex, parent, dolit=False):
    base = dirname(parent)
    found = False
    (tex, origext) = splitext(tex)
    for ext in textypes:
        tex2 = casepath(folder, join(base, tex + ext))
        if exists(join(folder, tex2)):
            found = True
            if not tex2 in secondary:
                secondary[tex2] = [parent]
            elif parent not in secondary[tex2]:
                secondary[tex2].append(parent)
    if not found:
        tex2 = join(base, tex)
        if tex not in missing:
            missing[tex + origext] = [parent]
        elif parent not in missing[tex]:
            missing[tex + origext].append(parent)

    if dolit:
        for lit in ['_lit', 'lit']:
            found = False
            for ext in textypes:
                tex2 = casepath(folder, join(base, tex + lit + ext))
                if exists(join(folder, tex2)):
                    found = True
                    if not tex2 in secondary:
                        secondary[tex2] = [parent]
                    elif parent not in secondary[tex2]:
                        secondary[tex2].append(parent)
            if found: break

    livdir = casepath(folder, 'liveries')
    if not isdir(join(folder, livdir)): return
    for objbase in listdir(join(folder, livdir)):
        if base:
            objdir = join(livdir, objbase,
                          casepath(join(folder, livdir, objbase), base))
        else:
            objdir = join(livdir, objbase)
        if not isdir(join(folder, objdir)): continue
        for ext in textypes:
            tex2 = join(objdir, casepath(join(folder, objdir), tex + ext))
            if exists(join(folder, tex2)):
                if not tex2 in secondary:
                    secondary[tex2] = [parent]
                elif parent not in secondary[tex2]:
                    secondary[tex2].append(parent)

        if dolit:
            for lit in ['_lit', 'lit']:
                found = False
                for ext in textypes:
                    tex2 = join(
                        objdir, casepath(join(folder, objdir),
                                         tex + lit + ext))
                    if exists(join(folder, tex2)):
                        found = True
                        if not tex2 in secondary:
                            secondary[tex2] = [parent]
                        elif parent not in secondary[tex2]:
                            secondary[tex2].append(parent)
                if found: break
Пример #5
0
def parseobj(folder, secondary, missing, nobackup, names, f, parent):
    try:
        h = file(join(folder, f), 'rU')
        secondary[f] = [parent]  # file at least is readable - ship it
        if not h.readline().strip(' \t\xef\xbb\xbf')[0] in [
                'I', 'A'
        ]:  # Also strip UTF-8 BOM
            raise IOError
        version = h.readline().split()[0]
        if not version in ['2', '700', '800', '850', '1000']:
            raise IOError
        if version in ['2', '700']:
            if version != '2' and not h.readline().split()[0] == 'OBJ':
                raise IOError
            for line in h:
                tex = line.strip()
                if tex:
                    if '//' in tex: tex = tex[:tex.index('//')].strip()
                    tex = unicodeify(tex.replace(':', '/').replace('\\', '/'))
                    if tex.lower() == 'none':
                        h.close()
                        return
                    break
            else:
                raise IOError

            if not names:
                # Misc Object
                liverytex(folder, secondary, missing, nobackup, tex, f, True)
                h.close()
                return
            (tex, origext) = splitext(tex)
            for d in [dirname(f), 'custom object textures']:
                # look for alternate extensions before custom object textures
                for ext in textypes:
                    tex2 = casepath(folder, join(d, tex + ext))
                    if exists(join(folder, tex2)):
                        if not tex2 in secondary:
                            secondary[tex2] = [f]
                        elif f not in secondary[tex2]:
                            secondary[tex2].append(f)
                        for lit in ['_lit', 'lit']:
                            for d in [dirname(f), 'custom object textures']:
                                found = False
                                for ext in textypes:
                                    tex2 = casepath(folder,
                                                    join(d, tex + lit + ext))
                                    if exists(join(folder, tex2)):
                                        found = True
                                        if not tex2 in secondary:
                                            secondary[tex2] = [f]
                                        elif f not in secondary[tex2]:
                                            secondary[tex2].append(f)
                                if found: break  # found matching ext
                            else:
                                continue  # next lit
                            break  # found matching dir
                        break  # found daytime
                else:
                    continue  # next dir
                break  # found matching ext
            else:  # missing
                if f.lower().startswith('custom objects'):
                    tex2 = normpath(tex + origext)
                else:
                    tex2 = normpath(join(dirname(f), tex + origext))
                if tex2 not in missing:
                    missing[tex2] = [f]
                elif f not in missing[tex2]:
                    missing[tex2].append(f)
            h.close()
            return

        else:
            kind = h.readline().split()[0]
            if not kind in [
                    'AG_POINT', 'BEACH', 'DECAL', 'FACADE', 'FOREST',
                    'LINE_PAINT', 'ROADS', 'OBJ', 'DRAPED_POLYGON',
                    'OBJECT_STRING', 'TERRAIN'
            ]:
                raise IOError
            for line in h:
                c = line.split('#')[0].split('//')[0].split()
                if not c: continue
                if kind == 'OBJ' and c[0] == 'VT': break  # early exit
                if (c[0] in [
                        'TEXTURE', 'TEXTURE_LIT', 'TEXTURE_NORMAL',
                        'TEXTURE_DRAPED', 'TEXTURE_DRAPED_NORMAL',
                        'TEXTURE_CONTROL', 'TEXTURE_CONTROL_NOWRAP',
                        'TEXTURE_DETAIL', 'TEXTURE_TERRAIN', 'TEXTURE_TILE',
                        'DECAL', 'DECAL_RGBA', 'DECAL_PARAMS',
                        'DECAL_PARAMS_PROJ'
                ] or (kind == 'DRAPED_POLYGON'
                      and c[0] in ['TEXTURE_NOWRAP', 'TEXTURE_LIT_NOWRAP']) or
                    (kind == 'BEACH' and c[0] in ['BASE_TEX', 'LIT_TEX']) or
                    (kind == 'TERRAIN' and c[0] in [
                        'BASE_TEX', 'BASE_TEX_NOWRAP', 'LIT_TEX',
                        'LIT_TEX_NOWRAP', 'NORMAL_TEX', 'NORMAL_TEX_NOWRAP',
                        'BORDER_TEX', 'BORDER_TEX_WRAP', 'BORDER_TEX_NOWRAP',
                        'COMPOSITE_TEX', 'COMPOSITE_TEX_NOWRAP'
                    ])):
                    # Texture
                    if kind == 'AG_POINT' and c[0] == 'TEXTURE_NORMAL':
                        tex = line.strip().split(None, 2)[-1]
                    elif c[0] in ['DECAL', 'DECAL_RGBA']:
                        tex = line.strip().split(None, 2)[-1]
                    elif c[0] in ['TEXTURE_DETAIL', 'TEXTURE_TERRAIN']:
                        tex = line.strip().split(None, 3)[-1]
                    elif c[0] == 'TEXTURE_TILE':
                        tex = line.strip().split(None, 5)[-1]
                    elif c[0] in ['DECAL_PARAMS', 'DECAL_PARAMS_PROJ']:
                        tex = line.strip().split(None, 15)[-1]
                    else:
                        tex = line.strip().split(None, 1)[-1]
                    if not tex: continue
                    tex = unicodeify(tex.replace(':', '/').replace('\\', '/'))

                    if not names:
                        # Misc Object
                        liverytex(folder, secondary, missing, nobackup, tex, f)
                        continue
                    (tex, origext) = splitext(tex)
                    for d in [dirname(f), 'custom object textures']:
                        # look for alternate extensions before custom object textures
                        found = False
                        for ext in textypes:
                            tex2 = casepath(folder, join(d, tex + ext))
                            if exists(join(folder, tex2)):
                                found = True
                                if not tex2 in secondary:
                                    secondary[tex2] = [f]
                                elif f not in secondary[tex2]:
                                    secondary[tex2].append(f)
                        if found: break  # found matching ext
                    else:  # missing
                        if kind == 'OBJ' and c[0] == 'TEXTURE_LIT':
                            pass  # don't warn on missing obj lit tex
                        else:
                            if kind == 'OBJ' and f.lower().startswith(
                                    'custom objects'):
                                tex2 = normpath(tex + origext)
                            else:
                                tex2 = normpath(join(dirname(f),
                                                     tex + origext))
                            if tex2 not in missing:
                                missing[tex2] = [f]
                            elif f not in missing[tex2]:
                                missing[tex2].append(f)

                elif ((kind == 'AG_POINT' and c[0] in ['VEGETATION', 'OBJECT'])
                      or (kind == 'FACADE' and c[0] == 'OBJ')
                      or (kind == 'DECAL' and c[0] == 'DECAL_LIB')
                      or (kind == 'OBJECT_STRING' and c[0] == 'OBJECT')):
                    # Sub-object
                    obj = unicodeify(c[-1].replace(':',
                                                   '/').replace('\\', '/'))
                    obj2 = casepath(folder, join(dirname(f), obj))
                    if exists(join(folder, obj2)):
                        if obj2 not in secondary:
                            parseobj(folder, secondary, missing, nobackup,
                                     names, obj2, f)
                        elif f not in secondary[obj2]:
                            secondary[obj2].append(f)
                    else:
                        if obj in names:  # terrain_Water or library obj
                            if names[obj]:
                                if obj not in nobackup:
                                    nobackup[obj] = [f]
                                elif f not in nobackup[obj]:
                                    nobackup[obj].append(f)
                        elif obj not in missing:
                            missing[obj] = [f]
                        elif f not in missing[obj]:
                            missing[obj].append(f)

        h.close()
    except:
        if __debug__:
            print f
            print_exc()
        if f not in missing:
            missing[f] = [parent]
        elif parent not in missing[f]:
            missing[f].append(parent)
Пример #6
0
def parseacf(folder, secondary, missing, nobackup, names, f, parent):
    newacf = {}
    try:
        h = file(join(folder, f), 'rb')
        c = h.read(1)
        if c == 'a':
            fmt = '>'
        elif c == 'i':
            fmt = '<'
        elif c in ['I', 'A']:
            # >1000 style?
            h.seek(0)
            try:
                if not h.readline().strip()[0] in ['I', 'A']: raise IOError
                version = int(h.readline().split()[0])
                if version <= 1000 or h.readline().split()[0] != 'ACF':
                    raise IOError
                for line in h:
                    line = line.split('#')[0].strip()
                    if not line: continue
                    line = line.split(None, 2)
                    if line[0] == 'P':
                        newacf[line[1]] = line[2].strip()
            except:
                die("%s isn't a v7, v8, v9 or v10 X-Plane file! " % f)
        else:
            die("%s isn't a v7, v8, v9 or v10 X-Plane file! " % f)

        if newacf:
            aflDIM = int(newacf['_wing/count'])
            Rafl0 = '_afl_file_R0'
            Rafl1 = '_afl_file_R1'
            Tafl0 = '_afl_file_T0'
            Tafl1 = '_afl_file_T1'
            wpnDIM = int(newacf['_wpna/count'])
            objDIM = int(newacf['_obja/count'])
        else:
            (version, ) = unpack(fmt + 'i', h.read(4))
            if version == 8000:
                version = 800  # v8.00 format was labelled 8000
            elif version < 600 or version > 1000:
                die("%s isn't a v7, v8, v9 or v10 X-Plane file! " % f)
            elif version < 740:
                die("%s is in X-Plane %4.2f format! \n\nPlease re-save it using Plane-Maker 7.63. "
                    % (f, version / 100.0))
            elif version not in [
                    740, 810, 815, 830, 840, 860, 900, 901, 902, 920, 941
            ]:
                die("%s is in X-Plane %4.2f format! \n\nI can't read %4.2f format planes. "
                    % (f, version / 100.0, version / 100.0))

            txtLEN = 40
            if version < 800:
                aflDIM = 44
                partSTRIDE = 4
                part = 0x2acd
                aflSTRIDE = 0x28
                Rafl0 = 0x02bf1
                Rafl1 = 0x03759
                Tafl0 = 0x042c1
                Tafl1 = 0x04e29
                wpnDIM = 24
                wpnSTRIDE = 500
                wpn = 0x098c29
            elif version == 800:
                version = 800
                aflDIM = 56
                aflSTRIDE = 0x6cc
                Rafl0 = 0x26ae9
                Rafl1 = 0x26b11
                Tafl0 = 0x26b39
                Tafl1 = 0x26b61
                partSTRIDE = 0x2ee4
                part = 0x3e77d
                wpnDIM = 24
                wpnSTRIDE = 0x48
                wpn = 0x155251
            else:  # version>800
                aflDIM = 56
                aflSTRIDE = 0x8b4
                Rafl0 = 0x26ae9
                Rafl1 = 0x26b11
                Tafl0 = 0x26b39
                Tafl1 = 0x26b61
                partSTRIDE = 0x2ee4
                part = 0x4523d
                wpnDIM = 24
                wpnSTRIDE = 0x48
                wpn = 0x15bd11
                objDIM = 24
                objSTRIDE = 0x48  # 8.40 and later
                obj = 0x15ee31

        for i in range(aflDIM):
            if newacf:
                eq = '_wing/%d/' % i
            else:
                h.seek(part + i * partSTRIDE)
                (eq, ) = unpack(fmt + 'i', h.read(4))
                if not eq:
                    continue  # airfoil names not cleared if doesn't exist
            for b in [Rafl0, Rafl1, Tafl0, Tafl1]:
                if newacf:
                    if not eq + b in newacf: continue
                    name = newacf[eq + b]
                else:
                    h.seek(b + i * aflSTRIDE)
                    name = unicodeify(h.read(txtLEN).split('\0')[0].strip())
                if not name: continue
                thing = casepath(folder, join('airfoils', name))
                if exists(join(folder, thing)):
                    if not thing in secondary:
                        secondary[thing] = [f]
                    elif f not in secondary[thing]:
                        secondary[thing].append(f)
                elif name.lower() in names:
                    pass
                elif thing not in missing:
                    missing[thing] = [f]
                elif f not in missing[thing]:
                    missing[thing].append(f)

        for i in range(wpnDIM):
            if newacf:
                eq = '_wpna/%d/_v10_att_file_stl' % i
                if not eq in newacf: continue
                name = newacf[eq]
            else:
                h.seek(wpn + i * wpnSTRIDE)
                name = unicodeify(h.read(txtLEN).split('\0')[0].strip())
            if not name: continue
            thing = casepath(folder, join('weapons', name))
            if exists(join(folder, thing)):
                if not thing in secondary:
                    secondary[thing] = [f]
                    # XXX weapon airfoils!
                    found = False
                    for ext in textypes:
                        tex2 = casepath(folder, join('weapons',
                                                     name[:-4] + ext))
                        if exists(join(folder, tex2)):
                            found = True
                            secondary[tex2] = [thing]
                    if not found:
                        missing[join('weapons', name[:-4] + '.png')] = [thing]
                elif f not in secondary[thing]:
                    secondary[thing].append(f)
            elif name.lower() in names:
                pass
            elif thing not in missing:
                missing[thing] = [f]
            elif f not in missing[thing]:
                missing[thing].append(f)

        if version < 840: return

        for i in range(objDIM):
            if newacf:
                eq = '_obja/%d/_v10_att_file_stl' % i
                if not eq in newacf: continue
                name = newacf[eq]
            else:
                h.seek(obj + i * objSTRIDE)
                name = unicodeify(h.read(txtLEN).split('\0')[0].strip())
            if not name: continue
            thing = casepath(folder, join('objects', name))
            if exists(join(folder, thing)):
                if not thing in secondary:
                    secondary[thing] = [f]
                    parseobj(folder, secondary, missing, nobackup, {}, thing,
                             f)
                elif f not in secondary[thing]:
                    secondary[thing].append(f)
            elif thing not in missing:
                missing[thing] = [f]
            elif f not in missing[thing]:
                missing[thing].append(f)

    except:
        if __debug__:
            print f
            print_exc()
        die("Can't read %s" % f)