From: Benjamin Auder Date: Wed, 13 Feb 2019 15:42:15 +0000 (+0100) Subject: Some advances in challenge handling (server+client) X-Git-Url: https://git.auder.net/doc/html/css/current/pieces/cp.svg?a=commitdiff_plain;h=052d17ea6e199533cefb11f1ef51020b55cb1382;p=vchess.git Some advances in challenge handling (server+client) --- diff --git a/client/src/views/Hall.vue b/client/src/views/Hall.vue index 822c90b2..0c991781 100644 --- a/client/src/views/Hall.vue +++ b/client/src/views/Hall.vue @@ -63,7 +63,7 @@ import { NbPlayers } from "@/data/nbPlayers"; import { checkChallenge } from "@/data/challengeCheck"; import { ArrayFun } from "@/utils/array"; import { ajax } from "@/utils/ajax"; -import { genRandString } from "@/utils/alea"; +import { getRandString } from "@/utils/alea"; import GameList from "@/components/GameList.vue"; import ChallengeList from "@/components/ChallengeList.vue"; export default { @@ -110,29 +110,31 @@ export default { // Always add myself to players' list this.players.push(this.st.user); // Ask server for current corr games (all but mines) - ajax( - "", - "GET", - response => { - - } - ); - // Also ask for corr challenges (all) - ajax( - "", - "GET", - response => { - - } - ); +// ajax( +// "", +// "GET", +// response => { +// +// } +// ); +// // Also ask for corr challenges (all) +// ajax( +// "", +// "GET", +// response => { +// +// } +// ); // 0.1] Ask server for for room composition: const socketOpenListener = () => { this.st.conn.send(JSON.stringify({code:"askclients"})); }; this.st.conn.onopen = socketOpenListener; + this.oldOnmessage = this.st.conn.onmessage || Function.prototype; //TODO: required here? this.st.conn.onmessage = this.socketMessageListener; + const oldOnclose = this.st.conn.onclose; const socketCloseListener = () => { - // connexion is reinitialized in store.js + oldOnclose(); //reinitialize connexion (in store.js) this.st.conn.addEventListener('message', this.socketMessageListener); this.st.conn.addEventListener('close', socketCloseListener); }; @@ -140,6 +142,10 @@ export default { }, methods: { socketMessageListener: function(msg) { + // Save and call current st.conn.onmessage if one was already defined + // --> also needed in future Game.vue (also in Chat.vue component) + // TODO: merge Game.vue and MoveList.vue (one logic entity, no ?) + this.oldOnmessage(msg); const data = JSON.parse(msg.data); switch (data.code) { @@ -308,8 +314,8 @@ export default { if (!!error) return alert(error); // TODO: set FEN, set mainTime and increment ?! -else //generate a FEN - c.fen = V.GenRandInitFen(); +//else //generate a FEN +// c.fen = V.GenRandInitFen(); // Less than 3 days ==> live game (TODO: heuristic... 40 moves also) const liveGame = this.newchallenge.mainTime + 40 * this.newchallenge.increment < 3*24*60*60; @@ -347,7 +353,7 @@ else //generate a FEN } } const finishAddChallenge = (cid) => { - chall.id = cid || "c" + genRandString(); + chall.id = cid || "c" + getRandString(); this.challenges.push(chall); // Send challenge to peers let challSock = @@ -397,7 +403,7 @@ else //generate a FEN ajax( "/challenges/" + this.newchallenge.vid, "POST", - , + chall, response => { chall.id = response.cid; finishAddChallenge(); diff --git a/server/db/create.sql b/server/db/create.sql index 936992ce..b98cfbb0 100644 --- a/server/db/create.sql +++ b/server/db/create.sql @@ -38,15 +38,15 @@ create table Challenges ( vid integer, nbPlayers integer, fen varchar, - mainTime integer, - addTime integer, + timeControl varchar, foreign key (uid) references Users(id), foreign key (vid) references Variants(id) ); --- Store informations about players who accept a challenge +-- Store informations about players who (potentially) accept a challenge create table WillPlay ( - cid integer, + yes boolean, + cid integer, uid integer, foreign key (cid) references Challenges(id), foreign key (uid) references Users(id) diff --git a/server/models/Challenge.js b/server/models/Challenge.js index e1fb448b..6d8f5c1e 100644 --- a/server/models/Challenge.js +++ b/server/models/Challenge.js @@ -8,8 +8,7 @@ var db = require("../utils/database"); * vid: variant id (int) * nbPlayers: integer * fen: varchar (optional) - * mainTime: integer - * addTime: integer + * timeControl: string (3m+2s, 7d+1d ...) * * Structure table WillPlay: * cid: ref challenge id @@ -20,53 +19,39 @@ const ChallengeModel = { checkChallenge: function(c) { - const vid = parseInt(c.vid); - if (isNaN(vid) || vid <= 0) - return "Please select a variant"; + if (!c.vid.match(/^[0-9]+$/)) + return "Wrong variant ID"; - const mainTime = parseInt(c.mainTime); - const increment = parseInt(c.increment); - if (isNaN(mainTime) || mainTime <= 0) - return "Main time should be strictly positive"; - if (isNaN(increment) || increment < 0) - return "Increment must be positive"; + if (!c.timeControl.match(/^[0-9dhms +]+$/)) + return "Wrong characters in time control"; - // Basic alphanumeric check for players names - let playerCount = 0; - for (p of c.players) - { - if (p.name.length > 0) - { - if (!p.name.match(/^[\w]+$/)) - return "Wrong characters in players names"; - playerCount++; - } - } + if (!c.nbPlayers.match(/^[0-9]+$/)) + return "Wrong number of players"; - if (playerCount > 0 && playerCount != c.nbPlayers-1) - return "None, or all of the opponent names must be filled" - - // Just characters check on server: - if (!c.fen.match(/^[a-zA-Z0-9, /-]*$/)) + if (!c.fen.match(/^[a-zA-Z0-9, /-]+$/)) return "Bad FEN string"; }, - // fen cannot be undefined; TODO: generate fen on server instead + // fen cannot be undefined create: function(c, cb) { db.serialize(function() { let query = "INSERT INTO Challenges " + - "(added, uid, vid, nbPlayers, fen, mainTime, addTime) VALUES " + + "(added, uid, vid, nbPlayers, fen, timeControl) VALUES " + "(" + Date.now() + "," + c.uid + "," + c.vid + "," + c.nbPlayers + - ",'" + c.fen + "'," + c.mainTime + "," + c.increment + ")"; + ",'" + c.fen + "'," + c.timeControl + ")"; db.run(query, err => { if (!!err) return cb(err); db.get("SELECT last_insert_rowid() AS rowid", (err2,lastId) => { - query = + + // TODO: also insert "will play" "no" for other players ? + // willplay = "maybe" by default ? + + query = "INSERT INTO WillPlay VALUES " + - "(" + lastId["rowid"] + "," + c.uid + ")"; + "(true," + lastId["rowid"] + "," + c.uid + ")"; db.run(query, (err,ret) => { cb(err, lastId); //all we need is the challenge ID }); @@ -104,8 +89,7 @@ const ChallengeModel = nbPlayers: challengeInfo.nbPlayers, players: players, //currently in fen: challengeInfo.fen, - mainTime: challengeInfo.mainTime, - increment: challengeInfo.addTime, + timeControl: challengeInfo.timeControl, }; return cb(null, challenge); }); diff --git a/server/routes/challenges.js b/server/routes/challenges.js index c85c6098..e64e8901 100644 --- a/server/routes/challenges.js +++ b/server/routes/challenges.js @@ -3,12 +3,13 @@ let router = require("express").Router(); const access = require("../utils/access"); const ChallengeModel = require("../models/Challenge"); +const UserModel = require("../models/User"); //for name check -router.post("/challenges/:vid([0-9]+)", access.logged, access.ajax, (req,res) => { - const vid = req.params["vid"]; - // TODO: check data req.body.chall ( - const error = ChallengeModel.checkChallenge(chall); - ChallengeModel.create(chall, (err,lastId) => { +router.post("/challenges", access.logged, access.ajax, (req,res) => { + const error = ChallengeModel.checkChallenge(req.body.chall); + // TODO: treat "to" field separately (search users by name) + // --> replace "to" by an array of uid (in chall), then call: + ChallengeModel.create(req.body.chall, (err,lastId) => { res.json(err || {cid: lastId["rowid"]}); }); }); diff --git a/server/sockets.js b/server/sockets.js index 333fe77b..c05293e3 100644 --- a/server/sockets.js +++ b/server/sockets.js @@ -33,7 +33,7 @@ module.exports = function(wss) { wss.on("connection", (socket, req) => { const query = getJsonFromUrl(req.url); const sid = query["sid"]; - // Ignore duplicate connections (on the same live game that we play): + // Ignore duplicate connections (on the same live game that we play): if (!!clients[sid]) return socket.send(JSON.stringify({code:"duplicate"})); clients[sid] = socket;