mirror of
https://github.com/SoDOff-Project/sodoff-mmo.git
synced 2025-10-11 08:18:49 -07:00
fix client stay in room and add Room.Send
- fix client stay in room: - replace Client.JoinRoom and Client.LeaveRoom by Client.SetRoom - do not call Client.LeaveRoom / Client.SetRoom(null) for SheduleDisconnect cases (only quietly remove client from room and the rest do in disconnect realisation) - add Room.Send for send message to all clients in room - replace Room.Client sending loops by calls Room.Send
This commit is contained in:
parent
fa0870784a
commit
82e83722da
@ -35,11 +35,7 @@ class ChatMessageHandler : ICommandHandler {
|
||||
cmd.Add("p", data);
|
||||
|
||||
NetworkPacket packet = NetworkObject.WrapObject(1, 13, cmd).Serialize();
|
||||
foreach (var roomClient in client.Room.Clients) {
|
||||
if (roomClient != client) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
}
|
||||
client.Room.Send(packet, client);
|
||||
|
||||
cmd = new();
|
||||
data = new();
|
||||
|
@ -7,6 +7,6 @@ namespace sodoffmmo.CommandHandlers;
|
||||
[CommandHandler(26)]
|
||||
class ExitHandler : ICommandHandler {
|
||||
public void Handle(Client client, NetworkObject receivedObject) {
|
||||
client.LeaveRoom();
|
||||
client.SetRoom(null);
|
||||
}
|
||||
}
|
||||
|
@ -39,10 +39,7 @@ class GauntletPlayAgainHandler : ICommandHandler
|
||||
client.PlayerData.Uid
|
||||
}, "msg", room.Id);
|
||||
|
||||
foreach (var roomClient in room.Clients) {
|
||||
if (roomClient != client)
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
room.Send(packet, client);
|
||||
room.SendPA(client);
|
||||
}
|
||||
}
|
||||
@ -61,9 +58,7 @@ class GauntletLobbyUserReadyHandler : ICommandHandler
|
||||
client.PlayerData.Uid
|
||||
}, "msg", room.Id);
|
||||
|
||||
foreach (var roomClient in room.Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
room.Send(packet);
|
||||
|
||||
if (room.GetReadyCount() > 1) {
|
||||
packet = Utils.ArrNetworkPacket(new string[] {
|
||||
@ -72,9 +67,7 @@ class GauntletLobbyUserReadyHandler : ICommandHandler
|
||||
client.PlayerData.Uid
|
||||
}, "msg", room.Id);
|
||||
|
||||
foreach (var roomClient in room.Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
room.Send(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -93,9 +86,7 @@ class GauntletLobbyUserNotReadyHandler : ICommandHandler
|
||||
client.PlayerData.Uid
|
||||
}, "msg", room.Id);
|
||||
|
||||
foreach (var roomClient in room.Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
room.Send(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,10 +105,7 @@ class GauntletLevelLoadHandler : ICommandHandler
|
||||
p.Get<string>("1"),
|
||||
p.Get<string>("2") // TODO use size of p.fields - 1
|
||||
}, "msg", room.Id);
|
||||
foreach (var roomClient in room.Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
|
||||
room.Send(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,9 +127,7 @@ class GauntletLevelLoadedHandler : ICommandHandler
|
||||
room.Id.ToString(),
|
||||
(--counter).ToString()
|
||||
}, "msg", room.Id);
|
||||
foreach (var roomClient in room.Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
room.Send(packet);
|
||||
|
||||
timer = new System.Timers.Timer(1500);
|
||||
timer.AutoReset = true;
|
||||
@ -169,9 +155,7 @@ class GauntletLevelLoadedHandler : ICommandHandler
|
||||
timer!.Close();
|
||||
timer = null;
|
||||
}
|
||||
foreach (var roomClient in room.Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
room.Send(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,10 +175,7 @@ class GauntletRelayGameDataHandler : ICommandHandler
|
||||
p.Get<string>("0"),
|
||||
p.Get<string>("1")
|
||||
}, "msg", room.Id);
|
||||
foreach (var roomClient in room.Clients) {
|
||||
if (roomClient != client)
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
room.Send(packet, client);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@ namespace sodoffmmo.CommandHandlers;
|
||||
class GenericMessageHandler : ICommandHandler {
|
||||
public void Handle(Client client, NetworkObject receivedObject) {
|
||||
NetworkPacket packet = NetworkObject.WrapObject(0, 7, receivedObject).Serialize();
|
||||
foreach (var roomClient in client.Room.Clients)
|
||||
roomClient.Send(packet);
|
||||
client.Room.Send(packet);
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ class JoinRoomHandler : ICommandHandler
|
||||
{
|
||||
string roomName = receivedObject.Get<NetworkObject>("p").Get<string>("rn");
|
||||
Room room = Room.GetOrAdd(roomName);
|
||||
Console.WriteLine($"Join Room: {roomName} RoomID: {room.Id} IID: {client.ClientID}");
|
||||
client.JoinRoom(room);
|
||||
client.SetRoom(room);
|
||||
}
|
||||
}
|
||||
|
@ -24,8 +24,6 @@ class RacingPMHandler : ICommandHandler
|
||||
cmd.Add("p", p);
|
||||
NetworkPacket packet = NetworkObject.WrapObject(1, 13, cmd).Serialize();
|
||||
|
||||
foreach (var roomClient in client.Room.Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
client.Room.Send(packet);
|
||||
}
|
||||
}
|
||||
|
@ -58,9 +58,7 @@ class RacingARACKHandler : ICommandHandler
|
||||
|
||||
if (room.GetPlayersCount(RacingPlayerState.RaceReady2) == room.ClientsCount) {
|
||||
NetworkPacket packet = room.GetSTAPacket();
|
||||
foreach (var roomClient in room.Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
room.Send(packet);
|
||||
Console.WriteLine($"STA");
|
||||
}
|
||||
}
|
||||
|
@ -59,11 +59,7 @@ class SetPositionVariablesHandler : ICommandHandler {
|
||||
cmd.Add("c", "SPV");
|
||||
cmd.Add("p", obj);
|
||||
|
||||
|
||||
NetworkPacket packet = NetworkObject.WrapObject(1, 13, cmd).Serialize();
|
||||
foreach (var roomClient in client.Room.Clients) {
|
||||
if (roomClient != client)
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
client.Room.Send(packet, client);
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,12 @@ class SetUserVariablesHandler : ICommandHandler {
|
||||
Client client;
|
||||
string? uid;
|
||||
public void Handle(Client client, NetworkObject receivedObject) {
|
||||
if (client.Room == null) {
|
||||
Console.WriteLine($"SUV Missing Room IID: {client.ClientID}");
|
||||
client.Send(NetworkObject.WrapObject(0, 1006, new NetworkObject()).Serialize());
|
||||
client.SheduleDisconnect();
|
||||
return;
|
||||
}
|
||||
this.client = client;
|
||||
suvData = receivedObject.Get<NetworkObject>("p");
|
||||
uid = suvData.Get<string>("UID");
|
||||
@ -90,8 +96,7 @@ class SetUserVariablesHandler : ICommandHandler {
|
||||
data.Add("vl", vl);
|
||||
|
||||
NetworkPacket packet = NetworkObject.WrapObject(0, 12, data).Serialize();
|
||||
foreach (var roomClient in client.Room.Clients)
|
||||
roomClient.Send(packet);
|
||||
client.Room.Send(packet);
|
||||
|
||||
NetworkObject cmd = new();
|
||||
cmd.Add("c", "SUV");
|
||||
@ -105,10 +110,7 @@ class SetUserVariablesHandler : ICommandHandler {
|
||||
container.Add("arr", arr);
|
||||
cmd.Add("p", container);
|
||||
packet = NetworkObject.WrapObject(1, 13, cmd).Serialize();
|
||||
foreach (var roomClient in client.Room.Clients) {
|
||||
if (roomClient != client)
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
client.Room.Send(packet, client);
|
||||
}
|
||||
|
||||
private void UpdatePlayersInRoom() {
|
||||
@ -129,10 +131,7 @@ class SetUserVariablesHandler : ICommandHandler {
|
||||
NetworkPacket packet = NetworkObject.WrapObject(0, 1000, data).Serialize();
|
||||
packet.Compress();
|
||||
|
||||
foreach (var roomClient in client.Room.Clients) {
|
||||
if (roomClient != client)
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
client.Room.Send(packet, client);
|
||||
}
|
||||
|
||||
private void SendSUVToPlayerInRoom() {
|
||||
@ -144,9 +143,6 @@ class SetUserVariablesHandler : ICommandHandler {
|
||||
cmd.Add("p", obj);
|
||||
|
||||
NetworkPacket packet = NetworkObject.WrapObject(1, 13, cmd).Serialize();
|
||||
foreach (var roomClient in client.Room.Clients) {
|
||||
if (roomClient != client)
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
client.Room.Send(packet, client);
|
||||
}
|
||||
}
|
||||
|
@ -37,9 +37,7 @@ class WorldEventHealthHandler : ICommandHandler {
|
||||
health.ToString("0.0#####", CultureInfo.GetCultureInfo("en-US")) + "," + DateTime.UtcNow.ToString("ddd MMM dd HH:mm:ss UTC yyyy", CultureInfo.GetCultureInfo("en-US")),
|
||||
WorldEvent.Get().GetRoom().Id
|
||||
);
|
||||
foreach (var roomClient in WorldEvent.Get().GetRoom().Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
WorldEvent.Get().GetRoom().Send(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -59,9 +57,7 @@ class WorldEventFlareHandler : ICommandHandler {
|
||||
p.Get<string>("oh") + "," + p.Get<string>("ts"),
|
||||
WorldEvent.Get().GetRoom().Id
|
||||
);
|
||||
foreach (var roomClient in WorldEvent.Get().GetRoom().Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
WorldEvent.Get().GetRoom().Send(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,9 +78,7 @@ class WorldEventMissileHandler : ICommandHandler {
|
||||
p.Get<string>("tID"),
|
||||
p.Get<string>("objID")
|
||||
});
|
||||
foreach (var roomClient in WorldEvent.Get().GetRoom().Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
WorldEvent.Get().GetRoom().Send(packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
using sodoffmmo.Data;
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace sodoffmmo.Core;
|
||||
public class Client {
|
||||
@ -9,12 +10,12 @@ public class Client {
|
||||
|
||||
public int ClientID { get; private set; }
|
||||
public PlayerData PlayerData { get; set; } = new();
|
||||
public Room Room { get; private set; }
|
||||
public Room? Room { get; private set; }
|
||||
|
||||
private readonly Socket socket;
|
||||
SocketBuffer socketBuffer = new();
|
||||
private volatile bool scheduledDisconnect = false;
|
||||
private object ClientLock = new();
|
||||
private readonly object clientLock = new();
|
||||
|
||||
public Client(Socket clientSocket) {
|
||||
socket = clientSocket;
|
||||
@ -39,36 +40,36 @@ public class Client {
|
||||
try {
|
||||
socket.Send(packet.SendData);
|
||||
} catch (SocketException) {
|
||||
LeaveRoom();
|
||||
SheduleDisconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public void LeaveRoom() {
|
||||
if (Room != null) {
|
||||
Console.WriteLine($"Leave room {Room.Name} IID: {ClientID}");
|
||||
Room.RemoveClient(this);
|
||||
NetworkObject data = new();
|
||||
data.Add("r", Room.Id);
|
||||
data.Add("u", ClientID);
|
||||
|
||||
NetworkPacket packet = NetworkObject.WrapObject(0, 1004, data).Serialize();
|
||||
foreach (var roomClient in Room.Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
Room = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void JoinRoom(Room room) {
|
||||
lock(ClientLock) {
|
||||
LeaveRoom();
|
||||
public void SetRoom(Room? room) {
|
||||
lock(clientLock) {
|
||||
// set variable player data as not valid, but do not reset all player data
|
||||
PlayerData.IsValid = false;
|
||||
|
||||
if (Room != null) {
|
||||
Console.WriteLine($"Leave room: {Room.Name} (id={Room.Id}, size={Room.ClientsCount}) IID: {ClientID}");
|
||||
Room.RemoveClient(this);
|
||||
|
||||
NetworkObject data = new();
|
||||
data.Add("r", Room.Id);
|
||||
data.Add("u", ClientID);
|
||||
Room.Send(NetworkObject.WrapObject(0, 1004, data).Serialize());
|
||||
}
|
||||
|
||||
// set new room (null when SetRoom is used as LeaveRoom)
|
||||
Room = room;
|
||||
Room.AddClient(this);
|
||||
|
||||
if (Room != null) {
|
||||
Console.WriteLine($"Join room: {Room.Name} RoomID (id={Room.Id}, size={Room.ClientsCount}) IID: {ClientID}");
|
||||
Room.AddClient(this);
|
||||
|
||||
Send(Room.SubscribeRoom());
|
||||
UpdatePlayerUserVariables();
|
||||
}
|
||||
}
|
||||
Send(Room.SubscribeRoom());
|
||||
UpdatePlayerUserVariables();
|
||||
}
|
||||
|
||||
private void UpdatePlayerUserVariables() {
|
||||
@ -91,6 +92,12 @@ public class Client {
|
||||
}
|
||||
|
||||
public void SheduleDisconnect() {
|
||||
if (Room != null) {
|
||||
// quiet remove from room (to avoid issues in Room.Send)
|
||||
// - do not change Room value here
|
||||
// - full remove will be will take place Server.HandleClient (before real disconnected)
|
||||
Room.RemoveClient(this);
|
||||
}
|
||||
scheduledDisconnect = true;
|
||||
}
|
||||
|
||||
|
@ -65,9 +65,7 @@ public class GauntletRoom : Room {
|
||||
}
|
||||
NetworkPacket packet = Utils.ArrNetworkPacket(info.ToArray(), "msg", base.Id);
|
||||
|
||||
foreach(var player in players) {
|
||||
player.Key.Send(packet);
|
||||
}
|
||||
Send(packet);
|
||||
}
|
||||
|
||||
public void SendPA(Client client) {
|
||||
@ -112,10 +110,7 @@ public class GauntletRoom : Room {
|
||||
}
|
||||
NetworkPacket packet = Utils.ArrNetworkPacket(info.ToArray(), "msg", base.Id);
|
||||
|
||||
foreach(var player in players) {
|
||||
player.Key.Send(packet);
|
||||
}
|
||||
|
||||
Send(packet);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -127,8 +122,8 @@ public class GauntletRoom : Room {
|
||||
if (room is null)
|
||||
room = GauntletRoom.Get();
|
||||
|
||||
room.AddPlayer(client); // must be call before JoinRoom (before InvalidatePlayerData) - we need uid
|
||||
client.JoinRoom(room);
|
||||
client.SetRoom(room);
|
||||
room.AddPlayer(client); // client will be not removed from GauntletRoom.players ... after remove all client from room whole GauntletRoom.players will be removed
|
||||
room.SendUJR();
|
||||
}
|
||||
}
|
||||
|
@ -94,9 +94,7 @@ public class RacingRoom : Room {
|
||||
}
|
||||
|
||||
NetworkPacket packet = Utils.ArrNetworkPacket(info.ToArray(), "", Id);
|
||||
foreach (var roomClient in Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
Send(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,8 +122,7 @@ public class RacingRoom : Room {
|
||||
|
||||
private void SendJoin(Object? source, ElapsedEventArgs e) {
|
||||
foreach(var player in players) {
|
||||
Console.WriteLine($"Join Racing Room: {Name} RoomID: {Id} IID: {player.Key.ClientID}");
|
||||
player.Key.JoinRoom(this);
|
||||
player.Key.SetRoom(this);
|
||||
}
|
||||
SetTimer(1, CountDown, true);
|
||||
}
|
||||
@ -142,9 +139,7 @@ public class RacingRoom : Room {
|
||||
"LT",
|
||||
(--counter).ToString()
|
||||
}, "", Id);
|
||||
foreach (var roomClient in Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
Send(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -167,9 +162,7 @@ public class RacingRoom : Room {
|
||||
"",
|
||||
"ST"
|
||||
}, "", Id);
|
||||
foreach (var roomClient in Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
Send(packet);
|
||||
}
|
||||
|
||||
// TODO StratTimer → kick out to main lobby players without RacingPlayerState.RaceReady1 after timeout, next kick out players without RacingPlayerState.RaceReady2 after timeout2
|
||||
|
@ -66,6 +66,14 @@ public class Room {
|
||||
}
|
||||
}
|
||||
|
||||
public void Send(NetworkPacket packet, Client? skip = null) {
|
||||
foreach (var roomClient in clients) {
|
||||
if (roomClient != skip) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool Exists(string name) => rooms.ContainsKey(name);
|
||||
|
||||
public static Room Get(string name) => rooms[name];
|
||||
@ -99,7 +107,7 @@ public class Room {
|
||||
roomInfo.Add((short)0); // max spectator count
|
||||
|
||||
NetworkArray userList = new();
|
||||
foreach (Client player in Clients) {
|
||||
foreach (Client player in clients) {
|
||||
if (player.PlayerData.Uid != "")
|
||||
userList.Add(player.PlayerData.GetNetworkData(player.ClientID, out _));
|
||||
}
|
||||
|
@ -160,9 +160,7 @@ class WorldEvent {
|
||||
lastResults,
|
||||
room.Id
|
||||
);
|
||||
foreach (var roomClient in room.Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
room.Send(packet);
|
||||
|
||||
NetworkArray vl = new();
|
||||
vl.Add(NetworkArray.VlElement("WE__AI", NetworkArray.NULL));
|
||||
@ -171,9 +169,7 @@ class WorldEvent {
|
||||
vl.Add(NetworkArray.VlElement("WEF_" + t.Key, NetworkArray.NULL));
|
||||
}
|
||||
packet = Utils.VlNetworkPacket(vl, room.Id);
|
||||
foreach (var roomClient in room.Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
room.Send(packet);
|
||||
|
||||
Console.WriteLine($"Event {uid} sent _End");
|
||||
|
||||
@ -206,9 +202,7 @@ class WorldEvent {
|
||||
Console.WriteLine($"Event {uid} send event notification (WE_ = {(WE ? startTimeString : WE)} WEN_ = {(WEN ? nextStartTimeString : WEN)}, room = {room.Id}) to all clients");
|
||||
NetworkPacket packet = Utils.VlNetworkPacket(EventInfoArray(WE, WEN), room.Id);
|
||||
foreach (var r in Room.AllRooms()) {
|
||||
foreach (var roomClient in r.Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
r.Send(packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ public class Server {
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
client.LeaveRoom();
|
||||
client.SetRoom(null);
|
||||
} catch (Exception) { }
|
||||
client.Disconnect();
|
||||
Console.WriteLine("Socket disconnected IID: " + client.ClientID);
|
||||
|
Loading…
x
Reference in New Issue
Block a user