From 4bd065845eeb016ef6f34ef0e6f76f5b811d350f Mon Sep 17 00:00:00 2001
From: Andy Janata
Date: Sat, 20 Jul 2013 11:11:01 -0700
Subject: [PATCH 1/5] Fix z-index for game options so you can actually click
into the password field when there are a lot of cardsets.
---
WebContent/cah.css | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/WebContent/cah.css b/WebContent/cah.css
index 401ce09..c82ef5c 100644
--- a/WebContent/cah.css
+++ b/WebContent/cah.css
@@ -377,6 +377,10 @@ span.debug, span.admin {
width: 700px;
}
+.game_options {
+ z-index: 500;
+}
+
.game_right_side_box {
height: 60%;
margin: 10px;
From 2187eaa32034b8dc7cb6ba621bd7a415c9f2e554 Mon Sep 17 00:00:00 2001
From: Andy Janata
Date: Wed, 7 Aug 2013 07:52:27 +0100
Subject: [PATCH 2/5] Increase max games to 250.
---
src/net/socialgamer/cah/CahModule.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/net/socialgamer/cah/CahModule.java b/src/net/socialgamer/cah/CahModule.java
index 48240a1..8f76ba6 100644
--- a/src/net/socialgamer/cah/CahModule.java
+++ b/src/net/socialgamer/cah/CahModule.java
@@ -60,7 +60,7 @@ public class CahModule extends AbstractModule {
@Provides
@MaxGames
Integer provideMaxGames() {
- return 200;
+ return 250;
}
/**
From fe0b3552b3715cb22231a6f0fefe6ad3ed4c1751 Mon Sep 17 00:00:00 2001
From: Andy Janata
Date: Wed, 7 Aug 2013 07:58:28 +0100
Subject: [PATCH 3/5] Resolve confusion between ns and ms, which should not
have actually changed much except the fuzz time around idle returns (which
seem to never happen in production anymore). Increased number of messages
returned at one time to 20. Increased wait time for more messages before
returning to 50ms.
---
src/net/socialgamer/cah/data/ConnectedUsers.java | 3 ++-
.../socialgamer/cah/servlets/LongPollServlet.java | 13 +++++++------
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/src/net/socialgamer/cah/data/ConnectedUsers.java b/src/net/socialgamer/cah/data/ConnectedUsers.java
index c53abde..70e9b4a 100644
--- a/src/net/socialgamer/cah/data/ConnectedUsers.java
+++ b/src/net/socialgamer/cah/data/ConnectedUsers.java
@@ -30,6 +30,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
@@ -58,7 +59,7 @@ public class ConnectedUsers {
/**
* Duration of a ping timeout, in nanoseconds.
*/
- public static final long PING_TIMEOUT = 45L * 1000L * 1000000L;
+ public static final long PING_TIMEOUT = TimeUnit.SECONDS.toNanos(45);
/**
* Key (username) must be stored in lower-case to facilitate case-insensitivity in nicks.
diff --git a/src/net/socialgamer/cah/servlets/LongPollServlet.java b/src/net/socialgamer/cah/servlets/LongPollServlet.java
index e5d846a..fd8413a 100644
--- a/src/net/socialgamer/cah/servlets/LongPollServlet.java
+++ b/src/net/socialgamer/cah/servlets/LongPollServlet.java
@@ -30,6 +30,7 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
@@ -60,28 +61,28 @@ public class LongPollServlet extends CahServlet {
/**
* Minimum amount of time before timing out and returning a no-op, in nanoseconds.
*/
- private static final long TIMEOUT_BASE = 20 * 1000 * 1000;
+ private static final long TIMEOUT_BASE = TimeUnit.SECONDS.toNanos(20);
// private static final long TIMEOUT_BASE = 10 * 1000 * 1000;
/**
* Randomness factor added to minimum timeout duration, in nanoseconds. The maximum timeout delay
* will be TIMEOUT_BASE + TIMEOUT_RANDOMNESS - 1.
*/
- private static final double TIMEOUT_RANDOMNESS = 5 * 1000 * 1000;
+ private static final double TIMEOUT_RANDOMNESS = TimeUnit.SECONDS.toNanos(5);
// private static final double TIMEOUT_RANDOMNESS = 0;
/**
* The maximum number of messages which will be returned to a client during a single poll
* operation.
*/
- private static final int MAX_MESSAGES_PER_POLL = 10;
+ private static final int MAX_MESSAGES_PER_POLL = 20;
/**
* An amount of milliseconds to wait after being notified that the user has at least one message
* to deliver, before we actually deliver messages. This will allow multiple messages that arrive
* in close proximity to each other to actually be delivered in the same client request.
*/
- private static final int WAIT_FOR_MORE_DELAY = 30;
+ private static final int WAIT_FOR_MORE_DELAY = 50;
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
@@ -99,9 +100,9 @@ public class LongPollServlet extends CahServlet {
final User user = (User) hSession.getAttribute(SessionAttribute.USER);
assert (user != null);
user.contactedServer();
- while (!(user.hasQueuedMessages()) && System.nanoTime() < end) {
+ while (!(user.hasQueuedMessages()) && System.nanoTime() - end < 0) {
try {
- user.waitForNewMessageNotification((end - System.nanoTime()) / 1000);
+ user.waitForNewMessageNotification(TimeUnit.NANOSECONDS.toMillis(end - System.nanoTime()));
} catch (final InterruptedException ie) {
// pass
}
From 638fac780a0b88f74ffcb826e9b869f26baaec50 Mon Sep 17 00:00:00 2001
From: Andy Janata
Date: Wed, 7 Aug 2013 08:01:47 +0100
Subject: [PATCH 4/5] Remove several game list refresh broadcasts: - never
broadcast when a player joins a game (unless it's a new game) - removed a
duplicate broadcast in this situation as well - never broadcast when a player
leaves a game (unless the game no longer exists) - never broadcast when a
game's options change (unless the state of it having or having not a password
changes) - DO broadcast when a game resets to the lobby state (we were
broadcasting when a game started but not when it ended)
In an effort to reduce deadlocks, do not actually hold a lock over the list of players in a game and instead make a copy into an array for looping, in several locations.
---
WebContent/game.jsp | 12 ++-
WebContent/index.jsp | 8 ++
src/net/socialgamer/cah/data/Game.java | 91 +++++++++----------
.../cah/handlers/ChangeGameOptionHandler.java | 8 +-
.../cah/handlers/JoinGameHandler.java | 1 -
5 files changed, 65 insertions(+), 55 deletions(-)
diff --git a/WebContent/game.jsp b/WebContent/game.jsp
index f7ff2d3..b715cd9 100644
--- a/WebContent/game.jsp
+++ b/WebContent/game.jsp
@@ -95,12 +95,14 @@ 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: 28 April 2013:
+ Most recent update: 7 August 2013:
- - Version 1.3 of the base Cards Against Humanity game.
- - Card sets are grouped by official or custom.
- - You can view all of the cards in the game,
- including searching by text and filtering card set.
+ - 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.
+ - A lot of custom card sets have been added.
+ - Cleaned up some error handling.
+ - Tried to fix some more of the server crashes.
Nickname:
diff --git a/WebContent/index.jsp b/WebContent/index.jsp
index 9539761..887b86c 100644
--- a/WebContent/index.jsp
+++ b/WebContent/index.jsp
@@ -54,6 +54,14 @@ to, for instance, display the number of connected players.
Recent Changes:
+ - 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
+ for new games, removed games, when games become passworded, or when you leave a game.
+ - A lot of custom card sets have been added.
+ - Cleaned up some error handling.
+ - Tried to fix some more of the server crashes.
+
- 28 April 2013:
- Version 1.3 of the base Cards Against Humanity game.
- Card sets are grouped by official or custom.
diff --git a/src/net/socialgamer/cah/data/Game.java b/src/net/socialgamer/cah/data/Game.java
index 0f73515..b291b92 100644
--- a/src/net/socialgamer/cah/data/Game.java
+++ b/src/net/socialgamer/cah/data/Game.java
@@ -195,7 +195,8 @@ public class Game {
data.put(LongPollResponse.NICKNAME, user.getNickname());
broadcastToPlayers(MessageType.GAME_PLAYER_EVENT, data);
- gameManager.broadcastGameListRefresh();
+ // Don't do this anymore, it was driving up a crazy amount of traffic.
+ // gameManager.broadcastGameListRefresh();
}
/**
@@ -263,7 +264,8 @@ public class Game {
data.put(LongPollResponse.NICKNAME, user.getNickname());
broadcastToPlayers(MessageType.GAME_PLAYER_EVENT, data);
- gameManager.broadcastGameListRefresh();
+ // Don't do this anymore, it was driving up a crazy amount of traffic.
+ // gameManager.broadcastGameListRefresh();
if (host == player) {
if (players.size() > 0) {
@@ -428,13 +430,13 @@ public class Game {
info.put(GameInfo.PASSWORD, password);
}
info.put(GameInfo.HAS_PASSWORD, password != null && !password.equals(""));
- synchronized (players) {
- final List playerNames = new ArrayList(players.size());
- for (final Player player : players) {
- playerNames.add(player.toString());
- }
- info.put(GameInfo.PLAYERS, playerNames);
+
+ final Player[] playersCopy = players.toArray(new Player[players.size()]);
+ final List playerNames = new ArrayList(playersCopy.length);
+ for (final Player player : playersCopy) {
+ playerNames.add(player.toString());
}
+ info.put(GameInfo.PLAYERS, playerNames);
return info;
}
@@ -444,12 +446,11 @@ public class Game {
*/
public List