From 1d7142ca9e1eb83e68061e4478bdcc603a16d569 Mon Sep 17 00:00:00 2001 From: Kalle <38327916+Sendouc@users.noreply.github.com> Date: Sun, 14 Apr 2024 12:21:47 +0300 Subject: [PATCH] Limit fresh account queue joining --- app/features/sendouq/q-utils.ts | 26 ++++++++++ app/features/sendouq/routes/q.tsx | 49 ++++++++++++++----- app/features/tournament/routes/to.$id.tsx | 2 +- .../user-page/UserRepository.server.ts | 20 ++++---- 4 files changed, 74 insertions(+), 23 deletions(-) diff --git a/app/features/sendouq/q-utils.ts b/app/features/sendouq/q-utils.ts index 9d2c08d3b..63fc2bc20 100644 --- a/app/features/sendouq/q-utils.ts +++ b/app/features/sendouq/q-utils.ts @@ -11,6 +11,8 @@ import { stageIds } from "~/modules/in-game-lists"; import type { Params } from "@remix-run/react"; import invariant from "tiny-invariant"; import type { MapPool } from "../map-list-generator/core/map-pool"; +import { accountCreatedInTheLastSixMonths } from "~/utils/users"; +import { databaseTimestampToDate } from "~/utils/dates"; function groupRedirectLocation( group?: Pick & { matchId?: number }, @@ -87,3 +89,27 @@ export function winnersArrayToWinner(winners: ("ALPHA" | "BRAVO")[]) { return null; } + +export function userCanJoinQueueAt( + user: { id: number; discordId: string }, + friendCode: { createdAt: number; submitterUserId: number }, +) { + if (!accountCreatedInTheLastSixMonths(user.discordId)) return "NOW"; + + // set by admin + if (friendCode.submitterUserId !== user.id) return "NOW"; + + const friendCodeCreatedAt = databaseTimestampToDate(friendCode.createdAt); + + const twentyFourHoursAgo = new Date(); + twentyFourHoursAgo.setDate(twentyFourHoursAgo.getDate() - 1); + + if (friendCodeCreatedAt < twentyFourHoursAgo) { + return "NOW"; + } + + const canJoinQueueAt = new Date(friendCodeCreatedAt); + canJoinQueueAt.setDate(canJoinQueueAt.getDate() + 1); + + return canJoinQueueAt; +} diff --git a/app/features/sendouq/routes/q.tsx b/app/features/sendouq/routes/q.tsx index b16aaf21c..ff65baf09 100644 --- a/app/features/sendouq/routes/q.tsx +++ b/app/features/sendouq/routes/q.tsx @@ -25,7 +25,7 @@ import { UsersIcon } from "~/components/icons/Users"; import { sql } from "~/db/sql"; import type { GroupMember } from "~/db/types"; import { useUser } from "~/features/auth/core/user"; -import { getUserId, requireUserId } from "~/features/auth/core/user.server"; +import { getUserId, requireUser } from "~/features/auth/core/user.server"; import type { RankingSeason } from "~/features/mmr/season"; import { currentSeason, nextSeason } from "~/features/mmr/season"; import * as QRepository from "~/features/sendouq/QRepository.server"; @@ -58,7 +58,10 @@ import { import { isAtLeastFiveDollarTierPatreon } from "~/utils/users"; import { FULL_GROUP_SIZE, JOIN_CODE_SEARCH_PARAM_KEY } from "../q-constants"; import { frontPageSchema } from "../q-schemas.server"; -import { groupRedirectLocationByCurrentLocation } from "../q-utils"; +import { + groupRedirectLocationByCurrentLocation, + userCanJoinQueueAt, +} from "../q-utils"; import { addMember } from "../queries/addMember.server"; import { deleteLikesByGroupId } from "../queries/deleteLikesByGroupId.server"; import { findCurrentGroupByUserId } from "../queries/findCurrentGroupByUserId.server"; @@ -86,17 +89,18 @@ export const meta: MetaFunction = () => { ]; }; -const validateCanJoinQ = async (user: { id: number }) => { +const validateCanJoinQ = async (user: { id: number; discordId: string }) => { + const friendCode = await UserRepository.currentFriendCodeByUserId(user.id); + validate(friendCode, "No friend code"); + const canJoinQueue = userCanJoinQueueAt(user, friendCode) === "NOW"; + validate(currentSeason(new Date()), "Season is not active"); validate(!findCurrentGroupByUserId(user.id), "Already in a group"); - validate( - await UserRepository.currentFriendCodeByUserId(user.id), - "No friend code", - ); + validate(canJoinQueue, "Can't join queue right now"); }; export const action: ActionFunction = async ({ request }) => { - const user = await requireUserId(request); + const user = await requireUser(request); const data = await parseRequestFormData({ request, schema: frontPageSchema, @@ -211,6 +215,9 @@ export default function QPage() { const data = useLoaderData(); const fetcher = useFetcher(); + const queueJoinStatus = + user && data.friendCode ? userCanJoinQueueAt(user, data.friendCode) : null; + return (
@@ -231,7 +238,7 @@ export default function QPage() { data.groupInvitedTo.members.length < FULL_GROUP_SIZE ? ( {t("q:front.noFriendCode")} ) : null} - {data.friendCode && + {queueJoinStatus === "NOW" && data.groupInvitedTo && data.groupInvitedTo.members.length < FULL_GROUP_SIZE ? ( ) : null} - {user ? : null} + {user ? ( + + ) : null} {user ? ( <> @@ -248,7 +257,7 @@ export default function QPage() {
} - disabled={!data.friendCode} + disabled={queueJoinStatus !== "NOW"} > {t("q:front.actions.joinWithGroup")} @@ -258,12 +267,26 @@ export default function QPage() { state={fetcher.state} icon={} variant="outlined" - disabled={!data.friendCode} + disabled={queueJoinStatus !== "NOW"} > {t("q:front.actions.joinSolo")}
- {!data.friendCode ? ( + {queueJoinStatus instanceof Date ? ( +
+ As a fresh account please wait before joining the queue. You + can join{" "} + {queueJoinStatus.toLocaleString("en-US", { + day: "numeric", + month: "long", + hour: "numeric", + minute: "numeric", + })} +
+ ) : !data.friendCode ? (
Save your friend code to join the queue
diff --git a/app/features/tournament/routes/to.$id.tsx b/app/features/tournament/routes/to.$id.tsx index 2d4c0a78c..ba4940f2d 100644 --- a/app/features/tournament/routes/to.$id.tsx +++ b/app/features/tournament/routes/to.$id.tsx @@ -201,7 +201,7 @@ export default function TournamentLayout() { bracketExpanded, setBracketExpanded, streamingParticipants: data.streamingParticipants, - friendCode: data.friendCode, + friendCode: data.friendCode?.friendCode, friendCodes: data.friendCodes, toSetMapPool: data.toSetMapPool, } satisfies TournamentContext diff --git a/app/features/user-page/UserRepository.server.ts b/app/features/user-page/UserRepository.server.ts index 01f096ca4..885c7201e 100644 --- a/app/features/user-page/UserRepository.server.ts +++ b/app/features/user-page/UserRepository.server.ts @@ -346,15 +346,17 @@ export function searchExact(args: { } export async function currentFriendCodeByUserId(userId: number) { - return ( - await db - .selectFrom("UserFriendCode") - .select("UserFriendCode.friendCode") - .where("userId", "=", userId) - .orderBy("UserFriendCode.createdAt desc") - .limit(1) - .executeTakeFirst() - )?.friendCode; + return db + .selectFrom("UserFriendCode") + .select([ + "UserFriendCode.friendCode", + "UserFriendCode.createdAt", + "UserFriendCode.submitterUserId", + ]) + .where("userId", "=", userId) + .orderBy("UserFriendCode.createdAt desc") + .limit(1) + .executeTakeFirst(); } export function insertFriendCode(args: TablesInsertable["UserFriendCode"]) {