From 8a72e1a13159200a40fef097d96447fd3131e7f8 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Sun, 8 Apr 2018 13:35:04 +0300 Subject: [PATCH 1/9] Hello, Spring! --- pom.xml | 116 ++++++++++++++++++++++++++++++++ src/main/java/mc/core/Main.java | 14 ++++ src/main/resources/log4j2.xml | 13 ++++ src/main/resources/spring.xml | 5 ++ 4 files changed, 148 insertions(+) create mode 100644 pom.xml create mode 100644 src/main/java/mc/core/Main.java create mode 100644 src/main/resources/log4j2.xml create mode 100644 src/main/resources/spring.xml diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..9822425 --- /dev/null +++ b/pom.xml @@ -0,0 +1,116 @@ + + + 4.0.0 + MC Core + + mc + core + 1.0-SNAPSHOT + + + UTF-8 + 1.8 + 1.7.21 + 2.5 + 4.2.5.RELEASE + + + + + + org.slf4j + slf4j-api + ${slf4j.version} + + + org.slf4j + jcl-over-slf4j + ${slf4j.version} + + + org.apache.logging.log4j + log4j-core + ${log4j.version} + + + org.apache.logging.log4j + log4j-slf4j-impl + ${log4j.version} + + + + + org.springframework + spring-context + ${spring.version} + + + commons-logging + commons-logging + + + + + + + org.projectlombok + lombok + 1.16.16 + + + + + ${project.artifactId}-${project.version} + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + ${java.version} + ${java.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.15 + + -Dfile.encoding=${project.build.sourceEncoding} + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + + true + dependency/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.8 + + + copy-dependencies + package + + copy-dependencies + + + + + + + + \ No newline at end of file diff --git a/src/main/java/mc/core/Main.java b/src/main/java/mc/core/Main.java new file mode 100644 index 0000000..19d18dc --- /dev/null +++ b/src/main/java/mc/core/Main.java @@ -0,0 +1,14 @@ +/* + * DmitriyMX + * 2018-04-08 + */ +package mc.core; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class Main { + public static void main(String[] args) { + ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); + } +} diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml new file mode 100644 index 0000000..2da8a36 --- /dev/null +++ b/src/main/resources/log4j2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/spring.xml b/src/main/resources/spring.xml new file mode 100644 index 0000000..60dc04d --- /dev/null +++ b/src/main/resources/spring.xml @@ -0,0 +1,5 @@ + + + \ No newline at end of file From ef3e158c8fc2834324ba1d724ba1a7ff7c100641 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Sun, 8 Apr 2018 13:35:50 +0300 Subject: [PATCH 2/9] Config --- pom.xml | 5 +++ src/main/java/mc/core/Config.java | 11 ++++++ src/main/java/mc/core/Main.java | 7 ++++ .../mc/core/embedded/ConfigFromSpring.java | 37 ++++++++++++++++++ src/main/resources/icon.png | Bin 0 -> 1675 bytes src/main/resources/spring.xml | 5 +++ 6 files changed, 65 insertions(+) create mode 100644 src/main/java/mc/core/Config.java create mode 100644 src/main/java/mc/core/embedded/ConfigFromSpring.java create mode 100644 src/main/resources/icon.png diff --git a/pom.xml b/pom.xml index 9822425..1e5e435 100644 --- a/pom.xml +++ b/pom.xml @@ -59,6 +59,11 @@ lombok 1.16.16 + + commons-io + commons-io + 2.6 + diff --git a/src/main/java/mc/core/Config.java b/src/main/java/mc/core/Config.java new file mode 100644 index 0000000..a772dd1 --- /dev/null +++ b/src/main/java/mc/core/Config.java @@ -0,0 +1,11 @@ +/* + * DmitriyMX + * 2018-04-08 + */ +package mc.core; + +public interface Config { + int getMaxPlayers(); + String getDescriptionServer(); + String getFaviconBase64(); +} diff --git a/src/main/java/mc/core/Main.java b/src/main/java/mc/core/Main.java index 19d18dc..6d4275f 100644 --- a/src/main/java/mc/core/Main.java +++ b/src/main/java/mc/core/Main.java @@ -4,11 +4,18 @@ */ package mc.core; +import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; +@Slf4j public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); + Config config = context.getBean("config", Config.class); + + log.info("Description: {}", config.getDescriptionServer()); + log.info("Max online: {}", config.getMaxPlayers()); + log.info("Favicon (base64): {}", config.getFaviconBase64()); } } diff --git a/src/main/java/mc/core/embedded/ConfigFromSpring.java b/src/main/java/mc/core/embedded/ConfigFromSpring.java new file mode 100644 index 0000000..5c4841e --- /dev/null +++ b/src/main/java/mc/core/embedded/ConfigFromSpring.java @@ -0,0 +1,37 @@ +/* + * DmitriyMX + * 2018-04-08 + */ +package mc.core.embedded; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import mc.core.Config; +import org.apache.commons.io.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.util.Base64; + +@Slf4j +@Getter +public class ConfigFromSpring implements Config { + private String descriptionServer; + private String faviconBase64; + private int maxPlayers; + + public ConfigFromSpring(String descriptionServer, int maxPlayers, File faviconImageFile) { + this.descriptionServer = descriptionServer; + this.maxPlayers = maxPlayers; + try { + faviconBase64 = new String( + Base64.getEncoder().encode( + FileUtils.readFileToByteArray(faviconImageFile) + ) + ); + } catch (IOException e) { + log.warn("Con't load favicon", e); + faviconBase64 = null; + } + } +} diff --git a/src/main/resources/icon.png b/src/main/resources/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d512fc5472e1d4b4573ba22b5e3e71587dbd4c9f GIT binary patch literal 1675 zcmV;626Xv}P)09zrl&^1WzcGf>6{pC7KKEp~p(7 zm8$R+BqT&YDrzr1B0?|WNG@&Q)Kgp3N=;EK4kUb5;xDLFQ7H?^5{eKeBm_fnt9);4 z_pn}j*IwH*J2STPlPs-g-^_dS+u4~n@6BpcQ&VUHf&eZ8_=ZvbTL2dT7&48Zlvb7b zWGbk@IDkU&w+{BsqbR#>t3NK?x*}u~Fo3erLlWB^vb8%Pv0Z5doP}xJElKUw!>yvO zvoabJC13)kF_$IS!i&pA-4h~>1O)0youCA81SSzd02{oOy^Me#(LSBG!vOFzZzbLl zunv>ycEuMkC(ICQ1s(zlywz-H;Z9ZWW}5U?3LZ=s>>jR;tiWJoJf zw-5CQ_z4`7NgE>svoEgDYHWu5;9OG&Pkzm3mLSdy4dU>?XFOGcl+vm`)fxfZ4n-@F z$z)&{%r1$mpxZKd-HS2Xdx)26p7GAxI{*OLY!-<`0>NNo_e9tA>y*+#dzl*nM@0Kttz#*yDvK`y0*UpH(X>rVM`=}ojZD5?-?68 zq@O*oAGpUcqZTpe|NcS26u0jodJ?uL0i9_bW z_df{fuSbHe>%US;Pg?}Y3}8Ai{Ui;auiD@8`Fxm}eSv&FkFG=6uy3{yxxs?>ov>&iFj2AYnKF#@HDT^oJ?v4^y(6l?EFLn)FF< z&!Nv9|DWEx>pGj;p?VT@gGGXL0-oNyTUFMI4zfaJc6d`jsUOhyZg1&2^>`W|b_B3J z}SADsBhDam=pu7tF21QY! zHr^DC17%nElnM=gpO5)x_XJfV6bgY-dKysd2jm)r!diuRyu3TL6L1uQXYSnKkAz*z zbE|8JMz;b0mX}xHM*(49<594blX76Clq0kgpu}Cvt*)Ub*hj@Jf9O$#f;+9AFM2|wG0Lza89UDD8SgLuKs%Ajn^iH5Dtfd8VR6U1mpl*0q`ZO zlA{L?a2qCqcs#}|8;ixRpvD8Obxh8}8aU1hGM>^mZY^%KS8vW6cX}DiT;b5AY>MG;n+=(kc=NAqF@e7;k1M1aoy@HHNc! z?+Ay(AcXt^&I8_FQe$6%<4{F2NFanD7K;S|oZ+qOH8;2cbC@xmD^^7UAq0ew>qT2U zIc}oK(PKsB=NbvhBq5nhf)H}9sQZ{mTe7mlmth)nu%3_z387HPdg6yPGkzxJV@=uV z@!K$o&;VR@6W}4Cv$NCc^woGgZnZ1*^IVlN!6B3*%|V!lvCacbBzy;81Wour^M8T$ Vqx`lI%8LL1002ovPDHLkV1m=#{XPHy literal 0 HcmV?d00001 diff --git a/src/main/resources/spring.xml b/src/main/resources/spring.xml index 60dc04d..d71d9fa 100644 --- a/src/main/resources/spring.xml +++ b/src/main/resources/spring.xml @@ -2,4 +2,9 @@ + + + + + \ No newline at end of file From 5fc94d0ab0de5d68602ea530048cbe9c0b2101d0 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Sun, 8 Apr 2018 16:37:16 +0300 Subject: [PATCH 3/9] simple server --- pom.xml | 8 +++ src/main/java/mc/core/Config.java | 2 + src/main/java/mc/core/Main.java | 9 ++-- src/main/java/mc/core/Server.java | 9 ++++ .../java/mc/core/StartServerException.java | 11 ++++ .../mc/core/embedded/ConfigFromSpring.java | 14 +++-- src/main/java/mc/core/netty/NettyServer.java | 54 +++++++++++++++++++ src/main/resources/spring.xml | 10 ++-- 8 files changed, 107 insertions(+), 10 deletions(-) create mode 100644 src/main/java/mc/core/Server.java create mode 100644 src/main/java/mc/core/StartServerException.java create mode 100644 src/main/java/mc/core/netty/NettyServer.java diff --git a/pom.xml b/pom.xml index 1e5e435..768b838 100644 --- a/pom.xml +++ b/pom.xml @@ -15,6 +15,7 @@ 1.7.21 2.5 4.2.5.RELEASE + 4.1.22.Final @@ -53,6 +54,13 @@ + + + io.netty + netty-all + ${netty.version} + + org.projectlombok diff --git a/src/main/java/mc/core/Config.java b/src/main/java/mc/core/Config.java index a772dd1..08b4969 100644 --- a/src/main/java/mc/core/Config.java +++ b/src/main/java/mc/core/Config.java @@ -8,4 +8,6 @@ public interface Config { int getMaxPlayers(); String getDescriptionServer(); String getFaviconBase64(); + String getHost(); + int getPort(); } diff --git a/src/main/java/mc/core/Main.java b/src/main/java/mc/core/Main.java index 6d4275f..f079a2a 100644 --- a/src/main/java/mc/core/Main.java +++ b/src/main/java/mc/core/Main.java @@ -14,8 +14,11 @@ public class Main { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Config config = context.getBean("config", Config.class); - log.info("Description: {}", config.getDescriptionServer()); - log.info("Max online: {}", config.getMaxPlayers()); - log.info("Favicon (base64): {}", config.getFaviconBase64()); + Server server = context.getBean("server", Server.class); + try { + server.start(config.getHost(), config.getPort()); + } catch (StartServerException e) { + log.error("Can't start server", e); + } } } diff --git a/src/main/java/mc/core/Server.java b/src/main/java/mc/core/Server.java new file mode 100644 index 0000000..eefcb65 --- /dev/null +++ b/src/main/java/mc/core/Server.java @@ -0,0 +1,9 @@ +/* + * DmitriyMX + * 2018-04-08 + */ +package mc.core; + +public interface Server { + void start(String host, int port) throws StartServerException; +} diff --git a/src/main/java/mc/core/StartServerException.java b/src/main/java/mc/core/StartServerException.java new file mode 100644 index 0000000..2cd4cbd --- /dev/null +++ b/src/main/java/mc/core/StartServerException.java @@ -0,0 +1,11 @@ +/* + * DmitriyMX + * 2018-04-08 + */ +package mc.core; + +public class StartServerException extends Exception { + public StartServerException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/mc/core/embedded/ConfigFromSpring.java b/src/main/java/mc/core/embedded/ConfigFromSpring.java index 5c4841e..d5cc215 100644 --- a/src/main/java/mc/core/embedded/ConfigFromSpring.java +++ b/src/main/java/mc/core/embedded/ConfigFromSpring.java @@ -5,6 +5,7 @@ package mc.core.embedded; import lombok.Getter; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import mc.core.Config; import org.apache.commons.io.FileUtils; @@ -16,13 +17,18 @@ import java.util.Base64; @Slf4j @Getter public class ConfigFromSpring implements Config { + @Setter private String descriptionServer; private String faviconBase64; + @Setter private int maxPlayers; + @Setter + private String host; + @Setter + private int port; - public ConfigFromSpring(String descriptionServer, int maxPlayers, File faviconImageFile) { - this.descriptionServer = descriptionServer; - this.maxPlayers = maxPlayers; + public void setFaviconBase64(File faviconImageFile) { + log.debug("faviconImageFile: {}", faviconImageFile.getAbsolutePath()); try { faviconBase64 = new String( Base64.getEncoder().encode( @@ -30,7 +36,7 @@ public class ConfigFromSpring implements Config { ) ); } catch (IOException e) { - log.warn("Con't load favicon", e); + log.warn("Can't load favicon", e); faviconBase64 = null; } } diff --git a/src/main/java/mc/core/netty/NettyServer.java b/src/main/java/mc/core/netty/NettyServer.java new file mode 100644 index 0000000..730eb90 --- /dev/null +++ b/src/main/java/mc/core/netty/NettyServer.java @@ -0,0 +1,54 @@ +/* + * DmitriyMX + * 2018-04-08 + */ +package mc.core.netty; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.logging.LoggingHandler; +import mc.core.Server; +import mc.core.StartServerException; + +public class NettyServer implements Server{ + private EventLoopGroup bossGroup, workerGroup; + + private ChannelInitializer buildChannelInitializer() { + return new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel socketChannel) { + socketChannel.pipeline().addLast( + new LoggingHandler() + ); + } + }; + } + + private ServerBootstrap buildServerBootstrap() { + ServerBootstrap bootstrap = new ServerBootstrap(); + + bootstrap.group(bossGroup, workerGroup) + .channel(NioServerSocketChannel.class) + .childHandler(buildChannelInitializer()); + + return bootstrap; + } + + @Override + public void start(String host, int port) throws StartServerException { + bossGroup = new NioEventLoopGroup(1); + workerGroup = new NioEventLoopGroup(); + + ServerBootstrap serverBootstrap = buildServerBootstrap(); + + try { + serverBootstrap.bind(host, port).sync().channel().closeFuture().sync(); + } catch (InterruptedException e) { + throw new StartServerException(e); + } + } +} diff --git a/src/main/resources/spring.xml b/src/main/resources/spring.xml index d71d9fa..e435841 100644 --- a/src/main/resources/spring.xml +++ b/src/main/resources/spring.xml @@ -3,8 +3,12 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> - - - + + + + + + + \ No newline at end of file From 9602e6afc5979171b18d4911ab20c32d5e1b2c77 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Sun, 8 Apr 2018 18:08:36 +0300 Subject: [PATCH 4/9] raw packet --- src/main/java/mc/core/CSPacket.java | 8 +++ src/main/java/mc/core/netty/NettyServer.java | 4 +- .../java/mc/core/netty/PacketDecoder.java | 71 +++++++++++++++++++ .../java/mc/core/netty/PacketHandler.java | 18 +++++ .../java/mc/core/netty/packets/RawPacket.java | 17 +++++ 5 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 src/main/java/mc/core/CSPacket.java create mode 100644 src/main/java/mc/core/netty/PacketDecoder.java create mode 100644 src/main/java/mc/core/netty/PacketHandler.java create mode 100644 src/main/java/mc/core/netty/packets/RawPacket.java diff --git a/src/main/java/mc/core/CSPacket.java b/src/main/java/mc/core/CSPacket.java new file mode 100644 index 0000000..45394cb --- /dev/null +++ b/src/main/java/mc/core/CSPacket.java @@ -0,0 +1,8 @@ +/* + * DmitriyMX + * 2018-04-08 + */ +package mc.core; + +public interface CSPacket { +} diff --git a/src/main/java/mc/core/netty/NettyServer.java b/src/main/java/mc/core/netty/NettyServer.java index 730eb90..edba79c 100644 --- a/src/main/java/mc/core/netty/NettyServer.java +++ b/src/main/java/mc/core/netty/NettyServer.java @@ -22,7 +22,9 @@ public class NettyServer implements Server{ @Override protected void initChannel(SocketChannel socketChannel) { socketChannel.pipeline().addLast( - new LoggingHandler() + new LoggingHandler(), + new PacketDecoder(), + new PacketHandler() ); } }; diff --git a/src/main/java/mc/core/netty/PacketDecoder.java b/src/main/java/mc/core/netty/PacketDecoder.java new file mode 100644 index 0000000..0da59da --- /dev/null +++ b/src/main/java/mc/core/netty/PacketDecoder.java @@ -0,0 +1,71 @@ +/* + * DmitriyMX + * 2018-04-08 + */ +package mc.core.netty; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageDecoder; +import lombok.extern.slf4j.Slf4j; +import mc.core.netty.packets.RawPacket; + +import java.util.List; + +@Slf4j +public class PacketDecoder extends ByteToMessageDecoder { + private int readVarInt(ByteBuf byteBuf) throws Exception { + int result = 0; + byte read; + byte numRead = 0; + + do { + read = byteBuf.readByte(); + int value = (read & 0b01111111); + result |= (value << (7 * numRead)); + + numRead++; + if (numRead > 5) + throw new Exception("VarInt is too big"); + } while ((read & 0b10000000) != 0); + + return result; + } + + private int sizeVarInt(final int value) { + byte size = 0; + int v = value; + + do { + v >>>= 7; + size++; + } while (v != 0); + + return size; + } + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + log.debug("ByteBuf readableBytes: {}", in.readableBytes()); + + int size = readVarInt(in); + log.debug("Pkt-Size: {}", size); + int id = readVarInt(in); + log.debug("Pkt-Id: {}", id); + + byte[] rawData; + if (size > in.readableBytes()) { + rawData = new byte[in.readableBytes()]; + } else { + rawData = new byte[size - sizeVarInt(id)]; + } + in.readBytes(rawData); + + RawPacket packet = new RawPacket(); + packet.setRawData(rawData); + out.add(packet); + + log.debug("ByteBuf readableBytes: {}", in.readableBytes()); + in.skipBytes(in.readableBytes()); + } +} diff --git a/src/main/java/mc/core/netty/PacketHandler.java b/src/main/java/mc/core/netty/PacketHandler.java new file mode 100644 index 0000000..5a1305f --- /dev/null +++ b/src/main/java/mc/core/netty/PacketHandler.java @@ -0,0 +1,18 @@ +/* + * DmitriyMX + * 2018-04-08 + */ +package mc.core.netty; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import lombok.extern.slf4j.Slf4j; +import mc.core.CSPacket; + +@Slf4j +public class PacketHandler extends SimpleChannelInboundHandler { + @Override + protected void channelRead0(ChannelHandlerContext ctx, CSPacket packet) throws Exception { + log.info("{}: {}", packet.getClass().getSimpleName(), packet.toString()); + } +} diff --git a/src/main/java/mc/core/netty/packets/RawPacket.java b/src/main/java/mc/core/netty/packets/RawPacket.java new file mode 100644 index 0000000..f8d1560 --- /dev/null +++ b/src/main/java/mc/core/netty/packets/RawPacket.java @@ -0,0 +1,17 @@ +/* + * DmitriyMX + * 2018-04-08 + */ +package mc.core.netty.packets; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import mc.core.CSPacket; + +@ToString +public class RawPacket implements CSPacket { + @Getter + @Setter + private byte[] rawData; +} From 6d090217b71265bee4420dd4835f54a879d24cd3 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Sun, 8 Apr 2018 21:03:47 +0300 Subject: [PATCH 5/9] Status request --- pom.xml | 5 ++ src/main/java/mc/core/CSPacket.java | 2 + src/main/java/mc/core/NetStream.java | 57 ++++++++++++++ .../java/mc/core/netty/PacketDecoder.java | 74 +++++++++---------- .../java/mc/core/netty/PacketHandler.java | 23 +++++- src/main/java/mc/core/netty/State.java | 40 ++++++++++ .../java/mc/core/netty/WrapperNetStream.java | 29 ++++++++ .../mc/core/netty/packets/StatusRequest.java | 38 ++++++++++ 8 files changed, 229 insertions(+), 39 deletions(-) create mode 100644 src/main/java/mc/core/NetStream.java create mode 100644 src/main/java/mc/core/netty/State.java create mode 100644 src/main/java/mc/core/netty/WrapperNetStream.java create mode 100644 src/main/java/mc/core/netty/packets/StatusRequest.java diff --git a/pom.xml b/pom.xml index 768b838..b5e43b8 100644 --- a/pom.xml +++ b/pom.xml @@ -72,6 +72,11 @@ commons-io 2.6 + + com.google.guava + guava + 24.1-jre + diff --git a/src/main/java/mc/core/CSPacket.java b/src/main/java/mc/core/CSPacket.java index 45394cb..319ba81 100644 --- a/src/main/java/mc/core/CSPacket.java +++ b/src/main/java/mc/core/CSPacket.java @@ -5,4 +5,6 @@ package mc.core; public interface CSPacket { + default void readSelf(NetStream netStream) { + } } diff --git a/src/main/java/mc/core/NetStream.java b/src/main/java/mc/core/NetStream.java new file mode 100644 index 0000000..898e5cb --- /dev/null +++ b/src/main/java/mc/core/NetStream.java @@ -0,0 +1,57 @@ +/* + * DmitriyMX + * 2018-04-08 + */ +package mc.core; + +import lombok.extern.slf4j.Slf4j; + +import java.nio.charset.StandardCharsets; + +@Slf4j +public abstract class NetStream { + public static int sizeVarInt(final int value) { + byte size = 0; + int v = value; + + do { + v >>>= 7; + size++; + } while (v != 0); + + return size; + } + + public int readVarInt() { + int result = 0; + byte read; + byte numRead = 0; + + do { + read = readByte(); + int value = (read & 0b01111111); + result |= (value << (7 * numRead)); + + numRead++; + if (numRead > 5) { + log.debug("VarInt is too big!"); + break; + } + } while ((read & 0b10000000) != 0); + + return result; + } + + public String readString() { + int length = readVarInt(); + + byte[] buffer = new byte[length]; + readBytes(buffer); + + return new String(buffer, StandardCharsets.UTF_8); + } + + public abstract byte readByte(); + public abstract void readBytes(byte[] buffer); + public abstract int readUnsignedShort(); +} diff --git a/src/main/java/mc/core/netty/PacketDecoder.java b/src/main/java/mc/core/netty/PacketDecoder.java index 0da59da..6e83d75 100644 --- a/src/main/java/mc/core/netty/PacketDecoder.java +++ b/src/main/java/mc/core/netty/PacketDecoder.java @@ -8,62 +8,60 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; import lombok.extern.slf4j.Slf4j; +import mc.core.CSPacket; +import mc.core.NetStream; import mc.core.netty.packets.RawPacket; import java.util.List; @Slf4j public class PacketDecoder extends ByteToMessageDecoder { - private int readVarInt(ByteBuf byteBuf) throws Exception { - int result = 0; - byte read; - byte numRead = 0; - - do { - read = byteBuf.readByte(); - int value = (read & 0b01111111); - result |= (value << (7 * numRead)); - - numRead++; - if (numRead > 5) - throw new Exception("VarInt is too big"); - } while ((read & 0b10000000) != 0); - - return result; + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + ctx.channel().attr(State.ATTR_STATE).set(State.STATUS); + ctx.fireChannelActive(); } - private int sizeVarInt(final int value) { - byte size = 0; - int v = value; - - do { - v >>>= 7; - size++; - } while (v != 0); - - return size; + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + ctx.channel().attr(State.ATTR_STATE).set(null); + ctx.fireChannelInactive(); } @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + State state = ctx.channel().attr(State.ATTR_STATE).get(); + NetStream netStream = new WrapperNetStream(in); + log.debug("ByteBuf readableBytes: {}", in.readableBytes()); - int size = readVarInt(in); + int size = netStream.readVarInt(); log.debug("Pkt-Size: {}", size); - int id = readVarInt(in); + int id = netStream.readVarInt(); log.debug("Pkt-Id: {}", id); - byte[] rawData; - if (size > in.readableBytes()) { - rawData = new byte[in.readableBytes()]; - } else { - rawData = new byte[size - sizeVarInt(id)]; - } - in.readBytes(rawData); + Class clientSidePacketClass = state.getClientSidePacket(id); + if (clientSidePacketClass == null) { + log.warn("Unknown packet: {}:{}", state.name(), id); - RawPacket packet = new RawPacket(); - packet.setRawData(rawData); - out.add(packet); + if (log.isDebugEnabled()) { + byte[] rawData; + if (size > in.readableBytes()) { + rawData = new byte[in.readableBytes()]; + } else { + rawData = new byte[size - NetStream.sizeVarInt(id)]; + } + in.readBytes(rawData); + + RawPacket packet = new RawPacket(); + packet.setRawData(rawData); + out.add(packet); + } + } else { + CSPacket packet = clientSidePacketClass.newInstance(); + packet.readSelf(netStream); + out.add(packet); + } log.debug("ByteBuf readableBytes: {}", in.readableBytes()); in.skipBytes(in.readableBytes()); diff --git a/src/main/java/mc/core/netty/PacketHandler.java b/src/main/java/mc/core/netty/PacketHandler.java index 5a1305f..5458007 100644 --- a/src/main/java/mc/core/netty/PacketHandler.java +++ b/src/main/java/mc/core/netty/PacketHandler.java @@ -8,11 +8,32 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import lombok.extern.slf4j.Slf4j; import mc.core.CSPacket; +import mc.core.netty.packets.StatusRequest; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Optional; @Slf4j public class PacketHandler extends SimpleChannelInboundHandler { @Override protected void channelRead0(ChannelHandlerContext ctx, CSPacket packet) throws Exception { - log.info("{}: {}", packet.getClass().getSimpleName(), packet.toString()); + log.debug("{}: {}", packet.getClass().getSimpleName(), packet.toString()); + + Optional optionalMethod = Arrays.stream(this.getClass().getDeclaredMethods()) + .filter(method -> method.getName().equals("on" + packet.getClass().getSimpleName()) + && method.getParameterCount() == 2 + && method.getParameterTypes()[0].isAssignableFrom(ctx.getClass()) + && method.getParameterTypes()[1].isAssignableFrom(packet.getClass())) + .findFirst(); + + if (optionalMethod.isPresent()) { + Method method = optionalMethod.get(); + method.invoke(this, ctx, packet); + } + } + + public void onStatusRequest(ChannelHandlerContext ctx, StatusRequest packet) { + log.info("Catch!"); } } diff --git a/src/main/java/mc/core/netty/State.java b/src/main/java/mc/core/netty/State.java new file mode 100644 index 0000000..d118d5c --- /dev/null +++ b/src/main/java/mc/core/netty/State.java @@ -0,0 +1,40 @@ +/* + * DmitriyMX + * 2018-04-08 + */ +package mc.core.netty; + +import com.google.common.collect.ImmutableMap; +import io.netty.util.AttributeKey; +import lombok.RequiredArgsConstructor; +import mc.core.CSPacket; +import mc.core.netty.packets.StatusRequest; + +import java.util.Arrays; +import java.util.Map; +import java.util.Optional; + +@RequiredArgsConstructor +public enum State { + UNKNOWN(0, ImmutableMap.of()), + STATUS(1, ImmutableMap.of( + 0, StatusRequest.class + )); + + public static final AttributeKey ATTR_STATE = AttributeKey.newInstance("ATTR_STATE"); + + public static State getStateById(final int id) { + Optional optionalState = Arrays.stream(State.values()) + .filter(state -> state.id == id) + .findFirst(); + + return optionalState.orElse(UNKNOWN); + } + + private final int id; + private final Map> clientSidePackets; + + public Class getClientSidePacket(final int packetId) { + return clientSidePackets.get(packetId); + } +} diff --git a/src/main/java/mc/core/netty/WrapperNetStream.java b/src/main/java/mc/core/netty/WrapperNetStream.java new file mode 100644 index 0000000..e69b067 --- /dev/null +++ b/src/main/java/mc/core/netty/WrapperNetStream.java @@ -0,0 +1,29 @@ +/* + * DmitriyMX + * 2018-04-08 + */ +package mc.core.netty; + +import io.netty.buffer.ByteBuf; +import lombok.RequiredArgsConstructor; +import mc.core.NetStream; + +@RequiredArgsConstructor +public class WrapperNetStream extends NetStream { + private final ByteBuf byteBuf; + + @Override + public byte readByte() { + return byteBuf.readByte(); + } + + @Override + public void readBytes(byte[] buffer) { + byteBuf.readBytes(buffer); + } + + @Override + public int readUnsignedShort() { + return byteBuf.readUnsignedShort(); + } +} diff --git a/src/main/java/mc/core/netty/packets/StatusRequest.java b/src/main/java/mc/core/netty/packets/StatusRequest.java new file mode 100644 index 0000000..305b33d --- /dev/null +++ b/src/main/java/mc/core/netty/packets/StatusRequest.java @@ -0,0 +1,38 @@ +/* + * DmitriyMX + * 2018-04-08 + */ +package mc.core.netty.packets; + +import lombok.Getter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; +import mc.core.CSPacket; +import mc.core.NetStream; +import mc.core.netty.State; + +@Slf4j +@Getter +@ToString +public class StatusRequest implements CSPacket { + private int protocolVersion; + private String serverAddress; + private int serverPort; + private State nextState; + + @Override + public void readSelf(NetStream netStream) { + protocolVersion = netStream.readVarInt(); + serverAddress = netStream.readString(); + serverPort = netStream.readUnsignedShort(); + + int nextStateId = netStream.readVarInt(); + State state = State.getStateById(nextStateId); + if (state != null) { + nextState = state; + } else { + log.warn("Unknown state ({})!", nextStateId); + nextState = State.UNKNOWN; + } + } +} From d6b7647fc97eab13dcfe4e2e8b4408b29d58b3f6 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Sun, 8 Apr 2018 23:45:23 +0300 Subject: [PATCH 6/9] Status response --- pom.xml | 5 ++ .../mc/core/ByteArrayOutputNetStream.java | 40 +++++++++++++ src/main/java/mc/core/Config.java | 2 +- src/main/java/mc/core/Main.java | 10 ++-- src/main/java/mc/core/NetStream.java | 20 +++++++ src/main/java/mc/core/SCPacket.java | 9 +++ .../mc/core/embedded/ConfigFromSpring.java | 8 +-- src/main/java/mc/core/netty/NettyServer.java | 3 +- .../java/mc/core/netty/PacketEncoder.java | 32 +++++++++++ .../java/mc/core/netty/PacketHandler.java | 23 ++++++-- src/main/java/mc/core/netty/State.java | 17 +++++- .../java/mc/core/netty/WrapperNetStream.java | 10 ++++ .../mc/core/netty/packets/StatusResponse.java | 56 +++++++++++++++++++ 13 files changed, 217 insertions(+), 18 deletions(-) create mode 100644 src/main/java/mc/core/ByteArrayOutputNetStream.java create mode 100644 src/main/java/mc/core/SCPacket.java create mode 100644 src/main/java/mc/core/netty/PacketEncoder.java create mode 100644 src/main/java/mc/core/netty/packets/StatusResponse.java diff --git a/pom.xml b/pom.xml index b5e43b8..3864046 100644 --- a/pom.xml +++ b/pom.xml @@ -77,6 +77,11 @@ guava 24.1-jre + + com.google.code.gson + gson + 2.8.2 + diff --git a/src/main/java/mc/core/ByteArrayOutputNetStream.java b/src/main/java/mc/core/ByteArrayOutputNetStream.java new file mode 100644 index 0000000..03e2902 --- /dev/null +++ b/src/main/java/mc/core/ByteArrayOutputNetStream.java @@ -0,0 +1,40 @@ +/* + * DmitriyMX + * 2018-04-08 + */ +package mc.core; + +import java.io.ByteArrayOutputStream; + +public class ByteArrayOutputNetStream extends NetStream { + private ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + @Override + public byte readByte() { + throw new UnsupportedOperationException(); + } + + @Override + public void readBytes(byte[] buffer) { + throw new UnsupportedOperationException(); + } + + @Override + public int readUnsignedShort() { + throw new UnsupportedOperationException(); + } + + @Override + public void writeByte(int value) { + baos.write(value); + } + + @Override + public void writeBytes(byte[] buffer) { + baos.write(buffer, 0, buffer.length); + } + + public byte[] toByteArray() { + return baos.toByteArray(); + } +} diff --git a/src/main/java/mc/core/Config.java b/src/main/java/mc/core/Config.java index 08b4969..247c2e0 100644 --- a/src/main/java/mc/core/Config.java +++ b/src/main/java/mc/core/Config.java @@ -7,7 +7,7 @@ package mc.core; public interface Config { int getMaxPlayers(); String getDescriptionServer(); - String getFaviconBase64(); + byte[] getFaviconBase64(); String getHost(); int getPort(); } diff --git a/src/main/java/mc/core/Main.java b/src/main/java/mc/core/Main.java index f079a2a..4385a32 100644 --- a/src/main/java/mc/core/Main.java +++ b/src/main/java/mc/core/Main.java @@ -10,11 +10,13 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; @Slf4j public class Main { - public static void main(String[] args) { - ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); - Config config = context.getBean("config", Config.class); + public static ApplicationContext appContext; //FIXME - Server server = context.getBean("server", Server.class); + public static void main(String[] args) { + appContext = new ClassPathXmlApplicationContext("spring.xml"); + Config config = appContext.getBean("config", Config.class); + + Server server = appContext.getBean("server", Server.class); try { server.start(config.getHost(), config.getPort()); } catch (StartServerException e) { diff --git a/src/main/java/mc/core/NetStream.java b/src/main/java/mc/core/NetStream.java index 898e5cb..53286b1 100644 --- a/src/main/java/mc/core/NetStream.java +++ b/src/main/java/mc/core/NetStream.java @@ -42,6 +42,18 @@ public abstract class NetStream { return result; } + public void writeVarInt(int value) { + do { + byte temp = (byte)(value & 0b01111111); + value >>>= 7; + if (value != 0) { + temp |= 0b10000000; + } + + writeByte(temp); + } while (value != 0); + } + public String readString() { int length = readVarInt(); @@ -51,7 +63,15 @@ public abstract class NetStream { return new String(buffer, StandardCharsets.UTF_8); } + public void writeString(String value) { + writeVarInt(value.length()); + writeBytes(value.getBytes()); + } + public abstract byte readByte(); public abstract void readBytes(byte[] buffer); public abstract int readUnsignedShort(); + + public abstract void writeByte(int value); + public abstract void writeBytes(byte[] buffer); } diff --git a/src/main/java/mc/core/SCPacket.java b/src/main/java/mc/core/SCPacket.java new file mode 100644 index 0000000..161b47e --- /dev/null +++ b/src/main/java/mc/core/SCPacket.java @@ -0,0 +1,9 @@ +/* + * DmitriyMX + * 2018-04-08 + */ +package mc.core; + +public interface SCPacket { + byte[] toByteArray(); +} diff --git a/src/main/java/mc/core/embedded/ConfigFromSpring.java b/src/main/java/mc/core/embedded/ConfigFromSpring.java index d5cc215..215f77a 100644 --- a/src/main/java/mc/core/embedded/ConfigFromSpring.java +++ b/src/main/java/mc/core/embedded/ConfigFromSpring.java @@ -19,7 +19,7 @@ import java.util.Base64; public class ConfigFromSpring implements Config { @Setter private String descriptionServer; - private String faviconBase64; + private byte[] faviconBase64; @Setter private int maxPlayers; @Setter @@ -30,10 +30,8 @@ public class ConfigFromSpring implements Config { public void setFaviconBase64(File faviconImageFile) { log.debug("faviconImageFile: {}", faviconImageFile.getAbsolutePath()); try { - faviconBase64 = new String( - Base64.getEncoder().encode( - FileUtils.readFileToByteArray(faviconImageFile) - ) + faviconBase64 = Base64.getEncoder().encode( + FileUtils.readFileToByteArray(faviconImageFile) ); } catch (IOException e) { log.warn("Can't load favicon", e); diff --git a/src/main/java/mc/core/netty/NettyServer.java b/src/main/java/mc/core/netty/NettyServer.java index edba79c..f5189c7 100644 --- a/src/main/java/mc/core/netty/NettyServer.java +++ b/src/main/java/mc/core/netty/NettyServer.java @@ -24,7 +24,8 @@ public class NettyServer implements Server{ socketChannel.pipeline().addLast( new LoggingHandler(), new PacketDecoder(), - new PacketHandler() + new PacketHandler(), + new PacketEncoder() ); } }; diff --git a/src/main/java/mc/core/netty/PacketEncoder.java b/src/main/java/mc/core/netty/PacketEncoder.java new file mode 100644 index 0000000..5f6673e --- /dev/null +++ b/src/main/java/mc/core/netty/PacketEncoder.java @@ -0,0 +1,32 @@ +/* + * DmitriyMX + * 2018-04-08 + */ +package mc.core.netty; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; +import lombok.extern.slf4j.Slf4j; +import mc.core.NetStream; +import mc.core.SCPacket; + +@Slf4j +public class PacketEncoder extends MessageToByteEncoder { + @Override + protected void encode(ChannelHandlerContext ctx, SCPacket pkt, ByteBuf out) throws Exception { + State state = ctx.channel().attr(State.ATTR_STATE).get(); + Integer id = state.getServerSidePaclet(pkt.getClass()); + if (id == null) { + log.error("Packet not found: {}:{}", state.name(), pkt.getClass().getSimpleName()); + return; + } + + byte[] bytes = pkt.toByteArray(); + NetStream netStream = new WrapperNetStream(out); + + netStream.writeVarInt(bytes.length + NetStream.sizeVarInt(id)); + netStream.writeVarInt(id); + netStream.writeBytes(bytes); + } +} diff --git a/src/main/java/mc/core/netty/PacketHandler.java b/src/main/java/mc/core/netty/PacketHandler.java index 5458007..5f89ac1 100644 --- a/src/main/java/mc/core/netty/PacketHandler.java +++ b/src/main/java/mc/core/netty/PacketHandler.java @@ -4,11 +4,16 @@ */ package mc.core.netty; +import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import mc.core.CSPacket; +import mc.core.Config; +import mc.core.Main; import mc.core.netty.packets.StatusRequest; +import mc.core.netty.packets.StatusResponse; import java.lang.reflect.Method; import java.util.Arrays; @@ -23,17 +28,27 @@ public class PacketHandler extends SimpleChannelInboundHandler { Optional optionalMethod = Arrays.stream(this.getClass().getDeclaredMethods()) .filter(method -> method.getName().equals("on" + packet.getClass().getSimpleName()) && method.getParameterCount() == 2 - && method.getParameterTypes()[0].isAssignableFrom(ctx.getClass()) + && method.getParameterTypes()[0].isAssignableFrom(Channel.class) && method.getParameterTypes()[1].isAssignableFrom(packet.getClass())) .findFirst(); if (optionalMethod.isPresent()) { Method method = optionalMethod.get(); - method.invoke(this, ctx, packet); + method.invoke(this, ctx.channel(), packet); } } - public void onStatusRequest(ChannelHandlerContext ctx, StatusRequest packet) { - log.info("Catch!"); + public void onStatusRequest(Channel channel, StatusRequest packet) { + if (!packet.getNextState().equals(State.UNKNOWN)) { + channel.attr(State.ATTR_STATE).set(packet.getNextState()); + } + + Config config = Main.appContext.getBean("config", Config.class); //FIXME + StatusResponse pkt = new StatusResponse(); + pkt.setDescription(config.getDescriptionServer()); + pkt.setMaxOnline(config.getMaxPlayers()); + pkt.setFaviconBase64(config.getFaviconBase64()); + + channel.writeAndFlush(pkt); } } diff --git a/src/main/java/mc/core/netty/State.java b/src/main/java/mc/core/netty/State.java index d118d5c..e507b48 100644 --- a/src/main/java/mc/core/netty/State.java +++ b/src/main/java/mc/core/netty/State.java @@ -8,7 +8,9 @@ import com.google.common.collect.ImmutableMap; import io.netty.util.AttributeKey; import lombok.RequiredArgsConstructor; import mc.core.CSPacket; +import mc.core.SCPacket; import mc.core.netty.packets.StatusRequest; +import mc.core.netty.packets.StatusResponse; import java.util.Arrays; import java.util.Map; @@ -16,10 +18,14 @@ import java.util.Optional; @RequiredArgsConstructor public enum State { - UNKNOWN(0, ImmutableMap.of()), - STATUS(1, ImmutableMap.of( + UNKNOWN(0, ImmutableMap.of(), ImmutableMap.of()), + STATUS(1, + ImmutableMap.of( 0, StatusRequest.class - )); + ), ImmutableMap.of( + StatusResponse.class, 0 + ) + ); public static final AttributeKey ATTR_STATE = AttributeKey.newInstance("ATTR_STATE"); @@ -33,8 +39,13 @@ public enum State { private final int id; private final Map> clientSidePackets; + private final Map, Integer> serverSidePackets; public Class getClientSidePacket(final int packetId) { return clientSidePackets.get(packetId); } + + public Integer getServerSidePaclet(final Class clazz) { + return serverSidePackets.get(clazz); + } } diff --git a/src/main/java/mc/core/netty/WrapperNetStream.java b/src/main/java/mc/core/netty/WrapperNetStream.java index e69b067..34039da 100644 --- a/src/main/java/mc/core/netty/WrapperNetStream.java +++ b/src/main/java/mc/core/netty/WrapperNetStream.java @@ -26,4 +26,14 @@ public class WrapperNetStream extends NetStream { public int readUnsignedShort() { return byteBuf.readUnsignedShort(); } + + @Override + public void writeByte(int value) { + byteBuf.writeByte(value); + } + + @Override + public void writeBytes(byte[] buffer) { + byteBuf.writeBytes(buffer); + } } diff --git a/src/main/java/mc/core/netty/packets/StatusResponse.java b/src/main/java/mc/core/netty/packets/StatusResponse.java new file mode 100644 index 0000000..a494914 --- /dev/null +++ b/src/main/java/mc/core/netty/packets/StatusResponse.java @@ -0,0 +1,56 @@ +/* + * DmitriyMX + * 2018-04-08 + */ +package mc.core.netty.packets; + +import com.google.gson.JsonObject; +import lombok.Setter; +import lombok.ToString; +import mc.core.ByteArrayOutputNetStream; +import mc.core.SCPacket; + +@ToString +public class StatusResponse implements SCPacket { + private static final String name = "1.12.2"; + private static final int protocol = 340; + + @Setter + private int maxOnline; + @Setter + private int online; + @Setter + private String description; + @Setter + private byte[] faviconBase64; + + @Override + public byte[] toByteArray() { + ByteArrayOutputNetStream netStream = new ByteArrayOutputNetStream(); + + JsonObject versionObj = new JsonObject(); + versionObj.addProperty("name", name); + versionObj.addProperty("protocol", protocol); + + JsonObject playersObj = new JsonObject(); + playersObj.addProperty("max", maxOnline); + playersObj.addProperty("online", online); + + JsonObject descriptionObj = new JsonObject(); + descriptionObj.addProperty("text", description); + + JsonObject rootObj = new JsonObject(); + rootObj.add("version", versionObj); + rootObj.add("players", playersObj); + rootObj.add("description", descriptionObj); + + if (faviconBase64 != null && faviconBase64.length > 0) { + rootObj.addProperty("favicon", + "data:image/png;base64," + new String(faviconBase64) + ); + } + + netStream.writeString(rootObj.toString()); + return netStream.toByteArray(); + } +} From 63608db3046df872662ec37bdd1fa91b2f89ed90 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Sun, 8 Apr 2018 23:57:22 +0300 Subject: [PATCH 7/9] Ping packet --- src/main/java/mc/core/NetStream.java | 8 +++++++ .../java/mc/core/netty/PacketDecoder.java | 1 + .../java/mc/core/netty/PacketHandler.java | 5 ++++ src/main/java/mc/core/netty/State.java | 10 +++++--- .../mc/core/netty/packets/PingPacket.java | 24 +++++++++++++++++++ 5 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 src/main/java/mc/core/netty/packets/PingPacket.java diff --git a/src/main/java/mc/core/NetStream.java b/src/main/java/mc/core/NetStream.java index 53286b1..73af53d 100644 --- a/src/main/java/mc/core/NetStream.java +++ b/src/main/java/mc/core/NetStream.java @@ -4,12 +4,18 @@ */ package mc.core; +import lombok.Getter; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import java.nio.charset.StandardCharsets; @Slf4j public abstract class NetStream { + @Getter + @Setter + private int expectedSize; + public static int sizeVarInt(final int value) { byte size = 0; int v = value; @@ -74,4 +80,6 @@ public abstract class NetStream { public abstract void writeByte(int value); public abstract void writeBytes(byte[] buffer); + + } diff --git a/src/main/java/mc/core/netty/PacketDecoder.java b/src/main/java/mc/core/netty/PacketDecoder.java index 6e83d75..e698237 100644 --- a/src/main/java/mc/core/netty/PacketDecoder.java +++ b/src/main/java/mc/core/netty/PacketDecoder.java @@ -59,6 +59,7 @@ public class PacketDecoder extends ByteToMessageDecoder { } } else { CSPacket packet = clientSidePacketClass.newInstance(); + netStream.setExpectedSize(size - NetStream.sizeVarInt(id)); packet.readSelf(netStream); out.add(packet); } diff --git a/src/main/java/mc/core/netty/PacketHandler.java b/src/main/java/mc/core/netty/PacketHandler.java index 5f89ac1..10e8180 100644 --- a/src/main/java/mc/core/netty/PacketHandler.java +++ b/src/main/java/mc/core/netty/PacketHandler.java @@ -12,6 +12,7 @@ import lombok.extern.slf4j.Slf4j; import mc.core.CSPacket; import mc.core.Config; import mc.core.Main; +import mc.core.netty.packets.PingPacket; import mc.core.netty.packets.StatusRequest; import mc.core.netty.packets.StatusResponse; @@ -51,4 +52,8 @@ public class PacketHandler extends SimpleChannelInboundHandler { channel.writeAndFlush(pkt); } + + public void onPingPacket(Channel channel, PingPacket packet) { + channel.writeAndFlush(packet); + } } diff --git a/src/main/java/mc/core/netty/State.java b/src/main/java/mc/core/netty/State.java index e507b48..d917f72 100644 --- a/src/main/java/mc/core/netty/State.java +++ b/src/main/java/mc/core/netty/State.java @@ -9,6 +9,7 @@ import io.netty.util.AttributeKey; import lombok.RequiredArgsConstructor; import mc.core.CSPacket; import mc.core.SCPacket; +import mc.core.netty.packets.PingPacket; import mc.core.netty.packets.StatusRequest; import mc.core.netty.packets.StatusResponse; @@ -21,9 +22,12 @@ public enum State { UNKNOWN(0, ImmutableMap.of(), ImmutableMap.of()), STATUS(1, ImmutableMap.of( - 0, StatusRequest.class - ), ImmutableMap.of( - StatusResponse.class, 0 + 0, StatusRequest.class, + 1, PingPacket.class + ), + ImmutableMap.of( + StatusResponse.class, 0, + PingPacket.class, 1 ) ); diff --git a/src/main/java/mc/core/netty/packets/PingPacket.java b/src/main/java/mc/core/netty/packets/PingPacket.java new file mode 100644 index 0000000..b51fe8a --- /dev/null +++ b/src/main/java/mc/core/netty/packets/PingPacket.java @@ -0,0 +1,24 @@ +/* + * DmitriyMX + * 2018-04-08 + */ +package mc.core.netty.packets; + +import mc.core.CSPacket; +import mc.core.NetStream; +import mc.core.SCPacket; + +public class PingPacket implements CSPacket, SCPacket { + private byte[] rawData; + + @Override + public void readSelf(NetStream netStream) { + rawData = new byte[netStream.getExpectedSize()]; + netStream.readBytes(rawData); + } + + @Override + public byte[] toByteArray() { + return rawData; + } +} From ad742a6ae8f1eefcc6f71e67e8eef878aa79fd13 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Mon, 9 Apr 2018 00:12:36 +0300 Subject: [PATCH 8/9] fix Unknown state notify --- src/main/java/mc/core/netty/packets/StatusRequest.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/mc/core/netty/packets/StatusRequest.java b/src/main/java/mc/core/netty/packets/StatusRequest.java index 305b33d..63437b1 100644 --- a/src/main/java/mc/core/netty/packets/StatusRequest.java +++ b/src/main/java/mc/core/netty/packets/StatusRequest.java @@ -27,12 +27,9 @@ public class StatusRequest implements CSPacket { serverPort = netStream.readUnsignedShort(); int nextStateId = netStream.readVarInt(); - State state = State.getStateById(nextStateId); - if (state != null) { - nextState = state; - } else { + nextState = State.getStateById(nextStateId); + if (nextState.equals(State.UNKNOWN)){ log.warn("Unknown state ({})!", nextStateId); - nextState = State.UNKNOWN; } } } From e8337ed0ea3945be3e335d02bbdff52423ec96b5 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Mon, 9 Apr 2018 00:49:27 +0300 Subject: [PATCH 9/9] fix State reaction --- src/main/java/mc/core/netty/PacketHandler.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/mc/core/netty/PacketHandler.java b/src/main/java/mc/core/netty/PacketHandler.java index 10e8180..c65e92d 100644 --- a/src/main/java/mc/core/netty/PacketHandler.java +++ b/src/main/java/mc/core/netty/PacketHandler.java @@ -44,13 +44,15 @@ public class PacketHandler extends SimpleChannelInboundHandler { channel.attr(State.ATTR_STATE).set(packet.getNextState()); } - Config config = Main.appContext.getBean("config", Config.class); //FIXME - StatusResponse pkt = new StatusResponse(); - pkt.setDescription(config.getDescriptionServer()); - pkt.setMaxOnline(config.getMaxPlayers()); - pkt.setFaviconBase64(config.getFaviconBase64()); + if (packet.getNextState().equals(State.STATUS)) { + Config config = Main.appContext.getBean("config", Config.class); //FIXME + StatusResponse pkt = new StatusResponse(); + pkt.setDescription(config.getDescriptionServer()); + pkt.setMaxOnline(config.getMaxPlayers()); + pkt.setFaviconBase64(config.getFaviconBase64()); - channel.writeAndFlush(pkt); + channel.writeAndFlush(pkt); + } } public void onPingPacket(Channel channel, PingPacket packet) {