using System.Linq; using System.Runtime.InteropServices; using System.Threading; using Windows.Win32; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace AMNet.Server; public static class DllMain { private const string WebAddress = "http://card.ppc.moe"; private static WebApplication _app; static DllMain() { PInvoke.AllocConsole(); } [UnmanagedCallersOnly(EntryPoint = "aime_io_get_api_version")] public static ushort GetApiVersion() => 0x0100; [UnmanagedCallersOnly(EntryPoint = "aime_io_init")] public static int Init() { var addresses = Config.ReadKey(Config.IOSection, "serverAddress", 1024, "http://+:6070").Split(';'); _app = WebServer.BuildServer(addresses); CancellationTokenRegistration? cancellationRegistration = null; cancellationRegistration = _app.Lifetime.ApplicationStarted.Register(() => { _app.Logger.LogInformation("AMNet Server ({gameId}) started successfully.", Config.GameId); _app.Logger.LogInformation("Visit {addr} from a mobile device on the same network to get started.", WebAddress); // ReSharper disable once AccessToModifiedClosure cancellationRegistration?.Dispose(); }); _app.RunAsync(); return 0; } [UnmanagedCallersOnly(EntryPoint = "aime_io_nfc_poll")] public static int NfcPoll(byte unitNo) { // there's no polling here (handled by the webserver) return 0; } [UnmanagedCallersOnly(EntryPoint = "aime_io_nfc_get_aime_id")] public static int GetAimeId(byte unitNo, nint luid, nint luidSize) { if (unitNo != 0) { return 1; } var card = _app.Services.GetRequiredService().TakeActiveCard(); if (card?.Expired != false) { return 1; } try { Marshal.Copy(card.Value, 0, luid, (int)luidSize); return 0; } finally { _app.Logger.LogInformation("Card read in: {0}", string.Join(" ", Enumerable.Range(0, 5).Select(x => card.OriginalValue.Substring(x * 4, 4)))); } } [UnmanagedCallersOnly(EntryPoint = "aime_io_nfc_get_felica_id")] public static unsafe int GetFelicaId(byte unitNo, ulong* idm) => 1; // felica not supported [UnmanagedCallersOnly(EntryPoint = "aime_io_led_set_color")] public static void SetLedColour(byte unitNo, byte r, byte g, byte b) { // do nothing } }