Add skipping plus tier admission from leaderboard

This commit is contained in:
Kalle 2023-11-19 12:59:07 +02:00
parent 350ab574af
commit abf4d0a596
8 changed files with 78 additions and 0 deletions

View File

@ -496,6 +496,7 @@ export interface User {
twitter: string | null;
vc: Generated<string | null>;
youtubeId: string | null;
plusSkippedForSeasonNth: number | null;
}
export interface UserResultHighlight {

View File

@ -140,6 +140,45 @@ PlusVoting(
},
);
PlusVoting(
"skips users from leaderboard with the skip flag for the season",
async () => {
MockDate.set(new Date("2023-11-29T00:00:00.000Z"));
await Test.database.insertUsers(11);
await createLeaderboard(Array.from({ length: 11 }).map((_, i) => i + 1));
await db
.updateTable("User")
.set({ plusSkippedForSeasonNth: 1 })
.where("User.id", "=", 1)
.execute();
await adminAction({ _action: "REFRESH" }, { user: "admin" });
assert.equal(await countPlusTierMembers(1), 10);
assert.equal(await countPlusTierMembers(2), 0);
},
);
PlusVoting("plus server skip flag ignored if for past season", async () => {
MockDate.set(new Date("2023-11-29T00:00:00.000Z"));
await Test.database.insertUsers(11);
await createLeaderboard(Array.from({ length: 11 }).map((_, i) => i + 1));
await db
.updateTable("User")
.set({ plusSkippedForSeasonNth: 0 })
.where("User.id", "=", 1)
.execute();
await adminAction({ _action: "REFRESH" }, { user: "admin" });
assert.equal(await countPlusTierMembers(1), 10);
assert.equal(await countPlusTierMembers(2), 1);
});
PlusVoting("ignores leaderboard while season is ongoing", async () => {
MockDate.set(new Date("2024-02-15T00:00:00.000Z"));

View File

@ -4,6 +4,7 @@ import type { SeasonPopularUsersWeapon } from "../queries/seasonPopularUsersWeap
import type { MainWeaponId } from "~/modules/in-game-lists";
import { weaponCategories } from "~/modules/in-game-lists";
import { seasonHasTopTen } from "../leaderboards-utils";
import { currentOrPreviousSeason } from "~/features/mmr/season";
export function addTiers(entries: UserSPLeaderboardItem[], season: number) {
const tiers = freshUserSkills(season);
@ -53,6 +54,12 @@ export function addPendingPlusTiers<T extends UserSPLeaderboardItem>(
if (!highestPlusTierWithSpace) break;
if (entry.plusTier && entry.plusTier <= highestPlusTierWithSpace) continue;
if (
entry.plusSkippedForSeasonNth === currentOrPreviousSeason(new Date())?.nth
) {
entry.plusSkippedForSeasonNth = null;
continue;
}
entry.pendingPlusTier = highestPlusTierWithSpace;
const key = `+${highestPlusTierWithSpace}` as const;

View File

@ -15,6 +15,7 @@ const stm = sql.prepare(/* sql */ `
"User"."discordAvatar",
"User"."discordId",
"User"."customUrl",
"User"."plusSkippedForSeasonNth",
"PlusTier"."tier" as "plusTier",
rank () over (
order by "Skill"."Ordinal" desc
@ -48,6 +49,7 @@ export interface UserSPLeaderboardItem {
discordId: User["discordId"];
customUrl: User["customUrl"];
plusTier?: PlusTier["tier"];
plusSkippedForSeasonNth: number | null;
/** Plus tier player is on track to join */
pendingPlusTier?: PlusTier["tier"];
placementRank: number;

Binary file not shown.

View File

@ -0,0 +1,5 @@
module.exports.up = function (db) {
db.prepare(
/* sql */ `alter table "User" add "plusSkippedForSeasonNth" integer`,
).run();
};

View File

@ -28,6 +28,7 @@
"delete-user": "node --experimental-specifier-resolution=node --loader ts-node/esm -r tsconfig-paths/register scripts/delete-user.ts",
"ban-user": "node --experimental-specifier-resolution=node --loader ts-node/esm -r tsconfig-paths/register scripts/ban-user.ts",
"delete-skill": "node --experimental-specifier-resolution=node --loader ts-node/esm -r tsconfig-paths/register scripts/delete-skill.ts",
"skip-plus": "node --experimental-specifier-resolution=node --loader ts-node/esm -r tsconfig-paths/register scripts/skip-plus.ts",
"season-initial-powers": "node --experimental-specifier-resolution=node --loader ts-node/esm -r tsconfig-paths/register scripts/season-initial-powers.ts",
"refresh-prod-db": "node --experimental-specifier-resolution=node --loader ts-node/esm -r tsconfig-paths/register scripts/refresh-prod-db.ts && npm run migrate up",
"lint:ts": "eslint . --ext .ts,.tsx",

23
scripts/skip-plus.ts Normal file
View File

@ -0,0 +1,23 @@
/* eslint-disable no-console */
import "dotenv/config";
import invariant from "tiny-invariant";
import { sql } from "~/db/sql";
import { currentOrPreviousSeason } from "~/features/mmr/season";
const discordId = process.argv[2]?.trim();
invariant(discordId, "discord id is required (argument 1)");
const currentSeasonNth = currentOrPreviousSeason(new Date())?.nth;
invariant(currentSeasonNth, "current season nth is required");
sql
.prepare(
'update "User" set plusSkippedForSeasonNth = @plusSkippedForSeasonNth where discordId = @discordId',
)
.run({ discordId, plusSkippedForSeasonNth: currentSeasonNth });
console.log(
`Plus Server admission will be skipped for Discord ID: ${discordId} (season ${currentSeasonNth})`,
);