using Microsoft.EntityFrameworkCore; using RadicadeServer.API.Storefront; using RadicadeServer.DB; using RadicadeServer.RecNet.Enums.Store; using RadicadeServer.Utils; namespace RadicadeServer.API.Notifications { public static class RewardDiag { private const int DefaultLogLines = 120; public static async Task DescribeAsync(RecDBContext db, long accountId, int logLines) { var lines = new System.Text.StringBuilder(); lines.AppendLine($"build {BuildInfo.Tag}; assembly published {BuildInfo.AssemblyBuiltUtc:u}; running since {BuildInfo.StartedUtc:u}"); lines.AppendLine($"account {accountId}"); var progression = await db.Progression.AsNoTracking().FirstOrDefaultAsync(x => x.PlayerId == accountId); var json = progression?.GetProgressionJson(); var rewards = json?.PendingGameRewards ?? new List(); var day = json == null ? null : RewardDay.For(json, DateTime.UtcNow); if (day != null) lines.AppendLine($"today: dayKey={day.Day} firstActivityPaid={day.FirstActivityPaid} " + $"dailyChallengePaid={day.DailyChallengePaid} activityBoxes={day.ActivityBoxes}/{RewardDay.ActivityBoxesPerDay}"); lines.AppendLine($"reward selections kept: {rewards.Count} ({rewards.Count(r => !r.Consumed)} outstanding)"); if (rewards.Count == 0) lines.AppendLine(" (none - no reward has been requested for this account since the ledger was last reset)"); foreach (var reward in rewards.OrderByDescending(r => r.CreatedAt)) { var state = reward.Consumed ? $"collected box={reward.ConsumedGiftDropId} at {reward.ConsumedAt:u}" : "OUTSTANDING"; lines.AppendLine($" selectionId={reward.RewardSelectionId} rewardType={reward.RewardType} " + $"context={RewardTrace.Context(reward.GiftContext)} created={reward.CreatedAt:u} {state}"); lines.AppendLine($" message=\"{reward.Message}\""); lines.AppendLine($" drop1={RewardTrace.Box(reward.GiftDrop1)}"); lines.AppendLine($" drop2={RewardTrace.Box(reward.GiftDrop2)}"); lines.AppendLine($" drop3={RewardTrace.Box(reward.GiftDrop3)}"); } var boxes = await StorefrontShared.GetPendingGiftsAsync(db, accountId); lines.AppendLine($"pending gift boxes: {boxes.Count}"); foreach (var box in boxes) lines.AppendLine($" {RewardTrace.Box(box)} room={RroRewardPools.RoomForContext(box.Context) ?? ""}"); lines.AppendLine($"game-rewards.log tail (last {logLines} lines):"); try { var path = System.IO.Path.Join(DBConfig.PersistentLogs, "game-rewards.log"); if (!System.IO.File.Exists(path)) lines.AppendLine(" (no reward log has been written yet - the reward routes have not been hit)"); else foreach (var line in System.IO.File.ReadLines(path).TakeLast(Math.Clamp(logLines, 1, 2000))) lines.AppendLine(" " + line); } catch (Exception ex) { lines.AppendLine($" (the reward log could not be read: {ex.Message})"); } return lines.ToString(); } } }