Files
2026-02-27 19:30:49 -08:00

87 lines
3.3 KiB
C#

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<ulong, WebSocket> 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<byte>(buffer), CancellationToken.None);
var handshakeJson = Encoding.UTF8.GetString(buffer, 0, result.Count);
var handshakeData = JsonSerializer.Deserialize<Dictionary<string, string>>(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<byte>(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<byte>(Encoding.UTF8.GetBytes(response)),
WebSocketMessageType.Text, true, CancellationToken.None);
/*await webSocket.SendAsync(
new ArraySegment<byte>(buffer, 0, receiveResult.Count),
receiveResult.MessageType,
receiveResult.EndOfMessage,
CancellationToken.None);*/
receiveResult = await webSocket.ReceiveAsync(
new ArraySegment<byte>(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);
}
}
}