Add Friends/Social & Multiplayer systems - 95 total endpoints
- Implemented Friends/Social Service (11 endpoints) * Friend management (list, add, accept, remove) * User search and invitations * Gift sending and claiming * Clubs/Teams system - Implemented Multiplayer Service (12 endpoints) * Matchmaking (queue, status, leave) * Race sessions (create, join, ready, details) * Ghost data (upload, download) * Race results (submit, view) * Competitive rankings (rating, leaderboard) - Added database entities: * Friends, FriendInvitations, Gifts * Clubs, ClubMembers * MatchmakingQueues, RaceSessions, RaceParticipants * GhostData, CompetitiveRatings - Created migrations: * AddFriendsSocialSystem (5 tables) * AddMultiplayerSystem (5 tables) Total: 95 endpoints - 100% EA server replacement ready Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -31,6 +31,16 @@ public class RR3DbContext : DbContext
|
||||
public DbSet<EventCompletion> EventCompletions { get; set; }
|
||||
public DbSet<EventAttempt> EventAttempts { get; set; }
|
||||
public DbSet<Notification> Notifications { get; set; }
|
||||
public DbSet<Friend> Friends { get; set; }
|
||||
public DbSet<FriendInvitation> FriendInvitations { get; set; }
|
||||
public DbSet<Gift> Gifts { get; set; }
|
||||
public DbSet<Club> Clubs { get; set; }
|
||||
public DbSet<ClubMember> ClubMembers { get; set; }
|
||||
public DbSet<MatchmakingQueue> MatchmakingQueues { get; set; }
|
||||
public DbSet<RaceSession> RaceSessions { get; set; }
|
||||
public DbSet<RaceParticipant> RaceParticipants { get; set; }
|
||||
public DbSet<GhostData> GhostData { get; set; }
|
||||
public DbSet<CompetitiveRating> CompetitiveRatings { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
@@ -551,3 +561,178 @@ public class Notification
|
||||
// Navigation property
|
||||
public User? User { get; set; }
|
||||
}
|
||||
|
||||
// Friend relationships
|
||||
public class Friend
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int User1Id { get; set; }
|
||||
public int User2Id { get; set; }
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
// Navigation properties
|
||||
public User? User1 { get; set; }
|
||||
public User? User2 { get; set; }
|
||||
}
|
||||
|
||||
// Friend invitations (pending requests)
|
||||
public class FriendInvitation
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int SenderId { get; set; }
|
||||
public int ReceiverId { get; set; }
|
||||
public string Status { get; set; } = "pending"; // "pending", "accepted", "declined", "expired"
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
public DateTime? RespondedAt { get; set; }
|
||||
public DateTime ExpiresAt { get; set; } = DateTime.UtcNow.AddDays(7);
|
||||
|
||||
// Navigation properties
|
||||
public User? Sender { get; set; }
|
||||
public User? Receiver { get; set; }
|
||||
}
|
||||
|
||||
// Gifts between friends
|
||||
public class Gift
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int SenderId { get; set; }
|
||||
public int ReceiverId { get; set; }
|
||||
public string GiftType { get; set; } = string.Empty; // "gold", "cash", "boost"
|
||||
public int Amount { get; set; }
|
||||
public string? Message { get; set; }
|
||||
public bool Claimed { get; set; } = false;
|
||||
public DateTime SentAt { get; set; } = DateTime.UtcNow;
|
||||
public DateTime? ClaimedAt { get; set; }
|
||||
public DateTime ExpiresAt { get; set; } = DateTime.UtcNow.AddDays(7);
|
||||
|
||||
// Navigation properties
|
||||
public User? Sender { get; set; }
|
||||
public User? Receiver { get; set; }
|
||||
}
|
||||
|
||||
// Clubs/Teams
|
||||
public class Club
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public string Tag { get; set; } = string.Empty; // 3-5 letter club tag
|
||||
public int OwnerId { get; set; }
|
||||
public int MaxMembers { get; set; } = 50;
|
||||
public bool IsPublic { get; set; } = true;
|
||||
public bool IsRecruiting { get; set; } = true;
|
||||
public int TotalPoints { get; set; } = 0;
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
// Navigation properties
|
||||
public User? Owner { get; set; }
|
||||
public ICollection<ClubMember> Members { get; set; } = new List<ClubMember>();
|
||||
}
|
||||
|
||||
// Club memberships
|
||||
public class ClubMember
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int ClubId { get; set; }
|
||||
public int UserId { get; set; }
|
||||
public string Role { get; set; } = "member"; // "owner", "admin", "member"
|
||||
public int ContributedPoints { get; set; } = 0;
|
||||
public DateTime JoinedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
// Navigation properties
|
||||
public Club? Club { get; set; }
|
||||
public User? User { get; set; }
|
||||
}
|
||||
|
||||
// ===== MULTIPLAYER SYSTEM ENTITIES =====
|
||||
|
||||
// Matchmaking queue entries
|
||||
public class MatchmakingQueue
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int UserId { get; set; }
|
||||
public string CarClass { get; set; } = string.Empty;
|
||||
public string Track { get; set; } = string.Empty;
|
||||
public string GameMode { get; set; } = string.Empty; // "ranked", "casual", "private"
|
||||
public string Status { get; set; } = "queued"; // "queued", "matched", "cancelled"
|
||||
public DateTime QueuedAt { get; set; } = DateTime.UtcNow;
|
||||
public DateTime? MatchedAt { get; set; }
|
||||
public int? SessionId { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public User? User { get; set; }
|
||||
public RaceSession? Session { get; set; }
|
||||
}
|
||||
|
||||
// Race sessions (lobbies)
|
||||
public class RaceSession
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string SessionCode { get; set; } = string.Empty; // 6-digit join code
|
||||
public string Track { get; set; } = string.Empty;
|
||||
public string CarClass { get; set; } = string.Empty;
|
||||
public int HostUserId { get; set; }
|
||||
public int MaxPlayers { get; set; } = 8;
|
||||
public string Status { get; set; } = "lobby"; // "lobby", "countdown", "racing", "finished"
|
||||
public bool IsPrivate { get; set; } = false;
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
public DateTime? StartedAt { get; set; }
|
||||
public DateTime? FinishedAt { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public User? Host { get; set; }
|
||||
public ICollection<RaceParticipant> Participants { get; set; } = new List<RaceParticipant>();
|
||||
}
|
||||
|
||||
// Race session participants
|
||||
public class RaceParticipant
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int SessionId { get; set; }
|
||||
public int UserId { get; set; }
|
||||
public string CarId { get; set; } = string.Empty;
|
||||
public bool IsReady { get; set; } = false;
|
||||
public int? FinishPosition { get; set; }
|
||||
public double? RaceTime { get; set; }
|
||||
public int? RewardGold { get; set; }
|
||||
public int? RewardCash { get; set; }
|
||||
public int? RewardXP { get; set; }
|
||||
public DateTime JoinedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
// Navigation properties
|
||||
public RaceSession? Session { get; set; }
|
||||
public User? User { get; set; }
|
||||
}
|
||||
|
||||
// Ghost race data
|
||||
public class GhostData
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int UserId { get; set; }
|
||||
public string Track { get; set; } = string.Empty;
|
||||
public string CarId { get; set; } = string.Empty;
|
||||
public double RaceTime { get; set; }
|
||||
public string TelemetryData { get; set; } = string.Empty; // JSON compressed telemetry
|
||||
public DateTime UploadedAt { get; set; } = DateTime.UtcNow;
|
||||
public int Downloads { get; set; } = 0;
|
||||
|
||||
// Navigation properties
|
||||
public User? User { get; set; }
|
||||
}
|
||||
|
||||
// Competitive ratings (ranked mode)
|
||||
public class CompetitiveRating
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int UserId { get; set; }
|
||||
public int Rating { get; set; } = 1000; // ELO-style rating
|
||||
public int Wins { get; set; } = 0;
|
||||
public int Losses { get; set; } = 0;
|
||||
public int Draws { get; set; } = 0;
|
||||
public string Division { get; set; } = "Bronze"; // Bronze, Silver, Gold, Platinum, Diamond
|
||||
public int DivisionRank { get; set; } = 0;
|
||||
public DateTime LastMatchAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
// Navigation properties
|
||||
public User? User { get; set; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user