diff --git a/Client/Client.cs b/Client/Client.cs index 8a51785..bc7b2b5 100644 --- a/Client/Client.cs +++ b/Client/Client.cs @@ -8,7 +8,7 @@ using static SharedClientServer.JSONConvert; namespace Client { - public delegate void OnLobbyCreated(int id); + public delegate void LobbyCallback(int id); class Client : ObservableObject { private TcpClient tcpClient; @@ -23,7 +23,8 @@ namespace Client public Callback OnLobbiesListReceived; public Callback OnLobbyJoinSuccess; public Callback OnLobbiesReceivedAndWaitingForHost; - public OnLobbyCreated OnLobbyCreated; + public LobbyCallback OnLobbyCreated; + public LobbyCallback OnLobbyLeave; private ClientData data = ClientData.Instance; public Lobby[] Lobbies { get; set; } @@ -125,6 +126,10 @@ namespace Client case LobbyIdentifier.JOIN_SUCCESS: OnLobbyJoinSuccess?.Invoke(); break; + case LobbyIdentifier.LEAVE: + int lobbyLeaveID = JSONConvert.GetLobbyID(payload); + OnLobbyLeave?.Invoke(lobbyLeaveID); + break; } //TODO fill lobby with the data received break; diff --git a/Client/ViewModels/ViewModel.cs b/Client/ViewModels/ViewModel.cs index bbb9843..37d4ed9 100644 --- a/Client/ViewModels/ViewModel.cs +++ b/Client/ViewModels/ViewModel.cs @@ -34,6 +34,7 @@ namespace Client _lobbies = new ObservableCollection(); client = ClientData.Instance.Client; client.OnLobbiesListReceived = updateLobbies; + client.OnLobbyLeave = leaveLobby; OnHostButtonClick = new RelayCommand(hostGame); @@ -41,6 +42,13 @@ namespace Client JoinSelectedLobby = new RelayCommand(joinLobby, true); } + private void leaveLobby(int id) + { + _model.CanStartGame = true; + ClientData.Instance.Lobby = null; + SelectedLobby = null; + } + private void hostGame() { Debug.WriteLine("attempting to host game for " + ClientData.Instance.User.Username); @@ -96,19 +104,6 @@ namespace Client Lobby[] lobbiesArr = client.Lobbies; Application.Current.Dispatcher.Invoke(delegate { - - //for (int i = 0; i < lobbiesArr.Length; i++) - //{ - // Lobby lobby = lobbiesArr[i]; - // Debug.WriteLine(lobby.PlayersIn); - // if (i < _lobbies.Count && _lobbies[i].ID == lobby.ID) - // { - // _lobbies[i].Set(lobby); - // } else - // { - // _lobbies.Add(lobbiesArr[i]); - // } - //} _lobbies.Clear(); diff --git a/Client/ViewModels/ViewModelGame.cs b/Client/ViewModels/ViewModelGame.cs index 298a7fc..661e83f 100644 --- a/Client/ViewModels/ViewModelGame.cs +++ b/Client/ViewModels/ViewModelGame.cs @@ -4,6 +4,7 @@ using GalaSoft.MvvmLight.Command; using SharedClientServer; using System.Collections.ObjectModel; using System.ComponentModel; +using System.Diagnostics; using System.Windows; using System.Windows.Input; using System.Windows.Media; @@ -127,6 +128,13 @@ namespace Client.ViewModels Messages.Add($"{username}: {message}"); }); } + public void LeaveGame(object sender, System.ComponentModel.CancelEventArgs e) + { + Debug.WriteLine("Leaving..."); + data.Client.SendMessage(JSONConvert.ConstructLobbyLeaveMessage(data.Lobby.ID)); + } + + } } diff --git a/Client/Views/GameWindow.xaml b/Client/Views/GameWindow.xaml index 6614197..1599e1f 100644 --- a/Client/Views/GameWindow.xaml +++ b/Client/Views/GameWindow.xaml @@ -3,7 +3,6 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:local="clr-namespace:Client.Views" xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit" mc:Ignorable="d" Title="Scrubl.io" Height="600" Width="1200"> diff --git a/Client/Views/GameWindow.xaml.cs b/Client/Views/GameWindow.xaml.cs index 9d90635..5947c52 100644 --- a/Client/Views/GameWindow.xaml.cs +++ b/Client/Views/GameWindow.xaml.cs @@ -1,15 +1,8 @@ using Client.ViewModels; -using System; -using System.Collections.Generic; -using System.Text; using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Shapes; + namespace Client.Views { @@ -24,6 +17,7 @@ namespace Client.Views { this.viewModel = new ViewModelGame(); DataContext = this.viewModel; + Closing += this.viewModel.LeaveGame; InitializeComponent(); } @@ -58,5 +52,6 @@ namespace Client.Views { viewModel.Color_Picker(e, this); } + } } diff --git a/Server/Models/ServerClient.cs b/Server/Models/ServerClient.cs index 125c8f7..cfd2483 100644 --- a/Server/Models/ServerClient.cs +++ b/Server/Models/ServerClient.cs @@ -170,6 +170,12 @@ namespace Server.Models sendMessage(JSONConvert.ConstructLobbyJoinSuccessMessage()); ServerCommunication.INSTANCE.sendToAll(JSONConvert.ConstructLobbyListMessage(ServerCommunication.INSTANCE.lobbies.ToArray())); break; + case LobbyIdentifier.LEAVE: + id = JSONConvert.GetLobbyID(payload); + ServerCommunication.INSTANCE.LeaveLobby(User, id); + sendMessage(JSONConvert.ConstructLobbyLeaveMessage(id)); + ServerCommunication.INSTANCE.sendToAll(JSONConvert.ConstructLobbyListMessage(ServerCommunication.INSTANCE.lobbies.ToArray())); + break; } } diff --git a/Server/Models/ServerCommunication.cs b/Server/Models/ServerCommunication.cs index 497f901..c461aa1 100644 --- a/Server/Models/ServerCommunication.cs +++ b/Server/Models/ServerCommunication.cs @@ -161,6 +161,7 @@ namespace Server.Models } } + public int HostForLobby(User user) { Lobby lobby = new Lobby( lobbies.Count + 1,0, 8); @@ -183,5 +184,40 @@ namespace Server.Models } } } + + public void LeaveLobby(User user, int id) + { + Debug.WriteLine("[SERVERCOMM] removing user from lobby"); + foreach (Lobby l in lobbies) + { + if (l.ID == id) + { + Debug.WriteLine($"[SERVERCOMM] checking for lobby with id {l.ID}"); + + foreach (User u in l.Users) + { + Debug.WriteLine($"[SERVERCOMM] checking if {u.Username} is {user.Username} "); + // contains doesn't work, so we'll do it like this... + if (u.Username == user.Username) + { + Debug.WriteLine("[SERVERCOMM] removed user from lobby!"); + l.Users.Remove(user); + foreach (ServerClient sc in serverClients) + { + if (sc.User.Username == user.Username) + { + serverClientsInlobbies[l].Remove(sc); + break; + } + } + break; + } + } + + + + } + } + } } } diff --git a/SharedClientServer/JSONConvert.cs b/SharedClientServer/JSONConvert.cs index dd967e8..9c96f2d 100644 --- a/SharedClientServer/JSONConvert.cs +++ b/SharedClientServer/JSONConvert.cs @@ -139,7 +139,6 @@ namespace SharedClientServer } #endregion - /// /// constructs a message that can be sent to the clients or server /// diff --git a/SharedClientServer/User.cs b/SharedClientServer/User.cs index e504418..8d45dc2 100644 --- a/SharedClientServer/User.cs +++ b/SharedClientServer/User.cs @@ -1,11 +1,12 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Text; namespace SharedClientServer { - class User + class User : IEquatable { private string _username; private int _score; @@ -27,6 +28,42 @@ namespace SharedClientServer _host = false; } + public static bool operator ==(User u1, User u2) + { + if (object.ReferenceEquals(u1, null)) + { + return object.ReferenceEquals(u2, null); + } + return u1.Equals(u2 as object); + } + + public static bool operator !=(User u1, User u2) + { + if (object.ReferenceEquals(u1, null)) + { + return object.ReferenceEquals(u2, null); + } + return u1.Equals(u2 as object); + } + + public override bool Equals(object obj) + { + if ((obj == null) || !this.GetType().Equals(obj.GetType())) + { + return false; + } + else + { + return this.Equals(obj as User); + + } + } + + public bool Equals([AllowNull] User other) + { + return other.Username == this.Username; + } + public string Username { get { return _username; }