Server-backed friends, chat, IAB scaffold + EF migrations/Postgres
- Social: EF-backed friends graph + chat (SocialService/SocialModels); REST endpoints (friends add/accept/decline/remove/list/requests, chat conversations/messages/send) with real-time hub events (friendRequest/social/chat). GameManager tracks online users for presence. - Client SignalrService: friends + chat now hit the server and react to hub events (refetch + emit); no longer delegated to the mock. - IAB: /api/coins/iab/verify endpoint + IabVerifyReq for Cafe Bazaar/Myket (token verification is a documented TODO pending store accounts/SKUs). - Persistence: EF Core Design package + DesignTimeDbContextFactory (Postgres), Program auto-migrate/EnsureCreated, appsettings.Production.json.example with Supabase connection + live ZarinPal template. Verified end-to-end (two users, SQLite dev): request -> accept -> bidirectional friends, chat send with per-user fromMe, unread count + read-on-fetch. Server + client builds clean (dotnet build, tsc, next build). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -141,18 +141,20 @@ public sealed class GameManager
|
||||
public void ChooseTrump(string userId, string suit) => RoomOf(userId)?.HumanChooseTrump(userId, suit);
|
||||
public void SendReaction(string userId, string reaction) => RoomOf(userId)?.Reaction(userId, reaction);
|
||||
|
||||
private int _online;
|
||||
public int OnlineCount => Volatile.Read(ref _online);
|
||||
private readonly ConcurrentDictionary<string, int> _onlineUsers = new();
|
||||
public int OnlineCount => _onlineUsers.Count;
|
||||
public bool IsOnline(string userId) => _onlineUsers.ContainsKey(userId);
|
||||
|
||||
public void OnConnected(string userId)
|
||||
{
|
||||
Interlocked.Increment(ref _online);
|
||||
_onlineUsers.AddOrUpdate(userId, 1, (_, n) => n + 1);
|
||||
RoomOf(userId)?.SetConnected(userId, true);
|
||||
}
|
||||
|
||||
public void OnDisconnected(string userId)
|
||||
{
|
||||
if (Interlocked.Decrement(ref _online) < 0) Interlocked.Exchange(ref _online, 0);
|
||||
if (_onlineUsers.AddOrUpdate(userId, 0, (_, n) => n - 1) <= 0)
|
||||
_onlineUsers.TryRemove(userId, out _);
|
||||
CancelMatchmaking(userId);
|
||||
RoomOf(userId)?.SetConnected(userId, false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user