public Packfile(Stream stream, bool isStr2)
        {
            IsStr2 = isStr2;
            stream.Seek(0, SeekOrigin.Begin);
            FileData = stream.ReadStruct<PackfileFileData>();

            m_Files = new List<IPackfileEntry>();

            uint runningPosition = 0;
            List<PackfileEntryFileData> entryFileData = new List<PackfileEntryFileData>();
            for (int i = 0; i < FileData.NumFiles; i++)
            {
                PackfileEntryFileData data = stream.ReadStruct<PackfileEntryFileData>();

                if (IsCondensed && IsCompressed)
                {
                    data.Flags = 0;
                    data.Start = runningPosition;
                    runningPosition += data.Size;
                }
                else if (IsCondensed)
                {
                    data.Start = runningPosition;
                    runningPosition += data.Size.Align(16);
                }

                entryFileData.Add(data);
            }

            for (int i = 0; i < FileData.NumFiles; i++)
            {
                stream.Align(2);
                string filename = stream.ReadAsciiNullTerminatedString();
                stream.Seek(1, SeekOrigin.Current);
                m_Files.Add(new PackfileEntry(this, entryFileData[i], filename));
                stream.Align(2);
            }

            if (IsCondensed && IsCompressed)
            {
                DataOffset = 0;
                byte[] compressedData = new byte[FileData.CompressedDataSize];
                stream.Read(compressedData, 0, (int)FileData.CompressedDataSize);
                using (MemoryStream tempStream = new MemoryStream(compressedData))
                {
                    using (Stream s = new ZlibStream(tempStream, CompressionMode.Decompress, true))
                    {
                        byte[] uncompressedData = new byte[FileData.DataSize];
                        s.Read(uncompressedData, 0, (int)FileData.DataSize);
                        DataStream = new MemoryStream(uncompressedData);
                    }
                }
                
            }
            else
            {
                DataStream = stream;
                DataOffset = stream.Position;
            }
        }
Beispiel #2
0
        /// <summary>
        ///     Copies the paths from the Index into the given stream at the current address
        ///     note: Creates the table on an align(512) address then creates the table-index on
        ///     an align(512) address following it.
        /// </summary>
        /// <param name="outputStream">The stream to write to</param>
        /// <returns>PathInfoStruct containing addresses/info of the paths table & index</returns>
        private PathsInfoStruct GeneratePathsTable(Stream outputStream)
        {
            var info = new PathsInfoStruct( );
            //  extract the paths from the index and copy them into a local list object.
            var paths = Index.Select(x => x.Path).ToList( );

            info.PathCount        = paths.Count;
            info.PathTableAddress = outputStream.Align(512);
            //  pad the stream to align(512) and assign the new address to PathTableAddress.
            GenerateStringEntries(outputStream, paths);
            //  Write the paths into the stream and subtract the PathTableAddress from the new stream position
            //  to get the PathTableLength.
            info.PathTableLength = ( int )outputStream.Position - info.PathTableAddress;
            //  pad the stream to align(512) and assign the new address to PathIndexAddress.
            info.PathIndexAddress = outputStream.Align(512);
            //  write the index for the path table
            GenerateTableIndex(outputStream, paths);

            //  finish on the next 512 alignment boundary
            outputStream.Align(512);
            Padding.AssertIsAligned(512, outputStream);
            //  return the struct that contains the information about where in the stream this
            //  resource was written
            return(info);
        }
Beispiel #3
0
        private void CopyMeta(Stream outputStream, int address, out int metaDataSize)
        {
            var startAddress = outputStream.Align(512);
            var buffer       = new VirtualStream(address);

            for (var i = 0; i < Index.Count; ++i)
            {
                var datum = Index[i];

                if (datum.Class == TagClass.Sbsp || datum.Class == TagClass.Ltmp)
                {
                    datum.Length         = 0;
                    datum.VirtualAddress = 0;
                    Index.Update(datum.Identifier, datum);
                    continue;
                }

                var data        = Deserialize(datum.Identifier);
                var dataAddress = ( int )buffer.Position;

                Padding.AssertIsAligned(4, buffer);

                buffer.Write(data);
                buffer.Align( );
                var length = ( int )buffer.Position - dataAddress;

                datum.Length         = length;
                datum.VirtualAddress = dataAddress;

                Index.Update(datum.Identifier, datum);
            }
            buffer.Position = 0;
            buffer.BufferedCopyBytesTo(( int )buffer.Length, outputStream);
            metaDataSize = outputStream.Align(4096) - startAddress;
        }
        public Packfile(Stream stream, bool isStr2)
        {
            IsStr2 = isStr2;
            stream.Seek(0, SeekOrigin.Begin);
            FileData = stream.ReadStruct <PackfileFileData>();

            m_Files = new List <IPackfileEntry>();

            uint runningPosition = 0;
            List <PackfileEntryFileData> entryFileData = new List <PackfileEntryFileData>();

            for (int i = 0; i < FileData.NumFiles; i++)
            {
                PackfileEntryFileData data = stream.ReadStruct <PackfileEntryFileData>();

                if (IsCondensed && IsCompressed)
                {
                    data.Flags       = 0;
                    data.Start       = runningPosition;
                    runningPosition += data.Size;
                }
                else if (IsCondensed)
                {
                    data.Start       = runningPosition;
                    runningPosition += data.Size.Align(16);
                }

                entryFileData.Add(data);
            }

            for (int i = 0; i < FileData.NumFiles; i++)
            {
                stream.Align(2);
                string filename = stream.ReadAsciiNullTerminatedString();
                stream.Seek(1, SeekOrigin.Current);
                m_Files.Add(new PackfileEntry(this, entryFileData[i], filename));
                stream.Align(2);
            }

            if (IsCondensed && IsCompressed)
            {
                DataOffset = 0;
                byte[] compressedData = new byte[FileData.CompressedDataSize];
                stream.Read(compressedData, 0, (int)FileData.CompressedDataSize);
                using (MemoryStream tempStream = new MemoryStream(compressedData))
                {
                    using (Stream s = new ZlibStream(tempStream, CompressionMode.Decompress, true))
                    {
                        byte[] uncompressedData = new byte[FileData.DataSize];
                        s.Read(uncompressedData, 0, (int)FileData.DataSize);
                        DataStream = new MemoryStream(uncompressedData);
                    }
                }
            }
            else
            {
                DataStream = stream;
                DataOffset = stream.Position;
            }
        }
Beispiel #5
0
        public void Save(Stream outStream)
        {
            TagGroupHeader header = new TagGroupHeader
            {
                AbideTag         = "atag",
                GroupTag         = TagGroup.Tag,
                TagResourceCount = (uint)resources.Count,
            };

            using (BinaryWriter writer = new BinaryWriter(outStream))
                using (BinaryReader reader = new BinaryReader(outStream))
                {
                    outStream.Seek(TagGroupHeader.Size, SeekOrigin.Current); // skip header
                    TagGroup.Write(writer);

                    if (resources.Count > 0)
                    {
                        header.RawOffsetsOffset = (uint)outStream.Align(512);
                        foreach (int offset in resources.Keys)
                        {
                            writer.Write(offset);
                        }

                        header.RawLengthsOffset = (uint)outStream.Align(512);
                        foreach (byte[] resource in resources.Values)
                        {
                            writer.Write(resource.Length);
                        }

                        header.RawDataOffset = (uint)outStream.Align(512);
                        foreach (byte[] datum in resources.Values)
                        {
                            writer.Write(datum);
                        }
                    }

                    int count = (int)(outStream.Align(16) - TagGroupHeader.Size) / 4;

                    outStream.Seek(TagGroupHeader.Size, SeekOrigin.Begin);
                    for (int i = 0; i < count; i++)
                    {
                        header.Checksum ^= reader.ReadUInt32();
                    }

                    outStream.Seek(0, SeekOrigin.Begin);
                    writer.Write(header);
                }
        }
Beispiel #6
0
        public ClaimsSetMetadata(byte[] data)
            : base(data)
        {
            ClaimSetSize = Stream.ReadInt();

            Stream.Seek(4);

            CompressionFormat        = (CompressionFormat)Stream.ReadInt();
            UncompressedClaimSetSize = Stream.ReadInt();
            ReservedType             = Stream.ReadShort();
            ReservedFieldSize        = Stream.ReadInt();

            Stream.Align(8);

            var size = Stream.ReadInt();

            if (size != ClaimSetSize)
            {
                throw new InvalidDataException($"Data length {size} doesn't match expected ClaimSetSize {ClaimSetSize}");
            }

            var claimSet = Stream.Read(ClaimSetSize);

            if (CompressionFormat != CompressionFormat.COMPRESSION_FORMAT_NONE)
            {
                claimSet = Compressions.Decompress(claimSet, UncompressedClaimSetSize, CompressionFormat);
            }

            ClaimsSet = new ClaimsSet(claimSet);

            ReservedField = Stream.Read(ReservedFieldSize);
        }
Beispiel #7
0
        public static void Write(this Stream stream, ref POF POF, int ID)
        {
            POF.Offsets.Sort();
            long CurrentPOFOffset = 0;
            long POFOffset        = 0;
            byte BitShift         = (byte)(2 + POF.Type);
            int  Max1             = (0x00FF >> BitShift) << BitShift;
            int  Max2             = (0xFFFF >> BitShift) << BitShift;

            POF.Length = 5 + ID;
            for (int i = 0; i < POF.Offsets.Count; i++)
            {
                POFOffset        = POF.Offsets[i] - CurrentPOFOffset;
                CurrentPOFOffset = POF.Offsets[i];
                if (POFOffset <= Max1)
                {
                    POF.Length += 1;
                }
                else if (POFOffset <= Max2)
                {
                    POF.Length += 2;
                }
                else
                {
                    POF.Length += 4;
                }
                POF.Offsets[i] = POFOffset;
            }

            long POFLengthAling = POF.Length.Align(16);

            POF.Header = new Header {
                DataSize = (int)POFLengthAling, ID = ID, Format = Main.Format.F2LE,
                Length   = 0x20, SectionSize = (int)POFLengthAling, Signature = 0x30464F50
            };
            POF.Header.Signature += POF.Type << 24;
            stream.Write(POF.Header);

            stream.Write(POF.Length);
            for (int i = 0; i < POF.Offsets.Count; i++)
            {
                POFOffset = POF.Offsets[i];
                if (POFOffset <= Max1)
                {
                    stream.Write((  byte)((1 << 6) | (POFOffset >> BitShift)));
                }
                else if (POFOffset <= Max2)
                {
                    stream.WriteEndian((ushort)((2 << 14) | (POFOffset >> BitShift)), true);
                }
                else
                {
                    stream.WriteEndian((  uint)((3 << 30) | (POFOffset >> BitShift)), true);
                }
            }
            stream.Write(0x00);
            stream.Align(16, true);
            stream.WriteEOFC(ID);
        }
Beispiel #8
0
        private StringsInfoStruct GenerateStringsTable(Stream outputStream)
        {
            var info = new StringsInfoStruct
            {
                StringCount            = Strings.Length,
                Strings128TableAddress = outputStream.Align(512)
            };

            GenerateStrings128(outputStream);
            info.StringIndexAddress = outputStream.Align(512);
            GenerateTableIndex(outputStream, Strings);
            info.StringTableAddress = outputStream.Align(512);
            GenerateStringEntries(outputStream, Strings);
            info.StringTableLength = ( int )outputStream.Position - info.StringTableAddress;

            outputStream.Align(512);

            return(info);
        }
Beispiel #9
0
        public ClaimEntry(NdrBinaryReader stream)
            : base(stream)
        {
            Stream.Seek(4);

            Type = (ClaimType)Stream.ReadShort();

            Stream.Align(4);

            Count = Stream.ReadUnsignedInt();

            Stream.Seek(4);
        }
Beispiel #10
0
        public ClaimsSet(byte[] claims)
            : base(claims)
        {
            Count = Stream.ReadInt();

            Stream.Seek(4);

            ReservedType      = Stream.ReadShort();
            ReservedFieldSize = Stream.ReadInt();

            ReservedField = Stream.Read(ReservedFieldSize);

            Stream.Align(8);

            ClaimsArray = ReadClaimsArray(Stream);
        }
Beispiel #11
0
        /// <summary>
        ///     Copys all the strings from the cache into 128 byte blocks into outputStream.
        ///     note: will pad to align(512) before and after the table
        /// </summary>
        /// <param name="outputStream">stream to copy strings into</param>
        private void GenerateStrings128(Stream outputStream)
        {
            outputStream.Align(512);
            var buffer = new byte[128];

            foreach (var value in Strings)
            {
                //  zero out the buffer, the convert the string into ASII encoding and get the bytes,
                //  compute the length truncated to the length of the buffer to avoid overrunning the buffer
                //  finally copy the string bytes into the buffer
                Array.Clear(buffer, 0, buffer.Length);
                var sourceArray = Encoding.ASCII.GetBytes(value);
                var length      = Math.Min(sourceArray.Length, buffer.Length);
                Array.Copy(sourceArray, buffer, length);

                outputStream.Write(buffer, 0, buffer.Length);
            }
        }
Beispiel #12
0
        public void Save(Stream s)
        {
            s.WriteStruct(Header);

            foreach (SimulatedNodeInfo sni in Nodes)
            {
                s.WriteStruct(sni);
            }

            foreach (SimulatedNodeLinkInfo snli in NodeLinks)
            {
                s.WriteStruct(snli);
            }

            foreach (ClothSimCollisionPrimitiveInfo cscpi in CollisionPrimitives)
            {
                s.WriteStruct(cscpi);
            }

            s.Align(8);

            foreach (ClothSimRopeInfo csri in Ropes)
            {
                s.WriteStruct(csri);
            }

            for (int i = 0; i < Header.NumRopes; i++)
            {
                List <UInt32> ropeNodes = RopeNodes[i];

                foreach (UInt32 ropeNode in ropeNodes)
                {
                    s.WriteUInt32(ropeNode);
                }

                List <UInt32> ropeLinks = RopeLinks[i];

                foreach (UInt32 ropeLink in ropeLinks)
                {
                    s.WriteUInt32(ropeLink);
                }
            }
        }
Beispiel #13
0
        public UpnDomainInfo(byte[] data)
            : base(data)
        {
            UpnLength = Stream.ReadShort();
            UpnOffset = Stream.ReadShort();

            DnsDomainNameLength = Stream.ReadShort();
            DnsDomainNameOffset = Stream.ReadShort();

            Flags = (UpnDomainFlags)Stream.ReadInt();

            Stream.Align(8);

            Upn = Encoding.Unicode.GetString(Stream.Read(UpnLength));

            Stream.Align(8);

            Domain = Encoding.Unicode.GetString(Stream.Read(DnsDomainNameLength));
        }
Beispiel #14
0
        public void Save(Stream s)
        {
            using (MemoryStream referenceStream = new MemoryStream())
            {
                foreach (string reference in References)
                {
                    referenceStream.WriteAsciiNullTerminatedString(reference);
                }

                Header.ReferenceCount    = (uint)References.Count;
                Header.ReferenceDataSize = (uint)referenceStream.Length;
                s.WriteStruct(Header);
                long position = s.Position;
                s.Seek(position + Header.ReferenceDataStart, SeekOrigin.Begin);
                referenceStream.Seek(0, SeekOrigin.Begin);
                referenceStream.CopyTo(s);
                s.Seek(position + Header.ReferenceDataSize + 1, SeekOrigin.Begin);

                s.Align(16);
            }
        }
Beispiel #15
0
        public VFile(Stream s)
        {
            References = new List <string>();

            Header = s.ReadStruct <VFileHeader>();
            long position = s.Position;

            s.Seek(position + Header.ReferenceDataStart, SeekOrigin.Begin);
            for (int i = 0; i < Header.ReferenceCount; i++)
            {
                string reference = s.ReadAsciiNullTerminatedString();
                References.Add(reference);
            }

            s.Seek(position + Header.ReferenceDataSize + 1, SeekOrigin.Begin);

            if (Header.Version >= 2)
            {
                s.Align(16);
            }
        }
Beispiel #16
0
        private void ProcessDataTable(Chunk chunk)
        {
            Progress?.Report("Processing data table");
            Stream.Align(0x10);

            var table = new AaronDataTable();

            table.Name    = HashResolver.Resolve(Reader.ReadUInt32());
            table.Entries = new List <AaronDataTableEntry>();

            while (Stream.Position < chunk.EndOffset)
            {
                var entry = new AaronDataTableEntry();
                entry.Name     = HashResolver.Resolve(Reader.ReadUInt32());
                entry.Unknown  = Reader.ReadUInt32();
                entry.Unknown2 = Reader.ReadSingle();

                table.Entries.Add(entry);
            }

            _dataTableService.AddDataTable(table);
        }
        static void CreateDummyClothSim(string path)
        {
            Console.WriteLine("Creating dummy cloth sim: {0}", path);
            string name = Path.GetFileNameWithoutExtension(path);

            if (name.Length >= 28) // the field in the struct is only 28 bytes long, and needs to include a null
            {
                name = name.Substring(0, 27);
            }

            using (Stream stream = File.Create(path))
            {
                stream.WriteUInt32(0x02); // version
                stream.WriteUInt32(0);    // data size
                stream.WriteAsciiNullTerminatedString(name);
                stream.Align(0x24);
                stream.WriteUInt32(0); // num passes
                stream.WriteUInt32(1); // air resistance
                stream.WriteUInt32(1); // wind multiplier
                stream.WriteUInt32(1); // wind constant
                stream.WriteUInt32(1); // gravity multiplier
                stream.WriteUInt32(0); // object velocity inheritance
                stream.WriteUInt32(0); // object position inheritance
                stream.WriteUInt32(0); // object rotation inheritance
                stream.WriteUInt32(0); // wind type
                stream.WriteUInt32(0); // num nodes
                stream.WriteUInt32(0); // num anchor nodes
                stream.WriteUInt32(0); // num node links
                stream.WriteUInt32(0); // num ropes
                stream.WriteUInt32(0); // num colliders
                //stream.WriteUInt32(0); // bounding sphere radius
                stream.WriteUInt32(0); // *nodes
                stream.WriteUInt32(0); // *node_links
                stream.WriteUInt32(0); // *ropes
                stream.WriteUInt32(0); // *colliders
            }
        }
        public void Save(Stream stream)
        {
            long dataStart = CalculateDataStartOffset();

            stream.Seek(dataStart, SeekOrigin.Begin);

            long fileStart = 0;

            long compressedSize   = 0;
            long uncompressedSize = 0;

            // Output file data
            ZlibStream dataStream = null;

            if (IsCompressed && IsCondensed)
            {
                dataStream           = new ZlibStream(stream, CompressionMode.Compress, CompressionLevel.BestCompression, true);
                dataStream.FlushMode = FlushType.Sync;
            }

            long compressedStart = 0;

            for (int i = 0; i < Files.Count; i++)
            {
                IPackfileEntry entry = Files[i];
                Stream         fs    = m_Streams[entry.Name];

                bool isLast = (i == (Files.Count - 1));

                PackfileEntry pfE  = (PackfileEntry)entry;
                var           data = pfE.Data;
                data.Start     = (uint)fileStart;
                data.Size      = (uint)fs.Length;
                data.Alignment = (IsCondensed) ? (ushort)16 : (ushort)1;

                if (this.IsCompressed)
                {
                    data.Flags = PackfileEntryFlags.Compressed;
                }

                if (IsCompressed && IsCondensed)
                {
                    fs.CopyTo(dataStream);
                    dataStream.Flush();
                    long afterData = dataStream.TotalOut;
                    data.CompressedSize = (uint)(afterData - compressedStart);
                    compressedStart     = afterData;

                    if (IsStr2)
                    {
                        fileStart        += data.Size.Align(16);
                        uncompressedSize += data.Size.Align(16);
                        compressedSize   += data.CompressedSize;
                    }
                    else
                    {
                        fileStart += data.Size; //.Align(16);
                        if (!isLast)
                        {
                            uncompressedSize += data.Size; //.Align(16);
                            //uint toSkip = data.Size.Align(16) - data.Size;
//                            for (int j = 0; j < toSkip; j++)
                            //dataStream.WriteByte(0);
                        }
                        else
                        {
                            uncompressedSize += data.Size;
                        }
                        compressedSize += data.CompressedSize;
                    }
                }
                else if (IsCondensed)
                {
                    fs.CopyTo(stream);
                    data.CompressedSize = 0xFFFFFFFF;

                    fileStart += data.Size.Align(16);

                    if (isLast)
                    {
                        uncompressedSize += data.Size;
                    }
                    else
                    {
                        uint toSkip = data.Size.Align(16) - data.Size;
                        uncompressedSize += data.Size.Align(16);
                        stream.Seek(toSkip, SeekOrigin.Current);
                    }
                }
                else if (IsCompressed)
                {
                    long beforeData = stream.Position;
                    using (dataStream = new ZlibStream(stream, CompressionMode.Compress, CompressionLevel.BestCompression, true))
                    {
                        dataStream.FlushMode = FlushType.Sync;
                        fs.CopyTo(dataStream);
                        dataStream.Flush();
                    }
                    long afterData = stream.Position;
                    data.CompressedSize = (uint)(afterData - beforeData);
                    fileStart          += data.CompressedSize;
                    uncompressedSize   += data.Size;
                    compressedSize     += data.CompressedSize;
                }
                else
                {
                    fs.CopyTo(stream);
                    data.CompressedSize = 0xFFFFFFFF;
                    fileStart          += data.Size;
                    uncompressedSize   += data.Size;
                }

                fs.Close();

                pfE.Data = data;
            }

            if (IsCompressed && IsCondensed)
            {
                dataStream.Close();
            }

            // Output file names
            stream.Seek(CalculateEntryNamesOffset(), SeekOrigin.Begin);
            long startOffset = CalculateEntryNamesOffset();

            foreach (IPackfileEntry entry in Files)
            {
                PackfileEntry pfE = (PackfileEntry)entry;
                stream.Align(2);
                pfE.Data.FilenameOffset = (UInt32)(stream.Position - startOffset);
                stream.WriteAsciiNullTerminatedString(entry.Name);
                stream.Seek(1, SeekOrigin.Current);
                stream.Align(2);
            }
            long nameSize = stream.Position - CalculateEntryNamesOffset();

            // Output file info
            stream.Seek(GetEntryDataOffset(), SeekOrigin.Begin);
            foreach (IPackfileEntry entry in Files)
            {
                PackfileEntry pfE = (PackfileEntry)entry;
                stream.WriteStruct(pfE.Data);
            }
            long dirSize = stream.Position - GetEntryDataOffset();

            // Output header
            stream.Seek(0, SeekOrigin.Begin);
            FileData.Descriptor     = 0x51890ACE;
            FileData.Version        = 0x0A;
            FileData.HeaderChecksum = 0;
            FileData.FileSize       = (uint)stream.Length;
            FileData.NumFiles       = (uint)Files.Count;
            FileData.DirSize        = (uint)dirSize;
            FileData.FilenameSize   = (uint)nameSize;
            FileData.DataSize       = (uint)uncompressedSize;
            if (IsCompressed)
            {
                FileData.CompressedDataSize = (uint)compressedSize;
            }
            else
            {
                FileData.CompressedDataSize = 0xFFFFFFFF;
            }
            stream.WriteStruct(FileData);

            uint checksum = 0;

            byte[] checksumBuffer = new byte[0x1C];

            stream.Seek(0x0C, SeekOrigin.Begin);
            stream.Read(checksumBuffer, 0, checksumBuffer.Length);
            checksum = Hashes.CrcVolition(checksumBuffer);

            stream.Seek(0x08, SeekOrigin.Begin);
            stream.WriteUInt32(checksum);

            stream.Flush();
        }
Beispiel #19
0
        public void STRWriter(string filepath)
        {
            uint   Offset        = 0;
            uint   CurrentOffset = 0;
            Stream writer        = File.OpenWriter(filepath + (Header.
                                                               Format > Main.Format.FT ? ".str" : ".bin"), true);

            writer.Format = Header.Format;
            POF           = new POF();
            writer.IsBE   = writer.Format == Main.Format.F2BE;

            long Count = STRs.LongLength;

            if (writer.Format > Main.Format.FT)
            {
                writer.Position = 0x40;
                writer.WriteEndian(Count);
                writer.GetOffset(ref POF).WriteEndian(0x80);
                writer.Position = 0x80;
                for (int i = 0; i < Count; i++)
                {
                    writer.GetOffset(ref POF).Write(0x00);
                    writer.WriteEndian(STRs[i].ID);
                }
                writer.Align(16);
            }
            else
            {
                for (int i = 0; i < Count; i++)
                {
                    writer.Write(0x00);
                }
                writer.Align(32);
            }

            List <string> UsedSTR    = new List <string>();
            List <int>    UsedSTRPos = new List <int>();

            int[] STRPos = new int[Count];
            for (int i1 = 0; i1 < Count; i1++)
            {
                if (UsedSTR.Contains(STRs[i1].Str))
                {
                    for (int i2 = 0; i2 < Count; i2++)
                    {
                        if (UsedSTR[i2] == STRs[i1].Str)
                        {
                            STRPos[i1] = UsedSTRPos[i2]; break;
                        }
                    }
                }
                else
                {
                    STRPos[i1] = writer.Position;
                    UsedSTRPos.Add(STRPos[i1]);
                    UsedSTR.Add(STRs[i1].Str);
                    writer.Write(STRs[i1].Str);
                    writer.WriteByte(0);
                }
            }
            if (writer.Format > Main.Format.FT)
            {
                writer.Align(16);
                Offset          = writer.UIntPosition;
                writer.Position = 0x80;
            }
            else
            {
                writer.Position = 0;
            }
            for (int i1 = 0; i1 < Count; i1++)
            {
                writer.WriteEndian(STRPos[i1]);
                if (writer.Format > Main.Format.FT)
                {
                    writer.Position += 4;
                }
            }

            if (writer.Format > Main.Format.FT)
            {
                writer.UIntPosition = Offset;
                writer.Write(ref POF, 1);
                CurrentOffset = writer.UIntPosition;
                writer.WriteEOFC(0);
                Header.Lenght      = 0x40;
                Header.DataSize    = (int)(CurrentOffset - Header.Lenght);
                Header.Signature   = 0x41525453;
                Header.SectionSize = (int)(Offset - Header.Lenght);
                writer.Position    = 0;
                writer.Write(Header);
            }
            writer.Close();
        }
Beispiel #20
0
        public void DEXWriter(string filepath, Main.Format Format)
        {
            Header = new PDHead()
            {
                Format = Format
            };
            IO        = File.OpenWriter(filepath + (Header.Format > Main.Format.F ? ".Dex" : ".bin"), true);
            IO.Format = Header.Format;

            if (IO.Format > Main.Format.F)
            {
                Header.Lenght      = 0x20;
                Header.DataSize    = 0x00;
                Header.Signature   = 0x43505845;
                Header.SectionSize = 0x00;
                IO.Write(Header);
            }

            IO.Write(0x64);
            IO.Write(Dex.Length);

            if (Header.IsX)
            {
                IO.Write((long)0x28);
            }
            else
            {
                IO.Write(0x20);
            }
            if (Header.IsX)
            {
                IO.Write((long)0x00);
            }
            else
            {
                IO.Write(0x00);
            }

            int Position0 = IO.Position;

            IO.Write((long)0x00);
            IO.Write((long)0x00);

            for (int i = 0; i < Dex.Length * 3; i++)
            {
                if (Header.IsX)
                {
                    IO.Write((long)0x00);
                }
                else
                {
                    IO.Write(0x00);
                }
            }

            IO.Align(0x20, true);

            for (int i0 = 0; i0 < Dex.Length; i0++)
            {
                Dex[i0].MainOffset = IO.Position - Header.Lenght;
                for (int i1 = 0; i1 < Dex[i0].Main.Count; i1++)
                {
                    IO.Write(Dex[i0].Main[i1].Frame);
                    IO.Write(Dex[i0].Main[i1].Both);
                    IO.Write(Dex[i0].Main[i1].ID);
                    IO.Write(Dex[i0].Main[i1].Value);
                    IO.Write(Dex[i0].Main[i1].Trans);
                }
                IO.Align(0x20, true);

                Dex[i0].EyesOffset = IO.Position - Header.Lenght;
                for (int i1 = 0; i1 < Dex[i0].Eyes.Count; i1++)
                {
                    IO.Write(Dex[i0].Eyes[i1].Frame);
                    IO.Write(Dex[i0].Eyes[i1].Both);
                    IO.Write(Dex[i0].Eyes[i1].ID);
                    IO.Write(Dex[i0].Eyes[i1].Value);
                    IO.Write(Dex[i0].Eyes[i1].Trans);
                }
                IO.Align(0x20, true);
            }
            for (int i0 = 0; i0 < Dex.Length; i0++)
            {
                Dex[i0].NameOffset = IO.Position - Header.Lenght;
                IO.Write(Dex[i0].Name + "\0");
            }
            IO.Align(0x10, true);

            if (Header.IsX)
            {
                IO.Seek(Header.Lenght + 0x28, 0);
            }
            else
            {
                IO.Seek(Header.Lenght + 0x20, 0);
            }
            for (int i0 = 0; i0 < Dex.Length; i0++)
            {
                IO.Write(Dex[i0].MainOffset);
                if (Header.IsX)
                {
                    IO.Write(0x00);
                }
                IO.Write(Dex[i0].EyesOffset);
                if (Header.IsX)
                {
                    IO.Write(0x00);
                }
            }
            int Position1 = IO.Position - Header.Lenght;

            for (int i0 = 0; i0 < Dex.Length; i0++)
            {
                IO.Write(Dex[i0].NameOffset);
                if (Header.IsX)
                {
                    IO.Write(0x00);
                }
            }

            if (Header.IsX)
            {
                IO.Seek(Position0 - 8, 0);
            }
            else
            {
                IO.Seek(Position0 - 4, 0);
            }
            IO.Write(Position1);

            if (IO.Format > Main.Format.F)
            {
                Offset = IO.Length - Header.Lenght;
                IO.Seek(IO.Length, 0);
                IO.WriteEOFC(0);
                IO.Seek(0, 0);
                Header.DataSize    = Offset;
                Header.SectionSize = Offset;
                IO.Write(Header);
            }
            IO.Close();
        }
        public void Save(Stream stream)
        {
            // Calculate IndexSize
            FileData.IndexCount = (uint)Files.Count;
            FileData.IndexSize  = (FileData.IndexCount * 0x1C);

            // Write Names & calculate NamesSize
            Dictionary <string, uint> filenames = new Dictionary <string, uint>(StringComparer.InvariantCultureIgnoreCase);

            stream.Seek(CalculateEntryNamesOffset(), SeekOrigin.Begin);
            uint filenameOffset = 0;

            foreach (PackfileEntry entry in Files)
            {
                string filename = Path.GetFileNameWithoutExtension(entry.Name);

                if (filenames.ContainsKey(filename))
                {
                    entry.Data.FilenameOffset = filenames[filename];
                }
                else
                {
                    entry.Data.FilenameOffset = filenameOffset;
                    int length = stream.WriteAsciiNullTerminatedString(filename);
                    filenames.Add(filename, filenameOffset);
                    filenameOffset += (uint)length;
                }
            }
            FileData.NamesSize = filenameOffset;

            // Write Extensions & calculate ExtensionsSize
            Dictionary <string, uint> extensions = new Dictionary <string, uint>(StringComparer.InvariantCultureIgnoreCase);
            uint extensionOffset = 0;

            stream.Seek(CalculateExtensionsOffset(), SeekOrigin.Begin);
            foreach (PackfileEntry entry in Files)
            {
                string extension = Path.GetExtension(entry.Name);
                if (extension.StartsWith("."))
                {
                    extension = extension.Remove(0, 1);
                }

                if (extensions.ContainsKey(extension))
                {
                    entry.Data.ExtensionOffset = extensions[extension];
                }
                else
                {
                    entry.Data.ExtensionOffset = extensionOffset;
                    int length = stream.WriteAsciiNullTerminatedString(extension);
                    extensions.Add(extension, extensionOffset);
                    extensionOffset += (uint)length;
                }
            }
            FileData.ExtensionsSize = extensionOffset;

            // Write data
            uint dataOffset = 0;

            stream.Seek(CalculateDataStartOffset(), SeekOrigin.Begin);
            foreach (PackfileEntry entry in Files)
            {
                Stream inStream = m_Streams[entry.Name];
                entry.Data.Size           = (uint)inStream.Length;
                entry.Data.Start          = dataOffset;
                entry.Data.CompressedSize = (uint)0xFFFFFFFF;
                inStream.CopyTo(stream);
                dataOffset += entry.Data.Size;
                stream.Align(16);
                dataOffset = dataOffset.Align(16);
            }

            // Write Header
            stream.Seek(0, SeekOrigin.Begin);
            FileData.Descriptor           = 0x51890ACE;
            FileData.Version              = 0x04;
            FileData.CompressedDataSize   = 0xFFFFFFFF;
            FileData.UncompressedDataSize = dataOffset;
            FileData.PackageSize          = (uint)stream.Length;
            stream.WriteStruct(FileData);

            // Write file index
            stream.Seek(GetEntryDataOffset(), SeekOrigin.Begin);
            foreach (PackfileEntry entry in Files)
            {
                stream.WriteStruct(entry.Data);
            }
        }
Beispiel #22
0
        public ClothSimulationFile(Stream s)
        {
            Header = s.ReadStruct <ClothSimulationHeader>();

            Nodes               = new List <SimulatedNodeInfo>();
            NodeLinks           = new List <SimulatedNodeLinkInfo>();
            Ropes               = new List <ClothSimRopeInfo>();
            RopeNodes           = new List <List <uint> >();
            RopeLinks           = new List <List <uint> >();
            CollisionPrimitives = new List <ClothSimCollisionPrimitiveInfo>();


            for (int i = 0; i < Header.NumNodes; i++)
            {
                SimulatedNodeInfo sni = s.ReadStruct <SimulatedNodeInfo>();
                Nodes.Add(sni);
            }

            for (int i = 0; i < Header.NumNodeLinks; i++)
            {
                SimulatedNodeLinkInfo snli = s.ReadStruct <SimulatedNodeLinkInfo>();
                NodeLinks.Add(snli);
            }

            for (int i = 0; i < Header.NumColliders; i++)
            {
                ClothSimCollisionPrimitiveInfo cscpi = s.ReadStruct <ClothSimCollisionPrimitiveInfo>();
                CollisionPrimitives.Add(cscpi);
            }

            s.Align(8);

            for (int i = 0; i < Header.NumRopes; i++)
            {
                ClothSimRopeInfo csri = s.ReadStruct <ClothSimRopeInfo>();
                Ropes.Add(csri);
            }

            for (int i = 0; i < Header.NumRopes; i++)
            {
                ClothSimRopeInfo csri      = Ropes[i];
                List <UInt32>    ropeNodes = new List <uint>();

                for (int j = 0; j < csri.NumNodes; j++)
                {
                    uint ropeNode = s.ReadUInt32();
                    ropeNodes.Add(ropeNode);
                }

                RopeNodes.Add(ropeNodes);

                List <UInt32> ropeLinks = new List <uint>();

                for (int j = 0; j < csri.NumLinks; j++)
                {
                    uint ropeLink = s.ReadUInt32();
                    ropeLinks.Add(ropeLink);
                }

                RopeLinks.Add(ropeLinks);
            }
        }
Beispiel #23
0
        public static void Write(this Stream IO, ref Pointer <Aif> Aif)
        {
            if (Aif.Value.Unk0.Count > 0)
            {
                Aif.Value.Unk0.Offset = IO.Position;
                for (int i = 0; i < Aif.Value.Unk0.Count; i++)
                {
                    IO.Write(Aif.Value.Unk0.Entries[i]);
                }
            }
            if (Aif.Value.Unk1.Count > 0)
            {
                Aif.Value.Unk1.Offset = IO.Position;
                for (int i = 0; i < Aif.Value.Unk1.Count; i++)
                {
                    IO.Write(Aif.Value.Unk1.Entries[i]);
                }
            }
            if (Aif.Value.Unk2.Count > 0)
            {
                Aif.Value.Unk2.Offset = IO.Position;
                for (int i = 0; i < Aif.Value.Unk2.Count; i++)
                {
                    IO.Write(Aif.Value.Unk2.Entries[i]);
                }
            }
            if (Aif.Value.Unk3.Count > 0)
            {
                Aif.Value.Unk3.Offset = IO.Position;
                for (int i = 0; i < Aif.Value.Unk3.Count; i++)
                {
                    IO.Write(Aif.Value.Unk3.Entries[i]);
                }
            }

            IO.Align(0x10);
            Aif.Value.Value.Offset = IO.Position;
            IO.Write(Aif.Value.Value.Value);

            IO.Align(0x10);
            Aif.Value.Pointer = IO.Position;
            if (Aif.Value.Unk0.Count > 0)
            {
                IO.Write(Aif.Value.Unk0.Count); IO.Write(Aif.Value.Unk0.Offset);
            }
            else
            {
                IO.Write(0L);
            }
            if (Aif.Value.Unk1.Count > 0)
            {
                IO.Write(Aif.Value.Unk1.Count); IO.Write(Aif.Value.Unk1.Offset);
            }
            else
            {
                IO.Write(0L);
            }
            if (Aif.Value.Unk2.Count > 0)
            {
                IO.Write(Aif.Value.Unk2.Count); IO.Write(Aif.Value.Unk2.Offset);
            }
            else
            {
                IO.Write(0L);
            }
            if (Aif.Value.Unk3.Count > 0)
            {
                IO.Write(Aif.Value.Unk3.Count); IO.Write(Aif.Value.Unk3.Offset);
            }
            else
            {
                IO.Write(0L);
            }
        }
        public void Save(Stream stream)
        {
            long dataStart = CalculateDataStartOffset();

            stream.Seek(dataStart, SeekOrigin.Begin);

            long fileStart = 0;

            long compressedSize = 0;
            long uncompressedSize = 0;

            // Output file data
            ZlibStream dataStream = null;
            if (IsCompressed && IsCondensed)
            {
                dataStream = new ZlibStream(stream, CompressionMode.Compress, CompressionLevel.BestCompression, true);
                dataStream.FlushMode = FlushType.Sync;
            }

            long compressedStart = 0;

            for (int i = 0; i < Files.Count; i++)
            {
                IPackfileEntry entry = Files[i];
                Stream fs = m_Streams[entry.Name];

                bool isLast = (i == (Files.Count - 1));

                PackfileEntry pfE = (PackfileEntry)entry;
                var data = pfE.Data;
                data.Start = (uint)fileStart;
                data.Size = (uint)fs.Length;
                data.Alignment = (IsCondensed) ? (ushort)16 : (ushort)1;
                
                if (this.IsCompressed)
                    data.Flags = PackfileEntryFlags.Compressed;

                if (IsCompressed && IsCondensed)
                {
                    fs.CopyTo(dataStream);
                    dataStream.Flush();
                    long afterData = dataStream.TotalOut;
                    data.CompressedSize = (uint)(afterData - compressedStart);
                    compressedStart = afterData;

                    if (IsStr2)
                    {
                        fileStart += data.Size.Align(16);
                        uncompressedSize += data.Size.Align(16);
                        compressedSize += data.CompressedSize;
                    }
                    else
                    {
                        fileStart += data.Size; //.Align(16);
                        if (!isLast)
                        {
                            uncompressedSize += data.Size; //.Align(16);
                            //uint toSkip = data.Size.Align(16) - data.Size;
//                            for (int j = 0; j < toSkip; j++)
                                //dataStream.WriteByte(0);
                        }
                        else
                        {
                            uncompressedSize += data.Size;
                        }
                        compressedSize += data.CompressedSize;
                    }
                }
                else if (IsCondensed)
                {
                    fs.CopyTo(stream);
                    data.CompressedSize = 0xFFFFFFFF;

                    fileStart += data.Size.Align(16);

                    if (isLast)
                        uncompressedSize += data.Size;
                    else
                    {
                        uint toSkip = data.Size.Align(16) - data.Size;
                        uncompressedSize += data.Size.Align(16);
                        stream.Seek(toSkip, SeekOrigin.Current);
                    }

                }
                else if (IsCompressed)
                {
                    long beforeData = stream.Position;
                    using (dataStream = new ZlibStream(stream, CompressionMode.Compress, CompressionLevel.BestCompression, true))
                    {
                        dataStream.FlushMode = FlushType.Sync;
                        fs.CopyTo(dataStream);
                        dataStream.Flush();
                    }
                    long afterData = stream.Position;
                    data.CompressedSize = (uint)(afterData - beforeData);
                    fileStart += data.CompressedSize;
                    uncompressedSize += data.Size;
                    compressedSize += data.CompressedSize;
                }
                else
                {
                    fs.CopyTo(stream);
                    data.CompressedSize = 0xFFFFFFFF;
                    fileStart += data.Size;
                    uncompressedSize += data.Size;
                }

                fs.Close();

                pfE.Data = data;
            }

            if (IsCompressed && IsCondensed)
            {
                dataStream.Close();
            }

            // Output file names
            stream.Seek(CalculateEntryNamesOffset(), SeekOrigin.Begin);
            long startOffset = CalculateEntryNamesOffset();
            foreach (IPackfileEntry entry in Files)
            {
                PackfileEntry pfE = (PackfileEntry)entry;
                stream.Align(2);
                pfE.Data.FilenameOffset = (UInt32)(stream.Position - startOffset);
                stream.WriteAsciiNullTerminatedString(entry.Name);
                stream.Seek(1, SeekOrigin.Current);
                stream.Align(2);
            }
            long nameSize = stream.Position - CalculateEntryNamesOffset();

            // Output file info
            stream.Seek(GetEntryDataOffset(), SeekOrigin.Begin);
            foreach (IPackfileEntry entry in Files)
            {
                PackfileEntry pfE = (PackfileEntry)entry;
                stream.WriteStruct(pfE.Data);
            }
            long dirSize = stream.Position - GetEntryDataOffset();

            // Output header
            stream.Seek(0, SeekOrigin.Begin);
            FileData.Descriptor = 0x51890ACE;
            FileData.Version = 0x0A;
            FileData.HeaderChecksum = 0;
            FileData.FileSize = (uint)stream.Length;
            FileData.NumFiles = (uint)Files.Count;
            FileData.DirSize = (uint)dirSize;
            FileData.FilenameSize = (uint)nameSize;
            FileData.DataSize = (uint)uncompressedSize;
            if (IsCompressed)
                FileData.CompressedDataSize = (uint)compressedSize;
            else
                FileData.CompressedDataSize = 0xFFFFFFFF;
            stream.WriteStruct(FileData);

            uint checksum = 0;
            byte[] checksumBuffer = new byte[0x1C];

            stream.Seek(0x0C, SeekOrigin.Begin);
            stream.Read(checksumBuffer, 0, checksumBuffer.Length);
            checksum = Hashes.CrcVolition(checksumBuffer);

            stream.Seek(0x08, SeekOrigin.Begin);
            stream.WriteUInt32(checksum);

            stream.Flush();
        }
Beispiel #25
0
        private void ProcessBoundsPack(Chunk chunk)
        {
            Progress?.Report("Processing car bounds pack");
            Stream.Align(0x10);

            var boundsHeader = BinaryHelpers.ReadStruct <BoundsHeader>(Reader);
            var car          = _carService.FindCarByCollisionHash(boundsHeader.NameHash);

            if (car.BoundsPack != null)
            {
                throw new InvalidDataException("Duplicate bounds pack for " + car.CarTypeName);
            }

            var bp = new AaronBoundsPack
            {
                Entries     = new List <AaronBoundsEntry>(boundsHeader.NumBounds),
                NameHash    = boundsHeader.NameHash,
                PointClouds = new List <AaronBoundsPointCloud>()
            };

            for (var i = 0; i < boundsHeader.NumBounds; i++)
            {
                var boundsStruct = BinaryHelpers.ReadStruct <Bounds>(Reader);

                Debug.Assert(boundsStruct.CollectionPtr == 0);

                var boundsEntry = new AaronBoundsEntry
                {
                    Position       = boundsStruct.Position,
                    AttributeName  = boundsStruct.AttributeName,
                    ChildIndex     = boundsStruct.ChildIndex,
                    Flags          = (AaronBoundsFlags)boundsStruct.Flags,
                    HalfDimensions = boundsStruct.HalfDimensions,
                    NameHash       = boundsStruct.NameHash,
                    NumChildren    = boundsStruct.NumChildren,
                    Orientation    = boundsStruct.Orientation,
                    PCloudIndex    = boundsStruct.PCloudIndex,
                    Pivot          = boundsStruct.Pivot,
                    Surface        = boundsStruct.Surface
                };

                bp.Entries.Add(boundsEntry);
            }

            var pointCloudHeader = BinaryHelpers.ReadStruct <PCloudHeader>(Reader);

            bp.PointClouds = new List <AaronBoundsPointCloud>(pointCloudHeader.NumPClouds);

            for (var i = 0; i < pointCloudHeader.NumPClouds; i++)
            {
                int numPoints = Reader.ReadInt32();
                Reader.ReadInt64();  // fPad
                Reader.ReadUInt32(); // fPList

                var pointCloud = new AaronBoundsPointCloud
                {
                    Vertices = new List <Vector4>(numPoints)
                };

                for (var j = 0; j < numPoints; j++)
                {
                    var vertex = BinaryHelpers.ReadStruct <Vector4>(Reader);

                    pointCloud.Vertices.Add(vertex);
                }

                bp.PointClouds.Add(pointCloud);
            }

            car.BoundsPack = bp;
        }
Beispiel #26
0
        public void STRWriter(string filepath)
        {
            if (STRs == null || STRs.Length == 0 || Header.Format > Main.Format.F2BE)
            {
                return;
            }
            uint Offset        = 0;
            uint CurrentOffset = 0;

            IO        = File.OpenWriter(filepath + (Header.Format > Main.Format.FT ? ".str" : ".bin"), true);
            IO.Format = Header.Format;
            POF       = new POF();
            IO.IsBE   = IO.Format == Main.Format.F2BE;

            long Count = STRs.LongLength;

            if (IO.Format > Main.Format.FT)
            {
                IO.Position = 0x40;
                IO.WriteX(Count);
                IO.GetOffset(ref POF);
                IO.WriteX(0x80);
                IO.Position = 0x80;
                for (int i = 0; i < Count; i++)
                {
                    IO.Write(0x00L);
                }
                IO.Align(0x10);
            }
            else
            {
                for (int i = 0; i < Count; i++)
                {
                    IO.Write(0x00);
                }
                IO.Align(0x20);
            }

            KKdList <string> UsedSTR    = KKdList <string> .New;
            KKdList <int>    UsedSTRPos = KKdList <int> .New;

            int[] STRPos = new int[Count];
            for (int i = 0; i < Count; i++)
            {
                if (!UsedSTR.Contains(STRs[i].Str.Value))
                {
                    STRPos[i] = IO.Position;
                    UsedSTRPos.Add(STRPos[i]);
                    UsedSTR.Add(STRs[i].Str.Value);
                    IO.Write(STRs[i].Str.Value + "\0");
                }
                else
                {
                    for (int i2 = 0; i2 < Count; i2++)
                    {
                        if (UsedSTR[i2] == STRs[i].Str.Value)
                        {
                            STRPos[i] = UsedSTRPos[i2]; break;
                        }
                    }
                }
            }

            if (IO.Format > Main.Format.FT)
            {
                IO.Align(0x10);
                Offset      = IO.UIntPosition;
                IO.Position = 0x80;
                for (int i = 0; i < Count; i++)
                {
                    IO.GetOffset(ref POF);
                    IO.WriteEndian(STRPos[i]);
                    IO.WriteEndian(STRs[i].ID);
                }

                IO.UIntPosition = Offset;
                IO.Write(ref POF, 1);
                CurrentOffset = IO.UIntPosition;
                IO.WriteEOFC(0);
                Header.DataSize    = (int)(CurrentOffset - 0x40);
                Header.Signature   = 0x41525453;
                Header.SectionSize = (int)(Offset - 0x40);
                IO.Position        = 0;
                IO.Write(Header);
            }
            else
            {
                IO.Position = 0;
                for (int i = 0; i < Count; i++)
                {
                    IO.Write(STRPos[i]);
                }
            }
            IO.Close();
        }
        public void Save(Stream s)
        {
            s.Align(4);

            s.Align(8);

            Header.NumNavpoints = (short)Navpoints.Count;
            Header.NumRigBones  = (short)RigBones.Count;
            // Header.NumMaterials
            // Header.NumMaterialMaps
            // Header.NumLODsPerSubmesh
            // Header.NumSubmeshVIDs
            Header.NumCSpheres   = (ushort)CSpheres.Count;
            Header.NumCCylinders = (ushort)CCylinders.Count;
            // NumLogicalSubmeshes

            s.WriteStruct(Header);

            using (MemoryStream textureNameStream = new MemoryStream())
            {
                string[] textureNames = new string[TextureNames.Count];
                TextureNames.Keys.CopyTo(textureNames, 0);
                foreach (var textureName in textureNames)
                {
                    textureNameStream.Align(2);
                    TextureNames[textureName] = (int)textureNameStream.Position;
                    textureNameStream.WriteAsciiNullTerminatedString(textureName);
                    textureNameStream.WriteUInt8(0); // padding byte?
                    textureNameStream.Align(2);
                }

                s.WriteInt32((int)textureNameStream.Length);
                s.Align(16);
                s.WriteUInt8(0);
                textureNameStream.Seek(0, SeekOrigin.Begin);
                textureNameStream.CopyTo(s);
            }

            if (Header.NumNavpoints > 0)
            {
                s.Align(16);

                foreach (StaticMeshNavpoint navpoint in Navpoints)
                {
                    s.WriteStruct(navpoint);
                }
            }

            if (Header.NumCSpheres > 0)
            {
                s.Align(16);

                foreach (CMeshCSphere csphere in CSpheres)
                {
                    s.WriteStruct(csphere);
                }
            }

            if (Header.NumCCylinders > 0)
            {
                s.Align(16);

                foreach (CMeshCCylinder ccylinder in CCylinders)
                {
                    s.WriteStruct(ccylinder);
                }
            }

            if (Header.NumRigBones > 0)
            {
                s.Align(16);

                foreach (uint rigBone in RigBones)
                {
                    s.WriteUInt32(rigBone);
                }
            }

            s.Align(8);

            s.WriteUInt16(MeshVersion);

            s.Align(4);
            s.WriteUInt32(MeshGpuDataCrc);
            s.WriteUInt32(MeshCpuDataSize);

            s.Write(MiscData, 0, MiscData.Length);

            if (Header.NumMaterialMaps > 0)
            {
                s.Align(8);

                // Skip pointer tables?
                s.Seek(8 * Header.NumMaterialMaps, SeekOrigin.Current);

                for (int i = 0; i < Header.NumMaterialMaps; i++)
                {
                    s.WriteUInt32(MaterialMapCrcs[i]);
                }
            }

            if (Header.NumMaterials > 0)
            {
                s.Align(8);

                // Skip more pointers
                s.Seek(8 * Header.NumMaterials, SeekOrigin.Current);

                for (int i = 0; i < Header.NumMaterials; i++)
                {
                    StaticMeshMaterial material = Materials[i];
                    s.WriteUInt32(material.DataSize);

                    s.Align(8);
                    s.WriteStruct(material.Data);

                    for (int j = 0; j < material.Data.NumTextures; j++)
                    {
                        string textureName = material.TextureNames[j];
                        RenderLibMaterialTextureDesc textureDesc = material.TextureDescriptions[j];
                        int textureNameOffset = TextureNames[textureName];
                        textureDesc.TextureHandle = textureNameOffset;

                        s.WriteStruct(textureDesc);
                    }

                    for (int j = 0; j < material.Data.NumConstants; j++)
                    {
                        uint constantNameChecksum = material.NameChecksums[j];
                        s.WriteUInt32(constantNameChecksum);
                    }

                    s.Align(16);

                    for (int j = 0; j < material.Data.NumConstants; j++)
                    {
                        RenderLibMaterialConstants constant = material.Constants[j];
                        s.WriteStruct(constant);
                    }
                }
            }

            s.Write(MaterialMapData, 0, MaterialMapData.Length);
        }
        public StaticMesh(Stream s)
        {
            s.Align(4);

            s.Align(8);

            Header = s.ReadStruct <StaticMeshHeader>();

            // Read texture names
            int textureNameSize = s.ReadInt32();

            s.Align(16);

            s.ReadByte();

            byte[] textureNameData = new byte[textureNameSize];
            s.Read(textureNameData, 0, textureNameSize);
            MemoryStream textureNameStream = new MemoryStream(textureNameData);

            while (textureNameStream.Position < textureNameData.Length)
            {
                textureNameStream.Align(2);

                int    position    = (int)textureNameStream.Position;
                string textureName = textureNameStream.ReadAsciiNullTerminatedString();
                byte   paddingByte = textureNameStream.ReadUInt8();

                TextureNames.Add(textureName, position);

                if (paddingByte != 0)
                {
                    throw new Exception();
                }

                textureNameStream.Align(2);
            }

            if (Header.Version < 0x2A)
            {
                Header.NumSubmeshVIDs = (ushort)Header.NumLogicalSubmeshes;
            }

            if (Header.NumNavpoints > 0)
            {
                s.Align(16);

                for (int i = 0; i < Header.NumNavpoints; i++)
                {
                    StaticMeshNavpoint navpoint = s.ReadStruct <StaticMeshNavpoint>();
                    Navpoints.Add(navpoint);
                }
            }

            if (Header.NumCSpheres > 0)
            {
                s.Align(16);

                for (int i = 0; i < Header.NumCSpheres; i++)
                {
                    CMeshCSphere cmeshCSphere = s.ReadStruct <CMeshCSphere>();
                    CSpheres.Add(cmeshCSphere);
                }
            }

            if (Header.NumCCylinders > 0)
            {
                s.Align(16);

                for (int i = 0; i < Header.NumCCylinders; i++)
                {
                    CMeshCCylinder cylinder = s.ReadStruct <CMeshCCylinder>();
                    CCylinders.Add(cylinder);
                }
            }

            if (Header.NumRigBones > 0)
            {
                s.Align(16);

                for (int i = 0; i < Header.NumRigBones; i++)
                {
                    UInt32 rigBone = s.ReadUInt32();
                    RigBones.Add(rigBone);
                }
            }

            s.Align(8);

            long originalOffset = s.Position;

            MeshVersion = s.ReadUInt16();

            s.Align(4);

            MeshGpuDataCrc  = s.ReadUInt32();
            MeshCpuDataSize = s.ReadUInt32();

            MiscData = new byte[(originalOffset + MeshCpuDataSize) - s.Position];
            s.Read(MiscData, 0, MiscData.Length);

            if (Header.NumMaterialMaps > 0)
            {
                s.Align(8);

                // Skip pointer tables?
                s.Seek(8 * Header.NumMaterialMaps, SeekOrigin.Current);

                MaterialMapCrcs = new uint[Header.NumMaterialMaps];
                for (int i = 0; i < Header.NumMaterialMaps; i++)
                {
                    MaterialMapCrcs[i] = s.ReadUInt32();
                }
            }

            if (Header.NumMaterials > 0)
            {
                s.Align(8);

                // Skip more pointers
                s.Seek(8 * Header.NumMaterials, SeekOrigin.Current);

                for (int i = 0; i < Header.NumMaterials; i++)
                {
                    StaticMeshMaterial material = new StaticMeshMaterial();
                    Materials.Add(material);

                    long materialStart = s.Position;

                    material.DataSize = s.ReadUInt32();

                    s.Align(8);

                    material.Data = s.ReadStruct <RenderLibMaterialData>();

                    s.Align(4);

                    for (int j = 0; j < material.Data.NumTextures; j++)
                    {
                        RenderLibMaterialTextureDesc textureDesc = s.ReadStruct <RenderLibMaterialTextureDesc>();
                        material.TextureDescriptions.Add(textureDesc);
                    }

                    s.Align(4);

                    for (int j = 0; j < material.Data.NumConstants; j++)
                    {
                        uint constantNameChecksum = s.ReadUInt32();
                        material.NameChecksums.Add(constantNameChecksum);
                    }

                    s.Align(16);

                    for (int j = 0; j < material.Data.NumConstants; j++)
                    {
                        RenderLibMaterialConstants constant = s.ReadStruct <RenderLibMaterialConstants>();
                        material.Constants.Add(constant);
                    }

                    uint materialSize = (uint)(s.Position - materialStart);
                    if (materialSize != material.DataSize)
                    {
                        throw new Exception(String.Format("materialSize != material.DataSize - {0} != {1}", materialSize, material.DataSize));
                    }

                    if (material.Data.NumTextures > 0)
                    {
                        for (int j = 0; j < material.Data.NumTextures; j++)
                        {
                            RenderLibMaterialTextureDesc textureDesc = material.TextureDescriptions[j];
                            textureNameStream.Seek(textureDesc.TextureHandle, SeekOrigin.Begin);
                            string textureName = textureNameStream.ReadAsciiNullTerminatedString();
                            material.TextureNames.Add(textureName);
                        }
                    }
                }
            }

            MaterialMapData = new byte[s.Length - s.Position];
            s.Read(MaterialMapData, 0, MaterialMapData.Length);
        }
        public void Save(Stream stream)
        {
            // Calculate IndexSize
            FileData.IndexCount = (uint)Files.Count;
            FileData.IndexSize = (FileData.IndexCount * 0x1C);

            // Write Names & calculate NamesSize
            Dictionary<string, uint> filenames = new Dictionary<string, uint>(StringComparer.InvariantCultureIgnoreCase);
            stream.Seek(CalculateEntryNamesOffset(), SeekOrigin.Begin);
            uint filenameOffset = 0;
            foreach (PackfileEntry entry in Files)
            {
                string filename = Path.GetFileNameWithoutExtension(entry.Name);

                if (filenames.ContainsKey(filename))
                {
                    entry.Data.FilenameOffset = filenames[filename];
                }
                else
                {
                    entry.Data.FilenameOffset = filenameOffset;
                    int length = stream.WriteAsciiNullTerminatedString(filename);
                    filenames.Add(filename, filenameOffset);
                    filenameOffset += (uint)length;
                }

            }
            FileData.NamesSize = filenameOffset;
            
            // Write Extensions & calculate ExtensionsSize
            Dictionary<string, uint> extensions = new Dictionary<string, uint>(StringComparer.InvariantCultureIgnoreCase);
            uint extensionOffset = 0;
            stream.Seek(CalculateExtensionsOffset(), SeekOrigin.Begin);
            foreach (PackfileEntry entry in Files)
            {
                string extension = Path.GetExtension(entry.Name);
                if (extension.StartsWith("."))
                    extension = extension.Remove(0, 1);

                if (extensions.ContainsKey(extension))
                {
                    entry.Data.ExtensionOffset = extensions[extension];
                }
                else
                {
                    entry.Data.ExtensionOffset = extensionOffset;
                    int length = stream.WriteAsciiNullTerminatedString(extension);
                    extensions.Add(extension, extensionOffset);
                    extensionOffset += (uint)length;
                }
            }
            FileData.ExtensionsSize = extensionOffset;

            // Write data
            uint dataOffset = 0;
            stream.Seek(CalculateDataStartOffset(), SeekOrigin.Begin);
            foreach (PackfileEntry entry in Files)
            {
                Stream inStream = m_Streams[entry.Name];
                entry.Data.Size = (uint)inStream.Length;
                entry.Data.Start = dataOffset;
                entry.Data.CompressedSize = (uint)0xFFFFFFFF;
                inStream.CopyTo(stream);
                dataOffset += entry.Data.Size;
                stream.Align(16);
                dataOffset = dataOffset.Align(16);
            }

            // Write Header
            stream.Seek(0, SeekOrigin.Begin);
            FileData.Descriptor = 0x51890ACE;
            FileData.Version = 0x04;
            FileData.CompressedDataSize = 0xFFFFFFFF;
            FileData.UncompressedDataSize = dataOffset;
            FileData.PackageSize = (uint)stream.Length;
            stream.WriteStruct(FileData);
            
            // Write file index
            stream.Seek(GetEntryDataOffset(), SeekOrigin.Begin);
            foreach (PackfileEntry entry in Files)
            {
                stream.WriteStruct(entry.Data);
            }
        }
Beispiel #30
0
        public void BINWriter(string file)
        {
            if (AetSets == null)
            {
                return;
            }
            if (AetSets.Length == 0)
            {
                return;
            }

            List <string> SetName     = new List <string>();
            List <string> SetFileName = new List <string>();

            List <int> Ids    = new List <int>();
            List <int> SetIds = new List <int>();

            List <int> NotAdd = new List <int>();
            AET        temp;
            AetSet     set;

            for (i = 0; i < AetSets.Length; i++)
            {
                set = AetSets[i];
                if (set.Name != null)
                {
                    if (SetName.Contains(set.Name))
                    {
                        NotAdd.Add(i); continue;
                    }
                    else
                    {
                        SetName.Add(set.Name);
                    }
                }
                if (set.FileName != null)
                {
                    if (SetFileName.Contains(set.FileName))
                    {
                        NotAdd.Add(i); continue;
                    }
                    else
                    {
                        SetFileName.Add(set.FileName);
                    }
                }

                if (set.NewId)
                {
                    AetSets[i].Id = null;
                    for (i0 = 0; i0 < set.Aets.Length; i0++)
                    {
                        AetSets[i].Aets[i0].Id = null;
                    }
                    continue;
                }

                if (set.Id != null)
                {
                    if (SetIds.Contains((int)set.Id))
                    {
                        NotAdd.Add(i); continue;
                    }
                    else
                    {
                        SetIds.Add((int)set.Id);
                    }
                }

                for (i0 = 0; i0 < set.Aets.Length; i0++)
                {
                    temp = set.Aets[i0];
                    if (temp.Id != null)
                    {
                        if (Ids.Contains((int)temp.Id))
                        {
                            NotAdd.Add(i); break;
                        }
                        else
                        {
                            Ids.Add((int)temp.Id);
                        }
                    }
                }
            }
            SetName     = null;
            SetFileName = null;

            for (i = 0; i < AetSets.Length; i++)
            {
                set = AetSets[i];
                if (NotAdd.Contains(i))
                {
                    continue;
                }
                if (!set.NewId)
                {
                    continue;
                }

                i1 = 0;
                if (set.Id == null)
                {
                    while (true)
                    {
                        if (!SetIds.Contains(i1))
                        {
                            AetSets[i].Id = i1; SetIds.Add(i1); break;
                        }
                        i1++;
                    }
                }

                for (i0 = 0, i1 = 0; i0 < set.Aets.Length; i0++)
                {
                    if (set.Aets[i0].Id == null)
                    {
                        while (true)
                        {
                            if (!Ids.Contains(i1))
                            {
                                AetSets[i].Aets[i0].Id = i1; Ids.Add(i1); break;
                            }
                            i1++;
                        }
                    }
                }
            }

            Ids    = null;
            SetIds = null;

            for (i = 0, i0 = 0, i2 = 0; i < AetSets.Length; i++)
            {
                if (!NotAdd.Contains(i))
                {
                    i0 += AetSets[i].Aets.Length; i2++;
                }
            }

            i1 = i0 * 12;
            i1 = i1.Align(0x20) + 0x20;

            IO = File.OpenWriter(file + ".bin", true);
            IO.Write(i2);
            IO.Write(i1);
            IO.Write(i0);
            IO.Write(0x20);
            IO.Write(0x9066906690669066);
            IO.Write(0x9066906690669066);

            IO.Position = (i1 + i2 * 0x14).Align(0x20);
            for (i = 0; i < AetSets.Length; i++)
            {
                if (NotAdd.Contains(i))
                {
                    continue;
                }
                AetSets[i].NameOffset     = IO.Position; IO.Write(AetSets[i].Name + "\0");
                AetSets[i].FileNameOffset = IO.Position; IO.Write(AetSets[i].FileName + "\0");
            }

            for (i = 0; i < AetSets.Length; i++)
            {
                if (NotAdd.Contains(i))
                {
                    continue;
                }
                for (i0 = 0; i0 < AetSets[i].Aets.Length; i0++)
                {
                    AetSets[i].Aets[i0].NameOffset = IO.Position; IO.Write(AetSets[i].Aets[i0].Name + "\0");
                }
            }
            IO.Align(0x08, true);

            IO.Position = 0x20;
            for (i = 0, i2 = 0; i < AetSets.Length; i++)
            {
                if (NotAdd.Contains(i))
                {
                    i2++; continue;
                }

                for (i0 = 0; i0 < AetSets[i].Aets.Length; i0++)
                {
                    IO.Write(AetSets[i].Aets[i0].Id);
                    IO.Write(AetSets[i].Aets[i0].NameOffset);
                    IO.Write((ushort)i0);
                    IO.Write((ushort)(i - i2));
                }
            }
            IO.Align(0x20);
            for (i = 0, i2 = 0; i < AetSets.Length; i++)
            {
                if (NotAdd.Contains(i))
                {
                    i2++; continue;
                }

                IO.Write(AetSets[i].Id);
                IO.Write(AetSets[i].NameOffset);
                IO.Write(AetSets[i].FileNameOffset);
                IO.Write(i - i2);
                IO.Write(AetSets[i].SpriteSetId);
            }
            IO.Close();
        }
Beispiel #31
0
        public void DEXWriter(string filepath, Main.Format Format)
        {
            Header        = new Header();
            IO            = File.OpenWriter(filepath + (Format > Main.Format.F ? ".dex" : ".bin"), true);
            Header.Format = IO.Format = Format;

            IO.Offset = Format > Main.Format.F ? 0x20 : 0;
            IO.Write(0x64);
            IO.Write(Dex.Length);

            IO.WriteX(Header.IsX ? 0x28 : 0x20);
            IO.WriteX(0x00);

            int Position0 = IO.Position;

            IO.Write(0x00L);
            IO.Write(0x00L);

            for (int i = 0; i < Dex.Length * 3; i++)
            {
                IO.WriteX(0x00);
            }

            IO.Align(0x20, true);

            for (int i0 = 0; i0 < Dex.Length; i0++)
            {
                Dex[i0].MainOffset = IO.Position;
                for (int i1 = 0; i1 < Dex[i0].Main.Count; i1++)
                {
                    IO.Write(Dex[i0].Main[i1].Frame);
                    IO.Write(Dex[i0].Main[i1].Both);
                    IO.Write(Dex[i0].Main[i1].ID);
                    IO.Write(Dex[i0].Main[i1].Value);
                    IO.Write(Dex[i0].Main[i1].Trans);
                }
                IO.Align(0x20, true);

                Dex[i0].EyesOffset = IO.Position;
                for (int i1 = 0; i1 < Dex[i0].Eyes.Count; i1++)
                {
                    IO.Write(Dex[i0].Eyes[i1].Frame);
                    IO.Write(Dex[i0].Eyes[i1].Both);
                    IO.Write(Dex[i0].Eyes[i1].ID);
                    IO.Write(Dex[i0].Eyes[i1].Value);
                    IO.Write(Dex[i0].Eyes[i1].Trans);
                }
                IO.Align(0x20, true);
            }
            for (int i0 = 0; i0 < Dex.Length; i0++)
            {
                Dex[i0].NameOffset = IO.Position;
                IO.Write(Dex[i0].Name + "\0");
            }
            IO.Align(0x10, true);

            IO.Position = Header.IsX ? 0x28 : 0x20;
            for (int i0 = 0; i0 < Dex.Length; i0++)
            {
                IO.WriteX(Dex[i0].MainOffset);
                IO.WriteX(Dex[i0].EyesOffset);
            }
            int Position1 = IO.Position;

            for (int i0 = 0; i0 < Dex.Length; i0++)
            {
                IO.WriteX(Dex[i0].NameOffset);
            }

            IO.Position = Position0 - (Header.IsX ? 8 : 4);
            IO.Write(Position1);

            if (Format > Main.Format.F)
            {
                Offset      = IO.Length;
                IO.Offset   = 0;
                IO.Position = IO.Length;
                IO.WriteEOFC(0);
                IO.Position        = 0;
                Header.DataSize    = Offset;
                Header.SectionSize = Offset;
                Header.Signature   = 0x43505845;
                IO.Write(Header, true);
            }
            IO.Close();
        }