public TwicasMessageContext(ITwicasMessage message, MessageMetadata metadata, IMessageMethods methods)
 {
     Message  = message;
     Metadata = metadata;
     Methods  = methods;
 }
Пример #2
0
        public async Task ConnectAsync(string broadcasterId, int cnum, long live_id)
        {
            _first.Reset();
            _cts             = new CancellationTokenSource();
            _receivedItemIds = new System.Collections.Concurrent.ConcurrentBag <string>();
            //TODO:try-catch
            //var liveInfo = await API.GetLiveContext(_server, broadcasterId);
            //var cnum = liveInfo.MovieCnum;
            //var live_id = liveInfo.MovieId;
            long lastCommentId = 0;

            try
            {
                var(initialComments, initialRaw) = await API.GetListAll(_server, broadcasterId, live_id, lastCommentId, 0, 20, _cc);

                if (initialComments.Length > 0)
                {
                    foreach (var lowComment in initialComments)
                    {
                        //showがfalseのデータが時々ある。
                        //{"id":15465669455,"show":false}
                        //よく分からないけど、有用な情報は無さそうだからスルー
                        if (!lowComment.show)
                        {
                            continue;
                        }

                        var context = CreateMessageContext(lowComment, true, initialRaw);
                        MessageReceived?.Invoke(this, context);
                    }
                    //var initialDataList = LowComment2Data(initialComments, initialRaw);
                    //if (initialDataList.Count > 0)
                    //{
                    //    InitialCommentsReceived?.Invoke(this, initialDataList);
                    //}
                    var lastComment = initialComments[initialComments.Length - 1];
                    lastCommentId = lastComment.id;
                }
            }
            catch (HttpRequestException ex)
            {
                _logger.LogException(ex);
                string message;
                if (ex.InnerException != null)
                {
                    message = ex.InnerException.Message;
                }
                else
                {
                    message = ex.Message;
                }
                SendInfo(message, InfoType.Debug);
            }
            catch (Exception ex)
            {
                _logger.LogException(ex);
                SendInfo(ex.Message, InfoType.Debug);
            }
            //Disconnect()が呼ばれた場合以外は接続し続ける。
            while (!_cts.IsCancellationRequested)
            {
                var    waitTimeMs  = 1000 * _siteOptions.CommentRetrieveIntervalSec;
                var    accWaitTime = 0;
                string lastItemId  = null;
                try
                {
                    var(streamChecker, streamCheckerRaw) = await API.GetUtreamChecker(_server, broadcasterId, lastItemId).ConfigureAwait(false);

                    if (streamChecker.Items != null && streamChecker.Items.Count > 0)
                    {
#if DEBUG
                        try
                        {
                            using (var sw = new System.IO.StreamWriter("アイテムあり.txt", true))
                            {
                                sw.WriteLine(streamCheckerRaw);
                            }
                        }
                        catch (Exception) { }
#endif
                        var lastItem         = streamChecker.Items[streamChecker.Items.Count - 1];
                        var lastItemIdBefore = lastItemId == null ? 0 : long.Parse(lastItemId);
                        lastItemId = Math.Max(lastItemIdBefore, long.Parse(lastItem.Id)).ToString();
                    }
                    MetaReceived?.Invoke(this, new Metadata
                    {
                        Title          = streamChecker.Telop,
                        CurrentViewers = streamChecker.CurrentViewers.ToString(),
                        TotalViewers   = streamChecker.TotalViewers.ToString()
                    });
                    foreach (var item in streamChecker.Items)
                    {
                        try
                        {
                            if (_receivedItemIds.Contains(item.Id))
                            {
                                continue;
                            }

                            ITwicasItem itemMessage = null;
                            if (Tools.IsKiitos(item))
                            {
                                itemMessage = Tools.CreateKiitosMessage(item);
                            }
                            else
                            {
                                var image = new MessageImage
                                {
                                    Url    = item.ItemImage,
                                    Alt    = item.t13,
                                    Height = 40,
                                    Width  = 40,
                                };
                                itemMessage = new TwicasItem(item.Raw)
                                {
                                    UserIcon = new MessageImage
                                    {
                                        Url    = item.SenderImage,
                                        Alt    = item.t13,
                                        Height = 40,
                                        Width  = 40,
                                    },
                                    ItemName = item.t13,
                                    //CommentItems = new List<IMessagePart> { Common.MessagePartFactory.CreateMessageText(item.t13) },
                                    CommentItems = new List <IMessagePart> {
                                        image
                                    },
                                    NameItems = new List <IMessagePart> {
                                        Common.MessagePartFactory.CreateMessageText(item.t12)
                                    },
                                    UserId = item.SenderName,
                                    ItemId = item.Id,
                                };
                            }
                            if (itemMessage != null)
                            {
                                var user     = GetUser(item.SenderName);
                                var metadata = new MessageMetadata(itemMessage, _options, _siteOptions, user, _cp, false)
                                {
                                    IsInitialComment = false,
                                    SiteContextGuid  = SiteContextGuid,
                                };
                                var methods = new TwicasMessageMethods();
                                var context = new TwicasMessageContext(itemMessage, metadata, methods);
                                MessageReceived?.Invoke(this, context);
                            }
                            SendInfo(item.SenderName + " " + item.ItemImage, InfoType.Debug);
                            _receivedItemIds.Add(item.Id);
                        }
                        catch (ParseException ex)
                        {
                            _logger.LogException(ex);
                        }
                        catch (Exception ex)
                        {
                            _logger.LogException(ex);
                        }
                    }

                    if (streamChecker.LiveId == null)
                    {
                        //放送してない。live_idは更新しない。
                    }
                    else
                    {
                        live_id = streamChecker.LiveId.Value;
                        SendInfo($"Twicas live_id={live_id}", InfoType.Debug);
                    }
                    var(lowComments, newCnum, updateRaw) = await API.GetListUpdate(_server, broadcasterId, live_id, cnum, lastCommentId, _cc);

                    if (lowComments != null && lowComments.Count > 0)
                    {
                        cnum = newCnum;


                        lastCommentId = lowComments[lowComments.Count - 1].id;
                        var eachInterval = waitTimeMs / lowComments.Count;
                        foreach (var lowComment in lowComments)
                        {
                            //showがfalseのデータが時々ある。
                            //{"id":15465669455,"show":false}
                            //よく分からないけど、有用な情報は無さそうだからスルー
                            if (!lowComment.show)
                            {
                                continue;
                            }

                            var context = CreateMessageContext(lowComment, false, updateRaw);
                            MessageReceived?.Invoke(this, context);

                            await Task.Delay(eachInterval);

                            accWaitTime += eachInterval;
                        }
                        ////htmlが""のことがある。コメントを削除した?省いておく
                        //var dataCollection = LowComment2Data(lowComments, updateRaw);//.Where(s=>!string.IsNullOrEmpty(s.html)).Select(Tools.Parse).ToList();
                        //if (dataCollection.Count > 0)
                        //{
                        //    lastCommentId = dataCollection[dataCollection.Count - 1].Id;

                        //    var eachInterval = waitTimeMs / dataCollection.Count;
                        //    foreach (var data in dataCollection)
                        //    {
                        //        Received?.Invoke(this, new List<ICommentData> { data });

                        //        await Task.Delay(eachInterval);
                        //        accWaitTime += eachInterval;
                        //    }
                        //}
                    }
                }
                catch (HttpRequestException ex)
                {
                    _logger.LogException(ex);
                    string message;
                    if (ex.InnerException != null)
                    {
                        message = ex.InnerException.Message;
                    }
                    else
                    {
                        message = ex.Message;
                    }
                    SendInfo(message, InfoType.Debug);
                }
                catch (ParseException ex)
                {
                    _logger.LogException(ex);
                    SendInfo(ex.Message, InfoType.Debug);
                }
                catch (TaskCanceledException)
                {
                    break;
                }
                catch (Exception ex)
                {
                    _logger.LogException(ex);
                    //Infoでエラー内容を通知。ただし同じエラーが連続する場合は通知しない
                    SendInfo(ex.Message, InfoType.Debug);
                }
                try
                {
                    var restWait = waitTimeMs - accWaitTime;
                    if (restWait > 0)
                    {
                        await Task.Delay(restWait, _cts.Token);
                    }
                }
                catch (TaskCanceledException)
                {
                    break;
                }
            }
            _cts = null;
        }