private async void Listen() { Stream _netStream = _clientSocket.InputStream.AsStreamForRead(1024); byte[] stableBuffer = new byte[1024]; while (true) { if (!_StartState) { break; } try { _netStream.ReadB(stableBuffer, 0, 4); var packetlength = BitConverter.ToInt32(stableBuffer, 0); packetlength = IPAddress.NetworkToHostOrder(packetlength); if (packetlength < 16) { throw new NotSupportedException("协议失败: (L:" + packetlength + ")"); } _netStream.ReadB(stableBuffer, 0, 2); //magic _netStream.ReadB(stableBuffer, 0, 2); //protocol_version _netStream.ReadB(stableBuffer, 0, 4); var typeId = BitConverter.ToInt32(stableBuffer, 0); typeId = IPAddress.NetworkToHostOrder(typeId); _netStream.ReadB(stableBuffer, 0, 4);//magic, params? var playloadlength = packetlength - 16; if (playloadlength == 0) { //continue;//没有内容了 } typeId = typeId - 1;//magic, again (为啥要减一啊) var buffer = new byte[playloadlength]; _netStream.ReadB(buffer, 0, playloadlength); var json = Encoding.UTF8.GetString(buffer, 0, playloadlength); if (typeId == 2) { var viewer = BitConverter.ToUInt32(buffer.Take(4).Reverse().ToArray(), 0); //观众人数 if (HasDanmu != null) { HasDanmu(new LiveDanmuModel() { type = LiveDanmuTypes.Viewer, viewer = Convert.ToInt32(viewer) }); } Debug.WriteLine(viewer); } else { if (json.Trim().Length != 0) { Debug.WriteLine(json); JObject obj = JObject.Parse(json); switch (obj["cmd"].ToString()) { case "DANMU_MSG": var v = new DanmuMsgModel(); if (obj["info"] != null && obj["info"].ToArray().Length != 0) { v.text = obj["info"][1].ToString(); if (obj["info"][2] != null && obj["info"][2].ToArray().Length != 0) { v.username = obj["info"][2][1].ToString() + ":"; //v.usernameColor = GetColor(obj["info"][2][0].ToString()); if (obj["info"][2][3] != null && Convert.ToInt32(obj["info"][2][3].ToString()) == 1) { v.vip = "老爷"; v.isVip = Visibility.Visible; } if (obj["info"][2][4] != null && Convert.ToInt32(obj["info"][2][4].ToString()) == 1) { v.vip = "年费老爷"; v.isVip = Visibility.Collapsed; v.isBigVip = Visibility.Visible; } if (obj["info"][2][2] != null && Convert.ToInt32(obj["info"][2][2].ToString()) == 1) { v.vip = "房管"; v.isAdmin = Visibility.Visible; } } if (obj["info"][3] != null && obj["info"][3].ToArray().Length != 0) { v.medal_name = obj["info"][3][1].ToString(); v.medal_lv = obj["info"][3][0].ToString(); v.medalColor = obj["info"][3][4].ToString(); v.hasMedal = Visibility.Visible; } if (obj["info"][4] != null && obj["info"][4].ToArray().Length != 0) { v.ul = "UL" + obj["info"][4][0].ToString(); v.ulColor = obj["info"][4][2].ToString(); } if (obj["info"][5] != null && obj["info"][5].ToArray().Length != 0) { v.user_title = obj["info"][5][0].ToString(); v.hasTitle = Visibility.Visible; } if (HasDanmu != null) { HasDanmu(new LiveDanmuModel() { type = LiveDanmuTypes.Danmu, value = v }); } } break; case "SEND_GIFT": var g = new GiftMsgModel(); if (obj["data"] != null) { g.uname = obj["data"]["uname"].ToString(); g.action = obj["data"]["action"].ToString(); g.giftId = Convert.ToInt32(obj["data"]["giftId"].ToString()); g.giftName = obj["data"]["giftName"].ToString(); g.num = obj["data"]["num"].ToString(); g.uid = obj["data"]["uid"].ToString(); if (HasDanmu != null) { HasDanmu(new LiveDanmuModel() { type = LiveDanmuTypes.Gift, value = g }); } } break; case "WELCOME": var w = new WelcomeMsgModel(); if (obj["data"] != null) { w.uname = obj["data"]["uname"].ToString(); w.uid = obj["data"]["uid"].ToString(); w.svip = obj["data"]["vip"].ToInt32() != 1; if (HasDanmu != null) { HasDanmu(new LiveDanmuModel() { type = LiveDanmuTypes.Welcome, value = w }); } } break; case "SYS_MSG": if (obj["msg"] != null) { if (HasDanmu != null) { HasDanmu(new LiveDanmuModel() { type = LiveDanmuTypes.SystemMsg, value = obj["msg"].ToString() }); } } break; default: break; } } } } catch (Exception ex) { Debug.WriteLine(ex); } await Task.Delay(delay); } }
private async void Listen() { Stream _netStream = _clientSocket.InputStream.AsStreamForRead(1024); byte[] stableBuffer = new byte[1024]; while (true) { if (!_StartState) { break; } try { _netStream.ReadB(stableBuffer, 0, 4); var packetlength = BitConverter.ToInt32(stableBuffer, 0); packetlength = IPAddress.NetworkToHostOrder(packetlength); if (packetlength < 16) { throw new NotSupportedException("协议失败: (L:" + packetlength + ")"); } _netStream.ReadB(stableBuffer, 0, 2); //magic _netStream.ReadB(stableBuffer, 0, 2); //protocol_version _netStream.ReadB(stableBuffer, 0, 4); var typeId = BitConverter.ToInt32(stableBuffer, 0); typeId = IPAddress.NetworkToHostOrder(typeId); _netStream.ReadB(stableBuffer, 0, 4);//magic, params? var playloadlength = packetlength - 16; if (playloadlength == 0) { continue;//没有内容了 } typeId = typeId - 1; var buffer = new byte[playloadlength]; _netStream.ReadB(buffer, 0, playloadlength); if (typeId == 2) { var viewer = BitConverter.ToUInt32(buffer.Take(4).Reverse().ToArray(), 0); //观众人数 if (HasDanmu != null) { HasDanmu(new LiveDanmuModel() { type = LiveDanmuTypes.Viewer, viewer = Convert.ToInt32(viewer) }); } Debug.WriteLine(viewer); continue; } var json_str = ""; try { //临时解决方案,可以优化 //参考https://github.com/Bililive/BililiveRecorder using (MemoryStream outBuffer = new MemoryStream()) { using (System.IO.Compression.DeflateStream compressedzipStream = new System.IO.Compression.DeflateStream(new MemoryStream(buffer, 2, playloadlength - 2), System.IO.Compression.CompressionMode.Decompress)) { byte[] block = new byte[1024]; while (true) { int bytesRead = compressedzipStream.Read(block, 0, block.Length); if (bytesRead <= 0) { break; } else { outBuffer.Write(block, 0, bytesRead); } } compressedzipStream.Close(); buffer = outBuffer.ToArray(); } } json_str = Regex.Replace(Encoding.UTF8.GetString(buffer, 16, buffer.Length - 16), "}\\0\\0.*?\\0\\0{", "},{"); } catch (Exception) { json_str = Encoding.UTF8.GetString(buffer, 0, buffer.Length); } if (json_str.Trim().Length != 0) { json_str = "[" + json_str + "]"; Debug.WriteLine(json_str); JArray json_array = JArray.Parse(json_str); foreach (var obj in json_array) { if (obj["cmd"].ToString().Contains("DANMU_MSG")) { var v = new DanmuMsgModel(); if (obj["info"] != null && obj["info"].ToArray().Length != 0) { v.text = obj["info"][1].ToString(); if (obj["info"][2] != null && obj["info"][2].ToArray().Length != 0) { v.username = obj["info"][2][1].ToString() + ":"; //v.usernameColor = GetColor(obj["info"][2][0].ToString()); if (obj["info"][2][3] != null && Convert.ToInt32(obj["info"][2][3].ToString()) == 1) { v.vip = "老爷"; v.isVip = Visibility.Visible; } if (obj["info"][2][4] != null && Convert.ToInt32(obj["info"][2][4].ToString()) == 1) { v.vip = "年费老爷"; v.isVip = Visibility.Collapsed; v.isBigVip = Visibility.Visible; } if (obj["info"][2][2] != null && Convert.ToInt32(obj["info"][2][2].ToString()) == 1) { v.vip = "房管"; v.isAdmin = Visibility.Visible; } } if (obj["info"][3] != null && obj["info"][3].ToArray().Length != 0) { v.medal_name = obj["info"][3][1].ToString(); v.medal_lv = obj["info"][3][0].ToString(); v.medalColor = obj["info"][3][4].ToString(); v.hasMedal = Visibility.Visible; } if (obj["info"][4] != null && obj["info"][4].ToArray().Length != 0) { v.ul = "UL" + obj["info"][4][0].ToString(); v.ulColor = obj["info"][4][2].ToString(); } if (obj["info"][5] != null && obj["info"][5].ToArray().Length != 0) { v.user_title = obj["info"][5][0].ToString(); v.hasTitle = Visibility.Visible; } if (HasDanmu != null) { HasDanmu(new LiveDanmuModel() { type = LiveDanmuTypes.Danmu, value = v }); } } } //19/10/01,cmd DANMU_MSG变成了DANMU_MSG:4:0:2:2:2:0 switch (obj["cmd"].ToString()) { //case "DANMU_MSG": // break; case "SEND_GIFT": var g = new GiftMsgModel(); if (obj["data"] != null) { g.uname = obj["data"]["uname"].ToString(); g.action = obj["data"]["action"].ToString(); g.giftId = Convert.ToInt32(obj["data"]["giftId"].ToString()); g.giftName = obj["data"]["giftName"].ToString(); g.num = obj["data"]["num"].ToString(); g.uid = obj["data"]["uid"].ToString(); if (HasDanmu != null) { HasDanmu(new LiveDanmuModel() { type = LiveDanmuTypes.Gift, value = g }); } } break; case "WELCOME": var w = new WelcomeMsgModel(); if (obj["data"] != null) { w.uname = obj["data"]["uname"].ToString(); w.uid = obj["data"]["uid"].ToString(); w.svip = obj["data"]["vip"].ToInt32() != 1; if (HasDanmu != null) { HasDanmu(new LiveDanmuModel() { type = LiveDanmuTypes.Welcome, value = w }); } } break; case "SYS_MSG": if (obj["msg"] != null) { if (HasDanmu != null) { HasDanmu(new LiveDanmuModel() { type = LiveDanmuTypes.SystemMsg, value = obj["msg"].ToString() }); } } break; default: break; } await Task.Delay(delay); } } // } } catch (Exception ex) { LogHelper.WriteLog("加载直播弹幕失败", LogType.ERROR, ex); } await Task.Delay(delay); } }