summaryrefslogtreecommitdiff
path: root/Impostor-dev/src/Impostor.Server/Program.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Impostor-dev/src/Impostor.Server/Program.cs')
-rw-r--r--Impostor-dev/src/Impostor.Server/Program.cs207
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);
+ }
+ }
+}