RoomHelper.FindBestRoom

This commit is contained in:
jvyden 2021-11-16 13:41:34 -05:00
parent 740a7f7803
commit 198c438abc
No known key found for this signature in database
GPG key ID: 18BCF2BE0262B278
8 changed files with 157 additions and 60 deletions

View file

@ -72,6 +72,7 @@
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForBuiltInTypes/@EntryValue">UseExplicitType</s:String> <s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForBuiltInTypes/@EntryValue">UseExplicitType</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForOtherTypes/@EntryValue">UseExplicitType</s:String> <s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForOtherTypes/@EntryValue">UseExplicitType</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForSimpleTypes/@EntryValue">UseExplicitType</s:String> <s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForSimpleTypes/@EntryValue">UseExplicitType</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DLC/@EntryIndexedValue">DLC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LBP/@EntryIndexedValue">LBP</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LBP/@EntryIndexedValue">LBP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MM/@EntryIndexedValue">MM</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MM/@EntryIndexedValue">MM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NAT/@EntryIndexedValue">NAT</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NAT/@EntryIndexedValue">NAT</s:String>

View file

@ -71,33 +71,6 @@ namespace LBPUnion.ProjectLighthouse.Controllers
#endregion #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 #region Update LastMatch
LastMatch? lastMatch = await this.database.LastMatches.Where(l => l.UserId == user.UserId).FirstOrDefaultAsync(); LastMatch? lastMatch = await this.database.LastMatches.Where(l => l.UserId == user.UserId).FirstOrDefaultAsync();
@ -119,6 +92,27 @@ namespace LBPUnion.ProjectLighthouse.Controllers
#endregion #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}]"); return this.Ok("[{\"StatusCode\":200}]");
} }
} }

View file

@ -39,37 +39,6 @@ namespace LBPUnion.ProjectLighthouse.Helpers
return recentlyDivedIn.Contains(otherUserId); return recentlyDivedIn.Contains(otherUserId);
} }
public static FindBestRoomResponse FindBestRoomResponse(string username, string otherUsername, string location, string otherLocation)
=> new()
{
Players = new List<Player>
{
new()
{
MatchingRes = 0,
PlayerId = otherUsername,
},
new()
{
MatchingRes = 1,
PlayerId = username,
},
},
Locations = new List<string>
{
location,
otherLocation,
},
Slots = new List<List<int>>
{
new()
{
5,
0,
},
},
};
public static IMatchData? Deserialize(string data) public static IMatchData? Deserialize(string data)
{ {
string matchType = ""; string matchType = "";

View file

@ -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<Room> 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<int, string> 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<Player>();
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<List<int>>
{
new()
{
(int)room.Slot.SlotType,
room.Slot.SlotId,
},
};
return response;
}
return null;
}
}
}

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace LBPUnion.ProjectLighthouse.Types.Match namespace LBPUnion.ProjectLighthouse.Types.Match
@ -6,7 +7,11 @@ namespace LBPUnion.ProjectLighthouse.Types.Match
[Serializable] [Serializable]
public class Player 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")] [JsonPropertyName("matching_res")]
public int MatchingRes { get; set; } public int MatchingRes { get; set; }

View file

@ -0,0 +1,15 @@
using System.Collections.Generic;
using LBPUnion.ProjectLighthouse.Types.Levels;
namespace LBPUnion.ProjectLighthouse.Types.Match
{
public class Room
{
public List<User> 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;
}
}

View file

@ -0,0 +1,10 @@
using LBPUnion.ProjectLighthouse.Types.Levels;
namespace LBPUnion.ProjectLighthouse.Types.Match
{
public class RoomSlot
{
public SlotType SlotType;
public int SlotId;
}
}

View file

@ -2,10 +2,29 @@ namespace LBPUnion.ProjectLighthouse.Types.Match
{ {
public enum RoomState public enum RoomState
{ {
/// <summary>
/// The room isn't doing anything in particular.
/// </summary>
Idle = 0, Idle = 0,
LookingForPlayersForLevel = 1,
/// <summary>
/// The room is looking to join an existing room playing a specific slot.
/// </summary>
DivingIntoLevel = 1,
/// <summary>
/// ???
/// </summary>
Unknown = 2, Unknown = 2,
/// <summary>
/// The room is looking for other rooms to join.
/// </summary>
DivingIn = 3, DivingIn = 3,
/// <summary>
/// The room is waiting for players to join their room.
/// </summary>
DivingInWaiting = 4, DivingInWaiting = 4,
} }
} }