X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=public%2Fjavascripts%2Fcomponents%2Fgame.js;h=4a077417616bd791f7bb5f113669aea85d87301f;hb=a29d9d6b7703d680ddb49cd3fe096f49b1d774f5;hp=9e00d12bcca91371206ea12a3ccda261c7d8c7c3;hpb=1fcaa356f499ed76957d650291706a65024145e3;p=vchess.git diff --git a/public/javascripts/components/game.js b/public/javascripts/components/game.js index 9e00d12b..4a077417 100644 --- a/public/javascripts/components/game.js +++ b/public/javascripts/components/game.js @@ -1,4 +1,4 @@ -// TODO: use indexedDB instead of localStorage? (more flexible...) +// TODO: use indexedDB instead of localStorage? (more flexible: allow several games) Vue.component('my-game', { data: function() { @@ -365,20 +365,19 @@ Vue.component('my-game', { const socketOpenListener = () => { if (continuation) { - // TODO: check FEN integrity with opponent const fen = localStorage.getItem("fen"); const mycolor = localStorage.getItem("mycolor"); const oppid = localStorage.getItem("oppid"); const moves = JSON.parse(localStorage.getItem("moves")); this.newGame("human", fen, mycolor, oppid, moves, true); - // Send ping to server, which answers pong if opponent is connected - this.conn.send(JSON.stringify({code:"ping", oppid:this.oppId})); + // Send ping to server (answer pong if opponent is connected) + this.conn.send(JSON.stringify({code:"ping",oppid:this.oppId})); } else if (localStorage.getItem("newgame") === variant) { // New game request has been cancelled on disconnect this.seek = true; - this.newGame("human"); + this.newGame("human", undefined, undefined, undefined, undefined, "reconnect"); } }; const socketMessageListener = msg => { @@ -391,9 +390,46 @@ Vue.component('my-game', { case "newmove": //..he played! this.play(data.move, "animate"); break; - case "pong": //sent when opponent stayed online after we disconnected + case "pong": //received if opponent sent a ping this.oppConnected = true; + const L = this.vr.moves.length; + // Send our "last state" informations to opponent (we are still playing) + this.conn.send(JSON.stringify({ + code:"lastate", + oppid:this.oppId, + lastMove:L>0?this.vr.moves[L-1]:undefined, + movesCount:L, + })); break; + case "lastate": //got opponent infos about last move (we might have resigned) + if (this.mode!="human" || this.oppid!=data.oppid) + { + // OK, we resigned + this.conn.send(JSON.stringify({ + code:"lastate", + oppid:this.oppId, + lastMove:undefined, + movesCount:-1, + })); + } + else if (data.movesCount < 0) + { + // OK, he resigned + this.endGame(this.mycolor=="w"?"1-0":"0-1"); + } + else if (data.movesCount < this.vr.moves.length) + { + // We must tell last move to opponent + const L = this.vr.moves.length; + this.conn.send(JSON.stringify({ + code:"lastate", + oppid:this.oppId, + lastMove:this.vr.moves[L-1], + movesCount:L, + })); + } + else if (data.movesCount > this.vr.moves.length) //just got last move from him + this.play(data.lastMove, "animate"); case "resign": //..you won! this.endGame(this.mycolor=="w"?"1-0":"0-1"); break; @@ -433,7 +469,7 @@ Vue.component('my-game', { try { this.conn.send(JSON.stringify({code: "resign", oppid: this.oppid})); } catch (INVALID_STATE_ERR) { - return; //resign failed for some reason... + return; //socket is not ready (and not yet reconnected) } } this.endGame(this.mycolor=="w"?"0-1":"1-0"); @@ -466,6 +502,13 @@ Vue.component('my-game', { this.score = "*"; if (mode=="human" && !oppId) { + const storageVariant = localStorage.getItem("variant"); + if (!!storageVariant && storageVariant !== variant) + { + // TODO: find a better way to ensure this. Newgame system is currently a mess. + alert("Finish your " + storageVariant + " game first!"); + return; + } // Send game request and wait.. this.clearStorage(); //in case of try { @@ -473,9 +516,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 (continuation == "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 || []); @@ -636,15 +682,7 @@ Vue.component('my-game', { this.incheck = this.vr.getCheckSquares(move, oppCol); //is opponent in check? // Not programmatic, or animation is over if (this.mode == "human" && this.vr.turn == this.mycolor) - { - if (!this.oppConnected) - return; //abort move if opponent is gone - try { - this.conn.send(JSON.stringify({code:"newmove", move:move, oppid:this.oppid})); - } catch(INVALID_STATE_ERR) { - return; //abort also if sending failed - } - } + this.conn.send(JSON.stringify({code:"newmove", move:move, oppid:this.oppid})); new Audio("/sounds/chessmove1.mp3").play(); this.vr.play(move, "ingame"); if (this.mode == "human")