From e1d83befb4bde5eff7f984bc5e43679c70061d6a Mon Sep 17 00:00:00 2001 From: Muihd <1083092844@qq.com> Date: Sat, 28 Sep 2024 15:39:00 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BarrageGrab/AppSetting.cs | 6 ++ BarrageGrab/LiveCompanHelper.cs | 21 ++++- BarrageGrab/ObjectExtension.cs | 129 ++++++++++++++++++++++++++++- BarrageGrab/Proxy/TitaniumProxy.cs | 92 +++++++++++--------- BarrageGrab/WsBarrageServer.cs | 2 +- 5 files changed, 210 insertions(+), 40 deletions(-) diff --git a/BarrageGrab/AppSetting.cs b/BarrageGrab/AppSetting.cs index 5a08010..188c0bf 100644 --- a/BarrageGrab/AppSetting.cs +++ b/BarrageGrab/AppSetting.cs @@ -40,6 +40,7 @@ namespace BarrageGrab PollingInterval = int.Parse(AppSettings["pollingInterval"].Trim()); DisableLivePageScriptCache = bool.Parse(AppSettings["disableLivePageScriptCache"].Trim()); WebRoomIds = AppSettings["webRoomIds"].Trim().Split(',').Where(w => !string.IsNullOrWhiteSpace(w)).ToArray(); + LiveCompanPath = AppSettings["liveCompanPath"].Trim(); ConfigComPort(); ConfigFilter(); @@ -243,5 +244,10 @@ namespace BarrageGrab /// 是否启用串口过滤器脚本 /// public bool UseComPortFilter { get; set; } + + /// + /// 直播伴侣文件位置 + /// + public string LiveCompanPath { get; set; } = string.Empty; } } diff --git a/BarrageGrab/LiveCompanHelper.cs b/BarrageGrab/LiveCompanHelper.cs index 740e19c..7785ce0 100644 --- a/BarrageGrab/LiveCompanHelper.cs +++ b/BarrageGrab/LiveCompanHelper.cs @@ -28,8 +28,27 @@ namespace BarrageGrab { //获取快捷方式的目标路径 exePath = GetInkTargetPath(shortcutPath); + if (!File.Exists(exePath)) + { + exePath = ""; + Logger.LogWarn($"直播伴侣.lnk 所指向的exe文件位置 {exePath} 无效"); + } + } + else + { + Logger.LogInfo("未找到直播伴侣的桌面快捷方式"); } + //再从配置文件读取 + if (exePath.IsNullOrWhiteSpace()) + { + exePath = AppSetting.Current.LiveCompanPath; + if(!exePath.IsNullOrWhiteSpace() && !File.Exists(exePath)) + { + Logger.LogWarn($"所配置的 {exePath} 不存在"); + exePath = ""; + } + } return exePath; } @@ -41,7 +60,7 @@ namespace BarrageGrab var exePath = GetExePath(); if (string.IsNullOrEmpty(exePath)) { - Logger.LogWarn("未找到直播伴侣的exe文件,跳过环境设置"); + Logger.LogWarn("未找到直播伴侣.exe文件,跳过环境设置"); return; } diff --git a/BarrageGrab/ObjectExtension.cs b/BarrageGrab/ObjectExtension.cs index 7677490..916578d 100644 --- a/BarrageGrab/ObjectExtension.cs +++ b/BarrageGrab/ObjectExtension.cs @@ -191,6 +191,133 @@ namespace BarrageGrab if (cookies == null) return; var cookieCollection = dic.ToCookies(domain); cookies.Add(cookieCollection); - } + } + + /// + /// 将字典转为查询参数 + /// + /// + /// + public static string ToQueryParam(this IDictionary dic, bool encode = true) + { + if (dic == null || dic.Count == 0) + return string.Empty; + + var queryParams = dic.Select(kvp => kvp.Key + "=" + (encode ? WebUtility.UrlEncode(kvp.Value) : kvp.Value)); + return string.Join("&", queryParams); + + } + + /// + /// 赋值字典,没有则添加,有则覆盖 + /// + /// + /// + /// + /// + /// + public static void Set(this IDictionary dic, TKey key, TValue value) + { + if (dic.ContainsKey(key)) + { + dic[key] = value; + } + else + { + dic.Add(key, value); + } + } + + /// + /// 赋值字典,没有则添加,有则覆盖 + /// + /// + /// + /// + /// + public static void Set(this IDictionary dic, KeyValuePair kv) + { + dic.Set(kv.Key, kv.Value); + } + + /// + /// 获取Uri查询参数 + /// + /// + /// + /// + public static IDictionary GetQueryParams(this UriBuilder uri) + { + if (uri == null) + { + throw new ArgumentNullException(nameof(uri)); + } + + var queryParams = uri.Query.TrimStart('?'); + + if (string.IsNullOrEmpty(queryParams)) + { + return new Dictionary(); + } + + return queryParams + .Split('&') + .Select(param => param.Split('=')) + .ToDictionary( + keyValuePair => Uri.UnescapeDataString(keyValuePair[0]), + keyValuePair => Uri.UnescapeDataString(keyValuePair.Length > 1 ? keyValuePair[1] : "")); + } + + /// + /// + /// + /// + /// + public static void AddQueryParam(this UriBuilder uri, IEnumerable> vals) + { + if (uri == null) return; + var dic = uri.GetQueryParams(); + foreach (var item in vals) + { + dic.Set(item); + } + uri.Query = dic.ToQueryParam(); + } + + /// + /// 删除一个query项 + /// + /// + /// + public static void RemoveQueryParam(this UriBuilder uri, string key) + { + if (uri == null) return; + var dic = uri.GetQueryParams(); + dic.Remove(key); + if (dic.Count > 0) + { + uri.Query = "?" + dic.ToQueryParam(); + } + else + { + uri.Query = ""; + } + } + + /// + /// 添加参数 + /// + /// + /// + /// + /// + public static void AddQueryParam(this UriBuilder uri, string key, string value) + { + if (uri == null) return; + uri.AddQueryParam(new[] { + new KeyValuePair(key,value) + }); + } + } } diff --git a/BarrageGrab/Proxy/TitaniumProxy.cs b/BarrageGrab/Proxy/TitaniumProxy.cs index cce1351..4921deb 100644 --- a/BarrageGrab/Proxy/TitaniumProxy.cs +++ b/BarrageGrab/Proxy/TitaniumProxy.cs @@ -18,6 +18,11 @@ using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.StreamExtended.Network; using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography; +using HtmlDocument = HtmlAgilityPack.HtmlDocument; +using System.Net.Http; +using System.Text; +using BrotliSharpLib; +using System.IO.Compression; namespace BarrageGrab.Proxy { @@ -180,6 +185,11 @@ namespace BarrageGrab.Proxy } } + private bool CheckBrowser(string processName) + { + return AppSetting.Current.ProcessFilter.Contains(processName) && processName!="直播伴侣" && processName!= "douyin"; + } + private async Task ProxyServer_BeforeResponse(object sender, SessionEventArgs e) { string uri = e.HttpClient.Request.RequestUri.ToString(); @@ -333,7 +343,7 @@ namespace BarrageGrab.Proxy }); liveRoomInjectScript = scriptContext + liveRoomInjectScript; var html = await e.GetResponseBodyAsString(); - var doc = new HtmlAgilityPack.HtmlDocument(); + var doc = new HtmlDocument(); doc.LoadHtml(html); if (!liveRoomInjectScript.IsNullOrWhiteSpace()) @@ -370,7 +380,6 @@ namespace BarrageGrab.Proxy AppRuntime.RoomCaches.AddRoomInfoCache(roominfo); } - try { @@ -394,27 +403,11 @@ namespace BarrageGrab.Proxy //给script标签 src加上时间戳避免缓存 if (AppSetting.Current.DisableLivePageScriptCache) { - var scripts = doc.DocumentNode.SelectNodes("//script[@src]"); - if (scripts != null) - { - var ticks = DateTime.Now.Ticks; - foreach (var script in scripts) - { - var src = script.Attributes["src"].Value; - if (src.Contains("?")) - { - src += "&_t=" + ticks; - } - else - { - src += "?_t=" + ticks; - } - script.Attributes["src"].Value = src; - } - html = doc.DocumentNode.OuterHtml; - } + ScriptAddTocks(doc); } + html = doc.DocumentNode.OuterHtml; + e.SetResponseBodyString(html); } @@ -454,6 +447,38 @@ namespace BarrageGrab.Proxy } } + //给部分脚本加上时间戳避免缓存 + private void ScriptAddTocks(HtmlDocument doc) + { + var scripts = doc.DocumentNode.SelectNodes("//script[@src]"); + if (scripts != null) + { + var ticks = DateTime.Now.Ticks; + foreach (var script in scripts) + { + var src = script.Attributes["src"].Value; + + var srcUri = new Uri(src); + if (!CheckHost(srcUri.Host)) continue; + + var fileName = Path.GetFileName(src.Split('?')[0]); + //目前只需要用到相关这些js + if (!fileName.StartsWith("island") && !src.Contains(LIVE_SCRIPT_PATH)) continue; + + if (src.Contains("?")) + { + src += "&_t=" + ticks; + } + else + { + src += "?_t=" + ticks; + } + script.Attributes["src"].Value = src; + } + + } + } + //生成注入上下文 private string BuildContext(IDictionary constVals) { @@ -537,6 +562,12 @@ namespace BarrageGrab.Proxy string url = e.HttpClient.Request.RequestUri.ToString(); string hostname = e.HttpClient.Request.RequestUri.Host; + e.DecryptSsl = CheckHost(hostname); + } + + //检测域名白名单 + protected override bool CheckHost(string hostname) + { //需要解析SSL的域名 放在这里,全开会导致性能问题,应只解析业务需要的域名 var decryptSsls = new string[] { @@ -547,24 +578,11 @@ namespace BarrageGrab.Proxy if (decryptSsls.Contains(hostname)) { - e.DecryptSsl = true; - return; + return true; } - else - { - if (!CheckHost(hostname)) - { - e.DecryptSsl = false; - } - } - } - //检测域名白名单 - protected override bool CheckHost(string host) - { - host = host.Trim().ToLower(); - var succ = base.CheckHost(host); - return succ || host == SCRIPT_HOST || host == LIVE_HOST; + hostname = hostname.Trim().ToLower(); + return base.CheckHost(hostname); } //WebSocket 流读取 diff --git a/BarrageGrab/WsBarrageServer.cs b/BarrageGrab/WsBarrageServer.cs index 401fc2a..eabb0c2 100644 --- a/BarrageGrab/WsBarrageServer.cs +++ b/BarrageGrab/WsBarrageServer.cs @@ -201,7 +201,7 @@ namespace BarrageGrab private void PrintMsg(Msg msg, PackMsgType barType) { var rinfo = AppRuntime.RoomCaches.GetCachedWebRoomInfo(msg.RoomId.ToString()); - var roomName = (rinfo?.Owner?.Nickname ?? ("直播间" + (msg.WebRoomId.IsNullOrWhiteSpace() ? msg.RoomId.ToString() : msg.WebRoomId))); + var roomName = (rinfo?.Owner?.Nickname ?? ((msg.WebRoomId.IsNullOrWhiteSpace() ? msg.RoomId.ToString() : msg.WebRoomId))); var text = $"{DateTime.Now.ToString("HH:mm:ss")} [{roomName}] [{barType}]"; if (msg.User != null)