2022-10-06 17:44:08 +08:00
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.IO.Compression;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using ProtoBuf;
|
2023-03-04 14:52:04 +08:00
|
|
|
using BarrageGrab.Proxy;
|
2023-03-28 23:06:09 +08:00
|
|
|
using BarrageGrab.Proxy.ProxyEventArgs;
|
2023-08-17 20:37:22 +08:00
|
|
|
using BarrageGrab.Modles.ProtoEntity;
|
2022-10-06 17:44:08 +08:00
|
|
|
|
|
|
|
|
namespace BarrageGrab
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 本机Wss弹幕抓取器
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class WssBarrageGrab : IDisposable
|
|
|
|
|
{
|
2023-03-04 14:52:04 +08:00
|
|
|
//ISystemProxy proxy = new FiddlerProxy();
|
|
|
|
|
ISystemProxy proxy = new TitaniumProxy();
|
2024-03-29 17:46:24 +08:00
|
|
|
AppSetting appsetting = AppSetting.Current;
|
2022-10-06 17:44:08 +08:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 进入直播间
|
|
|
|
|
/// </summary>
|
2023-09-24 12:47:55 +08:00
|
|
|
public event EventHandler<RoomMessageEventArgs<MemberMessage>> OnMemberMessage;
|
2022-10-06 17:44:08 +08:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 关注
|
|
|
|
|
/// </summary>
|
2023-09-24 12:47:55 +08:00
|
|
|
public event EventHandler<RoomMessageEventArgs<SocialMessage>> OnSocialMessage;
|
2022-10-06 17:44:08 +08:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 聊天
|
|
|
|
|
/// </summary>
|
2023-09-24 12:47:55 +08:00
|
|
|
public event EventHandler<RoomMessageEventArgs<ChatMessage>> OnChatMessage;
|
2022-10-06 17:44:08 +08:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 点赞
|
|
|
|
|
/// </summary>
|
2023-09-24 12:47:55 +08:00
|
|
|
public event EventHandler<RoomMessageEventArgs<LikeMessage>> OnLikeMessage;
|
2022-10-06 17:44:08 +08:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 礼物
|
|
|
|
|
/// </summary>
|
2023-09-24 12:47:55 +08:00
|
|
|
public event EventHandler<RoomMessageEventArgs<GiftMessage>> OnGiftMessage;
|
2022-10-06 17:44:08 +08:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 直播间统计
|
|
|
|
|
/// </summary>
|
2023-09-24 12:47:55 +08:00
|
|
|
public event EventHandler<RoomMessageEventArgs<RoomUserSeqMessage>> OnRoomUserSeqMessage;
|
2022-10-06 17:44:08 +08:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 直播间状态变更
|
|
|
|
|
/// </summary>
|
2023-09-24 12:47:55 +08:00
|
|
|
public event EventHandler<RoomMessageEventArgs<ControlMessage>> OnControlMessage;
|
2022-10-06 17:44:08 +08:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 粉丝团消息
|
|
|
|
|
/// </summary>
|
2023-09-24 12:47:55 +08:00
|
|
|
public event EventHandler<RoomMessageEventArgs<FansclubMessage>> OnFansclubMessage;
|
2022-10-06 17:44:08 +08:00
|
|
|
|
2023-11-14 20:29:18 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// 代理
|
|
|
|
|
/// </summary>
|
2023-11-16 09:26:40 +08:00
|
|
|
public ISystemProxy Proxy { get { return proxy; } }
|
2023-11-14 20:29:18 +08:00
|
|
|
|
2022-10-06 17:44:08 +08:00
|
|
|
public WssBarrageGrab()
|
|
|
|
|
{
|
|
|
|
|
proxy.OnWebSocketData += Proxy_OnWebSocketData;
|
2023-08-17 20:37:22 +08:00
|
|
|
proxy.OnFetchResponse += Proxy_OnFetchResponse;
|
2023-09-24 12:47:55 +08:00
|
|
|
}
|
2022-10-06 17:44:08 +08:00
|
|
|
|
|
|
|
|
public void Start()
|
|
|
|
|
{
|
|
|
|
|
proxy.Start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
2023-08-17 20:37:22 +08:00
|
|
|
proxy.Dispose();
|
2022-10-06 17:44:08 +08:00
|
|
|
}
|
|
|
|
|
|
2023-03-09 00:33:03 +08:00
|
|
|
|
2022-10-06 17:44:08 +08:00
|
|
|
//gzip解压缩
|
|
|
|
|
private byte[] Decompress(byte[] zippedData)
|
|
|
|
|
{
|
|
|
|
|
MemoryStream ms = new MemoryStream(zippedData);
|
|
|
|
|
GZipStream compressedzipStream = new GZipStream(ms, CompressionMode.Decompress);
|
|
|
|
|
MemoryStream outBuffer = new MemoryStream();
|
|
|
|
|
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();
|
|
|
|
|
return outBuffer.ToArray();
|
|
|
|
|
}
|
2023-03-09 01:23:46 +08:00
|
|
|
|
2023-03-09 00:33:03 +08:00
|
|
|
//ws数据处理
|
2023-03-04 14:52:04 +08:00
|
|
|
private void Proxy_OnWebSocketData(object sender, WsMessageEventArgs e)
|
2022-10-06 17:44:08 +08:00
|
|
|
{
|
2023-03-09 01:23:46 +08:00
|
|
|
if (!appsetting.ProcessFilter.Contains(e.ProcessName)) return;
|
2023-03-04 14:52:04 +08:00
|
|
|
var buff = e.Payload;
|
2022-10-06 17:44:08 +08:00
|
|
|
if (buff.Length == 0) return;
|
2023-08-17 20:37:22 +08:00
|
|
|
//如果需要Gzip解压缩,但是开头字节不符合Gzip特征字节 则不处理
|
|
|
|
|
if (e.NeedDecompress && buff[0] != 0x08) return;
|
2022-10-06 17:44:08 +08:00
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var enty = Serializer.Deserialize<WssResponse>(new ReadOnlyMemory<byte>(buff));
|
|
|
|
|
if (enty == null) return;
|
|
|
|
|
|
|
|
|
|
//检测包格式
|
|
|
|
|
if (!enty.Headers.Any(a => a.Key == "compress_type" && a.Value == "gzip")) return;
|
|
|
|
|
|
2023-08-17 20:37:22 +08:00
|
|
|
byte[] allBuff;
|
2022-10-06 17:44:08 +08:00
|
|
|
//解压gzip
|
2023-08-17 20:37:22 +08:00
|
|
|
allBuff = e.NeedDecompress ? Decompress(enty.Payload) : enty.Payload;
|
|
|
|
|
var response = Serializer.Deserialize<Response>(new ReadOnlyMemory<byte>(allBuff));
|
2023-03-09 01:23:46 +08:00
|
|
|
|
2024-03-10 04:03:39 +08:00
|
|
|
|
2023-09-24 12:47:55 +08:00
|
|
|
response.Messages.ForEach(f => DoMessage(f,e.ProcessName));
|
2022-10-06 17:44:08 +08:00
|
|
|
}
|
2024-04-26 00:47:08 +08:00
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Logger.LogError(ex,$"处理弹幕数据包时出错:{ex.Message}");
|
|
|
|
|
}
|
2022-10-06 17:44:08 +08:00
|
|
|
}
|
|
|
|
|
|
2023-08-17 20:37:22 +08:00
|
|
|
//http 数据处理
|
|
|
|
|
private void Proxy_OnFetchResponse(object sender, HttpResponseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
var payload = e.HttpClient.Response.Body;
|
2024-01-09 22:39:08 +08:00
|
|
|
|
2023-08-17 20:37:22 +08:00
|
|
|
var response = Serializer.Deserialize<Response>(new ReadOnlyMemory<byte>(payload));
|
|
|
|
|
|
|
|
|
|
response.Messages.ForEach(f =>
|
|
|
|
|
{
|
2023-09-24 12:47:55 +08:00
|
|
|
DoMessage(f,e.ProcessName);
|
2023-08-17 20:37:22 +08:00
|
|
|
});
|
2023-09-24 12:47:55 +08:00
|
|
|
}
|
2023-08-17 20:37:22 +08:00
|
|
|
|
2023-04-01 00:09:07 +08:00
|
|
|
//用于缓存接收过的消息ID,判断是否重复接收
|
2023-08-17 20:37:22 +08:00
|
|
|
Dictionary<string, List<long>> msgDic = new Dictionary<string, List<long>>();
|
2023-03-28 23:06:09 +08:00
|
|
|
|
2023-03-09 00:33:03 +08:00
|
|
|
//发送事件
|
2023-09-24 12:47:55 +08:00
|
|
|
private void DoMessage(Message msg,string processName)
|
2023-08-17 20:37:22 +08:00
|
|
|
{
|
2023-04-01 00:09:07 +08:00
|
|
|
List<long> msgIdList;
|
|
|
|
|
if (msgDic.ContainsKey(msg.Method))
|
|
|
|
|
{
|
2023-08-17 20:37:22 +08:00
|
|
|
msgIdList = msgDic[msg.Method];
|
2023-04-01 00:09:07 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-04-01 00:22:34 +08:00
|
|
|
msgIdList = new List<long>(320);
|
2023-04-01 00:09:07 +08:00
|
|
|
msgDic.Add(msg.Method, msgIdList);
|
|
|
|
|
}
|
|
|
|
|
if (msgIdList.Contains(msg.msgId))
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
msgIdList.Add(msg.msgId);
|
2023-04-01 00:22:34 +08:00
|
|
|
if (msgIdList.Count > 300) msgIdList.RemoveAt(0);
|
2023-08-17 20:37:22 +08:00
|
|
|
|
2022-10-06 17:44:08 +08:00
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
switch (msg.Method)
|
|
|
|
|
{
|
2022-11-05 16:38:08 +08:00
|
|
|
//来了
|
2022-10-06 17:44:08 +08:00
|
|
|
case "WebcastMemberMessage":
|
|
|
|
|
{
|
|
|
|
|
var arg = Serializer.Deserialize<MemberMessage>(new ReadOnlyMemory<byte>(msg.Payload));
|
2023-09-24 12:47:55 +08:00
|
|
|
this.OnMemberMessage?.Invoke(this, new RoomMessageEventArgs<MemberMessage>(processName,arg));
|
2022-10-06 17:44:08 +08:00
|
|
|
break;
|
|
|
|
|
}
|
2022-11-05 16:38:08 +08:00
|
|
|
//关注
|
2022-10-06 17:44:08 +08:00
|
|
|
case "WebcastSocialMessage":
|
|
|
|
|
{
|
2023-09-24 12:47:55 +08:00
|
|
|
var arg = Serializer.Deserialize<SocialMessage>(new ReadOnlyMemory<byte>(msg.Payload));
|
|
|
|
|
this.OnSocialMessage?.Invoke(this, new RoomMessageEventArgs<SocialMessage>(processName, arg));
|
2022-10-06 17:44:08 +08:00
|
|
|
break;
|
|
|
|
|
}
|
2022-11-05 16:38:08 +08:00
|
|
|
//消息
|
2022-10-06 17:44:08 +08:00
|
|
|
case "WebcastChatMessage":
|
|
|
|
|
{
|
|
|
|
|
var arg = Serializer.Deserialize<ChatMessage>(new ReadOnlyMemory<byte>(msg.Payload));
|
2023-09-24 12:47:55 +08:00
|
|
|
this.OnChatMessage?.Invoke(this, new RoomMessageEventArgs<ChatMessage>(processName, arg));
|
2022-10-06 17:44:08 +08:00
|
|
|
break;
|
|
|
|
|
}
|
2022-11-05 16:38:08 +08:00
|
|
|
//点赞
|
2022-10-06 17:44:08 +08:00
|
|
|
case "WebcastLikeMessage":
|
|
|
|
|
{
|
|
|
|
|
var arg = Serializer.Deserialize<LikeMessage>(new ReadOnlyMemory<byte>(msg.Payload));
|
2023-09-24 12:47:55 +08:00
|
|
|
this.OnLikeMessage?.Invoke(this, new RoomMessageEventArgs<LikeMessage>(processName, arg));
|
2022-10-06 17:44:08 +08:00
|
|
|
break;
|
|
|
|
|
}
|
2022-11-05 16:38:08 +08:00
|
|
|
//礼物
|
2022-10-06 17:44:08 +08:00
|
|
|
case "WebcastGiftMessage":
|
|
|
|
|
{
|
|
|
|
|
var arg = Serializer.Deserialize<GiftMessage>(new ReadOnlyMemory<byte>(msg.Payload));
|
2023-09-24 12:47:55 +08:00
|
|
|
this.OnGiftMessage?.Invoke(this, new RoomMessageEventArgs<GiftMessage>(processName, arg));
|
2022-10-06 17:44:08 +08:00
|
|
|
break;
|
|
|
|
|
}
|
2022-11-05 16:38:08 +08:00
|
|
|
//直播间统计
|
2022-10-06 17:44:08 +08:00
|
|
|
case "WebcastRoomUserSeqMessage":
|
|
|
|
|
{
|
|
|
|
|
var arg = Serializer.Deserialize<RoomUserSeqMessage>(new ReadOnlyMemory<byte>(msg.Payload));
|
2023-09-24 12:47:55 +08:00
|
|
|
this.OnRoomUserSeqMessage?.Invoke(this, new RoomMessageEventArgs<RoomUserSeqMessage>(processName, arg));
|
2022-10-06 17:44:08 +08:00
|
|
|
break;
|
|
|
|
|
}
|
2022-11-05 16:38:08 +08:00
|
|
|
//直播间状态变更
|
2022-10-06 17:44:08 +08:00
|
|
|
case "WebcastControlMessage":
|
|
|
|
|
{
|
|
|
|
|
var arg = Serializer.Deserialize<ControlMessage>(new ReadOnlyMemory<byte>(msg.Payload));
|
2023-09-24 12:47:55 +08:00
|
|
|
this.OnControlMessage?.Invoke(this, new RoomMessageEventArgs<ControlMessage>(processName, arg));
|
2022-10-06 17:44:08 +08:00
|
|
|
break;
|
|
|
|
|
}
|
2022-11-05 16:38:08 +08:00
|
|
|
//粉丝团消息
|
2022-10-06 17:44:08 +08:00
|
|
|
case "WebcastFansclubMessage":
|
|
|
|
|
{
|
|
|
|
|
var arg = Serializer.Deserialize<FansclubMessage>(new ReadOnlyMemory<byte>(msg.Payload));
|
2023-09-24 12:47:55 +08:00
|
|
|
this.OnFansclubMessage?.Invoke(this, new RoomMessageEventArgs<FansclubMessage>(processName, arg));
|
2022-10-06 17:44:08 +08:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-23 16:43:21 +08:00
|
|
|
catch (Exception ex)
|
2022-10-06 17:44:08 +08:00
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-03-09 01:23:46 +08:00
|
|
|
|
2023-09-24 12:47:55 +08:00
|
|
|
public class RoomMessageEventArgs<T> : EventArgs where T : class
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 进程名
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Process { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 消息
|
|
|
|
|
/// </summary>
|
|
|
|
|
public T Message { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public RoomMessageEventArgs()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public RoomMessageEventArgs(string process, T data)
|
|
|
|
|
{
|
|
|
|
|
this.Process = process;
|
|
|
|
|
this.Message = data;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-10-06 17:44:08 +08:00
|
|
|
}
|
|
|
|
|
}
|