GameOfferControl: Handle disappearing players correctly

git-svn-id: svn://sunsvr01.isp.uni-luebeck.de/swproj13/trunk@572 72836036-5685-4462-b002-a69064685172
This commit is contained in:
Matthias Schiffer 2011-06-22 03:48:51 +02:00
parent d2a96a4503
commit 670e4e8198
4 changed files with 127 additions and 40 deletions

View file

@ -52,6 +52,8 @@ public class MockConnectionControl implements IConnectionControl {
/** */ /** */
public MockEvent turnStartEvent = new MockEvent(); public MockEvent turnStartEvent = new MockEvent();
/** */ /** */
public MockEvent1<String> participantLeftEvent = new MockEvent1<String>();
/** */
public GameData currentGame; public GameData currentGame;
/** */ /** */
public GameData offeredGame; public GameData offeredGame;
@ -170,6 +172,11 @@ public class MockConnectionControl implements IConnectionControl {
return nextPlayerEvent; return nextPlayerEvent;
} }
@Override
public IEvent1<String> getParticipantLeftEvent() {
return participantLeftEvent;
}
@Override @Override
public void offerGame(GameData data) { public void offerGame(GameData data) {
offeredGame = data; offeredGame = data;

View file

@ -2,8 +2,6 @@ package jrummikub.control.network;
import java.awt.Color; import java.awt.Color;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
@ -43,6 +41,7 @@ import org.jivesoftware.smack.util.Base64;
import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.muc.DiscussionHistory; import org.jivesoftware.smackx.muc.DiscussionHistory;
import org.jivesoftware.smackx.muc.MultiUserChat; import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.muc.ParticipantStatusListener;
/** /**
* Connection control managing network connections, messages and events * Connection control managing network connections, messages and events
@ -117,6 +116,8 @@ public class ConnectionControl implements IConnectionControl {
private Event nextPlayerEvent = new Event(); private Event nextPlayerEvent = new Event();
private Event turnStartEvent = new Event(); private Event turnStartEvent = new Event();
private Event1<String> participantLeftEvent = new Event1<String>();
private GameData currentGame; private GameData currentGame;
private BlockingQueue<Runnable> actionQueue = new LinkedBlockingQueue<Runnable>(); private BlockingQueue<Runnable> actionQueue = new LinkedBlockingQueue<Runnable>();
@ -127,7 +128,7 @@ public class ConnectionControl implements IConnectionControl {
* Creates new connection control * Creates new connection control
* *
* @param loginData * @param loginData
* player's login data * player's login data
*/ */
public ConnectionControl(LoginData loginData) { public ConnectionControl(LoginData loginData) {
this.loginData = loginData; this.loginData = loginData;
@ -255,6 +256,11 @@ public class ConnectionControl implements IConnectionControl {
return turnStartEvent; return turnStartEvent;
} }
@Override
public IEvent1<String> getParticipantLeftEvent() {
return participantLeftEvent;
}
@Override @Override
public void offerGame(GameData data) { public void offerGame(GameData data) {
offeredGame = data; offeredGame = data;
@ -348,8 +354,7 @@ public class ConnectionControl implements IConnectionControl {
protected void addData(DefaultPacketExtension extension) { protected void addData(DefaultPacketExtension extension) {
extension.setValue("messageType", "change_color"); extension.setValue("messageType", "change_color");
extension.setValue("uuid", uuid.toString()); extension.setValue("uuid", uuid.toString());
extension.setValue("color", extension.setValue("color", Base64.encodeObject(color, Base64.GZIP));
Base64.encodeObject(color, Base64.GZIP));
} }
}); });
} }
@ -412,8 +417,7 @@ public class ConnectionControl implements IConnectionControl {
protected void addData(DefaultPacketExtension extension) { protected void addData(DefaultPacketExtension extension) {
extension.setValue("messageType", "table_update"); extension.setValue("messageType", "table_update");
extension.setValue("uuid", uuid.toString()); extension.setValue("uuid", uuid.toString());
extension.setValue("table", extension.setValue("table", Base64.encodeObject(table, Base64.GZIP));
Base64.encodeObject(table, Base64.GZIP));
} }
}); });
} }
@ -427,8 +431,8 @@ public class ConnectionControl implements IConnectionControl {
protected void addData(DefaultPacketExtension extension) { protected void addData(DefaultPacketExtension extension) {
extension.setValue("messageType", "turn_end"); extension.setValue("messageType", "turn_end");
extension.setValue("uuid", uuid.toString()); extension.setValue("uuid", uuid.toString());
extension.setValue("data", Base64.encodeObject(new TurnEndData( extension.setValue("data", Base64.encodeObject(new TurnEndData(state,
state, invalidTurnInfo), Base64.GZIP)); invalidTurnInfo), Base64.GZIP));
} }
}); });
} }
@ -464,8 +468,8 @@ public class ConnectionControl implements IConnectionControl {
protected void addData(DefaultPacketExtension extension) { protected void addData(DefaultPacketExtension extension) {
extension.setValue("messageType", "game_offer"); extension.setValue("messageType", "game_offer");
extension.setValue("uuid", data.getGameID().toString()); extension.setValue("uuid", data.getGameID().toString());
extension.setValue("gameSettings", Base64.encodeObject( extension.setValue("gameSettings",
data.getGameSettings(), Base64.GZIP)); Base64.encodeObject(data.getGameSettings(), Base64.GZIP));
} }
}); });
} }
@ -516,8 +520,8 @@ public class ConnectionControl implements IConnectionControl {
.getExtension(ELEMENT_NAME, NAMESPACE); .getExtension(ELEMENT_NAME, NAMESPACE);
if (((Message) packet).getType() == Message.Type.error) { if (((Message) packet).getType() == Message.Type.error) {
System.err.println("Received error message from '" System.err.println("Received error message from '" + packet.getFrom()
+ packet.getFrom() + "'"); + "'");
return; return;
} }
@ -533,15 +537,14 @@ public class ConnectionControl implements IConnectionControl {
String sender, String messageType) { String sender, String messageType) {
if (messageType.equals("game_offer")) { if (messageType.equals("game_offer")) {
UUID uuid = UUID.fromString(extension.getValue("uuid")); UUID uuid = UUID.fromString(extension.getValue("uuid"));
GameSettings settings = (GameSettings) Base64 GameSettings settings = (GameSettings) Base64.decodeToObject(extension
.decodeToObject(extension.getValue("gameSettings")); .getValue("gameSettings"));
fixGameSettings(settings); fixGameSettings(settings);
GameData gameData = new GameData(uuid, settings, sender); GameData gameData = new GameData(uuid, settings, sender);
gameOfferEvent.emit(gameData); gameOfferEvent.emit(gameData);
} else if (messageType.equals("game_withdrawal")) { } else if (messageType.equals("game_withdrawal")) {
gameWithdrawalEvent gameWithdrawalEvent.emit(UUID.fromString(extension.getValue("uuid")));
.emit(UUID.fromString(extension.getValue("uuid")));
} else if (messageType.equals("game_request")) { } else if (messageType.equals("game_request")) {
if (offeredGame != null) { if (offeredGame != null) {
sendGameOffer(); sendGameOffer();
@ -654,8 +657,7 @@ public class ConnectionControl implements IConnectionControl {
XMPPError xmppError = e.getXMPPError(); XMPPError xmppError = e.getXMPPError();
if (xmppError != null) { if (xmppError != null) {
if (xmppError.getType() == Type.WAIT if (xmppError.getType() == Type.WAIT && xmppError.getCode() == 504) {
&& xmppError.getCode() == 504) {
return LoginError.UNKNOWN_HOST; return LoginError.UNKNOWN_HOST;
} }
} }
@ -667,8 +669,7 @@ public class ConnectionControl implements IConnectionControl {
private LoginError doLogin() { private LoginError doLogin() {
try { try {
connection.login(loginData.getUserName(), connection.login(loginData.getUserName(), loginData.getPassword(),
loginData.getPassword(),
"JRummikub-" + StringUtils.randomString(8)); "JRummikub-" + StringUtils.randomString(8));
return null; return null;
} catch (XMPPException e) { } catch (XMPPException e) {
@ -686,7 +687,7 @@ public class ConnectionControl implements IConnectionControl {
while (true) { while (true) {
try { try {
muc.join(nickname, null, history, 10000); muc.join(nickname, null, history, 10000);
return null; // Join was successful, break the loop break; // Join was successful, break the loop
} catch (XMPPException e) { } catch (XMPPException e) {
XMPPError xmppError = e.getXMPPError(); XMPPError xmppError = e.getXMPPError();
@ -698,8 +699,7 @@ public class ConnectionControl implements IConnectionControl {
continue; continue;
} else { } else {
// An unknown error has occurred, cancel connect // An unknown error has occurred, cancel connect
if (xmppError != null if (xmppError != null && xmppError.getType() == Type.CANCEL
&& xmppError.getType() == Type.CANCEL
&& xmppError.getCode() == 404) { && xmppError.getCode() == 404) {
return LoginError.UNKNOWN_CHANNEL; 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) {
}
} }
} }

View file

@ -43,8 +43,7 @@ public class GameOfferControl extends AbstractGameBeginControl {
.add(new IListener() { .add(new IListener() {
@Override @Override
public void handle() { public void handle() {
gameData.getGameSettings() gameData.getGameSettings().getPlayerList();
.getPlayerList();
if (checkPlayers()) { if (checkPlayers()) {
startGame(); startGame();
} }
@ -95,22 +94,32 @@ public class GameOfferControl extends AbstractGameBeginControl {
new IListener1<String>() { new IListener1<String>() {
@Override @Override
public void handle(String sender) { public void handle(String sender) {
List<PlayerSettings> players = gameData.getGameSettings() handleLeave(sender);
.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);
} }
})); }));
connections.add(connectionControl.getParticipantLeftEvent().add(
new IListener1<String>() {
@Override
public void handle(String nickname) {
handleLeave(nickname);
}
}));
}
private void handleLeave(String nickname) {
List<PlayerSettings> 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;
}
}
} }
/** /**

View file

@ -52,6 +52,8 @@ interface IConnectionControl {
public IEvent getTurnStartEvent(); public IEvent getTurnStartEvent();
public IEvent1<String> getParticipantLeftEvent();
public void offerGame(GameData data); public void offerGame(GameData data);
public void withdrawGame(); public void withdrawGame();