soc.server
Class GameHandler

java.lang.Object
  extended by soc.server.GameHandler
Direct Known Subclasses:
SOCGameHandler

public abstract class GameHandler
extends java.lang.Object

Server class to handle game-specific actions and messages for a type of game.

Currently, these concepts are common to all hosted game types:

Interface and interaction:

Since:
2.0.00
Author:
Jeremy D Monin <jeremy@nand.net>

Field Summary
protected  SOCServer srv
           
 
Constructor Summary
protected GameHandler(SOCServer server)
           
 
Method Summary
abstract  void endTurnIfInactive(SOCGame ga, long currentTimeMillis)
          The server's timer thread thinks this game is inactive because of a robot bug.
abstract  java.lang.String[] getDebugCommandsHelp()
          Get the debug commands for this game type, if any, used with processDebugCommand(StringConnection, String, String, String).
abstract  void joinGame(SOCGame gameData, StringConnection c, boolean isReset, boolean isTakingOver)
          Client has been approved to join game; send the entire state of the game to client.
abstract  boolean leaveGame(SOCGame ga, StringConnection c)
          This member (player or observer) has left the game.
abstract  boolean processCommand(SOCGame ga, SOCMessageForGame mes, StringConnection c)
          Process one command from a client player of this game.
abstract  boolean processDebugCommand(StringConnection debugCli, java.lang.String gaName, java.lang.String dcmd, java.lang.String dcmdU)
          Look for a potential debug command in a text message sent by the "debug" client/player.
abstract  void sitDown_sendPrivateInfo(SOCGame ga, StringConnection c, int pn)
          When player has just sat down at a seat, send them all the private information.
abstract  void startGame(SOCGame ga)
          Do the things you need to do to start a game and send its data to the clients.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

srv

protected final SOCServer srv
Constructor Detail

GameHandler

protected GameHandler(SOCServer server)
Method Detail

processCommand

public abstract boolean processCommand(SOCGame ga,
                                       SOCMessageForGame mes,
                                       StringConnection c)
Process one command from a client player of this game.

Some game messages (such as player sits down, or board reset voting) are handled the same for all game types. These are handled at SOCServer; they should be ignored here and not appear in your switch statement.

Called from SOCServer message treater loop. Caller will catch any thrown Exceptions.

Parameters:
ga - Game in which client c is sending msg. Never null; from SOCMessageForGame.getGame().
mes - Message from client c. Never null.
c - Client sending msg. Never null.
Returns:
true if processed, false if ignored or unknown message type

processDebugCommand

public abstract boolean processDebugCommand(StringConnection debugCli,
                                            java.lang.String gaName,
                                            java.lang.String dcmd,
                                            java.lang.String dcmdU)
Look for a potential debug command in a text message sent by the "debug" client/player. If game debug is on, called for every game text message (chat message) received from that player.

Server-wide debug commands are processed before gametype-specific debug commands; see SOCServer.processDebugCommand(StringConnection, String, String, String).

Parameters:
debugCli - Client sending the potential debug command
gaName - Game in which the message is sent
dcmd - Text message which may be a debug command
dcmdU - dcmd as uppercase, for efficiency (it's already been uppercased in caller)
Returns:
true if dcmd is a recognized debug command, false otherwise
See Also:
getDebugCommandsHelp()

getDebugCommandsHelp

public abstract java.lang.String[] getDebugCommandsHelp()
Get the debug commands for this game type, if any, used with processDebugCommand(StringConnection, String, String, String). If client types the *help* debug command, the server will send them all the general debug command help, and these strings.

Returns:
a set of lines of help text to send to a client after sending SOCServer.DEBUG_COMMANDS_HELP, or null if no gametype-specific debug commands

joinGame

public abstract void joinGame(SOCGame gameData,
                              StringConnection c,
                              boolean isReset,
                              boolean isTakingOver)
Client has been approved to join game; send the entire state of the game to client. Unless isTakingOver, send client join event to other players. Assumes NEWGAME (or NEWGAMEWITHOPTIONS) has already been sent out. First message sent to connecting client is JOINGAMEAUTH, unless isReset.

Among other messages, player names are sent via SITDOWN, and pieces on board sent by PUTPIECE. See comments here for further details. If isTakingOver, assume the game already started and send any details about pieces, number of items, cards in hand, etc. The group of messages sent here ends with GAMEMEMBERS, SETTURN and GAMESTATE.

Parameters:
gameData - Game to join
c - The connection of joining client
isReset - Game is a board-reset of an existing game. This is always false when called from SOCServer instead of from inside the GameHandler. Not all game types may be reset.
isTakingOver - Client is re-joining; this connection replaces an earlier one which is defunct because of a network problem. If isTakingOver, don't send anything to other players.
See Also:
SOCServer.connectToGame(StringConnection, String, java.util.Map), SOCServer.createOrJoinGameIfUserOK(StringConnection, String, String, String, java.util.Map)

sitDown_sendPrivateInfo

public abstract void sitDown_sendPrivateInfo(SOCGame ga,
                                             StringConnection c,
                                             int pn)
When player has just sat down at a seat, send them all the private information. Cards in their hand, resource counts, anything else that isn't public to all players. Because they've just sat and become an active player, send the gameState, and prompt them if the game is waiting on any decision by their player number (discard, pick a free resource, etc).

Called from SOCServer.sitDown(SOCGame, StringConnection, int, boolean, boolean).

Locks: Assumes ga.takeMonitor() is held, and should remain held.

Parameters:
ga - the game
c - the connection for the player
pn - which seat the player is taking
Since:
1.1.08

startGame

public abstract void startGame(SOCGame ga)
Do the things you need to do to start a game and send its data to the clients. Players are already seated when this method is called.

Send all game members the piece counts, other public information for the game and each player, set up and send the board layout, game state, and finally send the STARTGAME and TURN messages.

Set game state to SOCGame.READY or higher, from an earlier/lower state.

Parameters:
ga - the game

endTurnIfInactive

public abstract void endTurnIfInactive(SOCGame ga,
                                       long currentTimeMillis)
The server's timer thread thinks this game is inactive because of a robot bug. Check the game. If this is the case, end the current turn, forcing if necessary. Use a separate thread so the main timer thread isn't tied up; see SOCForceEndTurnThread.

The server checks SOCGame.lastActionTime to decide inaction. The game could also seem inactive if we're waiting for another human player to decide something. Games with state >= SOCGame.OVER, and games which haven't started yet (SOCGame.getCurrentPlayerNumber() == -1), are ignored.

The default timeout is SOCServer.ROBOT_FORCE_ENDTURN_SECONDS. You may calculate and use a longer timeout if it makes sense in the current conditions, such as waiting for a human player to ignore or respond to a trade offer.

Parameters:
ga - Game to check
currentTimeMillis - The time when called, from System.currentTimeMillis()

leaveGame

public abstract boolean leaveGame(SOCGame ga,
                                  StringConnection c)
This member (player or observer) has left the game. Check the game and clean up, forcing end of current turn if necessary. Call SOCGame.removePlayer(String). If the game still has other players, continue it, otherwise it will be ended after returning from leaveGame. Send messages out to other game members.

Locks: Has gameList.takeMonitorForGame(gm) when calling this method; does not have SOCGame.takeMonitor().

Parameters:
ga - The game
c - The member connection which left. The server has already removed c from the list of game members. If c is being dropped because of an error, StringConnection.disconnect() has already been called. Don't exclude c from any communication about leaving the game, in case they are still connected and in other games.
Returns:
true if the game should be ended and deleted (does not have other observers or non-robot players, and game's isBotsOnly flag is false)