From 2c55a9d86c4f9ba15cb77176ec4c3306aa553d7c Mon Sep 17 00:00:00 2001 From: "Jamin W. Collins" Date: Wed, 28 Feb 2018 17:44:30 -0700 Subject: [PATCH 1/9] bump commons-lang3 version for Java 9 support Closes core-developers/forge#157 Signed-off-by: Jamin W. Collins --- forge-core/pom.xml | 2 +- forge-gui-android/pom.xml | 2 +- forge-gui-desktop/pom.xml | 2 +- forge-gui-mobile/pom.xml | 2 +- forge-gui/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/forge-core/pom.xml b/forge-core/pom.xml index 7de7afa6e3d..58e5275cf98 100644 --- a/forge-core/pom.xml +++ b/forge-core/pom.xml @@ -21,7 +21,7 @@ org.apache.commons commons-lang3 - 3.3 + 3.7 diff --git a/forge-gui-android/pom.xml b/forge-gui-android/pom.xml index be648139038..e12e0d8ce53 100644 --- a/forge-gui-android/pom.xml +++ b/forge-gui-android/pom.xml @@ -91,7 +91,7 @@ org.apache.commons commons-lang3 - 3.3 + 3.7 xmlpull diff --git a/forge-gui-desktop/pom.xml b/forge-gui-desktop/pom.xml index c4b422a477b..e1db3d54ea3 100644 --- a/forge-gui-desktop/pom.xml +++ b/forge-gui-desktop/pom.xml @@ -228,7 +228,7 @@ org.apache.commons commons-lang3 - 3.3 + 3.7 org.freemarker diff --git a/forge-gui-mobile/pom.xml b/forge-gui-mobile/pom.xml index fa856665d3e..07a19da76ee 100644 --- a/forge-gui-mobile/pom.xml +++ b/forge-gui-mobile/pom.xml @@ -58,7 +58,7 @@ org.apache.commons commons-lang3 - 3.3 + 3.7 com.badlogicgames.gdx diff --git a/forge-gui/pom.xml b/forge-gui/pom.xml index 5fb3c8ed742..bcad2f56a62 100644 --- a/forge-gui/pom.xml +++ b/forge-gui/pom.xml @@ -49,7 +49,7 @@ org.apache.commons commons-lang3 - 3.3 + 3.7 io.netty From 2b704e16c7635590b5dcf0887ccc0c6b6a545926 Mon Sep 17 00:00:00 2001 From: "Jamin W. Collins" Date: Wed, 28 Feb 2018 17:48:45 -0700 Subject: [PATCH 2/9] disable all network play variants Signed-off-by: Jamin W. Collins --- forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java b/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java index 9e8fc2f93d9..72ad2c8c6fd 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java @@ -94,7 +94,8 @@ public class VLobby implements ILobbyView { private final VariantCheckBox vntArchenemy = new VariantCheckBox(GameType.Archenemy); private final VariantCheckBox vntArchenemyRumble = new VariantCheckBox(GameType.ArchenemyRumble); private final ImmutableList vntBoxes = - ImmutableList.of(vntVanguard, vntMomirBasic, vntCommander, vntTinyLeaders, vntPlanechase, vntArchenemy, vntArchenemyRumble); + ImmutableList.of(); + // ImmutableList.of(vntVanguard, vntMomirBasic, vntCommander, vntTinyLeaders, vntPlanechase, vntArchenemy, vntArchenemyRumble); // Player frame elements private final JPanel playersFrame = new JPanel(new MigLayout("insets 0, gap 0 5, wrap, hidemode 3")); From f1a001a8344b0acee47f1d26ebd51bdbf8b81781 Mon Sep 17 00:00:00 2001 From: "Jamin W. Collins" Date: Wed, 28 Feb 2018 17:55:32 -0700 Subject: [PATCH 3/9] retrieve GameType from the Lobby The existing GameView does not accurately reflect the GameType when variants are selected. The Lobby does have the correct GameType. Signed-off-by: Jamin W. Collins --- .../java/forge/net/client/GameClientHandler.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) 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 08955a4d2c1..167e0f884c3 100644 --- a/forge-gui/src/main/java/forge/net/client/GameClientHandler.java +++ b/forge-gui/src/main/java/forge/net/client/GameClientHandler.java @@ -105,6 +105,18 @@ final class GameClientHandler extends GameProtocolHandler { return gameRules; } + /** + * Retrieve the desired GameType from the Lobby + * + * @return GameType + */ + private GameType getGameType() { + List lobbyListeners = client.getLobbyListeners(); + ILobbyListener lobbyListener = lobbyListeners.get(0); + ClientGameLobby myLobby = lobbyListener.getLobby(); + return myLobby.getGameType(); + } + /** * This method retrieves enough of the existing (incomplete) game state to * recreate a new viable Match object @@ -121,7 +133,7 @@ final class GameClientHandler extends GameProtocolHandler { final IGuiGame gui = client.getGui(); GameView gameView = gui.getGameView(); - final GameType gameType = gameView.getGameType(); + final GameType gameType = getGameType(); final GameRules gameRules = createGameRules(gameType, gameView); final List registeredPlayers = createRegisteredPlayers(gameType); From 72ca147b733009091265cc2a251a1e06177004ec Mon Sep 17 00:00:00 2001 From: "Jamin W. Collins" Date: Wed, 28 Feb 2018 17:59:38 -0700 Subject: [PATCH 4/9] ensure that selected variant is applied to GameRules Signed-off-by: Jamin W. Collins --- forge-gui/src/main/java/forge/net/client/GameClientHandler.java | 2 ++ 1 file changed, 2 insertions(+) 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 167e0f884c3..2cacfdccfda 100644 --- a/forge-gui/src/main/java/forge/net/client/GameClientHandler.java +++ b/forge-gui/src/main/java/forge/net/client/GameClientHandler.java @@ -99,6 +99,8 @@ final class GameClientHandler extends GameProtocolHandler { private GameRules createGameRules(GameType gameType, GameView gameView) { // FIXME: how do we know the rules are the same on each side??? GameRules gameRules = new GameRules(gameType); + // is this always safe to do? + gameRules.setAppliedVariants(Collections.singleton(gameType)); gameRules.setGamesPerMatch(gameView.getNumGamesInMatch()); gameRules.setPoisonCountersToLose(gameView.getPoisonCountersToLose()); From 420d31f825df180b5550604e5c1f2917359139ac Mon Sep 17 00:00:00 2001 From: "Jamin W. Collins" Date: Wed, 28 Feb 2018 18:09:49 -0700 Subject: [PATCH 5/9] replicate PlayerView(s) from incoming to existing With standard network play games, we got lucky. With variants the existing approach was not accurately reflecting state changes. This appears to be resolved by replicating incoming PlayerView objects onto their existing versions inside the Tracker object. Signed-off-by: Jamin W. Collins --- .../forge/net/client/GameClientHandler.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) 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 2cacfdccfda..93f11d7be96 100644 --- a/forge-gui/src/main/java/forge/net/client/GameClientHandler.java +++ b/forge-gui/src/main/java/forge/net/client/GameClientHandler.java @@ -7,7 +7,10 @@ import forge.game.player.RegisteredPlayer; import forge.interfaces.ILobbyListener; import forge.match.LobbySlot; import forge.player.LobbyPlayerHuman; +import forge.player.PlayerZoneUpdate; +import forge.player.PlayerZoneUpdates; import forge.trackable.TrackableObject; +import forge.trackable.TrackableTypes; import forge.trackable.Tracker; import io.netty.channel.ChannelHandlerContext; import forge.game.player.PlayerView; @@ -88,6 +91,7 @@ final class GameClientHandler extends GameProtocolHandler { } if (!(this.tracker == null)) { updateTrackers(args); + replicateProps(args); } } @@ -245,6 +249,41 @@ final class GameClientHandler extends GameProtocolHandler { } } + private void replicateProps(final Object[] objs) { + for (Object obj: objs) { + if (obj instanceof PlayerView) { + replicatePlayerView((PlayerView) obj); + } + else if (obj instanceof PlayerZoneUpdate) { + replicatePlayerView(((PlayerZoneUpdate) obj).getPlayer()); + } + else if (obj instanceof PlayerZoneUpdates) { + Iterator itrPlayerZoneUpdates = ((PlayerZoneUpdates) obj).iterator(); + while (itrPlayerZoneUpdates.hasNext()) { + PlayerView newPlayerView = ((PlayerZoneUpdate)itrPlayerZoneUpdates.next()).getPlayer(); + /** + * FIXME: this should be handled by the original call to updateTrackers + * However, PlayerZoneUpdates aren't a TrackableCollection. + * So, additional logic will be needed. Leaving here for now. + */ + updateTrackers(new Object[]{newPlayerView}); + replicatePlayerView(newPlayerView); + } + } + /* + else { + System.err.println("replicateProps - did not handle : " + obj.getClass().toString()); + } + */ + } + } + + private void replicatePlayerView(final PlayerView newPlayerView) { + PlayerView existingPlayerView = tracker.getObj(TrackableTypes.PlayerViewType, newPlayerView.getId()); + existingPlayerView.copyChangedProps(newPlayerView); + System.err.println("replicated PlayerView properties - " + existingPlayerView.toString()); + } + @Override public void channelActive(final ChannelHandlerContext ctx) { // Don't use send() here, as this.channel is not yet set! From 26c0df6e0524fb5eba6440949b0755225b92fc7d Mon Sep 17 00:00:00 2001 From: "Jamin W. Collins" Date: Wed, 28 Feb 2018 18:24:19 -0700 Subject: [PATCH 6/9] network play: fix for Commander and Tiny Leaders variants This method is called numerous times, many before the Commander data has been populated on the PlayerView objects. This is reflected a few lines above where similar logic is applied to the current PlayerView. This simply applies similar logic to the player's opponents. Signed-off-by: Jamin W. Collins --- forge-game/src/main/java/forge/game/player/PlayerView.java | 6 ++++++ .../src/main/java/forge/screens/home/VLobby.java | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/player/PlayerView.java b/forge-game/src/main/java/forge/game/player/PlayerView.java index f8dffa5482b..b5aeb4874a7 100644 --- a/forge-game/src/main/java/forge/game/player/PlayerView.java +++ b/forge-game/src/main/java/forge/game/player/PlayerView.java @@ -129,6 +129,12 @@ public class PlayerView extends GameEntityView { } final FCollectionView opponents = getOpponents(); + for (PlayerView opponent: opponents) { + if (opponent.getCommanders() == null) { + return Collections.emptyList(); + } + } + final List info = Lists.newArrayListWithExpectedSize(opponents.size()); info.add(TextUtil.concatWithSpace("Commanders:", Lang.joinHomogenous(commanders))); for (final PlayerView p : Iterables.concat(Collections.singleton(this), opponents)) { diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java b/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java index 72ad2c8c6fd..1dad755e7ad 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java @@ -94,7 +94,7 @@ public class VLobby implements ILobbyView { private final VariantCheckBox vntArchenemy = new VariantCheckBox(GameType.Archenemy); private final VariantCheckBox vntArchenemyRumble = new VariantCheckBox(GameType.ArchenemyRumble); private final ImmutableList vntBoxes = - ImmutableList.of(); + ImmutableList.of(vntCommander, vntTinyLeaders); // ImmutableList.of(vntVanguard, vntMomirBasic, vntCommander, vntTinyLeaders, vntPlanechase, vntArchenemy, vntArchenemyRumble); // Player frame elements From a5b9512fdb0c4348c16d21de605049a6a4bcceff Mon Sep 17 00:00:00 2001 From: "Jamin W. Collins" Date: Wed, 28 Feb 2018 18:27:07 -0700 Subject: [PATCH 7/9] network play: allow readying if Momir is selected Signed-off-by: Jamin W. Collins --- .../src/main/java/forge/screens/home/VLobby.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java b/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java index 1dad755e7ad..304b006a72f 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java @@ -94,7 +94,7 @@ public class VLobby implements ILobbyView { private final VariantCheckBox vntArchenemy = new VariantCheckBox(GameType.Archenemy); private final VariantCheckBox vntArchenemyRumble = new VariantCheckBox(GameType.ArchenemyRumble); private final ImmutableList vntBoxes = - ImmutableList.of(vntCommander, vntTinyLeaders); + ImmutableList.of(vntMomirBasic, vntCommander, vntTinyLeaders); // ImmutableList.of(vntVanguard, vntMomirBasic, vntCommander, vntTinyLeaders, vntPlanechase, vntArchenemy, vntArchenemyRumble); // Player frame elements @@ -303,7 +303,7 @@ public class VLobby implements ILobbyView { } void setReady(final int index, final boolean ready) { - if (ready && decks[index] == null) { + if (ready && decks[index] == null && !vntMomirBasic.isSelected()) { SOptionPane.showErrorDialog("Select a deck before readying!"); update(false); return; From 3415d76b40b04779f0055b43630abc601193d44a Mon Sep 17 00:00:00 2001 From: "Jamin W. Collins" Date: Wed, 28 Feb 2018 18:40:57 -0700 Subject: [PATCH 8/9] allow ALL cards to be (de)serialized This is needed by network play variants like: - Vanguard - Planechase Signed-off-by: Jamin W. Collins --- forge-core/src/main/java/forge/StaticData.java | 9 ++++++++- forge-core/src/main/java/forge/item/PaperCard.java | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/forge-core/src/main/java/forge/StaticData.java b/forge-core/src/main/java/forge/StaticData.java index 5bf271be201..57411a0434b 100644 --- a/forge-core/src/main/java/forge/StaticData.java +++ b/forge-core/src/main/java/forge/StaticData.java @@ -29,6 +29,7 @@ public class StaticData { private final String blockDataFolder; private final CardDb commonCards; private final CardDb variantCards; + private final CardDb allCards; private final TokenDb allTokens; private final CardEdition.Collection editions; @@ -54,6 +55,7 @@ public class StaticData { lastInstance = this; { + final Map allCardsMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); final Map regularCards = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); final Map variantsCards = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); @@ -61,6 +63,7 @@ public class StaticData { if (null == card) continue; final String cardName = card.getName(); + allCardsMap.put(cardName, card); if (card.isVariant()) { variantsCards.put(cardName, card); } else { @@ -68,10 +71,12 @@ public class StaticData { } } + allCards = new CardDb(allCardsMap, editions); commonCards = new CardDb(regularCards, editions); variantCards = new CardDb(variantsCards, editions); - //muse initialize after establish field values for the sake of card image logic + //must initialize after establish field values for the sake of card image logic + allCards.initialize(false, false); commonCards.initialize(false, false); variantCards.initialize(false, false); } @@ -184,6 +189,8 @@ public class StaticData { return variantCards; } + public CardDb getAllCards() { return allCards; } + public TokenDb getAllTokens() { return allTokens; } public PaperCard getCardByEditionDate(PaperCard card, Date editionDate) { diff --git a/forge-core/src/main/java/forge/item/PaperCard.java b/forge-core/src/main/java/forge/item/PaperCard.java index 17d113d723b..c77903541ed 100644 --- a/forge-core/src/main/java/forge/item/PaperCard.java +++ b/forge-core/src/main/java/forge/item/PaperCard.java @@ -212,7 +212,7 @@ public final class PaperCard implements Comparable, InventoryItemFro // default deserialization ois.defaultReadObject(); - final IPaperCard pc = StaticData.instance().getCommonCards().getCard(name, edition, artIndex); + final IPaperCard pc = StaticData.instance().getAllCards().getCard(name, edition, artIndex); if (pc == null) { throw new IOException(TextUtil.concatWithSpace("Card", name, "not found")); } From 193f1f8b2395b6b7c3b740d787cda16680f7e0e5 Mon Sep 17 00:00:00 2001 From: "Jamin W. Collins" Date: Wed, 28 Feb 2018 18:56:59 -0700 Subject: [PATCH 9/9] network play: enable Vanguard Signed-off-by: Jamin W. Collins --- forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java b/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java index 304b006a72f..b6908eee5d3 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java @@ -94,8 +94,7 @@ public class VLobby implements ILobbyView { private final VariantCheckBox vntArchenemy = new VariantCheckBox(GameType.Archenemy); private final VariantCheckBox vntArchenemyRumble = new VariantCheckBox(GameType.ArchenemyRumble); private final ImmutableList vntBoxes = - ImmutableList.of(vntMomirBasic, vntCommander, vntTinyLeaders); - // ImmutableList.of(vntVanguard, vntMomirBasic, vntCommander, vntTinyLeaders, vntPlanechase, vntArchenemy, vntArchenemyRumble); + ImmutableList.of(vntVanguard, vntMomirBasic, vntCommander, vntTinyLeaders /*, vntPlanechase, vntArchenemy, vntArchenemyRumble */); // Player frame elements private final JPanel playersFrame = new JPanel(new MigLayout("insets 0, gap 0 5, wrap, hidemode 3"));