private void ProcessSelectCharacter(ClientConnection client, SubPacket packet)
        {
            SelectCharacterPacket selectCharRequest = new SelectCharacterPacket(packet.data);

            Program.Log.Info("{0} => Select character id {1}", client.currentUserId == 0 ? client.GetAddress() : "User " + client.currentUserId, selectCharRequest.characterId);

            Character chara = Database.GetCharacter(client.currentUserId, selectCharRequest.characterId);
            World     world = null;

            if (chara != null)
            {
                world = Database.GetServer(chara.serverId);
            }

            if (world == null)
            {
                ErrorPacket errorPacket = new ErrorPacket(selectCharRequest.sequence, 0, 0, 13001, "World Does not exist or is inactive.");
                SubPacket   subpacket   = errorPacket.BuildPacket();
                BasePacket  basePacket  = BasePacket.CreatePacket(subpacket, true, false);
                BasePacket.EncryptPacket(client.blowfish, basePacket);
                client.QueuePacket(basePacket);
                return;
            }

            SelectCharacterConfirmPacket connectCharacter = new SelectCharacterConfirmPacket(selectCharRequest.sequence, selectCharRequest.characterId, client.currentSessionToken, world.address, world.port, selectCharRequest.ticket);

            BasePacket outgoingPacket = BasePacket.CreatePacket(connectCharacter.BuildPackets(), true, false);

            BasePacket.EncryptPacket(client.blowfish, outgoingPacket);
            client.QueuePacket(outgoingPacket);
        }
        private void SendRetainerList(ClientConnection client, SubPacket packet)
        {
            List <Retainer> retainers = Database.GetRetainers(client.currentUserId);

            RetainerListPacket retainerListPacket = new RetainerListPacket(0, retainers);
            List <SubPacket>   subPackets         = retainerListPacket.BuildPackets();
            BasePacket         basePacket         = BasePacket.CreatePacket(subPackets, true, false);

            BasePacket.EncryptPacket(client.blowfish, basePacket);
            client.QueuePacket(basePacket);
        }
        private void SendImportList(ClientConnection client, SubPacket packet)
        {
            List <String> names = Database.GetReservedNames(client.currentUserId);

            ImportListPacket importListPacket = new ImportListPacket(0, names);
            List <SubPacket> subPackets       = importListPacket.BuildPackets();
            BasePacket       basePacket       = BasePacket.CreatePacket(subPackets, true, false);

            BasePacket.EncryptPacket(client.blowfish, basePacket);
            client.QueuePacket(basePacket);
        }
        private void SendWorldList(ClientConnection client, SubPacket packet)
        {
            List <World>     serverList      = Database.GetServers();
            WorldListPacket  worldlistPacket = new WorldListPacket(0, serverList);
            List <SubPacket> subPackets      = worldlistPacket.BuildPackets();

            BasePacket basePacket = BasePacket.CreatePacket(subPackets, true, false);

            BasePacket.EncryptPacket(client.blowfish, basePacket);
            client.QueuePacket(basePacket);
        }
        private void ProcessStartSession(ClientConnection client, BasePacket packet)
        {
            SecurityHandshakePacket securityHandshake = new SecurityHandshakePacket(packet.data);

            byte[] blowfishKey = GenerateKey(securityHandshake.ticketPhrase, securityHandshake.clientNumber);
            client.blowfish = new Blowfish(blowfishKey);

            Program.Log.Info("SecCNum: 0x{0:X}", securityHandshake.clientNumber);

            //Respond with acknowledgment
            BasePacket outgoingPacket = new BasePacket(HardCoded_Packets.g_secureConnectionAcknowledgment);

            BasePacket.EncryptPacket(client.blowfish, outgoingPacket);
            client.QueuePacket(outgoingPacket);
        }
        private void SendCharacterList(ClientConnection client, SubPacket packet)
        {
            List <Character> characterList = Database.GetCharacters(client.currentUserId);

            if (characterList.Count > 8)
            {
                Program.Log.Error("Warning, got more than 8 characters. List truncated, check DB for issues.");
            }

            CharacterListPacket characterlistPacket = new CharacterListPacket(0, characterList);
            List <SubPacket>    subPackets          = characterlistPacket.BuildPackets();
            BasePacket          basePacket          = BasePacket.CreatePacket(subPackets, true, false);

            BasePacket.EncryptPacket(client.blowfish, basePacket);
            client.QueuePacket(basePacket);
        }
        private void ProcessSessionAcknowledgement(ClientConnection client, SubPacket packet)
        {
            packet.DebugPrintSubPacket();
            SessionPacket sessionPacket = new SessionPacket(packet.data);
            String        clientVersion = sessionPacket.version;

            Program.Log.Info("Got acknowledgment for secure session.");
            Program.Log.Info("CLIENT VERSION: {0}", clientVersion);

            uint userId = Database.GetUserIdFromSession(sessionPacket.session);

            client.currentUserId       = userId;
            client.currentSessionToken = sessionPacket.session;;

            if (userId == 0)
            {
                ErrorPacket errorPacket = new ErrorPacket(sessionPacket.sequence, 0, 0, 13001, "Your session has expired, please login again.");
                SubPacket   subpacket   = errorPacket.BuildPacket();
                subpacket.SetTargetId(0xe0006868);
                BasePacket errorBasePacket = BasePacket.CreatePacket(subpacket, true, false);
                BasePacket.EncryptPacket(client.blowfish, errorBasePacket);
                client.QueuePacket(errorBasePacket);

                Program.Log.Info("Invalid session, kicking...");
                return;
            }

            Program.Log.Info("USER ID: {0}", userId);

            List <Account> accountList    = new List <Account>();
            Account        defaultAccount = new Account();

            defaultAccount.id   = 1;
            defaultAccount.name = "FINAL FANTASY XIV";
            accountList.Add(defaultAccount);
            AccountListPacket listPacket = new AccountListPacket(1, accountList);
            BasePacket        basePacket = BasePacket.CreatePacket(listPacket.BuildPackets(), true, false);

            BasePacket.EncryptPacket(client.blowfish, basePacket);
            client.QueuePacket(basePacket);
        }
        private void ProcessModifyCharacter(ClientConnection client, SubPacket packet)
        {
            CharacterModifyPacket charaReq = new CharacterModifyPacket(packet.data);
            var slot    = charaReq.slot;
            var name    = charaReq.characterName;
            var worldId = charaReq.worldId;

            uint pid = 0, cid = 0;

            //Get world from new char instance
            if (worldId == 0)
            {
                worldId = client.newCharaWorldId;
            }

            //Check if this character exists, Get world from there
            if (worldId == 0 && charaReq.characterId != 0)
            {
                Character chara = Database.GetCharacter(client.currentUserId, charaReq.characterId);
                if (chara != null)
                {
                    worldId = chara.serverId;
                }
            }

            string worldName = null;
            World  world     = Database.GetServer(worldId);

            if (world != null)
            {
                worldName = world.name;
            }

            if (worldName == null)
            {
                ErrorPacket errorPacket = new ErrorPacket(charaReq.sequence, 0, 0, 13001, "World Does not exist or is inactive.");
                SubPacket   subpacket   = errorPacket.BuildPacket();
                BasePacket  basePacket  = BasePacket.CreatePacket(subpacket, true, false);
                BasePacket.EncryptPacket(client.blowfish, basePacket);
                client.QueuePacket(basePacket);

                Program.Log.Info("User {0} => Error; invalid server id: \"{1}\"", client.currentUserId, worldId);
                return;
            }

            bool alreadyTaken;

            switch (charaReq.command)
            {
            case 0x01:    //Reserve

                alreadyTaken = Database.ReserveCharacter(client.currentUserId, slot, worldId, name, out pid, out cid);

                if (alreadyTaken)
                {
                    ErrorPacket errorPacket = new ErrorPacket(charaReq.sequence, 1003, 0, 13005, "");     //BDB - Chara Name Used, //1003 - Bad Word
                    SubPacket   subpacket   = errorPacket.BuildPacket();
                    BasePacket  basePacket  = BasePacket.CreatePacket(subpacket, true, false);
                    BasePacket.EncryptPacket(client.blowfish, basePacket);
                    client.QueuePacket(basePacket);

                    Program.Log.Info("User {0} => Error; name taken: \"{1}\"", client.currentUserId, charaReq.characterName);
                    return;
                }
                else
                {
                    pid = 0;
                    client.newCharaCid     = cid;
                    client.newCharaSlot    = slot;
                    client.newCharaWorldId = worldId;
                    client.newCharaName    = name;
                }

                Program.Log.Info("User {0} => Character reserved \"{1}\"", client.currentUserId, name);
                break;

            case 0x02:    //Make
                CharaInfo info = CharaInfo.GetFromNewCharRequest(charaReq.characterInfoEncoded);

                //Set Initial Appearance (items will be loaded in by map server)
                uint[] classAppearance = CharacterCreatorUtils.GetEquipmentForClass(info.currentClass);
                info.weapon1 = classAppearance[0];
                info.weapon2 = classAppearance[1];
                info.head    = classAppearance[7];

                if (classAppearance[8] != 0)
                {
                    info.body = classAppearance[8];
                }
                else
                {
                    info.body = CharacterCreatorUtils.GetUndershirtForTribe(info.tribe);
                }

                info.legs  = classAppearance[9];
                info.hands = classAppearance[10];
                info.feet  = classAppearance[11];
                info.belt  = classAppearance[12];

                //Set Initial Position
                switch (info.initialTown)
                {
                case 1:         //ocn0Battle02 (Limsa)
                    info.zoneId = 193;
                    info.x      = 0.016f;
                    info.y      = 10.35f;
                    info.z      = -36.91f;
                    info.rot    = 0.025f;
                    break;

                case 2:         //fst0Battle03 (Gridania)
                    info.zoneId = 166;
                    info.x      = 369.5434f;
                    info.y      = 4.21f;
                    info.z      = -706.1074f;
                    info.rot    = -1.26721f;
                    break;

                case 3:         //wil0Battle01 (Ul'dah)
                    info.zoneId = 184;
                    info.x      = 5.364327f;
                    info.y      = 196.0f;
                    info.z      = 133.6561f;
                    info.rot    = -2.849384f;
                    break;
                }

                Database.MakeCharacter(client.currentUserId, client.newCharaCid, info);

                pid  = 1;
                cid  = client.newCharaCid;
                name = client.newCharaName;

                Program.Log.Info("User {0} => Character Created \"{1}\"", client.currentUserId, name);
                break;

            case 0x03:    //Rename

                alreadyTaken = Database.RenameCharacter(client.currentUserId, charaReq.characterId, worldId, charaReq.characterName);

                if (alreadyTaken)
                {
                    ErrorPacket errorPacket = new ErrorPacket(charaReq.sequence, 1003, 0, 13005, "");     //BDB - Chara Name Used, //1003 - Bad Word
                    SubPacket   subpacket   = errorPacket.BuildPacket();
                    BasePacket  basePacket  = BasePacket.CreatePacket(subpacket, true, false);
                    BasePacket.EncryptPacket(client.blowfish, basePacket);
                    client.QueuePacket(basePacket);

                    Program.Log.Info("User {0} => Error; name taken: \"{1}\"", client.currentUserId, charaReq.characterName);
                    return;
                }

                Program.Log.Info("User {0} => Character renamed \"{1}\"", client.currentUserId, name);
                break;

            case 0x04:    //Delete
                Database.DeleteCharacter(charaReq.characterId, charaReq.characterName);

                Program.Log.Info("User {0} => Character deleted \"{1}\"", client.currentUserId, name);
                break;

            case 0x06:    //Rename Retainer

                Program.Log.Info("User {0} => Retainer renamed \"{1}\"", client.currentUserId, name);
                break;
            }

            CharaCreatorPacket charaCreator       = new CharaCreatorPacket(charaReq.sequence, charaReq.command, pid, cid, 1, name, worldName);
            BasePacket         charaCreatorPacket = BasePacket.CreatePacket(charaCreator.BuildPacket(), true, false);

            BasePacket.EncryptPacket(client.blowfish, charaCreatorPacket);
            client.QueuePacket(charaCreatorPacket);
        }