Add Events Service - Career mode unlocked! (96% complete)

EVENTS SERVICE (4/4 endpoints - 100%):
- GET  /synergy/events/active - List active events with player progress
- GET  /synergy/events/{eventId} - Event details and requirements
- POST /synergy/events/{eventId}/start - Start event attempt
- POST /synergy/events/{eventId}/complete - Submit results, award rewards

Features:
- Track player progression through career events
- Personal best detection with improvement bonuses
- Reduced rewards on replays (prevents farming)
- Full integration with user/session system

Database:
- Events table (16 columns) with series/event organization
- EventCompletions table for player progress tracking
- EventAttempts table for session management
- Migration AddEventsSystem applied successfully

Documentation:
- AUTHENTICATION-ANALYSIS.md - Proof .NET implementation is correct
- BINARY-PATCH-ANALYSIS.md - ARM64 patch analysis

Server progress: 70/73 endpoints (96%)
Career mode now fully functional!

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-02-23 12:10:31 -08:00
parent a6167c8249
commit 4736637c3c
7 changed files with 2990 additions and 4 deletions

View File

@@ -27,6 +27,9 @@ public class RR3DbContext : DbContext
public DbSet<PlayerSave> PlayerSaves { get; set; }
public DbSet<LeaderboardEntry> LeaderboardEntries { get; set; }
public DbSet<PersonalRecord> PersonalRecords { get; set; }
public DbSet<Event> Events { get; set; }
public DbSet<EventCompletion> EventCompletions { get; set; }
public DbSet<EventAttempt> EventAttempts { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
@@ -478,3 +481,56 @@ public class ModPack
public DateTime CreatedAt { get; set; }
public DateTime? UpdatedAt { get; set; }
}
// Career Events entity
public class Event
{
public int Id { get; set; }
public string EventCode { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public string SeriesName { get; set; } = string.Empty;
public int SeriesOrder { get; set; }
public int EventOrder { get; set; }
public string Track { get; set; } = string.Empty;
public string EventType { get; set; } = "race"; // race, duel, elimination, etc
public int Laps { get; set; }
public int RequiredPR { get; set; }
public string? RequiredCarClass { get; set; }
public double? TargetTime { get; set; }
public int GoldReward { get; set; }
public int CashReward { get; set; }
public int XPReward { get; set; }
public bool Active { get; set; } = true;
}
// Tracks player's completion of events
public class EventCompletion
{
public int Id { get; set; }
public int UserId { get; set; }
public int EventId { get; set; }
public double BestTime { get; set; }
public int CompletionCount { get; set; }
public DateTime FirstCompletedAt { get; set; }
public DateTime LastCompletedAt { get; set; }
// Navigation properties
public User? User { get; set; }
public Event? Event { get; set; }
}
// Tracks active event attempts
public class EventAttempt
{
public int Id { get; set; }
public int UserId { get; set; }
public int EventId { get; set; }
public DateTime StartedAt { get; set; }
public bool Completed { get; set; }
public DateTime? CompletedAt { get; set; }
public double? TimeSeconds { get; set; }
// Navigation properties
public User? User { get; set; }
public Event? Event { get; set; }
}