using Microsoft.AspNetCore.Mvc; using RecRoomArchive.Models.API.Notification; using System.Net.WebSockets; using System.Text; using System.Text.Json; namespace RecRoomArchive.Controllers.API.Notification { [Route("api/[controller]")] [ApiController] public class NotificationController : ControllerBase { private static readonly Dictionary Clients = []; [HttpGet("v2")] public async Task Get() { if (!HttpContext.WebSockets.IsWebSocketRequest) { HttpContext.Response.StatusCode = 400; return; } var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); var buffer = new byte[1024 * 4]; var result = await webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None); var handshakeJson = Encoding.UTF8.GetString(buffer, 0, result.Count); var handshakeData = JsonSerializer.Deserialize>(handshakeJson)!; var playerId = ulong.Parse(handshakeData["PlayerId"]); Clients[playerId] = webSocket; var sessionResponse = JsonSerializer.Serialize(new { SessionId = playerId }); await webSocket.SendAsync(Encoding.UTF8.GetBytes(sessionResponse), WebSocketMessageType.Text, true, CancellationToken.None); await Echo(playerId, webSocket); Clients.Remove(playerId); } private static async Task Echo(ulong playerId, WebSocket webSocket) { var buffer = new byte[1024 * 4]; var receiveResult = await webSocket.ReceiveAsync( new ArraySegment(buffer), CancellationToken.None); while (!receiveResult.CloseStatus.HasValue) { var response = JsonSerializer.Serialize(new { SessionId = playerId }); // i think?? only for analytics tho lolololool await webSocket.SendAsync(new ArraySegment(Encoding.UTF8.GetBytes(response)), WebSocketMessageType.Text, true, CancellationToken.None); /*await webSocket.SendAsync( new ArraySegment(buffer, 0, receiveResult.Count), receiveResult.MessageType, receiveResult.EndOfMessage, CancellationToken.None);*/ receiveResult = await webSocket.ReceiveAsync( new ArraySegment(buffer), CancellationToken.None); } await webSocket.CloseAsync( receiveResult.CloseStatus.Value, receiveResult.CloseStatusDescription, CancellationToken.None); Clients.Remove(playerId); } public static async Task Notify(ulong playerId, PushNotificationId id, object msg) { if (!Clients.TryGetValue(playerId, out var socket)) return; if (socket.State != WebSocketState.Open) return; var notification = new { Id = (int)id, Msg = msg }; var json = JsonSerializer.Serialize(notification); var bytes = Encoding.UTF8.GetBytes(json); await socket.SendAsync(bytes, WebSocketMessageType.Text, true, CancellationToken.None); } } }