From efe6034837549ff43fdb4d08448afad92078d31f Mon Sep 17 00:00:00 2001 From: elcnesh Date: Wed, 29 Apr 2015 18:50:12 +0000 Subject: [PATCH] - Move some files around in net code (plus some cleanup) - Remove an unused method from IGuiGame --- .gitattributes | 1 + .../java/forge/screens/match/CMatchUI.java | 8 - .../forge/screens/match/MatchController.java | 5 - .../main/java/forge/interfaces/IGuiGame.java | 2 - .../java/forge/net/GameProtocolHandler.java | 1 - .../java/forge/net/GameProtocolSender.java | 1 - .../main/java/forge/net/ProtocolMethod.java | 167 ++++++++++++++++++ .../forge/net/client/GameClientHandler.java | 2 +- .../forge/net/client/NetGameController.java | 5 +- .../java/forge/net/event/GuiGameEvent.java | 2 +- .../java/forge/net/event/LogoutEvent.java | 1 + .../java/forge/net/event/MessageEvent.java | 3 + .../net/event/UpdateLobbyPlayerEvent.java | 1 + .../java/forge/net/server/FServerManager.java | 18 +- .../forge/net/server/GameServerHandler.java | 2 +- .../java/forge/net/server/NetGuiGame.java | 7 +- 16 files changed, 187 insertions(+), 39 deletions(-) create mode 100644 forge-gui/src/main/java/forge/net/ProtocolMethod.java diff --git a/.gitattributes b/.gitattributes index 038e65b9bb1..78ab21d8770 100644 --- a/.gitattributes +++ b/.gitattributes @@ -17720,6 +17720,7 @@ forge-gui/src/main/java/forge/net/GameProtocol.java -text forge-gui/src/main/java/forge/net/GameProtocolHandler.java -text forge-gui/src/main/java/forge/net/GameProtocolSender.java -text forge-gui/src/main/java/forge/net/IRemote.java -text +forge-gui/src/main/java/forge/net/ProtocolMethod.java -text forge-gui/src/main/java/forge/net/ReplyPool.java -text forge-gui/src/main/java/forge/net/client/ClientGameLobby.java -text forge-gui/src/main/java/forge/net/client/FGameClient.java -text 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 0f96d37d334..24a962757f6 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 @@ -833,14 +833,6 @@ public final class CMatchUI return FOptionPane.showOptionDialog(message, title, icon == null ? null : FSkin.getImage(icon), options, defaultOption); } - @Override - public int showCardOptionDialog(final CardView card, final String message, final String title, final FSkinProp skinIcon, final String[] options, final int defaultOption) { - if (card != null) { - setCard(card); - } - return showOptionDialog(message, title, skinIcon, options, defaultOption); - } - @Override public String showInputDialog(final String message, final String title, final FSkinProp icon, final String initialInput, final String[] inputOptions) { return FOptionPane.showInputDialog(message, title, icon == null ? null : FSkin.getImage(icon), initialInput, inputOptions); diff --git a/forge-gui-mobile/src/forge/screens/match/MatchController.java b/forge-gui-mobile/src/forge/screens/match/MatchController.java index e02d4a97b21..a60ca7115c1 100644 --- a/forge-gui-mobile/src/forge/screens/match/MatchController.java +++ b/forge-gui-mobile/src/forge/screens/match/MatchController.java @@ -417,11 +417,6 @@ public class MatchController extends AbstractGuiGame { return SOptionPane.showOptionDialog(message, title, icon, options, defaultOption); } - @Override - public int showCardOptionDialog(final CardView card, final String message, final String title, final FSkinProp icon, final String[] options, final int defaultOption) { - return FOptionPane.showCardOptionDialog(card, message, title, icon, options, defaultOption); - } - @Override public String showInputDialog(final String message, final String title, final FSkinProp icon, final String initialInput, final String[] inputOptions) { return SOptionPane.showInputDialog(message, title, icon, initialInput, inputOptions); diff --git a/forge-gui/src/main/java/forge/interfaces/IGuiGame.java b/forge-gui/src/main/java/forge/interfaces/IGuiGame.java index 1e4af7f7cfe..98f0794c486 100644 --- a/forge-gui/src/main/java/forge/interfaces/IGuiGame.java +++ b/forge-gui/src/main/java/forge/interfaces/IGuiGame.java @@ -65,8 +65,6 @@ public interface IGuiGame { int showOptionDialog(String message, String title, FSkinProp icon, String[] options, int defaultOption); - int showCardOptionDialog(CardView card, String message, String title, - FSkinProp icon, String[] options, int defaultOption); String showInputDialog(String message, String title); String showInputDialog(String message, String title, FSkinProp icon); diff --git a/forge-gui/src/main/java/forge/net/GameProtocolHandler.java b/forge-gui/src/main/java/forge/net/GameProtocolHandler.java index b10fa09fff6..888d0dffeed 100644 --- a/forge-gui/src/main/java/forge/net/GameProtocolHandler.java +++ b/forge-gui/src/main/java/forge/net/GameProtocolHandler.java @@ -1,7 +1,6 @@ package forge.net; import forge.FThreads; -import forge.net.GameProtocol.ProtocolMethod; import forge.net.event.GuiGameEvent; import forge.net.event.ReplyEvent; import io.netty.channel.ChannelHandlerContext; diff --git a/forge-gui/src/main/java/forge/net/GameProtocolSender.java b/forge-gui/src/main/java/forge/net/GameProtocolSender.java index ba6eb4f56a0..c692ebcb5c8 100644 --- a/forge-gui/src/main/java/forge/net/GameProtocolSender.java +++ b/forge-gui/src/main/java/forge/net/GameProtocolSender.java @@ -2,7 +2,6 @@ package forge.net; import java.util.concurrent.TimeoutException; -import forge.net.GameProtocol.ProtocolMethod; import forge.net.event.GuiGameEvent; public final class GameProtocolSender { diff --git a/forge-gui/src/main/java/forge/net/ProtocolMethod.java b/forge-gui/src/main/java/forge/net/ProtocolMethod.java new file mode 100644 index 00000000000..fed131286de --- /dev/null +++ b/forge-gui/src/main/java/forge/net/ProtocolMethod.java @@ -0,0 +1,167 @@ +package forge.net; + +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import com.google.common.base.Function; + +import forge.assets.FSkinProp; +import forge.deck.CardPool; +import forge.game.GameEntityView; +import forge.game.GameView; +import forge.game.card.CardView; +import forge.game.phase.PhaseType; +import forge.game.player.DelayedReveal; +import forge.game.player.PlayerView; +import forge.game.spellability.SpellAbilityView; +import forge.interfaces.IGameController; +import forge.interfaces.IGuiGame; +import forge.match.NextGameDecision; +import forge.trackable.TrackableCollection; +import forge.util.ITriggerEvent; +import forge.util.ReflectionUtil; + +/** + * The methods that can be sent through this protocol. + */ +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), + showPromptMessage (Mode.SERVER, Void.TYPE, PlayerView.class, String.class), + updateButtons (Mode.SERVER, Void.TYPE, PlayerView.class, String.class, String.class, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE), + flashIncorrectAction(Mode.SERVER), + updatePhase (Mode.SERVER), + updateTurn (Mode.SERVER, Void.TYPE, PlayerView.class), + updatePlayerControl (Mode.SERVER), + enableOverlay (Mode.SERVER), + disableOverlay (Mode.SERVER), + finishGame (Mode.SERVER), + showManaPool (Mode.SERVER, Object.class, PlayerView.class), + hideManaPool (Mode.SERVER, Void.TYPE, PlayerView.class), + updateStack (Mode.SERVER), + updateZones (Mode.SERVER, Void.TYPE, Iterable/*PlayerZoneUpdate*/.class), + updateCards (Mode.SERVER, Void.TYPE, Iterable/*CardView*/.class), + updateManaPool (Mode.SERVER, Void.TYPE, Iterable/*PlayerView*/.class), + updateLives (Mode.SERVER, Void.TYPE, Iterable/*PlayerView*/.class), + setPanelSelection (Mode.SERVER, Void.TYPE, CardView.class), + getAbilityToPlay (Mode.SERVER, SpellAbilityView.class, CardView.class, List/*SpellAbilityView*/.class, ITriggerEvent.class), + assignDamage (Mode.SERVER, Map.class, CardView.class, List/*CardView*/.class, Integer.TYPE, GameEntityView.class, Boolean.TYPE), + message (Mode.SERVER, Void.TYPE, String.class, String.class), + showErrorDialog (Mode.SERVER, Void.TYPE, String.class, String.class), + showConfirmDialog (Mode.SERVER, Boolean.TYPE, String.class, String.class, String.class, String.class, Boolean.TYPE), + showOptionDialog (Mode.SERVER, Integer.TYPE, String.class, String.class, FSkinProp.class, Array/*String*/.class, Integer.TYPE), + showInputDialog (Mode.SERVER, String.class, String.class, String.class, FSkinProp.class, String.class, Array/*String*/.class), + confirm (Mode.SERVER, Boolean.TYPE, CardView.class, String.class, Boolean.TYPE, Array/*String*/.class), + getChoices (Mode.SERVER, List.class, String.class, Integer.TYPE, Integer.TYPE, Collection.class, Object.class, Function.class), + order (Mode.SERVER, List.class, String.class, String.class, Integer.TYPE, Integer.TYPE, List.class, List.class, CardView.class, Boolean.TYPE), + sideboard (Mode.SERVER, List.class, CardPool.class, CardPool.class), + chooseSingleEntityForEffect(Mode.SERVER, GameEntityView.class, String.class, TrackableCollection.class, DelayedReveal.class, Boolean.TYPE), + setCard (Mode.SERVER, Void.TYPE, CardView.class), + // TODO case "setPlayerAvatar": + openZones (Mode.SERVER, Boolean.TYPE, Collection/*ZoneType*/.class, Map/*PlayerView,Object*/.class), + restoreOldZones (Mode.SERVER, Void.TYPE, Map/*PlayerView,Object*/.class), + isUiSetToSkipPhase (Mode.SERVER, Boolean.TYPE, PlayerView.class, PhaseType.class), + + // Client -> Server + // Note: these should all return void, to avoid awkward situations in + // 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), + 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), + selectAbility (Mode.CLIENT, Void.TYPE, SpellAbilityView.class), + passPriorityUntilEndOfTurn(Mode.CLIENT), + passPriority (Mode.CLIENT), + nextGameDecision (Mode.CLIENT, Void.TYPE, NextGameDecision.class), + getActivateDescription (Mode.CLIENT, Void.TYPE, String.class, CardView.class), + concede (Mode.CLIENT), + alphaStrike (Mode.CLIENT), + reorderHand (Mode.CLIENT, Void.TYPE, CardView.class, Integer.TYPE); + + private enum Mode { + SERVER(IGuiGame.class), + CLIENT(IGameController.class); + + private final Class toInvoke; + private Mode(final Class toInvoke) { + this.toInvoke = toInvoke; + } + }; + + private final ProtocolMethod.Mode mode; + private final Class returnType; + private final Class[] args; + + private ProtocolMethod(final ProtocolMethod.Mode mode) { + this(mode, Void.TYPE); + } + private ProtocolMethod(final ProtocolMethod.Mode mode, final Class returnType) { + this(mode, returnType, (Class[]) null); + } + @SafeVarargs + private ProtocolMethod(final ProtocolMethod.Mode mode, final Class returnType, final Class ... args) { + this.mode = mode; + this.returnType = returnType; + this.args = args == null ? new Class[] {} : args; + } + + public Method getMethod() { + try { + final Class toCall = mode.toInvoke; + final Method candidate = toCall.getMethod(name(), args); + // Don't check Client return values for now as some use void + // and a default return value, to improve performance + if (mode == Mode.SERVER && !candidate.getReturnType().equals(returnType)) { + throw new NoSuchMethodException(String.format("Wrong return type for method %s", name())); + } + return candidate; + } catch (final NoSuchMethodException | SecurityException e) { + System.err.println(String.format("Warning: class contains no accessible method named %s", name())); + return getMethodNoArgs(); + } + } + + private Method getMethodNoArgs() { + try { + return mode.toInvoke.getMethod(name(), (Class[]) null); + } catch (final NoSuchMethodException | SecurityException e) { + System.err.println(String.format("Warning: class contains no accessible arg-less method named %s", name())); + return null; + } + } + public Class getReturnType() { + return returnType; + } + public Class[] getArgTypes() { + return args; + } + + public void checkArgs(final Object[] args) { + 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())); + } + } + } + + public void checkReturnValue(final Object value) { + if (returnType.equals(Void.TYPE)) { + // If void is expected, any return value is fine + return; + } + 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())); + } + } +} \ No newline at end of file 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 7f21432091b..d8125bee65a 100644 --- a/forge-gui/src/main/java/forge/net/client/GameClientHandler.java +++ b/forge-gui/src/main/java/forge/net/client/GameClientHandler.java @@ -4,9 +4,9 @@ import io.netty.channel.ChannelHandlerContext; import forge.game.player.PlayerView; import forge.interfaces.IGuiGame; import forge.model.FModel; -import forge.net.GameProtocol.ProtocolMethod; import forge.net.GameProtocolHandler; import forge.net.IRemote; +import forge.net.ProtocolMethod; import forge.net.ReplyPool; import forge.net.event.LoginEvent; import forge.properties.ForgePreferences.FPref; 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 8762b20eef7..fe0235e656c 100644 --- a/forge-gui/src/main/java/forge/net/client/NetGameController.java +++ b/forge-gui/src/main/java/forge/net/client/NetGameController.java @@ -8,8 +8,8 @@ import forge.game.spellability.SpellAbilityView; import forge.interfaces.IDevModeCheats; import forge.interfaces.IGameController; import forge.match.NextGameDecision; -import forge.net.GameProtocol.ProtocolMethod; import forge.net.GameProtocolSender; +import forge.net.ProtocolMethod; import forge.util.ITriggerEvent; public class NetGameController implements IGameController { @@ -87,6 +87,7 @@ public class NetGameController implements IGameController { return false; } + @Override public String getActivateDescription(final CardView card) { return sendAndWait(ProtocolMethod.getActivateDescription, card); } @@ -114,7 +115,7 @@ public class NetGameController implements IGameController { } @Override - public void reorderHand(CardView card, int index) { + public void reorderHand(final CardView card, final int index) { send(ProtocolMethod.reorderHand, card, Integer.valueOf(index)); } } diff --git a/forge-gui/src/main/java/forge/net/event/GuiGameEvent.java b/forge-gui/src/main/java/forge/net/event/GuiGameEvent.java index a74d3454a87..20e9b9dfb2e 100644 --- a/forge-gui/src/main/java/forge/net/event/GuiGameEvent.java +++ b/forge-gui/src/main/java/forge/net/event/GuiGameEvent.java @@ -1,6 +1,6 @@ package forge.net.event; -import forge.net.GameProtocol.ProtocolMethod; +import forge.net.ProtocolMethod; import forge.net.server.RemoteClient; public final class GuiGameEvent implements IdentifiableNetEvent { diff --git a/forge-gui/src/main/java/forge/net/event/LogoutEvent.java b/forge-gui/src/main/java/forge/net/event/LogoutEvent.java index 760655b5c5a..e10fc3a95f7 100644 --- a/forge-gui/src/main/java/forge/net/event/LogoutEvent.java +++ b/forge-gui/src/main/java/forge/net/event/LogoutEvent.java @@ -10,6 +10,7 @@ public class LogoutEvent implements NetEvent { this.username = username; } + @Override public void updateForClient(final RemoteClient client) { } diff --git a/forge-gui/src/main/java/forge/net/event/MessageEvent.java b/forge-gui/src/main/java/forge/net/event/MessageEvent.java index 6f3aa8ef672..7ccfe9f2e25 100644 --- a/forge-gui/src/main/java/forge/net/event/MessageEvent.java +++ b/forge-gui/src/main/java/forge/net/event/MessageEvent.java @@ -13,12 +13,15 @@ public final class MessageEvent implements NetEvent { this.source = source; this.message = message; } + + @Override public void updateForClient(final RemoteClient client) { } public String getSource() { return source; } + public String getMessage() { return message; } diff --git a/forge-gui/src/main/java/forge/net/event/UpdateLobbyPlayerEvent.java b/forge-gui/src/main/java/forge/net/event/UpdateLobbyPlayerEvent.java index 3cd11597b1f..b7e8aaefe03 100644 --- a/forge-gui/src/main/java/forge/net/event/UpdateLobbyPlayerEvent.java +++ b/forge-gui/src/main/java/forge/net/event/UpdateLobbyPlayerEvent.java @@ -47,6 +47,7 @@ public final class UpdateLobbyPlayerEvent implements NetEvent { this.aiOptions = aiOptions; } + @Override public void updateForClient(final RemoteClient client) { } diff --git a/forge-gui/src/main/java/forge/net/server/FServerManager.java b/forge-gui/src/main/java/forge/net/server/FServerManager.java index c059ff71d0e..c07fd4a1c6f 100644 --- a/forge-gui/src/main/java/forge/net/server/FServerManager.java +++ b/forge-gui/src/main/java/forge/net/server/FServerManager.java @@ -1,7 +1,6 @@ package forge.net.server; import forge.GuiBase; -import forge.game.GameView; import forge.interfaces.IGameController; import forge.interfaces.IGuiGame; import forge.interfaces.ILobbyListener; @@ -71,16 +70,13 @@ public final class FServerManager { RemoteClient getClient(final Channel ch) { return clients.get(ch); } - GameView getGameView() { - return localLobby.getGameView(); - } IGameController getController(final int index) { return localLobby.getController(index); } /** * Get the singleton instance of {@link FServerManager}. - * + * * @return the singleton FServerManager. */ public static FServerManager getInstance() { @@ -94,10 +90,10 @@ public final class FServerManager { public void startServer(final int port) { try { final ServerBootstrap b = new ServerBootstrap() - .group(bossGroup, workerGroup) - .channel(NioServerSocketChannel.class) - .handler(new LoggingHandler(LogLevel.INFO)) - .childHandler(new ChannelInitializer() { + .group(bossGroup, workerGroup) + .channel(NioServerSocketChannel.class) + .handler(new LoggingHandler(LogLevel.INFO)) + .childHandler(new ChannelInitializer() { @Override public final void initChannel(final SocketChannel ch) { final ChannelPipeline p = ch.pipeline(); p.addLast( @@ -109,7 +105,7 @@ public final class FServerManager { new DeregisterClientHandler(), new GameServerHandler()); } - }); + }); // Bind and start to accept incoming connections. final ChannelFuture ch = b.bind(port).sync().channel().closeFuture(); @@ -277,7 +273,7 @@ public final class FServerManager { private class DeregisterClientHandler extends ChannelInboundHandlerAdapter { @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { + public void channelInactive(final ChannelHandlerContext ctx) throws Exception { final RemoteClient client = clients.remove(ctx.channel()); localLobby.disconnectPlayer(client.getIndex()); broadcast(new LogoutEvent(client.getUsername())); diff --git a/forge-gui/src/main/java/forge/net/server/GameServerHandler.java b/forge-gui/src/main/java/forge/net/server/GameServerHandler.java index 0eab072777e..fc1fabd1d89 100644 --- a/forge-gui/src/main/java/forge/net/server/GameServerHandler.java +++ b/forge-gui/src/main/java/forge/net/server/GameServerHandler.java @@ -2,9 +2,9 @@ package forge.net.server; import io.netty.channel.ChannelHandlerContext; import forge.interfaces.IGameController; -import forge.net.GameProtocol.ProtocolMethod; import forge.net.GameProtocolHandler; import forge.net.IRemote; +import forge.net.ProtocolMethod; import forge.net.ReplyPool; final class GameServerHandler extends GameProtocolHandler { 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 cea3f6d684c..7d4c9dfac7d 100644 --- a/forge-gui/src/main/java/forge/net/server/NetGuiGame.java +++ b/forge-gui/src/main/java/forge/net/server/NetGuiGame.java @@ -20,8 +20,8 @@ import forge.game.spellability.SpellAbilityView; import forge.game.zone.ZoneType; import forge.item.PaperCard; import forge.match.AbstractGuiGame; -import forge.net.GameProtocol.ProtocolMethod; import forge.net.GameProtocolSender; +import forge.net.ProtocolMethod; import forge.player.PlayerZoneUpdate; import forge.trackable.TrackableCollection; import forge.util.ITriggerEvent; @@ -193,11 +193,6 @@ public class NetGuiGame extends AbstractGuiGame { return sendAndWait(ProtocolMethod.showOptionDialog, message, title, icon, options, defaultOption); } - @Override - public int showCardOptionDialog(final CardView card, final String message, final String title, final FSkinProp icon, final String[] options, final int defaultOption) { - return sendAndWait(ProtocolMethod.showCardOptionDialog, card, message, title, icon, options, defaultOption); - } - @Override public String showInputDialog(final String message, final String title, final FSkinProp icon, final String initialInput, final String[] inputOptions) { return sendAndWait(ProtocolMethod.showInputDialog, message, title, icon, initialInput, inputOptions);