Class Server

java.lang.Object
java.lang.Thread
net.sf.colossus.server.Server
All Implemented Interfaces:
Runnable, IServer

public final class Server extends Thread implements IServer
Class Server lives on the server side and handles all communcation with the clients. It talks to the server classes locally, and to the Clients via the network protocol.
Author:
David Ripton
  • Field Details

    • LOGGER

      private static final Logger LOGGER
    • startLog

      private static StartupProgress startLog
    • game

      private GameServerSide game
    • whatNextManager

      private final WhatNextManager whatNextManager
    • recorder

      private final MessageRecorder recorder
    • clientStub

      private ClientHandlerStub clientStub
    • iClients

      private final List<IClient> iClients
      Recipients for everything send to "each client" - including the stub
    • realClients

      private final List<ClientHandler> realClients
      Only real ClientHandlers (excluding the stub)
    • remoteClients

      private final List<IClient> remoteClients
    • remoteLogHandlers

      private final List<RemoteLogHandler> remoteLogHandlers
    • playerToClientMap

      private final Map<Player,IClient> playerToClientMap
      Map of players to their clients.
    • activeSocketChannelList

      private final List<SocketChannel> activeSocketChannelList
      List of SocketChannels that are currently active
    • forcedWithdraws

      private final Map<String,Server.WithdrawInfo> forcedWithdraws
      ClientHandlers to be withdrawn, together with some related (timing) data; selector thread will do it then when it's the right time for it
    • waitingForClients

      private int waitingForClients
      Number of player clients we're waiting for to *connect*
    • waitingForPlayersToJoin

      private int waitingForPlayersToJoin
      Number of player clients we're waiting for to *join* - when last one has joined, then kick of newGame2() or loadGame2()
    • wfptjSemaphor

      private final Object wfptjSemaphor
      Semaphor for synchronized access to waitingForPlayersToJoin
    • sendPingRequests

      private boolean sendPingRequests
      Will be set to true after all clients are properly connected
    • spectators

      private int spectators
    • port

      private final int port
      Server socket port.
    • striker

      private CreatureServerSide striker
    • target

      private CreatureServerSide target
    • strikeNumber

      private int strikeNumber
    • rolls

      private List<String> rolls
    • serverSocket

      private ServerSocket serverSocket
    • selector

      private Selector selector
    • acceptKey

      private SelectionKey acceptKey
    • stopAcceptingFlag

      private boolean stopAcceptingFlag
    • guiRequestMutex

      private final Object guiRequestMutex
    • guiRequestSaveFlag

      private boolean guiRequestSaveFlag
    • guiRequestSaveFilename

      private String guiRequestSaveFilename
    • inPauseState

      private boolean inPauseState
    • fileServerThread

      private static Thread fileServerThread
    • serverRunning

      private boolean serverRunning
    • obsolete

      private boolean obsolete
    • shuttingDown

      private boolean shuttingDown
    • forceShutDown

      private boolean forceShutDown
    • initiateDisposal

      private boolean initiateDisposal
    • caughtUpAction

      private String caughtUpAction
    • timeoutDuringStart

      private final int timeoutDuringStart
      See Also:
    • timeoutDuringGame

      private final int timeoutDuringGame
      See Also:
    • timeoutDuringShutdown

      private final int timeoutDuringShutdown
      See Also:
    • WEBGAMES_STARTUP_TIMEOUT_SECS

      private static final int WEBGAMES_STARTUP_TIMEOUT_SECS
      How long in public server games socket shall wait for Clients.
      See Also:
    • PING_REQUEST_INTERVAL_SEC

      private final int PING_REQUEST_INTERVAL_SEC
      See Also:
    • lastPingRound

      private long lastPingRound
      How many ms ago last ping round was done.
    • startInititatedTime

      private long startInititatedTime
      When server started to listed for clients
    • gameStartupTimeoutSecs

      private int gameStartupTimeoutSecs
      Timeout how long server waits for clients before giving up; in normal/local games 0, meaning forever; in public server usage set to WEBGAMES_STARTUP_TIMEOUT_SECS
    • disposeAllClientsDoneMutex

      private final Object disposeAllClientsDoneMutex
    • disposeAllClientsDone

      private boolean disposeAllClientsDone
    • byteBuffer

      private final ByteBuffer byteBuffer
    • processingCH

      ClientHandler processingCH
    • overriddenCH

      ClientHandler overriddenCH
    • channelChanges

      private final List<ClientHandlerStub> channelChanges
    • waitUntilOverMutex

      private final Object waitUntilOverMutex
    • waitingToCatchup

      private final HashSet<IClient> waitingToCatchup
  • Constructor Details

  • Method Details

    • run

      public void run()
      Specified by:
      run in interface Runnable
      Overrides:
      run in class Thread
    • initFileServer

      void initFileServer()
    • startFileServerIfNotRunning

      void startFileServerIfNotRunning()
    • isKnownClient

      public boolean isKnownClient(InetAddress requester)
    • initSocketServer

      void initSocketServer()
    • waitForClients

      boolean waitForClients()
    • createClientHandlerStub

      public void createClientHandlerStub()
    • overrideProcessingCH

      public void overrideProcessingCH(Player player)
    • restoreProcessingCH

      public void restoreProcessingCH()
    • waitOnSelector

      public void waitOnSelector(int timeout, boolean stillWaitingForClients)
    • handleForcedWithdraws

      private void handleForcedWithdraws()
    • handleOutsideChanges

      private void handleOutsideChanges(boolean wasTimeout, boolean stillWaitingForClients)
    • handleSelectedKeys

      private void handleSelectedKeys() throws IOException, ClosedChannelException
      Throws:
      IOException
      ClosedChannelException
    • handleChannelChanges

      private void handleChannelChanges() throws IOException
      Throws:
      IOException
    • externShutdown

      public void externShutdown()
      Shutdown initiated by outside, i.e. NOT by the Server thread itself. Right now, this is used by StartupProgressDialog's abort button.
    • stopAccepting

      private void stopAccepting() throws IOException
      Throws:
      IOException
    • closeSocketAndSelector

      private void closeSocketAndSelector()
      Close serverSocket and selector, if needed
    • handleReadFromChannel

      private int handleReadFromChannel(SelectionKey key, SocketChannel sc) throws IOException
      Throws:
      IOException
    • processByteBuffer

      private void processByteBuffer()
    • withdrawFromGameIfRelevant

      private void withdrawFromGameIfRelevant(Exception gotException, boolean didDisconnect)
      Something with the connection of "processingCH" which makes perhaps Withdraw necessary. If client seems to support reconnect, mark CH to be temp. disconnected, otherwise take care of the proper withdrawal.
      Parameters:
      gotException - An exception, if calling this was caused by an (IO)Exception, otherwise null, i.e. it was triggered by EOF.
      didDisconnect - whether an explicit dicsonnect request message had been received already from that client ( = no point to wait for reconnect attempt).
    • triggerWithdrawIfDoesNotReconnect

      private void triggerWithdrawIfDoesNotReconnect(long intervalLen, int intervals)
    • queueClientHandlerForChannelChanges

      void queueClientHandlerForChannelChanges(ClientHandlerStub ch)
      Put the ClientHandler into the queue to be removed from selector on next possible opportunity
    • notifyThatGameFinished

      public void notifyThatGameFinished()
    • waitUntilGameFinishes

      public void waitUntilGameFinishes()
    • stopServerRunning

      public void stopServerRunning()
    • isServerRunning

      public boolean isServerRunning()
    • stopFileServer

      public void stopFileServer()
    • disconnectChannel

      private void disconnectChannel(SocketChannel sc, SelectionKey key) throws IOException
      Close the SocketChannel, cancel the selection key and unregister the SocketChannel from list of active SocketChannels.
      Parameters:
      sc - SocketChannel of the client
      key - Key for that SocketChannel
      Throws:
      IOException
    • unregisterSocketChannel

      public void unregisterSocketChannel(SocketChannel socketChannel)
    • setBoardVisibility

      public void setBoardVisibility(Player player, boolean val)
    • isClientGone

      public boolean isClientGone(Player player)
    • anyNonAiSocketsLeft

      private boolean anyNonAiSocketsLeft()
    • setObsolete

      public void setObsolete()
    • getPlayerName

      String getPlayerName()
      Name of the player, for which data from socket is currently processed.
    • getPlayer

      private Player getPlayer()
      The player, for which data from socket is currently processed.
    • getClientHandlerByName

      public ClientHandler getClientHandlerByName(String name)
      Might be a player or a spectator (but not a stub)
      Parameters:
      name - Name of the player/client/spectator for which ClientHandler is needed
    • isActivePlayer

      private boolean isActivePlayer()
      returns true if the active player is the player owning the connection from which data is currently processed
    • getActivePlayerSS

      private PlayerServerSide getActivePlayerSS()
    • isBattleActivePlayer

      private boolean isBattleActivePlayer()
    • addClient

      String addClient(ClientHandler client, String playerName, boolean remote, int clientVersion, String buildInfo, boolean spectator)
      Add a Client.
      Parameters:
      client -
      playerName -
      remote -
      clientVersion -
      spectator -
      Returns:
      Reason why adding Client was refused, null if all is fine.
    • startGame

      public void startGame()
      When the last player has *joined* (not just connected), he calls this here, and this will proceed with either loadGame2() or newGame2().
    • initWaitingForPlayersToJoin

      private void initWaitingForPlayersToJoin(int count)
      Initialize the number of players we wait for to join (thread-safe)
      Parameters:
      count - the number of players that are expected to join
    • addRemoteClient

      private void addRemoteClient(IClient client, Player player)
    • disposeAllClients

      void disposeAllClients()
    • loadFailed

      public void loadFailed()
    • cleanupStartlog

      public void cleanupStartlog()
    • doCleanup

      public void doCleanup()
    • allUpdatePlayerInfo

      void allUpdatePlayerInfo(boolean treatDeadAsAlive, String reason)
    • allUpdatePlayerInfo

      void allUpdatePlayerInfo(String reason)
    • allUpdateCreatureCount

      void allUpdateCreatureCount(CreatureType type, int count, int deadCount)
    • allTellMovementRoll

      void allTellMovementRoll(int roll)
    • leaveCarryMode

      public void leaveCarryMode()
      Specified by:
      leaveCarryMode in interface IServer
    • doneWithBattleMoves

      public void doneWithBattleMoves()
      Specified by:
      doneWithBattleMoves in interface IServer
    • doneWithStrikes

      public void doneWithStrikes()
      Specified by:
      doneWithStrikes in interface IServer
    • isDoneWithStrikesOk

      private String isDoneWithStrikesOk()
      Validates that it it OK to be "done with strikes" now for executing player
      Returns:
      reason why it's not OK; null if all is ok
    • getClient

      private IClient getClient(Player player)
    • allInitBoard

      void allInitBoard()
    • allTellReplay

      void allTellReplay(boolean val, int maxTurn)
    • allTellRedo

      void allTellRedo(boolean val)
    • allRequestConfirmCatchup

      void allRequestConfirmCatchup(String action, boolean skipInTrouble)
    • allTellAllLegionLocations

      void allTellAllLegionLocations()
    • allTellLegionLocation

      void allTellLegionLocation(Legion legion)
    • allRemoveLegion

      void allRemoveLegion(Legion legion)
    • allTellPlayerElim

      void allTellPlayerElim(Player eliminatedPlayer, Player slayer, boolean updateHistory)
    • repeatTellOneHasNetworkTrouble

      void repeatTellOneHasNetworkTrouble()
    • othersTellOneHasNetworkTrouble

      void othersTellOneHasNetworkTrouble(ClientHandler chInTrouble)
    • othersTellOnesTroubleIsOver

      void othersTellOnesTroubleIsOver(ClientHandler chInTrouble)
    • othersTellReconnectOngoing

      void othersTellReconnectOngoing(ClientHandler chInTrouble)
    • othersTellRemainingTime

      void othersTellRemainingTime(ClientHandler chInTrouble, int secondsLeft)
    • othersTellReconnectCompleted

      void othersTellReconnectCompleted(ClientHandler chInTrouble)
    • appendToConnLogs

      void appendToConnLogs(ClientHandler chInTrouble, String message)
    • allRequestPingIfNeeded

      void allRequestPingIfNeeded()
      IF last ping round is at least PING_REQUEST_INTERVAL_SEC seconds ago, then send a ping request to all clients (except those which are in trouble anyway).
    • allTellGameOver

      void allTellGameOver(String message, boolean disposeFollows)
    • allSetupTurnState

      void allSetupTurnState()
      Needed if loading game outside the split phase.
    • allSetupSplit

      void allSetupSplit()
    • allSetupMove

      void allSetupMove()
    • allSetupFight

      void allSetupFight()
    • allSetupMuster

      void allSetupMuster()
    • kickPhase

      void kickPhase()
    • allSetupBattleSummon

      void allSetupBattleSummon()
    • allSetupBattleRecruit

      void allSetupBattleRecruit()
    • allSetupBattleMove

      void allSetupBattleMove()
    • allSetupBattleFight

      void allSetupBattleFight()
    • allPlaceNewChit

      void allPlaceNewChit(CreatureServerSide critter)
    • allRemoveDeadBattleChits

      void allRemoveDeadBattleChits()
    • allTellEngagementResults

      void allTellEngagementResults(Legion winner, String method, int points, int turns)
    • nextEngagement

      void nextEngagement()
    • askAcquireAngel

      void askAcquireAngel(PlayerServerSide player, Legion legion, List<CreatureType> recruits)
      Find out if the player wants to acquire an angel or archangel.
    • acquireAngel

      public void acquireAngel(Legion legion, CreatureType angelType)
      Specified by:
      acquireAngel in interface IServer
    • createSummonAngel

      void createSummonAngel(Legion legion)
    • reinforce

      void reinforce(Legion legion)
    • doSummon

      public void doSummon(Summoning event)
      Description copied from interface: IServer
      Handles a summon event
      Specified by:
      doSummon in interface IServer
      Parameters:
      event - The summon event or null if summoning is not wanted.
    • doRecruit

      public void doRecruit(Recruitment event)
      Handle mustering for legion. if recruiting with nothing, recruiterName is a non-null String that contains "null".
      Specified by:
      doRecruit in interface IServer
    • didRecruit

      void didRecruit(AddCreatureAction event, CreatureType recruiter)
    • undidRecruit

      void undidRecruit(Legion legion, CreatureType recruit, boolean reinforced)
    • engage

      public void engage(MasterHex hex)
      Specified by:
      engage in interface IServer
    • allTellEngagement

      void allTellEngagement(MasterHex hex, Legion attacker, Legion defender)
    • askConcede

      void askConcede(Legion ally, Legion enemy)
      Ask ally's player whether he wants to concede with ally.
    • concede

      public void concede(Legion legion)
      Specified by:
      concede in interface IServer
    • doNotConcede

      public void doNotConcede(Legion legion)
      Specified by:
      doNotConcede in interface IServer
    • askFlee

      void askFlee(Legion ally, Legion enemy)
      Ask ally's player whether he wants to flee with ally.
    • flee

      public void flee(Legion legion)
      Specified by:
      flee in interface IServer
    • doNotFlee

      public void doNotFlee(Legion legion)
      Specified by:
      doNotFlee in interface IServer
    • twoNegotiate

      void twoNegotiate(Legion attacker, Legion defender)
    • makeProposal

      public void makeProposal(String proposalString)
      playerName makes a proposal.
      Specified by:
      makeProposal in interface IServer
    • tellProposal

      void tellProposal(Player player, Proposal proposal)
      Tell playerName about proposal.
    • fight

      public void fight(MasterHex hex)
      Specified by:
      fight in interface IServer
    • doBattleMove

      public void doBattleMove(int tag, BattleHex hex)
      Specified by:
      doBattleMove in interface IServer
    • allTellBattleMove

      void allTellBattleMove(int tag, BattleHex startingHex, BattleHex endingHex, boolean undo)
    • strike

      public void strike(int tag, BattleHex hex)
      Specified by:
      strike in interface IServer
    • applyCarries

      public void applyCarries(BattleHex hex)
      Specified by:
      applyCarries in interface IServer
    • undoBattleMove

      public void undoBattleMove(BattleHex hex)
      Specified by:
      undoBattleMove in interface IServer
    • allTellStrikeResults

      void allTellStrikeResults(CreatureServerSide striker, CreatureServerSide target, int strikeNumber, List<String> rolls, int damage, int carryDamageLeft, Set<String> carryTargetDescriptions)
    • allTellCarryResults

      void allTellCarryResults(CreatureServerSide carryTarget, int carryDamageDone, int carryDamageLeft, Set<String> carryTargetDescriptions)
    • allTellHexSlowResults

      void allTellHexSlowResults(CreatureServerSide target, int slowValue)
    • allTellHexDamageResults

      void allTellHexDamageResults(CreatureServerSide target, int damage)
    • askChooseStrikePenalty

      void askChooseStrikePenalty(SortedSet<PenaltyOption> penaltyOptions)
      Takes a Set of PenaltyOptions.
    • assignStrikePenalty

      public void assignStrikePenalty(String prompt)
      Specified by:
      assignStrikePenalty in interface IServer
    • allInitBattle

      void allInitBattle(MasterHex masterHex)
    • allCleanupBattle

      void allCleanupBattle()
    • mulligan

      public void mulligan()
      Specified by:
      mulligan in interface IServer
    • undoSplit

      public void undoSplit(Legion splitoff)
      Specified by:
      undoSplit in interface IServer
    • undidSplit

      void undidSplit(Legion splitoff, Legion survivor, boolean updateHistory, int turn)
    • undoMove

      public void undoMove(Legion legion)
      Specified by:
      undoMove in interface IServer
    • allTellUndidMove

      public void allTellUndidMove(Legion legion, MasterHex formerHex, MasterHex currentHex, boolean splitLegionHasForcedMove)
    • undoRecruit

      public void undoRecruit(Legion legion)
      Specified by:
      undoRecruit in interface IServer
    • doneWithSplits

      public void doneWithSplits()
      Specified by:
      doneWithSplits in interface IServer
    • doneWithMoves

      public void doneWithMoves()
      Specified by:
      doneWithMoves in interface IServer
    • doneWithEngagements

      public void doneWithEngagements()
      Specified by:
      doneWithEngagements in interface IServer
    • doneWithRecruits

      public void doneWithRecruits()
      Specified by:
      doneWithRecruits in interface IServer
    • isWithdrawalIrrelevant

      public boolean isWithdrawalIrrelevant()
    • withdrawFromGame

      public void withdrawFromGame()
      Withdraw the player for which data was currently processed on socket (if it is a real one, and withdrawal still makes sense).
      Specified by:
      withdrawFromGame in interface IServer
    • withdrawFromGame

      public void withdrawFromGame(String playerName)
      Withdraw a specific player of which we know only the name; e.g. when one clientHandler when trying to write to another clientHandler encountered closed socket.
      Parameters:
      playerName - Name of the player to withdraw
    • sendDisconnect

      public void sendDisconnect()
      Specified by:
      sendDisconnect in interface IServer
    • stopGame

      public void stopGame()
      Specified by:
      stopGame in interface IServer
    • triggerDispose

      void triggerDispose()
    • getPlayerInfo

      private List<String> getPlayerInfo(boolean treatDeadAsAlive)
    • doSplit

      public void doSplit(Legion parent, String childId, List<CreatureType> creaturesToSplit)
      Description copied from interface: IServer
      Executes a split of certain creatures from a legion.
      Specified by:
      doSplit in interface IServer
      Parameters:
      parent - The legion to split the creatures out of.
      childId - A marker for the new legion.
      creaturesToSplit - The creatures to split out.
    • allTellDidSplit

      void allTellDidSplit(Legion parent, Legion child, int turn, boolean history)
      Called from game after this legion was split off, or by history
    • doMove

      public void doMove(Legion legion, MasterHex hex, EntrySide entrySide, boolean teleport, CreatureType teleportingLord)
      Specified by:
      doMove in interface IServer
    • allTellDidMove

      void allTellDidMove(Legion legion, MasterHex startingHex, MasterHex hex, EntrySide entrySide, boolean teleport, CreatureType teleportingLord)
    • allTellDidSummon

      void allTellDidSummon(Legion receivingLegion, Legion donorLegion, CreatureType summon)
    • allTellAddCreature

      void allTellAddCreature(AddCreatureAction event, boolean updateHistory, String reason)
    • allTellRemoveCreature

      void allTellRemoveCreature(Legion legion, CreatureType creature, boolean updateHistory, String reason)
    • allRevealLegion

      void allRevealLegion(Legion legion, String reason)
    • allRevealEngagedLegion

      void allRevealEngagedLegion(Legion legion, boolean isAttacker, String reason)
      pass to all clients the 'revealEngagedCreatures' message, then fire an 'revealEvent' to the history.
      Parameters:
      legion - the legion marker to reveal which is in a battle
      isAttacker - true if the 'legion' is the atackker in the battle, false for the defender.
    • allRevealLegion

      void allRevealLegion(Legion legion, List<CreatureType> creatures, String reason)
      Call from History during load game only
    • oneRevealLegion

      void oneRevealLegion(Legion legion, Player player, String reason)
    • oneRevealLegion

      void oneRevealLegion(Player player, Legion legion, List<CreatureType> creatureNames, String reason)
      Call from History during load game only
    • allFullyUpdateLegionStatus

      void allFullyUpdateLegionStatus()
    • allFullyUpdateAllLegionContents

      void allFullyUpdateAllLegionContents(String reason)
    • allRevealCreatures

      void allRevealCreatures(Legion legion, List<CreatureType> creatureNames, String reason)
    • newGame

      public void newGame()
      Specified by:
      newGame in interface IServer
    • loadGame

      public void loadGame(String filename)
      Specified by:
      loadGame in interface IServer
    • saveGame

      public void saveGame(String filename)
      Specified by:
      saveGame in interface IServer
    • saveGame

      public void saveGame(String filename, boolean autoSave)
    • initiateSaveGame

      public void initiateSaveGame(String filename)
    • setPauseState

      public void setPauseState(boolean newState)
    • handleGuiRequests

      public boolean handleGuiRequests()
      Handle GUI-initiated requests: Save and Pause
      Returns:
      true if it did something (saving the game)
    • checkServerConnection

      public void checkServerConnection()
      Specified by:
      checkServerConnection in interface IServer
    • clientWontConfirmCatchup

      public void clientWontConfirmCatchup(ClientHandler ch, String reason)
      Check whether client is currently expected to send a caught-Up confirmation. If yes: it won't happen, so act accordingly. If no : even better so, so just do nothing.
      Parameters:
      reason - Reason why client won't send the confirmation (typically disconnected or something).
    • clientConfirmedCatchup

      public void clientConfirmedCatchup()
      Specified by:
      clientConfirmedCatchup in interface IServer
    • actOnAllCaughtUp

      private void actOnAllCaughtUp()
    • setPlayerName

      void setPlayerName(Player player, String newName)
      Used to change a player name after color is assigned.
    • askPickColor

      void askPickColor(Player player, List<PlayerColor> colorsLeft)
    • assignColor

      public void assignColor(PlayerColor color)
      Specified by:
      assignColor in interface IServer
    • askPickFirstMarker

      void askPickFirstMarker(Player player)
    • assignFirstMarker

      public void assignFirstMarker(String markerId)
      Specified by:
      assignFirstMarker in interface IServer
    • allSetColor

      void allSetColor()
      Hack to set color on load game.
    • getIntOption

      int getIntOption(String optname)
    • oneSetOption

      void oneSetOption(Player player, String optname, String value)
    • oneSetOption

      void oneSetOption(Player player, String optname, boolean value)
    • allSyncOption

      void allSyncOption(String optname, String value)
    • allSyncOption

      void allSyncOption(String optname, boolean value)
    • allSyncOption

      void allSyncOption(String optname, int value)
    • allLog

      void allLog(String message)
      DO NOT USE: package so that it can be called from Log4J Appender.
    • logToStartLog

      void logToStartLog(String message)
    • disableAutoCloseStartupLog

      private void disableAutoCloseStartupLog()
    • doSetWhatToDoNext

      public void doSetWhatToDoNext(WhatNextManager.WhatToDoNext whatToDoNext, boolean triggerQuitTimer)
    • startupProgressAbort

      public void startupProgressAbort()
    • startupProgressQuit

      public void startupProgressQuit()
    • getGame

      public GameServerSide getGame()
    • getRecorder

      public MessageRecorder getRecorder()
    • replyToRequestGameInfo

      public void replyToRequestGameInfo()
    • requestSyncDelta

      public void requestSyncDelta(int lastReceivedMessageNr, int syncRequestNumber)
    • joinGame

      public void joinGame(String playerName)
      Specified by:
      joinGame in interface IServer
    • watchGame

      public void watchGame()
      Specified by:
      watchGame in interface IServer
    • enforcedDisconnectClient

      public void enforcedDisconnectClient(String name)