SendouQ Season 2 changes (#1542)

* Initial

* Saves preferences

* Include TW

* mapModePreferencesToModeList

* mapPoolFromPreferences initial

* Preference to map pool

* Adjust seed

* q.looking tests

* adds about created map preferences to memento in the correct spot (two preferrers)

* Failing test about modes

* Mode preferences to memento

* Remove old Plus Voting code

* Fix seeding

* find match by id via kysely

* View map memento

* Fix up map list generation logic

* Mode memento info

* Future match modes

* Add TODO

* Migration number

* Migrate test DB

* Remove old map pool code

* createGroupFromPrevious new

* Settings styling

* VC to settings

* Weapon pool

* Add TODOs

* Progress

* Adjust mode exclusion policy

* Progress

* Progress

* Progress

* Notes in progress

* Note feedback after submit

* Textarea styling

* Unskip tests

* Note sorting failing test

* Private note in Q

* Ownerpicksmaps later

* New bottom section

* Mobile layout initial

* Add basic match meta

* Tabs initial

* Sticky tab

* Unseen messages in match page

* Front page i18n

* Settings i18n

* Looking 18n

* Chat i18n

* Progress

* Tranfer weapon pools script

* Sticky on match page

* Match page translations

* i18n - tiers page

* Preparing page i18n

* Icon

* Show add note right after report
This commit is contained in:
Kalle
2023-11-30 20:57:06 +02:00
committed by GitHub
parent 18bf6dd7bb
commit 7dec8c572e
98 changed files with 4985 additions and 2080 deletions

108
scripts/map-popularity.ts Normal file
View File

@@ -0,0 +1,108 @@
/* eslint-disable no-console */
import "dotenv/config";
import { db } from "~/db/sql";
import type { ModeShort, StageId } from "~/modules/in-game-lists";
import { modesShort, stageIds } from "~/modules/in-game-lists";
import names from "../public/locales/en/game-misc.json";
import { databaseTimestampToDate } from "~/utils/dates";
import { cutToNDecimalPlaces } from "~/utils/number";
import { BANNED_MAPS } from "~/features/sendouq-settings/banned-maps";
async function main() {
const appearance = await db
.selectFrom("MapPoolMap")
.select(({ fn }) => [
"MapPoolMap.stageId",
"MapPoolMap.mode",
fn.countAll<number>().as("count"),
])
.where("MapPoolMap.calendarEventId", "is not", null)
.groupBy(["MapPoolMap.stageId", "MapPoolMap.mode"])
.execute();
const usage: Record<
ModeShort,
{ stageId: StageId; count: number; relativeCount: number }[]
> = {
TW: [],
SZ: [],
TC: [],
RM: [],
CB: [],
};
const ageRow = await db
.selectFrom("Build")
.select((eb) => eb.fn.max("Build.updatedAt").as("age"))
.executeTakeFirstOrThrow();
const dbAgeDate = databaseTimestampToDate(ageRow.age);
for (const mode of modesShort) {
for (const stageId of stageIds) {
const count =
appearance.find((row) => row.stageId === stageId && row.mode === mode)
?.count ?? 0;
const firstAppear = await db
.selectFrom("MapPoolMap")
.innerJoin(
"CalendarEvent",
"MapPoolMap.calendarEventId",
"CalendarEvent.id",
)
.innerJoin(
"CalendarEventDate",
"CalendarEvent.id",
"CalendarEventDate.eventId",
)
.select((eb) =>
eb.fn.min("CalendarEventDate.startTime").as("firstAppear"),
)
.executeTakeFirst();
const firstAppearDate = firstAppear
? databaseTimestampToDate(firstAppear.firstAppear)
: null;
const datesSinceFirstAppear = firstAppearDate
? Math.floor((dbAgeDate.getTime() - firstAppearDate.getTime()) / 864e5)
: null;
usage[mode].push({
stageId,
count,
relativeCount: datesSinceFirstAppear
? cutToNDecimalPlaces((count / datesSinceFirstAppear) * 30, 3)
: 0,
});
}
usage[mode].sort((a, b) => b.relativeCount - a.relativeCount);
}
console.log(`DB Age: ${dbAgeDate.toISOString()}\n`);
for (const mode of modesShort) {
console.log(mode);
let banCount = 0;
for (const [i, { stageId, count, relativeCount }] of usage[
mode
].entries()) {
const name = names[`STAGE_${stageId}`];
const isBanned = BANNED_MAPS[mode].includes(stageId);
if (isBanned) banCount++;
console.log(
`${i < 9 ? " " : ""}${i + 1}) ${
isBanned ? "❌" : " "
} ${name}: ${relativeCount} (${count})`,
);
}
console.log("Banned maps: " + banCount);
console.log();
}
}
void main();

View File

@@ -0,0 +1,48 @@
/* eslint-disable no-console */
import "dotenv/config";
import { db } from "~/db/sql";
async function main() {
const weaponPools = await db
.selectFrom("UserWeapon")
.select([
"UserWeapon.userId",
"UserWeapon.weaponSplId",
"UserWeapon.userId",
])
.where("UserWeapon.order", "!=", 5)
.orderBy("UserWeapon.order asc")
.execute();
// group by userId
const weaponPoolsByUserId = weaponPools.reduce(
(acc, weaponPool) => {
if (!acc[weaponPool.userId]) {
acc[weaponPool.userId] = [];
}
acc[weaponPool.userId].push(weaponPool);
return acc;
},
{} as Record<string, typeof weaponPools>,
);
for (const [userId, weaponPools] of Object.entries(weaponPoolsByUserId)) {
const weaponPoolIds = weaponPools.map(
(weaponPool) => weaponPool.weaponSplId,
);
await db
.updateTable("User")
.set({
qWeaponPool: JSON.stringify(weaponPoolIds),
})
.where("User.id", "=", Number(userId))
.execute();
}
console.log("done with the transfer");
}
void main();