Some more network stuff. We almost have a working lobby!

This commit is contained in:
elcnesh
2015-02-27 13:02:20 +00:00
parent 7ff89bd6b2
commit ca82a3b0d9
25 changed files with 462 additions and 106 deletions

5
.gitattributes vendored
View File

@@ -17392,7 +17392,9 @@ forge-gui/src/main/java/forge/interfaces/IGameController.java -text
forge-gui/src/main/java/forge/interfaces/IGuiBase.java -text forge-gui/src/main/java/forge/interfaces/IGuiBase.java -text
forge-gui/src/main/java/forge/interfaces/IGuiGame.java -text forge-gui/src/main/java/forge/interfaces/IGuiGame.java -text
forge-gui/src/main/java/forge/interfaces/IGuiTimer.java -text forge-gui/src/main/java/forge/interfaces/IGuiTimer.java -text
forge-gui/src/main/java/forge/interfaces/ILobby.java -text
forge-gui/src/main/java/forge/interfaces/IMayViewCards.java -text forge-gui/src/main/java/forge/interfaces/IMayViewCards.java -text
forge-gui/src/main/java/forge/interfaces/IPlayerChangeListener.java -text
forge-gui/src/main/java/forge/interfaces/IProgressBar.java -text forge-gui/src/main/java/forge/interfaces/IProgressBar.java -text
forge-gui/src/main/java/forge/interfaces/ITextField.java -text forge-gui/src/main/java/forge/interfaces/ITextField.java -text
forge-gui/src/main/java/forge/interfaces/IWinLoseView.java -text forge-gui/src/main/java/forge/interfaces/IWinLoseView.java -text
@@ -17610,6 +17612,9 @@ forge-net/src/main/java/forge/net/client/state/UnauthorizedClientState.java -tex
forge-net/src/main/java/forge/net/client/state/package-info.java -text forge-net/src/main/java/forge/net/client/state/package-info.java -text
forge-net/src/main/java/forge/net/game/GuiGameEvent.java -text forge-net/src/main/java/forge/net/game/GuiGameEvent.java -text
forge-net/src/main/java/forge/net/game/IRemote.java -text forge-net/src/main/java/forge/net/game/IRemote.java -text
forge-net/src/main/java/forge/net/game/LobbySlotType.java -text
forge-net/src/main/java/forge/net/game/LobbyState.java -text
forge-net/src/main/java/forge/net/game/LobbyUpdateEvent.java -text
forge-net/src/main/java/forge/net/game/LoginEvent.java -text forge-net/src/main/java/forge/net/game/LoginEvent.java -text
forge-net/src/main/java/forge/net/game/LogoutEvent.java -text forge-net/src/main/java/forge/net/game/LogoutEvent.java -text
forge-net/src/main/java/forge/net/game/MessageEvent.java -text forge-net/src/main/java/forge/net/game/MessageEvent.java -text

View File

@@ -1,23 +1,30 @@
package forge.gui; package forge.gui;
import forge.model.FModel; import java.awt.Graphics;
import forge.net.FGameClient; import java.awt.Rectangle;
import forge.net.game.MessageEvent;
import forge.properties.ForgePreferences.FPref;
import forge.toolbox.*;
import forge.toolbox.FSkin.SkinnedPanel;
import net.miginfocom.swing.MigLayout;
import org.apache.commons.lang3.StringUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import javax.swing.ScrollPaneConstants;
import net.miginfocom.swing.MigLayout;
import org.apache.commons.lang3.StringUtils;
import forge.model.FModel;
import forge.net.game.IRemote;
import forge.net.game.MessageEvent;
import forge.properties.ForgePreferences.FPref;
import forge.toolbox.FLabel;
import forge.toolbox.FScrollPane;
import forge.toolbox.FSkin;
import forge.toolbox.FSkin.SkinnedPanel;
import forge.toolbox.FTextArea;
import forge.toolbox.FTextField;
import forge.toolbox.SmartScroller;
/** /**
* TODO: Write javadoc for this type. * TODO: Write javadoc for this type.
* *
@@ -39,9 +46,9 @@ public enum FNetOverlay {
private int height = 120; private int height = 120;
private int width = 400; private int width = 400;
private FGameClient client = null; private IRemote remote = null;
public void setGameClient(final FGameClient client) { public void setGameClient(final IRemote remote) {
this.client = client; this.remote = remote;
} }
private final ActionListener onSend = new ActionListener() { private final ActionListener onSend = new ActionListener() {
@@ -52,8 +59,8 @@ public enum FNetOverlay {
return; return;
} }
if (client != null) { if (remote != null) {
client.send(new MessageEvent(FModel.getPreferences().getPref(FPref.PLAYER_NAME), message)); remote.send(new MessageEvent(FModel.getPreferences().getPref(FPref.PLAYER_NAME), message));
} }
// lobby.speak(ChatArea.Room, lobby.getGuiPlayer(), message); // lobby.speak(ChatArea.Room, lobby.getGuiPlayer(), message);
} }

View File

@@ -26,11 +26,13 @@ import forge.game.GameType;
import forge.gui.framework.FScreen; import forge.gui.framework.FScreen;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.model.FModel; import forge.model.FModel;
import forge.net.game.LobbySlotType;
import forge.properties.ForgePreferences; import forge.properties.ForgePreferences;
import forge.properties.ForgePreferences.FPref; import forge.properties.ForgePreferences.FPref;
import forge.screens.deckeditor.CDeckEditorUI; import forge.screens.deckeditor.CDeckEditorUI;
import forge.screens.deckeditor.controllers.CEditorCommander; import forge.screens.deckeditor.controllers.CEditorCommander;
import forge.screens.deckeditor.controllers.CEditorVariant; import forge.screens.deckeditor.controllers.CEditorVariant;
import forge.screens.home.VLobby.LobbyType;
import forge.screens.home.sanctioned.AvatarSelector; import forge.screens.home.sanctioned.AvatarSelector;
import forge.toolbox.FComboBox; import forge.toolbox.FComboBox;
import forge.toolbox.FComboBoxWrapper; import forge.toolbox.FComboBoxWrapper;
@@ -52,7 +54,10 @@ public class PlayerPanel extends FPanel {
private static final SkinColor unfocusedPlayerOverlay = FSkin.getColor(FSkin.Colors.CLR_OVERLAY).alphaColor(120); private static final SkinColor unfocusedPlayerOverlay = FSkin.getColor(FSkin.Colors.CLR_OVERLAY).alphaColor(120);
private final int index; private final int index;
private final boolean allowRemote; private final LobbyType lobbyType;
private LobbySlotType type = LobbySlotType.LOCAL;
private boolean editableForClient;
private final FLabel nameRandomiser; private final FLabel nameRandomiser;
private final FLabel avatarLabel = new FLabel.Builder().opaque(true).hoverable(true).iconScaleFactor(0.99f).iconInBackground(true).build(); private final FLabel avatarLabel = new FLabel.Builder().opaque(true).hoverable(true).iconScaleFactor(0.99f).iconInBackground(true).build();
@@ -63,12 +68,11 @@ public class PlayerPanel extends FPanel {
private FRadioButton radioAi; private FRadioButton radioAi;
private JCheckBoxMenuItem radioAiUseSimulation; private JCheckBoxMenuItem radioAiUseSimulation;
private FRadioButton radioOpen; private FRadioButton radioOpen;
/** Whether this panel is occupied by a remote player. */
private boolean isRemote;
private FComboBoxWrapper<Object> teamComboBox = new FComboBoxWrapper<Object>(); private FComboBoxWrapper<Object> teamComboBox = new FComboBoxWrapper<Object>();
private FComboBoxWrapper<Object> aeTeamComboBox = new FComboBoxWrapper<Object>(); private FComboBoxWrapper<Object> aeTeamComboBox = new FComboBoxWrapper<Object>();
private final FLabel closeBtn;
private final FLabel deckBtn = new FLabel.ButtonBuilder().text("Select a deck").build(); private final FLabel deckBtn = new FLabel.ButtonBuilder().text("Select a deck").build();
private final FLabel deckLabel; private final FLabel deckLabel;
@@ -91,7 +95,7 @@ public class PlayerPanel extends FPanel {
private final FLabel vgdLabel; private final FLabel vgdLabel;
private final VLobby lobby; private final VLobby lobby;
public PlayerPanel(final VLobby lobby, final int index, final boolean allowRemote) { public PlayerPanel(final VLobby lobby, final int index, final LobbyType lobbyType) {
super(); super();
this.lobby = lobby; this.lobby = lobby;
this.deckLabel = lobby.newLabel("Deck:"); this.deckLabel = lobby.newLabel("Deck:");
@@ -101,14 +105,14 @@ public class PlayerPanel extends FPanel {
this.vgdLabel = lobby.newLabel("Vanguard:"); this.vgdLabel = lobby.newLabel("Vanguard:");
this.index = index; this.index = index;
this.allowRemote = allowRemote; this.lobbyType = lobbyType;
this.playerIsArchenemy = index == 0; this.playerIsArchenemy = index == 0;
setLayout(new MigLayout("insets 10px, gap 5px")); setLayout(new MigLayout("insets 10px, gap 5px"));
// Add a button to players 3+ (or if server) to remove them from the setup // Add a button to players 3+ (or if server) to remove them from the setup
if (index >= 2 || allowRemote) { closeBtn = createCloseButton();
FLabel closeBtn = createCloseButton(); if (index >= 2 || lobbyType == LobbyType.SERVER) {
this.add(closeBtn, "w 20, h 20, pos (container.w-20) 0"); this.add(closeBtn, "w 20, h 20, pos (container.w-20) 0");
} }
@@ -132,7 +136,7 @@ public class PlayerPanel extends FPanel {
aeTeamComboBox.addActionListener(teamListener); aeTeamComboBox.addActionListener(teamListener);
teamComboBox.addTo(this, variantBtnConstraints + ", pushx, growx, gaptop 5px"); teamComboBox.addTo(this, variantBtnConstraints + ", pushx, growx, gaptop 5px");
aeTeamComboBox.addTo(this, variantBtnConstraints + ", pushx, growx, gaptop 5px"); aeTeamComboBox.addTo(this, variantBtnConstraints + ", pushx, growx, gaptop 5px");
if (allowRemote) { if (lobbyType == LobbyType.SERVER) {
this.add(radioOpen, "gapleft 1px"); this.add(radioOpen, "gapleft 1px");
} }
@@ -168,13 +172,31 @@ public class PlayerPanel extends FPanel {
update(); update();
} }
private void update() { void update() {
final boolean enableComponents = !(isOpen() || isRemote()); if (type != LobbySlotType.REMOTE) {
avatarLabel.setEnabled(enableComponents); if (radioHuman.isSelected()) {
txtPlayerName.setEnabled(enableComponents); type = LobbySlotType.LOCAL;
nameRandomiser.setEnabled(enableComponents); } else if (radioAi.isSelected()) {
deckLabel.setVisible(enableComponents); type = LobbySlotType.AI;
deckBtn.setVisible(enableComponents); } else if (radioOpen.isSelected()) {
type = LobbySlotType.OPEN;
}
}
final boolean isEditable = lobbyType == LobbyType.LOCAL || type == LobbySlotType.LOCAL ||
(lobbyType == LobbyType.SERVER && (type == LobbySlotType.LOCAL || type == LobbySlotType.AI)) ||
(lobbyType == LobbyType.CLIENT && editableForClient);
avatarLabel.setEnabled(isEditable);
txtPlayerName.setEnabled(isEditable);
nameRandomiser.setEnabled(isEditable);
deckLabel.setVisible(isEditable);
deckBtn.setVisible(isEditable);
final boolean hasSlotControls = lobbyType == LobbyType.LOCAL || (lobbyType == LobbyType.SERVER && type != LobbySlotType.REMOTE);
closeBtn.setVisible(hasSlotControls);
radioAi.setVisible(hasSlotControls);
radioHuman.setVisible(hasSlotControls);
radioOpen.setVisible(hasSlotControls && lobbyType == LobbyType.SERVER);
} }
private final FMouseAdapter radioMouseAdapter = new FMouseAdapter() { private final FMouseAdapter radioMouseAdapter = new FMouseAdapter() {
@@ -204,6 +226,7 @@ public class PlayerPanel extends FPanel {
prefs.setPref(FPref.PLAYER_NAME, newName); prefs.setPref(FPref.PLAYER_NAME, newName);
prefs.save(); prefs.save();
} }
lobby.firePlayerChangeListener();
} }
} }
}; };
@@ -244,6 +267,8 @@ public class PlayerPanel extends FPanel {
if (index < 2) { if (index < 2) {
PlayerPanel.this.lobby.updateAvatarPrefs(); PlayerPanel.this.lobby.updateAvatarPrefs();
} }
lobby.firePlayerChangeListener();
} }
@Override public final void onRightClick(final MouseEvent e) { @Override public final void onRightClick(final MouseEvent e) {
if (!avatarLabel.isEnabled()) { if (!avatarLabel.isEnabled()) {
@@ -334,29 +359,38 @@ public class PlayerPanel extends FPanel {
return index; return index;
} }
LobbySlotType getType() {
return type;
}
public boolean isAi() { public boolean isAi() {
return radioAi.isSelected(); return type == LobbySlotType.AI;
} }
public boolean isSimulatedAi() { public boolean isSimulatedAi() {
return radioAi.isSelected() && radioAiUseSimulation.isSelected(); return radioAi.isSelected() && radioAiUseSimulation.isSelected();
} }
public boolean isOpen() { public boolean isLocal() {
return radioOpen.isSelected() && !isRemote; return type == LobbySlotType.LOCAL;
} }
public boolean isArchenemy() { public boolean isArchenemy() {
return playerIsArchenemy; return playerIsArchenemy;
} }
public boolean isRemote() { public void setRemote(final boolean remote) {
return isRemote; if (remote) {
type = LobbySlotType.REMOTE;
} else {
radioOpen.setSelected(true);
type = LobbySlotType.OPEN;
}
update();
} }
public void setRemote(final boolean remote) { public void setEditableForClient(final boolean editable) {
isRemote = remote; editableForClient = editable;
update();
} }
public void setVanguardButtonText(String text) { public void setVanguardButtonText(String text) {
@@ -516,9 +550,10 @@ public class PlayerPanel extends FPanel {
* @param index * @param index
*/ */
private void createPlayerTypeOptions() { private void createPlayerTypeOptions() {
radioHuman = new FRadioButton(allowRemote ? "Local" : "Human", index == 0); final boolean isServer = lobbyType == LobbyType.SERVER;
radioAi = new FRadioButton("AI", !allowRemote && index != 0); radioHuman = new FRadioButton(isServer ? "Local" : "Human", index == 0);
radioOpen = new FRadioButton("Open", allowRemote && index != 0); radioAi = new FRadioButton("AI", !isServer && index != 0);
radioOpen = new FRadioButton("Open", isServer && index != 0);
final JPopupMenu menu = new JPopupMenu(); final JPopupMenu menu = new JPopupMenu();
radioAiUseSimulation = new JCheckBoxMenuItem("Use Simulation"); radioAiUseSimulation = new JCheckBoxMenuItem("Use Simulation");
menu.add(radioAiUseSimulation); menu.add(radioAiUseSimulation);
@@ -605,7 +640,7 @@ public class PlayerPanel extends FPanel {
.icon(FSkin.getIcon(FSkinProp.ICO_CLOSE)).hoverable(true).build(); .icon(FSkin.getIcon(FSkinProp.ICO_CLOSE)).hoverable(true).build();
closeBtn.setCommand(new Runnable() { closeBtn.setCommand(new Runnable() {
@Override public final void run() { @Override public final void run() {
if (isRemote() && !SOptionPane.showConfirmDialog("Really kick player?", "Kick", false)) { if (type == LobbySlotType.REMOTE && !SOptionPane.showConfirmDialog(String.format("Really kick %s?", getPlayerName()), "Kick", false)) {
return; return;
} }
PlayerPanel.this.lobby.removePlayer(index); PlayerPanel.this.lobby.removePlayer(index);
@@ -639,6 +674,8 @@ public class PlayerPanel extends FPanel {
random = MyRandom.getRandom().nextInt(FSkin.getAvatars().size()); random = MyRandom.getRandom().nextInt(FSkin.getAvatars().size());
} while (usedAvatars.contains(random)); } while (usedAvatars.contains(random));
setAvatar(random); setAvatar(random);
lobby.firePlayerChangeListener();
} }
public void setAvatar(int newAvatarIndex) { public void setAvatar(int newAvatarIndex) {

View File

@@ -137,7 +137,7 @@ public enum VHomeUI implements IVTopLevelUI {
allSubmenus.add(VSubmenuSealed.SINGLETON_INSTANCE); allSubmenus.add(VSubmenuSealed.SINGLETON_INSTANCE);
//allSubmenus.add(VSubmenuWinston.SINGLETON_INSTANCE); //allSubmenus.add(VSubmenuWinston.SINGLETON_INSTANCE);
//allSubmenus.add(VSubmenuOnlineLobby.SINGLETON_INSTANCE); allSubmenus.add(VSubmenuOnlineLobby.SINGLETON_INSTANCE);
allSubmenus.add(VSubmenuDuels.SINGLETON_INSTANCE); allSubmenus.add(VSubmenuDuels.SINGLETON_INSTANCE);
allSubmenus.add(VSubmenuChallenges.SINGLETON_INSTANCE); allSubmenus.add(VSubmenuChallenges.SINGLETON_INSTANCE);

View File

@@ -35,8 +35,14 @@ import forge.deckchooser.IDecksComboBoxListener;
import forge.game.GameType; import forge.game.GameType;
import forge.game.card.CardView; import forge.game.card.CardView;
import forge.gui.CardDetailPanel; import forge.gui.CardDetailPanel;
import forge.interfaces.ILobby;
import forge.interfaces.IPlayerChangeListener;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.model.FModel; import forge.model.FModel;
import forge.net.game.LobbySlotType;
import forge.net.game.LobbyState;
import forge.net.game.LobbyState.LobbyPlayerData;
import forge.net.game.server.RemoteClient;
import forge.properties.ForgePreferences; import forge.properties.ForgePreferences;
import forge.properties.ForgePreferences.FPref; import forge.properties.ForgePreferences.FPref;
import forge.toolbox.FCheckBox; import forge.toolbox.FCheckBox;
@@ -57,13 +63,17 @@ import forge.util.NameGenerator;
* *
* <br><br><i>(V at beginning of class name denotes a view class.)</i> * <br><br><i>(V at beginning of class name denotes a view class.)</i>
*/ */
public class VLobby { public class VLobby implements ILobby {
static final int MAX_PLAYERS = 8; static final int MAX_PLAYERS = 8;
private static final ForgePreferences prefs = FModel.getPreferences(); private static final ForgePreferences prefs = FModel.getPreferences();
public enum LobbyType { LOCAL, SERVER, CLIENT; }
// General variables // General variables
private final boolean allowRemote; private final LobbyType type;
private int localPlayer = 0;
private IPlayerChangeListener playerChangeListener = null;
private final LblHeader lblTitle = new LblHeader("Sanctioned Format: Constructed"); private final LblHeader lblTitle = new LblHeader("Sanctioned Format: Constructed");
private int activePlayersNum = 2; private int activePlayersNum = 2;
private int playerWithFocus = 0; // index of the player that currently has focus private int playerWithFocus = 0; // index of the player that currently has focus
@@ -122,8 +132,9 @@ public class VLobby {
private final Vector<Object> aiListData = new Vector<Object>(); private final Vector<Object> aiListData = new Vector<Object>();
// CTR // CTR
public VLobby(final boolean allowRemote) { public VLobby(final LobbyType type) {
this.allowRemote = allowRemote; this.type = type;
lblTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); lblTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
@@ -153,7 +164,10 @@ public class VLobby {
teams.add(i + 1); teams.add(i + 1);
archenemyTeams.add(i == 0 ? 1 : 2); archenemyTeams.add(i == 0 ? 1 : 2);
final PlayerPanel player = new PlayerPanel(this, i, allowRemote); final PlayerPanel player = new PlayerPanel(this, i, type);
if (type == LobbyType.CLIENT) {
player.setRemote(true);
}
playerPanels.add(player); playerPanels.add(player);
// Populate players panel // Populate players panel
@@ -172,14 +186,15 @@ public class VLobby {
playersFrame.setOpaque(false); playersFrame.setOpaque(false);
playersFrame.add(playersScroll, "w 100%, h 100%-35px"); playersFrame.add(playersScroll, "w 100%, h 100%-35px");
addPlayerBtn.setFocusable(true); if (type != LobbyType.CLIENT) {
addPlayerBtn.setCommand(new Runnable() { addPlayerBtn.setFocusable(true);
@Override addPlayerBtn.setCommand(new Runnable() {
public void run() { @Override public final void run() {
addPlayer(); addPlayer();
} }
}); });
playersFrame.add(addPlayerBtn, "height 30px!, growx, pushx"); playersFrame.add(addPlayerBtn, "height 30px!, growx, pushx");
}
constructedFrame.add(playersFrame, "gapright 10px, w 50%-5px, growy, pushy"); constructedFrame.add(playersFrame, "gapright 10px, w 50%-5px, growy, pushy");
@@ -194,8 +209,10 @@ public class VLobby {
decksFrame.setOpaque(false); decksFrame.setOpaque(false);
// Start Button // Start Button
pnlStart.setOpaque(false); if (type != LobbyType.CLIENT) {
pnlStart.add(btnStart, "align center"); pnlStart.setOpaque(false);
pnlStart.add(btnStart, "align center");
}
} }
public void populate() { public void populate() {
@@ -213,20 +230,23 @@ public class VLobby {
} }
public void addPlayerInFreeSlot(final String name) { private int addPlayerInFreeSlot(final String name) {
if (activePlayersNum >= MAX_PLAYERS) { if (activePlayersNum >= MAX_PLAYERS) {
return; return -1;
} }
for (final PlayerPanel pp : getPlayerPanels()) { for (final PlayerPanel pp : getPlayerPanels()) {
if (pp.isVisible() && pp.isOpen()) { if (pp.isVisible() && (
addPlayer(pp.getIndex()); pp.getType() == LobbySlotType.OPEN || (pp.isLocal() && type == LobbyType.SERVER))) {
final int index = pp.getIndex();
addPlayer(index);
pp.setPlayerName(name); pp.setPlayerName(name);
pp.setRemote(true); System.out.println("Put player " + name + " in slot " + index);
return; return index;
} }
} }
return -1;
} }
private void addPlayer() { private void addPlayer() {
if (activePlayersNum >= MAX_PLAYERS) { if (activePlayersNum >= MAX_PLAYERS) {
@@ -250,10 +270,12 @@ public class VLobby {
playerPanels.get(slot).setVisible(true); playerPanels.get(slot).setVisible(true);
playerPanels.get(slot).focusOnAvatar(); playerPanels.get(slot).focusOnAvatar();
firePlayerChangeListener();
} }
void removePlayer(final int playerIndex) { void removePlayer(final int playerIndex) {
if (activePlayersNum < playerIndex) { if (activePlayersNum <= playerIndex) {
return; return;
} }
activePlayersNum--; activePlayersNum--;
@@ -279,6 +301,69 @@ public class VLobby {
changePlayerFocus(closest); changePlayerFocus(closest);
playerPanels.get(closest).focusOnAvatar(); playerPanels.get(closest).focusOnAvatar();
} }
firePlayerChangeListener();
}
@Override
public int login(final RemoteClient client) {
return addPlayerInFreeSlot(client.getUsername());
}
@Override
public void logout(final RemoteClient client) {
removePlayer(client.getIndex());
}
@Override
public LobbyState getState() {
final LobbyState state = new LobbyState();
for (int i = 0; i < activePlayersNum; i++) {
state.addPlayer(getData(i));
}
return state;
}
public void setState(final LobbyState state) {
setLocalPlayer(state.getLocalPlayer());
final List<LobbyPlayerData> players = state.getPlayers();
final int pSize = players.size();
activePlayersNum = pSize;
for (int i = 0; i < pSize; i++) {
final LobbyPlayerData player = players.get(i);
final PlayerPanel panel = playerPanels.get(i);
if (type == LobbyType.CLIENT) {
panel.setRemote(i != localPlayer);
panel.setEditableForClient(i == localPlayer);
} else {
panel.setRemote(player.getType() == LobbySlotType.REMOTE);
panel.setEditableForClient(false);
}
panel.setPlayerName(player.getName());
panel.setAvatar(player.getAvatarIndex());
panel.setVisible(true);
panel.update();
}
}
private void setLocalPlayer(final int index) {
localPlayer = index;
}
public void setPlayerChangeListener(final IPlayerChangeListener listener) {
this.playerChangeListener = listener;
}
void firePlayerChangeListener() {
if (playerChangeListener != null) {
playerChangeListener.update(getData(localPlayer));
}
}
private LobbyPlayerData getData(final int index) {
final PlayerPanel panel = playerPanels.get(index);
return new LobbyPlayerData(panel.getPlayerName(), panel.getAvatarIndex(), panel.getType());
} }
/** Builds the actual deck panel layouts for each player. /** Builds the actual deck panel layouts for each player.
@@ -373,7 +458,7 @@ public class VLobby {
private void populateDeckPanel(final GameType forGameType) { private void populateDeckPanel(final GameType forGameType) {
decksFrame.removeAll(); decksFrame.removeAll();
if (playerPanelWithFocus.isOpen() || playerPanelWithFocus.isRemote()) { if (playerPanelWithFocus.getType() == LobbySlotType.OPEN || playerPanelWithFocus.getType() == LobbySlotType.REMOTE) {
return; return;
} }
@@ -439,8 +524,8 @@ public class VLobby {
return deckChoosers.get(playernum); return deckChoosers.get(playernum);
} }
public List<Integer> getTeams() { return Collections.unmodifiableList(teams); } public List<Integer> getTeams() { return teams; }
public List<Integer> getArchenemyTeams() { return Collections.unmodifiableList(archenemyTeams); } public List<Integer> getArchenemyTeams() { return archenemyTeams; }
public GameType getCurrentGameMode() { return currentGameMode; } public GameType getCurrentGameMode() { return currentGameMode; }
public void setCurrentGameMode(final GameType mode) { currentGameMode = mode; } public void setCurrentGameMode(final GameType mode) { currentGameMode = mode; }

View File

@@ -3,12 +3,17 @@ package forge.screens.home.online;
import forge.UiCommand; import forge.UiCommand;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.screens.home.CLobby; import forge.screens.home.CLobby;
import forge.screens.home.VLobby;
public enum COnlineLobby implements ICDoc { public enum COnlineLobby implements ICDoc {
SINGLETON_INSTANCE; SINGLETON_INSTANCE;
private final VOnlineLobby view = VOnlineLobby.SINGLETON_INSTANCE; private CLobby lobby;
private final CLobby lobby = new CLobby(view.getLobby());
void setLobby(VLobby lobbyView) {
lobby = new CLobby(lobbyView);
initialize();
}
@Override @Override
public void register() { public void register() {
@@ -19,7 +24,9 @@ public enum COnlineLobby implements ICDoc {
*/ */
@Override @Override
public void update() { public void update() {
lobby.update(); if (lobby != null) {
lobby.update();
}
} }
/* (non-Javadoc) /* (non-Javadoc)
@@ -27,7 +34,9 @@ public enum COnlineLobby implements ICDoc {
*/ */
@Override @Override
public void initialize() { public void initialize() {
lobby.initialize(); if (lobby != null) {
lobby.initialize();
}
} }
/* (non-Javadoc) /* (non-Javadoc)

View File

@@ -13,40 +13,71 @@ import forge.game.GameType;
import forge.gui.FNetOverlay; import forge.gui.FNetOverlay;
import forge.gui.framework.FScreen; import forge.gui.framework.FScreen;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.interfaces.IPlayerChangeListener;
import forge.menus.IMenuProvider; import forge.menus.IMenuProvider;
import forge.menus.MenuUtil; import forge.menus.MenuUtil;
import forge.model.FModel; import forge.model.FModel;
import forge.net.FGameClient; import forge.net.FGameClient;
import forge.net.FServerManager; import forge.net.FServerManager;
import forge.net.game.LobbyState;
import forge.net.game.LobbyState.LobbyPlayerData;
import forge.net.game.LoginEvent;
import forge.net.game.client.ILobbyListener; import forge.net.game.client.ILobbyListener;
import forge.net.game.server.RemoteClient;
import forge.properties.ForgePreferences.FPref; import forge.properties.ForgePreferences.FPref;
import forge.screens.home.VLobby;
import forge.screens.home.VLobby.LobbyType;
import forge.screens.home.sanctioned.ConstructedGameMenu; import forge.screens.home.sanctioned.ConstructedGameMenu;
public enum CSubmenuOnlineLobby implements ICDoc, IMenuProvider { public enum CSubmenuOnlineLobby implements ICDoc, IMenuProvider {
SINGLETON_INSTANCE; SINGLETON_INSTANCE;
final void host(final int portNumber) { final void host(final int portNumber) {
final VLobby lobby = VOnlineLobby.SINGLETON_INSTANCE.setLobby(LobbyType.SERVER);
FServerManager.getInstance().startServer(portNumber); FServerManager.getInstance().startServer(portNumber);
FServerManager.getInstance().registerLobbyListener(new ILobbyListener() { FServerManager.getInstance().setLobby(lobby);
@Override public final void logout(final RemoteClient client) { FServerManager.getInstance().hostGame(new GameRules(GameType.Constructed));
FNetOverlay.SINGLETON_INSTANCE.showUp("Hosting game");
lobby.setPlayerChangeListener(new IPlayerChangeListener() {
@Override public final void update(final LobbyPlayerData data) {
FServerManager.getInstance().updateLobbyState();
} }
@Override public final void login(final RemoteClient client) { });
VOnlineLobby.SINGLETON_INSTANCE.getLobby().addPlayerInFreeSlot(client.getUsername());
final FGameClient client = new FGameClient(FModel.getPreferences().getPref(FPref.PLAYER_NAME), "0", GuiBase.getInterface().getNewGuiGame());
FNetOverlay.SINGLETON_INSTANCE.setGameClient(client);
client.addLobbyListener(new ILobbyListener() {
@Override public final void update(final LobbyState state) {
lobby.setState(state);
} }
@Override public final void message(final String source, final String message) { @Override public final void message(final String source, final String message) {
FNetOverlay.SINGLETON_INSTANCE.addMessage(source, message); FNetOverlay.SINGLETON_INSTANCE.addMessage(source, message);
} }
}); });
FServerManager.getInstance().hostGame(new GameRules(GameType.Constructed)); client.connect("localhost", portNumber);
Singletons.getControl().setCurrentScreen(FScreen.ONLINE_LOBBY); Singletons.getControl().setCurrentScreen(FScreen.ONLINE_LOBBY);
FNetOverlay.SINGLETON_INSTANCE.showUp("Hosting game"); FNetOverlay.SINGLETON_INSTANCE.showUp(String.format("Hosting on port %d", portNumber));
} }
final void join(final String hostname, final int port) { final void join(final String hostname, final int port) {
final FGameClient client = new FGameClient(FModel.getPreferences().getPref(FPref.PLAYER_NAME), "0", GuiBase.getInterface().getNewGuiGame()); final FGameClient client = new FGameClient(FModel.getPreferences().getPref(FPref.PLAYER_NAME), "0", GuiBase.getInterface().getNewGuiGame());
FNetOverlay.SINGLETON_INSTANCE.setGameClient(client); FNetOverlay.SINGLETON_INSTANCE.setGameClient(client);
final VLobby lobby = VOnlineLobby.SINGLETON_INSTANCE.setLobby(LobbyType.CLIENT);
client.addLobbyListener(new ILobbyListener() {
@Override public final void update(final LobbyState state) {
lobby.setState(state);
}
@Override public final void message(final String source, final String message) {
FNetOverlay.SINGLETON_INSTANCE.addMessage(source, message);
}
});
lobby.setPlayerChangeListener(new IPlayerChangeListener() {
@Override public final void update(final LobbyPlayerData data) {
client.send(new LoginEvent(data.getName()));
}
});
client.connect(hostname, port); client.connect(hostname, port);
Singletons.getControl().setCurrentScreen(FScreen.ONLINE_LOBBY); Singletons.getControl().setCurrentScreen(FScreen.ONLINE_LOBBY);

View File

@@ -13,6 +13,7 @@ import forge.gui.framework.FScreen;
import forge.gui.framework.IVDoc; import forge.gui.framework.IVDoc;
import forge.gui.framework.IVTopLevelUI; import forge.gui.framework.IVTopLevelUI;
import forge.screens.home.VLobby; import forge.screens.home.VLobby;
import forge.screens.home.VLobby.LobbyType;
import forge.toolbox.FPanel; import forge.toolbox.FPanel;
import forge.util.gui.SOptionPane; import forge.util.gui.SOptionPane;
import forge.view.FView; import forge.view.FView;
@@ -24,15 +25,19 @@ public enum VOnlineLobby implements IVDoc<COnlineLobby>, IVTopLevelUI {
private final DragTab tab = new DragTab("Lobby"); private final DragTab tab = new DragTab("Lobby");
// General variables // General variables
private final VLobby lobby; private VLobby lobby;
private VOnlineLobby() { private VOnlineLobby() {
this.lobby = new VLobby(true);
} }
VLobby getLobby() { VLobby getLobby() {
return lobby; return lobby;
} }
VLobby setLobby(final LobbyType type) {
this.lobby = new VLobby(type);
getLayoutControl().setLobby(lobby);
return this.lobby;
}
@Override @Override
public void populate() { public void populate() {

View File

@@ -13,6 +13,7 @@ import forge.screens.home.EMenuGroup;
import forge.screens.home.IVSubmenu; import forge.screens.home.IVSubmenu;
import forge.screens.home.VLobby; import forge.screens.home.VLobby;
import forge.screens.home.VHomeUI; import forge.screens.home.VHomeUI;
import forge.screens.home.VLobby.LobbyType;
/** /**
* Assembles Swing components of constructed submenu singleton. * Assembles Swing components of constructed submenu singleton.
@@ -27,7 +28,7 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
private DragCell parentCell; private DragCell parentCell;
private final DragTab tab = new DragTab("Constructed Mode"); private final DragTab tab = new DragTab("Constructed Mode");
private final VLobby lobby = new VLobby(false); private final VLobby lobby = new VLobby(LobbyType.LOCAL);
private VSubmenuConstructed() { private VSubmenuConstructed() {
} }

View File

@@ -46,5 +46,11 @@
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
<version>3.3</version> <version>3.3</version>
</dependency> </dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.0.25.Final</version>
<scope>compile</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -0,0 +1,10 @@
package forge.interfaces;
import forge.net.game.LobbyState;
import forge.net.game.server.RemoteClient;
public interface ILobby {
LobbyState getState();
int login(RemoteClient client);
void logout(RemoteClient client);
}

View File

@@ -0,0 +1,7 @@
package forge.interfaces;
import forge.net.game.LobbyState.LobbyPlayerData;
public interface IPlayerChangeListener {
void update(LobbyPlayerData data);
}

View File

@@ -14,15 +14,23 @@ import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers; import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder; import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder; import io.netty.handler.codec.serialization.ObjectEncoder;
import forge.GuiBase;
import java.util.List;
import com.google.common.collect.Lists;
import forge.game.GameView; import forge.game.GameView;
import forge.game.player.PlayerView; import forge.game.player.PlayerView;
import forge.interfaces.IGuiGame; import forge.interfaces.IGuiGame;
import forge.model.FModel;
import forge.net.game.GuiGameEvent; import forge.net.game.GuiGameEvent;
import forge.net.game.LobbyUpdateEvent;
import forge.net.game.LoginEvent; import forge.net.game.LoginEvent;
import forge.net.game.MessageEvent; import forge.net.game.MessageEvent;
import forge.net.game.NetEvent; import forge.net.game.NetEvent;
import forge.net.game.client.ILobbyListener;
import forge.net.game.client.IToServer; import forge.net.game.client.IToServer;
import forge.properties.ForgePreferences.FPref;
public class FGameClient implements IToServer { public class FGameClient implements IToServer {
private final IGuiGame clientGui; private final IGuiGame clientGui;
@@ -30,6 +38,8 @@ public class FGameClient implements IToServer {
this.clientGui = clientGui; this.clientGui = clientGui;
} }
private final List<ILobbyListener> lobbyListeners = Lists.newArrayList();
static final int SIZE = Integer.parseInt(System.getProperty("size", "256")); static final int SIZE = Integer.parseInt(System.getProperty("size", "256"));
private Channel channel; private Channel channel;
@@ -47,6 +57,7 @@ public class FGameClient implements IToServer {
new ObjectEncoder(), new ObjectEncoder(),
new ObjectDecoder(ClassResolvers.cacheDisabled(null)), new ObjectDecoder(ClassResolvers.cacheDisabled(null)),
new MessageHandler(), new MessageHandler(),
new LobbyUpdateHandler(),
new GameClientHandler()); new GameClientHandler());
} }
}); });
@@ -74,6 +85,10 @@ public class FGameClient implements IToServer {
channel.writeAndFlush(event); channel.writeAndFlush(event);
} }
public void addLobbyListener(final ILobbyListener listener) {
lobbyListeners.add(listener);
}
private class GameClientHandler extends ChannelInboundHandlerAdapter { private class GameClientHandler extends ChannelInboundHandlerAdapter {
/** /**
* Creates a client-side handler. * Creates a client-side handler.
@@ -83,7 +98,8 @@ public class FGameClient implements IToServer {
@Override @Override
public void channelActive(final ChannelHandlerContext ctx) { public void channelActive(final ChannelHandlerContext ctx) {
send(new LoginEvent("elcnesh")); // Don't use send here, as this.channel is not yet set!
ctx.channel().writeAndFlush(new LoginEvent(FModel.getPreferences().getPref(FPref.PLAYER_NAME)));
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -116,7 +132,21 @@ public class FGameClient implements IToServer {
public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception { public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
if (msg instanceof MessageEvent) { if (msg instanceof MessageEvent) {
final MessageEvent event = (MessageEvent) msg; final MessageEvent event = (MessageEvent) msg;
GuiBase.getInterface().netMessage(event.getSource(), event.getMessage()); for (final ILobbyListener listener : lobbyListeners) {
listener.message(event.getSource(), event.getMessage());
}
}
super.channelRead(ctx, msg);
}
}
private class LobbyUpdateHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
if (msg instanceof LobbyUpdateEvent) {
for (final ILobbyListener listener : lobbyListeners) {
listener.update(((LobbyUpdateEvent) msg).getState());
}
} }
super.channelRead(ctx, msg); super.channelRead(ctx, msg);
} }

View File

@@ -1,12 +1,14 @@
package forge.net; package forge.net;
import forge.game.GameRules; import forge.game.GameRules;
import forge.interfaces.ILobby;
import forge.net.game.LobbyState;
import forge.net.game.LobbyUpdateEvent;
import forge.net.game.LoginEvent; import forge.net.game.LoginEvent;
import forge.net.game.LogoutEvent; import forge.net.game.LogoutEvent;
import forge.net.game.MessageEvent; import forge.net.game.MessageEvent;
import forge.net.game.NetEvent; import forge.net.game.NetEvent;
import forge.net.game.RegisterDeckEvent; import forge.net.game.RegisterDeckEvent;
import forge.net.game.client.ILobbyListener;
import forge.net.game.server.RemoteClient; import forge.net.game.server.RemoteClient;
import io.netty.bootstrap.ServerBootstrap; import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel; import io.netty.channel.Channel;
@@ -25,10 +27,8 @@ import io.netty.handler.codec.serialization.ObjectEncoder;
import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler; import io.netty.handler.logging.LoggingHandler;
import java.util.List;
import java.util.Map; import java.util.Map;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
public final class FServerManager { public final class FServerManager {
@@ -39,7 +39,7 @@ public final class FServerManager {
private final Map<Integer, NetGame> games = Maps.newTreeMap(); private final Map<Integer, NetGame> games = Maps.newTreeMap();
private int id = 0; private int id = 0;
private final Map<Channel, RemoteClient> clients = Maps.newTreeMap(); private final Map<Channel, RemoteClient> clients = Maps.newTreeMap();
private final List<ILobbyListener> lobbyListeners = Lists.newArrayListWithExpectedSize(1); private ILobby localLobby;
private FServerManager() { private FServerManager() {
} }
@@ -102,12 +102,13 @@ public final class FServerManager {
public void broadcast(final NetEvent event) { public void broadcast(final NetEvent event) {
for (final RemoteClient client : clients.values()) { for (final RemoteClient client : clients.values()) {
event.updateForClient(client);
client.send(event); client.send(event);
} }
} }
public void registerLobbyListener(final ILobbyListener lobbyListener) { public void setLobby(final ILobby lobby) {
lobbyListeners.add(lobbyListener); this.localLobby = lobby;
} }
public NetGame hostGame(final GameRules rules) { public NetGame hostGame(final GameRules rules) {
@@ -117,6 +118,12 @@ public final class FServerManager {
return game; return game;
} }
public void updateLobbyState() {
final LobbyState state = localLobby.getState();
final LobbyUpdateEvent event = new LobbyUpdateEvent(state);
broadcast(event);
}
@Override @Override
protected void finalize() throws Throwable { protected void finalize() throws Throwable {
super.finalize(); super.finalize();
@@ -153,6 +160,7 @@ public final class FServerManager {
clients.put(ctx.channel(), client); clients.put(ctx.channel(), client);
games.get(0).addClient(client); games.get(0).addClient(client);
System.out.println("User connected to server at " + ctx.channel().remoteAddress()); System.out.println("User connected to server at " + ctx.channel().remoteAddress());
updateLobbyState();
super.channelActive(ctx); super.channelActive(ctx);
} }
@@ -161,6 +169,7 @@ public final class FServerManager {
final RemoteClient client = clients.get(ctx.channel()); final RemoteClient client = clients.get(ctx.channel());
if (msg instanceof LoginEvent) { if (msg instanceof LoginEvent) {
client.setUsername(((LoginEvent) msg).getUsername()); client.setUsername(((LoginEvent) msg).getUsername());
updateLobbyState();
} else if (msg instanceof RegisterDeckEvent) { } else if (msg instanceof RegisterDeckEvent) {
games.get(0).registerDeck(client, ((RegisterDeckEvent) msg).getDeck()); games.get(0).registerDeck(client, ((RegisterDeckEvent) msg).getDeck());
} }
@@ -173,15 +182,15 @@ public final class FServerManager {
final RemoteClient client = clients.get(ctx.channel()); final RemoteClient client = clients.get(ctx.channel());
if (msg instanceof LoginEvent) { if (msg instanceof LoginEvent) {
final LoginEvent event = (LoginEvent) msg; final LoginEvent event = (LoginEvent) msg;
for (final ILobbyListener lobbyListener : lobbyListeners) { final int index = localLobby.login(client);
lobbyListener.login(client); if (index == -1) {
ctx.close();
} else {
client.setIndex(index);
broadcast(event);
} }
broadcast(event);
} else if (msg instanceof MessageEvent) { } else if (msg instanceof MessageEvent) {
final MessageEvent event = (MessageEvent) msg; final MessageEvent event = (MessageEvent) msg;
for (final ILobbyListener lobbyListener : lobbyListeners) {
lobbyListener.message(client.getUsername(), event.getMessage());
}
broadcast(event); broadcast(event);
} }
super.channelRead(ctx, msg); super.channelRead(ctx, msg);
@@ -189,9 +198,8 @@ public final class FServerManager {
@Override public void channelInactive(final ChannelHandlerContext ctx) throws Exception { @Override public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
final RemoteClient client = clients.get(ctx.channel()); final RemoteClient client = clients.get(ctx.channel());
for (final ILobbyListener lobbyListener : lobbyListeners) { localLobby.logout(client);
lobbyListener.logout(client); updateLobbyState();
}
super.channelInactive(ctx); super.channelInactive(ctx);
} }
} }
@@ -205,4 +213,5 @@ public final class FServerManager {
super.channelInactive(ctx); super.channelInactive(ctx);
} }
} }
} }

View File

@@ -3,9 +3,11 @@ package forge.net.game;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import forge.net.game.server.RemoteClient;
import forge.trackable.TrackableObject; import forge.trackable.TrackableObject;
public final class GuiGameEvent implements NetEvent { public final class GuiGameEvent implements NetEvent {
private static final long serialVersionUID = 6223690008522514574L;
private final String method; private final String method;
private final Iterable<? extends TrackableObject> objects; private final Iterable<? extends TrackableObject> objects;
@@ -15,6 +17,10 @@ public final class GuiGameEvent implements NetEvent {
this.objects = objects == null ? ImmutableSet.<TrackableObject>of() : objects; this.objects = objects == null ? ImmutableSet.<TrackableObject>of() : objects;
} }
@Override
public void updateForClient(final RemoteClient client) {
}
public String getMethod() { public String getMethod() {
return method; return method;
} }

View File

@@ -0,0 +1,8 @@
package forge.net.game;
public enum LobbySlotType {
LOCAL,
AI,
OPEN,
REMOTE;
}

View File

@@ -0,0 +1,51 @@
package forge.net.game;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import com.google.common.collect.Lists;
public class LobbyState implements Serializable {
private static final long serialVersionUID = 3899410700896996173L;
private final List<LobbyPlayerData> players = Lists.newArrayList();
private int localPlayer = -1;
public int getLocalPlayer() {
return localPlayer;
}
public void setLocalPlayer(final int localPlayer) {
this.localPlayer = localPlayer;
}
public void addPlayer(final LobbyPlayerData data) {
players.add(data);
}
public List<LobbyPlayerData> getPlayers() {
return Collections.unmodifiableList(players);
}
public final static class LobbyPlayerData implements Serializable {
private static final long serialVersionUID = 8642923786206592216L;
private final String name;
private final int avatarIndex;
private final LobbySlotType type;
public LobbyPlayerData(final String name, final int avatarIndex, final LobbySlotType type) {
this.name = name;
this.avatarIndex = avatarIndex;
this.type = type;
}
public String getName() {
return name;
}
public int getAvatarIndex() {
return avatarIndex;
}
public LobbySlotType getType() {
return type;
}
}
}

View File

@@ -0,0 +1,21 @@
package forge.net.game;
import forge.net.game.server.RemoteClient;
public class LobbyUpdateEvent implements NetEvent {
private static final long serialVersionUID = -3176971304173703949L;
private final LobbyState state;
public LobbyUpdateEvent(final LobbyState state) {
this.state = state;
}
@Override
public void updateForClient(final RemoteClient client) {
state.setLocalPlayer(client.getIndex());
}
public LobbyState getState() {
return state;
}
}

View File

@@ -1,5 +1,7 @@
package forge.net.game; package forge.net.game;
import forge.net.game.server.RemoteClient;
public class LoginEvent implements NetEvent { public class LoginEvent implements NetEvent {
private static final long serialVersionUID = -8865183377417377938L; private static final long serialVersionUID = -8865183377417377938L;
@@ -8,6 +10,10 @@ public class LoginEvent implements NetEvent {
this.username = username; this.username = username;
} }
@Override
public void updateForClient(final RemoteClient client) {
}
public String getUsername() { public String getUsername() {
return username; return username;
} }

View File

@@ -1,5 +1,7 @@
package forge.net.game; package forge.net.game;
import forge.net.game.server.RemoteClient;
public class LogoutEvent implements NetEvent { public class LogoutEvent implements NetEvent {
private static final long serialVersionUID = -8262613254026625787L; private static final long serialVersionUID = -8262613254026625787L;
@@ -8,6 +10,9 @@ public class LogoutEvent implements NetEvent {
this.username = username; this.username = username;
} }
public void updateForClient(final RemoteClient client) {
}
public String getUsername() { public String getUsername() {
return username; return username;
} }

View File

@@ -1,5 +1,7 @@
package forge.net.game; package forge.net.game;
import forge.net.game.server.RemoteClient;
public class MessageEvent implements NetEvent { public class MessageEvent implements NetEvent {
private static final long serialVersionUID = 1700060210647684186L; private static final long serialVersionUID = 1700060210647684186L;
@@ -8,6 +10,8 @@ public class MessageEvent implements NetEvent {
this.source = source; this.source = source;
this.message = message; this.message = message;
} }
public void updateForClient(final RemoteClient client) {
}
public String getSource() { public String getSource() {
return source; return source;

View File

@@ -2,5 +2,8 @@ package forge.net.game;
import java.io.Serializable; import java.io.Serializable;
import forge.net.game.server.RemoteClient;
public interface NetEvent extends Serializable { public interface NetEvent extends Serializable {
void updateForClient(RemoteClient client);
} }

View File

@@ -1,6 +1,7 @@
package forge.net.game; package forge.net.game;
import forge.deck.Deck; import forge.deck.Deck;
import forge.net.game.server.RemoteClient;
public class RegisterDeckEvent implements NetEvent { public class RegisterDeckEvent implements NetEvent {
private static final long serialVersionUID = -6553476654530937343L; private static final long serialVersionUID = -6553476654530937343L;
@@ -9,6 +10,8 @@ public class RegisterDeckEvent implements NetEvent {
public RegisterDeckEvent(final Deck deck) { public RegisterDeckEvent(final Deck deck) {
this.deck = deck; this.deck = deck;
} }
public void updateForClient(final RemoteClient client) {
}
public final Deck getDeck() { public final Deck getDeck() {
return deck; return deck;

View File

@@ -1,9 +1,8 @@
package forge.net.game.client; package forge.net.game.client;
import forge.net.game.server.RemoteClient; import forge.net.game.LobbyState;
public interface ILobbyListener { public interface ILobbyListener {
void login(RemoteClient client);
void logout(RemoteClient client);
void message(String source, String message); void message(String source, String message);
void update(LobbyState state);
} }

View File

@@ -7,6 +7,7 @@ public final class RemoteClient implements IToClient {
private final Channel channel; private final Channel channel;
private String username; private String username;
private int index;
public RemoteClient(final Channel channel) { public RemoteClient(final Channel channel) {
this.channel = channel; this.channel = channel;
} }
@@ -22,4 +23,11 @@ public final class RemoteClient implements IToClient {
public void setUsername(final String username) { public void setUsername(final String username) {
this.username = username; this.username = username;
} }
public int getIndex() {
return index;
}
public void setIndex(final int index) {
this.index = index;
}
} }