Files
Radicade/Server/PlayerEvents/PlayerEventNotifications.cs
2026-10-16 23:33:13 -07:00

127 lines
3.7 KiB
C#

using RadicadeServer.API.Notifications;
using Microsoft.EntityFrameworkCore;
using RadicadeServer.DB;
using RadicadeServer.RecNet.Enums.Messages;
using RadicadeServer.RecNet.Notifications;
namespace RadicadeServer.RecNet.Events
{
public static class PlayerEventNotifications
{
public static async Task PushToEventInstancesAsync(RecDBContext db, PlayerEventDB ev)
{
var audienceIds = await (
from presence in db.Presences.AsNoTracking()
join instance in db.RoomInstances.AsNoTracking()
on presence.roomInstance equals (long?)instance.roomInstanceId
where presence.isOnline && instance.eventId == ev.PlayerEventId
select presence.playerId).ToListAsync();
var update = Updated(ev);
foreach (var recipientId in audienceIds.Append(ev.CreatorPlayerId).Distinct())
await PushAsync(recipientId, update);
}
public static Notification Created(PlayerEventDB ev) => new()
{
Id = NotificationType.PlayerEventCreated,
Msg = Payload(ev)
};
public static Notification Updated(PlayerEventDB ev) => new()
{
Id = NotificationType.PlayerEventUpdated,
Msg = Payload(ev)
};
public static Notification Deleted(long playerEventId) => new()
{
Id = NotificationType.PlayerEventDeleted,
Msg = new Dictionary<string, object?>
{
["playerEventId"] = playerEventId,
["PlayerEventId"] = playerEventId
}
};
public static Notification ResponseChanged(PlayerEventDB ev, PlayerEventResponse response) => new()
{
Id = NotificationType.PlayerEventResponseChanged,
Msg = new Dictionary<string, object?>
{
["PlayerEvent"] = Payload(ev),
["PlayerEventResponse"] = new Dictionary<string, object?>
{
["PlayerEventResponseId"] = response.PlayerEventResponseId,
["PlayerEventId"] = response.PlayerEventId,
["PlayerId"] = response.PlayerId,
["CreatedAt"] = response.CreatedAt,
["Type"] = (int)response.Type
}
}
};
public static Dictionary<string, object?> Payload(PlayerEventDB ev)
{
var tags = ParseTags(ev.TagsJson);
return new Dictionary<string, object?>
{
["tags"] = tags.Select(tag => new Dictionary<string, object?>
{
["tag"] = tag.Tag,
["type"] = tag.Type
}).ToArray(),
["playerEventId"] = ev.PlayerEventId,
["creatorPlayerId"] = ev.CreatorPlayerId,
["roomId"] = ev.RoomId,
["subRoomId"] = ev.SubRoomId,
["clubId"] = ev.ClubId,
["name"] = ev.Name,
["description"] = ev.Description,
["imageName"] = string.IsNullOrWhiteSpace(ev.ImageName) ? DefaultImageName : ev.ImageName,
["startTime"] = EventClock.ToWire(ev.StartTime),
["endTime"] = EventClock.ToWire(ev.EndTime),
["attendeeCount"] = ev.AttendeeCount,
["accessibility"] = (int)ev.Accessibility,
["isMultiInstance"] = ev.IsMultiInstance,
["supportMultiInstanceRoomChat"] = ev.SupportMultiInstanceRoomChat,
["defaultBroadcastPermissions"] = ev.DefaultBroadcastPermissions,
["canRequestBroadcastPermissions"] = ev.CanRequestBroadcastPermissions,
["broadcastingRoomInstanceId"] = ev.BroadcastingRoomInstanceId
};
}
public static async Task PushAsync(long accountId, Notification frame)
{
try
{
await Notify.SendNotify(accountId, frame);
}
catch (Exception ex)
{
Console.WriteLine($"[Events] pushing {Notify.WireId(frame.Id)} to account {accountId} failed: {ex.Message}");
}
}
private const string DefaultImageName = "default";
private static List<PlayerEventTag> ParseTags(string? tagsJson)
{
if (string.IsNullOrWhiteSpace(tagsJson)) return [];
try
{
return System.Text.Json.JsonSerializer.Deserialize<List<PlayerEventTag>>(tagsJson) ?? [];
}
catch
{
return [];
}
}
}
}