Move away from top level statements to keep everything under LANCommander namespace
parent
485b6febbe
commit
006bfcb866
|
@ -11,228 +11,238 @@ using System.Text;
|
|||
using Hangfire;
|
||||
using NLog;
|
||||
|
||||
Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
ConfigurationManager configuration = builder.Configuration;
|
||||
|
||||
// Add services to the container.
|
||||
Logger.Debug("Loading settings");
|
||||
var settings = SettingService.GetSettings(true);
|
||||
Logger.Debug("Loaded!");
|
||||
|
||||
#region Validate Settings
|
||||
Logger.Debug("Validating settings");
|
||||
if (settings?.Authentication?.TokenSecret?.Length < 16)
|
||||
namespace LANCommander
|
||||
{
|
||||
Logger.Debug("JWT token secret is too short. Regenerating...");
|
||||
settings.Authentication.TokenSecret = Guid.NewGuid().ToString();
|
||||
SettingService.SaveSettings(settings);
|
||||
}
|
||||
Logger.Debug("Done validating settings");
|
||||
#endregion
|
||||
|
||||
Logger.Debug("Configuring MVC and Blazor");
|
||||
builder.Services.AddMvc(options => options.EnableEndpointRouting = false);
|
||||
builder.Services.AddRazorPages();
|
||||
builder.Services.AddServerSideBlazor().AddCircuitOptions(option =>
|
||||
{
|
||||
option.DetailedErrors = true;
|
||||
}).AddHubOptions(option =>
|
||||
{
|
||||
option.MaximumReceiveMessageSize = 1024 * 1024 * 11;
|
||||
option.DisableImplicitFromServicesParameters = true;
|
||||
});
|
||||
|
||||
Logger.Debug("Starting web server on port {Port}", settings.Port);
|
||||
builder.WebHost.ConfigureKestrel(options =>
|
||||
{
|
||||
// Configure as HTTP only
|
||||
options.ListenAnyIP(settings.Port);
|
||||
});
|
||||
|
||||
Logger.Debug("Initializing DatabaseContext with connection string {ConnectionString}", settings.DatabaseConnectionString);
|
||||
builder.Services.AddDbContext<LANCommander.Data.DatabaseContext>(b =>
|
||||
{
|
||||
b.UseLazyLoadingProxies();
|
||||
b.UseSqlite(settings.DatabaseConnectionString);
|
||||
});
|
||||
|
||||
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
|
||||
|
||||
Logger.Debug("Initializing Identity");
|
||||
builder.Services.AddDefaultIdentity<User>((IdentityOptions options) =>
|
||||
{
|
||||
options.SignIn.RequireConfirmedAccount = false;
|
||||
options.SignIn.RequireConfirmedEmail = false;
|
||||
|
||||
options.Password.RequireNonAlphanumeric = settings.Authentication.PasswordRequireNonAlphanumeric;
|
||||
options.Password.RequireLowercase = settings.Authentication.PasswordRequireLowercase;
|
||||
options.Password.RequireUppercase = settings.Authentication.PasswordRequireUppercase;
|
||||
options.Password.RequireDigit = settings.Authentication.PasswordRequireDigit;
|
||||
options.Password.RequiredLength = settings.Authentication.PasswordRequiredLength;
|
||||
})
|
||||
.AddRoles<Role>()
|
||||
.AddEntityFrameworkStores<LANCommander.Data.DatabaseContext>()
|
||||
.AddDefaultTokenProviders();
|
||||
|
||||
builder.Services.AddAuthentication(options =>
|
||||
{
|
||||
/*options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;*/
|
||||
})
|
||||
.AddJwtBearer(options =>
|
||||
internal class Program
|
||||
{
|
||||
options.SaveToken = true;
|
||||
options.RequireHttpsMetadata = false;
|
||||
options.TokenValidationParameters = new TokenValidationParameters()
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
ValidateIssuer = false,
|
||||
ValidateAudience = false,
|
||||
// ValidAudience = configuration["JWT:ValidAudience"],
|
||||
// ValidIssuer = configuration["JWT:ValidIssuer"],
|
||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(settings.Authentication.TokenSecret))
|
||||
};
|
||||
});
|
||||
Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
Logger.Debug("Initializing Controllers");
|
||||
builder.Services.AddControllers().AddJsonOptions(x =>
|
||||
{
|
||||
x.JsonSerializerOptions.ReferenceHandler = System.Text.Json.Serialization.ReferenceHandler.IgnoreCycles;
|
||||
});
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
Logger.Debug("Initializing Hangfire");
|
||||
builder.Services.AddHangfire(configuration =>
|
||||
configuration
|
||||
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
|
||||
.UseSimpleAssemblyNameTypeSerializer()
|
||||
.UseRecommendedSerializerSettings()
|
||||
.UseInMemoryStorage());
|
||||
builder.Services.AddHangfireServer();
|
||||
ConfigurationManager configuration = builder.Configuration;
|
||||
|
||||
Logger.Debug("Registering Swashbuckle");
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
// Add services to the container.
|
||||
Logger.Debug("Loading settings");
|
||||
var settings = SettingService.GetSettings(true);
|
||||
Logger.Debug("Loaded!");
|
||||
|
||||
Logger.Debug("Registering AntDesign Blazor");
|
||||
builder.Services.AddAntDesign();
|
||||
#region Validate Settings
|
||||
Logger.Debug("Validating settings");
|
||||
if (settings?.Authentication?.TokenSecret?.Length < 16)
|
||||
{
|
||||
Logger.Debug("JWT token secret is too short. Regenerating...");
|
||||
settings.Authentication.TokenSecret = Guid.NewGuid().ToString();
|
||||
SettingService.SaveSettings(settings);
|
||||
}
|
||||
Logger.Debug("Done validating settings");
|
||||
#endregion
|
||||
|
||||
builder.Services.AddHttpClient();
|
||||
Logger.Debug("Configuring MVC and Blazor");
|
||||
builder.Services.AddMvc(options => options.EnableEndpointRouting = false);
|
||||
builder.Services.AddRazorPages();
|
||||
builder.Services.AddServerSideBlazor().AddCircuitOptions(option =>
|
||||
{
|
||||
option.DetailedErrors = true;
|
||||
}).AddHubOptions(option =>
|
||||
{
|
||||
option.MaximumReceiveMessageSize = 1024 * 1024 * 11;
|
||||
option.DisableImplicitFromServicesParameters = true;
|
||||
});
|
||||
|
||||
Logger.Debug("Registering Services");
|
||||
builder.Services.AddScoped<SettingService>();
|
||||
builder.Services.AddScoped<ArchiveService>();
|
||||
builder.Services.AddScoped<CategoryService>();
|
||||
builder.Services.AddScoped<GameService>();
|
||||
builder.Services.AddScoped<ScriptService>();
|
||||
builder.Services.AddScoped<GenreService>();
|
||||
builder.Services.AddScoped<KeyService>();
|
||||
builder.Services.AddScoped<TagService>();
|
||||
builder.Services.AddScoped<CompanyService>();
|
||||
builder.Services.AddScoped<IGDBService>();
|
||||
builder.Services.AddScoped<ServerService>();
|
||||
builder.Services.AddScoped<ServerConsoleService>();
|
||||
builder.Services.AddScoped<GameSaveService>();
|
||||
Logger.Debug("Starting web server on port {Port}", settings.Port);
|
||||
builder.WebHost.ConfigureKestrel(options =>
|
||||
{
|
||||
// Configure as HTTP only
|
||||
options.ListenAnyIP(settings.Port);
|
||||
});
|
||||
|
||||
builder.Services.AddSingleton<ServerProcessService>();
|
||||
builder.Services.AddSingleton<IPXRelayService>();
|
||||
Logger.Debug("Initializing DatabaseContext with connection string {ConnectionString}", settings.DatabaseConnectionString);
|
||||
builder.Services.AddDbContext<LANCommander.Data.DatabaseContext>(b =>
|
||||
{
|
||||
b.UseLazyLoadingProxies();
|
||||
b.UseSqlite(settings.DatabaseConnectionString);
|
||||
});
|
||||
|
||||
if (settings.Beacon)
|
||||
{
|
||||
Logger.Debug("The beacons have been lit! LANCommander calls for players!");
|
||||
builder.Services.AddHostedService<BeaconService>();
|
||||
}
|
||||
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
|
||||
|
||||
builder.WebHost.UseStaticWebAssets();
|
||||
Logger.Debug("Initializing Identity");
|
||||
builder.Services.AddDefaultIdentity<User>((IdentityOptions options) =>
|
||||
{
|
||||
options.SignIn.RequireConfirmedAccount = false;
|
||||
options.SignIn.RequireConfirmedEmail = false;
|
||||
|
||||
builder.WebHost.UseKestrel(options =>
|
||||
{
|
||||
options.Limits.MaxRequestBodySize = 1024 * 1024 * 150;
|
||||
});
|
||||
options.Password.RequireNonAlphanumeric = settings.Authentication.PasswordRequireNonAlphanumeric;
|
||||
options.Password.RequireLowercase = settings.Authentication.PasswordRequireLowercase;
|
||||
options.Password.RequireUppercase = settings.Authentication.PasswordRequireUppercase;
|
||||
options.Password.RequireDigit = settings.Authentication.PasswordRequireDigit;
|
||||
options.Password.RequiredLength = settings.Authentication.PasswordRequiredLength;
|
||||
})
|
||||
.AddRoles<Role>()
|
||||
.AddEntityFrameworkStores<LANCommander.Data.DatabaseContext>()
|
||||
.AddDefaultTokenProviders();
|
||||
|
||||
builder.Host.UseNLog();
|
||||
builder.Services.AddAuthentication(options =>
|
||||
{
|
||||
/*options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;*/
|
||||
})
|
||||
.AddJwtBearer(options =>
|
||||
{
|
||||
options.SaveToken = true;
|
||||
options.RequireHttpsMetadata = false;
|
||||
options.TokenValidationParameters = new TokenValidationParameters()
|
||||
{
|
||||
ValidateIssuer = false,
|
||||
ValidateAudience = false,
|
||||
// ValidAudience = configuration["JWT:ValidAudience"],
|
||||
// ValidIssuer = configuration["JWT:ValidIssuer"],
|
||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(settings.Authentication.TokenSecret))
|
||||
};
|
||||
});
|
||||
|
||||
Logger.Debug("Building Application");
|
||||
var app = builder.Build();
|
||||
Logger.Debug("Initializing Controllers");
|
||||
builder.Services.AddControllers().AddJsonOptions(x =>
|
||||
{
|
||||
x.JsonSerializerOptions.ReferenceHandler = System.Text.Json.Serialization.ReferenceHandler.IgnoreCycles;
|
||||
});
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
Logger.Debug("App has been run in a development environment");
|
||||
app.UseMigrationsEndPoint();
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseExceptionHandler("/Home/Error");
|
||||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||
app.UseHsts();
|
||||
}
|
||||
Logger.Debug("Initializing Hangfire");
|
||||
builder.Services.AddHangfire(configuration =>
|
||||
configuration
|
||||
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
|
||||
.UseSimpleAssemblyNameTypeSerializer()
|
||||
.UseRecommendedSerializerSettings()
|
||||
.UseInMemoryStorage());
|
||||
builder.Services.AddHangfireServer();
|
||||
|
||||
app.UseHangfireDashboard();
|
||||
Logger.Debug("Registering Swashbuckle");
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
|
||||
// app.UseHttpsRedirection();
|
||||
app.UseStaticFiles();
|
||||
Logger.Debug("Registering AntDesign Blazor");
|
||||
builder.Services.AddAntDesign();
|
||||
|
||||
app.UseRouting();
|
||||
builder.Services.AddHttpClient();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
Logger.Debug("Registering Services");
|
||||
builder.Services.AddScoped<SettingService>();
|
||||
builder.Services.AddScoped<ArchiveService>();
|
||||
builder.Services.AddScoped<CategoryService>();
|
||||
builder.Services.AddScoped<GameService>();
|
||||
builder.Services.AddScoped<ScriptService>();
|
||||
builder.Services.AddScoped<GenreService>();
|
||||
builder.Services.AddScoped<KeyService>();
|
||||
builder.Services.AddScoped<TagService>();
|
||||
builder.Services.AddScoped<CompanyService>();
|
||||
builder.Services.AddScoped<IGDBService>();
|
||||
builder.Services.AddScoped<ServerService>();
|
||||
builder.Services.AddScoped<ServerConsoleService>();
|
||||
builder.Services.AddScoped<GameSaveService>();
|
||||
|
||||
app.UseMvcWithDefaultRoute();
|
||||
builder.Services.AddSingleton<ServerProcessService>();
|
||||
builder.Services.AddSingleton<IPXRelayService>();
|
||||
|
||||
app.MapHub<GameServerHub>("/hubs/gameserver");
|
||||
if (settings.Beacon)
|
||||
{
|
||||
Logger.Debug("The beacons have been lit! LANCommander calls for players!");
|
||||
builder.Services.AddHostedService<BeaconService>();
|
||||
}
|
||||
|
||||
Logger.Debug("Registering Endpoints");
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapBlazorHub();
|
||||
endpoints.MapFallbackToPage("/_Host");
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
builder.WebHost.UseStaticWebAssets();
|
||||
|
||||
Logger.Debug("Ensuring required directories exist");
|
||||
if (!Directory.Exists(settings.Archives.StoragePath))
|
||||
Directory.CreateDirectory(settings.Archives.StoragePath);
|
||||
builder.WebHost.UseKestrel(options =>
|
||||
{
|
||||
options.Limits.MaxRequestBodySize = 1024 * 1024 * 150;
|
||||
});
|
||||
|
||||
if (!Directory.Exists("Icon"))
|
||||
Directory.CreateDirectory("Icon");
|
||||
builder.Host.UseNLog();
|
||||
|
||||
if (!Directory.Exists(settings.UserSaves.StoragePath))
|
||||
Directory.CreateDirectory(settings.UserSaves.StoragePath);
|
||||
Logger.Debug("Building Application");
|
||||
var app = builder.Build();
|
||||
|
||||
if (!Directory.Exists("Snippets"))
|
||||
Directory.CreateDirectory("Snippets");
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
Logger.Debug("App has been run in a development environment");
|
||||
app.UseMigrationsEndPoint();
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseExceptionHandler("/Home/Error");
|
||||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
// Migrate
|
||||
Logger.Debug("Migrating database if required");
|
||||
await using var scope = app.Services.CreateAsyncScope();
|
||||
using var db = scope.ServiceProvider.GetService<DatabaseContext>();
|
||||
await db.Database.MigrateAsync();
|
||||
app.UseHangfireDashboard();
|
||||
|
||||
// Autostart any server processes
|
||||
Logger.Debug("Autostarting Servers");
|
||||
var serverService = scope.ServiceProvider.GetService<ServerService>();
|
||||
var serverProcessService = scope.ServiceProvider.GetService<ServerProcessService>();
|
||||
// app.UseHttpsRedirection();
|
||||
app.UseStaticFiles();
|
||||
|
||||
foreach (var server in await serverService.Get(s => s.Autostart).ToListAsync())
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger.Debug("Autostarting server {ServerName} with a delay of {AutostartDelay} seconds", server.Name, server.AutostartDelay);
|
||||
app.UseRouting();
|
||||
|
||||
if (server.AutostartDelay > 0)
|
||||
await Task.Delay(server.AutostartDelay);
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
serverProcessService.StartServerAsync(server);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Debug(ex, "An unexpected error occurred while trying to autostart the server {ServerName}", server.Name);
|
||||
app.UseMvcWithDefaultRoute();
|
||||
|
||||
app.MapHub<GameServerHub>("/hubs/gameserver");
|
||||
|
||||
Logger.Debug("Registering Endpoints");
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapBlazorHub();
|
||||
endpoints.MapFallbackToPage("/_Host");
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
|
||||
Logger.Debug("Ensuring required directories exist");
|
||||
if (!Directory.Exists(settings.Archives.StoragePath))
|
||||
Directory.CreateDirectory(settings.Archives.StoragePath);
|
||||
|
||||
if (!Directory.Exists("Icon"))
|
||||
Directory.CreateDirectory("Icon");
|
||||
|
||||
if (!Directory.Exists(settings.UserSaves.StoragePath))
|
||||
Directory.CreateDirectory(settings.UserSaves.StoragePath);
|
||||
|
||||
if (!Directory.Exists("Snippets"))
|
||||
Directory.CreateDirectory("Snippets");
|
||||
|
||||
// Migrate
|
||||
Logger.Debug("Migrating database if required");
|
||||
await using var scope = app.Services.CreateAsyncScope();
|
||||
using var db = scope.ServiceProvider.GetService<DatabaseContext>();
|
||||
await db.Database.MigrateAsync();
|
||||
|
||||
// Autostart any server processes
|
||||
Logger.Debug("Autostarting Servers");
|
||||
var serverService = scope.ServiceProvider.GetService<ServerService>();
|
||||
var serverProcessService = scope.ServiceProvider.GetService<ServerProcessService>();
|
||||
|
||||
foreach (var server in await serverService.Get(s => s.Autostart).ToListAsync())
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger.Debug("Autostarting server {ServerName} with a delay of {AutostartDelay} seconds", server.Name, server.AutostartDelay);
|
||||
|
||||
if (server.AutostartDelay > 0)
|
||||
await Task.Delay(server.AutostartDelay);
|
||||
|
||||
serverProcessService.StartServerAsync(server);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Debug(ex, "An unexpected error occurred while trying to autostart the server {ServerName}", server.Name);
|
||||
}
|
||||
}
|
||||
|
||||
app.Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
app.Run();
|
Loading…
Reference in New Issue