From b5d3c5c37b33f1749533deff6695ea61911bd66e Mon Sep 17 00:00:00 2001
From: Andy Janata
Date: Mon, 11 Nov 2013 02:24:58 +0000
Subject: [PATCH 1/4] Card numbering support for the 13PAX set.
---
WebContent/cah.css | 7 +++++++
WebContent/game.jsp | 6 +++++-
WebContent/index.jsp | 6 ++++++
3 files changed, 18 insertions(+), 1 deletion(-)
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..1822b2a 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.
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
From 0cbf74b9156a0344f2122777143b49d133119343 Mon Sep 17 00:00:00 2001
From: Andy Janata
Date: Mon, 11 Nov 2013 03:21:20 +0000
Subject: [PATCH 2/4] Move the "click outside to apply password" message closer
to the box.
---
WebContent/game.jsp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/WebContent/game.jsp b/WebContent/game.jsp
index 1822b2a..f09c163 100644
--- a/WebContent/game.jsp
+++ b/WebContent/game.jsp
@@ -379,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.
From 844ce99cdb8205e79121b3c1fa4771917bfb6806 Mon Sep 17 00:00:00 2001
From: Andy Janata
Date: Mon, 11 Nov 2013 03:22:54 +0000
Subject: [PATCH 3/4] Update the URL bar with a deeplink to the current game,
and process these deeplinks when the app loads. Fixes #30.
---
WebContent/js/cah.ajax.handlers.js | 33 ++++++++++++++++++++++++++++++
WebContent/js/cah.app.js | 1 +
WebContent/js/cah.game.js | 4 ++++
WebContent/js/cah.gamelist.js | 32 ++++++++++++++++++++++++-----
WebContent/js/cah.js | 13 ++++++++++++
5 files changed, 78 insertions(+), 5 deletions(-)
diff --git a/WebContent/js/cah.ajax.handlers.js b/WebContent/js/cah.ajax.handlers.js
index 4440403..28d3a72 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,24 @@ cah.ajax.after_registered = function() {
cah.longpoll.longPoll();
// Dirty that we have to do this here... Oh well.
app_resize();
+
+ if (!cah.ajax.hasAutojoinedGame_) {
+ 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 +137,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_) {
+ 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 5d1716c..11801b9 100644
--- a/WebContent/js/cah.app.js
+++ b/WebContent/js/cah.app.js
@@ -185,6 +185,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);
+};
From 7e7be6c54e723c111e1f3f012ef914b25fdba638 Mon Sep 17 00:00:00 2001
From: Andy Janata
Date: Mon, 11 Nov 2013 03:27:23 +0000
Subject: [PATCH 4/4] Fix reloading page when inside a game from trying to
rejoin the game twice. Fixes #30, again.
---
WebContent/js/cah.ajax.handlers.js | 30 ++++++++++++++----------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/WebContent/js/cah.ajax.handlers.js b/WebContent/js/cah.ajax.handlers.js
index 28d3a72..db06804 100644
--- a/WebContent/js/cah.ajax.handlers.js
+++ b/WebContent/js/cah.ajax.handlers.js
@@ -98,21 +98,19 @@ cah.ajax.after_registered = function() {
// Dirty that we have to do this here... Oh well.
app_resize();
- if (!cah.ajax.hasAutojoinedGame_) {
- 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'];
- }
+ 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'];
}
}
};
@@ -138,7 +136,7 @@ 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_) {
+ if (cah.ajax.autojoinGameId_ && !cah.ajax.hasAutojoinedGame_) {
try {
cah.GameList.instance.joinGame(cah.ajax.autojoinGameId_);
} catch (e) {