diff --git a/Client/Client.cs b/Client/Client.cs index 15e58a9..50c60fc 100644 --- a/Client/Client.cs +++ b/Client/Client.cs @@ -5,19 +5,26 @@ using System.Diagnostics; using System.IO; using System.Net.Sockets; using System.Text; +using System.Windows.Media; using System.Windows; + using static SharedClientServer.JSONConvert; namespace Client { - public delegate void LobbyCallback(int id); public delegate void LobbyJoinCallback(bool isHost); + public delegate void CanvasDataReceived(double[][] coordinates, Color color); + public delegate void CanvasReset(); + public delegate void LobbyCallback(int id); 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; @@ -30,6 +37,8 @@ namespace Client public LobbyCallback OnLobbyCreated; public LobbyCallback OnLobbyLeave; private ClientData data = ClientData.Instance; + public CanvasDataReceived CanvasDataReceived; + public CanvasReset CReset; public Lobby[] Lobbies { get; set; } public Client(string username) @@ -60,17 +69,19 @@ namespace Client private void OnReadComplete(IAsyncResult ar) { + if (ar == null || (!ar.IsCompleted) || (!this.stream.CanRead) || !this.tcpClient.Client.Connected) return; try { int amountReceived = stream.EndRead(ar); - if (totalBufferReceived + amountReceived > 1024) + if (totalBufferReceived + amountReceived > 2048) { throw new OutOfMemoryException("buffer too small"); } + Array.Copy(buffer, 0, totalBuffer, totalBufferReceived, amountReceived); totalBufferReceived += amountReceived; @@ -82,7 +93,6 @@ namespace Client byte[] message = new byte[expectedMessageLength]; // put the message received into the message array Array.Copy(totalBuffer, 0, message, 0, expectedMessageLength); - handleData(message); totalBufferReceived -= expectedMessageLength; @@ -96,7 +106,6 @@ namespace Client Debug.WriteLine("[CLIENT] server not responding! got error: " + e.Message); OnServerDisconnect?.Invoke(); } - } private void handleData(byte[] message) @@ -160,7 +169,22 @@ namespace Client case JSONConvert.CANVAS: // canvas data - break; + //clientData.CanvasData = JSONConvert.getCoordinates(payload); + int type = JSONConvert.GetCanvasMessageType(payload); + switch (type) + { + case JSONConvert.CANVAS_RESET: + CReset?.Invoke(); + break; + + case JSONConvert.CANVAS_WRITING: + CanvasDataReceived?.Invoke(JSONConvert.getCoordinates(payload), JSONConvert.getCanvasDrawingColor(payload)); + // we hebben gedrawed, dus stuur dat we weer kunnen drawen + + break; + } + break; + case JSONConvert.RANDOMWORD: //Flag byte for receiving the random word. 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/ViewModel.cs b/Client/ViewModels/ViewModel.cs index d800b9a..3bedfe0 100644 --- a/Client/ViewModels/ViewModel.cs +++ b/Client/ViewModels/ViewModel.cs @@ -11,6 +11,9 @@ 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 { @@ -87,10 +90,16 @@ namespace Client private void joinLobby() { - // 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.LobbyJoinable) + { + return; + } + client.OnLobbyJoinSuccess = OnLobbyJoinSuccess; + client.SendMessage(JSONConvert.ConstructLobbyJoinMessage(SelectedLobby.ID)); + } + } private void OnLobbyJoinSuccess(bool isHost) @@ -166,5 +175,7 @@ namespace Client get { return _lobbies; } set { _lobbies = value; } } + + } } diff --git a/Client/ViewModels/ViewModelGame.cs b/Client/ViewModels/ViewModelGame.cs index cbc6a49..976e24d 100644 --- a/Client/ViewModels/ViewModelGame.cs +++ b/Client/ViewModels/ViewModelGame.cs @@ -1,148 +1,244 @@ - -using Client.Views; -using GalaSoft.MvvmLight.Command; -using SharedClientServer; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Shapes; - -namespace Client.ViewModels -{ - class ViewModelGame : INotifyPropertyChanged - { - private ClientData data = ClientData.Instance; - - public event PropertyChangedEventHandler PropertyChanged; - - private Point currentPoint = new Point(); - private Color color; - - public static ObservableCollection Messages { get; } = new ObservableCollection(); - - private dynamic _payload; - - public static string Word - { - get; - set; - } - - public string _username; - - public string _message; - public string Message - { - get - { - return _message; - } - set - { - _message = value; - } - } - public ICommand OnKeyDown { get; set; } - - public void Canvas_MouseDown(MouseButtonEventArgs e, GameWindow window) - { - if (e.ButtonState == MouseButtonState.Pressed) - { - currentPoint = e.GetPosition(window.CanvasForPaint); - } - } - - public void Canvas_MouseMove(MouseEventArgs e, GameWindow window) - { - if (e.LeftButton == MouseButtonState.Pressed) - { - double[] coordinates = new double[4]; - Line line = new Line(); - - line.Stroke = new SolidColorBrush(color); - //line.Stroke = SystemColors.WindowFrameBrush; - line.X1 = currentPoint.X; - line.Y1 = currentPoint.Y; - line.X2 = e.GetPosition(window.CanvasForPaint).X; - line.Y2 = e.GetPosition(window.CanvasForPaint).Y; - coordinates[0] = line.X1; - coordinates[1] = line.Y1; - coordinates[2] = line.X2; - coordinates[3] = line.Y2; - currentPoint = e.GetPosition(window.CanvasForPaint); - - window.CanvasForPaint.Children.Add(line); - data.Client.SendMessage(JSONConvert.GetMessageToSend(0x04, coordinates)); - } - } - - public void Color_Picker(RoutedPropertyChangedEventArgs e, GameWindow window) - { - Color colorSelected = new Color(); - colorSelected.A = 255; - colorSelected.R = window.ClrPcker_Background.SelectedColor.Value.R; - colorSelected.G = window.ClrPcker_Background.SelectedColor.Value.G; - colorSelected.B = window.ClrPcker_Background.SelectedColor.Value.B; - color = colorSelected; - } - - - public ViewModelGame() - { - OnKeyDown = new RelayCommand(ChatBox_KeyDown); - } - - private void ChatBox_KeyDown() - { - //if enter then clear textbox and send message. - if (Message != string.Empty) AddMessage(Message); - Message = string.Empty; - } - - internal void AddMessage(string message) - { - Messages.Add($"{data.User.Username}: {message}"); - - _payload = new - { - username = data.User.Username, - message = message - }; - - //Broadcast the message after adding it to the list! - data.Client.SendMessage(JSONConvert.GetMessageToSend(JSONConvert.MESSAGE, _payload)); - } - - /* - * MISC make this a callback - * Handles the incoming chat message from another client. - */ - public static void HandleIncomingMsg(string username, string message) - { - Application.Current.Dispatcher.Invoke(delegate - { - Messages.Add($"{username}: {message}"); - }); - } - public void LeaveGame(object sender, CancelEventArgs e) - { - Debug.WriteLine("Leaving..."); - data.Client.SendMessage(JSONConvert.ConstructLobbyLeaveMessage(data.Lobby.ID)); - } - - /* - * MISC make this a callback - * Handles the random word that has been received from the server. - */ - public static void HandleRandomWord(string randomWord) - { - Debug.WriteLine("[CLIENT] Reached the handle random word method!"); - Word = "NegerPik"; - } - } -} - + +using Client.Views; +using GalaSoft.MvvmLight.Command; +using SharedClientServer; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Diagnostics; +using System.Timers; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Shapes; + +namespace Client.ViewModels +{ + class ViewModelGame : INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + private ClientData data = ClientData.Instance; + private GameWindow window; + private Point currentPoint = new Point(); + public Color color; + public double[][] buffer; + public int pos = 0; + public int maxLines = 50; + public Queue linesQueue; + private Timer queueTimer; + + public static ObservableCollection Messages { get; } = new ObservableCollection(); + + private dynamic _payload; + + public static string Word + { + get; + set; + } + + public string _username; + + public string _message; + public string Message + { + get + { + return _message; + } + set + { + _message = value; + } + } + + public bool IsHost + { + get { return data.User.Host; } + } + + 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}"); + } + + buffer = new double[maxLines][]; + linesQueue = new Queue(); + OnKeyDown = new RelayCommand(ChatBox_KeyDown); + ButtonStartGame = new RelayCommand(BeginGame); + ButtonResetCanvas = new RelayCommand(CanvasResetLocal); + data.Client.CanvasDataReceived = UpdateCanvasWithNewData; + data.Client.CReset = CanvasResetData; + } + + public ICommand OnKeyDown { get; set; } + public ICommand ButtonStartGame { get; set; } + public ICommand ButtonResetCanvas { get; set; } + + public void BeginGame() + { + + queueTimer = new Timer(50); + queueTimer.Start(); + queueTimer.Elapsed += sendArrayFromQueue; + data.Client.SendMessage(JSONConvert.ConstructGameStartData(data.Lobby.ID)); + } + + + private void CanvasResetLocal() + { + this.window.CanvasForPaint.Children.Clear(); + data.Client.SendMessage(JSONConvert.GetMessageToSend(JSONConvert.CANVAS, JSONConvert.CANVAS_RESET)); + } + + + public void Canvas_MouseDown(MouseButtonEventArgs e, GameWindow window) + { + if (e.ButtonState == MouseButtonState.Pressed) + { + currentPoint = e.GetPosition(window.CanvasForPaint); + } + } + + public void Canvas_MouseMove(MouseEventArgs e, GameWindow window) + { + if (e.LeftButton == MouseButtonState.Pressed) + { + double[] coordinates = new double[4]; + Line line = new Line(); + + line.Stroke = new SolidColorBrush(color); + //line.Stroke = SystemColors.WindowFrameBrush; + line.X1 = currentPoint.X; + line.Y1 = currentPoint.Y; + line.X2 = e.GetPosition(window.CanvasForPaint).X; + line.Y2 = e.GetPosition(window.CanvasForPaint).Y; + coordinates[0] = line.X1; + coordinates[1] = line.Y1; + coordinates[2] = line.X2; + coordinates[3] = line.Y2; + currentPoint = e.GetPosition(window.CanvasForPaint); + buffer[pos] = coordinates; + pos++; + + window.CanvasForPaint.Children.Add(line); + if (pos == maxLines) + { + double[][] temp = new double[maxLines][]; + for (int i = 0; i < maxLines; i++) + { + temp[i] = buffer[i]; + } + linesQueue.Enqueue(temp); + Array.Clear(buffer, 0, buffer.Length); + pos = 0; + } + + } + } + + private void sendArrayFromQueue(object sender, ElapsedEventArgs e) + { + + if (linesQueue.Count != 0) + { + Debug.WriteLine("[GAME] sending canvas data..."); + double[][] temp = linesQueue.Dequeue(); + data.Client.SendMessage(JSONConvert.ConstructDrawingCanvasData(temp,color)); + } + } + + public void Color_Picker(RoutedPropertyChangedEventArgs e, GameWindow window) + { + Color colorSelected = new Color(); + colorSelected.A = 255; + colorSelected.R = window.ClrPcker_Background.SelectedColor.Value.R; + colorSelected.G = window.ClrPcker_Background.SelectedColor.Value.G; + colorSelected.B = window.ClrPcker_Background.SelectedColor.Value.B; + color = colorSelected; + } + + private void UpdateCanvasWithNewData(double[][] buffer, Color color) + { + Application.Current.Dispatcher.Invoke(delegate + { + foreach (double[] arr in buffer) + { + Line line = new Line(); + line.Stroke = new SolidColorBrush(color); + line.X1 = arr[0]; + line.Y1 = arr[1]; + line.X2 = arr[2]; + line.Y2 = arr[3]; + this.window.CanvasForPaint.Children.Add(line); + } + }); + } + + private void CanvasResetData() + { + this.window.CanvasForPaint.Children.Clear(); + } + + private void ChatBox_KeyDown() + { + //if enter then clear textbox and send message. + if (Message != string.Empty) AddMessage(Message); + Message = string.Empty; + } + + internal void AddMessage(string message) + { + Messages.Add($"{data.User.Username}: {message}"); + + _payload = new + { + username = data.User.Username, + message = message + }; + + //Broadcast the message after adding it to the list! + data.Client.SendMessage(JSONConvert.GetMessageToSend(JSONConvert.MESSAGE, _payload)); + } + + /* + * MISC make this a callback + * Handles the incoming chat message from another client. + */ + public static void HandleIncomingMsg(string username, string message) + { + Application.Current.Dispatcher.Invoke(delegate + { + Messages.Add($"{username}: {message}"); + }); + } + public void LeaveGame(object sender, CancelEventArgs e) + { + Debug.WriteLine("Leaving..."); + data.Client.SendMessage(JSONConvert.ConstructLobbyLeaveMessage(data.Lobby.ID)); + } + + /* + * MISC make this a callback + * Handles the random word that has been received from the server. + */ + public static void HandleRandomWord(string randomWord) + { + Debug.WriteLine("[CLIENT] Reached the handle random word method!"); + Word = "NegerPik"; + } + } +} + diff --git a/Client/Views/GameWindow.xaml b/Client/Views/GameWindow.xaml index dff9a66..ab2d3ef 100644 --- a/Client/Views/GameWindow.xaml +++ b/Client/Views/GameWindow.xaml @@ -34,12 +34,27 @@ -