Ejemplo n.º 1
0
        internal async Task check(CasterHub hub)
        {
            if (httpErrorCode >= 400 && httpErrorCode < 500)
            {
                log.e($"httpErrorCode={httpErrorCode}");
                return;
            }

            // 最低限3分は待つ
            var now = UnixTime.now;

            if (now < lastCheckTime + UnixTime.minute1 * 3)
            {
                return;
            }
            lastCheckTime = now;

            log.d("check start.");

            var csrfToken = "";
            var liveId    = "";
            var hasLive   = false;
            var castTotal = 0;

            while (!isDisposed)
            {
                try {
                    ConcurrentDictionary <Int32, Int32> giftMap;

                    String pageUrl;
                    Int64  timePageOpen;
                    if (!hasLive)
                    {
                        // 初回は部屋のHTMLを読む
                        pageUrl = $"{Config.URL_TOP}{roomName}";
                        var request = new HttpRequestMessage(HttpMethod.Get, pageUrl);
                        request.Headers.Add("Cookie", hub.cookie);
                        request.Headers.Add("Accept", "text/html");
                        var response = await Config.httpClient.SendAsync(request, canceller.Token).ConfigureAwait(false);

                        timePageOpen = UnixTime.now;
                        var code = response.codeInt();
                        if (!response.IsSuccessStatusCode)
                        {
                            log.d($"HTTP {code} {response.ReasonPhrase} {pageUrl}");
                            httpErrorCode = code;
                            httpError     = $"HTTP {code} {response.ReasonPhrase}";
                            hub.showStatus();
                            if (code >= 400 && code < 500)
                            {
                                log.d($"don't retry for error {code}.");
                                break;
                            }
                            await delayEx(UnixTime.second1 * 10L);

                            continue;
                        }
                        httpErrorCode = 0;
                        httpError     = "";

                        var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                        var json = reInitialData.matchOrNull(content)?.Groups[1].Value.decodeEntity();
                        if (json == null)
                        {
                            log.e("missing jsinitialData. (maybe not in live).");
                            break;
                        }
                        var jsinitialData = JToken.Parse(json);
                        csrfToken = jsinitialData.Value <String>("csrfToken") ?? "";
                        liveId    = jsinitialData.Value <String>("liveId") ?? "";
                        if (csrfToken == "" || liveId == "")
                        {
                            log.e("missing csrfToken or liveId in jsinitialData. (maybe not in live).");
                            break;
                        }
                        //
                        json = reLiveData.matchOrNull(content)?.Groups[1].Value.decodeEntity();
                        if (json == null)
                        {
                            log.d("missing jsLiveData. (maybe not in live).");
                            break;
                        }
                        try {
                            giftMap = JToken.Parse(json).Value <JArray>("gift_list").parseGiftCount();
                        } catch (Exception ex) {
                            log.e(ex, "gift list is null. (parse error)");
                            break;
                        }
                    }
                    else
                    {
                        // 2回目以降は current_user APIを読む
                        pageUrl = $"{Config.URL_TOP}api/live/current_user?room_id={ roomId }&_={UnixTime.now / 1000L}";
                        var request = new HttpRequestMessage(HttpMethod.Get, pageUrl);
                        request.Headers.Add("Accept", "application/json");
                        request.Headers.Add("Cookie", hub.cookie);

                        var response = await Config.httpClient.SendAsync(request, canceller.Token).ConfigureAwait(false);

                        timePageOpen = UnixTime.now;
                        var code = response.codeInt();

                        if (!response.IsSuccessStatusCode)
                        {
                            log.d($"HTTP {code} {response.ReasonPhrase} {pageUrl}");
                            httpErrorCode = code;
                            httpError     = $"HTTP {code} {response.ReasonPhrase}";
                            hub.showStatus();
                            if (code >= 400 && code < 500)
                            {
                                log.d($"don't retry for error {code}.");
                                break;
                            }
                            await delayEx(UnixTime.second1 * 10L);

                            continue;
                        }
                        httpErrorCode = 0;
                        httpError     = "";

                        // レスポンスを受け取った時刻
                        timePageOpen = UnixTime.now;
                        var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                        MyResourceRequestHandler.responceLog(UnixTime.now, url, content);
                        try {
                            giftMap = JToken.Parse(content).Value <JObject>("gift_list").Value <JArray>("normal").parseGiftCount();
                        } catch (Exception ex) {
                            log.e(ex, "gift list is null. (parse error)");
                            break;
                        }
                    }

                    if (giftMap.Count == 0)
                    {
                        // 配信してなかった…
                        log.d("gift list is empty. (not in live)");
                        break;
                    }

                    if (!hasLive)
                    {
                        var dontWait = Task.Run(() => count(hub, liveId, csrfToken, timePageOpen));
                    }
                    hasLive = true;

                    var giftIds = giftMap.Keys.ToArray();
                    Array.Sort(giftIds);

                    isCasting = true;
                    hub.showStatus();
                    hub.mainWindow.onGiftCount(UnixTime.now, giftMap, pageUrl);

                    while (true)
                    {
                        var castCount = 0;
                        foreach (var giftId in giftIds)
                        {
                            var freeNum = giftMap.getOrDefault(giftId, -1);
                            if (giftId < 0 || freeNum <= 0)
                            {
                                continue;
                            }

                            if (!Config.starIds.Contains(giftId) && !Config.seedIds.Contains(giftId))
                            {
                                continue;
                            }

                            var step = Math.Min(10, freeNum);
                            log.d($"gifting giftId={giftId}, num={step}");

                            var parameters = new Dictionary <String, String>()
                            {
                                { "gift_id", giftId.ToString() },
                                { "live_id", liveId },
                                { "num", step.ToString() },
                                { "csrf_token", csrfToken }
                            };
                            var url     = $"{Config.URL_TOP}api/live/gifting_free";
                            var request = new HttpRequestMessage(HttpMethod.Post, url);
                            request.Headers.Add("Cookie", hub.cookie);
                            request.Headers.Add("Accept", "application/json");
                            request.Content = new FormUrlEncodedContent(parameters);
                            //
                            var response = await Config.httpClient.SendAsync(request, canceller.Token).ConfigureAwait(false);

                            var code = response.codeInt();
                            if (!response.IsSuccessStatusCode)
                            {
                                log.d($"HTTP {code} {response.ReasonPhrase} {url}");
                                break;
                            }
                            castCount      += step;
                            freeNum        -= step;
                            giftMap[giftId] = freeNum;
                        }

                        if (castCount == 0)
                        {
                            break;
                        }
                        castTotal += castCount;

                        log.d($"castCount={castCount}, total={castTotal}");

                        hub.mainWindow.onGiftCount(UnixTime.now, giftMap, pageUrl);
                        await delayEx(UnixTime.second1 * 2L);
                    }

                    // ページを開いてから31秒は待つ
                    // (自動取得と足並みを揃える)
                    var remain = UnixTime.second1 * 31 + timePageOpen - UnixTime.now;
                    if (remain > 0L)
                    {
                        log.d($"wait {remain}ms");
                        await delayEx(remain);
                    }
                } catch (TaskCanceledException ex) {
                    log.e(ex, "task was cancelled.");
                    break;
                } catch (Exception ex) {
                    log.e(ex, "check() failed.");
                    await delayEx(UnixTime.second1 * 60L);
                }
            }

            isCasting = false;
            hub.showStatus();

            if (hasLive)
            {
                log.d("check() end.");
            }
        }
Ejemplo n.º 2
0
        async void count(CasterHub hub, String liveId, String csrfToken, Int64 lastPageOpen)
        {
            if (lastPageOpen - lastCountStart < UnixTime.hour1)
            {
                countStr = "カウント(前回から1時間経過してない)";
                hub.showStatus();
                log.d("dont count due to rapidly open pages.");
                return;
            }
            lastCountStart = lastPageOpen;

            countStr = "カウント開始";
            hub.showStatus();

            for (var count = 0; count <= 50; ++count)
            {
                for (var nTry = 4; nTry >= 1; --nTry)
                {
                    try {
                        if (isDisposed)
                        {
                            log.d("count cancelled.");
                            return;
                        }

                        var parameters = new Dictionary <String, String>()
                        {
                            { "live_id", liveId },
                            { "comment", count.ToString() },
                            { "is_delay", "0" },
                            { "csrf_token", csrfToken }
                        };
                        var url     = $"{Config.URL_TOP}api/live/post_live_comment";
                        var request = new HttpRequestMessage(HttpMethod.Post, url);
                        request.Headers.Add("Cookie", hub.cookie);
                        request.Headers.Add("Accept", "application/json");
                        request.Content = new FormUrlEncodedContent(parameters);
                        //
                        var response = await Config.httpClient.SendAsync(request, canceller.Token).ConfigureAwait(false);

                        var code = response.codeInt();
                        log.d($"count {count} HTTP {code} {response.ReasonPhrase}");
                        await delayEx(UnixTime.second1 * 2);

                        if (response.IsSuccessStatusCode)
                        {
                            countStr = $"カウント{count} 成功";
                            hub.showStatus();
                            break;
                        }

                        if (nTry == 1)
                        {
                            log.d($"count {count} too many retry. stop counting…");
                            countStr = $"カウント{count} 中断 HTTP {response.ReasonPhrase}";
                            hub.showStatus();
                            return;
                        }
                    } catch (Exception ex) {
                        countStr = $"カウント{count} {ex}";
                        hub.showStatus();
                        return;
                    }
                }
            }
        }