diff --git a/.gitignore b/.gitignore index c58169a..1a644c8 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ *.xml log.txt __pycache__/ +.idea/ diff --git a/MultiRoom.py b/MultiRoom.py index 0fc976b..cbfc395 100644 --- a/MultiRoom.py +++ b/MultiRoom.py @@ -4,127 +4,47 @@ from printer import Printer -class MultiRoom: - - async def asmr_area(self): - while True: - try: - url = "https://api.live.bilibili.com/room/v1/area/getRoomList?platform=web&parent_area_id=1&cate_id=0&area_id=0&sort_type=online&page=1&page_size=30" - response = await bilibili().bili_section_get(url) - json_response = await response.json(content_type=None) - checklen = len(json_response['data']) - asmr_area_room = json_response['data'][random.randint(0, checklen-1)]['roomid'] - state = await bilibili().check_room_state(asmr_area_room) - if state == 1: - return [asmr_area_room, "娱乐分区"] - else: - Printer().printer("检测到房间未开播,立即尝试重新获取", "Error", "red") - except Exception as e: - Printer().printer(f"获取 [娱乐分区] 房间列表失败,5s后进行下次尝试 {repr(e)}", "Error", "red") - await asyncio.sleep(5) - - async def game_area(self): - while True: - try: - url = "https://api.live.bilibili.com/room/v1/area/getRoomList?platform=web&parent_area_id=2&cate_id=0&area_id=0&sort_type=online&page=1&page_size=30" - response = await bilibili().bili_section_get(url) - json_response = await response.json(content_type=None) - checklen = len(json_response['data']) - game_area_room = json_response['data'][random.randint(0, checklen-1)]['roomid'] - state = await bilibili().check_room_state(game_area_room) - if state == 1: - return [game_area_room, "游戏分区"] - else: - Printer().printer("检测到房间未开播,立即尝试重新获取", "Error", "red") - except Exception as e: - Printer().printer(f"获取 [游戏分区] 房间列表失败,5s后进行下次尝试 {repr(e)}", "Error", "red") - await asyncio.sleep(5) - - async def mobile_area(self): - while True: - try: - url = "https://api.live.bilibili.com/room/v1/area/getRoomList?platform=web&parent_area_id=3&cate_id=0&area_id=0&sort_type=online&page=1&page_size=30" - response = await bilibili().bili_section_get(url) - json_response = await response.json(content_type=None) - checklen = len(json_response['data']) - mobile_area_room = json_response['data'][random.randint(0, checklen-1)]['roomid'] - state = await bilibili().check_room_state(mobile_area_room) - if state == 1: - return [mobile_area_room, "手游分区"] - else: - Printer().printer("检测到房间未开播,立即尝试重新获取", "Error", "red") - except Exception as e: - Printer().printer(f"获取 [手游分区] 房间列表失败,5s后进行下次尝试 {repr(e)}", "Error", "red") - await asyncio.sleep(5) - - async def draw_area(self): - while True: - try: - url = "https://api.live.bilibili.com/room/v1/area/getRoomList?platform=web&parent_area_id=4&cate_id=0&area_id=0&sort_type=online&page=1&page_size=30" - response = await bilibili().bili_section_get(url) - json_response = await response.json(content_type=None) - checklen = len(json_response['data']) - draw_area_room = json_response['data'][random.randint(0, checklen-1)]['roomid'] - state = await bilibili().check_room_state(draw_area_room) - if state == 1: - return [draw_area_room, "绘画分区"] - else: - Printer().printer(f"检测到房间未开播,立即尝试重新获取", "Error", "red") - except Exception as e: - Printer().printer(f"获取 [绘画分区] 房间列表失败,5s后进行下次尝试 {repr(e)}", "Error", "red") - await asyncio.sleep(5) - - async def radio_area(self): - while True: - try: - url = "https://api.live.bilibili.com/room/v1/area/getRoomList?platform=web&parent_area_id=5&cate_id=0&area_id=0&sort_type=online&page=1&page_size=30" - response = await bilibili().bili_section_get(url) - json_response = await response.json(content_type=None) - checklen = len(json_response['data']) - radio_area_room = json_response['data'][random.randint(0, checklen-1)]['roomid'] - state = await bilibili().check_room_state(radio_area_room) - if state == 1: - return [radio_area_room, "电台分区"] - else: - Printer().printer(f"检测到房间未开播,立即尝试重新获取", "Error", "red") - except Exception as e: - Printer().printer(f"获取 [电台分区] 房间列表失败,5s后进行下次尝试 {repr(e)}", "Error", "red") - await asyncio.sleep(5) - - async def check_state(self, area, roomid=None): - if roomid is not None: - response = await bilibili().check_room_info(roomid) +async def area2room(area_id): + while True: + try: + url = "https://api.live.bilibili.com/room/v1/area/getRoomList?platform=web&parent_area_id=" + \ + str(area_id) + "&cate_id=0&area_id=0&sort_type=online&page=1&page_size=30" + response = await bilibili().bili_section_get(url) json_response = await response.json(content_type=None) - live_status = json_response['data']['live_status'] - curr_area_name = json_response['data']['parent_area_name'] - if live_status == 1 and curr_area_name in area: - Printer().printer(f'[{area}] 房间 {roomid} 直播状态正常', "Info", "green") - return [roomid, area] - elif live_status != 1: - Printer().printer(f"[{area}] 房间 {roomid} 已未直播!将切换监听房间", "Info", "green") + checklen = len(json_response['data']) + rand_num = random.randint(0, checklen-1) + new_area_id = json_response['data'][rand_num]['parent_id'] + if not new_area_id == int(area_id): + continue + area_room = json_response['data'][rand_num]['roomid'] + state = await bilibili().check_room_state(area_room) + if state == 1: + new_area = str(new_area_id) + json_response['data'][rand_num]['parent_name'] + return [area_room, new_area] else: - # print(type(live_status), live_status, curr_area_name) - Printer().printer(f"[{area}] 房间 {roomid} 已切换分区[{curr_area_name}]!将切换监听房间", "Info", "green") - if area == "娱乐分区": - asmr = await self.asmr_area() - return asmr - elif area == "游戏分区": - game = await self.game_area() - return game - elif area == "手游分区": - mobile = await self.mobile_area() - return mobile - elif area == "绘画分区": - draw = await self.draw_area() - return draw - elif area == "电台分区": - radio = await self.radio_area() - return radio - - async def get_all(self): - asmr = await self.asmr_area() - game = await self.game_area() - mobile = await self.mobile_area() - draw = await self.draw_area() - radio = await self.radio_area() - return [asmr, game, mobile, draw, radio] + Printer().printer("检测到获取房间未开播,立即尝试重新获取", "Error", "red") + except Exception as e: + Printer().printer(f"获取房间列表失败,5s后进行下次尝试 {repr(e)}", "Error", "red") + await asyncio.sleep(5) + + +async def check_state(area, roomid=None): + if roomid is not None: + response = await bilibili().check_room_info(roomid) + json_response = await response.json(content_type=None) + live_status = json_response['data']['live_status'] + curr_area_name = json_response['data']['parent_area_name'] + if live_status == 1 and curr_area_name in area: + Printer().printer(f'[{area}分区] 房间 {roomid} 直播状态正常', "Info", "green") + return [roomid, area] + elif live_status != 1: + Printer().printer(f"[{area}分区] 房间 {roomid} 已未直播!将切换监听房间", "Info", "green") + else: + # print(type(live_status), live_status, curr_area_name) + Printer().printer(f"[{area}分区] 房间 {roomid} 已切换分区[{curr_area_name}]!将切换监听房间", "Info", "green") + + return await area2room(area[0]) + + +async def get_all(): + return [await area2room(i+1) for i in range(5)] diff --git a/OnlineHeart.py b/OnlineHeart.py index 222ed30..1443880 100644 --- a/OnlineHeart.py +++ b/OnlineHeart.py @@ -1,5 +1,6 @@ from bilibili import bilibili from login import login +import utils import time import traceback import datetime @@ -15,6 +16,7 @@ def CurrentTime(): class OnlineHeart: + last_guard_room = 0 async def apppost_heartbeat(self): await bilibili().apppost_heartbeat() @@ -27,55 +29,82 @@ async def heart_gift(self): await bilibili().heart_gift() async def guard_lottery(self): - response = await bilibili().guard_list() - json_response = response.json() + for k in range(3): + try: + response = await bilibili().guard_list() + json_response = response.json() + break + except Exception: + continue + else: + Printer().printer("连接舰长服务器失败", "Error", "red") + return for i in range(0, len(json_response)): if json_response[i]['Status']: GuardId = json_response[i]['GuardId'] - if GuardId not in had_gotted_guard: + if GuardId not in had_gotted_guard and GuardId != 0: had_gotted_guard.append(GuardId) OriginRoomId = json_response[i]['OriginRoomId'] + if not OriginRoomId == OnlineHeart.last_guard_room: + result = await utils.check_room_true(OriginRoomId) + if True in result: + Printer().printer(f"检测到房间 {OriginRoomId} 的钓鱼操作", "Warning", "red") + continue + await bilibili().post_watching_history(OriginRoomId) + OnlineHeart.last_guard_room = OriginRoomId response2 = await bilibili().get_gift_of_captain(OriginRoomId, GuardId) json_response2 = await response2.json(content_type=None) if json_response2['code'] == 0: - Printer().printer(f"获取到房间[{OriginRoomId}]编号[{GuardId}]的上船亲密度:{json_response2['data']['message']}", + Printer().printer(f"获取到房间 {OriginRoomId} 编号 {GuardId} 的上船亲密度: {json_response2['data']['message']}", "Lottery", "cyan") elif json_response2['code'] == 400 and json_response2['msg'] == "你已经领取过啦": Printer().printer( - f"房间[{OriginRoomId}]编号[{GuardId}]的上船亲密度已领过", + f"房间 {OriginRoomId} 编号 {GuardId} 的上船亲密度已领过", "Info", "green") + elif json_response2['code'] == 400 and json_response2['msg'] == "访问被拒绝": + Printer().printer(f"获取房间 {OriginRoomId} 编号 {GuardId} 的上船亲密度: {json_response2['message']}", + "Lottery", "cyan") + print(json_response2) else: Printer().printer( - f"房间[{OriginRoomId}]编号[{GuardId}] 的上船亲密度领取出错,{json_response2}", + f"房间 {OriginRoomId} 编号 {GuardId} 的上船亲密度领取出错: {json_response2}", "Error", "red") else: pass async def draw_lottery(self): - black_list = ["测试", "test", "12345"] - for i in range(212, 300): + black_list = ["123", "1111", "测试", "測試", "测一测", "ce-shi", "test", "T-E-S-T", "lala", # 已经出现 + "測一測", "TEST", "Test", "t-e-s-t"] # 合理猜想 + last_lottery = 0 + for i in range(247, 300): response = await bilibili().get_lotterylist(i) json_response = await response.json() if json_response['code'] == 0: - temp = json_response['data']['title'] - for k in black_list: - if k in temp: - Printer().printer(f"检测到疑似钓鱼类测试抽奖,默认不参与,请自行判断抽奖可参与性","Warning","red") - else: - check = len(json_response['data']['typeB']) - for g in range(0, check): - join_end_time = json_response['data']['typeB'][g]['join_end_time'] - join_start_time = json_response['data']['typeB'][g]['join_start_time'] - ts = CurrentTime() - if int(join_end_time) > int(ts) > int(join_start_time): + last_lottery = 0 + title = json_response['data']['title'] + check = len(json_response['data']['typeB']) + for g in range(check): + join_end_time = json_response['data']['typeB'][g]['join_end_time'] + join_start_time = json_response['data']['typeB'][g]['join_start_time'] + status = json_response['data']['typeB'][g]['status'] + ts = CurrentTime() + if int(join_end_time) > int(ts) > int(join_start_time) and status == 0: + jp_list = '&'.join([jp['jp_name'] for jp in json_response['data']['typeB'][g]['list']]) + for k in black_list: + if k in title or k in jp_list: + Printer().printer(f"检测到 {i} 号疑似钓鱼类测试抽奖『{title}>>>{jp_list}』" + \ + ",默认不参与,请自行判断抽奖可参与性","Warning","red") + break + else: response1 = await bilibili().get_gift_of_lottery(i, g) json_response1 = await response1.json(content_type=None) - Printer().printer(f"参与实物抽奖回显:{json_response1}", "Lottery","cyan") - else: - pass + Printer().printer(f"参与『{title}>>>{jp_list}』抽奖回显: {json_response1}", "Lottery", "cyan") else: - break + if not last_lottery == 0: # 因为有中途暂时空一个-400的情况 + break + else: + last_lottery = json_response['code'] async def run(self): while 1: diff --git a/bilibiliCilent.py b/bilibiliCilent.py index 75c2478..ef9cce8 100644 --- a/bilibiliCilent.py +++ b/bilibiliCilent.py @@ -11,11 +11,11 @@ async def handle_1_TV_raffle(type, num, real_roomid, raffleid): - await asyncio.sleep(random.uniform(1, 2)) + await asyncio.sleep(random.uniform(0, min(num, 30))) response2 = await bilibili().get_gift_of_TV(type, real_roomid, raffleid) Printer().printer(f"参与了房间 {real_roomid} 的广播抽奖", "Lottery", "cyan") json_response2 = await response2.json(content_type=None) - Printer().printer(f"广播道具抽奖状态:{json_response2['msg']}", "Lottery", "cyan") + Printer().printer(f"房间 {real_roomid} 广播道具抽奖状态: {json_response2['msg']}", "Lottery", "cyan") if json_response2['code'] == 0: Statistics().append_to_TVlist(raffleid, real_roomid) else: @@ -23,7 +23,7 @@ async def handle_1_TV_raffle(type, num, real_roomid, raffleid): async def handle_1_room_TV(real_roomid): - await asyncio.sleep(random.uniform(1, 2)) + await asyncio.sleep(random.uniform(0, 1)) result = await utils.check_room_true(real_roomid) if True in result: Printer().printer(f"检测到房间 {real_roomid} 的钓鱼操作", "Warning", "red") @@ -50,7 +50,7 @@ async def handle_1_room_TV(real_roomid): class bilibiliClient(): - def __init__(self, roomid, area_name): + def __init__(self, roomid, area): self.bilibili = bilibili() self._reader = None self._writer = None @@ -64,7 +64,7 @@ def __init__(self, roomid, area_name): 'url': 'str' } self._roomId = roomid - self.area_name = area_name + self.area = area def close_connection(self): self._writer.close() @@ -82,7 +82,7 @@ async def connectServer(self): self._writer = writer if (await self.SendJoinChannel(self._roomId) == True): self.connected = True - Printer().printer(f'连接 {self._roomId} [{self.area_name}]弹幕服务器成功', "Info", "green") + Printer().printer(f'[{self.area}分区] 连接 {self._roomId} 弹幕服务器成功', "Info", "green") await self.ReceiveMessageLoop() async def HeartbeatLoop(self): @@ -128,12 +128,12 @@ async def ReadSocketData(self, len_wanted): tmp = await asyncio.wait_for(self._reader.read(len_remain), timeout=35.0) except asyncio.TimeoutError: # 由于心跳包30s一次,但是发现35s内没有收到任何包,说明已经悄悄失联了,主动断开 - Printer().printer(f'心跳失联,主动断开 @[{self.area_name}]{self._roomId}',"Error","red") + Printer().printer(f'心跳失联,主动断开 @[{self.area}分区]{self._roomId}',"Error","red") self.close_connection() await asyncio.sleep(1) return None except ConnectionResetError: - Printer().printer(f'RESET,网络不稳定或者远端不正常断开 @[{self.area_name}]{self._roomId}',"Error","red") + Printer().printer(f'RESET,网络不稳定或者远端不正常断开 @[{self.area}分区]{self._roomId}',"Error","red") self.close_connection() await asyncio.sleep(5) return None @@ -141,13 +141,13 @@ async def ReadSocketData(self, len_wanted): return None except: - Printer().printer(f"{sys.exc_info()[0]}, {sys.exc_info()[1]} @[{self.area_name}]{self._roomId}","Error","red") - Printer().printer(f'请联系开发者',"Error","red") + Printer().printer(f"{sys.exc_info()[0]}, {sys.exc_info()[1]} @[{self.area}分区]{self._roomId}","Error","red") + Printer().printer(f'请联系开发者',"Warning","red") self.close_connection() return None if not tmp: - Printer().printer(f"主动关闭或者远端主动发来FIN @[{self.area_name}]{self._roomId}","Error","red") + Printer().printer(f"主动关闭或者远端主动发来FIN @[{self.area}分区]{self._roomId}","Error","red") self.close_connection() await asyncio.sleep(1) return None @@ -202,107 +202,70 @@ async def parseDanMu(self, messages): return cmd = dic['cmd'] - if cmd == 'PREPARING': - Printer().printer(f"[{self.area_name}] 房间 {self._roomId} 下播!将切换监听房间", "Info", "green") + if cmd == 'LIVE': + # Printer().printer(f"[{self.area}分区] 房间 {self._roomId} 疑似切换分区!启动分区检查", "Info", "green") + # await utils.check_area_list([self.area], mandatory_check=True) + pass + elif cmd == 'PREPARING': + Printer().printer(f"[{self.area}分区] 房间 {self._roomId} 下播!将切换监听房间", "Info", "green") self.close_connection() - await utils.reconnect(self.area_name) + await utils.reconnect(self.area) elif cmd == 'DANMU_MSG': - Printer().printer(f"{dic}", "Message", "cyan", printable=False) - return + # Printer().printer(f"{dic}", "Message", "cyan", printable=False) + pass elif cmd == 'SYS_GIFT': - try: - Printer().printer(f"出现了远古的SYS_GIFT,请尽快联系开发者{dic}", "Warning", "red") - except: - pass - return + # Printer().printer(f"出现了远古的SYS_GIFT,请尽快联系开发者{dic}", "Warning", "red") + pass elif cmd == 'SYS_MSG': - if set(self.dic_bulletin) == set(dic): - Printer().printer(dic['msg'], "Info", "green") + if set(dic) in [set(self.dic_bulletin), {'cmd', 'msg', 'msg_text'}, {'cmd', 'msg', 'url'}]: + Printer().printer(f"{dic['msg']} @[{self.area}分区]{self._roomId}", "Info", "green") else: try: real_roomid = dic['real_roomid'] - Printer().printer(f"检测到房间 {real_roomid} 的广播抽奖 @[{self.area_name}]{self._roomId}", "Lottery", "cyan") + Printer().printer(f"检测到房间 {real_roomid} 的广播抽奖 @[{self.area}分区]{self._roomId}", "Lottery", "cyan") Rafflehandler().append2list_TV(real_roomid) - Statistics().append2pushed_TVlist() + Statistics().append2pushed_TVlist(real_roomid, self.area[0]) except: - print('SYS_MSG出错,请联系开发者', dic) - return - elif cmd == "WELCOME": - pass - elif cmd == "SEND_GIFT": - pass - elif cmd == "WELCOME_GUARD": - pass - elif cmd == "WELCOME_ACTIVITY": # 欢迎来到活动 - pass - elif cmd == "WISH_BOTTLE": - pass - elif cmd == "COMBO_END": - pass - elif cmd == "ENTRY_EFFECT": - pass - elif cmd == "ROOM_RANK": - pass - elif cmd == "COMBO_SEND": - pass - elif cmd == "ROOM_BLOCK_MSG": - pass - elif cmd == "SPECIAL_GIFT": - pass - elif cmd == "NOTICE_MSG": - pass - elif cmd == "GUARD_MSG": - pass - elif cmd == "GUARD_BUY": - pass - elif cmd == "GUARD_LOTTERY_START": - pass - elif cmd == "PK_INVITE_INIT": - pass - elif cmd == "PK_INVITE_CANCEL": - pass - elif cmd == "PK_INVITE_FAIL": - pass - elif cmd == "PK_CLICK_AGAIN": - pass - elif cmd == "PK_AGAIN": - pass - elif cmd == "PK_MATCH": # pk匹配 - pass - elif cmd == "PK_MIC_END": - pass - elif cmd == "PK_PRE": # pk预备阶段 - pass - elif cmd == "LIVE": # 开播 - pass - elif cmd == "PK_PROCESS": # pk 过程值 - pass - elif cmd == "PK_END": # pk结束 - pass - elif cmd == "PK_SETTLE": # pk settle + Printer().printer(f"SYS_MSG出错,请联系开发者 {dic}", "Warning", "red") + + # 观众相关 [欢迎入场,送礼,发弹幕] + elif cmd in ["WELCOME", "SEND_GIFT", "DANMU_MSG"]: pass - elif cmd == "PK_START": # pk开始 + # 各种通知 [通知(当前房间开奖 活动小时榜 各种SYS_MSG都会同时有NOTICE_MSG),系统通知(友爱社 心愿达成 绘马 主播招募 直播间强推)] + elif cmd in ["NOTICE_MSG", "SYS_MSG"]: pass - elif cmd == "ACTIVITY_EVENT": # 没有用的充能值信息 + # 各种高能 [节奏风暴(开始 结束),高能广播(无抽奖 活动高能 全频风暴),抽奖通知(现在广播全在这里了),总督广播] + elif cmd in ["SPECIAL_GIFT", "SYS_GIFT", "SYS_MSG", "GUARD_MSG"]: pass - elif cmd == "WARNING": # {'cmd': 'WARNING', 'msg': '违反直播分区规范,请立即更换至游戏区', 'roomid': 69956} + # 礼物连击 + elif cmd in ["COMBO_SEND", "COMBO_END"]: pass - elif cmd == "RAFFLE_END": # 抽奖结束 + # PK相关 + elif cmd in ["PK_INVITE_INIT", "PK_INVITE_FAIL", "PK_INVITE_CANCEL", "PK_INVITE_SWITCH_OPEN", "PK_INVITE_SWITCH_CLOSE", + "PK_PRE", "PK_START", "PK_PROCESS", "PK_SETTLE", "PK_END", "PK_MIC_END", + "PK_MATCH", "PK_CLICK_AGAIN", "PK_AGAIN"]: pass - elif cmd == "RAFFLE_START": # 抽奖开始 + # 抽奖相关 + elif cmd in ["RAFFLE_START", "RAFFLE_END", "TV_START", "TV_END", "GUARD_LOTTERY_START"]: pass - elif cmd == "ROOM_SHIELD": # 屏蔽{'cmd': 'ROOM_SHIELD', 'type': 1, 'user': '', 'keyword': '', 'roomid': 3051144} + # 房间管理相关 [屏蔽关键词,用户被加入黑名单,禁言开启,禁言关闭,新设房管,房管变更] + elif cmd in ["ROOM_SHIELD", "ROOM_BLOCK_MSG", "ROOM_SILENT_ON", "ROOM_SILENT_OFF", "room_admin_entrance", "ROOM_ADMINS"]: pass - elif cmd == "TV_START": # 小电视开始{'cmd': 'TV_START', 'data': {'id': '159720', 'dtime': 180, 'msg': {'cmd': 'SYS_MSG', 'msg': 'もやしパワー:? 送给:? 管珩心-中间的字念横:? 1个小电视飞船 + # 舰队相关 [本房间购买舰长,船票购买,本房间舰队消息(登船),船员进房间,进房间特效] + elif cmd in ["USER_TOAST_MSG", "GUARD_BUY", "GUARD_MSG", "WELCOME_GUARD", "ENTRY_EFFECT"]: pass - elif cmd == "TV_END": # 小电视关闭{'cmd': 'TV_END', 'data': {'id': '159720', 'uname': '顾惜大哥哥', 'sname': 'もやしパワー', 'giftName': '100000x银瓜子', 'mobileTips': '恭喜 顾惜大哥哥 获得100000x银瓜子' + # 直播状态相关 [开播,下播,警告,被切直播,房间被封] + elif cmd in ["LIVE", "PREPARING", "WARNING", "CUT_OFF", "ROOM_LOCK"]: pass - elif cmd == "ROOM_ADMINS": # 房管列表{'cmd': 'ROOM_ADMINS', 'uids': [25866878, 7026393, 240404878, 52054996]} + # 活动榜单相关 [进入小时榜,未知,获小时榜第一道具奖励] + elif cmd in ["ROOM_RANK", "new_anchor_reward", "HOUR_RANK_AWARDS"]: pass - elif cmd == "ROOM_SILENT_ON": # 禁言开启{'cmd': 'ROOM_SILENT_ON', 'data': {'type': 'level', 'level': 1, 'second': -1}, 'roomid': 5225} + # 活动相关 [活动获得的直播间入场特效,活动事件(如充能值信息),以前的高能消息] + elif cmd in ["WELCOME_ACTIVITY", "ACTIVITY_EVENT", "EVENT_CMD"]: pass - elif cmd == "ROOM_SILENT_OFF": # 禁言关闭{'cmd': 'ROOM_SILENT_OFF', 'data': [], 'roomid': 5225} + # 直播间信息相关 [直播间更换壁纸,许愿瓶进度变化,实物抽奖宝箱提醒] + elif cmd in ["CHANGE_ROOM_INFO", "WISH_BOTTLE", "BOX_ACTIVITY_START"]: pass else: - Printer().printer(f"出现一个未知msg{dic}", "Info", "red") + Printer().printer(f"出现一个未知msg @[{self.area}分区]{self._roomId} {dic}", "Warning", "red") pass diff --git a/connect.py b/connect.py index 5b6cf5f..701892c 100644 --- a/connect.py +++ b/connect.py @@ -1,13 +1,14 @@ +import time import asyncio import traceback -from MultiRoom import MultiRoom +import MultiRoom from bilibiliCilent import bilibiliClient from printer import Printer class connect(): instance = None - area_name = [] + areas = [] roomids = [] tasks = {} @@ -16,58 +17,20 @@ def __new__(cls, *args, **kw): cls.instance = super(connect, cls).__new__(cls, *args, **kw) cls.instance.danmuji = None cls.instance.tag_reconnect = False + init_time = time.time() + cls.instance.check_time = {'1娱乐': init_time, '2游戏': init_time, '3手游': init_time, + '4绘画': init_time, '5电台': init_time} cls.instance.handle_area = [] return cls.instance - async def recreate(self, area_name, new_roomid=None): - if area_name in self.handle_area: - Printer().printer(f"[{area_name}] 重连任务已在处理", "Info", "green") - return - else: - self.handle_area.append(area_name) - # Printer().printer(f"[{area_name}] 重连任务开始处理", "Info", "green") - try: - old_roomid = connect.roomids[connect.area_name.index(area_name)] - item = connect.tasks[old_roomid] - task1 = item[0] - task2 = item[1] - if not task1.done(): - task1.cancel() - if not task2.done(): - task2.cancel() - connect.tasks[old_roomid] = [] - - if new_roomid is None: - [new_roomid, new_area_name] = await MultiRoom().check_state(area_name) - else: - new_area_name = area_name - - if not new_roomid == old_roomid: - connect.roomids.remove(old_roomid) - connect.area_name.remove(area_name) - del connect.tasks[old_roomid] - connect.roomids.append(new_roomid) - connect.area_name.append(area_name) - connect.tasks[new_roomid] = [] - Printer().printer(f"更新监听房间列表{connect.roomids} {connect.area_name}","Info","green") - - self.danmuji = bilibiliClient(new_roomid, new_area_name) - task11 = asyncio.ensure_future(self.danmuji.connectServer()) - task21 = asyncio.ensure_future(self.danmuji.HeartbeatLoop()) - connect.tasks[new_roomid] = [task11, task21] - except Exception: - traceback.print_exc() - # Printer().printer(f"[{area_name}] 重连任务处理完毕", "Info", "green") - self.handle_area.remove(area_name) - async def create(self): - tmp = await MultiRoom().get_all() + tmp = await MultiRoom.get_all() for i in range(len(tmp)): connect.roomids.append(tmp[i][0]) for n in range(len(tmp)): - connect.area_name.append(tmp[n][1]) - for roomid,area_name in zip(connect.roomids,connect.area_name): - self.danmuji = bilibiliClient(roomid,area_name) + connect.areas.append(tmp[n][1]) + for roomid,area in zip(connect.roomids, connect.areas): + self.danmuji = bilibiliClient(roomid,area) task1 = asyncio.ensure_future(self.danmuji.connectServer()) task2 = asyncio.ensure_future(self.danmuji.HeartbeatLoop()) connect.tasks[roomid] = [task1, task2] @@ -83,38 +46,91 @@ async def create(self): task1 = item[0] task2 = item[1] if task1.done() == True or task2.done() == True: - area_name = connect.area_name[connect.roomids.index(roomid)] - Printer().printer(f"[{area_name}] 房间 {roomid} 任务出现异常", "Info", "green") - [ckd_roomid, ckd_area_name] = await MultiRoom().check_state(roomid=roomid, area=area_name) - await self.recreate(new_roomid=ckd_roomid, area_name=area_name) + area = connect.areas[connect.roomids.index(roomid)] + Printer().printer(f"[{area}分区] 房间 {roomid} 任务出现异常", "Info", "green") + await self.check_area(roomid=roomid, area=area, mandatory_recreate=True) else: - # Printer().printer(f"[{area_name}] 房间 {roomid} 任务保持正常", "Info", "green") + # Printer().printer(f"[{area}分区] 房间 {roomid} 任务保持正常", "Info", "green") pass except Exception: traceback.print_exc() async def check_connect(self, skip_area=None): if self.tag_reconnect: - Printer().printer(f"connect检查任务已在运行", "Info", "green") + Printer().printer("connect检查任务已在运行", "Info", "green") return else: self.tag_reconnect = True - # print('connect类属性:', connect.roomids, connect.area_name) + # print('connect类属性:', connect.roomids, connect.areas) if not len(connect.roomids): # 说明程序刚启动还没获取监控房间,此时也不需要检查 self.tag_reconnect = False return else: - for roomid, area_name in list(zip(connect.roomids, connect.area_name)): - if (skip_area is not None) and (skip_area == area_name): - continue - elif not roomid in connect.roomids: + for roomid, area in list(zip(connect.roomids, connect.areas)): + if (skip_area is not None) and (skip_area == area): continue else: - [ckd_roomid, ckd_area_name] = await MultiRoom().check_state(roomid=roomid, area=area_name) - if ckd_roomid == roomid: - continue - else: - await self.recreate(new_roomid=ckd_roomid, area_name=area_name) - Printer().printer(f"connect检查任务已完成", "Info", "green") + await self.check_area(roomid=roomid, area=area) + Printer().printer("connect检查任务已完成", "Info", "green") self.tag_reconnect = False + + async def check_area(self, area, roomid=None, mandatory_check=False, mandatory_recreate=False): + if len(str(area)) == 1: + area = [tem_area for tem_area in connect.areas if str(area) in tem_area][0] + if roomid is None: + roomid = connect.roomids[connect.areas.index(area)] + + if not mandatory_check and time.time() - self.check_time[area] < 60: + Printer().printer(f"[{area}分区] 近已检查,跳过", "Info", "green") + [ckd_roomid, ckd_area] = [roomid, area] + else: + # Printer().printer(f"[{area}分区] {roomid} 检查开始", "Info", "green") + self.check_time[area] = time.time() + [ckd_roomid, ckd_area] = await MultiRoom.check_state(roomid=roomid, area=area) + self.check_time[area] = time.time() + if mandatory_recreate or ckd_roomid != roomid: + await self.recreate(new_roomid=ckd_roomid, area=ckd_area) + + async def recreate(self, area, new_roomid=None): + if area in self.handle_area: + Printer().printer(f"[{area}分区] 重连任务已在处理", "Info", "green") + return + else: + self.handle_area.append(area) + # Printer().printer(f"[{area}分区] 重连任务开始处理", "Info", "green") + try: + old_roomid = connect.roomids[connect.areas.index(area)] + item = connect.tasks[old_roomid] + task1 = item[0] + task2 = item[1] + if not task1.done(): + task1.cancel() + if not task2.done(): + task2.cancel() + connect.tasks[old_roomid] = [] + + if new_roomid is None: + self.check_time[area] = time.time() + [new_roomid, new_area] = await MultiRoom.check_state(area) + self.check_time[area] = time.time() + else: + new_area = area + + if not new_roomid == old_roomid: + connect.roomids.remove(old_roomid) + connect.areas.remove(area) + del connect.tasks[old_roomid] + connect.roomids.append(new_roomid) + connect.areas.append(new_area) + connect.tasks[new_roomid] = [] + Printer().printer(f"更新监听房间列表{connect.roomids} {connect.areas}","Info","green") + + self.danmuji = bilibiliClient(new_roomid, new_area) + task11 = asyncio.ensure_future(self.danmuji.connectServer()) + task21 = asyncio.ensure_future(self.danmuji.HeartbeatLoop()) + connect.tasks[new_roomid] = [task11, task21] + except Exception: + traceback.print_exc() + # Printer().printer(f"[{area}分区] 重连任务处理完毕", "Info", "green") + self.handle_area.remove(area) diff --git a/rafflehandler.py b/rafflehandler.py index a421d3b..d28f541 100644 --- a/rafflehandler.py +++ b/rafflehandler.py @@ -29,9 +29,9 @@ async def run(self): del self.list_activity[:len_list_activity] del self.list_TV[:len_list_TV] if len_list_activity == 0 and len_list_TV == 0: - await asyncio.sleep(0.1) + await asyncio.sleep(1.1) else: - await asyncio.sleep(0.1) + await asyncio.sleep(1.0) def append2list_TV(self, real_roomid): self.list_TV.append(real_roomid) diff --git a/statistics.py b/statistics.py index 9aa2223..435403e 100644 --- a/statistics.py +++ b/statistics.py @@ -1,4 +1,7 @@ import datetime +import asyncio +import traceback +import utils from bilibili import bilibili from printer import Printer @@ -22,6 +25,7 @@ def __new__(cls, *args, **kw): cls.instance.pushed_event = [] cls.instance.pushed_TV = [] + cls.instance.monitor = {} cls.instance.joined_event = [] cls.instance.joined_TV = [] @@ -61,27 +65,58 @@ async def clean_TV(self): try: if json_response['data']['gift_id'] == '-1': - return - elif json_response['data']['gift_id'] != '-1': + if json_response['msg'] == '正在抽奖中..': + break + else: + Printer().printer(f"房间 {self.TV_roomid_list[0]} 广播道具抽奖结果: {json_response['msg']}", + "Lottery", "cyan") + else: data = json_response['data'] Printer().printer(f"房间 {self.TV_roomid_list[0]} 广播道具抽奖结果: {data['gift_name']}X{data['gift_num']}", "Lottery", "cyan") self.add_to_result(data['gift_name'], int(data['gift_num'])) - self.delete_0st_TVlist() + self.delete_0st_TVlist() except: print(json_response) - else: - return + if self.monitor: + check_list = list(self.monitor) + await asyncio.sleep(3) + + total_area = 5 + for roomid in check_list: + check_str = bin(self.monitor[roomid]).replace('0b', '').rjust(total_area, '0') + # print(roomid, check_str) + check_int = [int(check) for check in check_str] + area_sum = sum(check_int) + try: + if area_sum in [1, total_area]: + pass + elif area_sum == 2: + to_check = [total_area-index for index in range(total_area) if check_int[index] == 1] + Printer().printer(f"发现监控重复 {to_check}", "Info", "green") + await utils.check_area_list(to_check) + elif area_sum == total_area-1: + to_check = [total_area-index for index in range(total_area) if check_int[index] == 0] + Printer().printer(f"发现监控缺失 {to_check}", "Info", "green") + await utils.check_area_list(to_check) + else: + Printer().printer(f"出现意外的监控情况,启动分区检查 {check_str}", "Info", "green") + await utils.reconnect() + except Exception: + traceback.print_exc() + finally: + del self.monitor[roomid] def append_to_TVlist(self, raffleid, real_roomid, time=''): self.TV_raffleid_list.append(raffleid) self.TV_roomid_list.append(real_roomid) self.joined_TV.append(decimal_time()) - def append2pushed_TVlist(self): + def append2pushed_TVlist(self, real_roomid, area_id): self.pushed_TV.append(decimal_time()) + self.monitor[real_roomid] = self.monitor.get(real_roomid, 0) | 2**(int(area_id)-1) def check_TVlist(self, raffleid): if raffleid not in self.TV_raffleid_list: diff --git a/utils.py b/utils.py index e66f505..7c2125a 100644 --- a/utils.py +++ b/utils.py @@ -224,6 +224,9 @@ async def check_room_true(roomid): param2 = data['is_locked'] param3 = data['encrypted'] return param1, param2, param3 + else: + Printer().printer(f"获取房间信息出错: {json_response}", "Error", "red") + return [None] async def check_up_name(name): @@ -249,3 +252,8 @@ async def reconnect(area=None): if area is not None: await connect().recreate(area) await connect().check_connect(area) + + +async def check_area_list(area_list, **kwargs): + for area_id in area_list: + await connect().check_area(area_id, **kwargs)