void ProcessClient(object _client) { if (!(_client is TcpClient)) { return; } ClientInfo clientInfo = new ClientInfo { isRunning = true, thread = Thread.CurrentThread, client = _client as TcpClient }; clientInfo.stream = clientInfo.client.GetStream(); lock (clientsLocker) { clients.Add(clientInfo); } byte[] data = new byte[ClientConnect.OneObjectSize]; { ClientConnect clientConnect; ClientConnectResponce responce; lock (clientInfo.locker) { while (!clientInfo.stream.DataAvailable) { Thread.Sleep(1); } PacketType type = Protocol.BaseRecieve(clientInfo.stream, out data); if (type == PacketType.ClientConnect) { clientConnect = ClientConnect.Deserialize(data); responce = ClientConnected(clientConnect); clientInfo.playerId = responce.playerId; clientInfo.Send(PacketType.ClientConnectResponce, ClientConnectResponce.Serialize(responce)); List <byte> listWorldState = new List <byte>(); foreach (var state in responce.initialWorldState) { listWorldState.AddRange(GameObjectState.Serialize(state)); } //Console.WriteLine($"Send {listWorldState.Count} bytes to player {responce.playerId}"); clientInfo.Send(PacketType.WorldState, listWorldState.ToArray()); } else { throw new Exception("Recieve smth wrong in Server.ProcessClient()"); } } } data = new byte[BasePlayerAction.OneObjectSize]; BasePlayerAction action; while (clientInfo.isRunning) { lock (clientInfo.locker) { if (!clientInfo.stream.DataAvailable) { System.Threading.Thread.Sleep(1); continue; } PacketType type = Protocol.BaseRecieve(clientInfo.stream, out data); if (type == PacketType.PlayerAction) { action = BasePlayerAction.Deserialize(data); action.playerId = clientInfo.playerId; playerActions.Enqueue(action); } else if (type == PacketType.ClientDisconnect) { clientInfo.isRunning = false; //Console.WriteLine("Client going to disconnect"); ClientDisconnect disconnectInfo = ClientDisconnect.Deserialize(data); //Console.WriteLine("Deserialize disconnect data"); clientInfo.Send(PacketType.ClientDisconnectResponce, ClientDisconnectResponce.Serialize( new ClientDisconnectResponce() { } )); //Console.WriteLine("Send ClientDisconnectResponce"); } } } lock (clientsLocker) { //Console.WriteLine("Close client streams"); lock (clientInfo.locker) { clientInfo.stream.Close(); clientInfo.client.Close(); } //Console.WriteLine("Try to remove from clients"); clients.Remove(clientInfo); } //Console.WriteLine("Close client"); }
public void OnConnectRequest(IAsyncResult ar) { TcpListener listener = (TcpListener)ar.AsyncState; try { Socket ClientConnection = listener.EndAcceptSocket(ar); listener.BeginAcceptSocket(new AsyncCallback(OnConnectRequest), listener); try { nBuffer buffer = new nBuffer(); buffer.ReceiveBuffer(ClientConnection); if (buffer.GetID() == MsgType.ClientConnect) { ClientConnect CC = buffer.GetObject <ClientConnect>(); ConnectedClient client = new ConnectedClient(); client.socket = ClientConnection; client.CC = new ClientConnect(); client.CC.sockettype = CC.sockettype; client.CC.Ip = CC.Ip; client.CC.Salt = CC.Salt; // Only add to clientlist if NOT FileSocket or LogoSocket client.Online = false; for (int i = 0; i < ConnectedClients.Count; i++) { if (ConnectedClients[i].CC.Ip == CC.Ip) // Second connection from same Ip should be discarded { if (CC.sockettype == ConnectionType.Client && ConnectedClients[i].CC.sockettype == ConnectionType.Client) { client.Online = true; ConnectedClients[i] = client; Console.WriteLine("Client " + client.socket.RemoteEndPoint.ToString() + " of Type " + CC.sockettype.ToString() + ", Reconnected"); } } } if (!client.Online) { ConnectedClients.Add(client); client.Online = true; Console.WriteLine("Client " + client.socket.RemoteEndPoint.ToString() + " of Type " + CC.sockettype.ToString() + " joined"); } client.StartThread(recvMessage); } Console.WriteLine("Ready to receive next Incomming connection"); } catch (Exception e) { ClientConnection.Shutdown(SocketShutdown.Both); ClientConnection.Close(1); listener.BeginAcceptSocket(new AsyncCallback(OnConnectRequest), listener); Console.WriteLine("Client " + ClientConnection.RemoteEndPoint + ", timed-out!"); } } catch (Exception e) { Console.WriteLine("Error: " + "\r\n " + e.Message); } }