diff --git a/lagrange/client/client.py b/lagrange/client/client.py index 17997d0..9ace844 100644 --- a/lagrange/client/client.py +++ b/lagrange/client/client.py @@ -16,7 +16,12 @@ from lagrange.info import AppInfo, DeviceInfo, SigInfo from lagrange.pb.message.msg_push import MsgPushBody from lagrange.pb.message.send import SendMsgRsp -from lagrange.pb.service.comm import SendGrpBotHD, SendNudge +from lagrange.pb.service.comm import ( + GetClientKeyRsp, + GetCookieRsp, + SendGrpBotHD, + SendNudge, +) from lagrange.pb.service.friend import ( GetFriendListRsp, GetFriendListUin, @@ -52,6 +57,7 @@ from lagrange.pb.service.oidb import OidbRequest, OidbResponse from lagrange.pb.highway.comm import IndexNode from lagrange.utils.binary.protobuf import proto_decode, proto_encode +from lagrange.utils.httpcat import HttpCat from lagrange.utils.log import log from lagrange.utils.operator import timestamp @@ -593,3 +599,40 @@ async def get_group_last_seq(self, grp_id: int) -> int: if not rsp.body.args.seq: raise AssertionError("No message found") return rsp.body.args.seq + + async def _get_client_key(self) -> str: + return GetClientKeyRsp.decode( + (await self.send_oidb_svc(0x102A, 1, proto_encode({}))).data + ).client_key + + def _gtk_1(self, skey_or_pskey: str): + _hash = 5381 + _len = len(skey_or_pskey) + for i in range(_len): + _hash += (_hash << 5) + ord(skey_or_pskey[i]) + return _hash & 2147483647 + + async def get_cookies(self, domains: list[str]) -> List[str]: + """pskey""" + return [ + i.value.decode() + for i in GetCookieRsp.decode( + ( + await self.send_oidb_svc( + 0x102A, + 0, + proto_encode({1: domains}), # type: ignore + ) + ).data + ).urls + ] + + async def get_skey(self) -> str: + jump = "https%3A%2F%2Fh5.qzone.qq.com%2Fqqnt%2Fqzoneinpcqq%2Ffriend%3Frefresh%3D0%26clientuin%3D0%26darkMode%3D0&keyindex=19&random=2599" + url = f"https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin={self.uin}&clientkey={await self._get_client_key()}&u1={jump}" + resp = await HttpCat.request("GET", url, follow_redirect=False) + return resp.cookies["skey"] + + async def get_csrf_token(self) -> int: + skey = await self.get_skey() + return self._gtk_1(skey) diff --git a/lagrange/pb/service/comm.py b/lagrange/pb/service/comm.py index 00da058..85be29b 100644 --- a/lagrange/pb/service/comm.py +++ b/lagrange/pb/service/comm.py @@ -21,3 +21,18 @@ class SendGrpBotHD(ProtoStruct): IDD: int = proto_field(7, default=0) grp_id: int = proto_field(8, default=None) grp_type: int = proto_field(9, default=0) # 0guild 1grp 2C2C(need grp_id==None) + + +class Propertys(ProtoStruct): + key: str = proto_field(1) + value: bytes = proto_field(2) + + +class GetCookieRsp(ProtoStruct): + urls: list[Propertys] = proto_field(1) + + +class GetClientKeyRsp(ProtoStruct): + f2: int = proto_field(2) + client_key: str = proto_field(3) + expiration: int = proto_field(4)