From c35226cc4e5dec6f4e2e8c6c6bd61f9efd9267cc Mon Sep 17 00:00:00 2001 From: Robert Paciorek Date: Fri, 1 Mar 2024 23:27:17 +0000 Subject: [PATCH] fix lobby players list and racing room management --- src/Core/GauntletRoom.cs | 41 ++++++++++++++++++++-------------------- src/Core/Racing.cs | 37 +++++++++++++++--------------------- src/Core/Room.cs | 22 +++++++++++++++++---- 3 files changed, 53 insertions(+), 47 deletions(-) diff --git a/src/Core/GauntletRoom.cs b/src/Core/GauntletRoom.cs index d427271..de62ff9 100644 --- a/src/Core/GauntletRoom.cs +++ b/src/Core/GauntletRoom.cs @@ -3,28 +3,23 @@ using sodoffmmo.Data; namespace sodoffmmo.Core; public class GauntletRoom : Room { - static List GauntletRooms = new(); + static GauntletRoom NextRoom = null; public static GauntletRoom Get() { - foreach (var room in GauntletRooms) { - if (room.ClientsCount < 2) { - lock (room.roomLock) { - if (room.ClientsCount == 0) - room.players.Clear(); - } - return room; - } + if (NextRoom != null && NextRoom.ClientsCount == 1) { + var ret = NextRoom; + NextRoom = null; + return ret; + } else { + NextRoom = new GauntletRoom(); + return NextRoom; } - var newroom = new GauntletRoom("GauntletDO" + "_" + GauntletRooms.Count.ToString()); - GauntletRooms.Add(newroom); - return newroom; } - public GauntletRoom(string name) : base (name, "GauntletDO") { + public GauntletRoom(string name = null) : base (name, "GauntletDO", true) { base.RoomVariables.Add(NetworkArray.VlElement("IS_RACE_ROOM", true)); } - class Status { public string uid; public bool isReady = false; @@ -119,13 +114,17 @@ public class GauntletRoom : Room { return true; } } - - static public void Join(Client client, GauntletRoom room = null) { - if (room is null) - room = GauntletRoom.Get(); - room.AddPlayer(client); // must be call before JoinRoom (before InvalidatePlayerData) - we need uid - client.JoinRoom(room); - room.SendUJR(); + static object joinLock = new object(); + + static public void Join(Client client, GauntletRoom room = null) { + lock(joinLock) { + if (room is null) + room = GauntletRoom.Get(); + + room.AddPlayer(client); // must be call before JoinRoom (before InvalidatePlayerData) - we need uid + client.JoinRoom(room); + room.SendUJR(); + } } } diff --git a/src/Core/Racing.cs b/src/Core/Racing.cs index 7ba4966..c17b3d7 100644 --- a/src/Core/Racing.cs +++ b/src/Core/Racing.cs @@ -13,26 +13,13 @@ public enum RacingPlayerState { } public class RacingRoom : Room { - static List RacingRooms = new(); static Random random = new Random(); public static RacingRoom Get() { - foreach (var room in RacingRooms) { - if (room.ClientsCount == 0) { - room.Reset(); - return room; - } - } - var newroom = new RacingRoom("RacingDragon" + "_" + RacingRooms.Count.ToString()); - RacingRooms.Add(newroom); - return newroom; + return new RacingRoom(); } - public RacingRoom(string name, int? trackId = null) : base (name, "RacingDragon") { - Reset(trackId); - } - - private void Reset(int? trackId = null) { + public RacingRoom(string name = null, int? trackId = null) : base (name, "RacingDragon", true) { if (trackId is null) { TID = random.Next(105); } else { @@ -47,7 +34,7 @@ public class RacingRoom : Room { base.RoomVariables.Add(NetworkArray.VlElement("IS_RACE_ROOM", "SINGLERACE#1#1#SINGLERACE#0#2")); base.RoomVariables.Add(NetworkArray.VlElement("TID", TID)); } - + public int TID; // players ready status @@ -267,7 +254,6 @@ public class RacingLobby { lock (lobbyLock) { if (GetPlayersCount(RacingPlayerState.Ready) >= Configuration.ServerConfiguration.RacingMinPlayers) { int i = 0; - List toRemove = new(); RacingRoom room = RacingRoom.Get(); foreach (var player in lobbyPlayers) { if (player.Value.state == RacingPlayerState.Ready) { @@ -284,12 +270,9 @@ public class RacingLobby { } } // join clients to racing room and start countdown + // after change room, client will be removed from lobbyPlayers (in GetPS) room.Init(); - foreach (var player in toRemove) { - lobbyPlayers.Remove(player); - } - return true; } return false; @@ -297,16 +280,26 @@ public class RacingLobby { } public static NetworkPacket GetPS() { + List toRemove = new(); + Room room = Room.Get("DragonRacingDO"); + // {"a":13,"c":1,"p":{"c":"PS","p":{"arr":["RA","","PS","e6147216-8100-4552-864d-be8f1347e201","8cb5842d-735a-4259-80af-e2e204b9c2bd"]}}} List info = new(); info.Add("RA"); info.Add(""); info.Add("PS"); foreach(var player in lobbyPlayers) { - if (player.Value.state != RacingPlayerState.InRacingRoom) { + if (player.Key.Room != room) { + toRemove.Add(player.Key); + } else if (player.Value.state != RacingPlayerState.InRacingRoom) { info.Add(player.Value.uid); } } + + foreach (var player in toRemove) { + lobbyPlayers.Remove(player); + } + return Utils.ArrNetworkPacket(info.ToArray(), "PS"); } } diff --git a/src/Core/Room.cs b/src/Core/Room.cs index 0007adb..7fc3c40 100644 --- a/src/Core/Room.cs +++ b/src/Core/Room.cs @@ -3,7 +3,8 @@ using sodoffmmo.Data; namespace sodoffmmo.Core; public class Room { - static Dictionary rooms = new(); + public static int MaxId { get; private set; } = 2; + protected static Dictionary rooms = new(); List clients = new(); protected object roomLock = new object(); @@ -11,16 +12,23 @@ public class Room { public int Id { get; private set; } public string Name { get; private set; } public string Group { get; private set; } + public bool AutoRemove { get; private set; } + public bool IsRemoved { get; private set; } = false; public NetworkArray RoomVariables = new(); - public Room(string name, string group = null) { - Id = rooms.Count + 3; - Name = name; + public Room(string name, string group = null, bool autoRemove = false) { + Id = ++MaxId; + if (name is null) { + Name = group + "_" + MaxId; + } else { + Name = name; + } if (group is null) { Group = name; } else { Group = group; } + AutoRemove = autoRemove; rooms.Add(Name, this); } @@ -38,6 +46,8 @@ public class Room { public void AddClient(Client client) { lock (roomLock) { + if (IsRemoved) + throw new Exception("Call AddClient on removed room"); client.Send(RespondJoinRoom()); // NOTE: send RespondJoinRoom() and add client to clients as atomic operation // to make sure to client get full list of players in room @@ -48,6 +58,10 @@ public class Room { public void RemoveClient(Client client) { lock (roomLock) { clients.Remove(client); + if (AutoRemove && ClientsCount == 0) { + IsRemoved = true; + rooms.Remove(Name); + } } }