Ejemplo n.º 1
0
        public void RebuildPackage()
        {
            List <byte> output = new List <byte>();

            uint packageVersion = 0;

            if (packageType == PackageType.Kingdom)
            {
                output.Add((byte)'D');
                output.Add((byte)'B');
                output.Add((byte)'P');
                output.Add((byte)'F');
                packageVersion = 2;
            }
            else if (packageType == PackageType.Agents)
            {
                output.Add((byte)'F');
                output.Add((byte)'P');
                output.Add((byte)'B');
                output.Add((byte)'D');
                packageVersion = 3;
            }

            //offset 0x04

            Utility.AddUIntToList(output, ReverseEndianIfNeeded(packageVersion));

            //offset 0x08

            for (int i = 0; i < 0x10; i++)
            {
                output.Add(0x00);
            }

            //offset 0x18

            if (packageType == PackageType.Kingdom)
            {
                for (int i = 0; i < 8; i++)
                {
                    output.Add(0x00);   //pad
                }
            }
            else if (packageType == PackageType.Agents)
            {
                Utility.AddLongToList(output, Utility.ReverseEndianLong(DateTime.Now.ToBinary()));
            }

            Utility.AddUIntToList(output, ReverseEndianIfNeeded(indexmajorversion));

            Utility.AddUIntToList(output, ReverseEndianIfNeeded((uint)subfiles.Count));

            //offset 0x28

            if (packageType == PackageType.Kingdom)
            {
                for (int i = 0; i < 4; i++)
                {
                    output.Add(0x00);   //pad
                }
            }
            else if (packageType == PackageType.Agents)
            {
                Utility.AddUIntToList(output, ReverseEndianIfNeeded(indexoffset));       //this will be returned to later once we know what it is
            }

            Utility.AddUIntToList(output, ReverseEndianIfNeeded(indexsize));        //this will be returned to later once we know what it is
            Utility.AddUIntToList(output, ReverseEndianIfNeeded(holeentrycount));
            Utility.AddUIntToList(output, ReverseEndianIfNeeded(holeoffset));
            Utility.AddUIntToList(output, ReverseEndianIfNeeded(holesize));
            Utility.AddUIntToList(output, ReverseEndianIfNeeded(indexminorversion));

            if (packageType == PackageType.Agents)
            {
                Utility.AddUIntToList(output, ReverseEndianIfNeeded(unknown4));
            }

            Utility.AddUIntToList(output, ReverseEndianIfNeeded(indexoffset));   //this will be returned to later once we know what it is
            Utility.AddUIntToList(output, ReverseEndianIfNeeded(unknown5));
            Utility.AddUIntToList(output, ReverseEndianIfNeeded(unknown6));
            Utility.AddUIntToList(output, ReverseEndianIfNeeded(reserved1));
            Utility.AddUIntToList(output, ReverseEndianIfNeeded(reserved2));

            while (output.Count < 0x60)
            {
                output.Add(0x00);
            }

            //sort by type ID, and within a type ID, by hash
            subfiles = subfiles.OrderBy(s => s.typeID).ThenBy(s => s.hash).ToList();

            List <IndexEntry> indexEntriesForWriting        = new List <IndexEntry>();
            List <uint>       TypeIDsThatRequireCompression = new List <uint>();

            int[] subfileOffsets = new int[subfiles.Count];

            for (int f = 0; f < subfiles.Count; f++)
            {
                subfileOffsets[f] = output.Count;

                bool typeIDhasIndexEntry = false;

                foreach (IndexEntry entry in indexEntriesForWriting)
                {
                    if (entry.typeID == subfiles[f].typeID)
                    {
                        entry.typeNumberOfInstances++;
                        typeIDhasIndexEntry = true;
                        break;
                    }
                }

                if (!typeIDhasIndexEntry)
                {
                    IndexEntry newIndexEntry = new IndexEntry();
                    newIndexEntry.typeID = subfiles[f].typeID;

                    if (subfiles[f].should_be_compressed_when_in_package)
                    {
                        newIndexEntry.groupID = 2;
                    }
                    else
                    {
                        newIndexEntry.groupID = 0;
                    }

                    newIndexEntry.indexnulls            = 0;
                    newIndexEntry.typeNumberOfInstances = 1;

                    if (newIndexEntry.groupID != 0)
                    {
                        TypeIDsThatRequireCompression.Add(newIndexEntry.typeID);
                    }

                    indexEntriesForWriting.Add(newIndexEntry);
                }


                if (subfiles[f].should_be_compressed_when_in_package)
                {
                    if (subfiles[f].has_been_decompressed)  //if it was decompressed by the user then compress it
                    {
                        subfiles[f].filebytes = Compression.Compress_QFS(subfiles[f].filebytes);
                    }
                }

                if (subfiles[f].filebytes == null || subfiles[f].filebytes.Length == 0) //then the file was not modified or read, so transfer it directly from the old package
                {
                    for (int i = 0; i < subfiles[f].filesize; i++)
                    {
                        output.Add(filebytes[subfiles[f].fileoffset + i]);
                    }
                }
                else //if it was modified or read, use the bytes from its filebytes array
                {
                    subfiles[f].filesize = (uint)subfiles[f].filebytes.Length;
                    Console.WriteLine("LENGTH BEING ADDED IS: " + subfiles[f].filesize);
                    for (int i = 0; i < subfiles[f].filebytes.Length; i++)
                    {
                        output.Add(subfiles[f].filebytes[i]);
                    }
                }

                while (output.Count % 0x20 != 0)
                {
                    output.Add(0x00);   //pad to multiple of 0x20
                }
            }

            //that should bring us up to the start of the index table

            uint newIndexOffset = (uint)output.Count;

            if (packageType == PackageType.Agents)
            {
                Utility.AddULongToList(output, Utility.ReverseEndianULong((ulong)indexEntriesForWriting.Count));

                for (int i = 0; i < indexEntriesForWriting.Count; i++)  //a bunch of entries that describe how many files there are of each type
                {
                    Utility.AddUIntToList(output, Utility.ReverseEndian(indexEntriesForWriting[i].typeID));
                    Utility.AddUIntToList(output, Utility.ReverseEndian(indexEntriesForWriting[i].groupID));
                    Utility.AddUIntToList(output, Utility.ReverseEndian(indexEntriesForWriting[i].typeNumberOfInstances));
                    Utility.AddUIntToList(output, Utility.ReverseEndian(indexEntriesForWriting[i].indexnulls));
                }

                for (int i = 0; i < subfiles.Count; i++)     //go through the files and add them to the index list. They are organised by type, one type after the other. (So X number of type A, as described above, then Y number of type B...) Within a type, they are organised by hash
                {
                    Utility.AddULongToList(output, Utility.ReverseEndianULong(subfiles[i].hash));
                    Utility.AddIntToList(output, Utility.ReverseEndianSigned(subfileOffsets[i]));
                    Utility.AddUIntToList(output, Utility.ReverseEndian(subfiles[i].filesize));

                    // this line is probably only required in MSK     utility.AddUIntToList(output, utility.ReverseEndian(subfiles[i].typeID));
                    // this line is probably only required in MSK     utility.AddUIntToList(output, utility.ReverseEndian(subfiles[i].groupID));

                    if (TypeIDsThatRequireCompression.Contains(subfiles[i].typeID))
                    {
                        Utility.AddUIntToList(output, Utility.ReverseEndian(subfiles[i].uncompressedsize));
                    }
                }

                Utility.OverWriteUIntInList(output, 0x28, ReverseEndianIfNeeded(newIndexOffset));
                Utility.OverWriteUIntInList(output, 0x2C, ReverseEndianIfNeeded((uint)(output.Count - newIndexOffset)));
                Utility.OverWriteUIntInList(output, 0x44, ReverseEndianIfNeeded(newIndexOffset));
            }
            else
            {
                MessageBox.Show("only Agents works at the moment");
            }

            SaveFileDialog saveFileDialog1 = new SaveFileDialog();

            saveFileDialog1.Title  = "Save new package";
            saveFileDialog1.Filter = ".package files (*.package)|*.package";

            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                File.WriteAllBytes(saveFileDialog1.FileName, output.ToArray());
            }
        }
Ejemplo n.º 2
0
        public void LoadPackage()
        {
            int currenttypeindexbeingprocessed  = 0;
            int instancesprocessedofcurrenttype = 0;

            using (BinaryReader reader = new BinaryReader(File.Open(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)))
            {
                uint magic = 0;

                magic = Utility.ReverseEndian(reader.ReadUInt32());

                switch (magic)
                {
                case 0x44425046:        //DBPF
                    packageType = PackageType.Kingdom;
                    break;

                case 0x46504244:        //FPBD
                    packageType = PackageType.Agents;
                    break;

                case 0x030502ED:        //Skyheroes
                case 0x03051771:        //Skyheroes
                    packageType = PackageType.SkyHeroes;
                    reader.Close();
                    LoadSkyHeroesPackage();
                    return;

                default:
                    MessageBox.Show("This is not a valid package!", "Package not supported", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    Console.WriteLine("invalid file magic");
                    break;
                }


                if (packageType == PackageType.Agents)
                {
                    majorversion      = Utility.ReverseEndian(reader.ReadUInt32());
                    minorversion      = Utility.ReverseEndian(reader.ReadUInt32());
                    unknown1          = Utility.ReverseEndian(reader.ReadUInt32());
                    unknown2          = Utility.ReverseEndian(reader.ReadUInt32());
                    unknown3          = Utility.ReverseEndian(reader.ReadUInt32());
                    date              = DateTime.FromBinary(Utility.ReverseEndianLong(reader.ReadInt64()));
                    indexmajorversion = Utility.ReverseEndian(reader.ReadUInt32());

                    filecount             = Utility.ReverseEndian(reader.ReadUInt32());
                    indexoffsetdeprecated = Utility.ReverseEndian(reader.ReadUInt32());
                    indexsize             = Utility.ReverseEndian(reader.ReadUInt32());
                    holeentrycount        = Utility.ReverseEndian(reader.ReadUInt32());
                    holeoffset            = Utility.ReverseEndian(reader.ReadUInt32());
                    holesize          = Utility.ReverseEndian(reader.ReadUInt32());
                    indexminorversion = Utility.ReverseEndian(reader.ReadUInt32());
                    unknown4          = Utility.ReverseEndian(reader.ReadUInt32());
                    indexoffset       = Utility.ReverseEndian(reader.ReadUInt32());
                    unknown5          = Utility.ReverseEndian(reader.ReadUInt32());
                    unknown6          = Utility.ReverseEndian(reader.ReadUInt32());
                    reserved1         = Utility.ReverseEndian(reader.ReadUInt32());
                    reserved2         = Utility.ReverseEndian(reader.ReadUInt32());
                }
                else
                {
                    majorversion      = reader.ReadUInt32();
                    minorversion      = reader.ReadUInt32();
                    unknown1          = reader.ReadUInt32();
                    unknown2          = reader.ReadUInt32();
                    unknown3          = reader.ReadUInt32();
                    date              = DateTime.FromBinary(Utility.ReverseEndianLong(reader.ReadInt64()));
                    indexmajorversion = reader.ReadUInt32();

                    filecount             = reader.ReadUInt32();
                    indexoffsetdeprecated = reader.ReadUInt32();
                    indexsize             = reader.ReadUInt32();
                    holeentrycount        = reader.ReadUInt32();
                    holeoffset            = reader.ReadUInt32();
                    holesize          = reader.ReadUInt32();
                    indexminorversion = reader.ReadUInt32();
                    indexoffset       = reader.ReadUInt32();
                    unknown5          = reader.ReadUInt32();
                    unknown6          = reader.ReadUInt32();
                    reserved1         = reader.ReadUInt32();
                    reserved2         = reader.ReadUInt32();
                }

                Console.WriteLine("Package date: " + date.ToString());


                reader.BaseStream.Position = indexoffset;

                //index header

                if (packageType == PackageType.Agents)
                {
                    indexnumberofentries = Utility.ReverseEndianULong(reader.ReadUInt64());

                    for (uint i = 0; i < indexnumberofentries; i++)  //a bunch of entries that describe how many files there are of each type
                    {
                        IndexEntry newEntry = new IndexEntry();

                        newEntry.typeID  = Utility.ReverseEndian(reader.ReadUInt32());
                        newEntry.groupID = Utility.ReverseEndian(reader.ReadUInt32());
                        newEntry.typeNumberOfInstances = Utility.ReverseEndian(reader.ReadUInt32());
                        newEntry.indexnulls            = Utility.ReverseEndian(reader.ReadUInt32());

                        IndexEntries.Add(newEntry);
                    }

                    currenttypeindexbeingprocessed  = 0;
                    instancesprocessedofcurrenttype = 0;

                    for (uint i = 0; i < filecount; i++)     //go through the files, they are organised by type, one type after the other. (So X number of type A, as described above, then Y number of type B...)
                    {
                        Subfile newSubfile = new Subfile();
                        newSubfile.hash       = Utility.ReverseEndianULong(reader.ReadUInt64());
                        newSubfile.fileoffset = Utility.ReverseEndian(reader.ReadUInt32());
                        newSubfile.filesize   = Utility.ReverseEndian(reader.ReadUInt32());
                        newSubfile.typeID     = IndexEntries[currenttypeindexbeingprocessed].typeID;
                        newSubfile.groupID    = IndexEntries[currenttypeindexbeingprocessed].groupID;

                        if (IndexEntries[currenttypeindexbeingprocessed].groupID != 0)   //it's compressed
                        {
                            newSubfile.should_be_compressed_when_in_package = true;
                            newSubfile.uncompressedsize = Utility.ReverseEndian(reader.ReadUInt32());
                            Console.WriteLine("Found a compressed file");
                        }

                        instancesprocessedofcurrenttype++;

                        if (instancesprocessedofcurrenttype == IndexEntries[currenttypeindexbeingprocessed].typeNumberOfInstances)
                        {
                            Console.WriteLine("Processed " + instancesprocessedofcurrenttype + " instances of " + currenttypeindexbeingprocessed);
                            currenttypeindexbeingprocessed++;
                            instancesprocessedofcurrenttype = 0;
                        }

                        subfiles.Add(newSubfile);
                    }
                }
                else     //MySims and MySims Kingdom use these
                {
                    MSKindexversion = reader.ReadUInt32();

                    if (MSKindexversion == 0)
                    {
                        Console.WriteLine("index version 0");
                        for (uint i = 0; i < filecount; i++)
                        {
                            Subfile newSubfile = new Subfile();

                            newSubfile.typeID  = reader.ReadUInt32();
                            newSubfile.groupID = reader.ReadUInt32();
                            newSubfile.hash    = (ulong)(reader.ReadUInt32()) << 32;
                            newSubfile.hash   |= (ulong)(reader.ReadUInt32());

                            newSubfile.fileoffset       = reader.ReadUInt32();
                            newSubfile.filesize         = reader.ReadUInt32() & 0x7FFFFFFF;
                            newSubfile.uncompressedsize = reader.ReadUInt32();
                            reader.BaseStream.Position += 0x04; //flags

                            if (newSubfile.filesize == newSubfile.uncompressedsize)
                            {
                                newSubfile.uncompressedsize = 0;
                            }
                            else
                            {
                                newSubfile.should_be_compressed_when_in_package = true;
                            }

                            subfiles.Add(newSubfile);
                        }
                    }
                    else if (MSKindexversion == 1)
                    {
                        MessageBox.Show("Index version 1 not implemented!");
                    }
                    else if (MSKindexversion == 2)
                    {
                        Console.WriteLine("index version 2");

                        reader.BaseStream.Position += 4;

                        for (uint i = 0; i < filecount; i++)
                        {
                            Subfile newSubfile = new Subfile();

                            newSubfile.typeID = reader.ReadUInt32();
                            newSubfile.hash   = (ulong)(reader.ReadUInt32()) << 32;
                            newSubfile.hash  |= (ulong)(reader.ReadUInt32());

                            newSubfile.fileoffset       = reader.ReadUInt32();
                            newSubfile.filesize         = reader.ReadUInt32() & 0x7FFFFFFF;
                            newSubfile.uncompressedsize = reader.ReadUInt32();
                            reader.BaseStream.Position += 0x04; //flags

                            if (newSubfile.filesize == newSubfile.uncompressedsize)
                            {
                                newSubfile.uncompressedsize = 0;
                            }
                            else
                            {
                                newSubfile.should_be_compressed_when_in_package = true;
                            }

                            subfiles.Add(newSubfile);
                        }
                    }
                    else if (MSKindexversion == 3)
                    {
                        Console.WriteLine("index version 3");
                        uint allFilesTypeID = reader.ReadUInt32();
                        reader.BaseStream.Position += 4;

                        for (uint i = 0; i < filecount; i++)
                        {
                            Subfile newSubfile = new Subfile();

                            newSubfile.typeID = allFilesTypeID;
                            newSubfile.hash   = (ulong)(reader.ReadUInt32()) << 32;
                            newSubfile.hash  |= (ulong)(reader.ReadUInt32());

                            newSubfile.fileoffset       = reader.ReadUInt32();
                            newSubfile.filesize         = reader.ReadUInt32() & 0x7FFFFFFF;
                            newSubfile.uncompressedsize = reader.ReadUInt32();
                            reader.BaseStream.Position += 0x04; //flags

                            if (newSubfile.filesize == newSubfile.uncompressedsize)
                            {
                                newSubfile.uncompressedsize = 0;
                            }
                            else
                            {
                                newSubfile.should_be_compressed_when_in_package = true;
                            }

                            subfiles.Add(newSubfile);
                        }
                    }
                    else if (MSKindexversion == 4)
                    {
                        Console.WriteLine("index version 4");
                        reader.BaseStream.Position += 4;

                        for (uint i = 0; i < filecount; i++)
                        {
                            Subfile newSubfile = new Subfile();

                            newSubfile.typeID = reader.ReadUInt32();
                            newSubfile.hash   = (ulong)(reader.ReadUInt32()) << 32;
                            newSubfile.hash  |= (ulong)(reader.ReadUInt32());

                            newSubfile.fileoffset       = reader.ReadUInt32();
                            newSubfile.filesize         = reader.ReadUInt32();
                            newSubfile.uncompressedsize = reader.ReadUInt32();

                            if (newSubfile.filesize == newSubfile.uncompressedsize)
                            {
                                newSubfile.uncompressedsize = 0;
                            }
                            else
                            {
                                newSubfile.should_be_compressed_when_in_package = true;
                            }

                            subfiles.Add(newSubfile);
                        }
                    }
                    else if (MSKindexversion == 7)
                    {
                        Console.WriteLine("index version 7");
                        for (uint i = 0; i < filecount; i++)
                        {
                            Subfile newSubfile = new Subfile();

                            newSubfile.typeID  = reader.ReadUInt32();
                            newSubfile.groupID = reader.ReadUInt32();
                            newSubfile.hash    = (ulong)(reader.ReadUInt32()) << 32;
                            newSubfile.hash   |= (ulong)(reader.ReadUInt32());

                            newSubfile.fileoffset       = reader.ReadUInt32();
                            newSubfile.filesize         = reader.ReadUInt32() & 0x7FFFFFFF;
                            newSubfile.uncompressedsize = reader.ReadUInt32();
                            reader.BaseStream.Position += 0x04;     //flags

                            if (newSubfile.filesize == newSubfile.uncompressedsize)
                            {
                                newSubfile.uncompressedsize = 0;
                            }
                            else
                            {
                                newSubfile.should_be_compressed_when_in_package = true;
                            }

                            subfiles.Add(newSubfile);
                        }
                    }
                    else
                    {
                        MessageBox.Show("Unknown index version: " + MSKindexversion);
                        return;
                    }
                }


                //extract files

                Console.WriteLine("filecount " + filecount);

                int filesprocessed = 0;


                List <string> luaFilenamesForDict = new List <string>();

                bool containslua = false;

                for (int i = 0; i < filecount; i++)
                {
                    if (subfiles[i].should_be_compressed_when_in_package)
                    {
                        subfiles[i].has_been_decompressed = false;    //set default state of a compressed file to compressed
                    }

                    {
                        string fileextension = null;

                        switch ((global.TypeID)subfiles[i].typeID)
                        {
                        case global.TypeID.RMDL_MSA:            //RMDL MSA
                            fileextension = ".rmdl";            //TYPE ID 29 54 E7 34
                            break;

                        case global.TypeID.RMDL_MSK:            //RMDL MSK
                            fileextension = ".rmdl";            //          "ModelData"
                            break;

                        case global.TypeID.MATD_MSA:            //MATD MSA
                            fileextension = ".matd";            //TYPE ID E6 64 05 42
                            break;

                        case global.TypeID.MATD_MSK:              //MATD MSK            "MaterialData"
                            fileextension = ".matd";
                            break;

                        case global.TypeID.TPL_MSA:             //altered TPL MSA
                            fileextension = ".tpl";             //TYPE ID 92 AA 4D 6A
                            break;

                        case global.TypeID.TPL_MSK:             //altered TPL MSK      "TextureData"
                            fileextension = ".tpl";
                            break;

                        case global.TypeID.MTST_MSK:          //MTST Material Set MSK       "MaterialSetData"
                            fileextension = ".mtst";
                            break;

                        case global.TypeID.MTST_MSA:             //MTST Material Set MSA
                            fileextension = ".mtst";             //TYPE ID 78 7E 84 2A
                            break;

                        case global.TypeID.FPST_MSK:            //FPST   MySims Kingdom footprint set.    "FootprintData"    contains a model footprint (ftpt) which is possibly documented at http://simswiki.info/wiki.php?title=Sims_3:PackedFileTypes
                        case global.TypeID.FPST_MSA:            //FPST   MySims Agents footprint set.                        contains a model footprint (ftpt) which is possibly documented at http://simswiki.info/wiki.php?title=Sims_3:PackedFileTypes
                            fileextension = ".fpst";            //It's like a heatmap of where sims can walk? Or perhaps which surfaces should generate which kind of footprint (but wouldn't that mean that overhangs wouldn't work?)
                            break;

                        case global.TypeID.BNK_MSA:            //BNKb    big endian BNK    MSA                             vgmstream can decode these.           https://github.com/losnoco/vgmstream/blob/master/src/meta/ea_schl.c
                            fileextension = ".bnk";            //TYPE ID 21 99 BB 60
                            break;

                        case global.TypeID.BNK_MSK:            //BNKb    BNK    MSK (idk which endian, not tested)       "AudioData"             vgmstream can decode these.           https://github.com/losnoco/vgmstream/blob/master/src/meta/ea_schl.c
                            fileextension = ".bnk";
                            break;

                        case global.TypeID.BIG_MSK:        //big
                            fileextension = ".big";        //"AptData" (but it is, of course, a familiar EA .BIG archive)
                            break;

                        case global.TypeID.BIG_MSA:            //BIGF
                            fileextension = ".big";
                            break;

                        case global.TypeID.COLLISION_MSA: //00 00 00 02             There's another, separate filetype that also begins with the 2 magic, but that one doesn't appear as frequently, so this one here is probably the collision type ID
                            //TYPE ID 1A 8F EB 14.
                            fileextension = ".collision"; //mesh collision
                            break;                        //there are mentions of 'rwphysics' in MSA's main.dol; could this mean Renderware Physics, which was indeed a product available at the time?

                        case global.TypeID.FX:            //FX
                            fileextension = ".fx";
                            break;

                        case global.TypeID.LUAC_MSA:            //LUAC MSA
                            fileextension = ".luac";
                            containslua   = true;
                            break;

                        case global.TypeID.LUAC_MSK:             //LUAC MSK  "LuaObjectData"
                            fileextension = ".luac";
                            containslua   = true;
                            break;

                        case global.TypeID.SLOT_MSA:         //SLOT MSA
                            fileextension = ".slot";
                            break;

                        case global.TypeID.SLOT_MSK:         //SLOT MSK
                            fileextension = ".slot";         //"SlotData"
                            break;

                        case global.TypeID.PARTICLES_MSA:           //particles file
                            fileextension = ".particles";           //TYPE ID 28 70 78 64
                            break;

                        case global.TypeID.BUILDABLEREGION_MSA:           //00 00 00 03        buildable region MSA
                            fileextension = ".buildableregion";
                            break;

                        case global.TypeID.BUILDABLEREGION_MSK:           //buildable region MSK        "BuildableRegionData"
                            fileextension = ".buildableregion";
                            break;

                        case global.TypeID.LLMF_MSA:                         //LLMF level bin MSA
                            fileextension = ".llmf";
                            break;

                        case global.TypeID.LLMF_MSK:                         //LLMF level bin MSK   "LevelData"
                            fileextension = ".llmf";
                            break;

                        case global.TypeID.RIG_MSA:        //RIG MSA                   //Interesting granny struct info at 0x49CFDD in MSA's main.dol
                            fileextension = ".grannyrig";  //TYPE ID 46 72 E5 BD
                            break;

                        case global.TypeID.RIG_MSK:        //RIG MSK
                            fileextension = ".grannyrig";  // "RigData"
                            break;

                        case global.TypeID.ANIMCLIP_MSA:        //ANIMATION MSA
                            fileextension = ".clip";            //TYPE ID D6 BE DA 43
                            break;

                        case global.TypeID.ANIMCLIP_MSK:        //ANIMATION MSK         "ClipData"
                            fileextension = ".clip";
                            break;

                        case global.TypeID.LTST_MSA:
                            fileextension = ".ltst";        //possibly lighting set?
                            break;

                        case global.TypeID.TTF_MSK:             //TrueType font MySims Kingdom
                        case global.TypeID.TTF_MSA:             //TrueType font MySims Agents
                            fileextension = ".ttf";             //TYPE ID 27 6C A4 B9
                            break;

                        case global.TypeID.HKX_MSK:        //MSK HKX havok collision file
                            fileextension = ".hkx";        // "PhysicsData"
                            break;

                        case global.TypeID.OGVD_MSK:
                            fileextension = ".objectGridVolumeData";       //MSK "ObjectGridVolumeData"
                            break;

                        case global.TypeID.OGVD_MSA:           //00 00 00 02           MSA ObjectGridVolumeData bounding box collision (for very simple objects)
                            fileextension = ".objectGridVolumeData";
                            break;

                        case global.TypeID.SPD_MSK:
                            fileextension = ".snapPointData";       //MSK "SnapPointData"
                            break;

                        case global.TypeID.SPD_MSA:           //00 00 00 03          MSA SnapPointData, most likely
                            fileextension = ".snapPointData";
                            break;

                        case global.TypeID.VGD_MSK:
                            fileextension = ".voxelGridData";       //MSK "VoxelGridData"
                            break;

                        case global.TypeID.VGD_MSA:           //00 00 00 01      MSA VoxelGridData, most likely, most likely
                            fileextension = ".voxelGridData";
                            break;

                        case global.TypeID.MODEL_MS:       //model          used by MySims, not the same as rmdl
                            fileextension = ".model";
                            break;

                        case global.TypeID.KEYNAMEMAP_MS:
                            fileextension = ".KeyNameMap";
                            break;

                        case global.TypeID.GEOMETRY_MS:
                            fileextension = ".geometry";
                            break;

                        case global.TypeID.OLDSPEEDTREE_MS:
                            fileextension = ".oldSpeedTree";
                            break;

                        case global.TypeID.SPEEDTREE_MS:
                            fileextension = ".speedTree";
                            break;

                        case global.TypeID.COMPOSITETEXTURE_MS:
                            fileextension = ".compositeTexture";
                            break;

                        case global.TypeID.SIMOUTFIT_MS:
                            fileextension = ".simOutfit";
                            break;

                        case global.TypeID.LEVELXML_MS:
                            fileextension = ".levelXml";
                            break;

                        case global.TypeID.LUA_MSK:        //uncompiled lua script "LuaTextData"
                            fileextension = ".lua";
                            break;

                        case global.TypeID.LIGHTSETXML_MS:        //Light set XML MySims
                            fileextension = ".lightSetXml";
                            break;

                        case global.TypeID.LIGHTSETBIN_MSK:        //Light set bin MySims
                            fileextension = ".lightSetBin";        //Named "LightSetData" in MSK's executable
                            break;

                        case global.TypeID.XML_MS:       //xml
                            fileextension = ".xml";
                            break;

                        case global.TypeID.FPST_MS:        //footprint set MySims
                            fileextension = ".footprintSet";
                            break;

                        case global.TypeID.OBJECTCONSTRUCTIONXML_MS:        //object construction xml
                            fileextension = ".objectConstructionXml";
                            break;

                        case global.TypeID.OBJECTCONSTRUCTIONBIN_MS:        //object construction bin
                            fileextension = ".objectConstructionBin";
                            break;

                        case global.TypeID.SLOTXML_MS:        //slot xml
                            fileextension = ".slotXml";
                            break;

                        case global.TypeID.SWARM_MSK:        //swm
                            fileextension = ".swm";          //MSK           "SwarmData"
                            break;

                        case global.TypeID.SWARM_MS:        //SwarmBin
                            fileextension = ".SwarmBin";
                            break;

                        case global.TypeID.XMLBIN_MS:        //XmlBin
                            fileextension = ".XmlBin";
                            break;

                        case global.TypeID.CABXML_MS:        //CABXml
                            fileextension = ".CABXml";
                            break;

                        case global.TypeID.CABBIN_MS:        //CABBin
                            fileextension = ".CABBin";
                            break;

                        case global.TypeID.LIGHTBOXXML_MS:      //LightBoxXml
                            fileextension = ".lightBoxXml";
                            break;

                        case global.TypeID.LIGHTBOXBIN_MS:      //LightBoxBin
                            fileextension = ".lightBoxBin";     //MSK LightBoxData (Named in MSK's executable, though I think I found it in MySims?)
                            break;

                        case global.TypeID.XMB_MS:      //xmb
                            fileextension = ".xmb";
                            break;

                        default:
                            Console.WriteLine("Unknown type ID " + subfiles[i].typeID);
                            Console.WriteLine("and this type ID appears " + GetNumOccurrencesOfTypeID(subfiles[i].typeID) + " times in total.");
                            Console.WriteLine("index of file was " + filesprocessed);
                            fileextension = "." + subfiles[i].typeID.ToString();
                            break;
                        }

                        subfiles[i].fileextension = fileextension;



                        Vault.luaString typeIDRealString = global.activeVault.GetLuaStringWithHash(subfiles[i].typeID);

                        //if (typeIDRealString != null)
                        //   {
                        //   fileextension = "." + typeIDRealString.name;
                        //   }



                        byte[] newfilenameasbytes = BitConverter.GetBytes(Utility.ReverseEndianULong(subfiles[i].hash));

                        subfiles[i].filename = "0x";

                        ulong newfilenameasulong = Utility.ReverseEndianULong(subfiles[i].hash);

                        subfiles[i].hashString = "0x" + BitConverter.ToString(newfilenameasbytes).Replace("-", "");

                        if (global.activeVault.VaultHashesAndFileNames.Keys.Contains(subfiles[i].hash))
                        {
                            subfiles[i].filename = global.activeVault.VaultHashesAndFileNames[subfiles[i].hash];
                        }
                        else
                        {
                            subfiles[i].filename = subfiles[i].hashString;
                        }

                        subfiles[i].filename += fileextension;

                        /*
                         * if (fileextension == ".lua") //temp
                         *  {
                         *  string luaName = "";
                         *
                         *  int currentOffset = 0x10;
                         *
                         *  while (newfile[currentOffset] != 0x00)
                         *      {
                         *      currentOffset++;
                         *      }
                         *
                         *  while (newfile[currentOffset] != 0x2F)
                         *  {
                         *      currentOffset--;
                         *  }
                         *
                         *  currentOffset++;
                         *
                         *  while (newfile[currentOffset] != 0x2E)
                         *      {
                         *      luaName += ((char)newfile[currentOffset]) + "";
                         *      currentOffset++;
                         *      }
                         *
                         *  luaFilenamesForDict.Add("VaultHashesAndFileNames.Add("+newfilename+",\""+luaName+"\");");
                         *  }*/

                        filesprocessed++;
                    }
                }
                form1.MakeFileTree();

                if (containslua && global.activeVault.luaStrings.Count > 0)
                {
                    string[] luaStringsForExport = new string[global.activeVault.luaStrings.Count];

                    for (int i = 0; i < global.activeVault.luaStrings.Count; i++)
                    {
                        luaStringsForExport[i]  = BitConverter.ToString(BitConverter.GetBytes(Utility.ReverseEndian(global.activeVault.luaStrings[i].hash))).Replace("-", "");;
                        luaStringsForExport[i] += " " + global.activeVault.luaStrings[i].name;
                    }

                    File.WriteAllLines("global.activeVault.luaStrings.lua", luaStringsForExport);
                }

                File.WriteAllLines("dict.txt", luaFilenamesForDict);
                MessageBox.Show("Processed " + filesprocessed + " files (out of a total " + filecount + ").", "Task complete", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }