import Flower from Hanafuda; import Messaging; import player from Room; import Save; import Session; import Table; import Time; var states = Table.make(function(o) {return 0;}); var metadata = Table.make(function(o) {return o.value.date;}); reload(); initMessageHandlers(); return { metadata: metadata, proposal: proposal, reload: reload }; function initMessageHandlers() { Messaging.addEventListener(["Game"], function(o) { var gameID = o.state.public.coordinates.gameID; pushState(gameID, o.state); metadata.insert(gameID, getMetadata(o.state)); metadata.save('games.metadata'); }); Messaging.addEventListener(["LogIn"], function(o) { var gamesAgainst = states.getAll( function(game) {return isAgainst(game.value, o.from);} ); gamesAgainst.forEach(function(game) { Messaging.send({ tag: "Sync", latestKnown: game.value.latest.public.coordinates, to: o.from }); }); }); Messaging.addEventListener(["Relay", "Sync"], function(o) { var gameID = o.message.latestKnown.gameID; var state = states.get(gameID); if(state != undefined) { switch(compare(state.latest.public.coordinates, o.message.latestKnown)) { case -1: Messaging.send({tag: "Yield", onGameID: gameID, to: o.from}); case 1: Messaging.send({tag: "Share", gameSave: state.latest}); } } }); Messaging.addEventListener(["Relay", "Yield"], function(o) { var gameID = o.message.onGameID; var state = states.get(gameID); if(state != undefined && isAgainst(state, o.from)) { Messaging.send({tag: "Share", gameSave: state.latest}); } }); } function isAgainst(state, playerID) { return state.latest.public.nextPlayer[Session.getKey()] == playerID; } function compare(gameCoordinatesA, gameCoordinatesB) { var monthIndexA = Flower[gameCoordinatesA.month]; var monthIndexB = Flower[gameCoordinatesB.month]; if(monthIndexA < monthIndexB) { return -1; } else if(monthIndexA > monthIndexB) { return 1; } else if(gameCoordinatesA.turn < gameCoordinatesB.turn) { return -1; } else if(gameCoordinatesA.turn > gameCoordinatesB.turn) { return 1; } else { return 0; } } function getMetadata(state) { var sessionKey = Session.getKey(); return Time.timestamp({ vs: player(state.public.nextPlayer[sessionKey]), yourTurn: state.public.playing == sessionKey }); } function proposal(playerID, yourTurn) { metadata.insert( playerID, Time.timestamp({vs: player(playerID), yourTurn: yourTurn}) ); } function pushState(gameID, newState) { if(states.get(gameID) == undefined) { states.insert(gameID, {}); } var state = states.get(gameID); state.former = state.latest; state.latest = newState; states.save('games.state'); } function reload() { states.load('games.state'); metadata.load('games.metadata'); }