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:
parent
d2a96a4503
commit
670e4e8198
4 changed files with 127 additions and 40 deletions
|
@ -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;
|
||||||
|
|
|
@ -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>();
|
||||||
|
@ -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) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
}
|
||||||
|
}));
|
||||||
|
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) {
|
for (PlayerSettings s : players) {
|
||||||
if (s.getName().equals(sender) && s.getType() == Type.NETWORK) {
|
if (s.getName().equals(nickname) && s.getType() == Type.NETWORK) {
|
||||||
s.setType(Type.VACANT);
|
s.setType(Type.VACANT);
|
||||||
s.setName("Offen");
|
s.setName("Offen");
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateSettingsPanel();
|
updateSettingsPanel();
|
||||||
checkPlayers();
|
checkPlayers();
|
||||||
|
|
||||||
connectionControl.offerGame(gameData);
|
connectionControl.offerGame(gameData);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Reference in a new issue