diff --git a/CHANGELOG.md b/CHANGELOG.md index 13844bd..1785605 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.1.35 + +feat: update Queries and `WEB_VIEW_VERSION` to match the latest version of the +NSO. + +feat: disable Salmon Run export for now. +([#42](https://github.com/spacemeowx2/s3si.ts/issues/42)) + ## 0.1.34 feat: add `--with-summary` to export summary data to file diff --git a/scripts/find-coop-map.ts b/scripts/find-coop-map.ts index 0f13d83..e9335bd 100644 --- a/scripts/find-coop-map.ts +++ b/scripts/find-coop-map.ts @@ -15,7 +15,6 @@ for (const dir of dirs) { const events = new Map(); const uniforms = new Map(); -const specials = new Map(); const bosses = new Map(); for (const file of files) { @@ -41,14 +40,6 @@ for (const file of files) { uniforms.set(b64Number(id), name); } - for ( - const { id, name } of data.detail.waveResults.flatMap((i) => - i.specialWeapons - ) - ) { - specials.set(b64Number(id), name); - } - for (const { id, name } of data.detail.enemyResults.map((i) => i.enemy)) { bosses.set(b64Number(id), name); } @@ -60,5 +51,4 @@ for (const file of files) { console.log([...events.entries()].sort((a, b) => a[0] - b[0])); console.log([...uniforms.entries()].sort((a, b) => a[0] - b[0])); -console.log([...specials.entries()].sort((a, b) => a[0] - b[0])); console.log([...bosses.entries()].sort((a, b) => a[0] - b[0])); diff --git a/scripts/update-constant.ts b/scripts/update-constant.ts index b9c5419..ec2ea24 100644 --- a/scripts/update-constant.ts +++ b/scripts/update-constant.ts @@ -51,8 +51,10 @@ async function getWebViewVer(): Promise { const mainJSBody = await (await fetch(SPLATNET3_URL + mainJS)).text(); const revision = /"([0-9a-f]{40})"/.exec(mainJSBody)?.[1]; - const version = /revision_info_not_set.*?="(\d+\.\d+\.\d+)/.exec(mainJSBody) - ?.[1]; + const version = /revision_info_not_set.*?=("|`)(\d+\.\d+\.\d+)-/.exec( + mainJSBody, + ) + ?.[2]; if (!version || !revision) { throw new Error("No version and revision found"); diff --git a/src/constant.ts b/src/constant.ts index f62c364..19be658 100644 --- a/src/constant.ts +++ b/src/constant.ts @@ -1,9 +1,9 @@ import type { StatInkPostBody, VsHistoryDetail } from "./types.ts"; export const AGENT_NAME = "s3si.ts"; -export const S3SI_VERSION = "0.1.34"; +export const S3SI_VERSION = "0.1.35"; export const NSOAPP_VERSION = "2.3.1"; -export const WEB_VIEW_VERSION = "1.0.0-433ec0e8"; +export const WEB_VIEW_VERSION = "2.0.0-8a061f6c"; export const S3SI_LINK = "https://github.com/spacemeowx2/s3si.ts"; export const USERAGENT = `${AGENT_NAME}/${S3SI_VERSION} (${S3SI_LINK})`; @@ -37,7 +37,6 @@ export const SPLATNET3_STATINK_MAP: { | "white" | undefined >; - COOP_SPECIAL_MAP: Record; WATER_LEVEL_MAP: Record<0 | 1 | 2, "low" | "normal" | "high">; } = { RULE: { @@ -81,15 +80,6 @@ export const SPLATNET3_STATINK_MAP: { 6: "black", 7: "white", }, - COOP_SPECIAL_MAP: { - 20006: "nicedama", - 20007: "hopsonar", - 20009: "megaphone51", - 20010: "jetpack", - 20012: "kanitank", - 20013: "sameride", - 20014: "tripletornado", - }, WATER_LEVEL_MAP: { 0: "low", 1: "normal", diff --git a/src/exporters/stat.ink.ts b/src/exporters/stat.ink.ts index 9a0c1c4..4867e5b 100644 --- a/src/exporters/stat.ink.ts +++ b/src/exporters/stat.ink.ts @@ -22,6 +22,7 @@ import { StatInkPlayer, StatInkPostBody, StatInkPostResponse, + StatInkSpecialWeapon, StatInkStage, StatInkUuidList, StatInkWeapon, @@ -182,6 +183,29 @@ class StatInkAPI { } } + _specialMap = new Map(); + async getSpecialMap() { + if (this._specialMap.size === 0) { + const specials = await this.getSpecial(); + for (const special of specials) { + for ( + const name of Object.values(special.name).flatMap((n) => + this._getAliasName(n) + ) + ) { + const prevKey = this._specialMap.get(name); + if (prevKey !== undefined && prevKey !== special.key) { + console.warn(`Duplicate weapon name: ${name}`); + } + this._specialMap.set(name, special.key); + } + } + if (this._specialMap.size === 0) { + throw new Error("Failed to get salmon weapon map"); + } + } + return this._specialMap; + } _salmonWeaponMap = new Map(); async getSalmonWeaponMap() { if (this._salmonWeaponMap.size === 0) { @@ -205,6 +229,10 @@ class StatInkAPI { } return this._salmonWeaponMap; } + getSpecial = (): Promise => { + // TODO: fix this after stat.ink supports special API + throw new Error("Not implemented"); + }; getSalmonWeapon = () => this._getCached( `${this.statInk}/api/v3/salmon/weapon?full=1`, @@ -262,13 +290,18 @@ export class StatInkExporter implements GameExporter { url, }; } else { - const body = await this.mapCoop(game); - const { url } = await this.api.postCoop(body); - return { - status: "success", - url, + status: "skip", + reason: + "Can not export Salmon Run for now. See https://github.com/spacemeowx2/s3si.ts/issues/42", }; + // const body = await this.mapCoop(game); + // const { url } = await this.api.postCoop(body); + + // return { + // status: "success", + // url, + // }; } } async notExported( @@ -559,6 +592,16 @@ export class StatInkExporter implements GameExporter { return weapon; } + async mapSpecial(name: string): Promise { + const specialMap = await this.api.getSpecialMap(); + const special = specialMap.get(name); + + if (!special) { + throw new Error(`Special not found: ${name}`); + } + + return special; + } async mapCoopPlayer({ player, weapons, @@ -578,7 +621,7 @@ export class StatInkExporter implements GameExporter { uniform: SPLATNET3_STATINK_MAP.COOP_UNIFORM_MAP[b64Number(player.uniform.id)], special: specialWeapon - ? SPLATNET3_STATINK_MAP.COOP_SPECIAL_MAP[b64Number(specialWeapon.id)] + ? await this.mapSpecial(specialWeapon.name) : undefined, weapons: await Promise.all(weapons.map((w) => this.mapCoopWeapon(w))), golden_eggs: goldenDeliverCount, @@ -598,18 +641,18 @@ export class StatInkExporter implements GameExporter { return nid; } - mapWave(wave: CoopHistoryDetail["waveResults"]["0"]): StatInkCoopWave { + async mapWave( + wave: CoopHistoryDetail["waveResults"]["0"], + ): Promise { const event = wave.eventWave ? SPLATNET3_STATINK_MAP.COOP_EVENT_MAP[b64Number(wave.eventWave.id)] : undefined; - const special_uses = wave.specialWeapons.reduce((p, { id }) => { - const key = SPLATNET3_STATINK_MAP.COOP_SPECIAL_MAP[b64Number(id)]; - - return { - ...p, - [key]: (p[key] ?? 0) + 1, - }; - }, {} as Record) as Record; + const special_uses = (await Promise.all( + wave.specialWeapons.map((w) => this.mapSpecial(w.name)), + )).reduce((p, key) => ({ + ...p, + [key]: (p[key] ?? 0) + 1, + }), {} as Record) as Record; return { tide: SPLATNET3_STATINK_MAP.WATER_LEVEL_MAP[wave.waterLevel], @@ -717,7 +760,7 @@ export class StatInkExporter implements GameExporter { job_score: detail.jobScore, job_rate: detail.jobRate, job_bonus: detail.jobBonus, - waves: detail.waveResults.map((w) => this.mapWave(w)), + waves: await Promise.all(detail.waveResults.map((w) => this.mapWave(w))), players: await Promise.all([ this.mapCoopPlayer(myResult), ...memberResults.map((p) => this.mapCoopPlayer(p)), diff --git a/src/types.ts b/src/types.ts index ba682c6..a329383 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,17 +2,17 @@ import { RankState } from "./state.ts"; export enum Queries { HomeQuery = "dba47124d5ec3090c97ba17db5d2f4b3", - LatestBattleHistoriesQuery = "7d8b560e31617e981cf7c8aa1ca13a00", - RegularBattleHistoriesQuery = "f6e7e0277e03ff14edfef3b41f70cd33", - BankaraBattleHistoriesQuery = "c1553ac75de0a3ea497cdbafaa93e95b", - PrivateBattleHistoriesQuery = "38e0529de8bc77189504d26c7a14e0b8", - VsHistoryDetailQuery = "2b085984f729cd51938fc069ceef784a", - CoopHistoryQuery = "817618ce39bcf5570f52a97d73301b30", - CoopHistoryDetailQuery = "f3799a033f0a7ad4b1b396f9a3bafb1e", + LatestBattleHistoriesQuery = "4f5f26e64bca394b45345a65a2f383bd", + RegularBattleHistoriesQuery = "d5b795d09e67ce153e622a184b7e7dfa", + BankaraBattleHistoriesQuery = "de4754588109b77dbcb90fbe44b612ee", + PrivateBattleHistoriesQuery = "1d6ed57dc8b801863126ad4f351dfb9a", + VsHistoryDetailQuery = "291295ad311b99a6288fc95a5c4cb2d2", + CoopHistoryQuery = "6ed02537e4a65bbb5e7f4f23092f6154", + CoopHistoryDetailQuery = "3cc5f826a6646b85f3ae45db51bd0707", myOutfitCommonDataFilteringConditionQuery = "d02ab22c9dccc440076055c8baa0fa7a", myOutfitCommonDataEquipmentsQuery = "d29cd0c2b5e6bac90dd5b817914832f8", - HistoryRecordQuery = "9d4ef9fba3f84d6933bb1f6f436f7200", + HistoryRecordQuery = "32b6771f94083d8f04848109b7300af5", ConfigureAnalyticsQuery = "f8ae00773cc412a50dd41a6d9a159ddd", } export type VarsMap = { @@ -224,7 +224,6 @@ export type CoopHistoryPlayerResult = { weapons: { name: string; image: Image | null }[]; specialWeapon: null | { name: string; - id: string; }; defeatEnemyCount: number; deliverCount: number; @@ -270,7 +269,6 @@ export type CoopHistoryDetail = { goldenPopCount: number; teamDeliverCount: number; specialWeapons: { - id: string; name: string; }[]; }[]; @@ -570,6 +568,12 @@ export type StatInkWeapon = { name: Record; }[]; +// TODO: Change when the API is released +export type StatInkSpecialWeapon = { + key: string; + name: Record; +}[]; + export type StatInkGear = { primary_ability: string; secondary_abilities: (string | null)[];