From 64488ed8135c11069b69a641bcad50c55bcd2f51 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Tue, 8 Mar 2022 10:27:50 +0800 Subject: [PATCH 1/3] [Mobile] Fix path for fallback_skin --- forge-gui-mobile/src/forge/Forge.java | 2 +- .../src/forge/adventure/scene/PlayerStatisticScene.java | 1 - forge-gui-mobile/src/forge/assets/FSkin.java | 2 +- forge-gui-mobile/src/forge/screens/SplashScreen.java | 4 +--- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/forge-gui-mobile/src/forge/Forge.java b/forge-gui-mobile/src/forge/Forge.java index 98960d81a4e..317643a6e32 100644 --- a/forge-gui-mobile/src/forge/Forge.java +++ b/forge-gui-mobile/src/forge/Forge.java @@ -339,7 +339,7 @@ public class Forge implements ApplicationListener { protected void afterDbLoaded() { //init here to fix crash if the assets are missing - transitionTexture = new Texture(GuiBase.isAndroid() ? Gdx.files.internal("fallback_skin").child("transition.png") : Gdx.files.classpath("fallback_skin").child("transition.png")); + transitionTexture = new Texture(Gdx.files.classpath("fallback_skin").child("transition.png")); destroyThis = false; //Allow back() diff --git a/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java b/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java index 7fcee8d10dc..74efeed902c 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java @@ -200,7 +200,6 @@ public class PlayerStatisticScene extends UIScene { back.getLabel().setText(Forge.getLocalizer().getMessage("lblBack")); ScrollPane scrollPane = ui.findActor("enemies"); scrollPane.setActor(enemiesGroup); - enemiesGroup.setFillParent(true); this.init = true; } } diff --git a/forge-gui-mobile/src/forge/assets/FSkin.java b/forge-gui-mobile/src/forge/assets/FSkin.java index 8f7abc78286..46f4619829d 100644 --- a/forge-gui-mobile/src/forge/assets/FSkin.java +++ b/forge-gui-mobile/src/forge/assets/FSkin.java @@ -108,7 +108,7 @@ public class FSkin { { if (!dir.exists() || !dir.isDirectory()) { //if skins directory doesn't exist, point to internal assets/skin directory instead for the sake of the splash screen - preferredDir = GuiBase.isAndroid() ? Gdx.files.internal("fallback_skin") : Gdx.files.classpath("fallback_skin"); + preferredDir = Gdx.files.classpath("fallback_skin"); } else { if (splashScreen != null) { diff --git a/forge-gui-mobile/src/forge/screens/SplashScreen.java b/forge-gui-mobile/src/forge/screens/SplashScreen.java index 958fa78dbb1..ce5b40db88f 100644 --- a/forge-gui-mobile/src/forge/screens/SplashScreen.java +++ b/forge-gui-mobile/src/forge/screens/SplashScreen.java @@ -97,9 +97,7 @@ public class SplashScreen extends FContainer { private float progress = 0; private boolean finished, openAdventure; //for transition image only... - TextureRegion transition_bg = new TextureRegion(new Texture(GuiBase.isAndroid() - ? Gdx.files.internal("fallback_skin").child("title_bg_lq.png") - : Gdx.files.classpath("fallback_skin").child("title_bg_lq.png"))); + TextureRegion transition_bg = new TextureRegion(new Texture(Gdx.files.classpath("fallback_skin").child("title_bg_lq.png"))); public void drawBackground(Graphics g) { float percentage = progress / DURATION; From 368acd1c594f9520c0f54723c3fb6c57074dbb01 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Tue, 8 Mar 2022 10:43:53 +0800 Subject: [PATCH 2/3] [Mobile] Update netcode, fix swapped players -update CObjectInputStream to use DecompressibleInputStream method --- .../java/forge/screens/match/CMatchUI.java | 6 ++ .../forge/screens/match/MatchController.java | 18 ++++-- .../gamemodes/match/input/InputBase.java | 4 +- .../gamemodes/net/CObjectInputStream.java | 22 ++++---- .../forge/gamemodes/net/ProtocolMethod.java | 55 ++++++++++--------- .../gamemodes/net/server/NetGuiGame.java | 4 +- .../java/forge/gui/interfaces/IGuiGame.java | 2 +- 7 files changed, 65 insertions(+), 46 deletions(-) diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java b/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java index 1a2a167ee15..dd8e8d006ed 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java @@ -1000,6 +1000,12 @@ public final class CMatchUI public void showPromptMessage(final PlayerView playerView, final String message) { cPrompt.setMessage(message); } + + @Override + public void showCardPromptMessage(PlayerView playerView, String message, CardView card) { + cPrompt.setMessage(message, card); + } + // no override for now public void showPromptMessage(final PlayerView playerView, final String message, final CardView card ) { cPrompt.setMessage(message,card); diff --git a/forge-gui-mobile/src/forge/screens/match/MatchController.java b/forge-gui-mobile/src/forge/screens/match/MatchController.java index 55cee891644..52724e136a9 100644 --- a/forge-gui-mobile/src/forge/screens/match/MatchController.java +++ b/forge-gui-mobile/src/forge/screens/match/MatchController.java @@ -12,6 +12,7 @@ import forge.deck.Deck; import forge.game.player.Player; import forge.item.IPaperCard; import forge.screens.TransitionScreen; +import forge.util.collect.FCollection; import org.apache.commons.lang3.StringUtils; import com.google.common.base.Function; @@ -157,13 +158,18 @@ public class MatchController extends AbstractGuiGame { public void openView(final TrackableCollection myPlayers) { final boolean noHumans = !hasLocalPlayers(); - final FCollectionView allPlayers = getGameView().getPlayers(); + FCollectionView players = getGameView().getPlayers(); + if (players.size() == 2 && myPlayers != null && myPlayers.size() == 1 && myPlayers.get(0).equals(players.get(1))) { + players = new FCollection<>(new PlayerView[]{players.get(1), players.get(0)}); + } final List playerPanels = new ArrayList<>(); - for (final PlayerView p : allPlayers) { + boolean init = false; + for (final PlayerView p : players) { final boolean isLocal = isLocalPlayer(p); - final VPlayerPanel playerPanel = new VPlayerPanel(p, isLocal || noHumans, allPlayers.size()); - if (isLocal && !playerPanels.isEmpty()) { + final VPlayerPanel playerPanel = new VPlayerPanel(p, isLocal || noHumans, players.size()); + if (isLocal && !init) { playerPanels.add(0, playerPanel); //ensure local player always first among player panels + init = true; } else { playerPanels.add(playerPanel); @@ -194,7 +200,7 @@ public class MatchController extends AbstractGuiGame { actuateMatchPreferences(); //reset daytime every match updateDayTime(null); - Forge.openScreen(view); + Forge.openScreen(view, GuiBase.isNetworkplay()); } @Override @@ -203,7 +209,7 @@ public class MatchController extends AbstractGuiGame { } @Override - public void showPromptMessage(final PlayerView player, final String message, final CardView card) { + public void showCardPromptMessage(final PlayerView player, final String message, final CardView card) { view.getPrompt(player).setMessage(message, card); } diff --git a/forge-gui/src/main/java/forge/gamemodes/match/input/InputBase.java b/forge-gui/src/main/java/forge/gamemodes/match/input/InputBase.java index 5a52d579371..a6e10c3d992 100644 --- a/forge-gui/src/main/java/forge/gamemodes/match/input/InputBase.java +++ b/forge-gui/src/main/java/forge/gamemodes/match/input/InputBase.java @@ -123,10 +123,10 @@ public abstract class InputBase implements java.io.Serializable, Input { controller.getGui().showPromptMessage(getOwner(), message); } protected final void showMessage(final String message, final SpellAbilityView sav) { - controller.getGui().showPromptMessage(getOwner(), message, sav.getHostCard()); + controller.getGui().showCardPromptMessage(getOwner(), message, sav.getHostCard()); } protected final void showMessage(final String message, final CardView card) { - controller.getGui().showPromptMessage(getOwner(), message, card); + controller.getGui().showCardPromptMessage(getOwner(), message, card); } protected String getTurnPhasePriorityMessage(final Game game) { diff --git a/forge-gui/src/main/java/forge/gamemodes/net/CObjectInputStream.java b/forge-gui/src/main/java/forge/gamemodes/net/CObjectInputStream.java index 9a7303230df..95d21c52637 100644 --- a/forge-gui/src/main/java/forge/gamemodes/net/CObjectInputStream.java +++ b/forge-gui/src/main/java/forge/gamemodes/net/CObjectInputStream.java @@ -5,7 +5,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectStreamClass; -import java.io.StreamCorruptedException; import io.netty.handler.codec.serialization.ClassResolver; @@ -23,16 +22,19 @@ public class CObjectInputStream extends ObjectInputStream { if (type < 0) { throw new EOFException(); } else { - switch(type) { - case 0: - return super.readClassDescriptor(); - case 1: - String className = readUTF(); - Class clazz = classResolver.resolve(className); - return ObjectStreamClass.lookupAny(clazz); - default: - throw new StreamCorruptedException("Unexpected class descriptor type: " + type); + ObjectStreamClass resultClassDescriptor = super.readClassDescriptor(); + Class localClass; + try { + localClass = Class.forName(resultClassDescriptor.getName()); + } catch (ClassNotFoundException e) { + System.err.println("[Class Not Found Exception]\nNo local class for " + resultClassDescriptor.getName()); + return resultClassDescriptor; } + ObjectStreamClass localClassDescriptor = ObjectStreamClass.lookupAny(localClass); + if (localClassDescriptor != null && type == 1) { + resultClassDescriptor = localClassDescriptor; // Use local class descriptor for deserialization by default + } + return resultClassDescriptor; } } diff --git a/forge-gui/src/main/java/forge/gamemodes/net/ProtocolMethod.java b/forge-gui/src/main/java/forge/gamemodes/net/ProtocolMethod.java index e29adcf0095..85017d15070 100644 --- a/forge-gui/src/main/java/forge/gamemodes/net/ProtocolMethod.java +++ b/forge-gui/src/main/java/forge/gamemodes/net/ProtocolMethod.java @@ -32,21 +32,22 @@ public enum ProtocolMethod { // Server -> Client setGameView (Mode.SERVER, Void.TYPE, GameView.class), openView (Mode.SERVER, Void.TYPE, TrackableCollection/*PlayerView*/.class), - afterGameEnd (Mode.SERVER), - showCombat (Mode.SERVER), + afterGameEnd (Mode.SERVER, Void.TYPE), + showCombat (Mode.SERVER, Void.TYPE), showPromptMessage (Mode.SERVER, Void.TYPE, PlayerView.class, String.class), + showCardPromptMessage (Mode.SERVER, Void.TYPE, PlayerView.class, String.class, CardView.class), updateButtons (Mode.SERVER, Void.TYPE, PlayerView.class, String.class, String.class, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE), - flashIncorrectAction(Mode.SERVER), - alertUser (Mode.SERVER), + flashIncorrectAction(Mode.SERVER, Void.TYPE), + alertUser (Mode.SERVER, Void.TYPE), updatePhase (Mode.SERVER, Void.TYPE, Boolean.TYPE), updateTurn (Mode.SERVER, Void.TYPE, PlayerView.class), - updatePlayerControl (Mode.SERVER), - enableOverlay (Mode.SERVER), - disableOverlay (Mode.SERVER), - finishGame (Mode.SERVER), + updatePlayerControl (Mode.SERVER, Void.TYPE), + enableOverlay (Mode.SERVER, Void.TYPE), + disableOverlay (Mode.SERVER, Void.TYPE), + finishGame (Mode.SERVER, Void.TYPE), showManaPool (Mode.SERVER, Void.TYPE, PlayerView.class), hideManaPool (Mode.SERVER, Void.TYPE, PlayerView.class), - updateStack (Mode.SERVER), + updateStack (Mode.SERVER, Void.TYPE), updateZones (Mode.SERVER, Void.TYPE, Iterable/*PlayerZoneUpdate*/.class), tempShowZones (Mode.SERVER, Iterable/*PlayerZoneUpdate*/.class, PlayerView.class, Iterable/*PlayerZoneUpdate*/.class), hideZones (Mode.SERVER, Void.TYPE, PlayerView.class, Iterable/*PlayerZoneUpdate*/.class), @@ -71,11 +72,11 @@ public enum ProtocolMethod { manipulateCardList (Mode.SERVER, List.class, String.class, Iterable.class, Iterable.class, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE), setCard (Mode.SERVER, Void.TYPE, CardView.class), setSelectables (Mode.SERVER, Void.TYPE, Iterable/*CardView*/.class), - clearSelectables (Mode.SERVER), - refreshField (Mode.SERVER), + clearSelectables (Mode.SERVER, Void.TYPE), + refreshField (Mode.SERVER, Void.TYPE, Boolean.TYPE), // TODO case "setPlayerAvatar": openZones (Mode.SERVER, PlayerZoneUpdates.class, PlayerView.class, Collection/*ZoneType*/.class, Map/*PlayerView,Object*/.class), - restoreOldZones (Mode.SERVER, Void.TYPE, PlayerView.class, PlayerZoneUpdates.class), + restoreOldZones (Mode.SERVER, Void.TYPE, PlayerView.class, Iterable/*PlayerZoneUpdates*/.class), isUiSetToSkipPhase (Mode.SERVER, Boolean.TYPE, PlayerView.class, PhaseType.class), setRememberedActions(Mode.SERVER, Void.TYPE), nextRememberedAction(Mode.SERVER, Void.TYPE), @@ -85,18 +86,18 @@ public enum ProtocolMethod { // which client and server wait for one another's response and block // the threads that're supposed to give that response useMana (Mode.CLIENT, Void.TYPE, Byte.TYPE), - undoLastAction (Mode.CLIENT, Void.TYPE, Boolean.TYPE), + undoLastAction (Mode.CLIENT, Void.TYPE), selectPlayer (Mode.CLIENT, Void.TYPE, PlayerView.class, ITriggerEvent.class), selectCard (Mode.CLIENT, Void.TYPE, CardView.class, List.class, ITriggerEvent.class), - selectButtonOk (Mode.CLIENT), - selectButtonCancel (Mode.CLIENT), + selectButtonOk (Mode.CLIENT, Void.TYPE), + selectButtonCancel (Mode.CLIENT, Void.TYPE), selectAbility (Mode.CLIENT, Void.TYPE, SpellAbilityView.class), - passPriorityUntilEndOfTurn(Mode.CLIENT), - passPriority (Mode.CLIENT), + passPriorityUntilEndOfTurn(Mode.CLIENT, Void.TYPE), + passPriority (Mode.CLIENT, Void.TYPE), nextGameDecision (Mode.CLIENT, Void.TYPE, NextGameDecision.class), getActivateDescription (Mode.CLIENT, String.class, CardView.class), - concede (Mode.CLIENT), - alphaStrike (Mode.CLIENT), + concede (Mode.CLIENT, Void.TYPE), + alphaStrike (Mode.CLIENT, Void.TYPE), reorderHand (Mode.CLIENT, Void.TYPE, CardView.class, Integer.TYPE); private enum Mode { @@ -161,13 +162,17 @@ public enum ProtocolMethod { if(!GuiBase.hasPropertyConfig()) return; //if the experimental network option is enabled, then check the args, else let the default decoder handle it - for (int iArg = 0; iArg < args.length; iArg++) { - final Object arg = args[iArg]; - final Class type = this.args[iArg]; - if (!ReflectionUtil.isInstance(arg, type)) { - //throw new InternalError(String.format("Protocol method %s: illegal argument (%d) of type %s, %s expected", name(), iArg, arg.getClass().getName(), type.getName())); - System.err.println(String.format("InternalError: Protocol method %s: illegal argument (%d) of type %s, %s expected (ProtocolMethod.java)", name(), iArg, arg.getClass().getName(), type.getName())); + try { + for (int iArg = 0; iArg < args.length; iArg++) { + final Object arg = args[iArg]; + final Class type = this.args[iArg]; + if (!ReflectionUtil.isInstance(arg, type)) { + //throw new InternalError(String.format("Protocol method %s: illegal argument (%d) of type %s, %s expected", name(), iArg, arg.getClass().getName(), type.getName())); + System.err.println(String.format("InternalError: Protocol method %s: illegal argument (%d) of type %s, %s expected (ProtocolMethod.java)", name(), iArg, arg.getClass().getName(), type.getName())); + } } + } catch (Exception e) { + e.printStackTrace(); } } diff --git a/forge-gui/src/main/java/forge/gamemodes/net/server/NetGuiGame.java b/forge-gui/src/main/java/forge/gamemodes/net/server/NetGuiGame.java index a88d5e6d960..c3788e4b3fb 100644 --- a/forge-gui/src/main/java/forge/gamemodes/net/server/NetGuiGame.java +++ b/forge-gui/src/main/java/forge/gamemodes/net/server/NetGuiGame.java @@ -76,9 +76,9 @@ public class NetGuiGame extends AbstractGuiGame { } @Override - public void showPromptMessage(final PlayerView playerView, final String message, final CardView card) { + public void showCardPromptMessage(final PlayerView playerView, final String message, final CardView card) { updateGameView(); - send(ProtocolMethod.showPromptMessage, playerView, message); + send(ProtocolMethod.showCardPromptMessage, playerView, message, card); } @Override diff --git a/forge-gui/src/main/java/forge/gui/interfaces/IGuiGame.java b/forge-gui/src/main/java/forge/gui/interfaces/IGuiGame.java index 849f170c837..9cf1c96fb09 100644 --- a/forge-gui/src/main/java/forge/gui/interfaces/IGuiGame.java +++ b/forge-gui/src/main/java/forge/gui/interfaces/IGuiGame.java @@ -39,7 +39,7 @@ public interface IGuiGame { void afterGameEnd(); void showCombat(); void showPromptMessage(PlayerView playerView, String message); - void showPromptMessage(PlayerView playerView, String message, CardView card); + void showCardPromptMessage(PlayerView playerView, String message, CardView card); void updateButtons(PlayerView owner, boolean okEnabled, boolean cancelEnabled, boolean focusOk); void updateButtons(PlayerView owner, String label1, String label2, boolean enable1, boolean enable2, boolean focus1); void flashIncorrectAction(); From e176a4791dc90606b1cd6c8bf7f81d1a0a9072d4 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Tue, 8 Mar 2022 10:45:48 +0800 Subject: [PATCH 3/3] remove extra field --- forge-gui/src/main/java/forge/gamemodes/net/ProtocolMethod.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-gui/src/main/java/forge/gamemodes/net/ProtocolMethod.java b/forge-gui/src/main/java/forge/gamemodes/net/ProtocolMethod.java index 85017d15070..e8bf8957670 100644 --- a/forge-gui/src/main/java/forge/gamemodes/net/ProtocolMethod.java +++ b/forge-gui/src/main/java/forge/gamemodes/net/ProtocolMethod.java @@ -73,7 +73,7 @@ public enum ProtocolMethod { setCard (Mode.SERVER, Void.TYPE, CardView.class), setSelectables (Mode.SERVER, Void.TYPE, Iterable/*CardView*/.class), clearSelectables (Mode.SERVER, Void.TYPE), - refreshField (Mode.SERVER, Void.TYPE, Boolean.TYPE), + refreshField (Mode.SERVER, Void.TYPE), // TODO case "setPlayerAvatar": openZones (Mode.SERVER, PlayerZoneUpdates.class, PlayerView.class, Collection/*ZoneType*/.class, Map/*PlayerView,Object*/.class), restoreOldZones (Mode.SERVER, Void.TYPE, PlayerView.class, Iterable/*PlayerZoneUpdates*/.class),