public void ReceiveTcp(AsyncSocket.ReadResult rr)
 {
     Read(rr.Buffer);
 }
        public void RemoveTarget(AsyncSocket socket)
        {
            bool b;
            _connectedClients.TryRemove(socket, out b);

            PlayerEndPoint endPoint;
            // perhaps add socket to PlayerEndPoint so we can always efficiently remove the player from _connectedClients
            if (_playerEndPoints.TryRemove(socket.IpEndPoint, out endPoint))
            {
                Console.WriteLine($"Client: {socket.IpEndPoint.ToString().Replace("::ffff:", "")} disconnected.");
                bool b2;
                _udpEndPoints.TryRemove(endPoint.IpEndPoint, out b2);

                Game game;
                if (BoDService.PlayerIngame.TryRemove(endPoint.PlayerId, out game))
                {
                    game.RemovePlayer(endPoint.PlayerId);
                    Console.WriteLine($"Player: {endPoint.PlayerId} quit game: {game.Id}.");
                }
            }
            socket.Dispose();
        }
        private async Task AcceptClientAsync(Socket socket)
        {
            await Task.Yield();

            AsyncSocket s = null;
            try
            {
                s = new AsyncSocket(socket);
            }
            catch (SocketException)
            {
                socket.Dispose();
                return;
            }

            _connectedClients.TryAdd(s, true);
            Console.WriteLine($"Client connected: {s.IpEndPoint?.ToString().Replace("::ffff:", "")}");

            try
            {
                while (true)
                {
                    Task<AsyncSocket.ReadResult> receive = s.ReceiveAsync();
                    await receive;
                    ReceiveTcp(receive.Result);
                }
            }
            catch (SocketException)
            {
            }
            catch (ObjectDisposedException)
            {
            }
            finally
            {
                RemoveTarget(s);
            }
        }
Exemple #4
0
        public void RemoveTarget(AsyncSocket socket)
        {
            LightEvent e;
            _connectedClients.TryRemove(socket, out e);

            PlayerEndPoint endPoint;
            // perhaps add socket to PlayerEndPoint so we can always efficiently remove the player from _connectedClients
            if (_playerEndPoints.TryRemove(socket.IpEndPoint, out endPoint))
            {
                BoDConsole.WriteLine($"Client: {socket.IpEndPoint.Address.MapToIPv4()}:{socket.IpEndPoint.Port} disconnected.");

                // If any PlayerEndPoint, other than the one that was just removed, 
                // references PlayerId, the player must be connected on another PlayerEndPoint.
                if (_playerEndPoints.Values.All(p => p.PlayerId != endPoint.PlayerId))
                {
                    Game game;
                    if (BoDService.PlayerIngame.TryRemove(endPoint.PlayerId, out game))
                    {
                        game.RemovePlayer(endPoint.PlayerId);
                    }
                }
            }
            socket.Dispose();
        }
Exemple #5
0
        private async Task ReceiveFromClientAsync(AsyncSocket s)
        {
            while (true)
            {
                AsyncSocket.ReadResult result = await s.ReceiveAsync();

                LightEvent e;
                if (_connectedClients.TryGetValue(s, out e))
                {
                    // Reset the LightEvent's timer to prevent timeout.
                    e.Reset();
                }

                Read(result.Buffer, s.IpEndPoint);
            }
        }
Exemple #6
0
        /// <summary>
        /// Awaits a message from the client containing a sessionId.
        /// If the sessionId matches any we have given out. Assign the found PlayerEndPoint
        /// to the client. We write back the sessionId again as a signal that the client should
        /// begin attempting to "connect" with UDP.
        /// </summary>
        /// <param name="socket"> The TCP socket for the client. </param>
        /// <returns> true if the client succesfully verified through TCP. false otherwise. </returns>
        private async Task<bool> AddTCPTarget(AsyncSocket socket)
        {
            AsyncSocket.ReadResult result = await socket.ReceiveAsync();
            if (result.BytesRead != SESSIONID_LENGTH)
            {
                return false;
            }

            string sessionId = Convert.ToBase64String(result.Buffer);
            PlayerEndPoint playerEndPoint;
            if (!_playerSessionTokens.TryGetValue(sessionId, out playerEndPoint))
            {
                return false;
            }

            if (sessionId != playerEndPoint.SessionId)
                return false;

            playerEndPoint.TCPSocket = socket;

            await socket.SendMessage(result.Buffer);

            return _playerEndPoints.TryAdd(socket.IpEndPoint, playerEndPoint);
        }
Exemple #7
0
        private async Task AcceptClientAsync(Socket socket)
        {
            await Task.Yield();

            AsyncSocket s = null;
            try
            {
                s = new AsyncSocket(socket);
            }
            catch (SocketException)
            {
                socket.Dispose();
                return;
            }

            // Cancel the attempt to communicate with the client on both TCP and UDP after 10 sec.
            CancellationTokenSource cts = new CancellationTokenSource(TCP_TIMEOUT);
            Task timeout = new Task(async () =>
            {
                await Task.Delay(TCP_TIMEOUT);
                throw new SocketException();
            });

            try
            {
                Task<bool> tcp = AddTCPTarget(s);
                // Only await timeout once. If tcp finishes first we wont get an exception when timeout finishes.
                await Task.WhenAny(tcp, timeout);

                // await tcp here aswell because we want the result of it. Once we got the result of AddTCPTarget(),
                // we await the result of AddUDPTarget.
                PlayerEndPoint playerEndPoint;
                if (await tcp && _playerEndPoints.TryGetValue(s.IpEndPoint, out playerEndPoint) && await AddUDPTarget(playerEndPoint, cts.Token))
                {
                    // Timeout the TCP and UDP connection to a client if we dont receive a TCP message
                    // at least once per 10 sec.
                    _connectedClients.TryAdd(s, new LightEvent(TCP_TIMEOUT, () => { RemoveTarget(s); }));
                    playerEndPoint.InactivityEvent = new LightEvent(60000, () => { RemoveTarget(s); });

                    BoDConsole.WriteLine($"Client connected: {s.IpEndPoint.Address.MapToIPv4()}");
                    // Start reading actual game related messages from the client.
                    await ReceiveFromClientAsync(s);
                }
            }
            catch (SocketException)
            {
            }
            catch (ObjectDisposedException)
            {
            }
            finally
            {
                cts.Dispose();
                RemoveTarget(s);
            }
        }
        private async Task AcceptClientAsync(Socket socket)
        {
            await Task.Yield();

            AsyncSocket s = null;
            try
            {
                s = new AsyncSocket(socket);
                _connectedClients.TryAdd(s, true);
                Console.WriteLine($"Client connected: {s.IpEndPoint?.ToString().Replace("::ffff:", "")}");

                while (true)
                {
                    Task<AsyncSocket.ReadResult> receive = s.ReceiveAsync();
                    await receive;
                    ReceiveTcp(receive.Result);
                }
            }
            catch (SocketException)
            {
            }
            finally
            {
                if (s != null)
                {
                    bool b;
                    if (_connectedClients.TryRemove(s, out b))
                    {
                        IPEndPoint ip = s.IpEndPoint;
                        if (ip != null)
                        {
                            Console.WriteLine($"Client: {ip.ToString().Replace("::ffff:", "")} disconnected.");
                            RemoveTarget(ip);
                        }
                    }
                    s.Dispose();
                }
                socket?.Close();
            }
        }