refactor(global): token in env

This commit is contained in:
kyuuseiryuu 2026-01-29 17:37:33 +09:00
parent bedd6ccb1b
commit 979e0abf59
7 changed files with 73 additions and 61 deletions

1
.env.example Normal file
View File

@ -0,0 +1 @@
KAIQIUCC_TOKEN=''

View File

@ -1,5 +1,7 @@
services: services:
kaiqiu-game-info: kaiqiu-game-info:
build: . build: .
env_file:
- .env
ports: ports:
- 3005:3000 - 3005:3000

View File

@ -4,7 +4,7 @@
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "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_*'", "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" "start": "NODE_ENV=production bun src/index.tsx"
}, },

View File

@ -1,5 +0,0 @@
import type { Config } from "./types";
export const config: Config = {
KAIQIUCC_TOKEN: '',
};

View File

@ -1,13 +1,15 @@
import { serve } from "bun"; import { serve } from "bun";
import { getMatchInfo, listEvent } from "./utils";
import index from "./index.html"; import index from "./index.html";
import { getAdvProfile, getMatchInfo, getMemberDetail, getPlayerTags, listEvent } from "./utils"; import { XCXAPI } from "./services/xcxApi";
import { config } from "./config";
if (!config.KAIQIUCC_TOKEN) { if (!process.env.KAIQIUCC_TOKEN) {
console.error('env KAIQIUCC_TOKEN not found'); console.error('env KAIQIUCC_TOKEN not found');
process.exit(1); process.exit(1);
} }
const xcxApi = new XCXAPI(process.env.KAIQIUCC_TOKEN ?? '');
const server = serve({ const server = serve({
port: process.env.PORT || 3000, port: process.env.PORT || 3000,
routes: { routes: {
@ -28,21 +30,21 @@ const server = serve({
"/api/match/:matchId/:itemId": { "/api/match/:matchId/:itemId": {
async GET(req) { async GET(req) {
const { matchId, itemId } = req.params; const { matchId, itemId } = req.params;
const data = await getMemberDetail(matchId, itemId); const data = await xcxApi.getMemberDetail(matchId, itemId);
return Response.json(data); return Response.json(data);
} }
}, },
"/api/user/:uid": { "/api/user/:uid": {
async GET(req) { async GET(req) {
const uid = req.params.uid; const uid = req.params.uid;
const profile = await getAdvProfile(uid); const profile = await xcxApi.getAdvProfile(uid);
return Response.json(profile); return Response.json(profile);
}, },
}, },
"/api/user/:uid/tags": { "/api/user/:uid/tags": {
async GET(req) { async GET(req) {
const uid = req.params.uid; const uid = req.params.uid;
const profile = await getPlayerTags(uid); const profile = await xcxApi.getPlayerTags(uid);
return Response.json(profile); return Response.json(profile);
}, },
} }

60
src/services/xcxApi.ts Normal file
View File

@ -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[]);
}
}

View File

@ -5,10 +5,8 @@ import path from 'path';
import { chunk } from 'lodash'; import { chunk } from 'lodash';
import type { XCXProfile } from "./types/profile"; import type { XCXProfile } from "./types/profile";
import type { XCXTag } from "./types/tag"; import type { XCXTag } from "./types/tag";
import { config } from './config';
const BASE_URL = `https://kaiqiuwang.cc`; export const BASE_URL = `https://kaiqiuwang.cc`;
const XCX_BASE_URL = `${BASE_URL}/xcx/public/index.php`;
/** /**
* *
@ -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 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 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 * @param tagid ID
*/ */
@ -133,41 +122,4 @@ export function sneckGroup(size: number, groupLen: number) {
newGroups.push(group); newGroups.push(group);
} }
return newGroups; 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[]);
} }