Example #1
0
 protected virtual void FreeResources(ICheckoutTaskContext context, CheckoutTask task)
 {
     task.ProxyPool.Release(task.Proxy);
     task.Proxy = null;
     context?.Dispose();
     TierControl.Release();
 }
Example #2
0
        private StepResult WaitQuota(ICheckoutTaskContext context, CheckoutTask task, CancellationToken cancelToken)
        {
            StepResult res = StepResult.Ok;

            bool isQuotaAvailable = task.Profile.Wait(cancelToken);

            if (!isQuotaAvailable)
            {
                res = StepResult.Failed;
            }

            return(res);
        }
Example #3
0
        public StepResult Run(ICheckoutTaskContext context, CheckoutTask task, TimeSpan delayBetweenRetires, out TimeSpan executionTime, CancellationToken cancelToken)
        {
            StepResult res       = StepResult.Error;
            Stopwatch  stopWatch = new Stopwatch();

            task.State = State != CheckoutTaskState.Undefined ? State : task.State;
            Logger.LogEvent(task.Log, $"TASK {task.Id}", $"{Name}...");

            while (res == StepResult.Error)
            {
                stopWatch.Reset();
                stopWatch.Start();

                try
                {
                    res = m_action(context, task, cancelToken);
                }
                catch (Exception e)
                {
                    Logger.LogEvent(task.Log, $"TASK {task.Id}", $"Exception has occurred.");

                    NotificationService.SendStatistic($"Excetpion: {e.ToString()}\nStack Trace:{e.StackTrace}",
                                                      "ERROR");

                    res = StepResult.Failed;
                }

                stopWatch.Stop();

                if (res == StepResult.Error)
                {
                    Logger.LogEvent(task.Log, $"TASK {task.Id}", $"{Name} got error... retry");

                    if (cancelToken.WaitHandle.WaitOne(delayBetweenRetires))
                    {
                        res = StepResult.Canceled;
                        break;
                    }
                }
            }

            executionTime = stopWatch.Elapsed;

            if (res == StepResult.Ok)
            {
                Logger.LogEvent(task.Log, $"TASK {task.Id}", $"{Name}... done ({(int)executionTime.TotalMilliseconds} ms)");
            }

            return(res);
        }
Example #4
0
        private void CheckoutTaskFinishedHandler(object sender, EventArgs args)
        {
            CheckoutTask task = sender as CheckoutTask;

            task.Finished -= CheckoutTaskFinishedHandler;

            lock (m_lock)
            {
                m_tasks.Remove(task);

                if (m_tasks.Count == 0)
                {
                    m_finishedEvent.Set();
                }
            }
        }
Example #5
0
        private bool IsCanceled(CancellationToken cancelToken, CheckoutTask task, ICheckoutTaskContext context = null, bool isTierAcquired = true)
        {
            bool ret = false;

            if (cancelToken.IsCancellationRequested)
            {
                task.State = CheckoutTaskState.Canceled;
                context?.Dispose();
                if (isTierAcquired)
                {
                    TierControl.Release();
                }
                Logger.LogEvent(task.Log, $"TASK {task.Id}", "Task is canceled!");
                ret = true;
            }

            return(ret);
        }
Example #6
0
        private StepResult WaitProxy(ICheckoutTaskContext context, CheckoutTask task, CancellationToken cancelToken)
        {
            StepResult res = StepResult.Ok;

            task.Proxy = task.ProxyPool.WaitOne(cancelToken);

            if (task.Proxy == null)
            {
                if (cancelToken.IsCancellationRequested)
                {
                    res = StepResult.Canceled;
                }
                else
                {
                    res = StepResult.Failed;
                }
            }

            return(res);
        }
Example #7
0
        protected override StepResult Billing(ICheckoutTaskContext context, CheckoutTask task, CancellationToken cancelToken)
        {
            StepResult res = StepResult.Ok;
            SupremeUSABotTaskContext cxt = context as SupremeUSABotTaskContext;

            string         html       = null;
            HttpStatusCode?statusCode = null;

            cxt.ResetCheckoutInfo();

            using (HttpRequestMessage checkoutPageRequest = new HttpRequestMessage()
            {
                RequestUri = new Uri($"https://{task.Footsite.Domain}{m_checkoutPagePath}"),
                Method = HttpMethod.Get
            })
            {
                checkoutPageRequest.Headers.TryAddWithoutValidation("User-Agent", BrowserAgent);
                checkoutPageRequest.Headers.TryAddWithoutValidation("Accept", "*/*");
                checkoutPageRequest.Headers.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate");

                html = HttpHelper.GetStringSync(checkoutPageRequest, cxt.Client, out statusCode, cancelToken);
            }

            if (cancelToken.IsCancellationRequested)
            {
                return(StepResult.Canceled);
            }
            if ((res = CheckResult(html, statusCode)) != StepResult.Ok)
            {
                return(res);
            }

            cxt.CheckoutTimestamp = TimeHelper.GetUnixTimeStamp();

            HtmlDocument doc = new HtmlDocument();

            doc.LoadHtml(html);

            HtmlNode checkoutFormNode = doc.GetElementbyId("checkout_form");

            if (checkoutFormNode != null)
            {
                HtmlNode creditCardDetailsNode = doc.GetElementbyId("card_details");

                if (creditCardDetailsNode != null)
                {
                    try
                    {
                        HtmlNodeCollection divs = creditCardDetailsNode.SelectNodes("div");

                        cxt.CreditCardNumberFieldName = divs[0]
                                                        .SelectSingleNode("input")
                                                        .GetAttributeValue("name", cxt.CreditCardNumberFieldName);
                        cxt.CreditCardMonthFieldName = divs[1].SelectNodes("select")[0]
                                                       .GetAttributeValue("name", cxt.CreditCardMonthFieldName);
                        cxt.CreditCardYearFieldName = divs[1].SelectNodes("select")[1]
                                                      .GetAttributeValue("name", cxt.CreditCardYearFieldName);
                        cxt.CreditCardCVVFieldName = divs[2]
                                                     .SelectSingleNode("input")
                                                     .GetAttributeValue("name", cxt.CreditCardCVVFieldName);

                        cxt.CsrfToken = doc.DocumentNode.SelectSingleNode("//meta[@name='csrf-token']")
                                        .GetAttributeValue("content", "");
                        //cxt.StoreId = checkoutFormNode.SelectSingleNode("//input[@name='store_credit_id']")
                        //    .GetAttributeValue("value", "");
                        cxt.Utf8Symbol = checkoutFormNode.SelectSingleNode("//input[@name='utf8']")
                                         .GetAttributeValue("value", "");
                        cxt.AuthenticityToken = checkoutFormNode.SelectSingleNode("//input[@name='authenticity_token']")
                                                .GetAttributeValue("value", "");
                    }
                    catch (Exception ex)
                    {
                        Logger.LogEvent(task.Log, $"TASK {task.Id}", $"Could not parse credit card form. Default field names will be used.");
                    }
                }
                else
                {
                    Logger.LogEvent(task.Log, $"TASK {task.Id}", $"Could not find credit card form. Default field names will be used.");
                }

                try
                {
                    HtmlNode extraFieldNode = doc.GetElementbyId("cart-cc").SelectSingleNode("fieldset").SelectNodes("input").Last();

                    cxt.ExtraField = new KeyValuePair <string, string>(extraFieldNode.GetAttributeValue("name", ""), extraFieldNode.GetAttributeValue("value", ""));
                }
                catch (Exception e)
                {
                }
            }
            else
            {
                Logger.LogEvent(task.Log, $"TASK {task.Id}", "Could not get checkout form. Contact with support.");

                res = StepResult.Failed;
            }

            return(res);
        }
Example #8
0
        protected override StepResult Paying(ICheckoutTaskContext context, CheckoutTask task, CancellationToken cancelToken)
        {
            StepResult res = StepResult.Ok;
            SupremeUSABotTaskContext cxt = context as SupremeUSABotTaskContext;

            string         html       = null;
            HttpStatusCode?statusCode = null;

            int timeElapsed = TimeHelper.GetUnixTimeStamp() - cxt.CheckoutTimestamp;

            if (timeElapsed * 1000 < task.Footsite.Settings.DelayInCheckout)
            {
                Logger.LogEvent(task.Log, $"TASK {task.Id}",
                                $"Delay in checkout {task.Footsite.Settings.DelayInCheckout - timeElapsed * 1000} ms");

                cancelToken.WaitHandle.WaitOne(TimeSpan.FromMilliseconds(task.Footsite.Settings.DelayInCheckout - timeElapsed * 1000));
                if (cancelToken.IsCancellationRequested)
                {
                    return(StepResult.Canceled);
                }
            }

            task.State = CheckoutTaskState.WaitingCaptcha;
            Logger.LogEvent(task.Log, $"TASK {task.Id}", $"Waiting captcha...");

            string token = null;

            while (true)
            {
                ICaptchaHarvesterTask harvesterTask = new CaptchaHarvesterTaskBase(null);

                Release.CaptchaHarvester.GetSolution(harvesterTask);

                WaitHandle.WaitAny(new[] { harvesterTask.SolutionReadyEvent, cancelToken.WaitHandle });

                if (cancelToken.IsCancellationRequested)
                {
                    return(StepResult.Canceled);
                }

                RecaptchaSolution solution = harvesterTask.Solution as RecaptchaSolution;

                if (solution.TimeStamp > cxt.CheckoutTimestamp)
                {
                    token = solution.Value;

                    break;
                }

                harvesterTask.SolutionReadyEvent.Dispose();
            }

            Logger.LogEvent(task.Log, $"TASK {task.Id}", $"Waiting captcha... done");

            task.State = CheckoutTaskState.Paying;

            using (HttpRequestMessage tohruCommitMessage = new HttpRequestMessage()
            {
                RequestUri = new Uri(m_tohruCommitPath),
                Method = HttpMethod.Post
            })
            {
                tohruCommitMessage.Headers.TryAddWithoutValidation("User-Agent", BrowserAgent);
                tohruCommitMessage.Headers.TryAddWithoutValidation("Accept", "*/*");
                tohruCommitMessage.Headers.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate");
                tohruCommitMessage.Headers.TryAddWithoutValidation("Content-Type", "application/octet-stream");
                tohruCommitMessage.Headers.TryAddWithoutValidation("Refer", "https://www.supremenewyork.com/checkout");
                tohruCommitMessage.Content = new StringContent(m_tohruTrackInfo);

                HttpHelper.GetStringSync(tohruCommitMessage, cxt.Client, out statusCode, cancelToken);
            }

            string billPhoneNumber = task.Profile.ReleaseCheckoutProfile.CheckoutProfile.BillingAddress.PhoneNumber.Insert(3, "-").Insert(7, "-");

            using (HttpRequestMessage checkoutRequest = new HttpRequestMessage()
            {
                RequestUri = new Uri($"https://{task.Footsite.Domain}{m_checkoutPath}"),
                Method = HttpMethod.Post
            })
            {
                checkoutRequest.Headers.TryAddWithoutValidation("User-Agent", BrowserAgent);
                checkoutRequest.Headers.TryAddWithoutValidation("Accept", "*/*");
                checkoutRequest.Headers.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate");
                checkoutRequest.Headers.TryAddWithoutValidation("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
                checkoutRequest.Headers.TryAddWithoutValidation("Refer", "https://www.supremenewyork.com/checkout");
                checkoutRequest.Headers.TryAddWithoutValidation("X-Requested-With", "XMLHttpRequest");
                checkoutRequest.Headers.TryAddWithoutValidation("Accept-Language", "en-US,en;q=0.8,en-GB;q=0.6");
                checkoutRequest.Headers.Add("X-CSRF-Token", cxt.CsrfToken);
                checkoutRequest.Content = new FormUrlEncodedContent(new KeyValuePair <string, string>[]
                {
                    new KeyValuePair <string, string>("store_credit_id", cxt.StoreId),
                    new KeyValuePair <string, string>("same_as_billing_address", "1"),
                    new KeyValuePair <string, string>("credit_card[last_name]", task.Profile.ReleaseCheckoutProfile.CheckoutProfile.BillingAddress.SecondName),
                    new KeyValuePair <string, string>("credit_card[first_name]", task.Profile.ReleaseCheckoutProfile.CheckoutProfile.BillingAddress.FirstName),
                    new KeyValuePair <string, string>("order[email]", task.Profile.ReleaseCheckoutProfile.CheckoutProfile.Email),
                    new KeyValuePair <string, string>("order[tel]", billPhoneNumber),
                    new KeyValuePair <string, string>("order[billing_address]", $"{task.Profile.ReleaseCheckoutProfile.CheckoutProfile.BillingAddress.StreetAddress1}, {task.Profile.ReleaseCheckoutProfile.CheckoutProfile.BillingAddress.StreetAddressLine2}"),
                    new KeyValuePair <string, string>("order[billing_city]", task.Profile.ReleaseCheckoutProfile.CheckoutProfile.BillingAddress.City),
                    new KeyValuePair <string, string>("order[billing_state]", task.Profile.ReleaseCheckoutProfile.CheckoutProfile.BillingAddress.State?.Abbreviation),
                    new KeyValuePair <string, string>("order[billing_zip]", task.Profile.ReleaseCheckoutProfile.CheckoutProfile.BillingAddress.PostalCode),
                    new KeyValuePair <string, string>("order[billing_country]", ConvertCommonCountryNameToSupremeName(task.Profile.ReleaseCheckoutProfile.CheckoutProfile.BillingAddress.Country.Code)),
                    new KeyValuePair <string, string>("credit_card[type]", ConvertCommonCreditCardTypeToSupremeType(task.Profile.ReleaseCheckoutProfile.CheckoutProfile.PayCard.Type.Code) ?? ""),
                    new KeyValuePair <string, string>(cxt.CreditCardNumberFieldName, task.Profile.ReleaseCheckoutProfile.CheckoutProfile.PayCard.Number),
                    new KeyValuePair <string, string>(cxt.CreditCardMonthFieldName, task.Profile.ReleaseCheckoutProfile.CheckoutProfile.PayCard.ExpirationDate.Value.ToString("MM")),
                    new KeyValuePair <string, string>(cxt.CreditCardYearFieldName, task.Profile.ReleaseCheckoutProfile.CheckoutProfile.PayCard.ExpirationDate.Value.ToString("yyyy")),
                    new KeyValuePair <string, string>(cxt.CreditCardCVVFieldName, task.Profile.ReleaseCheckoutProfile.CheckoutProfile.PayCard.CVS),
                    new KeyValuePair <string, string>("order[terms]", "0"),
                    new KeyValuePair <string, string>("order[terms]", "1"),
                    new KeyValuePair <string, string>("g-recaptcha-response", token),
                    new KeyValuePair <string, string>("utf8", cxt.Utf8Symbol),
                    new KeyValuePair <string, string>("authenticity_token", cxt.AuthenticityToken),

                    cxt.ExtraField
                });

                html = HttpHelper.GetStringSync(checkoutRequest, cxt.Client, out statusCode, cancelToken);
            }

            if (cancelToken.IsCancellationRequested)
            {
                return(StepResult.Canceled);
            }
            if ((res = CheckResult(html, statusCode)) != StepResult.Ok)
            {
                return(res);
            }

            JObject checkoutReponseJObject = null;
            string  checkoutStatus         = null;
            string  slug = null;

            try
            {
                checkoutReponseJObject = JObject.Parse(html);
                checkoutStatus         = checkoutReponseJObject["status"].Value <string>();
            }
            catch (Exception e)
            {
                Logger.LogEvent(task.Log, $"TASK {task.Id}", "Could not get checkout response. Contact with support.");
            }

            if (checkoutStatus != null)
            {
                if (checkoutStatus == "queued")
                {
                    try
                    {
                        slug = checkoutReponseJObject["slug"].Value <string>();
                    }
                    catch (Exception e)
                    {
                        Logger.LogEvent(task.Log, $"TASK {task.Id}", "Could not get queue id. Contact with support.");
                    }

                    if (slug != null)
                    {
                        cxt.Slug = slug;

                        CheckoutStep queuedCheckout = new CheckoutStep(QueuedCheckout, "Waiting in Queue", CheckoutTaskState.Undefined);
                        CheckoutStep retryCheckout  = new CheckoutStep(RetryCheckout, "Checking paying status", CheckoutTaskState.Undefined);
                        TimeSpan     executionTime;

                        res = queuedCheckout.Run(cxt, task, TimeSpan.FromMilliseconds(task.Footsite.Settings.RetryPeriod), out executionTime, cancelToken);

                        if (res == StepResult.Ok)
                        {
                            checkoutStatus = cxt.QueuedCheckoutResponse["status"].Value <string>();

                            int attempts = 1;

                            while (attempts < 5 && res != StepResult.Canceled && checkoutStatus == "failed")
                            {
                                Logger.LogEvent(task.Log, $"TASK {task.Id}", $"Attempt {attempts} is failed... retry");
                                attempts++;

                                cancelToken.WaitHandle.WaitOne(TimeSpan.FromMilliseconds(task.Footsite.Settings.RetryPeriod));
                                if (cancelToken.IsCancellationRequested)
                                {
                                    return(StepResult.Canceled);
                                }

                                res = retryCheckout.Run(cxt, task,
                                                        TimeSpan.FromMilliseconds(task.Footsite.Settings.RetryPeriod),
                                                        out executionTime, cancelToken);

                                if (res == StepResult.Ok)
                                {
                                    checkoutStatus = cxt.QueuedCheckoutResponse["status"].Value <string>();
                                }
                            }
                        }
                    }
                }

                if (res == StepResult.Ok)
                {
                    if (checkoutStatus == "failed")
                    {
                        string errorMessage = "";

                        try
                        {
                            foreach (JToken errorJToken in checkoutReponseJObject["errors"])
                            {
                                errorMessage += $"{errorJToken.First().Value<string>()};";
                            }
                        }
                        catch (Exception e)
                        {
                            ;
                        }

                        if (errorMessage != "")
                        {
                            Logger.LogEvent(task.Log, $"TASK {task.Id}", $"Has got errors: {errorMessage}");
                        }

                        res = StepResult.Failed;
                    }
                    else if (checkoutStatus == "dup")
                    {
                        Logger.LogEvent(task.Log, $"TASK {task.Id}", $"Has got duplication");

                        res = StepResult.Failed;
                    }
                    else if (checkoutReponseJObject.ToString().Contains("Your order has been submitted") || cxt.QueuedCheckoutResponse != null && cxt.QueuedCheckoutResponse.ToString().Contains("Your order has been submitted"))
                    {
                        res = StepResult.Ok;
                    }
                    else
                    {
                        Logger.LogEvent(task.Log, $"TASK {task.Id}",
                                        $"Could not resolve checkout status '{checkoutStatus}'. Contact with support.");

                        res = StepResult.Failed;
                    }
                }
            }
            else
            {
                res = StepResult.Failed;
            }

            return(res);
        }
Example #9
0
 protected virtual StepResult Paying(ICheckoutTaskContext context, CheckoutTask task, CancellationToken cancelToken)
 {
     return(StepResult.Ok);
 }
Example #10
0
 protected virtual StepResult WaitProduct(ICheckoutTaskContext context, CheckoutTask task, CancellationToken cancelToken)
 {
     task.ProductAvailableEvent.WaitOne(cancelToken);
     return(StepResult.Ok);
 }
Example #11
0
 protected virtual ICheckoutTaskContext CreateContext(CheckoutTask task)
 {
     return(null);
 }
Example #12
0
        private void Checkout(CancellationToken cancelToken, CheckoutTask task)
        {
            ICheckoutTaskContext context = null;

            CheckoutStep waitProxy   = new CheckoutStep(WaitProxy, "Waiting proxy", CheckoutTaskState.WaitingProxy);
            CheckoutStep waitProduct = new CheckoutStep(WaitProduct, "Waiting product", CheckoutTaskState.WaitingProduct);
            CheckoutStep addToCart   = new CheckoutStep(AddToCart, "Carting", CheckoutTaskState.Carting);
            CheckoutStep checkCart   = new CheckoutStep(CheckCart, "Checking cart", CheckoutTaskState.Checking);
            CheckoutStep billing     = new CheckoutStep(Billing, "Billing", CheckoutTaskState.Billing);
            CheckoutStep waitQuota   = new CheckoutStep(WaitQuota, "Waiting quota", CheckoutTaskState.WaitingQuota);
            CheckoutStep paying      = new CheckoutStep(Paying, "Paying", CheckoutTaskState.Paying);

            StepResult res = StepResult.Ok;
            TimeSpan   executionTime;

            if (!TierControl.Wait(cancelToken))
            {
                if (IsCanceled(cancelToken, task, null, false))
                {
                    return;
                }
                throw new Exception();
            }

            Logger.LogEvent(task.Log, $"TASK {task.Id}", "Initializing... done");

            //res = waitProxy.Run(null, task, TimeSpan.FromMilliseconds(task.Footsite.Settings.RetryPeriod), out executionTime, cancelToken);
            task.Proxy = task.ProxyPool.GetOne();

            if (IsCanceled(cancelToken, task))
            {
                return;
            }

            if (res != StepResult.Ok)
            {
                Logger.LogEvent(task.Log, $"TASK {task.Id}", "ATC can not be continued without proxy");

                return;
            }

            while (true)
            {
                if (res != StepResult.Ok)
                {
                    cancelToken.WaitHandle.WaitOne(TimeSpan.FromMilliseconds(task.Footsite.Settings.RetryPeriod));

                    if (IsCanceled(cancelToken, task, context))
                    {
                        return;
                    }
                }

                context?.Dispose();
                context = CreateContext(task);

                res = waitProduct.Run(context, task, TimeSpan.FromMilliseconds(task.Footsite.Settings.RetryPeriod), out executionTime, cancelToken);

                if (IsCanceled(cancelToken, task, context))
                {
                    return;
                }

                if (res != StepResult.Ok)
                {
                    Logger.LogEvent(task.Log, $"TASK {task.Id}", $"{waitProduct.Name} is failed... retry");

                    continue;
                }

                if (task.Size == ClothesSizeSystemCollection.RandomSize)
                {
                    task.Size = GetRandomSize();

                    Logger.LogEvent(task.Log, $"TASK {task.Id}", $"Size {task.Size} is selected");
                }

                res = addToCart.Run(context, task, TimeSpan.FromMilliseconds(task.Footsite.Settings.RetryPeriod), out executionTime, cancelToken);

                if (IsCanceled(cancelToken, task, context))
                {
                    return;
                }

                if (res == StepResult.OutOfStock)
                {
                    Logger.LogEvent(task.Log, $"TASK {task.Id}", $"{addToCart.Name} is failed... Out of Stock. Retry ATC");

                    continue;
                }

                if (res != StepResult.Ok)
                {
                    Logger.LogEvent(task.Log, $"TASK {task.Id}", $"{addToCart.Name} is failed... retry ATC");

                    continue;
                }

                while (true)
                {
                    if (res != StepResult.Ok)
                    {
                        cancelToken.WaitHandle.WaitOne(TimeSpan.FromMilliseconds(task.Footsite.Settings.RetryPeriod));

                        if (IsCanceled(cancelToken, task, context))
                        {
                            return;
                        }
                    }

                    res = checkCart.Run(context, task, TimeSpan.FromMilliseconds(task.Footsite.Settings.RetryPeriod), out executionTime, cancelToken);

                    if (IsCanceled(cancelToken, task, context))
                    {
                        return;
                    }

                    if (res != StepResult.Ok)
                    {
                        Logger.LogEvent(task.Log, $"TASK {task.Id}", $"{checkCart.Name} is failed... retry ATC");

                        break;
                    }

                    res = billing.Run(context, task, TimeSpan.FromMilliseconds(task.Footsite.Settings.RetryPeriod), out executionTime, cancelToken);

                    if (IsCanceled(cancelToken, task, context))
                    {
                        return;
                    }

                    if (res != StepResult.Ok)
                    {
                        Logger.LogEvent(task.Log, $"TASK {task.Id}", $"{billing.Name} is failed... retrying checkout");
                    }

                    res = waitQuota.Run(context, task, TimeSpan.FromMilliseconds(task.Footsite.Settings.RetryPeriod), out executionTime, cancelToken);

                    if (IsCanceled(cancelToken, task, context))
                    {
                        return;
                    }

                    if (res == StepResult.Failed)
                    {
                        Logger.LogEvent(task.Log, $"TASK {task.Id}", "Checkout quota has ended");
                    }

                    res = paying.Run(context, task, TimeSpan.FromMilliseconds(task.Footsite.Settings.RetryPeriod), out executionTime, cancelToken);

                    if (res == StepResult.Ok)
                    {
                        task.Profile.Release(true);

                        OnSuccessfulCheckout(new CheckoutInfo()
                        {
                            ReleaseName            = Release.Name,
                            ProductName            = ProductName,
                            ReleaseCheckoutProfile = task.Profile.ReleaseCheckoutProfile,
                            Size      = task.Size,
                            TimeStamp = DateTime.Now
                        });
                    }
                    else
                    {
                        task.Profile.Release(false);
                    }

                    if (IsCanceled(cancelToken, task, context))
                    {
                        return;
                    }

                    if (res != StepResult.Ok)
                    {
                        Logger.LogEvent(task.Log, $"TASK {task.Id}", $"{paying.Name} is failed... retrying checkout");

                        continue;
                    }

                    break;
                }

                if (res != StepResult.Ok)
                {
                    continue;
                }

                break;
            }

            Logger.LogEvent(task.Log, $"TASK {task.Id}", $"Finished!");

            task.State = CheckoutTaskState.Finished;

            FreeResources(context, task);
        }
Example #13
0
        public async Task <bool> Start(CancellationToken cancelToken)
        {
            bool ret = true;

            lock (m_lock)
            {
                if (m_state == ReleaseTaskState.Working)
                {
                    ret = false;
                }
                m_state = ReleaseTaskState.Working;
            }

            if (ret)
            {
                OnPropertyChanged("State");

                await Task.Run(() =>
                {
                    Log.Clear();

                    ReleaseProductInfo productInfo = new ReleaseProductInfo()
                    {
                        ProductLink = Release.ProductLink,
                        KeyWords    = Release.KeyWords.ToList()
                    };

                    ProductMonitorTask productMonitorTask = new ProductMonitorTask()
                    {
                        Period      = Release.Footsite.Settings.ProductMonitorPeriod,
                        ProductInfo = productInfo,
                        Proxy       = Release.GlobalProxy
                    };

                    Thread monitorThread = new Thread(() => MonitorProduct(cancelToken, Log, productMonitorTask));
                    monitorThread.Start();

                    List <CheckoutTask> checkoutTasks = new List <CheckoutTask>();

                    int taskId          = 0;
                    ProxyPool proxyPool = new ProxyPool(Release.Proxies.ToList(), 1);

                    foreach (ReleaseCheckoutProfile profile in Release.Profiles)
                    {
                        CheckoutTaskCcProfile checkoutTaskCcProfile = new CheckoutTaskCcProfile(new ReleaseCheckoutProfile(profile)
                        {
                            CheckoutProfile = new CheckoutProfile(profile.CheckoutProfile)
                        }, Release.Footsite.Settings.PurchaseLimitPerProfile);
                        Profiles.Add(checkoutTaskCcProfile);

                        for (int i = 0; i < profile.TasksCount; i++)
                        {
                            CheckoutTask checkoutTask = new CheckoutTask()
                            {
                                Id                    = taskId++,
                                Size                  = profile.Size,
                                VariantId             = profile.VariantId,
                                Profile               = checkoutTaskCcProfile,
                                ProxyPool             = proxyPool,
                                ProductAvailableEvent = productMonitorTask.ProductAvailableEvent,
                                Footsite              = Release.Footsite,
                                ProductInfo           = productInfo
                            };
                            Logger.LogEvent(checkoutTask.Log, $"TASK {checkoutTask.Id}", "Initializing...");

                            checkoutTaskCcProfile.CheckoutTasks.Add(checkoutTask);
                            checkoutTasks.Add(checkoutTask);
                        }
                    }

                    RestockMonitorTask restockMonitorTask = new RestockMonitorTask()
                    {
                        Period        = TimeSpan.FromMilliseconds(Release.Footsite.Settings.ProductMonitorPeriod),
                        CheckoutTasks = checkoutTasks,
                        ProductInfo   = productInfo,
                    };

                    Thread restockMonitorThread = new Thread(() => RestockMonitor(Log, restockMonitorTask, cancelToken));
                    restockMonitorThread.Start();

                    CheckoutTasksWatcher checkoutTasksWatcher = new CheckoutTasksWatcher(checkoutTasks);

                    Task.Run(() =>
                    {
                        foreach (CheckoutTask checkoutTask in checkoutTasks)
                        {
                            if (cancelToken.IsCancellationRequested)
                            {
                                break;
                            }

                            Thread checkoutThread = new Thread(() => Checkout(cancelToken, checkoutTask));
                            checkoutThread.Start();
                        }
                    });

                    checkoutTasksWatcher.FinishedEvent.WaitOne(cancelToken);

                    productMonitorTask.CompleteEvent.Set();
                    restockMonitorTask.CompleteEvent.Set();
                });

                TierControl.ReleaseQuota(Release.TasksCount, Release.Footsite.Type);

                State = ReleaseTaskState.Idle;
            }

            return(ret);
        }