X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=server%2Fmodels%2FGame.js;h=caa15c39579c992c1e474cfa294147726a6edd24;hb=584f81b93154313a3856112400b7df98e0eb2632;hp=92c013016034416daf8f27772acac4ae5553ecb0;hpb=3b64b66722edfed26978c2894e5357d066f33943;p=vchess.git diff --git a/server/models/Game.js b/server/models/Game.js index 92c01301..caa15c39 100644 --- a/server/models/Game.js +++ b/server/models/Game.js @@ -39,7 +39,7 @@ const GameModel = g.cadence.match(/^[0-9dhms +]+$/) && g.fen.match(/^[a-zA-Z0-9, /-]*$/) && g.players.length == 2 && - g.players.every(p => p.id.toString().match(/^[0-9]+$/)) + g.players.every(p => p.uid.toString().match(/^[0-9]+$/)) ); }, @@ -48,9 +48,9 @@ const GameModel = db.serialize(function() { let query = "INSERT INTO Games " + - "(vid, fenStart, fen, score, cadence, created, drawOffer) " + + "(vid, fenStart, fen, cadence, created) " + "VALUES " + - "(" + vid + ",'" + fen + "','" + fen + "','*','" + cadence + "'," + Date.now() + ",'')"; + "(" + vid + ",'" + fen + "','" + fen + "','" + cadence + "'," + Date.now() + ")"; db.run(query, function(err) { if (err) cb(err) @@ -60,7 +60,7 @@ const GameModel = const color = (idx==0 ? "w" : "b"); query = "INSERT INTO Players VALUES " + - "(" + this.lastID + "," + p.id + ",'" + color + "')"; + "(" + this.lastID + "," + p.uid + ",'" + color + "')"; db.run(query); }); cb(null, {gid: this.lastID}); @@ -70,65 +70,47 @@ const GameModel = }, // TODO: some queries here could be async - getOne: function(id, light, cb) + getOne: function(id, cb) { // NOTE: ignoring errors (shouldn't happen at this stage) db.serialize(function() { let query = "SELECT g.id, g.vid, g.fen, g.fenStart, g.cadence, g.created, g.score, " + - "g.scoreMsg, g.drawOffer, v.name AS vname " + + "g.scoreMsg, g.drawOffer, g.rematchOffer, v.name AS vname " + "FROM Games g " + "JOIN Variants v " + " ON g.vid = v.id " + "WHERE g.id = " + id; - db.get(query, (err,gameInfo) => { + db.get(query, (err, gameInfo) => { query = "SELECT p.uid, p.color, u.name " + "FROM Players p " + "JOIN Users u " + " ON p.uid = u.id " + "WHERE p.gid = " + id; - db.all(query, (err2,players) => { - if (light) - { + db.all(query, (err2, players) => { + query = + "SELECT squares, played, idx " + + "FROM Moves " + + "WHERE gid = " + id; + db.all(query, (err3, moves) => { query = - "SELECT COUNT(*) AS nbMoves " + - "FROM Moves " + + "SELECT msg, name, added " + + "FROM Chats " + "WHERE gid = " + id; - db.get(query, (err,ret) => { - const game = Object.assign({}, + db.all(query, (err4, chats) => { + const game = Object.assign( + {}, gameInfo, - {players: players}, - {movesCount: ret.nbMoves} + { + players: players, + moves: moves, + chats: chats, + } ); cb(null, game); }); - } - else - { - // Full game requested: - query = - "SELECT squares, played, idx " + - "FROM Moves " + - "WHERE gid = " + id; - db.all(query, (err3,moves) => { - query = - "SELECT msg, name, added " + - "FROM Chats " + - "WHERE gid = " + id; - db.all(query, (err4,chats) => { - const game = Object.assign({}, - gameInfo, - { - players: players, - moves: moves, - chats: chats, - } - ); - cb(null, game); - }); - }); - } + }); }); }); }); @@ -137,17 +119,50 @@ const GameModel = // For display on MyGames or Hall: no need for moves or chats getByUser: function(uid, excluded, cb) { + // Some fields are not required when showing a games list: + const getOneLight = (id, cb2) => { + let query = + "SELECT g.id, g.vid, g.fen, g.cadence, g.created, g.score, " + + "g.scoreMsg, g.deletedByWhite, g.deletedByBlack, v.name AS vname " + + "FROM Games g " + + "JOIN Variants v " + + " ON g.vid = v.id " + + "WHERE g.id = " + id; + db.get(query, (err, gameInfo) => { + query = + "SELECT p.uid, p.color, u.name " + + "FROM Players p " + + "JOIN Users u " + + " ON p.uid = u.id " + + "WHERE p.gid = " + id; + db.all(query, (err2, players) => { + query = + "SELECT COUNT(*) AS nbMoves " + + "FROM Moves " + + "WHERE gid = " + id; + db.get(query, (err,ret) => { + const game = Object.assign( + {}, + gameInfo, + { + players: players, + movesCount: ret.nbMoves + } + ); + cb2(game); + }); + }); + }); + }; db.serialize(function() { let query = ""; - if (uid == 0) - { + if (uid == 0) { // Special case anonymous user: show all games query = "SELECT id AS gid " + "FROM Games"; } - else - { + else { // Registered user: query = "SELECT gid " + @@ -157,15 +172,12 @@ const GameModel = (excluded ? " = 0" : " > 0"); } db.all(query, (err,gameIds) => { - if (err || gameIds.length == 0) - cb(err, []); - else - { + if (err || gameIds.length == 0) cb(err, []); + else { let gameArray = []; let gCounter = 0; - for (let i=0; i { + for (let i=0; i { gameArray.push(game); gCounter++; //TODO: let's hope this is atomic?! // Call callback function only when gameArray is complete: @@ -197,17 +209,19 @@ const GameModel = return ( ( !obj.move || ( - obj.move.played.toString().match(/^[0-9]+$/) && - obj.move.idx.toString().match(/^[0-9]+$/) + !!(obj.move.played.toString().match(/^[0-9]+$/)) && + !!(obj.move.idx.toString().match(/^[0-9]+$/)) ) ) && ( - !obj.drawOffer || obj.drawOffer.match(/^[wbtn]$/) + !obj.drawOffer || !!(obj.drawOffer.match(/^[wbtn]$/)) ) && ( - !obj.fen || obj.fen.match(/^[a-zA-Z0-9, /-]*$/) + !obj.rematchOffer || !!(obj.rematchOffer.match(/^[wbn]$/)) ) && ( - !obj.score || obj.score.match(/^[012?*\/-]+$/) + !obj.fen || !!(obj.fen.match(/^[a-zA-Z0-9, /-]*$/)) ) && ( - !obj.scoreMsg || obj.scoreMsg.match(/^[a-zA-Z ]+$/) + !obj.score || !!(obj.score.match(/^[012?*\/-]+$/)) + ) && ( + !obj.scoreMsg || !!(obj.scoreMsg.match(/^[a-zA-Z ]+$/)) ) && ( !obj.chat || UserModel.checkNameEmail({name: obj.chat.name}) ) @@ -224,18 +238,28 @@ const GameModel = let modifs = ""; // NOTE: if drawOffer is set, we should check that it's player's turn // A bit overcomplicated. Let's trust the client on that for now... - if (obj.drawOffer) + if (!!obj.drawOffer) { - if (obj.drawOffer == "n") //Special "None" update + if (obj.drawOffer == "n") //special "None" update obj.drawOffer = ""; modifs += "drawOffer = '" + obj.drawOffer + "',"; } - if (obj.fen) + if (!!obj.rematchOffer) + { + if (obj.rematchOffer == "n") //special "None" update + obj.rematchOffer = ""; + modifs += "rematchOffer = '" + obj.rematchOffer + "',"; + } + if (!!obj.fen) modifs += "fen = '" + obj.fen + "',"; - if (obj.score) + if (!!obj.score) modifs += "score = '" + obj.score + "',"; - if (obj.scoreMsg) + if (!!obj.scoreMsg) modifs += "scoreMsg = '" + obj.scoreMsg + "',"; + if (!!obj.deletedBy) { + const myColor = obj.deletedBy == 'w' ? "White" : "Black"; + modifs += "deletedBy" + myColor + " = true,"; + } modifs = modifs.slice(0,-1); //remove last comma if (modifs.length > 0) { @@ -243,7 +267,7 @@ const GameModel = db.run(query); } // NOTE: move, chat and delchat are mutually exclusive - if (obj.move) + if (!!obj.move) { // Security: only update moves if index is right query = @@ -252,10 +276,6 @@ const GameModel = "WHERE gid = " + id; db.get(query, (err,ret) => { const m = obj.move; - -return cb({errmsg: ret.maxIdx + " " + m.idx + " " + (!ret.maxIdx || ret.maxIdx + 1 == m.idx) + " " + query}); - - if (!ret.maxIdx || ret.maxIdx + 1 == m.idx) { query = "INSERT INTO Moves (gid, squares, played, idx) VALUES " + @@ -267,7 +287,7 @@ return cb({errmsg: ret.maxIdx + " " + m.idx + " " + (!ret.maxIdx || ret.maxIdx + }); } else cb(null); - if (obj.chat) + if (!!obj.chat) { query = "INSERT INTO Chats (gid, msg, name, added) VALUES (" @@ -282,6 +302,21 @@ return cb({errmsg: ret.maxIdx + " " + m.idx + " " + (!ret.maxIdx || ret.maxIdx + "WHERE gid = " + id; db.run(query); } + if (!!obj.deletedBy) { + // Did my opponent delete it too? + let selection = + "deletedBy" + + (obj.deletedBy == 'w' ? "Black" : "White") + + " AS deletedByOpp"; + query = + "SELECT " + selection + " " + + "FROM Games " + + "WHERE id = " + id; + db.get(query, (err,ret) => { + // If yes: just remove game + if (!!ret.deletedByOpp) GameModel.remove(id); + }); + } }); },