/// <summary> /// Takes in an unmapped ICommMessage and maps + routes it to subscribers. /// </summary> /// <param name="message"></param> public void Publish(ICommMessage message) { if (!_routes.ContainsKey(message.PayloadType)) { _logger.Log("Unknown message type in router. " + message.PayloadType, LogLevel.Error); return; } _routes[message.PayloadType](message); }
/// <summary> /// Fetch area with known type from database. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="areaId"></param> /// <param name="areaType"></param> /// <returns></returns> public async Task <T> GetAreaFromDatabase <T>(int areaId, AreaTypes areaType) where T : AreaModel { try { return(await _databaseManager.GetAreaAsync(areaId, areaType) as T); } catch (WrongAreaTypeException e) { _logger.Log("User requested area of different type. Potential race condition or hacking?", LogLevel.Warning); } return(null); }
private async Task <dynamic> _handleLogin(dynamic parameters, CancellationToken cancellationToken) { string username = parameters["username"]; string password = parameters["password"]; bool apiOnly = Request.Query["api-only"]; _logger.Log("Handling login attempt from " + username, LogLevel.Verbose); var am = await _databaseManager.GetAccountAsync(username); var lr = new LoginResponse(); if (am == null) { _logger.Log(username + " login failed: account not found.", LogLevel.Verbose); lr.Result = LoginResult.InvalidUsernameOrPassword; return(ReturnJsonResponse(lr)); } if (am.Password != password) { _logger.Log(username + " login failed: incorrect password.", LogLevel.Verbose); lr.Result = LoginResult.InvalidUsernameOrPassword; return(ReturnJsonResponse(lr)); } //else if(_IDToConnectionAddress.ContainsKey(am.Id)) //{ // //Ignore //} var ivkey = _cryptographyManager.GenerateIVKey(); lr.IV = ivkey.IV; lr.Key = ivkey.Key; // Grab player so that the UI knows what state the load initially. var player = await _databaseManager.GetPlayerAsync(username); var currentArea = await _databaseManager.GetAreaAsync(player.CurrentAreaID.Value); var areaType = player.CurrentAreaID.HasValue ? currentArea.AreaType : AreaTypes.Limbo; lr.CurrentAreaType = ConvertAreaToInterfaceState(areaType); var clientAddress = IPAddress.Parse(Request.UserHostAddress); var currentSession = await _sessionService.FindPlayerSession(am.PlayerID); // Client already logged in if (currentSession != null) { _logger.Log(username + " duplicate login, continuing.", LogLevel.Verbose); lr.ApiToken = currentSession.ApiToken; } else { // Can throw an exception, but we probably want to fail over if it does. var session = await _sessionService.CreatePlayerSession(am, clientAddress); lr.ApiToken = session.ApiToken; } //Wait for redis response var response = await PublishToSlave(am, lr, clientAddress); if (response == null) { var msg = "Error: no ServerConnectionAddress response recieved from redis. Possible causes: no slaves running, no slaves handling given account, account doesn't exist."; Console.WriteLine(msg); lr.Result = LoginResult.ServerNotReady; //throw new Exception(msg); } else if ((response.Result == LoginResult.AlreadyLoggedOn) || (response.Result == LoginResult.AlreadyPending)) { Console.WriteLine(username + ": " + response.Result); lr.Result = response.Result; } else { lr.ServerIP = response.ServerIP; lr.ServerPort = response.ServerPort; lr.Result = LoginResult.Success; #if DEBUG Console.WriteLine(username + " has logged in succesfully. Notifying slave..."); #endif } return(ReturnJsonResponse(lr)); }
public IServerTransportNode Start(Func <IClientNode, bool> validateClientCallback) { // If no validation callback was specified, just return true. Func <IClientNode, bool> validateClient = validateClientCallback != null ? validateClientCallback : validateClient = (c) => true; _server.Start(); _serverStatusChanged = new Subject <ServerStatusChanged>(); var rxStream = new Subject <RawClientRequest>(); var clientStatusStream = new Subject <ClientStatusChanged>(); _server.RegisterReceivedCallback(new SendOrPostCallback((obj) => { NetIncomingMessage message; while ((message = _server.ReadMessage()) != null) { switch (message.MessageType) { case NetIncomingMessageType.Data: LidgrenClientNode client = null; if (message.SenderConnection != null) { client = new LidgrenClientNode(message.SenderConnection); } // Todo: Perform session validation here. Maybe? rxStream.OnNext(new RawClientRequest(ReadMessage(message), client)); break; case NetIncomingMessageType.VerboseDebugMessage: case NetIncomingMessageType.DebugMessage: case NetIncomingMessageType.WarningMessage: case NetIncomingMessageType.ErrorMessage: _logger.Log("Unhandled type: " + message.MessageType, LogLevel.Verbose); break; case NetIncomingMessageType.ConnectionApproval: // Todo: Pass in node. if (validateClient(null)) { message.SenderConnection.Approve(); } else { message.SenderConnection.Deny(); } break; default: _logger.Log("Unhandled type: " + message.MessageType, LogLevel.Warning); break; } _server.Recycle(message); } }), new SynchronizationContext()); _transportNode = new ServerTransportNode(rxStream, clientStatusStream, _serverStatusChanged); return(_transportNode); }