From 2890c16224b6a816752ba93f731d2aabd1d09871 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Fri, 6 Jun 2008 14:20:36 +0000 Subject: [PATCH] Back in the wild and wooly days of Puzzle Pirates development, we determined that we needed to be able to tell if one game ended and another one had started so we introduced GameObject.roundId which was a value that was incremented every time the game started. Thus if you had a timer that expired and you wanted to make sure that somehow the game hadn't ended and then been started anew while you were away, you could save the roundId and check it when you woke up. That was all fine and good, except for the poor choice of variable name. Then we came to implement Whirled and wanted to provide an abstraction of "rounds" which were subunits into which a single game is divided. We had this lovely variable already lying around called roundId and we succumbed to the temptation to overload its meaning and have games that use round increment the round id multiple times during a game which preserves the monotonically increasing nature of roundId as expected by the Parlor code and seemed to do no harm. Then we discovered a pesky wrinkle, which is that GameManager sets GameObject.roundId in gameWillStart() and then goes on to set GameObject.state after that. We were naturally listening for roundId to change and triggering a call to roundDidStart() at that time, but this resulted in a strange sequencing of callback methods that went: roundDidStart(), gameDidStart(), roundDidEnd(), roundDidStart(), ..., roundDidEnd(), gameDidEnd(). The premature roundDidStart() was irksome, and I looked into what would be needed to remedy it. It turned out that a lot of code on the server-side of things depended on the Parlor semantics of roundId and wanted roundId to be set to the current round's value in gameWillStart() and similarly in gameDidStart(). However, there's no gameWillStart() on the client and it didn't appear to me that anyone much cared about roundId in gameDidStart(), so I opted for some hackery in the name of expedience that preserved the server-side semantics but changed the client to see ROUND_ID change after STATE changed. As you might expect given the verbosity of this explanation, that turned out to be a new bad idea stacked on the previous bad idea of reusing roundId which was stacked on the bad choice of name for roundId. It turns out some puzzles in Yohoho did expect roundId to be already set in gameDidStart() which was no longer the case and the inevitable digital mayhem ensued. The time has come to undo the various bad decisions and replace them with new decisions that we hope aren't bad. Those decisions are: - rename roundId in GameObject to sessionId and restore its original semantics which are that it represents a monotonically increasing integer that is incremented (and published to the client) in gameWillStart() and thus represents the current game session from the very first to the very last; - add WhirledGameObject.roundId for handling rounds in Whirled games and give it the semantics we desire which are for it to be set to 1 in gameDidStart() and then incremented only when a new round is started, and reset to 1 when a new game is started (this change is in another commit). This will temporarily break some builds as I need to go rename some things in Yohoho and then I need to look at Bang! Howdy which if I recall correctly also naughtily uses roundId for nefarious ulterior purposes and needs also to be cured of its wayward habits. git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@611 c613c5cb-e716-0410-b11b-feb51c14d237 --- .../parlor/game/client/GameController.as | 6 +- .../threerings/parlor/game/data/GameObject.as | 96 +++++++++---------- .../parlor/game/client/GameController.java | 6 +- .../parlor/game/data/GameObject.java | 85 ++++++++-------- .../parlor/game/server/GameManager.java | 17 +--- .../puzzle/client/PuzzleAnimationWaiter.java | 27 +++--- .../puzzle/client/PuzzleController.java | 19 ++-- .../puzzle/server/PuzzleManager.java | 35 +++---- 8 files changed, 129 insertions(+), 162 deletions(-) diff --git a/src/as/com/threerings/parlor/game/client/GameController.as b/src/as/com/threerings/parlor/game/client/GameController.as index f478f318..39cd330e 100644 --- a/src/as/com/threerings/parlor/game/client/GameController.as +++ b/src/as/com/threerings/parlor/game/client/GameController.as @@ -160,11 +160,11 @@ public /*abstract*/ class GameController extends PlaceController } /** - * Returns the unique round identifier for the current round. + * Returns the unique identifier for the current gameplay session. */ - public function getRoundId () :int + public function getSessionId () :int { - return (_gobj == null) ? -1 : _gobj.roundId; + return (_gobj == null) ? -1 : _gobj.sessionId; } /** diff --git a/src/as/com/threerings/parlor/game/data/GameObject.as b/src/as/com/threerings/parlor/game/data/GameObject.as index 7478096a..349bbfad 100644 --- a/src/as/com/threerings/parlor/game/data/GameObject.as +++ b/src/as/com/threerings/parlor/game/data/GameObject.as @@ -34,13 +34,11 @@ import com.threerings.io.TypedArray; import com.threerings.crowd.data.PlaceObject; /** - * A game object hosts the shared data associated with a game played by - * one or more players. The game object extends the place object so that - * the game can act as a place where players actually go when playing the - * game. Only very basic information is maintained in the base game - * object. It serves as the base for a hierarchy of game object - * derivatives that handle basic gameplay for a suite of different game - * types (ie. turn based games, party games, board games, card games, + * A game object hosts the shared data associated with a game played by one or more players. The + * game object extends the place object so that the game can act as a place where players actually + * go when playing the game. Only very basic information is maintained in the base game object. It + * serves as the base for a hierarchy of game object derivatives that handle basic gameplay for a + * suite of different game types (ie. turn based games, party games, board games, card games, * etc.). */ public class GameObject extends PlaceObject @@ -61,15 +59,15 @@ public class GameObject extends PlaceObject /** The field name of the winners field. */ public static const WINNERS :String = "winners"; - /** The field name of the roundId field. */ - public static const ROUND_ID :String = "roundId"; + /** The field name of the sessionId field. */ + public static const SESSION_ID :String = "sessionId"; /** The field name of the playerStatus field. */ public static const PLAYER_STATUS :String = "playerStatus"; // AUTO-GENERATED: FIELDS END - /** A game state constant indicating that the game has not yet started - * and is still awaiting the arrival of all of the players. */ + /** A game state constant indicating that the game has not yet started and is still awaiting + * the arrival of all of the players. */ public static const PRE_GAME :int = 0; /** A game state constant indicating that the game is in play. */ @@ -84,13 +82,12 @@ public class GameObject extends PlaceObject /** The player status constant for a player whose game is in play. */ public static const PLAYER_IN_PLAY :int = 0; - /** The player status constant for a player whose has been knocked out - * of the game. NOTE: This can include a player choosing to leave a - * game prematurely. */ + /** The player status constant for a player whose has been knocked out of the game. NOTE: This + * can include a player choosing to leave a game prematurely. */ public static const PLAYER_LEFT_GAME :int = 1; - /** The game state, one of {@link #PRE_GAME}, {@link #IN_PLAY}, - * {@link #GAME_OVER}, or {@link #CANCELLED}. */ + /** The game state, one of {@link #PRE_GAME}, {@link #IN_PLAY}, {@link #GAME_OVER}, or + * {@link #CANCELLED}. */ public var state :int = PRE_GAME; /** Indicates whether or not this game is rated. */ @@ -102,17 +99,16 @@ public class GameObject extends PlaceObject /** The usernames of the players involved in this game. */ public var players :TypedArray; /* of Name */ - /** Whether each player in the game is a winner, or null - * if the game is not yet over. */ + /** Whether each player in the game is a winner, or null if the game is not yet over. */ public var winners :TypedArray; /* of Boolean */ - /** The unique round identifier for the current round. */ - public var roundId :int; + /** A unique identifier for each game session. Every time the game is started, this value will + * be incremented to provide a unique identifier for that particular session. */ + public var sessionId :int; - /** If null, indicates that all present players are active, or for - * more complex games can be non-null to indicate the current status - * of each player in the game. The status value is one of - * {@link #PLAYER_LEFT_GAME} or {@link #PLAYER_IN_PLAY}. */ + /** If null, indicates that all present players are active, or for more complex games can be + * non-null to indicate the current status of each player in the game. The status value is one + * of {@link #PLAYER_LEFT_GAME} or {@link #PLAYER_IN_PLAY}. */ public var playerStatus :TypedArray; /* of int */ /** @@ -146,8 +142,8 @@ public class GameObject extends PlaceObject } /** - * Returns whether the given player is still an active player in - * the game. (Ie. whether or not they are still participating.) + * Returns whether the given player is still an active player in the game. (Ie. whether or not + * they are still participating.) */ public function isActivePlayer (pidx :int) :Boolean { @@ -156,8 +152,8 @@ public class GameObject extends PlaceObject } /** - * Returns the player index of the given user in the game, or - * -1 if the player is not involved in the game. + * Returns the player index of the given user in the game, or -1 if the player is + * not involved in the game. */ public function getPlayerIndex (username :Name) :int { @@ -165,8 +161,8 @@ public class GameObject extends PlaceObject } /** - * Returns whether the game is in play. A game that is not in play - * could either be awaiting players, ended, or cancelled. + * Returns whether the game is in play. A game that is not in play could either be awaiting + * players, ended, or cancelled. */ public function isInPlay () :Boolean { @@ -182,8 +178,8 @@ public class GameObject extends PlaceObject } /** - * Returns whether the given player index is a winner, or false if the - * winners are not yet assigned. + * Returns whether the given player index is a winner, or false if the winners are not yet + * assigned. */ public function isWinner (pidx :int) :Boolean { @@ -191,8 +187,8 @@ public class GameObject extends PlaceObject } /** - * Returns the number of winners for this game, or 0 if - * the winners array is not populated, e.g., the game is not yet over. + * Returns the number of winners for this game, or 0 if the winners array is not + * populated, e.g., the game is not yet over. */ public function getWinnerCount () :int { @@ -216,10 +212,9 @@ public class GameObject extends PlaceObject } /** - * Returns the winner index of the first winning player for this game, - * or -1 if there are no winners or the winners array is - * not yet assigned. This is only likely to be useful for games that - * are known to have a single winner. + * Returns the winner index of the first winning player for this game, or -1 if + * there are no winners or the winners array is not yet assigned. This is only likely to be + * useful for games that are known to have a single winner. */ public function getWinnerIndex () :int { @@ -227,9 +222,8 @@ public class GameObject extends PlaceObject } /** - * Used by {@link #isActivePlayer} to determine if the supplied status is - * associated with an active player (one that has not resigned from the - * game and/or left the game room). + * Used by {@link #isActivePlayer} to determine if the supplied status is associated with an + * active player (one that has not resigned from the game and/or left the game room). */ protected function isActivePlayerStatus (playerStatus :int) :Boolean { @@ -361,19 +355,19 @@ public class GameObject extends PlaceObject // } // // /** -// * Requests that the roundId field be set to the +// * Requests that the sessionId field be set to the // * specified value. The local value will be updated immediately and an // * event will be propagated through the system to notify all listeners // * that the attribute did change. Proxied copies of this object (on // * clients) will apply the value change when they received the // * attribute changed notification. // */ -// public function setRoundId (value :int) :void +// public function setSessionId (value :int) :void // { -// var ovalue :int = this.roundId; +// var ovalue :int = this.sessionId; // requestAttributeChange( -// ROUND_ID, Integer.valueOf(value), Integer.valueOf(ovalue)); -// this.roundId = value; +// SESSION_ID, Integer.valueOf(value), Integer.valueOf(ovalue)); +// this.sessionId = value; // } // // /** @@ -422,7 +416,7 @@ public class GameObject extends PlaceObject // out.writeBoolean(isPrivate); // out.writeObject(players); // out.writeField(winners); -// out.writeInt(roundId); +// out.writeInt(sessionId); // out.writeField(playerStatus); // } @@ -434,11 +428,9 @@ public class GameObject extends PlaceObject isRated = ins.readBoolean(); isPrivate = ins.readBoolean(); players = (ins.readObject() as TypedArray); - winners = (ins.readField(TypedArray.getJavaType(Boolean)) - as TypedArray); - roundId = ins.readInt(); - playerStatus = (ins.readField(TypedArray.getJavaType(int)) - as TypedArray); + winners = (ins.readField(TypedArray.getJavaType(Boolean)) as TypedArray); + sessionId = ins.readInt(); + playerStatus = (ins.readField(TypedArray.getJavaType(int)) as TypedArray); } } } diff --git a/src/java/com/threerings/parlor/game/client/GameController.java b/src/java/com/threerings/parlor/game/client/GameController.java index 4ba00cf1..690467c3 100644 --- a/src/java/com/threerings/parlor/game/client/GameController.java +++ b/src/java/com/threerings/parlor/game/client/GameController.java @@ -163,11 +163,11 @@ public abstract class GameController extends PlaceController } /** - * Returns the unique round identifier for the current round. + * Returns the unique session identifier for the current gameplay session. */ - public int getRoundId () + public int getSessionId () { - return (_gobj == null) ? -1 : _gobj.roundId; + return (_gobj == null) ? -1 : _gobj.sessionId; } /** diff --git a/src/java/com/threerings/parlor/game/data/GameObject.java b/src/java/com/threerings/parlor/game/data/GameObject.java index 0e9cb82a..7ea13eea 100644 --- a/src/java/com/threerings/parlor/game/data/GameObject.java +++ b/src/java/com/threerings/parlor/game/data/GameObject.java @@ -27,13 +27,11 @@ import com.threerings.util.Name; import com.threerings.crowd.data.PlaceObject; /** - * A game object hosts the shared data associated with a game played by - * one or more players. The game object extends the place object so that - * the game can act as a place where players actually go when playing the - * game. Only very basic information is maintained in the base game - * object. It serves as the base for a hierarchy of game object - * derivatives that handle basic gameplay for a suite of different game - * types (ie. turn based games, party games, board games, card games, + * A game object hosts the shared data associated with a game played by one or more players. The + * game object extends the place object so that the game can act as a place where players actually + * go when playing the game. Only very basic information is maintained in the base game object. It + * serves as the base for a hierarchy of game object derivatives that handle basic gameplay for a + * suite of different game types (ie. turn based games, party games, board games, card games, * etc.). */ public class GameObject extends PlaceObject @@ -54,15 +52,15 @@ public class GameObject extends PlaceObject /** The field name of the winners field. */ public static final String WINNERS = "winners"; - /** The field name of the roundId field. */ - public static final String ROUND_ID = "roundId"; + /** The field name of the sessionId field. */ + public static final String SESSION_ID = "sessionId"; /** The field name of the playerStatus field. */ public static final String PLAYER_STATUS = "playerStatus"; // AUTO-GENERATED: FIELDS END - /** A game state constant indicating that the game has not yet started - * and is still awaiting the arrival of all of the players. */ + /** A game state constant indicating that the game has not yet started and is still awaiting + * the arrival of all of the players. */ public static final int PRE_GAME = 0; /** A game state constant indicating that the game is in play. */ @@ -77,13 +75,12 @@ public class GameObject extends PlaceObject /** The player status constant for a player whose game is in play. */ public static final int PLAYER_IN_PLAY = 0; - /** The player status constant for a player whose has been knocked out - * of the game. NOTE: This can include a player choosing to leave a - * game prematurely. */ + /** The player status constant for a player whose has been knocked out of the game. NOTE: This + * can include a player choosing to leave a game prematurely. */ public static final int PLAYER_LEFT_GAME = 1; - /** The game state, one of {@link #PRE_GAME}, {@link #IN_PLAY}, - * {@link #GAME_OVER}, or {@link #CANCELLED}. */ + /** The game state, one of {@link #PRE_GAME}, {@link #IN_PLAY}, {@link #GAME_OVER}, or + * {@link #CANCELLED}. */ public int state = PRE_GAME; /** Indicates whether or not this game is rated. */ @@ -95,19 +92,19 @@ public class GameObject extends PlaceObject /** The usernames of the players involved in this game. */ public Name[] players; - /** Whether each player in the game is a winner, or null - * if the game is not yet over. */ + /** Whether each player in the game is a winner, or null if the game is not yet over. */ public boolean[] winners; - /** The unique round identifier for the current round. */ - public int roundId; + /** A unique identifier for each game session. Every time the game is started, this value will + * be incremented to provide a unique identifier for that particular session. */ + public int sessionId; /** * If null, indicates that all present players are active, or for more complex games can be * non-null to indicate the current status of each player in the game. The status value is one - * of {@link #PLAYER_LEFT_GAME} or {@link #PLAYER_IN_PLAY}.

- * Subclasses of GameObject may use other means to determine a player's status in the game, so - * call {@link #isActivePlayer(int)} to see if a player is still participating in a game. + * of {@link #PLAYER_LEFT_GAME} or {@link #PLAYER_IN_PLAY}.

Subclasses of GameObject may use + * other means to determine a player's status in the game, so call {@link #isActivePlayer(int)} + * to see if a player is still participating in a game. */ public int[] playerStatus; @@ -142,8 +139,8 @@ public class GameObject extends PlaceObject } /** - * Returns whether the given player is still an active player in - * the game. (Ie. whether or not they are still participating.) + * Returns whether the given player is still an active player in the game. (Ie. whether or not + * they are still participating.) */ public boolean isActivePlayer (int pidx) { @@ -152,8 +149,8 @@ public class GameObject extends PlaceObject } /** - * Returns the player index of the given user in the game, or - * -1 if the player is not involved in the game. + * Returns the player index of the given user in the game, or -1 if the player is + * not involved in the game. */ public int getPlayerIndex (Name username) { @@ -167,8 +164,8 @@ public class GameObject extends PlaceObject } /** - * Returns whether the game is in play. A game that is not in play - * could either be awaiting players, ended, or cancelled. + * Returns whether the game is in play. A game that is not in play could either be awaiting + * players, ended, or cancelled. */ public boolean isInPlay () { @@ -184,8 +181,8 @@ public class GameObject extends PlaceObject } /** - * Returns whether the given player index is a winner, or false if the - * winners are not yet assigned. + * Returns whether the given player index is a winner, or false if the winners are not yet + * assigned. */ public boolean isWinner (int pidx) { @@ -193,8 +190,8 @@ public class GameObject extends PlaceObject } /** - * Returns the number of winners for this game, or 0 if - * the winners array is not populated, e.g., the game is not yet over. + * Returns the number of winners for this game, or 0 if the winners array is not + * populated, e.g., the game is not yet over. */ public int getWinnerCount () { @@ -217,10 +214,9 @@ public class GameObject extends PlaceObject } /** - * Returns the winner index of the first winning player for this game, - * or -1 if there are no winners or the winners array is - * not yet assigned. This is only likely to be useful for games that - * are known to have a single winner. + * Returns the winner index of the first winning player for this game, or -1 if + * there are no winners or the winners array is not yet assigned. This is only likely to be + * useful for games that are known to have a single winner. */ public int getWinnerIndex () { @@ -234,9 +230,8 @@ public class GameObject extends PlaceObject } /** - * Used by {@link #isActivePlayer} to determine if the supplied status is - * associated with an active player (one that has not resigned from the - * game and/or left the game room). + * Used by {@link #isActivePlayer} to determine if the supplied status is associated with an + * active player (one that has not resigned from the game and/or left the game room). */ protected boolean isActivePlayerStatus (int playerStatus) { @@ -367,19 +362,19 @@ public class GameObject extends PlaceObject } /** - * Requests that the roundId field be set to the + * Requests that the sessionId field be set to the * specified value. The local value will be updated immediately and an * event will be propagated through the system to notify all listeners * that the attribute did change. Proxied copies of this object (on * clients) will apply the value change when they received the * attribute changed notification. */ - public void setRoundId (int value) + public void setSessionId (int value) { - int ovalue = this.roundId; + int ovalue = this.sessionId; requestAttributeChange( - ROUND_ID, Integer.valueOf(value), Integer.valueOf(ovalue)); - this.roundId = value; + SESSION_ID, Integer.valueOf(value), Integer.valueOf(ovalue)); + this.sessionId = value; } /** diff --git a/src/java/com/threerings/parlor/game/server/GameManager.java b/src/java/com/threerings/parlor/game/server/GameManager.java index a36c099a..9f271535 100644 --- a/src/java/com/threerings/parlor/game/server/GameManager.java +++ b/src/java/com/threerings/parlor/game/server/GameManager.java @@ -368,11 +368,11 @@ public class GameManager extends PlaceManager } /** - * Returns the unique round identifier for the current round. + * Returns the unique session identifier for this game session. */ - public int getRoundId () + public int getSessionId () { - return _gameobj.roundId; + return _gameobj.sessionId; } /** @@ -981,9 +981,8 @@ public class GameManager extends PlaceManager */ protected void gameWillStart () { - // update our round id locally; see gameDidStart() for where we actually broadcast this - // change to the clients - _gameobj.roundId = _gameobj.roundId + 1; + // update our session id + _gameobj.setSessionId(_gameobj.sessionId + 1); // let our delegates do their business applyToDelegates(new DelegateOp() { @@ -1045,12 +1044,6 @@ public class GameManager extends PlaceManager _noShowInterval.cancel(); } - // broadcast the increment of the round identifier (we set this value locally on the server - // in gameWillStart so that delegates and pre-game starters can know what the round is, but - // we don't want the client to hear the ROUND_ID update until after the STATE change has - // been dispatched) - _gameobj.setRoundId(_gameobj.roundId); - // let our delegates do their business applyToDelegates(new DelegateOp() { public void apply (PlaceManagerDelegate delegate) { diff --git a/src/java/com/threerings/puzzle/client/PuzzleAnimationWaiter.java b/src/java/com/threerings/puzzle/client/PuzzleAnimationWaiter.java index 3606c262..47bd632d 100644 --- a/src/java/com/threerings/puzzle/client/PuzzleAnimationWaiter.java +++ b/src/java/com/threerings/puzzle/client/PuzzleAnimationWaiter.java @@ -26,11 +26,9 @@ import com.threerings.media.animation.AnimationWaiter; import com.threerings.puzzle.data.PuzzleObject; /** - * An animation waiter to be used with puzzles that want to modify the - * game object or board in some way after the animations end, and would - * like to do so in a safe fashion such that their changes aren't - * unwittingly performed on game data for a subsequent round of the - * puzzle. + * An animation waiter to be used with puzzles that want to modify the game object or board in some + * way after the animations end, and would like to do so in a safe fashion such that their changes + * aren't unwittingly performed on game data for a subsequent round of the puzzle. */ public abstract class PuzzleAnimationWaiter extends AnimationWaiter { @@ -40,16 +38,15 @@ public abstract class PuzzleAnimationWaiter extends AnimationWaiter public PuzzleAnimationWaiter (PuzzleObject puzobj) { _puzobj = puzobj; - _roundId = puzobj.roundId; + _sessionId = puzobj.sessionId; } /** - * Returns whether the puzzle associated with this puzzle animation - * waiter is still valid. + * Returns whether the puzzle associated with this puzzle animation waiter is still valid. */ public boolean puzzleStillValid () { - return (_puzobj.isInPlay() && (_roundId == _puzobj.roundId)); + return (_puzobj.isInPlay() && (_sessionId == _puzobj.sessionId)); } // documentation inherited @@ -59,16 +56,14 @@ public abstract class PuzzleAnimationWaiter extends AnimationWaiter } /** - * Replacement for {@link AnimationWaiter#allAnimationsFinished} that - * also reports whether the puzzle associated with this animation - * waiter is still valid. + * Replacement for {@link AnimationWaiter#allAnimationsFinished} that also reports whether the + * puzzle associated with this animation waiter is still valid. */ protected abstract void allAnimationsFinished (boolean puzStillValid); - /** The initial round id. */ - protected int _roundId; + /** The initial session id. */ + protected int _sessionId; - /** The puzzle object that the animations we're observering want to - * modify. */ + /** The puzzle object that the animations we're observering want to modify. */ protected PuzzleObject _puzobj; } diff --git a/src/java/com/threerings/puzzle/client/PuzzleController.java b/src/java/com/threerings/puzzle/client/PuzzleController.java index cc12a5d7..8945b130 100644 --- a/src/java/com/threerings/puzzle/client/PuzzleController.java +++ b/src/java/com/threerings/puzzle/client/PuzzleController.java @@ -362,10 +362,9 @@ public abstract class PuzzleController extends GameController break; } - } else if (name.equals(PuzzleObject.ROUND_ID)) { - // Need to clear out stale events. If we don't, we could send - // events that claim to be from the new round that are actually - // from the old round. + } else if (name.equals(PuzzleObject.SESSION_ID)) { + // Need to clear out stale events. If we don't, we could send events that claim to be + // from the new session that are actually from the old session. _events.clear(); } } @@ -378,9 +377,8 @@ public abstract class PuzzleController extends GameController // stop the old action clearAction(); - // when the server gets around to resetting the game, we'll get a - // 'state => IN_PLAY' message which will result in gameDidStart() - // being called and starting the action back up + // when the server gets around to resetting the game, we'll get a 'state => IN_PLAY' + // message which will result in gameDidStart() being called and starting the action back up } /** @@ -767,7 +765,7 @@ public abstract class PuzzleController extends GameController int[] events = CollectionUtil.toIntArray(_events); _events.clear(); -// Log.info("Sending progress [round=" + _puzobj.roundId + +// Log.info("Sending progress [session=" + _puzobj.sessionId + // ", events=" + StringUtil.toString(events) + "]."); // create an array of the board states that correspond with those @@ -780,12 +778,11 @@ public abstract class PuzzleController extends GameController // send the update progress request _puzobj.puzzleGameService.updateProgressSync( - _ctx.getClient(), _puzobj.roundId, events, states); + _ctx.getClient(), _puzobj.sessionId, events, states); } else { // send the update progress request - _puzobj.puzzleGameService.updateProgress( - _ctx.getClient(), _puzobj.roundId, events); + _puzobj.puzzleGameService.updateProgress(_ctx.getClient(), _puzobj.sessionId, events); } } diff --git a/src/java/com/threerings/puzzle/server/PuzzleManager.java b/src/java/com/threerings/puzzle/server/PuzzleManager.java index 90e60e1b..1d789125 100644 --- a/src/java/com/threerings/puzzle/server/PuzzleManager.java +++ b/src/java/com/threerings/puzzle/server/PuzzleManager.java @@ -508,9 +508,9 @@ public abstract class PuzzleManager extends GameManager protected abstract BoardSummary newBoardSummary (Board board); // documentation inherited from interface PuzzleGameProvider - public void updateProgress (ClientObject caller, int roundId, int[] events) + public void updateProgress (ClientObject caller, int sessionId, int[] events) { - updateProgressSync(caller, roundId, events, null); + updateProgressSync(caller, sessionId, events, null); } /** @@ -518,42 +518,37 @@ public abstract class PuzzleManager extends GameManager * checks to make sure that the progress update is valid and the * puzzle is still in play and then applies the updates via {@link #applyProgressEvents}. */ - public void updateProgressSync (ClientObject caller, int roundId, int[] events, Board[] states) + public void updateProgressSync (ClientObject caller, int sessionId, int[] events, Board[] states) { - // bail if the progress update isn't for the current round - if (roundId != _puzobj.roundId) { - // only warn if this isn't a straggling update from the - // previous round - if (roundId != _puzobj.roundId-1) { - log.warning("Received progress update for invalid round, " + - "not applying [game=" + _puzobj.which() + - ", invalidRoundId=" + roundId + - ", roundId=" + _puzobj.roundId + "]."); + // bail if the progress update isn't for the current session + if (sessionId != _puzobj.sessionId) { + // only warn if this isn't a straggling update from the previous session + if (sessionId != _puzobj.sessionId-1) { + log.warning("Received progress update for invalid session, not applying " + + "[game=" + _puzobj.which() + ", invalidSessionId=" + sessionId + + ", sessionId=" + _puzobj.sessionId + "]."); } return; } // if the game is over, we wing straggling updates if (!_puzobj.isInPlay()) { - log.debug("Ignoring straggling events " + - "[game=" + _puzobj.which() + - ", who=" + caller.who() + - ", events=" + StringUtil.toString(events) + "]."); + log.debug("Ignoring straggling events", "game", _puzobj.which(), "who", caller.who(), + "events", events); return; } // determine the caller's player index in the game int pidx = IntListUtil.indexOf(_playerOids, caller.getOid()); if (pidx == -1) { - log.warning("Received progress update for non-player?! " + - "[game=" + _puzobj.which() + ", who=" + caller.who() + - ", ploids=" + StringUtil.toString(_playerOids) + "]."); + log.warning("Received progress update for non-player?!", "game", _puzobj.which(), + "who", caller.who(), "ploids", _playerOids); return; } // Log.info("Handling progress events [game=" + _puzobj.which() + -// ", pidx=" + pidx + ", roundId=" + roundId + +// ", pidx=" + pidx + ", sessionId=" + sessionId + // ", count=" + events.length + "]."); // note that we received a progress update from this player