// // DllMain.cs // // Copyright (c) František Boháček. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Diagnostics; using System.Runtime.InteropServices; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using NosSmooth.Comms.Core; using NosSmooth.Comms.Core.Extensions; using NosSmooth.Comms.Data; using NosSmooth.Comms.Inject.Extensions; using NosSmooth.Comms.Inject.MessageResponders; using NosSmooth.Comms.Inject.PacketResponders; using NosSmooth.Core.Extensions; using NosSmooth.Extensions.SharedBinding.Extensions; using NosSmooth.LocalBinding.Options; using NosSmooth.LocalClient.Extensions; using Remora.Results; namespace NosSmooth.Comms.Inject; /// /// A main entrypoint to NosSmooth local communications. /// public class DllMain { private static bool _consoleAllocated; private static IHost? _host; /// /// Enable named pipes server. /// [UnmanagedCallersOnly(EntryPoint = "EnableNamedPipes")] public static void EnableNamedPipes() { Main ( host => { var manager = host.Services.GetRequiredService(); return manager.RunManagerAsync (host.Services.GetRequiredService().ApplicationStopping); } ); } /// /// Open a console. /// [UnmanagedCallersOnly(EntryPoint = "OpenConsole")] public static void OpenConsole() { WinConsole.Initialize(false); } /// /// Close a console. /// [UnmanagedCallersOnly(EntryPoint = "CloseConsole")] public static void CloseConsole() { WinConsole.Close(); } private static void Main(Func> host) { new Thread ( () => { try { MainEntry(host).GetAwaiter().GetResult(); } catch (Exception e) { Console.WriteLine(e.ToString()); } } ).Start(); } /// /// The entrypoint method. /// /// A representing the asynchronous operation. private static async Task MainEntry(Func> host) { if (_host is not null) { var result = await host(_host); if (!result.IsSuccess) { _host.Services.GetRequiredService>().LogResultError(result); } return; } var clientState = new ClientState(); _host = Host.CreateDefaultBuilder() .UseConsoleLifetime() .ConfigureLogging ( b => { b .ClearProviders() .AddConsole(); } ) .ConfigureServices ( s => { s .AddSingleton(_ => clientState) .AddSingleton() .AddManagedNostaleCore() .AddLocalClient() .ShareNosSmooth() .AddNamedPipeServer(p => $"NosSmooth_{Process.GetCurrentProcess().Id}") .AddPacketResponder() .AddServerHandling() .AddMessageResponder() .AddMessageResponder() .AddMessageResponder() .AddMessageResponder() .AddMessageResponder() .AddMessageResponder() .AddMessageResponder() .Configure(clientState.HookOptions.CopyProperties) .Configure(clientState.PlayerManagerOptions.CopyProperties) .Configure(opts => clientState.NetworkManagerOptions.CopyProperties(opts)) .Configure(clientState.SceneManagerOptions.CopyProperties) .Configure(clientState.UnitManagerOptions.CopyProperties) .Configure(clientState.NtClientOptions.CopyProperties) .Configure(clientState.PetManagerOptions.CopyProperties); s.AddHostedService(); } ).Build(); await _host.StartAsync(); var hostTask = _host.WaitForShutdownAsync(); var serverTask = host(_host); await Task.WhenAll(hostTask, serverTask); } }