using ASodium; using EmbedIO; using Google.Protobuf; using nksrv.Utils; using Swan.Logging; namespace nksrv.LobbyServer { public static class LobbyHandler { public static readonly Dictionary Handlers = new Dictionary(); static LobbyHandler() { foreach (System.Type type in typeof(LobbyMsgHandler).Assembly.GetTypes()) { if (type.GetCustomAttributes(typeof(PacketPathAttribute), true).Length > 0) { var attrib = (PacketPathAttribute?)Attribute.GetCustomAttribute(type, typeof(PacketPathAttribute)); if (attrib == null) { Logger.Error("WARNING: Failed to get attribute for " + type.FullName); continue; } var instance = Activator.CreateInstance(type); if (instance is LobbyMsgHandler handler) { Handlers.Add(attrib.Url, handler); } else { Logger.Error($"WARNING: Type {type.FullName} has PacketPathAttribute but does not implement LobbyMsgHandler"); } } } } public static async Task DispatchSingle(IHttpContext ctx) { //var x = new RedirectionHandler(); //await x.HandleAsync(ctx); //return; LobbyMsgHandler? handler = null; foreach (var item in Handlers) { if (ctx.RequestedPath == item.Key) { handler = item.Value; } } if (handler == null) { ctx.Response.StatusCode = 404; //Logger.Error("HTTPS: No handler for /v1/" + ctx.RequestedPath); } else { // todo move everClass1.csything to its own handler handler.Reset(); await handler.HandleAsync(ctx); return; } } /// /// Private key, Token /// /// /// public static GameClientInfo GenGameClientTok(ByteString publicKey, string authToken) { var token = Rng.RandomString(381); var info = new GameClientInfo() { ClientPublicKey = publicKey.ToArray() }; var box = SodiumKeyExchange.CalculateServerSharedSecret(JsonDb.ServerPublicKey, JsonDb.ServerPrivateKey, publicKey.ToArray()); info.Keys = box; info.ClientAuthToken = token; // look up user id foreach (var user in JsonDb.Instance.LauncherAccessTokens) { if (user.Token == authToken) { info.UserId = user.UserID; } } if (info.UserId == 0) throw new Exception("expected user account"); JsonDb.Instance.GameClientTokens.Add(token, info); JsonDb.Save(); return info; } public static GameClientInfo? GetInfo(string token) { return JsonDb.Instance.GameClientTokens[token]; } public static void Init() { // By calling this function, we force .NET to initialize handler dictanary to catch errors early on. } } public class GameClientInfo { /// /// Client public key generated by game client /// public byte[] ClientPublicKey; /// /// Authentication token /// public string ClientAuthToken; /// /// Rx/Tx key pair /// public SodiumKeyExchangeSharedSecretBox Keys; /// /// User ID of the user /// public ulong UserId; } }