New variant idea
[xogo.git] / server.js
index 5661136..06d9866 100644 (file)
--- a/server.js
+++ b/server.js
@@ -27,7 +27,8 @@ function initializeGame(vname, players, options) {
     vname: vname,
     players: players,
     options: options,
-    time: Date.now()
+    time: Date.now(),
+    moveHash: {} //set of moves hashes seen so far
   };
   return gid;
 }
@@ -35,15 +36,12 @@ function initializeGame(vname, players, options) {
 // Provide seed in case of, so that both players initialize with same FEN
 function launchGame(gid) {
   const gameInfo = Object.assign(
-    {seed: Math.floor(Math.random() * 1984), gid: gid},
+    {seed: Math.floor(Math.random() * 19840), gid: gid},
     games[gid]
   );
   // players array is supposed to be full:
-  for (const p of games[gid].players) {
-    send(p.sid,
-         "gamestart",
-         Object.assign({randvar: p.randvar}, gameInfo));
-  }
+  for (const p of games[gid].players)
+    send(p.sid, "gamestart", gameInfo);
 }
 
 function getRandomVariant() {
@@ -57,15 +55,21 @@ wss.on("connection", (socket, req) => {
   sockets[sid] = socket;
   socket.isAlive = true;
   socket.on("pong", () => socket.isAlive = true);
-
+  if (params.dev == true) {
+    const chokidar = require("chokidar");
+    const watcher = chokidar.watch(
+      ["*.js", "*.css", "utils/", "variants/"],
+      {persistent: true});
+    watcher.on("change", path => send(sid, "filechange", {path: path}));
+  }
   socket.on("message", (msg) => {
     const obj = JSON.parse(msg);
     switch (obj.code) {
       // Send challenge (may trigger game creation)
       case "seekgame": {
-        let opponent = undefined,
-            choice = undefined;
-        const vname = obj.vname,
+        let oppIndex = undefined, //variant name
+            choice = undefined; //variant finally played
+        const vname = obj.vname, //variant requested
               randvar = (obj.vname == "_random");
         if (vname == "_random") {
           // Pick any current challenge if possible
@@ -73,22 +77,28 @@ wss.on("connection", (socket, req) => {
           if (currentChalls.length >= 1) {
             choice =
               currentChalls[Math.floor(Math.random() * currentChalls.length)];
-            opponent = challenges[choice];
+            oppIndex = choice;
           }
         }
         else if (challenges[vname]) {
-          opponent = challenges[vname];
+          // Anyone wanting to play the same variant ?
+          choice = vname;
+          oppIndex = vname;
+        }
+        else if (challenges["_random"]) {
+          // Anyone accepting any variant (including vname) ?
           choice = vname;
+          oppIndex = "_random";
         }
-        if (opponent) {
-          delete challenges[choice];
+        if (oppIndex) {
           if (choice == "_random")
             choice = getRandomVariant();
           // Launch game
           let players = [
             {sid: sid, name: obj.name, randvar: randvar},
-            opponent
+            Object.assign({}, challenges[oppIndex])
           ];
+          delete challenges[oppIndex];
           if (Math.random() < 0.5)
             players = players.reverse();
           // Empty options = default
@@ -129,11 +139,10 @@ wss.on("connection", (socket, req) => {
             const allrand = games[obj.gid].rematch.every(r => r == 2);
             if (allrand)
               vname = getRandomVariant();
-            games[obj.gid].players.forEach(p =>
-              p.randvar = allrand ? true : false);
+            games[obj.gid].players.forEach(p => p.randvar = allrand);
             const gid = initializeGame(vname,
-                           games[obj.gid].players.reverse(),
-                           games[obj.gid].options);
+                                       games[obj.gid].players.reverse(),
+                                       games[obj.gid].options);
             launchGame(gid);
           }
         }
@@ -187,8 +196,15 @@ wss.on("connection", (socket, req) => {
         break;
       // Relay a move + update games object
       case "newmove":
+        // NOTE: still potential racing issues, but... fingers crossed
+        const hash = Crypto.createHash("md5")
+                     .update(JSON.stringify(obj.fen))
+                     .digest("hex");
+        if (games[obj.gid].moveHash[hash])
+          break;
+        games[obj.gid].moveHash[hash] = true;
         games[obj.gid].fen = obj.fen;
-        games[obj.gid].time = Date.now(); //update timestamp in case of
+        games[obj.gid].time = Date.now(); //update useful if verrry slow game
         const playingWhite = (games[obj.gid].players[0].sid == sid);
         const oppSid = games[obj.gid].players[playingWhite ? 1 : 0].sid;
         send(oppSid, "newmove", {moves: obj.moves});