diff --git a/Client/Client.cs b/Client/Client.cs new file mode 100644 index 0000000..e0c88f0 --- /dev/null +++ b/Client/Client.cs @@ -0,0 +1,108 @@ +using SharedClientServer; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Net.Sockets; +using System.Text; + +namespace Client +{ + class Client : ObservableObject + { + private TcpClient tcpClient; + private NetworkStream stream; + private byte[] buffer = new byte[1024]; + private byte[] totalBuffer = new byte[1024]; + private int totalBufferReceived = 0; + public int Port = 5555; + public bool Connected = false; + //TODO send login packet to server with ClientServerUtil.createpayload(0x01,dynamic json with username) + public string username; + + public Client() + { + this.tcpClient = new TcpClient(); + tcpClient.BeginConnect("localhost", Port, new AsyncCallback(OnConnect), null); + } + + private void OnConnect(IAsyncResult ar) + { + this.tcpClient.EndConnect(ar); + this.stream = tcpClient.GetStream(); + this.stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(OnReadComplete),null); + } + + private void OnReadComplete(IAsyncResult ar) + { + int amountReceived = stream.EndRead(ar); + + if (totalBufferReceived + amountReceived > 1024) + { + 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; + expectedMessageLength = BitConverter.ToInt32(totalBuffer, 0); + } + + stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(OnReadComplete), null); + + } + + 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); + switch (id) + { + case 0x01: + // json log in username data + break; + case 0x02: + // 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 + break; + + case 0x03: + // lobby data + //TODO fill lobby with the data received + break; + case 0x04: + // canvas data + break; + default: + Debug.WriteLine("[CLIENT] Received weird identifier: " + id); + break; + } + + } + + public void SendMessage(byte[] message) + { + stream.BeginWrite(message, 0, message.Length, new AsyncCallback(OnWriteComplete), null); + } + + private void OnWriteComplete(IAsyncResult ar) + { + stream.EndWrite(ar); + } + } +} diff --git a/Client/Client.csproj b/Client/Client.csproj index f239f26..d66b4aa 100644 --- a/Client/Client.csproj +++ b/Client/Client.csproj @@ -8,6 +8,7 @@ + @@ -15,4 +16,6 @@ + + \ No newline at end of file diff --git a/Client/ViewModel.cs b/Client/ViewModel.cs index 63d41d5..acd41e8 100644 --- a/Client/ViewModel.cs +++ b/Client/ViewModel.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Text; using System.Windows.Input; +using SharedClientServer; namespace Client { diff --git a/Eindproject/Eindproject.sln b/Eindproject/Eindproject.sln index b96f3b4..4c7629c 100644 --- a/Eindproject/Eindproject.sln +++ b/Eindproject/Eindproject.sln @@ -13,6 +13,7 @@ Global GlobalSection(SharedMSBuildProjectFiles) = preSolution ..\SharedClientServer\SharedClientServer.projitems*{67a9bf1a-d317-47ca-9f07-c3480d1360ff}*SharedItemsImports = 5 ..\SharedClientServer\SharedClientServer.projitems*{6d26f969-9cb1-414f-ac3e-7253d449ac5a}*SharedItemsImports = 13 + ..\SharedClientServer\SharedClientServer.projitems*{83768edb-097e-4089-a5de-208cb252d1a0}*SharedItemsImports = 5 EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/Server/Models/ServerClient.cs b/Server/Models/ServerClient.cs index 94a563f..7aef7a6 100644 --- a/Server/Models/ServerClient.cs +++ b/Server/Models/ServerClient.cs @@ -90,22 +90,30 @@ namespace Server.Models Array.Copy(message,1,payload,0,message.Length-1); switch(id) { + case 0x01: - // canvas data + // json log in username data + string uName = JSONConvert.GetUsernameLogin(message); + if (uName != null) Username = uName; + Debug.WriteLine("[SERVERCLIENT] set username to " + Username); break; case 0x02: // json message data (string, string) combo = JSONConvert.GetUsernameAndMessage(payload); string textUsername = combo.Item1; string textMsg = combo.Item2; + // todo handle sending to all except this user the username and message to display in chat break; case 0x03: - // object data + // lobby data + break; + case 0x04: + // canvas data break; default: - Debug.WriteLine("Received weird identifier: " + id); + Debug.WriteLine("[SERVER] Received weird identifier: " + id); break; } //TODO implement ways to handle the message diff --git a/Server/Models/ServerCommunication.cs b/Server/Models/ServerCommunication.cs index 4dcf07a..7bc0fa1 100644 --- a/Server/Models/ServerCommunication.cs +++ b/Server/Models/ServerCommunication.cs @@ -1,4 +1,5 @@  +using Client; using SharedClientServer; using System; using System.Collections.Generic; @@ -15,6 +16,8 @@ namespace Server.Models private List serverClients; public bool Started = false; public int ClientsConnected { get { return serverClients.Count; } } + public List lobbies; + private Dictionary> serverClientsInlobbies; /// /// use a padlock object to make sure the singleton is thread-safe @@ -28,6 +31,8 @@ namespace Server.Models { listener = new TcpListener(IPAddress.Any, port); serverClients = new List(); + lobbies = new List(); + serverClientsInlobbies = new Dictionary>(); } /// @@ -87,12 +92,44 @@ namespace Server.Models } } - public void sendToAllExcept(string username, byte[] message) + public void SendToAllExcept(string username, byte[] message) { foreach (ServerClient sc in serverClients) { if (sc.Username != username) sc.sendMessage(message); } } + + public void SendToLobby(Lobby lobby, byte[] message) + { + foreach (Lobby l in lobbies) + { + if (l == lobby) + { + foreach (ServerClient sc in serverClientsInlobbies[l]) + { + sc.sendMessage(message); + } + break; + } + } + } + + public void AddToLobby(Lobby lobby, string username) + { + foreach (Lobby l in lobbies) + { + if (l == lobby) + { + bool succ; + l.AddUsername(username, out succ); + if (!succ) + { + // TODO send lobby full message + } + break; + } + } + } } } diff --git a/Server/Server.csproj b/Server/Server.csproj index c6ad1ce..4774318 100644 --- a/Server/Server.csproj +++ b/Server/Server.csproj @@ -6,8 +6,6 @@ true - - @@ -15,4 +13,6 @@ + + \ No newline at end of file diff --git a/SharedClientServer/ClientServerUtil.cs b/SharedClientServer/ClientServerUtil.cs index ba4a894..3572562 100644 --- a/SharedClientServer/ClientServerUtil.cs +++ b/SharedClientServer/ClientServerUtil.cs @@ -8,6 +8,15 @@ namespace SharedClientServer { class ClientServerUtil { + // creates a message array to send to the server or to clients + public byte[] createPayload(byte id, string payload) + { + byte[] stringAsBytes = Encoding.ASCII.GetBytes(payload); + byte[] res = new byte[stringAsBytes.Length + 1]; + res[0] = id; + Array.Copy(stringAsBytes, 0, res, 1, stringAsBytes.Length); + return res; + } } } diff --git a/SharedClientServer/JSONConvert.cs b/SharedClientServer/JSONConvert.cs index 004567a..c52ab50 100644 --- a/SharedClientServer/JSONConvert.cs +++ b/SharedClientServer/JSONConvert.cs @@ -13,5 +13,12 @@ namespace SharedClientServer dynamic payload = JsonConvert.DeserializeObject(msg); return (payload.username, payload.message); } + + public static string GetUsernameLogin(byte[] json) + { + string msg = Encoding.ASCII.GetString(json); + dynamic payload = JsonConvert.DeserializeObject(msg); + return payload.username; + } } } diff --git a/SharedClientServer/Lobby.cs b/SharedClientServer/Lobby.cs index f408097..283c219 100644 --- a/SharedClientServer/Lobby.cs +++ b/SharedClientServer/Lobby.cs @@ -13,12 +13,24 @@ namespace Client private int _id; private int _playersIn; private int _maxPlayers; + private List _usernames; + + public void AddUsername(string username, out bool success) + { + success = false; + if (_usernames.Count < _maxPlayers) + { + _usernames.Add(username); + success = true; + } + } public Lobby(int id, int playersIn, int maxPlayers) { _id = id; _playersIn = playersIn; _maxPlayers = maxPlayers; + _usernames = new List(); } public int ID diff --git a/SharedClientServer/SharedClientServer.projitems b/SharedClientServer/SharedClientServer.projitems index 97e39cb..c99a749 100644 --- a/SharedClientServer/SharedClientServer.projitems +++ b/SharedClientServer/SharedClientServer.projitems @@ -11,6 +11,7 @@ + \ No newline at end of file