feat: Live room connect support

This commit is contained in:
LWR 2022-11-04 19:37:39 +08:00
parent c25b88910b
commit 35bc6a4a21
3 changed files with 109 additions and 1 deletions

View File

@ -8,9 +8,11 @@ from loguru import logger
from .datasource import DataSource
from .server import http_init
from ..exception import LiveException
from ..exception.DataSourceException import DataSourceException
from ..exception.RedisException import RedisException
from ..utils import redis, config
from ..utils.network import request
class StarBot:
@ -61,6 +63,44 @@ class StarBot:
logger.error(ex.msg)
return
# 通过 UID 列表批量获取信息
uids = list(map(lambda u: str(u), self.__datasource.get_uid_list()))
info_url = "https://api.live.bilibili.com/room/v1/Room/get_status_info_by_uids?uids[]=" + "&uids[]=".join(uids)
info = await request("GET", info_url)
for uid in info:
base = info[uid]
uid = int(uid)
up = self.__datasource.get_up(uid)
up.uname = base["uname"]
up.room_id = base["room_id"]
status = base["live_status"]
logger.opt(colors=True).info(f"初始化 <cyan>{up.uname}</> "
f"(UID: <cyan>{up.uid}</>, "
f"房间号: <cyan>{up.room_id}</>) 的直播间状态: "
f"{'<green>直播中</>' if status == 1 else '<red>未开播</>'}")
await redis.hset("LiveStatus", up.room_id, status)
await redis.hset("StartTime", up.room_id, base["live_time"])
await redis.hset_ifnotexists("EndTime", up.room_id, 0)
await redis.hset_ifnotexists("RoomDanmuCount", up.room_id, 0)
await redis.hset_ifnotexists("RoomDanmuTotal", up.room_id, 0)
await redis.hset_ifnotexists("RoomBoxCount", up.room_id, 0)
await redis.hset_ifnotexists("RoomBoxTotal", up.room_id, 0)
await redis.hset_ifnotexists("RoomBoxProfit", up.room_id, 0)
await redis.hset_ifnotexists("RoomBoxProfitTotal", up.room_id, 0)
await redis.hset_ifnotexists("RoomGiftProfit", up.room_id, 0)
await redis.hset_ifnotexists("RoomGiftTotal", up.room_id, 0)
await redis.hset_ifnotexists("RoomScProfit", up.room_id, 0)
await redis.hset_ifnotexists("RoomScTotal", up.room_id, 0)
await redis.hset_ifnotexists("RoomGuardCount", up.room_id, "0-0-0")
await redis.hset_ifnotexists("RoomGuardTotal", up.room_id, "0-0-0")
for up in self.__datasource.get_up_list():
try:
await up.connect()
except LiveException as ex:
logger.error(ex.msg)
# 启动 HTTP API 服务
if config.get("USE_HTTP_API"):
asyncio.get_event_loop().create_task(http_init(self.__datasource))

View File

@ -0,0 +1,8 @@
s = "Unccl oveguqnl gb zr!"
d = {}
for c in (65, 97):
for i in range(26):
d[chr(i+c)] = chr((i+13) % 26 + c)
print("".join([d.get(c, c) for c in s]))

View File

@ -3,10 +3,15 @@ import typing
from asyncio import AbstractEventLoop
from typing import Optional, List, Any
from loguru import logger
from pydantic import BaseModel, PrivateAttr
from .live import LiveDanmaku
from .live import LiveDanmaku, LiveRoom
from .model import PushTarget
from .user import User
from ..exception import LiveException
from ..utils import config, redis
from ..utils.utils import get_credential
if typing.TYPE_CHECKING:
from .sender import Bot
@ -51,6 +56,61 @@ class Up(BaseModel):
def inject_bot(self, bot):
self.__bot = bot
def any_live_on_enabled(self):
return any(map(lambda conf: conf.enabled, map(lambda group: group.live_on, self.targets)))
def any_live_off_enabled(self):
return any(map(lambda conf: conf.enabled, map(lambda group: group.live_off, self.targets)))
def any_live_report_enabled(self):
return any(map(lambda conf: conf.enabled, map(lambda group: group.live_report, self.targets)))
async def connect(self):
"""
连接直播间
"""
if not all([self.uname, self.room_id]):
user = User(self.uid, get_credential())
user_info = await user.get_user_info()
self.uname = user_info["name"]
if user_info["live_room"] is None:
raise LiveException(f"UP 主 {self.uname} ( UID: {self.uid} ) 还未开通直播间~")
self.room_id = user_info["live_room"]["roomid"]
self.__room = LiveDanmaku(self.room_id, credential=get_credential())
# 开播推送开关和下播推送开关均处于关闭状态时跳过连接直播间,以节省性能
if config.get("ONLY_CONNECT_NECESSARY_ROOM"):
if not any([self.any_live_on_enabled(), self.any_live_off_enabled(), self.any_live_report_enabled()]):
logger.warning(f"{self.uname} 的开播, 下播和直播报告开关均处于关闭状态, 跳过连接直播间")
return
logger.opt(colors=True).info(f"准备连接到 <cyan>{self.uname}</> 的直播间 <cyan>{self.room_id}</>")
self.__loop.create_task(self.__room.connect())
@self.__room.on("VERIFICATION_SUCCESSFUL")
async def on_link(event):
if self.__is_reconnect:
logger.success(f"直播间 {self.room_id} 断线重连成功")
live_room = LiveRoom(self.room_id, get_credential())
room_info = await live_room.get_room_play_info()
last_status = await redis.hgeti("LiveStatus", self.room_id)
now_status = room_info["live_status"]
if now_status != last_status:
await redis.hset("LiveStatus", self.room_id, now_status)
if last_status == 1:
logger.warning(f"直播间 {self.room_id} 断线期间下播")
pass
if now_status == 1:
logger.warning(f"直播间 {self.room_id} 断线期间开播")
pass
else:
self.__is_reconnect = True
logger.success(f"已成功连接到 {self.uname} 的直播间 {self.room_id}")
def __eq__(self, other):
if isinstance(other, Up):
return self.uid == other.uid