mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 11:18:01 +00:00
Some more network stuff. We almost have a working lobby!
This commit is contained in:
5
.gitattributes
vendored
5
.gitattributes
vendored
@@ -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/IGuiGame.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/IPlayerChangeListener.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/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/game/GuiGameEvent.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/LogoutEvent.java -text
|
||||
forge-net/src/main/java/forge/net/game/MessageEvent.java -text
|
||||
|
||||
@@ -1,23 +1,30 @@
|
||||
package forge.gui;
|
||||
|
||||
import forge.model.FModel;
|
||||
import forge.net.FGameClient;
|
||||
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.Graphics;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.text.SimpleDateFormat;
|
||||
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.
|
||||
*
|
||||
@@ -39,9 +46,9 @@ public enum FNetOverlay {
|
||||
private int height = 120;
|
||||
private int width = 400;
|
||||
|
||||
private FGameClient client = null;
|
||||
public void setGameClient(final FGameClient client) {
|
||||
this.client = client;
|
||||
private IRemote remote = null;
|
||||
public void setGameClient(final IRemote remote) {
|
||||
this.remote = remote;
|
||||
}
|
||||
|
||||
private final ActionListener onSend = new ActionListener() {
|
||||
@@ -52,8 +59,8 @@ public enum FNetOverlay {
|
||||
return;
|
||||
}
|
||||
|
||||
if (client != null) {
|
||||
client.send(new MessageEvent(FModel.getPreferences().getPref(FPref.PLAYER_NAME), message));
|
||||
if (remote != null) {
|
||||
remote.send(new MessageEvent(FModel.getPreferences().getPref(FPref.PLAYER_NAME), message));
|
||||
}
|
||||
// lobby.speak(ChatArea.Room, lobby.getGuiPlayer(), message);
|
||||
}
|
||||
|
||||
@@ -26,11 +26,13 @@ import forge.game.GameType;
|
||||
import forge.gui.framework.FScreen;
|
||||
import forge.item.PaperCard;
|
||||
import forge.model.FModel;
|
||||
import forge.net.game.LobbySlotType;
|
||||
import forge.properties.ForgePreferences;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.screens.deckeditor.CDeckEditorUI;
|
||||
import forge.screens.deckeditor.controllers.CEditorCommander;
|
||||
import forge.screens.deckeditor.controllers.CEditorVariant;
|
||||
import forge.screens.home.VLobby.LobbyType;
|
||||
import forge.screens.home.sanctioned.AvatarSelector;
|
||||
import forge.toolbox.FComboBox;
|
||||
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 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 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 JCheckBoxMenuItem radioAiUseSimulation;
|
||||
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> aeTeamComboBox = new FComboBoxWrapper<Object>();
|
||||
|
||||
private final FLabel closeBtn;
|
||||
private final FLabel deckBtn = new FLabel.ButtonBuilder().text("Select a deck").build();
|
||||
private final FLabel deckLabel;
|
||||
|
||||
@@ -91,7 +95,7 @@ public class PlayerPanel extends FPanel {
|
||||
private final FLabel vgdLabel;
|
||||
|
||||
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();
|
||||
this.lobby = lobby;
|
||||
this.deckLabel = lobby.newLabel("Deck:");
|
||||
@@ -101,14 +105,14 @@ public class PlayerPanel extends FPanel {
|
||||
this.vgdLabel = lobby.newLabel("Vanguard:");
|
||||
|
||||
this.index = index;
|
||||
this.allowRemote = allowRemote;
|
||||
this.lobbyType = lobbyType;
|
||||
this.playerIsArchenemy = index == 0;
|
||||
|
||||
setLayout(new MigLayout("insets 10px, gap 5px"));
|
||||
|
||||
// Add a button to players 3+ (or if server) to remove them from the setup
|
||||
if (index >= 2 || allowRemote) {
|
||||
FLabel closeBtn = createCloseButton();
|
||||
closeBtn = createCloseButton();
|
||||
if (index >= 2 || lobbyType == LobbyType.SERVER) {
|
||||
this.add(closeBtn, "w 20, h 20, pos (container.w-20) 0");
|
||||
}
|
||||
|
||||
@@ -132,7 +136,7 @@ public class PlayerPanel extends FPanel {
|
||||
aeTeamComboBox.addActionListener(teamListener);
|
||||
teamComboBox.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");
|
||||
}
|
||||
|
||||
@@ -168,13 +172,31 @@ public class PlayerPanel extends FPanel {
|
||||
update();
|
||||
}
|
||||
|
||||
private void update() {
|
||||
final boolean enableComponents = !(isOpen() || isRemote());
|
||||
avatarLabel.setEnabled(enableComponents);
|
||||
txtPlayerName.setEnabled(enableComponents);
|
||||
nameRandomiser.setEnabled(enableComponents);
|
||||
deckLabel.setVisible(enableComponents);
|
||||
deckBtn.setVisible(enableComponents);
|
||||
void update() {
|
||||
if (type != LobbySlotType.REMOTE) {
|
||||
if (radioHuman.isSelected()) {
|
||||
type = LobbySlotType.LOCAL;
|
||||
} else if (radioAi.isSelected()) {
|
||||
type = LobbySlotType.AI;
|
||||
} 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() {
|
||||
@@ -204,6 +226,7 @@ public class PlayerPanel extends FPanel {
|
||||
prefs.setPref(FPref.PLAYER_NAME, newName);
|
||||
prefs.save();
|
||||
}
|
||||
lobby.firePlayerChangeListener();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -244,6 +267,8 @@ public class PlayerPanel extends FPanel {
|
||||
if (index < 2) {
|
||||
PlayerPanel.this.lobby.updateAvatarPrefs();
|
||||
}
|
||||
|
||||
lobby.firePlayerChangeListener();
|
||||
}
|
||||
@Override public final void onRightClick(final MouseEvent e) {
|
||||
if (!avatarLabel.isEnabled()) {
|
||||
@@ -334,29 +359,38 @@ public class PlayerPanel extends FPanel {
|
||||
return index;
|
||||
}
|
||||
|
||||
LobbySlotType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public boolean isAi() {
|
||||
return radioAi.isSelected();
|
||||
return type == LobbySlotType.AI;
|
||||
}
|
||||
|
||||
public boolean isSimulatedAi() {
|
||||
return radioAi.isSelected() && radioAiUseSimulation.isSelected();
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return radioOpen.isSelected() && !isRemote;
|
||||
public boolean isLocal() {
|
||||
return type == LobbySlotType.LOCAL;
|
||||
}
|
||||
|
||||
public boolean isArchenemy() {
|
||||
return playerIsArchenemy;
|
||||
}
|
||||
|
||||
public boolean isRemote() {
|
||||
return isRemote;
|
||||
public void setRemote(final boolean remote) {
|
||||
if (remote) {
|
||||
type = LobbySlotType.REMOTE;
|
||||
} else {
|
||||
radioOpen.setSelected(true);
|
||||
type = LobbySlotType.OPEN;
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setRemote(final boolean remote) {
|
||||
isRemote = remote;
|
||||
update();
|
||||
public void setEditableForClient(final boolean editable) {
|
||||
editableForClient = editable;
|
||||
}
|
||||
|
||||
public void setVanguardButtonText(String text) {
|
||||
@@ -516,9 +550,10 @@ public class PlayerPanel extends FPanel {
|
||||
* @param index
|
||||
*/
|
||||
private void createPlayerTypeOptions() {
|
||||
radioHuman = new FRadioButton(allowRemote ? "Local" : "Human", index == 0);
|
||||
radioAi = new FRadioButton("AI", !allowRemote && index != 0);
|
||||
radioOpen = new FRadioButton("Open", allowRemote && index != 0);
|
||||
final boolean isServer = lobbyType == LobbyType.SERVER;
|
||||
radioHuman = new FRadioButton(isServer ? "Local" : "Human", index == 0);
|
||||
radioAi = new FRadioButton("AI", !isServer && index != 0);
|
||||
radioOpen = new FRadioButton("Open", isServer && index != 0);
|
||||
final JPopupMenu menu = new JPopupMenu();
|
||||
radioAiUseSimulation = new JCheckBoxMenuItem("Use Simulation");
|
||||
menu.add(radioAiUseSimulation);
|
||||
@@ -605,7 +640,7 @@ public class PlayerPanel extends FPanel {
|
||||
.icon(FSkin.getIcon(FSkinProp.ICO_CLOSE)).hoverable(true).build();
|
||||
closeBtn.setCommand(new Runnable() {
|
||||
@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;
|
||||
}
|
||||
PlayerPanel.this.lobby.removePlayer(index);
|
||||
@@ -639,6 +674,8 @@ public class PlayerPanel extends FPanel {
|
||||
random = MyRandom.getRandom().nextInt(FSkin.getAvatars().size());
|
||||
} while (usedAvatars.contains(random));
|
||||
setAvatar(random);
|
||||
|
||||
lobby.firePlayerChangeListener();
|
||||
}
|
||||
|
||||
public void setAvatar(int newAvatarIndex) {
|
||||
|
||||
@@ -137,7 +137,7 @@ public enum VHomeUI implements IVTopLevelUI {
|
||||
allSubmenus.add(VSubmenuSealed.SINGLETON_INSTANCE);
|
||||
//allSubmenus.add(VSubmenuWinston.SINGLETON_INSTANCE);
|
||||
|
||||
//allSubmenus.add(VSubmenuOnlineLobby.SINGLETON_INSTANCE);
|
||||
allSubmenus.add(VSubmenuOnlineLobby.SINGLETON_INSTANCE);
|
||||
|
||||
allSubmenus.add(VSubmenuDuels.SINGLETON_INSTANCE);
|
||||
allSubmenus.add(VSubmenuChallenges.SINGLETON_INSTANCE);
|
||||
|
||||
@@ -35,8 +35,14 @@ import forge.deckchooser.IDecksComboBoxListener;
|
||||
import forge.game.GameType;
|
||||
import forge.game.card.CardView;
|
||||
import forge.gui.CardDetailPanel;
|
||||
import forge.interfaces.ILobby;
|
||||
import forge.interfaces.IPlayerChangeListener;
|
||||
import forge.item.PaperCard;
|
||||
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.FPref;
|
||||
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>
|
||||
*/
|
||||
public class VLobby {
|
||||
public class VLobby implements ILobby {
|
||||
|
||||
static final int MAX_PLAYERS = 8;
|
||||
private static final ForgePreferences prefs = FModel.getPreferences();
|
||||
|
||||
public enum LobbyType { LOCAL, SERVER, CLIENT; }
|
||||
|
||||
// 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 int activePlayersNum = 2;
|
||||
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>();
|
||||
|
||||
// CTR
|
||||
public VLobby(final boolean allowRemote) {
|
||||
this.allowRemote = allowRemote;
|
||||
public VLobby(final LobbyType type) {
|
||||
this.type = type;
|
||||
|
||||
lblTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
@@ -153,7 +164,10 @@ public class VLobby {
|
||||
teams.add(i + 1);
|
||||
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);
|
||||
|
||||
// Populate players panel
|
||||
@@ -172,14 +186,15 @@ public class VLobby {
|
||||
playersFrame.setOpaque(false);
|
||||
playersFrame.add(playersScroll, "w 100%, h 100%-35px");
|
||||
|
||||
addPlayerBtn.setFocusable(true);
|
||||
addPlayerBtn.setCommand(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
addPlayer();
|
||||
}
|
||||
});
|
||||
playersFrame.add(addPlayerBtn, "height 30px!, growx, pushx");
|
||||
if (type != LobbyType.CLIENT) {
|
||||
addPlayerBtn.setFocusable(true);
|
||||
addPlayerBtn.setCommand(new Runnable() {
|
||||
@Override public final void run() {
|
||||
addPlayer();
|
||||
}
|
||||
});
|
||||
playersFrame.add(addPlayerBtn, "height 30px!, growx, pushx");
|
||||
}
|
||||
|
||||
constructedFrame.add(playersFrame, "gapright 10px, w 50%-5px, growy, pushy");
|
||||
|
||||
@@ -194,8 +209,10 @@ public class VLobby {
|
||||
decksFrame.setOpaque(false);
|
||||
|
||||
// Start Button
|
||||
pnlStart.setOpaque(false);
|
||||
pnlStart.add(btnStart, "align center");
|
||||
if (type != LobbyType.CLIENT) {
|
||||
pnlStart.setOpaque(false);
|
||||
pnlStart.add(btnStart, "align center");
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (final PlayerPanel pp : getPlayerPanels()) {
|
||||
if (pp.isVisible() && pp.isOpen()) {
|
||||
addPlayer(pp.getIndex());
|
||||
if (pp.isVisible() && (
|
||||
pp.getType() == LobbySlotType.OPEN || (pp.isLocal() && type == LobbyType.SERVER))) {
|
||||
final int index = pp.getIndex();
|
||||
addPlayer(index);
|
||||
pp.setPlayerName(name);
|
||||
pp.setRemote(true);
|
||||
System.out.println("Put player " + name + " in slot " + index);
|
||||
|
||||
return;
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
private void addPlayer() {
|
||||
if (activePlayersNum >= MAX_PLAYERS) {
|
||||
@@ -250,10 +270,12 @@ public class VLobby {
|
||||
|
||||
playerPanels.get(slot).setVisible(true);
|
||||
playerPanels.get(slot).focusOnAvatar();
|
||||
|
||||
firePlayerChangeListener();
|
||||
}
|
||||
|
||||
void removePlayer(final int playerIndex) {
|
||||
if (activePlayersNum < playerIndex) {
|
||||
if (activePlayersNum <= playerIndex) {
|
||||
return;
|
||||
}
|
||||
activePlayersNum--;
|
||||
@@ -279,6 +301,69 @@ public class VLobby {
|
||||
changePlayerFocus(closest);
|
||||
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.
|
||||
@@ -373,7 +458,7 @@ public class VLobby {
|
||||
private void populateDeckPanel(final GameType forGameType) {
|
||||
decksFrame.removeAll();
|
||||
|
||||
if (playerPanelWithFocus.isOpen() || playerPanelWithFocus.isRemote()) {
|
||||
if (playerPanelWithFocus.getType() == LobbySlotType.OPEN || playerPanelWithFocus.getType() == LobbySlotType.REMOTE) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -439,8 +524,8 @@ public class VLobby {
|
||||
return deckChoosers.get(playernum);
|
||||
}
|
||||
|
||||
public List<Integer> getTeams() { return Collections.unmodifiableList(teams); }
|
||||
public List<Integer> getArchenemyTeams() { return Collections.unmodifiableList(archenemyTeams); }
|
||||
public List<Integer> getTeams() { return teams; }
|
||||
public List<Integer> getArchenemyTeams() { return archenemyTeams; }
|
||||
public GameType getCurrentGameMode() { return currentGameMode; }
|
||||
public void setCurrentGameMode(final GameType mode) { currentGameMode = mode; }
|
||||
|
||||
|
||||
@@ -3,12 +3,17 @@ package forge.screens.home.online;
|
||||
import forge.UiCommand;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.screens.home.CLobby;
|
||||
import forge.screens.home.VLobby;
|
||||
|
||||
public enum COnlineLobby implements ICDoc {
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
private final VOnlineLobby view = VOnlineLobby.SINGLETON_INSTANCE;
|
||||
private final CLobby lobby = new CLobby(view.getLobby());
|
||||
private CLobby lobby;
|
||||
|
||||
void setLobby(VLobby lobbyView) {
|
||||
lobby = new CLobby(lobbyView);
|
||||
initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
@@ -19,7 +24,9 @@ public enum COnlineLobby implements ICDoc {
|
||||
*/
|
||||
@Override
|
||||
public void update() {
|
||||
lobby.update();
|
||||
if (lobby != null) {
|
||||
lobby.update();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -27,7 +34,9 @@ public enum COnlineLobby implements ICDoc {
|
||||
*/
|
||||
@Override
|
||||
public void initialize() {
|
||||
lobby.initialize();
|
||||
if (lobby != null) {
|
||||
lobby.initialize();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -13,40 +13,71 @@ import forge.game.GameType;
|
||||
import forge.gui.FNetOverlay;
|
||||
import forge.gui.framework.FScreen;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.interfaces.IPlayerChangeListener;
|
||||
import forge.menus.IMenuProvider;
|
||||
import forge.menus.MenuUtil;
|
||||
import forge.model.FModel;
|
||||
import forge.net.FGameClient;
|
||||
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.server.RemoteClient;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.screens.home.VLobby;
|
||||
import forge.screens.home.VLobby.LobbyType;
|
||||
import forge.screens.home.sanctioned.ConstructedGameMenu;
|
||||
|
||||
public enum CSubmenuOnlineLobby implements ICDoc, IMenuProvider {
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
final void host(final int portNumber) {
|
||||
final VLobby lobby = VOnlineLobby.SINGLETON_INSTANCE.setLobby(LobbyType.SERVER);
|
||||
|
||||
FServerManager.getInstance().startServer(portNumber);
|
||||
FServerManager.getInstance().registerLobbyListener(new ILobbyListener() {
|
||||
@Override public final void logout(final RemoteClient client) {
|
||||
FServerManager.getInstance().setLobby(lobby);
|
||||
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) {
|
||||
FNetOverlay.SINGLETON_INSTANCE.addMessage(source, message);
|
||||
}
|
||||
});
|
||||
FServerManager.getInstance().hostGame(new GameRules(GameType.Constructed));
|
||||
client.connect("localhost", portNumber);
|
||||
|
||||
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 FGameClient client = new FGameClient(FModel.getPreferences().getPref(FPref.PLAYER_NAME), "0", GuiBase.getInterface().getNewGuiGame());
|
||||
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);
|
||||
|
||||
Singletons.getControl().setCurrentScreen(FScreen.ONLINE_LOBBY);
|
||||
|
||||
@@ -13,6 +13,7 @@ import forge.gui.framework.FScreen;
|
||||
import forge.gui.framework.IVDoc;
|
||||
import forge.gui.framework.IVTopLevelUI;
|
||||
import forge.screens.home.VLobby;
|
||||
import forge.screens.home.VLobby.LobbyType;
|
||||
import forge.toolbox.FPanel;
|
||||
import forge.util.gui.SOptionPane;
|
||||
import forge.view.FView;
|
||||
@@ -24,15 +25,19 @@ public enum VOnlineLobby implements IVDoc<COnlineLobby>, IVTopLevelUI {
|
||||
private final DragTab tab = new DragTab("Lobby");
|
||||
|
||||
// General variables
|
||||
private final VLobby lobby;
|
||||
private VLobby lobby;
|
||||
|
||||
private VOnlineLobby() {
|
||||
this.lobby = new VLobby(true);
|
||||
}
|
||||
|
||||
VLobby getLobby() {
|
||||
return lobby;
|
||||
}
|
||||
VLobby setLobby(final LobbyType type) {
|
||||
this.lobby = new VLobby(type);
|
||||
getLayoutControl().setLobby(lobby);
|
||||
return this.lobby;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populate() {
|
||||
|
||||
@@ -13,6 +13,7 @@ import forge.screens.home.EMenuGroup;
|
||||
import forge.screens.home.IVSubmenu;
|
||||
import forge.screens.home.VLobby;
|
||||
import forge.screens.home.VHomeUI;
|
||||
import forge.screens.home.VLobby.LobbyType;
|
||||
|
||||
/**
|
||||
* Assembles Swing components of constructed submenu singleton.
|
||||
@@ -27,7 +28,7 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
|
||||
private DragCell parentCell;
|
||||
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() {
|
||||
}
|
||||
|
||||
|
||||
@@ -46,5 +46,11 @@
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.0.25.Final</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
10
forge-gui/src/main/java/forge/interfaces/ILobby.java
Normal file
10
forge-gui/src/main/java/forge/interfaces/ILobby.java
Normal 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);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package forge.interfaces;
|
||||
|
||||
import forge.net.game.LobbyState.LobbyPlayerData;
|
||||
|
||||
public interface IPlayerChangeListener {
|
||||
void update(LobbyPlayerData data);
|
||||
}
|
||||
@@ -14,15 +14,23 @@ import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.handler.codec.serialization.ClassResolvers;
|
||||
import io.netty.handler.codec.serialization.ObjectDecoder;
|
||||
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.player.PlayerView;
|
||||
import forge.interfaces.IGuiGame;
|
||||
import forge.model.FModel;
|
||||
import forge.net.game.GuiGameEvent;
|
||||
import forge.net.game.LobbyUpdateEvent;
|
||||
import forge.net.game.LoginEvent;
|
||||
import forge.net.game.MessageEvent;
|
||||
import forge.net.game.NetEvent;
|
||||
import forge.net.game.client.ILobbyListener;
|
||||
import forge.net.game.client.IToServer;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
|
||||
public class FGameClient implements IToServer {
|
||||
private final IGuiGame clientGui;
|
||||
@@ -30,6 +38,8 @@ public class FGameClient implements IToServer {
|
||||
this.clientGui = clientGui;
|
||||
}
|
||||
|
||||
private final List<ILobbyListener> lobbyListeners = Lists.newArrayList();
|
||||
|
||||
static final int SIZE = Integer.parseInt(System.getProperty("size", "256"));
|
||||
|
||||
private Channel channel;
|
||||
@@ -47,6 +57,7 @@ public class FGameClient implements IToServer {
|
||||
new ObjectEncoder(),
|
||||
new ObjectDecoder(ClassResolvers.cacheDisabled(null)),
|
||||
new MessageHandler(),
|
||||
new LobbyUpdateHandler(),
|
||||
new GameClientHandler());
|
||||
}
|
||||
});
|
||||
@@ -74,6 +85,10 @@ public class FGameClient implements IToServer {
|
||||
channel.writeAndFlush(event);
|
||||
}
|
||||
|
||||
public void addLobbyListener(final ILobbyListener listener) {
|
||||
lobbyListeners.add(listener);
|
||||
}
|
||||
|
||||
private class GameClientHandler extends ChannelInboundHandlerAdapter {
|
||||
/**
|
||||
* Creates a client-side handler.
|
||||
@@ -83,7 +98,8 @@ public class FGameClient implements IToServer {
|
||||
|
||||
@Override
|
||||
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")
|
||||
@@ -116,7 +132,21 @@ public class FGameClient implements IToServer {
|
||||
public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
|
||||
if (msg instanceof MessageEvent) {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package forge.net;
|
||||
|
||||
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.LogoutEvent;
|
||||
import forge.net.game.MessageEvent;
|
||||
import forge.net.game.NetEvent;
|
||||
import forge.net.game.RegisterDeckEvent;
|
||||
import forge.net.game.client.ILobbyListener;
|
||||
import forge.net.game.server.RemoteClient;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
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.LoggingHandler;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public final class FServerManager {
|
||||
@@ -39,7 +39,7 @@ public final class FServerManager {
|
||||
private final Map<Integer, NetGame> games = Maps.newTreeMap();
|
||||
private int id = 0;
|
||||
private final Map<Channel, RemoteClient> clients = Maps.newTreeMap();
|
||||
private final List<ILobbyListener> lobbyListeners = Lists.newArrayListWithExpectedSize(1);
|
||||
private ILobby localLobby;
|
||||
|
||||
private FServerManager() {
|
||||
}
|
||||
@@ -102,12 +102,13 @@ public final class FServerManager {
|
||||
|
||||
public void broadcast(final NetEvent event) {
|
||||
for (final RemoteClient client : clients.values()) {
|
||||
event.updateForClient(client);
|
||||
client.send(event);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerLobbyListener(final ILobbyListener lobbyListener) {
|
||||
lobbyListeners.add(lobbyListener);
|
||||
public void setLobby(final ILobby lobby) {
|
||||
this.localLobby = lobby;
|
||||
}
|
||||
|
||||
public NetGame hostGame(final GameRules rules) {
|
||||
@@ -117,6 +118,12 @@ public final class FServerManager {
|
||||
return game;
|
||||
}
|
||||
|
||||
public void updateLobbyState() {
|
||||
final LobbyState state = localLobby.getState();
|
||||
final LobbyUpdateEvent event = new LobbyUpdateEvent(state);
|
||||
broadcast(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
@@ -153,6 +160,7 @@ public final class FServerManager {
|
||||
clients.put(ctx.channel(), client);
|
||||
games.get(0).addClient(client);
|
||||
System.out.println("User connected to server at " + ctx.channel().remoteAddress());
|
||||
updateLobbyState();
|
||||
super.channelActive(ctx);
|
||||
}
|
||||
|
||||
@@ -161,6 +169,7 @@ public final class FServerManager {
|
||||
final RemoteClient client = clients.get(ctx.channel());
|
||||
if (msg instanceof LoginEvent) {
|
||||
client.setUsername(((LoginEvent) msg).getUsername());
|
||||
updateLobbyState();
|
||||
} else if (msg instanceof RegisterDeckEvent) {
|
||||
games.get(0).registerDeck(client, ((RegisterDeckEvent) msg).getDeck());
|
||||
}
|
||||
@@ -173,15 +182,15 @@ public final class FServerManager {
|
||||
final RemoteClient client = clients.get(ctx.channel());
|
||||
if (msg instanceof LoginEvent) {
|
||||
final LoginEvent event = (LoginEvent) msg;
|
||||
for (final ILobbyListener lobbyListener : lobbyListeners) {
|
||||
lobbyListener.login(client);
|
||||
final int index = localLobby.login(client);
|
||||
if (index == -1) {
|
||||
ctx.close();
|
||||
} else {
|
||||
client.setIndex(index);
|
||||
broadcast(event);
|
||||
}
|
||||
broadcast(event);
|
||||
} else if (msg instanceof MessageEvent) {
|
||||
final MessageEvent event = (MessageEvent) msg;
|
||||
for (final ILobbyListener lobbyListener : lobbyListeners) {
|
||||
lobbyListener.message(client.getUsername(), event.getMessage());
|
||||
}
|
||||
broadcast(event);
|
||||
}
|
||||
super.channelRead(ctx, msg);
|
||||
@@ -189,9 +198,8 @@ public final class FServerManager {
|
||||
|
||||
@Override public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
|
||||
final RemoteClient client = clients.get(ctx.channel());
|
||||
for (final ILobbyListener lobbyListener : lobbyListeners) {
|
||||
lobbyListener.logout(client);
|
||||
}
|
||||
localLobby.logout(client);
|
||||
updateLobbyState();
|
||||
super.channelInactive(ctx);
|
||||
}
|
||||
}
|
||||
@@ -205,4 +213,5 @@ public final class FServerManager {
|
||||
super.channelInactive(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,9 +3,11 @@ package forge.net.game;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.net.game.server.RemoteClient;
|
||||
import forge.trackable.TrackableObject;
|
||||
|
||||
public final class GuiGameEvent implements NetEvent {
|
||||
private static final long serialVersionUID = 6223690008522514574L;
|
||||
|
||||
private final String method;
|
||||
private final Iterable<? extends TrackableObject> objects;
|
||||
@@ -15,6 +17,10 @@ public final class GuiGameEvent implements NetEvent {
|
||||
this.objects = objects == null ? ImmutableSet.<TrackableObject>of() : objects;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateForClient(final RemoteClient client) {
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package forge.net.game;
|
||||
|
||||
public enum LobbySlotType {
|
||||
LOCAL,
|
||||
AI,
|
||||
OPEN,
|
||||
REMOTE;
|
||||
}
|
||||
51
forge-net/src/main/java/forge/net/game/LobbyState.java
Normal file
51
forge-net/src/main/java/forge/net/game/LobbyState.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
21
forge-net/src/main/java/forge/net/game/LobbyUpdateEvent.java
Normal file
21
forge-net/src/main/java/forge/net/game/LobbyUpdateEvent.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package forge.net.game;
|
||||
|
||||
import forge.net.game.server.RemoteClient;
|
||||
|
||||
public class LoginEvent implements NetEvent {
|
||||
private static final long serialVersionUID = -8865183377417377938L;
|
||||
|
||||
@@ -8,6 +10,10 @@ public class LoginEvent implements NetEvent {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateForClient(final RemoteClient client) {
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package forge.net.game;
|
||||
|
||||
import forge.net.game.server.RemoteClient;
|
||||
|
||||
public class LogoutEvent implements NetEvent {
|
||||
private static final long serialVersionUID = -8262613254026625787L;
|
||||
|
||||
@@ -8,6 +10,9 @@ public class LogoutEvent implements NetEvent {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public void updateForClient(final RemoteClient client) {
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package forge.net.game;
|
||||
|
||||
import forge.net.game.server.RemoteClient;
|
||||
|
||||
public class MessageEvent implements NetEvent {
|
||||
private static final long serialVersionUID = 1700060210647684186L;
|
||||
|
||||
@@ -8,6 +10,8 @@ public class MessageEvent implements NetEvent {
|
||||
this.source = source;
|
||||
this.message = message;
|
||||
}
|
||||
public void updateForClient(final RemoteClient client) {
|
||||
}
|
||||
|
||||
public String getSource() {
|
||||
return source;
|
||||
|
||||
@@ -2,5 +2,8 @@ package forge.net.game;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import forge.net.game.server.RemoteClient;
|
||||
|
||||
public interface NetEvent extends Serializable {
|
||||
void updateForClient(RemoteClient client);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package forge.net.game;
|
||||
|
||||
import forge.deck.Deck;
|
||||
import forge.net.game.server.RemoteClient;
|
||||
|
||||
public class RegisterDeckEvent implements NetEvent {
|
||||
private static final long serialVersionUID = -6553476654530937343L;
|
||||
@@ -9,6 +10,8 @@ public class RegisterDeckEvent implements NetEvent {
|
||||
public RegisterDeckEvent(final Deck deck) {
|
||||
this.deck = deck;
|
||||
}
|
||||
public void updateForClient(final RemoteClient client) {
|
||||
}
|
||||
|
||||
public final Deck getDeck() {
|
||||
return deck;
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package forge.net.game.client;
|
||||
|
||||
import forge.net.game.server.RemoteClient;
|
||||
import forge.net.game.LobbyState;
|
||||
|
||||
public interface ILobbyListener {
|
||||
void login(RemoteClient client);
|
||||
void logout(RemoteClient client);
|
||||
void message(String source, String message);
|
||||
void update(LobbyState state);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ public final class RemoteClient implements IToClient {
|
||||
|
||||
private final Channel channel;
|
||||
private String username;
|
||||
private int index;
|
||||
public RemoteClient(final Channel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
@@ -22,4 +23,11 @@ public final class RemoteClient implements IToClient {
|
||||
public void setUsername(final String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
public void setIndex(final int index) {
|
||||
this.index = index;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user