mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-05-11 21:29:09 -05:00
* Read in x rank placements script
* Xsearch initial
* XSearch initial
* XSearch with select
* Add badges
* XSearch player page initial
* Consider only one build by user for popular builds Closes #1312
* Revert "Side nav labels on hover (#1290)"
This reverts commit 6e839c6c2d.
* Added and fixed DAnish translations (#1315)
* Added Danish translations
Added Danish translations for the builds.json file.
Translations for the following variables have been added
stats.count.title # used the Danish word for "average" instead of "stats", as it makes more sense in Danish.
stats.ap.title
stats.percentage.title
stats.all
linkButton.abilityStats
linkButton.popularBuilds
noPopularBuilds
* Added Danish translations
Added Danish translations in the calander.json file
tag.desc.SZ
tag.desc.TW
tag.desc.S1
tag.desc.S2
tag.desc.SR
tag.desc.CARDS
* Added Danish translations
Added Danish translations in the common.json file
The following translations have been added
pages.vods
tag.name.SZ
tag.name.TW
tag.name.S1
tag.name.S2
tag.name.SR
tag.name.CARDS
* Added Danish translations in the faq.json file
Added the following Danish translations in the faq.json file
q7
a7
* Updated the DA/game-misc.json file
Added the names for the 3.0 maps.
* Added Danish translation for team.json
Added the following Danish translations for team.json file
- roles.MIDLINE
Fixed the following translation for the team.json file
- "roles.FRONTLINE": # fixed a typo
* Created a vods.json file for the Danish trans
* Fixed typo
Fixed the following translation in the Da\contributions.json file
"yaga" # fixed a Typo of "våben"
* Add Chinese Translation (#1314)
* Update contributions.json
* Update contributions.json
* Update faq.json
* Update user.json
* Create team.json
* Update common.json
* Update analyzer.json
* Prettier
* Prettier
* Prettier
* Update builds.json
* Update calendar.json
* Update common.json
* Update faq.json
* Update team.json
* Create vods.json
* Admin link player action
* Make PlacementTable rounded if only child
* Fix arrow disappeared
* Placements on user page initial
* Remove S2 site link
* Add badge
* Add feature to README
* Fix type error
* Different badge text if XP badge
* Add badge winners script
* Better user avatar + name wrapping for mobile
* Allow script to skip users
* Fix bad align when no weapons in weapon pool
* Add aliases to player name
* Add division icon to placements table
* Link to user page
* Link to xsearch on player details page
* Top 500 icons to user build page
* Working query but slow for weapons page
* Fix lint complaints
* Add cache to builds
* Remove useless SWR value
* Group months in xsearch
* Add xsearch to nav
* Add meta
* Remove TW for now
* Add splatoon3.ink as contributor
* Remove unneeded TODO
* Fix TODOs related to fetching monthYears
* Add FAQ question
* Leaderboards to nav
* Fix sploosh build stat pages returning 404
* Add badge
* Add article
* Patch 3.1
* Fix Prettier issue
* Add badge
* Add April SR gear
* Add badges
* Rename badge
* Add badge
* Add zh badge translation (#1322)
* Splatoon Competitive Guide article (#1316)
* Create splatoon-competitive-guide.md
* Update splatoon-competitive-guide.md
* Fix ToC Issues
* Update splatoon-competitive-guide.md
* Update splatoon-competitive-guide.md
* Update splatoon-competitive-guide.md
* Corrections
* Formatting
---------
Co-authored-by: Kalle <38327916+Sendouc@users.noreply.github.com>
* Fix typos
* Rename table and adjust columns
* Make cache ttl 0 in dev
* Make placements container a bit nicer for mobile
* Rename leftover xxx
* Placements script allow passing number as arg
* Skip leaderboards for now
* Add translations
* Rename placements folder to top-search
* Add placements to seed
* Add E2E tests
* Read in x rank placements script
* Xsearch initial
* XSearch initial
* XSearch with select
* XSearch player page initial
* Admin link player action
* Make PlacementTable rounded if only child
* Fix arrow disappeared
* Placements on user page initial
* Fix bad align when no weapons in weapon pool
* Add aliases to player name
* Add division icon to placements table
* Link to user page
* Link to xsearch on player details page
* Top 500 icons to user build page
* Working query but slow for weapons page
* Fix lint complaints
* Add cache to builds
* Remove useless SWR value
* Group months in xsearch
* Add xsearch to nav
* Add meta
* Remove TW for now
* Add splatoon3.ink as contributor
* Remove unneeded TODO
* Fix TODOs related to fetching monthYears
* Add FAQ question
* Leaderboards to nav
* Fix sploosh build stat pages returning 404
* Rename table and adjust columns
* Make cache ttl 0 in dev
* Make placements container a bit nicer for mobile
* Rename leftover xxx
* Placements script allow passing number as arg
* Skip leaderboards for now
* Add translations
* Rename placements folder to top-search
* Add placements to seed
* Add E2E tests
* Rename url variable and unify
* Tweaks
---------
Co-authored-by: Frederik <112972665+FrederikFraJylland@users.noreply.github.com>
Co-authored-by: Gell <61431488+gellneko@users.noreply.github.com>
Co-authored-by: Zen <99558412+zenpk@users.noreply.github.com>
Co-authored-by: Teddi <83455454+teddinotteddy@users.noreply.github.com>
183 lines
4.4 KiB
TypeScript
183 lines
4.4 KiB
TypeScript
/* eslint-disable no-console */
|
|
import "dotenv/config";
|
|
|
|
import invariant from "tiny-invariant";
|
|
import { sql } from "~/db/sql";
|
|
import type { XRankPlacement } from "~/db/types";
|
|
import { type MainWeaponId, mainWeaponIds } from "~/modules/in-game-lists";
|
|
import { xRankSchema } from "./schemas";
|
|
|
|
const rawJsonNumber = process.argv[2]?.trim();
|
|
invariant(rawJsonNumber, "jsonNumber is required (argument 1)");
|
|
const jsonNumber = Number(rawJsonNumber);
|
|
invariant(
|
|
Number.isInteger(jsonNumber),
|
|
"jsonNumber must be an integer (argument 1)"
|
|
);
|
|
|
|
type Placements = Array<
|
|
Omit<XRankPlacement, "playerId" | "id"> & { playerSplId: string }
|
|
>;
|
|
|
|
const modes = ["splatzones", "towercontrol", "rainmaker", "clamblitz"] as const;
|
|
const modeToShort = {
|
|
splatzones: "SZ",
|
|
towercontrol: "TC",
|
|
rainmaker: "RM",
|
|
clamblitz: "CB",
|
|
} as const;
|
|
const regions = ["a", "p"] as const;
|
|
|
|
void main();
|
|
|
|
async function main() {
|
|
const placements: Placements = [];
|
|
|
|
for (const mode of modes) {
|
|
for (const region of regions) {
|
|
for (const includeWeapon of [false]) {
|
|
placements.push(
|
|
...(await processJson({
|
|
includeWeapon,
|
|
mode,
|
|
region,
|
|
number: jsonNumber,
|
|
}))
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
addPlacements(placements);
|
|
console.log(`done reading in ${placements.length} placements`);
|
|
}
|
|
|
|
async function processJson(args: {
|
|
mode: (typeof modes)[number];
|
|
region: (typeof regions)[number];
|
|
includeWeapon: boolean;
|
|
number: number;
|
|
}) {
|
|
const result: Placements = [];
|
|
|
|
const url = `https://splatoon3.ink/data/xrank/xrank.detail.${args.region}-${
|
|
args.number
|
|
}.${args.mode}${args.includeWeapon ? ".weapons" : ""}.json`;
|
|
|
|
console.log(`reading in ${url}...`);
|
|
|
|
const json = await fetch(url).then((res) => res.json());
|
|
const validated = xRankSchema.parse(json);
|
|
|
|
const array =
|
|
validated.data.node.xRankingAr ??
|
|
validated.data.node.xRankingCl ??
|
|
validated.data.node.xRankingLf ??
|
|
validated.data.node.xRankingGl;
|
|
invariant(array, "array is null");
|
|
|
|
for (const { node: placement } of array.edges) {
|
|
const weaponId = Number(atob(placement.weapon.id).replace("Weapon-", ""));
|
|
if (!mainWeaponIds.includes(weaponId as MainWeaponId)) {
|
|
throw new Error(`Invalid weapon ID: ${weaponId}`);
|
|
}
|
|
|
|
const { month, year } = resolveMonthYear(args.number);
|
|
|
|
result.push({
|
|
name: placement.name,
|
|
badges: placement.nameplate.badges
|
|
.map((badge) => atob(badge.id).replace("Badge-", ""))
|
|
.join(","),
|
|
bannerSplId: Number(
|
|
atob(placement.nameplate.background.id).replace(
|
|
"NameplateBackground-",
|
|
""
|
|
)
|
|
),
|
|
nameDiscriminator: placement.nameId,
|
|
power: placement.xPower,
|
|
rank: placement.rank,
|
|
region: args.region === "p" ? "JPN" : "WEST",
|
|
title: placement.byname,
|
|
weaponSplId: weaponId as MainWeaponId,
|
|
month,
|
|
year,
|
|
mode: modeToShort[args.mode],
|
|
playerSplId: parsePlayerId(placement.id),
|
|
});
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function parsePlayerId(encoded: string) {
|
|
const parts = atob(encoded).split("-");
|
|
const last = parts[parts.length - 1];
|
|
invariant(last, "last is null");
|
|
|
|
return last;
|
|
}
|
|
|
|
function resolveMonthYear(number: number) {
|
|
const start = new Date("2023-03-15");
|
|
// 2 is the first X Rank month
|
|
// 3 is the length of x rank season
|
|
const monthsToAdd = (number - 2) * 3;
|
|
|
|
start.setMonth(start.getMonth() + monthsToAdd);
|
|
|
|
return {
|
|
month: start.getMonth() + 1,
|
|
year: start.getFullYear(),
|
|
};
|
|
}
|
|
|
|
const addPlayerStm = sql.prepare(/* sql */ `
|
|
insert into "SplatoonPlayer" ("splId")
|
|
values (@splId)
|
|
on conflict ("splId") do nothing
|
|
`);
|
|
|
|
const addPlacementStm = sql.prepare(/* sql */ `
|
|
insert into "XRankPlacement" (
|
|
"weaponSplId",
|
|
"name",
|
|
"nameDiscriminator",
|
|
"power",
|
|
"rank",
|
|
"title",
|
|
"badges",
|
|
"bannerSplId",
|
|
"playerId",
|
|
"month",
|
|
"year",
|
|
"region",
|
|
"mode"
|
|
)
|
|
values (
|
|
@weaponSplId,
|
|
@name,
|
|
@nameDiscriminator,
|
|
@power,
|
|
@rank,
|
|
@title,
|
|
@badges,
|
|
@bannerSplId,
|
|
(select "id" from "SplatoonPlayer" where "splId" = @playerSplId),
|
|
@month,
|
|
@year,
|
|
@region,
|
|
@mode
|
|
)
|
|
`);
|
|
|
|
function addPlacements(placements: Placements) {
|
|
sql.transaction(() => {
|
|
for (const placement of placements) {
|
|
addPlayerStm.run({ splId: placement.playerSplId });
|
|
addPlacementStm.run(placement);
|
|
}
|
|
})();
|
|
}
|