diff --git a/protocol/build.gradle b/protocol/build.gradle
index 03ac861..b8fb582 100644
--- a/protocol/build.gradle
+++ b/protocol/build.gradle
@@ -1,8 +1,9 @@
apply from: rootDir.toPath().resolve('logic.gradle').toFile()
dependencies {
- api libs.netty
api libs.reactor
+
+ implementation libs.netty
implementation libs.json
testImplementation libs.lang3
diff --git a/protocol/src/main/java/mc/protocol/ChannelContext.java b/protocol/src/main/java/mc/protocol/ChannelContext.java
deleted file mode 100644
index 51d7a89..0000000
--- a/protocol/src/main/java/mc/protocol/ChannelContext.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package mc.protocol;
-
-import io.netty.channel.ChannelHandlerContext;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import mc.protocol.packets.ClientSidePacket;
-
-@RequiredArgsConstructor
-public class ChannelContext
{
-
- @Getter
- private final ChannelHandlerContext ctx;
-
- @Getter
- private final P packet;
-
- public void setState(State state) {
- ctx.channel().attr(NetworkAttributes.STATE).set(state);
- }
-}
diff --git a/protocol/src/main/java/mc/protocol/NettyConnectionContext.java b/protocol/src/main/java/mc/protocol/NettyConnectionContext.java
new file mode 100644
index 0000000..a4cdc65
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/NettyConnectionContext.java
@@ -0,0 +1,49 @@
+package mc.protocol;
+
+import io.netty.channel.ChannelHandlerContext;
+import lombok.RequiredArgsConstructor;
+import mc.protocol.api.ConnectionContext;
+import mc.protocol.packets.ClientSidePacket;
+import mc.protocol.packets.ServerSidePacket;
+
+@RequiredArgsConstructor
+public class NettyConnectionContext
implements ConnectionContext
{
+
+ private final ChannelHandlerContext ctx;
+ private final P packet;
+
+ @Override
+ public State getState() {
+ return ctx.channel().attr(NetworkAttributes.STATE).get();
+ }
+
+ @Override
+ public void setState(State state) {
+ ctx.channel().attr(NetworkAttributes.STATE).set(state);
+ }
+
+ @Override
+ public P clientPacket() {
+ return packet;
+ }
+
+ @Override
+ public void send(ServerSidePacket packet) {
+ ctx.write(packet);
+ }
+
+ @Override
+ public void sendNow(ServerSidePacket packet) {
+ ctx.writeAndFlush(packet);
+ }
+
+ @Override
+ public void flushSending() {
+ ctx.flush();
+ }
+
+ @Override
+ public void disconnect() {
+ ctx.disconnect();
+ }
+}
diff --git a/protocol/src/main/java/mc/protocol/NettyServer.java b/protocol/src/main/java/mc/protocol/NettyServer.java
index 2c92645..16325ac 100644
--- a/protocol/src/main/java/mc/protocol/NettyServer.java
+++ b/protocol/src/main/java/mc/protocol/NettyServer.java
@@ -1,22 +1,40 @@
package mc.protocol;
import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelPipeline;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.handler.logging.LogLevel;
+import io.netty.handler.logging.LoggingHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import mc.protocol.di.DaggerProtocolComponent;
-import mc.protocol.di.ProtocolComponent;
+import mc.protocol.api.ConnectionContext;
+import mc.protocol.api.Server;
+import mc.protocol.io.codec.ProtocolDecoder;
+import mc.protocol.io.codec.ProtocolEncoder;
+import mc.protocol.io.codec.ProtocolSplitter;
+
+import javax.annotation.Nonnull;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.function.Consumer;
@Slf4j
@RequiredArgsConstructor
-public class NettyServer {
+public class NettyServer implements Server {
- private final ServerBootstrap serverBootstrap;
+ private Consumer> consumerNewConnection;
+ private Consumer> consumerDisconnect;
+ @Override
public void bind(String host, int port) {
log.info("Network starting: {}:{}", host, port);
try {
- serverBootstrap.bind(host, port).sync().channel().closeFuture().sync();
+ createServerBootstrap().bind(host, port).sync().channel().closeFuture().sync();
} catch (InterruptedException e) {
if (log.isTraceEnabled()) {
log.trace("{}: {}", e.getClass().getSimpleName(), e.getMessage(), e);
@@ -24,8 +42,45 @@ public class NettyServer {
}
}
- public static NettyServer createServer() {
- ProtocolComponent component = DaggerProtocolComponent.create();
- return component.getNettyServer();
+ @Override
+ public void onNewConnect(Consumer> consumer) {
+ this.consumerNewConnection = consumer;
+ }
+
+ @Override
+ public void onDisonnect(Consumer> consumer) {
+ this.consumerDisconnect = consumer;
+ }
+
+ private ServerBootstrap createServerBootstrap() {
+ ServerBootstrap bootstrap = new ServerBootstrap();
+
+ bootstrap.group(new NioEventLoopGroup(1), new NioEventLoopGroup())
+ .channel(NioServerSocketChannel.class)
+ .childHandler(createChannelChannelInitializer());
+
+ return bootstrap;
+ }
+
+ private ChannelInitializer createChannelChannelInitializer() {
+ return new ChannelInitializer<>() {
+ @Override
+ protected void initChannel(@Nonnull SocketChannel socketChannel) {
+ ChannelPipeline pipeline = socketChannel.pipeline();
+ createChannelHandlerMap().forEach(pipeline::addLast);
+ }
+ };
+ }
+
+ private Map createChannelHandlerMap() {
+ Map map = new LinkedHashMap<>();
+
+ map.put("packet_splitter", new ProtocolSplitter());
+ map.put("logger", new LoggingHandler(LogLevel.DEBUG));
+ map.put("packet_decoder", new ProtocolDecoder(true, consumerNewConnection, consumerDisconnect));
+ map.put("packet_encoder", new ProtocolEncoder());
+ map.put("packet_handler", new PacketInboundHandler());
+
+ return map;
}
}
diff --git a/protocol/src/main/java/mc/protocol/PacketInboundHandler.java b/protocol/src/main/java/mc/protocol/PacketInboundHandler.java
index a99fb4d..3f170e9 100644
--- a/protocol/src/main/java/mc/protocol/PacketInboundHandler.java
+++ b/protocol/src/main/java/mc/protocol/PacketInboundHandler.java
@@ -3,6 +3,7 @@ package mc.protocol;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.RequiredArgsConstructor;
+import mc.protocol.api.ConnectionContext;
import mc.protocol.packets.ClientSidePacket;
import reactor.core.publisher.Sinks;
@@ -12,11 +13,11 @@ public class PacketInboundHandler extends SimpleChannelInboundHandler packetSinks = ctx.channel().attr(NetworkAttributes.STATE)
+ Sinks.Many packetSinks = ctx.channel().attr(NetworkAttributes.STATE)
.get().getPacketSinks(packet.getClass());
if (packetSinks != null) {
- packetSinks.tryEmitNext(new ChannelContext<>(ctx, packet));
+ packetSinks.tryEmitNext(new NettyConnectionContext<>(ctx, packet));
}
}
}
diff --git a/protocol/src/main/java/mc/protocol/State.java b/protocol/src/main/java/mc/protocol/State.java
index 180f4d7..72e39b4 100644
--- a/protocol/src/main/java/mc/protocol/State.java
+++ b/protocol/src/main/java/mc/protocol/State.java
@@ -2,6 +2,7 @@ package mc.protocol;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
+import mc.protocol.api.ConnectionContext;
import mc.protocol.packets.ClientSidePacket;
import mc.protocol.packets.Packet;
import mc.protocol.packets.PingPacket;
@@ -84,7 +85,7 @@ public enum State {
private final Map, Integer> serverSidePackets;
@SuppressWarnings("rawtypes")
- private final Map, Sinks.Many> observedMap = new HashMap<>();
+ private final Map, Sinks.Many> observedMap = new HashMap<>();
State(int id, Map> clientSidePackets) {
this.id = id;
@@ -104,13 +105,13 @@ public enum State {
@SuppressWarnings("rawtypes")
- public Sinks.Many getPacketSinks(Class packetClass) {
+ public
Sinks.Many getPacketSinks(Class packetClass) {
return observedMap.get(packetClass);
}
@SuppressWarnings("unchecked")
- public
Flux> packetFlux(Class packetClass) {
+ public
Flux> packetFlux(Class packetClass) {
return observedMap.computeIfAbsent(packetClass, aClass -> Sinks.many().multicast().directBestEffort())
- .asFlux().map(ChannelContext.class::cast);
+ .asFlux().map(ConnectionContext.class::cast);
}
}
diff --git a/protocol/src/main/java/mc/protocol/api/ConnectionContext.java b/protocol/src/main/java/mc/protocol/api/ConnectionContext.java
new file mode 100644
index 0000000..b2ed00e
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/api/ConnectionContext.java
@@ -0,0 +1,19 @@
+package mc.protocol.api;
+
+import mc.protocol.State;
+import mc.protocol.packets.ClientSidePacket;
+import mc.protocol.packets.ServerSidePacket;
+
+public interface ConnectionContext
{
+
+ State getState();
+ void setState(State state);
+
+ P clientPacket();
+
+ void send(ServerSidePacket packet);
+ void sendNow(ServerSidePacket packet);
+ void flushSending();
+
+ void disconnect();
+}
diff --git a/protocol/src/main/java/mc/protocol/api/Server.java b/protocol/src/main/java/mc/protocol/api/Server.java
new file mode 100644
index 0000000..e06d137
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/api/Server.java
@@ -0,0 +1,11 @@
+package mc.protocol.api;
+
+import java.util.function.Consumer;
+
+public interface Server {
+
+ void bind(String host, int port);
+
+ void onNewConnect(Consumer> consumer);
+ void onDisonnect(Consumer> consumer);
+}
diff --git a/protocol/src/main/java/mc/protocol/di/ProtocolComponent.java b/protocol/src/main/java/mc/protocol/di/ProtocolComponent.java
index a433211..84caa5b 100644
--- a/protocol/src/main/java/mc/protocol/di/ProtocolComponent.java
+++ b/protocol/src/main/java/mc/protocol/di/ProtocolComponent.java
@@ -1,11 +1,11 @@
package mc.protocol.di;
import dagger.Component;
-import mc.protocol.NettyServer;
+import mc.protocol.api.Server;
@Component(modules = ProtocolModule.class)
@ServerScope
public interface ProtocolComponent {
- NettyServer getNettyServer();
+ Server getServer();
}
diff --git a/protocol/src/main/java/mc/protocol/di/ProtocolModule.java b/protocol/src/main/java/mc/protocol/di/ProtocolModule.java
index 3e8a8df..c298873 100644
--- a/protocol/src/main/java/mc/protocol/di/ProtocolModule.java
+++ b/protocol/src/main/java/mc/protocol/di/ProtocolModule.java
@@ -2,68 +2,16 @@ package mc.protocol.di;
import dagger.Module;
import dagger.Provides;
-import io.netty.bootstrap.ServerBootstrap;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelPipeline;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.channel.socket.nio.NioServerSocketChannel;
-import io.netty.handler.logging.LogLevel;
-import io.netty.handler.logging.LoggingHandler;
import mc.protocol.NettyServer;
-import mc.protocol.PacketInboundHandler;
-import mc.protocol.io.codec.ProtocolDecoder;
-import mc.protocol.io.codec.ProtocolEncoder;
-import mc.protocol.io.codec.ProtocolSplitter;
-
-import javax.annotation.Nonnull;
-import javax.inject.Provider;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import mc.protocol.api.Server;
@Module
public class ProtocolModule {
@Provides
- NettyServer provideServer(ServerBootstrap serverBootstrap) {
- return new NettyServer(serverBootstrap);
+ @ServerScope
+ Server provideServer() {
+ return new NettyServer();
}
- @Provides
- ServerBootstrap provideServerBootstrap(ChannelInitializer channelChannelInitializer) {
- ServerBootstrap bootstrap = new ServerBootstrap();
-
- bootstrap.group(new NioEventLoopGroup(1), new NioEventLoopGroup())
- .channel(NioServerSocketChannel.class)
- .childHandler(channelChannelInitializer);
-
- return bootstrap;
- }
-
- @Provides
- ChannelInitializer provideChannelChannelInitializer(
- Provider