feat: getBattleList

main
spacemeowx2 2022-10-19 19:46:03 +08:00
parent 5113a0db04
commit 15c0e20966
4 changed files with 96 additions and 74 deletions

View File

@ -7,3 +7,4 @@ export * as base64 from "https://deno.land/std@0.160.0/encoding/base64.ts";
export * as flags from "https://deno.land/std@0.160.0/flags/mod.ts"; export * as flags from "https://deno.land/std@0.160.0/flags/mod.ts";
export * as io from "https://deno.land/std@0.160.0/io/mod.ts"; export * as io from "https://deno.land/std@0.160.0/io/mod.ts";
export * as uuid from "https://deno.land/std@0.160.0/uuid/mod.ts"; export * as uuid from "https://deno.land/std@0.160.0/uuid/mod.ts";
export * as msgpack from "https://deno.land/x/msgpack@v1.4/mod.ts";

11
s3si.ts
View File

@ -2,7 +2,7 @@ import { getBulletToken, getGToken, loginManually } from "./iksm.ts";
import { APIError } from "./APIError.ts"; import { APIError } from "./APIError.ts";
import { flags } from "./deps.ts"; import { flags } from "./deps.ts";
import { DEFAULT_STATE, State } from "./state.ts"; import { DEFAULT_STATE, State } from "./state.ts";
import { checkToken } from "./splatnet3.ts"; import { checkToken, getBattleList } from "./splatnet3.ts";
type Opts = { type Opts = {
configPath: string; configPath: string;
@ -65,9 +65,9 @@ Options:
} }
const sessionToken = this.state.loginState.sessionToken!; const sessionToken = this.state.loginState.sessionToken!;
if ( if (!await checkToken(this.state)) {
!this.state.loginState?.gToken || !this.state.loginState.bulletToken console.log("Token expired, refetch tokens.");
) {
const { webServiceToken, userCountry, userLang } = await getGToken({ const { webServiceToken, userCountry, userLang } = await getGToken({
fApi: this.state.fGen, fApi: this.state.fGen,
sessionToken, sessionToken,
@ -94,7 +94,8 @@ Options:
await this.writeState(); await this.writeState();
} }
await checkToken(this.state); const battleList = await getBattleList(this.state);
console.log(battleList);
} catch (e) { } catch (e) {
if (e instanceof APIError) { if (e instanceof APIError) {
console.error(`APIError: ${e.message}`, e.response, e.json); console.error(`APIError: ${e.message}`, e.response, e.json);

View File

@ -5,6 +5,7 @@ import { APIError } from "./APIError.ts";
import { import {
BattleType, BattleType,
GraphQLResponse, GraphQLResponse,
HistoryGroups,
Queries, Queries,
RespMap, RespMap,
VarsMap, VarsMap,
@ -13,8 +14,9 @@ import {
async function request<Q extends Queries>( async function request<Q extends Queries>(
state: State, state: State,
query: Q, query: Q,
variables: VarsMap[Q], ...rest: VarsMap[Q]
): Promise<RespMap[Q]> { ): Promise<RespMap[Q]> {
const variables = rest?.[0] ?? {};
const body = { const body = {
extensions: { extensions: {
persistedQuery: { persistedQuery: {
@ -68,10 +70,60 @@ export async function checkToken(state: State) {
return false; return false;
} }
await request(state, Queries.HomeQuery, {}); try {
await request(state, Queries.HomeQuery);
return true; return true;
} catch (_e) {
return false;
}
} }
export async function getBattleList(params: BattleType) { function getIdsFromGroups({ historyGroups }: { historyGroups: HistoryGroups }) {
return historyGroups.nodes.flatMap((i) => i.historyDetails.nodes).map((i) =>
i.id
);
}
const BATTLE_LIST_TYPE_MAP: Record<
BattleType,
(state: State) => Promise<string[]>
> = {
[BattleType.Regular]: (state: State) =>
request(state, Queries.RegularBattleHistoriesQuery)
.then((r) => getIdsFromGroups(r.regularBattleHistories)),
[BattleType.Bankara]: (state: State) =>
request(state, Queries.BankaraBattleHistoriesQuery)
.then((r) => getIdsFromGroups(r.bankaraBattleHistories)),
[BattleType.Private]: (state: State) =>
request(state, Queries.PrivateBattleHistoriesQuery)
.then((r) => getIdsFromGroups(r.privateBattleHistories)),
};
export async function getBattleList(
state: State,
types: BattleType[] = [
BattleType.Regular,
BattleType.Bankara,
BattleType.Private,
],
) {
const out = [];
for (const battleType of types) {
const ids = await BATTLE_LIST_TYPE_MAP[battleType](state);
out.push(...ids);
}
return out;
}
export function getBattleDetail(
state: State,
id: string,
) {
return request(
state,
Queries.VsHistoryDetailQuery,
{
vsResultId: id,
},
);
} }

View File

@ -9,18 +9,18 @@ export enum Queries {
CoopHistoryDetailQuery = "f3799a033f0a7ad4b1b396f9a3bafb1e", CoopHistoryDetailQuery = "f3799a033f0a7ad4b1b396f9a3bafb1e",
} }
export type VarsMap = { export type VarsMap = {
[Queries.HomeQuery]: Record<never, never>; [Queries.HomeQuery]: [];
[Queries.LatestBattleHistoriesQuery]: Record<never, never>; [Queries.LatestBattleHistoriesQuery]: [];
[Queries.RegularBattleHistoriesQuery]: Record<never, never>; [Queries.RegularBattleHistoriesQuery]: [];
[Queries.BankaraBattleHistoriesQuery]: Record<never, never>; [Queries.BankaraBattleHistoriesQuery]: [];
[Queries.PrivateBattleHistoriesQuery]: Record<never, never>; [Queries.PrivateBattleHistoriesQuery]: [];
[Queries.VsHistoryDetailQuery]: { [Queries.VsHistoryDetailQuery]: [{
vsResultId: string; vsResultId: string;
}; }];
[Queries.CoopHistoryQuery]: Record<never, never>; [Queries.CoopHistoryQuery]: [];
[Queries.CoopHistoryDetailQuery]: { [Queries.CoopHistoryDetailQuery]: [{
coopHistoryDetailId: string; coopHistoryDetailId: string;
}; }];
}; };
export type Image = { export type Image = {
@ -28,6 +28,15 @@ export type Image = {
width?: number; width?: number;
height?: number; height?: number;
}; };
export type HistoryGroups = {
nodes: {
historyDetails: {
nodes: {
id: string;
}[];
};
}[];
};
export type RespMap = { export type RespMap = {
[Queries.HomeQuery]: { [Queries.HomeQuery]: {
currentPlayer: { currentPlayer: {
@ -48,56 +57,21 @@ export type RespMap = {
footerMessages: unknown[]; footerMessages: unknown[];
}; };
[Queries.LatestBattleHistoriesQuery]: Record<never, never>; [Queries.LatestBattleHistoriesQuery]: Record<never, never>;
[Queries.RegularBattleHistoriesQuery]: Record<never, never>; [Queries.RegularBattleHistoriesQuery]: {
[Queries.BankaraBattleHistoriesQuery]: { regularBattleHistories: {
bankaraBattleHistories: { historyGroups: HistoryGroups;
summary: { };
assistAverage: number; };
deathAverage: number; [Queries.BankaraBattleHistoriesQuery]: {
killAverage: number; bankaraBattleHistories: {
lose: number; historyGroups: HistoryGroups;
perUnitTimeMinute: number; };
specialAverage: number; };
win: number; [Queries.PrivateBattleHistoriesQuery]: {
}; privateBattleHistories: {
historyGroups: { historyGroups: HistoryGroups;
nodes: {
bankaraMatchChallenge: null | {
winCount: number;
loseCount: number;
maxWinCount: number;
maxLoseCount: number;
state: "Failed";
isPromo: boolean;
isUdemaeUp: boolean;
udemaeAfter: string;
earnedUdemaePoint: number;
};
historyDetails: {
nodes: {
id: string;
vsMode: {
mode: "BANKARA";
id: string;
};
vsRule: {
name: string;
id: string;
};
vsStage: {
name: string;
id: string;
image: Image;
};
judgement: "LOSE";
player: unknown;
}[];
};
}[];
};
}; };
}; };
[Queries.PrivateBattleHistoriesQuery]: Record<never, never>;
[Queries.VsHistoryDetailQuery]: Record<never, never>; [Queries.VsHistoryDetailQuery]: Record<never, never>;
[Queries.CoopHistoryQuery]: Record<never, never>; [Queries.CoopHistoryQuery]: Record<never, never>;
[Queries.CoopHistoryDetailQuery]: Record<never, never>; [Queries.CoopHistoryDetailQuery]: Record<never, never>;
@ -115,9 +89,3 @@ export enum BattleType {
Bankara, Bankara,
Private, Private,
} }
export const BATTLE_QUERY_MAP: Record<BattleType, Queries> = {
[BattleType.Regular]: Queries.RegularBattleHistoriesQuery,
[BattleType.Bankara]: Queries.BankaraBattleHistoriesQuery,
[BattleType.Private]: Queries.PrivateBattleHistoriesQuery,
};