mirror of
https://github.com/samuelthomas2774/nxapi.git
synced 2026-03-21 18:04:10 -05:00
Add a command to download all battle results from SplatNet 3
This commit is contained in:
parent
0821235a89
commit
203a54be44
|
|
@ -655,6 +655,20 @@ interface HomeBanner {
|
|||
jumpTo: string;
|
||||
}
|
||||
|
||||
/** 994cf141e55213e6923426caf37a1934 VsHistoryDetailPagerRefetchQuery */
|
||||
export interface VsHistoryDetailPagerRefetchQueryResult {
|
||||
vsHistoryDetail: {
|
||||
__typename: 'VsHistoryDetail';
|
||||
nextHistoryDetail: {
|
||||
id: string;
|
||||
} | null;
|
||||
previousHistoryDetail: {
|
||||
id: string;
|
||||
} | null;
|
||||
id: string;
|
||||
};
|
||||
}
|
||||
|
||||
/** cd82f2ade8aca7687947c5f3210805a6 VsHistoryDetailQuery */
|
||||
export interface VsHistoryDetailResult {
|
||||
vsHistoryDetail: VsHistoryDetail;
|
||||
|
|
|
|||
|
|
@ -110,16 +110,30 @@ export default class SplatNet3Api {
|
|||
return this.persistedQuery<RegularBattleHistoriesResult>(RequestId.RegularBattleHistoriesQuery, {});
|
||||
}
|
||||
|
||||
async getBankaraBattleHistories() {
|
||||
return this.persistedQuery<BankaraBattleHistoriesResult>(RequestId.BankaraBattleHistoriesQuery, {});
|
||||
}
|
||||
|
||||
async getPrivateBattleHistories() {
|
||||
return this.persistedQuery<PrivateBattleHistoriesResult>(RequestId.PrivateBattleHistoriesQuery, {});
|
||||
}
|
||||
|
||||
async getVsHistoryDetail(id: string) {
|
||||
async getBattleHistoryDetail(id: string) {
|
||||
return this.persistedQuery<VsHistoryDetailResult>(RequestId.VsHistoryDetailQuery, {
|
||||
vsResultId: id,
|
||||
});
|
||||
}
|
||||
|
||||
async getBattleHistoryDetailPagerRefetch(id: string) {
|
||||
return this.persistedQuery<VsHistoryDetailResult>(RequestId.VsHistoryDetailPagerRefetchQuery, {
|
||||
vsResultId: id,
|
||||
});
|
||||
}
|
||||
|
||||
async getCoopHistory() {
|
||||
return this.persistedQuery<unknown>(RequestId.CoopHistoryQuery, {});
|
||||
}
|
||||
|
||||
static async createWithCoral(nso: CoralApi, user: NintendoAccountUser) {
|
||||
const data = await this.loginWithCoral(nso, user);
|
||||
return {splatnet: this.createWithSavedToken(data), data};
|
||||
|
|
|
|||
99
src/cli/splatnet3/dump-results.ts
Normal file
99
src/cli/splatnet3/dump-results.ts
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
import * as path from 'node:path';
|
||||
import * as fs from 'node:fs/promises';
|
||||
import createDebug from 'debug';
|
||||
import mkdirp from 'mkdirp';
|
||||
import type { Arguments as ParentArguments } from '../splatnet3.js';
|
||||
import { ArgumentsCamelCase, Argv, YargsArguments } from '../../util/yargs.js';
|
||||
import { initStorage } from '../../util/storage.js';
|
||||
import { getBulletToken } from '../../common/auth/splatnet3.js';
|
||||
import SplatNet3Api from '../../api/splatnet3.js';
|
||||
|
||||
const debug = createDebug('cli:splatnet3:dump-results');
|
||||
|
||||
export const command = 'dump-results [directory]';
|
||||
export const desc = 'Download all battle and coop results';
|
||||
|
||||
export function builder(yargs: Argv<ParentArguments>) {
|
||||
return yargs.positional('directory', {
|
||||
describe: 'Directory to write record data to',
|
||||
type: 'string',
|
||||
}).option('user', {
|
||||
describe: 'Nintendo Account ID',
|
||||
type: 'string',
|
||||
}).option('token', {
|
||||
describe: 'Nintendo Account session token',
|
||||
type: 'string',
|
||||
}).option('battles', {
|
||||
describe: 'Include regular/ranked/private/festival battle results',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
}).option('coop', {
|
||||
describe: 'Include coop (Salmon Run) results',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
});
|
||||
}
|
||||
|
||||
type Arguments = YargsArguments<ReturnType<typeof builder>>;
|
||||
|
||||
export async function handler(argv: ArgumentsCamelCase<Arguments>) {
|
||||
const storage = await initStorage(argv.dataPath);
|
||||
|
||||
const usernsid = argv.user ?? await storage.getItem('SelectedUser');
|
||||
const token: string = argv.token ||
|
||||
await storage.getItem('NintendoAccountToken.' + usernsid);
|
||||
const {splatnet} = await getBulletToken(storage, token, argv.zncProxyUrl, argv.autoUpdateSession);
|
||||
|
||||
const directory = argv.directory ?? path.join(argv.dataPath, 'splatnet3');
|
||||
|
||||
await mkdirp(directory);
|
||||
|
||||
if (argv.battles) {
|
||||
await dumpResults(splatnet, directory);
|
||||
}
|
||||
// if (argv.coop) {
|
||||
// await dumpCoopResults(splatnet, directory);
|
||||
// }
|
||||
}
|
||||
|
||||
export async function dumpResults(
|
||||
splatnet: SplatNet3Api, directory: string
|
||||
) {
|
||||
debug('Fetching battle results');
|
||||
const player = await splatnet.getBattleHistoryCurrentPlayer();
|
||||
const battles = await splatnet.getLatestBattleHistories();
|
||||
const battles_regular = await splatnet.getRegularBattleHistories();
|
||||
const battles_anarchy = await splatnet.getBankaraBattleHistories();
|
||||
const battles_private = await splatnet.getPrivateBattleHistories();
|
||||
|
||||
const skipped = [];
|
||||
|
||||
// Reverse battle history order so oldest records are downloaded first
|
||||
for (const group of battles.data.latestBattleHistories.historyGroups.nodes.reverse()) {
|
||||
for (const item of group.historyDetails.nodes.reverse()) {
|
||||
const id_str = Buffer.from(item.id, 'base64').toString() || item.id;
|
||||
|
||||
const filename = 'splatnet3-result-' + id_str + '.json';
|
||||
const file = path.join(directory, filename);
|
||||
|
||||
try {
|
||||
await fs.stat(file);
|
||||
skipped.push(item.id);
|
||||
} catch (err) {
|
||||
debug('Fetching battle result %s', id_str);
|
||||
const result = await splatnet.getBattleHistoryDetail(item.id);
|
||||
const pager = await splatnet.getBattleHistoryDetailPagerRefetch(item.id);
|
||||
|
||||
debug('Writing %s', filename);
|
||||
await fs.writeFile(file, JSON.stringify({
|
||||
result: result.data.vsHistoryDetail,
|
||||
}, null, 4) + '\n', 'utf-8');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (skipped.length) {
|
||||
if (skipped.length === 1) debug('Skipped battle result %s, file already exists', skipped[0]);
|
||||
else debug('Skipped %d battle results, files already exist', skipped.length);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,3 +2,4 @@ export * as user from './user.js';
|
|||
export * as token from './token.js';
|
||||
export * as schedule from './schedule.js';
|
||||
export * as battles from './battles.js';
|
||||
export * as dumpResults from './dump-results.js';
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user