diff --git a/pom.xml b/pom.xml index 63d497e7..2e0a4fb3 100644 --- a/pom.xml +++ b/pom.xml @@ -96,8 +96,8 @@ io.netty - netty - 3.10.6.Final + netty-all + 4.1.112.Final compile diff --git a/server/pom.xml b/server/pom.xml index c8678bbd..dd0fa844 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -19,7 +19,7 @@ io.netty - netty + netty-all compile diff --git a/server/src/main/java/org/moparforia/server/Server.java b/server/src/main/java/org/moparforia/server/Server.java index 1fe8a4f7..1b51c406 100644 --- a/server/src/main/java/org/moparforia/server/Server.java +++ b/server/src/main/java/org/moparforia/server/Server.java @@ -1,14 +1,20 @@ package org.moparforia.server; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.*; -import org.jboss.netty.channel.group.ChannelGroup; -import org.jboss.netty.channel.group.DefaultChannelGroup; -import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; -import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder; -import org.jboss.netty.handler.codec.frame.Delimiters; -import org.jboss.netty.handler.timeout.IdleStateHandler; -import org.jboss.netty.util.HashedWheelTimer; +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.group.ChannelGroup; +import io.netty.channel.group.DefaultChannelGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.codec.DelimiterBasedFrameDecoder; +import io.netty.handler.codec.Delimiters; +import io.netty.handler.timeout.IdleStateHandler; +import io.netty.util.concurrent.GlobalEventExecutor; import org.moparforia.server.event.Event; import org.moparforia.server.game.Lobby; import org.moparforia.server.game.LobbyType; @@ -32,8 +38,6 @@ import java.util.Iterator; import java.util.Optional; import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; public class Server implements Runnable { @@ -42,7 +46,7 @@ public class Server implements Runnable { public static final String DEFAULT_TRACKS_DIRECTORY = "tracks"; private HashMap players = new HashMap<>(); - private ChannelGroup allChannels = new DefaultChannelGroup(); + private ChannelGroup allChannels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); private ConcurrentLinkedQueue events = new ConcurrentLinkedQueue<>(); private HashMap> packetHandlers = new HashMap<>(); @@ -50,7 +54,7 @@ public class Server implements Runnable { private int port; private Optional tracksDirectory; - private Channel serverChannel; + private ChannelFuture serverChannelFuture; private boolean running; private HashMap lobbies = new HashMap(); @@ -175,23 +179,29 @@ public void start() { packetHandlers = PacketHandlerFactory.getPacketHandlers(); System.out.println("Loaded " + packetHandlers.size() + " packet handler type(s)"); - ChannelFactory factory = new NioServerSocketChannelFactory( - Executors.newCachedThreadPool(), - Executors.newCachedThreadPool()); - - ServerBootstrap bootstrap = new ServerBootstrap(factory); - final ClientChannelHandler clientHandler = new ClientChannelHandler(this); - final IdleStateHandler idleState = new IdleStateHandler(new HashedWheelTimer(1, TimeUnit.SECONDS), 2, 0, 0); - bootstrap.setPipelineFactory(() -> Channels.pipeline( - new DelimiterBasedFrameDecoder(250, Delimiters.lineDelimiter()), - new PacketDecoder(), - new PacketEncoder(), - idleState, - clientHandler)); - bootstrap.setOption("child.tcpNoDelay", true); - bootstrap.setOption("child.keepAlive", true); + EventLoopGroup bossGroup = new NioEventLoopGroup(); + EventLoopGroup workerGroup = new NioEventLoopGroup(); + ServerBootstrap bootstrap = new ServerBootstrap() + .group(bossGroup, workerGroup) + .channel(NioServerSocketChannel.class) + .childHandler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel ch) { + ch.attr(ClientState.CLIENT_STATE_ATTRIBUTE_KEY).set(new ClientState()); + ch.pipeline() + .addLast( + new DelimiterBasedFrameDecoder(250, Delimiters.lineDelimiter()), + new PacketDecoder(), + new PacketEncoder(), + new IdleStateHandler(2, 0, 0), + new ClientChannelHandler(Server.this) + ); + } + }) + .childOption(ChannelOption.TCP_NODELAY, true) + .childOption(ChannelOption.SO_KEEPALIVE, true); try { - this.serverChannel = bootstrap.bind(new InetSocketAddress(host, port)); + this.serverChannelFuture = bootstrap.bind(new InetSocketAddress(host, port)).sync(); this.running = true; new Thread(this).start(); } catch (Exception ex) { @@ -200,7 +210,7 @@ public void start() { } public void stop() throws InterruptedException { - this.serverChannel.close().sync(); + this.serverChannelFuture.channel().close().sync(); this.running = false; } diff --git a/server/src/main/java/org/moparforia/server/event/ClientConnectedEvent.java b/server/src/main/java/org/moparforia/server/event/ClientConnectedEvent.java index b61cbdfc..9bd63476 100644 --- a/server/src/main/java/org/moparforia/server/event/ClientConnectedEvent.java +++ b/server/src/main/java/org/moparforia/server/event/ClientConnectedEvent.java @@ -1,6 +1,6 @@ package org.moparforia.server.event; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.moparforia.server.Server; import java.util.Random; @@ -17,8 +17,7 @@ public ClientConnectedEvent(Channel channel) { public void process(Server server) { System.out.println("Client connected: " + channel); server.addChannel(channel); - //channel.write("h 1\nc io " + new Random().nextInt(1000000000) + "\nc crt 25\nc ctr\n"); - channel.write("h 1\nc io " + new Random().nextInt(1000000000) + "\nc crt 250\nc ctr\n"); + channel.writeAndFlush("h 1\nc io " + new Random().nextInt(1000000000) + "\nc crt 250\nc ctr\n"); } } diff --git a/server/src/main/java/org/moparforia/server/event/ClientDisconnectedEvent.java b/server/src/main/java/org/moparforia/server/event/ClientDisconnectedEvent.java index 6c24f985..69307ae5 100644 --- a/server/src/main/java/org/moparforia/server/event/ClientDisconnectedEvent.java +++ b/server/src/main/java/org/moparforia/server/event/ClientDisconnectedEvent.java @@ -1,6 +1,6 @@ package org.moparforia.server.event; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.moparforia.server.Server; import org.moparforia.server.game.Lobby; import org.moparforia.server.game.Player; @@ -15,8 +15,8 @@ public ClientDisconnectedEvent(Channel channel) { @Override public void process(Server server) { - Player player; - if ((player = (Player)channel.getAttachment()) != null) { + Player player = channel.attr(Player.PLAYER_ATTRIBUTE_KEY).get(); + if (player != null) { if (player.getLobby() != null) { player.getLobby().removePlayer(player, Lobby.PART_REASON_USERLEFT); } diff --git a/server/src/main/java/org/moparforia/server/game/Game.java b/server/src/main/java/org/moparforia/server/game/Game.java index 796a90b3..2715a9ae 100644 --- a/server/src/main/java/org/moparforia/server/game/Game.java +++ b/server/src/main/java/org/moparforia/server/game/Game.java @@ -1,6 +1,6 @@ package org.moparforia.server.game; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.moparforia.server.Server; import org.moparforia.server.game.gametypes.golf.MultiGame; import org.moparforia.server.net.Packet; @@ -102,7 +102,7 @@ protected void sendJoinMessages(Player player) { sendGameInfo(player); sendPlayerNames(player); writeExcluding(player, new Packet(PacketType.DATA, Tools.tabularize("game", "join", playerCount(), player.getNick(), player.getClan()))); - player.getChannel().write(new Packet(PacketType.DATA, Tools.tabularize("game", "owninfo", numberIndex, player.getNick(), player.getClan()))); + player.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("game", "owninfo", numberIndex, player.getNick(), player.getClan()))); } protected void sendPlayerNames(Player player) { @@ -112,7 +112,7 @@ protected void sendPlayerNames(Player player) { if (!p.equals(player)) playersData += Tools.tabularize("", getPlayerId(p), p.getNick(), p.getClan()); } - c.write(new Packet(PacketType.DATA, playersData)); + c.writeAndFlush(new Packet(PacketType.DATA, playersData)); } diff --git a/server/src/main/java/org/moparforia/server/game/Lobby.java b/server/src/main/java/org/moparforia/server/game/Lobby.java index deefac12..de3719e3 100644 --- a/server/src/main/java/org/moparforia/server/game/Lobby.java +++ b/server/src/main/java/org/moparforia/server/game/Lobby.java @@ -45,7 +45,7 @@ public boolean removePlayer(Player player, int partReason, String... gameName) { writeAll(new Packet(PacketType.DATA, cmd)); if (player.getChannel().isWritable() && partReason == PART_REASON_USERLEFT) { - player.getChannel().write(new Packet(PacketType.DATA, "status\tlobbyselect\t300")); + player.getChannel().writeAndFlush(new Packet(PacketType.DATA, "status\tlobbyselect\t300")); } return true; } @@ -54,23 +54,23 @@ public boolean addPlayer(Player player, int joinType) { if (player.getLobby() != null) { player.getLobby().removePlayer(player, PART_REASON_USERLEFT); } - player.getChannel().write(new Packet(PacketType.DATA, Tools.tabularize("status", "lobby", type + (player.isChatHidden() ? "h" : "")))); + player.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("status", "lobby", type + (player.isChatHidden() ? "h" : "")))); String[] otherPlayers = new String[playerCount()]; int pointer = 0; for (Player p : getPlayers()) { - p.getChannel().write(new Packet(PacketType.DATA, Tools.tabularize( + p.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize( "lobby", joinType == JOIN_TYPE_NORMAL ? "join" : "joinfromgame", player.toString()//todo not sure if should be getNick or getGameString ))); otherPlayers[pointer++] = p.toString(); } if (pointer != 0) { - player.getChannel().write(new Packet(PacketType.DATA, Tools.tabularize("lobby", "users", otherPlayers))); + player.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("lobby", "users", otherPlayers))); } else { - player.getChannel().write(new Packet(PacketType.DATA, Tools.tabularize("lobby", "users"))); + player.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("lobby", "users"))); } - player.getChannel().write(new Packet(PacketType.DATA, Tools.tabularize("lobby", "ownjoin", player.toString()))); + player.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("lobby", "ownjoin", player.toString()))); if (getLobbyType() == LobbyType.MULTI) { sendGameList(player); } @@ -89,7 +89,7 @@ public void sendGameList(Player player) { length++; } } - player.getChannel().write(new Packet(PacketType.DATA, Tools.tabularize("lobby", "gamelist", "full", length, buff.toString()))); + player.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("lobby", "gamelist", "full", length, buff.toString()))); } public Game getGame(int id) { diff --git a/server/src/main/java/org/moparforia/server/game/Player.java b/server/src/main/java/org/moparforia/server/game/Player.java index eb8708af..9068ce5e 100644 --- a/server/src/main/java/org/moparforia/server/game/Player.java +++ b/server/src/main/java/org/moparforia/server/game/Player.java @@ -1,10 +1,12 @@ package org.moparforia.server.game; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; +import io.netty.util.AttributeKey; import org.moparforia.shared.Tools; public class Player { + public static final AttributeKey PLAYER_ATTRIBUTE_KEY = AttributeKey.newInstance("PLAYER_ATTRIBUTE"); public static final int ACCESSLEVEL_NORMAL = 0; // todo: enum this ? public static final int ACCESSLEVEL_SHERIFF = 1; public static final int ACCESSLEVEL_ADMIN = 2; diff --git a/server/src/main/java/org/moparforia/server/game/PlayerCollection.java b/server/src/main/java/org/moparforia/server/game/PlayerCollection.java index 6f463d4e..ef61b462 100644 --- a/server/src/main/java/org/moparforia/server/game/PlayerCollection.java +++ b/server/src/main/java/org/moparforia/server/game/PlayerCollection.java @@ -34,20 +34,20 @@ protected boolean removePlayer(Player player) { public void writeAll(Packet packet) { for (Player player : getPlayers()) { - player.getChannel().write(packet); + player.getChannel().writeAndFlush(packet); } } public void writeAll(String message) { for (Player player : getPlayers()) { - player.getChannel().write(message); + player.getChannel().writeAndFlush(message); } } public void writeExcluding(Player exclude, Packet packet) { for (Player player : getPlayers()) { if (player != exclude) { - player.getChannel().write(packet); + player.getChannel().writeAndFlush(packet); } } } @@ -55,7 +55,7 @@ public void writeExcluding(Player exclude, Packet packet) { public void writeExcluding(Player exclude, String message) { for (Player player : getPlayers()) { if (player != exclude) { - player.getChannel().write(message); + player.getChannel().writeAndFlush(message); } } } diff --git a/server/src/main/java/org/moparforia/server/game/gametypes/GolfGame.java b/server/src/main/java/org/moparforia/server/game/gametypes/GolfGame.java index 546541bf..91ff7e04 100644 --- a/server/src/main/java/org/moparforia/server/game/gametypes/GolfGame.java +++ b/server/src/main/java/org/moparforia/server/game/gametypes/GolfGame.java @@ -1,6 +1,6 @@ package org.moparforia.server.game.gametypes; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.moparforia.server.Server; import org.moparforia.server.game.Game; import org.moparforia.server.game.Lobby; @@ -137,8 +137,8 @@ public void rateTrack(String rating) { public void sendGameInfo(Player player) { Channel c = player.getChannel(); - c.write(new Packet(PacketType.DATA, Tools.tabularize("status", "game"))); - c.write(new Packet(PacketType.DATA, Tools.tabularize("game", "gameinfo", + c.writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("status", "game"))); + c.writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("game", "gameinfo", name, passworded ? "t" : "f", gameId, numPlayers, tracks.size(), tracksType, maxStrokes, strokeTimeout, waterEvent, collision, trackScoring, trackScoringEnd, "f"))); diff --git a/server/src/main/java/org/moparforia/server/game/gametypes/golf/DualGame.java b/server/src/main/java/org/moparforia/server/game/gametypes/golf/DualGame.java index e26d7dda..3f441154 100644 --- a/server/src/main/java/org/moparforia/server/game/gametypes/golf/DualGame.java +++ b/server/src/main/java/org/moparforia/server/game/gametypes/golf/DualGame.java @@ -26,7 +26,7 @@ public DualGame(Player challenger, Player challenged, int gameId, int numberOfTr false, numberOfTracks, -1, tracksType, maxStrokes, strokeTimeout, waterEvent, collision, trackScoring, trackScoringEnd, 2); - challenged.getChannel().write(new Packet(PacketType.DATA, + challenged.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("lobby", "challenge", challenger.getNick(), numberOfTracks, tracksType, maxStrokes, strokeTimeout, waterEvent, collision, trackScoring, trackScoringEnd))); diff --git a/server/src/main/java/org/moparforia/server/net/ClientChannelHandler.java b/server/src/main/java/org/moparforia/server/net/ClientChannelHandler.java index e6ecba48..1e06f2d3 100644 --- a/server/src/main/java/org/moparforia/server/net/ClientChannelHandler.java +++ b/server/src/main/java/org/moparforia/server/net/ClientChannelHandler.java @@ -1,13 +1,15 @@ package org.moparforia.server.net; -import org.jboss.netty.channel.*; -import org.jboss.netty.handler.timeout.IdleState; -import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler; -import org.jboss.netty.handler.timeout.IdleStateEvent; +import io.netty.channel.Channel; +import io.netty.channel.ChannelDuplexHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.timeout.IdleState; +import io.netty.handler.timeout.IdleStateEvent; import org.moparforia.server.Server; import org.moparforia.server.event.*; +import org.moparforia.server.game.Player; -public class ClientChannelHandler extends IdleStateAwareChannelHandler { +public class ClientChannelHandler extends ChannelDuplexHandler { private final Server server; @@ -16,42 +18,46 @@ public ClientChannelHandler(Server server) { } @Override - public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { - Packet packet = (Packet) e.getMessage(); - System.out.println(">>> " + e.getMessage()); + public void channelRead(ChannelHandlerContext ctx, Object msg) { + Packet packet = (Packet) msg; + System.out.println("<<< " + packet); + ctx.channel().attr(ClientState.CLIENT_STATE_ATTRIBUTE_KEY).get().setLastActivityTime(System.currentTimeMillis()); server.addEvent(new PacketReceivedEvent(packet)); } @Override - public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) throws Exception { - if (e.getState() == IdleState.READER_IDLE) { - long time = System.currentTimeMillis() - e.getLastActivityTimeMillis(); - if (time > 20000) { - e.getChannel().close(); - } else if (time > 5000) { - e.getChannel().write("c ping\n"); + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { + if (evt instanceof IdleStateEvent e) { + if (e.state() == IdleState.READER_IDLE) { + ClientState state = ctx.channel().attr(ClientState.CLIENT_STATE_ATTRIBUTE_KEY).get(); + long time = System.currentTimeMillis() - state.getLastActivityTime(); + if (time > 20000) { + ctx.channel().close(); + } else if (time > 5000) { + ctx.channel().writeAndFlush("c ping\n"); + } } } } @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) { - //noinspection ThrowableResultOfMethodCallIgnored - e.getCause().printStackTrace(); - e.getChannel().close(); + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + cause.printStackTrace(); + ctx.channel().close(); } @Override - public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) { - server.addEvent(new ClientConnectedEvent(e.getChannel())); + public void channelActive(ChannelHandlerContext ctx) { + server.addEvent(new ClientConnectedEvent(ctx.channel())); } @Override - public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) { - Channel channel = e.getChannel(); + public void channelInactive(ChannelHandlerContext ctx) { + Channel channel = ctx.channel(); server.addEvent(new ClientDisconnectedEvent(channel)); - final int id = channel.getId(); - if (server.hasPlayer(id)) { + Player player = channel.attr(Player.PLAYER_ATTRIBUTE_KEY).get(); + if (player != null && server.hasPlayer(player.getId())) { + int id = player.getId(); server.addEvent(new TimedEvent(30_000) { // todo: confirm this time @Override public void process(Server server) { diff --git a/server/src/main/java/org/moparforia/server/net/ClientState.java b/server/src/main/java/org/moparforia/server/net/ClientState.java index 1a4ad218..863fe2b4 100644 --- a/server/src/main/java/org/moparforia/server/net/ClientState.java +++ b/server/src/main/java/org/moparforia/server/net/ClientState.java @@ -1,22 +1,44 @@ package org.moparforia.server.net; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelLocal; + +import io.netty.util.AttributeKey; + public final class ClientState { - public static final ChannelLocal sentCount = new ChannelLocal() { - @Override - protected Long initialValue(Channel channel) { - return 0L; - } - }; + public static final AttributeKey CLIENT_STATE_ATTRIBUTE_KEY = AttributeKey.valueOf("MESSAGE_COUNTS"); + + private long sentCount; + private long receivedCount; + private long lastActivityTime; + + public ClientState() { + this.sentCount = 0; + this.receivedCount = 0; + this.lastActivityTime = System.currentTimeMillis(); + } + + public long getSentCount() { + return sentCount; + } + + public void setSentCount(long sentCount) { + this.sentCount = sentCount; + } + + public long getReceivedCount() { + return receivedCount; + } + + public void setReceivedCount(long receivedCount) { + this.receivedCount = receivedCount; + } - public static final ChannelLocal recvCount = new ChannelLocal() { - @Override - protected Long initialValue(Channel channel) { - return 0L; - } - }; + public long getLastActivityTime() { + return lastActivityTime; + } + public void setLastActivityTime(long lastActivityTime) { + this.lastActivityTime = lastActivityTime; + } } diff --git a/server/src/main/java/org/moparforia/server/net/Packet.java b/server/src/main/java/org/moparforia/server/net/Packet.java index 371bc6c3..7cab2b38 100644 --- a/server/src/main/java/org/moparforia/server/net/Packet.java +++ b/server/src/main/java/org/moparforia/server/net/Packet.java @@ -1,6 +1,6 @@ package org.moparforia.server.net; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; @SuppressWarnings("SameParameterValue") public class Packet { diff --git a/server/src/main/java/org/moparforia/server/net/PacketDecoder.java b/server/src/main/java/org/moparforia/server/net/PacketDecoder.java index f2b99a95..bf1438ed 100644 --- a/server/src/main/java/org/moparforia/server/net/PacketDecoder.java +++ b/server/src/main/java/org/moparforia/server/net/PacketDecoder.java @@ -1,27 +1,26 @@ package org.moparforia.server.net; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; -import org.jboss.netty.util.CharsetUtil; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageDecoder; +import io.netty.util.CharsetUtil; -public class PacketDecoder extends OneToOneDecoder { +import java.util.List; + +public class PacketDecoder extends ByteToMessageDecoder { @Override - protected Object decode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { - if (msg instanceof ChannelBuffer) { - Packet packet = new Packet(channel, ((ChannelBuffer) msg).toString(CharsetUtil.UTF_8)); - if (packet.getType() == PacketType.DATA) { - long count = ClientState.recvCount.get(channel); - if (count == packet.getCount()) { - ClientState.recvCount.set(channel, count + 1); - } else { - channel.close(); - return null; - } + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + Channel channel = ctx.channel(); + Packet packet = new Packet(channel, in.readBytes(in.readableBytes()).toString(CharsetUtil.UTF_8)); + if (packet.getType() == PacketType.DATA) { + long count = channel.attr(ClientState.CLIENT_STATE_ATTRIBUTE_KEY).get().getReceivedCount(); + if (count == packet.getCount()) { + channel.attr(ClientState.CLIENT_STATE_ATTRIBUTE_KEY).get().setReceivedCount(count + 1); + } else { + channel.close(); } - return packet; } - return msg; + out.add(packet); } } diff --git a/server/src/main/java/org/moparforia/server/net/PacketEncoder.java b/server/src/main/java/org/moparforia/server/net/PacketEncoder.java index c0e5bc7f..c1e9a5c3 100644 --- a/server/src/main/java/org/moparforia/server/net/PacketEncoder.java +++ b/server/src/main/java/org/moparforia/server/net/PacketEncoder.java @@ -1,44 +1,44 @@ package org.moparforia.server.net; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; -import org.jboss.netty.util.CharsetUtil; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; +import io.netty.util.CharsetUtil; -import static org.jboss.netty.buffer.ChannelBuffers.copiedBuffer; +import static io.netty.buffer.Unpooled.copiedBuffer; -public class PacketEncoder extends OneToOneEncoder { +public class PacketEncoder extends MessageToByteEncoder { @Override - protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { - if (msg instanceof Packet) { - Packet packet = (Packet) msg; + protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) { + Channel channel = ctx.channel(); + if (msg instanceof Packet packet) { String encoded; if (packet.getType() != PacketType.NONE) { encoded = packet.getType().toString().toLowerCase().charAt(0) + " "; if (packet.getType() == PacketType.DATA) { - long count = ClientState.sentCount.get(channel); + long count = channel.attr(ClientState.CLIENT_STATE_ATTRIBUTE_KEY).get().getSentCount(); encoded += count + " "; - ClientState.sentCount.set(channel, count + 1); + channel.attr(ClientState.CLIENT_STATE_ATTRIBUTE_KEY).get().setSentCount(count + 1); } } else { encoded = ""; } encoded += packet.getMessage() + '\n'; - return copiedBuffer(ctx.getChannel().getConfig().getBufferFactory().getDefaultOrder(), encoded, CharsetUtil.UTF_8); - } else if (msg instanceof String) { - String m = (String) msg; + out.writeBytes(copiedBuffer(encoded, CharsetUtil.UTF_8)); + } else if (msg instanceof String m) { if (!m.endsWith("\n")) { m += "\n"; } if (m.startsWith("d ")) { - long count = ClientState.sentCount.get(channel); + long count = channel.attr(ClientState.CLIENT_STATE_ATTRIBUTE_KEY).get().getSentCount(); m = "d " + count + " " + m.substring(2); - ClientState.sentCount.set(channel, count + 1); + channel.attr(ClientState.CLIENT_STATE_ATTRIBUTE_KEY).get().setSentCount(count + 1); } - return copiedBuffer(ctx.getChannel().getConfig().getBufferFactory().getDefaultOrder(), m, CharsetUtil.UTF_8); + out.writeBytes(copiedBuffer(m, CharsetUtil.UTF_8)); + } else { + out.writeBytes((ByteBuf) msg); } - return msg; } - } diff --git a/server/src/main/java/org/moparforia/server/net/packethandlers/NewHandler.java b/server/src/main/java/org/moparforia/server/net/packethandlers/NewHandler.java index 401e645d..f63ffb0c 100644 --- a/server/src/main/java/org/moparforia/server/net/packethandlers/NewHandler.java +++ b/server/src/main/java/org/moparforia/server/net/packethandlers/NewHandler.java @@ -1,6 +1,6 @@ package org.moparforia.server.net.packethandlers; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.moparforia.server.Server; import org.moparforia.server.event.PlayerConnectedEvent; import org.moparforia.server.game.Player; @@ -28,9 +28,9 @@ public boolean handle(Server server, Packet packet, Matcher message) { Channel channel = packet.getChannel(); int id = server.getNextPlayerId(); Player player = new Player(channel, id); - channel.setAttachment(player); + channel.attr(Player.PLAYER_ATTRIBUTE_KEY).set(player); server.addPlayer(player); - channel.write("c id " + id + "\n"); + channel.writeAndFlush("c id " + id + "\n"); server.addEvent(new PlayerConnectedEvent(player.getId(), false)); return true; } diff --git a/server/src/main/java/org/moparforia/server/net/packethandlers/QuitHandler.java b/server/src/main/java/org/moparforia/server/net/packethandlers/QuitHandler.java index 454bfa90..2b85ec81 100644 --- a/server/src/main/java/org/moparforia/server/net/packethandlers/QuitHandler.java +++ b/server/src/main/java/org/moparforia/server/net/packethandlers/QuitHandler.java @@ -26,7 +26,7 @@ public Pattern getPattern() { @Override public boolean handle(Server server, Packet packet, Matcher message) { - Player player = (Player) packet.getChannel().getAttachment(); + Player player = packet.getChannel().attr(Player.PLAYER_ATTRIBUTE_KEY).get(); if (message.group(1).contains("lobby")) { player.getLobby().removePlayer(player, Lobby.PART_REASON_USERLEFT); } diff --git a/server/src/main/java/org/moparforia/server/net/packethandlers/ReconnectHandler.java b/server/src/main/java/org/moparforia/server/net/packethandlers/ReconnectHandler.java index 185ce45a..8524f767 100644 --- a/server/src/main/java/org/moparforia/server/net/packethandlers/ReconnectHandler.java +++ b/server/src/main/java/org/moparforia/server/net/packethandlers/ReconnectHandler.java @@ -1,6 +1,6 @@ package org.moparforia.server.net.packethandlers; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.moparforia.server.Server; import org.moparforia.server.event.PlayerConnectedEvent; import org.moparforia.server.game.Player; @@ -32,8 +32,8 @@ public boolean handle(Server server, Packet packet, Matcher message) { Player p = server.getPlayer(id); Channel c = packet.getChannel(); p.setChannel(c); - c.setAttachment(p); - c.write("c rcok\n"); + c.attr(Player.PLAYER_ATTRIBUTE_KEY).set(p); + c.writeAndFlush("c rcok\n"); server.addEvent(new PlayerConnectedEvent(id, true)); } return true; diff --git a/server/src/main/java/org/moparforia/server/net/packethandlers/VersionHandler.java b/server/src/main/java/org/moparforia/server/net/packethandlers/VersionHandler.java index cd768d27..854befac 100644 --- a/server/src/main/java/org/moparforia/server/net/packethandlers/VersionHandler.java +++ b/server/src/main/java/org/moparforia/server/net/packethandlers/VersionHandler.java @@ -30,10 +30,10 @@ public boolean handle(Server server, Packet packet, Matcher message) { packet.getChannel().close(); return true; } - Player player = (Player) packet.getChannel().getAttachment(); + Player player = packet.getChannel().attr(Player.PLAYER_ATTRIBUTE_KEY).get(); player.setGameType(gameType); if(gameType == GameType.GOLF) { - player.getChannel().write(new Packet(PacketType.DATA, Tools.tabularize("status", "login"))); + player.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("status", "login"))); }//todo return true; } diff --git a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/ChatHandler.java b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/ChatHandler.java index 9a7d559c..f79ab5de 100644 --- a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/ChatHandler.java +++ b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/ChatHandler.java @@ -29,7 +29,7 @@ public Pattern getPattern() { @Override public boolean handle(Server server, Packet packet, Matcher message) { - Player player = (Player) packet.getChannel().getAttachment(); + Player player = packet.getChannel().attr(Player.PLAYER_ATTRIBUTE_KEY).get(); PlayerCollection destination; if (message.group(1).equals("game")) { destination = player.getGame(); @@ -43,10 +43,10 @@ public boolean handle(Server server, Packet packet, Matcher message) { for (Player otherPlayer : destination.getPlayers()) { if (player != otherPlayer) { if (message.group(1).equals("game")) { - otherPlayer.getChannel().write(new Packet(PacketType.DATA, + otherPlayer.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("game", "say", ((Game) destination).getPlayerId(player), message.group(3)))); } else { - otherPlayer.getChannel().write(new Packet(PacketType.DATA, + otherPlayer.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("lobby", "say", message.group(3), player.getNick(), message.group(4)))); } } @@ -54,7 +54,7 @@ public boolean handle(Server server, Packet packet, Matcher message) { } else if (message.group(2).equals("sayp")) { for (Player otherPlayer : destination.getPlayers()) { if (otherPlayer.getNick().equals(message.group(3))) { - otherPlayer.getChannel().write(new Packet(PacketType.DATA, + otherPlayer.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize(message.group(1), "sayp", player.getNick(), message.group(4)))); break; } diff --git a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/GameHandler.java b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/GameHandler.java index 208b9acd..dbbc4d13 100644 --- a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/GameHandler.java +++ b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/GameHandler.java @@ -28,7 +28,7 @@ public Pattern getPattern() { @Override public boolean handle(Server server, Packet packet, Matcher message) { - Player player = (Player) packet.getChannel().getAttachment(); + Player player = packet.getChannel().attr(Player.PLAYER_ATTRIBUTE_KEY).get(); Game game = player.getGame(); return game.handlePacket(server, player, message); } diff --git a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LanguageHandler.java b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LanguageHandler.java index 89eda1ff..d3ab0d28 100644 --- a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LanguageHandler.java +++ b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LanguageHandler.java @@ -23,7 +23,7 @@ public Pattern getPattern() { @Override public boolean handle(Server server, Packet packet, Matcher message) { - Player player = (Player) packet.getChannel().getAttachment(); + Player player = packet.getChannel().attr(Player.PLAYER_ATTRIBUTE_KEY).get(); player.setLocale(message.group(1)); // todo: check if we axly support this locale return true; } diff --git a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbyCreateSinglePlayerHandler.java b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbyCreateSinglePlayerHandler.java index 9ed11b42..23afc780 100644 --- a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbyCreateSinglePlayerHandler.java +++ b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbyCreateSinglePlayerHandler.java @@ -28,7 +28,7 @@ public Pattern getPattern() { @Override public boolean handle(Server server, Packet packet, Matcher message) { - Player player = (Player) packet.getChannel().getAttachment(); + Player player = packet.getChannel().attr(Player.PLAYER_ATTRIBUTE_KEY).get(); int number = Integer.parseInt(message.group(2)); if (message.group(1).equals("t")) { int trackType = Integer.parseInt(message.group(3)); diff --git a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbyDualplayerHandler.java b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbyDualplayerHandler.java index 3a6b0768..e2501305 100644 --- a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbyDualplayerHandler.java +++ b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbyDualplayerHandler.java @@ -29,12 +29,12 @@ public Pattern getPattern() { @Override public boolean handle(Server server, Packet packet, Matcher message) { - Player player = (Player) packet.getChannel().getAttachment(); + Player player = packet.getChannel().attr(Player.PLAYER_ATTRIBUTE_KEY).get(); if (message.group(1).equals("lobby")) { if (message.group(2).equals("challenge")) { Player other = getPlayer(server, message.group(3)); if (other == null) {// || other.isNotAcceptingChallenges()) { - player.getChannel().write(new Packet(PacketType.DATA, + player.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("lobby", "cfail", "nochall"))); return true; } @@ -51,7 +51,7 @@ public boolean handle(Server server, Packet packet, Matcher message) { } else if (message.group(2).equals("accept")) { Player other = getPlayer(server, message.group(3)); if (other == null || !(other.getGame() instanceof DualGame)) { - player.getChannel().write(new Packet(PacketType.DATA, + player.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("lobby", "cfail", "nouser")));//todo kick the faggot return true; } @@ -60,20 +60,20 @@ public boolean handle(Server server, Packet packet, Matcher message) { } else if (message.group(2).equals("cancel")) { Player other = getPlayer(server, message.group(3)); if (other == null || !(other.getGame() instanceof DualGame)) { - player.getChannel().write(new Packet(PacketType.DATA, + player.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("lobby", "cfail", "nouser")));//todo kick the faggot return true; } - other.getChannel().write(new Packet(PacketType.DATA, + other.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("lobby", "cancel"))); } else if (message.group(2).equals("cfail") && message.group(4).equals("refuse")) { Player other = getPlayer(server, message.group(3)); if (other == null || !(other.getGame() instanceof DualGame)) { - player.getChannel().write(new Packet(PacketType.DATA,//todo kick the faggot + player.getChannel().writeAndFlush(new Packet(PacketType.DATA,//todo kick the faggot Tools.tabularize("lobby", "cfail", "nouser"))); return true; } - other.getChannel().write(new Packet(PacketType.DATA, + other.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("lobby", "cfail", "refuse"))); //todo HOW TO REMOVE THE GAME FROM THE SERVER } else if (message.group(2).equals("nc")) { diff --git a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbyHandler.java b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbyHandler.java index 69368245..65db4f6d 100644 --- a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbyHandler.java +++ b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbyHandler.java @@ -35,7 +35,7 @@ public Pattern getPattern() { @Override public boolean handle(Server server, Packet packet, Matcher message) { - Player player = (Player) packet.getChannel().getAttachment(); + Player player = packet.getChannel().attr(Player.PLAYER_ATTRIBUTE_KEY).get(); if (message.group(1).equals("back")) { if (player.getLobby() == null) { packet.getChannel().close(); @@ -73,7 +73,7 @@ public boolean handle(Server server, Packet packet, Matcher message) { for (int i = 0; i < tracksInfo.length; i++) { cmd += Tools.tabularize(tracksInfo[i]) + (i == tracksInfo.length - 1 ? "" : '\t'); } - packet.getChannel().write(new Packet(PacketType.DATA, + packet.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("lobby", "tracksetlist", cmd))); } return true; diff --git a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbyMultiplayerHandler.java b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbyMultiplayerHandler.java index c387b122..966c338a 100644 --- a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbyMultiplayerHandler.java +++ b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbyMultiplayerHandler.java @@ -30,7 +30,7 @@ public Pattern getPattern() { } public boolean handle(Server server, Packet packet, Matcher message) { - Player player = (Player) packet.getChannel().getAttachment(); + Player player = packet.getChannel().attr(Player.PLAYER_ATTRIBUTE_KEY).get(); Lobby lobby = player.getLobby(); if (message.group(1).equals("c")) { diff --git a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbySelectHandler.java b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbySelectHandler.java index 0a0b5f73..5de96283 100644 --- a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbySelectHandler.java +++ b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LobbySelectHandler.java @@ -30,11 +30,11 @@ public Pattern getPattern() { @Override public boolean handle(Server server, Packet packet, Matcher message) { if (message.group(1).equals("rnop")) { - packet.getChannel().write("d lobbyselect\tnop\t" + Tools.tabularize(server.getLobby(LobbyType.SINGLE).totalPlayerCount(), server.getLobby(LobbyType.DUAL).totalPlayerCount(), server.getLobby(LobbyType.MULTI).totalPlayerCount())); + packet.getChannel().writeAndFlush("d lobbyselect\tnop\t" + Tools.tabularize(server.getLobby(LobbyType.SINGLE).totalPlayerCount(), server.getLobby(LobbyType.DUAL).totalPlayerCount(), server.getLobby(LobbyType.MULTI).totalPlayerCount())); } else if (message.group(1).equals("select")) { // 1 for single, 1h for single hidden chat, 2 for dual, x for multi LobbyType lobbyType = LobbyType.getLobby(message.group(2)); - Player player = (Player) packet.getChannel().getAttachment(); + Player player = packet.getChannel().attr(Player.PLAYER_ATTRIBUTE_KEY).get(); player.setChatHidden(message.group(3) != null && message.group(3).equals("h")); server.getLobby(lobbyType).addPlayer(player, Lobby.JOIN_TYPE_NORMAL); } diff --git a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LoginHandler.java b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LoginHandler.java index d3614221..020a1f0f 100644 --- a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LoginHandler.java +++ b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LoginHandler.java @@ -27,7 +27,7 @@ public Pattern getPattern() { @Override public boolean handle(Server server, Packet packet, Matcher message) { - Player player = (Player) packet.getChannel().getAttachment(); + Player player = packet.getChannel().attr(Player.PLAYER_ATTRIBUTE_KEY).get(); String username = "~anonym-" + (int) (Math.random() * 10000); @@ -36,8 +36,8 @@ public boolean handle(Server server, Packet packet, Matcher message) { player.setEmailVerified(true); player.setRegistered(false); - packet.getChannel().write(new Packet(PacketType.DATA, Tools.tabularize("basicinfo", player.isEmailVerified(), player.getAccessLevel(), "t", "t"))); - packet.getChannel().write(new Packet(PacketType.DATA, Tools.tabularize("status", "lobbyselect", "300"))); + packet.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("basicinfo", player.isEmailVerified(), player.getAccessLevel(), "t", "t"))); + packet.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("status", "lobbyselect", "300"))); return true; } } diff --git a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LoginTypeHandler.java b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LoginTypeHandler.java index fda04a7a..5164e9b1 100644 --- a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LoginTypeHandler.java +++ b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/LoginTypeHandler.java @@ -26,7 +26,7 @@ public Pattern getPattern() { @Override public boolean handle(Server server, Packet packet, Matcher message) { - packet.getChannel().write(new Packet(PacketType.DATA, Tools.tabularize("status", "login"))); + packet.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("status", "login"))); return true; } } diff --git a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/TrackTestLoginHandler.java b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/TrackTestLoginHandler.java index 597b78f1..e076c743 100644 --- a/server/src/main/java/org/moparforia/server/net/packethandlers/golf/TrackTestLoginHandler.java +++ b/server/src/main/java/org/moparforia/server/net/packethandlers/golf/TrackTestLoginHandler.java @@ -50,12 +50,12 @@ public boolean handle(Server server, Packet packet, Matcher message) { } } - Player player = (Player) packet.getChannel().getAttachment(); + Player player = packet.getChannel().attr(Player.PLAYER_ATTRIBUTE_KEY).get(); player.setNick(username); player.setEmailVerified(true); player.setRegistered(!anonym); - packet.getChannel().write(new Packet(PacketType.DATA, Tools.tabularize("basicinfo", player.isEmailVerified(), player.getAccessLevel(), "t", "f"))); - packet.getChannel().write(new Packet(PacketType.DATA, Tools.tabularize("status", "lobbyselect", 300))); + packet.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("basicinfo", player.isEmailVerified(), player.getAccessLevel(), "t", "f"))); + packet.getChannel().writeAndFlush(new Packet(PacketType.DATA, Tools.tabularize("status", "lobbyselect", 300))); return true; } }