zhenxun_bot/plugins/genshin/query_user/query_role/data_source.py
2022-01-05 22:32:59 +08:00

250 lines
10 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.

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"],
}
await init_image(char_data_list, _x, home_data_list)
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(
url=f"https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/index?server={server_id}&role_id={uid_}",
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