0.4.0: Claim, Models/ DTOs, compile
CI / publish (push) Failing after 39s
CI / check (push) Successful in 52s

LeaderboardSession.ClaimAsync sends onClaim. Generated DTOs live under Models/ with nullable wire fields. Remove incomplete duplicate type files.
This commit is contained in:
edmand46
2026-08-29 11:33:01 +03:00
parent 3c590294c9
commit ea20ea6d51
89 changed files with 1414 additions and 396 deletions
@@ -62,9 +62,9 @@ public sealed partial class ScenarioService
// Prefer server-provided WaitDeadline from the plan boundary over local calculation.
// The server stamps WaitDeadline on server-enforced wait boundaries (see StampBoundaries).
var boundary = run.Plan.BoundaryNodes?.FirstOrDefault(
b => b.SourceNodeId == state.NodeId && !string.IsNullOrEmpty(b.WaitDeadline)
b => b.SourceNodeId == state.NodeId && b.WaitDeadline.HasValue
);
if (boundary != null && DateTimeOffset.TryParse(boundary.WaitDeadline, null, DateTimeStyles.RoundtripKind, out var parsed))
if (boundary?.WaitDeadline is { } parsed)
{
state.WaitDeadlineUtc = parsed;
}
@@ -40,6 +40,11 @@ public sealed partial class ScenarioService
return ex is OperationCanceledException || ex is RudderNetworkException;
}
private static bool IsRankNotEligible(Exception ex)
{
return ex is RudderApiException api && api.Code == "rank_not_eligible";
}
private IReadOnlyList<PlanRun> StartPlans(IEnumerable<ExecutionPlan>? plans)
{
var started = new List<PlanRun>();
@@ -181,6 +186,8 @@ public sealed partial class ScenarioService
}
catch (Exception ex)
{
if (IsRankNotEligible(ex))
throw;
FailRun(run, nodeId, ex);
}
}
@@ -69,7 +69,7 @@ public sealed class BattlePassSession
IdempotencyKey = Guid.NewGuid().ToString()
}, cancellationToken).ConfigureAwait(false);
if (response != null && response.Success)
if (response != null && response.Success == true)
await Context.CompleteAsync("onPremiumPurchase", cancellationToken).ConfigureAwait(false);
return response!;
@@ -1,3 +1,4 @@
using System;
using System.Threading;
using System.Threading.Tasks;
@@ -23,9 +24,17 @@ public sealed class LeaderboardSession
/// <summary>Advances the run through the onEnd handle (fire-and-forget).</summary>
public void End() => Context.Complete("onEnd");
/// <summary>Advances the run through the onRewardClaimed handle.</summary>
public Task RewardClaimedAsync(CancellationToken cancellationToken = default) => Context.CompleteAsync("onRewardClaimed", cancellationToken);
/// <summary>Advances the run through the onClaim handle. The server matches live rank to a place.</summary>
public Task ClaimAsync(CancellationToken cancellationToken = default) => Context.CompleteAsync("onClaim", cancellationToken);
/// <summary>Advances the run through the onRewardClaimed handle (fire-and-forget).</summary>
public void RewardClaimed() => Context.Complete("onRewardClaimed");
/// <summary>Advances the run through the onClaim handle (fire-and-forget).</summary>
public void Claim() => Context.Complete("onClaim");
/// <summary>Advances the run through the onClaim handle.</summary>
[Obsolete("Use ClaimAsync. Removed in the next SDK version.")]
public Task RewardClaimedAsync(CancellationToken cancellationToken = default) => ClaimAsync(cancellationToken);
/// <summary>Advances the run through the onClaim handle (fire-and-forget).</summary>
[Obsolete("Use Claim. Removed in the next SDK version.")]
public void RewardClaimed() => Claim();
}