添加ComPort 推送服务
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<!--配置更改后重启才能生效-->
|
||||
<appSettings>
|
||||
@@ -42,6 +42,10 @@
|
||||
<add key="pollingInterval" value="3000" />
|
||||
<!--禁用直播页浏览器脚本缓存 (如果需要确保脚本每次能够正常匹配替换,则启用它,可能会损失一定的页面加载速度)-->
|
||||
<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>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
|
||||
@@ -18,12 +18,17 @@ namespace BarrageGrab
|
||||
/// <summary>
|
||||
/// Ws弹幕服务示例
|
||||
/// </summary>
|
||||
public static WsBarrageService WssService { get; private set; } = new WsBarrageService();
|
||||
public static WsBarrageServer WsServer { get; private set; }
|
||||
|
||||
/// <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>
|
||||
/// 程序进程信息
|
||||
@@ -35,6 +40,13 @@ namespace BarrageGrab
|
||||
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
WsServer = new WsBarrageServer();
|
||||
RoomCaches = new RoomCacheManager();
|
||||
ComPortServer = new ComPortServer(WsServer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 隐藏/显示 控制台
|
||||
/// </summary>
|
||||
|
||||
+53
-10
@@ -10,13 +10,13 @@ using System.Drawing;
|
||||
|
||||
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
|
||||
{
|
||||
@@ -41,6 +41,40 @@ namespace BarrageGrab
|
||||
DisableLivePageScriptCache = bool.Parse(AppSettings["disableLivePageScriptCache"].Trim());
|
||||
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 pushFilter = AppSettings["pushFilter"].Trim().ToLower();
|
||||
var logFilter = AppSettings["logFilter"].Trim().ToLower();
|
||||
@@ -60,12 +94,6 @@ namespace BarrageGrab
|
||||
else LogFilter = logFilter.Split(',').Select(x => int.Parse(x)).ToArray();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.PrintColor("配置文件读取失败,请检查配置文件是否正确");
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
@@ -200,5 +228,20 @@ namespace BarrageGrab
|
||||
/// 禁用直播页面脚本缓存
|
||||
/// </summary>
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,9 +20,9 @@ namespace BarrageGrab
|
||||
{
|
||||
static int printCount = 0;
|
||||
|
||||
WsBarrageService barServer = AppRuntime.WssService;
|
||||
WssBarrageGrab grab = AppRuntime.WssService.Grab;
|
||||
ISystemProxy proxy = AppRuntime.WssService.Grab.Proxy;
|
||||
WsBarrageServer barServer = AppRuntime.WsServer;
|
||||
WssBarrageGrab grab = AppRuntime.WsServer.Grab;
|
||||
ISystemProxy proxy = AppRuntime.WsServer.Grab.Proxy;
|
||||
|
||||
public FormView()
|
||||
{
|
||||
@@ -32,7 +32,7 @@ namespace BarrageGrab
|
||||
AppRuntime.RoomCaches.OnCache += RoomCaches_OnCache;
|
||||
this.txb_wsaddr.Text = barServer.ServerLocation;
|
||||
this.txb_upstreamProxy.Text = proxy.HttpUpstreamProxy;
|
||||
this.cbx_barrageLog.Checked = Appsetting.Current.BarrageLog;
|
||||
this.cbx_barrageLog.Checked = AppSetting.Current.BarrageLog;
|
||||
InitTabPages();
|
||||
}
|
||||
|
||||
@@ -67,17 +67,17 @@ namespace BarrageGrab
|
||||
if (page == this.tabPage_Ws)
|
||||
{
|
||||
type = "ws";
|
||||
ck.Checked = Appsetting.Current.PushFilter.Contains(label.Key);
|
||||
ck.Checked = AppSetting.Current.PushFilter.Contains(label.Key);
|
||||
}
|
||||
if (page == this.tabPage_Console)
|
||||
{
|
||||
type = "console";
|
||||
ck.Checked = Appsetting.Current.PrintFilter.Contains(label.Key);
|
||||
ck.Checked = AppSetting.Current.PrintFilter.Contains(label.Key);
|
||||
}
|
||||
if (page == this.tabPage_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.CheckedChanged += Ck_CheckedChanged;
|
||||
@@ -94,17 +94,17 @@ namespace BarrageGrab
|
||||
var selected = GetCheckedBarTypes((FlowLayoutPanel)cbx.Parent);
|
||||
if (cbx.Parent.Parent == this.tabPage_Console)
|
||||
{
|
||||
Appsetting.Current.PrintFilter = selected;
|
||||
AppSetting.Current.PrintFilter = selected;
|
||||
}
|
||||
if (cbx.Parent.Parent == this.tabPage_Ws)
|
||||
{
|
||||
Appsetting.Current.PushFilter = selected;
|
||||
AppSetting.Current.PushFilter = selected;
|
||||
}
|
||||
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)
|
||||
@@ -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
|
||||
//颜色转换
|
||||
Color color = Appsetting.Current.ColorMap[e.MsgType].Item2;
|
||||
Color color = AppSetting.Current.ColorMap[e.MsgType].Item2;
|
||||
string msg = e.Message;
|
||||
|
||||
this.Invoke(new Action(() =>
|
||||
@@ -218,8 +218,8 @@ namespace BarrageGrab
|
||||
try
|
||||
{
|
||||
proxy.SetUpstreamProxy(text);
|
||||
Appsetting.Current.UpstreamProxy = text;
|
||||
Appsetting.Current.Save();
|
||||
AppSetting.Current.UpstreamProxy = text;
|
||||
AppSetting.Current.Save();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -231,8 +231,8 @@ namespace BarrageGrab
|
||||
private void cbx_barrageLog_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
var checker = (CheckBox)sender;
|
||||
Appsetting.Current.BarrageLog = checker.Checked;
|
||||
Appsetting.Current.Save();
|
||||
AppSetting.Current.BarrageLog = checker.Checked;
|
||||
AppSetting.Current.Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,9 +94,9 @@ namespace BarrageGrab
|
||||
/// <param name="msg">弹幕内容</param>
|
||||
public static void LogBarrage(PackMsgType type, Msg msg)
|
||||
{
|
||||
if (!Appsetting.Current.BarrageLog) return;
|
||||
if (!AppSetting.Current.BarrageLog) 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
|
||||
{
|
||||
@@ -135,7 +135,7 @@ namespace BarrageGrab
|
||||
text += $" [{msg.User?.GenderToString()}] ";
|
||||
}
|
||||
|
||||
ConsoleColor color = Appsetting.Current.ColorMap[barType].Item1;
|
||||
ConsoleColor color = AppSetting.Current.ColorMap[barType].Item1;
|
||||
var append = msg.Content;
|
||||
switch (barType)
|
||||
{
|
||||
|
||||
+90
-32
@@ -6,6 +6,9 @@ using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.IO;
|
||||
using Jint.Runtime;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace BarrageGrab
|
||||
{
|
||||
@@ -14,9 +17,14 @@ namespace BarrageGrab
|
||||
static FormView mainForm = null;
|
||||
static bool exited = false;
|
||||
static bool formExited = false;
|
||||
static WinApi.ControlCtrlDelegate controlCtr = ControlCtrlHandle;
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
//JintTest();
|
||||
//Console.WriteLine("结束");
|
||||
//Console.ReadKey();
|
||||
//return;
|
||||
if (CheckAlreadyRunning())
|
||||
{
|
||||
Logger.PrintColor("已经有一个监听程序在运行,按任意键退出...");
|
||||
@@ -25,19 +33,51 @@ namespace BarrageGrab
|
||||
}
|
||||
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();//禁用控制台快速编辑模式
|
||||
AppRuntime.DisplayConsole(!Appsetting.Current.HideConsole);//控制控制台可见
|
||||
AppRuntime.WssService.Grab.Proxy.SetUpstreamProxy(Appsetting.Current.UpstreamProxy);//设置上游代理
|
||||
AppRuntime.WssService.StartListen();//启动WS服务
|
||||
AppRuntime.DisplayConsole(!AppSetting.Current.HideConsole);//控制控制台可见
|
||||
AppRuntime.WsServer.Grab.Proxy.SetUpstreamProxy(AppSetting.Current.UpstreamProxy);//设置上游代理
|
||||
AppRuntime.WsServer.OnClose += (s, e) =>
|
||||
{
|
||||
exited = true;
|
||||
};
|
||||
|
||||
Logger.LogSucc($"{AppRuntime.WssService.ServerLocation} 弹幕服务已启动...");
|
||||
SetTitle($"抖音弹幕监听推送 [{AppRuntime.WssService.ServerLocation}]");
|
||||
|
||||
AppRuntime.WssService.OnClose += (s, e) => exited = true;
|
||||
//串口写入服务
|
||||
if (!AppSetting.Current.ComPort.IsNullOrWhiteSpace())
|
||||
{
|
||||
AppRuntime.ComPortServer.OpenStart();
|
||||
}
|
||||
|
||||
//显示窗体
|
||||
if (Appsetting.Current.ShowWindow)
|
||||
if (AppSetting.Current.ShowWindow)
|
||||
{
|
||||
var uiThread = new Thread(new ThreadStart(() =>
|
||||
{
|
||||
@@ -45,33 +85,16 @@ namespace BarrageGrab
|
||||
//开启消息循环
|
||||
System.Windows.Forms.Application.Run(mainForm);
|
||||
formExited = true;
|
||||
AppRuntime.WsServer.Dispose();//Close后自动释放资源
|
||||
}));
|
||||
uiThread.SetApartmentState(ApartmentState.STA);
|
||||
uiThread.IsBackground = true;
|
||||
uiThread.Start();
|
||||
}
|
||||
|
||||
while (!exited)
|
||||
{
|
||||
if (formExited && !exited)
|
||||
{
|
||||
AppRuntime.WssService.Close();
|
||||
}
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
|
||||
Logger.PrintColor("服务器已关闭...");
|
||||
|
||||
//if (!mainForm.IsDisposed)
|
||||
//{
|
||||
// mainForm.Invoke(new Action(() =>
|
||||
// {
|
||||
// mainForm.Close();
|
||||
// }));
|
||||
//}
|
||||
|
||||
//退出程序,不显示 按任意键退出
|
||||
//Environment.Exit(0);
|
||||
AppRuntime.WsServer.StartListen();//启动WS以及代理服务
|
||||
Logger.LogSucc($"{AppRuntime.WsServer.ServerLocation} 弹幕服务已启动...");
|
||||
SetTitle($"抖音弹幕监听推送 [{AppRuntime.WsServer.ServerLocation}]");
|
||||
}
|
||||
|
||||
//检测设置控制台标题
|
||||
@@ -84,7 +107,7 @@ namespace BarrageGrab
|
||||
}
|
||||
|
||||
//监听控制台消息事件
|
||||
private static bool ControlCtrlDelegate(int CtrlType)
|
||||
private static bool ControlCtrlHandle(int CtrlType)
|
||||
{
|
||||
switch (CtrlType)
|
||||
{
|
||||
@@ -94,7 +117,7 @@ namespace BarrageGrab
|
||||
break;
|
||||
case 2:
|
||||
Logger.PrintColor("2工具被强制关闭");//按控制台关闭按钮关闭
|
||||
AppRuntime.WssService.Close();
|
||||
AppRuntime.WsServer.Dispose();
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
@@ -111,5 +134,40 @@ namespace BarrageGrab
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace BarrageGrab.Proxy
|
||||
/// <summary>
|
||||
/// 代理端口
|
||||
/// </summary>
|
||||
public int ProxyPort { get { return Appsetting.Current.ProxyPort; } }
|
||||
public int ProxyPort { get { return AppSetting.Current.ProxyPort; } }
|
||||
|
||||
public abstract string HttpUpstreamProxy { get; }
|
||||
|
||||
@@ -55,11 +55,11 @@ namespace BarrageGrab.Proxy
|
||||
{
|
||||
host = host.Trim().ToLower();
|
||||
|
||||
if (!Appsetting.Current.FilterHostName) return true;
|
||||
if (!AppSetting.Current.FilterHostName) 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;
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ namespace BarrageGrab.Proxy
|
||||
var scriptContext = BuildContext(new Dictionary<string, string>()
|
||||
{
|
||||
{"PROCESS_NAME","'{processName}'"},
|
||||
{"AUTOPAUSE",Appsetting.Current.AutoPause.ToString().ToLower()}
|
||||
{"AUTOPAUSE",AppSetting.Current.AutoPause.ToString().ToLower()}
|
||||
});
|
||||
liveRoomInjectScript = scriptContext + liveRoomInjectScript;
|
||||
var html = await e.GetResponseBodyAsString();
|
||||
@@ -275,7 +275,7 @@ namespace BarrageGrab.Proxy
|
||||
}
|
||||
|
||||
//给script标签 src加上时间戳避免缓存
|
||||
if (Appsetting.Current.DisableLivePageScriptCache)
|
||||
if (AppSetting.Current.DisableLivePageScriptCache)
|
||||
{
|
||||
var scripts = doc.DocumentNode.SelectNodes("//script[@src]");
|
||||
if (scripts != null)
|
||||
@@ -311,7 +311,7 @@ namespace BarrageGrab.Proxy
|
||||
var scriptContext = BuildContext(new Dictionary<string, string>()
|
||||
{
|
||||
{"PROCESS_NAME","'{processName}'"},
|
||||
{"AUTOPAUSE",Appsetting.Current.AutoPause.ToString().ToLower()}
|
||||
{"AUTOPAUSE",AppSetting.Current.AutoPause.ToString().ToLower()}
|
||||
});
|
||||
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 js = await e.GetResponseBodyAsString();
|
||||
@@ -393,7 +393,7 @@ namespace BarrageGrab.Proxy
|
||||
var pollingIntervalMatch = pollingIntervalReg.Match(js);
|
||||
if (pollingIntervalMatch.Success)
|
||||
{
|
||||
var myValue = Appsetting.Current.PollingInterval;
|
||||
var myValue = AppSetting.Current.PollingInterval;
|
||||
js = pollingIntervalReg.Replace(js, $"this.pollingInterval={myValue},");
|
||||
Logger.PrintColor($"直播间已成功修改轮询间隔为{myValue}ms", ConsoleColor.Green);
|
||||
}
|
||||
@@ -515,7 +515,7 @@ namespace BarrageGrab.Proxy
|
||||
{
|
||||
proxyServer.Stop();
|
||||
proxyServer.Dispose();
|
||||
if (Appsetting.Current.UsedProxy)
|
||||
if (AppSetting.Current.UsedProxy)
|
||||
{
|
||||
CloseSystemProxy();
|
||||
}
|
||||
@@ -526,8 +526,8 @@ namespace BarrageGrab.Proxy
|
||||
/// </summary>
|
||||
override public void Start()
|
||||
{
|
||||
proxyServer.Start(Appsetting.Current.UsedProxy);
|
||||
if (Appsetting.Current.UsedProxy)
|
||||
proxyServer.Start(AppSetting.Current.UsedProxy);
|
||||
if (AppSetting.Current.UsedProxy)
|
||||
{
|
||||
proxyServer.SetAsSystemHttpProxy(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;
|
||||
}
|
||||
@@ -20,10 +20,15 @@ using System.Collections.Concurrent;
|
||||
|
||||
namespace BarrageGrab
|
||||
{
|
||||
/// <summary>
|
||||
/// WsBarrageServer 包装消息事件委托
|
||||
/// </summary>
|
||||
public delegate void PackMessageEventHandler(WsBarrageServer sender, WsBarrageServer.PackMsgEventArgs e);
|
||||
|
||||
/// <summary>
|
||||
/// 弹幕服务
|
||||
/// </summary>
|
||||
public class WsBarrageServer
|
||||
public class WsBarrageServer:IDisposable
|
||||
{
|
||||
WebSocketServer socketServer; //Ws服务器对象
|
||||
Dictionary<string, UserState> socketList = new Dictionary<string, UserState>(); //客户端列表
|
||||
@@ -31,25 +36,29 @@ namespace BarrageGrab
|
||||
Timer dieout = new Timer(10000);//离线客户端清理计时器
|
||||
Timer giftCountTimer = new Timer(10000);//礼物缓存清理计时器
|
||||
WssBarrageGrab grab = new WssBarrageGrab();//弹幕解析器核心
|
||||
Appsetting Appsetting = Appsetting.Current;//全局配置文件实例
|
||||
AppSetting Appsetting = AppSetting.Current;//全局配置文件实例
|
||||
static int printCount = 0; //控制台输出计数,用于判断清理控制台
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// WS服务器启动地址
|
||||
/// </summary>
|
||||
public string ServerLocation { get { return socketServer.Location; } }
|
||||
public string ServerLocation => socketServer.Location;
|
||||
|
||||
/// <summary>
|
||||
/// 数据内核
|
||||
/// </summary>
|
||||
public WssBarrageGrab Grab { get { return grab; } }
|
||||
public WssBarrageGrab Grab => grab;
|
||||
|
||||
/// <summary>
|
||||
/// 控制台打印事件
|
||||
/// </summary>
|
||||
public event EventHandler<PrintEventArgs> OnPrint;
|
||||
|
||||
/// <summary>
|
||||
/// 是否已经释放资源
|
||||
/// </summary>
|
||||
public bool IsDisposed { get; private set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 服务关闭后触发
|
||||
/// </summary>
|
||||
@@ -58,7 +67,7 @@ namespace BarrageGrab
|
||||
/// <summary>
|
||||
/// 消息包装完成后触发
|
||||
/// </summary>
|
||||
public event EventHandler<PackMsgEventArgs> OnPackMessage;
|
||||
public event PackMessageEventHandler OnPackMessage;
|
||||
|
||||
public WsBarrageServer()
|
||||
{
|
||||
@@ -111,12 +120,12 @@ namespace BarrageGrab
|
||||
//判断Rommid是否符合拦截规则
|
||||
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());
|
||||
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()}] ";
|
||||
}
|
||||
|
||||
ConsoleColor color = Appsetting.Current.ColorMap[barType].Item1;
|
||||
ConsoleColor color = AppSetting.Current.ColorMap[barType].Item1;
|
||||
var append = msg.Content;
|
||||
switch (barType)
|
||||
{
|
||||
@@ -176,13 +185,13 @@ namespace BarrageGrab
|
||||
|
||||
text += append;
|
||||
|
||||
if (Appsetting.Current.BarrageLog)
|
||||
if (AppSetting.Current.BarrageLog)
|
||||
{
|
||||
Logger.LogBarrage(barType, msg);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
@@ -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;
|
||||
var arg = new PackMsgEventArgs()
|
||||
@@ -210,7 +219,7 @@ namespace BarrageGrab
|
||||
Message = msg
|
||||
};
|
||||
//异步执行
|
||||
Task.Run(() => OnPackMessage(this, arg));
|
||||
OnPackMessage(this, arg);
|
||||
}
|
||||
|
||||
//粉丝团
|
||||
@@ -524,7 +533,7 @@ namespace BarrageGrab
|
||||
switch (cmdPack.Cmd)
|
||||
{
|
||||
case CommandCode.Close:
|
||||
this.Close();
|
||||
this.Dispose();
|
||||
break;
|
||||
case CommandCode.EnableProxy:
|
||||
{
|
||||
@@ -566,7 +575,7 @@ namespace BarrageGrab
|
||||
public void Broadcast(BarrageMsgPack pack)
|
||||
{
|
||||
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>();
|
||||
foreach (var item in socketList)
|
||||
@@ -589,21 +598,29 @@ namespace BarrageGrab
|
||||
/// 开始监听
|
||||
/// </summary>
|
||||
public void StartListen()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.grab.Start(); //启动代理
|
||||
this.socketServer.Start(Listen);//启动监听
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
this.Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭服务器连接,并关闭系统代理
|
||||
/// </summary>
|
||||
public void Close()
|
||||
public void Dispose()
|
||||
{
|
||||
socketList.Values.ToList().ForEach(f => f.Socket.Close());
|
||||
socketList.Clear();
|
||||
socketServer.Dispose();
|
||||
grab.Dispose();
|
||||
|
||||
this.IsDisposed = true;
|
||||
this.OnClose?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace BarrageGrab
|
||||
{
|
||||
//ISystemProxy proxy = new FiddlerProxy();
|
||||
ISystemProxy proxy = new TitaniumProxy();
|
||||
Appsetting appsetting = Appsetting.Current;
|
||||
AppSetting appsetting = AppSetting.Current;
|
||||
|
||||
/// <summary>
|
||||
/// 进入直播间
|
||||
|
||||
@@ -70,12 +70,20 @@
|
||||
<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>
|
||||
</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">
|
||||
<HintPath>..\packages\Fleck.1.2.0\lib\net45\Fleck.dll</HintPath>
|
||||
</Reference>
|
||||
<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>
|
||||
</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">
|
||||
<HintPath>..\packages\Microsoft.Win32.Registry.5.0.0\lib\net461\Microsoft.Win32.Registry.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -135,7 +143,8 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AppRuntime.cs" />
|
||||
<Compile Include="Appsetting.cs" />
|
||||
<Compile Include="AppSetting.cs" />
|
||||
<Compile Include="ComPortServer.cs" />
|
||||
<Compile Include="Forms\FormView.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
@@ -149,6 +158,7 @@
|
||||
<Compile Include="Forms\RoomDetail.Designer.cs">
|
||||
<DependentUpon>RoomDetail.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="JsEngine.cs" />
|
||||
<Compile Include="Logger.cs" />
|
||||
<Compile Include="Modles\BusinessExecption.cs" />
|
||||
<Compile Include="Modles\JsonEntity\BarrageMessages.cs" />
|
||||
@@ -167,7 +177,7 @@
|
||||
<Compile Include="WinApi.cs" />
|
||||
<Compile Include="WssBarrageGrab.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="WsBarrageService.cs" />
|
||||
<Compile Include="WsBarrageServer.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
@@ -178,6 +188,9 @@
|
||||
<None Include="Properties\app.manifest" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Scripts\engine\comPortFilter.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Scripts\inject\livePage.js">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
<packages>
|
||||
<package id="BouncyCastle.Cryptography" version="2.0.0" 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="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="Newtonsoft.Json" version="13.0.1" targetFramework="net48" />
|
||||
<package id="NLog" version="5.2.3" targetFramework="net48" />
|
||||
|
||||
Reference in New Issue
Block a user