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