diff --git a/leaky-ships/components/Gamefield/GamefieldPointer.tsx b/leaky-ships/components/Gamefield/GamefieldPointer.tsx
index 0863826..cbcc716 100644
--- a/leaky-ships/components/Gamefield/GamefieldPointer.tsx
+++ b/leaky-ships/components/Gamefield/GamefieldPointer.tsx
@@ -22,15 +22,11 @@ function GamefieldPointer({
: { "--x1": x - 1, "--x2": x + 2, "--y1": y - 1, "--y2": y + 2 }
return (
diff --git a/leaky-ships/components/Lobby/Button.tsx b/leaky-ships/components/Lobby/Button.tsx
new file mode 100644
index 0000000..d167218
--- /dev/null
+++ b/leaky-ships/components/Lobby/Button.tsx
@@ -0,0 +1,45 @@
+import classNames from "classnames"
+import React from "react"
+import { ReactNode } from "react"
+
+function Button({
+ type,
+ disabled,
+ onClick,
+ children,
+ latching,
+ isLatched,
+}: {
+ type: "red" | "orange" | "green"
+ disabled?: boolean
+ onClick: () => void
+ children: ReactNode
+ latching?: boolean
+ isLatched?: boolean
+}) {
+ return (
+
+ )
+}
+
+export default Button
diff --git a/leaky-ships/components/Lobby/LobbyFrame.tsx b/leaky-ships/components/Lobby/LobbyFrame.tsx
index 19de8d6..d66ae44 100644
--- a/leaky-ships/components/Lobby/LobbyFrame.tsx
+++ b/leaky-ships/components/Lobby/LobbyFrame.tsx
@@ -1,6 +1,10 @@
+import Button from "./Button"
import Icon from "./Icon"
import Player from "./Player"
-import { faSpinnerThird } from "@fortawesome/pro-solid-svg-icons"
+import {
+ faRightFromBracket,
+ faSpinnerThird,
+} from "@fortawesome/pro-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { useGameProps } from "@hooks/useGameProps"
import useSocket from "@hooks/useSocket"
@@ -16,6 +20,7 @@ function WithDots({ children }: { children: string }) {
const interval = setInterval(() => setDots((e) => (e % 3) + 1), 1000)
return () => clearInterval(interval)
}, [])
+
return (
<>
{children + " "}
@@ -75,9 +80,9 @@ function LobbyFrame({ openSettings }: { openSettings: () => void }) {
)}
-
-
)
diff --git a/leaky-ships/components/Lobby/Player.tsx b/leaky-ships/components/Lobby/Player.tsx
index 33f4f5e..298cc5b 100644
--- a/leaky-ships/components/Lobby/Player.tsx
+++ b/leaky-ships/components/Lobby/Player.tsx
@@ -1,7 +1,48 @@
+import Button from "./Button"
+import {
+ faCheck,
+ faHandPointer,
+ faHourglass1,
+ faHourglass2,
+ faHourglass3,
+ faHourglassClock,
+} from "@fortawesome/pro-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faCaretDown } from "@fortawesome/sharp-solid-svg-icons"
+import { useGameProps } from "@hooks/useGameProps"
+import { socket } from "@lib/socket"
import { PlayerSchema } from "@lib/zodSchemas"
import classNames from "classnames"
+import { CSSProperties, useEffect, useMemo, useState } from "react"
+
+function HourGlass() {
+ const [count, setCount] = useState(3)
+
+ useEffect(() => {
+ const interval = setInterval(() => setCount((e) => (e + 1) % 4), 1000)
+ return () => clearInterval(interval)
+ }, [])
+
+ const icon = useMemo(() => {
+ console.log(count)
+ switch (count) {
+ case 0:
+ return faHourglass3
+ case 1:
+ return faHourglass1
+ case 2:
+ return faHourglass2
+ case 3:
+ return faHourglass3
+ default:
+ return faHourglassClock
+ }
+ }, [count])
+
+ return (
+
+ )
+}
function Player({
src,
@@ -12,19 +53,21 @@ function Player({
player?: PlayerSchema
userId?: string
}) {
- const text =
- player?.name ?? "Spieler " + (player?.index === "player2" ? "2" : "1")
- const primary = userId && userId === player?.id
+ const { setIsReady } = useGameProps()
+ const primary = useMemo(
+ () => userId && userId === player?.id,
+ [player?.id, userId]
+ )
return (
-
+
- {text}
+ {player?.name ?? "Spieler " + (player?.index === "player2" ? "2" : "1")}

@@ -39,6 +82,44 @@ function Player({
<>>
)}
+
{
+ if (!player) return
+ socket.emit("isReady", !player?.isReady)
+ setIsReady({
+ index: player.index,
+ isReady: !player?.isReady,
+ })
+ }}
+ disabled={!primary}
+ >
+ Ready
+ {player?.isReady ? (
+
+ ) : primary ? (
+
+ ) : (
+
+ )}
+
)
}
diff --git a/leaky-ships/hooks/useGameProps.ts b/leaky-ships/hooks/useGameProps.ts
index d64a1ea..3f439ee 100644
--- a/leaky-ships/hooks/useGameProps.ts
+++ b/leaky-ships/hooks/useGameProps.ts
@@ -2,6 +2,7 @@ import { GameSettings } from "@components/Lobby/SettingsFrame/Setting"
import { getPayloadwithChecksum } from "@lib/getPayloadwithChecksum"
import { socket } from "@lib/socket"
import { GamePropsSchema, PlayerSchema } from "@lib/zodSchemas"
+import { PlayerN } from "@prisma/client"
import { produce } from "immer"
import { toast } from "react-toastify"
import { create } from "zustand"
@@ -21,6 +22,7 @@ export type Action = {
}) => string | null
full: (newProps: GamePropsSchema) => void
leave: (cb: () => void) => void
+ setIsReady: (payload: { index: PlayerN; isReady: boolean }) => void
reset: () => void
}
@@ -104,6 +106,16 @@ export const useGameProps = create
()(
cb()
})
},
+ setIsReady: ({ index, isReady }) =>
+ set(
+ produce((state: State) => {
+ if (!state.payload) return
+ const player = state.payload[index]
+ if (!player) return
+ player.isReady = isReady
+ state.payload[index] = player
+ })
+ ),
reset: () => {
set(initialState)
},
diff --git a/leaky-ships/hooks/useSocket.ts b/leaky-ships/hooks/useSocket.ts
index ef7bc42..3995279 100644
--- a/leaky-ships/hooks/useSocket.ts
+++ b/leaky-ships/hooks/useSocket.ts
@@ -1,6 +1,7 @@
import { useGameProps } from "./useGameProps"
import { socket } from "@lib/socket"
import status from "http-status"
+import { useSession } from "next-auth/react"
import { useRouter } from "next/router"
import { useEffect, useState } from "react"
import { toast } from "react-toastify"
@@ -8,10 +9,18 @@ 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 { setPlayer, setSetting, full, hash: stateHash } = useGameProps()
+ const {
+ setPlayer,
+ setSetting,
+ full,
+ setIsReady,
+ hash: stateHash,
+ } = useGameProps()
+ const { data: session } = useSession()
const router = useRouter()
useEffect(() => {
+ if (!session?.user.id) return
socket.connect()
socket.on("connect", () => {
@@ -37,7 +46,8 @@ function useSocket() {
toast.warn("Es gibt Probleme mit der Echtzeitverbindung.", { toastId })
})
- socket.on("gameSetting", (payload, hash) => {
+ socket.on("gameSetting", (payload, hash, userId) => {
+ if (userId === session?.user.id) return
const newHash = setSetting(payload)
if (!newHash || newHash === hash) return
console.log("hash", hash, newHash)
@@ -47,7 +57,8 @@ function useSocket() {
})
})
- socket.on("playerEvent", (payload, hash, type) => {
+ socket.on("playerEvent", (type, payload, hash, userId) => {
+ if (userId === session?.user.id) return
let message: string
switch (type) {
case "disconnect":
@@ -59,7 +70,8 @@ function useSocket() {
break
case "join":
- if (hash === stateHash || !stateHash) return
+ console.log(hash === stateHash, !stateHash, hash, stateHash)
+ if (stateHash && hash === stateHash) return
message = "Player has joined the lobby."
break
@@ -79,6 +91,11 @@ function useSocket() {
})
})
+ socket.on("isReady", (payload, hash, userId) => {
+ if (userId === session?.user.id) return
+ setIsReady(payload)
+ })
+
socket.on("disconnect", () => {
console.log("disconnect")
setIsConnected(false)
@@ -88,7 +105,7 @@ function useSocket() {
socket.removeAllListeners()
socket.disconnect()
}
- }, [])
+ }, [session])
// useEffect(() => {
// if (!isConnected) return
diff --git a/leaky-ships/interfaces/NextApiSocket.ts b/leaky-ships/interfaces/NextApiSocket.ts
index 12467ec..6216748 100644
--- a/leaky-ships/interfaces/NextApiSocket.ts
+++ b/leaky-ships/interfaces/NextApiSocket.ts
@@ -1,6 +1,6 @@
import { GameSettings } from "@components/Lobby/SettingsFrame/Setting"
import { GamePropsSchema, PlayerSchema } from "@lib/zodSchemas"
-import { User } from "@prisma/client"
+import { PlayerN, User } from "@prisma/client"
import type { Server as HTTPServer } from "http"
import type { Socket as NetSocket } from "net"
import type { NextApiResponse } from "next"
@@ -27,16 +27,26 @@ export interface ServerToClientEvents {
// noArg: () => void
// basicEmit: (a: number, b: string, c: Buffer) => void
// withAck: (d: string, ) => void
- gameSetting: (payload: GameSettings, hash: string) => void
+ gameSetting: (payload: GameSettings, hash: string, userId: string) => void
playerEvent: (
+ type: "join" | "leave" | "disconnect",
payload: { player1?: PlayerSchema; player2?: PlayerSchema },
hash: string,
- type: "join" | "leave" | "disconnect"
+ userId: string
+ ) => void
+ isReady: (
+ payload: {
+ index: PlayerN
+ isReady: boolean
+ },
+ hash: string,
+ userId: string
) => void
}
export interface ClientToServerEvents {
update: (callback: (game: GamePropsSchema) => void) => void
+ isReady: (isReady: boolean) => void
ping: (count: number, callback: (count: number) => void) => void
join: (withAck: (ack: boolean) => void) => void
gameSetting: (payload: GameSettings, callback: (hash: string) => void) => void
diff --git a/leaky-ships/lib/zodSchemas.ts b/leaky-ships/lib/zodSchemas.ts
index 7063b29..194775a 100644
--- a/leaky-ships/lib/zodSchemas.ts
+++ b/leaky-ships/lib/zodSchemas.ts
@@ -6,12 +6,14 @@ export const PlayerSchema = z
id: z.string(),
name: z.string().nullable(),
index: z.nativeEnum(PlayerN),
+ isReady: z.boolean(),
+ isConnected: z.boolean(),
chats: z
.object({
id: z.string(),
event: z.string().nullable(),
message: z.string().nullable(),
- createdAt: z.date(),
+ createdAt: z.coerce.date(),
})
.array(),
moves: z
diff --git a/leaky-ships/pages/api/game/join.ts b/leaky-ships/pages/api/game/join.ts
index f6ca22a..beebde7 100644
--- a/leaky-ships/pages/api/game/join.ts
+++ b/leaky-ships/pages/api/game/join.ts
@@ -66,7 +66,7 @@ export default async function join(
userId: id,
index: "player2",
},
- include: {
+ select: {
game: gameSelects,
},
})
diff --git a/leaky-ships/pages/api/game/running.ts b/leaky-ships/pages/api/game/running.ts
index 85ac7ac..c3127c2 100644
--- a/leaky-ships/pages/api/game/running.ts
+++ b/leaky-ships/pages/api/game/running.ts
@@ -24,6 +24,8 @@ export const gameSelects = {
select: {
id: true,
index: true,
+ isReady: true,
+ isConnected: true,
chats: {
select: {
id: true,
diff --git a/leaky-ships/pages/api/ws.ts b/leaky-ships/pages/api/ws.ts
index f3bbc56..bce8f7d 100644
--- a/leaky-ships/pages/api/ws.ts
+++ b/leaky-ships/pages/api/ws.ts
@@ -1,7 +1,6 @@
import {
NextApiResponseWithSocket,
sServer,
- sSocket,
} from "../../interfaces/NextApiSocket"
import {
composeBody,
@@ -62,6 +61,17 @@ const SocketHandler = async (
}
socket.data.gameId = game.id
socket.join(game.id)
+
+ const { payload, hash } = composeBody(game)
+ if (!hash) return socket.disconnect()
+ io.to(game.id).emit(
+ "playerEvent",
+ "join",
+ { player1: payload?.player1, player2: payload?.player2 },
+ hash,
+ socket.data.user?.id ?? ""
+ )
+
next()
} catch (err) {
logging(status["401"], ["warn"], socket.request)
@@ -77,7 +87,6 @@ const SocketHandler = async (
["infoGreen"],
socket.request
)
- join(socket, io)
socket.on("update", async (cb) => {
const game = await getAnyGame(socket.data.gameId ?? "")
@@ -95,7 +104,12 @@ const SocketHandler = async (
const { hash } = composeBody(game)
if (!hash) return
cb(hash)
- io.to(game.id).emit("gameSetting", payload, hash)
+ io.to(game.id).emit(
+ "gameSetting",
+ payload,
+ hash,
+ socket.data.user?.id ?? ""
+ )
})
socket.on("ping", (count, callback) => {
@@ -119,25 +133,21 @@ const SocketHandler = async (
})
let body: GamePropsSchema
if (user_Game.index === "player1" && enemy) {
- body = composeBody(
- (
- await prisma.user_Game.update({
- where: {
- gameId_index: {
- gameId: socket.data.gameId,
- index: "player2",
- },
- },
- data: {
- index: "player1",
- },
-
- select: {
- game: { ...gameSelects },
- },
- })
- ).game
- )
+ const { game } = await prisma.user_Game.update({
+ where: {
+ gameId_index: {
+ gameId: socket.data.gameId,
+ index: "player2",
+ },
+ },
+ data: {
+ index: "player1",
+ },
+ select: {
+ game: { ...gameSelects },
+ },
+ })
+ body = composeBody(game)
} else {
const game = await prisma.game.findUnique({
where: {
@@ -152,9 +162,10 @@ const SocketHandler = async (
if (!payload || !hash) return cb(false)
io.to(socket.data.gameId).emit(
"playerEvent",
+ "leave",
{ player1: payload.player1, player2: payload.player2 },
hash,
- "leave"
+ socket.data.user?.id ?? ""
)
cb(true)
@@ -167,6 +178,31 @@ const SocketHandler = async (
}
})
+ socket.on("isReady", async (isReady) => {
+ const { index, game } = await prisma.user_Game.update({
+ where: {
+ gameId_userId: {
+ userId: socket.data.user?.id ?? "",
+ gameId: socket.data.gameId ?? "",
+ },
+ },
+ data: { isReady },
+ select: { index: true, game: gameSelects },
+ })
+ const payload = {
+ index,
+ isReady,
+ }
+ const { hash } = composeBody(game)
+ if (!hash) return
+ io.to(game.id).emit(
+ "isReady",
+ payload,
+ hash,
+ socket.data.user?.id ?? ""
+ )
+ })
+
socket.on("disconnecting", async () => {
logging(
"Disconnecting: " + JSON.stringify(Array.from(socket.rooms)),
@@ -195,17 +231,4 @@ const SocketHandler = async (
res.end()
}
-async function join(socket: sSocket, io: sServer) {
- const game = await getAnyGame(socket.data.gameId ?? "")
- if (!game) return socket.disconnect()
- const { payload, hash } = composeBody(game)
- if (!hash) return socket.disconnect()
- io.to(game.id).emit(
- "playerEvent",
- { player1: payload?.player1, player2: payload?.player2 },
- hash,
- "join"
- )
-}
-
export default SocketHandler
diff --git a/leaky-ships/prisma/generated/zod/index.ts b/leaky-ships/prisma/generated/zod/index.ts
index f0d595e..58a1cd5 100644
--- a/leaky-ships/prisma/generated/zod/index.ts
+++ b/leaky-ships/prisma/generated/zod/index.ts
@@ -28,7 +28,7 @@ export const TransactionIsolationLevelSchema = z.enum(['ReadUncommitted','ReadCo
export const UserScalarFieldEnumSchema = z.enum(['id','name','email','emailVerified','image','createdAt','updatedAt']);
-export const User_GameScalarFieldEnumSchema = z.enum(['id','createdAt','gameId','userId','index']);
+export const User_GameScalarFieldEnumSchema = z.enum(['id','createdAt','gameId','userId','isReady','isConnected','index']);
export const VerificationTokenScalarFieldEnumSchema = z.enum(['identifier','token','expires']);
@@ -149,6 +149,8 @@ export const User_GameSchema = z.object({
createdAt: z.coerce.date(),
gameId: z.string(),
userId: z.string(),
+ isReady: z.boolean(),
+ isConnected: z.boolean(),
})
export type User_Game = z.infer
@@ -369,6 +371,8 @@ export const User_GameSelectSchema: z.ZodType = z.object
createdAt: z.boolean().optional(),
gameId: z.boolean().optional(),
userId: z.boolean().optional(),
+ isReady: z.boolean().optional(),
+ isConnected: z.boolean().optional(),
index: z.boolean().optional(),
moves: z.union([z.boolean(),z.lazy(() => MoveFindManyArgsSchema)]).optional(),
chats: z.union([z.boolean(),z.lazy(() => ChatFindManyArgsSchema)]).optional(),
@@ -769,6 +773,8 @@ export const User_GameWhereInputSchema: z.ZodType =
createdAt: z.union([ z.lazy(() => DateTimeFilterSchema),z.coerce.date() ]).optional(),
gameId: z.union([ z.lazy(() => StringFilterSchema),z.string() ]).optional(),
userId: z.union([ z.lazy(() => StringFilterSchema),z.string() ]).optional(),
+ isReady: z.union([ z.lazy(() => BoolFilterSchema),z.boolean() ]).optional(),
+ isConnected: z.union([ z.lazy(() => BoolFilterSchema),z.boolean() ]).optional(),
index: z.union([ z.lazy(() => EnumPlayerNFilterSchema),z.lazy(() => PlayerNSchema) ]).optional(),
moves: z.lazy(() => MoveListRelationFilterSchema).optional(),
chats: z.lazy(() => ChatListRelationFilterSchema).optional(),
@@ -781,6 +787,8 @@ export const User_GameOrderByWithRelationInputSchema: z.ZodType SortOrderSchema).optional(),
gameId: z.lazy(() => SortOrderSchema).optional(),
userId: z.lazy(() => SortOrderSchema).optional(),
+ isReady: z.lazy(() => SortOrderSchema).optional(),
+ isConnected: z.lazy(() => SortOrderSchema).optional(),
index: z.lazy(() => SortOrderSchema).optional(),
moves: z.lazy(() => MoveOrderByRelationAggregateInputSchema).optional(),
chats: z.lazy(() => ChatOrderByRelationAggregateInputSchema).optional(),
@@ -799,6 +807,8 @@ export const User_GameOrderByWithAggregationInputSchema: z.ZodType SortOrderSchema).optional(),
gameId: z.lazy(() => SortOrderSchema).optional(),
userId: z.lazy(() => SortOrderSchema).optional(),
+ isReady: z.lazy(() => SortOrderSchema).optional(),
+ isConnected: z.lazy(() => SortOrderSchema).optional(),
index: z.lazy(() => SortOrderSchema).optional(),
_count: z.lazy(() => User_GameCountOrderByAggregateInputSchema).optional(),
_max: z.lazy(() => User_GameMaxOrderByAggregateInputSchema).optional(),
@@ -813,6 +823,8 @@ export const User_GameScalarWhereWithAggregatesInputSchema: z.ZodType DateTimeWithAggregatesFilterSchema),z.coerce.date() ]).optional(),
gameId: z.union([ z.lazy(() => StringWithAggregatesFilterSchema),z.string() ]).optional(),
userId: z.union([ z.lazy(() => StringWithAggregatesFilterSchema),z.string() ]).optional(),
+ isReady: z.union([ z.lazy(() => BoolWithAggregatesFilterSchema),z.boolean() ]).optional(),
+ isConnected: z.union([ z.lazy(() => BoolWithAggregatesFilterSchema),z.boolean() ]).optional(),
index: z.union([ z.lazy(() => EnumPlayerNWithAggregatesFilterSchema),z.lazy(() => PlayerNSchema) ]).optional(),
}).strict();
@@ -1342,6 +1354,8 @@ export const GamepinUncheckedUpdateManyInputSchema: z.ZodType = z.object({
id: z.string().cuid().optional(),
createdAt: z.coerce.date().optional(),
+ isReady: z.boolean().optional(),
+ isConnected: z.boolean().optional(),
index: z.lazy(() => PlayerNSchema),
moves: z.lazy(() => MoveCreateNestedManyWithoutUser_gameInputSchema).optional(),
chats: z.lazy(() => ChatCreateNestedManyWithoutUser_gameInputSchema).optional(),
@@ -1354,6 +1368,8 @@ export const User_GameUncheckedCreateInputSchema: z.ZodType PlayerNSchema),
moves: z.lazy(() => MoveUncheckedCreateNestedManyWithoutUser_gameInputSchema).optional(),
chats: z.lazy(() => ChatUncheckedCreateNestedManyWithoutUser_gameInputSchema).optional()
@@ -1362,6 +1378,8 @@ export const User_GameUncheckedCreateInputSchema: z.ZodType = z.object({
id: z.union([ z.string().cuid(),z.lazy(() => StringFieldUpdateOperationsInputSchema) ]).optional(),
createdAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
+ isReady: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
+ isConnected: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
index: z.union([ z.lazy(() => PlayerNSchema),z.lazy(() => EnumPlayerNFieldUpdateOperationsInputSchema) ]).optional(),
moves: z.lazy(() => MoveUpdateManyWithoutUser_gameNestedInputSchema).optional(),
chats: z.lazy(() => ChatUpdateManyWithoutUser_gameNestedInputSchema).optional(),
@@ -1374,6 +1392,8 @@ export const User_GameUncheckedUpdateInputSchema: z.ZodType DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
gameId: z.union([ z.string(),z.lazy(() => StringFieldUpdateOperationsInputSchema) ]).optional(),
userId: z.union([ z.string(),z.lazy(() => StringFieldUpdateOperationsInputSchema) ]).optional(),
+ isReady: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
+ isConnected: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
index: z.union([ z.lazy(() => PlayerNSchema),z.lazy(() => EnumPlayerNFieldUpdateOperationsInputSchema) ]).optional(),
moves: z.lazy(() => MoveUncheckedUpdateManyWithoutUser_gameNestedInputSchema).optional(),
chats: z.lazy(() => ChatUncheckedUpdateManyWithoutUser_gameNestedInputSchema).optional()
@@ -1384,12 +1404,16 @@ export const User_GameCreateManyInputSchema: z.ZodType PlayerNSchema)
}).strict();
export const User_GameUpdateManyMutationInputSchema: z.ZodType = z.object({
id: z.union([ z.string().cuid(),z.lazy(() => StringFieldUpdateOperationsInputSchema) ]).optional(),
createdAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
+ isReady: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
+ isConnected: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
index: z.union([ z.lazy(() => PlayerNSchema),z.lazy(() => EnumPlayerNFieldUpdateOperationsInputSchema) ]).optional(),
}).strict();
@@ -1398,6 +1422,8 @@ export const User_GameUncheckedUpdateManyInputSchema: z.ZodType DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
gameId: z.union([ z.string(),z.lazy(() => StringFieldUpdateOperationsInputSchema) ]).optional(),
userId: z.union([ z.string(),z.lazy(() => StringFieldUpdateOperationsInputSchema) ]).optional(),
+ isReady: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
+ isConnected: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
index: z.union([ z.lazy(() => PlayerNSchema),z.lazy(() => EnumPlayerNFieldUpdateOperationsInputSchema) ]).optional(),
}).strict();
@@ -1957,6 +1983,8 @@ export const User_GameCountOrderByAggregateInputSchema: z.ZodType SortOrderSchema).optional(),
gameId: z.lazy(() => SortOrderSchema).optional(),
userId: z.lazy(() => SortOrderSchema).optional(),
+ isReady: z.lazy(() => SortOrderSchema).optional(),
+ isConnected: z.lazy(() => SortOrderSchema).optional(),
index: z.lazy(() => SortOrderSchema).optional()
}).strict();
@@ -1965,6 +1993,8 @@ export const User_GameMaxOrderByAggregateInputSchema: z.ZodType SortOrderSchema).optional(),
gameId: z.lazy(() => SortOrderSchema).optional(),
userId: z.lazy(() => SortOrderSchema).optional(),
+ isReady: z.lazy(() => SortOrderSchema).optional(),
+ isConnected: z.lazy(() => SortOrderSchema).optional(),
index: z.lazy(() => SortOrderSchema).optional()
}).strict();
@@ -1973,6 +2003,8 @@ export const User_GameMinOrderByAggregateInputSchema: z.ZodType SortOrderSchema).optional(),
gameId: z.lazy(() => SortOrderSchema).optional(),
userId: z.lazy(() => SortOrderSchema).optional(),
+ isReady: z.lazy(() => SortOrderSchema).optional(),
+ isConnected: z.lazy(() => SortOrderSchema).optional(),
index: z.lazy(() => SortOrderSchema).optional()
}).strict();
@@ -2856,6 +2888,8 @@ export const UserUncheckedUpdateWithoutSessionsInputSchema: z.ZodType = z.object({
id: z.string().cuid().optional(),
createdAt: z.coerce.date().optional(),
+ isReady: z.boolean().optional(),
+ isConnected: z.boolean().optional(),
index: z.lazy(() => PlayerNSchema),
moves: z.lazy(() => MoveCreateNestedManyWithoutUser_gameInputSchema).optional(),
chats: z.lazy(() => ChatCreateNestedManyWithoutUser_gameInputSchema).optional(),
@@ -2866,6 +2900,8 @@ export const User_GameUncheckedCreateWithoutUserInputSchema: z.ZodType PlayerNSchema),
moves: z.lazy(() => MoveUncheckedCreateNestedManyWithoutUser_gameInputSchema).optional(),
chats: z.lazy(() => ChatUncheckedCreateNestedManyWithoutUser_gameInputSchema).optional()
@@ -2971,6 +3007,8 @@ export const User_GameScalarWhereInputSchema: z.ZodType DateTimeFilterSchema),z.coerce.date() ]).optional(),
gameId: z.union([ z.lazy(() => StringFilterSchema),z.string() ]).optional(),
userId: z.union([ z.lazy(() => StringFilterSchema),z.string() ]).optional(),
+ isReady: z.union([ z.lazy(() => BoolFilterSchema),z.boolean() ]).optional(),
+ isConnected: z.union([ z.lazy(() => BoolFilterSchema),z.boolean() ]).optional(),
index: z.union([ z.lazy(() => EnumPlayerNFilterSchema),z.lazy(() => PlayerNSchema) ]).optional(),
}).strict();
@@ -3057,6 +3095,8 @@ export const GamepinCreateOrConnectWithoutGameInputSchema: z.ZodType = z.object({
id: z.string().cuid().optional(),
createdAt: z.coerce.date().optional(),
+ isReady: z.boolean().optional(),
+ isConnected: z.boolean().optional(),
index: z.lazy(() => PlayerNSchema),
moves: z.lazy(() => MoveCreateNestedManyWithoutUser_gameInputSchema).optional(),
chats: z.lazy(() => ChatCreateNestedManyWithoutUser_gameInputSchema).optional(),
@@ -3067,6 +3107,8 @@ export const User_GameUncheckedCreateWithoutGameInputSchema: z.ZodType PlayerNSchema),
moves: z.lazy(() => MoveUncheckedCreateNestedManyWithoutUser_gameInputSchema).optional(),
chats: z.lazy(() => ChatUncheckedCreateNestedManyWithoutUser_gameInputSchema).optional()
@@ -3391,6 +3433,8 @@ export const UserUncheckedUpdateWithoutGamesInputSchema: z.ZodType = z.object({
id: z.string().cuid().optional(),
createdAt: z.coerce.date().optional(),
+ isReady: z.boolean().optional(),
+ isConnected: z.boolean().optional(),
index: z.lazy(() => PlayerNSchema),
chats: z.lazy(() => ChatCreateNestedManyWithoutUser_gameInputSchema).optional(),
game: z.lazy(() => GameCreateNestedOneWithoutUsersInputSchema),
@@ -3402,6 +3446,8 @@ export const User_GameUncheckedCreateWithoutMovesInputSchema: z.ZodType PlayerNSchema),
chats: z.lazy(() => ChatUncheckedCreateNestedManyWithoutUser_gameInputSchema).optional()
}).strict();
@@ -3419,6 +3465,8 @@ export const User_GameUpsertWithoutMovesInputSchema: z.ZodType = z.object({
id: z.union([ z.string().cuid(),z.lazy(() => StringFieldUpdateOperationsInputSchema) ]).optional(),
createdAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
+ isReady: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
+ isConnected: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
index: z.union([ z.lazy(() => PlayerNSchema),z.lazy(() => EnumPlayerNFieldUpdateOperationsInputSchema) ]).optional(),
chats: z.lazy(() => ChatUpdateManyWithoutUser_gameNestedInputSchema).optional(),
game: z.lazy(() => GameUpdateOneRequiredWithoutUsersNestedInputSchema).optional(),
@@ -3430,6 +3478,8 @@ export const User_GameUncheckedUpdateWithoutMovesInputSchema: z.ZodType DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
gameId: z.union([ z.string(),z.lazy(() => StringFieldUpdateOperationsInputSchema) ]).optional(),
userId: z.union([ z.string(),z.lazy(() => StringFieldUpdateOperationsInputSchema) ]).optional(),
+ isReady: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
+ isConnected: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
index: z.union([ z.lazy(() => PlayerNSchema),z.lazy(() => EnumPlayerNFieldUpdateOperationsInputSchema) ]).optional(),
chats: z.lazy(() => ChatUncheckedUpdateManyWithoutUser_gameNestedInputSchema).optional()
}).strict();
@@ -3437,6 +3487,8 @@ export const User_GameUncheckedUpdateWithoutMovesInputSchema: z.ZodType = z.object({
id: z.string().cuid().optional(),
createdAt: z.coerce.date().optional(),
+ isReady: z.boolean().optional(),
+ isConnected: z.boolean().optional(),
index: z.lazy(() => PlayerNSchema),
moves: z.lazy(() => MoveCreateNestedManyWithoutUser_gameInputSchema).optional(),
game: z.lazy(() => GameCreateNestedOneWithoutUsersInputSchema),
@@ -3448,6 +3500,8 @@ export const User_GameUncheckedCreateWithoutChatsInputSchema: z.ZodType PlayerNSchema),
moves: z.lazy(() => MoveUncheckedCreateNestedManyWithoutUser_gameInputSchema).optional()
}).strict();
@@ -3465,6 +3519,8 @@ export const User_GameUpsertWithoutChatsInputSchema: z.ZodType = z.object({
id: z.union([ z.string().cuid(),z.lazy(() => StringFieldUpdateOperationsInputSchema) ]).optional(),
createdAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
+ isReady: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
+ isConnected: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
index: z.union([ z.lazy(() => PlayerNSchema),z.lazy(() => EnumPlayerNFieldUpdateOperationsInputSchema) ]).optional(),
moves: z.lazy(() => MoveUpdateManyWithoutUser_gameNestedInputSchema).optional(),
game: z.lazy(() => GameUpdateOneRequiredWithoutUsersNestedInputSchema).optional(),
@@ -3476,6 +3532,8 @@ export const User_GameUncheckedUpdateWithoutChatsInputSchema: z.ZodType DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
gameId: z.union([ z.string(),z.lazy(() => StringFieldUpdateOperationsInputSchema) ]).optional(),
userId: z.union([ z.string(),z.lazy(() => StringFieldUpdateOperationsInputSchema) ]).optional(),
+ isReady: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
+ isConnected: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
index: z.union([ z.lazy(() => PlayerNSchema),z.lazy(() => EnumPlayerNFieldUpdateOperationsInputSchema) ]).optional(),
moves: z.lazy(() => MoveUncheckedUpdateManyWithoutUser_gameNestedInputSchema).optional()
}).strict();
@@ -3484,6 +3542,8 @@ export const User_GameCreateManyUserInputSchema: z.ZodType PlayerNSchema)
}).strict();
@@ -3513,6 +3573,8 @@ export const SessionCreateManyUserInputSchema: z.ZodType = z.object({
id: z.union([ z.string().cuid(),z.lazy(() => StringFieldUpdateOperationsInputSchema) ]).optional(),
createdAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
+ isReady: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
+ isConnected: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
index: z.union([ z.lazy(() => PlayerNSchema),z.lazy(() => EnumPlayerNFieldUpdateOperationsInputSchema) ]).optional(),
moves: z.lazy(() => MoveUpdateManyWithoutUser_gameNestedInputSchema).optional(),
chats: z.lazy(() => ChatUpdateManyWithoutUser_gameNestedInputSchema).optional(),
@@ -3523,6 +3585,8 @@ export const User_GameUncheckedUpdateWithoutUserInputSchema: z.ZodType StringFieldUpdateOperationsInputSchema) ]).optional(),
createdAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
gameId: z.union([ z.string(),z.lazy(() => StringFieldUpdateOperationsInputSchema) ]).optional(),
+ isReady: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
+ isConnected: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
index: z.union([ z.lazy(() => PlayerNSchema),z.lazy(() => EnumPlayerNFieldUpdateOperationsInputSchema) ]).optional(),
moves: z.lazy(() => MoveUncheckedUpdateManyWithoutUser_gameNestedInputSchema).optional(),
chats: z.lazy(() => ChatUncheckedUpdateManyWithoutUser_gameNestedInputSchema).optional()
@@ -3532,6 +3596,8 @@ export const User_GameUncheckedUpdateManyWithoutGamesInputSchema: z.ZodType StringFieldUpdateOperationsInputSchema) ]).optional(),
createdAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
gameId: z.union([ z.string(),z.lazy(() => StringFieldUpdateOperationsInputSchema) ]).optional(),
+ isReady: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
+ isConnected: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
index: z.union([ z.lazy(() => PlayerNSchema),z.lazy(() => EnumPlayerNFieldUpdateOperationsInputSchema) ]).optional(),
}).strict();
@@ -3608,12 +3674,16 @@ export const User_GameCreateManyGameInputSchema: z.ZodType PlayerNSchema)
}).strict();
export const User_GameUpdateWithoutGameInputSchema: z.ZodType = z.object({
id: z.union([ z.string().cuid(),z.lazy(() => StringFieldUpdateOperationsInputSchema) ]).optional(),
createdAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
+ isReady: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
+ isConnected: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
index: z.union([ z.lazy(() => PlayerNSchema),z.lazy(() => EnumPlayerNFieldUpdateOperationsInputSchema) ]).optional(),
moves: z.lazy(() => MoveUpdateManyWithoutUser_gameNestedInputSchema).optional(),
chats: z.lazy(() => ChatUpdateManyWithoutUser_gameNestedInputSchema).optional(),
@@ -3624,6 +3694,8 @@ export const User_GameUncheckedUpdateWithoutGameInputSchema: z.ZodType StringFieldUpdateOperationsInputSchema) ]).optional(),
createdAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
userId: z.union([ z.string(),z.lazy(() => StringFieldUpdateOperationsInputSchema) ]).optional(),
+ isReady: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
+ isConnected: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
index: z.union([ z.lazy(() => PlayerNSchema),z.lazy(() => EnumPlayerNFieldUpdateOperationsInputSchema) ]).optional(),
moves: z.lazy(() => MoveUncheckedUpdateManyWithoutUser_gameNestedInputSchema).optional(),
chats: z.lazy(() => ChatUncheckedUpdateManyWithoutUser_gameNestedInputSchema).optional()
@@ -3633,6 +3705,8 @@ export const User_GameUncheckedUpdateManyWithoutUsersInputSchema: z.ZodType StringFieldUpdateOperationsInputSchema) ]).optional(),
createdAt: z.union([ z.coerce.date(),z.lazy(() => DateTimeFieldUpdateOperationsInputSchema) ]).optional(),
userId: z.union([ z.string(),z.lazy(() => StringFieldUpdateOperationsInputSchema) ]).optional(),
+ isReady: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
+ isConnected: z.union([ z.boolean(),z.lazy(() => BoolFieldUpdateOperationsInputSchema) ]).optional(),
index: z.union([ z.lazy(() => PlayerNSchema),z.lazy(() => EnumPlayerNFieldUpdateOperationsInputSchema) ]).optional(),
}).strict();
diff --git a/leaky-ships/prisma/schema.prisma b/leaky-ships/prisma/schema.prisma
index 2ad2558..d0caafc 100644
--- a/leaky-ships/prisma/schema.prisma
+++ b/leaky-ships/prisma/schema.prisma
@@ -101,15 +101,17 @@ enum PlayerN {
}
model User_Game {
- id String @id @default(cuid())
- createdAt DateTime @default(now())
- gameId String
- userId String
- index PlayerN
- moves Move[]
- chats Chat[]
- game Game @relation(fields: [gameId], references: [id], onDelete: Cascade)
- user User @relation(fields: [userId], references: [id])
+ id String @id @default(cuid())
+ createdAt DateTime @default(now())
+ gameId String
+ userId String
+ isReady Boolean @default(false)
+ isConnected Boolean @default(false)
+ index PlayerN
+ moves Move[]
+ chats Chat[]
+ game Game @relation(fields: [gameId], references: [id], onDelete: Cascade)
+ user User @relation(fields: [userId], references: [id])
@@unique([gameId, index])
@@unique([gameId, userId])