mirror of
https://github.com/xfgryujk/blivechat.git
synced 2025-01-14 14:20:58 +08:00
升级blivedm
This commit is contained in:
parent
2a22617c1a
commit
776b354517
183
api/chat.py
183
api/chat.py
@ -14,6 +14,7 @@ import tornado.websocket
|
|||||||
|
|
||||||
import api.base
|
import api.base
|
||||||
import blivedm.blivedm as blivedm
|
import blivedm.blivedm as blivedm
|
||||||
|
import blivedm.blivedm.client as blivedm_client
|
||||||
import config
|
import config
|
||||||
import models.avatar
|
import models.avatar
|
||||||
import models.translate
|
import models.translate
|
||||||
@ -42,64 +43,88 @@ def init():
|
|||||||
room_manager = RoomManager()
|
room_manager = RoomManager()
|
||||||
|
|
||||||
|
|
||||||
class Room(blivedm.BLiveClient):
|
class Room(blivedm.BLiveClient, blivedm.BaseHandler):
|
||||||
HEARTBEAT_INTERVAL = 10
|
HEARTBEAT_INTERVAL = 10
|
||||||
|
|
||||||
# 重新定义parse_XXX是为了减少对字段名的依赖,防止B站改字段名
|
# 重新定义XXX_callback是为了减少对字段名的依赖,防止B站改字段名
|
||||||
def __parse_danmaku(self, command):
|
def __danmu_msg_callback(self, client: blivedm.BLiveClient, command: dict):
|
||||||
info = command['info']
|
info = command['info']
|
||||||
if info[3]:
|
if len(info[3]) != 0:
|
||||||
room_id = info[3][3]
|
|
||||||
medal_level = info[3][0]
|
medal_level = info[3][0]
|
||||||
|
medal_room_id = info[3][3]
|
||||||
else:
|
else:
|
||||||
room_id = medal_level = 0
|
medal_level = 0
|
||||||
return self._on_receive_danmaku(blivedm.DanmakuMessage(
|
medal_room_id = 0
|
||||||
None, None, None, info[0][4], None, None, info[0][9], None,
|
|
||||||
info[1],
|
|
||||||
info[2][0], info[2][1], info[2][2], None, None, info[2][5], info[2][6], None,
|
|
||||||
medal_level, None, None, room_id, None, None,
|
|
||||||
info[4][0], None, None,
|
|
||||||
None, None,
|
|
||||||
info[7]
|
|
||||||
))
|
|
||||||
|
|
||||||
def __parse_gift(self, command):
|
message = blivedm.DanmakuMessage(
|
||||||
|
timestamp=info[0][4],
|
||||||
|
msg_type=info[0][9],
|
||||||
|
|
||||||
|
msg=info[1],
|
||||||
|
|
||||||
|
uid=info[2][0],
|
||||||
|
uname=info[2][1],
|
||||||
|
admin=info[2][2],
|
||||||
|
urank=info[2][5],
|
||||||
|
mobile_verify=info[2][6],
|
||||||
|
|
||||||
|
medal_level=medal_level,
|
||||||
|
medal_room_id=medal_room_id,
|
||||||
|
|
||||||
|
user_level=info[4][0],
|
||||||
|
|
||||||
|
privilege_type=info[7],
|
||||||
|
)
|
||||||
|
return self._on_danmaku(client, message)
|
||||||
|
|
||||||
|
def __send_gift_callback(self, client: blivedm.BLiveClient, command: dict):
|
||||||
data = command['data']
|
data = command['data']
|
||||||
return self._on_receive_gift(blivedm.GiftMessage(
|
message = blivedm.GiftMessage(
|
||||||
data['giftName'], data['num'], data['uname'], data['face'], None,
|
gift_name=data['giftName'],
|
||||||
data['uid'], data['timestamp'], None, None,
|
num=data['num'],
|
||||||
None, None, None, data['coin_type'], data['total_coin']
|
uname=data['uname'],
|
||||||
))
|
face=data['face'],
|
||||||
|
uid=data['uid'],
|
||||||
|
timestamp=data['timestamp'],
|
||||||
|
coin_type=data['coin_type'],
|
||||||
|
total_coin=data['total_coin'],
|
||||||
|
)
|
||||||
|
return self._on_gift(client, message)
|
||||||
|
|
||||||
def __parse_buy_guard(self, command):
|
def __guard_buy_callback(self, client: blivedm.BLiveClient, command: dict):
|
||||||
data = command['data']
|
data = command['data']
|
||||||
return self._on_buy_guard(blivedm.GuardBuyMessage(
|
message = blivedm.GuardBuyMessage(
|
||||||
data['uid'], data['username'], data['guard_level'], None, None,
|
uid=data['uid'],
|
||||||
None, None, data['start_time'], None
|
username=data['username'],
|
||||||
))
|
guard_level=data['guard_level'],
|
||||||
|
start_time=data['start_time'],
|
||||||
|
)
|
||||||
|
return self._on_buy_guard(client, message)
|
||||||
|
|
||||||
def __parse_super_chat(self, command):
|
def __super_chat_message_callback(self, client: blivedm.BLiveClient, command: dict):
|
||||||
data = command['data']
|
data = command['data']
|
||||||
return self._on_super_chat(blivedm.SuperChatMessage(
|
message = blivedm.SuperChatMessage(
|
||||||
data['price'], data['message'], None, data['start_time'],
|
price=data['price'],
|
||||||
None, None, data['id'], None,
|
message=data['message'],
|
||||||
None, data['uid'], data['user_info']['uname'],
|
start_time=data['start_time'],
|
||||||
data['user_info']['face'], None,
|
id_=data['id'],
|
||||||
None, None,
|
uid=data['uid'],
|
||||||
None, None, None,
|
uname=data['user_info']['uname'],
|
||||||
None
|
face=data['user_info']['face'],
|
||||||
))
|
)
|
||||||
|
return self._on_super_chat(client, message)
|
||||||
|
|
||||||
_COMMAND_HANDLERS = {
|
_CMD_CALLBACK_DICT = {
|
||||||
**blivedm.BLiveClient._COMMAND_HANDLERS,
|
**blivedm.BaseHandler._CMD_CALLBACK_DICT,
|
||||||
'DANMU_MSG': __parse_danmaku,
|
'DANMU_MSG': __danmu_msg_callback,
|
||||||
'SEND_GIFT': __parse_gift,
|
'SEND_GIFT': __send_gift_callback,
|
||||||
'GUARD_BUY': __parse_buy_guard,
|
'GUARD_BUY': __guard_buy_callback,
|
||||||
'SUPER_CHAT_MESSAGE': __parse_super_chat
|
'SUPER_CHAT_MESSAGE': __super_chat_message_callback
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, room_id):
|
def __init__(self, room_id):
|
||||||
super().__init__(room_id, session=_http_session, heartbeat_interval=self.HEARTBEAT_INTERVAL)
|
super().__init__(room_id, session=_http_session, heartbeat_interval=self.HEARTBEAT_INTERVAL)
|
||||||
|
self.add_handler(self)
|
||||||
self.clients: List['ChatHandler'] = []
|
self.clients: List['ChatHandler'] = []
|
||||||
self.auto_translate_count = 0
|
self.auto_translate_count = 0
|
||||||
|
|
||||||
@ -107,13 +132,6 @@ class Room(blivedm.BLiveClient):
|
|||||||
await super().init_room()
|
await super().init_room()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def stop_and_close(self):
|
|
||||||
if self.is_running:
|
|
||||||
future = self.stop()
|
|
||||||
future.add_done_callback(lambda _future: asyncio.ensure_future(self.close()))
|
|
||||||
else:
|
|
||||||
asyncio.ensure_future(self.close())
|
|
||||||
|
|
||||||
def send_message(self, cmd, data):
|
def send_message(self, cmd, data):
|
||||||
body = json.dumps({'cmd': cmd, 'data': data})
|
body = json.dumps({'cmd': cmd, 'data': data})
|
||||||
for client in self.clients:
|
for client in self.clients:
|
||||||
@ -130,22 +148,19 @@ class Room(blivedm.BLiveClient):
|
|||||||
except tornado.websocket.WebSocketClosedError:
|
except tornado.websocket.WebSocketClosedError:
|
||||||
room_manager.del_client(self.room_id, client)
|
room_manager.del_client(self.room_id, client)
|
||||||
|
|
||||||
async def _on_receive_danmaku(self, danmaku: blivedm.DanmakuMessage):
|
async def _on_danmaku(self, client: blivedm.BLiveClient, message: blivedm.DanmakuMessage):
|
||||||
asyncio.ensure_future(self.__on_receive_danmaku(danmaku))
|
if message.uid == self.room_owner_uid:
|
||||||
|
|
||||||
async def __on_receive_danmaku(self, danmaku: blivedm.DanmakuMessage):
|
|
||||||
if danmaku.uid == self.room_owner_uid:
|
|
||||||
author_type = 3 # 主播
|
author_type = 3 # 主播
|
||||||
elif danmaku.admin:
|
elif message.admin:
|
||||||
author_type = 2 # 房管
|
author_type = 2 # 房管
|
||||||
elif danmaku.privilege_type != 0: # 1总督,2提督,3舰长
|
elif message.privilege_type != 0: # 1总督,2提督,3舰长
|
||||||
author_type = 1 # 舰队
|
author_type = 1 # 舰队
|
||||||
else:
|
else:
|
||||||
author_type = 0
|
author_type = 0
|
||||||
|
|
||||||
need_translate = self._need_translate(danmaku.msg)
|
need_translate = self._need_translate(message.msg)
|
||||||
if need_translate:
|
if need_translate:
|
||||||
translation = models.translate.get_translation_from_cache(danmaku.msg)
|
translation = models.translate.get_translation_from_cache(message.msg)
|
||||||
if translation is None:
|
if translation is None:
|
||||||
# 没有缓存,需要后面异步翻译后通知
|
# 没有缓存,需要后面异步翻译后通知
|
||||||
translation = ''
|
translation = ''
|
||||||
@ -157,41 +172,41 @@ class Room(blivedm.BLiveClient):
|
|||||||
id_ = uuid.uuid4().hex
|
id_ = uuid.uuid4().hex
|
||||||
# 为了节省带宽用list而不是dict
|
# 为了节省带宽用list而不是dict
|
||||||
self.send_message(Command.ADD_TEXT, make_text_message(
|
self.send_message(Command.ADD_TEXT, make_text_message(
|
||||||
await models.avatar.get_avatar_url(danmaku.uid),
|
await models.avatar.get_avatar_url(message.uid),
|
||||||
int(danmaku.timestamp / 1000),
|
int(message.timestamp / 1000),
|
||||||
danmaku.uname,
|
message.uname,
|
||||||
author_type,
|
author_type,
|
||||||
danmaku.msg,
|
message.msg,
|
||||||
danmaku.privilege_type,
|
message.privilege_type,
|
||||||
danmaku.msg_type,
|
message.msg_type,
|
||||||
danmaku.user_level,
|
message.user_level,
|
||||||
danmaku.urank < 10000,
|
message.urank < 10000,
|
||||||
danmaku.mobile_verify,
|
message.mobile_verify,
|
||||||
0 if danmaku.room_id != self.room_id else danmaku.medal_level,
|
0 if message.medal_room_id != self.room_id else message.medal_level,
|
||||||
id_,
|
id_,
|
||||||
translation
|
translation
|
||||||
))
|
))
|
||||||
|
|
||||||
if need_translate:
|
if need_translate:
|
||||||
await self._translate_and_response(danmaku.msg, id_)
|
asyncio.ensure_future(self._translate_and_response(message.msg, id_))
|
||||||
|
|
||||||
async def _on_receive_gift(self, gift: blivedm.GiftMessage):
|
async def _on_gift(self, client: blivedm.BLiveClient, message: blivedm.GiftMessage):
|
||||||
avatar_url = models.avatar.process_avatar_url(gift.face)
|
avatar_url = models.avatar.process_avatar_url(message.face)
|
||||||
models.avatar.update_avatar_cache(gift.uid, avatar_url)
|
models.avatar.update_avatar_cache(message.uid, avatar_url)
|
||||||
if gift.coin_type != 'gold': # 丢人
|
if message.coin_type != 'gold': # 丢人
|
||||||
return
|
return
|
||||||
id_ = uuid.uuid4().hex
|
id_ = uuid.uuid4().hex
|
||||||
self.send_message(Command.ADD_GIFT, {
|
self.send_message(Command.ADD_GIFT, {
|
||||||
'id': id_,
|
'id': id_,
|
||||||
'avatarUrl': avatar_url,
|
'avatarUrl': avatar_url,
|
||||||
'timestamp': gift.timestamp,
|
'timestamp': message.timestamp,
|
||||||
'authorName': gift.uname,
|
'authorName': message.uname,
|
||||||
'totalCoin': gift.total_coin,
|
'totalCoin': message.total_coin,
|
||||||
'giftName': gift.gift_name,
|
'giftName': message.gift_name,
|
||||||
'num': gift.num
|
'num': message.num
|
||||||
})
|
})
|
||||||
|
|
||||||
async def _on_buy_guard(self, message: blivedm.GuardBuyMessage):
|
async def _on_buy_guard(self, client: blivedm.BLiveClient, message: blivedm.GuardBuyMessage):
|
||||||
asyncio.ensure_future(self.__on_buy_guard(message))
|
asyncio.ensure_future(self.__on_buy_guard(message))
|
||||||
|
|
||||||
async def __on_buy_guard(self, message: blivedm.GuardBuyMessage):
|
async def __on_buy_guard(self, message: blivedm.GuardBuyMessage):
|
||||||
@ -204,7 +219,7 @@ class Room(blivedm.BLiveClient):
|
|||||||
'privilegeType': message.guard_level
|
'privilegeType': message.guard_level
|
||||||
})
|
})
|
||||||
|
|
||||||
async def _on_super_chat(self, message: blivedm.SuperChatMessage):
|
async def _on_super_chat(self, client: blivedm.BLiveClient, message: blivedm.SuperChatMessage):
|
||||||
avatar_url = models.avatar.process_avatar_url(message.face)
|
avatar_url = models.avatar.process_avatar_url(message.face)
|
||||||
models.avatar.update_avatar_cache(message.uid, avatar_url)
|
models.avatar.update_avatar_cache(message.uid, avatar_url)
|
||||||
|
|
||||||
@ -233,7 +248,7 @@ class Room(blivedm.BLiveClient):
|
|||||||
if need_translate:
|
if need_translate:
|
||||||
asyncio.ensure_future(self._translate_and_response(message.message, id_))
|
asyncio.ensure_future(self._translate_and_response(message.message, id_))
|
||||||
|
|
||||||
async def _on_super_chat_delete(self, message: blivedm.SuperChatDeleteMessage):
|
async def _on_super_chat_delete(self, client: blivedm.BLiveClient, message: blivedm.SuperChatDeleteMessage):
|
||||||
self.send_message(Command.ADD_SUPER_CHAT, {
|
self.send_message(Command.ADD_SUPER_CHAT, {
|
||||||
'ids': list(map(str, message.ids))
|
'ids': list(map(str, message.ids))
|
||||||
})
|
})
|
||||||
@ -360,7 +375,7 @@ class RoomManager:
|
|||||||
logger.info('Removing room %d', room_id)
|
logger.info('Removing room %d', room_id)
|
||||||
for client in room.clients:
|
for client in room.clients:
|
||||||
client.close()
|
client.close()
|
||||||
room.stop_and_close()
|
asyncio.ensure_future(room.stop_and_close())
|
||||||
self._rooms.pop(room_id, None)
|
self._rooms.pop(room_id, None)
|
||||||
logger.info('%d rooms', len(self._rooms))
|
logger.info('%d rooms', len(self._rooms))
|
||||||
|
|
||||||
@ -547,7 +562,7 @@ class ChatHandler(tornado.websocket.WebSocketHandler):
|
|||||||
|
|
||||||
# noinspection PyAbstractClass
|
# noinspection PyAbstractClass
|
||||||
class RoomInfoHandler(api.base.ApiHandler):
|
class RoomInfoHandler(api.base.ApiHandler):
|
||||||
_host_server_list_cache = blivedm.DEFAULT_DANMAKU_SERVER_LIST
|
_host_server_list_cache = blivedm_client.DEFAULT_DANMAKU_SERVER_LIST
|
||||||
|
|
||||||
async def get(self):
|
async def get(self):
|
||||||
room_id = int(self.get_query_argument('roomId'))
|
room_id = int(self.get_query_argument('roomId'))
|
||||||
@ -569,7 +584,7 @@ class RoomInfoHandler(api.base.ApiHandler):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
async def _get_room_info(room_id):
|
async def _get_room_info(room_id):
|
||||||
try:
|
try:
|
||||||
async with _http_session.get(blivedm.ROOM_INIT_URL, params={'room_id': room_id}
|
async with _http_session.get(blivedm_client.ROOM_INIT_URL, params={'room_id': room_id}
|
||||||
) as res:
|
) as res:
|
||||||
if res.status != 200:
|
if res.status != 200:
|
||||||
logger.warning('room %d _get_room_info failed: %d %s', room_id,
|
logger.warning('room %d _get_room_info failed: %d %s', room_id,
|
||||||
|
2
blivedm
2
blivedm
@ -1 +1 @@
|
|||||||
Subproject commit 4669b2c1c9a1654db340d02ff16c9f88be661d9f
|
Subproject commit d8f7f6b7828069cb6c1fd13f756cfd891f0b1a46
|
@ -1,4 +1,5 @@
|
|||||||
aiohttp==3.7.4
|
aiohttp==3.7.4
|
||||||
|
Brotli==1.0.9
|
||||||
pycryptodome==3.10.1
|
pycryptodome==3.10.1
|
||||||
sqlalchemy==1.3.13
|
sqlalchemy==1.3.13
|
||||||
tornado==6.0.2
|
tornado==6.0.2
|
||||||
|
Loading…
Reference in New Issue
Block a user