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");
        }
Beispiel #2
0
        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);
            }
        }