Skip to content

Commit

Permalink
game chunk and patch build
Browse files Browse the repository at this point in the history
  • Loading branch information
Scighost committed Jan 18, 2025
1 parent a8c20c8 commit 8d0d3e8
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/Starward.Core/HoYoPlay/GameBranch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class GameBranchPackage
[JsonPropertyName("package_id")]
public string PackageId { get; set; }


// main or pre_download
[JsonPropertyName("branch")]
public string Branch { get; set; }

Expand Down
81 changes: 61 additions & 20 deletions src/Starward.Core/HoYoPlay/GameChunkBuild.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,63 +2,85 @@

namespace Starward.Core.HoYoPlay;


public class GameChunkBuild
{

// json string build_id
[JsonPropertyName("build_id")]
public string BuildId { get; set; }


// string tag
/// <summary>
/// 游戏版本
/// </summary>
[JsonPropertyName("tag")]
public string Tag { get; set; }


/// <summary>
/// 文件清单
/// </summary>
[JsonPropertyName("manifests")]
public List<GameChunkManifest> Manifests { get; set; }


}



/// <summary>
/// Chunk 下载模式文件清单
/// </summary>
public class GameChunkManifest
{

// string category_id
/// <summary>
/// 资源ID
/// </summary>
[JsonPropertyName("category_id")]
public string CategoryId { get; set; }

// string category_name
/// <summary>
/// 资源名称
/// </summary>
[JsonPropertyName("category_name")]
public string CategoryName { get; set; }

// string matching_field
/// <summary>
/// 资源类型,game or 语音类型(zh-cn, en-us, ja-jp, ko-kr)
/// </summary>
[JsonPropertyName("matching_field")]
public string MatchingField { get; set; }

// gamechunkmanifestfile manifest
/// <summary>
/// 清单文件信息
/// </summary>
[JsonPropertyName("manifest")]
public GameChunkManifestFile Manifest { get; set; }


// gamechunkmanifesturl chunk_download
/// <summary>
/// 分块文件下载链接前缀
/// </summary>
[JsonPropertyName("chunk_download")]
public GameChunkManifestUrl ChunkDownload { get; set; }


// gamechunkmanifesturl manifest_download
/// <summary>
/// 清单文件下载链接前缀
/// </summary>
[JsonPropertyName("manifest_download")]
public GameChunkManifestUrl ManifestDownload { get; set; }


// gamechunkmanifeststats stats
/// <summary>
/// 文件统计信息
/// </summary>
[JsonPropertyName("stats")]
public GameChunkManifestStats Stats { get; set; }


// gamechunkmanifeststats deduplicated_stats
/// <summary>
/// 去重后的文件统计信息
/// </summary>
[JsonPropertyName("deduplicated_stats")]
public GameChunkManifestStats DeduplicatedStats { get; set; }

Expand All @@ -68,11 +90,15 @@ public class GameChunkManifest

public class GameChunkManifestFile
{

/// <summary>
/// 文件名,与下载链接前缀拼接为下载链接
/// </summary>
[JsonPropertyName("id")]
public string Id { get; set; }


/// <summary>
/// 解压后的MD5
/// </summary>
[JsonPropertyName("checksum")]
public string Checksum { get; set; }

Expand All @@ -90,33 +116,46 @@ public class GameChunkManifestFile




/// <summary>
/// 文件下载链接前缀
/// </summary>
public class GameChunkManifestUrl
{

/// <summary>
/// 加密
/// </summary>
[JsonPropertyName("encryption")]
public int Encryption { get; set; }


/// <summary>
/// 密码
/// </summary>
[JsonPropertyName("password")]
public string Password { get; set; }


/// <summary>
/// 压缩
/// </summary>
[JsonPropertyName("compression")]
public int Compression { get; set; }


/// <summary>
/// 前缀
/// </summary>
[JsonPropertyName("url_prefix")]
public string UrlPrefix { get; set; }


/// <summary>
/// 后缀
/// </summary>
[JsonPropertyName("url_suffix")]
public string UrlSuffix { get; set; }

}




public class GameChunkManifestStats
{

Expand All @@ -139,4 +178,6 @@ public class GameChunkManifestStats
[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
public int ChunkCount { get; set; }


}

85 changes: 85 additions & 0 deletions src/Starward.Core/HoYoPlay/GamePatchBuild.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System.Text.Json.Serialization;

namespace Starward.Core.HoYoPlay;


public class GamePatchBuild
{

[JsonPropertyName("build_id")]
public string BuildId { get; set; }


[JsonPropertyName("patch_id")]
public string PatchId { get; set; }


/// <summary>
/// 游戏版本
/// </summary>
[JsonPropertyName("tag")]
public string Tag { get; set; }


/// <summary>
/// 文件清单
/// </summary>
[JsonPropertyName("manifests")]
public List<GamePatchManifest> Manifests { get; set; }


}


/// <summary>
/// Chunk 下载模式补丁文件清单
/// </summary>
public class GamePatchManifest
{
/// <summary>
/// 资源ID
/// </summary>
[JsonPropertyName("category_id")]
public string CategoryId { get; set; }

/// <summary>
/// 资源名称
/// </summary>
[JsonPropertyName("category_name")]
public string CategoryName { get; set; }

/// <summary>
/// 资源类型,game or 语音类型(zh-cn, en-us, ja-jp, ko-kr)
/// </summary>
[JsonPropertyName("matching_field")]
public string MatchingField { get; set; }

/// <summary>
/// 清单文件信息
/// </summary>
[JsonPropertyName("manifest")]
public GameChunkManifestFile Manifest { get; set; }


/// <summary>
/// 分块文件下载链接前缀
/// </summary>
[JsonPropertyName("diff_download")]
public GameChunkManifestUrl DiffDownload { get; set; }


/// <summary>
/// 清单文件下载链接前缀
/// </summary>
[JsonPropertyName("manifest_download")]
public GameChunkManifestUrl ManifestDownload { get; set; }


/// <summary>
/// 文件统计信息
/// </summary>
[JsonPropertyName("stats")]
public Dictionary<string, GameChunkManifestStats> Stats { get; set; }


}
65 changes: 57 additions & 8 deletions src/Starward.Core/HoYoPlay/HoYoPlayClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,25 @@ private async Task<T> CommonGetAsync<T>(string url, string node, CancellationTok



private async Task<T> CommonSendAsync<T>(HttpRequestMessage request, CancellationToken cancellationToken = default)
{
var response = await _httpClient.SendAsync(request, cancellationToken);
response.EnsureSuccessStatusCode();
var responseData = await response.Content.ReadFromJsonAsync(typeof(miHoYoApiWrapper<T>), HoYoPlayJsonContext.Default, cancellationToken) as miHoYoApiWrapper<T>;
if (responseData is null)
{
throw new miHoYoApiException(-1, "Can not parse the response body.");
}
if (responseData.Retcode != 0)
{
throw new miHoYoApiException(responseData.Retcode, responseData.Message);
}
return responseData.Data;
}





private static string BuildUrl(string api, string launcherId, string language)
{
Expand Down Expand Up @@ -455,7 +474,7 @@ public async Task<List<GameBranch>> GetGameBranchAsync(string launcherId, string


/// <summary>
/// Chunk 下载模式清单
/// Chunk 下载模式文件清单
/// </summary>
/// <param name="gameBranch"></param>
/// <param name="gameBranchPackage"></param>
Expand All @@ -467,25 +486,25 @@ public async Task<GameChunkBuild> GetGameChunkBuildAsync(GameBranch gameBranch,
string? url = null;
if (gameBranch.GameId.GameBiz.IsChinaServer())
{
url = "https://api-takumi.mihoyo.com/downloader/sophon_chunk/api/getBuild?plat_app=ddxf5qt290cg";
url = "https://downloader-api.mihoyo.com/downloader/sophon_chunk/api/getBuild?";
}
if (gameBranch.GameId.GameBiz.IsGlobalServer())
{
url = "https://sg-public-api.hoyoverse.com/downloader/sophon_chunk/api/getBuild?plat_app=ddxf6vlr1reo";
url = "https://sg-downloader-api.hoyoverse.com/downloader/sophon_chunk/api/getBuild?";
}
if (url is null)
{
throw new ArgumentOutOfRangeException(nameof(gameBranch), $"Unknown game biz ({gameBranch.GameId.GameBiz}).");
}
url += $"&branch={gameBranchPackage.Branch}&package_id={gameBranchPackage.PackageId}&password={gameBranchPackage.Password}";
url += $"branch={gameBranchPackage.Branch}&package_id={gameBranchPackage.PackageId}&password={gameBranchPackage.Password}";
return await CommonGetAsync<GameChunkBuild>(url, cancellationToken);
}




/// <summary>
/// Chunk 下载模式清单
/// Chunk 下载模式文件清单
/// </summary>
/// <param name="gameBranch"></param>
/// <param name="gameBranchPackage"></param>
Expand All @@ -498,22 +517,52 @@ public async Task<GameChunkBuild> GetGameChunkBuildAsync(GameBranch gameBranch,
string? url = null;
if (gameBranch.GameId.GameBiz.IsChinaServer())
{
url = "https://api-takumi.mihoyo.com/downloader/sophon_chunk/api/getBuild?plat_app=ddxf5qt290cg";
url = "https://downloader-api.mihoyo.com/downloader/sophon_chunk/api/getBuild?";
}
if (gameBranch.GameId.GameBiz.IsGlobalServer())
{
url = "https://sg-public-api.hoyoverse.com/downloader/sophon_chunk/api/getBuild?plat_app=ddxf6vlr1reo";
url = "https://sg-downloader-api.hoyoverse.com/downloader/sophon_chunk/api/getBuild?";
}
if (url is null)
{
throw new ArgumentOutOfRangeException(nameof(gameBranch), $"Unknown game biz ({gameBranch.GameId.GameBiz}).");
}
url += $"&branch={gameBranchPackage.Branch}&package_id={gameBranchPackage.PackageId}&password={gameBranchPackage.Password}&tag={version}";
url += $"branch={gameBranchPackage.Branch}&package_id={gameBranchPackage.PackageId}&password={gameBranchPackage.Password}&tag={version}";
return await CommonGetAsync<GameChunkBuild>(url, cancellationToken);
}




/// <summary>
/// Chunk 下载模式的增量更新补丁文件清单
/// </summary>
/// <param name="gameBranch"></param>
/// <param name="gameBranchPackage"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public async Task<GamePatchBuild> GetGameChunkPatchBuildAsync(GameBranch gameBranch, GameBranchPackage gameBranchPackage, CancellationToken cancellationToken = default)
{
string? url = null;
if (gameBranch.GameId.GameBiz.IsChinaServer())
{
url = "https://downloader-api.mihoyo.com/downloader/sophon_chunk/api/getPatchBuild?";
}
if (gameBranch.GameId.GameBiz.IsGlobalServer())
{
url = "https://sg-downloader-api.hoyoverse.com/downloader/sophon_chunk/api/getPatchBuild?";
}
if (url is null)
{
throw new ArgumentOutOfRangeException(nameof(gameBranch), $"Unknown game biz ({gameBranch.GameId.GameBiz}).");
}
url += $"branch={gameBranchPackage.Branch}&package_id={gameBranchPackage.PackageId}&password={gameBranchPackage.Password}";
var request = new HttpRequestMessage(HttpMethod.Post, url);
return await CommonSendAsync<GamePatchBuild>(request, cancellationToken);
}




}
1 change: 1 addition & 0 deletions src/Starward.Core/HoYoPlay/HoYoPlayJsonContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace Starward.Core.HoYoPlay;
[JsonSerializable(typeof(List<GameConfig>))]
[JsonSerializable(typeof(List<GameBranch>))]
[JsonSerializable(typeof(miHoYoApiWrapper<GameChunkBuild>))]
[JsonSerializable(typeof(miHoYoApiWrapper<GamePatchBuild>))]

internal partial class HoYoPlayJsonContext : JsonSerializerContext
{
Expand Down

0 comments on commit 8d0d3e8

Please sign in to comment.