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 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));
        }
Esempio n. 3
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,
            });