- Remove old net code

- Remove "Start/Stop Server" buttons (related to old code)
- Move new net code to forge-gui/forge/net/**
- Remove all dependencies on project forge-net
This commit is contained in:
elcnesh
2015-04-20 14:40:26 +00:00
parent 62a7b2b98d
commit 705d6cb937
41 changed files with 749 additions and 564 deletions

25
.gitattributes vendored
View File

@@ -17671,6 +17671,7 @@ forge-gui/src/main/java/forge/match/AbstractGuiGame.java -text
forge-gui/src/main/java/forge/match/GameLobby.java -text
forge-gui/src/main/java/forge/match/HostedMatch.java -text
forge-gui/src/main/java/forge/match/LobbySlot.java -text
forge-gui/src/main/java/forge/match/LobbySlotType.java -text
forge-gui/src/main/java/forge/match/LocalLobby.java -text
forge-gui/src/main/java/forge/match/MatchButtonType.java -text
forge-gui/src/main/java/forge/match/MatchConstants.java -text
@@ -17705,14 +17706,24 @@ forge-gui/src/main/java/forge/model/MetaSet.java -text
forge-gui/src/main/java/forge/model/MultipleForgeJarsFoundError.java -text
forge-gui/src/main/java/forge/model/UnOpenedMeta.java -text
forge-gui/src/main/java/forge/model/package-info.java svneol=native#text/plain
forge-gui/src/main/java/forge/net/ClientGameLobby.java -text
forge-gui/src/main/java/forge/net/FGameClient.java -text
forge-gui/src/main/java/forge/net/FServerManager.java -text
forge-gui/src/main/java/forge/net/LobbyUpdateEvent.java -text
forge-gui/src/main/java/forge/net/NetGameController.java -text
forge-gui/src/main/java/forge/net/NetGuiGame.java -text
forge-gui/src/main/java/forge/net/ServerGameLobby.java -text
forge-gui/src/main/java/forge/net/IRemote.java -text
forge-gui/src/main/java/forge/net/ReplyPool.java -text
forge-gui/src/main/java/forge/net/client/ClientGameLobby.java -text
forge-gui/src/main/java/forge/net/client/FGameClient.java -text
forge-gui/src/main/java/forge/net/client/GameClientHandler.java -text
forge-gui/src/main/java/forge/net/client/IToServer.java -text
forge-gui/src/main/java/forge/net/client/NetGameController.java -text
forge-gui/src/main/java/forge/net/client/package-info.java -text
forge-gui/src/main/java/forge/net/event/ReplyEvent.java -text
forge-gui/src/main/java/forge/net/event/UpdateLobbyPlayerEvent.java -text
forge-gui/src/main/java/forge/net/event/package-info.java -text
forge-gui/src/main/java/forge/net/package-info.java -text
forge-gui/src/main/java/forge/net/server/FServerManager.java -text
forge-gui/src/main/java/forge/net/server/IToClient.java -text
forge-gui/src/main/java/forge/net/server/NetGuiGame.java -text
forge-gui/src/main/java/forge/net/server/RemoteClient.java -text
forge-gui/src/main/java/forge/net/server/ServerGameLobby.java -text
forge-gui/src/main/java/forge/net/server/package-info.java -text
forge-gui/src/main/java/forge/planarconquest/ConquestAction.java -text
forge-gui/src/main/java/forge/planarconquest/ConquestCommander.java -text
forge-gui/src/main/java/forge/planarconquest/ConquestController.java -text

View File

@@ -62,11 +62,6 @@
<artifactId>forge-ai</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>forge</groupId>
<artifactId>forge-net</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>forge</groupId>
<artifactId>forge-gui</artifactId>

View File

@@ -174,11 +174,6 @@
<artifactId>forge-ai</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>forge</groupId>
<artifactId>forge-net</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>forge</groupId>
<artifactId>forge-gui</artifactId>

View File

@@ -18,8 +18,8 @@ import org.apache.commons.lang3.StringUtils;
import forge.Singletons;
import forge.gui.framework.SDisplayUtil;
import forge.model.FModel;
import forge.net.game.IRemote;
import forge.net.game.MessageEvent;
import forge.net.IRemote;
import forge.net.event.MessageEvent;
import forge.properties.ForgePreferences;
import forge.properties.ForgePreferences.FPref;
import forge.toolbox.FLabel;

View File

@@ -6,14 +6,11 @@ import javax.swing.JMenu;
import forge.Singletons;
import forge.UiCommand;
import forge.gui.FNetOverlay;
import forge.gui.framework.EDocID;
import forge.gui.framework.ICDoc;
import forge.menus.IMenuProvider;
import forge.menus.MenuUtil;
import forge.model.FModel;
import forge.net.FServer;
import forge.net.FServerManager;
import forge.properties.ForgePreferences;
import forge.properties.ForgePreferences.FPref;
import forge.screens.home.sanctioned.VSubmenuConstructed;
@@ -83,31 +80,6 @@ public enum CHomeUI implements ICDoc, IMenuProvider {
Singletons.getControl().getForgeMenu().setProvider(this);
selectPrevious();
VHomeUI.SINGLETON_INSTANCE.getLblStartServer().setCommand(new Runnable() {
@Override
public void run() {
//final NetServer srv = FServer.getServer();
//srv.listen(ForgeConstants.SERVER_PORT_NUMBER);
VHomeUI.SINGLETON_INSTANCE.getLblStopServer().setEnabled(true);
VHomeUI.SINGLETON_INSTANCE.getLblStartServer().setEnabled(false);
FNetOverlay.SINGLETON_INSTANCE.showUp("");//"Server listening on port " + srv.getPortNumber());
}
});
VHomeUI.SINGLETON_INSTANCE.getLblStopServer().setCommand(new Runnable() {
@Override
public void run() {
FServer.getServer().stop();
FServerManager.getInstance().stopServer();
VHomeUI.SINGLETON_INSTANCE.getLblStopServer().setEnabled(false);
VHomeUI.SINGLETON_INSTANCE.getLblStartServer().setEnabled(true);
FNetOverlay.SINGLETON_INSTANCE.getWindow().setVisible(false);
}
});
}
/* (non-Javadoc)

View File

@@ -30,8 +30,8 @@ import forge.game.GameType;
import forge.gui.framework.FScreen;
import forge.item.PaperCard;
import forge.match.LobbySlot;
import forge.match.LobbySlotType;
import forge.model.FModel;
import forge.net.game.LobbySlotType;
import forge.properties.ForgePreferences;
import forge.properties.ForgePreferences.FPref;
import forge.screens.deckeditor.CDeckEditorUI;

View File

@@ -41,7 +41,6 @@ import forge.gui.framework.ICDoc;
import forge.gui.framework.ILocalRepaint;
import forge.gui.framework.IVTopLevelUI;
import forge.model.FModel;
import forge.properties.ForgeConstants;
import forge.properties.ForgePreferences.FPref;
import forge.screens.home.gauntlet.VSubmenuGauntletBuild;
import forge.screens.home.gauntlet.VSubmenuGauntletContests;
@@ -97,35 +96,17 @@ public enum VHomeUI implements IVTopLevelUI {
.iconAlignX(SwingConstants.CENTER)
.iconInBackground(true).iconScaleFactor(1.0).build();
private final FLabel lblStartServer = new FLabel.ButtonBuilder().text("Start Server").fontSize(14).build();
private final FLabel lblStopServer = new FLabel.ButtonBuilder().text("Stop Server").fontSize(14).build();
private VHomeUI() {
// Add main menu containing logo and menu buttons
final JPanel pnlMainMenu = new JPanel(new MigLayout("w 200px!, ax center, insets 0, gap 0, wrap"));
pnlMainMenu.setOpaque(false);
final List<FLabel> mainMenuButtons = new ArrayList<FLabel>();
if (ForgeConstants.SERVER_PORT_NUMBER >= 80) {
mainMenuButtons.add(lblStartServer);
mainMenuButtons.add(lblStopServer);
lblStopServer.setEnabled(false);
}
final int logoSize = 170;
final int logoBottomGap = 4;
final int buttonHeight = 30;
final int buttonBottomGap = 8;
final int pnlMainMenuHeight = logoSize + logoBottomGap +
mainMenuButtons.size() * (buttonHeight + buttonBottomGap);
final int pnlMainMenuHeight = logoSize + logoBottomGap;
pnlMainMenu.add(lblLogo, "w " + logoSize + "px!, h " + logoSize +
"px!, gap 0 4px 0 " + logoBottomGap + "px");
String buttonLayout = "w 170px!, h " + buttonHeight +
"px!, gap 0 0 0 " + buttonBottomGap + "px";
for (FLabel button : mainMenuButtons) {
pnlMainMenu.add(button, buttonLayout);
}
pnlMenu.add(pnlMainMenu);
pnlSubmenus = new FScrollPanel(new MigLayout("insets 0, gap 0, wrap, hidemode 3"), true,
@@ -137,7 +118,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);
@@ -189,14 +170,6 @@ public enum VHomeUI implements IVTopLevelUI {
pnlDisplay.setBackground(l00.alphaColor(100));
}
public final FLabel getLblStartServer() {
return lblStartServer;
}
public final FLabel getLblStopServer() {
return lblStopServer;
}
/** @return {@link javax.swing.JPanel} */
public JPanel getPnlMenu() {
return pnlMenu;

View File

@@ -42,9 +42,9 @@ import forge.interfaces.IUpdateable;
import forge.item.PaperCard;
import forge.match.GameLobby;
import forge.match.LobbySlot;
import forge.match.LobbySlotType;
import forge.model.FModel;
import forge.net.game.LobbySlotType;
import forge.net.game.UpdateLobbyPlayerEvent;
import forge.net.event.UpdateLobbyPlayerEvent;
import forge.properties.ForgePreferences;
import forge.properties.ForgePreferences.FPref;
import forge.toolbox.FCheckBox;

View File

@@ -20,15 +20,15 @@ import forge.match.GameLobby.GameLobbyData;
import forge.menus.IMenuProvider;
import forge.menus.MenuUtil;
import forge.model.FModel;
import forge.net.ClientGameLobby;
import forge.net.FGameClient;
import forge.net.FServerManager;
import forge.net.ServerGameLobby;
import forge.net.game.IRemote;
import forge.net.game.IdentifiableNetEvent;
import forge.net.game.MessageEvent;
import forge.net.game.NetEvent;
import forge.net.game.UpdateLobbyPlayerEvent;
import forge.net.IRemote;
import forge.net.client.ClientGameLobby;
import forge.net.client.FGameClient;
import forge.net.event.IdentifiableNetEvent;
import forge.net.event.MessageEvent;
import forge.net.event.NetEvent;
import forge.net.event.UpdateLobbyPlayerEvent;
import forge.net.server.FServerManager;
import forge.net.server.ServerGameLobby;
import forge.properties.ForgePreferences.FPref;
import forge.screens.home.VLobby;
import forge.screens.home.sanctioned.ConstructedGameMenu;

View File

@@ -14,8 +14,8 @@ import forge.gui.framework.FScreen;
import forge.gui.framework.IVDoc;
import forge.gui.framework.IVTopLevelUI;
import forge.match.GameLobby;
import forge.net.FGameClient;
import forge.net.FServerManager;
import forge.net.client.FGameClient;
import forge.net.server.FServerManager;
import forge.screens.home.VLobby;
import forge.toolbox.FPanel;
import forge.util.gui.SOptionPane;

View File

@@ -12,7 +12,7 @@ import forge.gui.framework.EDocID;
import forge.interfaces.IPlayerChangeListener;
import forge.match.GameLobby;
import forge.match.LocalLobby;
import forge.net.game.UpdateLobbyPlayerEvent;
import forge.net.event.UpdateLobbyPlayerEvent;
import forge.screens.home.EMenuGroup;
import forge.screens.home.IVSubmenu;
import forge.screens.home.VHomeUI;

View File

@@ -10,7 +10,6 @@
<classpathentry combineaccessrules="false" kind="src" path="/forge-game"/>
<classpathentry combineaccessrules="false" kind="src" path="/forge-gui"/>
<classpathentry combineaccessrules="false" kind="src" path="/forge-gui-mobile"/>
<classpathentry combineaccessrules="false" kind="src" path="/forge-net"/>
<classpathentry combineaccessrules="false" kind="src" path="/forge-ai"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
<attributes>
@@ -24,7 +23,9 @@
</classpathentry>
<classpathentry kind="lib" path="minlog-1.2.jar"/>
<classpathentry kind="lib" path="libs/gdx-backend-robovm.jar"/>
<classpathentry kind="lib" path="/forge-gui-mobile/libs/gdx.jar" sourcepath="libs/gdx-sources.jar"/>
<classpathentry kind="lib" path="/forge-gui-mobile/libs/gdx-freetype.jar"/>
<classpathentry kind="lib" path="/forge-gui-mobile/libs/gdx.jar" sourcepath="/forge-gui-mobile/libs/gdx-sources.jar"/>
<classpathentry kind="con" path="org.robovm.eclipse.ROBOVM_CONTAINER"/>
<classpathentry kind="con" path="org.robovm.eclipse.ROBOVM_COCOA_TOUCH_CONTAINER"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@@ -56,11 +56,6 @@
<artifactId>forge-ai</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>forge</groupId>
<artifactId>forge-net</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>forge</groupId>
<artifactId>forge-gui</artifactId>

View File

@@ -35,11 +35,6 @@
<artifactId>forge-ai</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>forge</groupId>
<artifactId>forge-net</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>forge</groupId>
<artifactId>forge-gui</artifactId>

View File

@@ -8,7 +8,7 @@ Forge Beta: #-#-2015 ver 1.5.39
Release Notes
-------------
Interface Update
- Interface Update -
The interface has received several small changes.
- The "Players" panel has been removed. This information can now be viewed by
hovering the cursor over a player's avatar.
@@ -17,6 +17,14 @@ The interface has received several small changes.
- The poison counters button has been replaced with a Command Zone button.
The command zone panels have been removed.
- Network play (BETA) -
This version of Forge includes a preliminary version of peer-to-peer (P2P)
network support. If one player hosts, other players can connect to that
player's machine by filling out the corresponding IP address and port number
(default 36743), provided the lobby contains one or more open player slots.
Do not expect network support to work reliably yet, any bug reports or other
comments are welcome!
- Smarter Deck Color Determination -
When determining the color of decks, colors of hybrid and phyrexian cards are no
longer considered unless they can be produced by a land in the deck

View File

@@ -35,11 +35,6 @@
<groupId>forge</groupId>
<artifactId>forge-ai</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>forge</groupId>
<artifactId>forge-net</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>

View File

@@ -1,7 +1,7 @@
package forge.interfaces;
import forge.match.GameLobby;
import forge.net.game.server.RemoteClient;
import forge.net.server.RemoteClient;
public interface ILobby {
GameLobby getState();

View File

@@ -1,6 +1,6 @@
package forge.interfaces;
import forge.net.game.UpdateLobbyPlayerEvent;
import forge.net.event.UpdateLobbyPlayerEvent;
public interface IPlayerChangeListener {
void update(int index, UpdateLobbyPlayerEvent event);

View File

@@ -30,8 +30,7 @@ import forge.interfaces.IGuiGame;
import forge.interfaces.IUpdateable;
import forge.item.PaperCard;
import forge.model.FModel;
import forge.net.game.LobbySlotType;
import forge.net.game.UpdateLobbyPlayerEvent;
import forge.net.event.UpdateLobbyPlayerEvent;
import forge.player.GamePlayerUtil;
import forge.properties.ForgePreferences.FPref;
import forge.util.NameGenerator;

View File

@@ -7,8 +7,7 @@ import com.google.common.collect.ImmutableSet;
import forge.AIOption;
import forge.deck.Deck;
import forge.net.game.LobbySlotType;
import forge.net.game.UpdateLobbyPlayerEvent;
import forge.net.event.UpdateLobbyPlayerEvent;
public final class LobbySlot implements Serializable {
private static final long serialVersionUID = 6918205436608794289L;

View File

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

View File

@@ -5,7 +5,6 @@ import java.util.Collections;
import forge.AIOption;
import forge.GuiBase;
import forge.interfaces.IGuiGame;
import forge.net.game.LobbySlotType;
public final class LocalLobby extends GameLobby {

View File

@@ -1,398 +0,0 @@
package forge.net;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
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 java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeoutException;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import forge.FThreads;
import forge.UiCommand;
import forge.assets.FSkinProp;
import forge.deck.CardPool;
import forge.game.GameEntityView;
import forge.game.GameView;
import forge.game.card.CardView;
import forge.game.phase.PhaseType;
import forge.game.player.DelayedReveal;
import forge.game.player.PlayerView;
import forge.game.spellability.SpellAbilityView;
import forge.game.zone.ZoneType;
import forge.interfaces.IButton;
import forge.interfaces.IGuiGame;
import forge.interfaces.ILobbyListener;
import forge.match.MatchButtonType;
import forge.model.FModel;
import forge.net.game.GuiGameEvent;
import forge.net.game.IdentifiableNetEvent;
import forge.net.game.LoginEvent;
import forge.net.game.MessageEvent;
import forge.net.game.NetEvent;
import forge.net.game.ReplyEvent;
import forge.net.game.client.IToServer;
import forge.player.PlayerZoneUpdates;
import forge.properties.ForgePreferences.FPref;
import forge.trackable.TrackableCollection;
import forge.util.ITriggerEvent;
public class FGameClient implements IToServer {
private final IGuiGame clientGui;
public FGameClient(final String username, final String roomKey, final IGuiGame clientGui) {
this.clientGui = clientGui;
}
private final List<ILobbyListener> lobbyListeners = Lists.newArrayList();
private final ReplyPool replies = new ReplyPool();
static final int SIZE = Integer.parseInt(System.getProperty("size", "256"));
private Channel channel;
public void connect(final String host, final int port) {
final EventLoopGroup group = new NioEventLoopGroup();
try {
final Bootstrap b = new Bootstrap()
.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(final SocketChannel ch) throws Exception {
final ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(
new ObjectEncoder(),
new ObjectDecoder(ClassResolvers.cacheDisabled(null)),
new MessageHandler(),
new LobbyUpdateHandler(),
new GameClientHandler());
}
});
// Start the connection attempt.
channel = b.connect(host, port).sync().channel();
final ChannelFuture ch = channel.closeFuture();
new Thread(new Runnable() {
@Override public void run() {
try {
ch.sync();
} catch (final InterruptedException e) {
e.printStackTrace();
} finally {
group.shutdownGracefully();
}
}
}).start();
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
public void close() {
channel.close();
}
@Override
public void send(final NetEvent event) {
System.out.println("Client sent " + event);
channel.writeAndFlush(event);
}
@Override
public Object sendAndWait(final IdentifiableNetEvent event) throws TimeoutException {
replies.initialize(event.getId());
send(event);
// Wait for reply
return replies.get(event.getId());
}
public void addLobbyListener(final ILobbyListener listener) {
lobbyListeners.add(listener);
}
private void setGameControllers(final Iterable<PlayerView> myPlayers) {
for (final PlayerView p : myPlayers) {
clientGui.setGameController(p, new NetGameController(this));
}
}
private class GameClientHandler extends ChannelInboundHandlerAdapter {
/**
* Creates a client-side handler.
*/
public GameClientHandler() {
}
@Override
public void channelActive(final ChannelHandlerContext ctx) {
// Don't use send() here, as this.channel is not yet set!
ctx.channel().writeAndFlush(new LoginEvent(FModel.getPreferences().getPref(FPref.PLAYER_NAME), Integer.parseInt(FModel.getPreferences().getPref(FPref.UI_AVATARS).split(",")[0])));
}
@SuppressWarnings("unchecked")
@Override
public void channelRead(final ChannelHandlerContext ctx, final Object msg) {
System.out.println("Client received: " + msg);
if (msg instanceof ReplyEvent) {
final ReplyEvent event = (ReplyEvent) msg;
replies.complete(event.getIndex(), event.getReply());
} else if (msg instanceof GuiGameEvent) {
final GuiGameEvent event = (GuiGameEvent) msg;
final String method = event.getMethod();
final Object[] args = event.getObjects();
Serializable reply = null;
boolean doReply = false;
final IButton btn;
if (method.startsWith("btn_") && args.length >= 2 && args[0] instanceof PlayerView && args[1] instanceof MatchButtonType) {
btn = args[1] == MatchButtonType.OK ? clientGui.getBtnOK((PlayerView) args[0]) : clientGui.getBtnCancel((PlayerView) args[0]);
} else {
btn = null;
}
switch (method) {
case "setGameView":
clientGui.setGameView((GameView) args[0]);
break;
case "openView":
final TrackableCollection<PlayerView> myPlayers = (TrackableCollection<PlayerView>) args[0];
setGameControllers(myPlayers);
FThreads.invokeInEdtNowOrLater(new Runnable() {
@Override public final void run() {
//clientGui.setGameView(new NetGameView(FGameClient.this));
clientGui.openView(myPlayers);
}
});
break;
case "afterGameEnd":
clientGui.afterGameEnd();
break;
case "showCombat":
clientGui.showCombat();
break;
case "showPromptMessage":
clientGui.showPromptMessage((PlayerView) args[0], (String) args[1]);
break;
case "stopAtPhase":
reply = clientGui.stopAtPhase((PlayerView) args[0], (PhaseType) args[1]);
doReply = true;
break;
case "focusButton":
clientGui.focusButton((MatchButtonType) args[0]);
break;
case "flashIncorrectAction":
clientGui.flashIncorrectAction();
break;
case "updatePhase":
clientGui.updatePhase();
break;
case "updateTurn":
FThreads.invokeInEdtNowOrLater(new Runnable() {
@Override public final void run() {
clientGui.updateTurn((PlayerView) args[0]);
}
});
break;
case "udpdatePlayerControl":
clientGui.updatePlayerControl();
break;
case "enableOverlay":
clientGui.enableOverlay();
break;
case "disbleOverlay":
clientGui.disableOverlay();
break;
case "finishGame":
clientGui.finishGame();
break;
case "showManaPool":
clientGui.showManaPool((PlayerView) args[0]);
break;
case "hideManaPool":
clientGui.hideManaPool((PlayerView) args[0], args[1]);
break;
case "updateStack":
clientGui.updateStack();
break;
case "updateZones":
FThreads.invokeInEdtNowOrLater(new Runnable() {
@Override public final void run() {
clientGui.updateZones((PlayerZoneUpdates) args[0]);
}
});
break;
case "updateSingleCard":
clientGui.updateSingleCard((CardView) args[0]);
break;
case "updateManaPool":
clientGui.updateManaPool((Iterable<PlayerView>) args[0]);
break;
case "updateLives":
clientGui.updateLives((Iterable<PlayerView>) args[0]);
break;
case "setPanelSelection":
clientGui.setPanelSelection((CardView) args[0]);
break;
case "getAbilityToPlay":
reply = clientGui.getAbilityToPlay((List<SpellAbilityView>) args[0], (ITriggerEvent) args[1]);
doReply = true;
break;
case "assignDamage":
reply = (Serializable) clientGui.assignDamage((CardView) args[0], (List<CardView>) args[1], (int) args[2], (GameEntityView) args[3], (boolean) args[4]);
doReply = true;
break;
case "message":
clientGui.message((String) args[0], (String) args[1]);
break;
case "showErrorDialog":
clientGui.showErrorDialog((String) args[0], (String) args[1]);
break;
case "showConfirmDialog":
reply = clientGui.showConfirmDialog((String) args[0], (String) args[1], (String) args[2], (String) args[3], (boolean) args[4]);
doReply = true;
break;
case "showOptionDialog":
reply = clientGui.showOptionDialog((String) args[0], (String) args[1], (FSkinProp) args[2], (String[]) args[3], (int) args[4]);
doReply = true;
break;
case "showCardOptionDialog":
reply = clientGui.showCardOptionDialog((CardView) args[0], (String) args[1], (String) args[2], (FSkinProp) args[3], (String[]) args[4], (int) args[5]);
doReply = true;
break;
case "showInputDialog":
reply = clientGui.showInputDialog((String) args[0], (String) args[1], (FSkinProp) args[2], (String) args[3], (String[]) args[4]);
doReply = true;
break;
case "confirm":
reply = clientGui.confirm((CardView) args[0], (String) args[1], (boolean) args[2], (String[]) args[3]);
doReply = true;
break;
case "getChoices":
reply = (Serializable) clientGui.getChoices((String) args[0], (int) args[1], (int) args[2], (Collection<Object>) args[3], args[4], (Function<Object, String>) args[5]);
doReply = true;
break;
case "order":
reply = (Serializable) clientGui.order((String) args[0], (String) args[1], (int) args[2], (int) args[3], (List<Object>) args[4], (List<Object>) args[5], (CardView) args[6], (boolean) args[7]);
doReply = true;
break;
case "sideboard":
reply = (Serializable) clientGui.sideboard((CardPool) args[0], (CardPool) args[1]);
doReply = true;
break;
case "chooseSingleEntityForEffect":
reply = clientGui.chooseSingleEntityForEffect((String) args[0], (TrackableCollection<GameEntityView>) args[1], (DelayedReveal) args[2], (boolean) args[3]);
doReply = true;
break;
case "setCard":
clientGui.setCard((CardView) args[0]);
break;
// TODO case "setPlayerAvatar":
case "openZones":
reply = clientGui.openZones((Collection<ZoneType>) args[0], (Map<PlayerView, Object>) args[1]);
doReply = true;
break;
case "restoreOldZones":
clientGui.restoreOldZones((Map<PlayerView, Object>) args[0]);
break;
case "isUiSetToSkipPhase":
reply = clientGui.isUiSetToSkipPhase((PlayerView) args[0], (PhaseType) args[1]);
doReply = true;
break;
// BUTTONS
case "btn_setEnabled":
btn.setEnabled((boolean) args[2]);
break;
case "btn_setVisible":
btn.setVisible((boolean) args[2]);
break;
case "btn_setText":
btn.setText((String) args[2]);
break;
case "btn_isSelected":
reply = btn.isSelected();
doReply = true;
break;
case "btn_setSelected":
btn.setSelected((boolean) args[2]);
break;
case "btn_requestFocusInWindows":
reply = btn.requestFocusInWindow();
doReply = true;
break;
case "btn_setCommand":
btn.setCommand((UiCommand) args[2]);
break;
case "btn_setTextColor":
if (args.length == 3) {
btn.setTextColor((FSkinProp) args[2]);
} else {
btn.setTextColor((int) args[2], (int) args[3], (int) args[4]);
}
default:
System.err.println("Unsupported game event " + event.getMethod());
break;
}
if (doReply) {
send(new ReplyEvent(event.getId(), reply));
}
}
}
@Override
public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
private class MessageHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
if (msg instanceof MessageEvent) {
final MessageEvent event = (MessageEvent) msg;
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) {
final LobbyUpdateEvent event = (LobbyUpdateEvent) msg;
listener.update(event.getState(), event.getSlot());
}
}
super.channelRead(ctx, msg);
}
@Override
public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
for (final ILobbyListener listener : lobbyListeners) {
listener.close();
}
super.channelInactive(ctx);
}
}
}

View File

@@ -0,0 +1,11 @@
package forge.net;
import java.util.concurrent.TimeoutException;
import forge.net.event.IdentifiableNetEvent;
import forge.net.event.NetEvent;
public interface IRemote {
void send(NetEvent event);
Object sendAndWait(IdentifiableNetEvent event) throws TimeoutException;
}

View File

@@ -1,28 +0,0 @@
package forge.net;
import forge.match.GameLobby.GameLobbyData;
import forge.net.game.NetEvent;
import forge.net.game.server.RemoteClient;
public class LobbyUpdateEvent implements NetEvent {
private static final long serialVersionUID = 7114918637727047985L;
private final GameLobbyData state;
private int slot;
public LobbyUpdateEvent(final GameLobbyData state) {
this.state = state;
}
@Override
public void updateForClient(final RemoteClient client) {
this.slot = client.getIndex();
}
public GameLobbyData getState() {
return state;
}
public int getSlot() {
return slot;
}
}

View File

@@ -0,0 +1,57 @@
package forge.net;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import com.google.common.collect.Maps;
public class ReplyPool {
private final Map<Integer, CompletableFuture> pool = Maps.newHashMap();
public ReplyPool() {
}
public void initialize(final int index) {
synchronized (pool) {
pool.put(Integer.valueOf(index), new CompletableFuture());
}
}
public void complete(final int index, final Object value) {
synchronized (pool) {
pool.get(Integer.valueOf(index)).set(value);
}
}
public Object get(final int index) throws TimeoutException {
final CompletableFuture future;
synchronized (pool) {
future = pool.get(Integer.valueOf(index));
}
try {
return future.get(1, TimeUnit.MINUTES);
} catch (final InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
private static final class CompletableFuture extends FutureTask<Object> {
public CompletableFuture() {
super(new Callable<Object>() {
@Override public Object call() throws Exception {
return null;
}
});
}
@Override
public void set(final Object v) {
super.set(v);
}
}
}

View File

@@ -1,4 +1,4 @@
package forge.net;
package forge.net.client;
import forge.interfaces.IGuiGame;
import forge.match.GameLobby;

View File

@@ -0,0 +1,151 @@
package forge.net.client;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
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 java.util.List;
import java.util.concurrent.TimeoutException;
import com.google.common.collect.Lists;
import forge.game.player.PlayerView;
import forge.interfaces.IGuiGame;
import forge.interfaces.ILobbyListener;
import forge.net.ReplyPool;
import forge.net.event.IdentifiableNetEvent;
import forge.net.event.LobbyUpdateEvent;
import forge.net.event.MessageEvent;
import forge.net.event.NetEvent;
public class FGameClient implements IToServer {
private final IGuiGame clientGui;
private final List<ILobbyListener> lobbyListeners = Lists.newArrayList();
private final ReplyPool replies = new ReplyPool();
private Channel channel;
public FGameClient(final String username, final String roomKey, final IGuiGame clientGui) {
this.clientGui = clientGui;
}
final IGuiGame getGui() {
return clientGui;
}
final ReplyPool getReplyPool() {
return replies;
}
public void connect(final String host, final int port) {
final EventLoopGroup group = new NioEventLoopGroup();
try {
final Bootstrap b = new Bootstrap()
.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(final SocketChannel ch) throws Exception {
final ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(
new ObjectEncoder(),
new ObjectDecoder(ClassResolvers.cacheDisabled(null)),
new MessageHandler(),
new LobbyUpdateHandler(),
new GameClientHandler(FGameClient.this));
}
});
// Start the connection attempt.
channel = b.connect(host, port).sync().channel();
final ChannelFuture ch = channel.closeFuture();
new Thread(new Runnable() {
@Override public void run() {
try {
ch.sync();
} catch (final InterruptedException e) {
e.printStackTrace();
} finally {
group.shutdownGracefully();
}
}
}).start();
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
public void close() {
channel.close();
}
@Override
public void send(final NetEvent event) {
System.out.println("Client sent " + event);
channel.writeAndFlush(event);
}
@Override
public Object sendAndWait(final IdentifiableNetEvent event) throws TimeoutException {
replies.initialize(event.getId());
send(event);
// Wait for reply
return replies.get(event.getId());
}
public void addLobbyListener(final ILobbyListener listener) {
lobbyListeners.add(listener);
}
void setGameControllers(final Iterable<PlayerView> myPlayers) {
for (final PlayerView p : myPlayers) {
clientGui.setGameController(p, new NetGameController(this));
}
}
private class MessageHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
if (msg instanceof MessageEvent) {
final MessageEvent event = (MessageEvent) msg;
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) {
final LobbyUpdateEvent event = (LobbyUpdateEvent) msg;
listener.update(event.getState(), event.getSlot());
}
}
super.channelRead(ctx, msg);
}
@Override
public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
for (final ILobbyListener listener : lobbyListeners) {
listener.close();
}
super.channelInactive(ctx);
}
}
}

View File

@@ -0,0 +1,268 @@
package forge.net.client;
import forge.FThreads;
import forge.UiCommand;
import forge.assets.FSkinProp;
import forge.deck.CardPool;
import forge.game.GameEntityView;
import forge.game.GameView;
import forge.game.card.CardView;
import forge.game.phase.PhaseType;
import forge.game.player.DelayedReveal;
import forge.game.player.PlayerView;
import forge.game.spellability.SpellAbilityView;
import forge.game.zone.ZoneType;
import forge.interfaces.IButton;
import forge.interfaces.IGuiGame;
import forge.match.MatchButtonType;
import forge.model.FModel;
import forge.net.event.GuiGameEvent;
import forge.net.event.LoginEvent;
import forge.net.event.ReplyEvent;
import forge.player.PlayerZoneUpdates;
import forge.properties.ForgePreferences.FPref;
import forge.trackable.TrackableCollection;
import forge.util.ITriggerEvent;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import com.google.common.base.Function;
class GameClientHandler extends ChannelInboundHandlerAdapter {
private final FGameClient client;
private final IGuiGame gui;
/**
* Creates a client-side game handler.
*/
public GameClientHandler(final FGameClient client) {
this.client = client;
this.gui = client.getGui();
}
@Override
public void channelActive(final ChannelHandlerContext ctx) {
// Don't use send() here, as this.channel is not yet set!
ctx.channel().writeAndFlush(new LoginEvent(FModel.getPreferences().getPref(FPref.PLAYER_NAME), Integer.parseInt(FModel.getPreferences().getPref(FPref.UI_AVATARS).split(",")[0])));
}
@SuppressWarnings("unchecked")
@Override
public void channelRead(final ChannelHandlerContext ctx, final Object msg) {
System.out.println("Client received: " + msg);
if (msg instanceof ReplyEvent) {
final ReplyEvent event = (ReplyEvent) msg;
client.getReplyPool().complete(event.getIndex(), event.getReply());
} else if (msg instanceof GuiGameEvent) {
final GuiGameEvent event = (GuiGameEvent) msg;
final String method = event.getMethod();
final Object[] args = event.getObjects();
Serializable reply = null;
boolean doReply = false;
final IButton btn;
if (method.startsWith("btn_") && args.length >= 2 && args[0] instanceof PlayerView && args[1] instanceof MatchButtonType) {
btn = args[1] == MatchButtonType.OK ? gui.getBtnOK((PlayerView) args[0]) : gui.getBtnCancel((PlayerView) args[0]);
} else {
btn = null;
}
switch (method) {
case "setGameView":
gui.setGameView((GameView) args[0]);
break;
case "openView":
final TrackableCollection<PlayerView> myPlayers = (TrackableCollection<PlayerView>) args[0];
client.setGameControllers(myPlayers);
FThreads.invokeInEdtNowOrLater(new Runnable() {
@Override public final void run() {
gui.openView(myPlayers);
}
});
break;
case "afterGameEnd":
gui.afterGameEnd();
break;
case "showCombat":
gui.showCombat();
break;
case "showPromptMessage":
gui.showPromptMessage((PlayerView) args[0], (String) args[1]);
break;
case "stopAtPhase":
reply = gui.stopAtPhase((PlayerView) args[0], (PhaseType) args[1]);
doReply = true;
break;
case "focusButton":
gui.focusButton((MatchButtonType) args[0]);
break;
case "flashIncorrectAction":
gui.flashIncorrectAction();
break;
case "updatePhase":
gui.updatePhase();
break;
case "updateTurn":
FThreads.invokeInEdtNowOrLater(new Runnable() {
@Override public final void run() {
gui.updateTurn((PlayerView) args[0]);
}
});
break;
case "udpdatePlayerControl":
gui.updatePlayerControl();
break;
case "enableOverlay":
gui.enableOverlay();
break;
case "disbleOverlay":
gui.disableOverlay();
break;
case "finishGame":
gui.finishGame();
break;
case "showManaPool":
gui.showManaPool((PlayerView) args[0]);
break;
case "hideManaPool":
gui.hideManaPool((PlayerView) args[0], args[1]);
break;
case "updateStack":
gui.updateStack();
break;
case "updateZones":
FThreads.invokeInEdtNowOrLater(new Runnable() {
@Override public final void run() {
gui.updateZones((PlayerZoneUpdates) args[0]);
}
});
break;
case "updateSingleCard":
gui.updateSingleCard((CardView) args[0]);
break;
case "updateManaPool":
gui.updateManaPool((Iterable<PlayerView>) args[0]);
break;
case "updateLives":
gui.updateLives((Iterable<PlayerView>) args[0]);
break;
case "setPanelSelection":
gui.setPanelSelection((CardView) args[0]);
break;
case "getAbilityToPlay":
reply = gui.getAbilityToPlay((List<SpellAbilityView>) args[0], (ITriggerEvent) args[1]);
doReply = true;
break;
case "assignDamage":
reply = (Serializable) gui.assignDamage((CardView) args[0], (List<CardView>) args[1], (int) args[2], (GameEntityView) args[3], (boolean) args[4]);
doReply = true;
break;
case "message":
gui.message((String) args[0], (String) args[1]);
break;
case "showErrorDialog":
gui.showErrorDialog((String) args[0], (String) args[1]);
break;
case "showConfirmDialog":
reply = gui.showConfirmDialog((String) args[0], (String) args[1], (String) args[2], (String) args[3], (boolean) args[4]);
doReply = true;
break;
case "showOptionDialog":
reply = gui.showOptionDialog((String) args[0], (String) args[1], (FSkinProp) args[2], (String[]) args[3], (int) args[4]);
doReply = true;
break;
case "showCardOptionDialog":
reply = gui.showCardOptionDialog((CardView) args[0], (String) args[1], (String) args[2], (FSkinProp) args[3], (String[]) args[4], (int) args[5]);
doReply = true;
break;
case "showInputDialog":
reply = gui.showInputDialog((String) args[0], (String) args[1], (FSkinProp) args[2], (String) args[3], (String[]) args[4]);
doReply = true;
break;
case "confirm":
reply = gui.confirm((CardView) args[0], (String) args[1], (boolean) args[2], (String[]) args[3]);
doReply = true;
break;
case "getChoices":
reply = (Serializable) gui.getChoices((String) args[0], (int) args[1], (int) args[2], (Collection<Object>) args[3], args[4], (Function<Object, String>) args[5]);
doReply = true;
break;
case "order":
reply = (Serializable) gui.order((String) args[0], (String) args[1], (int) args[2], (int) args[3], (List<Object>) args[4], (List<Object>) args[5], (CardView) args[6], (boolean) args[7]);
doReply = true;
break;
case "sideboard":
reply = (Serializable) gui.sideboard((CardPool) args[0], (CardPool) args[1]);
doReply = true;
break;
case "chooseSingleEntityForEffect":
reply = gui.chooseSingleEntityForEffect((String) args[0], (TrackableCollection<GameEntityView>) args[1], (DelayedReveal) args[2], (boolean) args[3]);
doReply = true;
break;
case "setCard":
gui.setCard((CardView) args[0]);
break;
// TODO case "setPlayerAvatar":
case "openZones":
reply = gui.openZones((Collection<ZoneType>) args[0], (Map<PlayerView, Object>) args[1]);
doReply = true;
break;
case "restoreOldZones":
gui.restoreOldZones((Map<PlayerView, Object>) args[0]);
break;
case "isUiSetToSkipPhase":
reply = gui.isUiSetToSkipPhase((PlayerView) args[0], (PhaseType) args[1]);
doReply = true;
break;
// BUTTONS
case "btn_setEnabled":
btn.setEnabled((boolean) args[2]);
break;
case "btn_setVisible":
btn.setVisible((boolean) args[2]);
break;
case "btn_setText":
btn.setText((String) args[2]);
break;
case "btn_isSelected":
reply = btn.isSelected();
doReply = true;
break;
case "btn_setSelected":
btn.setSelected((boolean) args[2]);
break;
case "btn_requestFocusInWindows":
reply = btn.requestFocusInWindow();
doReply = true;
break;
case "btn_setCommand":
btn.setCommand((UiCommand) args[2]);
break;
case "btn_setTextColor":
if (args.length == 3) {
btn.setTextColor((FSkinProp) args[2]);
} else {
btn.setTextColor((int) args[2], (int) args[3], (int) args[4]);
}
break;
default:
System.err.println("Unsupported game event " + event.getMethod());
break;
}
if (doReply) {
client.send(new ReplyEvent(event.getId(), reply));
}
}
}
@Override
public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}

View File

@@ -0,0 +1,6 @@
package forge.net.client;
import forge.net.IRemote;
public interface IToServer extends IRemote {
}

View File

@@ -1,4 +1,4 @@
package forge.net;
package forge.net.client;
import java.util.List;
import java.util.concurrent.TimeoutException;
@@ -9,8 +9,7 @@ import forge.game.spellability.SpellAbilityView;
import forge.interfaces.IDevModeCheats;
import forge.interfaces.IGameController;
import forge.match.NextGameDecision;
import forge.net.game.GuiGameEvent;
import forge.net.game.client.IToServer;
import forge.net.event.GuiGameEvent;
import forge.util.ITriggerEvent;
public class NetGameController implements IGameController {

View File

@@ -0,0 +1 @@
package forge.net.client;

View File

@@ -0,0 +1,31 @@
package forge.net.event;
import java.io.Serializable;
import forge.net.server.RemoteClient;
public final class ReplyEvent implements NetEvent {
private static final long serialVersionUID = -2814651319617795386L;
private final int index;
private final Serializable reply;
public ReplyEvent(final int index, final Serializable reply) {
this.index = index;
this.reply = reply;
}
public int getIndex() {
return index;
}
public Object getReply() {
return reply;
}
@Override public void updateForClient(final RemoteClient client) {
}
@Override
public String toString() {
return String.format("Reply (%d): %s", index, reply);
}
}

View File

@@ -0,0 +1,83 @@
package forge.net.event;
import java.util.Collections;
import java.util.Set;
import forge.AIOption;
import forge.deck.CardPool;
import forge.deck.Deck;
import forge.deck.DeckSection;
import forge.match.LobbySlotType;
import forge.net.server.RemoteClient;
public final class UpdateLobbyPlayerEvent implements NetEvent {
private static final long serialVersionUID = -5073305607515425968L;
private final LobbySlotType type;
private final String name;
private final int avatarIndex;
private final int team;
private final Boolean isArchenemy;
private final Boolean isReady;
private final Deck deck;
private final DeckSection section;
private final CardPool cards;
private final Set<AIOption> aiOptions;
public static UpdateLobbyPlayerEvent create(final LobbySlotType type, final String name, final int avatarIndex, final int team, final boolean isArchenemy, final boolean isReady, final Set<AIOption> aiOptions) {
return new UpdateLobbyPlayerEvent(type, name, avatarIndex, team, isArchenemy, isReady, null, null, null, aiOptions);
}
public static UpdateLobbyPlayerEvent deckUpdate(final Deck deck) {
return new UpdateLobbyPlayerEvent(null, null, -1, -1, null, null, deck, null, null, null);
}
public static UpdateLobbyPlayerEvent deckUpdate(final DeckSection section, final CardPool cards) {
return new UpdateLobbyPlayerEvent(null, null, -1, -1, null, null, null, section, cards, null);
}
private UpdateLobbyPlayerEvent(final LobbySlotType type, final String name, final int avatarIndex, final int team, final Boolean isArchenemy, final Boolean isReady, final Deck deck, final DeckSection section, final CardPool cards, final Set<AIOption> aiOptions) {
this.type = type;
this.name = name;
this.avatarIndex = avatarIndex;
this.team = team;
this.isArchenemy = isArchenemy;
this.isReady = isReady;
this.deck = deck;
this.section = section;
this.cards = cards;
this.aiOptions = aiOptions;
}
public void updateForClient(final RemoteClient client) {
}
public LobbySlotType getType() {
return type;
}
public String getName() {
return name;
}
public int getAvatarIndex() {
return avatarIndex;
}
public int getTeam() {
return team;
}
public Boolean getArchenemy() {
return isArchenemy;
}
public Boolean getReady() {
return isReady;
}
public Deck getDeck() {
return deck;
}
public DeckSection getSection() {
return section;
}
public CardPool getCards() {
return cards;
}
public Set<AIOption> getAiOptions() {
return aiOptions == null ? null : Collections.unmodifiableSet(aiOptions);
}
}

View File

@@ -0,0 +1 @@
package forge.net.event;

View File

@@ -1,4 +1,4 @@
package forge.net;
package forge.net.server;
import forge.FThreads;
import forge.GuiBase;
@@ -11,16 +11,16 @@ import forge.interfaces.IGameController;
import forge.interfaces.IGuiGame;
import forge.interfaces.ILobbyListener;
import forge.match.LobbySlot;
import forge.match.LobbySlotType;
import forge.match.NextGameDecision;
import forge.net.game.GuiGameEvent;
import forge.net.game.LobbySlotType;
import forge.net.game.LoginEvent;
import forge.net.game.LogoutEvent;
import forge.net.game.MessageEvent;
import forge.net.game.NetEvent;
import forge.net.game.ReplyEvent;
import forge.net.game.UpdateLobbyPlayerEvent;
import forge.net.game.server.RemoteClient;
import forge.net.event.GuiGameEvent;
import forge.net.event.LobbyUpdateEvent;
import forge.net.event.LoginEvent;
import forge.net.event.LogoutEvent;
import forge.net.event.MessageEvent;
import forge.net.event.NetEvent;
import forge.net.event.ReplyEvent;
import forge.net.event.UpdateLobbyPlayerEvent;
import forge.properties.ForgeConstants;
import forge.util.ITriggerEvent;
import io.netty.bootstrap.ServerBootstrap;
@@ -41,7 +41,7 @@ import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import java.io.Serializable;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collection;
import java.util.Collections;
@@ -205,7 +205,7 @@ public final class FServerManager {
private void mapNatPort(final int port) {
final String localAddress;
try {
localAddress = Inet4Address.getLocalHost().getHostAddress();
localAddress = InetAddress.getLocalHost().getHostAddress();
} catch (final UnknownHostException e) {
throw new RuntimeException(e);
}
@@ -436,7 +436,7 @@ public final class FServerManager {
if (msg instanceof LoginEvent) {
final String username = ((LoginEvent) msg).getUsername();
client.setUsername(username);
broadcast(new MessageEvent(null, String.format("%s joined the room", username)));
broadcast(new MessageEvent(String.format("%s joined the room", username)));
updateLobbyState();
} else if (msg instanceof UpdateLobbyPlayerEvent) {
localLobby.applyToSlot(client.getIndex(), (UpdateLobbyPlayerEvent) msg);

View File

@@ -0,0 +1,6 @@
package forge.net.server;
import forge.net.IRemote;
public interface IToClient extends IRemote {
}

View File

@@ -1,4 +1,4 @@
package forge.net;
package forge.net.server;
import java.util.Collection;
import java.util.EnumMap;
@@ -26,8 +26,7 @@ import forge.interfaces.IButton;
import forge.item.PaperCard;
import forge.match.AbstractGuiGame;
import forge.match.MatchButtonType;
import forge.net.game.GuiGameEvent;
import forge.net.game.server.IToClient;
import forge.net.event.GuiGameEvent;
import forge.player.PlayerZoneUpdate;
import forge.trackable.TrackableCollection;
import forge.util.ITriggerEvent;

View File

@@ -0,0 +1,52 @@
package forge.net.server;
import forge.net.ReplyPool;
import forge.net.event.IdentifiableNetEvent;
import forge.net.event.NetEvent;
import io.netty.channel.Channel;
import java.util.concurrent.TimeoutException;
public final class RemoteClient implements IToClient {
private final Channel channel;
private String username;
private int index;
private ReplyPool replies = new ReplyPool();
public RemoteClient(final Channel channel) {
this.channel = channel;
}
@Override
public void send(final NetEvent event) {
System.out.println("Sending event " + event + " to " + channel);
channel.writeAndFlush(event);
}
@Override
public Object sendAndWait(final IdentifiableNetEvent event) throws TimeoutException {
replies.initialize(event.getId());
send(event);
return replies.get(event.getId());
}
public String getUsername() {
return username;
}
public void setUsername(final String username) {
this.username = username;
}
public int getIndex() {
return index;
}
public void setIndex(final int index) {
this.index = index;
}
public void setReply(final int id, final Object reply) {
replies.complete(id, reply);
}
}

View File

@@ -1,4 +1,4 @@
package forge.net;
package forge.net.server;
import java.util.Collections;
@@ -8,7 +8,7 @@ import forge.AIOption;
import forge.interfaces.IGuiGame;
import forge.match.GameLobby;
import forge.match.LobbySlot;
import forge.net.game.LobbySlotType;
import forge.match.LobbySlotType;
public final class ServerGameLobby extends GameLobby {

View File

@@ -0,0 +1 @@
package forge.net.server;