Some more network stuff. We almost have a working lobby!

This commit is contained in:
elcnesh
2015-02-27 13:02:20 +00:00
parent 7ff89bd6b2
commit ca82a3b0d9
25 changed files with 462 additions and 106 deletions

View File

@@ -0,0 +1,10 @@
package forge.interfaces;
import forge.net.game.LobbyState;
import forge.net.game.server.RemoteClient;
public interface ILobby {
LobbyState getState();
int login(RemoteClient client);
void logout(RemoteClient client);
}

View File

@@ -0,0 +1,7 @@
package forge.interfaces;
import forge.net.game.LobbyState.LobbyPlayerData;
public interface IPlayerChangeListener {
void update(LobbyPlayerData data);
}

View File

@@ -14,15 +14,23 @@ import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import forge.GuiBase;
import java.util.List;
import com.google.common.collect.Lists;
import forge.game.GameView;
import forge.game.player.PlayerView;
import forge.interfaces.IGuiGame;
import forge.model.FModel;
import forge.net.game.GuiGameEvent;
import forge.net.game.LobbyUpdateEvent;
import forge.net.game.LoginEvent;
import forge.net.game.MessageEvent;
import forge.net.game.NetEvent;
import forge.net.game.client.ILobbyListener;
import forge.net.game.client.IToServer;
import forge.properties.ForgePreferences.FPref;
public class FGameClient implements IToServer {
private final IGuiGame clientGui;
@@ -30,6 +38,8 @@ public class FGameClient implements IToServer {
this.clientGui = clientGui;
}
private final List<ILobbyListener> lobbyListeners = Lists.newArrayList();
static final int SIZE = Integer.parseInt(System.getProperty("size", "256"));
private Channel channel;
@@ -47,6 +57,7 @@ public class FGameClient implements IToServer {
new ObjectEncoder(),
new ObjectDecoder(ClassResolvers.cacheDisabled(null)),
new MessageHandler(),
new LobbyUpdateHandler(),
new GameClientHandler());
}
});
@@ -74,6 +85,10 @@ public class FGameClient implements IToServer {
channel.writeAndFlush(event);
}
public void addLobbyListener(final ILobbyListener listener) {
lobbyListeners.add(listener);
}
private class GameClientHandler extends ChannelInboundHandlerAdapter {
/**
* Creates a client-side handler.
@@ -83,7 +98,8 @@ public class FGameClient implements IToServer {
@Override
public void channelActive(final ChannelHandlerContext ctx) {
send(new LoginEvent("elcnesh"));
// Don't use send here, as this.channel is not yet set!
ctx.channel().writeAndFlush(new LoginEvent(FModel.getPreferences().getPref(FPref.PLAYER_NAME)));
}
@SuppressWarnings("unchecked")
@@ -116,7 +132,21 @@ public class FGameClient implements IToServer {
public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
if (msg instanceof MessageEvent) {
final MessageEvent event = (MessageEvent) msg;
GuiBase.getInterface().netMessage(event.getSource(), event.getMessage());
for (final ILobbyListener listener : lobbyListeners) {
listener.message(event.getSource(), event.getMessage());
}
}
super.channelRead(ctx, msg);
}
}
private class LobbyUpdateHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
if (msg instanceof LobbyUpdateEvent) {
for (final ILobbyListener listener : lobbyListeners) {
listener.update(((LobbyUpdateEvent) msg).getState());
}
}
super.channelRead(ctx, msg);
}

View File

@@ -1,12 +1,14 @@
package forge.net;
import forge.game.GameRules;
import forge.interfaces.ILobby;
import forge.net.game.LobbyState;
import forge.net.game.LobbyUpdateEvent;
import forge.net.game.LoginEvent;
import forge.net.game.LogoutEvent;
import forge.net.game.MessageEvent;
import forge.net.game.NetEvent;
import forge.net.game.RegisterDeckEvent;
import forge.net.game.client.ILobbyListener;
import forge.net.game.server.RemoteClient;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
@@ -25,10 +27,8 @@ import io.netty.handler.codec.serialization.ObjectEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import java.util.List;
import java.util.Map;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
public final class FServerManager {
@@ -39,7 +39,7 @@ public final class FServerManager {
private final Map<Integer, NetGame> games = Maps.newTreeMap();
private int id = 0;
private final Map<Channel, RemoteClient> clients = Maps.newTreeMap();
private final List<ILobbyListener> lobbyListeners = Lists.newArrayListWithExpectedSize(1);
private ILobby localLobby;
private FServerManager() {
}
@@ -102,12 +102,13 @@ public final class FServerManager {
public void broadcast(final NetEvent event) {
for (final RemoteClient client : clients.values()) {
event.updateForClient(client);
client.send(event);
}
}
public void registerLobbyListener(final ILobbyListener lobbyListener) {
lobbyListeners.add(lobbyListener);
public void setLobby(final ILobby lobby) {
this.localLobby = lobby;
}
public NetGame hostGame(final GameRules rules) {
@@ -117,6 +118,12 @@ public final class FServerManager {
return game;
}
public void updateLobbyState() {
final LobbyState state = localLobby.getState();
final LobbyUpdateEvent event = new LobbyUpdateEvent(state);
broadcast(event);
}
@Override
protected void finalize() throws Throwable {
super.finalize();
@@ -153,6 +160,7 @@ public final class FServerManager {
clients.put(ctx.channel(), client);
games.get(0).addClient(client);
System.out.println("User connected to server at " + ctx.channel().remoteAddress());
updateLobbyState();
super.channelActive(ctx);
}
@@ -161,6 +169,7 @@ public final class FServerManager {
final RemoteClient client = clients.get(ctx.channel());
if (msg instanceof LoginEvent) {
client.setUsername(((LoginEvent) msg).getUsername());
updateLobbyState();
} else if (msg instanceof RegisterDeckEvent) {
games.get(0).registerDeck(client, ((RegisterDeckEvent) msg).getDeck());
}
@@ -173,15 +182,15 @@ public final class FServerManager {
final RemoteClient client = clients.get(ctx.channel());
if (msg instanceof LoginEvent) {
final LoginEvent event = (LoginEvent) msg;
for (final ILobbyListener lobbyListener : lobbyListeners) {
lobbyListener.login(client);
final int index = localLobby.login(client);
if (index == -1) {
ctx.close();
} else {
client.setIndex(index);
broadcast(event);
}
broadcast(event);
} else if (msg instanceof MessageEvent) {
final MessageEvent event = (MessageEvent) msg;
for (final ILobbyListener lobbyListener : lobbyListeners) {
lobbyListener.message(client.getUsername(), event.getMessage());
}
broadcast(event);
}
super.channelRead(ctx, msg);
@@ -189,9 +198,8 @@ public final class FServerManager {
@Override public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
final RemoteClient client = clients.get(ctx.channel());
for (final ILobbyListener lobbyListener : lobbyListeners) {
lobbyListener.logout(client);
}
localLobby.logout(client);
updateLobbyState();
super.channelInactive(ctx);
}
}
@@ -205,4 +213,5 @@ public final class FServerManager {
super.channelInactive(ctx);
}
}
}