Compare commits
11 Commits
5fd0dbbd14
...
fcfa346969
| Author | SHA1 | Date |
|---|---|---|
|
|
fcfa346969 | |
|
|
cdaf7f3f1f | |
|
|
116243eac8 | |
|
|
3a599717de | |
|
|
e1b3703401 | |
|
|
812e7ab611 | |
|
|
858f9a3bcc | |
|
|
f026571844 | |
|
|
f81232ce86 | |
|
|
c2f42863b8 | |
|
|
feb486e775 |
15
CHANGELOG.md
15
CHANGELOG.md
|
|
@ -1,3 +1,18 @@
|
||||||
|
## 0.4.1
|
||||||
|
|
||||||
|
feat: add support for Challenges
|
||||||
|
([#72](https://github.com/spacemeowx2/s3si.ts/issues/72))
|
||||||
|
|
||||||
|
## 0.4.0
|
||||||
|
|
||||||
|
feat: update `callImink`
|
||||||
|
|
||||||
|
feat: update VersionData
|
||||||
|
|
||||||
|
## 0.3.6
|
||||||
|
|
||||||
|
feat: update `WEB_VIEW_VERSION` and query hashes for 4.0.0
|
||||||
|
|
||||||
## 0.3.5
|
## 0.3.5
|
||||||
|
|
||||||
fix: wrong ability keys in some languages
|
fix: wrong ability keys in some languages
|
||||||
|
|
|
||||||
|
|
@ -11,34 +11,34 @@
|
||||||
"lint": "eslint --max-warnings=0 src"
|
"lint": "eslint --max-warnings=0 src"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tauri-apps/api": "^1.2.0",
|
"@tauri-apps/api": "^1.3.0",
|
||||||
"classnames": "^2.3.2",
|
"classnames": "^2.3.2",
|
||||||
"daisyui": "^2.51.3",
|
"daisyui": "^2.52.0",
|
||||||
"i18next": "^22.4.10",
|
"i18next": "^22.5.0",
|
||||||
"i18next-browser-languagedetector": "^7.0.1",
|
"i18next-browser-languagedetector": "^7.0.2",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-i18next": "^12.2.0",
|
"react-i18next": "^12.3.1",
|
||||||
"react-icons": "^4.8.0",
|
"react-icons": "^4.9.0",
|
||||||
"react-router-dom": "^6.8.2",
|
"react-router-dom": "^6.11.2",
|
||||||
"react-use": "^17.4.0"
|
"react-use": "^17.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tauri-apps/cli": "^1.2.3",
|
"@tauri-apps/cli": "^1.3.1",
|
||||||
"@types/node": "^18.14.5",
|
"@types/node": "^20.2.5",
|
||||||
"@types/react": "^18.0.15",
|
"@types/react": "^18.0.15",
|
||||||
"@types/react-dom": "^18.0.6",
|
"@types/react-dom": "^18.0.6",
|
||||||
"@vitejs/plugin-react": "^3.1.0",
|
"@vitejs/plugin-react": "^4.0.0",
|
||||||
"autoprefixer": "^10.4.13",
|
"autoprefixer": "^10.4.14",
|
||||||
"eslint": "^8.35.0",
|
"eslint": "^8.41.0",
|
||||||
"eslint-config-react-app": "^7.0.1",
|
"eslint-config-react-app": "^7.0.1",
|
||||||
"i18next-http-backend": "^2.1.1",
|
"i18next-http-backend": "^2.2.1",
|
||||||
"postcss": "^8.4.21",
|
"postcss": "^8.4.24",
|
||||||
"tailwindcss": "^3.2.7",
|
"tailwindcss": "^3.3.2",
|
||||||
"typescript": "^4.9.5",
|
"typescript": "^5.0.4",
|
||||||
"vite": "^4.1.4",
|
"vite": "^4.3.9",
|
||||||
"vite-plugin-eslint": "^1.8.1",
|
"vite-plugin-eslint": "^1.8.1",
|
||||||
"vite-tsconfig-paths": "^4.0.5"
|
"vite-tsconfig-paths": "^4.2.0"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": "react-app"
|
"extends": "react-app"
|
||||||
|
|
|
||||||
1077
gui/pnpm-lock.yaml
1077
gui/pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
|
@ -8,7 +8,7 @@
|
||||||
},
|
},
|
||||||
"package": {
|
"package": {
|
||||||
"productName": "s3si-ts",
|
"productName": "s3si-ts",
|
||||||
"version": "0.3.5"
|
"version": "0.4.1"
|
||||||
},
|
},
|
||||||
"tauri": {
|
"tauri": {
|
||||||
"allowlist": {
|
"allowlist": {
|
||||||
|
|
|
||||||
|
|
@ -9,22 +9,19 @@ if (import.meta.main) {
|
||||||
"x86_64-apple-darwin",
|
"x86_64-apple-darwin",
|
||||||
"aarch64-apple-darwin",
|
"aarch64-apple-darwin",
|
||||||
];
|
];
|
||||||
const rustInfo = new TextDecoder().decode(
|
const rustInfo = await (new Deno.Command("rustc", {
|
||||||
await Deno.run({
|
args: ["-Vv"],
|
||||||
cmd: ["rustc", "-Vv"],
|
})).output();
|
||||||
stdout: "piped",
|
const target =
|
||||||
}).output(),
|
/host: (\S+)/g.exec(new TextDecoder().decode(rustInfo.stdout))?.[1] ?? "?";
|
||||||
);
|
|
||||||
const target = /host: (\S+)/g.exec(rustInfo)?.[1] ?? "?";
|
|
||||||
|
|
||||||
if (!TARGETS.includes(target)) {
|
if (!TARGETS.includes(target)) {
|
||||||
console.error(`Unsupported target: ${target}`);
|
console.error(`Unsupported target: ${target}`);
|
||||||
Deno.exit(1);
|
Deno.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const p = Deno.run({
|
const p = new Deno.Command("deno", {
|
||||||
cmd: [
|
args: [
|
||||||
"deno",
|
|
||||||
"compile",
|
"compile",
|
||||||
"--target",
|
"--target",
|
||||||
target,
|
target,
|
||||||
|
|
@ -35,7 +32,7 @@ if (import.meta.main) {
|
||||||
],
|
],
|
||||||
cwd: __dirname,
|
cwd: __dirname,
|
||||||
});
|
});
|
||||||
const status = await p.status();
|
const status = await p.output();
|
||||||
if (!status.success) {
|
if (!status.success) {
|
||||||
console.error(
|
console.error(
|
||||||
"Failed to run deno compile for target",
|
"Failed to run deno compile for target",
|
||||||
|
|
@ -50,18 +47,21 @@ if (import.meta.main) {
|
||||||
Deno.build.os === "windows" ? ".exe" : ""
|
Deno.build.os === "windows" ? ".exe" : ""
|
||||||
}`;
|
}`;
|
||||||
console.log("Test the binary");
|
console.log("Test the binary");
|
||||||
const s3si = Deno.run({
|
const s3si = new Deno.Command(binPath, {
|
||||||
cmd: [binPath],
|
|
||||||
stdin: "piped",
|
stdin: "piped",
|
||||||
stdout: "piped",
|
stdout: "piped",
|
||||||
});
|
}).spawn();
|
||||||
await s3si.stdin?.write(
|
const s3siWriter = s3si.stdin.getWriter();
|
||||||
|
await s3siWriter.write(
|
||||||
new TextEncoder().encode(
|
new TextEncoder().encode(
|
||||||
'{"jsonrpc":"2.0","method":"hello","params":[],"id":1}\n',
|
'{"jsonrpc":"2.0","method":"hello","params":[],"id":1}\n',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
s3si.stdin?.close();
|
|
||||||
const output = new TextDecoder().decode(await s3si.output());
|
const output = new TextDecoder().decode(
|
||||||
|
(await s3si.stdout.getReader().read()).value,
|
||||||
|
);
|
||||||
|
await s3siWriter.close();
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
output,
|
output,
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,62 @@ function getConst(content: string, name: string): string {
|
||||||
return JSON.parse(match[1]);
|
return JSON.parse(match[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function replaceEnum(
|
||||||
|
content: string,
|
||||||
|
name: string,
|
||||||
|
pairs: Record<string, string>,
|
||||||
|
): string {
|
||||||
|
const regex = new RegExp(`export enum ${name} {([\\s\\S^}]+?)}`);
|
||||||
|
|
||||||
|
const body = Object.entries(pairs).map(([key, value]) =>
|
||||||
|
` ${key} = "${value}"`
|
||||||
|
).join(",\n");
|
||||||
|
|
||||||
|
return content.replace(regex, `export enum ${name} {\n${body}\n}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getEnumKeys(content: string, name: string): string[] {
|
||||||
|
const regex = new RegExp(`export enum ${name} {([\\s\\S^}]+?)}`);
|
||||||
|
|
||||||
|
const match = regex.exec(content);
|
||||||
|
|
||||||
|
if (!match) {
|
||||||
|
throw new Error(`Cannot find ${name}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const body = match[1];
|
||||||
|
|
||||||
|
// extract keys from `key = "value"`
|
||||||
|
const keys: string[] = [];
|
||||||
|
const keyRE = /\s*(\w+)\s*=/g;
|
||||||
|
while (true) {
|
||||||
|
const match = keyRE.exec(body);
|
||||||
|
if (!match) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
keys.push(match[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getQueryHash(js: string, query: string): string {
|
||||||
|
const regex = new RegExp(
|
||||||
|
`params:\\{id:"([^"]*?)",metadata:{},name:"${query}"`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const match = regex.exec(js);
|
||||||
|
|
||||||
|
if (!match) {
|
||||||
|
throw new Error(`Cannot find ${query}`);
|
||||||
|
}
|
||||||
|
if (match[0].length > 500) {
|
||||||
|
throw new Error(`Match too large ${match[0].length}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return match[1];
|
||||||
|
}
|
||||||
|
|
||||||
async function printError<T>(p: Promise<T>): Promise<T | undefined> {
|
async function printError<T>(p: Promise<T>): Promise<T | undefined> {
|
||||||
try {
|
try {
|
||||||
return await p;
|
return await p;
|
||||||
|
|
@ -39,7 +95,7 @@ async function printError<T>(p: Promise<T>): Promise<T | undefined> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getWebViewVer(): Promise<string> {
|
async function getMainJSBody(): Promise<string> {
|
||||||
const splatnet3Home = await (await fetch(SPLATNET3_URL)).text();
|
const splatnet3Home = await (await fetch(SPLATNET3_URL)).text();
|
||||||
|
|
||||||
const mainJS = /src="(\/.*?\.js)"/.exec(splatnet3Home)?.[1];
|
const mainJS = /src="(\/.*?\.js)"/.exec(splatnet3Home)?.[1];
|
||||||
|
|
@ -50,9 +106,16 @@ 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];
|
return mainJSBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mainJSBody = await getMainJSBody();
|
||||||
|
|
||||||
|
// deno-lint-ignore require-await
|
||||||
|
async function getWebViewVer(js: string): Promise<string> {
|
||||||
|
const revision = /"([0-9a-f]{40})"/.exec(js)?.[1];
|
||||||
const version = /revision_info_not_set.*?=("|`)(\d+\.\d+\.\d+)-/.exec(
|
const version = /revision_info_not_set.*?=("|`)(\d+\.\d+\.\d+)-/.exec(
|
||||||
mainJSBody,
|
js,
|
||||||
)
|
)
|
||||||
?.[2];
|
?.[2];
|
||||||
|
|
||||||
|
|
@ -83,7 +146,7 @@ const oldValues = {
|
||||||
};
|
};
|
||||||
const newValues: Record<string, string | undefined> = {};
|
const newValues: Record<string, string | undefined> = {};
|
||||||
|
|
||||||
newValues.WEB_VIEW_VERSION = await printError(getWebViewVer());
|
newValues.WEB_VIEW_VERSION = await printError(getWebViewVer(mainJSBody));
|
||||||
newValues.NSOAPP_VERSION = await printError(getNSOVer());
|
newValues.NSOAPP_VERSION = await printError(getNSOVer());
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(newValues)) {
|
for (const [key, value] of Object.entries(newValues)) {
|
||||||
|
|
@ -91,8 +154,27 @@ for (const [key, value] of Object.entries(newValues)) {
|
||||||
content = replaceConst(content, key, value);
|
content = replaceConst(content, key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await Deno.writeTextFile(CONSTANT_PATH, content);
|
|
||||||
|
|
||||||
console.log("Done");
|
console.log("const updated");
|
||||||
console.log("Old:", oldValues);
|
console.log("Old:", oldValues);
|
||||||
console.log("New:", newValues);
|
console.log("New:", newValues);
|
||||||
|
|
||||||
|
const keys = getEnumKeys(content, "Queries");
|
||||||
|
const pairs = Object.fromEntries(
|
||||||
|
keys.map((key) => [key, getQueryHash(mainJSBody, key)]),
|
||||||
|
);
|
||||||
|
content = replaceEnum(content, "Queries", pairs);
|
||||||
|
console.log("query updated");
|
||||||
|
|
||||||
|
await Deno.writeTextFile(CONSTANT_PATH, content);
|
||||||
|
|
||||||
|
const command = new Deno.Command(Deno.execPath(), {
|
||||||
|
args: ["fmt", "./src/constant.ts"],
|
||||||
|
cwd: ROOT_DIR,
|
||||||
|
stdin: "inherit",
|
||||||
|
stdout: "inherit",
|
||||||
|
});
|
||||||
|
const { code } = command.outputSync();
|
||||||
|
if (code !== 0) {
|
||||||
|
Deno.exit(code);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,10 @@ Deno.test("getSeason", () => {
|
||||||
|
|
||||||
assertEquals(season3?.id, "season202303");
|
assertEquals(season3?.id, "season202303");
|
||||||
|
|
||||||
|
const season4 = getSeason(new Date("2023-06-01T00:00:00+00:00"));
|
||||||
|
|
||||||
|
assertEquals(season4?.id, "season202306");
|
||||||
|
|
||||||
const nonExist = getSeason(new Date("2022-06-09T00:00:00+00:00"));
|
const nonExist = getSeason(new Date("2022-06-09T00:00:00+00:00"));
|
||||||
|
|
||||||
assertEquals(nonExist, undefined);
|
assertEquals(nonExist, undefined);
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,12 @@ export const SEASONS: Season[] = [
|
||||||
start: new Date("2023-03-01T00:00:00+00:00"),
|
start: new Date("2023-03-01T00:00:00+00:00"),
|
||||||
end: new Date("2023-06-01T00:00:00+00:00"),
|
end: new Date("2023-06-01T00:00:00+00:00"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "season202306",
|
||||||
|
name: "Sizzle Season 2023",
|
||||||
|
start: new Date("2023-06-01T00:00:00+00:00"),
|
||||||
|
end: new Date("2023-09-01T00:00:00+00:00"),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const getSeason = (date: Date): Season | undefined => {
|
export const getSeason = (date: Date): Season | undefined => {
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,26 @@ import type { StatInkPostBody, VsHistoryDetail } from "./types.ts";
|
||||||
|
|
||||||
export const AGENT_NAME = "splashcat / s3si.ts";
|
export const AGENT_NAME = "splashcat / s3si.ts";
|
||||||
export const AGENT_VERSION = "1.1.1";
|
export const AGENT_VERSION = "1.1.1";
|
||||||
export const S3SI_VERSION = "0.3.5";
|
export const S3SI_VERSION = "0.4.1";
|
||||||
export const COMBINED_VERSION = `${AGENT_VERSION}/${S3SI_VERSION}`;
|
export const COMBINED_VERSION = `${AGENT_VERSION}/${S3SI_VERSION}`;
|
||||||
export const NSOAPP_VERSION = "2.5.1";
|
export const NSOAPP_VERSION = "2.5.1";
|
||||||
export const WEB_VIEW_VERSION = "3.0.0-0742bda0";
|
export const WEB_VIEW_VERSION = "4.0.0-d5178440";
|
||||||
|
export enum Queries {
|
||||||
|
HomeQuery = "7dcc64ea27a08e70919893a0d3f70871",
|
||||||
|
LatestBattleHistoriesQuery = "0d90c7576f1916469b2ae69f64292c02",
|
||||||
|
RegularBattleHistoriesQuery = "3baef04b095ad8975ea679d722bc17de",
|
||||||
|
BankaraBattleHistoriesQuery = "0438ea6978ae8bd77c5d1250f4f84803",
|
||||||
|
XBattleHistoriesQuery = "6796e3cd5dc3ebd51864dc709d899fc5",
|
||||||
|
PrivateBattleHistoriesQuery = "8e5ae78b194264a6c230e262d069bd28",
|
||||||
|
VsHistoryDetailQuery = "9ee0099fbe3d8db2a838a75cf42856dd",
|
||||||
|
CoopHistoryQuery = "91b917becd2fa415890f5b47e15ffb15",
|
||||||
|
CoopHistoryDetailQuery = "379f0d9b78b531be53044bcac031b34b",
|
||||||
|
myOutfitCommonDataFilteringConditionQuery =
|
||||||
|
"d02ab22c9dccc440076055c8baa0fa7a",
|
||||||
|
myOutfitCommonDataEquipmentsQuery = "d29cd0c2b5e6bac90dd5b817914832f8",
|
||||||
|
HistoryRecordQuery = "d9246baf077b2a29b5f7aac321810a77",
|
||||||
|
ConfigureAnalyticsQuery = "f8ae00773cc412a50dd41a6d9a159ddd",
|
||||||
|
}
|
||||||
export const S3SI_LINK = "https://forgejo.catgirlin.space/catgirl/s3si.ts";
|
export const S3SI_LINK = "https://forgejo.catgirlin.space/catgirl/s3si.ts";
|
||||||
|
|
||||||
export const USERAGENT = `${AGENT_NAME}/(${COMBINED_VERSION}) (${S3SI_LINK})`;
|
export const USERAGENT = `${AGENT_NAME}/(${COMBINED_VERSION}) (${S3SI_LINK})`;
|
||||||
|
|
|
||||||
|
|
@ -330,6 +330,8 @@ export class StatInkExporter implements GameExporter {
|
||||||
}
|
}
|
||||||
} else if (vsMode === "X_MATCH") {
|
} else if (vsMode === "X_MATCH") {
|
||||||
return "xmatch";
|
return "xmatch";
|
||||||
|
} else if (vsMode === "LEAGUE") {
|
||||||
|
return "event";
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new TypeError(`Unknown vsMode ${vsMode}`);
|
throw new TypeError(`Unknown vsMode ${vsMode}`);
|
||||||
|
|
@ -421,6 +423,7 @@ export class StatInkExporter implements GameExporter {
|
||||||
myTeam,
|
myTeam,
|
||||||
otherTeams,
|
otherTeams,
|
||||||
bankaraMatch,
|
bankaraMatch,
|
||||||
|
leagueMatch,
|
||||||
festMatch,
|
festMatch,
|
||||||
playedTime,
|
playedTime,
|
||||||
} = vsDetail;
|
} = vsDetail;
|
||||||
|
|
@ -563,6 +566,10 @@ export class StatInkExporter implements GameExporter {
|
||||||
result.rank_after_s_plus = result.rank_before_s_plus;
|
result.rank_after_s_plus = result.rank_before_s_plus;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (leagueMatch) {
|
||||||
|
result.event = leagueMatch.leagueMatchEvent?.id;
|
||||||
|
result.event_power = leagueMatch.myLeaguePower;
|
||||||
|
}
|
||||||
|
|
||||||
if (challengeProgress) {
|
if (challengeProgress) {
|
||||||
result.challenge_win = challengeProgress.winCount;
|
result.challenge_win = challengeProgress.winCount;
|
||||||
|
|
|
||||||
29
src/iksm.ts
29
src/iksm.ts
|
|
@ -175,13 +175,14 @@ export async function getGToken(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const uiRespJson = await uiResp.json();
|
const uiRespJson = await uiResp.json();
|
||||||
const { nickname, birthday, language, country } = uiRespJson;
|
const { nickname, birthday, language, country, id: userId } = uiRespJson;
|
||||||
|
|
||||||
const getIdToken2 = async (idToken: string) => {
|
const getIdToken2 = async (idToken: string) => {
|
||||||
const { f, request_id: requestId, timestamp } = await callImink({
|
const { f, request_id: requestId, timestamp } = await callImink({
|
||||||
fApi,
|
fApi,
|
||||||
step: 1,
|
step: 1,
|
||||||
idToken,
|
idToken,
|
||||||
|
userId,
|
||||||
env,
|
env,
|
||||||
});
|
});
|
||||||
const resp = await fetch.post(
|
const resp = await fetch.post(
|
||||||
|
|
@ -210,23 +211,28 @@ export async function getGToken(
|
||||||
);
|
);
|
||||||
const respJson = await resp.json();
|
const respJson = await resp.json();
|
||||||
|
|
||||||
const idToken2 = respJson?.result?.webApiServerCredential?.accessToken;
|
const idToken2: string = respJson?.result?.webApiServerCredential
|
||||||
|
?.accessToken;
|
||||||
|
const coralUserId: number = respJson?.result?.user?.id;
|
||||||
|
|
||||||
if (!idToken2) {
|
if (!idToken2 || !coralUserId) {
|
||||||
throw new APIError({
|
throw new APIError({
|
||||||
response: resp,
|
response: resp,
|
||||||
json: respJson,
|
json: respJson,
|
||||||
message: "No idToken2 found",
|
message:
|
||||||
|
`No idToken2 or coralUserId found. Please try again later. ('${idToken2}', '${coralUserId}')`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return idToken2 as string;
|
return [idToken2, coralUserId] as const;
|
||||||
};
|
};
|
||||||
const getGToken = async (idToken: string) => {
|
const getGToken = async (idToken: string, coralUserId: number) => {
|
||||||
const { f, request_id: requestId, timestamp } = await callImink({
|
const { f, request_id: requestId, timestamp } = await callImink({
|
||||||
step: 2,
|
step: 2,
|
||||||
idToken,
|
idToken,
|
||||||
fApi,
|
fApi,
|
||||||
|
userId,
|
||||||
|
coralUserId,
|
||||||
env,
|
env,
|
||||||
});
|
});
|
||||||
const resp = await fetch.post(
|
const resp = await fetch.post(
|
||||||
|
|
@ -266,8 +272,8 @@ export async function getGToken(
|
||||||
return webServiceToken as string;
|
return webServiceToken as string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const idToken2 = await retry(() => getIdToken2(idToken));
|
const [idToken2, coralUserId] = await retry(() => getIdToken2(idToken));
|
||||||
const webServiceToken = await retry(() => getGToken(idToken2));
|
const webServiceToken = await retry(() => getGToken(idToken2, coralUserId));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
webServiceToken,
|
webServiceToken,
|
||||||
|
|
@ -403,13 +409,16 @@ type IminkResponse = {
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
};
|
};
|
||||||
async function callImink(
|
async function callImink(
|
||||||
{ fApi, step, idToken, env }: {
|
params: {
|
||||||
fApi: string;
|
fApi: string;
|
||||||
step: number;
|
step: number;
|
||||||
idToken: string;
|
idToken: string;
|
||||||
|
userId: string;
|
||||||
|
coralUserId?: number;
|
||||||
env: Env;
|
env: Env;
|
||||||
},
|
},
|
||||||
): Promise<IminkResponse> {
|
): Promise<IminkResponse> {
|
||||||
|
const { fApi, step, idToken, userId, coralUserId, env } = params;
|
||||||
const { post } = env.newFetcher();
|
const { post } = env.newFetcher();
|
||||||
const resp = await post({
|
const resp = await post({
|
||||||
url: fApi,
|
url: fApi,
|
||||||
|
|
@ -420,6 +429,8 @@ async function callImink(
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
"token": idToken,
|
"token": idToken,
|
||||||
"hash_method": step,
|
"hash_method": step,
|
||||||
|
"na_id": userId,
|
||||||
|
"coral_user_id": coralUserId,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
41
src/types.ts
41
src/types.ts
|
|
@ -1,23 +1,8 @@
|
||||||
import { splatNet3Types } from "../deps.ts";
|
import { splatNet3Types } from "../deps.ts";
|
||||||
import { RankState } from "./state.ts";
|
import { RankState } from "./state.ts";
|
||||||
|
import { Queries } from "./constant.ts";
|
||||||
|
export { Queries };
|
||||||
|
|
||||||
export enum Queries {
|
|
||||||
HomeQuery = "22e2fa8294168003c21b00c333c35384",
|
|
||||||
LatestBattleHistoriesQuery = "0176a47218d830ee447e10af4a287b3f",
|
|
||||||
RegularBattleHistoriesQuery = "3baef04b095ad8975ea679d722bc17de",
|
|
||||||
BankaraBattleHistoriesQuery = "0438ea6978ae8bd77c5d1250f4f84803",
|
|
||||||
XBattleHistoriesQuery = "6796e3cd5dc3ebd51864dc709d899fc5",
|
|
||||||
PrivateBattleHistoriesQuery = "8e5ae78b194264a6c230e262d069bd28",
|
|
||||||
VsHistoryDetailQuery = "291295ad311b99a6288fc95a5c4cb2d2",
|
|
||||||
CoopHistoryQuery = "91b917becd2fa415890f5b47e15ffb15",
|
|
||||||
CoopHistoryDetailQuery = "379f0d9b78b531be53044bcac031b34b",
|
|
||||||
myOutfitCommonDataFilteringConditionQuery =
|
|
||||||
"d02ab22c9dccc440076055c8baa0fa7a",
|
|
||||||
myOutfitCommonDataEquipmentsQuery = "d29cd0c2b5e6bac90dd5b817914832f8",
|
|
||||||
HistoryRecordQuery = "f09da9d24d888797fdfb2f060dbdf4ed",
|
|
||||||
ConfigureAnalyticsQuery = "f8ae00773cc412a50dd41a6d9a159ddd",
|
|
||||||
StageRecordQuery = "f08a932d533845dde86e674e03bbb7d3",
|
|
||||||
}
|
|
||||||
export type VarsMap = {
|
export type VarsMap = {
|
||||||
[Queries.HomeQuery]: [];
|
[Queries.HomeQuery]: [];
|
||||||
[Queries.LatestBattleHistoriesQuery]: [];
|
[Queries.LatestBattleHistoriesQuery]: [];
|
||||||
|
|
@ -221,7 +206,13 @@ export type CoopInfo = {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
export type Game = VsInfo | CoopInfo;
|
export type Game = VsInfo | CoopInfo;
|
||||||
export type VsMode = "REGULAR" | "BANKARA" | "PRIVATE" | "FEST" | "X_MATCH";
|
export type VsMode =
|
||||||
|
| "REGULAR"
|
||||||
|
| "BANKARA"
|
||||||
|
| "PRIVATE"
|
||||||
|
| "FEST"
|
||||||
|
| "X_MATCH"
|
||||||
|
| "LEAGUE";
|
||||||
export type VsHistoryDetail = {
|
export type VsHistoryDetail = {
|
||||||
id: string;
|
id: string;
|
||||||
vsRule: {
|
vsRule: {
|
||||||
|
|
@ -252,6 +243,13 @@ export type VsHistoryDetail = {
|
||||||
contribution: number;
|
contribution: number;
|
||||||
myFestPower: number | null;
|
myFestPower: number | null;
|
||||||
} | null;
|
} | null;
|
||||||
|
leagueMatch: {
|
||||||
|
leagueMatchEvent: {
|
||||||
|
"name": string;
|
||||||
|
"id": string;
|
||||||
|
} | null;
|
||||||
|
myLeaguePower: number | null;
|
||||||
|
} | null;
|
||||||
|
|
||||||
myTeam: VsTeam;
|
myTeam: VsTeam;
|
||||||
otherTeams: VsTeam[];
|
otherTeams: VsTeam[];
|
||||||
|
|
@ -770,12 +768,13 @@ export type StatInkPostBody = {
|
||||||
| "xmatch"
|
| "xmatch"
|
||||||
| "splatfest_challenge"
|
| "splatfest_challenge"
|
||||||
| "splatfest_open"
|
| "splatfest_open"
|
||||||
| "private";
|
| "private"
|
||||||
|
| "event";
|
||||||
rule: "nawabari" | "area" | "hoko" | "yagura" | "asari" | "tricolor";
|
rule: "nawabari" | "area" | "hoko" | "yagura" | "asari" | "tricolor";
|
||||||
stage: string;
|
stage: string;
|
||||||
weapon: string;
|
weapon: string;
|
||||||
result: "win" | "lose" | "draw" | "exempted_lose";
|
result: "win" | "lose" | "draw" | "exempted_lose";
|
||||||
knockout?: "yes" | "no"; // for TW, set null or not sending
|
knockout?: "yes" | "no" | null; // for TW, set null or not sending
|
||||||
rank_in_team: number; // position in scoreboard
|
rank_in_team: number; // position in scoreboard
|
||||||
kill?: number;
|
kill?: number;
|
||||||
assist?: number;
|
assist?: number;
|
||||||
|
|
@ -827,6 +826,8 @@ export type StatInkPostBody = {
|
||||||
clout_before?: number; // Splatfest Clout, before the battle
|
clout_before?: number; // Splatfest Clout, before the battle
|
||||||
clout_after?: number; // Splatfest Clout, after the battle
|
clout_after?: number; // Splatfest Clout, after the battle
|
||||||
clout_change?: number; // Splatfest Clout, equals to clout_after - clout_before if you know them
|
clout_change?: number; // Splatfest Clout, equals to clout_after - clout_before if you know them
|
||||||
|
event?: string;
|
||||||
|
event_power?: number | null;
|
||||||
cash_before?: number;
|
cash_before?: number;
|
||||||
cash_after?: number;
|
cash_after?: number;
|
||||||
our_team_players: StatInkPlayer[];
|
our_team_players: StatInkPlayer[];
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue