mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 18:58:00 +00:00
Network Improvements
This commit is contained in:
@@ -55,6 +55,11 @@ public enum PhaseType {
|
|||||||
return result;
|
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) {
|
public final boolean isAfter(final PhaseType phase) {
|
||||||
return ALL_PHASES.indexOf(this) > ALL_PHASES.indexOf(phase);
|
return ALL_PHASES.indexOf(this) > ALL_PHASES.indexOf(phase);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
-keep class com.google.common.** { *; }
|
-keep class com.google.common.** { *; }
|
||||||
-keep class io.sentry.event.Event { *; }
|
-keep class io.sentry.event.Event { *; }
|
||||||
-keep class io.netty.util.internal.logging.** { *; }
|
-keep class io.netty.util.internal.logging.** { *; }
|
||||||
|
-keep class net.jpountz.** { *; }
|
||||||
|
|
||||||
-keepclassmembers class com.badlogic.gdx.backends.android.AndroidInput* {
|
-keepclassmembers class com.badlogic.gdx.backends.android.AndroidInput* {
|
||||||
<init>(com.badlogic.gdx.Application, android.content.Context, java.lang.Object, com.badlogic.gdx.backends.android.AndroidApplicationConfiguration);
|
<init>(com.badlogic.gdx.Application, android.content.Context, java.lang.Object, com.badlogic.gdx.backends.android.AndroidApplicationConfiguration);
|
||||||
|
|||||||
@@ -186,6 +186,7 @@ public class Main extends AndroidApplication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initForge(AndroidAdapter adapter, boolean permissiongranted){
|
private void initForge(AndroidAdapter adapter, boolean permissiongranted){
|
||||||
|
boolean isPortrait;
|
||||||
//establish assets directory
|
//establish assets directory
|
||||||
if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
|
if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
|
||||||
Gdx.app.error("Forge", "Can't access external storage");
|
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);
|
boolean landscapeMode = adapter.isTablet == !FileUtil.doesFileExist(adapter.switchOrientationFile);
|
||||||
if (permissiongranted){
|
if (permissiongranted){
|
||||||
if (landscapeMode) {
|
if (landscapeMode) {
|
||||||
|
isPortrait = false;
|
||||||
Main.this.setRequestedOrientation(Build.VERSION.SDK_INT >= 26 ?
|
Main.this.setRequestedOrientation(Build.VERSION.SDK_INT >= 26 ?
|
||||||
ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE : //Oreo and above has virtual back/menu buttons
|
ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE : //Oreo and above has virtual back/menu buttons
|
||||||
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
||||||
} else {
|
} else {
|
||||||
|
isPortrait = true;
|
||||||
Main.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
Main.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
isPortrait = true;
|
||||||
//set current orientation
|
//set current orientation
|
||||||
Main.this.setRequestedOrientation(Main.this.getResources().getConfiguration().orientation);
|
Main.this.setRequestedOrientation(Main.this.getResources().getConfiguration().orientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
ForgePreferences prefs = FModel.getPreferences();
|
ForgePreferences prefs = FModel.getPreferences();
|
||||||
boolean propertyConfig = prefs != null && prefs.getPrefBoolean(ForgePreferences.FPref.UI_NETPLAY_COMPAT);
|
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
|
/*@Override
|
||||||
|
|||||||
@@ -200,4 +200,8 @@ public enum VSubmenuOnlineLobby implements IVSubmenu<CSubmenuOnlineLobby>, IOnli
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeConn(String msg) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class Main extends IOSApplication.Delegate {
|
|||||||
config.useCompass = false;
|
config.useCompass = false;
|
||||||
ForgePreferences prefs = FModel.getPreferences();
|
ForgePreferences prefs = FModel.getPreferences();
|
||||||
boolean propertyConfig = prefs != null && prefs.getPrefBoolean(ForgePreferences.FPref.UI_NETPLAY_COMPAT);
|
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);
|
final IOSApplication iosApp = new IOSApplication(app, config);
|
||||||
return iosApp;
|
return iosApp;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ public class Main {
|
|||||||
ForgePreferences prefs = FModel.getPreferences();
|
ForgePreferences prefs = FModel.getPreferences();
|
||||||
boolean propertyConfig = prefs != null && prefs.getPrefBoolean(ForgePreferences.FPref.UI_NETPLAY_COMPAT);
|
boolean propertyConfig = prefs != null && prefs.getPrefBoolean(ForgePreferences.FPref.UI_NETPLAY_COMPAT);
|
||||||
new LwjglApplication(Forge.getApp(new LwjglClipboard(), new DesktopAdapter(switchOrientationFile),
|
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 {
|
private static class DesktopAdapter implements IDeviceAdapter {
|
||||||
|
|||||||
@@ -69,13 +69,15 @@ public class Forge implements ApplicationListener {
|
|||||||
public static String locale = "en-US";
|
public static String locale = "en-US";
|
||||||
public static boolean hdbuttons = false;
|
public static boolean hdbuttons = false;
|
||||||
public static boolean hdstart = 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) {
|
if (GuiBase.getInterface() == null) {
|
||||||
clipboard = clipboard0;
|
clipboard = clipboard0;
|
||||||
deviceAdapter = deviceAdapter0;
|
deviceAdapter = deviceAdapter0;
|
||||||
GuiBase.setInterface(new GuiMobile(assetDir0));
|
GuiBase.setInterface(new GuiMobile(assetDir0));
|
||||||
GuiBase.enablePropertyConfig(value);
|
GuiBase.enablePropertyConfig(value);
|
||||||
|
isPortraitMode = androidOrientation;
|
||||||
}
|
}
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
@@ -373,6 +375,8 @@ public class Forge implements ApplicationListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isLandscapeMode() {
|
public static boolean isLandscapeMode() {
|
||||||
|
if(GuiBase.isAndroid())
|
||||||
|
return !isPortraitMode;
|
||||||
return screenWidth > screenHeight;
|
return screenWidth > screenHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import com.badlogic.gdx.utils.Align;
|
|||||||
|
|
||||||
import forge.Forge;
|
import forge.Forge;
|
||||||
import forge.Graphics;
|
import forge.Graphics;
|
||||||
|
import forge.GuiBase;
|
||||||
import forge.assets.FImage;
|
import forge.assets.FImage;
|
||||||
import forge.assets.FSkinColor;
|
import forge.assets.FSkinColor;
|
||||||
import forge.assets.FSkinColor.Colors;
|
import forge.assets.FSkinColor.Colors;
|
||||||
@@ -80,14 +81,12 @@ public abstract class FScreen extends FContainer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final void doLayout(float width, float height) {
|
protected final void doLayout(float width, float height) {
|
||||||
if (width > height) { //handle landscape layout special
|
if ((GuiBase.isAndroid() && Forge.isLandscapeMode())||(width > height)) {
|
||||||
doLandscapeLayout(width, height);
|
doLandscapeLayout(width, height); //handle landscape layout special
|
||||||
}
|
} else if (header != null) {
|
||||||
else if (header != null) {
|
|
||||||
header.setBounds(0, 0, width, header.getPreferredHeight());
|
header.setBounds(0, 0, width, header.getPreferredHeight());
|
||||||
doLayout(header.getHeight(), width, height);
|
doLayout(header.getHeight(), width, height);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
doLayout(0, width, height);
|
doLayout(0, width, height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import forge.deck.DeckSection;
|
|||||||
import forge.deck.DeckType;
|
import forge.deck.DeckType;
|
||||||
import forge.deck.FDeckChooser;
|
import forge.deck.FDeckChooser;
|
||||||
|
|
||||||
|
import forge.net.server.FServerManager;
|
||||||
import forge.util.Localizer;
|
import forge.util.Localizer;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@@ -530,6 +531,8 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
|
|||||||
|
|
||||||
GuiBase.setNetworkplay(allowNetworking);
|
GuiBase.setNetworkplay(allowNetworking);
|
||||||
|
|
||||||
|
setStartButtonAvailability();
|
||||||
|
|
||||||
for (int i = 0; i < cbPlayerCount.getSelectedItem(); i++) {
|
for (int i = 0; i < cbPlayerCount.getSelectedItem(); i++) {
|
||||||
final boolean hasPanel = i < playerPanels.size();
|
final boolean hasPanel = i < playerPanels.size();
|
||||||
if (i < playerCount) {
|
if (i < playerCount) {
|
||||||
@@ -731,4 +734,11 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
|
|||||||
public FScrollPane getPlayersScroll() {
|
public FScrollPane getPlayersScroll() {
|
||||||
return playersScroll;
|
return playersScroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStartButtonAvailability() {
|
||||||
|
if (lobby.isAllowNetworking() && FServerManager.getInstance() != null)
|
||||||
|
btnStart.setVisible(FServerManager.getInstance().isHosting());
|
||||||
|
else
|
||||||
|
btnStart.setVisible(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,15 +125,12 @@ public class MatchController extends AbstractGuiGame {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refreshField() {
|
public void refreshField() {
|
||||||
if(!GuiBase.isNetworkplay()) //TODO alternate method for update Netplay...
|
if(!GuiBase.isNetworkplay())
|
||||||
return;
|
|
||||||
if(getGameView() == null)
|
|
||||||
return;
|
return;
|
||||||
if(getGameView().getPhase() == null)
|
if(getGameView().getPhase() == null)
|
||||||
return;
|
return;
|
||||||
if (getGameView().getPhase().phaseforUpdateField())
|
if (getGameView().getPhase().phaseforUpdateField())
|
||||||
for (final VPlayerPanel pnl : view.getPlayerPanels().values())
|
refreshCardDetails(null);
|
||||||
pnl.getField().update(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hotSeatMode() {
|
public boolean hotSeatMode() {
|
||||||
|
|||||||
@@ -565,6 +565,7 @@ public class MatchScreen extends FScreen {
|
|||||||
float x = 0;
|
float x = 0;
|
||||||
float y;
|
float y;
|
||||||
float w = getWidth();
|
float w = getWidth();
|
||||||
|
Color color = Color.CYAN;
|
||||||
|
|
||||||
//field separator lines
|
//field separator lines
|
||||||
if (!Forge.isLandscapeMode()) {
|
if (!Forge.isLandscapeMode()) {
|
||||||
@@ -591,17 +592,43 @@ public class MatchScreen extends FScreen {
|
|||||||
|
|
||||||
//Draw Priority Human Multiplayer 2 player
|
//Draw Priority Human Multiplayer 2 player
|
||||||
float oldAlphaComposite = g.getfloatAlphaComposite();
|
float oldAlphaComposite = g.getfloatAlphaComposite();
|
||||||
|
|
||||||
|
|
||||||
if ((getPlayerPanels().keySet().size() == 2) && (countHuman() == 2)){
|
if ((getPlayerPanels().keySet().size() == 2) && (countHuman() == 2)){
|
||||||
for (VPlayerPanel playerPanel: playerPanelsList){
|
for (VPlayerPanel playerPanel: playerPanelsList){
|
||||||
midField = playerPanel.getTop();
|
midField = playerPanel.getTop();
|
||||||
y = midField - 0.5f;
|
y = midField - 0.5f;
|
||||||
float adjustY = Forge.isLandscapeMode() ? y + 1f : midField;
|
float adjustY = Forge.isLandscapeMode() ? y + 1f : midField;
|
||||||
float adjustH = Forge.isLandscapeMode() ? playerPanel.getField().getBottom() - 1f : playerPanel.getBottom() - 1f;
|
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);
|
g.setAlphaComposite(0.8f);
|
||||||
else
|
else
|
||||||
g.setAlphaComposite(0f);
|
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);
|
g.setAlphaComposite(oldAlphaComposite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import com.badlogic.gdx.math.Vector2;
|
|||||||
|
|
||||||
import forge.FThreads;
|
import forge.FThreads;
|
||||||
import forge.Graphics;
|
import forge.Graphics;
|
||||||
|
import forge.GuiBase;
|
||||||
import forge.card.CardZoom;
|
import forge.card.CardZoom;
|
||||||
import forge.card.CardRenderer.CardStackPosition;
|
import forge.card.CardRenderer.CardStackPosition;
|
||||||
import forge.card.CardZoom.ActivateHandler;
|
import forge.card.CardZoom.ActivateHandler;
|
||||||
@@ -184,7 +185,10 @@ public abstract class VCardDisplayArea extends VDisplayArea implements ActivateH
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getActivateAction(int index) {
|
public String getActivateAction(int index) {
|
||||||
|
if(!GuiBase.isNetworkplay()) //causes lag on netplay client side
|
||||||
return MatchController.instance.getGameController().getActivateDescription(orderedCards.get(index));
|
return MatchController.instance.getGameController().getActivateDescription(orderedCards.get(index));
|
||||||
|
|
||||||
|
return "Activate | Cast | Play (if allowed)"; //simple text on card zoom swipe up
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -66,7 +66,12 @@ public class VZoneDisplay extends VCardDisplayArea {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setRevealedPanel(int idx) {
|
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();
|
clearChildren();
|
||||||
if (Forge.isLandscapeMode()) {
|
if (Forge.isLandscapeMode()) {
|
||||||
//for landscape mode, just show revealed card on top
|
//for landscape mode, just show revealed card on top
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package forge.screens.online;
|
package forge.screens.online;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import forge.FThreads;
|
import forge.FThreads;
|
||||||
import forge.Forge;
|
import forge.Forge;
|
||||||
|
import forge.GuiBase;
|
||||||
import forge.assets.FSkinProp;
|
import forge.assets.FSkinProp;
|
||||||
import forge.interfaces.ILobbyView;
|
import forge.interfaces.ILobbyView;
|
||||||
import forge.match.GameLobby;
|
import forge.match.GameLobby;
|
||||||
@@ -11,6 +13,7 @@ import forge.net.IOnlineLobby;
|
|||||||
import forge.net.NetConnectUtil;
|
import forge.net.NetConnectUtil;
|
||||||
import forge.net.OfflineLobby;
|
import forge.net.OfflineLobby;
|
||||||
import forge.net.client.FGameClient;
|
import forge.net.client.FGameClient;
|
||||||
|
import forge.net.server.FServerManager;
|
||||||
import forge.properties.ForgeConstants;
|
import forge.properties.ForgeConstants;
|
||||||
import forge.screens.LoadingOverlay;
|
import forge.screens.LoadingOverlay;
|
||||||
import forge.screens.constructed.LobbyScreen;
|
import forge.screens.constructed.LobbyScreen;
|
||||||
@@ -47,6 +50,7 @@ public class OnlineLobbyScreen extends LobbyScreen implements IOnlineLobby {
|
|||||||
fGameClient = null;
|
fGameClient = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void closeConn(String msg) {
|
public void closeConn(String msg) {
|
||||||
clearGameLobby();
|
clearGameLobby();
|
||||||
Forge.back();
|
Forge.back();
|
||||||
@@ -54,7 +58,15 @@ public class OnlineLobbyScreen extends LobbyScreen implements IOnlineLobby {
|
|||||||
FThreads.invokeInBackgroundThread(new Runnable() {
|
FThreads.invokeInBackgroundThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
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
|
@Override
|
||||||
public void onActivate() {
|
public void onActivate() {
|
||||||
|
if (GuiBase.isInterrupted()) {
|
||||||
|
GuiBase.setInterrupted(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (getGameLobby() == null) {
|
if (getGameLobby() == null) {
|
||||||
setGameLobby(getLobby());
|
setGameLobby(getLobby());
|
||||||
//prompt to connect to server when offline lobby activated
|
//prompt to connect to server when offline lobby activated
|
||||||
|
|||||||
@@ -77,6 +77,11 @@
|
|||||||
<artifactId>slf4j-simple</artifactId>
|
<artifactId>slf4j-simple</artifactId>
|
||||||
<version>1.7.22</version>
|
<version>1.7.22</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.lz4</groupId>
|
||||||
|
<artifactId>lz4-java</artifactId>
|
||||||
|
<version>1.7.1</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -7,23 +7,20 @@ public class GuiBase {
|
|||||||
private static boolean propertyConfig = true;
|
private static boolean propertyConfig = true;
|
||||||
private static boolean networkplay = false;
|
private static boolean networkplay = false;
|
||||||
private static boolean isAndroidport = 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 void setIsAndroid(boolean value) { isAndroidport = value; }
|
||||||
public static boolean isAndroid() { return isAndroidport; }
|
public static boolean isAndroid() { return isAndroidport; }
|
||||||
public static boolean isNetworkplay() {
|
|
||||||
return networkplay;
|
public static boolean isNetworkplay() { return networkplay; }
|
||||||
}
|
public static void setNetworkplay(boolean value) { networkplay = value; }
|
||||||
public static void setNetworkplay(boolean value) {
|
|
||||||
networkplay = value;
|
public static boolean hasPropertyConfig() { return propertyConfig; }
|
||||||
}
|
public static void enablePropertyConfig(boolean value) { propertyConfig = value; }
|
||||||
public static boolean hasPropertyConfig() {
|
|
||||||
return propertyConfig;
|
public static void setInterrupted(boolean value) { interrupted = value; }
|
||||||
}
|
public static boolean isInterrupted() { return interrupted; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,15 +17,9 @@ public class CObjectInputStream extends ObjectInputStream {
|
|||||||
this.classResolver = classResolver;
|
this.classResolver = classResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void readStreamHeader() throws IOException {
|
@Override
|
||||||
int version = this.readByte() & 255;
|
|
||||||
if (version != 5) {
|
|
||||||
throw new StreamCorruptedException("Unsupported version: " + version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
|
protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
|
||||||
int type = this.read();
|
int type = read();
|
||||||
if (type < 0) {
|
if (type < 0) {
|
||||||
throw new EOFException();
|
throw new EOFException();
|
||||||
} else {
|
} else {
|
||||||
@@ -33,8 +27,8 @@ public class CObjectInputStream extends ObjectInputStream {
|
|||||||
case 0:
|
case 0:
|
||||||
return super.readClassDescriptor();
|
return super.readClassDescriptor();
|
||||||
case 1:
|
case 1:
|
||||||
String className = this.readUTF();
|
String className = readUTF();
|
||||||
Class<?> clazz = this.classResolver.resolve(className);
|
Class<?> clazz = classResolver.resolve(className);
|
||||||
return ObjectStreamClass.lookupAny(clazz);
|
return ObjectStreamClass.lookupAny(clazz);
|
||||||
default:
|
default:
|
||||||
throw new StreamCorruptedException("Unexpected class descriptor type: " + type);
|
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 {
|
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
|
||||||
Class clazz;
|
Class<?> clazz;
|
||||||
try {
|
try {
|
||||||
clazz = this.classResolver.resolve(desc.getName());
|
clazz = classResolver.resolve(desc.getName());
|
||||||
} catch (ClassNotFoundException var4) {
|
} catch (ClassNotFoundException ignored) {
|
||||||
clazz = super.resolveClass(desc);
|
clazz = super.resolveClass(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return clazz;
|
return clazz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,26 +6,16 @@ import java.io.ObjectStreamClass;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
public class CObjectOutputStream extends ObjectOutputStream {
|
public class CObjectOutputStream extends ObjectOutputStream {
|
||||||
static final int TYPE_FAT_DESCRIPTOR = 0;
|
|
||||||
static final int TYPE_THIN_DESCRIPTOR = 1;
|
static final int TYPE_THIN_DESCRIPTOR = 1;
|
||||||
|
|
||||||
CObjectOutputStream(OutputStream out) throws IOException {
|
CObjectOutputStream(OutputStream out) throws IOException {
|
||||||
super(out);
|
super(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void writeStreamHeader() throws IOException {
|
@Override
|
||||||
this.writeByte(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException {
|
protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException {
|
||||||
Class<?> clazz = desc.forClass();
|
//we only pass this and the decoder will lookup in the stream (faster method both mobile and desktop)
|
||||||
if (!clazz.isPrimitive() && !clazz.isArray() && !clazz.isInterface() && desc.getSerialVersionUID() != 0L) {
|
write(TYPE_THIN_DESCRIPTOR);
|
||||||
this.write(1);
|
writeUTF(desc.getName());
|
||||||
this.writeUTF(desc.getName());
|
|
||||||
} else {
|
|
||||||
this.write(0);
|
|
||||||
super.writeClassDescriptor(desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import io.netty.buffer.ByteBufInputStream;
|
|||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
|
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
|
||||||
import io.netty.handler.codec.serialization.ClassResolver;
|
import io.netty.handler.codec.serialization.ClassResolver;
|
||||||
|
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||||
|
|
||||||
import java.io.ObjectInputStream;
|
import java.io.ObjectInputStream;
|
||||||
import java.io.StreamCorruptedException;
|
import java.io.StreamCorruptedException;
|
||||||
@@ -22,20 +23,21 @@ public class CompatibleObjectDecoder extends LengthFieldBasedFrameDecoder {
|
|||||||
this.classResolver = classResolver;
|
this.classResolver = classResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
|
protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
|
||||||
ByteBuf frame = (ByteBuf)super.decode(ctx, in);
|
ByteBuf frame = (ByteBuf)super.decode(ctx, in);
|
||||||
if (frame == null) {
|
if (frame == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
ObjectInputStream ois = GuiBase.hasPropertyConfig() ?
|
ObjectInputStream ois = GuiBase.hasPropertyConfig() ?
|
||||||
new ObjectInputStream(new ByteBufInputStream(frame, true)):
|
new ObjectInputStream(new LZ4BlockInputStream(new ByteBufInputStream(frame, true))):
|
||||||
new CObjectInputStream(new ByteBufInputStream(frame, true),this.classResolver);
|
new CObjectInputStream(new LZ4BlockInputStream(new ByteBufInputStream(frame, true)),this.classResolver);
|
||||||
|
|
||||||
Object var5 = null;
|
Object var5 = null;
|
||||||
try {
|
try {
|
||||||
var5 = ois.readObject();
|
var5 = ois.readObject();
|
||||||
} catch (StreamCorruptedException e) {
|
} catch (StreamCorruptedException e) {
|
||||||
e.printStackTrace();
|
System.err.println(String.format("Version Mismatch: %s", e.getMessage()));
|
||||||
} finally {
|
} finally {
|
||||||
ois.close();
|
ois.close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import io.netty.buffer.ByteBuf;
|
|||||||
import io.netty.buffer.ByteBufOutputStream;
|
import io.netty.buffer.ByteBufOutputStream;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.MessageToByteEncoder;
|
import io.netty.handler.codec.MessageToByteEncoder;
|
||||||
|
import net.jpountz.lz4.LZ4BlockOutputStream;
|
||||||
|
|
||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
@@ -20,7 +21,7 @@ public class CompatibleObjectEncoder extends MessageToByteEncoder<Serializable>
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
bout.write(LENGTH_PLACEHOLDER);
|
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.writeObject(msg);
|
||||||
oout.flush();
|
oout.flush();
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -7,4 +7,5 @@ import forge.net.client.FGameClient;
|
|||||||
public interface IOnlineLobby {
|
public interface IOnlineLobby {
|
||||||
ILobbyView setLobby(GameLobby lobby);
|
ILobbyView setLobby(GameLobby lobby);
|
||||||
void setClient(FGameClient client);
|
void setClient(FGameClient client);
|
||||||
|
void closeConn(String msg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import forge.properties.ForgeConstants;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import forge.GuiBase;
|
import forge.GuiBase;
|
||||||
import forge.assets.FSkinProp;
|
|
||||||
import forge.interfaces.IGuiGame;
|
import forge.interfaces.IGuiGame;
|
||||||
import forge.interfaces.ILobbyListener;
|
import forge.interfaces.ILobbyListener;
|
||||||
import forge.interfaces.ILobbyView;
|
import forge.interfaces.ILobbyView;
|
||||||
@@ -146,8 +145,8 @@ public class NetConnectUtil {
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public final void close() {
|
public final void close() {
|
||||||
SOptionPane.showMessageDialog("Your connection to the host (" + url + ") was interrupted.", "Error", FSkinProp.ICO_WARNING);
|
GuiBase.setInterrupted(true);
|
||||||
onlineLobby.setClient(null);
|
onlineLobby.closeConn("Your connection to the host (" + url + ") was interrupted.");
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public ClientGameLobby getLobby() {
|
public ClientGameLobby getLobby() {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package forge.net;
|
package forge.net;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
import forge.GuiBase;
|
||||||
import forge.assets.FSkinProp;
|
import forge.assets.FSkinProp;
|
||||||
import forge.deck.CardPool;
|
import forge.deck.CardPool;
|
||||||
import forge.game.GameEntityView;
|
import forge.game.GameEntityView;
|
||||||
@@ -155,28 +156,16 @@ public enum ProtocolMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void checkArgs(final Object[] args) {
|
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++) {
|
for (int iArg = 0; iArg < args.length; iArg++) {
|
||||||
final Object arg = args[iArg];
|
final Object arg = args[iArg];
|
||||||
final Class<?> type = this.args[iArg];
|
final Class<?> type = this.args[iArg];
|
||||||
if (!ReflectionUtil.isInstance(arg, type)) {
|
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()));
|
//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)) {
|
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()));
|
//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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,12 +40,12 @@ public class NetGameController implements IGameController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void selectPlayer(final PlayerView playerView, final ITriggerEvent triggerEvent) {
|
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
|
@Override
|
||||||
public boolean selectCard(final CardView cardView, final List<CardView> otherCardViewsToSelect, final ITriggerEvent triggerEvent) {
|
public boolean selectCard(final CardView cardView, final List<CardView> 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,
|
// Difference from local games! Always consider a card as successfully selected,
|
||||||
// to avoid blocks where server and client wait for each other to respond.
|
// to avoid blocks where server and client wait for each other to respond.
|
||||||
// Some cost in functionality but a huge gain in stability & speed.
|
// Some cost in functionality but a huge gain in stability & speed.
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class NetGuiGame extends AbstractGuiGame {
|
|||||||
return sender.sendAndWait(method, args);
|
return sender.sendAndWait(method, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateGameView() {
|
public void updateGameView() {
|
||||||
send(ProtocolMethod.setGameView, getGameView());
|
send(ProtocolMethod.setGameView, getGameView());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ public class NetGuiGame extends AbstractGuiGame {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpellAbilityView getAbilityToPlay(final CardView hostCard, final List<SpellAbilityView> abilities, final ITriggerEvent triggerEvent) {
|
public SpellAbilityView getAbilityToPlay(final CardView hostCard, final List<SpellAbilityView> 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
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user