package com.esir.sr.sweetsnake.client; import java.rmi.RemoteException; import java.util.LinkedList; import java.util.List; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.esir.sr.sweetsnake.api.IClientCallback; import com.esir.sr.sweetsnake.api.IClientForGui; import com.esir.sr.sweetsnake.api.IClientForServer; import com.esir.sr.sweetsnake.api.IGuiForClient; import com.esir.sr.sweetsnake.api.IServer; import com.esir.sr.sweetsnake.dto.GameRequestDTO; import com.esir.sr.sweetsnake.dto.GameSessionDTO; import com.esir.sr.sweetsnake.dto.PlayerDTO; import com.esir.sr.sweetsnake.enumeration.MoveDirection; import com.esir.sr.sweetsnake.exception.GameRequestNotFoundException; import com.esir.sr.sweetsnake.exception.GameSessionNotFoundException; import com.esir.sr.sweetsnake.exception.MaximumNumberOfPlayersException; import com.esir.sr.sweetsnake.exception.PlayerNotAvailableException; import com.esir.sr.sweetsnake.exception.PlayerNotFoundException; import com.esir.sr.sweetsnake.exception.UnableToConnectException; import com.esir.sr.sweetsnake.exception.UnauthorizedActionException; import com.esir.sr.sweetsnake.provider.RmiProvider; /** * * @author Herminaƫl Rougier * @author Damien Jouanno * */ @Component public class Client implements IClientForServer, IClientForGui { /********************************************************************************************** * [BLOCK] STATIC FIELDS **********************************************************************************************/ /** The logger */ private static final Logger log = LoggerFactory.getLogger(Client.class); /********************************************************************************************** * [BLOCK] FIELDS **********************************************************************************************/ /** The client callback */ @Autowired private IClientCallback callback; /** The rmi provider */ @Autowired private RmiProvider rmiProvider; /** The GUI */ @Autowired private IGuiForClient gui; /** The server */ private IServer server; /** The username */ private String username; /** The sent requests DTO */ private List<GameRequestDTO> requests; /** The session DTO (only one at a time) */ private GameSessionDTO session; /** Is the client connected to the server */ private boolean isConnected; /********************************************************************************************** * [BLOCK] CONSTRUCTOR & INIT **********************************************************************************************/ /** * */ protected Client() { super(); } /** * */ @PostConstruct protected void init() { log.info("Initialiazing the Client"); requests = new LinkedList<GameRequestDTO>(); server = rmiProvider.getRmiService(); if (server == null) { gui.serverNotReachable(); } else { gui.serverReachable(); } } /** * */ @PreDestroy protected void destroy() { log.info("Destroying the Client"); if (isConnected) { disconnect(); } } /********************************************************************************************** * [BLOCK] PUBLIC GUI EXPOSED METHODS **********************************************************************************************/ /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForGui#reachServer() */ @Override public void reachServer() { if (server == null) { rmiProvider.retryReach(); server = rmiProvider.getRmiService(); if (server == null) { gui.serverNotReachable(); } else { gui.serverReachable(); } } } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForGui#connect(java.lang.String) */ @Override public void connect(final String _username) throws UnableToConnectException { if (_username == null || _username.isEmpty()) { throw new UnableToConnectException("invalid username"); } log.debug("Connecting with username {}", _username); username = new String(_username).trim(); server.connect(callback); } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForGui#disconnect() */ @Override public void disconnect() { log.debug("Disconnecting from username {}", username); server.disconnect(callback); } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForGui#sendRequest(com.esir.sr.sweetsnake.dto.PlayerDTO) */ @Override public void sendRequest(final PlayerDTO playerDto) { try { server.sendRequest(callback, playerDto); } catch (PlayerNotFoundException | PlayerNotAvailableException | GameSessionNotFoundException e) { gui.displayErrorMessage(e.getMessage()); } } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForGui#createSession() */ @Override public void createSession() { try { server.createSession(callback); } catch (final UnauthorizedActionException e) { gui.displayErrorMessage(e.getMessage()); } } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForGui#joinSession(com.esir.sr.sweetsnake.dto.GameSessionDTO) */ @Override public void joinSession(final GameSessionDTO sessionDto) { try { server.joinSession(callback, sessionDto); } catch (GameSessionNotFoundException | MaximumNumberOfPlayersException e) { gui.displayErrorMessage(e.getMessage()); } } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForGui#readyToPlay() */ @Override public void readyToPlay() { log.debug("session : {}", session); try { session.getCallback().ready(callback); } catch (final NullPointerException e) { gui.displayErrorMessage("you are not currently playing"); } catch (final RemoteException e) { gui.displayErrorMessage(e.getMessage()); } } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForGui#startSession() */ @Override public void startSession() { try { session.getCallback().startGame(callback); } catch (final NullPointerException e) { gui.displayErrorMessage("you are not currently playing"); } catch (final UnauthorizedActionException | RemoteException e) { gui.displayErrorMessage(e.getMessage()); } } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForGui#leaveSession() */ @Override public void leaveSession() { try { session.getCallback().leaveGame(callback); } catch (final NullPointerException e) { gui.displayErrorMessage("you are not currently playing"); } catch (final RemoteException e) { gui.displayErrorMessage(e.getMessage()); } } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForGui#moveSnake(com.esir.sr.sweetsnake.enumeration.MoveDirection) */ @Override public void moveSnake(final MoveDirection direction) { try { session.getCallback().move(callback, direction); } catch (final NullPointerException e) { gui.displayErrorMessage("you are not currently playing"); } catch (final UnauthorizedActionException | RemoteException e) { gui.displayErrorMessage(e.getMessage()); } } /********************************************************************************************** * [BLOCK] PUBLIC SERVER EXPOSED METHODS **********************************************************************************************/ /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForServer#connected() */ @Override public void connected() { isConnected = true; gui.connectedToServer(); } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForServer#disconnected() */ @Override public void disconnected() { isConnected = false; gui.disconnectedFromServer(); server = null; reachServer(); } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForServer#refreshPlayersList(java.util.List) */ @Override public void refreshPlayersList(final List<PlayerDTO> playersList) { gui.refreshPlayersList(playersList); } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForServer#refreshSessionsList(java.util.List) */ @Override public void refreshSessionsList(final List<GameSessionDTO> sessionsList) { gui.refreshSessionsList(sessionsList); } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForServer#requestSent(com.esir.sr.sweetsnake.dto.GameRequestDTO) */ @Override public void requestSent(final GameRequestDTO requestDto) { requests.add(requestDto); gui.requestSent(requestDto); } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForServer#requestReceived(com.esir.sr.sweetsnake.dto.GameRequestDTO) */ @Override public void requestReceived(final GameRequestDTO requestDTO) { final int answer = gui.requestReceived(requestDTO); if (answer == 0) { try { server.acceptRequest(callback, requestDTO); } catch (GameRequestNotFoundException | GameSessionNotFoundException | MaximumNumberOfPlayersException e) { gui.displayErrorMessage(e.getMessage()); } } else { try { server.denyRequest(callback, requestDTO); } catch (final GameRequestNotFoundException e) { gui.displayErrorMessage(e.getMessage()); } } } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForServer#requestDenied(com.esir.sr.sweetsnake.dto.GameRequestDTO) */ @Override public void requestDenied(final GameRequestDTO requestDTO) { gui.requestDenied(requestDTO); } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForServer#sessionJoined(int, com.esir.sr.sweetsnake.dto.GameSessionDTO) */ @Override public void sessionJoined(final int playerNb, final GameSessionDTO sessionDto) { session = sessionDto; gui.sessionJoined(session, playerNb); } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForServer#sessionStarted(int, com.esir.sr.sweetsnake.dto.GameSessionDTO) */ @Override public void sessionStarted(final int playerNb, final GameSessionDTO sessionDto) { session = sessionDto; gui.sessionStarted(session, playerNb); } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForServer#sessionLeft(com.esir.sr.sweetsnake.dto.GameSessionDTO, * com.esir.sr.sweetsnake.dto.PlayerDTO, boolean, boolean) */ @Override public void sessionLeft(final GameSessionDTO sessionDto, final PlayerDTO leaver, final boolean stopped, final boolean finished) { session = sessionDto; gui.sessionLeft(session, leaver, stopped, finished); if (finished) { session = null; } } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForServer#sessionFinished(com.esir.sr.sweetsnake.dto.GameSessionDTO) */ @Override public void sessionFinished(final GameSessionDTO sessionDto) { session = sessionDto; gui.sessionFinished(session); } /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClientForServer#refreshSession(com.esir.sr.sweetsnake.dto.GameSessionDTO) */ @Override public void refreshSession(final GameSessionDTO sessionDto) { session = sessionDto; gui.refreshGameboard(session.getGameBoardDto()); gui.refreshScores(session.getPlayersDto()); } /********************************************************************************************** * [BLOCK] PUBLIC CLIENT EXPOSED METHODS **********************************************************************************************/ /* * (non-Javadoc) * * @see com.esir.sr.sweetsnake.api.IClient#getUsername() */ @Override public String getUsername() { return username; } }