// Client -> Us -> Server (Incoming)
        private void PacketModifierOnParsedIncomingPacket(object sender, PacketParsedEventArgs e)
        {
            switch (e.PacketModifier)
            {
            case ReleaseVersionModifier modifier:
            {
                if (ReleaseVersionReceived)
                {
                    throw new ApplicationException("HotelType was already sent by client.");
                }

                ReleaseVersionReceived = true;

                if (Enum.TryParse <HotelType>(modifier.HotelType, true, out var hotelType))
                {
                    var hotel = HotelManager.GetHotel(hotelType);
                    if (hotel != null)
                    {
                        // Open connection with the target server.
                        StartServerConnection(hotel);

                        // Apply the target release to this modifier.
                        // All future modifiers will automatically get this modifier as well.
                        modifier.ReleaseTarget = hotel.Release;
                        break;
                    }
                }

                throw new ApplicationException("HotelType was not sent properly by client.");
            }

            case SwfDataModifier modifier:
            {
                modifier.FlashClientUrl    = Config.FlashClientUrl;
                modifier.ExternalVariables = Config.ExternalVariables;
                break;
            }

            // Client sends his public key to the server.
            case GenerateSecretKeyModifier modifier:
            {
                var sharedKeyClient = Client.Encryption.Diffie.GetSharedKey(modifier.PublicKey);

                Client.Encryption.ServerRC4 = new HabboRC4(sharedKeyClient);
                Client.Encryption.ClientRC4 = new HabboRC4(sharedKeyClient);

                modifier.PublicKey = Server.Encryption.Diffie.GetPublicKey();
                break;
            }
            }
        }
        // Server -> Us -> Client (Outgoing)
        private void PacketModifierOnParsedOutgoingPacket(object sender, PacketParsedEventArgs e)
        {
            switch (e.PacketModifier)
            {
            // Server sends prime (p) and generator (g) to the client.
            case Modifiers.OutgoingMod.Handshake.InitCryptoModifier modifier:
            {
                Server.Encryption.Diffie.DoHandshake(modifier.SignedPrime, modifier.SignedGenerator);

                modifier.SignedPrime     = Client.Encryption.Diffie.GetSignedPrime();
                modifier.SignedGenerator = Client.Encryption.Diffie.GetSignedGenerator();
                break;
            }

            // Server sends his public key to the client.
            case Modifiers.OutgoingMod.Handshake.SecretKeyModifier modifier:
            {
                var sharedKeyServer = Server.Encryption.Diffie.GetSharedKey(modifier.PublicKey);

                Server.Encryption.ServerRC4 = new HabboRC4(sharedKeyServer);
                Server.Encryption.ClientRC4 = new HabboRC4(sharedKeyServer);

                if (!modifier.EnableClientEncryption)
                {
                    Client.Encryption.ClientRC4 = null;     // We will not send encrypted packets to the habbo client.
                    Server.Encryption.ServerRC4 = null;     // The habbo server won't send us encrypted packets.
                }

                modifier.PublicKey = Client.Encryption.Diffie.GetPublicKey();
                break;
            }

            case UserFlatCatsModifier modifier:
            {
                Session.Navigator.UserFlatCatMapping.Clear();

                foreach (var category in modifier.Categories)
                {
                    Session.Navigator.UserFlatCatMapping.Add(category.Id, category.NodeName);
                }
                break;
            }
            }
        }