Game settings and better socket performance
- 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
This commit is contained in:
parent
12295b316f
commit
61ae4b901d
31 changed files with 652 additions and 350 deletions
|
@ -2,7 +2,7 @@
|
|||
// import FogImages from './FogImages'
|
||||
import Labeling from "./Labeling"
|
||||
import Ships from "./Ships"
|
||||
import useGameEvent from "@lib/hooks/useGameEvent"
|
||||
import useGameEvent from "@hooks/useGameEvent"
|
||||
import { CSSProperties } from "react"
|
||||
|
||||
function Gamefield() {
|
||||
|
|
|
@ -2,32 +2,17 @@ import Icon from "./Icon"
|
|||
import Player from "./Player"
|
||||
import { faSpinnerThird } from "@fortawesome/pro-solid-svg-icons"
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||
import useGameState from "@lib/hooks/useGameState"
|
||||
import useSocket from "@lib/hooks/useSocket"
|
||||
import { useGameProps } from "@hooks/useGameProps"
|
||||
import useSocket from "@hooks/useSocket"
|
||||
import { useRouter } from "next/router"
|
||||
import { Fragment, useEffect, useState } from "react"
|
||||
import { toast } from "react-toastify"
|
||||
|
||||
function LobbyFrame({ openSettings }: { openSettings: () => void }) {
|
||||
const { payload } = useGameState().gameProps
|
||||
const { isConnected, hasJoined } = useSocket()
|
||||
const { payload } = useGameProps()
|
||||
const [dots, setDots] = useState(3)
|
||||
const { isConnected } = useSocket()
|
||||
const router = useRouter()
|
||||
|
||||
useEffect(() => {
|
||||
if (isConnected && hasJoined) return
|
||||
const timeout = setTimeout(() => {
|
||||
toast("Es konnte keine Echtzeitverbindung aufgebaute werden.", {
|
||||
toastId: "connection_error",
|
||||
type: "error",
|
||||
autoClose: 10000,
|
||||
})
|
||||
router.push("/start")
|
||||
}, 15000)
|
||||
|
||||
return () => clearTimeout(timeout)
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (payload?.player2) return
|
||||
const interval = setInterval(() => setDots((e) => (e % 3) + 1), 1000)
|
||||
|
@ -41,7 +26,7 @@ function LobbyFrame({ openSettings }: { openSettings: () => void }) {
|
|||
<h1 className="font-farro text-5xl font-medium">
|
||||
Game-PIN:{" "}
|
||||
{isConnected ? (
|
||||
<span className="underline">{payload?.gamePin?.pin ?? "---"}</span>
|
||||
<span className="underline">{payload?.gamePin ?? "----"}</span>
|
||||
) : (
|
||||
<FontAwesomeIcon icon={faSpinnerThird} spin={true} />
|
||||
)}
|
||||
|
@ -65,7 +50,7 @@ function LobbyFrame({ openSettings }: { openSettings: () => void }) {
|
|||
/>
|
||||
) : (
|
||||
<p className="font-farro w-96 text-center text-4xl font-medium">
|
||||
Warte auf {isConnected && hasJoined ? "Spieler 2" : "Verbindung"}{" "}
|
||||
Warte auf {isConnected ? "Spieler 2" : "Verbindung"}{" "}
|
||||
{Array.from(Array(dots), () => ".").join("")}
|
||||
{Array.from(Array(3 - dots), (_, i) => (
|
||||
<Fragment key={i}> </Fragment>
|
||||
|
@ -74,7 +59,10 @@ function LobbyFrame({ openSettings }: { openSettings: () => void }) {
|
|||
)}
|
||||
</div>
|
||||
<div className="flex items-center justify-center border-t-2 border-slate-900">
|
||||
<button className="font-farro m-4 rounded-xl border-b-4 border-orange-400 bg-warn px-12 py-4 text-5xl font-medium duration-100 active:border-t-4 active:border-b-0">
|
||||
<button
|
||||
className="font-farro m-4 rounded-xl border-b-4 border-orange-400 bg-warn px-12 py-4 text-5xl font-medium duration-100 active:border-t-4 active:border-b-0"
|
||||
onClick={() => router.push("/")}
|
||||
>
|
||||
START
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -3,38 +3,69 @@ import {
|
|||
faToggleLargeOn,
|
||||
} from "@fortawesome/pro-solid-svg-icons"
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||
import { useGameProps } from "@hooks/useGameProps"
|
||||
import { socket } from "@lib/socket"
|
||||
import classNames from "classnames"
|
||||
import { ReactNode, useMemo } from "react"
|
||||
import { toast } from "react-toastify"
|
||||
|
||||
type GameSettingKeys =
|
||||
| "allowSpectators"
|
||||
| "allowSpecials"
|
||||
| "allowChat"
|
||||
| "allowMarkDraw"
|
||||
|
||||
export type GameSettings = { [key in GameSettingKeys]?: boolean }
|
||||
|
||||
export const gameSetting = (payload: GameSettings) => {
|
||||
socket.emit("gameSetting", payload, ({ ack }) => {
|
||||
if (ack) return
|
||||
toast.warn("Something is wrong... ", {
|
||||
toastId: "st_wrong",
|
||||
theme: "colored",
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function Setting({
|
||||
props: { key, state, onClick },
|
||||
children,
|
||||
prop,
|
||||
}: {
|
||||
props: {
|
||||
key: string
|
||||
state: boolean
|
||||
onClick: () => void
|
||||
}
|
||||
children: ReactNode
|
||||
prop: GameSettingKeys
|
||||
}) {
|
||||
const { payload, setSetting } = useGameProps()
|
||||
const state = useMemo(() => payload?.game?.[prop], [payload?.game, prop])
|
||||
|
||||
return (
|
||||
<label className="flex items-center justify-between" htmlFor={key}>
|
||||
<label className="flex items-center justify-between" htmlFor={prop}>
|
||||
<span className="col-span-2 w-96 select-none text-5xl text-white drop-shadow-md">
|
||||
{key}
|
||||
{children}
|
||||
</span>
|
||||
<FontAwesomeIcon
|
||||
className={classNames(
|
||||
"text-md mx-auto w-24 rounded-full px-4 drop-shadow-md transition-all",
|
||||
"text-md mx-auto rounded-full px-4 drop-shadow-md transition-all",
|
||||
state ? "text-blue-500" : "text-gray-800",
|
||||
{
|
||||
"bg-gray-300 ": state,
|
||||
}
|
||||
)}
|
||||
size="3x"
|
||||
icon={state ? faToggleLargeOn : faToggleLargeOff}
|
||||
/>
|
||||
<input
|
||||
className="bg-none"
|
||||
checked={state}
|
||||
type="checkbox"
|
||||
id={key}
|
||||
onChange={onClick}
|
||||
id={prop}
|
||||
onChange={() => {
|
||||
const payload = {
|
||||
[prop]: !state,
|
||||
}
|
||||
|
||||
setSetting(payload)
|
||||
gameSetting(payload)
|
||||
}}
|
||||
hidden={true}
|
||||
/>
|
||||
</label>
|
||||
|
|
|
@ -1,18 +1,12 @@
|
|||
import Setting from "./Setting"
|
||||
import Setting, { gameSetting } from "./Setting"
|
||||
import { faRotateLeft } from "@fortawesome/pro-regular-svg-icons"
|
||||
import { faXmark } from "@fortawesome/pro-solid-svg-icons"
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||
import { useState } from "react"
|
||||
|
||||
const settingOptionsInit: { [key: string]: boolean } = {
|
||||
allowSpectators: false,
|
||||
allowSpecials: false,
|
||||
allowChat: false,
|
||||
allowMarkDraw: false,
|
||||
}
|
||||
import { useGameProps } from "@hooks/useGameProps"
|
||||
|
||||
function Settings({ closeSettings }: { closeSettings: () => void }) {
|
||||
const [settingOptions, setSettingOptions] = useState(settingOptionsInit)
|
||||
const { payload, setSetting } = useGameProps()
|
||||
|
||||
return (
|
||||
<div className="absolute inset-0 flex flex-col items-center justify-center bg-black/40">
|
||||
<div className="w-full max-w-screen-lg">
|
||||
|
@ -27,6 +21,7 @@ function Settings({ closeSettings }: { closeSettings: () => void }) {
|
|||
>
|
||||
<FontAwesomeIcon
|
||||
className="h-full w-full text-gray-800 drop-shadow-md"
|
||||
size="3x"
|
||||
icon={faXmark}
|
||||
/>
|
||||
</button>
|
||||
|
@ -35,21 +30,29 @@ function Settings({ closeSettings }: { closeSettings: () => void }) {
|
|||
<div className="flex items-center justify-end">
|
||||
<button
|
||||
className="top-8 right-12 h-14 w-14"
|
||||
onClick={() => setSettingOptions(settingOptionsInit)}
|
||||
onClick={() => {
|
||||
const payload = {
|
||||
allowSpectators: true,
|
||||
allowSpecials: true,
|
||||
allowChat: true,
|
||||
allowMarkDraw: true,
|
||||
}
|
||||
setSetting(payload)
|
||||
gameSetting(payload)
|
||||
}}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
className="h-full w-full text-gray-800 drop-shadow-md"
|
||||
size="3x"
|
||||
icon={faRotateLeft}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex flex-col gap-8">
|
||||
{Object.keys(settingOptions).map((key) => {
|
||||
const state = settingOptions[key]
|
||||
const onClick = () =>
|
||||
setSettingOptions((e) => ({ ...e, [key]: !e[key] }))
|
||||
return <Setting key={key} props={{ key, state, onClick }} />
|
||||
})}
|
||||
<Setting prop="allowSpectators">Erlaube Zuschauer</Setting>
|
||||
<Setting prop="allowSpecials">Erlaube spezial Items</Setting>
|
||||
<Setting prop="allowChat">Erlaube den Chat</Setting>
|
||||
<Setting prop="allowMarkDraw">Erlaube zeichen/makieren</Setting>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
13
leaky-ships/components/profileImg.tsx
Normal file
13
leaky-ships/components/profileImg.tsx
Normal file
|
@ -0,0 +1,13 @@
|
|||
import React from "react"
|
||||
|
||||
function profileImg(src: string) {
|
||||
return (
|
||||
<img
|
||||
style={{ transform: "scale(1.5)", borderRadius: "100%" }}
|
||||
src={src}
|
||||
alt="profile picture"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default profileImg
|
|
@ -1,22 +1,22 @@
|
|||
import BorderTiles from "../../components/Gamefield/BorderTiles"
|
||||
import EventBar from "../../components/Gamefield/EventBar"
|
||||
import type { PointerProps } from "../../components/Gamefield/GamefieldPointer"
|
||||
import HitElems from "../../components/Gamefield/HitElems"
|
||||
import Targets from "../../components/Gamefield/Targets"
|
||||
import {
|
||||
Hit,
|
||||
Mode,
|
||||
MouseCursor,
|
||||
Target,
|
||||
Position,
|
||||
} from "../../interfaces/frontend"
|
||||
} from "../interfaces/frontend"
|
||||
import BorderTiles from "@components/Gamefield/BorderTiles"
|
||||
import EventBar from "@components/Gamefield/EventBar"
|
||||
import type { PointerProps } from "@components/Gamefield/GamefieldPointer"
|
||||
import HitElems from "@components/Gamefield/HitElems"
|
||||
import Targets from "@components/Gamefield/Targets"
|
||||
import {
|
||||
hitReducer,
|
||||
initlialLastLeftTile,
|
||||
initlialTarget,
|
||||
initlialTargetPreview,
|
||||
initlialMouseCursor,
|
||||
} from "../utils/helpers"
|
||||
} from "@lib/utils/helpers"
|
||||
import { useCallback, useEffect, useReducer, useState } from "react"
|
||||
|
||||
const modes: Mode[] = [
|
58
leaky-ships/hooks/useGameProps.ts
Normal file
58
leaky-ships/hooks/useGameProps.ts
Normal file
|
@ -0,0 +1,58 @@
|
|||
import { GameSettings } from "@components/Lobby/SettingsFrame/Setting"
|
||||
import { GamePropsSchema } from "@lib/zodSchemas"
|
||||
import { produce } from "immer"
|
||||
import { create } from "zustand"
|
||||
import { devtools } from "zustand/middleware"
|
||||
|
||||
const initialState: GamePropsSchema = { payload: null, hash: null }
|
||||
|
||||
type State = GamePropsSchema
|
||||
|
||||
type Action = {
|
||||
setSetting: (by: GameSettings) => void
|
||||
full: (newProps: GamePropsSchema) => void
|
||||
reset: () => void
|
||||
}
|
||||
|
||||
export const useGameProps = create<State & Action>()(
|
||||
devtools(
|
||||
(set) => ({
|
||||
...initialState,
|
||||
setSetting: (settings) =>
|
||||
set(
|
||||
produce((state: State) => {
|
||||
if (!state.payload?.game) return
|
||||
Object.assign(state.payload.game, settings)
|
||||
})
|
||||
),
|
||||
full: (newGameProps) =>
|
||||
set((state) => {
|
||||
if (state.hash === newGameProps.hash) {
|
||||
console.log("Everything up to date.")
|
||||
} else {
|
||||
console.log("Update was needed.", state.hash, newGameProps.hash)
|
||||
|
||||
if (
|
||||
state.payload?.game?.id &&
|
||||
state.payload?.game?.id !== newGameProps.payload?.game?.id
|
||||
) {
|
||||
console.warn(
|
||||
"Different gameId detected on update: ",
|
||||
state.payload?.game?.id,
|
||||
newGameProps.payload?.game?.id
|
||||
)
|
||||
}
|
||||
|
||||
return newGameProps
|
||||
}
|
||||
return state
|
||||
}),
|
||||
reset: () => {
|
||||
set(initialState)
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: "gameState",
|
||||
}
|
||||
)
|
||||
)
|
105
leaky-ships/hooks/useSocket.ts
Normal file
105
leaky-ships/hooks/useSocket.ts
Normal file
|
@ -0,0 +1,105 @@
|
|||
import { useGameProps } from "@hooks/useGameProps"
|
||||
import { socket } from "@lib/socket"
|
||||
import { useEffect, useState } from "react"
|
||||
import { toast } from "react-toastify"
|
||||
|
||||
/** This function should only be called once per page, otherwise there will be multiple socket connections and duplicate event listeners. */
|
||||
function useSocket() {
|
||||
const [isConnected, setIsConnected] = useState(false)
|
||||
const { full } = useGameProps()
|
||||
|
||||
useEffect(() => setIsConnected(socket.connected), [socket.connected])
|
||||
|
||||
useEffect(() => {
|
||||
socket.connect()
|
||||
|
||||
socket.on("connect", () => {
|
||||
console.log("connected")
|
||||
|
||||
const toastId = "connect_error"
|
||||
toast.dismiss(toastId)
|
||||
})
|
||||
|
||||
socket.on("connect_error", () => {
|
||||
const toastId = "connect_error"
|
||||
const isActive = toast.isActive(toastId)
|
||||
if (isActive)
|
||||
toast.update(toastId, {
|
||||
autoClose: 5000,
|
||||
})
|
||||
else
|
||||
toast.warn("Es gibt Probleme mit der Echtzeitverbindung.", { toastId })
|
||||
})
|
||||
|
||||
socket.on("disconnect", () => {
|
||||
console.log("disconnect")
|
||||
})
|
||||
|
||||
socket.on("update", (body) => {
|
||||
console.log("update")
|
||||
full(body)
|
||||
})
|
||||
|
||||
return () => {
|
||||
socket.removeAllListeners()
|
||||
socket.disconnect()
|
||||
}
|
||||
}, [])
|
||||
|
||||
// useEffect(() => {
|
||||
// const toastId = "realtime"
|
||||
|
||||
// toast("Echtzeitverbindung wird hergestellt...", {
|
||||
// icon: Icons.spinner(),
|
||||
// toastId,
|
||||
// autoClose: false,
|
||||
// hideProgressBar: true,
|
||||
// closeButton: false,
|
||||
// })
|
||||
// socket.emit("join", ({ ack }) => {
|
||||
// if (!ack) {
|
||||
// toast.update(toastId, {
|
||||
// render: "Bei der Echtzeitverbindung ist ein Fehler aufgetreten 🤯",
|
||||
// type: "error",
|
||||
// icon: Icons.error,
|
||||
// theme: "colored",
|
||||
// autoClose: 5000,
|
||||
// hideProgressBar: false,
|
||||
// closeButton: true,
|
||||
// })
|
||||
// } else {
|
||||
// setHasJoined(true)
|
||||
// toast.update(toastId, {
|
||||
// render: "Echtzeitverbindung hergestellt 👌",
|
||||
// type: "info",
|
||||
// icon: Icons.success,
|
||||
// autoClose: 5000,
|
||||
// hideProgressBar: false,
|
||||
// closeButton: true,
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// }, [])
|
||||
|
||||
// useEffect(() => {
|
||||
// if (!isConnected) return
|
||||
// socket.emit("authenticate", { token: `hello from ${session?.user.email}` })
|
||||
// }, [isConnected, status, session?.user.email])
|
||||
|
||||
// useEffect(() => {
|
||||
// if (!isConnected) return
|
||||
// let count = 0
|
||||
// const interval = setInterval(() => {
|
||||
// const start = Date.now()
|
||||
// socket.volatile.emit("ping", ++count, (count) => {
|
||||
// const duration = Date.now() - start
|
||||
// console.log("ping", count, duration)
|
||||
// })
|
||||
// }, 5000)
|
||||
// return () => clearInterval(interval)
|
||||
// }, [isConnected])
|
||||
|
||||
return { isConnected }
|
||||
}
|
||||
|
||||
export default useSocket
|
|
@ -1,3 +1,4 @@
|
|||
import { GameSettings } from "@components/Lobby/SettingsFrame/Setting"
|
||||
import { GamePropsSchema } from "@lib/zodSchemas"
|
||||
import { User } from "@prisma/client"
|
||||
import type { Server as HTTPServer } from "http"
|
||||
|
@ -22,13 +23,16 @@ export interface ServerToClientEvents {
|
|||
// noArg: () => void
|
||||
// basicEmit: (a: number, b: string, c: Buffer) => void
|
||||
// withAck: (d: string, ) => void
|
||||
forbidden: () => void
|
||||
update: (game: GamePropsSchema) => void
|
||||
}
|
||||
|
||||
export interface ClientToServerEvents {
|
||||
join: (userId: string, callback: () => void) => void
|
||||
authenticate: (payload: { token: string }) => void
|
||||
ping: (count: number, callback: (count: number) => void) => void
|
||||
join: (withAck: ({ ack }: { ack: boolean }) => void) => void
|
||||
gameSetting: (
|
||||
payload: GameSettings,
|
||||
withAck: ({ ack }: { ack: boolean }) => void
|
||||
) => void
|
||||
}
|
||||
|
||||
interface InterServerEvents {
|
||||
|
@ -37,7 +41,7 @@ interface InterServerEvents {
|
|||
|
||||
interface SocketData {
|
||||
user: User | null
|
||||
gameProps: GamePropsSchema
|
||||
gameId: string | null
|
||||
}
|
||||
|
||||
export type cServer = Server<
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
import { GamePropsSchema } from "./zodSchemas"
|
||||
import crypto from "crypto"
|
||||
|
||||
export function getObjectChecksum(obj: Object) {
|
||||
const objString = JSON.stringify(obj)
|
||||
export function getPayloadwithChecksum(
|
||||
payload: GamePropsSchema["payload"] | null
|
||||
): GamePropsSchema {
|
||||
if (payload === null) return { payload: null, hash: null }
|
||||
const objString = JSON.stringify(payload)
|
||||
const hash = crypto.createHash("md5").update(objString).digest("hex")
|
||||
return hash
|
||||
return { payload, hash }
|
||||
}
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
import { GamePropsSchema } from "@lib/zodSchemas"
|
||||
import { useSession } from "next-auth/react"
|
||||
import {
|
||||
Dispatch,
|
||||
ReactNode,
|
||||
createContext,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useReducer,
|
||||
} from "react"
|
||||
import { toast } from "react-toastify"
|
||||
|
||||
const initialValue: GamePropsSchema = { payload: null, hash: null }
|
||||
|
||||
interface gameContext {
|
||||
gameProps: GamePropsSchema
|
||||
setGameProps: Dispatch<GamePropsSchema>
|
||||
}
|
||||
|
||||
export const gameContext = createContext<gameContext>({
|
||||
gameProps: initialValue,
|
||||
setGameProps: () => {},
|
||||
})
|
||||
|
||||
function updateProps(state: GamePropsSchema, body: GamePropsSchema) {
|
||||
if (state.hash === body.hash) {
|
||||
console.log("Everything up to date.")
|
||||
return state
|
||||
} else {
|
||||
console.log("Update was needed.", state.hash, body.hash)
|
||||
|
||||
if (
|
||||
state.payload?.game?.id &&
|
||||
state.payload?.game?.id !== body.payload?.game?.id
|
||||
) {
|
||||
console.warn(
|
||||
"Different gameId detected on update: ",
|
||||
state.payload?.game?.id,
|
||||
body.payload?.game?.id
|
||||
)
|
||||
}
|
||||
|
||||
return body
|
||||
}
|
||||
}
|
||||
|
||||
export function GameContextProvider({ children }: { children: ReactNode }) {
|
||||
const [gameProps, setGameProps] = useReducer(updateProps, initialValue)
|
||||
|
||||
const value = useMemo<gameContext>(
|
||||
() => ({ gameProps, setGameProps }),
|
||||
[gameProps, setGameProps]
|
||||
)
|
||||
|
||||
return <gameContext.Provider value={value}>{children}</gameContext.Provider>
|
||||
}
|
||||
|
||||
function useGameState() {
|
||||
const { gameProps, setGameProps } = useContext(gameContext)
|
||||
const { data: session, status } = useSession()
|
||||
|
||||
useEffect(() => {
|
||||
if (status === "loading") return
|
||||
if (!session)
|
||||
toast("Nicht angemeldet.", {
|
||||
toastId: "user",
|
||||
position: "top-center",
|
||||
})
|
||||
else
|
||||
toast(session.user.email, {
|
||||
toastId: "user",
|
||||
position: "top-center",
|
||||
icon: session.user.image ? (
|
||||
<img
|
||||
style={{ transform: "scale(1.5)", borderRadius: "100%" }}
|
||||
src={session.user.image}
|
||||
alt="profile picture"
|
||||
/>
|
||||
) : undefined,
|
||||
})
|
||||
}, [session, status])
|
||||
|
||||
return {
|
||||
gameProps,
|
||||
setGameProps,
|
||||
session,
|
||||
status,
|
||||
}
|
||||
}
|
||||
|
||||
export default useGameState
|
|
@ -1,58 +0,0 @@
|
|||
import useGameState from "@lib/hooks/useGameState"
|
||||
import { socket } from "@lib/socket"
|
||||
import { useEffect, useState } from "react"
|
||||
|
||||
function useSocket() {
|
||||
const [isConnected, setIsConnected] = useState(socket.connected)
|
||||
const [hasJoined, setHasJoined] = useState(false)
|
||||
// const [fooEvents, setFooEvents] = useState([])
|
||||
const { session, status, setGameProps } = useGameState()
|
||||
|
||||
useEffect(() => {
|
||||
if (status === "loading") return
|
||||
|
||||
socket.on("connect", () => {
|
||||
console.log("connected")
|
||||
setIsConnected(true)
|
||||
})
|
||||
socket.on("connect_error", () => {
|
||||
console.log("connect_error")
|
||||
})
|
||||
|
||||
socket.on("disconnect", () => {
|
||||
console.log("disconnect")
|
||||
setIsConnected(false)
|
||||
})
|
||||
|
||||
socket.on("forbidden", () => {
|
||||
console.log("forbidden")
|
||||
})
|
||||
|
||||
socket.on("update", (body) => {
|
||||
console.log("update")
|
||||
setGameProps(body)
|
||||
})
|
||||
|
||||
return () => {
|
||||
// for all events
|
||||
socket.removeAllListeners()
|
||||
}
|
||||
}, [status, setGameProps])
|
||||
|
||||
useEffect(() => {
|
||||
if (session?.user.id && !hasJoined) {
|
||||
socket?.emit("join", session?.user.id, () => {
|
||||
setHasJoined(true)
|
||||
})
|
||||
}
|
||||
}, [session?.user.id, hasJoined])
|
||||
|
||||
useEffect(() => {
|
||||
if (!isConnected) return
|
||||
socket?.emit("authenticate", { token: `hello from ${session?.user.email}` })
|
||||
}, [isConnected, status, session?.user.email])
|
||||
|
||||
return { isConnected, hasJoined }
|
||||
}
|
||||
|
||||
export default useSocket
|
|
@ -3,4 +3,5 @@ import { io } from "socket.io-client"
|
|||
|
||||
export const socket: cSocket = io({
|
||||
path: "/api/ws",
|
||||
autoConnect: false,
|
||||
})
|
||||
|
|
|
@ -1,23 +1,41 @@
|
|||
import {
|
||||
GameSchema,
|
||||
GamepinSchema,
|
||||
User_GameSchema,
|
||||
} from "../prisma/generated/zod"
|
||||
import { GameState, PlayerN } from "@prisma/client"
|
||||
import { z } from "zod"
|
||||
|
||||
export const PlayerSchema = z
|
||||
.object({
|
||||
email: z.string().nullable(),
|
||||
name: z.string().nullable(),
|
||||
})
|
||||
.and(User_GameSchema)
|
||||
export const PlayerSchema = z.object({
|
||||
id: z.string(),
|
||||
name: z.string().nullable(),
|
||||
index: z.nativeEnum(PlayerN),
|
||||
chats: z
|
||||
.object({
|
||||
id: z.string(),
|
||||
event: z.string().nullable(),
|
||||
message: z.string().nullable(),
|
||||
createdAt: z.date(),
|
||||
})
|
||||
.array(),
|
||||
moves: z
|
||||
.object({
|
||||
id: z.string(),
|
||||
index: z.number(),
|
||||
})
|
||||
.array(),
|
||||
})
|
||||
|
||||
export const CreateSchema = z
|
||||
.object({
|
||||
game: GameSchema.nullish(),
|
||||
gamePin: GamepinSchema.nullish(),
|
||||
player1: PlayerSchema.nullish(),
|
||||
player2: PlayerSchema.nullish(),
|
||||
game: z
|
||||
.object({
|
||||
id: z.string(),
|
||||
state: z.nativeEnum(GameState),
|
||||
allowSpectators: z.boolean(),
|
||||
allowSpecials: z.boolean(),
|
||||
allowChat: z.boolean(),
|
||||
allowMarkDraw: z.boolean(),
|
||||
})
|
||||
.nullable(),
|
||||
gamePin: z.string().nullable(),
|
||||
player1: PlayerSchema.nullable(),
|
||||
player2: PlayerSchema.nullable(),
|
||||
})
|
||||
.strict()
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
"eslint": "8.31.0",
|
||||
"eslint-config-next": "13.1.1",
|
||||
"http-status": "^1.6.2",
|
||||
"immer": "^10.0.2",
|
||||
"next": "13.1.1",
|
||||
"next-auth": "^4.22.1",
|
||||
"nodemailer": "^6.9.1",
|
||||
|
@ -38,7 +39,8 @@
|
|||
"typescript": "4.9.4",
|
||||
"unique-names-generator": "^4.7.1",
|
||||
"zod": "^3.21.1",
|
||||
"zod-prisma-types": "^2.5.6"
|
||||
"zod-prisma-types": "^2.5.6",
|
||||
"zustand": "^4.3.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@total-typescript/ts-reset": "^0.3.7",
|
||||
|
|
|
@ -3,7 +3,6 @@ import "../styles/globals.scss"
|
|||
import "../styles/grid2.scss"
|
||||
import "../styles/grid.scss"
|
||||
import "@fortawesome/fontawesome-svg-core/styles.css"
|
||||
import { GameContextProvider } from "@lib/hooks/useGameState"
|
||||
import { SessionProvider } from "next-auth/react"
|
||||
import type { AppProps } from "next/app"
|
||||
import { ToastContainer } from "react-toastify"
|
||||
|
@ -15,10 +14,8 @@ export default function App({
|
|||
}: AppProps) {
|
||||
return (
|
||||
<SessionProvider session={session}>
|
||||
<GameContextProvider>
|
||||
<Component {...pageProps} />
|
||||
<ToastContainer />
|
||||
</GameContextProvider>
|
||||
<Component {...pageProps} />
|
||||
<ToastContainer />
|
||||
</SessionProvider>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { authOptions } from "../auth/[...nextauth]"
|
||||
import { composeBody, gameIncludes, getAnyRunningGame } from "./running"
|
||||
import { composeBody, gameSelects, getAnyRunningGame } from "./running"
|
||||
import sendResponse from "@backend/sendResponse"
|
||||
import { rejectionErrors } from "@lib/backend/errors"
|
||||
import prisma from "@lib/prisma"
|
||||
|
@ -46,7 +46,7 @@ export default async function create(
|
|||
},
|
||||
},
|
||||
},
|
||||
...gameIncludes,
|
||||
...gameSelects,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { authOptions } from "../auth/[...nextauth]"
|
||||
import { composeBody, gameIncludes } from "./running"
|
||||
import { composeBody, gameSelects } from "./running"
|
||||
import sendError from "@backend/sendError"
|
||||
import sendResponse from "@backend/sendResponse"
|
||||
import { rejectionErrors } from "@lib/backend/errors"
|
||||
|
@ -46,7 +46,7 @@ export default async function join(
|
|||
index: "player2",
|
||||
},
|
||||
include: {
|
||||
game: gameIncludes,
|
||||
game: gameSelects,
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
@ -1,21 +1,46 @@
|
|||
import { authOptions } from "../auth/[...nextauth]"
|
||||
import sendResponse from "@backend/sendResponse"
|
||||
import { rejectionErrors } from "@lib/backend/errors"
|
||||
import { getObjectChecksum } from "@lib/getObjectChecksum"
|
||||
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 gameIncludes = {
|
||||
include: {
|
||||
gamePin: true,
|
||||
export const gameSelects = {
|
||||
select: {
|
||||
id: true,
|
||||
allowChat: true,
|
||||
allowMarkDraw: true,
|
||||
allowSpecials: true,
|
||||
allowSpectators: true,
|
||||
state: true,
|
||||
gamePin: {
|
||||
select: {
|
||||
pin: true,
|
||||
},
|
||||
},
|
||||
users: {
|
||||
include: {
|
||||
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,
|
||||
email: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -31,7 +56,7 @@ export const getAnyGame = (gameId: string) => {
|
|||
},
|
||||
id: gameId,
|
||||
},
|
||||
...gameIncludes,
|
||||
...gameSelects,
|
||||
})
|
||||
return game
|
||||
}
|
||||
|
@ -48,14 +73,14 @@ export const getAnyRunningGame = (userId: string) => {
|
|||
},
|
||||
},
|
||||
},
|
||||
...gameIncludes,
|
||||
...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,
|
||||
|
@ -64,13 +89,12 @@ export function composeBody(
|
|||
const player1 = users.find((user) => user.index === "player1")
|
||||
const player2 = users.find((user) => user.index === "player2")
|
||||
const payload = {
|
||||
game,
|
||||
gamePin,
|
||||
player1,
|
||||
player2,
|
||||
game: game,
|
||||
gamePin: gamePin?.pin ?? null,
|
||||
player1: player1 ?? null,
|
||||
player2: player2 ?? null,
|
||||
}
|
||||
const hash = getObjectChecksum(payload)
|
||||
return { payload, hash }
|
||||
return getPayloadwithChecksum(payload)
|
||||
}
|
||||
|
||||
export default async function running(
|
||||
|
|
|
@ -2,7 +2,12 @@ import {
|
|||
NextApiResponseWithSocket,
|
||||
cServer,
|
||||
} from "../../interfaces/NextApiSocket"
|
||||
import { composeBody, getAnyRunningGame } from "./game/running"
|
||||
import {
|
||||
composeBody,
|
||||
gameSelects,
|
||||
getAnyGame,
|
||||
getAnyRunningGame,
|
||||
} from "./game/running"
|
||||
import logging from "@lib/backend/logging"
|
||||
import prisma from "@lib/prisma"
|
||||
import colors from "colors"
|
||||
|
@ -40,31 +45,9 @@ const SocketHandler = async (
|
|||
id: session?.user.id,
|
||||
},
|
||||
})
|
||||
next()
|
||||
} catch (err) {
|
||||
logging("Unauthorized", ["warn"], socket.request)
|
||||
next(new Error("Unauthorized"))
|
||||
}
|
||||
})
|
||||
|
||||
io.on("connection", (socket) => {
|
||||
logging(
|
||||
`User connected <${socket.data.user?.email}>`.green +
|
||||
", " +
|
||||
socket.id.cyan,
|
||||
["infoGreen"],
|
||||
socket.request
|
||||
)
|
||||
|
||||
socket.on("join", async (userId, cb) => {
|
||||
logging(
|
||||
"Join: " + JSON.stringify(Array.from(socket.rooms)),
|
||||
["debug"],
|
||||
socket.request
|
||||
)
|
||||
const game = await getAnyRunningGame(userId ?? "")
|
||||
const game = await getAnyRunningGame(socket.data.user?.id ?? "")
|
||||
if (!game) {
|
||||
socket.emit("forbidden")
|
||||
logging(
|
||||
"Forbidden, no game found: " +
|
||||
JSON.stringify(Array.from(socket.rooms)),
|
||||
|
@ -73,11 +56,46 @@ const SocketHandler = async (
|
|||
)
|
||||
return
|
||||
}
|
||||
cb()
|
||||
socket.join(userId)
|
||||
socket.data.gameId = game.id
|
||||
socket.join(game.id)
|
||||
next()
|
||||
} catch (err) {
|
||||
logging("Unauthorized", ["warn"], socket.request)
|
||||
next(new Error("Unauthorized"))
|
||||
}
|
||||
})
|
||||
|
||||
io.on("connection", async (socket) => {
|
||||
logging(
|
||||
`User connected <${socket.data.user?.email}>`.green +
|
||||
", " +
|
||||
socket.id.cyan,
|
||||
["infoGreen"],
|
||||
socket.request
|
||||
)
|
||||
const game = await getAnyGame(socket.data.gameId ?? "")
|
||||
if (!socket.data.user || !socket.data.gameId || !game)
|
||||
return socket.disconnect()
|
||||
const body = composeBody(game)
|
||||
io.to(socket.data.gameId).emit("update", body)
|
||||
|
||||
socket.on("gameSetting", async (payload, cb) => {
|
||||
if (!socket.data.gameId) {
|
||||
cb({ ack: false })
|
||||
return
|
||||
}
|
||||
const game = await prisma.game.update({
|
||||
where: { id: socket.data.gameId },
|
||||
data: payload,
|
||||
...gameSelects,
|
||||
})
|
||||
const body = composeBody(game)
|
||||
socket.data.gameProps = body
|
||||
io.to(userId).emit("update", body)
|
||||
cb({ ack: true })
|
||||
io.to(game.id).emit("update", body)
|
||||
})
|
||||
|
||||
socket.on("ping", (count, callback) => {
|
||||
callback(count)
|
||||
})
|
||||
|
||||
socket.on("disconnecting", () => {
|
||||
|
|
|
@ -1,33 +1,36 @@
|
|||
import useGameState from "@lib/hooks/useGameState"
|
||||
import { useGameProps } from "@hooks/useGameProps"
|
||||
import { useSession } from "next-auth/react"
|
||||
import { useRouter } from "next/router"
|
||||
import React, { useEffect } from "react"
|
||||
import { toast } from "react-toastify"
|
||||
|
||||
export default function Game() {
|
||||
const { gameProps, session } = useGameState()
|
||||
const { payload } = useGameProps()
|
||||
const router = useRouter()
|
||||
const { data: session } = useSession()
|
||||
|
||||
useEffect(() => {
|
||||
const gameId = gameProps.payload?.game?.id
|
||||
const gameId = payload?.game?.id
|
||||
const path = gameId ? "/game" : "/start"
|
||||
toast.promise(router.push(path), {
|
||||
pending: {
|
||||
render: "Wird weitergeleitet...",
|
||||
toastId: "redirect",
|
||||
toastId: "pageLoad",
|
||||
},
|
||||
success: {
|
||||
render: gameId
|
||||
? "Spiel gefunden!"
|
||||
: session?.user
|
||||
: session?.user.id
|
||||
? "Kein laufendes Spiel."
|
||||
: "Kein laufendes Spiel. Bitte anmelden.",
|
||||
toastId: session?.user ? "postRedirect" : "user",
|
||||
theme: session?.user ? "dark" : undefined,
|
||||
toastId: "pageLoad",
|
||||
theme: session?.user.id ? "dark" : undefined,
|
||||
type: gameId ? "success" : "info",
|
||||
},
|
||||
error: {
|
||||
render: "Es ist ein Fehler aufgetreten 🤯",
|
||||
type: "error",
|
||||
toastId: "pageLoad",
|
||||
theme: "colored",
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import Gamefield from "../components/Gamefield/Gamefield"
|
||||
import Gamefield from "@components/Gamefield/Gamefield"
|
||||
import Head from "next/head"
|
||||
|
||||
export default function Home() {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import Grid from "../components/Grid"
|
||||
import Grid from "@components/Grid"
|
||||
import Head from "next/head"
|
||||
|
||||
export default function Home() {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import Grid2 from "../components/Grid2"
|
||||
import Grid2 from "@components/Grid2"
|
||||
import Head from "next/head"
|
||||
|
||||
export default function Home() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import BurgerMenu from "../components/BurgerMenu"
|
||||
import Logo from "../components/Logo"
|
||||
import BurgerMenu from "@components/BurgerMenu"
|
||||
import Logo from "@components/Logo"
|
||||
import { faCirclePlay } from "@fortawesome/pro-thin-svg-icons"
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||
import { useRouter } from "next/router"
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
import BurgerMenu from "../components/BurgerMenu"
|
||||
import LobbyFrame from "../components/Lobby/LobbyFrame"
|
||||
import Settings from "../components/Lobby/SettingsFrame/Settings"
|
||||
import Logo from "../components/Logo"
|
||||
import useGameState from "@lib/hooks/useGameState"
|
||||
import BurgerMenu from "@components/BurgerMenu"
|
||||
import LobbyFrame from "@components/Lobby/LobbyFrame"
|
||||
import Settings from "@components/Lobby/SettingsFrame/Settings"
|
||||
import Logo from "@components/Logo"
|
||||
import classNames from "classnames"
|
||||
import Head from "next/head"
|
||||
import { useState } from "react"
|
||||
|
||||
export default function Lobby() {
|
||||
useGameState()
|
||||
const [settings, setSettings] = useState(false)
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
import BurgerMenu from "../components/BurgerMenu"
|
||||
import Logo from "../components/Logo"
|
||||
import OptionButton from "../components/OptionButton"
|
||||
import BurgerMenu from "@components/BurgerMenu"
|
||||
import Logo from "@components/Logo"
|
||||
import OptionButton from "@components/OptionButton"
|
||||
import { faEye, faLeftLong } from "@fortawesome/pro-regular-svg-icons"
|
||||
import { faPlus, faUserPlus } from "@fortawesome/pro-solid-svg-icons"
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||
import useGameState from "@lib/hooks/useGameState"
|
||||
import { useGameProps } from "@hooks/useGameProps"
|
||||
import { GamePropsSchema } from "@lib/zodSchemas"
|
||||
import status from "http-status"
|
||||
import { useSession } from "next-auth/react"
|
||||
import { useRouter } from "next/router"
|
||||
import { useCallback, useEffect, useMemo, useState } from "react"
|
||||
import OtpInput from "react-otp-input"
|
||||
import { toast } from "react-toastify"
|
||||
import { Icons } from "react-toastify"
|
||||
|
||||
function isInputOnlyNumbers(input: string) {
|
||||
return /^\d+$/.test(input)
|
||||
|
@ -45,8 +47,9 @@ const handleConfirmation = () => {
|
|||
|
||||
export default function Start() {
|
||||
const [otp, setOtp] = useState("")
|
||||
const { session, setGameProps } = useGameState()
|
||||
const { full } = useGameProps()
|
||||
const router = useRouter()
|
||||
const { data: session } = useSession()
|
||||
|
||||
const query = useMemo((): { join?: boolean; watch?: boolean } => {
|
||||
switch (router.query.q) {
|
||||
|
@ -68,43 +71,58 @@ export default function Start() {
|
|||
.then(isAuthenticated)
|
||||
.then((game) => GamePropsSchema.parse(game))
|
||||
|
||||
const toastId = !pin ? "erstellt" : "angefragt"
|
||||
const res = await toast.promise(gamePromise, {
|
||||
pending: {
|
||||
render: "Raum wird " + toastId,
|
||||
toastId,
|
||||
},
|
||||
success: {
|
||||
render: "Raum " + (!pin ? "erstellt" : "angefragt") + " 👌",
|
||||
type: "info",
|
||||
theme: "colored",
|
||||
toastId,
|
||||
},
|
||||
error: {
|
||||
const action = !pin ? "erstellt" : "angefragt"
|
||||
const toastId = "pageLoad"
|
||||
toast("Raum wird " + action, {
|
||||
icon: Icons.spinner(),
|
||||
toastId,
|
||||
autoClose: false,
|
||||
hideProgressBar: true,
|
||||
closeButton: false,
|
||||
})
|
||||
const res = await gamePromise.catch(() =>
|
||||
toast.update(toastId, {
|
||||
render: "Es ist ein Fehler aufgetreten 🤯",
|
||||
type: "error",
|
||||
icon: Icons.error,
|
||||
theme: "colored",
|
||||
toastId,
|
||||
},
|
||||
autoClose: 5000,
|
||||
hideProgressBar: false,
|
||||
closeButton: true,
|
||||
})
|
||||
)
|
||||
if (!res) return
|
||||
full(res)
|
||||
|
||||
toast.update(toastId, {
|
||||
render: "Weiterleitung",
|
||||
})
|
||||
|
||||
setGameProps(res)
|
||||
|
||||
await toast.promise(router.push("/lobby"), {
|
||||
pending: {
|
||||
render: "Raum wird beigetreten",
|
||||
},
|
||||
success: {
|
||||
render: "Raum begetreten 👌",
|
||||
type: "info",
|
||||
},
|
||||
error: {
|
||||
render: "Es ist ein Fehler aufgetreten 🤯",
|
||||
type: "error",
|
||||
},
|
||||
})
|
||||
router
|
||||
.push("/lobby")
|
||||
.then(() =>
|
||||
toast.update(toastId, {
|
||||
render: "Raum begetreten 👌",
|
||||
type: "info",
|
||||
icon: Icons.success,
|
||||
autoClose: 5000,
|
||||
hideProgressBar: false,
|
||||
closeButton: true,
|
||||
})
|
||||
)
|
||||
.catch(() =>
|
||||
toast.update(toastId, {
|
||||
render: "Es ist ein Fehler aufgetreten 🤯",
|
||||
type: "error",
|
||||
icon: Icons.error,
|
||||
theme: "colored",
|
||||
autoClose: 5000,
|
||||
hideProgressBar: false,
|
||||
closeButton: true,
|
||||
})
|
||||
)
|
||||
},
|
||||
[router, setGameProps]
|
||||
[router, full]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -151,7 +169,7 @@ export default function Start() {
|
|||
icon={faUserPlus}
|
||||
disabled={!session}
|
||||
>
|
||||
{query.join && session?.user ? (
|
||||
{query.join && session ? (
|
||||
<OtpInput
|
||||
shouldAutoFocus
|
||||
containerStyle={{ color: "initial" }}
|
||||
|
@ -167,7 +185,7 @@ export default function Start() {
|
|||
)}
|
||||
</OptionButton>
|
||||
<OptionButton icon={faEye}>
|
||||
{query.watch && session?.user ? (
|
||||
{query.watch ? (
|
||||
<OtpInput
|
||||
shouldAutoFocus
|
||||
containerStyle={{ color: "initial" }}
|
||||
|
|
35
leaky-ships/pnpm-lock.yaml
generated
35
leaky-ships/pnpm-lock.yaml
generated
|
@ -49,6 +49,9 @@ dependencies:
|
|||
http-status:
|
||||
specifier: ^1.6.2
|
||||
version: 1.6.2
|
||||
immer:
|
||||
specifier: ^10.0.2
|
||||
version: 10.0.2
|
||||
next:
|
||||
specifier: 13.1.1
|
||||
version: 13.1.1(react-dom@18.2.0)(react@18.2.0)(sass@1.61.0)
|
||||
|
@ -91,6 +94,9 @@ dependencies:
|
|||
zod-prisma-types:
|
||||
specifier: ^2.5.6
|
||||
version: 2.5.6
|
||||
zustand:
|
||||
specifier: ^4.3.8
|
||||
version: 4.3.8(immer@10.0.2)(react@18.2.0)
|
||||
|
||||
devDependencies:
|
||||
'@total-typescript/ts-reset':
|
||||
|
@ -1861,6 +1867,10 @@ packages:
|
|||
resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
|
||||
engines: {node: '>= 4'}
|
||||
|
||||
/immer@10.0.2:
|
||||
resolution: {integrity: sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==}
|
||||
dev: false
|
||||
|
||||
/immutable@4.3.0:
|
||||
resolution: {integrity: sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==}
|
||||
|
||||
|
@ -3180,6 +3190,14 @@ packages:
|
|||
dependencies:
|
||||
punycode: 2.3.0
|
||||
|
||||
/use-sync-external-store@1.2.0(react@18.2.0):
|
||||
resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
dependencies:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
dev: true
|
||||
|
@ -3289,3 +3307,20 @@ packages:
|
|||
/zod@3.21.4:
|
||||
resolution: {integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==}
|
||||
dev: false
|
||||
|
||||
/zustand@4.3.8(immer@10.0.2)(react@18.2.0):
|
||||
resolution: {integrity: sha512-4h28KCkHg5ii/wcFFJ5Fp+k1J3gJoasaIbppdgZFO4BPJnsNxL0mQXBSFgOgAdCdBj35aDTPvdAJReTMntFPGg==}
|
||||
engines: {node: '>=12.7.0'}
|
||||
peerDependencies:
|
||||
immer: '>=9.0'
|
||||
react: '>=16.8'
|
||||
peerDependenciesMeta:
|
||||
immer:
|
||||
optional: true
|
||||
react:
|
||||
optional: true
|
||||
dependencies:
|
||||
immer: 10.0.2
|
||||
react: 18.2.0
|
||||
use-sync-external-store: 1.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
|
|
@ -14,7 +14,7 @@ export const AccountScalarFieldEnumSchema = z.enum(['id','userId','type','provid
|
|||
|
||||
export const ChatScalarFieldEnumSchema = z.enum(['id','createdAt','message','event','user_game_id']);
|
||||
|
||||
export const GameScalarFieldEnumSchema = z.enum(['id','createdAt','updatedAt','state']);
|
||||
export const GameScalarFieldEnumSchema = z.enum(['id','createdAt','updatedAt','state','allowSpectators','allowSpecials','allowChat','allowMarkDraw']);
|
||||
|
||||
export const GamepinScalarFieldEnumSchema = z.enum(['id','createdAt','pin','gameId']);
|
||||
|
||||
|
@ -118,6 +118,10 @@ export const GameSchema = z.object({
|
|||
id: z.string().cuid(),
|
||||
createdAt: z.coerce.date(),
|
||||
updatedAt: z.coerce.date(),
|
||||
allowSpectators: z.boolean(),
|
||||
allowSpecials: z.boolean(),
|
||||
allowChat: z.boolean(),
|
||||
allowMarkDraw: z.boolean(),
|
||||
})
|
||||
|
||||
export type Game = z.infer<typeof GameSchema>
|
||||
|
@ -306,6 +310,10 @@ export const GameSelectSchema: z.ZodType<Prisma.GameSelect> = z.object({
|
|||
createdAt: z.boolean().optional(),
|
||||
updatedAt: z.boolean().optional(),
|
||||
state: z.boolean().optional(),
|
||||
allowSpectators: z.boolean().optional(),
|
||||
allowSpecials: z.boolean().optional(),
|
||||
allowChat: z.boolean().optional(),
|
||||
allowMarkDraw: z.boolean().optional(),
|
||||
gamePin: z.union([z.boolean(),z.lazy(() => GamepinArgsSchema)]).optional(),
|
||||
users: z.union([z.boolean(),z.lazy(() => User_GameFindManyArgsSchema)]).optional(),
|
||||
_count: z.union([z.boolean(),z.lazy(() => GameCountOutputTypeArgsSchema)]).optional(),
|
||||
|
@ -655,6 +663,10 @@ export const GameWhereInputSchema: z.ZodType<Prisma.GameWhereInput> = z.object({
|
|||
createdAt: z.union([ z.lazy(() => DateTimeFilterSchema),z.coerce.date() ]).optional(),
|
||||
updatedAt: z.union([ z.lazy(() => DateTimeFilterSchema),z.coerce.date() ]).optional(),
|
||||
state: z.union([ z.lazy(() => EnumGameStateFilterSchema),z.lazy(() => GameStateSchema) ]).optional(),
|
||||
allowSpectators: z.union([ z.lazy(() => BoolFilterSchema),z.boolean() ]).optional(),
|
||||
allowSpecials: z.union([ z.lazy(() => BoolFilterSchema),z.boolean() ]).optional(),
|
||||
allowChat: z.union([ z.lazy(() => BoolFilterSchema),z.boolean() ]).optional(),
|
||||
allowMarkDraw: z.union([ z.lazy(() => BoolFilterSchema),z.boolean() ]).optional(),
|
||||
gamePin: z.union([ z.lazy(() => GamepinRelationFilterSchema),z.lazy(() => GamepinWhereInputSchema) ]).optional().nullable(),
|
||||
users: z.lazy(() => User_GameListRelationFilterSchema).optional()
|
||||
}).strict();
|
||||
|
@ -664,6 +676,10 @@ export const GameOrderByWithRelationInputSchema: z.ZodType<Prisma.GameOrderByWit
|
|||
createdAt: z.lazy(() => SortOrderSchema).optional(),
|
||||
updatedAt: z.lazy(() => SortOrderSchema).optional(),
|
||||
state: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowSpectators: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowSpecials: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowChat: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowMarkDraw: z.lazy(() => SortOrderSchema).optional(),
|
||||
gamePin: z.lazy(() => GamepinOrderByWithRelationInputSchema).optional(),
|
||||
users: z.lazy(() => User_GameOrderByRelationAggregateInputSchema).optional()
|
||||
}).strict();
|
||||
|
@ -677,6 +693,10 @@ export const GameOrderByWithAggregationInputSchema: z.ZodType<Prisma.GameOrderBy
|
|||
createdAt: z.lazy(() => SortOrderSchema).optional(),
|
||||
updatedAt: z.lazy(() => SortOrderSchema).optional(),
|
||||
state: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowSpectators: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowSpecials: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowChat: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowMarkDraw: z.lazy(() => SortOrderSchema).optional(),
|
||||
_count: z.lazy(() => GameCountOrderByAggregateInputSchema).optional(),
|
||||
_max: z.lazy(() => GameMaxOrderByAggregateInputSchema).optional(),
|
||||
_min: z.lazy(() => GameMinOrderByAggregateInputSchema).optional()
|
||||
|
@ -690,6 +710,10 @@ export const GameScalarWhereWithAggregatesInputSchema: z.ZodType<Prisma.GameScal
|
|||
createdAt: z.union([ z.lazy(() => DateTimeWithAggregatesFilterSchema),z.coerce.date() ]).optional(),
|
||||
updatedAt: z.union([ z.lazy(() => DateTimeWithAggregatesFilterSchema),z.coerce.date() ]).optional(),
|
||||
state: z.union([ z.lazy(() => EnumGameStateWithAggregatesFilterSchema),z.lazy(() => GameStateSchema) ]).optional(),
|
||||
allowSpectators: z.union([ z.lazy(() => BoolWithAggregatesFilterSchema),z.boolean() ]).optional(),
|
||||
allowSpecials: z.union([ z.lazy(() => BoolWithAggregatesFilterSchema),z.boolean() ]).optional(),
|
||||
allowChat: z.union([ z.lazy(() => BoolWithAggregatesFilterSchema),z.boolean() ]).optional(),
|
||||
allowMarkDraw: z.union([ z.lazy(() => BoolWithAggregatesFilterSchema),z.boolean() ]).optional(),
|
||||
}).strict();
|
||||
|
||||
export const GamepinWhereInputSchema: z.ZodType<Prisma.GamepinWhereInput> = z.object({
|
||||
|
@ -1187,6 +1211,10 @@ export const GameCreateInputSchema: z.ZodType<Prisma.GameCreateInput> = z.object
|
|||
createdAt: z.coerce.date().optional(),
|
||||
updatedAt: z.coerce.date().optional(),
|
||||
state: z.lazy(() => GameStateSchema).optional(),
|
||||
allowSpectators: z.boolean().optional(),
|
||||
allowSpecials: z.boolean().optional(),
|
||||
allowChat: z.boolean().optional(),
|
||||
allowMarkDraw: z.boolean().optional(),
|
||||
gamePin: z.lazy(() => GamepinCreateNestedOneWithoutGameInputSchema).optional(),
|
||||
users: z.lazy(() => User_GameCreateNestedManyWithoutGameInputSchema).optional()
|
||||
}).strict();
|
||||
|
@ -1196,6 +1224,10 @@ export const GameUncheckedCreateInputSchema: z.ZodType<Prisma.GameUncheckedCreat
|
|||
createdAt: z.coerce.date().optional(),
|
||||
updatedAt: z.coerce.date().optional(),
|
||||
state: z.lazy(() => GameStateSchema).optional(),
|
||||
allowSpectators: z.boolean().optional(),
|
||||
allowSpecials: z.boolean().optional(),
|
||||
allowChat: z.boolean().optional(),
|
||||
allowMarkDraw: z.boolean().optional(),
|
||||
gamePin: z.lazy(() => GamepinUncheckedCreateNestedOneWithoutGameInputSchema).optional(),
|
||||
users: z.lazy(() => User_GameUncheckedCreateNestedManyWithoutGameInputSchema).optional()
|
||||
}).strict();
|
||||
|
@ -1205,6 +1237,10 @@ export const GameUpdateInputSchema: z.ZodType<Prisma.GameUpdateInput> = z.object
|
|||
createdAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
updatedAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
state: z.union([ z.lazy(() => GameStateSchema),z.lazy(() => EnumGameStateFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowSpectators: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowSpecials: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowChat: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowMarkDraw: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
gamePin: z.lazy(() => GamepinUpdateOneWithoutGameNestedInputSchema).optional(),
|
||||
users: z.lazy(() => User_GameUpdateManyWithoutGameNestedInputSchema).optional()
|
||||
}).strict();
|
||||
|
@ -1214,6 +1250,10 @@ export const GameUncheckedUpdateInputSchema: z.ZodType<Prisma.GameUncheckedUpdat
|
|||
createdAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
updatedAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
state: z.union([ z.lazy(() => GameStateSchema),z.lazy(() => EnumGameStateFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowSpectators: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowSpecials: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowChat: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowMarkDraw: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
gamePin: z.lazy(() => GamepinUncheckedUpdateOneWithoutGameNestedInputSchema).optional(),
|
||||
users: z.lazy(() => User_GameUncheckedUpdateManyWithoutGameNestedInputSchema).optional()
|
||||
}).strict();
|
||||
|
@ -1222,7 +1262,11 @@ export const GameCreateManyInputSchema: z.ZodType<Prisma.GameCreateManyInput> =
|
|||
id: z.string().cuid().optional(),
|
||||
createdAt: z.coerce.date().optional(),
|
||||
updatedAt: z.coerce.date().optional(),
|
||||
state: z.lazy(() => GameStateSchema).optional()
|
||||
state: z.lazy(() => GameStateSchema).optional(),
|
||||
allowSpectators: z.boolean().optional(),
|
||||
allowSpecials: z.boolean().optional(),
|
||||
allowChat: z.boolean().optional(),
|
||||
allowMarkDraw: z.boolean().optional()
|
||||
}).strict();
|
||||
|
||||
export const GameUpdateManyMutationInputSchema: z.ZodType<Prisma.GameUpdateManyMutationInput> = z.object({
|
||||
|
@ -1230,6 +1274,10 @@ export const GameUpdateManyMutationInputSchema: z.ZodType<Prisma.GameUpdateManyM
|
|||
createdAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
updatedAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
state: z.union([ z.lazy(() => GameStateSchema),z.lazy(() => EnumGameStateFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowSpectators: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowSpecials: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowChat: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowMarkDraw: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
}).strict();
|
||||
|
||||
export const GameUncheckedUpdateManyInputSchema: z.ZodType<Prisma.GameUncheckedUpdateManyInput> = z.object({
|
||||
|
@ -1237,6 +1285,10 @@ export const GameUncheckedUpdateManyInputSchema: z.ZodType<Prisma.GameUncheckedU
|
|||
createdAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
updatedAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
state: z.union([ z.lazy(() => GameStateSchema),z.lazy(() => EnumGameStateFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowSpectators: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowSpecials: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowChat: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowMarkDraw: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
}).strict();
|
||||
|
||||
export const GamepinCreateInputSchema: z.ZodType<Prisma.GamepinCreateInput> = z.object({
|
||||
|
@ -1776,6 +1828,11 @@ export const EnumGameStateFilterSchema: z.ZodType<Prisma.EnumGameStateFilter> =
|
|||
not: z.union([ z.lazy(() => GameStateSchema),z.lazy(() => NestedEnumGameStateFilterSchema) ]).optional(),
|
||||
}).strict();
|
||||
|
||||
export const BoolFilterSchema: z.ZodType<Prisma.BoolFilter> = z.object({
|
||||
equals: z.boolean().optional(),
|
||||
not: z.union([ z.boolean(),z.lazy(() => NestedBoolFilterSchema) ]).optional(),
|
||||
}).strict();
|
||||
|
||||
export const GamepinRelationFilterSchema: z.ZodType<Prisma.GamepinRelationFilter> = z.object({
|
||||
is: z.lazy(() => GamepinWhereInputSchema).optional().nullable(),
|
||||
isNot: z.lazy(() => GamepinWhereInputSchema).optional().nullable()
|
||||
|
@ -1785,21 +1842,33 @@ export const GameCountOrderByAggregateInputSchema: z.ZodType<Prisma.GameCountOrd
|
|||
id: z.lazy(() => SortOrderSchema).optional(),
|
||||
createdAt: z.lazy(() => SortOrderSchema).optional(),
|
||||
updatedAt: z.lazy(() => SortOrderSchema).optional(),
|
||||
state: z.lazy(() => SortOrderSchema).optional()
|
||||
state: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowSpectators: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowSpecials: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowChat: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowMarkDraw: z.lazy(() => SortOrderSchema).optional()
|
||||
}).strict();
|
||||
|
||||
export const GameMaxOrderByAggregateInputSchema: z.ZodType<Prisma.GameMaxOrderByAggregateInput> = z.object({
|
||||
id: z.lazy(() => SortOrderSchema).optional(),
|
||||
createdAt: z.lazy(() => SortOrderSchema).optional(),
|
||||
updatedAt: z.lazy(() => SortOrderSchema).optional(),
|
||||
state: z.lazy(() => SortOrderSchema).optional()
|
||||
state: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowSpectators: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowSpecials: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowChat: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowMarkDraw: z.lazy(() => SortOrderSchema).optional()
|
||||
}).strict();
|
||||
|
||||
export const GameMinOrderByAggregateInputSchema: z.ZodType<Prisma.GameMinOrderByAggregateInput> = z.object({
|
||||
id: z.lazy(() => SortOrderSchema).optional(),
|
||||
createdAt: z.lazy(() => SortOrderSchema).optional(),
|
||||
updatedAt: z.lazy(() => SortOrderSchema).optional(),
|
||||
state: z.lazy(() => SortOrderSchema).optional()
|
||||
state: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowSpectators: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowSpecials: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowChat: z.lazy(() => SortOrderSchema).optional(),
|
||||
allowMarkDraw: z.lazy(() => SortOrderSchema).optional()
|
||||
}).strict();
|
||||
|
||||
export const EnumGameStateWithAggregatesFilterSchema: z.ZodType<Prisma.EnumGameStateWithAggregatesFilter> = z.object({
|
||||
|
@ -1812,6 +1881,14 @@ export const EnumGameStateWithAggregatesFilterSchema: z.ZodType<Prisma.EnumGameS
|
|||
_max: z.lazy(() => NestedEnumGameStateFilterSchema).optional()
|
||||
}).strict();
|
||||
|
||||
export const BoolWithAggregatesFilterSchema: z.ZodType<Prisma.BoolWithAggregatesFilter> = z.object({
|
||||
equals: z.boolean().optional(),
|
||||
not: z.union([ z.boolean(),z.lazy(() => NestedBoolWithAggregatesFilterSchema) ]).optional(),
|
||||
_count: z.lazy(() => NestedIntFilterSchema).optional(),
|
||||
_min: z.lazy(() => NestedBoolFilterSchema).optional(),
|
||||
_max: z.lazy(() => NestedBoolFilterSchema).optional()
|
||||
}).strict();
|
||||
|
||||
export const GameRelationFilterSchema: z.ZodType<Prisma.GameRelationFilter> = z.object({
|
||||
is: z.lazy(() => GameWhereInputSchema).optional(),
|
||||
isNot: z.lazy(() => GameWhereInputSchema).optional()
|
||||
|
@ -2207,6 +2284,10 @@ export const EnumGameStateFieldUpdateOperationsInputSchema: z.ZodType<Prisma.Enu
|
|||
set: z.lazy(() => GameStateSchema).optional()
|
||||
}).strict();
|
||||
|
||||
export const BoolFieldUpdateOperationsInputSchema: z.ZodType<Prisma.BoolFieldUpdateOperationsInput> = z.object({
|
||||
set: z.boolean().optional()
|
||||
}).strict();
|
||||
|
||||
export const GamepinUpdateOneWithoutGameNestedInputSchema: z.ZodType<Prisma.GamepinUpdateOneWithoutGameNestedInput> = z.object({
|
||||
create: z.union([ z.lazy(() => GamepinCreateWithoutGameInputSchema),z.lazy(() => GamepinUncheckedCreateWithoutGameInputSchema) ]).optional(),
|
||||
connectOrCreate: z.lazy(() => GamepinCreateOrConnectWithoutGameInputSchema).optional(),
|
||||
|
@ -2589,6 +2670,11 @@ export const NestedEnumGameStateFilterSchema: z.ZodType<Prisma.NestedEnumGameSta
|
|||
not: z.union([ z.lazy(() => GameStateSchema),z.lazy(() => NestedEnumGameStateFilterSchema) ]).optional(),
|
||||
}).strict();
|
||||
|
||||
export const NestedBoolFilterSchema: z.ZodType<Prisma.NestedBoolFilter> = z.object({
|
||||
equals: z.boolean().optional(),
|
||||
not: z.union([ z.boolean(),z.lazy(() => NestedBoolFilterSchema) ]).optional(),
|
||||
}).strict();
|
||||
|
||||
export const NestedEnumGameStateWithAggregatesFilterSchema: z.ZodType<Prisma.NestedEnumGameStateWithAggregatesFilter> = z.object({
|
||||
equals: z.lazy(() => GameStateSchema).optional(),
|
||||
in: z.lazy(() => GameStateSchema).array().optional(),
|
||||
|
@ -2599,6 +2685,14 @@ export const NestedEnumGameStateWithAggregatesFilterSchema: z.ZodType<Prisma.Nes
|
|||
_max: z.lazy(() => NestedEnumGameStateFilterSchema).optional()
|
||||
}).strict();
|
||||
|
||||
export const NestedBoolWithAggregatesFilterSchema: z.ZodType<Prisma.NestedBoolWithAggregatesFilter> = z.object({
|
||||
equals: z.boolean().optional(),
|
||||
not: z.union([ z.boolean(),z.lazy(() => NestedBoolWithAggregatesFilterSchema) ]).optional(),
|
||||
_count: z.lazy(() => NestedIntFilterSchema).optional(),
|
||||
_min: z.lazy(() => NestedBoolFilterSchema).optional(),
|
||||
_max: z.lazy(() => NestedBoolFilterSchema).optional()
|
||||
}).strict();
|
||||
|
||||
export const NestedEnumPlayerNFilterSchema: z.ZodType<Prisma.NestedEnumPlayerNFilter> = z.object({
|
||||
equals: z.lazy(() => PlayerNSchema).optional(),
|
||||
in: z.lazy(() => PlayerNSchema).array().optional(),
|
||||
|
@ -3026,6 +3120,10 @@ export const GameCreateWithoutGamePinInputSchema: z.ZodType<Prisma.GameCreateWit
|
|||
createdAt: z.coerce.date().optional(),
|
||||
updatedAt: z.coerce.date().optional(),
|
||||
state: z.lazy(() => GameStateSchema).optional(),
|
||||
allowSpectators: z.boolean().optional(),
|
||||
allowSpecials: z.boolean().optional(),
|
||||
allowChat: z.boolean().optional(),
|
||||
allowMarkDraw: z.boolean().optional(),
|
||||
users: z.lazy(() => User_GameCreateNestedManyWithoutGameInputSchema).optional()
|
||||
}).strict();
|
||||
|
||||
|
@ -3034,6 +3132,10 @@ export const GameUncheckedCreateWithoutGamePinInputSchema: z.ZodType<Prisma.Game
|
|||
createdAt: z.coerce.date().optional(),
|
||||
updatedAt: z.coerce.date().optional(),
|
||||
state: z.lazy(() => GameStateSchema).optional(),
|
||||
allowSpectators: z.boolean().optional(),
|
||||
allowSpecials: z.boolean().optional(),
|
||||
allowChat: z.boolean().optional(),
|
||||
allowMarkDraw: z.boolean().optional(),
|
||||
users: z.lazy(() => User_GameUncheckedCreateNestedManyWithoutGameInputSchema).optional()
|
||||
}).strict();
|
||||
|
||||
|
@ -3052,6 +3154,10 @@ export const GameUpdateWithoutGamePinInputSchema: z.ZodType<Prisma.GameUpdateWit
|
|||
createdAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
updatedAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
state: z.union([ z.lazy(() => GameStateSchema),z.lazy(() => EnumGameStateFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowSpectators: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowSpecials: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowChat: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowMarkDraw: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
users: z.lazy(() => User_GameUpdateManyWithoutGameNestedInputSchema).optional()
|
||||
}).strict();
|
||||
|
||||
|
@ -3060,6 +3166,10 @@ export const GameUncheckedUpdateWithoutGamePinInputSchema: z.ZodType<Prisma.Game
|
|||
createdAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
updatedAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
state: z.union([ z.lazy(() => GameStateSchema),z.lazy(() => EnumGameStateFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowSpectators: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowSpecials: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowChat: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowMarkDraw: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
users: z.lazy(() => User_GameUncheckedUpdateManyWithoutGameNestedInputSchema).optional()
|
||||
}).strict();
|
||||
|
||||
|
@ -3114,6 +3224,10 @@ export const GameCreateWithoutUsersInputSchema: z.ZodType<Prisma.GameCreateWitho
|
|||
createdAt: z.coerce.date().optional(),
|
||||
updatedAt: z.coerce.date().optional(),
|
||||
state: z.lazy(() => GameStateSchema).optional(),
|
||||
allowSpectators: z.boolean().optional(),
|
||||
allowSpecials: z.boolean().optional(),
|
||||
allowChat: z.boolean().optional(),
|
||||
allowMarkDraw: z.boolean().optional(),
|
||||
gamePin: z.lazy(() => GamepinCreateNestedOneWithoutGameInputSchema).optional()
|
||||
}).strict();
|
||||
|
||||
|
@ -3122,6 +3236,10 @@ export const GameUncheckedCreateWithoutUsersInputSchema: z.ZodType<Prisma.GameUn
|
|||
createdAt: z.coerce.date().optional(),
|
||||
updatedAt: z.coerce.date().optional(),
|
||||
state: z.lazy(() => GameStateSchema).optional(),
|
||||
allowSpectators: z.boolean().optional(),
|
||||
allowSpecials: z.boolean().optional(),
|
||||
allowChat: z.boolean().optional(),
|
||||
allowMarkDraw: z.boolean().optional(),
|
||||
gamePin: z.lazy(() => GamepinUncheckedCreateNestedOneWithoutGameInputSchema).optional()
|
||||
}).strict();
|
||||
|
||||
|
@ -3222,6 +3340,10 @@ export const GameUpdateWithoutUsersInputSchema: z.ZodType<Prisma.GameUpdateWitho
|
|||
createdAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
updatedAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
state: z.union([ z.lazy(() => GameStateSchema),z.lazy(() => EnumGameStateFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowSpectators: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowSpecials: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowChat: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowMarkDraw: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
gamePin: z.lazy(() => GamepinUpdateOneWithoutGameNestedInputSchema).optional()
|
||||
}).strict();
|
||||
|
||||
|
@ -3230,6 +3352,10 @@ export const GameUncheckedUpdateWithoutUsersInputSchema: z.ZodType<Prisma.GameUn
|
|||
createdAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
updatedAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
state: z.union([ z.lazy(() => GameStateSchema),z.lazy(() => EnumGameStateFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowSpectators: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowSpecials: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowChat: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
allowMarkDraw: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
|
||||
gamePin: z.lazy(() => GamepinUncheckedUpdateOneWithoutGameNestedInputSchema).optional()
|
||||
}).strict();
|
||||
|
||||
|
|
|
@ -75,12 +75,16 @@ enum GameState {
|
|||
}
|
||||
|
||||
model Game {
|
||||
id String @id @default(cuid())
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
state GameState @default(launching)
|
||||
gamePin Gamepin?
|
||||
users User_Game[]
|
||||
id String @id @default(cuid())
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
state GameState @default(launching)
|
||||
allowSpectators Boolean @default(true)
|
||||
allowSpecials Boolean @default(true)
|
||||
allowChat Boolean @default(true)
|
||||
allowMarkDraw Boolean @default(true)
|
||||
gamePin Gamepin?
|
||||
users User_Game[]
|
||||
}
|
||||
|
||||
model Gamepin {
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
"incremental": true,
|
||||
"paths": {
|
||||
"@lib/*": ["./lib/*"],
|
||||
"@hooks/*": ["./hooks/*"],
|
||||
"@components/*": ["./components/*"],
|
||||
"@backend/*": ["./lib/backend/*"]
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue