feat(stat.ink): add gears

main
spacemeowx2 2022-11-04 23:34:07 +08:00
parent af941a59fd
commit 1c9c03e327
5 changed files with 104 additions and 11 deletions

View File

@ -1,3 +1,7 @@
## 0.1.17
feat: add gears to stat.ink
## 0.1.16
fix: RankTracker broken when token expires

View File

@ -210,6 +210,8 @@ export class App {
),
);
endBar();
printStats(stats);
if (errors.length > 0) {
throw errors[0];
@ -221,8 +223,6 @@ export class App {
...this.state,
rankState: finalRankState,
});
endBar();
}
stats = initStats();
@ -268,12 +268,12 @@ export class App {
),
);
endBar();
printStats(stats);
if (errors.length > 0) {
throw errors[0];
}
endBar();
}
}
async monitor() {

View File

@ -1,7 +1,7 @@
import type { StatInkPostBody, VsHistoryDetail } from "./types.ts";
export const AGENT_NAME = "s3si.ts";
export const S3SI_VERSION = "0.1.16";
export const S3SI_VERSION = "0.1.17";
export const NSOAPP_VERSION = "2.3.1";
export const WEB_VIEW_VERSION = "1.0.0-5644e7a2";
export const S3SI_LINK = "https://github.com/spacemeowx2/s3si.ts";

View File

@ -9,6 +9,10 @@ import {
import {
CoopInfo,
GameExporter,
PlayerGear,
StatInkAbility,
StatInkGear,
StatInkGears,
StatInkPlayer,
StatInkPostBody,
StatInkPostResponse,
@ -17,7 +21,7 @@ import {
VsInfo,
VsPlayer,
} from "../types.ts";
import { base64, msgpack } from "../../deps.ts";
import { base64, msgpack, Mutex } from "../../deps.ts";
import { APIError } from "../APIError.ts";
import { cache, gameId } from "../utils.ts";
@ -30,11 +34,23 @@ function b64Number(id: string): number {
return parseInt(num);
}
const FETCH_LOCK = new Mutex();
async function _getAbility(): Promise<StatInkAbility> {
const release = await FETCH_LOCK.acquire();
try {
const resp = await fetch("https://stat.ink/api/v3/ability?full=1");
const json = await resp.json();
return json;
} finally {
release();
}
}
async function _getStage(): Promise<StatInkStage> {
const resp = await fetch("https://stat.ink/api/v3/stage");
const json = await resp.json();
return json;
}
const getAbility = cache(_getAbility);
const getStage = cache(_getStage);
/**
@ -157,7 +173,42 @@ export class StatInkExporter implements GameExporter {
return result.key;
}
mapPlayer(player: VsPlayer, index: number): StatInkPlayer {
async mapGears(
{ headGear, clothingGear, shoesGear }: VsPlayer,
): Promise<StatInkGears> {
const amap = (await getAbility()).map((i) => ({
...i,
names: Object.values(i.name),
}));
const mapAbility = ({ name }: { name: string }): string | null => {
const result = amap.find((a) => a.names.includes(name));
if (!result) {
return null;
}
return result.key;
};
const mapGear = (
{ primaryGearPower, additionalGearPowers }: PlayerGear,
): StatInkGear => {
const primary = mapAbility(primaryGearPower);
if (!primary) {
throw new Error("Unknown ability: " + primaryGearPower.name);
}
return {
primary_ability: primary,
secondary_abilities: additionalGearPowers.map(mapAbility),
};
};
return {
headgear: mapGear(headGear),
clothing: mapGear(clothingGear),
shoes: mapGear(shoesGear),
};
}
mapPlayer = async (
player: VsPlayer,
index: number,
): Promise<StatInkPlayer> => {
const result: StatInkPlayer = {
me: player.isMyself ? "yes" : "no",
rank_in_team: index + 1,
@ -166,6 +217,7 @@ export class StatInkExporter implements GameExporter {
splashtag_title: player.byname,
weapon: b64Number(player.weapon.id).toString(),
inked: player.paint,
gears: await this.mapGears(player),
disconnected: player.result ? "no" : "yes",
};
if (player.result) {
@ -176,7 +228,7 @@ export class StatInkExporter implements GameExporter {
result.special = player.result.special;
}
return result;
}
};
async mapBattle(
{
challengeProgress,
@ -216,10 +268,12 @@ export class StatInkExporter implements GameExporter {
medals: vsDetail.awards.map((i) => i.name),
our_team_players: myTeam.players.map(this.mapPlayer),
their_team_players: otherTeams.flatMap((i) => i.players).map(
our_team_players: await Promise.all(myTeam.players.map(this.mapPlayer)),
their_team_players: await Promise.all(
otherTeams.flatMap((i) => i.players).map(
this.mapPlayer,
),
),
agent: AGENT_NAME,
agent_version: S3SI_VERSION,

View File

@ -61,6 +61,19 @@ export type HistoryGroups<T> = {
};
}[];
};
export type PlayerGear = {
name: string;
primaryGearPower: {
name: string;
};
additionalGearPowers: {
name: string;
}[];
brand: {
name: string;
id: string;
};
};
export type VsPlayer = {
id: string;
nameId: string | null;
@ -81,6 +94,10 @@ export type VsPlayer = {
special: number;
} | null;
paint: number;
headGear: PlayerGear;
clothingGear: PlayerGear;
shoesGear: PlayerGear;
};
export type VsTeam = {
players: VsPlayer[];
@ -240,6 +257,23 @@ export enum BattleListType {
Coop,
}
export type StatInkAbility = {
key: string;
name: Record<string, string>;
primary_only: boolean;
}[];
export type StatInkGear = {
primary_ability: string;
secondary_abilities: (string | null)[];
};
export type StatInkGears = {
headgear: StatInkGear;
clothing: StatInkGear;
shoes: StatInkGear;
};
export type StatInkPlayer = {
me: "yes" | "no";
rank_in_team: number;
@ -253,6 +287,7 @@ export type StatInkPlayer = {
kill_or_assist?: number;
death?: number;
special?: number;
gears?: StatInkGears;
disconnected: "yes" | "no";
};