tgstation-server 5.12.7
The /tg/station 13 server suite
Loading...
Searching...
No Matches
ServerFactory.cs
Go to the documentation of this file.
1using System;
2using System.Linq;
3using System.Threading;
4using System.Threading.Tasks;
5
6using Microsoft.AspNetCore.Hosting;
7using Microsoft.AspNetCore.Server.Kestrel.Core;
8using Microsoft.Extensions.Configuration;
9using Microsoft.Extensions.DependencyInjection;
10using Microsoft.Extensions.Hosting;
11using Microsoft.Extensions.Logging;
12
18
20{
25 {
30
32 public IIOManager IOManager { get; }
33
40 {
41 this.assemblyInformationProvider = assemblyInformationProvider ?? throw new ArgumentNullException(nameof(assemblyInformationProvider));
42 IOManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
43 }
44
46 // TODO: Decomplexify
47#pragma warning disable CA1506
48 public async Task<IServer> CreateServer(string[] args, string updatePath, CancellationToken cancellationToken)
49 {
50 ArgumentNullException.ThrowIfNull(args);
51
52 // need to shove this arg in to disable config reloading unless a user specifically overrides it
53 if (!args.Any(arg => arg.Contains("hostBuilder:reloadConfigOnChange", StringComparison.OrdinalIgnoreCase))
54 && String.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("hostBuilder__reloadConfigOnChange")))
55 {
56 var oldArgs = args;
57 args = new string[oldArgs.Length + 1];
58 Array.Copy(oldArgs, args, oldArgs.Length);
59 args[oldArgs.Length] = "--hostBuilder:reloadConfigOnChange=false";
60 }
61
62 var basePath = IOManager.ResolvePath();
63 IHostBuilder CreateDefaultBuilder() => Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args)
64 .ConfigureAppConfiguration((context, builder) =>
65 {
66 builder.SetBasePath(basePath);
67
68 builder.AddYamlFile("appsettings.yml", optional: true, reloadOnChange: false)
69 .AddYamlFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.yml", optional: true, reloadOnChange: false);
70
71 // reorganize the builder so our yaml configs don't override the env/cmdline configs
72 // values obtained via debugger
73 var environmentJsonConfig = builder.Sources[2];
74 var envConfig = builder.Sources[3];
75
76 // CURSED
77 // https://github.com/dotnet/runtime/blob/30dc7e7aedb7aab085c7d9702afeae5bc5a43133/src/libraries/Microsoft.Extensions.Hosting/src/HostingHostBuilderExtensions.cs#L246-L249
78#if !NET6_0
79#error Validate this monstrosity works on current .NET
80#endif
81 IConfigurationSource cmdLineConfig, baseYmlConfig, environmentYmlConfig;
82 if (args.Length == 0)
83 {
84 cmdLineConfig = null;
85 baseYmlConfig = builder.Sources[4];
86 environmentYmlConfig = builder.Sources[5];
87 }
88 else
89 {
90 cmdLineConfig = builder.Sources[4];
91 baseYmlConfig = builder.Sources[5];
92 environmentYmlConfig = builder.Sources[6];
93 }
94
95 builder.Sources[2] = baseYmlConfig;
96 builder.Sources[3] = environmentJsonConfig;
97 builder.Sources[4] = environmentYmlConfig;
98 builder.Sources[5] = envConfig;
99
100 if (cmdLineConfig != null)
101 {
102 builder.Sources[6] = cmdLineConfig;
103 }
104 });
105
106 var setupWizardHostBuilder = CreateDefaultBuilder()
107 .UseSetupApplication(assemblyInformationProvider, IOManager);
108
109 IPostSetupServices<ServerFactory> postSetupServices;
110 using (var setupHost = setupWizardHostBuilder.Build())
111 {
112 postSetupServices = setupHost.Services.GetRequiredService<IPostSetupServices<ServerFactory>>();
113 await setupHost.RunAsync(cancellationToken);
114
115 if (postSetupServices.GeneralConfiguration.SetupWizardMode == SetupWizardMode.Only)
116 {
117 postSetupServices.Logger.LogInformation("Shutting down due to only running setup wizard.");
118 return null;
119 }
120 }
121
122 var hostBuilder = CreateDefaultBuilder()
123 .ConfigureWebHost(webHostBuilder =>
124 webHostBuilder
125 .UseKestrel(kestrelOptions =>
126 {
127 var serverPortProvider = kestrelOptions.ApplicationServices.GetRequiredService<IServerPortProvider>();
128 kestrelOptions.ListenAnyIP(
129 serverPortProvider.HttpApiPort,
130 listenOptions => listenOptions.Protocols = HttpProtocols.Http1AndHttp2);
131 })
132 .UseIIS()
133 .UseIISIntegration()
134 .UseApplication(assemblyInformationProvider, IOManager, postSetupServices)
135 .SuppressStatusMessages(true)
136 .UseShutdownTimeout(
137 TimeSpan.FromMinutes(
138 postSetupServices.GeneralConfiguration.RestartTimeoutMinutes)));
139
140 if (updatePath != null)
141 hostBuilder.UseContentRoot(
144
145 return new Server(hostBuilder, updatePath);
146 }
147#pragma warning restore CA1506
148 }
149}
Implementation of IServerFactory.
IIOManager IOManager
The IIOManager for the IServerFactory.
readonly IAssemblyInformationProvider assemblyInformationProvider
The IAssemblyInformationProvider for the ServerFactory.
async Task< IServer > CreateServer(string[] args, string updatePath, CancellationToken cancellationToken)
Create a IServer. A Task<TResult> resulting in a new IServer if it should be run, null otherwise.
Provides access to the server's HttpApiPort.
Interface for using filesystems.
Definition: IIOManager.cs:13
string ResolvePath()
Retrieve the full path of the current working directory.
string GetDirectoryName(string path)
Gets the directory portion of a given path .
Set of objects needed to configure an Core.Application.
GeneralConfiguration GeneralConfiguration
The Configuration.GeneralConfiguration.
ILogger< TLoggerType > Logger
The ILogger.
SetupWizardMode
Determines if the SetupWizard will run.