ReboundEmulator/Core/Sessions.cs
Moonbase 2631d3199c Implement Multiplayer Support
Implement Custom Screen Name Support
2026-10-06 19:00:15 -07:00

58 lines
2.4 KiB
C#

using Microsoft.AspNetCore.StaticFiles;
using System.Collections.Concurrent;
using System.Security.Cryptography;
using System.Text;
namespace NotPogo.Core
{
public sealed class Account
{
public required string ScreenName { get; init; }
public string ProfileId { get; init; } = "1000000000"; // pfid
public string Site { get; init; } = "pogo";
public int Tokens { get; set; } = 9999;
public string Avatar { get; set; } = "";
public bool OwnsPremiumAvatar { get; set; } = true; // enti.oava
public bool OwnsBadges { get; set; } = true; // enti.obad
}
public static class Sessions
{
static byte[] _secret = []; // set once at startup
static readonly ConcurrentDictionary<string, Account> Live = new(StringComparer.OrdinalIgnoreCase);
public static void Init(string secret) => _secret = Encoding.UTF8.GetBytes(secret);
// lkey = base64url(screenName) + "." + base64url(HMAC(screenName))
public static string Issue(string screenName)
{
var name = Encoding.UTF8.GetBytes(screenName);
return B64(name) + "." + B64(HMACSHA256.HashData(_secret, name));
}
public static Account? Find(string? lkey)
{
if (string.IsNullOrEmpty(lkey)) return null;
var parts = lkey.Split('.');
if (parts.Length != 2) return null;
try
{
var name = UnB64(parts[0]);
if (!CryptographicOperations.FixedTimeEquals(UnB64(parts[1]), HMACSHA256.HashData(_secret, name)))
return null; // forged or from another secret
var screenName = Encoding.UTF8.GetString(name);
// in-memory state for this run; recreated with defaults after a restart
return Live.GetOrAdd(screenName, n => new Account { ScreenName = n });
}
catch (FormatException) { return null; }
}
static string B64(byte[] b) => Convert.ToBase64String(b).TrimEnd('=').Replace('+', '-').Replace('/', '_');
static byte[] UnB64(string s)
{
s = s.Replace('-', '+').Replace('_', '/');
return Convert.FromBase64String(s + new string('=', (4 - s.Length % 4) % 4));
}
}
}