+ finishProcessingChallenge: function(c) {
+ if (c.accepted) {
+ c.seat = {
+ // Again, avoid c.seat = st.user to not reveal email
+ sid: this.st.user.sid,
+ id: this.st.user.id,
+ name: this.st.user.name
+ };
+ this.launchGame(c);
+ } 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", { data: c.id });
+ },
+ 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;
+ const vModule = await import("@/variants/" + c.vname + ".js");
+ window.V = vModule.VariantRules;
+ 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", { data: 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) {
+ let players =
+ !!c.mycolor
+ ? (c.mycolor == "w" ? [c.seat, c.from] : [c.from, c.seat])
+ : shuffle([c.from, c.seat]);
+ // Convention for players IDs in stored games is 'uid'
+ players.forEach(p => {
+ let pWithUid = p;
+ pWithUid["uid"] = p.id;
+ delete pWithUid["id"];
+ });
+ // These game informations will be shared
+ let gameInfo = {
+ id: getRandString(),
+ fen: c.fen || V.GenRandInitFen(c.randomness),
+ // White player index 0, black player index 1:
+ players: c.mycolor
+ ? (c.mycolor == "w" ? [c.seat, c.from] : [c.from, c.seat])
+ : shuffle([c.from, c.seat]),
+ 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 });
+ // Send game info (only if live) to everyone except me and opponent
+ // TODO: this double message send could be avoided.
+ this.send("newgame", { data: gameInfo, oppsid: oppsid });
+ // Also to MyGames page:
+ this.send(
+ "notifynewgame",
+ {
+ data: gameInfo,
+ targets: gameInfo.players.map(p => {
+ return { sid: p.sid, uid: p.uid };
+ })
+ }
+ );
+ };
+ 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.gameId;
+ notifyNewgame();
+ this.$router.push("/game/" + response.gameId);
+ }
+ }
+ );
+ }
+ },
+ // 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
+ initime: [0, 0], //initialized later
+ score: "*"
+ }
+ );
+ setTimeout(
+ () => {
+ GameStorage.add(game, (err) => {
+ // If an error occurred, game is not added: a tab already
+ // added the game and (if focused) is redirected toward it.
+ // If no error and the tab is hidden: do not show anything.
+ if (!err && !document.hidden) {
+ if (this.st.settings.sound)
+ new Audio("/sounds/newgame.flac").play().catch(() => {});
+ this.$router.push("/game/" + gameInfo.id);
+ }
+ });
+ },
+ document.hidden ? 500 + 1000 * Math.random() : 0
+ );
+ }
+ }