Skip to content

Commit

Permalink
make HFT controllers use HFTSystem to find next game to switch too. T…
Browse files Browse the repository at this point in the history
…his makes it much more responsive

make HFT controllers not able to connect if a game is not running. This will prevent people getting stuck on
a controller which I've seen. They'd be in a game, we'd switch games, they'd for some reason refresh or whatever
and the old controller would start and be waiting for the game. Now the controller will switch go back to "/"
which will then redirect it to whatever is running

make index.html use HFTSystem to list the games. This makes it much more responsive.
  • Loading branch information
greggman committed Oct 29, 2014
1 parent a4bad2c commit fa0c77e
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 97 deletions.
65 changes: 24 additions & 41 deletions public/hft/0.x.x/scripts/commonui.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,13 @@
define([
'./io',
'./hft-splash',
'./hft-system',
'./misc/misc',
'./misc/playername',
], function(
IO,
HFTSplash,
HFTSystem,
Misc,
PlayerNameHandler) {

Expand Down Expand Up @@ -125,49 +127,30 @@ define([
options.disconnectFn();
}

//
var checkForGame = function() {
IO.sendJSON(window.location.href, {cmd: 'listRunningGames'}, function (exception, obj) {
if (exception) {
// the server is down. Try again?. I'm not sure what to do here. Currently the display
// will say "restart"/"main menu" but neither have a point if the server is down.
// Maybe there should be no options?
setTimeout(checkForGame, 1000);
var hftSystem = new HFTSystem();
hftSystem.on('runningGames', function(obj) {
// Is the game running
for (var ii = 0; ii < obj.length; ++ii) {
var game = obj[ii];
if (game.gameId == client.getGameId()) {
// Yes! Reload
window.location.reload();
return;
}

// Is the game running
for (var ii = 0; ii < obj.length; ++ii) {
var game = obj[ii];
if (game.gameId == client.getGameId()) {
// Yes! Reload
window.location.reload();
return;
}
}

// Are any games running? If 1 game, go to it.
if (obj.length == 1 && obj[0].controllerUrl) {
window.location.href = obj[0].controllerUrl;
return;
}
// If 2+ games, go to the menu.
if (obj.length > 1) {
// Go to main menu
window.location.href = "/";
return;
}

// Note: If we knew the path each game and there was only 1 game running
// we could jump directly to that game. Right now gameIds don't correspond
// to their URL.

setTimeout(checkForGame, 1000);
});
};

// Give the game a moment to restart and connect to happyFunTimes
setTimeout(checkForGame, 1000);
}

// Are any games running? If 1 game, go to it.
if (obj.length == 1 && obj[0].controllerUrl) {
window.location.href = obj[0].controllerUrl;
return;
}
// If 2+ games, go to the menu.
if (obj.length > 1) {
// Go to main menu
window.location.href = "/";
return;
}
});
});

client.addEventListener('_hft_redirect_', function(data) {
Expand Down
64 changes: 29 additions & 35 deletions public/scripts/showgames.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,11 @@

"use strict";

// Start the main app logic.
requirejs(
[ 'hft/io',
[ 'hft/hft-system',
'hft/misc/strings',
], function(
IO,
HFTSystem,
Strings) {

var $ = function(id) {
Expand All @@ -48,41 +47,36 @@ requirejs(
var template = $("item-template").text;
var oldHtml = "";

var getGames = function() {
IO.sendJSON(window.location.href, {cmd: 'listRunningGames'}, function (exception, obj) {
if (exception) {
setTimeout(getGames, 1000);
return;
}
var hftSystem = new HFTSystem();
hftSystem.on('runningGames', function(obj) {
console.log(obj);
// If there's only one game just go to it.
if (obj.length == 1 && obj[0].controllerUrl) {
window.location.href = obj[0].controllerUrl;
return;
}

var items = [];
for (var ii = 0; ii < obj.length; ++ii) {
var game = obj[ii];
var items = [];
for (var ii = 0; ii < obj.length; ++ii) {
var game = obj[ii];
var runtimeInfo = game.runtimeInfo;
var hftInfo = runtimeInfo.info.happyFunTimes;
// Not sure how I should figure out the name and screenshot.
var basePath = game.controllerUrl.substring(0, game.controllerUrl.lastIndexOf('/') + 1);
var dev = (runtimeInfo.originalGameId != hftInfo.gameId) ? "(*)" : "";
game.name = dev + (hftInfo.name || runtimeInfo.originalGameId);
game.screenshotUrl = game.screenshotUrl;
items.push(Strings.replaceParams(template, game));
}
var html = items.join("");
if (html != oldHtml) {
oldHtml = html;
gamemenu.innerHTML = html;
}

// Not sure how I should figure out the name and screenshot.
var basePath = game.controllerUrl.substring(0, game.controllerUrl.lastIndexOf('/') + 1);
game.name = game.name || game.gameId;
game.screenshotUrl = game.screenshotUrl || (basePath + game.gameId + "-screenshot.png");
items.push(Strings.replaceParams(template, game));
}
var html = items.join("");
if (html != oldHtml) {
oldHtml = html;
gamemenu.innerHTML = html;
}
nogames.style.display = items.length ? "none" : "block";

nogames.style.display = items.length ? "none" : "block";

// If there's only one game just go to it.
if (obj.length == 1 && obj[0].controllerUrl) {
window.location.href = obj[0].controllerUrl;
return;
}

setTimeout(getGames, 5000);
});
};
getGames();
});
});


56 changes: 40 additions & 16 deletions server/hftgame.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,20 @@ var HFTPlayer = function(netPlayer, game, gameDB, relayServer) {
this.game = game;
this.gameDB = gameDB;
this.relayServer = relayServer;
this.getAvailableGamesSubscribed = false;
this.subscribedGetAvailableGames = false;
this.subscribedGetRunningGames = false;

// Remember these must be safe.
netPlayer.addEventListener('disconnect', HFTPlayer.prototype.disconnect.bind(this));
netPlayer.addEventListener('getGameInfo', HFTPlayer.prototype.handleGetGameInfo.bind(this));
netPlayer.addEventListener('getAvailableGames', HFTPlayer.prototype.handleGetAvailableGames.bind(this));
netPlayer.addEventListener('getRunningGames', HFTPlayer.prototype.handleGetRunningGames.bind(this));
netPlayer.addEventListener('install', HFTPlayer.prototype.handleInstall.bind(this));
netPlayer.addEventListener('upgrade', HFTPlayer.prototype.handleUpgrade.bind(this));
netPlayer.addEventListener('launch', HFTPlayer.prototype.handleLaunch.bind(this));
netPlayer.addEventListener('quit', HFTPlayer.prototype.handleQuit.bind(this));
netPlayer.addEventListener('quitGame', HFTPlayer.prototype.handleQuitGame.bind(this));
netPlayer.addEventListener('disconnectGame', HFTPlayer.prototype.handleDisconnectGame.bind(this));
netPlayer.addEventListener('disconnect', HFTPlayer.prototype.disconnect.bind(this));
netPlayer.addEventListener('getGameInfo', HFTPlayer.prototype.handleGetGameInfo.bind(this));
netPlayer.addEventListener('getAvailableGames', HFTPlayer.prototype.handleGetAvailableGames.bind(this));
netPlayer.addEventListener('getRunningGames', HFTPlayer.prototype.handleGetRunningGames.bind(this));
netPlayer.addEventListener('install', HFTPlayer.prototype.handleInstall.bind(this));
netPlayer.addEventListener('upgrade', HFTPlayer.prototype.handleUpgrade.bind(this));
netPlayer.addEventListener('launch', HFTPlayer.prototype.handleLaunch.bind(this));
netPlayer.addEventListener('quit', HFTPlayer.prototype.handleQuit.bind(this));
netPlayer.addEventListener('quitGame', HFTPlayer.prototype.handleQuitGame.bind(this));
netPlayer.addEventListener('disconnectGame', HFTPlayer.prototype.handleDisconnectGame.bind(this));

this.handleGameExited = HFTPlayer.prototype.handleGameExited.bind(this)
relayServer.on('gameExited', this.handleGameExited);
Expand All @@ -93,8 +94,8 @@ var HFTPlayer = function(netPlayer, game, gameDB, relayServer) {
};

HFTPlayer.prototype.disconnect = function() {
if (this.getAvailableGamesSubscribed) {
this.gameDB.removeListener('changed', this.getAvailableGamesSubscribed);
if (this.subscribedGetAvailableGames) {
this.gameDB.removeListener('changed', this.subscribedGetAvailableGames);
this.gameAvailableGamesSubscribed = undefined;
}
this.relayServer.removeListener('gameExited', this.handleGameExited);
Expand Down Expand Up @@ -142,20 +143,31 @@ HFTPlayer.prototype.handleGetGameInfo = function(data) {
};

HFTPlayer.prototype.handleGetAvailableGames = function(data) {
if (!this.getAvailableGamesSubscribed) {
this.getAvailableGamesSubscribed = HFTPlayer.prototype.handleGetAvailableGames.bind(this);
this.gameDB.on('changed', this.getAvailableGamesSubscribed);
if (!this.subscribedGetAvailableGames) {
this.subscribedGetAvailableGames = HFTPlayer.prototype.handleGetAvailableGames.bind(this);
this.gameDB.on('changed', this.subscribedGetAvailableGames);
}

debug("sending available games");
this.sendCmd("availableGames", this.gameDB.getGames());
};

HFTPlayer.prototype.handleGetRunningGames = function(data) {
this.subscribedGetRunningGames = true;
this.sendRunningGames();
};

HFTPlayer.prototype.sendRunningGames = function() {
debug("sending running games");
this.sendCmd("runningGames", this.relayServer.getGames());
};

HFTPlayer.prototype.sendRunningGamesIfSubscribed = function() {
if (this.subscribedGetRunningGames) {
this.sendRunningGames();
}
};

HFTPlayer.prototype.download = function(gameId, upgrade) {
var emitter = download(gameId, undefined, {
//verbose: true,
Expand Down Expand Up @@ -303,6 +315,18 @@ var HFTGame = function(options) {
players.push(new HFTPlayer(netPlayer, this, gameDB, relayServer));
}.bind(this));

relayServer.on('gameStarted', function() {
players.forEach(function(player) {
player.sendRunningGamesIfSubscribed();
});
});

relayServer.on('gameExited', function() {
players.forEach(function(player) {
player.sendRunningGamesIfSubscribed();
});
});

this.removePlayer = function(player) {
var index = players.indexOf(player);
if (index >= 0) {
Expand Down
2 changes: 1 addition & 1 deletion server/relayserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,9 @@ var RelayServer = function(servers, options) {
return;
}
debug("starting game: " + gameId);
eventEmitter.emit('gameStarted', {gameId: gameId});
var gameGroup = getGameGroup(gameId, true);
gameGroup.assignClient(client, data);
eventEmitter.emit('gameStarted', {gameId: gameId});
}.bind(this);

for (var ii = 0; ii < servers.length; ++ii) {
Expand Down
13 changes: 9 additions & 4 deletions todo.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
To Do
=====

* make games 'reload' if the server disconnects then reconnects

can we some how indicate to the game it's a reconnect? For example, set a local cookie.
On load read and clear the cookie. Set a flag on gameserver?

* send audio example
* move tiled support to hft-tiled?
* add tiled support to jumpjump
* make controllers only work if game is running, otherwise switch to other game
* make games use websockets to switch games instead of polling ajax
* Add unity support for multiple games
* fix back button on shft game page. Only center is hot.
* make hft-publish work for html-example
* Add option to skip name input. hft start --no-ask-name
* add optional player timeout?

I already have the ping but maybe I should also have an input timeout.
Expand All @@ -20,7 +22,6 @@ To Do
* add "hft remove --missing" and "--broken" to remove missing/broken ones
* consider using a fake inmem file system for testing, both reading and writing
* publish unity plugin
* figure out why unitycharacterexample is not exiting when hft asks it to.
* if hft is not running, have shft save a cookie if you choose a game to install.

when hft starts it can open an iframe to shft which will read the cookie and
Expand Down Expand Up @@ -759,6 +760,10 @@ Runs Repo noid
Done
====

* figure out why unitycharacterexample is not exiting when hft asks it to.
* Add option to skip name input. hft start --no-ask-name
* make controllers only work if game is running, otherwise switch to other game
* make games use websockets to switch games instead of polling ajax
* make subId the id. If not subId use a prefixed id like _hft_123
* test broadcast
* support multiple games on the same gameId for shared games.
Expand Down

0 comments on commit fa0c77e

Please sign in to comment.