From 596b79b83271298e8c5b47fa0a2ebe8d3a8e6366 Mon Sep 17 00:00:00 2001 From: Denver Jin Date: Wed, 30 Sep 2026 15:24:21 +0800 Subject: [PATCH 1/2] feat(protocol): add best-score replacement contracts Co-authored-by: Codex --- README-CN.md | 4 ++ README.md | 4 ++ .../PlatformBestScoreApiContracts.cs | 40 +++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 src/Sirius.Protocol/Models/InternalApi/PlatformBestScoreApiContracts.cs diff --git a/README-CN.md b/README-CN.md index f123974..7bc2f37 100644 --- a/README-CN.md +++ b/README-CN.md @@ -33,6 +33,10 @@ 除此之外,仓库还包含一部分 **TeamOpenSirius 自有协议**。这些类型位于 `Sirius.Protocol.InternalApi`,用于 OpenSirius 内部服务之间通信,例如游戏服务端、账号平台和 Realtime 后端。它们属于 OpenSirius 私有基础设施协议,**不是客户端原始 API 的一部分**。 +`PlatformBestScoreApiContracts.cs` 定义按版本校验的最佳成绩设置请求和响应,供 SiriusServer 的 +`/internal/platform/accounts/{accountId}/scores/best/{musicId}/{difficulty}` GET/PUT 接口使用。 +部署时需同时包含对应的服务端修改。 + 简单来说,SiriusData 是以下模块之间的公共数据边界: - 从 YMST 客户端恢复出的协议与数据结构; diff --git a/README.md b/README.md index 1f3f6cc..222f974 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,10 @@ Most game-facing models in `Sirius.Protocol` were reconstructed and adapted from The repository also contains a small set of **TeamOpenSirius-specific contracts** under `Sirius.Protocol.InternalApi`. These models are private infrastructure contracts used for communication between OpenSirius services such as the game server, account/platform services, and realtime backend. They are **not** intended to represent original client APIs. +`PlatformBestScoreApiContracts.cs` defines the version-checked best-score replacement +request and response used by SiriusServer's `/internal/platform/accounts/{accountId}/scores/best/{musicId}/{difficulty}` +GET/PUT endpoints. Deploy this contract together with the matching server change. + In short, SiriusData acts as the shared boundary between: - reconstructed YMST client protocol structures; diff --git a/src/Sirius.Protocol/Models/InternalApi/PlatformBestScoreApiContracts.cs b/src/Sirius.Protocol/Models/InternalApi/PlatformBestScoreApiContracts.cs new file mode 100644 index 0000000..a6d3238 --- /dev/null +++ b/src/Sirius.Protocol/Models/InternalApi/PlatformBestScoreApiContracts.cs @@ -0,0 +1,40 @@ +using System.Text.Json.Serialization; + +namespace Sirius.Protocol.InternalApi; + +[JsonUnmappedMemberHandling(JsonUnmappedMemberHandling.Disallow)] +public sealed class PlatformSetBestScoreRequest +{ + public required string OperationId { get; set; } + public required string Reason { get; set; } + public required long ExpectedRevision { get; set; } + public required long BestScore { get; set; } + public required int BestCombo { get; set; } + public required double AchievementRate { get; set; } + public required int ClearLamp { get; set; } + // Olivier's accuracy component cannot be inferred from aggregate achievement. + public int? AccuracyStar { get; set; } +} + +public sealed record PlatformBestScoreReply +{ + public long AccountId { get; init; } + public long MusicId { get; init; } + public long LiveId { get; init; } + public int Difficulty { get; init; } + public bool HasRecord { get; init; } + public long Revision { get; init; } + public long BestScore { get; init; } + public int BestCombo { get; init; } + public double AchievementRate { get; init; } + public int ClearLamp { get; init; } + public int RateGrade { get; init; } + public double NotationRate { get; init; } + public int? AccuracyStar { get; init; } + public int? SpPoint { get; init; } + public double PlayerRate { get; init; } + public double MaxPlayerRate { get; init; } + public int TotalSpCount { get; init; } + public long UpdatedAt { get; init; } + public bool AlreadyProcessed { get; init; } +} From aa7eaa3fd355e8cf2cc693cf97186d3d6f43efc2 Mon Sep 17 00:00:00 2001 From: Denver Jin Date: Wed, 30 Sep 2026 16:55:10 +0800 Subject: [PATCH 2/2] feat(protocol): model play record add and clear operations Replace direct best-score replacement contracts with per-chart record operations and judgement summaries. Co-authored-by: Codex --- README-CN.md | 5 +- README.md | 5 +- .../PlatformBestScoreApiContracts.cs | 40 ------------- .../PlatformScoreRecordMutationContracts.cs | 58 +++++++++++++++++++ 4 files changed, 62 insertions(+), 46 deletions(-) delete mode 100644 src/Sirius.Protocol/Models/InternalApi/PlatformBestScoreApiContracts.cs create mode 100644 src/Sirius.Protocol/Models/InternalApi/PlatformScoreRecordMutationContracts.cs diff --git a/README-CN.md b/README-CN.md index 7bc2f37..821e9ee 100644 --- a/README-CN.md +++ b/README-CN.md @@ -33,9 +33,8 @@ 除此之外,仓库还包含一部分 **TeamOpenSirius 自有协议**。这些类型位于 `Sirius.Protocol.InternalApi`,用于 OpenSirius 内部服务之间通信,例如游戏服务端、账号平台和 Realtime 后端。它们属于 OpenSirius 私有基础设施协议,**不是客户端原始 API 的一部分**。 -`PlatformBestScoreApiContracts.cs` 定义按版本校验的最佳成绩设置请求和响应,供 SiriusServer 的 -`/internal/platform/accounts/{accountId}/scores/best/{musicId}/{difficulty}` GET/PUT 接口使用。 -部署时需同时包含对应的服务端修改。 +`PlatformScoreRecordMutationContracts.cs` 定义 SiriusServer 补录正常结算成绩、 +清空指定谱面打歌记录的请求与响应类型。 简单来说,SiriusData 是以下模块之间的公共数据边界: diff --git a/README.md b/README.md index 222f974..d7beee0 100644 --- a/README.md +++ b/README.md @@ -33,9 +33,8 @@ Most game-facing models in `Sirius.Protocol` were reconstructed and adapted from The repository also contains a small set of **TeamOpenSirius-specific contracts** under `Sirius.Protocol.InternalApi`. These models are private infrastructure contracts used for communication between OpenSirius services such as the game server, account/platform services, and realtime backend. They are **not** intended to represent original client APIs. -`PlatformBestScoreApiContracts.cs` defines the version-checked best-score replacement -request and response used by SiriusServer's `/internal/platform/accounts/{accountId}/scores/best/{musicId}/{difficulty}` -GET/PUT endpoints. Deploy this contract together with the matching server change. +`PlatformScoreRecordMutationContracts.cs` defines the requests and replies for adding +a normally settled play and clearing one chart's play records in SiriusServer. In short, SiriusData acts as the shared boundary between: diff --git a/src/Sirius.Protocol/Models/InternalApi/PlatformBestScoreApiContracts.cs b/src/Sirius.Protocol/Models/InternalApi/PlatformBestScoreApiContracts.cs deleted file mode 100644 index a6d3238..0000000 --- a/src/Sirius.Protocol/Models/InternalApi/PlatformBestScoreApiContracts.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Text.Json.Serialization; - -namespace Sirius.Protocol.InternalApi; - -[JsonUnmappedMemberHandling(JsonUnmappedMemberHandling.Disallow)] -public sealed class PlatformSetBestScoreRequest -{ - public required string OperationId { get; set; } - public required string Reason { get; set; } - public required long ExpectedRevision { get; set; } - public required long BestScore { get; set; } - public required int BestCombo { get; set; } - public required double AchievementRate { get; set; } - public required int ClearLamp { get; set; } - // Olivier's accuracy component cannot be inferred from aggregate achievement. - public int? AccuracyStar { get; set; } -} - -public sealed record PlatformBestScoreReply -{ - public long AccountId { get; init; } - public long MusicId { get; init; } - public long LiveId { get; init; } - public int Difficulty { get; init; } - public bool HasRecord { get; init; } - public long Revision { get; init; } - public long BestScore { get; init; } - public int BestCombo { get; init; } - public double AchievementRate { get; init; } - public int ClearLamp { get; init; } - public int RateGrade { get; init; } - public double NotationRate { get; init; } - public int? AccuracyStar { get; init; } - public int? SpPoint { get; init; } - public double PlayerRate { get; init; } - public double MaxPlayerRate { get; init; } - public int TotalSpCount { get; init; } - public long UpdatedAt { get; init; } - public bool AlreadyProcessed { get; init; } -} diff --git a/src/Sirius.Protocol/Models/InternalApi/PlatformScoreRecordMutationContracts.cs b/src/Sirius.Protocol/Models/InternalApi/PlatformScoreRecordMutationContracts.cs new file mode 100644 index 0000000..82eeb65 --- /dev/null +++ b/src/Sirius.Protocol/Models/InternalApi/PlatformScoreRecordMutationContracts.cs @@ -0,0 +1,58 @@ +using System.Text.Json.Serialization; + +namespace Sirius.Protocol.InternalApi; + +[JsonUnmappedMemberHandling(JsonUnmappedMemberHandling.Disallow)] +public sealed class PlatformClearScoresRequest +{ + public required string OperationId { get; set; } + public required string Reason { get; set; } +} + +[JsonUnmappedMemberHandling(JsonUnmappedMemberHandling.Disallow)] +public sealed class PlatformAddScoreRequest +{ + public required string OperationId { get; set; } + public required string Reason { get; set; } + public required long PartyId { get; set; } + public required long LiveSettingMasterId { get; set; } + public bool UseStamina { get; set; } = true; + public int StaminaConsumptionRatio { get; set; } = 1; + public bool IsStoryEventChallenge { get; set; } + public required long Score { get; set; } + public long SenseScore { get; set; } + public long StarActScore { get; set; } + public int StarActCount { get; set; } + public required int MaxCombo { get; set; } + public required int FinalLife { get; set; } + public required PlatformScoreJudgements Judgements { get; set; } +} + +[JsonUnmappedMemberHandling(JsonUnmappedMemberHandling.Disallow)] +public sealed class PlatformScoreJudgements +{ + public required int PerfectStar { get; set; } + public required int Perfect { get; set; } + public required int Great { get; set; } + public required int Good { get; set; } + public required int Bad { get; set; } + public required int Miss { get; set; } +} + +public sealed record PlatformScoreReward(int ThingType, long ThingId, int Quantity); + +public sealed record PlatformScoreMutationReply +{ + public long AccountId { get; init; } + public long MusicId { get; init; } + public int Difficulty { get; init; } + public long? ResultId { get; init; } + public long ClearedRecords { get; init; } + public double PlayerRate { get; init; } + public double MaxPlayerRate { get; init; } + public int TotalSpCount { get; init; } + public int PlayerRank { get; init; } + public int CurrentStamina { get; init; } + public PlatformScoreReward[] Rewards { get; init; } = []; + public bool AlreadyProcessed { get; init; } +}