using DeluxeBackend.Models; using DeluxeBackend.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using static DeluxeBackend.Enums; namespace DeluxeBackend.Controllers.Matchmaking { [Route("Matchmaking/room")] [ApiController] [Authorize(Roles = "gameClient")] public class RoomController(IJwtService jwt, ILiteDbService db, DiscordBotService discord) : ControllerBase { [HttpGet("{roomId}/instances")] public async Task Instances(long roomId) { var account = await jwt.GetLogin(User); if (account == null) { return Unauthorized(); } var room = db.Rooms.FindById(roomId); if (room == null) { return NotFound(); } bool isMod = await account.HasRoleAsync(discord, "moderator") || await account.HasRoleAsync(discord, "developer"); if (!isMod && !room.HasRole(account.Id, RoomRoleType.Moderator)) { return StatusCode(StatusCodes.Status403Forbidden, "Permission Denied"); } var query = db.RoomInstances.Query() .Include(x => x.SubRoom) .Include(x => x.SubRoom!.Room) .Where(x => x.SubRoom.Room.Id == roomId); if (!isMod) { query = query.Where(x => x.InstanceType == RoomInstanceType.Public); } var instances = query.ToList(); if (instances.Count == 0) { return Ok(Array.Empty()); } var instanceIds = instances.Select(x => x.Id).ToList(); var presences = db.Presences.Query() .Include(x => x.Account) .Include(x => x.Instance) .Where(x => x.Instance != null && instanceIds.Contains(x.Instance.Id)) .ToList(); var playersByInstance = presences .Where(x => x.Instance != null && x.Account != null) .GroupBy(x => x.Instance!.Id) .ToDictionary( g => g.Key, g => g.Select(p => p.Account.Id).ToList() ); var result = instances .OrderByDescending(x => playersByInstance.TryGetValue(x.Id, out var ids) ? ids.Count : 0) .Select(x => { var playerIds = playersByInstance.TryGetValue(x.Id, out var ids) ? ids : []; return MapToDictionary(x, playerIds); }); return Ok(result); } #region Helpers private static Dictionary MapToDictionary(RoomInstance roomInstance, List playerIds) { return new Dictionary { ["RoomInstanceId"] = roomInstance.Id, ["RoomId"] = roomInstance.SubRoom?.Room?.Id ?? 0, ["SubRoomId"] = roomInstance.SubRoom?.Id ?? 0, ["IsFull"] = false, ["CreatedAt"] = roomInstance.CreatedAt.ToString("O"), ["PlayerIds"] = playerIds }; } #endregion } }