summaryrefslogtreecommitdiffstats
path: root/src/jrummikub
diff options
context:
space:
mode:
Diffstat (limited to 'src/jrummikub')
-rw-r--r--src/jrummikub/control/network/ConnectionControl.java141
-rw-r--r--src/jrummikub/control/network/GameJoinControl.java51
-rw-r--r--src/jrummikub/control/network/GameOfferControl.java36
-rw-r--r--src/jrummikub/control/network/NetworkControl.java38
-rw-r--r--src/jrummikub/view/ISettingsPanel.java4
-rw-r--r--src/jrummikub/view/impl/GameListPanel.java7
-rw-r--r--src/jrummikub/view/impl/SettingsPanel.java7
7 files changed, 269 insertions, 15 deletions
diff --git a/src/jrummikub/control/network/ConnectionControl.java b/src/jrummikub/control/network/ConnectionControl.java
index 7980c2d..d6bb5fe 100644
--- a/src/jrummikub/control/network/ConnectionControl.java
+++ b/src/jrummikub/control/network/ConnectionControl.java
@@ -7,9 +7,11 @@ import javax.swing.SwingUtilities;
import jrummikub.model.GameSettings;
import jrummikub.util.Event;
import jrummikub.util.Event1;
+import jrummikub.util.Event2;
import jrummikub.util.GameData;
import jrummikub.util.IEvent;
import jrummikub.util.IEvent1;
+import jrummikub.util.IEvent2;
import jrummikub.util.LoginData;
import org.jivesoftware.smack.Connection;
@@ -43,6 +45,11 @@ class ConnectionControl {
private Event1<GameData> gameOfferEvent = new Event1<GameData>();
private Event1<UUID> gameWithdrawalEvent = new Event1<UUID>();
+ private Event2<UUID, String> gameJoinEvent = new Event2<UUID, String>();
+ private Event2<UUID, String> gameLeaveEvent = new Event2<UUID, String>();
+
+ private Event2<UUID, Boolean> gameJoinAckEvent = new Event2<UUID, Boolean>();
+
private volatile GameData offeredGame;
ConnectionControl(LoginData loginData) {
@@ -80,6 +87,18 @@ class ConnectionControl {
return gameWithdrawalEvent;
}
+ IEvent2<UUID, String> getGameJoinEvent() {
+ return gameJoinEvent;
+ }
+
+ IEvent2<UUID, String> getGameLeaveEvent() {
+ return gameLeaveEvent;
+ }
+
+ IEvent2<UUID, Boolean> getGameJoinAckEvent() {
+ return gameJoinAckEvent;
+ }
+
void offerGame(GameData data) {
offeredGame = data;
@@ -92,6 +111,18 @@ class ConnectionControl {
new Thread(new SendGameWithdrawRunner(uuid)).start();
}
+ void joinGame(UUID uuid) {
+ new Thread(new SendGameJoinRunner(uuid)).start();
+ }
+
+ void leaveGame(UUID uuid) {
+ new Thread(new SendGameLeaveRunner(uuid)).start();
+ }
+
+ void ackJoinGame(UUID uuid, String recipient, boolean ack) {
+ new Thread(new SendGameJoinAckRunner(uuid, recipient, ack)).start();
+ }
+
private void sendGameOffer() {
new Thread(new SendGameOfferRunner(offeredGame)).start();
}
@@ -119,17 +150,23 @@ class ConnectionControl {
DefaultPacketExtension extension = (DefaultPacketExtension) packet
.getExtension(ELEMENT_NAME, NAMESPACE);
+ if (((Message) packet).getType() == Message.Type.error) {
+ System.err.println("Received error message from '" + packet.getFrom()
+ + "'");
+ return;
+ }
+
+ String sender = packet.getFrom();
+ sender = sender.substring(sender.indexOf('/') + 1);
+
String messageType = extension.getValue("messageType");
if (messageType.equals("game_offer")) {
- String host = packet.getFrom();
- host = host.substring(host.indexOf('/') + 1);
-
UUID uuid = UUID.fromString(extension.getValue("uuid"));
GameSettings settings = (GameSettings) Base64.decodeToObject(extension
.getValue("gameSettings"));
- GameData gameData = new GameData(uuid, settings, host);
+ GameData gameData = new GameData(uuid, settings, sender);
gameOfferEvent.emit(gameData);
} else if (messageType.equals("game_withdrawal")) {
gameWithdrawalEvent.emit(UUID.fromString(extension.getValue("uuid")));
@@ -137,6 +174,16 @@ class ConnectionControl {
if (offeredGame != null) {
sendGameOffer();
}
+ } else if (messageType.equals("game_join")) {
+ gameJoinEvent.emit(UUID.fromString(extension.getValue("uuid")), sender);
+ } else if (messageType.equals("game_leave")) {
+ gameLeaveEvent.emit(UUID.fromString(extension.getValue("uuid")), sender);
+ } else if (messageType.equals("game_join_ack")) {
+ gameJoinAckEvent.emit(UUID.fromString(extension.getValue("uuid")),
+ Boolean.valueOf(extension.getValue("ack")));
+ } else {
+ System.err.println("Received unrecognized message of type '"
+ + messageType + "'");
}
}
@@ -160,6 +207,37 @@ class ConnectionControl {
return createMessage(extension);
}
+ private Message createGameJoinMessage(UUID uuid) {
+ DefaultPacketExtension extension = createJRummikubExtension();
+
+ extension.setValue("messageType", "game_join");
+ extension.setValue("uuid", uuid.toString());
+
+ return createMessage(extension);
+ }
+
+ private Message createGameLeaveMessage(UUID uuid) {
+ DefaultPacketExtension extension = createJRummikubExtension();
+
+ extension.setValue("messageType", "game_leave");
+ extension.setValue("uuid", uuid.toString());
+
+ return createMessage(extension);
+ }
+
+ private Message createGameAckMessage(UUID uuid, String recipient, boolean ack) {
+ DefaultPacketExtension extension = createJRummikubExtension();
+
+ extension.setValue("messageType", "game_join_ack");
+ extension.setValue("uuid", uuid.toString());
+ extension.setValue("ack", Boolean.toString(ack));
+
+ Message message = createMessage(extension);
+ message.setType(Message.Type.normal);
+ message.setTo(muc.getRoom() + "/" + recipient);
+ return message;
+ }
+
private Message createGameRequestMessage() {
DefaultPacketExtension extension = createJRummikubExtension();
@@ -281,6 +359,61 @@ class ConnectionControl {
}
}
+ private class SendGameJoinRunner implements Runnable {
+ private UUID uuid;
+
+ public SendGameJoinRunner(UUID uuid) {
+ this.uuid = uuid;
+ }
+
+ @Override
+ public void run() {
+ synchronized (ConnectionControl.this) {
+ if (connection != null) {
+ connection.sendPacket(createGameJoinMessage(uuid));
+ }
+ }
+ }
+ }
+
+ private class SendGameLeaveRunner implements Runnable {
+ private UUID uuid;
+
+ public SendGameLeaveRunner(UUID uuid) {
+ this.uuid = uuid;
+ }
+
+ @Override
+ public void run() {
+ synchronized (ConnectionControl.this) {
+ if (connection != null) {
+ connection.sendPacket(createGameLeaveMessage(uuid));
+ }
+ }
+ }
+ }
+
+ private class SendGameJoinAckRunner implements Runnable {
+ private UUID uuid;
+ private String recipient;
+ private boolean ack;
+
+ public SendGameJoinAckRunner(UUID uuid, String recipient, boolean ack) {
+ this.uuid = uuid;
+ this.recipient = recipient;
+ this.ack = ack;
+ }
+
+ @Override
+ public void run() {
+ synchronized (ConnectionControl.this) {
+ if (connection != null) {
+ connection.sendPacket(createGameAckMessage(uuid, recipient, ack));
+ }
+ }
+ }
+ }
+
private class DisconnectRunner implements Runnable {
@Override
public void run() {
diff --git a/src/jrummikub/control/network/GameJoinControl.java b/src/jrummikub/control/network/GameJoinControl.java
new file mode 100644
index 0000000..c436887
--- /dev/null
+++ b/src/jrummikub/control/network/GameJoinControl.java
@@ -0,0 +1,51 @@
+package jrummikub.control.network;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jrummikub.util.Connection;
+import jrummikub.util.GameData;
+import jrummikub.util.IListener1;
+import jrummikub.view.ISettingsPanel.SettingsMode;
+import jrummikub.view.IView;
+
+public class GameJoinControl {
+ private List<Connection> connections = new ArrayList<Connection>();
+ private GameData gameData;
+ private ConnectionControl connectionControl;
+ private IView view;
+
+ public GameJoinControl(final ConnectionControl connectionControl,
+ final GameData gameData, final IView view) {
+ this.connectionControl = connectionControl;
+ this.gameData = gameData;
+ this.view = view;
+
+ view.getSettingsPanel().setSettingsMode(SettingsMode.NETWORK_JOIN);
+ view.getSettingsPanel().enableAddPlayerButton(false);
+ view.getSettingsPanel().setGameSettings(gameData.getGameSettings());
+
+ connections.add(connectionControl.getGameOfferEvent().add(
+ new IListener1<GameData>() {
+ @Override
+ public void handle(GameData data) {
+ if (data.getGameID().equals(gameData.getGameID())) {
+ gameData.setGameSettings(data.getGameSettings());
+ view.getSettingsPanel().setGameSettings(data.getGameSettings());
+ }
+ }
+ }));
+ }
+
+ public void startGameJoin() {
+ view.showSettingsPanel(true);
+ }
+
+ public void abort() {
+ // TODO Implement abort
+
+ for (Connection c : connections) {
+ c.remove();
+ }
+ }
+}
diff --git a/src/jrummikub/control/network/GameOfferControl.java b/src/jrummikub/control/network/GameOfferControl.java
index 0db5110..7cd289f 100644
--- a/src/jrummikub/control/network/GameOfferControl.java
+++ b/src/jrummikub/control/network/GameOfferControl.java
@@ -1,22 +1,27 @@
package jrummikub.control.network;
+import java.util.ArrayList;
+import java.util.List;
import java.util.UUID;
import jrummikub.model.GameSettings;
+import jrummikub.model.PlayerSettings;
+import jrummikub.model.PlayerSettings.Type;
+import jrummikub.util.Connection;
import jrummikub.util.GameData;
+import jrummikub.util.IListener2;
import jrummikub.view.ISettingsPanel.SettingsMode;
import jrummikub.view.IView;
public class GameOfferControl {
+ private List<Connection> connections = new ArrayList<Connection>();
private GameData gameData;
private ConnectionControl connectionControl;
- private GameSettings settings;
private IView view;
- public GameOfferControl(ConnectionControl connectionControl,
- GameSettings settings, IView view) {
+ public GameOfferControl(final ConnectionControl connectionControl,
+ final GameSettings settings, final IView view) {
this.connectionControl = connectionControl;
- this.settings = settings;
this.view = view;
gameData = new GameData(UUID.randomUUID(), settings);
@@ -24,6 +29,29 @@ public class GameOfferControl {
view.getSettingsPanel().setSettingsMode(SettingsMode.NETWORK_OFFER);
view.getSettingsPanel().enableAddPlayerButton(false);
view.getSettingsPanel().setGameSettings(settings);
+
+ connections.add(connectionControl.getGameJoinEvent().add(
+ new IListener2<UUID, String>() {
+ @Override
+ public void handle(UUID uuid, String sender) {
+ if (!uuid.equals(gameData.getGameID())) {
+ return;
+ }
+
+ for (PlayerSettings player : settings.getPlayerList()) {
+ if (player.getType() == Type.VACANT) {
+ player.setName(sender);
+ player.setType(Type.NETWORK);
+ view.getSettingsPanel().setGameSettings(settings);
+ connectionControl.ackJoinGame(uuid, sender, true);
+ connectionControl.offerGame(gameData);
+ return;
+ }
+ }
+
+ connectionControl.ackJoinGame(uuid, sender, false);
+ }
+ }));
}
public void startGameOffer() {
diff --git a/src/jrummikub/control/network/NetworkControl.java b/src/jrummikub/control/network/NetworkControl.java
index 7435839..dd4a949 100644
--- a/src/jrummikub/control/network/NetworkControl.java
+++ b/src/jrummikub/control/network/NetworkControl.java
@@ -13,6 +13,7 @@ import jrummikub.util.GameData;
import jrummikub.util.IEvent;
import jrummikub.util.IListener;
import jrummikub.util.IListener1;
+import jrummikub.util.IListener2;
import jrummikub.util.LoginData;
import jrummikub.view.IView;
@@ -27,6 +28,7 @@ public class NetworkControl {
private NetworkSettingsControl settingsControl;
private GameOfferControl gameOfferControl;
+ private GameJoinControl gameJoinControl;
private Map<UUID, GameData> gameMap = new HashMap<UUID, GameData>();
@@ -47,9 +49,8 @@ public class NetworkControl {
connections.add(view.getGameListPanel().getJoinEvent()
.add(new IListener1<GameData>() {
@Override
- public void handle(GameData value) {
- // TODO Auto-generated method stub
-
+ public void handle(GameData gameData) {
+ join(gameData);
}
}));
@@ -71,6 +72,11 @@ public class NetworkControl {
}));
}
+ private void join(GameData gameData) {
+ view.showGameListPanel(false);
+ connectionControl.joinGame(gameData.getGameID());
+ }
+
/**
* Adds the listeners for connection control events
*
@@ -126,6 +132,29 @@ public class NetworkControl {
}
}
}));
+ connections.add(connectionControl.getGameJoinAckEvent().add(
+ new IListener2<UUID, Boolean>() {
+ @Override
+ public void handle(UUID uuid, Boolean ack) {
+ if (ack) {
+ createGameJoinControl(uuid);
+ } else {
+ // TODO Error message
+ System.err.println("Join NACKed");
+ view.showGameListPanel(true);
+ }
+ }
+ }));
+ }
+
+ private void createGameJoinControl(UUID uuid) {
+ if (gameJoinControl != null) {
+ return;
+ }
+
+ GameData gameData = gameMap.get(uuid);
+ gameJoinControl = new GameJoinControl(connectionControl, gameData, view);
+ gameJoinControl.startGameJoin();
}
/**
@@ -150,6 +179,9 @@ public class NetworkControl {
if (gameOfferControl != null) {
gameOfferControl.abort();
}
+ if (gameJoinControl != null) {
+ gameJoinControl.abort();
+ }
connectionControl.disconnect();
}
diff --git a/src/jrummikub/view/ISettingsPanel.java b/src/jrummikub/view/ISettingsPanel.java
index c2bd766..279526a 100644
--- a/src/jrummikub/view/ISettingsPanel.java
+++ b/src/jrummikub/view/ISettingsPanel.java
@@ -268,6 +268,8 @@ public interface ISettingsPanel {
/** */
NETWORK_SETUP,
/** */
- NETWORK_OFFER
+ NETWORK_OFFER,
+ /** */
+ NETWORK_JOIN
}
} \ No newline at end of file
diff --git a/src/jrummikub/view/impl/GameListPanel.java b/src/jrummikub/view/impl/GameListPanel.java
index 7324559..2d07f2e 100644
--- a/src/jrummikub/view/impl/GameListPanel.java
+++ b/src/jrummikub/view/impl/GameListPanel.java
@@ -72,8 +72,11 @@ class GameListPanel extends JPanel implements IGameListPanel {
joinButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- // TODO Auto-generated method stub
- // joinEvent.emit();
+ Object data = gameList.getSelectedValue();
+
+ if (data instanceof GameData) {
+ joinEvent.emit((GameData) data);
+ }
}
});
diff --git a/src/jrummikub/view/impl/SettingsPanel.java b/src/jrummikub/view/impl/SettingsPanel.java
index 8ec9d3e..c7b6387 100644
--- a/src/jrummikub/view/impl/SettingsPanel.java
+++ b/src/jrummikub/view/impl/SettingsPanel.java
@@ -373,7 +373,8 @@ class SettingsPanel extends JPanel implements ISettingsPanel {
private void addPlayerSettingsPanel(int i, PlayerSettings settings,
List<Type> choices) {
PlayerSettingsPanel panel = new PlayerSettingsPanel(i, settings, choices,
- settingsMode != SettingsMode.NETWORK_OFFER);
+ settingsMode != SettingsMode.NETWORK_OFFER
+ && settingsMode != SettingsMode.NETWORK_JOIN);
playerSettingsPanels.add(panel);
playerSettingsViewport.add(panel,
playerSettingsViewport.getComponentCount() - 1);
@@ -765,6 +766,10 @@ class SettingsPanel extends JPanel implements ISettingsPanel {
addNetworkOfferButtons();
enableOptions(false);
break;
+ case NETWORK_JOIN:
+ // addNetworkJoinButtons();
+ enableOptions(false);
+ break;
}
}