From 8d2d66abb98267bce1ce3bd0f240151fcfb85771 Mon Sep 17 00:00:00 2001 From: "Jamin W. Collins" Date: Thu, 15 Feb 2018 18:07:22 -0700 Subject: [PATCH 1/3] move external address out to a class attribute Signed-off-by: Jamin W. Collins --- forge-gui/src/main/java/forge/net/server/FServerManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/forge-gui/src/main/java/forge/net/server/FServerManager.java b/forge-gui/src/main/java/forge/net/server/FServerManager.java index 8b8416c8a04..2d9118764e5 100644 --- a/forge-gui/src/main/java/forge/net/server/FServerManager.java +++ b/forge-gui/src/main/java/forge/net/server/FServerManager.java @@ -55,6 +55,7 @@ import com.google.common.collect.Maps; public final class FServerManager { private static FServerManager instance = null; + private byte[] externalAddress = new byte[]{8,8,8,8}; private boolean isHosting = false; private final EventLoopGroup bossGroup = new NioEventLoopGroup(1); private final EventLoopGroup workerGroup = new NioEventLoopGroup(); @@ -210,7 +211,7 @@ public final class FServerManager { // https://stackoverflow.com/a/901943 private String getRoutableAddress(boolean preferIpv4, boolean preferIPv6) throws SocketException, UnknownHostException { DatagramSocket s = new DatagramSocket(); - s.connect(InetAddress.getByAddress(new byte[]{8,8,8,8}), 0); + s.connect(InetAddress.getByAddress(this.externalAddress), 0); NetworkInterface n = NetworkInterface.getByInetAddress(s.getLocalAddress()); Enumeration en = n.getInetAddresses(); while (en.hasMoreElements()) { From d086e4d6926ef79aaf432859433bcbc04681e657 Mon Sep 17 00:00:00 2001 From: "Jamin W. Collins" Date: Sun, 18 Feb 2018 19:50:03 -0700 Subject: [PATCH 2/3] cleanup remote client game state creation Signed-off-by: Jamin W. Collins --- .../forge/net/client/GameClientHandler.java | 66 +++++++++++-------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/forge-gui/src/main/java/forge/net/client/GameClientHandler.java b/forge-gui/src/main/java/forge/net/client/GameClientHandler.java index f15a4576bc5..08955a4d2c1 100644 --- a/forge-gui/src/main/java/forge/net/client/GameClientHandler.java +++ b/forge-gui/src/main/java/forge/net/client/GameClientHandler.java @@ -27,6 +27,8 @@ final class GameClientHandler extends GameProtocolHandler { private final FGameClient client; private final IGuiGame gui; private Tracker tracker; + private Match match; + private Game game; /** * Creates a client-side game handler. @@ -36,6 +38,8 @@ final class GameClientHandler extends GameProtocolHandler { this.client = client; this.gui = client.getGui(); this.tracker = null; + this.match = null; + this.game = null; } @Override @@ -58,32 +62,26 @@ final class GameClientHandler extends GameProtocolHandler { protected void beforeCall(final ProtocolMethod protocolMethod, final Object[] args) { switch (protocolMethod) { case openView: - if (this.tracker == null) { - int maxAttempts = 5; - for (int numAttempts = 0; numAttempts < maxAttempts; numAttempts++) { - try { + // only need one **match** + if (this.match == null) { + this.match = createMatch(); + } - this.tracker = createTracker(); + // openView is called **once** per game, for now create a new Game instance each time + this.game = createGame(); - for (PlayerView myPlayer : (TrackableCollection) args[0]) { - if (myPlayer.getTracker() == null) { - myPlayer.setTracker(this.tracker); - } - } + // get a tracker + this.tracker = createTracker(); - final TrackableCollection myPlayers = (TrackableCollection) args[0]; - client.setGameControllers(myPlayers); - - } catch (Exception e) { - System.err.println("Failed: attempt number: " + numAttempts + " - " + e.toString()); - try { - Thread.sleep(100); - } catch (InterruptedException e1) { - e1.printStackTrace(); - } - } + for (PlayerView myPlayer : (TrackableCollection) args[0]) { + if (myPlayer.getTracker() == null) { + myPlayer.setTracker(this.tracker); } } + + final TrackableCollection myPlayers = (TrackableCollection) args[0]; + client.setGameControllers(myPlayers); + break; default: break; @@ -108,19 +106,17 @@ final class GameClientHandler extends GameProtocolHandler { } /** - * This method creates the necessary objects and state to retrieve a Tracker object. - * - * Near as I can tell, that means that we need to create a Match. + * This method retrieves enough of the existing (incomplete) game state to + * recreate a new viable Match object * * Creating a Match requires that we have: * * GameRules * * RegisteredPlayers * * Title * - * @return Tracker + * @return Match */ - private Tracker createTracker() { - + private Match createMatch() { // retrieve what we can from the existing (but incomplete) state final IGuiGame gui = client.getGui(); GameView gameView = gui.getGameView(); @@ -134,12 +130,24 @@ final class GameClientHandler extends GameProtocolHandler { // create a valid match object and game Match match = new Match(gameRules, registeredPlayers, title); - Game game = match.createGame(); + return match; + } + + private Game createGame() { + this.tracker = null; + return this.match.createGame(); + } + + /** + * Ensure the stored GameView is correct and retrieve a Tracker object. + * + * @return Tracker + */ + private Tracker createTracker() { // replace the existing incomplete GameView with the newly created one gui.setGameView(null); gui.setGameView(game.getView()); - return gui.getGameView().getTracker(); } From 487fec02580e981842de103bd7a2549ec3602984 Mon Sep 17 00:00:00 2001 From: "Jamin W. Collins" Date: Mon, 19 Feb 2018 13:11:53 -0700 Subject: [PATCH 3/3] multiplayer fix for 2nd and 3rd games of match The server was not updating the lobby player's game reference. So, the remote client's response was being processed for the wrong game instance. Signed-off-by: Jamin W. Collins --- .../src/main/java/forge/match/GameLobby.java | 6 ++++- .../main/java/forge/match/HostedMatch.java | 22 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/forge-gui/src/main/java/forge/match/GameLobby.java b/forge-gui/src/main/java/forge/match/GameLobby.java index 168a331c60b..097705ed545 100644 --- a/forge-gui/src/main/java/forge/match/GameLobby.java +++ b/forge-gui/src/main/java/forge/match/GameLobby.java @@ -4,10 +4,12 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; + import forge.util.TextUtil; import org.apache.commons.lang3.StringUtils; @@ -49,7 +51,7 @@ public abstract class GameLobby implements IHasGameType { private final boolean allowNetworking; private HostedMatch hostedMatch; - private final Map gameControllers = Maps.newHashMap(); + private final HashMap gameControllers = Maps.newHashMap(); protected GameLobby(final boolean allowNetworking) { this.allowNetworking = allowNetworking; } @@ -481,6 +483,8 @@ public abstract class GameLobby implements IHasGameType { } } + hostedMatch.gameControllers = gameControllers; + onGameStarted(); } }; diff --git a/forge-gui/src/main/java/forge/match/HostedMatch.java b/forge-gui/src/main/java/forge/match/HostedMatch.java index 3e3f757a962..d42aaa68072 100644 --- a/forge-gui/src/main/java/forge/match/HostedMatch.java +++ b/forge-gui/src/main/java/forge/match/HostedMatch.java @@ -3,11 +3,14 @@ package forge.match; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import forge.LobbyPlayer; +import forge.interfaces.IGameController; import forge.util.TextUtil; import org.apache.commons.lang3.StringUtils; @@ -55,6 +58,7 @@ public class HostedMatch { private Match match; private Game game; private String title; + public HashMap gameControllers = null; private Runnable startGameHook = null; private final List humanControllers = Lists.newArrayList(); private Map guis; @@ -180,6 +184,12 @@ public class HostedMatch { game.subscribeToEvents(new FControlGameEventHandler(humanController)); playersPerGui.add(gui, p.getView()); + + if (gameControllers != null ) { + LobbySlot lobbySlot = getLobbySlot(p.getLobbyPlayer()); + gameControllers.put(lobbySlot, humanController); + } + humanControllers.add(humanController); humanCount++; } @@ -238,6 +248,18 @@ public class HostedMatch { }); } + private LobbySlot getLobbySlot(LobbyPlayer lobbyPlayer) { + for (LobbySlot key: gameControllers.keySet()) { + IGameController value = gameControllers.get(key); + if (value instanceof PlayerControllerHuman) { + if (lobbyPlayer == ((PlayerControllerHuman) value).getLobbyPlayer()) { + return key; + } + } + } + return null; + } + public void registerSpectator(final IGuiGame gui) { final PlayerControllerHuman humanController = new WatchLocalGame(game, null, gui); gui.setSpectator(humanController);