using Newtonsoft.Json.Linq; #nullable enable namespace BililiveRecorder.Core.Api.Danmaku { internal enum DanmakuMsgType { /// /// 彈幕 /// Comment, /// /// 禮物 /// GiftSend, /// /// 直播開始 /// LiveStart, /// /// 直播結束 /// LiveEnd, /// /// 其他 /// Unknown, /// /// 购买船票(上船) /// GuardBuy, /// /// SuperChat /// SuperChat, /// /// 房间信息更新 /// RoomChange, /// /// 房间被锁定 /// RoomLock, /// /// 直播被切断 /// CutOff, } internal class DanmakuModel { /// /// 消息類型 /// public DanmakuMsgType MsgType { get; set; } /// /// 房间标题 /// public string? Title { get; set; } /// /// 大分区 /// public string? ParentAreaName { get; set; } /// /// 子分区 /// public string? AreaName { get; set; } /// /// 彈幕內容 /// 此项有值的消息类型: /// /// /// public string? CommentText { get; set; } /// /// 消息触发者用户名 /// 此项有值的消息类型: /// /// /// /// /// /// /// public string? UserName { get; set; } /// /// SC 价格 /// public double Price { get; set; } /// /// SC 保持时间 /// public int SCKeepTime { get; set; } /// /// 消息触发者用户ID /// 此项有值的消息类型: /// /// /// /// /// /// /// public long UserID { get; set; } /// /// 用户舰队等级 /// 0 为非船员 1 为总督 2 为提督 3 为舰长 /// 此项有值的消息类型: /// /// /// /// /// public int UserGuardLevel { get; set; } /// /// 禮物名稱 /// public string? GiftName { get; set; } /// /// 礼物数量 /// 此项有值的消息类型: /// /// /// /// 此字段也用于标识上船 的数量(月数) /// public int GiftCount { get; set; } /// /// 该用户是否为房管(包括主播) /// 此项有值的消息类型: /// /// /// /// public bool IsAdmin { get; set; } /// /// 是否VIP用戶(老爺) /// 此项有值的消息类型: /// /// /// /// public bool IsVIP { get; set; } /// /// , 事件对应的房间号 /// public string? RoomID { get; set; } /// /// 原始数据 /// public string RawString { get; set; } /// /// 原始数据 /// public JObject? RawObject { get; set; } private DanmakuModel() { this.RawString = string.Empty; } public DanmakuModel(string json) { this.RawString = json; var obj = JObject.Parse(json); this.RawObject = obj; var cmd = obj["cmd"]?.ToObject(); if (cmd?.StartsWith("DANMU_MSG:") ?? false) cmd = "DANMU_MSG"; switch (cmd) { case "LIVE": // 开播 this.MsgType = DanmakuMsgType.LiveStart; this.RoomID = obj["roomid"]?.ToObject(); break; case "PREPARING": // 下播 this.MsgType = DanmakuMsgType.LiveEnd; this.RoomID = obj["roomid"]?.ToObject(); break; case "DANMU_MSG": // 弹幕 this.MsgType = DanmakuMsgType.Comment; this.CommentText = obj["info"]?[1]?.ToObject(); this.UserID = obj["info"]?[2]?[0]?.ToObject() ?? 0; this.UserName = obj["info"]?[2]?[1]?.ToObject(); this.IsAdmin = obj["info"]?[2]?[2]?.ToObject() == "1"; this.IsVIP = obj["info"]?[2]?[3]?.ToObject() == "1"; this.UserGuardLevel = obj["info"]?[7]?.ToObject() ?? 0; break; case "SEND_GIFT": // 送礼物 this.MsgType = DanmakuMsgType.GiftSend; this.GiftName = obj["data"]?["giftName"]?.ToObject(); this.UserName = obj["data"]?["uname"]?.ToObject(); this.UserID = obj["data"]?["uid"]?.ToObject() ?? 0; this.GiftCount = obj["data"]?["num"]?.ToObject() ?? 0; break; case "GUARD_BUY": // 购买舰长 { this.MsgType = DanmakuMsgType.GuardBuy; this.UserID = obj["data"]?["uid"]?.ToObject() ?? 0; this.UserName = obj["data"]?["username"]?.ToObject(); this.UserGuardLevel = obj["data"]?["guard_level"]?.ToObject() ?? 0; this.GiftName = this.UserGuardLevel == 3 ? "舰长" : this.UserGuardLevel == 2 ? "提督" : this.UserGuardLevel == 1 ? "总督" : ""; this.GiftCount = obj["data"]?["num"]?.ToObject() ?? 0; break; } case "SUPER_CHAT_MESSAGE": // SC { this.MsgType = DanmakuMsgType.SuperChat; this.CommentText = obj["data"]?["message"]?.ToString(); this.UserID = obj["data"]?["uid"]?.ToObject() ?? 0; this.UserName = obj["data"]?["user_info"]?["uname"]?.ToString(); this.Price = obj["data"]?["price"]?.ToObject() ?? 0; this.SCKeepTime = obj["data"]?["time"]?.ToObject() ?? 0; break; } case "ROOM_CHANGE": // 房间信息变更 { this.MsgType = DanmakuMsgType.RoomChange; this.Title = obj["data"]?["title"]?.ToObject(); this.AreaName = obj["data"]?["area_name"]?.ToObject(); this.ParentAreaName = obj["data"]?["parent_area_name"]?.ToObject(); break; } case "ROOM_LOCK": // 房间被锁定 { this.MsgType = DanmakuMsgType.RoomLock; break; } case "CUT_OFF": // 直播被切断 { this.MsgType = DanmakuMsgType.CutOff; break; } default: { this.MsgType = DanmakuMsgType.Unknown; break; } } } } }