// // 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. /// /// Should be zero, is not used. /// The result, 0 success, 1 failure. [UnmanagedCallersOnly(EntryPoint = "EnableNamedPipes")] public static int EnableNamedPipes(nuint data) => Main ( host => { var manager = host.Services.GetRequiredService(); return manager.RunManagerAsync (host.Services.GetRequiredService().ApplicationStopping); } ); /// /// Open a console. /// /// Should be zero, is not used. /// The result, 0 success, 1 failure. [UnmanagedCallersOnly(EntryPoint = "OpenConsole")] public static int OpenConsole(nuint data) { WinConsole.Initialize(false); return 0; } /// /// Close a console. /// /// Should be zero, is not used. /// The result, 0 success, 1 failure. [UnmanagedCallersOnly(EntryPoint = "CloseConsole")] public static int CloseConsole(nuint data) { WinConsole.Close(); return 0; } private static int Main(Func> host) { try { new Thread ( () => { try { MainEntry(host).GetAwaiter().GetResult(); } catch (Exception e) { Console.WriteLine(e.ToString()); } } ).Start(); return 0; } catch (Exception) { return 1; } } /// /// 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); } }