using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using Newtonsoft.Json.Linq; using Newtonsoft.Json; namespace BarrageGrab.Modles { [Serializable] public class RoomInfo { /// /// Web房间号 /// public string WebRoomId { get; set; } /// /// 房间号 /// public string RoomId { get; set; } /// /// 直播间名称 /// public string Title { get; set; } /// /// 是否直播中 /// public bool IsLive { get; set; } /// /// 实时在线人数 /// public long UserCount { get; set; } /// /// 累计在线人数 /// public string TotalUserCount { get; set; } /// /// 点赞数 /// public long LikeCount { get; set; } /// /// 直播间二维码图像链接 /// public string QrcodeUrl { get; set; } /// /// 直播间地址 /// public string LiveUrl { get; set; } /// /// 封面链接 /// public string Cover { get; set; } /// /// 直播间管理员用户id /// public List AdminUserIds { get; set; } = new List(); /// /// 主播信息 /// public RoomAnchor Owner { get; set; } /// /// 直播间的一些配置 /// public RoomAuth AuthInfo { get; set; } /// /// 自身信息,Api方式没有 /// public OdinData Odin { get; set; } /// /// Response请求头设置的 Ttwid,Api方式没有 /// public string Ttwid { get; set; } public class RoomAnchor { /// /// 用户ID /// public string UserId { get; set; } /// /// SecUid /// public string SecUid { get; set; } /// /// 昵称 /// public string Nickname { get; set; } /// /// 头像地址 /// public string HeadUrl { get; set; } /// /// 关注状态 0未关注,1已关注,... /// public int FollowStatus { get; set; } } public class RoomAuth { /// /// 是否允许聊天 /// public bool Chat { get; set; } /// /// 是否允许弹幕 /// public bool Danmaku { get; set; } /// /// 是否允许送礼物 /// public bool Gift { get; set; } /// /// 是否允许发红包 /// public bool LuckMoney { get; set; } /// /// 是否允许点赞 /// public bool Digg { get; set; } /// /// 是否允许房间贡献者 /// public bool RoomContributor { get; set; } /// /// 是否允许使用道具 /// public bool Props { get; set; } /// /// 是否允许查看用户名片 /// public bool UserCard { get; set; } /// /// 是否允许查看 POI /// public bool POI { get; set; } /// /// 更多主播? /// public int MoreAnchor { get; set; } /// /// banner? /// public int Banner { get; set; } /// /// 分享配置? /// public int Share { get; set; } /// /// 用户角标? /// public int UserCorner { get; set; } /// /// 横屏? /// public int Landscape { get; set; } /// /// 横屏聊天? /// public int LandscapeChat { get; set; } /// /// 公屏? /// public int PublicScreen { get; set; } /// /// 礼物主播魔法表情配置? /// public int GiftAnchorMt { get; set; } /// /// 录屏配置? /// public int RecordScreen { get; set; } /// /// 打赏贴纸配置? /// public int DonationSticker { get; set; } /// /// 小时榜配置? /// public int HourRank { get; set; } /// /// 商务名片配置? /// public int CommerceCard { get; set; } /// /// 语音聊天配置? /// public int AudioChat { get; set; } /// /// 弹幕默认开关 /// public int DanmakuDefault { get; set; } /// /// KTV 点歌? /// public int KtvOrderSong { get; set; } /// /// 选集? /// public int SelectionAlbum { get; set; } /// /// 点赞? /// public int Like { get; set; } /// /// 倍速播放? /// public int MultiplierPlayback { get; set; } /// /// 下载视频? /// public int DownloadVideo { get; set; } /// /// 收藏? /// public int Collect { get; set; } /// /// 定时下播? /// public int TimedShutdown { get; set; } /// /// 快进? /// public int Seek { get; set; } /// /// 举报? /// public int Denounce { get; set; } /// /// 踩? /// public int Dislike { get; set; } /// /// 只看 TA? /// public int OnlyTa { get; set; } /// /// 投屏? /// public int CastScreen { get; set; } /// /// 评论墙? /// public int CommentWall { get; set; } /// /// 弹幕样式 /// public object BulletStyle { get; set; } /// /// 显示游戏插件? /// public int ShowGamePlugin { get; set; } /// /// PK礼物? /// public int VSGift { get; set; } /// /// PK话题? /// public int VSTopic { get; set; } /// /// PK排行榜? /// public int VSRank { get; set; } /// /// 管理员评论墙? /// public int AdminCommentWall { get; set; } /// /// 商务组件? /// public int CommerceComponent { get; set; } /// /// 抖音会员? /// public int DouPlus { get; set; } /// /// 游戏积分玩法? /// public int GamePointsPlaying { get; set; } /// /// 海报? /// public int Poster { get; set; } /// /// 精彩时刻? /// public int Highlights { get; set; } /// /// 打字评论状态? /// public int TypingCommentState { get; set; } /// /// 上下滑动引导? /// public int StrokeUpDownGuide { get; set; } /// /// 右上角统计浮层? /// public int UpRightStatsFloatingLayer { get; set; } /// /// 投屏显式? /// public int CastScreenExplicit { get; set; } /// /// 选集? /// public int Selection { get; set; } /// /// 行业服务? /// public int IndustryService { get; set; } /// /// 竖屏排行榜? /// public int VerticalRank { get; set; } /// /// 进场特效? /// public int EnterEffects { get; set; } /// /// 粉丝团? /// public int FansClub { get; set; } /// /// 表情外显? /// public int EmojiOutside { get; set; } /// /// 售票? /// public int CanSellTicket { get; set; } /// /// 抖音会员人气宝石? /// public int DouPlusPopularityGem { get; set; } /// /// 任务中心? /// public int MissionCenter { get; set; } /// ///扩展屏幕? /// public int ExpandScreen { get; set; } /// /// 粉丝群? /// public int FansGroup { get; set; } /// /// 话题? /// public int Topic { get; set; } /// /// 主播任务? /// public int AnchorMission { get; set; } /// /// 跑马灯? /// public int Teleprompter { get; set; } /// /// 长按? /// public int LongTouch { get; set; } /// /// 特殊样式 /// public SpecialStyle SpecialStyle { get; set; } /// /// 固定聊天? /// public int FixedChat { get; set; } /// /// 竞猜? /// public int QuizGamePointsPlaying { get; set; } } public class ChatStyle { /// /// 是否禁用样式 /// public int UnableStyle { get; set; } /// /// 内容 /// public string Content { get; set; } /// /// 关闭类型 /// public int OffType { get; set; } } public class SpecialStyle { /// /// 聊天样式 /// public ChatStyle Chat { get; set; } /// /// 点赞样式 /// public ChatStyle Like { get; set; } } public class OdinData { public string user_id { get; set; } public string user_type { get; set; } public string user_is_auth { get; set; } public string user_is_login { get; set; } public string user_unique_id { get; set; } } /// /// 将 直播间页面元素 转为房间信息对象 /// /// /// /// public static (int, string) TryParseRoomPageHtml(string html, out RoomInfo result) { result = null; if (html.IsNullOrWhiteSpace()) { return (-1, "无效的页面数据"); } var roomDataReg = new Regex(@"(?<=self\.__pace_f\.push\(\[1,""a:)\[.+?\](?=\\n?""\]\)[\s\n\r]*?<\/script>)"); var match = roomDataReg.Match(html); if (!match.Success) { //Logger.LogError("在通过正则匹配直播页房间信息时失败,可能是官方做了升级"); return (1, "未能匹配到房间信息"); } var matchData = Regex.Unescape(match.Value); JToken jsonObject = null; try { jsonObject = JsonConvert.DeserializeObject(matchData)[3]; } catch (Exception ex) { return (2, "匹配到的房间数据格式有错误"); } var roomInfo = jsonObject["state"]["roomStore"]["roomInfo"]; var odin = jsonObject["state"]["userStore"]["odin"]; var room = roomInfo["room"]; var roomOwner = roomInfo["anchor"]; if (room == null) { return (3, "房间信息为空,获取失败"); } result = new RoomInfo(); result.Odin = odin?.ToObject(); result.WebRoomId = roomInfo["web_rid"]?.ToString() ?? ""; result.RoomId = roomInfo["roomId"]?.ToString() ?? ""; result.AdminUserIds = room["admin_user_ids_str"]?.Values()?.ToList() ?? new List(); result.IsLive = room["status"]?.Value() == 2; result.Title = room["title"]?.ToString() ?? ""; result.UserCount = room["room_view_stats"]?["display_value"]?.Value() ?? 0; result.TotalUserCount = room["stats"]?["total_user_str"]?.Value() ?? "0"; result.LikeCount = room["like_count"]?.Value() ?? 0; result.QrcodeUrl = roomInfo["qrcode_url"]?.ToString() ?? ""; result.AuthInfo = room["room_auth"]?.ToObject(); result.Cover = room["cover"]?["url_list"]?.Values().FirstOrDefault() ?? "";//下播情况下没有cover字段 if (roomOwner != null) { result.Owner = new RoomInfo.RoomAnchor() { UserId = roomOwner["id_str"].ToString(), Nickname = roomOwner["nickname"].ToString(), SecUid = roomOwner["sec_uid"].ToString(), HeadUrl = roomOwner["avatar_thumb"]["url_list"].Values()?.FirstOrDefault() ?? "", FollowStatus = roomOwner["follow_info"]["follow_status"].Value() }; } return (0, "succ"); } } }