From 6512518fb72c6c15829ce2b6052062a5cac2a4ce Mon Sep 17 00:00:00 2001 From: Sem van der Hoeven Date: Fri, 23 Oct 2020 14:30:16 +0200 Subject: [PATCH 1/3] [FIX] made first user in lobby a host if the host leaves --- Server/Models/ServerCommunication.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Server/Models/ServerCommunication.cs b/Server/Models/ServerCommunication.cs index e55c835..e70d376 100644 --- a/Server/Models/ServerCommunication.cs +++ b/Server/Models/ServerCommunication.cs @@ -142,7 +142,7 @@ namespace Server.Models { foreach (ServerClient sc in serverClientsInlobbies[l]) { - Debug.WriteLine("[SERVERCLIENT] Sending message"); + Debug.WriteLine("[SERVERCLIENT] Sending message to lobby"); sc.sendMessage(message); } break; @@ -261,6 +261,10 @@ namespace Server.Models break; } } + if (l.Users.Count != 0) + { + l.Users[0].Host = true; + } break; } } From bf09dba8503c55483507d274e1592df968d75dae Mon Sep 17 00:00:00 2001 From: Sem van der Hoeven Date: Fri, 23 Oct 2020 15:44:18 +0200 Subject: [PATCH 2/3] [ADD] added timer start on next round message receive --- Client/Client.cs | 11 ++++++++ Server/Models/ServerClient.cs | 39 ++++++++++++++++++++++++++-- Server/Models/ServerCommunication.cs | 16 ++++++++++++ SharedClientServer/JSONConvert.cs | 22 +++++++++++++--- 4 files changed, 83 insertions(+), 5 deletions(-) diff --git a/Client/Client.cs b/Client/Client.cs index d3788f3..fd54caa 100644 --- a/Client/Client.cs +++ b/Client/Client.cs @@ -210,6 +210,17 @@ namespace Client default: Debug.WriteLine("[CLIENT] Received weird identifier: " + id); break; + case JSONConvert.GAME: + switch (JSONConvert.GetGameCommand(payload)) + { + case JSONConvert.GameCommand.TIMER_ELAPSED: + int lobbyElapsedID = JSONConvert.GetLobbyID(payload); + + //todo set next round + break; + + } + break; } SendMessage(JSONConvert.GetMessageToSend(JSONConvert.MESSAGE_RECEIVED,null)); diff --git a/Server/Models/ServerClient.cs b/Server/Models/ServerClient.cs index 57bb6cb..8af3a86 100644 --- a/Server/Models/ServerClient.cs +++ b/Server/Models/ServerClient.cs @@ -11,6 +11,7 @@ using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; +using System.Timers; using static SharedClientServer.JSONConvert; namespace Server.Models @@ -23,6 +24,7 @@ namespace Server.Models private byte[] buffer = new byte[2048]; private byte[] totalBuffer = new byte[2048]; private int totalBufferReceived = 0; + private Dictionary lobbyTimers; public User User { get; set; } private ServerCommunication serverCom = ServerCommunication.INSTANCE; private Callback OnMessageReceivedOk; @@ -34,6 +36,7 @@ namespace Server.Models /// the TcpClient object to use public ServerClient(TcpClient client) { + lobbyTimers = new Dictionary(); Debug.WriteLine("[SERVERCLIENT] making new instance and starting"); tcpClient = client; stream = tcpClient.GetStream(); @@ -186,14 +189,35 @@ namespace Server.Models case JSONConvert.GAME: Debug.WriteLine("[SERVERCLIENT] Got a message about the game logic"); - string command = JSONConvert.GetGameCommand(payload); + GameCommand command = JSONConvert.GetGameCommand(payload); switch (command) { - case "startGame": + case GameCommand.START_GAME: int lobbyID = JSONConvert.GetStartGameLobbyID(payload); serverCom.CloseALobby(lobbyID); + //todo start a timer for this lobby + Debug.WriteLine("[SERVERCLIENT] making timer for lobby " + lobbyID); + System.Timers.Timer lobbyTimer = new System.Timers.Timer(60 * 1000); + this.lobbyTimers.Add(lobbyTimer, lobbyID); + lobbyTimer.Elapsed += LobbyTimer_Elapsed; + lobbyTimer.Start(); ServerCommunication.INSTANCE.sendToAll(JSONConvert.ConstructLobbyListMessage(ServerCommunication.INSTANCE.lobbies.ToArray())); break; + case GameCommand.TIMER_ELAPSED: + + break; + case GameCommand.NEXT_ROUND: + // The next round has been started, so we can start the timer again + lobbyID = JSONConvert.GetLobbyID(payload); + foreach (System.Timers.Timer timer in lobbyTimers.Keys) + { + if (lobbyTimers[timer] == lobbyID) + { + timer.Start(); + break; + } + } + break; } break; @@ -211,6 +235,17 @@ namespace Server.Models } } + private void LobbyTimer_Elapsed(object sender, ElapsedEventArgs e) + { + System.Timers.Timer timer = sender as System.Timers.Timer; + int lobbyID = lobbyTimers[timer]; + Debug.WriteLine("[SERVERCLIENT] timer elapsed for lobby " + lobbyID); + serverCom.SendToLobby(lobbyID, JSONConvert.ConstructGameTimerElapsedMessage(lobbyID)); + timer.Stop(); + + + } + private void handleLobbyMessage(byte[] payload, LobbyIdentifier l) { switch (l) diff --git a/Server/Models/ServerCommunication.cs b/Server/Models/ServerCommunication.cs index e70d376..3dbdb8e 100644 --- a/Server/Models/ServerCommunication.cs +++ b/Server/Models/ServerCommunication.cs @@ -150,6 +150,22 @@ namespace Server.Models } } + public void SendToLobby(int lobbyID, byte[] message) + { + foreach (Lobby l in lobbies) + { + if (l.ID == lobbyID) + { + foreach (ServerClient sc in serverClientsInlobbies[l]) + { + Debug.WriteLine("[SERVERCLIENT] Sending message to lobby"); + sc.sendMessage(message); + } + break; + } + } + } + public void SendCanvasDataToLobby(Lobby lobby, string username, byte[] message) { foreach (Lobby l in lobbies) diff --git a/SharedClientServer/JSONConvert.cs b/SharedClientServer/JSONConvert.cs index 17e22f4..1f11b5a 100644 --- a/SharedClientServer/JSONConvert.cs +++ b/SharedClientServer/JSONConvert.cs @@ -35,6 +35,13 @@ namespace SharedClientServer REQUEST } + public enum GameCommand + { + START_GAME, + TIMER_ELAPSED, + NEXT_ROUND + } + public static (string,string) GetUsernameAndMessage(byte[] json) { string msg = Encoding.UTF8.GetString(json); @@ -205,15 +212,24 @@ namespace SharedClientServer public static byte[] ConstructGameStartData(int lobbyID) { - string startGame = "startGame"; + return GetMessageToSend(GAME, new { - command = startGame, + command = GameCommand.START_GAME, lobbyToStart = lobbyID }); ; } - public static string GetGameCommand(byte[] payload) + public static byte[] ConstructGameTimerElapsedMessage(int lobbyID) + { + return GetMessageToSend(GAME, new + { + command = GameCommand.TIMER_ELAPSED, + id = lobbyID + }); + } + + public static GameCommand GetGameCommand(byte[] payload) { dynamic json = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(payload)); return json.command; From ec08fbfced86d14f5ac849d33c7af1f7234e54cc Mon Sep 17 00:00:00 2001 From: Dogukan Date: Fri, 23 Oct 2020 15:47:52 +0200 Subject: [PATCH 3/3] [ADDITION] added a new property to the user (may be removed later on), and made a check for the random word --- Client/Client.cs | 41 +++++++++++++++++++++-------------- Server/Models/ServerClient.cs | 10 +++++++-- SharedClientServer/User.cs | 6 +++++ 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/Client/Client.cs b/Client/Client.cs index c33d66b..d1c3ce9 100644 --- a/Client/Client.cs +++ b/Client/Client.cs @@ -20,7 +20,7 @@ namespace Client public delegate void CanvasDataReceived(double[][] coordinates, Color color); public delegate void CanvasReset(); public delegate void LobbyCallback(int id); - + class Client : ObservableObject { @@ -70,9 +70,10 @@ namespace Client OnSuccessfullConnect?.Invoke(); OnLobbyUpdate = updateGameLobby; SendMessage(JSONConvert.ConstructUsernameMessage(username)); - this.stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(OnReadComplete),null); + this.stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(OnReadComplete), null); - } catch (Exception e) + } + catch (Exception e) { Debug.WriteLine("Can't connect, retrying..."); tcpClient.BeginConnect("localhost", Port, new AsyncCallback(OnConnect), null); @@ -113,10 +114,11 @@ namespace Client ar.AsyncWaitHandle.WaitOne(); stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(OnReadComplete), null); - } catch (IOException e) + } + catch (IOException e) { Debug.WriteLine("[CLIENT] server not responding! got error: " + e.Message); - OnServerDisconnect?.Invoke(); + OnServerDisconnect?.Invoke(); } } @@ -139,11 +141,16 @@ namespace Client string textUsername = combo.Item1; string textMsg = combo.Item2; - if(textUsername != data.User.Username) + if (textUsername != data.User.Username) { IncomingMsg?.Invoke(textUsername, textMsg); } + if (textMsg == data.User.RandomWord && !string.IsNullOrEmpty(data.User.RandomWord)) + { + Debug.WriteLine($"[CLIENT] word has been guessed! {data.User.Username} + Word: {data.User.RandomWord}"); + } + //TODO display username and message in chat window Debug.WriteLine("[CLIENT] INCOMING MESSAGE!"); Debug.WriteLine("[CLIENT] User name: {0}\t User message: {1}", textUsername, textMsg); @@ -191,29 +198,31 @@ namespace Client case JSONConvert.CANVAS_WRITING: CanvasDataReceived?.Invoke(JSONConvert.getCoordinates(payload), JSONConvert.getCanvasDrawingColor(payload)); - break; } - break; - + break; case JSONConvert.RANDOMWORD: //Flag byte for receiving the random word. int lobbyId = JSONConvert.GetLobbyID(payload); - string randomWord = JSONConvert.GetRandomWord(payload); - - if (data.Lobby?.ID == lobbyId) - RandomWord?.Invoke(randomWord); - + data.User.RandomWord = JSONConvert.GetRandomWord(payload); + data.User.TurnToDraw = true; // Dit is test code, dit kan weg zodra alles lopende is. + if (data.Lobby?.ID == lobbyId && data.User.TurnToDraw) + RandomWord?.Invoke(data.User.RandomWord); break; + default: Debug.WriteLine("[CLIENT] Received weird identifier: " + id); break; } - SendMessage(JSONConvert.GetMessageToSend(JSONConvert.MESSAGE_RECEIVED,null)); + SendMessage(JSONConvert.GetMessageToSend(JSONConvert.MESSAGE_RECEIVED, null)); } + /* + * Updates the current lobby with the joining players, + * their player score is also tracked and should always be zero. + */ private void updateGameLobby() { Debug.WriteLine("[CLIENT] updating game lobby"); @@ -228,7 +237,7 @@ namespace Client } } - + public void SendMessage(byte[] message) { Debug.WriteLine("[CLIENT] sending message " + Encoding.ASCII.GetString(message)); diff --git a/Server/Models/ServerClient.cs b/Server/Models/ServerClient.cs index 57bb6cb..6b8e91f 100644 --- a/Server/Models/ServerClient.cs +++ b/Server/Models/ServerClient.cs @@ -22,6 +22,7 @@ namespace Server.Models private NetworkStream stream; private byte[] buffer = new byte[2048]; private byte[] totalBuffer = new byte[2048]; + private string _randomWord = ""; private int totalBufferReceived = 0; public User User { get; set; } private ServerCommunication serverCom = ServerCommunication.INSTANCE; @@ -145,6 +146,11 @@ namespace Server.Models message = textMsg }; + if (textMsg == _randomWord && !string.IsNullOrEmpty(_randomWord)) + { + Debug.WriteLine($"[SERVERCLIENT] word has been guessed! {User.Username} + Word: {_randomWord}"); + } + //Sends the incomming message to be broadcast to all of the clients inside the current lobby. serverCom.SendToLobby(serverCom.GetLobbyForUser(User), JSONConvert.GetMessageToSend(JSONConvert.MESSAGE, packet)); break; @@ -234,11 +240,11 @@ namespace Server.Models ServerCommunication.INSTANCE.sendToAll(JSONConvert.ConstructLobbyListMessage(ServerCommunication.INSTANCE.lobbies.ToArray())); OnMessageReceivedOk = () => { - + _randomWord = JSONConvert.SendRandomWord("WordsForGame.json"); serverCom.sendToAll(JSONConvert.GetMessageToSend(JSONConvert.RANDOMWORD, new { id = serverCom.GetLobbyForUser(User).ID, - word = JSONConvert.SendRandomWord("WordsForGame.json") + word = _randomWord })); OnMessageReceivedOk = null; }; diff --git a/SharedClientServer/User.cs b/SharedClientServer/User.cs index 500a481..7b9770a 100644 --- a/SharedClientServer/User.cs +++ b/SharedClientServer/User.cs @@ -13,6 +13,7 @@ namespace SharedClientServer private bool _host; private bool _turnToDraw; private string _message; + private string _randomWord; [JsonConstructor] public User(string username, int score, bool host, bool turnToDraw) @@ -90,5 +91,10 @@ namespace SharedClientServer get { return _turnToDraw; } set { _turnToDraw = value; } } + public string RandomWord + { + get { return _randomWord; } + set { _randomWord = value; } + } } }