diff options
Diffstat (limited to 'Impostor-dev/src/Impostor.Server/Program.cs')
-rw-r--r-- | Impostor-dev/src/Impostor.Server/Program.cs | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/Impostor-dev/src/Impostor.Server/Program.cs b/Impostor-dev/src/Impostor.Server/Program.cs new file mode 100644 index 0000000..32a28fb --- /dev/null +++ b/Impostor-dev/src/Impostor.Server/Program.cs @@ -0,0 +1,207 @@ +using System; +using System.IO; +using System.Linq; +using Impostor.Api.Events.Managers; +using Impostor.Api.Games; +using Impostor.Api.Games.Managers; +using Impostor.Api.Net.Manager; +using Impostor.Api.Net.Messages; +using Impostor.Hazel.Extensions; +using Impostor.Server.Config; +using Impostor.Server.Events; +using Impostor.Server.Net; +using Impostor.Server.Net.Factories; +using Impostor.Server.Net.Manager; +using Impostor.Server.Net.Messages; +using Impostor.Server.Net.Redirector; +using Impostor.Server.Plugins; +using Impostor.Server.Recorder; +using Impostor.Server.Utils; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.ObjectPool; +using Serilog; +using Serilog.Events; + +namespace Impostor.Server +{ + internal static class Program + { + private static int Main(string[] args) + { +#if DEBUG + var logLevel = LogEventLevel.Debug; +#else + var logLevel = LogEventLevel.Information; +#endif + + if (args.Contains("--verbose")) + { + logLevel = LogEventLevel.Verbose; + } + else if (args.Contains("--errors-only")) + { + logLevel = LogEventLevel.Error; + } + + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Is(logLevel) +#if DEBUG + .MinimumLevel.Override("Microsoft", LogEventLevel.Debug) +#else + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) +#endif + .Enrich.FromLogContext() + .WriteTo.Console() + .CreateLogger(); + + try + { + Log.Information("Starting Impostor v{0}", DotnetUtils.GetVersion()); + CreateHostBuilder(args).Build().Run(); + return 0; + } + catch (Exception ex) + { + Log.Fatal(ex, "Impostor terminated unexpectedly"); + return 1; + } + finally + { + Log.CloseAndFlush(); + } + } + + private static IConfiguration CreateConfiguration(string[] args) + { + var configurationBuilder = new ConfigurationBuilder(); + + configurationBuilder.AddJsonFile("config.json", true); + configurationBuilder.AddJsonFile("config.Development.json", true); + configurationBuilder.AddEnvironmentVariables(prefix: "IMPOSTOR_"); + configurationBuilder.AddCommandLine(args); + + return configurationBuilder.Build(); + } + + //c 入口 + private static IHostBuilder CreateHostBuilder(string[] args) + { + var configuration = CreateConfiguration(args); + var pluginConfig = configuration.GetSection("PluginLoader") + .Get<PluginConfig>() ?? new PluginConfig(); + + return Host.CreateDefaultBuilder(args) + .UseContentRoot(Directory.GetCurrentDirectory()) +#if DEBUG + .UseEnvironment(Environment.GetEnvironmentVariable("IMPOSTOR_ENV") ?? "Development") +#else + .UseEnvironment("Production") +#endif + .ConfigureAppConfiguration(builder => + { + builder.AddConfiguration(configuration); + }) + .ConfigureServices((host, services) => + { + var debug = host.Configuration + .GetSection(DebugConfig.Section) + .Get<DebugConfig>() ?? new DebugConfig(); + + var redirector = host.Configuration + .GetSection(ServerRedirectorConfig.Section) + .Get<ServerRedirectorConfig>() ?? new ServerRedirectorConfig(); + + services.Configure<DebugConfig>(host.Configuration.GetSection(DebugConfig.Section)); + services.Configure<AntiCheatConfig>(host.Configuration.GetSection(AntiCheatConfig.Section)); + services.Configure<ServerConfig>(host.Configuration.GetSection(ServerConfig.Section)); + services.Configure<ServerRedirectorConfig>(host.Configuration.GetSection(ServerRedirectorConfig.Section)); + + if (redirector.Enabled) + { + if (!string.IsNullOrEmpty(redirector.Locator.Redis)) + { + // When joining a game, it retrieves the game server ip from redis. + // When a game has been created on this node, it stores the game code with its ip in redis. + services.AddSingleton<INodeLocator, NodeLocatorRedis>(); + + // Dependency for the NodeLocatorRedis. + services.AddStackExchangeRedisCache(options => + { + options.Configuration = redirector.Locator.Redis; + options.InstanceName = "ImpostorRedis"; + }); + } + else if (!string.IsNullOrEmpty(redirector.Locator.UdpMasterEndpoint)) + { + services.AddSingleton<INodeLocator, NodeLocatorUdp>(); + + if (redirector.Master) + { + services.AddHostedService<NodeLocatorUdpService>(); + } + } + else + { + throw new Exception("Missing a valid NodeLocator config."); + } + + // Use the configuration as source for the list of nodes to provide + // when creating a game. + services.AddSingleton<INodeProvider, NodeProviderConfig>(); + } + else + { + // Redirector is not enabled but the dependency is still required. + // So we provide one that ignores all calls. + services.AddSingleton<INodeLocator, NodeLocatorNoOp>(); + } + + services.AddSingleton<ClientManager>(); + services.AddSingleton<IClientManager>(p => p.GetRequiredService<ClientManager>()); + + if (redirector.Enabled && redirector.Master) + { + services.AddSingleton<IClientFactory, ClientFactory<ClientRedirector>>(); + + // For a master server, we don't need a GameManager. + } + else + { + if (debug.GameRecorderEnabled) + { + services.AddSingleton<ObjectPoolProvider>(new DefaultObjectPoolProvider()); + services.AddSingleton<ObjectPool<PacketSerializationContext>>(serviceProvider => + { + var provider = serviceProvider.GetRequiredService<ObjectPoolProvider>(); + var policy = new PacketSerializationContextPooledObjectPolicy(); + return provider.Create(policy); + }); + + services.AddSingleton<PacketRecorder>(); + services.AddHostedService(sp => sp.GetRequiredService<PacketRecorder>()); + services.AddSingleton<IClientFactory, ClientFactory<ClientRecorder>>(); + } + else + { + services.AddSingleton<IClientFactory, ClientFactory<Client>>(); + } + + services.AddSingleton<GameManager>(); + services.AddSingleton<IGameManager>(p => p.GetRequiredService<GameManager>()); + } + + services.AddHazel(); + services.AddSingleton<IMessageWriterProvider, MessageWriterProvider>(); + services.AddSingleton<IGameCodeFactory, GameCodeFactory>(); + services.AddSingleton<IEventManager, EventManager>(); + services.AddSingleton<Matchmaker>(); + services.AddHostedService<MatchmakerService>(); + }) + .UseSerilog() + .UseConsoleLifetime() + .UsePluginLoader(pluginConfig); + } + } +} |