using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using UnityEngine.Networking;
///
/// 云存档模块。
///
public sealed class BriskArchiveModule
: BriskModuleBase
{
///
/// 获取当前账号的存档槽位列表。
///
public async Task> GetSlotsAsync()
{
return await ExecuteAsync(async context =>
{
var data = await context.HttpClient.GetRawDataAsync("/archives/slots", null, true);
return (IReadOnlyList)BriskModelMapper.ToArchiveSlots(data);
});
}
///
/// 获取指定槽位的元信息。
///
public async Task GetMetaAsync(int slotNo)
{
ValidateSlotNo(slotNo);
return await ExecuteAsync(async context =>
{
var data = await context.HttpClient.GetDataAsync($"/archives/slot/{slotNo}/meta", null, true);
return BriskModelMapper.ToArchiveMeta(data);
});
}
///
/// 上传指定槽位的二进制存档。
///
public async Task UploadAsync(int slotNo, byte[] bytes, int? baseVersion = null, string checksum = null)
{
ValidateSlotNo(slotNo);
if (bytes == null || bytes.Length == 0)
{
throw new ArgumentException("bytes is required.", nameof(bytes));
}
return await ExecuteAsync(async context =>
{
var finalChecksum = string.IsNullOrWhiteSpace(checksum) ? ComputeSha256(bytes) : NormalizeChecksum(checksum);
var sections = new List
{
new MultipartFormDataSection("base_version", (baseVersion ?? 0).ToString()),
new MultipartFormDataSection("checksum", finalChecksum),
new MultipartFormFileSection("file", bytes, "archive.bin", "application/octet-stream")
};
var data = await context.HttpClient.PostMultipartAsync($"/archives/slot/{slotNo}/upload", sections, true);
return BriskModelMapper.ToArchiveUploadResult(data);
});
}
///
/// 以 UTF-8 文本形式上传指定槽位的存档。
///
public Task UploadTextAsync(int slotNo, string text, int? baseVersion = null, string checksum = null)
{
RequireNotNull(text, nameof(text));
return UploadAsync(slotNo, Encoding.UTF8.GetBytes(text), baseVersion, checksum);
}
///
/// 以 JSON 文本形式上传指定槽位的存档。
///
public Task UploadJsonAsync(int slotNo, object payload, int? baseVersion = null, string checksum = null)
{
RequireNotNull(payload, nameof(payload));
return UploadAsync(slotNo, Encoding.UTF8.GetBytes(BriskJson.Serialize(payload)), baseVersion, checksum);
}
///
/// 下载指定槽位的二进制存档。
///
public async Task DownloadAsync(int slotNo)
{
ValidateSlotNo(slotNo);
return await ExecuteAsync(async context =>
{
var response = await context.HttpClient.GetBytesAsync($"/archives/slot/{slotNo}/download", null, true);
return new BriskArchiveDownloadResult
{
Bytes = response.Bytes,
Version = ReadHeaderInt(response.Headers, "X-Archive-Version"),
Checksum = ReadHeader(response.Headers, "X-Archive-Checksum")
};
});
}
///
/// 以 UTF-8 文本形式下载指定槽位的存档。
///
public async Task DownloadTextAsync(int slotNo)
{
var result = await DownloadAsync(slotNo);
return result == null || result.Bytes == null ? string.Empty : Encoding.UTF8.GetString(result.Bytes);
}
///
/// 以 JSON 对象形式下载指定槽位的存档。
///
public async Task