From 734a7204f874eacf5ca7efd22524bd07d08a38ed Mon Sep 17 00:00:00 2001
From: Jerry Yan <792602257@qq.com>
Date: Sat, 30 Jan 2021 19:54:40 +0800
Subject: [PATCH] =?UTF-8?q?=E9=A2=9D=E5=A4=96=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 Common.py           |   3 +
 Struct/Chat.py      |  40 +++++++
 Struct/Digg.py      |   0
 Struct/Gift.py      |  72 +++++++++++++
 Struct/Lottery.py   |  71 +++++++++++++
 Struct/LuckyUser.py |  19 ++++
 Struct/MemberMsg.py |  36 +++++++
 Struct/User.py      |  36 +++++--
 api.py              | 250 +++++++++++++++++++++++++++++++++++++++++---
 9 files changed, 502 insertions(+), 25 deletions(-)
 create mode 100644 Struct/Chat.py
 create mode 100644 Struct/Digg.py
 create mode 100644 Struct/Gift.py
 create mode 100644 Struct/Lottery.py
 create mode 100644 Struct/LuckyUser.py
 create mode 100644 Struct/MemberMsg.py

diff --git a/Common.py b/Common.py
index 20856b4..14092a5 100644
--- a/Common.py
+++ b/Common.py
@@ -321,6 +321,9 @@ def loginBilibili(force=False):
 class downloader(XiGuaLiveApi):
     playlist = None
 
+    def _checkUsernameIsMatched(self, compare=None):
+        return True
+
     def updRoomInfo(self, force=False):
         global broadcaster
         _prev_status = self.isLive
diff --git a/Struct/Chat.py b/Struct/Chat.py
new file mode 100644
index 0000000..b226dce
--- /dev/null
+++ b/Struct/Chat.py
@@ -0,0 +1,40 @@
+from .User import User
+from .Lottery import Lottery
+from XiguaMessage_pb2 import ChatMessage
+
+class Chat:
+    content = ""
+    user = None
+    filterString = ["", ]
+    isFiltered = False
+
+    def __init__(self, json=None, lottery: Lottery = None):
+        if lottery:
+            self.filterString.append(lottery.content)
+        if json:
+            if type(json) == bytes:
+                self.parsePb(json)
+            else:
+                self.parse(json)
+
+    def parsePb(self, raw):
+        _message = ChatMessage()
+        _message.ParseFromString(raw)
+        self.user = User(_message.user)
+        self.content = _message.content
+        if self.content in self.filterString:
+            self.isFiltered = True
+
+    def parse(self, json):
+        self.user = User(json)
+        if "extra" in json:
+            if "content" in json["extra"]:
+                self.content = json["extra"]['content']
+        if self.content in self.filterString:
+            self.isFiltered = True
+
+    def __str__(self):
+        return "{} : {}".format(self.user, self.content)
+
+    def __unicode__(self):
+        return self.__str__()
diff --git a/Struct/Digg.py b/Struct/Digg.py
new file mode 100644
index 0000000..e69de29
diff --git a/Struct/Gift.py b/Struct/Gift.py
new file mode 100644
index 0000000..e154c99
--- /dev/null
+++ b/Struct/Gift.py
@@ -0,0 +1,72 @@
+import requests
+from .User import User
+from XiguaMessage_pb2 import GiftMessage
+
+
+class Gift:
+    giftList = {}
+
+    def __init__(self, json=None):
+        self.ID = 0
+        self.count = 0
+        self.user = None
+        self.isFinished = False
+        self.backupName = None
+        if json:
+            if type(json) == bytes:
+                self.parsePb(json)
+            else:
+                self.parse(json)
+
+    def parsePb(self, raw):
+        _message = GiftMessage()
+        _message.ParseFromString(raw)
+        self.user = User(_message.user)
+        self.ID = _message.giftId
+        self.count = _message.repeated
+        self.isFinished = _message.isFinished
+        self.backupName = _message.commonInfo.displayText.params.gifts.gift.name
+
+    def parse(self, json):
+        self.user = User(json)
+        if "extra" in json and json["extra"] is not None:
+            if "present_info" in json["extra"] and json["extra"]['present_info'] is not None:
+                self.ID = int(json["extra"]['present_info']['id'])
+                self.count = json["extra"]['present_info']['repeat_count']
+            elif "present_end_info" in json["extra"] and json["extra"]['present_end_info'] is not None:
+                self.ID = int(json["extra"]['present_end_info']['id'])
+                self.count = json["extra"]['present_end_info']['count']
+
+    def isAnimate(self):
+        if self.ID != 0 and self.ID in self.giftList:
+            if 'combo' in self.giftList[self.ID]:
+                return self.giftList[self.ID]["combo"] == False
+            elif 'meta' in self.giftList[self.ID] and 'combo' in self.giftList[self.ID]['meta']:
+                return self.giftList[self.ID]['meta']["combo"] == False
+            elif 'type' in self.giftList[self.ID]:
+                return self.giftList[self.ID]["type"] == 2
+        return False
+
+    def _getGiftName(self):
+        if self.ID in self.giftList:
+            return self.giftList[self.ID]["name"]
+        elif self.backupName is not None:
+            return self.backupName
+        else:
+            return "未知礼物[{}]".format(self.ID)
+
+    def __str__(self):
+        return "{user} 送出的 {count} 个 {name}".format(user=self.user, count=self.count, name=self._getGiftName())
+
+    def __unicode__(self):
+        return self.__str__()
+
+    def __repr__(self):
+        return "西瓜礼物【{}(ID:{})】".format(self._getGiftName(), self.ID)
+
+    @classmethod
+    def addGift(cls, _gift):
+        if 'id' not in _gift:
+            return
+        _id = int(_gift["id"])
+        cls.giftList[_id] = _gift
diff --git a/Struct/Lottery.py b/Struct/Lottery.py
new file mode 100644
index 0000000..e2d9eb8
--- /dev/null
+++ b/Struct/Lottery.py
@@ -0,0 +1,71 @@
+# coding=utf-8
+import requests
+import time
+from .LuckyUser import LuckyUser
+
+
+class Lottery:
+    ID = 0
+    isActive = False
+    content = ""
+    isFinished = False
+    luckyUsers = []
+    joinedUserCount = 0
+    prizeName = ""
+    finish = 0
+
+    def __init__(self, json=None):
+        if json:
+            self.parse(json)
+
+    def parse(self, json):
+        if "lottery_info" in json and json["lottery_info"] is not None:
+            self.isActive = int(json["lottery_info"]["status"]) > 0
+            self.ID = json["lottery_info"]["lottery_id"]
+            for i in json["lottery_info"]['conditions']:
+                if i['type'] != 3:
+                    continue
+                self.content = i["content"]
+            self.joinedUserCount = int(json["lottery_info"]["candidate_num"])
+            self.prizeName = json["lottery_info"]["prize_info"]["name"]
+            _delta = int(json["lottery_info"]["draw_time"]) - int(json["lottery_info"]["current_time"])
+            self.finish = time.time()+_delta+1
+        elif "extra" in json and json["extra"] is not None:
+            if "lottery_info" in json["extra"] and json["extra"]["lottery_info"] is not None:
+                return self.parse(json["extra"])
+
+    def update(self):
+        if self.isActive:
+            if not self.isFinished and self.finish > time.time():
+                self.checkFinished()
+                return True
+        return False
+
+    def checkFinished(self):
+        p = requests.get("https://i.snssdk.com/videolive/lottery/check_user_right?lottery_id={}"
+                         "&version_code=730&device_platform=android".format(
+            self.ID
+        ))
+        d = p.json()
+        if d["base_resp"]["status_code"] != 0:
+            self.isActive = False
+            self.isFinished = False
+            return
+        self.isActive = int(d["lottery_info"]["status"]) > 0
+        self.isFinished = int(d["lottery_info"]["status"]) == 2
+        self.joinedUserCount = int(d["lottery_info"]["candidate_num"])
+        if self.isFinished:
+            self.luckyUsers = [ LuckyUser(i) for i in d["lottery_info"]["lucky_users"] ]
+
+    def __str__(self):
+        if self.isFinished:
+            ret = "恭喜以下中奖用户:\n"
+            for i in self.luckyUsers:
+                ret += "> {} {}\n".format(i,self.prizeName)
+            ret += "> 参与人数:{}".format(self.joinedUserCount)
+            return ret
+        elif self.isActive:
+            return "正在抽奖中。。。\n" \
+                   "> 参与人数:{}".format(self.joinedUserCount)
+        else:
+            return "抽奖已失效"
diff --git a/Struct/LuckyUser.py b/Struct/LuckyUser.py
new file mode 100644
index 0000000..2fb195e
--- /dev/null
+++ b/Struct/LuckyUser.py
@@ -0,0 +1,19 @@
+from .User import User
+
+class LuckyUser:
+
+    user = None
+    count = 0
+
+    def __init__(self, json=None):
+        if json:
+            self.parse(json)
+
+    def parse(self, json):
+        self.user = User()
+        self.user.ID = json['user_id']
+        self.user.name = json['user_name']
+        self.count = int(json["grant_count"])
+
+    def __str__(self):
+        return "用户 {} 获得了 {} 个".format(self.user,self.count)
diff --git a/Struct/MemberMsg.py b/Struct/MemberMsg.py
new file mode 100644
index 0000000..2dcdeea
--- /dev/null
+++ b/Struct/MemberMsg.py
@@ -0,0 +1,36 @@
+from .User import User
+
+
+class MemberMsg:
+    type = 0
+    content = ""
+    user = None
+
+    def __init__(self, json=None):
+        if json:
+            self.parse(json)
+
+    def parse(self, json):
+        self.user = User(json)
+        if "extra" in json:
+            if "action" in json["extra"]:
+                self.type = json["extra"]['action']
+            elif "content" in json["extra"]:
+                self.content = json["extra"]['content']
+
+    def __str__(self):
+        if self.type == 3:
+            return "{} 被禁言了".format(self.user)
+        elif self.type == 4:
+            return "{} 被取消禁言了".format(self.user)
+        elif self.type == 5:
+            return "{} 被任命为房管".format(self.user)
+        elif self.type == 1:
+            return "{} 进入了房间".format(self.user)
+        else:
+            if self.content == "":
+                return "未知消息{} 关于用户 {}".format(self.type, self.user)
+            return self.content.format(self.user)
+
+    def __unicode__(self):
+        return self.__str__()
\ No newline at end of file
diff --git a/Struct/User.py b/Struct/User.py
index 4db684c..d58acf8 100644
--- a/Struct/User.py
+++ b/Struct/User.py
@@ -1,15 +1,33 @@
-class User:
-    ID = 0
-    name = ""
-    brand = ""
-    level = 0
-    type = 0
-    block = False
-    mute = False
+from XiguaUser_pb2 import User as UserPb
 
+
+class User:
     def __init__(self, json=None):
+        self.ID = 0
+        self.name = ""
+        self.brand = ""
+        self.level = 0
+        self.type = 0
+        self.block = False
+        self.mute = False
         if json:
-            self.parse(json)
+            if type(json) == bytes:
+                self.parsePb(json)
+            elif type(json) == UserPb:
+                self.parseUserPb(json)
+            else:
+                self.parse(json)
+
+    def parseUserPb(self, _user):
+        self.ID = _user.id
+        self.name = _user.nickname
+        self.brand = _user.fansClub.fansClub.title
+        self.level = _user.fansClub.fansClub.level
+
+    def parsePb(self, raw):
+        _user = UserPb()
+        _user.ParseFromString(raw)
+        self.parseUserPb(_user)
 
     def parse(self, json):
         if "extra" in json:
diff --git a/api.py b/api.py
index dde4341..ab0c7bb 100644
--- a/api.py
+++ b/api.py
@@ -1,9 +1,15 @@
 # coding=utf-8
+import sys
 
+from Struct.MemberMsg import MemberMsg
 from Struct.User import User
+from Struct.Gift import Gift
+from Struct.Chat import Chat
 import requests
 import time
 from datetime import datetime, timedelta
+from Xigua_pb2 import XiguaLive
+from XiguaMessage_pb2 import FansClubMessage, SocialMessage
 
 DEBUG = False
 # 自己抓的自己设备的参数,建议开发者自己抓一个长期使用
@@ -13,7 +19,7 @@ CUSTOM_INFO = {
     'device_id': "55714661189",
     'cdid': "ed4295e8-5d9a-4cb9-b2a2-04009a3baa2d",
     'openudid': "70d6668d41512c39",
-    # 'aid': "32", # 又是一个不变的值
+    # 'aid': "32", # 是一个不变的值
     'channel': "xiaomi",
     'device_brand': "Xiaomi",
     'device_type': "MI+8+SE",
@@ -23,16 +29,14 @@ CUSTOM_INFO = {
 }
 VERSION_INFO = {
     'app_name': "video_article",
-    'version_code': "926",
-    'version_code_full': "92609",
-    'version_name': "9.2.6",
-    'ab_version': "941090,785218,668858,1046292,1073579,830454,956074,929436,797199,1135476,1179370,994679,959010,"
-                  "900042,1113833,668854,1193963,901277,1043330,1038721,994822,1002058,1230687,1189797,1143356,1143441,"
-                  "1143501,1143698,1143713,1371009,1243997,1392586,1395695,1395486,1398858,668852,668856,668853,"
-                  "1186421,668851,668859,999124,668855,1039075",
-    'manifest_version_code': "518",
+    'version_code': "942",
+    'version_code_full': "94214",
+    'version_name': "9.4.2",
+    'ab_version': "668852,668853,668858,668851,668859,668856,668855,2358970,"
+                  "668854,2393607,1477978,994679,2408463,2412359",
+    'manifest_version_code': "542",
     'tma_jssdk_version': "1830001",
-    # 'oaid': "a625f466e0975d42", # 一个定值,几个版本换设备都没变过
+    'oaid': "693ea85657ef38ca",
 }
 COMMON_GET_PARAM = (
     "&iid={iid}&device_id={device_id}&channel={channel}&aid=32&app_name={app_name}&version_code={version_code}&"
@@ -40,7 +44,8 @@ COMMON_GET_PARAM = (
     "device_brand={device_brand}&language=zh&os_api={os_api}&os_version={os_version}&openudid={openudid}&fp=a_fake_fp&"
     "manifest_version_code={manifest_version_code}&update_version_code={version_code_full}&_rticket={{TIMESTAMP:.0f}}&"
     "_rticket={{TIMESTAMP:.0f}}&cdid_ts={{TIMESTAMP:.0f}}&tma_jssdk_version={tma_jssdk_version}&"
-    "rom_version={rom_version}&cdid={cdid}&oaid=a625f466e0975d42").format_map({**VERSION_INFO, **CUSTOM_INFO})
+    "rom_version={rom_version}&cdid={cdid}&oaid={oaid}").format_map({**VERSION_INFO, **CUSTOM_INFO})
+WEBCAST_GET_PARAMS = "webcast_sdk_version=1350&webcast_language=zh&webcast_locale=zh_CN"
 SEARCH_USER_API = (
     "https://search-hl.ixigua.com/video/app/search/search_content/?format=json"
     "&fss=search_subtab_switch&target_channel=video_search&keyword_type=search_subtab_switch&offset=0&count=10"
@@ -49,15 +54,18 @@ SEARCH_USER_API = (
     '&ab_param={{"is_show_filter_feature": 1, "is_hit_new_ui": 1}}'
     "&search_start_time={TIMESTAMP:.0f}&from=live&en_qc=1&pd=xigua_live&ssmix=a{COMMON}&keyword={keyword}")
 USER_INFO_API = "https://api100-quic-c-hl.ixigua.com/video/app/user/home/v7/?to_user_id={userId}{COMMON}"
-ROOM_INFO_API = ("https://webcast3-normal-c-hl.ixigua.com/webcast/room/enter/?room_id={roomId}&webcast_sdk_version=1350"
-                 "&webcast_language=zh&webcast_locale=zh_CN&pack_level=4{COMMON}")
+ROOM_INFO_API = "https://webcast3-normal-c-hl.ixigua.com/webcast/room/enter/?room_id={roomId}&pack_level=4{COMMON}"
+DANMAKU_GET_API = "https://webcast3-normal-c-hl.ixigua.com/webcast/im/fetch/?{WEBCAST}{COMMON}"
+GIFT_DATA_API = ("https://webcast3-normal-c-hl.ixigua.com/webcast/gift/list/?room_id={roomId}&to_room_id={roomId}&"
+                 "gift_scene=1&fetch_giftlist_from=2&current_network_quality_info={{}}&"
+                 "{WEBCAST}{COMMON}")
 COMMON_HEADERS = {
     "sdk-version": '2',
-    "passport-sdk-version": "19",
+    "passport-sdk-version": "21",
     "X-SS-DP": "32",
+    "x-vc-bdturing-sdk-version": "2.0.1",
     "User-Agent": "Dalvik/2.1.0 (Linux; U; Android 10) VideoArticle/9.2.6 cronet/TTNetVersion:828f6f3c 2020-09-06 "
                   "QuicVersion:7aee791b 2020-06-05",
-    # 最好别加br,requests库好像自带没法解析
     "Accept-Encoding": "gzip, deflate"
 }
 
@@ -87,6 +95,7 @@ class XiGuaLiveApi:
         self.isLive = False
         self._rawRoomInfo = {}
         self.roomID = 0
+        self.roomPopularity = 0
         self.s = requests.session()
         self.s.headers.update(COMMON_HEADERS)
         self._updRoomAt = datetime.fromtimestamp(0)
@@ -94,6 +103,19 @@ class XiGuaLiveApi:
         self._ext = ""
         self._cursor = "0"
 
+    def _updateRoomPopularity(self, _data):
+        """
+        更新房间人气的方法
+        Update Room Popularity
+        :param _data: Received Message
+        """
+        if "extra" in _data:
+            if "member_count" in _data["extra"] and _data["extra"]["member_count"] > 0:
+                self.roomPopularity = _data["extra"]["member_count"]
+        if "data" in _data:
+            if "popularity" in _data["data"]:
+                self.roomPopularity = _data["data"]["popularity"]
+
     def getJson(self, url, **kwargs):
         if "timeout" not in kwargs:
             kwargs["timeout"] = 10
@@ -152,13 +174,93 @@ class XiGuaLiveApi:
         if DEBUG:
             print(*args)
 
+    def onPresent(self, gift: Gift):
+        """
+        礼物连击中的消息
+        Message On Sending Presents
+        :param gift: Struct of Gift Message
+        """
+        print("礼物连击 :", gift)
+
+    def onPresentEnd(self, gift: Gift):
+        """
+        礼物送完了的提示信息
+        Message On Finished Send Present
+        :param gift: Struct of Gift Message
+        """
+        print("感谢", gift)
+
+    def onAd(self, i):
+        """
+        全局广播
+        All Channel Broadcasting Message( Just An Ad )
+        :param i: JSON DATA if you wanna using it
+        """
+        # print(i)
+        pass
+
+    def onChat(self, chat: Chat):
+        """
+        聊天信息
+        On Chatting
+        :param chat: Struct of Chat Message
+        """
+        if not chat.isFiltered:
+            print(chat)
+
+    def onEnter(self, msg: MemberMsg):
+        """
+        进入房间消息
+        On Entering Room
+        :param msg: Struct of Member Message
+        """
+        print("提示 :", msg)
+
+    def onSubscribe(self, user: User):
+        """
+        关注主播时的消息
+        On Subscribe
+        :param user: Struct of User Message
+        """
+        print("消息 :", user, "关注了主播")
+
+    def onJoin(self, user: User):
+        """
+        加入粉丝团消息
+        :param user:
+        """
+        print("欢迎", user, "加入了粉丝团")
+
+    def onMessage(self, msg: str):
+        """
+        系统消息
+        :param msg:
+        """
+        print("消息 :", msg)
+
+    def onLike(self, user: User):
+        """
+        点击喜欢的消息
+        On Like
+        :param user:
+        """
+        print("用户", user, "点了喜欢")
+
+    def onLeave(self, json: any):
+        """
+        下播消息
+        On Liver Leave
+        :param json:
+        """
+        print("消息 :", "主播离开了")
+        self.updRoomInfo()
+
     def _checkUsernameIsMatched(self, compare=None):
         """
         验证主播名字是自己想要的那个
         Check name matched
         :return: bool: 是否匹配
         """
-        return True
         if compare is None:
             compare = self.broadcaster
         if self.name is None or compare is None:
@@ -258,6 +360,7 @@ class XiGuaLiveApi:
         self._rawRoomInfo = d["data"]
         self.isLive = d["data"]["status"] == 2
         self._updRoomAt = datetime.now()
+        self._updateRoomPopularity(d)
         return self.isLive
 
     def updRoomInfo(self, force=False):
@@ -274,6 +377,121 @@ class XiGuaLiveApi:
         else:
             return self._getRoomInfo(force)
 
+    def updGiftInfo(self):
+        self.updRoomInfo()
+        _formatData = {"TIMESTAMP": time.time() * 1000, "roomId": self.roomID}
+        _COMMON = COMMON_GET_PARAM.format_map(_formatData)
+        _formatData['COMMON'] = _COMMON
+        _formatData['WEBCAST'] = WEBCAST_GET_PARAMS
+        _url = GIFT_DATA_API.format_map(_formatData)
+        d = self.getJson(_url)
+        if d is None or d["status_code"] != 0:
+            return "异常"
+        elif 'pages' in d["data"]:
+            for _page in d["data"]['pages']:
+                if 'gifts' in _page:
+                    for _gift in _page['gifts']:
+                        Gift.addGift(_gift)
+        return len(Gift.giftList)
+
+    def getDanmaku(self):
+        """
+        获取弹幕
+        """
+        self.updRoomInfo()
+        _formatData = {"TIMESTAMP": time.time() * 1000, "roomId": self.roomID}
+        _COMMON = COMMON_GET_PARAM.format_map(_formatData)
+        _formatData['COMMON'] = _COMMON
+        _formatData['WEBCAST'] = WEBCAST_GET_PARAMS
+        _url = DANMAKU_GET_API.format_map(_formatData)
+        p = self.s.post(_url, data="room_id={roomId}&fetch_rule=0&cursor={cursor}&"
+                                   "resp_content_type=protobuf&live_id=3&user_id=0&identity=audience&"
+                                   "last_rtt=85&internal_ext={ext}"
+                        .format_map({"roomId":self.roomID, "cursor": self._cursor, "ext": self._ext}),
+                        headers={"Content-Type": "application/x-www-form-urlencoded"})
+        if p.status_code != 200:
+            return
+        data = XiguaLive()
+        data.ParseFromString(p.content)
+        self._cursor = data.cursor
+        self._ext = data.internal_ext
+        for _each in data.data:
+            if _each.method == "WebcastGiftMessage":
+                _gift = Gift(_each.raw)
+                if _gift.isAnimate() or _gift.isFinished:
+                    self.onPresentEnd(_gift)
+                else:
+                    self.onPresent(_gift)
+            elif _each.method == "WebcastChatMessage":
+                _chat = Chat(_each.raw)
+                self.onChat(_chat)
+            elif _each.method == "WebcastControlMessage":
+                # 下播的时候会有个这个
+                self.onLeave(None)
+            elif _each.method == "WebcastSocialMessage":
+                _socialMessage = SocialMessage()
+                _socialMessage.ParseFromString(_each.raw)
+                _user = User(_socialMessage.user)
+                self.onSubscribe(_user)
+            elif _each.method == "WebcastFansclubMessage":
+                _fansClubMessage = FansClubMessage()
+                _fansClubMessage.ParseFromString(_each.raw)
+                # 升级是1,加入是2
+                if _fansClubMessage.type == 2:
+                    _user = User(_fansClubMessage.user)
+                    self.onJoin(_user)
+                else:
+                    self.onMessage(_fansClubMessage.content)
+            else:
+                pass
+
     @property
     def updateAt(self):
         return self._updRoomAt
+
+
+def public_hello():
+    print("西瓜直播弹幕助手 by JerryYan")
+    print("接口版本:{version_name}({version_code_full})".format_map(VERSION_INFO))
+
+
+if __name__ == "__main__":
+    name = "永恒de草薙"
+    if len(sys.argv) > 2:
+        if sys.argv[-1] == "d":
+            DEBUG = True
+        name = sys.argv[1]
+    public_hello()
+    print("搜索【", name, "】", end="\t", flush=True)
+    api = XiGuaLiveApi(name)
+    if not api.isValidUser:
+        input("用户不存在")
+        sys.exit()
+    print("OK")
+    print(api.broadcaster.__repr__())
+    print("更新房间信息,请稍后", end="\t", flush=True)
+    if api.updRoomInfo(True):
+        print("OK")
+    else:
+        print("FAIL")
+    print("更新房间礼物信息", end="\t", flush=True)
+    __res = api.updGiftInfo()
+    if __res < 0:
+        print("FAIL")
+    else:
+        print('OK\n礼物种数:', __res)
+    print("=" * 30)
+    while True:
+        if api.isLive:
+            try:
+                api.getDanmaku()
+                time.sleep(1)
+            except requests.exceptions.BaseHTTPError:
+                print("网络错误,请确认网络")
+                time.sleep(5)
+            # except Exception as e:
+            #     print(e)
+        else:
+            print("主播未开播,等待1分钟后重试")
+            time.sleep(60)
+            api.updRoomInfo(True)