diff --git a/pom.xml b/pom.xml
index f9a195c..3864046 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,6 +14,7 @@
1.8
1.7.21
2.5
+ 4.2.5.RELEASE
4.1.22.Final
@@ -24,6 +25,11 @@
slf4j-api
${slf4j.version}
+
+ org.slf4j
+ jcl-over-slf4j
+ ${slf4j.version}
+
org.apache.logging.log4j
log4j-core
@@ -35,28 +41,18 @@
${log4j.version}
-
+
- org.projectlombok
- lombok
- 1.16.16
+ org.springframework
+ spring-context
+ ${spring.version}
+
+
+ commons-logging
+ commons-logging
+
+
-
- com.google.code.gson
- gson
- 2.8.2
-
-
- com.google.guava
- guava
- 24.1-jre
-
-
- commons-io
- commons-io
- 2.6
-
-
@@ -65,6 +61,27 @@
${netty.version}
+
+
+ org.projectlombok
+ lombok
+ 1.16.16
+
+
+ commons-io
+ commons-io
+ 2.6
+
+
+ com.google.guava
+ 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/CSPacket.java b/src/main/java/mc/core/CSPacket.java
new file mode 100644
index 0000000..319ba81
--- /dev/null
+++ b/src/main/java/mc/core/CSPacket.java
@@ -0,0 +1,10 @@
+/*
+ * DmitriyMX
+ * 2018-04-08
+ */
+package mc.core;
+
+public interface CSPacket {
+ default void readSelf(NetStream netStream) {
+ }
+}
diff --git a/src/main/java/mc/core/Config.java b/src/main/java/mc/core/Config.java
new file mode 100644
index 0000000..247c2e0
--- /dev/null
+++ b/src/main/java/mc/core/Config.java
@@ -0,0 +1,13 @@
+/*
+ * DmitriyMX
+ * 2018-04-08
+ */
+package mc.core;
+
+public interface Config {
+ int getMaxPlayers();
+ String getDescriptionServer();
+ 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 096ddc8..440cf83 100644
--- a/src/main/java/mc/core/Main.java
+++ b/src/main/java/mc/core/Main.java
@@ -5,18 +5,22 @@
package mc.core;
import lombok.extern.slf4j.Slf4j;
-import mc.core.netty.NettyServer;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
@Slf4j
public class Main {
+ public static ApplicationContext appContext; //FIXME
+
public static void main(String[] args) {
- log.info("Start server");
- Server server = new NettyServer();
+ appContext = new ClassPathXmlApplicationContext("spring.xml");
+ Config config = appContext.getBean("config", Config.class);
+
+ Server server = appContext.getBean("server", Server.class);
try {
- server.start("127.0.0.1", 25565);
+ server.start(config.getHost(), config.getPort());
} catch (StartServerException e) {
- log.error("Starting server error", e);
- server.stop();
+ log.error("Can't start server", e);
}
}
}
diff --git a/src/main/java/mc/core/NetStream.java b/src/main/java/mc/core/NetStream.java
index 8c2d63b..5305236 100644
--- a/src/main/java/mc/core/NetStream.java
+++ b/src/main/java/mc/core/NetStream.java
@@ -4,29 +4,82 @@
*/
package mc.core;
-public interface NetStream {
- byte readByte();
- void writeByte(byte value);
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
- int readBytes(byte[] buffer);
- void writeBytes(byte[] buffer);
+import java.nio.charset.StandardCharsets;
- int readBytes(byte[] buffer, int offset, int length);
- void writeBytes(byte[] buffer, int offset, int length);
+@Slf4j
+public abstract class NetStream {
+ @Getter
+ @Setter
+ private int expectedSize;
- int readVarInt();
- void writeVarInt(int value);
+ public static int sizeVarInt(final int value) {
+ byte size = 0;
+ int v = value;
- long readVarLong();
- void writeVarLong(long value);
+ do {
+ v >>>= 7;
+ size++;
+ } while (v != 0);
- String readString();
- void writeString(String value);
+ return size;
+ }
- int readUnsignedShort();
+ 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 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();
+
+ byte[] buffer = new byte[length];
+ readBytes(buffer);
+
+ 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);
- void skipBytes(int count);
- void setExpectedLength(int value);
- int getExpectedLength();
}
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/Server.java b/src/main/java/mc/core/Server.java
index b98120e..19ee13b 100644
--- a/src/main/java/mc/core/Server.java
+++ b/src/main/java/mc/core/Server.java
@@ -6,6 +6,4 @@ package mc.core;
public interface Server {
void start(String host, int port) throws StartServerException;
- void stop();
- boolean isRunning();
}
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..215f77a
--- /dev/null
+++ b/src/main/java/mc/core/embedded/ConfigFromSpring.java
@@ -0,0 +1,41 @@
+/*
+ * DmitriyMX
+ * 2018-04-08
+ */
+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;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Base64;
+
+@Slf4j
+@Getter
+public class ConfigFromSpring implements Config {
+ @Setter
+ private String descriptionServer;
+ private byte[] faviconBase64;
+ @Setter
+ private int maxPlayers;
+ @Setter
+ private String host;
+ @Setter
+ private int port;
+
+ public void setFaviconBase64(File faviconImageFile) {
+ log.debug("faviconImageFile: {}", faviconImageFile.getAbsolutePath());
+ try {
+ faviconBase64 = Base64.getEncoder().encode(
+ FileUtils.readFileToByteArray(faviconImageFile)
+ );
+ } catch (IOException 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
index 4b192d0..74478d9 100644
--- a/src/main/java/mc/core/netty/NettyServer.java
+++ b/src/main/java/mc/core/netty/NettyServer.java
@@ -13,7 +13,6 @@ import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LoggingHandler;
import mc.core.Server;
import mc.core.StartServerException;
-import mc.core.netty.handlers.HandshakeHandler;
public class NettyServer implements Server {
private EventLoopGroup bossGroup, workerGroup;
@@ -49,25 +48,10 @@ public class NettyServer implements Server {
ServerBootstrap serverBootstrap = buildServerBootstrap();
- EventBus.getInstance().listenIncomingPacket(new HandshakeHandler());
-
try {
serverBootstrap.bind(host, port).sync().channel().closeFuture().sync();
} catch (InterruptedException e) {
throw new StartServerException(e);
}
}
-
- @Override
- public void stop() {
- workerGroup.shutdownGracefully();
- bossGroup.shutdownGracefully();
- }
-
- @Override
- public boolean isRunning() {
- return bossGroup != null
- && workerGroup != null
- && !(bossGroup.isShutdown() && workerGroup.isShutdown());
- }
}
diff --git a/src/main/java/mc/core/netty/PacketDecoder.java b/src/main/java/mc/core/netty/PacketDecoder.java
index b56b1b4..7269146 100644
--- a/src/main/java/mc/core/netty/PacketDecoder.java
+++ b/src/main/java/mc/core/netty/PacketDecoder.java
@@ -6,44 +6,65 @@ package mc.core.netty;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.ReplayingDecoder;
+import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;
+import mc.core.CSPacket;
import mc.core.NetStream;
-import mc.core.Packet;
+import mc.core.netty.packets.RawPacket;
import java.util.List;
-import java.util.Optional;
@Slf4j
-public class PacketDecoder extends ReplayingDecoder {
+public class PacketDecoder extends ByteToMessageDecoder {
@Override
- protected void decode(ChannelHandlerContext context, ByteBuf byteBuf, List