예제 #1
0
            public Stream OpenItem(string id)
            {
                EnsureLoaded();

                var item = _items[id];

                return(_bspFile.GetSubStream(item.FileOffset, item.FileLength));
            }
예제 #2
0
            public Stream OpenItem(string id)
            {
                EnsureLoaded();

                var item = _items[id];

                // Find index of current lump
                var keyArray = _items.Keys.ToArray();
                int index    = -1;

                for (int i = 0; i < keyArray.Length; i++)
                {
                    if (keyArray[i] == id)
                    {
                        index = i;
                        break;
                    }
                }

                // https://developer.valvesoftware.com/wiki/Source_BSP_File_Format#Lump_compression
                // Get the actual length of the item using offset of the next item.
                var valueArray   = _items.Values.ToArray();
                var actualLength = item.FileLength;

                if (index != -1)
                {
                    if (index < _items.Count - 1)
                    {
                        // The last game lump is /supposed/ to be a dummy containing nothing but the offset,
                        // but sometimes the offset is 0 which would result in negative actualLength.
                        if (valueArray[index + 1].FileOffset > valueArray[index].FileOffset)
                        {
                            actualLength = valueArray[index + 1].FileOffset - valueArray[index].FileOffset;
                        }
                    }
                }

                var stream = _bspFile.GetSubStream(item.FileOffset, actualLength);

                LzmaHeader lzmaHeader;

                try
                {
                    lzmaHeader = LzmaHeader.Read(stream);
                }
                catch (NotSupportedException e)
                {
                    stream.Seek(0, SeekOrigin.Begin);
                    return(stream);
                }

                using (var compressedStream =
                           _bspFile.GetSubStream(item.FileOffset + LzmaHeader.Size, lzmaHeader.LzmaSize))
                {
                    using (var uncompressedStream = new MemoryStream(( int )lzmaHeader.ActualSize))
                    {
                        Decoder decoder = new Decoder();
                        decoder.SetDecoderProperties(lzmaHeader.Properties);
                        decoder.Code(compressedStream, uncompressedStream, lzmaHeader.LzmaSize,
                                     lzmaHeader.ActualSize, null);
                        stream = new MemoryStream(( int )stream.Length);
                        uncompressedStream.Seek(0, SeekOrigin.Begin);
                        uncompressedStream.CopyTo(stream);
                    }
                }

                stream.Seek(0, SeekOrigin.Begin);
                return(stream);
            }