2021-12-16 11:16:28 +08:00
|
|
|
|
from typing import Optional, List, Dict, Union
|
|
|
|
|
|
from .draw_image import init_image, get_genshin_image
|
|
|
|
|
|
from nonebot.adapters.cqhttp import MessageSegment
|
|
|
|
|
|
from ..utils import get_ds, element_mastery
|
|
|
|
|
|
from services.log import logger
|
|
|
|
|
|
from utils.http_utils import AsyncHttpx
|
|
|
|
|
|
from configs.config import Config
|
|
|
|
|
|
from ..models import Genshin
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
import ujson as json
|
|
|
|
|
|
except ModuleNotFoundError:
|
|
|
|
|
|
import json
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def query_role_data(
|
|
|
|
|
|
user_id: int, uid: int, mys_id: Optional[str] = None, nickname: Optional[str] = None
|
|
|
|
|
|
) -> Optional[Union[MessageSegment, str]]:
|
|
|
|
|
|
uid = str(uid)
|
|
|
|
|
|
if uid[0] == "1" or uid[0] == "2":
|
|
|
|
|
|
server_id = "cn_gf01"
|
|
|
|
|
|
elif uid[0] == "5":
|
|
|
|
|
|
server_id = "cn_qd01"
|
|
|
|
|
|
else:
|
|
|
|
|
|
return None
|
|
|
|
|
|
return await get_image(user_id, uid, server_id, mys_id, nickname)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def get_image(
|
|
|
|
|
|
user_id: int,
|
|
|
|
|
|
uid: str,
|
|
|
|
|
|
server_id: str,
|
|
|
|
|
|
mys_id: Optional[str] = None,
|
|
|
|
|
|
nickname: Optional[str] = None,
|
|
|
|
|
|
) -> Optional[Union[MessageSegment, str]]:
|
|
|
|
|
|
"""
|
|
|
|
|
|
生成图片
|
|
|
|
|
|
:param user_id:用户qq
|
|
|
|
|
|
:param uid: 用户uid
|
|
|
|
|
|
:param server_id: 服务器
|
|
|
|
|
|
:param mys_id: 米游社id
|
|
|
|
|
|
:param nickname: QQ昵称
|
|
|
|
|
|
:return:
|
|
|
|
|
|
"""
|
|
|
|
|
|
data, code = await get_info(uid, server_id)
|
|
|
|
|
|
if code != 200:
|
|
|
|
|
|
return data
|
|
|
|
|
|
if data:
|
|
|
|
|
|
char_data_list, role_data, world_data_dict, home_data_list = parsed_data(data)
|
|
|
|
|
|
mys_data = await get_mys_data(uid, mys_id)
|
|
|
|
|
|
if mys_data:
|
|
|
|
|
|
nickname = None
|
|
|
|
|
|
if char_data_list:
|
|
|
|
|
|
char_detailed_data = await get_character(
|
|
|
|
|
|
uid, [x["id"] for x in char_data_list], server_id
|
|
|
|
|
|
)
|
|
|
|
|
|
_x = {}
|
|
|
|
|
|
if char_detailed_data:
|
|
|
|
|
|
for char in char_detailed_data["avatars"]:
|
|
|
|
|
|
_x[char["name"]] = {
|
|
|
|
|
|
"weapon": char["weapon"]["name"],
|
|
|
|
|
|
"weapon_image": char["weapon"]["icon"],
|
|
|
|
|
|
"level": char["weapon"]["level"],
|
|
|
|
|
|
"affix_level": char["weapon"]["affix_level"],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-01-05 22:32:59 +08:00
|
|
|
|
await init_image(char_data_list, _x, home_data_list)
|
2021-12-16 11:16:28 +08:00
|
|
|
|
return await get_genshin_image(
|
|
|
|
|
|
user_id,
|
|
|
|
|
|
uid,
|
|
|
|
|
|
char_data_list,
|
|
|
|
|
|
role_data,
|
|
|
|
|
|
world_data_dict,
|
|
|
|
|
|
home_data_list,
|
|
|
|
|
|
_x,
|
|
|
|
|
|
mys_data,
|
|
|
|
|
|
nickname,
|
|
|
|
|
|
)
|
|
|
|
|
|
return "未找到用户数据..."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Github-@lulu666lulu https://github.com/Azure99/GenshinPlayerQuery/issues/20
|
|
|
|
|
|
"""
|
|
|
|
|
|
{body:"",query:{"action_ticket": undefined, "game_biz": "hk4e_cn”}}
|
|
|
|
|
|
对应 https://api-takumi.mihoyo.com/binding/api/getUserGameRolesByCookie?game_biz=hk4e_cn //查询米哈游账号下绑定的游戏(game_biz可留空)
|
|
|
|
|
|
{body:"",query:{"uid": 12345(被查询账号米哈游uid)}}
|
|
|
|
|
|
对应 https://api-takumi.mihoyo.com/game_record/app/card/wapi/getGameRecordCard?uid=
|
|
|
|
|
|
{body:"",query:{'role_id': '查询账号的uid(游戏里的)' ,'server': '游戏服务器'}}
|
|
|
|
|
|
对应 https://api-takumi.mihoyo.com/game_record/app/genshin/api/index?server= server信息 &role_id= 游戏uid
|
|
|
|
|
|
{body:"",query:{'role_id': '查询账号的uid(游戏里的)' , 'schedule_type': 1(我这边只看到出现过1和2), 'server': 'cn_gf01'}}
|
|
|
|
|
|
对应 https://api-takumi.mihoyo.com/game_record/app/genshin/api/spiralAbyss?schedule_type=1&server= server信息 &role_id= 游戏uid
|
|
|
|
|
|
{body:"",query:{game_id: 2(目前我知道有崩坏3是1原神是2)}}
|
|
|
|
|
|
对应 https://api-takumi.mihoyo.com/game_record/app/card/wapi/getAnnouncement?game_id= 这个是公告api
|
|
|
|
|
|
b=body q=query
|
|
|
|
|
|
其中b只在post的时候有内容,q只在get的时候有内容
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def get_info(uid_: str, server_id: str) -> "Optional[Union[dict, str]], int":
|
|
|
|
|
|
try:
|
|
|
|
|
|
req = await AsyncHttpx.get(
|
2021-12-26 22:14:01 +08:00
|
|
|
|
url=f"https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/index?server={server_id}&role_id={uid_}",
|
2021-12-16 11:16:28 +08:00
|
|
|
|
headers={
|
|
|
|
|
|
"Accept": "application/json, text/plain, */*",
|
|
|
|
|
|
"DS": get_ds(f"role_id={uid_}&server={server_id}"),
|
|
|
|
|
|
"Origin": "https://webstatic.mihoyo.com",
|
|
|
|
|
|
"x-rpc-app_version": Config.get_config("genshin", "mhyVersion"),
|
|
|
|
|
|
"User-Agent": "Mozilla/5.0 (Linux; Android 9; Unspecified Device) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36 miHoYoBBS/2.2.0",
|
|
|
|
|
|
"x-rpc-client_type": Config.get_config("genshin", "client_type"),
|
|
|
|
|
|
"Referer": "https://webstatic.mihoyo.com/app/community-game-records/index.html?v=6",
|
|
|
|
|
|
"Accept-Encoding": "gzip, deflate",
|
|
|
|
|
|
"Accept-Language": "zh-CN,en-US;q=0.8",
|
|
|
|
|
|
"X-Requested-With": "com.mihoyo.hyperion",
|
|
|
|
|
|
"Cookie": await Genshin.get_user_cookie(int(uid_))
|
|
|
|
|
|
},
|
|
|
|
|
|
)
|
|
|
|
|
|
data = req.json()
|
|
|
|
|
|
if data["message"] == "OK":
|
|
|
|
|
|
return data["data"], 200
|
|
|
|
|
|
return data["message"], 999
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.error(f"访问失败,请重试! {type(e)}: {e}")
|
|
|
|
|
|
return None, -1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def get_character(
|
|
|
|
|
|
uid: str, character_ids: List[str], server_id="cn_gf01"
|
|
|
|
|
|
) -> Optional[dict]:
|
|
|
|
|
|
try:
|
|
|
|
|
|
req = await AsyncHttpx.post(
|
|
|
|
|
|
url="https://api-takumi.mihoyo.com/game_record/app/genshin/api/character",
|
|
|
|
|
|
headers={
|
|
|
|
|
|
"Accept": "application/json, text/plain, */*",
|
|
|
|
|
|
"DS": get_ds(
|
|
|
|
|
|
"",
|
|
|
|
|
|
{
|
|
|
|
|
|
"character_ids": character_ids,
|
|
|
|
|
|
"role_id": uid,
|
|
|
|
|
|
"server": server_id,
|
|
|
|
|
|
},
|
|
|
|
|
|
),
|
|
|
|
|
|
"Origin": "https://webstatic.mihoyo.com",
|
|
|
|
|
|
"Cookie": await Genshin.get_user_cookie(int(uid)),
|
|
|
|
|
|
"x-rpc-app_version": Config.get_config("genshin", "mhyVersion"),
|
|
|
|
|
|
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1",
|
|
|
|
|
|
"x-rpc-client_type": "5",
|
|
|
|
|
|
"Referer": "https://webstatic.mihoyo.com/",
|
|
|
|
|
|
"Accept-Encoding": "gzip, deflate",
|
|
|
|
|
|
"Accept-Language": "zh-CN,en-US;q=0.8",
|
|
|
|
|
|
"X-Requested-With": "com.mihoyo.hyperion",
|
|
|
|
|
|
},
|
|
|
|
|
|
json={"character_ids": character_ids, "role_id": uid, "server": server_id},
|
|
|
|
|
|
)
|
|
|
|
|
|
data = req.json()
|
|
|
|
|
|
if data["message"] == "OK":
|
|
|
|
|
|
return data["data"]
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.error(f"访问失败,请重试! {type(e)}: {e}")
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def parsed_data(
|
|
|
|
|
|
data: dict,
|
|
|
|
|
|
) -> "Optional[List[Dict[str, str]]], Dict[str, str], Optional[List[Dict[str, str]]], Optional[List[Dict[str, str]]]":
|
|
|
|
|
|
"""
|
|
|
|
|
|
解析数据
|
|
|
|
|
|
:param data: 数据
|
|
|
|
|
|
"""
|
|
|
|
|
|
char_data_list = []
|
|
|
|
|
|
for char in data["avatars"]:
|
|
|
|
|
|
_x = {
|
|
|
|
|
|
"id": char["id"],
|
|
|
|
|
|
"image": char["image"],
|
|
|
|
|
|
"name": char["name"],
|
|
|
|
|
|
"element": element_mastery[char["element"].lower()],
|
|
|
|
|
|
"fetter": char["fetter"],
|
|
|
|
|
|
"level": char["level"],
|
|
|
|
|
|
"rarity": char["rarity"],
|
|
|
|
|
|
"actived_constellation_num": char["actived_constellation_num"],
|
|
|
|
|
|
}
|
|
|
|
|
|
char_data_list.append(_x)
|
|
|
|
|
|
role_data = {
|
|
|
|
|
|
"active_day_number": data["stats"]["active_day_number"], # 活跃天数
|
|
|
|
|
|
"achievement_number": data["stats"]["achievement_number"], # 达成成就数量
|
|
|
|
|
|
"win_rate": data["stats"]["win_rate"],
|
|
|
|
|
|
"anemoculus_number": data["stats"]["anemoculus_number"], # 风神瞳已收集
|
|
|
|
|
|
"geoculus_number": data["stats"]["geoculus_number"], # 岩神瞳已收集
|
|
|
|
|
|
"avatar_number": data["stats"]["avatar_number"], # 获得角色数量
|
|
|
|
|
|
"way_point_number": data["stats"]["way_point_number"], # 传送点已解锁
|
|
|
|
|
|
"domain_number": data["stats"]["domain_number"], # 秘境解锁数量
|
|
|
|
|
|
"spiral_abyss": data["stats"]["spiral_abyss"], # 深渊当期进度
|
|
|
|
|
|
"precious_chest_number": data["stats"]["precious_chest_number"], # 珍贵宝箱
|
|
|
|
|
|
"luxurious_chest_number": data["stats"]["luxurious_chest_number"], # 华丽宝箱
|
|
|
|
|
|
"exquisite_chest_number": data["stats"]["exquisite_chest_number"], # 精致宝箱
|
|
|
|
|
|
"magic_chest_number": data["stats"]["magic_chest_number"], # 奇馈宝箱
|
|
|
|
|
|
"common_chest_number": data["stats"]["common_chest_number"], # 普通宝箱
|
|
|
|
|
|
"electroculus_number": data["stats"]["electroculus_number"], # 雷神瞳已收集
|
|
|
|
|
|
}
|
|
|
|
|
|
world_data_dict = {}
|
|
|
|
|
|
for world in data["world_explorations"]:
|
|
|
|
|
|
_x = {
|
|
|
|
|
|
"level": world["level"], # 声望等级
|
|
|
|
|
|
"exploration_percentage": world["exploration_percentage"], # 探索进度
|
|
|
|
|
|
"image": world["icon"],
|
|
|
|
|
|
"name": world["name"],
|
|
|
|
|
|
"offerings": world["offerings"],
|
|
|
|
|
|
}
|
|
|
|
|
|
world_data_dict[world["name"]] = _x
|
|
|
|
|
|
home_data_list = []
|
|
|
|
|
|
for home in data["homes"]:
|
|
|
|
|
|
_x = {
|
|
|
|
|
|
"level": home["level"], # 最大信任等级
|
|
|
|
|
|
"visit_num": home["visit_num"], # 最高历史访客数
|
|
|
|
|
|
"comfort_num": home["comfort_num"], # 最高洞天仙力
|
|
|
|
|
|
"item_num": home["item_num"], # 已获得摆件数量
|
|
|
|
|
|
"name": home["name"],
|
|
|
|
|
|
"icon": home["icon"],
|
|
|
|
|
|
"comfort_level_name": home["comfort_level_name"],
|
|
|
|
|
|
"comfort_level_icon": home["comfort_level_icon"],
|
|
|
|
|
|
}
|
|
|
|
|
|
home_data_list.append(_x)
|
|
|
|
|
|
return char_data_list, role_data, world_data_dict, home_data_list
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def get_mys_data(uid: str, mys_id: Optional[str]) -> Optional[List[Dict]]:
|
|
|
|
|
|
"""
|
|
|
|
|
|
获取用户米游社数据
|
|
|
|
|
|
:param uid: 原神uid
|
|
|
|
|
|
:param mys_id: 米游社id
|
|
|
|
|
|
"""
|
|
|
|
|
|
if mys_id:
|
|
|
|
|
|
try:
|
|
|
|
|
|
req = await AsyncHttpx.get(
|
|
|
|
|
|
url=f"https://api-takumi.mihoyo.com/game_record/card/wapi/getGameRecordCard?uid={mys_id}",
|
|
|
|
|
|
headers={
|
|
|
|
|
|
"DS": get_ds(f"uid={mys_id}"),
|
|
|
|
|
|
"x-rpc-app_version": Config.get_config("genshin", "mhyVersion"),
|
|
|
|
|
|
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1",
|
|
|
|
|
|
"x-rpc-client_type": "5",
|
|
|
|
|
|
"Referer": "https://webstatic.mihoyo.com/",
|
|
|
|
|
|
"Cookie": await Genshin.get_user_cookie(int(uid))
|
|
|
|
|
|
},
|
|
|
|
|
|
)
|
|
|
|
|
|
data = req.json()
|
|
|
|
|
|
if data["message"] == "OK":
|
|
|
|
|
|
return data["data"]["list"]
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.error(f"访问失败,请重试! {type(e)}: {e}")
|
|
|
|
|
|
return None
|