Fix two bugs in Ultima isAttackedBy...
[vchess.git] / sockets.js
1 const url = require('url');
2 const Variants = require("./variants");
3
4 module.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
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
24 wss.on("connection", (socket, req) => {
25 const params = new URL("http://localhost" + req.url).searchParams;
26 const sid = params.get("sid");
27 const page = params.get("page");
28 // Ignore duplicate connections:
29 if (!!clients[page][sid])
30 {
31 socket.send(JSON.stringify({code:"duplicate"}));
32 return;
33 }
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 => {
47 clients["index"][k].send(JSON.stringify({code:"increase",vname:page}), noop);
48 });
49 // Also notify potential opponents: hit all clients which check if sid corresponds
50 Object.keys(clients[page]).forEach( k => {
51 clients[page][k].send(JSON.stringify({code:"connect",id:sid}), noop);
52 });
53 socket.on("message", objtxt => {
54 let obj = JSON.parse(objtxt);
55 switch (obj.code)
56 {
57 case "newmove":
58 if (!!clients[page][obj.oppid])
59 {
60 clients[page][obj.oppid].send(
61 JSON.stringify({code:"newmove",move:obj.move}), noop);
62 }
63 break;
64 case "ping":
65 if (!!clients[page][obj.oppid])
66 socket.send(JSON.stringify({code:"pong"}));
67 break;
68 case "lastate":
69 if (!!clients[page][obj.oppid])
70 {
71 const oppId = obj.oppid;
72 obj.oppid = sid; //I'm oppid for my opponent
73 clients[page][oppId].send(JSON.stringify(obj), noop);
74 }
75 break;
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';
84 socket.send(
85 JSON.stringify({code:"newgame",fen:fen,oppid:oppId,color:mycolor}));
86 if (!!clients[page][oppId])
87 {
88 clients[page][oppId].send(
89 JSON.stringify(
90 {code:"newgame",fen:fen,oppid:sid,color:mycolor=="w"?"b":"w"}),
91 noop);
92 }
93 }
94 else
95 games[page] = {id:sid, fen:obj.fen}; //wait for opponent
96 break;
97 case "cancelnewgame": //if a user cancel his seek
98 delete games[page];
99 break;
100 case "resign":
101 if (!!clients[page][obj.oppid])
102 clients[page][obj.oppid].send(JSON.stringify({code:"resign"}), noop);
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 => {
116 clients["index"][k].send(JSON.stringify({code:"decrease",vname:page}), noop);
117 });
118 }
119 // Also notify potential opponents: hit all clients which check if sid corresponds
120 Object.keys(clients[page]).forEach( k => {
121 clients[page][k].send(JSON.stringify({code:"disconnect",id:sid}), noop);
122 });
123 });
124 });
125 }