namespace RR3CommunityServer.Models; // User Settings for Server Configuration public class UserSettings { public int Id { get; set; } public string DeviceId { get; set; } = string.Empty; public string ServerUrl { get; set; } = string.Empty; public string Mode { get; set; } = "offline"; // "online" or "offline" public DateTime LastUpdated { get; set; } = DateTime.UtcNow; } // Progression request/response models public class ProgressionUpdate { public int? GoldEarned { get; set; } public int? CashEarned { get; set; } public int? ExperienceEarned { get; set; } public int? ReputationEarned { get; set; } } public class CarPurchaseRequest { public string SynergyId { get; set; } = string.Empty; public string CarId { get; set; } = string.Empty; public bool UseGold { get; set; } = false; } public class CarUpgradeRequest { public string SynergyId { get; set; } = string.Empty; public string CarId { get; set; } = string.Empty; public string UpgradeType { get; set; } = string.Empty; // engine, tires, suspension, etc. } public class CareerEventCompletion { public string SynergyId { get; set; } = string.Empty; public string SeriesName { get; set; } = string.Empty; public string EventName { get; set; } = string.Empty; public int StarsEarned { get; set; } // 1-3 stars public double RaceTime { get; set; } public string? TrackName { get; set; } public string? CarName { get; set; } } // Standard Synergy API response wrapper public class SynergyResponse { public int resultCode { get; set; } = 0; // 0 = success, negative = error public string? message { get; set; } public T? data { get; set; } } // User models public class DeviceIdResponse { public string deviceId { get; set; } = string.Empty; public string synergyId { get; set; } = string.Empty; public long timestamp { get; set; } } public class AnonUidResponse { public string anonUid { get; set; } = string.Empty; public long expiresAt { get; set; } } // Product/Catalog models public class CatalogItem { public string itemId { get; set; } = string.Empty; public string sku { get; set; } = string.Empty; public string name { get; set; } = string.Empty; public string description { get; set; } = string.Empty; public string category { get; set; } = string.Empty; public decimal price { get; set; } public string currency { get; set; } = "USD"; public Dictionary metadata { get; set; } = new(); } public class CatalogCategory { public string categoryId { get; set; } = string.Empty; public string name { get; set; } = string.Empty; public List itemIds { get; set; } = new(); } // DRM models public class DrmNonceResponse { public string nonce { get; set; } = string.Empty; public long expiresAt { get; set; } } public class PurchasedItem { public string itemId { get; set; } = string.Empty; public string sku { get; set; } = string.Empty; public string orderId { get; set; } = string.Empty; public long purchaseTime { get; set; } public string token { get; set; } = string.Empty; } public class PurchaseVerificationRequest { public string receipt { get; set; } = string.Empty; public string signature { get; set; } = string.Empty; public string sku { get; set; } = string.Empty; public string orderId { get; set; } = string.Empty; } // Tracking models public class TrackingEvent { public string eventType { get; set; } = string.Empty; public long timestamp { get; set; } public Dictionary properties { get; set; } = new(); } // Director/Service Discovery public class DirectorResponse { public Dictionary serverUrls { get; set; } = new() { { "synergy.product", "https://localhost:5001" }, { "synergy.drm", "https://localhost:5001" }, { "synergy.user", "https://localhost:5001" }, { "synergy.tracking", "https://localhost:5001" }, { "synergy.s2s", "https://localhost:5001" } }; public string environment { get; set; } = "COMMUNITY"; public string version { get; set; } = "1.0.0"; } // Configuration models public class GameConfig { public long ServerTime { get; set; } public string ServerVersion { get; set; } = string.Empty; public string GameVersion { get; set; } = string.Empty; public bool MaintenanceMode { get; set; } public string MessageOfTheDay { get; set; } = string.Empty; public FeatureFlags FeatureFlags { get; set; } = new(); public ServerUrls Urls { get; set; } = new(); } public class FeatureFlags { public bool MultiplayerEnabled { get; set; } public bool LeaderboardsEnabled { get; set; } public bool DailyRewardsEnabled { get; set; } public bool TimeTrialsEnabled { get; set; } public bool CustomContentEnabled { get; set; } public bool SpecialEventsEnabled { get; set; } public bool AllItemsFree { get; set; } } public class ServerUrls { public string BaseUrl { get; set; } = string.Empty; public string AssetsUrl { get; set; } = string.Empty; public string LeaderboardsUrl { get; set; } = string.Empty; public string MultiplayerUrl { get; set; } = string.Empty; } public class ServerTime { public long ServerTimestamp { get; set; } public long ServerTimeMs { get; set; } public string Timezone { get; set; } = "UTC"; public bool IsDST { get; set; } } public class ServerStatus { public string Status { get; set; } = "online"; public string Version { get; set; } = string.Empty; public bool MaintenanceMode { get; set; } public int PlayerCount { get; set; } public long Uptime { get; set; } public string Message { get; set; } = string.Empty; } // Save/Load models public class PlayerSaveData { public string SynergyId { get; set; } = string.Empty; public string SaveDataJson { get; set; } = string.Empty; public long Version { get; set; } = 1; public long LastModified { get; set; } } public class SaveDataRequest { public string SynergyId { get; set; } = string.Empty; public string SaveData { get; set; } = string.Empty; } public class SaveDataResponse { public string SaveData { get; set; } = string.Empty; public long Version { get; set; } public long LastModified { get; set; } public bool Success { get; set; } } // ==================== LEADERBOARDS & RECORDS ==================== public class LeaderboardEntry { public int Id { get; set; } public string SynergyId { get; set; } = string.Empty; public string PlayerName { get; set; } = string.Empty; // What this record is for public string RecordType { get; set; } = string.Empty; // "TimeTrial", "Career", "Multiplayer" public string RecordCategory { get; set; } = string.Empty; // Time trial ID, series name, etc. public string? TrackName { get; set; } public string? CarName { get; set; } // The actual record public double TimeSeconds { get; set; } public DateTime SubmittedAt { get; set; } // Rankings (computed at query time) public int? GlobalRank { get; set; } public int? CountryRank { get; set; } } public class PersonalRecord { public int Id { get; set; } public string SynergyId { get; set; } = string.Empty; // What record this is public string RecordType { get; set; } = string.Empty; // "TimeTrial", "Career" public string RecordCategory { get; set; } = string.Empty; // Specific trial/event public string? TrackName { get; set; } public string? CarName { get; set; } // The record public double BestTimeSeconds { get; set; } public DateTime AchievedAt { get; set; } public DateTime? PreviousBestTime { get; set; } public double? ImprovementSeconds { get; set; } // Stats public int TotalAttempts { get; set; } } public class LeaderboardResponse { public string RecordType { get; set; } = string.Empty; public string RecordCategory { get; set; } = string.Empty; public int TotalEntries { get; set; } public List Entries { get; set; } = new(); public LeaderboardEntryDto? PlayerEntry { get; set; } // Requesting player's rank } public class LeaderboardEntryDto { public int Rank { get; set; } public string PlayerName { get; set; } = string.Empty; public string SynergyId { get; set; } = string.Empty; public double TimeSeconds { get; set; } public string FormattedTime { get; set; } = string.Empty; // "1:23.456" public DateTime SubmittedAt { get; set; } public string? CarName { get; set; } public bool IsCurrentPlayer { get; set; } } public class PersonalRecordsResponse { public string SynergyId { get; set; } = string.Empty; public string PlayerName { get; set; } = string.Empty; public int TotalRecords { get; set; } public List TimeTrialRecords { get; set; } = new(); public List CareerRecords { get; set; } = new(); } public class PersonalRecordDto { public string RecordCategory { get; set; } = string.Empty; public string? TrackName { get; set; } public string? CarName { get; set; } public double BestTimeSeconds { get; set; } public string FormattedTime { get; set; } = string.Empty; public DateTime AchievedAt { get; set; } public int TotalAttempts { get; set; } public int GlobalRank { get; set; } public double? ImprovementSeconds { get; set; } } public class RecordComparisonResponse { public PlayerRecordSummary Player1 { get; set; } = new(); public PlayerRecordSummary Player2 { get; set; } = new(); public List Comparisons { get; set; } = new(); } public class PlayerRecordSummary { public string SynergyId { get; set; } = string.Empty; public string PlayerName { get; set; } = string.Empty; public int TotalRecords { get; set; } public int BetterRecords { get; set; } } public class RecordComparison { public string RecordCategory { get; set; } = string.Empty; public string? TrackName { get; set; } public double? Player1Time { get; set; } public double? Player2Time { get; set; } public string? Winner { get; set; } // "player1", "player2", "tie" public double? TimeDifference { get; set; } } public class RecordSubmissionResponse { public bool Success { get; set; } public bool IsNewPersonalBest { get; set; } public bool IsNewGlobalRecord { get; set; } public int GlobalRank { get; set; } public double? PreviousBestTime { get; set; } public double? Improvement { get; set; } public int GoldEarned { get; set; } public int CashEarned { get; set; } } // ==================== NOTIFICATIONS ==================== public class NotificationDto { public int Id { get; set; } public string Type { get; set; } = string.Empty; public string Title { get; set; } = string.Empty; public string Message { get; set; } = string.Empty; public bool IsRead { get; set; } public long CreatedAt { get; set; } // Unix timestamp public long? ExpiresAt { get; set; } } public class NotificationsResponse { public List Notifications { get; set; } = new(); public int TotalCount { get; set; } public int UnreadCount { get; set; } } public class UnreadCountResponse { public int UnreadCount { get; set; } } public class MarkReadRequest { public string SynergyId { get; set; } = string.Empty; public List? NotificationIds { get; set; } // null = mark all read } public class SendNotificationRequest { public string? SynergyId { get; set; } // null = send to all players public string Type { get; set; } = "system"; public string Title { get; set; } = string.Empty; public string Message { get; set; } = string.Empty; public int? ExpiresInHours { get; set; } // null = never expires }