async def send(self, value): url = "https://api.live.bilibili.com/gift/v2/live/bag_send" csrf = account["Token"]["CSRF"] payload = { "coin_type": "silver", "gift_id": value["gift_id"], "ruid": self.ruid, "uid": self.uid, "biz_id": self.roomid, "gift_num": value["gift_num"], "data_source_id": "", "data_behavior_id": "", "bag_id": value["bag_id"], "csrf_token": csrf, "csrf": csrf } data = await AsyncioCurl().request_json("POST", url, headers=config["pcheaders"], data=payload) if data["code"] != 0: Log.warning("送礼失败!" + data["message"]) else: Log.info( "成功向 %s 投喂了 %s 个 %s" % (payload["biz_id"], value["gift_num"], value["gift_name"]))
async def work(self): if config["Function"]["GIFTSEND"] == "False": return if config["GiftSend"]["ROOM_ID"] == "": Log.warning("自动送礼模块房间号未配置,已停止...") return while 1: if self.ruid == 0: status = await self.getRoomInfo() if status == 1: return elif status == 25014: self.index = 0 await asyncio.sleep(std235959ptm()) url = "https://api.live.bilibili.com/gift/v2/gift/bag_list" data = await AsyncioCurl().request_json( "GET", url, headers=config["pcheaders"]) if data["code"] != 0: Log.warning("背包查看失败!" + data["message"]) if len(data["data"]["list"]) != 0: for each in data["data"]["list"]: if each["expire_at"] >= data["data"]["time"] and each[ "expire_at"] <= data["data"]["time"] + int( config["GiftSend"]["TIME"]): await self.send(each) await asyncio.sleep(3) await asyncio.sleep(600)
async def SendGift(self): status = await self.getRoomInfo() if status == 0: Log.info("开始执行自动送礼物...") url = "https://api.live.bilibili.com/gift/v2/gift/bag_list" data = await AsyncioCurl().request_json("GET", url, headers=config["pcheaders"]) if data["code"] != 0: Log.warning("背包查看失败!" + data["message"]) if len(data["data"]["list"]) != 0: for each in data["data"]["list"]: IfExpired = each["expire_at"] >= data["data"]["time"] and each["expire_at"] <= data["data"]["time"] + int(config["GiftSend"]["GIFTTiME"]) if IfExpired == True or int(config["GiftSend"]["GIFTTiME"]) == -1: NeedGift = await Utils.value_to_full_intimacy_today(self.roomid) SendGift = each # 1个亿元相当于10个单位的亲密度,所以要除掉一些 if each["gift_name"] == "亿元": # 向下取整 NeedGift = int ( NeedGift / 10 ) SendGift["gift_num"] = NeedGift # 判断需要的礼物是否过多,避免浪费 if each["gift_num"] >= NeedGift: SendGift["gift_num"] = NeedGift await self.send(SendGift) await asyncio.sleep(6) status = await Utils.is_intimacy_full_today(self.roomid) if status: Log.warning("当前房间勋章亲密度已满,正在退出任务...") return 0 else: Log.info("背包清空完毕,退出任务...") return 2 elif status == 1: Log.warning("清空礼物功能禁用!") return status
def getToken(self, username, password): payload = { "seccode": "", "validate": "", "subid": 1, "permission": "ALL", "username": username, "password": password, "captcha": "", "challenge": "", "cookies": config["Token"]["COOKIE"] } data = Curl().post("https://passport.bilibili.com/api/v3/oauth2/login", payload) data = json.loads(data) if data["code"] == 0: Log.info("账号登陆成功") else: Log.error("账号登陆失败" + "-" + data["message"]) config["Token"]["ACCESS_TOKEN"] = data["data"]["token_info"][ "access_token"] config["Token"]["REFRESH_TOKEN"] = data["data"]["token_info"][ "refresh_token"] csrf, uid, cookie = arrange_cookie(data) config["Token"]["CSRF"] = csrf config["Token"]["UID"] = uid set_cookie(cookie) config.write()
async def double_watch_info(self, value): if len(value["data"]["watch_info"]) == 0: return if "double_watch_info" in self.done: return Log.info("检查任务「双端观看直播」") info = value["data"]["double_watch_info"] if info["status"] == 2: Log.warning("「双端观看直播」奖励已经领取过") self.done.append("double_watch_info") return if info["mobile_watch"] != 1 or info["web_watch"] != 1: Log.warning("「双端观看直播」未完成,请等待") return url = "https://api.live.bilibili.com/activity/v1/task/receive_award" payload = { "task_id": "double_watch_task", "csrf_token": account["Token"]["CSRF"], "csrf": account["Token"]["CSRF"] } data = await AsyncioCurl().request_json("POST", url, headers=config["pcheaders"], data=payload) if data["code"] != 0: Log.error("「双端观看直播」奖励领取失败") else: Log.info("「双端观看直播」奖励领取成功") self.done.append("double_watch_info")
async def send(self, value): url = "https://api.live.bilibili.com/gift/v2/live/bag_send" csrf = account["Token"]["CSRF"] payload = { "coin_type": "silver", "gift_id": value["gift_id"], "ruid": self.ruid, "uid": self.uid, "biz_id": self.roomid, "gift_num": value["gift_num"], "data_source_id": "", "data_behavior_id": "", "bag_id": value["bag_id"], "csrf_token": csrf, "csrf": csrf } data = await AsyncioCurl().request_json("POST", url, headers=config["pcheaders"], data=payload) if data["code"] != 0: Log.warning("送礼失败!" + data["message"]) if self.roomid not in self.gift: self.gift[self.roomid] = {} if value["gift_name"] not in self.gift[self.roomid]: self.gift[self.roomid][value["gift_name"]] = value["gift_num"] else: self.gift[self.roomid][value["gift_name"]] += value["gift_num"] Log.debug( f'向 {self.roomid} 送出 {value["gift_num"]} 个 {value["gift_name"]}')
async def join(real_roomid, raffle_id, raffle_type, raffle_name): await BasicRequest.enter_room(real_roomid) data = await BasicRequest.tv_req_join(real_roomid, raffle_id, raffle_type) Log.raffle("参与了房间 %s 的 %s 抽奖" % (real_roomid, raffle_name)) Log.raffle("%s 抽奖状态: %s" % (raffle_name, "OK" if data["code"] == 0 else data["msg"])) Statistics.add2joined_raffles("小电视类(合计)") code = data["code"] # tasklist = [] if not code: # await asyncio.sleep(random.randint(170,190)) # task = asyncio.ensure_future(TvRaffleHandler.notice(raffle_id,real_roomid,raffle_name)) # tasklist.append(task) # await asyncio.wait(tasklist, return_when=asyncio.FIRST_COMPLETED) Log.raffle("房间 %s %s 抽奖结果: %s X %s" % (real_roomid, raffle_name, data["data"]["award_name"], data["data"]["award_num"])) Statistics.add2results(data["data"]["award_name"], int(data["data"]["award_num"])) elif code == -500: Log.error("-500繁忙,稍后重试") return False elif code == -403 or data["msg"] == "访问被拒绝": Log.error("当前账号正在小黑屋中") return False
async def sign_info(self): if "sign_info" in self.done: return Log.info("检查任务「每日签到」") sign_data = await BasicRequest.req_check_signinfo() if not sign_data["code"]: info = sign_data["data"] if info["status"] == 1: Log.warning("「每日签到」奖励已经领取") self.done.append("sign_info") return url = "https://api.live.bilibili.com/sign/doSign" data = await AsyncioCurl().request_json("GET", url, headers=config["pcheaders"]) if data["code"] == 0: Log.info("「每日签到」成功,您已连续签到 %s 天,获得%s,%s" % (data["data"]["hadSignDays"], data["data"]["text"], data["data"]["specialText"])) self.done.append("sign_info") elif data["code"] == 1011040: Log.warning("「每日签到」今日已签到过") self.done.append("sign_info") else: Log.error("「每日签到」失败")
async def close(self): try: await self.ws.close() except: Log.error("无法关闭与舰长监控服务器的连接") if not self.ws.closed: Log.error("舰长监控服务器状态 %s" % self.ws.closed)
async def check(real_roomid, raffle_name): if not await Utils.is_normal_room(real_roomid): return data = await BasicRequest.tv_req_check(real_roomid) checklen = data["data"]["list"] list_available_raffleid = [] try: for j in checklen: raffle_id = j["raffleId"] raffle_type = j["type"] time_wanted = j["time_wait"] + int(time.time()) if not Statistics.is_raffleid_duplicate(raffle_id): Log.raffle("本次获取到 %s 的抽奖id为: %s" % (raffle_name, raffle_id)) list_available_raffleid.append( (raffle_id, raffle_type, time_wanted)) Statistics.add2raffle_ids(raffle_id) except: Log.error("检测到无效的小电视类抽奖") # 暂时没啥用 # num_aviable = len(list_available_raffleid) for raffle_id, raffle_type, time_wanted in list_available_raffleid: Timer.add2list_jobs( TvRaffleHandler.join, time_wanted, (real_roomid, raffle_id, raffle_type, raffle_name))
def post(self, url, param): Log.debug("POST: " + url) payload = {"cookie": config["Token"]["COOKIE"]} payload = dict(param, **payload) payload = sign(payload) r = requests.post(url, payload) return r.text
async def work(self): if config["Function"]["MatchTask"] == "False": return while 1: Log.info("检查赛事每日任务") await self.LPLTask() await self.LPLShare() await asyncio.sleep(3) await self.OWLTask() await self.OWLShare() await asyncio.sleep(3) await self.KPLTask() await self.KPLDanmuTask() Log.info("今日全部赛事任务完成") await asyncio.sleep(3) if config["MatchTask"]["OpenCapsule"] == "True": await self.LPLOpenCapsule() await self.OWLOpenCapsule() await self.KPLOpenCapsule() await asyncio.sleep(3600)
async def read_datas(self): while True: datas = await self.read_bytes() # 本函数对bytes进行相关操作,不特别声明,均为bytes if datas is None: return data_l = 0 len_datas = len(datas) while data_l != len_datas: # 每片data都分为header和body,data和data可能粘连 # data_l == header_l && next_data_l = next_header_l # ||header_l...header_r|body_l...body_r||next_data_l... tuple_header = self.structer.unpack_from(datas[data_l:]) len_data, len_header, ver, opt, seq = tuple_header body_l = data_l + len_header next_data_l = data_l + len_data body = datas[body_l:next_data_l] # 人气值之类的,在这里不使用 if opt == 3: # 满屏都是这个破玩意,注释掉了 # Log.info("弹幕心跳检测 %s"%self._area_id) pass # cmd elif opt == 5: if not self.handle_danmu(body): return # 握手确认 elif opt == 8: Log.info("%s 号弹幕监控进入房间 %s" % (self._area_id, self._room_id)) else: Log.warning(datas[data_l:next_data_l]) data_l = next_data_l
def double_watch_info(self, value): if len(value["data"]["double_watch_info"]) == 0: return if "double_watch_info" in self.done: return Log.info("检查任务「双端观看直播」") info = value["data"]["double_watch_info"] if info["status"] == 2: Log.info("「双端观看直播」奖励已经领取") self.done.append("double_watch_info") return if info["mobile_watch"] != 1 or info["web_watch"] != 1: Log.warning("「双端观看直播」未完成,请等待") return payload = {"task_id": "double_watch_task"} data = Curl().post( "https://api.live.bilibili.com/activity/v1/task/receive_award", payload) data = json.loads(data) if data["code"] != 0: Log.error("「双端观看直播」奖励领取失败") else: Log.info("「双端观看直播」奖励领取成功") self.done.append("double_watch_info")
def work(self): if config["Function"]["GIFTSEND"] == "False": return if self.lock > int(time.time()): return if self.ruid == 0: self.getRoomInfo() if self.lock > int(time.time()): return url = "https://api.live.bilibili.com/gift/v2/gift/bag_list" payload = {} data = Curl().request_json("GET", url, headers=config["pcheaders"], params=payload) if data["code"] != 0: Log.warning("背包查看失败!" + data["message"]) if len(data["data"]["list"]) != 0: for each in data["data"]["list"]: if each["expire_at"] >= data["data"]["time"] and each[ "expire_at"] <= data["data"]["time"] + 3600: self.send(each) time.sleep(3) self.lock = int(time.time()) + 600
def request_json(self, method, url, headers=None, data=None, params=None, sign=True): i = 0 while True: i += 1 if i >= 10: Log.warning(url) try: if method == "GET": if sign == True: params = Sign(params) r = requests.get(url, headers=headers, params=params) return json.loads(r.text) elif method == "POST": if sign == True: data = Sign(data) r = requests.post(url, headers=headers, data=data) return json.loads(r.text) except: continue
async def request_json(self, method, url, headers=None, data=None, params=None, is_none_allowed=False): async with sem: i = 0 while True: i += 1 if i >= 10: Log.warning(url) try: async with self.session.request(method, url, headers=headers, data=data, params=params) as rsp: if rsp.status == 200: json_body = await self.__get_json_body(rsp) if json_body is not None or is_none_allowed: await self.session.close() return json_body elif rsp.status == 403: Log.warning("%s 403频繁,休眠240s" % url) await asyncio.sleep(240) elif rsp.status == 404: return None except: continue
def getToken(self, username, password): url = "https://passport.bilibili.com/api/v3/oauth2/login" payload = { "seccode": "", "validate": "", "subid": 1, "permission": "ALL", "username": username, "password": password, "captcha": "", "challenge": "", "cookies": account["Token"]["COOKIE"] } data = Curl().request_json("POST", url, headers=config["pcheaders"], data=payload) if data["code"] == 0: Log.info("账号登陆成功") else: Log.error("账号登陆失败" + "-" + data["message"]) if "Token" not in account: account["Token"] = {} account["Token"]["ACCESS_TOKEN"] = data["data"]["token_info"][ "access_token"] account["Token"]["REFRESH_TOKEN"] = data["data"]["token_info"][ "refresh_token"] csrf, uid, cookie = arrange_cookie(data) account["Token"]["CSRF"] = csrf account["Token"]["UID"] = uid set_cookie(cookie)
def request_json(self, method, url, headers = None, data = None, params = None, sign = True): i = 0 while True: i += 1 if i >= 10: Log.warning(url) exit(0) try: if method == "GET": if sign == True: params = Sign(params) if self.proxies != None: r = requests.get(url, headers = headers, params = params, proxies = self.proxies) else: r = requests.get(url, headers = headers, params = params) return json.loads(r.text) elif method == "POST": if sign == True: data = Sign(data) if self.proxies != None: r = requests.post(url, headers = headers, data = data, proxies = self.proxies) else: r = requests.post(url, headers = headers, data = data) return json.loads(r.text) except Exception as e: Log.error(e) continue
async def check(self): url = "https://api.live.bilibili.com/i/api/taskInfo" data = await AsyncioCurl().request_json("GET", url, headers=config["pcheaders"]) if data["code"] != 0: Log.error("每日任务检查失败") return data
async def reconnect(self, room_id): async with self.lock_for_reseting_roomid_manually: if self.ws is not None: await self.close() if self.task_main is not None: await self.task_main # 由于锁的存在,绝对不可能到达下一个的自动重连状态,这里是保证正确显示当前监控房间号 self.room_id = room_id Log.info("%s 号弹幕姬已经切换房间 %s" % (self._area_id, room_id))
def check(self): url = "https://api.live.bilibili.com/i/api/taskInfo" payload = {} data = Curl().request_json("GET",url,headers=config["pcheaders"],params=payload) if data["code"] != 0: Log.error("每日任务检查失败") return data
async def close(self): # 尝试关闭连接 try: await self.ws.close() # 如果关闭失败 except: Log.error("关闭与B站弹幕姬服务器时出现错误") if not self.ws.closed: Log.error("%s 号弹幕收尾模块状态 %s" % (self._area_id, self.ws.closed))
async def getList(self): url = "https://api.live.bilibili.com/room/v1/Area/getList" data = await AsyncioCurl().request_json("GET", url, headers=config["pcheaders"]) if data["code"] != 0: Log.error("获取分区列表失败") else: for item in data["data"]: Log.info("追加分区"+str(item["id"])) self.arealist.append(item["id"])
async def check(real_roomid): data = await BasicRequest.anchor_req_chcek(real_roomid) if not data["code"]: data = data["data"] if Utils.have_win_award(data["award_users"]): Log.raffle("%s 天选时刻抽奖结果: %s" % (real_roomid, data["name"])) Statistics.add2results(data["name"], 1) else: Log.raffle("%s 天选时刻抽奖结果: 没有中奖" % real_roomid)
def sign(): try: headers = {'User-Agent': 'Mozilla/5.0 (Linux; Android 9; DUK-AL20) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Mobile Safari/537.36','Cookie':cookie} url = 'http://api.live.bilibili.com/sign/doSign' request = urllib.request.Request(url=url, headers=headers, method='GET') html = urllib.request.urlopen(request).read().decode('utf-8') Log.info(str(html)) except: Log.info("签到网络失败")
async def open(self): try: url = "wss://broadcastlv.chat.bilibili.com:443/sub" self.ws = await asyncio.wait_for(self.client.ws_connect(url), timeout=3) except: Log.error("无法连接到B站弹幕姬服务器,请检查您的网络连接") return False Log.info("%s 号弹幕监控已连接到B站弹幕姬服务器" % self._area_id) return (await self.send_bytes(self.bytes_conn_room))
async def work(self): if config["Function"]["TASK"] == "False": return Log.info("检查每日任务") await self.web_info() await self.app_info() await self.sign_info()
async def app_info(self): try: response = BasicRequest.app_get_info_by_room() if response["code"] != 0: Log.warning( f"app getInfoByRoom 返回错误: {response.get('message') or response.get('msg')}" ) except Exception as exc: Log.error(f"{exc}")
async def open(self): try: url = f"ws://{self.address}" self.ws = await asyncio.wait_for(self.client.ws_connect(url), timeout=3) self.accepted = True except: Log.error("无法连接到舰长监控服务器,请检查网络连接以及端口是否开放") return False Log.info("监控服务器已连接到: %s" % url) return True