90 lines
2.8 KiB
C#
90 lines
2.8 KiB
C#
namespace ChessCubing.Server.Social;
|
|
|
|
public sealed class CollaborativeMatchCoordinator
|
|
{
|
|
private readonly object _sync = new();
|
|
private readonly Dictionary<string, CollaborativeSessionState> _sessions = new(StringComparer.Ordinal);
|
|
|
|
public void RegisterSession(PlaySessionResponse session)
|
|
{
|
|
lock (_sync)
|
|
{
|
|
_sessions[session.SessionId] = new CollaborativeSessionState(
|
|
session.SessionId,
|
|
new HashSet<string>(StringComparer.Ordinal)
|
|
{
|
|
session.WhiteSubject,
|
|
session.BlackSubject,
|
|
session.InitiatorSubject,
|
|
session.RecipientSubject,
|
|
},
|
|
null,
|
|
0);
|
|
}
|
|
}
|
|
|
|
public bool CanAccessSession(string sessionId, string subject)
|
|
{
|
|
lock (_sync)
|
|
{
|
|
return _sessions.TryGetValue(sessionId, out var session)
|
|
&& session.ParticipantSubjects.Contains(subject);
|
|
}
|
|
}
|
|
|
|
public CollaborativeMatchStateMessage? GetLatestState(string sessionId, string subject)
|
|
{
|
|
lock (_sync)
|
|
{
|
|
if (!_sessions.TryGetValue(sessionId, out var session) ||
|
|
!session.ParticipantSubjects.Contains(subject))
|
|
{
|
|
throw new SocialValidationException("Cette session de partie est introuvable ou n'est pas accessible.");
|
|
}
|
|
|
|
return session.LatestState;
|
|
}
|
|
}
|
|
|
|
public CollaborativeMatchStateMessage PublishState(
|
|
string sessionId,
|
|
string subject,
|
|
string? matchJson,
|
|
string route)
|
|
{
|
|
lock (_sync)
|
|
{
|
|
if (!_sessions.TryGetValue(sessionId, out var session) ||
|
|
!session.ParticipantSubjects.Contains(subject))
|
|
{
|
|
throw new SocialValidationException("Cette session de partie est introuvable ou n'est pas accessible.");
|
|
}
|
|
|
|
var revision = session.Revision + 1;
|
|
var message = new CollaborativeMatchStateMessage
|
|
{
|
|
SessionId = sessionId,
|
|
MatchJson = matchJson,
|
|
Route = string.IsNullOrWhiteSpace(route) ? "/application.html" : route.Trim(),
|
|
SenderSubject = subject,
|
|
Revision = revision,
|
|
UpdatedUtc = DateTime.UtcNow,
|
|
};
|
|
|
|
_sessions[sessionId] = session with
|
|
{
|
|
Revision = revision,
|
|
LatestState = message,
|
|
};
|
|
|
|
return message;
|
|
}
|
|
}
|
|
|
|
private sealed record CollaborativeSessionState(
|
|
string SessionId,
|
|
HashSet<string> ParticipantSubjects,
|
|
CollaborativeMatchStateMessage? LatestState,
|
|
long Revision);
|
|
}
|