From 670e4e819859d0927e870ff973ea2dabe5b170a4 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 22 Jun 2011 03:48:51 +0200 Subject: GameOfferControl: Handle disappearing players correctly git-svn-id: svn://sunsvr01.isp.uni-luebeck.de/swproj13/trunk@572 72836036-5685-4462-b002-a69064685172 --- .../control/network/MockConnectionControl.java | 7 ++ .../control/network/ConnectionControl.java | 117 ++++++++++++++++----- .../control/network/GameOfferControl.java | 41 +++++--- .../control/network/IConnectionControl.java | 2 + 4 files changed, 127 insertions(+), 40 deletions(-) diff --git a/mock/jrummikub/control/network/MockConnectionControl.java b/mock/jrummikub/control/network/MockConnectionControl.java index 4aec478..ce8c4e3 100644 --- a/mock/jrummikub/control/network/MockConnectionControl.java +++ b/mock/jrummikub/control/network/MockConnectionControl.java @@ -52,6 +52,8 @@ public class MockConnectionControl implements IConnectionControl { /** */ public MockEvent turnStartEvent = new MockEvent(); /** */ + public MockEvent1 participantLeftEvent = new MockEvent1(); + /** */ public GameData currentGame; /** */ public GameData offeredGame; @@ -170,6 +172,11 @@ public class MockConnectionControl implements IConnectionControl { return nextPlayerEvent; } + @Override + public IEvent1 getParticipantLeftEvent() { + return participantLeftEvent; + } + @Override public void offerGame(GameData data) { offeredGame = data; diff --git a/src/jrummikub/control/network/ConnectionControl.java b/src/jrummikub/control/network/ConnectionControl.java index 39fabf7..2ae098b 100644 --- a/src/jrummikub/control/network/ConnectionControl.java +++ b/src/jrummikub/control/network/ConnectionControl.java @@ -2,8 +2,6 @@ package jrummikub.control.network; import java.awt.Color; import java.io.Serializable; -import java.util.Collection; -import java.util.Iterator; import java.util.UUID; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; @@ -43,6 +41,7 @@ import org.jivesoftware.smack.util.Base64; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smackx.muc.DiscussionHistory; import org.jivesoftware.smackx.muc.MultiUserChat; +import org.jivesoftware.smackx.muc.ParticipantStatusListener; /** * Connection control managing network connections, messages and events @@ -117,6 +116,8 @@ public class ConnectionControl implements IConnectionControl { private Event nextPlayerEvent = new Event(); private Event turnStartEvent = new Event(); + private Event1 participantLeftEvent = new Event1(); + private GameData currentGame; private BlockingQueue actionQueue = new LinkedBlockingQueue(); @@ -127,7 +128,7 @@ public class ConnectionControl implements IConnectionControl { * Creates new connection control * * @param loginData - * player's login data + * player's login data */ public ConnectionControl(LoginData loginData) { this.loginData = loginData; @@ -255,6 +256,11 @@ public class ConnectionControl implements IConnectionControl { return turnStartEvent; } + @Override + public IEvent1 getParticipantLeftEvent() { + return participantLeftEvent; + } + @Override public void offerGame(GameData data) { offeredGame = data; @@ -348,8 +354,7 @@ public class ConnectionControl implements IConnectionControl { protected void addData(DefaultPacketExtension extension) { extension.setValue("messageType", "change_color"); extension.setValue("uuid", uuid.toString()); - extension.setValue("color", - Base64.encodeObject(color, Base64.GZIP)); + extension.setValue("color", Base64.encodeObject(color, Base64.GZIP)); } }); } @@ -412,8 +417,7 @@ public class ConnectionControl implements IConnectionControl { protected void addData(DefaultPacketExtension extension) { extension.setValue("messageType", "table_update"); extension.setValue("uuid", uuid.toString()); - extension.setValue("table", - Base64.encodeObject(table, Base64.GZIP)); + extension.setValue("table", Base64.encodeObject(table, Base64.GZIP)); } }); } @@ -427,8 +431,8 @@ public class ConnectionControl implements IConnectionControl { protected void addData(DefaultPacketExtension extension) { extension.setValue("messageType", "turn_end"); extension.setValue("uuid", uuid.toString()); - extension.setValue("data", Base64.encodeObject(new TurnEndData( - state, invalidTurnInfo), Base64.GZIP)); + extension.setValue("data", Base64.encodeObject(new TurnEndData(state, + invalidTurnInfo), Base64.GZIP)); } }); } @@ -464,8 +468,8 @@ public class ConnectionControl implements IConnectionControl { protected void addData(DefaultPacketExtension extension) { extension.setValue("messageType", "game_offer"); extension.setValue("uuid", data.getGameID().toString()); - extension.setValue("gameSettings", Base64.encodeObject( - data.getGameSettings(), Base64.GZIP)); + extension.setValue("gameSettings", + Base64.encodeObject(data.getGameSettings(), Base64.GZIP)); } }); } @@ -516,8 +520,8 @@ public class ConnectionControl implements IConnectionControl { .getExtension(ELEMENT_NAME, NAMESPACE); if (((Message) packet).getType() == Message.Type.error) { - System.err.println("Received error message from '" - + packet.getFrom() + "'"); + System.err.println("Received error message from '" + packet.getFrom() + + "'"); return; } @@ -533,15 +537,14 @@ public class ConnectionControl implements IConnectionControl { String sender, String messageType) { if (messageType.equals("game_offer")) { UUID uuid = UUID.fromString(extension.getValue("uuid")); - GameSettings settings = (GameSettings) Base64 - .decodeToObject(extension.getValue("gameSettings")); + GameSettings settings = (GameSettings) Base64.decodeToObject(extension + .getValue("gameSettings")); fixGameSettings(settings); GameData gameData = new GameData(uuid, settings, sender); gameOfferEvent.emit(gameData); } else if (messageType.equals("game_withdrawal")) { - gameWithdrawalEvent - .emit(UUID.fromString(extension.getValue("uuid"))); + gameWithdrawalEvent.emit(UUID.fromString(extension.getValue("uuid"))); } else if (messageType.equals("game_request")) { if (offeredGame != null) { sendGameOffer(); @@ -654,8 +657,7 @@ public class ConnectionControl implements IConnectionControl { XMPPError xmppError = e.getXMPPError(); if (xmppError != null) { - if (xmppError.getType() == Type.WAIT - && xmppError.getCode() == 504) { + if (xmppError.getType() == Type.WAIT && xmppError.getCode() == 504) { return LoginError.UNKNOWN_HOST; } } @@ -667,8 +669,7 @@ public class ConnectionControl implements IConnectionControl { private LoginError doLogin() { try { - connection.login(loginData.getUserName(), - loginData.getPassword(), + connection.login(loginData.getUserName(), loginData.getPassword(), "JRummikub-" + StringUtils.randomString(8)); return null; } catch (XMPPException e) { @@ -686,7 +687,7 @@ public class ConnectionControl implements IConnectionControl { while (true) { try { muc.join(nickname, null, history, 10000); - return null; // Join was successful, break the loop + break; // Join was successful, break the loop } catch (XMPPException e) { XMPPError xmppError = e.getXMPPError(); @@ -698,8 +699,7 @@ public class ConnectionControl implements IConnectionControl { continue; } else { // An unknown error has occurred, cancel connect - if (xmppError != null - && xmppError.getType() == Type.CANCEL + if (xmppError != null && xmppError.getType() == Type.CANCEL && xmppError.getCode() == 404) { return LoginError.UNKNOWN_CHANNEL; } @@ -710,6 +710,75 @@ public class ConnectionControl implements IConnectionControl { } } + muc.addParticipantStatusListener(new LeaveListener()); + + return null; + } + + private class LeaveListener implements ParticipantStatusListener { + @Override + public void voiceRevoked(String arg0) { + } + + @Override + public void voiceGranted(String arg0) { + } + + @Override + public void ownershipRevoked(String arg0) { + } + + @Override + public void ownershipGranted(String arg0) { + } + + @Override + public void nicknameChanged(String arg0, String arg1) { + } + + @Override + public void moderatorRevoked(String arg0) { + } + + @Override + public void moderatorGranted(String arg0) { + } + + @Override + public void membershipRevoked(String arg0) { + } + + @Override + public void membershipGranted(String arg0) { + } + + @Override + public void left(String participant) { + participant = participant.substring(participant.indexOf('/') + 1); + emitLater(participantLeftEvent, participant); + } + + @Override + public void kicked(String participant, String actor, String reason) { + left(participant); + } + + @Override + public void joined(String arg0) { + } + + @Override + public void banned(String participant, String arg1, String arg2) { + left(participant); + } + + @Override + public void adminRevoked(String arg0) { + } + + @Override + public void adminGranted(String arg0) { + } } } diff --git a/src/jrummikub/control/network/GameOfferControl.java b/src/jrummikub/control/network/GameOfferControl.java index 52b2d0e..91b0940 100644 --- a/src/jrummikub/control/network/GameOfferControl.java +++ b/src/jrummikub/control/network/GameOfferControl.java @@ -43,8 +43,7 @@ public class GameOfferControl extends AbstractGameBeginControl { .add(new IListener() { @Override public void handle() { - gameData.getGameSettings() - .getPlayerList(); + gameData.getGameSettings().getPlayerList(); if (checkPlayers()) { startGame(); } @@ -95,24 +94,34 @@ public class GameOfferControl extends AbstractGameBeginControl { new IListener1() { @Override public void handle(String sender) { - List players = gameData.getGameSettings() - .getPlayerList(); - for (PlayerSettings s : players) { - if (s.getName().equals(sender) && s.getType() == Type.NETWORK) { - s.setType(Type.VACANT); - s.setName("Offen"); - break; - } - } - - updateSettingsPanel(); - checkPlayers(); - - connectionControl.offerGame(gameData); + handleLeave(sender); + } + })); + connections.add(connectionControl.getParticipantLeftEvent().add( + new IListener1() { + @Override + public void handle(String nickname) { + handleLeave(nickname); } })); } + private void handleLeave(String nickname) { + List players = gameData.getGameSettings().getPlayerList(); + for (PlayerSettings s : players) { + if (s.getName().equals(nickname) && s.getType() == Type.NETWORK) { + s.setType(Type.VACANT); + s.setName("Offen"); + + updateSettingsPanel(); + checkPlayers(); + + connectionControl.offerGame(gameData); + return; + } + } + } + /** * The event that is emitted when the game is started * diff --git a/src/jrummikub/control/network/IConnectionControl.java b/src/jrummikub/control/network/IConnectionControl.java index 19042c3..9307ce0 100644 --- a/src/jrummikub/control/network/IConnectionControl.java +++ b/src/jrummikub/control/network/IConnectionControl.java @@ -52,6 +52,8 @@ interface IConnectionControl { public IEvent getTurnStartEvent(); + public IEvent1 getParticipantLeftEvent(); + public void offerGame(GameData data); public void withdrawGame(); -- cgit v1.2.3