mirror of
https://github.com/LBPUnion/ProjectLighthouse.git
synced 2025-05-03 09:28:21 +00:00
Implement Redis for storing rooms
This commit is contained in:
parent
e998e59607
commit
e12a798fd5
14 changed files with 194 additions and 67 deletions
|
@ -1,5 +1,5 @@
|
||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="Development Database" type="docker-deploy" factoryName="docker-compose.yml"
|
<configuration default="false" name="Development Databases" type="docker-deploy" factoryName="docker-compose.yml"
|
||||||
server-name="Docker">
|
server-name="Docker">
|
||||||
<deployment type="docker-compose.yml">
|
<deployment type="docker-compose.yml">
|
||||||
<settings>
|
<settings>
|
||||||
|
@ -7,6 +7,7 @@
|
||||||
<option name="sourceFilePath" value="docker-compose.yml"/>
|
<option name="sourceFilePath" value="docker-compose.yml"/>
|
||||||
</settings>
|
</settings>
|
||||||
</deployment>
|
</deployment>
|
||||||
|
<EXTENSION ID="com.jetbrains.rider.docker.debug" isFastModeEnabled="true" isPublishEnabled="true"/>
|
||||||
<method v="2"/>
|
<method v="2"/>
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
|
@ -120,7 +120,7 @@ public class LoginController : ControllerBase
|
||||||
await this.database.SaveChangesAsync();
|
await this.database.SaveChangesAsync();
|
||||||
|
|
||||||
// Create a new room on LBP2/3/Vita
|
// Create a new room on LBP2/3/Vita
|
||||||
if (token.GameVersion != GameVersion.LittleBigPlanet1) RoomHelper.CreateRoom(user, token.GameVersion, token.Platform);
|
if (token.GameVersion != GameVersion.LittleBigPlanet1) RoomHelper.CreateRoom(user.UserId, token.GameVersion, token.Platform);
|
||||||
|
|
||||||
return this.Ok
|
return this.Ok
|
||||||
(
|
(
|
||||||
|
|
|
@ -74,10 +74,10 @@ public class MatchController : ControllerBase
|
||||||
if (matchData is UpdateMyPlayerData playerData)
|
if (matchData is UpdateMyPlayerData playerData)
|
||||||
{
|
{
|
||||||
MatchHelper.SetUserLocation(user.UserId, gameToken.UserLocation);
|
MatchHelper.SetUserLocation(user.UserId, gameToken.UserLocation);
|
||||||
Room? room = RoomHelper.FindRoomByUser(user, gameToken.GameVersion, gameToken.Platform, true);
|
Room? room = RoomHelper.FindRoomByUser(user.UserId, gameToken.GameVersion, gameToken.Platform, true);
|
||||||
|
|
||||||
if (playerData.RoomState != null)
|
if (playerData.RoomState != null)
|
||||||
if (room != null && Equals(room.Host, user))
|
if (room != null && Equals(room.HostId, user.UserId))
|
||||||
room.State = (RoomState)playerData.RoomState;
|
room.State = (RoomState)playerData.RoomState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,12 +101,12 @@ public class MatchController : ControllerBase
|
||||||
|
|
||||||
if (matchData is CreateRoom createRoom && MatchHelper.UserLocations.Count >= 1)
|
if (matchData is CreateRoom createRoom && MatchHelper.UserLocations.Count >= 1)
|
||||||
{
|
{
|
||||||
List<User> users = new();
|
List<int> users = new();
|
||||||
foreach (string playerUsername in createRoom.Players)
|
foreach (string playerUsername in createRoom.Players)
|
||||||
{
|
{
|
||||||
User? player = await this.database.Users.FirstOrDefaultAsync(u => u.Username == playerUsername);
|
User? player = await this.database.Users.FirstOrDefaultAsync(u => u.Username == playerUsername);
|
||||||
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
|
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
|
||||||
if (player != null) users.Add(player);
|
if (player != null) users.Add(player.UserId);
|
||||||
else return this.BadRequest();
|
else return this.BadRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ public class MatchController : ControllerBase
|
||||||
|
|
||||||
if (matchData is UpdatePlayersInRoom updatePlayersInRoom)
|
if (matchData is UpdatePlayersInRoom updatePlayersInRoom)
|
||||||
{
|
{
|
||||||
Room? room = RoomHelper.Rooms.FirstOrDefault(r => r.Host == user);
|
Room? room = RoomHelper.Rooms.FirstOrDefault(r => r.HostId == user.UserId);
|
||||||
|
|
||||||
if (room != null)
|
if (room != null)
|
||||||
{
|
{
|
||||||
|
@ -129,7 +129,7 @@ public class MatchController : ControllerBase
|
||||||
else return this.BadRequest();
|
else return this.BadRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
room.Players = users;
|
room.PlayerIds = users.Select(u => u.UserId).ToList();
|
||||||
RoomHelper.CleanupRooms(null, room);
|
RoomHelper.CleanupRooms(null, room);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using LBPUnion.ProjectLighthouse.Extensions;
|
||||||
using LBPUnion.ProjectLighthouse.Helpers;
|
using LBPUnion.ProjectLighthouse.Helpers;
|
||||||
using LBPUnion.ProjectLighthouse.Types;
|
using LBPUnion.ProjectLighthouse.Types;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
@ -22,12 +23,12 @@ public class RoomVisualizerController : ControllerBase
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
return this.NotFound();
|
return this.NotFound();
|
||||||
#else
|
#else
|
||||||
List<User> users = await this.database.Users.OrderByDescending(_ => EF.Functions.Random()).Take(2).ToListAsync();
|
List<int> users = await this.database.Users.OrderByDescending(_ => EF.Functions.Random()).Take(2).Select(u => u.UserId).ToListAsync();
|
||||||
RoomHelper.CreateRoom(users, GameVersion.LittleBigPlanet2, Platform.PS3);
|
RoomHelper.CreateRoom(users, GameVersion.LittleBigPlanet2, Platform.PS3);
|
||||||
|
|
||||||
foreach (User user in users)
|
foreach (int user in users)
|
||||||
{
|
{
|
||||||
MatchHelper.SetUserLocation(user.UserId, "127.0.0.1");
|
MatchHelper.SetUserLocation(user, "127.0.0.1");
|
||||||
}
|
}
|
||||||
return this.Redirect("/debug/roomVisualizer");
|
return this.Redirect("/debug/roomVisualizer");
|
||||||
#endif
|
#endif
|
||||||
|
@ -39,7 +40,7 @@ public class RoomVisualizerController : ControllerBase
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
return this.NotFound();
|
return this.NotFound();
|
||||||
#else
|
#else
|
||||||
RoomHelper.Rooms.RemoveAll(_ => true);
|
RoomHelper.Rooms.DeleteAll();
|
||||||
return this.Redirect("/debug/roomVisualizer");
|
return this.Redirect("/debug/roomVisualizer");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
@page "/debug/roomVisualizer"
|
@page "/debug/roomVisualizer"
|
||||||
|
@using LBPUnion.ProjectLighthouse.Extensions
|
||||||
@using LBPUnion.ProjectLighthouse.Helpers
|
@using LBPUnion.ProjectLighthouse.Helpers
|
||||||
@using LBPUnion.ProjectLighthouse.Types
|
@using LBPUnion.ProjectLighthouse.Types
|
||||||
@using LBPUnion.ProjectLighthouse.Types.Match
|
@using LBPUnion.ProjectLighthouse.Types.Match
|
||||||
|
@ -35,7 +36,7 @@
|
||||||
<meta http-equiv="refresh" content="@refreshSeconds">
|
<meta http-equiv="refresh" content="@refreshSeconds">
|
||||||
</noscript>
|
</noscript>
|
||||||
|
|
||||||
<p>@RoomHelper.Rooms.Count rooms</p>
|
<p>@RoomHelper.Rooms.Count() rooms</p>
|
||||||
|
|
||||||
<a href="/debug/roomVisualizer/createFakeRoom">
|
<a href="/debug/roomVisualizer/createFakeRoom">
|
||||||
<div class="ui blue button">Create Fake Room</div>
|
<div class="ui blue button">Create Fake Room</div>
|
||||||
|
@ -63,7 +64,7 @@
|
||||||
|
|
||||||
@foreach (Room room in RoomHelper.Rooms)
|
@foreach (Room room in RoomHelper.Rooms)
|
||||||
{
|
{
|
||||||
bool userInRoom = room.Players.Select(p => p.Username).Contains(Model.User?.Username);
|
bool userInRoom = room.PlayerIds.Contains(Model.User?.UserId ?? -1);
|
||||||
string color = userInRoom ? "green" : "blue";
|
string color = userInRoom ? "green" : "blue";
|
||||||
<div class="ui @color inverted segment">
|
<div class="ui @color inverted segment">
|
||||||
<h3>Room @room.RoomId</h3>
|
<h3>Room @room.RoomId</h3>
|
||||||
|
@ -73,9 +74,9 @@
|
||||||
<b>You are currently in this room.</b>
|
<b>You are currently in this room.</b>
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
<p>@room.Players.Count players, state is @room.State, version is @room.RoomVersion.ToPrettyString()on paltform @room.RoomPlatform</p>
|
<p>@room.PlayerIds.Count players, state is @room.State, version is @room.RoomVersion.ToPrettyString()on paltform @room.RoomPlatform</p>
|
||||||
<p>Slot type: @room.Slot.SlotType, slot id: @room.Slot.SlotId</p>
|
<p>Slot type: @room.Slot.SlotType, slot id: @room.Slot.SlotId</p>
|
||||||
@foreach (User player in room.Players)
|
@foreach (User player in room.GetPlayers(Model.Database))
|
||||||
{
|
{
|
||||||
<div class="ui segment">@player.Username</div>
|
<div class="ui segment">@player.Username</div>
|
||||||
}
|
}
|
||||||
|
|
27
ProjectLighthouse/Extensions/IRedisCollectionExtensions.cs
Normal file
27
ProjectLighthouse/Extensions/IRedisCollectionExtensions.cs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Redis.OM.Searching;
|
||||||
|
|
||||||
|
namespace LBPUnion.ProjectLighthouse.Extensions;
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "LoopCanBePartlyConvertedToQuery")]
|
||||||
|
public static class IRedisCollectionExtensions
|
||||||
|
{
|
||||||
|
public static void DeleteAll<T>(this IRedisCollection<T> collection, Func<T, bool> predicate)
|
||||||
|
{
|
||||||
|
foreach (T item in collection)
|
||||||
|
{
|
||||||
|
if (!predicate.Invoke(item)) continue;
|
||||||
|
|
||||||
|
collection.DeleteSync(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DeleteAll<T>(this IRedisCollection<T> collection)
|
||||||
|
{
|
||||||
|
foreach (T item in collection)
|
||||||
|
{
|
||||||
|
collection.DeleteSync(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
ProjectLighthouse/Extensions/RoomExtensions.cs
Normal file
25
ProjectLighthouse/Extensions/RoomExtensions.cs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#nullable enable
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using LBPUnion.ProjectLighthouse.Types;
|
||||||
|
using LBPUnion.ProjectLighthouse.Types.Match;
|
||||||
|
|
||||||
|
namespace LBPUnion.ProjectLighthouse.Extensions;
|
||||||
|
|
||||||
|
public static class RoomExtensions
|
||||||
|
{
|
||||||
|
public static List<User> GetPlayers(this Room room, Database database)
|
||||||
|
{
|
||||||
|
List<User> players = new();
|
||||||
|
foreach (int playerId in room.PlayerIds)
|
||||||
|
{
|
||||||
|
User? player = database.Users.FirstOrDefault(p => p.UserId == playerId);
|
||||||
|
Debug.Assert(player != null);
|
||||||
|
|
||||||
|
players.Add(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
return players;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,17 +3,20 @@ using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using LBPUnion.ProjectLighthouse.Extensions;
|
||||||
using LBPUnion.ProjectLighthouse.Logging;
|
using LBPUnion.ProjectLighthouse.Logging;
|
||||||
using LBPUnion.ProjectLighthouse.Types;
|
using LBPUnion.ProjectLighthouse.Types;
|
||||||
using LBPUnion.ProjectLighthouse.Types.Levels;
|
using LBPUnion.ProjectLighthouse.Types.Levels;
|
||||||
using LBPUnion.ProjectLighthouse.Types.Match;
|
using LBPUnion.ProjectLighthouse.Types.Match;
|
||||||
using LBPUnion.ProjectLighthouse.Types.Profiles;
|
using LBPUnion.ProjectLighthouse.Types.Profiles;
|
||||||
|
using Redis.OM;
|
||||||
|
using Redis.OM.Searching;
|
||||||
|
|
||||||
namespace LBPUnion.ProjectLighthouse.Helpers;
|
namespace LBPUnion.ProjectLighthouse.Helpers;
|
||||||
|
|
||||||
public class RoomHelper
|
public class RoomHelper
|
||||||
{
|
{
|
||||||
public static readonly List<Room> Rooms = new();
|
public static readonly IRedisCollection<Room> Rooms = Redis.GetRooms();
|
||||||
|
|
||||||
public static readonly RoomSlot PodSlot = new()
|
public static readonly RoomSlot PodSlot = new()
|
||||||
{
|
{
|
||||||
|
@ -49,14 +52,9 @@ public class RoomHelper
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool anyRoomsLookingForPlayers;
|
IEnumerable<Room> rooms = Rooms;
|
||||||
List<Room> rooms;
|
|
||||||
|
|
||||||
lock(Rooms)
|
rooms = rooms.OrderBy(r => r.IsLookingForPlayers);
|
||||||
{
|
|
||||||
anyRoomsLookingForPlayers = Rooms.Any(r => r.IsLookingForPlayers);
|
|
||||||
rooms = anyRoomsLookingForPlayers ? Rooms.Where(r => anyRoomsLookingForPlayers && r.IsLookingForPlayers).ToList() : Rooms;
|
|
||||||
}
|
|
||||||
|
|
||||||
rooms = rooms.Where(r => r.RoomVersion == roomVersion).ToList();
|
rooms = rooms.Where(r => r.RoomVersion == roomVersion).ToList();
|
||||||
if (platform != null) rooms = rooms.Where(r => r.RoomPlatform == platform).ToList();
|
if (platform != null) rooms = rooms.Where(r => r.RoomPlatform == platform).ToList();
|
||||||
|
@ -72,24 +70,24 @@ public class RoomHelper
|
||||||
// Don't attempt to dive into the current room the player is in.
|
// Don't attempt to dive into the current room the player is in.
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
rooms = rooms.Where(r => !r.Players.Contains(user)).ToList();
|
rooms = rooms.Where(r => !r.PlayerIds.Contains(user.UserId)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Room room in rooms)
|
foreach (Room room in rooms)
|
||||||
// Look for rooms looking for players before moving on to rooms that are idle.
|
// Look for rooms looking for players before moving on to rooms that are idle.
|
||||||
{
|
{
|
||||||
if (user != null && MatchHelper.DidUserRecentlyDiveInWith(user.UserId, room.Host.UserId)) continue;
|
if (user != null && MatchHelper.DidUserRecentlyDiveInWith(user.UserId, room.HostId)) continue;
|
||||||
|
|
||||||
Dictionary<int, string> relevantUserLocations = new();
|
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
|
// 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
|
bool allPlayersHaveLocations = room.PlayerIds.All
|
||||||
(
|
(
|
||||||
p =>
|
p =>
|
||||||
{
|
{
|
||||||
bool gotValue = MatchHelper.UserLocations.TryGetValue(p.UserId, out string? value);
|
bool gotValue = MatchHelper.UserLocations.TryGetValue(p, out string? value);
|
||||||
|
|
||||||
if (gotValue && value != null) relevantUserLocations.Add(p.UserId, value);
|
if (gotValue && value != null) relevantUserLocations.Add(p, value);
|
||||||
return gotValue;
|
return gotValue;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -104,7 +102,7 @@ public class RoomHelper
|
||||||
|
|
||||||
response.Players = new List<Player>();
|
response.Players = new List<Player>();
|
||||||
response.Locations = new List<string>();
|
response.Locations = new List<string>();
|
||||||
foreach (User player in room.Players)
|
foreach (User player in room.GetPlayers(new Database()))
|
||||||
{
|
{
|
||||||
response.Players.Add
|
response.Players.Add
|
||||||
(
|
(
|
||||||
|
@ -147,74 +145,82 @@ public class RoomHelper
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Room CreateRoom(User user, GameVersion roomVersion, Platform roomPlatform, RoomSlot? slot = null)
|
public static Room CreateRoom(int userId, GameVersion roomVersion, Platform roomPlatform, RoomSlot? slot = null)
|
||||||
=> CreateRoom
|
=> CreateRoom
|
||||||
(
|
(
|
||||||
new List<User>
|
new List<int>
|
||||||
{
|
{
|
||||||
user,
|
userId,
|
||||||
},
|
},
|
||||||
roomVersion,
|
roomVersion,
|
||||||
roomPlatform,
|
roomPlatform,
|
||||||
slot
|
slot
|
||||||
);
|
);
|
||||||
public static Room CreateRoom(List<User> users, GameVersion roomVersion, Platform roomPlatform, RoomSlot? slot = null)
|
public static Room CreateRoom(List<int> users, GameVersion roomVersion, Platform roomPlatform, RoomSlot? slot = null)
|
||||||
{
|
{
|
||||||
Room room = new()
|
Room room = new()
|
||||||
{
|
{
|
||||||
RoomId = RoomIdIncrement,
|
RoomId = RoomIdIncrement,
|
||||||
Players = users,
|
PlayerIds = users,
|
||||||
State = RoomState.Idle,
|
State = RoomState.Idle,
|
||||||
Slot = slot ?? PodSlot,
|
Slot = slot ?? PodSlot,
|
||||||
RoomVersion = roomVersion,
|
RoomVersion = roomVersion,
|
||||||
RoomPlatform = roomPlatform,
|
RoomPlatform = roomPlatform,
|
||||||
};
|
};
|
||||||
|
|
||||||
CleanupRooms(room.Host, room);
|
CleanupRooms(room.HostId, room);
|
||||||
lock(Rooms) Rooms.Add(room);
|
lock(Rooms) Rooms.Insert(room);
|
||||||
Logger.LogInfo($"Created room (id: {room.RoomId}) for host {room.Host.Username} (id: {room.Host.UserId})", LogArea.Match);
|
Logger.LogInfo($"Created room (id: {room.RoomId}) for host {room.HostId}", LogArea.Match);
|
||||||
|
|
||||||
return room;
|
return room;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Room? FindRoomByUser(User user, GameVersion roomVersion, Platform roomPlatform, bool createIfDoesNotExist = false)
|
public static Room? FindRoomByUser(int userId, GameVersion roomVersion, Platform roomPlatform, bool createIfDoesNotExist = false)
|
||||||
{
|
{
|
||||||
lock(Rooms)
|
lock(Rooms)
|
||||||
foreach (Room room in Rooms.Where(room => room.Players.Any(player => user == player)))
|
foreach (Room room in Rooms.Where(room => room.PlayerIds.Any(player => userId == player)))
|
||||||
return room;
|
return room;
|
||||||
|
|
||||||
return createIfDoesNotExist ? CreateRoom(user, roomVersion, roomPlatform) : null;
|
return createIfDoesNotExist ? CreateRoom(userId, roomVersion, roomPlatform) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Room? FindRoomByUserId(int userId)
|
public static Room? FindRoomByUserId(int userId)
|
||||||
{
|
{
|
||||||
lock(Rooms)
|
lock(Rooms)
|
||||||
foreach (Room room in Rooms.Where(room => room.Players.Any(player => player.UserId == userId)))
|
foreach (Room room in Rooms)
|
||||||
return room;
|
{
|
||||||
|
if (room.PlayerIds.Any(p => p == userId))
|
||||||
|
{
|
||||||
|
return room;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "InvertIf")]
|
[SuppressMessage("ReSharper", "InvertIf")]
|
||||||
public static void CleanupRooms(User? host = null, Room? newRoom = null)
|
public static void CleanupRooms(int? hostId = null, Room? newRoom = null, Database? database = null)
|
||||||
{
|
{
|
||||||
|
// return;
|
||||||
lock(Rooms)
|
lock(Rooms)
|
||||||
{
|
{
|
||||||
int roomCountBeforeCleanup = Rooms.Count;
|
int roomCountBeforeCleanup = Rooms.Count();
|
||||||
|
|
||||||
// Remove offline players from rooms
|
// Remove offline players from rooms
|
||||||
foreach (Room room in Rooms)
|
foreach (Room room in Rooms)
|
||||||
{
|
{
|
||||||
// do not shorten, this prevents collection modified errors
|
List<User> players = room.GetPlayers(database ?? new Database());
|
||||||
List<User> playersToRemove = room.Players.Where(player => player.Status.StatusType == StatusType.Offline).ToList();
|
|
||||||
foreach (User user in playersToRemove) room.Players.Remove(user);
|
List<int> playersToRemove = players.Where(player => player.Status.StatusType == StatusType.Offline).Select(player => player.UserId).ToList();
|
||||||
|
|
||||||
|
foreach (int player in playersToRemove) room.PlayerIds.Remove(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete old rooms based on host
|
// Delete old rooms based on host
|
||||||
if (host != null)
|
if (hostId != null)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Rooms.RemoveAll(r => r.Host == host);
|
Rooms.DeleteAll(r => r.HostId == hostId);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
@ -227,13 +233,13 @@ public class RoomHelper
|
||||||
{
|
{
|
||||||
if (room == newRoom) continue;
|
if (room == newRoom) continue;
|
||||||
|
|
||||||
foreach (User newRoomPlayer in newRoom.Players) room.Players.RemoveAll(p => p == newRoomPlayer);
|
foreach (int newRoomPlayer in newRoom.PlayerIds) room.PlayerIds.RemoveAll(p => p == newRoomPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rooms.RemoveAll(r => r.Players.Count == 0); // Remove empty rooms
|
Rooms.DeleteAll(r => r.PlayerIds.Count == 0); // Remove empty rooms
|
||||||
Rooms.RemoveAll(r => r.Players.Count > 4); // Remove obviously bogus rooms
|
Rooms.DeleteAll(r => r.PlayerIds.Count > 4); // Remove obviously bogus rooms
|
||||||
|
|
||||||
int roomCountAfterCleanup = Rooms.Count;
|
int roomCountAfterCleanup = Rooms.Count();
|
||||||
|
|
||||||
if (roomCountBeforeCleanup != roomCountAfterCleanup)
|
if (roomCountBeforeCleanup != roomCountAfterCleanup)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,4 +18,5 @@ public enum LogArea
|
||||||
Photos,
|
Photos,
|
||||||
Resources,
|
Resources,
|
||||||
Logger,
|
Logger,
|
||||||
|
Redis,
|
||||||
}
|
}
|
41
ProjectLighthouse/Redis.cs
Normal file
41
ProjectLighthouse/Redis.cs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using LBPUnion.ProjectLighthouse.Logging;
|
||||||
|
using LBPUnion.ProjectLighthouse.Types.Match;
|
||||||
|
using LBPUnion.ProjectLighthouse.Types.Settings;
|
||||||
|
using Redis.OM;
|
||||||
|
using Redis.OM.Contracts;
|
||||||
|
using Redis.OM.Searching;
|
||||||
|
|
||||||
|
namespace LBPUnion.ProjectLighthouse;
|
||||||
|
|
||||||
|
public static class Redis
|
||||||
|
{
|
||||||
|
private static readonly RedisConnectionProvider provider;
|
||||||
|
|
||||||
|
static Redis()
|
||||||
|
{
|
||||||
|
provider = new RedisConnectionProvider(ServerConfiguration.Instance.RedisConnectionString);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool initialized = false;
|
||||||
|
public static async Task Initialize()
|
||||||
|
{
|
||||||
|
if (initialized) throw new InvalidOperationException("Redis has already been initialized.");
|
||||||
|
|
||||||
|
IRedisConnection connection = getConnection();
|
||||||
|
|
||||||
|
await connection.CreateIndexAsync(typeof(Room));
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
Logger.LogSuccess("Initialized Redis.", LogArea.Redis);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IRedisConnection getConnection()
|
||||||
|
{
|
||||||
|
Logger.LogDebug("Getting a redis connection", LogArea.Redis);
|
||||||
|
return provider.Connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IRedisCollection<Room> GetRooms() => provider.RedisCollection<Room>();
|
||||||
|
}
|
|
@ -76,6 +76,9 @@ public static class StartupTasks
|
||||||
Logger.LogInfo("Starting room cleanup thread...", LogArea.Startup);
|
Logger.LogInfo("Starting room cleanup thread...", LogArea.Startup);
|
||||||
RoomHelper.StartCleanupThread();
|
RoomHelper.StartCleanupThread();
|
||||||
|
|
||||||
|
Logger.LogInfo("Initializing Redis...", LogArea.Startup);
|
||||||
|
Redis.Initialize().Wait();
|
||||||
|
|
||||||
stopwatch.Stop();
|
stopwatch.Stop();
|
||||||
Logger.LogSuccess($"Ready! Startup took {stopwatch.ElapsedMilliseconds}ms. Passing off control to ASP.NET...", LogArea.Startup);
|
Logger.LogSuccess($"Ready! Startup took {stopwatch.ElapsedMilliseconds}ms. Passing off control to ASP.NET...", LogArea.Startup);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +1,47 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using LBPUnion.ProjectLighthouse.Types.Levels;
|
using Redis.OM.Modeling;
|
||||||
|
|
||||||
namespace LBPUnion.ProjectLighthouse.Types.Match;
|
namespace LBPUnion.ProjectLighthouse.Types.Match;
|
||||||
|
|
||||||
|
[Document(StorageType = StorageType.Json)]
|
||||||
public class Room
|
public class Room
|
||||||
{
|
{
|
||||||
[JsonIgnore]
|
private int roomId;
|
||||||
public List<User> Players { get; set; }
|
|
||||||
|
|
||||||
public int RoomId { get; set; }
|
public int RoomId {
|
||||||
|
get => this.roomId;
|
||||||
|
set {
|
||||||
|
this.RedisId = value.ToString();
|
||||||
|
this.roomId = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[JsonIgnore]
|
[RedisIdField]
|
||||||
|
public string RedisId { get; set; }
|
||||||
|
|
||||||
|
[Indexed]
|
||||||
|
public List<int> PlayerIds { get; set; }
|
||||||
|
|
||||||
|
[Indexed]
|
||||||
public GameVersion RoomVersion { get; set; }
|
public GameVersion RoomVersion { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[Indexed]
|
||||||
public Platform RoomPlatform { get; set; }
|
public Platform RoomPlatform { get; set; }
|
||||||
|
|
||||||
|
[Indexed]
|
||||||
public RoomSlot Slot { get; set; }
|
public RoomSlot Slot { get; set; }
|
||||||
|
|
||||||
|
[Indexed]
|
||||||
public RoomState State { get; set; }
|
public RoomState State { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public bool IsInPod => this.Slot.SlotType == SlotType.Pod;
|
[Indexed]
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
public bool IsLookingForPlayers => this.State == RoomState.PlayingLevel || this.State == RoomState.DivingInWaiting;
|
public bool IsLookingForPlayers => this.State == RoomState.PlayingLevel || this.State == RoomState.DivingInWaiting;
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public User Host => this.Players[0];
|
public int HostId => this.PlayerIds[0];
|
||||||
|
|
||||||
public int PlayerCount => this.Players.Count;
|
|
||||||
|
|
||||||
#nullable enable
|
#nullable enable
|
||||||
public override bool Equals(object? obj)
|
public override bool Equals(object? obj)
|
||||||
|
|
|
@ -22,7 +22,7 @@ public class ServerConfiguration
|
||||||
// You can use an ObsoleteAttribute instead. Make sure you set it to error, though.
|
// You can use an ObsoleteAttribute instead. Make sure you set it to error, though.
|
||||||
//
|
//
|
||||||
// Thanks for listening~
|
// Thanks for listening~
|
||||||
public const int CurrentConfigVersion = 3;
|
public const int CurrentConfigVersion = 4;
|
||||||
|
|
||||||
#region Meta
|
#region Meta
|
||||||
|
|
||||||
|
@ -170,6 +170,7 @@ public class ServerConfiguration
|
||||||
public string ApiListenUrl { get; set; } = "http://localhost:10062";
|
public string ApiListenUrl { get; set; } = "http://localhost:10062";
|
||||||
|
|
||||||
public string DbConnectionString { get; set; } = "server=127.0.0.1;uid=root;pwd=lighthouse;database=lighthouse";
|
public string DbConnectionString { get; set; } = "server=127.0.0.1;uid=root;pwd=lighthouse;database=lighthouse";
|
||||||
|
public string RedisConnectionString { get; set; } = "";
|
||||||
public string ExternalUrl { get; set; } = "http://localhost:10060";
|
public string ExternalUrl { get; set; } = "http://localhost:10060";
|
||||||
public bool ConfigReloading { get; set; }
|
public bool ConfigReloading { get; set; }
|
||||||
public string EulaText { get; set; } = "";
|
public string EulaText { get; set; } = "";
|
||||||
|
|
|
@ -14,6 +14,15 @@ services:
|
||||||
- '3306' # Expose port to localhost:3306
|
- '3306' # Expose port to localhost:3306
|
||||||
volumes:
|
volumes:
|
||||||
- lighthouse-db:/var/lib/mysql
|
- lighthouse-db:/var/lib/mysql
|
||||||
|
lighthouse-redis:
|
||||||
|
image: redis/redis-stack
|
||||||
|
ports:
|
||||||
|
- '6379:6379'
|
||||||
|
- '8001:8001'
|
||||||
|
expose:
|
||||||
|
- '6379'
|
||||||
|
- '8001'
|
||||||
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
lighthouse-db:
|
lighthouse-db:
|
Loading…
Add table
Add a link
Reference in a new issue