コード例 #1
0
        private void ParseLiveCommentServerResponse(string recievedString)
        {
            if (string.IsNullOrWhiteSpace(recievedString))
            {
                Debug.Write($"IGNORE");
                return;
            }

            if (!recievedString.StartsWith("<") || !recievedString.EndsWith(">"))
            {
                // Note: 寄り厳密にXMLフォーマットチェックをやるなら
                // <>の数が同数であることをチェックする
                Debug.Write($"illigal format, required XML");
                Debug.Write($" -> ");
                Debug.Write(recievedString);
                return;
            }

            var xmlDoc      = XDocument.Parse(recievedString);
            var xmlRoot     = xmlDoc.Root;
            var elementName = xmlRoot.Name.LocalName;

            Debug.Write(elementName);
            Debug.Write(" -> ");
            if (elementName == "thread")
            {
                Debug.Write("connect success");
                IsCommentServerConnected = true;

                // <thread ticket="{チケット}" server_time="{サーバー時刻}" last_res="{送信される過去のコメント数?(NECOで使用してないので不明)}">
                var  serverTimeText = xmlRoot.Attribute(XName.Get("server_time")).Value;
                long serverTime;
                if (long.TryParse(serverTimeText, out serverTime))
                {
                    _ServerTime = serverTime;
                }

                var ticketText = xmlRoot.Attribute(XName.Get("ticket")).Value;
                _Ticket = ticketText;

                CommentServerConnected?.Invoke();
            }
            else if (elementName == "chat_result")
            {
                // <chat_result status="{コメント投稿要求の返答}" />
                var result = xmlRoot.Attribute(XName.Get("status")).Value;

                /*
                 * 0 = 投稿に成功した
                 * 1 = 投稿に失敗した(短時間に同じ内容のコメントを投稿しようとした、パラメータが間違っている、他)
                 * 4 = 投稿に失敗した(ごく短時間にコメントを連投しようとした、パラメータが間違っている、他)
                 */

                Debug.Write(result);
                Debug.Write(result == "0" ? " (success)" : " (failed)");

                CommentPosted?.Invoke(result == "0", _LastPostChat);
                _LastPostChat = null;
            }
            else if (elementName == "chat")
            {
                // _LiveComments.Add(chat);
                // <chat anonymity="{184か}" no="{コメントの番号}" date="{コメントが投稿されたリアル時間?}" mail="{コマンド}" premium="{プレミアムID}" thread="{スレッドID}" user_id="{ユーザーID}" vpos="{コメントが投稿された生放送の時間}" score="{NGスコア}">{コメント}</chat>\0
                try
                {
                    var chatSerializer = new XmlSerializer(typeof(Chat));
                    using (var readerStream = new StringReader(recievedString))
                    {
                        var chat = chatSerializer.Deserialize(readerStream) as Chat;
                        if (chat != null)
                        {
                            Debug.Write(chat.Text);

                            OperationCommnad officialCommand          = null;
                            string[]         officialCommandArguments = null;
                            if (ChcekOfficialOperationComment(chat, out officialCommand, out officialCommandArguments))
                            {
                                var args = new NicoLiveOperationCommandEventArgs()
                                {
                                    CommandType = officialCommand.CommandType,
                                    Arguments   = officialCommandArguments,
                                    Chat        = chat
                                };

                                OperationCommandRecieved?.Invoke(this, args);
                            }
                            else
                            {
                                CommentRecieved?.Invoke(chat);
                            }
                        }
                    }
                }
                catch { }
            }
            else
            {
                Debug.WriteLine($"not supproted");
                Debug.Write(" -> ");
                Debug.Write(recievedString);
            }
        }
コード例 #2
0
        private void ParseChatXml(string xml)
        {
            var xmlDoc      = XDocument.Parse(xml);
            var xmlRoot     = xmlDoc.Root;
            var elementName = xmlRoot.Name.LocalName;

            Debug.Write(elementName);
            Debug.Write(" -> ");
            if (elementName == "thread")
            {
                Debug.Write("connect success");
                IsConnected = true;

                // <thread ticket="{チケット}" server_time="{サーバー時刻}" last_res="{送信される過去のコメント数?(NECOで使用してないので不明)}">
                var  serverTimeText = xmlRoot.Attribute(XName.Get("server_time")).Value;
                long serverTime;
                if (long.TryParse(serverTimeText, out serverTime))
                {
                    _ServerTime = serverTime;
                }

                var ticketText = xmlRoot.Attribute(XName.Get("ticket")).Value;
                _Ticket = ticketText;

                Connected?.Invoke(this, new CommentServerConnectedEventArgs()
                {
                    Ticket     = _Ticket,
                    ServerTime = (int)_ServerTime,
                    Thread     = this.ThreadId
                });
            }
            else if (elementName == "chat_result")
            {
                // <chat_result status="{コメント投稿要求の返答}" />
                var result = xmlRoot.Attribute(XName.Get("status")).Value;

                /*
                 *              0 = 投稿に成功した
                 *              1 = 投稿に失敗した(短時間に同じ内容のコメントを投稿しようとした、パラメータが間違っている、他)
                 *              4 = 投稿に失敗した(ごく短時間にコメントを連投しようとした、パラメータが間違っている、他)
                 */

                Debug.Write(result);
                Debug.Write(result == "0" ? " (success)" : " (failed)");

                CommentPosted?.Invoke(this, new CommentPostedEventArgs()
                {
                    ChatResult = (ChatResult)int.Parse(result),
                });
                _LastPostChat = null;
            }
            else if (elementName == "chat")
            {
                // _LiveComments.Add(chat);
                // <chat anonymity="{184か}" no="{コメントの番号}" date="{コメントが投稿されたリアル時間?}" mail="{コマンド}" premium="{プレミアムID}" thread="{スレッドID}" user_id="{ユーザーID}" vpos="{コメントが投稿された生放送の時間}" score="{NGスコア}">{コメント}</chat>\0
                try
                {
                    var chatSerializer = new XmlSerializer(typeof(Chat));
                    using (var readerStream = new StringReader(xml))
                    {
                        var chat = chatSerializer.Deserialize(readerStream) as Chat;
                        if (chat != null)
                        {
                            Debug.Write(chat.Text);

                            OperationCommnad officialCommand          = null;
                            string[]         officialCommandArguments = null;
                            if (ChcekOfficialOperationComment(chat, out officialCommand, out officialCommandArguments))
                            {
                                var args = new NicoLiveOperationCommandEventArgs()
                                {
                                    CommandType = officialCommand.CommandType,
                                    Arguments   = officialCommandArguments,
                                    Chat        = chat
                                };

//                                OperationCommandRecieved?.Invoke(this, args);
                            }
                            else
                            {
                                var liveChatData = new LiveChatData()
                                {
                                    No          = (int)chat.GetCommentNo(),
                                    Thread      = chat.Thread,
                                    IsAnonymity = chat.GetAnonymity(),
                                    Content     = chat.Text,
                                    Mail        = chat.Mail,
                                    UserId      = chat.User_id,
                                    Vpos        = (int)chat.GetVpos(),
                                    Date        = int.Parse(chat.Date),
                                };
                                CommentRecieved?.Invoke(this, new CommentRecievedEventArgs()
                                {
                                    Chat = liveChatData
                                });
                            }
                        }
                    }
                }
                catch { }
            }
            else
            {
                Debug.WriteLine($"not supproted");
                Debug.Write(" -> ");
                Debug.Write(xml);
            }
        }
コード例 #3
0
        private async void _NicoLiveCommentClient_OperationCommandRecieved(NicoLiveCommentClient sender, NicoLiveOperationCommandEventArgs args)
        {
            await HohoemaApp.UIDispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async() =>
            {
                switch (args.CommandType)
                {
                case NicoLiveOperationCommandType.Play:
                    break;

                case NicoLiveOperationCommandType.PlaySound:
                    break;

                case NicoLiveOperationCommandType.PermanentDisplay:
                    if (args.Arguments.Length > 0)
                    {
                        PermanentDisplayText = args.Arguments[0];
                    }
                    break;

                case NicoLiveOperationCommandType.ClearPermanentDisplay:
                    PermanentDisplayText = null;
                    break;

                case NicoLiveOperationCommandType.Vote:
                    break;

                case NicoLiveOperationCommandType.CommentMode:
                    break;

                case NicoLiveOperationCommandType.Call:
                    break;

                case NicoLiveOperationCommandType.Free:
                    break;

                case NicoLiveOperationCommandType.Reset:

                    // 動画接続のリセット
                    await RetryRtmpConnection();

                    break;

                case NicoLiveOperationCommandType.Info:

                    // 1:市場登録 2:コミュニティ参加 3:延長 4,5:未確認 6,7:地震速報 8:現在の放送ランキングの順位
                    // /info 数字 "表示内容"

                    if (args.Arguments.Length >= 2)
                    {
                        int infoType;
                        if (int.TryParse(args.Arguments[0], out infoType))
                        {
                            var nicoLiveInfoType = (NicoLiveInfoType)infoType;

                            args.Chat.Text = args.Arguments[1];
                            args.Chat.Mail = "shita";

                            _LiveComments.Add(args.Chat);
                        }
                    }
                    break;

                case NicoLiveOperationCommandType.Press:

                    // http://dic.nicovideo.jp/a/%E3%83%90%E3%83%83%E3%82%AF%E3%82%B9%E3%83%86%E3%83%BC%E3%82%B8%E3%83%91%E3%82%B9
                    // TODO: BSPユーザーによるコメントに対応
                    // BSPコメへの風当たりはやや強いのでオプションでON/OFF切り替え対応必要かも
                    if (args.Arguments.Length >= 4)
                    {
                        args.Chat.Mail = args.Arguments[1];
                        args.Chat.Text = args.Arguments[2];
                        //var name = args.Arguments[3];

                        _LiveComments.Add(args.Chat);
                    }
                    break;

                case NicoLiveOperationCommandType.Disconnect:

                    // 放送者側からの切断要請

                    // Note: RTMPによる動画受信の停止はDisconnect後の
                    // RtmpClient.Closedイベントによって処理されます。
                    // また、RtmpClientがクローズ中にここでRtmpClient.Close()を行うと
                    // スレッドセーフではないためか、例外が発生します。

                    await CloseRtmpConnection();

                    await Task.Delay(500);

                    // 次枠の自動巡回を開始
//						await StartNextLiveSubscribe(DefaultNextLiveSubscribeDuration);

                    break;

                case NicoLiveOperationCommandType.Koukoku:
                    break;

                case NicoLiveOperationCommandType.Telop:

                    /*
                     *      on ニコ生クルーズ(リンク付き)/ニコニコ実況コメント
                     *      show クルーズが到着/実況に接続
                     *      show0 実際に流れているコメント
                     *      perm ニコ生クルーズが去って行きました<改行>(降りた人の名前、人数)
                     *      off (プレイヤー下部のテロップを消去)
                     */

                    if (args.Arguments.Length >= 2)
                    {
                        // TODO:
                    }

                    break;

                case NicoLiveOperationCommandType.Hidden:
                    break;

                case NicoLiveOperationCommandType.CommentLock:
                    break;

                default:
                    break;
                }
            });
        }