feat(stat.ink): add gears
parent
af941a59fd
commit
1c9c03e327
|
|
@ -1,3 +1,7 @@
|
|||
## 0.1.17
|
||||
|
||||
feat: add gears to stat.ink
|
||||
|
||||
## 0.1.16
|
||||
|
||||
fix: RankTracker broken when token expires
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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,9 +268,11 @@ 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(
|
||||
this.mapPlayer,
|
||||
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,
|
||||
|
|
|
|||
35
src/types.ts
35
src/types.ts
|
|
@ -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";
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue