diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..b4da427 --- /dev/null +++ b/.env.example @@ -0,0 +1 @@ +KAIQIUCC_TOKEN='' \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index c82ff89..494323d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,7 @@ services: kaiqiu-game-info: build: . + env_file: + - .env ports: - 3005:3000 \ No newline at end of file diff --git a/package.json b/package.json index 632706e..c7c3b14 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "private": true, "type": "module", "scripts": { - "dev": "bun --hot src/index.tsx", + "dev": "bun --hot src/index.ts", "build": "bun build ./src/index.html --outdir=dist --sourcemap --target=browser --minify --define:process.env.NODE_ENV='\"production\"' --env='BUN_PUBLIC_*'", "start": "NODE_ENV=production bun src/index.tsx" }, diff --git a/src/config.example.ts b/src/config.example.ts deleted file mode 100644 index 1b4cc98..0000000 --- a/src/config.example.ts +++ /dev/null @@ -1,5 +0,0 @@ -import type { Config } from "./types"; - -export const config: Config = { - KAIQIUCC_TOKEN: '', -}; diff --git a/src/index.tsx b/src/index.ts similarity index 77% rename from src/index.tsx rename to src/index.ts index 824da7b..9ec0026 100644 --- a/src/index.tsx +++ b/src/index.ts @@ -1,13 +1,15 @@ import { serve } from "bun"; +import { getMatchInfo, listEvent } from "./utils"; import index from "./index.html"; -import { getAdvProfile, getMatchInfo, getMemberDetail, getPlayerTags, listEvent } from "./utils"; -import { config } from "./config"; +import { XCXAPI } from "./services/xcxApi"; -if (!config.KAIQIUCC_TOKEN) { +if (!process.env.KAIQIUCC_TOKEN) { console.error('env KAIQIUCC_TOKEN not found'); process.exit(1); } +const xcxApi = new XCXAPI(process.env.KAIQIUCC_TOKEN ?? ''); + const server = serve({ port: process.env.PORT || 3000, routes: { @@ -28,21 +30,21 @@ const server = serve({ "/api/match/:matchId/:itemId": { async GET(req) { const { matchId, itemId } = req.params; - const data = await getMemberDetail(matchId, itemId); + const data = await xcxApi.getMemberDetail(matchId, itemId); return Response.json(data); } }, "/api/user/:uid": { async GET(req) { const uid = req.params.uid; - const profile = await getAdvProfile(uid); + const profile = await xcxApi.getAdvProfile(uid); return Response.json(profile); }, }, "/api/user/:uid/tags": { async GET(req) { const uid = req.params.uid; - const profile = await getPlayerTags(uid); + const profile = await xcxApi.getPlayerTags(uid); return Response.json(profile); }, } diff --git a/src/services/xcxApi.ts b/src/services/xcxApi.ts new file mode 100644 index 0000000..893ddfc --- /dev/null +++ b/src/services/xcxApi.ts @@ -0,0 +1,60 @@ +import type { XCXMember, XCXProfile, XCXTag } from "../types"; +import { BASE_URL } from "../utils"; + +const XCX_BASE_URL = `${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); + } + + async getAdvProfile(uid: string) { + // return JSON.parse(fs.readFileSync( + // path.resolve(__dirname, '..', '__test__', 'data', 'profile.json'), + // ).toString()).data; + if (!/^\d+$/.test(uid)) return null; + if (!uid) return null; + const resp = await fetch(`${XCX_BASE_URL}/api/User/adv_profile?uid=${uid}`, { + headers: this.#defaultHeader, + }); + const data = await resp.json(); + if (data.code !== 1) return null; + return data.data as XCXProfile; + } + + async getPlayerTags(uid: string) { + // return JSON.parse(fs.readFileSync( + // path.resolve(__dirname, '..', '__test__', 'data', 'profile.json'), + // ).toString()).data; + if (!/^\d+$/.test(uid)) return null; + if (!uid) return null; + const resp = await fetch(`${XCX_BASE_URL}/api/User/get_tags?uid=${uid}&limitByCount=50&getNegative=true`, { + headers: this.#defaultHeader, + }); + const data = await resp.json(); + if (data.code !== 1) return null; + return (data.data as XCXTag[]).filter(e => Number(e.count) > 0); + } + + async getMemberDetail(matchId: string, itemId: string) { + const resp = await fetch(`${XCX_BASE_URL}/api/enter/get_member_detail?id=${itemId}&match_id=${matchId}`, { + headers: this.#defaultHeader, + }); + const data = await resp.json(); + if (data.code !== 1) return null; + return (data.data.list as XCXMember[]); + } +} \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts index 2d61e5e..bfa5f7a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -5,10 +5,8 @@ import path from 'path'; import { chunk } from 'lodash'; import type { XCXProfile } from "./types/profile"; import type { XCXTag } from "./types/tag"; -import { config } from './config'; -const BASE_URL = `https://kaiqiuwang.cc`; -const XCX_BASE_URL = `${BASE_URL}/xcx/public/index.php`; +export const BASE_URL = `https://kaiqiuwang.cc`; /** * @@ -19,15 +17,6 @@ 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 */ -const xcxDefaultHeaders = { - 'token': config.KAIQIUCC_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', -}; - /** * @param tagid 俱乐部 ID */ @@ -133,41 +122,4 @@ export function sneckGroup(size: number, groupLen: number) { newGroups.push(group); } return newGroups; -} - -export async function getAdvProfile(uid: string) { - // return JSON.parse(fs.readFileSync( - // path.resolve(__dirname, '..', '__test__', 'data', 'profile.json'), - // ).toString()).data; - if (!/^\d+$/.test(uid)) return null; - if (!uid) return null; - const resp = await fetch(`${XCX_BASE_URL}/api/User/adv_profile?uid=${uid}`, { - headers: xcxDefaultHeaders, - }); - const data = await resp.json(); - if (data.code !== 1) return null; - return data.data as XCXProfile; -} - -export async function getPlayerTags(uid: string) { - // return JSON.parse(fs.readFileSync( - // path.resolve(__dirname, '..', '__test__', 'data', 'profile.json'), - // ).toString()).data; - if (!/^\d+$/.test(uid)) return null; - if (!uid) return null; - const resp = await fetch(`${XCX_BASE_URL}/api/User/get_tags?uid=${uid}&limitByCount=50&getNegative=true`, { - headers: xcxDefaultHeaders, - }); - const data = await resp.json(); - if (data.code !== 1) return null; - return (data.data as XCXTag[]).filter(e => Number(e.count) > 0); -} - -export async function getMemberDetail(matchId: string, itemId: string) { - const resp = await fetch(`${XCX_BASE_URL}/api/enter/get_member_detail?id=${itemId}&match_id=${matchId}`, { - headers: xcxDefaultHeaders, - }); - const data = await resp.json(); - if (data.code !== 1) return null; - return (data.data.list as XCXMember[]); } \ No newline at end of file