-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
133 lines (114 loc) · 2.93 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import * as http from "http"
import * as path from "path"
import express from "express"
import { Server as WebSocketServer, WebSocket } from "ws"
const port = 1234
const app = express()
const server = http.createServer(app)
const wss = new WebSocketServer({ server: server, path: "/ws" })
export type MessageConnect = {
event: "connect"
code: string
nickname: string
player: "P1" | "P2"
}
export type MessageTokenPlaced = {
player: "P1" | "P2"
event: "tokenPlaced"
code: string
x: number
}
export type MessageOpponentConnected = {
opponent: {
nickname: string
player: "P1" | "P2"
}
event: "opponentIsConnected"
}
type PlayerState = {
nickname: string
client: WebSocket
}
type GameState = {
P1?: PlayerState
P2?: PlayerState
}
const games: Record<string, GameState> = {}
const generateCode = (): string => {
const code = Math.floor(1000 + Math.random() * 9000)
if (code in games) {
return generateCode()
}
return code.toString()
}
const opponentTo = (player: "P1" | "P2") => {
return player === "P1" ? "P2" : "P1"
}
wss.on("connection", (ws) => {
console.log("client connected")
ws.on("message", (buf: Buffer) => {
const data = JSON.parse(buf.toString()) as
| MessageConnect
| MessageTokenPlaced
console.log(data)
switch (data.event) {
case "connect": {
const { code, nickname, player } = data
console.log("on connect", games)
if (!(code in games)) {
games[code] = {}
}
games[code][player] = { nickname, client: ws }
const opponent = opponentTo(player)
if (opponent in games[code]) {
games[code][opponent]!.client.send(
JSON.stringify({
opponent: { nickname, player },
event: "opponentIsConnected",
} satisfies MessageOpponentConnected),
)
ws.send(
JSON.stringify({
opponent: {
nickname: games[code][opponent]!.nickname,
player: opponent,
},
event: "opponentIsConnected",
} satisfies MessageOpponentConnected),
)
}
break
}
case "tokenPlaced": {
const { player, code } = data
games[code][opponentTo(player)]?.client.send(buf.toString())
break
}
default: {
console.log("Could not handle message:", data)
break
}
}
})
ws.on("close", () => {
console.log("client has disconnected")
})
})
app.use(express.static(path.join(__dirname, "/dist/")))
app.get(["/game", "/singleplayer", "/multiplayer"], (req, res) => {
res.sendFile(path.join(__dirname, "/dist/index.html"))
})
export type GameExistsResponse = { gameExists: boolean }
app.get("/api/game-exists", (req, res) => {
const code = req.query?.code as string
console.log("game-exists", games, code, { gameExists: code in games })
res.json({ gameExists: code in games } satisfies GameExistsResponse)
})
app.post("/api/new-game", (req, res) => {
const code = generateCode()
games[code] = {}
console.log("new game", games)
res.json({ code })
})
console.log("Listening on port", port)
server.listen(port, "0.0.0.0")