Exemple #1
0
        /// <summary>
        /// Read an HTEX file into memory.
        /// </summary>
        /// <param name="input">A readable stream of an HTEX file.</param>
        public HTEX(Stream input)
        {
            using (var br = new BinaryReaderX(input))
            {
                // Packet Header
                _packetHeader = br.ReadType <PacketHeaderX>();

                // HTSF Packet Header
                _htsfPacketHeader = br.ReadType <PacketHeaderX>();

                // HTSF Header
                _htsfHeader = br.ReadType <HtsfHeader>();

                var bytes = br.ReadBytes(_htsfPacketHeader.DataSize - Common.PacketHeaderXSize);
                ImageStream = new MemoryStream(bytes);

                //if (input is FileStream stream && !File.Exists(Path.ChangeExtension(stream.Name, "gim")))
                //    File.WriteAllBytes(Path.ChangeExtension(stream.Name, "gim"), bytes);

                // Footers
                _htsfFooter = br.ReadType <PacketHeaderX>();
                _htexFooter = br.ReadType <PacketHeaderX>();
            }
        }
Exemple #2
0
        /// <summary>
        /// Read an MXEN file into memory.
        /// </summary>
        /// <param name="input">A readable stream of an MXEN file.</param>
        public MXEN(Stream input)
        {
            using (var br = new BinaryReaderX(input))
            {
                // Packet Header
                _packetHeader = br.ReadType <PacketHeaderX>();

                // MXEC Packet Header
                _mxecPacketHeader = br.ReadType <PacketHeaderX>();

                // Rolling XOR Encryption
                Stream ss;
                if (_mxecPacketHeader.Flags3 == 0x0C)
                {
                    var bytes = br.ReadBytes(_mxecPacketHeader.DataSize);
                    var b     = _xorKey = bytes[0];
                    ss = new MemoryStream {
                        Capacity = _mxecPacketHeader.DataSize
                    };

                    using (var bw = new BinaryWriterX(ss, true))
                    {
                        bw.Write((byte)0x01);
                        for (var i = 1; i < bytes.Length; i++)
                        {
                            var bs = bytes[i];
                            bw.Write((byte)(bs ^ b));
                            b = bs;
                        }
                    }

                    ss.Position = 0;
                }
                else
                {
                    ss = new SubStream(input, br.BaseStream.Position, _mxecPacketHeader.DataSize);
                }

                // Table1 Binary Reader
                var bbr = new BinaryReaderX(ss);

                // MXEC Header
                _mxecHeader = bbr.ReadType <MXECHeader>();

                // Unsupported Tables
                if (_mxecHeader.Table2Offset > 0)
                {
                    throw new Exception("Table2 is not supported by this plugin.");
                }
                if (_mxecHeader.Table4Offset > 0)
                {
                    throw new Exception("Table4 is not supported by this plugin.");
                }
                if (_mxecHeader.Table6Offset > 0)
                {
                    throw new Exception("Table6 is not supported by this plugin.");
                }

                // Table1 Metadata
                _table1Metadata = bbr.ReadMultiple <Table1Metadata>(_mxecHeader.Table1Count);
                _table1Objects  = new List <Table1Object>();

                // Table1
                foreach (var metadata in _table1Metadata)
                {
                    var obj = new Table1Object {
                        Metadata = metadata
                    };
                    _table1Objects.Add(obj);

                    bbr.BaseStream.Position = metadata.TypeOffset - Common.PacketHeaderXSize;
                    obj.Type = bbr.ReadCStringSJIS();

                    bbr.BaseStream.Position = metadata.DataOffset - Common.PacketHeaderXSize;
                    obj.Data = bbr.ReadBytes(metadata.DataSize);
                }

                bbr.SeekAlignment();

                // Text
                var textStart = bbr.BaseStream.Position;
                var textEnd   = _mxecPacketHeader.DataSize;

                _textEntries = new List <Table1TextEntry>();
                while (true)
                {
                    var entry = new Table1TextEntry {
                        Offset = (int)bbr.BaseStream.Position
                    };
                    var text = bbr.ReadCStringSJIS();
                    if (text == "" && _textEntries.Count > 0)
                    {
                        break;
                    }
                    entry.Text = text;
                    _textEntries.Add(entry);
                    if (bbr.BaseStream.Position >= textEnd)
                    {
                        break;
                    }
                }

                bbr.SeekAlignment();

                _editableTexts = new Dictionary <int, string>();
                foreach (var entry in _table1Objects)
                {
                    entry.TypeIndex = _textEntries.IndexOf(_textEntries.FirstOrDefault(t => t.Offset == entry.Metadata.TypeOffset - Common.PacketHeaderXSize));

                    for (var i = 0; i < entry.Data.Length / 4; i++)
                    {
                        var val = BitConverter.ToInt32(entry.Data, i * 4) - Common.PacketHeaderXSize;

                        if (val >= textStart && val <= textEnd)
                        {
                            var index = _textEntries.IndexOf(_textEntries.FirstOrDefault(t => t.Offset == val));
                            if (index <= -1)
                            {
                                continue;
                            }

                            entry.Texts.Add(new Table1ObjectText
                            {
                                DataOffset = i * 4,
                                TextIndex  = index
                            });

                            if (!_editableTexts.ContainsKey(val))
                            {
                                _editableTexts.Add(val, entry.Type);
                            }
                            else if (!_editableTexts[val].Contains(entry.Type))
                            {
                                _editableTexts[val] += ", " + entry.Type;
                            }
                        }
                    }
                }

                var id = 1;
                foreach (var entry in _textEntries)
                {
                    if (!_editableTexts.ContainsKey(entry.Offset))
                    {
                        continue;
                    }
                    entry.ID = id;
                    Entries.Add(new TextEntry
                    {
                        Name       = entry.ID.ToString(),
                        EditedText = entry.Text,
                        Notes      = _editableTexts[entry.Offset]
                    });
                    id++;
                }

                // Reset Stream
                br.BaseStream.Position = Common.PacketHeaderXSize * 2 + _mxecPacketHeader.DataSize;

                // POF0
                _pof0     = br.ReadType <PacketHeaderX>();
                _pof0Data = br.ReadBytes(_pof0.DataSize);

                // ENRS
                _enrs     = br.ReadType <PacketHeaderX>();
                _enrsData = br.ReadBytes(_enrs.DataSize);

                // CCRS
                _ccrs     = br.ReadType <PacketHeaderX>();
                _ccrsData = br.ReadBytes(_ccrs.DataSize);

                // Footers
                _ccrsFooter = br.ReadType <PacketHeaderX>();
                _mxecFooter = br.ReadType <PacketHeaderX>();
                _mxenFooter = br.ReadType <PacketHeaderX>();
            }
        }
Exemple #3
0
        /// <summary>
        /// Read an MTPA file into memory.
        /// </summary>
        /// <param name="input">A readable stream of an MTPA file.</param>
        public MTPA(Stream input)
        {
            using (var br = new BinaryReaderX(input))
            {
                // Packet Header
                _packetHeader = br.ReadType <PacketHeaderX>();

                // MTPA Header
                _mtpaHeader = br.ReadType <MTPAHeader>();
                var metadataSize = _mtpaHeader.MetadataSize;

                // Unknown MTPA Data
                _mtpaHeaderData = br.ReadMultiple <int>(_mtpaHeader.MetadataSize);

                // Text Metadata Pointers
                _mtpaTextMetadataPointers = br.ReadMultiple <int>(_mtpaHeader.PointerCount);

                // Text Metadata
                if (metadataSize == 2)
                {
                    _mtpaTextMetadata = br.ReadMultiple <TextMetadata>(_mtpaHeader.MetadataCount).ToList <ITextMetadata>();
                }
                else if (metadataSize == 4)
                {
                    _mtpaTextMetadata = br.ReadMultiple <TextMetadataX>(_mtpaHeader.MetadataCount).ToList <ITextMetadata>();
                }

                // Text
                var textStart = (int)br.BaseStream.Position;
                var textEnd   = _packetHeader.DataSize + _packetHeader.HeaderSize;

                for (var i = 0; i < _mtpaHeader.MetadataCount; i++)
                {
                    var offset = textStart;
                    var unused = false;

                    offset += _mtpaTextMetadata[i].Offset;

                    br.BaseStream.Position = offset;
                    var length = br.ReadROTnInt32();

                    if (length == 0)
                    {
                        var currentOffset = _mtpaTextMetadata[i].Offset;
                        unused = true;

                        if (i != _mtpaHeader.MetadataCount - 1)
                        {
                            length = _mtpaTextMetadata[i + 1].Offset - currentOffset - 4;
                        }
                        else
                        {
                            length = textEnd - currentOffset - 4;
                        }
                    }

                    var str = br.ReadROTnBytes(length);

                    Entries.Add(new TextEntry
                    {
                        Name       = _mtpaTextMetadata[i].ID.ToString(),
                        EditedText = Encoding.GetEncoding("shift-jis").GetString(str).Trim('\0'),
                        Notes      = unused ? "Text length was set to zero. This line might be unused." : string.Empty
                    });
                }

                br.BaseStream.Position = textEnd;

                // ENRS
                _enrs = br.ReadType <PacketHeaderX>();
                if (br.BaseStream.Position + _enrs.DataSize + Common.PacketHeaderXSize * 2 <= br.BaseStream.Length)
                {
                    _enrsData   = br.ReadBytes(_enrs.DataSize);
                    _enrsFooter = br.ReadType <PacketHeaderX>();
                }
                else
                {
                    br.BaseStream.Position = br.BaseStream.Length - Common.PacketHeaderXSize;
                }

                // MTPA Footer
                _mtpaFooter = br.ReadType <PacketHeaderX>();
            }
        }