// TODO: onopen, ask lastState informations + update observers and players status
const socketCloseListener = () => {
store.socketCloseListener(); //reinitialize connexion (in store.js)
- this.st.conn.addEventListener('message', socketMessageListener);
+ this.st.conn.addEventListener('message', this.socketMessageListener);
this.st.conn.addEventListener('close', socketCloseListener);
};
this.st.conn.onmessage = this.socketMessageListener;
// - from remote peer (one live game I don't play, finished or not)
loadGame: function(game) {
const afterRetrieval = async (game) => {
- const vModule = await import("@/variants/" + game.vname + ".js");
+ const vname = this.st.variants.filter(v => v.id == game.vid)[0].name;
+ const vModule = await import("@/variants/" + vname + ".js");
window.V = vModule.VariantRules;
this.vr = new V(game.fen);
const myIdx = game.players.findIndex(p => p.sid == this.st.user.sid);
game,
// NOTE: assign mycolor here, since BaseGame could also bs VS computer
{
+ vname: vname,
mycolor: [undefined,"w","b"][myIdx+1],
// opponent sid not strictly required, but easier
oppid: (myIdx < 0 ? undefined : game.players[1-myIdx].sid),
{uid: this.st.user.id, excluded: true},
response => {
this.games = this.games.concat(response.games.map(g => {
- const tc =
- return Object.assign({}, g, {mainT
- });
+ const type = this.classifyObject(g);
+ const vname = this.getVname(g.vid);
+ return Object.assign({}, g, {type: type, vname: vname});
+ }));
}
);
// Also ask for corr challenges (open + sent to me)
return this.challenges.filter(c => c.type == type);
},
filterGames: function(type) {
- return this.games.filter(c => c.type == type);
+ return this.games.filter(g => g.type == type);
},
classifyObject: function(o) { //challenge or game
// Heuristic: should work for most cases... (TODO)
// Minimal game informations:
id: game.id,
players: game.players.map(p => p.name),
- vname: game.vname,
+ vid: game.vid,
timeControl: game.timeControl,
};
this.st.conn.send(JSON.stringify({code:"game",
{
let newGame = data.game;
newGame.type = this.classifyObject(data.game);
+ newGame.vname = this.getVname(data.game.vid);
newGame.rid = data.from;
newGame.score = "*";
this.games.push(newGame);
{
// New game just started: data contain all information
if (data.gameInfo.type == "live")
- {
this.startNewGame(data.gameInfo);
- // TODO: redirect to game
- }
else
{
// TODO: notify with game link but do not redirect
// Send challenge to peers (if connected)
this.sendSomethingTo(chall.to, "challenge", {chall:chall}, !!warnDisconnected);
chall.added = Date.now();
+ // NOTE: vname and type are redundant (can be deduced from timeControl + vid)
chall.type = ctype;
chall.vname = vname;
-
-
-
-
-// TODO: vname and type are redundant (can be deduced from timeControl + vid)
-
-
-
-
chall.from = this.st.user;
this.challenges.push(chall);
localStorage.setItem("challenge", JSON.stringify(chall));
},
// NOTE: when launching game, the challenge is already deleted
launchGame: async function(c) {
- const vname = this.getVname(c.vid);
- const vModule = await import("@/variants/" + vname + ".js");
+ const vModule = await import("@/variants/" + c.vname + ".js");
window.V = vModule.VariantRules;
// These game informations will be sent to other players
const gameInfo =
fen: c.fen || V.GenRandInitFen(),
players: shuffle([c.from, c.seat]), //white then black
vid: c.vid,
- timeControl: tc.timeControl,
+ timeControl: c.timeControl,
};
this.st.conn.send(JSON.stringify({code:"newgame",
gameInfo:gameInfo, target:c.seat.sid}));
);
}
},
- // NOTE: for live games only (corr games are launched on server)
+ // NOTE: for live games only (corr games start on the server)
startNewGame: function(gameInfo) {
- // Extract times (in [milli]seconds), set clocks
- const tc = extractTime(c.timeControl);
const game = Object.assign({}, gameInfo, {
// (other) Game infos: constant
fenStart: gameInfo.fen,
// Game state (including FEN): will be updated
moves: [],
- clocks: [tc.mainTime, tc.mainTime],
- initime: [Date.now(), 0],
+ clocks: [-1, -1], //-1 = unstarted
+ initime: [0, 0], //timer starts after first 2 half-moves
score: "*",
});
GameStorage.add(game);
* vid: integer (variant id)
* fenStart: varchar (initial position)
* fen: varchar (current position)
- * mainTime: integer
- * addTime: integer (increment)
+ * timeControl: string
* score: varchar (result)
*
* Structure table Players:
const GameModel =
{
- // mainTime and increment in milliseconds
- create: function(vid, fen, mainTime, increment, players, cb)
+ create: function(vid, fen, timeControl, players, cb)
{
db.serialize(function() {
let query =
- "INSERT INTO Games (vid, fen, mainTime, addTime) " +
- "VALUES (" + vid + ",'" + fen + "'," + mainTime + "," + increment + ")";
+ "INSERT INTO Games (vid, fen, timeControl) " +
+ "VALUES (" + vid + ",'" + fen + "'," + timeControl + ")";
db.run(insertQuery, err => {
if (!!err)
return cb(err);
players.forEach(p => {
query =
"INSERT INTO Players VALUES " +
- "(" + lastId["rowid"] + "," + p.id + "," + p.color + "," + mainTime + ")";
+ // Remaining time = -1 means "unstarted"
+ "(" + lastId["rowid"] + "," + p.id + "," + p.color + ", -1)";
db.run(query, cb);
});
});
);
});
-// game page
router.get("/games", access.ajax, (req,res) => {
const gameId = req.query["gid"];
if (!!gameId)
});
});
-// variant page
-router.get("/gamesbyvariant", access.logged, access.ajax, (req,res) => {
- if (req.query["uid"] != req.user._id)
- return res.json({errmsg: "Not your games"});
- let uid = ObjectId(req.query["uid"]);
- let vid = ObjectId(req.query["vid"]);
- GameModel.getByVariant(uid, vid, (err,gameArray) => {
- // NOTE: res.json already stringify, no need to do it manually
- res.json(err || {games: gameArray});
- });
-});
-
-// For index: only moves count + myColor
-router.get("/gamesbyplayer", access.logged, access.ajax, (req,res) => {
- if (req.query["uid"] != req.user._id)
- return res.json({errmsg: "Not your games"});
- let uid = ObjectId(req.query["uid"]);
- GameModel.getByPlayer(uid, (err,games) => {
- res.json(err || {games: games});
- });
-});
-
// TODO: if newmove fail, takeback in GUI
// TODO: check move structure
-// TODO: for corr games, move should contain an optional "message" field ("corr chat" !)
+// TODO: move should contain an optional "message" field ("corr chat" !)
router.post("/moves", access.logged, access.ajax, (req,res) => {
let gid = ObjectId(req.body.gid);
let fen = req.body.fen;