public static async Task Invoke(Packet reader, Session session)
        {
            var message = reader.Header.Message;

            Tuple<MethodInfo, Type> data;

            if (MessageHandlers.TryGetValue(message, out data))
            {
                var handlerObj = Activator.CreateInstance(data.Item2) as ClientPacket;

                handlerObj.Packet = reader;

                await Task.Run(() => handlerObj.Read());

                // Fix the position after the last read.
                reader.Read(1);

                if (handlerObj.IsReadComplete)
                    data.Item1.Invoke(null, new object[] { handlerObj, session });
                else
                    Log.Error($"Packet read for '{data.Item2.Name}' failed.");
            }
            else
            {
                var msgName = Enum.GetName(typeof(ClientMessage), message) ?? Enum.GetName(typeof(GlobalClientMessage), message);

                if (msgName == null)
                    Log.Network($"Received unknown opcode '0x{message:X}, Length: {reader.Data.Length}'.");
                else
                    Log.Network($"Packet handler for '{msgName} (0x{message:X}), Length: {reader.Data.Length}' not implemented.");
            }

        }
        public static async void HandleRedirectRequest(RedirectRequest redirectRequest, Session session)
        {
            Log.Debug($"Received redirect request from 'Client: {session.GetClientInfo()}, LoginName: {redirectRequest.LoginName}'.");

            var account = DB.Auth.Single<Account>(a => a.Email == redirectRequest.LoginName);

            if (account != null && DB.Auth.Any<Framework.Database.Auth.Redirect>(r => r.AccountId == account.Id))
            {
                // Delete the redirect state from database.
                DB.Auth.Delete<Framework.Database.Auth.Redirect>(r => r.AccountId == account.Id);

                // Get the default realm.
                var realm = DB.Auth.Single<Realm>(r => r.Index == 0);

                if (realm != null)
                {
                    // Generate gateway ticket
                    var gatewayTicket = Helper.GenerateRandomKey(16);

                    account.GatewayTicket = gatewayTicket.ToHexString();

                    if (DB.Auth.Update(account))
                    {
                        await session.Send(new RedirectResponse { Result = 0 });

                        var redirect = new Server.Redirect.Redirect
                        {
                            IP            = BitConverter.ToUInt32(IPAddress.Parse(realm.IP).GetAddressBytes().Reverse().ToArray(), 0),
                            Port          = realm.Port,
                            GatewayTicket = gatewayTicket,
                            RealmName     = realm.Name
                        };

                        await session.Send(redirect);

                        Log.Debug($"'Client: {session.GetClientInfo()}' successfully redirected.");

                        return;
                    }
                }
            }

            Log.Debug($"Redirect for 'Client: {session.GetClientInfo()}' not possible.");

            // Close the connection for now.
            session.Dispose();
        }