From 198c438abca834b127d8abd3f541bb159a587e00 Mon Sep 17 00:00:00 2001 From: jvyden Date: Tue, 16 Nov 2021 13:41:34 -0500 Subject: [PATCH 01/10] RoomHelper.FindBestRoom --- ProjectLighthouse.sln.DotSettings | 1 + .../Controllers/MatchController.cs | 48 +++++------ ProjectLighthouse/Helpers/MatchHelper.cs | 31 ------- ProjectLighthouse/Helpers/RoomHelper.cs | 84 +++++++++++++++++++ ProjectLighthouse/Types/Match/Player.cs | 7 +- ProjectLighthouse/Types/Match/Room.cs | 15 ++++ ProjectLighthouse/Types/Match/RoomSlot.cs | 10 +++ ProjectLighthouse/Types/Match/RoomState.cs | 21 ++++- 8 files changed, 157 insertions(+), 60 deletions(-) create mode 100644 ProjectLighthouse/Helpers/RoomHelper.cs create mode 100644 ProjectLighthouse/Types/Match/Room.cs create mode 100644 ProjectLighthouse/Types/Match/RoomSlot.cs diff --git a/ProjectLighthouse.sln.DotSettings b/ProjectLighthouse.sln.DotSettings index 7a68182c..9a6134aa 100644 --- a/ProjectLighthouse.sln.DotSettings +++ b/ProjectLighthouse.sln.DotSettings @@ -72,6 +72,7 @@ UseExplicitType UseExplicitType UseExplicitType + DLC LBP MM NAT diff --git a/ProjectLighthouse/Controllers/MatchController.cs b/ProjectLighthouse/Controllers/MatchController.cs index 4d1fa398..07483f14 100644 --- a/ProjectLighthouse/Controllers/MatchController.cs +++ b/ProjectLighthouse/Controllers/MatchController.cs @@ -71,33 +71,6 @@ namespace LBPUnion.ProjectLighthouse.Controllers #endregion - #region Process match data - - if (matchData is UpdateMyPlayerData) MatchHelper.SetUserLocation(user.UserId, token.UserLocation); - - if (matchData is FindBestRoom && MatchHelper.UserLocations.Count > 1) - { - foreach ((int id, string? location) in MatchHelper.UserLocations) - { - if (id == user.UserId) continue; - if (location == null) continue; - if (MatchHelper.DidUserRecentlyDiveInWith(user.UserId, id)) continue; - - User? otherUser = await this.database.Users.FirstOrDefaultAsync(u => u.UserId == id); - if (otherUser == null) continue; - - FindBestRoomResponse response = MatchHelper.FindBestRoomResponse(user.Username, otherUser.Username, token.UserLocation, location); - - string serialized = JsonSerializer.Serialize(response, typeof(FindBestRoomResponse)); - - MatchHelper.AddUserRecentlyDivedIn(user.UserId, id); - - return new ObjectResult($"[{{\"StatusCode\":200}},{serialized}]"); - } - } - - #endregion - #region Update LastMatch LastMatch? lastMatch = await this.database.LastMatches.Where(l => l.UserId == user.UserId).FirstOrDefaultAsync(); @@ -119,6 +92,27 @@ namespace LBPUnion.ProjectLighthouse.Controllers #endregion + #region Process match data + + if (matchData is UpdateMyPlayerData) MatchHelper.SetUserLocation(user.UserId, token.UserLocation); + + if (matchData is FindBestRoom && MatchHelper.UserLocations.Count > 1) + { + FindBestRoomResponse? response = RoomHelper.FindBestRoom(user, token.UserLocation); + + if (response == null) return this.BadRequest(); + + string serialized = JsonSerializer.Serialize(response, typeof(FindBestRoomResponse)); + foreach (Player player in response.Players) + { + MatchHelper.AddUserRecentlyDivedIn(user.UserId, player.User.UserId); + } + + return new ObjectResult($"[{{\"StatusCode\":200}},{serialized}]"); + } + + #endregion + return this.Ok("[{\"StatusCode\":200}]"); } } diff --git a/ProjectLighthouse/Helpers/MatchHelper.cs b/ProjectLighthouse/Helpers/MatchHelper.cs index b3017e2a..30f07616 100644 --- a/ProjectLighthouse/Helpers/MatchHelper.cs +++ b/ProjectLighthouse/Helpers/MatchHelper.cs @@ -39,37 +39,6 @@ namespace LBPUnion.ProjectLighthouse.Helpers return recentlyDivedIn.Contains(otherUserId); } - public static FindBestRoomResponse FindBestRoomResponse(string username, string otherUsername, string location, string otherLocation) - => new() - { - Players = new List - { - new() - { - MatchingRes = 0, - PlayerId = otherUsername, - }, - new() - { - MatchingRes = 1, - PlayerId = username, - }, - }, - Locations = new List - { - location, - otherLocation, - }, - Slots = new List> - { - new() - { - 5, - 0, - }, - }, - }; - public static IMatchData? Deserialize(string data) { string matchType = ""; diff --git a/ProjectLighthouse/Helpers/RoomHelper.cs b/ProjectLighthouse/Helpers/RoomHelper.cs new file mode 100644 index 00000000..81647450 --- /dev/null +++ b/ProjectLighthouse/Helpers/RoomHelper.cs @@ -0,0 +1,84 @@ +#nullable enable +using System.Collections.Generic; +using System.Linq; +using LBPUnion.ProjectLighthouse.Types; +using LBPUnion.ProjectLighthouse.Types.Match; + +namespace LBPUnion.ProjectLighthouse.Helpers +{ + public class RoomHelper + { + public static readonly List Rooms = new(); + + public static FindBestRoomResponse? FindBestRoom(User user, string location) + { + bool anyRoomsLookingForPlayers = Rooms.Any(r => r.IsLookingForPlayers); + + // Look for rooms looking for players before moving on to rooms that are idle. + foreach (Room room in Rooms.Where(r => !anyRoomsLookingForPlayers || r.IsLookingForPlayers)) + { + if (MatchHelper.DidUserRecentlyDiveInWith(user.UserId, room.Players[0].UserId)) continue; + + Dictionary relevantUserLocations = new(); + + // Determine if all players in a room have UserLocations stored, also store the relevant userlocations while we're at it + bool allPlayersHaveLocations = room.Players.All + ( + p => + { + bool gotValue = MatchHelper.UserLocations.TryGetValue(p.UserId, out string? value) && value != null; + + if (gotValue) relevantUserLocations.Add(p.UserId, value!); + return gotValue; + } + ); + + // If we don't have all locations then the game won't know how to communicate. Thus, it's not a valid room. + if (!allPlayersHaveLocations) continue; + + // If we got here then it should be a valid room. + + FindBestRoomResponse response = new(); + + response.Players = new List(); + foreach (User player in room.Players) + { + response.Players.Add + ( + new Player + { + MatchingRes = 0, + User = player, + } + ); + + response.Locations.Add(relevantUserLocations.GetValueOrDefault(player.UserId)); // Already validated to exist + } + + response.Players.Add + ( + new Player + { + MatchingRes = 1, + User = user, + } + ); + + response.Locations.Add(location); + + response.Slots = new List> + { + new() + { + (int)room.Slot.SlotType, + room.Slot.SlotId, + }, + }; + + return response; + } + + return null; + } + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Types/Match/Player.cs b/ProjectLighthouse/Types/Match/Player.cs index ad2140fa..95c18ec6 100644 --- a/ProjectLighthouse/Types/Match/Player.cs +++ b/ProjectLighthouse/Types/Match/Player.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; namespace LBPUnion.ProjectLighthouse.Types.Match @@ -6,7 +7,11 @@ namespace LBPUnion.ProjectLighthouse.Types.Match [Serializable] public class Player { - public string PlayerId { get; set; } + [JsonIgnore] + public User User { get; set; } + + [SuppressMessage("ReSharper", "UnusedMember.Global")] + public string PlayerId => User.Username; [JsonPropertyName("matching_res")] public int MatchingRes { get; set; } diff --git a/ProjectLighthouse/Types/Match/Room.cs b/ProjectLighthouse/Types/Match/Room.cs new file mode 100644 index 00000000..466ecc4a --- /dev/null +++ b/ProjectLighthouse/Types/Match/Room.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using LBPUnion.ProjectLighthouse.Types.Levels; + +namespace LBPUnion.ProjectLighthouse.Types.Match +{ + public class Room + { + public List Players; + public RoomState State; + public RoomSlot Slot; + + public bool IsInPod => Slot.SlotType == SlotType.Pod; + public bool IsLookingForPlayers => this.State == RoomState.DivingIntoLevel || this.State == RoomState.DivingInWaiting; + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Types/Match/RoomSlot.cs b/ProjectLighthouse/Types/Match/RoomSlot.cs new file mode 100644 index 00000000..438fa763 --- /dev/null +++ b/ProjectLighthouse/Types/Match/RoomSlot.cs @@ -0,0 +1,10 @@ +using LBPUnion.ProjectLighthouse.Types.Levels; + +namespace LBPUnion.ProjectLighthouse.Types.Match +{ + public class RoomSlot + { + public SlotType SlotType; + public int SlotId; + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Types/Match/RoomState.cs b/ProjectLighthouse/Types/Match/RoomState.cs index 2cfc28e2..f3d31406 100644 --- a/ProjectLighthouse/Types/Match/RoomState.cs +++ b/ProjectLighthouse/Types/Match/RoomState.cs @@ -2,10 +2,29 @@ namespace LBPUnion.ProjectLighthouse.Types.Match { public enum RoomState { + /// + /// The room isn't doing anything in particular. + /// Idle = 0, - LookingForPlayersForLevel = 1, + + /// + /// The room is looking to join an existing room playing a specific slot. + /// + DivingIntoLevel = 1, + + /// + /// ??? + /// Unknown = 2, + + /// + /// The room is looking for other rooms to join. + /// DivingIn = 3, + + /// + /// The room is waiting for players to join their room. + /// DivingInWaiting = 4, } } \ No newline at end of file From ba60328eaf29641274a1e9204ff9b7b853d9b914 Mon Sep 17 00:00:00 2001 From: jvyden Date: Tue, 16 Nov 2021 16:10:42 -0500 Subject: [PATCH 02/10] Room creation --- .../Controllers/MatchController.cs | 42 ++++++++++++++++++- ProjectLighthouse/Helpers/RoomHelper.cs | 30 +++++++++++++ ProjectLighthouse/Types/Match/CreateRoom.cs | 8 ++++ ProjectLighthouse/Types/Match/FindBestRoom.cs | 27 +++++++++++- ProjectLighthouse/Types/Match/NatType.cs | 9 ++++ ProjectLighthouse/Types/Match/Room.cs | 2 + .../Types/Match/UpdateMyPlayerData.cs | 5 ++- ProjectLighthouse/Types/User.cs | 21 ++++++++++ 8 files changed, 139 insertions(+), 5 deletions(-) create mode 100644 ProjectLighthouse/Types/Match/NatType.cs 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 From 00e3d2013a293a10bdbbe2d120aeb491d74b731b Mon Sep 17 00:00:00 2001 From: jvyden Date: Tue, 16 Nov 2021 16:37:57 -0500 Subject: [PATCH 03/10] Fix state updating --- .../Controllers/MatchController.cs | 7 +++-- ProjectLighthouse/Helpers/RoomHelper.cs | 28 +++++++++++++++---- ProjectLighthouse/Types/Match/Room.cs | 15 ++++++++++ ProjectLighthouse/Types/User.cs | 4 +-- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/ProjectLighthouse/Controllers/MatchController.cs b/ProjectLighthouse/Controllers/MatchController.cs index 1b19196e..cab8ceeb 100644 --- a/ProjectLighthouse/Controllers/MatchController.cs +++ b/ProjectLighthouse/Controllers/MatchController.cs @@ -135,10 +135,11 @@ namespace LBPUnion.ProjectLighthouse.Controllers 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); + RoomHelper.Rooms.RemoveAll(r => r.Host == user); + + // Create a new one as requested + Room newRoom = RoomHelper.CreateRoom(users, createRoom.RoomSlot); // Remove players in this new room from other rooms foreach (Room room in RoomHelper.Rooms) diff --git a/ProjectLighthouse/Helpers/RoomHelper.cs b/ProjectLighthouse/Helpers/RoomHelper.cs index 9ce5569a..25211547 100644 --- a/ProjectLighthouse/Helpers/RoomHelper.cs +++ b/ProjectLighthouse/Helpers/RoomHelper.cs @@ -17,6 +17,10 @@ namespace LBPUnion.ProjectLighthouse.Helpers SlotId = 0, }; + private static int roomIdIncrement = 0; + + internal static int RoomIdIncrement => roomIdIncrement++ - 1; + public static FindBestRoomResponse? FindBestRoom(User user, string location) { bool anyRoomsLookingForPlayers = Rooms.Any(r => r.IsLookingForPlayers); @@ -99,16 +103,28 @@ namespace LBPUnion.ProjectLighthouse.Helpers ); public static Room CreateRoom(List users, RoomSlot? slot = null) { - Room room = new(); - - room.Players = users; - room.State = RoomState.Idle; - room.Slot = slot ?? PodSlot; + Room room = new() + { + RoomId = RoomIdIncrement, + Players = users, + State = RoomState.Idle, + Slot = slot ?? PodSlot, + }; Rooms.Add(room); return room; } - public static Room? FindRoomByUser(User user) => Rooms.FirstOrDefault(r => r.Players.Contains(user)); + public static Room? FindRoomByUser(User user) + { + foreach (Room room in Rooms) + { + foreach (User player in room.Players) + { + if (user == player) return room; + } + } + return null; + } } } \ No newline at end of file diff --git a/ProjectLighthouse/Types/Match/Room.cs b/ProjectLighthouse/Types/Match/Room.cs index 88e967be..213e565f 100644 --- a/ProjectLighthouse/Types/Match/Room.cs +++ b/ProjectLighthouse/Types/Match/Room.cs @@ -5,6 +5,8 @@ namespace LBPUnion.ProjectLighthouse.Types.Match { public class Room { + public int RoomId; + public List Players; public RoomState State; public RoomSlot Slot; @@ -13,5 +15,18 @@ namespace LBPUnion.ProjectLighthouse.Types.Match public bool IsLookingForPlayers => this.State == RoomState.DivingIntoLevel || this.State == RoomState.DivingInWaiting; public User Host => this.Players[0]; + + #nullable enable + public static bool operator ==(Room? room1, Room? room2) + { + if (ReferenceEquals(room1, room2)) return true; + if ((object?)room1 == null || (object?)room2 == null) return false; + + return room1.RoomId == room2.RoomId; + } + public static bool operator !=(Room? room1, Room? room2) => !(room1 == room2); + + public override int GetHashCode() => this.RoomId; + #nullable disable } } \ No newline at end of file diff --git a/ProjectLighthouse/Types/User.cs b/ProjectLighthouse/Types/User.cs index 6f7f7b6b..9668256d 100644 --- a/ProjectLighthouse/Types/User.cs +++ b/ProjectLighthouse/Types/User.cs @@ -197,10 +197,10 @@ namespace LBPUnion.ProjectLighthouse.Types } [SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalse")] - public static bool operator ==(User user1, User user2) + public static bool operator ==(User? user1, User? user2) { if (ReferenceEquals(user1, user2)) return true; - if ((object)user1 == null || (object)user2 == null) return false; + if ((object?)user1 == null || (object?)user2 == null) return false; return user1.UserId == user2.UserId; } From 92ffcf3c411da1fb9d48d14887213d559d451799 Mon Sep 17 00:00:00 2001 From: jvyden Date: Tue, 16 Nov 2021 17:05:23 -0500 Subject: [PATCH 04/10] Return NotFound when getting null from FindBestRoom --- ProjectLighthouse/Controllers/MatchController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProjectLighthouse/Controllers/MatchController.cs b/ProjectLighthouse/Controllers/MatchController.cs index cab8ceeb..28789b9d 100644 --- a/ProjectLighthouse/Controllers/MatchController.cs +++ b/ProjectLighthouse/Controllers/MatchController.cs @@ -110,7 +110,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers { FindBestRoomResponse? response = RoomHelper.FindBestRoom(user, token.UserLocation); - if (response == null) return this.BadRequest(); + if (response == null) return this.NotFound(); string serialized = JsonSerializer.Serialize(response, typeof(FindBestRoomResponse)); foreach (Player player in response.Players) From e92b1bf2c94e439853c08692dc7d46b4e426f44e Mon Sep 17 00:00:00 2001 From: jvyden Date: Tue, 16 Nov 2021 18:40:03 -0500 Subject: [PATCH 05/10] Fix bad request instead of 403 on getting slots --- .../Controllers/ListController.cs | 4 +-- ProjectLighthouse/Helpers/RoomHelper.cs | 34 +++++++++++++++++-- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/ProjectLighthouse/Controllers/ListController.cs b/ProjectLighthouse/Controllers/ListController.cs index 765582a5..701c9d12 100644 --- a/ProjectLighthouse/Controllers/ListController.cs +++ b/ProjectLighthouse/Controllers/ListController.cs @@ -29,7 +29,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers public async Task GetLevelQueue(string username) { Token? token = await this.database.TokenFromRequest(this.Request); - if (token == null) return this.BadRequest(); + if (token == null) return this.StatusCode(403, ""); GameVersion gameVersion = token.GameVersion; @@ -91,7 +91,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers public async Task GetFavouriteSlots(string username) { Token? token = await this.database.TokenFromRequest(this.Request); - if (token == null) return this.BadRequest(); + if (token == null) return this.StatusCode(403, ""); GameVersion gameVersion = token.GameVersion; diff --git a/ProjectLighthouse/Helpers/RoomHelper.cs b/ProjectLighthouse/Helpers/RoomHelper.cs index 25211547..c2d574d5 100644 --- a/ProjectLighthouse/Helpers/RoomHelper.cs +++ b/ProjectLighthouse/Helpers/RoomHelper.cs @@ -1,5 +1,6 @@ #nullable enable using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using LBPUnion.ProjectLighthouse.Types; using LBPUnion.ProjectLighthouse.Types.Levels; @@ -37,9 +38,12 @@ namespace LBPUnion.ProjectLighthouse.Helpers ( p => { - bool gotValue = MatchHelper.UserLocations.TryGetValue(p.UserId, out string? value) && value != null; + bool gotValue = MatchHelper.UserLocations.TryGetValue(p.UserId, out string? value); - if (gotValue) relevantUserLocations.Add(p.UserId, value!); + if (gotValue && value != null) + { + relevantUserLocations.Add(p.UserId, value); + } return gotValue; } ); @@ -97,7 +101,7 @@ namespace LBPUnion.ProjectLighthouse.Helpers ( new List { - user + user, }, slot ); @@ -112,6 +116,9 @@ namespace LBPUnion.ProjectLighthouse.Helpers }; Rooms.Add(room); + + CleanupRooms(room.Host, room); + return room; } @@ -126,5 +133,26 @@ namespace LBPUnion.ProjectLighthouse.Helpers } return null; } + + [SuppressMessage("ReSharper", "InvertIf")] + public static void CleanupRooms(User? host = null, Room? newRoom = null) + { + // Delete old rooms based on host + if (host != null) + { + Rooms.RemoveAll(r => r.Host == host); + } + + // Remove players in this new room from other rooms + if (newRoom != null) + { + foreach (Room room in Rooms) + { + if (room == newRoom) continue; + + foreach (User newRoomPlayer in newRoom.Players) room.Players.RemoveAll(p => p == newRoomPlayer); + } + } + } } } \ No newline at end of file From a5eb9400feff1636224d78ce74e4ee5d8cc0ee65 Mon Sep 17 00:00:00 2001 From: jvyden Date: Tue, 16 Nov 2021 18:41:18 -0500 Subject: [PATCH 06/10] Create room for user on login --- ProjectLighthouse/Controllers/LoginController.cs | 16 +++++++++++----- ProjectLighthouse/Controllers/MatchController.cs | 13 +------------ ProjectLighthouse/Controllers/SlotsController.cs | 10 +++++----- ProjectLighthouse/Types/User.cs | 2 +- 4 files changed, 18 insertions(+), 23 deletions(-) diff --git a/ProjectLighthouse/Controllers/LoginController.cs b/ProjectLighthouse/Controllers/LoginController.cs index 420f8b17..d3e4df74 100644 --- a/ProjectLighthouse/Controllers/LoginController.cs +++ b/ProjectLighthouse/Controllers/LoginController.cs @@ -3,6 +3,7 @@ using System.IO; using System.Net; using System.Threading.Tasks; using Kettu; +using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Types; using LBPUnion.ProjectLighthouse.Types.Settings; @@ -48,11 +49,16 @@ namespace LBPUnion.ProjectLighthouse.Controllers Token? token = await this.database.AuthenticateUser(loginData, userLocation, titleId); if (token == null) return this.StatusCode(403, ""); - Logger.Log - ( - $"Successfully logged in user {(await this.database.UserFromToken(token))!.Username} as {token.GameVersion} client ({titleId})", - LoggerLevelLogin.Instance - ); + User? user = await this.database.UserFromToken(token); + if (user == null) return this.StatusCode(403, ""); + + Logger.Log($"Successfully logged in user {user.Username} as {token.GameVersion} client ({titleId})", LoggerLevelLogin.Instance); + + // Create a new room on LBP2+/Vita + if (token.GameVersion != GameVersion.LittleBigPlanet1) + { + RoomHelper.CreateRoom(user); + } return this.Ok ( diff --git a/ProjectLighthouse/Controllers/MatchController.cs b/ProjectLighthouse/Controllers/MatchController.cs index 28789b9d..24e6bd6f 100644 --- a/ProjectLighthouse/Controllers/MatchController.cs +++ b/ProjectLighthouse/Controllers/MatchController.cs @@ -135,19 +135,8 @@ namespace LBPUnion.ProjectLighthouse.Controllers else return this.BadRequest(); } - // Delete old rooms based on host - RoomHelper.Rooms.RemoveAll(r => r.Host == user); - // Create a new one as requested - Room newRoom = RoomHelper.CreateRoom(users, createRoom.RoomSlot); - - // 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); - } + RoomHelper.CreateRoom(users, createRoom.RoomSlot); } #endregion diff --git a/ProjectLighthouse/Controllers/SlotsController.cs b/ProjectLighthouse/Controllers/SlotsController.cs index 5b536306..988f63ef 100644 --- a/ProjectLighthouse/Controllers/SlotsController.cs +++ b/ProjectLighthouse/Controllers/SlotsController.cs @@ -27,7 +27,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers public async Task SlotsBy([FromQuery] string u, [FromQuery] int pageStart, [FromQuery] int pageSize) { Token? token = await this.database.TokenFromRequest(this.Request); - if (token == null) return this.BadRequest(); + if (token == null) return this.StatusCode(403, ""); GameVersion gameVersion = token.GameVersion; @@ -71,7 +71,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers if (user == null) return this.StatusCode(403, ""); Token? token = await this.database.TokenFromRequest(this.Request); - if (token == null) return this.BadRequest(); + if (token == null) return this.StatusCode(403, ""); GameVersion gameVersion = token.GameVersion; @@ -95,7 +95,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers public async Task NewestSlots([FromQuery] int pageStart, [FromQuery] int pageSize) { Token? token = await this.database.TokenFromRequest(this.Request); - if (token == null) return this.BadRequest(); + if (token == null) return this.StatusCode(403, ""); GameVersion gameVersion = token.GameVersion; @@ -114,7 +114,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers public async Task TeamPickedSlots([FromQuery] int pageStart, [FromQuery] int pageSize) { Token? token = await this.database.TokenFromRequest(this.Request); - if (token == null) return this.BadRequest(); + if (token == null) return this.StatusCode(403, ""); GameVersion gameVersion = token.GameVersion; @@ -134,7 +134,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers public async Task LuckyDipSlots([FromQuery] int pageStart, [FromQuery] int pageSize, [FromQuery] int seed) { Token? token = await this.database.TokenFromRequest(this.Request); - if (token == null) return this.BadRequest(); + if (token == null) return this.StatusCode(403, ""); GameVersion gameVersion = token.GameVersion; diff --git a/ProjectLighthouse/Types/User.cs b/ProjectLighthouse/Types/User.cs index 9668256d..14de418d 100644 --- a/ProjectLighthouse/Types/User.cs +++ b/ProjectLighthouse/Types/User.cs @@ -204,7 +204,7 @@ namespace LBPUnion.ProjectLighthouse.Types return user1.UserId == user2.UserId; } - public static bool operator !=(User user1, User user2) => !(user1 == user2); + public static bool operator !=(User? user1, User? user2) => !(user1 == user2); public override int GetHashCode() => this.UserId; #nullable disable From 42b4906c2cf3c22a74a53873f1f526501d88e931 Mon Sep 17 00:00:00 2001 From: jvyden Date: Tue, 16 Nov 2021 19:18:29 -0500 Subject: [PATCH 07/10] Dive in works again probably --- .../Controllers/MatchController.cs | 2 +- ProjectLighthouse/Helpers/RoomHelper.cs | 20 +++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/ProjectLighthouse/Controllers/MatchController.cs b/ProjectLighthouse/Controllers/MatchController.cs index 24e6bd6f..94f4fff5 100644 --- a/ProjectLighthouse/Controllers/MatchController.cs +++ b/ProjectLighthouse/Controllers/MatchController.cs @@ -98,10 +98,10 @@ namespace LBPUnion.ProjectLighthouse.Controllers if (matchData is UpdateMyPlayerData playerData) { MatchHelper.SetUserLocation(user.UserId, token.UserLocation); + Room? room = RoomHelper.FindRoomByUser(user, true); if (playerData.RoomState != null) { - Room? room = RoomHelper.FindRoomByUser(user); if (room != null && Equals(room.Host, user)) room.State = (RoomState)playerData.RoomState; } } diff --git a/ProjectLighthouse/Helpers/RoomHelper.cs b/ProjectLighthouse/Helpers/RoomHelper.cs index c2d574d5..e654bed3 100644 --- a/ProjectLighthouse/Helpers/RoomHelper.cs +++ b/ProjectLighthouse/Helpers/RoomHelper.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; +using Kettu; +using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Types; using LBPUnion.ProjectLighthouse.Types.Levels; using LBPUnion.ProjectLighthouse.Types.Match; @@ -20,16 +22,17 @@ namespace LBPUnion.ProjectLighthouse.Helpers private static int roomIdIncrement = 0; - internal static int RoomIdIncrement => roomIdIncrement++ - 1; + internal static int RoomIdIncrement => roomIdIncrement++; public static FindBestRoomResponse? FindBestRoom(User user, string location) { bool anyRoomsLookingForPlayers = Rooms.Any(r => r.IsLookingForPlayers); - // Look for rooms looking for players before moving on to rooms that are idle. - foreach (Room room in Rooms.Where(r => !anyRoomsLookingForPlayers || r.IsLookingForPlayers)) + List rooms = anyRoomsLookingForPlayers ? Rooms.Where(r => anyRoomsLookingForPlayers && r.IsLookingForPlayers).ToList() : Rooms; + foreach (Room room in rooms) + // Look for rooms looking for players before moving on to rooms that are idle. { - if (MatchHelper.DidUserRecentlyDiveInWith(user.UserId, room.Players[0].UserId)) continue; + if (MatchHelper.DidUserRecentlyDiveInWith(user.UserId, room.Host.UserId)) continue; Dictionary relevantUserLocations = new(); @@ -56,6 +59,7 @@ namespace LBPUnion.ProjectLighthouse.Helpers FindBestRoomResponse response = new(); response.Players = new List(); + response.Locations = new List(); foreach (User player in room.Players) { response.Players.Add @@ -115,14 +119,14 @@ namespace LBPUnion.ProjectLighthouse.Helpers Slot = slot ?? PodSlot, }; - Rooms.Add(room); - CleanupRooms(room.Host, room); + Rooms.Add(room); + Logger.Log($"Created room (id: {room.RoomId}) for host {room.Host.Username} (id: {room.Host.UserId})", LoggerLevelMatch.Instance); return room; } - public static Room? FindRoomByUser(User user) + public static Room? FindRoomByUser(User user, bool createIfDoesNotExist = false) { foreach (Room room in Rooms) { @@ -131,7 +135,7 @@ namespace LBPUnion.ProjectLighthouse.Helpers if (user == player) return room; } } - return null; + return createIfDoesNotExist ? CreateRoom(user) : null; } [SuppressMessage("ReSharper", "InvertIf")] From 36b61ddb8c54a3ab5804f70475a0f646973bdc55 Mon Sep 17 00:00:00 2001 From: jvyden Date: Wed, 17 Nov 2021 20:33:45 -0500 Subject: [PATCH 08/10] Add PSP Title Ids and GameVersion --- ProjectLighthouse/Helpers/GameVersionHelper.cs | 10 ++++++++-- ProjectLighthouse/Types/GameVersion.cs | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ProjectLighthouse/Helpers/GameVersionHelper.cs b/ProjectLighthouse/Helpers/GameVersionHelper.cs index ba549839..c3e63be2 100644 --- a/ProjectLighthouse/Helpers/GameVersionHelper.cs +++ b/ProjectLighthouse/Helpers/GameVersionHelper.cs @@ -79,7 +79,12 @@ namespace LBPUnion.ProjectLighthouse.Helpers public static readonly string[] LittleBigPlanetVitaTitleIds = { - "PCSF00021", "PCSA00017", "PCSC00013", "PCSD00006", "PCSA00549", "PCSF00516" + "PCSF00021", "PCSA00017", "PCSC00013", "PCSD00006", "PCSA00549", "PCSF00516", + }; + + public static readonly string[] LittleBigPlanetPSPTitleIds = + { + "NPWR00500", "UCAS40262", "UCES01264", "UCUS98744", "UCJS10107", }; public static GameVersion FromTitleId(string titleId) @@ -88,8 +93,9 @@ namespace LBPUnion.ProjectLighthouse.Helpers if (LittleBigPlanet2TitleIds.Contains(titleId)) return GameVersion.LittleBigPlanet2; if (LittleBigPlanet3TitleIds.Contains(titleId)) return GameVersion.LittleBigPlanet3; if (LittleBigPlanetVitaTitleIds.Contains(titleId)) return GameVersion.LittleBigPlanetVita; + if (LittleBigPlanetPSPTitleIds.Contains(titleId)) return GameVersion.LittleBigPlanetPSP; return GameVersion.LittleBigPlanet1; } } -} +} \ No newline at end of file diff --git a/ProjectLighthouse/Types/GameVersion.cs b/ProjectLighthouse/Types/GameVersion.cs index fd3958fe..c0530d9c 100644 --- a/ProjectLighthouse/Types/GameVersion.cs +++ b/ProjectLighthouse/Types/GameVersion.cs @@ -6,6 +6,7 @@ namespace LBPUnion.ProjectLighthouse.Types LittleBigPlanet2 = 1, LittleBigPlanet3 = 2, LittleBigPlanetVita = 3, + LittleBigPlanetPSP = 4, Unknown = -1, } } \ No newline at end of file From 2c0cc41b2ce05c262aeba0abd957cf12e566eef9 Mon Sep 17 00:00:00 2001 From: jvyden Date: Wed, 17 Nov 2021 20:34:20 -0500 Subject: [PATCH 09/10] Rider bullshit (??? literally what is this) --- .../.idea/git_toolbox_prj.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .idea/.idea.ProjectLighthouse/.idea/git_toolbox_prj.xml diff --git a/.idea/.idea.ProjectLighthouse/.idea/git_toolbox_prj.xml b/.idea/.idea.ProjectLighthouse/.idea/git_toolbox_prj.xml new file mode 100644 index 00000000..b3820067 --- /dev/null +++ b/.idea/.idea.ProjectLighthouse/.idea/git_toolbox_prj.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file From 10935df972889590b092553f8c1980c8d42aa69c Mon Sep 17 00:00:00 2001 From: jvyden Date: Wed, 17 Nov 2021 20:34:32 -0500 Subject: [PATCH 10/10] Update Dockerfile for .NET 6.0 --- ProjectLighthouse.sln.DotSettings | 6 ++++++ ProjectLighthouse/Dockerfile | 7 +++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ProjectLighthouse.sln.DotSettings b/ProjectLighthouse.sln.DotSettings index 9a6134aa..779d9d6e 100644 --- a/ProjectLighthouse.sln.DotSettings +++ b/ProjectLighthouse.sln.DotSettings @@ -77,6 +77,7 @@ MM NAT NP + PSP <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="" Suffix="" Style="aaBb" /></Policy> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> @@ -108,15 +109,20 @@ True True True + True True True True True + True True True True True True + True + True + True True True True \ No newline at end of file diff --git a/ProjectLighthouse/Dockerfile b/ProjectLighthouse/Dockerfile index 3cbdb7a1..cd416564 100644 --- a/ProjectLighthouse/Dockerfile +++ b/ProjectLighthouse/Dockerfile @@ -1,9 +1,8 @@ -FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base +FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base WORKDIR /app -EXPOSE 80 -EXPOSE 443 +EXPOSE 10060 -FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /src COPY ["ProjectLighthouse/ProjectLighthouse.csproj", "ProjectLighthouse/"] RUN dotnet restore "ProjectLighthouse/ProjectLighthouse.csproj"