添加ComPort 推送服务

This commit is contained in:
梅浩东
2024-03-29 17:34:14 +08:00
parent 13b1914db8
commit 3c310ebffc
15 changed files with 587 additions and 127 deletions
+5 -1
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<!--配置更改后重启才能生效--> <!--配置更改后重启才能生效-->
<appSettings> <appSettings>
@@ -42,6 +42,10 @@
<add key="pollingInterval" value="3000" /> <add key="pollingInterval" value="3000" />
<!--禁用直播页浏览器脚本缓存 (如果需要确保脚本每次能够正常匹配替换,则启用它,可能会损失一定的页面加载速度)--> <!--禁用直播页浏览器脚本缓存 (如果需要确保脚本每次能够正常匹配替换,则启用它,可能会损失一定的页面加载速度)-->
<add key="disableLivePageScriptCache" value="true" /> <add key="disableLivePageScriptCache" value="true" />
<!--指定要发送的COM串口 格式:'COM1:9600' 代表用COM1发送,波特率9600,若不需要使用串口抄送服务请留空 -->
<add key="comPort" value="COM1:9600" />
<!--启用自定义消息过滤,启用后可去程序根目录 Scripts/engine/comPortFilter.js 调整过滤规则 -->
<add key="useComPortFilter" value="true" />
</appSettings> </appSettings>
<runtime> <runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+14 -2
View File
@@ -18,12 +18,17 @@ namespace BarrageGrab
/// <summary> /// <summary>
/// Ws弹幕服务示例 /// Ws弹幕服务示例
/// </summary> /// </summary>
public static WsBarrageService WssService { get; private set; } = new WsBarrageService(); public static WsBarrageServer WsServer { get; private set; }
/// <summary> /// <summary>
/// 房间缓存信息 /// 房间缓存信息
/// </summary> /// </summary>
public static RoomCacheManager RoomCaches { get; } = new RoomCacheManager(); public static RoomCacheManager RoomCaches { get; private set; }
/// <summary>
/// 串口服务
/// </summary>
public static ComPortServer ComPortServer { get; private set; }
/// <summary> /// <summary>
/// 程序进程信息 /// 程序进程信息
@@ -35,6 +40,13 @@ namespace BarrageGrab
} }
public static void Init()
{
WsServer = new WsBarrageServer();
RoomCaches = new RoomCacheManager();
ComPortServer = new ComPortServer(WsServer);
}
/// <summary> /// <summary>
/// 隐藏/显示 控制台 /// 隐藏/显示 控制台
/// </summary> /// </summary>
+53 -10
View File
@@ -10,13 +10,13 @@ using System.Drawing;
namespace BarrageGrab namespace BarrageGrab
{ {
internal class Appsetting internal class AppSetting
{ {
private static readonly Appsetting ins = new Appsetting(); private static readonly AppSetting ins = new AppSetting();
public static Appsetting Current { get { return ins; } } public static AppSetting Current { get { return ins; } }
public Appsetting() public AppSetting()
{ {
try try
{ {
@@ -41,6 +41,40 @@ namespace BarrageGrab
DisableLivePageScriptCache = bool.Parse(AppSettings["disableLivePageScriptCache"].Trim()); DisableLivePageScriptCache = bool.Parse(AppSettings["disableLivePageScriptCache"].Trim());
WebRoomIds = AppSettings["webRoomIds"].Trim().Split(',').Where(w => !string.IsNullOrWhiteSpace(w)).Select(x => long.Parse(x)).ToArray(); WebRoomIds = AppSettings["webRoomIds"].Trim().Split(',').Where(w => !string.IsNullOrWhiteSpace(w)).Select(x => long.Parse(x)).ToArray();
ConfigComPort();
ConfigFilter();
}
catch (Exception ex)
{
Logger.PrintColor("配置文件读取失败,请检查配置文件是否正确");
throw ex;
}
}
//com串口设置
private void ConfigComPort()
{
var comPort = AppSettings["comPort"];
if (!comPort.IsNullOrWhiteSpace())
{
try
{
var spit = comPort.Split(':');
ComPort = spit[0].Trim();
ComBaudRate = int.Parse(spit[1].Trim());
UseComPortFilter = bool.Parse(AppSettings["useComPortFilter"]);
}
catch (Exception ex)
{
throw new Exception("串口配置格式错误," + ex.Message, ex);
}
}
}
//各种过滤器设置
private void ConfigFilter()
{
var printFilter = AppSettings["printFilter"].Trim().ToLower(); var printFilter = AppSettings["printFilter"].Trim().ToLower();
var pushFilter = AppSettings["pushFilter"].Trim().ToLower(); var pushFilter = AppSettings["pushFilter"].Trim().ToLower();
var logFilter = AppSettings["logFilter"].Trim().ToLower(); var logFilter = AppSettings["logFilter"].Trim().ToLower();
@@ -60,12 +94,6 @@ namespace BarrageGrab
else LogFilter = logFilter.Split(',').Select(x => int.Parse(x)).ToArray(); else LogFilter = logFilter.Split(',').Select(x => int.Parse(x)).ToArray();
} }
} }
catch (Exception ex)
{
Logger.PrintColor("配置文件读取失败,请检查配置文件是否正确");
throw ex;
}
}
public void Save() public void Save()
{ {
@@ -200,5 +228,20 @@ namespace BarrageGrab
/// 禁用直播页面脚本缓存 /// 禁用直播页面脚本缓存
/// </summary> /// </summary>
public bool DisableLivePageScriptCache { get; private set; } = true; public bool DisableLivePageScriptCache { get; private set; } = true;
/// <summary>
/// 配置的串口
/// </summary>
public string ComPort { get; set; } = string.Empty;
/// <summary>
/// 波特率
/// </summary>
public int ComBaudRate { get; set; } = 9600;
/// <summary>
/// 是否启用串口过滤器脚本
/// </summary>
public bool UseComPortFilter { get; set; }
} }
} }
+136
View File
@@ -0,0 +1,136 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using Jint;
using Jint.Runtime;
using System.Windows.Forms;
namespace BarrageGrab
{
public class ComPortServer : IDisposable
{
WsBarrageServer server;
SerialPort sendPort;
static Engine jsEngine = null;
static ComPortServer()
{
if (AppSetting.Current.UseComPortFilter)
{
jsEngine = JsEngine.CreateNewEngine();
var jsFile = JsEngine.GetJsFile("comPortFilter.js");
jsEngine.Execute(jsFile);
}
}
public ComPortServer(WsBarrageServer server)
{
string portName = AppSetting.Current.ComPort;
int baudRate = AppSetting.Current.ComBaudRate;
if (portName.IsNullOrWhiteSpace())
{
return;
//throw new ArgumentNullException(nameof(portName));
}
this.server = server;
server.OnPackMessage += Server_OnPackMessage;
server.OnClose += Server_OnClose;
sendPort = new SerialPort(portName, baudRate);
}
private void Server_OnClose(object sender, EventArgs e)
{
this.Dispose();
}
private void Server_OnPackMessage(WsBarrageServer sender, WsBarrageServer.PackMsgEventArgs e)
{
if (!sendPort.IsOpen) return;
if (e == null) return;
if (!AppSetting.Current.UseComPortFilter)
{
var json = e.ToJson() + "\r\n";
var jbuff = Encoding.UTF8.GetBytes(json);
Send(jbuff);
return;
}
var result = jsEngine.Invoke("onPackData", e.MsgType.GetHashCode(), e.Message);
var nocanTypes = new Types[]
{
Types.Null,
Types.Undefined,
Types.Empty,
Types.Symbol
};
if (nocanTypes.Contains(result.Type)) return;
Func<string, byte[]> encode = (str) => Encoding.UTF8.GetBytes(str);
byte[] buff = new byte[0];
switch (result.Type)
{
case Types.Boolean:
buff = encode(result.AsBoolean().ToString().ToLower());
break;
case Types.String:
buff = encode(result.AsString());
break;
case Types.BigInt:
case Types.Number:
buff = BitConverter.GetBytes(result.AsNumber());
break;
case Types.Object:
if (result.ToObject() is byte[])
{
buff = result.AsArrayBuffer();
}
break;
default:
break;
}
if (buff.Length == 0) return;
Send(buff);
}
//发送数据包
private void Send(byte[] buff)
{
lock (this.sendPort)
{
sendPort.Write(buff, 0, buff.Length);
}
}
/// <summary>
/// 打开串口并开始接收写入数据
/// </summary>
public void OpenStart()
{
if (sendPort == null) throw new Exception("未成功初始化串口对象,请检查配置文件");
try
{
sendPort.Open();
}
catch (Exception ex)
{
sendPort.Close();
sendPort.Dispose();
sendPort = null;
throw ex;
}
}
public void Dispose()
{
if (sendPort == null) return;
sendPort.Close();
sendPort.Dispose();
sendPort = null;
jsEngine.Dispose();
}
}
}
+17 -17
View File
@@ -20,9 +20,9 @@ namespace BarrageGrab
{ {
static int printCount = 0; static int printCount = 0;
WsBarrageService barServer = AppRuntime.WssService; WsBarrageServer barServer = AppRuntime.WsServer;
WssBarrageGrab grab = AppRuntime.WssService.Grab; WssBarrageGrab grab = AppRuntime.WsServer.Grab;
ISystemProxy proxy = AppRuntime.WssService.Grab.Proxy; ISystemProxy proxy = AppRuntime.WsServer.Grab.Proxy;
public FormView() public FormView()
{ {
@@ -32,7 +32,7 @@ namespace BarrageGrab
AppRuntime.RoomCaches.OnCache += RoomCaches_OnCache; AppRuntime.RoomCaches.OnCache += RoomCaches_OnCache;
this.txb_wsaddr.Text = barServer.ServerLocation; this.txb_wsaddr.Text = barServer.ServerLocation;
this.txb_upstreamProxy.Text = proxy.HttpUpstreamProxy; this.txb_upstreamProxy.Text = proxy.HttpUpstreamProxy;
this.cbx_barrageLog.Checked = Appsetting.Current.BarrageLog; this.cbx_barrageLog.Checked = AppSetting.Current.BarrageLog;
InitTabPages(); InitTabPages();
} }
@@ -67,17 +67,17 @@ namespace BarrageGrab
if (page == this.tabPage_Ws) if (page == this.tabPage_Ws)
{ {
type = "ws"; type = "ws";
ck.Checked = Appsetting.Current.PushFilter.Contains(label.Key); ck.Checked = AppSetting.Current.PushFilter.Contains(label.Key);
} }
if (page == this.tabPage_Console) if (page == this.tabPage_Console)
{ {
type = "console"; type = "console";
ck.Checked = Appsetting.Current.PrintFilter.Contains(label.Key); ck.Checked = AppSetting.Current.PrintFilter.Contains(label.Key);
} }
if (page == this.tabPage_Log) if (page == this.tabPage_Log)
{ {
type = "log"; type = "log";
ck.Checked = Appsetting.Current.LogFilter.Contains(label.Key); ck.Checked = AppSetting.Current.LogFilter.Contains(label.Key);
} }
ck.Name = $"cbx_bartype_{type}_{label.Key}"; ck.Name = $"cbx_bartype_{type}_{label.Key}";
ck.CheckedChanged += Ck_CheckedChanged; ck.CheckedChanged += Ck_CheckedChanged;
@@ -94,17 +94,17 @@ namespace BarrageGrab
var selected = GetCheckedBarTypes((FlowLayoutPanel)cbx.Parent); var selected = GetCheckedBarTypes((FlowLayoutPanel)cbx.Parent);
if (cbx.Parent.Parent == this.tabPage_Console) if (cbx.Parent.Parent == this.tabPage_Console)
{ {
Appsetting.Current.PrintFilter = selected; AppSetting.Current.PrintFilter = selected;
} }
if (cbx.Parent.Parent == this.tabPage_Ws) if (cbx.Parent.Parent == this.tabPage_Ws)
{ {
Appsetting.Current.PushFilter = selected; AppSetting.Current.PushFilter = selected;
} }
if(cbx.Parent.Parent == this.tabPage_Log) if(cbx.Parent.Parent == this.tabPage_Log)
{ {
Appsetting.Current.LogFilter = selected; AppSetting.Current.LogFilter = selected;
} }
Appsetting.Current.Save(); AppSetting.Current.Save();
} }
private int[] GetCheckedBarTypes(FlowLayoutPanel panel) private int[] GetCheckedBarTypes(FlowLayoutPanel panel)
@@ -167,11 +167,11 @@ namespace BarrageGrab
})); }));
} }
private void WssService_OnPrint(object sender, WsBarrageService.PrintEventArgs e) private void WssService_OnPrint(object sender, WsBarrageServer.PrintEventArgs e)
{ {
//将弹幕输出到richTextBox //将弹幕输出到richTextBox
//颜色转换 //颜色转换
Color color = Appsetting.Current.ColorMap[e.MsgType].Item2; Color color = AppSetting.Current.ColorMap[e.MsgType].Item2;
string msg = e.Message; string msg = e.Message;
this.Invoke(new Action(() => this.Invoke(new Action(() =>
@@ -218,8 +218,8 @@ namespace BarrageGrab
try try
{ {
proxy.SetUpstreamProxy(text); proxy.SetUpstreamProxy(text);
Appsetting.Current.UpstreamProxy = text; AppSetting.Current.UpstreamProxy = text;
Appsetting.Current.Save(); AppSetting.Current.Save();
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -231,8 +231,8 @@ namespace BarrageGrab
private void cbx_barrageLog_CheckedChanged(object sender, EventArgs e) private void cbx_barrageLog_CheckedChanged(object sender, EventArgs e)
{ {
var checker = (CheckBox)sender; var checker = (CheckBox)sender;
Appsetting.Current.BarrageLog = checker.Checked; AppSetting.Current.BarrageLog = checker.Checked;
Appsetting.Current.Save(); AppSetting.Current.Save();
} }
} }
} }
+148
View File
@@ -0,0 +1,148 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Jint;
using Newtonsoft.Json;
using Jint.Native;
namespace BarrageGrab
{
public static class JsEngine
{
public static Engine CreateNewEngine()
{
var jsonParse = new Func<object, string>((obj) =>
{
try
{
return JsonConvert.SerializeObject(JsonConvert.SerializeObject(obj));
}
catch (Exception ex)
{
Logger.LogError("JS:" + ex.Message);
return null;
}
});
var engine = new Engine();
engine.SetValue("console", new JsConsole());
engine.SetValue("encoder", new JsEncoder(engine));
return engine;
}
/// <summary>
/// 从engine 目录获取js 文件
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string GetJsFile(string fileName)
{
var path = Path.Combine(AppContext.BaseDirectory, "Scripts", "engine", fileName);
if (!File.Exists(path)) throw new FileNotFoundException("不存在的文件", path);
return File.ReadAllText(path, Encoding.UTF8);
}
class JsConsole
{
public void log(object obj)
{
if (obj == null) return;
Logger.PrintColor("JS: " + obj.ToString());
}
public void error(object obj)
{
if (obj == null) return;
Logger.LogError("JS: " + obj.ToString());
}
public void warn(object obj)
{
if (obj == null) return;
Logger.LogWarn("JS: " + obj.ToString());
}
}
class JsEncoder
{
Engine eng;
public JsEncoder(Engine eng)
{
this.eng = eng;
eng.Execute(@"
byteToUint8Array = function(arr){
return new Uint8Array(arr);
}");
}
private JsValue ByteConvert(byte[] buff)
{
return eng.Invoke("byteToUint8Array", buff);
}
public JsValue utf8ToBytes(string str)
{
byte[] res = new byte[0];
if (str.IsNullOrWhiteSpace())
{
res = new byte[0];
}
else
{
res = Encoding.UTF8.GetBytes(str);
}
return ByteConvert(res);
}
public JsValue utf32ToBytes(string str)
{
byte[] res = new byte[0];
if (str.IsNullOrWhiteSpace())
{
res = new byte[0];
}
else
{
res = Encoding.UTF32.GetBytes(str);
}
return ByteConvert(res);
}
public JsValue asciiToBytes(string str)
{
byte[] res = new byte[0];
if (str.IsNullOrWhiteSpace())
{
res = new byte[0];
}
else
{
res = Encoding.ASCII.GetBytes(str);
}
return ByteConvert(res);
}
public string utf8ToString(byte[] bytes)
{
if (bytes == null) return null;
return Encoding.UTF8.GetString(bytes);
}
public string utf32ToString(byte[] bytes)
{
if (bytes == null) return null;
return Encoding.UTF32.GetString(bytes);
}
public string asciiToString(byte[] bytes)
{
if (bytes == null) return null;
return Encoding.ASCII.GetString(bytes);
}
}
}
}
+3 -3
View File
@@ -94,9 +94,9 @@ namespace BarrageGrab
/// <param name="msg">弹幕内容</param> /// <param name="msg">弹幕内容</param>
public static void LogBarrage(PackMsgType type, Msg msg) public static void LogBarrage(PackMsgType type, Msg msg)
{ {
if (!Appsetting.Current.BarrageLog) return; if (!AppSetting.Current.BarrageLog) return;
if (type == PackMsgType.无) return; if (type == PackMsgType.无) return;
if (Appsetting.Current.LogFilter.Any() && !Appsetting.Current.LogFilter.Contains(type.GetHashCode())) return; if (AppSetting.Current.LogFilter.Any() && !AppSetting.Current.LogFilter.Contains(type.GetHashCode())) return;
try try
{ {
@@ -135,7 +135,7 @@ namespace BarrageGrab
text += $" [{msg.User?.GenderToString()}] "; text += $" [{msg.User?.GenderToString()}] ";
} }
ConsoleColor color = Appsetting.Current.ColorMap[barType].Item1; ConsoleColor color = AppSetting.Current.ColorMap[barType].Item1;
var append = msg.Content; var append = msg.Content;
switch (barType) switch (barType)
{ {
+90 -32
View File
@@ -6,6 +6,9 @@ using System.Net;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.IO;
using Jint.Runtime;
using System.Windows.Forms;
namespace BarrageGrab namespace BarrageGrab
{ {
@@ -14,9 +17,14 @@ namespace BarrageGrab
static FormView mainForm = null; static FormView mainForm = null;
static bool exited = false; static bool exited = false;
static bool formExited = false; static bool formExited = false;
static WinApi.ControlCtrlDelegate controlCtr = ControlCtrlHandle;
static void Main(string[] args) static void Main(string[] args)
{ {
//JintTest();
//Console.WriteLine("结束");
//Console.ReadKey();
//return;
if (CheckAlreadyRunning()) if (CheckAlreadyRunning())
{ {
Logger.PrintColor("已经有一个监听程序在运行,按任意键退出..."); Logger.PrintColor("已经有一个监听程序在运行,按任意键退出...");
@@ -25,19 +33,51 @@ namespace BarrageGrab
} }
SetTitle("抖音弹幕监听推送"); SetTitle("抖音弹幕监听推送");
WinApi.SetConsoleCtrlHandler(ControlCtrlDelegate, true);//捕获控制台关闭 try
{
Init();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "程序初始化错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
exited = true;
}
while (!exited)
{
Thread.Sleep(500);
}
if (!AppRuntime.WsServer.IsDisposed)
{
AppRuntime.WsServer.Dispose();
}
Logger.PrintColor("服务器已关闭...");
WinApi.SetConsoleCtrlHandler(controlCtr, false);//反注册捕获控制台关闭
}
private static void Init()
{
AppRuntime.Init();
WinApi.SetConsoleCtrlHandler(controlCtr, true);//捕获控制台关闭
WinApi.DisableQuickEditMode();//禁用控制台快速编辑模式 WinApi.DisableQuickEditMode();//禁用控制台快速编辑模式
AppRuntime.DisplayConsole(!Appsetting.Current.HideConsole);//控制控制台可见 AppRuntime.DisplayConsole(!AppSetting.Current.HideConsole);//控制控制台可见
AppRuntime.WssService.Grab.Proxy.SetUpstreamProxy(Appsetting.Current.UpstreamProxy);//设置上游代理 AppRuntime.WsServer.Grab.Proxy.SetUpstreamProxy(AppSetting.Current.UpstreamProxy);//设置上游代理
AppRuntime.WssService.StartListen();//启动WS服务 AppRuntime.WsServer.OnClose += (s, e) =>
{
exited = true;
};
Logger.LogSucc($"{AppRuntime.WssService.ServerLocation} 弹幕服务已启动..."); //串口写入服务
SetTitle($"抖音弹幕监听推送 [{AppRuntime.WssService.ServerLocation}]"); if (!AppSetting.Current.ComPort.IsNullOrWhiteSpace())
{
AppRuntime.WssService.OnClose += (s, e) => exited = true; AppRuntime.ComPortServer.OpenStart();
}
//显示窗体 //显示窗体
if (Appsetting.Current.ShowWindow) if (AppSetting.Current.ShowWindow)
{ {
var uiThread = new Thread(new ThreadStart(() => var uiThread = new Thread(new ThreadStart(() =>
{ {
@@ -45,33 +85,16 @@ namespace BarrageGrab
//开启消息循环 //开启消息循环
System.Windows.Forms.Application.Run(mainForm); System.Windows.Forms.Application.Run(mainForm);
formExited = true; formExited = true;
AppRuntime.WsServer.Dispose();//Close后自动释放资源
})); }));
uiThread.SetApartmentState(ApartmentState.STA); uiThread.SetApartmentState(ApartmentState.STA);
uiThread.IsBackground = true; uiThread.IsBackground = true;
uiThread.Start(); uiThread.Start();
} }
while (!exited) AppRuntime.WsServer.StartListen();//启动WS以及代理服务
{ Logger.LogSucc($"{AppRuntime.WsServer.ServerLocation} 弹幕服务已启动...");
if (formExited && !exited) SetTitle($"抖音弹幕监听推送 [{AppRuntime.WsServer.ServerLocation}]");
{
AppRuntime.WssService.Close();
}
Thread.Sleep(500);
}
Logger.PrintColor("服务器已关闭...");
//if (!mainForm.IsDisposed)
//{
// mainForm.Invoke(new Action(() =>
// {
// mainForm.Close();
// }));
//}
//退出程序,不显示 按任意键退出
//Environment.Exit(0);
} }
//检测设置控制台标题 //检测设置控制台标题
@@ -84,7 +107,7 @@ namespace BarrageGrab
} }
//监听控制台消息事件 //监听控制台消息事件
private static bool ControlCtrlDelegate(int CtrlType) private static bool ControlCtrlHandle(int CtrlType)
{ {
switch (CtrlType) switch (CtrlType)
{ {
@@ -94,7 +117,7 @@ namespace BarrageGrab
break; break;
case 2: case 2:
Logger.PrintColor("2工具被强制关闭");//按控制台关闭按钮关闭 Logger.PrintColor("2工具被强制关闭");//按控制台关闭按钮关闭
AppRuntime.WssService.Close(); AppRuntime.WsServer.Dispose();
break; break;
} }
return false; return false;
@@ -111,5 +134,40 @@ namespace BarrageGrab
return !createdNew; return !createdNew;
} }
} }
private static void JintTest()
{
var jsEng = JsEngine.CreateNewEngine();
var jsFile = File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "Scripts", "engine", "comPortFilter.js"), Encoding.UTF8);
jsEng.Execute(jsFile);
var result = jsEng.Invoke("onPackData", 1, new
{
Aporp = 142,
Bprop = "48777",
Cprop = new string[] { "123" },
Dprop = new Dictionary<string, string>()
{
{ "key1","value1" }
}
});
Console.WriteLine("返回类型:" + result.Type.ToString());
if (result.Type == Types.String)
{
Console.WriteLine("返回String: " + result.ToString());
}
if (result.Type == Types.Object)
{
var obj = result.ToObject();
if (obj is byte[])
{
Console.WriteLine("返回byte[]");
}
}
if (result.Type == Types.Symbol)
{
Console.WriteLine("返回Symbol: " + result.ToString());
}
}
} }
} }
+3 -3
View File
@@ -32,7 +32,7 @@ namespace BarrageGrab.Proxy
/// <summary> /// <summary>
/// 代理端口 /// 代理端口
/// </summary> /// </summary>
public int ProxyPort { get { return Appsetting.Current.ProxyPort; } } public int ProxyPort { get { return AppSetting.Current.ProxyPort; } }
public abstract string HttpUpstreamProxy { get; } public abstract string HttpUpstreamProxy { get; }
@@ -55,11 +55,11 @@ namespace BarrageGrab.Proxy
{ {
host = host.Trim().ToLower(); host = host.Trim().ToLower();
if (!Appsetting.Current.FilterHostName) return true; if (!AppSetting.Current.FilterHostName) return true;
if (host.StartsWith("webcast")) return true; if (host.StartsWith("webcast")) return true;
if (Appsetting.Current.HostNameFilter.Any(a => a.Trim().ToLower() == host)) return true; if (AppSetting.Current.HostNameFilter.Any(a => a.Trim().ToLower() == host)) return true;
return false; return false;
} }
+8 -8
View File
@@ -212,7 +212,7 @@ namespace BarrageGrab.Proxy
var scriptContext = BuildContext(new Dictionary<string, string>() var scriptContext = BuildContext(new Dictionary<string, string>()
{ {
{"PROCESS_NAME","'{processName}'"}, {"PROCESS_NAME","'{processName}'"},
{"AUTOPAUSE",Appsetting.Current.AutoPause.ToString().ToLower()} {"AUTOPAUSE",AppSetting.Current.AutoPause.ToString().ToLower()}
}); });
liveRoomInjectScript = scriptContext + liveRoomInjectScript; liveRoomInjectScript = scriptContext + liveRoomInjectScript;
var html = await e.GetResponseBodyAsString(); var html = await e.GetResponseBodyAsString();
@@ -275,7 +275,7 @@ namespace BarrageGrab.Proxy
} }
//给script标签 src加上时间戳避免缓存 //给script标签 src加上时间戳避免缓存
if (Appsetting.Current.DisableLivePageScriptCache) if (AppSetting.Current.DisableLivePageScriptCache)
{ {
var scripts = doc.DocumentNode.SelectNodes("//script[@src]"); var scripts = doc.DocumentNode.SelectNodes("//script[@src]");
if (scripts != null) if (scripts != null)
@@ -311,7 +311,7 @@ namespace BarrageGrab.Proxy
var scriptContext = BuildContext(new Dictionary<string, string>() var scriptContext = BuildContext(new Dictionary<string, string>()
{ {
{"PROCESS_NAME","'{processName}'"}, {"PROCESS_NAME","'{processName}'"},
{"AUTOPAUSE",Appsetting.Current.AutoPause.ToString().ToLower()} {"AUTOPAUSE",AppSetting.Current.AutoPause.ToString().ToLower()}
}); });
liveHoomInjectScript = scriptContext + liveHoomInjectScript; liveHoomInjectScript = scriptContext + liveHoomInjectScript;
@@ -382,7 +382,7 @@ namespace BarrageGrab.Proxy
} }
} }
if (url.Contains(LIVE_SCRIPT_PATH) && Appsetting.Current.ForcePolling) if (url.Contains(LIVE_SCRIPT_PATH) && AppSetting.Current.ForcePolling)
{ {
var reg = new Regex(@"if\s*\((?<patt>!this\.stopPolling)\)"); var reg = new Regex(@"if\s*\((?<patt>!this\.stopPolling)\)");
var js = await e.GetResponseBodyAsString(); var js = await e.GetResponseBodyAsString();
@@ -393,7 +393,7 @@ namespace BarrageGrab.Proxy
var pollingIntervalMatch = pollingIntervalReg.Match(js); var pollingIntervalMatch = pollingIntervalReg.Match(js);
if (pollingIntervalMatch.Success) if (pollingIntervalMatch.Success)
{ {
var myValue = Appsetting.Current.PollingInterval; var myValue = AppSetting.Current.PollingInterval;
js = pollingIntervalReg.Replace(js, $"this.pollingInterval={myValue},"); js = pollingIntervalReg.Replace(js, $"this.pollingInterval={myValue},");
Logger.PrintColor($"直播间已成功修改轮询间隔为{myValue}ms", ConsoleColor.Green); Logger.PrintColor($"直播间已成功修改轮询间隔为{myValue}ms", ConsoleColor.Green);
} }
@@ -515,7 +515,7 @@ namespace BarrageGrab.Proxy
{ {
proxyServer.Stop(); proxyServer.Stop();
proxyServer.Dispose(); proxyServer.Dispose();
if (Appsetting.Current.UsedProxy) if (AppSetting.Current.UsedProxy)
{ {
CloseSystemProxy(); CloseSystemProxy();
} }
@@ -526,8 +526,8 @@ namespace BarrageGrab.Proxy
/// </summary> /// </summary>
override public void Start() override public void Start()
{ {
proxyServer.Start(Appsetting.Current.UsedProxy); proxyServer.Start(AppSetting.Current.UsedProxy);
if (Appsetting.Current.UsedProxy) if (AppSetting.Current.UsedProxy)
{ {
proxyServer.SetAsSystemHttpProxy(explicitEndPoint); proxyServer.SetAsSystemHttpProxy(explicitEndPoint);
proxyServer.SetAsSystemHttpsProxy(explicitEndPoint); proxyServer.SetAsSystemHttpsProxy(explicitEndPoint);
@@ -0,0 +1,28 @@
/**
* 注解:串口数据过滤脚本,可用于自定义配置串口的发送报文
* Tip: 该脚本引擎为Jint,支持的语法请参考官方文档:https://github.com/sebastienros/jint
* 工具环境:
* 1.支持 console.log, console.error, console.warn 这些日志将被输出到控制台, 其中error日志将被记录到日志文件
* 2.编码工具 encoder.utf8ToBytes(str),encoder.utf8ToString 字符串 和 Uint8Array 互转
* encoder.utf32ToBytes(str),encoder.utf32ToString
* encoder.asciiToBytes(str),encoder.asciiToString
*/
/**
* 这个函数由程序JS引擎调用,不要删除
* @param {number} msgType 消息类型,如礼物,弹幕消息等,和程序内定义一致
* @param {Object} msg 被WsBarrageServer简化后的消息对象,具体可参考Json实体文件
* @returns {Uint8Array|string} 返回一个Uint8Array类型的数据,或者返回一个字符串,如果返回 null 则不发送数据。返回的数据将会被发送到串口
*/
function onPackData(msgType, msg) {
let excludeMsgType = [3, 6, 0]; // 过滤掉进入直播间和统计信息
if (excludeMsgType.includes(msgType)) return;
var result = msg.Content + "\r\n";
return result;
// var buff = encoder.utf8ToBytes(result);
// var newjs = encoder.utf8ToString(buff);
// console.log(newjs);
// return newjs;
}
+34 -17
View File
@@ -20,10 +20,15 @@ using System.Collections.Concurrent;
namespace BarrageGrab namespace BarrageGrab
{ {
/// <summary>
/// WsBarrageServer 包装消息事件委托
/// </summary>
public delegate void PackMessageEventHandler(WsBarrageServer sender, WsBarrageServer.PackMsgEventArgs e);
/// <summary> /// <summary>
/// 弹幕服务 /// 弹幕服务
/// </summary> /// </summary>
public class WsBarrageServer public class WsBarrageServer:IDisposable
{ {
WebSocketServer socketServer; //Ws服务器对象 WebSocketServer socketServer; //Ws服务器对象
Dictionary<string, UserState> socketList = new Dictionary<string, UserState>(); //客户端列表 Dictionary<string, UserState> socketList = new Dictionary<string, UserState>(); //客户端列表
@@ -31,25 +36,29 @@ namespace BarrageGrab
Timer dieout = new Timer(10000);//离线客户端清理计时器 Timer dieout = new Timer(10000);//离线客户端清理计时器
Timer giftCountTimer = new Timer(10000);//礼物缓存清理计时器 Timer giftCountTimer = new Timer(10000);//礼物缓存清理计时器
WssBarrageGrab grab = new WssBarrageGrab();//弹幕解析器核心 WssBarrageGrab grab = new WssBarrageGrab();//弹幕解析器核心
Appsetting Appsetting = Appsetting.Current;//全局配置文件实例 AppSetting Appsetting = AppSetting.Current;//全局配置文件实例
static int printCount = 0; //控制台输出计数,用于判断清理控制台 static int printCount = 0; //控制台输出计数,用于判断清理控制台
/// <summary> /// <summary>
/// WS服务器启动地址 /// WS服务器启动地址
/// </summary> /// </summary>
public string ServerLocation { get { return socketServer.Location; } } public string ServerLocation => socketServer.Location;
/// <summary> /// <summary>
/// 数据内核 /// 数据内核
/// </summary> /// </summary>
public WssBarrageGrab Grab { get { return grab; } } public WssBarrageGrab Grab => grab;
/// <summary> /// <summary>
/// 控制台打印事件 /// 控制台打印事件
/// </summary> /// </summary>
public event EventHandler<PrintEventArgs> OnPrint; public event EventHandler<PrintEventArgs> OnPrint;
/// <summary>
/// 是否已经释放资源
/// </summary>
public bool IsDisposed { get; private set; } = false;
/// <summary> /// <summary>
/// 服务关闭后触发 /// 服务关闭后触发
/// </summary> /// </summary>
@@ -58,7 +67,7 @@ namespace BarrageGrab
/// <summary> /// <summary>
/// 消息包装完成后触发 /// 消息包装完成后触发
/// </summary> /// </summary>
public event EventHandler<PackMsgEventArgs> OnPackMessage; public event PackMessageEventHandler OnPackMessage;
public WsBarrageServer() public WsBarrageServer()
{ {
@@ -111,12 +120,12 @@ namespace BarrageGrab
//判断Rommid是否符合拦截规则 //判断Rommid是否符合拦截规则
private bool CheckRoomId(long roomid) private bool CheckRoomId(long roomid)
{ {
if (!Appsetting.Current.WebRoomIds.Any()) return true; if (!AppSetting.Current.WebRoomIds.Any()) return true;
var webrid = AppRuntime.RoomCaches.GetCachedWebRoomid(roomid.ToString()); var webrid = AppRuntime.RoomCaches.GetCachedWebRoomid(roomid.ToString());
if (webrid <= 0) return true; if (webrid <= 0) return true;
return Appsetting.Current.WebRoomIds.Contains(webrid); return AppSetting.Current.WebRoomIds.Contains(webrid);
} }
//解析用户 //解析用户
@@ -165,7 +174,7 @@ namespace BarrageGrab
text += $" [{msg.User?.GenderToString()}] "; text += $" [{msg.User?.GenderToString()}] ";
} }
ConsoleColor color = Appsetting.Current.ColorMap[barType].Item1; ConsoleColor color = AppSetting.Current.ColorMap[barType].Item1;
var append = msg.Content; var append = msg.Content;
switch (barType) switch (barType)
{ {
@@ -176,13 +185,13 @@ namespace BarrageGrab
text += append; text += append;
if (Appsetting.Current.BarrageLog) if (AppSetting.Current.BarrageLog)
{ {
Logger.LogBarrage(barType, msg); Logger.LogBarrage(barType, msg);
} }
if (!Appsetting.PrintBarrage) return; if (!Appsetting.PrintBarrage) return;
if (Appsetting.Current.PrintFilter.Any() && !Appsetting.Current.PrintFilter.Contains(barType.GetHashCode())) return; if (AppSetting.Current.PrintFilter.Any() && !AppSetting.Current.PrintFilter.Contains(barType.GetHashCode())) return;
OnPrint?.Invoke(this, new PrintEventArgs() OnPrint?.Invoke(this, new PrintEventArgs()
{ {
@@ -201,7 +210,7 @@ namespace BarrageGrab
} }
//发送消息包装事件 //发送消息包装事件
private void FirePack(Msg msg, PackMsgType barType) private async void FirePack(Msg msg, PackMsgType barType)
{ {
if (OnPackMessage == null) return; if (OnPackMessage == null) return;
var arg = new PackMsgEventArgs() var arg = new PackMsgEventArgs()
@@ -210,7 +219,7 @@ namespace BarrageGrab
Message = msg Message = msg
}; };
//异步执行 //异步执行
Task.Run(() => OnPackMessage(this, arg)); OnPackMessage(this, arg);
} }
//粉丝团 //粉丝团
@@ -524,7 +533,7 @@ namespace BarrageGrab
switch (cmdPack.Cmd) switch (cmdPack.Cmd)
{ {
case CommandCode.Close: case CommandCode.Close:
this.Close(); this.Dispose();
break; break;
case CommandCode.EnableProxy: case CommandCode.EnableProxy:
{ {
@@ -566,7 +575,7 @@ namespace BarrageGrab
public void Broadcast(BarrageMsgPack pack) public void Broadcast(BarrageMsgPack pack)
{ {
if (pack == null) return; if (pack == null) return;
if (Appsetting.Current.PushFilter.Any() && !Appsetting.Current.PushFilter.Contains(pack.Type.GetHashCode())) return; if (AppSetting.Current.PushFilter.Any() && !AppSetting.Current.PushFilter.Contains(pack.Type.GetHashCode())) return;
var offLines = new List<string>(); var offLines = new List<string>();
foreach (var item in socketList) foreach (var item in socketList)
@@ -589,21 +598,29 @@ namespace BarrageGrab
/// 开始监听 /// 开始监听
/// </summary> /// </summary>
public void StartListen() public void StartListen()
{
try
{ {
this.grab.Start(); //启动代理 this.grab.Start(); //启动代理
this.socketServer.Start(Listen);//启动监听 this.socketServer.Start(Listen);//启动监听
} }
catch (Exception)
{
this.Dispose();
throw;
}
}
/// <summary> /// <summary>
/// 关闭服务器连接,并关闭系统代理 /// 关闭服务器连接,并关闭系统代理
/// </summary> /// </summary>
public void Close() public void Dispose()
{ {
socketList.Values.ToList().ForEach(f => f.Socket.Close()); socketList.Values.ToList().ForEach(f => f.Socket.Close());
socketList.Clear(); socketList.Clear();
socketServer.Dispose(); socketServer.Dispose();
grab.Dispose(); grab.Dispose();
this.IsDisposed = true;
this.OnClose?.Invoke(this, EventArgs.Empty); this.OnClose?.Invoke(this, EventArgs.Empty);
} }
+1 -1
View File
@@ -19,7 +19,7 @@ namespace BarrageGrab
{ {
//ISystemProxy proxy = new FiddlerProxy(); //ISystemProxy proxy = new FiddlerProxy();
ISystemProxy proxy = new TitaniumProxy(); ISystemProxy proxy = new TitaniumProxy();
Appsetting appsetting = Appsetting.Current; AppSetting appsetting = AppSetting.Current;
/// <summary> /// <summary>
/// 进入直播间 /// 进入直播间
+15 -2
View File
@@ -70,12 +70,20 @@
<Reference Include="BrotliSharpLib, Version=0.3.2.0, Culture=neutral, PublicKeyToken=3f4e2a1cd615fcb7, processorArchitecture=MSIL"> <Reference Include="BrotliSharpLib, Version=0.3.2.0, Culture=neutral, PublicKeyToken=3f4e2a1cd615fcb7, processorArchitecture=MSIL">
<HintPath>..\packages\BrotliSharpLib.0.3.3\lib\net451\BrotliSharpLib.dll</HintPath> <HintPath>..\packages\BrotliSharpLib.0.3.3\lib\net451\BrotliSharpLib.dll</HintPath>
</Reference> </Reference>
<Reference Include="Esprima, Version=3.0.4.0, Culture=neutral, PublicKeyToken=2e92ba9c8d81157f, processorArchitecture=MSIL">
<HintPath>..\packages\Esprima.3.0.4\lib\net462\Esprima.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Fleck, Version=1.2.0.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="Fleck, Version=1.2.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Fleck.1.2.0\lib\net45\Fleck.dll</HintPath> <HintPath>..\packages\Fleck.1.2.0\lib\net45\Fleck.dll</HintPath>
</Reference> </Reference>
<Reference Include="HtmlAgilityPack, Version=1.11.51.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL"> <Reference Include="HtmlAgilityPack, Version=1.11.51.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
<HintPath>..\packages\HtmlAgilityPack.1.11.51\lib\Net45\HtmlAgilityPack.dll</HintPath> <HintPath>..\packages\HtmlAgilityPack.1.11.51\lib\Net45\HtmlAgilityPack.dll</HintPath>
</Reference> </Reference>
<Reference Include="Jint, Version=3.0.1.0, Culture=neutral, PublicKeyToken=2e92ba9c8d81157f, processorArchitecture=MSIL">
<HintPath>..\packages\Jint.3.0.1\lib\net462\Jint.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Win32.Registry, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> <Reference Include="Microsoft.Win32.Registry, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Win32.Registry.5.0.0\lib\net461\Microsoft.Win32.Registry.dll</HintPath> <HintPath>..\packages\Microsoft.Win32.Registry.5.0.0\lib\net461\Microsoft.Win32.Registry.dll</HintPath>
</Reference> </Reference>
@@ -135,7 +143,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="AppRuntime.cs" /> <Compile Include="AppRuntime.cs" />
<Compile Include="Appsetting.cs" /> <Compile Include="AppSetting.cs" />
<Compile Include="ComPortServer.cs" />
<Compile Include="Forms\FormView.cs"> <Compile Include="Forms\FormView.cs">
<SubType>Form</SubType> <SubType>Form</SubType>
</Compile> </Compile>
@@ -149,6 +158,7 @@
<Compile Include="Forms\RoomDetail.Designer.cs"> <Compile Include="Forms\RoomDetail.Designer.cs">
<DependentUpon>RoomDetail.cs</DependentUpon> <DependentUpon>RoomDetail.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="JsEngine.cs" />
<Compile Include="Logger.cs" /> <Compile Include="Logger.cs" />
<Compile Include="Modles\BusinessExecption.cs" /> <Compile Include="Modles\BusinessExecption.cs" />
<Compile Include="Modles\JsonEntity\BarrageMessages.cs" /> <Compile Include="Modles\JsonEntity\BarrageMessages.cs" />
@@ -167,7 +177,7 @@
<Compile Include="WinApi.cs" /> <Compile Include="WinApi.cs" />
<Compile Include="WssBarrageGrab.cs" /> <Compile Include="WssBarrageGrab.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="WsBarrageService.cs" /> <Compile Include="WsBarrageServer.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="App.config" /> <None Include="App.config" />
@@ -178,6 +188,9 @@
<None Include="Properties\app.manifest" /> <None Include="Properties\app.manifest" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Scripts\engine\comPortFilter.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Scripts\inject\livePage.js"> <Content Include="Scripts\inject\livePage.js">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
+2 -1
View File
@@ -2,9 +2,10 @@
<packages> <packages>
<package id="BouncyCastle.Cryptography" version="2.0.0" targetFramework="net48" /> <package id="BouncyCastle.Cryptography" version="2.0.0" targetFramework="net48" />
<package id="BrotliSharpLib" version="0.3.3" targetFramework="net48" /> <package id="BrotliSharpLib" version="0.3.3" targetFramework="net48" />
<package id="ColorConsole" version="1.0.1" targetFramework="net48" /> <package id="Esprima" version="3.0.4" targetFramework="net462" />
<package id="Fleck" version="1.2.0" targetFramework="net48" /> <package id="Fleck" version="1.2.0" targetFramework="net48" />
<package id="HtmlAgilityPack" version="1.11.51" targetFramework="net48" /> <package id="HtmlAgilityPack" version="1.11.51" targetFramework="net48" />
<package id="Jint" version="3.0.1" targetFramework="net462" />
<package id="Microsoft.Win32.Registry" version="5.0.0" targetFramework="net48" /> <package id="Microsoft.Win32.Registry" version="5.0.0" targetFramework="net48" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net48" /> <package id="Newtonsoft.Json" version="13.0.1" targetFramework="net48" />
<package id="NLog" version="5.2.3" targetFramework="net48" /> <package id="NLog" version="5.2.3" targetFramework="net48" />