public NicoLiveVideo( string liveId, MediaPlayer mediaPlayer, NiconicoSession niconicoSession, NicoLiveProvider nicoLiveProvider, LoginUserLiveReservationProvider loginUserLiveReservationProvider, PlayerSettings playerSettings, IScheduler scheduler, string communityId = null ) { LiveId = liveId; _CommunityId = communityId; MediaPlayer = mediaPlayer; NiconicoSession = niconicoSession; NicoLiveProvider = nicoLiveProvider; LoginUserLiveReservationProvider = loginUserLiveReservationProvider; PlayerSettings = playerSettings; _UIScheduler = scheduler; _LiveComments = new ObservableCollection <LiveChatData>(); LiveComments = new ReadOnlyObservableCollection <LiveChatData>(_LiveComments); LiveComments.ObserveAddChanged() .Where(x => x.IsOperater && x.HasOperatorCommand) .SubscribeOn(_UIScheduler) .Subscribe(chat => { OperationCommandRecieved?.Invoke(this, new OperationCommandRecievedEventArgs() { Chat = chat }); }); }
public NicoLiveVideo(string liveId, MediaPlayer mediaPlayer, HohoemaApp hohoemaApp, string communityId = null) { LiveId = liveId; _CommunityId = communityId; MediaPlayer = mediaPlayer; HohoemaApp = hohoemaApp; _LiveComments = new ObservableCollection <LiveChatData>(); LiveComments = new ReadOnlyObservableCollection <LiveChatData>(_LiveComments); LiveComments.ObserveAddChanged() .Where(x => x.IsOperater && x.HasOperatorCommand) .SubscribeOnUIDispatcher() .Subscribe(chat => { OperationCommandRecieved?.Invoke(this, new OperationCommandRecievedEventArgs() { Chat = chat }); }); }
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); } }