From a68d899d21456de948c4d1cb96594a981a510c44 Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Sun, 18 Nov 2018 16:25:31 +0100
Subject: [PATCH] Attempt to fix the non-transmitted moves issue

---
 TODO                                  |  2 +-
 public/javascripts/components/game.js | 11 +++++----
 sockets.js                            | 32 ++++++++++++++++++++++-----
 3 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/TODO b/TODO
index 006b9153..aeb537dd 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,6 @@
 Styles must be improved (full width for smartphones, selectable text for PGN...)
 Tooltip text should fade (even when mouse stay on it, especially for small screens)
 Checkered stage 2: switch button at reserve position (or on top).
-If a played disconnect right after opponent sent a move, it might be never received: secure this
 Mode expert: game.js, button on top (with online indicator)
 Turn indicator on top too (black or white)
+incheck by checkered pawns: not marked (because of turn changed?)
diff --git a/public/javascripts/components/game.js b/public/javascripts/components/game.js
index 1e68fe63..42e6507a 100644
--- a/public/javascripts/components/game.js
+++ b/public/javascripts/components/game.js
@@ -378,7 +378,7 @@ Vue.component('my-game', {
 			{
 				// New game request has been cancelled on disconnect
 				this.seek = true;
-				this.newGame("human");
+				this.newGame("human", "reconnect");
 			}
 		};
 		const socketMessageListener = msg => {
@@ -480,9 +480,12 @@ Vue.component('my-game', {
 				} catch (INVALID_STATE_ERR) {
 					return; //nothing achieved
 				}
-				let modalBox = document.getElementById("modal-control2");
-				modalBox.checked = true;
-				setTimeout(() => { modalBox.checked = false; }, 2000);
+				if (!fenInit || fenInit!="reconnect") //TODO: bad HACK...
+				{
+					let modalBox = document.getElementById("modal-control2");
+					modalBox.checked = true;
+					setTimeout(() => { modalBox.checked = false; }, 2000);
+				}
 				return;
 			}
 			this.vr = new VariantRules(fen, moves || []);
diff --git a/sockets.js b/sockets.js
index 62d51b70..10a794f8 100644
--- a/sockets.js
+++ b/sockets.js
@@ -18,9 +18,15 @@ module.exports = function(wss) {
 	for (const v of Variants)
 		clients[v.name] = {};
 
-	// TODO: when relaying to opponent, check readyState, potential setTimeout()? + send opponent (re)disconnect
 	// (resign, newgame, newmove). See https://github.com/websockets/ws/blob/master/lib/websocket.js around line 313
-	// TODO: awaiting newmove, resign, newgame :: in memory structure (use Redis ?)
+	// TODO: awaiting newmove, resign, (+newgame?) :: in memory structure (use Redis ?)
+	let newmoves = {};
+	let newresign = {};
+	for (const v of Variants)
+	{
+		newmoves[v.name] = {};
+		newresign[v.name] = {};
+	}
 
 	wss.on("connection", (socket, req) => {
 		//const params = new URL("http://localhost" + req.url).searchParams;
@@ -46,15 +52,28 @@ module.exports = function(wss) {
 			Object.keys(clients[page]).forEach( k => {
 				clients[page][k].send(JSON.stringify({code:"connect",id:sid}));
 			});
+			if (!!newmoves[page][sid])
+			{
+				socket.send(JSON.stringify({code:"newmove",move:newmoves[page][sid]}));
+				delete newmoves[page][sid];
+			}
+			if (!!newresign[page][sid])
+			{
+				socket.send(JSON.stringify({code:"resign"}));
+				delete newresign[page][sid];
+			}
 			socket.on("message", objtxt => {
 				let obj = JSON.parse(objtxt);
 				switch (obj.code)
 				{
 					case "newmove":
-						clients[page][obj.oppid].send(JSON.stringify({code:"newmove",move:obj.move}));
+						if (!!clients[page][obj.oppid] && clients[page][obj.oppid].readyState == WebSocket.OPEN)
+							clients[page][obj.oppid].send(JSON.stringify({code:"newmove",move:obj.move}));
+						else
+							newmoves[page][obj.oppid] = obj.move;
 						break;
 					case "ping":
-						if (!!clients[page][obj.oppid])
+						if (!!clients[page][obj.oppid] && clients[page][obj.oppid].readyState == WebSocket.OPEN)
 							socket.send(JSON.stringify({code:"pong"}));
 						break;
 					case "newgame":
@@ -72,7 +91,10 @@ module.exports = function(wss) {
 							games[page] = {id:sid, fen:obj.fen}; //wait for opponent
 						break;
 					case "resign":
-						clients[page][obj.oppid].send(JSON.stringify({code:"resign"}));
+						if (!!clients[page][obj.oppid] && clients[page][obj.oppid].readyState == WebSocket.OPEN)
+							clients[page][obj.oppid].send(JSON.stringify({code:"resign"}));
+						else
+							newresign[page][obj.oppid] = true;
 						break;
 				}
 			});
-- 
2.44.0