弹幕域名校验放宽
This commit is contained in:
@@ -11,12 +11,12 @@ namespace BarrageGrab
|
||||
{
|
||||
private delegate bool ControlCtrlDelegate(int CtrlType);
|
||||
|
||||
static WssBarrageService server = null;
|
||||
static WsBarrageService server = null;
|
||||
static void Main(string[] args)
|
||||
{
|
||||
SetConsoleCtrlHandler(cancelHandler, true);//捕获控制台关闭
|
||||
Console.Title = "抖音弹幕监听推送";
|
||||
server = new WssBarrageService();
|
||||
server = new WsBarrageService();
|
||||
server.StartListen();
|
||||
|
||||
while (true)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using Fiddler;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BarrageGrab.Proxy
|
||||
{
|
||||
@@ -8,6 +9,11 @@ namespace BarrageGrab.Proxy
|
||||
{
|
||||
event EventHandler<WsMessageEventArgs> OnWebSocketData;
|
||||
|
||||
/// <summary>
|
||||
/// 域名过滤器
|
||||
/// </summary>
|
||||
Func<string, bool> HostNameFilter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始监听
|
||||
/// </summary>
|
||||
|
||||
@@ -13,17 +13,10 @@ namespace BarrageGrab.Proxy
|
||||
{
|
||||
internal abstract class SystemProxy : ISystemProxy
|
||||
{
|
||||
//弹幕服务域名
|
||||
protected string[] barrageWsHostNames = new string[]
|
||||
{
|
||||
"webcast3-ws-web-hl.douyin.com",
|
||||
"webcast3-ws-web-lf.douyin.com",
|
||||
"frontier-im.douyin.com",
|
||||
"webcast100-ws-web-lq.amemv.com"
|
||||
};
|
||||
|
||||
|
||||
//https://live.douyin.com/webcast/gift/list/
|
||||
/// <summary>
|
||||
/// 域名过滤器
|
||||
/// </summary>
|
||||
public Func<string, bool> HostNameFilter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 接收到websocket消息事件
|
||||
@@ -33,17 +26,42 @@ namespace BarrageGrab.Proxy
|
||||
/// <summary>
|
||||
/// 代理端口
|
||||
/// </summary>
|
||||
public int ProxyPort { get => Appsetting.Instanse.ProxyPort; }
|
||||
public int ProxyPort { get => Appsetting.Current.ProxyPort; }
|
||||
|
||||
public abstract void Dispose();
|
||||
|
||||
public abstract void Start();
|
||||
|
||||
protected void SendWebSocketData(WsMessageEventArgs args)
|
||||
//https://live.douyin.com/webcast/gift/list/ [礼物数据接口]
|
||||
|
||||
/// <summary>
|
||||
/// 检测是否是业务相关链接
|
||||
/// </summary>
|
||||
/// <param name="host"></param>
|
||||
/// <returns></returns>
|
||||
protected bool CheckHost(string host)
|
||||
{
|
||||
var result = true;
|
||||
|
||||
if (HostNameFilter != null) return HostNameFilter(host);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 触发websocket消息事件
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
protected void FireWsEvent(WsMessageEventArgs args)
|
||||
{
|
||||
OnWebSocketData?.Invoke(this, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取进程名称
|
||||
/// </summary>
|
||||
/// <param name="processID"></param>
|
||||
/// <returns></returns>
|
||||
protected string GetProcessName(int processID)
|
||||
{
|
||||
var process = Process.GetProcessById(processID);
|
||||
@@ -54,7 +72,9 @@ namespace BarrageGrab.Proxy
|
||||
return $"<{processID}>";
|
||||
}
|
||||
|
||||
//注册系统代理
|
||||
/// <summary>
|
||||
/// 注册系统代理
|
||||
/// </summary>
|
||||
protected void RegisterSystemProxy()
|
||||
{
|
||||
RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace BarrageGrab.Proxy
|
||||
proxyServer.ServerCertificateValidationCallback += ProxyServer_ServerCertificateValidationCallback; ;
|
||||
proxyServer.BeforeResponse += ProxyServer_BeforeResponse;
|
||||
|
||||
explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any,ProxyPort, true);
|
||||
explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, ProxyPort, true);
|
||||
explicitEndPoint.BeforeTunnelConnectRequest += ExplicitEndPoint_BeforeTunnelConnectRequest;
|
||||
proxyServer.AddEndPoint(explicitEndPoint);
|
||||
}
|
||||
@@ -57,7 +57,6 @@ namespace BarrageGrab.Proxy
|
||||
{
|
||||
e.IsValid = true;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
@@ -65,20 +64,16 @@ namespace BarrageGrab.Proxy
|
||||
private async Task ProxyServer_BeforeResponse(object sender, SessionEventArgs e)
|
||||
{
|
||||
string hostname = e.HttpClient.Request.RequestUri.Host;
|
||||
if (!barrageWsHostNames.Contains(hostname)) return;
|
||||
|
||||
if (e.HttpClient.ConnectRequest?.TunnelType == TunnelType.Websocket)
|
||||
{
|
||||
e.DataReceived += WebSocket_DataReceived;
|
||||
}
|
||||
}
|
||||
|
||||
//List<string> hostlist = new List<string>();
|
||||
|
||||
private async Task ExplicitEndPoint_BeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e)
|
||||
{
|
||||
string hostname = e.HttpClient.Request.RequestUri.Host;
|
||||
if (!barrageWsHostNames.Contains(hostname))
|
||||
if (!CheckHost(hostname))
|
||||
{
|
||||
e.DecryptSsl = false;
|
||||
}
|
||||
@@ -93,12 +88,10 @@ namespace BarrageGrab.Proxy
|
||||
var processid = args.HttpClient.ProcessId.Value;
|
||||
|
||||
var frames = args.WebSocketDecoderReceive.Decode(e.Buffer, e.Offset, e.Count).ToList();
|
||||
//Console.WriteLine(frames.Count);
|
||||
|
||||
foreach (var frame in frames)
|
||||
{
|
||||
//Console.WriteLine(frame.GetText());
|
||||
base.SendWebSocketData(new WsMessageEventArgs()
|
||||
base.FireWsEvent(new WsMessageEventArgs()
|
||||
{
|
||||
ProcessID = processid,
|
||||
HostName = hostname,
|
||||
@@ -106,9 +99,6 @@ namespace BarrageGrab.Proxy
|
||||
ProcessName = base.GetProcessName(processid)
|
||||
});
|
||||
}
|
||||
//Console.WriteLine("获取到弹幕信息:" + hostname);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -6,26 +6,33 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
using BarrageGrab.JsonEntity;
|
||||
using BarrageGrab.ProtoEntity;
|
||||
using ColorConsole;
|
||||
using Fleck;
|
||||
using Newtonsoft.Json;
|
||||
using static BarrageGrab.ProtoEntity.Image;
|
||||
|
||||
namespace BarrageGrab
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 弹幕服务
|
||||
/// </summary>
|
||||
internal class WssBarrageService
|
||||
internal class WsBarrageService
|
||||
{
|
||||
WebSocketServer socketServer;
|
||||
Dictionary<string, UserState> socketList = new Dictionary<string, UserState>();
|
||||
Timer dieout = new Timer(10000);
|
||||
ConsoleWriter console = new ConsoleWriter();
|
||||
WssBarrageGrab grab = new WssBarrageGrab();
|
||||
Appsetting Appsetting = Appsetting.Get();
|
||||
Appsetting Appsetting = Appsetting.Current;
|
||||
bool debug = false;
|
||||
|
||||
public WssBarrageService()
|
||||
public WsBarrageService()
|
||||
{
|
||||
#if DEBUG
|
||||
debug = true;
|
||||
#endif
|
||||
var socket = new WebSocketServer($"ws://127.0.0.1:{Appsetting.WsProt}");
|
||||
socket.RestartAfterListenError = true;//异常重启
|
||||
|
||||
@@ -44,36 +51,46 @@ namespace BarrageGrab
|
||||
//dieout.Start();
|
||||
}
|
||||
|
||||
private MsgUser GetUser(dynamic obj)
|
||||
private bool CheckRoomId(long roomid)
|
||||
{
|
||||
return Appsetting.RoomIds.Length == 0 || Appsetting.RoomIds.Contains(roomid);
|
||||
}
|
||||
|
||||
//解析用户
|
||||
private MsgUser GetUser(ProtoEntity.User data)
|
||||
{
|
||||
MsgUser user = new MsgUser()
|
||||
{
|
||||
DisplayId = obj.User.displayId,
|
||||
Gender = obj.User.Gender,
|
||||
Id = obj.User.Id,
|
||||
Level = obj.User.Level,
|
||||
Nickname = obj.User.Nickname
|
||||
DisplayId = data.displayId,
|
||||
Gender = data.Gender,
|
||||
Id = data.Id,
|
||||
Level = data.Level,
|
||||
Nickname = data.Nickname
|
||||
};
|
||||
return user;
|
||||
}
|
||||
|
||||
//粉丝团
|
||||
private void Grab_OnFansclubMessage(object sender, ProtoEntity.FansclubMessage e)
|
||||
{
|
||||
if (!CheckRoomId(e.commonInfo.roomId)) return;
|
||||
var enty = new FansclubMsg()
|
||||
{
|
||||
Content = e.Content,
|
||||
RoomId = e.commonInfo.roomId,
|
||||
Type = e.Type,
|
||||
User = GetUser(e)
|
||||
User = GetUser(e.User)
|
||||
};
|
||||
Print($"[粉丝团消息] {enty.User.GenderToString()} " + enty.Content, ConsoleColor.Blue);
|
||||
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.粉丝团信息);
|
||||
Print(enty.User.GenderToString() + " " + enty.Content, ConsoleColor.Blue, BarrageMsgType.粉丝团消息);
|
||||
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.粉丝团消息);
|
||||
var json = JsonConvert.SerializeObject(pack);
|
||||
this.Broadcast(json);
|
||||
}
|
||||
|
||||
//统计消息
|
||||
private void Grab_OnRoomUserSeqMessage(object sender, ProtoEntity.RoomUserSeqMessage e)
|
||||
{
|
||||
if (!CheckRoomId(e.Common.roomId)) return;
|
||||
var enty = new UserSeqMsg()
|
||||
{
|
||||
OnlineUserCount = e.Total,
|
||||
@@ -84,92 +101,113 @@ namespace BarrageGrab
|
||||
Content = $"当前直播间人数 {e.onlineUserForAnchor},累计直播间人数 {e.totalPvForAnchor}",
|
||||
User = null
|
||||
};
|
||||
Print($"[直播间统计] " + enty.Content, ConsoleColor.Magenta);
|
||||
Print(enty.Content, ConsoleColor.Magenta, BarrageMsgType.直播间统计);
|
||||
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.直播间统计);
|
||||
var json = JsonConvert.SerializeObject(pack);
|
||||
this.Broadcast(json);
|
||||
}
|
||||
|
||||
//礼物
|
||||
private void Grab_OnGiftMessage(object sender, ProtoEntity.GiftMessage e)
|
||||
{
|
||||
if (!CheckRoomId(e.Common.roomId)) return;
|
||||
|
||||
var enty = new GiftMsg()
|
||||
{
|
||||
RoomId = e.Common.roomId,
|
||||
Content = e.Common.Describe,
|
||||
DiamondCount = e.Gift.diamondCount,
|
||||
GiftCount = e.repeatCount,
|
||||
GroupCount = e.groupCount,
|
||||
GiftId = e.giftId,
|
||||
GiftName = e.Gift.Name,
|
||||
User = GetUser(e)
|
||||
User = GetUser(e.User)
|
||||
};
|
||||
Print($"[礼物消息] " + $"{enty.User.GenderToString()} " + enty.Content, ConsoleColor.Red);
|
||||
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.送礼);
|
||||
|
||||
Print($"{enty.User.GenderToString()} {enty.Content}", ConsoleColor.Red, BarrageMsgType.礼物消息);
|
||||
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.礼物消息);
|
||||
var json = JsonConvert.SerializeObject(pack);
|
||||
this.Broadcast(json);
|
||||
}
|
||||
|
||||
//关注
|
||||
private void Grab_OnSocialMessage(object sender, ProtoEntity.SocialMessage e)
|
||||
{
|
||||
if (!CheckRoomId(e.Common.roomId)) return;
|
||||
|
||||
var enty = new Msg()
|
||||
{
|
||||
Content = $"{e.User.Nickname} 关注了主播",
|
||||
RoomId = e.Common.roomId,
|
||||
User = GetUser(e)
|
||||
User = GetUser(e.User)
|
||||
};
|
||||
Print($"[关注消息] {enty.User.GenderToString()} " + enty.Content, ConsoleColor.Yellow);
|
||||
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.关注主播);
|
||||
Print($"{enty.User.GenderToString()} {enty.Content}", ConsoleColor.Yellow, BarrageMsgType.关注消息);
|
||||
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.关注消息);
|
||||
var json = JsonConvert.SerializeObject(pack);
|
||||
this.Broadcast(json);
|
||||
}
|
||||
|
||||
//来了
|
||||
private void Grab_OnMemberMessage(object sender, ProtoEntity.MemberMessage e)
|
||||
{
|
||||
var enty = new Msg()
|
||||
if (!CheckRoomId(e.Common.roomId)) return;
|
||||
|
||||
var enty = new JsonEntity.MemberMessage()
|
||||
{
|
||||
Content = $"{e.User.Nickname} 来了",
|
||||
Content = $"{e.User.Nickname} 来了 直播间人数:{e.memberCount}",
|
||||
RoomId = e.Common.roomId,
|
||||
User = GetUser(e)
|
||||
CurrentCount = e.memberCount,
|
||||
User = GetUser(e.User)
|
||||
};
|
||||
Print($"[进直播间] {enty.User.GenderToString()} " + enty.Content, ConsoleColor.Green);
|
||||
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.进入直播间);
|
||||
Print($"{enty.User.GenderToString()} {enty.Content}", ConsoleColor.Green, BarrageMsgType.进直播间);
|
||||
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.进直播间);
|
||||
var json = JsonConvert.SerializeObject(pack);
|
||||
this.Broadcast(json);
|
||||
}
|
||||
|
||||
//点赞
|
||||
private void Grab_OnLikeMessage(object sender, ProtoEntity.LikeMessage e)
|
||||
{
|
||||
if (!CheckRoomId(e.Common.roomId)) return;
|
||||
|
||||
var enty = new LikeMsg()
|
||||
{
|
||||
Count = e.Count,
|
||||
Content = $"{e.User.Nickname} 为主播点了{e.Count}个赞",
|
||||
Content = $"{e.User.Nickname} 为主播点了{e.Count}个赞,总点赞{e.Total}",
|
||||
RoomId = e.Common.roomId,
|
||||
User = GetUser(e)
|
||||
Total = e.Total,
|
||||
User = GetUser(e.User)
|
||||
};
|
||||
Print($"[点赞消息] {enty.User.GenderToString()} " + enty.Content, ConsoleColor.Cyan);
|
||||
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.点赞);
|
||||
Print($"{enty.User.GenderToString()} {enty.Content}", ConsoleColor.Cyan, BarrageMsgType.点赞消息);
|
||||
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.点赞消息);
|
||||
var json = JsonConvert.SerializeObject(pack);
|
||||
this.Broadcast(json);
|
||||
}
|
||||
|
||||
//弹幕
|
||||
private void Grab_OnChatMessage(object sender, ProtoEntity.ChatMessage e)
|
||||
{
|
||||
if (!CheckRoomId(e.Common.roomId)) return;
|
||||
|
||||
var enty = new Msg()
|
||||
{
|
||||
Content = e.Content,
|
||||
RoomId = e.Common.roomId,
|
||||
User = GetUser(e)
|
||||
User = GetUser(e.User)
|
||||
};
|
||||
Print($"[弹幕消息] {enty.User.GenderToString()} {enty.User.Nickname}: {enty.Content}", ConsoleColor.White);
|
||||
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.消息);
|
||||
Print($"{enty.User.GenderToString()} {enty.User.Nickname}: {enty.Content}", ConsoleColor.White, BarrageMsgType.弹幕消息);
|
||||
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.弹幕消息);
|
||||
var json = JsonConvert.SerializeObject(pack);
|
||||
this.Broadcast(json);
|
||||
}
|
||||
|
||||
private void Print(string msg, ConsoleColor color)
|
||||
private void Print(string msg, ConsoleColor color, BarrageMsgType bartype)
|
||||
{
|
||||
if (!Appsetting.PrintFilter.Any(a => a == bartype.GetHashCode())) return;
|
||||
|
||||
if (Appsetting.PrintBarrage)
|
||||
{
|
||||
console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")} " + msg + "\n", color);
|
||||
console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")} [{bartype.ToString()}] " + msg + "\n", color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,6 +258,9 @@ namespace BarrageGrab
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始监听
|
||||
/// </summary>
|
||||
public void StartListen()
|
||||
{
|
||||
this.grab.Start(); //启动代理
|
||||
@@ -19,9 +19,18 @@ namespace BarrageGrab
|
||||
{
|
||||
//ISystemProxy proxy = new FiddlerProxy();
|
||||
ISystemProxy proxy = new TitaniumProxy();
|
||||
Appsetting appsetting = Appsetting.Get();
|
||||
Appsetting appsetting = Appsetting.Current;
|
||||
ConsoleWriter console = new ConsoleWriter();
|
||||
|
||||
//已知的弹幕域名服务器
|
||||
string[] wsHostNames = new string[]
|
||||
{
|
||||
"webcast3-ws-web-hl.douyin.com",
|
||||
"webcast3-ws-web-lf.douyin.com",
|
||||
"frontier-im.douyin.com",
|
||||
"webcast100-ws-web-lq.amemv.com"
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 进入直播间
|
||||
/// </summary>
|
||||
@@ -65,6 +74,7 @@ namespace BarrageGrab
|
||||
public WssBarrageGrab()
|
||||
{
|
||||
proxy.OnWebSocketData += Proxy_OnWebSocketData;
|
||||
proxy.HostNameFilter = HostNameChecker;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
@@ -77,6 +87,16 @@ namespace BarrageGrab
|
||||
proxy.Dispose();
|
||||
}
|
||||
|
||||
//域名过滤器
|
||||
private bool HostNameChecker(string hostName)
|
||||
{
|
||||
if (hostName.StartsWith("webcast")) return true;
|
||||
|
||||
if (wsHostNames.Any(a => a.ToLower() == hostName.ToLower())) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//gzip解压缩
|
||||
private byte[] Decompress(byte[] zippedData)
|
||||
{
|
||||
@@ -96,6 +116,7 @@ namespace BarrageGrab
|
||||
return outBuffer.ToArray();
|
||||
}
|
||||
|
||||
//ws数据处理
|
||||
private void Proxy_OnWebSocketData(object sender, WsMessageEventArgs e)
|
||||
{
|
||||
if (!appsetting.FilterProcess.Contains(e.ProcessName)) return;
|
||||
@@ -123,6 +144,7 @@ namespace BarrageGrab
|
||||
catch (Exception) { }
|
||||
}
|
||||
|
||||
//发送事件
|
||||
private void DoMessage(Message msg)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ProtoEntity\Messages.cs" />
|
||||
<Compile Include="ProtoEntity\Wss.cs" />
|
||||
<Compile Include="WssBarrageService.cs" />
|
||||
<Compile Include="WsBarrageService.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
|
||||
Reference in New Issue
Block a user