/// <summary> /// Begins a request to upload a file to the UFS. /// The <see cref="UFSClient"/> should be logged on before this point. /// Results are returned in a <see cref="UploadFileResponseCallback"/>. /// </summary> /// <param name="details">The details to use for uploading the file.</param> /// <returns>The Job ID of the request. This can be used to find the appropriate <see cref="UploadFileResponseCallback"/>.</returns> public JobID RequestFileUpload(UploadDetails details) { if (details == null) { throw new ArgumentNullException(nameof(details)); } byte[] compressedData = ZipUtil.Compress(details.FileData); var msg = new ClientMsgProtobuf <CMsgClientUFSUploadFileRequest>(EMsg.ClientUFSUploadFileRequest); msg.SourceJobID = steamClient.GetNextJobID(); msg.Body.app_id = details.AppID; msg.Body.can_encrypt = false; msg.Body.file_name = details.FileName; msg.Body.file_size = ( uint )compressedData.Length; msg.Body.raw_file_size = ( uint )details.FileData.Length; msg.Body.sha_file = CryptoHelper.SHAHash(details.FileData); msg.Body.time_stamp = DateUtils.DateTimeToUnixTime(DateTime.UtcNow); Send(msg); return(msg.SourceJobID); }
/// <summary> /// Uploads the actual contents of a file to the UFS. /// The <see cref="UFSClient"/> should be logged on before this point, and the previous request to upload a file must have completed successfully. /// Results are returned in a <see cref="UploadFileFinishedCallback"/>. /// </summary> /// <param name="details">The details to use for uploading the file.</param> /// <returns>The Job ID of the request. This can be used to find the appropriate <see cref="UploadFileFinishedCallback"/>.</returns> public void UploadFile(UploadDetails details) { const uint MaxBytesPerChunk = 10240; byte[] compressedData = ZipUtil.Compress(details.FileData); byte[] fileHash = CryptoHelper.SHAHash(details.FileData); var buffer = new byte[MaxBytesPerChunk]; using (var ms = new MemoryStream(compressedData)) { for (long readIndex = 0; readIndex < ms.Length; readIndex += buffer.Length) { var msg = new ClientMsgProtobuf <CMsgClientUFSFileChunk>(EMsg.ClientUFSUploadFileChunk); msg.TargetJobID = details.RemoteJobID; var bytesRead = ms.Read(buffer, 0, buffer.Length); if (bytesRead < buffer.Length) { msg.Body.data = buffer.Take(bytesRead).ToArray(); } else { msg.Body.data = buffer; } msg.Body.file_start = ( uint )readIndex; msg.Body.sha_file = fileHash; Send(msg); } } }
/// <summary> /// Request a list of files stored in the cloudfor a target App Id /// Results are returned in a <see cref="DepotKeyCallback"/> callback. /// The returned <see cref="AsyncJob{T}"/> can also be awaited to retrieve the callback result. /// </summary> /// <param name="appid">The AppID to request the file list for.</param> /// <returns>The Job ID of the request. This can be used to find the appropriate <see cref="DepotKeyCallback"/>.</returns> public AsyncJob <ClientBeginFileUploadCallback> RequestFileUpload(uint appID, string fileName, byte[] fileData, bool compress = false) { byte[] compressedData = compress ? ZipUtil.Compress(fileData) : fileData; var request = new ServiceCallMsgProtobuf <CCloud_ClientBeginFileUpload_Request>(EMsg.ServiceMethodCallFromClient); request.SourceJobID = Client.GetNextJobID(); request.Body.appid = appID; request.Body.is_shared_file = false; request.Body.can_encrypt = true; request.Body.filename = fileName; request.Body.file_size = (uint)compressedData.Length; request.Body.raw_file_size = (uint)fileData.Length; request.Body.file_sha = CryptoHelper.SHAHash(fileData); request.Body.time_stamp = DateUtils.DateTimeToUnixTime(DateTime.UtcNow); request.TargetJobName = SteamCloudServiceJobConstants.ClientBeginFileUpload; lock (_clientBeginFileUploadJobs) { _clientBeginFileUploadJobs.Add(request.SourceJobID); } Client.Send(request); return(new AsyncJob <ClientBeginFileUploadCallback>(Client, request.SourceJobID)); }