private static void Main() { var baseDirectory = Environment.GetEnvironmentVariable("NETSPHEREPIRATES_BASEDIR_RELAY"); if (string.IsNullOrWhiteSpace(baseDirectory)) { baseDirectory = AppDomain.CurrentDomain.BaseDirectory; } var configuration = Startup.Initialize(baseDirectory, "config.hjson", x => x.GetSection(nameof(AppOptions.Logging)).Get <LoggerOptions>()); Log.Information("Starting..."); var appOptions = configuration.Get <AppOptions>(); var hostBuilder = new HostBuilder(); var redisConnectionMultiplexer = ConnectionMultiplexer.Connect(appOptions.Database.ConnectionStrings.Redis); IPluginHost pluginHost = new MefPluginHost(); pluginHost.Initialize(configuration, Path.Combine(baseDirectory, "plugins")); ConfigureMapper(); hostBuilder .ConfigureHostConfiguration(builder => builder.AddConfiguration(configuration)) .ConfigureAppConfiguration(builder => builder.AddConfiguration(configuration)) .UseConsoleLifetime() .UseProudNetServer(builder => { var messageHandlerResolver = new DefaultMessageHandlerResolver( AppDomain.CurrentDomain.GetAssemblies(), typeof(IRelayMessage), typeof(IEventMessage), typeof(IP2PMessage)); builder .UseHostIdFactory <HostIdFactory>() .UseSessionFactory <SessionFactory>() .AddMessageFactory <RelayMessageFactory>() .AddMessageFactory <EventMessageFactory>() .UseMessageHandlerResolver(messageHandlerResolver) .UseNetworkConfiguration((context, options) => { options.Version = new Guid("{a43a97d1-9ec7-495e-ad5f-8fe45fde1151}"); options.TcpListener = appOptions.Network.Listener; options.UdpAddress = appOptions.Network.Address; options.UdpListenerPorts = appOptions.Network.UdpPorts; options.ServerAsP2PGroupMemberHack = true; }) .UseThreadingConfiguration((context, options) => { options.SocketListenerThreadsFactory = () => new MultithreadEventLoopGroup(1); options.SocketWorkerThreadsFactory = () => appOptions.Network.WorkerThreads < 1 ? new MultithreadEventLoopGroup() : new MultithreadEventLoopGroup(appOptions.Network.WorkerThreads); options.WorkerThreadFactory = () => new SingleThreadEventLoop(); }) .ConfigureSerializer(serializer => { serializer.AddSerializer(new ItemNumberSerializer()); serializer.AddSerializer(new CompressedFloatSerializer()); serializer.AddSerializer(new CompressedVector3Serializer()); serializer.AddSerializer(new LongPeerIdSerializer()); serializer.AddSerializer(new PeerIdSerializer()); serializer.AddSerializer(new RoomLocationSerializer()); serializer.AddSerializer(new RotationVectorSerializer()); }); }) .ConfigureServices((context, services) => { services .Configure <ConsoleLifetimeOptions>(options => options.SuppressStatusMessages = true) .Configure <HostOptions>(options => options.ShutdownTimeout = TimeSpan.FromMinutes(1)) .Configure <AppOptions>(context.Configuration) .Configure <NetworkOptions>(context.Configuration.GetSection(nameof(AppOptions.Network))) .Configure <DatabaseOptions>(context.Configuration.GetSection(nameof(AppOptions.Database))) .Configure <IdGeneratorOptions>(x => x.Id = 0) .AddSingleton <DatabaseService>() .AddDbContext <GameContext>(x => x.UseMySql(appOptions.Database.ConnectionStrings.Game)) .AddSingleton(redisConnectionMultiplexer) .AddTransient <ISerializer>(x => new JsonNetSerializer(JsonConvert.DefaultSettings())) .AddSingleton <ICacheClient, RedisCacheClient>() .AddSingleton <IMessageBus, RedisMessageBus>() .AddSingleton(x => new RedisCacheClientOptions { ConnectionMultiplexer = x.GetRequiredService <ConnectionMultiplexer>(), Serializer = x.GetRequiredService <ISerializer>() }) .AddSingleton(x => new RedisMessageBusOptions { Subscriber = x.GetRequiredService <ConnectionMultiplexer>().GetSubscriber(), Serializer = x.GetRequiredService <ISerializer>() }) .AddService <IdGeneratorService>() .AddHostedServiceEx <IpcService>() .AddSingleton <PlayerManager>() .AddTransient <Player>() .AddSingleton <RoomManager>(); pluginHost.OnConfigure(services); }); var host = hostBuilder.Build(); var contexts = host.Services.GetRequiredService <IEnumerable <DbContext> >(); foreach (var db in contexts) { Log.Information("Checking database={Context}...", db.GetType().Name); using (db) { if (db.Database.GetPendingMigrations().Any()) { if (appOptions.Database.RunMigration) { Log.Information("Applying database={Context} migrations...", db.GetType().Name); db.Database.Migrate(); } else { Log.Error("Database={Context} does not have all migrations applied", db.GetType().Name); return; } } } } host.Services.GetRequiredService <IApplicationLifetime>().ApplicationStarted.Register(() => Log.Information("Press Ctrl + C to shutdown")); host.Run(); host.Dispose(); pluginHost.Dispose(); }
private static void Main() { var baseDirectory = Environment.GetEnvironmentVariable("NETSPHEREPIRATES_BASEDIR_AUTH"); if (string.IsNullOrWhiteSpace(baseDirectory)) { baseDirectory = AppDomain.CurrentDomain.BaseDirectory; } var configuration = Startup.Initialize(baseDirectory, "config.hjson", x => x.GetSection(nameof(AppOptions.Logging)).Get <LoggerOptions>()); Log.Information("Starting..."); var appOptions = configuration.Get <AppOptions>(); var hostBuilder = new HostBuilder(); var redisConnectionMultiplexer = ConnectionMultiplexer.Connect(appOptions.Database.ConnectionStrings.Redis); IPluginHost pluginHost = new MefPluginHost(); pluginHost.Initialize(configuration, Path.Combine(baseDirectory, "plugins")); hostBuilder .ConfigureServices((context, services) => { services .Configure <ConsoleLifetimeOptions>(options => options.SuppressStatusMessages = true) .Configure <HostOptions>(options => options.ShutdownTimeout = TimeSpan.FromMinutes(1)) .Configure <AppOptions>(context.Configuration) .Configure <DatabaseOptions>(context.Configuration.GetSection(nameof(AppOptions.Database))) .AddSingleton <DatabaseService>() .AddDbContext <AuthContext>(x => x.UseMySql(appOptions.Database.ConnectionStrings.Auth)) .AddSingleton(redisConnectionMultiplexer) .AddTransient <ISerializer>(x => new JsonNetSerializer(JsonConvert.DefaultSettings())) .AddSingleton <ICacheClient, RedisCacheClient>() .AddSingleton <IMessageBus, RedisMessageBus>() .AddSingleton(x => new RedisCacheClientOptions { ConnectionMultiplexer = x.GetRequiredService <ConnectionMultiplexer>(), Serializer = x.GetRequiredService <ISerializer>() }) .AddSingleton(x => new RedisMessageBusOptions { Subscriber = x.GetRequiredService <ConnectionMultiplexer>().GetSubscriber(), Serializer = x.GetRequiredService <ISerializer>() }) .AddSingleton <ServerlistService>() .AddSingleton <IHostedService>(x => x.GetRequiredService <ServerlistService>()); pluginHost.OnConfigure(services); }) .ConfigureHostConfiguration(builder => builder.AddConfiguration(configuration)) .ConfigureAppConfiguration(builder => builder.AddConfiguration(configuration)) .UseConsoleLifetime() .UseProudNetServer(builder => { var messageHandlerResolver = new DefaultMessageHandlerResolver( AppDomain.CurrentDomain.GetAssemblies(), typeof(IAuthMessage)); builder .UseHostIdFactory <HostIdFactory>() .UseSessionFactory <SessionFactory>() .AddMessageFactory <AuthMessageFactory>() .UseMessageHandlerResolver(messageHandlerResolver) .UseNetworkConfiguration((context, options) => { options.Version = new Guid("{9be73c0b-3b10-403e-be7d-9f222702a38c}"); options.TcpListener = appOptions.Listener; }) .UseThreadingConfiguration((context, options) => { options.SocketListenerThreadsFactory = () => new MultithreadEventLoopGroup(1); options.SocketWorkerThreadsFactory = () => appOptions.WorkerThreads < 1 ? new MultithreadEventLoopGroup() : new MultithreadEventLoopGroup(appOptions.WorkerThreads); options.WorkerThreadFactory = () => new SingleThreadEventLoop(); }); }); var host = hostBuilder.Build(); var contexts = host.Services.GetRequiredService <IEnumerable <DbContext> >(); foreach (var db in contexts) { Log.Information("Checking database={Context}...", db.GetType().Name); using (db) { if (db.Database.GetPendingMigrations().Any()) { if (appOptions.Database.RunMigration) { Log.Information("Applying database={Context} migrations...", db.GetType().Name); db.Database.Migrate(); } else { Log.Error("Database={Context} does not have all migrations applied", db.GetType().Name); return; } } } } host.Services .GetRequiredService <IProudNetServerService>() .UnhandledRmi += (s, e) => Log.Debug("Unhandled Message={@Message} HostId={HostId}", e.Message, e.Session.HostId); host.Services.GetRequiredService <IApplicationLifetime>().ApplicationStarted.Register(() => Log.Information("Press Ctrl + C to shutdown")); host.Run(); host.Dispose(); pluginHost.Dispose(); }
private static void Main() { BaseDirectory = Environment.GetEnvironmentVariable("NETSPHEREPIRATES_BASEDIR_GAME"); if (string.IsNullOrWhiteSpace(BaseDirectory)) { BaseDirectory = AppDomain.CurrentDomain.BaseDirectory; } var configuration = Startup.Initialize(BaseDirectory, "config.hjson", x => x.GetSection(nameof(AppOptions.Logging)).Get <LoggerOptions>()); Log.Information("Starting..."); var appOptions = configuration.Get <AppOptions>(); var hostBuilder = new HostBuilder(); var redisConnectionMultiplexer = ConnectionMultiplexer.Connect(appOptions.Database.ConnectionStrings.Redis); IPluginHost pluginHost = new MefPluginHost(); pluginHost.Initialize(configuration, Path.Combine(BaseDirectory, "plugins")); ConfigureMapper(); hostBuilder .ConfigureHostConfiguration(builder => builder.AddConfiguration(configuration)) .ConfigureAppConfiguration(builder => builder.AddConfiguration(configuration)) .UseConsoleLifetime() .UseProudNetServer(builder => { var messageHandlerResolver = new DefaultMessageHandlerResolver( AppDomain.CurrentDomain.GetAssemblies(), typeof(IGameMessage), typeof(IGameRuleMessage)); builder .UseHostIdFactory <HostIdFactory>() .UseSessionFactory <SessionFactory>() .AddMessageFactory <GameMessageFactory>() .AddMessageFactory <GameRuleMessageFactory>() .UseMessageHandlerResolver(messageHandlerResolver) .UseNetworkConfiguration((context, options) => { options.Version = new Guid("{beb92241-8333-4117-ab92-9b4af78c688f}"); options.TcpListener = appOptions.Network.Listener; }) .UseThreadingConfiguration((context, options) => { options.SocketListenerThreadsFactory = () => new MultithreadEventLoopGroup(1); options.SocketWorkerThreadsFactory = () => appOptions.Network.WorkerThreads < 1 ? new MultithreadEventLoopGroup() : new MultithreadEventLoopGroup(appOptions.Network.WorkerThreads); options.WorkerThreadFactory = () => new SingleThreadEventLoop(); }) .ConfigureSerializer(serializer => { serializer.AddSerializer(new CharacterStyleSerializer()); serializer.AddSerializer(new ItemNumberSerializer()); serializer.AddSerializer(new MatchKeySerializer()); serializer.AddSerializer(new VersionSerializer()); serializer.AddSerializer(new ShopPriceSerializer()); serializer.AddSerializer(new ShopEffectSerializer()); serializer.AddSerializer(new ShopItemSerializer()); serializer.AddSerializer(new PeerIdSerializer()); serializer.AddSerializer(new LongPeerIdSerializer()); }); }) .ConfigureServices((context, services) => { services .Configure <ConsoleLifetimeOptions>(options => options.SuppressStatusMessages = true) .Configure <HostOptions>(options => options.ShutdownTimeout = TimeSpan.FromMinutes(1)) .Configure <AppOptions>(context.Configuration) .Configure <NetworkOptions>(context.Configuration.GetSection(nameof(AppOptions.Network))) .Configure <ServerListOptions>(context.Configuration.GetSection(nameof(AppOptions.ServerList))) .Configure <DatabaseOptions>(context.Configuration.GetSection(nameof(AppOptions.Database))) .Configure <GameOptions>(context.Configuration.GetSection(nameof(AppOptions.Game))) .Configure <DeathmatchOptions>(context.Configuration .GetSection(nameof(AppOptions.Game)) .GetSection(nameof(AppOptions.Game.Deathmatch))) .Configure <TouchdownOptions>(context.Configuration .GetSection(nameof(AppOptions.Game)) .GetSection(nameof(AppOptions.Game.Touchdown))) .Configure <BattleRoyalOptions>(context.Configuration .GetSection(nameof(AppOptions.Game)) .GetSection(nameof(AppOptions.Game.BattleRoyal))) .Configure <IdGeneratorOptions>(x => x.Id = 0) .AddSingleton <DatabaseService>() .AddDbContext <AuthContext>(x => x.UseMySql(appOptions.Database.ConnectionStrings.Auth)) .AddDbContext <GameContext>(x => x.UseMySql(appOptions.Database.ConnectionStrings.Game)) .AddSingleton(redisConnectionMultiplexer) .AddTransient <ISerializer>(x => new JsonNetSerializer(JsonConvert.DefaultSettings())) .AddSingleton <ICacheClient, RedisCacheClient>() .AddSingleton <IMessageBus, RedisMessageBus>() .AddSingleton(x => new RedisCacheClientOptions { ConnectionMultiplexer = x.GetRequiredService <ConnectionMultiplexer>(), Serializer = x.GetRequiredService <ISerializer>() }) .AddSingleton(x => new RedisMessageBusOptions { Subscriber = x.GetRequiredService <ConnectionMultiplexer>().GetSubscriber(), Serializer = x.GetRequiredService <ISerializer>() }) .AddTransient <Player>() .AddTransient <LicenseManager>() .AddTransient <CharacterManager>() .AddTransient <PlayerInventory>() .AddSingleton <PlayerManager>() .AddTransient <RoomManager>() .AddTransient <Room>() .AddSingleton <GameRuleResolver>() .AddTransient <GameRuleStateMachine>() .AddTransient <Deathmatch>() .AddTransient <Touchdown>() .AddTransient <BattleRoyal>() .AddTransient <Practice>() .AddSingleton <EquipValidator>() .AddCommands(typeof(Program).Assembly) .AddService <IdGeneratorService>() .AddHostedServiceEx <ServerlistService>() .AddHostedServiceEx <GameDataService>() .AddHostedServiceEx <ChannelService>() .AddHostedServiceEx <IpcService>() .AddHostedServiceEx <PlayerSaveService>() .AddHostedServiceEx <CommandService>(); pluginHost.OnConfigure(services); }); var host = hostBuilder.Build(); var contexts = host.Services.GetRequiredService <IEnumerable <DbContext> >(); foreach (var db in contexts) { Log.Information("Checking database={Context}...", db.GetType().Name); using (db) { if (db.Database.GetPendingMigrations().Any()) { if (appOptions.Database.RunMigration) { Log.Information("Applying database={Context} migrations...", db.GetType().Name); db.Database.Migrate(); } else { Log.Error("Database={Context} does not have all migrations applied", db.GetType().Name); return; } } } } host.Services .GetRequiredService <IProudNetServerService>() .UnhandledRmi += (s, e) => Log.Debug("Unhandled Message={@Message} HostId={HostId}", e.Message, e.Session.HostId); host.Services.GetRequiredService <IApplicationLifetime>().ApplicationStarted.Register(() => Log.Information("Press Ctrl + C to shutdown")); host.Run(); host.Dispose(); pluginHost.Dispose(); }