diff --git a/leaky-ships/components/Lobby/LobbyFrame.tsx b/leaky-ships/components/Lobby/LobbyFrame.tsx
index fffb44d..4c0becf 100644
--- a/leaky-ships/components/Lobby/LobbyFrame.tsx
+++ b/leaky-ships/components/Lobby/LobbyFrame.tsx
@@ -1,10 +1,12 @@
import Icon from "./Icon"
import Player from "./Player"
import useGameState from "@lib/hooks/useGameState"
+import useSocket from "@lib/hooks/useSocket"
import { Fragment, useEffect, useState } from "react"
function LobbyFrame({ openSettings }: { openSettings: () => void }) {
const { payload } = useGameState().gameProps
+ useSocket()
const [dots, setDots] = useState(1)
useEffect(() => {
@@ -18,7 +20,8 @@ function LobbyFrame({ openSettings }: { openSettings: () => void }) {
Chat
- Game-PIN: {payload?.gamePin?.pin}
+ Game-PIN:{" "}
+ {payload?.gamePin?.pin ?? "---"}
Settings
diff --git a/leaky-ships/components/SocketIO.tsx b/leaky-ships/components/SocketIO.tsx
deleted file mode 100644
index fdabef1..0000000
--- a/leaky-ships/components/SocketIO.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import { cSocket } from "../interfaces/NextApiSocket"
-import useGameState from "@lib/hooks/useGameState"
-import { useEffect } from "react"
-import { io } from "socket.io-client"
-
-let socket: cSocket
-
-function SocketIO() {
- const { session, status } = useGameState()
-
- useEffect(() => {
- if (status === "loading" || socket) return
- socket = io({
- path: "/api/ws2",
- })
-
- socket.on("connect", () => {
- console.log("connected")
- })
-
- socket.on("authenticated", () => {
- console.log("Yay!")
- })
-
- socket.on("unauthenticated", () => {
- console.log("No... pls work")
- })
-
- return () => {
- socket.off("connect")
- socket.off("authenticated")
- socket.off("unauthenticated")
- }
- }, [status])
-
- useEffect(() => {
- console.log(4, socket)
- socket?.emit("authenticate", { token: `hello from ${session?.user.email}` })
- }, [session?.user.email, status])
-
- return SocketIO
-}
-
-export default SocketIO
diff --git a/leaky-ships/interfaces/NextApiSocket.ts b/leaky-ships/interfaces/NextApiSocket.ts
index 9e31ec9..de80804 100644
--- a/leaky-ships/interfaces/NextApiSocket.ts
+++ b/leaky-ships/interfaces/NextApiSocket.ts
@@ -1,3 +1,4 @@
+import { GamePropsSchema } from "@lib/zodSchemas"
import { User } from "@prisma/client"
import type { Server as HTTPServer } from "http"
import type { Socket as NetSocket } from "net"
@@ -20,19 +21,14 @@ export interface NextApiResponseWithSocket extends NextApiResponse {
export interface ServerToClientEvents {
// noArg: () => void
// basicEmit: (a: number, b: string, c: Buffer) => void
- // withAck: (d: string, callback: (e: number) => void) => void
- "update-input": (msg: string) => void
- unauthenticated: () => void
- authenticated: () => void
- test2: (test: string) => void
- test: () => void
+ // withAck: (d: string, ) => void
+ forbidden: () => void
+ update: (game: GamePropsSchema) => void
}
export interface ClientToServerEvents {
- // hello: () => void
- "input-change": (msg: string) => void
+ join: (userId: string, callback: () => void) => void
authenticate: (payload: { token: string }) => void
- test: (payload: any) => void
}
interface InterServerEvents {
@@ -41,6 +37,7 @@ interface InterServerEvents {
interface SocketData {
user: User | null
+ gameProps: GamePropsSchema
}
export type cServer = Server<
diff --git a/leaky-ships/lib/hooks/useSocket.ts b/leaky-ships/lib/hooks/useSocket.ts
new file mode 100644
index 0000000..de8ebcb
--- /dev/null
+++ b/leaky-ships/lib/hooks/useSocket.ts
@@ -0,0 +1,58 @@
+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 socket
+}
+
+export default useSocket
diff --git a/leaky-ships/lib/socket.ts b/leaky-ships/lib/socket.ts
new file mode 100644
index 0000000..9e71296
--- /dev/null
+++ b/leaky-ships/lib/socket.ts
@@ -0,0 +1,6 @@
+import { cSocket } from "../interfaces/NextApiSocket"
+import { io } from "socket.io-client"
+
+export const socket: cSocket = io({
+ path: "/api/ws2",
+})
diff --git a/leaky-ships/pages/api/ws.ts b/leaky-ships/pages/api/ws.ts
deleted file mode 100644
index e2b9e96..0000000
--- a/leaky-ships/pages/api/ws.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import type {
- NextApiResponseWithSocket,
- cServer,
-} from "../../interfaces/NextApiSocket"
-import type { NextApiRequest } from "next"
-import { Server } from "socket.io"
-
-const SocketHandler = (req: NextApiRequest, res: NextApiResponseWithSocket) => {
- if (res.socket.server.io) {
- console.log("Socket is already running " + req.url)
- } else {
- console.log("Socket is initializing " + req.url)
- const io: cServer = new Server(res.socket.server, {
- path: "/api/ws",
- })
- res.socket.server.io = io
-
- // io.use(authenticate)
- io.on("connection", (socket) => {
- socket.on("input-change", (msg) => {
- if (!socket.data.user) socket.emit("unauthenticated")
- // socket.broadcast.emit("update-input", msg)
- io.emit("update-input", msg)
- })
-
- socket.on("test", (payload) => {
- console.log("Got test:", payload)
- // ...
- })
-
- socket.emit("test2", "lol")
- })
- }
- res.end()
-}
-
-export default SocketHandler
diff --git a/leaky-ships/pages/api/ws2.ts b/leaky-ships/pages/api/ws2.ts
index 06437ef..a32c5c7 100644
--- a/leaky-ships/pages/api/ws2.ts
+++ b/leaky-ships/pages/api/ws2.ts
@@ -2,6 +2,7 @@ import {
NextApiResponseWithSocket,
cServer,
} from "../../interfaces/NextApiSocket"
+import { composeBody, getAnyRunningGame } from "./game/running"
import prisma from "@lib/prisma"
import colors from "colors"
import { NextApiRequest } from "next"
@@ -18,7 +19,12 @@ const SocketHandler = async (
console.log("Socket is already running " + req.url)
} else {
console.log("Socket is initializing " + req.url)
- const io: cServer = new Server(res.socket.server, { path: "/api/ws2" })
+ const io: cServer = new Server(res.socket.server, {
+ path: "/api/ws2",
+ cors: {
+ origin: "https://leaky-ships.mal-noh.de",
+ },
+ })
res.socket.server.io = io
@@ -41,21 +47,34 @@ const SocketHandler = async (
})
io.on("connection", (socket) => {
- console.log(`User connected <${socket.data.user?.email}>`.green)
+ console.log(
+ `User connected <${socket.data.user?.email}>`.green,
+ socket.id
+ )
- socket.on("authenticate", (msg) => {
- // if (!socket.data.isAuthenticated) socket.emit("unauthenticated")
- // socket.broadcast.emit("update-input", msg)
- // io.emit("update-input", msg)
- console.log(msg)
+ socket.on("join", async (userId, cb) => {
+ console.log(socket.rooms, "join")
+ const game = await getAnyRunningGame(userId ?? "")
+ if (!game) {
+ const warst = socket.emit("forbidden")
+ console.log("forbidden", warst)
+ return
+ }
+ cb()
+ socket.join(userId)
+ const body = composeBody(game)
+ socket.data.gameProps = body
+ io.to(userId).emit("update", body)
})
- socket.on("test", (payload) => {
- console.log("Got test:", payload)
- // ...
+ socket.on("disconnecting", () => {
+ console.log("disconnecting", socket.rooms) // the Set contains at least the socket ID
})
- socket.emit("test2", "lol")
+ socket.on("disconnect", () => {
+ // socket.rooms.size === 0
+ console.log("disconnect", socket.id)
+ })
})
}
res.end()
diff --git a/leaky-ships/pages/socket.tsx b/leaky-ships/pages/socket.tsx
deleted file mode 100644
index fc00e5f..0000000
--- a/leaky-ships/pages/socket.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-import { cSocket } from "../interfaces/NextApiSocket"
-import useGameState from "@lib/hooks/useGameState"
-import { ChangeEventHandler, useEffect, useState } from "react"
-import { io } from "socket.io-client"
-
-let socket: cSocket
-
-const Home = () => {
- const [input, setInput] = useState("")
- const [data, setData] = useState("")
-
- const { status } = useGameState()
-
- useEffect(() => {
- if (status === "loading") return
- if (!socket) {
- console.log("Socket init.")
- socket = io({
- path: "/api/ws",
- })
- } else console.log("Socket present.")
-
- socket.on("connect", () => {
- console.log("connected")
- })
-
- socket.on("authenticated", () => {
- console.log("Yay!")
- })
-
- socket.on("unauthenticated", () => {
- console.log("No... pls work")
- })
-
- socket.on("update-input", (msg) => {
- setData(msg)
- })
-
- return () => {
- socket.off("connect")
- socket.off("authenticated")
- socket.off("unauthenticated")
- socket.off("update-input")
- }
- }, [status, setData])
-
- const onChangeHandler: ChangeEventHandler = (e) => {
- setInput(e.target.value)
- socket?.emit("input-change", e.target.value)
- }
-
- return (
- <>
- setInput(data)}
- />
- {data}
- >
- )
-}
-
-export default Home
diff --git a/leaky-ships/pages/socketio.tsx b/leaky-ships/pages/socketio.tsx
deleted file mode 100644
index b6d516a..0000000
--- a/leaky-ships/pages/socketio.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import SocketIO from "../components/SocketIO"
-
-export default function Home() {
- return (
- <>
-
-
-
-
-
- >
- )
-}