AuthLite实现,ApiHash草稿,各种小改进

This commit is contained in:
Remik1r3n
2025-02-18 14:53:27 +08:00
parent 32d566841c
commit 7570fbc8f4
9 changed files with 228 additions and 13 deletions

125
API_AuthLite.py Normal file
View File

@@ -0,0 +1,125 @@
# All.Net AuthLite 更新获取
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import httpx
from loguru import logger
from urllib.parse import parse_qs
import configparser as ini
def enc(key, iv, data):
cipher = AES.new(key, AES.MODE_CBC, iv)
encrypted = cipher.encrypt(data)
return encrypted
def dec(key, iv ,data):
de_cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = de_cipher.decrypt(data)
return decrypted
def getRawDelivery():
key = bytes([47, 63, 106, 111, 43, 34, 76, 38, 92, 67, 114, 57, 40, 61, 107, 71])
iv = bytes.fromhex('00000000000000000000000000000000')
content = bytes([0] * 16) + b'title_id=SDGB&title_ver=1.40&client_id=A63E01C2805'
header = bytes.fromhex('00000000000000000000000000000000')
bytes_data = pad(header + content, 16)
encrypted = enc(key, iv, bytes_data)
r = httpx.post(
'http://at.sys-allnet.cn/net/delivery/instruction',
data = encrypted,
headers = {
'User-Agent': "SDGB;Windows/Lite",
'Pragma': 'DFI'
}
)
resp_data = r.content
decrypted = dec(key, resp_data[:16], resp_data)
decrypted_str = decrypted[16:].decode('UTF-8').strip()
# 过滤所有控制字符
decrypted_str = ''.join([i for i in decrypted_str if 31 < ord(i) < 127])
logger.info(f"RAW Response: {decrypted_str}")
return decrypted_str
def parseRawDelivery(deliveryStr):
"""解析 RAW 的 Delivery 字符串,返回其中的有效的 instruction URL 的列表"""
parsedResponseDict = {key: value[0] for key, value in parse_qs(deliveryStr).items()}
urlList = parsedResponseDict['uri'].split('|')
# 过滤掉空字符串和内容为 null 的情况
urlList = [url for url in urlList if url and url != 'null']
logger.info(f"Parsed URL List: {urlList}")
validURLs = []
for url in urlList:
# 检查是否是 HTTPS 的 URL以及是否是 txt 文件,否则忽略
if not url.startswith('https://') or not url.endswith('.txt'):
logger.warning(f"Invalid URL will be ignored: {url}")
continue
validURLs.append(url)
logger.info(f"Verified Valid URLs: {validURLs}")
return validURLs
def getUpdateIniFromURL(url):
# 发送请求
response = httpx.get(url, headers={
'User-Agent': 'SDGB;Windows/Lite',
'Pragma': 'DFI'
})
logger.info(f"成功自 {url} 获取更新信息")
return response.text
def parseUpdateIni(iniText):
# 解析配置
config = ini.ConfigParser(allow_no_value=True)
config.read_string(iniText)
logger.info(f"成功解析配置文件,包含的节有:{config.sections()}")
# 获取 COMMON 节的配置
common = config['COMMON']
# 初始化消息列表
message = []
# 获取游戏描述并去除引号
game_desc = common['GAME_DESC'].strip('"')
# 根据前缀选择消息模板和图标
prefix_icons = {
'PATCH': ('💾 游戏程序更新 ', 'PATCH_'),
'OPTION': ('📚 游戏内容更新 ', 'OPTION_')
}
icon, prefix = prefix_icons.get(game_desc.split('_')[0], ('📦 游戏更新 ', ''))
# 构建消息标题
game_title = game_desc.replace(prefix, '', 1)
message.append(f"{icon}{game_title}")
# 添加主文件的下载链接
main_file = common['INSTALL1']
main_file_name = main_file.split('/')[-1]
message.append(f"下载: \n- [{main_file_name}]({main_file})")
# 添加可选文件的下载链接(如果有)
if 'OPTIONAL' in config:
message.append("其它文件:")
optional_files = [f"- [{url.split('/')[-1]}]({url})" for _, url in config.items('OPTIONAL')]
message.extend(optional_files)
# 添加发布时间信息
release_time = common['RELEASE_TIME'].replace('T', ' ')
message.append(f"将于 {release_time} 发布。\n")
# 构建最终的消息字符串
final_message = '\n'.join(message)
logger.info(f"消息构建完成,最终的消息为:\n{final_message}")
return final_message
if __name__ == '__main__':
urlList = parseRawDelivery(getRawDelivery())
for url in urlList:
iniText = getUpdateIniFromURL(url)
message = parseUpdateIni(iniText)