feat: update queries and version (#40)

* feat: update queries and version

* feat: add skip tip to user

* fix: find-coop-map

* build: bump version
main
imspace 2022-11-29 22:15:07 +08:00 committed by GitHub
parent 2a0bc5ff56
commit 5409ecdb16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 87 additions and 50 deletions

View File

@ -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 ## 0.1.34
feat: add `--with-summary` to export summary data to file feat: add `--with-summary` to export summary data to file

View File

@ -15,7 +15,6 @@ for (const dir of dirs) {
const events = new Map<number, string>(); const events = new Map<number, string>();
const uniforms = new Map<number, string>(); const uniforms = new Map<number, string>();
const specials = new Map<number, string>();
const bosses = new Map<number, string>(); const bosses = new Map<number, string>();
for (const file of files) { for (const file of files) {
@ -41,14 +40,6 @@ for (const file of files) {
uniforms.set(b64Number(id), name); 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)) { for (const { id, name } of data.detail.enemyResults.map((i) => i.enemy)) {
bosses.set(b64Number(id), name); 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([...events.entries()].sort((a, b) => a[0] - b[0]));
console.log([...uniforms.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])); console.log([...bosses.entries()].sort((a, b) => a[0] - b[0]));

View File

@ -51,8 +51,10 @@ async function getWebViewVer(): Promise<string> {
const mainJSBody = await (await fetch(SPLATNET3_URL + mainJS)).text(); const mainJSBody = await (await fetch(SPLATNET3_URL + mainJS)).text();
const revision = /"([0-9a-f]{40})"/.exec(mainJSBody)?.[1]; const revision = /"([0-9a-f]{40})"/.exec(mainJSBody)?.[1];
const version = /revision_info_not_set.*?="(\d+\.\d+\.\d+)/.exec(mainJSBody) const version = /revision_info_not_set.*?=("|`)(\d+\.\d+\.\d+)-/.exec(
?.[1]; mainJSBody,
)
?.[2];
if (!version || !revision) { if (!version || !revision) {
throw new Error("No version and revision found"); throw new Error("No version and revision found");

View File

@ -1,9 +1,9 @@
import type { StatInkPostBody, VsHistoryDetail } from "./types.ts"; import type { StatInkPostBody, VsHistoryDetail } from "./types.ts";
export const AGENT_NAME = "s3si.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 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 S3SI_LINK = "https://github.com/spacemeowx2/s3si.ts";
export const USERAGENT = `${AGENT_NAME}/${S3SI_VERSION} (${S3SI_LINK})`; export const USERAGENT = `${AGENT_NAME}/${S3SI_VERSION} (${S3SI_LINK})`;
@ -37,7 +37,6 @@ export const SPLATNET3_STATINK_MAP: {
| "white" | "white"
| undefined | undefined
>; >;
COOP_SPECIAL_MAP: Record<number, string>;
WATER_LEVEL_MAP: Record<0 | 1 | 2, "low" | "normal" | "high">; WATER_LEVEL_MAP: Record<0 | 1 | 2, "low" | "normal" | "high">;
} = { } = {
RULE: { RULE: {
@ -81,15 +80,6 @@ export const SPLATNET3_STATINK_MAP: {
6: "black", 6: "black",
7: "white", 7: "white",
}, },
COOP_SPECIAL_MAP: {
20006: "nicedama",
20007: "hopsonar",
20009: "megaphone51",
20010: "jetpack",
20012: "kanitank",
20013: "sameride",
20014: "tripletornado",
},
WATER_LEVEL_MAP: { WATER_LEVEL_MAP: {
0: "low", 0: "low",
1: "normal", 1: "normal",

View File

@ -22,6 +22,7 @@ import {
StatInkPlayer, StatInkPlayer,
StatInkPostBody, StatInkPostBody,
StatInkPostResponse, StatInkPostResponse,
StatInkSpecialWeapon,
StatInkStage, StatInkStage,
StatInkUuidList, StatInkUuidList,
StatInkWeapon, StatInkWeapon,
@ -182,6 +183,29 @@ class StatInkAPI {
} }
} }
_specialMap = new Map<string, string>();
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<string, string>(); _salmonWeaponMap = new Map<string, string>();
async getSalmonWeaponMap() { async getSalmonWeaponMap() {
if (this._salmonWeaponMap.size === 0) { if (this._salmonWeaponMap.size === 0) {
@ -205,6 +229,10 @@ class StatInkAPI {
} }
return this._salmonWeaponMap; return this._salmonWeaponMap;
} }
getSpecial = (): Promise<StatInkSpecialWeapon> => {
// TODO: fix this after stat.ink supports special API
throw new Error("Not implemented");
};
getSalmonWeapon = () => getSalmonWeapon = () =>
this._getCached<StatInkWeapon>( this._getCached<StatInkWeapon>(
`${this.statInk}/api/v3/salmon/weapon?full=1`, `${this.statInk}/api/v3/salmon/weapon?full=1`,
@ -262,13 +290,18 @@ export class StatInkExporter implements GameExporter {
url, url,
}; };
} else { } else {
const body = await this.mapCoop(game);
const { url } = await this.api.postCoop(body);
return { return {
status: "success", status: "skip",
url, 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( async notExported(
@ -559,6 +592,16 @@ export class StatInkExporter implements GameExporter {
return weapon; return weapon;
} }
async mapSpecial(name: string): Promise<string> {
const specialMap = await this.api.getSpecialMap();
const special = specialMap.get(name);
if (!special) {
throw new Error(`Special not found: ${name}`);
}
return special;
}
async mapCoopPlayer({ async mapCoopPlayer({
player, player,
weapons, weapons,
@ -578,7 +621,7 @@ export class StatInkExporter implements GameExporter {
uniform: uniform:
SPLATNET3_STATINK_MAP.COOP_UNIFORM_MAP[b64Number(player.uniform.id)], SPLATNET3_STATINK_MAP.COOP_UNIFORM_MAP[b64Number(player.uniform.id)],
special: specialWeapon special: specialWeapon
? SPLATNET3_STATINK_MAP.COOP_SPECIAL_MAP[b64Number(specialWeapon.id)] ? await this.mapSpecial(specialWeapon.name)
: undefined, : undefined,
weapons: await Promise.all(weapons.map((w) => this.mapCoopWeapon(w))), weapons: await Promise.all(weapons.map((w) => this.mapCoopWeapon(w))),
golden_eggs: goldenDeliverCount, golden_eggs: goldenDeliverCount,
@ -598,18 +641,18 @@ export class StatInkExporter implements GameExporter {
return nid; return nid;
} }
mapWave(wave: CoopHistoryDetail["waveResults"]["0"]): StatInkCoopWave { async mapWave(
wave: CoopHistoryDetail["waveResults"]["0"],
): Promise<StatInkCoopWave> {
const event = wave.eventWave const event = wave.eventWave
? SPLATNET3_STATINK_MAP.COOP_EVENT_MAP[b64Number(wave.eventWave.id)] ? SPLATNET3_STATINK_MAP.COOP_EVENT_MAP[b64Number(wave.eventWave.id)]
: undefined; : undefined;
const special_uses = wave.specialWeapons.reduce((p, { id }) => { const special_uses = (await Promise.all(
const key = SPLATNET3_STATINK_MAP.COOP_SPECIAL_MAP[b64Number(id)]; wave.specialWeapons.map((w) => this.mapSpecial(w.name)),
)).reduce((p, key) => ({
return { ...p,
...p, [key]: (p[key] ?? 0) + 1,
[key]: (p[key] ?? 0) + 1, }), {} as Record<string, number | undefined>) as Record<string, number>;
};
}, {} as Record<string, number | undefined>) as Record<string, number>;
return { return {
tide: SPLATNET3_STATINK_MAP.WATER_LEVEL_MAP[wave.waterLevel], tide: SPLATNET3_STATINK_MAP.WATER_LEVEL_MAP[wave.waterLevel],
@ -717,7 +760,7 @@ export class StatInkExporter implements GameExporter {
job_score: detail.jobScore, job_score: detail.jobScore,
job_rate: detail.jobRate, job_rate: detail.jobRate,
job_bonus: detail.jobBonus, 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([ players: await Promise.all([
this.mapCoopPlayer(myResult), this.mapCoopPlayer(myResult),
...memberResults.map((p) => this.mapCoopPlayer(p)), ...memberResults.map((p) => this.mapCoopPlayer(p)),

View File

@ -2,17 +2,17 @@ import { RankState } from "./state.ts";
export enum Queries { export enum Queries {
HomeQuery = "dba47124d5ec3090c97ba17db5d2f4b3", HomeQuery = "dba47124d5ec3090c97ba17db5d2f4b3",
LatestBattleHistoriesQuery = "7d8b560e31617e981cf7c8aa1ca13a00", LatestBattleHistoriesQuery = "4f5f26e64bca394b45345a65a2f383bd",
RegularBattleHistoriesQuery = "f6e7e0277e03ff14edfef3b41f70cd33", RegularBattleHistoriesQuery = "d5b795d09e67ce153e622a184b7e7dfa",
BankaraBattleHistoriesQuery = "c1553ac75de0a3ea497cdbafaa93e95b", BankaraBattleHistoriesQuery = "de4754588109b77dbcb90fbe44b612ee",
PrivateBattleHistoriesQuery = "38e0529de8bc77189504d26c7a14e0b8", PrivateBattleHistoriesQuery = "1d6ed57dc8b801863126ad4f351dfb9a",
VsHistoryDetailQuery = "2b085984f729cd51938fc069ceef784a", VsHistoryDetailQuery = "291295ad311b99a6288fc95a5c4cb2d2",
CoopHistoryQuery = "817618ce39bcf5570f52a97d73301b30", CoopHistoryQuery = "6ed02537e4a65bbb5e7f4f23092f6154",
CoopHistoryDetailQuery = "f3799a033f0a7ad4b1b396f9a3bafb1e", CoopHistoryDetailQuery = "3cc5f826a6646b85f3ae45db51bd0707",
myOutfitCommonDataFilteringConditionQuery = myOutfitCommonDataFilteringConditionQuery =
"d02ab22c9dccc440076055c8baa0fa7a", "d02ab22c9dccc440076055c8baa0fa7a",
myOutfitCommonDataEquipmentsQuery = "d29cd0c2b5e6bac90dd5b817914832f8", myOutfitCommonDataEquipmentsQuery = "d29cd0c2b5e6bac90dd5b817914832f8",
HistoryRecordQuery = "9d4ef9fba3f84d6933bb1f6f436f7200", HistoryRecordQuery = "32b6771f94083d8f04848109b7300af5",
ConfigureAnalyticsQuery = "f8ae00773cc412a50dd41a6d9a159ddd", ConfigureAnalyticsQuery = "f8ae00773cc412a50dd41a6d9a159ddd",
} }
export type VarsMap = { export type VarsMap = {
@ -224,7 +224,6 @@ export type CoopHistoryPlayerResult = {
weapons: { name: string; image: Image | null }[]; weapons: { name: string; image: Image | null }[];
specialWeapon: null | { specialWeapon: null | {
name: string; name: string;
id: string;
}; };
defeatEnemyCount: number; defeatEnemyCount: number;
deliverCount: number; deliverCount: number;
@ -270,7 +269,6 @@ export type CoopHistoryDetail = {
goldenPopCount: number; goldenPopCount: number;
teamDeliverCount: number; teamDeliverCount: number;
specialWeapons: { specialWeapons: {
id: string;
name: string; name: string;
}[]; }[];
}[]; }[];
@ -570,6 +568,12 @@ export type StatInkWeapon = {
name: Record<string, string>; name: Record<string, string>;
}[]; }[];
// TODO: Change when the API is released
export type StatInkSpecialWeapon = {
key: string;
name: Record<string, string>;
}[];
export type StatInkGear = { export type StatInkGear = {
primary_ability: string; primary_ability: string;
secondary_abilities: (string | null)[]; secondary_abilities: (string | null)[];