From 61ae4b901d269cc9a32c34774a4801df76e4752b Mon Sep 17 00:00:00 2001 From: aronmal Date: Wed, 10 May 2023 20:54:52 +0200 Subject: [PATCH] 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 --- .../components/Gamefield/Gamefield.tsx | 2 +- leaky-ships/components/Lobby/LobbyFrame.tsx | 32 ++--- .../Lobby/SettingsFrame/Setting.tsx | 53 +++++-- .../Lobby/SettingsFrame/Settings.tsx | 37 ++--- leaky-ships/components/profileImg.tsx | 13 ++ leaky-ships/{lib => }/hooks/useGameEvent.tsx | 14 +- leaky-ships/hooks/useGameProps.ts | 58 ++++++++ leaky-ships/hooks/useSocket.ts | 105 ++++++++++++++ leaky-ships/interfaces/NextApiSocket.ts | 12 +- leaky-ships/lib/getObjectChecksum.ts | 10 +- leaky-ships/lib/hooks/useGameState.tsx | 92 ------------ leaky-ships/lib/hooks/useSocket.ts | 58 -------- leaky-ships/lib/socket.ts | 1 + leaky-ships/lib/zodSchemas.ts | 48 +++++-- leaky-ships/package.json | 4 +- leaky-ships/pages/_app.tsx | 7 +- leaky-ships/pages/api/game/create.ts | 4 +- leaky-ships/pages/api/game/join.ts | 4 +- leaky-ships/pages/api/game/running.ts | 54 +++++-- leaky-ships/pages/api/ws.ts | 74 ++++++---- leaky-ships/pages/game.tsx | 17 ++- leaky-ships/pages/gamefield.tsx | 2 +- leaky-ships/pages/grid.tsx | 2 +- leaky-ships/pages/grid2.tsx | 2 +- leaky-ships/pages/index.tsx | 4 +- leaky-ships/pages/lobby.tsx | 10 +- leaky-ships/pages/start.tsx | 94 +++++++----- leaky-ships/pnpm-lock.yaml | 35 +++++ leaky-ships/prisma/generated/zod/index.ts | 136 +++++++++++++++++- leaky-ships/prisma/schema.prisma | 16 ++- leaky-ships/tsconfig.json | 2 + 31 files changed, 652 insertions(+), 350 deletions(-) create mode 100644 leaky-ships/components/profileImg.tsx rename leaky-ships/{lib => }/hooks/useGameEvent.tsx (94%) create mode 100644 leaky-ships/hooks/useGameProps.ts create mode 100644 leaky-ships/hooks/useSocket.ts delete mode 100644 leaky-ships/lib/hooks/useGameState.tsx delete mode 100644 leaky-ships/lib/hooks/useSocket.ts diff --git a/leaky-ships/components/Gamefield/Gamefield.tsx b/leaky-ships/components/Gamefield/Gamefield.tsx index 39ab1de..10ccee5 100644 --- a/leaky-ships/components/Gamefield/Gamefield.tsx +++ b/leaky-ships/components/Gamefield/Gamefield.tsx @@ -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() { diff --git a/leaky-ships/components/Lobby/LobbyFrame.tsx b/leaky-ships/components/Lobby/LobbyFrame.tsx index 8ca7d0f..b5e651d 100644 --- a/leaky-ships/components/Lobby/LobbyFrame.tsx +++ b/leaky-ships/components/Lobby/LobbyFrame.tsx @@ -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 }) {

Game-PIN:{" "} {isConnected ? ( - {payload?.gamePin?.pin ?? "---"} + {payload?.gamePin ?? "----"} ) : ( )} @@ -65,7 +50,7 @@ function LobbyFrame({ openSettings }: { openSettings: () => void }) { /> ) : (

- Warte auf {isConnected && hasJoined ? "Spieler 2" : "Verbindung"}{" "} + Warte auf {isConnected ? "Spieler 2" : "Verbindung"}{" "} {Array.from(Array(dots), () => ".").join("")} {Array.from(Array(3 - dots), (_, i) => (   @@ -74,7 +59,10 @@ function LobbyFrame({ openSettings }: { openSettings: () => void }) { )}

-
diff --git a/leaky-ships/components/Lobby/SettingsFrame/Setting.tsx b/leaky-ships/components/Lobby/SettingsFrame/Setting.tsx index b3756e2..289a22c 100644 --- a/leaky-ships/components/Lobby/SettingsFrame/Setting.tsx +++ b/leaky-ships/components/Lobby/SettingsFrame/Setting.tsx @@ -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 ( -