Esempio n. 1
0
        //Reads a block from the dictionary and decompresses.
        private Stream GetDecompressedDataBlock(IDictionaryData dict, Block block, Stream stream)
        {
            using (var reader = new FileReader(stream, true))
            {
                if (block.Offset > reader.BaseStream.Length || block.DecompressedSize == 0)
                {
                    return(new MemoryStream());
                }

                reader.SeekBegin(block.Offset);
                //Check the dictionary if the files are compressed
                if (dict.BlocksCompressed)
                {
                    //Check the magic to see if it's zlib compression
                    ushort Magic  = reader.ReadUInt16();
                    bool   IsZLIP = Magic == 0x9C78 || Magic == 0xDA78;
                    reader.SeekBegin(block.Offset);

                    if (IsZLIP)
                    {
                        return(new MemoryStream(STLibraryCompression.ZLIB.Decompress(
                                                    reader.ReadBytes((int)block.CompressedSize))));
                    }
                    else //Unknown compression so skip it.
                    {
                        return(new MemoryStream());
                    }
                } //File is decompressed so check if it's in the range of the current data file.
                else if (block.Offset + block.DecompressedSize <= reader.BaseStream.Length)
                {
                    return(new SubStream(reader.BaseStream, block.Offset, block.DecompressedSize));
                }
            }
            return(new MemoryStream());
        }
Esempio n. 2
0
        public string GetReportByDictionaryMetadata(
            IDictionaryMetadata rightHeaderDictionaryMetadata,
            IDictionaryMetadata topHeaderDictionaryMetadata,
            IDictionaryData rightHeaderDictionary,
            IDictionaryData topHeaderDictionary)
        {
            var sb = new StringBuilder();

            sb.Append("<table border=\"1\">");

            var rightHeaderFirstRow = rightHeaderDictionary.Rows.First();
            var topHeaderFirstRow   = topHeaderDictionary.Rows.First();

            // Displaying top header rows.
            for (int i = 0; i < topHeaderFirstRow.Items.Count; i++)
            {
                sb.Append("<tr>");
                for (int j = 0; j < rightHeaderFirstRow.Items.Count; j++)
                {
                    sb.Append($"<td></td>");
                }
                foreach (DictionaryRow topRow in topHeaderDictionary.Rows)
                {
                    sb.Append($"<td>{topRow.Items[i]}</td>");
                }
                sb.Append("</tr>");
            }

            var dataService = new DataService();

            // Displaying right header rows and data.
            foreach (DictionaryRow rightHeaderRow in rightHeaderDictionary.Rows)
            {
                sb.Append("<tr>");
                foreach (var item in rightHeaderRow.Items)
                {
                    sb.Append($"<td>{item}</td>");
                }
                foreach (DictionaryRow topHeaderRow in topHeaderDictionary.Rows)
                {
                    sb.Append($"<td>");
                    // Getting data from IDataService.
                    sb.Append(dataService.GetIntersectionData(
                                  rightHeaderDictionaryMetadata.Id,
                                  topHeaderDictionaryMetadata.Id,
                                  rightHeaderDictionary.Rows.IndexOf(rightHeaderRow) + 1,
                                  topHeaderDictionary.Rows.IndexOf(topHeaderRow) + 1
                                  ));
                    sb.Append($"</td>");
                }
                sb.Append("</tr>");
            }
            return(sb.ToString());
        }
        public static object Parse(Type t, object data, Action <object, object> onParseItem = null)
        {
            if (!typeof(IData).IsAssignableFrom(t))
            {
                return(null);
            }

            Type            instanceType = typeof(DictionaryData <>).MakeGenericType(t);
            IDictionaryData obj          = (IDictionaryData)Activator.CreateInstance(instanceType);

            obj.ParseObject(data, onParseItem);
            return(obj);
        }
Esempio n. 4
0
        public void Load(Stream stream)
        {
            _stream = stream;
            using (var reader = new FileReader(stream, true)) {
                reader.SetByteOrder(true);
                reader.SeekBegin(12);
                if (reader.ReadUInt32() == 0x78340300)
                {
                    Version = GameVersion.LM3;
                }
            }

            Tag = this;

            //Parse dictionary
            if (Version == GameVersion.LM3)
            {
                DictFile = new LM3.DICT_Parser(stream);
            }
            else
            {
                DictFile = new LM2.DICT_Parser(stream);
            }
            this.Label = FileInfo.FileName;

            DictFile.FilePath = FileInfo.FilePath;

            //Parse seperate data file
            string dataPath = FileInfo.FilePath.Replace(".dict", ".data");

            if (File.Exists(dataPath))
            {
                _dataStream = File.OpenRead(dataPath);
                DataFile    = new DATA_Parser(_dataStream, Version, DictFile);

                var root = LoadChunkTabe();
                Children.AddRange(root.Children);

                int index = 0;

                var subNode = new ObjectTreeNode("Data Entries");
                AddChild(subNode);
                foreach (var child in DataFile.Table.DataEntries)
                {
                    subNode.AddChild(ReadChunk(child));
                }
            }
        }
        public static Stream LoadDumpedBlocks(IDictionaryData dict, List <Block> blocks, Stream stream, int index)
        {
            var block = blocks[index];

            var fileName   = Path.GetFileNameWithoutExtension(dict.FilePath);
            var folderPath = Path.GetDirectoryName(dict.FilePath);
            var dir        = Path.Combine(folderPath, fileName, "File_Data");

            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }

            if (!File.Exists($"{dir}/{fileName}_{index}.lm3"))
            {
                GetDecompressedDataBlock(dict, block, stream).SaveToFile($"{dir}/{fileName}_{index}.lm3");
            }

            return(new FileStream($"{dir}/{fileName}_{index}.lm3", FileMode.Open, FileAccess.Read));
        }
Esempio n. 6
0
        public DATA_Parser(Stream stream, DICT.GameVersion version, IDictionaryData dict)
        {
            Version    = version;
            Dictionary = dict;

            foreach (var block in dict.BlockList)
            {
                block.DataParser = this;

                uint size = dict.BlocksCompressed ? block.CompressedSize : block.DecompressedSize;
                //Some cases the block sizes are too big?
                if (block.Offset + size > stream.Length)
                {
                    continue;
                }

                block.Dictionary     = dict;
                block.CompressedData = new SubStream(stream, block.Offset, size);
            }

            var blocks = dict.BlockList.ToList();

            Stream[] blockList = new Stream[100];
            if (version == DICT.GameVersion.LM3)
            {
                blockList[0]  = DataCompressionCache.LoadDumpedBlocks(dict, blocks, stream, 0);
                blockList[52] = DataCompressionCache.LoadDumpedBlocks(dict, blocks, stream, 52);
                blockList[53] = DataCompressionCache.LoadDumpedBlocks(dict, blocks, stream, 53);
                blockList[54] = DataCompressionCache.LoadDumpedBlocks(dict, blocks, stream, 54);
                blockList[55] = DataCompressionCache.LoadDumpedBlocks(dict, blocks, stream, 55);
                blockList[58] = DataCompressionCache.LoadDumpedBlocks(dict, blocks, stream, 58);

                blockList[63] = DataCompressionCache.LoadDumpedBlocks(dict, blocks, stream, 63);
                blockList[64] = DataCompressionCache.LoadDumpedBlocks(dict, blocks, stream, 64);
                blockList[65] = DataCompressionCache.LoadDumpedBlocks(dict, blocks, stream, 65);
                blockList[68] = DataCompressionCache.LoadDumpedBlocks(dict, blocks, stream, 68);
                blockList[69] = DataCompressionCache.LoadDumpedBlocks(dict, blocks, stream, 69);
            }
            else
            {
                blockList[0] = GetDecompressedDataBlock(dict, blocks[0], stream);
                blockList[2] = GetDecompressedDataBlock(dict, blocks[2], stream);
                blockList[3] = GetDecompressedDataBlock(dict, blocks[3], stream);
            }

            var table = new ChunkTable(blockList[0]);

            Table = table;

            for (int i = 0; i < table.Files.Count; i++)
            {
                var    file            = table.Files[i];
                Stream fileTableBlock  = null;
                Stream fileTableBlock2 = null;

                if (version == DICT.GameVersion.LM3)
                {
                    fileTableBlock  = blockList[52];
                    fileTableBlock2 = blockList[63];
                }
                else
                {
                    fileTableBlock  = blockList[2];
                    fileTableBlock2 = blockList[2];
                }

                if (file.ChunkType == ChunkFileType.Texture)
                {
                    Files.Add(ParseFileHeaders(fileTableBlock2, file));
                }
                else if (file.ChunkType == ChunkFileType.FileTable)
                {
                    Files.Add(ParseFileHeaders(fileTableBlock, file));
                }
                else if (file.ChunkType == ChunkFileType.Script)
                {
                    Files.Add(ParseFileHeaders(fileTableBlock2, file));
                }
                else if (file.ChunkType == ChunkFileType.ClothPhysics)
                {
                    Files.Add(ParseFileHeaders(fileTableBlock2, file));
                }
                else if (file.ChunkType == (ChunkFileType)0x6510)
                {
                    Files.Add(ParseFileHeaders(fileTableBlock2, file));
                }
                else
                {
                    Files.Add(ParseFileHeaders(fileTableBlock, file));
                }

                if (file.SubData.Count == 0)
                {
                    if (version == DICT.GameVersion.LM3)
                    {
                        file.Data = blockList[53];

                        if (file.ChunkType == ChunkFileType.FileTable)
                        {
                            file.Data = blockList[58];
                        }
                        if (file.ChunkType == (ChunkFileType)0x7200)
                        {
                            file.Data = blockList[54];
                        }
                        if (file.ChunkType == (ChunkFileType)0xF000)
                        {
                            file.Data = blockList[69];
                        }
                        if (file.ChunkType == (ChunkFileType)0x4300)
                        {
                            file.Data = blockList[53];
                        }
                        if (file.ChunkType == ChunkFileType.MessageData)
                        {
                            file.Data = blockList[69];
                        }
                    }
                    else
                    {
                        file.Data = blockList[3];
                    }

                    if (file.Data != null && file.Flags3 + file.Flags2 <= file.Data.Length)
                    {
                        file.Data = new SubStream(file.Data, file.Flags3, file.Flags2);
                    }
                }
            }

            foreach (var entry in table.DataEntries)
            {
                if (version == DICT.GameVersion.LM3)
                {
                    if (entry.ChunkType == ChunkDataType.TextureData)
                    {
                        entry.Data = blockList[65];
                    }

                    if (ChunkBlockFlags.ContainsKey(entry.Flags))
                    {
                        var blockType = ChunkBlockFlags[entry.Flags];
                        entry.Data = blockList[blockType];

                        entry.BlockIndex = blockType;
                    }
                    else
                    {
                        continue;
                    }

                    switch (entry.ChunkType)
                    {
                    case (ChunkDataType)0xA201:
                    case (ChunkDataType)0xA202:
                    case (ChunkDataType)0xA203:
                    case (ChunkDataType)0xA204:
                    case (ChunkDataType)0xA205:
                    case (ChunkDataType)0xA206:
                    case (ChunkDataType)0xA207:
                        entry.Data = blockList[64];
                        break;
                    }
                }
                else
                {
                    if (entry.BlockIndex == 0)
                    {
                        entry.Data = blockList[2];
                    }
                    if (entry.BlockIndex == 1)
                    {
                        entry.Data = blockList[3];
                    }
                }

                if (entry.ChunkOffset + entry.ChunkSize <= entry.Data.Length)
                {
                    entry.Data = new SubStream(entry.Data, entry.ChunkOffset, entry.ChunkSize);
                }
            }
        }