예제 #1
0
        public void PreviewPhase2Captcha(PagePrice pp)
        {
            // TODO: 这里使用异步处理,否则出现不能显示验证码。
            // TODO: 这里可以归为一类问题:模拟时,必须等到所有操作才能显示页面。需要解决。

            logger.InfoFormat("Execute PreviewPhase2Captcha @{0}", pp.pageTime);

            phase2Manager.OfferPrice(pp.basePrice + 1500, false, (img) => {
                biddingContext.PutAwaitImage(img, null);
                Phase2PreviewCaptcha = img;

                phase2Manager.CancelOfferedPrice();
                return(true);
            });

            // CaptchaAnswerImage img = null;
            //ThreadUtils.StartNewTaskSafe(() =>
            //{
            //    img = phase2Manager.OfferPrice(pp.basePrice + 1500, false);
            //
            //});

            IsPreviewDone = true;

            //return img;
        }
        public async Task <ShowInfo> ShowGoodsPrice([FromForm] PagePrice m)
        {
            int      total = 0;
            ShowInfo slist = new ShowInfo();

            slist.plist = goodsBLL.ShowGoodsPrice(m, ref total);
            slist.count = (total / m.pageSize) + (total % m.pageSize > 0 ? 1 : 0);

            ShowInfo info = await Task.Run(() => { return(slist); });

            return(info);
        }
예제 #3
0
        private string ToShowUpText(PageTimePriceResult LastResult)
        {
            string prefix = string.Format("本机时间:{0:HH:mm:ss}。\n解析的内容是:", DateTime.Now);

            if (LastResult.status != 0)
            {
                return(string.Format("{0}ERROR: {1}", prefix, LastResult.status));
            }

            PagePrice pp = LastResult.data;

            return(string.Format("{0}{1:HH:mm:ss}.\n{2} - {3}.", prefix, pp.pageTime, pp.low, pp.high));
        }
예제 #4
0
        private void AfterSuccessDetectInner(PagePrice pp)
        {
            // 1. 11:29:15 获取验证码 用于预览
            if (!IsPreviewDone && pp.pageTime.TimeOfDay >= PreviewStartTime.TimeOfDay && pp.pageTime.TimeOfDay <= PreviewEndTime.TimeOfDay)
            {
                PreviewPhase2Captcha(pp);
                // 第一次时,也重新加载策略,防止策略被刷掉
                this.ResetStrategyByReload();
                return;
            }

            // 本地 上报 29分25秒之后的价格
            if (isLegalMinte(pp.pageTime) && pp.pageTime.Second > 15)
            {
                AsyncReportPriceShow(pp, DateTime.Now);
            }

            AfterSuccessDetect(pp);
        }
예제 #5
0
        public BiddingPriceRequest CheckPriceOffer(PagePrice pp, SubmitPriceSetting strategy, bool needCheckSecond = true)
        {
            if (needCheckSecond && pp.pageTime.Second != strategy.second)
            {
                return(null);
            }

            logger.InfoFormat("CheckPriceOffer sec#{0}, strategy is {1} ", strategy.second, strategy);

            BiddingPriceRequest req = new BiddingPriceRequest();

            req.OperateStatus      = StrategyOperateStatus.NEED_OFFER_PRICE;
            req.OfferedScreenTime  = pp.pageTime;
            req.OfferedScreenPrice = pp.basePrice;
            req.ComputedDelayMills = 0;
            req.StrategySecond     = strategy.second;
            req.TargetPrice        = strategy.deltaPrice + pp.basePrice;
            req.CaptchaUuid        = "";
            req.IsRangeTriggered   = strategy.IsRange;

            return(req);
        }
예제 #6
0
        protected override JsonCommand DoExecute(string args)
        {
            string[] arr       = args.Split(',');
            long     mills     = long.Parse(arr[0]);
            int      basePrice = int.Parse(arr[1]);

            DateTime dt = KK.ToDateTime(mills);

            var pr = new PagePrice(dt, basePrice);

            if (biddingScreen.GetBiddingContext().IsPagePriceCalced(pr))
            {
                logger.InfoFormat("price-tell price#{0} already calced", pr);
                return(null);
            }

            logger.InfoFormat("price-tell price#{0} still donot be calced, try to do calc rule.", pr);

            biddingScreen.AfterSuccessDetect(pr);

            return(null);
        }
예제 #7
0
        public List <GoodsPrice> ShowGoodsPrice(PagePrice m, ref int total)
        {
            string procName = "PagePrice";

            SqlParameter[] param = new SqlParameter[]
            {
                new SqlParameter {
                    ParameterName = "@pageIndex", DbType = DbType.Int32, Direction = ParameterDirection.Input, Value = m.pageIndex
                },
                new SqlParameter {
                    ParameterName = "@pageSize", DbType = DbType.Int32, Direction = ParameterDirection.Input, Value = m.pageSize
                },
                new SqlParameter {
                    ParameterName = "@rowCount", DbType = DbType.Int32, Direction = ParameterDirection.Output
                },
                new SqlParameter {
                    ParameterName = "@goodsId", DbType = DbType.String, Direction = ParameterDirection.Input, Value = m.goodsId
                }
            };
            DataTable tb   = dBHelper.ExecuteProc(procName, param, ref total);
            string    json = JsonConvert.SerializeObject(tb);

            return(JsonConvert.DeserializeObject <List <GoodsPrice> >(json).ToList());
        }
예제 #8
0
        public BiddingPriceRequest Calc(PagePrice pp, SubmitPriceSetting strategy)
        {
            if (pp.pageTime.Second < strategy.second)
            {
                return(null);
            }

            // 检查是否 为 区间决策 且 未执行过检查
            if (strategy.IsRange && !strategy.IsRangeChecked)
            {
                /*
                 * 参考设置为50,700-1000,1200
                 * 意思表示在时间点11:29:50判断当前的出价,
                 * 如果当前没有任何出价,或者当前的出价<最低成交价+700,或者当前的出价>最低成交价+1000,则取消当前出价,重新出该时间点的最低成交价+1200。
                 *
                 */
                var reqs = GetPreviousUnSubmitRequest(pp.pageTime.Second);
                var last = reqs != null && reqs.Count > 0 ? reqs.Last() : null;
                var currentOfferPrice = last != null ? last.TargetPrice : 0;

                strategy.IsRangeChecked = true;

                // 如果有前一个出价,且在区间内,则不操作
                if (last != null &&
                    currentOfferPrice >= pp.basePrice + strategy.RangeStartDelta &&
                    currentOfferPrice <= pp.basePrice + strategy.RangeEndDelta)
                {
                    logger.InfoFormat("strategy#{0} is matched, currentOfferPrice#{1}, base#{2}, start#{3}, end#{4}",
                                      strategy.second, currentOfferPrice, pp.basePrice, strategy.RangeStartDelta, strategy.RangeEndDelta);
                    BiddingPriceRequest reqx = new BiddingPriceRequest();
                    reqx.OperateStatus = StrategyOperateStatus.STRATEGY_RANGE_MATCHED;
                    return(reqx);
                }

                logger.InfoFormat("strategy#{0} is not matched, currentOfferPrice#{1}, base#{2}, start#{3}, end#{4}",
                                  strategy.second, currentOfferPrice, pp.basePrice, strategy.RangeStartDelta, strategy.RangeEndDelta);

                // 剩下的 区间策略 和 一般策略 无任何不同
            }

            BiddingPriceRequest req = null;

            strategySecondRequests.TryGetValue(strategy.second, out req);
            if (req == null)
            {
                req = CheckPriceOffer(pp, strategy);
                strategySecondRequests[strategy.second] = req;
            }

            if (req == null)
            {
                return(null);
            }

            if (req.OperateStatus == StrategyOperateStatus.PRICE_SUBMITTED || req.OperateStatus == StrategyOperateStatus.CANCELLED)
            {
                logger.WarnFormat("strategy#{0} status#{1} still try calc", strategy.second, req.OperateStatus);
                return(null);
            }

            // 检测 策略的出价是否符合提交规则
            if (UsePriceMatchRule(pp, req) ||
                UseBack2PriceRule(pp, req) ||
                UseBack3PriceRule(pp, req) ||
                UseFinalRule(pp, req)
                )
            {
                return(req);
            }

            return(req);
        }
예제 #9
0
 private void AsyncReportPriceShow(PagePrice pp, DateTime occurTime)
 {
     AsyncReportPrice(PriceAction.PRICE_SHOW, pp.basePrice, 0, pp.pageTime, occurTime, "show");
 }
예제 #10
0
 private void AsyncReportPriceOffered(PagePrice pp, int offeredPrice, DateTime occurTime)
 {
     AsyncReportPrice(PriceAction.PRICE_OFFER, pp.basePrice, offeredPrice, pp.pageTime, occurTime, "offer");
 }
예제 #11
0
        public void AfterSuccessDetect(PagePrice pp)
        {
            if (!isLegalMinte(pp.pageTime))
            {
                return;
            }

            // 如果该秒已经计算过
            if (!biddingContext.TryStartPagePrice(pp))
            {
                return;
            }

            long s1 = KK.CurrentMills();

            DateTime now = DateTime.Now;

            biddingContext.AddPrice(pp);

            var req = biddingPriceManager.Calcs(pp);

            if (req == null)
            {
                logger.InfoFormat("afterDetect elapsed {0}ms", KK.CurrentMills() - s1);
                return;
            }

            logger.InfoFormat("req is {0}", Jsons.ToJson(req));

            // 这里存在,正在输入价格或上传验证码时,会有来自价格同步的触发,存在并发场景
            // 所以先用了同步锁
            lock (logger)
            {
                if (req.OperateStatus == StrategyOperateStatus.NEED_OFFER_PRICE)
                {
                    // 出价前 检查 距离上次 出价时间 是否在 6秒 内
                    // 如果在6秒内,则不能出价了,因为会报 操作频繁
                    List <BiddingPriceRequest> unSubmited = biddingPriceManager.GetPreviousUnSubmitRequest(pp.pageTime.Second);
                    bool canOffer = true;
                    if (unSubmited?.Count > 0)
                    {
                        var last     = unSubmited.Last();
                        int duration = (int)(pp.pageTime - last.OfferedScreenTime).TotalSeconds;
                        if (duration < 6)
                        {
                            canOffer = false;
                        }
                        logger.InfoFormat("unSubmited between now duration is {0}, canOffer is {1}", duration, canOffer);
                    }

                    // 然后直接出价
                    if (canOffer)
                    {
                        // CaptchaAnswerImage ansImg =
                        phase2Manager.OfferPrice(req.TargetPrice, true, (ansImg) => {
                            biddingContext.PutAwaitImage(ansImg, null);
                            req.CaptchaUuid = ansImg.Uuid;
                            return(true);
                        });

                        req.OperateStatus = StrategyOperateStatus.CAPTCHA_AWAIT;

                        biddingPriceManager.CancelnOutOfDateRequest(req.StrategySecond);

                        //
                        AsyncReportPriceOffered(pp, req.TargetPrice, DateTime.Now);
                    }
                    else
                    {
                        // 不能出价时,则取消该策略 TODO: 不能依赖 canOffer 做移除
                        logger.InfoFormat("strategy#{0} canOffer is false, need remove", req.StrategySecond);
                        biddingPriceManager.RemoveStrategy(req.StrategySecond);
                    }
                }
                else if (req.OperateStatus == StrategyOperateStatus.STRATEGY_RANGE_MATCHED)
                {
                    // 命中区间策略
                    // 移除该策略
                    logger.InfoFormat("range strategy#{0} matched, need remove", pp.pageTime.Second);
                    biddingPriceManager.RemoveStrategy(pp.pageTime.Second);
                }

                if (req.CanSubmit)
                {
                    req.SubmittedScreenTime  = pp.pageTime;
                    req.SubmittedScreenPrice = pp.basePrice;
                    SubmitOfferedPrice(req);
                }
            }

            logger.InfoFormat("afterDetect elapsed {0}ms", KK.CurrentMills() - s1);
        }
예제 #12
0
        private void LoopDetectPriceAndTimeInScreen()
        {
            logger.InfoFormat("begin loopDetectPriceAndTimeInScreen");
            int i = 0;

            PageTimePriceResult lastResultx = null;

            while (isCollectingWork)
            {
                long ss = KK.CurrentMills();

                try
                {
                    long s1 = KK.CurrentMills();
                    PageTimePriceResult lastResult = actionManager.DetectPriceAndTimeInScreen(lastResultx);

                    // 重复检测
                    if (lastResult.status == 300)
                    {
                        continue;
                    }

                    SetShowUpText(ToShowUpText(lastResult));

                    // 处理异常情况
                    if (lastResult.status != 0)
                    {
                        ProcessErrorDetect(lastResult);

                        // TODO: 这里也需要处理 可能需要的提交,因为远程会下发一个可能的当前秒数
                        // 目的是防止出现卡秒现象

                        continue;
                    }

                    lastResultx = lastResult;

                    PagePrice pp = lastResult.data;

                    logger.DebugFormat("detectPriceAndTimeInScreen elapsed {0}ms", KK.CurrentMills() - s1);

                    if (pp != null)
                    {
                        if (pp.pageTime.Minute == 28)
                        {
                            if (IsOneRoundStarted)
                            {
                                ResetContext();
                                IsOneRoundStarted = false;
                            }
                        }
                        else if (pp.pageTime.Minute == 29)
                        {
                            if (!IsOneRoundStarted)
                            {
                                IsOneRoundStarted = true;
                            }
                        }

                        s1 = KK.CurrentMills();
                        AfterSuccessDetectInner(pp);
                        logger.DebugFormat("afterDetect elapsed {0}ms", KK.CurrentMills() - s1);
                    }
                    else
                    {
                        // TODO:
                    }
                }
                catch (Exception e)
                {
                    logger.Error("detect price and time error", e);
                }
                finally
                {
                    // TODO: 这里可能不需要每次重置dict
                    // actionManager.ResetDictIndex();

                    KK.Sleep(12);
                }

                logger.DebugFormat("round {0} loopDetectPriceAndTimeInScreen elapsed {1}ms", i++, KK.CurrentMills() - ss);
            }

            logger.InfoFormat("END loopDetectPriceAndTimeInScreen ");
        }
예제 #13
0
        public PageTimePriceResult DetectPriceAndTimeInScreen(PageTimePriceResult LastResult)
        {
            long   t1   = KK.CurrentMills();
            string uuid = KK.uuid();

            if (this.coordOfCurrentTime == null || coordOfCurrentTime.x <= 0 || coordOfCurrentTime.y <= 0)
            {
                return(PageTimePriceResult.ErrorCoordTime());
            }

            var p = this.coordOfCurrentTime;

            // 11:29:57
            int x1 = p.x + 20, y1 = p.y, x2 = p.x + 20 + 150, y2 = p.y + 18;

            long s1 = KK.CurrentMills();

            robot.UseDict(DictIndex.INDEX_NUMBER);
            string ret1 = robot.Ocr(x1, y1, x2, y2, "ff0000-000000", 0.8);

            // string ret1 = robot.Ocr(x1, y1, x2, y2, "0066cc-101010", 0.8);
            logger.DebugFormat("目前时间 - OCR内容 {0}, {1}, {2}, {3}. elapsed {4}ms, {5}, {6}", x1, y1, x2, y2, KK.CurrentMills() - s1, ret1, uuid);


            if (ret1 == null || ret1.Length == 0 || ret1.Length < 6)
            {
                return(PageTimePriceResult.ErrorTime());
            }

            DateTime no = DateTime.Now;

            string td = KK.ExtractDigits(ret1);

            if (td == null || td.Length != 6)
            {
                return(PageTimePriceResult.ErrorTime());
            }

            logger.DebugFormat("Parsed time is {0}.", td);

            DateTime dt = new DateTime(no.Year, no.Month, no.Day, int.Parse(td.Substring(0, 2)), int.Parse(td.Substring(2, 2)), int.Parse(td.Substring(4, 2)));

            // 检测是否已经拿到过该秒的数据,则可以忽略不检测价格了
            if (LastResult?.data != null && dt == LastResult.data.pageTime)
            {
                return(PageTimePriceResult.RepeatedTime());
            }

            // 找到坐标 of 价格区间
            if (this.coordOfPriceSection == null || coordOfPriceSection.x <= 0 || coordOfPriceSection.y <= 0)
            {
                return(PageTimePriceResult.ErrorCoordPrice());
            }

            var p2 = this.coordOfPriceSection;

            logger.DebugFormat("价格区间 - 坐标是 - {0}. {1}", p2.ToString(), KK.CurrentMills() - t1);

            // 11:29:57
            int x21 = p2.x + 20, y21 = p2.y, x22 = p2.x + 20 + 250, y22 = p2.y + 18;

            // ff0000-101010
            s1 = KK.CurrentMills();
            robot.UseDict(DictIndex.INDEX_NUMBER);
            string ret2 = robot.Ocr(x21, y21, x22, y22, "ff0000-000000", 0.8);

            if (dt.Minute > 26)
            {
                logger.InfoFormat("价格区间 - OCR内容, {0} @ {1}, elapsed {2}ms", ret2, dt, KK.CurrentMills() - s1);
            }
            else
            {
                logger.DebugFormat("价格区间 - OCR内容, {0} @ {1}, elapsed {2}ms", ret2, dt, KK.CurrentMills() - s1);
            }


            if (ret2 == null || ret2.Length == 0 || ret2.Length < 10)
            {
                return(PageTimePriceResult.ErrorPrice());
            }

            string numberStr = KK.ExtractDigits(ret2);

            if (numberStr.Length < 10)
            {
                logger.WarnFormat("识别到 错误的 价格 - {0}. 数字的位数不对.", numberStr);
                return(PageTimePriceResult.ErrorPrice());
            }

            int[] arr2      = ParsePrice(numberStr);
            int   priceLow  = arr2[0];
            int   priceHigh = arr2[1];

            if (priceHigh < 70000 || priceHigh < 70000 || priceHigh > 200000 || priceLow > 200000)
            {
                logger.WarnFormat("识别到 错误的 价格 - {0}, {1}.", priceLow, priceHigh);
                return(PageTimePriceResult.ErrorPrice());
            }

            int basePrice = (priceLow + priceHigh) / 2;

            if (dt.Minute > 25)
            {
                logger.InfoFormat("parsed price - base#{0}, low#{1}, high#{2}", basePrice, priceLow, priceHigh);
            }
            else
            {
                logger.DebugFormat("parsed price - base#{0}, low#{1}, high#{2}", basePrice, priceLow, priceHigh);
            }

            var pp = new PagePrice(dt, basePrice);

            pp.low  = priceLow;
            pp.high = priceHigh;

            return(PageTimePriceResult.Ok(pp));
        }