public async Task ClientWebSocketChannelWriteAfterCloseTest()
        {
            var websocket = new ClientWebSocket();

            websocket.Options.AddSubProtocol(WebSocketConstants.SubProtocols.Mqtt);
            var uri = new Uri("ws://" + IotHubName + ":" + Port + WebSocketConstants.UriSuffix);
            await websocket.ConnectAsync(uri, CancellationToken.None);

            clientWebSocketChannel = new ClientWebSocketChannel(null, websocket);

            var threadLoop = new SingleThreadEventLoop("MQTTExecutionThread", TimeSpan.FromSeconds(1));
            await threadLoop.RegisterAsync(clientWebSocketChannel);

            await clientWebSocketChannel.CloseAsync();

            // Test Write API
            try
            {
                await clientWebSocketChannel.WriteAndFlushAsync(Unpooled.Buffer());

                Assert.Fail("Should have thrown ClosedChannelException");
            }
            catch (AggregateException e)
            {
                var innerException = e.InnerException as ClosedChannelException;
                Assert.IsNotNull(innerException);
            }

            done = true;
        }
Ejemplo n.º 2
0
        public void Setup()
        {
            _session = Substitute.For <ISession>();

            _pipeline = Substitute.For <IChannelPipeline>();

            _group = new SingleThreadEventLoop();

            _serializationService = new MessageSerializationService();

            _channel = Substitute.For <IChannel>();
            _channel.Pipeline.Returns(_pipeline);
            _channel.RemoteAddress.Returns(new IPEndPoint(IPAddress.Loopback, 8003));

            _channelHandlerContext = Substitute.For <IChannelHandlerContext>();
            _channelHandlerContext.Channel.Returns(_channel);

            _handshakeService = Substitute.For <IHandshakeService>();
            _handshakeService.Auth(Arg.Any <PublicKey>(), Arg.Any <EncryptionHandshake>()).Returns(_authPacket);
            _handshakeService.Ack(Arg.Any <EncryptionHandshake>(), Arg.Any <Packet>()).Returns(_ackPacket).AndDoes(ci => ci.Arg <EncryptionHandshake>().Secrets = NetTestVectors.BuildSecretsWithSameIngressAndEgress());
            _handshakeService.When(s => s.Agree(Arg.Any <EncryptionHandshake>(), Arg.Any <Packet>())).Do(ci => ci.Arg <EncryptionHandshake>().Secrets           = NetTestVectors.BuildSecretsWithSameIngressAndEgress());

            _logger = NullLogManager.Instance;
            _session.RemoteNodeId.Returns(NetTestVectors.StaticKeyB.PublicKey);
        }
Ejemplo n.º 3
0
        public async Task StartWithExistingSocket(StreamSocket socket)
        {
            try
            {
                Debug.WriteLine($"{nameof(PushClient)}: Starting with existing socket.");
                Socket = socket;
                if (_loopGroup != null)
                {
                    await Shutdown().ConfigureAwait(false);
                }
                _loopGroup = new SingleThreadEventLoop();

                var streamSocketChannel = new StreamSocketChannel(Socket);
                streamSocketChannel.Pipeline.AddLast(new FbnsPacketEncoder(), new FbnsPacketDecoder(), this);

                await _loopGroup.RegisterAsync(streamSocketChannel).ConfigureAwait(false);
                await SendPing().ConfigureAwait(false);

                await _context.Executor.Schedule(KeepAliveLoop, TimeSpan.FromSeconds(KEEP_ALIVE - 60));
            }
            catch (TaskCanceledException)
            {
                // pass
            }
            catch (Exception e)
            {
#if !DEBUG
                Crashes.TrackError(e);
#endif
                await Shutdown().ConfigureAwait(false);
            }
        }
Ejemplo n.º 4
0
        public async Task StartAsync(EndPoint endPoint)
        {
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug($"准备启动服务主机,监听地址:{endPoint}。");
            }

            IEventLoopGroup bossGroup   = new MultithreadEventLoopGroup(1);
            IEventLoopGroup workerGroup = new MultithreadEventLoopGroup();//Default eventLoopCount is Environment.ProcessorCount * 2
            var             bootstrap   = new ServerBootstrap();

            if (AppConfig.ServerOptions.Libuv)
            {
                var dispatcher = new DispatcherEventLoopGroup();
                bossGroup   = dispatcher;
                workerGroup = new WorkerEventLoopGroup(dispatcher);
                bootstrap.Channel <TcpServerChannel>();
            }
            else
            {
                bossGroup   = new MultithreadEventLoopGroup(1);
                workerGroup = new MultithreadEventLoopGroup();
                bootstrap.Channel <TcpServerSocketChannel>();
            }
            var workerGroup1 = new SingleThreadEventLoop();

            bootstrap
            .Option(ChannelOption.SoBacklog, AppConfig.ServerOptions.SoBacklog)
            .ChildOption(ChannelOption.Allocator, PooledByteBufferAllocator.Default)
            .Group(bossGroup, workerGroup)
            .ChildHandler(new ActionChannelInitializer <IChannel>(channel =>
            {
                var pipeline = channel.Pipeline;
                pipeline.AddLast(new LengthFieldPrepender(4));
                pipeline.AddLast(new LengthFieldBasedFrameDecoder(int.MaxValue, 0, 4, 0, 4));
                pipeline.AddLast(workerGroup1, "HandlerAdapter", new TransportMessageChannelHandlerAdapter(_transportMessageDecoder));
                pipeline.AddLast(workerGroup1, "ServerHandler", new ServerHandler(async(contenxt, message) =>
                {
                    var sender = new DotNettyServerMessageSender(_transportMessageEncoder, contenxt);
                    await OnReceived(sender, message);
                }, _logger));
            }));
            try
            {
                _channel = await bootstrap.BindAsync(endPoint);

                if (_logger.IsEnabled(LogLevel.Debug))
                {
                    _logger.LogDebug($"服务主机启动成功,监听地址:{endPoint}。");
                }
            }
            catch
            {
                _logger.LogError($"服务主机启动失败,监听地址:{endPoint}。 ");
            }
        }
        public async Task ClientWebSocketChannelReadWithoutConnectTest()
        {
            var websocket = new ClientWebSocket();

            clientWebSocketChannel = new ClientWebSocketChannel(null, websocket);
            var threadLoop = new SingleThreadEventLoop("MQTTExecutionThread", TimeSpan.FromSeconds(1));
            await threadLoop.RegisterAsync(clientWebSocketChannel);

            clientWebSocketChannel.Read();
        }
        public async Task ClientWebSocketChannelWriteWithoutConnectTest()
        {
            var websocket = new ClientWebSocket();

            clientWebSocketChannel = new ClientWebSocketChannel(null, websocket);
            var threadLoop = new SingleThreadEventLoop("MQTTExecutionThread", TimeSpan.FromSeconds(1));
            await threadLoop.RegisterAsync(clientWebSocketChannel).ConfigureAwait(false);

            await clientWebSocketChannel.WriteAndFlushAsync(new ConnectPacket()).ConfigureAwait(false);
        }
Ejemplo n.º 7
0
        public async Task CanCloseTheChannel()
        {
            var webSocket = Mock.Of <WebSocket>(ws => ws.State == WebSocketState.Open);
            var channel   = new ServerWebSocketChannel(webSocket, Mock.Of <EndPoint>());
            var loop      = new SingleThreadEventLoop();
            await loop.RegisterAsync(channel);

            await channel.CloseAsync();

            Assert.False(channel.Active);
            Mock.Get(webSocket).Verify(
                ws => ws.CloseAsync(WebSocketCloseStatus.NormalClosure, It.IsAny <string>(), It.IsAny <CancellationToken>()));
        }
Ejemplo n.º 8
0
        public async Task DoesNotCloseAnAlreadyClosedWebSocket()
        {
            var webSocket = Mock.Of <WebSocket>(ws => ws.State == WebSocketState.Open);
            var channel   = new ServerWebSocketChannel(webSocket, Mock.Of <EndPoint>());
            var loop      = new SingleThreadEventLoop();
            await loop.RegisterAsync(channel);

            Mock <WebSocket> wsMock = Mock.Get(webSocket);

            wsMock.Setup(ws => ws.State).Returns(WebSocketState.Closed);
            wsMock.Setup(ws => ws.CloseAsync(It.IsAny <WebSocketCloseStatus>(), It.IsAny <string>(), It.IsAny <CancellationToken>()))
            .Throws(new Exception("WebSocket.CloseAsync should not be called"));

            await channel.CloseAsync();
        }
Ejemplo n.º 9
0
        public async Task Shutdown()
        {
            if (_loopGroup != null)
            {
                Debug.WriteLine("Stopped pinging push server");
                var loopGroup = _loopGroup;
                _loopGroup = null;
                try
                {
                    await loopGroup.ShutdownGracefullyAsync(TimeSpan.FromSeconds(0.2), TimeSpan.FromSeconds(1))
                    .ConfigureAwait(false);
                }
                catch (Exception e)
                {
#if !DEBUG
                    Crashes.TrackError(e);
#endif
                }
            }
        }
        public async Task ClientWebSocketChannelReadAfterCloseTest()
        {
            var websocket = new ClientWebSocket();

            websocket.Options.AddSubProtocol(WebSocketConstants.SubProtocols.Mqtt);
            var uri = new Uri("ws://" + IotHubName + ":" + Port + WebSocketConstants.UriSuffix);
            await websocket.ConnectAsync(uri, CancellationToken.None);

            var clientReadListener = new ReadListeningHandler();
            var clientChannel      = new ClientWebSocketChannel(null, websocket);

            clientChannel
            .Option(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default)
            .Option(ChannelOption.AutoRead, true)
            .Option(ChannelOption.RcvbufAllocator, new AdaptiveRecvByteBufAllocator())
            .Option(ChannelOption.MessageSizeEstimator, DefaultMessageSizeEstimator.Default);

            clientChannel.Pipeline.AddLast(
                clientReadListener);
            var threadLoop = new SingleThreadEventLoop("MQTTExecutionThread", TimeSpan.FromSeconds(1));
            await threadLoop.RegisterAsync(clientChannel);

            await clientChannel.CloseAsync();

            // Test Read API
            try
            {
                await clientReadListener.ReceiveAsync(DefaultTimeout);

                Assert.Fail("Should have thrown InvalidOperationException");
            }
            catch (InvalidOperationException e)
            {
                Assert.IsTrue(e.Message.Contains("Channel is closed"));
            }

            done = true;
        }
Ejemplo n.º 11
0
        private static void Main()
        {
            GlobalVersion = Assembly.GetExecutingAssembly().GetName().Version;
            JsonConvert.DefaultSettings = () => new JsonSerializerSettings
            {
                Converters = new List <JsonConverter> {
                    new IPEndPointConverter()
                }
            };

            var jsonlog = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "GameServer.json");
            var logfile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "GameServer.log");

            Log.Logger = new LoggerConfiguration()
                         .WriteTo.File(new JsonFormatter(), jsonlog)
                         .WriteTo.File(logfile)
                         .WriteTo.Console(outputTemplate: "[{Level} {SourceContext}] {Message}{NewLine}{Exception}")
                         .MinimumLevel.Verbose()
                         .CreateLogger();
            var Logger = Log.ForContext(Constants.SourceContextPropertyName, "-Initialiazor");

#if !DEBUG
            AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
#endif
            TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
            Logger.Information("============================================");
            Logger.Information("Initializing GameServer build {ver}...",
                               $"{GlobalVersion.Major}.{GlobalVersion.Major / 2 + GlobalVersion.Minor + GlobalVersion.Build + GlobalVersion.Revision}");
#if NEWIDS
            Logger.Information("Set mode NEWIDS");
#endif
#if LATESTS4
            Logger.Information("Set mode LATESTS4");
#endif
            Logger.Information("============================================");
            Logger.Information("Initializing Database...");

            AuthDatabase.Initialize();
            GameDatabase.Initialize();

            Logger.Information("============================================");
            Logger.Information("Starting Serverinstances and ResourceCache...");

            ItemIdGenerator.Initialize();
            CharacterIdGenerator.Initialize();
            DenyIdGenerator.Initialize();

            var listenerThreads = new MultithreadEventLoopGroup(Config.Instance.ListenerThreads);
            var workerThreads   = new MultithreadEventLoopGroup(Config.Instance.WorkerThreads);
            var workerThread    = new SingleThreadEventLoop();
            ChatServer.Initialize(new Configuration
            {
                SocketListenerThreads = listenerThreads,
                SocketWorkerThreads   = workerThreads,
                WorkerThread          = workerThread,
#if DEBUG
                Logger = Logger,
#endif
            });
            RelayServer.Initialize(new Configuration
            {
                SocketListenerThreads = listenerThreads,
                SocketWorkerThreads   = workerThreads,
                WorkerThread          = workerThread,
#if DEBUG
                Logger = Logger,
#endif
            });
            GameServer.Initialize(new Configuration
            {
                SocketListenerThreads = listenerThreads,
                SocketWorkerThreads   = workerThreads,
                WorkerThread          = workerThread,
#if DEBUG
                Logger = Logger,
#endif
            });

            FillShop();

            ChatServer.Instance.Listen(Config.Instance.ChatListener);
            RelayServer.Instance.Listen(Config.Instance.RelayListener, IPAddress.Parse(Config.Instance.IP),
                                        Config.Instance.RelayUdpPorts);
            GameServer.Instance.Listen(Config.Instance.Listener);

            Logger.Information("Serverinstances successfully started, ready for connections!");
            Logger.Information("============================================\n");

            Console.CancelKeyPress += OnCancelKeyPress;
            while (true)
            {
                var input = Console.ReadLine();
                if (input == null)
                {
                    break;
                }

                if (input.Equals("exit", StringComparison.InvariantCultureIgnoreCase) ||
                    input.Equals("quit", StringComparison.InvariantCultureIgnoreCase) ||
                    input.Equals("stop", StringComparison.InvariantCultureIgnoreCase))
                {
                    break;
                }

                var args = input.GetArgs();
                if (args.Length == 0)
                {
                    continue;
                }

                Task.Run(() =>
                {
                    if (!GameServer.Instance.CommandManager.Execute(null, args))
                    {
                        Console.WriteLine("Unknown command");
                    }
                });
            }

            Exit();
        }
 public SingleInstanceEventLoopGroup()
 {
     this.eventLoop = new SingleThreadEventLoop();
 }
Ejemplo n.º 13
0
        public async Task StartAsync()
        {
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug($"准备启动服务主机,监听地址:{_tcpServerProperties.Host}:{_tcpServerProperties.Port}。");
            }

            IEventLoopGroup bossGroup               = new MultithreadEventLoopGroup(1);
            IEventLoopGroup workerGroup             = new MultithreadEventLoopGroup();//Default eventLoopCount is Environment.ProcessorCount * 2
            var             tcpServiceEntryProvider = ServiceLocator.GetService <ITcpServiceEntryProvider>();
            var             workerGroup1            = new SingleThreadEventLoop();

            var bootstrap = new ServerBootstrap();

            bootstrap
            .Channel <TcpServerSocketChannel>()
            .ChildOption(ChannelOption.SoKeepalive, true)
            .Option(ChannelOption.SoBacklog, AppConfig.ServerOptions.SoBacklog)
            .ChildOption(ChannelOption.Allocator, PooledByteBufferAllocator.Default)
            .Group(bossGroup, workerGroup)
            .ChildHandler(new ActionChannelInitializer <IChannel>(channel =>
            {
                var pipeline = channel.Pipeline;

                pipeline.AddLast(new ConnectionChannelHandlerAdapter(_logger, ServiceLocator.GetService <IDeviceProvider>(), tcpServiceEntryProvider, _tcpServerProperties));
                pipeline.AddLast(workerGroup1, "ServerHandler", new ServerHandler(_tcpServerProperties, _engine, _ruleWorkflow, _logger)
                                 );
                switch (_tcpServerProperties.ParserType)
                {
                case PayloadParserType.Direct:
                    {
                        pipeline.AddLast(new LengthFieldPrepender(4));
                        pipeline.AddLast(new LengthFieldBasedFrameDecoder(int.MaxValue, 0, 4, 0, 4));
                    }
                    break;

                case PayloadParserType.FixedLength:
                    {
                        if (_tcpServerProperties.ParserConfiguration != null && _tcpServerProperties.ParserConfiguration.ContainsKey("size"))
                        {
                            var configValue = _tcpServerProperties.ParserConfiguration["size"];
                            pipeline.AddLast(new FixedLengthFrameDecoder(int.Parse(configValue.ToString() ?? "0")));
                        }
                    }
                    break;

                case PayloadParserType.Delimited:
                    {
                        if (_tcpServerProperties.ParserConfiguration != null && _tcpServerProperties.ParserConfiguration.ContainsKey("delimited"))
                        {
                            var configValue = _tcpServerProperties.ParserConfiguration["delimited"];
                            var delimiter   = Unpooled.CopiedBuffer(Encoding.Default.GetBytes(configValue.ToString() ?? ""));
                            pipeline.AddLast(new DelimiterBasedFrameDecoder(int.MaxValue, true, delimiter));
                        }
                    }
                    break;
                }
            }))
            .Option(ChannelOption.SoBroadcast, true);
            try
            {
                _channel = await bootstrap.BindAsync(_tcpServerProperties.CreateSocketAddress());

                if (_logger.IsEnabled(LogLevel.Debug))
                {
                    _logger.LogDebug($"Tcp服务主机启动成功,监听地址:{_tcpServerProperties.Host}:{_tcpServerProperties.Port}。");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError($"Tcp服务主机启动失败,监听地址:{_tcpServerProperties.Host}:{_tcpServerProperties.Port}。 ");
            }
        }
Ejemplo n.º 14
0
        private static void Main()
        {
            AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
            TaskScheduler.UnobservedTaskException      += OnUnobservedTaskException;
            GlobalVersion = Assembly.GetExecutingAssembly().GetName().Version;
            JsonConvert.DefaultSettings = () => new JsonSerializerSettings
            {
                Converters = new List <JsonConverter> {
                    new IPEndPointConverter()
                }
            };

            var jsonlog = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "GameServer.json");
            var logfile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "GameServer.log");

            Log.Logger = new LoggerConfiguration()
                         .WriteTo.File(new JsonFormatter(), jsonlog)
                         .WriteTo.File(logfile)
                         .Enrich.With <ContextEnricher>()
                         .Enrich.With <AccUserEnricher>()
                         .WriteTo.Console(
                outputTemplate: "[{Level:u3}] |{SrcContext}| {AccUSpace:u3} | {Message}{NewLine}{Exception}")
                         .MinimumLevel.Verbose()
                         .CreateLogger();

            var Logger = Log.ForContext(Constants.SourceContextPropertyName, "Initialiazor");

            Logger.Information("============================================");
            //Logger.Information("Initializing GameServer build {ver}...",
            //  $"{GlobalVersion.Major}.{GlobalVersion.Major / 2 + GlobalVersion.Minor + GlobalVersion.Build + GlobalVersion.Revision}");
#if NEWIDS
            Logger.Information("Set mode NEWIDS");
#endif
#if LATESTS4
            Logger.Information("Set mode LATESTS4");
#endif
            Logger.Information("============================================");
            Logger.Information("Initializing Database...");

            AuthDatabase.Initialize();
            GameDatabase.Initialize();

            Logger.Information("============================================");
            Logger.Information("Starting Serverinstances and ResourceCache...");

            ItemIdGenerator.Initialize();
            DenyIdGenerator.Initialize();

            var listenerThreads = new MultithreadEventLoopGroup(Config.Instance.ListenerThreads);
            var workerThread    = new SingleThreadEventLoop();
            ChatServer.Initialize(new Configuration
            {
                SocketListenerThreads = listenerThreads,
                SocketWorkerThreads   = new MultithreadEventLoopGroup(Config.Instance.WorkerThreads / 3),
                WorkerThread          = workerThread
            });
            RelayServer.Initialize(new Configuration
            {
                SocketListenerThreads = listenerThreads,
                SocketWorkerThreads   = new MultithreadEventLoopGroup(Config.Instance.WorkerThreads / 3),
                WorkerThread          = workerThread,
            });
            GameServer.Initialize(new Configuration
            {
                SocketListenerThreads = listenerThreads,
                SocketWorkerThreads   = new MultithreadEventLoopGroup(Config.Instance.WorkerThreads / 3),
                WorkerThread          = workerThread
            });

            FillShop();

            ChatServer.Instance.Listen(Config.Instance.ChatListener);
            RelayServer.Instance.Listen(Config.Instance.RelayListener, IPAddress.Parse(Config.Instance.IP),
                                        Config.Instance.RelayUdpPorts);
            GameServer.Instance.Listen(Config.Instance.Listener);

            Log.Information("Starting Game API");
            s_gameApiEventLoopGroup = new MultithreadEventLoopGroup(2);
            s_gameHost = new ServerBootstrap()
                         .Group(s_gameApiEventLoopGroup)
                         .Channel <TcpServerSocketChannel>()
                         .Handler(new ActionChannelInitializer <IChannel>(ch => { }))
                         .ChildHandler(new ActionChannelInitializer <IChannel>(ch =>
            {
                ch.Pipeline.AddLast(new GameServerHandler());
            }))
                         .BindAsync(Config.Instance.FumbiAPI.EndPoint).GetAwaiter().GetResult();

            if (Config.Instance.ACMode == 2)
            {
                Logger.Information("[BE] Activated");
            }

            if (Config.Instance.ResCheck)
            {
                Logger.Information("[ResCheck] Activated : {0}", Config.Instance.ResHash);
                Logger.Information("[ResCheck_Red] Activated : {0}", Config.Instance.ResHash_red);
                Logger.Information("[ResCheck_Gold] Activated : {0}", Config.Instance.ResHash_gold);
                Logger.Information("[ResCheck_Blue] Activated : {0}", Config.Instance.ResHash_blue);
                Logger.Information("[ResCheck_Violet] Activated : {0}", Config.Instance.ResHash_violet);
            }
            Logger.Information("Waiting For Connections!");
            Logger.Information("============================================");

            Console.CancelKeyPress += OnCancelKeyPress;
            while (true)
            {
                var input = Console.ReadLine();
                if (input == null)
                {
                    break;
                }

                if (input.Equals("exit", StringComparison.InvariantCultureIgnoreCase) ||
                    input.Equals("quit", StringComparison.InvariantCultureIgnoreCase) ||
                    input.Equals("stop", StringComparison.InvariantCultureIgnoreCase))
                {
                    break;
                }

                var args = input.GetArgs();
                if (args.Length == 0)
                {
                    continue;
                }

                Task.Run(async() =>
                {
                    if (!await GameServer.Instance.CommandManager.Execute(null, args))
                    {
                        CommandManager.Logger.Information("Unknown command");
                    }
                });
            }

            Exit();
        }
Ejemplo n.º 15
0
        public async Task StartFresh()
        {
            try
            {
                Debug.WriteLine($"{nameof(PushClient)}: Starting fresh.");
                if (_loopGroup != null)
                {
                    await Shutdown();
                }
                _loopGroup = new SingleThreadEventLoop();

                var connectPacket = new FbnsConnectPacket
                {
                    Payload = await PayloadProcessor.BuildPayload(ConnectionData)
                };

                Socket = new StreamSocket();
                Socket.Control.KeepAlive = true;
                Socket.Control.NoDelay   = true;
                if (await RequestBackgroundAccess())
                {
                    try
                    {
                        Socket.EnableTransferOwnership(_socketActivityTask.TaskId, SocketActivityConnectedStandbyAction.Wake);
                    }
                    catch (Exception connectedStandby)
                    {
                        Debug.WriteLine(connectedStandby);
                        Debug.WriteLine($"{nameof(PushClient)}: Connected standby not available.");
                        try
                        {
                            Socket.EnableTransferOwnership(_socketActivityTask.TaskId, SocketActivityConnectedStandbyAction.DoNotWake);
                        }
                        catch (Exception e)
                        {
#if !DEBUG
                            Crashes.TrackError(e);
#endif
                            Debug.WriteLine(e);
                            Debug.WriteLine($"{nameof(PushClient)}: Failed to transfer socket completely!");
                            await Shutdown().ConfigureAwait(false);

                            return;
                        }
                    }
                }

                await Socket.ConnectAsync(new HostName(HOST_NAME), "443", SocketProtectionLevel.Tls12);

                var streamSocketChannel = new StreamSocketChannel(Socket);
                streamSocketChannel.Pipeline.AddLast(new FbnsPacketEncoder(), new FbnsPacketDecoder(), this);

                await _loopGroup.RegisterAsync(streamSocketChannel).ConfigureAwait(false);

                await streamSocketChannel.WriteAndFlushAsync(connectPacket).ConfigureAwait(false);
            }
            catch (Exception e)
            {
#if !DEBUG
                Crashes.TrackError(e);
#endif
                await Shutdown().ConfigureAwait(false);
            }
        }
Ejemplo n.º 16
0
        private static void Main()
        {
            JsonConvert.DefaultSettings = () => new JsonSerializerSettings
            {
                Converters = new List <JsonConverter> {
                    new IPEndPointConverter()
                }
            };

            Config <Config> .Initialize("game.hjson", "NETSPHEREPIRATES_GAMECONF");

            var jsonlog = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "game.json");
            var logfile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "game.log");

            Log.Logger = new LoggerConfiguration()
                         .Destructure.ByTransforming <IPEndPoint>(endPoint => endPoint.ToString())
                         .Destructure.ByTransforming <EndPoint>(endPoint => endPoint.ToString())
                         .WriteTo.File(new JsonFormatter(), jsonlog)
                         .WriteTo.File(logfile)
                         .WriteTo.Console(outputTemplate: "[{Level} {SourceContext}] {Message}{NewLine}{Exception}")
                         .MinimumLevel.Debug()
                         .CreateLogger();

            AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
            TaskScheduler.UnobservedTaskException      += OnUnobservedTaskException;

            Log.Information("Initializing...");

            try
            {
                AuthDatabase.Initialize(Config.Instance.Database.Auth);
                GameDatabase.Initialize(Config.Instance.Database.Game);
            }
            catch (DatabaseNotFoundException ex)
            {
                Log.Error("Database {Name} not found", ex.Name);
                Environment.Exit(1);
            }
            catch (DatabaseVersionMismatchException ex)
            {
                Log.Error("Invalid version. Database={CurrentVersion} Required={RequiredVersion}. Run the DatabaseMigrator to update your database.",
                          ex.CurrentVersion, ex.RequiredVersion);
                Environment.Exit(1);
            }

            ItemIdGenerator.Initialize();
            CharacterIdGenerator.Initialize();
            LicenseIdGenerator.Initialize();
            DenyIdGenerator.Initialize();
            Club.Initialize();

            var listenerThreads = new MultithreadEventLoopGroup(Config.Instance.ListenerThreads);
            var workerThreads   = new MultithreadEventLoopGroup(Config.Instance.WorkerThreads);
            var workerThread    = new SingleThreadEventLoop();

            ChatServer.Initialize(new ProudNet.Configuration
            {
                SocketListenerThreads = listenerThreads,
                SocketWorkerThreads   = workerThreads,
                WorkerThread          = workerThread
            });
            RelayServer.Initialize(new ProudNet.Configuration
            {
                SocketListenerThreads = listenerThreads,
                SocketWorkerThreads   = workerThreads,
                WorkerThread          = workerThread
            });
            GameServer.Initialize(new ProudNet.Configuration
            {
                SocketListenerThreads = listenerThreads,
                SocketWorkerThreads   = workerThreads,
                WorkerThread          = workerThread
            });

            FillShop();

            Log.Information("Starting server...");

            ChatServer.Instance.Listen(Config.Instance.ChatListener);
            RelayServer.Instance.Listen(Config.Instance.RelayListener, IPAddress.Parse(Config.Instance.IP), Config.Instance.RelayUdpPorts);
            GameServer.Instance.Listen(Config.Instance.Listener);

            Log.Information("Ready for connections!");

            if (Config.Instance.NoobMode)
            {
                Log.Warning("!!! NOOB MODE IS ENABLED! EVERY LOGIN SUCCEEDS AND OVERRIDES ACCOUNT LOGIN DETAILS !!!");
            }

            Console.CancelKeyPress += OnCancelKeyPress;
            while (true)
            {
                var input = Console.ReadLine();
                if (input == null)
                {
                    break;
                }

                if (input.Equals("exit", StringComparison.InvariantCultureIgnoreCase) ||
                    input.Equals("quit", StringComparison.InvariantCultureIgnoreCase) ||
                    input.Equals("stop", StringComparison.InvariantCultureIgnoreCase))
                {
                    break;
                }

                var args = input.GetArgs();
                if (args.Length == 0)
                {
                    continue;
                }

                if (!GameServer.Instance.CommandManager.Execute(null, args))
                {
                    Console.WriteLine("Unknown command");
                }
            }

            Exit();
        }
Ejemplo n.º 17
0
        public async Task TestDeadlockOnRemove()
        {
            IEventLoop thread1    = new SingleThreadEventLoop();
            Bootstrap  bootstrap1 = new Bootstrap()
                                    .Channel <LocalChannel>().Group(thread1).LocalAddress(new LocalAddress("#1"));
            IEventLoop thread2    = new SingleThreadEventLoop();
            Bootstrap  bootstrap2 = new Bootstrap()
                                    .Channel <LocalChannel>().Group(thread2).LocalAddress(new LocalAddress("#2"));

            // pool1 runs on thread2, pool2 runs on thread1
            FixedChannelPool pool1 = new FixedChannelPool(bootstrap2, NoopHandler.Instance, 1);
            FixedChannelPool pool2 = new FixedChannelPool(bootstrap1, NoopHandler.Instance, 1);
            var channelPoolMap     = new TestChannelPoolMap1(pool1, pool2);

            Assert.Same(pool1, channelPoolMap.Get("#1"));
            Assert.Same(pool2, channelPoolMap.Get("#2"));

            // thread1 tries to remove pool1 which is running on thread2
            // thread2 tries to remove pool2 which is running on thread1

            var barrier = new Barrier(2);

            var future1 = thread1.SubmitAsync(() =>
            {
                if (!barrier.SignalAndWait(TimeSpan.FromSeconds(1)))
                {
                    throw new TimeoutException();
                }
                channelPoolMap.Remove("#1");
                return(1);
            });

            var future2 = thread2.SubmitAsync(() =>
            {
                if (!barrier.SignalAndWait(TimeSpan.FromSeconds(1)))
                {
                    throw new TimeoutException();
                }
                channelPoolMap.Remove("#2");
                return(2);
            });

            // A blocking close on remove will cause a deadlock here and the test will time out
            try
            {
                var result = await TaskUtil.WaitAsync(future1, TimeSpan.FromSeconds(1));

                if (!result || !future1.IsSuccess())
                {
                    throw new TimeoutException();
                }
                result = await TaskUtil.WaitAsync(future2, TimeSpan.FromSeconds(1));

                if (!result || !future2.IsSuccess())
                {
                    throw new TimeoutException();
                }
            }
            catch (TimeoutException)
            {
                Assert.False(true); // Fail the test on timeout to distinguish from other errors
            }
            finally
            {
                pool1.Close();
                pool2.Close();
                channelPoolMap.Close();
                Shutdown(thread1, thread2);
            }
        }
Ejemplo n.º 18
0
        public async Task TestDeadlockOnAcquire()
        {
            IEventLoop threadA1    = new SingleThreadEventLoop();
            Bootstrap  bootstrapA1 = new Bootstrap()
                                     .Channel <LocalChannel>().Group(threadA1).LocalAddress(new LocalAddress("A1"));
            IEventLoop threadA2    = new SingleThreadEventLoop();
            Bootstrap  bootstrapA2 = new Bootstrap()
                                     .Channel <LocalChannel>().Group(threadA2).LocalAddress(new LocalAddress("A2"));
            IEventLoop threadB1    = new SingleThreadEventLoop();
            Bootstrap  bootstrapB1 = new Bootstrap()
                                     .Channel <LocalChannel>().Group(threadB1).LocalAddress(new LocalAddress("B1"));
            IEventLoop threadB2    = new SingleThreadEventLoop();
            Bootstrap  bootstrapB2 = new Bootstrap()
                                     .Channel <LocalChannel>().Group(threadB2).LocalAddress(new LocalAddress("B2"));

            FixedChannelPool poolA1 = new FixedChannelPool(bootstrapA1, NoopHandler.Instance, 1);
            FixedChannelPool poolA2 = new FixedChannelPool(bootstrapB2, NoopHandler.Instance, 1);
            FixedChannelPool poolB1 = new FixedChannelPool(bootstrapB1, NoopHandler.Instance, 1);
            FixedChannelPool poolB2 = new FixedChannelPool(bootstrapA2, NoopHandler.Instance, 1);

            // Synchronize threads on these barriers to ensure order of execution, first wait until each thread is inside
            // the newPool callbak, then hold the two threads that should lose the match until the first two returns, then
            // release them to test if they deadlock when trying to release their pools on each other's threads.
            Barrier arrivalBarrier = new Barrier(4);
            Barrier releaseBarrier = new Barrier(3);

            var channelPoolMap = new TestChannelPoolMap0(
                threadA1, threadA2, threadB1, threadB2,
                poolA1, poolA2, poolB1, poolB2, arrivalBarrier, releaseBarrier);

            // Thread A1 calls ChannelPoolMap.get(A)
            // Thread A2 calls ChannelPoolMap.get(A)
            // Thread B1 calls ChannelPoolMap.get(B)
            // Thread B2 calls ChannelPoolMap.get(B)

            var futureA1 = threadA1.SubmitAsync(() =>
            {
                return(channelPoolMap.Get("A"));
            });

            var futureA2 = threadA2.SubmitAsync(() =>
            {
                return(channelPoolMap.Get("A"));
            });

            var futureB1 = threadB1.SubmitAsync(() =>
            {
                return(channelPoolMap.Get("B"));
            });

            var futureB2 = threadB2.SubmitAsync(() =>
            {
                return(channelPoolMap.Get("B"));
            });

            // Thread A1 succeeds on updating the map and moves on
            // Thread B1 succeeds on updating the map and moves on
            // These should always succeed and return with new pools
            try
            {
                var result = await TaskUtil.WaitAsync(futureA1, TimeSpan.FromSeconds(1));

                if (!result || !futureA1.IsSuccess())
                {
                    throw new TimeoutException();
                }
                Assert.Same(poolA1, futureA1.Result);

                result = await TaskUtil.WaitAsync(futureB1, TimeSpan.FromSeconds(1));

                if (!result || !futureB1.IsSuccess())
                {
                    throw new TimeoutException();
                }
                Assert.Same(poolB1, futureB1.Result);
            }
            catch (Exception e)
            {
                Shutdown(threadA1, threadA2, threadB1, threadB2);
                throw e;
            }

            // Now release the other two threads which at this point lost the race and will try to clean up the acquired
            // pools. The expected scenario is that both pools close, in case of a deadlock they will hang.
            if (!releaseBarrier.SignalAndWait(TimeSpan.FromSeconds(1)))
            {
                Assert.False(true);
            }

            // Thread A2 fails to update the map and submits close to thread B2
            // Thread B2 fails to update the map and submits close to thread A2
            // If the close is blocking, then these calls will time out as the threads are waiting for each other
            // If the close is not blocking, then the previously created pools will be returned
            try
            {
                var result = await TaskUtil.WaitAsync(futureA2, TimeSpan.FromSeconds(1));

                if (!result || !futureA2.IsSuccess())
                {
                    throw new TimeoutException();
                }
                Assert.Same(poolA1, futureA2.Result);

                result = await TaskUtil.WaitAsync(futureB2, TimeSpan.FromSeconds(1));

                if (!result || !futureB2.IsSuccess())
                {
                    throw new TimeoutException();
                }
                Assert.Same(poolB1, futureB2.Result);
            }
            catch (TimeoutException)
            {
                Assert.False(true); // Fail the test on timeout to distinguish from other errors
                throw;
            }
            finally
            {
                poolA1.Close();
                poolA2.Close();
                poolB1.Close();
                poolB2.Close();
                channelPoolMap.Close();
                Shutdown(threadA1, threadA2, threadB1, threadB2);
            }
        }