コード例 #1
0
        private void DisconnectSession(AsyncSocketSession session)
        {
            // Socket already gone, someone else already cleaned it up
            Task removedSocket;

            if (!sessions.TryRemove(session, out removedSocket))
            {
                return;
            }

            try
            {
                session.Socket.Shutdown(SocketShutdown.Both);
            }
            catch (Exception)
            {
            }

            session.Socket.Close();

            if (session.Player != null)
            {
                session.Player.HasTwoFactorAuthenticated = null;

                logger.Info("Player disconnect {0}(1) IP: {2}", session.Player.Name, session.Player.PlayerId, session.RemoteIP);
            }
            else
            {
                logger.Debug("Socket disconnect without logged in player IP[{0}]", session.RemoteIP);
            }

            ThreadPool.UnsafeQueueUserWorkItem(obj => session.ProcessEvent(new Packet(Command.OnDisconnect)), null);
        }
コード例 #2
0
        private void Add(AsyncSocketSession session)
        {
            session.OnClose += OnClose;

            var readTask = ReadLoop(session);

            sessions.TryAdd(session, readTask);
            readTask.CatchUnhandledException("ReadTask for " + session.RemoteIP);
        }
コード例 #3
0
        private async Task ReadLoop(AsyncSocketSession session)
        {
            session.ProcessEvent(new Packet(Command.OnConnect));

            var hasCheckedForPolicyFile = false;

            var socketAwaitable = socketAwaitablePool.Take();

            var buffer = bufferManager.GetBuffer();

            socketAwaitable.Buffer = buffer;

            try
            {
                do
                {
                    // Check if it's a policy file request
                    if (!hasCheckedForPolicyFile && session.PacketMaker.Length > 22)
                    {
                        hasCheckedForPolicyFile = true;

                        if (Encoding.UTF8.GetString(session.PacketMaker.GetBytes(), 0, 22) == "<policy-file-request/>")
                        {
                            logger.Debug("Serving policy file through game server to {0}", session.RemoteIP);
                            try
                            {
                                await session.SendAsyncImmediatelly(policyFile);

                                session.Socket.Shutdown(SocketShutdown.Both);
                                session.Socket.Close(1);
                            }
                            catch (Exception e)
                            {
                                if (logger.IsDebugEnabled)
                                {
                                    logger.Debug(e, "Handled exception while serving policy file on main game port");
                                }
                            }

                            Task removedSocket;
                            sessions.TryRemove(session, out removedSocket);

                            return;
                        }
                    }

                    // Keep processing as many packets as we can
                    do
                    {
                        Packet packet = session.PacketMaker.GetNextPacket();

                        if (packet == null)
                        {
                            // Remove the player if after processing packets we still have over 1MB of data remaining.
                            // This probably means the player is spamming the server with an invalid client
                            if (session.PacketMaker.Length > 1048576)
                            {
                                DisconnectSession(session);
                                return;
                            }

                            break;
                        }

                        session.Process(packet);
                    }while (true);

                    // Read more data
                    var result = await session.Socket.ReceiveAsync(socketAwaitable);

                    if (result != SocketError.Success || socketAwaitable.Transferred.Count == 0)
                    {
                        break;
                    }

                    session.PacketMaker.Append(socketAwaitable.Transferred);
                }while (true);

                DisconnectSession(session);
            }
            catch (SocketException e)
            {
                logger.Info(e, "Handled socket exception while receiving socket data IP[{0}]", session.RemoteIP);

                DisconnectSession(session);
            }
            catch (ObjectDisposedException)
            {
            }
            catch (Exception e)
            {
                logger.ErrorException("Unhandled exception in readloop", e);

                throw;
            }
            finally
            {
                socketAwaitable.Clear();
                socketAwaitablePool.Add(socketAwaitable);

                bufferManager.ReleaseBuffer(buffer);
            }
        }