diff --git a/Client/Client.cs b/Client/Client.cs index 6ba9b16..71e8c43 100644 --- a/Client/Client.cs +++ b/Client/Client.cs @@ -4,9 +4,11 @@ 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); class Client : ObservableObject { private TcpClient tcpClient; @@ -18,6 +20,11 @@ namespace Client public bool Connected = false; private string username; public Callback OnSuccessfullConnect; + public Callback OnLobbiesListReceived; + public Callback OnLobbyJoinSuccess; + public Callback OnLobbiesReceivedAndWaitingForHost; + public OnLobbyCreated OnLobbyCreated; + public Lobby[] Lobbies { get; set; } public Client(string username) { @@ -70,9 +77,9 @@ namespace Client private void handleData(byte[] message) { - byte id = message[0]; - byte[] payload = new byte[message.Length - 1]; - Array.Copy(message, 1, payload, 0, message.Length - 1); + 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: @@ -89,6 +96,26 @@ namespace Client 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: diff --git a/Client/ViewModels/ViewModel.cs b/Client/ViewModels/ViewModel.cs index be55690..bbb9843 100644 --- a/Client/ViewModels/ViewModel.cs +++ b/Client/ViewModels/ViewModel.cs @@ -9,6 +9,8 @@ using System.Diagnostics; using System.Windows; using System.Collections.ObjectModel; using Client.Views; +using System.Linq; +using System.Windows.Data; namespace Client { @@ -21,21 +23,101 @@ namespace Client public Lobby SelectedLobby { get; set; } + private Client client; + + private bool wantToBeHost = false; + private int wantToBeHostId = 0; + public ViewModel() { _model = new Model(); _lobbies = new ObservableCollection(); + client = ClientData.Instance.Client; + client.OnLobbiesListReceived = updateLobbies; + - _lobbies.Add(new Lobby(50, 3, 8)); - _lobbies.Add(new Lobby(69, 1, 9)); - _lobbies.Add(new Lobby(420, 7, 7)); + OnHostButtonClick = new RelayCommand(hostGame); - OnHostButtonClick = new RelayCommand(() => + JoinSelectedLobby = new RelayCommand(joinLobby, true); + } + + private void hostGame() + { + Debug.WriteLine("attempting to host game for " + ClientData.Instance.User.Username); + client.SendMessage(JSONConvert.ConstructLobbyHostMessage()); + client.OnLobbyCreated = becomeHostForLobby; + } + + private void becomeHostForLobby(int id) + { + + Debug.WriteLine($"got host succes with data {id} "); + wantToBeHost = true; + wantToBeHostId = id; + client.OnLobbiesReceivedAndWaitingForHost = hostLobbiesReceived; + + } + + private void hostLobbiesReceived() + { + if (wantToBeHost) + foreach (Lobby l in Lobbies) + { + if (l.ID == wantToBeHostId) + { + Debug.WriteLine("found lobby that we want to be host of: " + l.ID + ", joining.."); + SelectedLobby = l; + startGameInLobby(); + wantToBeHost = false; + client.OnLobbiesReceivedAndWaitingForHost = null; + break; + } + } + } + + private void joinLobby() + { + // lobby die je wilt joinen verwijderen + // nieuwe binnengekregen lobby toevoegen + client.OnLobbyJoinSuccess = OnLobbyJoinSuccess; + client.SendMessage(JSONConvert.ConstructLobbyJoinMessage(SelectedLobby.ID)); + } + + private void OnLobbyJoinSuccess() + { + startGameInLobby(); + } + + + + private void updateLobbies() + { + Debug.WriteLine("updating lobbies..."); + Lobby[] lobbiesArr = client.Lobbies; + Application.Current.Dispatcher.Invoke(delegate { - Debug.WriteLine("Host button clicked"); - }); + + //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]); + // } + //} - JoinSelectedLobby = new RelayCommand(startGameInLobby, true); + _lobbies.Clear(); + + foreach (Lobby l in lobbiesArr) + { + _lobbies.Add(l); + } + + }); } private void startGameInLobby() @@ -43,11 +125,18 @@ namespace Client if (SelectedLobby != null) { ClientData.Instance.Lobby = SelectedLobby; - - _model.CanStartGame = false; + startGameWindow(); + } + } + + private void startGameWindow() + { + _model.CanStartGame = false; + Application.Current.Dispatcher.Invoke(delegate + { GameWindow window = new GameWindow(); window.Show(); - } + }); } private void ClickCheck() diff --git a/Client/Views/GameWindow.xaml.cs b/Client/Views/GameWindow.xaml.cs index aacc67e..f527b39 100644 --- a/Client/Views/GameWindow.xaml.cs +++ b/Client/Views/GameWindow.xaml.cs @@ -113,5 +113,10 @@ namespace Client.Views string user = data.User.Username; SentMessage.AppendText($"{user}: {message}\n"); } + + private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) + { + + } } } diff --git a/Client/Views/LoginScreen.xaml.cs b/Client/Views/LoginScreen.xaml.cs index 780b619..5b742d2 100644 --- a/Client/Views/LoginScreen.xaml.cs +++ b/Client/Views/LoginScreen.xaml.cs @@ -34,6 +34,7 @@ namespace Client.Views Application.Current.Dispatcher.Invoke(delegate { data.User = user; data.Client = client; + client.SendMessage(JSONConvert.ConstructLobbyRequestMessage()); MainWindow startWindow = new MainWindow(); startWindow.Show(); this.Close(); diff --git a/Client/Views/MainWindow.xaml.cs b/Client/Views/MainWindow.xaml.cs index aa9cf2f..058bbc8 100644 --- a/Client/Views/MainWindow.xaml.cs +++ b/Client/Views/MainWindow.xaml.cs @@ -33,18 +33,7 @@ namespace Client private void Button_Click(object sender, RoutedEventArgs e) { - Lobby lobbySelected = LobbyList.SelectedItem as Lobby; - if(lobbySelected != null) - { - testLabel.Content = lobbySelected.ID; - colorSelection.IsEnabled = false; - joinButton.IsEnabled = false; - hostButton.IsEnabled = false; - - GameWindow window = new GameWindow(); - window.Show(); - Close(); - } + } } } diff --git a/Server/Models/ServerClient.cs b/Server/Models/ServerClient.cs index b10639b..24a7a6f 100644 --- a/Server/Models/ServerClient.cs +++ b/Server/Models/ServerClient.cs @@ -1,10 +1,12 @@  +using Client; using SharedClientServer; using System; using System.Collections.Generic; using System.Diagnostics; using System.Net.Sockets; using System.Text; +using static SharedClientServer.JSONConvert; namespace Server.Models { @@ -121,6 +123,8 @@ namespace Server.Models case JSONConvert.LOBBY: // lobby data + LobbyIdentifier l = JSONConvert.GetLobbyIdentifier(payload); + handleLobbyMessage(payload,l); break; case JSONConvert.CANVAS: // canvas data @@ -130,7 +134,30 @@ namespace Server.Models Debug.WriteLine("[SERVER] Received weird identifier: " + id); break; } - //TODO implement ways to handle the message + } + + private void handleLobbyMessage(byte[] payload, LobbyIdentifier l) + { + switch (l) + { + case LobbyIdentifier.REQUEST: + Debug.WriteLine("[SERVERCLIENT] got lobby request message, sending lobbies..."); + sendMessage(JSONConvert.ConstructLobbyListMessage(ServerCommunication.INSTANCE.lobbies.ToArray())); + break; + case LobbyIdentifier.HOST: + // add new lobby and add this serverclient to it + int createdLobbyID = ServerCommunication.INSTANCE.HostForLobby(this.User); + Debug.WriteLine("[SERVERCLIENT] created lobby"); + sendMessage(JSONConvert.ConstructLobbyHostCreatedMessage(createdLobbyID)); + ServerCommunication.INSTANCE.sendToAll(JSONConvert.ConstructLobbyListMessage(ServerCommunication.INSTANCE.lobbies.ToArray())); + break; + case LobbyIdentifier.JOIN: + int id = JSONConvert.GetLobbyID(payload); + ServerCommunication.INSTANCE.JoinLobby(this.User,id); + sendMessage(JSONConvert.ConstructLobbyJoinSuccessMessage()); + ServerCommunication.INSTANCE.sendToAll(JSONConvert.ConstructLobbyListMessage(ServerCommunication.INSTANCE.lobbies.ToArray())); + break; + } } /// diff --git a/Server/Models/ServerCommunication.cs b/Server/Models/ServerCommunication.cs index ee51859..497f901 100644 --- a/Server/Models/ServerCommunication.cs +++ b/Server/Models/ServerCommunication.cs @@ -32,7 +32,10 @@ namespace Server.Models listener = new TcpListener(IPAddress.Any, port); serverClients = new List(); lobbies = new List(); + Lobby temp = new Lobby(1, 7, 8); + lobbies.Add(temp); serverClientsInlobbies = new Dictionary>(); + serverClientsInlobbies.Add(temp, new List()); } /// @@ -117,6 +120,18 @@ namespace Server.Models } } + public Lobby GetLobbyForUser(User user) + { + foreach (Lobby l in lobbies) + { + if (l.Users.Contains(user)) + { + return l; + } + } + return null; + } + public void AddToLobby(Lobby lobby, User user) { foreach (Lobby l in lobbies) @@ -125,6 +140,7 @@ namespace Server.Models { bool succ; l.AddUser(user, out succ); + Debug.WriteLine("[SERVERCOMM] added user to lobby, now contains " + l.PlayersIn); if (!succ) { // TODO send lobby full message @@ -144,5 +160,28 @@ namespace Server.Models } } } + + public int HostForLobby(User user) + { + Lobby lobby = new Lobby( lobbies.Count + 1,0, 8); + lobbies.Add(lobby); + serverClientsInlobbies.Add(lobby, new List()); + user.Host = true; + AddToLobby(lobby, user); + return lobby.ID; + } + + public void JoinLobby(User user, int id) + { + foreach (Lobby l in lobbies) + { + if (l.ID == id) + { + AddToLobby(l, user); + Debug.WriteLine($"{user.Username} joined lobby with id {id}"); + break; + } + } + } } } diff --git a/SharedClientServer/JSONConvert.cs b/SharedClientServer/JSONConvert.cs index b0d83cb..dd967e8 100644 --- a/SharedClientServer/JSONConvert.cs +++ b/SharedClientServer/JSONConvert.cs @@ -1,8 +1,10 @@ using Client; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Text; namespace SharedClientServer @@ -14,11 +16,13 @@ namespace SharedClientServer public const byte LOBBY = 0x03; public const byte CANVAS = 0x04; - enum LobbyIdentifier + public enum LobbyIdentifier { HOST, - ADD, + JOIN, + JOIN_SUCCESS, LEAVE, + LIST, REQUEST } public static (string,string) GetUsernameAndMessage(byte[] json) @@ -43,12 +47,98 @@ namespace SharedClientServer }); } - public static byte[] ConstructLobbyDataMessage(Lobby lobby) + #region lobby messages + + public static byte[] ConstructLobbyHostMessage() { - return null; + return GetMessageToSend(LOBBY, new + { + identifier = LobbyIdentifier.HOST + }); } + public static byte[] ConstructLobbyHostCreatedMessage(int lobbyID) + { + return GetMessageToSend(LOBBY, new + { + identifier = LobbyIdentifier.HOST, + id = lobbyID + }) ; + } + public static byte[] ConstructLobbyRequestMessage() + { + return GetMessageToSend(LOBBY, new + { + identifier = LobbyIdentifier.REQUEST + }); + } + + public static byte[] ConstructLobbyListMessage(Lobby[] lobbiesList) + { + return GetMessageToSend(LOBBY, new + { + identifier = LobbyIdentifier.LIST, + lobbies = lobbiesList + }); + } + + public static byte[] ConstructLobbyJoinMessage(int lobbyID) + { + return GetMessageToSend(LOBBY, new + { + identifier = LobbyIdentifier.JOIN, + id = lobbyID + }); + } + + public static byte[] ConstructLobbyLeaveMessage(int lobbyID) + { + return GetMessageToSend(LOBBY, new + { + identifier = LobbyIdentifier.LEAVE, + id = lobbyID + }); + } + public static LobbyIdentifier GetLobbyIdentifier(byte[] json) + { + dynamic payload = JsonConvert.DeserializeObject(Encoding.ASCII.GetString(json)); + return payload.identifier; + } + + public static Lobby[] GetLobbiesFromMessage(byte[] json) + { + dynamic payload = JsonConvert.DeserializeObject(Encoding.ASCII.GetString(json)); + JArray lobbiesArray = payload.lobbies; + Debug.WriteLine("[JSONCONVERT] got lobbies from message" + lobbiesArray.ToString()); + Lobby[] lobbiesTemp = lobbiesArray.ToObject(); + Debug.WriteLine("lobbies in array: "); + foreach (Lobby l in lobbiesTemp) + { + Debug.WriteLine("players: " + l.PlayersIn); + } + return lobbiesTemp; + } + + public static int GetLobbyID(byte[] json) + { + dynamic payload = JsonConvert.DeserializeObject(Encoding.ASCII.GetString(json)); + return payload.id; + } + + public static Lobby GetLobby(byte[] json) + { + dynamic payload = JsonConvert.DeserializeObject(Encoding.ASCII.GetString(json)); + JObject dynamicAsObject = payload.lobby; + return dynamicAsObject.ToObject(); + } + + public static byte[] ConstructLobbyJoinSuccessMessage() + { + return GetMessageToSend(LOBBY, new { identifier = LobbyIdentifier.JOIN_SUCCESS}); + } + + #endregion /// /// constructs a message that can be sent to the clients or server @@ -70,5 +160,7 @@ namespace SharedClientServer Array.Copy(BitConverter.GetBytes(payloadBytes.Length+5),0,res,0,4); return res; } + + } } diff --git a/SharedClientServer/Lobby.cs b/SharedClientServer/Lobby.cs index 5a69627..2ddf501 100644 --- a/SharedClientServer/Lobby.cs +++ b/SharedClientServer/Lobby.cs @@ -64,16 +64,29 @@ namespace Client public int PlayersIn { - get { return _playersIn; } + get { return _users.Count; } set { _playersIn = value; } } + public void Set(Lobby lobby) + { + this._id = lobby._id; + this._users = lobby._users; + this._maxPlayers = lobby._maxPlayers; + } + public int MaxPlayers { get { return _maxPlayers; } set { _maxPlayers = value; } } + public List Users + { + get { return _users; } + set { _users = value; } + } + } } diff --git a/SharedClientServer/User.cs b/SharedClientServer/User.cs index 6e95f64..35ec378 100644 --- a/SharedClientServer/User.cs +++ b/SharedClientServer/User.cs @@ -1,4 +1,5 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; using System.Text; @@ -10,6 +11,7 @@ namespace SharedClientServer private int _score; private bool _host; + [JsonConstructor] public User(string username, int score, bool host) { _username = username;