Finish Ultima rules. Seems ok (still potential bugs)
[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");
1d184b4c
BA
28 clients[page][sid] = socket;
29 if (page == "index")
30 {
31 // Send counting info
32 const countings = {};
33 for (const v of Variants)
34 countings[v.name] = Object.keys(clients[v.name]).length;
35 socket.send(JSON.stringify({code:"counts",counts:countings}));
36 }
37 else
38 {
39 // Send to every client connected on index an update message for counts
40 Object.keys(clients["index"]).forEach( k => {
098e8468 41 clients["index"][k].send(JSON.stringify({code:"increase",vname:page}), noop);
1d184b4c
BA
42 });
43 // Also notify potential opponents: hit all clients which check if sid corresponds
44 Object.keys(clients[page]).forEach( k => {
098e8468 45 clients[page][k].send(JSON.stringify({code:"connect",id:sid}), noop);
1d184b4c
BA
46 });
47 socket.on("message", objtxt => {
48 let obj = JSON.parse(objtxt);
49 switch (obj.code)
50 {
51 case "newmove":
a29d9d6b 52 if (!!clients[page][obj.oppid])
098e8468
BA
53 {
54 clients[page][obj.oppid].send(
55 JSON.stringify({code:"newmove",move:obj.move}), noop);
56 }
1d184b4c
BA
57 break;
58 case "ping":
a29d9d6b 59 if (!!clients[page][obj.oppid])
1d184b4c
BA
60 socket.send(JSON.stringify({code:"pong"}));
61 break;
a29d9d6b
BA
62 case "lastate":
63 if (!!clients[page][obj.oppid])
f3802fcd 64 {
ecf44502 65 const oppId = obj.oppid;
f3802fcd 66 obj.oppid = sid; //I'm oppid for my opponent
098e8468 67 clients[page][oppId].send(JSON.stringify(obj), noop);
f3802fcd 68 }
a29d9d6b 69 break;
1d184b4c
BA
70 case "newgame":
71 if (!!games[page])
72 {
73 // Start a new game
74 const oppId = games[page]["id"];
75 const fen = games[page]["fen"];
76 delete games[page];
77 const mycolor = Math.random() < 0.5 ? 'w' : 'b';
098e8468
BA
78 socket.send(
79 JSON.stringify({code:"newgame",fen:fen,oppid:oppId,color:mycolor}));
a29d9d6b 80 if (!!clients[page][oppId])
098e8468
BA
81 {
82 clients[page][oppId].send(
83 JSON.stringify(
84 {code:"newgame",fen:fen,oppid:sid,color:mycolor=="w"?"b":"w"}),
85 noop);
86 }
1d184b4c
BA
87 }
88 else
89 games[page] = {id:sid, fen:obj.fen}; //wait for opponent
90 break;
283d06a4
BA
91 case "cancelnewgame": //if a user cancel his seek
92 delete games[page];
93 break;
1d184b4c 94 case "resign":
a29d9d6b 95 if (!!clients[page][obj.oppid])
098e8468 96 clients[page][obj.oppid].send(JSON.stringify({code:"resign"}), noop);
1d184b4c
BA
97 break;
98 }
99 });
100 }
101 socket.on("close", () => {
102 delete clients[page][sid];
103 // Remove potential pending game
104 if (!!games[page] && games[page]["id"] == sid)
105 delete games[page];
106 if (page != "index")
107 {
108 // Send to every client connected on index an update message for counts
109 Object.keys(clients["index"]).forEach( k => {
098e8468 110 clients["index"][k].send(JSON.stringify({code:"decrease",vname:page}), noop);
1d184b4c
BA
111 });
112 }
113 // Also notify potential opponents: hit all clients which check if sid corresponds
114 Object.keys(clients[page]).forEach( k => {
098e8468 115 clients[page][k].send(JSON.stringify({code:"disconnect",id:sid}), noop);
1d184b4c
BA
116 });
117 });
118 });
119}