Fix '3 knights' bug + tiny advance on problems tab
[vchess.git] / sockets.js
CommitLineData
a29d9d6b 1const url = require('url');
1d184b4c
BA
2const Variants = require("./variants");
3
1d184b4c
BA
4module.exports = function(wss) {
5
6 let clients = { "index": {} };
7 let games = {}; //pending games (player sid)
8 for (const v of Variants)
9 clients[v.name] = {};
10
098e8468
BA
11// // Safety counter (TODO: is it necessary ?)
12// setInterval(() => {
13// Object.keys(clients).forEach(k => {
14// Object.keys(clients[k]).forEach(ck => {
15// if (!clients[k][ck] || clients[k][ck].readyState != 1)
16// delete clients[k][ck];
17// });
18// });
19// }, 60000); //every minute (will be lowered if a lot of users...)
20
21 // No-op function as a callback when sending messages
22 const noop = () => { };
23
1d184b4c 24 wss.on("connection", (socket, req) => {
a29d9d6b
BA
25 const params = new URL("http://localhost" + req.url).searchParams;
26 const sid = params.get("sid");
27 const page = params.get("page");
15c1295a
BA
28 // Ignore duplicate connections:
29 if (!!clients[page][sid])
30 {
31 socket.send(JSON.stringify({code:"duplicate"}));
32 return;
33 }
1d184b4c
BA
34 clients[page][sid] = socket;
35 if (page == "index")
36 {
37 // Send counting info
38 const countings = {};
39 for (const v of Variants)
40 countings[v.name] = Object.keys(clients[v.name]).length;
41 socket.send(JSON.stringify({code:"counts",counts:countings}));
42 }
43 else
44 {
45 // Send to every client connected on index an update message for counts
46 Object.keys(clients["index"]).forEach( k => {
098e8468 47 clients["index"][k].send(JSON.stringify({code:"increase",vname:page}), noop);
1d184b4c
BA
48 });
49 // Also notify potential opponents: hit all clients which check if sid corresponds
50 Object.keys(clients[page]).forEach( k => {
098e8468 51 clients[page][k].send(JSON.stringify({code:"connect",id:sid}), noop);
1d184b4c
BA
52 });
53 socket.on("message", objtxt => {
54 let obj = JSON.parse(objtxt);
55 switch (obj.code)
56 {
57 case "newmove":
a29d9d6b 58 if (!!clients[page][obj.oppid])
098e8468
BA
59 {
60 clients[page][obj.oppid].send(
61 JSON.stringify({code:"newmove",move:obj.move}), noop);
62 }
1d184b4c
BA
63 break;
64 case "ping":
a29d9d6b 65 if (!!clients[page][obj.oppid])
1d184b4c
BA
66 socket.send(JSON.stringify({code:"pong"}));
67 break;
a29d9d6b
BA
68 case "lastate":
69 if (!!clients[page][obj.oppid])
f3802fcd 70 {
ecf44502 71 const oppId = obj.oppid;
f3802fcd 72 obj.oppid = sid; //I'm oppid for my opponent
098e8468 73 clients[page][oppId].send(JSON.stringify(obj), noop);
f3802fcd 74 }
a29d9d6b 75 break;
1d184b4c
BA
76 case "newgame":
77 if (!!games[page])
78 {
79 // Start a new game
80 const oppId = games[page]["id"];
81 const fen = games[page]["fen"];
82 delete games[page];
83 const mycolor = Math.random() < 0.5 ? 'w' : 'b';
098e8468
BA
84 socket.send(
85 JSON.stringify({code:"newgame",fen:fen,oppid:oppId,color:mycolor}));
a29d9d6b 86 if (!!clients[page][oppId])
098e8468
BA
87 {
88 clients[page][oppId].send(
89 JSON.stringify(
90 {code:"newgame",fen:fen,oppid:sid,color:mycolor=="w"?"b":"w"}),
91 noop);
92 }
1d184b4c
BA
93 }
94 else
95 games[page] = {id:sid, fen:obj.fen}; //wait for opponent
96 break;
283d06a4
BA
97 case "cancelnewgame": //if a user cancel his seek
98 delete games[page];
99 break;
1d184b4c 100 case "resign":
a29d9d6b 101 if (!!clients[page][obj.oppid])
098e8468 102 clients[page][obj.oppid].send(JSON.stringify({code:"resign"}), noop);
1d184b4c
BA
103 break;
104 }
105 });
106 }
107 socket.on("close", () => {
108 delete clients[page][sid];
109 // Remove potential pending game
110 if (!!games[page] && games[page]["id"] == sid)
111 delete games[page];
112 if (page != "index")
113 {
114 // Send to every client connected on index an update message for counts
115 Object.keys(clients["index"]).forEach( k => {
098e8468 116 clients["index"][k].send(JSON.stringify({code:"decrease",vname:page}), noop);
1d184b4c
BA
117 });
118 }
119 // Also notify potential opponents: hit all clients which check if sid corresponds
120 Object.keys(clients[page]).forEach( k => {
098e8468 121 clients[page][k].send(JSON.stringify({code:"disconnect",id:sid}), noop);
1d184b4c
BA
122 });
123 });
124 });
125}