mirror of
https://gitea.tendokyu.moe/ppc/amnet.git
synced 2026-09-22 22:28:22 +03:00
126 lines
3.7 KiB
C#
126 lines
3.7 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
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";
|
|
|
|
// instance metrics
|
|
internal static long LastPollTime = -1;
|
|
internal static long ServerStartedAt;
|
|
|
|
static DllMain()
|
|
{
|
|
PInvoke.AllocConsole();
|
|
|
|
App = WebServer.BuildServer(Config.ReadKey(Config.IOSection, "serverAddress", 1024, "http://+:6070").Split(';'));
|
|
}
|
|
|
|
private static WebApplication App { get; }
|
|
|
|
[UnmanagedCallersOnly(EntryPoint = "aime_io_get_api_version")]
|
|
public static ushort GetApiVersion() => 0x0100;
|
|
|
|
[UnmanagedCallersOnly(EntryPoint = "aime_io_init")]
|
|
public static int Init()
|
|
{
|
|
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();
|
|
});
|
|
|
|
Volatile.Write(ref ServerStartedAt, Environment.TickCount64);
|
|
App.RunAsync();
|
|
return 0;
|
|
}
|
|
|
|
[UnmanagedCallersOnly(EntryPoint = "aime_io_nfc_poll")]
|
|
public static int NfcPoll(byte unitNo)
|
|
{
|
|
Volatile.Write(ref LastPollTime, Environment.TickCount64);
|
|
|
|
if (!Config.EnableAimeTxt)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
// check keyboard input for the enter key being held down (0x0D)
|
|
var enterPressed = (PInvoke.GetAsyncKeyState(0x0D) & 0x8000) != 0;
|
|
|
|
if (!enterPressed)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
try
|
|
{
|
|
using var aimeTxtReader = new StreamReader(File.OpenRead(Config.AimeTxtPath), Encoding.UTF8);
|
|
|
|
var fileName = Path.GetFileName(Config.AimeTxtPath);
|
|
var cardResult = App.Services.GetRequiredService<CardPresenter>().SetCard(aimeTxtReader.ReadLine());
|
|
|
|
if (cardResult == null)
|
|
{
|
|
App.Logger.LogWarning("Failed to read card from {file}: invalid format", fileName);
|
|
}
|
|
else
|
|
{
|
|
App.Logger.LogInformation("Card loaded from {fileName}", fileName);
|
|
}
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
App.Logger.LogWarning("Failed to read '{path}': {message}", Path.GetFullPath(Config.AimeTxtPath), e.Message);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
[UnmanagedCallersOnly(EntryPoint = "aime_io_nfc_get_aime_id")]
|
|
public static int GetAimeId(byte unitNo, IntPtr luid, nint luidSize)
|
|
{
|
|
if (unitNo != 0)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
var card = App.Services.GetRequiredService<CardPresenter>().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: {cardId}", card);
|
|
}
|
|
}
|
|
|
|
[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
|
|
}
|
|
} |