Make it possible for a player to report in when they arrive in a room but not
cause the game to start. In Whirled we'll have all players report in immediately for games that want to handle playerReady() themselves so that they can do whatever they want before the game starts and then finally start it with a call to playerReady() from all the players. git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@417 c613c5cb-e716-0410-b11b-feb51c14d237
This commit is contained in:
@@ -24,6 +24,7 @@ package com.threerings.parlor.game.server;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.samskivert.util.ArrayIntSet;
|
||||
import com.samskivert.util.IntListUtil;
|
||||
@@ -47,7 +48,6 @@ import com.threerings.crowd.server.CrowdServer;
|
||||
import com.threerings.crowd.server.PlaceManager;
|
||||
import com.threerings.crowd.server.PlaceManagerDelegate;
|
||||
|
||||
import com.threerings.parlor.Log;
|
||||
import com.threerings.parlor.data.ParlorCodes;
|
||||
import com.threerings.parlor.game.data.GameAI;
|
||||
import com.threerings.parlor.game.data.GameCodes;
|
||||
@@ -57,6 +57,8 @@ import com.threerings.parlor.server.ParlorSender;
|
||||
|
||||
import com.threerings.util.MessageBundle;
|
||||
|
||||
import static com.threerings.parlor.Log.log;
|
||||
|
||||
/**
|
||||
* The game manager handles the server side management of a game. It manipulates the game state in
|
||||
* accordance with the logic of the game flow and generally manages the whole game playing process.
|
||||
@@ -125,7 +127,7 @@ public class GameManager extends PlaceManager
|
||||
|
||||
// sanity-check the player index
|
||||
if (pidx == -1) {
|
||||
Log.warning("Couldn't find free player index for player [game=" + where() +
|
||||
log.warning("Couldn't find free player index for player [game=" + where() +
|
||||
", player=" + player +
|
||||
", players=" + StringUtil.toString(_gameobj.players) + "].");
|
||||
return -1;
|
||||
@@ -147,14 +149,14 @@ public class GameManager extends PlaceManager
|
||||
{
|
||||
// make sure the specified player index is valid
|
||||
if (pidx < 0 || pidx >= getPlayerSlots()) {
|
||||
Log.warning("Attempt to add player at an invalid index [game=" + where() +
|
||||
log.warning("Attempt to add player at an invalid index [game=" + where() +
|
||||
", player=" + player + ", pidx=" + pidx + "].");
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure the player index is available
|
||||
if (_gameobj.players[pidx] != null) {
|
||||
Log.warning("Attempt to add player at occupied index [game=" + where() +
|
||||
log.warning("Attempt to add player at occupied index [game=" + where() +
|
||||
", player=" + player + ", pidx=" + pidx + "].");
|
||||
return false;
|
||||
}
|
||||
@@ -162,7 +164,7 @@ public class GameManager extends PlaceManager
|
||||
// make sure the player isn't already somehow a part of the game to avoid any potential
|
||||
// badness that might ensue if we added them more than once
|
||||
if (_gameobj.getPlayerIndex(player) != -1) {
|
||||
Log.warning("Attempt to add player to game that they're already playing " +
|
||||
log.warning("Attempt to add player to game that they're already playing " +
|
||||
"[game=" + where() + ", player=" + player + "].");
|
||||
return false;
|
||||
}
|
||||
@@ -170,7 +172,7 @@ public class GameManager extends PlaceManager
|
||||
// get the player's body object
|
||||
BodyObject bobj = CrowdServer.lookupBody(player);
|
||||
if (bobj == null) {
|
||||
Log.warning("Unable to get body object while adding player [game=" + where() +
|
||||
log.warning("Unable to get body object while adding player [game=" + where() +
|
||||
", player=" + player + "].");
|
||||
return false;
|
||||
}
|
||||
@@ -205,7 +207,7 @@ public class GameManager extends PlaceManager
|
||||
|
||||
// sanity-check the player index
|
||||
if (pidx == -1) {
|
||||
Log.warning("Attempt to remove non-player from players list [game=" + where() +
|
||||
log.warning("Attempt to remove non-player from players list [game=" + where() +
|
||||
", player=" + player +
|
||||
", players=" + StringUtil.toString(_gameobj.players) + "].");
|
||||
return false;
|
||||
@@ -420,7 +422,7 @@ public class GameManager extends PlaceManager
|
||||
{
|
||||
// complain if we're already started
|
||||
if (_gameobj.state == GameObject.IN_PLAY) {
|
||||
Log.warning("Requested to start an already in-play game [game=" + where() + "].");
|
||||
log.warning("Requested to start an already in-play game [game=" + where() + "].");
|
||||
Thread.dumpStack();
|
||||
return false;
|
||||
}
|
||||
@@ -430,7 +432,7 @@ public class GameManager extends PlaceManager
|
||||
|
||||
// make sure everyone has turned up
|
||||
if (!allPlayersReady()) {
|
||||
Log.warning("Requested to start a game that is still awaiting players " +
|
||||
log.warning("Requested to start a game that is still awaiting players " +
|
||||
"[game=" + where() + ", pnames=" + StringUtil.toString(_gameobj.players) +
|
||||
", poids=" + StringUtil.toString(_playerOids) + "].");
|
||||
return false;
|
||||
@@ -442,12 +444,12 @@ public class GameManager extends PlaceManager
|
||||
if (_postponedStart) {
|
||||
// We've already tried postponing once, doesn't do us any good to throw ourselves
|
||||
// into a frenzy trying again.
|
||||
Log.warning("Tried to postpone the start of a still-ending game multiple times " +
|
||||
log.warning("Tried to postpone the start of a still-ending game multiple times " +
|
||||
"[game=" + where() + "].");
|
||||
_postponedStart = false;
|
||||
return false;
|
||||
}
|
||||
Log.info("Postponing start of still-ending game [game=" + where() + "].");
|
||||
log.info("Postponing start of still-ending game [game=" + where() + "].");
|
||||
_postponedStart = true;
|
||||
// TEMP: track down weirdness
|
||||
final Exception firstCall = new Exception();
|
||||
@@ -457,8 +459,7 @@ public class GameManager extends PlaceManager
|
||||
boolean result = startGame();
|
||||
// TEMP: track down weirdness
|
||||
if (!result && !_postponedStart) {
|
||||
Log.warning("First call to startGame: ");
|
||||
Log.logStackTrace(firstCall);
|
||||
log.log(Level.WARNING, "First call to startGame: ", firstCall);
|
||||
}
|
||||
// End: temp
|
||||
}
|
||||
@@ -523,7 +524,7 @@ public class GameManager extends PlaceManager
|
||||
// END TEMP
|
||||
|
||||
if (!_gameobj.isInPlay()) {
|
||||
Log.info("Refusing to end game that was not in play [game=" + where() + "].");
|
||||
log.info("Refusing to end game that was not in play [game=" + where() + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -591,26 +592,30 @@ public class GameManager extends PlaceManager
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the client when the player is ready for the game to start. This method is
|
||||
* dispatched dynamically by {@link #messageReceived}.
|
||||
* Called by the client when the player has arrived in the game room and has loaded their
|
||||
* bits. Most games will simply call {@link #playerReady} but games that wish to delay their
|
||||
* actual start until players take some action must report ASAP with a call to {@link
|
||||
* #playerInRoom} to let the server know that they have arrived and will later be calling
|
||||
* {@link #playerReady} when they are ready for the game to actually start.
|
||||
*/
|
||||
public void playerReady (BodyObject caller)
|
||||
public void playerInRoom (BodyObject caller)
|
||||
{
|
||||
// get the user's player index
|
||||
int pidx = _gameobj.getPlayerIndex(caller.getVisibleName());
|
||||
if (pidx == -1) {
|
||||
// only complain if this is not a party game, since it's perfectly normal to receive a
|
||||
// player ready notification from a user entering a party game in which they're not yet
|
||||
// a participant
|
||||
if (needsNoShowTimer()) {
|
||||
Log.warning("Received playerReady() from non-player? [game=" + where() +
|
||||
", who=" + caller.who() + "].");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// make a note of this player's oid
|
||||
_playerOids[pidx] = caller.getOid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the client when the player is ready for the game to start. This method is
|
||||
* dispatched dynamically by {@link #messageReceived}.
|
||||
*/
|
||||
public void playerReady (BodyObject caller)
|
||||
{
|
||||
playerInRoom(caller);
|
||||
|
||||
// if everyone is now ready to go, get things underway
|
||||
if (allPlayersReady()) {
|
||||
@@ -775,7 +780,7 @@ public class GameManager extends PlaceManager
|
||||
|
||||
BodyObject bobj = CrowdServer.lookupBody(_gameobj.players[ii]);
|
||||
if (bobj == null) {
|
||||
Log.warning("Unable to deliver game ready to non-existent player [game=" + where() +
|
||||
log.warning("Unable to deliver game ready to non-existent player [game=" + where() +
|
||||
", player=" + _gameobj.players[ii] + "].");
|
||||
continue;
|
||||
}
|
||||
@@ -836,7 +841,7 @@ public class GameManager extends PlaceManager
|
||||
*/
|
||||
protected void placeBecameEmpty ()
|
||||
{
|
||||
// Log.info("Game room empty. Going away. [game=" + where() + "].");
|
||||
// log.info("Game room empty. Going away. [game=" + where() + "].");
|
||||
|
||||
// if we're in play then move to game over
|
||||
if (_gameobj.state != GameObject.PRE_GAME && _gameobj.state != GameObject.GAME_OVER &&
|
||||
@@ -878,7 +883,7 @@ public class GameManager extends PlaceManager
|
||||
|
||||
// if there's no one in the room, go ahead and clear it out
|
||||
if (_plobj.occupants.size() == 0) {
|
||||
Log.info("Cancelling total no-show [game=" + where() +
|
||||
log.info("Cancelling total no-show [game=" + where() +
|
||||
", players=" + StringUtil.toString(_gameobj.players) +
|
||||
", poids=" + StringUtil.toString(_playerOids) + "].");
|
||||
placeBecameEmpty();
|
||||
@@ -913,14 +918,14 @@ public class GameManager extends PlaceManager
|
||||
|
||||
if ((humansHere == 0) && !startWithoutHumans()) {
|
||||
// if there are no human players in the game, just cancel it
|
||||
Log.info("Canceling no-show game [game=" + where() +
|
||||
log.info("Canceling no-show game [game=" + where() +
|
||||
", players=" + StringUtil.toString(_playerOids) + "].");
|
||||
cancelGame();
|
||||
|
||||
} else {
|
||||
// go ahead and report that everyone is ready (which will start the game);
|
||||
// gameDidStart() will take care of giving the boot to anyone who isn't around
|
||||
Log.info("Forcing start of partial no-show game [game=" + where() +
|
||||
log.info("Forcing start of partial no-show game [game=" + where() +
|
||||
", poids=" + StringUtil.toString(_playerOids) + "].");
|
||||
playersAllHere();
|
||||
}
|
||||
@@ -1023,7 +1028,7 @@ public class GameManager extends PlaceManager
|
||||
// any players who have not claimed that they are ready should now be given le boote royale
|
||||
for (int ii = 0; ii < _playerOids.length; ii++) {
|
||||
if (_playerOids[ii] == -1) {
|
||||
Log.info("Booting no-show player [game=" + where() +
|
||||
log.info("Booting no-show player [game=" + where() +
|
||||
", player=" + getPlayerName(ii) + "].");
|
||||
_playerOids[ii] = 0; // unfiddle the blank oid
|
||||
endPlayerGame(ii);
|
||||
@@ -1234,8 +1239,7 @@ public class GameManager extends PlaceManager
|
||||
try {
|
||||
gmgr.tick(now);
|
||||
} catch (Exception e) {
|
||||
Log.warning("Game manager choked during tick [gmgr=" + gmgr + "].");
|
||||
Log.logStackTrace(e);
|
||||
log.log(Level.WARNING, "Game manager choked during tick [gmgr=" + gmgr + "].", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user