Limit fresh account queue joining

This commit is contained in:
Kalle
2024-04-14 12:21:47 +03:00
parent 4ecf225a9b
commit 1d7142ca9e
4 changed files with 74 additions and 23 deletions

View File

@@ -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<Group, "status"> & { 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;
}

View File

@@ -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<typeof loader>();
const fetcher = useFetcher();
const queueJoinStatus =
user && data.friendCode ? userCanJoinQueueAt(user, data.friendCode) : null;
return (
<Main halfWidth className="stack lg">
<div className="stack md">
@@ -231,7 +238,7 @@ export default function QPage() {
data.groupInvitedTo.members.length < FULL_GROUP_SIZE ? (
<Alert variation="WARNING">{t("q:front.noFriendCode")}</Alert>
) : null}
{data.friendCode &&
{queueJoinStatus === "NOW" &&
data.groupInvitedTo &&
data.groupInvitedTo.members.length < FULL_GROUP_SIZE ? (
<JoinTeamDialog
@@ -240,7 +247,9 @@ export default function QPage() {
members={data.groupInvitedTo.members}
/>
) : null}
{user ? <FriendCodeInput friendCode={data.friendCode} /> : null}
{user ? (
<FriendCodeInput friendCode={data.friendCode?.friendCode} />
) : null}
{user ? (
<>
<fetcher.Form className="stack md" method="post">
@@ -248,7 +257,7 @@ export default function QPage() {
<div className="stack horizontal md items-center mt-4 mx-auto">
<SubmitButton
icon={<UsersIcon />}
disabled={!data.friendCode}
disabled={queueJoinStatus !== "NOW"}
>
{t("q:front.actions.joinWithGroup")}
</SubmitButton>
@@ -258,12 +267,26 @@ export default function QPage() {
state={fetcher.state}
icon={<UserIcon />}
variant="outlined"
disabled={!data.friendCode}
disabled={queueJoinStatus !== "NOW"}
>
{t("q:front.actions.joinSolo")}
</SubmitButton>
</div>
{!data.friendCode ? (
{queueJoinStatus instanceof Date ? (
<div
className="text-lighter text-xs text-center text-warning"
suppressHydrationWarning
>
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",
})}
</div>
) : !data.friendCode ? (
<div className="text-lighter text-xs text-center text-error">
Save your friend code to join the queue
</div>

View File

@@ -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

View File

@@ -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"]) {