private static void HandleCreate(LoginSession session, PacketReader packet)
    {
        Gender    gender    = (Gender)packet.ReadByte();
        Job       job       = (Job)packet.ReadShort();
        string    name      = packet.ReadUnicodeString();
        SkinColor skinColor = packet.Read <SkinColor>();

        packet.Skip(2);

        if (DatabaseManager.Characters.NameExists(name))
        {
            session.Send(ResponseCharCreatePacket.NameTaken());
            return;
        }

        Account account      = DatabaseManager.Accounts.FindById(session.AccountId);
        Player  newCharacter = new(account, name, gender, job, skinColor);

        session.CharacterId = newCharacter.CharacterId;

        byte equipCount = packet.ReadByte();

        for (int i = 0; i < equipCount; i++)
        {
            int    id      = packet.ReadInt();
            string typeStr = packet.ReadUnicodeString();
            if (!Enum.TryParse(typeStr, out ItemSlot type))
            {
                throw new ArgumentException($"Unknown equip type: {typeStr}");
            }

            EquipColor equipColor = packet.Read <EquipColor>();

            switch (type)
            {
            case ItemSlot.HR:     // Hair
                // Hair Length/Position
                float  backLength            = packet.ReadFloat();
                CoordF backPositionCoord     = packet.Read <CoordF>();
                CoordF backPositionRotation  = packet.Read <CoordF>();
                float  frontLength           = packet.ReadFloat();
                CoordF frontPositionCoord    = packet.Read <CoordF>();
                CoordF frontPositionRotation = packet.Read <CoordF>();
                if (!DefaultItemsMetadataStorage.IsValid((int)job, id))
                {
                    continue;
                }

                newCharacter.Inventory.Cosmetics.Add(ItemSlot.HR, new(id)
                {
                    Color      = equipColor,
                    HairData   = new(backLength, frontLength, backPositionCoord, backPositionRotation, frontPositionCoord, frontPositionRotation),
                    IsTemplate = false,
                    IsEquipped = true
                });
                break;
        public void HandleCreate(LoginSession session, PacketReader packet)
        {
            byte gender = packet.ReadByte();
            //packet.ReadShort(); // const?
            // var jobCode = (Job)packet.ReadShort();
            Job       job       = (Job)packet.ReadShort();
            string    name      = packet.ReadUnicodeString();
            SkinColor skinColor = packet.Read <SkinColor>();

            //packet.ReadShort(); // const?
            packet.Skip(2);
            Dictionary <ItemSlot, Item> equips = new Dictionary <ItemSlot, Item>();

            Logger.Info($"Creating character: {name}, gender: {gender}, skinColor: {skinColor}, job: {job}");

            int equipCount = packet.ReadByte();

            for (int i = 0; i < equipCount; i++)
            {
                uint   id      = packet.ReadUInt();
                string typeStr = packet.ReadUnicodeString();
                if (!Enum.TryParse(typeStr, out ItemSlot type))
                {
                    throw new ArgumentException($"Unknown equip type: {typeStr}");
                }
                EquipColor equipColor = packet.Read <EquipColor>();
                int        colorIndex = packet.ReadInt();

                switch (type)
                {
                case ItemSlot.HR:     // Hair
                    // Hair Length/Position
                    float  backLength         = BitConverter.ToSingle(packet.Read(4), 0);
                    byte[] backPositionArray  = packet.Read(24);
                    float  frontLength        = BitConverter.ToSingle(packet.Read(4), 0);
                    byte[] frontPositionArray = packet.Read(24);

                    equips.Add(ItemSlot.HR, new Item(Convert.ToInt32(id))
                    {
                        CreationTime = 1565575851,
                        Color        = equipColor,
                        HairD        = new HairData(backLength, frontLength, backPositionArray, frontPositionArray),
                        Stats        = new ItemStats(),
                        IsTemplate   = false,
                    });
                    break;

                case ItemSlot.FA:     // Face
                    equips.Add(ItemSlot.FA, new Item(Convert.ToInt32(id))
                    {
                        CreationTime = 1565575851,
                        Color        = equipColor,
                        Stats        = new ItemStats(),
                        IsTemplate   = false,
                    });
                    break;

                case ItemSlot.FD:                            // Face Decoration
                    byte[] faceDecoration = packet.Read(16); // Face decoration position
                    equips.Add(ItemSlot.FD, new Item(Convert.ToInt32(id))
                    {
                        CreationTime    = 1565575851,
                        Color           = equipColor,
                        FaceDecorationD = faceDecoration,
                        Stats           = new ItemStats(),
                        IsTemplate      = false,
                    });
                    break;

                case ItemSlot.CL:     // Clothes
                    equips.Add(ItemSlot.CL, new Item(Convert.ToInt32(id))
                    {
                        CreationTime = 1565575851,
                        Color        = equipColor,
                        Stats        = new ItemStats(),
                        IsTemplate   = false,
                    });
                    break;

                case ItemSlot.PA:     // Pants
                    equips.Add(ItemSlot.PA, new Item(Convert.ToInt32(id))
                    {
                        CreationTime = 1565575851,
                        Color        = equipColor,
                        Stats        = new ItemStats(),
                        IsTemplate   = false,
                    });
                    break;

                case ItemSlot.SH:     // Shoes
                    equips.Add(ItemSlot.SH, new Item(Convert.ToInt32(id))
                    {
                        CreationTime = 1565575851,
                        Color        = equipColor,
                        Stats        = new ItemStats(),
                        IsTemplate   = false,
                    });
                    break;

                case ItemSlot.ER:     // Ear
                    // Assign ER
                    equips.Add(ItemSlot.ER, new Item(Convert.ToInt32(id))
                    {
                        CreationTime = 1565575851,
                        Color        = equipColor,
                        Stats        = new ItemStats(),
                        IsTemplate   = false,
                    });
                    break;
                }
                Logger.Info($" > {type} - id: {id}, color: {equipColor}, colorIndex: {colorIndex}");
            }
            packet.ReadInt(); // const? (4)

            // Check if name is in use (currently just on local account)
            bool taken = false;

            foreach (Player character in AccountStorage.Characters.Values)
            {
                if (character.Name.ToLower().Equals(name.ToLower()))
                {
                    taken = true;
                }
            }

            if (taken)
            {
                session.Send(ResponseCharCreatePacket.NameTaken());
                return;
            }

            // Create new player object
            Player newCharacter = Player.NewCharacter(gender, job, name, skinColor, equips);

            // Add player object to account storage
            AccountStorage.AddCharacter(newCharacter);

            // Send updated CHAR_MAX_COUNT
            session.Send(CharacterListPacket.SetMax(4, 6));

            // Send CHARACTER_LIST for new character only (append)
            session.Send(CharacterListPacket.AppendEntry(newCharacter));
        }
        public void HandleCreate(LoginSession session, PacketReader packet)
        {
            byte      gender    = packet.ReadByte();
            Job       job       = (Job)packet.ReadShort();
            string    name      = packet.ReadUnicodeString();
            SkinColor skinColor = packet.Read <SkinColor>();

            packet.Skip(2);
            Dictionary <ItemSlot, Item> cosmetics = new Dictionary <ItemSlot, Item>();

            Logger.Info($"Creating character: {name}, gender: {gender}, skinColor: {skinColor}, job: {job}");

            int equipCount = packet.ReadByte();

            for (int i = 0; i < equipCount; i++)
            {
                uint   id      = packet.ReadUInt();
                string typeStr = packet.ReadUnicodeString();
                if (!Enum.TryParse(typeStr, out ItemSlot type))
                {
                    throw new ArgumentException($"Unknown equip type: {typeStr}");
                }
                EquipColor equipColor = packet.Read <EquipColor>();

                switch (type)
                {
                case ItemSlot.HR:     // Hair
                    // Hair Length/Position
                    float  backLength            = BitConverter.ToSingle(packet.Read(4), 0);
                    CoordF backPositionCoord     = packet.Read <CoordF>();
                    CoordF backPositionRotation  = packet.Read <CoordF>();
                    float  frontLength           = BitConverter.ToSingle(packet.Read(4), 0);
                    CoordF frontPositionCoord    = packet.Read <CoordF>();
                    CoordF frontPositionRotation = packet.Read <CoordF>();

                    cosmetics.Add(ItemSlot.HR, new Item(Convert.ToInt32(id))
                    {
                        Color      = equipColor,
                        HairData   = new HairData(backLength, frontLength, backPositionCoord, backPositionRotation, frontPositionCoord, frontPositionRotation),
                        IsTemplate = false,
                        IsEquipped = true
                    });
                    break;

                case ItemSlot.FA:     // Face
                    cosmetics.Add(ItemSlot.FA, new Item(Convert.ToInt32(id))
                    {
                        Color      = equipColor,
                        IsTemplate = false,
                        IsEquipped = true
                    });
                    break;

                case ItemSlot.FD:                            // Face Decoration
                    byte[] faceDecoration = packet.Read(16); // Face decoration position
                    cosmetics.Add(ItemSlot.FD, new Item(Convert.ToInt32(id))
                    {
                        Color = equipColor,
                        FaceDecorationData = faceDecoration,
                        IsTemplate         = false,
                        IsEquipped         = true
                    });
                    break;

                case ItemSlot.CL:     // Clothes
                    cosmetics.Add(ItemSlot.CL, new Item(Convert.ToInt32(id))
                    {
                        Color      = equipColor,
                        IsTemplate = false,
                        IsEquipped = true
                    });
                    break;

                case ItemSlot.PA:     // Pants
                    cosmetics.Add(ItemSlot.PA, new Item(Convert.ToInt32(id))
                    {
                        Color      = equipColor,
                        IsTemplate = false,
                        IsEquipped = true
                    });
                    break;

                case ItemSlot.SH:     // Shoes
                    cosmetics.Add(ItemSlot.SH, new Item(Convert.ToInt32(id))
                    {
                        Color      = equipColor,
                        IsTemplate = false,
                        IsEquipped = true
                    });
                    break;

                case ItemSlot.ER:     // Ear
                    // Assign ER
                    cosmetics.Add(ItemSlot.ER, new Item(Convert.ToInt32(id))
                    {
                        Color      = equipColor,
                        IsTemplate = false,
                        IsEquipped = true
                    });
                    break;
                }
                Logger.Info($" > {type} - id: {id}, color: {equipColor}");
            }
            packet.ReadInt(); // const? (4)

            if (DatabaseManager.NameExists(name))
            {
                session.Send(ResponseCharCreatePacket.NameTaken());
                return;
            }

            Player newCharacter = new Player(session.AccountId, name, gender, job, skinColor);

            foreach (Item item in cosmetics.Values)
            {
                item.Owner = newCharacter;
            }
            newCharacter.Inventory.Cosmetics = cosmetics;
            DatabaseManager.UpdateCharacter(newCharacter);

            // Send updated CHAR_MAX_COUNT
            session.Send(CharacterListPacket.SetMax(4, 6));

            // Send CHARACTER_LIST for new character only (append)
            session.Send(CharacterListPacket.AppendEntry(newCharacter));
        }
        public static void HandleCreate(LoginSession session, PacketReader packet)
        {
            byte      gender    = packet.ReadByte();
            Job       job       = (Job)packet.ReadShort();
            string    name      = packet.ReadUnicodeString();
            SkinColor skinColor = packet.Read <SkinColor>();

            packet.Skip(2);

            if (DatabaseManager.Characters.NameExists(name))
            {
                session.Send(ResponseCharCreatePacket.NameTaken());
                return;
            }

            Account account      = DatabaseManager.Accounts.FindById(session.AccountId);
            Player  newCharacter = new Player(account, name, gender, job, skinColor);

            session.CharacterId = newCharacter.CharacterId;

            byte equipCount = packet.ReadByte();

            for (int i = 0; i < equipCount; i++)
            {
                int    id      = packet.ReadInt();
                string typeStr = packet.ReadUnicodeString();
                if (!Enum.TryParse(typeStr, out ItemSlot type))
                {
                    throw new ArgumentException($"Unknown equip type: {typeStr}");
                }

                EquipColor equipColor = packet.Read <EquipColor>();

                switch (type)
                {
                case ItemSlot.HR:     // Hair
                    // Hair Length/Position
                    float  backLength            = packet.ReadFloat();
                    CoordF backPositionCoord     = packet.Read <CoordF>();
                    CoordF backPositionRotation  = packet.Read <CoordF>();
                    float  frontLength           = packet.ReadFloat();
                    CoordF frontPositionCoord    = packet.Read <CoordF>();
                    CoordF frontPositionRotation = packet.Read <CoordF>();
                    if (!DefaultItemsMetadataStorage.IsValid((int)job, id))
                    {
                        continue;
                    }

                    newCharacter.Inventory.Cosmetics.Add(ItemSlot.HR, new Item(id)
                    {
                        Color      = equipColor,
                        HairData   = new HairData(backLength, frontLength, backPositionCoord, backPositionRotation, frontPositionCoord, frontPositionRotation),
                        IsTemplate = false,
                        IsEquipped = true
                    });
                    break;

                case ItemSlot.FA:     // Face
                    if (!DefaultItemsMetadataStorage.IsValid((int)job, id))
                    {
                        continue;
                    }

                    newCharacter.Inventory.Cosmetics.Add(ItemSlot.FA, new Item(id)
                    {
                        Color      = equipColor,
                        IsTemplate = false,
                        IsEquipped = true
                    });
                    break;

                case ItemSlot.FD:                            // Face Decoration
                    byte[] faceDecoration = packet.Read(16); // Face decoration position

                    if (!DefaultItemsMetadataStorage.IsValid((int)job, id))
                    {
                        continue;
                    }

                    newCharacter.Inventory.Cosmetics.Add(ItemSlot.FD, new Item(id)
                    {
                        Color = equipColor,
                        FaceDecorationData = faceDecoration,
                        IsTemplate         = false,
                        IsEquipped         = true
                    });
                    break;

                case ItemSlot.CL:     // Clothes
                    if (!DefaultItemsMetadataStorage.IsValid((int)job, id))
                    {
                        continue;
                    }

                    newCharacter.Inventory.Cosmetics.Add(ItemSlot.CL, new Item(id)
                    {
                        Color      = equipColor,
                        IsTemplate = false,
                        IsEquipped = true
                    });
                    break;

                case ItemSlot.PA:     // Pants
                    if (!DefaultItemsMetadataStorage.IsValid((int)job, id))
                    {
                        continue;
                    }

                    newCharacter.Inventory.Cosmetics.Add(ItemSlot.PA, new Item(id)
                    {
                        Color      = equipColor,
                        IsTemplate = false,
                        IsEquipped = true
                    });
                    break;

                case ItemSlot.SH:     // Shoes
                    if (!DefaultItemsMetadataStorage.IsValid((int)job, id))
                    {
                        continue;
                    }

                    newCharacter.Inventory.Cosmetics.Add(ItemSlot.SH, new Item(id)
                    {
                        Color      = equipColor,
                        IsTemplate = false,
                        IsEquipped = true
                    });
                    break;

                case ItemSlot.ER:     // Ear
                    if (!DefaultItemsMetadataStorage.IsValid((int)job, id))
                    {
                        continue;
                    }

                    newCharacter.Inventory.Cosmetics.Add(ItemSlot.ER, new Item(id)
                    {
                        Color      = equipColor,
                        IsTemplate = false,
                        IsEquipped = true
                    });
                    break;
                }
            }
            packet.ReadInt(); // const? (4)

            DatabaseManager.Inventories.Update(newCharacter.Inventory);

            // Send updated CHAR_MAX_COUNT
            session.Send(CharacterListPacket.SetMax(account.CharacterSlots));

            // Send CHARACTER_LIST for new character only (append)
            session.Send(CharacterListPacket.AppendEntry(newCharacter));
        }
Exemple #5
0
    private static void HandleCreate(LoginSession session, PacketReader packet)
    {
        Gender    gender    = (Gender)packet.ReadByte();
        Job       job       = (Job)packet.ReadShort();
        string    name      = packet.ReadUnicodeString();
        SkinColor skinColor = packet.Read <SkinColor>();

        packet.Skip(2);

        switch (name.Length)
        {
        case <= 1:
            session.Send(ResponseCharCreatePacket.Error(ResponseCharCreatePacket.CharacterCreatePacketMode.NameNeeds2LettersMinimum));
            return;

        case > 13:
            session.Send(ResponseCharCreatePacket.Error(ResponseCharCreatePacket.CharacterCreatePacketMode.MaxCharactersReached));
            return;
        }

        if (DatabaseManager.Characters.NameExists(name))
        {
            session.Send(ResponseCharCreatePacket.Error(ResponseCharCreatePacket.CharacterCreatePacketMode.NameIsTaken));
            return;
        }

        if (CharacterCreateMetadataStorage.JobIsDisabled((int)job))
        {
            session.Send(ResponseCharCreatePacket.Error(ResponseCharCreatePacket.CharacterCreatePacketMode.JobRestriction));
            return;
        }

        Account account = DatabaseManager.Accounts.FindById(session.AccountId);

        List <Item> equips     = new();
        byte        equipCount = packet.ReadByte();

        for (int i = 0; i < equipCount; i++)
        {
            int    id      = packet.ReadInt();
            string typeStr = packet.ReadUnicodeString();
            if (!Enum.TryParse(typeStr, out ItemSlot type) || !DefaultItemsMetadataStorage.IsValid((int)job, id))
            {
                session.Send(ResponseCharCreatePacket.Error(ResponseCharCreatePacket.CharacterCreatePacketMode.IncorrectGear));
                return;
            }

            EquipColor equipColor     = packet.Read <EquipColor>();
            HairData   hair           = new();
            byte[]     faceDecoration = new byte[16];

            switch (type)
            {
            case ItemSlot.HR:
                float  backLength            = packet.ReadFloat();
                CoordF backPositionCoord     = packet.Read <CoordF>();
                CoordF backPositionRotation  = packet.Read <CoordF>();
                float  frontLength           = packet.ReadFloat();
                CoordF frontPositionCoord    = packet.Read <CoordF>();
                CoordF frontPositionRotation = packet.Read <CoordF>();
                hair = new(backLength, frontLength, backPositionCoord, backPositionRotation, frontPositionCoord, frontPositionRotation);
                break;

            case ItemSlot.FD:
                faceDecoration = packet.ReadBytes(16);
                break;
            }

            equips.Add(new(id)
            {
                Color              = equipColor,
                HairData           = hair,
                FaceDecorationData = faceDecoration,
            });