diff --git a/server/available-games.js b/server/available-games.js new file mode 100644 index 00000000..b06edbb0 --- /dev/null +++ b/server/available-games.js @@ -0,0 +1,81 @@ +/* + * Copyright 2014, Gregg Tavares. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Gregg Tavares. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// This is effectively a wrapper for lib/gamedb except we can add games +// on the fly that are not added to the db. This lets us handle games +// that have not been installed/added. +// +// This happens if we run a game directly, especially from unity. Because +// the game is not installed/added it won't show up at http://localhost:18679/games.html +// but unity can still start a game and send a message to happyFunTimes + +"use strict"; + +var debug = require('debug')("AvailableGames"); +var events = require('events'); + +var AvailableGames = function() { + var emitter = new events.EventEmitter(); + var gameDB = require('../lib/gamedb'); + + var unAddedAndUnInstalledGames = { + }; + + this.on = emitter.on.bind(emitter); + this.addListener = this.on; + this.removeListender = emitter.removeListener.bind(emitter); + this.reset = gameDB.reset.bind(gameDB); + + // When getting games only get what's installed + this.getGames = gameDB.getGames.bind(gameDB); + + this.add = function(runtimeInfo) { + var gameId = runtimeInfo.info.happyFunTimes.gameId; + var info = gameDB.getGameById(gameId); + if (!info) { + debug("Added: " + gameId); + unAddedAndUnInstalledGames[gameId] = runtimeInfo; + } + }; + + this.getGameById = function(id) { + var info = gameDB.getGameById(id); + if (!info) { + info = unAddedAndUnInstalledGames[id]; + debug("getting: " + id + (info ? "found" : "NOT found")); + } + return info; + }; +}; + +module.exports = AvailableGames; + + diff --git a/server/game-group.js b/server/game-group.js index 4b4d838b..ca64436b 100644 --- a/server/game-group.js +++ b/server/game-group.js @@ -33,7 +33,6 @@ var debug = require('debug')('game-group'); var Game = require('./game'); -var gamedb = require('../lib/gamedb'); /** * Represents a group of games. @@ -45,9 +44,10 @@ var gamedb = require('../lib/gamedb'); */ var GameGroup = function(gameId, relayServer, options) { options = options || {}; + var gameDB = options.gameDB; this.options = options; this.gameId = gameId; - this.runtimeInfo = gamedb.getGameById(gameId); + this.runtimeInfo = gameDB.getGameById(gameId); this.relayServer = relayServer; this.games = []; // first game is the "master" this.nextGameId = 1; diff --git a/server/hft-server.js b/server/hft-server.js index 2ab1fccd..c7a070ef 100644 --- a/server/hft-server.js +++ b/server/hft-server.js @@ -32,6 +32,7 @@ "use strict"; var AppleCaptivePortalHandler = require('./apple-captive-portal-handler'); +var AvailableGames = require('./available-games'); var browser = require('../lib/browser'); var Cache = require('inmemfilecache'); var computerName = require('../lib/computername'); @@ -91,7 +92,7 @@ var HFTServer = function(options, startedCallback) { screenshotCount: 0, baseDir: "public", cwd: process.cwd(), - gameDB: require('../lib/gamedb'), + gameDB: new AvailableGames(), }; Object.keys(options).forEach(function(prop) { @@ -521,6 +522,7 @@ var HFTServer = function(options, startedCallback) { address: g.address, baseUrl: "http://" + g.address + ":" + g.port, noMessageTimout: options.inactivityTimeout, + gameDB: g.gameDB, }); sys.print("Listening on port(s): " + goodPorts.join(", ") + "\n"); eventEmitter.emit('ports', goodPorts); diff --git a/server/relayserver.js b/server/relayserver.js index 42259028..d0d463a6 100644 --- a/server/relayserver.js +++ b/server/relayserver.js @@ -44,6 +44,7 @@ var WSServer = require('./websocketserver'); /** * RelayServer options * @typedef {Object} RelayServer~Options + * @property {AvailableGames} gameDB The game db * @property {String} address - address that will * replace "localhost" when a game's controllerUrl is * passed in. @@ -81,6 +82,7 @@ var RelayServer = function(servers, options) { var g_numGameGroups = 0; var socketServers = []; var eventEmitter = new events.EventEmitter(); + var gameDB = options.gameDB; this.on = eventEmitter.on.bind(eventEmitter); this.addListener = this.on; @@ -129,7 +131,7 @@ var RelayServer = function(servers, options) { } var gameGroup = g_gameGroups[gameId]; if (!gameGroup && makeGroup) { - gameGroup = new GameGroup(gameId, this, { baseUrl: options.baseUrl }); + gameGroup = new GameGroup(gameId, this, { gameDB: gameDB, baseUrl: options.baseUrl }); g_gameGroups[gameId] = gameGroup; ++g_numGameGroups; debug("added game group: " + gameId + ", num game groups = " + g_numGameGroups); @@ -230,6 +232,7 @@ var RelayServer = function(servers, options) { var runtimeInfo = gameInfo.readGameInfo(cwd); if (runtimeInfo) { gameId = runtimeInfo.info.happyFunTimes.gameId; + gameDB.add(runtimeInfo); } } catch (e) { gameId = gameInfo.makeRuntimeGameId(gameId, cwd);