using System.Collections.Generic; using Newtonsoft.Json.Linq; namespace BarrageGrab.Modles.BiliProtoEntity { /// /// B站直播弹幕WS协议操作码 /// public enum BiliOperation { /// 客户端心跳 HEARTBEAT = 2, /// 服务器心跳回复 (人气值) HEARTBEAT_REPLY = 3, /// 普通消息 (弹幕/礼物/进房等) MESSAGE = 5, /// 客户端认证请求 AUTH = 7, /// 服务器认证回复 AUTH_REPLY = 8 } /// /// B站WS协议版本 (影响Payload压缩方式) /// public enum BiliProtocolVersion { /// JSON明文 PLAIN = 0, /// 认证用JSON PLAIN_AUTH = 1, /// Zlib压缩 (内部可能含多个包) ZLIB = 2, /// Brotli压缩 (内部可能含多个包) BROTLI = 3 } /// /// B站WS协议帧头 (16字节, Big-Endian) /// public struct BiliSocketFrame { /// 整个包长度 (header+body) public uint PacketLength; /// 头长度 (固定16) public ushort HeaderLength; /// 协议版本 public BiliProtocolVersion ProtocolVersion; /// 操作码 public BiliOperation Operation; /// 序列号 (固定1) public uint SequenceId; public const int HEADER_SIZE = 16; /// 从字节缓冲区解析帧头 public static bool TryParse(byte[] buffer, int offset, int count, out BiliSocketFrame frame) { frame = default(BiliSocketFrame); if (buffer == null || count < HEADER_SIZE) return false; // Big-Endian 解析 frame.PacketLength = ReadUInt32BE(buffer, offset); frame.HeaderLength = ReadUInt16BE(buffer, offset + 4); frame.ProtocolVersion = (BiliProtocolVersion)ReadUInt16BE(buffer, offset + 6); frame.Operation = (BiliOperation)ReadUInt32BE(buffer, offset + 8); frame.SequenceId = ReadUInt32BE(buffer, offset + 12); return frame.HeaderLength >= HEADER_SIZE && frame.PacketLength >= HEADER_SIZE; } /// 帧体数据 (从 HeaderLength 开始到 PacketLength) public static byte[] GetPayload(byte[] buffer, int offset, BiliSocketFrame frame) { int bodyLen = (int)frame.PacketLength - frame.HeaderLength; if (bodyLen <= 0) return new byte[0]; var data = new byte[bodyLen]; System.Array.Copy(buffer, offset + frame.HeaderLength, data, 0, bodyLen); return data; } public static uint ReadUInt32BE(byte[] buf, int off) { return (uint)((buf[off] << 24) | (buf[off + 1] << 16) | (buf[off + 2] << 8) | buf[off + 3]); } public static ushort ReadUInt16BE(byte[] buf, int off) { return (ushort)((buf[off] << 8) | buf[off + 1]); } } /// /// B站弹幕消息 (cmd字段用于路由) /// public class BiliMessage { /// 消息类型 (DANMU_MSG / SEND_GIFT / INTERACT_WORD 等) public string Cmd { get; set; } /// 原始数据 public JObject Raw { get; set; } } /// /// B站弹幕消息 cmd 列表 (用于识别已知类型) /// public static class BiliCmd { public const string DANMU_MSG = "DANMU_MSG"; public const string SEND_GIFT = "SEND_GIFT"; public const string INTERACT_WORD = "INTERACT_WORD"; public const string LIKE_INFO_V3_CLICK = "LIKE_INFO_V3_CLICK"; public const string ONLINE_RANK_COUNT = "ONLINE_RANK_COUNT"; public const string WATCHED_CHANGE = "WATCHED_CHANGE"; public const string LIVE = "LIVE"; public const string PREPARING = "PREPARING"; public const string ROOM_REAL_TIME_MESSAGE_UPDATE = "ROOM_REAL_TIME_MESSAGE_UPDATE"; public const string SUPER_CHAT_MESSAGE = "SUPER_CHAT_MESSAGE"; } /// /// B站弹幕消息(DANMU_MSG)简化结构 /// public class BiliDanmuMsg { /// 弹幕内容 (info[1]) public string Content { get; set; } /// 用户UID (info[2][0]) public long Uid { get; set; } /// 用户昵称 (info[2][1]) public string Uname { get; set; } /// 管理员? (info[2][2]==1) public bool IsAdmin { get; set; } /// 主播? (info[2][4]存在) public bool IsAnchor { get; set; } } /// /// B站礼物消息(SEND_GIFT.data)简化结构 /// public class BiliGiftData { public long Uid { get; set; } public string Uname { get; set; } public string Face { get; set; } public uint GiftId { get; set; } public string GiftName { get; set; } /// 礼物数量 public uint Num { get; set; } /// 本批次礼物数 (连击时为本次增量) public uint ComboNum { get; set; } /// 礼物连击总数 public uint SuperBatchNum { get; set; } /// 价格 (1 = 1000金瓜子) public long Price { get; set; } /// 金币类型 gold=付费 silver=免费 public string CoinType { get; set; } /// 礼物图片 public string GifUrl { get; set; } } /// /// B站进房/关注消息(INTERACT_WORD.data)简化结构 /// public class BiliInteractData { public long Uid { get; set; } public string Uname { get; set; } /// 1=进入 2=关注 3=分享 public int MsgType { get; set; } } /// /// B站点赞消息(LIKE_INFO_V3_CLICK.data)简化结构 /// public class BiliLikeData { public long Uid { get; set; } public string Uname { get; set; } public string LikeText { get; set; } } /// /// B站房间统计(ONLINE_RANK_COUNT.data / ROOM_REAL_TIME_MESSAGE_UPDATE.data)简化结构 /// public class BiliRoomStats { /// 在线人数 public long Online { get; set; } /// 看过人数 public long Watched { get; set; } } }