private static void HandleSelectItem(GameSession session, PacketReader packet)
    {
        long itemUid = packet.ReadLong();

        Item item = session.Player.Inventory.GetByUid(itemUid);

        if (item is null)
        {
            return;
        }

        if (item.EnchantLevel < 15 && item.LimitBreakLevel <= 0)
        {
            session.Send(LimitBreakPacket.Notice((short)LimitBreakError.ItemCannotLimitBreak));
            return;
        }

        Script   script            = ScriptLoader.GetScript("Functions/calcLimitBreakValues");
        DynValue scriptResultCosts = script.RunFunction("calcLimitBreakCost", item.LimitBreakLevel);
        long     mesoCost          = (long)scriptResultCosts.Tuple[0].Number;

        List <EnchantIngredient> ingredients = GetIngredients(scriptResultCosts);

        Item nextLevelItem = GetNextLevelItem(item);

        session.Send(LimitBreakPacket.SelectedItem(item.Uid, nextLevelItem, mesoCost, ingredients));
    }
    private static void HandleLimitBreakItem(GameSession session, PacketReader packet)
    {
        long itemUid = packet.ReadLong();
        Item item    = session.Player.Inventory.GetByUid(itemUid);

        if (item is null)
        {
            return;
        }

        if (item.EnchantLevel < 15 && item.LimitBreakLevel <= 0)
        {
            session.Send(LimitBreakPacket.Notice((short)LimitBreakError.ItemCannotLimitBreak));
            return;
        }
        Script   script            = ScriptLoader.GetScript("Functions/calcLimitBreakValues");
        DynValue scriptResultCosts = script.RunFunction("calcLimitBreakCost", item.LimitBreakLevel);

        if (!session.Player.Wallet.Meso.Modify((long)-scriptResultCosts.Tuple[0].Number))
        {
            session.Send(LimitBreakPacket.Notice((short)LimitBreakError.InsufficientMesos));
            return;
        }

        List <EnchantIngredient> ingredients = GetIngredients(scriptResultCosts);

        if (!PlayerHasIngredients(ingredients, session.Player.Inventory))
        {
            session.Send(LimitBreakPacket.Notice((short)LimitBreakError.InsufficientIngredients));
            return;
        }

        foreach (EnchantIngredient ingredient in ingredients)
        {
            session.Player.Inventory.ConsumeByTag(session, ingredient.Tag.ToString(), ingredient.Amount);
        }

        Item nextLevelItem = GetNextLevelItem(item);

        item.LimitBreakLevel = nextLevelItem.LimitBreakLevel;
        item.EnchantLevel    = nextLevelItem.EnchantLevel;
        item.Stats           = nextLevelItem.Stats;
        session.Send(LimitBreakPacket.LimitBreakItem(item));
    }