diff --git a/ProjectLighthouse/Controllers/MatchController.cs b/ProjectLighthouse/Controllers/MatchController.cs index 07483f14..1b19196e 100644 --- a/ProjectLighthouse/Controllers/MatchController.cs +++ b/ProjectLighthouse/Controllers/MatchController.cs @@ -1,5 +1,6 @@ #nullable enable using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.Json; @@ -94,7 +95,16 @@ namespace LBPUnion.ProjectLighthouse.Controllers #region Process match data - if (matchData is UpdateMyPlayerData) MatchHelper.SetUserLocation(user.UserId, token.UserLocation); + if (matchData is UpdateMyPlayerData playerData) + { + MatchHelper.SetUserLocation(user.UserId, token.UserLocation); + + if (playerData.RoomState != null) + { + Room? room = RoomHelper.FindRoomByUser(user); + if (room != null && Equals(room.Host, user)) room.State = (RoomState)playerData.RoomState; + } + } if (matchData is FindBestRoom && MatchHelper.UserLocations.Count > 1) { @@ -108,7 +118,35 @@ namespace LBPUnion.ProjectLighthouse.Controllers MatchHelper.AddUserRecentlyDivedIn(user.UserId, player.User.UserId); } - return new ObjectResult($"[{{\"StatusCode\":200}},{serialized}]"); + return this.Ok($"[{{\"StatusCode\":200}},{serialized}]"); + } + + if (matchData is CreateRoom createRoom && MatchHelper.UserLocations.Count >= 1) + { + List users = new(); + foreach (string playerUsername in createRoom.Players) + { + User? player = await this.database.Users.FirstOrDefaultAsync(u => u.Username == playerUsername); + // ReSharper disable once ConditionIsAlwaysTrueOrFalse + if (player != null) + { + users.Add(player); + } + else return this.BadRequest(); + } + + Room newRoom = RoomHelper.CreateRoom(users, createRoom.RoomSlot); + + // Delete old rooms based on host + RoomHelper.Rooms.RemoveAll(r => r.Host == newRoom.Host); + + // Remove players in this new room from other rooms + foreach (Room room in RoomHelper.Rooms) + { + if (room == newRoom) continue; + + foreach (User newRoomPlayer in newRoom.Players) room.Players.RemoveAll(p => p == newRoomPlayer); + } } #endregion diff --git a/ProjectLighthouse/Helpers/RoomHelper.cs b/ProjectLighthouse/Helpers/RoomHelper.cs index 81647450..9ce5569a 100644 --- a/ProjectLighthouse/Helpers/RoomHelper.cs +++ b/ProjectLighthouse/Helpers/RoomHelper.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using LBPUnion.ProjectLighthouse.Types; +using LBPUnion.ProjectLighthouse.Types.Levels; using LBPUnion.ProjectLighthouse.Types.Match; namespace LBPUnion.ProjectLighthouse.Helpers @@ -10,6 +11,12 @@ namespace LBPUnion.ProjectLighthouse.Helpers { public static readonly List Rooms = new(); + public static readonly RoomSlot PodSlot = new() + { + SlotType = SlotType.Pod, + SlotId = 0, + }; + public static FindBestRoomResponse? FindBestRoom(User user, string location) { bool anyRoomsLookingForPlayers = Rooms.Any(r => r.IsLookingForPlayers); @@ -80,5 +87,28 @@ namespace LBPUnion.ProjectLighthouse.Helpers return null; } + + public static Room CreateRoom(User user, RoomSlot? slot = null) + => CreateRoom + ( + new List + { + user + }, + slot + ); + public static Room CreateRoom(List users, RoomSlot? slot = null) + { + Room room = new(); + + room.Players = users; + room.State = RoomState.Idle; + room.Slot = slot ?? PodSlot; + + Rooms.Add(room); + return room; + } + + public static Room? FindRoomByUser(User user) => Rooms.FirstOrDefault(r => r.Players.Contains(user)); } } \ No newline at end of file diff --git a/ProjectLighthouse/Types/Match/CreateRoom.cs b/ProjectLighthouse/Types/Match/CreateRoom.cs index 371acad9..1dc569c8 100644 --- a/ProjectLighthouse/Types/Match/CreateRoom.cs +++ b/ProjectLighthouse/Types/Match/CreateRoom.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; +using LBPUnion.ProjectLighthouse.Types.Levels; namespace LBPUnion.ProjectLighthouse.Types.Match { @@ -21,6 +22,13 @@ namespace LBPUnion.ProjectLighthouse.Types.Match [JsonIgnore] public IEnumerable FirstSlot => this.Slots[0]; + public RoomSlot RoomSlot + => new() + { + SlotType = (SlotType)Slots[0][0], + SlotId = Slots[0][1], + }; + public List NAT; public RoomState RoomState; public int HostMood; diff --git a/ProjectLighthouse/Types/Match/FindBestRoom.cs b/ProjectLighthouse/Types/Match/FindBestRoom.cs index 2b76de28..7e93f804 100644 --- a/ProjectLighthouse/Types/Match/FindBestRoom.cs +++ b/ProjectLighthouse/Types/Match/FindBestRoom.cs @@ -1,5 +1,28 @@ +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json.Serialization; + namespace LBPUnion.ProjectLighthouse.Types.Match { - public class FindBestRoom : CreateRoom - {} + // Schema is the EXACT SAME as CreateRoom (but cant be a subclass here), so see comments there for details + [SuppressMessage("ReSharper", "CollectionNeverUpdated.Global")] + public class FindBestRoom : IMatchData + { + public List Players { get; set; } + + public List Reservations { get; set; } + public List> Slots { get; set; } + + [JsonIgnore] + public IEnumerable FirstSlot => this.Slots[0]; + + public List NAT; + public RoomState RoomState; + public int HostMood; + public int PassedNoJoinPoint; + public List Location; + public int Language; + public int BuildVersion; + public string Search; + } } \ No newline at end of file diff --git a/ProjectLighthouse/Types/Match/NatType.cs b/ProjectLighthouse/Types/Match/NatType.cs new file mode 100644 index 00000000..fd6250ac --- /dev/null +++ b/ProjectLighthouse/Types/Match/NatType.cs @@ -0,0 +1,9 @@ +namespace LBPUnion.ProjectLighthouse.Types.Match +{ + public enum NatType + { + Open = 1, + Moderate = 2, + Strict = 3, + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Types/Match/Room.cs b/ProjectLighthouse/Types/Match/Room.cs index 466ecc4a..88e967be 100644 --- a/ProjectLighthouse/Types/Match/Room.cs +++ b/ProjectLighthouse/Types/Match/Room.cs @@ -11,5 +11,7 @@ namespace LBPUnion.ProjectLighthouse.Types.Match public bool IsInPod => Slot.SlotType == SlotType.Pod; public bool IsLookingForPlayers => this.State == RoomState.DivingIntoLevel || this.State == RoomState.DivingInWaiting; + + public User Host => this.Players[0]; } } \ No newline at end of file diff --git a/ProjectLighthouse/Types/Match/UpdateMyPlayerData.cs b/ProjectLighthouse/Types/Match/UpdateMyPlayerData.cs index ff93dd2c..fde5b8e7 100644 --- a/ProjectLighthouse/Types/Match/UpdateMyPlayerData.cs +++ b/ProjectLighthouse/Types/Match/UpdateMyPlayerData.cs @@ -1,7 +1,10 @@ +#nullable enable namespace LBPUnion.ProjectLighthouse.Types.Match { public class UpdateMyPlayerData : IMatchData { - public string Player; + public string Player { get; set; } + + public RoomState? RoomState { get; set; } } } \ No newline at end of file diff --git a/ProjectLighthouse/Types/User.cs b/ProjectLighthouse/Types/User.cs index b4c51d47..6f7f7b6b 100644 --- a/ProjectLighthouse/Types/User.cs +++ b/ProjectLighthouse/Types/User.cs @@ -1,4 +1,5 @@ using System.ComponentModel.DataAnnotations.Schema; +using System.Diagnostics.CodeAnalysis; using System.Linq; using LBPUnion.ProjectLighthouse.Serialization; using LBPUnion.ProjectLighthouse.Types.Profiles; @@ -187,5 +188,25 @@ namespace LBPUnion.ProjectLighthouse.Types #endregion Slots + #nullable enable + public override bool Equals(object? obj) + { + if (obj is User user) return user.UserId == UserId; + + return false; + } + + [SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalse")] + public static bool operator ==(User user1, User user2) + { + if (ReferenceEquals(user1, user2)) return true; + if ((object)user1 == null || (object)user2 == null) return false; + + return user1.UserId == user2.UserId; + } + public static bool operator !=(User user1, User user2) => !(user1 == user2); + + public override int GetHashCode() => this.UserId; + #nullable disable } } \ No newline at end of file