From 11afaae1f75a33e9efd59ab7ababbce41697b958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=85=E6=B5=A9=E4=B8=9C?= <1083092844@qq.com> Date: Fri, 26 Apr 2024 10:19:14 +0800 Subject: [PATCH] =?UTF-8?q?com=20js=E8=BF=87=E6=BB=A4=E5=99=A8=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=20BitConvert=20=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BarrageGrab/ComPortServer.cs | 36 ++++++++-- BarrageGrab/JsEngine.cs | 76 +++++++++++++++++++-- BarrageGrab/Program.cs | 9 +-- BarrageGrab/Scripts/engine/comPortFilter.js | 46 ++++++++----- BarrageGrab/WsBarrageServer.cs | 18 ++--- 5 files changed, 144 insertions(+), 41 deletions(-) diff --git a/BarrageGrab/ComPortServer.cs b/BarrageGrab/ComPortServer.cs index bbdda9a..f328ea1 100644 --- a/BarrageGrab/ComPortServer.cs +++ b/BarrageGrab/ComPortServer.cs @@ -7,9 +7,13 @@ using System.IO.Ports; using Jint; using Jint.Runtime; using System.Windows.Forms; +using Jint.Native; namespace BarrageGrab { + /// + /// 串口服务 + /// public class ComPortServer : IDisposable { WsBarrageServer server; @@ -22,7 +26,15 @@ namespace BarrageGrab { jsEngine = JsEngine.CreateNewEngine(); var jsFile = JsEngine.GetJsFile("comPortFilter.js"); - jsEngine.Execute(jsFile); + try + { + jsEngine.Execute(jsFile); + } + catch (Exception ex) + { + Logger.LogError(ex, $"comPortFilter.js 执行错误: {ex.Message}"); + throw; + } } } @@ -50,6 +62,8 @@ namespace BarrageGrab { if (!sendPort.IsOpen) return; if (e == null) return; + if (e.Message == null) return; + if (!AppSetting.Current.UseComPortFilter) { var json = e.ToJson() + "\r\n"; @@ -57,7 +71,20 @@ namespace BarrageGrab Send(jbuff); return; } - var result = jsEngine.Invoke("onPackData", e.MsgType.GetHashCode(), e.Message); + + var roomInfo = AppRuntime.RoomCaches.GetCachedWebRoomInfo(e.Message.RoomId.ToString()); + JsValue result = null; + try + { + result = jsEngine.Invoke("onPackData", e.MsgType.GetHashCode(), e.Message, roomInfo); + } + catch (Exception ex) + { + Logger.LogError(ex, $"串口过滤器 onPackData 执行错误:{ex.Message}"); + return; + } + if (result == null) return; + var nocanTypes = new Types[] { Types.Null, @@ -115,15 +142,14 @@ namespace BarrageGrab sendPort.Open(); } catch (Exception ex) - { + { sendPort.Close(); sendPort.Dispose(); - sendPort = null; + sendPort = null; throw ex; } } - public void Dispose() { if (sendPort == null) return; diff --git a/BarrageGrab/JsEngine.cs b/BarrageGrab/JsEngine.cs index 05ccd97..0ba724f 100644 --- a/BarrageGrab/JsEngine.cs +++ b/BarrageGrab/JsEngine.cs @@ -12,6 +12,10 @@ namespace BarrageGrab { public static class JsEngine { + /// + /// 创建一个Js引擎 + /// + /// public static Engine CreateNewEngine() { var jsonParse = new Func((obj) => @@ -28,8 +32,15 @@ namespace BarrageGrab }); var engine = new Engine(); + + engine.Execute(@" + byteToUint8Array = function(arr){ + return new Uint8Array(arr); + }"); + engine.SetValue("console", new JsConsole()); engine.SetValue("encoder", new JsEncoder(engine)); + engine.SetValue("bitConvert", new JsBitConvert(engine)); return engine; } @@ -72,11 +83,7 @@ namespace BarrageGrab Engine eng; public JsEncoder(Engine eng) { - this.eng = eng; - eng.Execute(@" - byteToUint8Array = function(arr){ - return new Uint8Array(arr); - }"); + this.eng = eng; } private JsValue ByteConvert(byte[] buff) @@ -144,5 +151,64 @@ namespace BarrageGrab return Encoding.ASCII.GetString(bytes); } } + + class JsBitConvert + { + Engine eng; + public JsBitConvert(Engine eng) + { + this.eng = eng; + } + + private JsValue ByteConvert(byte[] buff) + { + return eng.Invoke("byteToUint8Array", buff); + } + + public JsValue toNumber(byte[] buff,int startIndex = 0) + { + return BitConverter.ToDouble(buff, startIndex); + } + + public bool toBoolean(byte[] buff, int startIndex = 0) + { + return BitConverter.ToBoolean(buff, startIndex); + } + + public string toString(byte[] buff, int startIndex = 0) + { + return BitConverter.ToString(buff, startIndex); + } + + public string toString(byte[] buff, int startIndex, int length) + { + return BitConverter.ToString(buff, startIndex, length); + } + + public JsValue getBytes(JsValue value) + { + byte[] buff = new byte[0]; + switch (value.Type) + { + case Jint.Runtime.Types.Empty: + case Jint.Runtime.Types.Undefined: + case Jint.Runtime.Types.Null: + break; + case Jint.Runtime.Types.Boolean: + buff = BitConverter.GetBytes(value.AsBoolean()); + break; + case Jint.Runtime.Types.Number: + buff = BitConverter.GetBytes(value.AsNumber()); + break; + case Jint.Runtime.Types.BigInt: + buff = BitConverter.GetBytes((long)value.AsNumber()); + break; + default: + throw new Exception($"不支持该类型转换:" + value.Type); + } + + return ByteConvert(buff); + } + } } } diff --git a/BarrageGrab/Program.cs b/BarrageGrab/Program.cs index 2ecb8e0..39b6cb8 100644 --- a/BarrageGrab/Program.cs +++ b/BarrageGrab/Program.cs @@ -134,11 +134,12 @@ namespace BarrageGrab return !createdNew; } } - +#if DEBUG private static void JintTest() { var jsEng = JsEngine.CreateNewEngine(); var jsFile = File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "Scripts", "engine", "comPortFilter.js"), Encoding.UTF8); + //var jsFile = @"D:\develop\Project\dy-barrage-grab\BarrageGrab\Scripts\engine\comPortFilter.js"; jsEng.Execute(jsFile); var result = jsEng.Invoke("onPackData", 1, new { @@ -149,9 +150,8 @@ namespace BarrageGrab { { "key1","value1" } } - }); - - Console.WriteLine("返回类型:" + result.Type.ToString()); + },null); + Console.WriteLine($"返回类型:{ result.Type.ToString()},值:{result.ToString()}"); if (result.Type == Types.String) { Console.WriteLine("返回String: " + result.ToString()); @@ -169,5 +169,6 @@ namespace BarrageGrab Console.WriteLine("返回Symbol: " + result.ToString()); } } +#endif } } diff --git a/BarrageGrab/Scripts/engine/comPortFilter.js b/BarrageGrab/Scripts/engine/comPortFilter.js index 7dc0ecb..50fabd5 100644 --- a/BarrageGrab/Scripts/engine/comPortFilter.js +++ b/BarrageGrab/Scripts/engine/comPortFilter.js @@ -1,28 +1,38 @@ -/** +/* * 注解:串口数据过滤脚本,可用于自定义配置串口的发送报文 * 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 + * 为了 工具环境: + * 1.控制台: console: 控制台输出 + * console.log, console.error, console.warn 这些日志将被输出到控制台, 其中error日志将被记录到日志文件 + * + * 2.编码器: encoder: 字符串 和 Uint8Array 互转 + * encoder.utf8ToBytes(str):Unit8Array ,encoder.utf8ToString(buff):String + * encoder.utf32ToBytes(str):Unit8Array ,encoder.utf32ToString(buff):String + * encoder.asciiToBytes(str):Unit8Array ,encoder.asciiToString(buff):String + * + * 3.Bit转换: bitConvert: 支持 Number,Boolean 与 Uint8Array 互转 + * bitConvert.toNumber(bytes, offset):Number + * bitConvert.toBoolean(bytes, offset):Boolean + * bitConvert.toString(bytes, offset, length):String + * bitConvert.toString(bytes, offset):String + * bitConvert.toString(bytes):String + * bitConvert.getBytes(value):Unit8Array 支持传入 Number,Boolean String请使用 encoder.utf8ToBytes */ /** * 这个函数由程序JS引擎调用,不要删除 - * @param {number} msgType 消息类型,如礼物,弹幕消息等,和程序内定义一致 - * @param {Object} msg 被WsBarrageServer简化后的消息对象,具体可参考Json实体文件 - * @returns {Uint8Array|string} 返回一个Uint8Array类型的数据,或者返回一个字符串,如果返回 null 则不发送数据。返回的数据将会被发送到串口 + * @param {number} msgType 消息类型,如礼物,弹幕消息等,和程序内定义一致 见 Modles\JsonEntity\BarrageMessages.cs PackMsgType 枚举 + * @param {Object} msg 被WsBarrageServer简化后的消息对象,具体可参考Json实体文件 见 Modles\JsonEntity\BarrageMessages.cs + * @param {Object} roomInfo 当前消息对应的房间信息 见 Modles\RoomInfo.cs 结构 + * @returns {Uint8Array|string} 返回一个Uint8Array类型的数据,或者返回一个字符串(将自动进行utf8编码),如果返回 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; +function onPackData(msgType, msg , roomInfo) { + let json = JSON.stringify(msg); + return json+"\n"; + // let excludeMsgType = [3, 6, 0]; // 过滤掉进入直播间和统计信息 + // if (excludeMsgType.includes(msgType)) return; + // var result = msg.Content + "\r\n"; + // return result; } diff --git a/BarrageGrab/WsBarrageServer.cs b/BarrageGrab/WsBarrageServer.cs index f1e0825..2db81d6 100644 --- a/BarrageGrab/WsBarrageServer.cs +++ b/BarrageGrab/WsBarrageServer.cs @@ -284,7 +284,7 @@ namespace BarrageGrab { MsgId = msg.Common.msgId, Content = msg.Content, - RoomId = msg.Common.roomId, + RoomId = msg.Common.roomId.ToString(), WebRoomId = AppRuntime.RoomCaches.GetCachedWebRoomid(msg.Common.roomId.ToString()), Type = msg.Type, User = GetUser(msg.User) @@ -310,7 +310,7 @@ namespace BarrageGrab TotalUserCount = msg.totalUser, TotalUserCountStr = msg.totalPvForAnchor, OnlineUserCountStr = msg.onlineUserForAnchor, - RoomId = msg.Common.roomId, + RoomId = msg.Common.roomId.ToString(), WebRoomId = AppRuntime.RoomCaches.GetCachedWebRoomid(msg.Common.roomId.ToString()), Content = $"当前直播间人数 {msg.onlineUserForAnchor},累计直播间人数 {msg.totalPvForAnchor}", User = null @@ -391,7 +391,7 @@ namespace BarrageGrab var enty = new GiftMsg() { MsgId = msg.Common.msgId, - RoomId = msg.Common.roomId, + RoomId = msg.Common.roomId.ToString(), WebRoomId = AppRuntime.RoomCaches.GetCachedWebRoomid(msg.Common.roomId.ToString()), Content = $"{msg.User.Nickname} 送出 {msg.Gift.Name}{(msg.Gift.Combo ? "(可连击)" : "")} x {msg.repeatCount}个,增量{count}个", DiamondCount = msg.Gift.diamondCount, @@ -429,7 +429,7 @@ namespace BarrageGrab { MsgId = msg.Common.msgId, Content = $"{msg.User.Nickname} 关注了主播", - RoomId = msg.Common.roomId, + RoomId = msg.Common.roomId.ToString(), WebRoomId = AppRuntime.RoomCaches.GetCachedWebRoomid(msg.Common.roomId.ToString()), User = GetUser(msg.User) }; @@ -459,7 +459,7 @@ namespace BarrageGrab { MsgId = msg.Common.msgId, Content = $"{msg.User.Nickname} 分享了直播间到{type}", - RoomId = msg.Common.roomId, + RoomId = msg.Common.roomId.ToString(), WebRoomId = AppRuntime.RoomCaches.GetCachedWebRoomid(msg.Common.roomId.ToString()), ShareType = type, User = GetUser(msg.User) @@ -486,7 +486,7 @@ namespace BarrageGrab { MsgId = msg.Common.msgId, Content = $"{msg.User.Nickname} 来了 直播间人数:{msg.memberCount}", - RoomId = msg.Common.roomId, + RoomId = msg.Common.roomId.ToString(), WebRoomId = AppRuntime.RoomCaches.GetCachedWebRoomid(msg.Common.roomId.ToString()), CurrentCount = msg.memberCount, User = GetUser(msg.User) @@ -512,7 +512,7 @@ namespace BarrageGrab MsgId = msg.Common.msgId, Count = msg.Count, Content = $"{msg.User.Nickname} 为主播点了{msg.Count}个赞,总点赞{msg.Total}", - RoomId = msg.Common.roomId, + RoomId = msg.Common.roomId.ToString(), WebRoomId = AppRuntime.RoomCaches.GetCachedWebRoomid(msg.Common.roomId.ToString()), Total = msg.Total, User = GetUser(msg.User) @@ -536,7 +536,7 @@ namespace BarrageGrab { MsgId = msg.Common.msgId, Content = msg.Content, - RoomId = msg.Common.roomId, + RoomId = msg.Common.roomId.ToString(), WebRoomId = AppRuntime.RoomCaches.GetCachedWebRoomid(msg.Common.roomId.ToString()), User = GetUser(msg.User), }; @@ -563,7 +563,7 @@ namespace BarrageGrab { MsgId = msg.Common.msgId, Content = "直播已结束", - RoomId = msg.Common.roomId, + RoomId = msg.Common.roomId.ToString(), WebRoomId = AppRuntime.RoomCaches.GetCachedWebRoomid(msg.Common.roomId.ToString()), User = null };