diff --git a/forge-game/src/main/java/forge/game/phase/PhaseType.java b/forge-game/src/main/java/forge/game/phase/PhaseType.java index 0cea056d0ab..a1f5a208a75 100644 --- a/forge-game/src/main/java/forge/game/phase/PhaseType.java +++ b/forge-game/src/main/java/forge/game/phase/PhaseType.java @@ -55,6 +55,11 @@ public enum PhaseType { return result; } + public final boolean isCombatPhase() { + return ((ALL_PHASES.indexOf(this) >= ALL_PHASES.indexOf(COMBAT_BEGIN)) + && (ALL_PHASES.indexOf(this) <= ALL_PHASES.indexOf(COMBAT_END))); + } + public final boolean isAfter(final PhaseType phase) { return ALL_PHASES.indexOf(this) > ALL_PHASES.indexOf(phase); } diff --git a/forge-gui-android/proguard.cfg b/forge-gui-android/proguard.cfg index 8ed1f08d7f1..ab6fbdeecf0 100644 --- a/forge-gui-android/proguard.cfg +++ b/forge-gui-android/proguard.cfg @@ -39,6 +39,7 @@ -keep class com.google.common.** { *; } -keep class io.sentry.event.Event { *; } -keep class io.netty.util.internal.logging.** { *; } +-keep class net.jpountz.** { *; } -keepclassmembers class com.badlogic.gdx.backends.android.AndroidInput* { (com.badlogic.gdx.Application, android.content.Context, java.lang.Object, com.badlogic.gdx.backends.android.AndroidApplicationConfiguration); diff --git a/forge-gui-android/src/forge/app/Main.java b/forge-gui-android/src/forge/app/Main.java index 752253cd617..a54df3b32e3 100644 --- a/forge-gui-android/src/forge/app/Main.java +++ b/forge-gui-android/src/forge/app/Main.java @@ -186,6 +186,7 @@ public class Main extends AndroidApplication { } private void initForge(AndroidAdapter adapter, boolean permissiongranted){ + boolean isPortrait; //establish assets directory if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { Gdx.app.error("Forge", "Can't access external storage"); @@ -211,20 +212,23 @@ public class Main extends AndroidApplication { boolean landscapeMode = adapter.isTablet == !FileUtil.doesFileExist(adapter.switchOrientationFile); if (permissiongranted){ if (landscapeMode) { + isPortrait = false; Main.this.setRequestedOrientation(Build.VERSION.SDK_INT >= 26 ? ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE : //Oreo and above has virtual back/menu buttons ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } else { + isPortrait = true; Main.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } } else { + isPortrait = true; //set current orientation Main.this.setRequestedOrientation(Main.this.getResources().getConfiguration().orientation); } ForgePreferences prefs = FModel.getPreferences(); boolean propertyConfig = prefs != null && prefs.getPrefBoolean(ForgePreferences.FPref.UI_NETPLAY_COMPAT); - initialize(Forge.getApp(new AndroidClipboard(), adapter, assetsDir, propertyConfig)); + initialize(Forge.getApp(new AndroidClipboard(), adapter, assetsDir, propertyConfig, isPortrait)); } /*@Override diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/online/VSubmenuOnlineLobby.java b/forge-gui-desktop/src/main/java/forge/screens/home/online/VSubmenuOnlineLobby.java index 0b9c344906a..10f2b5ea446 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/online/VSubmenuOnlineLobby.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/online/VSubmenuOnlineLobby.java @@ -200,4 +200,8 @@ public enum VSubmenuOnlineLobby implements IVSubmenu, IOnli } return false; } + + @Override + public void closeConn(String msg) { + } } diff --git a/forge-gui-ios/src/forge/ios/Main.java b/forge-gui-ios/src/forge/ios/Main.java index b22e1923bd0..57fe63bc77c 100644 --- a/forge-gui-ios/src/forge/ios/Main.java +++ b/forge-gui-ios/src/forge/ios/Main.java @@ -33,7 +33,7 @@ public class Main extends IOSApplication.Delegate { config.useCompass = false; ForgePreferences prefs = FModel.getPreferences(); boolean propertyConfig = prefs != null && prefs.getPrefBoolean(ForgePreferences.FPref.UI_NETPLAY_COMPAT); - final ApplicationListener app = Forge.getApp(new IOSClipboard(), new IOSAdapter(), assetsDir, propertyConfig); + final ApplicationListener app = Forge.getApp(new IOSClipboard(), new IOSAdapter(), assetsDir, propertyConfig, false); final IOSApplication iosApp = new IOSApplication(app, config); return iosApp; } diff --git a/forge-gui-mobile-dev/src/forge/app/Main.java b/forge-gui-mobile-dev/src/forge/app/Main.java index 014bc13f08f..620209f7d74 100644 --- a/forge-gui-mobile-dev/src/forge/app/Main.java +++ b/forge-gui-mobile-dev/src/forge/app/Main.java @@ -97,7 +97,7 @@ public class Main { ForgePreferences prefs = FModel.getPreferences(); boolean propertyConfig = prefs != null && prefs.getPrefBoolean(ForgePreferences.FPref.UI_NETPLAY_COMPAT); new LwjglApplication(Forge.getApp(new LwjglClipboard(), new DesktopAdapter(switchOrientationFile), - desktopMode ? desktopModeAssetsDir : assetsDir, propertyConfig), config); + desktopMode ? desktopModeAssetsDir : assetsDir, propertyConfig, false), config); } private static class DesktopAdapter implements IDeviceAdapter { diff --git a/forge-gui-mobile/src/forge/Forge.java b/forge-gui-mobile/src/forge/Forge.java index 0102b16c2b3..4cbb9b327db 100644 --- a/forge-gui-mobile/src/forge/Forge.java +++ b/forge-gui-mobile/src/forge/Forge.java @@ -69,13 +69,15 @@ public class Forge implements ApplicationListener { public static String locale = "en-US"; public static boolean hdbuttons = false; public static boolean hdstart = false; + public static boolean isPortraitMode = false; - public static ApplicationListener getApp(Clipboard clipboard0, IDeviceAdapter deviceAdapter0, String assetDir0, boolean value) { + public static ApplicationListener getApp(Clipboard clipboard0, IDeviceAdapter deviceAdapter0, String assetDir0, boolean value, boolean androidOrientation) { if (GuiBase.getInterface() == null) { clipboard = clipboard0; deviceAdapter = deviceAdapter0; GuiBase.setInterface(new GuiMobile(assetDir0)); GuiBase.enablePropertyConfig(value); + isPortraitMode = androidOrientation; } return app; } @@ -373,6 +375,8 @@ public class Forge implements ApplicationListener { } public static boolean isLandscapeMode() { + if(GuiBase.isAndroid()) + return !isPortraitMode; return screenWidth > screenHeight; } diff --git a/forge-gui-mobile/src/forge/screens/FScreen.java b/forge-gui-mobile/src/forge/screens/FScreen.java index 163c5276e17..7ceece302c6 100644 --- a/forge-gui-mobile/src/forge/screens/FScreen.java +++ b/forge-gui-mobile/src/forge/screens/FScreen.java @@ -8,6 +8,7 @@ import com.badlogic.gdx.utils.Align; import forge.Forge; import forge.Graphics; +import forge.GuiBase; import forge.assets.FImage; import forge.assets.FSkinColor; import forge.assets.FSkinColor.Colors; @@ -80,14 +81,12 @@ public abstract class FScreen extends FContainer { @Override protected final void doLayout(float width, float height) { - if (width > height) { //handle landscape layout special - doLandscapeLayout(width, height); - } - else if (header != null) { + if ((GuiBase.isAndroid() && Forge.isLandscapeMode())||(width > height)) { + doLandscapeLayout(width, height); //handle landscape layout special + } else if (header != null) { header.setBounds(0, 0, width, header.getPreferredHeight()); doLayout(header.getHeight(), width, height); - } - else { + } else { doLayout(0, width, height); } } diff --git a/forge-gui-mobile/src/forge/screens/constructed/LobbyScreen.java b/forge-gui-mobile/src/forge/screens/constructed/LobbyScreen.java index 7ecde4cd371..5d6fd28f4d6 100644 --- a/forge-gui-mobile/src/forge/screens/constructed/LobbyScreen.java +++ b/forge-gui-mobile/src/forge/screens/constructed/LobbyScreen.java @@ -11,6 +11,7 @@ import forge.deck.DeckSection; import forge.deck.DeckType; import forge.deck.FDeckChooser; +import forge.net.server.FServerManager; import forge.util.Localizer; import org.apache.commons.lang3.StringUtils; @@ -530,6 +531,8 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView { GuiBase.setNetworkplay(allowNetworking); + setStartButtonAvailability(); + for (int i = 0; i < cbPlayerCount.getSelectedItem(); i++) { final boolean hasPanel = i < playerPanels.size(); if (i < playerCount) { @@ -731,4 +734,11 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView { public FScrollPane getPlayersScroll() { return playersScroll; } + + public void setStartButtonAvailability() { + if (lobby.isAllowNetworking() && FServerManager.getInstance() != null) + btnStart.setVisible(FServerManager.getInstance().isHosting()); + else + btnStart.setVisible(true); + } } diff --git a/forge-gui-mobile/src/forge/screens/match/MatchController.java b/forge-gui-mobile/src/forge/screens/match/MatchController.java index 8cc153d9ac4..a438e2510ed 100644 --- a/forge-gui-mobile/src/forge/screens/match/MatchController.java +++ b/forge-gui-mobile/src/forge/screens/match/MatchController.java @@ -125,15 +125,12 @@ public class MatchController extends AbstractGuiGame { @Override public void refreshField() { - if(!GuiBase.isNetworkplay()) //TODO alternate method for update Netplay... - return; - if(getGameView() == null) + if(!GuiBase.isNetworkplay()) return; if(getGameView().getPhase() == null) return; if (getGameView().getPhase().phaseforUpdateField()) - for (final VPlayerPanel pnl : view.getPlayerPanels().values()) - pnl.getField().update(false); + refreshCardDetails(null); } public boolean hotSeatMode() { diff --git a/forge-gui-mobile/src/forge/screens/match/MatchScreen.java b/forge-gui-mobile/src/forge/screens/match/MatchScreen.java index d736fdf1011..82479ebb60c 100644 --- a/forge-gui-mobile/src/forge/screens/match/MatchScreen.java +++ b/forge-gui-mobile/src/forge/screens/match/MatchScreen.java @@ -565,6 +565,7 @@ public class MatchScreen extends FScreen { float x = 0; float y; float w = getWidth(); + Color color = Color.CYAN; //field separator lines if (!Forge.isLandscapeMode()) { @@ -591,17 +592,43 @@ public class MatchScreen extends FScreen { //Draw Priority Human Multiplayer 2 player float oldAlphaComposite = g.getfloatAlphaComposite(); + + if ((getPlayerPanels().keySet().size() == 2) && (countHuman() == 2)){ for (VPlayerPanel playerPanel: playerPanelsList){ midField = playerPanel.getTop(); y = midField - 0.5f; float adjustY = Forge.isLandscapeMode() ? y + 1f : midField; float adjustH = Forge.isLandscapeMode() ? playerPanel.getField().getBottom() - 1f : playerPanel.getBottom() - 1f; - if(playerPanel.getPlayer().getHasPriority() && !playerPanel.getPlayer().isAI()) + + if(playerPanel.getPlayer().getHasPriority()) g.setAlphaComposite(0.8f); else g.setAlphaComposite(0f); - g.drawRect(4f, Color.CYAN, playerPanel.getField().getLeft(), adjustY, playerPanel.getField().getWidth(), adjustH); + + if(MatchController.instance.getGameView()!= null) { + if(MatchController.instance.getGameView().getPhase()!=null) + { + if(MatchController.instance.getGameView().getPhase().isCombatPhase()){ + if(playerPanel.getPlayer() == MatchController.instance.getCurrentPlayer()) + g.setAlphaComposite(0.8f); + else + g.setAlphaComposite(0f); + } + } + + + if(MatchController.instance.getGameView().getCombat() != null) { + if(playerPanel.getPlayer() == MatchController.instance.getGameView().getPlayerTurn()) + color = Color.RED; + else + color = Color.LIME; + } + else + color = Color.CYAN; + } + + g.drawRect(4f, color, playerPanel.getField().getLeft(), adjustY, playerPanel.getField().getWidth(), adjustH); g.setAlphaComposite(oldAlphaComposite); } } diff --git a/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java b/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java index 5caf394fdd6..6af3cc4c31f 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java @@ -10,6 +10,7 @@ import com.badlogic.gdx.math.Vector2; import forge.FThreads; import forge.Graphics; +import forge.GuiBase; import forge.card.CardZoom; import forge.card.CardRenderer.CardStackPosition; import forge.card.CardZoom.ActivateHandler; @@ -184,7 +185,10 @@ public abstract class VCardDisplayArea extends VDisplayArea implements ActivateH @Override public String getActivateAction(int index) { - return MatchController.instance.getGameController().getActivateDescription(orderedCards.get(index)); + if(!GuiBase.isNetworkplay()) //causes lag on netplay client side + return MatchController.instance.getGameController().getActivateDescription(orderedCards.get(index)); + + return "Activate | Cast | Play (if allowed)"; //simple text on card zoom swipe up } @Override diff --git a/forge-gui-mobile/src/forge/screens/match/views/VZoneDisplay.java b/forge-gui-mobile/src/forge/screens/match/views/VZoneDisplay.java index b3ab177f1b0..1b814d2752f 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VZoneDisplay.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VZoneDisplay.java @@ -66,7 +66,12 @@ public class VZoneDisplay extends VCardDisplayArea { } private void setRevealedPanel(int idx) { - revealedPanel = cardPanels.get(idx); + try { + revealedPanel = cardPanels.get(idx); //??? on network match, triggered by card ability + } catch (ArrayIndexOutOfBoundsException e) { + e.printStackTrace(); + return; + } clearChildren(); if (Forge.isLandscapeMode()) { //for landscape mode, just show revealed card on top diff --git a/forge-gui-mobile/src/forge/screens/online/OnlineLobbyScreen.java b/forge-gui-mobile/src/forge/screens/online/OnlineLobbyScreen.java index 048d9e4502d..43639400396 100644 --- a/forge-gui-mobile/src/forge/screens/online/OnlineLobbyScreen.java +++ b/forge-gui-mobile/src/forge/screens/online/OnlineLobbyScreen.java @@ -1,7 +1,9 @@ package forge.screens.online; +import com.google.common.collect.ImmutableList; import forge.FThreads; import forge.Forge; +import forge.GuiBase; import forge.assets.FSkinProp; import forge.interfaces.ILobbyView; import forge.match.GameLobby; @@ -11,6 +13,7 @@ import forge.net.IOnlineLobby; import forge.net.NetConnectUtil; import forge.net.OfflineLobby; import forge.net.client.FGameClient; +import forge.net.server.FServerManager; import forge.properties.ForgeConstants; import forge.screens.LoadingOverlay; import forge.screens.constructed.LobbyScreen; @@ -47,6 +50,7 @@ public class OnlineLobbyScreen extends LobbyScreen implements IOnlineLobby { fGameClient = null; } + @Override public void closeConn(String msg) { clearGameLobby(); Forge.back(); @@ -54,7 +58,15 @@ public class OnlineLobbyScreen extends LobbyScreen implements IOnlineLobby { FThreads.invokeInBackgroundThread(new Runnable() { @Override public void run() { - SOptionPane.showMessageDialog(msg, "Error", FSkinProp.ICO_WARNING); + final boolean callBackAlwaysTrue = SOptionPane.showOptionDialog(msg, "Error", FSkinProp.ICO_WARNING, ImmutableList.of("Ok"), 1) == 0; + if (callBackAlwaysTrue) { //to activate online menu popup when player press play online + GuiBase.setInterrupted(false); + + if(FServerManager.getInstance() != null) + FServerManager.getInstance().stopServer(); + if(getfGameClient() != null) + closeClient(); + } } }); } @@ -73,6 +85,10 @@ public class OnlineLobbyScreen extends LobbyScreen implements IOnlineLobby { @Override public void onActivate() { + if (GuiBase.isInterrupted()) { + GuiBase.setInterrupted(false); + return; + } if (getGameLobby() == null) { setGameLobby(getLobby()); //prompt to connect to server when offline lobby activated diff --git a/forge-gui/pom.xml b/forge-gui/pom.xml index c4097dc235d..929a9e2019d 100644 --- a/forge-gui/pom.xml +++ b/forge-gui/pom.xml @@ -77,6 +77,11 @@ slf4j-simple 1.7.22 + + org.lz4 + lz4-java + 1.7.1 + diff --git a/forge-gui/src/main/java/forge/GuiBase.java b/forge-gui/src/main/java/forge/GuiBase.java index 89001f1da97..52d487a467c 100644 --- a/forge-gui/src/main/java/forge/GuiBase.java +++ b/forge-gui/src/main/java/forge/GuiBase.java @@ -7,23 +7,20 @@ public class GuiBase { private static boolean propertyConfig = true; private static boolean networkplay = false; private static boolean isAndroidport = false; + private static boolean interrupted = false; + + public static IGuiBase getInterface() { return guiInterface; } + public static void setInterface(IGuiBase i0) { guiInterface = i0; } - public static IGuiBase getInterface() { - return guiInterface; - } - public static void setInterface(IGuiBase i0) { - guiInterface = i0; - } - public static void enablePropertyConfig(boolean value) { propertyConfig = value; } public static void setIsAndroid(boolean value) { isAndroidport = value; } public static boolean isAndroid() { return isAndroidport; } - public static boolean isNetworkplay() { - return networkplay; - } - public static void setNetworkplay(boolean value) { - networkplay = value; - } - public static boolean hasPropertyConfig() { - return propertyConfig; - } + + public static boolean isNetworkplay() { return networkplay; } + public static void setNetworkplay(boolean value) { networkplay = value; } + + public static boolean hasPropertyConfig() { return propertyConfig; } + public static void enablePropertyConfig(boolean value) { propertyConfig = value; } + + public static void setInterrupted(boolean value) { interrupted = value; } + public static boolean isInterrupted() { return interrupted; } } diff --git a/forge-gui/src/main/java/forge/net/CObjectInputStream.java b/forge-gui/src/main/java/forge/net/CObjectInputStream.java index b6d53c311ad..347879e6570 100644 --- a/forge-gui/src/main/java/forge/net/CObjectInputStream.java +++ b/forge-gui/src/main/java/forge/net/CObjectInputStream.java @@ -17,15 +17,9 @@ public class CObjectInputStream extends ObjectInputStream { this.classResolver = classResolver; } - protected void readStreamHeader() throws IOException { - int version = this.readByte() & 255; - if (version != 5) { - throw new StreamCorruptedException("Unsupported version: " + version); - } - } - + @Override protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException { - int type = this.read(); + int type = read(); if (type < 0) { throw new EOFException(); } else { @@ -33,8 +27,8 @@ public class CObjectInputStream extends ObjectInputStream { case 0: return super.readClassDescriptor(); case 1: - String className = this.readUTF(); - Class clazz = this.classResolver.resolve(className); + String className = readUTF(); + Class clazz = classResolver.resolve(className); return ObjectStreamClass.lookupAny(clazz); default: throw new StreamCorruptedException("Unexpected class descriptor type: " + type); @@ -42,14 +36,14 @@ public class CObjectInputStream extends ObjectInputStream { } } + @Override protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { - Class clazz; + Class clazz; try { - clazz = this.classResolver.resolve(desc.getName()); - } catch (ClassNotFoundException var4) { + clazz = classResolver.resolve(desc.getName()); + } catch (ClassNotFoundException ignored) { clazz = super.resolveClass(desc); } - return clazz; } } diff --git a/forge-gui/src/main/java/forge/net/CObjectOutputStream.java b/forge-gui/src/main/java/forge/net/CObjectOutputStream.java index b086ad87827..e0c408aa923 100644 --- a/forge-gui/src/main/java/forge/net/CObjectOutputStream.java +++ b/forge-gui/src/main/java/forge/net/CObjectOutputStream.java @@ -6,26 +6,16 @@ import java.io.ObjectStreamClass; import java.io.OutputStream; public class CObjectOutputStream extends ObjectOutputStream { - static final int TYPE_FAT_DESCRIPTOR = 0; static final int TYPE_THIN_DESCRIPTOR = 1; CObjectOutputStream(OutputStream out) throws IOException { super(out); } - protected void writeStreamHeader() throws IOException { - this.writeByte(5); - } - + @Override protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException { - Class clazz = desc.forClass(); - if (!clazz.isPrimitive() && !clazz.isArray() && !clazz.isInterface() && desc.getSerialVersionUID() != 0L) { - this.write(1); - this.writeUTF(desc.getName()); - } else { - this.write(0); - super.writeClassDescriptor(desc); - } - + //we only pass this and the decoder will lookup in the stream (faster method both mobile and desktop) + write(TYPE_THIN_DESCRIPTOR); + writeUTF(desc.getName()); } } diff --git a/forge-gui/src/main/java/forge/net/CompatibleObjectDecoder.java b/forge-gui/src/main/java/forge/net/CompatibleObjectDecoder.java index ff836965c88..c288eace00b 100644 --- a/forge-gui/src/main/java/forge/net/CompatibleObjectDecoder.java +++ b/forge-gui/src/main/java/forge/net/CompatibleObjectDecoder.java @@ -6,6 +6,7 @@ import io.netty.buffer.ByteBufInputStream; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import io.netty.handler.codec.serialization.ClassResolver; +import net.jpountz.lz4.LZ4BlockInputStream; import java.io.ObjectInputStream; import java.io.StreamCorruptedException; @@ -22,20 +23,21 @@ public class CompatibleObjectDecoder extends LengthFieldBasedFrameDecoder { this.classResolver = classResolver; } + @Override protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { ByteBuf frame = (ByteBuf)super.decode(ctx, in); if (frame == null) { return null; } else { ObjectInputStream ois = GuiBase.hasPropertyConfig() ? - new ObjectInputStream(new ByteBufInputStream(frame, true)): - new CObjectInputStream(new ByteBufInputStream(frame, true),this.classResolver); + new ObjectInputStream(new LZ4BlockInputStream(new ByteBufInputStream(frame, true))): + new CObjectInputStream(new LZ4BlockInputStream(new ByteBufInputStream(frame, true)),this.classResolver); Object var5 = null; try { var5 = ois.readObject(); } catch (StreamCorruptedException e) { - e.printStackTrace(); + System.err.println(String.format("Version Mismatch: %s", e.getMessage())); } finally { ois.close(); } diff --git a/forge-gui/src/main/java/forge/net/CompatibleObjectEncoder.java b/forge-gui/src/main/java/forge/net/CompatibleObjectEncoder.java index a1060ed1a30..59709288d41 100644 --- a/forge-gui/src/main/java/forge/net/CompatibleObjectEncoder.java +++ b/forge-gui/src/main/java/forge/net/CompatibleObjectEncoder.java @@ -5,6 +5,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufOutputStream; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToByteEncoder; +import net.jpountz.lz4.LZ4BlockOutputStream; import java.io.ObjectOutputStream; import java.io.Serializable; @@ -20,7 +21,7 @@ public class CompatibleObjectEncoder extends MessageToByteEncoder try { bout.write(LENGTH_PLACEHOLDER); - oout = GuiBase.hasPropertyConfig() ? new ObjectOutputStream(bout) : new CObjectOutputStream(bout); + oout = GuiBase.hasPropertyConfig() ? new ObjectOutputStream(new LZ4BlockOutputStream(bout)) : new CObjectOutputStream(new LZ4BlockOutputStream(bout)); oout.writeObject(msg); oout.flush(); } finally { diff --git a/forge-gui/src/main/java/forge/net/IOnlineLobby.java b/forge-gui/src/main/java/forge/net/IOnlineLobby.java index 29d75d91634..be7a2bcefd9 100644 --- a/forge-gui/src/main/java/forge/net/IOnlineLobby.java +++ b/forge-gui/src/main/java/forge/net/IOnlineLobby.java @@ -7,4 +7,5 @@ import forge.net.client.FGameClient; public interface IOnlineLobby { ILobbyView setLobby(GameLobby lobby); void setClient(FGameClient client); + void closeConn(String msg); } diff --git a/forge-gui/src/main/java/forge/net/NetConnectUtil.java b/forge-gui/src/main/java/forge/net/NetConnectUtil.java index 8b9e5fc39db..86d32841074 100644 --- a/forge-gui/src/main/java/forge/net/NetConnectUtil.java +++ b/forge-gui/src/main/java/forge/net/NetConnectUtil.java @@ -5,7 +5,6 @@ import forge.properties.ForgeConstants; import org.apache.commons.lang3.StringUtils; import forge.GuiBase; -import forge.assets.FSkinProp; import forge.interfaces.IGuiGame; import forge.interfaces.ILobbyListener; import forge.interfaces.ILobbyView; @@ -146,8 +145,8 @@ public class NetConnectUtil { } @Override public final void close() { - SOptionPane.showMessageDialog("Your connection to the host (" + url + ") was interrupted.", "Error", FSkinProp.ICO_WARNING); - onlineLobby.setClient(null); + GuiBase.setInterrupted(true); + onlineLobby.closeConn("Your connection to the host (" + url + ") was interrupted."); } @Override public ClientGameLobby getLobby() { diff --git a/forge-gui/src/main/java/forge/net/ProtocolMethod.java b/forge-gui/src/main/java/forge/net/ProtocolMethod.java index 8a274e99437..058c6c260fb 100644 --- a/forge-gui/src/main/java/forge/net/ProtocolMethod.java +++ b/forge-gui/src/main/java/forge/net/ProtocolMethod.java @@ -1,6 +1,7 @@ package forge.net; import com.google.common.base.Function; +import forge.GuiBase; import forge.assets.FSkinProp; import forge.deck.CardPool; import forge.game.GameEntityView; @@ -155,28 +156,16 @@ public enum ProtocolMethod { } public void checkArgs(final Object[] args) { + 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 Line 163)", 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())); } - //this should be handled via decoder or it will process them twice - /*if (arg != null) { - // attempt to Serialize each argument, this will throw an exception if it can't. - try { - byte[] serialized = SerializationUtils.serialize((Serializable) arg); - SerializationUtils.deserialize(serialized); - } catch (ArrayIndexOutOfBoundsException ex) { - // not sure why this one would be thrown, but it is - // it also doesn't prevent things from working, so, log for now, pending full network rewrite - ex.printStackTrace(); - } catch(ConcurrentModificationException ex) { - // can't seem to avoid this from periodically happening - ex.printStackTrace(); - } - }*/ } } @@ -187,7 +176,7 @@ public enum ProtocolMethod { } if (!ReflectionUtil.isInstance(value, returnType)) { //throw new IllegalStateException(String.format("Protocol method %s: illegal return object type %s returned by client, expected %s", name(), value.getClass().getName(), getReturnType().getName())); - System.err.println(String.format("IllegalStateException: Protocol method %s: illegal return object type %s returned by client, expected %s (ProtocolMethod.java Line 190)", name(), value.getClass().getName(), getReturnType().getName())); + System.err.println(String.format("IllegalStateException: Protocol method %s: illegal return object type %s returned by client, expected %s (ProtocolMethod.java)", name(), value.getClass().getName(), getReturnType().getName())); } } } diff --git a/forge-gui/src/main/java/forge/net/client/NetGameController.java b/forge-gui/src/main/java/forge/net/client/NetGameController.java index 826f5901161..85fe12feed5 100644 --- a/forge-gui/src/main/java/forge/net/client/NetGameController.java +++ b/forge-gui/src/main/java/forge/net/client/NetGameController.java @@ -40,12 +40,12 @@ public class NetGameController implements IGameController { @Override public void selectPlayer(final PlayerView playerView, final ITriggerEvent triggerEvent) { - send(ProtocolMethod.selectPlayer, playerView, triggerEvent); + send(ProtocolMethod.selectPlayer, playerView, null/*triggerEvent*/); //some platform don't have mousetriggerevent class or it will not allow them to click/tap } @Override public boolean selectCard(final CardView cardView, final List otherCardViewsToSelect, final ITriggerEvent triggerEvent) { - send(ProtocolMethod.selectCard, cardView, otherCardViewsToSelect, triggerEvent); + send(ProtocolMethod.selectCard, cardView, otherCardViewsToSelect, null/*triggerEvent*/); //some platform don't have mousetriggerevent class or it will not allow them to click/tap // Difference from local games! Always consider a card as successfully selected, // to avoid blocks where server and client wait for each other to respond. // Some cost in functionality but a huge gain in stability & speed. diff --git a/forge-gui/src/main/java/forge/net/server/NetGuiGame.java b/forge-gui/src/main/java/forge/net/server/NetGuiGame.java index 33e6f727b07..c835d079f03 100644 --- a/forge-gui/src/main/java/forge/net/server/NetGuiGame.java +++ b/forge-gui/src/main/java/forge/net/server/NetGuiGame.java @@ -41,7 +41,7 @@ public class NetGuiGame extends AbstractGuiGame { return sender.sendAndWait(method, args); } - private void updateGameView() { + public void updateGameView() { send(ProtocolMethod.setGameView, getGameView()); } @@ -191,7 +191,7 @@ public class NetGuiGame extends AbstractGuiGame { @Override public SpellAbilityView getAbilityToPlay(final CardView hostCard, final List abilities, final ITriggerEvent triggerEvent) { - return sendAndWait(ProtocolMethod.getAbilityToPlay, hostCard, abilities, triggerEvent); + return sendAndWait(ProtocolMethod.getAbilityToPlay, hostCard, abilities, null/*triggerEvent*/); //someplatform don't have mousetriggerevent class or it will not allow them to click/tap } @Override