From 8190724f770a62c2f6e4ef955f73db2896569750 Mon Sep 17 00:00:00 2001 From: Lars Date: Wed, 21 Oct 2020 23:18:37 +0200 Subject: [PATCH 1/7] [ADDED] canvas data sending to the server works, but not fully yet to all the clients --- Client/Client.cs | 20 +++++++++++++++----- Client/ClientData.cs | 7 +++++++ Client/ViewModels/ViewModelGame.cs | 24 ++++++++++++++++++++++-- Client/Views/GameWindow.xaml.cs | 2 +- Server/Models/ServerClient.cs | 11 ++++++++--- SharedClientServer/ClientServerUtil.cs | 2 ++ SharedClientServer/JSONConvert.cs | 19 +++++++++++++++++++ 7 files changed, 74 insertions(+), 11 deletions(-) diff --git a/Client/Client.cs b/Client/Client.cs index 5346d92..1540944 100644 --- a/Client/Client.cs +++ b/Client/Client.cs @@ -8,13 +8,18 @@ using static SharedClientServer.JSONConvert; namespace Client { - public delegate void OnLobbyCreated(int id); + public delegate void OnLobbyCreated(int id); + + public delegate void CanvasDataReceived(double[] coordinates); class Client : ObservableObject - { + { + + private ClientData clientData = ClientData.Instance; + private TcpClient tcpClient; private NetworkStream stream; - private byte[] buffer = new byte[1024]; - private byte[] totalBuffer = new byte[1024]; + private byte[] buffer = new byte[2048]; + private byte[] totalBuffer = new byte[2048]; private int totalBufferReceived = 0; public int Port = 5555; public bool Connected = false; @@ -24,6 +29,8 @@ namespace Client public Callback OnLobbyJoinSuccess; public Callback OnLobbiesReceivedAndWaitingForHost; public OnLobbyCreated OnLobbyCreated; + + public CanvasDataReceived CanvasDataReceived; public Lobby[] Lobbies { get; set; } public Client(string username) @@ -48,7 +55,7 @@ namespace Client { int amountReceived = stream.EndRead(ar); - if (totalBufferReceived + amountReceived > 1024) + if (totalBufferReceived > 2048) { throw new OutOfMemoryException("buffer too small"); } @@ -68,6 +75,7 @@ namespace Client handleData(message); totalBufferReceived -= expectedMessageLength; + Debug.WriteLine($"reduced buffer: {expectedMessageLength}"); expectedMessageLength = BitConverter.ToInt32(totalBuffer, 0); } @@ -124,6 +132,8 @@ namespace Client case JSONConvert.CANVAS: // canvas data + //clientData.CanvasData = JSONConvert.getCoordinates(payload); + CanvasDataReceived?.Invoke(JSONConvert.getCoordinates(payload)); break; default: diff --git a/Client/ClientData.cs b/Client/ClientData.cs index 8a217a0..507dbca 100644 --- a/Client/ClientData.cs +++ b/Client/ClientData.cs @@ -31,6 +31,7 @@ namespace Client private Client _client; private Lobby _lobby; private string _message; + private double[] _canvasData = new double[4]; private ClientData() { @@ -68,5 +69,11 @@ namespace Client } } + public double[] CanvasData + { + get { return _canvasData; } + set { _canvasData = value; } + } + } } diff --git a/Client/ViewModels/ViewModelGame.cs b/Client/ViewModels/ViewModelGame.cs index 65fd353..f4522eb 100644 --- a/Client/ViewModels/ViewModelGame.cs +++ b/Client/ViewModels/ViewModelGame.cs @@ -14,6 +14,7 @@ namespace Client.ViewModels class ViewModelGame : INotifyPropertyChanged { private ClientData data = ClientData.Instance; + private GameWindow window; public event PropertyChangedEventHandler PropertyChanged; @@ -68,7 +69,7 @@ namespace Client.ViewModels currentPoint = e.GetPosition(window.CanvasForPaint); window.CanvasForPaint.Children.Add(line); - data.Client.SendMessage(JSONConvert.GetMessageToSend(0x04, coordinates)); + data.Client.SendMessage(JSONConvert.ConstructCanvasDataSend(coordinates)); } } @@ -83,8 +84,9 @@ namespace Client.ViewModels } - public ViewModelGame() + public ViewModelGame(GameWindow window) { + this.window = window; if (_payload == null) { _message = ""; @@ -97,6 +99,24 @@ namespace Client.ViewModels //Messages.Add($"{data.User.Username}: {Message}"); } OnKeyDown = new RelayCommand(ChatBox_KeyDown); + data.Client.CanvasDataReceived = UpdateCanvasWithNewData; + } + + + private void UpdateCanvasWithNewData(double[] coordinates) + { + Application.Current.Dispatcher.Invoke(delegate + { + Line line = new Line(); + line.Stroke = new SolidColorBrush(Colors.Black); + line.X1 = coordinates[0]; + line.Y1 = coordinates[1]; + line.X2 = coordinates[2]; + line.Y2 = coordinates[3]; + + this.window.CanvasForPaint.Children.Add(line); + }); + } private void ChatBox_KeyDown() diff --git a/Client/Views/GameWindow.xaml.cs b/Client/Views/GameWindow.xaml.cs index 9d90635..d59926f 100644 --- a/Client/Views/GameWindow.xaml.cs +++ b/Client/Views/GameWindow.xaml.cs @@ -22,7 +22,7 @@ namespace Client.Views private ViewModelGame viewModel; public GameWindow() { - this.viewModel = new ViewModelGame(); + this.viewModel = new ViewModelGame(this); DataContext = this.viewModel; InitializeComponent(); diff --git a/Server/Models/ServerClient.cs b/Server/Models/ServerClient.cs index 90eab73..0e5f9b8 100644 --- a/Server/Models/ServerClient.cs +++ b/Server/Models/ServerClient.cs @@ -16,8 +16,8 @@ namespace Server.Models { private TcpClient tcpClient; private NetworkStream stream; - private byte[] buffer = new byte[1024]; - private byte[] totalBuffer = new byte[1024]; + private byte[] buffer = new byte[2048]; + private byte[] totalBuffer = new byte[2048]; private int totalBufferReceived = 0; public User User { get; set; } private ServerCommunication serverCom = ServerCommunication.INSTANCE; @@ -48,7 +48,7 @@ namespace Server.Models int bytesReceived = this.stream.EndRead(ar); - if (totalBufferReceived + bytesReceived > 1024) + if (totalBufferReceived > 2048) { throw new OutOfMemoryException("buffer is too small!"); } @@ -136,6 +136,11 @@ namespace Server.Models break; case JSONConvert.CANVAS: Debug.WriteLine("GOT A MESSAGE FROM THE CLIENT ABOUT THE CANVAS!!!"); + dynamic canvasData = new { + coordinatesLine = JSONConvert.getCoordinates(payload) + }; + serverCom.SendToLobby(serverCom.GetLobbyForUser(User), JSONConvert.GetMessageToSend(CANVAS, canvasData)); + // canvas data // todo send canvas data to all other serverclients in lobby break; diff --git a/SharedClientServer/ClientServerUtil.cs b/SharedClientServer/ClientServerUtil.cs index d9d30fe..1832973 100644 --- a/SharedClientServer/ClientServerUtil.cs +++ b/SharedClientServer/ClientServerUtil.cs @@ -7,6 +7,8 @@ using System.Text; namespace SharedClientServer { public delegate void Callback(); + + class ClientServerUtil { // creates a message array to send to the server or to clients diff --git a/SharedClientServer/JSONConvert.cs b/SharedClientServer/JSONConvert.cs index dd967e8..209057d 100644 --- a/SharedClientServer/JSONConvert.cs +++ b/SharedClientServer/JSONConvert.cs @@ -83,6 +83,7 @@ namespace SharedClientServer }); } + public static byte[] ConstructLobbyJoinMessage(int lobbyID) { return GetMessageToSend(LOBBY, new @@ -140,6 +141,24 @@ namespace SharedClientServer #endregion + public static byte[] ConstructCanvasDataSend(double[] coordinates) + { + return GetMessageToSend(CANVAS, new + { + coordinatesLine = coordinates + }); ; + } + + public static double[] getCoordinates(byte[] payload) + { + dynamic payloadD = JsonConvert.DeserializeObject(Encoding.ASCII.GetString(payload)); + JArray coordinatesArray = payloadD.coordinatesLine; + + double[] coordinates = coordinatesArray.ToObject(); + + return coordinates; + } + /// /// constructs a message that can be sent to the clients or server /// From cac0fdc0a468b94fc855293278de06a87bf9d048 Mon Sep 17 00:00:00 2001 From: Lars Date: Thu, 22 Oct 2020 15:40:09 +0200 Subject: [PATCH 2/7] [ADDED] lobby now secured when the game starts. start button is still for everyone available, not working yet --- Client/Client.cs | 308 +++++++++++----------- Client/ViewModels/ViewModel.cs | 19 +- Client/ViewModels/ViewModelGame.cs | 66 +++-- Client/Views/GameWindow.xaml | 18 +- Client/Views/MainWindow.xaml | 3 +- Server/Models/ServerClient.cs | 18 +- Server/Models/ServerCommunication.cs | 11 + SharedClientServer/JSONConvert.cs | 367 ++++++++++++++------------- SharedClientServer/Lobby.cs | 9 +- SharedClientServer/User.cs | 11 +- 10 files changed, 467 insertions(+), 363 deletions(-) diff --git a/Client/Client.cs b/Client/Client.cs index 1540944..1cb4822 100644 --- a/Client/Client.cs +++ b/Client/Client.cs @@ -1,158 +1,158 @@ -using SharedClientServer; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Net.Sockets; -using System.Text; -using static SharedClientServer.JSONConvert; - -namespace Client -{ +using SharedClientServer; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Net.Sockets; +using System.Text; +using static SharedClientServer.JSONConvert; + +namespace Client +{ public delegate void OnLobbyCreated(int id); - public delegate void CanvasDataReceived(double[] coordinates); - class Client : ObservableObject + public delegate void CanvasDataReceived(double[] coordinates); + class Client : ObservableObject { - private ClientData clientData = ClientData.Instance; - - private TcpClient tcpClient; - private NetworkStream stream; - private byte[] buffer = new byte[2048]; - private byte[] totalBuffer = new byte[2048]; - private int totalBufferReceived = 0; - public int Port = 5555; - public bool Connected = false; - private string username; - public Callback OnSuccessfullConnect; - public Callback OnLobbiesListReceived; - public Callback OnLobbyJoinSuccess; - public Callback OnLobbiesReceivedAndWaitingForHost; - public OnLobbyCreated OnLobbyCreated; - - public CanvasDataReceived CanvasDataReceived; - public Lobby[] Lobbies { get; set; } - - public Client(string username) - { - this.username = username; - this.tcpClient = new TcpClient(); - Debug.WriteLine("Starting connect to server"); - tcpClient.BeginConnect("localhost", Port, new AsyncCallback(OnConnect), null); - } - - private void OnConnect(IAsyncResult ar) - { - Debug.Write("finished connecting to server"); - this.tcpClient.EndConnect(ar); - this.stream = tcpClient.GetStream(); - OnSuccessfullConnect?.Invoke(); - SendMessage(JSONConvert.ConstructUsernameMessage(username)); - this.stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(OnReadComplete),null); - } - - private void OnReadComplete(IAsyncResult ar) - { - int amountReceived = stream.EndRead(ar); - - if (totalBufferReceived > 2048) - { - throw new OutOfMemoryException("buffer too small"); - } - - Array.Copy(buffer, 0, totalBuffer, totalBufferReceived, amountReceived); - totalBufferReceived += amountReceived; - - int expectedMessageLength = BitConverter.ToInt32(totalBuffer, 0); - - while (totalBufferReceived >= expectedMessageLength) - { - // we have received the complete packet - byte[] message = new byte[expectedMessageLength]; - // put the message received into the message array - Array.Copy(totalBuffer, 0, message, 0, expectedMessageLength); - - handleData(message); - - totalBufferReceived -= expectedMessageLength; - Debug.WriteLine($"reduced buffer: {expectedMessageLength}"); - expectedMessageLength = BitConverter.ToInt32(totalBuffer, 0); - } - - stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(OnReadComplete), null); - } - - private void handleData(byte[] message) - { - byte id = message[4]; - - byte[] payload = new byte[message.Length - 5]; - Array.Copy(message, 5, payload, 0, message.Length - 5); - - switch (id) - { - case JSONConvert.LOGIN: - // json log in username data - break; - case JSONConvert.MESSAGE: - // json message data - (string, string) combo = JSONConvert.GetUsernameAndMessage(payload); - string textUsername = combo.Item1; - string textMsg = combo.Item2; - - //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); - break; - - case JSONConvert.LOBBY: - // lobby data - LobbyIdentifier lobbyIdentifier = JSONConvert.GetLobbyIdentifier(payload); - switch (lobbyIdentifier) - { - case LobbyIdentifier.LIST: - Debug.WriteLine("got lobbies list"); - Lobbies = JSONConvert.GetLobbiesFromMessage(payload); - OnLobbiesListReceived?.Invoke(); - OnLobbiesReceivedAndWaitingForHost?.Invoke(); - break; - case LobbyIdentifier.HOST: - // we receive this when the server has made us a host of a new lobby - // TODO get lobby id - Debug.WriteLine("[CLIENT] got lobby object"); - int lobbyCreatedID = JSONConvert.GetLobbyID(payload); - OnLobbyCreated?.Invoke(lobbyCreatedID); - break; - case LobbyIdentifier.JOIN_SUCCESS: - OnLobbyJoinSuccess?.Invoke(); - break; - } - //TODO fill lobby with the data received - break; - - case JSONConvert.CANVAS: - // canvas data - //clientData.CanvasData = JSONConvert.getCoordinates(payload); - CanvasDataReceived?.Invoke(JSONConvert.getCoordinates(payload)); - break; - - default: - Debug.WriteLine("[CLIENT] Received weird identifier: " + id); - break; - } - - } - - public void SendMessage(byte[] message) - { - Debug.WriteLine("[CLIENT] sending message " + Encoding.ASCII.GetString(message)); - stream.BeginWrite(message, 0, message.Length, new AsyncCallback(OnWriteComplete), null); - } - - private void OnWriteComplete(IAsyncResult ar) - { - Debug.WriteLine("[CLIENT] finished writing"); - stream.EndWrite(ar); - } - } -} + private ClientData clientData = ClientData.Instance; + + private TcpClient tcpClient; + private NetworkStream stream; + private byte[] buffer = new byte[2048]; + private byte[] totalBuffer = new byte[2048]; + private int totalBufferReceived = 0; + public int Port = 5555; + public bool Connected = false; + private string username; + public Callback OnSuccessfullConnect; + public Callback OnLobbiesListReceived; + public Callback OnLobbyJoinSuccess; + public Callback OnLobbiesReceivedAndWaitingForHost; + public OnLobbyCreated OnLobbyCreated; + + public CanvasDataReceived CanvasDataReceived; + public Lobby[] Lobbies { get; set; } + + public Client(string username) + { + this.username = username; + this.tcpClient = new TcpClient(); + Debug.WriteLine("Starting connect to server"); + tcpClient.BeginConnect("localhost", Port, new AsyncCallback(OnConnect), null); + } + + private void OnConnect(IAsyncResult ar) + { + Debug.Write("finished connecting to server"); + this.tcpClient.EndConnect(ar); + this.stream = tcpClient.GetStream(); + OnSuccessfullConnect?.Invoke(); + SendMessage(JSONConvert.ConstructUsernameMessage(username)); + this.stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(OnReadComplete),null); + } + + private void OnReadComplete(IAsyncResult ar) + { + int amountReceived = stream.EndRead(ar); + + if (totalBufferReceived > 2048) + { + throw new OutOfMemoryException("buffer too small"); + } + + Array.Copy(buffer, 0, totalBuffer, totalBufferReceived, amountReceived); + totalBufferReceived += amountReceived; + + int expectedMessageLength = BitConverter.ToInt32(totalBuffer, 0); + + while (totalBufferReceived >= expectedMessageLength) + { + // we have received the complete packet + byte[] message = new byte[expectedMessageLength]; + // put the message received into the message array + Array.Copy(totalBuffer, 0, message, 0, expectedMessageLength); + + handleData(message); + + totalBufferReceived -= expectedMessageLength; + Debug.WriteLine($"reduced buffer: {expectedMessageLength}"); + expectedMessageLength = BitConverter.ToInt32(totalBuffer, 0); + } + + stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(OnReadComplete), null); + } + + private void handleData(byte[] message) + { + byte id = message[4]; + + byte[] payload = new byte[message.Length - 5]; + Array.Copy(message, 5, payload, 0, message.Length - 5); + + switch (id) + { + case JSONConvert.LOGIN: + // json log in username data + break; + case JSONConvert.MESSAGE: + // json message data + (string, string) combo = JSONConvert.GetUsernameAndMessage(payload); + string textUsername = combo.Item1; + string textMsg = combo.Item2; + + //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); + break; + + case JSONConvert.LOBBY: + // lobby data + LobbyIdentifier lobbyIdentifier = JSONConvert.GetLobbyIdentifier(payload); + switch (lobbyIdentifier) + { + case LobbyIdentifier.LIST: + Debug.WriteLine("got lobbies list"); + Lobbies = JSONConvert.GetLobbiesFromMessage(payload); + OnLobbiesListReceived?.Invoke(); + OnLobbiesReceivedAndWaitingForHost?.Invoke(); + break; + case LobbyIdentifier.HOST: + // we receive this when the server has made us a host of a new lobby + // TODO get lobby id + Debug.WriteLine("[CLIENT] got lobby object"); + int lobbyCreatedID = JSONConvert.GetLobbyID(payload); + OnLobbyCreated?.Invoke(lobbyCreatedID); + break; + case LobbyIdentifier.JOIN_SUCCESS: + OnLobbyJoinSuccess?.Invoke(); + break; + } + //TODO fill lobby with the data received + break; + + case JSONConvert.CANVAS: + // canvas data + //clientData.CanvasData = JSONConvert.getCoordinates(payload); + CanvasDataReceived?.Invoke(JSONConvert.getCoordinates(payload)); + break; + + default: + Debug.WriteLine("[CLIENT] Received weird identifier: " + id); + break; + } + + } + + public void SendMessage(byte[] message) + { + Debug.WriteLine("[CLIENT] sending message " + Encoding.ASCII.GetString(message)); + stream.BeginWrite(message, 0, message.Length, new AsyncCallback(OnWriteComplete), null); + } + + private void OnWriteComplete(IAsyncResult ar) + { + Debug.WriteLine("[CLIENT] finished writing"); + stream.EndWrite(ar); + } + } +} diff --git a/Client/ViewModels/ViewModel.cs b/Client/ViewModels/ViewModel.cs index bbb9843..f90c1fe 100644 --- a/Client/ViewModels/ViewModel.cs +++ b/Client/ViewModels/ViewModel.cs @@ -11,7 +11,10 @@ using System.Collections.ObjectModel; using Client.Views; using System.Linq; using System.Windows.Data; - +using System.Data; +using System.Windows.Controls.Primitives; +using System.Windows.Controls; + namespace Client { class ViewModel : INotifyPropertyChanged @@ -79,8 +82,16 @@ namespace Client { // lobby die je wilt joinen verwijderen // nieuwe binnengekregen lobby toevoegen - client.OnLobbyJoinSuccess = OnLobbyJoinSuccess; - client.SendMessage(JSONConvert.ConstructLobbyJoinMessage(SelectedLobby.ID)); + if (SelectedLobby != null) + { + if (SelectedLobby.PlayersIn == SelectedLobby.MaxPlayers || !SelectedLobby.LobbyJoineble) + { + return; + } + client.OnLobbyJoinSuccess = OnLobbyJoinSuccess; + client.SendMessage(JSONConvert.ConstructLobbyJoinMessage(SelectedLobby.ID)); + } + } private void OnLobbyJoinSuccess() @@ -168,5 +179,7 @@ namespace Client get { return _lobbies; } set { _lobbies = value; } } + + } } diff --git a/Client/ViewModels/ViewModelGame.cs b/Client/ViewModels/ViewModelGame.cs index f4522eb..406845f 100644 --- a/Client/ViewModels/ViewModelGame.cs +++ b/Client/ViewModels/ViewModelGame.cs @@ -13,21 +13,15 @@ namespace Client.ViewModels { class ViewModelGame : INotifyPropertyChanged { + public event PropertyChangedEventHandler PropertyChanged; private ClientData data = ClientData.Instance; private GameWindow window; - - public event PropertyChangedEventHandler PropertyChanged; - private Point currentPoint = new Point(); private Color color; - - public ObservableCollection Messages { get; } = new ObservableCollection(); - private dynamic _payload; - private string _username; - private string _message; + public string Message { get @@ -39,7 +33,43 @@ namespace Client.ViewModels _message = value; } } + + public User User + { + get { return data.User; } + set + { + data.User = value; + } + } + + public ViewModelGame(GameWindow window) + { + this.window = window; + if (_payload == null) + { + _message = ""; + + } + else + { + //_message = data.Message; + //_username = data.User.Username; + //Messages.Add($"{data.User.Username}: {Message}"); + } + OnKeyDown = new RelayCommand(ChatBox_KeyDown); + ButtonStartGame = new RelayCommand(BeginGame); + data.Client.CanvasDataReceived = UpdateCanvasWithNewData; + } + + public ObservableCollection Messages { get; } = new ObservableCollection(); public ICommand OnKeyDown { get; set; } + public ICommand ButtonStartGame { get; set; } + + public void BeginGame() + { + data.Client.SendMessage(JSONConvert.ConstructGameStartData(data.Lobby.ID)); + } public void Canvas_MouseDown(MouseButtonEventArgs e, GameWindow window) { @@ -82,26 +112,6 @@ namespace Client.ViewModels colorSelected.B = window.ClrPcker_Background.SelectedColor.Value.B; color = colorSelected; } - - - public ViewModelGame(GameWindow window) - { - this.window = window; - if (_payload == null) - { - _message = ""; - - } - else - { - //_message = data.Message; - //_username = data.User.Username; - //Messages.Add($"{data.User.Username}: {Message}"); - } - OnKeyDown = new RelayCommand(ChatBox_KeyDown); - data.Client.CanvasDataReceived = UpdateCanvasWithNewData; - } - private void UpdateCanvasWithNewData(double[] coordinates) { diff --git a/Client/Views/GameWindow.xaml b/Client/Views/GameWindow.xaml index 6614197..a69a641 100644 --- a/Client/Views/GameWindow.xaml +++ b/Client/Views/GameWindow.xaml @@ -35,9 +35,23 @@ -