/// <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);
        }
Esempio n. 2
0
        /// <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);
        }
Esempio n. 3
0
        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));
        }
Esempio n. 4
0
        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);
        }