puzzle/server/index.js

126 lines
3.3 KiB
JavaScript
Raw Normal View History

2020-11-07 11:35:29 +01:00
import WebSocketServer from './WebSocketServer.js'
import express from 'express'
2020-11-08 14:13:43 +01:00
import { createPuzzle } from './puzzle.js'
2020-11-07 12:21:38 +01:00
import config from './config.js'
2020-11-08 14:49:34 +01:00
import { uniqId, choice } from './util.js'
2020-11-07 12:21:38 +01:00
2020-11-08 14:13:43 +01:00
// desired number of tiles
// actual calculated number can be higher
2020-11-08 16:42:59 +01:00
const TARGET_TILES = 500
2020-11-08 14:13:43 +01:00
const IMAGES = [
'/example-images/ima_86ec3fa.jpeg',
'/example-images/bleu.png',
'/example-images/saechsische_schweiz.jpg',
'/example-images/132-2048x1365.jpg',
]
const games = {}
2020-11-07 12:21:38 +01:00
const port = config.http.port
const hostname = config.http.hostname
2020-11-07 11:35:29 +01:00
const app = express()
2020-11-07 12:21:38 +01:00
const statics = express.static('./../game/')
2020-11-08 14:49:34 +01:00
app.use('/g/:gid', (req, res, next) => {
res.send(`
<html><head><style>
html,body {margin: 0; overflow: hidden;}
html, body, #main { background: #222 }
canvas {cursor: none;}
</style></head><body>
<script>window.GAME_ID = '${req.params.gid}'</script>
<script>window.WS_ADDRESS = '${config.ws.connectstring}'</script>
<script src="/index.js" type="module"></script>
</body>
</html>
`)
})
2020-11-07 12:21:38 +01:00
app.use('/', (req, res, next) => {
if (req.path === '/') {
res.send(`
<html><head><style>
html,body {margin: 0; overflow: hidden;}
html, body, #main { background: #222 }
</style></head><body>
2020-11-08 14:49:34 +01:00
<a href="/g/${uniqId()}">New game :P</a>
${Object.keys(games).map(k => {
return `<a href="/g/${k}">Game ${k}</a>`
})}
2020-11-07 12:21:38 +01:00
</body>
</html>
`)
} else {
statics(req, res, next)
}
})
2020-11-07 11:35:29 +01:00
2020-11-07 12:21:38 +01:00
const wss = new WebSocketServer(config.ws);
2020-11-07 11:35:29 +01:00
2020-11-08 17:11:32 +01:00
const notify = (data, sockets) => {
2020-11-07 11:35:29 +01:00
// TODO: throttle
2020-11-08 17:11:32 +01:00
for (let socket of sockets) {
wss.notifyOne(data, socket)
}
2020-11-07 11:35:29 +01:00
console.log('notify', data)
}
2020-11-08 14:13:43 +01:00
wss.on('message', async ({socket, data}) => {
2020-11-07 11:35:29 +01:00
try {
const proto = socket.protocol.split('|')
const uid = proto[0]
const gid = proto[1]
const parsed = JSON.parse(data)
switch (parsed.type) {
case 'init': {
// a new player (or previous player) joined
2020-11-08 17:11:32 +01:00
games[gid] = games[gid] || {
puzzle: await createPuzzle(TARGET_TILES, choice(IMAGES)),
players: {},
sockets: []
}
if (!games[gid].sockets.includes(socket)) {
games[gid].sockets.push(socket)
}
2020-11-08 01:56:36 +01:00
games[gid].players[uid] = {id: uid, x: 0, y: 0, down: false}
2020-11-07 16:33:28 +01:00
wss.notifyOne({
type: 'init',
2020-11-08 01:56:36 +01:00
game: {
puzzle: games[gid].puzzle,
players: games[gid].players,
},
2020-11-07 16:33:28 +01:00
}, socket)
2020-11-07 11:35:29 +01:00
} break;
2020-11-07 16:33:28 +01:00
// somebody has changed the state
2020-11-07 11:35:29 +01:00
case 'state': {
2020-11-07 16:33:28 +01:00
for (let change of parsed.state.changes) {
switch (change.type) {
case 'change_player': {
games[gid].players[uid] = change.player
} break;
case 'change_tile': {
games[gid].puzzle.tiles[change.tile.idx] = change.tile
} break;
case 'change_data': {
games[gid].puzzle.data = change.data
} break;
}
}
2020-11-08 17:11:32 +01:00
notify({
type:'state_changed',
origin: uid,
changes: parsed.state.changes,
}, games[gid].sockets)
2020-11-07 11:35:29 +01:00
} break;
}
} catch (e) {
console.error(e)
}
})
2020-11-08 16:42:59 +01:00
app.listen(port, hostname, () => console.log(`server running on http://${hostname}:${port}`))
2020-11-07 11:35:29 +01:00
wss.listen()