Make game offers, withdrawals (untested) and requests work
git-svn-id: svn://sunsvr01.isp.uni-luebeck.de/swproj13/trunk@408 72836036-5685-4462-b002-a69064685172
This commit is contained in:
parent
e176dc4608
commit
630cdea1d9
3 changed files with 254 additions and 31 deletions
|
@ -1,19 +1,36 @@
|
|||
package jrummikub.control.network;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import jrummikub.util.Event;
|
||||
import jrummikub.util.Event1;
|
||||
import jrummikub.util.IEvent;
|
||||
import jrummikub.util.IEvent1;
|
||||
import jrummikub.util.LoginData;
|
||||
import jrummikub.view.IGameListPanel.GameData;
|
||||
|
||||
import org.jivesoftware.smack.Connection;
|
||||
import org.jivesoftware.smack.PacketListener;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.filter.AndFilter;
|
||||
import org.jivesoftware.smack.filter.PacketExtensionFilter;
|
||||
import org.jivesoftware.smack.filter.PacketTypeFilter;
|
||||
import org.jivesoftware.smack.packet.DefaultPacketExtension;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
import org.jivesoftware.smack.packet.XMPPError;
|
||||
import org.jivesoftware.smack.packet.XMPPError.Type;
|
||||
import org.jivesoftware.smackx.muc.DiscussionHistory;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChat;
|
||||
|
||||
class ConnectionControl {
|
||||
private final static String ELEMENT_NAME = "rummikub";
|
||||
private final static String NAMESPACE = "http://home.universe-factory.net/rummikub/";
|
||||
|
||||
private final LoginData loginData;
|
||||
private volatile Connection connection;
|
||||
private volatile MultiUserChat muc;
|
||||
|
@ -21,6 +38,11 @@ class ConnectionControl {
|
|||
private Event connectedEvent = new Event();
|
||||
private Event connectionFailedEvent = new Event();
|
||||
|
||||
private Event1<GameData> gameOfferEvent = new Event1<GameData>();
|
||||
private Event1<UUID> gameWithdrawalEvent = new Event1<UUID>();
|
||||
|
||||
private volatile GameData offeredGame;
|
||||
|
||||
ConnectionControl(LoginData loginData) {
|
||||
this.loginData = loginData;
|
||||
}
|
||||
|
@ -44,6 +66,30 @@ class ConnectionControl {
|
|||
return connectionFailedEvent;
|
||||
}
|
||||
|
||||
IEvent1<GameData> getGameOfferEvent() {
|
||||
return gameOfferEvent;
|
||||
}
|
||||
|
||||
IEvent1<UUID> getGameWithdrawalEvent() {
|
||||
return gameWithdrawalEvent;
|
||||
}
|
||||
|
||||
void offerGame(GameData data) {
|
||||
offeredGame = data;
|
||||
|
||||
sendGameOffer();
|
||||
}
|
||||
|
||||
void withdrawGame(UUID uuid) {
|
||||
offeredGame = null;
|
||||
|
||||
new Thread(new SendGameWithdrawRunner(uuid)).start();
|
||||
}
|
||||
|
||||
private void sendGameOffer() {
|
||||
new Thread(new SendGameOfferRunner(offeredGame)).start();
|
||||
}
|
||||
|
||||
private static void emitLater(final Event event) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
|
@ -53,28 +99,126 @@ class ConnectionControl {
|
|||
});
|
||||
}
|
||||
|
||||
private Message createMessage(PacketExtension extension) {
|
||||
Message message = muc.createMessage();
|
||||
message.addExtension(extension);
|
||||
return message;
|
||||
}
|
||||
|
||||
private static DefaultPacketExtension createJRummikubExtension() {
|
||||
return new DefaultPacketExtension(ELEMENT_NAME, NAMESPACE);
|
||||
}
|
||||
|
||||
private void processPacket(Packet packet) {
|
||||
DefaultPacketExtension extension = (DefaultPacketExtension) packet
|
||||
.getExtension(ELEMENT_NAME, NAMESPACE);
|
||||
|
||||
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"));
|
||||
int currentPlayerCount = Integer.parseInt(extension
|
||||
.getValue("currentPlayerCount"));
|
||||
int maxPlayerCount = Integer.parseInt(extension
|
||||
.getValue("maxPlayerCount"));
|
||||
|
||||
GameData gameData = new GameData(uuid, host);
|
||||
gameData.setCurrentPlayerCount(currentPlayerCount);
|
||||
gameData.setMaxPlayerCount(maxPlayerCount);
|
||||
gameOfferEvent.emit(gameData);
|
||||
} else if (messageType.equals("game_withdrawal")) {
|
||||
gameWithdrawalEvent.emit(UUID.fromString(extension.getValue("uuid")));
|
||||
} else if (messageType.equals("game_request")) {
|
||||
if (offeredGame != null) {
|
||||
sendGameOffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Message createGameOfferMessage(GameData data) {
|
||||
DefaultPacketExtension extension = createJRummikubExtension();
|
||||
|
||||
extension.setValue("messageType", "game_offer");
|
||||
extension.setValue("uuid", data.getGameID().toString());
|
||||
extension.setValue("currentPlayerCount",
|
||||
Integer.toString(data.getCurrentPlayerCount()));
|
||||
extension.setValue("maxPlayerCount",
|
||||
Integer.toString(data.getMaxPlayerCount()));
|
||||
|
||||
return createMessage(extension);
|
||||
}
|
||||
|
||||
private Message createGameWithdrawMessage(UUID uuid) {
|
||||
DefaultPacketExtension extension = createJRummikubExtension();
|
||||
|
||||
extension.setValue("messageType", "game_withdrawal");
|
||||
extension.setValue("uuid", uuid.toString());
|
||||
|
||||
return createMessage(extension);
|
||||
}
|
||||
|
||||
private Message createGameRequestMessage() {
|
||||
DefaultPacketExtension extension = createJRummikubExtension();
|
||||
|
||||
extension.setValue("messageType", "game_request");
|
||||
|
||||
return createMessage(extension);
|
||||
}
|
||||
|
||||
private class ConnectRunner implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (ConnectionControl.this) {
|
||||
connection = new XMPPConnection(loginData.getServerName());
|
||||
|
||||
connection.addPacketListener(new PacketListener() {
|
||||
@Override
|
||||
public void processPacket(final Packet packet) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ConnectionControl.this.processPacket(packet);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}, new AndFilter(new PacketTypeFilter(Message.class),
|
||||
new PacketExtensionFilter(ELEMENT_NAME, NAMESPACE)));
|
||||
|
||||
try {
|
||||
doConnect();
|
||||
} catch (XMPPException e) {
|
||||
connection.disconnect();
|
||||
connection = null;
|
||||
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
|
||||
emitLater(connectionFailedEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doConnect() throws XMPPException {
|
||||
connection.connect();
|
||||
connection.login(loginData.getUserName(),
|
||||
loginData.getPassword(), "JRummikub");
|
||||
muc = new MultiUserChat(connection,
|
||||
loginData.getChannelName());
|
||||
connection.login(loginData.getUserName(), loginData.getPassword(),
|
||||
"JRummikub");
|
||||
muc = new MultiUserChat(connection, loginData.getChannelName());
|
||||
DiscussionHistory history = new DiscussionHistory();
|
||||
history.setMaxStanzas(0);
|
||||
|
||||
String nickname = loginData.getUserName();
|
||||
// Loop until a unused nickname is found
|
||||
while (true) {
|
||||
try {
|
||||
muc.join(nickname);
|
||||
muc.join(nickname, null, history, 10000);
|
||||
break; // Join was successful, break the loop
|
||||
} catch (XMPPException e) {
|
||||
XMPPError error = e.getXMPPError();
|
||||
if (error.getType() == Type.CANCEL
|
||||
&& error.getCode() == 409) {
|
||||
if (error.getType() == Type.CANCEL && error.getCode() == 409) {
|
||||
// There was a conflict, try again with another
|
||||
// nickname
|
||||
nickname += "_";
|
||||
|
@ -87,14 +231,51 @@ class ConnectionControl {
|
|||
}
|
||||
|
||||
emitLater(connectedEvent);
|
||||
} catch (XMPPException e) {
|
||||
connection.disconnect();
|
||||
connection = null;
|
||||
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
new Thread(new SendGameRequestRunner()).start();
|
||||
}
|
||||
}
|
||||
|
||||
emitLater(connectionFailedEvent);
|
||||
private class SendGameOfferRunner implements Runnable {
|
||||
private GameData data;
|
||||
|
||||
public SendGameOfferRunner(GameData data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (ConnectionControl.this) {
|
||||
if (connection != null) {
|
||||
connection.sendPacket(createGameOfferMessage(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SendGameWithdrawRunner implements Runnable {
|
||||
private UUID uuid;
|
||||
|
||||
public SendGameWithdrawRunner(UUID uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (ConnectionControl.this) {
|
||||
if (connection != null) {
|
||||
connection.sendPacket(createGameWithdrawMessage(uuid));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SendGameRequestRunner implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (ConnectionControl.this) {
|
||||
if (connection != null) {
|
||||
connection.sendPacket(createGameRequestMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package jrummikub.control.network;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import jrummikub.util.Connection;
|
||||
|
@ -20,6 +22,8 @@ public class NetworkControl {
|
|||
private List<Connection> connections = new ArrayList<Connection>();
|
||||
private Event stopNetworkEvent = new Event();
|
||||
|
||||
private Map<UUID, GameData> gameMap = new HashMap<UUID, GameData>();
|
||||
|
||||
public NetworkControl(final LoginData loginData, final IView view) {
|
||||
this.view = view;
|
||||
connectionControl = new ConnectionControl(loginData);
|
||||
|
@ -33,7 +37,8 @@ public class NetworkControl {
|
|||
GameData testData = new GameData(UUID.randomUUID(), "NeoRaider");
|
||||
testData.setCurrentPlayerCount(2);
|
||||
testData.setMaxPlayerCount(4);
|
||||
view.getGameListPanel().addGame(testData);
|
||||
|
||||
connectionControl.offerGame(testData);
|
||||
}
|
||||
}));
|
||||
|
||||
|
@ -46,6 +51,36 @@ public class NetworkControl {
|
|||
}
|
||||
}));
|
||||
|
||||
connections.add(connectionControl.getGameOfferEvent().add(
|
||||
new IListener1<IGameListPanel.GameData>() {
|
||||
@Override
|
||||
public void handle(GameData value) {
|
||||
GameData game = gameMap.get(value.getGameID());
|
||||
|
||||
if (game == null) {
|
||||
game = value;
|
||||
gameMap.put(value.getGameID(), value);
|
||||
} else {
|
||||
game.setCurrentPlayerCount(value.getCurrentPlayerCount());
|
||||
game.setMaxPlayerCount(value.getMaxPlayerCount());
|
||||
}
|
||||
|
||||
view.getGameListPanel().addGame(game);
|
||||
}
|
||||
}));
|
||||
connections.add(connectionControl.getGameWithdrawalEvent().add(
|
||||
new IListener1<UUID>() {
|
||||
@Override
|
||||
public void handle(UUID value) {
|
||||
GameData game = gameMap.get(value);
|
||||
|
||||
if (game != null) {
|
||||
view.getGameListPanel().removeGame(game);
|
||||
gameMap.remove(value);
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
connections.add(view.getGameListPanel().getJoinEvent()
|
||||
.add(new IListener1<IGameListPanel.GameData>() {
|
||||
@Override
|
||||
|
|
|
@ -4,7 +4,6 @@ import java.awt.Color;
|
|||
import java.awt.Component;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
|
@ -163,16 +162,24 @@ class GameListPanel extends JPanel implements IGameListPanel {
|
|||
JLabel hostLabel, playerCountLabel;
|
||||
|
||||
GameDataCellRenderer() {
|
||||
setLayout(new GridLayout(1, 2));
|
||||
setLayout(new GridBagLayout());
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
c.fill = GridBagConstraints.BOTH;
|
||||
c.gridwidth = 1;
|
||||
c.weightx = 1;
|
||||
c.weighty = 1;
|
||||
|
||||
hostLabel = new JLabel();
|
||||
hostLabel.setOpaque(true);
|
||||
hostLabel.setHorizontalAlignment(JLabel.LEFT);
|
||||
add(hostLabel);
|
||||
add(hostLabel, c);
|
||||
|
||||
playerCountLabel = new JLabel();
|
||||
playerCountLabel.setOpaque(true);
|
||||
playerCountLabel.setHorizontalAlignment(JLabel.RIGHT);
|
||||
add(playerCountLabel);
|
||||
|
||||
c.gridwidth = GridBagConstraints.REMAINDER;
|
||||
add(playerCountLabel, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Reference in a new issue