diff --git a/BarrageGrab/AppRuntime.cs b/BarrageGrab/AppRuntime.cs new file mode 100644 index 0000000..35b792c --- /dev/null +++ b/BarrageGrab/AppRuntime.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; +using BarrageGrab.Modles; +using ColorConsole; + +namespace BarrageGrab +{ + /// + /// 程序运行时信息 + /// + public static class AppRuntime + { + /// + /// Ws弹幕服务示例 + /// + public static WsBarrageService WssService { get; private set; } = new WsBarrageService(); + + /// + /// 程序进程信息 + /// + public static Process CurrentProcess { get; private set; } = System.Diagnostics.Process.GetCurrentProcess(); + + + static AppRuntime() + { + + } + } +} diff --git a/BarrageGrab/ObjectExtension.cs b/BarrageGrab/ObjectExtension.cs new file mode 100644 index 0000000..afcc6f3 --- /dev/null +++ b/BarrageGrab/ObjectExtension.cs @@ -0,0 +1,175 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using System.Web; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace BarrageGrab +{ + /// + /// 扩展类 + /// + public static class ObjectExtension + { + /// + /// 判断字符串是否为空或空白 + /// + public static bool IsNullOrWhiteSpace(this string str) => string.IsNullOrWhiteSpace(str); + + /// + /// 判断字符串是否为空 + /// + public static bool IsNullOrEmpty(this string str) => string.IsNullOrEmpty(str); + + /// + /// 转为Json + /// + /// + /// + public static string ToJson(this object obj) + { + if (obj is string) + { + return obj.ToString(); + } + return JsonConvert.SerializeObject(obj); + } + + /// + /// 转为对象 + /// + /// + /// + /// + public static T AsObject(this string json) + { + return JsonConvert.DeserializeObject(json); + } + + /// + /// 获取Value或其Value默认值 + /// + public static TValue ValueOrDefault(this IDictionary dic, Tkey key) + { + if (dic.ContainsKey(key)) + { + return dic[key]; + } + return default; + } + + /// + /// 获取Value或其Value默认值 + /// + public static TValue ValueOrDefault(this IDictionary dic, Tkey key, TValue defaultValue) + { + if (dic.ContainsKey(key)) + { + return dic[key]; + } + return defaultValue; + } + + /// + /// 遍历集合 + /// + public static void Foreach(this IEnumerable list, Action func) + { + foreach (var item in list) func(item); + } + + /// + /// 遍历集合 + /// + public static void Foreach(this IEnumerable list, Action func) + { + int i = 0; + foreach (var item in list) func(item, i++); + } + + + public static CookieCollection ToCookies(this string cookieStr, string domain) + { + var cookies = new CookieCollection(); + if (!string.IsNullOrEmpty(cookieStr)) + { + var cookieArray = cookieStr.Split(';'); + foreach (var cookie in cookieArray) + { + var cookieParts = cookie.Split('='); + if (cookieParts.Length == 2) + { + var cookieName = cookieParts[0].Trim(); + var cookieValue = cookieParts[1].Trim(); + var newCookie = new Cookie(cookieName, Uri.EscapeDataString(cookieValue)); + newCookie.Path = "/"; + newCookie.Domain = domain; + cookies.Add(newCookie); + } + } + } + return cookies; + } + + /// + /// 追加另一个字典 + /// + /// + /// + /// + public static IDictionary Append(this IEnumerable> dic, IEnumerable> other) + { + var res = new Dictionary(); + foreach (var item in dic) + { + res.Add(item.Key, item.Value); + } + foreach (var item in other) + { + if (res.ContainsKey(item.Key)) + { + res[item.Key] = item.Value; + } + else + { + res.Add(item.Key, item.Value); + } + } + return res; + } + + + /// + /// 转换为Cookie对象列表 + /// + /// + /// + /// + public static CookieCollection ToCookies(this IDictionary dic, string domain) + { + var cookieCollection = new CookieCollection(); + foreach (var item in dic) + { + cookieCollection.Add(new Cookie(item.Key, item.Value, "/", domain)); + } + return cookieCollection; + } + + /// + /// 添加Cookie + /// + /// + /// + /// + public static void PushCookies(this CookieContainer cookies, string domain, IDictionary dic) + { + if (cookies == null) return; + var cookieCollection = dic.ToCookies(domain); + cookies.Add(cookieCollection); + } + } +} diff --git a/BarrageGrab/Program.cs b/BarrageGrab/Program.cs index b74f62f..b219958 100644 --- a/BarrageGrab/Program.cs +++ b/BarrageGrab/Program.cs @@ -1,48 +1,49 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net.Sockets; +using System.Net; using System.Runtime.InteropServices; using System.Text; using System.Threading; -using System.Threading.Tasks; namespace BarrageGrab { public class Program { - private delegate bool ControlCtrlDelegate(int CtrlType); - - static WsBarrageService server = null; static void Main(string[] args) - { - SetConsoleCtrlHandler(cancelHandler, true);//捕获控制台关闭 - Console.Title = "抖音弹幕监听推送"; - DisableQuickEditMode(); - bool exited = false; - server = new WsBarrageService(); - server.StartListen(); - server.OnClose += (s, e) => + { + if (CheckAlreadyRunning()) { - //退出程序 + Console.WriteLine("已经有一个监听程序在运行,按任意键退出..."); + Console.ReadKey(); + return; + } + + WinApi.SetConsoleCtrlHandler(cancelHandler, true);//捕获控制台关闭 + WinApi.DisableQuickEditMode();//禁用控制台快速编辑模式 + Console.Title = "抖音弹幕监听推送"; + + bool exited = false; + AppRuntime.WssService.StartListen(); + AppRuntime.WssService.OnClose += (s, e) => + { + //退出程序 exited = true; }; while (!exited) - { + { Thread.Sleep(500); } - Console.WriteLine("服务器已关闭..."); + Console.WriteLine("服务器已关闭..."); + //退出程序,不显示 按任意键退出 - Environment.Exit(0); + Environment.Exit(0); } - - [DllImport("kernel32.dll")] - private static extern bool SetConsoleCtrlHandler(ControlCtrlDelegate HandlerRoutine, bool Add); - private static ControlCtrlDelegate cancelHandler = new ControlCtrlDelegate(HandlerRoutine); - - public static bool HandlerRoutine(int CtrlType) + private static WinApi.ControlCtrlDelegate cancelHandler = new WinApi.ControlCtrlDelegate((CtrlType) => { switch (CtrlType) { @@ -52,39 +53,21 @@ namespace BarrageGrab break; case 2: Console.WriteLine("2工具被强制关闭");//按控制台关闭按钮关闭 - server.Close(); + AppRuntime.WssService.Close(); break; } return false; - } + }); - - const int STD_INPUT_HANDLE = -10; - const uint ENABLE_QUICK_EDIT_MODE = 0x0040; - [DllImport("kernel32.dll", SetLastError = true)] - internal static extern IntPtr GetStdHandle(int hConsoleHandle); - [DllImport("kernel32.dll", SetLastError = true)] - internal static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint mode); - [DllImport("kernel32.dll", SetLastError = true)] - internal static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint mode); - - public static void EnableQuickEditMode() + //检测程序是否多开 + private static bool CheckAlreadyRunning() { - IntPtr hStdin = GetStdHandle(STD_INPUT_HANDLE); - uint mode; - GetConsoleMode(hStdin, out mode); - mode |= ENABLE_QUICK_EDIT_MODE; - SetConsoleMode(hStdin, mode); + const string mutexName = "DyBarrageGrab"; + // Try to create a new named mutex. + using (Mutex mutex = new Mutex(true, mutexName, out bool createdNew)) + { + return !createdNew; + } } - - public static void DisableQuickEditMode() - { - IntPtr hStdin = GetStdHandle(STD_INPUT_HANDLE); - uint mode; - GetConsoleMode(hStdin, out mode); - mode &= ~ENABLE_QUICK_EDIT_MODE; - SetConsoleMode(hStdin, mode); - } - } } diff --git a/BarrageGrab/Properties/AssemblyInfo.cs b/BarrageGrab/Properties/AssemblyInfo.cs index cc5e8d2..f7026a3 100644 --- a/BarrageGrab/Properties/AssemblyInfo.cs +++ b/BarrageGrab/Properties/AssemblyInfo.cs @@ -5,11 +5,11 @@ using System.Runtime.InteropServices; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 -[assembly: AssemblyTitle("LiveCompanionBarrageGrab")] +[assembly: AssemblyTitle("抖音弹幕监听")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("LiveCompanionBarrageGrab")] +[assembly: AssemblyCompany("小白不圆")] +[assembly: AssemblyProduct("抖音弹幕监听器")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -20,7 +20,7 @@ using System.Runtime.InteropServices; [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID -[assembly: Guid("a07bb1da-d5c2-4eea-9f3f-e42aadb9c1d6")] +[assembly: Guid("a07bb1da-d5c2-4bea-9f3f-e42aadb9c1d5")] // 程序集的版本信息由下列四个值组成: // @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 //通过使用 "*",如下所示: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("2.6.8.0")] +[assembly: AssemblyFileVersion("2.6.8.0")] diff --git a/BarrageGrab/WinApi.cs b/BarrageGrab/WinApi.cs new file mode 100644 index 0000000..99c53bc --- /dev/null +++ b/BarrageGrab/WinApi.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace BarrageGrab +{ + public static class WinApi + { + const int STD_INPUT_HANDLE = -10; + const uint ENABLE_QUICK_EDIT_MODE = 0x0040; + + /// + /// 控制台系统操作回调委托 + /// + public delegate bool ControlCtrlDelegate(int CtrlType); + + /// + /// 设置控制台系统操作回调 + /// + [DllImport("kernel32.dll")] + public static extern bool SetConsoleCtrlHandler(ControlCtrlDelegate HandlerRoutine, bool Add); + [DllImport("kernel32.dll", SetLastError = true)] + internal static extern IntPtr GetStdHandle(int hConsoleHandle); + [DllImport("kernel32.dll", SetLastError = true)] + internal static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint mode); + [DllImport("kernel32.dll", SetLastError = true)] + internal static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint mode); + + /// + /// 启用控制台快速编辑 + /// + public static void EnableQuickEditMode() + { + IntPtr hStdin = GetStdHandle(STD_INPUT_HANDLE); + uint mode; + GetConsoleMode(hStdin, out mode); + mode |= ENABLE_QUICK_EDIT_MODE; + SetConsoleMode(hStdin, mode); + } + + /// + /// 禁用控制台快速编辑 + /// + public static void DisableQuickEditMode() + { + IntPtr hStdin = GetStdHandle(STD_INPUT_HANDLE); + uint mode; + GetConsoleMode(hStdin, out mode); + mode &= ~ENABLE_QUICK_EDIT_MODE; + SetConsoleMode(hStdin, mode); + } + } +} diff --git a/BarrageGrab/WsBarrageService.cs b/BarrageGrab/WsBarrageService.cs index 098bdc9..846014b 100644 --- a/BarrageGrab/WsBarrageService.cs +++ b/BarrageGrab/WsBarrageService.cs @@ -1,17 +1,22 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net; using System.Net.WebSockets; using System.Text; using System.Threading.Tasks; using System.Timers; -using BarrageGrab.JsonEntity; -using BarrageGrab.ProtoEntity; using ColorConsole; using Fleck; using Newtonsoft.Json; +using BarrageGrab.Modles; using Newtonsoft.Json.Linq; -using static BarrageGrab.ProtoEntity.Image; +using System.Net.Http; +using Org.BouncyCastle.Asn1.Crmf; +using System.IO.Compression; +using System.IO; +using BarrageGrab.Modles.JsonEntity; +using BarrageGrab.Modles.ProtoEntity; namespace BarrageGrab { @@ -19,7 +24,7 @@ namespace BarrageGrab /// /// 弹幕服务 /// - internal class WsBarrageService + public class WsBarrageService { WebSocketServer socketServer; Dictionary socketList = new Dictionary(); @@ -30,8 +35,8 @@ namespace BarrageGrab ConsoleWriter console = new ConsoleWriter(); WssBarrageGrab grab = new WssBarrageGrab(); Appsetting Appsetting = Appsetting.Current; - bool debug = false; - + bool debug = false; + /// /// 服务关闭后触发 /// @@ -42,7 +47,7 @@ namespace BarrageGrab #if DEBUG debug = true; #endif - var socket = new WebSocketServer($"ws://127.0.0.1:{Appsetting.WsProt}"); + var socket = new WebSocketServer($"ws://0.0.0.0:{Appsetting.WsProt}"); socket.RestartAfterListenError = true;//异常重启 dieout.Elapsed += Dieout_Elapsed; @@ -81,11 +86,12 @@ namespace BarrageGrab private bool CheckRoomId(long roomid) { - return Appsetting.RoomIds.Length == 0 || Appsetting.RoomIds.Contains(roomid); + if (Appsetting.RoomIds.Length == 0) return true; + return Appsetting.RoomIds.Any(a => a == roomid); } - + //解析用户 - private MsgUser GetUser(ProtoEntity.User data) + private MsgUser GetUser(User data) { MsgUser user = new MsgUser() { @@ -94,12 +100,12 @@ namespace BarrageGrab Gender = data.Gender, Id = data.Id, Level = data.Level, - PayLevel = (int)(data.payGrade?.Level??0), + PayLevel = (int)(data.payGrade?.Level ?? 0), Nickname = data.Nickname, HeadImgUrl = data.avatarThumb.urlLists.FirstOrDefault() ?? "", SecUid = data.sec_uid, FollowerCount = data.followInfo.followerCount, - FollowingCount = data.followInfo.followingCount, + FollowingCount = data.followInfo.followingCount, FollowStatus = data.followInfo.followStatus, }; user.FansClub = new FansClubInfo() @@ -118,7 +124,7 @@ namespace BarrageGrab } //粉丝团 - private void Grab_OnFansclubMessage(object sender, ProtoEntity.FansclubMessage e) + private void Grab_OnFansclubMessage(object sender, FansclubMessage e) { if (!CheckRoomId(e.Common.roomId)) return; var enty = new FansclubMsg() @@ -126,7 +132,7 @@ namespace BarrageGrab MsgId = e.Common.msgId, Content = e.Content, RoomId = e.Common.roomId, - Type = e.Type, + Type = e.Type, User = GetUser(e.User) }; enty.Level = enty.User.FansClub.Level; @@ -137,7 +143,7 @@ namespace BarrageGrab } //统计消息 - private void Grab_OnRoomUserSeqMessage(object sender, ProtoEntity.RoomUserSeqMessage e) + private void Grab_OnRoomUserSeqMessage(object sender, RoomUserSeqMessage e) { if (!CheckRoomId(e.Common.roomId)) return; var enty = new UserSeqMsg() @@ -158,7 +164,7 @@ namespace BarrageGrab } //礼物 - private void Grab_OnGiftMessage(object sender, ProtoEntity.GiftMessage e) + private void Grab_OnGiftMessage(object sender, GiftMessage e) { if (!CheckRoomId(e.Common.roomId)) return; @@ -207,7 +213,7 @@ namespace BarrageGrab } //比上次小,则说明先后顺序出了问题,直接丢掉,应为比它大的消息已经处理过了 if (backward) return; - + var count = currCount - lastCount; @@ -224,8 +230,8 @@ namespace BarrageGrab GiftName = e.Gift.Name, User = GetUser(e.User) }; - - + + Print($"{enty.User.GenderToString()} {enty.Content}", ConsoleColor.Red, BarrageMsgType.礼物消息); var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.礼物消息); var json = JsonConvert.SerializeObject(pack); @@ -233,7 +239,7 @@ namespace BarrageGrab } //关注 - private void Grab_OnSocialMessage(object sender, ProtoEntity.SocialMessage e) + private void Grab_OnSocialMessage(object sender, SocialMessage e) { if (!CheckRoomId(e.Common.roomId)) return; if (e.Action != 1) return; @@ -252,7 +258,7 @@ namespace BarrageGrab } //直播间分享 - private void Grab_OnShardMessage(object sender, ProtoEntity.SocialMessage e) + private void Grab_OnShardMessage(object sender, SocialMessage e) { if (!CheckRoomId(e.Common.roomId)) return; if (e.Action != 3) return; @@ -278,11 +284,11 @@ namespace BarrageGrab } //来了 - private void Grab_OnMemberMessage(object sender, ProtoEntity.MemberMessage e) + private void Grab_OnMemberMessage(object sender, Modles.ProtoEntity.MemberMessage e) { if (!CheckRoomId(e.Common.roomId)) return; - var enty = new JsonEntity.MemberMessage() + var enty = new Modles.JsonEntity.MemberMessage() { MsgId = e.Common.msgId, Content = $"{e.User.Nickname} 来了 直播间人数:{e.memberCount}", @@ -297,7 +303,7 @@ namespace BarrageGrab } //点赞 - private void Grab_OnLikeMessage(object sender, ProtoEntity.LikeMessage e) + private void Grab_OnLikeMessage(object sender, LikeMessage e) { if (!CheckRoomId(e.Common.roomId)) return; @@ -317,7 +323,7 @@ namespace BarrageGrab } //弹幕 - private void Grab_OnChatMessage(object sender, ProtoEntity.ChatMessage e) + private void Grab_OnChatMessage(object sender, ChatMessage e) { if (!CheckRoomId(e.Common.roomId)) return; @@ -335,7 +341,7 @@ namespace BarrageGrab { Console.WriteLine(e.User.followInfo.followStatus); } - + var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.弹幕消息); var json = JsonConvert.SerializeObject(pack); this.Broadcast(json); @@ -374,7 +380,7 @@ namespace BarrageGrab if (Appsetting.PrintBarrage) { if (++count > 1000) - { + { Console.Clear(); Console.WriteLine("控制台已清理"); } @@ -417,7 +423,7 @@ namespace BarrageGrab this.Close(); } } - catch (Exception) {} + catch (Exception) { } }; socket.OnClose = () => @@ -441,11 +447,11 @@ namespace BarrageGrab { foreach (var user in socketList) { - var socket = user.Value; + var socket = user.Value; socket.Socket.Send(msg); } //删除掉线的套接字 - var offlines = socketList.Where(w=>!w.Value.Socket.IsAvailable).Select(s=>s.Key).ToList(); + var offlines = socketList.Where(w => !w.Value.Socket.IsAvailable).Select(s => s.Key).ToList(); offlines.ForEach(key => socketList.Remove(key)); } @@ -470,7 +476,7 @@ namespace BarrageGrab socketServer.Dispose(); grab.Dispose(); - this.OnClose?.Invoke(this, EventArgs.Empty); + this.OnClose?.Invoke(this, EventArgs.Empty); } class UserState diff --git a/BarrageGrab/WssBarrageGrab.cs b/BarrageGrab/WssBarrageGrab.cs index 976bdd0..2bce1eb 100644 --- a/BarrageGrab/WssBarrageGrab.cs +++ b/BarrageGrab/WssBarrageGrab.cs @@ -5,11 +5,11 @@ using System.IO.Compression; using System.Linq; using System.Text; using System.Threading.Tasks; -using BarrageGrab.ProtoEntity; using ProtoBuf; using ColorConsole; using BarrageGrab.Proxy; using BarrageGrab.Proxy.ProxyEventArgs; +using BarrageGrab.Modles.ProtoEntity; namespace BarrageGrab { @@ -25,9 +25,6 @@ namespace BarrageGrab //解包成功的域名缓存 List succPackHostNames = new List(); - //已知的弹幕域名服务器 - string[] wsHostNames = Appsetting.Current.HostNameFilter; - /// /// 进入直播间 /// @@ -71,8 +68,8 @@ namespace BarrageGrab public WssBarrageGrab() { proxy.OnWebSocketData += Proxy_OnWebSocketData; - proxy.HostNameFilter = HostNameChecker; - } + proxy.OnFetchResponse += Proxy_OnFetchResponse; + } public void Start() { @@ -81,19 +78,9 @@ namespace BarrageGrab public void Dispose() { - proxy.Dispose(); + proxy.Dispose(); } - //域名过滤器 - private bool HostNameChecker(string hostName) - { - if (!Appsetting.Current.FilterHostName) return true; - if (hostName.StartsWith("webcast")) return true; - - if (wsHostNames.Any(a => a.ToLower() == hostName.ToLower())) return true; - - return false; - } //gzip解压缩 private byte[] Decompress(byte[] zippedData) @@ -120,7 +107,8 @@ namespace BarrageGrab if (!appsetting.ProcessFilter.Contains(e.ProcessName)) return; var buff = e.Payload; if (buff.Length == 0) return; - if (buff[0] != 0x08) return; + //如果需要Gzip解压缩,但是开头字节不符合Gzip特征字节 则不处理 + if (e.NeedDecompress && buff[0] != 0x08) return; try { @@ -130,11 +118,10 @@ namespace BarrageGrab //检测包格式 if (!enty.Headers.Any(a => a.Key == "compress_type" && a.Value == "gzip")) return; + byte[] allBuff; //解压gzip - var odata = enty.Payload; - var decomp = Decompress(odata); - - var response = Serializer.Deserialize(new ReadOnlyMemory(decomp)); + allBuff = e.NeedDecompress ? Decompress(enty.Payload) : enty.Payload; + var response = Serializer.Deserialize(new ReadOnlyMemory(allBuff)); if (!succPackHostNames.Contains(e.HostName)) { @@ -146,16 +133,33 @@ namespace BarrageGrab catch (Exception) { } } + //http 数据处理 + private void Proxy_OnFetchResponse(object sender, HttpResponseEventArgs e) + { + var payload = e.HttpClient.Response.Body; + var response = Serializer.Deserialize(new ReadOnlyMemory(payload)); + + if (!succPackHostNames.Contains(e.HostName)) + { + succPackHostNames.Add(e.HostName); + SaveHostNameCache(); + } + response.Messages.ForEach(f => + { + DoMessage(f); + }); + } + //用于缓存接收过的消息ID,判断是否重复接收 - Dictionary> msgDic = new Dictionary>(); + Dictionary> msgDic = new Dictionary>(); //发送事件 private void DoMessage(Message msg) - { + { List msgIdList; if (msgDic.ContainsKey(msg.Method)) { - msgIdList = msgDic[msg.Method]; + msgIdList = msgDic[msg.Method]; } else { @@ -169,7 +173,7 @@ namespace BarrageGrab msgIdList.Add(msg.msgId); if (msgIdList.Count > 300) msgIdList.RemoveAt(0); - + try { switch (msg.Method) @@ -211,7 +215,7 @@ namespace BarrageGrab { if (arg.giftId == 685) { - arg.Gift = new ProtoEntity.GiftStruct() + arg.Gift = new GiftStruct() { Id = arg.giftId, Name = "粉丝灯牌", @@ -292,7 +296,7 @@ namespace BarrageGrab File.Create(fullPath); } var text = File.ReadAllText(fullPath); - var currentHosts = text.Split('\n').Where(w => !string.IsNullOrWhiteSpace(w)).Select(s=>s.Trim().Trim('\r')).ToList(); + var currentHosts = text.Split('\n').Where(w => !string.IsNullOrWhiteSpace(w)).Select(s => s.Trim().Trim('\r')).ToList(); var newHosts = succPackHostNames.Except(currentHosts).ToList(); //保存 if (newHosts.Count > 0) diff --git a/BarrageGrab/WssBarrageService.csproj b/BarrageGrab/WssBarrageService.csproj index c7a8960..8de6cf2 100644 --- a/BarrageGrab/WssBarrageService.csproj +++ b/BarrageGrab/WssBarrageService.csproj @@ -13,6 +13,21 @@ v4.8 512 true + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true true @@ -40,6 +55,7 @@ false + Properties\app.manifest @@ -47,6 +63,9 @@ ..\packages\Portable.BouncyCastle.1.8.8\lib\net40\BouncyCastle.Crypto.dll + + ..\packages\BouncyCastle.Cryptography.2.0.0\lib\net461\BouncyCastle.Cryptography.dll + ..\packages\BrotliSharpLib.0.3.3\lib\net451\BrotliSharpLib.dll @@ -56,12 +75,18 @@ ..\packages\Fleck.1.2.0\lib\net45\Fleck.dll + + ..\packages\HtmlAgilityPack.1.11.51\lib\Net45\HtmlAgilityPack.dll + ..\packages\Microsoft.Win32.Registry.5.0.0\lib\net461\Microsoft.Win32.Registry.dll ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll + + ..\packages\NLog.5.2.3\lib\net46\NLog.dll + ..\packages\protobuf-net.3.1.22\lib\net462\protobuf-net.dll @@ -77,8 +102,9 @@ - - ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll @@ -96,6 +122,7 @@ ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + @@ -103,12 +130,20 @@ - ..\packages\Titanium.Web.Proxy.3.2.0\lib\net461\Titanium.Web.Proxy.dll + ..\packages\Titanium.Web.Proxy.3.2.2-beta\lib\net461\Titanium.Web.Proxy.dll + + + + + + + + @@ -116,22 +151,37 @@ + - - - + + Always + + + Always + - + + + Always - - - Always - + + + + + False + Microsoft .NET Framework 4.8 %28x86 和 x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + \ No newline at end of file diff --git a/BarrageGrab/packages.config b/BarrageGrab/packages.config index e3f42a3..2e56486 100644 --- a/BarrageGrab/packages.config +++ b/BarrageGrab/packages.config @@ -1,20 +1,23 @@  + + + - + - + \ No newline at end of file