Working real time lobby

This commit is contained in:
aronmal 2023-05-13 15:03:12 +02:00
parent 61ae4b901d
commit f1ea064d4c
Signed by: aronmal
GPG key ID: 816B7707426FC612
13 changed files with 386 additions and 152 deletions

View file

@ -1,16 +1,26 @@
import { GameSettings } from "@components/Lobby/SettingsFrame/Setting"
import { GamePropsSchema } from "@lib/zodSchemas"
import { getPayloadwithChecksum } from "@lib/getPayloadwithChecksum"
import { socket } from "@lib/socket"
import { GamePropsSchema, PlayerSchema } from "@lib/zodSchemas"
import { produce } from "immer"
import { toast } from "react-toastify"
import { create } from "zustand"
import { devtools } from "zustand/middleware"
const initialState: GamePropsSchema = { payload: null, hash: null }
const initialState: GamePropsSchema & {
queue: { payload: string; hash: string }[]
} = { payload: null, hash: null, queue: [] }
type State = GamePropsSchema
export type State = typeof initialState
type Action = {
setSetting: (by: GameSettings) => void
export type Action = {
setSetting: (settings: GameSettings) => string | null
setPlayer: (payload: {
player1?: PlayerSchema
player2?: PlayerSchema
}) => string | null
full: (newProps: GamePropsSchema) => void
leave: (cb: () => void) => void
reset: () => void
}
@ -18,13 +28,52 @@ export const useGameProps = create<State & Action>()(
devtools(
(set) => ({
...initialState,
setSetting: (settings) =>
setPlayer: (payload) => {
let hash: string | null = null
set(
produce((state: State) => {
if (!state.payload) return
Object.assign(state.payload, payload)
const body = getPayloadwithChecksum(state.payload)
if (!body.hash) {
toast.warn("Something is wrong... ", {
toastId: "st_wrong",
theme: "colored",
})
return
}
hash = body.hash
state.hash = hash
})
)
return hash
},
setSetting: (settings) => {
const payload = JSON.stringify(settings)
let hash: string | null = null
set(
produce((state: State) => {
const length = state.queue.length
state.queue.filter((e) => e.payload !== payload || e.hash !== hash)
if (state.queue.length !== length) return
if (!state.payload?.game) return
Object.assign(state.payload.game, settings)
const body = getPayloadwithChecksum(state.payload)
if (!body.hash) {
toast.warn("Something is wrong... ", {
toastId: "st_wrong",
theme: "colored",
})
return
}
hash = body.hash
state.hash = hash
state.queue.push({ payload, hash })
})
),
)
return hash
},
full: (newGameProps) =>
set((state) => {
if (state.hash === newGameProps.hash) {
@ -47,6 +96,14 @@ export const useGameProps = create<State & Action>()(
}
return state
}),
leave: (cb) => {
socket.emit("leave", (ack) => {
if (!ack) {
toast.error("Something is wrong...")
}
cb()
})
},
reset: () => {
set(initialState)
},