Skip to content

Commit

Permalink
Add bootstrap for login service
Browse files Browse the repository at this point in the history
  • Loading branch information
Kaioru committed Apr 15, 2024
1 parent a8c951e commit 1504809
Show file tree
Hide file tree
Showing 54 changed files with 1,846 additions and 184 deletions.
7 changes: 7 additions & 0 deletions Edelstein.sln
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Edelstein.Common.Network.Do
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Edelstein.Common.Crypto", "src\common\Edelstein.Common.Crypto\Edelstein.Common.Crypto.csproj", "{2B8D2564-3DF1-42B2-9A50-0AAD2E8A8AE8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Edelstein.Common.Gameplay", "src\common\Edelstein.Common.Gameplay\Edelstein.Common.Gameplay.csproj", "{F66379E6-CAB8-4E63-BB0C-94B98F021A29}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -76,6 +78,7 @@ Global
{406AF08D-7BF4-4C00-A959-60D5D4601295} = {82D7864B-19AD-484C-BD2E-897F05B5852C}
{F94D12DC-FDC8-48F2-9EF0-7F229AF1A9CC} = {E50DFCDF-39D5-4D0D-A46E-94D11D795087}
{2B8D2564-3DF1-42B2-9A50-0AAD2E8A8AE8} = {E50DFCDF-39D5-4D0D-A46E-94D11D795087}
{F66379E6-CAB8-4E63-BB0C-94B98F021A29} = {E50DFCDF-39D5-4D0D-A46E-94D11D795087}
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5AA56CCA-0711-4F1E-956D-6A9ECB62AA6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -130,5 +133,9 @@ Global
{2B8D2564-3DF1-42B2-9A50-0AAD2E8A8AE8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2B8D2564-3DF1-42B2-9A50-0AAD2E8A8AE8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2B8D2564-3DF1-42B2-9A50-0AAD2E8A8AE8}.Release|Any CPU.Build.0 = Release|Any CPU
{F66379E6-CAB8-4E63-BB0C-94B98F021A29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F66379E6-CAB8-4E63-BB0C-94B98F021A29}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F66379E6-CAB8-4E63-BB0C-94B98F021A29}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F66379E6-CAB8-4E63-BB0C-94B98F021A29}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
2 changes: 2 additions & 0 deletions src/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.0-preview.3.24172.4" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0-preview.3.24172.9" />
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.0" />
<PackageVersion Include="MinVer" Version="5.0.0" />
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.2" />
Expand All @@ -21,5 +22,6 @@
<PackageVersion Include="Serilog.Settings.Configuration" Version="8.0.0" />
<PackageVersion Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageVersion Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
</ItemGroup>
</Project>
12 changes: 12 additions & 0 deletions src/app/Edelstein.Application.Server/Bindings/StageConfigLogin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Edelstein.Protocol.Gameplay.Login;
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.

namespace Edelstein.Application.Server.Bindings;

public record StageConfigLogin : ILoginStageSystemOptions
{
public string ID { get; init; }

public string Host { get; init; }
public int Port { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@
<PackageReference Include="Serilog.Settings.Configuration" />
<PackageReference Include="Serilog.Sinks.Console" />
<PackageReference Include="Serilog.Sinks.File" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\common\Edelstein.Common.Services.Server\Edelstein.Common.Services.Server.csproj" />
<ProjectReference Include="..\..\protocol\Edelstein.Protocol.Utilities\Edelstein.Protocol.Utilities.csproj" />
<PackageReference Include="System.CommandLine" />
</ItemGroup>

<ItemGroup>
Expand All @@ -23,6 +19,7 @@
</ItemGroup>

<ItemGroup>
<Folder Include="Bindings\" />
<ProjectReference Include="..\..\common\Edelstein.Common.Gameplay.Login\Edelstein.Common.Gameplay.Login.csproj" />
<ProjectReference Include="..\..\common\Edelstein.Common.Network.DotNetty\Edelstein.Common.Network.DotNetty.csproj" />
</ItemGroup>
</Project>
31 changes: 15 additions & 16 deletions src/app/Edelstein.Application.Server/Program.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
using Edelstein.Common.Services.Server;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;
using System;
using System.CommandLine;
using System.IO;
using Edelstein.Application.Server;

var builder = Host.CreateApplicationBuilder();
var commandRoot = new RootCommand(
"A mushroom game server emulator"
);
var argumentFile = new Argument<FileInfo>(
"file or directory path",
() => new FileInfo(AppDomain.CurrentDomain.BaseDirectory),
"The file or directory path to stage json file(s)"
);

builder.Services.AddSerilog((_, logger)
=> logger.ReadFrom.Configuration(builder.Configuration));
commandRoot.AddArgument(argumentFile);
commandRoot.SetHandler(ProgramHandler.ExecuteRoot, argumentFile);

builder.Services.AddDbContextFactory<ServerDbContext>(options
=> options.UseNpgsql(builder.Configuration.GetConnectionString(ServerDbContext.ConnectionStringKey)));
builder.Services.AddAutoMapper(typeof(ServerDbContext));

var host = builder.Build();

await host.RunAsync();
await commandRoot.InvokeAsync(args);
67 changes: 67 additions & 0 deletions src/app/Edelstein.Application.Server/ProgramHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Edelstein.Application.Server.Bindings;
using Edelstein.Common.Gameplay.Login;
using Edelstein.Protocol.Gameplay.Login;
using Edelstein.Protocol.Network.Transports;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;

namespace Edelstein.Application.Server;

internal static class ProgramHandler
{
public async static Task ExecuteRoot(FileInfo file)
{
var builder = Host.CreateApplicationBuilder();

builder.Services.AddSerilog((_, configuration) => configuration.ReadFrom.Configuration(builder.Configuration));

builder.Services.AddEdelsteinCommonUtilities();
builder.Services.AddEdelsteinCommonGameplay();
builder.Services.AddEdelsteinCommonGameplayLogin();

var configFileInfos = (file.Attributes & FileAttributes.Directory) != 0
? file.Directory?.GetFiles() ?? Array.Empty<FileInfo>()
: new[]{ file };

foreach (var configFile in configFileInfos.Where(f => f.Extension == ".json"))
{
var version = new TransportVersion(95, "1", 8);
var config = new ConfigurationBuilder()
.AddJsonFile(configFile.FullName, false, false)
.Build();

switch (config["Type"])
{
case "Login":
builder.Services.AddHostedService(p =>
{
var loginConfig = new StageConfigLogin();
var loginSystem = new LoginStageSystem(loginConfig);

config.Bind(loginConfig);

return new ServiceHostStage<ILoginStageUser, ILoginStageSystem>(
p.GetRequiredService<ILogger<ServiceHostStage<ILoginStageUser, ILoginStageSystem>>>(),
version,
loginConfig,
loginSystem
);
});
break;
default:
continue;
}
}

var host = builder.Build();

await host.RunAsync();
}
}
55 changes: 55 additions & 0 deletions src/app/Edelstein.Application.Server/ServiceHostStage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System.Threading;
using System.Threading.Tasks;
using Edelstein.Common.Network.DotNetty.Transports;
using Edelstein.Protocol.Gameplay;
using Edelstein.Protocol.Network.Transports;
using Edelstein.Protocol.Services.Server;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace Edelstein.Application.Server;

public class ServiceHostStage<TStageUser, TStageSystem>(
ILogger<ServiceHostStage<TStageUser, TStageSystem>> logger,
TransportVersion version,
IServerEntry settings,
IStageSystem<TStageUser, TStageSystem> system
) : IHostedService
where TStageUser : class, IStageUser<TStageUser, TStageSystem>
where TStageSystem : IStageSystem<TStageUser, TStageSystem>
{
private ITransportContext? Context { get; set; }

public async Task StartAsync(CancellationToken cancellationToken)
{
var acceptor = new NettyTransportAcceptor<TStageUser>(
version,
system,
system
);

Context = await acceptor.Accept(settings.Host, settings.Port);
logger.LogInformation(
"{ID} socket acceptor for v{Version}.{Patch} (Locale {Locale}) bound at {Host}:{Port}",
settings.ID,
version.Major, version.Patch, version.Locale,
settings.Host, settings.Port
);
}

public async Task StopAsync(CancellationToken cancellationToken)
{
logger.LogInformation(
"{ID} socket acceptor shutting down, this may take awhile..",
settings.ID
);

if (Context != null)
await Context.Close();

logger.LogInformation(
"{ID} socket acceptor finished shutting down",
settings.ID
);
}
}
Loading

0 comments on commit 1504809

Please sign in to comment.