diff --git a/WebContent/cah.css b/WebContent/cah.css
index c82ef5c..1319501 100644
--- a/WebContent/cah.css
+++ b/WebContent/cah.css
@@ -582,3 +582,10 @@ span.debug, span.admin {
.nowrap {
white-space: nowrap;
}
+
+.cardnum {
+ position: absolute;
+ right: 10px;
+ bottom: 19px;
+ font-size: 8pt;
+}
diff --git a/WebContent/game.jsp b/WebContent/game.jsp
index b715cd9..f09c163 100644
--- a/WebContent/game.jsp
+++ b/WebContent/game.jsp
@@ -95,8 +95,12 @@ HttpSession hSession = request.getSession(true);
If this is your first time playing, you may wish to read the changelog and list of
known issues.
-
Most recent update: 7 August 2013:
+
Most recent update: 3 September 2013:
+
The Box Expansion and PAX Prime 2013 cards have been added. If you have
+ any spares of these card numbers and are willing to part with them, it would be awesome if you'd
+ email me and send them to me,
+ as I was unable to acquire them at PAX: 29, 30, 33, 34, 35, 36, 37
The game list will not automatically update all the time now.
You will need to start using the Refresh Games button. The game list will automatically update
for new games, removed games, when games become passworded, or when you leave a game.
@@ -375,13 +379,13 @@ HttpSession hSession = request.getSession(true);
+ You must click outside the box to apply the password.
- You must click outside the box to apply the password.
diff --git a/WebContent/index.jsp b/WebContent/index.jsp
index 887b86c..c062edc 100644
--- a/WebContent/index.jsp
+++ b/WebContent/index.jsp
@@ -54,6 +54,12 @@ to, for instance, display the number of connected players.
Recent Changes:
+
5 September 2013:
+
The Box Expansion and PAX Prime 2013 cards have been added. If you have
+ any spares of these card numbers and are willing to part with them, it would be awesome if you'd
+ email me and send them to me,
+ as I was unable to acquire them at PAX: 29, 30, 33, 34, 35, 36, 37
+
7 August 2013:
The game list will not automatically update all the time now.
You will need to start using the Refresh Games button. The game list will automatically update
diff --git a/WebContent/js/cah.ajax.handlers.js b/WebContent/js/cah.ajax.handlers.js
index 4440403..db06804 100644
--- a/WebContent/js/cah.ajax.handlers.js
+++ b/WebContent/js/cah.ajax.handlers.js
@@ -41,6 +41,8 @@ cah.ajax.ErrorHandlers[cah.$.AjaxOperation.REGISTER] = function(data) {
$("#nickname").focus();
};
+// hacky way to avoid joining a game from the hash if the server told us to join a game.
+cah.ajax.hasAutojoinedGame_ = false;
cah.ajax.SuccessHandlers[cah.$.AjaxOperation.FIRST_LOAD] = function(data) {
cah.CardSet.populateCardSets(data[cah.$.AjaxResponse.CARD_SETS]);
@@ -55,6 +57,7 @@ cah.ajax.SuccessHandlers[cah.$.AjaxOperation.FIRST_LOAD] = function(data) {
case cah.$.ReconnectNextAction.GAME:
cah.log.status("Reconnecting to game...");
cah.Game.joinGame(data[cah.$.AjaxResponse.GAME_ID]);
+ cah.ajax.hasAutojoinedGame_ = true;
break;
case cah.$.ReconnectNextAction.NONE:
// pass
@@ -77,6 +80,8 @@ cah.ajax.ErrorHandlers[cah.$.AjaxOperation.FIRST_LOAD] = function(data) {
}
};
+// another hack thing to trigger an auto-join after the first game list refresh
+cah.ajax.autojoinGameId_ = undefined;
/**
* This should only be called after we have a valid registration with the server, as we start doing
* long polling here.
@@ -92,6 +97,22 @@ cah.ajax.after_registered = function() {
cah.longpoll.longPoll();
// Dirty that we have to do this here... Oh well.
app_resize();
+
+ var hash = window.location.hash.substring(1);
+ if (hash && hash != '') {
+ // TODO find a better place for this if we ever have more than just game=id in the hash.
+ var params = hash.split('&');
+ var options = {};
+ for ( var i in params) {
+ var split = params[i].split('=');
+ var key = split[0];
+ var value = split[1];
+ options[key] = value;
+ }
+ if (options['game']) {
+ cah.ajax.autojoinGameId_ = options['game'];
+ }
+ }
};
cah.ajax.SuccessHandlers[cah.$.AjaxOperation.CHAT] = function(data) {
@@ -114,6 +135,16 @@ cah.ajax.SuccessHandlers[cah.$.AjaxOperation.NAMES] = function(data) {
cah.ajax.SuccessHandlers[cah.$.AjaxOperation.GAME_LIST] = function(data) {
cah.GameList.instance.processUpdate(data);
+
+ if (cah.ajax.autojoinGameId_ && !cah.ajax.hasAutojoinedGame_) {
+ try {
+ cah.GameList.instance.joinGame(cah.ajax.autojoinGameId_);
+ } catch (e) {
+ cah.log.error(e);
+ cah.updateHash('');
+ }
+ cah.ajax.autojoinGameId_ = undefined;
+ }
};
cah.ajax.SuccessHandlers[cah.$.AjaxOperation.JOIN_GAME] = function(data, req) {
diff --git a/WebContent/js/cah.app.js b/WebContent/js/cah.app.js
index 4940d9d..ed4e11a 100644
--- a/WebContent/js/cah.app.js
+++ b/WebContent/js/cah.app.js
@@ -194,6 +194,7 @@ function chatsubmit_click(game_id, parent_element) {
function logout_click() {
if (confirm("Are you sure you wish to log out?")) {
cah.Ajax.build(cah.$.AjaxOperation.LOG_OUT).run();
+ cah.updateHash('');
}
}
diff --git a/WebContent/js/cah.game.js b/WebContent/js/cah.game.js
index b40d14b..ccc70b2 100644
--- a/WebContent/js/cah.game.js
+++ b/WebContent/js/cah.game.js
@@ -308,6 +308,8 @@ cah.Game.joinGame = function(gameId) {
var game = new cah.Game(gameId);
cah.currentGames[gameId] = game;
game.insertIntoDocument();
+
+ cah.updateHash('game=' + gameId);
};
/**
@@ -1099,6 +1101,8 @@ cah.Game.prototype.dispose = function() {
$("#leave_game").unbind().hide();
$("#start_game").unbind().hide();
$(window).off("resize.game_" + this.id_);
+
+ cah.updateHash('');
};
/**
diff --git a/WebContent/js/cah.gamelist.js b/WebContent/js/cah.gamelist.js
index 0b6e913..abf4f8d 100644
--- a/WebContent/js/cah.gamelist.js
+++ b/WebContent/js/cah.gamelist.js
@@ -38,12 +38,12 @@ cah.GameList = function() {
this.element_ = $("#game_list")[0];
/**
- * Array of all game lobby objects.
+ * Map all game lobby objects, id -> game lobby.
*
- * @type {Array[cah.GameListLobby]}
+ * @type {Object}
* @private
*/
- this.games_ = new Array();
+ this.games_ = {};
$("#create_game").click(cah.bind(this, this.createGameClick_));
$("#refresh_games").click(cah.bind(this, this.refreshGamesClick_));
@@ -99,7 +99,7 @@ cah.GameList.prototype.processUpdate = function(gameData) {
for ( var key in this.games_) {
this.games_[key].dispose();
}
- this.games_ = new Array();
+ this.games_ = {};
// Sort the games into two lists, passworded and non-passworded.
var passworded = new Array();
@@ -118,7 +118,7 @@ cah.GameList.prototype.processUpdate = function(gameData) {
for ( var i = 0; i < games.length; i++) {
var game = games[i];
var lobby = new cah.GameListLobby(this.element_, game);
- this.games_.push(lobby);
+ this.games_[game[cah.$.GameInfo.ID]] = lobby;
}
if (gameData[cah.$.AjaxResponse.GAMES].length < gameData[cah.$.AjaxResponse.MAX_GAMES]) {
@@ -128,6 +128,21 @@ cah.GameList.prototype.processUpdate = function(gameData) {
}
};
+/**
+ * Join the given game.
+ *
+ * @param {Number}
+ * id The id of the game to join.
+ */
+cah.GameList.prototype.joinGame = function(id) {
+ var game = this.games_[Number(id)];
+ if (game) {
+ game.join();
+ } else {
+ throw 'Game ' + id + ' does not exist.';
+ }
+};
+
/**
* Event handler for the clicking the Create Game button.
*
@@ -237,6 +252,13 @@ cah.GameListLobby.prototype.joinClick = function() {
cah.Ajax.build(cah.$.AjaxOperation.JOIN_GAME).withGameId(this.id_).withPassword(password).run();
};
+/**
+ * Join this game, by simulating a click of its join button.
+ */
+cah.GameListLobby.prototype.join = function() {
+ $('.gamelist_lobby_join', this.element_).click();
+};
+
/**
* Remove the game lobby from the document and free up resources.
*/
diff --git a/WebContent/js/cah.js b/WebContent/js/cah.js
index 4ffe4d7..c4aa411 100644
--- a/WebContent/js/cah.js
+++ b/WebContent/js/cah.js
@@ -108,3 +108,16 @@ cah.inherits = function(childCtor, parentCtor) {
childCtor.prototype = new tempCtor();
childCtor.prototype.constructor = childCtor;
};
+
+/**
+ * Updates the hash in the browser's URL for deeplinks.
+ *
+ * TODO: If we ever want more than just game=id here, this will have to deal with a map somehow.
+ *
+ * @param {String}
+ * hash The hash to use in the URL.
+ */
+cah.updateHash = function(hash) {
+ window.location.replace(window.location.protocol + '//' + window.location.host
+ + window.location.pathname.replace(/#$/g, '') + '#' + hash);
+};