From 03608482744c433ad284f4b61e85b2e8cff4f5f3 Mon Sep 17 00:00:00 2001 From: Benjamin Auder <benjamin.auder@somewhere> Date: Fri, 8 Feb 2019 12:52:33 +0100 Subject: [PATCH] Saving current state --- client/src/App.vue | 8 +- client/src/components/ChallengeList.vue | 20 +--- client/src/data/challengeCheck.js | 4 +- client/src/store.js | 10 +- client/src/variants/Alice.js | 3 +- client/src/views/Hall.vue | 116 +++++++++++++++--------- 6 files changed, 92 insertions(+), 69 deletions(-) diff --git a/client/src/App.vue b/client/src/App.vue index 59b0371a..4b8e447c 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -30,8 +30,7 @@ .clickable(onClick="doClick('modalSettings')") | {{ st.tr["Settings"] }} .clickable#flagContainer(onClick="doClick('modalLang')") - img(v-if="!!st.lang" - :src="require(`@/assets/images/flags/${st.lang}.svg`)") + img(v-if="!!st.lang" :src="flagImage") router-view .row .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 @@ -67,6 +66,11 @@ export default { // gameRef: function() { // this.loadGame(); // }, + computed: { + flagImage: function() { + return `/images/flags/${this.st.lang}.svg`; + }, + }, }; </script> diff --git a/client/src/components/ChallengeList.vue b/client/src/components/ChallengeList.vue index a52e0cae..8951226b 100644 --- a/client/src/components/ChallengeList.vue +++ b/client/src/components/ChallengeList.vue @@ -1,34 +1,24 @@ <template lang="pug"> table tr - th(v-if="showVariant") Variant + th Variant th From th To th Cadence - th(v-if="showNbPlayers") Number of players tr(v-for="c in challenges" @click="$emit('click-challenge',c)") - td(v-if="showVariant") {{ c.variant }} + td {{ c.vname }} td {{ c.from.name }} - td + td(v-if="c.to[0].id > 0") span(v-for="p in c.to") {{ p.name }} - td {{ c.mainTime }} + {{ c.increment }} - td(v-if="showNbPlayers") {{ c.nbPlayers }} + td(v-else) {{ c.nbPlayers - 1 }} player{{ c.nbPlayers >= 3 ? 's' : '' }} + td {{ c.timeControl }} </template> <script> export default { name: "my-challenge-list", props: ["challenges"], - computed: { - showVariant: function() { - this.challenges.length > 0 && !!this.challenges[0].variant; - }, - showNbPlayers: function() { - this.challenges.length > 0 && !!this.challenges[0].nbPlayers; - }, - }, }; -// TODO: challenge format from/to ou uid/players ............ </script> <style lang="sass"> diff --git a/client/src/data/challengeCheck.js b/client/src/data/challengeCheck.js index 0a3a9917..c533b11d 100644 --- a/client/src/data/challengeCheck.js +++ b/client/src/data/challengeCheck.js @@ -50,10 +50,12 @@ export function checkChallenge(c) return "Increment must be positive"; c.increment = timeUnitToSeconds(incrementValue, incrementUnit); } + else + c.increment = 0; // Basic alphanumeric check for players names let playerCount = 0; - for (p of c.players) + for (const p of c.to) { if (p.name.length > 0) { diff --git a/client/src/store.js b/client/src/store.js index 32347119..e9bbf653 100644 --- a/client/src/store.js +++ b/client/src/store.js @@ -15,13 +15,11 @@ export const store = initialize() { ajax("/variants", "GET", res => { this.state.variants = res.variantArray; }); this.state.user = { - // id and name could be undefined - id: localStorage["myuid"], - name: localStorage["myname"], + id: localStorage["myuid"] || 0, + name: localStorage["myname"] || "", //"anonymous" + sid: localStorage["mysid"] || getRandString(), }; - // TODO: if there is a socket ID in localStorage, it means a live game was interrupted (and should resume) - const mysid = localStorage["mysid"] || getRandString(); - this.state.conn = new WebSocket(params.socketUrl + "/?sid=" + mysid); + this.state.conn = new WebSocket(params.socketUrl + "/?sid=" + this.state.user.sid); // Settings initialized with values from localStorage this.state.settings = { bcolor: localStorage["bcolor"] || "lichess", diff --git a/client/src/variants/Alice.js b/client/src/variants/Alice.js index 04b4a346..5a2d48cf 100644 --- a/client/src/variants/Alice.js +++ b/client/src/variants/Alice.js @@ -1,5 +1,6 @@ +import { ChessRules } from "@/base_rules"; // NOTE: alternative implementation, probably cleaner = use only 1 board -class AliceRules extends ChessRules +export const VariantRules = class AliceRules extends ChessRules { static get ALICE_PIECES() { diff --git a/client/src/views/Hall.vue b/client/src/views/Hall.vue index ae5e7830..674305a2 100644 --- a/client/src/views/Hall.vue +++ b/client/src/views/Hall.vue @@ -21,22 +21,26 @@ main fieldset label(for="selectPlayers") {{ st.tr["Play with? (optional)"] }} #selectPlayers - input(type="text" v-model="newchallenge.players[0].name") + input(type="text" v-model="newchallenge.to[0].name") input(v-show="newchallenge.nbPlayers>=3" type="text" - v-model="newchallenge.players[1].name") + v-model="newchallenge.to[1].name") input(v-show="newchallenge.nbPlayers==4" type="text" - v-model="newchallenge.players[2].name") + v-model="newchallenge.to[2].name") fieldset label(for="inputFen") {{ st.tr["FEN (optional)"] }} input#inputFen(type="text" v-model="newchallenge.fen") button(@click="newChallenge") Send challenge .row .col-sm-12.col-md-5.col-md-offset-1.col-lg-4.col-lg-offset-2 - ChallengeList(:challenges="challenges" @click-challenge="clickChallenge") - .col-sm-12.col-md-5.col-lg-4 - #players + .button-group + button(@click="cpdisplay='challenges'") Challenges + button(@click="cpdisplay='players'") Players + ChallengeList(v-show="cpdisplay=='challenges'" + :challenges="challenges" @click-challenge="clickChallenge") + #players(v-show="cpdisplay=='players'") h3 Online players - div(v-for="p in players" @click="challenge(p)") {{ p.name }} + //TODO: uniquePlayers, show "5 anonymous", and do nothing on click on anonymous + div(v-for="p in uniquePlayers" @click="challenge(p)") {{ p.name }} .row .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 button(onClick="doClick('modalNewgame')") New game @@ -81,11 +85,13 @@ fin de partie corr: supprimer partie du serveur au bout de 7 jours (arbitraire) * - receive "accept/withdraw/cancel challenge": apply action to challenges list * - receive "new game": if live, store locally + redirect to game * If corr: notify "new game has started", give link, but do not redirect + * - receive new challenge: if targeted, replace our name with sender name */ import { store } from "@/store"; import { NbPlayers } from "@/data/nbPlayers"; import { checkChallenge } from "@/data/challengeCheck"; import { ArrayFun } from "@/utils/array"; +import { ajax } from "@/utils/ajax"; import GameList from "@/components/GameList.vue"; import ChallengeList from "@/components/ChallengeList.vue"; export default { @@ -107,8 +113,13 @@ export default { fen: "", vid: 0, nbPlayers: 0, - // TODO: distinguer uid et sid ! - players: [{id:0,name:""},{id:0,name:""},{id:0,name:""}], + // NOTE: id (server DB) and sid (socket ID). + // Anonymous players just have a socket ID. + to: [ + {id:0, sid:"", name:""}, + {id:0, sid:"", name:""}, + {id:0, sid:"", name:""} + ], timeControl: "", }, }; @@ -156,6 +167,8 @@ export default { break; case "halldisconnect": ArrayFun.remove(this.players, p => p.id == data.uid); + // TODO: also remove all challenges sent by this player, + // and all live games where he plays and no other opponent is online break; } }, @@ -216,58 +229,73 @@ export default { newChallenge: async function() { const idxInVariants = this.st.variants.findIndex(v => v.id == this.newchallenge.vid); - const vname = variants[idxInVariants].name; + const vname = this.st.variants[idxInVariants].name; const vModule = await import("@/variants/" + vname + ".js"); window.V = vModule.VariantRules; - // NOTE: side-effect = set FEN, and mainTime + increment in seconds - // TODO: (to limit cheating options) separate the GenRandInitFen() functions - // in separate files, load on server and generate FEN on server. + // checkChallenge side-effect = set FEN, and mainTime + increment in seconds const error = checkChallenge(this.newchallenge); if (!!error) return alert(error); - // TODO: 40 = average number of moves ? - if (this.newchallenge.mainTime + 40 * this.newchallenge.increment - >= 3*24*60*60) //3 days (TODO: heuristic...) + // Less than 3 days ==> live game (TODO: heuristic... 40 moves also) + const liveGame = + this.newchallenge.mainTime + 40 * this.newchallenge.increment < 3*24*60*60; + // Check that the players (if any indicated) are online + for (let p of this.newchallenge.to) { - // Correspondance game: - // Possible (server) error if filled player does not exist - ajax( - "/challenges/" + this.newchallenge.vid, - "POST", + if (p.name != "") + { + const pIdx = this.players.findIndex(pl => pl.name == p.name); + if (pIdx === -1) + return alert(p.name + " is not connected"); + p.id = this.players[pIdx].id; + p.sid = this.players[pIdx].sid; + } + } + const finishAddChallenge = (cid) => { + const chall = Object.assign( + {}, this.newchallenge, - response => { - const chall = Object.assign({}, - this.newchallenge, - { - id: response.cid, - uid: this.st.user.id, - added: Date.now(), - vname: vname, - }); - this.challenges.push(chall); - document.getElementById("modalNewgame").checked = false; + { + id: cid, + from: this.st.user, + added: Date.now(), + vname: vname, } ); - } - else + this.challenges.push(chall); + document.getElementById("modalNewgame").checked = false; + }; + if (liveGame) { - // Considered live game - if (this.newchallenges.players[0].id > 0) + const chall = JSON.stringify({ + code: "sendchallenge", + sender: {name:this.st.user.name, id:this.st.user.id, sid:this.st.user.sid}, + }); + if (this.newchallenge.to[0].id > 0) { - // Challenge with target players - this.newchallenges.players.forEach(p => { - this.st.conn.send(JSON.stringify({ - code: "sendchallenge", - oppid: p.id, - user: {name:this.st.user.name, id:this.st.user.id} - })); + // Challenge with targeted players + this.newchallenge.to.forEach(p => { + if (p.id > 0) + this.st.conn.send(Object.assign({}, chall, {receiver: p.sid})); }); } else { // Open challenge: send to all connected players - // TODO + this.players.forEach(p => { this.st.conn.send(chall); }); } + // Live challenges have cid = 0 + finishAddChallenge(0); + } + else //correspondance game: + { + // Possible (server) error if filled player does not exist + ajax( + "/challenges/" + this.newchallenge.vid, + "POST", + this.newchallenge, + response => { finishAddChallenge(cid); } + ); } }, possibleNbplayers: function(nbp) { -- 2.44.0