Files
Arknights_Tools/src/SKland_Auto_Sign/auto_sign.py
T
2024-07-18 20:09:38 +08:00

162 lines
5.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import hashlib
import hmac
import json
import os.path
import time
import logging
import requests
from urllib import parse
app_code = '4ca99fa6b56cc2ba'
token_env = os.environ.get('TOKEN')
header = {
'cred': '',
'User-Agent': 'Skland/1.0.1 (com.hypergryph.skland; build:100001014; Android 31; ) Okhttp/4.11.0',
'Accept-Encoding': 'gzip',
'Connection': 'close'
}
header_login = {
'User-Agent': 'Skland/1.0.1 (com.hypergryph.skland; build:100001014; Android 31; ) Okhttp/4.11.0',
'Accept-Encoding': 'gzip',
'Connection': 'close'
}
# 签名请求头一定要这个顺序,否则失败
# timestamp是必填的,其它三个随便填,不要为none即可
header_for_sign = {
'platform': '',
'timestamp': '',
'dId': '',
'vName': ''
}
# 签到url
sign_url = "https://zonai.skland.com/api/v1/game/attendance"
# 绑定的角色url
binding_url = "https://zonai.skland.com/api/v1/game/player/binding"
# 使用token获得认证代码
grant_code_url = "https://as.hypergryph.com/user/oauth2/v2/grant"
# 使用认证代码获得cred
cred_code_url = "https://zonai.skland.com/api/v1/user/auth/generate_cred_by_code"
def generate_signature(token: str, path, body_or_query):
"""
获得签名头
接口地址+方法为Get请求?用query否则用body+时间戳+ 请求头的四个重要参数(dIdplatformtimestampvName.toJSON()
将此字符串做HMAC加密,算法为SHA-256,密钥token为请求cred接口会返回的一个token值
再将加密后的字符串做MD5即得到sign
:param token: 拿cred时候的token
:param path: 请求路径(不包括网址)
:param body_or_query: 如果是GET,则是它的query。POST则为它的body
:return: 计算完毕的sign
"""
# 总是说请勿修改设备时间,怕不是yj你的服务器有问题吧,所以这里特地-2
t = str(int(time.time()) - 2)
token = token.encode('utf-8')
header_ca = json.loads(json.dumps(header_for_sign))
header_ca['timestamp'] = t
header_ca_str = json.dumps(header_ca, separators=(',', ':'))
s = path + body_or_query + t + header_ca_str
hex_s = hmac.new(token, s.encode('utf-8'), hashlib.sha256).hexdigest()
md5 = hashlib.md5(hex_s.encode('utf-8')).hexdigest().encode('utf-8').decode('utf-8')
return md5, header_ca
def get_sign_header(url: str, method, body, old_header, local_s_token):
h = json.loads(json.dumps(old_header))
p = parse.urlparse(url)
if method.lower() == 'get':
h['sign'], header_ca = generate_signature(local_s_token, p.path, p.query)
else:
h['sign'], header_ca = generate_signature(local_s_token, p.path, json.dumps(body))
for i in header_ca:
h[i] = header_ca[i]
return h
def get_cred_by_token(token):
grant_code = get_grant_code(token)
return get_cred(grant_code)
def get_grant_code(token):
response = requests.post(grant_code_url, json={
'appCode': app_code,
'token': token,
'type': 0
}, headers=header_login)
resp = response.json()
if response.status_code != 200:
raise Exception(f'获得认证代码失败:{resp}')
if resp.get('status') != 0:
raise Exception(f'获得认证代码失败:{resp["msg"]}')
return resp['data']['code']
def get_cred(grant):
resp = requests.post(cred_code_url, json={
'code': grant,
'kind': 1
}, headers=header_login).json()
if resp['code'] != 0:
raise Exception(f'获得cred失败:{resp["message"]}')
return resp['data']
def get_binding_list(s_token):
error_message, error_code = 'Success', 0
result_list = []
header_dict = get_sign_header(binding_url, 'get', None, header, s_token)
resp = requests.get(binding_url, headers=header_dict).json()
if resp['code'] != 0:
error_message = f"请求角色列表出现问题:{resp['message']}"
error_code = -1
return error_message, error_code, []
for i in resp['data']['list']:
if i.get('appCode') != 'arknights':
continue
result_list.extend(i.get('bindingList'))
return error_message, error_code, result_list
def single_sign(cred_resp):
s_token = cred_resp['token']
header['cred'] = cred_resp['cred']
msg, code, characters = get_binding_list(s_token)
if code != 0 or not characters:
return msg, code
content = characters[0]
body = {'gameId': 1, 'uid': content.get('uid')}
resp = requests.post(sign_url, headers=get_sign_header(sign_url, 'post', body, header,s_token), json=body).json()
if resp['code'] != 0:
msg = f'角色{content.get("nickName")}({content.get("channelName")})签到失败了!原因:{resp.get("message")}'
code = -1
return msg, code
awards = resp['data']['awards']
for j in awards:
res = j['resource']
msg = f'角色{content.get("nickName")}({content.get("channelName")})签到成功,获得{res["name"]}×{j.get("count") or 1}'
code = 0
return msg, code
def new_start():
result_list = []
token_list = ['fqyRkfJrLlkuax8SzFffxc0W', 'i//Ozb2bFsXjxF9ZKgAgVi6K']
for i in token_list:
try:
credit_dict = get_cred_by_token(i)
msg, code = single_sign(credit_dict)
except Exception as ex:
print(f'签到失败,原因:{str(ex)}')
print("签到完成!")
if __name__ == '__main__':
new_start()