package mw.client.server;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.rmi.RemoteException;
import javax.swing.JOptionPane;
import mw.client.gui.MWClient;
import mw.client.managers.ConnectionManager;
import mw.client.managers.GameManager;
import mw.client.managers.ProfileFacade;
import mw.client.managers.SettingsManager;
import mw.client.managers.WindowManager;
import mw.client.server.action.MWAction;
import mw.client.utils.cache.SaveObjectUtil;
import mw.server.MWProfile;
import mw.server.msg.MWMessage;
import mw.server.rmi.MessagingInterface;
import mw.server.socket.ZippedObjectImpl;
import org.apache.log4j.Logger;
public class MWServerListener implements Runnable {
public MWServerListener(int playerID, ObjectInputStream serverIn, MWAction action) {
this.connection = ConnectionManager.getRMIConnection();
this.myId = playerID;
this.serverIn = serverIn;
this.action = action;
}
public void run() {
try {
sideboarding();
waitForGameIsReady();
chooseDeck();
getOpponentInfo();
waitForGameStarted();
displayTable();
_mainLoop();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.getMessage());
log.error(e.getMessage(), e);
}
}
private void sideboarding() {
if (SettingsManager.getManager().isGameContinued()) {
action.onSideboard();
}
};
private void waitForGameIsReady() throws Exception {
MWMessage msg = receiveMsg();
while (msg.getMessageID() != MWMessage.MessageID.SM_GAME_READY) {
if (msg.getMessageID() == MWMessage.MessageID.SM_ERROR) {
action.onError(msg);
}
Thread.sleep(100);
msg = receiveMsg();
}
}
private void chooseDeck() throws Exception {
action.onChooseDeckToPlay();
}
private void waitForGameStarted() throws Exception {
MWMessage msg = receiveMsg();
while (msg.getMessageID() != MWMessage.MessageID.SM_GAME_STARTED) {
if (msg.getMessageID() == MWMessage.MessageID.SM_ERROR) {
action.onError(msg);
}
msg = receiveMsg();
Thread.sleep(20);
log.info("Still waiting for GAME_STARTED message");
}
}
private void getOpponentInfo() throws RemoteException {
log.info("Game started.");
// find out about your opponent
MWProfile opponentProfile = connection.getOpponentProfile(myId);
SaveObjectUtil.saveObject(opponentProfile, ProfileFacade.getMyId(), "opp_profile");
ProfileFacade.getManager().setOpponentProfile(opponentProfile);
action.setOpponentNickName(opponentProfile.getNickName());
}
@SuppressWarnings("unchecked")
private MWMessage receiveMsg() throws Exception {
Object msgZip = null;
try {
msgZip = serverIn.readObject();
if (!(msgZip instanceof ZippedObjectImpl)) {
System.err.println("Could get message from server: object can't be cast to MWMessage.");
throw new Exception("Could get message from server: object can't be cast to MWMessage.");
}
} catch (ClassNotFoundException c) {
log.error(c);
} catch (IOException i) {
log.error(i);
}
if (msgZip == null) {
throw new Exception("Could get message from server: zipped message was null.");
}
MWMessage msg = ((ZippedObjectImpl<MWMessage>)msgZip).unzip();
SaveObjectUtil.saveObject(msgZip, ProfileFacade.getMyId(), "msg_"+msg.getMessageID().name());
if (msg == null) {
throw new Exception("Could get message from server: unzipped message was null.");
}
return msg;
}
private void displayTable() {
parent = GameManager.getClient();
if (!action.isSilent()) {
parent.showGameTable();
WindowManager.getManager().getJMenuConfigure().setEnabled(true);
WindowManager.getManager().getJGameConfigure().setEnabled(true);
}
}
/**
* Main game loop
*/
private void _mainLoop() throws Exception {
MWMessage msg = null;
while (true) {
msg = receiveMsg();
if (msg == null) {
JOptionPane.showMessageDialog(null, "Connection to server has been lost");
return;
}
log.debug("[" + myId + "] Received message (msgID = " + msg.getMessageID() + (msg.getReceiverID() == 0 ? ", broadcast" : ", userID = " + msg.getReceiverID()) + ")");
switch(msg.getMessageID()) {
case SM_PHASE_CHANGED:
action.onPhaseChanged(msg);
break;
case SM_STACK_CHANGED:
action.onStackChanged(msg);
break;
case SM_BLOCKERS_CHANGED:
action.onBlockersChanged(msg);
break;
case SM_CHAT_MESSAGE:
action.onChatMessage(msg);
break;
case SM_CHOOSE_CARD_TO_DISCARD:
action.onChooseCardToDiscard(msg);
break;
case SM_STACK_EMPTY:
action.onStackEmpty(msg);
break;
case SM_PAYFOR_SPELL_ABILITY:
action.onPayForSpellAbility(msg);
break;
case SM_CHOOSE_TARGET_CREATURE_OR_PLAYER:
action.onChooseTargetCreatureOrPlayer(msg);
break;
case SM_CHOOSE_THE_TARGETS:
action.onChooseTheTargets(msg);
break;
case SM_CHOOSE_PERMANENTS:
action.onChoosePermanents(msg);
break;
case SM_CHOOSE_TARGETS_AS_ADDITIONAL_COST:
action.onChooseTargetsAsAdditionalCost(msg);
break;
case SM_CHOOSE_SPECIFIC_CARD:
action.onChooseSpecificCard(msg);
break;
case SM_CHOOSE_SPECIFIC_ABILITY_PLAY:
action.onChooseSpecificAbilityToPlay(msg);
break;
case SM_CHOOSE_SPECIFIC_ABILITY:
action.onChooseSpecificAbility(msg);
break;
case SM_CHOOSE_SPECIFIC_MANASYMBOL:
action.onChooseSpecificManasymbol(msg);
break;
/*case SM_CHOOSE_TARGET_PLAYER:
action.onChooseTargetPlayer(msg);
break;*/
case SM_CHOOSE_YES_NO:
action.onChooseYesNo(msg);
break;
/*case SM_CLEAR_INFO:
action.onClearInfo(msg);
break;*/
/*case SM_MANAPOOL_CHANGED:
action.onManapoolChanged(msg);
break;*/
/*case SM_HAND_CHANGED:
action.onHandChanged(msg);
break;*/
/*case SM_TABLE_CHANGED:
action.onTableChanged(msg);
break;*/
case SM_TABLE_CHANGED_TAPPED:
action.onTableChangedTapped(msg);
break;
//case SM_LIFE_CHANGED:
//action.onLifeChanged(msg);
/*
prev = now;
now = (new Date()).getTime();
if (prev != 0) {
log.info("Life, time between messages: " + (now - prev) + "ms");
}*/
//break;
case SM_GAME_STATE_CHANGED:
action.onGameStateChanged(msg);
break;
/*case SM_GRAVE_CHANGED:
action.onGraveChanged(msg);
break;*/
/*case SM_LIBRARY_CHANGED:
action.onLibraryChanged(msg);
break;*/
case SM_PLAY_MADNESS:
action.onPlayMadness(msg);
break;
case SM_CHOOSE_STRING_VALUE:
action.onChooseValue(msg);
break;
case SM_CHOOSE_CARD_TO_DISCARD_PAY:
action.onChooseCardToDiscardPay(msg);
break;
case SM_CHOOSE_X_VALUE:
action.onChooseXValue(msg);
break;
case SM_CHOOSE_X_VALUE2:
action.onChooseXValue2(msg);
break;
case SM_MANA_BURN:
action.onManaBurn(msg);
break;
case SM_REVEALED_CHANGED:
action.onRevealedChanged(msg);
break;
case SM_REVEALED_CHANGED_TO_PLAY:
action.onRevealedChangedToPlay(msg);
break;
case SM_VIEWED_CHANGED:
action.onViewedChanged(msg);
break;
case SM_CLEANUP_DISCARD:
action.onCleanupDiscard(msg);
break;
case SM_GAME_ASK_MULLIGAN:
action.onGameAskMulligan(msg);
break;
case SM_GAME_ASK_PLAY_FIRST:
action.onGameAskPlayFirst(msg);
break;
case SM_GAME_ENDED:
action.onGameEnded(msg);
return;
case SM_MATCH_ENDED:
action.onMatchEnded(msg);
return;
case SM_ERROR:
action.onError(msg);
break;
}
}
}
private static final Logger log = Logger.getLogger(MWServerListener.class);
private MWClient parent;
private MessagingInterface connection;
private ObjectInputStream serverIn;
private int myId;
private MWAction action;
}
|