diff --git a/LightlessSyncAPI/Dto/Chat/ChatDtos.cs b/LightlessSyncAPI/Dto/Chat/ChatDtos.cs new file mode 100644 index 0000000..ae9adca --- /dev/null +++ b/LightlessSyncAPI/Dto/Chat/ChatDtos.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using LightlessSync.API.Data; +using LightlessSync.API.Dto.User; +using MessagePack; + +namespace LightlessSync.API.Dto.Chat; + +public enum ChatChannelType : byte +{ + Zone = 0, + Group = 1 +} + +public enum ChatSenderKind : byte +{ + Anonymous = 0, + IdentifiedUser = 1 +} + +[MessagePackObject] +public readonly record struct ChatChannelDescriptor +{ + [Key(0)] public ChatChannelType Type { get; init; } + [Key(1)] public ushort WorldId { get; init; } + [Key(2)] public ushort ZoneId { get; init; } + [Key(3)] public string? CustomKey { get; init; } + + public ChatChannelDescriptor WithNormalizedCustomKey() => + this with { CustomKey = string.IsNullOrWhiteSpace(CustomKey) ? string.Empty : CustomKey }; +} + +[MessagePackObject(keyAsPropertyName: true)] +public readonly record struct ChatPresenceUpdateDto(ChatChannelDescriptor Channel, ushort TerritoryId, bool IsActive); + +[MessagePackObject(keyAsPropertyName: true)] +public readonly record struct ChatSendRequestDto(ChatChannelDescriptor Channel, string Message); + +[MessagePackObject(keyAsPropertyName: true)] +public readonly record struct ChatSenderDescriptor( + ChatSenderKind Kind, + string Token, + string? DisplayName, + string? HashedCid, + UserData? User, + bool CanResolveProfile); + +[MessagePackObject(keyAsPropertyName: true)] +public readonly record struct ChatMessageDto( + ChatChannelDescriptor Channel, + ChatSenderDescriptor Sender, + string Message, + DateTime SentAtUtc, + string MessageId); + +[MessagePackObject(keyAsPropertyName: true)] +public readonly record struct ChatReportSubmitDto( + ChatChannelDescriptor Channel, + string MessageId, + string Reason, + string? AdditionalContext); + +[MessagePackObject(keyAsPropertyName: true)] +public readonly record struct ChatParticipantResolveRequestDto( + ChatChannelDescriptor Channel, + string Token); + +[MessagePackObject(keyAsPropertyName: true)] +public readonly record struct ChatParticipantResolveResultDto( + ChatChannelDescriptor Channel, + ChatSenderDescriptor Sender, + UserProfileDto? Profile); + +[MessagePackObject(keyAsPropertyName: true)] +public readonly record struct ZoneChatChannelInfoDto( + ChatChannelDescriptor Channel, + string DisplayName, + IReadOnlyList Territories); + +[MessagePackObject(keyAsPropertyName: true)] +public readonly record struct GroupChatChannelInfoDto( + ChatChannelDescriptor Channel, + string DisplayName, + string GroupId, + bool IsOwner); diff --git a/LightlessSyncAPI/SignalR/ILightlessHub.cs b/LightlessSyncAPI/SignalR/ILightlessHub.cs index 663df4c..f2679fd 100644 --- a/LightlessSyncAPI/SignalR/ILightlessHub.cs +++ b/LightlessSyncAPI/SignalR/ILightlessHub.cs @@ -1,15 +1,16 @@ using LightlessSync.API.Data; using LightlessSync.API.Data.Enum; using LightlessSync.API.Dto; +using LightlessSync.API.Dto.Chat; using LightlessSync.API.Dto.CharaData; using LightlessSync.API.Dto.Group; using LightlessSync.API.Dto.User; namespace LightlessSync.API.SignalR; -public interface ILightlessHub -{ - const int ApiVersion = 34; +public interface ILightlessHub +{ + const int ApiVersion = 37; const string Path = "/lightless"; Task CheckClientHealth(); @@ -21,7 +22,7 @@ public interface ILightlessHub Task Client_GroupPairJoined(GroupPairFullInfoDto groupPairInfoDto); Task Client_GroupPairLeft(GroupPairDto groupPairDto); Task Client_GroupSendFullInfo(GroupFullInfoDto groupInfo); - Task Client_GroupSendProfile (GroupProfileDto groupInfo); + Task Client_GroupSendProfile(GroupProfileDto groupInfo); Task Client_GroupSendInfo(GroupInfoDto groupInfo); Task Client_ReceiveServerMessage(MessageSeverity messageSeverity, string message); Task Client_ReceiveBroadcastPairRequest(UserPairNotificationDto dto); @@ -43,8 +44,11 @@ public interface ILightlessHub Task Client_GposeLobbyPushCharacterData(CharaDataDownloadDto charaDownloadDto); Task Client_GposeLobbyPushPoseData(UserData userData, PoseData poseData); Task Client_GposeLobbyPushWorldData(UserData userData, WorldData worldData); + Task Client_ChatReceive(ChatMessageDto message); - Task GetConnectionDto(); + Task GetConnectionDto(); + Task> GetZoneChatChannels(); + Task> GetGroupChatChannels(); Task GroupBanUser(GroupPairDto dto, string reason); Task GroupChangeGroupPermissionState(GroupPermissionDto dto); @@ -105,4 +109,8 @@ public interface ILightlessHub Task GposeLobbyPushCharacterData(CharaDataDownloadDto charaDownloadDto); Task GposeLobbyPushPoseData(PoseData poseData); Task GposeLobbyPushWorldData(WorldData worldData); -} + Task UpdateChatPresence(ChatPresenceUpdateDto presence); + Task SendChatMessage(ChatSendRequestDto request); + Task ReportChatMessage(ChatReportSubmitDto request); + Task ResolveChatParticipant(ChatParticipantResolveRequestDto request); +}