diff --git a/lib/lists/weapons.ts b/lib/lists/weapons.ts index 4e2380dbb..5ff55f7b0 100644 --- a/lib/lists/weapons.ts +++ b/lib/lists/weapons.ts @@ -144,3 +144,6 @@ export const altWeaponToNormal = new Map([ ]); export const isWeapon = (value: any) => weapons.includes(value); + +export const getWeaponNormalized = (weapon: any) => + altWeaponToNormal.has(weapon) ? altWeaponToNormal.get(weapon) : weapon; diff --git a/pages/api/builds/index.ts b/pages/api/builds/index.ts index 3810e9c83..8c93cca66 100644 --- a/pages/api/builds/index.ts +++ b/pages/api/builds/index.ts @@ -1,7 +1,7 @@ import { Ability } from "@prisma/client"; import { GANBA_DISCORD_ID } from "lib/constants"; import { getMySession } from "lib/getMySession"; -import { altWeaponToNormal } from "lib/lists/weapons"; +import { getWeaponNormalized } from "lib/lists/weapons"; import { buildSchema } from "lib/validators/build"; import { NextApiRequest, NextApiResponse } from "next"; import prisma from "prisma/client"; @@ -29,23 +29,6 @@ const postHandler = async (req: NextApiRequest, res: NextApiResponse) => { .json({ message: "You have too many builds posted already" }); } - const hasTop500WithTheWeapon = async () => { - const playerData = await prisma.player.findFirst({ - where: { userId: user.id }, - include: { placements: true }, - }); - - if (!playerData) return false; - - const weaponNormalized = altWeaponToNormal.has(parsed.data.weapon) - ? altWeaponToNormal.get(parsed.data.weapon) - : parsed.data.weapon; - - return playerData.placements.some( - (placement) => placement.weapon === weaponNormalized - ); - }; - await prisma.build.create({ data: { ...parsed.data, @@ -58,7 +41,7 @@ const postHandler = async (req: NextApiRequest, res: NextApiResponse) => { parsed.data.shoesAbilities ), jpn: postsJpBuilds, - top500: await hasTop500WithTheWeapon(), + top500: await hasTop500WithTheWeapon(user.id, parsed.data.weapon), user: { connect: { id: user.id, @@ -103,6 +86,10 @@ const updateHandler = async (req: NextApiRequest, res: NextApiResponse) => { modes: parsed.data.modes.sort( (a, b) => modes.indexOf(a) - modes.indexOf(b) ), + top500: + parsed.data.weapon === existingBuild.weapon + ? existingBuild.top500 + : await hasTop500WithTheWeapon(user.id, parsed.data.weapon), abilityPoints: getAbilityPoints( parsed.data.headAbilities, parsed.data.clothingAbilities, @@ -148,4 +135,17 @@ function getAbilityPoints( return result; } +async function hasTop500WithTheWeapon(userId: number, weapon: string) { + const playerData = await prisma.player.findFirst({ + where: { userId: userId }, + include: { placements: true }, + }); + + if (!playerData) return false; + + return playerData.placements.some( + (placement) => placement.weapon === getWeaponNormalized(weapon) + ); +} + export default buildHandler; diff --git a/prisma/scripts/top500jsons.ts b/prisma/scripts/top500jsons.ts index 101b00dbc..e8e70b637 100644 --- a/prisma/scripts/top500jsons.ts +++ b/prisma/scripts/top500jsons.ts @@ -1,6 +1,116 @@ +import { Prisma } from "@prisma/client"; +import { getWeaponNormalized } from "../../lib/lists/weapons"; +import prisma from "../client"; +import cb from "./data/october_clam_blitz_2020.json"; +import rm from "./data/october_rainmaker_2020.json"; import sz from "./data/october_splat_zones_2020.json"; -// import tc from "./data/october_tower_control_2020.json"; -// import rm from "./data/october_rainmaker_2020.json"; -// import cb from "./data/october_clam_blitz_2020.json" +import tc from "./data/october_tower_control_2020.json"; -console.log(sz[0]); +const MONTH = 10; +const YEAR = 2020; + +const filterJson = (result: any) => !result.cheater; + +const jsonToInput = ( + result: any, + mode: "SZ" | "TC" | "RM" | "CB", + month: number, + year: number +): Prisma.XRankPlacementCreateInput => ({ + playerName: result.name, + mode, + month, + year, + ranking: result.rank, + xPower: result.x_power, + weapon: getWeaponNormalized(result.weapon.name), + player: { + connectOrCreate: { + create: { + name: result.name, + switchAccountId: result.unique_id, + }, + where: { + switchAccountId: result.unique_id, + }, + }, + }, +}); + +const jsonToWeaponArrMap = (acc: Map, result: any) => { + const weaponArr = acc.get(result.unique_id) ?? []; + acc.set( + result.unique_id, + weaponArr.concat(getWeaponNormalized(result.weapon.name)) + ); + + return acc; +}; + +const main = async () => { + const builds = await prisma.build.findMany({ + where: { + top500: false, + }, + include: { user: { include: { player: true } } }, + }); + + const inputSZ = sz + .filter(filterJson) + .map((json) => jsonToInput(json, "SZ", MONTH, YEAR)); + + const inputTC = tc + .filter(filterJson) + .map((json) => jsonToInput(json, "TC", MONTH, YEAR)); + + const inputRM = rm + .filter(filterJson) + .map((json) => jsonToInput(json, "RM", MONTH, YEAR)); + + const inputCB = cb + .filter(filterJson) + .map((json) => jsonToInput(json, "CB", MONTH, YEAR)); + + const idsToWeapons = [...sz, ...tc, ...rm, ...cb].reduce( + jsonToWeaponArrMap, + new Map() + ); + + const idsToUpdate: number[] = []; + + builds.forEach((build) => { + if (!build.user.player?.switchAccountId) return; + const weaponArr = idsToWeapons.get(build.user.player.switchAccountId); + if (!weaponArr) return; + if (!weaponArr.includes(getWeaponNormalized(build.weapon))) return; + + idsToUpdate.push(build.id); + }); + + const newPlacements = [ + ...inputSZ, + ...inputTC, + ...inputRM, + ...inputCB, + ].map((input) => prisma.xRankPlacement.create({ data: input })); + + await prisma.$transaction([...newPlacements]); + console.log("new placements submitted"); + await prisma.build.updateMany({ + where: { + id: { + in: idsToUpdate, + }, + }, + data: { + top500: true, + }, + }); + console.log("builds updated:", idsToUpdate.length); +}; + +main() + .catch((e) => console.error(e)) + .finally(async () => { + await prisma.$disconnect(); + });