+ finishProcessingChallenge: function(c) {
+ if (c.accepted) {
+ c.seat = {
+ sid: this.st.user.sid,
+ id: this.st.user.id,
+ name: this.st.user.name
+ };
+ this.launchGame(c);
+ if (c.type == "live")
+ // Remove all live challenges of both players
+ this.send("deletechallenge_s", { data: { sids: [c.from.sid, c.seat.sid] } });
+ else
+ // Corr challenge: just remove the challenge
+ this.send("deletechallenge_s", { data: { cid: c.id } });
+ } else {
+ const oppsid = this.getOppsid(c);
+ if (!!oppsid)
+ this.send("refusechallenge", { data: c.id, target: oppsid });
+ if (c.type == "corr") {
+ ajax(
+ "/challenges",
+ "DELETE",
+ { data: { id: c.id } }
+ );
+ }
+ this.send("deletechallenge_s", { data: { cid: c.id } });
+ }
+ },
+ // TODO: if several players click same challenge at the same time: problem
+ clickChallenge: async function(c) {
+ const myChallenge =
+ c.from.sid == this.st.user.sid || //live
+ (this.st.user.id > 0 && c.from.id == this.st.user.id); //corr
+ if (!myChallenge) {
+ if (c.type == "corr" && this.st.user.id <= 0) {
+ alert(this.st.tr["Please log in to accept corr challenges"]);
+ return;
+ }
+ c.accepted = true;
+ await import("@/variants/" + c.vname + ".js")
+ .then((vModule) => {
+ window.V = vModule[c.vname + "Rules"];
+ if (!!c.to) {
+ // c.to == this.st.user.name (connected)
+ if (!!c.fen) {
+ const parsedFen = V.ParseFen(c.fen);
+ c.mycolor = V.GetOppCol(parsedFen.turn);
+ this.tchallDiag = getDiagram({
+ position: parsedFen.position,
+ orientation: c.mycolor
+ });
+ }
+ this.curChallToAccept = c;
+ document.getElementById("modalAccept").checked = true;
+ }
+ else this.finishProcessingChallenge(c);
+ });
+ }
+ else {
+ // My challenge
+ if (c.type == "corr") {
+ ajax(
+ "/challenges",
+ "DELETE",
+ { data: { id: c.id } }
+ );
+ }
+ this.send("deletechallenge_s", { data: { cid: c.id } });
+ }
+ // In all cases, the challenge is consumed:
+ ArrayFun.remove(this.challenges, ch => ch.id == c.id);
+ },
+ // NOTE: when launching game, the challenge is already being deleted
+ launchGame: function(c) {
+ // White player index 0, black player index 1:
+ const players =
+ !!c.mycolor
+ ? (c.mycolor == "w" ? [c.seat, c.from] : [c.from, c.seat])
+ : shuffle([c.from, c.seat]);
+ // These game informations will be shared
+ let gameInfo = {
+ id: getRandString(),
+ fen: c.fen || V.GenRandInitFen(c.randomness),
+ randomness: c.randomness, //for rematch
+ players: players,
+ vid: c.vid,
+ cadence: c.cadence
+ };
+ const notifyNewgame = () => {
+ const oppsid = this.getOppsid(c);
+ if (!!oppsid)
+ // Opponent is online
+ this.send("startgame", { data: gameInfo, target: oppsid });
+ // If new corr game, notify Hall (except opponent and me)
+ if (c.type == "corr") {
+ this.send(
+ "newgame",
+ {
+ data: gameInfo,
+ excluded: [this.st.user.sid, oppsid]
+ }
+ );
+ }
+ // Notify MyGames page:
+ this.send(
+ "notifynewgame",
+ {
+ data: gameInfo,
+ targets: gameInfo.players
+ }
+ );
+ // NOTE: no need to send the game to the room, since I'll connect
+ // on game just after, the main Hall will be notified.
+ };
+ if (c.type == "live") {
+ notifyNewgame();
+ this.startNewGame(gameInfo);
+ } else {
+ // corr: game only on server
+ ajax(
+ "/games",
+ "POST",
+ {
+ // cid is useful to delete the challenge:
+ data: {
+ gameInfo: gameInfo,
+ cid: c.id
+ },
+ success: (response) => {
+ gameInfo.id = response.id;
+ notifyNewgame();
+ this.$router.push("/game/" + response.id);
+ }
+ }
+ );
+ }
+ },
+ // NOTE: for live games only (corr games start on the server)
+ startNewGame: function(gameInfo) {
+ const game = Object.assign(
+ {},
+ gameInfo,
+ {
+ // (other) Game infos: constant
+ fenStart: gameInfo.fen,
+ vname: this.getVname(gameInfo.vid),
+ created: Date.now(),
+ // Game state (including FEN): will be updated
+ moves: [],
+ clocks: [-1, -1], //-1 = unstarted
+ score: "*"
+ }
+ );
+ setTimeout(
+ () => {
+ GameStorage.add(game, (err) => {
+ // If an error occurred, game is not added: a tab already
+ // added the game. Maybe a focused one, maybe not.
+ // We know for sure that it emitted the gong start sound.
+ // ==> Do not play it again.
+ if (!err && this.st.settings.sound)
+ new Audio("/sounds/newgame.flac").play().catch(() => {});
+ this.$router.push("/game/" + gameInfo.id);
+ });
+ },
+ document.hidden ? 500 + 1000 * Math.random() : 0
+ );
+ }
+ }