package com.mediamonks.googleflip.pages.game.management;
import android.util.Log;
import com.mediamonks.googleflip.data.vo.ClientVO;
import com.mediamonks.googleflip.data.vo.PlayerScoreVO;
import com.mediamonks.googleflip.pages.game.management.gamemessages.GameMessage;
import com.mediamonks.googleflip.pages.game.management.gamemessages.GameMessageConverter;
import com.mediamonks.googleflip.pages.game.management.gamemessages.c2s.C2SClientNameMessage;
import com.mediamonks.googleflip.pages.game.management.gamemessages.c2s.C2SRoundFinishedMessage;
import com.mediamonks.googleflip.pages.game.management.gamemessages.s2c.S2CClientAckMessage;
import com.mediamonks.googleflip.pages.game.management.gamemessages.s2c.S2CClientsScoreChangedMessage;
import com.mediamonks.googleflip.pages.game.management.gamemessages.s2c.S2CConnectedClientsChangedMessage;
import com.mediamonks.googleflip.pages.game.management.gamemessages.s2c.S2CGameFinishedMessage;
import com.mediamonks.googleflip.pages.game.management.gamemessages.s2c.S2CRoundFinishedMessage;
import com.mediamonks.googleflip.pages.game.management.gamemessages.s2c.S2CRoundStartedMessage;
import java.util.ArrayList;
import java.util.List;
import temple.multiplayer.net.common.connection.Connection;
/**
* Implementation of GameClient interface
*/
public class GameClientImpl implements GameClient, Connection.ConnectionHandler {
private static final String TAG = GameClientImpl.class.getSimpleName();
private Player _player;
private boolean _debug;
private List<ClientVO> _clients;
private List<PlayerScoreVO> _playerScores;
private GameClientListenerProxy _listenerProxy = new GameClientListenerProxy();
private Connection.MessageHandler _messageHandler = new Connection.MessageHandler() {
@Override
public void onMessageReceived(String message) {
GameClientImpl.this.onMessageReceived(message);
}
};
private boolean _isGameFinished;
private int _currentRoundIndex;
private boolean _isWinner;
private boolean _isRoundFinished;
private boolean _isConnected;
public GameClientImpl() {
}
@Override
public void setPlayer(Player player) {
if (_debug) Log.d(TAG, "setPlayer: " + player.getClientVO().name);
_player = player;
_player.getConnection().setMessageHandler(_messageHandler);
_player.getConnection().setConnectionHandler(this);
_isConnected = true;
// send this now, even though the server may not be ready to receive it
writeGameMessage(new C2SClientNameMessage(_player.getClientVO().name, _player.getClientVO().id));
}
private void writeGameMessage(GameMessage gameMessage) {
if (_isConnected) {
_player.getConnection().writeMessage(GameMessageConverter.writeMessage(gameMessage));
}
}
private void onMessageReceived(String message) {
if (_debug) Log.d(TAG, "onMessageReceived: message = " + message);
GameMessage gameMessage = GameMessageConverter.readMessage(message);
if (gameMessage == null) {
Log.e(TAG, "onMessageReceived: couldn't convert message " + message);
return;
}
switch (gameMessage.getType()) {
case S2C_CLIENT_ACK:
onClientAck((S2CClientAckMessage) gameMessage);
break;
case S2C_ROUND_STARTED:
onRoundStarted((S2CRoundStartedMessage) gameMessage);
break;
case S2C_CONNECTED_CLIENTS_CHANGED:
onConnectedClientsChanged((S2CConnectedClientsChangedMessage) gameMessage);
break;
case S2C_CLIENTS_SCORE_CHANGED:
onClientsScoresChanged((S2CClientsScoreChangedMessage) gameMessage);
break;
case S2C_ROUND_FINISHED:
onRoundFinished((S2CRoundFinishedMessage) gameMessage);
break;
case S2C_GAME_FINISHED:
onGameFinished((S2CGameFinishedMessage) gameMessage);
break;
default:
if (_debug) Log.d(TAG, "onMessageReceived: unhandled message type " + gameMessage.getType());
break;
}
}
private void onGameFinished(S2CGameFinishedMessage message) {
if (_debug) Log.d(TAG, "onGameFinished: winner = " + message.winnerId);
_isGameFinished = true;
_isWinner = (message.winnerId == _player.getClientVO().id);
_listenerProxy.onGameFinished();
}
private void onRoundFinished(S2CRoundFinishedMessage message) {
if (_debug) Log.d(TAG, "onRoundFinished: ");
_isRoundFinished = true;
_listenerProxy.onRoundFinished();
}
private void onClientsScoresChanged(S2CClientsScoreChangedMessage message) {
if (_debug) Log.d(TAG, "onClientsScoresChanged: " + message.playerScores);
_playerScores = message.playerScores;
_listenerProxy.onPlayerScoresChanged(message.playerScores);
}
private void onConnectedClientsChanged(S2CConnectedClientsChangedMessage message) {
if (_debug) Log.d(TAG, "onConnectedClientsChanged: " + message.clients);
_clients = message.clients;
_listenerProxy.onClientsChanged(message.clients);
}
private void onRoundStarted(S2CRoundStartedMessage message) {
_isGameFinished = false;
_isRoundFinished = false;
if (_debug) Log.d(TAG, "onRoundStarted: id = " + message.levelId);
_currentRoundIndex = message.index;
_listenerProxy.onRoundStarted(message.levelId);
}
private void onClientAck(S2CClientAckMessage message) {
if (_debug) Log.d(TAG, "onClientAck: id = " + message.id);
if (_player.getClientVO().id == message.id && _player.getClientVO().name.equals(message.name)) {
if (_debug) Log.d(TAG, "onClientAck: player already known to server");
} else {
_player.setPlayerId(message.id);
_player.setPlayerLevelColor(message.levelColor);
writeGameMessage(new C2SClientNameMessage(_player.getClientVO().name, _player.getClientVO().id));
}
}
@Override
public Player getPlayer() {
return _player;
}
@Override
public void setRoundComplete(Long levelId, float seconds, boolean success) {
writeGameMessage(new C2SRoundFinishedMessage(levelId, seconds, success));
}
@Override
public void addGameClientListener(GameClientListener listener) {
_listenerProxy.addGameClientListener(listener);
}
@Override
public void removeGameClientListener(GameClientListener listener) {
_listenerProxy.removeGameClientListener(listener);
}
@Override
public List<ClientVO> getConnectedClients() {
return _clients;
}
@Override
public List<PlayerScoreVO> getPlayerScores() {
return _playerScores;
}
@Override
public PlayerScoreVO getPlayerScore() {
if (_playerScores == null) {
return null;
}
for (PlayerScoreVO playerScoreVO : _playerScores) {
if (playerScoreVO.clientVO.id == _player.getClientVO().id) {
return playerScoreVO;
}
}
return null;
}
@Override
public boolean isGameFinished() {
return _isGameFinished;
}
@Override
public boolean isRoundFinished() {
return _isRoundFinished;
}
@Override
public void stop() {
if (_player == null) {
return;
}
// disconnect player
_player.getConnection().disconnect();
_clients = null;
_player = null;
_playerScores = null;
_isConnected = false;
}
@Override
public int getCurrentRoundIndex() {
return _currentRoundIndex;
}
@Override
public boolean isWinner() {
return _isWinner;
}
@Override
public boolean isConnected() {
return _isConnected;
}
public void setDebug(boolean debug) {
_debug = debug;
}
@Override
public void onConnectionLost() {
_listenerProxy.onConnectionLost();
_isConnected = false;
}
/**
* Helper class for serving multiple listeners
*/
private static class GameClientListenerProxy implements GameClientListener {
private ArrayList<GameClientListener> _gameClientListeners;
private void addGameClientListener(GameClientListener listener) {
if (_gameClientListeners == null) {
_gameClientListeners = new ArrayList<>();
}
_gameClientListeners.add(listener);
}
private void removeGameClientListener(GameClientListener listener) {
_gameClientListeners.remove(listener);
}
@Override
public void onClientsChanged(List<ClientVO> clients) {
if (_gameClientListeners != null) {
for (GameClientListener listener : _gameClientListeners) {
listener.onClientsChanged(clients);
}
}
}
@Override
public void onPlayerScoresChanged(List<PlayerScoreVO> playerScores) {
if (_gameClientListeners != null) {
for (GameClientListener listener : _gameClientListeners) {
listener.onPlayerScoresChanged(playerScores);
}
}
}
@Override
public void onRoundStarted(Long levelId) {
if (_gameClientListeners != null) {
for (GameClientListener listener : _gameClientListeners) {
listener.onRoundStarted(levelId);
}
}
}
@Override
public void onRoundFinished() {
if (_gameClientListeners != null) {
for (GameClientListener listener : _gameClientListeners) {
listener.onRoundFinished();
}
}
}
@Override
public void onGameFinished() {
if (_gameClientListeners != null) {
for (GameClientListener listener : _gameClientListeners) {
listener.onGameFinished();
}
}
}
@Override
public void onConnectionLost() {
if (_gameClientListeners != null) {
for (GameClientListener listener : _gameClientListeners) {
listener.onConnectionLost();
}
}
}
}
}