示例#1
0
        public async void HandleMessage(Client.Client sender, PacketReader stream)
        {
            if (sender == null)
            {
                throw new ArgumentNullException(nameof(sender));
            }

            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            try
            {
                string      userName = stream.ReadString();
                string      password = stream.ReadString();
                LoginResult result   = await _AuthenticationService.LoginClientAsync(sender, userName, password);

                if (result.Successful)
                {
                    using (var writer = _PacketWriterPool.GetScriptMessageStream(ScriptMessages.LoginAcknowledge))
                    {
                        sender.SendScriptMessage(writer, NetPriority.High, NetReliability.ReliableOrdered);
                    }
                }
                else
                {
                    if (result is LoginFailedResult failedResult)
                    {
                        using (var writer = _PacketWriterPool.GetScriptMessageStream(ScriptMessages.LoginDenied))
                        {
                            writer.Write((byte)failedResult.Reason);
                            writer.Write(failedResult.ReasonText);
                            sender.SendScriptMessage(writer, NetPriority.High, NetReliability.ReliableOrdered);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                _Logger.Error($"An exception occured while trying to handle a '{SupportedMessage}' script message. Exception: {e}");
            }
        }
示例#2
0
        public async void HandleMessage(Client.Client sender, PacketReader stream)
        {
            if (sender == null)
            {
                throw new ArgumentNullException(nameof(sender));
            }

            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            try
            {
                string userName = stream.ReadString();
                string password = stream.ReadString();

                AccountCreationResult result =
                    await _AuthenticationService.CreateAccountAsync(userName, password);

                if (result is AccountCreationSuccessful successfulResult)
                {
                    using (var writer = _PacketWriterPool.GetScriptMessageStream(ScriptMessages.AccountCreationResult))
                    {
                        writer.Write(true);
                        sender.SendScriptMessage(writer, NetPriority.Medium, NetReliability.ReliableOrdered);
                    }
                }
                else if (result is AccountCreationFailed failedResult)
                {
                    using (var writer = _PacketWriterPool.GetScriptMessageStream(ScriptMessages.AccountCreationResult))
                    {
                        writer.Write(false);
                        writer.Write(failedResult.ReasonText);
                        sender.SendScriptMessage(writer, NetPriority.Medium, NetReliability.ReliableOrdered);
                    }
                }
            }
            catch (Exception e)
            {
                _Log.Error($"Something went wrong while trying to handle a '{SupportedMessage}' script message. Exception: {e}");
            }
        }
示例#3
0
        /// <summary>
        /// Logs out the given <see cref="Client"/>.
        /// <remarks>Does nothing if the <see cref="Client"/> is not logged in.</remarks>
        /// </summary>
        /// <param name="client">The <see cref="Client"/> that should be logged out.</param>
        public void LogoutClient(Client.Client client)
        {
            if (client == null)
            {
                throw new ArgumentNullException(nameof(client));
            }

            //Check if the client is logged in and if that is the case remove it from the dictionary of logged in clients.
            Account account = null;

            lock (_Lock)
            {
                if (_SessionByClient.TryGetValue(client, out Session session))
                {
                    _SessionByClient.Remove(client);
                    account = session.Account;
                    _ClientIdLoggedIn[session.ClientId] = false;
                    session.Invalidate();
                }
            }

            //If the Client ist still connected we have to send the messages that are required to bring the client back to the state of being able to log in again.
            if (client.IsConnected)
            {
                using (var message = _PacketWriterPool.GetScriptMessageStream(ScriptMessages.LogoutAcknowledged))
                {
                    client.SendScriptMessage(message, NetPriority.High, NetReliability.ReliableOrdered);
                }
            }

            //Invoke the logout event.
            if (account != null)
            {
                _Dispatcher.RunOrEnqueue(() =>
                {
                    var eventArgs = new LogoutEventArgs(client, account);
                    account.OnLoggedOut(eventArgs);
                    ClientLoggedOut?.Invoke(this, eventArgs);
                });
            }
        }
示例#4
0
        public async void HandleMessage(Client.Client sender, PacketReader stream)
        {
            if (sender == null)
            {
                throw new ArgumentNullException(nameof(sender));
            }

            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            try
            {
                CharCreationInfo creationInfo = new CharCreationInfo();
                creationInfo.Read(stream);

                //Get the account session of the client.
                if (_AuthenticationService.TryGetSession(sender, out Session session))
                {
                    //Lets first check if the account can have an additional account(limit is taken from the rp config).
                    int charOwnershipsCount = await _CharacterService.GetCharacterOwnershipsCountAsync(session.Account);


                    if (charOwnershipsCount >= _RpConfig.MaxCharacterPerAccount)
                    {
                        using (var packet = _PacketWriterPool.GetScriptMessageStream(ScriptMessages.CharacterCreationResult))
                        {
                            packet.Write(false);
                            packet.Write((byte)CharacterCreationFailure.CharacterLimitReached);
                            sender.SendScriptMessage(packet, NetPriority.Medium, NetReliability.Reliable);
                        }
                        return;
                    }


                    //Create the new character.
                    CharacterCreationResult result =
                        await _CharacterService.CreateHumanPlayerCharacterAsync(creationInfo);



                    if (result is CharacterCreationFailed failed)
                    {
                        using (var packet = _PacketWriterPool.GetScriptMessageStream(ScriptMessages.CharacterCreationResult))
                        {
                            //Failure
                            packet.Write(false);
                            packet.Write((byte)failed.Reason);
                            sender.SendScriptMessage(packet, NetPriority.Medium, NetReliability.Reliable);
                        }
                    }
                    else if (result is CharacterCreationSuccess success)
                    {
                        //The character was created. Add an ownership entity and set the active character for account of the message sender.
                        await Task.WhenAll(new List <Task>
                        {
                            _CharacterService.AddCharacterOwnershipAsync(session.Account, success.Character),
                            _CharacterService.SetAccountActiveCharacterAsync(session.Account, success.Character)
                        });


                        using (var packet = _PacketWriterPool.GetScriptMessageStream(ScriptMessages.CharacterCreationResult))
                        {
                            //Success
                            packet.Write(true);
                            sender.SendScriptMessage(packet, NetPriority.Medium, NetReliability.Reliable);
                        }
                    }
                }
                else
                {
                    //This should not even be possible. Disconnect the client.
                    _Log.Error($"The client '{sender.SystemAddress}' tried to create a character while not being logged in(should never be possible)");
                    sender.Disconnect();
                }
            }
            catch (Exception e)
            {
                _Log.Error($"Something went wrong while handling a '{SupportedMessage}' message from the client '{sender.SystemAddress}'. Exception: {e}");
                sender.Disconnect();
            }
        }
示例#5
0
        public async void HandleMessage(Client.Client sender, PacketReader stream)
        {
            if (sender == null)
            {
                throw new ArgumentNullException(nameof(sender));
            }

            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            try
            {
                int id = stream.ReadInt();

                //Projection against receiving the message again(which would be a client problem).
                if (sender.TryGetControlledNpc(out NpcInst controlledNpc))
                {
                    if (_Service.TryGetMapping(controlledNpc, out CharacterMapping characterMapping))
                    {
                        characterMapping.Character.RemoveMapping();
                    }
                    else
                    {
                        controlledNpc.Despawn();
                    }

                    _Log.Error($"A client send a {SupportedMessage} even through it does already control a npc. Trying to disconnect the player and remove the npc to get back into a defined state");
                    sender.Disconnect();
                    return;
                }

                //Get and map the selected character of the client.
                if (_AuthenticationService.TryGetSession(sender, out Session session))
                {
                    IList <Character> list = await _Service.GetAccountOwnedCharactersAsync(session.Account);

                    Character selectedChar = list.FirstOrDefault(c => c.CharacterId == id);

                    bool success = true;
                    JoinGameFailedReason failureReason = JoinGameFailedReason.None;


                    if (selectedChar == null)
                    {
                        //Invalid character id... return an error
                        success       = false;
                        failureReason = JoinGameFailedReason.InvalidCharacterId;
                    }
                    else
                    {
                        //Save the active character(this causes a database access).
                        await _Service.SetAccountActiveCharacterAsync(session.Account, selectedChar);

                        if (!selectedChar.TryGetMapping(out CharacterMapping mapping))
                        {
                            mapping = selectedChar.SpawnAndMap();
                        }

                        if (mapping.CharacterNpc.TryGetControllingClient(out Client.Client controllingClient))
                        {
                            //Character is in use by someone else.
                            success       = false;
                            failureReason = JoinGameFailedReason.CharacterInUse;
                        }
                        else
                        {
                            sender.SetControl(mapping.CharacterNpc);
                        }
                    }

                    //Send the result to the client.
                    using (var packet = _PacketWriterPool.GetScriptMessageStream(ScriptMessages.JoinGameResult))
                    {
                        packet.Write(success);
                        //Write the error code.
                        if (!success)
                        {
                            packet.Write((byte)failureReason);
                        }
                        sender.SendScriptMessage(packet, NetPriority.Medium, NetReliability.Reliable);
                    }
                }
            }
            catch (Exception e)
            {
                _Log.Error($"Something went wrong while handling a '{SupportedMessage}' script message. Disconnecting the client to get back into a defined state. Exception:  {e}");

                //Disconnect the client to get back into a defined state.
                sender.Disconnect();
            }
        }
示例#6
0
        public async void HandleMessage(Client.Client sender, PacketReader stream)
        {
            if (sender == null)
            {
                throw new ArgumentNullException(nameof(sender));
            }

            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            try
            {
                //Get the account session of the client.
                if (_AuthenticationService.TryGetSession(sender, out Session session))
                {
                    var ownedCharsTask = _CharacterService.GetAccountOwnedCharactersAsync(session.Account);
                    var activeCharTask = _CharacterService.GetAccountActiveCharacterTransactionAsync(session.Account);
                    await Task.WhenAll(ownedCharsTask, activeCharTask);

                    //Get a message writer from the pool and use it to send a message.
                    using (var writer = _WriterPool.GetScriptMessageStream(ScriptMessages.CharacterListResult))
                    {
                        //Write the id of the active character. Write -1 if no active character was found.
                        if (activeCharTask.Result is ActiveCharacterFound activeCharacterFound)
                        {
                            writer.Write(activeCharacterFound.CharacterId);
                        }
                        else
                        {
                            writer.Write((int)-1);
                        }

                        var charList = ownedCharsTask.Result;

                        //Write the length of the character list and the visuals of all characters.
                        writer.Write((byte)charList.Count);
                        foreach (var character in charList)
                        {
                            _VisualsWriter.WriteCharacter(writer, character);
                        }

                        //Send the message to the client. This message does not need to be transmitted quickly but it has to be reliable.
                        sender.SendScriptMessage(writer, NetPriority.Medium, NetReliability.Reliable);
                    }
                }
                else
                {
                    //This should not even be possible. Disconnect the client.
                    _Log.Error($"The client '{sender.SystemAddress}' tried to request a character list while not being logged in(should never be possible)");
                    sender.Disconnect();
                }
            }
            catch (Exception e)
            {
                _Log.Error($"Something went wrong while handling a script message of type '{SupportedMessage}' from client '{sender.SystemAddress}'. Exception {e}");
                //Something went wrong really bad. Disconnect the client to get back to a consistent state.
                sender.Disconnect();
            }
        }