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); }
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)); }
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); }
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); }
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); }
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()); }
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); }
private void AsyncReportPriceShow(PagePrice pp, DateTime occurTime) { AsyncReportPrice(PriceAction.PRICE_SHOW, pp.basePrice, 0, pp.pageTime, occurTime, "show"); }
private void AsyncReportPriceOffered(PagePrice pp, int offeredPrice, DateTime occurTime) { AsyncReportPrice(PriceAction.PRICE_OFFER, pp.basePrice, offeredPrice, pp.pageTime, occurTime, "offer"); }
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); }
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 "); }
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)); }