Represents a single file or folder within a manifest.
예제 #1
0
            /// <summary>
            /// Downloads a specific file from the Steam servers to the specified Stream.
            /// </summary>
            /// <param name="file">The file to download, given from the manifest.</param>
            /// <param name="downloadStream">The stream to which file data should be written.</param>
            /// <param name="priority">The download priority.</param>
            /// <param name="cryptKey">The AES encryption key used for any encrypted files.</param>
            /// <returns>A byte array representing the file.</returns>
            public void DownloadFileToStream(Steam2Manifest.Node file, Stream downloadStream, DownloadPriority priority = DownloadPriority.Low, byte[] cryptKey = null)
            {
                if ((file.Attributes & Steam2Manifest.Node.Attribs.EncryptedFile) != 0 && cryptKey == null)
                {
                    throw new Steam2Exception(string.Format("AES encryption key required for file: {0}", file.FullName));
                }

                const uint MaxParts = 16;

                uint numFileparts = (uint)Math.Ceiling((float)file.SizeOrCount / (float)file.Parent.BlockSize);
                uint numChunks    = (uint)Math.Ceiling((float)numFileparts / (float)MaxParts);

                for (uint x = 0; x < numChunks; ++x)
                {
                    byte[] filePart = DownloadFileParts(file, x * MaxParts, MaxParts, priority, cryptKey);

                    downloadStream.Write(filePart, 0, filePart.Length);
                }
            }
예제 #2
0
            byte[] DownloadFileParts(Steam2Manifest.Node file, uint filePart, uint numParts, DownloadPriority priority = DownloadPriority.Low, byte[] cryptKey = null)
            {
                this.SendCommand(
                    7, // download file
                    this.StorageID,
                    this.MessageID,
                    file.FileID,
                    filePart,
                    numParts,
                    ( byte )priority
                    );

                uint storId = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32());
                uint msgId  = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32());

                byte hasFile = this.Socket.Reader.ReadByte();

                uint numChunks     = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32());
                uint fileModeValue = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32());

                FileMode fileMode = ( FileMode )fileModeValue;

                MemoryStream ms = new MemoryStream();

                for (int x = 0; x < numChunks; ++x)
                {
                    uint storId2  = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32());
                    uint msgId2   = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32());
                    uint chunkLen = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32());

                    uint storId3   = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32());
                    uint msgId3    = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32());
                    uint chunkLen2 = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32());

                    if (chunkLen == 0)
                    {
                        continue;
                    }

                    byte[] chunk = null;
                    int    len   = 0;

                    if (fileMode == FileMode.Compressed)
                    {
                        chunk = this.Socket.Reader.ReadBytes(( int )chunkLen);
                        len   = DecompressFileChunk(ref chunk, ( int )file.Parent.BlockSize);
                    }
                    else if (fileMode == FileMode.Encrypted)
                    {
                        len = DecryptFileChunk(out chunk, ( int )chunkLen, cryptKey);
                    }
                    else if (fileMode == FileMode.EncryptedAndCompressed)
                    {
                        // Account for 2 integers before the encrypted data
                        chunkLen -= 8;

                        // Skip first integer (length of the encrypted data)
                        this.Socket.Reader.ReadInt32();
                        // Length of decrypted and decompressed data
                        int plainLen = this.Socket.Reader.ReadInt32();

                        DecryptFileChunk(out chunk, ( int )chunkLen, cryptKey);
                        len = DecompressFileChunk(ref chunk, plainLen);
                    }
                    else if (fileMode == FileMode.None)
                    {
                        chunk = this.Socket.Reader.ReadBytes(( int )chunkLen);
                        len   = chunk.Length;
                    }

                    ms.Write(chunk, 0, len);
                }

                byte[] data = ms.ToArray();

                this.MessageID++;

                return(data);
            }