- Added game settings - Reworked GamePropsSchema for only relevant information -> Prisma schema and zod object - Imporved toast notifications - No duplicate socket connections anymore - Using now Zustand for the gameProps instead of React Context & State
129 lines
2.8 KiB
TypeScript
129 lines
2.8 KiB
TypeScript
import { authOptions } from "../auth/[...nextauth]"
|
|
import sendResponse from "@backend/sendResponse"
|
|
import { rejectionErrors } from "@lib/backend/errors"
|
|
import { getPayloadwithChecksum } from "@lib/getObjectChecksum"
|
|
import prisma from "@lib/prisma"
|
|
import { GamePropsSchema } from "@lib/zodSchemas"
|
|
import type { NextApiRequest, NextApiResponse } from "next"
|
|
import { getServerSession } from "next-auth"
|
|
|
|
export const gameSelects = {
|
|
select: {
|
|
id: true,
|
|
allowChat: true,
|
|
allowMarkDraw: true,
|
|
allowSpecials: true,
|
|
allowSpectators: true,
|
|
state: true,
|
|
gamePin: {
|
|
select: {
|
|
pin: true,
|
|
},
|
|
},
|
|
users: {
|
|
select: {
|
|
id: true,
|
|
index: true,
|
|
chats: {
|
|
select: {
|
|
id: true,
|
|
event: true,
|
|
message: true,
|
|
createdAt: true,
|
|
},
|
|
},
|
|
moves: {
|
|
select: {
|
|
id: true,
|
|
index: true,
|
|
},
|
|
},
|
|
user: {
|
|
select: {
|
|
name: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
export const getAnyGame = (gameId: string) => {
|
|
const game = prisma.game.findFirst({
|
|
where: {
|
|
NOT: {
|
|
state: "ended",
|
|
},
|
|
id: gameId,
|
|
},
|
|
...gameSelects,
|
|
})
|
|
return game
|
|
}
|
|
|
|
export const getAnyRunningGame = (userId: string) => {
|
|
const game = prisma.game.findFirst({
|
|
where: {
|
|
NOT: {
|
|
state: "ended",
|
|
},
|
|
users: {
|
|
some: {
|
|
userId,
|
|
},
|
|
},
|
|
},
|
|
...gameSelects,
|
|
})
|
|
return game
|
|
}
|
|
|
|
export function composeBody(
|
|
gameDB: NonNullable<Awaited<ReturnType<typeof getAnyRunningGame>>>
|
|
): GamePropsSchema {
|
|
const { gamePin, ...game } = gameDB
|
|
const users = gameDB.users.map(({ user, ...props }) => ({
|
|
...props,
|
|
...user,
|
|
}))
|
|
const player1 = users.find((user) => user.index === "player1")
|
|
const player2 = users.find((user) => user.index === "player2")
|
|
const payload = {
|
|
game: game,
|
|
gamePin: gamePin?.pin ?? null,
|
|
player1: player1 ?? null,
|
|
player2: player2 ?? null,
|
|
}
|
|
return getPayloadwithChecksum(payload)
|
|
}
|
|
|
|
export default async function running(
|
|
req: NextApiRequest,
|
|
res: NextApiResponse<GamePropsSchema>
|
|
) {
|
|
const session = await getServerSession(req, res, authOptions)
|
|
|
|
if (!session?.user) {
|
|
return sendResponse(req, res, rejectionErrors.unauthorized)
|
|
}
|
|
|
|
const { email, id } = session.user
|
|
|
|
const game = await getAnyRunningGame(id)
|
|
|
|
if (!game)
|
|
return sendResponse(req, res, {
|
|
message: `User <${email}> is in no game.`,
|
|
statusCode: 204,
|
|
type: ["debug", "infoCyan"],
|
|
})
|
|
|
|
const body = composeBody(game)
|
|
|
|
return sendResponse(req, res, {
|
|
message: `User <${email}> asked for game: ${game.id}`,
|
|
statusCode: 200,
|
|
body,
|
|
type: ["debug", "infoCyan"],
|
|
})
|
|
}
|