diff --git a/server/src/main/java/mc/server/Main.java b/server/src/main/java/mc/server/Main.java index c5f506e..61fd91d 100644 --- a/server/src/main/java/mc/server/Main.java +++ b/server/src/main/java/mc/server/Main.java @@ -8,15 +8,10 @@ import joptsimple.OptionSet; import joptsimple.util.PathConverter; import lombok.extern.slf4j.Slf4j; import mc.protocol.NettyServer; -import mc.protocol.ProtocolConstant; -import mc.protocol.model.ServerInfo; import mc.protocol.packets.PingPacket; import mc.protocol.packets.client.HandshakePacket; import mc.protocol.packets.client.LoginStartPacket; import mc.protocol.packets.client.StatusServerRequestPacket; -import mc.protocol.packets.server.DisconnectPacket; -import mc.protocol.packets.server.StatusServerResponse; -import mc.protocol.serializer.TextSerializer; import mc.server.config.Config; import mc.server.di.ConfigModule; import mc.server.di.DaggerServerComponent; @@ -30,8 +25,6 @@ import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Base64; -import java.util.Collections; import java.util.List; import java.util.Objects; @@ -53,44 +46,23 @@ public class Main { Config config = serverComponent.getConfig(); NettyServer server = NettyServer.createServer(); + PacketHandler packetHandler = serverComponent.getPacketHandler(); server.packetFlux(HandshakePacket.class) .doOnNext(channel -> log.info("{}", channel.getPacket())) - .subscribe(channel -> channel.setState(channel.getPacket().getNextState())); + .subscribe(packetHandler::onHandshake); server.packetFlux(PingPacket.class) .doOnNext(channel -> log.info("{}", channel.getPacket())) - .subscribe(channel -> channel.getCtx().writeAndFlush(channel.getPacket()).channel().disconnect()); + .subscribe(packetHandler::onKeepAlive); server.packetFlux(StatusServerRequestPacket.class) .doOnNext(channel -> log.info("{}", channel.getPacket())) - .subscribe(channel -> { - ServerInfo serverInfo = new ServerInfo(); - serverInfo.version().name(ProtocolConstant.PROTOCOL_NAME); - serverInfo.version().protocol(ProtocolConstant.PROTOCOL_NUMBER); - serverInfo.players().max(config.players().maxOnlile()); - serverInfo.players().online(config.players().onlile()); - serverInfo.players().sample(Collections.emptyList()); - serverInfo.description(TextSerializer.fromPlain(config.motd())); - - if (config.iconPath() != null) { - serverInfo.favicon(faviconToBase64(config.iconPath())); - } - - StatusServerResponse response = new StatusServerResponse(); - response.setInfo(serverInfo); - - channel.getCtx().writeAndFlush(response); - }); + .subscribe(packetHandler::onServerStatus); server.packetFlux(LoginStartPacket.class) .doOnNext(channel -> log.info("{}", channel.getPacket())) - .subscribe(channel -> { - DisconnectPacket disconnectPacket = new DisconnectPacket(); - disconnectPacket.setReason(TextSerializer.fromPlain(config.disconnectReason())); - - channel.getCtx().writeAndFlush(disconnectPacket).channel().disconnect(); - }); + .subscribe(packetHandler::onLoginStart); server.bind(config.server().host(), config.server().port()); } @@ -159,17 +131,6 @@ public class Main { return optionParser; } - private static String faviconToBase64(Path iconPath) { - try { - return "data:image/png;base64," + - Base64.getEncoder().encodeToString( - IOUtils.toByteArray(Files.newInputStream(iconPath))); - } catch (IOException e) { - log.error("Can't read icon '{}'", iconPath.toAbsolutePath(), e); - return ""; - } - } - private static boolean initializeCheckFiles(Path... paths) { for (Path path : paths) { if (Files.exists(path)) { diff --git a/server/src/main/java/mc/server/PacketHandler.java b/server/src/main/java/mc/server/PacketHandler.java new file mode 100644 index 0000000..b037ec1 --- /dev/null +++ b/server/src/main/java/mc/server/PacketHandler.java @@ -0,0 +1,74 @@ +package mc.server; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import mc.protocol.ChannelContext; +import mc.protocol.ProtocolConstant; +import mc.protocol.model.ServerInfo; +import mc.protocol.packets.PingPacket; +import mc.protocol.packets.client.HandshakePacket; +import mc.protocol.packets.client.LoginStartPacket; +import mc.protocol.packets.client.StatusServerRequestPacket; +import mc.protocol.packets.server.DisconnectPacket; +import mc.protocol.packets.server.StatusServerResponse; +import mc.protocol.serializer.TextSerializer; +import mc.server.config.Config; +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Base64; +import java.util.Collections; + +@Slf4j +@RequiredArgsConstructor +public class PacketHandler { + + private final Config config; + + public void onHandshake(ChannelContext channel) { + channel.setState(channel.getPacket().getNextState()); + } + + public void onKeepAlive(ChannelContext channel) { + channel.getCtx().writeAndFlush(channel.getPacket()).channel().disconnect(); + } + + public void onServerStatus(ChannelContext channel) { + ServerInfo serverInfo = new ServerInfo(); + serverInfo.version().name(ProtocolConstant.PROTOCOL_NAME); + serverInfo.version().protocol(ProtocolConstant.PROTOCOL_NUMBER); + serverInfo.players().max(config.players().maxOnlile()); + serverInfo.players().online(config.players().onlile()); + serverInfo.players().sample(Collections.emptyList()); + serverInfo.description(TextSerializer.fromPlain(config.motd())); + + if (config.iconPath() != null) { + serverInfo.favicon(faviconToBase64(config.iconPath())); + } + + StatusServerResponse response = new StatusServerResponse(); + response.setInfo(serverInfo); + + channel.getCtx().writeAndFlush(response); + } + + public void onLoginStart(ChannelContext channel) { + DisconnectPacket disconnectPacket = new DisconnectPacket(); + disconnectPacket.setReason(TextSerializer.fromPlain(config.disconnectReason())); + + channel.getCtx().writeAndFlush(disconnectPacket).channel().disconnect(); + } + + private static String faviconToBase64(Path iconPath) { + try { + return "data:image/png;base64," + + Base64.getEncoder().encodeToString( + IOUtils.toByteArray(Files.newInputStream(iconPath))); + } catch (IOException e) { + log.error("Can't read icon '{}'", iconPath.toAbsolutePath(), e); + return ""; + } + } +} diff --git a/server/src/main/java/mc/server/di/PacketHandlerModule.java b/server/src/main/java/mc/server/di/PacketHandlerModule.java new file mode 100644 index 0000000..d90f3a7 --- /dev/null +++ b/server/src/main/java/mc/server/di/PacketHandlerModule.java @@ -0,0 +1,15 @@ +package mc.server.di; + +import dagger.Module; +import dagger.Provides; +import mc.server.PacketHandler; +import mc.server.config.Config; + +@Module +public class PacketHandlerModule { + + @Provides + public PacketHandler providePacketHandler(Config config) { + return new PacketHandler(config); + } +} diff --git a/server/src/main/java/mc/server/di/ServerComponent.java b/server/src/main/java/mc/server/di/ServerComponent.java index 4147205..9b7ec2e 100644 --- a/server/src/main/java/mc/server/di/ServerComponent.java +++ b/server/src/main/java/mc/server/di/ServerComponent.java @@ -1,10 +1,14 @@ package mc.server.di; import dagger.Component; +import mc.server.PacketHandler; import mc.server.config.Config; -@Component(modules = ConfigModule.class) +@Component(modules = { + ConfigModule.class, PacketHandlerModule.class +}) public interface ServerComponent { Config getConfig(); + PacketHandler getPacketHandler(); }