예제 #1
0
        public static AssetReference Read(ExtendedBinaryReader br)
        {
            string assetPath = br.ReadNullTerminatedString();

            byte[] GUID     = br.ReadBytes(16);
            int    type     = br.ReadInt32();
            string filePath = br.ReadNullTerminatedString();

            return(new AssetReference(assetPath: assetPath, GUID: GUID, type: type, filePath: filePath));
        }
예제 #2
0
        public override void Load(ExtendedBinaryReader reader, bool keepOpen = false)
        {
            string header = reader.ReadNullTerminatedString();

            reader.FixPadding(16);
            uint   textureOffset = reader.ReadUInt32();
            uint   textureCount  = reader.ReadUInt32();
            int    layerOffset   = reader.ReadInt32();
            int    layerCount    = reader.ReadInt32();
            int    unknownOffset = reader.ReadInt32();
            int    unknownCount  = reader.ReadInt32();
            uint   unknown28     = reader.ReadUInt32();
            uint   unknown2C     = reader.ReadUInt32();
            string projectDir    = reader.ReadStringElsewhere();
            uint   unknown34     = reader.ReadUInt32();
            uint   unknown38     = reader.ReadUInt32();
            uint   unknown3C     = reader.ReadUInt32();

            reader.JumpTo(textureOffset);
            for (int i = 0; i < textureCount; ++i)
            {
                Textures.Add(new MATexture(reader));
            }

            reader.JumpTo(layerOffset);
            for (int i = 0; i < layerCount; ++i)
            {
                Layers.Add(new MALayer(reader));
            }
        }
예제 #3
0
        public override void Load(Stream fileStream)
        {
            // Header
            var reader = new ExtendedBinaryReader(fileStream);

            // Apparently SEGA doesn't even do signature checking (try loading an AR in-game
            // with the first 0xC bytes set to 0, it works just fine), so why should we?
            reader.JumpAhead(0xC);
            Padding = reader.ReadUInt32();

            // Data
            while (fileStream.Position < fileStream.Length)
            {
                reader.Offset = (uint)fileStream.Position;

                uint   dataEndOffset   = reader.ReadUInt32();
                uint   dataLength      = reader.ReadUInt32();
                uint   dataStartOffset = reader.ReadUInt32();
                uint   unknown1        = reader.ReadUInt32();
                uint   unknown2        = reader.ReadUInt32();
                string name            = reader.ReadNullTerminatedString();

                reader.JumpTo(dataStartOffset, false);
                var data = reader.ReadBytes((int)dataLength);
                reader.JumpTo(dataEndOffset, false);

                var file = new ArchiveFile()
                {
                    Name = name,
                    Data = data
                };
                Data.Add(file);
            }
        }
예제 #4
0
        public NXNN ReadNodeNames(ExtendedBinaryReader reader, long pos)
        {
            NodeTree = new NXNN()
            {
                TreeNode   = new string(reader.ReadChars(4)),
                NodeLength = reader.ReadUInt32()
            };

            pos = reader.BaseStream.Position; //Save Position
            reader.JumpTo(reader.ReadUInt32() + 4, false);
            var nodeCount = reader.ReadUInt32();

            reader.JumpTo(reader.ReadUInt32(), false);
            for (int i = 0; i < nodeCount; i++)
            {
                NodeTree node = new NodeTree();
                node.NodeIndex = reader.ReadUInt32();
                var  nameOffset = reader.ReadUInt32();
                long nodePos    = reader.BaseStream.Position; //Save Position
                reader.JumpTo(nameOffset, false);
                node.NodeName = reader.ReadNullTerminatedString();
                reader.JumpTo(nodePos);
                NodeTree.Nodes.Add(node);
            }
            reader.JumpTo(pos);
            reader.JumpAhead(NodeTree.NodeLength);
            return(NodeTree);
        }
예제 #5
0
        public NXTL ReadTextureList(ExtendedBinaryReader reader, long pos)
        {
            TextureList = new NXTL()
            {
                TextureListNode = new string(reader.ReadChars(4)),
                NodeLength      = reader.ReadUInt32()
            };

            pos = reader.BaseStream.Position; //Save Position
            reader.JumpTo(reader.ReadUInt32(), false);
            TextureList.TextureCount = reader.ReadUInt32();
            uint textureListOffset = reader.ReadUInt32();

            reader.JumpTo(textureListOffset, false);

            for (int i = 0; i < TextureList.TextureCount; i++)
            {
                reader.JumpAhead(0x4);
                uint textureNameOffset = reader.ReadUInt32();
                long texturePos        = reader.BaseStream.Position; //Save Position
                reader.JumpTo(textureNameOffset, false);
                TEXFILE tex = new TEXFILE();
                tex.Filename = reader.ReadNullTerminatedString();
                reader.JumpTo(texturePos);
                tex.Filters = reader.ReadUInt32();
                reader.JumpAhead(0x8);
                TextureList.Textures.Add(tex);
            }
            reader.JumpTo(pos);
            reader.JumpAhead(TextureList.NodeLength);
            return(TextureList);
        }
 public static string ReadEntry(ExtendedBinaryReader reader)
 {
     if (reader.BaseStream.Position < reader.BaseStream.Length)
     {
         return(reader.ReadNullTerminatedString());
     }
     return("");
 }
예제 #7
0
        public override void Load(ExtendedBinaryReader reader, bool keepOpen = false)
        {
            // Check if file has a signature
            string sig = reader.ReadSignature();

            if (sig == "STSC")
            { // Newer script format
                uint headerSize = reader.ReadUInt32();
                Version = reader.ReadUInt32();
                switch (Version)
                {
                case 4:     // Date A Live: Twin Edition Rio Reincarnation (PSV)
                    ScriptID = reader.ReadUInt16();
                    break;

                case 7:     // Date A Live: Rio Reincarnation (PC)
                    ScriptName = reader.ReadNullTerminatedString();
                    reader.JumpAhead((uint)(0x20 - (ScriptName.Length + 1)));
                    reader.JumpAhead(12);
                    ScriptID = reader.ReadUInt32();
                    break;
                }
            }
            else
            { // Older script format
                // Jump back as older scripts have much smaller headers
                reader.JumpBehind(4);
                ScriptID = reader.ReadUInt16();
            }
            // Stupid workaround to find the end of the code segment
            reader.Offset = (uint)reader.BaseStream.Length;
            while (true)
            {
                byte opcode = reader.ReadByte();

                if (opcode >= 0x94)
                {
                    throw new STSCDisassembleException(this,
                                                       $"Got opcode 0x{opcode:X2} at 0x{reader.BaseStream.Position - 1:X8} in \"{ScriptName}\"" +
                                                       " There is no opcodes larger than 0x93!");
                }

                // Check if its a known instruction
                if (STSCInstructions.DALRRInstructions[opcode] == null)
                {
                    throw new STSCDisassembleException(this,
                                                       $"Got opcode 0x{opcode:X2} at 0x{reader.BaseStream.Position - 1:X8} in \"{ScriptName}\"" +
                                                       " This opcode is unknown!");
                }

                var instruction = STSCInstructions.DALRRInstructions[opcode].Read(reader);
                Instructions.Add(instruction);
                if (reader.BaseStream.Position >= reader.Offset)
                {
                    break;
                }
            }
        }
예제 #8
0
        public NXEF ReadEffectList(ExtendedBinaryReader reader, long pos)
        {
            EffectList = new NXEF()
            {
                EffectNode = new string(reader.ReadChars(4)),
                NodeLength = reader.ReadUInt32()
            };

            pos = reader.BaseStream.Position; //Save Position
            reader.JumpTo(reader.ReadUInt32() + 4, false);
            var effectTypeCount  = reader.ReadUInt32();
            var effectTypeOffset = reader.ReadUInt32();
            var techiqueCount    = reader.ReadUInt32();
            var techniqueOffset  = reader.ReadUInt32();

            reader.JumpTo(effectTypeOffset, false);
            for (int i = 0; i < effectTypeCount; i++)
            {
                EFFFILE effFile = new EFFFILE();
                effFile.Type = reader.ReadUInt32();
                var  jumpPoint = reader.ReadUInt32();
                long effectPos = reader.BaseStream.Position; //Save Position
                reader.JumpTo(jumpPoint, false);
                effFile.Filename = reader.ReadNullTerminatedString();
                reader.JumpTo(effectPos);
                EffectList.Effects.Add(effFile);
            }
            reader.JumpTo(techniqueOffset, false);
            for (int i = 0; i < techiqueCount; i++)
            {
                TECHNAME tech = new TECHNAME();
                tech.Type   = reader.ReadUInt32();
                tech.NodeID = reader.ReadUInt32();
                var  jumpPoint = reader.ReadUInt32();
                long techPos   = reader.BaseStream.Position; //Save Position
                reader.JumpTo(jumpPoint, false);
                tech.Filename = reader.ReadNullTerminatedString();
                reader.JumpTo(techPos);
                EffectList.Techs.Add(tech);
            }
            reader.JumpTo(pos);
            reader.JumpAhead(EffectList.NodeLength);
            return(EffectList);
        }
예제 #9
0
        // TODO
        protected void LoadShadowArchive(ExtendedBinaryReader reader)
        {
            reader.JumpAhead(0x4);                                 // Unknown, Seems to always be 0
            uint   fileSize   = reader.ReadUInt32();               // File Size - 0xC
            uint   magic      = reader.ReadUInt32();               // Magic
            string ONEVersion = reader.ReadNullTerminatedString(); // Gets the version String

            reader.FixPadding();                                   // Aligns the reader

            uint fileCount = reader.ReadUInt32();                  // File Count

            reader.JumpAhead(0x38 * 2 + 0x20);                     // Jump to the third/first entry
            bool isVersion6     = ONEVersion == "ONE Ver 0.60";    // Checks if its version is 0.60
            int  fileNameLength = isVersion6 ? 0x2C : 0x20;        // The max file name size

            // Read File List
            var files = new FileEntry[FileEntryCount];

            for (int i = 0; i < fileCount; i++)
            {
                var entry = new FileEntry();
                entry.FileName = reader.ReadSignature(
                    fileNameLength).Replace("\0", string.Empty);

                entry.UncompressedSize = reader.ReadUInt32();
                entry.DataOffset       = reader.ReadUInt32();
                reader.JumpAhead(4); // Unknown, Seems to always be 1

                if (!isVersion6)
                {
                    reader.JumpAhead(0xC); // Unknown, Seems to always be 0
                }
                files[i] = entry;
            }

            // Read File Data
            if (files.Length > 0)
            {
                reader.JumpTo(files[0].DataOffset + 0xC);
                for (int i = 0; i < fileCount; ++i)
                {
                    // Compute the file's data length
                    files[i].DataLength = ((i == fileCount - 1) ?
                                           fileSize + 0xC : files[i + 1].DataOffset) - files[i].DataOffset;

                    var file = new ArchiveFile()
                    {
                        Name = files[i].FileName,
                        Data = reader.ReadBytes(
                            (int)files[i].DataLength) // TODO: Decompress file
                    };
                    Data.Add(file);
                }
            }
        }
예제 #10
0
        public void Read(ExtendedBinaryReader reader)
        {
            uint texNameOffset = reader.ReadUInt32();

            TexFlags = reader.ReadUInt32();
            uint texTypeOffset = reader.ReadUInt32();

            // Unknown Value Check
            if (TexFlags != 0)
            {
                Console.WriteLine($"WARNING: Texture Flags != 0 ({TexFlags})");
            }

            // Texture Name
            reader.JumpTo(texNameOffset, false);
            TextureName = reader.ReadNullTerminatedString();

            // Texture Type
            reader.JumpTo(texTypeOffset, false);
            Type = reader.ReadNullTerminatedString();
        }
        // Methods
        public static void Read(HavokFile h, ExtendedBinaryReader reader)
        {
            // Header
            reader.JumpAhead(0x10);

            // A lot of this was gathered from the Max Havok exporter.
            byte bytesInPointer = reader.ReadByte();

            reader.IsBigEndian = !reader.ReadBoolean();
            byte reusePaddingOpt   = reader.ReadByte();
            byte emptyBaseClassOpt = reader.ReadByte();

            // We jump around a lot here, but there's not really a much cleaner way to do it.
            reader.JumpTo(8, true);
            h.UserTag      = reader.ReadUInt32();
            h.ClassVersion = reader.ReadInt32();
            reader.JumpAhead(4);

            uint  sectionsCount = reader.ReadUInt32();
            uint  unknown1      = reader.ReadUInt32();
            ulong padding1      = reader.ReadUInt64();

            uint unknown2 = reader.ReadUInt32();

            h.ContentsVersion = reader.ReadNullTerminatedString();
            reader.JumpAhead(9); // Seems to be padding

            // Sections
            for (uint i = 0; i < sectionsCount; ++i)
            {
                string sectionName = new string(reader.ReadChars(0x10));
                sectionName = sectionName.Replace("\0", string.Empty);

                // TODO
                reader.JumpAhead(0x20);
            }

            // Padding Checks
            if (padding1 != 0)
            {
                Console.WriteLine($"WARNING: Padding1 != 0 ({padding1})");
            }

            // TODO
            throw new NotImplementedException();
        }
예제 #12
0
        public void Read(ExtendedBinaryReader reader, uint textureCount)
        {
            // Texture Offsets
            var textureOffsets = new uint[textureCount];

            for (uint i = 0; i < textureCount; ++i)
            {
                textureOffsets[i] = reader.ReadUInt32();
            }

            // Textures
            textures.Clear();
            for (uint i = 0; i < textureCount; ++i)
            {
                reader.JumpTo(textureOffsets[i], false);
                textures.Add(new GensTexture(
                                 reader.ReadNullTerminatedString()));
            }
        }
예제 #13
0
        public NinjaTextureList ReadNinjaTextureList(ExtendedBinaryReader reader, long pos)
        {
            NinjaTextureList = new NinjaTextureList()
            {
                NodeName = new string(reader.ReadChars(4))
            };
            uint NodeLength = reader.ReadUInt32();

            pos = reader.BaseStream.Position; //Save Position
            uint NodeOffset = reader.ReadUInt32();

            reader.JumpTo(NodeOffset, false);

            uint TextureCount      = reader.ReadUInt32();
            uint TextureListOffset = reader.ReadUInt32();

            reader.JumpTo(TextureListOffset, false);

            for (int i = 0; i < TextureCount; i++)
            {
                uint Unknown1          = reader.ReadUInt32();        //Seems to always be 0 (at least in XN*s)? (Padding?)
                uint TextureNameOffset = reader.ReadUInt32();
                long currentPos        = reader.BaseStream.Position; //Save Position
                reader.JumpTo(TextureNameOffset, false);
                NinjaTextureFile TextureFile = new NinjaTextureFile()
                {
                    TextureName = reader.ReadNullTerminatedString()
                };
                reader.JumpTo(currentPos, true);
                TextureFile.Filters = reader.ReadUInt32();
                uint Unknown2 = reader.ReadUInt32(); //Seems to always be 0 (at least in XN*s)? (Padding?)
                uint Unknown3 = reader.ReadUInt32(); //Seems to always be 0 (at least in XN*s)? (Padding?)
                NinjaTextureList.TextureFiles.Add(TextureFile);
            }

            reader.JumpTo(pos, true);
            reader.JumpAhead(NodeLength);
            return(NinjaTextureList);
        }
예제 #14
0
        public NinjaNodeNameList ReadNinjaNodeNameList(ExtendedBinaryReader reader, long pos)
        {
            NinjaNodeNameList = new NinjaNodeNameList()
            {
                NodeName = new string(reader.ReadChars(4))
            };
            uint NodeLength = reader.ReadUInt32();

            pos = reader.BaseStream.Position; //Save Position
            uint NodeOffset = reader.ReadUInt32();

            reader.JumpTo(NodeOffset, false);

            uint Unknown1        = reader.ReadUInt32(); //Padding?
            uint NodeTableCount  = reader.ReadUInt32();
            uint NodeTableOffset = reader.ReadUInt32();

            reader.JumpTo(NodeTableOffset, false);

            for (int i = 0; i < NodeTableCount; i++)
            {
                NinjaNodeName NodeName = new NinjaNodeName()
                {
                    ID = reader.ReadUInt32()
                };
                uint NodeNameIndex = reader.ReadUInt32();
                long currentPos    = reader.BaseStream.Position; //Save Position
                reader.JumpTo(NodeNameIndex, false);
                NodeName.Name = reader.ReadNullTerminatedString();
                reader.JumpTo(currentPos, true);
                NinjaNodeNameList.NinjaNodeNames.Add(NodeName);
            }

            reader.JumpTo(pos, true);
            reader.JumpAhead(NodeLength);
            return(NinjaNodeNameList);
        }
예제 #15
0
        public NinjaEffectList ReadNinjaEffectList(ExtendedBinaryReader reader, long pos)
        {
            NinjaEffectList = new NinjaEffectList()
            {
                NodeName = new string(reader.ReadChars(4))
            };
            uint NodeLength = reader.ReadUInt32();

            pos = reader.BaseStream.Position; //Save Position
            uint NodeOffset = reader.ReadUInt32();

            reader.JumpTo(NodeOffset, false);

            uint Unknown1           = reader.ReadUInt32(); //Seems to always be 0 (at least in XN*s)? (Padding?)
            uint EffectTypeCount    = reader.ReadUInt32();
            uint EffectTypeOffset   = reader.ReadUInt32();
            uint TechniqueCount     = reader.ReadUInt32();
            uint TechniqueOffset    = reader.ReadUInt32();
            uint TechniqueIDXCount  = reader.ReadUInt32();
            uint TechniqueIDXOffset = reader.ReadUInt32();

            //Effect Files
            reader.JumpTo(EffectTypeOffset, false);
            for (int i = 0; i < EffectTypeCount; i++)
            {
                NinjaEffectFile EffectFile = new NinjaEffectFile()
                {
                    Type = reader.ReadUInt32()
                };
                uint EffectFilenameOffset = reader.ReadUInt32();
                long currentPos           = reader.BaseStream.Position; //Save Position
                reader.JumpTo(EffectFilenameOffset, false);
                EffectFile.Filename = reader.ReadNullTerminatedString();
                reader.JumpTo(currentPos, true);
                NinjaEffectList.EffectFiles.Add(EffectFile);
            }

            //Effect List
            reader.JumpTo(TechniqueOffset, false);
            for (int i = 0; i < TechniqueCount; i++)
            {
                NinjaEffectTechnique Technique = new NinjaEffectTechnique()
                {
                    Type = reader.ReadUInt32(),
                    ID   = reader.ReadUInt32()
                };
                uint TechniqueNameOffset = reader.ReadUInt32();
                long currentPos          = reader.BaseStream.Position; //Save Position
                reader.JumpTo(TechniqueNameOffset, false);
                Technique.TechniqueName = reader.ReadNullTerminatedString();
                reader.JumpTo(currentPos, true);
                NinjaEffectList.Techniques.Add(Technique);
            }

            //Technique IDX (not sure what this is for)
            reader.JumpTo(TechniqueIDXOffset, false);
            for (int i = 0; i < TechniqueIDXCount; i++)
            {
                NinjaEffectList.TechniqueIDX.Add(reader.ReadUInt16());
            }

            reader.JumpTo(pos, true);
            reader.JumpAhead(NodeLength);
            return(NinjaEffectList);
        }
        public override void Parse(ExtendedBinaryReader br)
        {
            base.Parse(br);

            Version = br.ReadByte();
            Flags = br.ReadUInt24();
            TimeScale = br.ReadUInt32();
            QualityEntryCount = br.ReadByte();
            QualitySegmentUrlModifiers = Enumerable.Range(0, QualityEntryCount).Select(i => br.ReadNullTerminatedString()).ToArray();
            FragmentRunEntryCount = br.ReadUInt32();
            FragmentRunEntryTable = new FragmentRunEntry[FragmentRunEntryCount];
            for (uint i = 0; i < FragmentRunEntryCount; i++)
                FragmentRunEntryTable[i] = FragmentRunEntry.Parse(br);
        }
예제 #17
0
        /*
         * public TypeTree(TypeTree parent, uint format, int version, bool isArray, int size, int index, int flags, string type, string name)
         * {
         *  this.parent = parent;
         *  this.format = format;
         *
         *  this.version = version;
         *  this.isArray = isArray;
         *  this.size = size;
         *  this.index = index;
         *  this.flags = flags;
         *  this.type = type;
         *  this.name = name;
         * }
         */

        public static TypeTreeNode ReadTypeTree(uint format, ExtendedBinaryReader buf)
        {
            TypeTreeNode root = new TypeTreeNode();

            if (format == 10 || format >= 12)
            {
                int nodesCount        = buf.ReadInt32();
                int stringBufferBytes = buf.ReadInt32();

                int nodesize = format >= 19 ? 32 : 24;

                buf.BaseStream.Seek(nodesize * nodesCount, SeekOrigin.Current);
                byte[] stringData = buf.ReadBytes(stringBufferBytes);
                buf.BaseStream.Seek(-(nodesize * nodesCount + stringBufferBytes), SeekOrigin.Current);

                Stack <TypeTreeNode> stack = new Stack <TypeTreeNode>();

                stack.Push(root);

                using (var stringReader = new ExtendedBinaryReader(new MemoryStream(stringData)))
                {
                    for (int i = 0; i < nodesCount; i++)
                    {
                        short version = buf.ReadInt16();
                        byte  depth   = buf.ReadByte();

                        bool isArray = buf.ReadBoolean();

                        ushort typeIndex = buf.ReadUInt16();
                        string typeStr;
                        if (buf.ReadUInt16() == 0)
                        {
                            stringReader.BaseStream.Position = typeIndex;
                            typeStr = stringReader.ReadNullTerminatedString();
                        }
                        else
                        {
                            typeStr = baseStrings.ContainsKey(typeIndex) ? baseStrings[typeIndex] : typeIndex.ToString();
                        }

                        ushort nameIndex = buf.ReadUInt16();
                        string nameStr;
                        if (buf.ReadUInt16() == 0)
                        {
                            stringReader.BaseStream.Position = nameIndex;
                            nameStr = stringReader.ReadNullTerminatedString();
                        }
                        else
                        {
                            nameStr = baseStrings.ContainsKey(nameIndex) ? baseStrings[nameIndex] : nameIndex.ToString();
                        }

                        int   size        = buf.ReadInt32();
                        int   index       = buf.ReadInt32();
                        int   flags       = buf.ReadInt32();
                        ulong refTypeHash = 0;

                        if (format >= 19)
                        {
                            refTypeHash = buf.ReadUInt64();
                        }

                        TypeTreeNode t;
                        if (depth == 0)
                        {
                            t = root;
                        }
                        else
                        {
                            while (stack.Count > depth)
                            {
                                stack.Pop();
                            }
                            t = new TypeTreeNode();
                            stack.Peek().children.Add(t);
                            stack.Push(t);
                        }

                        t.version     = version;
                        t.isArray     = isArray;
                        t.type        = typeStr;
                        t.name        = nameStr;
                        t.size        = size;
                        t.index       = index;
                        t.flags       = flags;
                        t.refTypeHash = refTypeHash;
                    }
                }

                buf.BaseStream.Seek(stringBufferBytes, SeekOrigin.Current);
            }
            else
            {
                root.type    = buf.ReadNullTerminatedString();
                root.name    = buf.ReadNullTerminatedString();
                root.size    = buf.ReadInt32();
                root.index   = buf.ReadInt32();
                root.isArray = buf.ReadBoolean();
                root.version = buf.ReadInt32();
                root.flags   = buf.ReadInt32();

                int childCount = buf.ReadInt32();
                for (int i = 0; i < childCount; i++)
                {
                    root.children.Add(TypeTreeNode.ReadTypeTree(format, buf));
                }
            }

            return(root);
        }
예제 #18
0
        public override void Load(Stream fileStream)
        {
            // Header
            var reader  = new ExtendedBinaryReader(fileStream, true);
            var entries = new List <FileEntry>();

            uint sig = reader.ReadUInt32();

            if (sig != Signature)
            {
                throw new InvalidSignatureException(
                          Signature.ToString("X"), sig.ToString("X"));
            }

            uint fileTableOffset = reader.ReadUInt32();
            uint fileTableLength = reader.ReadUInt32();
            uint fileDataOffset  = reader.ReadUInt32();
            uint unknown5        = reader.ReadUInt32();
            uint unknown6        = reader.ReadUInt32();
            uint unknown7        = reader.ReadUInt32();
            uint unknown8        = reader.ReadUInt32();

            // File/Directory Entries
            long fileTableEnd = (fileTableOffset + fileTableLength);

            reader.JumpTo(fileTableOffset);

            while (fileStream.Position < fileTableEnd)
            {
                bool isDirectory = reader.ReadBoolean();
                byte padding1    = reader.ReadByte();

                if (padding1 != 0)
                {
                    fileStream.Position -= 2; // go bacc
                    break;
                }

                var fileEntry = new FileEntry()
                {
                    IsDirectory          = isDirectory,
                    FileNameOffset       = reader.ReadUInt16(),
                    DataOffset           = reader.ReadUInt32(),
                    DataLength           = reader.ReadUInt32(),
                    DataUncompressedSize = reader.ReadUInt32()
                };

                entries.Add(fileEntry);
            }

            // Entry Names
            uint fileNamesOffset = (uint)fileStream.Position;

            foreach (var entry in entries)
            {
                reader.JumpTo(fileNamesOffset + entry.FileNameOffset);
                entry.Name = reader.ReadNullTerminatedString();
            }

            // Entry Data
            ArchiveDirectory dir = null;

            for (int i = 0; i < entries.Count; ++i)
            {
                var entry = entries[i];

                // Directory
                if (entry.IsDirectory)
                {
                    // Generate a HedgeLib directory entry
                    if (i == 0)
                    {
                        continue;
                    }

                    if (entry.DataOffset >= i)
                    {
                        throw new Exception("Entry DataOffset is invalid");
                    }

                    var dirEntry = new ArchiveDirectory(entry.Name);
                    if (entry.DataOffset != 0)
                    {
                        var parentEntry = entries[(int)entry.DataOffset];
                        dirEntry.Parent = parentEntry.Directory;
                    }

                    if (dirEntry.Parent == null)
                    {
                        Data.Add(dirEntry);
                    }
                    else
                    {
                        dirEntry.Parent.Data.Add(dirEntry);
                    }

                    dir = entry.Directory = dirEntry;
                }

                // File
                else
                {
                    if (dir == null)
                    {
                        throw new Exception("Tried to read a file not in a directory!");
                    }

                    var data = new byte[entry.DataUncompressedSize];
                    int offset = 0, size = (int)entry.DataUncompressedSize;
                    reader.JumpTo(entry.DataOffset + 2);

                    using (var gzipStream = new DeflateStream(fileStream,
                                                              CompressionMode.Decompress, true))
                    {
                        while (offset < size)
                        {
                            offset += gzipStream.Read(data,
                                                      offset, (size - offset));
                        }
                    }

                    // Generate a HedgeLib file entry
                    dir.Data.Add(new ArchiveFile(entry.Name, data));
                }
            }
        }
예제 #19
0
        private static SetObject ReadObject(ExtendedBinaryReader reader,
                                            SetObjectType objTemplate, string objType, SOBJType type,
                                            bool rawDataMode = false) // true = full, false = only remaining bytes
        {
            // For some reason these separate values are saved as one uint rather than two ushorts.
            // Because of this, the values are in a different order depending on endianness, and
            // this is the easiest known way to read them.
            uint   unknownValue = reader.ReadUInt32();
            ushort unknown1     = (ushort)((unknownValue >> 16) & 0xFFFF);
            ushort objID        = (ushort)(unknownValue & 0xFFFF);

            var obj = new SetObject()
            {
                ObjectType = objType,
                ObjectID   = objID
            };

            uint  unknown2 = reader.ReadUInt32();
            uint  unknown3 = reader.ReadUInt32();
            float unknown4 = reader.ReadSingle();

            float rangeIn          = reader.ReadSingle();
            float rangeOut         = reader.ReadSingle();
            uint  parent           = (type == SOBJType.LostWorld) ? reader.ReadUInt32() : 0;
            uint  transformsOffset = reader.ReadUInt32();

            uint transformCount = reader.ReadUInt32();
            uint unknown5       = reader.ReadUInt32();
            uint unknown6       = (type == SOBJType.LostWorld) ? reader.ReadUInt32() : 0;
            uint unknown7       = (type == SOBJType.LostWorld) ? reader.ReadUInt32() : 0;

            // Call me crazy, but I have a weird feeling these values aren't JUST padding
            if (unknown3 != 0 || unknown5 != 0 || unknown6 != 0 || unknown7 != 0)
            {
                Console.WriteLine("WARNING: Not padding?! ({0},{1},{2},{3})",
                                  unknown3, unknown5, unknown6, unknown7);
            }

            // Add custom data to object
            obj.CustomData.Add("Unknown1", new SetObjectParam(typeof(ushort), unknown1));
            obj.CustomData.Add("Unknown2", new SetObjectParam(typeof(uint), unknown2));
            obj.CustomData.Add("Unknown3", new SetObjectParam(typeof(uint), unknown3));
            obj.CustomData.Add("Unknown4", new SetObjectParam(typeof(float), unknown4));
            obj.CustomData.Add("RangeIn", new SetObjectParam(typeof(float), rangeIn));
            obj.CustomData.Add("RangeOut", new SetObjectParam(typeof(float), rangeOut));

            if (type == SOBJType.LostWorld)
            {
                obj.CustomData.Add("Parent", new SetObjectParam(typeof(uint), parent));
            }

            // Skip loading parameters if template doesn't exist
            if (objTemplate != null)
            {
                // Get Raw Byte Length
                var  rawDataLenExtra = objTemplate.GetExtra("RawByteLength");
                long paramBegin      = reader.BaseStream.Position;
                int  rawLength       = 0;

                if (rawDataLenExtra != null &&
                    !string.IsNullOrEmpty(rawDataLenExtra.Value))
                {
                    int.TryParse(rawDataLenExtra.Value, out rawLength);
                }

                // Read all the data then return to beginning
                if (rawDataMode == true && rawLength != 0)
                {
                    obj.CustomData.Add("RawParamData", new SetObjectParam(typeof(byte[]),
                                                                          reader.ReadBytes(rawLength)));
                    reader.JumpTo(paramBegin);
                }

                // Parameters
                foreach (var param in objTemplate.Parameters)
                {
                    // For compatibility with SonicGlvl templates.
                    if (param.Name == "Unknown1" || param.Name == "Unknown2" ||
                        param.Name == "Unknown3" || param.Name == "RangeIn" ||
                        param.Name == "RangeOut" || param.Name == "Parent")
                    {
                        continue;
                    }

                    // Read Special Types/Fix Padding
                    if (param.DataType == typeof(uint[]))
                    {
                        // Data Info
                        reader.FixPadding(4);
                        uint arrOffset  = reader.ReadUInt32();
                        uint arrLength  = reader.ReadUInt32();
                        uint arrUnknown = reader.ReadUInt32();
                        long curPos     = reader.BaseStream.Position;

                        // Data
                        var arr = new uint[arrLength];
                        reader.JumpTo(arrOffset, false);

                        for (uint i = 0; i < arrLength; ++i)
                        {
                            arr[i] = reader.ReadUInt32();
                        }

                        obj.Parameters.Add(new SetObjectParam(param.DataType, arr));
                        reader.BaseStream.Position = curPos;
                        continue;
                    }
                    else if (param.DataType == typeof(string))
                    {
                        // Data Info
                        uint   strOffset  = reader.ReadUInt32();
                        uint   strUnknown = reader.ReadUInt32();
                        string str        = null;

                        // Data
                        if (strOffset != 0)
                        {
                            long curPos = reader.BaseStream.Position;
                            reader.JumpTo(strOffset, false);

                            str = reader.ReadNullTerminatedString();
                            reader.BaseStream.Position = curPos;
                        }

                        obj.Parameters.Add(new SetObjectParam(param.DataType, str));
                        continue;
                    }
                    else if (param.DataType == typeof(float) ||
                             param.DataType == typeof(int) || param.DataType == typeof(uint))
                    {
                        reader.FixPadding(4);
                    }
                    else if (type == SOBJType.LostWorld && param.DataType == typeof(Vector3))
                    {
                        reader.FixPadding(16);
                    }

                    // Read Data
                    var objParam = new SetObjectParam(param.DataType,
                                                      reader.ReadByType(param.DataType));
                    obj.Parameters.Add(objParam);
                }

                if (rawDataMode == false)
                {
                    long knownParamLength = (reader.BaseStream.Position - paramBegin);
                    long remainingBytes   = (rawLength - knownParamLength);

                    obj.CustomData.Add("RawParamData", new SetObjectParam(typeof(byte[]),
                                                                          reader.ReadBytes((int)remainingBytes)));
                }
            }

            // Transforms
            uint childCount = transformCount - 1;

            obj.Children = new SetObjectTransform[childCount];
            reader.JumpTo(transformsOffset, false);

            obj.Transform = ReadTransform(reader, type == SOBJType.LostWorld);
            for (uint i = 0; i < childCount; ++i)
            {
                obj.Children[i] = ReadTransform(reader,
                                                type == SOBJType.LostWorld);
            }

            return(obj);
        }
예제 #20
0
        public const uint TAGMagic = 0x30474154; // "TAG0" in little-endian

        // Methods
        public static void Read(HavokFile h, ExtendedBinaryReader reader)
        {
            var  fs     = reader.BaseStream;
            long pos    = fs.Position;
            long endPos = pos;

            var types = new List <string>();

            reader.IsBigEndian = true;
            while (pos < fs.Length)
            {
                uint   size    = reader.ReadUInt32();
                string type    = new string(reader.ReadChars(4));
                bool   isParam = (((size & 0xC0000000) >> 24) == 0x40);

                // Remove the param marker from the beginning of the size
                if (isParam)
                {
                    size &= 0xFFFFFF;
                }

                size  -= 8;
                pos    = fs.Position;
                endPos = pos + size;

                Console.WriteLine("{0}: \"{1}\"",
                                  (isParam) ? "Parameter" : "Section",
                                  type);

                // Read based on type
                switch (type)
                {
                // SDK Version
                case "SDKV":
                    h.ContentsVersion = new string(reader.ReadChars((int)size));
                    Console.WriteLine($"Contents Version: {h.ContentsVersion}");
                    break;

                case "DATA":
                    ReadDATASection();
                    break;

                // Type Strings
                case "TSTR":
                {
                    Console.WriteLine();
                    while (fs.Position < endPos)
                    {
                        string t = reader.ReadNullTerminatedString();
                        if (string.IsNullOrEmpty(t))
                        {
                            continue;
                        }

                        Console.WriteLine(t);
                        types.Add(t);
                        // TODO
                    }
                    Console.WriteLine();
                    break;
                }

                // Type Names (??)
                case "TNAM":
                {
                    uint unknown1 = reader.ReadUInt32();
                    // TODO
                    break;
                }

                // Format Strings
                case "FSTR":
                {
                    Console.WriteLine();
                    while (fs.Position < endPos)
                    {
                        string t = reader.ReadNullTerminatedString();
                        if (string.IsNullOrEmpty(t))
                        {
                            continue;
                        }

                        Console.WriteLine(t);
                        // TODO
                    }
                    Console.WriteLine();
                    // TODO
                    break;
                }
                }

                // TODO

                // Jump ahead to the next parameter
                if (isParam)
                {
                    pos = endPos;

                    if (fs.Position != pos)
                    {
                        reader.JumpTo(pos);
                    }
                }
            }

            // Sub-Methods
            //HavokSection ReadSection()
            //{
            //    var section = new HavokSection();
            //    // TODO
            //    return section;
            //}

            void ReadDATASection()
            {
                reader.IsBigEndian = false; // TODO

                ulong unknown1 = reader.ReadUInt64();
                ulong unknown2 = reader.ReadUInt64();
                ulong unknown3 = reader.ReadUInt64();
                ulong unknown4 = reader.ReadUInt64();
                ulong unknown5 = reader.ReadUInt64();

                for (uint i = 0; i < unknown1; ++i)
                {
                    string s = reader.ReadNullTerminatedString();
                    Console.WriteLine(s);
                }
                // TODO

                // Padding Checks
                if (unknown2 != 0)
                {
                    Console.WriteLine($"WARNING: DATA Unknown2 != 0 ({unknown2})");
                }

                reader.IsBigEndian = true; // TODO
            }
        }
 public static ServerEntry Parse(ExtendedBinaryReader br)
 {
     return new ServerEntry
     {
         ServerBaseURL = br.ReadNullTerminatedString()
     };
 }
        public override void Parse(ExtendedBinaryReader br)
        {
            base.Parse(br);

            Version = br.ReadByte();
            Flags = br.ReadUInt24();
            BootstrapinfoVersion = br.ReadUInt32();
            var b = br.ReadByte();
            Profile = (new byte[] { 0x80, 0x40 }).Select(i => (i & b) != 0).ToArray();
            Live = (0x02 & b) != 0;
            Update = (0x01 & b) != 0;
            Reserved = (new byte[] { 0x08, 0x04, 0x02, 0x01 }).Select(i => (i & b) != 0).ToArray();
            TimeScale = br.ReadUInt32();
            CurrentMediaTime = br.ReadUInt64();
            SmpteTimeCodeOffset = br.ReadUInt64();
            MovieIdentifier = br.ReadNullTerminatedString();
            ServerEntryCount = br.ReadByte();
            ServerEntryTable = new ServerEntry[ServerEntryCount];
            for (int i = 0; i < ServerEntryCount; i++)
                ServerEntryTable[i] = ServerEntry.Parse(br);
            QualityEntryCount = br.ReadByte();
            QualityEntryTable = new QualityEntry[QualityEntryCount];
            for (int i = 0; i < QualityEntryCount; i++)
                QualityEntryTable[i] = QualityEntry.Parse(br);
            DrmData = br.ReadNullTerminatedString();
            MetaData = br.ReadNullTerminatedString();
            SegmentRunTableCount = br.ReadByte();
            SegmentRunTableEntries = new SegmentRunTableBox[SegmentRunTableCount];
            for (int i = 0; i < SegmentRunTableCount; i++)
            {
                SegmentRunTableEntries[i] = new SegmentRunTableBox();
                SegmentRunTableEntries[i].Parse(br);
            }
            FragmentRunTableCount = br.ReadByte();
            FragmentRunTableEntries = new FragmentRunTableBox[FragmentRunTableCount];
            for (int i = 0; i < FragmentRunTableCount; i++)
            {
                FragmentRunTableEntries[i] = new FragmentRunTableBox();
                FragmentRunTableEntries[i].Parse(br);
            }
        }
 public static QualityEntry Parse(ExtendedBinaryReader br)
 {
     return new QualityEntry
     {
         QualitySegmentUrlModifier = br.ReadNullTerminatedString()
     };
 }
예제 #24
0
        private AssetsFile(string path)
        {
            this.path = path;

            buf      = new ExtendedBinaryReader(File.OpenRead(path));
            basepath = Path.GetDirectoryName(path);

            buf.endian = EndianType.BigEndian;

            metadata_size = buf.ReadUInt32();
            file_size     = buf.ReadUInt32();
            format        = buf.ReadUInt32();
            data_offset   = buf.ReadUInt32();

            if (format >= 9 && buf.ReadUInt32() == 0)
            {
                fileEndianType = EndianType.LittleEndian;
            }

            if (format >= 22)
            {
                metadata_size = buf.ReadUInt32();
                file_size     = buf.ReadInt64();
                data_offset   = buf.ReadInt64();
                buf.BaseStream.Seek(8, SeekOrigin.Current); // Unknown value
            }

            buf.endian = fileEndianType;

            string versionString = buf.ReadNullTerminatedString();

            versionString = versionString.Replace('p', '.');
            versionString = versionString.Replace('f', '.');

            version = new Version(versionString);

            platform = buf.ReadInt32();

            buf.endian = EndianType.LittleEndian;

            typeMetaData = new TypeMetaData(format, buf);

            if (format >= 7 && format < 14)
            {
                longObjectIDs = buf.ReadInt32() != 0;
            }

            // Read obejct info table
            int objectCount = buf.ReadInt32();

            // Save position for saving file
            objectsIndexOffset = buf.Position;

            var assetsDict = new Dictionary <long, AssetInfo>(objectCount);

            for (int i = 0; i < objectCount; i++)
            {
                var assetInfo = new AssetInfo();

                assetInfo.asset = this;

                assetInfo.pathID     = ReadPathID();
                assetInfo.dataOffset = format >= 22 ? buf.ReadInt64() : buf.ReadUInt32();
                assetInfo.size       = buf.ReadUInt32();
                assetInfo.typeID     = buf.ReadInt32();

                if (format < 16)
                {
                    assetInfo.classID = buf.ReadUInt16();
                }
                else
                {
                    assetInfo.classID = typeMetaData.ClassIDs[assetInfo.typeID].classID;
                }

                if (format < 16)
                {
                    assetInfo.isDestroyed = buf.ReadUInt16() != 0;
                }

                if (format == 15 || format == 16)
                {
                    assetInfo.stripped = buf.ReadByte();
                }

                assetsDict.Add(assetInfo.pathID, assetInfo);
            }

            assets = assetsDict;


            if (format >= 11)
            {
                int scriptCount = buf.ReadInt32();
                scriptTypes = new List <ScriptType>(scriptCount);
                for (int i = 0; i < scriptCount; i++)
                {
                    var add = new ScriptType
                    {
                        index = buf.ReadInt32(),
                        ID    = ReadPathID()
                    };
                    scriptTypes.Add(add);
                }
            }

            if (format >= 6)
            {
                int referenceCount = buf.ReadInt32();
                references = new List <AssetReference>(referenceCount);
                for (int i = 0; i < referenceCount; i++)
                {
                    references.Add(AssetReference.Read(buf));
                }
            }
        }