рефакторинг протокола
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
apply from: rootDir.toPath().resolve('logic.gradle').toFile()
|
apply from: rootDir.toPath().resolve('logic.gradle').toFile()
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api libs.netty
|
|
||||||
api libs.reactor
|
api libs.reactor
|
||||||
|
|
||||||
|
implementation libs.netty
|
||||||
implementation libs.json
|
implementation libs.json
|
||||||
|
|
||||||
testImplementation libs.lang3
|
testImplementation libs.lang3
|
||||||
|
|||||||
@@ -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<P extends ClientSidePacket> {
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private final ChannelHandlerContext ctx;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private final P packet;
|
|
||||||
|
|
||||||
public void setState(State state) {
|
|
||||||
ctx.channel().attr(NetworkAttributes.STATE).set(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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<P extends ClientSidePacket> implements ConnectionContext<P> {
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,22 +1,40 @@
|
|||||||
package mc.protocol;
|
package mc.protocol;
|
||||||
|
|
||||||
import io.netty.bootstrap.ServerBootstrap;
|
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.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import mc.protocol.di.DaggerProtocolComponent;
|
import mc.protocol.api.ConnectionContext;
|
||||||
import mc.protocol.di.ProtocolComponent;
|
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
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class NettyServer {
|
public class NettyServer implements Server {
|
||||||
|
|
||||||
private final ServerBootstrap serverBootstrap;
|
private Consumer<ConnectionContext<?>> consumerNewConnection;
|
||||||
|
private Consumer<ConnectionContext<?>> consumerDisconnect;
|
||||||
|
|
||||||
|
@Override
|
||||||
public void bind(String host, int port) {
|
public void bind(String host, int port) {
|
||||||
log.info("Network starting: {}:{}", host, port);
|
log.info("Network starting: {}:{}", host, port);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
serverBootstrap.bind(host, port).sync().channel().closeFuture().sync();
|
createServerBootstrap().bind(host, port).sync().channel().closeFuture().sync();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
if (log.isTraceEnabled()) {
|
if (log.isTraceEnabled()) {
|
||||||
log.trace("{}: {}", e.getClass().getSimpleName(), e.getMessage(), e);
|
log.trace("{}: {}", e.getClass().getSimpleName(), e.getMessage(), e);
|
||||||
@@ -24,8 +42,45 @@ public class NettyServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NettyServer createServer() {
|
@Override
|
||||||
ProtocolComponent component = DaggerProtocolComponent.create();
|
public void onNewConnect(Consumer<ConnectionContext<?>> consumer) {
|
||||||
return component.getNettyServer();
|
this.consumerNewConnection = consumer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisonnect(Consumer<ConnectionContext<?>> 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<SocketChannel> createChannelChannelInitializer() {
|
||||||
|
return new ChannelInitializer<>() {
|
||||||
|
@Override
|
||||||
|
protected void initChannel(@Nonnull SocketChannel socketChannel) {
|
||||||
|
ChannelPipeline pipeline = socketChannel.pipeline();
|
||||||
|
createChannelHandlerMap().forEach(pipeline::addLast);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, ChannelHandler> createChannelHandlerMap() {
|
||||||
|
Map<String, ChannelHandler> 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package mc.protocol;
|
|||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.SimpleChannelInboundHandler;
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import mc.protocol.api.ConnectionContext;
|
||||||
import mc.protocol.packets.ClientSidePacket;
|
import mc.protocol.packets.ClientSidePacket;
|
||||||
import reactor.core.publisher.Sinks;
|
import reactor.core.publisher.Sinks;
|
||||||
|
|
||||||
@@ -12,11 +13,11 @@ public class PacketInboundHandler extends SimpleChannelInboundHandler<ClientSide
|
|||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
@Override
|
@Override
|
||||||
protected void channelRead0(ChannelHandlerContext ctx, ClientSidePacket packet) {
|
protected void channelRead0(ChannelHandlerContext ctx, ClientSidePacket packet) {
|
||||||
Sinks.Many<ChannelContext> packetSinks = ctx.channel().attr(NetworkAttributes.STATE)
|
Sinks.Many<ConnectionContext> packetSinks = ctx.channel().attr(NetworkAttributes.STATE)
|
||||||
.get().getPacketSinks(packet.getClass());
|
.get().getPacketSinks(packet.getClass());
|
||||||
|
|
||||||
if (packetSinks != null) {
|
if (packetSinks != null) {
|
||||||
packetSinks.tryEmitNext(new ChannelContext<>(ctx, packet));
|
packetSinks.tryEmitNext(new NettyConnectionContext<>(ctx, packet));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package mc.protocol;
|
|||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import mc.protocol.api.ConnectionContext;
|
||||||
import mc.protocol.packets.ClientSidePacket;
|
import mc.protocol.packets.ClientSidePacket;
|
||||||
import mc.protocol.packets.Packet;
|
import mc.protocol.packets.Packet;
|
||||||
import mc.protocol.packets.PingPacket;
|
import mc.protocol.packets.PingPacket;
|
||||||
@@ -84,7 +85,7 @@ public enum State {
|
|||||||
private final Map<Class<? extends ServerSidePacket>, Integer> serverSidePackets;
|
private final Map<Class<? extends ServerSidePacket>, Integer> serverSidePackets;
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
private final Map<Class<? extends ClientSidePacket>, Sinks.Many<ChannelContext>> observedMap = new HashMap<>();
|
private final Map<Class<? extends ClientSidePacket>, Sinks.Many<ConnectionContext>> observedMap = new HashMap<>();
|
||||||
|
|
||||||
State(int id, Map<Integer, Class<? extends ClientSidePacket>> clientSidePackets) {
|
State(int id, Map<Integer, Class<? extends ClientSidePacket>> clientSidePackets) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
@@ -104,13 +105,13 @@ public enum State {
|
|||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
public <P extends ClientSidePacket> Sinks.Many<ChannelContext> getPacketSinks(Class<P> packetClass) {
|
public <P extends ClientSidePacket> Sinks.Many<ConnectionContext> getPacketSinks(Class<P> packetClass) {
|
||||||
return observedMap.get(packetClass);
|
return observedMap.get(packetClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <P extends ClientSidePacket> Flux<ChannelContext<P>> packetFlux(Class<P> packetClass) {
|
public <P extends ClientSidePacket> Flux<ConnectionContext<P>> packetFlux(Class<P> packetClass) {
|
||||||
return observedMap.computeIfAbsent(packetClass, aClass -> Sinks.many().multicast().directBestEffort())
|
return observedMap.computeIfAbsent(packetClass, aClass -> Sinks.many().multicast().directBestEffort())
|
||||||
.asFlux().map(ChannelContext.class::cast);
|
.asFlux().map(ConnectionContext.class::cast);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<P extends ClientSidePacket> {
|
||||||
|
|
||||||
|
State getState();
|
||||||
|
void setState(State state);
|
||||||
|
|
||||||
|
P clientPacket();
|
||||||
|
|
||||||
|
void send(ServerSidePacket packet);
|
||||||
|
void sendNow(ServerSidePacket packet);
|
||||||
|
void flushSending();
|
||||||
|
|
||||||
|
void disconnect();
|
||||||
|
}
|
||||||
11
protocol/src/main/java/mc/protocol/api/Server.java
Normal file
11
protocol/src/main/java/mc/protocol/api/Server.java
Normal file
@@ -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<ConnectionContext<?>> consumer);
|
||||||
|
void onDisonnect(Consumer<ConnectionContext<?>> consumer);
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package mc.protocol.di;
|
package mc.protocol.di;
|
||||||
|
|
||||||
import dagger.Component;
|
import dagger.Component;
|
||||||
import mc.protocol.NettyServer;
|
import mc.protocol.api.Server;
|
||||||
|
|
||||||
@Component(modules = ProtocolModule.class)
|
@Component(modules = ProtocolModule.class)
|
||||||
@ServerScope
|
@ServerScope
|
||||||
public interface ProtocolComponent {
|
public interface ProtocolComponent {
|
||||||
|
|
||||||
NettyServer getNettyServer();
|
Server getServer();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,68 +2,16 @@ package mc.protocol.di;
|
|||||||
|
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
import dagger.Provides;
|
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.NettyServer;
|
||||||
import mc.protocol.PacketInboundHandler;
|
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 javax.inject.Provider;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
public class ProtocolModule {
|
public class ProtocolModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
NettyServer provideServer(ServerBootstrap serverBootstrap) {
|
@ServerScope
|
||||||
return new NettyServer(serverBootstrap);
|
Server provideServer() {
|
||||||
|
return new NettyServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
ServerBootstrap provideServerBootstrap(ChannelInitializer<SocketChannel> channelChannelInitializer) {
|
|
||||||
ServerBootstrap bootstrap = new ServerBootstrap();
|
|
||||||
|
|
||||||
bootstrap.group(new NioEventLoopGroup(1), new NioEventLoopGroup())
|
|
||||||
.channel(NioServerSocketChannel.class)
|
|
||||||
.childHandler(channelChannelInitializer);
|
|
||||||
|
|
||||||
return bootstrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
ChannelInitializer<SocketChannel> provideChannelChannelInitializer(
|
|
||||||
Provider<Map<String, ChannelHandler>> channelHandlerMapProvider) {
|
|
||||||
|
|
||||||
return new ChannelInitializer<>() {
|
|
||||||
@Override
|
|
||||||
protected void initChannel(@Nonnull SocketChannel socketChannel) {
|
|
||||||
ChannelPipeline pipeline = socketChannel.pipeline();
|
|
||||||
channelHandlerMapProvider.get().forEach(pipeline::addLast);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
Map<String, ChannelHandler> provideChannelHandlerMap() {
|
|
||||||
Map<String, ChannelHandler> map = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
map.put("packet_splitter", new ProtocolSplitter());
|
|
||||||
map.put("logger", new LoggingHandler(LogLevel.DEBUG));
|
|
||||||
map.put("packet_decoder", new ProtocolDecoder(true));
|
|
||||||
map.put("packet_encoder", new ProtocolEncoder());
|
|
||||||
map.put("packet_handler", new PacketInboundHandler());
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,30 +5,36 @@ import io.netty.channel.ChannelHandlerContext;
|
|||||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import mc.protocol.NettyConnectionContext;
|
||||||
import mc.protocol.NetworkAttributes;
|
import mc.protocol.NetworkAttributes;
|
||||||
import mc.protocol.State;
|
import mc.protocol.State;
|
||||||
|
import mc.protocol.api.ConnectionContext;
|
||||||
import mc.protocol.io.NetByteBuf;
|
import mc.protocol.io.NetByteBuf;
|
||||||
import mc.protocol.packets.ClientSidePacket;
|
import mc.protocol.packets.ClientSidePacket;
|
||||||
import mc.protocol.packets.UnknownPacket;
|
import mc.protocol.packets.UnknownPacket;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ProtocolDecoder extends ByteToMessageDecoder {
|
public class ProtocolDecoder extends ByteToMessageDecoder {
|
||||||
|
|
||||||
private final boolean readUnknownPackets;
|
private final boolean readUnknownPackets;
|
||||||
|
private final Consumer<ConnectionContext<?>> consumerNewConnection;
|
||||||
|
private final Consumer<ConnectionContext<?>> consumerDisconnect;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
public void channelActive(@Nonnull ChannelHandlerContext ctx) throws Exception {
|
||||||
ctx.channel().attr(NetworkAttributes.STATE).set(State.HANDSHAKING);
|
consumerNewConnection.accept(new NettyConnectionContext<>(ctx, null));
|
||||||
super.channelActive(ctx);
|
super.channelActive(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
public void channelInactive(@Nonnull ChannelHandlerContext ctx) throws Exception {
|
||||||
ctx.channel().attr(NetworkAttributes.STATE).set(null);
|
consumerDisconnect.accept(new NettyConnectionContext<>(ctx, null));
|
||||||
super.channelInactive(ctx);
|
super.channelInactive(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,10 @@ import joptsimple.OptionParser;
|
|||||||
import joptsimple.OptionSet;
|
import joptsimple.OptionSet;
|
||||||
import joptsimple.util.PathConverter;
|
import joptsimple.util.PathConverter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import mc.protocol.NettyServer;
|
|
||||||
import mc.protocol.State;
|
import mc.protocol.State;
|
||||||
|
import mc.protocol.api.Server;
|
||||||
|
import mc.protocol.di.DaggerProtocolComponent;
|
||||||
|
import mc.protocol.di.ProtocolComponent;
|
||||||
import mc.protocol.packets.PingPacket;
|
import mc.protocol.packets.PingPacket;
|
||||||
import mc.protocol.packets.client.HandshakePacket;
|
import mc.protocol.packets.client.HandshakePacket;
|
||||||
import mc.protocol.packets.client.LoginStartPacket;
|
import mc.protocol.packets.client.LoginStartPacket;
|
||||||
@@ -38,6 +40,8 @@ public class Main {
|
|||||||
private void run(OptionSet optionSet) {
|
private void run(OptionSet optionSet) {
|
||||||
log.info("mc-project launch");
|
log.info("mc-project launch");
|
||||||
|
|
||||||
|
ProtocolComponent protocolComponent = DaggerProtocolComponent.create();
|
||||||
|
|
||||||
ConfigModule configModule = new ConfigModule((Path) optionSet.valueOf(CLI_CONFIG));
|
ConfigModule configModule = new ConfigModule((Path) optionSet.valueOf(CLI_CONFIG));
|
||||||
|
|
||||||
ServerComponent serverComponent = DaggerServerComponent.builder()
|
ServerComponent serverComponent = DaggerServerComponent.builder()
|
||||||
@@ -46,9 +50,12 @@ public class Main {
|
|||||||
|
|
||||||
Config config = serverComponent.getConfig();
|
Config config = serverComponent.getConfig();
|
||||||
|
|
||||||
NettyServer server = NettyServer.createServer();
|
Server server = protocolComponent.getServer();
|
||||||
PacketHandler packetHandler = serverComponent.getPacketHandler();
|
PacketHandler packetHandler = serverComponent.getPacketHandler();
|
||||||
|
|
||||||
|
server.onNewConnect(connectionContext -> connectionContext.setState(State.HANDSHAKING));
|
||||||
|
server.onDisonnect(connectionContext -> connectionContext.setState(null));
|
||||||
|
|
||||||
State.HANDSHAKING.packetFlux(HandshakePacket.class).subscribe(packetHandler::onHandshake);
|
State.HANDSHAKING.packetFlux(HandshakePacket.class).subscribe(packetHandler::onHandshake);
|
||||||
State.STATUS.packetFlux(PingPacket.class).subscribe(packetHandler::onKeepAlive);
|
State.STATUS.packetFlux(PingPacket.class).subscribe(packetHandler::onKeepAlive);
|
||||||
State.STATUS.packetFlux(StatusServerRequestPacket.class).subscribe(packetHandler::onServerStatus);
|
State.STATUS.packetFlux(StatusServerRequestPacket.class).subscribe(packetHandler::onServerStatus);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package mc.server;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import mc.protocol.*;
|
import mc.protocol.*;
|
||||||
|
import mc.protocol.api.ConnectionContext;
|
||||||
import mc.protocol.model.Location;
|
import mc.protocol.model.Location;
|
||||||
import mc.protocol.model.Look;
|
import mc.protocol.model.Look;
|
||||||
import mc.protocol.model.ServerInfo;
|
import mc.protocol.model.ServerInfo;
|
||||||
@@ -27,22 +28,23 @@ import java.util.UUID;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class PacketHandler {
|
public class PacketHandler {
|
||||||
|
|
||||||
private final Config config;
|
|
||||||
private final Random random = new Random(System.currentTimeMillis());
|
private final Random random = new Random(System.currentTimeMillis());
|
||||||
|
private final Config config;
|
||||||
|
|
||||||
public void onHandshake(ChannelContext<HandshakePacket> channel) {
|
public void onHandshake(ConnectionContext<HandshakePacket> context) {
|
||||||
channel.setState(channel.getPacket().getNextState());
|
context.setState(context.clientPacket().getNextState());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onKeepAlive(ChannelContext<PingPacket> channel) {
|
public void onKeepAlive(ConnectionContext<PingPacket> context) {
|
||||||
channel.getCtx().writeAndFlush(channel.getPacket()).channel().disconnect();
|
context.sendNow(context.clientPacket());
|
||||||
|
context.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onKeepAlivePlay(ChannelContext<PingPacket> channel) {
|
public void onKeepAlivePlay(ConnectionContext<PingPacket> context) {
|
||||||
channel.getCtx().writeAndFlush(channel.getPacket());
|
context.sendNow(context.clientPacket());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onServerStatus(ChannelContext<StatusServerRequestPacket> channel) {
|
public void onServerStatus(ConnectionContext<StatusServerRequestPacket> context) {
|
||||||
ServerInfo serverInfo = new ServerInfo();
|
ServerInfo serverInfo = new ServerInfo();
|
||||||
serverInfo.version().name(ProtocolConstant.PROTOCOL_NAME);
|
serverInfo.version().name(ProtocolConstant.PROTOCOL_NAME);
|
||||||
serverInfo.version().protocol(ProtocolConstant.PROTOCOL_NUMBER);
|
serverInfo.version().protocol(ProtocolConstant.PROTOCOL_NUMBER);
|
||||||
@@ -58,18 +60,18 @@ public class PacketHandler {
|
|||||||
StatusServerResponse response = new StatusServerResponse();
|
StatusServerResponse response = new StatusServerResponse();
|
||||||
response.setInfo(serverInfo);
|
response.setInfo(serverInfo);
|
||||||
|
|
||||||
channel.getCtx().writeAndFlush(response);
|
context.sendNow(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onLoginStart(ChannelContext<LoginStartPacket> channel) {
|
public void onLoginStart(ConnectionContext<LoginStartPacket> context) {
|
||||||
LoginStartPacket loginStartPacket = channel.getPacket();
|
LoginStartPacket loginStartPacket = context.clientPacket();
|
||||||
|
|
||||||
var loginSuccessPacket = new LoginSuccessPacket();
|
var loginSuccessPacket = new LoginSuccessPacket();
|
||||||
loginSuccessPacket.setUuid(UUID.randomUUID());
|
loginSuccessPacket.setUuid(UUID.randomUUID());
|
||||||
loginSuccessPacket.setName(loginStartPacket.getName());
|
loginSuccessPacket.setName(loginStartPacket.getName());
|
||||||
|
|
||||||
channel.getCtx().writeAndFlush(loginSuccessPacket);
|
context.sendNow(loginSuccessPacket);
|
||||||
channel.setState(State.PLAY);
|
context.setState(State.PLAY);
|
||||||
|
|
||||||
var joinGamePacket = new JoinGamePacket();
|
var joinGamePacket = new JoinGamePacket();
|
||||||
joinGamePacket.setEntityId(random.nextInt());
|
joinGamePacket.setEntityId(random.nextInt());
|
||||||
@@ -78,14 +80,14 @@ public class PacketHandler {
|
|||||||
joinGamePacket.setDifficulty(Difficulty.PEACEFUL);
|
joinGamePacket.setDifficulty(Difficulty.PEACEFUL);
|
||||||
joinGamePacket.setLevelType(LevelType.FLAT);
|
joinGamePacket.setLevelType(LevelType.FLAT);
|
||||||
|
|
||||||
channel.getCtx().write(joinGamePacket);
|
context.send(joinGamePacket);
|
||||||
|
|
||||||
Location spawnLocation = new Location(0d, 63d, 0d);
|
Location spawnLocation = new Location(0d, 63d, 0d);
|
||||||
|
|
||||||
var spawnPositionPacket = new SpawnPositionPacket();
|
var spawnPositionPacket = new SpawnPositionPacket();
|
||||||
spawnPositionPacket.setSpawn(spawnLocation);
|
spawnPositionPacket.setSpawn(spawnLocation);
|
||||||
|
|
||||||
channel.getCtx().write(spawnPositionPacket);
|
context.send(spawnPositionPacket);
|
||||||
|
|
||||||
var playerAbilitiesPacket = new PlayerAbilitiesPacket();
|
var playerAbilitiesPacket = new PlayerAbilitiesPacket();
|
||||||
playerAbilitiesPacket.setCatFly(true);
|
playerAbilitiesPacket.setCatFly(true);
|
||||||
@@ -95,29 +97,29 @@ public class PacketHandler {
|
|||||||
playerAbilitiesPacket.setFieldOfView(0.0f);
|
playerAbilitiesPacket.setFieldOfView(0.0f);
|
||||||
playerAbilitiesPacket.setFlyingSpeed(0.05f);
|
playerAbilitiesPacket.setFlyingSpeed(0.05f);
|
||||||
|
|
||||||
channel.getCtx().write(playerAbilitiesPacket);
|
context.send(playerAbilitiesPacket);
|
||||||
|
|
||||||
channel.getCtx().flush();
|
context.flushSending();
|
||||||
|
|
||||||
var chunkDataPacket = new ChunkDataPacket();
|
var chunkDataPacket = new ChunkDataPacket();
|
||||||
chunkDataPacket.setX(0);
|
chunkDataPacket.setX(0);
|
||||||
chunkDataPacket.setZ(0);
|
chunkDataPacket.setZ(0);
|
||||||
|
|
||||||
channel.getCtx().writeAndFlush(chunkDataPacket);
|
context.sendNow(chunkDataPacket);
|
||||||
|
|
||||||
var playerPositionAndLookPacket = new SPlayerPositionAndLookPacket();
|
var playerPositionAndLookPacket = new SPlayerPositionAndLookPacket();
|
||||||
playerPositionAndLookPacket.setPosition(spawnLocation);
|
playerPositionAndLookPacket.setPosition(spawnLocation);
|
||||||
playerPositionAndLookPacket.setLook(new Look(0f, 0f));
|
playerPositionAndLookPacket.setLook(new Look(0f, 0f));
|
||||||
playerPositionAndLookPacket.setTeleportId(random.nextInt());
|
playerPositionAndLookPacket.setTeleportId(random.nextInt());
|
||||||
|
|
||||||
channel.getCtx().write(playerPositionAndLookPacket);
|
context.send(playerPositionAndLookPacket);
|
||||||
|
|
||||||
PingPacket pingPacket = new PingPacket();
|
PingPacket pingPacket = new PingPacket();
|
||||||
pingPacket.setPayload(System.currentTimeMillis());
|
pingPacket.setPayload(System.currentTimeMillis());
|
||||||
|
|
||||||
channel.getCtx().write(pingPacket);
|
context.send(pingPacket);
|
||||||
|
|
||||||
channel.getCtx().flush();
|
context.flushSending();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String faviconToBase64(Path iconPath) {
|
private static String faviconToBase64(Path iconPath) {
|
||||||
|
|||||||
Reference in New Issue
Block a user