Saving current state
[vchess.git] / sockets.js
CommitLineData
a29d9d6b 1const url = require('url');
da06a6eb 2const sqlite3 = require('sqlite3');
a48ee8b8 3const db = new sqlite3.Database(__dirname + "/db/vchess.sqlite");
1d184b4c 4
2807f530
BA
5// Node version in Ubuntu 16.04 does not know about URL class
6function getJsonFromUrl(url) {
7 var query = url.substr(2); //starts with "/?"
8 var result = {};
9 query.split("&").forEach(function(part) {
10 var item = part.split("=");
11 result[item[0]] = decodeURIComponent(item[1]);
12 });
13 return result;
14}
15
b57dbd12
BA
16// TODO: empêcher multi-log du même user (envoyer le user ID + secret en même temps que name et...)
17// --> si secret ne matche pas celui trouvé en DB, stop
18
1d184b4c 19module.exports = function(wss) {
da06a6eb
BA
20 db.serialize(function() {
21 db.all("SELECT * FROM Variants", (err,variants) => {
22 let clients = { "index": {} };
23 let games = {}; //pending games (player sid)
24 for (const v of variants)
25 clients[v.name] = {};
26 // No-op function as a callback when sending messages
27 const noop = () => { };
28 wss.on("connection", (socket, req) => {
2807f530
BA
29// const params = new URL("http://localhost" + req.url).searchParams;
30// const sid = params.get("sid");
31// const page = params.get("page");
32 var query = getJsonFromUrl(req.url);
33 const sid = query["sid"];
34 const page = query["page"];
da06a6eb
BA
35 // Ignore duplicate connections:
36 if (!!clients[page][sid])
1d184b4c 37 {
da06a6eb
BA
38 socket.send(JSON.stringify({code:"duplicate"}));
39 return;
40 }
41 clients[page][sid] = socket;
42 if (page == "index")
43 {
44 // Send counting info
45 const countings = {};
46 for (const v of variants)
47 countings[v.name] = Object.keys(clients[v.name]).length;
48 socket.send(JSON.stringify({code:"counts",counts:countings}));
49 }
50 else
51 {
52 // Send to every client connected on index an update message for counts
53 Object.keys(clients["index"]).forEach( k => {
54 clients["index"][k].send(
55 JSON.stringify({code:"increase",vname:page}), noop);
56 });
57 // Also notify potential opponents:
58 // hit all clients which check if sid corresponds
59 Object.keys(clients[page]).forEach( k => {
60 clients[page][k].send(JSON.stringify({code:"connect",id:sid}), noop);
61 });
62 socket.on("message", objtxt => {
63 let obj = JSON.parse(objtxt);
64 switch (obj.code)
1d184b4c 65 {
3a609580
BA
66 case "newchat":
67 if (!!clients[page][obj.oppid])
68 {
69 clients[page][obj.oppid].send(
70 JSON.stringify({code:"newchat",msg:obj.msg}), noop);
71 }
72 break;
da06a6eb
BA
73 case "newmove":
74 if (!!clients[page][obj.oppid])
75 {
76 clients[page][obj.oppid].send(
77 JSON.stringify({code:"newmove",move:obj.move}), noop);
78 }
79 break;
80 case "ping":
81 if (!!clients[page][obj.oppid])
56a683cd 82 socket.send(JSON.stringify({code:"pong",gameId:obj.gameId}));
da06a6eb 83 break;
3a609580
BA
84 case "myname":
85 // Reveal my username to opponent
86 if (!!clients[page][obj.oppid])
87 {
88 clients[page][obj.oppid].send(JSON.stringify({
89 code:"oppname", name:obj.name}));
90 }
91 break;
da06a6eb
BA
92 case "lastate":
93 if (!!clients[page][obj.oppid])
94 {
95 const oppId = obj.oppid;
96 obj.oppid = sid; //I'm oppid for my opponent
97 clients[page][oppId].send(JSON.stringify(obj), noop);
98 }
99 break;
100 case "newgame":
101 if (!!games[page])
102 {
103 // Start a new game
104 const oppId = games[page]["id"];
105 const fen = games[page]["fen"];
edcd679a 106 const gameId = games[page]["gameid"];
da06a6eb 107 delete games[page];
edcd679a 108 const mycolor = (Math.random() < 0.5 ? 'w' : 'b');
da06a6eb 109 socket.send(JSON.stringify(
edcd679a 110 {code:"newgame",fen:fen,oppid:oppId,color:mycolor,gameid:gameId}));
da06a6eb
BA
111 if (!!clients[page][oppId])
112 {
113 clients[page][oppId].send(
114 JSON.stringify(
edcd679a 115 {code:"newgame",fen:fen,oppid:sid,color:mycolor=="w"?"b":"w",gameid:gameId}),
da06a6eb
BA
116 noop);
117 }
118 }
119 else
edcd679a 120 games[page] = {id:sid, fen:obj.fen, gameid:obj.gameid}; //wait for opponent
da06a6eb
BA
121 break;
122 case "cancelnewgame": //if a user cancel his seek
123 delete games[page];
124 break;
125 case "resign":
126 if (!!clients[page][obj.oppid])
127 clients[page][obj.oppid].send(JSON.stringify({code:"resign"}), noop);
128 break;
1d184b4c 129 }
da06a6eb 130 });
1d184b4c 131 }
da06a6eb
BA
132 socket.on("close", () => {
133 delete clients[page][sid];
134 // Remove potential pending game
135 if (!!games[page] && games[page]["id"] == sid)
136 delete games[page];
137 if (page != "index")
138 {
139 // Send to every client connected on index an update message for counts
140 Object.keys(clients["index"]).forEach( k => {
141 clients["index"][k].send(
142 JSON.stringify({code:"decrease",vname:page}), noop);
143 });
144 }
145 // Also notify potential opponents:
146 // hit all clients which check if sid corresponds
147 Object.keys(clients[page]).forEach( k => {
148 clients[page][k].send(JSON.stringify({code:"disconnect",id:sid}), noop);
149 });
1d184b4c 150 });
1d184b4c
BA
151 });
152 });
153 });
154}