+ }
+ case "askgame":
+ // Send current (live) game if not asked by any of the players
+ if (
+ this.game.type == "live" &&
+ this.game.players.every(p => p.sid != data.from[0])
+ ) {
+ const myGame = {
+ id: this.game.id,
+ fen: this.game.fen,
+ players: this.game.players,
+ vid: this.game.vid,
+ cadence: this.game.cadence,
+ score: this.game.score,
+ rid: this.st.user.sid //useful in Hall if I'm an observer
+ };
+ this.send("game", { data: myGame, target: data.from });
+ }
+ break;
+ case "askfullgame":
+ const gameToSend = Object.keys(this.game)
+ .filter(k =>
+ [
+ "id","fen","players","vid","cadence","fenStart","vname",
+ "moves","clocks","initime","score","drawOffer","rematchOffer"
+ ].includes(k))
+ .reduce(
+ (obj, k) => {
+ obj[k] = this.game[k];
+ return obj;
+ },
+ {}
+ );
+ this.send("fullgame", { data: gameToSend, target: data.from });
+ break;
+ case "fullgame":
+ // Callback "roomInit" to poll clients only after game is loaded
+ this.loadGame(data.data, this.roomInit);
+ break;
+ case "asklastate":
+ // Sending informative last state if I played a move or score != "*"
+ if (
+ (this.game.moves.length > 0 && this.vr.turn != this.game.mycolor) ||
+ this.game.score != "*" ||
+ this.drawOffer == "sent" ||
+ this.rematchOffer == "sent"
+ ) {
+ // Send our "last state" informations to opponent
+ const L = this.game.moves.length;
+ const myIdx = ["w", "b"].indexOf(this.game.mycolor);
+ const myLastate = {
+ lastMove: L > 0 ? this.game.moves[L - 1] : undefined,
+ clock: this.game.clocks[myIdx],
+ // Since we played a move (or abort or resign),
+ // only drawOffer=="sent" is possible
+ drawSent: this.drawOffer == "sent",
+ rematchSent: this.rematchOffer == "sent",
+ score: this.game.score,
+ score: this.game.scoreMsg,
+ movesCount: L,
+ initime: this.game.initime[1 - myIdx] //relevant only if I played
+ };
+ this.send("lastate", { data: myLastate, target: data.from });
+ } else {
+ this.send("lastate", { data: {nothing: true}, target: data.from });
+ }
+ break;
+ case "lastate": {
+ // Got opponent infos about last move
+ this.gotLastate = true;
+ if (!data.data.nothing) {
+ this.lastate = data.data;
+ if (this.game.rendered)
+ // Game is rendered (Board component)
+ this.processLastate();
+ // Else: will be processed when game is ready
+ }
+ break;
+ }
+ case "newmove": {
+ const movePlus = data.data;
+ const movesCount = this.game.moves.length;
+ if (movePlus.index > movesCount) {
+ // This can only happen if I'm an observer and missed a move.
+ if (this.gotMoveIdx < movePlus.index)
+ this.gotMoveIdx = movePlus.index;
+ if (!this.gameIsLoading) this.askGameAgain();
+ }
+ else {
+ if (
+ movePlus.index < movesCount ||
+ this.gotMoveIdx >= movePlus.index
+ ) {
+ // Opponent re-send but we already have the move:
+ // (maybe he didn't receive our pingback...)
+ this.send("gotmove", {data: movePlus.index, target: data.from});
+ } else {
+ this.gotMoveIdx = movePlus.index;
+ const receiveMyMove = (movePlus.color == this.game.mycolor);
+ if (!receiveMyMove && !!this.game.mycolor)
+ // Notify opponent that I got the move:
+ this.send("gotmove", {data: movePlus.index, target: data.from});
+ if (movePlus.cancelDrawOffer) {
+ // Opponent refuses draw
+ this.drawOffer = "";
+ // NOTE for corr games: drawOffer reset by player in turn
+ if (
+ this.game.type == "live" &&
+ !!this.game.mycolor &&
+ !receiveMyMove
+ ) {
+ GameStorage.update(this.gameRef.id, { drawOffer: "" });
+ }
+ }
+ this.$refs["basegame"].play(movePlus.move, "received", null, true);
+ this.processMove(
+ movePlus.move,
+ {
+ clock: movePlus.clock,
+ receiveMyMove: receiveMyMove
+ }
+ );
+ }
+ }
+ break;
+ }
+ case "gotmove": {
+ this.opponentGotMove = true;
+ // Now his clock starts running:
+ const oppIdx = ['w','b'].indexOf(this.vr.turn);
+ this.game.initime[oppIdx] = Date.now();
+ this.re_setClocks();