public static string ReadStringUnreal(this Stream stream)
        {
            Int32 length = stream.ReadValueS32();

            if (length == 0)
            {
                return("");
            }

            bool isUnicode = false;

            if (length < 0)
            {
                length    = Math.Abs(length);
                isUnicode = true;
            }

            if (length >= 1024 * 1024)
            {
                throw new InvalidOperationException("somehow I doubt there is a >1MB string to be read");
            }

            if (isUnicode == true)
            {
                return(stream.ReadStringUTF16((uint)(length * 2), true));
            }
            else
            {
                return(stream.ReadStringASCII((uint)(length), true));
            }
        }
Пример #2
0
        private void loadNames(Stream input)
        {
            namesTable = new List <NameEntry>();
            input.JumpTo(namesOffset);
            for (int i = 0; i < namesCount; i++)
            {
                NameEntry entry = new NameEntry();
                int       len   = input.ReadInt32();
                if (len < 0) // unicode
                {
                    byte[] str = input.ReadToBuffer(-len * 2);
                    if (version == packageFileVersionME3)
                    {
                        entry.name = Encoding.Unicode.GetString(str);
                    }
                    else
                    {
                        for (int c = 0; c < -len; c++)
                        {
                            entry.name += (char)str[c * 2];
                        }
                    }
                }
                else
                {
                    entry.name = input.ReadStringASCII(len);
                }
                entry.name = entry.name.Trim('\0');

                if (nameIdTexture2D == -1 && entry.name == "Texture2D")
                {
                    nameIdTexture2D = i;
                }
                else if (nameIdLightMapTexture2D == -1 && entry.name == "LightMapTexture2D")
                {
                    nameIdLightMapTexture2D = i;
                }
                else if (nameIdShadowMapTexture2D == -1 && entry.name == "ShadowMapTexture2D")
                {
                    nameIdShadowMapTexture2D = i;
                }
                else if (nameIdTextureFlipBook == -1 && entry.name == "TextureFlipBook")
                {
                    nameIdTextureFlipBook = i;
                }

                if (version == packageFileVersionME1)
                {
                    entry.flags = input.ReadUInt64();
                }
                if (version == packageFileVersionME2)
                {
                    entry.flags = input.ReadUInt32();
                }

                namesTable.Add(entry);
            }
            namesTableEnd = (uint)input.Position;
        }
Пример #3
0
        private void OnHeadMorphImport(object sender, EventArgs e)
        {
            if (this.openHeadMorphDialog.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            Stream input = this.openHeadMorphDialog.OpenFile();

            if (input.ReadStringASCII((uint)HeadMorphMagic.Length) != HeadMorphMagic)
            {
                MessageBox.Show(
                    "That file does not appear to be an exported head morph.",
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                input.Close();
                return;
            }

            if (input.ReadValueU8() != 0)
            {
                MessageBox.Show(
                    "Unsupported head morph export version.",
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                input.Close();
                return;
            }

            uint version = input.ReadValueU32();

            if (version != this.SaveFile.Version)
            {
                if (MessageBox.Show(
                        String.Format(
                            "The head morph you are importing has a different " +
                            "version ({0}) than your current save file ({1}).\n\n" +
                            "Import anyway?",
                            version,
                            this.SaveFile.Version),
                        "Question",
                        MessageBoxButtons.YesNo,
                        MessageBoxIcon.Question) == DialogResult.No)
                {
                    input.Close();
                    return;
                }
            }

            FileFormats.UnrealStream stream = new FileFormats.UnrealStream(
                input, true, version);
            stream.Serialize(ref this.SaveFile.PlayerRecord.Appearance.MorphHead);
            this.SaveFile.PlayerRecord.Appearance.HasMorphHead = true;

            input.Close();
        }
Пример #4
0
        public static string ReadStringPascal16(this Stream stream)
        {
            short  length  = stream.ReadValueS16();
            string text    = stream.ReadStringASCII((uint)length);
            int    padding = (-(length - 2)) & 3;

            stream.Seek(padding, SeekOrigin.Current);
            return(text);
        }
Пример #5
0
        public static MergeMod1 ReadMergeMod(Stream mergeFileStream, string mergeModName, bool loadAssets)
        {
            // Version and magic will already be read by main value
            var manifest = mergeFileStream.ReadUnrealString();
            var mm       = JsonConvert.DeserializeObject <MergeMod1>(manifest);

            MemoryAnalyzer.AddTrackedMemoryItem($@"MergeMod1 {mergeModName}", new WeakReference(mm));
            mm.MergeModFilename = mergeModName;

            // setup links
            foreach (var ff in mm.FilesToMergeInto)
            {
                ff.SetupParent(mm);
                ff.Validate();
            }

            var assetCount = mergeFileStream.ReadInt32();

            if (assetCount > 0)
            {
                for (int i = 0; i < assetCount; i++)
                {
                    var assetMag = mergeFileStream.ReadStringASCII(4);
                    if (assetMag != MMV1_ASSETMAGIC)
                    {
                        throw new Exception(M3L.GetString(M3L.string_error_mergefile_badMagic));
                    }

                    MergeAsset ma        = new MergeAsset();
                    var        assetName = mergeFileStream.ReadUnrealString();
                    ma.FileSize = mergeFileStream.ReadInt32();
                    if (loadAssets)
                    {
                        // Read now
                        ma.ReadAssetBinary(mergeFileStream);
                    }
                    else
                    {
                        // Will load at install time
                        ma.FileOffset = (int)mergeFileStream.Position;
                        mergeFileStream.Skip(ma.FileSize);
                    }

                    mm.Assets ??= new CaseInsensitiveDictionary <MergeAsset>();
                    mm.Assets[assetName] = ma;
                }
            }

            return(mm);
        }
        public static IMergeMod LoadMergeMod(Stream mergeFileStream, string filename, bool loadAssets)
        {
            if (mergeFileStream.ReadStringASCII(4) != MERGEMOD_MAGIC)
            {
                throw new Exception(M3L.GetString(M3L.string_mergeModFileDoesNotHaveCorrectMagicHeader));
            }

            var version = mergeFileStream.ReadByte();

            switch (version)
            {
            case 1:
                return(MergeMod1.ReadMergeMod(mergeFileStream, filename, loadAssets));

            default:
                return(null);
            }
        }
Пример #7
0
            public void Read(Stream stream)
            {
                Magic            = stream.ReadUInt32();
                Version          = stream.ReadUInt32();
                DataOffset       = stream.ReadUInt32();
                EntryOffset      = stream.ReadUInt32();
                FileCount        = stream.ReadUInt32();
                BlockTableOffset = stream.ReadUInt32();
                MaxBlockSize     = stream.ReadUInt32();

                CompressionScheme = stream.ReadStringASCII(4).ToCharArray();
                if (Magic != 0x53464152 ||
                    Version != 0x00010000 ||
                    MaxBlockSize != 0x00010000)
                {
                    throw new Exception("Not supported DLC file!");
                }
            }
Пример #8
0
        public void Read(Stream input)
        {
            this.Version = input.ReadValueS32();
            if (this.Version != 1)
            {
                throw new InvalidOperationException();
            }

            int count = input.ReadValueS32();

            this.Map = new Dictionary <ulong, string>();
            for (int i = 0; i < count; i++)
            {
                UInt64 hash   = input.ReadValueU64();
                uint   length = input.ReadValueU32();
                string name   = length == 0 ? "" : input.ReadStringASCII(length);
                this.Map[hash] = name;
            }
        }
Пример #9
0
        public void Deserialize(Stream input)
        {
            if (input.ReadStringASCII(3) != "WSG") // WSG is probably WillowSaveGame
            {
                throw new FormatException("not a Borderlands save file");
            }

            UInt32 version = input.ReadValueU32();

            if (version != 2 && version.Swap() != 2)
            {
                throw new FormatException("unsupported Borderlands save file version (" + version.ToString() + ")");
            }

            this.LittleEndian = version == 2;

            SaveStream saveStream = new SaveStream(input, this.LittleEndian);

            this.PlayerData = new Save.Player();
            this.PlayerData.Deserialize(saveStream);
        }
Пример #10
0
        public void Read(Stream input)
        {
            if (input.ReadStringASCII(4) != "STBL")
            {
                throw new Exception();
            }

            this.Version = input.ReadValueS16();

            byte unk1 = input.ReadValueU8();

            if (unk1 > 1)
            {
                throw new Exception();
            }
            else if (unk1 == 1)
            {
                UInt64 unk2 = input.ReadValueU64(LittleEndian);
                byte   unk3 = input.ReadValueU8();
                byte   unk4 = input.ReadValueU8();
            }
        }
Пример #11
0
        private void loadExtraNames(Stream input, bool rawMode = true)
        {
            extraNamesTable = new List <ExtraNameEntry>();
            uint extraNamesCount = input.ReadUInt32();

            for (int c = 0; c < extraNamesCount; c++)
            {
                ExtraNameEntry entry = new ExtraNameEntry();
                int            len   = input.ReadInt32();
                if (rawMode)
                {
                    if (len < 0)
                    {
                        entry.raw = input.ReadToBuffer(-len * 2);
                    }
                    else
                    {
                        entry.raw = input.ReadToBuffer(len);
                    }
                }
                else
                {
                    string name;
                    if (len < 0)
                    {
                        name = input.ReadStringUnicode(-len * 2);
                    }
                    else
                    {
                        name = input.ReadStringASCII(len);
                    }
                    name       = name.Trim('\0');
                    entry.name = name;
                }
                extraNamesTable.Add(entry);
            }
        }
Пример #12
0
        private void showVpxyFile(Stream vpxyStream)
        {
            showRcolHeader(vpxyStream);

            string vpxyString = vpxyStream.ReadStringASCII(4);
            uint vpxyVersion = vpxyStream.ReadValueU32();

            uint tailOffset = vpxyStream.ReadValueU32();
            uint tailSize = vpxyStream.ReadValueU32();

            vpxyStream.Seek(tailOffset - 4, SeekOrigin.Current);

            uint numTGIs = vpxyStream.ReadValueU32();

            for (int i = 0; i < numTGIs; i++)
            {
                ListViewItem loditem = new ListViewItem();

                loditem.Text = "TGI #" + i.ToString();

                uint lodTypeId = vpxyStream.ReadValueU32();
                uint lodGroupId = vpxyStream.ReadValueU32();
                ulong lodInstanceId = vpxyStream.ReadValueU64();

                loditem.SubItems.Add("key:" + lodTypeId.ToString("X8") + ":" + lodGroupId.ToString("X8") + ":" + lodInstanceId.ToString("X16"));

                if (isLocalFile(new ResourceKey(lodInstanceId, lodTypeId, lodGroupId)))
                {
                    loditem.SubItems.Add("*");
                }

                listView2.Items.Add(loditem);

            }
        }
Пример #13
0
        private void showKeyNameFile(Stream keyNameFile)
        {
            BinaryReader reader = new BinaryReader(keyNameFile);

            reader.ReadUInt32();

            int kCount = reader.ReadInt32();

            for (int i = 0; i < kCount; i++)
            {
                ulong instanceID = reader.ReadUInt64();
                uint nameLength = reader.ReadUInt32();
                string kName = keyNameFile.ReadStringASCII(nameLength);

                ListViewItem litem = new ListViewItem();
                litem.Text = instanceID.ToString("X16");
                litem.SubItems.Add(kName);

                listView2.Items.Add(litem);
            }
        }
Пример #14
0
 public static string ReadStringASCIINull(this Stream stream, int count)
 {
     return(stream.ReadStringASCII(count).Trim('\0'));
 }
Пример #15
0
        public void Deserialize(Stream input)
        {
            long baseOffset = input.Position;

            string magic = input.ReadStringASCII(4);

            if (magic != "BGEO" && magic != "OEGB")
            {
                throw new InvalidDataException("not a blend geometry");
            }

            this.LittleEndian = (magic == "BGEO");

            this.Version = input.ReadValueU32(this.LittleEndian);
            if (this.Version >= 0x400)
            {
                throw new InvalidOperationException("bad version");
            }

            UInt32 unknown1 = input.ReadValueU32(this.LittleEndian);
            UInt32 unknown2 = input.ReadValueU32(this.LittleEndian); // should always be 4
            UInt32 unknown3 = input.ReadValueU32(this.LittleEndian);
            UInt32 unknown4 = input.ReadValueU32(this.LittleEndian);
            UInt32 unknown5 = input.ReadValueU32(this.LittleEndian); // should always be 8
            UInt32 unknown6 = input.ReadValueU32(this.LittleEndian); // should always be 12
            UInt32 unknown7 = input.ReadValueU32(this.LittleEndian);
            UInt32 unknown8 = input.ReadValueU32(this.LittleEndian);
            UInt32 unknown9 = input.ReadValueU32(this.LittleEndian);

            if (unknown2 != 4)
            {
                throw new InvalidOperationException();
            }

            if (unknown5 != 8)
            {
                throw new InvalidOperationException();
            }

            if (unknown6 != 12)
            {
                throw new InvalidOperationException();
            }

            if (unknown1 > 0)
            {
                UInt32 _unknown3 = unknown3;
                UInt32 _unknown4 = unknown4;

                input.Seek(baseOffset + unknown7, SeekOrigin.Begin);

                for (int i = 0; i < unknown1; i++)
                {
                    UInt32 unknown10 = input.ReadValueU32(this.LittleEndian);
                    UInt32 unknown11 = input.ReadValueU32(this.LittleEndian);
                    // unknown5 represents previous reads size (8 bytes)

                    for (int j = 0; j < 4; j++) // unknown2 ?
                    {
                        UInt32 unknown12 = input.ReadValueU32(this.LittleEndian);
                        UInt32 unknown13 = input.ReadValueU32(this.LittleEndian);
                        UInt32 unknown14 = input.ReadValueU32(this.LittleEndian);
                        // unknown6 represents previous reads size (12 bytes)

                        if (unknown13 > _unknown3)
                        {
                            throw new InvalidOperationException();
                        }

                        if (unknown14 > _unknown4)
                        {
                            throw new InvalidOperationException();
                        }

                        _unknown3 -= unknown13;
                        _unknown4 -= unknown14;
                    }
                }
            }

            if (this.Version < 0x300)
            {
                input.Seek(baseOffset + unknown8, SeekOrigin.Begin);
                for (uint i = 0; i < unknown3; i++)
                {
                    input.ReadValueU32(this.LittleEndian);
                }
            }
            else
            {
                input.Seek(baseOffset + unknown8, SeekOrigin.Begin);
                for (uint i = 0; i < unknown3; i++)
                {
                    input.ReadValueU16(this.LittleEndian);
                }
            }

            if (this.Version == 0x100)
            {
                input.Seek(baseOffset + unknown9, SeekOrigin.Begin);
                for (uint i = 0; i < unknown4; i++)
                {
                    input.ReadValueF32(this.LittleEndian);
                    input.ReadValueF32(this.LittleEndian);
                    input.ReadValueF32(this.LittleEndian);
                }
            }
            else
            {
                input.Seek(baseOffset + unknown9, SeekOrigin.Begin);
                for (uint i = 0; i < unknown4; i++)
                {
                    input.ReadValueU16(this.LittleEndian);
                    input.ReadValueU16(this.LittleEndian);
                    input.ReadValueU16(this.LittleEndian);
                }
            }
        }
Пример #16
0
        public void Read(Stream input)
        {
            Int64 indexCount;
            Int64 indexSize;
            Int64 indexOffset;

            string magic = input.ReadStringASCII(4);

            if (magic != "DBPF" && magic != "DBBF") // DBPF & DBBF
            {
                throw new NotAPackageException();
            }

            this.Big = magic == "DBBF";

            if (this.Big == true)
            {
                BigHeader header = input.ReadStructure <BigHeader>();

                if (header.IndexVersion != 3)
                {
                    throw new DatabasePackedFileException("index version was not 3");
                }

                // Nab useful stuff
                this.Version = new Version(header.MajorVersion, header.MinorVersion);
                indexCount   = header.IndexCount;
                indexOffset  = header.IndexOffset;
                indexSize    = header.IndexSize;
            }
            else
            {
                Header header = input.ReadStructure <Header>();

                if (header.IndexVersion != 3)
                {
                    throw new DatabasePackedFileException("index version was not 3");
                }

                // Nab useful stuff
                this.Version = new Version(header.MajorVersion, header.MinorVersion);
                indexCount   = header.IndexCount;
                indexOffset  = header.IndexOffset;
                indexSize    = header.IndexSize;
            }

            this.IndexOffset = indexOffset;
            this.Entries.Clear();

            if (indexCount > 0)
            {
                // Read index
                input.Seek(indexOffset, SeekOrigin.Begin);

                int presentPackageValues = input.ReadValueS32();
                this.IndexType = presentPackageValues;
                if ((presentPackageValues & ~7) != 0)
                {
                    throw new InvalidDataException("don't know how to handle this index data");
                }

                bool hasPackageTypeId       = (presentPackageValues & (1 << 0)) == 1 << 0;
                bool hasPackageGroupId      = (presentPackageValues & (1 << 1)) == 1 << 1;
                bool hasPackageHiInstanceId = (presentPackageValues & (1 << 2)) == 1 << 2;

                uint packageTypeId       = hasPackageTypeId ? input.ReadValueU32() : 0xFFFFFFFF;
                uint packageGroupId      = hasPackageGroupId ? input.ReadValueU32() : 0xFFFFFFFF;
                uint packageHiInstanceId = hasPackageHiInstanceId ? input.ReadValueU32() : 0xFFFFFFFF;

                for (int i = 0; i < indexCount; i++)
                {
                    Entry entry = new Entry();

                    entry.Key.TypeId       = hasPackageTypeId ? packageTypeId : input.ReadValueU32();
                    entry.Key.GroupId      = hasPackageGroupId ? packageGroupId : input.ReadValueU32();
                    entry.Key.InstanceId   = 0;
                    entry.Key.InstanceId  |= (hasPackageHiInstanceId ? packageHiInstanceId : input.ReadValueU32());
                    entry.Key.InstanceId <<= 32;
                    entry.Key.InstanceId  |= input.ReadValueU32();

                    entry.Offset           = (this.Big == true) ? input.ReadValueS64() : input.ReadValueS32();
                    entry.CompressedSize   = input.ReadValueU32();
                    entry.DecompressedSize = input.ReadValueU32();

                    // compressed bit
                    if ((entry.CompressedSize & 0x80000000) == 0x80000000)
                    {
                        entry.CompressedSize  &= ~0x80000000;
                        entry.CompressionFlags = input.ReadValueS16();
                        entry.Flags            = input.ReadValueU16();
                    }
                    else
                    {
                        if (entry.CompressedSize != entry.DecompressedSize)
                        {
                            entry.CompressionFlags = -1;
                        }
                        else
                        {
                            entry.CompressionFlags = 0;
                        }

                        entry.Flags = 0;

                        throw new DatabasePackedFileException("strange index data");
                    }

                    if (entry.CompressionFlags != 0 && entry.CompressionFlags != -1)
                    {
                        throw new DatabasePackedFileException("bad compression flags");
                    }

                    this.Entries.Add(entry);
                }
            }
        }