From 27fa079145961b6e7bf22d8f1388af9120272bab Mon Sep 17 00:00:00 2001 From: wbt5 Date: Tue, 18 Aug 2020 21:48:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=89=BA=E6=B0=94=E5=B1=B1?= =?UTF-8?q?=E7=9B=B4=E6=92=AD=E5=BC=B9=E5=B9=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- danmu/danmaku/_173.py | 137 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 danmu/danmaku/_173.py diff --git a/danmu/danmaku/_173.py b/danmu/danmaku/_173.py new file mode 100644 index 0000000..8ec8205 --- /dev/null +++ b/danmu/danmaku/_173.py @@ -0,0 +1,137 @@ +import binascii +import struct + +import requests +from Crypto.Cipher import DES +from Crypto.Util.Padding import pad + +from . import _173_pb2 as pb + + +class YiQiShan: + ws_url = 'wss://websocket.173.com/' + + def __init__(self, rid): + self.rid = str(rid) + self.key = b'e#>&*m16' + with requests.Session() as se: + res = se.get('http://www.173.com/{}'.format(rid)) + try: + self.uuid, _, token, _ = res.cookies.values() + except ValueError: + raise Exception('房间不存在') + self.accesstoken = binascii.a2b_hex(token) + s = YiQiShan.des_decode(self.accesstoken, self.key) + p = pb.Token() + p.ParseFromString(s) + self.gtkey = p.gtkey[:8] + + @staticmethod + def des_encode(t, key): + t = pad(t, DES.block_size) + c = DES.new(key, DES.MODE_ECB) + res = c.encrypt(t) + return res + + @staticmethod + def des_decode(t, key): + c = DES.new(key, DES.MODE_ECB) + res = c.decrypt(t) + length = len(res) + padding = res[length - 1] + res = res[0:length - padding] + return res + + def startup(self): + p = pb.TCPAccessReq() + p.AccessToken = self.accesstoken + return p.SerializeToString() + + def tcphelloreq(self): + p = pb.TcpHelloReq() + p.uuid = self.uuid + return p.SerializeToString() + + def enterroomreq(self): + p = pb.EnterRoomReq() + p.uuid = self.uuid.encode() + p.roomid = self.rid.encode() + return p.SerializeToString() + + def roomhelloreq(self): + p = pb.RoomHelloReq() + p.uuid = self.uuid.encode() + p.roomid = self.rid.encode() + return p.SerializeToString() + + def pack(self, paylod_type): + command = { + 'startup': 123, + 'tcphelloreq': 122, + 'enterroomreq': 601, + 'roomhelloreq': 600 + } + subcmd = { + 'startup': 0, + 'tcphelloreq': 0, + 'enterroomreq': 1, + 'roomhelloreq': 1 + } + p = pb.CSHead() + p.command = command[paylod_type] + p.subcmd = subcmd[paylod_type] + p.uuid = self.uuid.encode() + p.clientType = 4 + p.routeKey = int(self.rid) + n = p.SerializeToString() + + key = self.key if paylod_type == 'startup' else self.gtkey + payload = getattr(self, paylod_type)() + s = YiQiShan.des_encode(payload, key) + + buf = struct.pack('!HcH', len(n) + len(s) + 8, b'W', len(n)) + buf += n + buf += struct.pack('!H', len(s)) + buf += s + b'M' + return buf + + def unpack(self, data): + msgs = [{'name': '', 'content': '', 'msg_type': 'other'}] + + s, = struct.unpack_from('!h', data, 3) + p, = struct.unpack_from('!h', data, 5 + s) + u = data[7 + s:7 + s + p] + + a = pb.CSHead() + a.ParseFromString(data[5:5 + s]) + cmd = a.command + key = self.key if cmd == 123 else self.gtkey + t = u if cmd == 102 else YiQiShan.des_decode(u, key) + + o = cmd + # r = a.subcmd + if o == 102: + p = pb.SendBroadcastPkg() + p.ParseFromString(t) + for i in p.broadcastmsg: + # PublicChatNotify = 1 + # BUSINESS_TYPE_FREE_GIFT = 2 + # BUSINESS_TYPE_PAY_GIFT = 3 + if i.businesstype == 1: # 发言 + q = pb.PublicChatNotify() + q.ParseFromString(i.content) + user = q.nick.decode() + content = q.info.textmsg.decode() + # elif i.businesstype == 2: # 免费礼物 + # print(i.businesstype) + # q = pb.NotifyFreeGift() + # q.ParseFromString(i.content) + # elif i.businesstype == 3: # 收费礼物 + # print(i.businesstype) + # q = pb.GiftNotyInfo() + # q.ParseFromString(i.content) + # else: + # pass + msg = {'name': user, 'content': content, 'msg_type': 'danmaku'} + msgs.append(msg.copy()) + return msgs