soc.server
Class SOCGameHandler

java.lang.Object
  extended by soc.server.GameHandler
      extended by soc.server.SOCGameHandler
All Implemented Interfaces:
SOCScenarioEventListener

public class SOCGameHandler
extends GameHandler
implements SOCScenarioEventListener

Server class to handle game-specific actions and messages for the SoC game type.

Before v2.0.00, these methods and fields were part of SOCServer. So, some may have @since javadoc labels with versions older than 2.0.00.

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

Field Summary
private static java.lang.String DEBUG_CMD_FREEPLACEMENT
          Used by SOC_DEBUG_COMMANDS_HELP, etc.
private static java.lang.String DEBUG_COMMANDS_HELP_DEV
          Used by SOC_DEBUG_COMMANDS_HELP, etc.
private static java.lang.String DEBUG_COMMANDS_HELP_DEV_TYPES
          Debug help: 1-line summary of dev card types, from SOCDevCardConstants.
private static java.lang.String DEBUG_COMMANDS_HELP_PLAYER
          Debug help: player name or number.
private static java.lang.String DEBUG_COMMANDS_HELP_RSRCS
          Used by SOC_DEBUG_COMMANDS_HELP, etc.
static int ROBOT_FORCE_ENDTURN_TRADEOFFER_SECONDS
          Force robot to end their turn after this much inactivity, while they've made a trade offer.
private static java.lang.String[] SOC_DEBUG_COMMANDS_HELP
          Debug help text to place at the end of SOCServer.DEBUG_COMMANDS_HELP via getDebugCommandsHelp().
 
Fields inherited from class soc.server.GameHandler
srv
 
Constructor Summary
SOCGameHandler(SOCServer server)
           
 
Method Summary
private  boolean checkTurn(StringConnection c, SOCGame ga)
          Make sure it's the player's turn.
private  SOCPlayer debug_getPlayer(StringConnection c, SOCGame ga, java.lang.String name)
          Given a player name or player number, find that player in the game.
private  void debugGiveDevCard(StringConnection c, java.lang.String mes, SOCGame game)
          this is a debugging command that gives a dev card to a player.
private  void debugGiveResources(StringConnection c, java.lang.String mes, SOCGame game)
          this is a debugging command that gives resources to a player.
private  void endGameTurn(SOCGame ga, SOCPlayer pl, boolean callEndTurn)
          Pre-checking already done, end the current player's turn in this game.
(package private)  boolean endGameTurnOrForce(SOCGame ga, int plNumber, java.lang.String plName, StringConnection plConn, boolean hasMonitorFromGameList)
          A bot is unresponsive, or a human player has left the game.
 void endTurnIfInactive(SOCGame ga, long currentTimeMillis)
          The server's timer thread thinks this game is inactive because of a robot bug.
private  boolean forceEndGameTurn(SOCGame ga, java.lang.String plName)
          Try to force-end the current player's turn in this game.
private  void forceGamePlayerDiscardOrGain(SOCGame cg, int cpn, StringConnection c, java.lang.String plName, int pn)
          Force this player (not current player) to discard, or gain random resources from a gold hex, and report resources to all players.
 void gameEvent(SOCGame ga, SOCScenarioGameEvent evt, java.lang.Object detail)
          Listener callback for scenario events on the large sea board which affect the game or board, not a specific player.
private  SOCMessage getBoardLayoutMessage(SOCGame ga)
          Put together the board layout message for this game.
 java.lang.String[] getDebugCommandsHelp()
          Get the debug commands for this game type, if any, used with GameHandler.processDebugCommand(StringConnection, String, String, String).
private  void handleACCEPTOFFER(SOCGame ga, StringConnection c, SOCAcceptOffer mes)
          handle "accept offer" message.
private  void handleBANKTRADE(SOCGame ga, StringConnection c, SOCBankTrade mes)
          handle "bank trade" message.
private  void handleBUILDREQUEST(SOCGame ga, StringConnection c, SOCBuildRequest mes)
          handle "build request" message.
private  void handleBUYCARDREQUEST(SOCGame ga, StringConnection c, SOCBuyCardRequest mes)
          handle "buy card request" message.
private  void handleCANCELBUILDREQUEST(SOCGame ga, StringConnection c, SOCCancelBuildRequest mes)
          handle "cancel build request" message.
private  void handleCHOOSEPLAYER(SOCGame ga, StringConnection c, SOCChoosePlayer mes)
          handle "choose player" message during robbery.
private  void handleCLEAROFFER(SOCGame ga, StringConnection c, SOCClearOffer mes)
          handle "clear offer" message.
private  void handleDEBUGFREEPLACE(SOCGame ga, StringConnection c, SOCDebugFreePlace mes)
          Handle the client's debug Free Placement putpiece request.
private  void handleDISCARD(SOCGame ga, StringConnection c, SOCDiscard mes)
          handle "discard" message.
private  void handleDISCOVERYPICK(SOCGame ga, StringConnection c, SOCDiscoveryPick mes)
          handle "discovery pick" message (while playing Discovery/Year of Plenty card).
private  void handleENDTURN(SOCGame ga, StringConnection c, SOCEndTurn mes)
          handle "end turn" message.
private  void handleINVENTORYITEMACTION(SOCGame ga, StringConnection c, SOCInventoryItemAction mes)
          Special inventory item action (play request) from a player.
private  void handleMAKEOFFER(SOCGame ga, StringConnection c, SOCMakeOffer mes)
          handle "make offer" message.
private  void handleMONOPOLYPICK(SOCGame ga, StringConnection c, SOCMonopolyPick mes)
          handle "monopoly pick" message.
private  void handleMOVEPIECEREQUEST(SOCGame ga, StringConnection c, SOCMovePieceRequest mes)
          Handle the client's "move piece request" message.
private  void handleMOVEROBBER(SOCGame ga, StringConnection c, SOCMoveRobber mes)
          handle "move robber" message (move the robber or the pirate).
private  void handlePICKRESOURCES(SOCGame ga, StringConnection c, SOCPickResources mes)
          Handle "pick resources" message (gold hex).
private  void handlePLAYDEVCARDREQUEST(SOCGame ga, StringConnection c, SOCPlayDevCardRequest mes)
          handle "play development card request" message.
private  void handlePUTPIECE(SOCGame ga, StringConnection c, SOCPutPiece mes)
          handle "put piece" message.
private  void handleREJECTOFFER(SOCGame ga, StringConnection c, SOCRejectOffer mes)
          handle "reject offer" message.
private  void handleROLLDICE(SOCGame ga, StringConnection c, SOCRollDice mes)
          handle "roll dice" message.
private  void handleSETSPECIALITEM(SOCGame ga, StringConnection c, SOCSetSpecialItem mes)
          Handle Special Item requests from a player.
private  void handleSIMPLEREQUEST(SOCGame ga, StringConnection c, SOCSimpleRequest mes)
          Handle the "simple request" message.
private  void joinGame_sendBoardSpecialEdgeChanges(SOCGame game, SOCBoardLarge board, StringConnection c)
          Client is joining this game, which uses SOCBoardLarge with SOCBoardLarge.hasSpecialEdges(); send any changes to special edges from the starting board layout.
 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.
 boolean leaveGame(SOCGame ga, StringConnection c)
          This member (player or observer) has left the game.
private  boolean playerEvent_newSettlementIsByShip(SOCGame ga, SOCSettlement se)
          For Special VP player events, check if a new settlement was apparently reached by land or sea.
 void playerEvent(SOCGame ga, SOCPlayer pl, SOCScenarioPlayerEvent evt, boolean flagsChanged, java.lang.Object obj)
          Listener callback for per-player scenario events on the large sea board.
 boolean processCommand(SOCGame ga, SOCMessageForGame mes, StringConnection c)
          Process one command from a client player of this game.
private  void processDebugCommand_freePlace(StringConnection c, java.lang.String gaName, java.lang.String arg)
          Process the *FREEPLACE* Free Placement debug command.
 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.
private  void reportBankTrade(SOCGame ga, SOCResourceSet give, SOCResourceSet get)
          report that the current player traded with the bank or a port, using SOCPlayerElement and SOCGameTextMsg messages.
private  void reportRobbery(SOCGame ga, SOCPlayer pe, SOCPlayer vi, int rsrc)
          The current player is stealing from another player.
private  void reportRsrcGainGold(SOCGame ga, SOCPlayer player, int pn, SOCResourceSet rsrcs, boolean includeGoldHexText)
          Report to game members what a player picked from the gold hex.
private  void reportRsrcGainLoss(java.lang.String gaName, SOCResourceSet rset, boolean isLoss, int mainPlayer, int tradingPlayer, java.lang.StringBuffer message, StringConnection playerConn)
          Report the resources gained/lost by a player, and optionally (for trading) lost/gained by a second player.
private  void reportTrade(SOCGame ga, int offering, int accepting)
          report a trade that has taken place between players, using SOCPlayerElement and SOCGameTextMsg messages.
private  void sendGamePendingMessages(SOCGame ga, boolean takeMon)
          Sends the contents of this game's SOCGame.pendingMessagesOut, then empties that list.
private  void sendGameState_sendGoldPickAnnounceText(SOCGame ga, java.lang.String gname, StringConnection playerCon, SOCGame.RollResult roll)
          Send a game text message "x, y, and z need to pick resources from the gold hex." and, for each picking player, a SOCPlayerElement(NUM_PICK_GOLD_HEX_RESOURCES).
private  void sendGameState(SOCGame ga)
          Send the current state of the game with a message.
private  boolean sendGameState(SOCGame ga, boolean sendRollPrompt)
          send the current state of the game with a message.
private  void sendGameStateOVER(SOCGame ga)
          If game is OVER, send messages reporting winner, final score, and each player's victory-point cards.
private  void sendTurn(SOCGame ga, boolean sendRollPrompt)
          send whose turn it is.
 void sitDown_sendPrivateInfo(SOCGame ga, StringConnection c, int pn)
          When player has just sat down at a seat, send them all the private information.
 void startGame(SOCGame ga)
          Do the things you need to do to start a game and send its data to the clients.
private static void updatePlayerSVPPendingMessage(SOCGame ga, SOCPlayer pl, int svp, java.lang.String descKey)
          A player has been awarded Special Victory Points (SVP), so send a SOCSVPTextMessage to the game about the SVP description, and also call SOCPlayer.addSpecialVPInfo(int, String).
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

ROBOT_FORCE_ENDTURN_TRADEOFFER_SECONDS

public static int ROBOT_FORCE_ENDTURN_TRADEOFFER_SECONDS
Force robot to end their turn after this much inactivity, while they've made a trade offer. Default is 60 seconds.

This field was originally in SOCServer, moved in v2.0.00.

Since:
1.1.11
See Also:
SOCServer.ROBOT_FORCE_ENDTURN_SECONDS, SOCServer.checkForExpiredTurns(long)

DEBUG_COMMANDS_HELP_RSRCS

private static final java.lang.String DEBUG_COMMANDS_HELP_RSRCS
Used by SOC_DEBUG_COMMANDS_HELP, etc.

See Also:
DEBUG_COMMANDS_HELP_PLAYER, Constant Field Values

DEBUG_COMMANDS_HELP_DEV

private static final java.lang.String DEBUG_COMMANDS_HELP_DEV
Used by SOC_DEBUG_COMMANDS_HELP, etc.

See Also:
DEBUG_COMMANDS_HELP_PLAYER, Constant Field Values

DEBUG_COMMANDS_HELP_PLAYER

private static final java.lang.String DEBUG_COMMANDS_HELP_PLAYER
Debug help: player name or number. Used by SOC_DEBUG_COMMANDS_HELP, etc.

Since:
1.1.20
See Also:
Constant Field Values

DEBUG_COMMANDS_HELP_DEV_TYPES

private static final java.lang.String DEBUG_COMMANDS_HELP_DEV_TYPES
Debug help: 1-line summary of dev card types, from SOCDevCardConstants.

Since:
1.1.17
See Also:
SOC_DEBUG_COMMANDS_HELP, Constant Field Values

DEBUG_CMD_FREEPLACEMENT

private static final java.lang.String DEBUG_CMD_FREEPLACEMENT
Used by SOC_DEBUG_COMMANDS_HELP, etc. Used with SOCGame.debugFreePlacement.

See Also:
Constant Field Values

SOC_DEBUG_COMMANDS_HELP

private static final java.lang.String[] SOC_DEBUG_COMMANDS_HELP
Debug help text to place at the end of SOCServer.DEBUG_COMMANDS_HELP via getDebugCommandsHelp().

Constructor Detail

SOCGameHandler

public SOCGameHandler(SOCServer server)
Method Detail

processCommand

public boolean processCommand(SOCGame ga,
                              SOCMessageForGame mes,
                              StringConnection c)
Description copied from class: GameHandler
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.

Specified by:
processCommand in class GameHandler
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 boolean processDebugCommand(StringConnection debugCli,
                                   java.lang.String gaName,
                                   java.lang.String dcmd,
                                   java.lang.String dcmdU)
Description copied from class: GameHandler
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).

Specified by:
processDebugCommand in class GameHandler
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:
GameHandler.getDebugCommandsHelp()

getDebugCommandsHelp

public final java.lang.String[] getDebugCommandsHelp()
Description copied from class: GameHandler
Get the debug commands for this game type, if any, used with GameHandler.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.

Specified by:
getDebugCommandsHelp in class GameHandler
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

processDebugCommand_freePlace

private final void processDebugCommand_freePlace(StringConnection c,
                                                 java.lang.String gaName,
                                                 java.lang.String arg)
Process the *FREEPLACE* Free Placement debug command. Can turn it off at any time, but can only turn it on during your own turn after rolling (during game state SOCGame.PLAY1).

Parameters:
c - Connection (client) sending this message
gaName - Game to which this applies
arg - 1 or 0, to turn on or off, or empty string or null to print current value
Since:
1.1.12

checkTurn

private final boolean checkTurn(StringConnection c,
                                SOCGame ga)
Make sure it's the player's turn.

Parameters:
c - the connection for player
ga - the game
Returns:
true if it is the player's turn; false if another player's turn, or if this player isn't in the game

endGameTurn

private void endGameTurn(SOCGame ga,
                         SOCPlayer pl,
                         boolean callEndTurn)
Pre-checking already done, end the current player's turn in this game. Alter game state and send messages to players. (Clear all the Ask Special Building, Reset Board Request, and Trade Offer flags; send Game State; send Turn).

Calls SOCGame.endTurn(), which may also end the game. On the 6-player board, this may begin the Special Building Phase, or end a player's placements during that phase. Otherwise, calls sendTurn(SOCGame, boolean) and begins the next player's turn.

Assumes:

As a special case, endTurn is used to begin the Special Building Phase during the start of a player's own turn, if permitted. (Added in 1.1.09)

A simplified version of this logic (during initial placement) is used in handlePUTPIECE(SOCGame, StringConnection, SOCPutPiece).

Parameters:
ga - Game to end turn
pl - Current player in ga, or null. Not needed except in SPECIAL_BUILDING. If null, will be determined within this method.
callEndTurn - Almost always true; if false, don't call SOCGame.endTurn() because it was called before calling this method. If false, be sure to set pl to the player whose turn it was before endTurn() was called.

forceEndGameTurn

private final boolean forceEndGameTurn(SOCGame ga,
                                       java.lang.String plName)
Try to force-end the current player's turn in this game. Alter game state and send messages to players. Will call endGameTurn(SOCGame, SOCPlayer, boolean) if appropriate. Will send gameState and current player (turn) to clients.

If the current player has lost connection, send the LEAVEGAME message out before calling this method.

Assumes, as endGameTurn(SOCGame, SOCPlayer, boolean) does:

Parameters:
ga - Game to force end turn
plName - Current player's name. Needed because if they have been disconnected by leaveGame(SOCGame, StringConnection), their name within game object is already null.
Returns:
true if the turn was ended and game is still active; false if we find that all players have left and the gamestate has been changed here to SOCGame.OVER.
See Also:
endGameTurnOrForce(SOCGame, int, String, StringConnection, boolean), SOCGame.forceEndTurn()

joinGame

public 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.

Does not add the client to the game's or server's list of players, that should be done before calling this method.

Assumes NEWGAME (or NEWGAMEWITHOPTIONS) has already been sent out. The game's first message* sent to the 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, some details are sent by calling sitDown_sendPrivateInfo(SOCGame, StringConnection, int). The group of messages sent here ends with GAMEMEMBERS, SETTURN and GAMESTATE. Then, the entire game is sent a JOINGAME for the new game member.

*I18N: If the game has a SOCScenario and the client needs scenario info or localized strings for the scenario name and description, SOCScenarioInfo or SOCLocalizedStrings is sent before JOINGAMEAUTH. This covers i18n and scenarios added or changed between the client's and server's version.

Specified by:
joinGame in class GameHandler
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 SOCGameHandler.
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, Map), SOCServer.createOrJoinGameIfUserOK(StringConnection, String, String, String, Map)

joinGame_sendBoardSpecialEdgeChanges

private final void joinGame_sendBoardSpecialEdgeChanges(SOCGame game,
                                                        SOCBoardLarge board,
                                                        StringConnection c)
Client is joining this game, which uses SOCBoardLarge with SOCBoardLarge.hasSpecialEdges(); send any changes to special edges from the starting board layout.

Compares the current SOCBoardLarge.getSpecialEdges() against each SOCBoardLarge.getAddedLayoutPart(String) which defines special edges (currently "CE", "VE").

Called as part of joinGame(SOCGame, StringConnection, boolean, boolean).

Parameters:
game - Game being joined
board - Game's board layout
c - Client joining

sitDown_sendPrivateInfo

public void sitDown_sendPrivateInfo(SOCGame ga,
                                    StringConnection c,
                                    int pn)
Description copied from class: GameHandler
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.

Specified by:
sitDown_sendPrivateInfo in class GameHandler
Parameters:
ga - the game
c - the connection for the player
pn - which seat the player is taking

leaveGame

public boolean leaveGame(SOCGame ga,
                         StringConnection c)
Description copied from class: GameHandler
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().

Specified by:
leaveGame in class GameHandler
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)

sendGameState

private void sendGameState(SOCGame ga)
Send the current state of the game with a message. Assumes current player does not change during this state. If we send a text message to prompt the new player to roll, also sends a RollDicePrompt data message.

For more details and references, see sendGameState(SOCGame, boolean). Be sure that callers to sendGameState don't assume the game will still exist after calling this method, if the game state was OVER.

Equivalent to: sendGameState(ga, true).

Parameters:
ga - the game

sendGameState

private boolean sendGameState(SOCGame ga,
                              boolean sendRollPrompt)
send the current state of the game with a message. Note that the current (or new) player number is not sent here. If game is now OVER, send appropriate messages.

State SOCGame.WAITING_FOR_DISCARDS: If a 7 is rolled, will also say who must discard (in a GAMETEXTMSG).

State SOCGame.WAITING_FOR_ROB_CHOOSE_PLAYER: If current player must choose which player to rob, will also prompt their client to choose (in a CHOOSEPLAYERREQUEST).

State SOCGame.STARTS_WAITING_FOR_PICK_GOLD_RESOURCE: To announce the player must pick a resource to gain from the gold hex initial placement, please call sendGameState_sendGoldPickAnnounceText(SOCGame, String, StringConnection, SOCGame.RollResult).

State SOCGame.WAITING_FOR_PICK_GOLD_RESOURCE: If a gold hex is rolled, does not say who must pick resources to gain (because of timing). Please call sendGameState_sendGoldPickAnnounceText(SOCGame, String, StringConnection, SOCGame.RollResult) after sending the resource gain text ("x gets 1 sheep").

Note: If game is now OVER and the SOCGame.isBotsOnly flag is set, sendGameStateOVER(SOCGame) will call SOCServer.destroyGameAndBroadcast(String, String). Be sure that callers to sendGameState don't assume the game will still exist after calling this method. Also, destroyGame might create more SOCGame.isBotsOnly games, depending on server settings.

Locks: Does not hold SOCGameList.takeMonitor() or SOCGameList.takeMonitorForGame(java.lang.String)(gaName) when called. Some callers call SOCGame.takeMonitor() before calling; not important here.

Parameters:
ga - the game
sendRollPrompt - If true, and if we send a text message to prompt the player to roll, send a RollDicePrompt data message. If the client is too old (1.0.6), it will ignore the prompt.
Returns:
did we send a text message to prompt the player to roll? If so, sendTurn can also send a RollDicePrompt data message.
See Also:
sendTurn(SOCGame, boolean), sendGameState(SOCGame), sendGameStateOVER(SOCGame)

sendGameState_sendGoldPickAnnounceText

private final void sendGameState_sendGoldPickAnnounceText(SOCGame ga,
                                                          java.lang.String gname,
                                                          StringConnection playerCon,
                                                          SOCGame.RollResult roll)
Send a game text message "x, y, and z need to pick resources from the gold hex." and, for each picking player, a SOCPlayerElement(NUM_PICK_GOLD_HEX_RESOURCES). To prompt the specific players to choose a resource, also sends their clients a SOCPickResourcesRequest. Used in game state SOCGame.STARTS_WAITING_FOR_PICK_GOLD_RESOURCE and SOCGame.WAITING_FOR_PICK_GOLD_RESOURCE.

The text and SOCPlayerElement messages are sent to the entire game. Any SOCPickResourcesRequests are sent to those player clients only. If you know that only 1 player will pick gold, pass their playerCon for efficiency.

This is separate from sendGameState(SOCGame) because when the dice are rolled, sendGameState is called, then resource distribution messages are sent out, then this method is called.

Parameters:
ga - Game object
gname - Game name
playerCon - null, or current player's client connection to send SOCPickResourcesRequest if they are the only one to pick gold. If more than 1 player has SOCPlayer.getNeedToPickGoldHexResources(), no message will be sent to playerCon.
roll - For gold gained from dice rolls, the roll details, otherwise null. In scenario SC_PIRI, is used to avoid announcing twice for a pick from victory against pirate fleet.
Since:
2.0.00

sendGameStateOVER

private void sendGameStateOVER(SOCGame ga)
If game is OVER, send messages reporting winner, final score, and each player's victory-point cards. Also give stats on game length, and on each player's connect time. If player has finished more than 1 game since connecting, send their win-loss count.

Increments server stats' numberOfGamesFinished. If db is active, calls SOCServer.storeGameScores(SOCGame) to save game stats.

If SOCGame.isBotsOnly, calls SOCServer.destroyGameAndBroadcast(String, String) to make room for more games to run: The bots don't know on their own to leave, it's easier for the server to dismiss them within destroyGame.

Make sure SOCGameState(OVER) is sent before calling this method.

Parameters:
ga - This game is over; state should be OVER

reportRobbery

private void reportRobbery(SOCGame ga,
                           SOCPlayer pe,
                           SOCPlayer vi,
                           int rsrc)
The current player is stealing from another player. Send messages saying what was stolen.

Parameters:
ga - the game
pe - the perpetrator
vi - the the victim
rsrc - type of resource stolen, as in SOCResourceConstants.SHEEP, or SOCResourceConstants.CLOTH_STOLEN_LOCAL for cloth (scenario option _SC_CLVI).

reportTrade

private void reportTrade(SOCGame ga,
                         int offering,
                         int accepting)
report a trade that has taken place between players, using SOCPlayerElement and SOCGameTextMsg messages. Trades are also reported to robots by re-sending the accepting player's SOCAcceptOffer message.

Parameters:
ga - the game
offering - the number of the player making the offer
accepting - the number of the player accepting the offer
See Also:
reportBankTrade(SOCGame, SOCResourceSet, SOCResourceSet)

reportBankTrade

private void reportBankTrade(SOCGame ga,
                             SOCResourceSet give,
                             SOCResourceSet get)
report that the current player traded with the bank or a port, using SOCPlayerElement and SOCGameTextMsg messages.

Parameters:
ga - the game
give - the number of the player making the offer
get - the number of the player accepting the offer
See Also:
reportTrade(SOCGame, int, int)

reportRsrcGainLoss

private void reportRsrcGainLoss(java.lang.String gaName,
                                SOCResourceSet rset,
                                boolean isLoss,
                                int mainPlayer,
                                int tradingPlayer,
                                java.lang.StringBuffer message,
                                StringConnection playerConn)
Report the resources gained/lost by a player, and optionally (for trading) lost/gained by a second player. Sends PLAYERELEMENT messages, either to entire game, or to player only. Builds the resource-amount string used to report the trade as text. Takes and releases the gameList monitor for this game.

Used to report the resources gained from a roll, discard, or discovery (year-of-plenty) pick. Also used to report the "give" or "get" half of a resource trade.

Parameters:
gaName - Game name
rset - Resource set (from a roll, or the "give" or "get" side of a trade). Resource type UNKNOWN or GOLD_LOCAL is ignored. Only positive resource amounts are sent (negative is ignored).
isLoss - If true, "give" (SOCPlayerElement.LOSE), otherwise "get" (SOCPlayerElement.GAIN)
mainPlayer - Player number "giving" if isLose==true, otherwise "getting". For each nonzero resource involved, PLAYERELEMENT messages will be sent about this player.
tradingPlayer - Player number on other side of trade, or -1 if no second player is involved. If not -1, PLAYERELEMENT messages will also be sent about this player.
message - Append resource numbers/types to this stringbuffer, format like "3 clay,3 wood"; can be null.
playerConn - Null to announce to the entire game, or mainPlayer's connection to send messages there instead of sending to all players in game. Because trades are public, there is no such parameter for tradingPlayer.
See Also:
reportTrade(SOCGame, int, int), reportBankTrade(SOCGame, SOCResourceSet, SOCResourceSet), reportRsrcGainGold(SOCGame, SOCPlayer, int, SOCResourceSet, boolean), handleDISCARD(SOCGame, StringConnection, SOCDiscard), handleDISCOVERYPICK(SOCGame, StringConnection, SOCDiscoveryPick), handleROLLDICE(SOCGame, StringConnection, SOCRollDice)

reportRsrcGainGold

private void reportRsrcGainGold(SOCGame ga,
                                SOCPlayer player,
                                int pn,
                                SOCResourceSet rsrcs,
                                boolean includeGoldHexText)
Report to game members what a player picked from the gold hex. Sends SOCPlayerElement for resources and to reset the SOCPlayerElement.NUM_PICK_GOLD_HEX_RESOURCES counter. Sends text "playername has picked ___ from the gold hex.".

Parameters:
ga - Game with gaining player
player - Player gaining
pn - player.getPlayerNumber()
rsrcs - Resources picked
includeGoldHexText - If true, text ends with "from the gold hex." after the resource name.
Since:
2.0.00

startGame

public 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.

If SOCGame.hasSeaBoard: Once the board is made, send the updated potential settlements.

Specified by:
startGame in class GameHandler
Parameters:
ga - the game

sendTurn

private void sendTurn(SOCGame ga,
                      boolean sendRollPrompt)
send whose turn it is. Optionally also send a prompt to roll. If the client is too old (1.0.6), it will ignore the prompt.

sendTurn should be called whenever the current player changes, including during and after initial placement.

Parameters:
ga - the game
sendRollPrompt - whether to send a RollDicePrompt message afterwards

getBoardLayoutMessage

private SOCMessage getBoardLayoutMessage(SOCGame ga)
                                  throws java.lang.IllegalArgumentException
Put together the board layout message for this game. Message type will be SOCBoardLayout or SOCBoardLayout2, depending on ga.getBoard().getBoardEncodingFormat() and SOCGame.getClientVersionMinRequired().

Parameters:
ga - the game
Returns:
a board layout message
Throws:
java.lang.IllegalArgumentException - if game board's encoding is unrecognized

handlePUTPIECE

private void handlePUTPIECE(SOCGame ga,
                            StringConnection c,
                            SOCPutPiece mes)
handle "put piece" message.

Because the current player changes during initial placement, this method has a simplified version of some of the logic from endGameTurn(SOCGame, SOCPlayer, boolean) to detect and announce the new turn.

Parameters:
c - the connection that sent the message
mes - the message

handleMOVEROBBER

private void handleMOVEROBBER(SOCGame ga,
                              StringConnection c,
                              SOCMoveRobber mes)
handle "move robber" message (move the robber or the pirate).

Parameters:
c - the connection that sent the message
mes - the message

handleROLLDICE

private void handleROLLDICE(SOCGame ga,
                            StringConnection c,
                            SOCRollDice mes)
handle "roll dice" message.

Parameters:
c - the connection that sent the message
mes - the message

handleDISCARD

private void handleDISCARD(SOCGame ga,
                           StringConnection c,
                           SOCDiscard mes)
handle "discard" message.

Parameters:
c - the connection that sent the message
mes - the message

handlePICKRESOURCES

private final void handlePICKRESOURCES(SOCGame ga,
                                       StringConnection c,
                                       SOCPickResources mes)
Handle "pick resources" message (gold hex). Game state SOCGame.WAITING_FOR_PICK_GOLD_RESOURCE, or rarely SOCGame.STARTS_WAITING_FOR_PICK_GOLD_RESOURCE. Also used with _SC_PIRI after winning a pirate fleet battle at dice roll.

Parameters:
c - the connection that sent the message
mes - the message
Since:
2.0.00

handleSETSPECIALITEM

private final void handleSETSPECIALITEM(SOCGame ga,
                                        StringConnection c,
                                        SOCSetSpecialItem mes)
Handle Special Item requests from a player. Calls SOCSpecialItem.playerPickItem(String, SOCGame, SOCPlayer, int, int) or SOCSpecialItem.playerSetItem(String, SOCGame, SOCPlayer, int, int, boolean) which provide scenario-specific responses or decline the request.

Parameters:
c - the connection that sent the message
mes - the message
Since:
2.0.00

handleENDTURN

private void handleENDTURN(SOCGame ga,
                           StringConnection c,
                           SOCEndTurn mes)
handle "end turn" message. This normally ends a player's normal turn (phase SOCGame.PLAY1). On the 6-player board, it ends their placements during the Special Building Phase.

Parameters:
c - the connection that sent the message
mes - the message

handleCHOOSEPLAYER

private void handleCHOOSEPLAYER(SOCGame ga,
                                StringConnection c,
                                SOCChoosePlayer mes)
handle "choose player" message during robbery.

Parameters:
c - the connection that sent the message
mes - the message

handleMAKEOFFER

private void handleMAKEOFFER(SOCGame ga,
                             StringConnection c,
                             SOCMakeOffer mes)
handle "make offer" message.

Parameters:
c - the connection that sent the message
mes - the message

handleCLEAROFFER

private void handleCLEAROFFER(SOCGame ga,
                              StringConnection c,
                              SOCClearOffer mes)
handle "clear offer" message.

Parameters:
c - the connection that sent the message
mes - the message

handleREJECTOFFER

private void handleREJECTOFFER(SOCGame ga,
                               StringConnection c,
                               SOCRejectOffer mes)
handle "reject offer" message.

Parameters:
c - the connection that sent the message
mes - the message

handleACCEPTOFFER

private void handleACCEPTOFFER(SOCGame ga,
                               StringConnection c,
                               SOCAcceptOffer mes)
handle "accept offer" message.

Parameters:
c - the connection that sent the message
mes - the message

handleBANKTRADE

private void handleBANKTRADE(SOCGame ga,
                             StringConnection c,
                             SOCBankTrade mes)
handle "bank trade" message.

Parameters:
c - the connection that sent the message
mes - the message

handleBUILDREQUEST

private void handleBUILDREQUEST(SOCGame ga,
                                StringConnection c,
                                SOCBuildRequest mes)
handle "build request" message. If client is current player, they want to buy a SOCPlayingPiece. Otherwise, if 6-player board, they want to build during the Special Building Phase.

Parameters:
c - the connection that sent the message
mes - the message

handleCANCELBUILDREQUEST

private void handleCANCELBUILDREQUEST(SOCGame ga,
                                      StringConnection c,
                                      SOCCancelBuildRequest mes)
handle "cancel build request" message. Cancel placement and send new game state, if cancel is allowed.

Parameters:
c - the connection that sent the message
mes - the message

handleBUYCARDREQUEST

private void handleBUYCARDREQUEST(SOCGame ga,
                                  StringConnection c,
                                  SOCBuyCardRequest mes)
handle "buy card request" message.

Parameters:
c - the connection that sent the message
mes - the message

handlePLAYDEVCARDREQUEST

private void handlePLAYDEVCARDREQUEST(SOCGame ga,
                                      StringConnection c,
                                      SOCPlayDevCardRequest mes)
handle "play development card request" message.

Parameters:
c - the connection that sent the message
mes - the message

handleDISCOVERYPICK

private void handleDISCOVERYPICK(SOCGame ga,
                                 StringConnection c,
                                 SOCDiscoveryPick mes)
handle "discovery pick" message (while playing Discovery/Year of Plenty card).

Parameters:
c - the connection that sent the message
mes - the message

handleMONOPOLYPICK

private void handleMONOPOLYPICK(SOCGame ga,
                                StringConnection c,
                                SOCMonopolyPick mes)
handle "monopoly pick" message.

Parameters:
c - the connection that sent the message
mes - the message

handleSIMPLEREQUEST

private void handleSIMPLEREQUEST(SOCGame ga,
                                 StringConnection c,
                                 SOCSimpleRequest mes)
Handle the "simple request" message.

Parameters:
c - the connection
mes - the message
Since:
1.1.18

handleINVENTORYITEMACTION

private void handleINVENTORYITEMACTION(SOCGame ga,
                                       StringConnection c,
                                       SOCInventoryItemAction mes)
Special inventory item action (play request) from a player. Ignored unless mes.action == PLAY. Calls SOCGame.canPlayInventoryItem(int, int), SOCGame.playInventoryItem(int). If game state changes here, calls sendGameState(SOCGame) just before returning.

Parameters:
ga - game with c as a client player
c - the connection sending the message
mes - the message
Since:
2.0.00

handleDEBUGFREEPLACE

private final void handleDEBUGFREEPLACE(SOCGame ga,
                                        StringConnection c,
                                        SOCDebugFreePlace mes)
Handle the client's debug Free Placement putpiece request.

Since:
1.1.12

handleMOVEPIECEREQUEST

private final void handleMOVEPIECEREQUEST(SOCGame ga,
                                          StringConnection c,
                                          SOCMovePieceRequest mes)
Handle the client's "move piece request" message.

Since:
2.0.00

debugGiveResources

private final void debugGiveResources(StringConnection c,
                                      java.lang.String mes,
                                      SOCGame game)
this is a debugging command that gives resources to a player. Format: rsrcs: #cl #or #sh #wh #wo playername


debugGiveDevCard

private final void debugGiveDevCard(StringConnection c,
                                    java.lang.String mes,
                                    SOCGame game)
this is a debugging command that gives a dev card to a player.
 dev: cardtype player 
For card-types numbers, see SOCDevCardConstants or DEBUG_COMMANDS_HELP_DEV_TYPES.


debug_getPlayer

private SOCPlayer debug_getPlayer(StringConnection c,
                                  SOCGame ga,
                                  java.lang.String name)
Given a player name or player number, find that player in the game. If not found by name, or player number doesn't match expected format, sends a message to the requesting user.

Parameters:
c - Connection of requesting debug user
ga - Game to find player
name - Player name, or player position number in format "#3" numbered 0 to ga.maxPlayers-1 inclusive
Returns:
SOCPlayer with this name or number, or null if an error was sent to the user
Since:
1.1.20

endTurnIfInactive

public void endTurnIfInactive(SOCGame ga,
                              long currentTimeMillis)
Description copied from class: GameHandler
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.

Specified by:
endTurnIfInactive in class GameHandler
Parameters:
ga - Game to check
currentTimeMillis - The time when called, from System.currentTimeMillis()

endGameTurnOrForce

boolean endGameTurnOrForce(SOCGame ga,
                           int plNumber,
                           java.lang.String plName,
                           StringConnection plConn,
                           boolean hasMonitorFromGameList)
A bot is unresponsive, or a human player has left the game. End this player's turn cleanly, or force-end if needed.

Can be called for a player still in the game, or for a player who has left (SOCGame.removePlayer(String) has been called). Can be called for a player who isn't current player; in that case it takes action if the game was waiting for the player (picking random resources for discard or gold-hex picks) but won't end the current turn.

If they were placing an initial road, also cancels that road's initial settlement.

Locks: Must not have ga.takeMonitor() when calling this method. May or may not have gameList.takeMonitorForGame(ga); use hasMonitorFromGameList to indicate.

Not public, but package visibility, for use by SOCForceEndTurnThread for SOCGameTimeoutChecker.

Parameters:
ga - The game to end turn if called for current player, or to otherwise stop waiting for a player
plNumber - player.getNumber; may or may not be current player
plName - player.getName
plConn - player's client connection
hasMonitorFromGameList - if false, have not yet called gameList.takeMonitorForGame(ga); if false, this method will take this monitor at its start, and release it before returning.
Returns:
true if the turn was ended and game is still active; false if we find that all players have left and the gamestate has been changed here to OVER.

forceGamePlayerDiscardOrGain

private final void forceGamePlayerDiscardOrGain(SOCGame cg,
                                                int cpn,
                                                StringConnection c,
                                                java.lang.String plName,
                                                int pn)
                                         throws java.lang.IllegalStateException
Force this player (not current player) to discard, or gain random resources from a gold hex, and report resources to all players. Does not send gameState, which may have changed; see SOCGame.discardOrGainPickRandom(SOCResourceSet, int, boolean, SOCResourceSet, Random)

Discards if cg.getGameState() == SOCGame.WAITING_FOR_DISCARDS, otherwise picks enough random resources for SOCPlayer.getNeedToPickGoldHexResources().

Assumes, as endGameTurn(SOCGame, SOCPlayer, boolean) does:

Parameters:
cg - Game object
cpn - Game's current player number
c - Connection of discarding/gaining player
plName - Discarding/gaining player pn's name, for GameTextMsg
pn - Player number who must discard/gain resources
Throws:
java.lang.IllegalStateException - if pn is current player, or if incorrect game state or incorrect player status; see SOCGame.playerDiscardOrGainRandom(int, boolean) for details

gameEvent

public void gameEvent(SOCGame ga,
                      SOCScenarioGameEvent evt,
                      java.lang.Object detail)
Listener callback for scenario events on the large sea board which affect the game or board, not a specific player. For example, a hex might be revealed from fog.

Threads: The game's treater thread handles incoming client messages and calls game methods that change state. Those same game methods will trigger the scenario events; so, the treater thread will also run this gameEvent callback.

Specified by:
gameEvent in interface SOCScenarioEventListener
Parameters:
ga - Game
evt - Event code
detail - Game piece, coordinate, or other data about the event, or null, depending on evt
Since:
2.0.00
See Also:
playerEvent(SOCGame, SOCPlayer, SOCScenarioPlayerEvent, boolean, Object)

playerEvent

public void playerEvent(SOCGame ga,
                        SOCPlayer pl,
                        SOCScenarioPlayerEvent evt,
                        boolean flagsChanged,
                        java.lang.Object obj)
Listener callback for per-player scenario events on the large sea board. For example, there might be an SVP awarded for settlements. Server sends messages to the game to announce it (PLAYERELEMENT, updatePlayerSVPPendingMessage(SOCGame, SOCPlayer, int, String), etc).

Threads: The game's treater thread handles incoming client messages and calls game methods that change state. Those same game methods will trigger the scenario events; so, the treater thread will also run this playerEvent callback.

Specified by:
playerEvent in interface SOCScenarioEventListener
Parameters:
ga - Game
pl - Player
evt - Event code
flagsChanged - True if this event changed SOCPlayer.getScenarioPlayerEvents(), SOCPlayer.getSpecialVP(), or another flag documented for evt in SOCScenarioPlayerEvent
obj - Object related to the event, or null; documented for evt in SOCScenarioPlayerEvent. Example: The SOCVillage for SOCScenarioPlayerEvent.CLOTH_TRADE_ESTABLISHED_VILLAGE.
Since:
2.0.00
See Also:
gameEvent(SOCGame, SOCScenarioGameEvent, Object)

playerEvent_newSettlementIsByShip

private final boolean playerEvent_newSettlementIsByShip(SOCGame ga,
                                                        SOCSettlement se)
For Special VP player events, check if a new settlement was apparently reached by land or sea. Most new LandAreas are on other islands, but a few (SC_TTD) are on the main island.

Parameters:
ga - Game with this new settlement
se - Newly placed settlement to check, passed to playerEvent(SOCGame, SOCPlayer, SOCScenarioPlayerEvent, boolean, Object)
Returns:
Does the new settlement have more adjacent ships than roads?
Since:
2.0.00

updatePlayerSVPPendingMessage

private static void updatePlayerSVPPendingMessage(SOCGame ga,
                                                  SOCPlayer pl,
                                                  int svp,
                                                  java.lang.String descKey)
A player has been awarded Special Victory Points (SVP), so send a SOCSVPTextMessage to the game about the SVP description, and also call SOCPlayer.addSpecialVPInfo(int, String). Should be called before SOCPlayerElement(SCENARIO_SVP), not after.

Adds the message to SOCGame.pendingMessagesOut; note that right now, that field is checked only in handlePUTPIECE(SOCGame, StringConnection, SOCPutPiece) and handleMOVEPIECEREQUEST(SOCGame, StringConnection, SOCMovePieceRequest), because no other method currently awards SVP.

Parameters:
ga - Game
pl - Player
svp - Number of SVP
descKey - String key for description of the player's action that led to SVP
Since:
2.0.00
See Also:
sendGamePendingMessages(SOCGame, boolean)

sendGamePendingMessages

private void sendGamePendingMessages(SOCGame ga,
                                     boolean takeMon)
Sends the contents of this game's SOCGame.pendingMessagesOut, then empties that list. To avoid unnecessary work here, check if the list is empty before calling this method.

I18N: Checks pendingMessagesOut for SOCKeyedMessages and handles them accordingly. Currently this is the only method that checks for those, because other places send text messages immediately instead of queueing them and localizing/sending later.

Locks: If takeMon is true, takes and releases gameList.takeMonitorForGame(gameName). Otherwise call gameList.takeMonitorForGame(gameName) before calling this method.

Parameters:
ga - game with pending messages
takeMon - Should this method take and release game's monitor via gameList.takeMonitorForGame(gameName)? True unless caller already holds that monitor.
Since:
2.0.00
See Also:
updatePlayerSVPPendingMessage(SOCGame, SOCPlayer, int, String)