import type { GamesData, XCXFindUserResp, XCXMember, XCXProfile, XCXTag } from "../types"; import { KAIQIU_BASE_URL } from "../utils/common"; import { redis } from "../utils/server"; const XCX_BASE_URL = `${KAIQIU_BASE_URL}/xcx/public/index.php`; export function createXCXHeader(token: string) { const xcxDefaultHeaders = { 'token': token, 'XX-Device-Type': 'wxapp', 'content-type': 'application/json', 'Accept-Encoding': 'gzip,compress,br,deflate', 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.68(0x1800442a) NetType/WIFI Language/zh_CN', 'Referer': 'https://servicewechat.com/wxff09fb0e92aa456a/464/page-frame.html', }; return xcxDefaultHeaders; } export class XCXAPI { #defaultHeader: any; constructor(token: string) { this.#defaultHeader = createXCXHeader(token); console.log(`XCXAPI init: ${token}`); } async #fetch(pathAndQuery: string, init?: RequestInit): Promise { const resp = await fetch(`${XCX_BASE_URL}${pathAndQuery}`, { headers: this.#defaultHeader, ...init, }); const response = await resp.json() as { code: number; data: unknown, msg: string; time: string; }; if (response.code !== 1) return null; return response.data as T; } async getAdvProfile(uid: string) { const cacheProfile = await redis.get(`my-kaiqiuwang:profile:${uid}`); if (!cacheProfile) { const url = `/api/User/adv_profile?uid=${uid}`; const profile = await this.#fetch(url); await redis.setex(`my-kaiqiuwang:profile:${uid}`, 60 * 10, JSON.stringify(profile)); return profile; } return JSON.parse(cacheProfile); } async getPlayerTags(uid: string) { const url = `/api/User/get_tags?uid=${uid}&limitByCount=50&getNegative=true`; return ((await this.#fetch(url)) ?? []).filter(e => Number(e.count) > 0); } async getMemberDetail(matchId: string, itemId: string) { const url = `/api/enter/get_member_detail?id=${itemId}&match_id=${matchId}`; return (await this.#fetch<{ list: XCXMember[] }>(url))?.list; } async getGameList(uid: string, page: number = 1) { const url = `/api/User/getGames?uid=${uid}&page=${page}&size=50`; return (await this.#fetch<{ data: GamesData[] }>(url))?.data; } async findUser(key: string = '', page: number = 1) { if (!key) return null; const url = `/api/user/lists?page=${page}&key=${key}`; return (await this.#fetch(url)); } }