/// <summary> /// コメント受信イベントハンドラ /// </summary> /// <param name="sender"></param> /// <param name="comment"></param> private void twcasChatClient_OnCommentReceiveEach(TwcasChatClient sender, CommentStruct comment) { // コメントの追加 UiCommentData uiCommentData = new UiCommentData(); uiCommentData.UserThumbUrl = comment.UserThumbUrl; uiCommentData.UserName = comment.UserName; uiCommentData.CommentStr = comment.Text; System.Diagnostics.Debug.WriteLine("UserThumbUrl " + uiCommentData.UserThumbUrl); System.Diagnostics.Debug.WriteLine("UserName " + uiCommentData.UserName); System.Diagnostics.Debug.WriteLine("CommentStr " + uiCommentData.CommentStr); ViewModel viewModel = this.DataContext as ViewModel; ObservableCollection <UiCommentData> uiCommentDataList = viewModel.UiCommentDataCollection; uiCommentDataList.Add(uiCommentData); // コメントログを記録 writeLog(uiCommentData.UserName, uiCommentData.CommentStr); // 棒読みちゃんへ送信 if (comment.IsBouyomiOn) { string sendText = comment.Text; string bcTitle = twcasChatClient.BcTitle; if (bcTitle != "") { StringBuilder sendTextSb = new StringBuilder(sendText); sendTextSb.Replace("(" + bcTitle + ")", ""); sendText = sendTextSb.ToString(); } bouyomiChan.Talk(sendText); } }
/// <summary> /// コメントをGUIに登録する /// </summary> /// <param name="workCommentList"></param> private void setCmntToGui(IList <CommentStruct> workCommentList) { // 登録済みの最新コメントを取得 CommentStruct prevComment = new CommentStruct(); if (CommentList.Count > 0) { prevComment = CommentList[CommentList.Count - 1]; } // 新しいコメントから順にチェック int iStPos = 0; // 未登録のコメントの開始位置 for (int iComment = workCommentList.Count - 1; iComment >= 0; iComment--) { CommentStruct tagtComment = workCommentList[iComment]; // 登録済みかチェック if (tagtComment.Id == prevComment.Id) { iStPos = iComment + 1; // 登録済みのコメントの次のコメントが未登録の開始位置 System.Diagnostics.Debug.WriteLine("found stored comment."); break; } } if (iStPos == workCommentList.Count) { // すべて登録済み return; } // 新規分だけ登録 for (int iComment = iStPos; iComment < workCommentList.Count; iComment++) { CommentStruct tagtComment = workCommentList[iComment]; // 新規のコメントの場合、リストに追加する CommentList.Add(tagtComment); System.Diagnostics.Debug.WriteLine("■{0} {1} {2}", tagtComment.UserName, tagtComment.Text, tagtComment.TimeStr); System.Diagnostics.Debug.WriteLine("■ThumbUrl " + tagtComment.UserThumbUrl); // 最大コメント数チェック if (CommentList.Count > MaxStoredCommentCnt) { CommentList.RemoveAt(0); System.Diagnostics.Debug.Assert(CommentList.Count == MaxStoredCommentCnt); } if (OnCommentReceiveEach != null) { OnCommentReceiveEach(this, tagtComment); } } if (OnCommentReceiveDone != null) { OnCommentReceiveDone(this); } }
/// <summary> /// コメント一覧を取得する /// </summary> /// <returns></returns> private IList <CommentStruct> getBcCmntListAll() { IList <CommentStruct> workCommentList = new List <CommentStruct>(); if (!IsBcMovieValid()) { return(workCommentList); } // コメント一覧の取得 // http://ja.twitcasting.tv/アカウント/userajax.php?c=listall&m=動画ID&k=0&f=0&n=10 // [{"id":,"class":,"html":,"date":,"dur":,"uid":,"screen":,"statusid":"","lat":0,"lng":0,"show":true,"yomi":""}, // ... // ] string url = TwcastUrl + "/" + ChannelName + "/userajax.php?c=listall&m=" + MovieId + "&k=0&f=0&n=10"; string recvStr = doHttpRequest(url); //System.Diagnostics.Debug.WriteLine("recvStr:[" + recvStr + "]"); if (recvStr == null) { // 接続エラー return(workCommentList); } try { // JSON形式からコメント応答オブジェクトに変換 IList <BcCmntResponse> cmnts = JsonConvert.DeserializeObject <List <BcCmntResponse> >(recvStr); // コメント応答リストからコメントを取り出す workCommentList = parseBcCmntResponse(cmnts); // 直近の取得開始コメントIDをセットする if (workCommentList.Count > 0) { lastBcCmntId = workCommentList[workCommentList.Count - 1].Id; } else { lastBcCmntId = 0; } // 一覧取得の場合は棒読みちゃんに送信しないようにする for (int i = 0; i < workCommentList.Count; i++) { CommentStruct tmpComment = workCommentList[i]; tmpComment.IsBouyomiOn = false; workCommentList[i] = tmpComment; } } catch (Exception exception) { System.Diagnostics.Debug.WriteLine(exception.Message + " " + exception.StackTrace); System.Diagnostics.Debug.WriteLine("[Error]getBcCmntListAll: recvStr: " + recvStr); return(workCommentList); } return(workCommentList); }
/// <summary> /// コメント応答のパース /// </summary> /// <param name="cmnts"></param> private IList <CommentStruct> parseBcCmntResponse(IList <BcCmntResponse> cmnts) { IList <CommentStruct> workCommentList = new List <CommentStruct>(); if (cmnts == null) { return(workCommentList); } // コメント応答を取得 // 日付順 foreach (BcCmntResponse bcCmntResponse in cmnts) { //uint id = bcCmntResponse.id; ulong id = bcCmntResponse.id; string htmlStr = bcCmntResponse.html; string dateStr = bcCmntResponse.date; System.Diagnostics.Debug.WriteLine("htmlStr:" + htmlStr); HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); doc.LoadHtml(htmlStr); // 最初のimgタグ:プロフィール画像 HtmlNode profileImgTdTag = doc.DocumentNode.SelectSingleNode(@"//td[@class=""img""]"); if (profileImgTdTag == null) { System.Diagnostics.Debug.WriteLine("profileImgTdTag is null. id: [" + id + "] html: [" + htmlStr + "]"); continue; } HtmlNode profImgTag = profileImgTdTag.SelectSingleNode(@"//img[1]"); if (profImgTag == null) { System.Diagnostics.Debug.WriteLine("profImgTag is null. id: [" + id + "] html: [" + htmlStr + "]"); continue; } string profImgSrc = profImgTag.GetAttributeValue("src", ""); // ユーザーノード HtmlNode userSpanTag = doc.DocumentNode.SelectSingleNode(@"//span[@class=""user""]"); if (userSpanTag == null) { System.Diagnostics.Debug.WriteLine("userSpanTag is null. id: [" + id + "] html: [" + htmlStr + "]"); continue; } if (profImgSrc.IndexOf("//") == 0) { profImgSrc = "https:" + profImgSrc; } string userName = userSpanTag.InnerText; // コメントノード HtmlNode cmntTdTag = doc.DocumentNode.SelectSingleNode(@"//td[@class=""comment""]"); if (cmntTdTag == null) { System.Diagnostics.Debug.WriteLine("cmntTdTag is null. id: [" + id + "] html: [" + htmlStr + "]"); continue; } // コメントテキストノード string cmntStr = ""; HtmlNode cmntTxtTag = cmntTdTag.SelectSingleNode(@"//span[@class=""comment-text""]"); if (cmntTxtTag == null) { System.Diagnostics.Debug.WriteLine("cmntTxtTag is null. id: [" + id + "] html: [" + htmlStr + "]"); continue; } cmntStr += cmntTxtTag.InnerText; //cmntStr = cmntStr.Replace("<br>", System.Environment.NewLine); HtmlNode subTitleNode = cmntTdTag.SelectSingleNode(@"//span[@class=""smallsubtitle""]"); if (subTitleNode != null) { cmntStr += subTitleNode.InnerText; } cmntStr = System.Web.HttpUtility.HtmlDecode(cmntStr); CommentStruct workComment = new CommentStruct(); workComment.Id = id; workComment.UserThumbUrl = profImgSrc; workComment.UserName = userName; workComment.TimeStr = dateStr; workComment.Text = cmntStr; workComment.IsBouyomiOn = true; // 初期値 //System.Diagnostics.Debug.WriteLine("Id " + workComment.Id); //System.Diagnostics.Debug.WriteLine("UserThumbUrl " + workComment.UserThumbUrl); //System.Diagnostics.Debug.WriteLine("UserName " + workComment.UserName); //System.Diagnostics.Debug.WriteLine("TimeStr " + workComment.TimeStr); //System.Diagnostics.Debug.WriteLine("Text " + workComment.Text); workCommentList.Add(workComment); } return(workCommentList); }