221 lines
5.9 KiB
C#
221 lines
5.9 KiB
C#
using LightlessSync.API.Data;
|
|
using LightlessSync.API.Data.Enum;
|
|
using LightlessSync.API.Data.Extensions;
|
|
using LightlessSync.API.Dto.Group;
|
|
|
|
namespace LightlessSync.PlayerData.Pairs;
|
|
|
|
/// <summary>
|
|
/// core models for the pair system
|
|
/// </summary>
|
|
public sealed class PairState
|
|
{
|
|
public CharacterData? CharacterData { get; set; }
|
|
public Guid? TemporaryCollectionId { get; set; }
|
|
|
|
public bool IsEmpty => CharacterData is null && (TemporaryCollectionId is null || TemporaryCollectionId == Guid.Empty);
|
|
}
|
|
|
|
public readonly record struct PairUniqueIdentifier(string UserId);
|
|
|
|
/// <summary>
|
|
/// link between a pair id and character ident
|
|
/// </summary>
|
|
public sealed record PairRegistration(PairUniqueIdentifier PairIdent, string? CharacterIdent);
|
|
|
|
/// <summary>
|
|
/// per group membership info for a pair
|
|
/// </summary>
|
|
public sealed class GroupPairRelationship
|
|
{
|
|
public GroupPairRelationship(string groupId, GroupPairUserInfo? info)
|
|
{
|
|
GroupId = groupId;
|
|
UserInfo = info;
|
|
}
|
|
|
|
public string GroupId { get; }
|
|
public GroupPairUserInfo? UserInfo { get; private set; }
|
|
|
|
public void SetUserInfo(GroupPairUserInfo? info)
|
|
{
|
|
UserInfo = info;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// runtime view of a single pair connection
|
|
/// </summary>
|
|
public sealed class PairConnection
|
|
{
|
|
public PairConnection(UserData user)
|
|
{
|
|
User = user;
|
|
Groups = new Dictionary<string, GroupPairRelationship>(StringComparer.Ordinal);
|
|
}
|
|
|
|
public UserData User { get; }
|
|
public bool IsOnline { get; private set; }
|
|
public string? Ident { get; private set; }
|
|
public UserPermissions SelfToOtherPermissions { get; private set; } = UserPermissions.NoneSet;
|
|
public UserPermissions OtherToSelfPermissions { get; private set; } = UserPermissions.NoneSet;
|
|
public IndividualPairStatus? IndividualPairStatus { get; private set; }
|
|
public Dictionary<string, GroupPairRelationship> Groups { get; }
|
|
|
|
public bool IsPaused => SelfToOtherPermissions.IsPaused();
|
|
public bool IsDirectlyPaired => IndividualPairStatus is not null && IndividualPairStatus != API.Data.Enum.IndividualPairStatus.None;
|
|
public bool IsOneSided => IndividualPairStatus == API.Data.Enum.IndividualPairStatus.OneSided;
|
|
public bool HasAnyConnection => IsDirectlyPaired || Groups.Count > 0;
|
|
|
|
public void SetOnline(string? ident)
|
|
{
|
|
IsOnline = true;
|
|
Ident = ident;
|
|
}
|
|
|
|
public void SetOffline()
|
|
{
|
|
IsOnline = false;
|
|
}
|
|
|
|
public void UpdatePermissions(UserPermissions own, UserPermissions other)
|
|
{
|
|
SelfToOtherPermissions = own;
|
|
OtherToSelfPermissions = other;
|
|
}
|
|
|
|
public void UpdateStatus(IndividualPairStatus? status)
|
|
{
|
|
IndividualPairStatus = status;
|
|
}
|
|
|
|
public void EnsureGroupRelationship(string groupId, GroupPairUserInfo? info)
|
|
{
|
|
if (Groups.TryGetValue(groupId, out var relationship))
|
|
{
|
|
relationship.SetUserInfo(info);
|
|
}
|
|
else
|
|
{
|
|
Groups[groupId] = new GroupPairRelationship(groupId, info);
|
|
}
|
|
}
|
|
|
|
public void RemoveGroupRelationship(string groupId)
|
|
{
|
|
Groups.Remove(groupId);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// syncshell metadata plus member connections
|
|
/// </summary>
|
|
public sealed class Syncshell
|
|
{
|
|
public Syncshell(GroupFullInfoDto dto)
|
|
{
|
|
GroupFullInfo = dto;
|
|
Users = new Dictionary<string, PairConnection>(StringComparer.Ordinal);
|
|
}
|
|
|
|
public GroupFullInfoDto GroupFullInfo { get; private set; }
|
|
public Dictionary<string, PairConnection> Users { get; }
|
|
|
|
public void Update(GroupFullInfoDto dto)
|
|
{
|
|
GroupFullInfo = dto;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// simple success/failure result
|
|
/// </summary>
|
|
public readonly struct PairOperationResult
|
|
{
|
|
private PairOperationResult(bool success, string? error)
|
|
{
|
|
Success = success;
|
|
Error = error;
|
|
}
|
|
|
|
public bool Success { get; }
|
|
public string? Error { get; }
|
|
|
|
public static PairOperationResult Ok() => new(true, null);
|
|
|
|
public static PairOperationResult Fail(string error) => new(false, error);
|
|
}
|
|
|
|
/// <summary>
|
|
/// typed success/failure result
|
|
/// </summary>
|
|
public readonly struct PairOperationResult<T>
|
|
{
|
|
private PairOperationResult(bool success, T value, string? error)
|
|
{
|
|
Success = success;
|
|
Value = value;
|
|
Error = error;
|
|
}
|
|
|
|
public bool Success { get; }
|
|
public T Value { get; }
|
|
public string? Error { get; }
|
|
|
|
public static PairOperationResult<T> Ok(T value) => new(true, value, null);
|
|
|
|
public static PairOperationResult<T> Fail(string error) => new(false, default!, error);
|
|
}
|
|
|
|
/// <summary>
|
|
/// state of which optional plugin warnings were shown
|
|
/// </summary>
|
|
public record OptionalPluginWarning
|
|
{
|
|
public bool ShownHeelsWarning { get; set; } = false;
|
|
public bool ShownCustomizePlusWarning { get; set; } = false;
|
|
public bool ShownHonorificWarning { get; set; } = false;
|
|
public bool ShownMoodlesWarning { get; set; } = false;
|
|
public bool ShowPetNicknamesWarning { get; set; } = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// tracks the handler registered pairs for an ident
|
|
/// </summary>
|
|
internal sealed class PairHandlerEntry
|
|
{
|
|
private readonly HashSet<PairUniqueIdentifier> _pairs = new();
|
|
|
|
public PairHandlerEntry(string ident, IPairHandlerAdapter handler)
|
|
{
|
|
Ident = ident;
|
|
Handler = handler;
|
|
}
|
|
|
|
public string Ident { get; }
|
|
public IPairHandlerAdapter Handler { get; }
|
|
|
|
public bool HasPairs => _pairs.Count > 0;
|
|
public int PairCount => _pairs.Count;
|
|
|
|
public void AddPair(PairUniqueIdentifier pair)
|
|
{
|
|
_pairs.Add(pair);
|
|
}
|
|
|
|
public bool RemovePair(PairUniqueIdentifier pair)
|
|
{
|
|
return _pairs.Remove(pair);
|
|
}
|
|
|
|
public IReadOnlyCollection<PairUniqueIdentifier> SnapshotPairs()
|
|
{
|
|
if (_pairs.Count == 0)
|
|
{
|
|
return Array.Empty<PairUniqueIdentifier>();
|
|
}
|
|
|
|
return _pairs.ToArray();
|
|
}
|
|
}
|